Stubbed custom attribute adding via context menu

Made MPContextToolbarButton usable as normal button.
Added private API helper for adding buttons to NSUserNotification
Remove Autotype plugin API
Enhanced custom attribute plugin API
Enhanced EntryActionPlugin API to decouple menu items from actual action/target setup
Stubbed action on no-open documents NSUserNotifications
Stubbed HMACOTP custom attribute setup
This commit is contained in:
Michael Starke
2017-12-05 15:56:06 +01:00
parent e8ddbd092c
commit 5574b01fed
20 changed files with 243 additions and 112 deletions

View File

@@ -12,6 +12,8 @@
4C01C2421764D8980016D5D0 /* MPContextMenuHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C01C2411764D8980016D5D0 /* MPContextMenuHelper.m */; };
4C0728BD17B5B7F7005A7DD9 /* MPPasswordEditWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C0728BC17B5B7F7005A7DD9 /* MPPasswordEditWindowController.m */; };
4C0728BF17B68ED0005A7DD9 /* SavePanelAccessoryView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C0728BE17B68ED0005A7DD9 /* SavePanelAccessoryView.xib */; };
4C0949591FD6B89B004F2971 /* NSUserNotification+MPAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C0949581FD6B89B004F2971 /* NSUserNotification+MPAdditions.m */; };
4C09495C1FD6E510004F2971 /* MPAddCustomFieldContextMenuDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C09495B1FD6E510004F2971 /* MPAddCustomFieldContextMenuDelegate.m */; };
4C0AF62F195C1F2B009E658D /* MPEntrySearchContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C0AF62E195C1F2B009E658D /* MPEntrySearchContext.m */; };
4C0B038C18E36DA400B9F9C9 /* MPFixAutotypeWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C0B038A18E36DA400B9F9C9 /* MPFixAutotypeWindowController.m */; };
4C0B038D18E36DA400B9F9C9 /* FixAutotypeWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C0B038B18E36DA400B9F9C9 /* FixAutotypeWindow.xib */; };
@@ -129,7 +131,7 @@
4C5FE9AE17843CE20001D5A8 /* MPSelectedAttachmentTableCellView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C5FE9AD17843CE20001D5A8 /* MPSelectedAttachmentTableCellView.m */; };
4C61EA0316D2FD0800AC519E /* MPOutlineViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C61EA0216D2FD0800AC519E /* MPOutlineViewController.m */; };
4C61EA0516D2FFE200AC519E /* OutlineView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C61EA0416D2FFE200AC519E /* OutlineView.xib */; };
4C63B8FB17A3154D0091BD72 /* MPContextToolbarButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C63B8FA17A3154D0091BD72 /* MPContextToolbarButton.m */; };
4C63B8FB17A3154D0091BD72 /* MPContextButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C63B8FA17A3154D0091BD72 /* MPContextButton.m */; };
4C65C79C16DD283900E32CFF /* MPToolbarButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C65C79B16DD283900E32CFF /* MPToolbarButton.m */; };
4C65FAE916D16DDB006E0577 /* MPPasswordInputController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C65FAE716D16DDB006E0577 /* MPPasswordInputController.m */; };
4C663D411D6D91A900CB6237 /* MPNumberFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C663D401D6D91A900CB6237 /* MPNumberFormatter.m */; };
@@ -324,6 +326,10 @@
4C0728BB17B5B7F7005A7DD9 /* MPPasswordEditWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPasswordEditWindowController.h; sourceTree = "<group>"; };
4C0728BC17B5B7F7005A7DD9 /* MPPasswordEditWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPPasswordEditWindowController.m; sourceTree = "<group>"; };
4C0728BE17B68ED0005A7DD9 /* SavePanelAccessoryView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SavePanelAccessoryView.xib; sourceTree = "<group>"; };
4C0949571FD6B89B004F2971 /* NSUserNotification+MPAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSUserNotification+MPAdditions.h"; sourceTree = "<group>"; };
4C0949581FD6B89B004F2971 /* NSUserNotification+MPAdditions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSUserNotification+MPAdditions.m"; sourceTree = "<group>"; };
4C09495A1FD6E510004F2971 /* MPAddCustomFieldContextMenuDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MPAddCustomFieldContextMenuDelegate.h; sourceTree = "<group>"; };
4C09495B1FD6E510004F2971 /* MPAddCustomFieldContextMenuDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MPAddCustomFieldContextMenuDelegate.m; sourceTree = "<group>"; };
4C0AF62D195C1F2B009E658D /* MPEntrySearchContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPEntrySearchContext.h; sourceTree = "<group>"; };
4C0AF62E195C1F2B009E658D /* MPEntrySearchContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPEntrySearchContext.m; sourceTree = "<group>"; };
4C0B038918E36DA400B9F9C9 /* MPFixAutotypeWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPFixAutotypeWindowController.h; sourceTree = "<group>"; };
@@ -517,8 +523,8 @@
4C61EA0116D2FD0800AC519E /* MPOutlineViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPOutlineViewController.h; sourceTree = "<group>"; };
4C61EA0216D2FD0800AC519E /* MPOutlineViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPOutlineViewController.m; sourceTree = "<group>"; };
4C61EA0416D2FFE200AC519E /* OutlineView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = OutlineView.xib; sourceTree = "<group>"; };
4C63B8F917A3154D0091BD72 /* MPContextToolbarButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPContextToolbarButton.h; sourceTree = "<group>"; };
4C63B8FA17A3154D0091BD72 /* MPContextToolbarButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPContextToolbarButton.m; sourceTree = "<group>"; };
4C63B8F917A3154D0091BD72 /* MPContextButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPContextButton.h; sourceTree = "<group>"; };
4C63B8FA17A3154D0091BD72 /* MPContextButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPContextButton.m; sourceTree = "<group>"; };
4C65C79A16DD283900E32CFF /* MPToolbarButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPToolbarButton.h; sourceTree = "<group>"; };
4C65C79B16DD283900E32CFF /* MPToolbarButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPToolbarButton.m; sourceTree = "<group>"; };
4C65FAE616D16DDB006E0577 /* MPPasswordInputController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPasswordInputController.h; sourceTree = "<group>"; };
@@ -1005,6 +1011,8 @@
4CDA35741EBA0CF2003CD59F /* NSString+MPComposedCharacterAdditions.m */,
4C8F0C771FD05A6A00BE157F /* NSString+MPPrettyPasswordDisplay.h */,
4C8F0C781FD05A6A00BE157F /* NSString+MPPrettyPasswordDisplay.m */,
4C0949571FD6B89B004F2971 /* NSUserNotification+MPAdditions.h */,
4C0949581FD6B89B004F2971 /* NSUserNotification+MPAdditions.m */,
);
name = Categories;
sourceTree = "<group>";
@@ -1094,6 +1102,8 @@
4CE501331BBC47F500FB819D /* MPTagsTokenFieldDelegate.m */,
4C2F17A01FD69BCA0097418D /* MPUserNotificationCenterDelegate.h */,
4C2F17A11FD69BCA0097418D /* MPUserNotificationCenterDelegate.m */,
4C09495A1FD6E510004F2971 /* MPAddCustomFieldContextMenuDelegate.h */,
4C09495B1FD6E510004F2971 /* MPAddCustomFieldContextMenuDelegate.m */,
);
name = Delegates;
sourceTree = "<group>";
@@ -1515,8 +1525,8 @@
4C65C79B16DD283900E32CFF /* MPToolbarButton.m */,
4C888C9116EB6F5E003D34A1 /* MPToolbarItem.h */,
4C888C9216EB6F5E003D34A1 /* MPToolbarItem.m */,
4C63B8F917A3154D0091BD72 /* MPContextToolbarButton.h */,
4C63B8FA17A3154D0091BD72 /* MPContextToolbarButton.m */,
4C63B8F917A3154D0091BD72 /* MPContextButton.h */,
4C63B8FA17A3154D0091BD72 /* MPContextButton.m */,
4C57AE1217BA422B00CA4F34 /* MPSegmentedContextCell.h */,
4C57AE1317BA422B00CA4F34 /* MPSegmentedContextCell.m */,
8345D7271F39023E002B7B0F /* MPPathControl.h */,
@@ -1961,7 +1971,7 @@
4CB33F861EAF54A000C9341E /* KPKNode+MPIsHistory.m in Sources */,
4CCEDE2E179F213B008402BE /* MPNotifications.m in Sources */,
4C17D8E517A1C780006C8C1E /* MPDocumentWindowDelegate.m in Sources */,
4C63B8FB17A3154D0091BD72 /* MPContextToolbarButton.m in Sources */,
4C63B8FB17A3154D0091BD72 /* MPContextButton.m in Sources */,
4C1E9885185F71A800943563 /* MPContextBarViewController.m in Sources */,
4C1FA07B18231900003A3F8C /* MPDocument+Autotype.m in Sources */,
4C4B7EE917A45EC6000234C7 /* MPDatePickingViewController.m in Sources */,
@@ -1974,9 +1984,11 @@
8345D7291F39023E002B7B0F /* MPPathControl.m in Sources */,
4CD7223B17A7CB0700F5A1E1 /* MPWorkflowSettingsController.m in Sources */,
4CA08DA017A831B200A6544B /* MPAddEntryContextMenuDelegate.m in Sources */,
4C09495C1FD6E510004F2971 /* MPAddCustomFieldContextMenuDelegate.m in Sources */,
4CE3E62617AB0D2D00D9E4B4 /* MPAttachmentTableDataSource.m in Sources */,
4C0728BD17B5B7F7005A7DD9 /* MPPasswordEditWindowController.m in Sources */,
4C0F647B17B6BC9C00D9522A /* MPSavePanelAccessoryViewController.m in Sources */,
4C0949591FD6B89B004F2971 /* NSUserNotification+MPAdditions.m in Sources */,
4C3B42871F935316007B04FD /* MPDayCountFormatter.m in Sources */,
4C57AE1417BA422B00CA4F34 /* MPSegmentedContextCell.m in Sources */,
4CE2961518429AA5005F01CE /* MPAutotypeKeyPress.m in Sources */,

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13529" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13771" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13529"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13771"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@@ -10,7 +10,7 @@
<connections>
<outlet property="URLTextField" destination="56" id="262"/>
<outlet property="addAttachmentButton" destination="177" id="w3F-U0-Rpk"/>
<outlet property="addCustomFieldButton" destination="179" id="I3F-Sp-dbI"/>
<outlet property="addCustomFieldButton" destination="G9J-nn-2bu" id="vco-Lt-hkc"/>
<outlet property="addWindowAssociationButton" destination="Iy9-9L-Aev" id="kDA-Mm-lah"/>
<outlet property="associationSequenceTextField" destination="NjR-ea-Y7k" id="kTb-Y5-XrZ"/>
<outlet property="attachmentTableView" destination="137" id="265"/>
@@ -455,17 +455,6 @@
<outlet property="delegate" destination="-2" id="bJ5-Un-81o"/>
</connections>
</textField>
<button focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="179">
<rect key="frame" x="200" y="100" width="71" height="25"/>
<buttonCell key="cell" type="roundTextured" title="Add Field" bezelStyle="texturedRounded" alignment="center" state="on" borderStyle="border" focusRingType="none" imageScaling="proportionallyDown" inset="2" id="232">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="addCustomField:" target="-2" id="273"/>
<outlet property="nextKeyView" destination="193" id="aWG-La-YP3"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="QSX-Xo-tcH">
<rect key="frame" x="20" y="18" width="251" height="25"/>
<buttonCell key="cell" type="roundTextured" title="Show Plugin Data" bezelStyle="texturedRounded" alignment="center" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="X9y-K7-lix">
@@ -477,6 +466,20 @@
<outlet property="nextKeyView" destination="53" id="HTB-dl-8aH"/>
</connections>
</button>
<segmentedControl verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="G9J-nn-2bu" customClass="MPContextButton">
<rect key="frame" x="220" y="100" width="51" height="25"/>
<segmentedCell key="cell" borderStyle="border" alignment="left" style="texturedRounded" trackingMode="selectOne" id="POU-2t-8fl">
<font key="font" metaFont="system"/>
<segments>
<segment image="NSAddTemplate" width="32"/>
<segment/>
</segments>
</segmentedCell>
<connections>
<action selector="addCustomField:" target="-2" id="3sZ-a1-V2r"/>
<outlet property="nextKeyView" destination="QSX-Xo-tcH" id="P9m-Wl-V3E"/>
</connections>
</segmentedControl>
</subviews>
<constraints>
<constraint firstItem="52" firstAttribute="top" secondItem="4" secondAttribute="top" constant="5" id="11"/>
@@ -513,24 +516,24 @@
<constraint firstItem="QSX-Xo-tcH" firstAttribute="leading" secondItem="4" secondAttribute="leading" constant="20" symbolic="YES" id="2AA-hQ-mL7"/>
<constraint firstItem="IpW-b2-jWu" firstAttribute="leading" secondItem="4" secondAttribute="leading" constant="20" id="51R-pR-KLO"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="52" secondAttribute="trailing" constant="20" symbolic="YES" id="6P6-fW-kGx"/>
<constraint firstAttribute="trailing" secondItem="179" secondAttribute="trailing" constant="20" symbolic="YES" id="Bys-px-9xs"/>
<constraint firstAttribute="trailing" secondItem="IpW-b2-jWu" secondAttribute="trailing" constant="20" id="D0t-s7-2hT"/>
<constraint firstItem="0U8-TS-giU" firstAttribute="top" secondItem="179" secondAttribute="bottom" constant="8" symbolic="YES" id="GNj-yE-507"/>
<constraint firstItem="7" firstAttribute="top" secondItem="56" secondAttribute="bottom" constant="12" id="Gh9-Lg-kcm"/>
<constraint firstItem="IpW-b2-jWu" firstAttribute="top" secondItem="0U8-TS-giU" secondAttribute="bottom" constant="8" symbolic="YES" id="HSM-Aj-X9I"/>
<constraint firstItem="58" firstAttribute="top" secondItem="55" secondAttribute="bottom" constant="12" id="JiM-Dm-AG8"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="57" secondAttribute="trailing" constant="20" symbolic="YES" id="N4A-wg-PdS"/>
<constraint firstItem="179" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="4" secondAttribute="leading" constant="20" symbolic="YES" id="OUg-H1-uyM"/>
<constraint firstItem="QSX-Xo-tcH" firstAttribute="top" secondItem="IpW-b2-jWu" secondAttribute="bottom" constant="8" symbolic="YES" id="TPp-cx-48q"/>
<constraint firstItem="8" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="7" secondAttribute="trailing" constant="8" symbolic="YES" id="Xa5-Ir-XNC"/>
<constraint firstAttribute="bottom" secondItem="QSX-Xo-tcH" secondAttribute="bottom" constant="20" symbolic="YES" id="ZdF-5c-xDa"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="0U8-TS-giU" secondAttribute="trailing" constant="20" symbolic="YES" id="a5R-eI-VuV"/>
<constraint firstItem="0U8-TS-giU" firstAttribute="top" secondItem="G9J-nn-2bu" secondAttribute="bottom" constant="8" symbolic="YES" id="aes-tv-LHA"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="54" secondAttribute="trailing" constant="20" symbolic="YES" id="cYP-oK-dVP"/>
<constraint firstAttribute="trailing" secondItem="G9J-nn-2bu" secondAttribute="trailing" constant="20" symbolic="YES" id="ggu-f5-LtR"/>
<constraint firstAttribute="trailing" secondItem="QSX-Xo-tcH" secondAttribute="trailing" constant="20" symbolic="YES" id="hr2-Eb-g24"/>
<constraint firstItem="0U8-TS-giU" firstAttribute="leading" secondItem="4" secondAttribute="leading" constant="20" id="kLH-Bj-C5m"/>
<constraint firstItem="57" firstAttribute="top" secondItem="59" secondAttribute="bottom" constant="8" symbolic="YES" id="lYe-am-xJx"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="58" secondAttribute="trailing" constant="20" symbolic="YES" id="rbs-i7-bti"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="6" secondAttribute="trailing" constant="20" symbolic="YES" id="uuh-ba-z4h"/>
<constraint firstItem="G9J-nn-2bu" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="4" secondAttribute="leading" constant="20" symbolic="YES" id="z4K-PB-Qfb"/>
</constraints>
<point key="canvasLocation" x="-679" y="-1054"/>
</customView>
@@ -898,7 +901,7 @@
<autoresizingMask key="autoresizingMask"/>
</scroller>
<connections>
<outlet property="nextKeyView" destination="QSX-Xo-tcH" id="KP9-D4-4cC"/>
<outlet property="nextKeyView" destination="G9J-nn-2bu" id="CZ9-f2-JDQ"/>
</connections>
<point key="canvasLocation" x="-1015" y="-1275"/>
</scrollView>

View File

@@ -0,0 +1,15 @@
//
// MPAddCustomFieldContextMenuDelegate.h
// MacPass
//
// Created by Michael Starke on 05.12.17.
// Copyright © 2017 HicknHack Software GmbH. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface MPAddCustomFieldContextMenuDelegate : NSObject <NSMenuDelegate>
@property (weak) NSViewController *viewController;
@end

View File

@@ -0,0 +1,58 @@
//
// MPAddCustomFieldContextMenuDelegate.m
// MacPass
//
// Created by Michael Starke on 05.12.17.
// Copyright © 2017 HicknHack Software GmbH. All rights reserved.
//
#import "MPAddCustomFieldContextMenuDelegate.h"
#import "KeePassKit/KeePassKit.h"
NSString *const MPHMACOTPSeedAttributeKey = @"HMACOTP-Seed";
NSString *const MPHMACOTPConfigAttributeKey = @"HMACOTP-Config";
@interface MPAddCustomFieldContextMenuDelegate ()
@property (readonly, nonatomic) KPKEntry *entry;
@end
@implementation MPAddCustomFieldContextMenuDelegate
- (KPKEntry *)entry {
KPKEntry *entry = self.viewController.representedObject;
if([entry isKindOfClass:KPKEntry.class]) {
return entry;
}
return nil;
}
- (void)menuNeedsUpdate:(NSMenu *)menu {
[menu removeAllItems];
[self _setupHOTPMenuItemsToMenu:menu];
}
- (void)_setupHOTPMenuItemsToMenu:(NSMenu *)menu {
BOOL hasConfigAttribute = nil != [self.entry customAttributeWithKey:MPHMACOTPConfigAttributeKey];
if(!hasConfigAttribute) {
NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:@"Add config" action:@selector(_addHMACConfig:) keyEquivalent:@""];
item.target = self;
[menu addItem:item];
}
BOOL hasSeedAttribute = nil != [self.entry customAttributeWithKey:MPHMACOTPSeedAttributeKey];
if(!hasSeedAttribute) {
NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:@"Add seed" action:@selector(_addHMACSeed:) keyEquivalent:@""];
item.target = self;
[menu addItem:item];
}
}
- (IBAction)_addHMACConfig:(id)sender {
[self.entry addCustomAttribute:[[KPKAttribute alloc] initWithKey:MPHMACOTPConfigAttributeKey value:@"<config>"]];
}
- (IBAction)_addHMACSeed:(id)sender {
[self.entry addCustomAttribute:[[KPKAttribute alloc] initWithKey:MPHMACOTPSeedAttributeKey value:@"<seed>"]];
}
@end

View File

@@ -38,6 +38,7 @@
#import "MPPrettyPasswordTransformer.h"
#import "MPTemporaryFileStorageCenter.h"
#import "MPValueTransformerHelper.h"
#import "MPUserNotificationCenterDelegate.h"
#import "NSApplication+MPAdditions.h"
@@ -50,6 +51,7 @@ NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDi
@interface MPAppDelegate () {
@private
MPDockTileHelper *_dockTileHelper;
MPUserNotificationCenterDelegate *_userNotificationCenterDelegate;
BOOL _shouldOpenFile; // YES if app was started to open a
}
@@ -71,6 +73,7 @@ NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDi
- (instancetype)init {
self = [super init];
if(self) {
_userNotificationCenterDelegate = [[MPUserNotificationCenterDelegate alloc] init];
/* We know that we do not use the variable after instantiation */
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-variable"

View File

@@ -22,23 +22,20 @@
#import "MPAutotypeDaemon.h"
#import "MPDocument.h"
#import "MPAutotypeCommand.h"
#import "MPAutotypeContext.h"
#import "MPAutotypePaste.h"
#import "MPPasteBoardController.h"
#import "MPSettingsHelper.h"
#import "NSApplication+MPAdditions.h"
#import "MPAutotypeCandidateSelectionViewController.h"
#import "KeePassKit/KeePassKit.h"
#import "NSApplication+MPAdditions.h"
#import "NSUserNotification+MPAdditions.h"
#import "DDHotKeyCenter.h"
#import "DDHotKey+MacPassAdditions.h"
#import "KeePassKit/KeePassKit.h"
#import <Carbon/Carbon.h>
NSString *const kMPWindowTitleKey = @"kMPWindowTitleKey";
@@ -170,7 +167,8 @@ static MPAutotypeDaemon *_sharedInstance;
NSUserNotification *notification = [[NSUserNotification alloc] init];
notification.title = NSApp.applicationName;
notification.informativeText = NSLocalizedString(@"AUTOTYPE_OVERLAY_NO_DOCUMENTS", "Notification: Autotype failed, no documents are open");
notification.actionButtonTitle = NSLocalizedString(@"OPEN_DOCUMENT", "Action button in Notification to open a document");
//notification.showsButtons = YES;
[NSUserNotificationCenter.defaultUserNotificationCenter deliverNotification:notification];
return;
}

View File

@@ -22,12 +22,10 @@
#import <Cocoa/Cocoa.h>
@interface MPContextToolbarButton : NSSegmentedControl
@interface MPContextButton : NSSegmentedControl
@property (nonatomic, strong) NSMenu *contextMenu;
- (void)setImage:(NSImage *)image;
- (void)setContextMenu:(NSMenu *)menu;
- (NSControlSize)controlSize;
- (void)setControlSize:(NSControlSize)controlSize;
@end

View File

@@ -20,41 +20,51 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
#import "MPContextToolbarButton.h"
#import "MPContextButton.h"
#import "MPSegmentedContextCell.h"
@interface MPContextToolbarButton () {
@private
NSMenu *_contextMenu;
}
@interface MPContextButton ()
@end
@implementation MPContextToolbarButton
@implementation MPContextButton
- (id)initWithFrame:(NSRect)frame {
- (instancetype)initWithCoder:(NSCoder *)coder {
self = [super initWithCoder:coder];
if(self) {
[self _setup];
}
return self;
}
- (instancetype)initWithFrame:(NSRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self _setup];
}
return self;
}
- (void)_setup {
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:[self cell]];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
MPSegmentedContextCell *cell = [[MPSegmentedContextCell alloc] initWithCoder:unarchiver];
self.cell = cell;
self.focusRingType = NSFocusRingTypeNone;
self.segmentStyle = NSSegmentStyleTexturedSquare;
self.segmentCount = 2;
cell.trackingMode = NSSegmentSwitchTrackingMomentary;
self.segmentStyle = NSSegmentStyleTexturedSquare;
[cell setWidth:31 forSegment:0];
[cell setWidth:17 forSegment:1];
cell.trackingMode = NSSegmentSwitchTrackingMomentary;
NSImage *contextTriangle = [[NSBundle mainBundle] imageForResource:@"contextTriangleTemplate"];
NSImage *contextTriangle = [NSBundle.mainBundle imageForResource:@"contextTriangleTemplate"];
[self setImage:contextTriangle forSegment:1];
cell.contextMenuAction = @selector(showContextMenu:);
cell.contextMenuTarget = self;
}
return self;
}
- (void)setContextMenu:(NSMenu *)menu {
if(_contextMenu != menu) {
@@ -106,25 +116,11 @@
default:
break;
}
if([self.superclass instancesRespondToSelector:@selector(setControlSize:)]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunguarded-availability"
super.controlSize = controlSize;
#pragma clang diagnostic pop
}
else {
self.cell.controlSize = controlSize;
}
}
- (NSControlSize)controlSize {
if([self.superclass instancesRespondToSelector:@selector(controlSize)]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunguarded-availability"
return super.controlSize;
#pragma clang diagnostic pop
}
return self.cell.controlSize;
}
@end

View File

@@ -25,7 +25,7 @@
#import "MPAppDelegate.h"
#import "MPAutotypeDaemon.h"
#import "MPConstants.h"
#import "MPContextToolbarButton.h"
#import "MPContextButton.h"
#import "MPDatabaseSettingsWindowController.h"
#import "MPDocument.h"
#import "MPDocumentWindowDelegate.h"

View File

@@ -25,6 +25,7 @@
#import <Quartz/Quartz.h>
@class HNHUIRoundedSecureTextField;
@class MPContextButton;
@class MPDocument;
@interface MPEntryInspectorViewController : MPViewController <NSPopoverDelegate, QLPreviewPanelDelegate, HNHUITextFieldDelegate>
@@ -48,7 +49,7 @@
@property (weak) IBOutlet NSTextField *createdTextField;
@property (weak) IBOutlet NSTextField *modifiedTextField;
@property (weak) IBOutlet NSButton *addCustomFieldButton;
@property (weak) IBOutlet MPContextButton *addCustomFieldButton;
/* Attachments */
@property (weak) IBOutlet NSButtonCell *addAttachmentButton;

View File

@@ -43,6 +43,8 @@
#import "MPActionHelper.h"
#import "MPSettingsHelper.h"
#import "MPPasteBoardController.h"
#import "MPContextButton.h"
#import "MPAddCustomFieldContextMenuDelegate.h"
#import "MPArrayController.h"
@@ -67,6 +69,7 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
MPWindowAssociationsTableViewDelegate *_windowAssociationsTableDelegate;
MPWindowTitleComboBoxDelegate *_windowTitleMenuDelegate;
MPTagsTokenFieldDelegate *_tagTokenFieldDelegate;
MPAddCustomFieldContextMenuDelegate *_addCustomFieldContextMenuDelegate;
}
@property (nonatomic, assign) BOOL showPassword;
@@ -97,9 +100,12 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
_windowAssociationsTableDelegate = [[MPWindowAssociationsTableViewDelegate alloc] init];
_windowTitleMenuDelegate = [[MPWindowTitleComboBoxDelegate alloc] init];
_tagTokenFieldDelegate = [[MPTagsTokenFieldDelegate alloc] init];
_addCustomFieldContextMenuDelegate = [[MPAddCustomFieldContextMenuDelegate alloc] init];
_tagTokenFieldDelegate.viewController = self;
_attachmentTableDelegate.viewController = self;
_customFieldTableDelegate.viewController = self;
_addCustomFieldContextMenuDelegate.viewController = self;
_activeTab = MPEntryTabGeneral;
}
return self;
@@ -166,6 +172,7 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
self.tagsTokenField.delegate = _tagTokenFieldDelegate;
[self _setupCustomFieldsButton];
[self _setupViewBindings];
}
@@ -542,6 +549,14 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
}
- (void)_setupCustomFieldsButton {
/* FIXME: this is a bug in MPContextButton preventing the image set in IB to be used */
[self.addCustomFieldButton setImage:[NSImage imageNamed:NSImageNameAddTemplate]];
NSMenu *customFieldMenu = [[NSMenu alloc] initWithTitle:NSLocalizedString(@"ADD_CUSTOM_FIELD_CONTEXT_MENU", @"Menu displayed for adding special custom keys")];
customFieldMenu.delegate = _addCustomFieldContextMenuDelegate;
self.addCustomFieldButton.contextMenu = customFieldMenu;
}
#pragma mark -
#pragma mark HNHUITextFieldDelegate
- (NSMenu *)textField:(NSTextField *)textField textView:(NSTextView *)view menu:(NSMenu *)menu {

View File

@@ -46,7 +46,7 @@
for(NSString *character in string.composedCharacters) {
}
return nil;
}
/*

View File

@@ -27,6 +27,7 @@ NS_ASSUME_NONNULL_BEGIN
@class MPPluginHost;
@class MPAutotypeCommand;
@class KPKEntry;
@class KPKAttribute;
@interface MPPlugin : NSObject
@@ -35,8 +36,6 @@ NS_ASSUME_NONNULL_BEGIN
@property (copy, readonly) NSString *version;
@property (nonatomic, strong, readonly) NSBundle *bundle;
@property (readonly) NSString *requiredHostVersion; // the host version required for running the plugin in mayor.minor.path format
/**
If your plugin needs initalization override this method but you have to call [super initWithPluginHost:]
@@ -59,41 +58,29 @@ NS_ASSUME_NONNULL_BEGIN
@end
/* Adopt this protocoll if you plugin supplied additinal autotype commands */
@protocol MPAutotypePlugin <NSObject>
@required
/**
Returns an array of string of commands supported by this pluing. Leave out enclosing curly brackets!
E.g. if you support {FOO} and {BAR} you will return @[ @"FOO", @"BAR" ]. The autotype system is case insenstivie.
*/
@property (nonatomic,copy) NSArray <NSString *> *commandStrings;
/**
Will be called by the plugin host to generate autotype commands for the corresponding string.
Command strings are considered case insensitive but mostly will be used in upper case.
You should therefore compare case insensitive.
@param commandString The command string without any enclosing curly brackets. The string is normalized to upper cased.
@param entry The entry for which the command will be used
@return a command for the supplied string, return nil if parsing fails or an unsupported command is supplied
*/
- (MPAutotypeCommand * _Nullable)commandForString:(NSString *)commandString entry:(KPKEntry *)entry;
@end
/*
Adopt this protocoll if your plugin supports actions on entries.
Actions will get listed in various places in menues. You should shoudl supply a valid menu item
that is wired up with the correct target and action. Since there's responder chain resolving involved
as well as a
Actions will get listed in various places in menues.
You should not set target nor actions since they will get stripped.
MacPass will call you back via -[MPPlugin performActionFroMenuItem:withEntries:]
*/
@protocol MPEntryActionPlugin <NSObject>
@optional
- (NSMenuItem * _Nullable)menuItemForEntry;
- (void)performActionForMenuItem:(NSMenuItem *)item withEntries:(NSArray <KPKEntry *>*)entries;
@end
@protocol MPCustomAttributePlugin <NSObject>
@optional
/* Supply a list of attribute keys that will get suggested for autocompletion as well as added to the extend add for custom fields */
@property (nonatomic,copy) NSArray<NSString *>* attributeKeys;
/*
For any attribute created with the special key the plugin will get called to offer a custom generation for the attributes value.
You can e.g. show UI to help the user create a special format.
If nil is returned, an empty value will be used.
*/
- (NSString *)valueForAttributeWithKey:(NSString *)key;
@end
@interface MPPlugin (Deprecated)

View File

@@ -24,7 +24,7 @@
#import "MPToolbarButton.h"
#import "MPToolbarItem.h"
#import "MPContextToolbarButton.h"
#import "MPContextButton.h"
#import "MPAddEntryContextMenuDelegate.h"
#import "MPActionHelper.h"
@@ -103,7 +103,7 @@ NSString *const MPToolbarItemHistory = @"TOOLBAR_HISTORY";
if(!item) {
item = [[MPToolbarItem alloc] initWithItemIdentifier:itemIdentifier];
NSString *itemLabel = [self _localizedLabelForToolbarItemIdentifier:itemIdentifier];
[item setLabel:itemLabel];
item.label = itemLabel;
if([itemIdentifier isEqualToString:MPToolbarItemAction]) {
NSPopUpButton *popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(0, 0, 50, 32) pullsDown:YES];
@@ -135,8 +135,8 @@ NSString *const MPToolbarItemHistory = @"TOOLBAR_HISTORY";
item.view = popupButton;
}
else if( [itemIdentifier isEqualToString:MPToolbarItemAddEntry]) {
MPContextToolbarButton *button = [[MPContextToolbarButton alloc] initWithFrame:NSMakeRect(0, 0, 32, 32)];
[button setAction:[self _actionForToolbarItemIdentifier:itemIdentifier]];
MPContextButton *button = [[MPContextButton alloc] initWithFrame:NSMakeRect(0, 0, 32, 32)];
button.action = [self _actionForToolbarItemIdentifier:itemIdentifier];
NSImage *image = self.toolbarImages[itemIdentifier];
image.size = NSMakeSize(16, 16);
[button setImage:image];
@@ -145,7 +145,7 @@ NSString *const MPToolbarItemHistory = @"TOOLBAR_HISTORY";
NSMenu *menu = [NSMenu allocWithZone:[NSMenu menuZone]];
[menu addItemWithTitle:NSLocalizedString(@"UNKNOWN_TOOLBAR_ITEM", @"") action:NULL keyEquivalent:@""];
menu.delegate = _entryMenuDelegate;
[button setContextMenu:menu];
button.contextMenu = menu;
NSRect fittingRect = button.frame;

View File

@@ -95,7 +95,7 @@
panel.title = NSLocalizedString(@"PICKFIELD_WINDOW_TITLE", @"Window displayed to the user to pick an amout of characters");
[panel center];
if(NSModalResponseOK == [NSApp runModalForWindow:panel]) {
/* add appropriate key press comamnds? or let the pick-char view-controller handel this? */
/* add appropriate key press commands? or let the pick-char view-controller handel this? */
return pickFieldViewController.pickedValue;
}
return @"";

View File

@@ -18,4 +18,8 @@
return self;
}
- (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification {
NSLog(@"%@", notification);
}
@end

View File

@@ -2,6 +2,8 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSUserNotificationAlertStyle</key>
<string>alert</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDocumentTypes</key>

View File

@@ -0,0 +1,15 @@
//
// NSUserNotification+MPAdditions.h
// MacPass
//
// Created by Michael Starke on 05.12.17.
// Copyright © 2017 HicknHack Software GmbH. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface NSUserNotification (MPAdditions)
@property (nonatomic) BOOL showsButtons;
@end

View File

@@ -0,0 +1,21 @@
//
// NSUserNotification+MPAdditions.m
// MacPass
//
// Created by Michael Starke on 05.12.17.
// Copyright © 2017 HicknHack Software GmbH. All rights reserved.
//
#import "NSUserNotification+MPAdditions.h"
@implementation NSUserNotification (MPAdditions)
- (BOOL)showsButtons {
return [[self valueForKey:@"_showsButtons"] boolValue];
}
- (void)setShowsButtons:(BOOL)showsButtons {
[self setValue:@(showsButtons) forKey:@"_showsButtons"];
}
@end

View File

@@ -372,6 +372,9 @@
/* Open button in the open panel to import an XML file */
"OPEN_BUTTON_IMPORT_XML_OPEN_PANEL" = "Import";
/* Notification Button */
"OPEN_DOCUMENT" = "Open Document";
/* Menu item to open the URL with the default application */
"OPEN_URL" = "Open URL";