mirror of
https://github.com/MacPass/MacPass.git
synced 2025-12-13 21:42:32 +00:00
More progress on import plugin support
This commit is contained in:
@@ -162,6 +162,9 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
</items>
|
</items>
|
||||||
|
<connections>
|
||||||
|
<outlet property="delegate" destination="494" id="gzA-SE-HKO"/>
|
||||||
|
</connections>
|
||||||
</menu>
|
</menu>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Export" id="tz9-yK-pOf">
|
<menuItem title="Export" id="tz9-yK-pOf">
|
||||||
@@ -350,6 +353,7 @@ CA
|
|||||||
<connections>
|
<connections>
|
||||||
<outlet property="fileNewMenuItem" destination="82" id="BUX-dy-HS2"/>
|
<outlet property="fileNewMenuItem" destination="82" id="BUX-dy-HS2"/>
|
||||||
<outlet property="fixAutotypeMenuItem" destination="nx7-Vf-LiD" id="5n1-bG-JxJ"/>
|
<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="itemMenu" destination="Ttt-tR-emo" id="cdF-dt-2h9"/>
|
||||||
<outlet property="saveMenuItem" destination="75" id="dsN-Im-4eZ"/>
|
<outlet property="saveMenuItem" destination="75" id="dsN-Im-4eZ"/>
|
||||||
</connections>
|
</connections>
|
||||||
|
|||||||
@@ -26,10 +26,11 @@ APPKIT_EXTERN NSString *const MPDidChangeStoredKeyFilesSettings;
|
|||||||
|
|
||||||
@interface MPAppDelegate : NSObject <NSApplicationDelegate, NSMenuDelegate>
|
@interface MPAppDelegate : NSObject <NSApplicationDelegate, NSMenuDelegate>
|
||||||
|
|
||||||
@property (weak) IBOutlet NSMenuItem *saveMenuItem;
|
@property (strong) IBOutlet NSMenuItem *saveMenuItem;
|
||||||
@property (weak) IBOutlet NSMenuItem *fixAutotypeMenuItem;
|
@property (strong) IBOutlet NSMenuItem *fixAutotypeMenuItem;
|
||||||
@property (weak) IBOutlet NSMenuItem *fileNewMenuItem;
|
@property (strong) IBOutlet NSMenuItem *fileNewMenuItem;
|
||||||
@property (weak) IBOutlet NSMenu *itemMenu;
|
@property (strong) IBOutlet NSMenu *itemMenu;
|
||||||
|
@property (strong) IBOutlet NSMenu *importMenu;
|
||||||
|
|
||||||
@property (nonatomic, assign) BOOL isAllowedToStoreKeyFile;
|
@property (nonatomic, assign) BOOL isAllowedToStoreKeyFile;
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
#import "MPValueTransformerHelper.h"
|
#import "MPValueTransformerHelper.h"
|
||||||
#import "MPUserNotificationCenterDelegate.h"
|
#import "MPUserNotificationCenterDelegate.h"
|
||||||
#import "MPWelcomeViewController.h"
|
#import "MPWelcomeViewController.h"
|
||||||
|
#import "MPPlugin.h"
|
||||||
|
|
||||||
#import "NSApplication+MPAdditions.h"
|
#import "NSApplication+MPAdditions.h"
|
||||||
|
|
||||||
@@ -208,6 +209,17 @@ NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDi
|
|||||||
[menu addItem:item];
|
[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 -
|
#pragma mark -
|
||||||
|
|||||||
@@ -149,6 +149,7 @@ FOUNDATION_EXPORT NSString *const MPDocumentGroupKey;
|
|||||||
- (BOOL)shouldEnforcePasswordChange;
|
- (BOOL)shouldEnforcePasswordChange;
|
||||||
- (BOOL)shouldRecommendPasswordChange;
|
- (BOOL)shouldRecommendPasswordChange;
|
||||||
|
|
||||||
|
- (void)importTree:(KPKTree *)tree;
|
||||||
- (void)writeXMLToURL:(NSURL *)url;
|
- (void)writeXMLToURL:(NSURL *)url;
|
||||||
- (void)readXMLfromURL:(NSURL *)url;
|
- (void)readXMLfromURL:(NSURL *)url;
|
||||||
- (void)mergeWithContentsFromURL:(NSURL *)url key:(KPKCompositeKey *)key;
|
- (void)mergeWithContentsFromURL:(NSURL *)url key:(KPKCompositeKey *)key;
|
||||||
|
|||||||
@@ -329,6 +329,12 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou
|
|||||||
// else do nothing!
|
// else do nothing!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)importTree:(KPKTree *)tree {
|
||||||
|
self.tree = tree;
|
||||||
|
self.compositeKey = nil;
|
||||||
|
self.encryptedData = nil;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)writeXMLToURL:(NSURL *)url {
|
- (void)writeXMLToURL:(NSURL *)url {
|
||||||
NSData *xmlData = [self.tree xmlData];
|
NSData *xmlData = [self.tree xmlData];
|
||||||
NSError *error;
|
NSError *error;
|
||||||
@@ -339,9 +345,8 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou
|
|||||||
|
|
||||||
- (void)readXMLfromURL:(NSURL *)url {
|
- (void)readXMLfromURL:(NSURL *)url {
|
||||||
NSError *error;
|
NSError *error;
|
||||||
self.tree = [[KPKTree alloc] initWithXmlContentsOfURL:url error:&error];
|
KPKTree *tree = [[KPKTree alloc] initWithXmlContentsOfURL:url error:&error];
|
||||||
self.compositeKey = nil;
|
[self importTree:tree];
|
||||||
self.encryptedData = nil;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)mergeWithContentsFromURL:(NSURL *)url key:(KPKCompositeKey *)key {
|
- (void)mergeWithContentsFromURL:(NSURL *)url key:(KPKCompositeKey *)key {
|
||||||
|
|||||||
@@ -58,6 +58,7 @@
|
|||||||
- (IBAction)exportAsXML:(id)sender;
|
- (IBAction)exportAsXML:(id)sender;
|
||||||
- (IBAction)mergeWithOther:(id)sender;
|
- (IBAction)mergeWithOther:(id)sender;
|
||||||
- (IBAction)importFromXML:(id)sender;
|
- (IBAction)importFromXML:(id)sender;
|
||||||
|
- (IBAction)importFromPlugin:(id)sender;
|
||||||
|
|
||||||
- (IBAction)lock:(id)sender;
|
- (IBAction)lock:(id)sender;
|
||||||
- (IBAction)createGroup:(id)sender;
|
- (IBAction)createGroup:(id)sender;
|
||||||
|
|||||||
@@ -40,6 +40,9 @@
|
|||||||
#import "MPToolbarDelegate.h"
|
#import "MPToolbarDelegate.h"
|
||||||
#import "MPTitlebarColorAccessoryViewController.h"
|
#import "MPTitlebarColorAccessoryViewController.h"
|
||||||
|
|
||||||
|
#import "MPPluginHost.h"
|
||||||
|
#import "MPPlugin.h"
|
||||||
|
|
||||||
#import "KeePassKit/KeePassKit.h"
|
#import "KeePassKit/KeePassKit.h"
|
||||||
|
|
||||||
typedef NS_ENUM(NSUInteger, MPAlertContext) {
|
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 {
|
- (void)mergeWithOther:(id)sender {
|
||||||
NSOpenPanel *openPanel = [NSOpenPanel openPanel];
|
NSOpenPanel *openPanel = [NSOpenPanel openPanel];
|
||||||
MPDocument *document = self.document;
|
MPDocument *document = self.document;
|
||||||
|
|||||||
@@ -89,8 +89,33 @@ FOUNDATION_EXPORT NSString *const MPPluginUnkownVersion;
|
|||||||
|
|
||||||
@protocol MPImportPlugin <NSObject>
|
@protocol MPImportPlugin <NSObject>
|
||||||
@required
|
@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
|
@end
|
||||||
|
|
||||||
@interface MPPlugin (Deprecated)
|
@interface MPPlugin (Deprecated)
|
||||||
|
|||||||
@@ -23,8 +23,8 @@
|
|||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
/* Notifications for loading plugins */
|
/* Notifications for loading plugins */
|
||||||
FOUNDATION_EXPORT NSString *const MPPluginHostWillLoadPlugin;
|
FOUNDATION_EXPORT NSString *const MPPluginHostWillLoadPluginNotification;
|
||||||
FOUNDATION_EXPORT NSString *const MPPluginHostDidLoadPlugin;
|
FOUNDATION_EXPORT NSString *const MPPluginHostDidLoadPluginNotification;
|
||||||
|
|
||||||
/* Keys used in info dictionary on notifications */
|
/* Keys used in info dictionary on notifications */
|
||||||
FOUNDATION_EXPORT NSString *const MPPluginHostPluginBundleIdentifiyerKey;
|
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! */
|
/* 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*> *plugins;
|
||||||
@property (readonly, copy) NSArray <MPPlugin __kindof*> *importPlugins;
|
|
||||||
@property (nonatomic, readonly, copy) NSString *version;
|
@property (nonatomic, readonly, copy) NSString *version;
|
||||||
|
|
||||||
+ (instancetype)sharedHost;
|
+ (instancetype)sharedHost;
|
||||||
@@ -54,3 +53,9 @@ FOUNDATION_EXPORT NSString *const MPPluginHostPluginBundleIdentifiyerKey;
|
|||||||
- (MPPlugin *)pluginWithBundleIdentifier:(NSString *)identifer;
|
- (MPPlugin *)pluginWithBundleIdentifier:(NSString *)identifer;
|
||||||
- (NSArray *)avilableMenuItemsForEntries:(NSArray <KPKEntry *>*)entries;
|
- (NSArray *)avilableMenuItemsForEntries:(NSArray <KPKEntry *>*)entries;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@interface MPPluginHost (MPImportPluginSupport)
|
||||||
|
|
||||||
|
@property (readonly, copy) NSArray <MPPlugin<MPImportPlugin> __kindof*> *importPlugins;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|||||||
@@ -38,8 +38,8 @@
|
|||||||
#import "KeePassKit/KeePassKit.h"
|
#import "KeePassKit/KeePassKit.h"
|
||||||
|
|
||||||
|
|
||||||
NSString *const MPPluginHostWillLoadPlugin = @"com.hicknhack.macpass.MPPluginHostWillLoadPlugin";
|
NSString *const MPPluginHostWillLoadPluginNotification = @"com.hicknhack.macpass.MPPluginHostWillLoadPlugin";
|
||||||
NSString *const MPPluginHostDidLoadPlugin = @"comt.hicknhack.macpass.MPPluginHostDidLoadPlugin";
|
NSString *const MPPluginHostDidLoadPluginNotification = @"comt.hicknhack.macpass.MPPluginHostDidLoadPlugin";
|
||||||
|
|
||||||
NSString *const MPPluginHostPluginBundleIdentifiyerKey = @"MPPluginHostPluginBundleIdentifiyerKey";
|
NSString *const MPPluginHostPluginBundleIdentifiyerKey = @"MPPluginHostPluginBundleIdentifiyerKey";
|
||||||
|
|
||||||
@@ -87,13 +87,6 @@ NSString *const MPPluginHostPluginBundleIdentifiyerKey = @"MPPluginHostPluginBun
|
|||||||
return [self.mutablePlugins copy];
|
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 {
|
- (BOOL)installPluginAtURL:(NSURL *)url error:(NSError *__autoreleasing *)error {
|
||||||
if(![self _isValidPluginURL:url]) {
|
if(![self _isValidPluginURL:url]) {
|
||||||
if(error) {
|
if(error) {
|
||||||
@@ -267,11 +260,11 @@ NSString *const MPPluginHostPluginBundleIdentifiyerKey = @"MPPluginHostPluginBun
|
|||||||
|
|
||||||
if(plugin) {
|
if(plugin) {
|
||||||
NSLog(@"Loaded plugin instance %@", pluginBundle.principalClass);
|
NSLog(@"Loaded plugin instance %@", pluginBundle.principalClass);
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:MPPluginHostWillLoadPlugin
|
[[NSNotificationCenter defaultCenter] postNotificationName:MPPluginHostWillLoadPluginNotification
|
||||||
object:self
|
object:self
|
||||||
userInfo:@{ MPPluginHostPluginBundleIdentifiyerKey : plugin.identifier }];
|
userInfo:@{ MPPluginHostPluginBundleIdentifiyerKey : plugin.identifier }];
|
||||||
[self _addPlugin:plugin];
|
[self _addPlugin:plugin];
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:MPPluginHostDidLoadPlugin
|
[[NSNotificationCenter defaultCenter] postNotificationName:MPPluginHostDidLoadPluginNotification
|
||||||
object:self
|
object:self
|
||||||
userInfo:@{ MPPluginHostPluginBundleIdentifiyerKey : plugin.identifier }];
|
userInfo:@{ MPPluginHostPluginBundleIdentifiyerKey : plugin.identifier }];
|
||||||
}
|
}
|
||||||
@@ -414,6 +407,18 @@ NSString *const MPPluginHostPluginBundleIdentifiyerKey = @"MPPluginHostPluginBun
|
|||||||
[context.plugin performActionForMenuItem:item withEntries:context.entries];
|
[context.plugin performActionForMenuItem:item withEntries:context.entries];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@end
|
@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