Various usability improvements (#665)

* Set password creator window title

* Fix TODO, help url is read from Info.plist instead of a string literal

* Remove width constraint for 'Set Defaults' button of password generator so text is not cropped

* Improve keyboard shortcuts
New entries can be created using cmd + n, while cmd + shift + n creates new groups. Creating new databases is probably done too rarely to warrant a keyboard shortcut.
Additionally the 'New' menu item now has a submenu containing actions to create new entries, groups and databases (fixing #405).

* Hook up keyboard shortcut cmd + backspace to delete action

* Use shorter date format in inspector and add special output for distant future

* Show date picker when expiration is activates for either groups or entries but no date set

* Prompt for key file pops up automatically when the field is selected using tab

* Focus title field when new groups are created (#606).

* Rename search method so text fields don't capture it (#531)

* Don't show empty tags

* Remove menu item used for debugging.
This commit is contained in:
Christoph Leimbrock
2017-10-19 13:10:43 +02:00
committed by Michael Starke
parent 864e323ec7
commit fc70464e19
24 changed files with 182 additions and 47 deletions

View File

@@ -260,6 +260,7 @@
6021FE8218E160BC00C3BC51 /* PasswordEditWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6021FE8418E160BC00C3BC51 /* PasswordEditWindow.xib */; }; 6021FE8218E160BC00C3BC51 /* PasswordEditWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6021FE8418E160BC00C3BC51 /* PasswordEditWindow.xib */; };
6021FE8D18E1617300C3BC51 /* PasswordCreatorView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6021FE8F18E1617300C3BC51 /* PasswordCreatorView.xib */; }; 6021FE8D18E1617300C3BC51 /* PasswordCreatorView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6021FE8F18E1617300C3BC51 /* PasswordCreatorView.xib */; };
6021FE9818E1650F00C3BC51 /* DatabaseSettingsWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6021FE9A18E1650F00C3BC51 /* DatabaseSettingsWindow.xib */; }; 6021FE9818E1650F00C3BC51 /* DatabaseSettingsWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6021FE9A18E1650F00C3BC51 /* DatabaseSettingsWindow.xib */; };
8345D7291F39023E002B7B0F /* MPPathControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 8345D7281F39023E002B7B0F /* MPPathControl.m */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */ /* Begin PBXCopyFilesBuildPhase section */
@@ -796,6 +797,8 @@
60ECAD271F12262400EA9DB3 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/IntegrationSettings.strings"; sourceTree = "<group>"; }; 60ECAD271F12262400EA9DB3 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/IntegrationSettings.strings"; sourceTree = "<group>"; };
6E719715172058BA00E4C5FC /* MPDatabaseVersion.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MPDatabaseVersion.h; sourceTree = "<group>"; }; 6E719715172058BA00E4C5FC /* MPDatabaseVersion.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MPDatabaseVersion.h; sourceTree = "<group>"; };
713F9B481C95CEA000605880 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/PluginSettings.strings; sourceTree = "<group>"; }; 713F9B481C95CEA000605880 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/PluginSettings.strings; sourceTree = "<group>"; };
8345D7271F39023E002B7B0F /* MPPathControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPathControl.h; sourceTree = "<group>"; };
8345D7281F39023E002B7B0F /* MPPathControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPPathControl.m; sourceTree = "<group>"; };
BD6C365619484CF40089EB37 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/DatabaseSettingsWindow.strings; sourceTree = "<group>"; }; BD6C365619484CF40089EB37 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/DatabaseSettingsWindow.strings; sourceTree = "<group>"; };
BD6C365719484CF40089EB37 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/PasswordEditWindow.strings; sourceTree = "<group>"; }; BD6C365719484CF40089EB37 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/PasswordEditWindow.strings; sourceTree = "<group>"; };
BD6C365819484CF40089EB37 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/GeneralSettings.strings; sourceTree = "<group>"; }; BD6C365819484CF40089EB37 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/GeneralSettings.strings; sourceTree = "<group>"; };
@@ -1413,6 +1416,8 @@
4C63B8FA17A3154D0091BD72 /* MPContextToolbarButton.m */, 4C63B8FA17A3154D0091BD72 /* MPContextToolbarButton.m */,
4C57AE1217BA422B00CA4F34 /* MPSegmentedContextCell.h */, 4C57AE1217BA422B00CA4F34 /* MPSegmentedContextCell.h */,
4C57AE1317BA422B00CA4F34 /* MPSegmentedContextCell.m */, 4C57AE1317BA422B00CA4F34 /* MPSegmentedContextCell.m */,
8345D7271F39023E002B7B0F /* MPPathControl.h */,
8345D7281F39023E002B7B0F /* MPPathControl.m */,
); );
name = Controls; name = Controls;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -1844,6 +1849,7 @@
4C1BDF2B1E4392640012A3F0 /* MPPluginDataViewController.m in Sources */, 4C1BDF2B1E4392640012A3F0 /* MPPluginDataViewController.m in Sources */,
4C4B7EF817A4B335000234C7 /* MPUniqueCharactersFormatter.m in Sources */, 4C4B7EF817A4B335000234C7 /* MPUniqueCharactersFormatter.m in Sources */,
4C8B36AB17A6ED4B005E1FF1 /* MPOutlineContextMenuDelegate.m in Sources */, 4C8B36AB17A6ED4B005E1FF1 /* MPOutlineContextMenuDelegate.m in Sources */,
8345D7291F39023E002B7B0F /* MPPathControl.m in Sources */,
4CD7223B17A7CB0700F5A1E1 /* MPWorkflowSettingsController.m in Sources */, 4CD7223B17A7CB0700F5A1E1 /* MPWorkflowSettingsController.m in Sources */,
4CA08DA017A831B200A6544B /* MPAddEntryContextMenuDelegate.m in Sources */, 4CA08DA017A831B200A6544B /* MPAddEntryContextMenuDelegate.m in Sources */,
4CE3E62617AB0D2D00D9E4B4 /* MPAttachmentTableDataSource.m in Sources */, 4CE3E62617AB0D2D00D9E4B4 /* MPAttachmentTableDataSource.m in Sources */,

View File

@@ -393,6 +393,7 @@
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
</buttonCell> </buttonCell>
<connections> <connections>
<action selector="toggleExpire:" target="-2" id="EBe-2q-ASh"/>
<outlet property="nextKeyView" destination="8" id="SbJ-ZA-mXZ"/> <outlet property="nextKeyView" destination="8" id="SbJ-ZA-mXZ"/>
</connections> </connections>
</button> </button>
@@ -582,7 +583,7 @@
<rect key="frame" x="20" y="138" width="261" height="160"/> <rect key="frame" x="20" y="138" width="261" height="160"/>
<clipView key="contentView" id="aDE-WT-YIv"> <clipView key="contentView" id="aDE-WT-YIv">
<rect key="frame" x="1" y="1" width="259" height="158"/> <rect key="frame" x="1" y="1" width="259" height="158"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" alternatingRowBackgroundColors="YES" columnReordering="NO" columnSelection="YES" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowSizeStyle="automatic" viewBased="YES" id="caM-L6-UHC"> <tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" alternatingRowBackgroundColors="YES" columnReordering="NO" columnSelection="YES" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowSizeStyle="automatic" viewBased="YES" id="caM-L6-UHC">
<rect key="frame" x="0.0" y="0.0" width="259" height="158"/> <rect key="frame" x="0.0" y="0.0" width="259" height="158"/>
@@ -784,7 +785,7 @@
<rect key="frame" x="0.0" y="0.0" width="261" height="270"/> <rect key="frame" x="0.0" y="0.0" width="261" height="270"/>
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="k8G-zp-BXZ"> <clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="k8G-zp-BXZ">
<rect key="frame" x="1" y="1" width="259" height="268"/> <rect key="frame" x="1" y="1" width="259" height="268"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<tableView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" selectionHighlightStyle="none" columnSelection="YES" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="54" rowSizeStyle="automatic" viewBased="YES" id="193"> <tableView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" selectionHighlightStyle="none" columnSelection="YES" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="54" rowSizeStyle="automatic" viewBased="YES" id="193">
<rect key="frame" x="0.0" y="0.0" width="259" height="268"/> <rect key="frame" x="0.0" y="0.0" width="259" height="268"/>

View File

@@ -1,8 +1,7 @@
<?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"> <document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<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>
@@ -11,6 +10,7 @@
<outlet property="autotypePopupButton" destination="240" id="285"/> <outlet property="autotypePopupButton" destination="240" id="285"/>
<outlet property="autotypeSequenceTextField" destination="Fnw-qz-IZU" id="a7M-zz-0ye"/> <outlet property="autotypeSequenceTextField" destination="Fnw-qz-IZU" id="a7M-zz-0ye"/>
<outlet property="contentView" destination="38" id="Dv7-1B-VeH"/> <outlet property="contentView" destination="38" id="Dv7-1B-VeH"/>
<outlet property="expireDateSelectButton" destination="4" id="W6H-j5-GLf"/>
<outlet property="expiresCheckButton" destination="5" id="283"/> <outlet property="expiresCheckButton" destination="5" id="283"/>
<outlet property="searchPopupButton" destination="229" id="284"/> <outlet property="searchPopupButton" destination="229" id="284"/>
<outlet property="titleTextField" destination="23" id="35"/> <outlet property="titleTextField" destination="23" id="35"/>
@@ -28,7 +28,7 @@
<view translatesAutoresizingMaskIntoConstraints="NO" id="38" customClass="HNHUIScrollDocumentViewAdapter"> <view translatesAutoresizingMaskIntoConstraints="NO" id="38" customClass="HNHUIScrollDocumentViewAdapter">
<rect key="frame" x="0.0" y="0.0" width="257" height="291"/> <rect key="frame" x="0.0" y="0.0" width="257" height="291"/>
<subviews> <subviews>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="24"> <textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="24">
<rect key="frame" x="18" y="272" width="35" height="14"/> <rect key="frame" x="18" y="272" width="35" height="14"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Name" id="25"> <textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Name" id="25">
<font key="font" metaFont="smallSystem"/> <font key="font" metaFont="smallSystem"/>
@@ -36,7 +36,7 @@
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell> </textFieldCell>
</textField> </textField>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="249" translatesAutoresizingMaskIntoConstraints="NO" id="23" customClass="HNHUIRoundedTextField"> <textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="249" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="23" customClass="HNHUIRoundedTextField">
<rect key="frame" x="20" y="242" width="217" height="22"/> <rect key="frame" x="20" y="242" width="217" height="22"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" truncatesLastVisibleLine="YES" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" usesSingleLineMode="YES" id="26"> <textFieldCell key="cell" lineBreakMode="truncatingTail" truncatesLastVisibleLine="YES" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" usesSingleLineMode="YES" id="26">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
@@ -57,6 +57,7 @@
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
</buttonCell> </buttonCell>
<connections> <connections>
<action selector="toggleExpire:" target="-2" id="t1w-WN-Eud"/>
<outlet property="nextKeyView" destination="4" id="Rem-Pk-yFJ"/> <outlet property="nextKeyView" destination="4" id="Rem-Pk-yFJ"/>
</connections> </connections>
</button> </button>
@@ -96,7 +97,7 @@
<outlet property="nextKeyView" destination="Fnw-qz-IZU" id="Q0q-HY-T34"/> <outlet property="nextKeyView" destination="Fnw-qz-IZU" id="Q0q-HY-T34"/>
</connections> </connections>
</popUpButton> </popUpButton>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="264"> <textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="264">
<rect key="frame" x="18" y="190" width="41" height="14"/> <rect key="frame" x="18" y="190" width="41" height="14"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Search" id="265"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Search" id="265">
<font key="font" metaFont="smallSystem"/> <font key="font" metaFont="smallSystem"/>
@@ -104,7 +105,7 @@
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell> </textFieldCell>
</textField> </textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="276"> <textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="276">
<rect key="frame" x="18" y="135" width="52" height="14"/> <rect key="frame" x="18" y="135" width="52" height="14"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Autotype" id="277"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Autotype" id="277">
<font key="font" metaFont="smallSystem"/> <font key="font" metaFont="smallSystem"/>
@@ -112,7 +113,7 @@
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell> </textFieldCell>
</textField> </textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Fnw-qz-IZU" customClass="HNHUIRoundedTextField"> <textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Fnw-qz-IZU" customClass="HNHUIRoundedTextField">
<rect key="frame" x="20" y="50" width="217" height="22"/> <rect key="frame" x="20" y="50" width="217" height="22"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="VeF-V7-i2I"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="VeF-V7-i2I">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
@@ -123,7 +124,7 @@
<outlet property="nextKeyView" destination="1Uh-eo-H0j" id="zer-UH-73e"/> <outlet property="nextKeyView" destination="1Uh-eo-H0j" id="zer-UH-73e"/>
</connections> </connections>
</textField> </textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="6Lw-XW-x20"> <textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6Lw-XW-x20">
<rect key="frame" x="18" y="80" width="107" height="14"/> <rect key="frame" x="18" y="80" width="107" height="14"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Autotype Sequence" id="6FG-UZ-Adh"> <textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Autotype Sequence" id="6FG-UZ-Adh">
<font key="font" metaFont="smallSystem"/> <font key="font" metaFont="smallSystem"/>

View File

@@ -76,10 +76,27 @@
<menuItem title="File" id="83"> <menuItem title="File" id="83">
<menu key="submenu" title="File" id="81"> <menu key="submenu" title="File" id="81">
<items> <items>
<menuItem title="New" keyEquivalent="n" id="82"> <menuItem title="New" id="82">
<connections> <menu key="submenu" id="Mjd-iK-MxC">
<action selector="newDocument:" target="-1" id="373"/> <items>
</connections> <menuItem title="Entry" keyEquivalent="n" id="5pt-iM-iQB">
<connections>
<action selector="createEntry:" target="-1" id="NRG-FC-HaO"/>
</connections>
</menuItem>
<menuItem title="Group" keyEquivalent="N" id="dMl-Ia-k8o">
<connections>
<action selector="createGroup:" target="-1" id="RtX-HO-Zdw"/>
</connections>
</menuItem>
<menuItem title="Database" id="Ame-Ou-khG">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="newDocument:" target="-1" id="VEe-mh-brx"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem> </menuItem>
<menuItem title="Open…" keyEquivalent="o" id="72"> <menuItem title="Open…" keyEquivalent="o" id="72">
<connections> <connections>
@@ -226,6 +243,9 @@
</connections> </connections>
</menuItem> </menuItem>
<menuItem title="Delete" id="202"> <menuItem title="Delete" id="202">
<string key="keyEquivalent" base64-UTF8="YES">
CA
</string>
<connections> <connections>
<action selector="delete:" target="-1" id="235"/> <action selector="delete:" target="-1" id="235"/>
</connections> </connections>
@@ -240,7 +260,7 @@
</menuItem> </menuItem>
<menuItem title="Find…" tag="1" keyEquivalent="f" id="209"> <menuItem title="Find…" tag="1" keyEquivalent="f" id="209">
<connections> <connections>
<action selector="performFindPanelAction:" target="-1" id="241"/> <action selector="perfromCustomSearch:" target="-1" id="RSR-PQ-TH1"/>
</connections> </connections>
</menuItem> </menuItem>
</items> </items>

View File

@@ -3,8 +3,6 @@
<dependencies> <dependencies>
<deployment identifier="macosx"/> <deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13196"/> <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13196"/>
<capability name="box content view" minToolsVersion="7.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<objects> <objects>
<customObject id="-2" userLabel="File's Owner" customClass="MPPasswordCreatorViewController"> <customObject id="-2" userLabel="File's Owner" customClass="MPPasswordCreatorViewController">
@@ -32,7 +30,7 @@
<rect key="frame" x="0.0" y="0.0" width="351" height="291"/> <rect key="frame" x="0.0" y="0.0" width="351" height="291"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews> <subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="148"> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="NO" translatesAutoresizingMaskIntoConstraints="NO" id="148">
<rect key="frame" x="18" y="251" width="66" height="17"/> <rect key="frame" x="18" y="251" width="66" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Password:" id="149"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Password:" id="149">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
@@ -40,7 +38,7 @@
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell> </textFieldCell>
</textField> </textField>
<textField horizontalHuggingPriority="249" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="152"> <textField horizontalHuggingPriority="249" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" allowsCharacterPickerTouchBarItem="NO" translatesAutoresizingMaskIntoConstraints="NO" id="152">
<rect key="frame" x="90" y="247" width="201" height="24"/> <rect key="frame" x="90" y="247" width="201" height="24"/>
<constraints> <constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="200" id="621"/> <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="200" id="621"/>
@@ -55,7 +53,7 @@
<rect key="frame" x="88" y="221" width="205" height="19"/> <rect key="frame" x="88" y="221" width="205" height="19"/>
<sliderCell key="cell" state="on" alignment="left" maxValue="100" doubleValue="50" tickMarkPosition="above" sliderType="linear" id="174"/> <sliderCell key="cell" state="on" alignment="left" maxValue="100" doubleValue="50" tickMarkPosition="above" sliderType="linear" id="174"/>
</slider> </slider>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="178"> <textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="NO" translatesAutoresizingMaskIntoConstraints="NO" id="178">
<rect key="frame" x="18" y="223" width="66" height="17"/> <rect key="frame" x="18" y="223" width="66" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Length:" id="179"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Length:" id="179">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
@@ -63,7 +61,7 @@
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell> </textFieldCell>
</textField> </textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="182"> <textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="NO" translatesAutoresizingMaskIntoConstraints="NO" id="182">
<rect key="frame" x="299" y="219" width="32" height="22"/> <rect key="frame" x="299" y="219" width="32" height="22"/>
<constraints> <constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="32" id="eVc-Kg-bCi"/> <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="32" id="eVc-Kg-bCi"/>
@@ -81,7 +79,7 @@
<rect key="frame" x="1" y="1" width="315" height="78"/> <rect key="frame" x="1" y="1" width="315" height="78"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="411"> <textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="NO" translatesAutoresizingMaskIntoConstraints="NO" id="411">
<rect key="frame" x="18" y="19" width="279" height="22"/> <rect key="frame" x="18" y="19" width="279" height="22"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" usesSingleLineMode="YES" id="412" customClass="HNHUIRoundedTextFieldCell"> <textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" usesSingleLineMode="YES" id="412" customClass="HNHUIRoundedTextFieldCell">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
@@ -200,7 +198,7 @@
<rect key="frame" x="90" y="190" width="173" height="16"/> <rect key="frame" x="90" y="190" width="173" height="16"/>
<levelIndicatorCell key="cell" alignment="left" doubleValue="10" maxValue="90" warningValue="55" criticalValue="30" levelIndicatorStyle="continuousCapacity" id="636" customClass="HNHUILevelIndicatorCell"/> <levelIndicatorCell key="cell" alignment="left" doubleValue="10" maxValue="90" warningValue="55" criticalValue="30" levelIndicatorStyle="continuousCapacity" id="636" customClass="HNHUILevelIndicatorCell"/>
</levelIndicator> </levelIndicator>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="646"> <textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="NO" translatesAutoresizingMaskIntoConstraints="NO" id="646">
<rect key="frame" x="18" y="190" width="66" height="17"/> <rect key="frame" x="18" y="190" width="66" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Entropy:" id="647"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Entropy:" id="647">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
@@ -208,7 +206,7 @@
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell> </textFieldCell>
</textField> </textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="652"> <textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="NO" translatesAutoresizingMaskIntoConstraints="NO" id="652">
<rect key="frame" x="269" y="190" width="64" height="17"/> <rect key="frame" x="269" y="190" width="64" height="17"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="25000 bit" id="653"> <textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="25000 bit" id="653">
<numberFormatter key="formatter" formatterBehavior="custom10_4" positiveFormat="# bit" negativeFormat="# bit" usesGroupingSeparator="NO" paddingCharacter="*" groupingSize="0" minimumIntegerDigits="0" maximumIntegerDigits="309" decimalSeparator="," groupingSeparator="." currencyDecimalSeparator="," plusSign="+" minusSign="-" notANumberSymbol="NaN" perMillSymbol="‰" percentSymbol="%" exponentSymbol="E" positivePrefix="" positiveSuffix=" bit" negativePrefix="-" negativeSuffix=" bit" id="681"/> <numberFormatter key="formatter" formatterBehavior="custom10_4" positiveFormat="# bit" negativeFormat="# bit" usesGroupingSeparator="NO" paddingCharacter="*" groupingSize="0" minimumIntegerDigits="0" maximumIntegerDigits="309" decimalSeparator="," groupingSeparator="." currencyDecimalSeparator="," plusSign="+" minusSign="-" notANumberSymbol="NaN" perMillSymbol="‰" percentSymbol="%" exponentSymbol="E" positivePrefix="" positiveSuffix=" bit" negativePrefix="-" negativeSuffix=" bit" id="681"/>
@@ -218,10 +216,7 @@
</textFieldCell> </textFieldCell>
</textField> </textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="yil-UB-jtO"> <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="yil-UB-jtO">
<rect key="frame" x="20" y="18" width="83" height="25"/> <rect key="frame" x="20" y="18" width="82" height="25"/>
<constraints>
<constraint firstAttribute="width" constant="83" id="b3N-Jq-46u"/>
</constraints>
<buttonCell key="cell" type="roundTextured" title="Set Default" bezelStyle="texturedRounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Wvs-Md-Ob8"> <buttonCell key="cell" type="roundTextured" title="Set Default" bezelStyle="texturedRounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Wvs-Md-Ob8">
<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"/>

View File

@@ -44,11 +44,14 @@ DQ
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell> </textFieldCell>
</textField> </textField>
<pathControl verticalHuggingPriority="750" allowsExpansionToolTips="YES" translatesAutoresizingMaskIntoConstraints="NO" id="241"> <pathControl verticalHuggingPriority="750" allowsExpansionToolTips="YES" translatesAutoresizingMaskIntoConstraints="NO" id="241" customClass="MPPathControl">
<rect key="frame" x="164" y="108" width="197" height="26"/> <rect key="frame" x="164" y="108" width="197" height="26"/>
<pathCell key="cell" selectable="YES" editable="YES" alignment="left" pathStyle="popUp" id="242"> <pathCell key="cell" selectable="YES" editable="YES" alignment="left" pathStyle="popUp" id="242">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
</pathCell> </pathCell>
<connections>
<outlet property="delegate" destination="MfG-kk-cQe" id="9pp-rr-g4V"/>
</connections>
</pathControl> </pathControl>
<imageView translatesAutoresizingMaskIntoConstraints="NO" id="262"> <imageView translatesAutoresizingMaskIntoConstraints="NO" id="262">
<rect key="frame" x="238" y="197" width="48" height="48"/> <rect key="frame" x="238" y="197" width="48" height="48"/>
@@ -148,6 +151,7 @@ Gw
</constraints> </constraints>
<point key="canvasLocation" x="-240" y="25"/> <point key="canvasLocation" x="-240" y="25"/>
</customView> </customView>
<customObject id="MfG-kk-cQe" customClass="MPKeyfilePathControlDelegate"/>
</objects> </objects>
<resources> <resources>
<image name="02_MessageBoxWarningTemplate" width="16" height="16"/> <image name="02_MessageBoxWarningTemplate" width="16" height="16"/>

View File

@@ -43,7 +43,7 @@
#import <Sparkle/Sparkle.h> #import <Sparkle/Sparkle.h>
NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDidChangeStoredKeyFilesSettings"; NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDidChangeStoredKeyFilesSettings";
NSString *const MPHelpURLKey = @"MPHelpURL";
@interface MPAppDelegate () { @interface MPAppDelegate () {
@private @private
MPDockTileHelper *dockTileHelper; MPDockTileHelper *dockTileHelper;
@@ -229,8 +229,8 @@ NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDi
} }
- (void)showHelp:(id)sender { - (void)showHelp:(id)sender {
/* TODO: use Info.plist for URL */ NSString *urlString = [[NSBundle mainBundle] infoDictionary][MPHelpURLKey];
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://github.com/mstarke/MacPass"]]; [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:urlString]];
} }
- (void)checkForUpdates:(id)sender { - (void)checkForUpdates:(id)sender {

View File

@@ -48,10 +48,10 @@ static void MPContextmenuHelperBeginSection(NSMutableArray *items) {
NSMenuItem *newGroup = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"ADD_GROUP", @"") NSMenuItem *newGroup = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"ADD_GROUP", @"")
action:[MPActionHelper actionOfType:MPActionAddGroup] action:[MPActionHelper actionOfType:MPActionAddGroup]
keyEquivalent:@"G"]; keyEquivalent:@"N"];
NSMenuItem *newEntry = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"ADD_ENTRY", @"") NSMenuItem *newEntry = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"ADD_ENTRY", @"")
action:[MPActionHelper actionOfType:MPActionAddEntry] action:[MPActionHelper actionOfType:MPActionAddEntry]
keyEquivalent:@"E"]; keyEquivalent:@"n"];
[items addObjectsFromArray:@[ newGroup, newEntry ]]; [items addObjectsFromArray:@[ newGroup, newEntry ]];
} }

View File

@@ -49,8 +49,7 @@ NSString *const kMPDocumentSearchResultsKey = @"kMPDocumentSearchResul
} }
#pragma mark Actions #pragma mark Actions
- (IBAction)perfromCustomSearch:(id)sender {
- (void)performFindPanelAction:(id)sender {
[self enterSearchWithContext:[MPEntrySearchContext userContext]]; [self enterSearchWithContext:[MPEntrySearchContext userContext]];
} }

View File

@@ -254,7 +254,7 @@ FOUNDATION_EXTERN NSString *const MPDocumentDidChangeSearchResults;
FOUNDATION_EXTERN NSString *const kMPDocumentSearchResultsKey; FOUNDATION_EXTERN NSString *const kMPDocumentSearchResultsKey;
@interface MPDocument (Search) @interface MPDocument (Search)
- (IBAction)perfromCustomSearch:(id)sender;
- (void)enterSearchWithContext:(MPEntrySearchContext *)context; - (void)enterSearchWithContext:(MPEntrySearchContext *)context;
/* Should be called by the NSSearchTextField to update the search string */ /* Should be called by the NSSearchTextField to update the search string */

View File

@@ -89,5 +89,5 @@
- (IBAction)removeWindowAssociation:(id)sender; - (IBAction)removeWindowAssociation:(id)sender;
- (IBAction)toggleQuicklookPreview:(id)sender; - (IBAction)toggleQuicklookPreview:(id)sender;
- (IBAction)toggleExpire:(NSButton*)sender;
@end @end

View File

@@ -448,10 +448,11 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
toObject:self toObject:self
withKeyPath:[NSString stringWithFormat:@"%@.%@.%@", NSStringFromSelector(@selector(representedObject)), NSStringFromSelector(@selector(timeInfo)), NSStringFromSelector(@selector(expires))] withKeyPath:[NSString stringWithFormat:@"%@.%@.%@", NSStringFromSelector(@selector(representedObject)), NSStringFromSelector(@selector(timeInfo)), NSStringFromSelector(@selector(expires))]
options:nil]; options:nil];
[self.tagsTokenField bind:NSValueBinding [self.tagsTokenField bind:NSValueBinding
toObject:self toObject:self
withKeyPath:[NSString stringWithFormat:@"%@.%@", NSStringFromSelector(@selector(representedObject)), NSStringFromSelector(@selector(tags))] withKeyPath:[NSString stringWithFormat:@"%@.%@", NSStringFromSelector(@selector(representedObject)), NSStringFromSelector(@selector(tags))]
options:nil]; options:@{ NSValueTransformerNameBindingOption:MPTokenValueTransformerName }];
[self.uuidTextField bind:NSValueBinding [self.uuidTextField bind:NSValueBinding
@@ -510,6 +511,11 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
} }
- (IBAction)toggleExpire:(NSButton*)sender {
if([sender state] == NSOnState && [self.representedEntry.timeInfo.expirationDate isEqualToDate:[NSDate distantFuture]]) {
[NSApp sendAction:self.pickExpireDateButton.action to:nil from:self.pickExpireDateButton];
}
}
#pragma mark - #pragma mark -
#pragma mark MPDocument Notifications #pragma mark MPDocument Notifications

View File

@@ -36,4 +36,5 @@
@property (weak) IBOutlet NSPopUpButton *autotypePopupButton; @property (weak) IBOutlet NSPopUpButton *autotypePopupButton;
@property (weak) IBOutlet HNHUIRoundedTextField *autotypeSequenceTextField; @property (weak) IBOutlet HNHUIRoundedTextField *autotypeSequenceTextField;
- (void)registerNotificationsForDocument:(MPDocument *)document;
@end @end

View File

@@ -31,7 +31,7 @@
@interface MPGroupInspectorViewController () @interface MPGroupInspectorViewController ()
@property (strong) NSPopover *popover; @property (strong) NSPopover *popover;
@property BOOL focusTitleOnceViewAppears;
@end @end
@implementation MPGroupInspectorViewController @implementation MPGroupInspectorViewController
@@ -40,6 +40,21 @@
return @"GroupInspectorView"; return @"GroupInspectorView";
} }
- (void)registerNotificationsForDocument:(MPDocument *)document {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(_didAddGroup:)
name:MPDocumentDidAddGroupNotification
object:document];
}
- (void)viewDidAppear {
if(self.focusTitleOnceViewAppears) {
self.focusTitleOnceViewAppears = false;
[self.titleTextField becomeFirstResponder];
}
}
- (void)awakeFromNib { - (void)awakeFromNib {
HNHUIScrollView *scrollView = (HNHUIScrollView *)self.view; HNHUIScrollView *scrollView = (HNHUIScrollView *)self.view;
@@ -112,5 +127,20 @@
withKeyPath:[NSString stringWithFormat:@"%@.%@", NSStringFromSelector(@selector(representedObject)), NSStringFromSelector(@selector(isSearchEnabled))] withKeyPath:[NSString stringWithFormat:@"%@.%@", NSStringFromSelector(@selector(representedObject)), NSStringFromSelector(@selector(isSearchEnabled))]
options:nil]; options:nil];
} }
- (IBAction)toggleExpire:(NSButton*)sender {
KPKGroup *group = [self representedObject];
if([sender state] == NSOnState && [group.timeInfo.expirationDate isEqualToDate:[NSDate distantFuture]]) {
[NSApp sendAction:self.expireDateSelectButton.action to:nil from:self.expireDateSelectButton];
}
}
#pragma mark - MPDocument Notifications
- (void)_didAddGroup:(NSNotification *)notification {
if(!self.titleTextField.window) {
self.focusTitleOnceViewAppears = true;
} else {
[self.titleTextField becomeFirstResponder];
}
}
@end @end

View File

@@ -139,6 +139,7 @@ typedef NS_ENUM(NSUInteger, MPContentTab) {
self.observer = document; self.observer = document;
[self.entryViewController registerNotificationsForDocument:document]; [self.entryViewController registerNotificationsForDocument:document];
[self.groupViewController registerNotificationsForDocument:document];
} }
#pragma mark - #pragma mark -

View File

@@ -21,7 +21,8 @@
// //
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "MPPathControl.h"
@interface MPKeyfilePathControlDelegate : NSObject <NSPathControlDelegate> @interface MPKeyfilePathControlDelegate : NSObject <MPPathControlDelegate>
@end @end

View File

@@ -29,7 +29,18 @@
} }
- (void)pathControl:(NSPathControl *)pathControl willDisplayOpenPanel:(NSOpenPanel *)openPanel { - (void)pathControl:(NSPathControl *)pathControl willDisplayOpenPanel:(NSOpenPanel *)openPanel {
}
- (void)pathControlDidBecomeKey:(NSPathControl *)control {
if(control.URL) return;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSOpenPanel *panel = [NSOpenPanel openPanel];
panel.allowedFileTypes = control.allowedTypes;
if([panel runModal] != NSModalResponseOK) return;
control.URL = panel.URL;
});
} }
@end @end

View File

@@ -71,13 +71,15 @@
} }
- (void)viewDidLoad { - (void)viewDidLoad {
self.keyPathControl.delegate = self.pathControlDelegate; self.keyPathControl.delegate = self.pathControlDelegate = [[MPKeyfilePathControlDelegate alloc] init];
self.errorImageView.image = [NSImage imageNamed:NSImageNameCaution]; self.errorImageView.image = [NSImage imageNamed:NSImageNameCaution];
[self.passwordTextField bind:NSStringFromSelector(@selector(showPassword)) toObject:self withKeyPath:NSStringFromSelector(@selector(showPassword)) options:nil]; [self.passwordTextField bind:NSStringFromSelector(@selector(showPassword)) toObject:self withKeyPath:NSStringFromSelector(@selector(showPassword)) options:nil];
[self.togglePasswordButton bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(showPassword)) options:nil]; [self.togglePasswordButton bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(showPassword)) options:nil];
[self.enablePasswordCheckBox bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(enablePassword)) options:nil]; [self.enablePasswordCheckBox bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(enablePassword)) options:nil];
[self.togglePasswordButton bind:NSEnabledBinding toObject:self withKeyPath:NSStringFromSelector(@selector(enablePassword)) options:nil]; [self.togglePasswordButton bind:NSEnabledBinding toObject:self withKeyPath:NSStringFromSelector(@selector(enablePassword)) options:nil];
[self.passwordTextField bind:NSEnabledBinding toObject:self withKeyPath:NSStringFromSelector(@selector(enablePassword)) options:nil]; [self.passwordTextField bind:NSEnabledBinding toObject:self withKeyPath:NSStringFromSelector(@selector(enablePassword)) options:nil];
[self.passwordTextField setNextKeyView:self.keyPathControl];
[self _reset]; [self _reset];
} }

16
MacPass/MPPathControl.h Normal file
View File

@@ -0,0 +1,16 @@
//
// MPPathControl.h
// MacPass
//
// Created by Christoph Leimbrock on 8/7/17.
//
#import <Cocoa/Cocoa.h>
@protocol MPPathControlDelegate <NSPathControlDelegate>
- (void)pathControlDidBecomeKey:(NSPathControl *_Nullable)control;
@end
@interface MPPathControl : NSPathControl
@property (nullable, weak) id <MPPathControlDelegate> delegate;
@end

25
MacPass/MPPathControl.m Normal file
View File

@@ -0,0 +1,25 @@
//
// MPPathControl.m
// MacPass
//
// Created by Christoph Leimbrock on 8/7/17.
//
#import "MPPathControl.h"
@implementation MPPathControl
@dynamic delegate;
- (BOOL)canBecomeKeyView {
return TRUE;
}
- (BOOL)acceptsFirstResponder {
return TRUE;
}
- (BOOL)becomeFirstResponder {
[self.delegate performSelector:@selector(pathControlDidBecomeKey:) withObject:self];
return TRUE;
}
@end

View File

@@ -24,6 +24,7 @@
FOUNDATION_EXPORT NSString *const MPStripLineBreaksTransformerName; FOUNDATION_EXPORT NSString *const MPStripLineBreaksTransformerName;
FOUNDATION_EXPORT NSString *const MPExpiryDateValueTransformerName; FOUNDATION_EXPORT NSString *const MPExpiryDateValueTransformerName;
FOUNDATION_EXPORT NSString *const MPTokenValueTransformerName;
@interface MPValueTransformerHelper : NSObject @interface MPValueTransformerHelper : NSObject

View File

@@ -25,7 +25,7 @@
NSString *const MPStripLineBreaksTransformerName = @"com.hicknhack.macpass.MPStripLineBreaksTransformerName"; NSString *const MPStripLineBreaksTransformerName = @"com.hicknhack.macpass.MPStripLineBreaksTransformerName";
NSString *const MPExpiryDateValueTransformerName = @"com.hicknhack.macpass.MPExpiryDateValueTransformer"; NSString *const MPExpiryDateValueTransformerName = @"com.hicknhack.macpass.MPExpiryDateValueTransformer";
NSString *const MPTokenValueTransformerName = @"com.hicknhack.macpass.MPTokenValueTransformer";
@implementation MPValueTransformerHelper @implementation MPValueTransformerHelper
+ (void)registerValueTransformer { + (void)registerValueTransformer {
@@ -49,12 +49,25 @@ NSString *const MPExpiryDateValueTransformerName = @"com.hicknhack.macpass.MPExp
static NSDateFormatter *formatter; static NSDateFormatter *formatter;
if(!formatter) { if(!formatter) {
formatter = [[NSDateFormatter alloc] init]; formatter = [[NSDateFormatter alloc] init];
formatter.dateStyle = NSDateFormatterFullStyle; formatter.dateStyle = kCFDateFormatterLongStyle;
formatter.timeStyle = NSDateFormatterNoStyle; formatter.timeStyle = NSDateFormatterNoStyle;
} }
if([value isEqualToDate:[NSDate distantFuture]]) {
return NSLocalizedString(@"NO_EXPIRE_DATE_SET", "");
}
NSString *template = NSLocalizedString(@"EXPIRES_AT_DATE_%@", ""); NSString *template = NSLocalizedString(@"EXPIRES_AT_DATE_%@", "");
return [[NSString alloc] initWithFormat:template, [formatter stringFromDate:value]]; return [[NSString alloc] initWithFormat:template, [formatter stringFromDate:value]];
}]; }];
[NSValueTransformer registerValueTransformerWithName:MPTokenValueTransformerName
transformedValueClass:NSArray.class
returningTransformedValueWithBlock:^id(NSArray *value) {
return [value filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
return [evaluatedObject length];
}]];
}];
} }
@end @end

View File

@@ -75,6 +75,8 @@
<true/> <true/>
<key>SUFeedURL</key> <key>SUFeedURL</key>
<string>https://raw.githubusercontent.com/MacPass/MacPassUpdates/master/appcast_macpass.xml</string> <string>https://raw.githubusercontent.com/MacPass/MacPassUpdates/master/appcast_macpass.xml</string>
<key>MPHelpURL</key>
<string>https://github.com/mstarke/MacPass</string>
<key>UTExportedTypeDeclarations</key> <key>UTExportedTypeDeclarations</key>
<array> <array>
<dict> <dict>

View File

@@ -15,7 +15,7 @@
<window title="Password Generator" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="1"> <window title="Password Generator" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="1">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/> <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
<rect key="contentRect" x="196" y="240" width="338" height="216"/> <rect key="contentRect" x="196" y="240" width="338" height="216"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/> <rect key="screenRect" x="0.0" y="0.0" width="1280" height="777"/>
<view key="contentView" id="2"> <view key="contentView" id="2">
<rect key="frame" x="0.0" y="0.0" width="338" height="216"/> <rect key="frame" x="0.0" y="0.0" width="338" height="216"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>