diff --git a/MacPass.xcodeproj/project.pbxproj b/MacPass.xcodeproj/project.pbxproj index ab695197..8b75ad7c 100644 --- a/MacPass.xcodeproj/project.pbxproj +++ b/MacPass.xcodeproj/project.pbxproj @@ -10,6 +10,7 @@ 4C01C23F1764D2980016D5D0 /* KdbEntry+Undo.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C01C23E1764D2980016D5D0 /* KdbEntry+Undo.m */; }; 4C01C2421764D8980016D5D0 /* MPContextMenuHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C01C2411764D8980016D5D0 /* MPContextMenuHelper.m */; }; 4C01C245176500C40016D5D0 /* HNHLevelIndicatorCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C01C244176500C40016D5D0 /* HNHLevelIndicatorCell.m */; }; + 4C10412C178CDD44001B5239 /* NSDate+Humanized.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C10412B178CDD44001B5239 /* NSDate+Humanized.m */; }; 4C16BA6217879A3C002B42BD /* MPPasswordStringFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C16BA6117879A3C002B42BD /* MPPasswordStringFormatter.m */; }; 4C1DDCDD1711ECEB00C98DA3 /* PasswordCreatorWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C1DDCDC1711ECEB00C98DA3 /* PasswordCreatorWindow.xib */; }; 4C22040D1746ED160054C916 /* KdbGroup+Undo.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C22040C1746ED160054C916 /* KdbGroup+Undo.m */; }; @@ -209,6 +210,8 @@ 4C01C2411764D8980016D5D0 /* MPContextMenuHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPContextMenuHelper.m; sourceTree = ""; }; 4C01C243176500C40016D5D0 /* HNHLevelIndicatorCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HNHLevelIndicatorCell.h; sourceTree = ""; }; 4C01C244176500C40016D5D0 /* HNHLevelIndicatorCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HNHLevelIndicatorCell.m; sourceTree = ""; }; + 4C10412A178CDD44001B5239 /* NSDate+Humanized.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDate+Humanized.h"; sourceTree = ""; }; + 4C10412B178CDD44001B5239 /* NSDate+Humanized.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDate+Humanized.m"; sourceTree = ""; }; 4C16BA6017879A3C002B42BD /* MPPasswordStringFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPasswordStringFormatter.h; sourceTree = ""; }; 4C16BA6117879A3C002B42BD /* MPPasswordStringFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPPasswordStringFormatter.m; sourceTree = ""; }; 4C1DDCDC1711ECEB00C98DA3 /* PasswordCreatorWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PasswordCreatorWindow.xib; sourceTree = ""; }; @@ -614,6 +617,15 @@ name = Views; sourceTree = ""; }; + 4C104129178CDD26001B5239 /* Categories */ = { + isa = PBXGroup; + children = ( + 4C10412A178CDD44001B5239 /* NSDate+Humanized.h */, + 4C10412B178CDD44001B5239 /* NSDate+Humanized.m */, + ); + name = Categories; + sourceTree = ""; + }; 4C16BA5F1787997E002B42BD /* ValueTransformer */ = { isa = PBXGroup; children = ( @@ -1050,6 +1062,7 @@ 4C77E36C15B84A240093A587 /* MacPass */ = { isa = PBXGroup; children = ( + 4C104129178CDD26001B5239 /* Categories */, 4C245C11176E22150086100E /* KeepassHttp */, 4C46B8821706397A0046109A /* Security Additions */, 4C2C4C2516D3BCEA00D49295 /* KeePassLib Categories */, @@ -1535,6 +1548,7 @@ 4C3666411787327E00B249F1 /* MPDocument+Attachments.m in Sources */, 4C16BA6217879A3C002B42BD /* MPPasswordStringFormatter.m in Sources */, 4CD6C5AE1789FDE6000891F6 /* HNHRoundedSecureTextField.m in Sources */, + 4C10412C178CDD44001B5239 /* NSDate+Humanized.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/MacPass/Kdb3Tree+NewTree.m b/MacPass/Kdb3Tree+NewTree.m index 6d894775..f880401f 100644 --- a/MacPass/Kdb3Tree+NewTree.m +++ b/MacPass/Kdb3Tree+NewTree.m @@ -18,32 +18,32 @@ tree.root = rootGroup; KdbGroup *parentGroup = [tree createGroup:rootGroup]; - parentGroup.name = @"General"; + parentGroup.name = NSLocalizedString(@"GENERAL", "General"); parentGroup.image = 48; [rootGroup addGroup:parentGroup]; KdbGroup *group = [tree createGroup:parentGroup]; - group.name = @"Windows"; + group.name = NSLocalizedString(@"WINDOWS", "Windows"); group.image = 38; [parentGroup addGroup:group]; group = [tree createGroup:parentGroup]; - group.name = @"Network"; + group.name = NSLocalizedString(@"NETWORK", "Network"); group.image = 3; [parentGroup addGroup:group]; group = [tree createGroup:parentGroup]; - group.name = @"Internet"; + group.name = NSLocalizedString(@"INTERNET", "Internet"); group.image = 1; [parentGroup addGroup:group]; group = [tree createGroup:parentGroup]; - group.name = @"eMail"; + group.name = NSLocalizedString(@"EMAIL", "EMail"); group.image = 19; [parentGroup addGroup:group]; group = [tree createGroup:parentGroup]; - group.name = @"Homebanking"; + group.name = NSLocalizedString(@"HOMEBANKING", "Homebanking"); group.image = 37; [parentGroup addGroup:group]; diff --git a/MacPass/Kdb4Tree+NewTree.m b/MacPass/Kdb4Tree+NewTree.m index d1d82c24..3ddfe579 100644 --- a/MacPass/Kdb4Tree+NewTree.m +++ b/MacPass/Kdb4Tree+NewTree.m @@ -15,7 +15,7 @@ Kdb4Tree *tree = [[Kdb4Tree alloc] init]; tree.generator = @"MacPass"; - tree.databaseName = NSLocalizedString(@"NEW_DATABASE", "Name for a newly created Database"); + tree.databaseName = NSLocalizedString(@"DATABASE", ""); tree.databaseNameChanged = currentTime; tree.databaseDescription = @""; tree.databaseDescriptionChanged = currentTime; @@ -42,32 +42,32 @@ tree.lastTopVisibleGroup = [UUID nullUuid]; KdbGroup *parentGroup = [tree createGroup:nil]; - parentGroup.name = @"General"; + parentGroup.name = NSLocalizedString(@"GENERAL", "General"); parentGroup.image = 48; tree.root = parentGroup; KdbGroup *group = [tree createGroup:parentGroup]; - group.name = @"Windows"; + group.name = NSLocalizedString(@"WINDOWS", "Windows"); group.image = 38; [parentGroup addGroup:group]; group = [tree createGroup:parentGroup]; - group.name = @"Network"; + group.name = NSLocalizedString(@"NETWORK", "Network"); group.image = 3; [parentGroup addGroup:group]; group = [tree createGroup:parentGroup]; - group.name = @"Internet"; + group.name = NSLocalizedString(@"INTERNET", "Internet"); group.image = 1; [parentGroup addGroup:group]; group = [tree createGroup:parentGroup]; - group.name = @"eMail"; + group.name = NSLocalizedString(@"EMAIL", "EMail"); group.image = 19; [parentGroup addGroup:group]; group = [tree createGroup:parentGroup]; - group.name = @"Homebanking"; + group.name = NSLocalizedString(@"HOMEBANKING", "Homebanking"); group.image = 37; [parentGroup addGroup:group]; diff --git a/MacPass/KdbEntry+Undo.m b/MacPass/KdbEntry+Undo.m index 0b05b7c9..d0c78ed3 100644 --- a/MacPass/KdbEntry+Undo.m +++ b/MacPass/KdbEntry+Undo.m @@ -122,7 +122,7 @@ if(![[self undoManager] isUndoing]) {\ [[self undoManager] setActionName:NSLocalizedString(@"DELETE_ENTRY", "Set Title")]; } - [[NSNotificationCenter defaultCenter] postNotificationName:@"" object:self userInfo:nil]; + //[[NSNotificationCenter defaultCenter] postNotificationName:@"" object:self userInfo:nil]; [self.parent removeObjectFromEntriesAtIndex:oldIndex]; } @@ -131,7 +131,7 @@ if(![[self undoManager] isUndoing]) {\ } - (void)moveToTrashUndoable:(KdbGroup *)trash atIndex:(NSUInteger)index { - [self _moveToGroup:trash atIndex:index actionName:NSLocalizedString(@"MOVE_ENTRY_TO_TRASH", "Move Entryo to Trash")]; + [self _moveToGroup:trash atIndex:index actionName:NSLocalizedString(@"TRASH_ENTRY", "Move Entry to Trash")]; } - (void)_moveToGroup:(KdbGroup *)group atIndex:(NSUInteger)index actionName:(NSString *)name { @@ -149,6 +149,8 @@ if(![[self undoManager] isUndoing]) {\ } [self.parent removeObjectFromEntriesAtIndex:oldIndex]; + // Old indices might be wrong, correct them if necessary + index = MIN(index, [group.entries count]); [group insertObject:self inEntriesAtIndex:index]; } diff --git a/MacPass/KdbGroup+Undo.h b/MacPass/KdbGroup+Undo.h index 294925a6..0c50243b 100644 --- a/MacPass/KdbGroup+Undo.h +++ b/MacPass/KdbGroup+Undo.h @@ -22,6 +22,5 @@ APPKIT_EXTERN NSString *const MPGroupNameUndoableKey; - (void)addEntryUndoable:(KdbEntry *)entry atIndex:(NSUInteger)index; - (void)moveToGroupUndoable:(KdbGroup *)group atIndex:(NSUInteger)index; - (void)moveToTrashUndoable:(KdbGroup *)trash atIndex:(NSUInteger)index; -- (void)restoreFromTrashUndoable:(KdbGroup *)group atIndex:(NSUInteger)index; @end diff --git a/MacPass/KdbGroup+Undo.m b/MacPass/KdbGroup+Undo.m index 51ad1b96..6e7319f2 100644 --- a/MacPass/KdbGroup+Undo.m +++ b/MacPass/KdbGroup+Undo.m @@ -10,13 +10,6 @@ #import "KdbGroup+KVOAdditions.h" #import "KdbEntry+Undo.h" -#ifndef MPSetActionName -#define MPSetActionName(key, comment) \ -if(![[self undoManager] isUndoing]) {\ -[[self undoManager] setActionName:[[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:nil]];\ -} -#endif - NSString *const MPGroupNameUndoableKey = @"nameUndoable"; @implementation KdbGroup (Undo) @@ -31,7 +24,11 @@ NSString *const MPGroupNameUndoableKey = @"nameUndoable"; - (void)setNameUndoable:(NSString *)newName { [[self undoManager] registerUndoWithTarget:self selector:@selector(setNameUndoable:) object:self.name]; - MPSetActionName(@"SET_NAME", "Set Name") + + if(![[self undoManager] isUndoing]) { + [[self undoManager] setActionName:NSLocalizedString(@"SET_NAME", "Set Name")]; + } + self.name = newName; } @@ -44,19 +41,26 @@ NSString *const MPGroupNameUndoableKey = @"nameUndoable"; return; // Inconsistent data } [[[self undoManager] prepareWithInvocationTarget:self.parent] addGroupUndoable:self atIndex:oldIndex]; - MPSetActionName(@"DELETE_GROUP", "Delete Group") - [self.parent removeObjectFromGroupsAtIndex:[self.parent.groups indexOfObject:self]]; + + if(![[self undoManager] isUndoing]) { + [[self undoManager] setActionName:NSLocalizedString(@"DELETE_GROUP", "Delete Group")]; + } + + [self.parent removeObjectFromGroupsAtIndex:oldIndex]; } - (void)addGroupUndoable:(KdbGroup *)group atIndex:(NSUInteger)index { if(!group) { return; } - if(index < [group.groups count]) { - return; // Wrong index! - } + [[[self undoManager] prepareWithInvocationTarget:group] deleteUndoable]; - MPSetActionName(@"ADD_GROUP", "Add Group") + + if(![[self undoManager] isUndoing]) { + [[self undoManager] setActionName:NSLocalizedString(@"ADD_GROUP", "Add Group")]; + } + + index = MIN(index, [group.groups count]); [self insertObject:group inGroupsAtIndex:index]; } @@ -64,53 +68,40 @@ NSString *const MPGroupNameUndoableKey = @"nameUndoable"; if(!entry) { return; } - if(index > [self.entries count]) { - return; // Wrong index! - } + index = MIN(index, [self.entries count]); [[[self undoManager] prepareWithInvocationTarget:entry] deleteUndoable]; - MPSetActionName(@"ADD_ENTRY", "Add Entry") + + if(![[self undoManager] isUndoing]) { + [[self undoManager] setActionName:NSLocalizedString(@"ADD_ENTRY", "Add Entry")]; + } + [self insertObject:entry inEntriesAtIndex:index]; } - (void)moveToGroupUndoable:(KdbGroup *)group atIndex:(NSUInteger)index { - if(!self.parent || !group) { - return; // No target or origin - } - NSUInteger oldIndex = [self.parent.groups indexOfObject:self]; - if(index == NSNotFound) { - return; // We aren't in our parents groups list. - } - [[[self undoManager] prepareWithInvocationTarget:self] moveToGroupUndoable:self.parent atIndex:oldIndex]; - MPSetActionName(@"MOVE_GROUP", "Move Group") - [self.parent removeObjectFromGroupsAtIndex:oldIndex]; - [group insertObject:self inGroupsAtIndex:index]; + [self _moveToGroup:group atIndex:index actionName:NSLocalizedString(@"MOVE_GROUP", "Move Group" )]; } - (void)moveToTrashUndoable:(KdbGroup *)trash atIndex:(NSUInteger)index { - if(!self.parent || !trash) { - return; // No target or origin - } - NSUInteger oldIndex = [self.parent.groups indexOfObject:self]; - if(index == NSNotFound) { - return; // We aren't in our parents groups list. - } - [[[self undoManager] prepareWithInvocationTarget:self] restoreFromTrashUndoable:self.parent atIndex:oldIndex]; - MPSetActionName(@"MOVE_TO_TRASH", @"Move to Trash") - [self.parent removeObjectFromGroupsAtIndex:oldIndex]; - [trash insertObject:self inGroupsAtIndex:index]; + [self _moveToGroup:trash atIndex:index actionName:NSLocalizedString(@"TRASH_GROUP", "Move Group to Trash")]; } -- (void)restoreFromTrashUndoable:(KdbGroup *)group atIndex:(NSUInteger)index { +- (void)_moveToGroup:(KdbGroup *)group atIndex:(NSUInteger)index actionName:(NSString *)actionName { if(!self.parent || !group) { return; // No target or origin } NSUInteger oldIndex = [self.parent.groups indexOfObject:self]; - if(index == NSNotFound) { + if(oldIndex == NSNotFound) { return; // We aren't in our parents groups list. } - [[[self undoManager] prepareWithInvocationTarget:self] moveToTrashUndoable:self.parent atIndex:oldIndex]; - MPSetActionName(@"RESTORE_GROUP", "Restore from Trash") + [[[self undoManager] prepareWithInvocationTarget:self] moveToGroupUndoable:self.parent atIndex:oldIndex]; + + if(![[self undoManager] isUndoing]) { + [[self undoManager] setActionName:actionName]; + } + [self.parent removeObjectFromGroupsAtIndex:oldIndex]; + index = MIN(index, [group.groups count]); [group insertObject:self inGroupsAtIndex:index]; } diff --git a/MacPass/MPDocument.m b/MacPass/MPDocument.m index a5a2ce6c..5d126f82 100644 --- a/MacPass/MPDocument.m +++ b/MacPass/MPDocument.m @@ -408,14 +408,23 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey"; #pragma mark Actions - (void)emptyTrash:(id)sender { - for(KdbEntry *entry in [self.trash childEntries]) { - [[self undoManager] removeAllActionsWithTarget:entry]; - } - for(KdbGroup *group in [self.trash childGroups]) { - [[self undoManager] removeAllActionsWithTarget:group]; - } + NSAlert *alert = [[NSAlert alloc] init]; + [alert setAlertStyle:NSWarningAlertStyle]; + [alert setMessageText:NSLocalizedString(@"WARNING_ON_EMPTY_TRASH_TITLE", "")]; + [alert setInformativeText:NSLocalizedString(@"WARNING_ON_EMPTY_TRASH_DESCRIPTION", "Informative Text displayed when clearing the Trash")]; + [alert addButtonWithTitle:NSLocalizedString(@"EMPTY_TRASH", "Empty Trash")]; + [alert addButtonWithTitle:NSLocalizedString(@"CANCEL", "Cancel")]; - [self.trash clear]; + [[alert buttons][1] setKeyEquivalent:[NSString stringWithFormat:@"%c", 0x1b]]; + + NSWindow *window = [[self windowControllers][0] window]; + [alert beginSheetModalForWindow:window modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:NULL]; +} + +- (void) alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo { + if(returnCode == NSAlertFirstButtonReturn) { + [self _emptyTrash]; + } } - (BOOL)validateMenuItem:(NSMenuItem *)menuItem { @@ -448,7 +457,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey"; } else if(self.version == MPDatabaseVersion4) { KdbGroup *trash = [self.tree createGroup:self.tree.root]; - trash.name = NSLocalizedString(@"TRASH_GROUP", @"Name for the trash group"); + trash.name = NSLocalizedString(@"TRASH", @"Name for the trash group"); trash.image = MPIconTrash; [self.tree.root insertObject:trash inGroupsAtIndex:[self.tree.root.groups count]]; self.treeV4.recycleBinUuid = ((Kdb4Group *)trash).uuid; @@ -460,4 +469,14 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey"; } } +- (void)_emptyTrash { + for(KdbEntry *entry in [self.trash childEntries]) { + [[self undoManager] removeAllActionsWithTarget:entry]; + } + for(KdbGroup *group in [self.trash childGroups]) { + [[self undoManager] removeAllActionsWithTarget:group]; + } + [self.trash clear]; +} + @end diff --git a/MacPass/MPInspectorViewController.m b/MacPass/MPInspectorViewController.m index 3f20930e..a31cdfbf 100644 --- a/MacPass/MPInspectorViewController.m +++ b/MacPass/MPInspectorViewController.m @@ -21,6 +21,8 @@ #import "MPCustomFieldTableCellView.h" #import "MPSelectedAttachmentTableCellView.h" +#import "NSDate+Humanized.h" + #import "KdbLib.h" #import "Kdb4Node.h" #import "Kdb3Node.h" @@ -128,6 +130,9 @@ enum { 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]]; @@ -137,6 +142,7 @@ enum { NSString *creationString = [NSDateFormatter localizedStringFromDate:creationDate dateStyle:NSDateFormatterShortStyle timeStyle:NSDateFormatterShortStyle]; + creationString = [creationDate humanized]; NSString *createdAtTemplate = NSLocalizedString(@"CREATED_AT_%@", @"Created at template string. %@ is replaced by locaized date and time"); [self.createdTextField setStringValue:[NSString stringWithFormat:createdAtTemplate, creationString]]; diff --git a/MacPass/MPOutlineViewController.m b/MacPass/MPOutlineViewController.m index cd8184fc..719b6859 100644 --- a/MacPass/MPOutlineViewController.m +++ b/MacPass/MPOutlineViewController.m @@ -39,6 +39,8 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell"; @property (strong) MPOutlineDataSource *datasource; @property (strong) NSMenu *menu; +@property (copy, nonatomic) NSString *databaseNameWrapper; + @end @implementation MPOutlineViewController @@ -53,6 +55,7 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell"; _treeController = [[NSTreeController alloc] init]; _bindingEstablished = NO; _datasource = [[MPOutlineDataSource alloc] init]; + _databaseNameWrapper = NSLocalizedString(@"NEW_DATABASE", "Name for a newly created Database"); } return self; @@ -76,6 +79,9 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell"; [_treeController setChildrenKeyPath:@"groups"]; [_treeController bind:NSContentBinding toObject:document withKeyPath:@"rootAdapter" options:nil]; [_outlineView bind:NSContentBinding toObject:_treeController withKeyPath:@"arrangedObjects" options:nil]; + if([document.tree respondsToSelector:@selector(databaseName)]) { + [self bind:@"databaseNameWrapper" toObject:document.tree withKeyPath:@"databaseName" options:nil]; + } [_outlineView setDataSource:self.datasource]; _bindingEstablished = YES; } @@ -83,7 +89,7 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell"; [_outlineView expandItem:node expandChildren:YES]; } -#pragma makr Notifications +#pragma mark Notifications - (void)setupNotifications:(MPDocumentWindowController *)windowController { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_didCreateGroup:) name:MPDocumentDidAddGroupNotification object:[windowController document]]; } @@ -108,6 +114,17 @@ 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 @@ -135,13 +152,7 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell"; if( [self _itemIsRootNodeAdapter:item] ) { //NSDictionary *options = @{ NSValueTransformerBindingOption : [NSValueTransformer valueTransformerForName:MPUppsercaseStringValueTransformerName] }; view = [outlineView makeViewWithIdentifier:_MPOutlinveViewHeaderViewIdentifier owner:self]; - MPRootAdapter *rootNode = [item representedObject]; - if([rootNode.tree respondsToSelector:@selector(databaseName)]) { - [view.textField bind:NSValueBinding toObject:rootNode.tree withKeyPath:@"databaseName" options:nil]; - } - else { - [view.textField setStringValue:NSLocalizedString(@"GROUPS", @"")]; - } + [view.textField bind:NSValueBinding toObject:self withKeyPath:@"databaseNameWrapper" options:nil]; } else { KdbGroup *group = [item representedObject]; diff --git a/MacPass/MacPass-Info.plist b/MacPass/MacPass-Info.plist index 80ee4e2e..778f4edc 100644 --- a/MacPass/MacPass-Info.plist +++ b/MacPass/MacPass-Info.plist @@ -48,7 +48,7 @@ CFBundleSignature ???? CFBundleVersion - 2335 + 2383 LSMinimumSystemVersion ${MACOSX_DEPLOYMENT_TARGET} NSHumanReadableCopyright diff --git a/MacPass/NSDate+Humanized.h b/MacPass/NSDate+Humanized.h new file mode 100644 index 00000000..badd765c --- /dev/null +++ b/MacPass/NSDate+Humanized.h @@ -0,0 +1,16 @@ +// +// NSDate+Humanized.h +// MacPass +// +// Created by Michael Starke on 10.07.13. +// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved. +// + +#import + +@interface NSDate (Humanized) + ++ (NSString *)humanizedDate:(NSDate *)date; +- (NSString *)humanized; + +@end diff --git a/MacPass/NSDate+Humanized.m b/MacPass/NSDate+Humanized.m new file mode 100644 index 00000000..b61fc974 --- /dev/null +++ b/MacPass/NSDate+Humanized.m @@ -0,0 +1,39 @@ +// +// NSDate+Humanized.m +// MacPass +// +// Created by Michael Starke on 10.07.13. +// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved. +// + +#import "NSDate+Humanized.h" + +@implementation NSDate (Humanized) + ++ (NSString *)humanizedDate:(NSDate *)date { + return [date humanized]; +} + +- (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) { + return [NSDateFormatter localizedStringFromDate:self + dateStyle:NSDateFormatterShortStyle + timeStyle:NSDateFormatterShortStyle]; + } + if([components day] == 1) { + return NSLocalizedString(@"YESTERDAY", "Yesterday"); + } + if([components hour] > 1) { + NSString *hourTemplate = NSLocalizedString(@"%ld_HOURS_AGO", "% Hours ago"); + return [NSString stringWithFormat:hourTemplate, [components hour]]; + } + NSInteger minutes = [components minute]; + if(minutes > 1) { + NSString *minuteTemplate = NSLocalizedString(@"%ld_MINUTES_AGO", "% Minutes ago"); + return [NSString stringWithFormat:minuteTemplate, minutes]; + } + return NSLocalizedString(@"JUST_NOW", "Just now"); +} +@end diff --git a/MacPass/de.lproj/Localizable.strings b/MacPass/de.lproj/Localizable.strings index c405ed6b..5da3bc8d 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 8010651b..805634a5 100644 Binary files a/MacPass/en.lproj/Localizable.strings and b/MacPass/en.lproj/Localizable.strings differ