diff --git a/CHANGES.rst b/CHANGES.rst index 5b3d60031..f349825e1 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,7 @@ Changes to be released in next version * 🙌 Improvements - * + * MXKPasteboardManager: Introduce dedicated pasteboard manager to change the pasteboard used on copy operations (vector-im/element-ios/issues/3732). 🐛 Bugfix * Room: Refresh UI when the app is fully active (vector-im/element-ios/issues/3672). diff --git a/MatrixKit.xcodeproj/project.pbxproj b/MatrixKit.xcodeproj/project.pbxproj index 38a9c01b2..2a111f3c0 100644 --- a/MatrixKit.xcodeproj/project.pbxproj +++ b/MatrixKit.xcodeproj/project.pbxproj @@ -76,6 +76,7 @@ CE14CA661E80122600E329A3 /* MXKAttachmentAnimator.m in Sources */ = {isa = PBXBuildFile; fileRef = CE14CA631E80122600E329A3 /* MXKAttachmentAnimator.m */; }; CE14CA671E80122600E329A3 /* MXKAttachmentInteractionController.m in Sources */ = {isa = PBXBuildFile; fileRef = CE14CA651E80122600E329A3 /* MXKAttachmentInteractionController.m */; }; EC6DC7BB24F9562600B6C40F /* MarkdownToHTMLRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC6DC7BA24F9562600B6C40F /* MarkdownToHTMLRenderer.swift */; }; + EC9010C825308312004DC138 /* MXKPasteboardManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC9010C725308312004DC138 /* MXKPasteboardManager.swift */; }; F0026B661C91EED1001D2C04 /* MXKWebViewViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F0026B651C91EED1001D2C04 /* MXKWebViewViewController.m */; }; F0036EEF1AB98DC40008E432 /* MXKRoomInputToolbarView.m in Sources */ = {isa = PBXBuildFile; fileRef = F0036EED1AB98DC40008E432 /* MXKRoomInputToolbarView.m */; }; F0036EF01AB98DC40008E432 /* MXKRoomInputToolbarView.xib in Resources */ = {isa = PBXBuildFile; fileRef = F0036EEE1AB98DC40008E432 /* MXKRoomInputToolbarView.xib */; }; @@ -399,6 +400,8 @@ CE14CA651E80122600E329A3 /* MXKAttachmentInteractionController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXKAttachmentInteractionController.m; sourceTree = ""; }; E5AB7F3690B214D676BB9B72 /* Pods-MatrixKitSamplePods-MatrixKitSample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MatrixKitSamplePods-MatrixKitSample.debug.xcconfig"; path = "Pods/Target Support Files/Pods-MatrixKitSamplePods-MatrixKitSample/Pods-MatrixKitSamplePods-MatrixKitSample.debug.xcconfig"; sourceTree = ""; }; EC6DC7BA24F9562600B6C40F /* MarkdownToHTMLRenderer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarkdownToHTMLRenderer.swift; sourceTree = ""; }; + EC9010C725308312004DC138 /* MXKPasteboardManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MXKPasteboardManager.swift; sourceTree = ""; }; + EC9010C92530875E004DC138 /* MXKSwiftHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MXKSwiftHeader.h; sourceTree = ""; }; F0026B641C91EED1001D2C04 /* MXKWebViewViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MXKWebViewViewController.h; sourceTree = ""; }; F0026B651C91EED1001D2C04 /* MXKWebViewViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXKWebViewViewController.m; sourceTree = ""; }; F0036EEC1AB98DC40008E432 /* MXKRoomInputToolbarView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MXKRoomInputToolbarView.h; sourceTree = ""; }; @@ -865,6 +868,7 @@ 328AC48E1AA86E110044A6FB /* MXKDataSource.m */, 328AC4911AA8B05C0044A6FB /* MXKCellData.h */, 328AC4921AA8B05C0044A6FB /* MXKCellData.m */, + EC9010C725308312004DC138 /* MXKPasteboardManager.swift */, ); path = Models; sourceTree = ""; @@ -1030,6 +1034,7 @@ B125D0FC22D5D2C200570CA4 /* MXKUTI.swift */, B125D10822D6396700570CA4 /* MXKDocumentPickerPresenter.swift */, B125D10B22D7414400570CA4 /* MXKVideoThumbnailGenerator.swift */, + EC9010C92530875E004DC138 /* MXKSwiftHeader.h */, ); path = Utils; sourceTree = ""; @@ -1919,6 +1924,7 @@ F06CDD5F1EF017CB00870B75 /* MXKRoomEmptyBubbleTableViewCell.m in Sources */, 32D9F4E221D54A08008007F2 /* UIViewController+MatrixKit.m in Sources */, F01449AD1B53FA7600EA7D73 /* MXKPushRuleCreationTableViewCell.m in Sources */, + EC9010C825308312004DC138 /* MXKPasteboardManager.swift in Sources */, 3235CD771C32DC8A0084EA40 /* MXKSearchDataSource.m in Sources */, F0CF98DD1B0B7FDC00EAE373 /* MXKTableViewCellWithLabelAndSubLabel.m in Sources */, 92663A6C1EF6E5B3005FB712 /* MXKSoundPlayer.m in Sources */, diff --git a/MatrixKit/Controllers/MXKRoomViewController.m b/MatrixKit/Controllers/MXKRoomViewController.m index bfcbb76df..153381f7f 100644 --- a/MatrixKit/Controllers/MXKRoomViewController.m +++ b/MatrixKit/Controllers/MXKRoomViewController.m @@ -51,6 +51,7 @@ #import "NSBundle+MatrixKit.h" #import "UIScrollView+MatrixKit.h" #import "MXKSlashCommands.h" +#import "MXKSwiftHeader.h" @interface MXKRoomViewController () { @@ -2858,7 +2859,7 @@ - (void)dataSource:(MXKDataSource *)dataSource didRecognizeAction:(NSString *)ac if (textMessage) { - [[UIPasteboard generalPasteboard] setString:textMessage]; + MXKPasteboardManager.shared.pasteboard.string = textMessage; } else { @@ -3181,7 +3182,7 @@ - (void)copy:(id)sender { if (selectedText) { - [[UIPasteboard generalPasteboard] setString:selectedText]; + MXKPasteboardManager.shared.pasteboard.string = selectedText; } else { diff --git a/MatrixKit/MatrixKit.h b/MatrixKit/MatrixKit.h index 2f11efa29..be9cb0442 100644 --- a/MatrixKit/MatrixKit.h +++ b/MatrixKit/MatrixKit.h @@ -154,3 +154,4 @@ #import "MXKSessionGroupsDataSource.h" #import "MXKGroupListViewController.h" #import "MXKGroupTableViewCell.h" +#import "MXKSwiftHeader.h" diff --git a/MatrixKit/Models/MXKPasteboardManager.swift b/MatrixKit/Models/MXKPasteboardManager.swift new file mode 100644 index 000000000..814ae10b4 --- /dev/null +++ b/MatrixKit/Models/MXKPasteboardManager.swift @@ -0,0 +1,33 @@ +/* + Copyright 2020 The Matrix.org Foundation C.I.C + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +import Foundation +import UIKit + +@objcMembers +public class MXKPasteboardManager: NSObject { + + public static let shared = MXKPasteboardManager(withPasteboard: .general) + + private init(withPasteboard pasteboard: UIPasteboard) { + self.pasteboard = pasteboard + super.init() + } + + /// Pasteboard to use on copy operations. Defaults to `UIPasteboard.generalPasteboard`. + public var pasteboard: UIPasteboard + +} diff --git a/MatrixKit/Models/Room/MXKAttachment.m b/MatrixKit/Models/Room/MXKAttachment.m index f6946dd70..2f8276d5d 100644 --- a/MatrixKit/Models/Room/MXKAttachment.m +++ b/MatrixKit/Models/Room/MXKAttachment.m @@ -16,6 +16,7 @@ */ #import "MXKAttachment.h" +#import "MXKSwiftHeader.h" @import MatrixSDK; @import MobileCoreServices; @@ -587,7 +588,7 @@ - (void)copy:(void (^)(void))onSuccess failure:(void (^)(NSError *error))onFailu if (self.type == MXKAttachmentTypeImage) { [self getImage:^(MXKAttachment *attachment, UIImage *img) { - [[UIPasteboard generalPasteboard] setImage:img]; + MXKPasteboardManager.shared.pasteboard.image = img; if (onSuccess) { onSuccess(); @@ -607,7 +608,7 @@ - (void)copy:(void (^)(void))onSuccess failure:(void (^)(NSError *error))onFailu if (UTI) { - [[UIPasteboard generalPasteboard] setData:data forPasteboardType:UTI]; + [MXKPasteboardManager.shared.pasteboard setData:data forPasteboardType:UTI]; if (onSuccess) { onSuccess(); diff --git a/MatrixKit/Utils/EventFormatter/MXKEventFormatter.m b/MatrixKit/Utils/EventFormatter/MXKEventFormatter.m index afc739f36..b4c382e54 100644 --- a/MatrixKit/Utils/EventFormatter/MXKEventFormatter.m +++ b/MatrixKit/Utils/EventFormatter/MXKEventFormatter.m @@ -23,13 +23,7 @@ #import "MXEvent+MatrixKit.h" #import "NSBundle+MatrixKit.h" - -#if __has_include() - #import -#elif __has_include("MatrixKit-Swift.h") - #import "MatrixKit-Swift.h" -#endif - +#import "MXKSwiftHeader.h" #import "MXKTools.h" #import "MXRoom+Sync.h" diff --git a/MatrixKit/Utils/MXKSwiftHeader.h b/MatrixKit/Utils/MXKSwiftHeader.h new file mode 100644 index 000000000..b600c3e4a --- /dev/null +++ b/MatrixKit/Utils/MXKSwiftHeader.h @@ -0,0 +1,29 @@ +/* + Copyright 2020 The Matrix.org Foundation C.I.C + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ +/* + Never import this file in header files (.h) only in implementation files (.m). + If you want to reference a Swift class from the project please use forward declaration in the header file and then import this header in your implementation file. +*/ +#ifndef MXKSwiftHeader_h +#define MXKSwiftHeader_h + +#if __has_include() + #import +#elif __has_include("MatrixKit-Swift.h") + #import "MatrixKit-Swift.h" +#endif + +#endif /* MXKSwiftHeader_h */ diff --git a/MatrixKit/Views/RoomInputToolbar/MXKRoomInputToolbarView.m b/MatrixKit/Views/RoomInputToolbar/MXKRoomInputToolbarView.m index 42fbaddce..4df23ee22 100644 --- a/MatrixKit/Views/RoomInputToolbar/MXKRoomInputToolbarView.m +++ b/MatrixKit/Views/RoomInputToolbar/MXKRoomInputToolbarView.m @@ -17,6 +17,7 @@ */ #import "MXKRoomInputToolbarView.h" +#import "MXKSwiftHeader.h" @import MatrixSDK.MXMediaManager; @import MediaPlayer; @@ -1146,15 +1147,15 @@ - (void)dismissMediaPicker - (void)paste:(id)sender { - UIPasteboard *generalPasteboard = [UIPasteboard generalPasteboard]; - if (generalPasteboard.numberOfItems) + UIPasteboard *pasteboard = MXKPasteboardManager.shared.pasteboard; + if (pasteboard.numberOfItems) { [self dismissValidationViews]; [self dismissKeyboard]; __weak typeof(self) weakSelf = self; - for (NSDictionary* dict in generalPasteboard.items) + for (NSDictionary* dict in pasteboard.items) { NSArray* allKeys = dict.allKeys; for (NSString* key in allKeys) @@ -1333,10 +1334,10 @@ - (BOOL)canPerformAction:(SEL)action withSender:(id)sender if (action == @selector(paste:)) { // Check whether some data listed in general pasteboard can be paste - UIPasteboard *generalPasteboard = [UIPasteboard generalPasteboard]; - if (generalPasteboard.numberOfItems) + UIPasteboard *pasteboard = MXKPasteboardManager.shared.pasteboard; + if (pasteboard.numberOfItems) { - for (NSDictionary* dict in generalPasteboard.items) + for (NSDictionary* dict in pasteboard.items) { NSArray* allKeys = dict.allKeys; for (NSString* key in allKeys)