diff --git a/HNHUi b/HNHUi index b915d2b1..05245dc6 160000 --- a/HNHUi +++ b/HNHUi @@ -1 +1 @@ -Subproject commit b915d2b15089d353cfed5cd38ea0f03b1bd24122 +Subproject commit 05245dc6a68661199b1c43f677a600a7d519c607 diff --git a/MacPass.xcodeproj/project.pbxproj b/MacPass.xcodeproj/project.pbxproj index 78c85d63..99906bce 100644 --- a/MacPass.xcodeproj/project.pbxproj +++ b/MacPass.xcodeproj/project.pbxproj @@ -102,7 +102,6 @@ 4C46E09E17673A0A00DA62E8 /* HNHShadowBox.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C46E09D17673A0A00DA62E8 /* HNHShadowBox.m */; }; 4C473A7F18AFD6340073FD2E /* KPKTestReference.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C473A7E18AFD6340073FD2E /* KPKTestReference.m */; }; 4C473A8718AFD85B0073FD2E /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C473A8518AFD7250073FD2E /* XCTest.framework */; }; - 4C48A56218BE932100278A2D /* HNHCommon.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C48A56118BE932100278A2D /* HNHCommon.m */; }; 4C4A100F176286FD00BBF2CA /* MPTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C4A100E176286FD00BBF2CA /* MPTableView.m */; }; 4C4B7EE917A45EC6000234C7 /* MPDatePickingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C4B7EE717A45EC5000234C7 /* MPDatePickingViewController.m */; }; 4C4B7EEA17A45EC6000234C7 /* DatePickingView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C4B7EE817A45EC5000234C7 /* DatePickingView.xib */; }; @@ -521,7 +520,6 @@ 4C473A7E18AFD6340073FD2E /* KPKTestReference.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KPKTestReference.m; sourceTree = ""; }; 4C473A8518AFD7250073FD2E /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 4C48A56018BE932100278A2D /* HNHCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HNHCommon.h; sourceTree = ""; }; - 4C48A56118BE932100278A2D /* HNHCommon.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HNHCommon.m; 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 = ""; }; 4C4B7EE617A45EC5000234C7 /* MPDatePickingViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPDatePickingViewController.h; sourceTree = ""; }; @@ -1593,7 +1591,6 @@ 4CFDDDE7185E92A600A9E7F1 /* HNHTextView.h */, 4CFDDDE8185E92A600A9E7F1 /* HNHTextView.m */, 4C48A56018BE932100278A2D /* HNHCommon.h */, - 4C48A56118BE932100278A2D /* HNHCommon.m */, ); path = HNHUi; sourceTree = ""; @@ -2123,7 +2120,6 @@ 4C888C9316EB6F5E003D34A1 /* MPToolbarItem.m in Sources */, 4C888C9716EB754B003D34A1 /* MPActionHelper.m in Sources */, 4C811C8316ECD06E00C4BAC6 /* MPKeyfilePathControlDelegate.m in Sources */, - 4C48A56218BE932100278A2D /* HNHCommon.m in Sources */, 4CE39ABF16ECE34A000FE29D /* MPIconSelectViewController.m in Sources */, 4CE39AC416ECE4F7000FE29D /* MPPopupImageView.m in Sources */, 4C46B88517063A070046109A /* NSString+MPPasswordCreation.m in Sources */, diff --git a/MacPass/MPActionHelper.h b/MacPass/MPActionHelper.h index b40a7d8e..fb79d526 100644 --- a/MacPass/MPActionHelper.h +++ b/MacPass/MPActionHelper.h @@ -12,6 +12,8 @@ typedef NS_ENUM(NSUInteger, MPActionType) { MPUnkownAction, // Neutral element to be used for returns MPActionAddEntry, // Add an new entry MPActionAddGroup, // Add a new group + MPActionCloneEntry, // Simply clone an entry (inlcuding history) + MPActionCloneEntryWithOptions, // Request user inptu what clone MPActionDelete, // Delete entry or group MPActionCopyUsername, // copy username to pasteboard MPActionCopyPassword, // copy password to pasteboard diff --git a/MacPass/MPActionHelper.m b/MacPass/MPActionHelper.m index a58e4531..cb076c2b 100644 --- a/MacPass/MPActionHelper.m +++ b/MacPass/MPActionHelper.m @@ -15,21 +15,22 @@ static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ actionDict = @{ - @(MPActionAddEntry) : @"createEntry:", - @(MPActionAddGroup) : @"createGroup:", - @(MPActionCopyPassword) : @"copyPassword:", - @(MPActionCopyURL) : @"copyURL:", - @(MPActionCopyUsername) : @"copyUsername:", - @(MPActionDelete) : @"delete:", - @(MPActionEditPassword) : @"editPassword:", - @(MPActionOpenURL) : @"openURL:", - @(MPActionToggleInspector) : @"toggleInspector:", - @(MPActionLock) : @"lock:", - @(MPActionEmptyTrash) : @"emptyTrash:", - @(MPActionDatabaseSettings) : @"showDatabaseSettings:", - @(MPActionEditTemplateGroup) : @"editTemplateGroup:", - @(MPActionExportXML) : @"exportAsXML", - @(MPActionImportXML) : @"importFromXMl", + @(MPActionAddEntry): @"createEntry:", + @(MPActionAddGroup): @"createGroup:", + @(MPActionCloneEntry): @"cloneEntry:", + @(MPActionCopyPassword): @"copyPassword:", + @(MPActionCopyURL): @"copyURL:", + @(MPActionCopyUsername): @"copyUsername:", + @(MPActionDelete): @"delete:", + @(MPActionEditPassword): @"editPassword:", + @(MPActionOpenURL): @"openURL:", + @(MPActionToggleInspector): @"toggleInspector:", + @(MPActionLock): @"lock:", + @(MPActionEmptyTrash): @"emptyTrash:", + @(MPActionDatabaseSettings): @"showDatabaseSettings:", + @(MPActionEditTemplateGroup): @"editTemplateGroup:", + @(MPActionExportXML): @"exportAsXML", + @(MPActionImportXML): @"importFromXMl", }; }); return actionDict; diff --git a/MacPass/MPContextBarViewController.m b/MacPass/MPContextBarViewController.m index 2c877a63..ee2bb014 100644 --- a/MacPass/MPContextBarViewController.m +++ b/MacPass/MPContextBarViewController.m @@ -44,6 +44,7 @@ typedef NS_ENUM(NSUInteger, MPContextTab) { @implementation MPContextBarViewController +#pragma mark Livecycle - (instancetype)init { self = [self initWithNibName:@"ContextBar" bundle:nil]; return self; @@ -76,7 +77,13 @@ typedef NS_ENUM(NSUInteger, MPContextTab) { [self _updateFilterButtons]; } -#pragma mark Properties +#pragma mark MPDocument Notifications +- (void)registerNotificationsForDocument:(MPDocument *)document { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_updateFilterButtons) name:MPDocumentDidChangeSearchFlags object:document]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_didEnterSearch:) name:MPDocumentDidEnterSearchNotification object:document]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_didEnterHistory:) name:MPDocumentDidEnterHistoryNotification object:document]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_didChangeCurrentItem:) name:MPDocumentCurrentItemChangedNotification object:document]; +} - (void)_didEnterSearch:(NSNotification *)notification { /* Select text if already visible */ @@ -89,15 +96,13 @@ typedef NS_ENUM(NSUInteger, MPContextTab) { [self _updateBindings]; } -- (void)_showTrash { - self.activeTab = MPContextTabTrash; - [self _updateBindings]; -} - -- (void)registerNotificationsForDocument:(MPDocument *)document { - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_updateFilterButtons) name:MPDocumentDidChangeSearchFlags object:document]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_didEnterSearch:) name:MPDocumentDidEnterSearchNotification object:document]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_didEnterHistory:) name:MPDocumentDidEnterHistoryNotification object:document]; +- (void)_didChangeCurrentItem:(NSNotification *)notification { + MPDocument *document = [notification object]; + BOOL showTrash = document.useTrash && (document.selectedGroup == document.trash || [document isItemTrashed:document.selectedItem]); + if(showTrash) { + self.activeTab = MPContextTabTrash; + [self _updateBindings]; + } } /* @@ -109,6 +114,7 @@ typedef NS_ENUM(NSUInteger, MPContextTab) { } */ + #pragma mark UI Helper - (void)_updateBindings { // only the entry view has to be bound, the rest not diff --git a/MacPass/MPContextMenuHelper.m b/MacPass/MPContextMenuHelper.m index 3dd0bd61..4973cf75 100644 --- a/MacPass/MPContextMenuHelper.m +++ b/MacPass/MPContextMenuHelper.m @@ -9,13 +9,22 @@ #import "MPContextMenuHelper.h" #import "MPActionHelper.h" +#import "MPFlagsHelper.h" + +static void MPContextmenuHelperBeginSection(NSMutableArray *items) { + if([items count] > 0) { + [items addObject:[NSMenuItem separatorItem]]; + } +} + @implementation MPContextMenuHelper + (NSArray *)contextMenuItemsWithItems:(MPContextMenuItemsFlags)flags { - BOOL insertCreate = (0 != (flags & MPContextMenuCreate)); - BOOL insertDelete = (0 != (flags & MPContextMenuDelete)); - BOOL insertCopy = (0 != (flags & MPContextMenuCopy)); - BOOL insertTrash = (0 != (flags & MPContextMenuTrash)); + + BOOL const insertCreate = MPTestFlagInOptions(MPContextMenuCreate, flags); + BOOL const insertDelete = MPTestFlagInOptions(MPContextMenuDelete, flags); + BOOL const insertCopy = MPTestFlagInOptions(MPContextMenuCopy, flags); + BOOL const insertTrash = MPTestFlagInOptions(MPContextMenuTrash, flags); NSMutableArray *items = [NSMutableArray arrayWithCapacity:10]; if(insertCreate) { @@ -30,27 +39,27 @@ [items addObjectsFromArray:@[ newGroup, newEntry ]]; } if(insertDelete || insertTrash) { - [self _beginSection:items]; + MPContextmenuHelperBeginSection(items); if(insertDelete) { NSMenuItem *delete = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"DELETE", @"") action:[MPActionHelper actionOfType:MPActionDelete] keyEquivalent:@""]; [items addObject:delete]; - + } if(insertTrash) { NSMenuItem *emptyTrash = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"EMPTY_TRASH", @"") - action:[MPActionHelper actionOfType:MPActionEmptyTrash] - keyEquivalent:@""]; + action:[MPActionHelper actionOfType:MPActionEmptyTrash] + keyEquivalent:@""]; [emptyTrash setKeyEquivalentModifierMask:(NSShiftKeyMask | NSCommandKeyMask)]; unichar backSpace = NSBackspaceCharacter; [emptyTrash setKeyEquivalent:[NSString stringWithCharacters:&backSpace length:1]]; [items addObject:emptyTrash]; - + } } if(insertCopy) { - [self _beginSection:items]; + MPContextmenuHelperBeginSection(items); NSMenuItem *copyUsername = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"COPY_USERNAME", @"") action:[MPActionHelper actionOfType:MPActionCopyUsername] keyEquivalent:@"C"]; @@ -79,10 +88,4 @@ return items; } -+ (void)_beginSection:(NSMutableArray *)items { - if([items count] > 0) { - [items addObject:[NSMenuItem separatorItem]]; - } -} - @end diff --git a/MacPass/MPEntryViewController.m b/MacPass/MPEntryViewController.m index 6cc30e79..ba9121ea 100644 --- a/MacPass/MPEntryViewController.m +++ b/MacPass/MPEntryViewController.m @@ -206,7 +206,7 @@ NSString *const _MPTAbleSecurCellView = @"PasswordCell"; [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(_updateContextBar) + selector:@selector(_didExitSearch:) name:MPDocumentDidExitSearchNotification object:document]; @@ -355,8 +355,8 @@ NSString *const _MPTAbleSecurCellView = @"PasswordCell"; }); } -#pragma mark MPContextBarDelegate -- (void)contextBarDidExitFilter { +#pragma mark NSDocument+Search Notifications +- (void)_didExitSearch:(NSNotification *)notification { [[self.entryTable tableColumnWithIdentifier:MPEntryTableParentColumnIdentifier] setHidden:YES]; MPDocument *document = [[self windowController] document]; document.selectedItem = document.selectedGroup; @@ -368,16 +368,12 @@ NSString *const _MPTAbleSecurCellView = @"PasswordCell"; } #pragma mark ContextBar -- (void)_showTrashBar { - [self _showContextBar]; -} - - (void)_updateContextBar { MPDocument *document = [[self windowController] document]; if(!document.hasSearch) { BOOL showTrash = document.useTrash && (document.selectedGroup == document.trash || [document isItemTrashed:document.selectedItem]); if(showTrash) { - [self _showTrashBar]; + [self _showContextBar]; } else { [self _hideContextBar];