From 0160b9055a2f86db5ed7a466f1d3645487c2eee1 Mon Sep 17 00:00:00 2001 From: michael starke Date: Thu, 27 Mar 2014 22:03:04 +0100 Subject: [PATCH] Cleaned up logging Added bagde icon to show timeout for clipboard clearing Badge display not optimal if clipboard clearing is disabled Autotype incovation on locked documents now activates MacPass to unlock. If multipel entries match, the seleciton dialog will pop up as well --- MacPass.xcodeproj/project.pbxproj | 6 ++ MacPass/MPAppDelegate.m | 3 + MacPass/MPAutotypeDaemon.m | 103 ++++++++++++++++++++------- MacPass/MPAutotypePaste.m | 1 - MacPass/MPDockTileHelper.h | 13 ++++ MacPass/MPDockTileHelper.m | 64 +++++++++++++++++ MacPass/MPDocument.m | 4 ++ MacPass/MPPasteBoardController.h | 2 +- MacPass/MPPasteBoardController.m | 7 +- MacPass/de.lproj/Localizable.strings | Bin 9612 -> 9754 bytes MacPass/en.lproj/Localizable.strings | Bin 9498 -> 9170 bytes MacPass/fr.lproj/Localizable.strings | Bin 9748 -> 9888 bytes 12 files changed, 171 insertions(+), 32 deletions(-) create mode 100644 MacPass/MPDockTileHelper.h create mode 100644 MacPass/MPDockTileHelper.m diff --git a/MacPass.xcodeproj/project.pbxproj b/MacPass.xcodeproj/project.pbxproj index 0bf84533..ca0b742c 100644 --- a/MacPass.xcodeproj/project.pbxproj +++ b/MacPass.xcodeproj/project.pbxproj @@ -114,6 +114,7 @@ 4C473A7F18AFD6340073FD2E /* KPKTestReference.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C473A7E18AFD6340073FD2E /* KPKTestReference.m */; }; 4C473A8718AFD85B0073FD2E /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C473A8518AFD7250073FD2E /* XCTest.framework */; }; 4C4A100F176286FD00BBF2CA /* MPTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C4A100E176286FD00BBF2CA /* MPTableView.m */; }; + 4C4B728518E4B9B400A1A5D5 /* MPDockTileHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C4B728418E4B9B400A1A5D5 /* MPDockTileHelper.m */; }; 4C4B7EE917A45EC6000234C7 /* MPDatePickingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C4B7EE717A45EC5000234C7 /* MPDatePickingViewController.m */; }; 4C4B7EEE17A467E1000234C7 /* MPGroupInspectorViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C4B7EEC17A467E1000234C7 /* MPGroupInspectorViewController.m */; }; 4C4B7EF317A467FC000234C7 /* MPEntryInspectorViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C4B7EF117A467FC000234C7 /* MPEntryInspectorViewController.m */; }; @@ -559,6 +560,8 @@ 4C48A56018BE932100278A2D /* HNHCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HNHCommon.h; sourceTree = ""; }; 4C4A100D176286FD00BBF2CA /* MPTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPTableView.h; sourceTree = ""; }; 4C4A100E176286FD00BBF2CA /* MPTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPTableView.m; sourceTree = ""; }; + 4C4B728318E4B9B400A1A5D5 /* MPDockTileHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPDockTileHelper.h; sourceTree = ""; }; + 4C4B728418E4B9B400A1A5D5 /* MPDockTileHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPDockTileHelper.m; sourceTree = ""; }; 4C4B7EE617A45EC5000234C7 /* MPDatePickingViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPDatePickingViewController.h; sourceTree = ""; }; 4C4B7EE717A45EC5000234C7 /* MPDatePickingViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPDatePickingViewController.m; sourceTree = ""; }; 4C4B7EEB17A467E1000234C7 /* MPGroupInspectorViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPGroupInspectorViewController.h; sourceTree = ""; }; @@ -1267,6 +1270,8 @@ 4C26C33E18D8C92100CF1A1C /* MPTemporaryFileStorage.m */, 4C88C66718D9F8D600F43852 /* MPTemporaryFileStorageCenter.h */, 4C88C66818D9F8D600F43852 /* MPTemporaryFileStorageCenter.m */, + 4C4B728318E4B9B400A1A5D5 /* MPDockTileHelper.h */, + 4C4B728418E4B9B400A1A5D5 /* MPDockTileHelper.m */, ); name = Helper; sourceTree = ""; @@ -2321,6 +2326,7 @@ 4C74DD07177BD1640034A9DB /* MPCustomFieldView.m in Sources */, 4C4FCE15177CFE6B00BBF7AE /* MPCustomFieldTableCellView.m in Sources */, 4C26C34B18D8D5A300CF1A1C /* MPPreviewViewController.m in Sources */, + 4C4B728518E4B9B400A1A5D5 /* MPDockTileHelper.m in Sources */, 4C52A244177D7B9F0000D88F /* HNHScrollView.m in Sources */, 4CC7EA1B17807E7E0089D4F3 /* HNHRoundedTextFieldCellHelper.m in Sources */, 4C5FE9AE17843CE20001D5A8 /* MPSelectedAttachmentTableCellView.m in Sources */, diff --git a/MacPass/MPAppDelegate.m b/MacPass/MPAppDelegate.m index 5388fe2e..8e62885b 100644 --- a/MacPass/MPAppDelegate.m +++ b/MacPass/MPAppDelegate.m @@ -32,6 +32,7 @@ #import "MPAutotypeDaemon.h" #import "MPDocumentWindowController.h" #import "MPFixAutotypeWindowController.h" +#import "MPDockTileHelper.h" #import "MPTemporaryFileStorageCenter.h" @@ -45,6 +46,7 @@ NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDi MPServerDaemon *serverDaemon; MPLockDaemon *lockDaemon; MPAutotypeDaemon *autotypeDaemon; + MPDockTileHelper *dockTileHelper; BOOL _shouldOpenFile; // YES if app was started to open a } @@ -147,6 +149,7 @@ NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDi serverDaemon = [[MPServerDaemon alloc] init]; lockDaemon = [[MPLockDaemon alloc] init]; autotypeDaemon = [[MPAutotypeDaemon alloc] init]; + dockTileHelper = [[MPDockTileHelper alloc] init]; } - (NSString *)applicationName { diff --git a/MacPass/MPAutotypeDaemon.m b/MacPass/MPAutotypeDaemon.m index fb737982..c3dbc2c1 100644 --- a/MacPass/MPAutotypeDaemon.m +++ b/MacPass/MPAutotypeDaemon.m @@ -29,12 +29,16 @@ NSString *const kMPApplciationNameKey = @"applicationName"; @interface MPAutotypeDaemon () @property (nonatomic, assign) BOOL enabled; -@property (copy) NSString *lastFrontMostApplication; +@property (copy) NSString *targetApplicationName; +@property (copy) NSString *targetWindowTitle; @end @implementation MPAutotypeDaemon +#pragma mark - +#pragma mark Lifecylce + - (id)init { self = [super init]; if (self) { @@ -51,7 +55,9 @@ NSString *const kMPApplciationNameKey = @"applicationName"; [self unbind:@"enabled"]; } +#pragma mark - #pragma mark Properties + - (void)setEnabled:(BOOL)enabled { if(_enabled != enabled) { _enabled = enabled; @@ -59,6 +65,9 @@ NSString *const kMPApplciationNameKey = @"applicationName"; } } +#pragma mark - +#pragma mark Actions + - (void)executeAutotypeWithSelectedMatch:(id)sender { NSMenuItem *item = [self.matchSelectionButton selectedItem]; MPAutotypeContext *context = [item representedObject]; @@ -68,16 +77,33 @@ NSString *const kMPApplciationNameKey = @"applicationName"; - (void)cancelAutotypeSelection:(id)sender { [self.matchSelectionWindow orderOut:sender]; - if(self.lastFrontMostApplication) { - [MPAutotypeDaemon _orderApplicationToFront:self.lastFrontMostApplication]; + if(self.targetApplicationName) { + [MPAutotypeDaemon _orderApplicationToFront:self.targetApplicationName]; } } -- (void)_didPressHotKey { +#pragma mark - +#pragma mark Hotkey evaluation - /* Reset the applciation on every keypress */ - self.lastFrontMostApplication = nil; - +- (void)_didPressHotKey { + [self _performAutotypeUsingCurrentWindowAndApplication:YES]; +} + +- (void)_performAutotypeUsingCurrentWindowAndApplication:(BOOL)useCurrentWindowAndApplication { + if(useCurrentWindowAndApplication) { + [self _updateTargetApplicationAndWindow]; + } + + MPDocument *document = [self _findAutotypeDocument]; + if(!document) { + return; // nothing to do + } + + MPAutotypeContext *context = [self _autotypeContextInDocument:document forWindowTitle:self.targetWindowTitle]; + [self _performAutotypeForContext:context]; +} + +- (MPDocument *)_findAutotypeDocument { NSArray *documents = [NSApp orderedDocuments]; MPDocument *currentDocument = nil; for(MPDocument *openDocument in documents) { @@ -86,40 +112,42 @@ NSString *const kMPApplciationNameKey = @"applicationName"; break; } } - if(!currentDocument) { - return; // No need to search in closed documents + BOOL hasOpenDocuments = [documents count] > 0; + if(!currentDocument && hasOpenDocuments) { + [NSApp activateIgnoringOtherApps:YES]; + [[NSApp mainWindow] makeKeyAndOrderFront:self]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_didUnlockDatabase:) name:MPDocumentDidUnlockDatabaseNotification object:nil]; } - /* - Determine the window title of the current front most application - Start searching the db for the best fit (based on title, then on window associations - */ - NSDictionary *frontApplicationInfoDict = [self _frontMostApplicationInfoDict]; - NSString *windowTitle = frontApplicationInfoDict[kMPWindowTitleKey]; - self.lastFrontMostApplication = frontApplicationInfoDict[kMPApplciationNameKey]; + return currentDocument; +} + +- (MPAutotypeContext *)_autotypeContextInDocument:(MPDocument *)document forWindowTitle:(NSString *)windowTitle { /* Query the document to generate a autotype command list for the window title We do not care where this came form, just get the autotype commands */ - NSArray *autotypeCandidates = [currentDocument autotypContextsForWindowTitle:windowTitle]; - NSInteger candiates = [autotypeCandidates count]; - if(candiates == 0) { - return; // No Entries found. + NSArray *autotypeCandidates = [document autotypContextsForWindowTitle:windowTitle]; + NSUInteger candidates = [autotypeCandidates count]; + if(candidates == 0) { + return nil; } - if(candiates > 1) { - [self _presentSelectionWindow:autotypeCandidates]; - return; // Nothing to do, we get called back by the window + if(candidates == 1 ) { + return [autotypeCandidates lastObject]; } - [self _performAutotypeForContext:autotypeCandidates[0]]; + [self _presentSelectionWindow:autotypeCandidates]; + return nil; // Nothing to do, we get called back by the window } - (void)_performAutotypeForContext:(MPAutotypeContext *)context { + if(nil == context) { + return; // No context to work with + } dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSArray *commands = [MPAutotypeCommand commandsForContext:context]; - [MPAutotypeDaemon _orderApplicationToFront:self.lastFrontMostApplication]; + [MPAutotypeDaemon _orderApplicationToFront:self.targetApplicationName]; BOOL lastCommandWasPaste = NO; for(MPAutotypeCommand *command in commands) { if(lastCommandWasPaste) { - NSLog(@"Sleeping for pasting!"); usleep(1000*1000); } [command execute]; @@ -128,6 +156,9 @@ NSString *const kMPApplciationNameKey = @"applicationName"; }); } +#pragma mark - +#pragma mark Hotkey Registration + - (void)_registerHotKey { [[DDHotKeyCenter sharedHotKeyCenter] registerHotKeyWithKeyCode:kVK_ANSI_M modifierFlags:(NSCommandKeyMask | NSAlternateKeyMask ) @@ -188,6 +219,17 @@ NSString *const kMPApplciationNameKey = @"applicationName"; /* Setup Items in Popup */ } +#pragma mark - +#pragma mark MPDocument Notifications + +- (void)_didUnlockDatabase:(NSNotification *)notification { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [self _performAutotypeUsingCurrentWindowAndApplication:NO]; +} + +#pragma mark - +#pragma mark Application information + + (void)_orderApplicationToFront:(NSString *)applicationName { //NSLog(@"Moving %@ to the front.", applicationName); NSString *appleScript = [[NSString alloc] initWithFormat:@"activate application \"%@\"", applicationName]; @@ -199,5 +241,14 @@ NSString *const kMPApplciationNameKey = @"applicationName"; } } +- (void)_updateTargetApplicationAndWindow { + /* + Determine the window title of the current front most application + Start searching the db for the best fit (based on title, then on window associations + */ + NSDictionary *frontApplicationInfoDict = [self _frontMostApplicationInfoDict]; + self.targetApplicationName = frontApplicationInfoDict[kMPApplciationNameKey]; + self.targetWindowTitle = frontApplicationInfoDict[kMPWindowTitleKey]; +} @end diff --git a/MacPass/MPAutotypePaste.m b/MacPass/MPAutotypePaste.m index bb644ade..66d0b916 100644 --- a/MacPass/MPAutotypePaste.m +++ b/MacPass/MPAutotypePaste.m @@ -28,7 +28,6 @@ } - (void)execute { - [NSThread isMainThread] ? NSLog(@"MainThread") : NSLog(@"NonMainThread"); if([self.pasteData length] > 0) { MPPasteBoardController *controller = [MPPasteBoardController defaultController]; [controller copyObjects:@[self.pasteData]]; diff --git a/MacPass/MPDockTileHelper.h b/MacPass/MPDockTileHelper.h new file mode 100644 index 00000000..135e2f77 --- /dev/null +++ b/MacPass/MPDockTileHelper.h @@ -0,0 +1,13 @@ +// +// MPDockTileHelper.h +// MacPass +// +// Created by Michael Starke on 27/03/14. +// Copyright (c) 2014 HicknHack Software GmbH. All rights reserved. +// + +#import + +@interface MPDockTileHelper : NSObject + +@end diff --git a/MacPass/MPDockTileHelper.m b/MacPass/MPDockTileHelper.m new file mode 100644 index 00000000..46b07c3e --- /dev/null +++ b/MacPass/MPDockTileHelper.m @@ -0,0 +1,64 @@ +// +// MPDockTileHelper.m +// MacPass +// +// Created by Michael Starke on 27/03/14. +// Copyright (c) 2014 HicknHack Software GmbH. All rights reserved. +// + +#import "MPDockTileHelper.h" +#import "MPPasteBoardController.h" + +@interface MPDockTileHelper () { + BOOL _pasteboardCleard; +} + +@property (assign) NSTimeInterval timeStamp; + +@end + +@implementation MPDockTileHelper + +- (instancetype)init { + self = [super init]; + if (self) { + MPPasteBoardController *controller = [MPPasteBoardController defaultController]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didCopyToPastboard:) name:MPPasteBoardControllerDidCopyObjects object:controller]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didClearPasteboard:) name:MPPasteBoardControllerDidClearClipboard object:controller]; + } + return self; +} + +- (void)didCopyToPastboard:(NSNotification *)notification { + self.timeStamp = [NSDate timeIntervalSinceReferenceDate]; + _pasteboardCleard = NO; + if([MPPasteBoardController defaultController].clearTimeout > 0) { + [self updateBadge]; + } +} + +- (void)didClearPasteboard:(NSNotification *)notification { + _pasteboardCleard = YES; + if([MPPasteBoardController defaultController].clearTimeout > 0) { + [[NSApp dockTile] setBadgeLabel:NSLocalizedString(@"CLEARING_PASTEBOARD","")]; + } + [self performSelector:@selector(clearBadge) withObject:nil afterDelay:1]; +} + +- (void)clearBadge { + [[NSApp dockTile] setBadgeLabel:nil]; +} + +- (void)updateBadge { + if(_pasteboardCleard) { + return; + } + NSTimeInterval timeOut = [MPPasteBoardController defaultController].clearTimeout; + NSTimeInterval countDown = timeOut - ([NSDate timeIntervalSinceReferenceDate] - self.timeStamp); + if(countDown > 0) { + [[NSApp dockTile] setBadgeLabel:[[NSString alloc] initWithFormat:@"%d", (int)countDown]]; + [self performSelector:@selector(updateBadge) withObject:nil afterDelay:1]; + } +} + +@end diff --git a/MacPass/MPDocument.m b/MacPass/MPDocument.m index fa06c996..3527bcdd 100644 --- a/MacPass/MPDocument.m +++ b/MacPass/MPDocument.m @@ -262,6 +262,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey /* Locking needs to be lossless hence just use the XML format */ _encryptedData = [self.tree encryptWithPassword:self.compositeKey forVersion:KPKXmlVersion error:&error]; self.tree = nil; + [[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidLockDatabaseNotification object:self]; } - (BOOL)unlockWithPassword:(NSString *)password keyFileURL:(NSURL *)keyFileURL error:(NSError *__autoreleasing*)error{ @@ -280,6 +281,9 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey else { self.compositeKey = nil; // clear the key? } + if(isUnlocked) { + [[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidUnlockDatabaseNotification object:self]; + } return isUnlocked; } diff --git a/MacPass/MPPasteBoardController.h b/MacPass/MPPasteBoardController.h index 806bd90c..66ab6740 100644 --- a/MacPass/MPPasteBoardController.h +++ b/MacPass/MPPasteBoardController.h @@ -1,5 +1,5 @@ -// // MPPastBoardController.h +// // MacPass // // Created by Michael Starke on 02.03.13. diff --git a/MacPass/MPPasteBoardController.m b/MacPass/MPPasteBoardController.m index 78bb34e5..6362776c 100644 --- a/MacPass/MPPasteBoardController.m +++ b/MacPass/MPPasteBoardController.m @@ -11,7 +11,7 @@ /* Notifications */ NSString *const MPPasteBoardControllerDidCopyObjects = @"com.hicknhack.macpass.MPPasteBoardControllerDidCopyObjects"; -NSString *const MPPasteBoardControllerDidClearClipboard = @"com.hicknhack.macpass.MPPasteBoardControllerDidCopyObjects"; +NSString *const MPPasteBoardControllerDidClearClipboard = @"com.hicknhack.macpass.MPPasteBoardControllerDidClearClipboard"; @interface MPPasteBoardController () @@ -73,7 +73,6 @@ NSString *const MPPasteBoardControllerDidClearClipboard = @"com.hicknhack.macpas } - (void)copyObjects:(NSArray *)objects { - NSLog(@"ShoudlCopy %@", objects); /* Should we save the old content ?*/ [[NSPasteboard generalPasteboard] clearContents]; [[NSPasteboard generalPasteboard] writeObjects:objects]; @@ -96,9 +95,9 @@ NSString *const MPPasteBoardControllerDidClearClipboard = @"com.hicknhack.macpas - (void)_setupBindings { NSUserDefaultsController *userDefaultsController = [NSUserDefaultsController sharedUserDefaultsController]; NSString *clearOnShutdownKeyPath = [NSString stringWithFormat:@"values.%@", kMPSettingsKeyClearPasteboardOnQuit]; + [self bind:NSStringFromSelector(@selector(clearPasteboardOnShutdown)) toObject:userDefaultsController withKeyPath:clearOnShutdownKeyPath options:nil]; NSString *clearTimoutKeyPath = [NSString stringWithFormat:@"values.%@", kMPSettingsKeyPasteboardClearTimeout]; - [self bind:@"clearPasteboardOnShutdown" toObject:userDefaultsController withKeyPath:clearOnShutdownKeyPath options:nil]; - [self bind:@"clearTimeout" toObject:userDefaultsController withKeyPath:clearTimoutKeyPath options:nil]; + [self bind:NSStringFromSelector(@selector(clearTimeout)) toObject:userDefaultsController withKeyPath:clearTimoutKeyPath options:nil]; } @end diff --git a/MacPass/de.lproj/Localizable.strings b/MacPass/de.lproj/Localizable.strings index 284f207fe7f601f08f947d8de5bc207fd978e7fb..d21fed7c612cc2205ffcf7048faebaeb326c544e 100644 GIT binary patch delta 132 zcmeD2p5?RQ3Ws_CLlA>2Ll}c6kPK%~Vo+eP1!5(jNIpXmLoq`#Lk2@4L+NBePSMQ| zIDB{{^%=B)3S5BF$qd;*mJ?7qg(00Gb@F>IQ4LQ9KL&S(c!mH5M}}aA5TKz>4E{iN Q5Ksrga5aU^Dxw(z0Q(6TumAu6 delta 25 hcmbQ`)8oD23ddwGPM*yIoIX60e=&1yJ|Y?>004ab2%-JB3YPn=K6fQ~@DDmSFJTEMg_PL=4f5?rsV}(0AC*rx5Zc zmVysqVefZ`q)Rb#=YDg}+__)fkKU)}mETL1>8tm?^43%+Uq`x8t`SwCF*#AD0jwbV zoD<`PUi4&SpcIm6$Sp^4hb!aExjzsI-61T6-Qsd{@69^NBI(&1+%in74 ya<1s0>Fb2J(y1w&;|v<%+Mj!v?rV=|*yPrNJzK6*)>msARxQ}n`1Ei6XZatfEk&#V diff --git a/MacPass/fr.lproj/Localizable.strings b/MacPass/fr.lproj/Localizable.strings index 73031cbf0d60681d1f18905add304e2b326c2181..128b292279c4ca58feaa2e51523d5b45e3ac27b3 100644 GIT binary patch delta 142 zcmbQ@v%q)5D-P8Fh9Cx4hA;+CAQ{e}#Gt@n3&ctc0SrY9sSITdnLx69^Fxl;JYo6_ zT0kimhJ1!(hHN0qi6N08g&`fNKmjPD&%g!L=FH#&G{_NXs3(ITgF8b!&>%;KV1^K& Us1t)fSjGj(8a0K@M??bz0MRZPQ2+n{ delta 17 ZcmZ4BJH=