mirror of
https://github.com/MacPass/MacPass.git
synced 2026-01-31 13:08:15 +00:00
Compare commits
236 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
99ea0d7a14 | ||
|
|
d7f6bcc6c3 | ||
|
|
3731e92339 | ||
|
|
f609ba9795 | ||
|
|
64ad7d9c08 | ||
|
|
8b3cc34ab5 | ||
|
|
b028ef51f9 | ||
|
|
ae9278c4b5 | ||
|
|
86d4defc78 | ||
|
|
c85a9cdce1 | ||
|
|
9409887942 | ||
|
|
40c62954e4 | ||
|
|
c6f93ef59a | ||
|
|
5eef186ab2 | ||
|
|
6c60d72ef9 | ||
|
|
217b311783 | ||
|
|
8cd5273082 | ||
|
|
3e8a320598 | ||
|
|
0197bdc5bc | ||
|
|
a425acea4d | ||
|
|
c4222a3159 | ||
|
|
bd0fe6baf8 | ||
|
|
b2999ca8a8 | ||
|
|
77d96976ec | ||
|
|
a4b9b0be8b | ||
|
|
8e52da7069 | ||
|
|
228170c717 | ||
|
|
2216a14729 | ||
|
|
77f3f23cfe | ||
|
|
07ae4675d4 | ||
|
|
f2279863db | ||
|
|
df68d0140f | ||
|
|
1b6efbfd0c | ||
|
|
626bb35f80 | ||
|
|
e6bb9ad191 | ||
|
|
4cfe54b65c | ||
|
|
2b2e5ddbea | ||
|
|
334451471e | ||
|
|
4069052c86 | ||
|
|
7be5190ada | ||
|
|
7a1510b77b | ||
|
|
f16c767cbd | ||
|
|
3f76188bf5 | ||
|
|
1215b7317b | ||
|
|
e5ba73589b | ||
|
|
9ba902471c | ||
|
|
b1568c5eef | ||
|
|
8535579de2 | ||
|
|
6ec89e146c | ||
|
|
09a7a15141 | ||
|
|
9b77790ddc | ||
|
|
16cdd4dd4f | ||
|
|
0a7fcc415c | ||
|
|
ff72632b3b | ||
|
|
b6a7240534 | ||
|
|
f10735f96f | ||
|
|
ba538d05af | ||
|
|
3639913e6d | ||
|
|
b87e20ca7e | ||
|
|
c7bdce46ff | ||
|
|
11bea5fa32 | ||
|
|
e8a6af086c | ||
|
|
f1033c1006 | ||
|
|
264866dff0 | ||
|
|
631741d30b | ||
|
|
6897f9e51c | ||
|
|
21a5b5d6bb | ||
|
|
3817bf503f | ||
|
|
2beb033572 | ||
|
|
d7b016e5ef | ||
|
|
46b6ab3925 | ||
|
|
c5ed3c42e6 | ||
|
|
00d69d5bad | ||
|
|
fa58c7e423 | ||
|
|
f134290c27 | ||
|
|
3b244c3145 | ||
|
|
541ef6e749 | ||
|
|
eb9d15ffa5 | ||
|
|
05cfb73734 | ||
|
|
d9322d7544 | ||
|
|
7de8d0abd5 | ||
|
|
3289ffb2e4 | ||
|
|
38d64c7cb9 | ||
|
|
01b1372dda | ||
|
|
c76a8baa88 | ||
|
|
d048ea47a6 | ||
|
|
2a8766eccb | ||
|
|
a2078f721a | ||
|
|
7e402601f8 | ||
|
|
88d7d8792a | ||
|
|
68bdcb461f | ||
|
|
ec8ce8ec29 | ||
|
|
95275d9c8a | ||
|
|
7671a6e3f5 | ||
|
|
c0c053d422 | ||
|
|
4cda972d14 | ||
|
|
09eb1dcf41 | ||
|
|
224ca6c65b | ||
|
|
10dd3e352d | ||
|
|
48aa21faa8 | ||
|
|
c295f5df6f | ||
|
|
2103eb8875 | ||
|
|
3b7bf0d77b | ||
|
|
9298feea2d | ||
|
|
7f79dde83a | ||
|
|
ed4e4b0f72 | ||
|
|
62670a605e | ||
|
|
9e5d9f3bf5 | ||
|
|
bc47fb592c | ||
|
|
4b04699b30 | ||
|
|
3910b117a8 | ||
|
|
81dce1928a | ||
|
|
05f820a4a3 | ||
|
|
b9fbe43653 | ||
|
|
145f27c334 | ||
|
|
bf93ab574d | ||
|
|
7fc1dd8a1b | ||
|
|
e31c7c6cd7 | ||
|
|
7d8bb85d9b | ||
|
|
245a58d81b | ||
|
|
6b94cbd81b | ||
|
|
cbc74ccca6 | ||
|
|
9b2f8e5f6f | ||
|
|
9c177afdb0 | ||
|
|
6b13ab37b8 | ||
|
|
d4efba00ae | ||
|
|
2d3e81a5c1 | ||
|
|
c523ba716f | ||
|
|
32c6bae7e4 | ||
|
|
2aba4cbd93 | ||
|
|
5fbd6d1cde | ||
|
|
091a565bc8 | ||
|
|
0d3bf5ba71 | ||
|
|
d3a575fce3 | ||
|
|
1baf2cd8e6 | ||
|
|
0455628d72 | ||
|
|
9d0dc1630d | ||
|
|
fc21257173 | ||
|
|
53b807788a | ||
|
|
024131de35 | ||
|
|
a47557672f | ||
|
|
9a55559e71 | ||
|
|
e82db2fe9d | ||
|
|
50dad4de30 | ||
|
|
f7eb7147f3 | ||
|
|
d37164ad89 | ||
|
|
add09827ba | ||
|
|
9a625dd57d | ||
|
|
3191e56e58 | ||
|
|
a5c97469eb | ||
|
|
02840548ba | ||
|
|
52720a79d4 | ||
|
|
71e795c4f4 | ||
|
|
2381acfde9 | ||
|
|
9d2819ce2c | ||
|
|
d5592774d1 | ||
|
|
55f1ce22a9 | ||
|
|
2d98c480da | ||
|
|
30a68fc9e3 | ||
|
|
32899cb707 | ||
|
|
b1cb776e14 | ||
|
|
176a3b7db4 | ||
|
|
38e61b96a5 | ||
|
|
54d7ce4f77 | ||
|
|
2e523f6018 | ||
|
|
077a5851cf | ||
|
|
3cab0ea4dd | ||
|
|
ddb0f92dce | ||
|
|
0c12236401 | ||
|
|
c7d85d6daa | ||
|
|
28817b6c80 | ||
|
|
972f775ab3 | ||
|
|
4a33a7ece2 | ||
|
|
e0d12bea5a | ||
|
|
8f5914afd2 | ||
|
|
eaa0f68c7b | ||
|
|
9f43d52917 | ||
|
|
9e474375bf | ||
|
|
714bba4ce5 | ||
|
|
8d66621803 | ||
|
|
3ef2c01859 | ||
|
|
4abdff79a5 | ||
|
|
f9b36177fd | ||
|
|
9134f4959b | ||
|
|
6e011c00fa | ||
|
|
64de5a0d21 | ||
|
|
5da86637e5 | ||
|
|
ba2fc255dc | ||
|
|
8cc701af5f | ||
|
|
305ce06ab4 | ||
|
|
349eb5791e | ||
|
|
2beb1bbceb | ||
|
|
c46dba59c3 | ||
|
|
25538dd3bf | ||
|
|
e8fa409cef | ||
|
|
6b6c4fb736 | ||
|
|
7c2cf6eadb | ||
|
|
853e47c43f | ||
|
|
a5da80f094 | ||
|
|
878cef88c5 | ||
|
|
43508ad3a5 | ||
|
|
d909c377fb | ||
|
|
ae4656c79a | ||
|
|
1c0a76dc74 | ||
|
|
b667cf75bf | ||
|
|
4222922b68 | ||
|
|
81d722dd3a | ||
|
|
d26304285f | ||
|
|
1f4966e4c0 | ||
|
|
c72566d4c1 | ||
|
|
3dedbc1f68 | ||
|
|
7df1c9dff8 | ||
|
|
76b76526e3 | ||
|
|
bb4390aa84 | ||
|
|
e5e0e689c3 | ||
|
|
9026efa662 | ||
|
|
9a721c0a1f | ||
|
|
be5b2577f0 | ||
|
|
1372dbd444 | ||
|
|
f59f8f5cb9 | ||
|
|
77143591c2 | ||
|
|
515fd4be70 | ||
|
|
4ddb0c5e07 | ||
|
|
1d42d996ca | ||
|
|
6d046bc933 | ||
|
|
7ba9ec2685 | ||
|
|
cbdfff8ea2 | ||
|
|
b3de0556f5 | ||
|
|
e3c8248761 | ||
|
|
2c22245bb8 | ||
|
|
272412965a | ||
|
|
f252a2a6a8 | ||
|
|
eabf1e52b2 | ||
|
|
b73de01897 | ||
|
|
70c25c9b1f | ||
|
|
02c5e1b2dc |
2
.github/FUNDING.yml
vendored
Normal file
2
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
github: mstarke
|
||||
custom: https://flattr.com/thing/1550529/mstarkeMacPass-on-GitHub
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -24,3 +24,4 @@ Docs/Acknowlegements/*.fls
|
||||
Docs/Acknowlegements/*.log
|
||||
Docs/Acknowlegements/*.synctex.gz
|
||||
docs/acknowledgement/*.lb
|
||||
MacPass/en.lproj/Localizable.strings.updated
|
||||
|
||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,6 +1,3 @@
|
||||
[submodule "DDHotKey"]
|
||||
path = DDHotKey
|
||||
url = https://github.com/mstarke/DDHotKey.git
|
||||
[submodule "TransformerKit"]
|
||||
path = TransformerKit
|
||||
url = https://github.com/mattt/TransformerKit.git
|
||||
|
||||
11
.travis.yml
11
.travis.yml
@@ -8,6 +8,16 @@ before_install:
|
||||
- gem install xcpretty --no-document --quiet
|
||||
|
||||
after_success:
|
||||
- xcodebuild -project MacPass.xcodeproj -exportLocalizations -localizationPath Localisations -exportLanguage de
|
||||
- xcodebuild -project MacPass.xcodeproj -exportLocalizations -localizationPath Localisations -exportLanguage en
|
||||
- xcodebuild -project MacPass.xcodeproj -exportLocalizations -localizationPath Localisations -exportLanguage es
|
||||
- xcodebuild -project MacPass.xcodeproj -exportLocalizations -localizationPath Localisations -exportLanguage fr
|
||||
- xcodebuild -project MacPass.xcodeproj -exportLocalizations -localizationPath Localisations -exportLanguage it
|
||||
- xcodebuild -project MacPass.xcodeproj -exportLocalizations -localizationPath Localisations -exportLanguage nl
|
||||
- xcodebuild -project MacPass.xcodeproj -exportLocalizations -localizationPath Localisations -exportLanguage ru
|
||||
- xcodebuild -project MacPass.xcodeproj -exportLocalizations -localizationPath Localisations -exportLanguage sv-SE
|
||||
- xcodebuild -project MacPass.xcodeproj -exportLocalizations -localizationPath Localisations -exportLanguage zh-Hans
|
||||
- zip -9ry Localisations.zip Localisations
|
||||
- cd ./build/Build/Products/Release
|
||||
- zip -9ry MacPass-continuous.zip MacPass.app
|
||||
- shasum -a 256 MacPass-continuous.zip > MacPass-continuous.zip.sha256
|
||||
@@ -30,6 +40,7 @@ deploy:
|
||||
api_key:
|
||||
secure: AEb7fgi29S3aXFt5bXz+lq1KHISumny6bf4j06JBC5gUrSs+dW0/tmVFq68XRAqigeOQU31wwv20f7OHiy+GRYDXM2xBsX9ZBQ2IilnaXlDy/mPsNcJJJsZ2gyodi3KnU0rZtTb93me2YyU86H4Na/gtaZZUKjLwCFtGGziExD8=
|
||||
file:
|
||||
- Localisations.zip
|
||||
- MacPass-continuous.zip
|
||||
- MacPass-continuous.zip.sha256
|
||||
overwrite: true
|
||||
|
||||
@@ -4,18 +4,21 @@ Thanks for taking the time to contribute to MacPass! This documents describes a
|
||||
|
||||
## Translations
|
||||
MacPass has translations for a few languages. If you can translate to another language, or you think a translation is wrong, follow the next steps to add or improve a translation:
|
||||
- You can use a XLIFF editor for translating the strings. For example [XLIFFTool](https://itunes.apple.com/us/app/xlifftool/id1074282695)
|
||||
- For a new localization only:
|
||||
- Select MacPass in the project navigator
|
||||
- Select the MacPass project in the project and targets list
|
||||
- Open the info tab and click the `+` button un the localizations section.
|
||||
- Choose the language you want to translate
|
||||
- Select all resources and click finish, now the new language is available for export in the next step
|
||||
- Export the XLIFF file
|
||||
- Select the MacPass project in XCode
|
||||
- Go to `Editor -> Export for Localization`
|
||||
- Select the language you want to translate
|
||||
- Now use your XLIFF editor and save the file if you are done with your translations
|
||||
|
||||
- Get a XLIFF editor for translating localization files. For example [XLIFFTool](https://itunes.apple.com/us/app/xlifftool/id1074282695)
|
||||
- Get the current XLIFF export for your language. You can either download the `Localizations.zip` on the [Continous release](https://github.com/MacPass/MacPass/releases) or you can export them in Xcode:
|
||||
- For a new localization only:
|
||||
- Select MacPass in the project navigator
|
||||
- Select the MacPass project in the project and targets list
|
||||
- Open the info tab and click the `+` button un the localizations section.
|
||||
- Choose the language you want to translate
|
||||
- Select all resources and click finish, now the new language is available for export in the next step
|
||||
- For present localizations directly Export the XLIFF file
|
||||
- Select the MacPass project in Xcode
|
||||
- Go to `Editor -> Export for Localization`
|
||||
- Select the language you want to translate
|
||||
- Now use your XLIFF editor and save the file after you are done with your translations
|
||||
- Go back to XCode and use `Editor -> Import Localization` to import the changes
|
||||
- Open a Pull Request with your changes.
|
||||
|
||||
Alternatively, you can open an issue to ask a dev to create the XLIFF file for you and send it back after you've finished localising.
|
||||
|
||||
3
Cartfile
3
Cartfile
@@ -1,3 +1,4 @@
|
||||
github "sparkle-project/Sparkle" ~> 1.18.1
|
||||
github "sparkle-project/Sparkle" ~> 1.22
|
||||
github "MacPass/TransformerKit" "b28de3a7de9249dd886979cae4985092523b6dd1"
|
||||
github "MacPass/KeePassKit" ~> 2.4
|
||||
github "mstarke/HNHUi" ~> 3.0
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
github "MacPass/KeePassKit" "2.4.1"
|
||||
github "MacPass/KeePassKit" "2.4.7"
|
||||
github "MacPass/TransformerKit" "b28de3a7de9249dd886979cae4985092523b6dd1"
|
||||
github "mstarke/HNHUi" "3.0"
|
||||
github "robbiehanson/KissXML" "5.2.3"
|
||||
github "sparkle-project/Sparkle" "1.20.0"
|
||||
github "robbiehanson/KissXML" "5.3.1"
|
||||
github "sparkle-project/Sparkle" "1.22.0"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1010"
|
||||
LastUpgradeVersion = "1130"
|
||||
version = "2.0">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@@ -26,20 +26,8 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
codeCoverageEnabled = "YES"
|
||||
shouldUseLaunchSchemeArgsEnv = "NO">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "4C45FB19178E09ED0010007D"
|
||||
BuildableName = "MacPassTests.xctest"
|
||||
BlueprintName = "MacPassTests"
|
||||
ReferencedContainer = "container:MacPass.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
shouldUseLaunchSchemeArgsEnv = "NO"
|
||||
codeCoverageEnabled = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
@@ -55,9 +43,24 @@
|
||||
value = "YES"
|
||||
isEnabled = "YES">
|
||||
</EnvironmentVariable>
|
||||
<EnvironmentVariable
|
||||
key = "MPIsRunningTests"
|
||||
value = "YES"
|
||||
isEnabled = "YES">
|
||||
</EnvironmentVariable>
|
||||
</EnvironmentVariables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "4C45FB19178E09ED0010007D"
|
||||
BuildableName = "MacPassTests.xctest"
|
||||
BlueprintName = "MacPassTests"
|
||||
ReferencedContainer = "container:MacPass.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
@@ -102,8 +105,6 @@
|
||||
isEnabled = "NO">
|
||||
</EnvironmentVariable>
|
||||
</EnvironmentVariables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15705" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14460.31"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15705"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="MPAutotypeCandidateSelectionViewController">
|
||||
<connections>
|
||||
<outlet property="contextTableView" destination="Ih2-lo-t2W" id="8uy-Mz-1vc"/>
|
||||
<outlet property="messageTextField" destination="kDw-2l-7gQ" id="7bW-as-yGU"/>
|
||||
<outlet property="selectAutotypeContextButton" destination="V5B-Qq-GN8" id="mqv-H3-N01"/>
|
||||
<outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
|
||||
</connections>
|
||||
@@ -19,13 +20,13 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="241"/>
|
||||
<subviews>
|
||||
<scrollView wantsLayer="YES" autohidesScrollers="YES" horizontalLineScroll="38" horizontalPageScroll="10" verticalLineScroll="38" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7cB-re-3ys">
|
||||
<rect key="frame" x="20" y="61" width="440" height="118"/>
|
||||
<rect key="frame" x="20" y="61" width="440" height="120"/>
|
||||
<clipView key="contentView" id="WSc-o2-GsZ">
|
||||
<rect key="frame" x="1" y="1" width="438" height="116"/>
|
||||
<rect key="frame" x="1" y="1" width="438" height="118"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" alternatingRowBackgroundColors="YES" columnReordering="NO" multipleSelection="NO" emptySelection="NO" autosaveColumns="NO" typeSelect="NO" rowHeight="36" viewBased="YES" id="Ih2-lo-t2W">
|
||||
<rect key="frame" x="0.0" y="0.0" width="438" height="116"/>
|
||||
<tableView verticalHuggingPriority="750" ambiguous="YES" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" alternatingRowBackgroundColors="YES" columnReordering="NO" multipleSelection="NO" emptySelection="NO" autosaveColumns="NO" typeSelect="NO" rowHeight="36" viewBased="YES" id="Ih2-lo-t2W">
|
||||
<rect key="frame" x="0.0" y="0.0" width="438" height="118"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<size key="intercellSpacing" width="3" height="2"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -44,12 +45,12 @@
|
||||
</textFieldCell>
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES"/>
|
||||
<prototypeCellViews>
|
||||
<tableCellView id="vkI-FK-7wg">
|
||||
<tableCellView misplaced="YES" id="vkI-FK-7wg" customClass="MPExtendedTableCellView">
|
||||
<rect key="frame" x="1" y="1" width="435" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Utl-Gl-ETE">
|
||||
<rect key="frame" x="2" y="1" width="14" height="14"/>
|
||||
<rect key="frame" x="2" y="20" width="14" height="14"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="lessThanOrEqual" constant="32" id="N48-cx-w8q"/>
|
||||
<constraint firstAttribute="height" relation="lessThanOrEqual" constant="32" id="mde-14-jf7"/>
|
||||
@@ -57,8 +58,16 @@
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="NSActionTemplate" id="gT4-lt-7Ir"/>
|
||||
</imageView>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" allowsExpansionToolTips="YES" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Dxk-A7-QSy">
|
||||
<rect key="frame" x="22" y="0.0" width="413" height="17"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" allowsUndo="NO" sendsActionOnEndEditing="YES" title="Content" id="TN3-3a-LaA">
|
||||
<rect key="frame" x="22" y="20" width="413" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" allowsUndo="NO" sendsActionOnEndEditing="YES" title="Title" id="TN3-3a-LaA">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" allowsExpansionToolTips="YES" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="rHv-KR-Ja6">
|
||||
<rect key="frame" x="22" y="2" width="413" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" allowsUndo="NO" sendsActionOnEndEditing="YES" title="Sequence" id="bvJ-2i-eMc">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -66,14 +75,18 @@
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="Dxk-A7-QSy" secondAttribute="bottom" id="0Ds-yc-1wj"/>
|
||||
<constraint firstItem="Dxk-A7-QSy" firstAttribute="top" secondItem="vkI-FK-7wg" secondAttribute="top" id="3KK-oo-Ogk"/>
|
||||
<constraint firstAttribute="bottom" secondItem="rHv-KR-Ja6" secondAttribute="bottom" constant="2" id="Fct-2X-0MX"/>
|
||||
<constraint firstItem="Dxk-A7-QSy" firstAttribute="leading" secondItem="Utl-Gl-ETE" secondAttribute="trailing" constant="8" symbolic="YES" id="L0l-PB-4Dt"/>
|
||||
<constraint firstItem="rHv-KR-Ja6" firstAttribute="leading" secondItem="Dxk-A7-QSy" secondAttribute="leading" id="cHl-VR-d3w"/>
|
||||
<constraint firstAttribute="trailing" secondItem="rHv-KR-Ja6" secondAttribute="trailing" constant="2" id="jqL-Dd-V0M"/>
|
||||
<constraint firstAttribute="trailing" secondItem="Dxk-A7-QSy" secondAttribute="trailing" constant="2" id="kOy-Jo-rYe"/>
|
||||
<constraint firstItem="Utl-Gl-ETE" firstAttribute="leading" secondItem="vkI-FK-7wg" secondAttribute="leading" constant="2" id="rRi-nE-1Z3"/>
|
||||
<constraint firstItem="Utl-Gl-ETE" firstAttribute="top" secondItem="vkI-FK-7wg" secondAttribute="top" constant="2" id="sJf-FS-87E"/>
|
||||
<constraint firstItem="rHv-KR-Ja6" firstAttribute="top" secondItem="Dxk-A7-QSy" secondAttribute="bottom" constant="2" id="uTd-5E-IzI"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<outlet property="addionalTextField" destination="rHv-KR-Ja6" id="VTf-Dz-qYp"/>
|
||||
<outlet property="imageView" destination="Utl-Gl-ETE" id="5dQ-R4-kfV"/>
|
||||
<outlet property="textField" destination="Dxk-A7-QSy" id="8uP-9M-aOd"/>
|
||||
</connections>
|
||||
@@ -82,6 +95,7 @@
|
||||
</tableColumn>
|
||||
</tableColumns>
|
||||
<connections>
|
||||
<action trigger="doubleAction" selector="selectAutotypeContext:" target="-2" id="NoK-fa-xIL"/>
|
||||
<outlet property="dataSource" destination="-2" id="4ld-qs-eNP"/>
|
||||
<outlet property="delegate" destination="-2" id="ibb-G8-tPQ"/>
|
||||
</connections>
|
||||
@@ -98,7 +112,7 @@
|
||||
</scroller>
|
||||
</scrollView>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" preferredMaxLayoutWidth="330" translatesAutoresizingMaskIntoConstraints="NO" id="kDw-2l-7gQ">
|
||||
<rect key="frame" x="18" y="187" width="444" height="34"/>
|
||||
<rect key="frame" x="18" y="189" width="444" height="32"/>
|
||||
<textFieldCell key="cell" sendsActionOnEndEditing="YES" title="There are multiple matches for the current window. Please select which match should be used." id="gcf-gb-ZsF">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -146,7 +160,7 @@ DQ
|
||||
<constraint firstItem="7cB-re-3ys" firstAttribute="top" secondItem="kDw-2l-7gQ" secondAttribute="bottom" constant="8" symbolic="YES" id="ss6-Ku-XPY"/>
|
||||
<constraint firstAttribute="trailing" secondItem="kDw-2l-7gQ" secondAttribute="trailing" constant="20" symbolic="YES" id="zSz-fH-fVn"/>
|
||||
</constraints>
|
||||
<point key="canvasLocation" x="176" y="-39"/>
|
||||
<point key="canvasLocation" x="176" y="-39.5"/>
|
||||
</customView>
|
||||
</objects>
|
||||
<resources>
|
||||
|
||||
149
MacPass/Base.lproj/AutotypeDoctorReportViewController.xib
Normal file
149
MacPass/Base.lproj/AutotypeDoctorReportViewController.xib
Normal file
@@ -0,0 +1,149 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15702" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15702"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="MPAutotypeDoctorReportViewController">
|
||||
<connections>
|
||||
<outlet property="accessibiltyStatusImageView" destination="Xzw-kJ-WoH" id="jEb-0z-dNB"/>
|
||||
<outlet property="accessibiltyStatusTextField" destination="Pqa-Ff-7cc" id="h5M-ZN-GhR"/>
|
||||
<outlet property="requestScreenRecordingButton" destination="d5Z-hD-bpr" id="gS2-vu-2zM"/>
|
||||
<outlet property="screenRecordingStatusImageView" destination="vvZ-Lj-v22" id="7h0-cF-Mxt"/>
|
||||
<outlet property="screenRecordingStatusTextField" destination="IP0-CP-tlA" id="AfL-XZ-KRk"/>
|
||||
<outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<customView id="Hz6-mo-xeY">
|
||||
<rect key="frame" x="0.0" y="0.0" width="400" height="469"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Xzw-kJ-WoH">
|
||||
<rect key="frame" x="20" y="433" width="16" height="16"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="NSStatusAvailable" id="DWu-HI-z3k"/>
|
||||
</imageView>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Pqa-Ff-7cc">
|
||||
<rect key="frame" x="42" y="433" width="80" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Accessibility" id="aIL-8W-63g">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" verticalCompressionResistancePriority="751" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="hY9-T0-hke">
|
||||
<rect key="frame" x="42" y="369" width="340" height="56"/>
|
||||
<textFieldCell key="cell" controlSize="small" selectable="YES" id="6GI-KJ-Xue">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<string key="title">MacPass will send key press events to the system when Autotype or Global Autotype is executed. Since macOS 10.14 Mojave this is only possible, if Accessibility permissions are granted to the application.</string>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="x9d-0h-hyJ">
|
||||
<rect key="frame" x="38" y="321" width="236" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="Open Accessibilty Preferences…" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="8m1-vs-pd5">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="openAccessibiltyPreferences:" target="-2" id="aZf-xi-w73"/>
|
||||
</connections>
|
||||
</button>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="vvZ-Lj-v22">
|
||||
<rect key="frame" x="20" y="283" width="16" height="16"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="NSStatusAvailable" id="kCX-CB-5vQ"/>
|
||||
</imageView>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" verticalCompressionResistancePriority="751" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6vq-iM-inn">
|
||||
<rect key="frame" x="42" y="177" width="340" height="98"/>
|
||||
<textFieldCell key="cell" controlSize="small" selectable="YES" id="7of-1z-Nfk">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<string key="title">MacPass will read every window title when Global Autotype is executed to find a match. Since macOS 10.15 Catalina it is not possible to read any window title, if the user has not granted permissions to record the screen. If you are running macOS 10.15 or higher, MacPass will check if it can read every window title of currently visible windows. This test will not read the actual title. The titles aren't stored or processed in any way.</string>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="IP0-CP-tlA">
|
||||
<rect key="frame" x="42" y="283" width="112" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Screen Recording" id="9gr-mz-2I4">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<box verticalHuggingPriority="750" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="BHb-cd-Q0r">
|
||||
<rect key="frame" x="20" y="305" width="360" height="5"/>
|
||||
</box>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="d5Z-hD-bpr">
|
||||
<rect key="frame" x="38" y="129" width="177" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="Request Permissions…" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="1Nx-Cg-TCn">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="requestScreenRecordingPermissions:" target="-2" id="dvF-Aw-j5Q"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" preferredMaxLayoutWidth="336" translatesAutoresizingMaskIntoConstraints="NO" id="cu4-Jq-eaS">
|
||||
<rect key="frame" x="42" y="86" width="340" height="42"/>
|
||||
<textFieldCell key="cell" selectable="YES" id="Mhg-rd-1hK">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<string key="title">To request Screen Recording permissions, MacPass will try to capture a 1 by 1 Pixel sized screenshot of the top left part of your screen. The data is not stored nor processed in any way.</string>
|
||||
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="dek-ho-dPm">
|
||||
<rect key="frame" x="38" y="50" width="271" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="Open Screen Recording Preferences…" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="lgB-Ys-L9R">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="openScreenRecordingPreferences:" target="-2" id="rvE-ff-sR2"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="IP0-CP-tlA" firstAttribute="top" secondItem="BHb-cd-Q0r" secondAttribute="bottom" constant="8" symbolic="YES" id="0sS-li-mx4"/>
|
||||
<constraint firstItem="d5Z-hD-bpr" firstAttribute="top" secondItem="6vq-iM-inn" secondAttribute="bottom" constant="20" symbolic="YES" id="1SD-9R-lf0"/>
|
||||
<constraint firstAttribute="trailing" secondItem="hY9-T0-hke" secondAttribute="trailing" constant="20" symbolic="YES" id="1lC-Hg-bzq"/>
|
||||
<constraint firstItem="vvZ-Lj-v22" firstAttribute="leading" secondItem="Xzw-kJ-WoH" secondAttribute="leading" id="2ZC-Uf-Pe3"/>
|
||||
<constraint firstItem="vvZ-Lj-v22" firstAttribute="centerY" secondItem="IP0-CP-tlA" secondAttribute="centerY" id="2t3-9h-RIf"/>
|
||||
<constraint firstItem="Pqa-Ff-7cc" firstAttribute="leading" secondItem="Xzw-kJ-WoH" secondAttribute="trailing" constant="8" symbolic="YES" id="57a-U7-goz"/>
|
||||
<constraint firstItem="6vq-iM-inn" firstAttribute="top" secondItem="IP0-CP-tlA" secondAttribute="bottom" constant="8" symbolic="YES" id="5ag-ah-YEW"/>
|
||||
<constraint firstItem="dek-ho-dPm" firstAttribute="leading" secondItem="6vq-iM-inn" secondAttribute="leading" id="6Zj-Te-qHt"/>
|
||||
<constraint firstItem="cu4-Jq-eaS" firstAttribute="leading" secondItem="6vq-iM-inn" secondAttribute="leading" id="A1C-96-raA"/>
|
||||
<constraint firstItem="x9d-0h-hyJ" firstAttribute="top" secondItem="hY9-T0-hke" secondAttribute="bottom" constant="20" symbolic="YES" id="Avt-sj-8GL"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="Pqa-Ff-7cc" secondAttribute="trailing" constant="20" symbolic="YES" id="Bmg-tH-M7Q"/>
|
||||
<constraint firstAttribute="trailing" secondItem="6vq-iM-inn" secondAttribute="trailing" constant="20" symbolic="YES" id="Cga-EU-fSf"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="x9d-0h-hyJ" secondAttribute="trailing" constant="20" symbolic="YES" id="D8o-Gu-s2Y"/>
|
||||
<constraint firstItem="dek-ho-dPm" firstAttribute="top" secondItem="cu4-Jq-eaS" secondAttribute="bottom" constant="8" symbolic="YES" id="EH9-BF-LGO"/>
|
||||
<constraint firstItem="x9d-0h-hyJ" firstAttribute="leading" secondItem="Pqa-Ff-7cc" secondAttribute="leading" id="J4Y-VM-MZt"/>
|
||||
<constraint firstAttribute="trailing" secondItem="cu4-Jq-eaS" secondAttribute="trailing" constant="20" symbolic="YES" id="Mvl-zI-d9a"/>
|
||||
<constraint firstItem="BHb-cd-Q0r" firstAttribute="top" secondItem="x9d-0h-hyJ" secondAttribute="bottom" constant="20" symbolic="YES" id="TlD-dn-LEm"/>
|
||||
<constraint firstItem="BHb-cd-Q0r" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" symbolic="YES" id="YdV-6E-JaO"/>
|
||||
<constraint firstItem="IP0-CP-tlA" firstAttribute="leading" secondItem="Pqa-Ff-7cc" secondAttribute="leading" id="c76-Ak-WXw"/>
|
||||
<constraint firstItem="Xzw-kJ-WoH" firstAttribute="centerY" secondItem="Pqa-Ff-7cc" secondAttribute="centerY" id="dF3-uj-K2q"/>
|
||||
<constraint firstItem="Pqa-Ff-7cc" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="20" symbolic="YES" id="eyJ-B0-kI3"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="d5Z-hD-bpr" secondAttribute="trailing" constant="20" symbolic="YES" id="hEn-cJ-Ymz"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="dek-ho-dPm" secondAttribute="trailing" constant="20" symbolic="YES" id="jIb-UJ-efk"/>
|
||||
<constraint firstItem="hY9-T0-hke" firstAttribute="leading" secondItem="Pqa-Ff-7cc" secondAttribute="leading" id="kLD-8A-d1Y"/>
|
||||
<constraint firstItem="cu4-Jq-eaS" firstAttribute="top" secondItem="d5Z-hD-bpr" secondAttribute="bottom" constant="8" symbolic="YES" id="nRl-Zo-yCx"/>
|
||||
<constraint firstItem="6vq-iM-inn" firstAttribute="leading" secondItem="IP0-CP-tlA" secondAttribute="leading" id="nby-S7-orD"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="IP0-CP-tlA" secondAttribute="trailing" constant="20" symbolic="YES" id="ntn-yh-HC3"/>
|
||||
<constraint firstItem="Xzw-kJ-WoH" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" symbolic="YES" id="oAi-Zl-LCI"/>
|
||||
<constraint firstItem="hY9-T0-hke" firstAttribute="top" secondItem="Pqa-Ff-7cc" secondAttribute="bottom" constant="8" symbolic="YES" id="oK3-FK-r0S"/>
|
||||
<constraint firstItem="d5Z-hD-bpr" firstAttribute="leading" secondItem="6vq-iM-inn" secondAttribute="leading" id="oZ8-mG-RYJ"/>
|
||||
<constraint firstAttribute="trailing" secondItem="BHb-cd-Q0r" secondAttribute="trailing" constant="20" symbolic="YES" id="ryW-3O-g6b"/>
|
||||
</constraints>
|
||||
<point key="canvasLocation" x="-409" y="-112.5"/>
|
||||
</customView>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="NSStatusAvailable" width="16" height="16"/>
|
||||
</resources>
|
||||
</document>
|
||||
118
MacPass/Base.lproj/Credits.rtf
Normal file
118
MacPass/Base.lproj/Credits.rtf
Normal file
@@ -0,0 +1,118 @@
|
||||
{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf600
|
||||
{\fonttbl\f0\fswiss\fcharset0 Helvetica-Bold;\f1\fswiss\fcharset0 Helvetica;\f2\fnil\fcharset0 SFProText-Regular;
|
||||
}
|
||||
{\colortbl;\red255\green255\blue255;\red0\green0\blue0;\red9\green79\blue209;\red69\green60\blue204;
|
||||
\red52\green110\blue183;\red38\green38\blue38;}
|
||||
{\*\expandedcolortbl;;\cssrgb\c0\c0\c0\cname textColor;\cssrgb\c0\c40784\c85490\cname linkColor;\cssrgb\c34510\c33725\c83922;
|
||||
\csgenericrgb\c20392\c43137\c71765;\csgenericrgb\c14902\c14902\c14902;}
|
||||
\paperw11900\paperh16840\vieww25780\viewh19380\viewkind0
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
|
||||
|
||||
\f0\b\fs24 \cf2 Project Website:\cf0 \
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
|
||||
{\field{\*\fldinst{HYPERLINK "https://macpassapp.org"}}{\fldrslt
|
||||
\f1\b0 \cf2 macpassapp.org}}
|
||||
\f1\b0 \cf3 \
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
|
||||
{\field{\*\fldinst{HYPERLINK "https://github.com/mstarke/MacPass"}}{\fldrslt \cf3 MacPass}} \cf2 on GitHub.\
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
|
||||
|
||||
\f0\b \cf2 \
|
||||
License:\
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
|
||||
|
||||
\f1\b0 \cf2 MacPass KeePass compatible client for OS X\
|
||||
Copyright (c) 2012-2020 Michael Starke, HicknHack Software GmbH\
|
||||
\
|
||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by\
|
||||
the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\
|
||||
\
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of\
|
||||
\
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\
|
||||
\
|
||||
You should have received a copy of the GNU General Public License along with this program. If not, see {\field{\*\fldinst{HYPERLINK "http://www.gnu.org/licenses/"}}{\fldrslt \cf3 http://www.gnu.org/licenses/}}\cf0 .\
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
|
||||
\cf0 \kerning1\expnd0\expndtw3
|
||||
\
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
|
||||
|
||||
\f0\b \cf2 \kerning1\expnd0\expndtw0 Credits:\
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
|
||||
|
||||
\f1\b0 \cf2 \
|
||||
Dutch translation: {\field{\*\fldinst{HYPERLINK "https://github.com/FrankKooij"}}{\fldrslt \cf3 Frank Kooij}},
|
||||
\f2 \cf4 \expnd0\expndtw0\kerning0
|
||||
{\field{\*\fldinst{HYPERLINK "https://github.com/clone1612"}}{\fldrslt
|
||||
\f1 \cf3 \kerning1\expnd0\expndtw0 Jannick Hemelhof}}
|
||||
\f1 \cf0 \kerning1\expnd0\expndtw0 \
|
||||
\
|
||||
\cf2 French translation:\cf0 {\field{\*\fldinst{HYPERLINK "mailto:gil@panix.com"}}{\fldrslt \cf3 Gil Andr\'e9}}\
|
||||
\
|
||||
\cf2 Italian translation:\cf0 {\field{\*\fldinst{HYPERLINK "mailto:info@francescoservida.ch"}}{\fldrslt \cf3 Francesco Servida}}\
|
||||
\
|
||||
\cf2 Polish translation:\cf0 {\field{\*\fldinst{HYPERLINK "http://www.webii.pl/"}}{\fldrslt \cf3 Micha\uc0\u322 Jaglewicz}}\
|
||||
\
|
||||
\cf2 Russian translation:\cf0 {\field{\*\fldinst{HYPERLINK "mailto:alex@mrdoggy.info"}}{\fldrslt \cf3 Aliaksandr Piatkevich}}\
|
||||
\
|
||||
\cf2 Simplified Chinese translation:\cf0 {\field{\*\fldinst{HYPERLINK "mailto:patchao2000@gmail.com"}}{\fldrslt \cf3 Zhao Peng}}\
|
||||
\
|
||||
\cf2 Spanisch translation:\cf0 {\field{\*\fldinst{HYPERLINK "https://github.com/m0yP"}}{\fldrslt \cf3 \expnd0\expndtw0\kerning0
|
||||
Moises Perez}}\
|
||||
\
|
||||
\cf2 MacPass\kerning1\expnd0\expndtw3
|
||||
\kerning1\expnd0\expndtw0 Icon:\cf0 {\field{\*\fldinst{HYPERLINK "http://iiro.jappinen.me"}}{\fldrslt \cf3 Iiro J\'e4ppinen}}\
|
||||
\
|
||||
\cf2 Database Icons:\cf0 {\field{\*\fldinst{HYPERLINK "https://github.com/JoannaOlsen"}}{\fldrslt \cf3 Joanna Olsen}}\cf5 \
|
||||
\
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
|
||||
{\field{\*\fldinst{HYPERLINK "https://github.com/robbiehanson/KissXML"}}{\fldrslt \cf3 KissXML}}\cf6 \
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
|
||||
\cf2 Copyright \'a9 2012 Robbie Hanson. All rights reserved.\
|
||||
\
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
|
||||
{\field{\*\fldinst{HYPERLINK "https://github.com/MiniKeePass/MiniKeePass"}}{\fldrslt \cf3 MiniKeePass}}\cf6 \
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
|
||||
\cf2 Copyright \'a9 2011 Jason Rush and John Flanagan. All rights reserved.\cf6 \
|
||||
\
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
|
||||
{\field{\*\fldinst{HYPERLINK "https://github.com/mpowrie/KeePassLib"}}{\fldrslt \cf3 KeePass Database Library}}\
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
|
||||
\cf2 Copyright \'a9 2010 Qiang Yu. All rights reserved.\
|
||||
\
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
|
||||
{\field{\*\fldinst{HYPERLINK "http://sparkle.andymatuschak.org"}}{\fldrslt \cf3 Sparkl\kerning1\expnd0\expndtw3
|
||||
e}}\cf6 \kerning1\expnd0\expndtw3
|
||||
\
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
|
||||
\cf2 \kerning1\expnd0\expndtw3
|
||||
Copyright \'a9 2006 Andy Matuschak. \kerning1\expnd0\expndtw0 All rights reserved.\kerning1\expnd0\expndtw3
|
||||
\
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
|
||||
\cf2 \kerning1\expnd0\expndtw0 \
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
|
||||
{\field{\*\fldinst{HYPERLINK "http://stackoverflow.com/questions/11386876/how-to-encode-and-decode-files-as-base64-in-cocoa-objective-c"}}{\fldrslt \cf3 NSData+Base64}}\cf6 \
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
|
||||
\cf2 Copyright \'a92013, {\field{\*\fldinst{HYPERLINK "http://stackoverflow.com/users/200321/denis2342"}}{\fldrslt \cf3 denis2342}}\cf3 \
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
|
||||
\cf6 \
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
|
||||
{\field{\*\fldinst{HYPERLINK "http://www.cocoadev.com/index.pl?NSDataCategory"}}{\fldrslt \cf3 NSData+Gzip}}\
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
|
||||
\cf2 Extracted from code on the CocoaDev Wiki\cf6 \
|
||||
\
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
|
||||
{\field{\*\fldinst{HYPERLINK "https://github.com/karelia/SecurityInterface"}}{\fldrslt \cf3 KSPasswordField}}\
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
|
||||
\cf2 Code reused in HNHUISecureTextField\
|
||||
Copyright \'a92012 Mike Abdullah, Karelia Software. All rights reserved.\cf6 \
|
||||
\
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
|
||||
{\field{\*\fldinst{HYPERLINK "https://github.com/AlanQuatermain/aqtoolkit"}}{\fldrslt \cf3 NSData+CommonCrypto}}\
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
|
||||
\cf2 Copyright \'a92008-2009 Jim Dovey, All rights reserved.\cf6 \
|
||||
\
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
|
||||
{\field{\*\fldinst{HYPERLINK "https://github.com/mattt/TransformerKit"}}{\fldrslt \cf3 TransformerKit}}\
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
|
||||
\cf2 Copyright \'a92012 Mattt Thompson. All rights reserved}
|
||||
@@ -1,9 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14113" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14113"/>
|
||||
<capability name="box content view" minToolsVersion="7.0"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
@@ -48,7 +47,7 @@
|
||||
</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="1">
|
||||
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="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="500" height="360"/>
|
||||
@@ -99,7 +98,7 @@ Gw
|
||||
</constraints>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="232">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
@@ -120,7 +119,7 @@ Gw
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="1394">
|
||||
<rect key="frame" x="152" y="73" width="70" height="26"/>
|
||||
<rect key="frame" x="152" y="73" width="71" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="1395">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
@@ -158,30 +157,30 @@ Gw
|
||||
</colorWell>
|
||||
<scrollView horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1530">
|
||||
<rect key="frame" x="154" y="117" width="280" height="100"/>
|
||||
<clipView key="contentView" id="WOI-1v-RCe">
|
||||
<clipView key="contentView" drawsBackground="NO" id="WOI-1v-RCe">
|
||||
<rect key="frame" x="1" y="1" width="278" height="98"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textView importsGraphics="NO" verticallyResizable="YES" usesFontPanel="YES" findStyle="panel" continuousSpellChecking="YES" allowsUndo="YES" usesRuler="YES" allowsNonContiguousLayout="YES" spellingCorrection="YES" smartInsertDelete="YES" id="1531">
|
||||
<rect key="frame" x="0.0" y="0.0" width="278" height="98"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
<size key="minSize" width="278" height="98"/>
|
||||
<size key="maxSize" width="463" height="10000000"/>
|
||||
<color key="insertionPointColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="insertionPointColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
</textView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</clipView>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="100" id="8fE-cP-ksD"/>
|
||||
<constraint firstAttribute="width" constant="280" id="J06-kE-yVi"/>
|
||||
</constraints>
|
||||
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="YES" id="1532">
|
||||
<scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="YES" id="1532">
|
||||
<rect key="frame" x="-100" y="-100" width="87" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<scroller key="verticalScroller" verticalHuggingPriority="750" horizontal="NO" id="1533">
|
||||
<scroller key="verticalScroller" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="1533">
|
||||
<rect key="frame" x="263" y="1" width="16" height="98"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
@@ -241,7 +240,7 @@ Gw
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="3ek-Rg-w82">
|
||||
<rect key="frame" x="150" y="199" width="155" height="26"/>
|
||||
<rect key="frame" x="150" y="199" width="155" height="25"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="150" id="F8Y-Uw-4mL"/>
|
||||
</constraints>
|
||||
@@ -252,7 +251,7 @@ Gw
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="vH7-5a-52C">
|
||||
<rect key="frame" x="73" y="206" width="73" height="17"/>
|
||||
<rect key="frame" x="73" y="205" width="73" height="17"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Encryption:" id="gxY-UL-bEG">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -262,18 +261,18 @@ Gw
|
||||
<box title="Key derivation" translatesAutoresizingMaskIntoConstraints="NO" id="pbl-Mb-r8V">
|
||||
<rect key="frame" x="17" y="16" width="420" height="178"/>
|
||||
<view key="contentView" id="hkT-SX-Te1">
|
||||
<rect key="frame" x="2" y="2" width="416" height="161"/>
|
||||
<rect key="frame" x="3" y="3" width="414" height="160"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="P98-Cu-Tha">
|
||||
<rect key="frame" x="253" y="18" width="143" height="25"/>
|
||||
<rect key="frame" x="251" y="18" width="143" height="23"/>
|
||||
<buttonCell key="cell" type="roundTextured" title="Generate Parameters" bezelStyle="texturedRounded" alignment="center" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="PoI-Er-Y8P">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<tabView drawsBackground="NO" type="noTabsNoBorder" translatesAutoresizingMaskIntoConstraints="NO" id="2MY-PW-kzL">
|
||||
<rect key="frame" x="13" y="50" width="390" height="62"/>
|
||||
<rect key="frame" x="12" y="49" width="390" height="62"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<tabViewItems>
|
||||
<tabViewItem label="Aes" identifier="1" id="ft1-pl-lpO">
|
||||
@@ -299,7 +298,7 @@ Gw
|
||||
<real key="minimum" value="0.0"/>
|
||||
</numberFormatter>
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
@@ -347,7 +346,7 @@ Gw
|
||||
<real key="maximum" value="16777215"/>
|
||||
</numberFormatter>
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
@@ -359,7 +358,7 @@ Gw
|
||||
<real key="maximum" value="4294967295"/>
|
||||
</numberFormatter>
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
@@ -415,7 +414,7 @@ Gw
|
||||
</tabViewItems>
|
||||
</tabView>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="2cq-R3-Ksh">
|
||||
<rect key="frame" x="131" y="117" width="155" height="26"/>
|
||||
<rect key="frame" x="130" y="116" width="155" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="Pb9-YV-rYe">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
@@ -426,7 +425,7 @@ Gw
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="4el-r1-iRL">
|
||||
<rect key="frame" x="64" y="124" width="63" height="17"/>
|
||||
<rect key="frame" x="63" y="122" width="63" height="17"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Algorithm" id="GVd-KH-pHc">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -494,7 +493,7 @@ Gw
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<stepper horizontalHuggingPriority="750" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="1294">
|
||||
<rect key="frame" x="255" y="324" width="19" height="27"/>
|
||||
<rect key="frame" x="255" y="325" width="19" height="27"/>
|
||||
<stepperCell key="cell" continuous="YES" alignment="left" maxValue="100" id="1295"/>
|
||||
</stepper>
|
||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="1268">
|
||||
@@ -522,18 +521,18 @@ Gw
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<stepper horizontalHuggingPriority="750" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="599">
|
||||
<rect key="frame" x="255" y="296" width="19" height="27"/>
|
||||
<rect key="frame" x="255" y="297" width="19" height="27"/>
|
||||
<stepperCell key="cell" continuous="YES" alignment="left" maxValue="100" id="600"/>
|
||||
</stepper>
|
||||
<button translatesAutoresizingMaskIntoConstraints="NO" id="535">
|
||||
<rect key="frame" x="184" y="265" width="137" height="18"/>
|
||||
<rect key="frame" x="184" y="266" width="137" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="Enable Recycle Bin" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="536">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="678">
|
||||
<rect key="frame" x="184" y="235" width="37" height="26"/>
|
||||
<rect key="frame" x="184" y="236" width="38" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="679">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
@@ -541,10 +540,10 @@ Gw
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<box verticalHuggingPriority="750" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="U7M-MH-EFw">
|
||||
<rect key="frame" x="20" y="287" width="467" height="5"/>
|
||||
<rect key="frame" x="20" y="288" width="467" height="5"/>
|
||||
</box>
|
||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="1582">
|
||||
<rect key="frame" x="63" y="199" width="117" height="17"/>
|
||||
<rect key="frame" x="63" y="200" width="117" height="17"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Default Username:" id="1591">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -552,15 +551,15 @@ Gw
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="1730">
|
||||
<rect key="frame" x="186" y="196" width="301" height="22"/>
|
||||
<rect key="frame" x="186" y="197" width="301" height="22"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="1731">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="1738">
|
||||
<rect key="frame" x="184" y="152" width="37" height="26"/>
|
||||
<rect key="frame" x="184" y="153" width="38" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="1739">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
@@ -568,7 +567,7 @@ Gw
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="19r-LE-7X5">
|
||||
<rect key="frame" x="186" y="94" width="128" height="22"/>
|
||||
<rect key="frame" x="186" y="95" width="128" height="22"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="128" id="COb-0V-OmT"/>
|
||||
</constraints>
|
||||
@@ -584,21 +583,21 @@ Gw
|
||||
<stepperCell key="cell" continuous="YES" alignment="left" maxValue="100" id="qQV-3d-GpK"/>
|
||||
</stepper>
|
||||
<button verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Hqc-B0-xyz">
|
||||
<rect key="frame" x="184" y="122" width="171" height="18"/>
|
||||
<rect key="frame" x="184" y="123" width="171" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="Recommend key change" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="CtU-Eq-dgy">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button translatesAutoresizingMaskIntoConstraints="NO" id="upv-b3-vCc">
|
||||
<rect key="frame" x="184" y="70" width="129" height="18"/>
|
||||
<rect key="frame" x="184" y="71" width="129" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="Force key change" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="z6u-YT-7LE">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="VYh-cm-fix">
|
||||
<rect key="frame" x="186" y="42" width="128" height="22"/>
|
||||
<rect key="frame" x="186" y="43" width="128" height="22"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="M9G-Yy-1s4">
|
||||
<customFormatter key="formatter" id="3Ax-U4-Ofb" customClass="MPDayCountFormatter"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
@@ -619,7 +618,7 @@ Gw
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<box verticalHuggingPriority="750" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="I0d-r2-ySf">
|
||||
<rect key="frame" x="20" y="144" width="467" height="5"/>
|
||||
<rect key="frame" x="20" y="145" width="467" height="5"/>
|
||||
</box>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="NPm-5h-2Mz">
|
||||
<rect key="frame" x="65" y="242" width="115" height="17"/>
|
||||
@@ -630,7 +629,7 @@ Gw
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="OmP-GD-2nA">
|
||||
<rect key="frame" x="27" y="111" width="153" height="17"/>
|
||||
<rect key="frame" x="27" y="98" width="153" height="17"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Recommend key change" id="Xib-Fn-sqx">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -638,7 +637,7 @@ Gw
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="S0c-4E-42z">
|
||||
<rect key="frame" x="56" y="59" width="124" height="17"/>
|
||||
<rect key="frame" x="56" y="46" width="124" height="17"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Enforce key change" id="5QH-N1-FHK">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -646,7 +645,7 @@ Gw
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button translatesAutoresizingMaskIntoConstraints="NO" id="VMc-Qg-eCr">
|
||||
<rect key="frame" x="184" y="18" width="257" height="18"/>
|
||||
<rect key="frame" x="184" y="19" width="257" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="Force key change once after unlocking" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="pA1-aL-KjT">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6254" systemVersion="13F34" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15702" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6254"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15702"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="MPDatePickingViewController">
|
||||
@@ -15,24 +16,23 @@
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<customView id="1">
|
||||
<rect key="frame" x="0.0" y="0.0" width="316" height="259"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="180" height="134"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<datePicker horizontalHuggingPriority="750" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="3">
|
||||
<rect key="frame" x="20" y="91" width="277" height="148"/>
|
||||
<datePickerCell key="cell" borderStyle="bezel" alignment="left" datePickerStyle="clockAndCalendar" id="4">
|
||||
<rect key="frame" x="20" y="91" width="143" height="27"/>
|
||||
<datePickerCell key="cell" borderStyle="bezel" alignment="left" id="4">
|
||||
<font key="font" metaFont="system"/>
|
||||
<calendarDate key="date" timeIntervalSinceReferenceDate="-595929600" calendarFormat="%Y-%m-%d %H:%M:%S %z">
|
||||
<date key="date" timeIntervalSinceReferenceDate="-595929600">
|
||||
<!--1982-02-12 16:00:00 +0000-->
|
||||
<timeZone key="timeZone" name="US/Pacific"/>
|
||||
</calendarDate>
|
||||
</date>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<datePickerElements key="datePickerElements" year="YES" month="YES" day="YES" hour="YES" minute="YES"/>
|
||||
</datePickerCell>
|
||||
</datePicker>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="15">
|
||||
<rect key="frame" x="18" y="47" width="281" height="26"/>
|
||||
<rect key="frame" x="18" y="47" width="145" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="16">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
@@ -43,7 +43,7 @@
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="25">
|
||||
<rect key="frame" x="226" y="18" width="70" height="25"/>
|
||||
<rect key="frame" x="90" y="19" width="70" height="23"/>
|
||||
<buttonCell key="cell" type="roundTextured" title="Use Date" bezelStyle="texturedRounded" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="26">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
@@ -53,7 +53,7 @@
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="29">
|
||||
<rect key="frame" x="162" y="18" width="56" height="25"/>
|
||||
<rect key="frame" x="26" y="19" width="56" height="23"/>
|
||||
<buttonCell key="cell" type="roundTextured" title="Cancel" bezelStyle="texturedRounded" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="30">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
@@ -77,6 +77,7 @@
|
||||
<constraint firstItem="15" firstAttribute="top" secondItem="3" secondAttribute="bottom" constant="20" symbolic="YES" id="qKB-vi-OAw"/>
|
||||
<constraint firstItem="25" firstAttribute="top" secondItem="15" secondAttribute="bottom" constant="8" symbolic="YES" id="sxX-fk-xaJ"/>
|
||||
</constraints>
|
||||
<point key="canvasLocation" x="-89" y="77"/>
|
||||
</customView>
|
||||
</objects>
|
||||
</document>
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15702" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14460.31"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15702"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="MPGeneralSettingsController">
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="MPGeneralPreferencesController">
|
||||
<connections>
|
||||
<outlet property="clearPasteboardOnQuitCheckButton" destination="447" id="520"/>
|
||||
<outlet property="clearPasteboardTimeoutPopup" destination="419" id="521"/>
|
||||
<outlet property="enableAutosaveCheckButton" destination="lz3-4U-UMI" id="L5y-58-IgH"/>
|
||||
<outlet property="fileChangeStrategyPopup" destination="wIu-Sh-2a2" id="oJo-dA-lEE"/>
|
||||
<outlet property="idleTimeOutPopup" destination="584" id="809"/>
|
||||
<outlet property="lockOnLogoutCheckButton" destination="5SP-Vi-1sn" id="yaI-LH-R5A"/>
|
||||
<outlet property="lockOnScreenSleepCheckButton" destination="nRe-7S-HwK" id="0IB-5B-pfw"/>
|
||||
<outlet property="lockOnSleepCheckButton" destination="630" id="810"/>
|
||||
<outlet property="preventUniversalClipboardSupportCheckButton" destination="nqZ-rB-mFS" id="sbx-rl-reT"/>
|
||||
<outlet property="rememberKeyFileCheckButton" destination="bSt-Wf-FNZ" id="aQm-EA-yAN"/>
|
||||
@@ -23,16 +25,16 @@
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<customView translatesAutoresizingMaskIntoConstraints="NO" id="1">
|
||||
<rect key="frame" x="0.0" y="0.0" width="400" height="482"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="411" height="547"/>
|
||||
<subviews>
|
||||
<box autoresizesSubviews="NO" verticalHuggingPriority="500" borderType="line" title="Security" translatesAutoresizingMaskIntoConstraints="NO" id="465">
|
||||
<rect key="frame" x="17" y="16" width="366" height="357"/>
|
||||
<rect key="frame" x="17" y="16" width="377" height="381"/>
|
||||
<view key="contentView" id="mNh-3L-Z6E">
|
||||
<rect key="frame" x="3" y="3" width="360" height="339"/>
|
||||
<rect key="frame" x="3" y="3" width="371" height="363"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="431">
|
||||
<rect key="frame" x="14" y="311" width="120" height="17"/>
|
||||
<rect key="frame" x="14" y="335" width="120" height="17"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="17" id="803"/>
|
||||
</constraints>
|
||||
@@ -43,13 +45,10 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="419">
|
||||
<rect key="frame" x="177" y="308" width="170" height="21"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="165" id="877"/>
|
||||
</constraints>
|
||||
<rect key="frame" x="138" y="332" width="143" height="21"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Never" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="429" id="420">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<menu key="menu" title="ClipboardClearInterval" id="421">
|
||||
<items>
|
||||
<menuItem title="Never" state="on" id="429">
|
||||
@@ -64,7 +63,7 @@
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<button verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="447">
|
||||
<rect key="frame" x="29" y="287" width="164" height="18"/>
|
||||
<rect key="frame" x="29" y="311" width="164" height="18"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="14" id="773"/>
|
||||
</constraints>
|
||||
@@ -74,10 +73,10 @@
|
||||
</buttonCell>
|
||||
</button>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="584">
|
||||
<rect key="frame" x="177" y="168" width="170" height="25"/>
|
||||
<rect key="frame" x="111" y="192" width="125" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="585">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<menu key="menu" title="LockTimes" id="586">
|
||||
<items>
|
||||
<menuItem title="Never" id="804"/>
|
||||
@@ -91,14 +90,14 @@
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<button translatesAutoresizingMaskIntoConstraints="NO" id="630">
|
||||
<rect key="frame" x="29" y="149" width="119" height="18"/>
|
||||
<rect key="frame" x="29" y="173" width="119" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="Lock after sleep" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="631">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="805">
|
||||
<rect key="frame" x="14" y="173" width="93" height="17"/>
|
||||
<rect key="frame" x="14" y="197" width="93" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Lock while idle" id="806">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -113,7 +112,7 @@
|
||||
</buttonCell>
|
||||
</button>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5cV-xX-SUU">
|
||||
<rect key="frame" x="18" y="41" width="324" height="56"/>
|
||||
<rect key="frame" x="18" y="41" width="335" height="56"/>
|
||||
<textFieldCell key="cell" sendsActionOnEndEditing="YES" id="ACh-7H-42N">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<string key="title">Enabling this compromises security. If enabled, your preferences will contain mappings from database to keyfile. Key locations for databases without a password will not be saved.</string>
|
||||
@@ -122,7 +121,7 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="oQr-FC-HkN">
|
||||
<rect key="frame" x="160" y="5" width="190" height="32"/>
|
||||
<rect key="frame" x="171" y="5" width="190" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="Clear all stored locations" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="8Ri-2s-c39">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
@@ -132,21 +131,21 @@
|
||||
</connections>
|
||||
</button>
|
||||
<button translatesAutoresizingMaskIntoConstraints="NO" id="5SP-Vi-1sn">
|
||||
<rect key="frame" x="29" y="129" width="129" height="18"/>
|
||||
<rect key="frame" x="29" y="151" width="129" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="Lock after log out" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="Dzn-9R-JjE">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="nqZ-rB-mFS">
|
||||
<rect key="frame" x="14" y="262" width="242" height="18"/>
|
||||
<rect key="frame" x="14" y="286" width="242" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="Prevent Universal Clipboard support" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="fNy-mS-phi">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="hy4-RL-dAa">
|
||||
<rect key="frame" x="18" y="200" width="324" height="56"/>
|
||||
<rect key="frame" x="18" y="224" width="335" height="56"/>
|
||||
<textFieldCell key="cell" sendsActionOnEndEditing="YES" id="JGX-Tp-KJk">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<string key="title">Disabling this compromises security. If enabled, anything copied to the Clipboard in MacPass will be available on your connected iOS devices. You should clear the clipboard on those devices manually.</string>
|
||||
@@ -154,14 +153,31 @@
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="nRe-7S-HwK">
|
||||
<rect key="frame" x="29" y="129" width="164" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="Lock after screen sleep" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="l3t-og-mJd">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="5cV-xX-SUU" firstAttribute="leading" secondItem="mNh-3L-Z6E" secondAttribute="leading" constant="20" symbolic="YES" id="1jw-nb-bAB"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="630" secondAttribute="trailing" constant="20" symbolic="YES" id="7cd-1e-eRD"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="nqZ-rB-mFS" secondAttribute="trailing" constant="20" symbolic="YES" id="CL9-fA-GTJ"/>
|
||||
<constraint firstItem="bSt-Wf-FNZ" firstAttribute="top" secondItem="nRe-7S-HwK" secondAttribute="bottom" constant="11" id="MkJ-O0-qYd"/>
|
||||
<constraint firstItem="nRe-7S-HwK" firstAttribute="leading" secondItem="447" secondAttribute="leading" id="Mrg-k2-soG"/>
|
||||
<constraint firstItem="584" firstAttribute="top" secondItem="hy4-RL-dAa" secondAttribute="bottom" constant="8" symbolic="YES" id="SV7-PD-nId"/>
|
||||
<constraint firstItem="bSt-Wf-FNZ" firstAttribute="top" secondItem="5SP-Vi-1sn" secondAttribute="bottom" constant="11" id="WUG-Uf-FCO"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="bSt-Wf-FNZ" secondAttribute="trailing" constant="20" symbolic="YES" id="VQY-eq-fCM"/>
|
||||
<constraint firstItem="nRe-7S-HwK" firstAttribute="top" secondItem="5SP-Vi-1sn" secondAttribute="bottom" constant="8" id="YZv-Dp-CrZ"/>
|
||||
<constraint firstItem="5SP-Vi-1sn" firstAttribute="leading" secondItem="447" secondAttribute="leading" id="Ylr-aA-jaD"/>
|
||||
<constraint firstItem="hy4-RL-dAa" firstAttribute="top" secondItem="nqZ-rB-mFS" secondAttribute="bottom" constant="8" symbolic="YES" id="a3i-tc-gUU"/>
|
||||
<constraint firstItem="5SP-Vi-1sn" firstAttribute="top" secondItem="630" secondAttribute="bottom" constant="6" symbolic="YES" id="acg-vp-LeB"/>
|
||||
<constraint firstItem="5SP-Vi-1sn" firstAttribute="top" secondItem="630" secondAttribute="bottom" constant="8" id="acg-vp-LeB"/>
|
||||
<constraint firstItem="584" firstAttribute="leading" secondItem="805" secondAttribute="trailing" constant="8" symbolic="YES" id="aoz-sS-O0n"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="447" secondAttribute="trailing" constant="20" symbolic="YES" id="i8H-ad-IKb"/>
|
||||
<constraint firstItem="419" firstAttribute="leading" secondItem="431" secondAttribute="trailing" constant="8" symbolic="YES" id="pN3-pB-Z5I"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="nRe-7S-HwK" secondAttribute="trailing" constant="20" symbolic="YES" id="pgB-km-W16"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="5SP-Vi-1sn" secondAttribute="trailing" constant="20" symbolic="YES" id="q0v-Wo-mHx"/>
|
||||
<constraint firstItem="nqZ-rB-mFS" firstAttribute="top" secondItem="447" secondAttribute="bottom" constant="11" id="qLm-ih-A04"/>
|
||||
<constraint firstAttribute="trailing" secondItem="5cV-xX-SUU" secondAttribute="trailing" constant="20" symbolic="YES" id="qY0-io-RZ0"/>
|
||||
<constraint firstAttribute="trailing" secondItem="hy4-RL-dAa" secondAttribute="trailing" constant="20" symbolic="YES" id="r5c-KT-eh0"/>
|
||||
@@ -170,8 +186,8 @@
|
||||
</constraints>
|
||||
</view>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="419" secondAttribute="trailing" constant="16" id="1de-jU-TAq"/>
|
||||
<constraint firstAttribute="trailing" secondItem="584" secondAttribute="trailing" constant="16" id="GAz-Mn-Z2y"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="419" secondAttribute="trailing" constant="16" id="1de-jU-TAq"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="584" secondAttribute="trailing" constant="16" id="GAz-Mn-Z2y"/>
|
||||
<constraint firstAttribute="bottom" secondItem="oQr-FC-HkN" secondAttribute="bottom" constant="11" id="M71-WV-WFc"/>
|
||||
<constraint firstItem="5cV-xX-SUU" firstAttribute="top" secondItem="bSt-Wf-FNZ" secondAttribute="bottom" constant="9" id="NYW-dJ-CHg"/>
|
||||
<constraint firstItem="805" firstAttribute="centerY" secondItem="584" secondAttribute="centerY" id="OOq-TD-dmj"/>
|
||||
@@ -187,26 +203,40 @@
|
||||
<constraint firstItem="oQr-FC-HkN" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="465" secondAttribute="leading" constant="16" id="kZ7-HL-y2Q"/>
|
||||
<constraint firstItem="oQr-FC-HkN" firstAttribute="top" secondItem="5cV-xX-SUU" secondAttribute="bottom" constant="8" id="qsT-Cs-vVj"/>
|
||||
<constraint firstItem="447" firstAttribute="top" secondItem="419" secondAttribute="bottom" constant="8" symbolic="YES" id="u35-aE-Ui9"/>
|
||||
<constraint firstItem="419" firstAttribute="leading" secondItem="584" secondAttribute="leading" id="xws-PK-qQU"/>
|
||||
<constraint firstItem="630" firstAttribute="leading" secondItem="447" secondAttribute="leading" id="ybt-cQ-JwG"/>
|
||||
<constraint firstItem="447" firstAttribute="top" secondItem="431" secondAttribute="bottom" constant="8" symbolic="YES" id="zkd-Hf-09b"/>
|
||||
</constraints>
|
||||
</box>
|
||||
<box autoresizesSubviews="NO" verticalHuggingPriority="500" borderType="line" title="File Handling" translatesAutoresizingMaskIntoConstraints="NO" id="888">
|
||||
<rect key="frame" x="17" y="375" width="366" height="87"/>
|
||||
<rect key="frame" x="17" y="399" width="377" height="128"/>
|
||||
<view key="contentView" id="cpg-tt-SHE">
|
||||
<rect key="frame" x="3" y="3" width="360" height="69"/>
|
||||
<rect key="frame" x="3" y="3" width="371" height="110"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="252" translatesAutoresizingMaskIntoConstraints="NO" id="530">
|
||||
<rect key="frame" x="14" y="43" width="234" height="18"/>
|
||||
<rect key="frame" x="14" y="84" width="234" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="Reopen last Database after Launch" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="531">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="lz3-4U-UMI">
|
||||
<rect key="frame" x="14" y="64" width="123" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="Enable Autosave" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="wG7-bi-2fi">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3Bo-Ml-1KB">
|
||||
<rect key="frame" x="18" y="44" width="335" height="14"/>
|
||||
<textFieldCell key="cell" controlSize="small" title="Close and open all documents for changes to take effect" id="ya5-ps-c4W">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="h3w-Ms-ohK">
|
||||
<rect key="frame" x="14" y="20" width="93" height="17"/>
|
||||
<rect key="frame" x="14" y="20" width="93" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="If file changes:" id="QrK-hM-Xt1">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -214,21 +244,28 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<popUpButton verticalHuggingPriority="750" horizontalCompressionResistancePriority="749" translatesAutoresizingMaskIntoConstraints="NO" id="wIu-Sh-2a2">
|
||||
<rect key="frame" x="111" y="14" width="232" height="25"/>
|
||||
<rect key="frame" x="111" y="13" width="38" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="1R2-5t-LWk">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<menu key="menu" id="DQY-17-yKP"/>
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="wIu-Sh-2a2" secondAttribute="trailing" constant="20" id="2Qw-fT-Dd8"/>
|
||||
<constraint firstItem="3Bo-Ml-1KB" firstAttribute="leading" secondItem="cpg-tt-SHE" secondAttribute="leading" constant="20" symbolic="YES" id="2Jh-pk-bN7"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="wIu-Sh-2a2" secondAttribute="trailing" constant="20" id="2Qw-fT-Dd8"/>
|
||||
<constraint firstAttribute="trailing" secondItem="3Bo-Ml-1KB" secondAttribute="trailing" constant="20" symbolic="YES" id="2UW-ao-hrC"/>
|
||||
<constraint firstAttribute="bottom" secondItem="h3w-Ms-ohK" secondAttribute="bottom" constant="20" symbolic="YES" id="3KB-kR-5d6"/>
|
||||
<constraint firstItem="h3w-Ms-ohK" firstAttribute="leading" secondItem="530" secondAttribute="leading" id="4Fi-rX-8e0"/>
|
||||
<constraint firstItem="lz3-4U-UMI" firstAttribute="top" secondItem="530" secondAttribute="bottom" constant="6" symbolic="YES" id="BQf-9P-8Y8"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="lz3-4U-UMI" secondAttribute="trailing" constant="20" symbolic="YES" id="Kaj-GT-zpd"/>
|
||||
<constraint firstItem="wIu-Sh-2a2" firstAttribute="leading" secondItem="h3w-Ms-ohK" secondAttribute="trailing" constant="8" id="LYK-Na-Md1"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="530" secondAttribute="trailing" constant="20" symbolic="YES" id="QEp-Zq-u24"/>
|
||||
<constraint firstItem="wIu-Sh-2a2" firstAttribute="baseline" secondItem="h3w-Ms-ohK" secondAttribute="baseline" id="Zqx-cl-oal"/>
|
||||
<constraint firstItem="h3w-Ms-ohK" firstAttribute="top" secondItem="530" secondAttribute="bottom" constant="8" id="kIs-yJ-F2K"/>
|
||||
<constraint firstItem="h3w-Ms-ohK" firstAttribute="top" secondItem="3Bo-Ml-1KB" secondAttribute="bottom" constant="8" symbolic="YES" id="emA-Z1-LCv"/>
|
||||
<constraint firstItem="lz3-4U-UMI" firstAttribute="leading" secondItem="cpg-tt-SHE" secondAttribute="leading" constant="16" id="pm7-O1-afa"/>
|
||||
<constraint firstItem="3Bo-Ml-1KB" firstAttribute="top" secondItem="lz3-4U-UMI" secondAttribute="bottom" constant="8" symbolic="YES" id="xkU-ut-P9X"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<constraints>
|
||||
@@ -243,11 +280,11 @@
|
||||
<constraint firstItem="888" firstAttribute="leading" secondItem="1" secondAttribute="leading" constant="20" symbolic="YES" id="891"/>
|
||||
<constraint firstAttribute="trailing" secondItem="888" secondAttribute="trailing" constant="20" symbolic="YES" id="893"/>
|
||||
<constraint firstItem="888" firstAttribute="top" secondItem="1" secondAttribute="top" constant="20" symbolic="YES" id="903"/>
|
||||
<constraint firstAttribute="width" constant="400" id="918"/>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="400" id="918"/>
|
||||
<constraint firstAttribute="bottom" secondItem="465" secondAttribute="bottom" constant="20" symbolic="YES" id="uwq-az-XwJ"/>
|
||||
<constraint firstItem="465" firstAttribute="top" secondItem="cpg-tt-SHE" secondAttribute="bottom" constant="5" id="wyH-HB-i2U"/>
|
||||
</constraints>
|
||||
<point key="canvasLocation" x="-363" y="-54"/>
|
||||
<point key="canvasLocation" x="-458" y="-295"/>
|
||||
</customView>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14460.31"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="MPIntegrationSettingsController">
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="MPIntegrationPreferencesController">
|
||||
<connections>
|
||||
<outlet property="autotypeStackView" destination="j52-9L-k7c" id="Mxw-aa-elx"/>
|
||||
<outlet property="autotypeWarningTextField" destination="hMJ-Mo-xOM" id="LcH-X2-TAm"/>
|
||||
@@ -26,34 +26,34 @@
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<customView translatesAutoresizingMaskIntoConstraints="NO" id="1">
|
||||
<rect key="frame" x="0.0" y="0.0" width="400" height="463"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="400" height="449"/>
|
||||
<subviews>
|
||||
<box autoresizesSubviews="NO" verticalHuggingPriority="500" borderType="line" title="Autotype" translatesAutoresizingMaskIntoConstraints="NO" id="P9N-HM-wER">
|
||||
<rect key="frame" x="17" y="115" width="366" height="328"/>
|
||||
<rect key="frame" x="17" y="115" width="366" height="314"/>
|
||||
<view key="contentView" id="faU-Ok-HJ3">
|
||||
<rect key="frame" x="3" y="3" width="360" height="310"/>
|
||||
<rect key="frame" x="3" y="3" width="360" height="296"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<stackView orientation="vertical" alignment="leading" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" translatesAutoresizingMaskIntoConstraints="NO" id="j52-9L-k7c">
|
||||
<rect key="frame" x="16" y="17" width="328" height="283"/>
|
||||
<rect key="frame" x="16" y="17" width="328" height="269"/>
|
||||
<beginningViews>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" preferredMaxLayoutWidth="328" translatesAutoresizingMaskIntoConstraints="NO" id="hMJ-Mo-xOM">
|
||||
<rect key="frame" x="-2" y="227" width="332" height="56"/>
|
||||
<rect key="frame" x="-2" y="227" width="332" height="42"/>
|
||||
<textFieldCell key="cell" controlSize="small" id="H37-ku-aTc">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<string key="title">Autotype is not available, because MacPass is not allowed to control your computer. To enable Autotype, go to the Security and Privacy Preferences and add MacPass to the Accessibilty group. Changes require a restart of MacPass.</string>
|
||||
<string key="title">Autotype might not work properly. Some issues where found that prevent Autotype or Global Autotype to work. Please run the Autotype Doctor to fix those issues.</string>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="jai-b6-Qv4">
|
||||
<rect key="frame" x="-6" y="191" width="160" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="Open Preferences…" bezelStyle="rounded" alignment="center" borderStyle="border" inset="2" id="NP0-R3-m6n">
|
||||
<rect key="frame" x="-6" y="191" width="177" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="Run Autotype Doctor…" bezelStyle="rounded" alignment="center" borderStyle="border" inset="2" id="NP0-R3-m6n">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="openAccessibiltyPreferences:" target="-2" id="GTg-6Z-6nd"/>
|
||||
<action selector="runAutotypeDoctor:" target="-2" id="u2q-ab-rQY"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="tik-Ar-FJg">
|
||||
@@ -229,7 +229,7 @@
|
||||
<constraint firstItem="P9N-HM-wER" firstAttribute="leading" secondItem="1" secondAttribute="leading" constant="20" id="ulV-xL-ldJ"/>
|
||||
<constraint firstItem="VVs-b5-cX9" firstAttribute="leading" secondItem="P9N-HM-wER" secondAttribute="leading" id="z4a-9C-78h"/>
|
||||
</constraints>
|
||||
<point key="canvasLocation" x="-357" y="-1007.5"/>
|
||||
<point key="canvasLocation" x="-558" y="-1123"/>
|
||||
</customView>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14313.18" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14313.18"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
||||
@@ -151,9 +151,9 @@
|
||||
<action selector="mergeWithOther:" target="-1" id="OyM-CZ-TDD"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Import" id="aTb-sW-nUd">
|
||||
<menuItem title="Import From" id="aTb-sW-nUd">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Import" id="4q9-u1-pcm">
|
||||
<menu key="submenu" title="Import From" id="4q9-u1-pcm">
|
||||
<items>
|
||||
<menuItem title="XML…" id="rW0-r1-QYL">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
@@ -167,16 +167,20 @@
|
||||
</connections>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Export" id="tz9-yK-pOf">
|
||||
<menuItem title="Export To" id="tz9-yK-pOf">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Export" id="p8h-Fg-h1O">
|
||||
<menu key="submenu" title="Export To" id="p8h-Fg-h1O">
|
||||
<items>
|
||||
<menuItem title="XML…" keyEquivalent="E" id="1259">
|
||||
<menuItem title="XML…" id="1259">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="exportAsXML:" target="-1" id="NCG-gr-YI5"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="494" id="ALY-P3-PzW"/>
|
||||
</connections>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="74">
|
||||
@@ -317,12 +321,18 @@ CA
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="1176"/>
|
||||
<menuItem title="Show Password Generator" keyEquivalent="p" id="1200">
|
||||
<menuItem title="Password Generator" keyEquivalent="p" id="1200">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="showPasswordCreator:" target="494" id="1202"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Autotype Doctor" id="zWx-Re-iuJ">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="showAutotypeDoctor:" target="494" id="fsq-lt-9gZ"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="92">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
@@ -351,6 +361,7 @@ CA
|
||||
</menu>
|
||||
<customObject id="494" customClass="MPAppDelegate">
|
||||
<connections>
|
||||
<outlet property="exportMenu" destination="p8h-Fg-h1O" id="elV-BC-ZZt"/>
|
||||
<outlet property="fileNewMenuItem" destination="82" id="BUX-dy-HS2"/>
|
||||
<outlet property="fixAutotypeMenuItem" destination="nx7-Vf-LiD" id="5n1-bG-JxJ"/>
|
||||
<outlet property="importMenu" destination="4q9-u1-pcm" id="0XM-fS-Vyy"/>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14460.31"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15705" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14460.31"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15705"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
@@ -25,18 +25,18 @@
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="196" y="240" width="403" height="219"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
||||
<view key="contentView" misplaced="YES" id="2">
|
||||
<rect key="frame" x="0.0" y="0.0" width="403" height="219"/>
|
||||
<view key="contentView" id="2">
|
||||
<rect key="frame" x="0.0" y="0.0" width="403" height="210"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<pathControl verticalHuggingPriority="750" allowsExpansionToolTips="YES" translatesAutoresizingMaskIntoConstraints="NO" id="4" customClass="MPPathControl">
|
||||
<rect key="frame" x="105" y="87" width="242" height="25"/>
|
||||
<pathCell key="cell" selectable="YES" editable="YES" alignment="left" pathStyle="popUp" id="23">
|
||||
<pathCell key="cell" selectable="YES" editable="YES" alignment="left" pathStyle="popUp" id="23" customClass="MPPathCell">
|
||||
<font key="font" metaFont="system"/>
|
||||
</pathCell>
|
||||
</pathControl>
|
||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="5">
|
||||
<rect key="frame" x="53" y="91" width="49" height="17"/>
|
||||
<rect key="frame" x="53" y="91" width="49" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Keyfile:" id="22">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -54,7 +54,7 @@
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="7">
|
||||
<rect key="frame" x="352" y="153" width="31" height="23"/>
|
||||
<rect key="frame" x="352" y="145" width="31" height="23"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="31" id="59"/>
|
||||
</constraints>
|
||||
@@ -74,7 +74,7 @@
|
||||
</connections>
|
||||
</button>
|
||||
<secureTextField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="9" customClass="HNHUISecureTextField">
|
||||
<rect key="frame" x="108" y="152" width="236" height="24"/>
|
||||
<rect key="frame" x="108" y="148" width="236" height="20"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="200" id="Gin-yR-DMk"/>
|
||||
</constraints>
|
||||
@@ -88,7 +88,7 @@
|
||||
</secureTextFieldCell>
|
||||
</secureTextField>
|
||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="10">
|
||||
<rect key="frame" x="51" y="122" width="51" height="17"/>
|
||||
<rect key="frame" x="51" y="121" width="51" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Repeat:" id="16">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -96,7 +96,7 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<secureTextField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="11" customClass="HNHUISecureTextField">
|
||||
<rect key="frame" x="108" y="118" width="236" height="24"/>
|
||||
<rect key="frame" x="108" y="118" width="236" height="20"/>
|
||||
<secureTextFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="Repeat Password" drawsBackground="YES" usesSingleLineMode="YES" id="15">
|
||||
<font key="font" size="13" name="Menlo-Regular"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -107,8 +107,8 @@
|
||||
</secureTextFieldCell>
|
||||
</secureTextField>
|
||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="12">
|
||||
<rect key="frame" x="158" y="184" width="136" height="14"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Missmatching Passwords" id="14">
|
||||
<rect key="frame" x="161" y="176" width="131" height="14"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Mismatching Passwords" id="14">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" red="1" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -138,7 +138,7 @@ Gw
|
||||
</connections>
|
||||
</button>
|
||||
<button horizontalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="yKc-I9-uzv">
|
||||
<rect key="frame" x="18" y="155" width="84" height="18"/>
|
||||
<rect key="frame" x="18" y="150" width="84" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="Password:" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="OQz-DA-SoY">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
@@ -189,7 +189,7 @@ Gw
|
||||
<constraint firstItem="6" firstAttribute="leading" secondItem="9" secondAttribute="leading" id="zeJ-6i-fY3"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<point key="canvasLocation" x="-312" y="-21"/>
|
||||
<point key="canvasLocation" x="-8" y="-14"/>
|
||||
</window>
|
||||
</objects>
|
||||
<resources>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15705" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14460.31"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15705"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
@@ -10,6 +10,7 @@
|
||||
<connections>
|
||||
<outlet property="cancelButton" destination="2pb-ZG-spA" id="YrR-Yi-dnQ"/>
|
||||
<outlet property="enablePasswordCheckBox" destination="d8O-Ha-rrS" id="2AI-e9-sph"/>
|
||||
<outlet property="keyFileWarningTextField" destination="txI-yI-5nE" id="WhF-O8-fsZ"/>
|
||||
<outlet property="keyPathControl" destination="241" id="261"/>
|
||||
<outlet property="messageImageView" destination="262" id="726-wK-c2h"/>
|
||||
<outlet property="messageInfoTextField" destination="268" id="ahE-sq-QzR"/>
|
||||
@@ -22,10 +23,10 @@
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<customView horizontalCompressionResistancePriority="751" translatesAutoresizingMaskIntoConstraints="NO" id="1">
|
||||
<rect key="frame" x="0.0" y="0.0" width="508" height="392"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="508" height="526"/>
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="2">
|
||||
<rect key="frame" x="310" y="105" width="83" height="32"/>
|
||||
<rect key="frame" x="310" y="168" width="83" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="Unlock" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="3">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
@@ -38,7 +39,7 @@ DQ
|
||||
</connections>
|
||||
</button>
|
||||
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="17">
|
||||
<rect key="frame" x="108" y="157" width="45" height="17"/>
|
||||
<rect key="frame" x="108" y="226" width="45" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Keyfile" id="18">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -46,13 +47,13 @@ DQ
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<pathControl verticalHuggingPriority="750" allowsExpansionToolTips="YES" translatesAutoresizingMaskIntoConstraints="NO" id="241" customClass="MPPathControl">
|
||||
<rect key="frame" x="156" y="153" width="197" height="25"/>
|
||||
<pathCell key="cell" selectable="YES" editable="YES" alignment="left" pathStyle="popUp" id="242">
|
||||
<rect key="frame" x="156" y="222" width="197" height="25"/>
|
||||
<pathCell key="cell" selectable="YES" editable="YES" alignment="left" pathStyle="popUp" id="242" customClass="MPPathCell">
|
||||
<font key="font" metaFont="system"/>
|
||||
</pathCell>
|
||||
</pathControl>
|
||||
<imageView translatesAutoresizingMaskIntoConstraints="NO" id="262">
|
||||
<rect key="frame" x="230" y="241" width="48" height="48"/>
|
||||
<rect key="frame" x="230" y="305" width="48" height="48"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="48" id="273"/>
|
||||
<constraint firstAttribute="width" constant="48" id="456"/>
|
||||
@@ -60,7 +61,7 @@ DQ
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" image="02_MessageBoxWarningTemplate" id="263"/>
|
||||
</imageView>
|
||||
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="268">
|
||||
<rect key="frame" x="199" y="216" width="110" height="17"/>
|
||||
<rect key="frame" x="199" y="281" width="110" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Wrong password!" id="269">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -68,7 +69,7 @@ DQ
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<secureTextField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="338" customClass="HNHUISecureTextField">
|
||||
<rect key="frame" x="159" y="184" width="191" height="24"/>
|
||||
<rect key="frame" x="159" y="253" width="191" height="20"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="191" id="389"/>
|
||||
</constraints>
|
||||
@@ -85,14 +86,14 @@ DQ
|
||||
</connections>
|
||||
</secureTextField>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="408">
|
||||
<rect key="frame" x="358" y="185" width="29" height="23"/>
|
||||
<rect key="frame" x="358" y="250" width="29" height="23"/>
|
||||
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="NSQuickLookTemplate" imagePosition="only" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="409">
|
||||
<behavior key="behavior" pushIn="YES" changeContents="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="486">
|
||||
<rect key="frame" x="358" y="152" width="29" height="23"/>
|
||||
<rect key="frame" x="358" y="220" width="29" height="23"/>
|
||||
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="NSStopProgressTemplate" imagePosition="only" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="487">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
@@ -102,14 +103,14 @@ DQ
|
||||
</connections>
|
||||
</button>
|
||||
<button translatesAutoresizingMaskIntoConstraints="NO" id="d8O-Ha-rrS">
|
||||
<rect key="frame" x="72" y="187" width="81" height="18"/>
|
||||
<rect key="frame" x="72" y="254" width="81" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="Password" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="IU9-5u-jn9">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="2pb-ZG-spA">
|
||||
<rect key="frame" x="228" y="105" width="82" height="32"/>
|
||||
<rect key="frame" x="228" y="168" width="82" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="erj-mR-UyO">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
@@ -121,6 +122,14 @@ Gw
|
||||
<action selector="_submit:" target="-2" id="aVF-1d-1Hq"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField hidden="YES" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="txI-yI-5nE">
|
||||
<rect key="frame" x="157" y="204" width="195" height="14"/>
|
||||
<textFieldCell key="cell" selectable="YES" title="key_file_warnig" id="f6J-5f-ZvP">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="2" secondAttribute="bottom" constant="20" symbolic="YES" id="122"/>
|
||||
@@ -144,15 +153,18 @@ Gw
|
||||
<constraint firstItem="2" firstAttribute="trailing" secondItem="486" secondAttribute="trailing" id="496"/>
|
||||
<constraint firstItem="408" firstAttribute="leading" secondItem="338" secondAttribute="trailing" constant="8" symbolic="YES" id="7qE-8F-QgB"/>
|
||||
<constraint firstItem="2pb-ZG-spA" firstAttribute="baseline" secondItem="2" secondAttribute="baseline" id="9nK-MH-Ozs"/>
|
||||
<constraint firstItem="txI-yI-5nE" firstAttribute="trailing" secondItem="241" secondAttribute="trailing" id="AVL-HO-SMq"/>
|
||||
<constraint firstItem="17" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="1" secondAttribute="leading" constant="20" symbolic="YES" id="EOa-K4-v7J"/>
|
||||
<constraint firstItem="338" firstAttribute="leading" secondItem="d8O-Ha-rrS" secondAttribute="trailing" constant="8" symbolic="YES" id="KYs-Ia-SVl"/>
|
||||
<constraint firstItem="2pb-ZG-spA" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="1" secondAttribute="leading" constant="20" symbolic="YES" id="SUS-76-os4"/>
|
||||
<constraint firstItem="2" firstAttribute="top" secondItem="txI-yI-5nE" secondAttribute="bottom" constant="8" symbolic="YES" id="jJs-hc-O2O"/>
|
||||
<constraint firstItem="d8O-Ha-rrS" firstAttribute="centerY" secondItem="338" secondAttribute="centerY" id="kgB-jV-OGy"/>
|
||||
<constraint firstItem="2" firstAttribute="top" secondItem="486" secondAttribute="bottom" constant="20" symbolic="YES" id="v1K-wm-EeB"/>
|
||||
<constraint firstItem="txI-yI-5nE" firstAttribute="top" secondItem="241" secondAttribute="bottom" constant="8" symbolic="YES" id="lfg-eB-T2O"/>
|
||||
<constraint firstItem="txI-yI-5nE" firstAttribute="leading" secondItem="241" secondAttribute="leading" id="nGY-6Q-Vwy"/>
|
||||
<constraint firstItem="d8O-Ha-rrS" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="1" secondAttribute="leading" constant="20" symbolic="YES" id="vxq-YP-UhR"/>
|
||||
<constraint firstItem="2" firstAttribute="leading" secondItem="2pb-ZG-spA" secondAttribute="trailing" constant="12" id="ytJ-5Z-5rT"/>
|
||||
</constraints>
|
||||
<point key="canvasLocation" x="-217" y="-96"/>
|
||||
<point key="canvasLocation" x="-127" y="-46"/>
|
||||
</customView>
|
||||
</objects>
|
||||
<resources>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14313.18" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14313.18"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
@@ -31,6 +31,9 @@
|
||||
<buttonCell key="cell" type="push" title="Select" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="6Wi-9i-Tcb">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<string key="keyEquivalent" base64-UTF8="YES">
|
||||
DQ
|
||||
</string>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="pickField:" target="-2" id="fLO-qW-oC9"/>
|
||||
@@ -121,11 +124,11 @@
|
||||
</tableView>
|
||||
</subviews>
|
||||
</clipView>
|
||||
<scroller key="horizontalScroller" verticalHuggingPriority="750" horizontal="YES" id="RHy-ph-0lP">
|
||||
<scroller key="horizontalScroller" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="RHy-ph-0lP">
|
||||
<rect key="frame" x="1" y="255" width="432" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="b5D-WW-IPI">
|
||||
<scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="b5D-WW-IPI">
|
||||
<rect key="frame" x="224" y="17" width="15" height="102"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15705" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14460.31"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15705"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="MPPluginPreferencesController">
|
||||
<connections>
|
||||
<outlet property="addRemovePluginsControl" destination="B9Q-hq-K4N" id="Oqj-Ko-8UR"/>
|
||||
<outlet property="allowRemoteConnectionCheckButton" destination="K0z-aD-K2P" id="VDW-fd-evK"/>
|
||||
<outlet property="fallbackDescriptionTextField" destination="qPL-FR-ky7" id="xCb-ED-NIX"/>
|
||||
<outlet property="fallbackSettingsView" destination="wIk-iw-Tcz" id="dHl-zW-0aI"/>
|
||||
<outlet property="forceIncompatiblePluginsCheckButton" destination="XIl-03-JZP" id="Aj4-rc-Ao0"/>
|
||||
@@ -21,19 +22,19 @@
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<customView translatesAutoresizingMaskIntoConstraints="NO" id="Hz6-mo-xeY">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="473"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="607" height="502"/>
|
||||
<subviews>
|
||||
<box borderType="line" title="Box" titlePosition="noTitle" translatesAutoresizingMaskIntoConstraints="NO" id="vBs-Ga-aq0">
|
||||
<rect key="frame" x="175" y="46" width="408" height="321"/>
|
||||
<rect key="frame" x="175" y="46" width="415" height="306"/>
|
||||
<view key="contentView" id="tD5-Na-7XI">
|
||||
<rect key="frame" x="3" y="3" width="402" height="315"/>
|
||||
<rect key="frame" x="3" y="3" width="409" height="300"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<customView translatesAutoresizingMaskIntoConstraints="NO" id="wIk-iw-Tcz">
|
||||
<rect key="frame" x="20" y="20" width="362" height="275"/>
|
||||
<rect key="frame" x="20" y="20" width="369" height="260"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="qPL-FR-ky7">
|
||||
<rect key="frame" x="18" y="238" width="326" height="17"/>
|
||||
<rect key="frame" x="18" y="224" width="333" height="16"/>
|
||||
<textFieldCell key="cell" controlSize="mini" sendsActionOnEndEditing="YES" title="Plugin Settings Info" id="OOr-SW-jZb">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -58,14 +59,14 @@
|
||||
</view>
|
||||
</box>
|
||||
<button translatesAutoresizingMaskIntoConstraints="NO" id="CqP-oK-S8k">
|
||||
<rect key="frame" x="18" y="437" width="159" height="18"/>
|
||||
<rect key="frame" x="18" y="422" width="159" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="Load unsecure Plugins" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="C4B-6z-ZqX">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="aoG-FD-ds8">
|
||||
<rect key="frame" x="18" y="403" width="564" height="28"/>
|
||||
<rect key="frame" x="18" y="388" width="571" height="28"/>
|
||||
<textFieldCell key="cell" controlSize="small" sendsActionOnEndEditing="YES" id="2bX-8S-9XM">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<string key="title">If enabled, Plugins without proper signatures will be allowed to load. Keep in mind, that Plugins have full access to your data! Changes take affect on restart.</string>
|
||||
@@ -74,13 +75,13 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<scrollView autohidesScrollers="YES" horizontalLineScroll="37" horizontalPageScroll="10" verticalLineScroll="37" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fCk-fL-jU8">
|
||||
<rect key="frame" x="20" y="50" width="150" height="315"/>
|
||||
<rect key="frame" x="20" y="50" width="150" height="300"/>
|
||||
<clipView key="contentView" id="lTL-Q2-k45">
|
||||
<rect key="frame" x="1" y="1" width="148" height="313"/>
|
||||
<rect key="frame" x="1" y="1" width="148" height="298"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnSelection="YES" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="35" rowSizeStyle="automatic" viewBased="YES" id="Ocu-C0-03d">
|
||||
<rect key="frame" x="0.0" y="0.0" width="148" height="313"/>
|
||||
<tableView verticalHuggingPriority="750" ambiguous="YES" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnSelection="YES" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="35" usesAutomaticRowHeights="YES" viewBased="YES" id="Ocu-C0-03d">
|
||||
<rect key="frame" x="0.0" y="0.0" width="148" height="298"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<size key="intercellSpacing" width="3" height="2"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -99,12 +100,12 @@
|
||||
</textFieldCell>
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
<prototypeCellViews>
|
||||
<tableCellView id="vVt-P3-yLp" customClass="MPPluginTabelCellView">
|
||||
<tableCellView misplaced="YES" id="vVt-P3-yLp" customClass="MPExtendedTableCellView">
|
||||
<rect key="frame" x="1" y="1" width="145" height="35"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="q1P-PD-0LW">
|
||||
<rect key="frame" x="0.0" y="18" width="127" height="17"/>
|
||||
<rect key="frame" x="0.0" y="18" width="145" height="16"/>
|
||||
<textFieldCell key="cell" sendsActionOnEndEditing="YES" title="Table View Cell" id="fug-79-n9g">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -125,7 +126,7 @@
|
||||
<constraint firstAttribute="trailing" secondItem="fQy-Sz-4VA" secondAttribute="trailing" constant="2" id="Iy0-iV-Mbx"/>
|
||||
<constraint firstItem="fQy-Sz-4VA" firstAttribute="top" secondItem="q1P-PD-0LW" secondAttribute="bottom" constant="2" id="RZb-58-Zwr"/>
|
||||
<constraint firstItem="q1P-PD-0LW" firstAttribute="leading" secondItem="vVt-P3-yLp" secondAttribute="leading" constant="2" id="bTc-2c-BYB"/>
|
||||
<constraint firstAttribute="trailing" secondItem="q1P-PD-0LW" secondAttribute="trailing" constant="20" symbolic="YES" id="gSi-vN-xzX"/>
|
||||
<constraint firstAttribute="trailing" secondItem="q1P-PD-0LW" secondAttribute="trailing" constant="2" id="gSi-vN-xzX"/>
|
||||
<constraint firstItem="q1P-PD-0LW" firstAttribute="top" secondItem="vVt-P3-yLp" secondAttribute="top" id="tTs-2E-33f"/>
|
||||
<constraint firstItem="fQy-Sz-4VA" firstAttribute="leading" secondItem="vVt-P3-yLp" secondAttribute="leading" constant="2" id="zLP-Ci-nUM"/>
|
||||
</constraints>
|
||||
@@ -154,7 +155,7 @@
|
||||
</scroller>
|
||||
</scrollView>
|
||||
<segmentedControl verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="B9Q-hq-K4N">
|
||||
<rect key="frame" x="20" y="19" width="71" height="23"/>
|
||||
<rect key="frame" x="19.5" y="19" width="71" height="23"/>
|
||||
<segmentedCell key="cell" borderStyle="border" alignment="left" style="texturedSquare" trackingMode="momentary" id="cj3-R6-g1E">
|
||||
<font key="font" metaFont="system"/>
|
||||
<segments>
|
||||
@@ -167,7 +168,7 @@
|
||||
</connections>
|
||||
</segmentedControl>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="SNe-cc-CZs">
|
||||
<rect key="frame" x="406" y="19" width="174" height="23"/>
|
||||
<rect key="frame" x="413.5" y="19" width="174" height="23"/>
|
||||
<buttonCell key="cell" type="roundTextured" title="Browse Available Plugins…" bezelStyle="texturedRounded" alignment="center" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="sqO-8H-n1y">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
@@ -177,30 +178,51 @@
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="XIl-03-JZP">
|
||||
<rect key="frame" x="18" y="371" width="250" height="18"/>
|
||||
<rect key="frame" x="18" y="356" width="250" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="Force loading of incompatible Plugins" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="yak-fS-jtA">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="K0z-aD-K2P">
|
||||
<rect key="frame" x="18" y="466" width="243" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="Download current Plugin information" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="uHR-uL-Ddm">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="nrf-Hz-0vB">
|
||||
<rect key="frame" x="18" y="446" width="349" height="14"/>
|
||||
<textFieldCell key="cell" controlSize="small" selectable="YES" title="If enabled, a remote connection is established to macpassapp.org" id="i3S-9b-Bpf">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="CqP-oK-S8k" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="20" id="1Rj-zS-7t2"/>
|
||||
<constraint firstItem="CqP-oK-S8k" firstAttribute="top" secondItem="nrf-Hz-0vB" secondAttribute="bottom" constant="8" symbolic="YES" id="1Rj-zS-7t2"/>
|
||||
<constraint firstItem="XIl-03-JZP" firstAttribute="top" secondItem="aoG-FD-ds8" secondAttribute="bottom" constant="16" id="2Wk-4D-AHu"/>
|
||||
<constraint firstItem="vBs-Ga-aq0" firstAttribute="top" secondItem="fCk-fL-jU8" secondAttribute="top" id="2h6-C9-4N5"/>
|
||||
<constraint firstItem="nrf-Hz-0vB" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" symbolic="YES" id="2hE-FW-30g"/>
|
||||
<constraint firstItem="B9Q-hq-K4N" firstAttribute="top" secondItem="fCk-fL-jU8" secondAttribute="bottom" constant="8" symbolic="YES" id="3vA-Oh-cFO"/>
|
||||
<constraint firstAttribute="bottom" secondItem="B9Q-hq-K4N" secondAttribute="bottom" constant="20" symbolic="YES" id="7HD-ji-Whc"/>
|
||||
<constraint firstAttribute="trailing" secondItem="SNe-cc-CZs" secondAttribute="trailing" constant="20" symbolic="YES" id="8Je-yg-f1l"/>
|
||||
<constraint firstAttribute="trailing" secondItem="aoG-FD-ds8" secondAttribute="trailing" constant="20" symbolic="YES" id="95O-Jh-0KG"/>
|
||||
<constraint firstItem="vBs-Ga-aq0" firstAttribute="bottom" secondItem="fCk-fL-jU8" secondAttribute="bottom" id="BQ2-Wp-Fsh"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="K0z-aD-K2P" secondAttribute="trailing" constant="20" symbolic="YES" id="CFf-LD-G7q"/>
|
||||
<constraint firstAttribute="bottom" secondItem="SNe-cc-CZs" secondAttribute="bottom" constant="20" symbolic="YES" id="Fqe-ch-vsS"/>
|
||||
<constraint firstAttribute="trailing" secondItem="vBs-Ga-aq0" secondAttribute="trailing" constant="20" id="LUb-Un-azV"/>
|
||||
<constraint firstItem="aoG-FD-ds8" firstAttribute="leading" secondItem="CqP-oK-S8k" secondAttribute="leading" id="NcW-ya-DPx"/>
|
||||
<constraint firstItem="B9Q-hq-K4N" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" symbolic="YES" id="Rtj-Ad-zkg"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="CqP-oK-S8k" secondAttribute="trailing" constant="20" symbolic="YES" id="TXL-mf-nxu"/>
|
||||
<constraint firstItem="K0z-aD-K2P" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" symbolic="YES" id="XzM-3L-OgP"/>
|
||||
<constraint firstItem="SNe-cc-CZs" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="B9Q-hq-K4N" secondAttribute="trailing" constant="8" symbolic="YES" id="a62-en-kDA"/>
|
||||
<constraint firstItem="fCk-fL-jU8" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="fzW-4b-L8S"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="nrf-Hz-0vB" secondAttribute="trailing" constant="20" symbolic="YES" id="hMs-HE-d8h"/>
|
||||
<constraint firstItem="nrf-Hz-0vB" firstAttribute="top" secondItem="K0z-aD-K2P" secondAttribute="bottom" constant="8" symbolic="YES" id="ohE-9y-xO4"/>
|
||||
<constraint firstItem="XIl-03-JZP" firstAttribute="leading" secondItem="CqP-oK-S8k" secondAttribute="leading" id="oqX-wa-jm0"/>
|
||||
<constraint firstItem="K0z-aD-K2P" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="20" symbolic="YES" id="q4N-Jc-F3L"/>
|
||||
<constraint firstItem="SNe-cc-CZs" firstAttribute="top" secondItem="vBs-Ga-aq0" secondAttribute="bottom" constant="8" symbolic="YES" id="r4X-iM-iYU"/>
|
||||
<constraint firstItem="CqP-oK-S8k" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="rN1-3Z-BBi"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="XIl-03-JZP" secondAttribute="trailing" constant="20" symbolic="YES" id="rkN-ew-RtP"/>
|
||||
@@ -208,7 +230,7 @@
|
||||
<constraint firstItem="vBs-Ga-aq0" firstAttribute="leading" secondItem="fCk-fL-jU8" secondAttribute="trailing" constant="8" id="xNu-Sj-xQO"/>
|
||||
<constraint firstItem="aoG-FD-ds8" firstAttribute="top" secondItem="CqP-oK-S8k" secondAttribute="bottom" constant="8" symbolic="YES" id="zSW-h3-BrT"/>
|
||||
</constraints>
|
||||
<point key="canvasLocation" x="110" y="-97"/>
|
||||
<point key="canvasLocation" x="179" y="115"/>
|
||||
</customView>
|
||||
</objects>
|
||||
<resources>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14460.31"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
@@ -228,7 +228,7 @@
|
||||
<constraint firstItem="bGv-Zc-Vrk" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="tk3-kF-k22"/>
|
||||
<constraint firstItem="d2Q-7O-ilP" firstAttribute="leading" secondItem="fjQ-ni-Ayx" secondAttribute="trailing" constant="8" symbolic="YES" id="wHQ-Lk-2fv"/>
|
||||
</constraints>
|
||||
<point key="canvasLocation" x="-130" y="-66"/>
|
||||
<point key="canvasLocation" x="193" y="-18"/>
|
||||
</customView>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14313.18" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15702" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14313.18"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15702"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
@@ -18,11 +18,11 @@
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<customView id="c22-O7-iKe">
|
||||
<rect key="frame" x="0.0" y="0.0" width="205" height="215"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="207" height="213"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="IZP-Gd-jdU">
|
||||
<rect key="frame" x="13" y="152" width="82" height="25"/>
|
||||
<rect key="frame" x="13" y="151" width="83" height="23"/>
|
||||
<popUpButtonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" alignment="center" lineBreakMode="truncatingTail" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="KPf-xE-gde">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
@@ -37,7 +37,7 @@
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="IFf-vC-3vk" customClass="HNHUITextField">
|
||||
<rect key="frame" x="13" y="102" width="172" height="22"/>
|
||||
<rect key="frame" x="13" y="101" width="174" height="21"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="100" id="Seu-01-P53"/>
|
||||
</constraints>
|
||||
@@ -48,14 +48,14 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="T2o-aJ-JmD">
|
||||
<rect key="frame" x="147" y="18" width="38" height="25"/>
|
||||
<rect key="frame" x="149" y="19" width="38" height="23"/>
|
||||
<buttonCell key="cell" type="roundTextured" title="Use" bezelStyle="texturedRounded" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Kqx-qm-nMG">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="VR5-Rx-ueN">
|
||||
<rect key="frame" x="101" y="184" width="24" height="14"/>
|
||||
<rect key="frame" x="102" y="182" width="24" height="14"/>
|
||||
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Key" id="K1t-OZ-ACe">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -63,7 +63,7 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="sZo-ie-Asw">
|
||||
<rect key="frame" x="11" y="184" width="58" height="14"/>
|
||||
<rect key="frame" x="11" y="182" width="58" height="14"/>
|
||||
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Reference" id="r1V-VE-ngy">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -71,10 +71,10 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<popUpButton horizontalHuggingPriority="249" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="b4e-k2-WPS">
|
||||
<rect key="frame" x="103" y="152" width="82" height="25"/>
|
||||
<rect key="frame" x="104" y="151" width="83" height="23"/>
|
||||
<popUpButtonCell key="cell" type="roundTextured" title="Matching" bezelStyle="texturedRounded" alignment="center" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" selectedItem="yT1-XL-k6a" id="Aob-tW-bUP">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<menu key="menu" id="j2A-qj-k7L">
|
||||
<items>
|
||||
<menuItem title="Matching" state="on" id="yT1-XL-k6a">
|
||||
@@ -88,7 +88,7 @@
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="WTJ-he-uTu">
|
||||
<rect key="frame" x="11" y="132" width="37" height="14"/>
|
||||
<rect key="frame" x="11" y="130" width="37" height="14"/>
|
||||
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Match" id="9ce-da-syF">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -96,7 +96,7 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="mcC-bG-cCz">
|
||||
<rect key="frame" x="11" y="80" width="92" height="14"/>
|
||||
<rect key="frame" x="11" y="79" width="92" height="14"/>
|
||||
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Reference String" id="gik-Ha-hRd">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -104,7 +104,7 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="b36-T7-1tO" customClass="HNHUITextField">
|
||||
<rect key="frame" x="13" y="50" width="172" height="22"/>
|
||||
<rect key="frame" x="13" y="50" width="174" height="21"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" placeholderString="Reference" drawsBackground="YES" id="dr9-x8-kKk">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="10117" systemVersion="15G31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15702" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15702"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="MPUpdateSettingsController">
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="MPUpdatePreferencesController">
|
||||
<connections>
|
||||
<outlet property="automaticallyCheckForUpdatesCheckButton" destination="Z6x-oU-NC5" id="xHU-Lt-PmA"/>
|
||||
<outlet property="checkIntervallPopupButton" destination="pWJ-eJ-MBf" id="znu-Me-2Me"/>
|
||||
@@ -17,8 +18,8 @@
|
||||
<customView translatesAutoresizingMaskIntoConstraints="NO" id="1">
|
||||
<rect key="frame" x="0.0" y="0.0" width="400" height="95"/>
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="500" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Z6x-oU-NC5">
|
||||
<rect key="frame" x="21" y="59" width="228" height="18"/>
|
||||
<button verticalHuggingPriority="500" translatesAutoresizingMaskIntoConstraints="NO" id="Z6x-oU-NC5">
|
||||
<rect key="frame" x="22" y="59" width="221" height="18"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="14" id="ppB-Ka-SVN"/>
|
||||
</constraints>
|
||||
@@ -27,11 +28,11 @@
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<popUpButton verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="pWJ-eJ-MBf">
|
||||
<rect key="frame" x="145" y="17" width="112" height="26"/>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="pWJ-eJ-MBf">
|
||||
<rect key="frame" x="144" y="17" width="114" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="Hl5-gO-B1c">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<menu key="menu" title="OtherViews" id="RKd-H8-eCF">
|
||||
<items>
|
||||
<menuItem title="every Hour" tag="3600" id="DjF-1I-6Nq"/>
|
||||
@@ -44,8 +45,8 @@
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ckg-9t-MDS">
|
||||
<rect key="frame" x="21" y="23" width="120" height="17"/>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ckg-9t-MDS">
|
||||
<rect key="frame" x="22" y="23" width="118" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Check for Updates" id="9tL-CA-Vdg">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -61,10 +62,11 @@
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="pWJ-eJ-MBf" secondAttribute="trailing" constant="20" symbolic="YES" id="QsU-uT-lfo"/>
|
||||
<constraint firstItem="ckg-9t-MDS" firstAttribute="leading" secondItem="Z6x-oU-NC5" secondAttribute="leading" id="W0y-Rp-Ucq"/>
|
||||
<constraint firstItem="pWJ-eJ-MBf" firstAttribute="top" secondItem="Z6x-oU-NC5" secondAttribute="bottom" constant="20" symbolic="YES" id="fhM-Ri-Op9"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="Z6x-oU-NC5" secondAttribute="trailing" constant="20" symbolic="YES" id="mpe-6b-p3W"/>
|
||||
<constraint firstItem="ckg-9t-MDS" firstAttribute="baseline" secondItem="pWJ-eJ-MBf" secondAttribute="baseline" id="ozZ-bW-f7y"/>
|
||||
<constraint firstAttribute="bottom" secondItem="pWJ-eJ-MBf" secondAttribute="bottom" constant="20" symbolic="YES" id="pHW-e8-EU6"/>
|
||||
</constraints>
|
||||
<point key="canvasLocation" x="504" y="511.5"/>
|
||||
<point key="canvasLocation" x="21" y="2"/>
|
||||
</customView>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14460.31"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
@@ -187,7 +187,7 @@
|
||||
<constraint firstItem="ITj-5P-sn9" firstAttribute="leading" secondItem="9Nv-Zl-Z9p" secondAttribute="leading" constant="20" id="oWL-PJ-VCT"/>
|
||||
<constraint firstAttribute="bottom" secondItem="ITj-5P-sn9" secondAttribute="bottom" id="syW-TO-uwv"/>
|
||||
</constraints>
|
||||
<point key="canvasLocation" x="-378" y="-552"/>
|
||||
<point key="canvasLocation" x="-680" y="-522"/>
|
||||
</view>
|
||||
</objects>
|
||||
<resources>
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="10117" systemVersion="15G31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15702" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/>
|
||||
<capability name="box content view" minToolsVersion="7.0"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15702"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="MPWorkflowSettingsController">
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="MPWorkflowPreferencesController">
|
||||
<connections>
|
||||
<outlet property="browserPopup" destination="ehI-gq-lsb" id="YMy-L1-pQw"/>
|
||||
<outlet property="doubleClickTitlePopup" destination="40" id="aKJ-q9-xjb"/>
|
||||
<outlet property="doubleClickURLPopup" destination="13" id="fGP-5I-0XK"/>
|
||||
<outlet property="hideAfterCopyToClipboardCheckButton" destination="vT4-wF-ned" id="d7e-vc-cAQ"/>
|
||||
<outlet property="updatePasswordOnTemplateEntriesCheckButton" destination="LPY-sM-hjS" id="wav-op-uck"/>
|
||||
<outlet property="view" destination="1" id="52"/>
|
||||
</connections>
|
||||
@@ -18,16 +19,16 @@
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<customView translatesAutoresizingMaskIntoConstraints="NO" id="1">
|
||||
<rect key="frame" x="0.0" y="0.0" width="400" height="231"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="400" height="314"/>
|
||||
<subviews>
|
||||
<box autoresizesSubviews="NO" verticalHuggingPriority="500" title="Entry Table" borderType="line" translatesAutoresizingMaskIntoConstraints="NO" id="2">
|
||||
<rect key="frame" x="17" y="90" width="366" height="92"/>
|
||||
<box autoresizesSubviews="NO" verticalHuggingPriority="500" borderType="line" title="Entry Table" translatesAutoresizingMaskIntoConstraints="NO" id="2">
|
||||
<rect key="frame" x="17" y="166" width="366" height="99"/>
|
||||
<view key="contentView" id="cfa-nq-Kzt">
|
||||
<rect key="frame" x="1" y="1" width="364" height="76"/>
|
||||
<rect key="frame" x="3" y="3" width="360" height="81"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="9">
|
||||
<rect key="frame" x="17" y="47" width="133" height="17"/>
|
||||
<rect key="frame" x="18" y="53" width="134" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Double-click on URL:" id="10">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -35,10 +36,10 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="13">
|
||||
<rect key="frame" x="154" y="42" width="108" height="26"/>
|
||||
<rect key="frame" x="156" y="47" width="109" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="14">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<menu key="menu" title="OtherViews" id="15">
|
||||
<items>
|
||||
<menuItem title="Copies URL" id="16"/>
|
||||
@@ -48,7 +49,7 @@
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="36">
|
||||
<rect key="frame" x="16" y="16" width="134" height="17"/>
|
||||
<rect key="frame" x="18" y="22" width="134" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" enabled="NO" sendsActionOnEndEditing="YES" title="Double-click on Title:" id="37">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -56,10 +57,10 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="40">
|
||||
<rect key="frame" x="154" y="11" width="138" height="26"/>
|
||||
<rect key="frame" x="156" y="17" width="139" height="24"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Opens Inspector" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="44" id="41">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<menu key="menu" title="OtherViews" id="42">
|
||||
<items>
|
||||
<menuItem title="Opens Inspector" state="on" id="44"/>
|
||||
@@ -69,27 +70,30 @@
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="40" secondAttribute="trailing" constant="20" symbolic="YES" id="3iK-WD-tbs"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="13" secondAttribute="trailing" constant="20" symbolic="YES" id="EQn-DK-viK"/>
|
||||
<constraint firstItem="9" firstAttribute="leading" secondItem="cfa-nq-Kzt" secondAttribute="leading" constant="20" symbolic="YES" id="FHR-zo-tjR"/>
|
||||
<constraint firstItem="9" firstAttribute="firstBaseline" secondItem="13" secondAttribute="firstBaseline" id="Swb-ay-7G0"/>
|
||||
<constraint firstItem="36" firstAttribute="firstBaseline" secondItem="40" secondAttribute="firstBaseline" id="dWh-SS-Sc4"/>
|
||||
<constraint firstItem="36" firstAttribute="leading" secondItem="cfa-nq-Kzt" secondAttribute="leading" constant="20" symbolic="YES" id="eqy-R2-mpP"/>
|
||||
<constraint firstAttribute="bottom" secondItem="40" secondAttribute="bottom" constant="20" symbolic="YES" id="lle-u8-JWP"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<constraints>
|
||||
<constraint firstItem="13" firstAttribute="leading" secondItem="9" secondAttribute="trailing" constant="8" symbolic="YES" id="1WE-nm-pp2"/>
|
||||
<constraint firstItem="40" firstAttribute="centerY" secondItem="36" secondAttribute="centerY" id="1hi-oU-uNn"/>
|
||||
<constraint firstItem="36" firstAttribute="leading" secondItem="2" secondAttribute="leading" constant="16" id="MEC-5G-cdx"/>
|
||||
<constraint firstItem="13" firstAttribute="top" secondItem="2" secondAttribute="top" constant="25" id="Nd9-4H-y8b"/>
|
||||
<constraint firstAttribute="bottom" secondItem="40" secondAttribute="bottom" constant="11" id="OcJ-8r-v55"/>
|
||||
<constraint firstItem="36" firstAttribute="centerY" secondItem="40" secondAttribute="centerY" id="Rts-Ze-x1u"/>
|
||||
<constraint firstItem="40" firstAttribute="top" secondItem="13" secondAttribute="bottom" constant="10" symbolic="YES" id="YWX-K2-P8C"/>
|
||||
<constraint firstItem="13" firstAttribute="centerY" secondItem="9" secondAttribute="centerY" id="YqK-Q6-jmb"/>
|
||||
<constraint firstItem="13" firstAttribute="leading" secondItem="40" secondAttribute="leading" id="mih-x6-1K0"/>
|
||||
<constraint firstItem="40" firstAttribute="leading" secondItem="36" secondAttribute="trailing" constant="8" symbolic="YES" id="tsy-wg-saI"/>
|
||||
</constraints>
|
||||
<color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
|
||||
<color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
</box>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ehI-gq-lsb">
|
||||
<rect key="frame" x="115" y="187" width="134" height="26"/>
|
||||
<rect key="frame" x="113" y="270" width="135" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Default Browser" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="7YX-EA-9KA" id="7Ip-sU-sAK">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<menu key="menu" title="OtherViews" id="XgO-Tj-QjO">
|
||||
<items>
|
||||
<menuItem title="Default Browser" state="on" id="7YX-EA-9KA"/>
|
||||
@@ -100,21 +104,21 @@
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="lOo-NI-b07">
|
||||
<rect key="frame" x="20" y="190" width="91" height="21"/>
|
||||
<rect key="frame" x="18" y="273" width="91" height="19"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" enabled="NO" sendsActionOnEndEditing="YES" title="Open URLs in:" id="soD-wI-YOH">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<box title="Templates" borderType="line" translatesAutoresizingMaskIntoConstraints="NO" id="Xvt-tP-TbR">
|
||||
<rect key="frame" x="17" y="16" width="366" height="70"/>
|
||||
<box borderType="line" title="Templates" translatesAutoresizingMaskIntoConstraints="NO" id="Xvt-tP-TbR">
|
||||
<rect key="frame" x="17" y="92" width="366" height="72"/>
|
||||
<view key="contentView" id="g0i-00-sng">
|
||||
<rect key="frame" x="1" y="1" width="364" height="54"/>
|
||||
<rect key="frame" x="3" y="3" width="360" height="54"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="LPY-sM-hjS">
|
||||
<rect key="frame" x="18" y="18" width="328" height="18"/>
|
||||
<rect key="frame" x="18" y="18" width="222" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="Update password for new entries" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="RaM-t2-DVR">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
@@ -125,31 +129,53 @@
|
||||
<constraint firstItem="LPY-sM-hjS" firstAttribute="top" secondItem="g0i-00-sng" secondAttribute="top" constant="20" symbolic="YES" id="Ip3-vX-0L9"/>
|
||||
<constraint firstItem="LPY-sM-hjS" firstAttribute="leading" secondItem="g0i-00-sng" secondAttribute="leading" constant="20" symbolic="YES" id="RE9-Jf-nFR"/>
|
||||
<constraint firstAttribute="bottom" secondItem="LPY-sM-hjS" secondAttribute="bottom" constant="20" symbolic="YES" id="nGd-XA-Jj9"/>
|
||||
<constraint firstAttribute="trailing" secondItem="LPY-sM-hjS" secondAttribute="trailing" constant="20" symbolic="YES" id="wyU-eZ-BSC"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="LPY-sM-hjS" secondAttribute="trailing" constant="20" symbolic="YES" id="wyU-eZ-BSC"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</box>
|
||||
<box title="Clipboard" translatesAutoresizingMaskIntoConstraints="NO" id="Kff-Xp-hAT">
|
||||
<rect key="frame" x="17" y="16" width="366" height="72"/>
|
||||
<view key="contentView" id="Ntf-zj-VZL">
|
||||
<rect key="frame" x="3" y="3" width="360" height="54"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="vT4-wF-ned">
|
||||
<rect key="frame" x="18" y="18" width="280" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="Hide application after copying to clipboard" bezelStyle="regularSquare" imagePosition="left" inset="2" id="1Vr-nY-Ogv">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="vT4-wF-ned" firstAttribute="leading" secondItem="Ntf-zj-VZL" secondAttribute="leading" constant="20" symbolic="YES" id="3ck-ZU-EY0"/>
|
||||
<constraint firstAttribute="bottom" secondItem="vT4-wF-ned" secondAttribute="bottom" constant="20" symbolic="YES" id="coG-iy-hF8"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="vT4-wF-ned" secondAttribute="trailing" constant="20" symbolic="YES" id="grJ-mW-4AM"/>
|
||||
<constraint firstItem="vT4-wF-ned" firstAttribute="top" secondItem="Ntf-zj-VZL" secondAttribute="top" constant="20" symbolic="YES" id="ibE-Gy-bR6"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
|
||||
<color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
</box>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="2" firstAttribute="leading" secondItem="1" secondAttribute="leading" constant="20" symbolic="YES" id="5"/>
|
||||
<constraint firstAttribute="trailing" secondItem="2" secondAttribute="trailing" constant="20" symbolic="YES" id="8"/>
|
||||
<constraint firstAttribute="width" constant="400" id="53"/>
|
||||
<constraint firstItem="Xvt-tP-TbR" firstAttribute="leading" secondItem="1" secondAttribute="leading" constant="20" id="BH4-4y-uma"/>
|
||||
<constraint firstItem="Kff-Xp-hAT" firstAttribute="top" secondItem="Xvt-tP-TbR" secondAttribute="bottom" constant="8" symbolic="YES" id="3RL-tm-4wu"/>
|
||||
<constraint firstAttribute="bottom" secondItem="Kff-Xp-hAT" secondAttribute="bottom" constant="20" symbolic="YES" id="8k6-1d-wPj"/>
|
||||
<constraint firstItem="Xvt-tP-TbR" firstAttribute="leading" secondItem="1" secondAttribute="leading" constant="20" symbolic="YES" id="BH4-4y-uma"/>
|
||||
<constraint firstItem="2" firstAttribute="top" secondItem="ehI-gq-lsb" secondAttribute="bottom" constant="8" symbolic="YES" id="CnN-aU-Qa1"/>
|
||||
<constraint firstAttribute="bottom" secondItem="Xvt-tP-TbR" secondAttribute="bottom" constant="20" symbolic="YES" id="Dnn-I2-lsA"/>
|
||||
<constraint firstItem="Xvt-tP-TbR" firstAttribute="top" secondItem="cfa-nq-Kzt" secondAttribute="bottom" constant="5" id="FVK-Uf-kLv"/>
|
||||
<constraint firstItem="ehI-gq-lsb" firstAttribute="leading" secondItem="lOo-NI-b07" secondAttribute="trailing" constant="8" symbolic="YES" id="KxB-TG-rH5"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="ehI-gq-lsb" secondAttribute="trailing" constant="20" symbolic="YES" id="Ldw-aO-wuX"/>
|
||||
<constraint firstItem="ehI-gq-lsb" firstAttribute="top" secondItem="1" secondAttribute="top" constant="20" symbolic="YES" id="MAe-l7-8k2"/>
|
||||
<constraint firstItem="lOo-NI-b07" firstAttribute="centerY" secondItem="ehI-gq-lsb" secondAttribute="centerY" id="agv-2Z-m5A"/>
|
||||
<constraint firstAttribute="trailing" secondItem="Kff-Xp-hAT" secondAttribute="trailing" constant="20" symbolic="YES" id="VLC-2A-Vdd"/>
|
||||
<constraint firstItem="Kff-Xp-hAT" firstAttribute="leading" secondItem="1" secondAttribute="leading" constant="20" symbolic="YES" id="Vle-Z0-mh8"/>
|
||||
<constraint firstAttribute="trailing" secondItem="Xvt-tP-TbR" secondAttribute="trailing" constant="20" id="anU-nC-YAw"/>
|
||||
<constraint firstItem="lOo-NI-b07" firstAttribute="leading" secondItem="1" secondAttribute="leading" constant="22" id="kaP-lB-tDY"/>
|
||||
<constraint firstItem="lOo-NI-b07" firstAttribute="top" secondItem="1" secondAttribute="top" constant="20" symbolic="YES" id="tEf-Ag-oTi"/>
|
||||
<constraint firstItem="lOo-NI-b07" firstAttribute="firstBaseline" secondItem="ehI-gq-lsb" secondAttribute="firstBaseline" id="gFK-Ce-Q3b"/>
|
||||
<constraint firstItem="lOo-NI-b07" firstAttribute="leading" secondItem="1" secondAttribute="leading" constant="20" symbolic="YES" id="kaP-lB-tDY"/>
|
||||
<constraint firstItem="2" firstAttribute="top" secondItem="lOo-NI-b07" secondAttribute="bottom" constant="8" symbolic="YES" id="xlS-Dj-cOt"/>
|
||||
</constraints>
|
||||
<point key="canvasLocation" x="435" y="649"/>
|
||||
<point key="canvasLocation" x="-2" y="125"/>
|
||||
</customView>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14460.31"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#import "KPKEntry+MPCustomAttributeProperties.h"
|
||||
#import <objc/runtime.h>
|
||||
|
||||
NSString *const MPCustomAttributePropertyPrefix = @"valueForCustomAttribute";
|
||||
NSString *const MPCustomAttributePropertyPrefix = @"mp_valueForCustomAttribute";
|
||||
|
||||
@implementation KPKEntry (MPCustomAttributeProperties)
|
||||
|
||||
@@ -36,7 +36,7 @@ static id propertyIMP(id self, SEL _cmd) {
|
||||
|
||||
+ (BOOL)resolveInstanceMethod:(SEL)aSEL {
|
||||
if ([NSStringFromSelector(aSEL) hasPrefix:MPCustomAttributePropertyPrefix]) {
|
||||
class_addMethod([self class], aSEL,(IMP)propertyIMP, "@@:");
|
||||
class_addMethod(self.class, aSEL,(IMP)propertyIMP, "@@:");
|
||||
return YES;
|
||||
}
|
||||
return [super resolveInstanceMethod:aSEL];
|
||||
|
||||
22
MacPass/KPKEntry+MPTags.h
Normal file
22
MacPass/KPKEntry+MPTags.h
Normal file
@@ -0,0 +1,22 @@
|
||||
//
|
||||
// KPKEntry+MPTags.h
|
||||
// MacPass
|
||||
//
|
||||
// Created by Michael Starke on 20.03.20.
|
||||
// Copyright © 2020 HicknHack Software GmbH. All rights reserved.
|
||||
//
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
|
||||
#import <KeePassKit/KeePassKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface KPKEntry (MPTags)
|
||||
|
||||
@property (readonly, copy) NSString *tagsString;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
24
MacPass/KPKEntry+MPTags.m
Normal file
24
MacPass/KPKEntry+MPTags.m
Normal file
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// KPKEntry+MPTags.m
|
||||
// MacPass
|
||||
//
|
||||
// Created by Michael Starke on 20.03.20.
|
||||
// Copyright © 2020 HicknHack Software GmbH. All rights reserved.
|
||||
//
|
||||
|
||||
#import "KPKEntry+MPTags.h"
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
|
||||
@implementation KPKEntry (MPTags)
|
||||
|
||||
+ (NSSet<NSString *> *)keyPathsForValuesAffectingTagsString {
|
||||
return [NSSet setWithObject:NSStringFromSelector(@selector(tags))];
|
||||
}
|
||||
|
||||
- (NSString *)tagsString {
|
||||
return [self.tags componentsJoinedByString:@" "];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -28,6 +28,7 @@ typedef NS_ENUM(NSUInteger, MPActionType) {
|
||||
MPActionAddGroup, // Add a new group
|
||||
MPActionDuplicateEntry, // Simply duplicate an entry (including history)
|
||||
MPActionDuplicateEntryWithOptions, // Request user input on what to duplicate
|
||||
MPActionDuplicateGroup, // Duplicate the group and all it's children
|
||||
MPActionReverToHistoryEntry, // Restore an entry to an older state in history
|
||||
MPActionDelete, // Delete entry or group
|
||||
MPActionCopyUsername, // copy username to pasteboard
|
||||
@@ -47,6 +48,7 @@ typedef NS_ENUM(NSUInteger, MPActionType) {
|
||||
MPActionToggleQuicklook,
|
||||
MPActionShowEntryHistory, // show history
|
||||
MPActionHideEntryHistory, // exit history
|
||||
MPActionShowGroupInOutline, // show the group (of the entry) in the outline view
|
||||
MPActionPerformAutotypeForSelectedEntry, // Perform Autotype for selected Entry
|
||||
MPActionRemoveAttachment // Remove an attachment
|
||||
};
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
@(MPActionAddGroup): NSStringFromSelector(@selector(createGroup:)),
|
||||
@(MPActionDuplicateEntry): NSStringFromSelector(@selector(duplicateEntry:)),
|
||||
@(MPActionDuplicateEntryWithOptions): NSStringFromSelector(@selector(duplicateEntryWithOptions:)),
|
||||
@(MPActionDuplicateGroup): NSStringFromSelector(@selector(duplicateGroup:)),
|
||||
@(MPActionReverToHistoryEntry): NSStringFromSelector(@selector(revertToHistoryEntry:)),
|
||||
@(MPActionCopyPassword): NSStringFromSelector(@selector(copyPassword:)),
|
||||
@(MPActionCopyURL): NSStringFromSelector(@selector(copyURL:)),
|
||||
@@ -57,6 +58,7 @@
|
||||
@(MPActionToggleQuicklook): NSStringFromSelector(@selector(toggleQuicklookPreview:)),
|
||||
@(MPActionShowEntryHistory): NSStringFromSelector(@selector(showEntryHistory:)),
|
||||
@(MPActionHideEntryHistory): NSStringFromSelector(@selector(hideEntryHistory:)),
|
||||
@(MPActionShowGroupInOutline): NSStringFromSelector(@selector(showGroupInOutline:)),
|
||||
@(MPActionPerformAutotypeForSelectedEntry): NSStringFromSelector(@selector(performAutotypeForEntry:)),
|
||||
@(MPActionRemoveAttachment): NSStringFromSelector(@selector(removeAttachment:))
|
||||
};
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#import "MPDocument.h"
|
||||
#import "MPDocumentWindowController.h"
|
||||
#import "MPActionHelper.h"
|
||||
#import "KPKNode+IconImage.h"
|
||||
|
||||
#import "KeePassKit/KeePassKit.h"
|
||||
|
||||
@@ -47,6 +48,8 @@
|
||||
NSMenuItem *templateItem = [[NSMenuItem alloc] initWithTitle:[NSString stringWithFormat:templateMask, entry.title]
|
||||
action:@selector(createEntryFromTemplate:)
|
||||
keyEquivalent:@""];
|
||||
templateItem.image = [entry.iconImage copy];
|
||||
templateItem.image.size = NSMakeSize(14, 14);
|
||||
templateItem.representedObject = entry.uuid;
|
||||
[menu addItem:templateItem];
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ APPKIT_EXTERN NSString *const MPDidChangeStoredKeyFilesSettings;
|
||||
@property (strong) IBOutlet NSMenuItem *fileNewMenuItem;
|
||||
@property (strong) IBOutlet NSMenu *itemMenu;
|
||||
@property (strong) IBOutlet NSMenu *importMenu;
|
||||
@property (strong) IBOutlet NSMenu *exportMenu;
|
||||
|
||||
@property (strong, readonly) MPEntryContextMenuDelegate *itemActionMenuDelegate;
|
||||
|
||||
@@ -42,6 +43,7 @@ APPKIT_EXTERN NSString *const MPDidChangeStoredKeyFilesSettings;
|
||||
- (IBAction)showPreferences:(id)sender;
|
||||
- (IBAction)showPluginPrefences:(id)sender;
|
||||
- (IBAction)showPasswordCreator:(id)sender;
|
||||
- (IBAction)showAutotypeDoctor:(id)sender;
|
||||
- (IBAction)createNewDatabase:(id)sender;
|
||||
- (IBAction)openDatabase:(id)sender;
|
||||
- (IBAction)showHelp:(id)sender;
|
||||
|
||||
@@ -42,8 +42,10 @@
|
||||
#import "MPWelcomeViewController.h"
|
||||
#import "MPPlugin.h"
|
||||
#import "MPEntryContextMenuDelegate.h"
|
||||
#import "MPAutotypeDoctor.h"
|
||||
|
||||
#import "NSApplication+MPAdditions.h"
|
||||
#import "NSTextView+MPTouchBarExtension.h"
|
||||
|
||||
#import "KeePassKit/KeePassKit.h"
|
||||
|
||||
@@ -51,6 +53,12 @@
|
||||
|
||||
NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDidChangeStoredKeyFilesSettings";
|
||||
|
||||
typedef NS_OPTIONS(NSInteger, MPAppStartupState) {
|
||||
MPAppStartupStateNone = 0,
|
||||
MPAppStartupStateRestoredWindows = 1,
|
||||
MPAppStartupStateFinishedLaunch = 2
|
||||
};
|
||||
|
||||
@interface MPAppDelegate () {
|
||||
@private
|
||||
MPDockTileHelper *_dockTileHelper;
|
||||
@@ -62,6 +70,7 @@ NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDi
|
||||
@property (strong) IBOutlet NSWindow *passwordCreatorWindow;
|
||||
@property (strong, nonatomic) MPPreferencesWindowController *preferencesController;
|
||||
@property (strong, nonatomic) MPPasswordCreatorViewController *passwordCreatorController;
|
||||
@property (assign, nonatomic) MPAppStartupState startupState;
|
||||
|
||||
@property (strong) MPEntryContextMenuDelegate *itemActionMenuDelegate;
|
||||
|
||||
@@ -82,11 +91,22 @@ NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDi
|
||||
if(self) {
|
||||
_userNotificationCenterDelegate = [[MPUserNotificationCenterDelegate alloc] init];
|
||||
self.itemActionMenuDelegate = [[MPEntryContextMenuDelegate alloc] init];
|
||||
_shouldOpenFile = NO;
|
||||
self.startupState = MPAppStartupStateNone;
|
||||
|
||||
[NSNotificationCenter.defaultCenter addObserver:self
|
||||
selector:@selector(_applicationDidFinishRestoringWindows:)
|
||||
name:NSApplicationDidFinishRestoringWindowsNotification
|
||||
object:nil];
|
||||
|
||||
/* We know that we do not use the variable after instantiation */
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunused-variable"
|
||||
MPDocumentController *documentController = [[MPDocumentController alloc] init];
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
|
||||
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -109,6 +129,17 @@ NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDi
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setStartupState:(MPAppStartupState)notificationState {
|
||||
if(notificationState != self.startupState) {
|
||||
_startupState = notificationState;
|
||||
BOOL restored = self.startupState & MPAppStartupStateRestoredWindows;
|
||||
BOOL launched = self.startupState & MPAppStartupStateFinishedLaunch;
|
||||
if(restored && launched ) {
|
||||
[self _applicationDidFinishLaunchingAndDidRestoreWindows];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)awakeFromNib {
|
||||
_isAllowedToStoreKeyFile = NO;
|
||||
/* Update the … at the save menu */
|
||||
@@ -127,7 +158,7 @@ NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDi
|
||||
[fileMenu insertItem:item atIndex:insertIndex];
|
||||
}
|
||||
[self.itemMenu removeAllItems];
|
||||
for(NSMenuItem *item in [MPContextMenuHelper contextMenuItemsWithItems:MPContextMenuFull]) {
|
||||
for(NSMenuItem *item in [MPContextMenuHelper contextMenuItemsWithItems:MPContextMenuFull|MPContextMenuShowGroupInOutline]) {
|
||||
[self.itemMenu addItem:item];
|
||||
}
|
||||
self.itemMenu.delegate = self.itemActionMenuDelegate;
|
||||
@@ -154,23 +185,13 @@ NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDi
|
||||
return [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyOpenEmptyDatabaseOnLaunch];
|
||||
}
|
||||
|
||||
|
||||
- (void)applicationWillFinishLaunching:(NSNotification *)notification {
|
||||
_shouldOpenFile = NO;
|
||||
[NSNotificationCenter.defaultCenter addObserver:self
|
||||
selector:@selector(_applicationDidFinishRestoringWindows:)
|
||||
name:NSApplicationDidFinishRestoringWindowsNotification
|
||||
object:nil];
|
||||
|
||||
|
||||
}
|
||||
|
||||
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender {
|
||||
return [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyQuitOnLastWindowClose];
|
||||
}
|
||||
|
||||
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
|
||||
if([[MPTemporaryFileStorageCenter defaultCenter] hasPendingStorages]) {
|
||||
[self hideWelcomeWindow];
|
||||
if(MPTemporaryFileStorageCenter.defaultCenter.hasPendingStorages) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[MPTemporaryFileStorageCenter.defaultCenter cleanupStorages];
|
||||
[sender replyToApplicationShouldTerminate:YES];
|
||||
@@ -201,6 +222,13 @@ NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDi
|
||||
/* Disable updates if in debug or nosparkle */
|
||||
[SUUpdater sharedUpdater];
|
||||
#endif
|
||||
self.startupState |= MPAppStartupStateFinishedLaunch;
|
||||
// Here we just opt-in for allowing our bar to be customized throughout the app.
|
||||
if([NSApplication.sharedApplication respondsToSelector:@selector(isAutomaticCustomizeTouchBarMenuItemEnabled)]) {
|
||||
if(@available(macOS 10.12.2, *)) {
|
||||
NSApplication.sharedApplication.automaticCustomizeTouchBarMenuItemEnabled = YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
@@ -212,19 +240,36 @@ NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDi
|
||||
NSString *saveTitle = displayDots ? NSLocalizedString(@"SAVE_WITH_DOTS", "Save file menu item title when save will prompt for a location to save or ask for a password/key") : NSLocalizedString(@"SAVE", "Save file menu item title when save will just save the file");
|
||||
self.saveMenuItem.title = saveTitle;
|
||||
}
|
||||
if(menu == self.fixAutotypeMenuItem.menu) {
|
||||
else if(menu == self.fixAutotypeMenuItem.menu) {
|
||||
self.fixAutotypeMenuItem.hidden = !(NSEvent.modifierFlags & NSAlternateKeyMask);
|
||||
}
|
||||
if(menu == self.importMenu) {
|
||||
else if(menu == self.importMenu) {
|
||||
NSMenuItem *exportXML = menu.itemArray.firstObject;
|
||||
[menu removeAllItems];
|
||||
[menu addItem:exportXML];
|
||||
for(MPPlugin<MPImportPlugin> * plugin in MPPluginHost.sharedHost.importPlugins) {
|
||||
NSMenuItem *importItem = [[NSMenuItem alloc] init];
|
||||
[plugin prepareImportMenuItem:importItem];
|
||||
importItem.submenu = nil; // kill any potential submenu!
|
||||
importItem.representedObject = plugin.identifier;
|
||||
importItem.target = nil;
|
||||
importItem.action = @selector(importFromPlugin:);
|
||||
importItem.action = @selector(importWithPlugin:);
|
||||
[menu addItem:importItem];
|
||||
}
|
||||
}
|
||||
else if(menu == self.exportMenu) {
|
||||
NSMenuItem *importXML = menu.itemArray.firstObject;
|
||||
[menu removeAllItems];
|
||||
[menu addItem:importXML];
|
||||
for(MPPlugin<MPExportPlugin> * plugin in MPPluginHost.sharedHost.exportPlugins) {
|
||||
NSMenuItem *exportItem = [[NSMenuItem alloc] init];
|
||||
[plugin prepareExportMenuItem:exportItem];
|
||||
exportItem.submenu = nil; // kill any potential submenu!
|
||||
exportItem.representedObject = plugin.identifier;
|
||||
exportItem.target = nil;
|
||||
exportItem.action = @selector(exportWithPlugin:);
|
||||
[menu addItem:exportItem];
|
||||
}
|
||||
[menu insertItem:exportXML atIndex:0];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -290,6 +335,7 @@ NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDi
|
||||
styleMask:NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskResizable
|
||||
backing:NSBackingStoreBuffered
|
||||
defer:NO];
|
||||
self.welcomeWindow.restorable = NO; // do not restore the welcome window!
|
||||
self.welcomeWindow.releasedWhenClosed = NO;
|
||||
}
|
||||
if(!self.welcomeWindow.contentViewController) {
|
||||
@@ -313,11 +359,15 @@ NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDi
|
||||
[NSWorkspace.sharedWorkspace openURL:[NSURL URLWithString:urlString]];
|
||||
}
|
||||
|
||||
- (void)showAutotypeDoctor:(id)sender {
|
||||
[MPAutotypeDoctor.defaultDoctor runChecksAndPresentResults];
|
||||
}
|
||||
|
||||
- (void)checkForUpdates:(id)sender {
|
||||
#if defined(DEBUG) || defined(NO_SPARKLE)
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
alert.messageText = NSLocalizedString(@"ALERT_UPDATES_DISABLED_MESSAGE_TEXT", @"Message text for disabled updates alert!");
|
||||
alert.informativeText = [NSString stringWithFormat:NSLocalizedString(@"ALERT_UPDATES_DISABLED_INFORMATIVE_TEXT_%@!", @"Infromative text of the disabled updates alert!"), NSApp.applicationName];
|
||||
alert.informativeText = [NSString stringWithFormat:NSLocalizedString(@"ALERT_UPDATES_DISABLED_INFORMATIVE_TEXT_%@!", @"Informative text of the disabled updates alert!"), NSApp.applicationName];
|
||||
[alert addButtonWithTitle:NSLocalizedString(@"OK", @"Ok Button to dismiss disabled updates alert")];
|
||||
[alert runModal];
|
||||
#else
|
||||
@@ -328,8 +378,12 @@ NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDi
|
||||
#pragma mark -
|
||||
#pragma mark Private Helper
|
||||
- (void)_applicationDidFinishRestoringWindows:(NSNotification *)notification {
|
||||
self.startupState |= MPAppStartupStateRestoredWindows;
|
||||
}
|
||||
|
||||
- (void)_applicationDidFinishLaunchingAndDidRestoreWindows {
|
||||
NSArray *documents = NSDocumentController.sharedDocumentController.documents;
|
||||
BOOL restoredWindows = documents.count > 0;
|
||||
BOOL hasOpenDocuments = documents.count > 0;
|
||||
|
||||
for(NSDocument *document in documents) {
|
||||
for(NSWindowController *windowController in document.windowControllers) {
|
||||
@@ -338,17 +392,13 @@ NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDi
|
||||
}
|
||||
|
||||
BOOL reopen = [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyReopenLastDatabaseOnLaunch];
|
||||
BOOL showWelcomeScreen = !restoredWindows && !_shouldOpenFile;
|
||||
if(reopen && !restoredWindows && !_shouldOpenFile) {
|
||||
BOOL showWelcomeScreen = !hasOpenDocuments && !_shouldOpenFile;
|
||||
if(reopen && !hasOpenDocuments && !_shouldOpenFile) {
|
||||
showWelcomeScreen = ![((MPDocumentController *)NSDocumentController.sharedDocumentController) reopenLastDocument];
|
||||
}
|
||||
if(showWelcomeScreen) {
|
||||
[self showWelcomeWindow];
|
||||
}
|
||||
/* run check for accessibilty after the windowserver should have presented the UI */
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
[MPAutotypeDaemon.defaultDaemon checkForAccessibiltyPermissions];
|
||||
});
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -22,12 +22,19 @@
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class MPAutotypeEnvironment;
|
||||
@class MPAutotypeContext;
|
||||
|
||||
@interface MPAutotypeCandidateSelectionViewController : NSViewController
|
||||
|
||||
@property (copy) NSArray *candidates;
|
||||
|
||||
@property (strong) MPAutotypeEnvironment *environment;
|
||||
@property (copy) NSArray<MPAutotypeContext *> *candidates;
|
||||
|
||||
- (IBAction)selectAutotypeContext:(id)sender;
|
||||
- (IBAction)cancelSelection:(id)sender;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@@ -22,14 +22,17 @@
|
||||
#import "MPAutotypeCandidateSelectionViewController.h"
|
||||
#import "MPAutotypeContext.h"
|
||||
#import "MPAutotypeDaemon.h"
|
||||
#import "MPAutotypeEnvironment.h"
|
||||
#import "MPExtendedTableCellView.h"
|
||||
|
||||
#import "KPKNode+IconImage.h"
|
||||
|
||||
#import <KeePassKit/KeePassKit.h>
|
||||
|
||||
@interface MPAutotypeCandidateSelectionViewController () <NSTableViewDataSource, NSTableViewDelegate>
|
||||
@property (weak) IBOutlet NSButton *selectAutotypeContextButton;
|
||||
@property (weak) IBOutlet NSTableView *contextTableView;
|
||||
@property (strong) IBOutlet NSButton *selectAutotypeContextButton;
|
||||
@property (strong) IBOutlet NSTableView *contextTableView;
|
||||
@property (strong) IBOutlet NSTextField *messageTextField;
|
||||
|
||||
@end
|
||||
|
||||
@@ -41,7 +44,11 @@
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
NSString *template = NSLocalizedString(@"AUTOTYPE_CANDIDATE_SELECTION_WINDOW_MESSAGE_%@", "Message text in the autotype selection window. Placeholder is %1 - windowTitle");
|
||||
self.messageTextField.stringValue = [NSString stringWithFormat:template, self.environment.windowTitle];
|
||||
self.selectAutotypeContextButton.enabled = NO;
|
||||
NSNotification *notification = [NSNotification notificationWithName:NSTableViewSelectionDidChangeNotification object:self.contextTableView];
|
||||
[self tableViewSelectionDidChange:notification];
|
||||
}
|
||||
|
||||
#pragma mark NSTableViewDataSource
|
||||
@@ -53,12 +60,10 @@
|
||||
#pragma mark NSTableViewDelegate
|
||||
|
||||
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
|
||||
NSTableCellView *view = [tableView makeViewWithIdentifier:tableColumn.identifier owner:self];
|
||||
MPExtendedTableCellView *view = [tableView makeViewWithIdentifier:tableColumn.identifier owner:self];
|
||||
MPAutotypeContext *context = self.candidates[row];
|
||||
NSString *maskedEvaluatedCommand = context.maskedEvaluatedCommand;
|
||||
NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@\n%@", context.entry.title, maskedEvaluatedCommand]];
|
||||
[string setAttributes:@{NSForegroundColorAttributeName: NSColor.disabledControlTextColor} range:NSMakeRange((string.length - maskedEvaluatedCommand.length), maskedEvaluatedCommand.length)];
|
||||
view.textField.attributedStringValue = string;
|
||||
view.addionalTextField.stringValue = context.maskedEvaluatedCommand;
|
||||
view.textField.stringValue = context.entry.title;
|
||||
view.imageView.image = context.entry.iconImage;
|
||||
return view;
|
||||
}
|
||||
@@ -75,7 +80,7 @@
|
||||
- (void)selectAutotypeContext:(id)sender {
|
||||
NSInteger selectedRow = self.contextTableView.selectedRow;
|
||||
if(selectedRow >= 0 && selectedRow < self.candidates.count) {
|
||||
[MPAutotypeDaemon.defaultDaemon selectAutotypeCandiate:self.candidates[selectedRow]];
|
||||
[MPAutotypeDaemon.defaultDaemon selectAutotypeContext:self.candidates[selectedRow] forEnvironment:self.environment];
|
||||
}
|
||||
else {
|
||||
[self cancelSelection:sender]; // cancel since the selection was invalid!
|
||||
@@ -83,7 +88,7 @@
|
||||
}
|
||||
|
||||
- (void)cancelSelection:(id)sender {
|
||||
[[MPAutotypeDaemon defaultDaemon] cancelAutotypeCandidateSelection];
|
||||
[MPAutotypeDaemon.defaultDaemon cancelAutotypeContextSelectionForEnvironment:self.environment];
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
@class DDHotKey;
|
||||
@class KPKEntry;
|
||||
@class MPAutotypeContext;
|
||||
@class MPAutotypeExecutionContext;
|
||||
@class MPAutotypeEnvironment;
|
||||
/**
|
||||
* The autotype daemon is responsible for registering the global hotkey and to perform any autotype actions
|
||||
*/
|
||||
@@ -35,16 +35,12 @@
|
||||
@property (weak) IBOutlet NSPopUpButton *matchSelectionButton;
|
||||
@property (readonly, strong) DDHotKey *registredHotKey;
|
||||
@property (readonly, strong, class) MPAutotypeDaemon *defaultDaemon;
|
||||
@property (nonatomic, readonly) BOOL autotypeSupported; // YES if the system allows for Autotype. NO if the user has denied this.
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
- (void)checkForAccessibiltyPermissions;
|
||||
- (void)openAccessibiltyPreferences;
|
||||
|
||||
- (void)performAutotypeForEntry:(KPKEntry *)entry;
|
||||
- (void)performAutotypeForEntry:(KPKEntry *)entry overrideSequence:(NSString *)sequence;
|
||||
- (void)selectAutotypeCandiate:(MPAutotypeContext *)context;
|
||||
- (void)cancelAutotypeCandidateSelection;
|
||||
- (void)selectAutotypeContext:(MPAutotypeContext *)context forEnvironment:(MPAutotypeEnvironment *)environment;
|
||||
- (void)cancelAutotypeContextSelectionForEnvironment:(MPAutotypeEnvironment *)environment;
|
||||
|
||||
@end
|
||||
|
||||
@@ -25,11 +25,17 @@
|
||||
#import "MPDocumentWindowController.h"
|
||||
#import "MPAutotypeCommand.h"
|
||||
#import "MPAutotypeContext.h"
|
||||
#import "MPAutotypeEnvironment.h"
|
||||
#import "MPAutotypePaste.h"
|
||||
#import "MPAutotypeDelay.h"
|
||||
#import "MPPasteBoardController.h"
|
||||
#import "MPSettingsHelper.h"
|
||||
#import "MPAutotypeCandidateSelectionViewController.h"
|
||||
#import "MPUserNotificationCenterDelegate.h"
|
||||
#import "MPAutotypeDoctor.h"
|
||||
|
||||
#import "MPPluginHost.h"
|
||||
#import "MPPlugin.h"
|
||||
|
||||
#import "NSApplication+MPAdditions.h"
|
||||
#import "NSUserNotification+MPAdditions.h"
|
||||
@@ -40,25 +46,20 @@
|
||||
#import "KeePassKit/KeePassKit.h"
|
||||
#import <Carbon/Carbon.h>
|
||||
|
||||
NSString *const kMPWindowTitleKey = @"kMPWindowTitleKey";
|
||||
NSString *const kMPProcessIdentifierKey = @"kMPProcessIdentifierKey";
|
||||
|
||||
@interface MPAutotypeDaemon ()
|
||||
|
||||
@property (nonatomic, assign) BOOL enabled;
|
||||
@property (nonatomic, copy) NSData *hotKeyData;
|
||||
@property (strong) DDHotKey *registredHotKey;
|
||||
@property (assign) pid_t targetPID; // The pid of the process we want to sent commands to
|
||||
@property (copy) NSString *targetWindowTitle; // The title of the window that we are targeting
|
||||
|
||||
@property (strong) NSRunningApplication *previousApplication; // The application that was active before we got invoked
|
||||
@property (assign) NSTimeInterval userActionRequested;
|
||||
|
||||
@property (strong) id applicationActivationObserver;
|
||||
@property (nonatomic, readonly) BOOL hasNecessaryAutotypePermissions;
|
||||
@end
|
||||
|
||||
@implementation MPAutotypeDaemon
|
||||
|
||||
@dynamic autotypeSupported;
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Lifecylce
|
||||
|
||||
@@ -81,7 +82,6 @@ static MPAutotypeDaemon *_sharedInstance;
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_enabled = NO;
|
||||
_targetPID = -1;
|
||||
_userActionRequested = NSDate.distantPast.timeIntervalSinceReferenceDate;
|
||||
[self bind:NSStringFromSelector(@selector(enabled))
|
||||
toObject:NSUserDefaultsController.sharedUserDefaultsController
|
||||
@@ -104,19 +104,15 @@ static MPAutotypeDaemon *_sharedInstance;
|
||||
- (void)dealloc {
|
||||
[NSNotificationCenter.defaultCenter removeObserver:self];
|
||||
[NSWorkspace.sharedWorkspace.notificationCenter removeObserver:self];
|
||||
if(self.applicationActivationObserver) {
|
||||
[NSWorkspace.sharedWorkspace.notificationCenter removeObserver:self.applicationActivationObserver name:NSWorkspaceDidActivateApplicationNotification object:nil];
|
||||
}
|
||||
[self unbind:NSStringFromSelector(@selector(enabled))];
|
||||
[self unbind:NSStringFromSelector(@selector(hotKeyData))];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Properties
|
||||
- (BOOL)autotypeSupported {
|
||||
if(@available(macOS 10.14, *)) {
|
||||
return AXIsProcessTrusted();
|
||||
}
|
||||
/* macOS 10.13 and lower allows us to send key events regardless of accessibilty trust */
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)setEnabled:(BOOL)enabled {
|
||||
if(_enabled != enabled) {
|
||||
@@ -135,45 +131,8 @@ static MPAutotypeDaemon *_sharedInstance;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)checkForAccessibiltyPermissions {
|
||||
if(!self.enabled) {
|
||||
return;
|
||||
}
|
||||
BOOL hideAlert = NO;
|
||||
if(nil != [NSUserDefaults.standardUserDefaults objectForKey:kMPSettingsKeyAutotypeHideAccessibiltyWarning]) {
|
||||
hideAlert = [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyAutotypeHideAccessibiltyWarning];
|
||||
}
|
||||
if(hideAlert || self.autotypeSupported) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
alert.alertStyle = NSWarningAlertStyle;
|
||||
alert.messageText = NSLocalizedString(@"ALERT_AUTOTYPE_MISSING_ACCESSIBILTY_PERMISSIONS_MESSAGE_TEXT", @"Alert message displayed when Autotype performs self check and lacks accessibilty permissions");
|
||||
alert.informativeText = NSLocalizedString(@"ALERT_AUTOTYPE_MISSING_ACCESSIBILTY_PERMISSIONS_INFORMATIVE_TEXT", @"Alert informative text displayed when Autotype performs self check and lacks accessibilty permissions");
|
||||
alert.showsSuppressionButton = YES;
|
||||
[alert addButtonWithTitle:NSLocalizedString(@"ALERT_AUTOTYPE_MISSING_ACCESSIBILTY_PERMISSIONS_BUTTON_OK", @"Button in dialog to leave autotype disabled and continiue!")];
|
||||
[alert addButtonWithTitle:NSLocalizedString(@"ALERT_AUTOTYPE_MISSING_ACCESSIBILTY_PERMISSIONS_BUTTON_OPEN_PREFERENCES", @"Button in dialog to open accessibilty preferences pane!")];
|
||||
NSModalResponse returnCode = [alert runModal];
|
||||
BOOL suppressWarning = (alert.suppressionButton.state == NSOnState);
|
||||
[NSUserDefaults.standardUserDefaults setBool:suppressWarning forKey:kMPSettingsKeyAutotypeHideAccessibiltyWarning];
|
||||
switch(returnCode) {
|
||||
case NSAlertFirstButtonReturn: {
|
||||
/* ok, ignore */
|
||||
break;
|
||||
}
|
||||
case NSAlertSecondButtonReturn:
|
||||
/* open prefs */
|
||||
[self openAccessibiltyPreferences];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)openAccessibiltyPreferences {
|
||||
[NSWorkspace.sharedWorkspace openURL:[NSURL URLWithString:@"x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility"]];
|
||||
- (BOOL)hasNecessaryAutotypePermissions {
|
||||
return MPAutotypeDoctor.defaultDoctor.hasNecessaryAutotypePermissions;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
@@ -181,51 +140,69 @@ static MPAutotypeDaemon *_sharedInstance;
|
||||
- (void)performAutotypeForEntry:(KPKEntry *)entry {
|
||||
[self performAutotypeForEntry:entry overrideSequence:nil];
|
||||
}
|
||||
|
||||
- (void)performAutotypeForEntry:(KPKEntry *)entry overrideSequence:(NSString *)sequence {
|
||||
if(entry) {
|
||||
[self _updateTargeInformationForApplication:self.previousApplication];
|
||||
[self _performAutotypeForEntry:entry];
|
||||
MPAutotypeEnvironment *env = [MPAutotypeEnvironment environmentWithTargetApplication:self.previousApplication entry:entry];
|
||||
[self _runAutotypeWithEnvironment:env];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_didPressHotKey {
|
||||
[self _updateTargetInformationForFrontMostApplication];
|
||||
[self _performAutotypeForEntry:nil];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Actions
|
||||
- (void)selectAutotypeCandiate:(MPAutotypeContext *)context {
|
||||
[self.matchSelectionWindow orderOut:self];
|
||||
self.matchSelectionWindow = nil;
|
||||
[self _performAutotypeForContext:context];
|
||||
}
|
||||
|
||||
- (void)cancelAutotypeCandidateSelection {
|
||||
[self.matchSelectionWindow orderOut:self];
|
||||
self.matchSelectionWindow = nil;
|
||||
if(self.targetPID) {
|
||||
[self _orderApplicationToFront:self.targetPID];
|
||||
}
|
||||
MPAutotypeEnvironment *env = [MPAutotypeEnvironment environmentWithTargetApplication:NSWorkspace.sharedWorkspace.frontmostApplication entry:nil];
|
||||
[self _runAutotypeWithEnvironment:env];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Autotype Execution
|
||||
- (void)selectAutotypeContext:(MPAutotypeContext *)context forEnvironment:(MPAutotypeEnvironment *)environment {
|
||||
[self.matchSelectionWindow orderOut:self];
|
||||
self.matchSelectionWindow = nil;
|
||||
[self _runAutotypeWithEnvironment:environment forContext:context];
|
||||
if(environment.hidden) {
|
||||
[NSApplication.sharedApplication hide:nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_performAutotypeForEntry:(KPKEntry *)entryOrNil {
|
||||
/*if(!self.autotypeSupported) {
|
||||
NSUserNotification *notification = [[NSUserNotification alloc] init];
|
||||
notification.title = NSApp.applicationName;
|
||||
notification.informativeText = NSLocalizedString(@"AUTOTYPE_NOTIFICATION_MACPASS_HAS_NO_ACCESSIBILTY_PERMISSIONS", "Notification: Autotype failed, MacPass has no permission to send key strokes");
|
||||
notification.actionButtonTitle = NSLocalizedString(@"OPEN_PREFERENCES", "Action button in Notification to show the Accessibilty preferences");
|
||||
notification.userInfo = @{ MPUserNotificationTypeKey: MPUserNotificationTypeShowAccessibiltyPreferences };
|
||||
notification.showsButtons = YES;
|
||||
[NSUserNotificationCenter.defaultUserNotificationCenter deliverNotification:notification];
|
||||
return;
|
||||
}*/
|
||||
NSInteger pid = NSProcessInfo.processInfo.processIdentifier;
|
||||
if(self.targetPID == pid) {
|
||||
return; // We do not perform Autotype on ourselves
|
||||
- (void)cancelAutotypeContextSelectionForEnvironment:(MPAutotypeEnvironment *)environment {
|
||||
[self.matchSelectionWindow orderOut:self];
|
||||
self.matchSelectionWindow = nil;
|
||||
if(environment.hidden) {
|
||||
[NSApplication.sharedApplication hide:nil];
|
||||
}
|
||||
if(environment.pid) {
|
||||
[self _orderApplicationToFront:environment.pid completionHandler:nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_runAutotypeAfterDatabaseUnlockWithEnvironment:(MPAutotypeEnvironment *)environment requestedAt:(NSTimeInterval)requestTime {
|
||||
NSTimeInterval now = NSDate.date.timeIntervalSinceReferenceDate;
|
||||
if(now - requestTime > 30) {
|
||||
NSUserNotification *notification = [[NSUserNotification alloc] init];
|
||||
notification.title = NSLocalizedString(@"AUTOTYPE_NOTIFICATION_TIMED_OUT_TITLE", "Title for the notification when the Autotype operation timed out");
|
||||
notification.informativeText = NSLocalizedString(@"AUTOTYPE_TIMED_OUT", "Notficication: Autotype timed out");
|
||||
notification.userInfo = @{ MPUserNotificationTypeKey: MPUserNotificationTypeAutotypeFeedback };
|
||||
[NSUserNotificationCenter.defaultUserNotificationCenter deliverNotification:notification];
|
||||
}
|
||||
else {
|
||||
[self _runAutotypeWithEnvironment:environment];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_runAutotypeWithEnvironment:(MPAutotypeEnvironment *)env {
|
||||
if(env.isSelfTargeting) {
|
||||
return; // we do not want to target ourselves
|
||||
}
|
||||
|
||||
if(!self.hasNecessaryAutotypePermissions) {
|
||||
NSUserNotification *notification = [[NSUserNotification alloc] init];
|
||||
notification.title = NSLocalizedString(@"AUTOTYPE_NOTIFICATION_PERMISSIONS_MISSING_TITLE", "Title for autotype feedback on missing permissions");
|
||||
notification.informativeText = NSLocalizedString(@"AUTOTYPE_NOTIFICATION_MACPASS_IS_MISSING_PERMISSIONS", "Notification: Autotype failed, MacPass has not enough permissions to perform autotype");
|
||||
notification.actionButtonTitle = NSLocalizedString(@"SHOW_AUTOTYPE_DOCTOR", "Action button in Notification to show the Autotype Doctor");
|
||||
notification.userInfo = @{ MPUserNotificationTypeKey: MPUserNotificationTypeRunAutotypeDoctor };
|
||||
notification.showsButtons = YES;
|
||||
[NSUserNotificationCenter.defaultUserNotificationCenter deliverNotification:notification];
|
||||
return;
|
||||
}
|
||||
|
||||
/* find autotype documents */
|
||||
@@ -233,20 +210,30 @@ static MPAutotypeDaemon *_sharedInstance;
|
||||
/* No open document, inform the user and return without any action */
|
||||
if(documents.count == 0) {
|
||||
NSUserNotification *notification = [[NSUserNotification alloc] init];
|
||||
notification.title = NSApp.applicationName;
|
||||
notification.informativeText = NSLocalizedString(@"AUTOTYPE_OVERLAY_NO_DOCUMENTS", "Notification: Autotype failed, no documents are open");
|
||||
notification.title = NSLocalizedString(@"AUTOTYPE_NOTIFICATION_NO_DOCUMENTS_TITLE", "Notification: Title for autotype feedback");
|
||||
notification.informativeText = NSLocalizedString(@"AUTOTYPE_NOTIFICATION_NO_DOCUMENTS_INFORMATIVE_TEXT", "Notification: Autotype failed, no documents are open");
|
||||
notification.actionButtonTitle = NSLocalizedString(@"OPEN_DOCUMENT", "Action button in Notification to open a document");
|
||||
notification.userInfo = @{ MPUserNotificationTypeKey: MPUserNotificationTypeAutotypeOpenDocumentRequest };
|
||||
notification.showsButtons = YES;
|
||||
[NSUserNotificationCenter.defaultUserNotificationCenter deliverNotification:notification];
|
||||
self.userActionRequested = NSDate.date.timeIntervalSinceReferenceDate;
|
||||
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(_didUnlockDatabase:) name:MPDocumentDidUnlockDatabaseNotification object:nil];
|
||||
NSNotificationCenter * __weak nc = [NSNotificationCenter defaultCenter];
|
||||
MPAutotypeDaemon * __weak welf = self;
|
||||
NSTimeInterval requestTime = NSDate.date.timeIntervalSinceReferenceDate;
|
||||
id __block unlockToken = [nc addObserverForName:MPDocumentDidUnlockDatabaseNotification
|
||||
object:nil
|
||||
queue:NSOperationQueue.mainQueue
|
||||
usingBlock:^(NSNotification *notification) {
|
||||
[welf _runAutotypeAfterDatabaseUnlockWithEnvironment:env requestedAt:requestTime];
|
||||
[nc removeObserver:unlockToken];
|
||||
}];
|
||||
return; // Unlock should trigger autotype
|
||||
}
|
||||
|
||||
NSPredicate *filterPredicate = [NSPredicate predicateWithBlock:^BOOL(id _Nonnull evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
|
||||
MPDocument *document = evaluatedObject;
|
||||
return !document.encrypted;}];
|
||||
return !document.encrypted;
|
||||
}];
|
||||
|
||||
NSArray *unlockedDocuments = [documents filteredArrayUsingPredicate:filterPredicate];
|
||||
/* We look for all unlocked documents, if all open documents are locked, we pop the front most and try to search again */
|
||||
if(unlockedDocuments.count == 0) {
|
||||
@@ -257,68 +244,98 @@ static MPAutotypeDaemon *_sharedInstance;
|
||||
[document showWindows];
|
||||
MPDocumentWindowController *wc = document.windowControllers.firstObject;
|
||||
[wc showPasswordInputWithMessage:NSLocalizedString(@"AUTOTYPE_MESSAGE_UNLOCK_DATABASE", @"Message displayed to the user to unlock the database to perform global autotype")];
|
||||
self.userActionRequested = NSDate.date.timeIntervalSinceReferenceDate;
|
||||
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(_didUnlockDatabase:) name:MPDocumentDidUnlockDatabaseNotification object:nil];
|
||||
NSNotificationCenter * __weak nc = [NSNotificationCenter defaultCenter];
|
||||
MPAutotypeDaemon * __weak welf = self;
|
||||
NSTimeInterval requestTime = NSDate.date.timeIntervalSinceReferenceDate;
|
||||
id __block unlockToken = [nc addObserverForName:MPDocumentDidUnlockDatabaseNotification
|
||||
object:nil
|
||||
queue:NSOperationQueue.mainQueue
|
||||
usingBlock:^(NSNotification *notification) {
|
||||
[welf _runAutotypeAfterDatabaseUnlockWithEnvironment:env requestedAt:requestTime];
|
||||
|
||||
[nc removeObserver:unlockToken];
|
||||
}];
|
||||
return; // wait for the unlock to happen
|
||||
}
|
||||
|
||||
MPAutotypeContext *context = [self _autotypeContextForDocuments:documents forWindowTitle:self.targetWindowTitle preferredEntry:entryOrNil];
|
||||
/* TODO: that's popping up if the mulit selection dialog goes up! */
|
||||
MPAutotypeContext *context = [self _autotypeContextForDocuments:documents withEnvironment:env];
|
||||
if(self.matchSelectionWindow) {
|
||||
return; // we present the match selection window, just return
|
||||
}
|
||||
if(!entryOrNil) {
|
||||
if(!env.preferredEntry) {
|
||||
NSUserNotification *notification = [[NSUserNotification alloc] init];
|
||||
notification.title = NSApp.applicationName;
|
||||
notification.title = NSLocalizedString(@"AUTOTYPE_NOTIFICATION_MATCH_TITLE", "Notification: Title for autotype feedback");
|
||||
notification.userInfo = @{ MPUserNotificationTypeKey: MPUserNotificationTypeAutotypeFeedback };
|
||||
if(context) {
|
||||
notification.informativeText = [NSString stringWithFormat:NSLocalizedString(@"AUTOTYPE_OVERLAY_SINGLE_MATCH_FOR_%@", "Notification: Autotype found a single match for %@ (string placeholder)."), self.targetWindowTitle];
|
||||
notification.informativeText = [NSString stringWithFormat:NSLocalizedString(@"AUTOTYPE_NOTIFICATION_SINGLE_MATCH_FOR_%@", "Notification: Autotype found a single match for %@ (string placeholder)."), env.windowTitle];
|
||||
}
|
||||
else {
|
||||
notification.informativeText = [NSString stringWithFormat:NSLocalizedString(@"AUTOTYPE_OVERLAY_NO_MATCH_FOR_%@", "Noticiation: Autotype failed to find a match for %@ (string placeholder)"), self.targetWindowTitle];
|
||||
notification.informativeText = [NSString stringWithFormat:NSLocalizedString(@"AUTOTYPE_NOTIFICATION_NO_MATCH_FOR_%@", "Noticiation: Autotype failed to find a match for %@ (string placeholder)"), env.windowTitle];
|
||||
}
|
||||
[NSUserNotificationCenter.defaultUserNotificationCenter deliverNotification:notification];
|
||||
}
|
||||
[self _performAutotypeForContext:context];
|
||||
[self _runAutotypeWithEnvironment:env forContext:context];
|
||||
}
|
||||
|
||||
- (MPAutotypeContext *)_autotypeContextForDocuments:(NSArray<MPDocument *> *)documents forWindowTitle:(NSString *)windowTitle preferredEntry:(KPKEntry *)entry {
|
||||
- (MPAutotypeContext *)_autotypeContextForDocuments:(NSArray<MPDocument *> *)documents withEnvironment:(MPAutotypeEnvironment *)environment {
|
||||
/*
|
||||
Query the document to generate a autotype command list for the window title
|
||||
We do not care where this came form, just get the autotype commands
|
||||
*/
|
||||
NSMutableArray *autotypeCandidates = [[NSMutableArray alloc] init];
|
||||
for(MPDocument *document in documents) {
|
||||
NSArray *contexts = [document autotypContextsForWindowTitle:windowTitle preferredEntry:entry];
|
||||
NSArray *contexts = [document autotypContextsForWindowTitle:environment.windowTitle preferredEntry:environment.preferredEntry];
|
||||
if(contexts ) {
|
||||
[autotypeCandidates addObjectsFromArray:contexts];
|
||||
}
|
||||
}
|
||||
NSUInteger candidates = autotypeCandidates.count;
|
||||
if(candidates == 0) {
|
||||
return nil;
|
||||
}
|
||||
if(candidates == 1 ) {
|
||||
|
||||
if(autotypeCandidates.count <= 1) {
|
||||
return autotypeCandidates.lastObject;
|
||||
}
|
||||
[self _presentSelectionWindow:autotypeCandidates];
|
||||
[self _presentCandiadates:autotypeCandidates forEnvironment:environment];
|
||||
return nil; // Nothing to do, we get called back by the window
|
||||
}
|
||||
|
||||
- (void)_performAutotypeForContext:(MPAutotypeContext *)context {
|
||||
- (void)_runAutotypeWithEnvironment:(MPAutotypeEnvironment *)environment forContext:(MPAutotypeContext *)context {
|
||||
if(nil == environment) {
|
||||
return; // no Environment to work in
|
||||
}
|
||||
if(nil == context) {
|
||||
return; // No context to work with
|
||||
}
|
||||
|
||||
if([self _orderApplicationToFront:self.targetPID]) {
|
||||
/* Sleep a bit after the app was activated */
|
||||
/* TODO - we might be able to a notification to check if the app actally was activated instead of guessing a waiting time */
|
||||
usleep(1 * NSEC_PER_MSEC);
|
||||
__weak MPAutotypeDaemon *welf = self;
|
||||
BOOL appIsFrontmost = [self _orderApplicationToFront:environment.pid completionHandler:^{
|
||||
[welf _runAutotypeWithEnvironment:environment forContext:context];
|
||||
}];
|
||||
if(!appIsFrontmost) {
|
||||
return; // We will get called back when the application is in front - hopfully
|
||||
}
|
||||
|
||||
useconds_t globalDelay = 0;
|
||||
for(MPAutotypeCommand *command in [MPAutotypeCommand commandsForContext:context]) {
|
||||
/*
|
||||
FIXME: Introduce a global state for execution to allow command to set state value
|
||||
e.g. [command executeWithContext:(MPCommandExectionContext *)context]
|
||||
and inside the command set the sate e.g. context.delay = myDelay
|
||||
then use this state in the command scheduling to set the global delay
|
||||
*/
|
||||
if([command isKindOfClass:MPAutotypeDelay.class]) {
|
||||
MPAutotypeDelay *delayCommand = (MPAutotypeDelay *)command;
|
||||
if(delayCommand.isGlobal) {
|
||||
globalDelay = (useconds_t)delayCommand.delay;
|
||||
}
|
||||
}
|
||||
/* dispatch commands to main thread since most of them translate key events which is disallowed on background thread */
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if(globalDelay > 0) {
|
||||
usleep(globalDelay*NSEC_PER_USEC);
|
||||
}
|
||||
[command execute];
|
||||
/* re-hide after every command since this might have put us back up front */
|
||||
if(environment.hidden) {
|
||||
[NSApplication.sharedApplication hide:nil];
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -343,34 +360,7 @@ static MPAutotypeDaemon *_sharedInstance;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSDictionary *)_infoDictionaryForApplication:(NSRunningApplication *)application {
|
||||
NSArray *currentWindows = CFBridgingRelease(CGWindowListCopyWindowInfo(kCGWindowListExcludeDesktopElements, kCGNullWindowID));
|
||||
NSArray *windowNumbers = [NSWindow windowNumbersWithOptions:NSWindowNumberListAllApplications];
|
||||
NSUInteger minZIndex = NSNotFound;
|
||||
NSDictionary *infoDict = nil;
|
||||
for(NSDictionary *windowDict in currentWindows) {
|
||||
NSString *windowTitle = windowDict[(NSString *)kCGWindowName];
|
||||
if(windowTitle.length <= 0) {
|
||||
continue;
|
||||
}
|
||||
NSNumber *processId = windowDict[(NSString *)kCGWindowOwnerPID];
|
||||
if(processId && [processId isEqualToNumber:@(application.processIdentifier)]) {
|
||||
|
||||
NSNumber *number = (NSNumber *)windowDict[(NSString *)kCGWindowNumber];
|
||||
NSUInteger zIndex = [windowNumbers indexOfObject:number];
|
||||
if(zIndex < minZIndex) {
|
||||
minZIndex = zIndex;
|
||||
infoDict = @{
|
||||
kMPWindowTitleKey: windowTitle,
|
||||
kMPProcessIdentifierKey : processId
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
return infoDict;
|
||||
}
|
||||
|
||||
- (void)_presentSelectionWindow:(NSArray *)candidates {
|
||||
- (void)_presentCandiadates:(NSArray *)candidates forEnvironment:(MPAutotypeEnvironment *)environment {
|
||||
if(!self.matchSelectionWindow) {
|
||||
self.matchSelectionWindow = [[NSPanel alloc] initWithContentRect:NSMakeRect(0, 0, 100, 100)
|
||||
styleMask:NSWindowStyleMaskNonactivatingPanel|NSWindowStyleMaskTitled
|
||||
@@ -379,6 +369,7 @@ static MPAutotypeDaemon *_sharedInstance;
|
||||
self.matchSelectionWindow.level = kCGAssistiveTechHighWindowLevel;
|
||||
MPAutotypeCandidateSelectionViewController *vc = [[MPAutotypeCandidateSelectionViewController alloc] init];
|
||||
vc.candidates = candidates;
|
||||
vc.environment = environment;
|
||||
self.matchSelectionWindow.collectionBehavior |= (NSWindowCollectionBehaviorFullScreenAuxiliary |
|
||||
NSWindowCollectionBehaviorMoveToActiveSpace |
|
||||
NSWindowCollectionBehaviorTransient );
|
||||
@@ -389,24 +380,6 @@ static MPAutotypeDaemon *_sharedInstance;
|
||||
[self.matchSelectionWindow makeKeyAndOrderFront:self];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark MPDocument Notifications
|
||||
- (void)_didUnlockDatabase:(NSNotification *)notification {
|
||||
/* Remove ourselves and call again to search matches */
|
||||
[NSNotificationCenter.defaultCenter removeObserver:self name:MPDocumentDidUnlockDatabaseNotification object:nil];
|
||||
NSTimeInterval now = NSDate.date.timeIntervalSinceReferenceDate;
|
||||
if(now - self.userActionRequested > 30) {
|
||||
NSUserNotification *notification = [[NSUserNotification alloc] init];
|
||||
notification.title = NSApp.applicationName;
|
||||
notification.informativeText = NSLocalizedString(@"AUTOTYPE_TIMED_OUT", "Notficication: Autotype timed out");
|
||||
notification.userInfo = @{ MPUserNotificationTypeKey: MPUserNotificationTypeAutotypeFeedback };
|
||||
[NSUserNotificationCenter.defaultUserNotificationCenter deliverNotification:notification];
|
||||
}
|
||||
else {
|
||||
[self _performAutotypeForEntry:nil];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark NSApplication Notifications
|
||||
- (void)_didDeactivateApplication:(NSNotification *)notification {
|
||||
@@ -416,29 +389,25 @@ static MPAutotypeDaemon *_sharedInstance;
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Application information
|
||||
- (BOOL)_orderApplicationToFront:(pid_t)processIdentifier {
|
||||
//- (BOOL)_orderApplicationToFront:(pid_t)processIdentifier inEnvironment:(MPAutotypeEnvironment *) environment {
|
||||
- (BOOL)_orderApplicationToFront:(pid_t)processIdentifier completionHandler:(void (^_Nullable)(void))completionHandler {
|
||||
NSRunningApplication *runingApplication = [NSRunningApplication runningApplicationWithProcessIdentifier:processIdentifier];
|
||||
NSRunningApplication *frontApplication = NSWorkspace.sharedWorkspace.frontmostApplication;
|
||||
if(frontApplication.processIdentifier == processIdentifier) {
|
||||
return NO;
|
||||
return YES;
|
||||
}
|
||||
|
||||
NSNotificationCenter * __weak nc = NSWorkspace.sharedWorkspace.notificationCenter;
|
||||
id __block didActivateToken = [nc addObserverForName:NSWorkspaceDidActivateApplicationNotification
|
||||
object:nil
|
||||
queue:NSOperationQueue.mainQueue
|
||||
usingBlock:^(NSNotification *notification) {
|
||||
[nc removeObserver:didActivateToken];
|
||||
if(completionHandler) {
|
||||
completionHandler();
|
||||
}
|
||||
}];
|
||||
[runingApplication activateWithOptions:NSApplicationActivateIgnoringOtherApps];
|
||||
return YES;
|
||||
return NO;
|
||||
}
|
||||
- (void)_updateTargetInformationForFrontMostApplication {
|
||||
[self _updateTargeInformationForApplication:NSWorkspace.sharedWorkspace.frontmostApplication];
|
||||
}
|
||||
|
||||
- (void)_updateTargeInformationForApplication:(NSRunningApplication *)application {
|
||||
if(!application) {
|
||||
self.targetPID = -1;
|
||||
self.targetWindowTitle = @"";
|
||||
}
|
||||
else {
|
||||
NSDictionary *frontApplicationInfoDict = [self _infoDictionaryForApplication:application];
|
||||
self.targetPID = [frontApplicationInfoDict[kMPProcessIdentifierKey] intValue];
|
||||
self.targetWindowTitle = frontApplicationInfoDict[kMPWindowTitleKey];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
@interface MPAutotypeDelay : MPAutotypeCommand
|
||||
|
||||
@property (readonly) NSUInteger delay;
|
||||
@property (readonly) BOOL isGlobal;
|
||||
/**
|
||||
* Creates an DelayCommand that delays the execution for n milliseconds
|
||||
*
|
||||
@@ -33,5 +34,6 @@
|
||||
* @return <#return value description#>
|
||||
*/
|
||||
- (instancetype)initWithDelay:(NSUInteger)delay;
|
||||
- (instancetype)initWithGlobalDelay:(NSUInteger)delay;
|
||||
|
||||
@end
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
@implementation MPAutotypeDelay
|
||||
|
||||
- (id)init {
|
||||
self = [self initWithDelay:0];
|
||||
self = [self _initWithDelay:0 global:NO];
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -38,17 +38,32 @@
|
||||
}
|
||||
|
||||
- (instancetype)initWithDelay:(NSUInteger)delay {
|
||||
self = [self _initWithDelay:delay global:NO];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithGlobalDelay:(NSUInteger)delay {
|
||||
self = [self _initWithDelay:delay global:YES];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)_initWithDelay:(NSUInteger)delay global:(BOOL)global {
|
||||
self = [super init];
|
||||
if(self) {
|
||||
_isGlobal = global;
|
||||
/* Delays longer than a minute are a bit long */
|
||||
_delay = MIN(60*1000,delay);
|
||||
_delay = MIN(60*NSEC_PER_USEC,delay);
|
||||
}
|
||||
return self;
|
||||
|
||||
}
|
||||
|
||||
- (void)execute {
|
||||
/* milliseconds * 10000 = microseconds */
|
||||
usleep((useconds_t)(self.delay*1000));
|
||||
if(self.isGlobal) {
|
||||
return; // global delays should not be executed locally
|
||||
}
|
||||
usleep((useconds_t)(self.delay*NSEC_PER_USEC));
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
30
MacPass/MPAutotypeDoctor.h
Normal file
30
MacPass/MPAutotypeDoctor.h
Normal file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// MPAutotypeDoctor.h
|
||||
// MacPass
|
||||
//
|
||||
// Created by Michael Starke on 03.07.19.
|
||||
// Copyright © 2019 HicknHack Software GmbH. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface MPAutotypeDoctor : NSObject
|
||||
|
||||
|
||||
@property (class, readonly, strong) MPAutotypeDoctor *defaultDoctor;
|
||||
@property (nonatomic, readonly) BOOL hasNecessaryAutotypePermissions; // MacPass has all the permissions it needs to run autotype on the current system
|
||||
|
||||
- (BOOL)hasScreenRecordingPermissions:(NSError *__autoreleasing*)error;
|
||||
- (BOOL)hasAccessibiltyPermissions:(NSError *__autoreleasing*)error;
|
||||
|
||||
- (void)runChecksAndPresentResults;
|
||||
- (void)openScreenRecordingPreferences;
|
||||
- (void)requestScreenRecordingPermission;
|
||||
- (void)openAccessibiltyPreferences;
|
||||
- (void)openAutomationPreferences;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
172
MacPass/MPAutotypeDoctor.m
Normal file
172
MacPass/MPAutotypeDoctor.m
Normal file
@@ -0,0 +1,172 @@
|
||||
//
|
||||
// MPAutotypeDoctor.m
|
||||
// MacPass
|
||||
//
|
||||
// Created by Michael Starke on 03.07.19.
|
||||
// Copyright © 2019 HicknHack Software GmbH. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MPAutotypeDoctor.h"
|
||||
#import "MPSettingsHelper.h"
|
||||
#import "NSApplication+MPAdditions.h"
|
||||
#import "MPAutotypeDoctorReportViewController.h"
|
||||
#import "NSError+Messages.h"
|
||||
|
||||
|
||||
@interface MPReportItem : NSObject
|
||||
|
||||
@property (copy) NSString *statusDescription;
|
||||
@property (copy) NSString *label;
|
||||
@property (copy) NSString *actionLabel;
|
||||
@property BOOL isOK;
|
||||
@property (weak) id target;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MPReportItem
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if(self) {
|
||||
_isOK = NO;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface MPAutotypeDoctor () <NSWindowDelegate>
|
||||
@property (strong) NSWindow *reportWindow;
|
||||
@end
|
||||
|
||||
@implementation MPAutotypeDoctor
|
||||
|
||||
+ (MPAutotypeDoctor *)defaultDoctor {
|
||||
static MPAutotypeDoctor *instance;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
instance = [[MPAutotypeDoctor alloc] init];
|
||||
});
|
||||
return instance;
|
||||
}
|
||||
|
||||
- (BOOL)hasNecessaryAutotypePermissions {
|
||||
if(![self hasAccessibiltyPermissions:NULL]) {
|
||||
return NO;
|
||||
}
|
||||
if(![self hasScreenRecordingPermissions:NULL]) {
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)hasScreenRecordingPermissions:(NSError *__autoreleasing*)error {
|
||||
/* macos 10.14 and lower do not require screen recording permission to get window titles */
|
||||
|
||||
/*
|
||||
Solution is heavily inspired by Craig Hockenberry's
|
||||
https://stackoverflow.com/questions/56597221/detecting-screen-recording-settings-on-macos-catalina/58985069#58985069
|
||||
*/
|
||||
if(@available(macOS 10.15, *)) {
|
||||
CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
|
||||
NSUInteger numberOfWindows = CFArrayGetCount(windowList);
|
||||
BOOL canRecordScreen = NO;
|
||||
for(int idx = 0; idx < numberOfWindows; idx++) {
|
||||
NSDictionary *windowInfo = (NSDictionary *)CFArrayGetValueAtIndex(windowList, idx);
|
||||
NSNumber *ownerPid = windowInfo[(id)kCGWindowOwnerPID];
|
||||
/*
|
||||
Skip over our own windows
|
||||
*/
|
||||
if(ownerPid.intValue == NSProcessInfo.processInfo.processIdentifier) {
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
Skip applications we aren't allowed to access anyway
|
||||
*/
|
||||
NSRunningApplication *ownerApp = [NSRunningApplication runningApplicationWithProcessIdentifier:ownerPid.intValue];
|
||||
if(!ownerApp) {
|
||||
continue;
|
||||
}
|
||||
NSString *windowName = windowInfo[(id)kCGWindowName];
|
||||
if(windowName) {
|
||||
if([ownerApp.executableURL.lastPathComponent isEqualToString:@"Dock"]) {
|
||||
continue;
|
||||
}
|
||||
canRecordScreen = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
CFRelease(windowList);
|
||||
if(!canRecordScreen && error) {
|
||||
*error = [NSError errorInDomain:MPAutotypeErrorDomain withCode:MPErrorAutotypeIsMissingScreenRecordingPermissions description:NSLocalizedString(@"ERROR_NO_PERMISSION_TO_RECORD_SCREEN", "Error description for missing screen recording permissions")];
|
||||
}
|
||||
return canRecordScreen;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)hasAccessibiltyPermissions:(NSError *__autoreleasing*)error {
|
||||
BOOL isTrusted = YES;
|
||||
/* macOS 10.13 and lower allows us to send key events regardless of accessibilty trust */
|
||||
if(@available(macOS 10.14, *)) {
|
||||
isTrusted = AXIsProcessTrusted();
|
||||
if(!isTrusted && error) {
|
||||
*error = [NSError errorInDomain:MPAutotypeErrorDomain withCode:MPErrorAutotypeIsMissingAccessibiltyPermissions description:NSLocalizedString(@"ERROR_NO_ACCESSIBILITY_PERMISSIONS", "Error description for missing accessibility permissions")];
|
||||
}
|
||||
}
|
||||
return isTrusted;
|
||||
}
|
||||
|
||||
- (void)openAccessibiltyPreferences {
|
||||
[NSWorkspace.sharedWorkspace openURL:[NSURL URLWithString:@"x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility"]];
|
||||
}
|
||||
|
||||
- (void)openScreenRecordingPreferences {
|
||||
[NSWorkspace.sharedWorkspace openURL:[NSURL URLWithString:@"x-apple.systempreferences:com.apple.preference.security?Privacy_ScreenCapture"]];
|
||||
}
|
||||
|
||||
- (void)requestScreenRecordingPermission {
|
||||
/* macos 10.14 and lower do not require screen recording permission to get window titles */
|
||||
if(@available(macos 10.15, *)) {
|
||||
/*
|
||||
To minimize the intrusion just make a 1px image of the upper left corner
|
||||
This way there is no real possibilty to access any private data
|
||||
*/
|
||||
CGImageRef screenshot = CGWindowListCreateImage(
|
||||
CGRectMake(0, 0, 1, 1),
|
||||
kCGWindowListOptionOnScreenOnly,
|
||||
kCGNullWindowID,
|
||||
kCGWindowImageDefault);
|
||||
CFRelease(screenshot);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)openAutomationPreferences {
|
||||
[NSWorkspace.sharedWorkspace openURL:[NSURL URLWithString:@"x-apple.systempreferences:com.apple.preference.security?Privacy_Automation"]];
|
||||
}
|
||||
|
||||
- (void)runChecksAndPresentResults {
|
||||
if(!self.reportWindow) {
|
||||
self.reportWindow = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 100, 100)
|
||||
styleMask:NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskResizable
|
||||
backing:NSBackingStoreBuffered
|
||||
defer:NO];
|
||||
self.reportWindow.releasedWhenClosed = NO;
|
||||
self.reportWindow.title = NSLocalizedString(@"AUTOTYPE_DOCTOR_RESULTS_WINDOW_TITLE", @"Window title for the stand-alone password creator window");
|
||||
self.reportWindow.delegate = self;
|
||||
}
|
||||
MPAutotypeDoctorReportViewController *vc = [[MPAutotypeDoctorReportViewController alloc] init];
|
||||
self.reportWindow.contentViewController = vc;
|
||||
|
||||
[self.reportWindow center];
|
||||
[self.reportWindow makeKeyAndOrderFront:vc];
|
||||
}
|
||||
|
||||
- (void)windowWillClose:(NSNotification *)notification {
|
||||
if(notification.object == self.reportWindow) {
|
||||
self.reportWindow = nil;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
29
MacPass/MPAutotypeDoctorReportViewController.h
Normal file
29
MacPass/MPAutotypeDoctorReportViewController.h
Normal file
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// MPAutotypeDoctorReportViewController.h
|
||||
// MacPass
|
||||
//
|
||||
// Created by Michael Starke on 05.07.19.
|
||||
// Copyright © 2019 HicknHack Software GmbH. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface MPAutotypeDoctorReportViewController : NSViewController
|
||||
|
||||
@property (strong) IBOutlet NSImageView *accessibiltyStatusImageView;
|
||||
@property (strong) IBOutlet NSTextField *accessibiltyStatusTextField;
|
||||
|
||||
@property (strong) IBOutlet NSImageView *screenRecordingStatusImageView;
|
||||
@property (strong) IBOutlet NSTextField *screenRecordingStatusTextField;
|
||||
@property (strong) IBOutlet NSButton *requestScreenRecordingButton;
|
||||
|
||||
- (IBAction)openAccessibiltyPreferences:(id)sender;
|
||||
- (IBAction)openScreenRecordingPreferences:(id)sender;
|
||||
- (IBAction)requestScreenRecordingPermissions:(id)sender;
|
||||
- (IBAction)openAutomationPreferences:(id)sender;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
73
MacPass/MPAutotypeDoctorReportViewController.m
Normal file
73
MacPass/MPAutotypeDoctorReportViewController.m
Normal file
@@ -0,0 +1,73 @@
|
||||
//
|
||||
// MPAutotypeDoctorReportViewController.m
|
||||
// MacPass
|
||||
//
|
||||
// Created by Michael Starke on 05.07.19.
|
||||
// Copyright © 2019 HicknHack Software GmbH. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MPAutotypeDoctorReportViewController.h"
|
||||
#import "MPAutotypeDoctor.h"
|
||||
|
||||
@implementation MPAutotypeDoctorReportViewController
|
||||
|
||||
- (NSNibName)nibName {
|
||||
return @"AutotypeDoctorReportViewController";
|
||||
}
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
[self _updateView];
|
||||
|
||||
}
|
||||
|
||||
- (void)openAccessibiltyPreferences:(id)sender {
|
||||
[MPAutotypeDoctor.defaultDoctor openAccessibiltyPreferences];
|
||||
}
|
||||
|
||||
- (void)openScreenRecordingPreferences:(id)sender {
|
||||
[MPAutotypeDoctor.defaultDoctor openScreenRecordingPreferences];
|
||||
}
|
||||
|
||||
- (IBAction)requestScreenRecordingPermissions:(id)sender {
|
||||
[MPAutotypeDoctor.defaultDoctor requestScreenRecordingPermission];
|
||||
}
|
||||
|
||||
- (void)openAutomationPreferences:(id)sender {
|
||||
[MPAutotypeDoctor.defaultDoctor openAutomationPreferences];
|
||||
}
|
||||
|
||||
|
||||
- (void)_updateView {
|
||||
NSError *error;
|
||||
if([MPAutotypeDoctor.defaultDoctor hasAccessibiltyPermissions:&error]) {
|
||||
self.accessibiltyStatusImageView.image = [NSImage imageNamed:NSImageNameStatusAvailable];
|
||||
self.accessibiltyStatusTextField.stringValue = NSLocalizedString(@"AUTOTYPE_STATUS_ACCESSIBILTY_PERMISSIONS_OK", "Status label when no issue were found in accessibilty");
|
||||
}
|
||||
else {
|
||||
self.accessibiltyStatusImageView.image = [NSImage imageNamed:NSImageNameStatusUnavailable];
|
||||
if(error && error.localizedDescription) {
|
||||
self.accessibiltyStatusTextField.stringValue = error.localizedDescription;
|
||||
}
|
||||
else {
|
||||
self.accessibiltyStatusTextField.stringValue = NSLocalizedString(@"AUTOTYPE_STATUS_NO_ACCESSIBILTY_PERMISSIONS", "Status MacPass has no accessibilty permissions");
|
||||
}
|
||||
}
|
||||
if([MPAutotypeDoctor.defaultDoctor hasScreenRecordingPermissions:&error]) {
|
||||
self.requestScreenRecordingButton.enabled = NO;
|
||||
self.screenRecordingStatusImageView.image = [NSImage imageNamed:NSImageNameStatusAvailable];
|
||||
self.screenRecordingStatusTextField.stringValue = NSLocalizedString(@"AUTOTYPE_STATUS_SCREEN_RECORDING_PERMISSIONS_OK", "Status label when no issue were found in screen recording permissions");
|
||||
}
|
||||
else {
|
||||
self.requestScreenRecordingButton.enabled = YES;
|
||||
self.screenRecordingStatusImageView.image = [NSImage imageNamed:NSImageNameStatusUnavailable];
|
||||
if(error && error.localizedDescription) {
|
||||
self.screenRecordingStatusTextField.stringValue = error.localizedDescription;
|
||||
}
|
||||
else {
|
||||
self.screenRecordingStatusTextField.stringValue = NSLocalizedString(@"AUTOTYPE_STATUS_NO_SCREEN_RECORDING_PERMISSIONS", "Status MacPass has no screen recording permissions");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
34
MacPass/MPAutotypeEnvironment.h
Normal file
34
MacPass/MPAutotypeEnvironment.h
Normal file
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// MPAutotypeEnvironment.h
|
||||
// MacPass
|
||||
//
|
||||
// Created by Michael Starke on 15.01.20.
|
||||
// Copyright © 2020 HicknHack Software GmbH. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class KPKEntry;
|
||||
@class MPAutotypeContext;
|
||||
|
||||
@interface MPAutotypeEnvironment : NSObject
|
||||
|
||||
/**
|
||||
The selected entry, if Autotype is run only for a single entry.
|
||||
If autotype should search for entries, set this to nil.
|
||||
*/
|
||||
@property (readonly, weak, nullable) KPKEntry *preferredEntry;
|
||||
@property (readonly) pid_t pid; // the PID of the target application to which the key strokes should be sent
|
||||
@property (readonly, copy) NSString *windowTitle; /// The window title of the target application.
|
||||
@property (readonly) BOOL hidden; /// If set to YES, MacPass was hidden when autotype was initiated
|
||||
@property (readonly) BOOL isSelfTargeting; /// If MacPass should autotype to itself, YES, otherwise NO
|
||||
|
||||
+ (instancetype)environmentWithTargetApplication:(NSRunningApplication *)targetApplication entry:(KPKEntry * _Nullable)entry;
|
||||
- (instancetype)initWithTargetApplication:(NSRunningApplication *)targetApplication entry:(KPKEntry * _Nullable)entry NS_DESIGNATED_INITIALIZER;
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
84
MacPass/MPAutotypeEnvironment.m
Normal file
84
MacPass/MPAutotypeEnvironment.m
Normal file
@@ -0,0 +1,84 @@
|
||||
//
|
||||
// MPAutotypeEnvironment.m
|
||||
// MacPass
|
||||
//
|
||||
// Created by Michael Starke on 15.01.20.
|
||||
// Copyright © 2020 HicknHack Software GmbH. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MPAutotypeEnvironment.h"
|
||||
#import "NSRunningApplication+MPAdditions.h"
|
||||
#import "MPPluginHost.h"
|
||||
#import "MPPlugin.h"
|
||||
|
||||
@implementation MPAutotypeEnvironment
|
||||
|
||||
+ (instancetype)environmentWithTargetApplication:(NSRunningApplication *)targetApplication entry:(KPKEntry *)entry {
|
||||
return [[MPAutotypeEnvironment alloc] initWithTargetApplication:targetApplication entry:entry];
|
||||
}
|
||||
|
||||
- (instancetype)initWithTargetApplication:(NSRunningApplication *)targetApplication entry:(KPKEntry *)entry {
|
||||
self = [super init];
|
||||
if(self) {
|
||||
_preferredEntry = entry;
|
||||
if(!targetApplication) {
|
||||
_pid = -1;
|
||||
_windowTitle = @"";
|
||||
}
|
||||
else {
|
||||
NSDictionary *frontApplicationInfoDict = targetApplication.mp_infoDictionary;
|
||||
|
||||
_pid = [frontApplicationInfoDict[MPProcessIdentifierKey] intValue];
|
||||
_windowTitle = frontApplicationInfoDict[MPWindowTitleKey];
|
||||
|
||||
/* if we have any resolvers, let them provide the window title */
|
||||
NSArray *resolvers = [MPPluginHost.sharedHost windowTitleResolverForRunningApplication:targetApplication];
|
||||
for(MPPlugin<MPAutotypeWindowTitleResolverPlugin> *resolver in resolvers) {
|
||||
NSString *windowTitle = [resolver windowTitleForRunningApplication:targetApplication];
|
||||
if(windowTitle.length > 0) {
|
||||
_windowTitle = windowTitle;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
_hidden = NSRunningApplication.currentApplication.isHidden;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)isSelfTargeting {
|
||||
return NSRunningApplication.currentApplication.processIdentifier == _pid;
|
||||
}
|
||||
|
||||
- (NSDictionary *)_infoDictionaryForApplication:(NSRunningApplication *)application {
|
||||
NSArray *currentWindows = CFBridgingRelease(CGWindowListCopyWindowInfo(kCGWindowListExcludeDesktopElements, kCGNullWindowID));
|
||||
NSArray *windowNumbers = [NSWindow windowNumbersWithOptions:NSWindowNumberListAllApplications];
|
||||
NSUInteger minZIndex = NSNotFound;
|
||||
NSDictionary *infoDict = nil;
|
||||
for(NSDictionary *windowDict in currentWindows) {
|
||||
NSString *windowTitle = windowDict[(NSString *)kCGWindowName];
|
||||
if(windowTitle.length <= 0) {
|
||||
continue;
|
||||
}
|
||||
NSNumber *processId = windowDict[(NSString *)kCGWindowOwnerPID];
|
||||
if(processId && [processId isEqualToNumber:@(application.processIdentifier)]) {
|
||||
|
||||
NSNumber *number = (NSNumber *)windowDict[(NSString *)kCGWindowNumber];
|
||||
NSUInteger zIndex = [windowNumbers indexOfObject:number];
|
||||
if(zIndex < minZIndex) {
|
||||
minZIndex = zIndex;
|
||||
infoDict = @{
|
||||
MPWindowTitleKey: windowTitle,
|
||||
MPProcessIdentifierKey : processId
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
if(currentWindows.count > 0 && infoDict.count == 0) {
|
||||
// show some information about not being able to determine any windows
|
||||
NSLog(@"Unable to retrieve any window names. If you encounter this issue you might be running 10.15 and MacPass has no permission for screen recording.");
|
||||
}
|
||||
return infoDict;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -281,7 +281,7 @@ static CGKeyCode kMPNumpadKeyCodes[] = {
|
||||
static NSRegularExpression *delayRegExp;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
NSString *delayPattern = [[NSString alloc] initWithFormat:@"\\{(%@|%@)[ |=]+([0-9]+)\\}",
|
||||
NSString *delayPattern = [[NSString alloc] initWithFormat:@"\\{(%@|%@)([ |=])+([0-9]+)\\}",
|
||||
kKPKAutotypeDelay,
|
||||
kKPKAutotypeVirtualKey/*,
|
||||
kKPKAutotypeVirtualExtendedKey,
|
||||
@@ -327,9 +327,10 @@ static CGKeyCode kMPNumpadKeyCodes[] = {
|
||||
// TODO: add {APPLICATION <appname>}
|
||||
/* Delay */
|
||||
NSTextCheckingResult *result = [delayRegExp firstMatchInString:commandString options:0 range:NSMakeRange(0, commandString.length)];
|
||||
if(result && (result.numberOfRanges == 3)) {
|
||||
if(result && (result.numberOfRanges == 4)) {
|
||||
NSString *uppercaseCommand = [[commandString substringWithRange:[result rangeAtIndex:1]] uppercaseString];
|
||||
NSString *valueString = [commandString substringWithRange:[result rangeAtIndex:2]];
|
||||
NSString *assignOrNot = [commandString substringWithRange:[result rangeAtIndex:2]];
|
||||
NSString *valueString = [commandString substringWithRange:[result rangeAtIndex:3]];
|
||||
NSScanner *numberScanner = [[NSScanner alloc] initWithString:valueString];
|
||||
NSInteger value;
|
||||
if([numberScanner scanInteger:&value]) {
|
||||
@@ -337,7 +338,12 @@ static CGKeyCode kMPNumpadKeyCodes[] = {
|
||||
if(MAX(0, value) <= 0) {
|
||||
return; // Value too low, just skipp
|
||||
}
|
||||
[self.mutableCommands addObject:[[MPAutotypeDelay alloc] initWithDelay:value]];
|
||||
if([assignOrNot isEqualToString:@"="]) {
|
||||
[self.mutableCommands addObject:[[MPAutotypeDelay alloc] initWithGlobalDelay:value]];
|
||||
}
|
||||
else {
|
||||
[self.mutableCommands addObject:[[MPAutotypeDelay alloc] initWithDelay:value]];
|
||||
}
|
||||
return; // Done
|
||||
}
|
||||
else if([kKPKAutotypeVirtualKey isEqualToString:uppercaseCommand]) {
|
||||
|
||||
@@ -24,6 +24,12 @@
|
||||
|
||||
@interface MPContextButton : NSSegmentedControl
|
||||
|
||||
typedef NS_ENUM(NSUInteger, MPContextButtonSegment) {
|
||||
MPContextButtonSegmentButton,
|
||||
MPContextButtonSegmentContextButton,
|
||||
MPContextButtonSegmentCount // do not use
|
||||
};
|
||||
|
||||
@property (nonatomic, strong) NSMenu *contextMenu;
|
||||
|
||||
- (void)setImage:(NSImage *)image;
|
||||
|
||||
@@ -53,14 +53,14 @@
|
||||
|
||||
self.focusRingType = NSFocusRingTypeNone;
|
||||
self.segmentStyle = NSSegmentStyleTexturedSquare;
|
||||
self.segmentCount = 2;
|
||||
self.segmentCount = MPContextButtonSegmentCount;
|
||||
cell.trackingMode = NSSegmentSwitchTrackingMomentary;
|
||||
[cell setWidth:31 forSegment:0];
|
||||
[cell setWidth:17 forSegment:1];
|
||||
[cell setWidth:31 forSegment:MPContextButtonSegmentButton];
|
||||
[cell setWidth:17 forSegment:MPContextButtonSegmentContextButton];
|
||||
cell.trackingMode = NSSegmentSwitchTrackingMomentary;
|
||||
|
||||
NSImage *contextTriangle = [NSBundle.mainBundle imageForResource:@"contextTriangleTemplate"];
|
||||
[self setImage:contextTriangle forSegment:1];
|
||||
[self setImage:contextTriangle forSegment:MPContextButtonSegmentContextButton];
|
||||
|
||||
cell.contextMenuAction = @selector(showContextMenu:);
|
||||
cell.contextMenuTarget = self;
|
||||
@@ -76,42 +76,42 @@
|
||||
Block the segment setter to prevent accidental settings
|
||||
*/
|
||||
- (void)setImage:(NSImage *)image forSegment:(NSInteger)segment {
|
||||
if(segment < 2) {
|
||||
if(segment < MPContextButtonSegmentCount) {
|
||||
[super setImage:image forSegment:segment];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setSegmentCount:(NSInteger)count {
|
||||
if(count == 2) {
|
||||
if(count == MPContextButtonSegmentCount) {
|
||||
super.segmentCount = count;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setImage:(NSImage *)image {
|
||||
[self setImage:image forSegment:0];
|
||||
[self setImage:image forSegment:MPContextButtonSegmentButton];
|
||||
}
|
||||
|
||||
- (void)showContextMenu:(id)sender {
|
||||
NSPoint point = self.frame.origin;
|
||||
point.x = [self.cell widthForSegment:0];
|
||||
point.x = [self.cell widthForSegment:MPContextButtonSegmentButton];
|
||||
point.y = NSHeight(self.frame) + 3;
|
||||
[_contextMenu popUpMenuPositioningItem:nil atLocation:point inView:self];
|
||||
}
|
||||
|
||||
- (void)setControlSize:(NSControlSize)controlSize {
|
||||
NSImageRep *rep = [[self imageForSegment:0] bestRepresentationForRect:NSMakeRect(0, 0, 100, 100) context:nil hints:nil];
|
||||
NSImageRep *rep = [[self imageForSegment:MPContextButtonSegmentButton] bestRepresentationForRect:NSMakeRect(0, 0, 100, 100) context:nil hints:nil];
|
||||
CGFloat scale = rep.size.width / rep.size.height;
|
||||
switch (controlSize) {
|
||||
case NSRegularControlSize:
|
||||
[self imageForSegment:0].size = NSMakeSize(16 * scale, 16);
|
||||
[self imageForSegment:MPContextButtonSegmentButton].size = NSMakeSize(16 * scale, 16);
|
||||
break;
|
||||
|
||||
case NSSmallControlSize:
|
||||
[self imageForSegment:0].size = NSMakeSize(14 * scale, 14);
|
||||
[self imageForSegment:MPContextButtonSegmentButton].size = NSMakeSize(14 * scale, 14);
|
||||
break;
|
||||
|
||||
case NSMiniControlSize:
|
||||
[self imageForSegment:0].size = NSMakeSize(8 * scale, 8);
|
||||
[self imageForSegment:MPContextButtonSegmentButton].size = NSMakeSize(8 * scale, 8);
|
||||
|
||||
default:
|
||||
break;
|
||||
@@ -123,4 +123,9 @@
|
||||
return super.controlSize;
|
||||
}
|
||||
|
||||
- (void)_updateContextButtonState {
|
||||
BOOL hasContextMenu = (self.contextMenu != nil);
|
||||
[self setEnabled:hasContextMenu forSegment:MPContextButtonSegmentContextButton];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -23,16 +23,17 @@
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
typedef NS_OPTIONS(NSUInteger, MPContextMenuItemsFlags) {
|
||||
MPContextMenuCreate = 1 << 0,
|
||||
MPContextMenuDelete = 1 << 1,
|
||||
MPContextMenuCopy = 1 << 2,
|
||||
MPContextMenuTrash = 1 << 3,
|
||||
MPContextMenuDuplicate = 1 << 4,
|
||||
MPContextMenuAutotype = 1 << 5,
|
||||
MPContextMenuHistory = 1 << 6,
|
||||
MPContextMenuMinimal = MPContextMenuCreate | MPContextMenuDelete,
|
||||
MPContextMenuFull = MPContextMenuMinimal | MPContextMenuCopy | MPContextMenuDuplicate | MPContextMenuAutotype | MPContextMenuHistory,
|
||||
MPContextMenuExtended = MPContextMenuFull | MPContextMenuTrash
|
||||
MPContextMenuCreate = 1 << 0,
|
||||
MPContextMenuDelete = 1 << 1,
|
||||
MPContextMenuCopy = 1 << 2,
|
||||
MPContextMenuTrash = 1 << 3,
|
||||
MPContextMenuDuplicate = 1 << 4,
|
||||
MPContextMenuAutotype = 1 << 5,
|
||||
MPContextMenuHistory = 1 << 6,
|
||||
MPContextMenuShowGroupInOutline = 1 << 7,
|
||||
MPContextMenuMinimal = MPContextMenuCreate | MPContextMenuDelete | MPContextMenuDuplicate,
|
||||
MPContextMenuFull = MPContextMenuMinimal | MPContextMenuCopy | MPContextMenuDuplicate | MPContextMenuAutotype | MPContextMenuHistory,
|
||||
MPContextMenuExtended = MPContextMenuFull | MPContextMenuTrash
|
||||
};
|
||||
|
||||
@interface MPContextMenuHelper : NSTableCellView
|
||||
|
||||
@@ -42,6 +42,7 @@ static void MPContextmenuHelperBeginSection(NSMutableArray *items) {
|
||||
BOOL const insertDuplicate = MPIsFlagSetInOptions(MPContextMenuDuplicate, flags);
|
||||
BOOL const insertAutotype = MPIsFlagSetInOptions(MPContextMenuAutotype, flags);
|
||||
BOOL const insertHistory = MPIsFlagSetInOptions(MPContextMenuHistory, flags);
|
||||
BOOL const insertShowGroupInOutline = MPIsFlagSetInOptions(MPContextMenuShowGroupInOutline, flags);
|
||||
|
||||
NSMutableArray *items = [NSMutableArray arrayWithCapacity:10];
|
||||
if(insertCreate) {
|
||||
@@ -63,8 +64,11 @@ static void MPContextmenuHelperBeginSection(NSMutableArray *items) {
|
||||
NSMenuItem *duplicateEntyWithOptions = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"DUPLICATE_ENTRY_WITH_OPTIONS", @"Menu item to duplicate an entry with options how to duplicate. Will present a dialog.")
|
||||
action:[MPActionHelper actionOfType:MPActionDuplicateEntryWithOptions]
|
||||
keyEquivalent:@""];
|
||||
|
||||
[items addObjectsFromArray:@[ duplicateEntry, duplicateEntyWithOptions ]];
|
||||
NSMenuItem *duplicateGroup = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"DUPLICATE_GROUP", @"Menu item to directly diplicate a group")
|
||||
action:[MPActionHelper actionOfType:MPActionDuplicateGroup]
|
||||
keyEquivalent:@""];
|
||||
|
||||
[items addObjectsFromArray:@[ duplicateEntry, duplicateEntyWithOptions, duplicateGroup ]];
|
||||
|
||||
}
|
||||
if(insertDelete || insertTrash) {
|
||||
@@ -113,7 +117,7 @@ static void MPContextmenuHelperBeginSection(NSMutableArray *items) {
|
||||
|
||||
[items addObjectsFromArray:@[ copyUsername, copyPassword, urlItem]];
|
||||
}
|
||||
if(insertAutotype || insertHistory) {
|
||||
if(insertAutotype || insertHistory || insertShowGroupInOutline) {
|
||||
MPContextmenuHelperBeginSection(items);
|
||||
if(insertAutotype) {
|
||||
NSMenuItem *performAutotype = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"PERFORM_AUTOTYPE_FOR_ENTRY", @"Menu item to perform autotype with the selected entry")
|
||||
@@ -128,6 +132,12 @@ static void MPContextmenuHelperBeginSection(NSMutableArray *items) {
|
||||
showHistory.keyEquivalentModifierMask = (showHistory.keyEquivalentModifierMask | NSCommandKeyMask | NSControlKeyMask);
|
||||
[items addObject:showHistory];
|
||||
}
|
||||
if(insertShowGroupInOutline) {
|
||||
NSMenuItem *showGroupInOutline = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"SHOW_GROUP_IN_OUTLINE", @"Menu item to show the entries group in the outline view")
|
||||
action:[MPActionHelper actionOfType:MPActionShowGroupInOutline]
|
||||
keyEquivalent:@""];
|
||||
[items addObject:showGroupInOutline];
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
|
||||
@@ -115,7 +115,7 @@ typedef NS_ENUM(NSUInteger, MPDatePreset) {
|
||||
default:
|
||||
return; // Nothing to do;
|
||||
}
|
||||
self.datePicker.dateValue = [gregorian dateByAddingComponents:offsetComponents toDate:[NSDate date] options:0];
|
||||
self.datePicker.dateValue = [gregorian dateByAddingComponents:offsetComponents toDate:NSDate.date options:0];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -53,7 +53,7 @@ NSString *const MPDocumentHideEntryHistoryNotification = @"MPDocumentHideEntryH
|
||||
- (void)revertEntry:(KPKEntry *)entry toEntry:(KPKEntry *)historyEntry {
|
||||
[entry pushHistory];
|
||||
[entry revertToEntry:historyEntry];
|
||||
[self.undoManager setActionName:NSLocalizedString(@"RESTORE_HISTORY_ENTRY", "Action to restore and Entry to a previous state of it's history")];
|
||||
[self.undoManager setActionName:NSLocalizedString(@"RESTORE_HISTORY_ENTRY", "Action to restore an Entry to its previous state of it's history")];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -44,7 +44,7 @@ NSString *const kMPDocumentSearchResultsKey = @"kMPDocumentSearchResul
|
||||
self.searchContext = context;
|
||||
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(updateSearch:) name:NSUndoManagerDidRedoChangeNotification object:self.undoManager];
|
||||
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(updateSearch:) name:NSUndoManagerDidUndoChangeNotification object:self.undoManager];
|
||||
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(updateSearch:) name:NSUndoManagerDidCloseUndoGroupNotification object:self.undoManager];
|
||||
//[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(updateSearch:) name:NSUndoManagerDidCloseUndoGroupNotification object:self.undoManager];
|
||||
[NSNotificationCenter.defaultCenter postNotificationName:MPDocumentDidEnterSearchNotification object:self];
|
||||
[self updateSearch:self];
|
||||
}
|
||||
@@ -64,7 +64,7 @@ NSString *const kMPDocumentSearchResultsKey = @"kMPDocumentSearchResul
|
||||
MPDocument __weak *weakSelf = self;
|
||||
dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
|
||||
dispatch_async(backgroundQueue, ^{
|
||||
NSArray *results = [weakSelf _findEntriesMatchingCurrentSearch];
|
||||
NSArray *results = [weakSelf _findEntriesMatchingSearch:weakSelf.searchContext];
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
[NSNotificationCenter.defaultCenter postNotificationName:MPDocumentDidChangeSearchResults object:weakSelf userInfo:@{ kMPDocumentSearchResultsKey: results }];
|
||||
});
|
||||
@@ -74,7 +74,7 @@ NSString *const kMPDocumentSearchResultsKey = @"kMPDocumentSearchResul
|
||||
- (void)exitSearch:(id)sender {
|
||||
[NSNotificationCenter.defaultCenter removeObserver:self name:NSUndoManagerDidUndoChangeNotification object:self.undoManager];
|
||||
[NSNotificationCenter.defaultCenter removeObserver:self name:NSUndoManagerDidRedoChangeNotification object:self.undoManager];
|
||||
[NSNotificationCenter.defaultCenter removeObserver:self name:NSUndoManagerDidCloseUndoGroupNotification object:self.undoManager];
|
||||
//[NSNotificationCenter.defaultCenter removeObserver:self name:NSUndoManagerDidCloseUndoGroupNotification object:self.undoManager];
|
||||
self.searchContext = nil;
|
||||
[NSNotificationCenter.defaultCenter postNotificationName:MPDocumentDidExitSearchNotification object:self];
|
||||
}
|
||||
@@ -128,9 +128,9 @@ NSString *const kMPDocumentSearchResultsKey = @"kMPDocumentSearchResul
|
||||
}
|
||||
|
||||
#pragma mark Search
|
||||
- (NSArray *)_findEntriesMatchingCurrentSearch {
|
||||
- (NSArray *)_findEntriesMatchingSearch:(MPEntrySearchContext *)context {
|
||||
/* Filter double passwords */
|
||||
if(MPIsFlagSetInOptions(MPEntrySearchDoublePasswords, self.searchContext.searchFlags)) {
|
||||
if(MPIsFlagSetInOptions(MPEntrySearchDoublePasswords, context.searchFlags)) {
|
||||
NSMutableDictionary *passwordToEntryMap = [[NSMutableDictionary alloc] initWithCapacity:100];
|
||||
/* Build up a usage map */
|
||||
for(KPKEntry *entry in self.root.searchableChildEntries) {
|
||||
@@ -155,7 +155,7 @@ NSString *const kMPDocumentSearchResultsKey = @"kMPDocumentSearchResul
|
||||
}
|
||||
return doublePasswords;
|
||||
}
|
||||
if(MPIsFlagSetInOptions(MPEntrySearchExpiredEntries, self.searchContext.searchFlags)) {
|
||||
if(MPIsFlagSetInOptions(MPEntrySearchExpiredEntries, context.searchFlags)) {
|
||||
NSPredicate *expiredPredicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
|
||||
KPKNode *node = evaluatedObject;
|
||||
return node.timeInfo.isExpired;
|
||||
@@ -163,7 +163,7 @@ NSString *const kMPDocumentSearchResultsKey = @"kMPDocumentSearchResul
|
||||
return [[self.root searchableChildEntries] filteredArrayUsingPredicate:expiredPredicate];
|
||||
}
|
||||
/* Filter using predicates */
|
||||
NSArray *predicates = [self _filterPredicatesWithString:self.searchContext.searchString];
|
||||
NSArray *predicates = [self _filterPredicatesWithString:context.searchString];
|
||||
if(predicates) {
|
||||
NSPredicate *fullFilter = [NSCompoundPredicate orPredicateWithSubpredicates:predicates];
|
||||
return [[self.root searchableChildEntries] filteredArrayUsingPredicate:fullFilter];
|
||||
@@ -194,7 +194,7 @@ NSString *const kMPDocumentSearchResultsKey = @"kMPDocumentSearchResul
|
||||
[prediactes addObject:[NSPredicate predicateWithFormat:@"SELF.notes CONTAINS[cd] %@", string]];
|
||||
}
|
||||
if(searchInAllAttributes) {
|
||||
[prediactes addObject:[NSPredicate predicateWithFormat:@"SELF.tags CONTAINS[cd] %@", string]];
|
||||
[prediactes addObject:[NSPredicate predicateWithFormat:@"SELF.tagsString CONTAINS[cd] %@", string]];
|
||||
[prediactes addObject:[NSPredicate predicateWithFormat:@"SELF.uuid.UUIDString CONTAINS[cd] %@", string]];
|
||||
|
||||
NSPredicate *allAttributesPredicate = [NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
|
||||
|
||||
@@ -92,6 +92,8 @@ FOUNDATION_EXPORT NSString *const MPDocumentGroupKey;
|
||||
|
||||
/*
|
||||
Search - see MPDocument+Search for further details
|
||||
|
||||
FIXME: Document is pinned to mode bases search. Wrong design!
|
||||
*/
|
||||
@property (nonatomic, readonly) BOOL hasSearch;
|
||||
@property (nonatomic, copy) MPEntrySearchContext *searchContext;
|
||||
@@ -163,7 +165,6 @@ FOUNDATION_EXPORT NSString *const MPDocumentGroupKey;
|
||||
- (void)deleteNode:(KPKNode *)node;
|
||||
- (void)duplicateEntryWithOptions:(KPKCopyOptions)options;
|
||||
|
||||
|
||||
#pragma mark Actions
|
||||
/**
|
||||
* Empties the Trash group. Removing all Groups and Entries inside. This action is not undo-able
|
||||
@@ -177,6 +178,7 @@ FOUNDATION_EXPORT NSString *const MPDocumentGroupKey;
|
||||
*/
|
||||
- (IBAction)createEntryFromTemplate:(id)sender;
|
||||
- (IBAction)duplicateEntry:(id)sender;
|
||||
- (IBAction)duplicateGroup:(id)sender;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou
|
||||
}
|
||||
|
||||
+ (BOOL)autosavesInPlace {
|
||||
return YES;
|
||||
return [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyEnableAutosave];
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
@@ -168,11 +168,19 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou
|
||||
NSRecoveryAttempterErrorKey : recovery
|
||||
};
|
||||
if(outError != NULL) {
|
||||
*outError = [NSError errorWithDomain:MPErrorDomain code:MPErrorNoPasswordOrKeyFile userInfo:userInfo];
|
||||
*outError = [NSError errorWithDomain:MPDefaultErrorDomain code:MPErrorNoPasswordOrKeyFile userInfo:userInfo];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (NSString *)fileNameExtensionForType:(NSString *)typeName saveOperation:(NSSaveOperationType)saveOperation {
|
||||
NSString *proposedExtension = [super fileNameExtensionForType:typeName saveOperation:saveOperation];
|
||||
if(!self.fileURL) {
|
||||
return proposedExtension;
|
||||
}
|
||||
return self.fileURL.pathExtension;
|
||||
}
|
||||
|
||||
- (NSData *)dataOfType:(NSString *)typeName error:(NSError * _Nullable __autoreleasing *)outError {
|
||||
if(self.encrypted) {
|
||||
NSLog(@"%@ should not be called on locked databases!", NSStringFromSelector(_cmd));
|
||||
@@ -181,7 +189,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou
|
||||
if(!self.compositeKey.hasPasswordOrKeyFile) {
|
||||
if(outError != NULL) {
|
||||
NSDictionary *userInfo = @{ NSLocalizedDescriptionKey: NSLocalizedString(@"WARNING_ON_SAVE_NO_PASSWORD_OR_KEY_SET", "") };
|
||||
*outError = [NSError errorWithDomain:MPErrorDomain code:0 userInfo:userInfo];
|
||||
*outError = [NSError errorWithDomain:MPDefaultErrorDomain code:0 userInfo:userInfo];
|
||||
}
|
||||
return nil; // Saving without a password/key is not possible
|
||||
}
|
||||
@@ -190,7 +198,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou
|
||||
if(format == KPKDatabaseFormatUnknown) {
|
||||
if(outError != NULL) {
|
||||
NSDictionary *userInfo = @{ NSLocalizedDescriptionKey: NSLocalizedString(@"UNKNOWN_FILE_VERSION", "") };
|
||||
*outError = [NSError errorWithDomain:MPErrorDomain code:0 userInfo:userInfo];
|
||||
*outError = [NSError errorWithDomain:MPDefaultErrorDomain code:0 userInfo:userInfo];
|
||||
}
|
||||
return nil; // We do not know what version to save!
|
||||
}
|
||||
@@ -828,7 +836,16 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou
|
||||
KPKEntry *duplicate = [entry copyWithTitle:nil options:options];
|
||||
[duplicate addToGroup:entry.parent];
|
||||
}
|
||||
[self.undoManager setActionName:[NSString stringWithFormat:NSLocalizedString(@"DUPLICATE_ENTRIES_%ld", @"Action name for duplicating entries"), self.selectedEntries.count]];
|
||||
[self.undoManager setActionName:[NSString stringWithFormat:NSLocalizedString(@"DUPLICATE_ENTRIES_ACTION_NAME", @"Action name for duplicating entries"), self.selectedEntries.count]];
|
||||
}
|
||||
|
||||
- (void)duplicateGroup:(id)sender {
|
||||
for(KPKGroup *group in self.selectedGroups) {
|
||||
KPKGroup *duplicate = [group copyWithTitle:nil options:kKPKCopyOptionNone];
|
||||
/* if group is root group, add the duplicate below */
|
||||
[duplicate addToGroup:(group.parent ? group.parent : group)];
|
||||
}
|
||||
[self.undoManager setActionName:[NSString stringWithFormat:NSLocalizedString(@"DUPLICATE_GROUPS_ACTION_NAME", @"Action name for duplicating groups"), self.selectedGroups.count]];
|
||||
}
|
||||
|
||||
#pragma mark Validation
|
||||
@@ -886,6 +903,9 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou
|
||||
valid &= targetEntries.count > 0;
|
||||
valid &= !self.historyEntry;
|
||||
break;
|
||||
case MPActionDuplicateGroup:
|
||||
valid &= targetGroups.count > 0;
|
||||
break;
|
||||
case MPActionEmptyTrash:
|
||||
valid &= (self.trash.groups.count + self.trash.entries.count) > 0;
|
||||
break;
|
||||
@@ -915,6 +935,10 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou
|
||||
case MPActionCopyAsReference:
|
||||
valid &= (nil != targetEntry);
|
||||
break;
|
||||
case MPActionShowGroupInOutline:
|
||||
valid &= (nil != targetEntry);
|
||||
valid &= self.hasSearch;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
@class MPOutlineViewController;
|
||||
@class MPToolbarDelegate;
|
||||
|
||||
@interface MPDocumentWindowController : NSWindowController
|
||||
@interface MPDocumentWindowController : NSWindowController <NSTouchBarDelegate>
|
||||
|
||||
@property (readonly, strong) MPPasswordInputController *passwordInputController;
|
||||
@property (readonly, strong) MPEntryViewController *entryViewController;
|
||||
@@ -39,8 +39,7 @@
|
||||
@property (readonly, strong) MPInspectorViewController *inspectorViewController;
|
||||
@property (readonly, strong) MPToolbarDelegate *toolbarDelegate;
|
||||
|
||||
#pragma mark Search
|
||||
- (NSSearchField *)searchField;
|
||||
@property (readonly, nonatomic, strong) NSSearchField *searchField;
|
||||
|
||||
- (void)showEntries;
|
||||
- (void)showPasswordInput;
|
||||
@@ -59,7 +58,8 @@
|
||||
- (IBAction)exportAsXML:(id)sender;
|
||||
- (IBAction)mergeWithOther:(id)sender;
|
||||
- (IBAction)importFromXML:(id)sender;
|
||||
- (IBAction)importFromPlugin:(id)sender;
|
||||
- (IBAction)importWithPlugin:(id)sender;
|
||||
- (IBAction)exportWithPlugin:(id)sender;
|
||||
|
||||
- (IBAction)lock:(id)sender;
|
||||
- (IBAction)createGroup:(id)sender;
|
||||
@@ -67,11 +67,11 @@
|
||||
- (IBAction)delete:(id)sender;
|
||||
|
||||
- (IBAction)duplicateEntryWithOptions:(id)sender;
|
||||
|
||||
- (IBAction)pickExpiryDate:(id)sender;
|
||||
|
||||
- (IBAction)performAutotypeForEntry:(id)sender;
|
||||
|
||||
- (IBAction)showGroupInOutline:(id)sender;
|
||||
|
||||
/* actions relayed to MPEntryViewController */
|
||||
- (IBAction)copyUsername:(id)sender;
|
||||
- (IBAction)copyPassword:(id)sender;
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
#import "MPSettingsHelper.h"
|
||||
#import "MPToolbarDelegate.h"
|
||||
#import "MPTitlebarColorAccessoryViewController.h"
|
||||
#import "MPTouchBarButtonCreator.h"
|
||||
#import "MPIconHelper.h"
|
||||
|
||||
#import "MPPluginHost.h"
|
||||
#import "MPPlugin.h"
|
||||
@@ -120,6 +122,11 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword);
|
||||
self.toolbar = [[NSToolbar alloc] initWithIdentifier:@"MainWindowToolbar"];
|
||||
self.toolbar.autosavesConfiguration = YES;
|
||||
self.toolbar.allowsUserCustomization = YES;
|
||||
if (@available(macOS 10.14, *)) {
|
||||
self.toolbar.centeredItemIdentifier = MPToolbarItemIdentifierSearch;
|
||||
} else {
|
||||
// to not do any magic here
|
||||
}
|
||||
self.toolbar.delegate = self.toolbarDelegate;
|
||||
self.window.toolbar = self.toolbar;
|
||||
self.toolbarDelegate.toolbar = self.toolbar;
|
||||
@@ -277,12 +284,12 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword);
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)importFromPlugin:(id)sender {
|
||||
- (void)importWithPlugin:(id)sender {
|
||||
if(![sender isKindOfClass:NSMenuItem.class]) {
|
||||
return;
|
||||
}
|
||||
NSMenuItem *menuItem = sender;
|
||||
if(![menuItem.representedObject isKindOfClass:NSDictionary.class]) {
|
||||
if(![menuItem.representedObject isKindOfClass:NSString.class]) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -290,12 +297,39 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword);
|
||||
if(!sheetWindow) {
|
||||
return;
|
||||
}
|
||||
MPPlugin<MPImportPlugin> *importPlugin;
|
||||
NSString *bundleIdentifier = menuItem.representedObject;
|
||||
MPPlugin<MPImportPlugin> *importPlugin = (MPPlugin<MPImportPlugin> *)[MPPluginHost.sharedHost pluginWithBundleIdentifier:bundleIdentifier];
|
||||
NSOpenPanel *openPanel = NSOpenPanel.openPanel;
|
||||
[importPlugin prepareOpenPanel:openPanel];
|
||||
[openPanel beginSheetModalForWindow:sheetWindow completionHandler:^(NSModalResponse result) {
|
||||
KPKTree *importedTree = [importPlugin treeForRunningOpenPanel:openPanel withResponse:result];
|
||||
[self.document importTree:importedTree];
|
||||
if(result == NSModalResponseOK) {
|
||||
KPKTree *importedTree = [importPlugin treeForRunningOpenPanel:openPanel];
|
||||
[self.document importTree:importedTree];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)exportWithPlugin:(id)sender {
|
||||
if(![sender isKindOfClass:NSMenuItem.class]) {
|
||||
return;
|
||||
}
|
||||
NSMenuItem *menuItem = sender;
|
||||
if(![menuItem.representedObject isKindOfClass:NSString.class]) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSWindow *sheetWindow = ((MPDocument *)self.document).windowForSheet;
|
||||
if(!sheetWindow) {
|
||||
return;
|
||||
}
|
||||
NSString *bundleIdentifier = menuItem.representedObject;
|
||||
MPPlugin<MPExportPlugin> *exportPlugin = (MPPlugin<MPExportPlugin> *)[MPPluginHost.sharedHost pluginWithBundleIdentifier:bundleIdentifier];
|
||||
NSSavePanel *savePanel = NSSavePanel.savePanel;
|
||||
[exportPlugin prepareSavePanel:savePanel];
|
||||
[savePanel beginSheetModalForWindow:sheetWindow completionHandler:^(NSModalResponse result) {
|
||||
if(result == NSModalResponseOK) {
|
||||
[exportPlugin exportTree:((MPDocument *)self.document).tree forRunningSavePanel:savePanel];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
@@ -462,7 +496,7 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword);
|
||||
id<MPTargetNodeResolving> entryResolver = [NSApp targetForAction:@selector(currentTargetEntries)];
|
||||
NSArray *entries = entryResolver.currentTargetEntries;
|
||||
if(entries.count == 1) {
|
||||
[[MPAutotypeDaemon defaultDaemon] performAutotypeForEntry:entries.firstObject];
|
||||
[MPAutotypeDaemon.defaultDaemon performAutotypeForEntry:entries.firstObject];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -543,6 +577,14 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword);
|
||||
[contentView layoutSubtreeIfNeeded];
|
||||
}
|
||||
|
||||
- (void)showGroupInOutline:(id)sender {
|
||||
NSArray<KPKEntry *> *targetEntries = self.entryViewController.currentTargetEntries;
|
||||
if(targetEntries.count != 1) {
|
||||
return;
|
||||
}
|
||||
[self.outlineViewController selectGroup:targetEntries.lastObject.parent];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Actions forwarded to MPEntryViewController
|
||||
- (void)copyUsername:(id)sender {
|
||||
@@ -652,4 +694,97 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword);
|
||||
return (nil != inspectorView.superview);
|
||||
}
|
||||
|
||||
- (NSTouchBar *)makeTouchBar {
|
||||
NSTouchBar *touchBar = [[NSTouchBar alloc] init];
|
||||
touchBar.delegate = self;
|
||||
touchBar.customizationIdentifier = MPTouchBarCustomizationIdentifierDocument;
|
||||
NSArray<NSTouchBarItemIdentifier> *defaultItemIdentifiers = @[MPTouchBarItemIdentifierSearch, MPTouchBarItemIdentifierEditPopover, MPTouchBarItemIdentifierCopyUsername, MPTouchBarItemIdentifierCopyPassword, MPTouchBarItemIdentifierPerformAutotype, NSTouchBarItemIdentifierFlexibleSpace, MPTouchBarItemIdentifierLock];
|
||||
touchBar.defaultItemIdentifiers = defaultItemIdentifiers;
|
||||
touchBar.customizationAllowedItemIdentifiers = defaultItemIdentifiers;
|
||||
return touchBar;
|
||||
}
|
||||
|
||||
- (NSTouchBarItem *)touchBar:(NSTouchBar *)touchBar makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier API_AVAILABLE(macos(10.12.2)) {
|
||||
#pragma mark primary touchbar elements
|
||||
if([identifier isEqualToString:MPTouchBarItemIdentifierSearch]) {
|
||||
return [MPTouchBarButtonCreator touchBarButtonWithImage:[NSImage imageNamed:NSImageNameTouchBarSearchTemplate]
|
||||
identifier:MPTouchBarItemIdentifierSearch
|
||||
target:self
|
||||
selector:@selector(focusSearchField)
|
||||
customizationLabel:NSLocalizedString(@"TOUCHBAR_SEARCH","Touchbar button label for searching the database")];
|
||||
}
|
||||
|
||||
if([identifier isEqualToString:MPTouchBarItemIdentifierEditPopover]) {
|
||||
NSTouchBar *secondaryTouchBar = [[NSTouchBar alloc] init];
|
||||
secondaryTouchBar.delegate = self;
|
||||
secondaryTouchBar.defaultItemIdentifiers = @[MPTouchBarItemIdentifierNewEntry, MPTouchBarItemIdentifierNewGroup, MPTouchBarItemIdentifierDelete];
|
||||
return [MPTouchBarButtonCreator popoverTouchBarButton:NSLocalizedString(@"TOUCHBAR_EDIT","Touchbar button label for opening the popover to edit")
|
||||
identifier:MPTouchBarItemIdentifierEditPopover
|
||||
popoverTouchBar:secondaryTouchBar
|
||||
customizationLabel:NSLocalizedString(@"TOUCHBAR_EDIT","Touchbar button label for opening the popover to edit")];
|
||||
}
|
||||
|
||||
if([identifier isEqualToString:MPTouchBarItemIdentifierCopyUsername]) {
|
||||
return [MPTouchBarButtonCreator touchBarButtonWithTitle:NSLocalizedString(@"TOUCHBAR_COPY_USERNAME","Touchbar button label for copying the username")
|
||||
identifier:MPTouchBarItemIdentifierCopyUsername
|
||||
target:self
|
||||
selector:@selector(copyUsername:)
|
||||
customizationLabel:NSLocalizedString(@"TOUCHBAR_COPY_USERNAME","Touchbar button label for copying the username")];
|
||||
}
|
||||
|
||||
if([identifier isEqualToString:MPTouchBarItemIdentifierCopyPassword]) {
|
||||
return [MPTouchBarButtonCreator touchBarButtonWithTitle:NSLocalizedString(@"TOUCHBAR_COPY_PASSWORD","Touchbar button label for copying the password")
|
||||
identifier:MPTouchBarItemIdentifierCopyPassword
|
||||
target:self
|
||||
selector:@selector(copyPassword:)
|
||||
customizationLabel:NSLocalizedString(@"TOUCHBAR_COPY_PASSWORD","Touchbar button label for copying the password")];
|
||||
}
|
||||
|
||||
if([identifier isEqualToString:MPTouchBarItemIdentifierPerformAutotype]) {
|
||||
return [MPTouchBarButtonCreator touchBarButtonWithTitle:NSLocalizedString(@"TOUCHBAR_PERFORM_AUTOTYPE","Touchbar button label for performing autotype")
|
||||
identifier:MPTouchBarItemIdentifierPerformAutotype
|
||||
target:self
|
||||
selector:@selector(performAutotypeForEntry:)
|
||||
customizationLabel:NSLocalizedString(@"TOUCHBAR_PERFORM_AUTOTYPE","Touchbar button label for performing autotype")];
|
||||
}
|
||||
if([identifier isEqualToString:MPTouchBarItemIdentifierLock]) {
|
||||
return [MPTouchBarButtonCreator touchBarButtonWithImage:[NSImage imageNamed:NSImageNameLockLockedTemplate]
|
||||
identifier:MPTouchBarItemIdentifierLock
|
||||
target:self
|
||||
selector:@selector(lock:)
|
||||
customizationLabel:NSLocalizedString(@"TOUCHBAR_LOCK_DATABASE","Touchbar button label for locking the database")];
|
||||
}
|
||||
#pragma mark secondary/popover touchbar elements
|
||||
if([identifier isEqualToString:MPTouchBarItemIdentifierNewEntry]) {
|
||||
return [MPTouchBarButtonCreator touchBarButtonWithTitleAndImage:NSLocalizedString(@"TOUCHBAR_NEW_ENTRY","Touchbar button label for creating a new item")
|
||||
identifier:MPTouchBarItemIdentifierNewEntry
|
||||
image:[MPIconHelper icon:MPIconAddEntry]
|
||||
target:self
|
||||
selector:@selector(createEntry:)
|
||||
customizationLabel:NSLocalizedString(@"TOUCHBAR_NEW_ENTRY","Touchbar button label for creating a new item")];
|
||||
}
|
||||
if([identifier isEqualToString:MPTouchBarItemIdentifierNewGroup]) {
|
||||
return [MPTouchBarButtonCreator touchBarButtonWithTitleAndImage:NSLocalizedString(@"TOUCHBAR_NEW_GROUP","Touchbar button label for creating a new group")
|
||||
identifier:MPTouchBarItemIdentifierNewGroup
|
||||
image:[MPIconHelper icon:MPIconAddFolder]
|
||||
target:self
|
||||
selector:@selector(createGroup:)
|
||||
customizationLabel:NSLocalizedString(@"TOUCHBAR_NEW_GROUP","Touchbar button label for creating a new group")];
|
||||
}
|
||||
if([identifier isEqualToString:MPTouchBarItemIdentifierDelete]) {
|
||||
return [MPTouchBarButtonCreator touchBarButtonWithTitleAndImageAndColor:NSLocalizedString(@"TOUCHBAR_DELETE","Touchbar button label for deleting elements")
|
||||
identifier:MPTouchBarItemIdentifierDelete
|
||||
image:[MPIconHelper icon:MPIconTrash]
|
||||
color:NSColor.systemRedColor
|
||||
target:self
|
||||
selector:@selector(delete:)
|
||||
customizationLabel:NSLocalizedString(@"TOUCHBAR_DELETE","Touchbar button label for deleting elements")];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)focusSearchField {
|
||||
[self.window makeFirstResponder:self.searchField];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
/**
|
||||
Delegate is used for context menus that are show in the entries table
|
||||
Delegate is used for context menus that are show in the entries table as well as the items menu in the main menu
|
||||
*/
|
||||
@interface MPEntryContextMenuDelegate : NSObject <NSMenuDelegate>
|
||||
|
||||
|
||||
@@ -201,7 +201,7 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
|
||||
}
|
||||
- (void)removeCustomField:(id)sender {
|
||||
NSInteger rowIndex = [self.customFieldsTableView rowForView:sender];
|
||||
NSAssert(rowIndex > 0 && rowIndex < self.representedEntry.customAttributes.count, @"Invalid custom attribute index.");
|
||||
NSAssert(rowIndex >= 0 && rowIndex < self.representedEntry.customAttributes.count, @"Invalid custom attribute index.");
|
||||
KPKAttribute *attribute = self.representedEntry.customAttributes[rowIndex];
|
||||
[self.observer willChangeModelProperty];
|
||||
[self.representedEntry removeCustomAttribute:attribute];
|
||||
@@ -297,7 +297,7 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
|
||||
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
|
||||
switch([MPActionHelper typeForAction:menuItem.action]) {
|
||||
case MPActionToggleQuicklook: {
|
||||
BOOL enabled = [[NSUserDefaults standardUserDefaults] boolForKey:kMPSettingsKeyEnableQuicklookPreview];
|
||||
BOOL enabled = [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyEnableQuicklookPreview];
|
||||
return enabled ? [self acceptsPreviewPanelControl:nil] : NO;
|
||||
case MPActionRemoveAttachment:
|
||||
return !self.representedEntry.isHistory;
|
||||
@@ -323,16 +323,16 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
|
||||
|
||||
- (void)endPreviewPanelControl:(QLPreviewPanel *)panel {
|
||||
MPTemporaryFileStorage *storage = (MPTemporaryFileStorage *)panel.dataSource;
|
||||
[[MPTemporaryFileStorageCenter defaultCenter] unregisterStorage:storage];
|
||||
[MPTemporaryFileStorageCenter.defaultCenter unregisterStorage:storage];
|
||||
}
|
||||
|
||||
- (void)_updatePreviewItemForPanel:(QLPreviewPanel *)panel {
|
||||
NSInteger row = [self.attachmentTableView selectedRow];
|
||||
NSInteger row = self.attachmentTableView.selectedRow;
|
||||
NSAssert(row > -1, @"Row needs to be selected");
|
||||
KPKBinary *binary = self.representedEntry.binaries[row];
|
||||
MPTemporaryFileStorage *oldStorage = (MPTemporaryFileStorage *)panel.dataSource;
|
||||
[[MPTemporaryFileStorageCenter defaultCenter] unregisterStorage:oldStorage];
|
||||
panel.dataSource = [[MPTemporaryFileStorageCenter defaultCenter] storageForBinary:binary];
|
||||
[MPTemporaryFileStorageCenter.defaultCenter unregisterStorage:oldStorage];
|
||||
panel.dataSource = [MPTemporaryFileStorageCenter.defaultCenter storageForBinary:binary];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
@@ -557,6 +557,7 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
|
||||
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;
|
||||
[self.addCustomFieldButton setEnabled:NO forSegment:MPContextButtonSegmentContextButton];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@@ -153,7 +153,8 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
|
||||
attachmentsColumn.minWidth = 40.0;
|
||||
modifiedColumn.minWidth = 40.0;
|
||||
historyColumn.minWidth = 40.0;
|
||||
indexColumn.minWidth = 16.0;
|
||||
indexColumn.minWidth = 27.0;
|
||||
indexColumn.maxWidth = 27.0;
|
||||
[self.entryTable addTableColumn:notesColumn];
|
||||
[self.entryTable addTableColumn:attachmentsColumn];
|
||||
[self.entryTable addTableColumn:modifiedColumn];
|
||||
@@ -180,6 +181,7 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
|
||||
modifiedColumn.sortDescriptorPrototype = [NSSortDescriptor sortDescriptorWithKey:timeInfoModificationTimeKeyPath ascending:YES selector:@selector(compare:)];
|
||||
|
||||
indexColumn.headerCell.stringValue = @"";
|
||||
indexColumn.headerToolTip = NSLocalizedString(@"ENTRY_INDEX_COLUMN_TOOLTIP", "Tooltip displayed on the index header cell");
|
||||
parentColumn.headerCell.stringValue = NSLocalizedString(@"GROUP", "Group column title");
|
||||
titleColumn.headerCell.stringValue = NSLocalizedString(@"TITLE", "Title column title");
|
||||
userNameColumn.headerCell.stringValue = NSLocalizedString(@"USERNAME", "Username column title");
|
||||
@@ -461,6 +463,7 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
|
||||
|
||||
- (void)_didAddItem:(NSNotification *)notification {
|
||||
MPDocument *document = notification.object;
|
||||
// FIXME: UI should know search state not document!
|
||||
if(document.hasSearch) {
|
||||
return; // Search should not react to new Entries as it's displaying search results
|
||||
}
|
||||
@@ -599,7 +602,7 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
|
||||
- (void)_setupEntryMenu {
|
||||
|
||||
NSMenu *menu = [[NSMenu alloc] init];
|
||||
NSArray *items = [MPContextMenuHelper contextMenuItemsWithItems:MPContextMenuFull];
|
||||
NSArray *items = [MPContextMenuHelper contextMenuItemsWithItems:MPContextMenuFull|MPContextMenuShowGroupInOutline];
|
||||
for(NSMenuItem *item in items) {
|
||||
[menu addItem:item];
|
||||
}
|
||||
@@ -746,14 +749,14 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
|
||||
}
|
||||
|
||||
- (void)_columnDoubleClick:(id)sender {
|
||||
if(0 == [[self.entryArrayController arrangedObjects] count]) {
|
||||
if(0 == [self.entryArrayController.arrangedObjects count]) {
|
||||
return; // No data available
|
||||
}
|
||||
NSInteger columnIndex = [self.entryTable clickedColumn];
|
||||
NSInteger columnIndex = self.entryTable.clickedColumn;
|
||||
if(columnIndex < 0 || columnIndex >= self.entryTable.tableColumns.count) {
|
||||
return; // No Column to use
|
||||
}
|
||||
NSTableColumn *column = self.entryTable.tableColumns[self.entryTable.clickedColumn];
|
||||
NSTableColumn *column = self.entryTable.tableColumns[columnIndex];
|
||||
NSString *identifier = column.identifier;
|
||||
if([identifier isEqualToString:MPEntryTableTitleColumnIdentifier]) {
|
||||
[self _executeTitleColumnDoubleClick];
|
||||
@@ -767,9 +770,17 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
|
||||
else if([identifier isEqualToString:MPEntryTableURLColumnIdentifier]) {
|
||||
[self _executeURLColumnDoubleClick];
|
||||
}
|
||||
else if([identifier isEqualToString:MPEntryTableParentColumnIdentifier]) {
|
||||
[self _executeGroupColumnDoubleClick];
|
||||
}
|
||||
// TODO: Add more actions for new columns
|
||||
}
|
||||
|
||||
- (void)_executeGroupColumnDoubleClick {
|
||||
id target = [NSApp targetForAction:@selector(showGroupInOutline:)];
|
||||
[target showGroupInOutline:self];
|
||||
}
|
||||
|
||||
- (void)_executeTitleColumnDoubleClick {
|
||||
MPDoubleClickTitleAction action = [NSUserDefaults.standardUserDefaults integerForKey:kMPSettingsKeyDoubleClickTitleAction];
|
||||
switch(action) {
|
||||
@@ -797,4 +808,5 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface MPPluginTabelCellView : NSTableCellView
|
||||
@interface MPExtendedTableCellView : NSTableCellView
|
||||
|
||||
@property (strong) IBOutlet NSTextField *addionalTextField;
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#import "MPPluginTabelCellView.h"
|
||||
#import "MPExtendedTableCellView.h"
|
||||
|
||||
@implementation MPPluginTabelCellView
|
||||
@implementation MPExtendedTableCellView
|
||||
|
||||
- (void)setBackgroundStyle:(NSBackgroundStyle)backgroundStyle {
|
||||
super.backgroundStyle = backgroundStyle;
|
||||
@@ -24,17 +24,18 @@
|
||||
#import "MPViewController.h"
|
||||
#import "MPPreferencesTab.h"
|
||||
|
||||
@interface MPGeneralSettingsController : MPViewController <MPPreferencesTab>
|
||||
@interface MPGeneralPreferencesController : MPViewController <MPPreferencesTab>
|
||||
|
||||
@property (weak) IBOutlet NSButton *clearPasteboardOnQuitCheckButton;
|
||||
@property (weak) IBOutlet NSPopUpButton *clearPasteboardTimeoutPopup;
|
||||
@property (strong) IBOutlet NSButton *clearPasteboardOnQuitCheckButton;
|
||||
@property (strong) IBOutlet NSPopUpButton *clearPasteboardTimeoutPopup;
|
||||
@property (strong) IBOutlet NSButton *preventUniversalClipboardSupportCheckButton;
|
||||
@property (weak) IBOutlet NSPopUpButton *idleTimeOutPopup;
|
||||
@property (weak) IBOutlet NSButton *lockOnSleepCheckButton;
|
||||
@property (weak) IBOutlet NSButton *lockOnLogoutCheckButton;
|
||||
@property (weak) IBOutlet NSButton *reopenLastDatabase;
|
||||
@property (weak) IBOutlet NSButton *createUntitledOnActivation;
|
||||
@property (weak) IBOutlet NSButton *rememberKeyFileCheckButton;
|
||||
@property (weak) IBOutlet NSPopUpButton *fileChangeStrategyPopup;
|
||||
@property (strong) IBOutlet NSPopUpButton *idleTimeOutPopup;
|
||||
@property (strong) IBOutlet NSButton *lockOnSleepCheckButton;
|
||||
@property (strong) IBOutlet NSButton *lockOnLogoutCheckButton;
|
||||
@property (strong) IBOutlet NSButton *lockOnScreenSleepCheckButton;
|
||||
@property (strong) IBOutlet NSButton *reopenLastDatabase;
|
||||
@property (strong) IBOutlet NSButton *enableAutosaveCheckButton;
|
||||
@property (strong) IBOutlet NSButton *rememberKeyFileCheckButton;
|
||||
@property (strong) IBOutlet NSPopUpButton *fileChangeStrategyPopup;
|
||||
|
||||
@end
|
||||
@@ -20,20 +20,18 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#import "MPGeneralSettingsController.h"
|
||||
#import "MPGeneralPreferencesController.h"
|
||||
#import "MPSettingsHelper.h"
|
||||
#import "MPIconHelper.h"
|
||||
|
||||
NSString *const MPGeneralSetingsIdentifier = @"GeneralSettingsTab";
|
||||
|
||||
@implementation MPGeneralSettingsController
|
||||
@implementation MPGeneralPreferencesController
|
||||
|
||||
- (NSString *)nibName {
|
||||
return @"GeneralSettings";
|
||||
return @"GeneralPreferences";
|
||||
}
|
||||
|
||||
- (NSString *)identifier {
|
||||
return MPGeneralSetingsIdentifier;
|
||||
return @"GeneralPreferences";
|
||||
}
|
||||
|
||||
- (NSImage *)image {
|
||||
@@ -41,7 +39,7 @@ NSString *const MPGeneralSetingsIdentifier = @"GeneralSettingsTab";
|
||||
}
|
||||
|
||||
- (NSString *)label {
|
||||
return NSLocalizedString(@"GENERAL_SETTINGS", @"General Settings Label");
|
||||
return NSLocalizedString(@"GENERAL_PREFERENCES", @"General Settings Label");
|
||||
}
|
||||
|
||||
- (void)viewDidLoad {
|
||||
@@ -52,10 +50,11 @@ NSString *const MPGeneralSetingsIdentifier = @"GeneralSettingsTab";
|
||||
[self.preventUniversalClipboardSupportCheckButton bind:NSValueBinding toObject:defaultsController withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyPreventUniversalClipboard] options:nil];
|
||||
[self.lockOnSleepCheckButton bind:NSValueBinding toObject:defaultsController withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyLockOnSleep] options:nil];
|
||||
[self.lockOnLogoutCheckButton bind:NSValueBinding toObject:defaultsController withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingskeyLockOnLogout] options:nil];
|
||||
[self.lockOnScreenSleepCheckButton bind:NSValueBinding toObject:defaultsController withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingskeyLockOnScreenSleep] options:nil];
|
||||
[self.idleTimeOutPopup bind:NSSelectedTagBinding toObject:defaultsController withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyIdleLockTimeOut] options:nil];
|
||||
[self.reopenLastDatabase bind:NSValueBinding toObject:defaultsController withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyReopenLastDatabaseOnLaunch] options:nil];
|
||||
[self.enableAutosaveCheckButton bind:NSValueBinding toObject:defaultsController withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyEnableAutosave] options:nil];
|
||||
[self.rememberKeyFileCheckButton bind:NSValueBinding toObject:defaultsController withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyRememberKeyFilesForDatabases] options:nil];
|
||||
[self.createUntitledOnActivation setState:NSOffState]; //kMPSettingsKeyOpenEmptyDatabaseOnLaunch
|
||||
|
||||
/* File Change Strategy Menu */
|
||||
NSDictionary *fileChangeStragegyDict = @{ @(MPFileChangeStrategyAsk) : NSLocalizedString(@"FILE_CHANGE_STRATEGY_ASK", @"External file change strategy option: ask what to do"),
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
@class DDHotKeyTextField;
|
||||
|
||||
@interface MPIntegrationSettingsController : MPViewController <MPPreferencesTab, NSTextFieldDelegate>
|
||||
@interface MPIntegrationPreferencesController : MPViewController <MPPreferencesTab, NSTextFieldDelegate>
|
||||
/* Autotype */
|
||||
@property (strong) IBOutlet NSButton *enableGlobalAutotypeCheckBox;
|
||||
@property (strong) IBOutlet DDHotKeyTextField *hotKeyTextField;
|
||||
@@ -44,6 +44,6 @@
|
||||
/* Preview */
|
||||
@property (strong) IBOutlet NSButton *enableQuicklookCheckBox;
|
||||
|
||||
- (IBAction)openAccessibiltyPreferences:(id)sender;
|
||||
- (IBAction)runAutotypeDoctor:(id)sender;
|
||||
|
||||
@end
|
||||
@@ -20,25 +20,25 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#import "MPIntegrationSettingsController.h"
|
||||
#import "MPIntegrationPreferencesController.h"
|
||||
#import "MPSettingsHelper.h"
|
||||
#import "MPIconHelper.h"
|
||||
#import "MPAutotypeDaemon.h"
|
||||
#import "MPAutotypeDoctor.h"
|
||||
|
||||
#import "DDHotKeyCenter.h"
|
||||
#import "DDHotKey+MacPassAdditions.h"
|
||||
#import "DDHotKeyTextField.h"
|
||||
|
||||
@interface MPIntegrationSettingsController ()
|
||||
@interface MPIntegrationPreferencesController ()
|
||||
|
||||
@property (nonatomic, strong) DDHotKey *hotKey;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MPIntegrationSettingsController
|
||||
@implementation MPIntegrationPreferencesController
|
||||
|
||||
- (NSString *)nibName {
|
||||
return @"IntegrationSettings";
|
||||
return @"IntegrationPreferences";
|
||||
}
|
||||
|
||||
- (NSString *)identifier {
|
||||
@@ -105,7 +105,8 @@
|
||||
}
|
||||
|
||||
- (void)_updateAccessabilityWarning {
|
||||
BOOL hasAutotypeSupport = MPAutotypeDaemon.defaultDaemon.autotypeSupported;
|
||||
|
||||
BOOL hasAutotypeSupport = MPAutotypeDoctor.defaultDoctor.hasNecessaryAutotypePermissions;
|
||||
|
||||
if(hasAutotypeSupport) {
|
||||
[self.autotypeStackView setVisibilityPriority:NSStackViewVisibilityPriorityNotVisible forView:self.autotypeWarningTextField];
|
||||
@@ -117,7 +118,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (void)openAccessibiltyPreferences:(id)sender {
|
||||
[MPAutotypeDaemon.defaultDaemon openAccessibiltyPreferences];
|
||||
- (void)runAutotypeDoctor:(id)sender {
|
||||
[MPAutotypeDoctor.defaultDoctor runChecksAndPresentResults];
|
||||
}
|
||||
@end
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
@property (nonatomic,assign) BOOL lockOnSleep;
|
||||
@property (nonatomic,assign) BOOL lockOnLogout;
|
||||
@property (nonatomic,assign) BOOL lockOnScreenSleep;
|
||||
@property (nonatomic,assign) NSUInteger idleLockTime;
|
||||
@property (nonatomic,strong) id localEventHandler;
|
||||
@property (nonatomic,strong) NSTimer *idleCheckTimer;
|
||||
@@ -59,6 +60,7 @@ static MPLockDaemon *_sharedInstance;
|
||||
[self bind:NSStringFromSelector(@selector(lockOnSleep)) toObject:defaultsController withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyLockOnSleep] options:nil];
|
||||
[self bind:NSStringFromSelector(@selector(idleLockTime)) toObject:defaultsController withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyIdleLockTimeOut] options:nil];
|
||||
[self bind:NSStringFromSelector(@selector(lockOnLogout)) toObject:defaultsController withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingskeyLockOnLogout] options:nil];
|
||||
[self bind:NSStringFromSelector(@selector(lockOnScreenSleep)) toObject:defaultsController withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingskeyLockOnScreenSleep] options:nil];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -95,6 +97,18 @@ static MPLockDaemon *_sharedInstance;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setLockOnScreenSleep:(BOOL)lockOnScreenSleep {
|
||||
if(_lockOnScreenSleep != lockOnScreenSleep) {
|
||||
_lockOnScreenSleep = lockOnScreenSleep;
|
||||
if(_lockOnScreenSleep) {
|
||||
[NSWorkspace.sharedWorkspace.notificationCenter addObserver:self selector:@selector(_willScreenSleepNotification:) name:NSWorkspaceScreensDidSleepNotification object:nil];
|
||||
}
|
||||
else {
|
||||
[NSWorkspace.sharedWorkspace.notificationCenter removeObserver:self name:NSWorkspaceScreensDidSleepNotification object:nil];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setIdleLockTime:(NSUInteger)idleLockTime {
|
||||
if(_idleLockTime != idleLockTime) {
|
||||
_idleLockTime = idleLockTime;
|
||||
@@ -113,6 +127,9 @@ static MPLockDaemon *_sharedInstance;
|
||||
- (void)_willSleepNotification:(NSNotification *)notification {
|
||||
[((MPAppDelegate *)NSApp.delegate) lockAllDocuments];
|
||||
}
|
||||
- (void)_willScreenSleepNotification:(NSNotification *)notification {
|
||||
[((MPAppDelegate *)NSApp.delegate) lockAllDocuments];
|
||||
}
|
||||
|
||||
- (void)_checkIdleTime:(NSTimer *)timer {
|
||||
if(timer != self.idleCheckTimer) {
|
||||
|
||||
@@ -57,7 +57,7 @@ NSString *const _MPOutlineMenuTemplate = @"Template";
|
||||
|
||||
if( [item isKindOfClass:KPKGroup.class]) {
|
||||
KPKGroup *group = (KPKGroup *)item;
|
||||
MPDocument *document = [NSDocumentController sharedDocumentController].currentDocument;
|
||||
MPDocument *document = NSDocumentController.sharedDocumentController.currentDocument;
|
||||
if(group && document.root == group ) {
|
||||
|
||||
}
|
||||
|
||||
@@ -26,12 +26,14 @@
|
||||
APPKIT_EXTERN NSString *const MPOutlineViewDidChangeGroupSelection;
|
||||
|
||||
@class MPDocument;
|
||||
@class KPKGroup;
|
||||
|
||||
@interface MPOutlineViewController : MPViewController <MPTargetNodeResolving, NSOutlineViewDelegate, NSMenuDelegate>
|
||||
|
||||
- (void)clearSelection;
|
||||
- (void)showOutline;
|
||||
- (void)registerNotificationsForDocument:(MPDocument *)document;
|
||||
- (void)selectGroup:(KPKGroup *)group;
|
||||
|
||||
/**
|
||||
* Retrieves the current item for the current mouse location
|
||||
|
||||
@@ -143,6 +143,23 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
|
||||
}
|
||||
}
|
||||
|
||||
- (void)selectGroup:(KPKGroup *)group {
|
||||
NSMutableArray *parents = [[NSMutableArray alloc] init];
|
||||
NSUUID *groupUUID = group.uuid;
|
||||
while(group.parent) {
|
||||
[parents insertObject:group.parent atIndex:0];
|
||||
group = group.parent;
|
||||
}
|
||||
NSTreeNode *node = [self.outlineView itemAtRow:0];
|
||||
for(KPKGroup *group in parents) {
|
||||
NSUInteger row = [self _rowForUUID:group.uuid node:node];
|
||||
[self.outlineView expandItem:[self.outlineView itemAtRow:row]];
|
||||
}
|
||||
NSUInteger rowToSelect = [self _rowForUUID:groupUUID node:node];
|
||||
[self.outlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:rowToSelect] byExtendingSelection:NO];
|
||||
[self.outlineView scrollRowToVisible:rowToSelect];
|
||||
}
|
||||
|
||||
- (void)_expandItems:(NSTreeNode *)node {
|
||||
id nodeItem = node.representedObject;
|
||||
if([nodeItem isKindOfClass:KPKTree.class]) {
|
||||
|
||||
@@ -60,10 +60,14 @@
|
||||
self.window.alphaValue = 0;
|
||||
self.window.opaque = NO;
|
||||
self.window.hasShadow = YES;
|
||||
self.window.backgroundColor = NSColor.clearColor;
|
||||
|
||||
self.textField.cell.backgroundStyle = NSBackgroundStyleLowered;
|
||||
self.imageView.cell.backgroundStyle = NSBackgroundStyleDark;
|
||||
self.imageView.cell.backgroundStyle = NSBackgroundStyleEmphasized;
|
||||
((NSImageCell *)self.imageView.cell).imageAlignment = NSImageAlignCenter;
|
||||
if (@available(macOS 10.14, *)) {
|
||||
self.imageView.contentTintColor = NSColor.textColor;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)displayOverlayImage:(NSImage *)imageOrNil label:(NSString *)labelOrNil atView:(NSView *)view {
|
||||
|
||||
@@ -241,6 +241,7 @@ typedef NS_ENUM(NSUInteger, MPPasswordRating) {
|
||||
[NSUserDefaults.standardUserDefaults setInteger:self.characterFlags forKey:kMPSettingsKeyPasswordCharacterFlags];
|
||||
[NSUserDefaults.standardUserDefaults setBool:self.useCustomString forKey:kMPSettingsKeyPasswordUseCustomString];
|
||||
[NSUserDefaults.standardUserDefaults setObject:self.customCharactersTextField.stringValue forKey:kMPSettingsKeyPasswordCustomString];
|
||||
[NSUserDefaults.standardUserDefaults setBool:self.ensureOccurance forKey:kMPSettingsKeyPasswordEnsureOccurance];
|
||||
}
|
||||
else {
|
||||
NSLog(@"Cannot set password generator defaults. Inconsistent state. Aborting.");
|
||||
@@ -274,10 +275,8 @@ typedef NS_ENUM(NSUInteger, MPPasswordRating) {
|
||||
}
|
||||
|
||||
- (void)setRepresentedObject:(id)representedObject {
|
||||
if(self.representedObject != representedObject) {
|
||||
self.useEntryDefaults = [self _hasValidDefaultsForCurrentEntry];
|
||||
}
|
||||
[super setRepresentedObject:representedObject];
|
||||
self.useEntryDefaults = [self _hasValidDefaultsForCurrentEntry];
|
||||
}
|
||||
|
||||
- (void)setPassword:(NSString *)password {
|
||||
@@ -307,6 +306,7 @@ typedef NS_ENUM(NSUInteger, MPPasswordRating) {
|
||||
|
||||
- (void)setEnsureOccurance:(BOOL)useCharacterFromEachGroup {
|
||||
if(self.ensureOccurance != useCharacterFromEachGroup) {
|
||||
self.setDefaultButton.enabled = YES;
|
||||
_ensureOccurance = useCharacterFromEachGroup;
|
||||
[self _resetCharacters];
|
||||
[self _generatePassword:nil];
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
@class KPKCompositeKey;
|
||||
|
||||
@interface MPPasswordInputController : MPViewController
|
||||
@interface MPPasswordInputController : MPViewController <NSTouchBarDelegate>
|
||||
|
||||
typedef BOOL (^passwordInputCompletionBlock)(NSString *password, NSURL *keyURL, BOOL didCancel, NSError *__autoreleasing*error);
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#import "MPDocument.h"
|
||||
#import "MPSettingsHelper.h"
|
||||
#import "MPPathControl.h"
|
||||
#import "MPTouchBarButtonCreator.h"
|
||||
|
||||
#import "HNHUi/HNHUi.h"
|
||||
|
||||
@@ -33,10 +34,12 @@
|
||||
|
||||
@interface MPPasswordInputController ()
|
||||
|
||||
@property (strong) NSButton *showPasswordButton;
|
||||
@property (weak) IBOutlet HNHUISecureTextField *passwordTextField;
|
||||
@property (weak) IBOutlet MPPathControl *keyPathControl;
|
||||
@property (weak) IBOutlet NSImageView *messageImageView;
|
||||
@property (weak) IBOutlet NSTextField *messageInfoTextField;
|
||||
@property (strong) IBOutlet NSTextField *keyFileWarningTextField;
|
||||
@property (weak) IBOutlet NSButton *togglePasswordButton;
|
||||
@property (weak) IBOutlet NSButton *enablePasswordCheckBox;
|
||||
@property (weak) IBOutlet NSButton *unlockButton;
|
||||
@@ -48,6 +51,7 @@
|
||||
@property (assign) BOOL showPassword;
|
||||
@property (nonatomic, assign) BOOL enablePassword;
|
||||
@property (copy) passwordInputCompletionBlock completionHandler;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MPPasswordInputController
|
||||
@@ -70,6 +74,7 @@
|
||||
}
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(_didSetKeyURL:) name:MPPathControlDidSetURLNotification object:self.keyPathControl];
|
||||
self.messageImageView.image = [NSImage imageNamed:NSImageNameCaution];
|
||||
[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];
|
||||
@@ -106,7 +111,7 @@
|
||||
self.passwordTextField.placeholderString = NSLocalizedString(@"PASSWORD_INPUT_ENTER_PASSWORD", "Placeholder in the unlock-password input field if password is enabled");
|
||||
}
|
||||
else {
|
||||
self.passwordTextField.placeholderString = NSLocalizedString(@"PASSWORD_INPUT_NO_PASSWORD", "Placeholder in the unlock-password input field if password is disabled");
|
||||
self.passwordTextField.placeholderString = NSLocalizedString(@"PASSWORD_INPUT_NO_PASSWORD", "Placeholder in the unlock-password input field if password is disabled");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,4 +182,61 @@
|
||||
self.messageInfoTextField.hidden = NO;
|
||||
}
|
||||
|
||||
|
||||
- (NSTouchBar *)makeTouchBar {
|
||||
NSTouchBar *touchBar = [[NSTouchBar alloc] init];
|
||||
touchBar.delegate = self;
|
||||
touchBar.customizationIdentifier = MPTouchBarCustomizationIdentifierPasswordInput;
|
||||
NSArray<NSTouchBarItemIdentifier> *defaultItemIdentifiers = @[MPTouchBarItemIdentifierShowPassword, MPTouchBarItemIdentifierChooseKeyfile, NSTouchBarItemIdentifierFlexibleSpace,MPTouchBarItemIdentifierUnlock];
|
||||
touchBar.defaultItemIdentifiers = defaultItemIdentifiers;
|
||||
touchBar.customizationAllowedItemIdentifiers = defaultItemIdentifiers;
|
||||
return touchBar;
|
||||
}
|
||||
|
||||
- (NSTouchBarItem *)touchBar:(NSTouchBar *)touchBar makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier API_AVAILABLE(macos(10.12.2)) {
|
||||
if (identifier == MPTouchBarItemIdentifierChooseKeyfile) {
|
||||
return [MPTouchBarButtonCreator touchBarButtonWithTitleAndImage:NSLocalizedString(@"TOUCHBAR_CHOOSE_KEYFILE","Touchbar button label for choosing the keyfile") identifier:MPTouchBarItemIdentifierChooseKeyfile image:[NSImage imageNamed:NSImageNameTouchBarFolderTemplate] target:self.keyPathControl selector:@selector(showOpenPanel:) customizationLabel:NSLocalizedString(@"TOUCHBAR_CHOOSE_KEYFILE","Touchbar button label for choosing the keyfile")];
|
||||
} else if (identifier == MPTouchBarItemIdentifierShowPassword) {
|
||||
NSTouchBarItem *item = [MPTouchBarButtonCreator touchBarButtonWithTitleAndImage:NSLocalizedString(@"TOUCHBAR_SHOW_PASSWORD","Touchbar button label for showing the password") identifier:MPTouchBarItemIdentifierShowPassword image:[NSImage imageNamed:NSImageNameTouchBarQuickLookTemplate] target:self selector:@selector(toggleShowPassword) customizationLabel:NSLocalizedString(@"TOUCHBAR_SHOW_PASSWORD","Touchbar button label for showing the password")];
|
||||
_showPasswordButton = (NSButton *) item.view;
|
||||
return item;
|
||||
} else if (identifier == MPTouchBarItemIdentifierUnlock) {
|
||||
return [MPTouchBarButtonCreator touchBarButtonWithImage:[NSImage imageNamed:NSImageNameLockUnlockedTemplate] identifier:MPTouchBarItemIdentifierUnlock target:self selector:@selector(_submit:) customizationLabel:NSLocalizedString(@"TOUCHBAR_UNLOCK_DATABASE","Touchbar button label for unlocking the database")];
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)toggleShowPassword {
|
||||
self.showPassword = !self.showPassword;
|
||||
if (@available(macOS 10.12.2, *)) {
|
||||
_showPasswordButton.bezelColor = self.showPassword ? [NSColor selectedControlColor] : [NSColor controlColor];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_didSetKeyURL:(NSNotification *)notification {
|
||||
if(notification.object != self.keyPathControl) {
|
||||
return; // wrong sender
|
||||
}
|
||||
NSDocument *document = (NSDocument *)self.windowController.document;
|
||||
NSData *keyFileData = [NSData dataWithContentsOfURL:self.keyPathControl.URL];
|
||||
KPKFileVersion keyFileVersion = [KPKFormat.sharedFormat fileVersionForData:keyFileData];
|
||||
BOOL isKdbDatabaseFile = (keyFileVersion.format != KPKDatabaseFormatUnknown);
|
||||
if(isKdbDatabaseFile) {
|
||||
if([document.fileURL isEqual:self.keyPathControl.URL]) {
|
||||
self.keyFileWarningTextField.stringValue = NSLocalizedString(@"WARNING_CURRENT_DATABASE_FILE_SELECTED_AS_KEY_FILE", "Error message displayed when the current database file is also set as the key file");
|
||||
self.keyFileWarningTextField.hidden = NO;
|
||||
}
|
||||
else {
|
||||
self.keyFileWarningTextField.stringValue = NSLocalizedString(@"WARNING_DATABASE_FILE_SELECTED_AS_KEY_FILE", "Error message displayed when a keepass database file is set as the key file");
|
||||
self.keyFileWarningTextField.hidden = NO;
|
||||
}
|
||||
}
|
||||
else {
|
||||
self.keyFileWarningTextField.stringValue = @"";
|
||||
self.keyFileWarningTextField.hidden = YES;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@@ -58,6 +58,18 @@ FOUNDATION_EXPORT NSString *const MPPasteBoardControllerDidClearClipboard;
|
||||
- (void)copyObjects:(NSArray<id<NSPasteboardWriting>> *)objects;
|
||||
- (void)copyObjectsWithoutTimeout:(NSArray<id<NSPasteboardWriting>> *)objects;
|
||||
|
||||
/**
|
||||
The pastboard controller will copy the object to the clipboard, display an appropriate overlay image
|
||||
and text and will set the clear time out if any is set. Additinally it will hide the application if
|
||||
the user has set this option. This call should always be used when a user is directly copying anything
|
||||
to the clipboard. If the clipboard is used internally (e.g. for autotype) you should call copyObjects:
|
||||
or even copyObjectsWithoutTimeout:
|
||||
|
||||
@param objects object so be copied
|
||||
@param overlayInfoType infotype discribing what is copied
|
||||
@param name a custom name
|
||||
@param view the view that initiated the copy action
|
||||
*/
|
||||
- (void)copyObjects:(NSArray<id<NSPasteboardWriting>> *)objects overlayInfo:(MPPasteboardOverlayInfoType)overlayInfoType name:(NSString *)name atView:(NSView *)view;
|
||||
|
||||
@end
|
||||
|
||||
@@ -71,7 +71,7 @@ NSString *const MPPasteBoardControllerDidClearClipboard = @"com.hicknhack.macpas
|
||||
|
||||
- (void)stashObjects {
|
||||
self.stashedObjects = [NSMutableArray array];
|
||||
for (NSPasteboardItem *item in NSPasteboard.generalPasteboard.pasteboardItems) {
|
||||
for(NSPasteboardItem *item in NSPasteboard.generalPasteboard.pasteboardItems) {
|
||||
NSPasteboardItem *newItem = [[NSPasteboardItem alloc] init];
|
||||
for (NSString *type in item.types) {
|
||||
/* mutable copy to ensure actual deep copy */
|
||||
@@ -85,7 +85,7 @@ NSString *const MPPasteBoardControllerDidClearClipboard = @"com.hicknhack.macpas
|
||||
}
|
||||
|
||||
- (void)restoreObjects {
|
||||
if (self.stashedObjects) {
|
||||
if(self.stashedObjects) {
|
||||
[NSPasteboard.generalPasteboard clearContents];
|
||||
[NSPasteboard.generalPasteboard writeObjects:self.stashedObjects];
|
||||
self.stashedObjects = nil;
|
||||
@@ -143,7 +143,7 @@ NSString *const MPPasteBoardControllerDidClearClipboard = @"com.hicknhack.macpas
|
||||
infoImage = [NSBundle.mainBundle imageForResource:@"00_PasswordTemplate"];
|
||||
infoText = [NSString stringWithFormat:NSLocalizedString(@"COPIED_FIELD_%@", "Field name that was copied to the pasteboard"), name];
|
||||
break;
|
||||
|
||||
|
||||
case MPPasteboardOverlayInfoReference:
|
||||
infoImage = [NSBundle.mainBundle imageForResource:@"04_KlipperTemplate"];
|
||||
infoText = name;
|
||||
@@ -151,6 +151,13 @@ NSString *const MPPasteBoardControllerDidClearClipboard = @"com.hicknhack.macpas
|
||||
|
||||
}
|
||||
[MPOverlayWindowController.sharedController displayOverlayImage:infoImage label:infoText atView:view];
|
||||
|
||||
BOOL hide = [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyHideAfterCopyToClipboard];
|
||||
if(hide) {
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(400 * NSEC_PER_MSEC)), dispatch_get_main_queue(), ^{
|
||||
[NSApplication.sharedApplication hide:nil];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_clearPasteboardContents {
|
||||
|
||||
17
MacPass/MPPathCell.h
Normal file
17
MacPass/MPPathCell.h
Normal file
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// MPPathCell.h
|
||||
// MacPass
|
||||
//
|
||||
// Created by Michael Starke on 14.01.20.
|
||||
// Copyright © 2020 HicknHack Software GmbH. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface MPPathCell : NSPathCell
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
23
MacPass/MPPathCell.m
Normal file
23
MacPass/MPPathCell.m
Normal file
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// MPPathCell.m
|
||||
// MacPass
|
||||
//
|
||||
// Created by Michael Starke on 14.01.20.
|
||||
// Copyright © 2020 HicknHack Software GmbH. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MPPathCell.h"
|
||||
#import "MPPathControl+Private.h"
|
||||
|
||||
@implementation MPPathCell
|
||||
|
||||
- (void)setURL:(NSURL *)URL {
|
||||
super.URL = URL;
|
||||
if([self.controlView isKindOfClass:MPPathControl.class]) {
|
||||
MPPathControl *pc = (MPPathControl *)self.controlView;
|
||||
[pc _postDidSetURLNotification];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
22
MacPass/MPPathControl+Private.h
Normal file
22
MacPass/MPPathControl+Private.h
Normal file
@@ -0,0 +1,22 @@
|
||||
//
|
||||
// MPPathControl+Private.h
|
||||
// MacPass
|
||||
//
|
||||
// Created by Michael Starke on 14.01.20.
|
||||
// Copyright © 2020 HicknHack Software GmbH. All rights reserved.
|
||||
//
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
|
||||
#import "MPPathControl.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface MPPathControl ()
|
||||
|
||||
- (void)_postDidSetURLNotification;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -10,6 +10,8 @@
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
APPKIT_EXTERN NSString *const MPPathControlDidSetURLNotification;
|
||||
|
||||
@interface MPPathControl : NSPathControl <NSPathControlDelegate>
|
||||
|
||||
- (IBAction)showOpenPanel:(id _Nullable)sender;
|
||||
|
||||
@@ -7,21 +7,54 @@
|
||||
//
|
||||
|
||||
#import "MPPathControl.h"
|
||||
#import "MPPathControl+Private.h"
|
||||
|
||||
#import "MPPathCell.h"
|
||||
|
||||
NSString *const MPPathControlDidSetURLNotification = @"MPPathControlDidSetURLNotification";
|
||||
|
||||
@implementation MPPathControl
|
||||
|
||||
+ (Class)cellClass{
|
||||
return MPPathCell.class;
|
||||
}
|
||||
|
||||
- (BOOL)canBecomeKeyView {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)acceptsFirstResponder {
|
||||
/*
|
||||
documentation state YES is required when canBecomeKeyView is YES but setting to YES
|
||||
causes NSWindow to use this as first responder when closing the password generator popover
|
||||
*/
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (instancetype)initWithFrame:(NSRect)frameRect {
|
||||
self = [super initWithFrame:frameRect];
|
||||
self.delegate = self;
|
||||
[self _setupCell];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithCoder:(NSCoder *)coder {
|
||||
/* FIXME: this doesn't work well anymore. Need more work, see: https://www.mikeash.com/pyblog/custom-nscells-done-right.html */
|
||||
self = [super initWithCoder:coder];
|
||||
self.delegate = self;
|
||||
self.delegate = self;
|
||||
[self _setupCell];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)_setupCell {
|
||||
if([self.cell isKindOfClass:MPPathCell.class]) {
|
||||
return;
|
||||
}
|
||||
NSData *archive = [NSKeyedArchiver archivedDataWithRootObject:self.cell];
|
||||
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:archive];
|
||||
self.cell = [[MPPathCell alloc] initWithCoder:unarchiver];
|
||||
}
|
||||
|
||||
- (void)willOpenMenu:(NSMenu *)menu withEvent:(NSEvent *)event {
|
||||
if(!self.URL) {
|
||||
[menu cancelTracking];
|
||||
@@ -47,7 +80,7 @@
|
||||
return;
|
||||
}
|
||||
if(@available(macOS 10.11, *)) {
|
||||
NSLog(@"Skipping 10.10 pathControl:willPopUpMenu");
|
||||
// skip
|
||||
}
|
||||
else {
|
||||
if(!self.URL) {
|
||||
@@ -66,4 +99,8 @@
|
||||
openPanel.prompt = NSLocalizedString(@"CHOOSE_FILE_BUTTON_TITLE", @"Button title in the key file selection dialog for selecting a key");
|
||||
}
|
||||
|
||||
- (void)_postDidSetURLNotification {
|
||||
[NSNotificationCenter.defaultCenter postNotificationName:MPPathControlDidSetURLNotification object:self];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -30,6 +30,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@class KPKTree;
|
||||
|
||||
FOUNDATION_EXPORT NSString *const MPPluginUnkownVersion;
|
||||
FOUNDATION_EXPORT NSString *const MPPluginDescriptionInfoDictionaryKey;
|
||||
|
||||
@interface MPPlugin : NSObject
|
||||
|
||||
@@ -37,8 +38,10 @@ FOUNDATION_EXPORT NSString *const MPPluginUnkownVersion;
|
||||
@property (copy, readonly) NSString *name;
|
||||
@property (nonatomic, copy, readonly, nullable) NSString *shortVersionString;
|
||||
@property (nonatomic, copy, readonly) NSString *versionString;
|
||||
@property (nonatomic, copy, readonly) NSString *localizedDescription;
|
||||
@property (nonatomic, strong, readonly) NSBundle *bundle;
|
||||
|
||||
|
||||
/**
|
||||
If your plugin needs initalization override this method but you have to call [super initWithPluginHost:]
|
||||
Otherwise your plugin might not get registered correctly
|
||||
@@ -53,6 +56,13 @@ FOUNDATION_EXPORT NSString *const MPPluginUnkownVersion;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark Supported Plugin Protocolls
|
||||
|
||||
/*
|
||||
Adopting this protocolls allows for custom settings in the Plugin settings pane.
|
||||
MacPass will load your view controller and place it inside the settings window
|
||||
when a user has selected your plugin in the list
|
||||
*/
|
||||
@protocol MPPluginSettings <NSObject>
|
||||
|
||||
@required
|
||||
@@ -60,6 +70,20 @@ FOUNDATION_EXPORT NSString *const MPPluginUnkownVersion;
|
||||
|
||||
@end
|
||||
|
||||
/*
|
||||
Adopt this protocoll if you plugin can extract window title information for a set of applications
|
||||
This way, MacPass might yield better results for autotype. Beware that his might break interoparbility
|
||||
*/
|
||||
@protocol MPAutotypeWindowTitleResolverPlugin <NSObject>
|
||||
@required
|
||||
|
||||
- (BOOL)acceptsRunningApplication:(NSRunningApplication *)runningApplication;
|
||||
- (NSString *)windowTitleForRunningApplication:(NSRunningApplication *)runningApplication;
|
||||
@end
|
||||
|
||||
|
||||
#pragma mark Proposed Plugin Protocolls
|
||||
|
||||
/*
|
||||
Adopt this protocoll if your plugin supports actions on entries.
|
||||
Actions will get listed in various places in menues.
|
||||
@@ -111,13 +135,51 @@ FOUNDATION_EXPORT NSString *const MPPluginUnkownVersion;
|
||||
This will get called when the open panel is closed by the user.
|
||||
You should retrieve any results from the panel and act accordingly.
|
||||
|
||||
If you need custom UI in the process, you can show them here.
|
||||
For example, if a CVS import might need user input on how to handle the parsed files this is the place to show it.
|
||||
|
||||
@param panel The open panel used for selecting what file(s) to import
|
||||
@param response The response for of the user for running the panel
|
||||
@return The tree constructed from the selected input file(s)
|
||||
@return The KPKTree constructed from the selected input file(s)
|
||||
*/
|
||||
- (KPKTree *)treeForRunningOpenPanel:(NSOpenPanel *)panel withResponse:(NSModalResponse)response;
|
||||
- (nullable KPKTree *)treeForRunningOpenPanel:(NSOpenPanel *)panel;
|
||||
@end
|
||||
|
||||
@protocol MPExportPlugin <NSObject>
|
||||
|
||||
@required
|
||||
/**
|
||||
Called by the host to update a menu item for exporting.
|
||||
You are supposed to update the title to something meaningfull.
|
||||
Target and action will get set by host, so do not rely on them
|
||||
|
||||
@param item MenuItem that will be used to export via the plugin
|
||||
*/
|
||||
- (void)prepareExportMenuItem:(NSMenuItem *)item;
|
||||
|
||||
/**
|
||||
Called by the host when an export is about to happen.
|
||||
Update the panel to work for all the files and formats you can export
|
||||
|
||||
@param panel The panel used to select the export destination
|
||||
*/
|
||||
- (void)prepareSavePanel:(NSSavePanel *)panel;
|
||||
/**
|
||||
This will get called when the save panel is closed by the user.
|
||||
You should retrieve any results from the panel and act accordingly.
|
||||
|
||||
If you need custom UI in the process, you can show them here.
|
||||
For example, if a CSV export might need user input to configure its output this is the place to show it.
|
||||
|
||||
@param tree The current tree to be exported
|
||||
@param panel The save panel that was used to specify the export destination
|
||||
*/
|
||||
- (void)exportTree:(KPKTree *)tree forRunningSavePanel:(NSSavePanel *)panel;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#pragma mark Deprecated
|
||||
|
||||
@interface MPPlugin (Deprecated)
|
||||
|
||||
- (instancetype)initWithPluginManager:(id)manager;
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#import "MPPluginVersionComparator.h"
|
||||
|
||||
NSString *const MPPluginUnkownVersion = @"unkown.plugin.version";
|
||||
NSString *const MPPluginDescriptionInfoDictionaryKey = @"MPPluginDescription";
|
||||
|
||||
@implementation MPPlugin
|
||||
|
||||
@@ -90,6 +91,16 @@ NSString *const MPPluginUnkownVersion = @"unkown.plugin.version";
|
||||
return MPPluginUnkownVersion;
|
||||
}
|
||||
|
||||
- (NSString *)localizedDescription {
|
||||
if([self.bundle.localizedInfoDictionary objectForKey:MPPluginDescriptionInfoDictionaryKey]) {
|
||||
return self.bundle.localizedInfoDictionary[MPPluginDescriptionInfoDictionaryKey];
|
||||
}
|
||||
if([self.bundle.infoDictionary objectForKey:MPPluginDescriptionInfoDictionaryKey]) {
|
||||
return self.bundle.infoDictionary[MPPluginDescriptionInfoDictionaryKey];
|
||||
}
|
||||
return @"";
|
||||
}
|
||||
|
||||
|
||||
- (void)didLoadPlugin {
|
||||
|
||||
|
||||
@@ -32,6 +32,8 @@ FOUNDATION_EXPORT NSString *const MPPluginHostPluginBundleIdentifiyerKey;
|
||||
@class MPPlugin;
|
||||
@class KPKEntry;
|
||||
@protocol MPImportPlugin;
|
||||
@protocol MPExportPlugin;
|
||||
@protocol MPAutotypeWindowTitleResolverPlugin;
|
||||
|
||||
@interface MPPluginHost : NSObject
|
||||
|
||||
@@ -52,8 +54,15 @@ FOUNDATION_EXPORT NSString *const MPPluginHostPluginBundleIdentifiyerKey;
|
||||
- (NSArray *)avilableMenuItemsForEntries:(NSArray <KPKEntry *>*)entries;
|
||||
@end
|
||||
|
||||
@interface MPPluginHost (MPImportPluginSupport)
|
||||
@interface MPPluginHost (MPImportExportPluginSupport)
|
||||
|
||||
@property (readonly, copy) NSArray <MPPlugin<MPImportPlugin> __kindof*> *importPlugins;
|
||||
@property (readonly, copy) NSArray <MPPlugin<MPExportPlugin> __kindof*> *exportPlugins;
|
||||
|
||||
@end
|
||||
|
||||
@interface MPPluginHost (MPWindowTitleResolverSupport)
|
||||
|
||||
- (NSArray<MPPlugin<MPAutotypeWindowTitleResolverPlugin> __kindof*> *)windowTitleResolverForRunningApplication:(NSRunningApplication *)runningApplication;
|
||||
|
||||
@end
|
||||
|
||||
@@ -282,7 +282,7 @@ NSString *const MPPluginHostPluginBundleIdentifiyerKey = @"MPPluginHostPluginBun
|
||||
}
|
||||
}
|
||||
if(incompatiblePlugins.count > 0) {
|
||||
BOOL hideAlert = NO;
|
||||
BOOL hideAlert = NSApplication.sharedApplication.isRunningTests ? YES : NO;
|
||||
if(nil != [NSUserDefaults.standardUserDefaults objectForKey:kMPSettingsKeyHideIncopatiblePluginsWarning]) {
|
||||
hideAlert = [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyHideIncopatiblePluginsWarning];
|
||||
}
|
||||
@@ -447,18 +447,41 @@ NSString *const MPPluginHostPluginBundleIdentifiyerKey = @"MPPluginHostPluginBun
|
||||
[context.plugin performActionForMenuItem:item withEntries:context.entries];
|
||||
}
|
||||
|
||||
- (NSArray *)_pluginsConformingToProtocoll:(Protocol *)protocol {
|
||||
NSPredicate *filterPredicate = [NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
|
||||
return ([evaluatedObject conformsToProtocol:protocol]);
|
||||
}];
|
||||
return [self.mutablePlugins filteredArrayUsingPredicate:filterPredicate];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NSString *const MPPluginBundleIdentifierKey = @"MPPluginBundleIdentifierKey";
|
||||
NSString *const MPImportPluginUTIKey = @"MPImportPluginUTIKey";
|
||||
|
||||
@implementation MPPluginHost (MPImportPluginSupport)
|
||||
@implementation MPPluginHost (MPImportExportPluginSupport)
|
||||
|
||||
- (NSArray<MPPlugin *> *)importPlugins {
|
||||
NSPredicate *filterPredicate = [NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
|
||||
return ([evaluatedObject conformsToProtocol:@protocol(MPImportPlugin)]);
|
||||
}];
|
||||
return [self.mutablePlugins filteredArrayUsingPredicate:filterPredicate];
|
||||
return [self _pluginsConformingToProtocoll:@protocol(MPImportPlugin)];
|
||||
}
|
||||
- (NSArray<MPPlugin<MPImportPlugin> *> *)exportPlugins {
|
||||
return [self _pluginsConformingToProtocoll:@protocol(MPExportPlugin)];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation MPPluginHost (MPWindowTitleResolverSupport)
|
||||
|
||||
- (NSArray<MPPlugin *> *)windowTitleResolverForRunningApplication:(NSRunningApplication *)runningApplication {
|
||||
NSArray<MPPlugin<MPAutotypeWindowTitleResolverPlugin> *> *plugins = [self _pluginsConformingToProtocoll:@protocol(MPAutotypeWindowTitleResolverPlugin)];
|
||||
NSMutableArray *resolver = [[NSMutableArray alloc] init];
|
||||
for(MPPlugin<MPAutotypeWindowTitleResolverPlugin> *plugin in plugins) {
|
||||
if([plugin acceptsRunningApplication:runningApplication]) {
|
||||
[resolver addObject:plugin];
|
||||
}
|
||||
}
|
||||
return [resolver copy];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
//
|
||||
|
||||
#import "MPPluginPreferencesController.h"
|
||||
#import "MPPluginTabelCellView.h"
|
||||
#import "MPExtendedTableCellView.h"
|
||||
#import "MPPluginHost.h"
|
||||
#import "MPPlugin.h"
|
||||
#import "MPPlugin_Private.h"
|
||||
@@ -42,6 +42,7 @@ typedef NS_ENUM(NSUInteger, MPPluginSegmentType) {
|
||||
|
||||
@interface MPPluginPreferencesController () <NSTableViewDataSource, NSTableViewDelegate>
|
||||
|
||||
@property (strong) IBOutlet NSButton *allowRemoteConnectionCheckButton;
|
||||
@property (strong) IBOutlet NSTableView *pluginTableView;
|
||||
@property (strong) IBOutlet NSView *settingsView;
|
||||
@property (strong) IBOutlet NSView *fallbackSettingsView;
|
||||
@@ -83,6 +84,10 @@ typedef NS_ENUM(NSUInteger, MPPluginSegmentType) {
|
||||
toObject:NSUserDefaultsController.sharedUserDefaultsController
|
||||
withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyLoadIncompatiblePlugins]
|
||||
options:nil];
|
||||
[self.allowRemoteConnectionCheckButton bind:NSValueBinding
|
||||
toObject:NSUserDefaultsController.sharedUserDefaultsController
|
||||
withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyAllowRemoteFetchOfPluginRepository]
|
||||
options:nil];
|
||||
[self.pluginTableView registerForDraggedTypes:@[(NSString *)kUTTypeFileURL]];
|
||||
}
|
||||
|
||||
@@ -93,7 +98,7 @@ typedef NS_ENUM(NSUInteger, MPPluginSegmentType) {
|
||||
|
||||
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
|
||||
MPPlugin *plugin = [self pluginForRow:row];
|
||||
MPPluginTabelCellView *view = [tableView makeViewWithIdentifier:tableColumn.identifier owner:nil];
|
||||
MPExtendedTableCellView *view = [tableView makeViewWithIdentifier:tableColumn.identifier owner:nil];
|
||||
if(plugin.enabled) {
|
||||
view.textField.stringValue = plugin.name;
|
||||
}
|
||||
@@ -119,22 +124,29 @@ typedef NS_ENUM(NSUInteger, MPPluginSegmentType) {
|
||||
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[view]|" options:0 metrics:nil views:dict]];
|
||||
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[view]|" options:0 metrics:nil views:dict]];
|
||||
}
|
||||
else {
|
||||
[self _showInfoMessageForPlugin:plugin.localizedDescription];
|
||||
}
|
||||
}
|
||||
else if(nil != plugin) {
|
||||
[self.settingsView addSubview:self.fallbackSettingsView];
|
||||
NSDictionary *dict = @{ @"view" : self.fallbackSettingsView,
|
||||
@"table" : self.pluginTableView.enclosingScrollView };
|
||||
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[view]|" options:0 metrics:nil views:dict]];
|
||||
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[view]|" options:0 metrics:nil views:dict]];
|
||||
if(plugin.errorMessage.length > 0) {
|
||||
self.fallbackDescriptionTextField.stringValue = plugin.errorMessage;
|
||||
[self _showInfoMessageForPlugin:plugin.errorMessage];
|
||||
}
|
||||
else {
|
||||
self.fallbackDescriptionTextField.stringValue = NSLocalizedString(@"PLUGIN_SETTINGS_GENERIC_ERROR_MESSAGE", "Generic message displayed if no details are know why a plugin was not loaded.");
|
||||
[self _showInfoMessageForPlugin:NSLocalizedString(@"PLUGIN_SETTINGS_GENERIC_ERROR_MESSAGE", "Generic message displayed if no details are know why a plugin was not loaded.")];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_showInfoMessageForPlugin:(NSString *)message {
|
||||
[self.settingsView addSubview:self.fallbackSettingsView];
|
||||
NSDictionary *dict = @{ @"view" : self.fallbackSettingsView,
|
||||
@"table" : self.pluginTableView.enclosingScrollView };
|
||||
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[view]|" options:0 metrics:nil views:dict]];
|
||||
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[view]|" options:0 metrics:nil views:dict]];
|
||||
self.fallbackDescriptionTextField.stringValue = message.length > 0 ? message : @"";
|
||||
}
|
||||
|
||||
- (MPPlugin *)pluginForRow:(NSInteger)row {
|
||||
NSArray<MPPlugin __kindof *> *plugins = [MPPluginHost sharedHost].plugins;
|
||||
if(0 > row || row >= plugins.count) {
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#import "MPPluginRepository.h"
|
||||
#import "MPConstants.h"
|
||||
#import "MPPluginRepositoryItem.h"
|
||||
#import "MPSettingsHelper.h"
|
||||
|
||||
NSString *const MPPluginRepositoryDidUpdateAvailablePluginsNotification = @"com.hicknhack.macpass.MPPluginRepositoryDidInitializeAvailablePluginsNotification";
|
||||
|
||||
@@ -56,7 +57,7 @@ NSString *const MPPluginRepositoryDidUpdateAvailablePluginsNotification = @"com.
|
||||
if(self) {
|
||||
_isInitialized = NO;
|
||||
_lastDataFetchTime = NSDate.distantPast.timeIntervalSinceReferenceDate;
|
||||
[self fetchRepositoryDataCompletionHandler:^(NSArray<MPPluginRepositoryItem *> * _Nonnull availablePlugins) {
|
||||
[self _fetchAppropriateRepositoryDataCompletionHandler:^(NSArray<MPPluginRepositoryItem *> * _Nonnull availablePlugins) {
|
||||
self.availablePlugins = availablePlugins;
|
||||
self.isInitialized = YES;
|
||||
}];
|
||||
@@ -65,10 +66,12 @@ NSString *const MPPluginRepositoryDidUpdateAvailablePluginsNotification = @"com.
|
||||
}
|
||||
|
||||
- (NSArray<MPPluginRepositoryItem *> *)availablePlugins {
|
||||
/* update cache on every read if it's older than 5 minutes */
|
||||
/* FIXME: Invalidate fetch when settings have changed!
|
||||
update cache on every read if it's older than 5 minutes
|
||||
*/
|
||||
if((NSDate.timeIntervalSinceReferenceDate - self.lastDataFetchTime) > 60*5 ) {
|
||||
NSLog(@"%@: updating available plugins cache.", self.className);
|
||||
[self fetchRepositoryDataCompletionHandler:^(NSArray<MPPluginRepositoryItem *> * _Nonnull availablePlugins) {
|
||||
[self _fetchAppropriateRepositoryDataCompletionHandler:^(NSArray<MPPluginRepositoryItem *> * _Nonnull availablePlugins) {
|
||||
self.availablePlugins = availablePlugins;
|
||||
}];
|
||||
}
|
||||
@@ -87,59 +90,99 @@ NSString *const MPPluginRepositoryDidUpdateAvailablePluginsNotification = @"com.
|
||||
}
|
||||
}
|
||||
|
||||
- (void)fetchRepositoryDataCompletionHandler:(void (^)(NSArray<MPPluginRepositoryItem *> * _Nonnull))completionHandler {
|
||||
- (void)_fetchAppropriateRepositoryDataCompletionHandler:(void (^)(NSArray<MPPluginRepositoryItem *> * _Nonnull))completionHandler {
|
||||
/* dispatch the call to allow for direct return and handle result later on */
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
BOOL allowRemoteConnection = [self _askForPluginRepositoryPermission];
|
||||
if(!allowRemoteConnection) {
|
||||
[self _fetchLocalFallbackRepositoryData:completionHandler];
|
||||
}
|
||||
else {
|
||||
[self _fetchRepositoryDataCompletionHandler:completionHandler];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (void)_fetchRepositoryDataCompletionHandler:(void (^)(NSArray<MPPluginRepositoryItem *> * _Nonnull))completionHandler {
|
||||
NSString *urlString = NSBundle.mainBundle.infoDictionary[MPBundlePluginRepositoryURLKey];
|
||||
if(!urlString) {
|
||||
if(completionHandler) {
|
||||
completionHandler(@[]);
|
||||
}
|
||||
[self _fetchLocalFallbackRepositoryData:completionHandler];
|
||||
return;
|
||||
}
|
||||
NSURL *jsonURL = [NSURL URLWithString:urlString];
|
||||
if(!jsonURL) {
|
||||
if(completionHandler) {
|
||||
completionHandler(@[]);
|
||||
}
|
||||
[self _fetchLocalFallbackRepositoryData:completionHandler];
|
||||
return;
|
||||
}
|
||||
|
||||
NSURLSessionTask *downloadTask = [NSURLSession.sharedSession dataTaskWithURL:jsonURL completionHandler:^(NSData * _Nullable jsonData, NSURLResponse * _Nullable response, NSError * _Nullable error) {
|
||||
if(![response isKindOfClass:NSHTTPURLResponse.class]) {
|
||||
if(completionHandler) {
|
||||
completionHandler(@[]);
|
||||
}
|
||||
[self _fetchLocalFallbackRepositoryData:completionHandler];
|
||||
return;
|
||||
}
|
||||
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
|
||||
if(httpResponse.statusCode != 200 || jsonData.length == 0) {
|
||||
if(completionHandler) {
|
||||
completionHandler(@[]);
|
||||
}
|
||||
[self _fetchLocalFallbackRepositoryData:completionHandler];
|
||||
return;
|
||||
}
|
||||
id jsonRoot = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
|
||||
if(!jsonRoot || ![jsonRoot isKindOfClass:NSArray.class]) {
|
||||
if(completionHandler) {
|
||||
completionHandler(@[]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
NSMutableArray *items = [[NSMutableArray alloc] init];
|
||||
for(id item in jsonRoot) {
|
||||
if(![item isKindOfClass:NSDictionary.class]) {
|
||||
continue;
|
||||
}
|
||||
MPPluginRepositoryItem *pluginItem = [MPPluginRepositoryItem pluginItemFromDictionary:item];
|
||||
if(pluginItem.isVaid) {
|
||||
[items addObject:pluginItem];
|
||||
}
|
||||
}
|
||||
|
||||
NSArray *items = [self _parseJSONData:jsonData];
|
||||
|
||||
if(completionHandler) {
|
||||
completionHandler([items copy]);
|
||||
}
|
||||
}];
|
||||
|
||||
[downloadTask resume];
|
||||
}
|
||||
|
||||
- (void)_fetchLocalFallbackRepositoryData:(void (^)(NSArray<MPPluginRepositoryItem *> * _Nonnull))completionHandler {
|
||||
NSURL *jsonURL = [NSBundle.mainBundle URLForResource:@"plugins" withExtension:@"json"];
|
||||
NSData *localJsonData = [NSData dataWithContentsOfURL:jsonURL];
|
||||
if(!localJsonData) {
|
||||
if(completionHandler) {
|
||||
completionHandler(@[]);
|
||||
}
|
||||
}
|
||||
NSArray<MPPluginRepositoryItem *> *items = [self _parseJSONData:localJsonData];
|
||||
if(completionHandler) {
|
||||
completionHandler(items);
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray<MPPluginRepositoryItem *> *)_parseJSONData:(NSData *)jsonData {
|
||||
NSError *error;
|
||||
id jsonRoot = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
|
||||
if(!jsonRoot || ![jsonRoot isKindOfClass:NSArray.class]) {
|
||||
return @[];
|
||||
}
|
||||
NSMutableArray *items = [[NSMutableArray alloc] init];
|
||||
for(id item in jsonRoot) {
|
||||
if(![item isKindOfClass:NSDictionary.class]) {
|
||||
continue;
|
||||
}
|
||||
MPPluginRepositoryItem *pluginItem = [MPPluginRepositoryItem pluginItemFromDictionary:item];
|
||||
if(pluginItem.isVaid) {
|
||||
[items addObject:pluginItem];
|
||||
}
|
||||
}
|
||||
return [items copy];
|
||||
}
|
||||
|
||||
- (BOOL)_askForPluginRepositoryPermission {
|
||||
if(![NSUserDefaults.standardUserDefaults objectForKey:kMPSettingsKeyAllowRemoteFetchOfPluginRepository]) {
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
alert.alertStyle = NSAlertStyleWarning;
|
||||
alert.informativeText = NSLocalizedString(@"ALERT_ASK_FOR_PLUGIN_REPOSITORY_CONNECTION_PERMISSION_INFORMATIVE_TEXT", @"Informative text displayed on the alert that shows up when MacPass asks for permssion to download the plugin repository JSON file");
|
||||
alert.messageText = NSLocalizedString(@"ALERT_ASK_FOR_PLUGIN_REPOSITORY_CONNECTION_PERMISSION_MESSAGE", @"Message displayed on the alert that asks for permission to download the plugin repository JSON file");
|
||||
alert.showsSuppressionButton = YES;
|
||||
[alert addButtonWithTitle:NSLocalizedString(@"ALERT_ASK_FOR_PLUGIN_REPOSITORY_ALLOW_DOWNLOAD", @"Allow the download of the plugin repository file")];
|
||||
[alert addButtonWithTitle:NSLocalizedString(@"ALERT_ASK_FOR_PLUGIN_REPOSITORY_DISALLOW_DOWNLOAD", @"Disallow the download of the plugin repository file")];
|
||||
NSModalResponse repsonse = [alert runModal];
|
||||
BOOL allow = (repsonse == NSAlertFirstButtonReturn);
|
||||
[NSUserDefaults.standardUserDefaults setBool:allow forKey:kMPSettingsKeyAllowRemoteFetchOfPluginRepository];
|
||||
return allow;
|
||||
}
|
||||
return [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyAllowRemoteFetchOfPluginRepository];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#import "MPPluginRepositoryItem.h"
|
||||
#import "MPPluginVersionComparator.h"
|
||||
#import "MPPluginStatusTableCellView.h"
|
||||
#import "MPSettingsHelper.h"
|
||||
|
||||
|
||||
typedef NS_ENUM(NSUInteger, MPPluginTableColumn) {
|
||||
@@ -39,7 +40,13 @@ typedef NS_ENUM(NSUInteger, MPPluginTableColumn) {
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
self.downloadedItems = [[NSMutableSet alloc] init];
|
||||
[self.updatedAtTextField bind:NSValueBinding toObject:MPPluginRepository.defaultRepository withKeyPath:NSStringFromSelector(@selector(updatedAt)) options:nil];
|
||||
BOOL allowRemoteData = [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyAllowRemoteFetchOfPluginRepository];
|
||||
if(allowRemoteData) {
|
||||
[self.updatedAtTextField bind:NSValueBinding toObject:MPPluginRepository.defaultRepository withKeyPath:NSStringFromSelector(@selector(updatedAt)) options:nil];
|
||||
}
|
||||
else {
|
||||
self.updatedAtTextField.stringValue = NSLocalizedString(@"REPOSITORY_UPDATED_AT_LOCAL", @"Updated at text when the local plugin defintino is used");
|
||||
}
|
||||
[self _refreshRepository];
|
||||
}
|
||||
|
||||
|
||||
@@ -24,10 +24,10 @@
|
||||
|
||||
#import "MPPreferencesTab.h"
|
||||
|
||||
#import "MPGeneralSettingsController.h"
|
||||
#import "MPIntegrationSettingsController.h"
|
||||
#import "MPWorkflowSettingsController.h"
|
||||
#import "MPUpdateSettingsController.h"
|
||||
#import "MPGeneralPreferencesController.h"
|
||||
#import "MPIntegrationPreferencesController.h"
|
||||
#import "MPWorkflowPreferencesController.h"
|
||||
#import "MPUpdatePreferencesController.h"
|
||||
#import "MPPluginPreferencesController.h"
|
||||
|
||||
@interface MPPreferencesWindowController () {
|
||||
@@ -121,14 +121,14 @@
|
||||
tabClass = MPPluginPreferencesController.class;
|
||||
break;
|
||||
case MPPreferencesTabUpdate:
|
||||
tabClass = MPUpdateSettingsController.class;
|
||||
tabClass = MPUpdatePreferencesController.class;
|
||||
break;
|
||||
case MPPreferencesTabWorkflow:
|
||||
tabClass = MPWorkflowSettingsController.class;
|
||||
tabClass = MPWorkflowPreferencesController.class;
|
||||
break;
|
||||
case MPPreferencesTabGeneral:
|
||||
default:
|
||||
tabClass = MPGeneralSettingsController.class;
|
||||
tabClass = MPGeneralPreferencesController.class;
|
||||
break;
|
||||
}
|
||||
NSString *identifier;
|
||||
@@ -164,10 +164,10 @@
|
||||
}
|
||||
|
||||
- (void)_setupDefaultPreferencesTabs {
|
||||
NSArray *controllers = @[ [[MPGeneralSettingsController alloc] init],
|
||||
[[MPIntegrationSettingsController alloc] init],
|
||||
[[MPWorkflowSettingsController alloc] init],
|
||||
[[MPUpdateSettingsController alloc] init],
|
||||
NSArray *controllers = @[ [[MPGeneralPreferencesController alloc] init],
|
||||
[[MPIntegrationPreferencesController alloc] init],
|
||||
[[MPWorkflowPreferencesController alloc] init],
|
||||
[[MPUpdatePreferencesController alloc] init],
|
||||
[[MPPluginPreferencesController alloc] init] ];
|
||||
NSMutableArray *identifier = [[NSMutableArray alloc] initWithCapacity:controllers.count];
|
||||
for(id<MPPreferencesTab> controller in controllers) {
|
||||
|
||||
@@ -37,8 +37,8 @@
|
||||
}
|
||||
|
||||
- (void)viewDidLoad {
|
||||
self.searchKeyPopUpButton.menu = [self _allocateAttributeItemMenu:YES withTitle:NSLocalizedString(@"SEARCH_VALUE", "")];
|
||||
self.valuePopUpButton.menu = [self _allocateAttributeItemMenu:NO withTitle:NSLocalizedString(@"OUTPUT_VALUE", "")];
|
||||
self.searchKeyPopUpButton.menu = [self _allocateAttributeItemMenu:YES withTitle:NSLocalizedString(@"SEARCH_VALUE", "Search field for references lookup")];
|
||||
self.valuePopUpButton.menu = [self _allocateAttributeItemMenu:NO withTitle:NSLocalizedString(@"OUTPUT_VALUE", "Value field for reference lookup")];
|
||||
[self.searchStringTextField bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(searchString)) options:nil];
|
||||
[self _updateReferenceString];
|
||||
}
|
||||
@@ -53,7 +53,7 @@
|
||||
[menu addItemWithTitle:NSLocalizedString(@"URL","URL reference item") action:NULL keyEquivalent:@""];
|
||||
[menu addItemWithTitle:NSLocalizedString(@"NOTES","Notes reference item") action:NULL keyEquivalent:@""];
|
||||
if(allowCustomAttributes) {
|
||||
[menu addItemWithTitle:NSLocalizedString(@"CUSTOM_ATTRIBUTE","Curstom attribute reference item") action:NULL keyEquivalent:@""];
|
||||
[menu addItemWithTitle:NSLocalizedString(@"CUSTOM_ATTRIBUTE","Custom attribute reference item") action:NULL keyEquivalent:@""];
|
||||
}
|
||||
NSArray *keys = @[ kKPKReferenceUUIDKey, kKPKReferenceTitleKey, kKPKReferenceUsernameKey, kKPKReferencePasswordKey, kKPKReferenceURLKey, kKPKReferenceNotesKey, @"S" ];
|
||||
[menu.itemArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
|
||||
|
||||
@@ -33,6 +33,7 @@ APPKIT_EXTERN NSString *const kMPSettingsKeyOpenEmptyDatabaseOnLaunch;
|
||||
APPKIT_EXTERN NSString *const kMPSettingsKeyReopenLastDatabaseOnLaunch;
|
||||
APPKIT_EXTERN NSString *const kMPSettingsKeyQuitOnLastWindowClose; // Quit MacPass when the user closes the last window
|
||||
APPKIT_EXTERN NSString *const kMPSettingsKeyFileChangeStrategy;
|
||||
APPKIT_EXTERN NSString *const kMPSettingsKeyEnableAutosave; // if set to YES MacPass support Autosaving for documents
|
||||
|
||||
/* URL handling */
|
||||
APPKIT_EXTERN NSString *const kMPSettingsKeyBrowserBundleId;
|
||||
@@ -41,6 +42,7 @@ APPKIT_EXTERN NSString *const kMPSettingsKeyBrowserBundleId;
|
||||
APPKIT_EXTERN NSString *const kMPSettingsKeyLockOnSleep;
|
||||
APPKIT_EXTERN NSString *const kMPSettingskeyLockOnLogout;
|
||||
APPKIT_EXTERN NSString *const kMPSettingsKeyIdleLockTimeOut;
|
||||
APPKIT_EXTERN NSString *const kMPSettingskeyLockOnScreenSleep;
|
||||
|
||||
/* Autosaving states */
|
||||
APPKIT_EXTERN NSString *const kMPSettingsKeyShowInspector;
|
||||
@@ -67,7 +69,7 @@ APPKIT_EXTERN NSString *const kMPSettingsKeyAutotypeMatchTitle; //
|
||||
APPKIT_EXTERN NSString *const kMPSettingsKeyAutotypeMatchURL; // Autotype lookup includes entry URL
|
||||
APPKIT_EXTERN NSString *const kMPSettingsKeyAutotypeMatchHost; // Autotype lookup includes host part of entry URL
|
||||
APPKIT_EXTERN NSString *const kMPSettingsKeyAutotypeMatchTags; // Autotype lookup includes tags for entries
|
||||
APPKIT_EXTERN NSString *const kMPSettingsKeyAutotypeHideAccessibiltyWarning; // Do not show an alert, when MacPass has no support for Autotype
|
||||
APPKIT_EXTERN NSString *const kMPSettingsKeyAutotpyeHideMissingPermissionsWarning;
|
||||
|
||||
/* Search */
|
||||
APPKIT_EXTERN NSString *const kMPSettingsKeyEntrySearchFilterContext;
|
||||
@@ -79,12 +81,15 @@ APPKIT_EXTERN NSString *const kMPSettingsKeyEnableQuicklookPreview;
|
||||
APPKIT_EXTERN NSString *const kMPSettingsKeyDoubleClickURLAction;
|
||||
APPKIT_EXTERN NSString *const kMPSettingsKeyDoubleClickTitleAction;
|
||||
APPKIT_EXTERN NSString *const kMPSettingsKeyUpdatePasswordOnTemplateEntries;
|
||||
APPKIT_EXTERN NSString *const kMPSettingsKeyHideAfterCopyToClipboard;
|
||||
|
||||
/* Plugins */
|
||||
APPKIT_EXTERN NSString *const kMPSettingsKeyLoadUnsecurePlugins; // If set to YES this will load all plugins regardless of their codesignature status
|
||||
APPKIT_EXTERN NSString *const kMPSettingsKeyDisabledPlugins; // NSArray of bundle identifiers of disabled plugins
|
||||
APPKIT_EXTERN NSString *const kMPSettingsKeyLoadIncompatiblePlugins; // If set to YES incompatible plugins (no version info, marked as incompatible, etc) will be loaded regardless
|
||||
APPKIT_EXTERN NSString *const kMPSettingsKeyHideIncopatiblePluginsWarning; // Do not show an alert, when MacPass encounteres incompatible plugins
|
||||
APPKIT_EXTERN NSString *const kMPSettingsKeyAllowRemoteFetchOfPluginRepository; // Allow the download of the plugin repository file
|
||||
APPKIT_EXTERN NSString *const kMPSettingsKeyPluginHideAksForRemoveConnectionPermission;
|
||||
|
||||
typedef NS_ENUM(NSUInteger, MPFileChangeStrategy) {
|
||||
MPFileChangeStrategyAsk,
|
||||
|
||||
@@ -34,8 +34,10 @@ NSString *const kMPSettingsKeyOpenEmptyDatabaseOnLaunch = @"OpenEm
|
||||
NSString *const kMPSettingsKeyReopenLastDatabaseOnLaunch = @"ReopenLastDatabaseOnLaunch";
|
||||
NSString *const kMPSettingsKeyQuitOnLastWindowClose = @"QuitOnLastWindowClose";
|
||||
NSString *const kMPSettingsKeyFileChangeStrategy = @"FileChangeStrategy";
|
||||
NSString *const kMPSettingsKeyEnableAutosave = @"EnableAutosave";
|
||||
NSString *const kMPSettingsKeyLockOnSleep = @"LockOnSleep";
|
||||
NSString *const kMPSettingskeyLockOnLogout = @"LockOnLogout";
|
||||
NSString *const kMPSettingskeyLockOnScreenSleep = @"LockOnScreenSleep";
|
||||
NSString *const kMPSettingsKeyIdleLockTimeOut = @"IdleLockTimeOut";
|
||||
NSString *const kMPSettingsKeyShowInspector = @"ShowInspector";
|
||||
NSString *const kMPSettingsKeyEntryTableSortDescriptors = @"EntryTableSortDescriptors";
|
||||
@@ -58,7 +60,7 @@ NSString *const kMPSettingsKeyAutotypeMatchTitle = @"Autoty
|
||||
NSString *const kMPSettingsKeyAutotypeMatchURL = @"AutotypeMatchURL";
|
||||
NSString *const kMPSettingsKeyAutotypeMatchHost = @"AutotypeMatchHost";
|
||||
NSString *const kMPSettingsKeyAutotypeMatchTags = @"AutotypeMatchTags";
|
||||
NSString *const kMPSettingsKeyAutotypeHideAccessibiltyWarning = @"AutotypeHideAccessibiltyWarning";
|
||||
NSString *const kMPSettingsKeyAutotpyeHideMissingPermissionsWarning = @"AutotpyeHideMissingPermissionsWarning";
|
||||
|
||||
NSString *const kMPSettingsKeyEntrySearchFilterContext = @"EntrySearchFilterContext";
|
||||
|
||||
@@ -77,11 +79,13 @@ NSString *const kMPSettingsKeyPasswordDefaultsForEntry = @"Passwo
|
||||
NSString *const kMPSettingsKeyDoubleClickURLAction = @"DoubleClickURLAction";
|
||||
NSString *const kMPSettingsKeyDoubleClickTitleAction = @"DoubleClickTitleAction";
|
||||
NSString *const kMPSettingsKeyUpdatePasswordOnTemplateEntries = @"UpdatePasswordOnTemplateEntries";
|
||||
NSString *const kMPSettingsKeyHideAfterCopyToClipboard = @"HideAfterCopyToClipboard";
|
||||
|
||||
NSString *const kMPSettingsKeyLoadUnsecurePlugins = @"LoadUnsecurePlugins";
|
||||
NSString *const kMPSettingsKeyLoadIncompatiblePlugins = @"LoadIncompatiblePlugins";
|
||||
NSString *const kMPSettingsKeyDisabledPlugins = @"DisabledPlugins";
|
||||
NSString *const kMPSettingsKeyHideIncopatiblePluginsWarning = @"HideIncopatiblePluginsWarning";
|
||||
NSString *const kMPSettingsKeyAllowRemoteFetchOfPluginRepository = @"AllowRemoteFetchOfPluginRepository";
|
||||
|
||||
/* Deprecated */
|
||||
NSString *const kMPDeprecatedSettingsKeyRememberKeyFilesForDatabases = @"kMPSettingsKeyRememberKeyFilesForDatabases";
|
||||
@@ -94,12 +98,12 @@ NSString *const kMPDeprecatedSettingsKeyEnableHttpServer = @"En
|
||||
NSString *const kMPDeprecatedSettingsKeyShowMenuItem = @"ShowMenuItem";
|
||||
NSString *const kMPDeprecatedSettingsKeyDefaultPasswordRounds = @"KeyDefaultPasswordRounds";
|
||||
NSString *const kMPDepricatedSettingsKeyLoadUnsecurePlugins = @"MPLoadUnsecurePlugins";
|
||||
|
||||
NSString *const kMPDepricatedSettingsKeyAutotypeHideAccessibiltyWarning = @"AutotypeHideAccessibiltyWarning";
|
||||
|
||||
@implementation MPSettingsHelper
|
||||
|
||||
+ (void)setupDefaults {
|
||||
[[NSUserDefaults standardUserDefaults] registerDefaults:[self _standardDefaults]];
|
||||
[NSUserDefaults.standardUserDefaults registerDefaults:[self _standardDefaults]];
|
||||
}
|
||||
|
||||
+ (void)migrateDefaults {
|
||||
@@ -122,23 +126,24 @@ NSString *const kMPDepricatedSettingsKeyLoadUnsecurePlugins = @"MP
|
||||
standardDefaults = @{
|
||||
kMPSettingsKeyShowInspector: @YES, // Show the Inspector by default
|
||||
kMPSettingsKeyPasteboardClearTimeout: @30, // 30 seconds
|
||||
kMPSettingsKeyClearPasteboardOnQuit: @YES,
|
||||
kMPSettingsKeyClearPasteboardOnQuit: @YES, // Clear Clipboard on quit
|
||||
kMPSettingsKeyPreventUniversalClipboard: @YES, // Disable Universal Clipboard by default
|
||||
kMPSettingsKeyOpenEmptyDatabaseOnLaunch: @NO,
|
||||
kMPSettingsKeyReopenLastDatabaseOnLaunch: @YES,
|
||||
kMPSettingsKeyFileChangeStrategy: @(MPFileChangeStrategyAsk), // Ask what to do on a file change!
|
||||
kMPSettingsKeyLockOnSleep: @YES,
|
||||
kMPSettingskeyLockOnLogout: @NO,
|
||||
kMPSettingsKeyIdleLockTimeOut: @0, // 5 minutes
|
||||
kMPSettingskeyLockOnScreenSleep: @NO,
|
||||
kMPSettingsKeyIdleLockTimeOut: @0, // Do not lock while idle by default
|
||||
kMPSettingsKeyLegacyHideNotes: @NO,
|
||||
kMPSettingsKeyLegacyHidePassword: @YES,
|
||||
kMPSettingsKeyLegacyHideTitle: @NO,
|
||||
kMPSettingsKeyLegacyHideURL: @NO,
|
||||
kMPSettingsKeyLegacyHideUsername: @NO,
|
||||
kMPSettingsKeyRememberKeyFilesForDatabases: @NO,
|
||||
kMPSettingsKeySendCommandForControlKey: @YES,
|
||||
kMPSettingsKeyEnableGlobalAutotype: @NO,
|
||||
kMPSettingsKeyGlobalAutotypeKeyDataKey: DDHotKey.defaultHotKeyData,
|
||||
kMPSettingsKeySendCommandForControlKey: @YES, // translate Ctrl to Cmd by default
|
||||
kMPSettingsKeyEnableGlobalAutotype: @NO, // Keep global autotype disabled by default
|
||||
kMPSettingsKeyGlobalAutotypeKeyDataKey: DDHotKey.defaultHotKeyData, // Cmd + Alt + M
|
||||
kMPSettingsKeyDefaultGlobalAutotypeSequence: @"{USERNAME}{TAB}{PASSWORD}{ENTER}",
|
||||
kMPSettingsKeyAutotypeMatchTitle: @YES,
|
||||
kMPSettingsKeyAutotypeMatchURL: @NO,
|
||||
@@ -157,7 +162,9 @@ NSString *const kMPDepricatedSettingsKeyLoadUnsecurePlugins = @"MP
|
||||
kMPSettingsKeyUpdatePasswordOnTemplateEntries: @YES,
|
||||
kMPSettingsKeyDisabledPlugins: @[],
|
||||
kMPSettingsKeyLoadIncompatiblePlugins: @NO,
|
||||
kMPSettingsKeyQuitOnLastWindowClose: @NO
|
||||
kMPSettingsKeyQuitOnLastWindowClose: @NO,
|
||||
kMPSettingsKeyEnableAutosave: @YES,
|
||||
kMPSettingsKeyHideAfterCopyToClipboard: @NO
|
||||
};
|
||||
});
|
||||
return standardDefaults;
|
||||
@@ -177,7 +184,8 @@ NSString *const kMPDepricatedSettingsKeyLoadUnsecurePlugins = @"MP
|
||||
kMPDeprecatedSettingsKeyHttpPort,
|
||||
kMPDeprecatedSettingsKeyEnableHttpServer,
|
||||
kMPDeprecatedSettingsKeyShowMenuItem,
|
||||
kMPDepricatedSettingsKeyLoadUnsecurePlugins
|
||||
kMPDepricatedSettingsKeyLoadUnsecurePlugins,
|
||||
kMPDepricatedSettingsKeyAutotypeHideAccessibiltyWarning
|
||||
];
|
||||
});
|
||||
return deprecatedSettings;
|
||||
@@ -187,7 +195,7 @@ NSString *const kMPDepricatedSettingsKeyLoadUnsecurePlugins = @"MP
|
||||
+ (void)_removeDeprecatedValues {
|
||||
/* Clear old style values */
|
||||
for(NSString *key in [self _deprecatedSettingsKeys]) {
|
||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:key];
|
||||
[NSUserDefaults.standardUserDefaults removeObjectForKey:key];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,7 +208,7 @@ NSString *const kMPDepricatedSettingsKeyLoadUnsecurePlugins = @"MP
|
||||
this was changed in 0.6. to parent.title
|
||||
|
||||
*/
|
||||
NSData *descriptorData = [[NSUserDefaults standardUserDefaults] dataForKey:kMPSettingsKeyEntryTableSortDescriptors];
|
||||
NSData *descriptorData = [NSUserDefaults.standardUserDefaults dataForKey:kMPSettingsKeyEntryTableSortDescriptors];
|
||||
if(!descriptorData) {
|
||||
return; // No user defaults
|
||||
}
|
||||
@@ -211,27 +219,35 @@ NSString *const kMPDepricatedSettingsKeyLoadUnsecurePlugins = @"MP
|
||||
if(descriptor.selector == @selector(compare:)
|
||||
|| [descriptor.key isEqualToString:@"timeInfo.modificationDate"]
|
||||
|| [descriptor.key isEqualToString:@"parent.name"] ) {
|
||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:kMPSettingsKeyEntryTableSortDescriptors];
|
||||
[NSUserDefaults.standardUserDefaults removeObjectForKey:kMPSettingsKeyEntryTableSortDescriptors];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)_migrateURLDoubleClickPreferences {
|
||||
/* Default was NO so if the key was not set, we also get NO, which is what we want */
|
||||
BOOL openURL = [[NSUserDefaults standardUserDefaults] boolForKey:kMPDeprecatedSettingsKeyDoubleClickURLToLaunch];
|
||||
if(NO == openURL) {
|
||||
[[NSUserDefaults standardUserDefaults] setInteger:MPDoubleClickURLActionOpen forKey:kMPSettingsKeyDoubleClickURLAction];
|
||||
/*
|
||||
Default was NO so if the key was not set the correct action now should be MPDoubleClickURLActionCopy
|
||||
But MPDoubleClickURLActionCopy is the default we cannot simply add this value.
|
||||
Hence we chose to only migrate a changed default and let the "old" default silenty be updated
|
||||
This is a worth trade-off since the other solution will always re-set the default
|
||||
*/
|
||||
if(nil == [NSUserDefaults.standardUserDefaults objectForKey:kMPDeprecatedSettingsKeyDoubleClickURLToLaunch]) {
|
||||
return; // the value was not set, do nothing since we cannot determine what to do
|
||||
}
|
||||
/* only update the settings if the defaults return an explicit set value */
|
||||
if([NSUserDefaults.standardUserDefaults boolForKey:kMPDeprecatedSettingsKeyDoubleClickURLToLaunch]) {
|
||||
[NSUserDefaults.standardUserDefaults setInteger:MPDoubleClickURLActionOpen forKey:kMPSettingsKeyDoubleClickURLAction];
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)_migrateEntrySearchFlags {
|
||||
/* Entry filters are now stored as archivd search context not just flags */
|
||||
NSInteger flags = [[NSUserDefaults standardUserDefaults] integerForKey:kMPDeprecatedSettingsKeyEntrySearchFilterMode];
|
||||
/* Entry filters are now stored as archived search context not just flags */
|
||||
NSInteger flags = [NSUserDefaults.standardUserDefaults integerForKey:kMPDeprecatedSettingsKeyEntrySearchFilterMode];
|
||||
if(flags != 0) {
|
||||
MPEntrySearchContext *context = [[MPEntrySearchContext alloc] initWithString:nil flags:flags];
|
||||
NSData *contextData = [NSKeyedArchiver archivedDataWithRootObject:context];
|
||||
[[NSUserDefaults standardUserDefaults] setObject:contextData forKey:kMPSettingsKeyEntrySearchFilterContext];
|
||||
[NSUserDefaults.standardUserDefaults setObject:contextData forKey:kMPSettingsKeyEntrySearchFilterContext];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,7 +256,7 @@ NSString *const kMPDepricatedSettingsKeyLoadUnsecurePlugins = @"MP
|
||||
Database file paths was stored as plain text in keyfile mapping.
|
||||
We only need to store the key file url in plain text, thus hashing the path is sufficent
|
||||
*/
|
||||
NSDictionary<NSString *, NSString *> *currentMapping = [[NSUserDefaults standardUserDefaults] dictionaryForKey:kMPSettingsKeyRememeberdKeysForDatabases];
|
||||
NSDictionary<NSString *, NSString *> *currentMapping = [NSUserDefaults.standardUserDefaults dictionaryForKey:kMPSettingsKeyRememeberdKeysForDatabases];
|
||||
if(!currentMapping) {
|
||||
return;
|
||||
}
|
||||
@@ -262,7 +278,7 @@ NSString *const kMPDepricatedSettingsKeyLoadUnsecurePlugins = @"MP
|
||||
}
|
||||
}
|
||||
if(didHash) {
|
||||
[[NSUserDefaults standardUserDefaults] setObject:hashedDict forKey:kMPSettingsKeyRememeberdKeysForDatabases];
|
||||
[NSUserDefaults.standardUserDefaults setObject:hashedDict forKey:kMPSettingsKeyRememeberdKeysForDatabases];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
self = [super init];
|
||||
if(self) {
|
||||
_binary = binary;
|
||||
_loadScheduled = NO;
|
||||
[MPTemporaryFileStorageCenter.defaultCenter registerStorage:self];
|
||||
}
|
||||
return self;
|
||||
@@ -64,17 +63,8 @@
|
||||
#pragma mark QLPreviewPanelDataSource
|
||||
|
||||
- (id<QLPreviewItem>)previewPanel:(QLPreviewPanel *)panel previewItemAtIndex:(NSInteger)index {
|
||||
if(!self.temporaryFileURL && !self.loadScheduled) {
|
||||
self.loadScheduled = YES;
|
||||
dispatch_queue_t defaultQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
|
||||
dispatch_async(defaultQueue, ^{
|
||||
BOOL success = [self _saveBinary:self.binary];
|
||||
if(success){
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[panel refreshCurrentPreviewItem];
|
||||
});
|
||||
}
|
||||
});
|
||||
if(!self.temporaryFileURL) {
|
||||
[self _saveBinary:self.binary];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -98,11 +88,22 @@
|
||||
#pragma mark Private
|
||||
|
||||
- (BOOL)_saveBinary:(KPKBinary *)binary {
|
||||
if(!binary || !binary.data || !binary.name || [binary.name length] == 0) {
|
||||
if(!binary || !binary.data || !binary.name || binary.name.length == 0) {
|
||||
return NO;
|
||||
}
|
||||
NSString *fileName = [NSString stringWithFormat:@"%@_%@", NSProcessInfo.processInfo.globallyUniqueString, binary.name];
|
||||
self.temporaryFileURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:fileName]];
|
||||
|
||||
NSURL *userDesktop = [NSFileManager.defaultManager URLsForDirectory:NSDesktopDirectory inDomains:NSUserDomainMask].firstObject;
|
||||
if(!userDesktop) {
|
||||
return NO;
|
||||
}
|
||||
NSError *error;
|
||||
NSURL *tempURL = [NSFileManager.defaultManager URLForDirectory:NSItemReplacementDirectory inDomain:NSUserDomainMask appropriateForURL:userDesktop create:YES error:&error];
|
||||
if(!tempURL) {
|
||||
NSLog(@"Unable to create temporary directory for file preview: %@", error.description);
|
||||
return NO;
|
||||
}
|
||||
self.temporaryFileURL = [tempURL URLByAppendingPathComponent:fileName isDirectory:NO];
|
||||
|
||||
BOOL success = [binary.data writeToURL:self.temporaryFileURL options:0 error:0];
|
||||
if(!success) {
|
||||
@@ -131,7 +132,9 @@
|
||||
}
|
||||
|
||||
+ (void)_runCleanupForPath:(NSString *)path {
|
||||
NSTask *task = [[NSTask alloc] init];
|
||||
NSTask *task = [[NSTask alloc] init];
|
||||
|
||||
// FIXME: Remove when moving to 10.12 as deploy target
|
||||
|
||||
NSURL *srmURL = [NSURL fileURLWithPath:@"/usr/bin/srm"];
|
||||
NSURL *rmURL = [NSURL fileURLWithPath:@"/bin/rm"];
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
if(self) {
|
||||
self.focusRingType = NSFocusRingTypeNone;
|
||||
self.bezelStyle = NSTexturedRoundedBezelStyle;
|
||||
[self.cell setImageScaling:NSImageScaleProportionallyDown];
|
||||
((NSButtonCell *)(self.cell)).imageScaling = NSImageScaleProportionallyDown;
|
||||
[self setButtonType:NSMomentaryPushInButton];
|
||||
self.imagePosition = NSImageOnly;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,18 @@
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
APPKIT_EXTERN NSString *const MPToolbarItemIdentifierLock;
|
||||
APPKIT_EXTERN NSString *const MPToolbarItemIdentifierAddGroup;
|
||||
APPKIT_EXTERN NSString *const MPToolbarItemIdentifierAddEntry;
|
||||
APPKIT_EXTERN NSString *const MPToolbarItemIdentifierDelete;
|
||||
APPKIT_EXTERN NSString *const MPToolbarItemIdentifierAction;
|
||||
APPKIT_EXTERN NSString *const MPToolbarItemIdentifierInspector;
|
||||
APPKIT_EXTERN NSString *const MPToolbarItemIdentifierSearch;
|
||||
APPKIT_EXTERN NSString *const MPToolbarItemIdentifierCopyUsername;
|
||||
APPKIT_EXTERN NSString *const MPToolbarItemIdentifierCopyPassword;
|
||||
APPKIT_EXTERN NSString *const MPToolbarItemIdentifierHistory;
|
||||
APPKIT_EXTERN NSString *const MPToolbarItemIdentifierAutotype;
|
||||
|
||||
@class MPDocument;
|
||||
|
||||
@interface MPToolbarDelegate : NSObject <NSToolbarDelegate, NSTextFieldDelegate>
|
||||
|
||||
@@ -38,17 +38,17 @@
|
||||
#import "NSApplication+MPAdditions.h"
|
||||
#import "MPAppDelegate.h"
|
||||
|
||||
NSString *const MPToolbarItemLock = @"TOOLBAR_LOCK";
|
||||
NSString *const MPToolbarItemAddGroup = @"TOOLBAR_ADD_GROUP";
|
||||
NSString *const MPToolbarItemAddEntry = @"TOOLBAR_ADD_ENTRY";
|
||||
NSString *const MPToolbarItemDelete =@"TOOLBAR_DELETE";
|
||||
NSString *const MPToolbarItemAction = @"TOOLBAR_ACTION";
|
||||
NSString *const MPToolbarItemInspector = @"TOOLBAR_INSPECTOR";
|
||||
NSString *const MPToolbarItemSearch = @"TOOLBAR_SEARCH";
|
||||
NSString *const MPToolbarItemCopyUsername = @"TOOLBAR_COPY_USERNAME";
|
||||
NSString *const MPToolbarItemCopyPassword = @"TOOLBAR_COPY_PASSWORD";
|
||||
NSString *const MPToolbarItemHistory = @"TOOLBAR_HISTORY";
|
||||
NSString *const MPToolbarItemAutotype = @"TOOLBAR_AUTOTYPE";
|
||||
NSString *const MPToolbarItemIdentifierLock = @"TOOLBAR_LOCK";
|
||||
NSString *const MPToolbarItemIdentifierAddGroup = @"TOOLBAR_ADD_GROUP";
|
||||
NSString *const MPToolbarItemIdentifierAddEntry = @"TOOLBAR_ADD_ENTRY";
|
||||
NSString *const MPToolbarItemIdentifierDelete = @"TOOLBAR_DELETE";
|
||||
NSString *const MPToolbarItemIdentifierAction = @"TOOLBAR_ACTION";
|
||||
NSString *const MPToolbarItemIdentifierInspector = @"TOOLBAR_INSPECTOR";
|
||||
NSString *const MPToolbarItemIdentifierSearch = @"TOOLBAR_SEARCH";
|
||||
NSString *const MPToolbarItemIdentifierCopyUsername = @"TOOLBAR_COPY_USERNAME";
|
||||
NSString *const MPToolbarItemIdentifierCopyPassword = @"TOOLBAR_COPY_PASSWORD";
|
||||
NSString *const MPToolbarItemIdentifierHistory = @"TOOLBAR_HISTORY";
|
||||
NSString *const MPToolbarItemIdentifierAutotype = @"TOOLBAR_AUTOTYPE";
|
||||
|
||||
@interface MPToolbarDelegate() {
|
||||
MPAddEntryContextMenuDelegate *_addEntryMenuDelegate;
|
||||
@@ -72,27 +72,28 @@ NSString *const MPToolbarItemAutotype = @"TOOLBAR_AUTOTYPE";
|
||||
if (self) {
|
||||
_didShowToolbarForSearch = NO;
|
||||
_didAddSearchfieldForSearch = NO;
|
||||
_toolbarIdentifiers = @[ MPToolbarItemAddEntry,
|
||||
MPToolbarItemDelete,
|
||||
MPToolbarItemAddGroup,
|
||||
MPToolbarItemAction,
|
||||
MPToolbarItemCopyPassword,
|
||||
MPToolbarItemCopyUsername,
|
||||
_toolbarIdentifiers = @[ MPToolbarItemIdentifierAddEntry,
|
||||
MPToolbarItemIdentifierDelete,
|
||||
MPToolbarItemIdentifierAddGroup,
|
||||
MPToolbarItemIdentifierAction,
|
||||
MPToolbarItemIdentifierCopyPassword,
|
||||
MPToolbarItemIdentifierCopyUsername,
|
||||
NSToolbarFlexibleSpaceItemIdentifier,
|
||||
MPToolbarItemSearch,
|
||||
MPToolbarItemLock,
|
||||
MPToolbarItemInspector,
|
||||
MPToolbarItemHistory,
|
||||
MPToolbarItemAutotype ];
|
||||
_defaultToolbarIdentifiers = @[ MPToolbarItemAddEntry,
|
||||
MPToolbarItemDelete,
|
||||
MPToolbarItemAddGroup,
|
||||
MPToolbarItemAutotype,
|
||||
MPToolbarItemAction,
|
||||
MPToolbarItemIdentifierSearch,
|
||||
MPToolbarItemIdentifierLock,
|
||||
MPToolbarItemIdentifierInspector,
|
||||
MPToolbarItemIdentifierHistory,
|
||||
MPToolbarItemIdentifierAutotype ];
|
||||
_defaultToolbarIdentifiers = @[ MPToolbarItemIdentifierAddEntry,
|
||||
MPToolbarItemIdentifierDelete,
|
||||
MPToolbarItemIdentifierAddGroup,
|
||||
MPToolbarItemIdentifierAutotype,
|
||||
MPToolbarItemIdentifierAction,
|
||||
NSToolbarFlexibleSpaceItemIdentifier,
|
||||
MPToolbarItemSearch,
|
||||
MPToolbarItemLock,
|
||||
MPToolbarItemInspector ];
|
||||
MPToolbarItemIdentifierSearch,
|
||||
NSToolbarFlexibleSpaceItemIdentifier,
|
||||
MPToolbarItemIdentifierLock,
|
||||
MPToolbarItemIdentifierInspector ];
|
||||
_toolbarImages = [self createToolbarImages];
|
||||
_toolbarItems = [[NSMutableDictionary alloc] initWithCapacity:[self.toolbarIdentifiers count]];
|
||||
_addEntryMenuDelegate = [[MPAddEntryContextMenuDelegate alloc] init];
|
||||
@@ -111,8 +112,9 @@ NSString *const MPToolbarItemAutotype = @"TOOLBAR_AUTOTYPE";
|
||||
item = [[MPToolbarItem alloc] initWithItemIdentifier:itemIdentifier];
|
||||
NSString *itemLabel = [self _localizedLabelForToolbarItemIdentifier:itemIdentifier];
|
||||
item.label = itemLabel;
|
||||
item.paletteLabel = itemLabel;
|
||||
|
||||
if([itemIdentifier isEqualToString:MPToolbarItemAction]) {
|
||||
if([itemIdentifier isEqualToString:MPToolbarItemIdentifierAction]) {
|
||||
NSPopUpButton *popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(0, 0, 50, 32) pullsDown:YES];
|
||||
popupButton.bezelStyle = NSTexturedRoundedBezelStyle;
|
||||
popupButton.focusRingType = NSFocusRingTypeNone;
|
||||
@@ -125,9 +127,9 @@ NSString *const MPToolbarItemAutotype = @"TOOLBAR_AUTOTYPE";
|
||||
|
||||
NSMenu *menu = [[NSMenu alloc] init];
|
||||
NSMenuItem *actionImageItem = [[NSMenuItem alloc] initWithTitle:@"" action:NULL keyEquivalent:@""];
|
||||
actionImageItem.image = self.toolbarImages[MPToolbarItemAction];
|
||||
actionImageItem.image = self.toolbarImages[MPToolbarItemIdentifierAction];
|
||||
[menu addItem:actionImageItem];
|
||||
NSArray *menuItems = [MPContextMenuHelper contextMenuItemsWithItems:MPContextMenuExtended];
|
||||
NSArray *menuItems = [MPContextMenuHelper contextMenuItemsWithItems:MPContextMenuExtended|MPContextMenuShowGroupInOutline];
|
||||
for(NSMenuItem *item in menuItems) {
|
||||
[menu addItem:item];
|
||||
}
|
||||
@@ -142,7 +144,7 @@ NSString *const MPToolbarItemAutotype = @"TOOLBAR_AUTOTYPE";
|
||||
item.menuFormRepresentation = menuRepresentation;
|
||||
item.view = popupButton;
|
||||
}
|
||||
else if( [itemIdentifier isEqualToString:MPToolbarItemAddEntry]) {
|
||||
else if( [itemIdentifier isEqualToString:MPToolbarItemIdentifierAddEntry]) {
|
||||
MPContextButton *button = [[MPContextButton alloc] initWithFrame:NSMakeRect(0, 0, 32, 32)];
|
||||
button.action = [self _actionForToolbarItemIdentifier:itemIdentifier];
|
||||
NSImage *image = self.toolbarImages[itemIdentifier];
|
||||
@@ -167,7 +169,7 @@ NSString *const MPToolbarItemAutotype = @"TOOLBAR_AUTOTYPE";
|
||||
item.menuFormRepresentation = menuRepresentation;
|
||||
|
||||
}
|
||||
else if( [itemIdentifier isEqualToString:MPToolbarItemSearch]){
|
||||
else if( [itemIdentifier isEqualToString:MPToolbarItemIdentifierSearch]){
|
||||
NSSearchField *searchField = [[NSSearchField alloc] init];
|
||||
searchField.action = @selector(updateSearch:);
|
||||
NSSearchFieldCell *cell = searchField.cell;
|
||||
@@ -177,9 +179,10 @@ NSString *const MPToolbarItemAutotype = @"TOOLBAR_AUTOTYPE";
|
||||
item.view = searchField;
|
||||
/* Use default size base on documentation */
|
||||
item.minSize = NSMakeSize(140, 32);
|
||||
item.maxSize = NSMakeSize(240, 32);
|
||||
item.maxSize = NSMakeSize(400, 32);
|
||||
NSMenu *templateMenu = [self _allocateSearchMenuTemplate];
|
||||
searchField.searchMenuTemplate = templateMenu;
|
||||
searchField.placeholderString = NSLocalizedString(@"SEARCH_EVERYWHERE", @"Placeholder string displayed in the search field in the toolbar");
|
||||
/* 10.10 does not support NSSearchFieldDelegate */
|
||||
((NSTextField *)searchField).delegate = self;
|
||||
self.searchField = searchField;
|
||||
@@ -215,16 +218,16 @@ NSString *const MPToolbarItemAutotype = @"TOOLBAR_AUTOTYPE";
|
||||
}
|
||||
|
||||
- (NSDictionary *)createToolbarImages {
|
||||
NSDictionary *imageDict = @{ MPToolbarItemLock: [NSImage imageNamed:NSImageNameLockUnlockedTemplate],
|
||||
MPToolbarItemAddEntry: [MPIconHelper icon:MPIconAddEntry],
|
||||
MPToolbarItemAddGroup: [MPIconHelper icon:MPIconAddFolder],
|
||||
MPToolbarItemCopyUsername : [MPIconHelper icon:MPIconIdentity],
|
||||
MPToolbarItemCopyPassword : [MPIconHelper icon:MPIconPassword],
|
||||
MPToolbarItemDelete: [MPIconHelper icon:MPIconTrash],
|
||||
MPToolbarItemAction: [NSImage imageNamed:NSImageNameActionTemplate],
|
||||
MPToolbarItemInspector: [MPIconHelper icon:MPIconInfo],
|
||||
MPToolbarItemHistory: [MPIconHelper icon:MPIconHistory],
|
||||
MPToolbarItemAutotype : [MPIconHelper icon:MPIconKeyboard]
|
||||
NSDictionary *imageDict = @{ MPToolbarItemIdentifierLock: [NSImage imageNamed:NSImageNameLockLockedTemplate],
|
||||
MPToolbarItemIdentifierAddEntry: [MPIconHelper icon:MPIconAddEntry],
|
||||
MPToolbarItemIdentifierAddGroup: [MPIconHelper icon:MPIconAddFolder],
|
||||
MPToolbarItemIdentifierCopyUsername : [MPIconHelper icon:MPIconIdentity],
|
||||
MPToolbarItemIdentifierCopyPassword : [MPIconHelper icon:MPIconPassword],
|
||||
MPToolbarItemIdentifierDelete: [MPIconHelper icon:MPIconTrash],
|
||||
MPToolbarItemIdentifierAction: [NSImage imageNamed:NSImageNameActionTemplate],
|
||||
MPToolbarItemIdentifierInspector: [MPIconHelper icon:MPIconInfo],
|
||||
MPToolbarItemIdentifierHistory: [MPIconHelper icon:MPIconHistory],
|
||||
MPToolbarItemIdentifierAutotype : [MPIconHelper icon:MPIconKeyboard]
|
||||
};
|
||||
return imageDict;
|
||||
}
|
||||
@@ -237,12 +240,20 @@ NSString *const MPToolbarItemAutotype = @"TOOLBAR_AUTOTYPE";
|
||||
|
||||
#pragma mark - NSSearchFieldDelegate
|
||||
- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector {
|
||||
if(control != self.searchField) {
|
||||
return NO;
|
||||
}
|
||||
if(commandSelector == @selector(insertNewline:) || commandSelector == @selector(moveDown:)) {
|
||||
/* Dispatch the focus loss since doing it now will break recent search storage */
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[[NSApp targetForAction:@selector(focusEntries:) to:nil from:self] focusEntries:self];
|
||||
});
|
||||
}
|
||||
if(commandSelector == @selector(cancelOperation:) ) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[[NSApp targetForAction:@selector(exitSearch:) to:nil from:self] exitSearch:nil];
|
||||
});
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
@@ -251,17 +262,17 @@ NSString *const MPToolbarItemAutotype = @"TOOLBAR_AUTOTYPE";
|
||||
static NSDictionary *labelDict;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
labelDict = @{ MPToolbarItemLock: NSLocalizedString(@"LOCK", @"Toolbar item to Lock the database"),
|
||||
MPToolbarItemAction: NSLocalizedString(@"ACTION", @"Toolbar item with action menu"),
|
||||
MPToolbarItemAddEntry: NSLocalizedString(@"NEW_ENTRY", @"Toolbar item new entry"),
|
||||
MPToolbarItemAddGroup: NSLocalizedString(@"NEW_GROUP", @"Toolbar item new group"),
|
||||
MPToolbarItemCopyPassword: NSLocalizedString(@"COPY_PASSWORD", @"Toolbar item copy password"),
|
||||
MPToolbarItemCopyUsername: NSLocalizedString(@"COPY_USERNAME", @"Toolbar item copy username"),
|
||||
MPToolbarItemDelete: NSLocalizedString(@"DELETE", @"Toolbar item delete item"),
|
||||
MPToolbarItemInspector: NSLocalizedString(@"INSPECTOR", @"Toolbar item toggle inspector"),
|
||||
MPToolbarItemSearch: NSLocalizedString(@"SEARCH", @"Search input in Toolbar "),
|
||||
MPToolbarItemHistory: NSLocalizedString(@"SHOW_HISTORY", @"Toolbar item to toggle history display"),
|
||||
MPToolbarItemAutotype: NSLocalizedString(@"TOOLBAR_PERFORM_AUTOTYPE_FOR_ENTRY", @"Toolbar item to perform autotype")
|
||||
labelDict = @{ MPToolbarItemIdentifierLock: NSLocalizedString(@"LOCK", @"Toolbar item to Lock the database"),
|
||||
MPToolbarItemIdentifierAction: NSLocalizedString(@"ACTION", @"Toolbar item with action menu"),
|
||||
MPToolbarItemIdentifierAddEntry: NSLocalizedString(@"NEW_ENTRY", @"Toolbar item new entry"),
|
||||
MPToolbarItemIdentifierAddGroup: NSLocalizedString(@"NEW_GROUP", @"Toolbar item new group"),
|
||||
MPToolbarItemIdentifierCopyPassword: NSLocalizedString(@"COPY_PASSWORD", @"Toolbar item copy password"),
|
||||
MPToolbarItemIdentifierCopyUsername: NSLocalizedString(@"COPY_USERNAME", @"Toolbar item copy username"),
|
||||
MPToolbarItemIdentifierDelete: NSLocalizedString(@"DELETE", @"Toolbar item delete item"),
|
||||
MPToolbarItemIdentifierInspector: NSLocalizedString(@"INSPECTOR", @"Toolbar item toggle inspector"),
|
||||
MPToolbarItemIdentifierSearch: NSLocalizedString(@"SEARCH", @"Search input in Toolbar "),
|
||||
MPToolbarItemIdentifierHistory: NSLocalizedString(@"SHOW_HISTORY", @"Toolbar item to toggle history display"),
|
||||
MPToolbarItemIdentifierAutotype: NSLocalizedString(@"TOOLBAR_PERFORM_AUTOTYPE_FOR_ENTRY", @"Toolbar item to perform autotype")
|
||||
};
|
||||
});
|
||||
return labelDict[identifier];
|
||||
@@ -271,15 +282,15 @@ NSString *const MPToolbarItemAutotype = @"TOOLBAR_AUTOTYPE";
|
||||
static NSDictionary *actionDict;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
actionDict = @{ MPToolbarItemLock: @(MPActionLock),
|
||||
MPToolbarItemAddEntry: @(MPActionAddEntry),
|
||||
MPToolbarItemAddGroup: @(MPActionAddGroup),
|
||||
MPToolbarItemDelete: @(MPActionDelete),
|
||||
MPToolbarItemCopyPassword: @(MPActionCopyPassword),
|
||||
MPToolbarItemCopyUsername: @(MPActionCopyUsername),
|
||||
MPToolbarItemInspector: @(MPActionToggleInspector),
|
||||
MPToolbarItemHistory: @(MPActionShowEntryHistory),
|
||||
MPToolbarItemAutotype: @(MPActionPerformAutotypeForSelectedEntry)
|
||||
actionDict = @{ MPToolbarItemIdentifierLock: @(MPActionLock),
|
||||
MPToolbarItemIdentifierAddEntry: @(MPActionAddEntry),
|
||||
MPToolbarItemIdentifierAddGroup: @(MPActionAddGroup),
|
||||
MPToolbarItemIdentifierDelete: @(MPActionDelete),
|
||||
MPToolbarItemIdentifierCopyPassword: @(MPActionCopyPassword),
|
||||
MPToolbarItemIdentifierCopyUsername: @(MPActionCopyUsername),
|
||||
MPToolbarItemIdentifierInspector: @(MPActionToggleInspector),
|
||||
MPToolbarItemIdentifierHistory: @(MPActionShowEntryHistory),
|
||||
MPToolbarItemIdentifierAutotype: @(MPActionPerformAutotypeForSelectedEntry)
|
||||
};
|
||||
});
|
||||
MPActionType actionType = (MPActionType)[actionDict[identifier] integerValue];
|
||||
@@ -293,7 +304,7 @@ NSString *const MPToolbarItemAutotype = @"TOOLBAR_AUTOTYPE";
|
||||
[menu addItem:item];
|
||||
|
||||
[menu addItem:[NSMenuItem separatorItem]];
|
||||
|
||||
|
||||
item = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"RECENT_SEARCHES", @"Recent searches menu item") action:NULL keyEquivalent:@""];
|
||||
item.tag = NSSearchFieldRecentsTitleMenuItemTag;
|
||||
[menu addItem:item];
|
||||
@@ -312,9 +323,9 @@ NSString *const MPToolbarItemAutotype = @"TOOLBAR_AUTOTYPE";
|
||||
- (void)_didEnterSearch:(NSNotification *)notification {
|
||||
/* We enter search. If there is no Item to search in the toolbar, we need to add it */
|
||||
NSArray *currentItems = self.toolbar.items;
|
||||
NSToolbarItem *searchItem = self.toolbarItems[MPToolbarItemSearch];
|
||||
NSToolbarItem *searchItem = self.toolbarItems[MPToolbarItemIdentifierSearch];
|
||||
if(!searchItem || ![currentItems containsObject:searchItem]) {
|
||||
[self.toolbar insertItemWithItemIdentifier:MPToolbarItemSearch atIndex:[currentItems count]];
|
||||
[self.toolbar insertItemWithItemIdentifier:MPToolbarItemIdentifierSearch atIndex:[currentItems count]];
|
||||
_didAddSearchfieldForSearch = YES;
|
||||
}
|
||||
/* Then we should make sure the toolbar is visible. Just to make life easier */
|
||||
@@ -334,14 +345,14 @@ NSString *const MPToolbarItemAutotype = @"TOOLBAR_AUTOTYPE";
|
||||
}
|
||||
|
||||
- (void)_didExitSearch:(NSNotification *)notification {
|
||||
[self.searchField setStringValue:@""];
|
||||
self.searchField.stringValue = @"";
|
||||
NSWindow *window = [self.searchField window];
|
||||
/* Resign first responder form search field only if it was the first responder */
|
||||
if(window.firstResponder == [self.searchField currentEditor]) {
|
||||
[window makeFirstResponder:nil];
|
||||
}
|
||||
if(_didAddSearchfieldForSearch) {
|
||||
NSToolbarItem *searchItem = self.toolbarItems[MPToolbarItemSearch];
|
||||
NSToolbarItem *searchItem = self.toolbarItems[MPToolbarItemIdentifierSearch];
|
||||
NSUInteger index = [self.toolbar.items indexOfObject:searchItem];
|
||||
if(index != NSNotFound) {
|
||||
[self.toolbar removeItemAtIndex:index];
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user