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
This commit is contained in:
michael starke
2013-06-26 01:19:44 +02:00
parent c2e9cfc7d6
commit cb18013964
17 changed files with 217 additions and 229 deletions

View File

@@ -154,7 +154,6 @@
4CC299FF176F99E50050C939 /* MPRequestHandlerService.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CC299FE176F99E50050C939 /* MPRequestHandlerService.m */; }; 4CC299FF176F99E50050C939 /* MPRequestHandlerService.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CC299FE176F99E50050C939 /* MPRequestHandlerService.m */; };
4CC29A02176F9D140050C939 /* MPTestAssociateRequestHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CC29A01176F9D140050C939 /* MPTestAssociateRequestHandler.m */; }; 4CC29A02176F9D140050C939 /* MPTestAssociateRequestHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CC29A01176F9D140050C939 /* MPTestAssociateRequestHandler.m */; };
4CC3AABD175F4983003EF01B /* HNHRoundedTextFieldCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CC3AAB9175F4983003EF01B /* HNHRoundedTextFieldCell.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 */; }; 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 */; }; 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 */; }; 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 = "<group>"; }; 4CC29A01176F9D140050C939 /* MPTestAssociateRequestHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPTestAssociateRequestHandler.m; sourceTree = "<group>"; };
4CC3AAB8175F4983003EF01B /* HNHRoundedTextFieldCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HNHRoundedTextFieldCell.h; sourceTree = "<group>"; }; 4CC3AAB8175F4983003EF01B /* HNHRoundedTextFieldCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HNHRoundedTextFieldCell.h; sourceTree = "<group>"; };
4CC3AAB9175F4983003EF01B /* HNHRoundedTextFieldCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HNHRoundedTextFieldCell.m; sourceTree = "<group>"; }; 4CC3AAB9175F4983003EF01B /* HNHRoundedTextFieldCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HNHRoundedTextFieldCell.m; sourceTree = "<group>"; };
4CC6258F15BA1C99002F5B11 /* MPOutlineViewDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPOutlineViewDelegate.h; sourceTree = "<group>"; };
4CC6259015BA1C99002F5B11 /* MPOutlineViewDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPOutlineViewDelegate.m; sourceTree = "<group>"; };
4CD78AB716D155FF00768A1D /* 07_NotepadTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 07_NotepadTemplate.pdf; sourceTree = "<group>"; }; 4CD78AB716D155FF00768A1D /* 07_NotepadTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 07_NotepadTemplate.pdf; sourceTree = "<group>"; };
4CD78AB816D155FF00768A1D /* 08_SocketTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 08_SocketTemplate.pdf; sourceTree = "<group>"; }; 4CD78AB816D155FF00768A1D /* 08_SocketTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 08_SocketTemplate.pdf; sourceTree = "<group>"; };
4CD78AB916D155FF00768A1D /* 09_IdentityTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 09_IdentityTemplate.pdf; sourceTree = "<group>"; }; 4CD78AB916D155FF00768A1D /* 09_IdentityTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 09_IdentityTemplate.pdf; sourceTree = "<group>"; };
@@ -764,8 +761,6 @@
children = ( children = (
4C77E37815B84A240093A587 /* MPAppDelegate.h */, 4C77E37815B84A240093A587 /* MPAppDelegate.h */,
4C77E37915B84A240093A587 /* MPAppDelegate.m */, 4C77E37915B84A240093A587 /* MPAppDelegate.m */,
4CC6258F15BA1C99002F5B11 /* MPOutlineViewDelegate.h */,
4CC6259015BA1C99002F5B11 /* MPOutlineViewDelegate.m */,
4C3BD51316D276F800389F1F /* MPToolbarDelegate.h */, 4C3BD51316D276F800389F1F /* MPToolbarDelegate.h */,
4C3BD51416D276F800389F1F /* MPToolbarDelegate.m */, 4C3BD51416D276F800389F1F /* MPToolbarDelegate.m */,
4C811C8116ECD06E00C4BAC6 /* MPKeyfilePathControlDelegate.h */, 4C811C8116ECD06E00C4BAC6 /* MPKeyfilePathControlDelegate.h */,
@@ -1298,7 +1293,6 @@
4CAD747E15B887FD00104512 /* DDXMLElement.m in Sources */, 4CAD747E15B887FD00104512 /* DDXMLElement.m in Sources */,
4CAD747F15B887FD00104512 /* DDXMLNode.m in Sources */, 4CAD747F15B887FD00104512 /* DDXMLNode.m in Sources */,
4C37A84015B8B474005EF8EE /* MPOutlineDataSource.m in Sources */, 4C37A84015B8B474005EF8EE /* MPOutlineDataSource.m in Sources */,
4CC6259115BA1C99002F5B11 /* MPOutlineViewDelegate.m in Sources */,
4CA0B2F915BCAF6700654E32 /* MPGeneralSettingsController.m in Sources */, 4CA0B2F915BCAF6700654E32 /* MPGeneralSettingsController.m in Sources */,
4CA0B2FC15BCAF8600654E32 /* MPSettingsWindowController.m in Sources */, 4CA0B2FC15BCAF8600654E32 /* MPSettingsWindowController.m in Sources */,
4C83814215BF4677001AE468 /* MPDocumentWindowController.m in Sources */, 4C83814215BF4677001AE468 /* MPDocumentWindowController.m in Sources */,

View File

@@ -17,11 +17,4 @@ APPKIT_EXTERN NSString *const MPGroupNameUndoableKey;
- (NSString *)nameUndoable; - (NSString *)nameUndoable;
- (void)setNameUndoable:(NSString *)newName; - (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 @end

View File

@@ -27,48 +27,4 @@ NSString *const MPGroupNameUndoableKey = @"nameUndoable";
self.name = newName; 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 @end

View File

@@ -20,7 +20,7 @@
@(MPActionCopyPassword) : @"copyPassword:", @(MPActionCopyPassword) : @"copyPassword:",
@(MPActionCopyURL) : @"copyURL:", @(MPActionCopyURL) : @"copyURL:",
@(MPActionCopyUsername) : @"copyUsername:", @(MPActionCopyUsername) : @"copyUsername:",
@(MPActionDelete) : @"deleteEntry:", @(MPActionDelete) : @"deleteNode:",
@(MPActionEdit) : @"editEntry:", @(MPActionEdit) : @"editEntry:",
@(MPActionOpenURL) : @"openURL:", @(MPActionOpenURL) : @"openURL:",
@(MPActionToggleInspector) : @"toggleInspector:", @(MPActionToggleInspector) : @"toggleInspector:",

View File

@@ -14,6 +14,7 @@ APPKIT_EXTERN NSString *const MPDocumentDidAddGroupNotification;
APPKIT_EXTERN NSString *const MPDocumentWillDelteGroupNotification; APPKIT_EXTERN NSString *const MPDocumentWillDelteGroupNotification;
APPKIT_EXTERN NSString *const MPDocumentDidAddEntryNotification; APPKIT_EXTERN NSString *const MPDocumentDidAddEntryNotification;
APPKIT_EXTERN NSString *const MPDocumentWillDeleteEntryNotification; APPKIT_EXTERN NSString *const MPDocumentWillDeleteEntryNotification;
APPKIT_EXTERN NSString *const MPDocumentDidRevertNotifiation;
APPKIT_EXTERN NSString *const MPDocumentEntryKey; APPKIT_EXTERN NSString *const MPDocumentEntryKey;
APPKIT_EXTERN NSString *const MPDocumentGroupKey; APPKIT_EXTERN NSString *const MPDocumentGroupKey;
@@ -34,7 +35,7 @@ APPKIT_EXTERN NSString *const MPDocumentGroupKey;
/* true, if document is loaded and decrypted (tree is loaded) */ /* true, if document is loaded and decrypted (tree is loaded) */
@property (assign, readonly, getter = isDecrypted) BOOL decrypted; @property (assign, readonly, getter = isDecrypted) BOOL decrypted;
@property (retain, readonly) KdbTree *tree; @property (retain, readonly) KdbTree *tree;
@property (assign, readonly) KdbGroup *root; @property (assign, readonly, nonatomic) KdbGroup *root;
@property (nonatomic,retain) NSString *password; @property (nonatomic,retain) NSString *password;
@property (nonatomic, retain) NSURL *key; @property (nonatomic, retain) NSURL *key;
@property (assign, readonly) MPDatabaseVersion version; @property (assign, readonly) MPDatabaseVersion version;
@@ -59,11 +60,19 @@ APPKIT_EXTERN NSString *const MPDocumentGroupKey;
- (KdbEntry *)createEntry:(KdbGroup *)parent; - (KdbEntry *)createEntry:(KdbGroup *)parent;
/* /*
Undoable movement of object All non-setter undoable actions
*/ */
- (void)moveGroup:(KdbGroup *)group toGroup:(KdbGroup *)target index:(NSInteger)index; - (void)moveGroup:(KdbGroup *)group toGroup:(KdbGroup *)target index:(NSInteger)index;
- (BOOL)group:(KdbGroup *)group isMoveableToGroup:(KdbGroup *)target; - (BOOL)group:(KdbGroup *)group isMoveableToGroup:(KdbGroup *)target;
- (void)moveEntry:(KdbEntry *)entry toGroup:(KdbGroup *)target index:(NSInteger)index; - (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 @end

View File

@@ -20,19 +20,21 @@
#import "Kdb3Tree+NewTree.h" #import "Kdb3Tree+NewTree.h"
#import "Kdb4Tree+NewTree.h" #import "Kdb4Tree+NewTree.h"
NSString *const MPDocumentDidAddGroupNotification = @"MPDocumentDidAddGroupNotification"; NSString *const MPDocumentDidAddGroupNotification = @"com.hicknhack.macpass.MPDocumentDidAddGroupNotification";
NSString *const MPDocumentWillDelteGroupNotification = @"MPDocumentDidDelteGroupNotification"; NSString *const MPDocumentWillDelteGroupNotification = @"com.hicknhack.macpass.MPDocumentDidDelteGroupNotification";
NSString *const MPDocumentDidAddEntryNotification = @"MPDocumentDidAddEntryNotification"; NSString *const MPDocumentDidAddEntryNotification = @"com.hicknhack.macpass.MPDocumentDidAddEntryNotification";
NSString *const MPDocumentWillDeleteEntryNotification = @"MPDocumentDidDeleteEntryNotification"; NSString *const MPDocumentWillDeleteEntryNotification = @"com.hicknhack.macpass.MPDocumentDidDeleteEntryNotification";
NSString *const MPDocumentDidRevertNotifiation = @"com.hicknhack.macpass.MPDocumentDidRevertNotifiation";
NSString *const MPDocumentEntryKey = @"MPDocumentEntryKey"; NSString *const MPDocumentEntryKey = @"MPDocumentEntryKey";
NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey"; NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
@interface MPDocument () @interface MPDocument ()
@property (assign, nonatomic) BOOL secured; @property (assign, nonatomic) BOOL secured;
@property (retain) KdbTree *tree; @property (retain) KdbTree *tree;
@property (assign, nonatomic) KdbGroup *root;
@property (nonatomic, readonly) KdbPassword *passwordHash; @property (nonatomic, readonly) KdbPassword *passwordHash;
@property (assign) MPDatabaseVersion version; @property (assign) MPDatabaseVersion version;
@property (assign) BOOL decrypted; @property (assign) BOOL decrypted;
@@ -94,6 +96,15 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
return YES; 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 { - (BOOL)isEntireFileLoaded {
return _decrypted; return _decrypted;
} }
@@ -115,6 +126,8 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
else if( [self.tree isKindOfClass:[Kdb3Tree class]]) { else if( [self.tree isKindOfClass:[Kdb3Tree class]]) {
self.version = MPDatabaseVersion3; self.version = MPDatabaseVersion3;
} }
/* reset the root to inform KVO listeners */
self.root = self.tree.root;
_decrypted = YES; _decrypted = YES;
return YES; return YES;
} }
@@ -147,7 +160,13 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
#pragma mark Data Accesors #pragma mark Data Accesors
- (KdbGroup *)root { - (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 { - (KdbEntry *)findEntry:(UUID *)uuid {
@@ -172,7 +191,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
- (KdbEntry *)createEntry:(KdbGroup *)parent { - (KdbEntry *)createEntry:(KdbGroup *)parent {
KdbEntry *newEntry = [self.tree createEntry:parent]; KdbEntry *newEntry = [self.tree createEntry:parent];
newEntry.title = NSLocalizedString(@"DEFAULT_ENTRY_TITLE", @"Title for a newly created entry"); newEntry.title = NSLocalizedString(@"DEFAULT_ENTRY_TITLE", @"Title for a newly created entry");
[parent addEntryUndoable:newEntry]; [self group:parent addEntry:newEntry];
NSDictionary *userInfo = @{ MPDocumentEntryKey : newEntry }; NSDictionary *userInfo = @{ MPDocumentEntryKey : newEntry };
[[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidAddEntryNotification object:self userInfo:userInfo]; [[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidAddEntryNotification object:self userInfo:userInfo];
return newEntry; return newEntry;
@@ -181,7 +200,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
- (KdbGroup *)createGroup:(KdbGroup *)parent { - (KdbGroup *)createGroup:(KdbGroup *)parent {
KdbGroup *newGroup = [self.tree createGroup:parent]; KdbGroup *newGroup = [self.tree createGroup:parent];
newGroup.name = NSLocalizedString(@"DEFAULT_GROUP_NAME", @"Title for a newly created group"); newGroup.name = NSLocalizedString(@"DEFAULT_GROUP_NAME", @"Title for a newly created group");
[parent addGroupUndoable:newGroup]; [self group:parent addGroup:newGroup];
NSDictionary *userInfo = @{ MPDocumentGroupKey : newGroup }; NSDictionary *userInfo = @{ MPDocumentGroupKey : newGroup };
[[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidAddGroupNotification object:self userInfo:userInfo]; [[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidAddGroupNotification object:self userInfo:userInfo];
return newGroup; return newGroup;
@@ -231,4 +250,43 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
[target insertObject:entry inEntriesAtIndex:index]; [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 @end

View File

@@ -32,7 +32,8 @@ APPKIT_EXTERN NSString *const MPCurrentItemChangedNotification;
/* Holds the current item. That is either a KdbGroup or a KdbEntry */ /* Holds the current item. That is either a KdbGroup or a KdbEntry */
@property (readonly, assign) id currentItem; @property (readonly, assign) id currentItem;
@property (readonly, assign) KdbGroup *currentGroup;
@property (readonly, assign) KdbEntry *currentEntry;
- (void)showEntries; - (void)showEntries;
- (void)showPasswordInput; - (void)showPasswordInput;

View File

@@ -13,7 +13,6 @@
#import "MPPasswordEditViewController.h" #import "MPPasswordEditViewController.h"
#import "MPToolbarDelegate.h" #import "MPToolbarDelegate.h"
#import "MPOutlineViewController.h" #import "MPOutlineViewController.h"
#import "MPOutlineViewDelegate.h"
#import "MPInspectorViewController.h" #import "MPInspectorViewController.h"
#import "MPAppDelegate.h" #import "MPAppDelegate.h"
#import "MPActionHelper.h" #import "MPActionHelper.h"
@@ -29,6 +28,8 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
@property (retain) NSToolbar *toolbar; @property (retain) NSToolbar *toolbar;
@property (assign) id currentItem; @property (assign) id currentItem;
@property (assign) KdbGroup *currentGroup;
@property (assign) KdbEntry *currentEntry;
@property (retain) MPPasswordInputController *passwordInputController; @property (retain) MPPasswordInputController *passwordInputController;
@property (retain) MPPasswordEditViewController *passwordEditController; @property (retain) MPPasswordEditViewController *passwordEditController;
@@ -54,14 +55,15 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
_inspectorViewController = [[MPInspectorViewController alloc] init]; _inspectorViewController = [[MPInspectorViewController alloc] init];
_currentItem = nil; _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]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_updateCurrentItem:) name:MPDidChangeSelectedEntryNotification object:_entryViewController];
} }
return self; return self;
} }
- (void)dealloc { - (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[_toolbar release]; [_toolbar release];
[_passwordInputController release]; [_passwordInputController release];
@@ -76,8 +78,10 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
} }
#pragma mark View Handling #pragma mark View Handling
- (void)windowDidLoad - (void)windowDidLoad {
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_didRevertDocument:) name:MPDocumentDidRevertNotifiation object:[self document]];
[_entryViewController setupNotifications:self]; [_entryViewController setupNotifications:self];
[_inspectorViewController setupNotifications:self]; [_inspectorViewController setupNotifications:self];
[_outlineViewController setupNotifications:self]; [_outlineViewController setupNotifications:self];
@@ -143,11 +147,15 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
[self.window makeFirstResponder:[viewController reconmendedFirstResponder]]; [self.window makeFirstResponder:[viewController reconmendedFirstResponder]];
} }
#pragma mark Resonder handling #pragma mark Notification handling
- (void)_updateCurrentItem:(NSNotification *)notification { - (void)_updateCurrentItem:(NSNotification *)notification {
id sender = [notification object]; 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) { else if( sender == _entryViewController.entryTable || sender == _entryViewController) {
self.currentItem = _entryViewController.selectedEntry; self.currentItem = _entryViewController.selectedEntry;
@@ -158,6 +166,11 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
[[NSNotificationCenter defaultCenter] postNotificationName:MPCurrentItemChangedNotification object:self]; [[NSNotificationCenter defaultCenter] postNotificationName:MPCurrentItemChangedNotification object:self];
} }
- (void)_didRevertDocument:(NSNotification *)notification {
[self.outlineViewController clearSelection];
[self showPasswordInput];
}
#pragma mark Actions #pragma mark Actions
- (void)performFindPanelAction:(id)sender { - (void)performFindPanelAction:(id)sender {
[self.entryViewController showFilter:sender]; [self.entryViewController showFilter:sender];
@@ -175,7 +188,7 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
return showsNoLockScreen && document.isSecured; return showsNoLockScreen && document.isSecured;
} }
if(itemAction == [MPActionHelper actionOfType:MPActionAddEntry]) { if(itemAction == [MPActionHelper actionOfType:MPActionAddEntry]) {
return (nil != _outlineViewController.outlineDelegate.selectedGroup); return (nil != _outlineViewController.selectedGroup);
} }
if(itemAction == [MPActionHelper actionOfType:MPActionDelete]) { if(itemAction == [MPActionHelper actionOfType:MPActionDelete]) {
return (nil != _currentItem); return (nil != _currentItem);

View File

@@ -52,6 +52,6 @@ typedef enum {
- (void)openURL:(id)sender; - (void)openURL:(id)sender;
/* Entry Handling*/ /* Entry Handling*/
- (void)deleteEntry:(id)sender; - (void)deleteNode:(id)sender;
@end @end

View File

@@ -8,7 +8,6 @@
#import "MPEntryViewController.h" #import "MPEntryViewController.h"
#import "MPAppDelegate.h" #import "MPAppDelegate.h"
#import "MPOutlineViewDelegate.h"
#import "MPOutlineViewController.h" #import "MPOutlineViewController.h"
#import "MPDocument.h" #import "MPDocument.h"
#import "MPIconHelper.h" #import "MPIconHelper.h"
@@ -236,21 +235,26 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername";
[self clearFilter:nil]; [self clearFilter:nil];
} }
MPDocumentWindowController *sender = [notification object]; MPDocumentWindowController *sender = [notification object];
if([sender.currentItem isKindOfClass:[KdbGroup class]]) { id item = sender.currentItem;
KdbGroup *item = sender.currentItem; /*
if(item) { Filter? If no group is selected, we shouldn display a list of entries
if([[self.entryArrayController content] count] > 0) { */
KdbEntry *entry = [[self.entryArrayController content] lastObject]; if(!sender.currentGroup) {
if(entry.parent == item) { [self.entryArrayController unbind:NSContentArrayBinding];
return; // we are showing the correct object right now. [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]) { if([self _showsFilterBar]) {
return; // nothing to to return; // nothing to to
} }
NSView *scrollView = [_entryTable enclosingScrollView]; NSView *scrollView = [_entryTable enclosingScrollView];
NSDictionary *views = NSDictionaryOfVariableBindings(scrollView, _filterBar); NSDictionary *views = NSDictionaryOfVariableBindings(scrollView, _filterBar);
[self.view layout]; [self.view layout];
@@ -479,9 +483,10 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername";
} }
} }
- (void)deleteEntry:(id)sender { - (void)deleteNode:(id)sender {
KdbEntry *entry =[self _clickedOrSelectedEntry]; KdbEntry *entry =[self _clickedOrSelectedEntry];
[entry.parent removeEntryUndoable:entry]; MPDocument *document = [[self windowController] document];
[document group:entry.parent removeEntry:entry];
} }
- (void)_toggleFilterSpace:(id)sender { - (void)_toggleFilterSpace:(id)sender {

View File

@@ -8,7 +8,6 @@
#import "MPInspectorViewController.h" #import "MPInspectorViewController.h"
#import "MPEntryViewController.h" #import "MPEntryViewController.h"
#import "MPOutlineViewDelegate.h"
#import "MPPasswordCreatorViewController.h" #import "MPPasswordCreatorViewController.h"
#import "MPShadowBox.h" #import "MPShadowBox.h"
#import "MPIconHelper.h" #import "MPIconHelper.h"
@@ -16,7 +15,6 @@
#import "MPIconSelectViewController.h" #import "MPIconSelectViewController.h"
#import "MPDocumentWindowController.h" #import "MPDocumentWindowController.h"
#import "MPOutlineViewController.h" #import "MPOutlineViewController.h"
#import "MPOutlineViewDelegate.h"
#import "MPDocument.h" #import "MPDocument.h"
#import "KdbLib.h" #import "KdbLib.h"

View File

@@ -8,22 +8,25 @@
#import "MPViewController.h" #import "MPViewController.h"
APPKIT_EXTERN NSString *const MPOutlineViewDidChangeGroupSelection;
@class MPOutlineViewDelegate; @class MPOutlineViewDelegate;
@class KdbGroup; @class KdbGroup;
@class HNHGradientView; @class HNHGradientView;
@class MPDocumentWindowController; @class MPDocumentWindowController;
@interface MPOutlineViewController : MPViewController @interface MPOutlineViewController : MPViewController <NSOutlineViewDelegate>
@property (readonly, assign) NSOutlineView *outlineView; @property (readonly, assign) NSOutlineView *outlineView;
@property (retain, readonly) MPOutlineViewDelegate *outlineDelegate;
@property (assign) IBOutlet HNHGradientView *bottomBar; @property (assign) IBOutlet HNHGradientView *bottomBar;
@property (assign, readonly) KdbGroup *selectedGroup;
- (void)clearSelection;
- (void)showOutline; - (void)showOutline;
- (void)setupNotifications:(MPDocumentWindowController *)windowController; - (void)setupNotifications:(MPDocumentWindowController *)windowController;
- (void)createGroup:(id)sender; - (void)createGroup:(id)sender;
- (void)createEntry:(id)sender; - (void)createEntry:(id)sender;
- (void)deleteEntry:(id)sender; - (void)deleteNode:(id)sender;
@end @end

View File

@@ -7,30 +7,34 @@
// //
#import "MPOutlineViewController.h" #import "MPOutlineViewController.h"
#import "MPOutlineViewDelegate.h"
#import "MPOutlineDataSource.h" #import "MPOutlineDataSource.h"
#import "MPDocument.h" #import "MPDocument.h"
#import "MPAppDelegate.h" #import "MPAppDelegate.h"
#import "MPContextMenuHelper.h" #import "MPContextMenuHelper.h"
#import "MPConstants.h" #import "MPConstants.h"
#import "MPActionHelper.h" #import "MPActionHelper.h"
#import "MPIconHelper.h"
#import "MPUppercaseStringValueTransformer.h"
#import "KdbLib.h" #import "KdbLib.h"
#import "KdbGroup+Undo.h" #import "KdbGroup+Undo.h"
#import "HNHGradientView.h" #import "HNHGradientView.h"
NSString *const MPOutlineViewDidChangeGroupSelection = @"com.macpass.MPOutlineViewDidChangeGroupSelection";
NSString *const _MPOutlineViewDataViewIdentifier = @"DataCell";
NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
@interface MPOutlineViewController () { @interface MPOutlineViewController () {
BOOL _bindingEstablished; BOOL _bindingEstablished;
} }
@property (assign) IBOutlet NSOutlineView *outlineView; @property (assign) IBOutlet NSOutlineView *outlineView;
@property (assign) IBOutlet NSButton *addGroupButton; @property (assign) IBOutlet NSButton *addGroupButton;
@property (assign) KdbGroup *selectedGroup;
@property (retain) NSTreeController *treeController; @property (retain) NSTreeController *treeController;
@property (retain) MPOutlineDataSource *datasource; @property (retain) MPOutlineDataSource *datasource;
@property (retain) MPOutlineViewDelegate *outlineDelegate;
@property (retain) NSMenu *menu; @property (retain) NSMenu *menu;
@end @end
@@ -46,24 +50,14 @@
if (self) { if (self) {
_treeController = [[NSTreeController alloc] init]; _treeController = [[NSTreeController alloc] init];
_bindingEstablished = NO; _bindingEstablished = NO;
_outlineDelegate = [[MPOutlineViewDelegate alloc] init];
_datasource = [[MPOutlineDataSource alloc] init]; _datasource = [[MPOutlineDataSource alloc] init];
} }
return self; return self;
} }
- (void)dealloc
{
[_datasource release];
[_outlineDelegate release];
[_menu release];
[super dealloc];
}
- (void)didLoadView { - (void)didLoadView {
[_outlineView setDelegate:_outlineDelegate]; [_outlineView setDelegate:self];
[_outlineView setMenu:[self _contextMenu]]; [_outlineView setMenu:[self _contextMenu]];
[_outlineView setAllowsEmptySelection:YES]; [_outlineView setAllowsEmptySelection:YES];
[_outlineView setFloatsGroupRows:NO]; [_outlineView setFloatsGroupRows:NO];
@@ -86,10 +80,16 @@
[_outlineView expandItem:node expandChildren:NO]; [_outlineView expandItem:node expandChildren:NO];
} }
#pragma makr Notifications
- (void)setupNotifications:(MPDocumentWindowController *)windowController { - (void)setupNotifications:(MPDocumentWindowController *)windowController {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_didCreateGroup:) name:MPDocumentDidAddGroupNotification object:[windowController document]]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_didCreateGroup:) name:MPDocumentDidAddGroupNotification object:[windowController document]];
} }
- (void)clearSelection {
[_outlineView deselectAll:nil];
[self outlineViewSelectionDidChange:nil];
}
- (void)_didCreateGroup:(NSNotification *)notification { - (void)_didCreateGroup:(NSNotification *)notification {
NSInteger selectedRow = [_outlineView selectedRow]; NSInteger selectedRow = [_outlineView selectedRow];
NSIndexSet *indexSet; NSIndexSet *indexSet;
@@ -106,14 +106,8 @@
[_outlineView selectRowIndexes:indexSet byExtendingSelection:NO]; [_outlineView selectRowIndexes:indexSet byExtendingSelection:NO];
} }
- (NSMenu *)_contextMenu { #pragma mark -
NSMenu *menu = [[NSMenu alloc] init]; #pragma mark Actions
NSArray *items = [MPContextMenuHelper contextMenuItemsWithItems:MPContextMenuMinimal];
for(NSMenuItem *item in items) {
[menu addItem:item];
}
return [menu autorelease];
}
- (void)createGroup:(id)sender { - (void)createGroup:(id)sender {
KdbGroup *group = [self _clickedOrSelectedGroup]; KdbGroup *group = [self _clickedOrSelectedGroup];
@@ -144,13 +138,68 @@
} }
} }
- (void)deleteEntry:(id)sender { - (void)deleteNode:(id)sender {
KdbGroup *group = [self _clickedOrSelectedGroup]; KdbGroup *group = [self _clickedOrSelectedGroup];
if(group && group.parent) { 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 { - (KdbGroup *)_clickedOrSelectedGroup {
NSInteger row = [self.outlineView clickedRow]; NSInteger row = [self.outlineView clickedRow];
if( row < 0 ) { if( row < 0 ) {
@@ -159,4 +208,13 @@
return [[self.outlineView itemAtRow:row] representedObject]; 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 @end

View File

@@ -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 <Foundation/Foundation.h>
APPKIT_EXTERN NSString *const MPOutlineViewDidChangeGroupSelection;
@class KdbGroup;
@interface MPOutlineViewDelegate : NSObject <NSOutlineViewDelegate>
@property (assign, readonly) KdbGroup *selectedGroup;
@end

View File

@@ -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

View File

@@ -48,7 +48,7 @@
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1121</string> <string>1163</string>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>
<string>${MACOSX_DEPLOYMENT_TARGET}</string> <string>${MACOSX_DEPLOYMENT_TARGET}</string>
<key>NSHumanReadableCopyright</key> <key>NSHumanReadableCopyright</key>