204 Commits

Author SHA1 Message Date
Michael Starke
99ea0d7a14 Versioning now respects builds from release branches 2020-03-25 21:12:33 +01:00
Michael Starke
d7f6bcc6c3 Tags are now search case insensitive (fixes #1048)
The issue was that the tags string array was not correctly searched case insensitive via the predicate CONTAINS
2020-03-25 21:03:28 +01:00
Michael Starke
3731e92339 Bumped version 2020-03-17 11:51:12 +01:00
Benjamin Blonde
f609ba9795 Update french localizations (#1047)
- Add 121 missing translations
- Tweak few old translations

Co-authored-by: Michael Starke <michael.starke@hicknhack-software.com>
2020-03-17 11:50:00 +01:00
Bartłomiej Jakub Kwiatek
64ad7d9c08 Updated polish localization (#1042)
Co-authored-by: Bartlomiej.Kwiatek <bartlomiej.kwiatek@vml.com>
2020-03-17 11:50:00 +01:00
Michael Starke
8b3cc34ab5 Fixe missing custom cell in MPPathControl 2020-03-17 11:48:06 +01:00
Michael Starke
b028ef51f9 Updated localization 2020-01-28 10:44:31 +01:00
Michael Starke
ae9278c4b5 Added privacy usage descriptions for all folders to enhance macOS 10.15 Catalina experience 2020-01-28 10:39:15 +01:00
Michael Starke
86d4defc78 Removed ad-hoc signing 2020-01-28 10:28:49 +01:00
Michael Starke
c85a9cdce1 Fixed autotype regression preventing self-autotyping. Added re-hiding for special placeholders 2020-01-28 10:28:42 +01:00
Michael Starke
9409887942 Introduced direct signing of all parts since --deep did not sign Autoupdate and fileop in Sparkle.framework 2020-01-28 09:41:07 +01:00
Michael Starke
40c62954e4 Removed special code signing id for macOs which caused Xcode to choke on the project 2020-01-28 09:40:18 +01:00
Michael Starke
c6f93ef59a Updated copyright to 2020 2020-01-27 12:25:13 +01:00
Michael Starke
5eef186ab2 Updated contributors 2020-01-27 10:30:36 +01:00
Michael Starke
6c60d72ef9 Update CONTRIBUTE.md 2020-01-27 10:24:25 +01:00
Michael Starke
217b311783 Update CONTRIBUTE.md 2020-01-27 10:24:17 +01:00
Michael Starke
8cd5273082 Added download option for XLIFF files 2020-01-27 10:23:44 +01:00
Michael Starke
3e8a320598 Updated german localization 2020-01-24 12:10:58 +01:00
Michael Starke
0197bdc5bc Added missing english localization 2020-01-24 11:43:36 +01:00
Michael Starke
a425acea4d Updated english localization 2020-01-24 11:41:45 +01:00
Michael Starke
c4222a3159 Fixed regression resulting in auto-type never timing out. 2020-01-24 11:39:42 +01:00
Michael Starke
bd0fe6baf8 Updated localizations 2020-01-24 09:37:06 +01:00
Michael Starke
b2999ca8a8 Merge branch 'feature/refactor_autotype' 2020-01-22 15:11:41 +01:00
Michael Starke
77d96976ec Refactored Autotype to use environment for better encapsulation of parameters 2020-01-22 15:11:28 +01:00
Michael Starke
a4b9b0be8b Formatting 2020-01-22 10:13:33 +01:00
Michael Starke
8e52da7069 Better placeholder for search field to clarify location of the search. Also made the search field larger. 2020-01-21 15:27:38 +01:00
Michael Starke
228170c717 Center search in 10.14 and above, keep it "centerish" in older systems 2020-01-21 15:12:25 +01:00
Michael Starke
2216a14729 Broken WIP commit 2020-01-21 14:38:52 +01:00
Michael Starke
77f3f23cfe Use class property 2020-01-15 13:00:14 +01:00
Michael Starke
07ae4675d4 Fixed typos in localization 2020-01-15 13:00:06 +01:00
Michael Starke
f2279863db removed unnecessary method 2020-01-15 12:59:39 +01:00
Michael Starke
df68d0140f Updated localizations 2020-01-15 12:59:29 +01:00
Michael Starke
1b6efbfd0c Added sanity checks to key file selection in unlock screen (fixes #1008) 2020-01-14 14:54:15 +01:00
Michael Starke
626bb35f80 Re-hide MacPass if it was shown only for autotype candidate selection (fixes #964) 2020-01-13 13:46:24 +01:00
Michael Starke
e6bb9ad191 use class propeties 2020-01-13 12:07:43 +01:00
Michael Starke
4cfe54b65c Updated documentation on export plugin 2020-01-10 15:01:53 +01:00
Michael Starke
2b2e5ddbea Merge branch 'feature/import_plugins' 2020-01-10 10:47:59 +01:00
Michael Starke
334451471e Removed delayed write of preview files to fix missing preview in macOs 10.15 Catalina (fix #1016) 2020-01-10 10:47:11 +01:00
Michael Starke
4069052c86 Using class properties 2020-01-10 10:43:13 +01:00
Michael Starke
7be5190ada Updated comments 2020-01-10 10:42:58 +01:00
Michael Starke
7a1510b77b Using Carthage setup for TransformerKit 2020-01-08 15:23:36 +01:00
Michael Starke
f16c767cbd Use textual date picker instead of graphical one. Fixes #923 2019-12-18 15:45:00 +01:00
Michael Starke
3f76188bf5 Modern objective C 2019-12-18 15:44:26 +01:00
Michael Starke
1215b7317b Merge branch 'master' into feature/import_plugins
# Conflicts:
#	MacPass.xcodeproj/project.pbxproj
2019-12-17 16:27:43 +01:00
Michael Starke
e5ba73589b Cleaned up merge of LockOnScreenSleep feature. Updated fonts 2019-12-17 14:18:24 +01:00
georgesnow
9ba902471c Add Lock database on Screen Sleep (#998)
* added lock databse on Screen sleep

* remove unneeded change

* fix unregister screen sleep method

* fixed constraints and checkbox label
2019-12-17 13:59:01 +01:00
Michael Starke
b1568c5eef Using documented way to create temporary folders for storing preview content (#1016) 2019-12-17 13:47:15 +01:00
Michael Starke
8535579de2 Updated to Xcode 11 2019-12-13 11:18:34 +01:00
Michael Starke
6ec89e146c Merge branch 'refs/heads/master' into feature/import_plugins 2019-11-27 23:05:46 +01:00
Michael Starke
09a7a15141 Altered screen recording check to Craig Hockenberry's solution 2019-11-27 12:02:45 +01:00
Michael Starke
9b77790ddc Use blog based api instead of block one to track down macOS 10.15 bug 2019-11-22 16:30:21 +01:00
Anton Glezman
16cdd4dd4f Fixed overlay window image color (#999)
* Fixed overlay window image color

* Fixed color property
2019-11-07 20:43:23 +01:00
Michael Starke
0a7fcc415c Disabled currently unused context button for add fields button (fixes #995) 2019-11-04 16:11:44 +01:00
Michael Starke
ff72632b3b Do show info when no recent documents are present in Welcome Window (fixes #996) 2019-11-04 16:08:24 +01:00
Michael Starke
b6a7240534 Bumped version. Ensure versioning is always done after Info.plist was copied. 2019-11-04 15:48:36 +01:00
Michael Starke
f10735f96f Changed screen recording detection to use "at least one window name should be present) 2019-11-04 15:47:54 +01:00
Michael Starke
ba538d05af note to use xmllint to check for notarization status 2019-11-04 15:45:34 +01:00
Michael Starke
3639913e6d Re-added english localization for Info.plist since it seems to break on macOS 10.15 2019-11-04 12:38:34 +01:00
Michael Starke
b87e20ca7e prepare release now works 2019-11-04 10:38:45 +01:00
Michael Starke
c7bdce46ff first stab at a automated release 2019-11-01 16:07:42 +01:00
Michael Starke
11bea5fa32 Removed magic numbers 2019-11-01 16:07:42 +01:00
Michael Starke
e8a6af086c Using cancelOperation: since this is called by pressing the Esc key. 2019-11-01 16:07:42 +01:00
Michael Starke
f1033c1006 Use properties 2019-11-01 16:07:42 +01:00
Anton Glezman
264866dff0 Fixed missed localizations (#990)
Thank you very much!
2019-11-01 14:43:39 +01:00
Oleksandr Yakubchyk
631741d30b Fixed #945 Cancel search mode while the search field is empty (#946) 2019-10-30 16:02:06 +01:00
Michael Starke
6897f9e51c Added Github sponsorship details 2019-10-30 14:50:46 +01:00
Michael Starke
21a5b5d6bb Using class properties 2019-10-30 10:29:23 +01:00
Michael Starke
3817bf503f Fixed re-setting of url copy or open after each application launch (fixes #989) 2019-10-30 10:14:37 +01:00
Michael Starke
2beb033572 Updated contributors 2019-10-28 17:03:04 +01:00
Michael Starke
d7b016e5ef Bumped to 0.7.10 2019-10-28 15:06:15 +01:00
Michael Starke
46b6ab3925 Added entitlements file for codesigning 2019-10-28 14:18:15 +01:00
Michael Starke
c5ed3c42e6 Updated Sparkle to 1.22.0 2019-10-09 17:31:56 +02:00
Michael Starke
00d69d5bad Update FUNDING.yml 2019-09-17 13:57:32 +02:00
Michael Starke
fa58c7e423 Create FUNDING.yml 2019-09-17 13:55:23 +02:00
Michael Starke
f134290c27 wired up button to actually do something 2019-09-17 13:08:29 +02:00
Michael Starke
3b244c3145 Added button to initiate screen recording permission request on macOS 10.15 Catalina 2019-09-10 14:47:56 +02:00
Michael Starke
541ef6e749 Added correct system preferences url to open screen capture privacy pane 2019-09-10 14:12:54 +02:00
Michael Starke
eb9d15ffa5 Use enter to accept a field in PICKFIELD view 2019-09-09 11:03:55 +02:00
Michael Starke
05cfb73734 Updated Icons for exported UTIs 2019-09-03 12:25:01 +02:00
Michael Starke
d9322d7544 split localisation export into singel language builds to make them more travis friendly 2019-08-30 11:04:20 +02:00
Michael Starke
7de8d0abd5 re-added missing exported languages 2019-08-30 10:46:41 +02:00
Michael Starke
3289ffb2e4 Fixed typo 2019-08-29 21:06:16 +02:00
Michael Starke
38d64c7cb9 Added export localisations step to continous deployment for easier workflow 2019-08-29 17:17:03 +02:00
Michael Starke
01b1372dda Merge branch 'master' into feature/import_plugins 2019-08-29 12:02:25 +02:00
Chester Liu
c76a8baa88 Update zh-Hans localization (#970)
* Update zh-Hans localization

* More zh-Hans localization
2019-08-29 11:22:36 +02:00
Michael Starke
d048ea47a6 Aligned localizations 2019-08-28 13:33:40 +02:00
Michael Starke
2a8766eccb Fixed typo 2019-08-28 13:32:32 +02:00
Michael Starke
a2078f721a Merge branch 'master' into feature/import_plugins
# Conflicts:
#	Cartfile.resolved
2019-08-28 13:13:49 +02:00
Michael Starke
7e402601f8 Updated KeePassKit to fix various Pickchars issues 2019-08-28 11:53:43 +02:00
Chester Liu
88d7d8792a Update zh-Hans localization (#969) 2019-08-28 08:33:15 +02:00
Michael Starke
68bdcb461f Using KeePassKit 2.4.5 to fix breadcrumb issue 2019-08-27 18:43:10 +02:00
Michael Starke
ec8ce8ec29 remove unnecessary assignment 2019-08-27 18:26:40 +02:00
Michael Starke
95275d9c8a Merge branch 'master' into feature/import_plugins 2019-08-27 15:01:54 +02:00
Michael Starke
7671a6e3f5 remove unnecessary logging 2019-08-27 14:59:38 +02:00
Michael Starke
c0c053d422 Retain custom file extension if present and do not change back to .kdbx (or .kdb) 2019-08-27 14:54:00 +02:00
Chester Liu
4cda972d14 Update zh-Hans translation (#968) 2019-08-27 11:33:31 +02:00
Michael Starke
09eb1dcf41 Updated at now displays a special text if remote updates are disabled 2019-08-27 11:30:08 +02:00
Michael Starke
224ca6c65b Updated plugin definition 2019-08-27 11:29:39 +02:00
Michael Starke
10dd3e352d Merge branch 'master' into feature/import_plugins 2019-08-27 10:15:42 +02:00
Michael Starke
48aa21faa8 Current plugins.json 2019-08-27 10:15:19 +02:00
Michael Starke
c295f5df6f Updated plugin retrieval to overwrite exiting file 2019-08-27 10:15:11 +02:00
Michael Starke
2103eb8875 Added rudimentary export plugin support 2019-08-26 17:25:25 +02:00
Michael Starke
3b7bf0d77b Removed unneeded parameters in import API 2019-08-26 12:03:14 +02:00
Michael Starke
9298feea2d Removed english localisation that is not necessary 2019-08-23 16:30:56 +02:00
Michael Starke
7f79dde83a Fixed malformed .strings file 2019-08-23 13:15:30 +02:00
Michael Starke
ed4e4b0f72 Found a better german translation 2019-08-23 12:31:08 +02:00
Michael Starke
62670a605e Updated KeePassKit to fix KDBX4 date offset bug (-2days) 2019-08-23 12:27:59 +02:00
Alessandro Vinciguerra
9e5d9f3bf5 Update Italian Localization (#965)
* Added missing Italian translations

Added translations directly to strings files
Update translation for "inspector"

* Updated Italian translations and added missing strings files

Added fixes for German, French, and English
2019-08-23 12:27:38 +02:00
Michael Starke
bc47fb592c Merge branch 'master' into feature/import_plugins 2019-08-23 10:17:49 +02:00
Michael Starke
4b04699b30 Removed unnecessary english localisation files since Base localisation is english 2019-08-23 10:17:21 +02:00
Michael Starke
3910b117a8 Updated german localization 2019-08-23 09:50:50 +02:00
Michael Starke
81dce1928a Updated to Xcode 10.3 2019-08-20 16:08:57 +02:00
Michael Starke
05f820a4a3 Merge branch 'master' into feature/import_plugins 2019-08-20 12:56:06 +02:00
Michael Starke
b9fbe43653 Merge branch 'master' into feature/duplicate_group 2019-08-20 12:55:31 +02:00
Michael Starke
145f27c334 Clarified localization context 2019-08-20 12:55:18 +02:00
Michael Starke
bf93ab574d Merge branch 'master' into feature/duplicate_group 2019-08-19 14:22:30 +02:00
Michael Starke
7fc1dd8a1b Do not relay on taking a screenshot to determine screen recording permissions. Instead read window titles of all visible windows. 2019-08-19 14:21:12 +02:00
Michael Starke
e31c7c6cd7 Updated translations 2019-08-19 14:20:27 +02:00
Michael Starke
7d8bb85d9b Added duplicate group as context menu action 2019-08-16 17:24:54 +02:00
Michael Starke
245a58d81b Fixed missing break in action validation resulting in copy as reference and copy custom attributes note working in search mode 2019-08-16 16:52:13 +02:00
Michael Starke
6b94cbd81b added prefix to prevent name clash 2019-08-16 15:38:01 +02:00
Michael Starke
cbc74ccca6 Split test into valid and invalid attributes 2019-08-16 14:57:41 +02:00
Michael Starke
9b2f8e5f6f Using property 2019-08-16 14:57:32 +02:00
Michael Starke
9c177afdb0 Added show group in outline to context menus 2019-08-14 13:26:33 +02:00
Michael Starke
6b13ab37b8 Updated localizations 2019-08-14 13:25:55 +02:00
Michael Starke
d4efba00ae Removed unused file 2019-08-14 13:25:47 +02:00
Michael Starke
2d3e81a5c1 Added double click action to select the group of the currently selected entry.
This feature is mainly aimed to ease navigation when browsing search results
2019-08-14 12:08:18 +02:00
Michael Starke
c523ba716f code style 2019-08-09 21:31:11 +02:00
Michael Starke
32c6bae7e4 Updated to Xcode 10.3 2019-08-07 15:09:25 +02:00
Anton Glezman
2aba4cbd93 Improved russian localization (#961) 2019-08-05 10:37:36 +02:00
Anton Glezman
5fbd6d1cde Fix localized string ambiguous with word allow/disallow (#959)
* Fix localized string ambiguous with word allow/disallow
* Fix typo
2019-08-05 10:37:01 +02:00
César Arratia
091a565bc8 Translation to spanish improved (#953)
* - Translation to Spanish of the new functionalities (adapt to new Localizable strings order)
- Corrections of some typos in English translation

* - Update all spanish translations, UI included
2019-07-19 12:40:56 +02:00
Michael Starke
0d3bf5ba71 Fixed typo in localisation comment 2019-07-18 11:41:22 +02:00
Michael Starke
d3a575fce3 Merge branch 'master' into feature/import_plugins 2019-07-15 18:21:33 +02:00
Michael Starke
1baf2cd8e6 Display a generic description text if the appropriate key is present in the InfoDictionary of the plugin bundle 2019-07-15 18:21:03 +02:00
Michael Starke
0455628d72 Merge branch 'master' into feature/import_plugins 2019-07-15 12:25:15 +02:00
Michael Starke
9d0dc1630d Added simple support for import Plugins via plugin API 2019-07-15 12:23:32 +02:00
Michael Starke
fc21257173 Minor style fixes 2019-07-15 12:22:07 +02:00
Michael Starke
53b807788a Fixed issue where remove connection would be used despite the user not consenting to it. 2019-07-12 17:07:30 +02:00
Michael Starke
024131de35 Fixed typo in comment 2019-07-12 17:01:22 +02:00
Michael Starke
a47557672f Merge branch 'master' into feature/use_local_plugins_json
# Conflicts:
#	MacPass/de.lproj/Localizable.strings
#	MacPass/en.lproj/Localizable.strings
2019-07-12 16:55:38 +02:00
Michael Starke
9a55559e71 Merge branch 'master' into feature/refactor_touchbar
# Conflicts:
#	MacPass/MPDocumentWindowController.m
2019-07-12 16:50:10 +02:00
Michael Starke
e82db2fe9d Added missing contraints 2019-07-12 16:47:26 +02:00
Michael Starke
50dad4de30 Updated english localization 2019-07-12 16:43:34 +02:00
Michael Starke
f7eb7147f3 Updated english localization 2019-07-12 16:42:21 +02:00
Michael Starke
d37164ad89 Updated english localization for database settings window 2019-07-12 16:40:51 +02:00
Michael Starke
add09827ba added missing changes to project file 2019-07-12 16:04:06 +02:00
Michael Starke
9a625dd57d Updated german and english localizations 2019-07-12 16:03:58 +02:00
Michael Starke
3191e56e58 Used more appropriate buttons for unlock/lock in Touch- and Toolbar 2019-07-12 14:40:14 +02:00
Michael Starke
a5c97469eb Moved constants into MPTouchBarButtonCreator, adjusted naming of constants to current convention 2019-07-12 13:26:21 +02:00
Michael Starke
02840548ba use isEqualToString instead of == 2019-07-12 11:26:11 +02:00
Michael Starke
52720a79d4 Fixed memory leak in taking a screenshot 2019-07-12 11:26:00 +02:00
Michael Starke
71e795c4f4 Updated Xcode version 2019-07-12 11:14:45 +02:00
Michael Starke
2381acfde9 Codestyle. Do not use == for string compare 2019-07-10 12:27:34 +02:00
Michael Starke
9d2819ce2c Codestyle 2019-07-10 12:27:18 +02:00
Michael Starke
d5592774d1 Disable plugin alert when running tests 2019-07-10 12:27:11 +02:00
Michael Starke
55f1ce22a9 Codestyle 2019-07-10 12:13:56 +02:00
Veit-Hendrik Schlenker
2d98c480da Add touchbar support (#862)
* Add touchbar support for the password input

* Add touchbar support for entry list

* Set NSTouchBarItemIdentifier as static strings

* Simplify touchbar initialization in NSTextView

* Remove colored buttons in touchbar to adhere to the Human Interface Guidelines

* Add search action to touchbar

* Create a TouchBarButtonCreator

* Enable Touchbar customization

* Fix typo

* Add customizationLabel to all buttons

* Use localised strings instead of hardcoded

* Add a popover touchbar for editing

* Update localisation

* Set the bezel color of the show password button to selected if toggled
2019-07-10 12:00:38 +02:00
Michael Starke
30a68fc9e3 Merge branch 'feature/check_autotype_screen_recording_permission' 2019-07-09 15:39:43 +02:00
Michael Starke
32899cb707 Introduced Autotype doctor in preparation for macOS 10.15.
This change removes the test for autotype on startup and will only check for permissoins when the pereferences are shown or when (gloabal)autotype is performed.
2019-07-09 15:39:23 +02:00
Michael Starke
b1cb776e14 Moved accessibilty permission checks into MPAutotypeDoctor. Added screen capture permission test. 2019-07-03 17:28:58 +02:00
Michael Starke
176a3b7db4 use property instead of setter 2019-07-03 12:47:28 +02:00
Michael Starke
38e61b96a5 Added missing palettlabel to toolbar items to show up in customizing sheet 2019-07-03 12:05:43 +02:00
Michael Starke
54d7ce4f77 Merge branch 'master' into feature/use_local_plugins_json 2019-07-03 12:03:09 +02:00
Michael Starke
2e523f6018 Merge branch 'master' into feature/check_autotype_screen_recording_permission 2019-07-03 12:02:56 +02:00
Michael Starke
077a5851cf append branch name if we're not on master 2019-07-03 11:14:42 +02:00
Michael Starke
3cab0ea4dd Fixed versioning script to correctly work with more complex branches 2019-07-03 11:02:10 +02:00
Michael Starke
ddb0f92dce Using a notification based aproach to ensure the desired target application is activated before performing any autotype commands 2019-07-01 16:53:05 +02:00
Michael Starke
0c12236401 Use naive polling to check if requested application is already active 2019-07-01 14:40:10 +02:00
Michael Starke
c7d85d6daa Added log message when no window title can be determined 2019-07-01 13:27:18 +02:00
Michael Starke
28817b6c80 wired plugin repository download settings and fixed crash when initializing plugin host 2019-06-26 13:05:40 +02:00
Michael Starke
972f775ab3 added load external content ui for settings 2019-06-26 12:33:49 +02:00
Michael Starke
4a33a7ece2 ignore updated localizations helper file 2019-06-26 12:33:38 +02:00
Michael Starke
e0d12bea5a Added setup to store a copy of the plugin.json inside Macpass and use that as fallback as well as if the user denies access to remote systems 2019-06-25 12:59:51 +02:00
Michael Starke
8f5914afd2 Project structure cleanup and renaming 2019-06-25 11:41:53 +02:00
Jesse Reppin
eaa0f68c7b Updated german localization (#943)
* Updated german localization

Add in GeneralSettings.strings "Enable Autosave" and "Close and open all documents for changes to take effect" in German.

* Updated german localization
2019-06-19 10:10:43 +02:00
Michael Starke
9f43d52917 Remove alert pop-up in test scenarios to prevent main thread stalls 2019-06-17 16:32:36 +02:00
Michael Starke
9e474375bf Removed unimplemented test cases 2019-06-17 16:32:12 +02:00
Michael Starke
714bba4ce5 Revert "Added delay settings key"
This reverts commit 3ef2c01859.
2019-06-17 15:39:19 +02:00
Michael Starke
8d66621803 Added support for {DELAY=<delay>} to allow for custom delay in command execution instead of using dedicated UI and settings for this 2019-06-17 15:38:12 +02:00
Michael Starke
3ef2c01859 Added delay settings key 2019-06-17 11:23:39 +02:00
Michael Starke
4abdff79a5 Fixed typos in comment 2019-05-16 09:21:09 +02:00
Michael Starke
f9b36177fd Fixed wrong usage of window title 2019-05-09 20:43:07 +02:00
Michael Starke
9134f4959b Use window title supplied by plugins 2019-05-09 20:39:09 +02:00
Michael Starke
6e011c00fa Using resolvers to determine the window title. Title is currently not used for anything besides logging. 2019-05-08 08:33:11 +02:00
Michael Starke
64de5a0d21 Add apple event usage descriptions since Info.plists of plugins will not be considered when determining Automation capabilites 2019-05-08 08:32:43 +02:00
Michael Starke
5da86637e5 Stubbed API for Autotype plugins that resolve window titles 2019-05-07 08:13:41 +02:00
Michael Starke
ba2fc255dc Updated dutch localization 2019-04-26 14:51:22 +02:00
Michael Starke
8cc701af5f Updated french localization 2019-04-25 16:01:19 +02:00
Michael Starke
305ce06ab4 Updated french localization 2019-04-25 11:57:19 +02:00
Michael Starke
349eb5791e Renamed statupstate 2019-04-24 17:09:56 +02:00
Michael Starke
2beb1bbceb Merge branch 'feature/fix-welcome-window-restoration' 2019-04-24 15:57:51 +02:00
Michael Starke
c46dba59c3 do not show welcome window when we are asked to open a file via double-click in the Finder 2019-04-24 15:57:20 +02:00
Michael Starke
25538dd3bf Updated to Xcode 10.2 2019-04-24 12:06:28 +02:00
Michael Starke
e8fa409cef moved observation to init since it’s need from the start 2019-04-24 12:06:16 +02:00
Michael Starke
6b6c4fb736 Updated to Xcode 10.2 2019-04-05 17:09:08 +02:00
Michael Starke
7c2cf6eadb Re-worked hide after copy to pasteboard. It now works for all copy actions that securely copy to the clipboard (closed #906) 2019-04-05 08:57:59 +02:00
Michael Starke
853e47c43f Moved hide after copy to separate section since it’s meaning changes 2019-04-05 08:35:13 +02:00
Michael Starke
a5da80f094 Added UI to enable hide-after-copy 2019-04-05 08:24:47 +02:00
Michael Starke
878cef88c5 Reenabled tababale key selection also fixing first responder issue when closing password generator popover (fixes #896) 2019-04-05 08:24:47 +02:00
Michael Starke
43508ad3a5 Added trailing comma 2019-04-05 08:24:47 +02:00
Michael Starke
d909c377fb Dutch advanced database settings tab was broken because of a malformed localisation (fixes #913) 2019-04-05 08:24:47 +02:00
Deniz Türkoglu
ae4656c79a Keyfile selection window must be modal (#898)
If we don't use the modal view, the user can put the file selection
window to background, click 'Choose...' and open additional windows.
2019-04-05 08:23:32 +02:00
Anton Glezman
1c0a76dc74 Russian localization (#918) 2019-04-05 08:22:54 +02:00
428 changed files with 10315 additions and 4084 deletions

2
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,2 @@
github: mstarke
custom: https://flattr.com/thing/1550529/mstarkeMacPass-on-GitHub

1
.gitignore vendored
View File

@@ -24,3 +24,4 @@ Docs/Acknowlegements/*.fls
Docs/Acknowlegements/*.log Docs/Acknowlegements/*.log
Docs/Acknowlegements/*.synctex.gz Docs/Acknowlegements/*.synctex.gz
docs/acknowledgement/*.lb docs/acknowledgement/*.lb
MacPass/en.lproj/Localizable.strings.updated

3
.gitmodules vendored
View File

@@ -1,6 +1,3 @@
[submodule "DDHotKey"] [submodule "DDHotKey"]
path = DDHotKey path = DDHotKey
url = https://github.com/mstarke/DDHotKey.git url = https://github.com/mstarke/DDHotKey.git
[submodule "TransformerKit"]
path = TransformerKit
url = https://github.com/mattt/TransformerKit.git

View File

@@ -8,6 +8,16 @@ before_install:
- gem install xcpretty --no-document --quiet - gem install xcpretty --no-document --quiet
after_success: 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 - cd ./build/Build/Products/Release
- zip -9ry MacPass-continuous.zip MacPass.app - zip -9ry MacPass-continuous.zip MacPass.app
- shasum -a 256 MacPass-continuous.zip > MacPass-continuous.zip.sha256 - shasum -a 256 MacPass-continuous.zip > MacPass-continuous.zip.sha256
@@ -30,6 +40,7 @@ deploy:
api_key: api_key:
secure: AEb7fgi29S3aXFt5bXz+lq1KHISumny6bf4j06JBC5gUrSs+dW0/tmVFq68XRAqigeOQU31wwv20f7OHiy+GRYDXM2xBsX9ZBQ2IilnaXlDy/mPsNcJJJsZ2gyodi3KnU0rZtTb93me2YyU86H4Na/gtaZZUKjLwCFtGGziExD8= secure: AEb7fgi29S3aXFt5bXz+lq1KHISumny6bf4j06JBC5gUrSs+dW0/tmVFq68XRAqigeOQU31wwv20f7OHiy+GRYDXM2xBsX9ZBQ2IilnaXlDy/mPsNcJJJsZ2gyodi3KnU0rZtTb93me2YyU86H4Na/gtaZZUKjLwCFtGGziExD8=
file: file:
- Localisations.zip
- MacPass-continuous.zip - MacPass-continuous.zip
- MacPass-continuous.zip.sha256 - MacPass-continuous.zip.sha256
overwrite: true overwrite: true

View File

@@ -4,18 +4,21 @@ Thanks for taking the time to contribute to MacPass! This documents describes a
## Translations ## 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: 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: - Get a XLIFF editor for translating localization files. For example [XLIFFTool](https://itunes.apple.com/us/app/xlifftool/id1074282695)
- Select MacPass in the project navigator - 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:
- Select the MacPass project in the project and targets list - For a new localization only:
- Open the info tab and click the `+` button un the localizations section. - Select MacPass in the project navigator
- Choose the language you want to translate - Select the MacPass project in the project and targets list
- Select all resources and click finish, now the new language is available for export in the next step - Open the info tab and click the `+` button un the localizations section.
- Export the XLIFF file - Choose the language you want to translate
- Select the MacPass project in XCode - Select all resources and click finish, now the new language is available for export in the next step
- Go to `Editor -> Export for Localization` - For present localizations directly Export the XLIFF file
- Select the language you want to translate - Select the MacPass project in Xcode
- Now use your XLIFF editor and save the file if you are done with your translations - 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 - 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. 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.

View File

@@ -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 "MacPass/KeePassKit" ~> 2.4
github "mstarke/HNHUi" ~> 3.0 github "mstarke/HNHUi" ~> 3.0

View File

@@ -1,4 +1,5 @@
github "MacPass/KeePassKit" "2.4.2" github "MacPass/KeePassKit" "2.4.7"
github "MacPass/TransformerKit" "b28de3a7de9249dd886979cae4985092523b6dd1"
github "mstarke/HNHUi" "3.0" github "mstarke/HNHUi" "3.0"
github "robbiehanson/KissXML" "5.2.3" github "robbiehanson/KissXML" "5.3.1"
github "sparkle-project/Sparkle" "1.20.0" github "sparkle-project/Sparkle" "1.22.0"

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "1010" LastUpgradeVersion = "1130"
version = "2.0"> version = "2.0">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"
@@ -26,20 +26,8 @@
buildConfiguration = "Debug" buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
codeCoverageEnabled = "YES" shouldUseLaunchSchemeArgsEnv = "NO"
shouldUseLaunchSchemeArgsEnv = "NO"> codeCoverageEnabled = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4C45FB19178E09ED0010007D"
BuildableName = "MacPassTests.xctest"
BlueprintName = "MacPassTests"
ReferencedContainer = "container:MacPass.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion> <MacroExpansion>
<BuildableReference <BuildableReference
BuildableIdentifier = "primary" BuildableIdentifier = "primary"
@@ -55,9 +43,24 @@
value = "YES" value = "YES"
isEnabled = "YES"> isEnabled = "YES">
</EnvironmentVariable> </EnvironmentVariable>
<EnvironmentVariable
key = "MPIsRunningTests"
value = "YES"
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables> </EnvironmentVariables>
<AdditionalOptions> <Testables>
</AdditionalOptions> <TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4C45FB19178E09ED0010007D"
BuildableName = "MacPassTests.xctest"
BlueprintName = "MacPassTests"
ReferencedContainer = "container:MacPass.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction> </TestAction>
<LaunchAction <LaunchAction
buildConfiguration = "Debug" buildConfiguration = "Debug"
@@ -102,8 +105,6 @@
isEnabled = "NO"> isEnabled = "NO">
</EnvironmentVariable> </EnvironmentVariable>
</EnvironmentVariables> </EnvironmentVariables>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction> </LaunchAction>
<ProfileAction <ProfileAction
buildConfiguration = "Release" buildConfiguration = "Release"

View File

@@ -1,14 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="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> <dependencies>
<deployment identifier="macosx"/> <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"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<objects> <objects>
<customObject id="-2" userLabel="File's Owner" customClass="MPAutotypeCandidateSelectionViewController"> <customObject id="-2" userLabel="File's Owner" customClass="MPAutotypeCandidateSelectionViewController">
<connections> <connections>
<outlet property="contextTableView" destination="Ih2-lo-t2W" id="8uy-Mz-1vc"/> <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="selectAutotypeContextButton" destination="V5B-Qq-GN8" id="mqv-H3-N01"/>
<outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/> <outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
</connections> </connections>
@@ -19,13 +20,13 @@
<rect key="frame" x="0.0" y="0.0" width="480" height="241"/> <rect key="frame" x="0.0" y="0.0" width="480" height="241"/>
<subviews> <subviews>
<scrollView wantsLayer="YES" autohidesScrollers="YES" horizontalLineScroll="38" horizontalPageScroll="10" verticalLineScroll="38" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7cB-re-3ys"> <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"> <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"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <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"> <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="116"/> <rect key="frame" x="0.0" y="0.0" width="438" height="118"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<size key="intercellSpacing" width="3" height="2"/> <size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
@@ -44,12 +45,12 @@
</textFieldCell> </textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES"/> <tableColumnResizingMask key="resizingMask" resizeWithTable="YES"/>
<prototypeCellViews> <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"/> <rect key="frame" x="1" y="1" width="435" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Utl-Gl-ETE"> <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> <constraints>
<constraint firstAttribute="width" relation="lessThanOrEqual" constant="32" id="N48-cx-w8q"/> <constraint firstAttribute="width" relation="lessThanOrEqual" constant="32" id="N48-cx-w8q"/>
<constraint firstAttribute="height" relation="lessThanOrEqual" constant="32" id="mde-14-jf7"/> <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"/> <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="NSActionTemplate" id="gT4-lt-7Ir"/>
</imageView> </imageView>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" allowsExpansionToolTips="YES" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Dxk-A7-QSy"> <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"/> <rect key="frame" x="22" y="20" width="413" height="16"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" allowsUndo="NO" sendsActionOnEndEditing="YES" title="Content" id="TN3-3a-LaA"> <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"/> <font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
@@ -66,14 +75,18 @@
</textField> </textField>
</subviews> </subviews>
<constraints> <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 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="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 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="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="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> </constraints>
<connections> <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="imageView" destination="Utl-Gl-ETE" id="5dQ-R4-kfV"/>
<outlet property="textField" destination="Dxk-A7-QSy" id="8uP-9M-aOd"/> <outlet property="textField" destination="Dxk-A7-QSy" id="8uP-9M-aOd"/>
</connections> </connections>
@@ -99,7 +112,7 @@
</scroller> </scroller>
</scrollView> </scrollView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" preferredMaxLayoutWidth="330" translatesAutoresizingMaskIntoConstraints="NO" id="kDw-2l-7gQ"> <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"> <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"/> <font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -147,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 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"/> <constraint firstAttribute="trailing" secondItem="kDw-2l-7gQ" secondAttribute="trailing" constant="20" symbolic="YES" id="zSz-fH-fVn"/>
</constraints> </constraints>
<point key="canvasLocation" x="176" y="-39"/> <point key="canvasLocation" x="176" y="-39.5"/>
</customView> </customView>
</objects> </objects>
<resources> <resources>

View 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>

View File

@@ -1,4 +1,4 @@
{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf200 {\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf600
{\fonttbl\f0\fswiss\fcharset0 Helvetica-Bold;\f1\fswiss\fcharset0 Helvetica;\f2\fnil\fcharset0 SFProText-Regular; {\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; {\colortbl;\red255\green255\blue255;\red0\green0\blue0;\red9\green79\blue209;\red69\green60\blue204;
@@ -22,7 +22,7 @@ License:\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0 \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
\f1\b0 \cf2 MacPass KeePass compatible client for OS X\ \f1\b0 \cf2 MacPass KeePass compatible client for OS X\
Copyright (c) 2012-2019 Michael Starke, HicknHack Software GmbH\ 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\ 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.\ the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="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> <dependencies>
<deployment identifier="macosx"/> <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"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<objects> <objects>
@@ -51,13 +51,13 @@
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/> <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/> <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="500" height="360"/> <rect key="contentRect" x="196" y="240" width="500" height="360"/>
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/> <rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
<view key="contentView" id="2"> <view key="contentView" id="2">
<rect key="frame" x="0.0" y="0.0" width="500" height="360"/> <rect key="frame" x="0.0" y="0.0" width="553" height="484"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="288"> <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="288">
<rect key="frame" x="427" y="13" width="59" height="32"/> <rect key="frame" x="480" y="13" width="59" height="32"/>
<buttonCell key="cell" type="push" title="OK" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="289"> <buttonCell key="cell" type="push" title="OK" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="289">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
@@ -70,7 +70,7 @@ DQ
</connections> </connections>
</button> </button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="956"> <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="956">
<rect key="frame" x="345" y="13" width="82" height="32"/> <rect key="frame" x="398" y="13" width="82" height="32"/>
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="957"> <buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="957">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
@@ -83,7 +83,7 @@ Gw
</connections> </connections>
</button> </button>
<tabView translatesAutoresizingMaskIntoConstraints="NO" id="357"> <tabView translatesAutoresizingMaskIntoConstraints="NO" id="357">
<rect key="frame" x="13" y="41" width="474" height="313"/> <rect key="frame" x="13" y="41" width="527" height="437"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
<tabViewItems> <tabViewItems>
<tabViewItem label="General" identifier="1" id="358"> <tabViewItem label="General" identifier="1" id="358">
@@ -159,7 +159,7 @@ Gw
<rect key="frame" x="154" y="117" width="280" height="100"/> <rect key="frame" x="154" y="117" width="280" height="100"/>
<clipView key="contentView" drawsBackground="NO" id="WOI-1v-RCe"> <clipView key="contentView" drawsBackground="NO" id="WOI-1v-RCe">
<rect key="frame" x="1" y="1" width="278" height="98"/> <rect key="frame" x="1" y="1" width="278" height="98"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<textView importsGraphics="NO" verticallyResizable="YES" usesFontPanel="YES" findStyle="panel" continuousSpellChecking="YES" allowsUndo="YES" usesRuler="YES" allowsNonContiguousLayout="YES" spellingCorrection="YES" smartInsertDelete="YES" id="1531"> <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"/> <rect key="frame" x="0.0" y="0.0" width="278" height="98"/>
@@ -265,7 +265,7 @@ Gw
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="P98-Cu-Tha"> <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="P98-Cu-Tha">
<rect key="frame" x="251.5" y="18" width="143" height="23"/> <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"> <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"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>

View File

@@ -1,8 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6254" systemVersion="13F34" 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> <dependencies>
<deployment identifier="macosx"/> <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> </dependencies>
<objects> <objects>
<customObject id="-2" userLabel="File's Owner" customClass="MPDatePickingViewController"> <customObject id="-2" userLabel="File's Owner" customClass="MPDatePickingViewController">
@@ -15,24 +16,23 @@
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/> <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/> <customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView id="1"> <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"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews> <subviews>
<datePicker horizontalHuggingPriority="750" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="3"> <datePicker horizontalHuggingPriority="750" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="3">
<rect key="frame" x="20" y="91" width="277" height="148"/> <rect key="frame" x="20" y="91" width="143" height="27"/>
<datePickerCell key="cell" borderStyle="bezel" alignment="left" datePickerStyle="clockAndCalendar" id="4"> <datePickerCell key="cell" borderStyle="bezel" alignment="left" id="4">
<font key="font" metaFont="system"/> <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--> <!--1982-02-12 16:00:00 +0000-->
<timeZone key="timeZone" name="US/Pacific"/> </date>
</calendarDate>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="textColor" name="controlTextColor" 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"/> <datePickerElements key="datePickerElements" year="YES" month="YES" day="YES" hour="YES" minute="YES"/>
</datePickerCell> </datePickerCell>
</datePicker> </datePicker>
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="15"> <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"> <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"/> <behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/> <font key="font" metaFont="menu"/>
@@ -43,7 +43,7 @@
</connections> </connections>
</popUpButton> </popUpButton>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="25"> <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"> <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"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
@@ -53,7 +53,7 @@
</connections> </connections>
</button> </button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="29"> <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"> <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"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/> <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="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"/> <constraint firstItem="25" firstAttribute="top" secondItem="15" secondAttribute="bottom" constant="8" symbolic="YES" id="sxX-fk-xaJ"/>
</constraints> </constraints>
<point key="canvasLocation" x="-89" y="77"/>
</customView> </customView>
</objects> </objects>
</document> </document>

View File

@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="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> <dependencies>
<deployment identifier="macosx"/> <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"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<objects> <objects>
<customObject id="-2" userLabel="File's Owner" customClass="MPGeneralSettingsController"> <customObject id="-2" userLabel="File's Owner" customClass="MPGeneralPreferencesController">
<connections> <connections>
<outlet property="clearPasteboardOnQuitCheckButton" destination="447" id="520"/> <outlet property="clearPasteboardOnQuitCheckButton" destination="447" id="520"/>
<outlet property="clearPasteboardTimeoutPopup" destination="419" id="521"/> <outlet property="clearPasteboardTimeoutPopup" destination="419" id="521"/>
@@ -14,6 +14,7 @@
<outlet property="fileChangeStrategyPopup" destination="wIu-Sh-2a2" id="oJo-dA-lEE"/> <outlet property="fileChangeStrategyPopup" destination="wIu-Sh-2a2" id="oJo-dA-lEE"/>
<outlet property="idleTimeOutPopup" destination="584" id="809"/> <outlet property="idleTimeOutPopup" destination="584" id="809"/>
<outlet property="lockOnLogoutCheckButton" destination="5SP-Vi-1sn" id="yaI-LH-R5A"/> <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="lockOnSleepCheckButton" destination="630" id="810"/>
<outlet property="preventUniversalClipboardSupportCheckButton" destination="nqZ-rB-mFS" id="sbx-rl-reT"/> <outlet property="preventUniversalClipboardSupportCheckButton" destination="nqZ-rB-mFS" id="sbx-rl-reT"/>
<outlet property="rememberKeyFileCheckButton" destination="bSt-Wf-FNZ" id="aQm-EA-yAN"/> <outlet property="rememberKeyFileCheckButton" destination="bSt-Wf-FNZ" id="aQm-EA-yAN"/>
@@ -24,16 +25,16 @@
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/> <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/> <customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="1"> <customView translatesAutoresizingMaskIntoConstraints="NO" id="1">
<rect key="frame" x="0.0" y="0.0" width="400" height="524"/> <rect key="frame" x="0.0" y="0.0" width="411" height="547"/>
<subviews> <subviews>
<box autoresizesSubviews="NO" verticalHuggingPriority="500" borderType="line" title="Security" translatesAutoresizingMaskIntoConstraints="NO" id="465"> <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"> <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"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="431"> <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> <constraints>
<constraint firstAttribute="height" constant="17" id="803"/> <constraint firstAttribute="height" constant="17" id="803"/>
</constraints> </constraints>
@@ -44,13 +45,10 @@
</textFieldCell> </textFieldCell>
</textField> </textField>
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="419"> <popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="419">
<rect key="frame" x="177" y="308" width="170" height="21"/> <rect key="frame" x="138" y="332" width="143" height="21"/>
<constraints>
<constraint firstAttribute="width" constant="165" id="877"/>
</constraints>
<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"> <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"/> <behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/> <font key="font" metaFont="system"/>
<menu key="menu" title="ClipboardClearInterval" id="421"> <menu key="menu" title="ClipboardClearInterval" id="421">
<items> <items>
<menuItem title="Never" state="on" id="429"> <menuItem title="Never" state="on" id="429">
@@ -65,7 +63,7 @@
</popUpButtonCell> </popUpButtonCell>
</popUpButton> </popUpButton>
<button verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="447"> <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> <constraints>
<constraint firstAttribute="height" constant="14" id="773"/> <constraint firstAttribute="height" constant="14" id="773"/>
</constraints> </constraints>
@@ -75,10 +73,10 @@
</buttonCell> </buttonCell>
</button> </button>
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="584"> <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"> <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"/> <behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/> <font key="font" metaFont="system"/>
<menu key="menu" title="LockTimes" id="586"> <menu key="menu" title="LockTimes" id="586">
<items> <items>
<menuItem title="Never" id="804"/> <menuItem title="Never" id="804"/>
@@ -92,14 +90,14 @@
</popUpButtonCell> </popUpButtonCell>
</popUpButton> </popUpButton>
<button translatesAutoresizingMaskIntoConstraints="NO" id="630"> <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"> <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"/> <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
</buttonCell> </buttonCell>
</button> </button>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="805"> <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"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Lock while idle" id="806">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -114,7 +112,7 @@
</buttonCell> </buttonCell>
</button> </button>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5cV-xX-SUU"> <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"> <textFieldCell key="cell" sendsActionOnEndEditing="YES" id="ACh-7H-42N">
<font key="font" metaFont="smallSystem"/> <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> <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>
@@ -123,7 +121,7 @@
</textFieldCell> </textFieldCell>
</textField> </textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="oQr-FC-HkN"> <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"> <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"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
@@ -133,21 +131,21 @@
</connections> </connections>
</button> </button>
<button translatesAutoresizingMaskIntoConstraints="NO" id="5SP-Vi-1sn"> <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"> <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"/> <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
</buttonCell> </buttonCell>
</button> </button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="nqZ-rB-mFS"> <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"> <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"/> <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
</buttonCell> </buttonCell>
</button> </button>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="hy4-RL-dAa"> <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"> <textFieldCell key="cell" sendsActionOnEndEditing="YES" id="JGX-Tp-KJk">
<font key="font" metaFont="smallSystem"/> <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> <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>
@@ -155,20 +153,30 @@
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell> </textFieldCell>
</textField> </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> </subviews>
<constraints> <constraints>
<constraint firstItem="5cV-xX-SUU" firstAttribute="leading" secondItem="mNh-3L-Z6E" secondAttribute="leading" constant="20" symbolic="YES" id="1jw-nb-bAB"/> <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="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 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="584" firstAttribute="top" secondItem="hy4-RL-dAa" secondAttribute="bottom" constant="8" symbolic="YES" id="SV7-PD-nId"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="bSt-Wf-FNZ" secondAttribute="trailing" constant="20" symbolic="YES" id="VQY-eq-fCM"/> <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="bSt-Wf-FNZ" secondAttribute="trailing" constant="20" symbolic="YES" id="VQY-eq-fCM"/>
<constraint firstItem="bSt-Wf-FNZ" firstAttribute="top" secondItem="5SP-Vi-1sn" secondAttribute="bottom" constant="11" id="WUG-Uf-FCO"/> <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="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="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" relation="greaterThanOrEqual" secondItem="805" secondAttribute="trailing" constant="8" symbolic="YES" id="aoz-sS-O0n"/> <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 firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="447" secondAttribute="trailing" constant="20" symbolic="YES" id="i8H-ad-IKb"/>
<constraint firstItem="419" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="431" secondAttribute="trailing" constant="8" symbolic="YES" id="pN3-pB-Z5I"/> <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 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 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="5cV-xX-SUU" secondAttribute="trailing" constant="20" symbolic="YES" id="qY0-io-RZ0"/>
@@ -178,8 +186,8 @@
</constraints> </constraints>
</view> </view>
<constraints> <constraints>
<constraint firstAttribute="trailing" secondItem="419" secondAttribute="trailing" constant="16" id="1de-jU-TAq"/> <constraint firstAttribute="trailing" relation="greaterThanOrEqual" 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="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 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="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"/> <constraint firstItem="805" firstAttribute="centerY" secondItem="584" secondAttribute="centerY" id="OOq-TD-dmj"/>
@@ -195,41 +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="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="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="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="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"/> <constraint firstItem="447" firstAttribute="top" secondItem="431" secondAttribute="bottom" constant="8" symbolic="YES" id="zkd-Hf-09b"/>
</constraints> </constraints>
</box> </box>
<box autoresizesSubviews="NO" verticalHuggingPriority="500" borderType="line" title="File Handling" translatesAutoresizingMaskIntoConstraints="NO" id="888"> <box autoresizesSubviews="NO" verticalHuggingPriority="500" borderType="line" title="File Handling" translatesAutoresizingMaskIntoConstraints="NO" id="888">
<rect key="frame" x="17" y="375" width="366" height="129"/> <rect key="frame" x="17" y="399" width="377" height="128"/>
<view key="contentView" id="cpg-tt-SHE"> <view key="contentView" id="cpg-tt-SHE">
<rect key="frame" x="3" y="3" width="360" height="111"/> <rect key="frame" x="3" y="3" width="371" height="110"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<button verticalHuggingPriority="252" translatesAutoresizingMaskIntoConstraints="NO" id="530"> <button verticalHuggingPriority="252" translatesAutoresizingMaskIntoConstraints="NO" id="530">
<rect key="frame" x="14" y="85" 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"> <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"/> <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
</buttonCell> </buttonCell>
</button> </button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="lz3-4U-UMI"> <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="lz3-4U-UMI">
<rect key="frame" x="14" y="65" width="123" height="18"/> <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"> <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"/> <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
</buttonCell> </buttonCell>
</button> </button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="3Bo-Ml-1KB"> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3Bo-Ml-1KB">
<rect key="frame" x="18" y="45" width="324" height="14"/> <rect key="frame" x="18" y="44" width="335" height="14"/>
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" title="Close and open all documents for changes to take effect" id="ya5-ps-c4W"> <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"/> <font key="font" metaFont="smallSystem"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell> </textFieldCell>
</textField> </textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="h3w-Ms-ohK"> <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"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="If file changes:" id="QrK-hM-Xt1">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@@ -237,17 +244,17 @@
</textFieldCell> </textFieldCell>
</textField> </textField>
<popUpButton verticalHuggingPriority="750" horizontalCompressionResistancePriority="749" translatesAutoresizingMaskIntoConstraints="NO" id="wIu-Sh-2a2"> <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"> <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"/> <behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/> <font key="font" metaFont="system"/>
<menu key="menu" id="DQY-17-yKP"/> <menu key="menu" id="DQY-17-yKP"/>
</popUpButtonCell> </popUpButtonCell>
</popUpButton> </popUpButton>
</subviews> </subviews>
<constraints> <constraints>
<constraint firstItem="3Bo-Ml-1KB" firstAttribute="leading" secondItem="cpg-tt-SHE" secondAttribute="leading" constant="20" symbolic="YES" id="2Jh-pk-bN7"/> <constraint firstItem="3Bo-Ml-1KB" firstAttribute="leading" secondItem="cpg-tt-SHE" secondAttribute="leading" constant="20" symbolic="YES" id="2Jh-pk-bN7"/>
<constraint firstAttribute="trailing" secondItem="wIu-Sh-2a2" secondAttribute="trailing" constant="20" id="2Qw-fT-Dd8"/> <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="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 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="h3w-Ms-ohK" firstAttribute="leading" secondItem="530" secondAttribute="leading" id="4Fi-rX-8e0"/>
@@ -273,11 +280,11 @@
<constraint firstItem="888" firstAttribute="leading" secondItem="1" secondAttribute="leading" constant="20" symbolic="YES" id="891"/> <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 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 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 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"/> <constraint firstItem="465" firstAttribute="top" secondItem="cpg-tt-SHE" secondAttribute="bottom" constant="5" id="wyH-HB-i2U"/>
</constraints> </constraints>
<point key="canvasLocation" x="-131" y="-93"/> <point key="canvasLocation" x="-458" y="-295"/>
</customView> </customView>
</objects> </objects>
</document> </document>

View File

@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="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> <dependencies>
<deployment identifier="macosx"/> <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"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<objects> <objects>
<customObject id="-2" userLabel="File's Owner" customClass="MPIntegrationSettingsController"> <customObject id="-2" userLabel="File's Owner" customClass="MPIntegrationPreferencesController">
<connections> <connections>
<outlet property="autotypeStackView" destination="j52-9L-k7c" id="Mxw-aa-elx"/> <outlet property="autotypeStackView" destination="j52-9L-k7c" id="Mxw-aa-elx"/>
<outlet property="autotypeWarningTextField" destination="hMJ-Mo-xOM" id="LcH-X2-TAm"/> <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="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/> <customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="1"> <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> <subviews>
<box autoresizesSubviews="NO" verticalHuggingPriority="500" borderType="line" title="Autotype" translatesAutoresizingMaskIntoConstraints="NO" id="P9N-HM-wER"> <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"> <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"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<stackView orientation="vertical" alignment="leading" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" translatesAutoresizingMaskIntoConstraints="NO" id="j52-9L-k7c"> <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> <beginningViews>
<textField verticalHuggingPriority="750" fixedFrame="YES" preferredMaxLayoutWidth="328" translatesAutoresizingMaskIntoConstraints="NO" id="hMJ-Mo-xOM"> <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"> <textFieldCell key="cell" controlSize="small" id="H37-ku-aTc">
<font key="font" metaFont="smallSystem"/> <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="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell> </textFieldCell>
</textField> </textField>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="jai-b6-Qv4"> <button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="jai-b6-Qv4">
<rect key="frame" x="-6" y="191" width="160" height="32"/> <rect key="frame" x="-6" y="191" width="177" height="32"/>
<buttonCell key="cell" type="push" title="Open Preferences…" bezelStyle="rounded" alignment="center" borderStyle="border" inset="2" id="NP0-R3-m6n"> <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"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
</buttonCell> </buttonCell>
<connections> <connections>
<action selector="openAccessibiltyPreferences:" target="-2" id="GTg-6Z-6nd"/> <action selector="runAutotypeDoctor:" target="-2" id="u2q-ab-rQY"/>
</connections> </connections>
</button> </button>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="tik-Ar-FJg"> <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="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"/> <constraint firstItem="VVs-b5-cX9" firstAttribute="leading" secondItem="P9N-HM-wER" secondAttribute="leading" id="z4a-9C-78h"/>
</constraints> </constraints>
<point key="canvasLocation" x="-357" y="-1007.5"/> <point key="canvasLocation" x="-558" y="-1123"/>
</customView> </customView>
</objects> </objects>
</document> </document>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="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> <dependencies>
<deployment identifier="macosx"/> <deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14313.18"/> <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
</dependencies> </dependencies>
<objects> <objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication"> <customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
@@ -151,9 +151,9 @@
<action selector="mergeWithOther:" target="-1" id="OyM-CZ-TDD"/> <action selector="mergeWithOther:" target="-1" id="OyM-CZ-TDD"/>
</connections> </connections>
</menuItem> </menuItem>
<menuItem title="Import" id="aTb-sW-nUd"> <menuItem title="Import From" id="aTb-sW-nUd">
<modifierMask key="keyEquivalentModifierMask"/> <modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Import" id="4q9-u1-pcm"> <menu key="submenu" title="Import From" id="4q9-u1-pcm">
<items> <items>
<menuItem title="XML…" id="rW0-r1-QYL"> <menuItem title="XML…" id="rW0-r1-QYL">
<modifierMask key="keyEquivalentModifierMask"/> <modifierMask key="keyEquivalentModifierMask"/>
@@ -167,16 +167,20 @@
</connections> </connections>
</menu> </menu>
</menuItem> </menuItem>
<menuItem title="Export" id="tz9-yK-pOf"> <menuItem title="Export To" id="tz9-yK-pOf">
<modifierMask key="keyEquivalentModifierMask"/> <modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Export" id="p8h-Fg-h1O"> <menu key="submenu" title="Export To" id="p8h-Fg-h1O">
<items> <items>
<menuItem title="XML…" keyEquivalent="E" id="1259"> <menuItem title="XML…" id="1259">
<modifierMask key="keyEquivalentModifierMask"/>
<connections> <connections>
<action selector="exportAsXML:" target="-1" id="NCG-gr-YI5"/> <action selector="exportAsXML:" target="-1" id="NCG-gr-YI5"/>
</connections> </connections>
</menuItem> </menuItem>
</items> </items>
<connections>
<outlet property="delegate" destination="494" id="ALY-P3-PzW"/>
</connections>
</menu> </menu>
</menuItem> </menuItem>
<menuItem isSeparatorItem="YES" id="74"> <menuItem isSeparatorItem="YES" id="74">
@@ -317,12 +321,18 @@ CA
</connections> </connections>
</menuItem> </menuItem>
<menuItem isSeparatorItem="YES" id="1176"/> <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"/> <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections> <connections>
<action selector="showPasswordCreator:" target="494" id="1202"/> <action selector="showPasswordCreator:" target="494" id="1202"/>
</connections> </connections>
</menuItem> </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"> <menuItem isSeparatorItem="YES" id="92">
<modifierMask key="keyEquivalentModifierMask" command="YES"/> <modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem> </menuItem>
@@ -351,6 +361,7 @@ CA
</menu> </menu>
<customObject id="494" customClass="MPAppDelegate"> <customObject id="494" customClass="MPAppDelegate">
<connections> <connections>
<outlet property="exportMenu" destination="p8h-Fg-h1O" id="elV-BC-ZZt"/>
<outlet property="fileNewMenuItem" destination="82" id="BUX-dy-HS2"/> <outlet property="fileNewMenuItem" destination="82" id="BUX-dy-HS2"/>
<outlet property="fixAutotypeMenuItem" destination="nx7-Vf-LiD" id="5n1-bG-JxJ"/> <outlet property="fixAutotypeMenuItem" destination="nx7-Vf-LiD" id="5n1-bG-JxJ"/>
<outlet property="importMenu" destination="4q9-u1-pcm" id="0XM-fS-Vyy"/> <outlet property="importMenu" destination="4q9-u1-pcm" id="0XM-fS-Vyy"/>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="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> <dependencies>
<deployment identifier="macosx"/> <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"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<objects> <objects>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="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> <dependencies>
<deployment identifier="macosx"/> <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"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<objects> <objects>
@@ -25,18 +25,18 @@
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/> <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="403" height="219"/> <rect key="contentRect" x="196" y="240" width="403" height="219"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/> <rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
<view key="contentView" misplaced="YES" id="2"> <view key="contentView" id="2">
<rect key="frame" x="0.0" y="0.0" width="403" height="219"/> <rect key="frame" x="0.0" y="0.0" width="403" height="210"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<pathControl verticalHuggingPriority="750" allowsExpansionToolTips="YES" translatesAutoresizingMaskIntoConstraints="NO" id="4" customClass="MPPathControl"> <pathControl verticalHuggingPriority="750" allowsExpansionToolTips="YES" translatesAutoresizingMaskIntoConstraints="NO" id="4" customClass="MPPathControl">
<rect key="frame" x="105" y="87" width="242" height="25"/> <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"/> <font key="font" metaFont="system"/>
</pathCell> </pathCell>
</pathControl> </pathControl>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="5"> <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"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Keyfile:" id="22">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -54,7 +54,7 @@
</connections> </connections>
</button> </button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="7"> <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> <constraints>
<constraint firstAttribute="width" constant="31" id="59"/> <constraint firstAttribute="width" constant="31" id="59"/>
</constraints> </constraints>
@@ -74,7 +74,7 @@
</connections> </connections>
</button> </button>
<secureTextField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="9" customClass="HNHUISecureTextField"> <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> <constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="200" id="Gin-yR-DMk"/> <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="200" id="Gin-yR-DMk"/>
</constraints> </constraints>
@@ -88,7 +88,7 @@
</secureTextFieldCell> </secureTextFieldCell>
</secureTextField> </secureTextField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="10"> <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"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Repeat:" id="16">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -96,7 +96,7 @@
</textFieldCell> </textFieldCell>
</textField> </textField>
<secureTextField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="11" customClass="HNHUISecureTextField"> <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"> <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"/> <font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -107,8 +107,8 @@
</secureTextFieldCell> </secureTextFieldCell>
</secureTextField> </secureTextField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="12"> <textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="12">
<rect key="frame" x="158" y="184" width="136" height="14"/> <rect key="frame" x="161" y="176" width="131" height="14"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Missmatching Passwords" id="14"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Mismatching Passwords" id="14">
<font key="font" metaFont="smallSystem"/> <font key="font" metaFont="smallSystem"/>
<color key="textColor" red="1" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/> <color key="textColor" red="1" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
@@ -138,7 +138,7 @@ Gw
</connections> </connections>
</button> </button>
<button horizontalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="yKc-I9-uzv"> <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"> <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"/> <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
@@ -189,7 +189,7 @@ Gw
<constraint firstItem="6" firstAttribute="leading" secondItem="9" secondAttribute="leading" id="zeJ-6i-fY3"/> <constraint firstItem="6" firstAttribute="leading" secondItem="9" secondAttribute="leading" id="zeJ-6i-fY3"/>
</constraints> </constraints>
</view> </view>
<point key="canvasLocation" x="-312" y="-21"/> <point key="canvasLocation" x="-8" y="-14"/>
</window> </window>
</objects> </objects>
<resources> <resources>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="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> <dependencies>
<deployment identifier="macosx"/> <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"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<objects> <objects>
@@ -10,6 +10,7 @@
<connections> <connections>
<outlet property="cancelButton" destination="2pb-ZG-spA" id="YrR-Yi-dnQ"/> <outlet property="cancelButton" destination="2pb-ZG-spA" id="YrR-Yi-dnQ"/>
<outlet property="enablePasswordCheckBox" destination="d8O-Ha-rrS" id="2AI-e9-sph"/> <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="keyPathControl" destination="241" id="261"/>
<outlet property="messageImageView" destination="262" id="726-wK-c2h"/> <outlet property="messageImageView" destination="262" id="726-wK-c2h"/>
<outlet property="messageInfoTextField" destination="268" id="ahE-sq-QzR"/> <outlet property="messageInfoTextField" destination="268" id="ahE-sq-QzR"/>
@@ -22,10 +23,10 @@
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/> <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/> <customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView horizontalCompressionResistancePriority="751" translatesAutoresizingMaskIntoConstraints="NO" id="1"> <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> <subviews>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="2"> <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="2">
<rect key="frame" x="309" 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"> <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"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
@@ -38,7 +39,7 @@ DQ
</connections> </connections>
</button> </button>
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="17"> <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"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Keyfile" id="18">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -46,13 +47,13 @@ DQ
</textFieldCell> </textFieldCell>
</textField> </textField>
<pathControl verticalHuggingPriority="750" allowsExpansionToolTips="YES" translatesAutoresizingMaskIntoConstraints="NO" id="241" customClass="MPPathControl"> <pathControl verticalHuggingPriority="750" allowsExpansionToolTips="YES" translatesAutoresizingMaskIntoConstraints="NO" id="241" customClass="MPPathControl">
<rect key="frame" x="156" y="153" width="197" height="25"/> <rect key="frame" x="156" y="222" width="197" height="25"/>
<pathCell key="cell" selectable="YES" editable="YES" alignment="left" pathStyle="popUp" id="242"> <pathCell key="cell" selectable="YES" editable="YES" alignment="left" pathStyle="popUp" id="242" customClass="MPPathCell">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
</pathCell> </pathCell>
</pathControl> </pathControl>
<imageView translatesAutoresizingMaskIntoConstraints="NO" id="262"> <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> <constraints>
<constraint firstAttribute="height" constant="48" id="273"/> <constraint firstAttribute="height" constant="48" id="273"/>
<constraint firstAttribute="width" constant="48" id="456"/> <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"/> <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" image="02_MessageBoxWarningTemplate" id="263"/>
</imageView> </imageView>
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="268"> <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"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Wrong password!" id="269">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -68,7 +69,7 @@ DQ
</textFieldCell> </textFieldCell>
</textField> </textField>
<secureTextField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="338" customClass="HNHUISecureTextField"> <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> <constraints>
<constraint firstAttribute="width" constant="191" id="389"/> <constraint firstAttribute="width" constant="191" id="389"/>
</constraints> </constraints>
@@ -85,14 +86,14 @@ DQ
</connections> </connections>
</secureTextField> </secureTextField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="408"> <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="408">
<rect key="frame" x="357.5" 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"> <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"/> <behavior key="behavior" pushIn="YES" changeContents="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
</buttonCell> </buttonCell>
</button> </button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="486"> <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="486">
<rect key="frame" x="357.5" 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"> <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"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
@@ -102,14 +103,14 @@ DQ
</connections> </connections>
</button> </button>
<button translatesAutoresizingMaskIntoConstraints="NO" id="d8O-Ha-rrS"> <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"> <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"/> <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
</buttonCell> </buttonCell>
</button> </button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="2pb-ZG-spA"> <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="2pb-ZG-spA">
<rect key="frame" x="227" 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"> <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"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
@@ -121,6 +122,14 @@ Gw
<action selector="_submit:" target="-2" id="aVF-1d-1Hq"/> <action selector="_submit:" target="-2" id="aVF-1d-1Hq"/>
</connections> </connections>
</button> </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> </subviews>
<constraints> <constraints>
<constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="2" secondAttribute="bottom" constant="20" symbolic="YES" id="122"/> <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="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="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="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="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="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="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="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="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"/> <constraint firstItem="2" firstAttribute="leading" secondItem="2pb-ZG-spA" secondAttribute="trailing" constant="12" id="ytJ-5Z-5rT"/>
</constraints> </constraints>
<point key="canvasLocation" x="-217" y="-96"/> <point key="canvasLocation" x="-127" y="-46"/>
</customView> </customView>
</objects> </objects>
<resources> <resources>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="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> <dependencies>
<deployment identifier="macosx"/> <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"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<objects> <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"> <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"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
DQ
</string>
</buttonCell> </buttonCell>
<connections> <connections>
<action selector="pickField:" target="-2" id="fLO-qW-oC9"/> <action selector="pickField:" target="-2" id="fLO-qW-oC9"/>
@@ -121,11 +124,11 @@
</tableView> </tableView>
</subviews> </subviews>
</clipView> </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"/> <rect key="frame" x="1" y="255" width="432" height="16"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
</scroller> </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"/> <rect key="frame" x="224" y="17" width="15" height="102"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
</scroller> </scroller>

View File

@@ -1,14 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="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> <dependencies>
<deployment identifier="macosx"/> <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"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<objects> <objects>
<customObject id="-2" userLabel="File's Owner" customClass="MPPluginPreferencesController"> <customObject id="-2" userLabel="File's Owner" customClass="MPPluginPreferencesController">
<connections> <connections>
<outlet property="addRemovePluginsControl" destination="B9Q-hq-K4N" id="Oqj-Ko-8UR"/> <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="fallbackDescriptionTextField" destination="qPL-FR-ky7" id="xCb-ED-NIX"/>
<outlet property="fallbackSettingsView" destination="wIk-iw-Tcz" id="dHl-zW-0aI"/> <outlet property="fallbackSettingsView" destination="wIk-iw-Tcz" id="dHl-zW-0aI"/>
<outlet property="forceIncompatiblePluginsCheckButton" destination="XIl-03-JZP" id="Aj4-rc-Ao0"/> <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="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/> <customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="Hz6-mo-xeY"> <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> <subviews>
<box borderType="line" title="Box" titlePosition="noTitle" translatesAutoresizingMaskIntoConstraints="NO" id="vBs-Ga-aq0"> <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"> <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"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="wIk-iw-Tcz"> <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> <subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="qPL-FR-ky7"> <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"> <textFieldCell key="cell" controlSize="mini" sendsActionOnEndEditing="YES" title="Plugin Settings Info" id="OOr-SW-jZb">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@@ -58,14 +59,14 @@
</view> </view>
</box> </box>
<button translatesAutoresizingMaskIntoConstraints="NO" id="CqP-oK-S8k"> <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"> <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"/> <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
</buttonCell> </buttonCell>
</button> </button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="aoG-FD-ds8"> <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"> <textFieldCell key="cell" controlSize="small" sendsActionOnEndEditing="YES" id="2bX-8S-9XM">
<font key="font" metaFont="smallSystem"/> <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> <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> </textFieldCell>
</textField> </textField>
<scrollView autohidesScrollers="YES" horizontalLineScroll="37" horizontalPageScroll="10" verticalLineScroll="37" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fCk-fL-jU8"> <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"> <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"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <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"> <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="313"/> <rect key="frame" x="0.0" y="0.0" width="148" height="298"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<size key="intercellSpacing" width="3" height="2"/> <size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
@@ -99,12 +100,12 @@
</textFieldCell> </textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/> <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<prototypeCellViews> <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"/> <rect key="frame" x="1" y="1" width="145" height="35"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="q1P-PD-0LW"> <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"> <textFieldCell key="cell" sendsActionOnEndEditing="YES" title="Table View Cell" id="fug-79-n9g">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> <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 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="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 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="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"/> <constraint firstItem="fQy-Sz-4VA" firstAttribute="leading" secondItem="vVt-P3-yLp" secondAttribute="leading" constant="2" id="zLP-Ci-nUM"/>
</constraints> </constraints>
@@ -154,7 +155,7 @@
</scroller> </scroller>
</scrollView> </scrollView>
<segmentedControl verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="B9Q-hq-K4N"> <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"> <segmentedCell key="cell" borderStyle="border" alignment="left" style="texturedSquare" trackingMode="momentary" id="cj3-R6-g1E">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
<segments> <segments>
@@ -167,7 +168,7 @@
</connections> </connections>
</segmentedControl> </segmentedControl>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="SNe-cc-CZs"> <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"> <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"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
@@ -177,30 +178,51 @@
</connections> </connections>
</button> </button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="XIl-03-JZP"> <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"> <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"/> <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
</buttonCell> </buttonCell>
</button> </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> </subviews>
<constraints> <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="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="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 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="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="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 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 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="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 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="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 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 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="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 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="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="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 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"/> <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="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"/> <constraint firstItem="aoG-FD-ds8" firstAttribute="top" secondItem="CqP-oK-S8k" secondAttribute="bottom" constant="8" symbolic="YES" id="zSW-h3-BrT"/>
</constraints> </constraints>
<point key="canvasLocation" x="110" y="-97"/> <point key="canvasLocation" x="179" y="115"/>
</customView> </customView>
</objects> </objects>
<resources> <resources>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="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> <dependencies>
<deployment identifier="macosx"/> <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"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<objects> <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="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"/> <constraint firstItem="d2Q-7O-ilP" firstAttribute="leading" secondItem="fjQ-ni-Ayx" secondAttribute="trailing" constant="8" symbolic="YES" id="wHQ-Lk-2fv"/>
</constraints> </constraints>
<point key="canvasLocation" x="-130" y="-66"/> <point key="canvasLocation" x="193" y="-18"/>
</customView> </customView>
</objects> </objects>
</document> </document>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="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> <dependencies>
<deployment identifier="macosx"/> <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"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<objects> <objects>
@@ -18,11 +18,11 @@
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/> <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/> <customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView id="c22-O7-iKe"> <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"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews> <subviews>
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="IZP-Gd-jdU"> <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"> <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"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/> <font key="font" metaFont="menu"/>
@@ -37,7 +37,7 @@
</connections> </connections>
</popUpButton> </popUpButton>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="IFf-vC-3vk" customClass="HNHUITextField"> <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> <constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="100" id="Seu-01-P53"/> <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="100" id="Seu-01-P53"/>
</constraints> </constraints>
@@ -48,14 +48,14 @@
</textFieldCell> </textFieldCell>
</textField> </textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="T2o-aJ-JmD"> <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"> <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"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
</buttonCell> </buttonCell>
</button> </button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="VR5-Rx-ueN"> <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"> <textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Key" id="K1t-OZ-ACe">
<font key="font" metaFont="smallSystem"/> <font key="font" metaFont="smallSystem"/>
<color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/>
@@ -63,7 +63,7 @@
</textFieldCell> </textFieldCell>
</textField> </textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="sZo-ie-Asw"> <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"> <textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Reference" id="r1V-VE-ngy">
<font key="font" metaFont="smallSystem"/> <font key="font" metaFont="smallSystem"/>
<color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/>
@@ -71,10 +71,10 @@
</textFieldCell> </textFieldCell>
</textField> </textField>
<popUpButton horizontalHuggingPriority="249" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="b4e-k2-WPS"> <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"> <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"/> <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"> <menu key="menu" id="j2A-qj-k7L">
<items> <items>
<menuItem title="Matching" state="on" id="yT1-XL-k6a"> <menuItem title="Matching" state="on" id="yT1-XL-k6a">
@@ -88,7 +88,7 @@
</connections> </connections>
</popUpButton> </popUpButton>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="WTJ-he-uTu"> <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"> <textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Match" id="9ce-da-syF">
<font key="font" metaFont="smallSystem"/> <font key="font" metaFont="smallSystem"/>
<color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/>
@@ -96,7 +96,7 @@
</textFieldCell> </textFieldCell>
</textField> </textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="mcC-bG-cCz"> <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"> <textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Reference String" id="gik-Ha-hRd">
<font key="font" metaFont="smallSystem"/> <font key="font" metaFont="smallSystem"/>
<color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/>
@@ -104,7 +104,7 @@
</textFieldCell> </textFieldCell>
</textField> </textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="b36-T7-1tO" customClass="HNHUITextField"> <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"> <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"/> <font key="font" metaFont="system"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>

View File

@@ -1,11 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="10117" systemVersion="15G31" 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> <dependencies>
<deployment identifier="macosx"/> <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> </dependencies>
<objects> <objects>
<customObject id="-2" userLabel="File's Owner" customClass="MPUpdateSettingsController"> <customObject id="-2" userLabel="File's Owner" customClass="MPUpdatePreferencesController">
<connections> <connections>
<outlet property="automaticallyCheckForUpdatesCheckButton" destination="Z6x-oU-NC5" id="xHU-Lt-PmA"/> <outlet property="automaticallyCheckForUpdatesCheckButton" destination="Z6x-oU-NC5" id="xHU-Lt-PmA"/>
<outlet property="checkIntervallPopupButton" destination="pWJ-eJ-MBf" id="znu-Me-2Me"/> <outlet property="checkIntervallPopupButton" destination="pWJ-eJ-MBf" id="znu-Me-2Me"/>
@@ -17,8 +18,8 @@
<customView translatesAutoresizingMaskIntoConstraints="NO" id="1"> <customView translatesAutoresizingMaskIntoConstraints="NO" id="1">
<rect key="frame" x="0.0" y="0.0" width="400" height="95"/> <rect key="frame" x="0.0" y="0.0" width="400" height="95"/>
<subviews> <subviews>
<button verticalHuggingPriority="500" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Z6x-oU-NC5"> <button verticalHuggingPriority="500" translatesAutoresizingMaskIntoConstraints="NO" id="Z6x-oU-NC5">
<rect key="frame" x="21" y="59" width="228" height="18"/> <rect key="frame" x="22" y="59" width="221" height="18"/>
<constraints> <constraints>
<constraint firstAttribute="height" constant="14" id="ppB-Ka-SVN"/> <constraint firstAttribute="height" constant="14" id="ppB-Ka-SVN"/>
</constraints> </constraints>
@@ -27,11 +28,11 @@
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
</buttonCell> </buttonCell>
</button> </button>
<popUpButton verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="pWJ-eJ-MBf"> <popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="pWJ-eJ-MBf">
<rect key="frame" x="145" y="17" width="112" height="26"/> <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"> <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"/> <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"> <menu key="menu" title="OtherViews" id="RKd-H8-eCF">
<items> <items>
<menuItem title="every Hour" tag="3600" id="DjF-1I-6Nq"/> <menuItem title="every Hour" tag="3600" id="DjF-1I-6Nq"/>
@@ -44,8 +45,8 @@
</menu> </menu>
</popUpButtonCell> </popUpButtonCell>
</popUpButton> </popUpButton>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ckg-9t-MDS"> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ckg-9t-MDS">
<rect key="frame" x="21" y="23" width="120" height="17"/> <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"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Check for Updates" id="9tL-CA-Vdg">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> <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 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="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 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 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"/> <constraint firstAttribute="bottom" secondItem="pWJ-eJ-MBf" secondAttribute="bottom" constant="20" symbolic="YES" id="pHW-e8-EU6"/>
</constraints> </constraints>
<point key="canvasLocation" x="504" y="511.5"/> <point key="canvasLocation" x="21" y="2"/>
</customView> </customView>
</objects> </objects>
</document> </document>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="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> <dependencies>
<deployment identifier="macosx"/> <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"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<objects> <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 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"/> <constraint firstAttribute="bottom" secondItem="ITj-5P-sn9" secondAttribute="bottom" id="syW-TO-uwv"/>
</constraints> </constraints>
<point key="canvasLocation" x="-378" y="-552"/> <point key="canvasLocation" x="-680" y="-522"/>
</view> </view>
</objects> </objects>
<resources> <resources>

View File

@@ -1,16 +1,17 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="10117" systemVersion="15G31" 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> <dependencies>
<deployment identifier="macosx"/> <deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/> <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15702"/>
<capability name="box content view" minToolsVersion="7.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<objects> <objects>
<customObject id="-2" userLabel="File's Owner" customClass="MPWorkflowSettingsController"> <customObject id="-2" userLabel="File's Owner" customClass="MPWorkflowPreferencesController">
<connections> <connections>
<outlet property="browserPopup" destination="ehI-gq-lsb" id="YMy-L1-pQw"/> <outlet property="browserPopup" destination="ehI-gq-lsb" id="YMy-L1-pQw"/>
<outlet property="doubleClickTitlePopup" destination="40" id="aKJ-q9-xjb"/> <outlet property="doubleClickTitlePopup" destination="40" id="aKJ-q9-xjb"/>
<outlet property="doubleClickURLPopup" destination="13" id="fGP-5I-0XK"/> <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="updatePasswordOnTemplateEntriesCheckButton" destination="LPY-sM-hjS" id="wav-op-uck"/>
<outlet property="view" destination="1" id="52"/> <outlet property="view" destination="1" id="52"/>
</connections> </connections>
@@ -18,16 +19,16 @@
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/> <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/> <customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="1"> <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> <subviews>
<box autoresizesSubviews="NO" verticalHuggingPriority="500" title="Entry Table" borderType="line" translatesAutoresizingMaskIntoConstraints="NO" id="2"> <box autoresizesSubviews="NO" verticalHuggingPriority="500" borderType="line" title="Entry Table" translatesAutoresizingMaskIntoConstraints="NO" id="2">
<rect key="frame" x="17" y="90" width="366" height="92"/> <rect key="frame" x="17" y="166" width="366" height="99"/>
<view key="contentView" id="cfa-nq-Kzt"> <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"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="9"> <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"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Double-click on URL:" id="10">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -35,10 +36,10 @@
</textFieldCell> </textFieldCell>
</textField> </textField>
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="13"> <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"> <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"/> <behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/> <font key="font" metaFont="system"/>
<menu key="menu" title="OtherViews" id="15"> <menu key="menu" title="OtherViews" id="15">
<items> <items>
<menuItem title="Copies URL" id="16"/> <menuItem title="Copies URL" id="16"/>
@@ -48,7 +49,7 @@
</popUpButtonCell> </popUpButtonCell>
</popUpButton> </popUpButton>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="36"> <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"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" enabled="NO" sendsActionOnEndEditing="YES" title="Double-click on Title:" id="37">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -56,10 +57,10 @@
</textFieldCell> </textFieldCell>
</textField> </textField>
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="40"> <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"> <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"/> <behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/> <font key="font" metaFont="system"/>
<menu key="menu" title="OtherViews" id="42"> <menu key="menu" title="OtherViews" id="42">
<items> <items>
<menuItem title="Opens Inspector" state="on" id="44"/> <menuItem title="Opens Inspector" state="on" id="44"/>
@@ -69,27 +70,30 @@
</popUpButtonCell> </popUpButtonCell>
</popUpButton> </popUpButton>
</subviews> </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> </view>
<constraints> <constraints>
<constraint firstItem="13" firstAttribute="leading" secondItem="9" secondAttribute="trailing" constant="8" symbolic="YES" id="1WE-nm-pp2"/> <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="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 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="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="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"/> <constraint firstItem="40" firstAttribute="leading" secondItem="36" secondAttribute="trailing" constant="8" symbolic="YES" id="tsy-wg-saI"/>
</constraints> </constraints>
<color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
<color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</box> </box>
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ehI-gq-lsb"> <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"> <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"/> <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"> <menu key="menu" title="OtherViews" id="XgO-Tj-QjO">
<items> <items>
<menuItem title="Default Browser" state="on" id="7YX-EA-9KA"/> <menuItem title="Default Browser" state="on" id="7YX-EA-9KA"/>
@@ -100,21 +104,21 @@
</popUpButtonCell> </popUpButtonCell>
</popUpButton> </popUpButton>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="lOo-NI-b07"> <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"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" enabled="NO" sendsActionOnEndEditing="YES" title="Open URLs in:" id="soD-wI-YOH">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell> </textFieldCell>
</textField> </textField>
<box title="Templates" borderType="line" translatesAutoresizingMaskIntoConstraints="NO" id="Xvt-tP-TbR"> <box borderType="line" title="Templates" translatesAutoresizingMaskIntoConstraints="NO" id="Xvt-tP-TbR">
<rect key="frame" x="17" y="16" width="366" height="70"/> <rect key="frame" x="17" y="92" width="366" height="72"/>
<view key="contentView" id="g0i-00-sng"> <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"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="LPY-sM-hjS"> <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"> <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"/> <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/> <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="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 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="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> </constraints>
</view> </view>
<color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
<color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</box> </box>
</subviews> </subviews>
<constraints> <constraints>
<constraint firstItem="2" firstAttribute="leading" secondItem="1" secondAttribute="leading" constant="20" symbolic="YES" id="5"/> <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="trailing" secondItem="2" secondAttribute="trailing" constant="20" symbolic="YES" id="8"/>
<constraint firstAttribute="width" constant="400" id="53"/> <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 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="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 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 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="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 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="firstBaseline" secondItem="ehI-gq-lsb" secondAttribute="firstBaseline" id="gFK-Ce-Q3b"/>
<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="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"/> <constraint firstItem="2" firstAttribute="top" secondItem="lOo-NI-b07" secondAttribute="bottom" constant="8" symbolic="YES" id="xlS-Dj-cOt"/>
</constraints> </constraints>
<point key="canvasLocation" x="435" y="649"/> <point key="canvasLocation" x="-2" y="125"/>
</customView> </customView>
</objects> </objects>
</document> </document>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="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> <dependencies>
<deployment identifier="macosx"/> <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"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<objects> <objects>

View File

@@ -23,7 +23,7 @@
#import "KPKEntry+MPCustomAttributeProperties.h" #import "KPKEntry+MPCustomAttributeProperties.h"
#import <objc/runtime.h> #import <objc/runtime.h>
NSString *const MPCustomAttributePropertyPrefix = @"valueForCustomAttribute"; NSString *const MPCustomAttributePropertyPrefix = @"mp_valueForCustomAttribute";
@implementation KPKEntry (MPCustomAttributeProperties) @implementation KPKEntry (MPCustomAttributeProperties)
@@ -36,7 +36,7 @@ static id propertyIMP(id self, SEL _cmd) {
+ (BOOL)resolveInstanceMethod:(SEL)aSEL { + (BOOL)resolveInstanceMethod:(SEL)aSEL {
if ([NSStringFromSelector(aSEL) hasPrefix:MPCustomAttributePropertyPrefix]) { if ([NSStringFromSelector(aSEL) hasPrefix:MPCustomAttributePropertyPrefix]) {
class_addMethod([self class], aSEL,(IMP)propertyIMP, "@@:"); class_addMethod(self.class, aSEL,(IMP)propertyIMP, "@@:");
return YES; return YES;
} }
return [super resolveInstanceMethod:aSEL]; return [super resolveInstanceMethod:aSEL];

22
MacPass/KPKEntry+MPTags.h Normal file
View 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
View 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

View File

@@ -28,6 +28,7 @@ typedef NS_ENUM(NSUInteger, MPActionType) {
MPActionAddGroup, // Add a new group MPActionAddGroup, // Add a new group
MPActionDuplicateEntry, // Simply duplicate an entry (including history) MPActionDuplicateEntry, // Simply duplicate an entry (including history)
MPActionDuplicateEntryWithOptions, // Request user input on what to duplicate 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 MPActionReverToHistoryEntry, // Restore an entry to an older state in history
MPActionDelete, // Delete entry or group MPActionDelete, // Delete entry or group
MPActionCopyUsername, // copy username to pasteboard MPActionCopyUsername, // copy username to pasteboard
@@ -47,6 +48,7 @@ typedef NS_ENUM(NSUInteger, MPActionType) {
MPActionToggleQuicklook, MPActionToggleQuicklook,
MPActionShowEntryHistory, // show history MPActionShowEntryHistory, // show history
MPActionHideEntryHistory, // exit history MPActionHideEntryHistory, // exit history
MPActionShowGroupInOutline, // show the group (of the entry) in the outline view
MPActionPerformAutotypeForSelectedEntry, // Perform Autotype for selected Entry MPActionPerformAutotypeForSelectedEntry, // Perform Autotype for selected Entry
MPActionRemoveAttachment // Remove an attachment MPActionRemoveAttachment // Remove an attachment
}; };

View File

@@ -38,6 +38,7 @@
@(MPActionAddGroup): NSStringFromSelector(@selector(createGroup:)), @(MPActionAddGroup): NSStringFromSelector(@selector(createGroup:)),
@(MPActionDuplicateEntry): NSStringFromSelector(@selector(duplicateEntry:)), @(MPActionDuplicateEntry): NSStringFromSelector(@selector(duplicateEntry:)),
@(MPActionDuplicateEntryWithOptions): NSStringFromSelector(@selector(duplicateEntryWithOptions:)), @(MPActionDuplicateEntryWithOptions): NSStringFromSelector(@selector(duplicateEntryWithOptions:)),
@(MPActionDuplicateGroup): NSStringFromSelector(@selector(duplicateGroup:)),
@(MPActionReverToHistoryEntry): NSStringFromSelector(@selector(revertToHistoryEntry:)), @(MPActionReverToHistoryEntry): NSStringFromSelector(@selector(revertToHistoryEntry:)),
@(MPActionCopyPassword): NSStringFromSelector(@selector(copyPassword:)), @(MPActionCopyPassword): NSStringFromSelector(@selector(copyPassword:)),
@(MPActionCopyURL): NSStringFromSelector(@selector(copyURL:)), @(MPActionCopyURL): NSStringFromSelector(@selector(copyURL:)),
@@ -57,6 +58,7 @@
@(MPActionToggleQuicklook): NSStringFromSelector(@selector(toggleQuicklookPreview:)), @(MPActionToggleQuicklook): NSStringFromSelector(@selector(toggleQuicklookPreview:)),
@(MPActionShowEntryHistory): NSStringFromSelector(@selector(showEntryHistory:)), @(MPActionShowEntryHistory): NSStringFromSelector(@selector(showEntryHistory:)),
@(MPActionHideEntryHistory): NSStringFromSelector(@selector(hideEntryHistory:)), @(MPActionHideEntryHistory): NSStringFromSelector(@selector(hideEntryHistory:)),
@(MPActionShowGroupInOutline): NSStringFromSelector(@selector(showGroupInOutline:)),
@(MPActionPerformAutotypeForSelectedEntry): NSStringFromSelector(@selector(performAutotypeForEntry:)), @(MPActionPerformAutotypeForSelectedEntry): NSStringFromSelector(@selector(performAutotypeForEntry:)),
@(MPActionRemoveAttachment): NSStringFromSelector(@selector(removeAttachment:)) @(MPActionRemoveAttachment): NSStringFromSelector(@selector(removeAttachment:))
}; };

View File

@@ -33,6 +33,7 @@ APPKIT_EXTERN NSString *const MPDidChangeStoredKeyFilesSettings;
@property (strong) IBOutlet NSMenuItem *fileNewMenuItem; @property (strong) IBOutlet NSMenuItem *fileNewMenuItem;
@property (strong) IBOutlet NSMenu *itemMenu; @property (strong) IBOutlet NSMenu *itemMenu;
@property (strong) IBOutlet NSMenu *importMenu; @property (strong) IBOutlet NSMenu *importMenu;
@property (strong) IBOutlet NSMenu *exportMenu;
@property (strong, readonly) MPEntryContextMenuDelegate *itemActionMenuDelegate; @property (strong, readonly) MPEntryContextMenuDelegate *itemActionMenuDelegate;
@@ -42,6 +43,7 @@ APPKIT_EXTERN NSString *const MPDidChangeStoredKeyFilesSettings;
- (IBAction)showPreferences:(id)sender; - (IBAction)showPreferences:(id)sender;
- (IBAction)showPluginPrefences:(id)sender; - (IBAction)showPluginPrefences:(id)sender;
- (IBAction)showPasswordCreator:(id)sender; - (IBAction)showPasswordCreator:(id)sender;
- (IBAction)showAutotypeDoctor:(id)sender;
- (IBAction)createNewDatabase:(id)sender; - (IBAction)createNewDatabase:(id)sender;
- (IBAction)openDatabase:(id)sender; - (IBAction)openDatabase:(id)sender;
- (IBAction)showHelp:(id)sender; - (IBAction)showHelp:(id)sender;

View File

@@ -42,8 +42,10 @@
#import "MPWelcomeViewController.h" #import "MPWelcomeViewController.h"
#import "MPPlugin.h" #import "MPPlugin.h"
#import "MPEntryContextMenuDelegate.h" #import "MPEntryContextMenuDelegate.h"
#import "MPAutotypeDoctor.h"
#import "NSApplication+MPAdditions.h" #import "NSApplication+MPAdditions.h"
#import "NSTextView+MPTouchBarExtension.h"
#import "KeePassKit/KeePassKit.h" #import "KeePassKit/KeePassKit.h"
@@ -51,6 +53,12 @@
NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDidChangeStoredKeyFilesSettings"; NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDidChangeStoredKeyFilesSettings";
typedef NS_OPTIONS(NSInteger, MPAppStartupState) {
MPAppStartupStateNone = 0,
MPAppStartupStateRestoredWindows = 1,
MPAppStartupStateFinishedLaunch = 2
};
@interface MPAppDelegate () { @interface MPAppDelegate () {
@private @private
MPDockTileHelper *_dockTileHelper; MPDockTileHelper *_dockTileHelper;
@@ -62,6 +70,7 @@ NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDi
@property (strong) IBOutlet NSWindow *passwordCreatorWindow; @property (strong) IBOutlet NSWindow *passwordCreatorWindow;
@property (strong, nonatomic) MPPreferencesWindowController *preferencesController; @property (strong, nonatomic) MPPreferencesWindowController *preferencesController;
@property (strong, nonatomic) MPPasswordCreatorViewController *passwordCreatorController; @property (strong, nonatomic) MPPasswordCreatorViewController *passwordCreatorController;
@property (assign, nonatomic) MPAppStartupState startupState;
@property (strong) MPEntryContextMenuDelegate *itemActionMenuDelegate; @property (strong) MPEntryContextMenuDelegate *itemActionMenuDelegate;
@@ -82,11 +91,22 @@ NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDi
if(self) { if(self) {
_userNotificationCenterDelegate = [[MPUserNotificationCenterDelegate alloc] init]; _userNotificationCenterDelegate = [[MPUserNotificationCenterDelegate alloc] init];
self.itemActionMenuDelegate = [[MPEntryContextMenuDelegate 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 */ /* We know that we do not use the variable after instantiation */
#pragma clang diagnostic push #pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-variable" #pragma clang diagnostic ignored "-Wunused-variable"
MPDocumentController *documentController = [[MPDocumentController alloc] init]; MPDocumentController *documentController = [[MPDocumentController alloc] init];
#pragma clang diagnostic pop #pragma clang diagnostic pop
} }
return self; 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 { - (void)awakeFromNib {
_isAllowedToStoreKeyFile = NO; _isAllowedToStoreKeyFile = NO;
/* Update the at the save menu */ /* Update the at the save menu */
@@ -127,7 +158,7 @@ NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDi
[fileMenu insertItem:item atIndex:insertIndex]; [fileMenu insertItem:item atIndex:insertIndex];
} }
[self.itemMenu removeAllItems]; [self.itemMenu removeAllItems];
for(NSMenuItem *item in [MPContextMenuHelper contextMenuItemsWithItems:MPContextMenuFull]) { for(NSMenuItem *item in [MPContextMenuHelper contextMenuItemsWithItems:MPContextMenuFull|MPContextMenuShowGroupInOutline]) {
[self.itemMenu addItem:item]; [self.itemMenu addItem:item];
} }
self.itemMenu.delegate = self.itemActionMenuDelegate; self.itemMenu.delegate = self.itemActionMenuDelegate;
@@ -154,23 +185,13 @@ NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDi
return [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyOpenEmptyDatabaseOnLaunch]; 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 { - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender {
return [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyQuitOnLastWindowClose]; return [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyQuitOnLastWindowClose];
} }
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender { - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
if([[MPTemporaryFileStorageCenter defaultCenter] hasPendingStorages]) { [self hideWelcomeWindow];
if(MPTemporaryFileStorageCenter.defaultCenter.hasPendingStorages) {
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
[MPTemporaryFileStorageCenter.defaultCenter cleanupStorages]; [MPTemporaryFileStorageCenter.defaultCenter cleanupStorages];
[sender replyToApplicationShouldTerminate:YES]; [sender replyToApplicationShouldTerminate:YES];
@@ -201,6 +222,13 @@ NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDi
/* Disable updates if in debug or nosparkle */ /* Disable updates if in debug or nosparkle */
[SUUpdater sharedUpdater]; [SUUpdater sharedUpdater];
#endif #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 - #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"); 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; self.saveMenuItem.title = saveTitle;
} }
if(menu == self.fixAutotypeMenuItem.menu) { else if(menu == self.fixAutotypeMenuItem.menu) {
self.fixAutotypeMenuItem.hidden = !(NSEvent.modifierFlags & NSAlternateKeyMask); self.fixAutotypeMenuItem.hidden = !(NSEvent.modifierFlags & NSAlternateKeyMask);
} }
if(menu == self.importMenu) { else if(menu == self.importMenu) {
NSMenuItem *exportXML = menu.itemArray.firstObject; NSMenuItem *exportXML = menu.itemArray.firstObject;
[menu removeAllItems]; [menu removeAllItems];
[menu addItem:exportXML];
for(MPPlugin<MPImportPlugin> * plugin in MPPluginHost.sharedHost.importPlugins) { for(MPPlugin<MPImportPlugin> * plugin in MPPluginHost.sharedHost.importPlugins) {
NSMenuItem *importItem = [[NSMenuItem alloc] init]; NSMenuItem *importItem = [[NSMenuItem alloc] init];
[plugin prepareImportMenuItem:importItem]; [plugin prepareImportMenuItem:importItem];
importItem.submenu = nil; // kill any potential submenu!
importItem.representedObject = plugin.identifier;
importItem.target = nil; 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 styleMask:NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskResizable
backing:NSBackingStoreBuffered backing:NSBackingStoreBuffered
defer:NO]; defer:NO];
self.welcomeWindow.restorable = NO; // do not restore the welcome window!
self.welcomeWindow.releasedWhenClosed = NO; self.welcomeWindow.releasedWhenClosed = NO;
} }
if(!self.welcomeWindow.contentViewController) { if(!self.welcomeWindow.contentViewController) {
@@ -313,11 +359,15 @@ NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDi
[NSWorkspace.sharedWorkspace openURL:[NSURL URLWithString:urlString]]; [NSWorkspace.sharedWorkspace openURL:[NSURL URLWithString:urlString]];
} }
- (void)showAutotypeDoctor:(id)sender {
[MPAutotypeDoctor.defaultDoctor runChecksAndPresentResults];
}
- (void)checkForUpdates:(id)sender { - (void)checkForUpdates:(id)sender {
#if defined(DEBUG) || defined(NO_SPARKLE) #if defined(DEBUG) || defined(NO_SPARKLE)
NSAlert *alert = [[NSAlert alloc] init]; NSAlert *alert = [[NSAlert alloc] init];
alert.messageText = NSLocalizedString(@"ALERT_UPDATES_DISABLED_MESSAGE_TEXT", @"Message text for disabled updates alert!"); 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 addButtonWithTitle:NSLocalizedString(@"OK", @"Ok Button to dismiss disabled updates alert")];
[alert runModal]; [alert runModal];
#else #else
@@ -328,8 +378,12 @@ NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDi
#pragma mark - #pragma mark -
#pragma mark Private Helper #pragma mark Private Helper
- (void)_applicationDidFinishRestoringWindows:(NSNotification *)notification { - (void)_applicationDidFinishRestoringWindows:(NSNotification *)notification {
self.startupState |= MPAppStartupStateRestoredWindows;
}
- (void)_applicationDidFinishLaunchingAndDidRestoreWindows {
NSArray *documents = NSDocumentController.sharedDocumentController.documents; NSArray *documents = NSDocumentController.sharedDocumentController.documents;
BOOL restoredWindows = documents.count > 0; BOOL hasOpenDocuments = documents.count > 0;
for(NSDocument *document in documents) { for(NSDocument *document in documents) {
for(NSWindowController *windowController in document.windowControllers) { for(NSWindowController *windowController in document.windowControllers) {
@@ -338,17 +392,13 @@ NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDi
} }
BOOL reopen = [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyReopenLastDatabaseOnLaunch]; BOOL reopen = [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyReopenLastDatabaseOnLaunch];
BOOL showWelcomeScreen = !restoredWindows && !_shouldOpenFile; BOOL showWelcomeScreen = !hasOpenDocuments && !_shouldOpenFile;
if(reopen && !restoredWindows && !_shouldOpenFile) { if(reopen && !hasOpenDocuments && !_shouldOpenFile) {
showWelcomeScreen = ![((MPDocumentController *)NSDocumentController.sharedDocumentController) reopenLastDocument]; showWelcomeScreen = ![((MPDocumentController *)NSDocumentController.sharedDocumentController) reopenLastDocument];
} }
if(showWelcomeScreen) { if(showWelcomeScreen) {
[self showWelcomeWindow]; [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 @end

View File

@@ -22,12 +22,19 @@
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
NS_ASSUME_NONNULL_BEGIN
@class MPAutotypeEnvironment;
@class MPAutotypeContext;
@interface MPAutotypeCandidateSelectionViewController : NSViewController @interface MPAutotypeCandidateSelectionViewController : NSViewController
@property (copy) NSArray *candidates; @property (strong) MPAutotypeEnvironment *environment;
@property (copy) NSArray<MPAutotypeContext *> *candidates;
- (IBAction)selectAutotypeContext:(id)sender; - (IBAction)selectAutotypeContext:(id)sender;
- (IBAction)cancelSelection:(id)sender; - (IBAction)cancelSelection:(id)sender;
@end @end
NS_ASSUME_NONNULL_END

View File

@@ -22,14 +22,17 @@
#import "MPAutotypeCandidateSelectionViewController.h" #import "MPAutotypeCandidateSelectionViewController.h"
#import "MPAutotypeContext.h" #import "MPAutotypeContext.h"
#import "MPAutotypeDaemon.h" #import "MPAutotypeDaemon.h"
#import "MPAutotypeEnvironment.h"
#import "MPExtendedTableCellView.h"
#import "KPKNode+IconImage.h" #import "KPKNode+IconImage.h"
#import <KeePassKit/KeePassKit.h> #import <KeePassKit/KeePassKit.h>
@interface MPAutotypeCandidateSelectionViewController () <NSTableViewDataSource, NSTableViewDelegate> @interface MPAutotypeCandidateSelectionViewController () <NSTableViewDataSource, NSTableViewDelegate>
@property (weak) IBOutlet NSButton *selectAutotypeContextButton; @property (strong) IBOutlet NSButton *selectAutotypeContextButton;
@property (weak) IBOutlet NSTableView *contextTableView; @property (strong) IBOutlet NSTableView *contextTableView;
@property (strong) IBOutlet NSTextField *messageTextField;
@end @end
@@ -41,6 +44,8 @@
- (void)viewDidLoad { - (void)viewDidLoad {
[super 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; self.selectAutotypeContextButton.enabled = NO;
NSNotification *notification = [NSNotification notificationWithName:NSTableViewSelectionDidChangeNotification object:self.contextTableView]; NSNotification *notification = [NSNotification notificationWithName:NSTableViewSelectionDidChangeNotification object:self.contextTableView];
[self tableViewSelectionDidChange:notification]; [self tableViewSelectionDidChange:notification];
@@ -55,12 +60,10 @@
#pragma mark NSTableViewDelegate #pragma mark NSTableViewDelegate
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { - (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]; MPAutotypeContext *context = self.candidates[row];
NSString *maskedEvaluatedCommand = context.maskedEvaluatedCommand; view.addionalTextField.stringValue = context.maskedEvaluatedCommand;
NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@\n%@", context.entry.title, maskedEvaluatedCommand]]; view.textField.stringValue = context.entry.title;
[string setAttributes:@{NSForegroundColorAttributeName: NSColor.disabledControlTextColor} range:NSMakeRange((string.length - maskedEvaluatedCommand.length), maskedEvaluatedCommand.length)];
view.textField.attributedStringValue = string;
view.imageView.image = context.entry.iconImage; view.imageView.image = context.entry.iconImage;
return view; return view;
} }
@@ -77,7 +80,7 @@
- (void)selectAutotypeContext:(id)sender { - (void)selectAutotypeContext:(id)sender {
NSInteger selectedRow = self.contextTableView.selectedRow; NSInteger selectedRow = self.contextTableView.selectedRow;
if(selectedRow >= 0 && selectedRow < self.candidates.count) { if(selectedRow >= 0 && selectedRow < self.candidates.count) {
[MPAutotypeDaemon.defaultDaemon selectAutotypeCandiate:self.candidates[selectedRow]]; [MPAutotypeDaemon.defaultDaemon selectAutotypeContext:self.candidates[selectedRow] forEnvironment:self.environment];
} }
else { else {
[self cancelSelection:sender]; // cancel since the selection was invalid! [self cancelSelection:sender]; // cancel since the selection was invalid!
@@ -85,7 +88,7 @@
} }
- (void)cancelSelection:(id)sender { - (void)cancelSelection:(id)sender {
[[MPAutotypeDaemon defaultDaemon] cancelAutotypeCandidateSelection]; [MPAutotypeDaemon.defaultDaemon cancelAutotypeContextSelectionForEnvironment:self.environment];
} }

View File

@@ -25,7 +25,7 @@
@class DDHotKey; @class DDHotKey;
@class KPKEntry; @class KPKEntry;
@class MPAutotypeContext; @class MPAutotypeContext;
@class MPAutotypeExecutionContext; @class MPAutotypeEnvironment;
/** /**
* The autotype daemon is responsible for registering the global hotkey and to perform any autotype actions * 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 (weak) IBOutlet NSPopUpButton *matchSelectionButton;
@property (readonly, strong) DDHotKey *registredHotKey; @property (readonly, strong) DDHotKey *registredHotKey;
@property (readonly, strong, class) MPAutotypeDaemon *defaultDaemon; @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; - (instancetype)init NS_UNAVAILABLE;
- (void)checkForAccessibiltyPermissions;
- (void)openAccessibiltyPreferences;
- (void)performAutotypeForEntry:(KPKEntry *)entry; - (void)performAutotypeForEntry:(KPKEntry *)entry;
- (void)performAutotypeForEntry:(KPKEntry *)entry overrideSequence:(NSString *)sequence; - (void)performAutotypeForEntry:(KPKEntry *)entry overrideSequence:(NSString *)sequence;
- (void)selectAutotypeCandiate:(MPAutotypeContext *)context; - (void)selectAutotypeContext:(MPAutotypeContext *)context forEnvironment:(MPAutotypeEnvironment *)environment;
- (void)cancelAutotypeCandidateSelection; - (void)cancelAutotypeContextSelectionForEnvironment:(MPAutotypeEnvironment *)environment;
@end @end

View File

@@ -25,11 +25,17 @@
#import "MPDocumentWindowController.h" #import "MPDocumentWindowController.h"
#import "MPAutotypeCommand.h" #import "MPAutotypeCommand.h"
#import "MPAutotypeContext.h" #import "MPAutotypeContext.h"
#import "MPAutotypeEnvironment.h"
#import "MPAutotypePaste.h" #import "MPAutotypePaste.h"
#import "MPAutotypeDelay.h"
#import "MPPasteBoardController.h" #import "MPPasteBoardController.h"
#import "MPSettingsHelper.h" #import "MPSettingsHelper.h"
#import "MPAutotypeCandidateSelectionViewController.h" #import "MPAutotypeCandidateSelectionViewController.h"
#import "MPUserNotificationCenterDelegate.h" #import "MPUserNotificationCenterDelegate.h"
#import "MPAutotypeDoctor.h"
#import "MPPluginHost.h"
#import "MPPlugin.h"
#import "NSApplication+MPAdditions.h" #import "NSApplication+MPAdditions.h"
#import "NSUserNotification+MPAdditions.h" #import "NSUserNotification+MPAdditions.h"
@@ -40,25 +46,20 @@
#import "KeePassKit/KeePassKit.h" #import "KeePassKit/KeePassKit.h"
#import <Carbon/Carbon.h> #import <Carbon/Carbon.h>
NSString *const kMPWindowTitleKey = @"kMPWindowTitleKey";
NSString *const kMPProcessIdentifierKey = @"kMPProcessIdentifierKey";
@interface MPAutotypeDaemon () @interface MPAutotypeDaemon ()
@property (nonatomic, assign) BOOL enabled; @property (nonatomic, assign) BOOL enabled;
@property (nonatomic, copy) NSData *hotKeyData; @property (nonatomic, copy) NSData *hotKeyData;
@property (strong) DDHotKey *registredHotKey; @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 (strong) NSRunningApplication *previousApplication; // The application that was active before we got invoked
@property (assign) NSTimeInterval userActionRequested; @property (assign) NSTimeInterval userActionRequested;
@property (strong) id applicationActivationObserver;
@property (nonatomic, readonly) BOOL hasNecessaryAutotypePermissions;
@end @end
@implementation MPAutotypeDaemon @implementation MPAutotypeDaemon
@dynamic autotypeSupported;
#pragma mark - #pragma mark -
#pragma mark Lifecylce #pragma mark Lifecylce
@@ -81,7 +82,6 @@ static MPAutotypeDaemon *_sharedInstance;
self = [super init]; self = [super init];
if (self) { if (self) {
_enabled = NO; _enabled = NO;
_targetPID = -1;
_userActionRequested = NSDate.distantPast.timeIntervalSinceReferenceDate; _userActionRequested = NSDate.distantPast.timeIntervalSinceReferenceDate;
[self bind:NSStringFromSelector(@selector(enabled)) [self bind:NSStringFromSelector(@selector(enabled))
toObject:NSUserDefaultsController.sharedUserDefaultsController toObject:NSUserDefaultsController.sharedUserDefaultsController
@@ -104,19 +104,15 @@ static MPAutotypeDaemon *_sharedInstance;
- (void)dealloc { - (void)dealloc {
[NSNotificationCenter.defaultCenter removeObserver:self]; [NSNotificationCenter.defaultCenter removeObserver:self];
[NSWorkspace.sharedWorkspace.notificationCenter 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(enabled))];
[self unbind:NSStringFromSelector(@selector(hotKeyData))]; [self unbind:NSStringFromSelector(@selector(hotKeyData))];
} }
#pragma mark - #pragma mark -
#pragma mark Properties #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 { - (void)setEnabled:(BOOL)enabled {
if(_enabled != enabled) { if(_enabled != enabled) {
@@ -135,45 +131,8 @@ static MPAutotypeDaemon *_sharedInstance;
} }
} }
- (void)checkForAccessibiltyPermissions { - (BOOL)hasNecessaryAutotypePermissions {
if(!self.enabled) { return MPAutotypeDoctor.defaultDoctor.hasNecessaryAutotypePermissions;
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"]];
} }
#pragma mark - #pragma mark -
@@ -181,51 +140,69 @@ static MPAutotypeDaemon *_sharedInstance;
- (void)performAutotypeForEntry:(KPKEntry *)entry { - (void)performAutotypeForEntry:(KPKEntry *)entry {
[self performAutotypeForEntry:entry overrideSequence:nil]; [self performAutotypeForEntry:entry overrideSequence:nil];
} }
- (void)performAutotypeForEntry:(KPKEntry *)entry overrideSequence:(NSString *)sequence { - (void)performAutotypeForEntry:(KPKEntry *)entry overrideSequence:(NSString *)sequence {
if(entry) { if(entry) {
[self _updateTargeInformationForApplication:self.previousApplication]; MPAutotypeEnvironment *env = [MPAutotypeEnvironment environmentWithTargetApplication:self.previousApplication entry:entry];
[self _performAutotypeForEntry:entry]; [self _runAutotypeWithEnvironment:env];
} }
} }
- (void)_didPressHotKey { - (void)_didPressHotKey {
[self _updateTargetInformationForFrontMostApplication]; MPAutotypeEnvironment *env = [MPAutotypeEnvironment environmentWithTargetApplication:NSWorkspace.sharedWorkspace.frontmostApplication entry:nil];
[self _performAutotypeForEntry:nil]; [self _runAutotypeWithEnvironment:env];
}
#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];
}
} }
#pragma mark - #pragma mark -
#pragma mark Autotype Execution #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 { - (void)cancelAutotypeContextSelectionForEnvironment:(MPAutotypeEnvironment *)environment {
/*if(!self.autotypeSupported) { [self.matchSelectionWindow orderOut:self];
NSUserNotification *notification = [[NSUserNotification alloc] init]; self.matchSelectionWindow = nil;
notification.title = NSApp.applicationName; if(environment.hidden) {
notification.informativeText = NSLocalizedString(@"AUTOTYPE_NOTIFICATION_MACPASS_HAS_NO_ACCESSIBILTY_PERMISSIONS", "Notification: Autotype failed, MacPass has no permission to send key strokes"); [NSApplication.sharedApplication hide:nil];
notification.actionButtonTitle = NSLocalizedString(@"OPEN_PREFERENCES", "Action button in Notification to show the Accessibilty preferences"); }
notification.userInfo = @{ MPUserNotificationTypeKey: MPUserNotificationTypeShowAccessibiltyPreferences }; if(environment.pid) {
notification.showsButtons = YES; [self _orderApplicationToFront:environment.pid completionHandler:nil];
[NSUserNotificationCenter.defaultUserNotificationCenter deliverNotification:notification]; }
return; }
}*/
NSInteger pid = NSProcessInfo.processInfo.processIdentifier; - (void)_runAutotypeAfterDatabaseUnlockWithEnvironment:(MPAutotypeEnvironment *)environment requestedAt:(NSTimeInterval)requestTime {
if(self.targetPID == pid) { NSTimeInterval now = NSDate.date.timeIntervalSinceReferenceDate;
return; // We do not perform Autotype on ourselves 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 */ /* find autotype documents */
@@ -233,20 +210,30 @@ static MPAutotypeDaemon *_sharedInstance;
/* No open document, inform the user and return without any action */ /* No open document, inform the user and return without any action */
if(documents.count == 0) { if(documents.count == 0) {
NSUserNotification *notification = [[NSUserNotification alloc] init]; NSUserNotification *notification = [[NSUserNotification alloc] init];
notification.title = NSApp.applicationName; notification.title = NSLocalizedString(@"AUTOTYPE_NOTIFICATION_NO_DOCUMENTS_TITLE", "Notification: Title for autotype feedback");
notification.informativeText = NSLocalizedString(@"AUTOTYPE_OVERLAY_NO_DOCUMENTS", "Notification: Autotype failed, no documents are open"); 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.actionButtonTitle = NSLocalizedString(@"OPEN_DOCUMENT", "Action button in Notification to open a document");
notification.userInfo = @{ MPUserNotificationTypeKey: MPUserNotificationTypeAutotypeOpenDocumentRequest }; notification.userInfo = @{ MPUserNotificationTypeKey: MPUserNotificationTypeAutotypeOpenDocumentRequest };
notification.showsButtons = YES; notification.showsButtons = YES;
[NSUserNotificationCenter.defaultUserNotificationCenter deliverNotification:notification]; [NSUserNotificationCenter.defaultUserNotificationCenter deliverNotification:notification];
self.userActionRequested = NSDate.date.timeIntervalSinceReferenceDate; NSNotificationCenter * __weak nc = [NSNotificationCenter defaultCenter];
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(_didUnlockDatabase:) name:MPDocumentDidUnlockDatabaseNotification object:nil]; 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 return; // Unlock should trigger autotype
} }
NSPredicate *filterPredicate = [NSPredicate predicateWithBlock:^BOOL(id _Nonnull evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) { NSPredicate *filterPredicate = [NSPredicate predicateWithBlock:^BOOL(id _Nonnull evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
MPDocument *document = evaluatedObject; MPDocument *document = evaluatedObject;
return !document.encrypted;}]; return !document.encrypted;
}];
NSArray *unlockedDocuments = [documents filteredArrayUsingPredicate:filterPredicate]; 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 */ /* 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) { if(unlockedDocuments.count == 0) {
@@ -257,68 +244,98 @@ static MPAutotypeDaemon *_sharedInstance;
[document showWindows]; [document showWindows];
MPDocumentWindowController *wc = document.windowControllers.firstObject; 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")]; [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 * __weak nc = [NSNotificationCenter defaultCenter];
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(_didUnlockDatabase:) name:MPDocumentDidUnlockDatabaseNotification object:nil]; 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 return; // wait for the unlock to happen
} }
MPAutotypeContext *context = [self _autotypeContextForDocuments:documents forWindowTitle:self.targetWindowTitle preferredEntry:entryOrNil]; MPAutotypeContext *context = [self _autotypeContextForDocuments:documents withEnvironment:env];
/* TODO: that's popping up if the mulit selection dialog goes up! */
if(self.matchSelectionWindow) { if(self.matchSelectionWindow) {
return; // we present the match selection window, just return return; // we present the match selection window, just return
} }
if(!entryOrNil) { if(!env.preferredEntry) {
NSUserNotification *notification = [[NSUserNotification alloc] init]; 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 }; notification.userInfo = @{ MPUserNotificationTypeKey: MPUserNotificationTypeAutotypeFeedback };
if(context) { 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 { 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]; [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 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 We do not care where this came form, just get the autotype commands
*/ */
NSMutableArray *autotypeCandidates = [[NSMutableArray alloc] init]; NSMutableArray *autotypeCandidates = [[NSMutableArray alloc] init];
for(MPDocument *document in documents) { for(MPDocument *document in documents) {
NSArray *contexts = [document autotypContextsForWindowTitle:windowTitle preferredEntry:entry]; NSArray *contexts = [document autotypContextsForWindowTitle:environment.windowTitle preferredEntry:environment.preferredEntry];
if(contexts ) { if(contexts ) {
[autotypeCandidates addObjectsFromArray:contexts]; [autotypeCandidates addObjectsFromArray:contexts];
} }
} }
NSUInteger candidates = autotypeCandidates.count;
if(candidates == 0) { if(autotypeCandidates.count <= 1) {
return nil;
}
if(candidates == 1 ) {
return autotypeCandidates.lastObject; return autotypeCandidates.lastObject;
} }
[self _presentSelectionWindow:autotypeCandidates]; [self _presentCandiadates:autotypeCandidates forEnvironment:environment];
return nil; // Nothing to do, we get called back by the window 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) { if(nil == context) {
return; // No context to work with return; // No context to work with
} }
__weak MPAutotypeDaemon *welf = self;
if([self _orderApplicationToFront:self.targetPID]) { BOOL appIsFrontmost = [self _orderApplicationToFront:environment.pid completionHandler:^{
/* Sleep a bit after the app was activated */ [welf _runAutotypeWithEnvironment:environment forContext:context];
/* 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); 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]) { 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 commands to main thread since most of them translate key events which is disallowed on background thread */
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
if(globalDelay > 0) {
usleep(globalDelay*NSEC_PER_USEC);
}
[command execute]; [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 { - (void)_presentCandiadates:(NSArray *)candidates forEnvironment:(MPAutotypeEnvironment *)environment {
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 {
if(!self.matchSelectionWindow) { if(!self.matchSelectionWindow) {
self.matchSelectionWindow = [[NSPanel alloc] initWithContentRect:NSMakeRect(0, 0, 100, 100) self.matchSelectionWindow = [[NSPanel alloc] initWithContentRect:NSMakeRect(0, 0, 100, 100)
styleMask:NSWindowStyleMaskNonactivatingPanel|NSWindowStyleMaskTitled styleMask:NSWindowStyleMaskNonactivatingPanel|NSWindowStyleMaskTitled
@@ -379,6 +369,7 @@ static MPAutotypeDaemon *_sharedInstance;
self.matchSelectionWindow.level = kCGAssistiveTechHighWindowLevel; self.matchSelectionWindow.level = kCGAssistiveTechHighWindowLevel;
MPAutotypeCandidateSelectionViewController *vc = [[MPAutotypeCandidateSelectionViewController alloc] init]; MPAutotypeCandidateSelectionViewController *vc = [[MPAutotypeCandidateSelectionViewController alloc] init];
vc.candidates = candidates; vc.candidates = candidates;
vc.environment = environment;
self.matchSelectionWindow.collectionBehavior |= (NSWindowCollectionBehaviorFullScreenAuxiliary | self.matchSelectionWindow.collectionBehavior |= (NSWindowCollectionBehaviorFullScreenAuxiliary |
NSWindowCollectionBehaviorMoveToActiveSpace | NSWindowCollectionBehaviorMoveToActiveSpace |
NSWindowCollectionBehaviorTransient ); NSWindowCollectionBehaviorTransient );
@@ -389,24 +380,6 @@ static MPAutotypeDaemon *_sharedInstance;
[self.matchSelectionWindow makeKeyAndOrderFront:self]; [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 -
#pragma mark NSApplication Notifications #pragma mark NSApplication Notifications
- (void)_didDeactivateApplication:(NSNotification *)notification { - (void)_didDeactivateApplication:(NSNotification *)notification {
@@ -416,29 +389,25 @@ static MPAutotypeDaemon *_sharedInstance;
#pragma mark - #pragma mark -
#pragma mark Application information #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 *runingApplication = [NSRunningApplication runningApplicationWithProcessIdentifier:processIdentifier];
NSRunningApplication *frontApplication = NSWorkspace.sharedWorkspace.frontmostApplication; NSRunningApplication *frontApplication = NSWorkspace.sharedWorkspace.frontmostApplication;
if(frontApplication.processIdentifier == processIdentifier) { 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]; [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 @end

View File

@@ -25,6 +25,7 @@
@interface MPAutotypeDelay : MPAutotypeCommand @interface MPAutotypeDelay : MPAutotypeCommand
@property (readonly) NSUInteger delay; @property (readonly) NSUInteger delay;
@property (readonly) BOOL isGlobal;
/** /**
* Creates an DelayCommand that delays the execution for n milliseconds * Creates an DelayCommand that delays the execution for n milliseconds
* *
@@ -33,5 +34,6 @@
* @return <#return value description#> * @return <#return value description#>
*/ */
- (instancetype)initWithDelay:(NSUInteger)delay; - (instancetype)initWithDelay:(NSUInteger)delay;
- (instancetype)initWithGlobalDelay:(NSUInteger)delay;
@end @end

View File

@@ -29,7 +29,7 @@
@implementation MPAutotypeDelay @implementation MPAutotypeDelay
- (id)init { - (id)init {
self = [self initWithDelay:0]; self = [self _initWithDelay:0 global:NO];
return self; return self;
} }
@@ -38,17 +38,32 @@
} }
- (instancetype)initWithDelay:(NSUInteger)delay { - (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]; self = [super init];
if(self) { if(self) {
_isGlobal = global;
/* Delays longer than a minute are a bit long */ /* Delays longer than a minute are a bit long */
_delay = MIN(60*1000,delay); _delay = MIN(60*NSEC_PER_USEC,delay);
} }
return self; return self;
} }
- (void)execute { - (void)execute {
/* milliseconds * 10000 = microseconds */ /* 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 @end

View 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
View 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

View 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

View 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

View 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

View 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

View File

@@ -281,7 +281,7 @@ static CGKeyCode kMPNumpadKeyCodes[] = {
static NSRegularExpression *delayRegExp; static NSRegularExpression *delayRegExp;
static dispatch_once_t onceToken; static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{ dispatch_once(&onceToken, ^{
NSString *delayPattern = [[NSString alloc] initWithFormat:@"\\{(%@|%@)[ |=]+([0-9]+)\\}", NSString *delayPattern = [[NSString alloc] initWithFormat:@"\\{(%@|%@)([ |=])+([0-9]+)\\}",
kKPKAutotypeDelay, kKPKAutotypeDelay,
kKPKAutotypeVirtualKey/*, kKPKAutotypeVirtualKey/*,
kKPKAutotypeVirtualExtendedKey, kKPKAutotypeVirtualExtendedKey,
@@ -327,9 +327,10 @@ static CGKeyCode kMPNumpadKeyCodes[] = {
// TODO: add {APPLICATION <appname>} // TODO: add {APPLICATION <appname>}
/* Delay */ /* Delay */
NSTextCheckingResult *result = [delayRegExp firstMatchInString:commandString options:0 range:NSMakeRange(0, commandString.length)]; 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 *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]; NSScanner *numberScanner = [[NSScanner alloc] initWithString:valueString];
NSInteger value; NSInteger value;
if([numberScanner scanInteger:&value]) { if([numberScanner scanInteger:&value]) {
@@ -337,7 +338,12 @@ static CGKeyCode kMPNumpadKeyCodes[] = {
if(MAX(0, value) <= 0) { if(MAX(0, value) <= 0) {
return; // Value too low, just skipp 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 return; // Done
} }
else if([kKPKAutotypeVirtualKey isEqualToString:uppercaseCommand]) { else if([kKPKAutotypeVirtualKey isEqualToString:uppercaseCommand]) {

View File

@@ -24,6 +24,12 @@
@interface MPContextButton : NSSegmentedControl @interface MPContextButton : NSSegmentedControl
typedef NS_ENUM(NSUInteger, MPContextButtonSegment) {
MPContextButtonSegmentButton,
MPContextButtonSegmentContextButton,
MPContextButtonSegmentCount // do not use
};
@property (nonatomic, strong) NSMenu *contextMenu; @property (nonatomic, strong) NSMenu *contextMenu;
- (void)setImage:(NSImage *)image; - (void)setImage:(NSImage *)image;

View File

@@ -53,14 +53,14 @@
self.focusRingType = NSFocusRingTypeNone; self.focusRingType = NSFocusRingTypeNone;
self.segmentStyle = NSSegmentStyleTexturedSquare; self.segmentStyle = NSSegmentStyleTexturedSquare;
self.segmentCount = 2; self.segmentCount = MPContextButtonSegmentCount;
cell.trackingMode = NSSegmentSwitchTrackingMomentary; cell.trackingMode = NSSegmentSwitchTrackingMomentary;
[cell setWidth:31 forSegment:0]; [cell setWidth:31 forSegment:MPContextButtonSegmentButton];
[cell setWidth:17 forSegment:1]; [cell setWidth:17 forSegment:MPContextButtonSegmentContextButton];
cell.trackingMode = NSSegmentSwitchTrackingMomentary; cell.trackingMode = NSSegmentSwitchTrackingMomentary;
NSImage *contextTriangle = [NSBundle.mainBundle imageForResource:@"contextTriangleTemplate"]; NSImage *contextTriangle = [NSBundle.mainBundle imageForResource:@"contextTriangleTemplate"];
[self setImage:contextTriangle forSegment:1]; [self setImage:contextTriangle forSegment:MPContextButtonSegmentContextButton];
cell.contextMenuAction = @selector(showContextMenu:); cell.contextMenuAction = @selector(showContextMenu:);
cell.contextMenuTarget = self; cell.contextMenuTarget = self;
@@ -76,42 +76,42 @@
Block the segment setter to prevent accidental settings Block the segment setter to prevent accidental settings
*/ */
- (void)setImage:(NSImage *)image forSegment:(NSInteger)segment { - (void)setImage:(NSImage *)image forSegment:(NSInteger)segment {
if(segment < 2) { if(segment < MPContextButtonSegmentCount) {
[super setImage:image forSegment:segment]; [super setImage:image forSegment:segment];
} }
} }
- (void)setSegmentCount:(NSInteger)count { - (void)setSegmentCount:(NSInteger)count {
if(count == 2) { if(count == MPContextButtonSegmentCount) {
super.segmentCount = count; super.segmentCount = count;
} }
} }
- (void)setImage:(NSImage *)image { - (void)setImage:(NSImage *)image {
[self setImage:image forSegment:0]; [self setImage:image forSegment:MPContextButtonSegmentButton];
} }
- (void)showContextMenu:(id)sender { - (void)showContextMenu:(id)sender {
NSPoint point = self.frame.origin; NSPoint point = self.frame.origin;
point.x = [self.cell widthForSegment:0]; point.x = [self.cell widthForSegment:MPContextButtonSegmentButton];
point.y = NSHeight(self.frame) + 3; point.y = NSHeight(self.frame) + 3;
[_contextMenu popUpMenuPositioningItem:nil atLocation:point inView:self]; [_contextMenu popUpMenuPositioningItem:nil atLocation:point inView:self];
} }
- (void)setControlSize:(NSControlSize)controlSize { - (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; CGFloat scale = rep.size.width / rep.size.height;
switch (controlSize) { switch (controlSize) {
case NSRegularControlSize: case NSRegularControlSize:
[self imageForSegment:0].size = NSMakeSize(16 * scale, 16); [self imageForSegment:MPContextButtonSegmentButton].size = NSMakeSize(16 * scale, 16);
break; break;
case NSSmallControlSize: case NSSmallControlSize:
[self imageForSegment:0].size = NSMakeSize(14 * scale, 14); [self imageForSegment:MPContextButtonSegmentButton].size = NSMakeSize(14 * scale, 14);
break; break;
case NSMiniControlSize: case NSMiniControlSize:
[self imageForSegment:0].size = NSMakeSize(8 * scale, 8); [self imageForSegment:MPContextButtonSegmentButton].size = NSMakeSize(8 * scale, 8);
default: default:
break; break;
@@ -123,4 +123,9 @@
return super.controlSize; return super.controlSize;
} }
- (void)_updateContextButtonState {
BOOL hasContextMenu = (self.contextMenu != nil);
[self setEnabled:hasContextMenu forSegment:MPContextButtonSegmentContextButton];
}
@end @end

View File

@@ -23,16 +23,17 @@
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
typedef NS_OPTIONS(NSUInteger, MPContextMenuItemsFlags) { typedef NS_OPTIONS(NSUInteger, MPContextMenuItemsFlags) {
MPContextMenuCreate = 1 << 0, MPContextMenuCreate = 1 << 0,
MPContextMenuDelete = 1 << 1, MPContextMenuDelete = 1 << 1,
MPContextMenuCopy = 1 << 2, MPContextMenuCopy = 1 << 2,
MPContextMenuTrash = 1 << 3, MPContextMenuTrash = 1 << 3,
MPContextMenuDuplicate = 1 << 4, MPContextMenuDuplicate = 1 << 4,
MPContextMenuAutotype = 1 << 5, MPContextMenuAutotype = 1 << 5,
MPContextMenuHistory = 1 << 6, MPContextMenuHistory = 1 << 6,
MPContextMenuMinimal = MPContextMenuCreate | MPContextMenuDelete, MPContextMenuShowGroupInOutline = 1 << 7,
MPContextMenuFull = MPContextMenuMinimal | MPContextMenuCopy | MPContextMenuDuplicate | MPContextMenuAutotype | MPContextMenuHistory, MPContextMenuMinimal = MPContextMenuCreate | MPContextMenuDelete | MPContextMenuDuplicate,
MPContextMenuExtended = MPContextMenuFull | MPContextMenuTrash MPContextMenuFull = MPContextMenuMinimal | MPContextMenuCopy | MPContextMenuDuplicate | MPContextMenuAutotype | MPContextMenuHistory,
MPContextMenuExtended = MPContextMenuFull | MPContextMenuTrash
}; };
@interface MPContextMenuHelper : NSTableCellView @interface MPContextMenuHelper : NSTableCellView

View File

@@ -42,6 +42,7 @@ static void MPContextmenuHelperBeginSection(NSMutableArray *items) {
BOOL const insertDuplicate = MPIsFlagSetInOptions(MPContextMenuDuplicate, flags); BOOL const insertDuplicate = MPIsFlagSetInOptions(MPContextMenuDuplicate, flags);
BOOL const insertAutotype = MPIsFlagSetInOptions(MPContextMenuAutotype, flags); BOOL const insertAutotype = MPIsFlagSetInOptions(MPContextMenuAutotype, flags);
BOOL const insertHistory = MPIsFlagSetInOptions(MPContextMenuHistory, flags); BOOL const insertHistory = MPIsFlagSetInOptions(MPContextMenuHistory, flags);
BOOL const insertShowGroupInOutline = MPIsFlagSetInOptions(MPContextMenuShowGroupInOutline, flags);
NSMutableArray *items = [NSMutableArray arrayWithCapacity:10]; NSMutableArray *items = [NSMutableArray arrayWithCapacity:10];
if(insertCreate) { 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.") 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] action:[MPActionHelper actionOfType:MPActionDuplicateEntryWithOptions]
keyEquivalent:@""]; keyEquivalent:@""];
NSMenuItem *duplicateGroup = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"DUPLICATE_GROUP", @"Menu item to directly diplicate a group")
action:[MPActionHelper actionOfType:MPActionDuplicateGroup]
keyEquivalent:@""];
[items addObjectsFromArray:@[ duplicateEntry, duplicateEntyWithOptions ]]; [items addObjectsFromArray:@[ duplicateEntry, duplicateEntyWithOptions, duplicateGroup ]];
} }
if(insertDelete || insertTrash) { if(insertDelete || insertTrash) {
@@ -113,7 +117,7 @@ static void MPContextmenuHelperBeginSection(NSMutableArray *items) {
[items addObjectsFromArray:@[ copyUsername, copyPassword, urlItem]]; [items addObjectsFromArray:@[ copyUsername, copyPassword, urlItem]];
} }
if(insertAutotype || insertHistory) { if(insertAutotype || insertHistory || insertShowGroupInOutline) {
MPContextmenuHelperBeginSection(items); MPContextmenuHelperBeginSection(items);
if(insertAutotype) { if(insertAutotype) {
NSMenuItem *performAutotype = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"PERFORM_AUTOTYPE_FOR_ENTRY", @"Menu item to perform autotype with the selected entry") 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); showHistory.keyEquivalentModifierMask = (showHistory.keyEquivalentModifierMask | NSCommandKeyMask | NSControlKeyMask);
[items addObject:showHistory]; [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; return items;

View File

@@ -115,7 +115,7 @@ typedef NS_ENUM(NSUInteger, MPDatePreset) {
default: default:
return; // Nothing to do; 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 @end

View File

@@ -53,7 +53,7 @@ NSString *const MPDocumentHideEntryHistoryNotification = @"MPDocumentHideEntryH
- (void)revertEntry:(KPKEntry *)entry toEntry:(KPKEntry *)historyEntry { - (void)revertEntry:(KPKEntry *)entry toEntry:(KPKEntry *)historyEntry {
[entry pushHistory]; [entry pushHistory];
[entry revertToEntry:historyEntry]; [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 @end

View File

@@ -64,7 +64,7 @@ NSString *const kMPDocumentSearchResultsKey = @"kMPDocumentSearchResul
MPDocument __weak *weakSelf = self; MPDocument __weak *weakSelf = self;
dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(backgroundQueue, ^{ dispatch_async(backgroundQueue, ^{
NSArray *results = [weakSelf _findEntriesMatchingCurrentSearch]; NSArray *results = [weakSelf _findEntriesMatchingSearch:weakSelf.searchContext];
dispatch_sync(dispatch_get_main_queue(), ^{ dispatch_sync(dispatch_get_main_queue(), ^{
[NSNotificationCenter.defaultCenter postNotificationName:MPDocumentDidChangeSearchResults object:weakSelf userInfo:@{ kMPDocumentSearchResultsKey: results }]; [NSNotificationCenter.defaultCenter postNotificationName:MPDocumentDidChangeSearchResults object:weakSelf userInfo:@{ kMPDocumentSearchResultsKey: results }];
}); });
@@ -128,9 +128,9 @@ NSString *const kMPDocumentSearchResultsKey = @"kMPDocumentSearchResul
} }
#pragma mark Search #pragma mark Search
- (NSArray *)_findEntriesMatchingCurrentSearch { - (NSArray *)_findEntriesMatchingSearch:(MPEntrySearchContext *)context {
/* Filter double passwords */ /* Filter double passwords */
if(MPIsFlagSetInOptions(MPEntrySearchDoublePasswords, self.searchContext.searchFlags)) { if(MPIsFlagSetInOptions(MPEntrySearchDoublePasswords, context.searchFlags)) {
NSMutableDictionary *passwordToEntryMap = [[NSMutableDictionary alloc] initWithCapacity:100]; NSMutableDictionary *passwordToEntryMap = [[NSMutableDictionary alloc] initWithCapacity:100];
/* Build up a usage map */ /* Build up a usage map */
for(KPKEntry *entry in self.root.searchableChildEntries) { for(KPKEntry *entry in self.root.searchableChildEntries) {
@@ -155,7 +155,7 @@ NSString *const kMPDocumentSearchResultsKey = @"kMPDocumentSearchResul
} }
return doublePasswords; return doublePasswords;
} }
if(MPIsFlagSetInOptions(MPEntrySearchExpiredEntries, self.searchContext.searchFlags)) { if(MPIsFlagSetInOptions(MPEntrySearchExpiredEntries, context.searchFlags)) {
NSPredicate *expiredPredicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) { NSPredicate *expiredPredicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
KPKNode *node = evaluatedObject; KPKNode *node = evaluatedObject;
return node.timeInfo.isExpired; return node.timeInfo.isExpired;
@@ -163,7 +163,7 @@ NSString *const kMPDocumentSearchResultsKey = @"kMPDocumentSearchResul
return [[self.root searchableChildEntries] filteredArrayUsingPredicate:expiredPredicate]; return [[self.root searchableChildEntries] filteredArrayUsingPredicate:expiredPredicate];
} }
/* Filter using predicates */ /* Filter using predicates */
NSArray *predicates = [self _filterPredicatesWithString:self.searchContext.searchString]; NSArray *predicates = [self _filterPredicatesWithString:context.searchString];
if(predicates) { if(predicates) {
NSPredicate *fullFilter = [NSCompoundPredicate orPredicateWithSubpredicates:predicates]; NSPredicate *fullFilter = [NSCompoundPredicate orPredicateWithSubpredicates:predicates];
return [[self.root searchableChildEntries] filteredArrayUsingPredicate:fullFilter]; return [[self.root searchableChildEntries] filteredArrayUsingPredicate:fullFilter];
@@ -194,7 +194,7 @@ NSString *const kMPDocumentSearchResultsKey = @"kMPDocumentSearchResul
[prediactes addObject:[NSPredicate predicateWithFormat:@"SELF.notes CONTAINS[cd] %@", string]]; [prediactes addObject:[NSPredicate predicateWithFormat:@"SELF.notes CONTAINS[cd] %@", string]];
} }
if(searchInAllAttributes) { 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]]; [prediactes addObject:[NSPredicate predicateWithFormat:@"SELF.uuid.UUIDString CONTAINS[cd] %@", string]];
NSPredicate *allAttributesPredicate = [NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) { NSPredicate *allAttributesPredicate = [NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {

View File

@@ -165,7 +165,6 @@ FOUNDATION_EXPORT NSString *const MPDocumentGroupKey;
- (void)deleteNode:(KPKNode *)node; - (void)deleteNode:(KPKNode *)node;
- (void)duplicateEntryWithOptions:(KPKCopyOptions)options; - (void)duplicateEntryWithOptions:(KPKCopyOptions)options;
#pragma mark Actions #pragma mark Actions
/** /**
* Empties the Trash group. Removing all Groups and Entries inside. This action is not undo-able * Empties the Trash group. Removing all Groups and Entries inside. This action is not undo-able
@@ -179,6 +178,7 @@ FOUNDATION_EXPORT NSString *const MPDocumentGroupKey;
*/ */
- (IBAction)createEntryFromTemplate:(id)sender; - (IBAction)createEntryFromTemplate:(id)sender;
- (IBAction)duplicateEntry:(id)sender; - (IBAction)duplicateEntry:(id)sender;
- (IBAction)duplicateGroup:(id)sender;
@end @end

View File

@@ -168,11 +168,19 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou
NSRecoveryAttempterErrorKey : recovery NSRecoveryAttempterErrorKey : recovery
}; };
if(outError != NULL) { if(outError != NULL) {
*outError = [NSError errorWithDomain:MPErrorDomain code:MPErrorNoPasswordOrKeyFile userInfo:userInfo]; *outError = [NSError errorWithDomain:MPDefaultErrorDomain code:MPErrorNoPasswordOrKeyFile userInfo:userInfo];
} }
return NO; 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 { - (NSData *)dataOfType:(NSString *)typeName error:(NSError * _Nullable __autoreleasing *)outError {
if(self.encrypted) { if(self.encrypted) {
NSLog(@"%@ should not be called on locked databases!", NSStringFromSelector(_cmd)); NSLog(@"%@ should not be called on locked databases!", NSStringFromSelector(_cmd));
@@ -181,7 +189,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou
if(!self.compositeKey.hasPasswordOrKeyFile) { if(!self.compositeKey.hasPasswordOrKeyFile) {
if(outError != NULL) { if(outError != NULL) {
NSDictionary *userInfo = @{ NSLocalizedDescriptionKey: NSLocalizedString(@"WARNING_ON_SAVE_NO_PASSWORD_OR_KEY_SET", "") }; 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 return nil; // Saving without a password/key is not possible
} }
@@ -190,7 +198,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou
if(format == KPKDatabaseFormatUnknown) { if(format == KPKDatabaseFormatUnknown) {
if(outError != NULL) { if(outError != NULL) {
NSDictionary *userInfo = @{ NSLocalizedDescriptionKey: NSLocalizedString(@"UNKNOWN_FILE_VERSION", "") }; 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! 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]; KPKEntry *duplicate = [entry copyWithTitle:nil options:options];
[duplicate addToGroup:entry.parent]; [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 #pragma mark Validation
@@ -886,6 +903,9 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou
valid &= targetEntries.count > 0; valid &= targetEntries.count > 0;
valid &= !self.historyEntry; valid &= !self.historyEntry;
break; break;
case MPActionDuplicateGroup:
valid &= targetGroups.count > 0;
break;
case MPActionEmptyTrash: case MPActionEmptyTrash:
valid &= (self.trash.groups.count + self.trash.entries.count) > 0; valid &= (self.trash.groups.count + self.trash.entries.count) > 0;
break; break;
@@ -915,6 +935,10 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou
case MPActionCopyAsReference: case MPActionCopyAsReference:
valid &= (nil != targetEntry); valid &= (nil != targetEntry);
break; break;
case MPActionShowGroupInOutline:
valid &= (nil != targetEntry);
valid &= self.hasSearch;
break;
default: default:
break; break;
} }

View File

@@ -31,7 +31,7 @@
@class MPOutlineViewController; @class MPOutlineViewController;
@class MPToolbarDelegate; @class MPToolbarDelegate;
@interface MPDocumentWindowController : NSWindowController @interface MPDocumentWindowController : NSWindowController <NSTouchBarDelegate>
@property (readonly, strong) MPPasswordInputController *passwordInputController; @property (readonly, strong) MPPasswordInputController *passwordInputController;
@property (readonly, strong) MPEntryViewController *entryViewController; @property (readonly, strong) MPEntryViewController *entryViewController;
@@ -39,8 +39,7 @@
@property (readonly, strong) MPInspectorViewController *inspectorViewController; @property (readonly, strong) MPInspectorViewController *inspectorViewController;
@property (readonly, strong) MPToolbarDelegate *toolbarDelegate; @property (readonly, strong) MPToolbarDelegate *toolbarDelegate;
#pragma mark Search @property (readonly, nonatomic, strong) NSSearchField *searchField;
- (NSSearchField *)searchField;
- (void)showEntries; - (void)showEntries;
- (void)showPasswordInput; - (void)showPasswordInput;
@@ -59,7 +58,8 @@
- (IBAction)exportAsXML:(id)sender; - (IBAction)exportAsXML:(id)sender;
- (IBAction)mergeWithOther:(id)sender; - (IBAction)mergeWithOther:(id)sender;
- (IBAction)importFromXML:(id)sender; - (IBAction)importFromXML:(id)sender;
- (IBAction)importFromPlugin:(id)sender; - (IBAction)importWithPlugin:(id)sender;
- (IBAction)exportWithPlugin:(id)sender;
- (IBAction)lock:(id)sender; - (IBAction)lock:(id)sender;
- (IBAction)createGroup:(id)sender; - (IBAction)createGroup:(id)sender;
@@ -67,11 +67,11 @@
- (IBAction)delete:(id)sender; - (IBAction)delete:(id)sender;
- (IBAction)duplicateEntryWithOptions:(id)sender; - (IBAction)duplicateEntryWithOptions:(id)sender;
- (IBAction)pickExpiryDate:(id)sender; - (IBAction)pickExpiryDate:(id)sender;
- (IBAction)performAutotypeForEntry:(id)sender; - (IBAction)performAutotypeForEntry:(id)sender;
- (IBAction)showGroupInOutline:(id)sender;
/* actions relayed to MPEntryViewController */ /* actions relayed to MPEntryViewController */
- (IBAction)copyUsername:(id)sender; - (IBAction)copyUsername:(id)sender;
- (IBAction)copyPassword:(id)sender; - (IBAction)copyPassword:(id)sender;

View File

@@ -39,6 +39,8 @@
#import "MPSettingsHelper.h" #import "MPSettingsHelper.h"
#import "MPToolbarDelegate.h" #import "MPToolbarDelegate.h"
#import "MPTitlebarColorAccessoryViewController.h" #import "MPTitlebarColorAccessoryViewController.h"
#import "MPTouchBarButtonCreator.h"
#import "MPIconHelper.h"
#import "MPPluginHost.h" #import "MPPluginHost.h"
#import "MPPlugin.h" #import "MPPlugin.h"
@@ -120,6 +122,11 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword);
self.toolbar = [[NSToolbar alloc] initWithIdentifier:@"MainWindowToolbar"]; self.toolbar = [[NSToolbar alloc] initWithIdentifier:@"MainWindowToolbar"];
self.toolbar.autosavesConfiguration = YES; self.toolbar.autosavesConfiguration = YES;
self.toolbar.allowsUserCustomization = 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.toolbar.delegate = self.toolbarDelegate;
self.window.toolbar = self.toolbar; self.window.toolbar = self.toolbar;
self.toolbarDelegate.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]) { if(![sender isKindOfClass:NSMenuItem.class]) {
return; return;
} }
NSMenuItem *menuItem = sender; NSMenuItem *menuItem = sender;
if(![menuItem.representedObject isKindOfClass:NSDictionary.class]) { if(![menuItem.representedObject isKindOfClass:NSString.class]) {
return; return;
} }
@@ -290,12 +297,39 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword);
if(!sheetWindow) { if(!sheetWindow) {
return; return;
} }
MPPlugin<MPImportPlugin> *importPlugin; NSString *bundleIdentifier = menuItem.representedObject;
MPPlugin<MPImportPlugin> *importPlugin = (MPPlugin<MPImportPlugin> *)[MPPluginHost.sharedHost pluginWithBundleIdentifier:bundleIdentifier];
NSOpenPanel *openPanel = NSOpenPanel.openPanel; NSOpenPanel *openPanel = NSOpenPanel.openPanel;
[importPlugin prepareOpenPanel:openPanel]; [importPlugin prepareOpenPanel:openPanel];
[openPanel beginSheetModalForWindow:sheetWindow completionHandler:^(NSModalResponse result) { [openPanel beginSheetModalForWindow:sheetWindow completionHandler:^(NSModalResponse result) {
KPKTree *importedTree = [importPlugin treeForRunningOpenPanel:openPanel withResponse:result]; if(result == NSModalResponseOK) {
[self.document importTree:importedTree]; 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)]; id<MPTargetNodeResolving> entryResolver = [NSApp targetForAction:@selector(currentTargetEntries)];
NSArray *entries = entryResolver.currentTargetEntries; NSArray *entries = entryResolver.currentTargetEntries;
if(entries.count == 1) { 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]; [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 -
#pragma mark Actions forwarded to MPEntryViewController #pragma mark Actions forwarded to MPEntryViewController
- (void)copyUsername:(id)sender { - (void)copyUsername:(id)sender {
@@ -652,4 +694,97 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword);
return (nil != inspectorView.superview); 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 @end

View File

@@ -23,7 +23,7 @@
#import <Foundation/Foundation.h> #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> @interface MPEntryContextMenuDelegate : NSObject <NSMenuDelegate>

View File

@@ -297,7 +297,7 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem { - (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
switch([MPActionHelper typeForAction:menuItem.action]) { switch([MPActionHelper typeForAction:menuItem.action]) {
case MPActionToggleQuicklook: { case MPActionToggleQuicklook: {
BOOL enabled = [[NSUserDefaults standardUserDefaults] boolForKey:kMPSettingsKeyEnableQuicklookPreview]; BOOL enabled = [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyEnableQuicklookPreview];
return enabled ? [self acceptsPreviewPanelControl:nil] : NO; return enabled ? [self acceptsPreviewPanelControl:nil] : NO;
case MPActionRemoveAttachment: case MPActionRemoveAttachment:
return !self.representedEntry.isHistory; return !self.representedEntry.isHistory;
@@ -323,16 +323,16 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
- (void)endPreviewPanelControl:(QLPreviewPanel *)panel { - (void)endPreviewPanelControl:(QLPreviewPanel *)panel {
MPTemporaryFileStorage *storage = (MPTemporaryFileStorage *)panel.dataSource; MPTemporaryFileStorage *storage = (MPTemporaryFileStorage *)panel.dataSource;
[[MPTemporaryFileStorageCenter defaultCenter] unregisterStorage:storage]; [MPTemporaryFileStorageCenter.defaultCenter unregisterStorage:storage];
} }
- (void)_updatePreviewItemForPanel:(QLPreviewPanel *)panel { - (void)_updatePreviewItemForPanel:(QLPreviewPanel *)panel {
NSInteger row = [self.attachmentTableView selectedRow]; NSInteger row = self.attachmentTableView.selectedRow;
NSAssert(row > -1, @"Row needs to be selected"); NSAssert(row > -1, @"Row needs to be selected");
KPKBinary *binary = self.representedEntry.binaries[row]; KPKBinary *binary = self.representedEntry.binaries[row];
MPTemporaryFileStorage *oldStorage = (MPTemporaryFileStorage *)panel.dataSource; MPTemporaryFileStorage *oldStorage = (MPTemporaryFileStorage *)panel.dataSource;
[[MPTemporaryFileStorageCenter defaultCenter] unregisterStorage:oldStorage]; [MPTemporaryFileStorageCenter.defaultCenter unregisterStorage:oldStorage];
panel.dataSource = [[MPTemporaryFileStorageCenter defaultCenter] storageForBinary:binary]; panel.dataSource = [MPTemporaryFileStorageCenter.defaultCenter storageForBinary:binary];
} }
#pragma mark - #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")]; NSMenu *customFieldMenu = [[NSMenu alloc] initWithTitle:NSLocalizedString(@"ADD_CUSTOM_FIELD_CONTEXT_MENU", @"Menu displayed for adding special custom keys")];
customFieldMenu.delegate = _addCustomFieldContextMenuDelegate; customFieldMenu.delegate = _addCustomFieldContextMenuDelegate;
self.addCustomFieldButton.contextMenu = customFieldMenu; self.addCustomFieldButton.contextMenu = customFieldMenu;
[self.addCustomFieldButton setEnabled:NO forSegment:MPContextButtonSegmentContextButton];
} }
#pragma mark - #pragma mark -

View File

@@ -602,7 +602,7 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
- (void)_setupEntryMenu { - (void)_setupEntryMenu {
NSMenu *menu = [[NSMenu alloc] init]; NSMenu *menu = [[NSMenu alloc] init];
NSArray *items = [MPContextMenuHelper contextMenuItemsWithItems:MPContextMenuFull]; NSArray *items = [MPContextMenuHelper contextMenuItemsWithItems:MPContextMenuFull|MPContextMenuShowGroupInOutline];
for(NSMenuItem *item in items) { for(NSMenuItem *item in items) {
[menu addItem:item]; [menu addItem:item];
} }
@@ -749,14 +749,14 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
} }
- (void)_columnDoubleClick:(id)sender { - (void)_columnDoubleClick:(id)sender {
if(0 == [[self.entryArrayController arrangedObjects] count]) { if(0 == [self.entryArrayController.arrangedObjects count]) {
return; // No data available return; // No data available
} }
NSInteger columnIndex = [self.entryTable clickedColumn]; NSInteger columnIndex = self.entryTable.clickedColumn;
if(columnIndex < 0 || columnIndex >= self.entryTable.tableColumns.count) { if(columnIndex < 0 || columnIndex >= self.entryTable.tableColumns.count) {
return; // No Column to use return; // No Column to use
} }
NSTableColumn *column = self.entryTable.tableColumns[self.entryTable.clickedColumn]; NSTableColumn *column = self.entryTable.tableColumns[columnIndex];
NSString *identifier = column.identifier; NSString *identifier = column.identifier;
if([identifier isEqualToString:MPEntryTableTitleColumnIdentifier]) { if([identifier isEqualToString:MPEntryTableTitleColumnIdentifier]) {
[self _executeTitleColumnDoubleClick]; [self _executeTitleColumnDoubleClick];
@@ -770,9 +770,17 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
else if([identifier isEqualToString:MPEntryTableURLColumnIdentifier]) { else if([identifier isEqualToString:MPEntryTableURLColumnIdentifier]) {
[self _executeURLColumnDoubleClick]; [self _executeURLColumnDoubleClick];
} }
else if([identifier isEqualToString:MPEntryTableParentColumnIdentifier]) {
[self _executeGroupColumnDoubleClick];
}
// TODO: Add more actions for new columns // TODO: Add more actions for new columns
} }
- (void)_executeGroupColumnDoubleClick {
id target = [NSApp targetForAction:@selector(showGroupInOutline:)];
[target showGroupInOutline:self];
}
- (void)_executeTitleColumnDoubleClick { - (void)_executeTitleColumnDoubleClick {
MPDoubleClickTitleAction action = [NSUserDefaults.standardUserDefaults integerForKey:kMPSettingsKeyDoubleClickTitleAction]; MPDoubleClickTitleAction action = [NSUserDefaults.standardUserDefaults integerForKey:kMPSettingsKeyDoubleClickTitleAction];
switch(action) { switch(action) {
@@ -800,4 +808,5 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
break; break;
} }
} }
@end @end

View File

@@ -22,7 +22,7 @@
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
@interface MPPluginTabelCellView : NSTableCellView @interface MPExtendedTableCellView : NSTableCellView
@property (strong) IBOutlet NSTextField *addionalTextField; @property (strong) IBOutlet NSTextField *addionalTextField;

View File

@@ -20,9 +20,9 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // 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 { - (void)setBackgroundStyle:(NSBackgroundStyle)backgroundStyle {
super.backgroundStyle = backgroundStyle; super.backgroundStyle = backgroundStyle;

View File

@@ -24,7 +24,7 @@
#import "MPViewController.h" #import "MPViewController.h"
#import "MPPreferencesTab.h" #import "MPPreferencesTab.h"
@interface MPGeneralSettingsController : MPViewController <MPPreferencesTab> @interface MPGeneralPreferencesController : MPViewController <MPPreferencesTab>
@property (strong) IBOutlet NSButton *clearPasteboardOnQuitCheckButton; @property (strong) IBOutlet NSButton *clearPasteboardOnQuitCheckButton;
@property (strong) IBOutlet NSPopUpButton *clearPasteboardTimeoutPopup; @property (strong) IBOutlet NSPopUpButton *clearPasteboardTimeoutPopup;
@@ -32,6 +32,7 @@
@property (strong) IBOutlet NSPopUpButton *idleTimeOutPopup; @property (strong) IBOutlet NSPopUpButton *idleTimeOutPopup;
@property (strong) IBOutlet NSButton *lockOnSleepCheckButton; @property (strong) IBOutlet NSButton *lockOnSleepCheckButton;
@property (strong) IBOutlet NSButton *lockOnLogoutCheckButton; @property (strong) IBOutlet NSButton *lockOnLogoutCheckButton;
@property (strong) IBOutlet NSButton *lockOnScreenSleepCheckButton;
@property (strong) IBOutlet NSButton *reopenLastDatabase; @property (strong) IBOutlet NSButton *reopenLastDatabase;
@property (strong) IBOutlet NSButton *enableAutosaveCheckButton; @property (strong) IBOutlet NSButton *enableAutosaveCheckButton;
@property (strong) IBOutlet NSButton *rememberKeyFileCheckButton; @property (strong) IBOutlet NSButton *rememberKeyFileCheckButton;

View File

@@ -20,20 +20,18 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
// //
#import "MPGeneralSettingsController.h" #import "MPGeneralPreferencesController.h"
#import "MPSettingsHelper.h" #import "MPSettingsHelper.h"
#import "MPIconHelper.h" #import "MPIconHelper.h"
NSString *const MPGeneralSetingsIdentifier = @"GeneralSettingsTab"; @implementation MPGeneralPreferencesController
@implementation MPGeneralSettingsController
- (NSString *)nibName { - (NSString *)nibName {
return @"GeneralSettings"; return @"GeneralPreferences";
} }
- (NSString *)identifier { - (NSString *)identifier {
return MPGeneralSetingsIdentifier; return @"GeneralPreferences";
} }
- (NSImage *)image { - (NSImage *)image {
@@ -41,7 +39,7 @@ NSString *const MPGeneralSetingsIdentifier = @"GeneralSettingsTab";
} }
- (NSString *)label { - (NSString *)label {
return NSLocalizedString(@"GENERAL_SETTINGS", @"General Settings Label"); return NSLocalizedString(@"GENERAL_PREFERENCES", @"General Settings Label");
} }
- (void)viewDidLoad { - (void)viewDidLoad {
@@ -52,6 +50,7 @@ NSString *const MPGeneralSetingsIdentifier = @"GeneralSettingsTab";
[self.preventUniversalClipboardSupportCheckButton bind:NSValueBinding toObject:defaultsController withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyPreventUniversalClipboard] options:nil]; [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.lockOnSleepCheckButton bind:NSValueBinding toObject:defaultsController withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyLockOnSleep] options:nil];
[self.lockOnLogoutCheckButton bind:NSValueBinding toObject:defaultsController withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingskeyLockOnLogout] 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.idleTimeOutPopup bind:NSSelectedTagBinding toObject:defaultsController withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyIdleLockTimeOut] options:nil];
[self.reopenLastDatabase bind:NSValueBinding toObject:defaultsController withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyReopenLastDatabaseOnLaunch] 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.enableAutosaveCheckButton bind:NSValueBinding toObject:defaultsController withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyEnableAutosave] options:nil];

View File

@@ -25,7 +25,7 @@
@class DDHotKeyTextField; @class DDHotKeyTextField;
@interface MPIntegrationSettingsController : MPViewController <MPPreferencesTab, NSTextFieldDelegate> @interface MPIntegrationPreferencesController : MPViewController <MPPreferencesTab, NSTextFieldDelegate>
/* Autotype */ /* Autotype */
@property (strong) IBOutlet NSButton *enableGlobalAutotypeCheckBox; @property (strong) IBOutlet NSButton *enableGlobalAutotypeCheckBox;
@property (strong) IBOutlet DDHotKeyTextField *hotKeyTextField; @property (strong) IBOutlet DDHotKeyTextField *hotKeyTextField;
@@ -44,6 +44,6 @@
/* Preview */ /* Preview */
@property (strong) IBOutlet NSButton *enableQuicklookCheckBox; @property (strong) IBOutlet NSButton *enableQuicklookCheckBox;
- (IBAction)openAccessibiltyPreferences:(id)sender; - (IBAction)runAutotypeDoctor:(id)sender;
@end @end

View File

@@ -20,25 +20,25 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
// //
#import "MPIntegrationSettingsController.h" #import "MPIntegrationPreferencesController.h"
#import "MPSettingsHelper.h" #import "MPSettingsHelper.h"
#import "MPIconHelper.h" #import "MPIconHelper.h"
#import "MPAutotypeDaemon.h" #import "MPAutotypeDoctor.h"
#import "DDHotKeyCenter.h" #import "DDHotKeyCenter.h"
#import "DDHotKey+MacPassAdditions.h" #import "DDHotKey+MacPassAdditions.h"
#import "DDHotKeyTextField.h" #import "DDHotKeyTextField.h"
@interface MPIntegrationSettingsController () @interface MPIntegrationPreferencesController ()
@property (nonatomic, strong) DDHotKey *hotKey; @property (nonatomic, strong) DDHotKey *hotKey;
@end @end
@implementation MPIntegrationSettingsController @implementation MPIntegrationPreferencesController
- (NSString *)nibName { - (NSString *)nibName {
return @"IntegrationSettings"; return @"IntegrationPreferences";
} }
- (NSString *)identifier { - (NSString *)identifier {
@@ -105,7 +105,8 @@
} }
- (void)_updateAccessabilityWarning { - (void)_updateAccessabilityWarning {
BOOL hasAutotypeSupport = MPAutotypeDaemon.defaultDaemon.autotypeSupported;
BOOL hasAutotypeSupport = MPAutotypeDoctor.defaultDoctor.hasNecessaryAutotypePermissions;
if(hasAutotypeSupport) { if(hasAutotypeSupport) {
[self.autotypeStackView setVisibilityPriority:NSStackViewVisibilityPriorityNotVisible forView:self.autotypeWarningTextField]; [self.autotypeStackView setVisibilityPriority:NSStackViewVisibilityPriorityNotVisible forView:self.autotypeWarningTextField];
@@ -117,7 +118,7 @@
} }
} }
- (void)openAccessibiltyPreferences:(id)sender { - (void)runAutotypeDoctor:(id)sender {
[MPAutotypeDaemon.defaultDaemon openAccessibiltyPreferences]; [MPAutotypeDoctor.defaultDoctor runChecksAndPresentResults];
} }
@end @end

View File

@@ -28,6 +28,7 @@
@property (nonatomic,assign) BOOL lockOnSleep; @property (nonatomic,assign) BOOL lockOnSleep;
@property (nonatomic,assign) BOOL lockOnLogout; @property (nonatomic,assign) BOOL lockOnLogout;
@property (nonatomic,assign) BOOL lockOnScreenSleep;
@property (nonatomic,assign) NSUInteger idleLockTime; @property (nonatomic,assign) NSUInteger idleLockTime;
@property (nonatomic,strong) id localEventHandler; @property (nonatomic,strong) id localEventHandler;
@property (nonatomic,strong) NSTimer *idleCheckTimer; @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(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(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(lockOnLogout)) toObject:defaultsController withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingskeyLockOnLogout] options:nil];
[self bind:NSStringFromSelector(@selector(lockOnScreenSleep)) toObject:defaultsController withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingskeyLockOnScreenSleep] options:nil];
} }
return self; 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 { - (void)setIdleLockTime:(NSUInteger)idleLockTime {
if(_idleLockTime != idleLockTime) { if(_idleLockTime != idleLockTime) {
_idleLockTime = idleLockTime; _idleLockTime = idleLockTime;
@@ -113,6 +127,9 @@ static MPLockDaemon *_sharedInstance;
- (void)_willSleepNotification:(NSNotification *)notification { - (void)_willSleepNotification:(NSNotification *)notification {
[((MPAppDelegate *)NSApp.delegate) lockAllDocuments]; [((MPAppDelegate *)NSApp.delegate) lockAllDocuments];
} }
- (void)_willScreenSleepNotification:(NSNotification *)notification {
[((MPAppDelegate *)NSApp.delegate) lockAllDocuments];
}
- (void)_checkIdleTime:(NSTimer *)timer { - (void)_checkIdleTime:(NSTimer *)timer {
if(timer != self.idleCheckTimer) { if(timer != self.idleCheckTimer) {

View File

@@ -57,7 +57,7 @@ NSString *const _MPOutlineMenuTemplate = @"Template";
if( [item isKindOfClass:KPKGroup.class]) { if( [item isKindOfClass:KPKGroup.class]) {
KPKGroup *group = (KPKGroup *)item; KPKGroup *group = (KPKGroup *)item;
MPDocument *document = [NSDocumentController sharedDocumentController].currentDocument; MPDocument *document = NSDocumentController.sharedDocumentController.currentDocument;
if(group && document.root == group ) { if(group && document.root == group ) {
} }

View File

@@ -26,12 +26,14 @@
APPKIT_EXTERN NSString *const MPOutlineViewDidChangeGroupSelection; APPKIT_EXTERN NSString *const MPOutlineViewDidChangeGroupSelection;
@class MPDocument; @class MPDocument;
@class KPKGroup;
@interface MPOutlineViewController : MPViewController <MPTargetNodeResolving, NSOutlineViewDelegate, NSMenuDelegate> @interface MPOutlineViewController : MPViewController <MPTargetNodeResolving, NSOutlineViewDelegate, NSMenuDelegate>
- (void)clearSelection; - (void)clearSelection;
- (void)showOutline; - (void)showOutline;
- (void)registerNotificationsForDocument:(MPDocument *)document; - (void)registerNotificationsForDocument:(MPDocument *)document;
- (void)selectGroup:(KPKGroup *)group;
/** /**
* Retrieves the current item for the current mouse location * Retrieves the current item for the current mouse location

View File

@@ -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 { - (void)_expandItems:(NSTreeNode *)node {
id nodeItem = node.representedObject; id nodeItem = node.representedObject;
if([nodeItem isKindOfClass:KPKTree.class]) { if([nodeItem isKindOfClass:KPKTree.class]) {

View File

@@ -60,10 +60,14 @@
self.window.alphaValue = 0; self.window.alphaValue = 0;
self.window.opaque = NO; self.window.opaque = NO;
self.window.hasShadow = YES; self.window.hasShadow = YES;
self.window.backgroundColor = NSColor.clearColor;
self.textField.cell.backgroundStyle = NSBackgroundStyleLowered; self.textField.cell.backgroundStyle = NSBackgroundStyleLowered;
self.imageView.cell.backgroundStyle = NSBackgroundStyleDark; self.imageView.cell.backgroundStyle = NSBackgroundStyleEmphasized;
((NSImageCell *)self.imageView.cell).imageAlignment = NSImageAlignCenter; ((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 { - (void)displayOverlayImage:(NSImage *)imageOrNil label:(NSString *)labelOrNil atView:(NSView *)view {

View File

@@ -24,7 +24,7 @@
@class KPKCompositeKey; @class KPKCompositeKey;
@interface MPPasswordInputController : MPViewController @interface MPPasswordInputController : MPViewController <NSTouchBarDelegate>
typedef BOOL (^passwordInputCompletionBlock)(NSString *password, NSURL *keyURL, BOOL didCancel, NSError *__autoreleasing*error); typedef BOOL (^passwordInputCompletionBlock)(NSString *password, NSURL *keyURL, BOOL didCancel, NSError *__autoreleasing*error);

View File

@@ -26,6 +26,7 @@
#import "MPDocument.h" #import "MPDocument.h"
#import "MPSettingsHelper.h" #import "MPSettingsHelper.h"
#import "MPPathControl.h" #import "MPPathControl.h"
#import "MPTouchBarButtonCreator.h"
#import "HNHUi/HNHUi.h" #import "HNHUi/HNHUi.h"
@@ -33,10 +34,12 @@
@interface MPPasswordInputController () @interface MPPasswordInputController ()
@property (strong) NSButton *showPasswordButton;
@property (weak) IBOutlet HNHUISecureTextField *passwordTextField; @property (weak) IBOutlet HNHUISecureTextField *passwordTextField;
@property (weak) IBOutlet MPPathControl *keyPathControl; @property (weak) IBOutlet MPPathControl *keyPathControl;
@property (weak) IBOutlet NSImageView *messageImageView; @property (weak) IBOutlet NSImageView *messageImageView;
@property (weak) IBOutlet NSTextField *messageInfoTextField; @property (weak) IBOutlet NSTextField *messageInfoTextField;
@property (strong) IBOutlet NSTextField *keyFileWarningTextField;
@property (weak) IBOutlet NSButton *togglePasswordButton; @property (weak) IBOutlet NSButton *togglePasswordButton;
@property (weak) IBOutlet NSButton *enablePasswordCheckBox; @property (weak) IBOutlet NSButton *enablePasswordCheckBox;
@property (weak) IBOutlet NSButton *unlockButton; @property (weak) IBOutlet NSButton *unlockButton;
@@ -48,6 +51,7 @@
@property (assign) BOOL showPassword; @property (assign) BOOL showPassword;
@property (nonatomic, assign) BOOL enablePassword; @property (nonatomic, assign) BOOL enablePassword;
@property (copy) passwordInputCompletionBlock completionHandler; @property (copy) passwordInputCompletionBlock completionHandler;
@end @end
@implementation MPPasswordInputController @implementation MPPasswordInputController
@@ -70,6 +74,7 @@
} }
- (void)viewDidLoad { - (void)viewDidLoad {
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(_didSetKeyURL:) name:MPPathControlDidSetURLNotification object:self.keyPathControl];
self.messageImageView.image = [NSImage imageNamed:NSImageNameCaution]; self.messageImageView.image = [NSImage imageNamed:NSImageNameCaution];
[self.passwordTextField bind:NSStringFromSelector(@selector(showPassword)) toObject:self withKeyPath:NSStringFromSelector(@selector(showPassword)) options:nil]; [self.passwordTextField bind:NSStringFromSelector(@selector(showPassword)) toObject:self withKeyPath:NSStringFromSelector(@selector(showPassword)) options:nil];
[self.togglePasswordButton bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(showPassword)) options:nil]; [self.togglePasswordButton bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(showPassword)) options:nil];
@@ -106,7 +111,7 @@
self.passwordTextField.placeholderString = NSLocalizedString(@"PASSWORD_INPUT_ENTER_PASSWORD", "Placeholder in the unlock-password input field if password is enabled"); self.passwordTextField.placeholderString = NSLocalizedString(@"PASSWORD_INPUT_ENTER_PASSWORD", "Placeholder in the unlock-password input field if password is enabled");
} }
else { 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; 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 @end

View File

@@ -58,6 +58,18 @@ FOUNDATION_EXPORT NSString *const MPPasteBoardControllerDidClearClipboard;
- (void)copyObjects:(NSArray<id<NSPasteboardWriting>> *)objects; - (void)copyObjects:(NSArray<id<NSPasteboardWriting>> *)objects;
- (void)copyObjectsWithoutTimeout:(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; - (void)copyObjects:(NSArray<id<NSPasteboardWriting>> *)objects overlayInfo:(MPPasteboardOverlayInfoType)overlayInfoType name:(NSString *)name atView:(NSView *)view;
@end @end

View File

@@ -71,7 +71,7 @@ NSString *const MPPasteBoardControllerDidClearClipboard = @"com.hicknhack.macpas
- (void)stashObjects { - (void)stashObjects {
self.stashedObjects = [NSMutableArray array]; self.stashedObjects = [NSMutableArray array];
for (NSPasteboardItem *item in NSPasteboard.generalPasteboard.pasteboardItems) { for(NSPasteboardItem *item in NSPasteboard.generalPasteboard.pasteboardItems) {
NSPasteboardItem *newItem = [[NSPasteboardItem alloc] init]; NSPasteboardItem *newItem = [[NSPasteboardItem alloc] init];
for (NSString *type in item.types) { for (NSString *type in item.types) {
/* mutable copy to ensure actual deep copy */ /* mutable copy to ensure actual deep copy */
@@ -85,7 +85,7 @@ NSString *const MPPasteBoardControllerDidClearClipboard = @"com.hicknhack.macpas
} }
- (void)restoreObjects { - (void)restoreObjects {
if (self.stashedObjects) { if(self.stashedObjects) {
[NSPasteboard.generalPasteboard clearContents]; [NSPasteboard.generalPasteboard clearContents];
[NSPasteboard.generalPasteboard writeObjects:self.stashedObjects]; [NSPasteboard.generalPasteboard writeObjects:self.stashedObjects];
self.stashedObjects = nil; self.stashedObjects = nil;
@@ -151,6 +151,13 @@ NSString *const MPPasteBoardControllerDidClearClipboard = @"com.hicknhack.macpas
} }
[MPOverlayWindowController.sharedController displayOverlayImage:infoImage label:infoText atView:view]; [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 { - (void)_clearPasteboardContents {

17
MacPass/MPPathCell.h Normal file
View 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
View 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

View 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

View File

@@ -10,6 +10,8 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
APPKIT_EXTERN NSString *const MPPathControlDidSetURLNotification;
@interface MPPathControl : NSPathControl <NSPathControlDelegate> @interface MPPathControl : NSPathControl <NSPathControlDelegate>
- (IBAction)showOpenPanel:(id _Nullable)sender; - (IBAction)showOpenPanel:(id _Nullable)sender;

View File

@@ -7,30 +7,54 @@
// //
#import "MPPathControl.h" #import "MPPathControl.h"
#import "MPPathControl+Private.h"
#import "MPPathCell.h"
NSString *const MPPathControlDidSetURLNotification = @"MPPathControlDidSetURLNotification";
@implementation MPPathControl @implementation MPPathControl
/*- (BOOL)canBecomeKeyView { + (Class)cellClass{
return MPPathCell.class;
}
- (BOOL)canBecomeKeyView {
return YES; return YES;
} }
- (BOOL)acceptsFirstResponder { - (BOOL)acceptsFirstResponder {
return YES; /*
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 { - (instancetype)initWithFrame:(NSRect)frameRect {
self = [super initWithFrame:frameRect]; self = [super initWithFrame:frameRect];
self.delegate = self; self.delegate = self;
[self _setupCell];
return self; return self;
} }
- (instancetype)initWithCoder:(NSCoder *)coder { - (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 = [super initWithCoder:coder];
self.delegate = self; self.delegate = self;
[self _setupCell];
return self; 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 { - (void)willOpenMenu:(NSMenu *)menu withEvent:(NSEvent *)event {
if(!self.URL) { if(!self.URL) {
[menu cancelTracking]; [menu cancelTracking];
@@ -56,7 +80,7 @@
return; return;
} }
if(@available(macOS 10.11, *)) { if(@available(macOS 10.11, *)) {
NSLog(@"Skipping 10.10 pathControl:willPopUpMenu"); // skip
} }
else { else {
if(!self.URL) { if(!self.URL) {
@@ -75,4 +99,8 @@
openPanel.prompt = NSLocalizedString(@"CHOOSE_FILE_BUTTON_TITLE", @"Button title in the key file selection dialog for selecting a key"); 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 @end

View File

@@ -30,6 +30,7 @@ NS_ASSUME_NONNULL_BEGIN
@class KPKTree; @class KPKTree;
FOUNDATION_EXPORT NSString *const MPPluginUnkownVersion; FOUNDATION_EXPORT NSString *const MPPluginUnkownVersion;
FOUNDATION_EXPORT NSString *const MPPluginDescriptionInfoDictionaryKey;
@interface MPPlugin : NSObject @interface MPPlugin : NSObject
@@ -37,8 +38,10 @@ FOUNDATION_EXPORT NSString *const MPPluginUnkownVersion;
@property (copy, readonly) NSString *name; @property (copy, readonly) NSString *name;
@property (nonatomic, copy, readonly, nullable) NSString *shortVersionString; @property (nonatomic, copy, readonly, nullable) NSString *shortVersionString;
@property (nonatomic, copy, readonly) NSString *versionString; @property (nonatomic, copy, readonly) NSString *versionString;
@property (nonatomic, copy, readonly) NSString *localizedDescription;
@property (nonatomic, strong, readonly) NSBundle *bundle; @property (nonatomic, strong, readonly) NSBundle *bundle;
/** /**
If your plugin needs initalization override this method but you have to call [super initWithPluginHost:] If your plugin needs initalization override this method but you have to call [super initWithPluginHost:]
Otherwise your plugin might not get registered correctly Otherwise your plugin might not get registered correctly
@@ -53,6 +56,13 @@ FOUNDATION_EXPORT NSString *const MPPluginUnkownVersion;
@end @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> @protocol MPPluginSettings <NSObject>
@required @required
@@ -60,6 +70,20 @@ FOUNDATION_EXPORT NSString *const MPPluginUnkownVersion;
@end @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. Adopt this protocoll if your plugin supports actions on entries.
Actions will get listed in various places in menues. 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. This will get called when the open panel is closed by the user.
You should retrieve any results from the panel and act accordingly. 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 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 KPKTree constructed from the selected input file(s)
@return The tree constructed from the selected input file(s)
*/ */
- (KPKTree *)treeForRunningOpenPanel:(NSOpenPanel *)panel withResponse:(NSModalResponse)response; - (nullable KPKTree *)treeForRunningOpenPanel:(NSOpenPanel *)panel;
@end @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) @interface MPPlugin (Deprecated)
- (instancetype)initWithPluginManager:(id)manager; - (instancetype)initWithPluginManager:(id)manager;

View File

@@ -28,6 +28,7 @@
#import "MPPluginVersionComparator.h" #import "MPPluginVersionComparator.h"
NSString *const MPPluginUnkownVersion = @"unkown.plugin.version"; NSString *const MPPluginUnkownVersion = @"unkown.plugin.version";
NSString *const MPPluginDescriptionInfoDictionaryKey = @"MPPluginDescription";
@implementation MPPlugin @implementation MPPlugin
@@ -90,6 +91,16 @@ NSString *const MPPluginUnkownVersion = @"unkown.plugin.version";
return MPPluginUnkownVersion; 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 { - (void)didLoadPlugin {

View File

@@ -32,6 +32,8 @@ FOUNDATION_EXPORT NSString *const MPPluginHostPluginBundleIdentifiyerKey;
@class MPPlugin; @class MPPlugin;
@class KPKEntry; @class KPKEntry;
@protocol MPImportPlugin; @protocol MPImportPlugin;
@protocol MPExportPlugin;
@protocol MPAutotypeWindowTitleResolverPlugin;
@interface MPPluginHost : NSObject @interface MPPluginHost : NSObject
@@ -52,8 +54,15 @@ FOUNDATION_EXPORT NSString *const MPPluginHostPluginBundleIdentifiyerKey;
- (NSArray *)avilableMenuItemsForEntries:(NSArray <KPKEntry *>*)entries; - (NSArray *)avilableMenuItemsForEntries:(NSArray <KPKEntry *>*)entries;
@end @end
@interface MPPluginHost (MPImportPluginSupport) @interface MPPluginHost (MPImportExportPluginSupport)
@property (readonly, copy) NSArray <MPPlugin<MPImportPlugin> __kindof*> *importPlugins; @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 @end

View File

@@ -282,7 +282,7 @@ NSString *const MPPluginHostPluginBundleIdentifiyerKey = @"MPPluginHostPluginBun
} }
} }
if(incompatiblePlugins.count > 0) { if(incompatiblePlugins.count > 0) {
BOOL hideAlert = NO; BOOL hideAlert = NSApplication.sharedApplication.isRunningTests ? YES : NO;
if(nil != [NSUserDefaults.standardUserDefaults objectForKey:kMPSettingsKeyHideIncopatiblePluginsWarning]) { if(nil != [NSUserDefaults.standardUserDefaults objectForKey:kMPSettingsKeyHideIncopatiblePluginsWarning]) {
hideAlert = [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyHideIncopatiblePluginsWarning]; hideAlert = [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyHideIncopatiblePluginsWarning];
} }
@@ -447,18 +447,41 @@ NSString *const MPPluginHostPluginBundleIdentifiyerKey = @"MPPluginHostPluginBun
[context.plugin performActionForMenuItem:item withEntries:context.entries]; [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 @end
NSString *const MPPluginBundleIdentifierKey = @"MPPluginBundleIdentifierKey"; NSString *const MPPluginBundleIdentifierKey = @"MPPluginBundleIdentifierKey";
NSString *const MPImportPluginUTIKey = @"MPImportPluginUTIKey"; NSString *const MPImportPluginUTIKey = @"MPImportPluginUTIKey";
@implementation MPPluginHost (MPImportPluginSupport) @implementation MPPluginHost (MPImportExportPluginSupport)
- (NSArray<MPPlugin *> *)importPlugins { - (NSArray<MPPlugin *> *)importPlugins {
NSPredicate *filterPredicate = [NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) { return [self _pluginsConformingToProtocoll:@protocol(MPImportPlugin)];
return ([evaluatedObject conformsToProtocol:@protocol(MPImportPlugin)]);
}];
return [self.mutablePlugins filteredArrayUsingPredicate:filterPredicate];
} }
- (NSArray<MPPlugin<MPImportPlugin> *> *)exportPlugins {
return [self _pluginsConformingToProtocoll:@protocol(MPExportPlugin)];
}
@end @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

View File

@@ -21,7 +21,7 @@
// //
#import "MPPluginPreferencesController.h" #import "MPPluginPreferencesController.h"
#import "MPPluginTabelCellView.h" #import "MPExtendedTableCellView.h"
#import "MPPluginHost.h" #import "MPPluginHost.h"
#import "MPPlugin.h" #import "MPPlugin.h"
#import "MPPlugin_Private.h" #import "MPPlugin_Private.h"
@@ -42,6 +42,7 @@ typedef NS_ENUM(NSUInteger, MPPluginSegmentType) {
@interface MPPluginPreferencesController () <NSTableViewDataSource, NSTableViewDelegate> @interface MPPluginPreferencesController () <NSTableViewDataSource, NSTableViewDelegate>
@property (strong) IBOutlet NSButton *allowRemoteConnectionCheckButton;
@property (strong) IBOutlet NSTableView *pluginTableView; @property (strong) IBOutlet NSTableView *pluginTableView;
@property (strong) IBOutlet NSView *settingsView; @property (strong) IBOutlet NSView *settingsView;
@property (strong) IBOutlet NSView *fallbackSettingsView; @property (strong) IBOutlet NSView *fallbackSettingsView;
@@ -83,6 +84,10 @@ typedef NS_ENUM(NSUInteger, MPPluginSegmentType) {
toObject:NSUserDefaultsController.sharedUserDefaultsController toObject:NSUserDefaultsController.sharedUserDefaultsController
withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyLoadIncompatiblePlugins] withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyLoadIncompatiblePlugins]
options:nil]; options:nil];
[self.allowRemoteConnectionCheckButton bind:NSValueBinding
toObject:NSUserDefaultsController.sharedUserDefaultsController
withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyAllowRemoteFetchOfPluginRepository]
options:nil];
[self.pluginTableView registerForDraggedTypes:@[(NSString *)kUTTypeFileURL]]; [self.pluginTableView registerForDraggedTypes:@[(NSString *)kUTTypeFileURL]];
} }
@@ -93,7 +98,7 @@ typedef NS_ENUM(NSUInteger, MPPluginSegmentType) {
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { - (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
MPPlugin *plugin = [self pluginForRow: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) { if(plugin.enabled) {
view.textField.stringValue = plugin.name; 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:@"H:|[view]|" options:0 metrics:nil views:dict]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[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) { 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) { if(plugin.errorMessage.length > 0) {
self.fallbackDescriptionTextField.stringValue = plugin.errorMessage; [self _showInfoMessageForPlugin:plugin.errorMessage];
} }
else { 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 { - (MPPlugin *)pluginForRow:(NSInteger)row {
NSArray<MPPlugin __kindof *> *plugins = [MPPluginHost sharedHost].plugins; NSArray<MPPlugin __kindof *> *plugins = [MPPluginHost sharedHost].plugins;
if(0 > row || row >= plugins.count) { if(0 > row || row >= plugins.count) {

View File

@@ -23,6 +23,7 @@
#import "MPPluginRepository.h" #import "MPPluginRepository.h"
#import "MPConstants.h" #import "MPConstants.h"
#import "MPPluginRepositoryItem.h" #import "MPPluginRepositoryItem.h"
#import "MPSettingsHelper.h"
NSString *const MPPluginRepositoryDidUpdateAvailablePluginsNotification = @"com.hicknhack.macpass.MPPluginRepositoryDidInitializeAvailablePluginsNotification"; NSString *const MPPluginRepositoryDidUpdateAvailablePluginsNotification = @"com.hicknhack.macpass.MPPluginRepositoryDidInitializeAvailablePluginsNotification";
@@ -56,7 +57,7 @@ NSString *const MPPluginRepositoryDidUpdateAvailablePluginsNotification = @"com.
if(self) { if(self) {
_isInitialized = NO; _isInitialized = NO;
_lastDataFetchTime = NSDate.distantPast.timeIntervalSinceReferenceDate; _lastDataFetchTime = NSDate.distantPast.timeIntervalSinceReferenceDate;
[self fetchRepositoryDataCompletionHandler:^(NSArray<MPPluginRepositoryItem *> * _Nonnull availablePlugins) { [self _fetchAppropriateRepositoryDataCompletionHandler:^(NSArray<MPPluginRepositoryItem *> * _Nonnull availablePlugins) {
self.availablePlugins = availablePlugins; self.availablePlugins = availablePlugins;
self.isInitialized = YES; self.isInitialized = YES;
}]; }];
@@ -65,10 +66,12 @@ NSString *const MPPluginRepositoryDidUpdateAvailablePluginsNotification = @"com.
} }
- (NSArray<MPPluginRepositoryItem *> *)availablePlugins { - (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 ) { if((NSDate.timeIntervalSinceReferenceDate - self.lastDataFetchTime) > 60*5 ) {
NSLog(@"%@: updating available plugins cache.", self.className); NSLog(@"%@: updating available plugins cache.", self.className);
[self fetchRepositoryDataCompletionHandler:^(NSArray<MPPluginRepositoryItem *> * _Nonnull availablePlugins) { [self _fetchAppropriateRepositoryDataCompletionHandler:^(NSArray<MPPluginRepositoryItem *> * _Nonnull availablePlugins) {
self.availablePlugins = 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]; NSString *urlString = NSBundle.mainBundle.infoDictionary[MPBundlePluginRepositoryURLKey];
if(!urlString) { if(!urlString) {
if(completionHandler) { [self _fetchLocalFallbackRepositoryData:completionHandler];
completionHandler(@[]);
}
return; return;
} }
NSURL *jsonURL = [NSURL URLWithString:urlString]; NSURL *jsonURL = [NSURL URLWithString:urlString];
if(!jsonURL) { if(!jsonURL) {
if(completionHandler) { [self _fetchLocalFallbackRepositoryData:completionHandler];
completionHandler(@[]);
}
return; return;
} }
NSURLSessionTask *downloadTask = [NSURLSession.sharedSession dataTaskWithURL:jsonURL completionHandler:^(NSData * _Nullable jsonData, NSURLResponse * _Nullable response, NSError * _Nullable error) { NSURLSessionTask *downloadTask = [NSURLSession.sharedSession dataTaskWithURL:jsonURL completionHandler:^(NSData * _Nullable jsonData, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if(![response isKindOfClass:NSHTTPURLResponse.class]) { if(![response isKindOfClass:NSHTTPURLResponse.class]) {
if(completionHandler) { [self _fetchLocalFallbackRepositoryData:completionHandler];
completionHandler(@[]);
}
return; return;
} }
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if(httpResponse.statusCode != 200 || jsonData.length == 0) { if(httpResponse.statusCode != 200 || jsonData.length == 0) {
if(completionHandler) { [self _fetchLocalFallbackRepositoryData:completionHandler];
completionHandler(@[]);
}
return; return;
} }
id jsonRoot = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
if(!jsonRoot || ![jsonRoot isKindOfClass:NSArray.class]) { NSArray *items = [self _parseJSONData:jsonData];
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];
}
}
if(completionHandler) { if(completionHandler) {
completionHandler([items copy]); completionHandler([items copy]);
} }
}]; }];
[downloadTask resume]; [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 @end

View File

@@ -13,6 +13,7 @@
#import "MPPluginRepositoryItem.h" #import "MPPluginRepositoryItem.h"
#import "MPPluginVersionComparator.h" #import "MPPluginVersionComparator.h"
#import "MPPluginStatusTableCellView.h" #import "MPPluginStatusTableCellView.h"
#import "MPSettingsHelper.h"
typedef NS_ENUM(NSUInteger, MPPluginTableColumn) { typedef NS_ENUM(NSUInteger, MPPluginTableColumn) {
@@ -39,7 +40,13 @@ typedef NS_ENUM(NSUInteger, MPPluginTableColumn) {
- (void)viewDidLoad { - (void)viewDidLoad {
[super viewDidLoad]; [super viewDidLoad];
self.downloadedItems = [[NSMutableSet alloc] init]; 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]; [self _refreshRepository];
} }

View File

@@ -24,10 +24,10 @@
#import "MPPreferencesTab.h" #import "MPPreferencesTab.h"
#import "MPGeneralSettingsController.h" #import "MPGeneralPreferencesController.h"
#import "MPIntegrationSettingsController.h" #import "MPIntegrationPreferencesController.h"
#import "MPWorkflowSettingsController.h" #import "MPWorkflowPreferencesController.h"
#import "MPUpdateSettingsController.h" #import "MPUpdatePreferencesController.h"
#import "MPPluginPreferencesController.h" #import "MPPluginPreferencesController.h"
@interface MPPreferencesWindowController () { @interface MPPreferencesWindowController () {
@@ -121,14 +121,14 @@
tabClass = MPPluginPreferencesController.class; tabClass = MPPluginPreferencesController.class;
break; break;
case MPPreferencesTabUpdate: case MPPreferencesTabUpdate:
tabClass = MPUpdateSettingsController.class; tabClass = MPUpdatePreferencesController.class;
break; break;
case MPPreferencesTabWorkflow: case MPPreferencesTabWorkflow:
tabClass = MPWorkflowSettingsController.class; tabClass = MPWorkflowPreferencesController.class;
break; break;
case MPPreferencesTabGeneral: case MPPreferencesTabGeneral:
default: default:
tabClass = MPGeneralSettingsController.class; tabClass = MPGeneralPreferencesController.class;
break; break;
} }
NSString *identifier; NSString *identifier;
@@ -164,10 +164,10 @@
} }
- (void)_setupDefaultPreferencesTabs { - (void)_setupDefaultPreferencesTabs {
NSArray *controllers = @[ [[MPGeneralSettingsController alloc] init], NSArray *controllers = @[ [[MPGeneralPreferencesController alloc] init],
[[MPIntegrationSettingsController alloc] init], [[MPIntegrationPreferencesController alloc] init],
[[MPWorkflowSettingsController alloc] init], [[MPWorkflowPreferencesController alloc] init],
[[MPUpdateSettingsController alloc] init], [[MPUpdatePreferencesController alloc] init],
[[MPPluginPreferencesController alloc] init] ]; [[MPPluginPreferencesController alloc] init] ];
NSMutableArray *identifier = [[NSMutableArray alloc] initWithCapacity:controllers.count]; NSMutableArray *identifier = [[NSMutableArray alloc] initWithCapacity:controllers.count];
for(id<MPPreferencesTab> controller in controllers) { for(id<MPPreferencesTab> controller in controllers) {

View File

@@ -37,8 +37,8 @@
} }
- (void)viewDidLoad { - (void)viewDidLoad {
self.searchKeyPopUpButton.menu = [self _allocateAttributeItemMenu:YES withTitle:NSLocalizedString(@"SEARCH_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", "")]; 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.searchStringTextField bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(searchString)) options:nil];
[self _updateReferenceString]; [self _updateReferenceString];
} }
@@ -53,7 +53,7 @@
[menu addItemWithTitle:NSLocalizedString(@"URL","URL reference item") action:NULL keyEquivalent:@""]; [menu addItemWithTitle:NSLocalizedString(@"URL","URL reference item") action:NULL keyEquivalent:@""];
[menu addItemWithTitle:NSLocalizedString(@"NOTES","Notes reference item") action:NULL keyEquivalent:@""]; [menu addItemWithTitle:NSLocalizedString(@"NOTES","Notes reference item") action:NULL keyEquivalent:@""];
if(allowCustomAttributes) { 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" ]; NSArray *keys = @[ kKPKReferenceUUIDKey, kKPKReferenceTitleKey, kKPKReferenceUsernameKey, kKPKReferencePasswordKey, kKPKReferenceURLKey, kKPKReferenceNotesKey, @"S" ];
[menu.itemArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { [menu.itemArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

View File

@@ -42,6 +42,7 @@ APPKIT_EXTERN NSString *const kMPSettingsKeyBrowserBundleId;
APPKIT_EXTERN NSString *const kMPSettingsKeyLockOnSleep; APPKIT_EXTERN NSString *const kMPSettingsKeyLockOnSleep;
APPKIT_EXTERN NSString *const kMPSettingskeyLockOnLogout; APPKIT_EXTERN NSString *const kMPSettingskeyLockOnLogout;
APPKIT_EXTERN NSString *const kMPSettingsKeyIdleLockTimeOut; APPKIT_EXTERN NSString *const kMPSettingsKeyIdleLockTimeOut;
APPKIT_EXTERN NSString *const kMPSettingskeyLockOnScreenSleep;
/* Autosaving states */ /* Autosaving states */
APPKIT_EXTERN NSString *const kMPSettingsKeyShowInspector; APPKIT_EXTERN NSString *const kMPSettingsKeyShowInspector;
@@ -68,7 +69,7 @@ APPKIT_EXTERN NSString *const kMPSettingsKeyAutotypeMatchTitle; //
APPKIT_EXTERN NSString *const kMPSettingsKeyAutotypeMatchURL; // Autotype lookup includes entry URL 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 kMPSettingsKeyAutotypeMatchHost; // Autotype lookup includes host part of entry URL
APPKIT_EXTERN NSString *const kMPSettingsKeyAutotypeMatchTags; // Autotype lookup includes tags for entries 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 */ /* Search */
APPKIT_EXTERN NSString *const kMPSettingsKeyEntrySearchFilterContext; APPKIT_EXTERN NSString *const kMPSettingsKeyEntrySearchFilterContext;
@@ -80,12 +81,15 @@ APPKIT_EXTERN NSString *const kMPSettingsKeyEnableQuicklookPreview;
APPKIT_EXTERN NSString *const kMPSettingsKeyDoubleClickURLAction; APPKIT_EXTERN NSString *const kMPSettingsKeyDoubleClickURLAction;
APPKIT_EXTERN NSString *const kMPSettingsKeyDoubleClickTitleAction; APPKIT_EXTERN NSString *const kMPSettingsKeyDoubleClickTitleAction;
APPKIT_EXTERN NSString *const kMPSettingsKeyUpdatePasswordOnTemplateEntries; APPKIT_EXTERN NSString *const kMPSettingsKeyUpdatePasswordOnTemplateEntries;
APPKIT_EXTERN NSString *const kMPSettingsKeyHideAfterCopyToClipboard;
/* Plugins */ /* Plugins */
APPKIT_EXTERN NSString *const kMPSettingsKeyLoadUnsecurePlugins; // If set to YES this will load all plugins regardless of their codesignature status 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 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 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 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) { typedef NS_ENUM(NSUInteger, MPFileChangeStrategy) {
MPFileChangeStrategyAsk, MPFileChangeStrategyAsk,

View File

@@ -37,6 +37,7 @@ NSString *const kMPSettingsKeyFileChangeStrategy = @"FileCh
NSString *const kMPSettingsKeyEnableAutosave = @"EnableAutosave"; NSString *const kMPSettingsKeyEnableAutosave = @"EnableAutosave";
NSString *const kMPSettingsKeyLockOnSleep = @"LockOnSleep"; NSString *const kMPSettingsKeyLockOnSleep = @"LockOnSleep";
NSString *const kMPSettingskeyLockOnLogout = @"LockOnLogout"; NSString *const kMPSettingskeyLockOnLogout = @"LockOnLogout";
NSString *const kMPSettingskeyLockOnScreenSleep = @"LockOnScreenSleep";
NSString *const kMPSettingsKeyIdleLockTimeOut = @"IdleLockTimeOut"; NSString *const kMPSettingsKeyIdleLockTimeOut = @"IdleLockTimeOut";
NSString *const kMPSettingsKeyShowInspector = @"ShowInspector"; NSString *const kMPSettingsKeyShowInspector = @"ShowInspector";
NSString *const kMPSettingsKeyEntryTableSortDescriptors = @"EntryTableSortDescriptors"; NSString *const kMPSettingsKeyEntryTableSortDescriptors = @"EntryTableSortDescriptors";
@@ -59,7 +60,7 @@ NSString *const kMPSettingsKeyAutotypeMatchTitle = @"Autoty
NSString *const kMPSettingsKeyAutotypeMatchURL = @"AutotypeMatchURL"; NSString *const kMPSettingsKeyAutotypeMatchURL = @"AutotypeMatchURL";
NSString *const kMPSettingsKeyAutotypeMatchHost = @"AutotypeMatchHost"; NSString *const kMPSettingsKeyAutotypeMatchHost = @"AutotypeMatchHost";
NSString *const kMPSettingsKeyAutotypeMatchTags = @"AutotypeMatchTags"; NSString *const kMPSettingsKeyAutotypeMatchTags = @"AutotypeMatchTags";
NSString *const kMPSettingsKeyAutotypeHideAccessibiltyWarning = @"AutotypeHideAccessibiltyWarning"; NSString *const kMPSettingsKeyAutotpyeHideMissingPermissionsWarning = @"AutotpyeHideMissingPermissionsWarning";
NSString *const kMPSettingsKeyEntrySearchFilterContext = @"EntrySearchFilterContext"; NSString *const kMPSettingsKeyEntrySearchFilterContext = @"EntrySearchFilterContext";
@@ -78,11 +79,13 @@ NSString *const kMPSettingsKeyPasswordDefaultsForEntry = @"Passwo
NSString *const kMPSettingsKeyDoubleClickURLAction = @"DoubleClickURLAction"; NSString *const kMPSettingsKeyDoubleClickURLAction = @"DoubleClickURLAction";
NSString *const kMPSettingsKeyDoubleClickTitleAction = @"DoubleClickTitleAction"; NSString *const kMPSettingsKeyDoubleClickTitleAction = @"DoubleClickTitleAction";
NSString *const kMPSettingsKeyUpdatePasswordOnTemplateEntries = @"UpdatePasswordOnTemplateEntries"; NSString *const kMPSettingsKeyUpdatePasswordOnTemplateEntries = @"UpdatePasswordOnTemplateEntries";
NSString *const kMPSettingsKeyHideAfterCopyToClipboard = @"HideAfterCopyToClipboard";
NSString *const kMPSettingsKeyLoadUnsecurePlugins = @"LoadUnsecurePlugins"; NSString *const kMPSettingsKeyLoadUnsecurePlugins = @"LoadUnsecurePlugins";
NSString *const kMPSettingsKeyLoadIncompatiblePlugins = @"LoadIncompatiblePlugins"; NSString *const kMPSettingsKeyLoadIncompatiblePlugins = @"LoadIncompatiblePlugins";
NSString *const kMPSettingsKeyDisabledPlugins = @"DisabledPlugins"; NSString *const kMPSettingsKeyDisabledPlugins = @"DisabledPlugins";
NSString *const kMPSettingsKeyHideIncopatiblePluginsWarning = @"HideIncopatiblePluginsWarning"; NSString *const kMPSettingsKeyHideIncopatiblePluginsWarning = @"HideIncopatiblePluginsWarning";
NSString *const kMPSettingsKeyAllowRemoteFetchOfPluginRepository = @"AllowRemoteFetchOfPluginRepository";
/* Deprecated */ /* Deprecated */
NSString *const kMPDeprecatedSettingsKeyRememberKeyFilesForDatabases = @"kMPSettingsKeyRememberKeyFilesForDatabases"; NSString *const kMPDeprecatedSettingsKeyRememberKeyFilesForDatabases = @"kMPSettingsKeyRememberKeyFilesForDatabases";
@@ -95,12 +98,12 @@ NSString *const kMPDeprecatedSettingsKeyEnableHttpServer = @"En
NSString *const kMPDeprecatedSettingsKeyShowMenuItem = @"ShowMenuItem"; NSString *const kMPDeprecatedSettingsKeyShowMenuItem = @"ShowMenuItem";
NSString *const kMPDeprecatedSettingsKeyDefaultPasswordRounds = @"KeyDefaultPasswordRounds"; NSString *const kMPDeprecatedSettingsKeyDefaultPasswordRounds = @"KeyDefaultPasswordRounds";
NSString *const kMPDepricatedSettingsKeyLoadUnsecurePlugins = @"MPLoadUnsecurePlugins"; NSString *const kMPDepricatedSettingsKeyLoadUnsecurePlugins = @"MPLoadUnsecurePlugins";
NSString *const kMPDepricatedSettingsKeyAutotypeHideAccessibiltyWarning = @"AutotypeHideAccessibiltyWarning";
@implementation MPSettingsHelper @implementation MPSettingsHelper
+ (void)setupDefaults { + (void)setupDefaults {
[[NSUserDefaults standardUserDefaults] registerDefaults:[self _standardDefaults]]; [NSUserDefaults.standardUserDefaults registerDefaults:[self _standardDefaults]];
} }
+ (void)migrateDefaults { + (void)migrateDefaults {
@@ -123,23 +126,24 @@ NSString *const kMPDepricatedSettingsKeyLoadUnsecurePlugins = @"MP
standardDefaults = @{ standardDefaults = @{
kMPSettingsKeyShowInspector: @YES, // Show the Inspector by default kMPSettingsKeyShowInspector: @YES, // Show the Inspector by default
kMPSettingsKeyPasteboardClearTimeout: @30, // 30 seconds kMPSettingsKeyPasteboardClearTimeout: @30, // 30 seconds
kMPSettingsKeyClearPasteboardOnQuit: @YES, kMPSettingsKeyClearPasteboardOnQuit: @YES, // Clear Clipboard on quit
kMPSettingsKeyPreventUniversalClipboard: @YES, // Disable Universal Clipboard by default kMPSettingsKeyPreventUniversalClipboard: @YES, // Disable Universal Clipboard by default
kMPSettingsKeyOpenEmptyDatabaseOnLaunch: @NO, kMPSettingsKeyOpenEmptyDatabaseOnLaunch: @NO,
kMPSettingsKeyReopenLastDatabaseOnLaunch: @YES, kMPSettingsKeyReopenLastDatabaseOnLaunch: @YES,
kMPSettingsKeyFileChangeStrategy: @(MPFileChangeStrategyAsk), // Ask what to do on a file change! kMPSettingsKeyFileChangeStrategy: @(MPFileChangeStrategyAsk), // Ask what to do on a file change!
kMPSettingsKeyLockOnSleep: @YES, kMPSettingsKeyLockOnSleep: @YES,
kMPSettingskeyLockOnLogout: @NO, kMPSettingskeyLockOnLogout: @NO,
kMPSettingsKeyIdleLockTimeOut: @0, // 5 minutes kMPSettingskeyLockOnScreenSleep: @NO,
kMPSettingsKeyIdleLockTimeOut: @0, // Do not lock while idle by default
kMPSettingsKeyLegacyHideNotes: @NO, kMPSettingsKeyLegacyHideNotes: @NO,
kMPSettingsKeyLegacyHidePassword: @YES, kMPSettingsKeyLegacyHidePassword: @YES,
kMPSettingsKeyLegacyHideTitle: @NO, kMPSettingsKeyLegacyHideTitle: @NO,
kMPSettingsKeyLegacyHideURL: @NO, kMPSettingsKeyLegacyHideURL: @NO,
kMPSettingsKeyLegacyHideUsername: @NO, kMPSettingsKeyLegacyHideUsername: @NO,
kMPSettingsKeyRememberKeyFilesForDatabases: @NO, kMPSettingsKeyRememberKeyFilesForDatabases: @NO,
kMPSettingsKeySendCommandForControlKey: @YES, kMPSettingsKeySendCommandForControlKey: @YES, // translate Ctrl to Cmd by default
kMPSettingsKeyEnableGlobalAutotype: @NO, kMPSettingsKeyEnableGlobalAutotype: @NO, // Keep global autotype disabled by default
kMPSettingsKeyGlobalAutotypeKeyDataKey: DDHotKey.defaultHotKeyData, kMPSettingsKeyGlobalAutotypeKeyDataKey: DDHotKey.defaultHotKeyData, // Cmd + Alt + M
kMPSettingsKeyDefaultGlobalAutotypeSequence: @"{USERNAME}{TAB}{PASSWORD}{ENTER}", kMPSettingsKeyDefaultGlobalAutotypeSequence: @"{USERNAME}{TAB}{PASSWORD}{ENTER}",
kMPSettingsKeyAutotypeMatchTitle: @YES, kMPSettingsKeyAutotypeMatchTitle: @YES,
kMPSettingsKeyAutotypeMatchURL: @NO, kMPSettingsKeyAutotypeMatchURL: @NO,
@@ -159,7 +163,8 @@ NSString *const kMPDepricatedSettingsKeyLoadUnsecurePlugins = @"MP
kMPSettingsKeyDisabledPlugins: @[], kMPSettingsKeyDisabledPlugins: @[],
kMPSettingsKeyLoadIncompatiblePlugins: @NO, kMPSettingsKeyLoadIncompatiblePlugins: @NO,
kMPSettingsKeyQuitOnLastWindowClose: @NO, kMPSettingsKeyQuitOnLastWindowClose: @NO,
kMPSettingsKeyEnableAutosave: @YES kMPSettingsKeyEnableAutosave: @YES,
kMPSettingsKeyHideAfterCopyToClipboard: @NO
}; };
}); });
return standardDefaults; return standardDefaults;
@@ -179,7 +184,8 @@ NSString *const kMPDepricatedSettingsKeyLoadUnsecurePlugins = @"MP
kMPDeprecatedSettingsKeyHttpPort, kMPDeprecatedSettingsKeyHttpPort,
kMPDeprecatedSettingsKeyEnableHttpServer, kMPDeprecatedSettingsKeyEnableHttpServer,
kMPDeprecatedSettingsKeyShowMenuItem, kMPDeprecatedSettingsKeyShowMenuItem,
kMPDepricatedSettingsKeyLoadUnsecurePlugins kMPDepricatedSettingsKeyLoadUnsecurePlugins,
kMPDepricatedSettingsKeyAutotypeHideAccessibiltyWarning
]; ];
}); });
return deprecatedSettings; return deprecatedSettings;
@@ -189,7 +195,7 @@ NSString *const kMPDepricatedSettingsKeyLoadUnsecurePlugins = @"MP
+ (void)_removeDeprecatedValues { + (void)_removeDeprecatedValues {
/* Clear old style values */ /* Clear old style values */
for(NSString *key in [self _deprecatedSettingsKeys]) { for(NSString *key in [self _deprecatedSettingsKeys]) {
[[NSUserDefaults standardUserDefaults] removeObjectForKey:key]; [NSUserDefaults.standardUserDefaults removeObjectForKey:key];
} }
} }
@@ -202,7 +208,7 @@ NSString *const kMPDepricatedSettingsKeyLoadUnsecurePlugins = @"MP
this was changed in 0.6. to parent.title this was changed in 0.6. to parent.title
*/ */
NSData *descriptorData = [[NSUserDefaults standardUserDefaults] dataForKey:kMPSettingsKeyEntryTableSortDescriptors]; NSData *descriptorData = [NSUserDefaults.standardUserDefaults dataForKey:kMPSettingsKeyEntryTableSortDescriptors];
if(!descriptorData) { if(!descriptorData) {
return; // No user defaults return; // No user defaults
} }
@@ -213,27 +219,35 @@ NSString *const kMPDepricatedSettingsKeyLoadUnsecurePlugins = @"MP
if(descriptor.selector == @selector(compare:) if(descriptor.selector == @selector(compare:)
|| [descriptor.key isEqualToString:@"timeInfo.modificationDate"] || [descriptor.key isEqualToString:@"timeInfo.modificationDate"]
|| [descriptor.key isEqualToString:@"parent.name"] ) { || [descriptor.key isEqualToString:@"parent.name"] ) {
[[NSUserDefaults standardUserDefaults] removeObjectForKey:kMPSettingsKeyEntryTableSortDescriptors]; [NSUserDefaults.standardUserDefaults removeObjectForKey:kMPSettingsKeyEntryTableSortDescriptors];
break; break;
} }
} }
} }
+ (void)_migrateURLDoubleClickPreferences { + (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]; Default was NO so if the key was not set the correct action now should be MPDoubleClickURLActionCopy
if(NO == openURL) { But MPDoubleClickURLActionCopy is the default we cannot simply add this value.
[[NSUserDefaults standardUserDefaults] setInteger:MPDoubleClickURLActionOpen forKey:kMPSettingsKeyDoubleClickURLAction]; 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 { + (void)_migrateEntrySearchFlags {
/* Entry filters are now stored as archivd search context not just flags */ /* Entry filters are now stored as archived search context not just flags */
NSInteger flags = [[NSUserDefaults standardUserDefaults] integerForKey:kMPDeprecatedSettingsKeyEntrySearchFilterMode]; NSInteger flags = [NSUserDefaults.standardUserDefaults integerForKey:kMPDeprecatedSettingsKeyEntrySearchFilterMode];
if(flags != 0) { if(flags != 0) {
MPEntrySearchContext *context = [[MPEntrySearchContext alloc] initWithString:nil flags:flags]; MPEntrySearchContext *context = [[MPEntrySearchContext alloc] initWithString:nil flags:flags];
NSData *contextData = [NSKeyedArchiver archivedDataWithRootObject:context]; NSData *contextData = [NSKeyedArchiver archivedDataWithRootObject:context];
[[NSUserDefaults standardUserDefaults] setObject:contextData forKey:kMPSettingsKeyEntrySearchFilterContext]; [NSUserDefaults.standardUserDefaults setObject:contextData forKey:kMPSettingsKeyEntrySearchFilterContext];
} }
} }
@@ -242,7 +256,7 @@ NSString *const kMPDepricatedSettingsKeyLoadUnsecurePlugins = @"MP
Database file paths was stored as plain text in keyfile mapping. 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 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) { if(!currentMapping) {
return; return;
} }
@@ -264,7 +278,7 @@ NSString *const kMPDepricatedSettingsKeyLoadUnsecurePlugins = @"MP
} }
} }
if(didHash) { if(didHash) {
[[NSUserDefaults standardUserDefaults] setObject:hashedDict forKey:kMPSettingsKeyRememeberdKeysForDatabases]; [NSUserDefaults.standardUserDefaults setObject:hashedDict forKey:kMPSettingsKeyRememeberdKeysForDatabases];
} }
} }

View File

@@ -41,7 +41,6 @@
self = [super init]; self = [super init];
if(self) { if(self) {
_binary = binary; _binary = binary;
_loadScheduled = NO;
[MPTemporaryFileStorageCenter.defaultCenter registerStorage:self]; [MPTemporaryFileStorageCenter.defaultCenter registerStorage:self];
} }
return self; return self;
@@ -64,17 +63,8 @@
#pragma mark QLPreviewPanelDataSource #pragma mark QLPreviewPanelDataSource
- (id<QLPreviewItem>)previewPanel:(QLPreviewPanel *)panel previewItemAtIndex:(NSInteger)index { - (id<QLPreviewItem>)previewPanel:(QLPreviewPanel *)panel previewItemAtIndex:(NSInteger)index {
if(!self.temporaryFileURL && !self.loadScheduled) { if(!self.temporaryFileURL) {
self.loadScheduled = YES; [self _saveBinary:self.binary];
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];
});
}
});
} }
return self; return self;
} }
@@ -98,11 +88,22 @@
#pragma mark Private #pragma mark Private
- (BOOL)_saveBinary:(KPKBinary *)binary { - (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; return NO;
} }
NSString *fileName = [NSString stringWithFormat:@"%@_%@", NSProcessInfo.processInfo.globallyUniqueString, binary.name]; 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]; BOOL success = [binary.data writeToURL:self.temporaryFileURL options:0 error:0];
if(!success) { if(!success) {
@@ -131,7 +132,9 @@
} }
+ (void)_runCleanupForPath:(NSString *)path { + (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 *srmURL = [NSURL fileURLWithPath:@"/usr/bin/srm"];
NSURL *rmURL = [NSURL fileURLWithPath:@"/bin/rm"]; NSURL *rmURL = [NSURL fileURLWithPath:@"/bin/rm"];

View File

@@ -30,7 +30,7 @@
if(self) { if(self) {
self.focusRingType = NSFocusRingTypeNone; self.focusRingType = NSFocusRingTypeNone;
self.bezelStyle = NSTexturedRoundedBezelStyle; self.bezelStyle = NSTexturedRoundedBezelStyle;
[self.cell setImageScaling:NSImageScaleProportionallyDown]; ((NSButtonCell *)(self.cell)).imageScaling = NSImageScaleProportionallyDown;
[self setButtonType:NSMomentaryPushInButton]; [self setButtonType:NSMomentaryPushInButton];
self.imagePosition = NSImageOnly; self.imagePosition = NSImageOnly;
} }

View File

@@ -22,6 +22,18 @@
#import <AppKit/AppKit.h> #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; @class MPDocument;
@interface MPToolbarDelegate : NSObject <NSToolbarDelegate, NSTextFieldDelegate> @interface MPToolbarDelegate : NSObject <NSToolbarDelegate, NSTextFieldDelegate>

View File

@@ -38,17 +38,17 @@
#import "NSApplication+MPAdditions.h" #import "NSApplication+MPAdditions.h"
#import "MPAppDelegate.h" #import "MPAppDelegate.h"
NSString *const MPToolbarItemLock = @"TOOLBAR_LOCK"; NSString *const MPToolbarItemIdentifierLock = @"TOOLBAR_LOCK";
NSString *const MPToolbarItemAddGroup = @"TOOLBAR_ADD_GROUP"; NSString *const MPToolbarItemIdentifierAddGroup = @"TOOLBAR_ADD_GROUP";
NSString *const MPToolbarItemAddEntry = @"TOOLBAR_ADD_ENTRY"; NSString *const MPToolbarItemIdentifierAddEntry = @"TOOLBAR_ADD_ENTRY";
NSString *const MPToolbarItemDelete =@"TOOLBAR_DELETE"; NSString *const MPToolbarItemIdentifierDelete = @"TOOLBAR_DELETE";
NSString *const MPToolbarItemAction = @"TOOLBAR_ACTION"; NSString *const MPToolbarItemIdentifierAction = @"TOOLBAR_ACTION";
NSString *const MPToolbarItemInspector = @"TOOLBAR_INSPECTOR"; NSString *const MPToolbarItemIdentifierInspector = @"TOOLBAR_INSPECTOR";
NSString *const MPToolbarItemSearch = @"TOOLBAR_SEARCH"; NSString *const MPToolbarItemIdentifierSearch = @"TOOLBAR_SEARCH";
NSString *const MPToolbarItemCopyUsername = @"TOOLBAR_COPY_USERNAME"; NSString *const MPToolbarItemIdentifierCopyUsername = @"TOOLBAR_COPY_USERNAME";
NSString *const MPToolbarItemCopyPassword = @"TOOLBAR_COPY_PASSWORD"; NSString *const MPToolbarItemIdentifierCopyPassword = @"TOOLBAR_COPY_PASSWORD";
NSString *const MPToolbarItemHistory = @"TOOLBAR_HISTORY"; NSString *const MPToolbarItemIdentifierHistory = @"TOOLBAR_HISTORY";
NSString *const MPToolbarItemAutotype = @"TOOLBAR_AUTOTYPE"; NSString *const MPToolbarItemIdentifierAutotype = @"TOOLBAR_AUTOTYPE";
@interface MPToolbarDelegate() { @interface MPToolbarDelegate() {
MPAddEntryContextMenuDelegate *_addEntryMenuDelegate; MPAddEntryContextMenuDelegate *_addEntryMenuDelegate;
@@ -72,27 +72,28 @@ NSString *const MPToolbarItemAutotype = @"TOOLBAR_AUTOTYPE";
if (self) { if (self) {
_didShowToolbarForSearch = NO; _didShowToolbarForSearch = NO;
_didAddSearchfieldForSearch = NO; _didAddSearchfieldForSearch = NO;
_toolbarIdentifiers = @[ MPToolbarItemAddEntry, _toolbarIdentifiers = @[ MPToolbarItemIdentifierAddEntry,
MPToolbarItemDelete, MPToolbarItemIdentifierDelete,
MPToolbarItemAddGroup, MPToolbarItemIdentifierAddGroup,
MPToolbarItemAction, MPToolbarItemIdentifierAction,
MPToolbarItemCopyPassword, MPToolbarItemIdentifierCopyPassword,
MPToolbarItemCopyUsername, MPToolbarItemIdentifierCopyUsername,
NSToolbarFlexibleSpaceItemIdentifier, NSToolbarFlexibleSpaceItemIdentifier,
MPToolbarItemSearch, MPToolbarItemIdentifierSearch,
MPToolbarItemLock, MPToolbarItemIdentifierLock,
MPToolbarItemInspector, MPToolbarItemIdentifierInspector,
MPToolbarItemHistory, MPToolbarItemIdentifierHistory,
MPToolbarItemAutotype ]; MPToolbarItemIdentifierAutotype ];
_defaultToolbarIdentifiers = @[ MPToolbarItemAddEntry, _defaultToolbarIdentifiers = @[ MPToolbarItemIdentifierAddEntry,
MPToolbarItemDelete, MPToolbarItemIdentifierDelete,
MPToolbarItemAddGroup, MPToolbarItemIdentifierAddGroup,
MPToolbarItemAutotype, MPToolbarItemIdentifierAutotype,
MPToolbarItemAction, MPToolbarItemIdentifierAction,
NSToolbarFlexibleSpaceItemIdentifier, NSToolbarFlexibleSpaceItemIdentifier,
MPToolbarItemSearch, MPToolbarItemIdentifierSearch,
MPToolbarItemLock, NSToolbarFlexibleSpaceItemIdentifier,
MPToolbarItemInspector ]; MPToolbarItemIdentifierLock,
MPToolbarItemIdentifierInspector ];
_toolbarImages = [self createToolbarImages]; _toolbarImages = [self createToolbarImages];
_toolbarItems = [[NSMutableDictionary alloc] initWithCapacity:[self.toolbarIdentifiers count]]; _toolbarItems = [[NSMutableDictionary alloc] initWithCapacity:[self.toolbarIdentifiers count]];
_addEntryMenuDelegate = [[MPAddEntryContextMenuDelegate alloc] init]; _addEntryMenuDelegate = [[MPAddEntryContextMenuDelegate alloc] init];
@@ -111,8 +112,9 @@ NSString *const MPToolbarItemAutotype = @"TOOLBAR_AUTOTYPE";
item = [[MPToolbarItem alloc] initWithItemIdentifier:itemIdentifier]; item = [[MPToolbarItem alloc] initWithItemIdentifier:itemIdentifier];
NSString *itemLabel = [self _localizedLabelForToolbarItemIdentifier:itemIdentifier]; NSString *itemLabel = [self _localizedLabelForToolbarItemIdentifier:itemIdentifier];
item.label = itemLabel; 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]; NSPopUpButton *popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(0, 0, 50, 32) pullsDown:YES];
popupButton.bezelStyle = NSTexturedRoundedBezelStyle; popupButton.bezelStyle = NSTexturedRoundedBezelStyle;
popupButton.focusRingType = NSFocusRingTypeNone; popupButton.focusRingType = NSFocusRingTypeNone;
@@ -125,9 +127,9 @@ NSString *const MPToolbarItemAutotype = @"TOOLBAR_AUTOTYPE";
NSMenu *menu = [[NSMenu alloc] init]; NSMenu *menu = [[NSMenu alloc] init];
NSMenuItem *actionImageItem = [[NSMenuItem alloc] initWithTitle:@"" action:NULL keyEquivalent:@""]; NSMenuItem *actionImageItem = [[NSMenuItem alloc] initWithTitle:@"" action:NULL keyEquivalent:@""];
actionImageItem.image = self.toolbarImages[MPToolbarItemAction]; actionImageItem.image = self.toolbarImages[MPToolbarItemIdentifierAction];
[menu addItem:actionImageItem]; [menu addItem:actionImageItem];
NSArray *menuItems = [MPContextMenuHelper contextMenuItemsWithItems:MPContextMenuExtended]; NSArray *menuItems = [MPContextMenuHelper contextMenuItemsWithItems:MPContextMenuExtended|MPContextMenuShowGroupInOutline];
for(NSMenuItem *item in menuItems) { for(NSMenuItem *item in menuItems) {
[menu addItem:item]; [menu addItem:item];
} }
@@ -142,7 +144,7 @@ NSString *const MPToolbarItemAutotype = @"TOOLBAR_AUTOTYPE";
item.menuFormRepresentation = menuRepresentation; item.menuFormRepresentation = menuRepresentation;
item.view = popupButton; item.view = popupButton;
} }
else if( [itemIdentifier isEqualToString:MPToolbarItemAddEntry]) { else if( [itemIdentifier isEqualToString:MPToolbarItemIdentifierAddEntry]) {
MPContextButton *button = [[MPContextButton alloc] initWithFrame:NSMakeRect(0, 0, 32, 32)]; MPContextButton *button = [[MPContextButton alloc] initWithFrame:NSMakeRect(0, 0, 32, 32)];
button.action = [self _actionForToolbarItemIdentifier:itemIdentifier]; button.action = [self _actionForToolbarItemIdentifier:itemIdentifier];
NSImage *image = self.toolbarImages[itemIdentifier]; NSImage *image = self.toolbarImages[itemIdentifier];
@@ -167,7 +169,7 @@ NSString *const MPToolbarItemAutotype = @"TOOLBAR_AUTOTYPE";
item.menuFormRepresentation = menuRepresentation; item.menuFormRepresentation = menuRepresentation;
} }
else if( [itemIdentifier isEqualToString:MPToolbarItemSearch]){ else if( [itemIdentifier isEqualToString:MPToolbarItemIdentifierSearch]){
NSSearchField *searchField = [[NSSearchField alloc] init]; NSSearchField *searchField = [[NSSearchField alloc] init];
searchField.action = @selector(updateSearch:); searchField.action = @selector(updateSearch:);
NSSearchFieldCell *cell = searchField.cell; NSSearchFieldCell *cell = searchField.cell;
@@ -177,9 +179,10 @@ NSString *const MPToolbarItemAutotype = @"TOOLBAR_AUTOTYPE";
item.view = searchField; item.view = searchField;
/* Use default size base on documentation */ /* Use default size base on documentation */
item.minSize = NSMakeSize(140, 32); item.minSize = NSMakeSize(140, 32);
item.maxSize = NSMakeSize(240, 32); item.maxSize = NSMakeSize(400, 32);
NSMenu *templateMenu = [self _allocateSearchMenuTemplate]; NSMenu *templateMenu = [self _allocateSearchMenuTemplate];
searchField.searchMenuTemplate = templateMenu; searchField.searchMenuTemplate = templateMenu;
searchField.placeholderString = NSLocalizedString(@"SEARCH_EVERYWHERE", @"Placeholder string displayed in the search field in the toolbar");
/* 10.10 does not support NSSearchFieldDelegate */ /* 10.10 does not support NSSearchFieldDelegate */
((NSTextField *)searchField).delegate = self; ((NSTextField *)searchField).delegate = self;
self.searchField = searchField; self.searchField = searchField;
@@ -215,16 +218,16 @@ NSString *const MPToolbarItemAutotype = @"TOOLBAR_AUTOTYPE";
} }
- (NSDictionary *)createToolbarImages { - (NSDictionary *)createToolbarImages {
NSDictionary *imageDict = @{ MPToolbarItemLock: [NSImage imageNamed:NSImageNameLockUnlockedTemplate], NSDictionary *imageDict = @{ MPToolbarItemIdentifierLock: [NSImage imageNamed:NSImageNameLockLockedTemplate],
MPToolbarItemAddEntry: [MPIconHelper icon:MPIconAddEntry], MPToolbarItemIdentifierAddEntry: [MPIconHelper icon:MPIconAddEntry],
MPToolbarItemAddGroup: [MPIconHelper icon:MPIconAddFolder], MPToolbarItemIdentifierAddGroup: [MPIconHelper icon:MPIconAddFolder],
MPToolbarItemCopyUsername : [MPIconHelper icon:MPIconIdentity], MPToolbarItemIdentifierCopyUsername : [MPIconHelper icon:MPIconIdentity],
MPToolbarItemCopyPassword : [MPIconHelper icon:MPIconPassword], MPToolbarItemIdentifierCopyPassword : [MPIconHelper icon:MPIconPassword],
MPToolbarItemDelete: [MPIconHelper icon:MPIconTrash], MPToolbarItemIdentifierDelete: [MPIconHelper icon:MPIconTrash],
MPToolbarItemAction: [NSImage imageNamed:NSImageNameActionTemplate], MPToolbarItemIdentifierAction: [NSImage imageNamed:NSImageNameActionTemplate],
MPToolbarItemInspector: [MPIconHelper icon:MPIconInfo], MPToolbarItemIdentifierInspector: [MPIconHelper icon:MPIconInfo],
MPToolbarItemHistory: [MPIconHelper icon:MPIconHistory], MPToolbarItemIdentifierHistory: [MPIconHelper icon:MPIconHistory],
MPToolbarItemAutotype : [MPIconHelper icon:MPIconKeyboard] MPToolbarItemIdentifierAutotype : [MPIconHelper icon:MPIconKeyboard]
}; };
return imageDict; return imageDict;
} }
@@ -237,12 +240,20 @@ NSString *const MPToolbarItemAutotype = @"TOOLBAR_AUTOTYPE";
#pragma mark - NSSearchFieldDelegate #pragma mark - NSSearchFieldDelegate
- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector { - (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector {
if(control != self.searchField) {
return NO;
}
if(commandSelector == @selector(insertNewline:) || commandSelector == @selector(moveDown:)) { if(commandSelector == @selector(insertNewline:) || commandSelector == @selector(moveDown:)) {
/* Dispatch the focus loss since doing it now will break recent search storage */ /* Dispatch the focus loss since doing it now will break recent search storage */
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
[[NSApp targetForAction:@selector(focusEntries:) to:nil from:self] focusEntries:self]; [[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; return NO;
} }
@@ -251,17 +262,17 @@ NSString *const MPToolbarItemAutotype = @"TOOLBAR_AUTOTYPE";
static NSDictionary *labelDict; static NSDictionary *labelDict;
static dispatch_once_t onceToken; static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{ dispatch_once(&onceToken, ^{
labelDict = @{ MPToolbarItemLock: NSLocalizedString(@"LOCK", @"Toolbar item to Lock the database"), labelDict = @{ MPToolbarItemIdentifierLock: NSLocalizedString(@"LOCK", @"Toolbar item to Lock the database"),
MPToolbarItemAction: NSLocalizedString(@"ACTION", @"Toolbar item with action menu"), MPToolbarItemIdentifierAction: NSLocalizedString(@"ACTION", @"Toolbar item with action menu"),
MPToolbarItemAddEntry: NSLocalizedString(@"NEW_ENTRY", @"Toolbar item new entry"), MPToolbarItemIdentifierAddEntry: NSLocalizedString(@"NEW_ENTRY", @"Toolbar item new entry"),
MPToolbarItemAddGroup: NSLocalizedString(@"NEW_GROUP", @"Toolbar item new group"), MPToolbarItemIdentifierAddGroup: NSLocalizedString(@"NEW_GROUP", @"Toolbar item new group"),
MPToolbarItemCopyPassword: NSLocalizedString(@"COPY_PASSWORD", @"Toolbar item copy password"), MPToolbarItemIdentifierCopyPassword: NSLocalizedString(@"COPY_PASSWORD", @"Toolbar item copy password"),
MPToolbarItemCopyUsername: NSLocalizedString(@"COPY_USERNAME", @"Toolbar item copy username"), MPToolbarItemIdentifierCopyUsername: NSLocalizedString(@"COPY_USERNAME", @"Toolbar item copy username"),
MPToolbarItemDelete: NSLocalizedString(@"DELETE", @"Toolbar item delete item"), MPToolbarItemIdentifierDelete: NSLocalizedString(@"DELETE", @"Toolbar item delete item"),
MPToolbarItemInspector: NSLocalizedString(@"INSPECTOR", @"Toolbar item toggle inspector"), MPToolbarItemIdentifierInspector: NSLocalizedString(@"INSPECTOR", @"Toolbar item toggle inspector"),
MPToolbarItemSearch: NSLocalizedString(@"SEARCH", @"Search input in Toolbar "), MPToolbarItemIdentifierSearch: NSLocalizedString(@"SEARCH", @"Search input in Toolbar "),
MPToolbarItemHistory: NSLocalizedString(@"SHOW_HISTORY", @"Toolbar item to toggle history display"), MPToolbarItemIdentifierHistory: NSLocalizedString(@"SHOW_HISTORY", @"Toolbar item to toggle history display"),
MPToolbarItemAutotype: NSLocalizedString(@"TOOLBAR_PERFORM_AUTOTYPE_FOR_ENTRY", @"Toolbar item to perform autotype") MPToolbarItemIdentifierAutotype: NSLocalizedString(@"TOOLBAR_PERFORM_AUTOTYPE_FOR_ENTRY", @"Toolbar item to perform autotype")
}; };
}); });
return labelDict[identifier]; return labelDict[identifier];
@@ -271,15 +282,15 @@ NSString *const MPToolbarItemAutotype = @"TOOLBAR_AUTOTYPE";
static NSDictionary *actionDict; static NSDictionary *actionDict;
static dispatch_once_t onceToken; static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{ dispatch_once(&onceToken, ^{
actionDict = @{ MPToolbarItemLock: @(MPActionLock), actionDict = @{ MPToolbarItemIdentifierLock: @(MPActionLock),
MPToolbarItemAddEntry: @(MPActionAddEntry), MPToolbarItemIdentifierAddEntry: @(MPActionAddEntry),
MPToolbarItemAddGroup: @(MPActionAddGroup), MPToolbarItemIdentifierAddGroup: @(MPActionAddGroup),
MPToolbarItemDelete: @(MPActionDelete), MPToolbarItemIdentifierDelete: @(MPActionDelete),
MPToolbarItemCopyPassword: @(MPActionCopyPassword), MPToolbarItemIdentifierCopyPassword: @(MPActionCopyPassword),
MPToolbarItemCopyUsername: @(MPActionCopyUsername), MPToolbarItemIdentifierCopyUsername: @(MPActionCopyUsername),
MPToolbarItemInspector: @(MPActionToggleInspector), MPToolbarItemIdentifierInspector: @(MPActionToggleInspector),
MPToolbarItemHistory: @(MPActionShowEntryHistory), MPToolbarItemIdentifierHistory: @(MPActionShowEntryHistory),
MPToolbarItemAutotype: @(MPActionPerformAutotypeForSelectedEntry) MPToolbarItemIdentifierAutotype: @(MPActionPerformAutotypeForSelectedEntry)
}; };
}); });
MPActionType actionType = (MPActionType)[actionDict[identifier] integerValue]; MPActionType actionType = (MPActionType)[actionDict[identifier] integerValue];
@@ -312,9 +323,9 @@ NSString *const MPToolbarItemAutotype = @"TOOLBAR_AUTOTYPE";
- (void)_didEnterSearch:(NSNotification *)notification { - (void)_didEnterSearch:(NSNotification *)notification {
/* We enter search. If there is no Item to search in the toolbar, we need to add it */ /* We enter search. If there is no Item to search in the toolbar, we need to add it */
NSArray *currentItems = self.toolbar.items; NSArray *currentItems = self.toolbar.items;
NSToolbarItem *searchItem = self.toolbarItems[MPToolbarItemSearch]; NSToolbarItem *searchItem = self.toolbarItems[MPToolbarItemIdentifierSearch];
if(!searchItem || ![currentItems containsObject:searchItem]) { if(!searchItem || ![currentItems containsObject:searchItem]) {
[self.toolbar insertItemWithItemIdentifier:MPToolbarItemSearch atIndex:[currentItems count]]; [self.toolbar insertItemWithItemIdentifier:MPToolbarItemIdentifierSearch atIndex:[currentItems count]];
_didAddSearchfieldForSearch = YES; _didAddSearchfieldForSearch = YES;
} }
/* Then we should make sure the toolbar is visible. Just to make life easier */ /* 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 { - (void)_didExitSearch:(NSNotification *)notification {
[self.searchField setStringValue:@""]; self.searchField.stringValue = @"";
NSWindow *window = [self.searchField window]; NSWindow *window = [self.searchField window];
/* Resign first responder form search field only if it was the first responder */ /* Resign first responder form search field only if it was the first responder */
if(window.firstResponder == [self.searchField currentEditor]) { if(window.firstResponder == [self.searchField currentEditor]) {
[window makeFirstResponder:nil]; [window makeFirstResponder:nil];
} }
if(_didAddSearchfieldForSearch) { if(_didAddSearchfieldForSearch) {
NSToolbarItem *searchItem = self.toolbarItems[MPToolbarItemSearch]; NSToolbarItem *searchItem = self.toolbarItems[MPToolbarItemIdentifierSearch];
NSUInteger index = [self.toolbar.items indexOfObject:searchItem]; NSUInteger index = [self.toolbar.items indexOfObject:searchItem];
if(index != NSNotFound) { if(index != NSNotFound) {
[self.toolbar removeItemAtIndex:index]; [self.toolbar removeItemAtIndex:index];

View File

@@ -0,0 +1,40 @@
//
// MPTouchBarButtonCreator.h
// MacPass
//
// Created by Veit-Hendrik Schlenker on 25.12.18.
// Copyright © 2018 HicknHack Software GmbH. All rights reserved.
//
#import "MPPasswordInputController.h"
@interface MPTouchBarButtonCreator: NSObject
APPKIT_EXTERN NSTouchBarCustomizationIdentifier MPTouchBarCustomizationIdentifierPasswordInput;
APPKIT_EXTERN NSTouchBarItemIdentifier MPTouchBarItemIdentifierChooseKeyfile;
APPKIT_EXTERN NSTouchBarItemIdentifier MPTouchBarItemIdentifierShowPassword;
APPKIT_EXTERN NSTouchBarItemIdentifier MPTouchBarItemIdentifierUnlock;
APPKIT_EXTERN NSTouchBarCustomizationIdentifier MPTouchBarCustomizationIdentifierDocument;
APPKIT_EXTERN NSTouchBarItemIdentifier MPTouchBarItemIdentifierSearch;
APPKIT_EXTERN NSTouchBarItemIdentifier MPTouchBarItemIdentifierEditPopover;
APPKIT_EXTERN NSTouchBarItemIdentifier MPTouchBarItemIdentifierCopyUsername;
APPKIT_EXTERN NSTouchBarItemIdentifier MPTouchBarItemIdentifierCopyPassword;
APPKIT_EXTERN NSTouchBarItemIdentifier MPTouchBarItemIdentifierPerformAutotype;
APPKIT_EXTERN NSTouchBarItemIdentifier MPTouchBarItemIdentifierLock;
APPKIT_EXTERN NSTouchBarItemIdentifier MPTouchBarItemIdentifierNewEntry;
APPKIT_EXTERN NSTouchBarItemIdentifier MPTouchBarItemIdentifierNewGroup;
APPKIT_EXTERN NSTouchBarItemIdentifier MPTouchBarItemIdentifierDelete;
+ (NSTouchBarItem *)touchBarButtonWithTitle:(NSString *)title identifier:(NSTouchBarItemIdentifier)identifier target:(id)target selector:(SEL)selector customizationLabel:(NSString *)customizationLabel API_AVAILABLE(macos(10.12.2));
+ (NSTouchBarItem *)touchBarButtonWithTitleAndImage:(NSString *)title identifier:(NSTouchBarItemIdentifier)identifier image:(NSImage *)image target:(id)target selector:(SEL)selector customizationLabel:(NSString *)customizationLabel API_AVAILABLE(macos(10.12.2));
+ (NSTouchBarItem *)touchBarButtonWithTitleAndImageAndColor:(NSString *)title identifier:(NSTouchBarItemIdentifier)identifier image:(NSImage *)image color:(NSColor *)color target:(id)target selector:(SEL)selector customizationLabel:(NSString *)customizationLabel API_AVAILABLE(macos(10.12.2));
+ (NSTouchBarItem *)touchBarButtonWithImage:(NSImage *)image identifier:(NSTouchBarItemIdentifier)identifier target:(id)target selector:(SEL)selector customizationLabel:(NSString *)customizationLabel API_AVAILABLE(macos(10.12.2));
+ (NSPopoverTouchBarItem *)popoverTouchBarButton:(NSString *)title identifier:(NSTouchBarItemIdentifier)identifier popoverTouchBar:(NSTouchBar *)popoverTouchBar customizationLabel:(NSString *)customizationLabel API_AVAILABLE(macos(10.12.2));
@end

View File

@@ -0,0 +1,68 @@
//
// MPTouchBarButtonCreator.m
// MacPass
//
// Created by Veit-Hendrik Schlenker on 25.12.18.
// Copyright © 2018 HicknHack Software GmbH. All rights reserved.
//
#import "MPTouchBarButtonCreator.h"
NSTouchBarCustomizationIdentifier MPTouchBarCustomizationIdentifierPasswordInput = @"com.hicknhacksoftware.MacPass.TouchBar.passwordInput";
NSTouchBarItemIdentifier MPTouchBarItemIdentifierChooseKeyfile = @"com.hicknhacksoftware.MacPass.TouchBar.passwordInput.chooseKeyfile";
NSTouchBarItemIdentifier MPTouchBarItemIdentifierShowPassword = @"com.hicknhacksoftware.MacPass.TouchBar.passwordInput.showPassword";
NSTouchBarItemIdentifier MPTouchBarItemIdentifierUnlock = @"com.hicknhacksoftware.MacPass.TouchBar.passwordInput.unlock";
NSTouchBarCustomizationIdentifier MPTouchBarCustomizationIdentifierDocument = @"com.hicknhacksoftware.MacPass.TouchBar.documentWindow";
NSTouchBarItemIdentifier MPTouchBarItemIdentifierSearch = @"com.hicknhacksoftware.MacPass.TouchBar.documentWindow.search";
NSTouchBarItemIdentifier MPTouchBarItemIdentifierEditPopover = @"com.hicknhacksoftware.MacPass.TouchBar.documentWindow.editPopover";
NSTouchBarItemIdentifier MPTouchBarItemIdentifierCopyUsername = @"com.hicknhacksoftware.MacPass.TouchBar.documentWindow.copyUsername";
NSTouchBarItemIdentifier MPTouchBarItemIdentifierCopyPassword = @"com.hicknhacksoftware.MacPass.TouchBar.documentWindow.copyPassword";
NSTouchBarItemIdentifier MPTouchBarItemIdentifierPerformAutotype = @"com.hicknhacksoftware.MacPass.TouchBar.documentWindow.performAutotype";
NSTouchBarItemIdentifier MPTouchBarItemIdentifierLock = @"com.hicknhacksoftware.MacPass.TouchBar.documentWindow.lock";
NSTouchBarItemIdentifier MPTouchBarItemIdentifierNewEntry = @"com.hicknhacksoftware.MacPass.TouchBar.documentWindow.newEntry";
NSTouchBarItemIdentifier MPTouchBarItemIdentifierNewGroup = @"com.hicknhacksoftware.MacPass.TouchBar.documentWindow.newGroup";
NSTouchBarItemIdentifier MPTouchBarItemIdentifierDelete = @"com.hicknhacksoftware.MacPass.TouchBar.documentWindow.delete";
@implementation MPTouchBarButtonCreator
+ (NSTouchBarItem *)touchBarButtonWithTitle:(NSString *)title identifier:(NSTouchBarItemIdentifier)identifier target:(id)target selector:(SEL)selector customizationLabel:(NSString *)customizationLabel API_AVAILABLE(macos(10.12.2)){
NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier];
NSButton *button = [NSButton buttonWithTitle:title target:target action:selector];
item.view = button;
item.customizationLabel = customizationLabel;
return item;
}
+ (NSTouchBarItem *)touchBarButtonWithTitleAndImage:(NSString *)title identifier:(NSTouchBarItemIdentifier)identifier image:(NSImage *)image target:(id)target selector:(SEL)selector customizationLabel:(NSString *)customizationLabel API_AVAILABLE(macos(10.12.2)){
return [self touchBarButtonWithTitleAndImageAndColor:title identifier:identifier image:image color:nil target:target selector:selector customizationLabel:customizationLabel];
}
+ (NSTouchBarItem *)touchBarButtonWithTitleAndImageAndColor:(NSString *)title identifier:(NSTouchBarItemIdentifier)identifier image:(NSImage *)image color:(NSColor *)color target:(id)target selector:(SEL)selector customizationLabel:(NSString *)customizationLabel API_AVAILABLE(macos(10.12.2)){
NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier];
NSButton *button = [NSButton buttonWithTitle:title image:image target:target action:selector];
button.bezelColor = color;
item.view = button;
item.customizationLabel = customizationLabel;
return item;
}
+ (NSTouchBarItem *)touchBarButtonWithImage:(NSImage *)image identifier:(NSTouchBarItemIdentifier)identifier target:(id)target selector:(SEL)selector customizationLabel:(NSString *)customizationLabel API_AVAILABLE(macos(10.12.2)){
NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier];
NSButton *button = [NSButton buttonWithImage:image target:target action:selector];
item.view = button;
item.customizationLabel = customizationLabel;
return item;
}
+ (NSPopoverTouchBarItem *)popoverTouchBarButton:(NSString *)title identifier:(NSTouchBarItemIdentifier)identifier popoverTouchBar:(NSTouchBar *)popoverTouchBar customizationLabel:(NSString *)customizationLabel API_AVAILABLE(macos(10.12.2)){
NSPopoverTouchBarItem *item = [[NSPopoverTouchBarItem alloc] initWithIdentifier:identifier];
item.collapsedRepresentationLabel = title;
item.popoverTouchBar = popoverTouchBar;
item.customizationLabel = customizationLabel;
return item;
}
@end

View File

@@ -99,10 +99,9 @@
return (response == NSModalResponseOK) ? pickFieldViewController.pickedValue : @""; return (response == NSModalResponseOK) ? pickFieldViewController.pickedValue : @"";
} }
- (NSString *)tree:(KPKTree *)tree resolvePickCharsPlaceholderForEntry:(KPKEntry *)entry field:(NSString *)field options:(NSString *)options { - (NSString *)tree:(KPKTree *)tree resolvePickCharsPlaceholderForValue:(NSString *)value options:(NSString *)options {
NSString *value = [[entry valueForAttributeWithKey:field] kpk_finalValueForEntry:entry];
if(value.length == 0) { if(value.length == 0) {
return @""; // error while retrieving source value return @"";
} }
MPPickcharsParser *parser = [[MPPickcharsParser alloc] initWithOptions:options]; MPPickcharsParser *parser = [[MPPickcharsParser alloc] initWithOptions:options];
MPPickcharsViewController *pickCharViewController = [[MPPickcharsViewController alloc] init]; MPPickcharsViewController *pickCharViewController = [[MPPickcharsViewController alloc] init];

Some files were not shown because too many files have changed in this diff Show More