From 9da60cdaea66863aeaac65354030c676e5f8fdcf Mon Sep 17 00:00:00 2001 From: michael starke Date: Tue, 28 Oct 2014 23:07:57 +0100 Subject: [PATCH] Hotkey settings now actually should work. --- MacPass.xcodeproj/project.pbxproj | 12 +++---- MacPass/Base.lproj/IntegrationSettings.xib | 31 ++++++++++-------- MacPass/Base.lproj/PasswordCreatorView.xib | 2 +- MacPass/DDHotKey+MacPassAdditions.h | 19 +++++++++-- MacPass/DDHotKey+MacPassAdditions.m | 38 ++++++++++++++++++++-- MacPass/MPAutotypeDaemon.m | 3 +- MacPass/MPDocumentWindowController.m | 6 ++-- MacPass/MPIntegrationSettingsController.h | 1 + MacPass/MPIntegrationSettingsController.m | 38 +++++++++++++++------- MacPass/MPSettingsHelper.m | 2 ++ MacPass/MPSettingsTab.h | 4 +-- MacPass/MPSettingsWindowController.m | 11 ++++--- MacPass/MPWorkflowSettingsController.m | 2 +- MacPass/MacPass-Info.plist | 2 +- 14 files changed, 121 insertions(+), 50 deletions(-) diff --git a/MacPass.xcodeproj/project.pbxproj b/MacPass.xcodeproj/project.pbxproj index b3edd1bf..1241bfe0 100644 --- a/MacPass.xcodeproj/project.pbxproj +++ b/MacPass.xcodeproj/project.pbxproj @@ -184,7 +184,7 @@ 4C7714AA176C998F00549F2A /* 43_TrashTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4C7714A9176C998F00549F2A /* 43_TrashTemplate.pdf */; }; 4C7714AC176C9D4600549F2A /* 99_InfoTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4C7714AB176C9D4600549F2A /* 99_InfoTemplate.pdf */; }; 4C77547516E55FE800970E02 /* MPInspectorViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C77547416E55FE800970E02 /* MPInspectorViewController.m */; }; - 4C77C84118E240E000D1C42B /* DDHotKey+Keydata.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C77C84018E240E000D1C42B /* DDHotKey+Keydata.m */; }; + 4C77C84118E240E000D1C42B /* DDHotKey+MacPassAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C77C84018E240E000D1C42B /* DDHotKey+MacPassAdditions.m */; }; 4C77E36715B84A240093A587 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C77E36615B84A240093A587 /* Cocoa.framework */; }; 4C77E37115B84A240093A587 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 4C77E36F15B84A240093A587 /* InfoPlist.strings */; }; 4C77E37315B84A240093A587 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C77E37215B84A240093A587 /* main.m */; }; @@ -705,8 +705,8 @@ 4C7714AB176C9D4600549F2A /* 99_InfoTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; name = 99_InfoTemplate.pdf; path = Icons/99_InfoTemplate.pdf; sourceTree = ""; }; 4C77547316E55FE800970E02 /* MPInspectorViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPInspectorViewController.h; sourceTree = ""; }; 4C77547416E55FE800970E02 /* MPInspectorViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPInspectorViewController.m; sourceTree = ""; }; - 4C77C83F18E240E000D1C42B /* DDHotKey+Keydata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "DDHotKey+Keydata.h"; sourceTree = ""; }; - 4C77C84018E240E000D1C42B /* DDHotKey+Keydata.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "DDHotKey+Keydata.m"; sourceTree = ""; }; + 4C77C83F18E240E000D1C42B /* DDHotKey+MacPassAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "DDHotKey+MacPassAdditions.h"; sourceTree = ""; }; + 4C77C84018E240E000D1C42B /* DDHotKey+MacPassAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "DDHotKey+MacPassAdditions.m"; sourceTree = ""; }; 4C77E36215B84A240093A587 /* MacPass.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MacPass.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4C77E36615B84A240093A587 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 4C77E36915B84A240093A587 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; @@ -1098,8 +1098,8 @@ 4CC6DB7917D23719002C6091 /* KPKNode+IconImage.m */, 4CEED1C417D7BD0E007180F1 /* NSError+Messages.h */, 4CEED1C517D7BD0E007180F1 /* NSError+Messages.m */, - 4C77C83F18E240E000D1C42B /* DDHotKey+Keydata.h */, - 4C77C84018E240E000D1C42B /* DDHotKey+Keydata.m */, + 4C77C83F18E240E000D1C42B /* DDHotKey+MacPassAdditions.h */, + 4C77C84018E240E000D1C42B /* DDHotKey+MacPassAdditions.m */, ); name = Categories; sourceTree = ""; @@ -2357,7 +2357,7 @@ 4C245B77176E1E3D0086100E /* DDNumber.m in Sources */, 4C245B78176E1E3D0086100E /* DDRange.m in Sources */, 4C94A0721938DDC20040ABAB /* MPDocument+EditingSession.m in Sources */, - 4C77C84118E240E000D1C42B /* DDHotKey+Keydata.m in Sources */, + 4C77C84118E240E000D1C42B /* DDHotKey+MacPassAdditions.m in Sources */, 4C3C4EA618D6FEA100153127 /* TTTJSONTransformer.m in Sources */, 4C89B71019B4B4A300DC0A6A /* MPTreeDelegate.m in Sources */, 4C88C66918D9F8D600F43852 /* MPTemporaryFileStorageCenter.m in Sources */, diff --git a/MacPass/Base.lproj/IntegrationSettings.xib b/MacPass/Base.lproj/IntegrationSettings.xib index 42ed8320..5b1e0cdd 100644 --- a/MacPass/Base.lproj/IntegrationSettings.xib +++ b/MacPass/Base.lproj/IntegrationSettings.xib @@ -1,8 +1,8 @@ - + - - + + @@ -11,25 +11,23 @@ + - + - - - + + + + + + + + @@ -88,7 +90,10 @@ + + + @@ -98,14 +103,12 @@ - - @@ -147,6 +149,7 @@ + diff --git a/MacPass/Base.lproj/PasswordCreatorView.xib b/MacPass/Base.lproj/PasswordCreatorView.xib index 3c5a0fac..6d4d9a43 100644 --- a/MacPass/Base.lproj/PasswordCreatorView.xib +++ b/MacPass/Base.lproj/PasswordCreatorView.xib @@ -53,7 +53,7 @@ - + diff --git a/MacPass/DDHotKey+MacPassAdditions.h b/MacPass/DDHotKey+MacPassAdditions.h index 685661ab..5ae2442c 100644 --- a/MacPass/DDHotKey+MacPassAdditions.h +++ b/MacPass/DDHotKey+MacPassAdditions.h @@ -8,11 +8,26 @@ #import "DDHotKeyCenter.h" -@interface DDHotKey (Keydata) +@interface DDHotKey (MPKeydata) + +@property (readonly, copy) NSData *keyData; + (instancetype)defaultHotKey; + (instancetype)defaultHotKeyWithTask:(DDHotKeyTask)task; -- (NSData *)keyData; + - (instancetype)initWithKeyData:(NSData *)data task:(DDHotKeyTask)task; - (instancetype)initWithKeyData:(NSData *)data; + +@end + +@interface DDHotKey (MPValidation) + +/* + A hotkey is considered valid, if the key contains at least a modifier and a non-modifier key. + For example Control+Alt is no valid hotkey, as it's missing a non-modifier. Control+Escape however is valid. + + @return YES if the hot key is a valid hotkey, NO otherwise + */ +@property (nonatomic, readonly, getter=isValid) BOOL valid; + @end diff --git a/MacPass/DDHotKey+MacPassAdditions.m b/MacPass/DDHotKey+MacPassAdditions.m index 32785d7a..f083aa10 100644 --- a/MacPass/DDHotKey+MacPassAdditions.m +++ b/MacPass/DDHotKey+MacPassAdditions.m @@ -6,10 +6,13 @@ // Copyright (c) 2014 HicknHack Software GmbH. All rights reserved. // -#import "DDHotKey+Keydata.h" +#import "DDHotKey+MacPassAdditions.h" + +#import "MPFlagsHelper.h" + #import -@implementation DDHotKey (Keydata) +@implementation DDHotKey (MPKeydata) + (instancetype)defaultHotKey { return [DDHotKey defaultHotKeyWithTask:nil]; @@ -59,3 +62,34 @@ return YES; } @end + +@implementation DDHotKey (MPValidation) + +- (BOOL)isValid { + NSEventModifierFlags flags = 0; + switch(self.keyCode) { + case kVK_Command: + flags = NSCommandKeyMask; + break; + case kVK_Shift: + case kVK_RightShift: + flags = NSShiftKeyMask; + break; + case kVK_Option: + case kVK_RightOption: + flags = NSAlternateKeyMask; + break; + case kVK_Control: + case kVK_RightControl: + flags = NSControlKeyMask; + break; + } + BOOL missingModifier = self.modifierFlags == 0; + BOOL onlyModifiers = MPIsFlagSetInOptions(flags, self.modifierFlags) || (self.modifierFlags != 0 && flags != 0); + BOOL isInvalid = onlyModifiers || missingModifier; + NSLog(@"%@ valid:%d", self, !isInvalid); + return !isInvalid; +} + +@end + diff --git a/MacPass/MPAutotypeDaemon.m b/MacPass/MPAutotypeDaemon.m index b9bd5412..a17bd2d7 100644 --- a/MacPass/MPAutotypeDaemon.m +++ b/MacPass/MPAutotypeDaemon.m @@ -21,7 +21,8 @@ #import "KPKEntry.h" #import "DDHotKeyCenter.h" -#import "DDHotKey+Keydata.h" +#import "DDHotKey+MacPassAdditions.h" + #import NSString *const kMPWindowTitleKey = @"kMPWindowTitleKey"; diff --git a/MacPass/MPDocumentWindowController.m b/MacPass/MPDocumentWindowController.m index 54352246..1ddd57a6 100644 --- a/MacPass/MPDocumentWindowController.m +++ b/MacPass/MPDocumentWindowController.m @@ -185,7 +185,7 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword); - (void)_didUnlockDatabase:(NSNotification *)notification { [self showEntries]; /* Show password reminders */ - [self _presentPasswordIntervalAlters]; + [self _presentPasswordIntervalAlerts]; } #pragma mark Actions @@ -226,7 +226,7 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword); [weakDocument saveDocument:nil]; } }; - [self _presentPasswordIntervalAlters]; + [self _presentPasswordIntervalAlerts]; return; } /* All set and good ready to save */ @@ -463,7 +463,7 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword); } #pragma mark NSAlert handling -- (void)_presentPasswordIntervalAlters { +- (void)_presentPasswordIntervalAlerts { MPDocument *document = [self document]; if(document.shouldEnforcePasswordChange) { NSAlert *alert = [[NSAlert alloc] init]; diff --git a/MacPass/MPIntegrationSettingsController.h b/MacPass/MPIntegrationSettingsController.h index 1ea4b9a0..75476e82 100644 --- a/MacPass/MPIntegrationSettingsController.h +++ b/MacPass/MPIntegrationSettingsController.h @@ -17,5 +17,6 @@ @property (weak) IBOutlet NSButton *enableGlobalAutotypeCheckbutton; @property (weak) IBOutlet NSButton *enableQuicklookCheckbutton; @property (weak) IBOutlet DDHotKeyTextField *hotKeyTextField; +@property (weak) IBOutlet NSTextField *hotkeyWarningTextField; @end diff --git a/MacPass/MPIntegrationSettingsController.m b/MacPass/MPIntegrationSettingsController.m index 0cc30b86..bc01b5e3 100644 --- a/MacPass/MPIntegrationSettingsController.m +++ b/MacPass/MPIntegrationSettingsController.m @@ -11,7 +11,7 @@ #import "MPIconHelper.h" #import "DDHotKeyCenter.h" -#import "DDHotKey+Keydata.h" +#import "DDHotKey+MacPassAdditions.h" #import "DDHotKeyTextField.h" @interface MPIntegrationSettingsController () @@ -39,7 +39,6 @@ } - (void)awakeFromNib { - self.hotKey = [DDHotKey defaultHotKey]; NSUserDefaultsController *defaultsController = [NSUserDefaultsController sharedUserDefaultsController]; NSString *serverKeyPath = [MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyEnableHttpServer]; NSString *enableGlobalAutotypeKeyPath = [MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyEnableGlobalAutotype]; @@ -49,25 +48,40 @@ [self.enableGlobalAutotypeCheckbutton bind:NSValueBinding toObject:defaultsController withKeyPath:enableGlobalAutotypeKeyPath options:nil]; [self.enableQuicklookCheckbutton bind:NSValueBinding toObject:defaultsController withKeyPath:quicklookKeyPath options:nil]; [self.hotKeyTextField bind:NSEnabledBinding toObject:defaultsController withKeyPath:enableGlobalAutotypeKeyPath options:nil]; - self.hotKeyTextField.hotKey = self.hotKey; self.hotKeyTextField.delegate = self; + + [self _showWarning:NO]; } +- (void)willShowTab { + _hotKey = [[DDHotKey alloc] initWithKeyData:[[NSUserDefaults standardUserDefaults] dataForKey:kMPSettingsKeyGlobalAutotypeKeyDataKey]]; + /* Change any invalid hotkeys to valid ones? */ + self.hotKeyTextField.hotKey = self.hotKey; +} + +#pragma mark - +#pragma mark Properties - (void)setHotKey:(DDHotKey *)hotKey { - static NSData *defaultHotKeyData = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - defaultHotKeyData = [[DDHotKey defaultHotKey] keyData]; - }); - NSData *newData = [hotKey keyData]; - if(![newData isEqualToData:defaultHotKeyData]) { - [[NSUserDefaults standardUserDefaults] setObject:newData forKey:kMPSettingsKeyGlobalAutotypeKeyDataKey]; + if([self.hotKey isEqual:hotKey]) { + return; // Nothing of interest has changed; } _hotKey = hotKey; + [[NSUserDefaults standardUserDefaults] setObject:self.hotKey.keyData forKey:kMPSettingsKeyGlobalAutotypeKeyDataKey]; } +#pragma mark - +#pragma mark NSTextFieldDelegate + - (void)controlTextDidChange:(NSNotification *)obj { - NSLog(@"controlTextDidChange:"); + BOOL validHotKey = self.hotKeyTextField.hotKey.valid; + [self _showWarning:!validHotKey]; + if(validHotKey) { + self.hotKey = self.hotKeyTextField.hotKey; + } +} + +- (void)_showWarning:(BOOL)show { + self.hotkeyWarningTextField.hidden = !show; } @end diff --git a/MacPass/MPSettingsHelper.m b/MacPass/MPSettingsHelper.m index c468f2ee..7946804e 100644 --- a/MacPass/MPSettingsHelper.m +++ b/MacPass/MPSettingsHelper.m @@ -9,6 +9,7 @@ #import "MPSettingsHelper.h" #import "NSString+MPPasswordCreation.h" #import "MPEntryViewController.h" // Sort descriptors +#import "DDHotKey+MacPassAdditions.h" // Default hotkey; NSString *const kMPSettingsKeyPasteboardClearTimeout = @"ClipboardClearTimeout"; NSString *const kMPSettingsKeyClearPasteboardOnQuit = @"ClearClipboardOnQuit"; @@ -102,6 +103,7 @@ NSString *const kMPDeprecatedSettingsKeyEntrySearchFilterMode = @"En kMPSettingsKeyRememberKeyFilesForDatabases: @NO, kMPSettingsKeySendCommandForControlKey: @YES, kMPSettingsKeyEnableGlobalAutotype: @NO, + kMPSettingsKeyGlobalAutotypeKeyDataKey: [[DDHotKey defaultHotKey] keyData], kMPSettingsKeyDefaultGlobalAutotypeSequence: @"{USERNAME}{TAB}{PASSWORD}{ENTER}", kMPSettingsKeyEnableQuicklookPreview: @NO, kMPSettingsKeyCopyGeneratedPasswordToClipboard: @NO, diff --git a/MacPass/MPSettingsTab.h b/MacPass/MPSettingsTab.h index c897ec4f..247c513f 100644 --- a/MacPass/MPSettingsTab.h +++ b/MacPass/MPSettingsTab.h @@ -21,8 +21,8 @@ - (NSString *)label; - (NSImage *)image; /* Called when the tab is about to be selected and displayed */ -- (void)willSelectTab; +- (void)willShowTab; /* Called whent the tab was selected and is being displayed */ -- (void)didSelectTab; +- (void)didShowTab; @end diff --git a/MacPass/MPSettingsWindowController.m b/MacPass/MPSettingsWindowController.m index db26d8e0..9c91919f 100644 --- a/MacPass/MPSettingsWindowController.m +++ b/MacPass/MPSettingsWindowController.m @@ -63,9 +63,6 @@ NSLog(@"Warning. Unknow settingscontroller for identifier: %@. Did you miss to add the controller?", identifier); return; } - if([tab respondsToSelector:@selector(willSelectTab)]) { - [tab willSelectTab]; - } [self.toolbar setSelectedItemIdentifier:identifier]; if([tab respondsToSelector:@selector(label)]) { [[self window] setTitle:[tab label]]; @@ -73,7 +70,11 @@ else { [[self window] setTitle:[tab identifier]]; } + /* Access the view before calling the willShoTab to make sure the view is fully loaded */ NSView *tabView = [(NSViewController *)tab view]; + if([tab respondsToSelector:@selector(willShowTab)]) { + [tab willShowTab]; + } NSView *contentView = [[self window] contentView]; if( [[contentView subviews] count] == 1) { [[contentView subviews][0] removeFromSuperview]; @@ -90,8 +91,8 @@ views:NSDictionaryOfVariableBindings(tabView)]]; [contentView layoutSubtreeIfNeeded]; - if([tab respondsToSelector:@selector(didSelectTab)]) { - [tab didSelectTab]; + if([tab respondsToSelector:@selector(didShowTab)]) { + [tab didShowTab]; } [[self window] makeKeyAndOrderFront:[self window]]; } diff --git a/MacPass/MPWorkflowSettingsController.m b/MacPass/MPWorkflowSettingsController.m index cdb79cc2..b28c555d 100644 --- a/MacPass/MPWorkflowSettingsController.m +++ b/MacPass/MPWorkflowSettingsController.m @@ -42,7 +42,7 @@ return NSLocalizedString(@"WORKFLOW_SETTINGS", ""); } -- (void)willSelectTab { +- (void)willShowTab { [self _updateBrowserSelection]; } diff --git a/MacPass/MacPass-Info.plist b/MacPass/MacPass-Info.plist index 0fe95c71..edb626d6 100644 --- a/MacPass/MacPass-Info.plist +++ b/MacPass/MacPass-Info.plist @@ -54,7 +54,7 @@ CFBundleSignature ???? CFBundleVersion - 2536 + 2537 LSMinimumSystemVersion ${MACOSX_DEPLOYMENT_TARGET} NSHumanReadableCopyright