From 692ade211079c76c12d0417988bd00aea08c58a2 Mon Sep 17 00:00:00 2001 From: michael starke Date: Wed, 17 Dec 2014 11:20:30 +0100 Subject: [PATCH] Autotype for selected entry is working rudimentarily --- MacPass/MPActionHelper.h | 3 +- MacPass/MPActionHelper.m | 41 ++++++++++++++------------- MacPass/MPAutotypeContext.h | 10 +++---- MacPass/MPAutotypeDaemon.h | 2 +- MacPass/MPAutotypeDaemon.m | 36 ++++++++++++----------- MacPass/MPContextMenuHelper.h | 17 +++++------ MacPass/MPContextMenuHelper.m | 9 ++++++ MacPass/MPDocument+Autotype.m | 14 +++++++-- MacPass/MPDocument.m | 3 ++ MacPass/MPDocumentWindowController.m | 2 +- MacPass/MPEntryViewController.m | 1 - MacPass/en.lproj/Localizable.strings | Bin 11956 -> 12058 bytes 12 files changed, 80 insertions(+), 58 deletions(-) diff --git a/MacPass/MPActionHelper.h b/MacPass/MPActionHelper.h index b2347152..cb29f8fa 100644 --- a/MacPass/MPActionHelper.h +++ b/MacPass/MPActionHelper.h @@ -29,7 +29,8 @@ typedef NS_ENUM(NSUInteger, MPActionType) { MPActionImportXML, // Import form XML MPActionToggleQuicklook, MPActionShowHistory, // History anzeigen - MPActionExitHistory // History ausblenden + MPActionExitHistory, // History ausblenden + MPActionPerformAutotypeForSelectedEntry // Perform Autotype for selected Entry }; /** * Helper to retrieve commonly used actions diff --git a/MacPass/MPActionHelper.m b/MacPass/MPActionHelper.m index 557dbff8..e629b779 100644 --- a/MacPass/MPActionHelper.m +++ b/MacPass/MPActionHelper.m @@ -19,26 +19,27 @@ static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ actionDict = @{ - @(MPActionAddEntry): NSStringFromSelector(@selector(createEntry:)), - @(MPActionAddGroup): NSStringFromSelector(@selector(createGroup:)), - @(MPActionDuplicateEntry): NSStringFromSelector(@selector(duplicateEntry:)), - @(MPActionDuplicateEntryWithOptions): NSStringFromSelector(@selector(duplicateEntryWithOptions:)), - @(MPActionCopyPassword): NSStringFromSelector(@selector(copyPassword:)), - @(MPActionCopyURL): NSStringFromSelector(@selector(copyURL:)), - @(MPActionCopyUsername): NSStringFromSelector(@selector(copyUsername:)), - @(MPActionDelete): NSStringFromSelector(@selector(delete:)), - @(MPActionEditPassword): NSStringFromSelector(@selector(editPassword:)), - @(MPActionOpenURL): NSStringFromSelector(@selector(openURL:)), - @(MPActionToggleInspector): NSStringFromSelector(@selector(toggleInspector:)), - @(MPActionLock): NSStringFromSelector(@selector(lock:)), - @(MPActionEmptyTrash): NSStringFromSelector(@selector(emptyTrash:)), - @(MPActionDatabaseSettings): NSStringFromSelector(@selector(showDatabaseSettings:)), - @(MPActionEditTemplateGroup): NSStringFromSelector(@selector(editTemplateGroup:)), - @(MPActionExportXML): NSStringFromSelector(@selector(exportAsXML:)), - @(MPActionImportXML): NSStringFromSelector(@selector(importFromXML:)), - @(MPActionToggleQuicklook): NSStringFromSelector(@selector(toggleQuicklookPreview:)), - @(MPActionShowHistory): NSStringFromSelector(@selector(showHistory:)), - @(MPActionExitHistory): NSStringFromSelector(@selector(exitHistory:)) + @(MPActionAddEntry): NSStringFromSelector(@selector(createEntry:)), + @(MPActionAddGroup): NSStringFromSelector(@selector(createGroup:)), + @(MPActionDuplicateEntry): NSStringFromSelector(@selector(duplicateEntry:)), + @(MPActionDuplicateEntryWithOptions): NSStringFromSelector(@selector(duplicateEntryWithOptions:)), + @(MPActionCopyPassword): NSStringFromSelector(@selector(copyPassword:)), + @(MPActionCopyURL): NSStringFromSelector(@selector(copyURL:)), + @(MPActionCopyUsername): NSStringFromSelector(@selector(copyUsername:)), + @(MPActionDelete): NSStringFromSelector(@selector(delete:)), + @(MPActionEditPassword): NSStringFromSelector(@selector(editPassword:)), + @(MPActionOpenURL): NSStringFromSelector(@selector(openURL:)), + @(MPActionToggleInspector): NSStringFromSelector(@selector(toggleInspector:)), + @(MPActionLock): NSStringFromSelector(@selector(lock:)), + @(MPActionEmptyTrash): NSStringFromSelector(@selector(emptyTrash:)), + @(MPActionDatabaseSettings): NSStringFromSelector(@selector(showDatabaseSettings:)), + @(MPActionEditTemplateGroup): NSStringFromSelector(@selector(editTemplateGroup:)), + @(MPActionExportXML): NSStringFromSelector(@selector(exportAsXML:)), + @(MPActionImportXML): NSStringFromSelector(@selector(importFromXML:)), + @(MPActionToggleQuicklook): NSStringFromSelector(@selector(toggleQuicklookPreview:)), + @(MPActionShowHistory): NSStringFromSelector(@selector(showHistory:)), + @(MPActionExitHistory): NSStringFromSelector(@selector(exitHistory:)), + @(MPActionPerformAutotypeForSelectedEntry): NSStringFromSelector(@selector(performAutotypeForEntry:)) }; }); return actionDict; diff --git a/MacPass/MPAutotypeContext.h b/MacPass/MPAutotypeContext.h index d83cfd73..282ecb36 100644 --- a/MacPass/MPAutotypeContext.h +++ b/MacPass/MPAutotypeContext.h @@ -30,6 +30,10 @@ * Command with placeholders and references resolved */ @property (nonatomic, readonly, copy) NSString *evaluatedCommand; +/** + * @return YES if valid, NO otherwise + */ +@property (nonatomic, readonly, assign) BOOL isValid; /** * Designated initializer @@ -42,11 +46,5 @@ - (instancetype)initWithEntry:(KPKEntry *)entry andSequence:(NSString *)sequence; - (instancetype)initWithDefaultSequenceForEntry:(KPKEntry *)entry; - (instancetype)initWithWindowAssociation:(KPKWindowAssociation *)association; -/** - * Returns YES if the given sequence is valid (currentyl only bracke missmatch is regarded as invalid - * - * @return YES if valid, NO otherwise - */ -- (BOOL)isValid; @end diff --git a/MacPass/MPAutotypeDaemon.h b/MacPass/MPAutotypeDaemon.h index 10a7c974..d67351c4 100644 --- a/MacPass/MPAutotypeDaemon.h +++ b/MacPass/MPAutotypeDaemon.h @@ -20,7 +20,7 @@ @property (weak) IBOutlet NSPopUpButton *matchSelectionButton; @property (readonly, strong) DDHotKey *registredHotKey; -- (void)performAutotypeForEntry:(KPKEntry *)entryOrNil; +- (void)performAutotypeForEntry:(KPKEntry *)entry; - (IBAction)performAutotypeWithSelectedMatch:(id)sender; - (IBAction)cancelAutotypeSelection:(id)sender; diff --git a/MacPass/MPAutotypeDaemon.m b/MacPass/MPAutotypeDaemon.m index b9accd23..6a448128 100644 --- a/MacPass/MPAutotypeDaemon.m +++ b/MacPass/MPAutotypeDaemon.m @@ -34,8 +34,9 @@ NSString *const kMPProcessIdentifierKey = @"kMPProcessIdentifierKey"; @property (nonatomic, assign) BOOL enabled; @property (nonatomic, copy) NSData *hotKeyData; @property (strong) DDHotKey *registredHotKey; -@property (assign) pid_t targetPID; -@property (copy) NSString *targetWindowTitle; +@property (assign) pid_t targetPID; // The pid of the process we want to sent commands to +@property (copy) NSString *targetWindowTitle; // The title of the window that we are targeting +@property (strong) NSRunningApplication *previousApplication; // The application that was active before we got invoked @end @@ -43,7 +44,6 @@ NSString *const kMPProcessIdentifierKey = @"kMPProcessIdentifierKey"; #pragma mark - #pragma mark Lifecylce - - (instancetype)init { self = [super init]; if (self) { @@ -76,7 +76,6 @@ NSString *const kMPProcessIdentifierKey = @"kMPProcessIdentifierKey"; #pragma mark - #pragma mark Properties - - (void)setEnabled:(BOOL)enabled { if(_enabled != enabled) { _enabled = enabled; @@ -94,7 +93,18 @@ NSString *const kMPProcessIdentifierKey = @"kMPProcessIdentifierKey"; } } -- (void)executeAutotypeForEntry:(KPKEntry *)entry { +#pragma mark - +#pragma mark Autotype Invocation +- (void)performAutotypeForEntry:(KPKEntry *)entry { + if(entry) { + [self _updateTargeInformationForApplication:self.previousApplication]; + [self _performAutotypeForEntry:entry]; + } +} + +- (void)_didPressHotKey { + [self _updateTargetInfoForFrontMostApplication]; + [self _performAutotypeForEntry:nil]; } #pragma mark - @@ -114,14 +124,9 @@ NSString *const kMPProcessIdentifierKey = @"kMPProcessIdentifierKey"; } #pragma mark - -#pragma mark Hotkey evaluation +#pragma mark Autotype Execution -- (void)_didPressHotKey { - [self _updateTargetInfoForFrontMostApplication]; - [self performAutotypeForEntry:nil]; -} - -- (void)performAutotypeForEntry:(KPKEntry *)entryOrNil { +- (void)_performAutotypeForEntry:(KPKEntry *)entryOrNil { NSInteger pid = [[NSProcessInfo processInfo] processIdentifier]; if(self.targetPID == pid) { return; // We do not perform Autotype on ourselves @@ -200,7 +205,6 @@ NSString *const kMPProcessIdentifierKey = @"kMPProcessIdentifierKey"; #pragma mark - #pragma mark Hotkey Registration - - (void)_registerHotKey { __weak MPAutotypeDaemon *welf = self; DDHotKeyTask aTask = ^(NSEvent *event) { @@ -272,23 +276,21 @@ NSString *const kMPProcessIdentifierKey = @"kMPProcessIdentifierKey"; #pragma mark - #pragma mark MPDocument Notifications - - (void)_didUnlockDatabase:(NSNotification *)notification { /* Remove ourselves and call again to search matches */ [[NSNotificationCenter defaultCenter] removeObserver:self]; - [self performAutotypeForEntry:nil]; + [self _performAutotypeForEntry:nil]; } #pragma mark - #pragma mark NSApplication Notifications - (void)_didDeactivateApplication:(NSNotification *)notification { NSDictionary *userInfo = notification.userInfo; - [self _updateTargeInformationForApplication:userInfo[NSWorkspaceApplicationKey]]; + self.previousApplication = userInfo[NSWorkspaceApplicationKey]; } #pragma mark - #pragma mark Application information - - (BOOL)_orderApplicationToFront:(pid_t)processIdentifier { NSRunningApplication *runingApplication = [NSRunningApplication runningApplicationWithProcessIdentifier:processIdentifier]; NSRunningApplication *frontApplication = [[NSWorkspace sharedWorkspace] frontmostApplication]; diff --git a/MacPass/MPContextMenuHelper.h b/MacPass/MPContextMenuHelper.h index 8e1682c1..92c4d458 100644 --- a/MacPass/MPContextMenuHelper.h +++ b/MacPass/MPContextMenuHelper.h @@ -9,14 +9,15 @@ #import typedef NS_OPTIONS(NSUInteger, MPContextMenuItemsFlags) { - MPContextMenuCreate = 1 << 0, - MPContextMenuDelete = 1 << 1, - MPContextMenuCopy = 1 << 2, - MPContextMenuTrash = 1 << 3, - MPContextMenuDuplicate = 1 << 4, - MPContextMenuMinimal = MPContextMenuCreate | MPContextMenuDelete, - MPContextMenuFull = MPContextMenuMinimal | MPContextMenuCopy | MPContextMenuDuplicate, - MPContextMenuExtended = MPContextMenuFull | MPContextMenuTrash + MPContextMenuCreate = 1 << 0, + MPContextMenuDelete = 1 << 1, + MPContextMenuCopy = 1 << 2, + MPContextMenuTrash = 1 << 3, + MPContextMenuDuplicate = 1 << 4, + MPContextMenuAutotype = 1 << 5, + MPContextMenuMinimal = MPContextMenuCreate | MPContextMenuDelete, + MPContextMenuFull = MPContextMenuMinimal | MPContextMenuCopy | MPContextMenuDuplicate | MPContextMenuAutotype, + MPContextMenuExtended = MPContextMenuFull | MPContextMenuTrash }; @interface MPContextMenuHelper : NSTableCellView diff --git a/MacPass/MPContextMenuHelper.m b/MacPass/MPContextMenuHelper.m index f2269992..4274e388 100644 --- a/MacPass/MPContextMenuHelper.m +++ b/MacPass/MPContextMenuHelper.m @@ -26,6 +26,7 @@ static void MPContextmenuHelperBeginSection(NSMutableArray *items) { BOOL const insertCopy = MPIsFlagSetInOptions(MPContextMenuCopy, flags); BOOL const insertTrash = MPIsFlagSetInOptions(MPContextMenuTrash, flags); BOOL const insertDuplicate = MPIsFlagSetInOptions(MPContextMenuDuplicate, flags); + BOOL const insertAutotype = MPIsFlagSetInOptions(MPContextMenuAutotype, flags); NSMutableArray *items = [NSMutableArray arrayWithCapacity:10]; if(insertCreate) { @@ -97,6 +98,14 @@ static void MPContextmenuHelperBeginSection(NSMutableArray *items) { [items addObjectsFromArray:@[ copyUsername, copyPassword, urlItem]]; } + if(insertAutotype) { + MPContextmenuHelperBeginSection(items); + NSMenuItem *performAutotype = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"PERFORM_AUTOTYPE_FOR_ENTRY", @"") + action:[MPActionHelper actionOfType:MPActionPerformAutotypeForSelectedEntry] + keyEquivalent:@"a"]; + [performAutotype setKeyEquivalentModifierMask:[performAutotype keyEquivalentModifierMask] | NSControlKeyMask]; + [items addObject:performAutotype]; + } return items; } diff --git a/MacPass/MPDocument+Autotype.m b/MacPass/MPDocument+Autotype.m index 84c1f9e0..719841bb 100644 --- a/MacPass/MPDocument+Autotype.m +++ b/MacPass/MPDocument+Autotype.m @@ -50,8 +50,10 @@ if(!windowTitle) { return nil; } - NSArray *autotypeEntries = entry ? [[NSArray alloc] initWithObjects:entry, nil] : [self.root autotypeableChildEntries]; + BOOL usePreferredEntry = (nil != entry); + NSArray *autotypeEntries = usePreferredEntry ? [[NSArray alloc] initWithObjects:entry, nil] : [self.root autotypeableChildEntries]; NSMutableArray *contexts = [[NSMutableArray alloc] initWithCapacity:MAX(1,ceil([autotypeEntries count] / 4.0))]; + MPAutotypeContext *context; for(KPKEntry *entry in autotypeEntries) { /* TODO: @@ -68,7 +70,6 @@ if (titleRange.location == NSNotFound || titleRange.length == 0) { titleRange = [entry.title rangeOfString:windowTitle options:NSCaseInsensitiveSearch]; } - MPAutotypeContext *context; if(titleRange.location != NSNotFound && titleRange.length != 0) { context = [[MPAutotypeContext alloc] initWithEntry:entry andSequence:entry.autotype.defaultKeystrokeSequence]; } @@ -77,7 +78,14 @@ KPKWindowAssociation *association = [entry.autotype windowAssociationMatchingWindowTitle:windowTitle]; context = [[MPAutotypeContext alloc] initWithWindowAssociation:association]; } - if([context isValid]) { + if(context.isValid) { + [contexts addObject:context]; + } + } + /* Fall back to preferred Entry if no match was found */ + if(contexts.count == 0 && usePreferredEntry) { + context = [[MPAutotypeContext alloc] initWithEntry:entry andSequence:entry.autotype.defaultKeystrokeSequence]; + if(context.isValid) { [contexts addObject:context]; } } diff --git a/MacPass/MPDocument.m b/MacPass/MPDocument.m index 8b23da17..e02aa781 100644 --- a/MacPass/MPDocument.m +++ b/MacPass/MPDocument.m @@ -713,6 +713,9 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey case MPActionOpenURL: valid &= (nil != targetEntry ) && ([targetEntry.url length] > 0); break; + case MPActionPerformAutotypeForSelectedEntry: + valid &= (nil != targetEntry); + break; default: break; } diff --git a/MacPass/MPDocumentWindowController.m b/MacPass/MPDocumentWindowController.m index 46a17095..158f8f15 100644 --- a/MacPass/MPDocumentWindowController.m +++ b/MacPass/MPDocumentWindowController.m @@ -373,7 +373,7 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword); - (void)performAutotypeForEntry:(id)sender { id entryResolver = [NSApp targetForAction:@selector(currentTargetEntry)]; KPKEntry *targetEntry = [entryResolver currentTargetEntry]; - MPAutotypeDaemon *autotyped = ((MPAppDelegate *)[NSApplication sharedApplication]).autotypeDaemon; + MPAutotypeDaemon *autotyped = ((MPAppDelegate *)[NSApplication sharedApplication].delegate).autotypeDaemon; [autotyped performAutotypeForEntry:targetEntry]; } diff --git a/MacPass/MPEntryViewController.m b/MacPass/MPEntryViewController.m index 50d1cb44..5f37511e 100644 --- a/MacPass/MPEntryViewController.m +++ b/MacPass/MPEntryViewController.m @@ -143,7 +143,6 @@ NSString *const _MPTableSecurCellView = @"PasswordCell"; selector:@selector(_didBecomFirstResponder:) name:MPDidActivateViewNotification object:_entryTable]; - /* Filter bar notifications */ [self _setupEntryMenu]; NSTableColumn *parentColumn = [self.entryTable tableColumns][0]; diff --git a/MacPass/en.lproj/Localizable.strings b/MacPass/en.lproj/Localizable.strings index e3c97eaf8c945f40870e0eaccf62552ed6a22eda..b5d3ffbcc20ac82326f0de5532d08bf80fd05774 100644 GIT binary patch delta 72 zcmdlIJ1cI37N@E!LlA=-gFle;Wr$~RWC&#l0rEl^A{hc0T!A8BxygoH;=BP2sSHI7 TX$<*5GI#Prap}z(oIR=lJx>q? delta 12 TcmbOgws*