mirror of
https://github.com/MacPass/MacPass.git
synced 2025-12-14 02:22:28 +00:00
began work for seamless editing with history support
This commit is contained in:
@@ -859,12 +859,12 @@
|
|||||||
4C10412B178CDD44001B5239 /* NSDate+Humanized.m */,
|
4C10412B178CDD44001B5239 /* NSDate+Humanized.m */,
|
||||||
4CC6DB7817D23719002C6091 /* KPKNode+IconImage.h */,
|
4CC6DB7817D23719002C6091 /* KPKNode+IconImage.h */,
|
||||||
4CC6DB7917D23719002C6091 /* KPKNode+IconImage.m */,
|
4CC6DB7917D23719002C6091 /* KPKNode+IconImage.m */,
|
||||||
|
4C32B0E51A1D4436007E12F1 /* KPKFormat+MPUTIDetection.h */,
|
||||||
|
4C32B0E61A1D4436007E12F1 /* KPKFormat+MPUTIDetection.m */,
|
||||||
4CEED1C417D7BD0E007180F1 /* NSError+Messages.h */,
|
4CEED1C417D7BD0E007180F1 /* NSError+Messages.h */,
|
||||||
4CEED1C517D7BD0E007180F1 /* NSError+Messages.m */,
|
4CEED1C517D7BD0E007180F1 /* NSError+Messages.m */,
|
||||||
4C77C83F18E240E000D1C42B /* DDHotKey+MacPassAdditions.h */,
|
4C77C83F18E240E000D1C42B /* DDHotKey+MacPassAdditions.h */,
|
||||||
4C77C84018E240E000D1C42B /* DDHotKey+MacPassAdditions.m */,
|
4C77C84018E240E000D1C42B /* DDHotKey+MacPassAdditions.m */,
|
||||||
4C32B0E51A1D4436007E12F1 /* KPKFormat+MPUTIDetection.h */,
|
|
||||||
4C32B0E61A1D4436007E12F1 /* KPKFormat+MPUTIDetection.m */,
|
|
||||||
4C5807761C64F67000E7171F /* NSString+MPHash.h */,
|
4C5807761C64F67000E7171F /* NSString+MPHash.h */,
|
||||||
4C5807771C64F67000E7171F /* NSString+MPHash.m */,
|
4C5807771C64F67000E7171F /* NSString+MPHash.m */,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -8,11 +8,12 @@
|
|||||||
<customObject id="-2" userLabel="File's Owner" customClass="MPInspectorViewController">
|
<customObject id="-2" userLabel="File's Owner" customClass="MPInspectorViewController">
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="bottomBar" destination="2930" id="2995"/>
|
<outlet property="bottomBar" destination="2930" id="2995"/>
|
||||||
<outlet property="editButton" destination="3109" id="3122"/>
|
<outlet property="discardChangesButton" destination="hfJ-b8-tQJ" id="CCz-S9-SiC"/>
|
||||||
<outlet property="itemImageView" destination="2998" id="3024"/>
|
<outlet property="itemImageView" destination="2998" id="3024"/>
|
||||||
<outlet property="itemNameTextField" destination="3013" id="3025"/>
|
<outlet property="itemNameTextField" destination="3013" id="3025"/>
|
||||||
<outlet property="noSelectionInfo" destination="2985" id="2993"/>
|
<outlet property="noSelectionInfo" destination="2985" id="2993"/>
|
||||||
<outlet property="notesTextView" destination="g24-gQ-foD" id="pcU-EQ-Vgn"/>
|
<outlet property="notesTextView" destination="g24-gQ-foD" id="pcU-EQ-Vgn"/>
|
||||||
|
<outlet property="saveChangesButton" destination="lje-Eh-VCc" id="JK1-gy-w3R"/>
|
||||||
<outlet property="splitView" destination="3145" id="lyG-RH-yu4"/>
|
<outlet property="splitView" destination="3145" id="lyG-RH-yu4"/>
|
||||||
<outlet property="tabView" destination="2895" id="2994"/>
|
<outlet property="tabView" destination="2895" id="2994"/>
|
||||||
<outlet property="view" destination="2894" id="2976"/>
|
<outlet property="view" destination="2894" id="2976"/>
|
||||||
@@ -26,9 +27,16 @@
|
|||||||
<customView translatesAutoresizingMaskIntoConstraints="NO" id="2930" customClass="HNHUIGradientView">
|
<customView translatesAutoresizingMaskIntoConstraints="NO" id="2930" customClass="HNHUIGradientView">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="278" height="30"/>
|
<rect key="frame" x="0.0" y="0.0" width="278" height="30"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<button verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3109">
|
<button hidden="YES" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="lje-Eh-VCc">
|
||||||
<rect key="frame" x="219" y="2" width="39" height="25"/>
|
<rect key="frame" x="194" y="-2" width="70" height="32"/>
|
||||||
<buttonCell key="cell" type="roundTextured" title="Edit" bezelStyle="texturedRounded" imagePosition="left" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="3110">
|
<buttonCell key="cell" type="push" title="Save" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="15U-vA-2Dj">
|
||||||
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
</buttonCell>
|
||||||
|
</button>
|
||||||
|
<button hidden="YES" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="hfJ-b8-tQJ">
|
||||||
|
<rect key="frame" x="107" y="-2" width="87" height="32"/>
|
||||||
|
<buttonCell key="cell" type="push" title="Discard" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="bQO-6W-0DC">
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
</buttonCell>
|
</buttonCell>
|
||||||
@@ -36,8 +44,13 @@
|
|||||||
</subviews>
|
</subviews>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="height" constant="30" id="2949"/>
|
<constraint firstAttribute="height" constant="30" id="2949"/>
|
||||||
<constraint firstAttribute="trailing" secondItem="3109" secondAttribute="trailing" constant="20" symbolic="YES" id="3138"/>
|
<constraint firstAttribute="bottom" secondItem="hfJ-b8-tQJ" secondAttribute="bottom" constant="5" id="98h-mh-kLI"/>
|
||||||
<constraint firstItem="3109" firstAttribute="centerY" secondItem="2930" secondAttribute="centerY" id="3139"/>
|
<constraint firstItem="hfJ-b8-tQJ" firstAttribute="top" secondItem="2930" secondAttribute="top" constant="4" id="KJY-bS-IEo"/>
|
||||||
|
<constraint firstAttribute="trailing" secondItem="lje-Eh-VCc" secondAttribute="trailing" constant="20" symbolic="YES" id="ctS-Ss-3p5"/>
|
||||||
|
<constraint firstItem="lje-Eh-VCc" firstAttribute="leading" secondItem="hfJ-b8-tQJ" secondAttribute="trailing" constant="12" symbolic="YES" id="dqP-vX-v2w"/>
|
||||||
|
<constraint firstItem="hfJ-b8-tQJ" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="2930" secondAttribute="leading" constant="20" symbolic="YES" id="eHL-y7-iiE"/>
|
||||||
|
<constraint firstAttribute="bottom" secondItem="lje-Eh-VCc" secondAttribute="bottom" constant="5" id="jQ2-v5-1GZ"/>
|
||||||
|
<constraint firstItem="lje-Eh-VCc" firstAttribute="top" secondItem="2930" secondAttribute="top" constant="4" id="t64-P5-H3N"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</customView>
|
</customView>
|
||||||
<imageView translatesAutoresizingMaskIntoConstraints="NO" id="2998" customClass="MPPopupImageView">
|
<imageView translatesAutoresizingMaskIntoConstraints="NO" id="2998" customClass="MPPopupImageView">
|
||||||
@@ -95,8 +108,8 @@
|
|||||||
<rect key="frame" x="0.0" y="0.0" width="278" height="370"/>
|
<rect key="frame" x="0.0" y="0.0" width="278" height="370"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2985">
|
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="2985">
|
||||||
<rect key="frame" x="80" y="194" width="119" height="24"/>
|
<rect key="frame" x="81" y="194" width="118" height="24"/>
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="No Selection" id="2986">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="No Selection" id="2986">
|
||||||
<font key="font" metaFont="system" size="20"/>
|
<font key="font" metaFont="system" size="20"/>
|
||||||
<color key="textColor" name="controlShadowColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlShadowColor" catalog="System" colorSpace="catalog"/>
|
||||||
@@ -125,8 +138,8 @@
|
|||||||
<rect key="frame" x="0.0" y="371" width="278" height="211"/>
|
<rect key="frame" x="0.0" y="371" width="278" height="211"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="PzR-P9-3al">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="PzR-P9-3al">
|
||||||
<rect key="frame" x="18" y="192" width="36" height="14"/>
|
<rect key="frame" x="18" y="192" width="35" height="14"/>
|
||||||
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Notes" id="hwn-UY-9Cr">
|
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Notes" id="hwn-UY-9Cr">
|
||||||
<font key="font" metaFont="smallSystem"/>
|
<font key="font" metaFont="smallSystem"/>
|
||||||
<color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
@@ -203,9 +216,8 @@
|
|||||||
<constraint firstAttribute="trailing" secondItem="3145" secondAttribute="trailing" id="3154"/>
|
<constraint firstAttribute="trailing" secondItem="3145" secondAttribute="trailing" id="3154"/>
|
||||||
<constraint firstItem="3145" firstAttribute="leading" secondItem="2894" secondAttribute="leading" id="3155"/>
|
<constraint firstItem="3145" firstAttribute="leading" secondItem="2894" secondAttribute="leading" id="3155"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<point key="canvasLocation" x="268" y="-437"/>
|
<point key="canvasLocation" x="412" y="-682"/>
|
||||||
</customView>
|
</customView>
|
||||||
<userDefaultsController representsSharedInstance="YES" id="U5N-S2-0zc"/>
|
|
||||||
</objects>
|
</objects>
|
||||||
<resources>
|
<resources>
|
||||||
<image name="NSActionTemplate" width="14" height="14"/>
|
<image name="NSActionTemplate" width="14" height="14"/>
|
||||||
|
|||||||
@@ -167,6 +167,14 @@ APPKIT_EXTERN NSString *const MPDocumentGroupKey;
|
|||||||
|
|
||||||
- (IBAction)duplicateEntryWithOptions:(id)sender;
|
- (IBAction)duplicateEntryWithOptions:(id)sender;
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark Editing
|
||||||
|
|
||||||
|
- (void)willChangeEntry:(KPKEntry *)entry;
|
||||||
|
- (void)commitChangesToEntry:(KPKEntry *)entry;
|
||||||
|
- (void)discardChangesToEntry:(KPKEntry *)entry;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface MPDocument (Attachments)
|
@interface MPDocument (Attachments)
|
||||||
@@ -211,23 +219,6 @@ APPKIT_EXTERN NSString *const MPDocumentGroupKey;
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#pragma mark -
|
|
||||||
#pragma mark Edit Sessiong
|
|
||||||
|
|
||||||
APPKIT_EXTERN NSString *const MPDocumentDidBeginEditingSelectedItem;
|
|
||||||
APPKIT_EXTERN NSString *const MPDocumentDidCancelChangesToSelectedItem;
|
|
||||||
APPKIT_EXTERN NSString *const MPDocumentDidCommitChangesToSelectedItem;
|
|
||||||
|
|
||||||
@interface MPDocument (EditingSession)
|
|
||||||
|
|
||||||
#pragma mark Edit Actions
|
|
||||||
- (IBAction)beginEditingSelectedItem:(id)sender;
|
|
||||||
- (IBAction)cancelChangesToSelectedItem:(id)sender;
|
|
||||||
- (IBAction)commitChangesToSelectedItem:(id)sender;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark History Browsing
|
#pragma mark History Browsing
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey
|
|||||||
@property (weak, nonatomic) KPKGroup *root;
|
@property (weak, nonatomic) KPKGroup *root;
|
||||||
@property (nonatomic, strong) KPKCompositeKey *compositeKey;
|
@property (nonatomic, strong) KPKCompositeKey *compositeKey;
|
||||||
@property (nonatomic, strong) NSData *encryptedData;
|
@property (nonatomic, strong) NSData *encryptedData;
|
||||||
@property (nonatomic, strong) MPTreeDelegate *treeDelgate;
|
@property (nonatomic, strong) MPTreeDelegate *treeDelegate;
|
||||||
|
|
||||||
@property (nonatomic, copy) NSArray<KPKNode *> *selectedNodes;
|
@property (nonatomic, copy) NSArray<KPKNode *> *selectedNodes;
|
||||||
|
|
||||||
@@ -75,7 +75,9 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey
|
|||||||
@property (strong) IBOutlet NSView *warningView;
|
@property (strong) IBOutlet NSView *warningView;
|
||||||
@property (weak) IBOutlet NSImageView *warningViewImage;
|
@property (weak) IBOutlet NSImageView *warningViewImage;
|
||||||
|
|
||||||
@property (assign) BOOL fileChangeDialogOpen;;
|
@property (assign) BOOL fileChangeDialogOpen;
|
||||||
|
|
||||||
|
@property (strong) NSMutableDictionary *modifiedEntries;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@@ -412,12 +414,12 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)setTree:(KPKTree *)tree {
|
- (void)setTree:(KPKTree *)tree {
|
||||||
if(_tree != tree) {
|
if(self.tree != tree) {
|
||||||
_tree = tree;
|
_tree = tree;
|
||||||
if(nil == _treeDelgate) {
|
if(nil == self.treeDelegate) {
|
||||||
_treeDelgate = [[MPTreeDelegate alloc] initWithDocument:self];
|
self.treeDelegate = [[MPTreeDelegate alloc] initWithDocument:self];
|
||||||
}
|
}
|
||||||
_tree.delegate = _treeDelgate;
|
self.tree.delegate = self.treeDelegate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -769,6 +771,22 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey
|
|||||||
[self.trash clear];
|
[self.trash clear];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)willChangeEntry:(KPKEntry *)entry {
|
||||||
|
/* we store a copy of the entry */
|
||||||
|
NSAssert(nil == self.modifiedEntries[entry.uuid], @"Inconsistent state, pending changes present for entry!");
|
||||||
|
self.modifiedEntries[entry.uuid] = [entry copy];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)discardChangesToEntry:(KPKEntry *)entry {
|
||||||
|
self.modifiedEntries[entry.uuid] = nil;
|
||||||
|
/* TODO KeePassKit copy entry with info from old entry */
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)commitChangesToEntry:(KPKEntry *)entry {
|
||||||
|
/* TODO KeePassKit entry pushHistory:self.modifiedEntries[entry.uuid] */
|
||||||
|
[self discardChangesToEntry:entry];
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark MPTargetNodeResolving
|
#pragma mark MPTargetNodeResolving
|
||||||
|
|
||||||
|
|||||||
@@ -66,7 +66,4 @@
|
|||||||
|
|
||||||
- (IBAction)toggleQuicklookPreview:(id)sender;
|
- (IBAction)toggleQuicklookPreview:(id)sender;
|
||||||
|
|
||||||
- (void)beginEditing;
|
|
||||||
- (void)endEditing;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -268,6 +268,15 @@ static NSString *kMPContentBindingString3 = @"content.%@.%@.%@";
|
|||||||
MPPasswordCreatorViewController *viewController = [[MPPasswordCreatorViewController alloc] init];
|
MPPasswordCreatorViewController *viewController = [[MPPasswordCreatorViewController alloc] init];
|
||||||
viewController.allowsEntryDefaults = YES;
|
viewController.allowsEntryDefaults = YES;
|
||||||
viewController.representedObject = self.representedObject;
|
viewController.representedObject = self.representedObject;
|
||||||
|
viewController.completionHandler = ^void (NSModalResponse response, NSString *password) {
|
||||||
|
/* TODO mark for modification! */
|
||||||
|
self.generatePasswordButton.enabled = YES;
|
||||||
|
/* We should only use the password if there is actually one */
|
||||||
|
if(password.length > 0) {
|
||||||
|
self.representedEntry.password = password;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
[self _showPopopver:viewController atView:self.passwordTextField onEdge:NSMinYEdge];
|
[self _showPopopver:viewController atView:self.passwordTextField onEdge:NSMinYEdge];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,18 +294,6 @@ static NSString *kMPContentBindingString3 = @"content.%@.%@.%@";
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)popoverDidClose:(NSNotification *)notification {
|
- (void)popoverDidClose:(NSNotification *)notification {
|
||||||
/* We do not enable the button all the time, but it's working find this way */
|
|
||||||
[self.generatePasswordButton setEnabled:YES];
|
|
||||||
NSPopover *popover = notification.object;
|
|
||||||
id controller = _activePopover.contentViewController;
|
|
||||||
/* Check for password wizzard */
|
|
||||||
if([controller respondsToSelector:@selector(generatedPassword)]) {
|
|
||||||
NSString *password = [controller generatedPassword];
|
|
||||||
/* We should only use the password if there is actually one */
|
|
||||||
if(password.length > 0) {
|
|
||||||
self.representedEntry.password = [controller generatedPassword];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.activePopover = nil;
|
self.activePopover = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -437,21 +434,6 @@ static NSString *kMPContentBindingString3 = @"content.%@.%@.%@";
|
|||||||
options:nil];
|
options:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_toggleEditing:(BOOL)edit {
|
|
||||||
NSArray <NSTextField *> *textFields = @[self.titleTextField,
|
|
||||||
self.usernameTextField,
|
|
||||||
self.URLTextField,
|
|
||||||
self.passwordTextField,
|
|
||||||
self.tagsTokenField
|
|
||||||
/*self.createdTextField,
|
|
||||||
self.modifiedTextField*/
|
|
||||||
];
|
|
||||||
for(NSTextField *t in textFields) {
|
|
||||||
t.editable = edit;
|
|
||||||
t.selectable = edit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark MPDocument Notifications
|
#pragma mark MPDocument Notifications
|
||||||
|
|
||||||
|
|||||||
@@ -457,8 +457,6 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
|
|||||||
- (void)_didExitHistory:(NSNotification *)notification {
|
- (void)_didExitHistory:(NSNotification *)notification {
|
||||||
[self _hideContextBar];
|
[self _hideContextBar];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#pragma mark ContextBar
|
#pragma mark ContextBar
|
||||||
- (void)_updateContextBar {
|
- (void)_updateContextBar {
|
||||||
MPDocument *document = [[self windowController] document];
|
MPDocument *document = [[self windowController] document];
|
||||||
|
|||||||
@@ -22,7 +22,4 @@
|
|||||||
@property (weak) IBOutlet NSPopUpButton *autotypePopupButton;
|
@property (weak) IBOutlet NSPopUpButton *autotypePopupButton;
|
||||||
@property (weak) IBOutlet HNHUIRoundedTextField *autotypeSequenceTextField;
|
@property (weak) IBOutlet HNHUIRoundedTextField *autotypeSequenceTextField;
|
||||||
|
|
||||||
- (void)beginEditing;
|
|
||||||
- (void)endEditing;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -19,13 +19,18 @@
|
|||||||
@property (weak) IBOutlet NSTextField *noSelectionInfo;
|
@property (weak) IBOutlet NSTextField *noSelectionInfo;
|
||||||
@property (weak) IBOutlet MPPopupImageView *itemImageView;
|
@property (weak) IBOutlet MPPopupImageView *itemImageView;
|
||||||
@property (weak) IBOutlet NSTextField *itemNameTextField;
|
@property (weak) IBOutlet NSTextField *itemNameTextField;
|
||||||
@property (weak) IBOutlet NSButton *editButton;
|
@property (weak) IBOutlet NSButton *saveChangesButton;
|
||||||
@property (weak) IBOutlet NSButton *cancelEditButton;
|
@property (weak) IBOutlet NSButton *discardChangesButton;
|
||||||
|
|
||||||
- (IBAction)pickIcon:(id)sender;
|
- (IBAction)pickIcon:(id)sender;
|
||||||
- (IBAction)pickExpiryDate:(id)sender;
|
- (IBAction)pickExpiryDate:(id)sender;
|
||||||
|
- (IBAction)saveChanges:(id)sender;
|
||||||
|
- (IBAction)discardChanges:(id)sender;
|
||||||
|
|
||||||
|
|
||||||
/* Separate call to ensure all registered objects are in place */
|
/* Separate call to ensure all registered objects are in place */
|
||||||
- (void)registerNotificationsForDocument:(NSDocument *)document;
|
- (void)registerNotificationsForDocument:(NSDocument *)document;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -100,7 +100,8 @@ typedef NS_ENUM(NSUInteger, MPContentTab) {
|
|||||||
|
|
||||||
[self.view layout];
|
[self.view layout];
|
||||||
|
|
||||||
self.cancelEditButton.hidden = YES;
|
self.discardChangesButton.hidden = YES;
|
||||||
|
self.saveChangesButton.hidden = YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)registerNotificationsForDocument:(MPDocument *)document {
|
- (void)registerNotificationsForDocument:(MPDocument *)document {
|
||||||
@@ -183,6 +184,22 @@ typedef NS_ENUM(NSUInteger, MPContentTab) {
|
|||||||
[self.popover showRelativeToRect:NSZeroRect ofView:sender preferredEdge:NSMinYEdge];
|
[self.popover showRelativeToRect:NSZeroRect ofView:sender preferredEdge:NSMinYEdge];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (void)saveChanges:(id)sender {
|
||||||
|
MPDocument *document = self.windowController.document;
|
||||||
|
KPKEntry *entry = self.representedObject;
|
||||||
|
[document commitChangesToEntry:entry];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)discardChanges:(id)sender {
|
||||||
|
MPDocument *document = self.windowController.document;
|
||||||
|
KPKEntry *entry = self.representedObject;
|
||||||
|
[document discardChangesToEntry:entry];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark NSPopover Delegate
|
||||||
|
|
||||||
- (void)popoverDidClose:(NSNotification *)notification {
|
- (void)popoverDidClose:(NSNotification *)notification {
|
||||||
/* clear out the popover */
|
/* clear out the popover */
|
||||||
self.popover = nil;
|
self.popover = nil;
|
||||||
@@ -206,14 +223,16 @@ typedef NS_ENUM(NSUInteger, MPContentTab) {
|
|||||||
// options:@{NSNullPlaceholderBindingOption: NSLocalizedString(@"NONE", "")}];
|
// options:@{NSNullPlaceholderBindingOption: NSLocalizedString(@"NONE", "")}];
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark -
|
- (void)willChangeValueForRepresentedObjectKeyPath:(NSString *)keyPath {
|
||||||
#pragma mark Editing
|
MPDocument *document = self.windowController.document;
|
||||||
- (void)_toggleEditors:(BOOL)editable {
|
KPKEntry *entry = [self.representedObject asEntry];
|
||||||
self.itemImageView.enabled = editable;
|
if(entry) {
|
||||||
self.itemNameTextField.enabled = editable;
|
[document willChangeEntry:entry];
|
||||||
self.itemImageView.editable = editable;
|
}
|
||||||
self.notesTextView.editable = editable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark MPDocument Notifications
|
#pragma mark MPDocument Notifications
|
||||||
|
|
||||||
@@ -232,24 +251,6 @@ typedef NS_ENUM(NSUInteger, MPContentTab) {
|
|||||||
self.representedObject = node;
|
self.representedObject = node;
|
||||||
self.entryViewController.representedObject = node.asEntry;
|
self.entryViewController.representedObject = node.asEntry;
|
||||||
self.groupViewController.representedObject = node.asGroup;
|
self.groupViewController.representedObject = node.asGroup;
|
||||||
[self _toggleEditors:(nil != node.asGroup)];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)beginEditing:(id)sender {
|
|
||||||
self.editButton.action = @selector(commitEditing:);
|
|
||||||
self.editButton.title = NSLocalizedString(@"SAVE", "");
|
|
||||||
self.cancelEditButton.hidden = NO;
|
|
||||||
[self _toggleEditors:YES];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)cancelEditing:(id)sender {
|
|
||||||
self.editButton.title = NSLocalizedString(@"EDIT", "");
|
|
||||||
self.cancelEditButton.hidden = YES;
|
|
||||||
self.editButton.action = @selector(beginEditing:);
|
|
||||||
[self _toggleEditors:NO];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)commitEditing:(id)sender {
|
|
||||||
[self cancelEditing:sender];
|
|
||||||
}
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -6,14 +6,22 @@
|
|||||||
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
|
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
#import "MPViewController.h"
|
#import "MPViewController.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
@class KPKEntry;
|
@class KPKEntry;
|
||||||
|
|
||||||
@interface MPPasswordCreatorViewController : MPViewController <NSTextFieldDelegate>
|
@interface MPPasswordCreatorViewController : MPViewController <NSTextFieldDelegate>
|
||||||
|
|
||||||
@property (copy, readonly) NSString *generatedPassword;
|
|
||||||
//@property (weak) id closeTarget;
|
//@property (weak) id closeTarget;
|
||||||
@property (assign) BOOL allowsEntryDefaults;
|
@property (assign) BOOL allowsEntryDefaults;
|
||||||
|
/**
|
||||||
|
* Block gets called whenever the user opts to store the password or cancel
|
||||||
|
*/
|
||||||
|
@property (nonatomic, copy, nullable) void (^completionHandler)(NSModalResponse response, NSString *password);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should be called to reset the generator
|
* Should be called to reset the generator
|
||||||
@@ -23,3 +31,5 @@
|
|||||||
- (void)reset;
|
- (void)reset;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
|
|||||||
@@ -171,14 +171,19 @@ typedef NS_ENUM(NSUInteger, MPPasswordRating) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)_usePassword:(id)sender {
|
- (IBAction)_usePassword:(id)sender {
|
||||||
self.generatedPassword = self.password;
|
|
||||||
if(self.shouldCopyPasswordToPasteboardButton.state == NSOnState) {
|
if(self.shouldCopyPasswordToPasteboardButton.state == NSOnState) {
|
||||||
[[MPPasteBoardController defaultController] copyObjects:@[self.password]];
|
[[MPPasteBoardController defaultController] copyObjects:@[self.password]];
|
||||||
}
|
}
|
||||||
|
if(self.completionHandler) {
|
||||||
|
self.completionHandler(NSModalResponseOK, self.password);
|
||||||
|
}
|
||||||
[self.view.window performClose:sender];
|
[self.view.window performClose:sender];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)_cancel:(id)sender {
|
- (IBAction)_cancel:(id)sender {
|
||||||
|
if(self.completionHandler) {
|
||||||
|
self.completionHandler(NSModalResponseCancel, self.password);
|
||||||
|
}
|
||||||
[self.view.window performClose:sender];
|
[self.view.window performClose:sender];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,8 +16,6 @@
|
|||||||
- (NSResponder *)reconmendedFirstResponder;
|
- (NSResponder *)reconmendedFirstResponder;
|
||||||
- (void)updateResponderChain;
|
- (void)updateResponderChain;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#pragma mark Binding Observation
|
#pragma mark Binding Observation
|
||||||
/**
|
/**
|
||||||
* Override this to get notificied when setValue:forKeyPath will be called with a keypath starting with representedObject.
|
* Override this to get notificied when setValue:forKeyPath will be called with a keypath starting with representedObject.
|
||||||
@@ -36,4 +34,6 @@
|
|||||||
*/
|
*/
|
||||||
- (void)didChangeValueForRepresentedObjectKeyPath:(NSString *)keyPath;
|
- (void)didChangeValueForRepresentedObjectKeyPath:(NSString *)keyPath;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
#pragma mark Binding observation
|
#pragma mark Binding observation
|
||||||
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath {
|
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath {
|
||||||
if([keyPath hasPrefix:@"representedObject."]) {
|
if([keyPath hasPrefix:@"representedObject."]) {
|
||||||
[self didChangeValueForRepresentedObjectKeyPath:keyPath];
|
[self willChangeValueForRepresentedObjectKeyPath:keyPath];
|
||||||
[super setValue:value forKeyPath:keyPath];
|
[super setValue:value forKeyPath:keyPath];
|
||||||
[self didChangeValueForRepresentedObjectKeyPath:keyPath];
|
[self didChangeValueForRepresentedObjectKeyPath:keyPath];
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user