[Libreoffice-commits] core.git: 4 commits - ios/.DS_Store ios/iosremote

siqi me at siqi.fr
Thu Jul 4 01:11:28 PDT 2013


 ios/.DS_Store                                                                                                    |binary
 ios/iosremote/.DS_Store                                                                                          |binary
 ios/iosremote/iosremote.xcodeproj/project.pbxproj                                                                |   18 
 ios/iosremote/iosremote.xcodeproj/project.xcworkspace/contents.xcworkspacedata                                   |    7 
 ios/iosremote/iosremote.xcodeproj/project.xcworkspace/xcuserdata/siqi.xcuserdatad/UserInterfaceState.xcuserstate |binary
 ios/iosremote/iosremote.xcodeproj/project.xcworkspace/xcuserdata/siqi.xcuserdatad/WorkspaceSettings.xcsettings   |   10 
 ios/iosremote/iosremote.xcodeproj/xcuserdata/siqi.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist                  |   33 +
 ios/iosremote/iosremote.xcodeproj/xcuserdata/siqi.xcuserdatad/xcschemes/iosremote.xcscheme                       |   86 +++
 ios/iosremote/iosremote.xcodeproj/xcuserdata/siqi.xcuserdatad/xcschemes/xcschememanagement.plist                 |   22 
 ios/iosremote/iosremote/.DS_Store                                                                                |binary
 ios/iosremote/iosremote/Communication/CommunicationManager.h                                                     |    6 
 ios/iosremote/iosremote/Communication/CommunicationManager.m                                                     |   31 -
 ios/iosremote/iosremote/EditableTableViewCell.h                                                                  |   14 
 ios/iosremote/iosremote/EditableTableViewCell.m                                                                  |   54 +
 ios/iosremote/iosremote/en.lproj/MainStoryboard_iPad.storyboard                                                  |   22 
 ios/iosremote/iosremote/en.lproj/MainStoryboard_iPhone.storyboard                                                |  137 ++++-
 ios/iosremote/iosremote/main.m                                                                                   |    1 
 ios/iosremote/iosremote/newServer_vc.h                                                                           |   38 +
 ios/iosremote/iosremote/newServer_vc.m                                                                           |  273 ++++++++++
 ios/iosremote/iosremote/server_list_vc.h                                                                         |   15 
 ios/iosremote/iosremote/server_list_vc.m                                                                         |   92 +++
 21 files changed, 823 insertions(+), 36 deletions(-)

New commits:
commit 0f4348f49b864d13c6381d4d2dc4d1af4ab618fb
Author: siqi <me at siqi.fr>
Date:   Thu Jul 4 10:07:51 2013 +0200

    minor
    
    Change-Id: I200cfda3c086177b6c43347afa6e794d5f74054f

diff --git a/ios/iosremote/iosremote.xcodeproj/project.xcworkspace/xcuserdata/siqi.xcuserdatad/UserInterfaceState.xcuserstate b/ios/iosremote/iosremote.xcodeproj/project.xcworkspace/xcuserdata/siqi.xcuserdatad/UserInterfaceState.xcuserstate
index 318fb69..7941e44 100644
Binary files a/ios/iosremote/iosremote.xcodeproj/project.xcworkspace/xcuserdata/siqi.xcuserdatad/UserInterfaceState.xcuserstate and b/ios/iosremote/iosremote.xcodeproj/project.xcworkspace/xcuserdata/siqi.xcuserdatad/UserInterfaceState.xcuserstate differ
commit 56abd1316a66a90d20efa5478cc9407fa0275aeb
Author: siqi <me at siqi.fr>
Date:   Wed Jul 3 17:14:46 2013 +0200

    iphone storyboard
    
    Change-Id: I79b2b6bc078a1c12cb3793ae38e494f705a62b50

diff --git a/ios/iosremote/iosremote.xcodeproj/project.pbxproj b/ios/iosremote/iosremote.xcodeproj/project.pbxproj
index bd554ee..3a3ba14 100644
--- a/ios/iosremote/iosremote.xcodeproj/project.pbxproj
+++ b/ios/iosremote/iosremote.xcodeproj/project.pbxproj
@@ -38,10 +38,6 @@
 		5753DD8F1781EA0300DB71BB /* server_list_vc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = server_list_vc.m; sourceTree = "<group>"; };
 		5753DD9717834D7100DB71BB /* newServer_vc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = newServer_vc.h; sourceTree = "<group>"; };
 		5753DD9817834D7100DB71BB /* newServer_vc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = newServer_vc.m; sourceTree = "<group>"; };
-		5753DD9A1783851700DB71BB /* TPKeyboardAvoidingScrollView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TPKeyboardAvoidingScrollView.h; path = iosremote/TPKeyboardAvoidingScrollView.h; sourceTree = "<group>"; };
-		5753DD9B1783851700DB71BB /* TPKeyboardAvoidingScrollView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = TPKeyboardAvoidingScrollView.m; path = iosremote/TPKeyboardAvoidingScrollView.m; sourceTree = "<group>"; };
-		5753DD9C1783851700DB71BB /* TPKeyboardAvoidingTableView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TPKeyboardAvoidingTableView.h; path = iosremote/TPKeyboardAvoidingTableView.h; sourceTree = "<group>"; };
-		5753DD9D1783851700DB71BB /* TPKeyboardAvoidingTableView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = TPKeyboardAvoidingTableView.m; path = iosremote/TPKeyboardAvoidingTableView.m; sourceTree = "<group>"; };
 		57B152971764703500EECC67 /* Base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Base64.h; path = iosremote/Base64.h; sourceTree = "<group>"; };
 		57B152981764703500EECC67 /* Base64.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Base64.m; path = iosremote/Base64.m; sourceTree = "<group>"; };
 		57B1529A1764714900EECC67 /* slideShowViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = slideShowViewController.h; sourceTree = "<group>"; };
@@ -101,10 +97,6 @@
 				BE9EBD061765BF0800283FD2 /* CoreImage.framework */,
 				57B152971764703500EECC67 /* Base64.h */,
 				57B152981764703500EECC67 /* Base64.m */,
-				5753DD9A1783851700DB71BB /* TPKeyboardAvoidingScrollView.h */,
-				5753DD9B1783851700DB71BB /* TPKeyboardAvoidingScrollView.m */,
-				5753DD9C1783851700DB71BB /* TPKeyboardAvoidingTableView.h */,
-				5753DD9D1783851700DB71BB /* TPKeyboardAvoidingTableView.m */,
 				57C6E425175E076900E8BC5F /* Communication */,
 				57C6E3F8175E06E800E8BC5F /* iosremote */,
 				57C6E3F1175E06E800E8BC5F /* Frameworks */,
diff --git a/ios/iosremote/iosremote.xcodeproj/project.xcworkspace/xcuserdata/siqi.xcuserdatad/UserInterfaceState.xcuserstate b/ios/iosremote/iosremote.xcodeproj/project.xcworkspace/xcuserdata/siqi.xcuserdatad/UserInterfaceState.xcuserstate
index 15c1493..318fb69 100644
Binary files a/ios/iosremote/iosremote.xcodeproj/project.xcworkspace/xcuserdata/siqi.xcuserdatad/UserInterfaceState.xcuserstate and b/ios/iosremote/iosremote.xcodeproj/project.xcworkspace/xcuserdata/siqi.xcuserdatad/UserInterfaceState.xcuserstate differ
commit 5da2c45328aa0d064a267348e13cfda4606d76ef
Author: siqi <me at siqi.fr>
Date:   Wed Jul 3 17:09:52 2013 +0200

    iphone storyboard
    
    Change-Id: I08ffe80fc228997b8a6618248116b52506100a79

diff --git a/ios/iosremote/iosremote.xcodeproj/project.xcworkspace/xcuserdata/siqi.xcuserdatad/UserInterfaceState.xcuserstate b/ios/iosremote/iosremote.xcodeproj/project.xcworkspace/xcuserdata/siqi.xcuserdatad/UserInterfaceState.xcuserstate
index 37b2f77..15c1493 100644
Binary files a/ios/iosremote/iosremote.xcodeproj/project.xcworkspace/xcuserdata/siqi.xcuserdatad/UserInterfaceState.xcuserstate and b/ios/iosremote/iosremote.xcodeproj/project.xcworkspace/xcuserdata/siqi.xcuserdatad/UserInterfaceState.xcuserstate differ
diff --git a/ios/iosremote/iosremote/.DS_Store b/ios/iosremote/iosremote/.DS_Store
index 46c9bed..2d76c56 100644
Binary files a/ios/iosremote/iosremote/.DS_Store and b/ios/iosremote/iosremote/.DS_Store differ
diff --git a/ios/iosremote/iosremote/EditableTableViewController.h b/ios/iosremote/iosremote/EditableTableViewController.h
deleted file mode 100755
index b9a473d..0000000
--- a/ios/iosremote/iosremote/EditableTableViewController.h
+++ /dev/null
@@ -1,64 +0,0 @@
-
-#import <UIKit/UIKit.h>
-#import "MyListController.h"
-
- at class Book;
- at class EditableTableViewCell;
-
-//  Constants representing the book's fields.
-//
-enum {
-    BookTitle,
-    BookLastName,
-    BookFirstName,
-    BookYear,
-    BookImagePath
-};
-
-//  Constants representing the various sections of our grouped table view.
-//
-enum {
-    TitleSection,
-    AuthorSection,
-    YearSection,
-    ImageSection
-};
-
-typedef NSUInteger BookAttribute;
-
- at interface MyDetailController : UITableViewController <UITextFieldDelegate>
-{
-    Book *_book;
-    MyListController *_listController;
-    EditableDetailCell *_titleCell;
-    EditableDetailCell *_firstNameCell;
-    EditableDetailCell *_lastNameCell;
-    EditableDetailCell *_yearCell;
-    EditableDetailCell *_imagePathCell;
-}
-
- at property (nonatomic, retain) Book *book;
-
-//  Watch out for retain cycles (objects that retain each other can never
-//  be deallocated). If the list controller were to retain the detail controller,
-//  we should change 'retain' to 'assign' below to avoid a cycle. (Note that in
-//  that case, dealloc shouldn't release the list controller.)
-//
- at property (nonatomic, retain) MyListController *listController;
-
- at property (nonatomic, retain) EditableDetailCell *titleCell;
- at property (nonatomic, retain) EditableDetailCell *firstNameCell;
- at property (nonatomic, retain) EditableDetailCell *lastNameCell;
- at property (nonatomic, retain) EditableDetailCell *yearCell;
- at property (nonatomic, retain) EditableDetailCell *imagePathCell;
-
-- (BOOL)isModal;
-
-- (EditableDetailCell *)newDetailCellWithTag:(NSInteger)tag;
-
-//  Action Methods
-//
-- (void)save;
-- (void)cancel;
-
- at end
diff --git a/ios/iosremote/iosremote/TPKeyboardAvoidingScrollView.h b/ios/iosremote/iosremote/TPKeyboardAvoidingScrollView.h
deleted file mode 100755
index ffecaa2..0000000
--- a/ios/iosremote/iosremote/TPKeyboardAvoidingScrollView.h
+++ /dev/null
@@ -1,14 +0,0 @@
-//
-//  TPKeyboardAvoidingScrollView.h
-//
-//  Created by Michael Tyson on 11/04/2011.
-//  Copyright 2011 A Tasty Pixel. All rights reserved.
-//
-
-#import <UIKit/UIKit.h>
-
- at interface TPKeyboardAvoidingScrollView : UIScrollView
- at property (assign, nonatomic) BOOL autoAdjustsContentSizeToBounds;
-- (BOOL)focusNextTextField;
-- (void)scrollToActiveTextField;
- at end
diff --git a/ios/iosremote/iosremote/TPKeyboardAvoidingScrollView.m b/ios/iosremote/iosremote/TPKeyboardAvoidingScrollView.m
deleted file mode 100755
index 5970f02..0000000
--- a/ios/iosremote/iosremote/TPKeyboardAvoidingScrollView.m
+++ /dev/null
@@ -1,285 +0,0 @@
-//
-//  TPKeyboardAvoidingScrollView.m
-//
-//  Created by Michael Tyson on 11/04/2011.
-//  Copyright 2011 A Tasty Pixel. All rights reserved.
-//
-
-#import "TPKeyboardAvoidingScrollView.h"
-
-#define _UIKeyboardFrameEndUserInfoKey (&UIKeyboardFrameEndUserInfoKey != NULL ? UIKeyboardFrameEndUserInfoKey : @"UIKeyboardBoundsUserInfoKey")
-
- at interface TPKeyboardAvoidingScrollView () <UITextFieldDelegate, UITextViewDelegate> {
-    UIEdgeInsets    _priorInset;
-    BOOL            _priorInsetSaved;
-    BOOL            _keyboardVisible;
-    CGRect          _keyboardRect;
-    CGSize          _originalContentSize;
-}
-- (UIView*)findFirstResponderBeneathView:(UIView*)view;
-- (UIEdgeInsets)contentInsetForKeyboard;
-- (CGFloat)idealOffsetForView:(UIView *)view withSpace:(CGFloat)space;
-- (CGRect)keyboardRect;
- at end
-
- at implementation TPKeyboardAvoidingScrollView
-
-#pragma mark - Setup/Teardown
-
-- (void)setup {
-    _priorInsetSaved = NO;
-    if ( CGSizeEqualToSize(self.contentSize, CGSizeZero) ) {
-        self.contentSize = self.bounds.size;
-    }
-    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
-    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
-}
-
--(id)initWithFrame:(CGRect)frame {
-    if ( !(self = [super initWithFrame:frame]) ) return nil;
-    [self setup];
-    return self;
-}
-
--(void)awakeFromNib {
-    [self setup];
-}
-
--(void)dealloc {
-    [[NSNotificationCenter defaultCenter] removeObserver:self];
-#if !__has_feature(objc_arc)
-    [super dealloc];
-#endif
-}
-
--(void)setFrame:(CGRect)frame {
-    [super setFrame:frame];
-    
-    [self handleContentSize];
-}
-
--(void)setContentSize:(CGSize)contentSize {
-    _originalContentSize = contentSize;
-    
-    [self handleContentSize];
-}
-
--(void)setAutoAdjustsContentSizeToBounds:(BOOL)autoAdjustsContentSizeToBounds {
-    _autoAdjustsContentSizeToBounds = autoAdjustsContentSizeToBounds;
-    
-    [self handleContentSize];
-}
-
-#pragma mark - Responders, events
-
-- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
-    [[self findFirstResponderBeneathView:self] resignFirstResponder];
-    [super touchesEnded:touches withEvent:event];
-}
-
-- (void)keyboardWillShow:(NSNotification*)notification {
-    _keyboardRect = [[[notification userInfo] objectForKey:_UIKeyboardFrameEndUserInfoKey] CGRectValue];
-    _keyboardVisible = YES;
-    
-    UIView *firstResponder = [self findFirstResponderBeneathView:self];
-    if ( !firstResponder ) {
-        // No child view is the first responder - nothing to do here
-        return;
-    }
-    
-    if (!_priorInsetSaved) {
-        _priorInset = self.contentInset;
-        _priorInsetSaved = YES;
-    }
-    
-    // Shrink view's inset by the keyboard's height, and scroll to show the text field/view being edited
-    [UIView beginAnimations:nil context:NULL];
-    [UIView setAnimationCurve:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
-    [UIView setAnimationDuration:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue]];
-    
-    self.contentInset = [self contentInsetForKeyboard];
-    [self setContentOffset:CGPointMake(self.contentOffset.x,
-                                       [self idealOffsetForView:firstResponder withSpace:[self keyboardRect].origin.y - self.bounds.origin.y])
-                  animated:YES];
-    [self setScrollIndicatorInsets:self.contentInset];
-    
-    [UIView commitAnimations];
-}
-
-- (void)keyboardWillHide:(NSNotification*)notification {
-    _keyboardRect = CGRectZero;
-    _keyboardVisible = NO;
-    
-    // Restore dimensions to prior size
-    [UIView beginAnimations:nil context:NULL];
-    [UIView setAnimationCurve:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
-    [UIView setAnimationDuration:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue]];
-    self.contentInset = _priorInset;
-    [self setScrollIndicatorInsets:self.contentInset];
-    _priorInsetSaved = NO;
-    [UIView commitAnimations];
-}
-
--(BOOL)textFieldShouldReturn:(UITextField *)textField {
-    if ( ![self focusNextTextField] ) {
-        [textField resignFirstResponder];
-    }
-    return YES;
-}
-
--(void)textFieldDidBeginEditing:(UITextField *)textField {
-    [self scrollToActiveTextField];
-}
-
--(void)textViewDidBeginEditing:(UITextView *)textView {
-    [self scrollToActiveTextField];
-}
-
--(void)layoutSubviews {
-    [super layoutSubviews];
-    [self initializeViewsBeneathView:self];
-}
-
-#pragma mark - Utilities
-
-- (BOOL)focusNextTextField {
-    UIView *firstResponder = [self findFirstResponderBeneathView:self];
-    if ( !firstResponder ) {
-        return NO;
-    }
-    
-    CGFloat minY = CGFLOAT_MAX;
-    UIView *view = nil;
-    [self findTextFieldAfterTextField:firstResponder beneathView:self minY:&minY foundView:&view];
-    
-    if ( view ) {
-        [view becomeFirstResponder];
-        return YES;
-    }
-    
-    return NO;
-}
-
--(void)scrollToActiveTextField {
-    if ( !_keyboardVisible ) return;
-    
-    CGFloat visibleSpace = self.bounds.size.height - self.contentInset.top - self.contentInset.bottom;
-    
-    CGPoint idealOffset = CGPointMake(0, [self idealOffsetForView:[self findFirstResponderBeneathView:self] withSpace:visibleSpace]);
-    
-    [self setContentOffset:idealOffset animated:YES];
-}
-
-#pragma mark - Helpers
-
--(void)handleContentSize {
-    CGSize contentSize = _autoAdjustsContentSizeToBounds ? self.bounds.size : _originalContentSize;
-    contentSize.width = MAX(contentSize.width, self.frame.size.width);
-    contentSize.height = MAX(contentSize.height, self.frame.size.height);
-    [super setContentSize:contentSize];
-    
-    if ( _keyboardVisible ) {
-        self.contentInset = [self contentInsetForKeyboard];
-    }
-}
-
-- (UIView*)findFirstResponderBeneathView:(UIView*)view {
-    // Search recursively for first responder
-    for ( UIView *childView in view.subviews ) {
-        if ( [childView respondsToSelector:@selector(isFirstResponder)] && [childView isFirstResponder] ) return childView;
-        UIView *result = [self findFirstResponderBeneathView:childView];
-        if ( result ) return result;
-    }
-    return nil;
-}
-
-- (void)findTextFieldAfterTextField:(UIView*)priorTextField beneathView:(UIView*)view minY:(CGFloat*)minY foundView:(UIView**)foundView {
-    // Search recursively for text field or text view below priorTextField
-    CGFloat priorFieldOffset = CGRectGetMinY([self convertRect:priorTextField.frame fromView:priorTextField.superview]);
-    for ( UIView *childView in view.subviews ) {
-        if ( childView.hidden ) continue;
-        if ( ([childView isKindOfClass:[UITextField class]] || [childView isKindOfClass:[UITextView class]]) ) {
-            CGRect frame = [self convertRect:childView.frame fromView:view];
-            if ( childView != priorTextField && CGRectGetMinY(frame) >= priorFieldOffset && CGRectGetMinY(frame) < *minY ) {
-                *minY = CGRectGetMinY(frame);
-                *foundView = childView;
-            }
-        } else {
-            [self findTextFieldAfterTextField:priorTextField beneathView:childView minY:minY foundView:foundView];
-        }
-    }
-}
-
-- (void)initializeViewsBeneathView:(UIView*)view {
-    for ( UIView *childView in view.subviews ) {
-        if ( ([childView isKindOfClass:[UITextField class]] || [childView isKindOfClass:[UITextView class]]) ) {
-            [self initializeView:childView];
-        } else {
-            [self initializeViewsBeneathView:childView];
-        }
-    }
-}
-
-- (UIEdgeInsets)contentInsetForKeyboard {
-    UIEdgeInsets newInset = self.contentInset;
-    CGRect keyboardRect = [self keyboardRect];
-    newInset.bottom = keyboardRect.size.height - ((keyboardRect.origin.y+keyboardRect.size.height) - (self.bounds.origin.y+self.bounds.size.height));
-    return newInset;
-}
-
--(CGFloat)idealOffsetForView:(UIView *)view withSpace:(CGFloat)space {
-    
-    // Convert the rect to get the view's distance from the top of the scrollView.
-    CGRect rect = [view convertRect:view.bounds toView:self];
-    
-    // Set starting offset to that point
-    CGFloat offset = rect.origin.y;
-    
-    
-    if ( self.contentSize.height - offset < space ) {
-        // Scroll to the bottom
-        offset = self.contentSize.height - space;
-    } else {
-        if ( view.bounds.size.height < space ) {
-            // Center vertically if there's room
-            offset -= floor((space-view.bounds.size.height)/2.0);
-        }
-        if ( offset + space > self.contentSize.height ) {
-            // Clamp to content size
-            offset = self.contentSize.height - space;
-        }
-    }
-    
-    if (offset < 0) offset = 0;
-    
-    return offset;
-}
-
-- (CGRect)keyboardRect {
-    CGRect keyboardRect = [self convertRect:_keyboardRect fromView:nil];
-    if ( keyboardRect.origin.y == 0 ) {
-        CGRect screenBounds = [self convertRect:[UIScreen mainScreen].bounds fromView:nil];
-        keyboardRect.origin = CGPointMake(0, screenBounds.size.height - keyboardRect.size.height);
-    }
-    return keyboardRect;
-}
-
-- (void)initializeView:(UIView*)view {
-    if ( ([view isKindOfClass:[UITextField class]] || [view isKindOfClass:[UITextView class]]) && (![(id)view delegate] || [(id)view delegate] == self) ) {
-        [(id)view setDelegate:self];
-        
-        if ( [view isKindOfClass:[UITextField class]] ) {
-            UIView *otherView = nil;
-            CGFloat minY = CGFLOAT_MAX;
-            [self findTextFieldAfterTextField:view beneathView:self minY:&minY foundView:&otherView];
-            
-            if ( otherView ) {
-                ((UITextField*)view).returnKeyType = UIReturnKeyNext;
-            } else {
-                ((UITextField*)view).returnKeyType = UIReturnKeyDone;
-            }
-        }
-    }
-}
-
- at end
diff --git a/ios/iosremote/iosremote/TPKeyboardAvoidingTableView.h b/ios/iosremote/iosremote/TPKeyboardAvoidingTableView.h
deleted file mode 100755
index 7f2949c..0000000
--- a/ios/iosremote/iosremote/TPKeyboardAvoidingTableView.h
+++ /dev/null
@@ -1,13 +0,0 @@
-//
-//  TPKeyboardAvoidingTableView.h
-//
-//  Created by Michael Tyson on 11/04/2011.
-//  Copyright 2011 A Tasty Pixel. All rights reserved.
-//
-
-#import <UIKit/UIKit.h>
-
- at interface TPKeyboardAvoidingTableView : UITableView
-- (BOOL)focusNextTextField;
-- (void)scrollToActiveTextField;
- at end
diff --git a/ios/iosremote/iosremote/TPKeyboardAvoidingTableView.m b/ios/iosremote/iosremote/TPKeyboardAvoidingTableView.m
deleted file mode 100755
index 8d08c2a..0000000
--- a/ios/iosremote/iosremote/TPKeyboardAvoidingTableView.m
+++ /dev/null
@@ -1,284 +0,0 @@
-//
-//  TPKeyboardAvoidingTableView.m
-//
-//  Created by Michael Tyson on 11/04/2011.
-//  Copyright 2011 A Tasty Pixel. All rights reserved.
-//
-
-#import "TPKeyboardAvoidingTableView.h"
-
-#define _UIKeyboardFrameEndUserInfoKey (&UIKeyboardFrameEndUserInfoKey != NULL ? UIKeyboardFrameEndUserInfoKey : @"UIKeyboardBoundsUserInfoKey")
-
- at interface TPKeyboardAvoidingTableView () <UITextFieldDelegate, UITextViewDelegate> {
-    UIEdgeInsets    _priorInset;
-    BOOL            _priorInsetSaved;
-    BOOL            _keyboardVisible;
-    CGRect          _keyboardRect;
-    CGSize          _originalContentSize;
-}
-- (UIView*)findFirstResponderBeneathView:(UIView*)view;
-- (UIEdgeInsets)contentInsetForKeyboard;
-- (CGFloat)idealOffsetForView:(UIView *)view withSpace:(CGFloat)space;
-- (CGRect)keyboardRect;
- at end
-
- at implementation TPKeyboardAvoidingTableView
-
-#pragma mark - Setup/Teardown
-
-- (void)setup {
-    _priorInsetSaved = NO;
-    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
-    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
-}
-
--(id)initWithFrame:(CGRect)frame {
-    if ( !(self = [super initWithFrame:frame]) ) return nil;
-    [self setup];
-    return self;
-}
-
--(id)initWithFrame:(CGRect)frame style:(UITableViewStyle)withStyle {
-    if ( !(self = [super initWithFrame:frame style:withStyle]) ) return nil;
-    [self setup];
-    return self;
-}
-
--(void)awakeFromNib {
-    [self setup];
-}
-
--(void)dealloc {
-    [[NSNotificationCenter defaultCenter] removeObserver:self];
-#if !__has_feature(objc_arc)
-    [super dealloc];
-#endif
-}
-
--(void)setFrame:(CGRect)frame {
-    [super setFrame:frame];
-    
-    CGSize contentSize = _originalContentSize;
-    contentSize.width = MAX(contentSize.width, self.frame.size.width);
-    contentSize.height = MAX(contentSize.height, self.frame.size.height);
-    [super setContentSize:contentSize];
-    
-    if ( _keyboardVisible ) {
-        self.contentInset = [self contentInsetForKeyboard];
-    }
-}
-
--(void)setContentSize:(CGSize)contentSize {
-    _originalContentSize = contentSize;
-    
-    contentSize.width = MAX(contentSize.width, self.frame.size.width);
-    contentSize.height = MAX(contentSize.height, self.frame.size.height);
-    [super setContentSize:contentSize];
-    
-    if ( _keyboardVisible ) {
-        self.contentInset = [self contentInsetForKeyboard];
-    }
-}
-
-#pragma mark - Responders, events
-
-- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
-    [[self findFirstResponderBeneathView:self] resignFirstResponder];
-    [super touchesEnded:touches withEvent:event];
-}
-
-- (void)keyboardWillShow:(NSNotification*)notification {
-    _keyboardRect = [[[notification userInfo] objectForKey:_UIKeyboardFrameEndUserInfoKey] CGRectValue];
-    _keyboardVisible = YES;
-    
-    UIView *firstResponder = [self findFirstResponderBeneathView:self];
-    if ( !firstResponder ) {
-        // No child view is the first responder - nothing to do here
-        return;
-    }
-    
-    if (!_priorInsetSaved) {
-        _priorInset = self.contentInset;
-        _priorInsetSaved = YES;
-    }
-    
-    // Shrink view's inset by the keyboard's height, and scroll to show the text field/view being edited
-    [UIView beginAnimations:nil context:NULL];
-    [UIView setAnimationCurve:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
-    [UIView setAnimationDuration:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue]];
-    
-    self.contentInset = [self contentInsetForKeyboard];
-    [self setContentOffset:CGPointMake(self.contentOffset.x,
-                                       [self idealOffsetForView:firstResponder withSpace:[self keyboardRect].origin.y - self.bounds.origin.y])
-                  animated:YES];
-    [self setScrollIndicatorInsets:self.contentInset];
-    
-    [UIView commitAnimations];
-}
-
-- (void)keyboardWillHide:(NSNotification*)notification {
-    _keyboardRect = CGRectZero;
-    _keyboardVisible = NO;
-    
-    // Restore dimensions to prior size
-    [UIView beginAnimations:nil context:NULL];
-    [UIView setAnimationCurve:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
-    [UIView setAnimationDuration:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue]];
-    self.contentInset = _priorInset;
-    [self setScrollIndicatorInsets:self.contentInset];
-    _priorInsetSaved = NO;
-    [UIView commitAnimations];
-}
-
--(BOOL)textFieldShouldReturn:(UITextField *)textField {
-    if ( ![self focusNextTextField] ) {
-        [textField resignFirstResponder];
-    }
-    return YES;
-}
-
--(void)textFieldDidBeginEditing:(UITextField *)textField {
-    [self scrollToActiveTextField];
-}
-
--(void)textViewDidBeginEditing:(UITextView *)textView {
-    [self scrollToActiveTextField];
-}
-
--(void)layoutSubviews {
-    [super layoutSubviews];
-    [self initializeViewsBeneathView:self];
-}
-
-#pragma mark - Utilities
-
-- (BOOL)focusNextTextField {
-    UIView *firstResponder = [self findFirstResponderBeneathView:self];
-    if ( !firstResponder ) {
-        return NO;
-    }
-    
-    CGFloat minY = CGFLOAT_MAX;
-    UIView *view = nil;
-    [self findTextFieldAfterTextField:firstResponder beneathView:self minY:&minY foundView:&view];
-    
-    if ( view ) {
-        [view becomeFirstResponder];
-        return YES;
-    }
-    
-    return NO;
-}
-
--(void)scrollToActiveTextField {
-    if ( !_keyboardVisible ) return;
-    
-    CGFloat visibleSpace = self.bounds.size.height - self.contentInset.top - self.contentInset.bottom;
-    
-    CGPoint idealOffset = CGPointMake(0, [self idealOffsetForView:[self findFirstResponderBeneathView:self] withSpace:visibleSpace]);
-    
-    [self setContentOffset:idealOffset animated:YES];
-}
-
-#pragma mark - Helpers
-
-- (UIView*)findFirstResponderBeneathView:(UIView*)view {
-    // Search recursively for first responder
-    for ( UIView *childView in view.subviews ) {
-        if ( [childView respondsToSelector:@selector(isFirstResponder)] && [childView isFirstResponder] ) return childView;
-        UIView *result = [self findFirstResponderBeneathView:childView];
-        if ( result ) return result;
-    }
-    return nil;
-}
-
-- (void)findTextFieldAfterTextField:(UIView*)priorTextField beneathView:(UIView*)view minY:(CGFloat*)minY foundView:(UIView**)foundView {
-    // Search recursively for text field or text view below priorTextField
-    CGFloat priorFieldOffset = CGRectGetMinY([self convertRect:priorTextField.frame fromView:priorTextField.superview]);
-    for ( UIView *childView in view.subviews ) {
-        if ( childView.hidden ) continue;
-        if ( ([childView isKindOfClass:[UITextField class]] || [childView isKindOfClass:[UITextView class]]) ) {
-            CGRect frame = [self convertRect:childView.frame fromView:view];
-            if ( childView != priorTextField && CGRectGetMinY(frame) >= priorFieldOffset && CGRectGetMinY(frame) < *minY ) {
-                *minY = CGRectGetMinY(frame);
-                *foundView = childView;
-            }
-        } else {
-            [self findTextFieldAfterTextField:priorTextField beneathView:childView minY:minY foundView:foundView];
-        }
-    }
-}
-
-- (void)initializeViewsBeneathView:(UIView*)view {
-    for ( UIView *childView in view.subviews ) {
-        if ( ([childView isKindOfClass:[UITextField class]] || [childView isKindOfClass:[UITextView class]]) ) {
-            [self initializeView:childView];
-        } else {
-            [self initializeViewsBeneathView:childView];
-        }
-    }
-}
-
-- (UIEdgeInsets)contentInsetForKeyboard {
-    UIEdgeInsets newInset = self.contentInset;
-    CGRect keyboardRect = [self keyboardRect];
-    newInset.bottom = keyboardRect.size.height - ((keyboardRect.origin.y+keyboardRect.size.height) - (self.bounds.origin.y+self.bounds.size.height));
-    return newInset;
-}
-
--(CGFloat)idealOffsetForView:(UIView *)view withSpace:(CGFloat)space {
-    
-    // Convert the rect to get the view's distance from the top of the scrollView.
-    CGRect rect = [view convertRect:view.bounds toView:self];
-    
-    // Set starting offset to that point
-    CGFloat offset = rect.origin.y;
-    
-    
-    if ( self.contentSize.height - offset < space ) {
-        // Scroll to the bottom
-        offset = self.contentSize.height - space;
-    } else {
-        if ( view.bounds.size.height < space ) {
-            // Center vertically if there's room
-            offset -= floor((space-view.bounds.size.height)/2.0);
-        }
-        if ( offset + space > self.contentSize.height ) {
-            // Clamp to content size
-            offset = self.contentSize.height - space;
-        }
-    }
-    
-    if (offset < 0) offset = 0;
-    
-    return offset;
-}
-
-- (CGRect)keyboardRect {
-    CGRect keyboardRect = [self convertRect:_keyboardRect fromView:nil];
-    if ( keyboardRect.origin.y == 0 ) {
-        CGRect screenBounds = [self convertRect:[UIScreen mainScreen].bounds fromView:nil];
-        keyboardRect.origin = CGPointMake(0, screenBounds.size.height - keyboardRect.size.height);
-    }
-    return keyboardRect;
-}
-
-- (void)initializeView:(UIView*)view {
-    if ( ([view isKindOfClass:[UITextField class]] || [view isKindOfClass:[UITextView class]]) && (![(id)view delegate] || [(id)view delegate] == self) ) {
-        [(id)view setDelegate:self];
-        
-        if ( [view isKindOfClass:[UITextField class]] ) {
-            UIView *otherView = nil;
-            CGFloat minY = CGFLOAT_MAX;
-            [self findTextFieldAfterTextField:view beneathView:self minY:&minY foundView:&otherView];
-            
-            if ( otherView ) {
-                ((UITextField*)view).returnKeyType = UIReturnKeyNext;
-            } else {
-                ((UITextField*)view).returnKeyType = UIReturnKeyDone;
-            }
-        }
-    }
-}
-
- at end
commit 5d0b5f6f42ff4766e937f7d55f5fcb694e2eb0ce
Author: siqi <me at siqi.fr>
Date:   Wed Jul 3 17:08:22 2013 +0200

    iphone storyboard
    
    Change-Id: I67f93d812ab856578378bb891b44f55c06ca7421

diff --git a/ios/.DS_Store b/ios/.DS_Store
new file mode 100644
index 0000000..4e262b1
Binary files /dev/null and b/ios/.DS_Store differ
diff --git a/ios/iosremote/.DS_Store b/ios/iosremote/.DS_Store
new file mode 100644
index 0000000..2997260
Binary files /dev/null and b/ios/iosremote/.DS_Store differ
diff --git a/ios/iosremote/iosremote.xcodeproj/project.pbxproj b/ios/iosremote/iosremote.xcodeproj/project.pbxproj
index 7fa842c..bd554ee 100644
--- a/ios/iosremote/iosremote.xcodeproj/project.pbxproj
+++ b/ios/iosremote/iosremote.xcodeproj/project.pbxproj
@@ -7,6 +7,8 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
+		5753DD901781EA0300DB71BB /* server_list_vc.m in Sources */ = {isa = PBXBuildFile; fileRef = 5753DD8F1781EA0300DB71BB /* server_list_vc.m */; };
+		5753DD9917834D7100DB71BB /* newServer_vc.m in Sources */ = {isa = PBXBuildFile; fileRef = 5753DD9817834D7100DB71BB /* newServer_vc.m */; };
 		57B152991764703500EECC67 /* Base64.m in Sources */ = {isa = PBXBuildFile; fileRef = 57B152981764703500EECC67 /* Base64.m */; };
 		57B1529C1764714900EECC67 /* slideShowViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 57B1529B1764714900EECC67 /* slideShowViewController.m */; };
 		57B1529F176486C300EECC67 /* CommandTransmitter.m in Sources */ = {isa = PBXBuildFile; fileRef = 57B1529E176486C300EECC67 /* CommandTransmitter.m */; };
@@ -27,10 +29,19 @@
 		57C6E42F175E076900E8BC5F /* CommunicationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 57C6E429175E076900E8BC5F /* CommunicationManager.m */; };
 		57C6E430175E076900E8BC5F /* CommandInterpreter.m in Sources */ = {isa = PBXBuildFile; fileRef = 57C6E42B175E076900E8BC5F /* CommandInterpreter.m */; };
 		57C6E431175E076900E8BC5F /* Server.m in Sources */ = {isa = PBXBuildFile; fileRef = 57C6E42D175E076900E8BC5F /* Server.m */; };
+		57CFED9917838FDC00E82E05 /* EditableTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 57CFED9817838FDC00E82E05 /* EditableTableViewCell.m */; };
 		BE9EBD071765BF0800283FD2 /* CoreImage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BE9EBD061765BF0800283FD2 /* CoreImage.framework */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
+		5753DD8E1781EA0300DB71BB /* server_list_vc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = server_list_vc.h; sourceTree = "<group>"; };
+		5753DD8F1781EA0300DB71BB /* server_list_vc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = server_list_vc.m; sourceTree = "<group>"; };
+		5753DD9717834D7100DB71BB /* newServer_vc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = newServer_vc.h; sourceTree = "<group>"; };
+		5753DD9817834D7100DB71BB /* newServer_vc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = newServer_vc.m; sourceTree = "<group>"; };
+		5753DD9A1783851700DB71BB /* TPKeyboardAvoidingScrollView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TPKeyboardAvoidingScrollView.h; path = iosremote/TPKeyboardAvoidingScrollView.h; sourceTree = "<group>"; };
+		5753DD9B1783851700DB71BB /* TPKeyboardAvoidingScrollView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = TPKeyboardAvoidingScrollView.m; path = iosremote/TPKeyboardAvoidingScrollView.m; sourceTree = "<group>"; };
+		5753DD9C1783851700DB71BB /* TPKeyboardAvoidingTableView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TPKeyboardAvoidingTableView.h; path = iosremote/TPKeyboardAvoidingTableView.h; sourceTree = "<group>"; };
+		5753DD9D1783851700DB71BB /* TPKeyboardAvoidingTableView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = TPKeyboardAvoidingTableView.m; path = iosremote/TPKeyboardAvoidingTableView.m; sourceTree = "<group>"; };
 		57B152971764703500EECC67 /* Base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Base64.h; path = iosremote/Base64.h; sourceTree = "<group>"; };
 		57B152981764703500EECC67 /* Base64.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Base64.m; path = iosremote/Base64.m; sourceTree = "<group>"; };
 		57B1529A1764714900EECC67 /* slideShowViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = slideShowViewController.h; sourceTree = "<group>"; };
@@ -64,6 +75,8 @@
 		57C6E42B175E076900E8BC5F /* CommandInterpreter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CommandInterpreter.m; sourceTree = "<group>"; };
 		57C6E42C175E076900E8BC5F /* Server.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Server.h; sourceTree = "<group>"; };
 		57C6E42D175E076900E8BC5F /* Server.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Server.m; sourceTree = "<group>"; };
+		57CFED9717838FDC00E82E05 /* EditableTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EditableTableViewCell.h; sourceTree = "<group>"; };
+		57CFED9817838FDC00E82E05 /* EditableTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EditableTableViewCell.m; sourceTree = "<group>"; };
 		BE9EBD061765BF0800283FD2 /* CoreImage.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreImage.framework; path = System/Library/Frameworks/CoreImage.framework; sourceTree = SDKROOT; };
 /* End PBXFileReference section */
 
@@ -88,6 +101,10 @@
 				BE9EBD061765BF0800283FD2 /* CoreImage.framework */,
 				57B152971764703500EECC67 /* Base64.h */,
 				57B152981764703500EECC67 /* Base64.m */,
+				5753DD9A1783851700DB71BB /* TPKeyboardAvoidingScrollView.h */,
+				5753DD9B1783851700DB71BB /* TPKeyboardAvoidingScrollView.m */,
+				5753DD9C1783851700DB71BB /* TPKeyboardAvoidingTableView.h */,
+				5753DD9D1783851700DB71BB /* TPKeyboardAvoidingTableView.m */,
 				57C6E425175E076900E8BC5F /* Communication */,
 				57C6E3F8175E06E800E8BC5F /* iosremote */,
 				57C6E3F1175E06E800E8BC5F /* Frameworks */,
@@ -119,12 +136,18 @@
 				57C6E401175E06E800E8BC5F /* libreoffice_sdremoteAppDelegate.h */,
 				57C6E402175E06E800E8BC5F /* libreoffice_sdremoteAppDelegate.m */,
 				57C6E40A175E06E800E8BC5F /* MainStoryboard_iPhone.storyboard */,
+				5753DD9717834D7100DB71BB /* newServer_vc.h */,
+				5753DD9817834D7100DB71BB /* newServer_vc.m */,
+				5753DD8E1781EA0300DB71BB /* server_list_vc.h */,
+				5753DD8F1781EA0300DB71BB /* server_list_vc.m */,
 				57C6E40D175E06E800E8BC5F /* MainStoryboard_iPad.storyboard */,
 				57C6E410175E06E800E8BC5F /* libreoffice_sdremoteViewController.h */,
 				57C6E411175E06E800E8BC5F /* libreoffice_sdremoteViewController.m */,
 				57C6E3F9175E06E800E8BC5F /* Supporting Files */,
 				57B1529A1764714900EECC67 /* slideShowViewController.h */,
 				57B1529B1764714900EECC67 /* slideShowViewController.m */,
+				57CFED9717838FDC00E82E05 /* EditableTableViewCell.h */,
+				57CFED9817838FDC00E82E05 /* EditableTableViewCell.m */,
 			);
 			path = iosremote;
 			sourceTree = "<group>";
@@ -242,6 +265,9 @@
 				57B152991764703500EECC67 /* Base64.m in Sources */,
 				57B1529C1764714900EECC67 /* slideShowViewController.m in Sources */,
 				57B1529F176486C300EECC67 /* CommandTransmitter.m in Sources */,
+				5753DD901781EA0300DB71BB /* server_list_vc.m in Sources */,
+				5753DD9917834D7100DB71BB /* newServer_vc.m in Sources */,
+				57CFED9917838FDC00E82E05 /* EditableTableViewCell.m in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
diff --git a/ios/iosremote/iosremote.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/iosremote/iosremote.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..130b46b
--- /dev/null
+++ b/ios/iosremote/iosremote.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+   version = "1.0">
+   <FileRef
+      location = "self:iosremote.xcodeproj">
+   </FileRef>
+</Workspace>
diff --git a/ios/iosremote/iosremote.xcodeproj/project.xcworkspace/xcuserdata/siqi.xcuserdatad/UserInterfaceState.xcuserstate b/ios/iosremote/iosremote.xcodeproj/project.xcworkspace/xcuserdata/siqi.xcuserdatad/UserInterfaceState.xcuserstate
new file mode 100644
index 0000000..37b2f77
Binary files /dev/null and b/ios/iosremote/iosremote.xcodeproj/project.xcworkspace/xcuserdata/siqi.xcuserdatad/UserInterfaceState.xcuserstate differ
diff --git a/ios/iosremote/iosremote.xcodeproj/project.xcworkspace/xcuserdata/siqi.xcuserdatad/WorkspaceSettings.xcsettings b/ios/iosremote/iosremote.xcodeproj/project.xcworkspace/xcuserdata/siqi.xcuserdatad/WorkspaceSettings.xcsettings
new file mode 100644
index 0000000..659c876
--- /dev/null
+++ b/ios/iosremote/iosremote.xcodeproj/project.xcworkspace/xcuserdata/siqi.xcuserdatad/WorkspaceSettings.xcsettings
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges</key>
+	<true/>
+	<key>SnapshotAutomaticallyBeforeSignificantChanges</key>
+	<true/>
+</dict>
+</plist>
diff --git a/ios/iosremote/iosremote.xcodeproj/xcuserdata/siqi.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist b/ios/iosremote/iosremote.xcodeproj/xcuserdata/siqi.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist
new file mode 100644
index 0000000..8060e63
--- /dev/null
+++ b/ios/iosremote/iosremote.xcodeproj/xcuserdata/siqi.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Bucket
+   type = "1"
+   version = "1.0">
+   <FileBreakpoints>
+      <FileBreakpoint
+         shouldBeEnabled = "No"
+         ignoreCount = "0"
+         continueAfterRunningActions = "No"
+         filePath = "iosremote/libreoffice_sdremoteViewController.m"
+         timestampString = "393022219.861088"
+         startingColumnNumber = "9223372036854775807"
+         endingColumnNumber = "9223372036854775807"
+         startingLineNumber = "47"
+         endingLineNumber = "47"
+         landmarkName = "@implementation libreoffice_sdremoteViewController"
+         landmarkType = "3">
+      </FileBreakpoint>
+      <FileBreakpoint
+         shouldBeEnabled = "No"
+         ignoreCount = "0"
+         continueAfterRunningActions = "No"
+         filePath = "iosremote/Communication/SlideShow.m"
+         timestampString = "393177884.882194"
+         startingColumnNumber = "9223372036854775807"
+         endingColumnNumber = "9223372036854775807"
+         startingLineNumber = "57"
+         endingLineNumber = "57"
+         landmarkName = "-init"
+         landmarkType = "5">
+      </FileBreakpoint>
+   </FileBreakpoints>
+</Bucket>
diff --git a/ios/iosremote/iosremote.xcodeproj/xcuserdata/siqi.xcuserdatad/xcschemes/iosremote.xcscheme b/ios/iosremote/iosremote.xcodeproj/xcuserdata/siqi.xcuserdatad/xcschemes/iosremote.xcscheme
new file mode 100644
index 0000000..bb82040
--- /dev/null
+++ b/ios/iosremote/iosremote.xcodeproj/xcuserdata/siqi.xcuserdatad/xcschemes/iosremote.xcscheme
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   LastUpgradeVersion = "0460"
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "57C6E3EE175E06E800E8BC5F"
+               BuildableName = "iosremote.app"
+               BlueprintName = "iosremote"
+               ReferencedContainer = "container:iosremote.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      buildConfiguration = "Debug">
+      <Testables>
+      </Testables>
+      <MacroExpansion>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "57C6E3EE175E06E800E8BC5F"
+            BuildableName = "iosremote.app"
+            BlueprintName = "iosremote"
+            ReferencedContainer = "container:iosremote.xcodeproj">
+         </BuildableReference>
+      </MacroExpansion>
+   </TestAction>
+   <LaunchAction
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      buildConfiguration = "Debug"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      allowLocationSimulation = "YES">
+      <BuildableProductRunnable>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "57C6E3EE175E06E800E8BC5F"
+            BuildableName = "iosremote.app"
+            BlueprintName = "iosremote"
+            ReferencedContainer = "container:iosremote.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+      <AdditionalOptions>
+      </AdditionalOptions>
+   </LaunchAction>
+   <ProfileAction
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      buildConfiguration = "Release"
+      debugDocumentVersioning = "YES">
+      <BuildableProductRunnable>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "57C6E3EE175E06E800E8BC5F"
+            BuildableName = "iosremote.app"
+            BlueprintName = "iosremote"
+            ReferencedContainer = "container:iosremote.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>
diff --git a/ios/iosremote/iosremote.xcodeproj/xcuserdata/siqi.xcuserdatad/xcschemes/xcschememanagement.plist b/ios/iosremote/iosremote.xcodeproj/xcuserdata/siqi.xcuserdatad/xcschemes/xcschememanagement.plist
new file mode 100644
index 0000000..74079c7
--- /dev/null
+++ b/ios/iosremote/iosremote.xcodeproj/xcuserdata/siqi.xcuserdatad/xcschemes/xcschememanagement.plist
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>SchemeUserState</key>
+	<dict>
+		<key>iosremote.xcscheme</key>
+		<dict>
+			<key>orderHint</key>
+			<integer>0</integer>
+		</dict>
+	</dict>
+	<key>SuppressBuildableAutocreation</key>
+	<dict>
+		<key>57C6E3EE175E06E800E8BC5F</key>
+		<dict>
+			<key>primary</key>
+			<true/>
+		</dict>
+	</dict>
+</dict>
+</plist>
diff --git a/ios/iosremote/iosremote/.DS_Store b/ios/iosremote/iosremote/.DS_Store
new file mode 100644
index 0000000..46c9bed
Binary files /dev/null and b/ios/iosremote/iosremote/.DS_Store differ
diff --git a/ios/iosremote/iosremote/Communication/CommunicationManager.h b/ios/iosremote/iosremote/Communication/CommunicationManager.h
index 8df7e09..7fe5451 100644
--- a/ios/iosremote/iosremote/Communication/CommunicationManager.h
+++ b/ios/iosremote/iosremote/Communication/CommunicationManager.h
@@ -51,12 +51,16 @@ enum ConnectionState : NSInteger {
     CONNECTED
 };
 
- at interface CommunicationManager : NSObject
+ at interface CommunicationManager : NSObject <UITableViewDataSource>
 
+- (id) initWithExistingServers;
 - (void) connectToServer:(Server*)server;
+- (void) addServersWithName:(NSString*)name
+                  AtAddress:(NSString*)addr;
 
 @property ConnectionState state;
 @property (nonatomic, strong) id delegate;
+ at property (atomic, strong) NSMutableArray* servers;
 @property (nonatomic, strong) CommandInterpreter* interpreter;
 @property (nonatomic, strong) CommandTransmitter* transmitter;
 
diff --git a/ios/iosremote/iosremote/Communication/CommunicationManager.m b/ios/iosremote/iosremote/Communication/CommunicationManager.m
index bd86180..701d4eb 100644
--- a/ios/iosremote/iosremote/Communication/CommunicationManager.m
+++ b/ios/iosremote/iosremote/Communication/CommunicationManager.m
@@ -19,7 +19,6 @@
 @interface CommunicationManager()
 
 @property (nonatomic, strong) Client* client;
- at property (atomic, strong) NSMutableSet* servers;
 @property (nonatomic, strong) id connectionConnectedObserver;
 @property (nonatomic, strong) id connectionDisconnectedObserver;
 
@@ -40,7 +39,6 @@
 + (CommunicationManager *)sharedComManager
 {
     static CommunicationManager *sharedComManager = nil;
-    
     static dispatch_once_t _singletonPredicate;
     
     dispatch_once(&_singletonPredicate, ^{
@@ -74,6 +72,7 @@
     self = [super init];
     self.state = DISCONNECTED;
     self.interpreter = [[CommandInterpreter alloc] init];
+    self.servers = [[NSMutableArray alloc] init];
     
     [[NSNotificationCenter defaultCenter]addObserver: self
                                             selector: @selector(connectionStatusHandler:)
@@ -103,10 +102,10 @@
     {
         NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingExistingServers];
         if (oldSavedArray != nil)
-            self.servers = [[NSMutableSet alloc] initWithArray:oldSavedArray];
+            self.servers = [[NSMutableArray alloc] initWithArray:oldSavedArray];
         else
-            self.servers = [[NSMutableSet alloc] init];
-    }
+            self.servers = [[NSMutableArray alloc] init];
+    } 
     return self;
 }
 
@@ -141,7 +140,29 @@
 }
 
 
+-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+    return [self.servers count];
+}
+
+-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+    
+    static NSString *cellIdentifier = @"server_item_cell";
+    
+    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
+    
+    Server *s = [self.servers objectAtIndex:indexPath.row];
 
+    [cell.textLabel setText:[s serverName]];
+    [cell.detailTextLabel setText:[s serverAddress]];
+    return cell;
+}
 
+- (void) addServersWithName:(NSString*)name
+                  AtAddress:(NSString*)addr
+{
+    Server * s = [[Server alloc] initWithProtocol:NETWORK atAddress:addr ofName:name];
+    [self.servers addObject:s];
+    NSLog(@"Having %lu servers now", (unsigned long)[self.servers count]);
+}
 
 @end
diff --git a/ios/iosremote/iosremote/EditableTableViewCell.h b/ios/iosremote/iosremote/EditableTableViewCell.h
new file mode 100644
index 0000000..6dd1666
--- /dev/null
+++ b/ios/iosremote/iosremote/EditableTableViewCell.h
@@ -0,0 +1,14 @@
+// -*- Mode: ObjC; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+//
+// 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 <UIKit/UIKit.h>
+
+ at interface EditableTableViewCell : UITableViewCell
+    @property (weak, nonatomic) UITextField * textField;
+    @property (weak, nonatomic) UILabel * inputLabel;
+ at end
diff --git a/ios/iosremote/iosremote/EditableTableViewCell.m b/ios/iosremote/iosremote/EditableTableViewCell.m
new file mode 100644
index 0000000..73199a0
--- /dev/null
+++ b/ios/iosremote/iosremote/EditableTableViewCell.m
@@ -0,0 +1,54 @@
+// -*- Mode: ObjC; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+//
+// 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 "EditableTableViewCell.h"
+
+ at implementation EditableTableViewCell
+
+ at synthesize inputLabel = _inputLabel;
+ at synthesize textField = _textField;
+
+- (id)initWithStyle:(UITableViewCellStyle)style
+    reuseIdentifier:(NSString *)identifier
+{
+    self = [super initWithStyle:style reuseIdentifier:identifier];
+    
+    if (self == nil)
+    {
+        return nil;
+    }
+    
+    CGRect bounds = [[self contentView] bounds];
+    CGRect rect = CGRectInset(bounds, 20.0, 10.0);
+    UITextField *textField = [[UITextField alloc] initWithFrame:rect];
+    
+    //  Set the keyboard's return key label to 'Next'.
+    //
+    [textField setReturnKeyType:UIReturnKeyNext];
+    
+    //  Make the clear button appear automatically.
+    [textField setClearButtonMode:UITextFieldViewModeWhileEditing];
+    [textField setOpaque:YES];
+    
+    [[self contentView] addSubview:textField];
+    [self setTextField:textField];
+    
+    return self;
+}
+
+//  Disable highlighting of currently selected cell.
+//
+- (void)setSelected:(BOOL)selected
+           animated:(BOOL)animated
+{
+    [super setSelected:selected animated:NO];
+    
+    [self setSelectionStyle:UITableViewCellSelectionStyleNone];
+}
+
+ at end
diff --git a/ios/iosremote/iosremote/EditableTableViewController.h b/ios/iosremote/iosremote/EditableTableViewController.h
new file mode 100755
index 0000000..b9a473d
--- /dev/null
+++ b/ios/iosremote/iosremote/EditableTableViewController.h
@@ -0,0 +1,64 @@
+
+#import <UIKit/UIKit.h>
+#import "MyListController.h"
+
+ at class Book;
+ at class EditableTableViewCell;
+
+//  Constants representing the book's fields.
+//
+enum {
+    BookTitle,
+    BookLastName,
+    BookFirstName,
+    BookYear,
+    BookImagePath
+};
+
+//  Constants representing the various sections of our grouped table view.
+//
+enum {
+    TitleSection,
+    AuthorSection,
+    YearSection,
+    ImageSection
+};
+
+typedef NSUInteger BookAttribute;
+
+ at interface MyDetailController : UITableViewController <UITextFieldDelegate>
+{
+    Book *_book;
+    MyListController *_listController;
+    EditableDetailCell *_titleCell;
+    EditableDetailCell *_firstNameCell;
+    EditableDetailCell *_lastNameCell;
+    EditableDetailCell *_yearCell;
+    EditableDetailCell *_imagePathCell;
+}
+
+ at property (nonatomic, retain) Book *book;
+
+//  Watch out for retain cycles (objects that retain each other can never
+//  be deallocated). If the list controller were to retain the detail controller,
+//  we should change 'retain' to 'assign' below to avoid a cycle. (Note that in
+//  that case, dealloc shouldn't release the list controller.)
+//
+ at property (nonatomic, retain) MyListController *listController;
+
+ at property (nonatomic, retain) EditableDetailCell *titleCell;
+ at property (nonatomic, retain) EditableDetailCell *firstNameCell;
+ at property (nonatomic, retain) EditableDetailCell *lastNameCell;
+ at property (nonatomic, retain) EditableDetailCell *yearCell;
+ at property (nonatomic, retain) EditableDetailCell *imagePathCell;
+
+- (BOOL)isModal;
+
+- (EditableDetailCell *)newDetailCellWithTag:(NSInteger)tag;
+
+//  Action Methods
+//
+- (void)save;
+- (void)cancel;
+
+ at end
diff --git a/ios/iosremote/iosremote/TPKeyboardAvoidingScrollView.h b/ios/iosremote/iosremote/TPKeyboardAvoidingScrollView.h
new file mode 100755
index 0000000..ffecaa2
--- /dev/null
+++ b/ios/iosremote/iosremote/TPKeyboardAvoidingScrollView.h
@@ -0,0 +1,14 @@
+//
+//  TPKeyboardAvoidingScrollView.h
+//
+//  Created by Michael Tyson on 11/04/2011.
+//  Copyright 2011 A Tasty Pixel. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+ at interface TPKeyboardAvoidingScrollView : UIScrollView
+ at property (assign, nonatomic) BOOL autoAdjustsContentSizeToBounds;
+- (BOOL)focusNextTextField;
+- (void)scrollToActiveTextField;
+ at end
diff --git a/ios/iosremote/iosremote/TPKeyboardAvoidingScrollView.m b/ios/iosremote/iosremote/TPKeyboardAvoidingScrollView.m
new file mode 100755
index 0000000..5970f02
--- /dev/null
+++ b/ios/iosremote/iosremote/TPKeyboardAvoidingScrollView.m
@@ -0,0 +1,285 @@
+//
+//  TPKeyboardAvoidingScrollView.m
+//
+//  Created by Michael Tyson on 11/04/2011.
+//  Copyright 2011 A Tasty Pixel. All rights reserved.
+//
+
+#import "TPKeyboardAvoidingScrollView.h"
+
+#define _UIKeyboardFrameEndUserInfoKey (&UIKeyboardFrameEndUserInfoKey != NULL ? UIKeyboardFrameEndUserInfoKey : @"UIKeyboardBoundsUserInfoKey")
+
+ at interface TPKeyboardAvoidingScrollView () <UITextFieldDelegate, UITextViewDelegate> {
+    UIEdgeInsets    _priorInset;
+    BOOL            _priorInsetSaved;
+    BOOL            _keyboardVisible;
+    CGRect          _keyboardRect;
+    CGSize          _originalContentSize;
+}
+- (UIView*)findFirstResponderBeneathView:(UIView*)view;
+- (UIEdgeInsets)contentInsetForKeyboard;
+- (CGFloat)idealOffsetForView:(UIView *)view withSpace:(CGFloat)space;
+- (CGRect)keyboardRect;
+ at end
+
+ at implementation TPKeyboardAvoidingScrollView
+
+#pragma mark - Setup/Teardown
+
+- (void)setup {
+    _priorInsetSaved = NO;
+    if ( CGSizeEqualToSize(self.contentSize, CGSizeZero) ) {
+        self.contentSize = self.bounds.size;
+    }
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
+}
+
+-(id)initWithFrame:(CGRect)frame {
+    if ( !(self = [super initWithFrame:frame]) ) return nil;
+    [self setup];
+    return self;
+}
+
+-(void)awakeFromNib {
+    [self setup];
+}
+
+-(void)dealloc {
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
+#if !__has_feature(objc_arc)
+    [super dealloc];
+#endif
+}
+
+-(void)setFrame:(CGRect)frame {
+    [super setFrame:frame];
+    
+    [self handleContentSize];
+}
+
+-(void)setContentSize:(CGSize)contentSize {
+    _originalContentSize = contentSize;
+    
+    [self handleContentSize];
+}
+
+-(void)setAutoAdjustsContentSizeToBounds:(BOOL)autoAdjustsContentSizeToBounds {
+    _autoAdjustsContentSizeToBounds = autoAdjustsContentSizeToBounds;
+    
+    [self handleContentSize];
+}
+
+#pragma mark - Responders, events
+
+- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
+    [[self findFirstResponderBeneathView:self] resignFirstResponder];
+    [super touchesEnded:touches withEvent:event];
+}
+
+- (void)keyboardWillShow:(NSNotification*)notification {
+    _keyboardRect = [[[notification userInfo] objectForKey:_UIKeyboardFrameEndUserInfoKey] CGRectValue];
+    _keyboardVisible = YES;
+    
+    UIView *firstResponder = [self findFirstResponderBeneathView:self];
+    if ( !firstResponder ) {
+        // No child view is the first responder - nothing to do here
+        return;
+    }
+    
+    if (!_priorInsetSaved) {
+        _priorInset = self.contentInset;
+        _priorInsetSaved = YES;
+    }
+    
+    // Shrink view's inset by the keyboard's height, and scroll to show the text field/view being edited
+    [UIView beginAnimations:nil context:NULL];
+    [UIView setAnimationCurve:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
+    [UIView setAnimationDuration:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue]];
+    
+    self.contentInset = [self contentInsetForKeyboard];
+    [self setContentOffset:CGPointMake(self.contentOffset.x,
+                                       [self idealOffsetForView:firstResponder withSpace:[self keyboardRect].origin.y - self.bounds.origin.y])
+                  animated:YES];
+    [self setScrollIndicatorInsets:self.contentInset];
+    
+    [UIView commitAnimations];
+}
+
+- (void)keyboardWillHide:(NSNotification*)notification {
+    _keyboardRect = CGRectZero;
+    _keyboardVisible = NO;
+    
+    // Restore dimensions to prior size
+    [UIView beginAnimations:nil context:NULL];
+    [UIView setAnimationCurve:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
+    [UIView setAnimationDuration:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue]];
+    self.contentInset = _priorInset;
+    [self setScrollIndicatorInsets:self.contentInset];
+    _priorInsetSaved = NO;
+    [UIView commitAnimations];
+}
+
+-(BOOL)textFieldShouldReturn:(UITextField *)textField {
+    if ( ![self focusNextTextField] ) {
+        [textField resignFirstResponder];
+    }
+    return YES;
+}
+
+-(void)textFieldDidBeginEditing:(UITextField *)textField {
+    [self scrollToActiveTextField];
+}
+
+-(void)textViewDidBeginEditing:(UITextView *)textView {
+    [self scrollToActiveTextField];
+}
+
+-(void)layoutSubviews {
+    [super layoutSubviews];
+    [self initializeViewsBeneathView:self];
+}
+
+#pragma mark - Utilities
+
+- (BOOL)focusNextTextField {
+    UIView *firstResponder = [self findFirstResponderBeneathView:self];
+    if ( !firstResponder ) {
+        return NO;
+    }
+    
+    CGFloat minY = CGFLOAT_MAX;
+    UIView *view = nil;
+    [self findTextFieldAfterTextField:firstResponder beneathView:self minY:&minY foundView:&view];
+    
+    if ( view ) {
+        [view becomeFirstResponder];
+        return YES;
+    }
+    
+    return NO;
+}
+
+-(void)scrollToActiveTextField {
+    if ( !_keyboardVisible ) return;
+    
+    CGFloat visibleSpace = self.bounds.size.height - self.contentInset.top - self.contentInset.bottom;
+    
+    CGPoint idealOffset = CGPointMake(0, [self idealOffsetForView:[self findFirstResponderBeneathView:self] withSpace:visibleSpace]);
+    
+    [self setContentOffset:idealOffset animated:YES];
+}
+
+#pragma mark - Helpers
+
+-(void)handleContentSize {
+    CGSize contentSize = _autoAdjustsContentSizeToBounds ? self.bounds.size : _originalContentSize;
+    contentSize.width = MAX(contentSize.width, self.frame.size.width);
+    contentSize.height = MAX(contentSize.height, self.frame.size.height);
+    [super setContentSize:contentSize];
+    
+    if ( _keyboardVisible ) {
+        self.contentInset = [self contentInsetForKeyboard];
+    }
+}
+
+- (UIView*)findFirstResponderBeneathView:(UIView*)view {
+    // Search recursively for first responder
+    for ( UIView *childView in view.subviews ) {
+        if ( [childView respondsToSelector:@selector(isFirstResponder)] && [childView isFirstResponder] ) return childView;
+        UIView *result = [self findFirstResponderBeneathView:childView];
+        if ( result ) return result;
+    }
+    return nil;
+}
+
+- (void)findTextFieldAfterTextField:(UIView*)priorTextField beneathView:(UIView*)view minY:(CGFloat*)minY foundView:(UIView**)foundView {
+    // Search recursively for text field or text view below priorTextField
+    CGFloat priorFieldOffset = CGRectGetMinY([self convertRect:priorTextField.frame fromView:priorTextField.superview]);
+    for ( UIView *childView in view.subviews ) {
+        if ( childView.hidden ) continue;
+        if ( ([childView isKindOfClass:[UITextField class]] || [childView isKindOfClass:[UITextView class]]) ) {
+            CGRect frame = [self convertRect:childView.frame fromView:view];
+            if ( childView != priorTextField && CGRectGetMinY(frame) >= priorFieldOffset && CGRectGetMinY(frame) < *minY ) {
+                *minY = CGRectGetMinY(frame);
+                *foundView = childView;
+            }
+        } else {
+            [self findTextFieldAfterTextField:priorTextField beneathView:childView minY:minY foundView:foundView];
+        }
+    }
+}
+
+- (void)initializeViewsBeneathView:(UIView*)view {
+    for ( UIView *childView in view.subviews ) {
+        if ( ([childView isKindOfClass:[UITextField class]] || [childView isKindOfClass:[UITextView class]]) ) {
+            [self initializeView:childView];
+        } else {
+            [self initializeViewsBeneathView:childView];
+        }
+    }
+}
+
+- (UIEdgeInsets)contentInsetForKeyboard {
+    UIEdgeInsets newInset = self.contentInset;
+    CGRect keyboardRect = [self keyboardRect];
+    newInset.bottom = keyboardRect.size.height - ((keyboardRect.origin.y+keyboardRect.size.height) - (self.bounds.origin.y+self.bounds.size.height));
+    return newInset;
+}
+
+-(CGFloat)idealOffsetForView:(UIView *)view withSpace:(CGFloat)space {
+    
+    // Convert the rect to get the view's distance from the top of the scrollView.
+    CGRect rect = [view convertRect:view.bounds toView:self];
+    
+    // Set starting offset to that point
+    CGFloat offset = rect.origin.y;
+    
+    
+    if ( self.contentSize.height - offset < space ) {
+        // Scroll to the bottom
+        offset = self.contentSize.height - space;
+    } else {
+        if ( view.bounds.size.height < space ) {
+            // Center vertically if there's room
+            offset -= floor((space-view.bounds.size.height)/2.0);
+        }
+        if ( offset + space > self.contentSize.height ) {
+            // Clamp to content size
+            offset = self.contentSize.height - space;
+        }
+    }
+    
+    if (offset < 0) offset = 0;
+    
+    return offset;
+}
+
+- (CGRect)keyboardRect {
+    CGRect keyboardRect = [self convertRect:_keyboardRect fromView:nil];
+    if ( keyboardRect.origin.y == 0 ) {
+        CGRect screenBounds = [self convertRect:[UIScreen mainScreen].bounds fromView:nil];
+        keyboardRect.origin = CGPointMake(0, screenBounds.size.height - keyboardRect.size.height);
+    }
+    return keyboardRect;
+}
+
+- (void)initializeView:(UIView*)view {
+    if ( ([view isKindOfClass:[UITextField class]] || [view isKindOfClass:[UITextView class]]) && (![(id)view delegate] || [(id)view delegate] == self) ) {
+        [(id)view setDelegate:self];
+        
+        if ( [view isKindOfClass:[UITextField class]] ) {
+            UIView *otherView = nil;
+            CGFloat minY = CGFLOAT_MAX;
+            [self findTextFieldAfterTextField:view beneathView:self minY:&minY foundView:&otherView];
+            
+            if ( otherView ) {
+                ((UITextField*)view).returnKeyType = UIReturnKeyNext;
+            } else {
+                ((UITextField*)view).returnKeyType = UIReturnKeyDone;
+            }
+        }
+    }
+}
+
+ at end
diff --git a/ios/iosremote/iosremote/TPKeyboardAvoidingTableView.h b/ios/iosremote/iosremote/TPKeyboardAvoidingTableView.h
new file mode 100755
index 0000000..7f2949c
--- /dev/null
+++ b/ios/iosremote/iosremote/TPKeyboardAvoidingTableView.h
@@ -0,0 +1,13 @@
+//
+//  TPKeyboardAvoidingTableView.h
+//
+//  Created by Michael Tyson on 11/04/2011.
+//  Copyright 2011 A Tasty Pixel. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+ at interface TPKeyboardAvoidingTableView : UITableView
+- (BOOL)focusNextTextField;
+- (void)scrollToActiveTextField;
+ at end
diff --git a/ios/iosremote/iosremote/TPKeyboardAvoidingTableView.m b/ios/iosremote/iosremote/TPKeyboardAvoidingTableView.m
new file mode 100755
index 0000000..8d08c2a
--- /dev/null
+++ b/ios/iosremote/iosremote/TPKeyboardAvoidingTableView.m
@@ -0,0 +1,284 @@
+//
+//  TPKeyboardAvoidingTableView.m
+//
+//  Created by Michael Tyson on 11/04/2011.
+//  Copyright 2011 A Tasty Pixel. All rights reserved.
+//
+
+#import "TPKeyboardAvoidingTableView.h"
+
+#define _UIKeyboardFrameEndUserInfoKey (&UIKeyboardFrameEndUserInfoKey != NULL ? UIKeyboardFrameEndUserInfoKey : @"UIKeyboardBoundsUserInfoKey")
+
+ at interface TPKeyboardAvoidingTableView () <UITextFieldDelegate, UITextViewDelegate> {
+    UIEdgeInsets    _priorInset;
+    BOOL            _priorInsetSaved;
+    BOOL            _keyboardVisible;
+    CGRect          _keyboardRect;
+    CGSize          _originalContentSize;
+}
+- (UIView*)findFirstResponderBeneathView:(UIView*)view;
+- (UIEdgeInsets)contentInsetForKeyboard;
+- (CGFloat)idealOffsetForView:(UIView *)view withSpace:(CGFloat)space;
+- (CGRect)keyboardRect;
+ at end
+
+ at implementation TPKeyboardAvoidingTableView
+
+#pragma mark - Setup/Teardown
+
+- (void)setup {
+    _priorInsetSaved = NO;
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
+}
+
+-(id)initWithFrame:(CGRect)frame {
+    if ( !(self = [super initWithFrame:frame]) ) return nil;
+    [self setup];
+    return self;
+}
+
+-(id)initWithFrame:(CGRect)frame style:(UITableViewStyle)withStyle {
+    if ( !(self = [super initWithFrame:frame style:withStyle]) ) return nil;
+    [self setup];
+    return self;
+}
+
+-(void)awakeFromNib {
+    [self setup];
+}
+
+-(void)dealloc {
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
+#if !__has_feature(objc_arc)
+    [super dealloc];
+#endif
+}
+
+-(void)setFrame:(CGRect)frame {
+    [super setFrame:frame];
+    
+    CGSize contentSize = _originalContentSize;
+    contentSize.width = MAX(contentSize.width, self.frame.size.width);
+    contentSize.height = MAX(contentSize.height, self.frame.size.height);
+    [super setContentSize:contentSize];
+    
+    if ( _keyboardVisible ) {
+        self.contentInset = [self contentInsetForKeyboard];
+    }
+}
+
+-(void)setContentSize:(CGSize)contentSize {
+    _originalContentSize = contentSize;
+    
+    contentSize.width = MAX(contentSize.width, self.frame.size.width);
+    contentSize.height = MAX(contentSize.height, self.frame.size.height);
+    [super setContentSize:contentSize];
+    
+    if ( _keyboardVisible ) {
+        self.contentInset = [self contentInsetForKeyboard];
+    }
+}
+
+#pragma mark - Responders, events
+
+- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
+    [[self findFirstResponderBeneathView:self] resignFirstResponder];
+    [super touchesEnded:touches withEvent:event];
+}
+
+- (void)keyboardWillShow:(NSNotification*)notification {
+    _keyboardRect = [[[notification userInfo] objectForKey:_UIKeyboardFrameEndUserInfoKey] CGRectValue];
+    _keyboardVisible = YES;
+    
+    UIView *firstResponder = [self findFirstResponderBeneathView:self];
+    if ( !firstResponder ) {
+        // No child view is the first responder - nothing to do here
+        return;
+    }
+    
+    if (!_priorInsetSaved) {
+        _priorInset = self.contentInset;
+        _priorInsetSaved = YES;
+    }
+    
+    // Shrink view's inset by the keyboard's height, and scroll to show the text field/view being edited
+    [UIView beginAnimations:nil context:NULL];
+    [UIView setAnimationCurve:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
+    [UIView setAnimationDuration:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue]];
+    
+    self.contentInset = [self contentInsetForKeyboard];
+    [self setContentOffset:CGPointMake(self.contentOffset.x,
+                                       [self idealOffsetForView:firstResponder withSpace:[self keyboardRect].origin.y - self.bounds.origin.y])
+                  animated:YES];
+    [self setScrollIndicatorInsets:self.contentInset];
+    
+    [UIView commitAnimations];
+}
+
+- (void)keyboardWillHide:(NSNotification*)notification {
+    _keyboardRect = CGRectZero;
+    _keyboardVisible = NO;
+    
+    // Restore dimensions to prior size
+    [UIView beginAnimations:nil context:NULL];
+    [UIView setAnimationCurve:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
+    [UIView setAnimationDuration:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue]];
+    self.contentInset = _priorInset;
+    [self setScrollIndicatorInsets:self.contentInset];
+    _priorInsetSaved = NO;
+    [UIView commitAnimations];
+}
+
+-(BOOL)textFieldShouldReturn:(UITextField *)textField {
+    if ( ![self focusNextTextField] ) {
+        [textField resignFirstResponder];
+    }
+    return YES;
+}
+
+-(void)textFieldDidBeginEditing:(UITextField *)textField {
+    [self scrollToActiveTextField];
+}
+
+-(void)textViewDidBeginEditing:(UITextView *)textView {
+    [self scrollToActiveTextField];
+}
+
+-(void)layoutSubviews {
+    [super layoutSubviews];
+    [self initializeViewsBeneathView:self];
+}
+
+#pragma mark - Utilities
+
+- (BOOL)focusNextTextField {
+    UIView *firstResponder = [self findFirstResponderBeneathView:self];
+    if ( !firstResponder ) {
+        return NO;
+    }
+    
+    CGFloat minY = CGFLOAT_MAX;
+    UIView *view = nil;
+    [self findTextFieldAfterTextField:firstResponder beneathView:self minY:&minY foundView:&view];
+    
+    if ( view ) {
+        [view becomeFirstResponder];
+        return YES;
+    }
+    
+    return NO;
+}
+
+-(void)scrollToActiveTextField {
+    if ( !_keyboardVisible ) return;
+    
+    CGFloat visibleSpace = self.bounds.size.height - self.contentInset.top - self.contentInset.bottom;
+    
+    CGPoint idealOffset = CGPointMake(0, [self idealOffsetForView:[self findFirstResponderBeneathView:self] withSpace:visibleSpace]);
+    
+    [self setContentOffset:idealOffset animated:YES];
+}
+
+#pragma mark - Helpers
+
+- (UIView*)findFirstResponderBeneathView:(UIView*)view {
+    // Search recursively for first responder
+    for ( UIView *childView in view.subviews ) {
+        if ( [childView respondsToSelector:@selector(isFirstResponder)] && [childView isFirstResponder] ) return childView;
+        UIView *result = [self findFirstResponderBeneathView:childView];
+        if ( result ) return result;
+    }
+    return nil;
+}
+
+- (void)findTextFieldAfterTextField:(UIView*)priorTextField beneathView:(UIView*)view minY:(CGFloat*)minY foundView:(UIView**)foundView {
+    // Search recursively for text field or text view below priorTextField
+    CGFloat priorFieldOffset = CGRectGetMinY([self convertRect:priorTextField.frame fromView:priorTextField.superview]);
+    for ( UIView *childView in view.subviews ) {
+        if ( childView.hidden ) continue;
+        if ( ([childView isKindOfClass:[UITextField class]] || [childView isKindOfClass:[UITextView class]]) ) {
+            CGRect frame = [self convertRect:childView.frame fromView:view];
+            if ( childView != priorTextField && CGRectGetMinY(frame) >= priorFieldOffset && CGRectGetMinY(frame) < *minY ) {
+                *minY = CGRectGetMinY(frame);
+                *foundView = childView;
+            }
+        } else {
+            [self findTextFieldAfterTextField:priorTextField beneathView:childView minY:minY foundView:foundView];
+        }
+    }
+}
+
+- (void)initializeViewsBeneathView:(UIView*)view {
+    for ( UIView *childView in view.subviews ) {
+        if ( ([childView isKindOfClass:[UITextField class]] || [childView isKindOfClass:[UITextView class]]) ) {
+            [self initializeView:childView];
+        } else {
+            [self initializeViewsBeneathView:childView];
+        }
+    }
+}
+
+- (UIEdgeInsets)contentInsetForKeyboard {
+    UIEdgeInsets newInset = self.contentInset;
+    CGRect keyboardRect = [self keyboardRect];
+    newInset.bottom = keyboardRect.size.height - ((keyboardRect.origin.y+keyboardRect.size.height) - (self.bounds.origin.y+self.bounds.size.height));
+    return newInset;
+}
+
+-(CGFloat)idealOffsetForView:(UIView *)view withSpace:(CGFloat)space {
+    
+    // Convert the rect to get the view's distance from the top of the scrollView.
+    CGRect rect = [view convertRect:view.bounds toView:self];
+    
+    // Set starting offset to that point
+    CGFloat offset = rect.origin.y;
+    
+    
+    if ( self.contentSize.height - offset < space ) {
+        // Scroll to the bottom
+        offset = self.contentSize.height - space;
+    } else {
+        if ( view.bounds.size.height < space ) {
+            // Center vertically if there's room
+            offset -= floor((space-view.bounds.size.height)/2.0);
+        }
+        if ( offset + space > self.contentSize.height ) {
+            // Clamp to content size
+            offset = self.contentSize.height - space;
+        }
+    }
+    
+    if (offset < 0) offset = 0;
+    
+    return offset;
+}
+
+- (CGRect)keyboardRect {
+    CGRect keyboardRect = [self convertRect:_keyboardRect fromView:nil];
+    if ( keyboardRect.origin.y == 0 ) {
+        CGRect screenBounds = [self convertRect:[UIScreen mainScreen].bounds fromView:nil];
+        keyboardRect.origin = CGPointMake(0, screenBounds.size.height - keyboardRect.size.height);
+    }
+    return keyboardRect;
+}
+
+- (void)initializeView:(UIView*)view {
+    if ( ([view isKindOfClass:[UITextField class]] || [view isKindOfClass:[UITextView class]]) && (![(id)view delegate] || [(id)view delegate] == self) ) {
+        [(id)view setDelegate:self];
+        
+        if ( [view isKindOfClass:[UITextField class]] ) {
+            UIView *otherView = nil;
+            CGFloat minY = CGFLOAT_MAX;
+            [self findTextFieldAfterTextField:view beneathView:self minY:&minY foundView:&otherView];
+            
+            if ( otherView ) {
+                ((UITextField*)view).returnKeyType = UIReturnKeyNext;
+            } else {
+                ((UITextField*)view).returnKeyType = UIReturnKeyDone;
+            }
+        }
+    }
+}
+
+ at end
diff --git a/ios/iosremote/iosremote/en.lproj/MainStoryboard_iPad.storyboard b/ios/iosremote/iosremote/en.lproj/MainStoryboard_iPad.storyboard
index 8a373a5..9eab508 100644
--- a/ios/iosremote/iosremote/en.lproj/MainStoryboard_iPad.storyboard
+++ b/ios/iosremote/iosremote/en.lproj/MainStoryboard_iPad.storyboard
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="2.0" toolsVersion="3084" systemVersion="12E55" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" initialViewController="KFV-Ae-zm8">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="2.0" toolsVersion="3084" systemVersion="13A497d" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" initialViewController="KFV-Ae-zm8">
     <dependencies>
         <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="2083"/>
     </dependencies>
@@ -174,26 +174,6 @@
             <point key="canvasLocation" x="3804" y="-569"/>
         </scene>
     </scenes>
-    <classes>
-        <class className="libreoffice_sdremoteViewController" superclassName="UIViewController">
-            <source key="sourceIdentifier" type="project" relativePath="./Classes/libreoffice_sdremoteViewController.h"/>
-            <relationships>
-                <relationship kind="action" name="connectToServer:"/>
-                <relationship kind="action" name="startPresentation:"/>
-                <relationship kind="outlet" name="ipAddressTextEdit" candidateClass="UITextField"/>
-                <relationship kind="outlet" name="pinLabel" candidateClass="UILabel"/>
-            </relationships>
-        </class>
-        <class className="slideShowViewController" superclassName="UIViewController">
-            <source key="sourceIdentifier" type="project" relativePath="./Classes/slideShowViewController.h"/>
-            <relationships>
-                <relationship kind="action" name="nextSlide:"/>
-                <relationship kind="action" name="previousSlide:"/>
-                <relationship kind="outlet" name="image" candidateClass="UIImageView"/>
-                <relationship kind="outlet" name="lecturer_notes" candidateClass="UIWebView"/>
-            </relationships>
-        </class>
-    </classes>
     <simulatedMetricsContainer key="defaultSimulatedMetrics">
         <simulatedStatusBarMetrics key="statusBar" statusBarStyle="blackTranslucent"/>
         <simulatedOrientationMetrics key="orientation"/>
diff --git a/ios/iosremote/iosremote/en.lproj/MainStoryboard_iPhone.storyboard b/ios/iosremote/iosremote/en.lproj/MainStoryboard_iPhone.storyboard
index dd21c31..fd0b6cb 100644
--- a/ios/iosremote/iosremote/en.lproj/MainStoryboard_iPhone.storyboard
+++ b/ios/iosremote/iosremote/en.lproj/MainStoryboard_iPhone.storyboard
@@ -1,23 +1,142 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="2.0" toolsVersion="2519" systemVersion="12A206j" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="2">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="2.0" toolsVersion="3084" systemVersion="13A497d" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" initialViewController="qoG-TN-hN0">
     <dependencies>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="1856"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="2083"/>
     </dependencies>
     <scenes>
-        <!--class Prefix:identifier View Controller-->
+        <!--Server list vc - Connect-->
         <scene sceneID="5">
             <objects>
-                <viewController id="2" customClass="libreoffice_sdremoteViewController" sceneMemberID="viewController">
-                    <view key="view" contentMode="scaleToFill" id="3">
-                        <rect key="frame" x="0.0" y="20" width="320" height="460"/>
-                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
-                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
-                    </view>
+                <viewController id="2" customClass="server_list_vc" sceneMemberID="viewController">
+                    <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="naQ-T4-jWV">
+                        <rect key="frame" x="0.0" y="64" width="320" height="504"/>
+                        <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                        <prototypes>
+                            <tableViewCell contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="server_item_cell" textLabel="Rg3-PU-OuS" detailTextLabel="9Mc-gD-acc" style="IBUITableViewCellStyleValue1" id="Pvl-Uw-Ghs">
+                                <rect key="frame" x="0.0" y="22" width="320" height="44"/>
+                                <autoresizingMask key="autoresizingMask"/>
+                                <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
+                                    <rect key="frame" x="0.0" y="0.0" width="320" height="43"/>
+                                    <autoresizingMask key="autoresizingMask"/>
+                                    <subviews>
+                                        <label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" text="Title" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Rg3-PU-OuS">
+                                            <rect key="frame" x="10" y="11" width="35" height="21"/>
+                                            <fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
+                                            <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
+                                            <color key="highlightedColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                                        </label>
+                                        <label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" text="Detail" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="9Mc-gD-acc">
+                                            <rect key="frame" x="266" y="11" width="44" height="21"/>
+                                            <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                            <color key="textColor" red="0.21960784310000001" green="0.3294117647" blue="0.52941176469999995" alpha="1" colorSpace="calibratedRGB"/>
+                                            <color key="highlightedColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                                        </label>
+                                    </subviews>
+                                    <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
+                                </view>
+                            </tableViewCell>
+                        </prototypes>
+                    </tableView>
+                    <navigationItem key="navigationItem" title="Connect" id="yR1-m8-JWN">
+                        <barButtonItem key="rightBarButtonItem" systemItem="add" id="bHy-yX-SPg">
+                            <connections>
+                                <segue destination="maT-Bx-l5y" kind="push" identifier="create_new_server" id="UYr-8d-fk5"/>
+                            </connections>
+                        </barButtonItem>
+                    </navigationItem>
+                    <connections>
+                        <outlet property="serverTable" destination="naQ-T4-jWV" id="hd3-Vm-fk6"/>
+                    </connections>
                 </viewController>
                 <placeholder placeholderIdentifier="IBFirstResponder" id="4" sceneMemberID="firstResponder"/>
             </objects>
+            <point key="canvasLocation" x="689" y="-6"/>
+        </scene>
+        <!--New Server View Controller - New Server-->
+        <scene sceneID="tlJ-c5-Jp2">
+            <objects>
+                <tableViewController id="maT-Bx-l5y" customClass="newServerViewController" sceneMemberID="viewController">
+                    <tableView key="view" opaque="NO" clipsSubviews="YES" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="grouped" separatorStyle="singleLineEtched" rowHeight="44" sectionHeaderHeight="10" sectionFooterHeight="10" id="VUL-K7-xsS">
+                        <rect key="frame" x="0.0" y="64" width="320" height="504"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
+                        <sections>
+                            <tableViewSection footerTitle="Register a new server and remeber it for future connection" id="46W-NE-CYW">
+                                <cells>
+                                    <tableViewCell contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" id="EN9-tY-k4P" customClass="EditableTableViewCell">
+                                        <rect key="frame" x="0.0" y="10" width="320" height="45"/>
+                                        <autoresizingMask key="autoresizingMask"/>
+                                        <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
+                                            <rect key="frame" x="10" y="1" width="300" height="43"/>
+                                            <autoresizingMask key="autoresizingMask"/>
+                                            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
+                                        </view>
+                                    </tableViewCell>
+                                    <tableViewCell contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" id="qeE-95-2Gh" customClass="EditableTableViewCell">
+                                        <rect key="frame" x="0.0" y="55" width="320" height="45"/>
+                                        <autoresizingMask key="autoresizingMask"/>
+                                        <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
+                                            <rect key="frame" x="10" y="0.0" width="300" height="43"/>
+                                            <autoresizingMask key="autoresizingMask"/>
+                                            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
+                                        </view>
+                                    </tableViewCell>
+                                </cells>
+                            </tableViewSection>
+                        </sections>
+                        <connections>
+                            <outlet property="dataSource" destination="maT-Bx-l5y" id="B5v-aO-O0a"/>
+                            <outlet property="delegate" destination="maT-Bx-l5y" id="Q3h-jf-Kor"/>
+                        </connections>
+                    </tableView>
+                    <navigationItem key="navigationItem" title="New Server" id="qbR-M4-5O0">
+                        <barButtonItem key="rightBarButtonItem" systemItem="save" id="sqC-Fa-Vem">
+                            <connections>
+                                <action selector="save:" destination="maT-Bx-l5y" id="OtP-lO-h9g"/>
+                            </connections>
+                        </barButtonItem>
+                    </navigationItem>
+                </tableViewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="b5I-aN-vyr" userLabel="First Responder" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="1133" y="-6"/>
+        </scene>
+        <!--Navigation Controller-->
+        <scene sceneID="yRe-s4-oKK">
+            <objects>
+                <navigationController id="qoG-TN-hN0" sceneMemberID="viewController">
+                    <toolbarItems/>
+                    <navigationBar key="navigationBar" contentMode="scaleToFill" id="WJT-Yy-XZ0">
+                        <rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
+                        <autoresizingMask key="autoresizingMask"/>
+                    </navigationBar>
+                    <nil name="viewControllers"/>
+                    <connections>
+                        <segue destination="2" kind="relationship" relationship="rootViewController" id="Sds-4S-ZnU"/>
+                    </connections>
+                </navigationController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="f9j-Cw-dxh" userLabel="First Responder" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="202" y="-75"/>
         </scene>
     </scenes>
+    <classes>
+        <class className="EditableTableViewCell" superclassName="UITableViewCell">
+            <source key="sourceIdentifier" type="project" relativePath="./Classes/EditableTableViewCell.h"/>
+        </class>
+        <class className="newServerViewController" superclassName="UITableViewController">
+            <source key="sourceIdentifier" type="project" relativePath="./Classes/newServerViewController.h"/>
+            <relationships>
+                <relationship kind="action" name="save:"/>
+            </relationships>
+        </class>
+        <class className="server_list_vc" superclassName="UITableViewController">
+            <source key="sourceIdentifier" type="project" relativePath="./Classes/server_list_vc.h"/>
+            <relationships>
+                <relationship kind="outlet" name="serverTable" candidateClass="UITableView"/>
+            </relationships>
+        </class>
+    </classes>
     <simulatedMetricsContainer key="defaultSimulatedMetrics">
         <simulatedStatusBarMetrics key="statusBar"/>
         <simulatedOrientationMetrics key="orientation"/>
diff --git a/ios/iosremote/iosremote/main.m b/ios/iosremote/iosremote/main.m
index 126838a..60d8585 100644
--- a/ios/iosremote/iosremote/main.m
+++ b/ios/iosremote/iosremote/main.m
@@ -9,6 +9,7 @@
 #import <UIKit/UIKit.h>
 
 #import "libreoffice_sdremoteAppDelegate.h"
+#import "TPKeyboardAvoidingScrollView.h"
 
 int main(int argc, char *argv[])
 {
diff --git a/ios/iosremote/iosremote/newServer_vc.h b/ios/iosremote/iosremote/newServer_vc.h
new file mode 100644
index 0000000..6d725b5
--- /dev/null
+++ b/ios/iosremote/iosremote/newServer_vc.h
@@ -0,0 +1,38 @@
+
+#import <UIKit/UIKit.h>
+
+ at class Server;
+ at class EditableTableViewCell;
+ at class CommunicationManager;
+
+//  Constants representing the book's fields.
+//
+enum {
+    ServerName,
+    ServerAddr,
+    ServerStore
+};
+
+//  Constants representing the various sections of our grouped table view.
+//
+enum {
+    InformationSection
+};
+
+typedef NSUInteger ServerAttribute;
+
+ at interface newServerViewController : UITableViewController <UITextFieldDelegate>
+ at property (nonatomic, strong) Server *server;
+ at property (nonatomic, strong) EditableTableViewCell *nameCell;
+ at property (nonatomic, strong) EditableTableViewCell *addrCell;
+ at property (nonatomic, strong) CommunicationManager *comManager;
+- (IBAction)save:(id)sender;
+- (BOOL)isModal;
+
+- (EditableTableViewCell *)newDetailCellWithTag:(NSInteger)tag;
+
+//  Action Methods
+- (void)save;
+- (void)cancel;
+
+ at end
diff --git a/ios/iosremote/iosremote/newServer_vc.m b/ios/iosremote/iosremote/newServer_vc.m
new file mode 100644
index 0000000..64c9693
--- /dev/null
+++ b/ios/iosremote/iosremote/newServer_vc.m
@@ -0,0 +1,273 @@
+// -*- Mode: ObjC; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+//
+// 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 "newServer_vc.h"
+#import "CommunicationManager.h"
+#import "EditableTableViewCell.h"
+#import "Server.h"
+
+ at implementation newServerViewController
+
+ at synthesize server = _server;
+
+ at synthesize nameCell = _nameCell;
+ at synthesize addrCell = _addrCell;
+
+- (IBAction)save:(id)sender {
+    NSString *serverName = [self.nameCell.textField text];
+    NSString *serverAddr = [self.addrCell.textField text];
+    NSLog(@"New server name:%@ ip:%@", serverName, serverAddr);
+    [self.comManager addServersWithName:serverName AtAddress:serverAddr];
+    [self save];
+    [self.navigationController popViewControllerAnimated:YES];
+}
+
+- (BOOL)isModal
+{
+    NSArray *viewControllers = [[self navigationController] viewControllers];
+    UIViewController *rootViewController = [viewControllers objectAtIndex:0];
+    
+    return rootViewController == self;
+}
+
+- (EditableTableViewCell *)newDetailCellWithTag:(NSInteger)tag
+{
+    EditableTableViewCell *cell = [[EditableTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
+    
+    [[cell textField] setDelegate:self];
+    [[cell textField] setTag:tag];
+    
+    return cell;
+}
+
+#pragma mark -
+#pragma mark Action Methods
+
+- (void)save
+{
+    [self dismissModalViewControllerAnimated:YES];
+}
+
+- (void)cancel
+{
+    [self dismissModalViewControllerAnimated:YES];
+}
+
+#pragma mark -
+#pragma mark UIViewController Methods
+
+- (void)viewDidLoad
+{
+    //  If the user clicked the '+' button in the list view, we're
+    //  creating a new entry rather than modifying an existing one, so
+    //  we're in a modal nav controller. Modal nav controllers don't add
+    //  a back button to the nav bar; instead we'll add Save and
+    //  Cancel buttons.
+    //
+    if ([self isModal])
+    {
+        UIBarButtonItem *saveButton = [[UIBarButtonItem alloc]
+                                       initWithBarButtonSystemItem:UIBarButtonSystemItemSave
+                                       target:self
+                                       action:@selector(save)];
+        
+        [[self navigationItem] setRightBarButtonItem:saveButton];
+        
+        UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc]
+                                         initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
+                                         target:self
+                                         action:@selector(cancel)];
+        
+        [[self navigationItem] setLeftBarButtonItem:cancelButton];
+    }
+    self.comManager = [CommunicationManager sharedComManager];
+    [self setNameCell: [self newDetailCellWithTag:ServerName]];
+    [self setAddrCell: [self newDetailCellWithTag:ServerAddr]];
+}
+
+//  Override this method to automatically place the insertion point in the
+//  first field.
+//
+- (void)viewWillAppear:(BOOL)animated
+{
+    [super viewWillAppear:animated];
+    
+    NSUInteger indexes[] = { 0, 0 };
+    NSIndexPath *indexPath = [NSIndexPath indexPathWithIndexes:indexes
+                                                        length:2];
+    
+    EditableTableViewCell *cell = (EditableTableViewCell *)[[self tableView]
+                                                      cellForRowAtIndexPath:indexPath];
+    
+    [[cell textField] becomeFirstResponder];
+}
+
+//  Force textfields to resign firstResponder so that our implementation of
+//  -textFieldDidEndEditing: gets called. That will ensure that the current
+//  UI values are flushed to our model object before we return to the list view.
+//
+- (void)viewWillDisappear:(BOOL)animated
+{
+    [super viewWillDisappear:animated];
+    
+    for (NSUInteger section = 0; section < [[self tableView] numberOfSections]; section++)
+    {
+        for (NSUInteger row = 0; row < [[self tableView] numberOfRowsInSection:section]; row++)
+        {
+            NSUInteger indexes[] = { section, row };
+            NSIndexPath *indexPath = [NSIndexPath indexPathWithIndexes:indexes
+                                                                length:2];
+            
+            EditableTableViewCell *cell = (EditableTableViewCell *)[[self tableView]
+                                                              cellForRowAtIndexPath:indexPath];
+            if ([[cell textField] isFirstResponder])
+            {
+                [[cell textField] resignFirstResponder];
+            }
+        }
+    }
+}
+
+#pragma mark -
+#pragma mark UITextFieldDelegate Protocol
+
+//  Sets the label of the keyboard's return key to 'Done' when the insertion
+//  point moves to the table view's last field.
+//
+- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
+{
+    if ([textField tag] == ServerAddr)
+    {
+        [textField setReturnKeyType:UIReturnKeyDone];
+    }
+    
+    return YES;
+}
+
+//  UITextField sends this message to its delegate after resigning
+//  firstResponder status. Use this as a hook to save the text field's
+//  value to the corresponding property of the model object.
+//
+- (void)textFieldDidEndEditing:(UITextField *)textField
+{
+    static NSNumberFormatter *_formatter;
+    
+    if (_formatter == nil)
+    {
+        _formatter = [[NSNumberFormatter alloc] init];
+    }
+    
+    NSString *text = [textField text];
+    
+    switch ([textField tag])
+    {
+        case ServerName:     [self.server setServerName:text];          break;
+        case ServerAddr:  [self.server setServerAddress:text];       break;
+    }
+}
+
+//  UITextField sends this message to its delegate when the return key
+//  is pressed. Use this as a hook to navigate back to the list view
+//  (by 'popping' the current view controller, or dismissing a modal nav
+//  controller, as the case may be).
+//
+//  If the user is adding a new item rather than editing an existing one,
+//  respond to the return key by moving the insertion point to the next cell's
+//  textField, unless we're already at the last cell.
+//
+- (BOOL)textFieldShouldReturn:(UITextField *)textField
+{
+    if ([textField returnKeyType] != UIReturnKeyDone)
+    {
+        //  If this is not the last field (in which case the keyboard's
+        //  return key label will currently be 'Next' rather than 'Done'),
+        //  just move the insertion point to the next field.
+        //
+        //  (See the implementation of -textFieldShouldBeginEditing: above.)
+        //
+        NSInteger nextTag = [textField tag] + 1;
+        UIView *nextTextField = [[self tableView] viewWithTag:nextTag];
+        
+        [nextTextField becomeFirstResponder];
+    }
+    else if ([self isModal])
+    {
+        //  We're in a modal navigation controller, which means the user is
+        //  adding a new book rather than editing an existing one.
+        //
+        [self save];
+    }
+    else
+    {
+        [[self navigationController] popViewControllerAnimated:YES];
+    }
+    
+    return YES;
+}
+
+#pragma mark -
+#pragma mark UITableViewDataSource Protocol
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
+{
+    return 1;
+}
+
+- (NSInteger)tableView:(UITableView *)tableView
+ numberOfRowsInSection:(NSInteger)section
+{
+    return section == 0 ? 2 : 1;
+}
+
+- (NSString *)tableView:(UITableView *)tableView
+titleForHeaderInSection:(NSInteger)section
+{

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list