diff --git a/ios/iosremote/UserDefaults.plist b/ios/iosremote/UserDefaults.plist
new file mode 100644
index 000000000000..d7714cf2f31d
--- /dev/null
+++ b/ios/iosremote/UserDefaults.plist
@@ -0,0 +1,10 @@
+
+
+
+
+ TOUCH_POINTER_ENABLED
+
+ TIMER_AUTOSTART_ENABLED
+
+
+
diff --git a/ios/iosremote/iPad_autosize.storyboard b/ios/iosremote/iPad_autosize.storyboard
new file mode 100644
index 000000000000..2028340308d6
--- /dev/null
+++ b/ios/iosremote/iPad_autosize.storyboard
@@ -0,0 +1,576 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ios/iosremote/iosremote/AppDelegate_ipad.h b/ios/iosremote/iosremote/AppDelegate_ipad.h
new file mode 100644
index 000000000000..0c120c466c43
--- /dev/null
+++ b/ios/iosremote/iosremote/AppDelegate_ipad.h
@@ -0,0 +1,16 @@
+//
+// AppDelegate_ipad.h
+// iosremote
+//
+// Created by Siqi Liu on 7/28/13.
+// Copyright (c) 2013 libreoffice. All rights reserved.
+//
+
+#import "AppDelegate.h"
+
+@class BasePresentationViewController;
+@class MainSplitViewController;
+
+@interface AppDelegate_ipad : AppDelegate
+
+@end
diff --git a/ios/iosremote/iosremote/AppDelegate_ipad.m b/ios/iosremote/iosremote/AppDelegate_ipad.m
new file mode 100644
index 000000000000..ad5f2b787e91
--- /dev/null
+++ b/ios/iosremote/iosremote/AppDelegate_ipad.m
@@ -0,0 +1,16 @@
+//
+// AppDelegate_ipad.m
+// iosremote
+//
+// Created by Siqi Liu on 7/28/13.
+// Copyright (c) 2013 libreoffice. All rights reserved.
+//
+
+#import "AppDelegate_ipad.h"
+#import "slideShowSwipeInList_ipad.h"
+#import "MainSplitViewController.h"
+#import "BasePresentationViewController.h"
+
+@implementation AppDelegate_ipad
+
+@end
diff --git a/ios/iosremote/iosremote/ControlVariables.h b/ios/iosremote/iosremote/ControlVariables.h
new file mode 100644
index 000000000000..b96e5b7afab0
--- /dev/null
+++ b/ios/iosremote/iosremote/ControlVariables.h
@@ -0,0 +1,43 @@
+//
+// ControlVariables.h
+// iosremote
+//
+// Created by Siqi Liu on 7/28/13.
+// Copyright (c) 2013 libreoffice. All rights reserved.
+//
+
+#ifndef iosremote_ControlVariables_h
+#define iosremote_ControlVariables_h
+
+// Width (or length before rotation) of the table view embedded within another table view's row
+#define kTableLength 768
+
+// Width of the cells of the embedded table view (after rotation, which means it controls the rowHeight property)
+#define kCellWidth 172
+// Height of the cells of the embedded table view (after rotation, which would be the table's width)
+#define kCellHeight 129
+
+// Padding for the Cell containing the article image and title
+#define kArticleCellVerticalInnerPadding 6
+#define kArticleCellHorizontalInnerPadding 7
+
+// Padding for the title label in an article's cell
+#define kArticleTitleLabelPadding 10
+
+// Vertical padding for the embedded table view within the row
+#define kRowVerticalPadding 1
+// Horizontal padding for the embedded table view within the row
+#define kRowHorizontalPadding 1
+
+// The background color of the vertical table view
+#define kVerticalTableBackgroundColor [UIColor colorWithRed:0.58823529 green:0.58823529 blue:0.58823529 alpha:1.0]
+
+// Background color for the horizontal table view (the one embedded inside the rows of our vertical table)
+#define kHorizontalTableBackgroundColor [UIColor blackColor]
+
+// The background color on the horizontal table view for when we select a particular cell
+#define kHorizontalTableSelectedBackgroundColor [UIColor colorWithRed:0.0 green:0.59607843 blue:0.37254902 alpha:1.0]
+
+#define kHorizontalTableCellHighlightedBackgroundColor [UIColor colorWithRed:0 green:0.4745098 blue:0.29019808 alpha:0.9]
+
+#endif
diff --git a/ios/iosremote/iosremote/HorizontalSlideCell.h b/ios/iosremote/iosremote/HorizontalSlideCell.h
new file mode 100644
index 000000000000..599a1d03076a
--- /dev/null
+++ b/ios/iosremote/iosremote/HorizontalSlideCell.h
@@ -0,0 +1,16 @@
+//
+// HorizontalSlideCell.h
+// iosremote
+//
+// Created by Siqi Liu on 7/28/13.
+// Copyright (c) 2013 libreoffice. All rights reserved.
+//
+
+#import
+
+@interface HorizontalSlideCell : UITableViewCell
+
+@property (strong, nonatomic) UIImageView *thumbnail;
+@property (strong, nonatomic) UILabel *numberLabel;
+
+@end
diff --git a/ios/iosremote/iosremote/HorizontalSlideCell.m b/ios/iosremote/iosremote/HorizontalSlideCell.m
new file mode 100644
index 000000000000..e114095f3579
--- /dev/null
+++ b/ios/iosremote/iosremote/HorizontalSlideCell.m
@@ -0,0 +1,65 @@
+//
+// HorizontalSlideCell.m
+// iosremote
+//
+// Created by Siqi Liu on 7/28/13.
+// Copyright (c) 2013 libreoffice. All rights reserved.
+//
+
+#import "HorizontalSlideCell.h"
+#import "ControlVariables.h"
+
+@implementation HorizontalSlideCell
+
+@synthesize thumbnail = _thumbnail;
+@synthesize numberLabel = _numberLabel;
+
+- (NSString *)reuseIdentifier
+{
+ return @"HorizontalTableSlideCell";
+}
+
+- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
+{
+ self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
+ if (self) {
+ // Initialization code
+ }
+ return self;
+}
+
+- (id)initWithFrame:(CGRect)frame
+{
+ self = [super initWithFrame:frame];
+
+ self.thumbnail = [[UIImageView alloc] initWithFrame:CGRectMake(kArticleCellHorizontalInnerPadding, kArticleCellVerticalInnerPadding, kCellWidth - kArticleCellHorizontalInnerPadding * 2, kCellHeight - kArticleCellVerticalInnerPadding * 2)];
+ self.thumbnail.opaque = YES;
+
+ [self.contentView addSubview:self.thumbnail];
+
+ self.numberLabel = [[UILabel alloc] initWithFrame:CGRectMake(self.thumbnail.frame.size.width * 0.8, self.thumbnail.frame.size.height * 0.8, self.thumbnail.frame.size.width * 0.2, self.thumbnail.frame.size.height * 0.2)];
+ self.numberLabel.opaque = YES;
+ self.numberLabel.backgroundColor = kHorizontalTableCellHighlightedBackgroundColor;
+ self.numberLabel.textColor = [UIColor whiteColor];
+ self.numberLabel.font = [UIFont boldSystemFontOfSize:11];
+ self.numberLabel.textAlignment = UITextAlignmentCenter;
+ self.numberLabel.numberOfLines = 1;
+ [self.thumbnail addSubview:self.numberLabel];
+
+ self.backgroundColor = [UIColor colorWithRed:0 green:0.40784314 blue:0.21568627 alpha:1.0];
+ self.selectedBackgroundView = [[UIView alloc] initWithFrame:self.thumbnail.frame];
+ self.selectedBackgroundView.backgroundColor = kHorizontalTableSelectedBackgroundColor;
+
+ self.transform = CGAffineTransformMakeRotation(M_PI * 0.5);
+
+ return self;
+}
+
+- (void)setSelected:(BOOL)selected animated:(BOOL)animated
+{
+ [super setSelected:selected animated:animated];
+
+ // Configure the view for the selected state
+}
+
+@end
diff --git a/ios/iosremote/iosremote/MainSplitViewController.h b/ios/iosremote/iosremote/MainSplitViewController.h
new file mode 100644
index 000000000000..2ae6eff403af
--- /dev/null
+++ b/ios/iosremote/iosremote/MainSplitViewController.h
@@ -0,0 +1,17 @@
+//
+// PresentationViewController.h
+// iosremote
+//
+// Created by Siqi Liu on 7/26/13.
+// Copyright (c) 2013 libreoffice. All rights reserved.
+//
+
+#import
+#import "slideShowPreviewTable_vc_ipad.h"
+
+@interface MainSplitViewController : UISplitViewController
+
+- (void) didReceivePresentationStarted;
+
+@property (strong, nonatomic) UIViewController * splitController;
+@end
diff --git a/ios/iosremote/iosremote/MainSplitViewController.m b/ios/iosremote/iosremote/MainSplitViewController.m
new file mode 100644
index 000000000000..fbb8b0203828
--- /dev/null
+++ b/ios/iosremote/iosremote/MainSplitViewController.m
@@ -0,0 +1,80 @@
+//
+// PresentationViewController.m
+// iosremote
+//
+// Created by Siqi Liu on 7/26/13.
+// Copyright (c) 2013 libreoffice. All rights reserved.
+//
+
+#import "MainSplitViewController.h"
+#import "server_list_vc_ipad.h"
+#import "CommunicationManager.h"
+#import "BasePresentationViewController.h"
+#import "slideShowSwipeInList_ipad.h"
+#import
+#import
+
+@interface MainSplitViewController ()
+
+@property UINavigationController * masterViewController;
+@property BasePresentationViewController * detailViewController;
+
+@end
+
+@implementation MainSplitViewController
+
+# pragma mark - System defaults
+
+- (BOOL) shouldAutorotate
+{
+ return YES;
+}
+
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
+{
+ return YES;
+}
+
+
+- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
+{
+ self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
+ if (self) {
+ // Custom initialization
+ }
+ return self;
+}
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+ [[[[UIApplication sharedApplication] delegate] window] setRootViewController:self];
+ // Do any additional setup after loading the view.
+
+ self.detailViewController = [self.viewControllers objectAtIndex:1];
+ self.masterViewController = [self.viewControllers objectAtIndex:0];
+
+ self.delegate = self.detailViewController;
+}
+
+-(void) viewDidAppear:(BOOL)animated
+{
+ [super viewDidAppear:animated];
+}
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+ // Dispose of any resources that can be recreated.
+}
+
+- (void) didReceivePresentationStarted
+{
+ [self.detailViewController hideMaster:NO];
+ [self dismissViewControllerAnimated:YES completion:nil];
+// [(UITableView *)[(slideShowSwipeInList_ipad *)[[self viewControllers] objectAtIndex:2] view] reloadData];
+ [(slideShowSwipeInList_ipad *)[(UINavigationController *)[[self viewControllers] objectAtIndex:0] topViewController] didReceivePresentationStarted];
+ [(BasePresentationViewController *)[[self viewControllers] objectAtIndex:1] setWelcomePageVisible:NO];
+}
+
+@end
diff --git a/ios/iosremote/iosremote/arrow_left.png b/ios/iosremote/iosremote/arrow_left.png
new file mode 100644
index 000000000000..d99560fea1b6
Binary files /dev/null and b/ios/iosremote/iosremote/arrow_left.png differ
diff --git a/ios/iosremote/iosremote/arrow_left@2x.png b/ios/iosremote/iosremote/arrow_left@2x.png
new file mode 100644
index 000000000000..dba2497f936d
Binary files /dev/null and b/ios/iosremote/iosremote/arrow_left@2x.png differ
diff --git a/ios/iosremote/iosremote/arrow_right.png b/ios/iosremote/iosremote/arrow_right.png
new file mode 100644
index 000000000000..e271d4655f8e
Binary files /dev/null and b/ios/iosremote/iosremote/arrow_right.png differ
diff --git a/ios/iosremote/iosremote/arrow_right@2x.png b/ios/iosremote/iosremote/arrow_right@2x.png
new file mode 100644
index 000000000000..44be9d652a00
Binary files /dev/null and b/ios/iosremote/iosremote/arrow_right@2x.png differ
diff --git a/ios/iosremote/iosremote/autoDismissKeyboardNavigationViewController.h b/ios/iosremote/iosremote/autoDismissKeyboardNavigationViewController.h
new file mode 100644
index 000000000000..93d1da1c2d7e
--- /dev/null
+++ b/ios/iosremote/iosremote/autoDismissKeyboardNavigationViewController.h
@@ -0,0 +1,13 @@
+//
+// autoDismissKeyboardNavigationViewController.h
+// iosremote
+//
+// Created by Siqi Liu on 7/28/13.
+// Copyright (c) 2013 libreoffice. All rights reserved.
+//
+
+#import
+
+@interface autoDismissKeyboardNavigationViewController : UINavigationController
+
+@end
diff --git a/ios/iosremote/iosremote/autoDismissKeyboardNavigationViewController.m b/ios/iosremote/iosremote/autoDismissKeyboardNavigationViewController.m
new file mode 100644
index 000000000000..fb6039815102
--- /dev/null
+++ b/ios/iosremote/iosremote/autoDismissKeyboardNavigationViewController.m
@@ -0,0 +1,43 @@
+//
+// autoDismissKeyboardNavigationViewController.m
+// iosremote
+//
+// Created by Siqi Liu on 7/28/13.
+// Copyright (c) 2013 libreoffice. All rights reserved.
+//
+
+#import "autoDismissKeyboardNavigationViewController.h"
+
+@interface autoDismissKeyboardNavigationViewController ()
+
+@end
+
+@implementation autoDismissKeyboardNavigationViewController
+
+- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
+{
+ self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
+ if (self) {
+ // Custom initialization
+ }
+ return self;
+}
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+ // Do any additional setup after loading the view.
+}
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+ // Dispose of any resources that can be recreated.
+}
+
+- (BOOL)disablesAutomaticKeyboardDismissal
+{
+ return NO;
+}
+
+@end
diff --git a/ios/iosremote/iosremote/server_list_vc_ipad.h b/ios/iosremote/iosremote/server_list_vc_ipad.h
new file mode 100644
index 000000000000..2fb881ec4143
--- /dev/null
+++ b/ios/iosremote/iosremote/server_list_vc_ipad.h
@@ -0,0 +1,15 @@
+//
+// server_list_vc_ipad.h
+// iosremote
+//
+// Created by Siqi Liu on 7/26/13.
+// Copyright (c) 2013 libreoffice. All rights reserved.
+//
+
+#import "serverList_vc.h"
+
+@interface server_list_vc_ipad : server_list_vc
+
+- (IBAction)cancelModalView:(id)sender;
+
+@end
diff --git a/ios/iosremote/iosremote/server_list_vc_ipad.m b/ios/iosremote/iosremote/server_list_vc_ipad.m
new file mode 100644
index 000000000000..bb4dea61728d
--- /dev/null
+++ b/ios/iosremote/iosremote/server_list_vc_ipad.m
@@ -0,0 +1,46 @@
+//
+// server_list_vc_ipad.m
+// iosremote
+//
+// Created by Siqi Liu on 7/26/13.
+// Copyright (c) 2013 libreoffice. All rights reserved.
+//
+
+#import "server_list_vc_ipad.h"
+
+@interface server_list_vc_ipad ()
+
+@end
+
+@implementation server_list_vc_ipad
+
+- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
+{
+ self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
+ if (self) {
+ // Custom initialization
+ }
+ return self;
+}
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+ // Do any additional setup after loading the view.
+}
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+ // Dispose of any resources that can be recreated.
+}
+
+- (void)viewDidUnload {
+ [super viewDidUnload];
+}
+
+#pragma mark - Actions
+- (IBAction)cancelModalView:(id)sender {
+ [self.presentingViewController dismissModalViewControllerAnimated:YES];
+}
+@end
diff --git a/ios/iosremote/iosremote/slideShowPreviewTable_vc_ipad.h b/ios/iosremote/iosremote/slideShowPreviewTable_vc_ipad.h
new file mode 100644
index 000000000000..ded75b0ec920
--- /dev/null
+++ b/ios/iosremote/iosremote/slideShowPreviewTable_vc_ipad.h
@@ -0,0 +1,21 @@
+//
+// slideShowPreview_vc~ipad.h
+// iosremote
+//
+// Created by Siqi Liu on 7/26/13.
+// Copyright (c) 2013 libreoffice. All rights reserved.
+//
+
+#import "slideShowPreviewTable_vc.h"
+
+@protocol MainSplitViewControllerProtocol
+
+- (void) didReceivePresentationStarted;
+
+@end
+
+@interface slideShowPreviewTable_vc_ipad : slideShowPreviewTable_vc
+
+@property (strong, nonatomic) id delegate;
+
+@end
diff --git a/ios/iosremote/iosremote/slideShowPreviewTable_vc_ipad.m b/ios/iosremote/iosremote/slideShowPreviewTable_vc_ipad.m
new file mode 100644
index 000000000000..93474628d57c
--- /dev/null
+++ b/ios/iosremote/iosremote/slideShowPreviewTable_vc_ipad.m
@@ -0,0 +1,73 @@
+//
+// slideShowPreview_vc~ipad.m
+// iosremote
+//
+// Created by Siqi Liu on 7/26/13.
+// Copyright (c) 2013 libreoffice. All rights reserved.
+//
+
+#import "slideShowPreviewTable_vc_ipad.h"
+#import "slideShowPreviewTable_vc.h"
+#import "CommunicationManager.h"
+#import "CommandTransmitter.h"
+#import "CommandInterpreter.h"
+#import "SlideShow.h"
+#import "MainSplitViewController.h"
+
+@interface slideShowPreviewTable_vc_ipad ()
+
+@end
+
+@implementation slideShowPreviewTable_vc_ipad
+
+#pragma mark - System defaults
+
+- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
+{
+ self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
+ if (self) {
+ // Custom initialization
+ }
+ return self;
+}
+
+- (void) viewDidLoad
+{
+ [super viewDidLoad];
+ if (self.navigationController)
+ self.delegate = (MainSplitViewController *) self.navigationController.presentingViewController;
+ else
+ self.delegate = (MainSplitViewController *) self.presentingViewController;
+ NSLog(@"%@", [self.delegate class]);
+ if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
+ self.optionsArray = [NSArray arrayWithObjects:OPTION_TIMER, nil];
+ } else
+ self.optionsArray = [NSArray arrayWithObjects:OPTION_TIMER, OPTION_POINTER, nil];
+ self.comManager = [CommunicationManager sharedComManager];
+ self.comManager.delegate = self;
+}
+
+- (void) viewDidAppear:(BOOL)animated
+{
+ [super viewDidAppear:animated];
+ if ([self.comManager.interpreter.slideShow size] > 0){
+ NSLog(@"3");
+ [self.delegate didReceivePresentationStarted];
+ }
+ NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
+ self.slideShowStartObserver = [[NSNotificationCenter defaultCenter] addObserverForName:STATUS_CONNECTED_SLIDESHOW_RUNNING
+ object:nil
+ queue:mainQueue
+ usingBlock:^(NSNotification *note) {
+ [self.delegate didReceivePresentationStarted];
+ }];
+}
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+ // Dispose of any resources that can be recreated.
+}
+
+
+@end
diff --git a/ios/iosremote/iosremote/slideShowPreviewTable_vc_iphone.h b/ios/iosremote/iosremote/slideShowPreviewTable_vc_iphone.h
new file mode 100644
index 000000000000..1f2d5d5c81f1
--- /dev/null
+++ b/ios/iosremote/iosremote/slideShowPreviewTable_vc_iphone.h
@@ -0,0 +1,14 @@
+//
+// slideShowPreview_vc~iphone.h
+// iosremote
+//
+// Created by Siqi Liu on 7/26/13.
+// Copyright (c) 2013 libreoffice. All rights reserved.
+//
+
+#import
+#import "slideShowPreviewTable_vc.h"
+
+@interface slideShowPreviewTable_vc_iphone : slideShowPreviewTable_vc
+
+@end
diff --git a/ios/iosremote/iosremote/slideShowPreviewTable_vc_iphone.m b/ios/iosremote/iosremote/slideShowPreviewTable_vc_iphone.m
new file mode 100644
index 000000000000..51cf96a4d638
--- /dev/null
+++ b/ios/iosremote/iosremote/slideShowPreviewTable_vc_iphone.m
@@ -0,0 +1,39 @@
+//
+// slideShowPreview_vc~iphone.m
+// iosremote
+//
+// Created by Siqi Liu on 7/26/13.
+// Copyright (c) 2013 libreoffice. All rights reserved.
+//
+
+#import "slideShowPreviewTable_vc_iphone.h"
+#import "CommandInterpreter.h"
+#import "SlideShow.h"
+
+@implementation slideShowPreviewTable_vc_iphone
+
+- (void) viewDidLoad
+{
+ [super viewDidLoad];
+ self.optionsArray = [NSArray arrayWithObjects:OPTION_TIMER, OPTION_POINTER, nil];
+ self.comManager = [CommunicationManager sharedComManager];
+ self.comManager.delegate = self;
+}
+
+- (void) viewDidAppear:(BOOL)animated
+{
+ [super viewDidAppear:animated];
+
+ if ([self.comManager.interpreter.slideShow size] > 0){
+ [self performSegueWithIdentifier:@"slideShowSegue" sender:self];
+ }
+ NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
+ self.slideShowStartObserver = [[NSNotificationCenter defaultCenter] addObserverForName:STATUS_CONNECTED_SLIDESHOW_RUNNING
+ object:nil
+ queue:mainQueue
+ usingBlock:^(NSNotification *note) {
+ [self performSegueWithIdentifier:@"slideShowSegue" sender:self];
+ }];
+}
+
+@end
diff --git a/ios/iosremote/iosremote/slideShowSwipeInList_ipad.h b/ios/iosremote/iosremote/slideShowSwipeInList_ipad.h
new file mode 100644
index 000000000000..3bb1a5d5cd7a
--- /dev/null
+++ b/ios/iosremote/iosremote/slideShowSwipeInList_ipad.h
@@ -0,0 +1,13 @@
+//
+// slideShowSwipeInList~ipad.h
+// iosremote
+//
+// Created by Siqi Liu on 7/27/13.
+// Copyright (c) 2013 libreoffice. All rights reserved.
+//
+
+@interface slideShowSwipeInList_ipad : UITableViewController
+
+- (void) didReceivePresentationStarted;
+
+@end
\ No newline at end of file
diff --git a/ios/iosremote/iosremote/slideShowSwipeInList_ipad.m b/ios/iosremote/iosremote/slideShowSwipeInList_ipad.m
new file mode 100644
index 000000000000..77c6258ff188
--- /dev/null
+++ b/ios/iosremote/iosremote/slideShowSwipeInList_ipad.m
@@ -0,0 +1,168 @@
+//
+// slideShowSwipeInList~ipad.m
+// iosremote
+//
+// Created by Siqi Liu on 7/27/13.
+// Copyright (c) 2013 libreoffice. All rights reserved.
+//
+
+#import "slideShowSwipeInList_ipad.h"
+#import "CommunicationManager.h"
+#import "CommandInterpreter.h"
+#import "SlideShow.h"
+#import "CommandTransmitter.h"
+#import "SWRevealViewController.h"
+#import "slideShowPreviewTable_vc.h"
+#import
+
+@interface slideShowSwipeInList_ipad ()
+
+@property (nonatomic, strong) CommunicationManager *comManager;
+@property (nonatomic, strong) SlideShow *slideshow;
+@property (nonatomic, strong) id slideChangedObserver;
+
+@end
+
+@implementation slideShowSwipeInList_ipad
+
+@synthesize comManager = _comManager;
+@synthesize slideshow = _slideshow;
+@synthesize slideChangedObserver = _slideChangedObserver;
+
+dispatch_queue_t backgroundQueue;
+
+- (void) handleBack:(id)sender
+{
+ [self.comManager.transmitter stopPresentation];
+ [self.tableView reloadData];
+}
+
+- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
+{
+ self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
+ if (self) {
+ // Custom initialization
+ }
+ return self;
+}
+
+- (SlideShow *)slideshow
+{
+ return self.comManager.interpreter.slideShow;
+}
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+ self.comManager = [CommunicationManager sharedComManager];
+ self.slideshow.secondaryDelegate = self;
+
+ UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"Stop Presentation"
+ style:UIBarButtonItemStyleBordered
+ target:self
+ action:@selector(handleBack:)];
+ [backButton setTintColor:[UIColor redColor]];
+ self.navigationItem.leftBarButtonItem = backButton;
+
+ NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
+ NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
+ self.slideChangedObserver =[center addObserverForName:MSG_SLIDE_CHANGED
+ object:nil
+ queue:mainQueue
+ usingBlock:^(NSNotification *note) {
+ if ([self.tableView numberOfRowsInSection:0] > 0){
+ NSIndexPath *indexPath = [NSIndexPath indexPathForRow:self.slideshow.currentSlide inSection:0];
+ [self.tableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionNone];
+ [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
+ }
+ }];
+ UIImageView *bgImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"slideshowRail"]];
+ [bgImageView setFrame:self.tableView.frame];
+
+ self.tableView.backgroundView = bgImageView;
+}
+
+- (void)viewDidUnload
+{
+ [[NSNotificationCenter defaultCenter] removeObserver:self.slideChangedObserver];
+ [super viewDidUnload];
+}
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+ // Dispose of any resources that can be recreated.
+}
+
+- (void) viewWillAppear:(BOOL)animated
+{
+ [self.tableView reloadData];
+ [super viewWillAppear:animated];
+}
+
+- (void) viewDidAppear:(BOOL)animated
+{
+ if ([self.comManager.interpreter.slideShow size] > 0) {
+ NSIndexPath *indexPath = [NSIndexPath indexPathForRow:self.slideshow.currentSlide
+ inSection:0];
+ [self.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
+ [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:NO];
+ }
+}
+
+- (void) didReceivePresentationStarted
+{
+ self.slideshow.secondaryDelegate = self;
+ [self.tableView reloadData];
+}
+
+#pragma mark - Table view data source
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
+{
+ return 1;
+}
+
+
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
+{
+ return [self.slideshow size];
+}
+
+- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
+{
+ return @"Slides";
+}
+
+
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
+{
+ static NSString *CellIdentifier = @"slide";
+
+ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: CellIdentifier];
+ UILabel * slideNumber = (UILabel *)[cell viewWithTag:2];
+
+ // Starting 20, all tags are used for thumbnails in this sidebar
+ [cell setTag:20+indexPath.row];
+ [self.slideshow getContentAtIndex:indexPath.row forView:cell];
+ [slideNumber setText:[NSString stringWithFormat:@"%u", indexPath.row+1]];
+ return cell;
+}
+
+- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
+ // Otherwise selection will disable background color and make slide number unreadable
+ if(cell.selected){
+ UILabel *label = (UILabel *)[cell viewWithTag:2];
+ if ([label backgroundColor]!=[UIColor lightGrayColor]) {
+ [label setBackgroundColor:[UIColor lightGrayColor]];
+ }
+ }
+}
+
+- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
+{
+ [self.comManager.transmitter gotoSlide:indexPath.row];
+ [[[self.tableView cellForRowAtIndexPath:indexPath] viewWithTag:2] setBackgroundColor:[UIColor lightGrayColor]];
+}
+
+@end
diff --git a/ios/iosremote/iosremote/slideShowSwipeInList_iphone.h b/ios/iosremote/iosremote/slideShowSwipeInList_iphone.h
new file mode 100644
index 000000000000..2953e59591cb
--- /dev/null
+++ b/ios/iosremote/iosremote/slideShowSwipeInList_iphone.h
@@ -0,0 +1,12 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#import
+
+@interface slideShowSwipeInList : UITableViewController
+
+@end
diff --git a/ios/iosremote/iosremote/slideShowSwipeInList_iphone.m b/ios/iosremote/iosremote/slideShowSwipeInList_iphone.m
new file mode 100644
index 000000000000..67db07ac3a36
--- /dev/null
+++ b/ios/iosremote/iosremote/slideShowSwipeInList_iphone.m
@@ -0,0 +1,183 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import "slideShowSwipeInList_iphone.h"
+#import "CommunicationManager.h"
+#import "CommandInterpreter.h"
+#import "SlideShow.h"
+#import "CommandTransmitter.h"
+#import "SWRevealViewController.h"
+#import "slideShowPreviewTable_vc.h"
+#import "ControlVariables.h"
+#import "stopWatch.h"
+#import
+
+@interface slideShowSwipeInList ()
+
+@property (nonatomic, strong) CommunicationManager *comManager;
+@property (nonatomic, strong) SlideShow *slideshow;
+@property (nonatomic, strong) stopWatch *stopWatch;
+
+@end
+
+@implementation slideShowSwipeInList
+
+@synthesize comManager = _comManager;
+@synthesize slideshow = _slideshow;
+
+dispatch_queue_t backgroundQueue;
+
+- (void) viewDidLoad
+{
+ [super viewDidLoad];
+
+ self.comManager = [CommunicationManager sharedComManager];
+ self.slideshow = self.comManager.interpreter.slideShow;
+ self.slideshow.secondaryDelegate = self;
+
+ self.clearsSelectionOnViewWillAppear = NO;
+
+ self.stopWatch = [[stopWatch alloc] init];
+ if ([[NSUserDefaults standardUserDefaults] boolForKey:KEY_TIMER]) {
+ [self.stopWatch start];
+ }
+
+ UIImageView *tempImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"slideshowRail.png"]];
+ [tempImageView setFrame:self.tableView.frame];
+
+ self.tableView.backgroundView = tempImageView;
+}
+
+- (void) viewDidAppear:(BOOL)animated
+{
+ if (!self.stopWatch.set) {
+ [self.stopWatch setupWithTableViewCell:[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]];
+ }
+ [self.stopWatch updateStartButtonIcon];
+ if ([self.comManager.interpreter.slideShow size] > 0) {
+ [self.stopWatch updateStartButtonIcon];
+ NSIndexPath *indexPath = [NSIndexPath indexPathForRow:self.slideshow.currentSlide
+ inSection:1];
+ [self.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
+ [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:NO];
+ }
+}
+
+- (void) prepareForSegue: (UIStoryboardSegue *) segue sender: (id) sender
+{
+ // configure the segue.
+ // in this case we dont swap out the front view controller, which is a UINavigationController.
+ // but we could..
+ if ( [segue isKindOfClass: [SWRevealViewControllerSegue class]] )
+ {
+ SWRevealViewControllerSegue* rvcs = (SWRevealViewControllerSegue*) segue;
+
+ SWRevealViewController* rvc = self.revealViewController;
+ NSAssert( rvc != nil, @"oops! must have a revealViewController" );
+
+ NSAssert( [rvc.frontViewController isKindOfClass: [UINavigationController class]], @"oops! for this segue we want a permanent navigation controller in the front!" );
+
+ rvcs.performBlock = ^(SWRevealViewControllerSegue* rvc_segue, UIViewController* svc, UIViewController* dvc) {
+
+ UINavigationController* nc = (UINavigationController*)rvc.frontViewController;
+ [nc setViewControllers: @[ dvc ] animated: YES ];
+
+ [rvc setFrontViewPosition: FrontViewPositionLeft animated: YES];
+ };
+ }
+}
+
+
+#pragma mark - Table view data source
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
+{
+ return 2;
+}
+
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
+{
+ // Section one used for stopwatch
+ if (section == 0)
+ return 1;
+ else
+ return [self.slideshow size];
+}
+
+- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
+{
+ switch (section) {
+ case 0:
+ return @"Stop Watch";
+ break;
+ case 1:
+ return @"Slides";
+ default:
+ break;
+ }
+ return nil;
+}
+
+- (void) tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
+{
+ [self performSegueWithIdentifier: @"sw_customized_segue" sender: [tableView cellForRowAtIndexPath: indexPath]];
+}
+
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
+{
+ if (indexPath.section == 0) {
+ static NSString *CellIdentifier = @"stopWatch";
+
+ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: CellIdentifier];
+ [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
+ cell.contentView.backgroundColor = [UIColor whiteColor];
+ return cell;
+ } else {
+ static NSString *CellIdentifier = @"slide";
+
+ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: CellIdentifier];
+ UILabel * slideNumber = (UILabel *)[cell viewWithTag:2];
+
+ // Starting 20, all tags are used for thumbnails in this sidebar
+ [cell setTag:20+indexPath.row];
+ [self.slideshow getContentAtIndex:indexPath.row forView:cell];
+ [slideNumber setText:[NSString stringWithFormat:@"%u", indexPath.row+1]];
+
+
+ cell.backgroundColor = [UIColor colorWithRed:0 green:0.40784314 blue:0.21568627 alpha:1.0];
+
+ return cell;
+ }
+}
+
+- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
+ // Otherwise selection will disable background color and make slide number unreadable
+ if(indexPath.section == 1 && cell.selected){
+ UILabel *label = (UILabel *)[cell viewWithTag:2];
+ if ([label backgroundColor]!=[UIColor lightGrayColor]) {
+ [label setBackgroundColor:[UIColor lightGrayColor]];
+ }
+ }
+}
+
+- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
+{
+ if (indexPath.section == 0)
+ return;
+ [self.comManager.transmitter gotoSlide:indexPath.row];
+ [[[self.tableView cellForRowAtIndexPath:indexPath] viewWithTag:2] setBackgroundColor:[UIColor lightGrayColor]];
+ [self.revealViewController revealToggle: self];
+}
+
+
+- (void)viewDidUnload {
+ [self setStopWatch:nil];
+ [super viewDidUnload];
+}
+
+@end
diff --git a/ios/iosremote/iosremote/slideShow_vc_iphone.h b/ios/iosremote/iosremote/slideShow_vc_iphone.h
new file mode 100644
index 000000000000..67f3b6026c91
--- /dev/null
+++ b/ios/iosremote/iosremote/slideShow_vc_iphone.h
@@ -0,0 +1,31 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#import
+#import "SlideShow.h"
+
+@interface slideShow_vc : UIViewController
+
+- (IBAction)nextSlideAction:(id)sender;
+- (IBAction)previousSlideAction:(id)sender;
+- (IBAction)pointerAction:(id)sender;
+- (IBAction)accPointerAction:(id)sender;
+
+@property (weak, nonatomic) IBOutlet UIView *notesView;
+@property (weak, nonatomic) IBOutlet UIWebView *lecturer_notes;
+@property (weak, nonatomic) IBOutlet UIImageView *slideView;
+@property (weak, nonatomic) IBOutlet UIImageView *secondarySlideView;
+@property (weak, nonatomic) IBOutlet UILabel *slideNumber;
+
+@property (weak, nonatomic) IBOutlet UIView *movingPointer;
+@property (weak, nonatomic) IBOutlet UIImageView *touchPointerImage;
+@property (weak, nonatomic) IBOutlet UIView *blockingView;
+@property (weak, nonatomic) IBOutlet UIView *bottomView;
+@property (weak, nonatomic) IBOutlet UIButton *pointerBtn;
+
+@end
diff --git a/ios/iosremote/iosremote/slideShow_vc_iphone.m b/ios/iosremote/iosremote/slideShow_vc_iphone.m
new file mode 100644
index 000000000000..6ddde90409d9
--- /dev/null
+++ b/ios/iosremote/iosremote/slideShow_vc_iphone.m
@@ -0,0 +1,401 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#import "slideShow_vc_iphone.h"
+#import "SlideShow.h"
+#import "UIViewTransitionCategory.h"
+#import "CommunicationManager.h"
+#import "SWRevealViewController.h"
+#import "CommandInterpreter.h"
+#import "CommandTransmitter.h"
+#import "slideShowPreviewTable_vc.h"
+#import
+#import
+
+
+#define CURRENT_SLIDE_IMAGEVIEW 1
+#define NEXT_SLIDE_IMAGEVIEW 2
+#define TOUCH_POINTER_VIEW 3
+#define CURRENT_SLIDE_NOTES 4
+
+@interface slideShow_vc ()
+
+@property (nonatomic, strong) CommunicationManager *comManager;
+@property (nonatomic, strong) id slideShowImageNoteReadyObserver;
+@property (nonatomic, strong) id slideShowFinishedObserver;
+@property (nonatomic, strong) SlideShow* slideshow;
+
+@property BOOL pointerCalibrationOn;
+@property CGPoint refLeftUpperGravity;
+@property CGPoint refRightUpperGravity;
+@property CGPoint refRightLowerGravity;
+
+// SWReveal Controller
+@property (readwrite) IBOutlet UIBarButtonItem* revealButtonItem;
+
+@property int count;
+
+@end
+
+@implementation slideShow_vc
+
+@synthesize comManager = _comManager;
+@synthesize slideShowImageNoteReadyObserver = _slideShowImageNoteReadyObserver;
+@synthesize slideShowFinishedObserver = _slideShowFinishedObserver;
+@synthesize slideshow = _slideshow;
+
+#pragma mark - Pointer
+
+- (CMMotionManager *)motionManager
+{
+ CMMotionManager *motionManager = nil;
+
+ id appDelegate = [UIApplication sharedApplication].delegate;
+
+ if ([appDelegate respondsToSelector:@selector(motionManager)]) {
+ motionManager = [appDelegate motionManager];
+ }
+
+ return motionManager;
+}
+
+- (void)startMotionDetect
+{
+ // __block float stepMoveFactorX = 5;
+ // __block float stepMoveFactorY = 5;
+ // __block double refX, refY;
+
+ [self.motionManager
+ startAccelerometerUpdatesToQueue:[[NSOperationQueue alloc] init]
+ withHandler:^(CMAccelerometerData *data, NSError *error)
+ {
+
+ dispatch_async(dispatch_get_main_queue(),
+ ^{
+ CGRect rect = self.movingPointer.frame;
+ NSLog(@"x:%f y:%f z:%f", data.acceleration.x, data.acceleration.y, data.acceleration.z);
+ // Used to calibrate pointer based on initial position
+ // if (self.pointerCalibrationOn){
+ // refX = data.acceleration.x;
+ // refY = data.acceleration.y;
+ // self.pointerCalibrationOn = NO;
+ // }
+ // float movetoX = rect.origin.x + ((data.acceleration.x - refX) * stepMoveFactorX);
+
+ float movetoX = self.touchPointerImage.frame.origin.x + self.touchPointerImage.frame.size.width * ABS(data.acceleration.x - self.refLeftUpperGravity.x) / ABS(self.refRightUpperGravity.x - self.refLeftUpperGravity.x);
+ float maxX = self.touchPointerImage.frame.origin.x + self.touchPointerImage.frame.size.width - rect.size.width;
+
+ // float movetoY = (rect.origin.y) + ((data.acceleration.y - refY) * stepMoveFactorY);
+ float movetoY = self.touchPointerImage.frame.origin.y + self.touchPointerImage.frame.size.height * ABS(data.acceleration.y - self.refRightUpperGravity.y) / ABS(self.refRightLowerGravity.y - self.refRightUpperGravity.y);
+ float maxY = self.touchPointerImage.frame.origin.y + self.touchPointerImage.frame.size.height;
+
+ if ( movetoX > self.touchPointerImage.frame.origin.x && movetoX < maxX ) {
+ rect.origin.x = movetoX;
+ };
+
+ if ( movetoY > self.touchPointerImage.frame.origin.y && movetoY < maxY ) {
+ rect.origin.y = movetoY;
+ };
+
+ [UIView animateWithDuration:0 delay:0
+ options:UIViewAnimationOptionCurveEaseIn
+ animations:^{
+ self.movingPointer.frame = rect;
+ }
+ completion:nil
+ ];
+ });
+ }];
+}
+
+- (IBAction)accPointerAction:(id)sender{
+ BOOL acc = [[NSUserDefaults standardUserDefaults] boolForKey:KEY_POINTER];
+ if (!acc) {
+ static BOOL pointer = NO;
+ if (!pointer){
+ [self startMotionDetect];
+ [self.movingPointer setHidden:NO];
+ }
+ else {
+ [self.motionManager stopAccelerometerUpdates];
+ self.pointerCalibrationOn = NO;
+ [self.movingPointer setHidden:YES];
+ }
+ pointer = !pointer;
+ }
+}
+
+- (IBAction)pointerAction:(id)sender {
+ if (self.count == 0 || self.count == 1){
+ CGPoint p;
+ p.x = [self.motionManager accelerometerData].acceleration.x;
+ p.y = [self.motionManager accelerometerData].acceleration.y;
+ self.refLeftUpperGravity = p;
+ if (self.count == 1) {
+ UIAlertView *message = [[UIAlertView alloc] initWithTitle:@"Calibration"
+ message:@"Upper left corner calibrated, now point your device to the upper right corner of the screen and click Pointer button again"
+ delegate:nil
+ cancelButtonTitle:@"OK"
+ otherButtonTitles:@"Help", nil];
+ [message show];
+ }
+ ++self.count;
+ } else if (self.count == 2 || self.count == 3) {
+ CGPoint p;
+ p.x = [self.motionManager accelerometerData].acceleration.x;
+ p.y = [self.motionManager accelerometerData].acceleration.y;
+ self.refRightUpperGravity = p;
+ if (self.count == 3) {
+ UIAlertView *message = [[UIAlertView alloc] initWithTitle:@"Calibration"
+ message:@"Upper right corner calibrated, now point your device to the lower right corner of the screen and click Pointer button again!"
+ delegate:nil
+ cancelButtonTitle:@"OK"
+ otherButtonTitles:@"Help", nil];
+ [message show];
+ }
+ ++self.count;
+ } else if (self.count == 4 || self.count == 5) {
+ CGPoint p;
+ p.x = [self.motionManager accelerometerData].acceleration.x;
+ p.y = [self.motionManager accelerometerData].acceleration.y;
+ self.refRightLowerGravity = p;
+ if (self.count == 5) {
+ UIAlertView *message = [[UIAlertView alloc] initWithTitle:@"Calibration"
+ message:@"Lower right corner calibrated, enjoy your pointer!"
+ delegate:nil
+ cancelButtonTitle:@"OK"
+ otherButtonTitles:@"Help", nil];
+ [message show];
+ }
+ ++self.count;
+ } else {
+ if ([self.touchPointerImage isHidden]){
+ [self.slideshow getContentAtIndex:self.slideshow.currentSlide forView:self.touchPointerImage];
+ CGPoint p = self.view.center;
+ p.y -= 50;
+ self.touchPointerImage.center = p;
+ }
+ [self.touchPointerImage fadeInfadeOutwithDuration:0.0 maxAlpha:1.0];
+ [self.blockingView fadeInfadeOutwithDuration:0.0 maxAlpha:0.7];
+ }
+}
+
+- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
+ UITouch *touch = [[event allTouches] anyObject];
+ if (!self.touchPointerImage.isHidden){
+ CGPoint loc = [touch locationInView:self.touchPointerImage];
+ if (loc.x >= 0 && loc.x <= self.touchPointerImage.frame.size.width
+ && loc.y >= 0 && loc.y <= self.touchPointerImage.frame.size.height){
+ CGPoint pointerInPercentage;
+ pointerInPercentage.x = loc.x / self.touchPointerImage.frame.size.width;
+ pointerInPercentage.y = loc.y / self.touchPointerImage.frame.size.height;
+ [self.comManager.transmitter setPointerVisibleAt:pointerInPercentage];
+
+ CGPoint p;
+ p.x = loc.x + self.touchPointerImage.frame.origin.x;
+ p.y = loc.y + self.touchPointerImage.frame.origin.y;
+ self.movingPointer.center = p;
+ [self.movingPointer setHidden:NO];
+ }
+ }
+
+ if ([touch view] == self.secondarySlideView)
+ {
+ // Change to the next slide when secondary slide is clicked
+ [self.comManager.transmitter gotoSlide:self.slideshow.currentSlide + 1];
+ }
+}
+
+- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
+{
+ if (!self.touchPointerImage.isHidden){
+ UITouch *touch = [[event allTouches] anyObject];
+ CGPoint loc = [touch locationInView:self.touchPointerImage];
+ if (loc.x >= 0 && loc.x <= self.touchPointerImage.frame.size.width
+ && loc.y >= self.movingPointer.frame.size.height && loc.y <= self.touchPointerImage.frame.size.height - self.movingPointer.frame.size.height)
+ {
+ CGPoint pointerInPercentage;
+ pointerInPercentage.x = loc.x / self.touchPointerImage.frame.size.width;
+ pointerInPercentage.y = loc.y / self.touchPointerImage.frame.size.height;
+ [self.comManager.transmitter pointerCoordination:pointerInPercentage];
+
+ CGPoint p;
+ p.x = loc.x + self.touchPointerImage.frame.origin.x;
+ p.y = loc.y + self.touchPointerImage.frame.origin.y;
+ self.movingPointer.center = p;
+ }
+ }
+}
+
+- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
+{
+ [self.movingPointer setHidden:YES];
+ [self.comManager.transmitter setPointerDismissed];
+}
+
+#pragma mark - System defaults
+
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
+{
+ return (interfaceOrientation == UIInterfaceOrientationPortrait);
+}
+
+- (NSUInteger) supportedInterfaceOrientations
+{
+ return UIInterfaceOrientationMaskPortrait;
+}
+
+- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
+{
+ self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
+ if (self) {
+ // Custom initialization
+ }
+ return self;
+}
+
+- (SlideShow *)slideshow
+{
+ return self.comManager.interpreter.slideShow;
+}
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ // Unique tag assignment. Don't use 0 as it's default. 0-10 for central VC
+ [self.slideView setTag:CURRENT_SLIDE_IMAGEVIEW];
+ [self.secondarySlideView setTag:NEXT_SLIDE_IMAGEVIEW];
+ [self.lecturer_notes setTag:CURRENT_SLIDE_NOTES];
+ [self.touchPointerImage setTag:TOUCH_POINTER_VIEW];
+
+ self.comManager = [CommunicationManager sharedComManager];
+ self.slideshow.delegate = self;
+
+ [self.slideshow getContentAtIndex:self.slideshow.currentSlide forView:self.slideView];
+ [self.slideshow getContentAtIndex:self.slideshow.currentSlide+1 forView:self.secondarySlideView];
+ [self.slideshow getContentAtIndex:self.slideshow.currentSlide forView:self.lecturer_notes];
+ [self.slideshow getContentAtIndex:self.slideshow.currentSlide forView:self.touchPointerImage];
+ [self.slideNumber setText:[NSString stringWithFormat:@"%u/%u", [self.slideshow currentSlide]+1, [self.slideshow size]]];
+
+
+ UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"Stop Presentation"
+ style:UIBarButtonItemStyleBordered
+ target:self
+ action:@selector(handleBack:)];
+ [backButton setTintColor:[UIColor redColor]];
+ self.revealViewController.navigationItem.leftBarButtonItem = backButton;
+
+ self.revealButtonItem = [[UIBarButtonItem alloc] initWithImage: [UIImage imageNamed:@"more_icon.png"]
+ style:UIBarButtonItemStyleBordered
+ target:self.revealViewController
+ action:@selector( revealToggle: )];
+ self.revealViewController.navigationItem.rightBarButtonItem = self.revealButtonItem;
+ [self.navigationController.navigationBar addGestureRecognizer: self.revealViewController.panGestureRecognizer];
+
+ self.pointerCalibrationOn = NO;
+ self.movingPointer.layer.cornerRadius = 3;
+
+ BOOL acc = [[NSUserDefaults standardUserDefaults] boolForKey:KEY_POINTER];
+ if (!acc) {
+ // Hook up acc detection
+ [self.pointerBtn addTarget:self action:@selector(pointerAction:) forControlEvents:UIControlEventTouchUpOutside];
+ [self.pointerBtn addTarget:self action:@selector(pointerAction:) forControlEvents:UIControlEventTouchUpInside];
+ } else {
+ // Disable all calibration functions for acc based pointer
+ self.count = INT_MAX;
+ }
+}
+
+- (void) handleBack:(id)sender
+{
+ [self.comManager.transmitter stopPresentation];
+ [self.navigationController popViewControllerAnimated:YES];
+}
+
+
+- (void) viewDidAppear:(BOOL)animated
+{
+ NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
+ NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
+
+ self.slideShowImageNoteReadyObserver =[center addObserverForName:MSG_SLIDE_CHANGED
+ object:nil
+ queue:mainQueue
+ usingBlock:^(NSNotification *note) {
+ [self.slideshow getContentAtIndex:self.slideshow.currentSlide forView:self.slideView];
+ [self.slideshow getContentAtIndex:self.slideshow.currentSlide forView:self.touchPointerImage];
+ [self.slideshow getContentAtIndex:self.slideshow.currentSlide+1 forView:self.secondarySlideView];
+ [self.slideshow getContentAtIndex:self.slideshow.currentSlide forView:self.lecturer_notes];
+ [self.slideNumber setText:[NSString stringWithFormat:@"%u/%u", [self.slideshow currentSlide]+1, [self.slideshow size]]];
+
+ }];
+
+ self.slideShowFinishedObserver = [center addObserverForName:STATUS_CONNECTED_NOSLIDESHOW
+ object:nil
+ queue:mainQueue
+ usingBlock:^(NSNotification *note) {
+ [self.navigationController popViewControllerAnimated:YES];
+ }];
+ self.slideView.layer.shadowColor = [[UIColor blackColor] CGColor];
+ self.slideView.layer.shadowOpacity = 0.5;
+ self.slideView.layer.shadowRadius = 4.0;
+ self.slideView.layer.shadowOffset = CGSizeMake(3.0f, 3.0f);
+ self.slideView.layer.shadowPath = [UIBezierPath bezierPathWithRect:self.slideView.bounds].CGPath;
+ self.slideView.clipsToBounds = NO;
+
+ self.secondarySlideView.layer.shadowColor = [[UIColor blackColor] CGColor];
+ self.secondarySlideView.layer.shadowOpacity = 0.5;
+ self.secondarySlideView.layer.shadowRadius = 4.0;
+ self.secondarySlideView.layer.shadowOffset = CGSizeMake(3.0f, 3.0f);
+ self.secondarySlideView.layer.shadowPath = [UIBezierPath bezierPathWithRect:self.secondarySlideView.bounds].CGPath;
+ self.secondarySlideView.clipsToBounds = NO;
+
+ // We calibrate once when presentation starts. needs a users alert to inform users to point at the center of the screen at the beginning
+ self.pointerCalibrationOn = YES;
+
+ [super viewDidAppear:animated];
+}
+
+- (void) viewDidDisappear:(BOOL)animated
+{
+ self.count = 0;
+ [[NSNotificationCenter defaultCenter] removeObserver:self.slideShowFinishedObserver];
+ [[NSNotificationCenter defaultCenter] removeObserver:self.slideShowImageNoteReadyObserver];
+ [super viewDidDisappear:animated];
+}
+
+
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+ // Dispose of any resources that can be recreated.
+}
+
+- (void)viewDidUnload {
+ [self setLecturer_notes:nil];
+ [self setSlideView:nil];
+ [self setSlideNumber:nil];
+ [self setSecondarySlideView:nil];
+ [self setNotesView:nil];
+ [self setMovingPointer:nil];
+ [self setBlockingView:nil];
+ [self setBottomView:nil];
+ [self setPointerBtn:nil];
+ [super viewDidUnload];
+}
+
+- (IBAction)nextSlideAction:(id)sender {
+ [[self.comManager transmitter] nextTransition];
+}
+
+- (IBAction)previousSlideAction:(id)sender {
+ [[self.comManager transmitter] previousTransition];
+}
+
+@end
diff --git a/ios/iosremote/iosremote/stopWatch.h b/ios/iosremote/iosremote/stopWatch.h
new file mode 100644
index 000000000000..bd0edde8e6ef
--- /dev/null
+++ b/ios/iosremote/iosremote/stopWatch.h
@@ -0,0 +1,31 @@
+//
+// stopWatch.h
+// iosremote
+//
+// Created by Siqi Liu on 7/29/13.
+// Copyright (c) 2013 libreoffice. All rights reserved.
+//
+
+#import
+
+#define TIMER_STATE_RUNNING 0
+#define TIMER_STATE_PAUSED 1
+#define TIMER_STATE_CLEARED 2
+
+@interface stopWatch : NSObject
+
+// StopWatch
+@property (strong, nonatomic) NSTimer *stopWatchTimer;
+@property (strong, nonatomic) NSDate *startDate;
+@property BOOL set;
+
+- (stopWatch *) initWithStartButton:(UIButton *)startButton
+ ClearButton:(UIButton *)clearButton
+ TimeLabel:(UILabel *)timeLabel;
+- (void) setupWithTableViewCell:(UITableViewCell *)cell;
+
+- (void) start;
+- (void) clear;
+- (void) updateStartButtonIcon;
+
+@end
diff --git a/ios/iosremote/iosremote/stopWatch.m b/ios/iosremote/iosremote/stopWatch.m
new file mode 100644
index 000000000000..b955a12d1f87
--- /dev/null
+++ b/ios/iosremote/iosremote/stopWatch.m
@@ -0,0 +1,148 @@
+//
+// stopWatch.m
+// iosremote
+//
+// Created by Siqi Liu on 7/29/13.
+// Copyright (c) 2013 libreoffice. All rights reserved.
+//
+
+#import "stopWatch.h"
+
+@interface stopWatch ()
+
+@property NSTimeInterval lastInterval;
+@property int state;
+@property (weak, nonatomic) UIButton * startButton;
+@property (weak, nonatomic) UIButton * clearButton;
+@property (weak, nonatomic) UILabel * timeLabel;
+
+@end
+
+@implementation stopWatch
+@synthesize startButton = _startButton;
+@synthesize clearButton = _clearButton;
+@synthesize timeLabel = _timeLabel;
+
+@synthesize lastInterval = _lastInterval;
+
+- (stopWatch *) init
+{
+ self = [super init];
+ self.state = TIMER_STATE_CLEARED;
+ self.set = NO;
+ return self;
+}
+
+- (stopWatch *) initWithStartButton:(UIButton *)startButton
+ ClearButton:(UIButton *)clearButton
+ TimeLabel:(UILabel *)timeLabel
+{
+ self = [self init];
+
+ self.startButton = startButton;
+ self.clearButton = clearButton;
+ self.timeLabel = timeLabel;
+
+ [self setupActions];
+ return self;
+}
+
+- (void) setupWithTableViewCell:(UITableViewCell *)cell
+{
+ self.startButton = (UIButton *)[cell viewWithTag:2];
+ self.clearButton = (UIButton *)[cell viewWithTag:3];
+ self.timeLabel = (UILabel *)[cell viewWithTag:1];
+
+ [self setupActions];
+}
+
+- (void) setupActions
+{
+ [self.startButton addTarget:self action:@selector(start) forControlEvents:UIControlEventTouchUpInside];
+ [self.clearButton addTarget:self action:@selector(clear) forControlEvents:UIControlEventTouchUpInside];
+ self.set = YES;
+}
+
+- (void)updateTimer
+{
+ // Create date from the elapsed time
+ NSDate *currentDate = [NSDate date];
+ NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate:self.startDate] + self.lastInterval;
+ NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
+
+ // Create a date formatter
+ NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
+ [dateFormatter setDateFormat:@"HH:mm:ss"];
+ [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
+
+ // Format the elapsed time and set it to the label
+ NSString *timeString = [dateFormatter stringFromDate:timerDate];
+ self.timeLabel.text = timeString;
+}
+
+
+- (void) start
+{
+ switch (self.state) {
+ case TIMER_STATE_RUNNING:
+ self.state = TIMER_STATE_PAUSED;
+ [self.stopWatchTimer invalidate];
+ self.lastInterval += [[NSDate date] timeIntervalSinceDate:self.startDate];
+ break;
+ case TIMER_STATE_PAUSED:
+ self.state = TIMER_STATE_RUNNING;
+ self.startDate = [NSDate date];
+ self.stopWatchTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/10.0
+ target:self
+ selector:@selector(updateTimer)
+ userInfo:nil
+ repeats:YES];
+ break;
+ case TIMER_STATE_CLEARED:
+ self.state = TIMER_STATE_RUNNING;
+ self.startDate = [NSDate date];
+ // Create the stop watch timer that fires every 100 ms
+ self.stopWatchTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/10.0
+ target:self
+ selector:@selector(updateTimer)
+ userInfo:nil
+ repeats:YES];
+ break;
+ default:
+ break;
+ }
+
+ [self updateStartButtonIcon];
+}
+
+- (void) updateStartButtonIcon
+{
+ switch (self.state) {
+ case TIMER_STATE_RUNNING:
+ [self.startButton setImage:[UIImage imageNamed:@"timer_pause_btn"] forState:UIControlStateNormal];
+ break;
+ case TIMER_STATE_PAUSED:
+ [self.startButton setImage:[UIImage imageNamed:@"timer_resume_btn"] forState:UIControlStateNormal];
+ break;
+ case TIMER_STATE_CLEARED:
+ [self.startButton setImage:[UIImage imageNamed:@"timer_start_btn"] forState:UIControlStateNormal];
+ break;
+ default:
+ break;
+ }
+}
+
+- (void) clear
+{
+ [self.stopWatchTimer invalidate];
+ self.stopWatchTimer = nil;
+ self.startDate = [NSDate date];
+ self.lastInterval = 0;
+ self.state = TIMER_STATE_CLEARED;
+
+ [self.startButton setImage:[UIImage imageNamed:@"timer_start_btn"] forState:UIControlStateNormal];
+ [self updateTimer];
+}
+
+@end
+
diff --git a/ios/iosremote/iosremote_ipad_icon.png b/ios/iosremote/iosremote_ipad_icon.png
new file mode 100644
index 000000000000..859d53a87941
Binary files /dev/null and b/ios/iosremote/iosremote_ipad_icon.png differ
diff --git a/ios/iosremote/iosremote_ipad_icon@2x.png b/ios/iosremote/iosremote_ipad_icon@2x.png
new file mode 100644
index 000000000000..9c1da2a53a8d
Binary files /dev/null and b/ios/iosremote/iosremote_ipad_icon@2x.png differ
diff --git a/ios/iosremote/iosremote_iphone_icon.png b/ios/iosremote/iosremote_iphone_icon.png
new file mode 100644
index 000000000000..e976b082bc01
Binary files /dev/null and b/ios/iosremote/iosremote_iphone_icon.png differ
diff --git a/ios/iosremote/iosremote_iphone_icon@2x.png b/ios/iosremote/iosremote_iphone_icon@2x.png
new file mode 100644
index 000000000000..cb045bc0cf56
Binary files /dev/null and b/ios/iosremote/iosremote_iphone_icon@2x.png differ
diff --git a/ios/iosremote/libO_icon.png b/ios/iosremote/libO_icon.png
new file mode 100644
index 000000000000..34bd3dbbb3aa
Binary files /dev/null and b/ios/iosremote/libO_icon.png differ
diff --git a/ios/iosremote/nextButton_normal.png b/ios/iosremote/nextButton_normal.png
new file mode 100644
index 000000000000..b3a48886da66
Binary files /dev/null and b/ios/iosremote/nextButton_normal.png differ
diff --git a/ios/iosremote/nextButton_normal@2x.png b/ios/iosremote/nextButton_normal@2x.png
new file mode 100644
index 000000000000..dbe6dbd58a04
Binary files /dev/null and b/ios/iosremote/nextButton_normal@2x.png differ
diff --git a/ios/iosremote/nextButton_pressed.png b/ios/iosremote/nextButton_pressed.png
new file mode 100644
index 000000000000..8ed46c1c5171
Binary files /dev/null and b/ios/iosremote/nextButton_pressed.png differ
diff --git a/ios/iosremote/nextButton_pressed@2x.png b/ios/iosremote/nextButton_pressed@2x.png
new file mode 100644
index 000000000000..48e5b3184a01
Binary files /dev/null and b/ios/iosremote/nextButton_pressed@2x.png differ
diff --git a/ios/iosremote/previousButton_normal.png b/ios/iosremote/previousButton_normal.png
new file mode 100644
index 000000000000..6292ac9acb0f
Binary files /dev/null and b/ios/iosremote/previousButton_normal.png differ
diff --git a/ios/iosremote/previousButton_normal@2x.png b/ios/iosremote/previousButton_normal@2x.png
new file mode 100644
index 000000000000..b8f2ac7fd9b3
Binary files /dev/null and b/ios/iosremote/previousButton_normal@2x.png differ
diff --git a/ios/iosremote/previousButton_pressed.png b/ios/iosremote/previousButton_pressed.png
new file mode 100644
index 000000000000..5759e70bc6bf
Binary files /dev/null and b/ios/iosremote/previousButton_pressed.png differ
diff --git a/ios/iosremote/previousButton_pressed@2x.png b/ios/iosremote/previousButton_pressed@2x.png
new file mode 100644
index 000000000000..7c10564226e0
Binary files /dev/null and b/ios/iosremote/previousButton_pressed@2x.png differ
diff --git a/ios/iosremote/slideshowRail.png b/ios/iosremote/slideshowRail.png
new file mode 100644
index 000000000000..db4a03cae739
Binary files /dev/null and b/ios/iosremote/slideshowRail.png differ
diff --git a/ios/iosremote/slideshowRail@2x.png b/ios/iosremote/slideshowRail@2x.png
new file mode 100644
index 000000000000..f736b58ad81a
Binary files /dev/null and b/ios/iosremote/slideshowRail@2x.png differ