Simple cloning added.

This commit is contained in:
michael starke
2014-02-27 22:33:43 +01:00
parent 90d5bc9ef2
commit 7f03985eff
8 changed files with 128 additions and 18 deletions

View File

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="4514" systemVersion="13C64" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment defaultVersion="1080" identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="4514"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner"/>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application"/>
<window title="Clone Entry" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" wantsToBeColor="NO" animationBehavior="default" id="1">
<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="287" height="115"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1418"/>
<view key="contentView" id="2">
<rect key="frame" x="0.0" y="0.0" width="287" height="115"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="SZv-a7-ifG">
<rect key="frame" x="196" y="13" width="77" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="Clone" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="SfB-Er-9Rw">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
</button>
<button translatesAutoresizingMaskIntoConstraints="NO" id="XpT-SI-BXo">
<rect key="frame" x="75" y="79" width="103" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="check" title="clone history" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="oD5-qB-8vK">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
</button>
<button translatesAutoresizingMaskIntoConstraints="NO" id="r9h-fj-Sew">
<rect key="frame" x="75" y="59" width="137" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="check" title="clone attachments" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="hah-2H-RqN">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="j5y-Yw-WYI">
<rect key="frame" x="111" y="13" width="82" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="XYx-Ie-si3">
<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="XpT-SI-BXo" firstAttribute="top" secondItem="2" secondAttribute="top" constant="20" symbolic="YES" id="9Ro-Kb-xO4"/>
<constraint firstItem="r9h-fj-Sew" firstAttribute="top" secondItem="XpT-SI-BXo" secondAttribute="bottom" constant="6" symbolic="YES" id="JFD-Va-WFi"/>
<constraint firstItem="r9h-fj-Sew" firstAttribute="centerX" secondItem="2" secondAttribute="centerX" id="fDQ-Tk-yhX"/>
<constraint firstAttribute="trailing" secondItem="SZv-a7-ifG" secondAttribute="trailing" constant="20" symbolic="YES" id="hhb-E3-WP7"/>
<constraint firstItem="j5y-Yw-WYI" firstAttribute="baseline" secondItem="SZv-a7-ifG" secondAttribute="baseline" id="kkG-ta-sym"/>
<constraint firstItem="j5y-Yw-WYI" firstAttribute="top" secondItem="r9h-fj-Sew" secondAttribute="bottom" constant="20" symbolic="YES" id="mAF-ad-rDG"/>
<constraint firstItem="SZv-a7-ifG" firstAttribute="leading" secondItem="j5y-Yw-WYI" secondAttribute="trailing" constant="15" id="vId-Wx-Snz"/>
<constraint firstItem="XpT-SI-BXo" firstAttribute="leading" secondItem="r9h-fj-Sew" secondAttribute="leading" id="vUr-UJ-DzQ"/>
</constraints>
</view>
</window>
</objects>
</document>

View File

@@ -15,22 +15,23 @@
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
actionDict = @{
@(MPActionAddEntry): @"createEntry:",
@(MPActionAddGroup): @"createGroup:",
@(MPActionCloneEntry): @"cloneEntry:",
@(MPActionCopyPassword): @"copyPassword:",
@(MPActionCopyURL): @"copyURL:",
@(MPActionCopyUsername): @"copyUsername:",
@(MPActionDelete): @"delete:",
@(MPActionEditPassword): @"editPassword:",
@(MPActionOpenURL): @"openURL:",
@(MPActionToggleInspector): @"toggleInspector:",
@(MPActionLock): @"lock:",
@(MPActionEmptyTrash): @"emptyTrash:",
@(MPActionDatabaseSettings): @"showDatabaseSettings:",
@(MPActionEditTemplateGroup): @"editTemplateGroup:",
@(MPActionExportXML): @"exportAsXML",
@(MPActionImportXML): @"importFromXMl",
@(MPActionAddEntry): @"createEntry:",
@(MPActionAddGroup): @"createGroup:",
@(MPActionCloneEntry): @"cloneEntry:",
@(MPActionCloneEntryWithOptions): @"cloneEntryWithOptions:",
@(MPActionCopyPassword): @"copyPassword:",
@(MPActionCopyURL): @"copyURL:",
@(MPActionCopyUsername): @"copyUsername:",
@(MPActionDelete): @"delete:",
@(MPActionEditPassword): @"editPassword:",
@(MPActionOpenURL): @"openURL:",
@(MPActionToggleInspector): @"toggleInspector:",
@(MPActionLock): @"lock:",
@(MPActionEmptyTrash): @"emptyTrash:",
@(MPActionDatabaseSettings): @"showDatabaseSettings:",
@(MPActionEditTemplateGroup): @"editTemplateGroup:",
@(MPActionExportXML): @"exportAsXML",
@(MPActionImportXML): @"importFromXMl",
};
});
return actionDict;

View File

@@ -13,8 +13,9 @@ typedef NS_OPTIONS(NSUInteger, MPContextMenuItemsFlags) {
MPContextMenuDelete = 1 << 1,
MPContextMenuCopy = 1 << 2,
MPContextMenuTrash = 1 << 3,
MPContextMenuClone = 1 << 4,
MPContextMenuMinimal = MPContextMenuCreate | MPContextMenuDelete,
MPContextMenuFull = MPContextMenuMinimal | MPContextMenuCopy,
MPContextMenuFull = MPContextMenuMinimal | MPContextMenuCopy | MPContextMenuClone,
MPContextMenuExtended = MPContextMenuFull | MPContextMenuTrash
};

View File

@@ -25,6 +25,7 @@ static void MPContextmenuHelperBeginSection(NSMutableArray *items) {
BOOL const insertDelete = MPTestFlagInOptions(MPContextMenuDelete, flags);
BOOL const insertCopy = MPTestFlagInOptions(MPContextMenuCopy, flags);
BOOL const insertTrash = MPTestFlagInOptions(MPContextMenuTrash, flags);
BOOL const insertClone = MPTestFlagInOptions(MPContextMenuClone, flags);
NSMutableArray *items = [NSMutableArray arrayWithCapacity:10];
if(insertCreate) {
@@ -38,6 +39,18 @@ static void MPContextmenuHelperBeginSection(NSMutableArray *items) {
[items addObjectsFromArray:@[ newGroup, newEntry ]];
}
if(insertClone) {
MPContextmenuHelperBeginSection(items);
NSMenuItem *cloneEntry = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"CLONE_ENTRY", @"")
action:[MPActionHelper actionOfType:MPActionCloneEntry]
keyEquivalent:@"D"];
NSMenuItem *cloneEntyWithOptions = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"CLONE_ENTRY_WITH_OPTIONS", @"")
action:[MPActionHelper actionOfType:MPActionCloneEntryWithOptions]
keyEquivalent:@""];
[items addObjectsFromArray:@[ cloneEntry, cloneEntyWithOptions ]];
}
if(insertDelete || insertTrash) {
MPContextmenuHelperBeginSection(items);
if(insertDelete) {

View File

@@ -165,4 +165,8 @@ typedef NS_OPTIONS(NSUInteger, MPEntrySearchFlags) {
*/
- (IBAction)createEntryFromTemplate:(id)sender;
- (IBAction)cloneEntry:(id)sender;
- (IBAction)cloneEntryWithOptions:(id)sender;
@end

View File

@@ -489,6 +489,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey
#pragma mark Actions
- (void)emptyTrash:(id)sender {
NSAlert *alert = [[NSAlert alloc] init];
[alert setAlertStyle:NSWarningAlertStyle];
@@ -528,6 +529,18 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey
}
}
- (void)cloneEntry:(id)sender {
KPKEntry *clone = [self.selectedEntry copyWithTitle:nil];
NSInteger index = [self.selectedEntry.parent.entries indexOfObject:self.selectedEntry];
[self.selectedEntry.parent addEntry:clone atIndex:index+1];
[self.undoManager setActionName:NSLocalizedString(@"CLONE_ENTRY", "")];
}
- (void)cloneEntryWithOptions:(id)sender {
}
#pragma mark Validation
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
return [self validateUserInterfaceItem:menuItem];
}
@@ -538,7 +551,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey
- (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)anItem {
if(self.encrypted || self.isReadOnly) { return NO; }
BOOL valid = YES;
switch([MPActionHelper typeForAction:[anItem action]]) {
case MPActionAddGroup:
@@ -551,6 +564,11 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey
valid &= (self.trash != self.selectedItem);
valid &= ![self isItemTrashed:self.selectedItem];
break;
case MPActionCloneEntry:
//case MPActionCloneEntryWithOptions:
valid &= (nil != self.selectedItem);
valid &= self.selectedEntry == self.selectedItem;
break;
case MPActionEmptyTrash:
valid &= [self.trash.groups count] > 0;
valid &= [self.trash.entries count] > 0;

Binary file not shown.