mirror of
https://github.com/MacPass/MacPass.git
synced 2025-12-23 10:19:26 +00:00
Included TransformerKit for easier NSValueTransformer generation
Date picking for expiry dates now works
This commit is contained in:
@@ -70,7 +70,7 @@
|
||||
</constraints>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" image="NSActionTemplate" id="2999"/>
|
||||
<connections>
|
||||
<action selector="showImagePopup:" target="-2" id="3095"/>
|
||||
<action selector="pickIcon:" target="-1" id="IZz-hu-GkW"/>
|
||||
</connections>
|
||||
</imageView>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="249" translatesAutoresizingMaskIntoConstraints="NO" id="3013">
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application"/>
|
||||
<customView id="1">
|
||||
<rect key="frame" x="0.0" y="0.0" width="179" height="259"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="316" height="259"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<datePicker horizontalHuggingPriority="750" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="3">
|
||||
<rect key="frame" x="20" y="91" width="139" height="148"/>
|
||||
<rect key="frame" x="20" y="91" width="277" height="148"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<datePickerCell key="cell" borderStyle="bezel" alignment="left" datePickerStyle="clockAndCalendar" id="4">
|
||||
<font key="font" metaFont="system"/>
|
||||
@@ -49,10 +49,11 @@ AQABAAEAAQAB//+dkAEA//+PgAAE//+dkAEI//+dkAEMUERUAFBTVABQV1QAUFBUAAAAAAEAAAABA
|
||||
</calendarDate>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<datePickerElements key="datePickerElements" year="YES" month="YES" day="YES" hour="YES" minute="YES" second="YES"/>
|
||||
</datePickerCell>
|
||||
</datePicker>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="15">
|
||||
<rect key="frame" x="18" y="47" width="144" height="26"/>
|
||||
<rect key="frame" x="18" y="47" width="281" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="16">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
@@ -61,7 +62,7 @@ AQABAAEAAQAB//+dkAEA//+PgAAE//+dkAEI//+dkAEMUERUAFBTVABQV1QAUFBUAAAAAAEAAAABA
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="25">
|
||||
<rect key="frame" x="89" y="18" width="70" height="25"/>
|
||||
<rect key="frame" x="226" y="18" width="70" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="roundTextured" title="Use Date" bezelStyle="texturedRounded" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="26">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
@@ -72,7 +73,7 @@ AQABAAEAAQAB//+dkAEA//+PgAAE//+dkAEI//+dkAEMUERUAFBTVABQV1QAUFBUAAAAAAEAAAABA
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="29">
|
||||
<rect key="frame" x="20" y="18" width="56" height="25"/>
|
||||
<rect key="frame" x="162" y="18" width="56" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="roundTextured" title="Cancel" bezelStyle="texturedRounded" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="30">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
@@ -90,10 +91,11 @@ AQABAAEAAQAB//+dkAEA//+PgAAE//+dkAEI//+dkAEMUERUAFBTVABQV1QAUFBUAAAAAAEAAAABA
|
||||
<constraint firstItem="15" firstAttribute="leading" secondItem="1" secondAttribute="leading" constant="20" symbolic="YES" id="22"/>
|
||||
<constraint firstAttribute="trailing" secondItem="15" secondAttribute="trailing" constant="20" symbolic="YES" id="24"/>
|
||||
<constraint firstAttribute="trailing" secondItem="25" secondAttribute="trailing" constant="20" symbolic="YES" id="27"/>
|
||||
<constraint firstItem="29" firstAttribute="leading" secondItem="1" secondAttribute="leading" constant="20" symbolic="YES" id="35"/>
|
||||
<constraint firstItem="29" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="1" secondAttribute="leading" constant="20" symbolic="YES" id="35"/>
|
||||
<constraint firstAttribute="bottom" secondItem="25" secondAttribute="bottom" constant="20" symbolic="YES" id="36"/>
|
||||
<constraint firstAttribute="trailing" secondItem="3" secondAttribute="trailing" constant="20" id="6Qs-OP-VRr"/>
|
||||
<constraint firstItem="25" firstAttribute="centerY" secondItem="29" secondAttribute="centerY" id="M8N-5g-ClS"/>
|
||||
<constraint firstItem="25" firstAttribute="leading" secondItem="29" secondAttribute="trailing" constant="8" symbolic="YES" id="on5-xg-jcC"/>
|
||||
<constraint firstItem="25" firstAttribute="top" secondItem="15" secondAttribute="bottom" constant="8" symbolic="YES" id="sxX-fk-xaJ"/>
|
||||
</constraints>
|
||||
</customView>
|
||||
|
||||
@@ -577,10 +577,10 @@
|
||||
<outlet property="nextKeyView" destination="59" id="ZRe-l9-kNq"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button translatesAutoresizingMaskIntoConstraints="NO" id="7">
|
||||
<button horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="7">
|
||||
<rect key="frame" x="18" y="129" width="67" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Expires" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="78">
|
||||
<buttonCell key="cell" type="check" title="Expires" bezelStyle="regularSquare" imagePosition="left" lineBreakMode="truncatingMiddle" state="on" inset="2" id="78">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
@@ -599,6 +599,7 @@
|
||||
<font key="font" metaFont="cellTitle"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="pickExpiryDate:" target="-1" id="DQK-sp-SIL"/>
|
||||
<outlet property="nextKeyView" destination="5" id="Yg4-Ua-HVe"/>
|
||||
</connections>
|
||||
</button>
|
||||
@@ -661,6 +662,7 @@
|
||||
<constraint firstAttribute="trailing" secondItem="5" secondAttribute="trailing" constant="20" symbolic="YES" id="50"/>
|
||||
<constraint firstAttribute="bottom" secondItem="5" secondAttribute="bottom" constant="20" symbolic="YES" id="51"/>
|
||||
<constraint firstItem="7" firstAttribute="top" secondItem="59" secondAttribute="bottom" constant="8" symbolic="YES" id="QPJ-9m-AzZ"/>
|
||||
<constraint firstItem="8" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="7" secondAttribute="trailing" constant="8" symbolic="YES" id="Xa5-Ir-XNC"/>
|
||||
</constraints>
|
||||
</customView>
|
||||
<view translatesAutoresizingMaskIntoConstraints="NO" id="zv7-wE-Bmg" customClass="HNHScrollDocumentViewAdapter">
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<connections>
|
||||
<outlet property="autotypePopupButton" destination="240" id="285"/>
|
||||
<outlet property="contentView" destination="38" id="Dv7-1B-VeH"/>
|
||||
<outlet property="expireDateSelectButton" destination="4" id="KxN-kK-lan"/>
|
||||
<outlet property="expireDateSelectButton" destination="4" id="Bzg-8k-0OS"/>
|
||||
<outlet property="expiresCheckButton" destination="5" id="283"/>
|
||||
<outlet property="searchPopupButton" destination="229" id="284"/>
|
||||
<outlet property="titleTextField" destination="23" id="35"/>
|
||||
@@ -47,24 +47,27 @@
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button translatesAutoresizingMaskIntoConstraints="NO" id="5">
|
||||
<button horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="5">
|
||||
<rect key="frame" x="18" y="128" width="67" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Expires" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="32">
|
||||
<buttonCell key="cell" type="check" title="Expires" bezelStyle="regularSquare" imagePosition="left" lineBreakMode="truncatingMiddle" state="on" inset="2" id="32">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="4">
|
||||
<button focusRingType="exterior" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="4">
|
||||
<rect key="frame" x="206" y="127" width="31" height="19"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="31" id="l5I-EF-dHs"/>
|
||||
</constraints>
|
||||
<buttonCell key="cell" type="roundRect" bezelStyle="roundedRect" image="NSActionTemplate" imagePosition="only" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="33">
|
||||
<buttonCell key="cell" type="roundRect" bezelStyle="roundedRect" image="NSActionTemplate" imagePosition="only" alignment="center" state="on" borderStyle="border" focusRingType="exterior" imageScaling="proportionallyDown" inset="2" id="33">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="cellTitle"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="pickExpiryDate:" target="-1" id="KIc-p2-zJQ"/>
|
||||
</connections>
|
||||
</button>
|
||||
<popUpButton verticalHuggingPriority="750" horizontalCompressionResistancePriority="249" translatesAutoresizingMaskIntoConstraints="NO" id="229">
|
||||
<rect key="frame" x="18" y="72" width="222" height="26"/>
|
||||
@@ -125,6 +128,7 @@
|
||||
<constraint firstItem="240" firstAttribute="leading" secondItem="38" secondAttribute="leading" constant="20" id="E0a-1e-KR9"/>
|
||||
<constraint firstItem="5" firstAttribute="centerY" secondItem="4" secondAttribute="centerY" id="FdF-Pn-yY2"/>
|
||||
<constraint firstItem="5" firstAttribute="top" secondItem="23" secondAttribute="bottom" constant="8" symbolic="YES" id="GFF-xs-Nuj"/>
|
||||
<constraint firstItem="4" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="5" secondAttribute="trailing" constant="8" symbolic="YES" id="HDo-Yu-P02"/>
|
||||
<constraint firstItem="24" firstAttribute="leading" secondItem="38" secondAttribute="leading" constant="20" id="OhC-BP-oPg"/>
|
||||
<constraint firstAttribute="trailing" secondItem="240" secondAttribute="trailing" constant="20" symbolic="YES" id="V4d-R9-46P"/>
|
||||
<constraint firstAttribute="trailing" secondItem="23" secondAttribute="trailing" constant="20" id="Vej-zI-z2w"/>
|
||||
@@ -157,7 +161,6 @@
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
</scrollView>
|
||||
<userDefaultsController representsSharedInstance="YES" id="ePk-k3-9qj"/>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="NSActionTemplate" width="14" height="14"/>
|
||||
|
||||
@@ -25,9 +25,8 @@
|
||||
#import "MPSettingsWindowController.h"
|
||||
#import "MPPasswordCreatorViewController.h"
|
||||
#import "MPSettingsHelper.h"
|
||||
#import "MPUppercaseStringValueTransformer.h"
|
||||
#import "MPStringLengthValueTransformer.h"
|
||||
#import "MPStripLineBreaksTransformer.h"
|
||||
#import "MPValueTransformerHelper.h"
|
||||
#import "MPServerDaemon.h"
|
||||
#import "MPLockDaemon.h"
|
||||
#import "MPAutotypeDaemon.h"
|
||||
@@ -57,9 +56,8 @@ NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDi
|
||||
+ (void)initialize {
|
||||
[MPSettingsHelper setupDefaults];
|
||||
[MPSettingsHelper migrateDefaults];
|
||||
[MPUppercaseStringValueTransformer registerTransformer];
|
||||
[MPStringLengthValueTransformer registerTransformer];
|
||||
[MPStripLineBreaksTransformer registerTransformer];
|
||||
[MPValueTransformerHelper registerValueTransformer];
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
|
||||
@@ -16,5 +16,6 @@
|
||||
|
||||
- (IBAction)useDate:(id)sender;
|
||||
- (IBAction)cancel:(id)sender;
|
||||
- (IBAction)setDatePreset:(id)sender;
|
||||
|
||||
@end
|
||||
|
||||
@@ -8,7 +8,11 @@
|
||||
|
||||
#import "MPDatePickingViewController.h"
|
||||
|
||||
typedef NS_ENUM(NSUInteger, MPDatePresets) {
|
||||
#import "MPDocument.h"
|
||||
#import "KPKNode.h"
|
||||
#import "KPKTimeInfo.h"
|
||||
|
||||
typedef NS_ENUM(NSUInteger, MPDatePreset) {
|
||||
MPDatePresetTomorrow,
|
||||
MPDatePresetOneWeek,
|
||||
MPDatePresetOneMonth,
|
||||
@@ -30,16 +34,18 @@ typedef NS_ENUM(NSUInteger, MPDatePresets) {
|
||||
|
||||
- (void)awakeFromNib {
|
||||
NSMenu *presetMenu = [[NSMenu alloc] init];
|
||||
NSDictionary *dateItems = @{ @(MPDatePresetTomorrow): NSLocalizedString(@"TOMORROW", ""),
|
||||
@(MPDatePresetOneWeek): NSLocalizedString(@"ONE_WEEK", ""),
|
||||
@(MPDatePresetOneMonth): NSLocalizedString(@"ONE_MONTH", ""),
|
||||
@(MPDatePresetOneYear): NSLocalizedString(@"ONE_YEAR", "") };
|
||||
for(NSNumber *tagNumber in dateItems) {
|
||||
NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:dateItems[tagNumber] action:NULL keyEquivalent:@""];
|
||||
[item setTag:[tagNumber integerValue]];
|
||||
NSUInteger tags[] = { MPDatePresetTomorrow, MPDatePresetOneWeek, MPDatePresetOneMonth, MPDatePresetOneYear };
|
||||
NSArray *dateItems = @[ NSLocalizedString(@"TOMORROW", ""), NSLocalizedString(@"ONE_WEEK", ""), NSLocalizedString(@"ONE_MONTH", ""), NSLocalizedString(@"ONE_YEAR", "") ];
|
||||
for(NSInteger iIndex = 0; iIndex < sizeof(tags)/sizeof(NSUInteger); iIndex++) {
|
||||
NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:dateItems[iIndex] action:NULL keyEquivalent:@""];
|
||||
[item setTag:tags[iIndex]];
|
||||
[presetMenu addItem:item];
|
||||
}
|
||||
|
||||
MPDocument *document = [[self windowController] document];
|
||||
|
||||
[self.datePicker setDateValue:document.selectedItem.timeInfo.expiryTime];
|
||||
[self.presetPopupButton setAction:@selector(setDatePreset:)];
|
||||
[self.presetPopupButton setMenu:presetMenu];
|
||||
}
|
||||
|
||||
@@ -54,4 +60,30 @@ typedef NS_ENUM(NSUInteger, MPDatePresets) {
|
||||
id target = [NSApp targetForAction:@selector(performClose:)];
|
||||
[target performClose:sender];
|
||||
}
|
||||
|
||||
- (IBAction)setDatePreset:(id)sender {
|
||||
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
|
||||
NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
|
||||
|
||||
MPDatePreset preset = [[sender selectedItem] tag];
|
||||
switch(preset) {
|
||||
case MPDatePresetTomorrow:
|
||||
[offsetComponents setDay:1];
|
||||
break;
|
||||
case MPDatePresetOneWeek:
|
||||
[offsetComponents setWeek:1];
|
||||
break;
|
||||
case MPDatePresetOneMonth:
|
||||
[offsetComponents setMonth:1];
|
||||
break;
|
||||
case MPDatePresetOneYear:
|
||||
[offsetComponents setYear:1];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
NSDate *newDate = [gregorian dateByAddingComponents:offsetComponents toDate:[NSDate date] options:0];
|
||||
[self.datePicker setDateValue:newDate];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -95,7 +95,7 @@ typedef NS_OPTIONS(NSUInteger, MPEntrySearchFlags) {
|
||||
+ (NSString *)fileTypeForVersion:(KPKVersion)version;
|
||||
|
||||
#pragma mark Lock/Decrypt
|
||||
- (void)lockDatabase:(id)sender;
|
||||
- (IBAction)lockDatabase:(id)sender;
|
||||
/**
|
||||
* Decrypts the databse with the given password and keyfile
|
||||
*
|
||||
|
||||
@@ -43,9 +43,11 @@
|
||||
- (IBAction)importFromXML:(id)sender;
|
||||
|
||||
- (IBAction)lock:(id)sender;
|
||||
|
||||
- (IBAction)createGroup:(id)sender;
|
||||
|
||||
- (IBAction)pickIcon:(id)sender;
|
||||
- (IBAction)pickExpiryDate:(id)sender;
|
||||
|
||||
#pragma mark View Actions
|
||||
- (IBAction)toggleInspector:(id)sender;
|
||||
- (IBAction)focusGroups:(id)sender;
|
||||
|
||||
@@ -288,6 +288,14 @@ typedef void (^MPPasswordChangedBlock)(void);
|
||||
[_outlineViewController createEntry:nil];
|
||||
}
|
||||
|
||||
- (void)pickIcon:(id)sender {
|
||||
[self.inspectorViewController pickIcon:sender];
|
||||
}
|
||||
|
||||
- (void)pickExpiryDate:(id)sender {
|
||||
[self.inspectorViewController pickExpiryDate:sender];
|
||||
}
|
||||
|
||||
- (void)toggleInspector:(id)sender {
|
||||
NSView *inspectorView = [_inspectorViewController view];
|
||||
BOOL inspectorVisible = NO;
|
||||
@@ -303,6 +311,7 @@ typedef void (^MPPasswordChangedBlock)(void);
|
||||
options:0
|
||||
metrics:nil
|
||||
views:NSDictionaryOfVariableBindings(inspectorView)]];
|
||||
[self.inspectorViewController updateResponderChain];
|
||||
}
|
||||
[[NSUserDefaults standardUserDefaults] setBool:inspectorVisible forKey:kMPSettingsKeyShowInspector];
|
||||
}
|
||||
@@ -328,7 +337,6 @@ typedef void (^MPPasswordChangedBlock)(void);
|
||||
[[contentView subviews][0] removeFromSuperviewWithoutNeedingDisplay];
|
||||
}
|
||||
[contentView addSubview:_splitView];
|
||||
//[_splitView adjustSubviews];
|
||||
NSView *outlineView = [_outlineViewController view];
|
||||
NSView *inspectorView = [_inspectorViewController view];
|
||||
NSView *entryView = [_entryViewController view];
|
||||
|
||||
@@ -15,10 +15,12 @@
|
||||
|
||||
#import "MPDocument.h"
|
||||
#import "MPIconHelper.h"
|
||||
#import "MPValueTransformerHelper.h"
|
||||
|
||||
#import "KPKEntry.h"
|
||||
#import "KPKBinary.h"
|
||||
#import "KPKAutotype.h"
|
||||
#import "KPKTimeInfo.h"
|
||||
#import "KPKWindowAssociation.h"
|
||||
|
||||
#import "HNHScrollView.h"
|
||||
@@ -266,12 +268,15 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
|
||||
}
|
||||
|
||||
- (void)_bindEntry {
|
||||
|
||||
if(self.entry) {
|
||||
[self.titleTextField bind:NSValueBinding toObject:self.entry withKeyPath:@"title" options:nil];
|
||||
[self.passwordTextField bind:NSValueBinding toObject:self.entry withKeyPath:@"password" options:nil];
|
||||
[self.usernameTextField bind:NSValueBinding toObject:self.entry withKeyPath:@"username" options:nil];
|
||||
[self.URLTextField bind:NSValueBinding toObject:self.entry withKeyPath:@"url" options:nil];
|
||||
[self.expiresCheckButton bind:NSTitleBinding
|
||||
toObject:self.entry.timeInfo
|
||||
withKeyPath:NSStringFromSelector(@selector(expiryTime))
|
||||
options:@{ NSValueTransformerNameBindingOption:MPExpiryDateValueTransformer }];
|
||||
[self.expiresCheckButton bind:NSValueBinding toObject:self.entry.timeInfo withKeyPath:@"expires" options:nil];
|
||||
[self.tagsTokenField bind:NSValueBinding toObject:self.entry withKeyPath:@"tags" options:nil];
|
||||
}
|
||||
@@ -281,6 +286,7 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
|
||||
[self.usernameTextField unbind:NSValueBinding];
|
||||
[self.URLTextField unbind:NSValueBinding];
|
||||
[self.expiresCheckButton unbind:NSValueBinding];
|
||||
[self.expiresCheckButton unbind:NSTitleBinding];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#import "MPSettingsHelper.h"
|
||||
#import "MPEntryTableDataSource.h"
|
||||
#import "MPStringLengthValueTransformer.h"
|
||||
#import "MPStripLineBreaksTransformer.h"
|
||||
#import "MPValueTransformerHelper.h"
|
||||
#import "MPEntryContextMenuDelegate.h"
|
||||
|
||||
#import "KPKUTIs.h"
|
||||
@@ -32,6 +32,7 @@
|
||||
#import "KPKEntry.h"
|
||||
#import "KPKNode+IconImage.h"
|
||||
#import "KPKAttribute.h"
|
||||
#import "KPKTimeInfo.h"
|
||||
|
||||
#import "HNHTableHeaderCell.h"
|
||||
#import "HNHGradientView.h"
|
||||
@@ -149,11 +150,13 @@ NSString *const _MPTAbleSecurCellView = @"PasswordCell";
|
||||
[self.entryTable setAutosaveName:@"EntryTable"];
|
||||
[self.entryTable setAutosaveTableColumns:YES];
|
||||
|
||||
NSSortDescriptor *titleColumSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"title" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];
|
||||
NSSortDescriptor *userNameSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"username" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];
|
||||
NSSortDescriptor *urlSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"url" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];
|
||||
NSSortDescriptor *groupnameSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"parent.name" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];
|
||||
NSSortDescriptor *dateSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"timeInfo.lastModificationTime" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];
|
||||
NSString *parentNameKeyPath = [[NSString alloc] initWithFormat:@"%@.%@", NSStringFromSelector(@selector(parent)), NSStringFromSelector(@selector(name))];
|
||||
NSString *timeInfoModificationTimeKeyPath = [[NSString alloc] initWithFormat:@"%@.%@", NSStringFromSelector(@selector(timeInfo)), NSStringFromSelector(@selector(lastModificationTime))];
|
||||
NSSortDescriptor *titleColumSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:NSStringFromSelector(@selector(title))ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];
|
||||
NSSortDescriptor *userNameSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:NSStringFromSelector(@selector(username)) ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];
|
||||
NSSortDescriptor *urlSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:NSStringFromSelector(@selector(url)) ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];
|
||||
NSSortDescriptor *groupnameSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:parentNameKeyPath ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];
|
||||
NSSortDescriptor *dateSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:timeInfoModificationTimeKeyPath ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];
|
||||
|
||||
[titleColumn setSortDescriptorPrototype:titleColumSortDescriptor];
|
||||
[userNameColumn setSortDescriptorPrototype:userNameSortDescriptor];
|
||||
@@ -270,18 +273,18 @@ NSString *const _MPTAbleSecurCellView = @"PasswordCell";
|
||||
});
|
||||
[textField setFormatter:formatter];
|
||||
}
|
||||
[textField bind:NSValueBinding toObject:entry.timeInfo withKeyPath:@"lastModificationTime" options:nil];
|
||||
[textField bind:NSValueBinding toObject:entry.timeInfo withKeyPath:NSStringFromSelector(@selector(lastModificationTime)) options:nil];
|
||||
return view;
|
||||
}
|
||||
else if(isURLColumn) {
|
||||
[textField bind:NSValueBinding toObject:entry withKeyPath:@"url" options:nil];
|
||||
[textField bind:NSValueBinding toObject:entry withKeyPath:NSStringFromSelector(@selector(url)) options:nil];
|
||||
}
|
||||
else if(isUsernameColumn) {
|
||||
[textField bind:NSValueBinding toObject:entry withKeyPath:@"username" options:nil];
|
||||
[textField bind:NSValueBinding toObject:entry withKeyPath:NSStringFromSelector(@selector(username)) options:nil];
|
||||
}
|
||||
else if(isNotesColumn) {
|
||||
NSDictionary *options = @{ NSValueTransformerNameBindingOption : MPStripLineBreaksTransformerName };
|
||||
[textField bind:NSValueBinding toObject:entry withKeyPath:@"notes" options:options];
|
||||
[textField bind:NSValueBinding toObject:entry withKeyPath:NSStringFromSelector(@selector(notes)) options:options];
|
||||
}
|
||||
else if(isAttachmentColumn) {
|
||||
[textField bind:NSValueBinding toObject:entry withKeyPath:@"binaries.@count" options:nil];
|
||||
@@ -322,7 +325,7 @@ NSString *const _MPTAbleSecurCellView = @"PasswordCell";
|
||||
return; // we are showing the correct object right now.
|
||||
}
|
||||
}
|
||||
[self.entryArrayController bind:NSContentArrayBinding toObject:document.selectedGroup withKeyPath:@"entries" options:nil];
|
||||
[self.entryArrayController bind:NSContentArrayBinding toObject:document.selectedGroup withKeyPath:NSStringFromSelector(@selector(entries)) options:nil];
|
||||
}
|
||||
[self _updateContextBar];
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#import "MPGroupInspectorViewController.h"
|
||||
#import "MPDocument.h"
|
||||
#import "MPPasteBoardController.h"
|
||||
#import "MPValueTransformerHelper.h"
|
||||
|
||||
#import "KPKGroup.h"
|
||||
#import "KPKTimeInfo.h"
|
||||
@@ -16,6 +17,7 @@
|
||||
#import "HNHScrollView.h"
|
||||
#import "HNHRoundedTextField.h"
|
||||
|
||||
|
||||
@interface MPGroupInspectorViewController ()
|
||||
|
||||
@property (nonatomic, weak) KPKGroup *group;
|
||||
@@ -54,7 +56,6 @@
|
||||
metrics:nil
|
||||
views:views]];
|
||||
[[self view] layoutSubtreeIfNeeded];
|
||||
|
||||
/*
|
||||
void(^copyBlock)(NSTextField *textField) = ^void(NSTextField *textField) {
|
||||
[[MPPasteBoardController defaultController] copyObjects:@[ textField.stringValue ]];
|
||||
@@ -79,6 +80,10 @@
|
||||
if(self.group) {
|
||||
[self.titleTextField bind:NSValueBinding toObject:self.group withKeyPath:NSStringFromSelector(@selector(name)) options:nil];
|
||||
[self.expiresCheckButton bind:NSValueBinding toObject:self.group.timeInfo withKeyPath:NSStringFromSelector(@selector(expires)) options:nil];
|
||||
[self.expiresCheckButton bind:NSTitleBinding
|
||||
toObject:self.group.timeInfo
|
||||
withKeyPath:NSStringFromSelector(@selector(expiryTime))
|
||||
options:@{ NSValueTransformerNameBindingOption:MPExpiryDateValueTransformer }];
|
||||
[self.expireDateSelectButton bind:NSHiddenBinding
|
||||
toObject:self.group.timeInfo
|
||||
withKeyPath:NSStringFromSelector(@selector(expires))
|
||||
@@ -90,6 +95,8 @@
|
||||
[self.titleTextField unbind:NSValueBinding];
|
||||
|
||||
[self.expiresCheckButton unbind:NSValueBinding];
|
||||
[self.expiresCheckButton unbind:NSTitleBinding];
|
||||
[self.expiresCheckButton setTitle:NSLocalizedString(@"EXPIRES", "")];
|
||||
[self.expireDateSelectButton unbind:NSHiddenBinding];
|
||||
[self.autotypePopupButton unbind:NSSelectedTagBinding];
|
||||
[self.searchPopupButton unbind:NSSelectedTagBinding];
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
@property (weak) IBOutlet NSButton *editButton;
|
||||
@property (weak) IBOutlet NSButton *cancelEditButton;
|
||||
|
||||
- (IBAction)showImagePopup:(id)sender;
|
||||
- (IBAction)pickIcon:(id)sender;
|
||||
- (IBAction)pickExpiryDate:(id)sender;
|
||||
- (IBAction)toggleEdit:(id)sender;
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#import "HNHGradientView.h"
|
||||
#import "MPPopupImageView.h"
|
||||
|
||||
|
||||
typedef NS_ENUM(NSUInteger, MPContentTab) {
|
||||
MPEntryTab,
|
||||
MPGroupTab,
|
||||
@@ -45,6 +46,7 @@ typedef NS_ENUM(NSUInteger, MPContentTab) {
|
||||
|
||||
@property (nonatomic, strong) NSDate *modificationDate;
|
||||
@property (nonatomic, strong) NSDate *creationDate;
|
||||
@property (copy) NSString *expiryDateText;
|
||||
|
||||
@property (nonatomic, assign) NSUInteger activeTab;
|
||||
@property (weak) IBOutlet NSTabView *tabView;
|
||||
@@ -78,13 +80,6 @@ typedef NS_ENUM(NSUInteger, MPContentTab) {
|
||||
return [self view];
|
||||
}
|
||||
|
||||
#pragma mark Properties
|
||||
- (void)setActiveTab:(NSUInteger)activeTab {
|
||||
if(_activeTab != activeTab) {
|
||||
_activeTab = activeTab;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)awakeFromNib {
|
||||
[self.bottomBar setBorderType:HNHBorderTop|HNHBorderHighlight];
|
||||
|
||||
@@ -95,28 +90,26 @@ typedef NS_ENUM(NSUInteger, MPContentTab) {
|
||||
NSView *entryView = [_entryViewController view];
|
||||
NSView *groupView = [_groupViewController view];
|
||||
|
||||
NSView *entryTabView = [[self.tabView tabViewItemAtIndex:MPEntryTab] view];
|
||||
|
||||
NSTabViewItem *entryTabItem = [self.tabView tabViewItemAtIndex:MPEntryTab];
|
||||
NSView *entryTabView = [entryTabItem view];
|
||||
[entryTabView addSubview:entryView];
|
||||
NSDictionary *views = NSDictionaryOfVariableBindings(entryView, groupView);
|
||||
[entryTabView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[entryView]|" options:0 metrics:nil views:views]];
|
||||
[entryTabView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[entryView]|" options:0 metrics:nil views:views]];
|
||||
[entryTabItem setInitialFirstResponder:entryTabView];
|
||||
|
||||
NSView *groupTabView = [[self.tabView tabViewItemAtIndex:MPGroupTab] view];
|
||||
NSTabViewItem *groupTabItem = [self.tabView tabViewItemAtIndex:MPGroupTab];
|
||||
NSView *groupTabView = [groupTabItem view];
|
||||
[groupTabView addSubview:groupView];
|
||||
[groupTabView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[groupView]|" options:0 metrics:nil views:views]];
|
||||
[groupTabView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[groupView]|" options:0 metrics:nil views:views]];
|
||||
|
||||
[_groupViewController updateResponderChain];
|
||||
[_entryViewController updateResponderChain];
|
||||
[groupTabItem setInitialFirstResponder:groupView];
|
||||
|
||||
[[self view] layout];
|
||||
[self _updateBindings:nil];
|
||||
}
|
||||
|
||||
- (void)didLoadView {
|
||||
|
||||
}
|
||||
|
||||
- (void)regsiterNotificationsForDocument:(MPDocument *)document {
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(_didChangeCurrentItem:)
|
||||
@@ -124,7 +117,20 @@ typedef NS_ENUM(NSUInteger, MPContentTab) {
|
||||
object:document];
|
||||
[_entryViewController setupBindings:document];
|
||||
[_groupViewController setupBindings:document];
|
||||
|
||||
}
|
||||
|
||||
- (void)updateResponderChain {
|
||||
[super updateResponderChain];
|
||||
[_groupViewController updateResponderChain];
|
||||
[_entryViewController updateResponderChain];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Properties
|
||||
- (void)setActiveTab:(NSUInteger)activeTab {
|
||||
if(_activeTab != activeTab) {
|
||||
_activeTab = activeTab;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setModificationDate:(NSDate *)modificationDate {
|
||||
@@ -190,19 +196,32 @@ typedef NS_ENUM(NSUInteger, MPContentTab) {
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Popup
|
||||
- (IBAction)showImagePopup:(id)sender {
|
||||
|
||||
NSAssert(_popover == nil, @"Popover hast to be niled out");
|
||||
_popover = [[NSPopover alloc] init];
|
||||
_popover.delegate = self;
|
||||
_popover.behavior = NSPopoverBehaviorTransient;
|
||||
- (IBAction)pickIcon:(id)sender {
|
||||
if(self.popover) {
|
||||
return; // There is still a popover so do nothing
|
||||
}
|
||||
self.popover = [[NSPopover alloc] init];
|
||||
self.popover.delegate = self;
|
||||
self.popover.behavior = NSPopoverBehaviorTransient;
|
||||
if(!self.iconSelectionViewController) {
|
||||
self.iconSelectionViewController = [[MPIconSelectViewController alloc] init];
|
||||
}
|
||||
[self.iconSelectionViewController reset];
|
||||
self.iconSelectionViewController.popover = _popover;
|
||||
_popover.contentViewController = self.iconSelectionViewController;
|
||||
[_popover showRelativeToRect:NSZeroRect ofView:self.itemImageView preferredEdge:NSMinYEdge];
|
||||
self.popover.contentViewController = self.iconSelectionViewController;
|
||||
[self.popover showRelativeToRect:NSZeroRect ofView:sender preferredEdge:NSMinYEdge];
|
||||
}
|
||||
|
||||
- (IBAction)pickExpiryDate:(id)sender {
|
||||
if(self.popover) {
|
||||
return; // Popover still active, abort
|
||||
}
|
||||
NSAssert([sender isKindOfClass:[NSView class]], @"");
|
||||
self.popover = [[NSPopover alloc] init];
|
||||
self.popover.delegate = self;
|
||||
self.popover.behavior = NSPopoverBehaviorTransient;
|
||||
self.popover.contentViewController = [[MPDatePickingViewController alloc] init];
|
||||
[self.popover showRelativeToRect:NSZeroRect ofView:sender preferredEdge:NSMinYEdge];
|
||||
}
|
||||
|
||||
- (void)popoverDidClose:(NSNotification *)notification {
|
||||
@@ -220,16 +239,6 @@ typedef NS_ENUM(NSUInteger, MPContentTab) {
|
||||
self.popover = nil;
|
||||
}
|
||||
|
||||
- (IBAction)pickExpiryDate:(id)sender {
|
||||
NSAssert(self.popover == nil, @"Popover hast to be niled out");
|
||||
NSAssert([sender isKindOfClass:[NSView class]], @"");
|
||||
self.popover = [[NSPopover alloc] init];
|
||||
self.popover.delegate = self;
|
||||
self.popover.behavior = NSPopoverBehaviorTransient;
|
||||
self.popover.contentViewController = [[MPDatePickingViewController alloc] init];
|
||||
[self.popover showRelativeToRect:NSZeroRect ofView:sender preferredEdge:NSMinYEdge];
|
||||
}
|
||||
|
||||
- (void)_setIcon:(NSInteger)iconId {
|
||||
MPDocument *document = [[self windowController] document];
|
||||
BOOL useDefault = (iconId == -1);
|
||||
@@ -279,7 +288,7 @@ typedef NS_ENUM(NSUInteger, MPContentTab) {
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Notificiations
|
||||
#pragma mark MPDocument Notifications
|
||||
|
||||
- (void)_didChangeCurrentItem:(NSNotification *)notification {
|
||||
MPDocument *document = [notification object];
|
||||
|
||||
@@ -32,4 +32,8 @@
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)resignFirstResponder {
|
||||
return [super resignFirstResponder];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#import "MPConstants.h"
|
||||
#import "MPActionHelper.h"
|
||||
#import "MPIconHelper.h"
|
||||
#import "MPUppercaseStringValueTransformer.h"
|
||||
#import "MPNotifications.h"
|
||||
#import "MPOutlineContextMenuDelegate.h"
|
||||
|
||||
@@ -188,7 +187,6 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
|
||||
- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item {
|
||||
NSTableCellView *view;
|
||||
if( [self _itemIsRootNode:item] ) {
|
||||
//NSDictionary *options = @{ NSValueTransformerBindingOption : [NSValueTransformer valueTransformerForName:MPUppsercaseStringValueTransformerName] };
|
||||
view = [outlineView makeViewWithIdentifier:_MPOutlinveViewHeaderViewIdentifier owner:self];
|
||||
[view.textField bind:NSValueBinding toObject:self withKeyPath:@"databaseNameWrapper" options:nil];
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// MPStringLengthValueTransformer.h
|
||||
//
|
||||
// MacPass
|
||||
//
|
||||
// Created by Michael Starke on 17.06.13.
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
//
|
||||
// MPStripLineBreaksTransformer.h
|
||||
// MacPass
|
||||
//
|
||||
// Created by Michael Starke on 31.07.13.
|
||||
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
FOUNDATION_EXPORT NSString *const MPStripLineBreaksTransformerName;
|
||||
|
||||
@interface MPStripLineBreaksTransformer : NSValueTransformer
|
||||
|
||||
+ (void)registerTransformer;
|
||||
|
||||
@end
|
||||
@@ -1,37 +0,0 @@
|
||||
//
|
||||
// MPStripLineBreaksTransformer.m
|
||||
// MacPass
|
||||
//
|
||||
// Created by Michael Starke on 31.07.13.
|
||||
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MPStripLineBreaksTransformer.h"
|
||||
|
||||
NSString *const MPStripLineBreaksTransformerName = @"com.hicknhack.macpass.MPStripLineBreaksTransformerName";
|
||||
|
||||
@implementation MPStripLineBreaksTransformer
|
||||
|
||||
+ (Class)transformedValueClass {
|
||||
return [NSString class];
|
||||
}
|
||||
|
||||
+ (BOOL)allowsReverseTransformation {
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (void)registerTransformer {
|
||||
MPStripLineBreaksTransformer *transformer = [[MPStripLineBreaksTransformer alloc] init];
|
||||
[NSValueTransformer setValueTransformer:transformer
|
||||
forName:MPStripLineBreaksTransformerName];
|
||||
}
|
||||
|
||||
- (id)transformedValue:(id)value {
|
||||
if(![value isKindOfClass:[NSString class]]) {
|
||||
return nil;
|
||||
}
|
||||
NSArray *elements = [value componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
|
||||
return [elements componentsJoinedByString:@" "];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,17 +0,0 @@
|
||||
//
|
||||
// MPUppercaseStringValueTransformer.h
|
||||
// MacPass
|
||||
//
|
||||
// Created by Michael Starke on 03.06.13.
|
||||
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
|
||||
//
|
||||
|
||||
APPKIT_EXTERN NSString *const MPUppsercaseStringValueTransformerName;
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface MPUppercaseStringValueTransformer : NSValueTransformer
|
||||
|
||||
+ (void)registerTransformer;
|
||||
|
||||
@end
|
||||
@@ -1,36 +0,0 @@
|
||||
//
|
||||
// MPUppercaseStringValueTransformer.m
|
||||
// MacPass
|
||||
//
|
||||
// Created by Michael Starke on 03.06.13.
|
||||
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MPUppercaseStringValueTransformer.h"
|
||||
|
||||
NSString *const MPUppsercaseStringValueTransformerName = @"com.hicknhack.macpass.StringToUppercaseStringTransformer";
|
||||
|
||||
@implementation MPUppercaseStringValueTransformer
|
||||
|
||||
+ (Class)transformedValueClass {
|
||||
return [NSString class];
|
||||
}
|
||||
|
||||
+ (BOOL)allowsReverseTransformation {
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (void)registerTransformer {
|
||||
MPUppercaseStringValueTransformer *transformer = [[MPUppercaseStringValueTransformer alloc] init];
|
||||
[NSValueTransformer setValueTransformer:transformer
|
||||
forName:MPUppsercaseStringValueTransformerName];
|
||||
}
|
||||
|
||||
- (id)transformedValue:(id)value {
|
||||
if([value respondsToSelector:@selector(uppercaseString)]) {
|
||||
return [value uppercaseString];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@end
|
||||
18
MacPass/MPValueTransformerHelper.h
Normal file
18
MacPass/MPValueTransformerHelper.h
Normal file
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// MPValueTransformerHelper.h
|
||||
// MacPass
|
||||
//
|
||||
// Created by Michael Starke on 17/03/14.
|
||||
// Copyright (c) 2014 HicknHack Software GmbH. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
FOUNDATION_EXPORT NSString *const MPStripLineBreaksTransformerName;
|
||||
FOUNDATION_EXPORT NSString *const MPExpiryDateValueTransformer;
|
||||
|
||||
@interface MPValueTransformerHelper : NSObject
|
||||
|
||||
+ (void)registerValueTransformer;
|
||||
|
||||
@end
|
||||
46
MacPass/MPValueTransformerHelper.m
Normal file
46
MacPass/MPValueTransformerHelper.m
Normal file
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// MPValueTransformerHelper.m
|
||||
// MacPass
|
||||
//
|
||||
// Created by Michael Starke on 17/03/14.
|
||||
// Copyright (c) 2014 HicknHack Software GmbH. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MPValueTransformerHelper.h"
|
||||
#import "NSValueTransformer+TransformerKit.h"
|
||||
|
||||
NSString *const MPStripLineBreaksTransformerName = @"com.hicknhack.macpass.MPStripLineBreaksTransformerName";
|
||||
NSString *const MPExpiryDateValueTransformer = @"com.hicknhack.macpass.kMPExpiryDateValueTransformer";
|
||||
|
||||
@implementation MPValueTransformerHelper
|
||||
|
||||
+ (void)registerValueTransformer {
|
||||
[NSValueTransformer registerValueTransformerWithName:MPStripLineBreaksTransformerName
|
||||
transformedValueClass:[NSString class]
|
||||
returningTransformedValueWithBlock:^id(id value) {
|
||||
if(![value isKindOfClass:[NSString class]]) {
|
||||
return @"";
|
||||
}
|
||||
NSArray *elements = [value componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
|
||||
return [elements componentsJoinedByString:@" "];
|
||||
}];
|
||||
|
||||
|
||||
[NSValueTransformer registerValueTransformerWithName:MPExpiryDateValueTransformer
|
||||
transformedValueClass:[NSString class]
|
||||
returningTransformedValueWithBlock:^id(id value) {
|
||||
if(![value isKindOfClass:[NSDate class]]) {
|
||||
return @""; // Wrong input
|
||||
}
|
||||
static NSDateFormatter *formatter;
|
||||
if(!formatter) {
|
||||
formatter = [[NSDateFormatter alloc] init];
|
||||
[formatter setDateStyle:NSDateFormatterFullStyle];
|
||||
[formatter setTimeStyle:NSDateFormatterNoStyle];
|
||||
}
|
||||
NSString *template = NSLocalizedString(@"EXPIRES_AT_DATE_%@", "");
|
||||
return [[NSString alloc] initWithFormat:template, [formatter stringFromDate:value]];
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
||||
Binary file not shown.
Reference in New Issue
Block a user