[Libreoffice-commits] online.git: Branch 'distro/collabora/co-4-2-2' - ios/Mobile kit/ChildSession.cpp
Tor Lillqvist (via logerrit)
logerrit at kemper.freedesktop.org
Mon Apr 13 15:28:24 UTC 2020
ios/Mobile/DocumentViewController.mm | 51 +++++++++++++++++++++++++++++++++-
kit/ChildSession.cpp | 52 +----------------------------------
2 files changed, 52 insertions(+), 51 deletions(-)
New commits:
commit 3c3e38b4b1f42fa2059813e2ea84d38f523c50d6
Author: Tor Lillqvist <tml at collabora.com>
AuthorDate: Mon Apr 13 15:48:51 2020 +0300
Commit: Andras Timar <andras.timar at collabora.com>
CommitDate: Mon Apr 13 17:28:06 2020 +0200
Implement the "download as" functionality properly in the iOS app
We need to catch the downloadas message already in
-[DocumentViewController
userContentController:didReceiveScriptMessage:] and use an
UIDocumentPickerViewController to let the user choose where to
download (or export) the document. The iOS-specific code in
ChildSession::downloadAs() can go away.
Change-Id: I626b9986ec6156f7e83bda02b04e65f7819f8017
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/92112
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
Reviewed-by: Tor Lillqvist <tml at collabora.com>
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/92115
Reviewed-by: Andras Timar <andras.timar at collabora.com>
diff --git a/ios/Mobile/DocumentViewController.mm b/ios/Mobile/DocumentViewController.mm
index 97ac7ab96..54932be3f 100644
--- a/ios/Mobile/DocumentViewController.mm
+++ b/ios/Mobile/DocumentViewController.mm
@@ -28,8 +28,9 @@
static DocumentViewController* theSingleton = nil;
- at interface DocumentViewController() <WKNavigationDelegate, WKUIDelegate, WKScriptMessageHandler, UIScrollViewDelegate> {
+ at interface DocumentViewController() <WKNavigationDelegate, WKUIDelegate, WKScriptMessageHandler, UIScrollViewDelegate, UIDocumentPickerDelegate> {
int closeNotificationPipeForForwardingThread[2];
+ NSURL *downloadAsTmpURL;
}
@end
@@ -449,6 +450,46 @@ static IMP standardImpOfInputAccessoryView = nil;
[application openURL:url options:@{} completionHandler:nil];
return;
}
+ } else if ([message.body hasPrefix:@"downloadas "]) {
+ NSArray<NSString*> *messageBodyItems = [message.body componentsSeparatedByString:@" "];
+ NSString *format = nil;
+ if ([messageBodyItems count] >= 2) {
+ for (int i = 1; i < [messageBodyItems count]; i++) {
+ if ([messageBodyItems[i] hasPrefix:@"format="])
+ format = [messageBodyItems[i] substringFromIndex:[@"format=" length]];
+ }
+
+ if (format == nil)
+ return; // Warn?
+
+ // First save it in the requested format to a temporary location. First remove any
+ // leftover identically named temporary file.
+
+ NSString *tmpFileName = [[[self.document->copyFileURL lastPathComponent] stringByDeletingPathExtension] stringByAppendingString:[@"." stringByAppendingString:format]];
+ downloadAsTmpURL = [[NSFileManager.defaultManager temporaryDirectory] URLByAppendingPathComponent:tmpFileName];
+
+ std::remove([[downloadAsTmpURL path] UTF8String]);
+
+ lok_document->saveAs([[downloadAsTmpURL absoluteString] UTF8String], [format UTF8String], nullptr);
+
+ // Then verify that it indeed was saved, and then use an
+ // UIDocumentPickerViewController to ask the user where to store the exported
+ // document.
+
+ struct stat statBuf;
+ if (stat([[downloadAsTmpURL path] UTF8String], &statBuf) == -1) {
+ LOG_ERR("Could apparently not save to '" << [[downloadAsTmpURL path] UTF8String] << "'");
+ } else {
+ UIDocumentPickerViewController *picker =
+ [[UIDocumentPickerViewController alloc] initWithURL:downloadAsTmpURL
+ inMode:UIDocumentPickerModeExportToService];
+ picker.delegate = self;
+ [self presentViewController:picker
+ animated:YES
+ completion:nil];
+ }
+ return;
+ }
}
const char *buf = [message.body UTF8String];
@@ -461,6 +502,14 @@ static IMP standardImpOfInputAccessoryView = nil;
}
}
+- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls {
+ std::remove([[downloadAsTmpURL path] UTF8String]);
+}
+
+- (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller {
+ std::remove([[downloadAsTmpURL path] UTF8String]);
+}
+
- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view {
scrollView.pinchGestureRecognizer.enabled = NO;
}
diff --git a/kit/ChildSession.cpp b/kit/ChildSession.cpp
index 534d6c2fb..edbe7e8c0 100644
--- a/kit/ChildSession.cpp
+++ b/kit/ChildSession.cpp
@@ -921,56 +921,8 @@ bool ChildSession::downloadAs(const char* /*buffer*/, int /*length*/, const Stri
}
#ifdef IOS
- NSURL *docURL = [NSURL URLWithString:[NSString stringWithUTF8String:getDocURL().c_str()]];
-
-#if 0
- // Experimentation
-
- // Check if we can figure out the name of the file provider service the document is on. (No, the
- // services dictionary passed to the completion handler is always empty, except for On My iPad
- // and iCloud Drive.)
- [NSFileManager.defaultManager
- getFileProviderServicesForItemAtURL:docURL
- completionHandler:^(NSDictionary<NSFileProviderServiceName,NSFileProviderService *> *services,
- NSError *error) {
- if (services == nil) {
- std::cerr << "Could not get file provider services for " << [[docURL absoluteString] UTF8String] << "\n";
- } else if ([services count] == 0) {
- std::cerr << "No file provider services returned for " << [[docURL absoluteString] UTF8String] << "\n";
- } else {
- std::cerr << "File provider services for " << [[docURL absoluteString] UTF8String] << ":\n";
- for (auto key in [services allKeys]) {
- std::cerr << " " << [(NSString*)key UTF8String] << "\n";
- }
- }
- }];
-
- // Check if we can figure out the "ubiquitous item container" name, which apparently means the file provider extension name.
- // Alas, this seems to work only for documents on iCloud Drive.
- NSError *error;
- auto resources = [docURL promisedItemResourceValuesForKeys:@[NSURLUbiquitousItemContainerDisplayNameKey] error:&error];
- if (resources == nil) {
- std::cerr << "Could not get ubiquitous container names for " << [[docURL absoluteString] UTF8String] << "\n";
- } else if ([resources count] == 0) {
- std::cerr << "No ubiquitous container names for " << [[docURL absoluteString] UTF8String] << "\n";
- } else {
- std::cerr << "Ubiquitous container names for " << [[docURL absoluteString] UTF8String] << ":\n";
- for (auto name in [resources allValues]) {
- std::cerr << " " << [(NSString*)name UTF8String] << "\n";
- }
- }
-#endif
-
- NSArray<NSString *> *pathComponents = [docURL pathComponents];
- NSString *baseName = [[pathComponents lastObject] stringByDeletingPathExtension];
- NSURL *documentDirectory = [NSFileManager.defaultManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask][0];
- NSString *dotFormat = [@"." stringByAppendingString:[NSString stringWithUTF8String:format.c_str()]];
- NSURL *exportedURL = [documentDirectory URLByAppendingPathComponent:[baseName stringByAppendingString:dotFormat]];
- LOG_TRC("Exporting as " << [[exportedURL absoluteString] UTF8String]);
-
- getLOKitDocument()->saveAs([[exportedURL absoluteString] UTF8String],
- format.empty() ? nullptr : format.c_str(),
- filterOptions.empty() ? nullptr : filterOptions.c_str());
+ NSLog(@"We should never come here, aborting");
+ std::abort();
#else
// Prevent user inputting anything funny here.
// A "name" should always be a name, not a path
More information about the Libreoffice-commits
mailing list