From 31c7c6c0e3b13d358f2867fe67702230f9d0fae9 Mon Sep 17 00:00:00 2001 From: Skyler Grey Date: Fri, 6 Dec 2024 16:43:12 +0000 Subject: [PATCH] feat(iOS): Store all known UTIs to clipboard Previously we only stored a couple of mime-types to the clipboard, but this misses out copying images/etc. to the clipboard in a format understandable to other applications. To improve this, we can copy every UTI we know about to the clipboard. We'll always know about HTML and Text since as these are defined by Apple, so this will work fine with our previous code. Signed-off-by: Skyler Grey Change-Id: Ifb13fd910d63a985ad015335658815af3bd69f6b --- ios/Mobile/DocumentViewController.mm | 48 ++++++++++++++++------------ 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/ios/Mobile/DocumentViewController.mm b/ios/Mobile/DocumentViewController.mm index 8ffcc9753972..5fef554bec71 100644 --- a/ios/Mobile/DocumentViewController.mm +++ b/ios/Mobile/DocumentViewController.mm @@ -295,7 +295,7 @@ - (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView { } // This is the same method as Java_org_libreoffice_androidlib_LOActivity_getClipboardContent, with minimal editing to work with objective C -- (bool)getClipboardWithTypesPlain:(out NSString ** _Nullable)plain HTML:(out NSString ** _Nullable)html { +- (bool)getClipboardContent:(out NSMutableDictionary *)content { const char** mimeTypes = nullptr; size_t outCount = 0; char **outMimeTypes = nullptr; @@ -313,12 +313,18 @@ - (bool)getClipboardWithTypesPlain:(out NSString ** _Nullable)plain HTML:(out NS for (size_t i = 0; i < outCount; ++i) { - // Create new LokClipboardEntry instance - - if (strcmp(outMimeTypes[i], "text/html") == 0) { - *html = outStreams[i] == NULL ? @"" : [NSString stringWithUTF8String:outStreams[i]]; - } else { - *plain = outStreams[i] == NULL ? @"" : [NSString stringWithUTF8String:outStreams[i]]; + NSString * identifier = [NSString stringWithUTF8String:outMimeTypes[i]]; + + // For interop with other apps, if this mime-type is known we can export it + UTType * uti = [UTType typeWithMIMEType:identifier]; + if (uti != nil && !uti.dynamic) { + if ([uti conformsToType:UTTypePlainText]) { + [content setValue:outStreams[i] == NULL ? @"" : [NSString stringWithUTF8String:outStreams[i]] forKey:uti.identifier]; + } else if (uti != nil && [uti conformsToType:UTTypeImage]) { + [content setValue:[UIImage imageWithData:[NSData dataWithBytes:outStreams[i] length:outSizes[i]]] forKey:uti.identifier]; + } else { + [content setValue:[NSData dataWithBytes:outStreams[i] length:outSizes[i]] forKey:uti.identifier]; + } } } bResult = true; @@ -338,12 +344,18 @@ - (bool)getClipboardWithTypesPlain:(out NSString ** _Nullable)plain HTML:(out NS for (size_t i = 0; i < outCount; ++i) { - // Create new LokClipboardEntry instance - - if (strcmp(outMimeTypes[i], "text/html") == 0) { - *html = outStreams[i] == NULL ? @"" : [NSString stringWithUTF8String:outStreams[i]]; - } else { - *plain = outStreams[i] == NULL ? @"" : [NSString stringWithUTF8String:outStreams[i]]; + NSString * identifier = [NSString stringWithUTF8String:outMimeTypes[i]]; + + // For interop with other apps, if this mime-type is known we can export it + UTType * uti = [UTType typeWithMIMEType:identifier]; + if (uti != nil && !uti.dynamic) { + if ([uti conformsToType:UTTypePlainText]) { + [content setValue:outStreams[i] == NULL ? @"" : [NSString stringWithUTF8String:outStreams[i]] forKey:uti.identifier]; + } else if (uti != nil && [uti conformsToType:UTTypeImage]) { + [content setValue:[UIImage imageWithData:[NSData dataWithBytes:outStreams[i] length:outSizes[i]]] forKey:uti.identifier]; + } else { + [content setValue:[NSData dataWithBytes:outStreams[i] length:outSizes[i]] forKey:uti.identifier]; + } } } bResult = true; @@ -370,10 +382,8 @@ - (void)userContentController:(WKUserContentController *)userContentController d replyHandler([NSString stringWithFormat:@"%@ %@", encodedPlainPayload, encodedHtmlPayload], nil); } else if ([message.body isEqualToString:@"write"]) { - NSString * _Nullable plain; - NSString * _Nullable html; - - bool success = [self getClipboardWithTypesPlain:&plain HTML:&html]; + NSMutableDictionary * pasteboardItem = [NSMutableDictionary dictionaryWithCapacity:2]; + bool success = [self getClipboardContent:pasteboardItem]; if (!success) { replyHandler(nil, @"Failed to get clipboard contents..."); @@ -381,10 +391,6 @@ - (void)userContentController:(WKUserContentController *)userContentController d } UIPasteboard * pasteboard = [UIPasteboard generalPasteboard]; - - NSMutableDictionary * pasteboardItem = [NSMutableDictionary dictionaryWithCapacity:2]; - [pasteboardItem setValue:plain forKey:UTTypeUTF8PlainText.identifier]; - [pasteboardItem setValue:html forKey:UTTypeHTML.identifier]; [pasteboard setItems:[NSArray arrayWithObject:pasteboardItem]];