summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsiqi <me@siqi.fr>2013-07-03 17:08:22 +0200
committersiqi <me@siqi.fr>2013-07-04 10:10:46 +0200
commit5d0b5f6f42ff4766e937f7d55f5fcb694e2eb0ce (patch)
tree899eb9dadd12d47a271e05e54a2c548adfb8dd23
parentb775c8043242a8657eae11bae4085bd4291ac580 (diff)
iphone storyboard
Change-Id: I67f93d812ab856578378bb891b44f55c06ca7421
-rw-r--r--ios/.DS_Storebin0 -> 6148 bytes
-rw-r--r--ios/iosremote/.DS_Storebin0 -> 6148 bytes
-rw-r--r--ios/iosremote/iosremote.xcodeproj/project.pbxproj26
-rw-r--r--ios/iosremote/iosremote.xcodeproj/project.xcworkspace/contents.xcworkspacedata7
-rw-r--r--ios/iosremote/iosremote.xcodeproj/project.xcworkspace/xcuserdata/siqi.xcuserdatad/UserInterfaceState.xcuserstatebin0 -> 72441 bytes
-rw-r--r--ios/iosremote/iosremote.xcodeproj/project.xcworkspace/xcuserdata/siqi.xcuserdatad/WorkspaceSettings.xcsettings10
-rw-r--r--ios/iosremote/iosremote.xcodeproj/xcuserdata/siqi.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist33
-rw-r--r--ios/iosremote/iosremote.xcodeproj/xcuserdata/siqi.xcuserdatad/xcschemes/iosremote.xcscheme86
-rw-r--r--ios/iosremote/iosremote.xcodeproj/xcuserdata/siqi.xcuserdatad/xcschemes/xcschememanagement.plist22
-rw-r--r--ios/iosremote/iosremote/.DS_Storebin0 -> 15364 bytes
-rw-r--r--ios/iosremote/iosremote/Communication/CommunicationManager.h6
-rw-r--r--ios/iosremote/iosremote/Communication/CommunicationManager.m31
-rw-r--r--ios/iosremote/iosremote/EditableTableViewCell.h14
-rw-r--r--ios/iosremote/iosremote/EditableTableViewCell.m54
-rwxr-xr-xios/iosremote/iosremote/EditableTableViewController.h64
-rwxr-xr-xios/iosremote/iosremote/TPKeyboardAvoidingScrollView.h14
-rwxr-xr-xios/iosremote/iosremote/TPKeyboardAvoidingScrollView.m285
-rwxr-xr-xios/iosremote/iosremote/TPKeyboardAvoidingTableView.h13
-rwxr-xr-xios/iosremote/iosremote/TPKeyboardAvoidingTableView.m284
-rw-r--r--ios/iosremote/iosremote/en.lproj/MainStoryboard_iPad.storyboard22
-rw-r--r--ios/iosremote/iosremote/en.lproj/MainStoryboard_iPhone.storyboard137
-rw-r--r--ios/iosremote/iosremote/main.m1
-rw-r--r--ios/iosremote/iosremote/newServer_vc.h38
-rw-r--r--ios/iosremote/iosremote/newServer_vc.m273
-rw-r--r--ios/iosremote/iosremote/server_list_vc.h15
-rw-r--r--ios/iosremote/iosremote/server_list_vc.m92
26 files changed, 1491 insertions, 36 deletions
diff --git a/ios/.DS_Store b/ios/.DS_Store
new file mode 100644
index 000000000000..4e262b151d7a
--- /dev/null
+++ b/ios/.DS_Store
Binary files differ
diff --git a/ios/iosremote/.DS_Store b/ios/iosremote/.DS_Store
new file mode 100644
index 000000000000..2997260c1ac8
--- /dev/null
+++ b/ios/iosremote/.DS_Store
Binary files differ
diff --git a/ios/iosremote/iosremote.xcodeproj/project.pbxproj b/ios/iosremote/iosremote.xcodeproj/project.pbxproj
index 7fa842ce0885..bd554ee06d9f 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 000000000000..130b46bd01f9
--- /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 000000000000..37b2f77549fd
--- /dev/null
+++ b/ios/iosremote/iosremote.xcodeproj/project.xcworkspace/xcuserdata/siqi.xcuserdatad/UserInterfaceState.xcuserstate
Binary files 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 000000000000..659c8766e0c0
--- /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 000000000000..8060e630f4f9
--- /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 000000000000..bb82040d1bb5
--- /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 000000000000..74079c753a96
--- /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 000000000000..46c9bed55e16
--- /dev/null
+++ b/ios/iosremote/iosremote/.DS_Store
Binary files differ
diff --git a/ios/iosremote/iosremote/Communication/CommunicationManager.h b/ios/iosremote/iosremote/Communication/CommunicationManager.h
index 8df7e09091ae..7fe5451a0af1 100644
--- a/ios/iosremote/iosremote/Communication/CommunicationManager.h
+++ b/ios/iosremote/iosremote/Communication/CommunicationManager.h
@@ -51,12 +51,16 @@ enum ConnectionState : NSInteger {
CONNECTED
};
-@interface CommunicationManager : NSObject
+@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;
+@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 bd86180ca971..701d4ebc5185 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;
-@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 000000000000..6dd16660b352
--- /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>
+
+@interface EditableTableViewCell : UITableViewCell
+ @property (weak, nonatomic) UITextField * textField;
+ @property (weak, nonatomic) UILabel * inputLabel;
+@end
diff --git a/ios/iosremote/iosremote/EditableTableViewCell.m b/ios/iosremote/iosremote/EditableTableViewCell.m
new file mode 100644
index 000000000000..73199a077863
--- /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"
+
+@implementation EditableTableViewCell
+
+@synthesize inputLabel = _inputLabel;
+@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];
+}
+
+@end
diff --git a/ios/iosremote/iosremote/EditableTableViewController.h b/ios/iosremote/iosremote/EditableTableViewController.h
new file mode 100755
index 000000000000..b9a473d7937f
--- /dev/null
+++ b/ios/iosremote/iosremote/EditableTableViewController.h
@@ -0,0 +1,64 @@
+
+#import <UIKit/UIKit.h>
+#import "MyListController.h"
+
+@class Book;
+@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;
+
+@interface MyDetailController : UITableViewController <UITextFieldDelegate>
+{
+ Book *_book;
+ MyListController *_listController;
+ EditableDetailCell *_titleCell;
+ EditableDetailCell *_firstNameCell;
+ EditableDetailCell *_lastNameCell;
+ EditableDetailCell *_yearCell;
+ EditableDetailCell *_imagePathCell;
+}
+
+@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.)
+//
+@property (nonatomic, retain) MyListController *listController;
+
+@property (nonatomic, retain) EditableDetailCell *titleCell;
+@property (nonatomic, retain) EditableDetailCell *firstNameCell;
+@property (nonatomic, retain) EditableDetailCell *lastNameCell;
+@property (nonatomic, retain) EditableDetailCell *yearCell;
+@property (nonatomic, retain) EditableDetailCell *imagePathCell;
+
+- (BOOL)isModal;
+
+- (EditableDetailCell *)newDetailCellWithTag:(NSInteger)tag;
+
+// Action Methods
+//
+- (void)save;
+- (void)cancel;
+
+@end
diff --git a/ios/iosremote/iosremote/TPKeyboardAvoidingScrollView.h b/ios/iosremote/iosremote/TPKeyboardAvoidingScrollView.h
new file mode 100755
index 000000000000..ffecaa272d4b
--- /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>
+
+@interface TPKeyboardAvoidingScrollView : UIScrollView
+@property (assign, nonatomic) BOOL autoAdjustsContentSizeToBounds;
+- (BOOL)focusNextTextField;
+- (void)scrollToActiveTextField;
+@end
diff --git a/ios/iosremote/iosremote/TPKeyboardAvoidingScrollView.m b/ios/iosremote/iosremote/TPKeyboardAvoidingScrollView.m
new file mode 100755
index 000000000000..5970f0260db3
--- /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")
+
+@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;
+@end
+
+@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;
+ }
+ }
+ }
+}
+
+@end
diff --git a/ios/iosremote/iosremote/TPKeyboardAvoidingTableView.h b/ios/iosremote/iosremote/TPKeyboardAvoidingTableView.h
new file mode 100755
index 000000000000..7f2949c755f5
--- /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>
+
+@interface TPKeyboardAvoidingTableView : UITableView
+- (BOOL)focusNextTextField;
+- (void)scrollToActiveTextField;
+@end
diff --git a/ios/iosremote/iosremote/TPKeyboardAvoidingTableView.m b/ios/iosremote/iosremote/TPKeyboardAvoidingTableView.m
new file mode 100755
index 000000000000..8d08c2a21337
--- /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")
+
+@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;
+@end
+
+@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;
+ }
+ }
+ }
+}
+
+@end
diff --git a/ios/iosremote/iosremote/en.lproj/MainStoryboard_iPad.storyboard b/ios/iosremote/iosremote/en.lproj/MainStoryboard_iPad.storyboard
index 8a373a57113e..9eab508b5e99 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 dd21c3188b1f..fd0b6cb2f826 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 126838a75b05..60d8585ee850 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 000000000000..6d725b56be7b
--- /dev/null
+++ b/ios/iosremote/iosremote/newServer_vc.h
@@ -0,0 +1,38 @@
+
+#import <UIKit/UIKit.h>
+
+@class Server;
+@class EditableTableViewCell;
+@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;
+
+@interface newServerViewController : UITableViewController <UITextFieldDelegate>
+@property (nonatomic, strong) Server *server;
+@property (nonatomic, strong) EditableTableViewCell *nameCell;
+@property (nonatomic, strong) EditableTableViewCell *addrCell;
+@property (nonatomic, strong) CommunicationManager *comManager;
+- (IBAction)save:(id)sender;
+- (BOOL)isModal;
+
+- (EditableTableViewCell *)newDetailCellWithTag:(NSInteger)tag;
+
+// Action Methods
+- (void)save;
+- (void)cancel;
+
+@end
diff --git a/ios/iosremote/iosremote/newServer_vc.m b/ios/iosremote/iosremote/newServer_vc.m
new file mode 100644
index 000000000000..64c969319868
--- /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"
+
+@implementation newServerViewController
+
+@synthesize server = _server;
+
+@synthesize nameCell = _nameCell;
+@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
+{
+ switch (section)
+ {
+ case InformationSection: return nil;
+ }
+ return nil;
+}
+
+- (UITableViewCell *)tableView:(UITableView *)tableView
+ cellForRowAtIndexPath:(NSIndexPath *)indexPath
+{
+ EditableTableViewCell *cell = nil;
+ NSInteger tag = INT_MIN;
+ NSString *text = nil;
+ NSString *placeholder = nil;
+
+ // Pick the editable cell and the values for its textField
+ //
+ NSUInteger section = [indexPath section];
+ switch (section)
+ {
+ case InformationSection:
+ {
+ if ([indexPath row] == 0)
+ {
+ cell = [self nameCell];
+ text = [self.server serverName];
+ tag = ServerName;
+ placeholder = @"Server Name (optional)";
+ }
+ else
+ {
+ cell = [self addrCell];
+ text = [self.server serverAddress];
+ tag = ServerAddr;
+ placeholder = @"IP Address";
+ }
+ break;
+ }
+ }
+ return cell;
+}
+
+@end
+
diff --git a/ios/iosremote/iosremote/server_list_vc.h b/ios/iosremote/iosremote/server_list_vc.h
new file mode 100644
index 000000000000..a895660c6a0b
--- /dev/null
+++ b/ios/iosremote/iosremote/server_list_vc.h
@@ -0,0 +1,15 @@
+// -*- 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>
+
+@interface server_list_vc : UITableViewController
+
+@property (weak, nonatomic) IBOutlet UITableView *serverTable;
+
+@end
diff --git a/ios/iosremote/iosremote/server_list_vc.m b/ios/iosremote/iosremote/server_list_vc.m
new file mode 100644
index 000000000000..8bbbbb4aadf2
--- /dev/null
+++ b/ios/iosremote/iosremote/server_list_vc.m
@@ -0,0 +1,92 @@
+// -*- 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 "server_list_vc.h"
+#import "CommunicationManager.h"
+#import "newServer_vc.h"
+
+@interface server_list_vc ()
+
+@property (nonatomic, strong) CommunicationManager *comManager;
+@property (nonatomic, weak) NSNotificationCenter* center;
+@property (nonatomic, strong) id slideShowPreviewStartObserver;
+
+@end
+
+@implementation server_list_vc
+
+@synthesize center = _center;
+@synthesize comManager = _comManager;
+@synthesize slideShowPreviewStartObserver = _slideShowPreviewStartObserver;
+
+- (id)initWithStyle:(UITableViewStyle)style
+{
+ self = [super initWithStyle:style];
+ if (self) {
+ // Custom initialization
+ }
+ return self;
+}
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+ // Uncomment the following line to preserve selection between presentations.
+ // self.clearsSelectionOnViewWillAppear = NO;
+
+ // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
+ // self.navigationItem.rightBarButtonItem = self.editButtonItem;
+
+ self.center = [NSNotificationCenter defaultCenter];
+ self.comManager = [[CommunicationManager alloc] initWithExistingServers];
+ self.serverTable.dataSource = self.comManager;
+}
+
+- (void)viewDidAppear:(BOOL)animated {
+}
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+ // Dispose of any resources that can be recreated.
+}
+
+#pragma mark - Table view data source
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
+{
+ return 0;
+}
+
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
+{
+ return 0;
+}
+
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
+{
+ static NSString *CellIdentifier = @"Cell";
+ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
+
+ // Configure the cell...
+
+ return cell;
+}
+
+#pragma mark - Table view delegate
+
+- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
+{
+}
+
+- (void)viewDidUnload {
+ [self setServerTable:nil];
+ [super viewDidUnload];
+}
+
+@end