diff --git a/MacPass.xcodeproj/project.pbxproj b/MacPass.xcodeproj/project.pbxproj index e7dafbd5..63f51394 100644 --- a/MacPass.xcodeproj/project.pbxproj +++ b/MacPass.xcodeproj/project.pbxproj @@ -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 = ""; }; 4C46B8891706D16E0046109A /* NSData+MPRandomBytes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+MPRandomBytes.h"; sourceTree = ""; }; 4C46B88A1706D16E0046109A /* NSData+MPRandomBytes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+MPRandomBytes.m"; sourceTree = ""; }; + 4C4A100D176286FD00BBF2CA /* MPTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPTableView.h; sourceTree = ""; }; + 4C4A100E176286FD00BBF2CA /* MPTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPTableView.m; sourceTree = ""; }; + 4C4A101017629DA900BBF2CA /* KdbGroup+KVOAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "KdbGroup+KVOAdditions.h"; sourceTree = ""; }; + 4C4A101117629DA900BBF2CA /* KdbGroup+KVOAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "KdbGroup+KVOAdditions.m"; sourceTree = ""; }; 4C586F9D16D07ABD00E7DB57 /* 00_PasswordTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 00_PasswordTemplate.pdf; sourceTree = ""; }; 4C586F9F16D07D7200E7DB57 /* 01_PackageNetworkTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 01_PackageNetworkTemplate.pdf; sourceTree = ""; }; 4C586FA116D07F6A00E7DB57 /* 02_MessageBoxWarningTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 02_MessageBoxWarningTemplate.pdf; sourceTree = ""; }; @@ -381,6 +387,8 @@ 4CFC53BE16E94729007396BE /* MPShadowBox.m */, 4CE39AC216ECE4F7000FE29D /* MPPopupImageView.h */, 4CE39AC316ECE4F7000FE29D /* MPPopupImageView.m */, + 4C4A100D176286FD00BBF2CA /* MPTableView.h */, + 4C4A100E176286FD00BBF2CA /* MPTableView.m */, ); name = Views; sourceTree = ""; @@ -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 = ""; @@ -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; }; diff --git a/MacPass/EntryView.xib b/MacPass/EntryView.xib index d2b0db86..45730f72 100644 --- a/MacPass/EntryView.xib +++ b/MacPass/EntryView.xib @@ -320,6 +320,7 @@ {{0, 310}, {480, 16}} + _NS:60 NO 1 @@ -347,7 +348,7 @@ _NS:9 - 133680 + 154160 @@ -362,7 +363,6 @@ - YES _NS:9 NSView @@ -449,7 +449,7 @@ 266 - {105, 17} + {104.5, 17} {250, 750} @@ -471,7 +471,7 @@ NO - {{1, 1}, {105, 17}} + {{1, 1}, {104.5, 17}} @@ -499,6 +499,7 @@ {{3, 0}, {17, 17}} + _NS:11 YES @@ -539,7 +540,7 @@ NO - {{109, 1}, {144, 17}} + {{108.5, 1}, {144, 17}} _NS:9 @@ -582,7 +583,7 @@ NO - {{378, 1}, {113, 17}} + {{377, 1}, {113, 17}} @@ -599,7 +600,7 @@ 266 - {119, 17} + {118.5, 17} {250, 750} @@ -616,7 +617,7 @@ NO - {{256, 1}, {119, 17}} + {{255.5, 1}, {118.5, 17}} @@ -650,7 +651,7 @@ NO - {{494, 1}, {292, 17}} + {{493, 1}, {292, 17}} @@ -1476,6 +1477,7 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + MPTableView com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -1586,6 +1588,14 @@ ./Classes/MPEntryViewController.h + + MPTableView + NSTableView + + IBProjectSource + ./Classes/MPTableView.h + + MPViewController NSViewController diff --git a/MacPass/KdbGroup+KVOAdditions.h b/MacPass/KdbGroup+KVOAdditions.h new file mode 100644 index 00000000..9638905f --- /dev/null +++ b/MacPass/KdbGroup+KVOAdditions.h @@ -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 diff --git a/MacPass/KdbGroup+KVOAdditions.m b/MacPass/KdbGroup+KVOAdditions.m new file mode 100644 index 00000000..77708d1a --- /dev/null +++ b/MacPass/KdbGroup+KVOAdditions.m @@ -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 diff --git a/MacPass/KdbGroup+MPAdditions.h b/MacPass/KdbGroup+MPAdditions.h index 6fbd2fa5..250b93cd 100644 --- a/MacPass/KdbGroup+MPAdditions.h +++ b/MacPass/KdbGroup+MPAdditions.h @@ -16,4 +16,4 @@ - (void)moveEntry:(KdbEntry *)entry toIndex:(NSUInteger)index; -@end +@end \ No newline at end of file diff --git a/MacPass/KdbGroup+MPAdditions.m b/MacPass/KdbGroup+MPAdditions.m index ae3d17b0..b6924616 100644 --- a/MacPass/KdbGroup+MPAdditions.m +++ b/MacPass/KdbGroup+MPAdditions.m @@ -38,5 +38,4 @@ [entries exchangeObjectAtIndex:oldIndex withObjectAtIndex:index]; } - -@end +@end \ No newline at end of file diff --git a/MacPass/KdbGroup+Undo.m b/MacPass/KdbGroup+Undo.m index 20229e4f..1bcb5158 100644 --- a/MacPass/KdbGroup+Undo.m +++ b/MacPass/KdbGroup+Undo.m @@ -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 diff --git a/MacPass/MPEntryViewController.m b/MacPass/MPEntryViewController.m index 6d13dc00..338df0a9 100644 --- a/MacPass/MPEntryViewController.m +++ b/MacPass/MPEntryViewController.m @@ -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 { diff --git a/MacPass/MPOutlineViewController.m b/MacPass/MPOutlineViewController.m index 715479c2..94708051 100644 --- a/MacPass/MPOutlineViewController.m +++ b/MacPass/MPOutlineViewController.m @@ -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 { diff --git a/MacPass/MPOutlineViewDelegate.m b/MacPass/MPOutlineViewDelegate.m index 5279d207..6495dfe7 100644 --- a/MacPass/MPOutlineViewDelegate.m +++ b/MacPass/MPOutlineViewDelegate.m @@ -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]; } diff --git a/MacPass/MPTableView.h b/MacPass/MPTableView.h new file mode 100644 index 00000000..1eb22632 --- /dev/null +++ b/MacPass/MPTableView.h @@ -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 + +@interface MPTableView : NSTableView + +@end diff --git a/MacPass/MPTableView.m b/MacPass/MPTableView.m new file mode 100644 index 00000000..5270947f --- /dev/null +++ b/MacPass/MPTableView.m @@ -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 diff --git a/MacPass/MacPass-Info.plist b/MacPass/MacPass-Info.plist index a8b6947b..099d4615 100644 --- a/MacPass/MacPass-Info.plist +++ b/MacPass/MacPass-Info.plist @@ -48,7 +48,7 @@ CFBundleSignature ???? CFBundleVersion - 89E + 8DB LSMinimumSystemVersion ${MACOSX_DEPLOYMENT_TARGET} NSHumanReadableCopyright