mirror of
https://github.com/MacPass/MacPass.git
synced 2025-12-23 18:39:23 +00:00
Added duplicate entry with options
This commit is contained in:
@@ -1,26 +1,62 @@
|
||||
<?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>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11762"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="12121"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<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="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<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"/>
|
||||
<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"/>
|
||||
<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"/>
|
||||
<subviews>
|
||||
<button translatesAutoresizingMaskIntoConstraints="NO" id="KYV-1i-31e">
|
||||
<rect key="frame" x="18" y="79" width="312" 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">
|
||||
<button verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="KYV-1i-31e">
|
||||
<rect key="frame" x="18" y="99" width="274" height="18"/>
|
||||
<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"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
@@ -32,39 +68,25 @@
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</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>
|
||||
<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 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 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="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="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 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"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<point key="canvasLocation" x="79" y="236"/>
|
||||
<point key="canvasLocation" x="-787" y="-72"/>
|
||||
</window>
|
||||
</objects>
|
||||
</document>
|
||||
|
||||
@@ -159,6 +159,7 @@ FOUNDATION_EXPORT NSString *const MPDocumentGroupKey;
|
||||
- (KPKAttribute *)createCustomAttribute:(KPKEntry *)entry;
|
||||
|
||||
- (void)deleteNode:(KPKNode *)node;
|
||||
- (void)duplicateEntryWithOptions:(KPKCopyOptions)options;
|
||||
|
||||
#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
|
||||
*/
|
||||
- (IBAction)createEntryFromTemplate:(id)sender;
|
||||
|
||||
- (IBAction)duplicateEntry:(id)sender;
|
||||
|
||||
- (IBAction)duplicateEntryWithOptions:(id)sender;
|
||||
|
||||
@end
|
||||
|
||||
@interface MPDocument (Attachments)
|
||||
|
||||
@@ -699,18 +699,18 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou
|
||||
}
|
||||
|
||||
- (void)duplicateEntry:(id)sender {
|
||||
[self duplicateEntryWithOptions:kKPKCopyOptionNone];
|
||||
}
|
||||
|
||||
- (void)duplicateEntryWithOptions:(KPKCopyOptions)options {
|
||||
BOOL plural = self.selectedEntries.count > 1;
|
||||
for(KPKEntry *entry in self.selectedEntries) {
|
||||
KPKEntry *duplicate = [entry copyWithTitle:nil options:kKPKCopyOptionNone];
|
||||
KPKEntry *duplicate = [entry copyWithTitle:nil options:options];
|
||||
[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
|
||||
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
|
||||
return [self validateUserInterfaceItem:menuItem];
|
||||
|
||||
@@ -51,6 +51,8 @@
|
||||
- (IBAction)createEntry:(id)sender;
|
||||
- (IBAction)delete:(id)sender;
|
||||
|
||||
- (IBAction)duplicateEntryWithOptions:(id)sender;
|
||||
|
||||
- (IBAction)pickExpiryDate:(id)sender;
|
||||
|
||||
- (IBAction)performAutotypeForEntry:(id)sender;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#import "MPDatabaseSettingsWindowController.h"
|
||||
#import "MPDocument.h"
|
||||
#import "MPDocumentWindowDelegate.h"
|
||||
#import "MPDuplicateEntryOptionsWindowController.h"
|
||||
#import "MPEntryViewController.h"
|
||||
#import "MPFixAutotypeWindowController.h"
|
||||
#import "MPInspectorViewController.h"
|
||||
@@ -397,6 +398,27 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword);
|
||||
[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 {
|
||||
[self.inspectorViewController pickExpiryDate:sender];
|
||||
|
||||
17
MacPass/MPDuplicateEntryOptionsWindowController.h
Normal file
17
MacPass/MPDuplicateEntryOptionsWindowController.h
Normal 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
|
||||
63
MacPass/MPDuplicateEntryOptionsWindowController.m
Normal file
63
MacPass/MPDuplicateEntryOptionsWindowController.m
Normal 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
|
||||
Reference in New Issue
Block a user