Marino Faggiana 6 жил өмнө
parent
commit
f182d770fb
100 өөрчлөгдсөн 1140 нэмэгдсэн , 431 устгасан
  1. 5 1
      CHANGELOG.md
  2. 12 0
      Nextcloud.xcodeproj/project.pbxproj
  3. 1 4
      iOSClient/AppDelegate.m
  4. 2 2
      iOSClient/Brand/File_Provider_Extension.plist
  5. 15 11
      iOSClient/Brand/Intro/CCIntro.m
  6. 1 1
      iOSClient/Brand/NCBrand.swift
  7. 2 2
      iOSClient/Brand/Notification_Service_Extension.plist
  8. 2 2
      iOSClient/Brand/Share.plist
  9. 11 5
      iOSClient/Brand/iOSClient.plist
  10. 4 1
      iOSClient/CCGlobal.h
  11. 292 137
      iOSClient/Create/CCCreateCloud.swift
  12. 1 0
      iOSClient/Database/NCDatabase.swift
  13. 23 2
      iOSClient/Database/NCManageDatabase.swift
  14. 23 0
      iOSClient/Images.xcassets/deleteScan.imageset/Contents.json
  15. BIN
      iOSClient/Images.xcassets/deleteScan.imageset/deleteScan.png
  16. BIN
      iOSClient/Images.xcassets/deleteScan.imageset/deleteScan@2x.png
  17. BIN
      iOSClient/Images.xcassets/deleteScan.imageset/deleteScan@3x.png
  18. 3 0
      iOSClient/Library/OCCommunicationLib/OCCapabilities.h
  19. 2 0
      iOSClient/Library/OCCommunicationLib/OCCapabilities.m
  20. 4 0
      iOSClient/Library/OCCommunicationLib/OCCommunication.h
  21. 67 1
      iOSClient/Library/OCCommunicationLib/OCCommunication.m
  22. 3 0
      iOSClient/Library/OCCommunicationLib/OCFrameworkConstants.h
  23. 6 0
      iOSClient/Library/OCCommunicationLib/OCWebDavClient/OCWebDAVClient.h
  24. 19 1
      iOSClient/Library/OCCommunicationLib/OCWebDavClient/OCWebDAVClient.m
  25. 1 1
      iOSClient/Library/XLForm/XL/Cell/XLFormSliderCell.m
  26. 55 114
      iOSClient/Login/CCLogin.m
  27. 34 0
      iOSClient/Main/CCDetail.m
  28. 1 3
      iOSClient/Main/CCMain.m
  29. 7 9
      iOSClient/Main/CCMore.swift
  30. 2 2
      iOSClient/Networking/CCNetworking.m
  31. 27 10
      iOSClient/Networking/NCService.swift
  32. 5 2
      iOSClient/Networking/OCNetworking.h
  33. 119 2
      iOSClient/Networking/OCNetworking.m
  34. 65 0
      iOSClient/Richdocument/NCRichdocument.swift
  35. 33 12
      iOSClient/Scan/Scan.storyboard
  36. 226 86
      iOSClient/Scan/ScanCollectionView.swift
  37. 1 1
      iOSClient/Scan/WeScan/ImageScannerController.swift
  38. 1 1
      iOSClient/Scan/WeScan/Scan/CloseButton.swift
  39. 4 1
      iOSClient/Scan/WeScan/Scan/ScannerViewController.swift
  40. 18 0
      iOSClient/Settings/Acknowledgements.rtf
  41. 24 15
      iOSClient/Settings/NCManageAutoUploadFileName.swift
  42. BIN
      iOSClient/Supporting Files/ast.lproj/Localizable.strings
  43. BIN
      iOSClient/Supporting Files/ca.lproj/Localizable.strings
  44. BIN
      iOSClient/Supporting Files/cs-CZ.lproj/BKPasscodeView.strings
  45. BIN
      iOSClient/Supporting Files/cs-CZ.lproj/InfoPlist.strings
  46. BIN
      iOSClient/Supporting Files/cs-CZ.lproj/Localizable.strings
  47. BIN
      iOSClient/Supporting Files/da.lproj/Localizable.strings
  48. BIN
      iOSClient/Supporting Files/de.lproj/Intro.strings
  49. BIN
      iOSClient/Supporting Files/de.lproj/Localizable.strings
  50. BIN
      iOSClient/Supporting Files/el.lproj/Intro.strings
  51. BIN
      iOSClient/Supporting Files/el.lproj/Localizable.strings
  52. BIN
      iOSClient/Supporting Files/en-GB.lproj/Localizable.strings
  53. 19 2
      iOSClient/Supporting Files/en.lproj/Localizable.strings
  54. BIN
      iOSClient/Supporting Files/es-419.lproj/Localizable.strings
  55. BIN
      iOSClient/Supporting Files/es-AR.lproj/Localizable.strings
  56. BIN
      iOSClient/Supporting Files/es-CL.lproj/Localizable.strings
  57. BIN
      iOSClient/Supporting Files/es-CO.lproj/Localizable.strings
  58. BIN
      iOSClient/Supporting Files/es-CR.lproj/Localizable.strings
  59. BIN
      iOSClient/Supporting Files/es-DO.lproj/Localizable.strings
  60. BIN
      iOSClient/Supporting Files/es-EC.lproj/Localizable.strings
  61. BIN
      iOSClient/Supporting Files/es-GT.lproj/Localizable.strings
  62. BIN
      iOSClient/Supporting Files/es-HN.lproj/Localizable.strings
  63. BIN
      iOSClient/Supporting Files/es-MX.lproj/Localizable.strings
  64. BIN
      iOSClient/Supporting Files/es-NI.lproj/Localizable.strings
  65. BIN
      iOSClient/Supporting Files/es-PA.lproj/Localizable.strings
  66. BIN
      iOSClient/Supporting Files/es-PE.lproj/Localizable.strings
  67. BIN
      iOSClient/Supporting Files/es-PR.lproj/Localizable.strings
  68. BIN
      iOSClient/Supporting Files/es-PY.lproj/Localizable.strings
  69. BIN
      iOSClient/Supporting Files/es-SV.lproj/Localizable.strings
  70. BIN
      iOSClient/Supporting Files/es-UY.lproj/Localizable.strings
  71. BIN
      iOSClient/Supporting Files/es.lproj/Localizable.strings
  72. BIN
      iOSClient/Supporting Files/fa.lproj/Localizable.strings
  73. BIN
      iOSClient/Supporting Files/fi-FI.lproj/Error.strings
  74. BIN
      iOSClient/Supporting Files/fi-FI.lproj/Intro.strings
  75. BIN
      iOSClient/Supporting Files/fi-FI.lproj/Localizable.strings
  76. BIN
      iOSClient/Supporting Files/fr.lproj/BKPasscodeView.strings
  77. BIN
      iOSClient/Supporting Files/fr.lproj/CTAssetsPicker.strings
  78. BIN
      iOSClient/Supporting Files/fr.lproj/Error.strings
  79. BIN
      iOSClient/Supporting Files/fr.lproj/Intro.strings
  80. BIN
      iOSClient/Supporting Files/fr.lproj/Localizable.strings
  81. BIN
      iOSClient/Supporting Files/hu.lproj/Localizable.strings
  82. BIN
      iOSClient/Supporting Files/is.lproj/Localizable.strings
  83. BIN
      iOSClient/Supporting Files/it.lproj/Localizable.strings
  84. BIN
      iOSClient/Supporting Files/ja_JP.lproj/Localizable.strings
  85. BIN
      iOSClient/Supporting Files/ka-GE.lproj/Localizable.strings
  86. BIN
      iOSClient/Supporting Files/ko.lproj/Localizable.strings
  87. BIN
      iOSClient/Supporting Files/nb-NO.lproj/Localizable.strings
  88. BIN
      iOSClient/Supporting Files/nl.lproj/Localizable.strings
  89. BIN
      iOSClient/Supporting Files/pl.lproj/Localizable.strings
  90. BIN
      iOSClient/Supporting Files/pt-BR.lproj/Localizable.strings
  91. BIN
      iOSClient/Supporting Files/pt-PT.lproj/Localizable.strings
  92. BIN
      iOSClient/Supporting Files/ru.lproj/Localizable.strings
  93. BIN
      iOSClient/Supporting Files/sk-SK.lproj/Intro.strings
  94. BIN
      iOSClient/Supporting Files/sk-SK.lproj/Localizable.strings
  95. BIN
      iOSClient/Supporting Files/sq.lproj/Localizable.strings
  96. BIN
      iOSClient/Supporting Files/sr.lproj/Localizable.strings
  97. BIN
      iOSClient/Supporting Files/sv.lproj/Intro.strings
  98. BIN
      iOSClient/Supporting Files/sv.lproj/Localizable.strings
  99. BIN
      iOSClient/Supporting Files/tr.lproj/Localizable.strings
  100. BIN
      iOSClient/Supporting Files/zh-Hans.lproj/Error.strings

+ 5 - 1
CHANGELOG.md

@@ -6,8 +6,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
 
 ## [Unreleased]
 
-### [2.22.3] - 2018-xx-xx
+### [2.22.4] - 2018-xx-xx
+- See https://github.com/nextcloud/ios/milestone/39
+
+## [2.22.3] - 2018-09-07
 - See https://github.com/nextcloud/ios/milestone/38
+- Scan documents and create multipage pdfs or jpg
 
 ## [2.22.2] - 2018-08-28
 - See https://github.com/nextcloud/ios/milestone/37

+ 12 - 0
Nextcloud.xcodeproj/project.pbxproj

@@ -418,6 +418,7 @@
 		F78964AE1EBB576C00403E13 /* JDStatusBarStyle.m in Sources */ = {isa = PBXBuildFile; fileRef = F78964AA1EBB576C00403E13 /* JDStatusBarStyle.m */; };
 		F78964AF1EBB576C00403E13 /* JDStatusBarView.m in Sources */ = {isa = PBXBuildFile; fileRef = F78964AC1EBB576C00403E13 /* JDStatusBarView.m */; };
 		F78BFEE11D31126B00E513CF /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F78BFEDE1D31126B00E513CF /* MainInterface.storyboard */; };
+		F790110E21415BF600D7B136 /* NCRichdocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = F790110D21415BF600D7B136 /* NCRichdocument.swift */; };
 		F7A321551E9E2A070069AD1B /* CCFavorites.m in Sources */ = {isa = PBXBuildFile; fileRef = F7A3214F1E9E2A070069AD1B /* CCFavorites.m */; };
 		F7A321651E9E37960069AD1B /* CCActivity.m in Sources */ = {isa = PBXBuildFile; fileRef = F7A321641E9E37960069AD1B /* CCActivity.m */; };
 		F7A3218C1E9E42B30069AD1B /* CCMenuAccount.m in Sources */ = {isa = PBXBuildFile; fileRef = F7A3218B1E9E42B30069AD1B /* CCMenuAccount.m */; };
@@ -1363,6 +1364,7 @@
 		F78D6F571F0B7D48002F9619 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Error.strings; sourceTree = "<group>"; };
 		F78F6FAE1CC8CCB700F4EA25 /* CCSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCSection.h; sourceTree = "<group>"; };
 		F78F6FAF1CC8CCB700F4EA25 /* CCSection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCSection.m; sourceTree = "<group>"; };
+		F790110D21415BF600D7B136 /* NCRichdocument.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCRichdocument.swift; sourceTree = "<group>"; };
 		F792A77B1BC7C45400C9388E /* CCSplit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCSplit.h; sourceTree = "<group>"; };
 		F792A77C1BC7C45400C9388E /* CCSplit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCSplit.m; sourceTree = "<group>"; };
 		F7956FC91B4886E60085DEA3 /* CCUploadFromOtherUpp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCUploadFromOtherUpp.h; sourceTree = "<group>"; };
@@ -2727,6 +2729,14 @@
 			path = JDStatusBarNotification;
 			sourceTree = "<group>";
 		};
+		F790110C21415BA900D7B136 /* Richdocument */ = {
+			isa = PBXGroup;
+			children = (
+				F790110D21415BF600D7B136 /* NCRichdocument.swift */,
+			);
+			path = Richdocument;
+			sourceTree = "<group>";
+		};
 		F7A3214D1E9E2A070069AD1B /* Favorites */ = {
 			isa = PBXGroup;
 			children = (
@@ -3347,6 +3357,7 @@
 				F7C5259A1E3B441D00FFE02C /* Notification */,
 				F7FCFFD51D70798C000E6E29 /* PeekPop */,
 				F7BE6E2A1D2D5C3B00106933 /* QuickActions */,
+				F790110C21415BA900D7B136 /* Richdocument */,
 				F7FE125B1BAC03FB0041924B /* Security */,
 				F7ACE4281BAC0268006C0017 /* Settings */,
 				F728CE741BF6322C00E69702 /* Share */,
@@ -4001,6 +4012,7 @@
 				F73B4F081F470D9100BBEE4B /* nsEUCJPProber.cpp in Sources */,
 				F758B43F212C516300515F55 /* RectangleFeaturesFunnel.swift in Sources */,
 				F70022DA1EC4C9100080073F /* OCHTTPRequestOperation.m in Sources */,
+				F790110E21415BF600D7B136 /* NCRichdocument.swift in Sources */,
 				F7D4245C1F063B82009C9782 /* CTAssetCheckmark.m in Sources */,
 				F70022A11EC4C9100080073F /* AFHTTPSessionManager.m in Sources */,
 				F762CB041EACB66200B38484 /* XLFormSwitchCell.m in Sources */,

+ 1 - 4
iOSClient/AppDelegate.m

@@ -94,11 +94,8 @@
     if (![[NSFileManager defaultManager] fileExistsAtPath: path])
         [[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];
     
-    // create Directory Scan + ScanSelect
+    // create Directory Scan
     path = [[dirGroup URLByAppendingPathComponent:k_appScan] path];
-    if (![[NSFileManager defaultManager] fileExistsAtPath:path])
-        [[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];
-    path = [[dirGroup URLByAppendingPathComponent:k_appScanSelect] path];
     if (![[NSFileManager defaultManager] fileExistsAtPath:path])
         [[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];
     

+ 2 - 2
iOSClient/Brand/File_Provider_Extension.plist

@@ -17,9 +17,9 @@
 	<key>CFBundlePackageType</key>
 	<string>XPC!</string>
 	<key>CFBundleShortVersionString</key>
-	<string>2.22.2</string>
+	<string>2.22.3</string>
 	<key>CFBundleVersion</key>
-	<string>2</string>
+	<string>12</string>
 	<key>NSExtension</key>
 	<dict>
 		<key>NSExtensionFileProviderDocumentGroup</key>

+ 15 - 11
iOSClient/Brand/Intro/CCIntro.m

@@ -112,18 +112,22 @@
     buttonLogin.backgroundColor = [[NCBrandColor sharedInstance] customerText];
     [buttonLogin addTarget:self action:@selector(login:) forControlEvents:UIControlEventTouchDown];
     
-    UIButton *buttonSignUp = [UIButton buttonWithType:UIButtonTypeRoundedRect];
-    buttonSignUp.frame = CGRectMake(50.0, 60.0, width - 100.0, 40.0);
-    buttonSignUp.layer.cornerRadius = 3;
-    buttonSignUp.clipsToBounds = YES;
-    [buttonSignUp setTitle:[NSLocalizedStringFromTable(@"_sign_up_", @"Intro", nil) uppercaseString] forState:UIControlStateNormal];
-    buttonSignUp.titleLabel.font = [UIFont systemFontOfSize:14];
-    [buttonSignUp setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
-    buttonSignUp.backgroundColor = [UIColor colorWithRed:25.0/255.0 green:89.0/255.0 blue:141.0/255.0 alpha:1.000];
-    [buttonSignUp addTarget:self action:@selector(signUp:) forControlEvents:UIControlEventTouchDown];
-    
     [buttonView addSubview:buttonLogin];
-    [buttonView addSubview:buttonSignUp];
+
+    if (![NCBrandOptions sharedInstance].disable_linkLoginProvider) {
+        
+        UIButton *buttonSignUp = [UIButton buttonWithType:UIButtonTypeRoundedRect];
+        buttonSignUp.frame = CGRectMake(50.0, 60.0, width - 100.0, 40.0);
+        buttonSignUp.layer.cornerRadius = 3;
+        buttonSignUp.clipsToBounds = YES;
+        [buttonSignUp setTitle:[NSLocalizedStringFromTable(@"_sign_up_", @"Intro", nil) uppercaseString] forState:UIControlStateNormal];
+        buttonSignUp.titleLabel.font = [UIFont systemFontOfSize:14];
+        [buttonSignUp setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
+        buttonSignUp.backgroundColor = [UIColor colorWithRed:25.0/255.0 green:89.0/255.0 blue:141.0/255.0 alpha:1.000];
+        [buttonSignUp addTarget:self action:@selector(signUp:) forControlEvents:UIControlEventTouchDown];
+        
+        [buttonView addSubview:buttonSignUp];
+    }
     
     // Pages
     

+ 1 - 1
iOSClient/Brand/NCBrand.swift

@@ -98,7 +98,7 @@ class NCBrandColor: NSObject {
     @objc public let use_storeLocalAutoUploadAll:       Bool = false
     
     @objc public let disable_intro:                     Bool = false
-    @objc public let disable_linkLoginProvider:         Bool = false
+    @objc public let disable_linkLoginProvider:         Bool = true
     @objc public let disable_request_login_url:         Bool = false
     @objc public let disable_multiaccount:              Bool = false
     @objc public let disable_manage_account:            Bool = false

+ 2 - 2
iOSClient/Brand/Notification_Service_Extension.plist

@@ -17,9 +17,9 @@
 	<key>CFBundlePackageType</key>
 	<string>XPC!</string>
 	<key>CFBundleShortVersionString</key>
-	<string>2.22.2</string>
+	<string>2.22.3</string>
 	<key>CFBundleVersion</key>
-	<string>2</string>
+	<string>12</string>
 	<key>NSExtension</key>
 	<dict>
 		<key>NSExtensionPointIdentifier</key>

+ 2 - 2
iOSClient/Brand/Share.plist

@@ -17,9 +17,9 @@
 	<key>CFBundlePackageType</key>
 	<string>XPC!</string>
 	<key>CFBundleShortVersionString</key>
-	<string>2.22.2</string>
+	<string>2.22.3</string>
 	<key>CFBundleVersion</key>
-	<string>2</string>
+	<string>12</string>
 	<key>NSAppTransportSecurity</key>
 	<dict>
 		<key>NSAllowsArbitraryLoads</key>

+ 11 - 5
iOSClient/Brand/iOSClient.plist

@@ -46,7 +46,7 @@
 	<key>CFBundlePackageType</key>
 	<string>APPL</string>
 	<key>CFBundleShortVersionString</key>
-	<string>2.22.2</string>
+	<string>2.22.3</string>
 	<key>CFBundleSignature</key>
 	<string>????</string>
 	<key>CFBundleURLTypes</key>
@@ -69,7 +69,7 @@
 		</dict>
 	</array>
 	<key>CFBundleVersion</key>
-	<string>2</string>
+	<string>12</string>
 	<key>FIREBASE_ANALYTICS_COLLECTION_DEACTIVATED</key>
 	<true/>
 	<key>Fabric</key>
@@ -98,13 +98,17 @@
 	</array>
 	<key>LSRequiresIPhoneOS</key>
 	<true/>
+	<key>LSSupportsOpeningDocumentsInPlace</key>
+	<true/>
 	<key>NSAppTransportSecurity</key>
 	<dict>
 		<key>NSAllowsArbitraryLoads</key>
 		<true/>
 	</dict>
 	<key>NSCameraUsageDescription</key>
-	<string>The use of Camera is used to scan documet</string>
+	<string>$(PRODUCT_NAME) requires access to the camera for scan documents</string>
+	<key>NSFaceIDUsageDescription</key>
+	<string>This app requires Face ID permission to authenticate using Face recognition.</string>
 	<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
 	<string>The use of GPS is used to detect new photos from camera roll, continued use of GPS running in the background can dramatically decrease battery life.</string>
 	<key>NSLocationAlwaysUsageDescription</key>
@@ -112,9 +116,9 @@
 	<key>NSLocationWhenInUseUsageDescription</key>
 	<string>The use of GPS is used to detect new photos from camera roll on background, the use of GPS only when the App is in use is useless</string>
 	<key>NSPhotoLibraryAddUsageDescription</key>
-	<string>$(PRODUCT_NAME) requires access to the photo library</string>
+	<string>$(PRODUCT_NAME) requires access to the photo library for send your photos and videos to your cloud.</string>
 	<key>NSPhotoLibraryUsageDescription</key>
-	<string>$(PRODUCT_NAME) requires access to the photo library</string>
+	<string>$(PRODUCT_NAME) requires access to the photo library for send your photos and videos to your cloud.</string>
 	<key>UIBackgroundModes</key>
 	<array>
 		<string>audio</string>
@@ -144,6 +148,8 @@
 		<string>UIInterfaceOrientationLandscapeRight</string>
 		<string>UIInterfaceOrientationPortraitUpsideDown</string>
 	</array>
+	<key>UISupportsDocumentBrowser</key>
+	<true/>
 	<key>UIViewControllerBasedStatusBarAppearance</key>
 	<false/>
 </dict>

+ 4 - 1
iOSClient/CCGlobal.h

@@ -45,7 +45,6 @@
 #define k_appUserData                                   @"Library/Application Support/UserData"
 #define k_appCertificates                               @"Library/Application Support/Certificates"
 #define k_appScan                                       @"Library/Application Support/Scan"
-#define k_appScanSelect                                 @"Library/Application Support/Scan/Select"
 
 #define k_DirectoryProviderStorage                      @"File Provider Storage"
 
@@ -298,6 +297,10 @@
 #define k_action_MOD                                    1
 #define k_action_DEL                                    2
 
+// Nextcloud unsupported
+#define k_nextcloud_unsupported                         12
+
+
 // -----------------------------------------------------------------------------------------------------------
 // -----------------------------------------------------------------------------------------------------------
 

+ 292 - 137
iOSClient/Create/CCCreateCloud.swift

@@ -69,15 +69,6 @@ class CreateMenuAdd: NSObject {
             appDelegate.activeMain.openAssetsPickerController()
         })
         
-/*
-#if DEBUG
-        if #available(iOS 11.0, *) {
-            actionSheet.addButton(withTitle: NSLocalizedString("_scans_document_", comment: ""), image: CCGraphics.changeThemingColorImage(UIImage(named: "scan"), multiplier:2, color: colorGray), backgroundColor: NCBrandColor.sharedInstance.backgroundView, height: 50.0, type: AHKActionSheetButtonType.default, handler: {(AHKActionSheet) -> Void in
-                NCCreateScanDocument.sharedInstance.openScannerDocument(viewController: appDelegate.activeMain, openScan: true)
-            })
-        }
-#endif
-*/
         actionSheet.addButton(withTitle: NSLocalizedString("_upload_file_", comment: ""), image: CCGraphics.changeThemingColorImage(UIImage(named: "file"), multiplier:2, color: colorGray), backgroundColor: NCBrandColor.sharedInstance.backgroundView, height: 50.0, type: AHKActionSheetButtonType.default, handler: {(AHKActionSheet) -> Void in
             appDelegate.activeMain.openImportDocumentPicker()
         })
@@ -90,6 +81,12 @@ class CreateMenuAdd: NSObject {
             appDelegate.activeMain.present(controller, animated: true, completion: nil)
         })
         
+        if #available(iOS 11.0, *) {
+            actionSheet.addButton(withTitle: NSLocalizedString("_scans_document_", comment: ""), image: CCGraphics.changeThemingColorImage(UIImage(named: "scan"), multiplier:2, color: colorGray), backgroundColor: NCBrandColor.sharedInstance.backgroundView, height: 50.0, type: AHKActionSheetButtonType.default, handler: {(AHKActionSheet) -> Void in
+                NCCreateScanDocument.sharedInstance.openScannerDocument(viewController: appDelegate.activeMain, openScan: true)
+            })
+        }
+        
         actionSheet.addButton(withTitle: NSLocalizedString("_create_folder_", comment: ""), image: CCGraphics.changeThemingColorImage(UIImage(named: "folder"), multiplier:2, color: colorIcon), backgroundColor: NCBrandColor.sharedInstance.backgroundView, height: 50.0 ,type: AHKActionSheetButtonType.default, handler: {(AHKActionSheet) -> Void in
             appDelegate.activeMain.createFolder()
         })
@@ -141,7 +138,7 @@ class CreateFormUploadAssets: XLFormViewController, CCMoveDelegate {
 
     func initializeForm() {
 
-        let form : XLFormDescriptor = XLFormDescriptor() as XLFormDescriptor
+        let form : XLFormDescriptor = XLFormDescriptor(title: NSLocalizedString("_upload_photos_videos_", comment: "")) as XLFormDescriptor
         form.rowNavigationOptions = XLFormRowNavigationOptions.stopDisableRow
 
         var section : XLFormSectionDescriptor
@@ -149,83 +146,94 @@ class CreateFormUploadAssets: XLFormViewController, CCMoveDelegate {
         
         // Section: Destination Folder
         
-        section = XLFormSectionDescriptor.formSection()
+        section = XLFormSectionDescriptor.formSection(withTitle: NSLocalizedString("_save_path_", comment: ""))
         form.addFormSection(section)
         
         row = XLFormRowDescriptor(tag: "ButtonDestinationFolder", rowType: XLFormRowDescriptorTypeButton, title: self.titleServerUrl)
-        let imageFolder = CCGraphics.changeThemingColorImage(UIImage(named: "folder")!, multiplier:2, color: NCBrandColor.sharedInstance.brandElement) as UIImage
-        row.cellConfig.setObject(imageFolder, forKey: "imageView.image" as NSCopying)
-        row.cellConfig.setObject(UIColor.black, forKey: "textLabel.textColor" as NSCopying)
-        row.cellConfig.setObject(UIFont.systemFont(ofSize: 15.0), forKey: "textLabel.font" as NSCopying)
         row.action.formSelector = #selector(changeDestinationFolder(_:))
-        section.addFormRow(row)
-        
-        // Section Switch
+
+        let imageFolder = CCGraphics.changeThemingColorImage(UIImage(named: "folder")!, multiplier:2, color: NCBrandColor.sharedInstance.brandElement) as UIImage
+        row.cellConfig["imageView.image"] = imageFolder
         
-        section = XLFormSectionDescriptor.formSection()
-        form.addFormSection(section)
+        row.cellConfig["textLabel.textAlignment"] = NSTextAlignment.right.rawValue
+        row.cellConfig["textLabel.font"] = UIFont.systemFont(ofSize: 15.0)
         
-        // Folder Photo
+        section.addFormRow(row)
         
+        // User folder Media
         row = XLFormRowDescriptor(tag: "useFolderMedia", rowType: XLFormRowDescriptorTypeBooleanSwitch, title: NSLocalizedString("_use_folder_media_", comment: ""))
         row.value = 0
-        row.cellConfig.setObject(UIFont.systemFont(ofSize: 15.0), forKey: "textLabel.font" as NSCopying)
+        
+        row.cellConfig["textLabel.font"] = UIFont.systemFont(ofSize: 15.0)
+        
         section.addFormRow(row)
         
         // Use Sub folder
         row = XLFormRowDescriptor(tag: "useSubFolder", rowType: XLFormRowDescriptorTypeBooleanSwitch, title: NSLocalizedString("_autoupload_create_subfolder_", comment: ""))
-        row.hidden = "$\("useFolderMedia") == 0"
-        row.cellConfig.setObject(UIFont.systemFont(ofSize: 15.0), forKey: "textLabel.font" as NSCopying)
-        
         let tableAccount = NCManageDatabase.sharedInstance.getAccountActive()
-        
         if tableAccount?.autoUploadCreateSubfolder == true {
             row.value = 1
         } else {
             row.value = 0
         }
-        section.addFormRow(row)
+        row.hidden = "$\("useFolderMedia") == 0"
+
+        row.cellConfig["textLabel.font"] = UIFont.systemFont(ofSize: 15.0)
 
+        section.addFormRow(row)
+        
+        // Section Mode filename
+        
+        section = XLFormSectionDescriptor.formSection(withTitle: NSLocalizedString("_mode_filename_", comment: ""))
+        form.addFormSection(section)
+        
         // Maintain the original fileName
         
         row = XLFormRowDescriptor(tag: "maintainOriginalFileName", rowType: XLFormRowDescriptorTypeBooleanSwitch, title: NSLocalizedString("_maintain_original_filename_", comment: ""))
         row.value = CCUtility.getOriginalFileName(k_keyFileNameOriginal)
-        row.cellConfig.setObject(UIFont.systemFont(ofSize: 15.0), forKey: "textLabel.font" as NSCopying)
+        
+        row.cellConfig["textLabel.font"] = UIFont.systemFont(ofSize: 15.0)
+        
         section.addFormRow(row)
         
         // Add File Name Type
 
         row = XLFormRowDescriptor(tag: "addFileNameType", rowType: XLFormRowDescriptorTypeBooleanSwitch, title: NSLocalizedString("_add_filenametype_", comment: ""))
-        row.hidden = "$\("maintainOriginalFileName") == 1"
-        row.cellConfig.setObject(UIFont.systemFont(ofSize: 15.0), forKey: "textLabel.font" as NSCopying)
         row.value = CCUtility.getFileNameType(k_keyFileNameType)
+        row.hidden = "$\("maintainOriginalFileName") == 1"
+        
+        row.cellConfig["textLabel.font"] = UIFont.systemFont(ofSize: 15.0)
+
         section.addFormRow(row)
         
         // Section: Rename File Name
         
-        section = XLFormSectionDescriptor.formSection()
+        section = XLFormSectionDescriptor.formSection(withTitle: NSLocalizedString("_filename_", comment: ""))
         form.addFormSection(section)
         
-        row = XLFormRowDescriptor(tag: "maskFileName", rowType: XLFormRowDescriptorTypeAccount, title: (NSLocalizedString("_filename_", comment: ""))+":")
-        row.hidden = "$\("maintainOriginalFileName") == 1"
-        row.cellConfig.setObject(UIFont.systemFont(ofSize: 15.0), forKey: "textLabel.font" as NSCopying)
-
+        row = XLFormRowDescriptor(tag: "maskFileName", rowType: XLFormRowDescriptorTypeAccount, title: (NSLocalizedString("_filename_", comment: "")))
         let fileNameMask : String = CCUtility.getFileNameMask(k_keyFileNameMask)
         if fileNameMask.count > 0 {
             row.value = fileNameMask
         }
+        row.hidden = "$\("maintainOriginalFileName") == 1"
+        
+        row.cellConfig["textLabel.font"] = UIFont.systemFont(ofSize: 15.0)
+        
+        row.cellConfig["textField.textAlignment"] = NSTextAlignment.right.rawValue
+        row.cellConfig["textField.font"] = UIFont.systemFont(ofSize: 15.0)
+
         section.addFormRow(row)
         
         // Section: Preview File Name
         
         row = XLFormRowDescriptor(tag: "previewFileName", rowType: XLFormRowDescriptorTypeTextView, title: "")
-
         row.height = 180
-        row.cellConfig.setObject(NCBrandColor.sharedInstance.backgroundView, forKey: "backgroundColor" as NSCopying)
-        row.cellConfig.setObject(NCBrandColor.sharedInstance.backgroundView, forKey: "textView.backgroundColor" as NSCopying)
-
         row.disabled = true
-        row.cellConfig.setObject(UIFont.systemFont(ofSize: 15.0), forKey: "textLabel.font" as NSCopying)
+
+        row.cellConfig["textView.backgroundColor"] = NCBrandColor.sharedInstance.backgroundView
+        row.cellConfig["textView.font"] = UIFont.systemFont(ofSize: 14.0)
+        
         section.addFormRow(row)
         
         self.form = form
@@ -313,8 +321,6 @@ class CreateFormUploadAssets: XLFormViewController, CCMoveDelegate {
         
         self.tableView.separatorStyle = UITableViewCellSeparatorStyle.none
         
-        self.tableView.backgroundColor = NCBrandColor.sharedInstance.backgroundView
-        
         self.reloadForm()
     }
     
@@ -482,24 +488,34 @@ class CreateFormUploadFileText: XLFormViewController, CCMoveDelegate {
         
         // Section: Destination Folder
         
-        section = XLFormSectionDescriptor.formSection()
+        section = XLFormSectionDescriptor.formSection(withTitle: NSLocalizedString("_save_path_", comment: ""))
         form.addFormSection(section)
+        
         row = XLFormRowDescriptor(tag: "ButtonDestinationFolder", rowType: XLFormRowDescriptorTypeButton, title: self.titleServerUrl)
-        let imageFolder = CCGraphics.changeThemingColorImage(UIImage(named: "folder")!, multiplier:2, color: NCBrandColor.sharedInstance.brandElement) as UIImage
-        row.cellConfig.setObject(imageFolder, forKey: "imageView.image" as NSCopying)
-        row.cellConfig.setObject(UIColor.black, forKey: "textLabel.textColor" as NSCopying)
-        row.cellConfig.setObject(UIFont.systemFont(ofSize: 15.0), forKey: "textLabel.font" as NSCopying)
         row.action.formSelector = #selector(changeDestinationFolder(_:))
+
+        let imageFolder = CCGraphics.changeThemingColorImage(UIImage(named: "folder")!, multiplier:2, color: NCBrandColor.sharedInstance.brandElement) as UIImage
+        row.cellConfig["imageView.image"] = imageFolder
+        
+        row.cellConfig["textLabel.textAlignment"] = NSTextAlignment.right.rawValue
+        row.cellConfig["textLabel.font"] = UIFont.systemFont(ofSize: 15.0)
+        
         section.addFormRow(row)
         
         // Section: File Name
         
-        section = XLFormSectionDescriptor.formSection()
+        section = XLFormSectionDescriptor.formSection(withTitle: NSLocalizedString("_filename_", comment: ""))
         form.addFormSection(section)
         
+        
         row = XLFormRowDescriptor(tag: "fileName", rowType: XLFormRowDescriptorTypeAccount, title: NSLocalizedString("_filename_", comment: ""))
-        row.cellConfig.setObject(UIFont.systemFont(ofSize: 15.0), forKey: "textLabel.font" as NSCopying)
-        row.value = fileName
+        row.value = self.fileName
+        
+        row.cellConfig["textLabel.font"] = UIFont.systemFont(ofSize: 15.0)
+        
+        row.cellConfig["textField.textAlignment"] = NSTextAlignment.right.rawValue
+        row.cellConfig["textField.font"] = UIFont.systemFont(ofSize: 15.0)
+        
         section.addFormRow(row)
         
         self.form = form
@@ -517,8 +533,11 @@ class CreateFormUploadFileText: XLFormViewController, CCMoveDelegate {
                  self.fileName = CCUtility.removeForbiddenCharactersServer(fileNameNew as! String)
             }
         
+            formRow.value = self.fileName
             self.title = fileName
-
+            
+            self.updateFormRow(formRow)
+            
             self.form.delegate = self
         }
     }
@@ -530,7 +549,6 @@ class CreateFormUploadFileText: XLFormViewController, CCMoveDelegate {
         super.viewDidLoad()
         
         let saveButton : UIBarButtonItem = UIBarButtonItem(title: NSLocalizedString("_save_", comment: ""), style: UIBarButtonItemStyle.plain, target: self, action: #selector(save))
-        
         self.navigationItem.rightBarButtonItem = saveButton
         
         self.navigationController?.navigationBar.isTranslucent = false
@@ -539,23 +557,6 @@ class CreateFormUploadFileText: XLFormViewController, CCMoveDelegate {
         self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: NCBrandColor.sharedInstance.brandText]
         
         self.tableView.separatorStyle = UITableViewCellSeparatorStyle.none
-        self.tableView.backgroundColor = NCBrandColor.sharedInstance.backgroundView
-        
-        self.reloadForm()
-    }
-    
-    func reloadForm() {
-        
-        self.form.delegate = nil
-        
-        let buttonDestinationFolder : XLFormRowDescriptor  = self.form.formRow(withTag: "ButtonDestinationFolder")!
-        buttonDestinationFolder.title = self.titleServerUrl
-        
-        self.title = fileName
-        
-        self.tableView.reloadData()
-        
-        self.form.delegate = self
     }
     
     // MARK: - Action
@@ -573,7 +574,10 @@ class CreateFormUploadFileText: XLFormViewController, CCMoveDelegate {
             self.titleServerUrl = "/"
         }
         
-        self.reloadForm()
+        // Update
+        let row : XLFormRowDescriptor  = self.form.formRow(withTag: "ButtonDestinationFolder")!
+        row.title = self.titleServerUrl
+        self.updateFormRow(row)
     }
     
     @objc func save() {
@@ -686,12 +690,15 @@ class CreateFormUploadScanDocument: XLFormViewController, CCMoveDelegate {
     
     var serverUrl = ""
     var titleServerUrl = ""
-    var arrayFileName = [String]()
+    var arrayImages = [UIImage]()
     var fileName = "scan.pdf"
+    var password : PDFPassword = ""
+    var compressionQuality: Double = 0.5
+    var fileType = "PDF"
     
     let appDelegate = UIApplication.shared.delegate as! AppDelegate
     
-    convenience init(serverUrl: String, arrayFileName: [String]) {
+    convenience init(serverUrl: String, arrayImages: [UIImage]) {
         
         self.init()
         
@@ -702,7 +709,7 @@ class CreateFormUploadScanDocument: XLFormViewController, CCMoveDelegate {
         }
         
         self.serverUrl = serverUrl
-        self.arrayFileName = arrayFileName
+        self.arrayImages = arrayImages
         
         initializeForm()
     }
@@ -711,7 +718,7 @@ class CreateFormUploadScanDocument: XLFormViewController, CCMoveDelegate {
     
     func initializeForm() {
         
-        let form : XLFormDescriptor = XLFormDescriptor() as XLFormDescriptor
+        let form : XLFormDescriptor = XLFormDescriptor(title: NSLocalizedString("_save_settings_", comment: "")) as XLFormDescriptor
         form.rowNavigationOptions = XLFormRowNavigationOptions.stopDisableRow
         
         var section : XLFormSectionDescriptor
@@ -719,26 +726,80 @@ class CreateFormUploadScanDocument: XLFormViewController, CCMoveDelegate {
         
         // Section: Destination Folder
         
-        section = XLFormSectionDescriptor.formSection()
+        section = XLFormSectionDescriptor.formSection(withTitle: NSLocalizedString("_save_path_", comment: ""))
         form.addFormSection(section)
+        
         row = XLFormRowDescriptor(tag: "ButtonDestinationFolder", rowType: XLFormRowDescriptorTypeButton, title: self.titleServerUrl)
-        let imageFolder = CCGraphics.changeThemingColorImage(UIImage(named: "folder")!, multiplier:2, color: NCBrandColor.sharedInstance.brandElement) as UIImage
-        row.cellConfig.setObject(imageFolder, forKey: "imageView.image" as NSCopying)
-        row.cellConfig.setObject(UIColor.black, forKey: "textLabel.textColor" as NSCopying)
-        row.cellConfig.setObject(UIFont.systemFont(ofSize: 15.0), forKey: "textLabel.font" as NSCopying)
         row.action.formSelector = #selector(changeDestinationFolder(_:))
+
+        let imageFolder = CCGraphics.changeThemingColorImage(UIImage(named: "folder")!, multiplier:2, color: NCBrandColor.sharedInstance.brandElement) as UIImage
+        row.cellConfig["imageView.image"] = imageFolder
+
+        row.cellConfig["textLabel.textAlignment"] = NSTextAlignment.right.rawValue
+        row.cellConfig["textLabel.font"] = UIFont.systemFont(ofSize: 15.0)
+        
         section.addFormRow(row)
         
-        // Section: File Name
+        // Section: Quality
         
-        section = XLFormSectionDescriptor.formSection()
+        section = XLFormSectionDescriptor.formSection(withTitle: NSLocalizedString("_quality_image_title_", comment: ""))
         form.addFormSection(section)
         
-        row = XLFormRowDescriptor(tag: "fileName", rowType: XLFormRowDescriptorTypeAccount, title: NSLocalizedString("_filename_", comment: ""))
-        row.cellConfig.setObject(UIFont.systemFont(ofSize: 15.0), forKey: "textLabel.font" as NSCopying)
-        row.value = fileName
+        row = XLFormRowDescriptor(tag: "compressionQuality", rowType: XLFormRowDescriptorTypeSlider)
+        row.value = 0.5
+        row.title = NSLocalizedString("_quality_medium_", comment: "")
+        
+        row.cellConfig["slider.minimumTrackTintColor"] = NCBrandColor.sharedInstance.brand
+
+        row.cellConfig["slider.maximumValue"] = 1
+        row.cellConfig["slider.minimumValue"] = 0
+        row.cellConfig["steps"] = 2
+
+        row.cellConfig["textLabel.textAlignment"] = NSTextAlignment.center.rawValue
+        row.cellConfig["textLabel.font"] = UIFont.systemFont(ofSize: 15.0)
+        
+        section.addFormRow(row)
+
+        // Section: Password
+        
+        section = XLFormSectionDescriptor.formSection(withTitle: NSLocalizedString("_pdf_password_", comment: ""))
+        form.addFormSection(section)
+        
+        row = XLFormRowDescriptor(tag: "password", rowType: XLFormRowDescriptorTypePassword, title: NSLocalizedString("_password_", comment: ""))
+        
+        row.cellConfig["textLabel.font"] = UIFont.systemFont(ofSize: 15.0)
+        
+        row.cellConfig["textField.textAlignment"] = NSTextAlignment.right.rawValue
+        row.cellConfig["textField.font"] = UIFont.systemFont(ofSize: 15.0)
+        
         section.addFormRow(row)
         
+        // Section: File
+        
+        section = XLFormSectionDescriptor.formSection(withTitle: NSLocalizedString("_file_creation_", comment: ""))
+        form.addFormSection(section)
+        
+        if arrayImages.count == 1 {
+            row = XLFormRowDescriptor(tag: "filetype", rowType: XLFormRowDescriptorTypeSelectorSegmentedControl, title: NSLocalizedString("_file_type_", comment: ""))
+            row.selectorOptions = ["PDF","JPG"]
+            row.value = "PDF"
+            
+            row.cellConfig["tintColor"] = NCBrandColor.sharedInstance.brand
+            row.cellConfig["textLabel.font"] = UIFont.systemFont(ofSize: 15.0)
+            
+            section.addFormRow(row)
+        }
+        
+        row = XLFormRowDescriptor(tag: "fileName", rowType: XLFormRowDescriptorTypeAccount, title: NSLocalizedString("_filename_", comment: ""))
+        row.value = self.fileName
+
+        row.cellConfig["textLabel.font"] = UIFont.systemFont(ofSize: 15.0)
+        
+        row.cellConfig["textField.textAlignment"] = NSTextAlignment.right.rawValue
+        row.cellConfig["textField.font"] = UIFont.systemFont(ofSize: 15.0)
+
+        section.addFormRow(row)
+       
         self.form = form
     }
     
@@ -750,14 +811,92 @@ class CreateFormUploadScanDocument: XLFormViewController, CCMoveDelegate {
             
             self.form.delegate = nil
             
-            if let fileNameNew = formRow.value {
-                self.fileName = CCUtility.removeForbiddenCharactersServer(fileNameNew as! String)
+            let fileNameNew = newValue as? String
+            
+            if fileNameNew != nil {
+                self.fileName = CCUtility.removeForbiddenCharactersServer(fileNameNew)
+            } else {
+                self.fileName = ""
             }
             
-            self.title = fileName
+            formRow.value = self.fileName
+            
+            self.updateFormRow(formRow)
             
             self.form.delegate = self
         }
+        
+        if formRow.tag == "compressionQuality" {
+            
+            self.form.delegate = nil
+            
+            //let row : XLFormRowDescriptor  = self.form.formRow(withTag: "descriptionQuality")!
+            let newQuality = newValue as? NSNumber
+            compressionQuality = (newQuality?.doubleValue)!
+            
+            if compressionQuality >= 0.0 && compressionQuality <= 0.3  {
+                formRow.title = NSLocalizedString("_quality_low_", comment: "")
+                compressionQuality = 0.1
+            } else if compressionQuality >= 0.4 && compressionQuality <= 0.6 {
+                formRow.title = NSLocalizedString("_quality_medium_", comment: "")
+                compressionQuality = 0.5
+            } else if compressionQuality >= 0.7 && compressionQuality <= 1.0 {
+                formRow.title = NSLocalizedString("_quality_high_", comment: "")
+                compressionQuality = 0.8
+            }
+            
+            self.updateFormRow(formRow)
+            
+            self.form.delegate = self
+        }
+        
+        if formRow.tag == "password" {
+            let stringPassword = newValue as? String
+            if stringPassword != nil {
+                password = PDFPassword(stringPassword!)
+            } else {
+                password = PDFPassword("")
+            }
+        }
+        
+        if formRow.tag == "filetype" {
+            fileType = newValue as! String
+            
+            let rowFileName : XLFormRowDescriptor  = self.form.formRow(withTag: "fileName")!
+            let rowPassword : XLFormRowDescriptor  = self.form.formRow(withTag: "password")!
+            
+            // rowFileName
+            guard var name = rowFileName.value else {
+                return
+            }
+            if name as! String == "" {
+                name = "scan"
+            }
+            
+            let ext = (name as! NSString).pathExtension.uppercased()
+            var newFileName = ""
+            
+            if (ext == "") {
+                newFileName = name as! String + "." + fileType.lowercased()
+            } else {
+                newFileName = (name as! NSString).deletingPathExtension + "." + fileType.lowercased()
+            }
+            
+            rowFileName.value = newFileName
+            
+            self.updateFormRow(rowFileName)
+            
+            // rowPassword
+            if fileType == "JPG" {
+                rowPassword.value = ""
+                password = PDFPassword("")
+                rowPassword.disabled = true
+            } else {
+                rowPassword.disabled = false
+            }
+            
+            self.updateFormRow(rowPassword)
+        }
     }
     
     // MARK: - View Life Cycle
@@ -767,7 +906,6 @@ class CreateFormUploadScanDocument: XLFormViewController, CCMoveDelegate {
         super.viewDidLoad()
         
         let saveButton : UIBarButtonItem = UIBarButtonItem(title: NSLocalizedString("_save_", comment: ""), style: UIBarButtonItemStyle.plain, target: self, action: #selector(save))
-        
         self.navigationItem.rightBarButtonItem = saveButton
         
         self.navigationController?.navigationBar.isTranslucent = false
@@ -776,23 +914,14 @@ class CreateFormUploadScanDocument: XLFormViewController, CCMoveDelegate {
         self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: NCBrandColor.sharedInstance.brandText]
         
         self.tableView.separatorStyle = UITableViewCellSeparatorStyle.none
-        self.tableView.backgroundColor = NCBrandColor.sharedInstance.backgroundView
+//        self.tableView.sectionHeaderHeight = 10
+//        self.tableView.sectionFooterHeight = 10
+//        self.tableView.backgroundColor = NCBrandColor.sharedInstance.backgroundView
         
-        self.reloadForm()
-    }
-    
-    func reloadForm() {
-        
-        self.form.delegate = nil
-        
-        let buttonDestinationFolder : XLFormRowDescriptor  = self.form.formRow(withTag: "ButtonDestinationFolder")!
-        buttonDestinationFolder.title = self.titleServerUrl
-        
-        self.title = fileName
-        
-        self.tableView.reloadData()
         
-        self.form.delegate = self
+//        let row : XLFormRowDescriptor  = self.form.formRow(withTag: "fileName")!
+//        let rowCell = row.cell(forForm: self)
+//        rowCell.becomeFirstResponder()
     }
     
     // MARK: - Action
@@ -810,7 +939,10 @@ class CreateFormUploadScanDocument: XLFormViewController, CCMoveDelegate {
             self.titleServerUrl = "/"
         }
         
-        self.reloadForm()
+        // Update
+        let row : XLFormRowDescriptor  = self.form.formRow(withTag: "ButtonDestinationFolder")!
+        row.title = self.titleServerUrl
+        self.updateFormRow(row)
     }
     
     @objc func save() {
@@ -819,13 +951,17 @@ class CreateFormUploadScanDocument: XLFormViewController, CCMoveDelegate {
         guard let name = rowFileName.value else {
             return
         }
+        if name as! String == "" {
+            return
+        }
+        
         let ext = (name as! NSString).pathExtension.uppercased()
         var fileNameSave = ""
         
         if (ext == "") {
-            fileNameSave = name as! String + ".pdf"
+            fileNameSave = name as! String + "." + fileType.lowercased()
         } else {
-            fileNameSave = (name as! NSString).deletingPathExtension + ".pdf"
+            fileNameSave = (name as! NSString).deletingPathExtension + "." + fileType.lowercased()
         }
         
         guard let directoryID = NCManageDatabase.sharedInstance.getDirectoryID(self.serverUrl) else {
@@ -858,37 +994,48 @@ class CreateFormUploadScanDocument: XLFormViewController, CCMoveDelegate {
     
     func dismissAndUpload(_ fileNameSave: String, fileID: String, directoryID: String) {
         
-        var pdfPages = [PDFPage]()
-
-        guard let fileNameGeneratePDF = CCUtility.getDirectoryProviderStorageFileID(fileID, fileNameView: fileNameSave) else {
+        guard let fileNameGenerateExport = CCUtility.getDirectoryProviderStorageFileID(fileID, fileNameView: fileNameSave) else {
             self.appDelegate.messageNotification("_error_", description: "_error_creation_file_", visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.info, errorCode: 0)
             return
         }
         
-        //Generate PDF
-        for fileNameImage in self.arrayFileName {
-            let fileNameImagePath = CCUtility.getDirectoryScanSelect() + "/" + fileNameImage
-            let page = PDFPage.imagePath(fileNameImagePath)
-            pdfPages.append(page)
-        }
+        if fileType == "PDF" {
         
-        do {
-            try PDFGenerator.generate(pdfPages, to: fileNameGeneratePDF)
-        } catch {
-            self.appDelegate.messageNotification("_error_", description: "_error_creation_file_", visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.info, errorCode: 0)
-            return
+            var pdfPages = [PDFPage]()
+
+            //Generate PDF
+            for image in self.arrayImages {
+                guard let data = UIImageJPEGRepresentation(image, CGFloat(compressionQuality)) else {
+                    self.appDelegate.messageNotification("_error_", description: "_error_creation_file_", visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.info, errorCode: 0)
+                    return
+                }
+                let page = PDFPage.image(UIImage(data: data)!)
+                pdfPages.append(page)
+            }
+            
+            do {
+                try PDFGenerator.generate(pdfPages, to: fileNameGenerateExport, password: password)
+            } catch {
+                self.appDelegate.messageNotification("_error_", description: "_error_creation_file_", visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.info, errorCode: 0)
+                return
+            }
         }
         
-        //Remove images processed
-        for fileNameImage in self.arrayFileName {
-            let fileNameImagePath = CCUtility.getDirectoryScanSelect() + "/" + fileNameImage
-            CCUtility.removeFile(atPath: fileNameImagePath)
+        if fileType == "JPG" {
+            
+            guard let data = UIImageJPEGRepresentation(self.arrayImages[0], CGFloat(compressionQuality)) else {
+                self.appDelegate.messageNotification("_error_", description: "_error_creation_file_", visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.info, errorCode: 0)
+                return
+            }
+            
+            do {
+                try data.write(to: NSURL.fileURL(withPath: fileNameGenerateExport), options: .atomic)
+            } catch {
+                self.appDelegate.messageNotification("_error_", description: "_error_creation_file_", visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.info, errorCode: 0)
+                return
+            }
         }
         
-        //Remove plist in reader for cache issue
-        //let filePlistReader = CCUtility.getDirectoryReaderMetadata() + "/" + (fileNameSave as NSString).deletingPathExtension + ".plist"
-        //CCUtility.removeFile(atPath: filePlistReader)
-        
         //Create metadata for upload
         let metadataForUpload = tableMetadata()
         
@@ -962,15 +1109,24 @@ class NCCreateScanDocument : NSObject, ImageScannerControllerDelegate {
     @available(iOS 10, *)
     func imageScannerController(_ scanner: ImageScannerController, didFinishScanningWithResults results: ImageScannerResults) {
         
+        let fileName = CCUtility.createFileName("scan.png", fileDate: Date(), fileType: PHAssetMediaType.image, keyFileName: k_keyFileNameMask, keyFileNameType: k_keyFileNameType, keyFileNameOriginal: k_keyFileNameOriginal)!
+        let fileNamePath = CCUtility.getDirectoryScan() + "/" + fileName
+        
+        // A4 74 DPI : 595 x 842 px 
+        
+        var image = results.scannedImage
+        let imageWidthInPixels = image.size.width * results.scannedImage.scale
+        let imageHeightInPixels = image.size.height * results.scannedImage.scale
+        
+        if imageWidthInPixels > 595 || imageHeightInPixels > 842  {
+            image = CCGraphics.scale(image, to: CGSize(width: 595, height: 842), isAspectRation: true)
+        }
+        
+        do {
+            try UIImagePNGRepresentation(image)?.write(to: NSURL.fileURL(withPath: fileNamePath), options: .atomic)
+        } catch { }
+        
         scanner.dismiss(animated: true, completion: {
-            
-            let fileName = CCUtility.createFileName("scan.png", fileDate: Date(), fileType: PHAssetMediaType.image, keyFileName: k_keyFileNameMask, keyFileNameType: k_keyFileNameType, keyFileNameOriginal: k_keyFileNameOriginal)!
-            let fileNamePath = CCUtility.getDirectoryScan() + "/" + fileName
-            
-            do {
-                try UIImagePNGRepresentation(results.scannedImage)?.write(to: NSURL.fileURL(withPath: fileNamePath), options: .atomic)
-            } catch { }
-            
             if (self.openScan) {
                 let storyboard = UIStoryboard(name: "Scan", bundle: nil)
                 let controller = storyboard.instantiateInitialViewController()!
@@ -989,7 +1145,6 @@ class NCCreateScanDocument : NSObject, ImageScannerControllerDelegate {
     @available(iOS 10, *)
     func imageScannerController(_ scanner: ImageScannerController, didFailWithError error: Error) {
         appDelegate.messageNotification("_error_", description: error.localizedDescription, visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: Int(k_CCErrorInternalError))
-        print(error)
     }
 }
 

+ 1 - 0
iOSClient/Database/NCDatabase.swift

@@ -93,6 +93,7 @@ class tableCapabilities: Object {
     @objc dynamic var versionString = ""
     @objc dynamic var endToEndEncryption: Bool = false
     @objc dynamic var endToEndEncryptionVersion = ""
+    let richdocumentsMimetypes = List<String>()
 }
 
 class tableCertificates: Object {

+ 23 - 2
iOSClient/Database/NCManageDatabase.swift

@@ -57,7 +57,7 @@ class NCManageDatabase: NSObject {
         let config = Realm.Configuration(
         
             fileURL: dirGroup?.appendingPathComponent("\(k_appDatabaseNextcloud)/\(k_databaseDefault)"),
-            schemaVersion: 27,
+            schemaVersion: 28,
             
             // 10 : Version 2.18.0
             // 11 : Version 2.18.2
@@ -77,6 +77,7 @@ class NCManageDatabase: NSObject {
             // 25 : Version 2.21.3.1
             // 26 : Version 2.22.0.4
             // 27 : Version 2.22.0.7
+            // 28 : Version 2.22.3.5
             
             migrationBlock: { migration, oldSchemaVersion in
                 // We haven’t migrated anything yet, so oldSchemaVersion == 0
@@ -667,7 +668,11 @@ class NCManageDatabase: NSObject {
                 resultCapabilities.versionString = capabilities.versionString
                 resultCapabilities.endToEndEncryption = capabilities.isEndToEndEncryptionEnabled
                 resultCapabilities.endToEndEncryptionVersion = capabilities.endToEndEncryptionVersion
-            
+                resultCapabilities.richdocumentsMimetypes.removeAll()
+                for mimeType in capabilities.richdocumentsMimetypes {
+                    resultCapabilities.richdocumentsMimetypes.append(mimeType as! String)
+                }
+                
                 if result == nil {
                     realm.add(resultCapabilities)
                 }
@@ -754,6 +759,22 @@ class NCManageDatabase: NSObject {
         return result
     }
     
+    @objc func getRichdocumentsMimetypes() -> [String]? {
+        
+        guard let tableAccount = self.getAccountActive() else {
+            return nil
+        }
+        
+        let realm = try! Realm()
+        realm.refresh()
+        
+        guard let result = realm.objects(tableCapabilities.self).filter("account = %@", tableAccount.account).first else {
+            return nil
+        }
+        
+        return Array(result.richdocumentsMimetypes)
+    }
+    
     //MARK: -
     //MARK: Table Certificates
     

+ 23 - 0
iOSClient/Images.xcassets/deleteScan.imageset/Contents.json

@@ -0,0 +1,23 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "filename" : "deleteScan.png",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "filename" : "deleteScan@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "filename" : "deleteScan@3x.png",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}

BIN
iOSClient/Images.xcassets/deleteScan.imageset/deleteScan.png


BIN
iOSClient/Images.xcassets/deleteScan.imageset/deleteScan@2x.png


BIN
iOSClient/Images.xcassets/deleteScan.imageset/deleteScan@3x.png


+ 3 - 0
iOSClient/Library/OCCommunicationLib/OCCapabilities.h

@@ -83,4 +83,7 @@
 @property (nonatomic) BOOL isEndToEndEncryptionEnabled;
 @property (nonatomic, strong) NSString *endToEndEncryptionVersion;
 
+// Richdocuments
+@property (nonatomic, strong) NSArray *RichdocumentsMimetypes;
+
 @end

+ 2 - 0
iOSClient/Library/OCCommunicationLib/OCCapabilities.m

@@ -38,6 +38,8 @@
         self.notificationPush = @"";
         
         self.spreedFeatures = @"";
+        
+        self.RichdocumentsMimetypes = [NSArray new];
     }
     return self;
 }

+ 4 - 0
iOSClient/Library/OCCommunicationLib/OCCommunication.h

@@ -945,6 +945,10 @@ typedef enum {
 
 - (void)deleteEndToEndMetadata:(NSString*)serverPath fileID:(NSString *)fileID onCommunication:(OCCommunication *)sharedOCComunication successRequest:(void(^)(NSHTTPURLResponse *response, NSString *redirectedServer)) successRequest failureRequest:(void(^)(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer)) failureRequest;
 
+#pragma mark - Manage Mobile Editor OCS API
+
+- (void)createLinkRichdocuments:(NSString *)serverPath fileID:(NSString *)fileID onCommunication:(OCCommunication *)sharedOCComunication successRequest:(void(^)(NSHTTPURLResponse *response, NSString *link, NSString *redirectedServer))successRequest  failureRequest:(void(^)(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer)) failureRequest;
+
 @end
 
 

+ 67 - 1
iOSClient/Library/OCCommunicationLib/OCCommunication.m

@@ -1478,6 +1478,14 @@
                     if ([endToEndEncryption valueForKey:@"api-version"] && ![[endToEndEncryption valueForKey:@"api-version"] isEqual:[NSNull null]])
                         capabilities.endToEndEncryptionVersion = [endToEndEncryption valueForKey:@"api-version"];
                 }
+                
+                //Richdocuments
+                
+                NSDictionary *richdocuments = [capabilitiesDict valueForKey:@"richdocuments"];
+                
+                if (richdocuments!= nil && [richdocuments count] > 0) {
+                    capabilities.RichdocumentsMimetypes = [richdocuments valueForKey:@"mimetypes"];
+                }
             }
         
             successRequest(response, capabilities, request.redirectedServer);
@@ -2705,7 +2713,65 @@
     }];
 }
 
-#pragma mark - Clear Cache
+#pragma mark - Manage Mobile Editor OCS API
+
+- (void)createLinkRichdocuments:(NSString *)serverPath fileID:(NSString *)fileID onCommunication:(OCCommunication *)sharedOCComunication successRequest:(void(^)(NSHTTPURLResponse *response, NSString *link, NSString *redirectedServer))successRequest failureRequest:(void(^)(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer)) failureRequest {
+    
+    serverPath = [serverPath stringByAppendingString:k_url_create_link_mobile_editor];
+    serverPath = [serverPath stringByAppendingString:@"?format=json"];
+    
+    OCWebDAVClient *request = [[OCWebDAVClient alloc] init];
+    request = [self getRequestWithCredentials:request];
+    
+    [request createLinkRichdocuments:serverPath fileID:fileID onCommunication:sharedOCComunication success:^(NSHTTPURLResponse *operation, id response) {
+        
+        NSData *responseData = (NSData*) response;
+        
+        //Parse
+        NSError *error;
+        NSDictionary *jsongParsed = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:&error];
+        NSLog(@"[LOG] Link richdocuments : %@",jsongParsed);
+        
+        if (jsongParsed && jsongParsed.allKeys > 0) {
+            
+            NSDictionary *ocs = [jsongParsed valueForKey:@"ocs"];
+            NSDictionary *meta = [ocs valueForKey:@"meta"];
+            NSDictionary *data = [ocs valueForKey:@"data"];
+            
+            NSInteger statusCode = [[meta valueForKey:@"statuscode"] integerValue];
+            
+            if (statusCode == kOCUserProfileAPISuccessful) {
+                
+                if ([data valueForKey:@"url"] && ![[data valueForKey:@"url"] isKindOfClass:[NSNull class]]) {
+                    
+                    NSString *link = [data valueForKey:@"url"];
+                    successRequest(response, link, request.redirectedServer);
+                    
+                } else {
+                    failureRequest(response, [UtilsFramework getErrorWithCode:k_CCErrorWebdavResponseError andCustomMessageFromTheServer:NSLocalizedStringFromTable(@"_server_response_error_", @"Error", nil)], request.redirectedServer);
+                }
+                
+            } else {
+                
+                NSString *message = (NSString *)[meta objectForKey:@"message"];
+                if ([message isKindOfClass:[NSNull class]]) {
+                    message = NSLocalizedStringFromTable(@"_server_response_error_", @"Error", nil);
+                }
+                failureRequest(response, [UtilsFramework getErrorWithCode:statusCode andCustomMessageFromTheServer:message], request.redirectedServer);
+            }
+            
+        } else {
+            failureRequest(response, [UtilsFramework getErrorWithCode:k_CCErrorWebdavResponseError andCustomMessageFromTheServer:NSLocalizedStringFromTable(@"_server_response_error_", @"Error", nil)], request.redirectedServer);
+        }
+  
+    } failure:^(NSHTTPURLResponse *response, NSData *responseData, NSError *error) {
+        
+        //Return error
+        failureRequest(response, error, request.redirectedServer);
+    }];
+}
+
+#pragma mark - Manage Mobile Editor OCS API
 
 - (void)eraseURLCache
 {

+ 3 - 0
iOSClient/Library/OCCommunicationLib/OCFrameworkConstants.h

@@ -70,6 +70,9 @@
 //Url to access to End To End Encryption API
 #define k_url_client_side_encryption @"ocs/v2.php/apps/end_to_end_encryption/api/v1"
 
+//Url to access to Mobile Editor OCS API
+#define k_url_create_link_mobile_editor @"ocs/v2.php/apps/richdocuments/api/v1/document"
+
 //Version of the server that have share API
 #define k_version_support_shared [NSArray arrayWithObjects:  @"5", @"0", @"27", nil]
 

+ 6 - 0
iOSClient/Library/OCCommunicationLib/OCWebDavClient/OCWebDAVClient.h

@@ -650,4 +650,10 @@ extern NSString * _Nullable OCWebDAVModificationDateKey;
 
 - (void)deleteEndToEndMetadata:(NSString * _Nonnull)serverPath onCommunication:(OCCommunication * _Nonnull)sharedOCComunication success:(void(^ _Nonnull)(NSHTTPURLResponse * _Nonnull operation, id _Nonnull response))success failure:(void(^ _Nonnull)(NSHTTPURLResponse * _Nonnull operation, id  _Nullable responseObject, NSError * _Nonnull error))failure;
 
+///-----------------------------------
+/// Manage Mobile Editor OCS API
+///-----------------------------------
+
+- (void)createLinkRichdocuments:(NSString *_Nonnull)serverPath fileID:(NSString * _Nonnull)fileID onCommunication:(OCCommunication * _Nonnull)sharedOCCommunication success:(void(^)(NSHTTPURLResponse *operation, id response))success failure:(void(^)(NSHTTPURLResponse *operation, id  _Nullable responseObject, NSError *error))failure;
+
 @end

+ 19 - 1
iOSClient/Library/OCCommunicationLib/OCWebDavClient/OCWebDAVClient.m

@@ -1157,7 +1157,7 @@ NSString const *OCWebDAVModificationDateKey	= @"modificationdate";
     [operation resume];
 }
 
-- (void)deleteEndToEndMetadata:(NSString*)serverPath onCommunication:(OCCommunication *)sharedOCCommunication success:(void(^)(NSHTTPURLResponse *operation, id response))success failure:(void(^)(NSHTTPURLResponse *operation, id  _Nullable responseObject, NSError *error))failure{
+- (void)deleteEndToEndMetadata:(NSString*)serverPath onCommunication:(OCCommunication *)sharedOCCommunication success:(void(^)(NSHTTPURLResponse *operation, id response))success failure:(void(^)(NSHTTPURLResponse *operation, id  _Nullable responseObject, NSError *error))failure {
     
     NSParameterAssert(success);
     
@@ -1172,6 +1172,24 @@ NSString const *OCWebDAVModificationDateKey	= @"modificationdate";
     [operation resume];
 }
 
+#pragma mark - Manage Mobile Editor OCS API
+
+- (void)createLinkRichdocuments:(NSString *)serverPath fileID:(NSString *)fileID onCommunication:(OCCommunication *)sharedOCCommunication success:(void(^)(NSHTTPURLResponse *operation, id response))success failure:(void(^)(NSHTTPURLResponse *operation, id  _Nullable responseObject, NSError *error))failure {
+    
+    NSParameterAssert(success);
+    
+    _requestMethod = @"POST";
+    
+    NSMutableURLRequest *request = [self sharedRequestWithMethod:_requestMethod path:serverPath parameters:nil timeout:k_timeout_webdav];
+    [request setValue:@"true" forHTTPHeaderField:@"OCS-APIRequest"];
+    [request setHTTPBody:[[NSString stringWithFormat: @"fileId=%@",fileID] dataUsingEncoding:NSUTF8StringEncoding]];
+    
+    OCHTTPRequestOperation *operation = [self mr_operationWithRequest:request onCommunication:sharedOCCommunication success:success failure:failure];
+    [self setRedirectionBlockOnDatataskWithOCCommunication:sharedOCCommunication andSessionManager:sharedOCCommunication.networkSessionManager];
+    
+    [operation resume];
+}
+
 #pragma mark - Manage Redirections
 
 - (void)setRedirectionBlockOnDatataskWithOCCommunication: (OCCommunication *) sharedOCCommunication andSessionManager:(AFURLSessionManager *) sessionManager{

+ 1 - 1
iOSClient/Library/XLForm/XL/Cell/XLFormSliderCell.m

@@ -48,7 +48,7 @@
 	[self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:self.textLabel attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.contentView attribute:NSLayoutAttributeTop multiplier:1 constant:10]];
 	[self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:self.slider attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.contentView attribute:NSLayoutAttributeTop multiplier:1 constant:44]];
 	[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[textLabel]-|" options:0 metrics:0 views:@{@"textLabel": self.textLabel}]];
-	[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[slider]-|" options:0 metrics:0 views:@{@"slider": self.slider}]];
+	[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-30-[slider]-30-|" options:0 metrics:0 views:@{@"slider": self.slider}]];
 	
 	[self valueChanged:nil];
 }

+ 55 - 114
iOSClient/Login/CCLogin.m

@@ -31,14 +31,6 @@
 {
     AppDelegate *appDelegate;
     UIView *rootView;
-    
-    NSString *serverProductName;
-    NSString *serverVersion;
-    NSString *serverVersionString;
-    
-    NSInteger versionMajor;
-    NSInteger versionMicro;
-    NSInteger versionMinor;
 }
 @end
 
@@ -232,77 +224,55 @@
     if ([self.baseUrl.text hasSuffix:@"/"])
         self.baseUrl.text = [self.baseUrl.text substringToIndex:[self.baseUrl.text length] - 1];
     
-    // add status.php for valid test url
-    NSString *urlTest = [self.baseUrl.text stringByAppendingString:k_serverStatus];
-    
-    // Remove stored cookies
-    NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
-    for (NSHTTPCookie *cookie in [storage cookies])
-    {
-        [storage deleteCookie:cookie];
-    }
-    
-    NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlTest] cachePolicy:0 timeoutInterval:20.0];
-    [request addValue:[CCUtility getUserAgent] forHTTPHeaderField:@"User-Agent"];
-    [request addValue:@"true" forHTTPHeaderField:@"OCS-APIRequest"];
-
-    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
-    NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
+    OCnetworking *ocNetworking = [[OCnetworking alloc] initWithDelegate:self metadataNet:nil withUser:@"" withUserID:@"" withPassword:@"" withUrl:nil];
+    [ocNetworking serverStatus:self.baseUrl.text success:^(NSString *serverProductName, NSInteger versionMajor, NSInteger versionMicro, NSInteger versionMinor) {
         
-    NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler: ^(NSData *data, NSURLResponse *response, NSError *error) {
+        self.loadingBaseUrl.hidden = YES;
+        self.login.enabled = YES;
+        
+        // Login Flow
+        if (_user.hidden && _password.hidden && versionMajor >= k_flow_version_available) {
             
-        dispatch_async(dispatch_get_main_queue(), ^{
-                
-            self.loadingBaseUrl.hidden = YES;
-            self.login.enabled = YES;
+            appDelegate.activeLoginWeb = [CCLoginWeb new];
+            appDelegate.activeLoginWeb.loginType = _loginType;
+            appDelegate.activeLoginWeb.delegate = self;
+            appDelegate.activeLoginWeb.urlBase = self.baseUrl.text;
             
-            if (error) {
-                    
-                if ([error code] == NSURLErrorServerCertificateUntrusted) {
-                        
-                    [[CCCertificate sharedManager] presentViewControllerCertificateWithTitle:[error localizedDescription] viewController:self delegate:self];
-                        
-                } else {
-                        
-                    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_connection_error_", nil) message:[error localizedDescription] preferredStyle:UIAlertControllerStyleAlert];
-                    UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"_ok_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {}];
-                        
-                    [alertController addAction:okAction];
-                    [self presentViewController:alertController animated:YES completion:nil];
-                }
-
-            } else {
-                    
-                [self serverStatus:data];
-                
-                // Login Flow
-                if (_user.hidden && _password.hidden && versionMajor >= k_flow_version_available) {
-                    
-                    appDelegate.activeLoginWeb = [CCLoginWeb new];
-                    appDelegate.activeLoginWeb.loginType = _loginType;
-                    appDelegate.activeLoginWeb.delegate = self;
-                    appDelegate.activeLoginWeb.urlBase = self.baseUrl.text;
-                    
-                    [appDelegate.activeLoginWeb presentModalWithDefaultTheme:self];
-                }
-                
-                // NO Login Flow available
-                if (versionMajor < k_flow_version_available) {
-                    
-                    [self.loginTypeView setHidden:YES];
-
-                    _imageUser.hidden = NO;
-                    _user.hidden = NO;
-                    _imagePassword.hidden = NO;
-                    _password.hidden = NO;
-                    
-                    [_user becomeFirstResponder];
-                }
-            }
-        });
-    }];
+            [appDelegate.activeLoginWeb presentModalWithDefaultTheme:self];
+        }
+        
+        // NO Login Flow available
+        if (versionMajor < k_flow_version_available) {
+            
+            [self.loginTypeView setHidden:YES];
+            
+            _imageUser.hidden = NO;
+            _user.hidden = NO;
+            _imagePassword.hidden = NO;
+            _password.hidden = NO;
+            
+            [_user becomeFirstResponder];
+        }
+        
+    } failure:^(NSString *message, NSInteger errorCode) {
+        
+        self.loadingBaseUrl.hidden = YES;
+        self.login.enabled = YES;
+        
+        if (errorCode == NSURLErrorServerCertificateUntrusted) {
+            
+            [[CCCertificate sharedManager] presentViewControllerCertificateWithTitle:message viewController:self delegate:self];
+            
+        } else {
+            
+            UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_connection_error_", nil) message:message preferredStyle:UIAlertControllerStyleAlert];
+            UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"_ok_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {}];
+            
+            [alertController addAction:okAction];
+            [self presentViewController:alertController animated:YES completion:nil];
+        }
         
-    [task resume];
+    }];
 }
 
 - (void)trustedCerticateAccepted
@@ -316,45 +286,6 @@
         [self handleAnnulla:self];
 }
 
--(void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler
-{
-    // The pinnning check
-    
-    if ([[CCCertificate sharedManager] checkTrustedChallenge:challenge]) {
-        completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
-    } else {
-        completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
-    }
-}
-
-- (void)serverStatus:(NSData *)data
-{
-    serverProductName = @"";
-    serverVersion = @"0.0.0";
-    serverVersionString = @"0.0.0";
-    
-    versionMajor = 0;
-    versionMicro = 0;
-    versionMinor = 0;
-    
-    NSError *error;
-    NSDictionary *jsongParsed = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
-    
-    if (error)
-        return;
-    
-    serverProductName = [jsongParsed valueForKey:@"productname"];
-    serverVersion = [jsongParsed valueForKey:@"version"];
-    serverVersionString = [jsongParsed valueForKey:@"versionstring"];
-
-    NSArray *arrayVersion = [serverVersionString componentsSeparatedByString:@"."];
-    if (arrayVersion.count >= 3) {
-        versionMajor = [arrayVersion[0] integerValue];
-        versionMicro = [arrayVersion[1] integerValue];
-        versionMinor = [arrayVersion[2] integerValue];
-    }
-}
-
 #pragma --------------------------------------------------------------------------------------------
 #pragma mark == TextField ==
 #pragma --------------------------------------------------------------------------------------------
@@ -527,4 +458,14 @@
     }
 }
 
+-(void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler
+{
+    // The pinnning check
+    if ([[CCCertificate sharedManager] checkTrustedChallenge:challenge]) {
+        completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
+    } else {
+        completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
+    }
+}
+
 @end

+ 34 - 0
iOSClient/Main/CCDetail.m

@@ -205,6 +205,36 @@
         
         fileNameExtension = [[self.metadataDetail.fileNameView pathExtension] uppercaseString];
         
+/*
+#if DEBUG
+        // Richdocument editor
+        NSString *mimeType = [CCUtility getMimeType:self.metadataDetail.fileNameView];
+        NSArray *richdocumentsMimetypes = [[NCManageDatabase sharedInstance] getRichdocumentsMimetypes];
+        
+        if (richdocumentsMimetypes.count > 0 & mimeType != nil && [mimeType componentsSeparatedByString:@"."].count > 2) {
+            NSArray *mimeTypeArray = [mimeType componentsSeparatedByString:@"."];
+            NSString* mimeType = [NSString stringWithFormat:@"%@.%@",mimeTypeArray[mimeTypeArray.count-2], mimeTypeArray[mimeTypeArray.count-1]];
+            for (NSString *richdocumentMimetype in richdocumentsMimetypes) {
+                if ([richdocumentMimetype containsString:mimeType]) {
+                    NSLog(@"Collabora");
+                    
+                    OCnetworking *ocNetworking = [[OCnetworking alloc] initWithDelegate:nil metadataNet:nil withUser:appDelegate.activeUser withUserID:appDelegate.activeUserID withPassword:appDelegate.activePassword withUrl:appDelegate.activeUrl];
+                    
+                    [ocNetworking createLinkRichdocumentsWithFileID:self.metadataDetail.fileID success:^(NSString *link) {
+                        
+                        [[NCRichdocument sharedInstance] viewRichDocumentAt:link navigationViewController:self.navigationController];
+                        
+                    } failure:^(NSString *message, NSInteger errorCode) {
+                        
+                        [appDelegate messageNotification:@"_error_" description:message visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:errorCode];
+                        [self backNavigationController];
+                        return;
+                    }];
+                }
+            }
+        }
+#endif
+*/
         if ([fileNameExtension isEqualToString:@"PDF"]) {
             
             self.edgesForExtendedLayout = UIRectEdgeBottom;
@@ -913,6 +943,10 @@
 
 - (void)viewPDF:(NSString *)password
 {
+    // remove cache PDF
+    NSString *filePlistReader = [NSString stringWithFormat:@"%@/%@.plist", [CCUtility getDirectoryReaderMetadata], self.metadataDetail.fileNameView.stringByDeletingPathExtension];
+    [CCUtility removeFileAtPath:filePlistReader];
+    
     NSString *fileNamePath = [CCUtility getDirectoryProviderStorageFileID:self.metadataDetail.fileID fileNameView:self.metadataDetail.fileNameView];
     
     if ([CCUtility fileProviderStorageExists:self.metadataDetail.fileID fileNameView:self.metadataDetail.fileNameView] == NO) {

+ 1 - 3
iOSClient/Main/CCMain.m

@@ -856,10 +856,8 @@
         NSString *serverUrl = [appDelegate getTabBarControllerActiveServerUrl];
         
         CreateFormUploadAssets *form = [[CreateFormUploadAssets alloc] initWithServerUrl:serverUrl assets:assets cryptated:NO session:k_upload_session delegate:self];
-        form.title = NSLocalizedString(@"_upload_photos_videos_", nil);
-            
+        
         UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:form];
-            
         [navigationController setModalPresentationStyle:UIModalPresentationFormSheet];
         
         [self presentViewController:navigationController animated:YES completion:nil];

+ 7 - 9
iOSClient/Main/CCMore.swift

@@ -114,16 +114,14 @@ class CCMore: UIViewController, UITableViewDelegate, UITableViewDataSource, CCLo
         item.url = "segueShares"
         functionMenu.append(item)
 
-/*
-#if DEBUG
         // ITEM : Scan
-        item = OCExternalSites.init()
-        item.name = "_scanned_images_"
-        item.icon = "scan"
-        item.url = "Scanopen"
-        functionMenu.append(item)
-#endif
-*/
+        if #available(iOS 11.0, *) {
+            item = OCExternalSites.init()
+            item.name = "_scanned_images_"
+            item.icon = "scan"
+            item.url = "Scanopen"
+            functionMenu.append(item)
+        }
         
         // ITEM : External
         

+ 2 - 2
iOSClient/Networking/CCNetworking.m

@@ -1117,9 +1117,9 @@
             // adjust file system Directory Provider Storage
             if ([tempSession isEqualToString:k_upload_session_extension]) {
                 // this is for File Provider Extension [Apple Works and ... ?]
-                [[NSFileManager defaultManager] copyItemAtPath:[NSString stringWithFormat:@"%@/%@", [CCUtility getDirectoryProviderStorage], tempFileID]  toPath:[NSString stringWithFormat:@"%@/%@", [CCUtility getDirectoryProviderStorage], metadata.fileID] error:nil];
+                [CCUtility copyFileAtPath:[NSString stringWithFormat:@"%@/%@", [CCUtility getDirectoryProviderStorage], tempFileID] toPath:[NSString stringWithFormat:@"%@/%@", [CCUtility getDirectoryProviderStorage], metadata.fileID]];
             } else {
-                [[NSFileManager defaultManager] moveItemAtPath:[NSString stringWithFormat:@"%@/%@", [CCUtility getDirectoryProviderStorage], tempFileID] toPath:[NSString stringWithFormat:@"%@/%@", [CCUtility getDirectoryProviderStorage], metadata.fileID] error:nil];
+                [CCUtility moveFileAtPath:[NSString stringWithFormat:@"%@/%@", [CCUtility getDirectoryProviderStorage], tempFileID] toPath:[NSString stringWithFormat:@"%@/%@", [CCUtility getDirectoryProviderStorage], metadata.fileID]];
             }
         }
          

+ 27 - 10
iOSClient/Networking/NCService.swift

@@ -35,7 +35,7 @@ class NCService: NSObject, OCNetworkingDelegate {
     //MARK: -
     //MARK: Start Services API NC
     
-    @objc func startRequestServicesServer() {
+    @objc public func startRequestServicesServer() {
    
         if (appDelegate.activeAccount == nil || appDelegate.activeAccount.count == 0 || appDelegate.maintenanceMode == true) {
             return
@@ -44,12 +44,13 @@ class NCService: NSObject, OCNetworkingDelegate {
         self.requestUserProfile()
         self.requestServerCapabilities()
         self.requestActivityServer()
+        self.requestServerStatus()
     }
 
     //MARK: -
-    //MARK: Request Service API NC
+    //MARK: Internal request Service API NC
     
-    @objc func requestServerCapabilities() {
+    private func requestServerCapabilities() {
         
         if (appDelegate.activeAccount == nil || appDelegate.activeAccount.count == 0 || appDelegate.maintenanceMode == true) {
             return
@@ -63,7 +64,7 @@ class NCService: NSObject, OCNetworkingDelegate {
         appDelegate.addNetworkingOperationQueue(appDelegate.netQueue, delegate: self, metadataNet: metadataNet)
     }
     
-    @objc func requestUserProfile() {
+    private func requestUserProfile() {
         
         if (appDelegate.activeAccount == nil || appDelegate.activeAccount.count == 0 || appDelegate.maintenanceMode == true) {
             return
@@ -77,7 +78,7 @@ class NCService: NSObject, OCNetworkingDelegate {
         appDelegate.addNetworkingOperationQueue(appDelegate.netQueue, delegate: self, metadataNet: metadataNet)
     }
     
-    @objc func requestActivityServer() {
+    private func requestActivityServer() {
         
         if (appDelegate.activeAccount == nil || appDelegate.activeAccount.count == 0 || appDelegate.maintenanceMode == true) {
             return
@@ -91,7 +92,7 @@ class NCService: NSObject, OCNetworkingDelegate {
         appDelegate.addNetworkingOperationQueue(appDelegate.netQueue, delegate: self, metadataNet: metadataNet)
     }
     
-    @objc func middlewarePing() {
+    @objc public func middlewarePing() {
         
         if (appDelegate.activeAccount == nil || appDelegate.activeAccount.count == 0 || appDelegate.maintenanceMode == true) {
             return
@@ -107,6 +108,22 @@ class NCService: NSObject, OCNetworkingDelegate {
         //appDelegate.addNetworkingOperationQueue(appDelegate.netQueue, delegate: self, metadataNet: metadataNet)
     }
     
+    private func requestServerStatus() {
+
+        let ocNetworking = OCnetworking.init(delegate: self, metadataNet: nil, withUser: appDelegate.activeUser, withUserID: appDelegate.activeUserID, withPassword: appDelegate.activePassword, withUrl: appDelegate.activeUrl)
+        ocNetworking?.serverStatus(appDelegate.activeUrl, success: { (serverProductName, versionMajor, versionMicro, versionMinor) in
+            
+            if serverProductName == "owncloud" {
+                self.appDelegate.messageNotification("_warning_", description: "_warning_owncloud_", visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.info, errorCode: Int(k_CCErrorInternalError))
+            } else if versionMajor <= k_nextcloud_unsupported {
+                self.appDelegate.messageNotification("_warning_", description: "_warning_unsupported_", visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.info, errorCode: Int(k_CCErrorInternalError))
+            }
+            
+        }, failure: { (message, errorCode) in
+            //
+        })
+    }
+    
     //MARK: -
     //MARK: Delegate Service API NC
     
@@ -220,7 +237,7 @@ class NCService: NSObject, OCNetworkingDelegate {
         }
     }
     
-    @objc func getUserProfileSuccessFailure(_ metadataNet: CCMetadataNet!, userProfile: OCUserProfile?, message: String?, errorCode: Int) {
+   func getUserProfileSuccessFailure(_ metadataNet: CCMetadataNet!, userProfile: OCUserProfile?, message: String?, errorCode: Int) {
         
         // Check Active Account
         if (metadataNet.account != appDelegate.activeAccount) {
@@ -286,7 +303,7 @@ class NCService: NSObject, OCNetworkingDelegate {
         }
     }
     
-    @objc func getExternalSitesServerSuccessFailure(_ metadataNet: CCMetadataNet!, listOfExternalSites: [Any]?, message: String?, errorCode: Int) {
+    func getExternalSitesServerSuccessFailure(_ metadataNet: CCMetadataNet!, listOfExternalSites: [Any]?, message: String?, errorCode: Int) {
         
         // Check Active Account
         if (metadataNet.account != appDelegate.activeAccount) {
@@ -313,7 +330,7 @@ class NCService: NSObject, OCNetworkingDelegate {
         }
     }
     
-    @objc func getActivityServerSuccessFailure(_ metadataNet: CCMetadataNet!, listOfActivity: [Any]?, message: String?, errorCode: Int) {
+    func getActivityServerSuccessFailure(_ metadataNet: CCMetadataNet!, listOfActivity: [Any]?, message: String?, errorCode: Int) {
         
         // Check Active Account
         if (metadataNet.account != appDelegate.activeAccount) {
@@ -340,7 +357,7 @@ class NCService: NSObject, OCNetworkingDelegate {
         }
     }
     
-    @objc func getNotificationServerSuccessFailure(_ metadataNet: CCMetadataNet!, listOfNotifications: [Any]?, message: String?, errorCode: Int) {
+    func getNotificationServerSuccessFailure(_ metadataNet: CCMetadataNet!, listOfNotifications: [Any]?, message: String?, errorCode: Int) {
     
         // Check Active Account
         if (metadataNet.account != appDelegate.activeAccount) {

+ 5 - 2
iOSClient/Networking/OCNetworking.h

@@ -34,15 +34,16 @@
 
 @interface OCnetworking : NSOperation <CCNetworkingDelegate>
 
-- (id)initWithDelegate:(id <OCNetworkingDelegate>)delegate metadataNet:(CCMetadataNet *)metadataNet withUser:(NSString *)withUser withUserID:(NSString *)withUserID withPassword:(NSString *)withPassword withUrl:(NSString *)withUrl;
+- (id)initWithDelegate:(id)delegate metadataNet:(CCMetadataNet *)metadataNet withUser:(NSString *)withUser withUserID:(NSString *)withUserID withPassword:(NSString *)withPassword withUrl:(NSString *)withUrl;
 
-@property (nonatomic, weak) id <OCNetworkingDelegate> delegate;
+@property (nonatomic, weak) id delegate;
 
 @property (nonatomic, strong) CCMetadataNet *metadataNet;
 @property (nonatomic, assign) BOOL isExecuting;
 @property (nonatomic, assign) BOOL isFinished;
 
 - (void)checkServer:(NSString *)serverUrl success:(void (^)(void))success failure:(void (^)(NSString *message, NSInteger errorCode))failure;
+- (void)serverStatus:(NSString *)serverUrl success:(void(^)(NSString *serverProductName, NSInteger versionMajor, NSInteger versionMicro, NSInteger versionMinor))success failure:(void (^)(NSString *message, NSInteger errorCode))failure;
 
 - (NSURLSessionTask *)downloadFileNameServerUrl:(NSString *)fileNameServerUrl fileNameLocalPath:(NSString *)fileNameLocalPath communication:(OCCommunication *)communication success:(void (^)(int64_t length, NSString *etag, NSDate *date))success failure:(void (^)(NSString *message, NSInteger errorCode))failure;
 
@@ -72,6 +73,8 @@
 
 - (void)unsubscribingPushNotificationServer:(NSString *)url deviceIdentifier:(NSString *)deviceIdentifier deviceIdentifierSignature:(NSString *)deviceIdentifierSignature publicKey:(NSString *)publicKey success:(void (^)(void))success failure:(void (^)(NSString *message, NSInteger errorCode))failure;
 
+- (void)createLinkRichdocumentsWithFileID:(NSString *)fileID success:(void(^)(NSString *link))success failure:(void (^)(NSString *message, NSInteger errorCode))failure;
+
 @end
 
 @protocol OCNetworkingDelegate <NSObject>

+ 119 - 2
iOSClient/Networking/OCNetworking.m

@@ -42,7 +42,7 @@
 
 @implementation OCnetworking
 
-- (id)initWithDelegate:(id <OCNetworkingDelegate>)delegate metadataNet:(CCMetadataNet *)metadataNet withUser:(NSString *)withUser withUserID:(NSString *)withUserID withPassword:(NSString *)withPassword withUrl:(NSString *)withUrl
+- (id)initWithDelegate:(id)delegate metadataNet:(CCMetadataNet *)metadataNet withUser:(NSString *)withUser withUserID:(NSString *)withUserID withPassword:(NSString *)withPassword withUrl:(NSString *)withUrl
 {
     self = [super init];
     
@@ -129,7 +129,7 @@
 }
 
 #pragma --------------------------------------------------------------------------------------------
-#pragma mark ===== Check Server =====
+#pragma mark ===== Server =====
 #pragma --------------------------------------------------------------------------------------------
 
 - (void)checkServer:(NSString *)serverUrl success:(void (^)(void))success failure:(void (^)(NSString *message, NSInteger errorCode))failure
@@ -161,6 +161,85 @@
     }];
 }
 
+- (void)serverStatus:(NSString *)serverUrl success:(void(^)(NSString *serverProductName, NSInteger versionMajor, NSInteger versionMicro, NSInteger versionMinor))success failure:(void (^)(NSString *message, NSInteger errorCode))failure
+{
+    NSString *urlTest = [serverUrl stringByAppendingString:k_serverStatus];
+    
+    // Remove stored cookies
+    NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
+    for (NSHTTPCookie *cookie in [storage cookies])
+    {
+        [storage deleteCookie:cookie];
+    }
+    
+    NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlTest] cachePolicy:0 timeoutInterval:20.0];
+    [request addValue:[CCUtility getUserAgent] forHTTPHeaderField:@"User-Agent"];
+    [request addValue:@"true" forHTTPHeaderField:@"OCS-APIRequest"];
+    
+    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
+    NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self.delegate delegateQueue:nil];
+    
+    NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler: ^(NSData *data, NSURLResponse *response, NSError *error) {
+        
+        if (error) {
+            
+            NSString *message;
+            NSInteger errorCode;
+            
+            NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
+            errorCode = httpResponse.statusCode;
+            
+            if (errorCode == 0 || (errorCode >= 200 && errorCode < 300))
+                errorCode = error.code;
+            
+            // Error
+            if (errorCode == 503)
+                message = NSLocalizedStringFromTable(@"_server_error_retry_", @"Error", nil);
+            else
+                message = [error.userInfo valueForKey:@"NSLocalizedDescription"];
+            
+            dispatch_async(dispatch_get_main_queue(), ^{
+                failure(message, errorCode);
+            });
+            
+        } else {
+            
+            NSString *serverProductName = @"";
+            NSString *serverVersion = @"0.0.0";
+            NSString *serverVersionString = @"0.0.0";
+            
+            NSInteger versionMajor = 0;
+            NSInteger versionMicro = 0;
+            NSInteger versionMinor = 0;
+            
+            NSError *error;
+            NSDictionary *jsongParsed = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
+            
+            if (error) {
+                failure(error.description, error.code);
+                return;
+            }
+            
+            serverProductName = [[jsongParsed valueForKey:@"productname"] lowercaseString];
+            serverVersion = [jsongParsed valueForKey:@"version"];
+            serverVersionString = [jsongParsed valueForKey:@"versionstring"];
+            
+            NSArray *arrayVersion = [serverVersionString componentsSeparatedByString:@"."];
+            if (arrayVersion.count >= 3) {
+                versionMajor = [arrayVersion[0] integerValue];
+                versionMicro = [arrayVersion[1] integerValue];
+                versionMinor = [arrayVersion[2] integerValue];
+            }
+            
+            dispatch_async(dispatch_get_main_queue(), ^{
+                success(serverProductName, versionMajor, versionMicro, versionMinor);
+            });
+        }
+    }];
+    
+    [task resume];
+}
+
 #pragma --------------------------------------------------------------------------------------------
 #pragma mark ===== download =====
 #pragma --------------------------------------------------------------------------------------------
@@ -2112,6 +2191,44 @@
     }];
 }
 
+#pragma --------------------------------------------------------------------------------------------
+#pragma mark =====  Manage Mobile Editor OCS API =====
+#pragma --------------------------------------------------------------------------------------------
+
+- (void)createLinkRichdocumentsWithFileID:(NSString *)fileID success:(void(^)(NSString *link))success failure:(void (^)(NSString *message, NSInteger errorCode))failure
+{
+    OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication;
+    
+    [communication setCredentialsWithUser:_activeUser andUserID:_activeUserID andPassword:_activePassword];
+    [communication setUserAgent:[CCUtility getUserAgent]];
+    
+    NSString *fileIDServer = [[NCUtility sharedInstance] convertFileIDClientToFileIDServer:fileID];
+    
+    [communication createLinkRichdocuments:[_activeUrl stringByAppendingString:@"/"] fileID:fileIDServer onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *link, NSString *redirectedServer) {
+        
+        success(link);
+        
+    } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
+        
+        NSString *message;
+        
+        NSInteger errorCode = response.statusCode;
+        if (errorCode == 0 || (errorCode >= 200 && errorCode < 300))
+            errorCode = error.code;
+        
+        // Error
+        if (errorCode == 503)
+            message = NSLocalizedStringFromTable(@"_server_error_retry_", @"Error", nil);
+        else
+            message = [error.userInfo valueForKey:@"NSLocalizedDescription"];
+        
+        // Activity
+        [[NCManageDatabase sharedInstance] addActivityClient:_activeUrl fileID:@"" action:k_activityDebugActionUnsubscribingServerPush selector:@"" note:[error.userInfo valueForKey:@"NSLocalizedDescription"] type:k_activityTypeFailure verbose:k_activityVerboseHigh activeUrl:_activeUrl];
+        
+        failure(message, errorCode);
+    }];
+}
+
 @end
 
 #pragma --------------------------------------------------------------------------------------------

+ 65 - 0
iOSClient/Richdocument/NCRichdocument.swift

@@ -0,0 +1,65 @@
+//
+//  NCRichdocument.swift
+//  Nextcloud
+//
+//  Created by Marino Faggiana on 06/09/18.
+//  Copyright © 2018 TWS. All rights reserved.
+//
+//  Author Marino Faggiana <m.faggiana@twsweb.it>
+//
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+
+import Foundation
+
+class NCRichdocument: NSObject, SwiftWebVCDelegate {
+    
+    @objc static let sharedInstance: NCRichdocument = {
+        let instance = NCRichdocument()
+        return instance
+    }()
+    
+    let appDelegate = UIApplication.shared.delegate as! AppDelegate
+
+    @objc func viewRichDocumentAt(_ link: String, navigationViewController: UINavigationController) {
+        
+        let webVC = SwiftWebVC(urlString: link, hideToolbar: true)
+        webVC.delegate = self
+        navigationViewController.setViewControllers([webVC], animated: false)
+    }
+    
+    func didStartLoading() {
+        print("Started loading.")
+    }
+    
+    func didReceiveServerRedirectForProvisionalNavigation(url: URL) {
+        
+    }
+    
+    func didFinishLoading(success: Bool) {
+        print("Finished loading. Success: \(success).")
+    }
+    
+    func didFinishLoading(success: Bool, url: URL) {
+        print("Finished loading. Success: \(success).")
+    }
+    
+    func webDismiss() {
+        print("Web dismiss.")
+    }
+    
+    func decidePolicyForNavigationAction(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
+        decisionHandler(.allow)
+    }
+}

+ 33 - 12
iOSClient/Scan/Scan.storyboard

@@ -41,10 +41,10 @@
                                                 <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="sam-7M-bIk">
                                                     <rect key="frame" x="20" y="20" width="100" height="100"/>
                                                 </imageView>
-                                                <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="06r-jm-ARX">
+                                                <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="06r-jm-ARX">
                                                     <rect key="frame" x="0.0" y="0.0" width="25" height="25"/>
                                                     <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
-                                                    <state key="normal" backgroundImage="no_red"/>
+                                                    <state key="normal" image="deleteScan"/>
                                                 </button>
                                             </subviews>
                                         </view>
@@ -68,25 +68,28 @@
                             <collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="fGo-qU-AYi" userLabel="collectionViewDestination">
                                 <rect key="frame" x="0.0" y="278" width="375" height="339"/>
                                 <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="339" id="nTl-vy-iQ8"/>
+                                </constraints>
                                 <collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="0.0" minimumInteritemSpacing="0.0" id="9Sn-Y3-S86">
-                                    <size key="itemSize" width="140" height="140"/>
+                                    <size key="itemSize" width="120" height="120"/>
                                     <size key="headerReferenceSize" width="0.0" height="0.0"/>
                                     <size key="footerReferenceSize" width="0.0" height="0.0"/>
                                     <inset key="sectionInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
                                 </collectionViewFlowLayout>
                                 <cells>
                                     <collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="cell2" id="Pph-tY-PGX" customClass="ScanCell" customModule="Nextcloud" customModuleProvider="target">
-                                        <rect key="frame" x="0.0" y="0.0" width="140" height="140"/>
+                                        <rect key="frame" x="0.0" y="0.0" width="120" height="120"/>
                                         <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
                                         <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO">
-                                            <rect key="frame" x="0.0" y="0.0" width="140" height="140"/>
+                                            <rect key="frame" x="0.0" y="0.0" width="120" height="120"/>
                                             <autoresizingMask key="autoresizingMask"/>
                                             <subviews>
                                                 <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="sdV-W7-Hkd">
-                                                    <rect key="frame" x="20" y="20" width="100" height="100"/>
+                                                    <rect key="frame" x="20" y="20" width="80" height="80"/>
                                                 </imageView>
                                                 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Page" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="wcM-U8-GLh">
-                                                    <rect key="frame" x="20" y="100" width="100" height="20"/>
+                                                    <rect key="frame" x="20" y="100" width="80" height="20"/>
                                                     <color key="backgroundColor" white="0.0" alpha="0.39940068490000002" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                                     <constraints>
                                                         <constraint firstAttribute="height" constant="20" id="8He-ef-19r"/>
@@ -95,10 +98,10 @@
                                                     <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                                     <nil key="highlightedColor"/>
                                                 </label>
-                                                <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="wSg-Gm-0s3">
+                                                <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="wSg-Gm-0s3">
                                                     <rect key="frame" x="0.0" y="0.0" width="25" height="25"/>
                                                     <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
-                                                    <state key="normal" backgroundImage="no_red"/>
+                                                    <state key="normal" image="deleteScan"/>
                                                 </button>
                                             </subviews>
                                         </view>
@@ -108,7 +111,7 @@
                                             <constraint firstAttribute="trailing" secondItem="sdV-W7-Hkd" secondAttribute="trailing" constant="20" id="Jia-SE-8bu"/>
                                             <constraint firstAttribute="bottom" secondItem="sdV-W7-Hkd" secondAttribute="bottom" constant="20" id="Ljw-b9-Sp8"/>
                                             <constraint firstItem="sdV-W7-Hkd" firstAttribute="leading" secondItem="Pph-tY-PGX" secondAttribute="leading" constant="20" id="kwQ-gl-6Bj"/>
-                                            <constraint firstAttribute="bottom" secondItem="wcM-U8-GLh" secondAttribute="bottom" constant="20" id="qat-UY-DBH"/>
+                                            <constraint firstAttribute="bottom" secondItem="wcM-U8-GLh" secondAttribute="bottom" id="qat-UY-DBH"/>
                                             <constraint firstAttribute="trailing" secondItem="wcM-U8-GLh" secondAttribute="trailing" constant="20" id="rLg-WD-x2l"/>
                                         </constraints>
                                         <connections>
@@ -144,6 +147,21 @@
                                     <action selector="addWithSender:" destination="BYZ-38-t0r" eventType="touchUpInside" id="bkr-97-4RR"/>
                                 </connections>
                             </button>
+                            <segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="b3i-bF-ITj">
+                                <rect key="frame" x="16" y="629" width="343" height="28"/>
+                                <constraints>
+                                    <constraint firstAttribute="width" constant="343" id="BL3-tS-haJ"/>
+                                    <constraint firstAttribute="height" constant="27" id="Kx0-Zp-wJh"/>
+                                </constraints>
+                                <segments>
+                                    <segment title="First"/>
+                                    <segment title="Second"/>
+                                    <segment title="Third"/>
+                                </segments>
+                                <connections>
+                                    <action selector="indexChanged:" destination="BYZ-38-t0r" eventType="valueChanged" id="yeI-C2-uGJ"/>
+                                </connections>
+                            </segmentedControl>
                         </subviews>
                         <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                         <constraints>
@@ -153,11 +171,13 @@
                             <constraint firstItem="0Gy-eG-A0f" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" constant="18" id="BNZ-HM-6yi"/>
                             <constraint firstItem="jwq-kF-6Nq" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" constant="57" id="ELU-RG-o16"/>
                             <constraint firstItem="fGo-qU-AYi" firstAttribute="trailing" secondItem="6Tk-OE-BBY" secondAttribute="trailing" id="Ew2-9q-DKl"/>
-                            <constraint firstAttribute="bottom" secondItem="fGo-qU-AYi" secondAttribute="bottom" constant="50" id="Eza-ZC-K9z"/>
                             <constraint firstItem="YHy-9G-ngy" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" id="FvJ-EK-Evb"/>
                             <constraint firstItem="0Gy-eG-A0f" firstAttribute="top" secondItem="6Tk-OE-BBY" secondAttribute="top" constant="72" id="O4H-NJ-Mot"/>
                             <constraint firstItem="fGo-qU-AYi" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" id="aU0-Bn-B6T"/>
                             <constraint firstItem="jwq-kF-6Nq" firstAttribute="top" secondItem="6Tk-OE-BBY" secondAttribute="top" constant="8" id="dyH-ym-lrb"/>
+                            <constraint firstItem="6Tk-OE-BBY" firstAttribute="bottom" secondItem="b3i-bF-ITj" secondAttribute="bottom" constant="11" id="iCt-vj-sDA"/>
+                            <constraint firstItem="b3i-bF-ITj" firstAttribute="top" secondItem="fGo-qU-AYi" secondAttribute="bottom" constant="12" id="kGQ-oN-ccm"/>
+                            <constraint firstItem="b3i-bF-ITj" firstAttribute="centerX" secondItem="6Tk-OE-BBY" secondAttribute="centerX" id="p4i-a8-soi"/>
                             <constraint firstItem="fGo-qU-AYi" firstAttribute="top" secondItem="YHy-9G-ngy" secondAttribute="bottom" constant="8" id="x2i-aj-hzf"/>
                         </constraints>
                         <viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
@@ -181,6 +201,7 @@
                         <outlet property="collectionViewSource" destination="jwq-kF-6Nq" id="6hn-7D-P8K"/>
                         <outlet property="labelTitlePDFzone" destination="YHy-9G-ngy" id="hQk-4n-stD"/>
                         <outlet property="save" destination="LAS-W8-RG6" id="Dan-xp-JAB"/>
+                        <outlet property="segmentControlFilter" destination="b3i-bF-ITj" id="lPr-xp-LVI"/>
                     </connections>
                 </viewController>
                 <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
@@ -211,6 +232,6 @@
     </scenes>
     <resources>
         <image name="add" width="25" height="25"/>
-        <image name="no_red" width="25" height="25"/>
+        <image name="deleteScan" width="25" height="25"/>
     </resources>
 </document>

+ 226 - 86
iOSClient/Scan/ScanCollectionView.swift

@@ -27,27 +27,33 @@ import UIKit
 
 class DragDropViewController: UIViewController {
     
-    //MARK: Private Properties
     //Data Source for collectionViewSource
     private var itemsSource = [String]()
     
     //Data Source for collectionViewDestination
-    private var itemsDestination = [String]()
+    private var imagesDestination = [UIImage]()
 
     //AppDelegate
-    let appDelegate = UIApplication.shared.delegate as! AppDelegate
+    private let appDelegate = UIApplication.shared.delegate as! AppDelegate
 
     //MARK: Outlets
     @IBOutlet weak var collectionViewSource: UICollectionView!
     @IBOutlet weak var collectionViewDestination: UICollectionView!
-    
     @IBOutlet weak var cancel: UIBarButtonItem!
     @IBOutlet weak var save: UIBarButtonItem!
-
     @IBOutlet weak var add: UIButton!
-
     @IBOutlet weak var labelTitlePDFzone: UILabel!
+    @IBOutlet weak var segmentControlFilter: UISegmentedControl!
 
+    // filter
+    enum typeFilter {
+        case original
+        case grayScale
+        case bn
+    }
+    private var filter: typeFilter = typeFilter.grayScale
+    
+    override var canBecomeFirstResponder: Bool { return true }
     
     //MARK: View Lifecycle Methods
     override func viewDidLoad() {
@@ -65,22 +71,35 @@ class DragDropViewController: UIViewController {
         self.navigationItem.title = NSLocalizedString("_scanned_images_", comment: "")
         cancel.title = NSLocalizedString("_cancel_", comment: "")
         save.title = NSLocalizedString("_save_", comment: "")
-        labelTitlePDFzone.text = NSLocalizedString("_scan_label_PDF_zone_", comment: "")
-        
+        labelTitlePDFzone.text = NSLocalizedString("_scan_label_document_zone_", comment: "")
+        segmentControlFilter.setTitle(NSLocalizedString("_filter_grayscale_", comment: ""), forSegmentAt: 0)
+        segmentControlFilter.setTitle(NSLocalizedString("_filter_bn_", comment: ""), forSegmentAt: 1)
+        segmentControlFilter.setTitle(NSLocalizedString("_filter_original_", comment: ""), forSegmentAt: 2)
+
         add.setImage(CCGraphics.changeThemingColorImage(UIImage(named: "add"), multiplier:2, color: NCBrandColor.sharedInstance.brand), for: .normal)
+        
+        let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPressGesture(recognizer:)))
+        add.addGestureRecognizer(longPressRecognizer)
     }
     
     override func viewWillAppear(_ animated: Bool) {
         super.viewWillAppear(animated)
         
         appDelegate.aspectNavigationControllerBar(self.navigationController?.navigationBar, online: appDelegate.reachability.isReachable(), hidden: false)
-//        appDelegate.aspectTabBar(self.tabBarController?.tabBar, hidden: false)
         
         labelTitlePDFzone.textColor = NCBrandColor.sharedInstance.brandText
         labelTitlePDFzone.backgroundColor = NCBrandColor.sharedInstance.brand
         
+        segmentControlFilter.tintColor = NCBrandColor.sharedInstance.brand
+        
+        // Save button
+        if imagesDestination.count == 0 {
+            save.isEnabled = false
+        } else {
+            save.isEnabled = true
+        }
+        
         loadImage(atPath: CCUtility.getDirectoryScan(), items: &itemsSource)
-//        loadImage(atPath: CCUtility.getDirectoryScanSelect(), items: &itemsDestination)
     }
     
     //MARK: Button Action
@@ -91,8 +110,15 @@ class DragDropViewController: UIViewController {
     
     @IBAction func saveAction(sender: UIBarButtonItem) {
         
-        if itemsDestination.count > 0 {
-            let formViewController = CreateFormUploadScanDocument.init(serverUrl: appDelegate.activeMain.serverUrl, arrayFileName: self.itemsDestination)
+        if imagesDestination.count > 0 {
+            
+            var images = [UIImage]()
+
+            for image in imagesDestination {
+                images.append(filter(image: image)!)
+            }
+            
+            let formViewController = CreateFormUploadScanDocument.init(serverUrl: appDelegate.activeMain.serverUrl, arrayImages: images)
             self.navigationController?.pushViewController(formViewController, animated: true)
         }
     }
@@ -102,6 +128,26 @@ class DragDropViewController: UIViewController {
         NCCreateScanDocument.sharedInstance.openScannerDocument(viewController: self, openScan: false)
     }
     
+    @IBAction func indexChanged(_ sender: AnyObject) {
+        
+        switch segmentControlFilter.selectedSegmentIndex
+        {
+        case 0:
+            // Grayscale
+            filter = typeFilter.grayScale
+        case 1:
+            // Original
+            filter = typeFilter.bn
+        case 2:
+            // Original
+            filter = typeFilter.original
+        default:
+            break
+        }
+        
+        self.collectionViewDestination.reloadData()
+    }
+    
     //MARK: Private Methods
     
     private func loadImage(atPath: String, items: inout [String]) {
@@ -111,19 +157,35 @@ class DragDropViewController: UIViewController {
         do {
             let directoryContents = try FileManager.default.contentsOfDirectory(atPath: atPath)
             for fileName in directoryContents {
-                if fileName != "Select" && fileName.first != "." {
+                if fileName.first != "." {
                     items.append(fileName)
                 }
             }
         } catch {
             print(error.localizedDescription)
         }
+        
+        self.collectionViewSource.reloadData()
     }
     
     func filter(image: UIImage) -> UIImage? {
         
+        var inputContrast: Double = 0
+        
+        if filter == typeFilter.original {
+            return image
+        }
+        
+        if filter == typeFilter.grayScale {
+            inputContrast = 1
+        }
+        
+        if filter == typeFilter.bn {
+            inputContrast = 4
+        }
+        
         let ciImage = CIImage(image: image)!
-        let imageFilter = ciImage.applyingFilter("CIColorControls", parameters: ["inputSaturation": 0, "inputContrast": 1])
+        let imageFilter = ciImage.applyingFilter("CIColorControls", parameters: ["inputSaturation": 0, "inputContrast": inputContrast])
         
         let context:CIContext = CIContext.init(options: nil)
         let cgImage:CGImage = context.createCGImage(imageFilter, from: imageFilter.extent)!
@@ -137,6 +199,7 @@ class DragDropViewController: UIViewController {
     ///   - coordinator: coordinator obtained from performDropWith: UICollectionViewDropDelegate method
     ///   - destinationIndexPath: indexpath of the collection view where the user drops the element
     ///   - collectionView: collectionView in which reordering needs to be done.
+    
     private func reorderItems(coordinator: UICollectionViewDropCoordinator, destinationIndexPath: IndexPath, collectionView: UICollectionView) {
         
         let items = coordinator.items
@@ -153,8 +216,8 @@ class DragDropViewController: UIViewController {
                 
                 if collectionView === self.collectionViewDestination {
                     
-                    self.itemsDestination.remove(at: sourceIndexPath.row)
-                    self.itemsDestination.insert(item.dragItem.localObject as! String, at: dIndexPath.row)
+                    self.imagesDestination.remove(at: sourceIndexPath.row)
+                    self.imagesDestination.insert(item.dragItem.localObject as! UIImage, at: dIndexPath.row)
                     
                 } else {
                     
@@ -176,6 +239,7 @@ class DragDropViewController: UIViewController {
     ///   - coordinator: coordinator obtained from performDropWith: UICollectionViewDropDelegate method
     ///   - destinationIndexPath: indexpath of the collection view where the user drops the element
     ///   - collectionView: collectionView in which reordering needs to be done.
+    
     private func copyItems(coordinator: UICollectionViewDropCoordinator, destinationIndexPath: IndexPath, collectionView: UICollectionView)
     {
         collectionView.performBatchUpdates({
@@ -188,9 +252,8 @@ class DragDropViewController: UIViewController {
                 
                 if collectionView === self.collectionViewDestination {
                     
-                    let fileName = item.dragItem.localObject as! String
-                    let fileNamePathAt = CCUtility.getDirectoryScan() + "/" + fileName
-                    let fileNamePathTo = CCUtility.getDirectoryScanSelect() + "/" + fileName
+                    let fileName = item.dragItem.localObject as! NSString
+                    let fileNamePathAt = CCUtility.getDirectoryScan() + "/" + (fileName as String)
                     
                     guard let data = try? Data(contentsOf: fileNamePathAt.url) else {
                         return
@@ -198,23 +261,13 @@ class DragDropViewController: UIViewController {
                     guard let image =  UIImage(data: data) else {
                         return
                     }
-                    guard let imageFilter = self.filter(image: image) else {
-                        return
-                    }
-                    
-                    let imageData = UIImageJPEGRepresentation(imageFilter, 0.5)!
-                    
-                    do {
-                        try imageData.write(to: fileNamePathTo.url)
-                    } catch {
-                        return
-                    }
-                    
-                    self.itemsDestination.insert(item.dragItem.localObject as! String, at: indexPath.row)
+                   
+                    self.imagesDestination.insert(image, at: indexPath.row)
                     
                 } else {
                     
-                    self.itemsSource.insert(item.dragItem.localObject as! String, at: indexPath.row)
+                    // NOT PERMITTED
+                    return
                 }
                 
                 indexPaths.append(indexPath)
@@ -223,6 +276,64 @@ class DragDropViewController: UIViewController {
             collectionView.insertItems(at: indexPaths)
         })
     }
+    
+    // MARK: - UIGestureRecognizerv - Paste
+    
+    @objc func handleLongPressGesture(recognizer: UIGestureRecognizer) {
+        
+        if recognizer.state == UIGestureRecognizerState.began {
+        
+            self.becomeFirstResponder()
+            
+            let pasteboard = UIPasteboard.general
+            
+            if let recognizerView = recognizer.view, let recognizerSuperView = recognizerView.superview, pasteboard.hasImages {
+                
+                UIMenuController.shared.menuItems = [UIMenuItem(title: "Paste", action: #selector(pasteImage))]
+                UIMenuController.shared.setTargetRect(recognizerView.frame, in: recognizerSuperView)
+                UIMenuController.shared.setMenuVisible(true, animated:true)
+            }
+        }
+    }
+    
+    override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
+        if action == #selector(pasteImage) {
+            return true
+        }
+        return false
+    }
+    
+    @objc func pasteImage() {
+        
+        let pasteboard = UIPasteboard.general
+        
+        if pasteboard.hasImages {
+            
+            let fileName = CCUtility.createFileName("scan.png", fileDate: Date(), fileType: PHAssetMediaType.image, keyFileName: k_keyFileNameMask, keyFileNameType: k_keyFileNameType, keyFileNameOriginal: k_keyFileNameOriginal)!
+            let fileNamePath = CCUtility.getDirectoryScan() + "/" + fileName
+            
+            guard var image = pasteboard.image else {
+                return
+            }
+            
+            // A4 74 DPI : 595 x 842 px
+            
+            let imageWidthInPixels = image.size.width * image.scale
+            let imageHeightInPixels = image.size.height * image.scale
+            
+            if imageWidthInPixels > 595 || imageHeightInPixels > 842  {
+                image = CCGraphics.scale(image, to: CGSize(width: 595, height: 842), isAspectRation: true)
+            }
+            
+            do {
+                try UIImagePNGRepresentation(image)?.write(to: NSURL.fileURL(withPath: fileNamePath), options: .atomic)
+            } catch {
+                return
+            }
+            
+            loadImage(atPath: CCUtility.getDirectoryScan(), items: &itemsSource)
+        }
+    }
 }
 
 // MARK: - UICollectionViewDataSource Methods
@@ -233,7 +344,7 @@ extension DragDropViewController : UICollectionViewDataSource {
     
     func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
         
-        return collectionView == self.collectionViewSource ? self.itemsSource.count : self.itemsDestination.count
+        return collectionView == self.collectionViewSource ? self.itemsSource.count : self.imagesDestination.count
     }
     
     func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
@@ -249,7 +360,7 @@ extension DragDropViewController : UICollectionViewDataSource {
             }
             
             cell.customImageView?.image = UIImage(data: data)
-            cell.delete.setImage(CCGraphics.changeThemingColorImage(UIImage(named: "no_red"), multiplier:2, color: NCBrandColor.sharedInstance.icon).withRenderingMode(.alwaysOriginal), for: .normal)
+//            cell.delete.setImage(CCGraphics.changeThemingColorImage(UIImage(named: "no_red"), multiplier:2, color: NCBrandColor.sharedInstance.icon).withRenderingMode(.alwaysOriginal), for: .normal)
             cell.delete.addTarget(self, action: #selector(deleteSource(_:)), for: .touchUpInside)
 
             return cell
@@ -258,19 +369,11 @@ extension DragDropViewController : UICollectionViewDataSource {
             
             let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell2", for: indexPath) as! ScanCell
             
-            let fileNamePath = CCUtility.getDirectoryScan() + "/" + self.itemsDestination[indexPath.row]
-            
-            guard let data = try? Data(contentsOf: fileNamePath.url) else {
-                return cell
-            }
-            
-            guard let image = UIImage(data: data) else {
-                return cell
-            }
+            let image = self.imagesDestination[indexPath.row]
             
             cell.customImageView?.image = self.filter(image: image)
             cell.customLabel.text = NSLocalizedString("_scan_document_pdf_page_", comment: "") + " " + "\(indexPath.row+1)"
-            cell.delete.setImage(CCGraphics.changeThemingColorImage(UIImage(named: "no_red"), multiplier:2, color: NCBrandColor.sharedInstance.icon).withRenderingMode(.alwaysOriginal), for: .normal)
+//            cell.delete.setImage(CCGraphics.changeThemingColorImage(UIImage(named: "no_red"), multiplier:2, color: NCBrandColor.sharedInstance.icon).withRenderingMode(.alwaysOriginal), for: .normal)
             cell.delete.addTarget(self, action: #selector(deleteDestination(_:)), for: .touchUpInside)
             
             return cell
@@ -294,21 +397,16 @@ extension DragDropViewController : UICollectionViewDataSource {
         let buttonPosition:CGPoint =  sender.convert(.zero, to: self.collectionViewDestination)
         let indexPath:IndexPath = self.collectionViewDestination.indexPathForItem(at: buttonPosition)!
         
-        // Remove file only if exist 1 item
-        var cont = 0
-        for item in itemsDestination {
-            if item == self.itemsDestination[indexPath.row] {
-                cont += 1
-            }
-        }
-        
-        if cont == 1 {
-            let fileNameAtPath = CCUtility.getDirectoryScanSelect() + "/" + self.itemsDestination[indexPath.row]
-            CCUtility.removeFile(atPath: fileNameAtPath)
-        }
-        self.itemsDestination.remove(at: indexPath.row)
+        self.imagesDestination.remove(at: indexPath.row)
         
         self.collectionViewDestination.reloadData()
+        
+        // Save button
+        if imagesDestination.count == 0 {
+            save.isEnabled = false
+        } else {
+            save.isEnabled = true
+        }
     }
 }
 
@@ -320,30 +418,56 @@ extension DragDropViewController : UICollectionViewDragDelegate
 {
     func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
         
-        let item = collectionView == collectionViewSource ? self.itemsSource[indexPath.row] : self.itemsDestination[indexPath.row]
-        let itemProvider = NSItemProvider(object: item as NSString)
-        let dragItem = UIDragItem(itemProvider: itemProvider)
-        
-        dragItem.localObject = item
-        
-        return [dragItem]
+        if collectionView == self.collectionViewSource {
+            let item = self.itemsSource[indexPath.row]
+            let itemProvider = NSItemProvider(object: item as NSString)
+            let dragItem = UIDragItem(itemProvider: itemProvider)
+
+            dragItem.localObject = item
+
+            return [dragItem]
+
+        } else {
+            let item = self.imagesDestination[indexPath.row]
+            let itemProvider = NSItemProvider(object: item as UIImage)
+            let dragItem = UIDragItem(itemProvider: itemProvider)
+
+            dragItem.localObject = item
+            
+            return [dragItem]
+        }
     }
     
     func collectionView(_ collectionView: UICollectionView, itemsForAddingTo session: UIDragSession, at indexPath: IndexPath, point: CGPoint) -> [UIDragItem] {
         
-        let item = collectionView == collectionViewSource ? self.itemsSource[indexPath.row] : self.itemsDestination[indexPath.row]
-        let itemProvider = NSItemProvider(object: item as NSString)
-        let dragItem = UIDragItem(itemProvider: itemProvider)
-        
-        dragItem.localObject = item
-        
-        return [dragItem]
+        if collectionView == self.collectionViewSource {
+            let item = self.itemsSource[indexPath.row]
+            let itemProvider = NSItemProvider(object: item as NSString)
+            let dragItem = UIDragItem(itemProvider: itemProvider)
+            
+            dragItem.localObject = item
+            
+            return [dragItem]
+            
+        } else {
+            let item = self.imagesDestination[indexPath.row]
+            let itemProvider = NSItemProvider(object: item as UIImage)
+            let dragItem = UIDragItem(itemProvider: itemProvider)
+            
+            dragItem.localObject = item
+            
+            return [dragItem]
+        }
     }
     
     func collectionView(_ collectionView: UICollectionView, dragPreviewParametersForItemAt indexPath: IndexPath) -> UIDragPreviewParameters? {
         
         let previewParameters = UIDragPreviewParameters()
-        previewParameters.visiblePath = UIBezierPath(rect: CGRect(x: 20, y: 20, width: 100, height: 100))
+        if collectionView == self.collectionViewSource {
+            previewParameters.visiblePath = UIBezierPath(rect: CGRect(x: 20, y: 20, width: 100, height: 100))
+        } else {
+            previewParameters.visiblePath = UIBezierPath(rect: CGRect(x: 20, y: 20, width: 80, height: 80))
+        }
          
         return previewParameters
     }
@@ -357,7 +481,7 @@ extension DragDropViewController : UICollectionViewDropDelegate {
     
     func collectionView(_ collectionView: UICollectionView, canHandle session: UIDropSession) -> Bool {
         
-        return session.canLoadObjects(ofClass: NSString.self)
+        return true //session.canLoadObjects(ofClass: NSString.self)
     }
     
     func collectionView(_ collectionView: UICollectionView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UICollectionViewDropProposal {
@@ -384,27 +508,35 @@ extension DragDropViewController : UICollectionViewDropDelegate {
         
         let destinationIndexPath: IndexPath
         
-        if let indexPath = coordinator.destinationIndexPath {
+        switch coordinator.proposal.operation {
             
-            destinationIndexPath = indexPath
+        case .move:
             
-        } else {
+            if let indexPath = coordinator.destinationIndexPath {
+                
+                destinationIndexPath = indexPath
+                
+            } else {
+                
+                // Get last index path of table view.
+                let section = collectionView.numberOfSections - 1
+                let row = collectionView.numberOfItems(inSection: section)
+                
+                destinationIndexPath = IndexPath(row: row, section: section)
+            }
+            self.reorderItems(coordinator: coordinator, destinationIndexPath: destinationIndexPath, collectionView: collectionView)
+            
+            break
+            
+        case .copy:
             
             // Get last index path of table view.
             let section = collectionView.numberOfSections - 1
             let row = collectionView.numberOfItems(inSection: section)
             
             destinationIndexPath = IndexPath(row: row, section: section)
-        }
-        
-        switch coordinator.proposal.operation {
-            
-        case .move:
-            self.reorderItems(coordinator: coordinator, destinationIndexPath: destinationIndexPath, collectionView: collectionView)
-            break
-            
-        case .copy:
             self.copyItems(coordinator: coordinator, destinationIndexPath: destinationIndexPath, collectionView: collectionView)
+            
             break
             
         default:
@@ -413,7 +545,15 @@ extension DragDropViewController : UICollectionViewDropDelegate {
     }
     
     func collectionView(_ collectionView: UICollectionView, dropSessionDidEnd session: UIDropSession) {
+        
         self.collectionViewDestination.reloadData()
+        
+        // Save button
+        if imagesDestination.count == 0 {
+            save.isEnabled = false
+        } else {
+            save.isEnabled = true
+        }
     }
 }
 

+ 1 - 1
iOSClient/Scan/WeScan/ImageScannerController.swift

@@ -63,7 +63,7 @@ public final class ImageScannerController: UINavigationController {
     public required init() {
         let scannerViewController = ScannerViewController()
         super.init(rootViewController: scannerViewController)
-        navigationBar.tintColor = .black
+        navigationBar.tintColor = NCBrandColor.sharedInstance.brandText
         navigationBar.isTranslucent = false
         self.view.addSubview(blackFlashView)
         setupConstraints()

+ 1 - 1
iOSClient/Scan/WeScan/Scan/CloseButton.swift

@@ -31,7 +31,7 @@ final class CloseButton: UIControl {
         xLayer.lineWidth = 3.0
         xLayer.path = pathForX(inRect: rect.insetBy(dx: xLayer.lineWidth / 2, dy: xLayer.lineWidth / 2)).cgPath
         xLayer.fillColor = UIColor.clear.cgColor
-        xLayer.strokeColor = UIColor.black.cgColor
+        xLayer.strokeColor = NCBrandColor.sharedInstance.brandText.cgColor
         xLayer.lineCap = kCALineCapRound
     }
     

+ 4 - 1
iOSClient/Scan/WeScan/Scan/ScannerViewController.swift

@@ -35,7 +35,7 @@ final class ScannerViewController: UIViewController {
     }()
 
     lazy private var closeButton: CloseButton = {
-        let button = CloseButton(frame: CGRect(x: 0, y: 0, width: 18, height: 18))
+        let button = CloseButton(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
         button.addTarget(self, action: #selector(cancelImageScannerController(_:)), for: .touchUpInside)
         return button
     }()
@@ -60,6 +60,9 @@ final class ScannerViewController: UIViewController {
         quadView.removeQuadrilateral()
         captureSessionManager?.start()
         UIApplication.shared.isIdleTimerDisabled = true
+        
+        self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: NCBrandColor.sharedInstance.brandText]
+        self.navigationController?.navigationBar.barTintColor = NCBrandColor.sharedInstance.brand
     }
     
     override func viewDidLayoutSubviews() {

+ 18 - 0
iOSClient/Settings/Acknowledgements.rtf

@@ -246,4 +246,22 @@ The MIT License (MIT)\
 \
 Copyright (c) libobjc\
 ____________________________________________\
+\
+
+\b PDFGenerator
+\b0 \
+\
+The MIT License (MIT)\
+\
+Copyright (c) Suguru Kishimoto\
+____________________________________________\
+\
+Includes a modified version of 
+\b WeScan 
+\b0 \
+\
+The MIT License (MIT)\
+\
+Copyright (c) WeTransfer\
+____________________________________________\
 }

+ 24 - 15
iOSClient/Settings/NCManageAutoUploadFileName.swift

@@ -46,47 +46,58 @@ class NCManageAutoUploadFileName: XLFormViewController {
         var section : XLFormSectionDescriptor
         var row : XLFormRowDescriptor
 
-        section = XLFormSectionDescriptor.formSection()
+        // Section Mode filename
+
+        section = XLFormSectionDescriptor.formSection(withTitle: NSLocalizedString("_mode_filename_", comment: ""))
         form.addFormSection(section)
         
         // Maintain the original fileName
         
         row = XLFormRowDescriptor(tag: "maintainOriginalFileName", rowType: XLFormRowDescriptorTypeBooleanSwitch, title: NSLocalizedString("_maintain_original_filename_", comment: ""))
-        row.cellConfig.setObject(UIFont.systemFont(ofSize: 15.0), forKey: "textLabel.font" as NSCopying)
         row.value = CCUtility.getOriginalFileName(k_keyFileNameOriginalAutoUpload)
+
+        row.cellConfig["textLabel.font"] = UIFont.systemFont(ofSize: 15.0)
+
         section.addFormRow(row)
         
         // Add File Name Type
         
         row = XLFormRowDescriptor(tag: "addFileNameType", rowType: XLFormRowDescriptorTypeBooleanSwitch, title: NSLocalizedString("_add_filenametype_", comment: ""))
-        row.hidden = "$\("maintainOriginalFileName") == 1"
-        row.cellConfig.setObject(UIFont.systemFont(ofSize: 15.0), forKey: "textLabel.font" as NSCopying)
         row.value = CCUtility.getFileNameType(k_keyFileNameAutoUploadType)
+        row.hidden = "$\("maintainOriginalFileName") == 1"
+
+        row.cellConfig["textLabel.font"] = UIFont.systemFont(ofSize: 15.0)
+
         section.addFormRow(row)
                 
         // Section: Rename File Name
         
-        section = XLFormSectionDescriptor.formSection()
+        section = XLFormSectionDescriptor.formSection(withTitle: NSLocalizedString("_filename_", comment: ""))
         form.addFormSection(section)
         
-        row = XLFormRowDescriptor(tag: "maskFileName", rowType: XLFormRowDescriptorTypeAccount, title: (NSLocalizedString("_filename_", comment: ""))+":")
-        row.hidden = "$\("maintainOriginalFileName") == 1"
-        row.cellConfig.setObject(UIFont.systemFont(ofSize: 15.0), forKey: "textLabel.font" as NSCopying)
+        row = XLFormRowDescriptor(tag: "maskFileName", rowType: XLFormRowDescriptorTypeAccount, title: (NSLocalizedString("_filename_", comment: "")))
         let fileNameMask : String = CCUtility.getFileNameMask(k_keyFileNameAutoUploadMask)
         if fileNameMask.count > 0 {
             row.value = fileNameMask
         }
+        row.hidden = "$\("maintainOriginalFileName") == 1"
+        
+        row.cellConfig["textLabel.font"] = UIFont.systemFont(ofSize: 15.0)
+        
+        row.cellConfig["textField.textAlignment"] = NSTextAlignment.right.rawValue
+        row.cellConfig["textField.font"] = UIFont.systemFont(ofSize: 15.0)
+        
         section.addFormRow(row)
         
         // Section: Preview File Name
         
         row = XLFormRowDescriptor(tag: "previewFileName", rowType: XLFormRowDescriptorTypeTextView, title: "")
-        row.cellConfig.setObject(UIFont.systemFont(ofSize: 15.0), forKey: "textLabel.font" as NSCopying)
         row.height = 180
-        row.cellConfig.setObject(NCBrandColor.sharedInstance.backgroundView, forKey: "backgroundColor" as NSCopying)
-        row.cellConfig.setObject(NCBrandColor.sharedInstance.backgroundView, forKey: "textView.backgroundColor" as NSCopying)
-        
         row.disabled = true
+        
+        row.cellConfig["textView.backgroundColor"] = NCBrandColor.sharedInstance.backgroundView
+        row.cellConfig["textView.font"] = UIFont.systemFont(ofSize: 14.0)
+        
         section.addFormRow(row)
         
         self.form = form
@@ -146,9 +157,7 @@ class NCManageAutoUploadFileName: XLFormViewController {
         self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: NCBrandColor.sharedInstance.brandText]
         
         self.tableView.separatorStyle = UITableViewCellSeparatorStyle.none
-        
-        self.tableView.backgroundColor = NCBrandColor.sharedInstance.backgroundView
-        
+                
         self.reloadForm()
     }
     

BIN
iOSClient/Supporting Files/ast.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/ca.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/cs-CZ.lproj/BKPasscodeView.strings


BIN
iOSClient/Supporting Files/cs-CZ.lproj/InfoPlist.strings


BIN
iOSClient/Supporting Files/cs-CZ.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/da.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/de.lproj/Intro.strings


BIN
iOSClient/Supporting Files/de.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/el.lproj/Intro.strings


BIN
iOSClient/Supporting Files/el.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/en-GB.lproj/Localizable.strings


+ 19 - 2
iOSClient/Supporting Files/en.lproj/Localizable.strings

@@ -62,6 +62,7 @@
 "_scan_fingerprint_"        = "Scan fingerprint to authenticate";
 "_no_active_account_"       = "No account found";
 "_info_"                    = "Info";
+"_warning_"                 = "Warning";
 "_email_"                   = "Email";
 "_save_exit_"               = "Do you want to exit without saving?";
 "_video_"                   = "Video";
@@ -86,6 +87,11 @@
 "_experimental_"            = "Experimental";
 "_select_dir_media_tab_"    = "Select as folder \"Media\"";
 "_error_creation_file_"     = "Ops! Could not create the file";
+"_save_path_"               = "Save path";
+"_save_settings_"           = "Save settings";
+"_mode_filename_"           = "Filename mode";
+"_warning_owncloud_"        = "You are connected to an ownCloud server. This is untested and unsupported, use at your own risk. To upgrade to Nextcloud, see https://nextcloud.com/migration";
+"_warning_unsupported_"     = "You are using an unsupported version of Nextcloud. For the safety of your data we strongly recommend updating to the latest stable Nextcloud";
 
 // App
 
@@ -218,7 +224,7 @@
 
 "_optimized_photos_"            = "Optimized photo resolution";
 "_upload_del_photos_"           = "Remove files after upload";
-"_optimized_photos_how_"        = "View, if possible, only a low-resolution photos.";
+"_optimized_photos_how_"        = "View, if possible, only low-resolution photos.";
 "_upload_del_photos_how_"       = "Files will be removed from device memory after they’ve been uploaded to your cloud. They will remain in the camera roll. Just download the files to see them.";
 "_show_hidden_files_"           = "Show hidden files";
 "_format_compatibility_"        = "Most Compatible";
@@ -564,7 +570,18 @@
 "_scans_document_"                  = "Scans document";
 "_scanned_images_"                  = "Scanned images";
 "_scan_document_pdf_page_"          = "Page";
-"_scan_label_PDF_zone_"             = "Drag below the images for make your PDF document";
+"_scan_label_document_zone_"        = "Drag images down for document creation";
+"_filter_original_"                 = "Original";
+"_filter_bn_"                       = "Black & White";
+"_filter_grayscale_"                = "Grayscale";
+"_quality_image_title_"             = "Image quality";
+"_quality_high_"                    = "Large file size of high quality";
+"_quality_medium_"                  = "Average file size of medium quality";
+"_quality_low_"                     = "Small file size of low quality";
+"_file_type_"                       = "File type";
+"_pdf_password_"                    = "PDF Password";
+"_file_creation_"                   = "File creation";
+
 
 /* The title on the navigation bar of the Scanning screen. */
 "wescan.scanning.title"             = "Scanning";

BIN
iOSClient/Supporting Files/es-419.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-AR.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-CL.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-CO.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-CR.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-DO.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-EC.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-GT.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-HN.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-MX.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-NI.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-PA.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-PE.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-PR.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-PY.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-SV.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-UY.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/fa.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/fi-FI.lproj/Error.strings


BIN
iOSClient/Supporting Files/fi-FI.lproj/Intro.strings


BIN
iOSClient/Supporting Files/fi-FI.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/fr.lproj/BKPasscodeView.strings


BIN
iOSClient/Supporting Files/fr.lproj/CTAssetsPicker.strings


BIN
iOSClient/Supporting Files/fr.lproj/Error.strings


BIN
iOSClient/Supporting Files/fr.lproj/Intro.strings


BIN
iOSClient/Supporting Files/fr.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/hu.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/is.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/it.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/ja_JP.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/ka-GE.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/ko.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/nb-NO.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/nl.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/pl.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/pt-BR.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/pt-PT.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/ru.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/sk-SK.lproj/Intro.strings


BIN
iOSClient/Supporting Files/sk-SK.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/sq.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/sr.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/sv.lproj/Intro.strings


BIN
iOSClient/Supporting Files/sv.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/tr.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/zh-Hans.lproj/Error.strings


Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно