Introduced KVO compliance for group and entry manipulation

Converted outline view to use NSTreeController
This commit is contained in:
michael starke
2013-06-08 01:34:03 +02:00
parent ba924701b0
commit 929871e682
13 changed files with 183 additions and 26 deletions

View File

@@ -28,6 +28,8 @@
4C46B88517063A070046109A /* NSString+MPPasswordCreation.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C46B88417063A070046109A /* NSString+MPPasswordCreation.m */; };
4C46B88817063A170046109A /* NSString+MPPasswordAnalysis.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C46B88717063A170046109A /* NSString+MPPasswordAnalysis.m */; };
4C46B88B1706D16E0046109A /* NSData+MPRandomBytes.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C46B88A1706D16E0046109A /* NSData+MPRandomBytes.m */; };
4C4A100F176286FD00BBF2CA /* MPTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C4A100E176286FD00BBF2CA /* MPTableView.m */; };
4C4A101217629DA900BBF2CA /* KdbGroup+KVOAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C4A101117629DA900BBF2CA /* KdbGroup+KVOAdditions.m */; };
4C586F9E16D07ABD00E7DB57 /* 00_PasswordTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4C586F9D16D07ABD00E7DB57 /* 00_PasswordTemplate.pdf */; };
4C586FA016D07D7200E7DB57 /* 01_PackageNetworkTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4C586F9F16D07D7200E7DB57 /* 01_PackageNetworkTemplate.pdf */; };
4C586FA216D07F6A00E7DB57 /* 02_MessageBoxWarningTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4C586FA116D07F6A00E7DB57 /* 02_MessageBoxWarningTemplate.pdf */; };
@@ -163,6 +165,10 @@
4C46B88717063A170046109A /* NSString+MPPasswordAnalysis.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+MPPasswordAnalysis.m"; sourceTree = "<group>"; };
4C46B8891706D16E0046109A /* NSData+MPRandomBytes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+MPRandomBytes.h"; sourceTree = "<group>"; };
4C46B88A1706D16E0046109A /* NSData+MPRandomBytes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+MPRandomBytes.m"; sourceTree = "<group>"; };
4C4A100D176286FD00BBF2CA /* MPTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPTableView.h; sourceTree = "<group>"; };
4C4A100E176286FD00BBF2CA /* MPTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPTableView.m; sourceTree = "<group>"; };
4C4A101017629DA900BBF2CA /* KdbGroup+KVOAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "KdbGroup+KVOAdditions.h"; sourceTree = "<group>"; };
4C4A101117629DA900BBF2CA /* KdbGroup+KVOAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "KdbGroup+KVOAdditions.m"; sourceTree = "<group>"; };
4C586F9D16D07ABD00E7DB57 /* 00_PasswordTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 00_PasswordTemplate.pdf; sourceTree = "<group>"; };
4C586F9F16D07D7200E7DB57 /* 01_PackageNetworkTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 01_PackageNetworkTemplate.pdf; sourceTree = "<group>"; };
4C586FA116D07F6A00E7DB57 /* 02_MessageBoxWarningTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 02_MessageBoxWarningTemplate.pdf; sourceTree = "<group>"; };
@@ -381,6 +387,8 @@
4CFC53BE16E94729007396BE /* MPShadowBox.m */,
4CE39AC216ECE4F7000FE29D /* MPPopupImageView.h */,
4CE39AC316ECE4F7000FE29D /* MPPopupImageView.m */,
4C4A100D176286FD00BBF2CA /* MPTableView.h */,
4C4A100E176286FD00BBF2CA /* MPTableView.m */,
);
name = Views;
sourceTree = "<group>";
@@ -396,6 +404,8 @@
4CCF9753173EFBA500460BD2 /* KdbEntry+Undo.m */,
4C22040B1746ED160054C916 /* KdbGroup+Undo.h */,
4C22040C1746ED160054C916 /* KdbGroup+Undo.m */,
4C4A101017629DA900BBF2CA /* KdbGroup+KVOAdditions.h */,
4C4A101117629DA900BBF2CA /* KdbGroup+KVOAdditions.m */,
);
name = KeePassLibAdditions;
sourceTree = "<group>";
@@ -1002,6 +1012,8 @@
4C5BF67B175C01F300D53DF7 /* MPUppercaseStringValueTransformer.m in Sources */,
4CC3AABD175F4983003EF01B /* HNHRoundedTextFieldCell.m in Sources */,
4C9D6AA917615199001C660C /* HNHRoundedSecureTextFieldCell.m in Sources */,
4C4A100F176286FD00BBF2CA /* MPTableView.m in Sources */,
4C4A101217629DA900BBF2CA /* KdbGroup+KVOAdditions.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@@ -320,6 +320,7 @@
<string key="NSFrame">{{0, 310}, {480, 16}}</string>
<reference key="NSSuperview" ref="613995671"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView"/>
<string key="NSReuseIdentifierKey">_NS:60</string>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
<int key="NSsFlags">1</int>
@@ -347,7 +348,7 @@
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="736877784"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<int key="NSsFlags">133680</int>
<int key="NSsFlags">154160</int>
<reference key="NSVScroller" ref="1037276411"/>
<reference key="NSHScroller" ref="802411427"/>
<reference key="NSContentView" ref="262664416"/>
@@ -362,7 +363,6 @@
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="613995671"/>
<bool key="NSViewIsLayerTreeHost">YES</bool>
<string key="NSReuseIdentifierKey">_NS:9</string>
<string key="NSClassName">NSView</string>
</object>
@@ -449,7 +449,7 @@
<object class="NSTextField" id="306813103">
<reference key="NSNextResponder" ref="788738248"/>
<int key="NSvFlags">266</int>
<string key="NSFrameSize">{105, 17}</string>
<string key="NSFrameSize">{104.5, 17}</string>
<reference key="NSSuperview" ref="788738248"/>
<reference key="NSNextKeyView" ref="804102913"/>
<string key="NSAntiCompressionPriority">{250, 750}</string>
@@ -471,7 +471,7 @@
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
</object>
</array>
<string key="NSFrame">{{1, 1}, {105, 17}}</string>
<string key="NSFrame">{{1, 1}, {104.5, 17}}</string>
<reference key="NSNextKeyView" ref="306813103"/>
</object>
<reference key="destination" ref="306813103"/>
@@ -499,6 +499,7 @@
</set>
<string key="NSFrame">{{3, 0}, {17, 17}}</string>
<reference key="NSSuperview" ref="804102913"/>
<reference key="NSNextKeyView" ref="798656808"/>
<string key="NSReuseIdentifierKey">_NS:11</string>
<bool key="NSEnabled">YES</bool>
<object class="NSImageCell" key="NSCell" id="38968149">
@@ -539,7 +540,7 @@
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
</object>
</array>
<string key="NSFrame">{{109, 1}, {144, 17}}</string>
<string key="NSFrame">{{108.5, 1}, {144, 17}}</string>
<reference key="NSNextKeyView" ref="591921532"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
</object>
@@ -582,7 +583,7 @@
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
</object>
</array>
<string key="NSFrame">{{378, 1}, {113, 17}}</string>
<string key="NSFrame">{{377, 1}, {113, 17}}</string>
<reference key="NSNextKeyView" ref="441850286"/>
</object>
<reference key="destination" ref="441850286"/>
@@ -599,7 +600,7 @@
<object class="NSTextField" id="1042596093">
<reference key="NSNextResponder" ref="878614701"/>
<int key="NSvFlags">266</int>
<string key="NSFrameSize">{119, 17}</string>
<string key="NSFrameSize">{118.5, 17}</string>
<reference key="NSSuperview" ref="878614701"/>
<reference key="NSNextKeyView" ref="542633869"/>
<string key="NSAntiCompressionPriority">{250, 750}</string>
@@ -616,7 +617,7 @@
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
</object>
</array>
<string key="NSFrame">{{256, 1}, {119, 17}}</string>
<string key="NSFrame">{{255.5, 1}, {118.5, 17}}</string>
<reference key="NSNextKeyView" ref="1042596093"/>
</object>
<reference key="destination" ref="1042596093"/>
@@ -650,7 +651,7 @@
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
</object>
</array>
<string key="NSFrame">{{494, 1}, {292, 17}}</string>
<string key="NSFrame">{{493, 1}, {292, 17}}</string>
<reference key="NSNextKeyView" ref="488604658"/>
</object>
<reference key="destination" ref="488604658"/>
@@ -1476,6 +1477,7 @@
<string key="434.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="NO" key="54.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
<string key="54.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="55.CustomClassName">MPTableView</string>
<string key="55.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES" key="55.ibExternalAutomaticallyCalculatesRowSizeFromViewHeight"/>
<string key="56.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -1586,6 +1588,14 @@
<string key="minorKey">./Classes/MPEntryViewController.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">MPTableView</string>
<string key="superclassName">NSTableView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/MPTableView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">MPViewController</string>
<string key="superclassName">NSViewController</string>

View File

@@ -0,0 +1,25 @@
//
// KdbGroup+KVOAdditions.h
// MacPass
//
// Created by Michael Starke on 08.06.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import "Kdb.h"
@interface KdbGroup (KVOAdditions)
/* KVO Accesors for the entries */
- (KdbEntry *)objectInEntriesAtIndex:(NSUInteger)index;
- (NSUInteger)countOfEntries;
- (void)insertObject:(KdbEntry *)entry inEntriesAtIndex:(NSUInteger)index;
- (void)removeObjectFromEntriesAtIndex:(NSUInteger)index;
/* KVO Accessors for the groups */
- (KdbGroup *)objectInGroupsAtIndex:(NSUInteger)index;
- (NSUInteger)countOfGroups;
- (void)insertObject:(KdbGroup *)group inGroupsAtIndex:(NSUInteger)index;
- (void)removeObjectFromGroupsAtIndex:(NSUInteger)index;
@end

View File

@@ -0,0 +1,51 @@
//
// KdbGroup+KVOAdditions.m
// MacPass
//
// Created by Michael Starke on 08.06.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import "KdbGroup+KVOAdditions.h"
@implementation KdbGroup (KVOAdditions)
- (void)insertObject:(KdbEntry *)entry inEntriesAtIndex:(NSUInteger)index {
entry.parent = self;
[entries insertObject:entry atIndex:index];
}
- (void)removeObjectFromEntriesAtIndex:(NSUInteger)index {
KdbEntry *entry = [entries objectAtIndex:index];
entry.parent = nil;
[entries removeObjectAtIndex:index];
}
- (NSUInteger)countOfEntries {
return [entries count];
}
- (KdbEntry *)objectInEntriesAtIndex:(NSUInteger)index {
return entries[index];
}
- (KdbGroup *)objectInGroupsAtIndex:(NSUInteger)index {
return groups[index];
}
- (NSUInteger)countOfGroups {
return [groups count];
}
- (void)insertObject:(KdbGroup *)group inGroupsAtIndex:(NSUInteger)index {
group.parent = self;
[groups insertObject:group atIndex:index];
}
- (void)removeObjectFromGroupsAtIndex:(NSUInteger)index {
KdbGroup *group = [groups objectAtIndex:index];
group.parent = nil;
[groups removeObjectAtIndex:index];
}
@end

View File

@@ -16,4 +16,4 @@
- (void)moveEntry:(KdbEntry *)entry toIndex:(NSUInteger)index;
@end
@end

View File

@@ -38,5 +38,4 @@
[entries exchangeObjectAtIndex:oldIndex withObjectAtIndex:index];
}
@end
@end

View File

@@ -7,6 +7,7 @@
//
#import "KdbGroup+Undo.h"
#import "KdbGroup+KVOAdditions.h"
NSString *const MPGroupNameUndoableKey = @"nameUndoable";
@@ -29,24 +30,32 @@ NSString *const MPGroupNameUndoableKey = @"nameUndoable";
- (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 addEntry: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 addGroup:group];
[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 removeEntry: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 removeGroup:group];
[group.parent removeObjectFromGroupsAtIndex:index];
}
@end

View File

@@ -141,6 +141,7 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername";
[self.entryTable setDelegate:self];
[self.entryTable setDoubleAction:@selector(_columnDoubleClick:)];
[self.entryTable setTarget:self];
[self.entryTable setFloatsGroupRows:NO];
[self _setupEntryMenu];
NSTableColumn *parentColumn = [self.entryTable tableColumns][0];
@@ -216,6 +217,9 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername";
return view;
}
- (void)tableView:(NSTableView *)tableView didAddRowView:(NSTableRowView *)rowView forRow:(NSInteger)row {
NSLog(@"didAddRowViewForRow: %ld color:%@ isFloating:%i", (long)row, rowView.backgroundColor, rowView.isFloating);
}
- (void)tableViewSelectionDidChange:(NSNotification *)notification {
if([self.entryTable selectedRow] < 0) {
@@ -469,12 +473,14 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername";
if(!_activeGroup) {
return; // Entries are not allowed in root group
}
MPDocument *document = [[NSDocumentController sharedDocumentController] currentDocument];
[document createEntry:_activeGroup];
}
- (void)deleteEntry:(id)sender {
// TODO:
KdbEntry *entry =[self _clickedOrSelectedEntry];
[entry.parent removeEntryUndoable:entry];
}
- (void)_toggleFilterSpace:(id)sender {

View File

@@ -17,6 +17,7 @@
@property (assign) IBOutlet NSOutlineView *outlineView;
@property (retain) NSTreeController *treeController;
@property (retain) MPOutlineDataSource *datasource;
@property (retain) MPOutlineViewDelegate *outlineDelegate;
@property (retain) NSMenu *menu;
@@ -40,9 +41,10 @@
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
_isVisible = YES;
_treeController = [[NSTreeController alloc] init];
self.outlineDelegate = [[[MPOutlineViewDelegate alloc] init] autorelease];
self.datasource = [[[MPOutlineDataSource alloc] init] autorelease];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(_didUpdateData:)
name:MPDocumentDidAddGroupNotification
@@ -69,7 +71,7 @@
}
- (void)didLoadView {
[self.outlineView setDataSource:self.datasource];
//[self.outlineView setDataSource:self.datasource];
[self.outlineView setDelegate:self.outlineDelegate];
[self.outlineView setMenu:[self _contextMenu]];
[self.outlineView setAllowsEmptySelection:YES];
@@ -90,8 +92,13 @@
}
- (void)showOutline {
[self.outlineView reloadData];
MPDocument *document = [[NSDocumentController sharedDocumentController] currentDocument];
[_treeController setChildrenKeyPath:@"groups"];
[_treeController bind:NSContentBinding toObject:document withKeyPath:@"root" options:nil];
[_outlineView bind:NSContentBinding toObject:_treeController withKeyPath:@"arrangedObjects" options:nil];
[self.outlineView reloadData];
//MPDocument *document = [[NSDocumentController sharedDocumentController] currentDocument];
[self.outlineView expandItem:document.root expandChildren:NO];
}
@@ -153,7 +160,7 @@
if( row < 0 ) {
row = [self.outlineView selectedRow];
}
return [self.outlineView itemAtRow:row];
return [[self.outlineView itemAtRow:row] representedObject];
}
- (void)_didUpdateData:(NSNotification *)notification {

View File

@@ -25,7 +25,9 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
@implementation MPOutlineViewDelegate
- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item {
KdbGroup *group = item;
NSTreeNode *treeNode = item;
KdbGroup *group = [treeNode representedObject];
//KdbGroup *group = item;
NSTableCellView *view;
if(![group parent]) {
NSDictionary *options = @{ NSValueTransformerBindingOption : [NSValueTransformer valueTransformerForName:MPUppsercaseStringValueTransformerName] };
@@ -44,7 +46,9 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
}
- (BOOL)outlineView:(NSOutlineView *)outlineView isGroupItem:(id)item {
KdbGroup *group = item;
NSTreeNode *treeNode = item;
KdbGroup *group = [treeNode representedObject];
//KdbGroup *group = item;
if(!group.parent) {
return YES;
}
@@ -52,13 +56,17 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
}
- (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item {
KdbGroup *group = 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]];
//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];
}

13
MacPass/MPTableView.h Normal file
View File

@@ -0,0 +1,13 @@
//
// MPTableView.h
// MacPass
//
// Created by Michael Starke on 07.06.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface MPTableView : NSTableView
@end

17
MacPass/MPTableView.m Normal file
View File

@@ -0,0 +1,17 @@
//
// MPTableView.m
// MacPass
//
// Created by Michael Starke on 07.06.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import "MPTableView.h"
@implementation MPTableView
- (void)drawBackgroundInClipRect:(NSRect)clipRect {
[super drawBackgroundInClipRect:clipRect];
}
@end

View File

@@ -48,7 +48,7 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>89E</string>
<string>8DB</string>
<key>LSMinimumSystemVersion</key>
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
<key>NSHumanReadableCopyright</key>