Skip to content

Commit

Permalink
feat(iOS): Store all known UTIs to clipboard
Browse files Browse the repository at this point in the history
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 <skyler.grey@collabora.com>
Change-Id: Ifb13fd910d63a985ad015335658815af3bd69f6b
  • Loading branch information
Minion3665 committed Dec 18, 2024
1 parent 81d5137 commit 31c7c6c
Showing 1 changed file with 27 additions and 21 deletions.
48 changes: 27 additions & 21 deletions ios/Mobile/DocumentViewController.mm
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -370,21 +382,15 @@ - (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...");
return;
}

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]];

Expand Down

0 comments on commit 31c7c6c

Please sign in to comment.