Added duplicate entry with options

This commit is contained in:
michael starke
2017-06-08 15:40:08 +02:00
parent 6771d68454
commit 8dd465866e
10 changed files with 172 additions and 42 deletions

View File

@@ -1,3 +1,3 @@
github "sparkle-project/Sparkle" ~> 1.17.0 github "sparkle-project/Sparkle" ~> 1.17.0
github "mstarke/KeePassKit" "b25eab0892f6101ee4929bef3f57788dbc5fa607" github "mstarke/KeePassKit" "6568b250d41e53f1bdc508255432661216d3fe7f"
github "mstarke/HNHUi" ~> 1.1 github "mstarke/HNHUi" ~> 1.1

View File

@@ -1,3 +1,3 @@
github "mstarke/HNHUi" "1.1" github "mstarke/HNHUi" "1.1"
github "mstarke/KeePassKit" "b25eab0892f6101ee4929bef3f57788dbc5fa607" github "mstarke/KeePassKit" "6568b250d41e53f1bdc508255432661216d3fe7f"
github "sparkle-project/Sparkle" "1.17.0" github "sparkle-project/Sparkle" "1.17.0"

View File

@@ -182,6 +182,7 @@
4C888C9716EB754B003D34A1 /* MPActionHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C888C9616EB754B003D34A1 /* MPActionHelper.m */; }; 4C888C9716EB754B003D34A1 /* MPActionHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C888C9616EB754B003D34A1 /* MPActionHelper.m */; };
4C88C66918D9F8D600F43852 /* MPTemporaryFileStorageCenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C88C66818D9F8D600F43852 /* MPTemporaryFileStorageCenter.m */; }; 4C88C66918D9F8D600F43852 /* MPTemporaryFileStorageCenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C88C66818D9F8D600F43852 /* MPTemporaryFileStorageCenter.m */; };
4C8913661A422C8C0071A4CB /* MPFileWatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8913651A422C8C0071A4CB /* MPFileWatcher.m */; }; 4C8913661A422C8C0071A4CB /* MPFileWatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8913651A422C8C0071A4CB /* MPFileWatcher.m */; };
4C8990F71EE978EB0043B48D /* MPDuplicateEntryOptionsWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8990F51EE978EB0043B48D /* MPDuplicateEntryOptionsWindowController.m */; };
4C89B71019B4B4A300DC0A6A /* MPTreeDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C89B70F19B4B4A300DC0A6A /* MPTreeDelegate.m */; }; 4C89B71019B4B4A300DC0A6A /* MPTreeDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C89B70F19B4B4A300DC0A6A /* MPTreeDelegate.m */; };
4C89F524182FB4740069C73C /* MPAutotypeCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C89F523182FB4740069C73C /* MPAutotypeCommand.m */; }; 4C89F524182FB4740069C73C /* MPAutotypeCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C89F523182FB4740069C73C /* MPAutotypeCommand.m */; };
4C8B36AB17A6ED4B005E1FF1 /* MPOutlineContextMenuDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8B36AA17A6ED4B005E1FF1 /* MPOutlineContextMenuDelegate.m */; }; 4C8B36AB17A6ED4B005E1FF1 /* MPOutlineContextMenuDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8B36AA17A6ED4B005E1FF1 /* MPOutlineContextMenuDelegate.m */; };
@@ -592,6 +593,8 @@
4C88C66818D9F8D600F43852 /* MPTemporaryFileStorageCenter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPTemporaryFileStorageCenter.m; sourceTree = "<group>"; }; 4C88C66818D9F8D600F43852 /* MPTemporaryFileStorageCenter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPTemporaryFileStorageCenter.m; sourceTree = "<group>"; };
4C8913641A422C8C0071A4CB /* MPFileWatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPFileWatcher.h; sourceTree = "<group>"; }; 4C8913641A422C8C0071A4CB /* MPFileWatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPFileWatcher.h; sourceTree = "<group>"; };
4C8913651A422C8C0071A4CB /* MPFileWatcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPFileWatcher.m; sourceTree = "<group>"; }; 4C8913651A422C8C0071A4CB /* MPFileWatcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPFileWatcher.m; sourceTree = "<group>"; };
4C8990F41EE978EB0043B48D /* MPDuplicateEntryOptionsWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPDuplicateEntryOptionsWindowController.h; sourceTree = "<group>"; };
4C8990F51EE978EB0043B48D /* MPDuplicateEntryOptionsWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPDuplicateEntryOptionsWindowController.m; sourceTree = "<group>"; };
4C89B70E19B4B4A300DC0A6A /* MPTreeDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPTreeDelegate.h; sourceTree = "<group>"; }; 4C89B70E19B4B4A300DC0A6A /* MPTreeDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPTreeDelegate.h; sourceTree = "<group>"; };
4C89B70F19B4B4A300DC0A6A /* MPTreeDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPTreeDelegate.m; sourceTree = "<group>"; }; 4C89B70F19B4B4A300DC0A6A /* MPTreeDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPTreeDelegate.m; sourceTree = "<group>"; };
4C89F522182FB4740069C73C /* MPAutotypeCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAutotypeCommand.h; sourceTree = "<group>"; }; 4C89F522182FB4740069C73C /* MPAutotypeCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAutotypeCommand.h; sourceTree = "<group>"; };
@@ -1400,6 +1403,9 @@
4C0B038918E36DA400B9F9C9 /* MPFixAutotypeWindowController.h */, 4C0B038918E36DA400B9F9C9 /* MPFixAutotypeWindowController.h */,
4C0B038A18E36DA400B9F9C9 /* MPFixAutotypeWindowController.m */, 4C0B038A18E36DA400B9F9C9 /* MPFixAutotypeWindowController.m */,
4C0B038B18E36DA400B9F9C9 /* FixAutotypeWindow.xib */, 4C0B038B18E36DA400B9F9C9 /* FixAutotypeWindow.xib */,
4C8990F41EE978EB0043B48D /* MPDuplicateEntryOptionsWindowController.h */,
4C8990F51EE978EB0043B48D /* MPDuplicateEntryOptionsWindowController.m */,
4CB915931A0159A20089CE5B /* DuplicateEntryOptionsWindow.xib */,
); );
name = "Window Controller"; name = "Window Controller";
sourceTree = "<group>"; sourceTree = "<group>";
@@ -1423,7 +1429,6 @@
4C1DDCDC1711ECEB00C98DA3 /* PasswordCreatorWindow.xib */, 4C1DDCDC1711ECEB00C98DA3 /* PasswordCreatorWindow.xib */,
4C7F8B6A1A10B68400CCB83D /* WelcomeWindow.xib */, 4C7F8B6A1A10B68400CCB83D /* WelcomeWindow.xib */,
4C0DD6C518B2A44700FCB193 /* AutotypeCandidateSelectionWindow.xib */, 4C0DD6C518B2A44700FCB193 /* AutotypeCandidateSelectionWindow.xib */,
4CB915931A0159A20089CE5B /* DuplicateEntryOptionsWindow.xib */,
); );
name = Windows; name = Windows;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -1776,6 +1781,7 @@
4C10412C178CDD44001B5239 /* NSDate+Humanized.m in Sources */, 4C10412C178CDD44001B5239 /* NSDate+Humanized.m in Sources */,
4C0C59F118B17F10009C7B76 /* DDHotKeyUtilities.m in Sources */, 4C0C59F118B17F10009C7B76 /* DDHotKeyUtilities.m in Sources */,
4CEE46DD181C301D006BF1E5 /* MPAutotypeDaemon.m in Sources */, 4CEE46DD181C301D006BF1E5 /* MPAutotypeDaemon.m in Sources */,
4C8990F71EE978EB0043B48D /* MPDuplicateEntryOptionsWindowController.m in Sources */,
4CA3530B18A53CB800839B0F /* MPKeyMapper.m in Sources */, 4CA3530B18A53CB800839B0F /* MPKeyMapper.m in Sources */,
4CE298EB1795FC2A00DF7BDB /* MPEntryContextMenuDelegate.m in Sources */, 4CE298EB1795FC2A00DF7BDB /* MPEntryContextMenuDelegate.m in Sources */,
4CCCE8011D75CA48006AA951 /* MPArrayController.m in Sources */, 4CCCE8011D75CA48006AA951 /* MPArrayController.m in Sources */,

View File

@@ -1,26 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11762" systemVersion="16D32" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct"> <document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="12121" systemVersion="16F73" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies> <dependencies>
<deployment identifier="macosx"/> <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="12121"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11762"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<objects> <objects>
<customObject id="-2" userLabel="File's Owner"/> <customObject id="-2" userLabel="File's Owner" customClass="MPDuplicateEntryOptionsWindowController">
<connections>
<outlet property="duplicateHistoryCheckButton" destination="DG4-bd-Jhl" id="jU7-PF-AQy"/>
<outlet property="referencePasswordCheckButton" destination="YDe-Wa-lXV" id="I7r-ry-zTz"/>
<outlet property="referenceUsernameCheckButton" destination="KYV-1i-31e" id="mwD-m5-tiZ"/>
<outlet property="window" destination="QvC-M9-y7g" id="LQj-Pb-B9y"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/> <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/> <customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="QvC-M9-y7g"> <window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="QvC-M9-y7g">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/> <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/> <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="364" height="115"/> <rect key="contentRect" x="196" y="240" width="161" height="135"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/> <rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
<view key="contentView" id="EiT-Mj-1SZ"> <view key="contentView" id="EiT-Mj-1SZ">
<rect key="frame" x="0.0" y="0.0" width="364" height="115"/> <rect key="frame" x="0.0" y="0.0" width="310" height="135"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<button translatesAutoresizingMaskIntoConstraints="NO" id="KYV-1i-31e"> <button verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="KYV-1i-31e">
<rect key="frame" x="18" y="79" width="312" height="18"/> <rect key="frame" x="18" y="99" width="274" height="18"/>
<buttonCell key="cell" type="check" title="Replace password and username with refernces" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="O9X-XH-n8o"> <buttonCell key="cell" type="check" title="Reference username instead of copying it" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="O9X-XH-n8o">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="TFC-xG-RlB">
<rect key="frame" x="163" y="13" width="133" height="32"/>
<buttonCell key="cell" type="push" title="Duplicate Entry" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="WqI-qH-ARf">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="duplicateEntry:" target="-2" id="e6Z-Kp-sfb"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="0j0-db-9Wu">
<rect key="frame" x="81" y="13" width="82" height="32"/>
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="x6e-bE-Y6R">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
Gw
</string>
</buttonCell>
<connections>
<action selector="cancel:" target="-2" id="g8K-Ga-tWv"/>
</connections>
</button>
<button translatesAutoresizingMaskIntoConstraints="NO" id="YDe-Wa-lXV">
<rect key="frame" x="18" y="79" width="272" height="18"/>
<buttonCell key="cell" type="check" title="Reference password instead of copying it" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="daA-QV-CDq">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/> <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
</buttonCell> </buttonCell>
@@ -32,39 +68,25 @@
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
</buttonCell> </buttonCell>
</button> </button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="TFC-xG-RlB">
<rect key="frame" x="217" y="13" width="133" height="32"/>
<buttonCell key="cell" type="push" title="Duplicate Entry" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="WqI-qH-ARf">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="0j0-db-9Wu">
<rect key="frame" x="135" y="13" width="82" height="32"/>
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="x6e-bE-Y6R">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
Gw
</string>
</buttonCell>
</button>
</subviews> </subviews>
<constraints> <constraints>
<constraint firstItem="DG4-bd-Jhl" firstAttribute="top" secondItem="YDe-Wa-lXV" secondAttribute="bottom" constant="6" symbolic="YES" id="1hs-wf-aEe"/>
<constraint firstItem="KYV-1i-31e" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" constant="20" id="2MP-Nd-nEI"/> <constraint firstItem="KYV-1i-31e" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" constant="20" id="2MP-Nd-nEI"/>
<constraint firstAttribute="bottom" secondItem="TFC-xG-RlB" secondAttribute="bottom" constant="20" symbolic="YES" id="7dL-yz-Jec"/> <constraint firstAttribute="bottom" secondItem="TFC-xG-RlB" secondAttribute="bottom" constant="20" symbolic="YES" id="7dL-yz-Jec"/>
<constraint firstAttribute="trailing" secondItem="TFC-xG-RlB" secondAttribute="trailing" constant="20" symbolic="YES" id="Bp5-7H-WQn"/> <constraint firstAttribute="trailing" secondItem="TFC-xG-RlB" secondAttribute="trailing" constant="20" symbolic="YES" id="Bp5-7H-WQn"/>
<constraint firstItem="TFC-xG-RlB" firstAttribute="leading" secondItem="0j0-db-9Wu" secondAttribute="trailing" constant="12" id="Mo1-NA-twC"/> <constraint firstItem="TFC-xG-RlB" firstAttribute="leading" secondItem="0j0-db-9Wu" secondAttribute="trailing" constant="12" id="Mo1-NA-twC"/>
<constraint firstItem="YDe-Wa-lXV" firstAttribute="leading" secondItem="KYV-1i-31e" secondAttribute="leading" id="NqU-4e-nL1"/>
<constraint firstItem="TFC-xG-RlB" firstAttribute="centerY" secondItem="0j0-db-9Wu" secondAttribute="centerY" id="OI2-vr-Dxa"/> <constraint firstItem="TFC-xG-RlB" firstAttribute="centerY" secondItem="0j0-db-9Wu" secondAttribute="centerY" id="OI2-vr-Dxa"/>
<constraint firstItem="DG4-bd-Jhl" firstAttribute="top" secondItem="KYV-1i-31e" secondAttribute="bottom" constant="6" id="Qsu-7N-dnm"/>
<constraint firstItem="KYV-1i-31e" firstAttribute="leading" secondItem="DG4-bd-Jhl" secondAttribute="leading" id="TpN-gj-FoI"/> <constraint firstItem="KYV-1i-31e" firstAttribute="leading" secondItem="DG4-bd-Jhl" secondAttribute="leading" id="TpN-gj-FoI"/>
<constraint firstItem="TFC-xG-RlB" firstAttribute="top" secondItem="DG4-bd-Jhl" secondAttribute="bottom" constant="20" symbolic="YES" id="dbV-TU-M0Z"/> <constraint firstItem="TFC-xG-RlB" firstAttribute="top" relation="greaterThanOrEqual" secondItem="DG4-bd-Jhl" secondAttribute="bottom" constant="20" symbolic="YES" id="dbV-TU-M0Z"/>
<constraint firstItem="YDe-Wa-lXV" firstAttribute="top" secondItem="KYV-1i-31e" secondAttribute="bottom" constant="6" symbolic="YES" id="lS4-f0-hSy"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="YDe-Wa-lXV" secondAttribute="trailing" constant="20" symbolic="YES" id="sth-Lq-2Qj"/>
<constraint firstItem="KYV-1i-31e" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="20" id="tvk-Ic-tmq"/> <constraint firstItem="KYV-1i-31e" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="20" id="tvk-Ic-tmq"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="KYV-1i-31e" secondAttribute="trailing" constant="20" symbolic="YES" id="xhH-o0-KHo"/> <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="KYV-1i-31e" secondAttribute="trailing" constant="20" symbolic="YES" id="xhH-o0-KHo"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="DG4-bd-Jhl" secondAttribute="trailing" constant="20" symbolic="YES" id="xnL-R7-g2p"/> <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="DG4-bd-Jhl" secondAttribute="trailing" constant="20" symbolic="YES" id="xnL-R7-g2p"/>
</constraints> </constraints>
</view> </view>
<point key="canvasLocation" x="79" y="236"/> <point key="canvasLocation" x="-787" y="-72"/>
</window> </window>
</objects> </objects>
</document> </document>

View File

@@ -159,6 +159,7 @@ FOUNDATION_EXPORT NSString *const MPDocumentGroupKey;
- (KPKAttribute *)createCustomAttribute:(KPKEntry *)entry; - (KPKAttribute *)createCustomAttribute:(KPKEntry *)entry;
- (void)deleteNode:(KPKNode *)node; - (void)deleteNode:(KPKNode *)node;
- (void)duplicateEntryWithOptions:(KPKCopyOptions)options;
#pragma mark Actions #pragma mark Actions
/** /**
@@ -172,11 +173,8 @@ FOUNDATION_EXPORT NSString *const MPDocumentGroupKey;
* @param sender sender, that should respond to representedObject and return an NSUUID for the template to use * @param sender sender, that should respond to representedObject and return an NSUUID for the template to use
*/ */
- (IBAction)createEntryFromTemplate:(id)sender; - (IBAction)createEntryFromTemplate:(id)sender;
- (IBAction)duplicateEntry:(id)sender; - (IBAction)duplicateEntry:(id)sender;
- (IBAction)duplicateEntryWithOptions:(id)sender;
@end @end
@interface MPDocument (Attachments) @interface MPDocument (Attachments)

View File

@@ -699,18 +699,18 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou
} }
- (void)duplicateEntry:(id)sender { - (void)duplicateEntry:(id)sender {
[self duplicateEntryWithOptions:kKPKCopyOptionNone];
}
- (void)duplicateEntryWithOptions:(KPKCopyOptions)options {
BOOL plural = self.selectedEntries.count > 1;
for(KPKEntry *entry in self.selectedEntries) { for(KPKEntry *entry in self.selectedEntries) {
KPKEntry *duplicate = [entry copyWithTitle:nil options:kKPKCopyOptionNone]; KPKEntry *duplicate = [entry copyWithTitle:nil options:options];
[duplicate addToGroup:entry.parent]; [duplicate addToGroup:entry.parent];
} }
[self.undoManager setActionName:NSLocalizedString(@"DUPLICATE_ENTRY", "")]; [self.undoManager setActionName:plural ? NSLocalizedString(@"DUPLICATE_ENTRIES", "") : NSLocalizedString(@"DUPLICATE_ENTRY", "")];
} }
- (void)duplicateEntryWithOptions:(id)sender {
}
#pragma mark Validation #pragma mark Validation
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem { - (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
return [self validateUserInterfaceItem:menuItem]; return [self validateUserInterfaceItem:menuItem];

View File

@@ -51,6 +51,8 @@
- (IBAction)createEntry:(id)sender; - (IBAction)createEntry:(id)sender;
- (IBAction)delete:(id)sender; - (IBAction)delete:(id)sender;
- (IBAction)duplicateEntryWithOptions:(id)sender;
- (IBAction)pickExpiryDate:(id)sender; - (IBAction)pickExpiryDate:(id)sender;
- (IBAction)performAutotypeForEntry:(id)sender; - (IBAction)performAutotypeForEntry:(id)sender;

View File

@@ -15,6 +15,7 @@
#import "MPDatabaseSettingsWindowController.h" #import "MPDatabaseSettingsWindowController.h"
#import "MPDocument.h" #import "MPDocument.h"
#import "MPDocumentWindowDelegate.h" #import "MPDocumentWindowDelegate.h"
#import "MPDuplicateEntryOptionsWindowController.h"
#import "MPEntryViewController.h" #import "MPEntryViewController.h"
#import "MPFixAutotypeWindowController.h" #import "MPFixAutotypeWindowController.h"
#import "MPInspectorViewController.h" #import "MPInspectorViewController.h"
@@ -397,6 +398,27 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword);
[self.document deleteNode:node]; [self.document deleteNode:node];
} }
} }
- (void)duplicateEntryWithOptions:(id)sender {
MPDuplicateEntryOptionsWindowController *wc = [[MPDuplicateEntryOptionsWindowController alloc] init];
__weak MPDocumentWindowController *welf = self;
[self.window beginSheet:wc.window completionHandler:^(NSModalResponse returnCode) {
if(returnCode == NSModalResponseOK) {
KPKCopyOptions options = kKPKCopyOptionNone;
if(wc.referenceUsername) {
options |= kKPKCopyOptionReferenceUsername;
}
if(wc.referencePassword) {
options |= kKPKCopyOptionReferencePassword;
}
if(wc.duplicateHistory) {
options |= kKPKCopyOptionCopyHistory;
}
[((MPDocument *)welf.document) duplicateEntryWithOptions:options];
}
}];
}
- (void)pickExpiryDate:(id)sender { - (void)pickExpiryDate:(id)sender {
[self.inspectorViewController pickExpiryDate:sender]; [self.inspectorViewController pickExpiryDate:sender];

View File

@@ -0,0 +1,17 @@
//
// MPDuplicateEntryOptionsWindowController.h
// MacPass
//
// Created by Michael Starke on 08.06.17.
// Copyright © 2017 HicknHack Software GmbH. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface MPDuplicateEntryOptionsWindowController : NSWindowController
@property (readonly) BOOL referencePassword;
@property (readonly) BOOL referenceUsername;
@property (readonly) BOOL duplicateHistory;
@end

View File

@@ -0,0 +1,63 @@
//
// MPDuplicateEntryOptionsWindowController.m
// MacPass
//
// Created by Michael Starke on 08.06.17.
// Copyright © 2017 HicknHack Software GmbH. All rights reserved.
//
#import "MPDuplicateEntryOptionsWindowController.h"
@interface MPDuplicateEntryOptionsWindowController ()
@property BOOL referencePassword;
@property BOOL referenceUsername;
@property BOOL duplicateHistory;
@property (weak) IBOutlet NSButton *referenceUsernameCheckButton;
@property (weak) IBOutlet NSButton *referencePasswordCheckButton;
@property (weak) IBOutlet NSButton *duplicateHistoryCheckButton;
@end
@implementation MPDuplicateEntryOptionsWindowController
- (instancetype)initWithWindow:(NSWindow *)window {
self = [super initWithWindow:window];
if(self) {
_referencePassword = NO;
_referenceUsername = NO;
_duplicateHistory = NO;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)coder {
self = [super initWithCoder:coder];
if(self) {
_referencePassword = NO;
_referenceUsername = NO;
_duplicateHistory = NO;
}
return self;
}
- (NSString *)windowNibName {
return @"DuplicateEntryOptionsWindow";
}
- (void)windowDidLoad {
[super windowDidLoad];
[self.referencePasswordCheckButton bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(referencePassword)) options:nil];
[self.referenceUsernameCheckButton bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(referenceUsername)) options:nil];
[self.duplicateHistoryCheckButton bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(duplicateHistory)) options:nil];
}
- (IBAction)duplicateEntry:(id)sender {
[self.window.sheetParent endSheet:self.window returnCode:NSModalResponseOK];
}
- (IBAction)cancel:(id)sender {
[self.window.sheetParent endSheet:self.window returnCode:NSModalResponseCancel];
}
@end