mirror of
https://github.com/MacPass/MacPass.git
synced 2025-12-13 19:22:25 +00:00
More progress on import plugin support
This commit is contained in:
@@ -162,6 +162,9 @@
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="494" id="gzA-SE-HKO"/>
|
||||
</connections>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Export" id="tz9-yK-pOf">
|
||||
@@ -350,6 +353,7 @@ CA
|
||||
<connections>
|
||||
<outlet property="fileNewMenuItem" destination="82" id="BUX-dy-HS2"/>
|
||||
<outlet property="fixAutotypeMenuItem" destination="nx7-Vf-LiD" id="5n1-bG-JxJ"/>
|
||||
<outlet property="importMenu" destination="4q9-u1-pcm" id="0XM-fS-Vyy"/>
|
||||
<outlet property="itemMenu" destination="Ttt-tR-emo" id="cdF-dt-2h9"/>
|
||||
<outlet property="saveMenuItem" destination="75" id="dsN-Im-4eZ"/>
|
||||
</connections>
|
||||
|
||||
@@ -26,10 +26,11 @@ APPKIT_EXTERN NSString *const MPDidChangeStoredKeyFilesSettings;
|
||||
|
||||
@interface MPAppDelegate : NSObject <NSApplicationDelegate, NSMenuDelegate>
|
||||
|
||||
@property (weak) IBOutlet NSMenuItem *saveMenuItem;
|
||||
@property (weak) IBOutlet NSMenuItem *fixAutotypeMenuItem;
|
||||
@property (weak) IBOutlet NSMenuItem *fileNewMenuItem;
|
||||
@property (weak) IBOutlet NSMenu *itemMenu;
|
||||
@property (strong) IBOutlet NSMenuItem *saveMenuItem;
|
||||
@property (strong) IBOutlet NSMenuItem *fixAutotypeMenuItem;
|
||||
@property (strong) IBOutlet NSMenuItem *fileNewMenuItem;
|
||||
@property (strong) IBOutlet NSMenu *itemMenu;
|
||||
@property (strong) IBOutlet NSMenu *importMenu;
|
||||
|
||||
@property (nonatomic, assign) BOOL isAllowedToStoreKeyFile;
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#import "MPValueTransformerHelper.h"
|
||||
#import "MPUserNotificationCenterDelegate.h"
|
||||
#import "MPWelcomeViewController.h"
|
||||
#import "MPPlugin.h"
|
||||
|
||||
#import "NSApplication+MPAdditions.h"
|
||||
|
||||
@@ -208,6 +209,17 @@ NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDi
|
||||
[menu addItem:item];
|
||||
}
|
||||
}
|
||||
if(menu == self.importMenu) {
|
||||
NSMenuItem *exportXML = menu.itemArray.firstObject;
|
||||
[menu removeAllItems];
|
||||
for(MPPlugin<MPImportPlugin> * plugin in MPPluginHost.sharedHost.importPlugins) {
|
||||
NSMenuItem *importItem = [[NSMenuItem alloc] init];
|
||||
[plugin prepareImportMenuItem:importItem];
|
||||
importItem.target = nil;
|
||||
importItem.action = @selector(importFromPlugin:);
|
||||
}
|
||||
[menu insertItem:exportXML atIndex:0];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@@ -149,6 +149,7 @@ FOUNDATION_EXPORT NSString *const MPDocumentGroupKey;
|
||||
- (BOOL)shouldEnforcePasswordChange;
|
||||
- (BOOL)shouldRecommendPasswordChange;
|
||||
|
||||
- (void)importTree:(KPKTree *)tree;
|
||||
- (void)writeXMLToURL:(NSURL *)url;
|
||||
- (void)readXMLfromURL:(NSURL *)url;
|
||||
- (void)mergeWithContentsFromURL:(NSURL *)url key:(KPKCompositeKey *)key;
|
||||
|
||||
@@ -329,6 +329,12 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou
|
||||
// else do nothing!
|
||||
}
|
||||
|
||||
- (void)importTree:(KPKTree *)tree {
|
||||
self.tree = tree;
|
||||
self.compositeKey = nil;
|
||||
self.encryptedData = nil;
|
||||
}
|
||||
|
||||
- (void)writeXMLToURL:(NSURL *)url {
|
||||
NSData *xmlData = [self.tree xmlData];
|
||||
NSError *error;
|
||||
@@ -339,9 +345,8 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou
|
||||
|
||||
- (void)readXMLfromURL:(NSURL *)url {
|
||||
NSError *error;
|
||||
self.tree = [[KPKTree alloc] initWithXmlContentsOfURL:url error:&error];
|
||||
self.compositeKey = nil;
|
||||
self.encryptedData = nil;
|
||||
KPKTree *tree = [[KPKTree alloc] initWithXmlContentsOfURL:url error:&error];
|
||||
[self importTree:tree];
|
||||
}
|
||||
|
||||
- (void)mergeWithContentsFromURL:(NSURL *)url key:(KPKCompositeKey *)key {
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
- (IBAction)exportAsXML:(id)sender;
|
||||
- (IBAction)mergeWithOther:(id)sender;
|
||||
- (IBAction)importFromXML:(id)sender;
|
||||
- (IBAction)importFromPlugin:(id)sender;
|
||||
|
||||
- (IBAction)lock:(id)sender;
|
||||
- (IBAction)createGroup:(id)sender;
|
||||
|
||||
@@ -40,6 +40,9 @@
|
||||
#import "MPToolbarDelegate.h"
|
||||
#import "MPTitlebarColorAccessoryViewController.h"
|
||||
|
||||
#import "MPPluginHost.h"
|
||||
#import "MPPlugin.h"
|
||||
|
||||
#import "KeePassKit/KeePassKit.h"
|
||||
|
||||
typedef NS_ENUM(NSUInteger, MPAlertContext) {
|
||||
@@ -274,6 +277,28 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword);
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)importFromPlugin:(id)sender {
|
||||
if(![sender isKindOfClass:NSMenuItem.class]) {
|
||||
return;
|
||||
}
|
||||
NSMenuItem *menuItem = sender;
|
||||
if(![menuItem.representedObject isKindOfClass:NSDictionary.class]) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSWindow *sheetWindow = ((MPDocument *)self.document).windowForSheet;
|
||||
if(!sheetWindow) {
|
||||
return;
|
||||
}
|
||||
MPPlugin<MPImportPlugin> *importPlugin;
|
||||
NSOpenPanel *openPanel = NSOpenPanel.openPanel;
|
||||
[importPlugin prepareOpenPanel:openPanel];
|
||||
[openPanel beginSheetModalForWindow:sheetWindow completionHandler:^(NSModalResponse result) {
|
||||
KPKTree *importedTree = [importPlugin treeForRunningOpenPanel:openPanel withResponse:result];
|
||||
[self.document importTree:importedTree];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)mergeWithOther:(id)sender {
|
||||
NSOpenPanel *openPanel = [NSOpenPanel openPanel];
|
||||
MPDocument *document = self.document;
|
||||
|
||||
@@ -89,8 +89,33 @@ FOUNDATION_EXPORT NSString *const MPPluginUnkownVersion;
|
||||
|
||||
@protocol MPImportPlugin <NSObject>
|
||||
@required
|
||||
@property (readonly, copy) NSArray<NSString *> *supportedUTIs;
|
||||
- (KPKTree *)importTreeWithContentsOfURL:(NSURL *)url;
|
||||
/**
|
||||
Called by the Host to upate a menu item for importing.
|
||||
You are supposed to update the title to something meaningfull.
|
||||
target and action will get set by host, so do not rely on them
|
||||
|
||||
@param item MenuItem that will be used to import via the plugin
|
||||
*/
|
||||
- (void)prepareImportMenuItem:(NSMenuItem *)item;
|
||||
/**
|
||||
Called by the host when an import is about to happen.
|
||||
Update the panel to allow work for all the files and formats you can open.
|
||||
|
||||
Host will simply run the panel with - beginSheetModalForWindow:completionHandler:
|
||||
and will call treeForRunningOpenPanel:withResponse: afterwards to handle the result.
|
||||
|
||||
@param panel The open panel that will be displayed to the user for importing files
|
||||
*/
|
||||
- (void)prepareOpenPanel:(NSOpenPanel *)panel;
|
||||
/**
|
||||
This will get called when the open panel is closed by the user.
|
||||
You should retrieve any results from the panel and act accordingly.
|
||||
|
||||
@param panel The open panel used for selecting what file(s) to import
|
||||
@param response The response for of the user for running the panel
|
||||
@return The tree constructed from the selected input file(s)
|
||||
*/
|
||||
- (KPKTree *)treeForRunningOpenPanel:(NSOpenPanel *)panel withResponse:(NSModalResponse)response;
|
||||
@end
|
||||
|
||||
@interface MPPlugin (Deprecated)
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
/* Notifications for loading plugins */
|
||||
FOUNDATION_EXPORT NSString *const MPPluginHostWillLoadPlugin;
|
||||
FOUNDATION_EXPORT NSString *const MPPluginHostDidLoadPlugin;
|
||||
FOUNDATION_EXPORT NSString *const MPPluginHostWillLoadPluginNotification;
|
||||
FOUNDATION_EXPORT NSString *const MPPluginHostDidLoadPluginNotification;
|
||||
|
||||
/* Keys used in info dictionary on notifications */
|
||||
FOUNDATION_EXPORT NSString *const MPPluginHostPluginBundleIdentifiyerKey;
|
||||
@@ -37,7 +37,6 @@ FOUNDATION_EXPORT NSString *const MPPluginHostPluginBundleIdentifiyerKey;
|
||||
|
||||
/* List of all plugins known to the plugin manager. Disabled plugins are also present! */
|
||||
@property (readonly, copy) NSArray <MPPlugin __kindof*> *plugins;
|
||||
@property (readonly, copy) NSArray <MPPlugin __kindof*> *importPlugins;
|
||||
@property (nonatomic, readonly, copy) NSString *version;
|
||||
|
||||
+ (instancetype)sharedHost;
|
||||
@@ -54,3 +53,9 @@ FOUNDATION_EXPORT NSString *const MPPluginHostPluginBundleIdentifiyerKey;
|
||||
- (MPPlugin *)pluginWithBundleIdentifier:(NSString *)identifer;
|
||||
- (NSArray *)avilableMenuItemsForEntries:(NSArray <KPKEntry *>*)entries;
|
||||
@end
|
||||
|
||||
@interface MPPluginHost (MPImportPluginSupport)
|
||||
|
||||
@property (readonly, copy) NSArray <MPPlugin<MPImportPlugin> __kindof*> *importPlugins;
|
||||
|
||||
@end
|
||||
|
||||
@@ -38,8 +38,8 @@
|
||||
#import "KeePassKit/KeePassKit.h"
|
||||
|
||||
|
||||
NSString *const MPPluginHostWillLoadPlugin = @"com.hicknhack.macpass.MPPluginHostWillLoadPlugin";
|
||||
NSString *const MPPluginHostDidLoadPlugin = @"comt.hicknhack.macpass.MPPluginHostDidLoadPlugin";
|
||||
NSString *const MPPluginHostWillLoadPluginNotification = @"com.hicknhack.macpass.MPPluginHostWillLoadPlugin";
|
||||
NSString *const MPPluginHostDidLoadPluginNotification = @"comt.hicknhack.macpass.MPPluginHostDidLoadPlugin";
|
||||
|
||||
NSString *const MPPluginHostPluginBundleIdentifiyerKey = @"MPPluginHostPluginBundleIdentifiyerKey";
|
||||
|
||||
@@ -87,13 +87,6 @@ NSString *const MPPluginHostPluginBundleIdentifiyerKey = @"MPPluginHostPluginBun
|
||||
return [self.mutablePlugins copy];
|
||||
}
|
||||
|
||||
- (NSArray<MPPlugin *> *)importPlugins {
|
||||
NSPredicate *filterPredicate = [NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
|
||||
return ([evaluatedObject conformsToProtocol:@protocol(MPImportPlugin)]);
|
||||
}];
|
||||
return [self.mutablePlugins filteredArrayUsingPredicate:filterPredicate];
|
||||
}
|
||||
|
||||
- (BOOL)installPluginAtURL:(NSURL *)url error:(NSError *__autoreleasing *)error {
|
||||
if(![self _isValidPluginURL:url]) {
|
||||
if(error) {
|
||||
@@ -267,11 +260,11 @@ NSString *const MPPluginHostPluginBundleIdentifiyerKey = @"MPPluginHostPluginBun
|
||||
|
||||
if(plugin) {
|
||||
NSLog(@"Loaded plugin instance %@", pluginBundle.principalClass);
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:MPPluginHostWillLoadPlugin
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:MPPluginHostWillLoadPluginNotification
|
||||
object:self
|
||||
userInfo:@{ MPPluginHostPluginBundleIdentifiyerKey : plugin.identifier }];
|
||||
[self _addPlugin:plugin];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:MPPluginHostDidLoadPlugin
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:MPPluginHostDidLoadPluginNotification
|
||||
object:self
|
||||
userInfo:@{ MPPluginHostPluginBundleIdentifiyerKey : plugin.identifier }];
|
||||
}
|
||||
@@ -414,6 +407,18 @@ NSString *const MPPluginHostPluginBundleIdentifiyerKey = @"MPPluginHostPluginBun
|
||||
[context.plugin performActionForMenuItem:item withEntries:context.entries];
|
||||
}
|
||||
|
||||
|
||||
|
||||
@end
|
||||
|
||||
NSString *const MPPluginBundleIdentifierKey = @"MPPluginBundleIdentifierKey";
|
||||
NSString *const MPImportPluginUTIKey = @"MPImportPluginUTIKey";
|
||||
|
||||
@implementation MPPluginHost (MPImportPluginSupport)
|
||||
|
||||
- (NSArray<MPPlugin *> *)importPlugins {
|
||||
NSPredicate *filterPredicate = [NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
|
||||
return ([evaluatedObject conformsToProtocol:@protocol(MPImportPlugin)]);
|
||||
}];
|
||||
return [self.mutablePlugins filteredArrayUsingPredicate:filterPredicate];
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user