From 780c8782e641251b76a83e6d162b44156ebbe6c1 Mon Sep 17 00:00:00 2001 From: michael starke Date: Wed, 31 Jul 2013 02:50:13 +0200 Subject: [PATCH] Updated Localization Added configureable Table headers in Entry view --- MacPass.xcodeproj/project.pbxproj | 6 ++ MacPass/EntryView.xib | 31 +++++--- MacPass/IconSelection.xib | 55 ++++++++++---- MacPass/KdbEntry+Undo.h | 7 -- MacPass/KdbEntry+Undo.m | 6 -- MacPass/MPAppDelegate.m | 2 + MacPass/MPDocument.m | 9 ++- MacPass/MPDocumentWindowDelegate.m | 2 +- MacPass/MPEntryContextMenuDelegate.h | 3 - MacPass/MPEntryContextMenuDelegate.m | 8 +- MacPass/MPEntryViewController.m | 100 ++++++++++++++++++------- MacPass/MPStripLineBreaksTransformer.h | 17 +++++ MacPass/MPStripLineBreaksTransformer.m | 37 +++++++++ MacPass/MacPass-Info.plist | 2 +- MacPass/de.lproj/Localizable.strings | Bin 12416 -> 9198 bytes MacPass/en.lproj/Localizable.strings | Bin 12058 -> 8754 bytes 16 files changed, 204 insertions(+), 81 deletions(-) create mode 100644 MacPass/MPStripLineBreaksTransformer.h create mode 100644 MacPass/MPStripLineBreaksTransformer.m diff --git a/MacPass.xcodeproj/project.pbxproj b/MacPass.xcodeproj/project.pbxproj index c09248bd..f4b3eac0 100644 --- a/MacPass.xcodeproj/project.pbxproj +++ b/MacPass.xcodeproj/project.pbxproj @@ -168,6 +168,7 @@ 4C67D33017981A2B00A7BDFC /* HNHTokenField.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C67D32F17981A2B00A7BDFC /* HNHTokenField.m */; }; 4C67D33317981ABA00A7BDFC /* HNHTokenFieldCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C67D33217981ABA00A7BDFC /* HNHTokenFieldCell.m */; }; 4C69A73A16D589DF00EC1B1A /* HNHGradientView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C69A73916D589DF00EC1B1A /* HNHGradientView.m */; }; + 4C6BEA3117A88E6C00CF69A8 /* MPStripLineBreaksTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C6BEA3017A88E6C00CF69A8 /* MPStripLineBreaksTransformer.m */; }; 4C6D1D25178579570014C5A5 /* 48_FolderTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4C6D1D24178579570014C5A5 /* 48_FolderTemplate.pdf */; }; 4C6D1D27178586CA0014C5A5 /* 99_AddFolderTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4C6D1D26178586CA0014C5A5 /* 99_AddFolderTemplate.pdf */; }; 4C6D1D2B17858A250014C5A5 /* MacPass.icns in Resources */ = {isa = PBXBuildFile; fileRef = 4C6D1D2A17858A250014C5A5 /* MacPass.icns */; }; @@ -577,6 +578,8 @@ 4C67D33217981ABA00A7BDFC /* HNHTokenFieldCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HNHTokenFieldCell.m; sourceTree = ""; }; 4C69A73816D589DF00EC1B1A /* HNHGradientView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HNHGradientView.h; sourceTree = ""; }; 4C69A73916D589DF00EC1B1A /* HNHGradientView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HNHGradientView.m; sourceTree = ""; }; + 4C6BEA2F17A88E6C00CF69A8 /* MPStripLineBreaksTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPStripLineBreaksTransformer.h; sourceTree = ""; }; + 4C6BEA3017A88E6C00CF69A8 /* MPStripLineBreaksTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPStripLineBreaksTransformer.m; sourceTree = ""; }; 4C6D1D24178579570014C5A5 /* 48_FolderTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 48_FolderTemplate.pdf; sourceTree = ""; }; 4C6D1D26178586CA0014C5A5 /* 99_AddFolderTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 99_AddFolderTemplate.pdf; sourceTree = ""; }; 4C6D1D2A17858A250014C5A5 /* MacPass.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = MacPass.icns; path = "../Assets/App icon/MacPass.icns"; sourceTree = ""; }; @@ -1082,6 +1085,8 @@ 4C5BF67A175C01F300D53DF7 /* MPUppercaseStringValueTransformer.m */, 4CF6C70F176F4533007A811D /* MPStringLengthValueTransformer.h */, 4CF6C710176F4533007A811D /* MPStringLengthValueTransformer.m */, + 4C6BEA2F17A88E6C00CF69A8 /* MPStripLineBreaksTransformer.h */, + 4C6BEA3017A88E6C00CF69A8 /* MPStripLineBreaksTransformer.m */, 4C888C9516EB754B003D34A1 /* MPActionHelper.h */, 4C888C9616EB754B003D34A1 /* MPActionHelper.m */, 4C2E382116D1421B00037A9D /* MPIconHelper.h */, @@ -2060,6 +2065,7 @@ 4CD7223B17A7CB0700F5A1E1 /* MPWorkflowSettingsController.m in Sources */, 4C2671AD17A7D8FC00F3A645 /* HNHColorWell.m in Sources */, 4CA08DA017A831B200A6544B /* MPAddEntryContextMenuDelegate.m in Sources */, + 4C6BEA3117A88E6C00CF69A8 /* MPStripLineBreaksTransformer.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/MacPass/EntryView.xib b/MacPass/EntryView.xib index cd7e680c..165c0c8f 100644 --- a/MacPass/EntryView.xib +++ b/MacPass/EntryView.xib @@ -45,7 +45,7 @@ NSApplication - + 268 @@ -55,8 +55,10 @@ 268 + {{7, 5}, {32, 19}} + _NS:9 YES @@ -86,6 +88,7 @@ {694, 30} + _NS:9 HNHGradientView @@ -104,6 +107,7 @@ {694, 548} + _NS:13 YES @@ -114,6 +118,7 @@ 256 {694, 17} + @@ -143,7 +148,7 @@ 6 System headerColor - + 3 MQA @@ -299,10 +304,7 @@ 3 2 - - 1 - MSAxIDEAA - + 6 System @@ -326,17 +328,19 @@ {{0, 17}, {694, 548}} + _NS:11 - 6 + 4 -2147483392 {{224, 17}, {15, 102}} + _NS:58 NO @@ -349,6 +353,7 @@ -2147483392 {{0, 310}, {480, 16}} + _NS:60 NO @@ -365,6 +370,7 @@ {694, 17} + @@ -373,6 +379,7 @@ {{0, 30}, {694, 565}} + _NS:9 133680 @@ -387,6 +394,8 @@ {694, 594} + + _NS:9 NSView @@ -1729,7 +1738,7 @@ - 844 + 867 @@ -1756,7 +1765,7 @@ NSButton NSButton NSButton - NSLayoutConstraint + NSLayoutConstraint HNHGradientView @@ -1804,8 +1813,8 @@ filterUsernameButton NSButton - - tableToTop + + tableToTopConstraint NSLayoutConstraint diff --git a/MacPass/IconSelection.xib b/MacPass/IconSelection.xib index b2d06fcf..bf86973c 100644 --- a/MacPass/IconSelection.xib +++ b/MacPass/IconSelection.xib @@ -45,9 +45,10 @@ 268 - {{182, 18}, {118, 25}} + {{262, 18}, {118, 25}} + _NS:22 YES @@ -81,7 +82,7 @@ 4370 - {300, 250} + {380, 280} @@ -105,7 +106,7 @@ 0 - {300, 250} + {380, 280} @@ -151,7 +152,7 @@ 0.63157892227172852 - {{10, 50}, {300, 250}} + {{10, 50}, {380, 280}} @@ -165,7 +166,7 @@ 1 - {320, 310} + {400, 340} @@ -179,9 +180,10 @@ 268 - {{9, 9}, {32, 32}} + {{4, 4}, {32, 32}} + _NS:9 YES @@ -205,7 +207,7 @@ NO - {50, 50} + {40, 40} @@ -562,22 +564,22 @@ - 148 + 161 - 149 + 162 - 150 + 168 - 151 + 169 @@ -617,10 +619,10 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin HNHScrollView com.apple.InterfaceBuilder.CocoaPlugin @@ -635,7 +637,7 @@ - 151 + 169 @@ -688,6 +690,27 @@ ./Classes/MPViewController.h + + NSCollectionViewItem + + NSImageView + NSTextField + + + + imageView + NSImageView + + + textField + NSTextField + + + + IBProjectSource + ./Classes/NSCollectionViewItem.h + + NSLayoutConstraint NSObject diff --git a/MacPass/KdbEntry+Undo.h b/MacPass/KdbEntry+Undo.h index 5c80cb13..fa93440f 100644 --- a/MacPass/KdbEntry+Undo.h +++ b/MacPass/KdbEntry+Undo.h @@ -8,13 +8,6 @@ #import "Kdb.h" -APPKIT_EXTERN NSString *const MPEntryTitleUndoableKey; -APPKIT_EXTERN NSString *const MPEntryUsernameUndoableKey; -APPKIT_EXTERN NSString *const MPEntryPasswordUndoableKey; -APPKIT_EXTERN NSString *const MPEntryUrlUndoableKey; -APPKIT_EXTERN NSString *const MPEntryNotesUndoableKey; - - @interface KdbEntry (Undo) - (NSString *)titleUndoable; diff --git a/MacPass/KdbEntry+Undo.m b/MacPass/KdbEntry+Undo.m index aa79da7e..213168c4 100644 --- a/MacPass/KdbEntry+Undo.m +++ b/MacPass/KdbEntry+Undo.m @@ -11,12 +11,6 @@ #import "KdbGroup+KVOAdditions.h" #import "KdbGroup+MPTreeTools.h" -NSString *const MPEntryTitleUndoableKey = @"titleUndoable"; -NSString *const MPEntryUsernameUndoableKey = @"usernameUndoable"; -NSString *const MPEntryPasswordUndoableKey = @"passwordUndoable"; -NSString *const MPEntryUrlUndoableKey = @"urlUndoable"; -NSString *const MPEntryNotesUndoableKey = @"notesUndoable"; - #ifndef MPSetActionName #define MPSetActionName(key, comment) \ if(![[self undoManager] isUndoing]) {\ diff --git a/MacPass/MPAppDelegate.m b/MacPass/MPAppDelegate.m index 6e26abc4..d7ed4113 100644 --- a/MacPass/MPAppDelegate.m +++ b/MacPass/MPAppDelegate.m @@ -13,6 +13,7 @@ #import "MPSettingsHelper.h" #import "MPUppercaseStringValueTransformer.h" #import "MPStringLengthValueTransformer.h" +#import "MPStripLineBreaksTransformer.h" #import "MPServerDaemon.h" #import "MPLockDaemon.h" #import "MPDocumentWindowController.h" @@ -37,6 +38,7 @@ [MPSettingsHelper setupDefaults]; [MPUppercaseStringValueTransformer registerTransformer]; [MPStringLengthValueTransformer registerTransformer]; + [MPStripLineBreaksTransformer registerTransformer]; } - (void)dealloc { diff --git a/MacPass/MPDocument.m b/MacPass/MPDocument.m index befec16f..d84b7627 100644 --- a/MacPass/MPDocument.m +++ b/MacPass/MPDocument.m @@ -99,6 +99,7 @@ typedef NS_ENUM(NSUInteger, MPAlertType) { _readOnly = NO; _rootAdapter = [[MPRootAdapter alloc] init]; _version = version; + [[self undoManager] setLevelsOfUndo:10]; switch(_version) { case MPDatabaseVersion3: self.tree = [Kdb3Tree templateTree]; @@ -195,10 +196,10 @@ typedef NS_ENUM(NSUInteger, MPAlertType) { #pragma mark Lock/Unlock/Decrypt - (BOOL)unlockWithPassword:(NSString *)password keyFileURL:(NSURL *)keyFileURL { -// KPKPassword *pwd = [[KPKPassword alloc] initWithPassword:password key:nil]; -// -// KPKTreeCryptor *cryptor = [KPKTreeCryptor treeCryptorWithData:_fileData password:pwd]; -// KPKTree *tree = [cryptor decryptTree:NULL]; + // KPKPassword *pwd = [[KPKPassword alloc] initWithPassword:password key:nil]; + // + // KPKTreeCryptor *cryptor = [KPKTreeCryptor treeCryptorWithData:_fileData password:pwd]; + // KPKTree *tree = [cryptor decryptTree:NULL]; self.key = keyFileURL; self.password = [password length] > 0 ? password : nil; diff --git a/MacPass/MPDocumentWindowDelegate.m b/MacPass/MPDocumentWindowDelegate.m index c8fb53a7..fcf7deda 100644 --- a/MacPass/MPDocumentWindowDelegate.m +++ b/MacPass/MPDocumentWindowDelegate.m @@ -24,7 +24,7 @@ NSArray *classArray = [NSArray arrayWithObject:[NSURL class]]; NSArray *arrayOfURLs = [draggingPasteBoard readObjectsForClasses:classArray options:nil]; - BOOL ok; + BOOL ok = NO; for(NSURL *url in arrayOfURLs) { if([url isFileURL] || [url isFileReferenceURL]) { continue; diff --git a/MacPass/MPEntryContextMenuDelegate.h b/MacPass/MPEntryContextMenuDelegate.h index 5a16c1e9..a05434a3 100644 --- a/MacPass/MPEntryContextMenuDelegate.h +++ b/MacPass/MPEntryContextMenuDelegate.h @@ -7,10 +7,7 @@ // #import -@class MPEntryViewController; @interface MPEntryContextMenuDelegate : NSObject -@property (weak) MPEntryViewController *viewController; - @end diff --git a/MacPass/MPEntryContextMenuDelegate.m b/MacPass/MPEntryContextMenuDelegate.m index f6aa05ed..ba0bd801 100644 --- a/MacPass/MPEntryContextMenuDelegate.m +++ b/MacPass/MPEntryContextMenuDelegate.m @@ -7,7 +7,7 @@ // #import "MPEntryContextMenuDelegate.h" -#import "MPEntryViewController.h" +#import "MPDocument.h" #import "Kdb4Node.h" @@ -30,9 +30,9 @@ static NSUInteger const kMPAttachmentsMenuItem = 2000; if([lastItem isSeparatorItem]) { [menu removeItem:lastItem]; } - - if([self.viewController.selectedEntry isKindOfClass:[Kdb4Entry class]]) { - Kdb4Entry *entry = (Kdb4Entry *)self.viewController.selectedEntry; + MPDocument *document = [[NSDocumentController sharedDocumentController] currentDocument]; + if([document.selectedEntry isKindOfClass:[Kdb4Entry class]]) { + Kdb4Entry *entry = (Kdb4Entry *)document.selectedEntry; if([entry.stringFields count] > 0) { [menu addItem:[NSMenuItem separatorItem]]; NSMenuItem *customFieldsItem = [[NSMenuItem alloc] init]; diff --git a/MacPass/MPEntryViewController.m b/MacPass/MPEntryViewController.m index 316be541..ec266956 100644 --- a/MacPass/MPEntryViewController.m +++ b/MacPass/MPEntryViewController.m @@ -21,6 +21,7 @@ #import "MPConstants.h" #import "MPEntryTableDataSource.h" #import "MPStringLengthValueTransformer.h" +#import "MPStripLineBreaksTransformer.h" #import "MPEntryContextMenuDelegate.h" #import "HNHTableHeaderCell.h" @@ -54,6 +55,8 @@ NSString *const MPEntryTableTitleColumnIdentifier = @"MPTitleColumnIdentifier"; NSString *const MPEntryTablePasswordColumnIdentifier = @"MPPasswordColumnIdentifier"; NSString *const MPEntryTableParentColumnIdentifier = @"MPParentColumnIdentifier"; NSString *const MPEntryTableURLColumnIdentifier = @"MPEntryTableURLColumnIdentifier"; +NSString *const MPEntryTableNotesColumnIdentifier = @"MPEntryTableNotesColumnIdentifier"; +NSString *const MPEntryTableAttachmentColumnIdentifier = @"MPEntryTableAttachmentColumnIdentifier"; NSString *const _MPTableImageCellView = @"ImageCell"; NSString *const _MPTableStringCellView = @"StringCell"; @@ -113,9 +116,7 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername"; _entryArrayController = [[NSArrayController alloc] init]; _dataSource = [[MPEntryTableDataSource alloc] init]; _dataSource.viewController = self; - _menuDelegate = [[MPEntryContextMenuDelegate alloc] init]; - _menuDelegate.viewController = self; - + _menuDelegate = [[MPEntryContextMenuDelegate alloc] init]; _selectedEntry = nil; } return self; @@ -127,7 +128,7 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername"; } - (void)didLoadView { - [self.view setWantsLayer:YES]; + [[self view] setWantsLayer:YES]; [self _hideFilterBarAnimated]; [_bottomBar setBorderType:HNHBorderTop]; @@ -150,7 +151,10 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername"; NSTableColumn *userNameColumn = [self.entryTable tableColumns][2]; NSTableColumn *passwordColumn = [self.entryTable tableColumns][3]; NSTableColumn *urlColumn = [self.entryTable tableColumns][4]; - + NSTableColumn *attachmentsColumn = [[NSTableColumn alloc] initWithIdentifier:MPEntryTableAttachmentColumnIdentifier]; + NSTableColumn *notesColumn = [[NSTableColumn alloc] initWithIdentifier:MPEntryTableNotesColumnIdentifier]; + [self.entryTable addTableColumn:notesColumn]; + [self.entryTable addTableColumn:attachmentsColumn]; [parentColumn setIdentifier:MPEntryTableParentColumnIdentifier]; [titleColumn setIdentifier:MPEntryTableTitleColumnIdentifier]; @@ -169,16 +173,19 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername"; [userNameColumn setSortDescriptorPrototype:userNameSortDescriptor]; [urlColumn setSortDescriptorPrototype:urlSortDescriptor]; - [[parentColumn headerCell] setStringValue:@"Group"]; - [[titleColumn headerCell] setStringValue:@"Title"]; - [[userNameColumn headerCell] setStringValue:@"Username"]; - [[passwordColumn headerCell] setStringValue:@"Password"]; - [[urlColumn headerCell] setStringValue:@"URL"]; + [[parentColumn headerCell] setStringValue:NSLocalizedString(@"GROUP", "")]; + [[titleColumn headerCell] setStringValue:NSLocalizedString(@"TITLE", "")]; + [[userNameColumn headerCell] setStringValue:NSLocalizedString(@"USERNAME", "")]; + [[passwordColumn headerCell] setStringValue:NSLocalizedString(@"PASSWORD", "")]; + [[urlColumn headerCell] setStringValue:NSLocalizedString(@"URL", "")]; + [[notesColumn headerCell] setStringValue:NSLocalizedString(@"NOTES", "")]; + [[attachmentsColumn headerCell] setStringValue:NSLocalizedString(@"ATTACHMENTS", "")]; [self.entryTable bind:NSContentBinding toObject:self.entryArrayController withKeyPath:@"arrangedObjects" options:nil]; [self.entryTable bind:NSSortDescriptorsBinding toObject:self.entryArrayController withKeyPath:@"sortDescriptors" options:nil]; [self.entryTable setDataSource:_dataSource]; + [self _setupHeaderMenu]; [parentColumn setHidden:YES]; } @@ -195,18 +202,19 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername"; - (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { KdbEntry *entry = [self.entryArrayController arrangedObjects][row]; - - const BOOL isTitleColumn = [[tableColumn identifier] isEqualToString:MPEntryTableTitleColumnIdentifier]; - const BOOL isGroupColumn = [[tableColumn identifier] isEqualToString:MPEntryTableParentColumnIdentifier]; - const BOOL isPasswordColum = [[tableColumn identifier] isEqualToString:MPEntryTablePasswordColumnIdentifier]; - const BOOL isUsernameColumn = [[tableColumn identifier] isEqualToString:MPEntryTableUserNameColumnIdentifier]; - const BOOL isURLColumn = [[tableColumn identifier] isEqualToString:MPEntryTableURLColumnIdentifier]; + BOOL isTitleColumn = [[tableColumn identifier] isEqualToString:MPEntryTableTitleColumnIdentifier]; + BOOL isGroupColumn = [[tableColumn identifier] isEqualToString:MPEntryTableParentColumnIdentifier]; + BOOL isPasswordColum = [[tableColumn identifier] isEqualToString:MPEntryTablePasswordColumnIdentifier]; + BOOL isUsernameColumn = [[tableColumn identifier] isEqualToString:MPEntryTableUserNameColumnIdentifier]; + BOOL isURLColumn = [[tableColumn identifier] isEqualToString:MPEntryTableURLColumnIdentifier]; + BOOL isAttachmentColumn = [[tableColumn identifier] isEqualToString:MPEntryTableAttachmentColumnIdentifier]; + BOOL isNotesColumn = [[tableColumn identifier] isEqualToString:MPEntryTableNotesColumnIdentifier]; NSTableCellView *view = nil; if(isTitleColumn || isGroupColumn) { view = [tableView makeViewWithIdentifier:_MPTableImageCellView owner:self]; if( isTitleColumn ) { - [[view textField] bind:NSValueBinding toObject:entry withKeyPath:MPEntryTitleUndoableKey options:nil]; + [[view textField] bind:NSValueBinding toObject:entry withKeyPath:@"titleUndoable" options:nil]; [[view imageView] setImage:[MPIconHelper icon:(MPIconType)entry.image]]; } else { @@ -218,17 +226,23 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername"; else if( isPasswordColum ) { view = [tableView makeViewWithIdentifier:_MPTAbleSecurCellView owner:self]; NSDictionary *options = @{ NSValueTransformerBindingOption : [NSValueTransformer valueTransformerForName:MPStringLengthValueTransformerName] }; - [[view textField] bind:NSValueBinding toObject:entry withKeyPath:MPEntryPasswordUndoableKey options:options]; + [[view textField] bind:NSValueBinding toObject:entry withKeyPath:@"passwordUndoable" options:options]; } - else if( isUsernameColumn || isURLColumn ) { + else { view = [tableView makeViewWithIdentifier:_MPTableStringCellView owner:self]; if(isURLColumn) { - [[view textField] bind:NSValueBinding toObject:entry withKeyPath:MPEntryUrlUndoableKey options:nil]; - //[[view textField] setStringValue:entry.url]; + [[view textField] bind:NSValueBinding toObject:entry withKeyPath:@"urlUndoable" options:nil]; } - else { - [[view textField] bind:NSValueBinding toObject:entry withKeyPath:MPEntryUsernameUndoableKey options:nil]; - //[[view textField] setStringValue:entry.username]; + else if( isUsernameColumn) { + [[view textField] bind:NSValueBinding toObject:entry withKeyPath:@"usernameUndoable" options:nil]; + } + else if( isNotesColumn ) { + NSDictionary *options = @{ NSValueTransformerNameBindingOption : MPStripLineBreaksTransformerName }; + [[view textField] bind:NSValueBinding toObject:entry withKeyPath:@"notesUndoable" options:options]; + } + else if( isAttachmentColumn ) { + [[view textField] setStringValue:@""]; + //[[view textField] bind:NSValueBinding toObject:entry withKeyPath:@"countOfBinaries" options:nil]; } } @@ -412,7 +426,6 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername"; multiplier:1 constant:0]; [[self view] addConstraint:self.filterbarTopConstraint]; - [NSAnimationContext runAnimationGroup:^(NSAnimationContext* context) { context.duration = STATUS_BAR_ANIMATION_TIME; context.allowsImplicitAnimation = YES; @@ -424,7 +437,6 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername"; } - (void)_hideFilterBarAnimated { - if(![self _showsFilterBar]) { return; // nothing to do; } @@ -522,7 +534,7 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername"; self.trashBar.inactiveGradient = [[NSGradient alloc] initWithColors:inactiveColors]; } -#pragma mark EntryMenu +#pragma mark ContextMenu - (void)_setupEntryMenu { @@ -533,9 +545,36 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername"; } [menu setDelegate:_menuDelegate]; [self.entryTable setMenu:menu]; - } +- (void)_setupHeaderMenu { + NSMenu *headerMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] init]; + + [headerMenu addItemWithTitle:NSLocalizedString(@"TITLE", "") action:NULL keyEquivalent:@""]; + [headerMenu addItemWithTitle:NSLocalizedString(@"USERNAME", "") action:NULL keyEquivalent:@""]; + [headerMenu addItemWithTitle:NSLocalizedString(@"PASSWORD", "") action:NULL keyEquivalent:@""]; + [headerMenu addItemWithTitle:NSLocalizedString(@"URL", "") action:NULL keyEquivalent:@""]; + [headerMenu addItemWithTitle:NSLocalizedString(@"NOTES", "") action:NULL keyEquivalent:@""]; + [headerMenu addItemWithTitle:NSLocalizedString(@"ATTACHMENTS", "") action:NULL keyEquivalent:@""]; + + NSArray *identifier = @[ MPEntryTableTitleColumnIdentifier, + MPEntryTableUserNameColumnIdentifier, + MPEntryTablePasswordColumnIdentifier, + MPEntryTableURLColumnIdentifier, + MPEntryTableNotesColumnIdentifier, + MPEntryTableAttachmentColumnIdentifier ]; + + NSDictionary *options = @{ NSValueTransformerNameBindingOption : NSNegateBooleanTransformerName }; + for(NSMenuItem *item in [headerMenu itemArray]) { + NSUInteger index = [headerMenu indexOfItem:item]; + NSTableColumn *column= [self.entryTable tableColumnWithIdentifier:identifier[index]]; + [item bind:NSValueBinding toObject:column withKeyPath:@"hidden" options:options]; + } + + [[self.entryTable headerView] setMenu:headerMenu]; +} + + #pragma makr Action Helper - (KdbEntry *)_clickedOrSelectedEntry { @@ -598,6 +637,10 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername"; [document deleteEntry:entry]; } +//- (void)toggleHeader:(id)sender { +// // +//} + #pragma mark Validation - (BOOL)validateMenuItem:(NSMenuItem *)menuItem { return YES; @@ -643,6 +686,7 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername"; else [self copyURL:nil]; } + // TODO: Add more actions for new columns } - (void)setFilterMode:(MPFilterModeType)newFilterMode { diff --git a/MacPass/MPStripLineBreaksTransformer.h b/MacPass/MPStripLineBreaksTransformer.h new file mode 100644 index 00000000..75c983cd --- /dev/null +++ b/MacPass/MPStripLineBreaksTransformer.h @@ -0,0 +1,17 @@ +// +// MPStripLineBreaksTransformer.h +// MacPass +// +// Created by Michael Starke on 31.07.13. +// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved. +// + +#import + +FOUNDATION_EXPORT NSString *const MPStripLineBreaksTransformerName; + +@interface MPStripLineBreaksTransformer : NSValueTransformer + ++ (void)registerTransformer; + +@end diff --git a/MacPass/MPStripLineBreaksTransformer.m b/MacPass/MPStripLineBreaksTransformer.m new file mode 100644 index 00000000..26c96305 --- /dev/null +++ b/MacPass/MPStripLineBreaksTransformer.m @@ -0,0 +1,37 @@ +// +// MPStripLineBreaksTransformer.m +// MacPass +// +// Created by Michael Starke on 31.07.13. +// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved. +// + +#import "MPStripLineBreaksTransformer.h" + +NSString *const MPStripLineBreaksTransformerName = @"com.hicknhack.macpass.MPStripLineBreaksTransformerName"; + +@implementation MPStripLineBreaksTransformer + ++ (Class)transformedValueClass { + return [NSString class]; +} + ++ (BOOL)allowsReverseTransformation { + return NO; +} + ++ (void)registerTransformer { + MPStripLineBreaksTransformer *transformer = [[MPStripLineBreaksTransformer alloc] init]; + [NSValueTransformer setValueTransformer:transformer + forName:MPStripLineBreaksTransformerName]; +} + +- (id)transformedValue:(id)value { + if(![value isKindOfClass:[NSString class]]) { + return nil; + } + NSArray *elements = [value componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]]; + return [elements componentsJoinedByString:@" "]; +} + +@end diff --git a/MacPass/MacPass-Info.plist b/MacPass/MacPass-Info.plist index 71d05b9a..4dfa2d40 100644 --- a/MacPass/MacPass-Info.plist +++ b/MacPass/MacPass-Info.plist @@ -48,7 +48,7 @@ CFBundleSignature ???? CFBundleVersion - 2525 + 2527 LSMinimumSystemVersion ${MACOSX_DEPLOYMENT_TARGET} NSHumanReadableCopyright diff --git a/MacPass/de.lproj/Localizable.strings b/MacPass/de.lproj/Localizable.strings index f36901826b1c2d16ebe63c20d9f8ba235381d34c..2fb634ba38260d8f1d545c2e3be3d3c4c6b83ebd 100644 GIT binary patch delta 1371 zcmZ`(OKcle6ulG2u{(|v*B{2Noq9aA<0K?;9jhOulzi$YK@BM)R#PZyNJs*16FZtX zfMAnKs1z0f>xd02BC$e+O*e=I6#^s_fshbvDi(l{V8f?~C2BZt652EpdYYN1`|i8< z+;i@owVB^Xvs-s^(j}&hNL6fEk{PLS&C48ZB`MP~FDqi!<2~rrg7x!P>sJHy$Gr8w z`|ImoZZN0?(HB0B<%ns_^Xf~yV9FH3JtNO?Z^;R~b>IvZ+WYaOwyq6fOUuV}QE7F0 z4$-g1L{+IUk&ZtaMm-j-MJZy)ZQxy30v-MleC!|FXUS>WACVHS#5!Z=9LS4={4DcS z__k$LmSq_!E2&wirVUtuJ|v9Zh{7~WuNU}idn;V88TtHf>ykoCRF+II)09l}JwX~C zmnXQNQki9pxg)NO48rHiq)cXCRRqcXXiTApQ~Qt60VEC_Mc2VT{N)d0^I$j5`J=35 zlF>^tjZ`#_FU&CPRG0BH>zE@(o8SMi&<|J4q&9*5Rs@@75VqA9sxjvtZ~S6qTKC${ z9?GBEV`GK)_%D)sn;De~N^+YODJ2xIyLDM@C=`?~C9WYkC1djF4m*=XYRXAI>byeL zRX)YC;@ICahhxLEsqrm4qg&w}C8Lrhr{~b%vtauMk#=$5^&qU~B5t+(iVp*8 zu){CYiMaPL+$qw!)=-*ikE|Kok*bZ5cyF9_Z|8~^|S literal 12416 zcmc(l+fpM(5{B!Vr_d7NSg&K(-o0JN9yCH63`hjhz;dPFAQ)me1&GC-=k+tpm1DjC zSE(Yax?3Qy7>7bLjk-HC>(6sm{rbP}!Z)E6zS4Ik9EP95ovseUS-95!--PeNQdrjA zi*OP~dZHZ;!a!H;uon8d(+dC4cRBo5&)@3Go@|9-q%jUxy7zrSV_omP54%rN8HY)D z5Cx|<&@cC*b`qLsZikJ~6V+kp7Id3s+YaZVbT5icwDv`#8#W6%X_a5q*14~BABPVa zr6pkoqTBJedtIGJPM5kmouYIYxnGA%t#P9J$GSHWeuqN;gRYNtJ)YjXmaMLcc3fpY zbcA46T42Q^{kyB{L0H%Is_@;Crn>sg^|K>tH{vuF<&RN{BT=o&aTnLpicj4|sV}5? zM=7nXCkjZ(3NGXQiT=J3?Q0=)9<_9$Uyfu?P`i>nf%#aU+wiS^OP1BvN`}&2U;1-t z+maDnSi9NJTX0?xN+aRai})R6{Ckq~KFZqCeIz&SoV~d;YtkD2vC|+;OFnlixo-3s zznLT*SyE40>B@?7jT}jvSY@-d_oa7qdm)=b=lIr-`qyp#M%uiI(&G_W{+XU}OX$dY z;k+i!BU!|@{^HtYc&FzN#p6i-n@=U{SeCr`+r+7%zVGxMM0!14Z5Px!^0dQfnMgtG zo9KI_?_HFurz>nb#jlb>?r}{zE2$49b@FX=cpY&lEqhgK8pk->l2q^pMPvj;q9KtP zpEEzkzb5+2o?;C*@fnam((fR}Gs)9Bva228+KpDf8n1{GBgO20XDD|H4tCEXcu8R= zVmk=?qPr_P%i?A6mRNJA&x0tL3`Cq1eJ0@#8K${RWQE-3?C(~LSM$7$rgvpQRZU|z z7Vkgl>UN4Qh&?UWfw1Yw7YDMXzO0AX3VxtA$kt1Qz?O+`E#UzVv{2IbD2lbRZs}>t%&ZaINoa=c(?gGyi5*{L(7lct1->}&0-e_61}cu)n#Oi{V%f46q7(R;XrM%s@1=jCxE~#AE7SU(05DEyR@s3^T{(Z?r9|#k_AlO zR>nQ8WJ_zwWlTO?;%K;054lX#sD|A|%zIwBnO&h3?30{03qP+wnh`6jky*9KYot4q zWR{C&OXt~b)DT;fY+t4}!Sb*ss$RFKt?*ek+gz6{u2Ri;k5rk|>$JQ&Ysq@Qyi{&U zj!s#>ekr-AGVpzuV|MkHqM}zuRNYjF=P^blzv;%Ba6=a0RQb)GD}A-6*l`&vMY_^! z#Smzk?-0}O)RVT9J&7^YX2im;!(YRn_5VM^-@>2b{edJPuiVEcp!D_Qy(CrYjT81% z2zhmoI%3zu&#_uCdA+wz@8^9;{avc&>Pi>Yi-F~ibVgm_^{r#w+(Qx%$$Iq+p6hch z-sd^PI-y5}-_w`=HP>rf8o7u#k%Q4fx#}vtfu5S^WBMXnZHW_|0-9~+Hj2H$P-|s+ zuvTd8dHyMK!i)a@P`R7+<=j$?$nAm1L4UUsS6;4aUGhW4Yx)hX{7y9teHU3dr@t<_ ziAr=!JxLEmx@qch*P2tHr#1>y9(O{=dV4rl@vTeJ*E#{YnQuHVQEpA^S_gKK>K)U%BhQS9Zjb)2r&*5a*SR;pU+Tg#htF>4 z3c(9KSZ;?amF8>>)%8LS?F$jAWinaQ^kY->6UyzVDZ0N8;$BLaBeEeWkc;jHPjD=d zfqY44MCNo9s_&H4e~6r|I=zmyVbb#t(k?xbt)z1BQNK+^OqVFetOYDd}+@)_PI)2nuLT^hpY3QX%qidx8UP*TmHn}CV zI$Ec59mM!@D-`P5+Lk^}gw3h$(G~svUD&qdr?yy?erI)I*j+g(n$?N1J|-c}h7MTbj&58{cbbH+C7GrWW=eD|fr*Z0udl7UD; zoFF>cbdJgkuOTedsn9vXL`;$t-O=ATtIZD@**Hhwj3b1JcW|JDK$x=Tl zuKIK->B)AVY;VvbiPseKc55X+&qZC?L7Gz8p2AQzly)pq6m>51RscF{B)k| z#!S^-UACh+Wm}vDzs$Qz4K7ZKwsIrYR1ujvw>CNVSve&HqCdQ9^ z7qGhim+W1=MuN0|SmisbmU#`2E7?5tU|!X^E%jqPmrsB2SZo68rJH=7=i+?4dEKS2 zERNfLtde@u*^Bk)mR$cqC?wti<1}9VK-l(LhO4Czx?o0^KQ`)g!n)W)s7fMYLqrP_XYd)3zS0z^G z*>qp4x5)ia*zkVT+e)kebNelyFKy=_YQv^b>|^Gg^no_ zZD~E&%7v^63908;HS0LnT_z^13cErZXSz;yv>b6rGS;QzJljAY&cF;~r(rW*+pA>i zJ6m>___L%mRGF?>heeN7^@m?#6rzvC7QTIUWw|f0GA7An=hv^!ZQ-{{-z)<));!of zt5c_ngAZeW)maMu#H@^yoz>_)l%G%m z)h9Hm4@k3JllCfR$)=gGMV$F0q(dj0tVgLFDXO%lX>&(Xo-4K>EB=k2&EmHiBg?-2 zwKF{E#LiysPQA9|_fb6Qz41LxRhVv8W9%a9G-HqCROX<{IScT&-6PY2^H`V6z5`__ zG6BNo=y`|(>CDA^=%q=x@g-|BQ70;ycA3X)sb4@Qc6!&fZkNX}E~ojNEaU8sP0W0r z&yFCIAx`no@m|hEy~z$;PWBLcLd(u-k!|d}PF=40PQ$LyvpmRTkFEnL(ZBR?UR{K4{tpZ2l76kVN7(IAJS&8zT7$z*3~v0bD) ziLv@X$T64XJQLPc_VGM-qdV+&_(hJ6&m=-HO3uj;zL?k+g2P3MAGt3rK5B zap}2;gyxA6W%P7ku`K#jq#~bEalc%~A7yiP8Y+1vzQare$s<+DWeGIWbLGQ(wtWr%UYM6;Y`{?CmvTgjcQXUdVMl~vP+9$ S)I-z{uC-Y)Xi4WQ`1~JT`g0Nh diff --git a/MacPass/en.lproj/Localizable.strings b/MacPass/en.lproj/Localizable.strings index 08d3ba1f89f7bb6c3417de084936e3266b9c7d87..2e72c31cde4ce8a202d2746a6df55645dcdca19e 100644 GIT binary patch delta 594 zcmY+B&ui0Q7{{Nir88;Mg=}flrrpxmRw%RDFlX6jbTvZ})=eB`2N74TXsN4g9fF96 zc=Ry%?jXA;9z3XrVt4Q$io>&b5j^;d-DShSz$ejz5}rKo^Sn=<&-Zzwb?~`l==$|!J` zT~R|Tt>AS!k6+d>XMXk@=!TSlr}I;`gnhX&)Prj8X|NtV@@Hucy24|vQOh65t?&uVM|YqrxA9`|103xe g+{7MU85OL{XRw`GL^t4~nl1L$_veM)X6~-|8<@10>i_@% delta 2553 zcmbtWOK%%h6h3bJj+Nj9dkm%OB&bPK6-6nuB~%s|+c;@sJBsZlETA>DNg^EEOMFW}##XQ_qfCbe;G(-r(oTBSAEEyKpd?nw&MD5YtJQdFQEW$6OV zQXY3$^GN96_I#x6oiY(X9dK2EG!%3b>oo;Z!>WVdGx%-b$*92cr@@na@$TTc-TTT2 zKmu&I!fWDw6ZdJLZ{TeU$PdsHuoSx*o~ckdAD!f5(Xo=9_-^d;h@b%sNzG3Ezhjrq z*|<8!#txh+Ff~>~75NehTUVLa5uu576Opg0car}H(fq#fmVwo>S|)fmq80u*Hp9PI z)Of4!F-3%Ltn0lY^L{)2oNI4ZwR=_7TX0T?CiukAPg{wzd@&K{E$`TPuWdP%kg!Th zs>}aMXo};*uU>WFr7K)8fM)PIW0AE07xP%BsSKA3E_Yo}9t_`;-rH3Xb?zX|Rn=jW z&MW2#Bkgo7fBbd)NWenn-{XhJol=;HNqAdVbI_#c6xy=J;7>v+bZcN*bAJs_Wm1G; zlALCcc$e|)nKs`H8CNf0M2i^E60)7MGM>egf-C0&qA+3Mps(Ud6Bh1ryW^HZOAPC{ z*0FN3o&|Cleim@eQkkd2BZurNp0#FGrlO^$7q#Mw=Ok|pe`m}oEfB0tVAfF$O`$hD z)BCK$V)zJj5gRdG2D$JS&f1#FzHj z({KGTuJzxQwEI**raCjbLw5Y4?sCGdApd2o-RgX~f8s$KA&)n5An)vwoN6Yf$-$7y z#r!EZTMtTQd)O)VeI6O%NBj}K6-kJC{}$@;ZO}aeDri?tK~;BChK;^QyA*cpM37`) zZ8B>5yyHJTVJCLGt7#zPHy{*c<0ZPhH z3GKu_70BJeM+IUvr!A#uN-E2W?8iev{wOeThipX1WQ^?3jq8CF|7Fba&_JAjHD2F- x(-`v{b}Q$iQfn#mW_Qz#ejJjKQ-}1Y*^>%RtE+q`$>*6Q@wX?neJ$~F=pVYc=E?v7