diff --git a/MacPass/DatabaseSettingsWindow.xib b/MacPass/DatabaseSettingsWindow.xib index fd571e73..429b538c 100644 --- a/MacPass/DatabaseSettingsWindow.xib +++ b/MacPass/DatabaseSettingsWindow.xib @@ -100,7 +100,7 @@ {{13, 41}, {520, 246}} - + _NS:9 @@ -212,7 +212,7 @@ 2322 {278, 121} - + _NS:13 @@ -304,7 +304,7 @@ 256 {{263, 1}, {16, 121}} - + _NS:83 NO @@ -328,7 +328,7 @@ {{136, 17}, {280, 123}} - + _NS:9 133138 @@ -349,7 +349,7 @@ - + 256 @@ -357,7 +357,6 @@ 268 {{111, 140}, {68, 17}} - _NS:1535 YES @@ -382,7 +381,6 @@ {{181, 74}, {170, 26}} - _NS:9 YES @@ -407,7 +405,6 @@ 268 {{128, 78}, {51, 17}} - _NS:1535 YES @@ -428,8 +425,7 @@ 268 {{184, 51}, {164, 19}} - - + _NS:9 YES @@ -457,7 +453,6 @@ 268 {{356, 136}, {31, 25}} - _NS:22 YES @@ -486,7 +481,6 @@ 268 {{356, 75}, {31, 25}} - _NS:22 YES @@ -515,7 +509,6 @@ 268 {{184, 138}, {164, 22}} - _NS:9 YES @@ -540,7 +533,6 @@ 268 {{127, 108}, {52, 17}} - _NS:1535 YES @@ -561,7 +553,6 @@ 268 {{184, 106}, {164, 22}} - _NS:9 YES @@ -586,7 +577,6 @@ 268 {{198, 168}, {137, 17}} - _NS:1535 YES @@ -611,8 +601,6 @@ {{10, 33}, {500, 200}} - - Password @@ -738,7 +726,7 @@ 268 {{138, 38}, {107, 18}} - + _NS:9 YES @@ -829,7 +817,7 @@ 268 {{112, 37}, {187, 18}} - + _NS:9 YES @@ -1049,14 +1037,129 @@ + + + + 256 + + + + 268 + {{97, 114}, {121, 17}} + + + + _NS:1535 + YES + + 68157504 + 272630784 + Default Username: + + _NS:1535 + + + + + NO + + + + 268 + {{223, 111}, {178, 22}} + + + + _NS:9 + YES + + -1804599231 + 272630784 + + + _NS:9 + + YES + + + + NO + + + + 268 + {{220, 79}, {184, 26}} + + + + _NS:9 + YES + + -2076180416 + 2048 + + _NS:9 + + 109199360 + 129 + + + 400 + 75 + + YES + + OtherViews + + + + -1 + 1 + YES + YES + 2 + + NO + + + + 268 + {{107, 84}, {110, 17}} + + + + _NS:1535 + YES + + 68157504 + 272630784 + Template Group: + + _NS:1535 + + + + + NO + + + {{10, 33}, {500, 200}} + + + + + Templates + + + - + 0 YES YES - + @@ -1090,7 +1193,7 @@ - {{0, 0}, {1920, 1058}} + {{0, 0}, {2560, 1418}} {10000000000000, 10000000000000} YES @@ -1281,6 +1384,22 @@ 1202 + + + defaultUsernameTextField + + + + 1261 + + + + templateGroupPopUpButton + + + + 1262 + @@ -1480,6 +1599,7 @@ + @@ -2540,11 +2660,6 @@ - - 520 - - - 488 @@ -3502,6 +3617,301 @@ + + 1209 + + + + + 1210 + + + + + + + + 1211 + + + + + 5 + 0 + + 6 + 1 + + 8 + + 1000 + + 6 + 24 + 3 + + + + 6 + 0 + + 6 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + + + + 3 + 0 + + 4 + 1 + + 8 + + 1000 + + 6 + 24 + 3 + + + + 3 + 0 + + 3 + 1 + + 67 + + 1000 + + 3 + 9 + 3 + + + + 5 + 0 + + 6 + 1 + + 8 + + 1000 + + 6 + 24 + 3 + + + + 10 + 0 + + 10 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + + + + 10 + 0 + + 10 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + + + + 5 + 0 + + 5 + 1 + + 100 + + 1000 + + 3 + 9 + 3 + + + + + + + + + + 1212 + + + + + + + + 1213 + + + + + 1216 + + + + + + 7 + 0 + + 0 + 1 + + 178 + + 1000 + + 3 + 9 + 1 + + + + + + 1217 + + + + + 1225 + + + + + 1227 + + + + + 1228 + + + + + 1230 + + + + + + 7 + 0 + + 0 + 1 + + 179 + + 1000 + + 3 + 9 + 1 + + + + + + 1231 + + + + + + + + 1232 + + + + + + 1239 + + + + + + + + 1240 + + + + + 1253 + + + + + 1255 + + + + + 1256 + + + + + 1257 + + + + + 1258 + + + + + 1259 + + + + + 1260 + + + @@ -3578,6 +3988,49 @@ 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 + HNHRoundedTextField + + + + + 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 + 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 @@ -3647,7 +4100,7 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - + @@ -3685,7 +4138,6 @@ 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 @@ -3807,7 +4259,7 @@ - 1202 + 1262 @@ -3830,27 +4282,46 @@ ./Classes/HNHRoundedSecureTextField.h + + HNHRoundedTextField + NSTextField + + IBProjectSource + ./Classes/HNHRoundedTextField.h + + MPDatabaseSettingsWindowController NSWindowController id + id id + id clearKey: id + + close: + id + generateKey: id + + save: + id + NSButton NSTextView NSTextField + HNHRoundedTextField NSButton NSButton NSTextField @@ -3865,6 +4336,7 @@ NSButton NSTabView NSPopUpButton + NSPopUpButton NSButton @@ -3880,6 +4352,10 @@ databaseNameTextField NSTextField + + defaultUsernameTextField + HNHRoundedTextField + emptyRecycleBinOnQuitCheckButton NSButton @@ -3936,6 +4412,10 @@ selectRecycleBinGroupPopUpButton NSPopUpButton + + templateGroupPopUpButton + NSPopUpButton + togglePasswordButton NSButton diff --git a/MacPass/MPDatabaseSettingsWindowController.h b/MacPass/MPDatabaseSettingsWindowController.h index 72100b96..0e502773 100644 --- a/MacPass/MPDatabaseSettingsWindowController.h +++ b/MacPass/MPDatabaseSettingsWindowController.h @@ -12,13 +12,15 @@ typedef NS_ENUM(NSUInteger, MPDatabaseSettingsTab) { MPDatabaseSettingsTabGeneral, MPDatabaseSettingsTabPassword, MPDatabaseSettingsTabDisplay, - MPDatabaseSettingsTabAdvanced + MPDatabaseSettingsTabAdvanced, + MPDatabaseSettingsTemplatesTab, }; @class MPDocument; +@class HNHRoundendTextField; @class HNHRoundedSecureTextField; -@interface MPDatabaseSettingsWindowController : NSWindowController +@interface MPDatabaseSettingsWindowController : NSWindowController @property (weak) IBOutlet NSTabView *sectionTabView; @property (weak) IBOutlet NSButton *saveButton; @@ -51,6 +53,12 @@ typedef NS_ENUM(NSUInteger, MPDatabaseSettingsTab) { @property (weak) IBOutlet NSButton *emptyRecycleBinOnQuitCheckButton; @property (weak) IBOutlet NSPopUpButton *selectRecycleBinGroupPopUpButton; + +/* Templates Tab */ +@property (weak) IBOutlet HNHRoundendTextField *defaultUsernameTextField; +@property (weak) IBOutlet NSPopUpButton *templateGroupPopUpButton; + + - (id)initWithDocument:(MPDocument *)document; - (void)showSettingsTab:(MPDatabaseSettingsTab)tab; diff --git a/MacPass/MPDatabaseSettingsWindowController.m b/MacPass/MPDatabaseSettingsWindowController.m index b35f23b0..449eaaef 100644 --- a/MacPass/MPDatabaseSettingsWindowController.m +++ b/MacPass/MPDatabaseSettingsWindowController.m @@ -11,7 +11,9 @@ #import "MPDocumentWindowController.h" #import "MPDatabaseVersion.h" #import "MPIconHelper.h" +#import "MPSettingsHelper.h" +#import "HNHRoundedTextField.h" #import "HNHRoundedSecureTextField.h" #import "NSString+Empty.h" @@ -22,6 +24,7 @@ @interface MPDatabaseSettingsWindowController () { MPDocument *_document; + NSString *_missingFeature; } @property (nonatomic,assign) BOOL trashEnabled; @@ -43,6 +46,7 @@ _document = document; _showPassword = NO; _hasValidPasswordOrKey = NO; + _missingFeature = NSLocalizedString(@"KDBX_ONLX_FEATURE", "Feature only available in kdbx databases"); } return self; } @@ -55,16 +59,10 @@ [self.saveButton bind:NSEnabledBinding toObject:self withKeyPath:@"hasValidPasswordOrKey" options:nil]; [self.cancelButton bind:NSEnabledBinding toObject:self withKeyPath:@"hasValidPasswordOrKey" options:nil]; - Kdb4Tree *tree = _document.treeV4; - if( tree ) { - [self _setupDatabase:tree]; - [self _setupProtectionTab:tree]; - [self _setupAdvancedTab:tree]; - [self _setupPasswordTab:tree]; - } - else { - // Switch to KdbV3 View - } + [self.sectionTabView setDelegate:self]; + + + [self update]; } - (IBAction)save:(id)sender { @@ -81,15 +79,37 @@ /* Advanced */ _document.treeV4.recycleBinEnabled = self.trashEnabled; - NSMenuItem *menuItem = [self.selectRecycleBinGroupPopUpButton selectedItem]; - KdbGroup *group = [menuItem representedObject]; - [_document useGroupAsTrash:group]; + NSMenuItem *trashMenuItem = [self.selectRecycleBinGroupPopUpButton selectedItem]; + KdbGroup *trashGroup = [trashMenuItem representedObject]; + [_document useGroupAsTrash:trashGroup]; - _document.treeV4.protectNotes = [self.protectNotesCheckButton state] == NSOnState; - _document.treeV4.protectPassword = [self.protectPasswortCheckButton state] == NSOnState; - _document.treeV4.protectTitle = [self.protectTitleCheckButton state] == NSOnState; - _document.treeV4.protectUrl = [self.protectURLCheckButton state] == NSOnState; - _document.treeV4.protectUserName = [self.protectUserNameCheckButton state] == NSOnState; + NSMenuItem *templateMenuItem = [self.templateGroupPopUpButton selectedItem]; + KdbGroup *templateGroup = [templateMenuItem representedObject]; + [_document useGroupAsTemplate:templateGroup]; + + BOOL protectNotes = [self.protectNotesCheckButton state] == NSOnState; + BOOL protectPassword = [self.protectPasswortCheckButton state] == NSOnState; + BOOL protectTitle = [self.protectTitleCheckButton state] == NSOnState; + BOOL protectURL = [self.protectURLCheckButton state] == NSOnState; + BOOL protectUsername = [self.protectUserNameCheckButton state] == NSOnState; + + if(_document.version == MPDatabaseVersion4) { + _document.treeV4.protectNotes = protectNotes; + _document.treeV4.protectPassword = protectPassword; + _document.treeV4.protectTitle = protectTitle; + _document.treeV4.protectUrl = protectURL; + _document.treeV4.protectUserName = protectUsername; + + } + else { + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + [defaults setBool:protectNotes forKey:kMPSettingsKeyLegacyHideNotes]; + [defaults setBool:protectPassword forKey:kMPSettingsKeyLegacyHidePassword]; + [defaults setBool:protectTitle forKey:kMPSettingsKeyLegacyHideTitle]; + [defaults setBool:protectURL forKey:kMPSettingsKeyLegacyHideURL]; + [defaults setBool:protectUsername forKey:kMPSettingsKeyLegacyHideUsername]; + [defaults synchronize]; + } /* Close to finish */ [self close:nil]; @@ -104,16 +124,27 @@ - (void)update { /* Update all stuff that might have changed */ Kdb4Tree *tree = _document.treeV4; - if(tree) { - [self _setupDatabase:tree]; - [self _setupProtectionTab:tree]; - [self _setupAdvancedTab:tree]; - [self _setupPasswordTab:tree]; - } + [self _setupPasswordTab:tree]; + [self _setupDatabase:tree]; + [self _setupProtectionTab:tree]; + [self _setupAdvancedTab:tree]; + [self _setupTemplatesTab:tree]; } - (void)showSettingsTab:(MPDatabaseSettingsTab)tab { + /* + We need to make sure the window is loaded + so we just call the the getter and led teh loading commence + */ + if(![self window]) { + return; + } self.showPassword = NO; + NSTabViewItem *tabViewItem = [self.sectionTabView tabViewItemAtIndex:tab]; + BOOL canSelectTab = [self tabView:self.sectionTabView shouldSelectTabViewItem:tabViewItem]; + if(!canSelectTab) { + [self.sectionTabView selectTabViewItemAtIndex:MPDatabaseSettingsTabPassword]; + } [self.sectionTabView selectTabViewItemAtIndex:tab]; } @@ -139,11 +170,29 @@ - (IBAction)generateKey:(id)sender { } -#pragma makr NSTextFieldDelegate +#pragma mark NSTextFieldDelegate - (void)controlTextDidChange:(NSNotification *)obj { [self _verifyPasswordAndKey]; } +#pragma mark NSTableViewDelegate +- (BOOL)tabView:(NSTabView *)tabView shouldSelectTabViewItem:(NSTabViewItem *)tabViewItem { + NSUInteger index = [tabView indexOfTabViewItem:tabViewItem]; + switch ((MPDatabaseSettingsTab)index) { + case MPDatabaseSettingsTabPassword: + case MPDatabaseSettingsTabDisplay: + return YES; + + case MPDatabaseSettingsTabAdvanced: + case MPDatabaseSettingsTabGeneral: + case MPDatabaseSettingsTemplatesTab: + return (_document.version == MPDatabaseVersion4); + + default: + return NO; + } +} + #pragma mark Private Helper - (void)_verifyPasswordAndKey { NSString *password = [self.passwordTextField stringValue]; @@ -180,23 +229,48 @@ } - (void)_setupDatabase:(Kdb4Tree *)tree { - [self.databaseNameTextField setStringValue:tree.databaseName]; - [self.databaseDescriptionTextView setString:tree.databaseDescription]; + BOOL isKdbx = (nil != tree); + [self.databaseDescriptionTextView setEditable:isKdbx]; + [self.databaseNameTextField setEnabled:isKdbx]; + if(isKdbx) { + [self.databaseNameTextField setStringValue:tree.databaseName]; + [self.databaseDescriptionTextView setString:tree.databaseDescription]; + } + else { + [self.databaseNameTextField setStringValue:_missingFeature]; + [self.databaseDescriptionTextView setString:_missingFeature]; + } } - (void)_setupProtectionTab:(Kdb4Tree *)tree { - [self.protectNotesCheckButton setState:tree.protectNotes ? NSOnState : NSOffState ]; - [self.protectNotesCheckButton setState:tree.protectPassword ? NSOnState : NSOffState]; - [self.protectTitleCheckButton setState:tree.protectTitle ? NSOnState : NSOffState]; - [self.protectURLCheckButton setState:tree.protectUrl ? NSOnState : NSOffState]; - [self.protectUserNameCheckButton setState:tree.protectUserName ? NSOnState : NSOffState]; + BOOL isKdbX = (nil != tree); + + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + + BOOL protectNotes = isKdbX ? tree.protectNotes : [defaults boolForKey:kMPSettingsKeyLegacyHideNotes]; + BOOL protectPassword = isKdbX ? tree.protectPassword : [defaults boolForKey:kMPSettingsKeyLegacyHidePassword]; + BOOL protectTitle = isKdbX ? tree.protectTitle : [defaults boolForKey:kMPSettingsKeyLegacyHideTitle]; + BOOL protectUrl = isKdbX ? tree.protectUrl : [defaults boolForKey:kMPSettingsKeyLegacyHideURL]; + BOOL protectUsername = isKdbX ? tree.protectUserName : [defaults boolForKey:kMPSettingsKeyLegacyHideUsername]; + + [self.protectNotesCheckButton setState:protectNotes ? NSOnState : NSOffState ]; + [self.protectPasswortCheckButton setState:protectPassword ? NSOnState : NSOffState]; + [self.protectTitleCheckButton setState:protectTitle ? NSOnState : NSOffState]; + [self.protectURLCheckButton setState:protectUrl ? NSOnState : NSOffState]; + [self.protectUserNameCheckButton setState:protectUsername ? NSOnState : NSOffState]; } - (void)_setupAdvancedTab:(Kdb4Tree *)tree { - self.trashEnabled = tree.recycleBinEnabled; + BOOL isKdbX = (nil != tree); + + self.trashEnabled = isKdbX ? tree.recycleBinEnabled : NO; + [self.enableRecycleBinCheckButton bind:NSValueBinding toObject:self withKeyPath:@"trashEnabled" options:nil]; + [self.enableRecycleBinCheckButton setEnabled:isKdbX]; [self.selectRecycleBinGroupPopUpButton bind:NSEnabledBinding toObject:self withKeyPath:@"trashEnabled" options:nil]; - [self _updateTrashFolders:tree]; + if(isKdbX) { + [self _updateTrashFolders:tree]; + } } - (void)_setupPasswordTab:(Kdb4Tree *)tree { @@ -218,11 +292,40 @@ [self _verifyPasswordAndKey]; } +- (void)_setupTemplatesTab:(Kdb4Tree *)tree { + +} + - (void)_updateTrashFolders:(Kdb4Tree *)tree { NSMenu *menu = [self _buildTreeMenu:tree]; [self.selectRecycleBinGroupPopUpButton setMenu:menu]; } +- (void)_updateTemplateGroup:(Kdb4Tree *)tree { + // +} + +- (NSMenu *)_buildTrashTreeMenu:(Kdb4Tree *)tree { + NSMenu *menu = [self _buildTreeMenu:tree]; + + NSMenuItem *selectItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"SELECT_RECYCLEBIN", @"Menu item if no reycleBin is selected") action:NULL keyEquivalent:@""]; + [selectItem setEnabled:YES]; + [menu insertItem:selectItem atIndex:0]; + + return menu; +} + +- (NSMenu *)_buildTemplateTreeMenu:(Kdb4Tree *)tree { + NSMenu *menu = [self _buildTreeMenu:tree]; + + NSMenuItem *selectItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"SELECT_RECYCLEBIN", @"Menu item if no reycleBin is selected") action:NULL keyEquivalent:@""]; + [selectItem setEnabled:YES]; + [menu insertItem:selectItem atIndex:0]; + + return menu; +} + + - (NSMenu *)_buildTreeMenu:(Kdb4Tree *)tree { NSMenu *menu = [[NSMenu alloc] init]; [menu setAutoenablesItems:NO]; @@ -238,10 +341,7 @@ } [menu addItem:groupItem]; } - NSMenuItem *selectItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"SELECT_RECYCLEBIN", @"Menu item if no reycleBin is selected") action:NULL keyEquivalent:@""]; - [selectItem setEnabled:YES]; - [menu insertItem:selectItem atIndex:0]; - return menu; } + @end diff --git a/MacPass/MPDocument.h b/MacPass/MPDocument.h index ba50dd86..b97cbedd 100644 --- a/MacPass/MPDocument.h +++ b/MacPass/MPDocument.h @@ -66,6 +66,7 @@ APPKIT_EXTERN NSString *const MPDocumentGroupKey; - (Kdb3Tree *)treeV3; - (void)useGroupAsTrash:(KdbGroup *)group; +- (void)useGroupAsTemplate:(KdbGroup *)group; #pragma mark Export - (void)writeXMLToURL:(NSURL *)url; diff --git a/MacPass/MPDocument.m b/MacPass/MPDocument.m index c2df2f35..44fcd015 100644 --- a/MacPass/MPDocument.m +++ b/MacPass/MPDocument.m @@ -316,6 +316,13 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey"; } } +- (void)useGroupAsTemplate:(KdbGroup *)group { + Kdb4Group *groupv4 = (Kdb4Group *)group; + if([self.treeV4.entryTemplatesGroup isEqual:groupv4.uuid]) { + self.treeV4.entryTemplatesGroup = groupv4.uuid; + } +} + #pragma mark Data manipulation - (KdbEntry *)createEntry:(KdbGroup *)parent { if(!parent) { diff --git a/MacPass/MPDocumentWindowController.m b/MacPass/MPDocumentWindowController.m index 80d487ab..b2550046 100644 --- a/MacPass/MPDocumentWindowController.m +++ b/MacPass/MPDocumentWindowController.m @@ -363,12 +363,12 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur #pragma mark Helper - (void)_showDatabaseSetting:(MPDatabaseSettingsTab)tab { - if(!self.documentSettingsWindowController) { - _documentSettingsWindowController = [[MPDatabaseSettingsWindowController alloc] initWithDocument:[self document]]; - } - [self.documentSettingsWindowController update]; + if(!self.documentSettingsWindowController) { + _documentSettingsWindowController = [[MPDatabaseSettingsWindowController alloc] initWithDocument:[self document]]; + } + [self.documentSettingsWindowController update]; [self.documentSettingsWindowController showSettingsTab:tab]; - [[NSApplication sharedApplication] beginSheet:[self.documentSettingsWindowController window] modalForWindow:[self window] modalDelegate:nil didEndSelector:NULL contextInfo:NULL]; + [[NSApplication sharedApplication] beginSheet:[self.documentSettingsWindowController window] modalForWindow:[self window] modalDelegate:nil didEndSelector:NULL contextInfo:NULL]; } - (NSSearchField *)locateToolbarSearchField { diff --git a/MacPass/MPInspectorViewController.m b/MacPass/MPInspectorViewController.m index 4d515b45..0fef36dd 100644 --- a/MacPass/MPInspectorViewController.m +++ b/MacPass/MPInspectorViewController.m @@ -59,8 +59,8 @@ enum { @property (strong) NSPopover *activePopover; @property (weak) IBOutlet NSButton *generatePasswordButton; -@property (nonatomic, weak) NSDate *modificationDate; -@property (nonatomic, weak) NSDate *creationDate; +@property (nonatomic, strong) NSDate *modificationDate; +@property (nonatomic, strong) NSDate *creationDate; @property (nonatomic, assign) BOOL showPassword; @@ -137,25 +137,32 @@ enum { } - (void)setModificationDate:(NSDate *)modificationDate { - NSString *modificationString = [NSDateFormatter localizedStringFromDate:modificationDate - dateStyle:NSDateFormatterShortStyle - timeStyle:NSDateFormatterShortStyle]; - - modificationString = [modificationDate humanized]; - - NSString *modifedAtTemplate = NSLocalizedString(@"MODIFED_AT_%@", @"Modifed at template string. %@ is replaced by locaized date and time"); - [self.modifiedTextField setStringValue:[NSString stringWithFormat:modifedAtTemplate, modificationString]]; - + _modificationDate = modificationDate; + [self _updateDateStrings]; } - (void)setCreationDate:(NSDate *)creationDate { - NSString *creationString = [NSDateFormatter localizedStringFromDate:creationDate - dateStyle:NSDateFormatterShortStyle - timeStyle:NSDateFormatterShortStyle]; - creationString = [creationDate humanized]; + _creationDate = creationDate; + [self _updateDateStrings]; +} + +- (void)_updateDateStrings { + if(!self.creationDate || !self.modificationDate ) { + [self.modifiedTextField setStringValue:@""]; + [self.createdTextField setStringValue:@""]; + return; // No dates, just clear + } + + NSString *creationString = [self.creationDate humanized]; + NSString *modificationString = [self.modificationDate humanized]; + + NSString *modifedAtTemplate = NSLocalizedString(@"MODIFED_AT_%@", @"Modifed at template string. %@ is replaced by locaized date and time"); NSString *createdAtTemplate = NSLocalizedString(@"CREATED_AT_%@", @"Created at template string. %@ is replaced by locaized date and time"); + + [self.modifiedTextField setStringValue:[NSString stringWithFormat:modifedAtTemplate, modificationString]]; [self.createdTextField setStringValue:[NSString stringWithFormat:createdAtTemplate, creationString]]; + } - (void)_updateContent { diff --git a/MacPass/MPOutlineViewController.h b/MacPass/MPOutlineViewController.h index 197abc4a..c6f59437 100644 --- a/MacPass/MPOutlineViewController.h +++ b/MacPass/MPOutlineViewController.h @@ -19,7 +19,7 @@ APPKIT_EXTERN NSString *const MPOutlineViewDidChangeGroupSelection; @property (readonly, weak) NSOutlineView *outlineView; @property (weak) IBOutlet HNHGradientView *bottomBar; -@property (weak, readonly) KdbGroup *selectedGroup; +@property (weak, readonly, nonatomic) KdbGroup *selectedGroup; - (void)clearSelection; - (void)showOutline; diff --git a/MacPass/MPOutlineViewController.m b/MacPass/MPOutlineViewController.m index 719b6859..8868d6df 100644 --- a/MacPass/MPOutlineViewController.m +++ b/MacPass/MPOutlineViewController.m @@ -33,7 +33,7 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell"; } @property (weak) IBOutlet NSOutlineView *outlineView; @property (weak) IBOutlet NSButton *addGroupButton; -@property (weak) KdbGroup *selectedGroup; +@property (nonatomic, weak) KdbGroup *selectedGroup; @property (strong) NSTreeController *treeController; @property (strong) MPOutlineDataSource *datasource; @@ -89,6 +89,29 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell"; [_outlineView expandItem:node expandChildren:YES]; } +#pragma mark Custom Setter/Getter +- (void)setDatabaseNameWrapper:(NSString *)databaseNameWrapper { + if(![_databaseNameWrapper isEqualToString:databaseNameWrapper]) { + if([databaseNameWrapper length] == 0) { + _databaseNameWrapper = NSLocalizedString(@"DATABASE", "Default name database"); + } + else { + _databaseNameWrapper= [databaseNameWrapper copy]; + } + } +} + +//- (void)setSelectedGroup:(KdbGroup *)selectedGroup { +// if(_selectedGroup != selectedGroup) { +// _selectedGroup = selectedGroup; +// if([selectedGroup isKindOfClass:[Kdb4Group class]]) { +// MPDocument *document = [[self windowController] document]; +// document.treeV4.lastSelectedGroup = ((Kdb4Group *)selectedGroup).uuid; +// } +// } +//} + + #pragma mark Notifications - (void)setupNotifications:(MPDocumentWindowController *)windowController { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_didCreateGroup:) name:MPDocumentDidAddGroupNotification object:[windowController document]]; @@ -114,17 +137,6 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell"; } } -- (void)setDatabaseNameWrapper:(NSString *)databaseNameWrapper { - if(![_databaseNameWrapper isEqualToString:databaseNameWrapper]) { - if([databaseNameWrapper length] == 0) { - _databaseNameWrapper = NSLocalizedString(@"DATABASE", "Default name database"); - } - else { - _databaseNameWrapper= [databaseNameWrapper copy]; - } - } -} - #pragma mark - #pragma mark Actions diff --git a/MacPass/MPSettingsHelper.h b/MacPass/MPSettingsHelper.h index 2e7cdf47..b0d2db9a 100644 --- a/MacPass/MPSettingsHelper.h +++ b/MacPass/MPSettingsHelper.h @@ -26,10 +26,16 @@ APPKIT_EXTERN NSString *const kMPSettingsKeyShowMenuItem; APPKIT_EXTERN NSString *const kMPSettingsKeyLockOnSleep; APPKIT_EXTERN NSString *const kMPSettingsKeyIdleLockTimeOut; - /* Autosaving states */ APPKIT_EXTERN NSString *const kMPSettingsKeyShowInspector; +/* Kdb Hide/Show settings */ +APPKIT_EXTERN NSString *const kMPSettingsKeyLegacyHideTitle; +APPKIT_EXTERN NSString *const kMPSettingsKeyLegacyHideUsername; +APPKIT_EXTERN NSString *const kMPSettingsKeyLegacyHidePassword; +APPKIT_EXTERN NSString *const kMPSettingsKeyLegacyHideNotes; +APPKIT_EXTERN NSString *const kMPSettingsKeyLegacyHideURL; + typedef NS_ENUM(NSUInteger, MPPasswordEncoding) { MPPasswordEncodingUTF8, MPPasswordEncodingASCII, diff --git a/MacPass/MPSettingsHelper.m b/MacPass/MPSettingsHelper.m index 49db03d5..565a5cb1 100644 --- a/MacPass/MPSettingsHelper.m +++ b/MacPass/MPSettingsHelper.m @@ -19,6 +19,13 @@ NSString *const kMPSettingsKeyLockOnSleep = @"LockOnSleep"; NSString *const kMPSettingsKeyIdleLockTimeOut = @"IdleLockTimeOut"; NSString *const kMPSettingsKeyShowInspector = @"ShowInspector"; +NSString *const kMPSettingsKeyLegacyHideTitle = @"LegacyHideTitle"; +NSString *const kMPSettingsKeyLegacyHideUsername = @"LegacyHideUsername "; +NSString *const kMPSettingsKeyLegacyHidePassword = @"LegacyHidePassword"; +NSString *const kMPSettingsKeyLegacyHideNotes = @"LegacyHideNotes"; +NSString *const kMPSettingsKeyLegacyHideURL = @"LegacyHideURL"; + + @implementation MPSettingsHelper + (void)setupDefaults { @@ -36,7 +43,12 @@ NSString *const kMPSettingsKeyShowInspector = @"ShowInspector"; kMPSettingsKeyEnableHttpServer: @NO, kMPSettingsKeyShowMenuItem: @YES, kMPSettingsKeyLockOnSleep: @YES, - kMPSettingsKeyIdleLockTimeOut: @0 // 5 minutes + kMPSettingsKeyIdleLockTimeOut: @0, // 5 minutes + kMPSettingsKeyLegacyHideNotes: @NO, + kMPSettingsKeyLegacyHidePassword: @YES, + kMPSettingsKeyLegacyHideTitle: @NO, + kMPSettingsKeyLegacyHideURL: @NO, + kMPSettingsKeyLegacyHideUsername: @NO }; } diff --git a/MacPass/NSDate+Humanized.m b/MacPass/NSDate+Humanized.m index b61fc974..7f3db0fa 100644 --- a/MacPass/NSDate+Humanized.m +++ b/MacPass/NSDate+Humanized.m @@ -16,15 +16,38 @@ - (NSString *)humanized { NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; - NSDateComponents *components = [calendar components:NSMinuteCalendarUnit|NSHourCalendarUnit|NSDayCalendarUnit fromDate:self toDate:[NSDate date] options:0]; - if([components day] > 1) { + NSDateComponents *components = [calendar components:NSMinuteCalendarUnit|NSHourCalendarUnit|NSDayCalendarUnit|NSWeekCalendarUnit|NSMonthCalendarUnit fromDate:self toDate:[NSDate date] options:0]; + /* More than one month in the past, give full date */ + if([components month] > 1) { return [NSDateFormatter localizedStringFromDate:self dateStyle:NSDateFormatterShortStyle timeStyle:NSDateFormatterShortStyle]; } - if([components day] == 1) { + NSUInteger weeks = [components week]; + /* More than one week, less than a month */ + if(weeks > 1) { + NSString *weekTemplate = NSLocalizedString(@"%ld_WEEKS_AGO", "% Weeks ago"); + return [NSString stringWithFormat:weekTemplate, weeks]; + } + /* One week or more */ + if( weeks == 1) { + return NSLocalizedString(@"ONE_WEEK_AGO", "one week ago"); + } + /* Last week */ + NSUInteger days = [components day]; + if(days > 3) { + return NSLocalizedString(@"LAST_WEEK", "last week"); + } + /* 1-3 days */ + if(days > 1 ) { + NSString *daysTemplate = NSLocalizedString(@"%ld_DAYS_AGO", "% days ago"); + return [NSString stringWithFormat:daysTemplate, days]; + } + /* Yesterday */ + if(days == 1) { return NSLocalizedString(@"YESTERDAY", "Yesterday"); } + /* Hours ago */ if([components hour] > 1) { NSString *hourTemplate = NSLocalizedString(@"%ld_HOURS_AGO", "% Hours ago"); return [NSString stringWithFormat:hourTemplate, [components hour]]; diff --git a/MacPass/de.lproj/Localizable.strings b/MacPass/de.lproj/Localizable.strings index b0bb4851..c7515ddd 100644 Binary files a/MacPass/de.lproj/Localizable.strings and b/MacPass/de.lproj/Localizable.strings differ diff --git a/MacPass/en.lproj/Localizable.strings b/MacPass/en.lproj/Localizable.strings index 670f0205..70ad69a1 100644 Binary files a/MacPass/en.lproj/Localizable.strings and b/MacPass/en.lproj/Localizable.strings differ