From cb180139642d192d5269a87195b22b3990bc7702 Mon Sep 17 00:00:00 2001 From: michael starke Date: Wed, 26 Jun 2013 01:19:44 +0200 Subject: [PATCH] Fixed #23 Revert to saved now working Fixed KVO issues with active items not being updated on tree reset Fixed #6 Moved all move/delete/create functions into MPDocument Intigrated OutlineViewDelegate into OutlineViewController --- MacPass.xcodeproj/project.pbxproj | 6 -- MacPass/KdbGroup+Undo.h | 7 -- MacPass/KdbGroup+Undo.m | 44 ----------- MacPass/MPActionHelper.m | 2 +- MacPass/MPDocument.h | 15 +++- MacPass/MPDocument.m | 76 ++++++++++++++++--- MacPass/MPDocumentWindowController.h | 3 +- MacPass/MPDocumentWindowController.m | 31 +++++--- MacPass/MPEntryViewController.h | 2 +- MacPass/MPEntryViewController.m | 39 +++++----- MacPass/MPInspectorViewController.m | 2 - MacPass/MPOutlineViewController.h | 9 ++- MacPass/MPOutlineViewController.m | 106 +++++++++++++++++++++------ MacPass/MPOutlineViewDelegate.h | 19 ----- MacPass/MPOutlineViewDelegate.m | 81 -------------------- MacPass/MacPass-Info.plist | 2 +- MiniKeePassLib | 2 +- 17 files changed, 217 insertions(+), 229 deletions(-) delete mode 100644 MacPass/MPOutlineViewDelegate.h delete mode 100644 MacPass/MPOutlineViewDelegate.m diff --git a/MacPass.xcodeproj/project.pbxproj b/MacPass.xcodeproj/project.pbxproj index 334b42f0..18c9f308 100644 --- a/MacPass.xcodeproj/project.pbxproj +++ b/MacPass.xcodeproj/project.pbxproj @@ -154,7 +154,6 @@ 4CC299FF176F99E50050C939 /* MPRequestHandlerService.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CC299FE176F99E50050C939 /* MPRequestHandlerService.m */; }; 4CC29A02176F9D140050C939 /* MPTestAssociateRequestHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CC29A01176F9D140050C939 /* MPTestAssociateRequestHandler.m */; }; 4CC3AABD175F4983003EF01B /* HNHRoundedTextFieldCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CC3AAB9175F4983003EF01B /* HNHRoundedTextFieldCell.m */; }; - 4CC6259115BA1C99002F5B11 /* MPOutlineViewDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CC6259015BA1C99002F5B11 /* MPOutlineViewDelegate.m */; }; 4CD78ABC16D155FF00768A1D /* 07_NotepadTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4CD78AB716D155FF00768A1D /* 07_NotepadTemplate.pdf */; }; 4CD78ABD16D155FF00768A1D /* 08_SocketTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4CD78AB816D155FF00768A1D /* 08_SocketTemplate.pdf */; }; 4CD78ABE16D155FF00768A1D /* 09_IdentityTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4CD78AB916D155FF00768A1D /* 09_IdentityTemplate.pdf */; }; @@ -474,8 +473,6 @@ 4CC29A01176F9D140050C939 /* MPTestAssociateRequestHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPTestAssociateRequestHandler.m; sourceTree = ""; }; 4CC3AAB8175F4983003EF01B /* HNHRoundedTextFieldCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HNHRoundedTextFieldCell.h; sourceTree = ""; }; 4CC3AAB9175F4983003EF01B /* HNHRoundedTextFieldCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HNHRoundedTextFieldCell.m; sourceTree = ""; }; - 4CC6258F15BA1C99002F5B11 /* MPOutlineViewDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPOutlineViewDelegate.h; sourceTree = ""; }; - 4CC6259015BA1C99002F5B11 /* MPOutlineViewDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPOutlineViewDelegate.m; sourceTree = ""; }; 4CD78AB716D155FF00768A1D /* 07_NotepadTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 07_NotepadTemplate.pdf; sourceTree = ""; }; 4CD78AB816D155FF00768A1D /* 08_SocketTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 08_SocketTemplate.pdf; sourceTree = ""; }; 4CD78AB916D155FF00768A1D /* 09_IdentityTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 09_IdentityTemplate.pdf; sourceTree = ""; }; @@ -764,8 +761,6 @@ children = ( 4C77E37815B84A240093A587 /* MPAppDelegate.h */, 4C77E37915B84A240093A587 /* MPAppDelegate.m */, - 4CC6258F15BA1C99002F5B11 /* MPOutlineViewDelegate.h */, - 4CC6259015BA1C99002F5B11 /* MPOutlineViewDelegate.m */, 4C3BD51316D276F800389F1F /* MPToolbarDelegate.h */, 4C3BD51416D276F800389F1F /* MPToolbarDelegate.m */, 4C811C8116ECD06E00C4BAC6 /* MPKeyfilePathControlDelegate.h */, @@ -1298,7 +1293,6 @@ 4CAD747E15B887FD00104512 /* DDXMLElement.m in Sources */, 4CAD747F15B887FD00104512 /* DDXMLNode.m in Sources */, 4C37A84015B8B474005EF8EE /* MPOutlineDataSource.m in Sources */, - 4CC6259115BA1C99002F5B11 /* MPOutlineViewDelegate.m in Sources */, 4CA0B2F915BCAF6700654E32 /* MPGeneralSettingsController.m in Sources */, 4CA0B2FC15BCAF8600654E32 /* MPSettingsWindowController.m in Sources */, 4C83814215BF4677001AE468 /* MPDocumentWindowController.m in Sources */, diff --git a/MacPass/KdbGroup+Undo.h b/MacPass/KdbGroup+Undo.h index 0ba98ac9..2ba766ec 100644 --- a/MacPass/KdbGroup+Undo.h +++ b/MacPass/KdbGroup+Undo.h @@ -17,11 +17,4 @@ APPKIT_EXTERN NSString *const MPGroupNameUndoableKey; - (NSString *)nameUndoable; - (void)setNameUndoable:(NSString *)newName; -- (void)addEntryUndoable:(KdbEntry *)entry; -- (void)addGroupUndoable:(KdbGroup *)group; -- (void)removeGroupUndoable:(KdbGroup *)group; -- (void)removeEntryUndoable:(KdbEntry *)entry; - -- (void)moveToGroupUndoable:(KdbGroup *)group; - @end diff --git a/MacPass/KdbGroup+Undo.m b/MacPass/KdbGroup+Undo.m index e26f9c78..9bb5ddaf 100644 --- a/MacPass/KdbGroup+Undo.m +++ b/MacPass/KdbGroup+Undo.m @@ -27,48 +27,4 @@ NSString *const MPGroupNameUndoableKey = @"nameUndoable"; self.name = newName; } -- (void)addEntryUndoable:(KdbEntry *)entry { - [[self undoManager] registerUndoWithTarget:self selector:@selector(removeEntryUndoable:) object:entry]; - [[self undoManager] setActionName:NSLocalizedString(@"UNDO_ADD_ENTRY", "Undo adding of entry")]; - [self insertObject:entry inEntriesAtIndex:[_entries count]]; -} - -- (void)addGroupUndoable:(KdbGroup *)group { - [[self undoManager] registerUndoWithTarget:self selector:@selector(removeGroupUndoable:) object:group]; - [[self undoManager] setActionName:NSLocalizedString(@"UNDO_ADD_GROUP", @"Create Group Undo")]; - [self insertObject:group inGroupsAtIndex:[_groups count]]; -} - -- (void)removeEntryUndoable:(KdbEntry *)entry { - NSInteger index = [_entries indexOfObject:entry]; - if(NSNotFound == index) { - return; // No object found; - } - [[self undoManager] registerUndoWithTarget:self selector:@selector(addEntryUndoable:) object:entry]; - [[self undoManager] setActionName:NSLocalizedString(@"UNDO_DELETE_ENTRY", "Undo deleting of entry")]; - [self removeObjectFromEntriesAtIndex:index]; -} - -- (void)removeGroupUndoable:(KdbGroup *)group { - NSInteger index = [group.parent.groups indexOfObject:group]; - if(NSNotFound == index) { - return; // No object found - } - [[self undoManager] registerUndoWithTarget:self selector:@selector(addGroupUndoable:) object:group]; - [[self undoManager] setActionName:NSLocalizedString(@"UNDO_DELETE_GROUP", @"Create Group Undo")]; - [group.parent removeObjectFromGroupsAtIndex:index]; -} - -- (void)moveToGroupUndoable:(KdbGroup *)group { - NSInteger index = [self.parent.groups indexOfObject:self]; - if(NSNotFound == index) { - return; // No object found - } - [[self undoManager] registerUndoWithTarget:self selector:@selector(moveToGroupUndoable:) object:self.parent]; - [[self undoManager] setActionName:NSLocalizedString(@"UNDO_MOVE_GROUP", @"Move Group Undo")]; - [self.parent removeObjectFromGroupsAtIndex:index]; - [group insertObject:self inGroupsAtIndex:[group.groups count]]; -} - - @end diff --git a/MacPass/MPActionHelper.m b/MacPass/MPActionHelper.m index c181ea20..24c55453 100644 --- a/MacPass/MPActionHelper.m +++ b/MacPass/MPActionHelper.m @@ -20,7 +20,7 @@ @(MPActionCopyPassword) : @"copyPassword:", @(MPActionCopyURL) : @"copyURL:", @(MPActionCopyUsername) : @"copyUsername:", - @(MPActionDelete) : @"deleteEntry:", + @(MPActionDelete) : @"deleteNode:", @(MPActionEdit) : @"editEntry:", @(MPActionOpenURL) : @"openURL:", @(MPActionToggleInspector) : @"toggleInspector:", diff --git a/MacPass/MPDocument.h b/MacPass/MPDocument.h index 90711f1f..0d458983 100644 --- a/MacPass/MPDocument.h +++ b/MacPass/MPDocument.h @@ -14,6 +14,7 @@ APPKIT_EXTERN NSString *const MPDocumentDidAddGroupNotification; APPKIT_EXTERN NSString *const MPDocumentWillDelteGroupNotification; APPKIT_EXTERN NSString *const MPDocumentDidAddEntryNotification; APPKIT_EXTERN NSString *const MPDocumentWillDeleteEntryNotification; +APPKIT_EXTERN NSString *const MPDocumentDidRevertNotifiation; APPKIT_EXTERN NSString *const MPDocumentEntryKey; APPKIT_EXTERN NSString *const MPDocumentGroupKey; @@ -34,7 +35,7 @@ APPKIT_EXTERN NSString *const MPDocumentGroupKey; /* true, if document is loaded and decrypted (tree is loaded) */ @property (assign, readonly, getter = isDecrypted) BOOL decrypted; @property (retain, readonly) KdbTree *tree; -@property (assign, readonly) KdbGroup *root; +@property (assign, readonly, nonatomic) KdbGroup *root; @property (nonatomic,retain) NSString *password; @property (nonatomic, retain) NSURL *key; @property (assign, readonly) MPDatabaseVersion version; @@ -59,11 +60,19 @@ APPKIT_EXTERN NSString *const MPDocumentGroupKey; - (KdbEntry *)createEntry:(KdbGroup *)parent; /* - Undoable movement of object + All non-setter undoable actions */ + - (void)moveGroup:(KdbGroup *)group toGroup:(KdbGroup *)target index:(NSInteger)index; - (BOOL)group:(KdbGroup *)group isMoveableToGroup:(KdbGroup *)target; - - (void)moveEntry:(KdbEntry *)entry toGroup:(KdbGroup *)target index:(NSInteger)index; +- (void)group:(KdbGroup *)group addEntry:(KdbEntry *)entry; +- (void)group:(KdbGroup *)group addGroup:(KdbGroup *)aGroup; +- (void)group:(KdbGroup *)group removeEntry:(KdbEntry *)entry; +- (void)group:(KdbGroup *)group removeGroup:(KdbGroup *)aGroup; + + + + @end diff --git a/MacPass/MPDocument.m b/MacPass/MPDocument.m index 15ff6340..8882f8b8 100644 --- a/MacPass/MPDocument.m +++ b/MacPass/MPDocument.m @@ -20,19 +20,21 @@ #import "Kdb3Tree+NewTree.h" #import "Kdb4Tree+NewTree.h" -NSString *const MPDocumentDidAddGroupNotification = @"MPDocumentDidAddGroupNotification"; -NSString *const MPDocumentWillDelteGroupNotification = @"MPDocumentDidDelteGroupNotification"; -NSString *const MPDocumentDidAddEntryNotification = @"MPDocumentDidAddEntryNotification"; -NSString *const MPDocumentWillDeleteEntryNotification = @"MPDocumentDidDeleteEntryNotification"; +NSString *const MPDocumentDidAddGroupNotification = @"com.hicknhack.macpass.MPDocumentDidAddGroupNotification"; +NSString *const MPDocumentWillDelteGroupNotification = @"com.hicknhack.macpass.MPDocumentDidDelteGroupNotification"; +NSString *const MPDocumentDidAddEntryNotification = @"com.hicknhack.macpass.MPDocumentDidAddEntryNotification"; +NSString *const MPDocumentWillDeleteEntryNotification = @"com.hicknhack.macpass.MPDocumentDidDeleteEntryNotification"; +NSString *const MPDocumentDidRevertNotifiation = @"com.hicknhack.macpass.MPDocumentDidRevertNotifiation"; -NSString *const MPDocumentEntryKey = @"MPDocumentEntryKey"; -NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey"; +NSString *const MPDocumentEntryKey = @"MPDocumentEntryKey"; +NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey"; @interface MPDocument () @property (assign, nonatomic) BOOL secured; @property (retain) KdbTree *tree; +@property (assign, nonatomic) KdbGroup *root; @property (nonatomic, readonly) KdbPassword *passwordHash; @property (assign) MPDatabaseVersion version; @property (assign) BOOL decrypted; @@ -94,6 +96,15 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey"; return YES; } +- (BOOL)revertToContentsOfURL:(NSURL *)absoluteURL ofType:(NSString *)typeName error:(NSError **)outError { + [self _resetTree]; + if([self readFromURL:absoluteURL ofType:typeName error:outError]) { + [[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidRevertNotifiation object:self]; + return YES; + } + return NO; +} + - (BOOL)isEntireFileLoaded { return _decrypted; } @@ -115,6 +126,8 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey"; else if( [self.tree isKindOfClass:[Kdb3Tree class]]) { self.version = MPDatabaseVersion3; } + /* reset the root to inform KVO listeners */ + self.root = self.tree.root; _decrypted = YES; return YES; } @@ -147,7 +160,13 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey"; #pragma mark Data Accesors - (KdbGroup *)root { - return [self.tree root]; + return self.tree.root; +} + +- (void)setRoot:(KdbGroup *)root { + if(self.root != root) { + self.tree.root = root; + } } - (KdbEntry *)findEntry:(UUID *)uuid { @@ -172,7 +191,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey"; - (KdbEntry *)createEntry:(KdbGroup *)parent { KdbEntry *newEntry = [self.tree createEntry:parent]; newEntry.title = NSLocalizedString(@"DEFAULT_ENTRY_TITLE", @"Title for a newly created entry"); - [parent addEntryUndoable:newEntry]; + [self group:parent addEntry:newEntry]; NSDictionary *userInfo = @{ MPDocumentEntryKey : newEntry }; [[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidAddEntryNotification object:self userInfo:userInfo]; return newEntry; @@ -181,7 +200,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey"; - (KdbGroup *)createGroup:(KdbGroup *)parent { KdbGroup *newGroup = [self.tree createGroup:parent]; newGroup.name = NSLocalizedString(@"DEFAULT_GROUP_NAME", @"Title for a newly created group"); - [parent addGroupUndoable:newGroup]; + [self group:parent addGroup:newGroup]; NSDictionary *userInfo = @{ MPDocumentGroupKey : newGroup }; [[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidAddGroupNotification object:self userInfo:userInfo]; return newGroup; @@ -231,4 +250,43 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey"; [target insertObject:entry inEntriesAtIndex:index]; } +- (void)group:(KdbGroup *)group addEntry:(KdbEntry *)entry { + [[[self undoManager] prepareWithInvocationTarget:self] group:group removeEntry:entry]; + [[self undoManager] setActionName:NSLocalizedString(@"UNDO_ADD_ENTRY", "Undo adding of entry")]; + [group insertObject:entry inEntriesAtIndex:[group.entries count]]; +} + +- (void)group:(KdbGroup *)group addGroup:(KdbGroup *)aGroup { + [[[self undoManager] prepareWithInvocationTarget:self] group:group removeGroup:aGroup]; + [[self undoManager] setActionName:NSLocalizedString(@"UNDO_ADD_GROUP", @"Create Group Undo")]; + [group insertObject:aGroup inGroupsAtIndex:[group.groups count]]; +} + +- (void)group:(KdbGroup *)group removeEntry:(KdbEntry *)entry { + NSInteger index = [group.entries indexOfObject:entry]; + if(NSNotFound == index) { + return; // No object found; + } + [[[self undoManager] prepareWithInvocationTarget:self] group:group addEntry:entry]; + [[self undoManager] setActionName:NSLocalizedString(@"UNDO_DELETE_ENTRY", "Undo deleting of entry")]; + [group removeObjectFromEntriesAtIndex:index]; +} + +- (void)group:(KdbGroup *)group removeGroup:(KdbGroup *)aGroup { + NSInteger index = [group.groups indexOfObject:aGroup]; + if(NSNotFound == index) { + return; // No object found + } + [[[self undoManager] prepareWithInvocationTarget:self] group:group addGroup:aGroup]; + [[self undoManager] setActionName:NSLocalizedString(@"UNDO_DELETE_GROUP", @"Create Group Undo")]; + [group removeObjectFromGroupsAtIndex:index]; +} + +#pragma mark Private +- (void)_resetTree { + // Reset both values to inform any KVO listener + self.root = nil; + self.tree = nil; +} + @end diff --git a/MacPass/MPDocumentWindowController.h b/MacPass/MPDocumentWindowController.h index a6938ea1..7a59c61d 100644 --- a/MacPass/MPDocumentWindowController.h +++ b/MacPass/MPDocumentWindowController.h @@ -32,7 +32,8 @@ APPKIT_EXTERN NSString *const MPCurrentItemChangedNotification; /* Holds the current item. That is either a KdbGroup or a KdbEntry */ @property (readonly, assign) id currentItem; - +@property (readonly, assign) KdbGroup *currentGroup; +@property (readonly, assign) KdbEntry *currentEntry; - (void)showEntries; - (void)showPasswordInput; diff --git a/MacPass/MPDocumentWindowController.m b/MacPass/MPDocumentWindowController.m index f43e75e1..cd7c49e5 100644 --- a/MacPass/MPDocumentWindowController.m +++ b/MacPass/MPDocumentWindowController.m @@ -13,7 +13,6 @@ #import "MPPasswordEditViewController.h" #import "MPToolbarDelegate.h" #import "MPOutlineViewController.h" -#import "MPOutlineViewDelegate.h" #import "MPInspectorViewController.h" #import "MPAppDelegate.h" #import "MPActionHelper.h" @@ -29,6 +28,8 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur @property (retain) NSToolbar *toolbar; @property (assign) id currentItem; +@property (assign) KdbGroup *currentGroup; +@property (assign) KdbEntry *currentEntry; @property (retain) MPPasswordInputController *passwordInputController; @property (retain) MPPasswordEditViewController *passwordEditController; @@ -54,14 +55,15 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur _inspectorViewController = [[MPInspectorViewController alloc] init]; _currentItem = nil; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_updateCurrentItem:) name:MPOutlineViewDidChangeGroupSelection object:_outlineViewController.outlineDelegate]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_updateCurrentItem:) name:MPOutlineViewDidChangeGroupSelection object:_outlineViewController]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_updateCurrentItem:) name:MPDidChangeSelectedEntryNotification object:_entryViewController]; - } return self; } - (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [_toolbar release]; [_passwordInputController release]; @@ -76,8 +78,10 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur } #pragma mark View Handling -- (void)windowDidLoad -{ +- (void)windowDidLoad { + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_didRevertDocument:) name:MPDocumentDidRevertNotifiation object:[self document]]; + [_entryViewController setupNotifications:self]; [_inspectorViewController setupNotifications:self]; [_outlineViewController setupNotifications:self]; @@ -143,11 +147,15 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur [self.window makeFirstResponder:[viewController reconmendedFirstResponder]]; } -#pragma mark Resonder handling +#pragma mark Notification handling - (void)_updateCurrentItem:(NSNotification *)notification { id sender = [notification object]; - if( sender == _outlineViewController.outlineView || sender == _outlineViewController.outlineDelegate ) { - self.currentItem = _outlineViewController.outlineDelegate.selectedGroup; + + self.currentGroup = _outlineViewController.selectedGroup; + self.currentEntry = _entryViewController.selectedEntry; + + if( sender == _outlineViewController.outlineView || sender == _outlineViewController ) { + self.currentItem = _outlineViewController.selectedGroup; } else if( sender == _entryViewController.entryTable || sender == _entryViewController) { self.currentItem = _entryViewController.selectedEntry; @@ -158,6 +166,11 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur [[NSNotificationCenter defaultCenter] postNotificationName:MPCurrentItemChangedNotification object:self]; } +- (void)_didRevertDocument:(NSNotification *)notification { + [self.outlineViewController clearSelection]; + [self showPasswordInput]; +} + #pragma mark Actions - (void)performFindPanelAction:(id)sender { [self.entryViewController showFilter:sender]; @@ -175,7 +188,7 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur return showsNoLockScreen && document.isSecured; } if(itemAction == [MPActionHelper actionOfType:MPActionAddEntry]) { - return (nil != _outlineViewController.outlineDelegate.selectedGroup); + return (nil != _outlineViewController.selectedGroup); } if(itemAction == [MPActionHelper actionOfType:MPActionDelete]) { return (nil != _currentItem); diff --git a/MacPass/MPEntryViewController.h b/MacPass/MPEntryViewController.h index 88dedb53..864de4e4 100644 --- a/MacPass/MPEntryViewController.h +++ b/MacPass/MPEntryViewController.h @@ -52,6 +52,6 @@ typedef enum { - (void)openURL:(id)sender; /* Entry Handling*/ -- (void)deleteEntry:(id)sender; +- (void)deleteNode:(id)sender; @end diff --git a/MacPass/MPEntryViewController.m b/MacPass/MPEntryViewController.m index edd35983..5c9ece06 100644 --- a/MacPass/MPEntryViewController.m +++ b/MacPass/MPEntryViewController.m @@ -8,7 +8,6 @@ #import "MPEntryViewController.h" #import "MPAppDelegate.h" -#import "MPOutlineViewDelegate.h" #import "MPOutlineViewController.h" #import "MPDocument.h" #import "MPIconHelper.h" @@ -236,21 +235,26 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername"; [self clearFilter:nil]; } MPDocumentWindowController *sender = [notification object]; - if([sender.currentItem isKindOfClass:[KdbGroup class]]) { - KdbGroup *item = sender.currentItem; - if(item) { - if([[self.entryArrayController content] count] > 0) { - KdbEntry *entry = [[self.entryArrayController content] lastObject]; - if(entry.parent == item) { - return; // we are showing the correct object right now. - } + id item = sender.currentItem; + /* + Filter? If no group is selected, we shouldn display a list of entries + */ + if(!sender.currentGroup) { + [self.entryArrayController unbind:NSContentArrayBinding]; + [self.entryArrayController setContent:nil]; + return; + } + /* + If a grup is the current item, see if we already show that group + */ + if(item == sender.currentGroup) { + if([[self.entryArrayController content] count] > 0) { + KdbEntry *entry = [[self.entryArrayController content] lastObject]; + if(entry.parent == item) { + return; // we are showing the correct object right now. } - [self.entryArrayController bind:NSContentArrayBinding toObject:item withKeyPath:@"entries" options:nil]; - } - else { - [self.entryArrayController unbind:NSContentArrayBinding]; - [self.entryArrayController setContent:nil]; } + [self.entryArrayController bind:NSContentArrayBinding toObject:item withKeyPath:@"entries" options:nil]; } } @@ -353,7 +357,7 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername"; if([self _showsFilterBar]) { return; // nothing to to } - + NSView *scrollView = [_entryTable enclosingScrollView]; NSDictionary *views = NSDictionaryOfVariableBindings(scrollView, _filterBar); [self.view layout]; @@ -479,9 +483,10 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername"; } } -- (void)deleteEntry:(id)sender { +- (void)deleteNode:(id)sender { KdbEntry *entry =[self _clickedOrSelectedEntry]; - [entry.parent removeEntryUndoable:entry]; + MPDocument *document = [[self windowController] document]; + [document group:entry.parent removeEntry:entry]; } - (void)_toggleFilterSpace:(id)sender { diff --git a/MacPass/MPInspectorViewController.m b/MacPass/MPInspectorViewController.m index 4c3a268d..2f5a3401 100644 --- a/MacPass/MPInspectorViewController.m +++ b/MacPass/MPInspectorViewController.m @@ -8,7 +8,6 @@ #import "MPInspectorViewController.h" #import "MPEntryViewController.h" -#import "MPOutlineViewDelegate.h" #import "MPPasswordCreatorViewController.h" #import "MPShadowBox.h" #import "MPIconHelper.h" @@ -16,7 +15,6 @@ #import "MPIconSelectViewController.h" #import "MPDocumentWindowController.h" #import "MPOutlineViewController.h" -#import "MPOutlineViewDelegate.h" #import "MPDocument.h" #import "KdbLib.h" diff --git a/MacPass/MPOutlineViewController.h b/MacPass/MPOutlineViewController.h index 86384674..6b4ba88e 100644 --- a/MacPass/MPOutlineViewController.h +++ b/MacPass/MPOutlineViewController.h @@ -8,22 +8,25 @@ #import "MPViewController.h" +APPKIT_EXTERN NSString *const MPOutlineViewDidChangeGroupSelection; + @class MPOutlineViewDelegate; @class KdbGroup; @class HNHGradientView; @class MPDocumentWindowController; -@interface MPOutlineViewController : MPViewController +@interface MPOutlineViewController : MPViewController @property (readonly, assign) NSOutlineView *outlineView; -@property (retain, readonly) MPOutlineViewDelegate *outlineDelegate; @property (assign) IBOutlet HNHGradientView *bottomBar; +@property (assign, readonly) KdbGroup *selectedGroup; +- (void)clearSelection; - (void)showOutline; - (void)setupNotifications:(MPDocumentWindowController *)windowController; - (void)createGroup:(id)sender; - (void)createEntry:(id)sender; -- (void)deleteEntry:(id)sender; +- (void)deleteNode:(id)sender; @end diff --git a/MacPass/MPOutlineViewController.m b/MacPass/MPOutlineViewController.m index a53cbd08..8d145067 100644 --- a/MacPass/MPOutlineViewController.m +++ b/MacPass/MPOutlineViewController.m @@ -7,30 +7,34 @@ // #import "MPOutlineViewController.h" -#import "MPOutlineViewDelegate.h" #import "MPOutlineDataSource.h" - #import "MPDocument.h" #import "MPAppDelegate.h" #import "MPContextMenuHelper.h" #import "MPConstants.h" #import "MPActionHelper.h" +#import "MPIconHelper.h" +#import "MPUppercaseStringValueTransformer.h" #import "KdbLib.h" #import "KdbGroup+Undo.h" #import "HNHGradientView.h" +NSString *const MPOutlineViewDidChangeGroupSelection = @"com.macpass.MPOutlineViewDidChangeGroupSelection"; + +NSString *const _MPOutlineViewDataViewIdentifier = @"DataCell"; +NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell"; @interface MPOutlineViewController () { BOOL _bindingEstablished; } @property (assign) IBOutlet NSOutlineView *outlineView; @property (assign) IBOutlet NSButton *addGroupButton; +@property (assign) KdbGroup *selectedGroup; @property (retain) NSTreeController *treeController; @property (retain) MPOutlineDataSource *datasource; -@property (retain) MPOutlineViewDelegate *outlineDelegate; @property (retain) NSMenu *menu; @end @@ -46,24 +50,14 @@ if (self) { _treeController = [[NSTreeController alloc] init]; _bindingEstablished = NO; - _outlineDelegate = [[MPOutlineViewDelegate alloc] init]; _datasource = [[MPOutlineDataSource alloc] init]; } return self; } -- (void)dealloc -{ - [_datasource release]; - [_outlineDelegate release]; - [_menu release]; - - [super dealloc]; -} - - (void)didLoadView { - [_outlineView setDelegate:_outlineDelegate]; + [_outlineView setDelegate:self]; [_outlineView setMenu:[self _contextMenu]]; [_outlineView setAllowsEmptySelection:YES]; [_outlineView setFloatsGroupRows:NO]; @@ -86,10 +80,16 @@ [_outlineView expandItem:node expandChildren:NO]; } +#pragma makr Notifications - (void)setupNotifications:(MPDocumentWindowController *)windowController { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_didCreateGroup:) name:MPDocumentDidAddGroupNotification object:[windowController document]]; } +- (void)clearSelection { + [_outlineView deselectAll:nil]; + [self outlineViewSelectionDidChange:nil]; +} + - (void)_didCreateGroup:(NSNotification *)notification { NSInteger selectedRow = [_outlineView selectedRow]; NSIndexSet *indexSet; @@ -106,14 +106,8 @@ [_outlineView selectRowIndexes:indexSet byExtendingSelection:NO]; } -- (NSMenu *)_contextMenu { - NSMenu *menu = [[NSMenu alloc] init]; - NSArray *items = [MPContextMenuHelper contextMenuItemsWithItems:MPContextMenuMinimal]; - for(NSMenuItem *item in items) { - [menu addItem:item]; - } - return [menu autorelease]; -} +#pragma mark - +#pragma mark Actions - (void)createGroup:(id)sender { KdbGroup *group = [self _clickedOrSelectedGroup]; @@ -144,13 +138,68 @@ } } -- (void)deleteEntry:(id)sender { +- (void)deleteNode:(id)sender { KdbGroup *group = [self _clickedOrSelectedGroup]; if(group && group.parent) { - [group.parent removeGroupUndoable:group]; + [[[self windowController] document] group:group.parent removeGroup:group]; } } +#pragma mark NSOutlineViewDelegate +- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item { + NSTreeNode *treeNode = item; + KdbGroup *group = [treeNode representedObject]; + //KdbGroup *group = item; + NSTableCellView *view; + if(![group parent]) { + NSDictionary *options = @{ NSValueTransformerBindingOption : [NSValueTransformer valueTransformerForName:MPUppsercaseStringValueTransformerName] }; + view = [outlineView makeViewWithIdentifier:_MPOutlinveViewHeaderViewIdentifier owner:self]; + [view.textField bind:NSValueBinding toObject:group withKeyPath:@"name" options:options]; + } + else { + view = [outlineView makeViewWithIdentifier:_MPOutlineViewDataViewIdentifier owner:self]; + NSImage *icon = [MPIconHelper icon:(MPIconType)[group image]]; + [view.imageView setImage:icon]; + [view.textField bind:NSValueBinding toObject:group withKeyPath:@"name" options:nil]; + [view.textField bind:@"count" toObject:group withKeyPath:@"entries.@count" options:nil]; + } + + return view; +} + +- (BOOL)outlineView:(NSOutlineView *)outlineView isGroupItem:(id)item { + NSTreeNode *treeNode = item; + KdbGroup *group = [treeNode representedObject]; + //KdbGroup *group = item; + if(!group.parent) { + return YES; + } + return NO; +} + +- (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item { + NSTreeNode *treeNode = item; + KdbGroup *group = [treeNode representedObject]; + //KdbGroup *group = item; + return (nil != [group parent]); +} + +- (void)outlineViewSelectionDidChange:(NSNotification *)notification { + NSTreeNode *treeNode = [_outlineView itemAtRow:[_outlineView selectedRow]]; + KdbGroup *selectedGroup = [treeNode representedObject]; + self.selectedGroup = selectedGroup; + [[NSNotificationCenter defaultCenter] postNotificationName:MPOutlineViewDidChangeGroupSelection object:self userInfo:nil]; +} + +- (BOOL)outlineView:(NSOutlineView *)outlineView shouldShowOutlineCellForItem:(id)item { + return YES; + // KdbGroup *group = [item representedObject]; + // return (nil != group.parent); +} + +#pragma mark - +#pragma mark Private + - (KdbGroup *)_clickedOrSelectedGroup { NSInteger row = [self.outlineView clickedRow]; if( row < 0 ) { @@ -159,4 +208,13 @@ return [[self.outlineView itemAtRow:row] representedObject]; } +- (NSMenu *)_contextMenu { + NSMenu *menu = [[NSMenu alloc] init]; + NSArray *items = [MPContextMenuHelper contextMenuItemsWithItems:MPContextMenuMinimal]; + for(NSMenuItem *item in items) { + [menu addItem:item]; + } + return [menu autorelease]; +} + @end diff --git a/MacPass/MPOutlineViewDelegate.h b/MacPass/MPOutlineViewDelegate.h deleted file mode 100644 index a6639a68..00000000 --- a/MacPass/MPOutlineViewDelegate.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// MPOutlineViewDelegate.h -// MacPass -// -// Created by Michael Starke on 21.07.12. -// Copyright (c) 2012 HicknHack Software GmbH. All rights reserved. -// - -#import - -APPKIT_EXTERN NSString *const MPOutlineViewDidChangeGroupSelection; - -@class KdbGroup; - -@interface MPOutlineViewDelegate : NSObject - -@property (assign, readonly) KdbGroup *selectedGroup; - -@end diff --git a/MacPass/MPOutlineViewDelegate.m b/MacPass/MPOutlineViewDelegate.m deleted file mode 100644 index 81362c6c..00000000 --- a/MacPass/MPOutlineViewDelegate.m +++ /dev/null @@ -1,81 +0,0 @@ -// -// MPOutlineViewDelegate.m -// MacPass -// -// Created by Michael Starke on 21.07.12. -// Copyright (c) 2012 HicknHack Software GmbH. All rights reserved. -// - -#import "MPOutlineViewDelegate.h" -#import "MPIconHelper.h" -#import "MPUppercaseStringValueTransformer.h" -#import "HNHBadgedTextFieldCell.h" -#import "KdbLib.h" - -NSString *const MPOutlineViewDidChangeGroupSelection = @"com.macpass.MPOutlineViewDidChangeGroupSelection"; - -NSString *const _MPOutlineViewDataViewIdentifier = @"DataCell"; -NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell"; - -@interface MPOutlineViewDelegate () - -@property (assign) KdbGroup *selectedGroup; - -@end - -@implementation MPOutlineViewDelegate - -- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item { - NSTreeNode *treeNode = item; - KdbGroup *group = [treeNode representedObject]; - //KdbGroup *group = item; - NSTableCellView *view; - if(![group parent]) { - NSDictionary *options = @{ NSValueTransformerBindingOption : [NSValueTransformer valueTransformerForName:MPUppsercaseStringValueTransformerName] }; - view = [outlineView makeViewWithIdentifier:_MPOutlinveViewHeaderViewIdentifier owner:self]; - [view.textField bind:NSValueBinding toObject:group withKeyPath:@"name" options:options]; - } - else { - view = [outlineView makeViewWithIdentifier:_MPOutlineViewDataViewIdentifier owner:self]; - NSImage *icon = [MPIconHelper icon:(MPIconType)[group image]]; - [view.imageView setImage:icon]; - [view.textField bind:NSValueBinding toObject:group withKeyPath:@"name" options:nil]; - [view.textField bind:@"count" toObject:group withKeyPath:@"entries.@count" options:nil]; - } - - return view; -} - -- (BOOL)outlineView:(NSOutlineView *)outlineView isGroupItem:(id)item { - NSTreeNode *treeNode = item; - KdbGroup *group = [treeNode representedObject]; - //KdbGroup *group = item; - if(!group.parent) { - return YES; - } - return NO; -} - -- (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item { - NSTreeNode *treeNode = item; - KdbGroup *group = [treeNode representedObject]; - //KdbGroup *group = item; - return (nil != [group parent]); -} - -- (void)outlineViewSelectionDidChange:(NSNotification *)notification { - NSOutlineView *outlineView = [notification object]; - //KdbGroup *selectedGroup = [outlineView itemAtRow:[outlineView selectedRow]]; - NSTreeNode *treeNode = [outlineView itemAtRow:[outlineView selectedRow]]; - KdbGroup *selectedGroup = [treeNode representedObject]; - self.selectedGroup = selectedGroup; - [[NSNotificationCenter defaultCenter] postNotificationName:MPOutlineViewDidChangeGroupSelection object:self userInfo:nil]; -} - -- (BOOL)outlineView:(NSOutlineView *)outlineView shouldShowOutlineCellForItem:(id)item { - return YES; -// KdbGroup *group = [item representedObject]; -// return (nil != group.parent); -} - -@end diff --git a/MacPass/MacPass-Info.plist b/MacPass/MacPass-Info.plist index a4c85629..2c1f45b5 100644 --- a/MacPass/MacPass-Info.plist +++ b/MacPass/MacPass-Info.plist @@ -48,7 +48,7 @@ CFBundleSignature ???? CFBundleVersion - 1121 + 1163 LSMinimumSystemVersion ${MACOSX_DEPLOYMENT_TARGET} NSHumanReadableCopyright diff --git a/MiniKeePassLib b/MiniKeePassLib index 3126a177..69f1a0cd 160000 --- a/MiniKeePassLib +++ b/MiniKeePassLib @@ -1 +1 @@ -Subproject commit 3126a1773ac850f9c610550fdd4ca6d308e171c5 +Subproject commit 69f1a0cde5ac91041dcb994bc0f65e77175beb65