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 */; };
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 = "<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>"; };
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>"; };
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>"; };
@@ -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 */,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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>
<string>????</string>
<key>CFBundleVersion</key>
<string>1121</string>
<string>1163</string>
<key>LSMinimumSystemVersion</key>
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
<key>NSHumanReadableCopyright</key>