mirror of
https://github.com/MacPass/MacPass.git
synced 2025-12-13 22:52:26 +00:00
Pickchar parser parses options. Output is not converted at the moment
This commit is contained in:
2
Cartfile
2
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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 = "<group>"; };
|
||||
4C8F0C6C1FCEE98900BE157F /* MPPluginConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MPPluginConstants.h; sourceTree = "<group>"; };
|
||||
4C8F0C6D1FCEE9B900BE157F /* MPPluginConstants.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MPPluginConstants.m; sourceTree = "<group>"; };
|
||||
4C8F0C6F1FCEF91400BE157F /* MPPickcharsParser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MPPickcharsParser.h; sourceTree = "<group>"; };
|
||||
4C8F0C701FCEF91400BE157F /* MPPickcharsParser.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MPPickcharsParser.m; sourceTree = "<group>"; };
|
||||
4C8F0C721FCF1B7A00BE157F /* MPTestPickcharsParser.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MPTestPickcharsParser.m; sourceTree = "<group>"; };
|
||||
4C8FB9FA1FC2D0EF003691AA /* MPPlugin_Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MPPlugin_Private.h; sourceTree = "<group>"; };
|
||||
4C93C5701FBDFEF700F36855 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/AutotypeCandidateSelectionView.strings; sourceTree = "<group>"; };
|
||||
4C93C5711FBDFEF900F36855 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/AutotypeBuilderView.strings; sourceTree = "<group>"; };
|
||||
@@ -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 = "<group>";
|
||||
@@ -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 */,
|
||||
|
||||
@@ -115,6 +115,7 @@ static MPLockDaemon *_sharedInstance;
|
||||
}
|
||||
|
||||
- (void)_checkIdleTime:(NSTimer *)timer {
|
||||
NSLog(@"Check Idle");
|
||||
if(timer != self.idleCheckTimer) {
|
||||
return; // Wrong timer?!
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -12,17 +12,22 @@
|
||||
#import <HNHUi/HNHUi.h>
|
||||
|
||||
@interface MPPickcharViewController () <NSTableViewDelegate, NSTableViewDataSource>
|
||||
|
||||
@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<NSString *> *)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
|
||||
|
||||
40
MacPass/MPPickcharsParser.h
Normal file
40
MacPass/MPPickcharsParser.h
Normal file
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// MPPickcharParser.h
|
||||
// MacPass
|
||||
//
|
||||
// Created by Michael Starke on 29.11.17.
|
||||
// Copyright © 2017 HicknHack Software GmbH. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@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
|
||||
134
MacPass/MPPickcharsParser.m
Normal file
134
MacPass/MPPickcharsParser.m
Normal file
@@ -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 <KeePassKit/KeePassKit.h>
|
||||
|
||||
@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 <NSString *>*keyValuePair = [option componentsSeparatedByString:@"="];
|
||||
if(![self _parseOptionKeyValuePair:keyValuePair]) {
|
||||
NSLog(@"Invalid Option: %@", option);
|
||||
continue;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)_parseOptionKeyValuePair:(NSArray <NSString *> *)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
|
||||
@@ -36,7 +36,6 @@ typedef NS_ENUM(NSUInteger, MPPickfieldTableColumn) {
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
self.tableModel = [[MPPickfieldTableModel alloc] initWithEntry:self.representedEntry inDocument:nil];
|
||||
|
||||
}
|
||||
|
||||
- (KPKEntry *)representedEntry {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -9,8 +9,10 @@
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="MPPickcharViewController">
|
||||
<connections>
|
||||
<outlet property="characterTableView" destination="KJq-FZ-rAE" id="H5Y-kG-Mvm"/>
|
||||
<outlet property="messageTextField" destination="wAr-f2-ZUQ" id="kaZ-v7-6UW"/>
|
||||
<outlet property="pickedStatusTextField" destination="e2q-qh-Zlv" id="paL-BH-g7a"/>
|
||||
<outlet property="pickedValueTextField" destination="KQ1-tZ-qja" id="ETe-j3-jdp"/>
|
||||
<outlet property="submitButton" destination="k8l-uy-C3l" id="nLN-Wz-dGW"/>
|
||||
<outlet property="togglePasswordDisplayButton" destination="hKI-WP-N93" id="ZDt-Rp-Ix2"/>
|
||||
<outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
|
||||
</connections>
|
||||
@@ -18,7 +20,7 @@
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<customView id="Hz6-mo-xeY">
|
||||
<rect key="frame" x="0.0" y="0.0" width="410" height="190"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="410" height="220"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="249" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="KQ1-tZ-qja" customClass="HNHUIRoundedSecureTextField">
|
||||
@@ -108,13 +110,13 @@
|
||||
</tableHeaderView>
|
||||
</scrollView>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="k8l-uy-C3l">
|
||||
<rect key="frame" x="324" y="13" width="72" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="Done" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="8vP-Ka-vsA">
|
||||
<rect key="frame" x="313" y="13" width="83" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="Submit" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="8vP-Ka-vsA">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="finishedPicking:" target="-1" id="Gb1-1S-8bv"/>
|
||||
<action selector="submitValue:" target="-2" id="Hvu-95-9mF"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Y8X-Bm-qLt">
|
||||
@@ -128,8 +130,16 @@
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="e2q-qh-Zlv">
|
||||
<rect key="frame" x="187" y="49" width="37" height="17"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Label" id="M3h-q8-FLO">
|
||||
<rect key="frame" x="167" y="49" width="76" height="17"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="StatusLabel" id="M3h-q8-FLO">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="wAr-f2-ZUQ">
|
||||
<rect key="frame" x="18" y="178" width="374" height="22"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="MessageLabel" id="sHz-kg-YJQ">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -143,19 +153,24 @@
|
||||
<constraint firstItem="MVS-ug-wys" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" symbolic="YES" id="9cE-TT-pqS"/>
|
||||
<constraint firstItem="hKI-WP-N93" firstAttribute="leading" secondItem="Y8X-Bm-qLt" secondAttribute="trailing" constant="8" id="AVv-zt-6sj"/>
|
||||
<constraint firstAttribute="trailing" secondItem="k8l-uy-C3l" secondAttribute="trailing" constant="20" symbolic="YES" id="Eaa-oF-Lt5"/>
|
||||
<constraint firstItem="MVS-ug-wys" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="20" symbolic="YES" id="Klq-Q9-Rjp"/>
|
||||
<constraint firstItem="MVS-ug-wys" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="50" id="Klq-Q9-Rjp"/>
|
||||
<constraint firstItem="wAr-f2-ZUQ" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="20" symbolic="YES" id="QQM-Db-MJM"/>
|
||||
<constraint firstItem="Y8X-Bm-qLt" firstAttribute="leading" secondItem="KQ1-tZ-qja" secondAttribute="trailing" constant="8" id="Qxu-Wk-ckL"/>
|
||||
<constraint firstAttribute="trailing" secondItem="wAr-f2-ZUQ" secondAttribute="trailing" constant="20" symbolic="YES" id="Scg-AR-d0y"/>
|
||||
<constraint firstItem="Y8X-Bm-qLt" firstAttribute="centerY" secondItem="KQ1-tZ-qja" secondAttribute="centerY" id="T81-yL-LEh"/>
|
||||
<constraint firstItem="e2q-qh-Zlv" firstAttribute="top" secondItem="KQ1-tZ-qja" secondAttribute="bottom" constant="8" symbolic="YES" id="UWG-aW-fsW"/>
|
||||
<constraint firstAttribute="bottom" secondItem="k8l-uy-C3l" secondAttribute="bottom" constant="20" symbolic="YES" id="UXs-2n-gB5"/>
|
||||
<constraint firstItem="e2q-qh-Zlv" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" symbolic="YES" id="WVC-0y-S19"/>
|
||||
<constraint firstItem="MVS-ug-wys" firstAttribute="top" secondItem="wAr-f2-ZUQ" secondAttribute="bottom" constant="8" symbolic="YES" id="b0M-bk-j9E"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="e2q-qh-Zlv" secondAttribute="trailing" constant="20" symbolic="YES" id="fCf-pK-CXQ"/>
|
||||
<constraint firstItem="k8l-uy-C3l" firstAttribute="top" secondItem="e2q-qh-Zlv" secondAttribute="bottom" constant="8" id="jwg-Z1-txO"/>
|
||||
<constraint firstAttribute="trailing" secondItem="MVS-ug-wys" secondAttribute="trailing" constant="20" symbolic="YES" id="mMv-HC-fEv"/>
|
||||
<constraint firstItem="KQ1-tZ-qja" firstAttribute="top" secondItem="MVS-ug-wys" secondAttribute="bottom" constant="8" symbolic="YES" id="nKb-eh-ba4"/>
|
||||
<constraint firstItem="e2q-qh-Zlv" firstAttribute="centerX" secondItem="Hz6-mo-xeY" secondAttribute="centerX" id="tE5-PK-tp0"/>
|
||||
<constraint firstItem="wAr-f2-ZUQ" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" symbolic="YES" id="xV9-bY-eZn"/>
|
||||
<constraint firstItem="k8l-uy-C3l" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="319" id="zZ5-GH-8no"/>
|
||||
</constraints>
|
||||
<point key="canvasLocation" x="-1020" y="-227"/>
|
||||
<point key="canvasLocation" x="-1291" y="-443"/>
|
||||
</customView>
|
||||
</objects>
|
||||
<resources>
|
||||
|
||||
@@ -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";
|
||||
};
|
||||
};
|
||||
}
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>%ld_CHARACTERS_TO_PICK_REMAINING</key>
|
||||
<dict>
|
||||
<key>NSStringLocalizedFormatKey</key>
|
||||
<string>%#@characters@</string>
|
||||
<key>characters</key>
|
||||
<dict>
|
||||
<key>NSStringFormatSpecTypeKey</key>
|
||||
<string>NSStringPluralRuleType</string>
|
||||
<key>NSStringFormatValueTypeKey</key>
|
||||
<string>ld</string>
|
||||
<key>zero</key>
|
||||
<string>alle Zeichen ausgewählt</string>
|
||||
<key>one</key>
|
||||
<string>ein Zeichen übrig</string>
|
||||
<key>other</key>
|
||||
<string>%ld Zeichen übrig</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>PICKED_%ld_CHARACTERS</key>
|
||||
<dict>
|
||||
<key>NSStringLocalizedFormatKey</key>
|
||||
<string>%#@characters@</string>
|
||||
<key>characters</key>
|
||||
<dict>
|
||||
<key>NSStringFormatSpecTypeKey</key>
|
||||
<string>NSStringPluralRuleType</string>
|
||||
<key>NSStringFormatValueTypeKey</key>
|
||||
<string>ld</string>
|
||||
<key>zero</key>
|
||||
<string>Kein Zeichen ausgewählt</string>
|
||||
<key>one</key>
|
||||
<string>%ld character picked</string>
|
||||
<key>other</key>
|
||||
<string>%ld characters picked</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>DUPLICATE_ENTRIES_%ld</key>
|
||||
<dict>
|
||||
<key>NSStringLocalizedFormatKey</key>
|
||||
<string>%#@entries@</string>
|
||||
<key>entries</key>
|
||||
<dict>
|
||||
<key>NSStringFormatSpecTypeKey</key>
|
||||
<string>NSStringPluralRuleType</string>
|
||||
<key>NSStringFormatValueTypeKey</key>
|
||||
<string>ld</string>
|
||||
<key>one</key>
|
||||
<string>Eintrag duplizieren</string>
|
||||
<key>other</key>
|
||||
<string>Einträge duplizieren</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>EVERY_%ld_DAYS</key>
|
||||
<dict>
|
||||
<key>NSStringLocalizedFormatKey</key>
|
||||
<string>%#@days@</string>
|
||||
<key>days</key>
|
||||
<dict>
|
||||
<key>NSStringFormatSpecTypeKey</key>
|
||||
<string>NSStringPluralRuleType</string>
|
||||
<key>NSStringFormatValueTypeKey</key>
|
||||
<string>ld</string>
|
||||
<key>one</key>
|
||||
<string>jeden Tag</string>
|
||||
<key>other</key>
|
||||
<string>alle %ld Tage</string>
|
||||
<key>zero</key>
|
||||
<string>nach jedem Entsperren</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
@@ -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";
|
||||
};
|
||||
};
|
||||
}
|
||||
37
MacPassTests/MPTestPickcharsParser.m
Normal file
37
MacPassTests/MPTestPickcharsParser.m
Normal file
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// MPTestPickcharsParser.m
|
||||
// MacPassTests
|
||||
//
|
||||
// Created by Michael Starke on 29.11.17.
|
||||
// Copyright © 2017 HicknHack Software GmbH. All rights reserved.
|
||||
//
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
#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
|
||||
Reference in New Issue
Block a user