diff --git a/Cartfile b/Cartfile index 59470bce..bf9521b1 100644 --- a/Cartfile +++ b/Cartfile @@ -1,3 +1,3 @@ github "sparkle-project/Sparkle" ~> 1.18.1 github "MacPass/KeePassKit" ~> 1.9 -github "mstarke/HNHUi" ~> 1.4.1 +github "mstarke/HNHUi" ~> 1.4.2 diff --git a/Cartfile.resolved b/Cartfile.resolved index a4535702..9e8c120b 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,3 +1,3 @@ github "MacPass/KeePassKit" "1.9" -github "mstarke/HNHUi" "1.4.1" +github "mstarke/HNHUi" "1.4.2" github "sparkle-project/Sparkle" "1.18.1" diff --git a/MacPass.xcodeproj/project.pbxproj b/MacPass.xcodeproj/project.pbxproj index ea3ef2fc..e0f8fda2 100644 --- a/MacPass.xcodeproj/project.pbxproj +++ b/MacPass.xcodeproj/project.pbxproj @@ -191,6 +191,8 @@ 4C8B36AB17A6ED4B005E1FF1 /* MPOutlineContextMenuDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8B36AA17A6ED4B005E1FF1 /* MPOutlineContextMenuDelegate.m */; }; 4C8DEAA21C314D2C00D24C32 /* MPTestAutotypeDelay.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8DEAA11C314D2C00D24C32 /* MPTestAutotypeDelay.m */; }; 4C8F0C6E1FCEE9B900BE157F /* MPPluginConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8F0C6D1FCEE9B900BE157F /* MPPluginConstants.m */; }; + 4C8F0C711FCEF91400BE157F /* MPPickcharsParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8F0C701FCEF91400BE157F /* MPPickcharsParser.m */; }; + 4C8F0C731FCF1B7A00BE157F /* MPTestPickcharsParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8F0C721FCF1B7A00BE157F /* MPTestPickcharsParser.m */; }; 4C978E0D19AE54AB003067DF /* MPFlagsHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C978E0C19AE54AB003067DF /* MPFlagsHelper.m */; }; 4CA08DA017A831B200A6544B /* MPAddEntryContextMenuDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CA08D9F17A831B200A6544B /* MPAddEntryContextMenuDelegate.m */; }; 4CA0B2ED15BCADAC00654E32 /* SettingsWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4CA0B2EC15BCADAC00654E32 /* SettingsWindow.xib */; }; @@ -658,6 +660,9 @@ 4C8DEAA11C314D2C00D24C32 /* MPTestAutotypeDelay.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPTestAutotypeDelay.m; sourceTree = ""; }; 4C8F0C6C1FCEE98900BE157F /* MPPluginConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MPPluginConstants.h; sourceTree = ""; }; 4C8F0C6D1FCEE9B900BE157F /* MPPluginConstants.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MPPluginConstants.m; sourceTree = ""; }; + 4C8F0C6F1FCEF91400BE157F /* MPPickcharsParser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MPPickcharsParser.h; sourceTree = ""; }; + 4C8F0C701FCEF91400BE157F /* MPPickcharsParser.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MPPickcharsParser.m; sourceTree = ""; }; + 4C8F0C721FCF1B7A00BE157F /* MPTestPickcharsParser.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MPTestPickcharsParser.m; sourceTree = ""; }; 4C8FB9FA1FC2D0EF003691AA /* MPPlugin_Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MPPlugin_Private.h; sourceTree = ""; }; 4C93C5701FBDFEF700F36855 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/AutotypeCandidateSelectionView.strings; sourceTree = ""; }; 4C93C5711FBDFEF900F36855 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/AutotypeBuilderView.strings; sourceTree = ""; }; @@ -1102,6 +1107,7 @@ 4C45FB1E178E09ED0010007D /* MacPassTests */ = { isa = PBXGroup; children = ( + 4C8F0C721FCF1B7A00BE157F /* MPTestPickcharsParser.m */, 4CCFA12C1BF0CC7A0078E0A1 /* Databases */, 4C10207E1B750E2F00BFCD59 /* MPTestAutotype.m */, 4C8DEAA11C314D2C00D24C32 /* MPTestAutotypeDelay.m */, @@ -1383,6 +1389,8 @@ 4CA3530A18A53CB800839B0F /* MPKeyMapper.m */, 4C1F7FA01E3A12E600D6A40E /* MPModifiedKey.h */, 4C1F7FA11E3A12E600D6A40E /* MPModifiedKey.m */, + 4C8F0C6F1FCEF91400BE157F /* MPPickcharsParser.h */, + 4C8F0C701FCEF91400BE157F /* MPPickcharsParser.m */, ); name = Autotype; sourceTree = ""; @@ -1820,6 +1828,7 @@ files = ( 4C45FB2D178E0BCB0010007D /* MPDatabaseLoading.m in Sources */, 4C8DEAA21C314D2C00D24C32 /* MPTestAutotypeDelay.m in Sources */, + 4C8F0C731FCF1B7A00BE157F /* MPTestPickcharsParser.m in Sources */, 4C45FB30178E0CE20010007D /* MPTestDocument.m in Sources */, 4C6BC6601A36717E00BDDF3D /* MPDatabaseSearch.m in Sources */, 4C10207F1B750E2F00BFCD59 /* MPTestAutotype.m in Sources */, @@ -1849,6 +1858,7 @@ 4CDF01A316D1B76700D0AC08 /* MPEntryViewController.m in Sources */, 4C3BD51516D276F800389F1F /* MPToolbarDelegate.m in Sources */, 4C7B63731C0CB51F00D7038C /* TTTDataTransformer.m in Sources */, + 4C8F0C711FCEF91400BE157F /* MPPickcharsParser.m in Sources */, 4C61EA0316D2FD0800AC519E /* MPOutlineViewController.m in Sources */, 4C65C79C16DD283900E32CFF /* MPToolbarButton.m in Sources */, 4C431BCD16E2A82800700A81 /* MPPasteBoardController.m in Sources */, diff --git a/MacPass/MPLockDaemon.m b/MacPass/MPLockDaemon.m index a076f24b..3ec58812 100644 --- a/MacPass/MPLockDaemon.m +++ b/MacPass/MPLockDaemon.m @@ -115,6 +115,7 @@ static MPLockDaemon *_sharedInstance; } - (void)_checkIdleTime:(NSTimer *)timer { + NSLog(@"Check Idle"); if(timer != self.idleCheckTimer) { return; // Wrong timer?! } diff --git a/MacPass/MPPickcharViewController.h b/MacPass/MPPickcharViewController.h index e177190a..15cd19db 100644 --- a/MacPass/MPPickcharViewController.h +++ b/MacPass/MPPickcharViewController.h @@ -13,10 +13,12 @@ NS_ASSUME_NONNULL_BEGIN @property (copy) NSString *sourceValue; @property (nonatomic, copy) NSString *pickedValue; -@property NSInteger countToPick; -@property (nonatomic) BOOL hideSource; +@property NSInteger minimumCharacterCount; +@property (nonatomic) BOOL hidePickedCharacters; - (IBAction)reset:(id)sender; +- (IBAction)submitValue:(id)sender; + @end diff --git a/MacPass/MPPickcharViewController.m b/MacPass/MPPickcharViewController.m index a96bf9a3..94b382ee 100644 --- a/MacPass/MPPickcharViewController.m +++ b/MacPass/MPPickcharViewController.m @@ -12,17 +12,22 @@ #import @interface MPPickcharViewController () + @property (weak) IBOutlet NSTableView *characterTableView; @property (weak) IBOutlet NSTextField *pickedValueTextField; @property (weak) IBOutlet NSButton *togglePasswordDisplayButton; +@property (weak) IBOutlet NSTextField *messageTextField; @property (weak) IBOutlet NSTextField *pickedStatusTextField; +@property (weak) IBOutlet NSButton *submitButton; + @property (nonatomic) NSInteger availableCountToPick; + @end @implementation MPPickcharViewController + (NSSet *)keyPathsForValuesAffectingAvailableCountToPick { - return [NSSet setWithArray:@[NSStringFromSelector(@selector(countToPick)), NSStringFromSelector(@selector(pickedValue))]]; + return [NSSet setWithArray:@[NSStringFromSelector(@selector(minimumCharacterCount)), NSStringFromSelector(@selector(pickedValue))]]; } - (NSString *)nibName { @@ -32,7 +37,7 @@ - (instancetype)initWithCoder:(NSCoder *)coder { self = [super initWithCoder:coder]; if(self) { - self.hideSource = NO; + self.hidePickedCharacters = NO; } return self; } @@ -40,13 +45,10 @@ - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if(self) { - self.hideSource = NO; + self.hidePickedCharacters = NO; } return self; } -- (void)reset:(id)sender { - self.pickedValue = @""; -} - (void)viewDidLoad { [super viewDidLoad]; @@ -65,28 +67,35 @@ self.characterTableView.enclosingScrollView.horizontalScroller.scrollerStyle = NSScrollerStyleLegacy; [self.pickedValueTextField bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(pickedValue)) options:nil]; [self.togglePasswordDisplayButton bind:NSValueBinding toObject:self.pickedValueTextField withKeyPath:NSStringFromSelector(@selector(showPassword)) options:nil]; - + [self reset:self]; } -- (void)setHideSource:(BOOL)hideSource { - if(_hideSource != hideSource) { - _hideSource = hideSource; +- (void)setHidePickedCharacters:(BOOL)hide { + if(_hidePickedCharacters != hide) { + _hidePickedCharacters = hide; [self.characterTableView reloadData]; } } - (void)setPickedValue:(NSString *)pickedValue { _pickedValue = [pickedValue copy]; - [self _updatePickedStatus]; + [self _updateContent]; } - (NSInteger)availableCountToPick { - return (self.countToPick - self.pickedValue.composedCharacterLength); + return (self.minimumCharacterCount - self.pickedValue.composedCharacterLength); } -- (void)_updatePickedStatus { - self.pickedStatusTextField.stringValue = [NSString stringWithFormat:@"%ld characters remaining", self.availableCountToPick]; +- (void)_updateContent { + self.messageTextField.stringValue = [NSString stringWithFormat:NSLocalizedString(@"PICKCHAR_INFO_MESSAGE_PICK_CHARACTERS_%ld", "Info about how many character has to pick in pickchar dialog"), self.minimumCharacterCount]; + if(self.minimumCharacterCount == 0) { + self.pickedStatusTextField.stringValue = [NSString stringWithFormat:NSLocalizedString(@"PICKED_%ld_CHARACTERS", @"Count of picked characters in pickchars dialog if no limit is set"), self.pickedValue.composedCharacterLength]; + } + else { + self.pickedStatusTextField.stringValue = [NSString stringWithFormat:NSLocalizedString(@"%ld_CHARACTERS_TO_PICK_REMAINING", @"Count of characters remaining in pickchars dialog"), self.availableCountToPick]; + } + self.submitButton.enabled = (self.availableCountToPick == 0 || self.minimumCharacterCount == 0); } - (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView { @@ -102,12 +111,12 @@ if(index == NSNotFound) { view.textField.stringValue = @"?"; } - view.textField.stringValue = self.hideSource ? @"•" : [self.sourceValue composedCharacterAtIndex:index]; + view.textField.stringValue = self.hidePickedCharacters ? @"•" : [self.sourceValue composedCharacterAtIndex:index]; return view; } - (void)tableView:(NSTableView *)tableView didClickTableColumn:(NSTableColumn *)tableColumn { - if(self.availableCountToPick <= 0) { + if(self.minimumCharacterCount != 0 && self.availableCountToPick <= 0) { return; } NSInteger index = [tableView.tableColumns indexOfObjectIdenticalTo:tableColumn]; @@ -122,12 +131,13 @@ } } -- (IBAction)finishedPicking:(id)sender { +- (void)submitValue:(id)sender { [NSApp stopModalWithCode:NSModalResponseOK]; } -- (IBAction)cancelPicking:(id)sender { - [NSApp stopModalWithCode:NSModalResponseCancel]; +- (void)reset:(id)sender { + self.pickedValue = @""; } + @end diff --git a/MacPass/MPPickcharsParser.h b/MacPass/MPPickcharsParser.h new file mode 100644 index 00000000..659fd27a --- /dev/null +++ b/MacPass/MPPickcharsParser.h @@ -0,0 +1,40 @@ +// +// MPPickcharParser.h +// MacPass +// +// Created by Michael Starke on 29.11.17. +// Copyright © 2017 HicknHack Software GmbH. All rights reserved. +// + +#import + +@interface MPPickcharsParser : NSObject + +@property (readonly) BOOL hideCharacters; +@property (readonly) BOOL convertToDownArrows; +@property (readonly) NSUInteger pickCount; // count to pick - 0 if unlimted +@property (readonly) NSUInteger checkboxOffset; +@property (readonly, copy) NSString *checkboxFormat; + + +/** + Initializes the parser with the given option string. + + @param options Options raw as from PICKCHARS entry + @return Parser instance configured with the provided options or defaults if errors occured + */ +- (instancetype)initWithOptions:(NSString *)options NS_DESIGNATED_INITIALIZER; + +/** + This message is used to actually process any input string picked by the user + into the format specified by the options. + For a default initalized parsers input will be the same as output, + If conversion is enabled, the string will contain autotype commands for arrow presses, tabs etc. + The returned string is to be processed further by the autotype system to yield the final values. + + @param string Input value picked by the user + @return converted input as set by the options + */ +- (NSString *)processPickedString:(NSString *)string; + +@end diff --git a/MacPass/MPPickcharsParser.m b/MacPass/MPPickcharsParser.m new file mode 100644 index 00000000..7b24bfb5 --- /dev/null +++ b/MacPass/MPPickcharsParser.m @@ -0,0 +1,134 @@ +// +// MPPickcharParser.m +// MacPass +// +// Created by Michael Starke on 29.11.17. +// Copyright © 2017 HicknHack Software GmbH. All rights reserved. +// + +#import "MPPickcharsParser.h" +#import + +@interface MPPickcharsParser () + +@property NSUInteger pickCount; // count to pick +@property NSUInteger checkboxOffset; +@property BOOL convertToDownArrows; +@property BOOL hideCharacters; +@property (copy) NSString *checkboxFormat; + +@end + +@implementation MPPickcharsParser + +- (instancetype)init { + self = [self initWithOptions:nil]; + return self; +} + +- (instancetype)initWithOptions:(NSString *)options { + self = [super init]; + if(self) { + _pickCount = 0; + _checkboxOffset = 0; + _convertToDownArrows = NO; + _hideCharacters = YES; + [self _parseOptions:options]; + } + return self; +} + +- (NSString *)processPickedString:(NSString *)string { + return string; +} + +/* + {PICKCHAR:Field:Options} + + Options allow to convert picked character to be typed into drop-down-boxes. + E.g. select digits or letters + Options: + + ID=id (id for multiple pickchars in a field will not get processed + Conv=D If set, convert values to down arrow presses + Conv-Offset= Offset for conversion of characters, will be added to all arrow presses + + Conv-Fmt= Format of the check-box + + 0 - Numbers 0129456789 + 1 - NUmber 1234567890 + a - lowercase characters + A - uppercase characters + ? - skip combobox item + + -> combine for layout e.g. 0a or 0aA 0?aA + */ +- (void)_parseOptions:(NSString *)options { + for(NSString *option in [options componentsSeparatedByString:kKPKPlaceholderPickCharsOptionDelemiter]) { + NSArray *keyValuePair = [option componentsSeparatedByString:@"="]; + if(![self _parseOptionKeyValuePair:keyValuePair]) { + NSLog(@"Invalid Option: %@", option); + continue; + }; + } +} + +- (BOOL)_parseOptionKeyValuePair:(NSArray *)optionPair { + if(optionPair.count != 2) { + return NO; + } + NSString *key = [optionPair.firstObject stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + NSString *option = [optionPair.lastObject stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + + if(NSOrderedSame == [key compare:kKPKPlaceholderPickCharsOptionCount options:NSCaseInsensitiveSearch] + || NSOrderedSame == [key compare:kKPKPlaceholderPickCharsOptionCountShort options:NSCaseInsensitiveSearch]) { + NSScanner *scanner = [[NSScanner alloc] initWithString:option]; + NSInteger count; + if([scanner scanInteger:&count]) { + if(count != INT_MIN && count != INT_MAX) { + self.pickCount = MAX(0,count); + return YES; + } + } + return NO; + } + /* + FOUNDATION_EXPORT NSString *const kKPKPlaceholderPickCharsOptionConvertFormat; + */ + if(NSOrderedSame == [key compare:kKPKPlaceholderPickCharsOptionHide options:NSCaseInsensitiveSearch]) { + if(NSOrderedSame == [option compare:@"false" options:NSCaseInsensitiveSearch]) { + self.hideCharacters = NO; + return YES; + } + if(NSOrderedSame == [option compare:@"true" options:NSCaseInsensitiveSearch]) { + self.hideCharacters = YES; + return YES; + } + return NO; + } + if(NSOrderedSame == [key compare:kKPKPlaceholderPickCharsOptionConvert options:NSCaseInsensitiveSearch]) { + if(NSOrderedSame == [option compare:@"D" options:NSCaseInsensitiveSearch]) { + self.convertToDownArrows = YES; + return YES; + } + return NO; + } + if(NSOrderedSame == [key compare:kKPKPlaceholderPickCharsOptionConvertOffset options:NSCaseInsensitiveSearch]) { + NSScanner *scanner = [[NSScanner alloc] initWithString:option]; + NSInteger offset; + if([scanner scanInteger:&offset]) { + if(offset != INT_MIN && offset != INT_MAX) { + self.checkboxOffset = MAX(0,offset); + return YES; + } + } + return NO; + } + if(NSOrderedSame == [key compare:kKPKPlaceholderPickCharsOptionConvertFormat options:NSCaseInsensitiveSearch]) { + self.checkboxFormat = option; + return YES; + } + return NO; +} + +@end diff --git a/MacPass/MPPickfieldViewController.m b/MacPass/MPPickfieldViewController.m index f6fb98cc..5c463d6c 100644 --- a/MacPass/MPPickfieldViewController.m +++ b/MacPass/MPPickfieldViewController.m @@ -36,7 +36,6 @@ typedef NS_ENUM(NSUInteger, MPPickfieldTableColumn) { - (void)viewDidLoad { [super viewDidLoad]; self.tableModel = [[MPPickfieldTableModel alloc] initWithEntry:self.representedEntry inDocument:nil]; - } - (KPKEntry *)representedEntry { diff --git a/MacPass/MPTreeDelegate.m b/MacPass/MPTreeDelegate.m index 5c67a485..08fe6b6b 100644 --- a/MacPass/MPTreeDelegate.m +++ b/MacPass/MPTreeDelegate.m @@ -26,6 +26,7 @@ #import "MPSettingsHelper.h" #import "MPPickcharViewController.h" #import "MPPickfieldViewController.h" +#import "MPPickcharsParser.h" @interface MPTreeDelegate (); @@ -106,11 +107,12 @@ if(value.length == 0) { return @""; // error while retrieving source value } - + MPPickcharsParser *parser = [[MPPickcharsParser alloc] initWithOptions:options]; MPPickcharViewController *pickCharViewController = [[MPPickcharViewController alloc] init]; pickCharViewController.sourceValue = value; - pickCharViewController.countToPick = 10; + pickCharViewController.minimumCharacterCount = parser.pickCount; + pickCharViewController.hidePickedCharacters = parser.hideCharacters; NSPanel *panel = [[NSPanel alloc] initWithContentRect:NSMakeRect(0, 0, 100, 100) styleMask:NSWindowStyleMaskNonactivatingPanel|NSWindowStyleMaskTitled|NSWindowStyleMaskResizable diff --git a/MacPass/PickcharView.xib b/MacPass/PickcharView.xib index 08235844..fcc3785e 100644 --- a/MacPass/PickcharView.xib +++ b/MacPass/PickcharView.xib @@ -9,8 +9,10 @@ + + @@ -18,7 +20,7 @@ - + @@ -108,13 +110,13 @@ - - + + + + + + + + + + @@ -143,19 +153,24 @@ - + + + + + + - + diff --git a/MacPass/de.lproj/Localizable.stringsdict b/MacPass/de.lproj/Localizable.stringsdict index 21d66f9e..8930d663 100644 --- a/MacPass/de.lproj/Localizable.stringsdict +++ b/MacPass/de.lproj/Localizable.stringsdict @@ -1,21 +1,76 @@ -{ - "DUPLICATE_ENTRIES_%ld" = { - NSStringLocalizedFormatKey = "%#@entries@"; - entries = { - NSStringFormatSpecTypeKey = NSStringPluralRuleType; - NSStringFormatValueTypeKey = ld; - one = "Eintrag duplizieren"; - other = "Eintr\U00e4ge duplizieren"; - }; - }; - "EVERY_%ld_DAYS" = { - NSStringLocalizedFormatKey = "%#@days@"; - days = { - NSStringFormatSpecTypeKey = NSStringPluralRuleType; - NSStringFormatValueTypeKey = ld; - one = "jeden Tag"; - other = "alle %ld Tage"; - zero = "nach jedem Entsperren"; - }; - }; -} \ No newline at end of file + + + + + %ld_CHARACTERS_TO_PICK_REMAINING + + NSStringLocalizedFormatKey + %#@characters@ + characters + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + zero + alle Zeichen ausgewählt + one + ein Zeichen übrig + other + %ld Zeichen übrig + + + PICKED_%ld_CHARACTERS + + NSStringLocalizedFormatKey + %#@characters@ + characters + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + zero + Kein Zeichen ausgewählt + one + %ld character picked + other + %ld characters picked + + + DUPLICATE_ENTRIES_%ld + + NSStringLocalizedFormatKey + %#@entries@ + entries + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Eintrag duplizieren + other + Einträge duplizieren + + + EVERY_%ld_DAYS + + NSStringLocalizedFormatKey + %#@days@ + days + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + jeden Tag + other + alle %ld Tage + zero + nach jedem Entsperren + + + + diff --git a/MacPass/en.lproj/Localizable.strings b/MacPass/en.lproj/Localizable.strings index 4e266193..5a61e04f 100644 --- a/MacPass/en.lproj/Localizable.strings +++ b/MacPass/en.lproj/Localizable.strings @@ -13,6 +13,9 @@ /* % Weeks ago */ "%ld_WEEKS_AGO" = "%ld weeks ago"; +/* Count of characters remaining in Pickchars view */ +"%ld_CHARACTERS_TO_PICK_REMAINING" = "%ld characters to pick remaining"; + /* preset to expire after 90 days from now */ "90_DAYS" = "in 90 days"; @@ -404,6 +407,12 @@ /* Menu item to perform autotype with the selected entry */ "PERFORM_AUTOTYPE_FOR_ENTRY" = "Perform Autotype"; +/* Count of picked characters in Pickchars view if no limit is set */ +"PICKED_%ld_CHARACTERS" = "Picked %ld characters"; + +/* Comment */ +"PICKCHAR_INFO_MESSAGE_PICK_CHARACTERS_%ld" = "Please pick %ld characters"; + /* The plugin could not be initalized */ "PLUGIN_ERROR_INTILIZATION_FAILED" = "Plugin could not be initalized"; diff --git a/MacPass/en.lproj/Localizable.stringsdict b/MacPass/en.lproj/Localizable.stringsdict index 17361c64..8eed47d5 100644 --- a/MacPass/en.lproj/Localizable.stringsdict +++ b/MacPass/en.lproj/Localizable.stringsdict @@ -1,22 +1,52 @@ { - "DUPLICATE_ENTRIES_%ld" = { - NSStringLocalizedFormatKey = "%#@entries@"; - entries = { - NSStringFormatSpecTypeKey = NSStringPluralRuleType; - NSStringFormatValueTypeKey = ld; - one = "Duplicate Entry"; - other = "Duplicate Entries"; - zero = "Duplicate Entries"; - }; - }; - "EVERY_%ld_DAYS" = { - NSStringLocalizedFormatKey = "%#@days@"; - days = { - NSStringFormatSpecTypeKey = NSStringPluralRuleType; - NSStringFormatValueTypeKey = ld; - one = "every day"; - other = "every %ld days"; - zero = "after each unlock"; - }; - }; + "PICKCHAR_INFO_MESSAGE_PICK_CHARACTERS_%ld" = { + "NSStringLocalizedFormatKey" = "%#@characters@"; + characters = { + "NSStringFormatSpecTypeKey" = "NSStringPluralRuleType"; + "NSStringFormatValueTypeKey" = ld; + zero = "Please pick character to use"; + one = "Please pick a single character to use"; + other = "Pleas pick %ld characters to use"; + }; + }; + "%ld_CHARACTERS_TO_PICK_REMAINING" = { + "NSStringLocalizedFormatKey" = "%#@characters@"; + characters = { + "NSStringFormatSpecTypeKey" = "NSStringPluralRuleType"; + "NSStringFormatValueTypeKey" = ld; + zero = "All characters picked"; + one = "One character remaining"; + other = "%ld characters remaining"; + }; + }; + "PICKED_%ld_CHARACTERS" = { + "NSStringLocalizedFormatKey" = "%#@characters@"; + characters = { + "NSStringFormatSpecTypeKey" = "NSStringPluralRuleType"; + "NSStringFormatValueTypeKey" = ld; + zero = "No characters picked"; + one = "%ld character picked"; + other = "%ld characters picked"; + }; + }; + "DUPLICATE_ENTRIES_%ld" = { + "NSStringLocalizedFormatKey" = "%#@entries@"; + entries = { + "NSStringFormatSpecTypeKey" = "NSStringPluralRuleType"; + "NSStringFormatValueTypeKey" = ld; + zero = "Duplicate Entries"; + one = "Duplicate Entry"; + other = "Duplicate Entries"; + }; + }; + "EVERY_%ld_DAYS" = { + "NSStringLocalizedFormatKey" = "%#@days@"; + days = { + "NSStringFormatSpecTypeKey" = "NSStringPluralRuleType"; + "NSStringFormatValueTypeKey" = ld; + zero = "after each unlock"; + one = "every day"; + other = "every %ld days"; + }; + }; } \ No newline at end of file diff --git a/MacPassTests/MPTestPickcharsParser.m b/MacPassTests/MPTestPickcharsParser.m new file mode 100644 index 00000000..cc251235 --- /dev/null +++ b/MacPassTests/MPTestPickcharsParser.m @@ -0,0 +1,37 @@ +// +// MPTestPickcharsParser.m +// MacPassTests +// +// Created by Michael Starke on 29.11.17. +// Copyright © 2017 HicknHack Software GmbH. All rights reserved. +// + +#import +#import "MPPickcharsParser.h" + +@interface MPTestPickcharsParser : XCTestCase + +@end + +@implementation MPTestPickcharsParser + +- (void)testValidOptionsParser { + MPPickcharsParser *parser = [[MPPickcharsParser alloc] initWithOptions:@"Count=10,Hide=false,Conv=D,Conv-Offset=11,Conv-Fmt=0?aA"]; + XCTAssertEqual(10, parser.pickCount); + XCTAssertEqual(NO, parser.hideCharacters); + XCTAssertEqual(YES, parser.convertToDownArrows); + XCTAssertEqual(11, parser.checkboxOffset); + XCTAssertEqualObjects(@"0?aA", parser.checkboxFormat); +} + + +- (void)testInvalidOptionsParser { + MPPickcharsParser *parser = [[MPPickcharsParser alloc] initWithOptions:@"Count=-10,Hide=whatever,Con=D,Conv-Offset=20,Conv-Fmt=0A"]; + XCTAssertEqual(0, parser.pickCount); // negative count will result in 0-count + XCTAssertEqual(YES, parser.hideCharacters); // option invalid, default is YES + XCTAssertEqual(NO, parser.convertToDownArrows); // option was invalid, default is NO + XCTAssertEqual(20, parser.checkboxOffset); + XCTAssertEqualObjects(@"0A", parser.checkboxFormat); +} + +@end