63 Commits

Author SHA1 Message Date
michael starke
8d34f77a1f Bumped Version
Updated Credits
2013-07-19 03:21:47 +02:00
michael starke
859fe5ede8 Default fields are now respected too in validation 2013-07-19 03:14:41 +02:00
michael starke
fef291df88 Added custom string field validation. Still needs testing for default keys 2013-07-19 03:06:29 +02:00
michael starke
c1b47bdb77 Enhanced password input to check and verify
Added repeat password input in settings
New databases without password request on (it's not changed on file until the saved)
2013-07-19 01:39:52 +02:00
michael starke
0e102d3f0f Saving last state of Inspector (last document wins) 2013-07-18 21:23:32 +02:00
michael starke
d4c7d49d6f Fixed issue with window restoration 2013-07-18 21:16:56 +02:00
michael starke
0144e3c21f Bumped Build number 2013-07-18 04:36:45 +02:00
michael starke
dd5eef4e60 Fixed missing delete button on custom fields 2013-07-18 04:29:17 +02:00
michael starke
bfc610a25e Added "reopen last database" featuer
Removed standard open new db on activate
Enabled windows state restoration
Enabled table column state restoration
Menu items should be validated better
2013-07-18 04:21:23 +02:00
michael starke
0986271199 Updated Submodules
Extracted TabelViewDelegates for Attachments and Custom Fields
2013-07-18 02:55:09 +02:00
michael starke
63c3c83eb8 Updated Screenshots
Fixed some localization errors
2013-07-17 01:34:57 +02:00
michael starke
0a42e55f0e Added custom-field copy to the context menu on entries. It's not fully functional as it's not correctly using the click but always the selected entry! 2013-07-17 01:02:02 +02:00
michael starke
442d16e297 Updated submodules 2013-07-17 00:03:24 +02:00
michael starke
6f92b70039 Updated Submodules 2013-07-16 02:07:11 +02:00
michael starke
8496140f9c XML Export now uses pretty print option 2013-07-16 01:07:11 +02:00
michael starke
d814556376 Merge branch 'master' of https://github.com/mstarke/MacPass 2013-07-15 22:10:32 +02:00
michael starke
c0051f852e Added export to XML action for Version2 Databases
Small updates to Database Settings window
2013-07-15 22:10:27 +02:00
Michael Starke
726f8846b8 Merge branch 'master' of https://github.com/mstarke/MacPass 2013-07-15 17:37:43 +02:00
Michael Starke
c50da8f0ac Changed file encodings 2013-07-15 17:37:18 +02:00
michael starke
f4c67ea603 Updated Submodules 2013-07-15 10:36:22 +02:00
Michael Starke
99163ab84c Updated submodules 2013-07-14 22:54:14 +02:00
michael starke
3ae08796a1 Updated KeePassKit 2013-07-14 15:03:22 +02:00
michael starke
665dad02ac Updated KeePassKit 2013-07-14 12:05:29 +02:00
michael starke
2630dc8778 Added shared Schemes to transfer Build Incremente script 2013-07-14 12:04:54 +02:00
michael starke
9836d3c194 Updated KeePassKit 2013-07-14 01:51:09 +02:00
michael starke
55d0eddbf8 Merge branch 'master' of https://github.com/mstarke/MacPass
Conflicts:
	MacPass/MacPass-Info.plist
2013-07-14 01:50:31 +02:00
michael starke
03c5f78960 Updated build 2013-07-14 01:49:17 +02:00
Michael Starke
1d688293af Updated KeePassKit 2013-07-13 23:02:30 +02:00
michael starke
6b14f84afb Experimenting with edit mode for the Inspector 2013-07-13 18:45:32 +02:00
michael starke
a31e287ec8 Fixed Tests
Fixed error that lead to trying to create and array with nil object
2013-07-13 00:00:51 +02:00
michael starke
860d6bb21c Added KeePassKit to start rewrite of MiniKeePassLib 2013-07-12 01:07:06 +02:00
michael starke
3d14904640 Key/Password set/reset test 2013-07-11 01:51:20 +02:00
michael starke
3d4c183bdb Updated tests 2013-07-11 00:25:20 +02:00
michael starke
00eec52781 Merge branch 'master' of https://github.com/mstarke/MacPass 2013-07-11 00:23:43 +02:00
michael starke
ab0199e3dd Setup for UnitTests 2013-07-11 00:23:30 +02:00
Michael Starke
910c89288f Added IRC channel information 2013-07-10 23:17:59 +02:00
Michael Starke
eaa072f298 Update README.md 2013-07-10 19:34:10 +02:00
Michael Starke
d0b6927a5e Update README.md 2013-07-10 19:33:31 +02:00
Michael Starke
b7d15f7e49 Restructured and updated Readme. Added more alternatives. 2013-07-10 10:40:26 +02:00
michael starke
515190a74e Added humanized Date formatting (simple)
Fixed errors that would occur if undo was mixed with emptying the trash
Updated localizations
Added localized descriptions
Fixed #31 Database name is displayed, if none is given fallback is used
2013-07-10 03:37:31 +02:00
michael starke
75c9aa6873 Temporarily disabled drag and drop until it's working properly
Fixed issues with clearing the trash
2013-07-10 01:20:08 +02:00
michael starke
c34d840e35 Fixed wrong names for redo-actions 2013-07-09 23:50:38 +02:00
michael starke
fb0887ebf0 Refactored Undo/Redo 2013-07-09 21:58:28 +02:00
michael starke
6ba8b1445d Updated to new HNHRoundedSecureTextField 2013-07-09 03:04:55 +02:00
michael starke
79a8c05e95 Updated views to new Password input. 2013-07-09 02:41:22 +02:00
michael starke
a98720a00c experiments with password toggle input 2013-07-07 23:39:06 +02:00
michael starke
c674745103 Updated references 2013-07-07 22:09:21 +02:00
michael starke
d3cdc4d574 Added 4 more icons. Updated HNHUi 2013-07-07 14:04:43 +02:00
michael starke
dfb8c7936a Updated HNHUi 2013-07-06 12:13:38 +02:00
michael starke
02f54d2c35 Updated HNHUi 2013-07-06 12:11:01 +02:00
michael starke
1db5bd0e12 Bumped Version to 0.3.1 2013-07-06 04:22:08 +02:00
michael starke
cadfd3fdca Fixed issue that occurred in no reset on Database settings after cancle 2013-07-06 04:20:36 +02:00
michael starke
f55e78349e Reworked DatabaseSettings to be cancelable
Moved Password edit to Database settings
2013-07-06 04:18:10 +02:00
michael starke
005bab7380 Updated HNHUi 2013-07-06 04:16:56 +02:00
michael starke
f0e4def758 Added better save to disk icon 2013-07-06 01:05:45 +02:00
michael starke
58abad34a1 Updated HNHUi 2013-07-06 01:05:24 +02:00
michael starke
628fbbfeda Removal off attachments included 2013-07-05 20:50:38 +02:00
michael starke
9c3a62bef6 Added support to save and load Attachemnts on KeePass2 Databases.
Support for Keepass1 DBs is still missing
2013-07-05 20:09:17 +02:00
michael starke
7feb2517dd Added a default Database name
Minor changes
Updtaed KeePassLib
2013-07-05 16:37:35 +02:00
michael starke
59db224a35 OutlineView group now displays the database name if a KeePass 2 database is used 2013-07-05 01:06:02 +02:00
michael starke
c32003d7c6 Merge branch 'master' of https://github.com/mstarke/MacPass 2013-07-04 23:55:21 +02:00
michael starke
1a095ce1d7 Added Icon supplied by Iiro Jäppinen
Added more KeePass Icon replacements
2013-07-04 23:54:45 +02:00
Michael Starke
7b8ce088fe Updated releases 2013-07-04 00:09:07 +02:00
145 changed files with 7631 additions and 3841 deletions

3
.gitmodules vendored
View File

@@ -10,3 +10,6 @@
[submodule "CocoaHTTPServer"] [submodule "CocoaHTTPServer"]
path = CocoaHTTPServer path = CocoaHTTPServer
url = git://github.com/robbiehanson/CocoaHTTPServer.git url = git://github.com/robbiehanson/CocoaHTTPServer.git
[submodule "KeePassKit"]
path = KeePassKit
url = https://mstarke@github.com/mstarke/KeePassKit

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 KiB

BIN
Assets/App icon/PSD.zip Normal file

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 163 KiB

After

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

2
HNHUi

Submodule HNHUi updated: 332586b554...c32f87da30

1
KeePassKit Submodule

Submodule KeePassKit added at 8b8d3406a5

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,121 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0460"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4C77E36115B84A240093A587"
BuildableName = "MacPass.app"
BlueprintName = "MacPass"
ReferencedContainer = "container:MacPass.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4C45FB19178E09ED0010007D"
BuildableName = "MacPassTests.octest"
BlueprintName = "MacPassTests"
ReferencedContainer = "container:MacPass.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4C77E36115B84A240093A587"
BuildableName = "MacPass.app"
BlueprintName = "MacPass"
ReferencedContainer = "container:MacPass.xcodeproj">
</BuildableReference>
</MacroExpansion>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<BuildableProductRunnable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4C77E36115B84A240093A587"
BuildableName = "MacPass.app"
BlueprintName = "MacPass"
ReferencedContainer = "container:MacPass.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<CommandLineArguments>
<CommandLineArgument
argument = "-NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints YES"
isEnabled = "NO">
</CommandLineArgument>
</CommandLineArguments>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
<BuildableProductRunnable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4C77E36115B84A240093A587"
BuildableName = "MacPass.app"
BlueprintName = "MacPass"
ReferencedContainer = "container:MacPass.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
<PreActions>
<ExecutionAction
ActionType = "Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction">
<ActionContent
title = "Run Script"
scriptText = "PLIST_FILE=$PROJECT_DIR/$INFOPLIST_FILE&#10;VERSION=$(/usr/libexec/PlistBuddy -c &quot;Print CFBundleVersion&quot; $PLIST_FILE)&#10;VERSION=$(($VERSION + 1))&#10;/usr/libexec/PlistBuddy -c &quot;Set :CFBundleVersion $VERSION&quot; $PLIST_FILE"
shellToInvoke = "/bin/bash">
<EnvironmentBuildable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4C77E36115B84A240093A587"
BuildableName = "MacPass.app"
BlueprintName = "MacPass"
ReferencedContainer = "container:MacPass.xcodeproj">
</BuildableReference>
</EnvironmentBuildable>
</ActionContent>
</ExecutionAction>
</PreActions>
</ArchiveAction>
</Scheme>

View File

@@ -48,7 +48,7 @@
<object class="NSButton" id="145041823"> <object class="NSButton" id="145041823">
<reference key="NSNextResponder" ref="1005"/> <reference key="NSNextResponder" ref="1005"/>
<int key="NSvFlags">268</int> <int key="NSvFlags">268</int>
<string key="NSFrame">{{18, 174}, {233, 18}}</string> <string key="NSFrame">{{18, 177}, {241, 18}}</string>
<reference key="NSSuperview" ref="1005"/> <reference key="NSSuperview" ref="1005"/>
<reference key="NSWindow"/> <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="60918609"/> <reference key="NSNextKeyView" ref="60918609"/>
@@ -56,9 +56,9 @@
<string key="NSHuggingPriority">{250, 252}</string> <string key="NSHuggingPriority">{250, 252}</string>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="168279901"> <object class="NSButtonCell" key="NSCell" id="168279901">
<int key="NSCellFlags">-1543503872</int> <int key="NSCellFlags">-2080374784</int>
<int key="NSCellFlags2">268435456</int> <int key="NSCellFlags2">268435456</int>
<string key="NSContents">Open empty database on activate</string> <string key="NSContents">Reopen last Database after Launch</string>
<object class="NSFont" key="NSSupport" id="874940307"> <object class="NSFont" key="NSSupport" id="874940307">
<string key="NSName">LucidaGrande</string> <string key="NSName">LucidaGrande</string>
<double key="NSSize">13</double> <double key="NSSize">13</double>
@@ -82,34 +82,6 @@
</object> </object>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool> <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
</object> </object>
<object class="NSButton" id="297534459">
<reference key="NSNextResponder" ref="1005"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{18, 194}, {226, 18}}</string>
<reference key="NSSuperview" ref="1005"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="145041823"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<string key="NSHuggingPriority">{250, 253}</string>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="197992074">
<int key="NSCellFlags">-1543503872</int>
<int key="NSCellFlags2">268435456</int>
<string key="NSContents">Open empty database on launch</string>
<reference key="NSSupport" ref="874940307"/>
<string key="NSCellIdentifier">_NS:9</string>
<reference key="NSControlView" ref="297534459"/>
<int key="NSButtonFlags">1211912448</int>
<int key="NSButtonFlags2">2</int>
<reference key="NSNormalImage" ref="125685135"/>
<reference key="NSAlternateImage" ref="765261007"/>
<string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/>
<int key="NSPeriodicDelay">200</int>
<int key="NSPeriodicInterval">25</int>
</object>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
</object>
<object class="NSBox" id="60918609"> <object class="NSBox" id="60918609">
<reference key="NSNextResponder" ref="1005"/> <reference key="NSNextResponder" ref="1005"/>
<int key="NSvFlags">12</int> <int key="NSvFlags">12</int>
@@ -121,7 +93,7 @@
<object class="NSTextField" id="958810247"> <object class="NSTextField" id="958810247">
<reference key="NSNextResponder" ref="731672371"/> <reference key="NSNextResponder" ref="731672371"/>
<int key="NSvFlags">268</int> <int key="NSvFlags">268</int>
<string key="NSFrame">{{15, 96}, {170, 17}}</string> <string key="NSFrame">{{15, 96}, {124, 17}}</string>
<reference key="NSSuperview" ref="731672371"/> <reference key="NSSuperview" ref="731672371"/>
<reference key="NSWindow"/> <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="222890410"/> <reference key="NSNextKeyView" ref="222890410"/>
@@ -158,7 +130,7 @@
<object class="NSPopUpButton" id="222890410"> <object class="NSPopUpButton" id="222890410">
<reference key="NSNextResponder" ref="731672371"/> <reference key="NSNextResponder" ref="731672371"/>
<int key="NSvFlags">268</int> <int key="NSvFlags">268</int>
<string key="NSFrame">{{237, 92}, {112, 23}}</string> <string key="NSFrame">{{179, 92}, {170, 23}}</string>
<reference key="NSSuperview" ref="731672371"/> <reference key="NSSuperview" ref="731672371"/>
<reference key="NSWindow"/> <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="326334884"/> <reference key="NSNextKeyView" ref="326334884"/>
@@ -200,7 +172,7 @@
<reference ref="855032005"/> <reference ref="855032005"/>
<object class="NSMenuItem" id="303393620"> <object class="NSMenuItem" id="303393620">
<reference key="NSMenu" ref="437492746"/> <reference key="NSMenu" ref="437492746"/>
<string key="NSTitle">10 Seconds</string> <string key="NSTitle">after 10 Seconds</string>
<string key="NSKeyEquiv"/> <string key="NSKeyEquiv"/>
<int key="NSKeyEquivModMask">1048576</int> <int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int> <int key="NSMnemonicLoc">2147483647</int>
@@ -212,7 +184,7 @@
</object> </object>
<object class="NSMenuItem" id="460415455"> <object class="NSMenuItem" id="460415455">
<reference key="NSMenu" ref="437492746"/> <reference key="NSMenu" ref="437492746"/>
<string key="NSTitle">30 Seconds</string> <string key="NSTitle">after 30 Seconds</string>
<string key="NSKeyEquiv"/> <string key="NSKeyEquiv"/>
<int key="NSKeyEquivModMask">1048576</int> <int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int> <int key="NSMnemonicLoc">2147483647</int>
@@ -224,7 +196,7 @@
</object> </object>
<object class="NSMenuItem" id="678942088"> <object class="NSMenuItem" id="678942088">
<reference key="NSMenu" ref="437492746"/> <reference key="NSMenu" ref="437492746"/>
<string key="NSTitle">1 Minute</string> <string key="NSTitle">after 1 Minute</string>
<string key="NSKeyEquiv"/> <string key="NSKeyEquiv"/>
<int key="NSKeyEquivModMask">1048576</int> <int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int> <int key="NSMnemonicLoc">2147483647</int>
@@ -248,7 +220,7 @@
<object class="NSButton" id="326334884"> <object class="NSButton" id="326334884">
<reference key="NSNextResponder" ref="731672371"/> <reference key="NSNextResponder" ref="731672371"/>
<int key="NSvFlags">268</int> <int key="NSvFlags">268</int>
<string key="NSFrame">{{16, 70}, {172, 18}}</string> <string key="NSFrame">{{31, 72}, {172, 18}}</string>
<reference key="NSSuperview" ref="731672371"/> <reference key="NSSuperview" ref="731672371"/>
<reference key="NSWindow"/> <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="982397212"/> <reference key="NSNextKeyView" ref="982397212"/>
@@ -276,7 +248,7 @@
<object class="NSPopUpButton" id="272904029"> <object class="NSPopUpButton" id="272904029">
<reference key="NSNextResponder" ref="731672371"/> <reference key="NSNextResponder" ref="731672371"/>
<int key="NSvFlags">268</int> <int key="NSvFlags">268</int>
<string key="NSFrame">{{237, 32}, {112, 26}}</string> <string key="NSFrame">{{179, 33}, {170, 26}}</string>
<reference key="NSSuperview" ref="731672371"/> <reference key="NSSuperview" ref="731672371"/>
<reference key="NSWindow"/> <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="1066302408"/> <reference key="NSNextKeyView" ref="1066302408"/>
@@ -360,7 +332,7 @@
<object class="NSButton" id="1066302408"> <object class="NSButton" id="1066302408">
<reference key="NSNextResponder" ref="731672371"/> <reference key="NSNextResponder" ref="731672371"/>
<int key="NSvFlags">268</int> <int key="NSvFlags">268</int>
<string key="NSFrame">{{16, 12}, {122, 18}}</string> <string key="NSFrame">{{31, 12}, {122, 18}}</string>
<reference key="NSSuperview" ref="731672371"/> <reference key="NSSuperview" ref="731672371"/>
<reference key="NSWindow"/> <reference key="NSWindow"/>
<string key="NSReuseIdentifierKey">_NS:9</string> <string key="NSReuseIdentifierKey">_NS:9</string>
@@ -386,7 +358,7 @@
<object class="NSTextField" id="982397212"> <object class="NSTextField" id="982397212">
<reference key="NSNextResponder" ref="731672371"/> <reference key="NSNextResponder" ref="731672371"/>
<int key="NSvFlags">268</int> <int key="NSvFlags">268</int>
<string key="NSFrame">{{18, 38}, {98, 17}}</string> <string key="NSFrame">{{15, 38}, {98, 17}}</string>
<reference key="NSSuperview" ref="731672371"/> <reference key="NSSuperview" ref="731672371"/>
<reference key="NSWindow"/> <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="272904029"/> <reference key="NSNextKeyView" ref="272904029"/>
@@ -453,7 +425,7 @@
<string key="NSFrameSize">{400, 230}</string> <string key="NSFrameSize">{400, 230}</string>
<reference key="NSSuperview"/> <reference key="NSSuperview"/>
<reference key="NSWindow"/> <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="297534459"/> <reference key="NSNextKeyView" ref="145041823"/>
<string key="NSClassName">NSView</string> <string key="NSClassName">NSView</string>
</object> </object>
</array> </array>
@@ -499,6 +471,14 @@
</object> </object>
<int key="connectionID">810</int> <int key="connectionID">810</int>
</object> </object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">reopenLastDatabase</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="145041823"/>
</object>
<int key="connectionID">878</int>
</object>
</array> </array>
<object class="IBMutableOrderedSet" key="objectRecords"> <object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects"> <array key="orderedObjects">
@@ -530,6 +510,22 @@
<int key="objectID">1</int> <int key="objectID">1</int>
<reference key="object" ref="1005"/> <reference key="object" ref="1005"/>
<array class="NSMutableArray" key="children"> <array class="NSMutableArray" key="children">
<object class="IBNSLayoutConstraint" id="505875569">
<reference key="firstItem" ref="60918609"/>
<int key="firstAttribute">3</int>
<int key="relation">0</int>
<reference key="secondItem" ref="1005"/>
<int key="secondAttribute">3</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">74</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="1005"/>
<int key="scoringType">3</int>
<float key="scoringTypeFloat">9</float>
<int key="contentType">3</int>
</object>
<object class="IBNSLayoutConstraint" id="213536579"> <object class="IBNSLayoutConstraint" id="213536579">
<reference key="firstItem" ref="1005"/> <reference key="firstItem" ref="1005"/>
<int key="firstAttribute">4</int> <int key="firstAttribute">4</int>
@@ -546,38 +542,6 @@
<float key="scoringTypeFloat">29</float> <float key="scoringTypeFloat">29</float>
<int key="contentType">3</int> <int key="contentType">3</int>
</object> </object>
<object class="IBNSLayoutConstraint" id="528706521">
<reference key="firstItem" ref="1005"/>
<int key="firstAttribute">4</int>
<int key="relation">1</int>
<reference key="secondItem" ref="60918609"/>
<int key="secondAttribute">4</int>
<float key="multiplier">1</float>
<object class="IBNSLayoutSymbolicConstant" key="constant">
<double key="value">20</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="1005"/>
<int key="scoringType">9</int>
<float key="scoringTypeFloat">40</float>
<int key="contentType">3</int>
</object>
<object class="IBNSLayoutConstraint" id="19198291">
<reference key="firstItem" ref="60918609"/>
<int key="firstAttribute">3</int>
<int key="relation">0</int>
<reference key="secondItem" ref="145041823"/>
<int key="secondAttribute">4</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">20</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="1005"/>
<int key="scoringType">9</int>
<float key="scoringTypeFloat">40</float>
<int key="contentType">3</int>
</object>
<object class="IBNSLayoutConstraint" id="484547610"> <object class="IBNSLayoutConstraint" id="484547610">
<reference key="firstItem" ref="1005"/> <reference key="firstItem" ref="1005"/>
<int key="firstAttribute">6</int> <int key="firstAttribute">6</int>
@@ -610,56 +574,24 @@
<float key="scoringTypeFloat">40</float> <float key="scoringTypeFloat">40</float>
<int key="contentType">3</int> <int key="contentType">3</int>
</object> </object>
<object class="IBNSLayoutConstraint" id="343337820"> <object class="IBNSLayoutConstraint" id="119736576">
<reference key="firstItem" ref="145041823"/> <reference key="firstItem" ref="145041823"/>
<int key="firstAttribute">3</int> <int key="firstAttribute">3</int>
<int key="relation">0</int> <int key="relation">0</int>
<reference key="secondItem" ref="297534459"/>
<int key="secondAttribute">4</int>
<float key="multiplier">1</float>
<object class="IBNSLayoutSymbolicConstant" key="constant">
<double key="value">6</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="1005"/>
<int key="scoringType">9</int>
<float key="scoringTypeFloat">40</float>
<int key="contentType">3</int>
</object>
<object class="IBNSLayoutConstraint" id="1065146703">
<reference key="firstItem" ref="145041823"/>
<int key="firstAttribute">5</int>
<int key="relation">0</int>
<reference key="secondItem" ref="1005"/>
<int key="secondAttribute">5</int>
<float key="multiplier">1</float>
<object class="IBNSLayoutSymbolicConstant" key="constant">
<double key="value">20</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="1005"/>
<int key="scoringType">8</int>
<float key="scoringTypeFloat">29</float>
<int key="contentType">3</int>
</object>
<object class="IBNSLayoutConstraint" id="799708645">
<reference key="firstItem" ref="297534459"/>
<int key="firstAttribute">3</int>
<int key="relation">0</int>
<reference key="secondItem" ref="1005"/> <reference key="secondItem" ref="1005"/>
<int key="secondAttribute">3</int> <int key="secondAttribute">3</int>
<float key="multiplier">1</float> <float key="multiplier">1</float>
<object class="IBNSLayoutSymbolicConstant" key="constant"> <object class="IBLayoutConstant" key="constant">
<double key="value">20</double> <double key="value">37</double>
</object> </object>
<float key="priority">1000</float> <float key="priority">1000</float>
<reference key="containingView" ref="1005"/> <reference key="containingView" ref="1005"/>
<int key="scoringType">9</int> <int key="scoringType">3</int>
<float key="scoringTypeFloat">40</float> <float key="scoringTypeFloat">9</float>
<int key="contentType">3</int> <int key="contentType">3</int>
</object> </object>
<object class="IBNSLayoutConstraint" id="285907299"> <object class="IBNSLayoutConstraint" id="1065146703">
<reference key="firstItem" ref="297534459"/> <reference key="firstItem" ref="145041823"/>
<int key="firstAttribute">5</int> <int key="firstAttribute">5</int>
<int key="relation">0</int> <int key="relation">0</int>
<reference key="secondItem" ref="1005"/> <reference key="secondItem" ref="1005"/>
@@ -708,7 +640,6 @@
</object> </object>
<reference ref="60918609"/> <reference ref="60918609"/>
<reference ref="145041823"/> <reference ref="145041823"/>
<reference ref="297534459"/>
</array> </array>
<reference key="parent" ref="0"/> <reference key="parent" ref="0"/>
</object> </object>
@@ -716,7 +647,23 @@
<int key="objectID">465</int> <int key="objectID">465</int>
<reference key="object" ref="60918609"/> <reference key="object" ref="60918609"/>
<array class="NSMutableArray" key="children"> <array class="NSMutableArray" key="children">
<object class="IBNSLayoutConstraint" id="370071994"> <object class="IBNSLayoutConstraint" id="771059501">
<reference key="firstItem" ref="60918609"/>
<int key="firstAttribute">6</int>
<int key="relation">0</int>
<reference key="secondItem" ref="272904029"/>
<int key="secondAttribute">6</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">16</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="60918609"/>
<int key="scoringType">8</int>
<float key="scoringTypeFloat">29</float>
<int key="contentType">3</int>
</object>
<object class="IBNSLayoutConstraint" id="920770187">
<reference key="firstItem" ref="60918609"/> <reference key="firstItem" ref="60918609"/>
<int key="firstAttribute">4</int> <int key="firstAttribute">4</int>
<int key="relation">0</int> <int key="relation">0</int>
@@ -724,7 +671,7 @@
<int key="secondAttribute">4</int> <int key="secondAttribute">4</int>
<float key="multiplier">1</float> <float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant"> <object class="IBLayoutConstant" key="constant">
<double key="value">32</double> <double key="value">33</double>
</object> </object>
<float key="priority">1000</float> <float key="priority">1000</float>
<reference key="containingView" ref="60918609"/> <reference key="containingView" ref="60918609"/>
@@ -733,10 +680,10 @@
<int key="contentType">3</int> <int key="contentType">3</int>
</object> </object>
<object class="IBNSLayoutConstraint" id="459585909"> <object class="IBNSLayoutConstraint" id="459585909">
<reference key="firstItem" ref="272904029"/> <reference key="firstItem" ref="222890410"/>
<int key="firstAttribute">5</int> <int key="firstAttribute">5</int>
<int key="relation">0</int> <int key="relation">0</int>
<reference key="secondItem" ref="222890410"/> <reference key="secondItem" ref="272904029"/>
<int key="secondAttribute">5</int> <int key="secondAttribute">5</int>
<float key="multiplier">1</float> <float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant"> <object class="IBLayoutConstant" key="constant">
@@ -748,11 +695,11 @@
<float key="scoringTypeFloat">24</float> <float key="scoringTypeFloat">24</float>
<int key="contentType">2</int> <int key="contentType">2</int>
</object> </object>
<object class="IBNSLayoutConstraint" id="771059501"> <object class="IBNSLayoutConstraint" id="437525640">
<reference key="firstItem" ref="60918609"/> <reference key="firstItem" ref="60918609"/>
<int key="firstAttribute">6</int> <int key="firstAttribute">6</int>
<int key="relation">0</int> <int key="relation">0</int>
<reference key="secondItem" ref="272904029"/> <reference key="secondItem" ref="222890410"/>
<int key="secondAttribute">6</int> <int key="secondAttribute">6</int>
<float key="multiplier">1</float> <float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant"> <object class="IBLayoutConstant" key="constant">
@@ -780,37 +727,21 @@
<float key="scoringTypeFloat">24</float> <float key="scoringTypeFloat">24</float>
<int key="contentType">2</int> <int key="contentType">2</int>
</object> </object>
<object class="IBNSLayoutConstraint" id="811582841"> <object class="IBNSLayoutConstraint" id="1043261939">
<reference key="firstItem" ref="222890410"/> <reference key="firstItem" ref="1066302408"/>
<int key="firstAttribute">5</int> <int key="firstAttribute">5</int>
<int key="relation">0</int> <int key="relation">0</int>
<reference key="secondItem" ref="958810247"/> <reference key="secondItem" ref="326334884"/>
<int key="secondAttribute">6</int> <int key="secondAttribute">5</int>
<float key="multiplier">1</float> <float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant"> <object class="IBLayoutConstant" key="constant">
<double key="value">57</double> <double key="value">0.0</double>
</object> </object>
<float key="priority">1000</float> <float key="priority">1000</float>
<reference key="containingView" ref="60918609"/> <reference key="containingView" ref="60918609"/>
<int key="scoringType">9</int> <int key="scoringType">6</int>
<float key="scoringTypeFloat">40</float> <float key="scoringTypeFloat">24</float>
<int key="contentType">3</int> <int key="contentType">2</int>
</object>
<object class="IBNSLayoutConstraint" id="520285939">
<reference key="firstItem" ref="60918609"/>
<int key="firstAttribute">6</int>
<int key="relation">0</int>
<reference key="secondItem" ref="222890410"/>
<int key="secondAttribute">6</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">16</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="60918609"/>
<int key="scoringType">9</int>
<float key="scoringTypeFloat">40</float>
<int key="contentType">3</int>
</object> </object>
<object class="IBNSLayoutConstraint" id="806133159"> <object class="IBNSLayoutConstraint" id="806133159">
<reference key="firstItem" ref="60918609"/> <reference key="firstItem" ref="60918609"/>
@@ -845,7 +776,7 @@
<int key="contentType">3</int> <int key="contentType">3</int>
</object> </object>
<object class="IBNSLayoutConstraint" id="476689522"> <object class="IBNSLayoutConstraint" id="476689522">
<reference key="firstItem" ref="1066302408"/> <reference key="firstItem" ref="982397212"/>
<int key="firstAttribute">5</int> <int key="firstAttribute">5</int>
<int key="relation">0</int> <int key="relation">0</int>
<reference key="secondItem" ref="60918609"/> <reference key="secondItem" ref="60918609"/>
@@ -860,12 +791,12 @@
<float key="scoringTypeFloat">29</float> <float key="scoringTypeFloat">29</float>
<int key="contentType">3</int> <int key="contentType">3</int>
</object> </object>
<object class="IBNSLayoutConstraint" id="287888619"> <object class="IBNSLayoutConstraint" id="1037442692">
<reference key="firstItem" ref="982397212"/> <reference key="firstItem" ref="982397212"/>
<int key="firstAttribute">11</int> <int key="firstAttribute">10</int>
<int key="relation">0</int> <int key="relation">0</int>
<reference key="secondItem" ref="272904029"/> <reference key="secondItem" ref="272904029"/>
<int key="secondAttribute">11</int> <int key="secondAttribute">10</int>
<float key="multiplier">1</float> <float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant"> <object class="IBLayoutConstant" key="constant">
<double key="value">0.0</double> <double key="value">0.0</double>
@@ -876,15 +807,15 @@
<float key="scoringTypeFloat">24</float> <float key="scoringTypeFloat">24</float>
<int key="contentType">2</int> <int key="contentType">2</int>
</object> </object>
<object class="IBNSLayoutConstraint" id="561950720"> <object class="IBNSLayoutConstraint" id="236685633">
<reference key="firstItem" ref="982397212"/> <reference key="firstItem" ref="326334884"/>
<int key="firstAttribute">5</int> <int key="firstAttribute">5</int>
<int key="relation">0</int> <int key="relation">0</int>
<reference key="secondItem" ref="60918609"/> <reference key="secondItem" ref="60918609"/>
<int key="secondAttribute">5</int> <int key="secondAttribute">5</int>
<float key="multiplier">1</float> <float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant"> <object class="IBLayoutConstant" key="constant">
<double key="value">19</double> <double key="value">31</double>
</object> </object>
<float key="priority">1000</float> <float key="priority">1000</float>
<reference key="containingView" ref="60918609"/> <reference key="containingView" ref="60918609"/>
@@ -892,36 +823,20 @@
<float key="scoringTypeFloat">9</float> <float key="scoringTypeFloat">9</float>
<int key="contentType">3</int> <int key="contentType">3</int>
</object> </object>
<object class="IBNSLayoutConstraint" id="376978074"> <object class="IBNSLayoutConstraint" id="933426524">
<reference key="firstItem" ref="326334884"/> <reference key="firstItem" ref="326334884"/>
<int key="firstAttribute">3</int> <int key="firstAttribute">3</int>
<int key="relation">0</int> <int key="relation">0</int>
<reference key="secondItem" ref="958810247"/> <reference key="secondItem" ref="958810247"/>
<int key="secondAttribute">4</int> <int key="secondAttribute">4</int>
<float key="multiplier">1</float> <float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant"> <object class="IBNSLayoutSymbolicConstant" key="constant">
<double key="value">10</double> <double key="value">8</double>
</object> </object>
<float key="priority">1000</float> <float key="priority">1000</float>
<reference key="containingView" ref="60918609"/> <reference key="containingView" ref="60918609"/>
<int key="scoringType">9</int> <int key="scoringType">6</int>
<float key="scoringTypeFloat">40</float> <float key="scoringTypeFloat">24</float>
<int key="contentType">3</int>
</object>
<object class="IBNSLayoutConstraint" id="467548005">
<reference key="firstItem" ref="326334884"/>
<int key="firstAttribute">5</int>
<int key="relation">0</int>
<reference key="secondItem" ref="60918609"/>
<int key="secondAttribute">5</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">16</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="60918609"/>
<int key="scoringType">8</int>
<float key="scoringTypeFloat">29</float>
<int key="contentType">3</int> <int key="contentType">3</int>
</object> </object>
<object class="IBNSLayoutConstraint" id="432174165"> <object class="IBNSLayoutConstraint" id="432174165">
@@ -973,11 +888,11 @@
<int key="contentType">3</int> <int key="contentType">3</int>
</object> </object>
<reference ref="958810247"/> <reference ref="958810247"/>
<reference ref="326334884"/> <reference ref="982397212"/>
<reference ref="272904029"/> <reference ref="272904029"/>
<reference ref="326334884"/>
<reference ref="1066302408"/> <reference ref="1066302408"/>
<reference ref="222890410"/> <reference ref="222890410"/>
<reference ref="982397212"/>
</array> </array>
<reference key="parent" ref="1005"/> <reference key="parent" ref="1005"/>
</object> </object>
@@ -1020,7 +935,7 @@
<reference key="object" ref="222890410"/> <reference key="object" ref="222890410"/>
<array class="NSMutableArray" key="children"> <array class="NSMutableArray" key="children">
<reference ref="934584997"/> <reference ref="934584997"/>
<object class="IBNSLayoutConstraint" id="943587685"> <object class="IBNSLayoutConstraint" id="777025190">
<reference key="firstItem" ref="222890410"/> <reference key="firstItem" ref="222890410"/>
<int key="firstAttribute">7</int> <int key="firstAttribute">7</int>
<int key="relation">0</int> <int key="relation">0</int>
@@ -1028,7 +943,7 @@
<int key="secondAttribute">0</int> <int key="secondAttribute">0</int>
<float key="multiplier">1</float> <float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant"> <object class="IBLayoutConstant" key="constant">
<double key="value">107</double> <double key="value">165</double>
</object> </object>
<float key="priority">1000</float> <float key="priority">1000</float>
<reference key="containingView" ref="222890410"/> <reference key="containingView" ref="222890410"/>
@@ -1112,34 +1027,6 @@
<reference key="object" ref="891799107"/> <reference key="object" ref="891799107"/>
<reference key="parent" ref="60918609"/> <reference key="parent" ref="60918609"/>
</object> </object>
<object class="IBObjectRecord">
<int key="objectID">506</int>
<reference key="object" ref="520285939"/>
<reference key="parent" ref="60918609"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">509</int>
<reference key="object" ref="811582841"/>
<reference key="parent" ref="60918609"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">526</int>
<reference key="object" ref="297534459"/>
<array class="NSMutableArray" key="children">
<reference ref="197992074"/>
</array>
<reference key="parent" ref="1005"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">527</int>
<reference key="object" ref="197992074"/>
<reference key="parent" ref="297534459"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">528</int>
<reference key="object" ref="285907299"/>
<reference key="parent" ref="1005"/>
</object>
<object class="IBObjectRecord"> <object class="IBObjectRecord">
<int key="objectID">530</int> <int key="objectID">530</int>
<reference key="object" ref="145041823"/> <reference key="object" ref="145041823"/>
@@ -1158,16 +1045,6 @@
<reference key="object" ref="1065146703"/> <reference key="object" ref="1065146703"/>
<reference key="parent" ref="1005"/> <reference key="parent" ref="1005"/>
</object> </object>
<object class="IBObjectRecord">
<int key="objectID">535</int>
<reference key="object" ref="343337820"/>
<reference key="parent" ref="1005"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">536</int>
<reference key="object" ref="799708645"/>
<reference key="parent" ref="1005"/>
</object>
<object class="IBObjectRecord"> <object class="IBObjectRecord">
<int key="objectID">584</int> <int key="objectID">584</int>
<reference key="object" ref="272904029"/> <reference key="object" ref="272904029"/>
@@ -1210,16 +1087,6 @@
<reference key="object" ref="328220222"/> <reference key="object" ref="328220222"/>
<reference key="parent" ref="552398563"/> <reference key="parent" ref="552398563"/>
</object> </object>
<object class="IBObjectRecord">
<int key="objectID">660</int>
<reference key="object" ref="467548005"/>
<reference key="parent" ref="60918609"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">664</int>
<reference key="object" ref="943587685"/>
<reference key="parent" ref="222890410"/>
</object>
<object class="IBObjectRecord"> <object class="IBObjectRecord">
<int key="objectID">630</int> <int key="objectID">630</int>
<reference key="object" ref="1066302408"/> <reference key="object" ref="1066302408"/>
@@ -1233,26 +1100,6 @@
<reference key="object" ref="252113219"/> <reference key="object" ref="252113219"/>
<reference key="parent" ref="1066302408"/> <reference key="parent" ref="1066302408"/>
</object> </object>
<object class="IBObjectRecord">
<int key="objectID">706</int>
<reference key="object" ref="771059501"/>
<reference key="parent" ref="60918609"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">708</int>
<reference key="object" ref="459585909"/>
<reference key="parent" ref="60918609"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">718</int>
<reference key="object" ref="476689522"/>
<reference key="parent" ref="60918609"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">759</int>
<reference key="object" ref="376978074"/>
<reference key="parent" ref="60918609"/>
</object>
<object class="IBObjectRecord"> <object class="IBObjectRecord">
<int key="objectID">773</int> <int key="objectID">773</int>
<reference key="object" ref="871797750"/> <reference key="object" ref="871797750"/>
@@ -1288,11 +1135,6 @@
<reference key="object" ref="806133159"/> <reference key="object" ref="806133159"/>
<reference key="parent" ref="60918609"/> <reference key="parent" ref="60918609"/>
</object> </object>
<object class="IBObjectRecord">
<int key="objectID">802</int>
<reference key="object" ref="370071994"/>
<reference key="parent" ref="60918609"/>
</object>
<object class="IBObjectRecord"> <object class="IBObjectRecord">
<int key="objectID">803</int> <int key="objectID">803</int>
<reference key="object" ref="15468834"/> <reference key="object" ref="15468834"/>
@@ -1317,40 +1159,80 @@
<reference key="parent" ref="982397212"/> <reference key="parent" ref="982397212"/>
</object> </object>
<object class="IBObjectRecord"> <object class="IBObjectRecord">
<int key="objectID">807</int> <int key="objectID">788</int>
<reference key="object" ref="561950720"/> <reference key="object" ref="772519144"/>
<reference key="parent" ref="60918609"/> <reference key="parent" ref="60918609"/>
</object> </object>
<object class="IBObjectRecord"> <object class="IBObjectRecord">
<int key="objectID">808</int> <int key="objectID">840</int>
<reference key="object" ref="287888619"/>
<reference key="parent" ref="60918609"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">537</int>
<reference key="object" ref="19198291"/>
<reference key="parent" ref="1005"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">721</int>
<reference key="object" ref="528706521"/>
<reference key="parent" ref="1005"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">800</int>
<reference key="object" ref="213536579"/> <reference key="object" ref="213536579"/>
<reference key="parent" ref="1005"/> <reference key="parent" ref="1005"/>
</object> </object>
<object class="IBObjectRecord"> <object class="IBObjectRecord">
<int key="objectID">799</int> <int key="objectID">845</int>
<reference key="object" ref="119736576"/>
<reference key="parent" ref="1005"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">846</int>
<reference key="object" ref="505875569"/>
<reference key="parent" ref="1005"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">847</int>
<reference key="object" ref="250630005"/> <reference key="object" ref="250630005"/>
<reference key="parent" ref="1005"/> <reference key="parent" ref="1005"/>
</object> </object>
<object class="IBObjectRecord"> <object class="IBObjectRecord">
<int key="objectID">788</int> <int key="objectID">861</int>
<reference key="object" ref="772519144"/> <reference key="object" ref="1037442692"/>
<reference key="parent" ref="60918609"/> <reference key="parent" ref="60918609"/>
</object> </object>
<object class="IBObjectRecord">
<int key="objectID">862</int>
<reference key="object" ref="920770187"/>
<reference key="parent" ref="60918609"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">867</int>
<reference key="object" ref="933426524"/>
<reference key="parent" ref="60918609"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">868</int>
<reference key="object" ref="1043261939"/>
<reference key="parent" ref="60918609"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">870</int>
<reference key="object" ref="476689522"/>
<reference key="parent" ref="60918609"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">871</int>
<reference key="object" ref="236685633"/>
<reference key="parent" ref="60918609"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">873</int>
<reference key="object" ref="771059501"/>
<reference key="parent" ref="60918609"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">875</int>
<reference key="object" ref="437525640"/>
<reference key="parent" ref="60918609"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">876</int>
<reference key="object" ref="459585909"/>
<reference key="parent" ref="60918609"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">877</int>
<reference key="object" ref="777025190"/>
<reference key="parent" ref="222890410"/>
</object>
</array> </array>
</object> </object>
<dictionary class="NSMutableDictionary" key="flattenedProperties"> <dictionary class="NSMutableDictionary" key="flattenedProperties">
@@ -1360,21 +1242,18 @@
<array key="1.IBNSViewMetadataConstraints"> <array key="1.IBNSViewMetadataConstraints">
<reference ref="1063893674"/> <reference ref="1063893674"/>
<reference ref="250630005"/> <reference ref="250630005"/>
<reference ref="285907299"/>
<reference ref="799708645"/>
<reference ref="1065146703"/> <reference ref="1065146703"/>
<reference ref="343337820"/> <reference ref="119736576"/>
<reference ref="989429017"/> <reference ref="989429017"/>
<reference ref="484547610"/> <reference ref="484547610"/>
<reference ref="19198291"/>
<reference ref="528706521"/>
<reference ref="213536579"/> <reference ref="213536579"/>
<reference ref="505875569"/>
</array> </array>
<boolean value="NO" key="1.IBNSViewMetadataLastInspectedTranslatesAutoresizingMaskIntoConstraints"/> <boolean value="NO" key="1.IBNSViewMetadataLastInspectedTranslatesAutoresizingMaskIntoConstraints"/>
<boolean value="NO" key="1.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/> <boolean value="NO" key="1.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
<string key="1.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="1.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<array key="419.IBNSViewMetadataConstraints"> <array key="419.IBNSViewMetadataConstraints">
<reference ref="943587685"/> <reference ref="777025190"/>
</array> </array>
<boolean value="NO" key="419.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/> <boolean value="NO" key="419.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
<string key="419.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="419.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -1400,38 +1279,28 @@
<reference ref="891799107"/> <reference ref="891799107"/>
<reference ref="1014678196"/> <reference ref="1014678196"/>
<reference ref="432174165"/> <reference ref="432174165"/>
<reference ref="467548005"/> <reference ref="933426524"/>
<reference ref="376978074"/> <reference ref="236685633"/>
<reference ref="561950720"/> <reference ref="1037442692"/>
<reference ref="287888619"/>
<reference ref="476689522"/> <reference ref="476689522"/>
<reference ref="772519144"/> <reference ref="772519144"/>
<reference ref="806133159"/> <reference ref="806133159"/>
<reference ref="520285939"/> <reference ref="1043261939"/>
<reference ref="811582841"/>
<reference ref="311160635"/> <reference ref="311160635"/>
<reference ref="771059501"/> <reference ref="437525640"/>
<reference ref="459585909"/> <reference ref="459585909"/>
<reference ref="370071994"/> <reference ref="920770187"/>
<reference ref="771059501"/>
</array> </array>
<boolean value="NO" key="465.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/> <boolean value="NO" key="465.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
<string key="465.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="465.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="475.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="475.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="499.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="499.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="506.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="509.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="525.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="525.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="NO" key="526.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
<string key="526.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="527.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="528.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="NO" key="530.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/> <boolean value="NO" key="530.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
<string key="530.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="530.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="531.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="531.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="532.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="532.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="535.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="536.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="537.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="NO" key="584.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/> <boolean value="NO" key="584.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
<string key="584.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="584.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="585.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="585.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -1442,36 +1311,38 @@
<boolean value="NO" key="630.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/> <boolean value="NO" key="630.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
<string key="630.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="630.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="631.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="631.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="660.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="664.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="706.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="708.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="718.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="721.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="759.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="773.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="773.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="784.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="784.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="788.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="788.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="789.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="789.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="792.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="792.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="798.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="798.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="799.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="800.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="801.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="801.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="802.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="803.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="803.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="804.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="804.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="NO" key="805.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/> <boolean value="NO" key="805.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
<string key="805.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="805.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="806.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="806.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="807.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="840.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="808.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="845.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="846.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="847.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="861.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="862.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="867.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="868.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="870.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="871.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="873.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="875.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="876.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="877.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
</dictionary> </dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/> <dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/> <nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/> <dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/> <nil key="sourceID"/>
<int key="maxID">814</int> <int key="maxID">878</int>
</object> </object>
<object class="IBClassDescriber" key="IBDocument.Classes"> <object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions"> <array class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -1483,6 +1354,7 @@
<string key="clearPasteboardTimeoutPopup">NSPopUpButton</string> <string key="clearPasteboardTimeoutPopup">NSPopUpButton</string>
<string key="idleTimeOutPopup">NSPopUpButton</string> <string key="idleTimeOutPopup">NSPopUpButton</string>
<string key="lockOnSleepCheckButton">NSButton</string> <string key="lockOnSleepCheckButton">NSButton</string>
<string key="reopenLastDatabase">NSButton</string>
</dictionary> </dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName"> <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="clearPasteboardOnQuitCheckButton"> <object class="IBToOneOutletInfo" key="clearPasteboardOnQuitCheckButton">
@@ -1501,6 +1373,10 @@
<string key="name">lockOnSleepCheckButton</string> <string key="name">lockOnSleepCheckButton</string>
<string key="candidateClassName">NSButton</string> <string key="candidateClassName">NSButton</string>
</object> </object>
<object class="IBToOneOutletInfo" key="reopenLastDatabase">
<string key="name">reopenLastDatabase</string>
<string key="candidateClassName">NSButton</string>
</object>
</dictionary> </dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier"> <object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string> <string key="majorKey">IBProjectSource</string>

File diff suppressed because it is too large Load Diff

View File

@@ -253,6 +253,24 @@
<reference key="NSOnImage" ref="35465992"/> <reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/> <reference key="NSMixedImage" ref="502551668"/>
</object> </object>
<object class="NSMenuItem" id="663106531">
<reference key="NSMenu" ref="720053764"/>
<string key="NSTitle">Save As…</string>
<string key="NSKeyEquiv">S</string>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
<object class="NSMenuItem" id="438377242">
<reference key="NSMenu" ref="720053764"/>
<string key="NSTitle">Export As XML…</string>
<string key="NSKeyEquiv">E</string>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
<object class="NSMenuItem" id="579971712"> <object class="NSMenuItem" id="579971712">
<reference key="NSMenu" ref="720053764"/> <reference key="NSMenu" ref="720053764"/>
<string key="NSTitle">Revert to Saved</string> <string key="NSTitle">Revert to Saved</string>
@@ -274,7 +292,7 @@
</object> </object>
<object class="NSMenuItem" id="544639599"> <object class="NSMenuItem" id="544639599">
<reference key="NSMenu" ref="720053764"/> <reference key="NSMenu" ref="720053764"/>
<string key="NSTitle">Document Settings…</string> <string key="NSTitle">Database Settings…</string>
<string key="NSKeyEquiv"/> <string key="NSKeyEquiv"/>
<int key="NSMnemonicLoc">2147483647</int> <int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/> <reference key="NSOnImage" ref="35465992"/>
@@ -282,7 +300,7 @@
</object> </object>
<object class="NSMenuItem" id="915918141"> <object class="NSMenuItem" id="915918141">
<reference key="NSMenu" ref="720053764"/> <reference key="NSMenu" ref="720053764"/>
<string key="NSTitle">Change Password…</string> <string key="NSTitle">Change Master Password…</string>
<string key="NSKeyEquiv"/> <string key="NSKeyEquiv"/>
<int key="NSMnemonicLoc">2147483647</int> <int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/> <reference key="NSOnImage" ref="35465992"/>
@@ -788,11 +806,27 @@
</object> </object>
<object class="IBConnectionRecord"> <object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection"> <object class="IBActionConnection" key="connection">
<string key="label">showDocumentSettings:</string> <string key="label">showDatabaseSettings:</string>
<reference key="source" ref="1014"/> <reference key="source" ref="1014"/>
<reference key="destination" ref="544639599"/> <reference key="destination" ref="544639599"/>
</object> </object>
<int key="connectionID">1233</int> <int key="connectionID">1234</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">saveDocumentAs:</string>
<reference key="source" ref="1014"/>
<reference key="destination" ref="663106531"/>
</object>
<int key="connectionID">1255</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">exportDatabase:</string>
<reference key="source" ref="1014"/>
<reference key="destination" ref="438377242"/>
</object>
<int key="connectionID">1260</int>
</object> </object>
<object class="IBConnectionRecord"> <object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection"> <object class="IBActionConnection" key="connection">
@@ -896,6 +930,8 @@
<reference ref="1010469920"/> <reference ref="1010469920"/>
<reference ref="915918141"/> <reference ref="915918141"/>
<reference ref="544639599"/> <reference ref="544639599"/>
<reference ref="663106531"/>
<reference ref="438377242"/>
</array> </array>
<reference key="parent" ref="379814623"/> <reference key="parent" ref="379814623"/>
</object> </object>
@@ -1226,6 +1262,16 @@
<reference key="object" ref="544639599"/> <reference key="object" ref="544639599"/>
<reference key="parent" ref="720053764"/> <reference key="parent" ref="720053764"/>
</object> </object>
<object class="IBObjectRecord">
<int key="objectID">1243</int>
<reference key="object" ref="663106531"/>
<reference key="parent" ref="720053764"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">1259</int>
<reference key="object" ref="438377242"/>
<reference key="parent" ref="720053764"/>
</object>
</array> </array>
</object> </object>
<dictionary class="NSMutableDictionary" key="flattenedProperties"> <dictionary class="NSMutableDictionary" key="flattenedProperties">
@@ -1241,7 +1287,9 @@
<string key="1203.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="1203.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="1231.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="1231.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="124.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="124.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="1243.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="125.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="125.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="1259.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="126.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="126.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="129.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="129.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="130.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="130.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -1298,7 +1346,7 @@
<nil key="activeLocalization"/> <nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/> <dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/> <nil key="sourceID"/>
<int key="maxID">1233</int> <int key="maxID">1260</int>
</object> </object>
<object class="IBClassDescriber" key="IBDocument.Classes"> <object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions"> <array class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -1358,15 +1406,20 @@
<string key="superclassName">NSWindowController</string> <string key="superclassName">NSWindowController</string>
<dictionary class="NSMutableDictionary" key="actions"> <dictionary class="NSMutableDictionary" key="actions">
<string key="editPassword:">id</string> <string key="editPassword:">id</string>
<string key="showDocumentSettings:">id</string> <string key="exportDatabase:">id</string>
<string key="showDatabaseSettings:">id</string>
</dictionary> </dictionary>
<dictionary class="NSMutableDictionary" key="actionInfosByName"> <dictionary class="NSMutableDictionary" key="actionInfosByName">
<object class="IBActionInfo" key="editPassword:"> <object class="IBActionInfo" key="editPassword:">
<string key="name">editPassword:</string> <string key="name">editPassword:</string>
<string key="candidateClassName">id</string> <string key="candidateClassName">id</string>
</object> </object>
<object class="IBActionInfo" key="showDocumentSettings:"> <object class="IBActionInfo" key="exportDatabase:">
<string key="name">showDocumentSettings:</string> <string key="name">exportDatabase:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo" key="showDatabaseSettings:">
<string key="name">showDatabaseSettings:</string>
<string key="candidateClassName">id</string> <string key="candidateClassName">id</string>
</object> </object>
</dictionary> </dictionary>

View File

@@ -1,947 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1080</int>
<string key="IBDocument.SystemVersion">12E55</string>
<string key="IBDocument.InterfaceBuilderVersion">3084</string>
<string key="IBDocument.AppKitVersion">1187.39</string>
<string key="IBDocument.HIToolboxVersion">626.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="NS.object.0">3084</string>
</object>
<array key="IBDocument.IntegratedClassDependencies">
<string>IBNSLayoutConstraint</string>
<string>NSButton</string>
<string>NSButtonCell</string>
<string>NSCustomObject</string>
<string>NSCustomView</string>
<string>NSPathCell</string>
<string>NSPathControl</string>
<string>NSSecureTextField</string>
<string>NSSecureTextFieldCell</string>
<string>NSTextField</string>
<string>NSTextFieldCell</string>
</array>
<array key="IBDocument.PluginDependencies">
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
</array>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<object class="NSCustomObject" id="1001">
<string key="NSClassName">MPPasswordEditViewController</string>
</object>
<object class="NSCustomObject" id="1003">
<string key="NSClassName">FirstResponder</string>
</object>
<object class="NSCustomObject" id="1004">
<string key="NSClassName">NSApplication</string>
</object>
<object class="NSCustomView" id="595834490">
<reference key="NSNextResponder"/>
<int key="NSvFlags">268</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="NSTextField" id="762740216">
<reference key="NSNextResponder" ref="595834490"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{99, 157}, {164, 17}}</string>
<reference key="NSSuperview" ref="595834490"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="847623533"/>
<string key="NSReuseIdentifierKey">_NS:1535</string>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="79241474">
<int key="NSCellFlags">68157504</int>
<int key="NSCellFlags2">272630784</int>
<string key="NSContents">Change Password/Keyfile</string>
<object class="NSFont" key="NSSupport" id="385477987">
<string key="NSName">LucidaGrande</string>
<double key="NSSize">13</double>
<int key="NSfFlags">1044</int>
</object>
<string key="NSCellIdentifier">_NS:1535</string>
<reference key="NSControlView" ref="762740216"/>
<object class="NSColor" key="NSBackgroundColor" id="515490923">
<int key="NSColorSpace">6</int>
<string key="NSCatalogName">System</string>
<string key="NSColorName">controlColor</string>
<object class="NSColor" key="NSColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MC42NjY2NjY2NjY3AA</bytes>
</object>
</object>
<object class="NSColor" key="NSTextColor" id="504890084">
<int key="NSColorSpace">6</int>
<string key="NSCatalogName">System</string>
<string key="NSColorName">controlTextColor</string>
<object class="NSColor" key="NSColor" id="354127501">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MAA</bytes>
</object>
</object>
</object>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
</object>
<object class="NSButton" id="256981522">
<reference key="NSNextResponder" ref="595834490"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{113, 13}, {82, 32}}</string>
<reference key="NSSuperview" ref="595834490"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="771851607"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="69579583">
<int key="NSCellFlags">67108864</int>
<int key="NSCellFlags2">134217728</int>
<string key="NSContents">Cancel</string>
<reference key="NSSupport" ref="385477987"/>
<string key="NSCellIdentifier">_NS:9</string>
<reference key="NSControlView" ref="256981522"/>
<int key="NSButtonFlags">-2038284288</int>
<int key="NSButtonFlags2">129</int>
<string key="NSAlternateContents"/>
<string type="base64-UTF8" key="NSKeyEquivalent">Gw</string>
<int key="NSPeriodicDelay">200</int>
<int key="NSPeriodicInterval">25</int>
</object>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
</object>
<object class="NSPathControl" id="679285412">
<reference key="NSNextResponder" ref="595834490"/>
<int key="NSvFlags">268</int>
<set class="NSMutableSet" key="NSDragTypes">
<string>Apple URL pasteboard type</string>
<string>NSFilenamesPboardType</string>
</set>
<string key="NSFrame">{{83, 57}, {197, 22}}</string>
<reference key="NSSuperview" ref="595834490"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="256981522"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="NSEnabled">YES</bool>
<object class="NSPathCell" key="NSCell" id="902994558">
<int key="NSCellFlags">337641473</int>
<int key="NSCellFlags2">131072</int>
<object class="NSFont" key="NSSupport">
<string key="NSName">LucidaGrande</string>
<double key="NSSize">11</double>
<int key="NSfFlags">3100</int>
</object>
<string key="NSCellIdentifier">_NS:9</string>
<reference key="NSControlView" ref="679285412"/>
<array class="NSMutableArray" key="NSPathComponentCells"/>
<int key="NSPathStyle">2</int>
<reference key="NSDelegate" ref="679285412"/>
</object>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
</object>
<object class="NSSecureTextField" id="670734441">
<reference key="NSNextResponder" ref="595834490"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{86, 86}, {191, 22}}</string>
<reference key="NSSuperview" ref="595834490"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="365869599"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="NSEnabled">YES</bool>
<object class="NSSecureTextFieldCell" key="NSCell" id="656181976">
<int key="NSCellFlags">342884416</int>
<int key="NSCellFlags2">272630848</int>
<string key="NSContents"/>
<reference key="NSSupport" ref="385477987"/>
<string key="NSCellIdentifier">_NS:9</string>
<reference key="NSControlView" ref="670734441"/>
<bool key="NSDrawsBackground">YES</bool>
<object class="NSColor" key="NSBackgroundColor">
<int key="NSColorSpace">6</int>
<string key="NSCatalogName">System</string>
<string key="NSColorName">textBackgroundColor</string>
<object class="NSColor" key="NSColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
</object>
</object>
<object class="NSColor" key="NSTextColor">
<int key="NSColorSpace">6</int>
<string key="NSCatalogName">System</string>
<string key="NSColorName">textColor</string>
<reference key="NSColor" ref="354127501"/>
</object>
<array key="NSAllowedInputLocales">
<string>NSAllRomanInputSourcesLocaleIdentifier</string>
</array>
</object>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
</object>
<object class="NSTextField" id="847623533">
<reference key="NSNextResponder" ref="595834490"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{17, 89}, {64, 17}}</string>
<reference key="NSSuperview" ref="595834490"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="670734441"/>
<string key="NSReuseIdentifierKey">_NS:1535</string>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="792960157">
<int key="NSCellFlags">68157504</int>
<int key="NSCellFlags2">272630784</int>
<string key="NSContents">Password</string>
<reference key="NSSupport" ref="385477987"/>
<string key="NSCellIdentifier">_NS:1535</string>
<reference key="NSControlView" ref="847623533"/>
<reference key="NSBackgroundColor" ref="515490923"/>
<reference key="NSTextColor" ref="504890084"/>
</object>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
</object>
<object class="NSTextField" id="365869599">
<reference key="NSNextResponder" ref="595834490"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{35, 62}, {46, 17}}</string>
<reference key="NSSuperview" ref="595834490"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="679285412"/>
<string key="NSReuseIdentifierKey">_NS:1535</string>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="324335303">
<int key="NSCellFlags">68157504</int>
<int key="NSCellFlags2">272630784</int>
<string key="NSContents">Keyfile</string>
<reference key="NSSupport" ref="385477987"/>
<string key="NSCellIdentifier">_NS:1535</string>
<reference key="NSControlView" ref="365869599"/>
<reference key="NSBackgroundColor" ref="515490923"/>
<reference key="NSTextColor" ref="504890084"/>
</object>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
</object>
<object class="NSButton" id="771851607">
<reference key="NSNextResponder" ref="595834490"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{195, 13}, {88, 32}}</string>
<reference key="NSSuperview" ref="595834490"/>
<reference key="NSWindow"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<string key="NSHuggingPriority">{250, 250}</string>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="251779948">
<int key="NSCellFlags">67108864</int>
<int key="NSCellFlags2">134217728</int>
<string key="NSContents">Change</string>
<reference key="NSSupport" ref="385477987"/>
<string key="NSCellIdentifier">_NS:9</string>
<reference key="NSControlView" ref="771851607"/>
<int key="NSButtonFlags">-2038284288</int>
<int key="NSButtonFlags2">129</int>
<string key="NSAlternateContents"/>
<string type="base64-UTF8" key="NSKeyEquivalent">DQ</string>
<int key="NSPeriodicDelay">200</int>
<int key="NSPeriodicInterval">25</int>
</object>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
</object>
</array>
<string key="NSFrameSize">{363, 194}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="762740216"/>
<string key="NSAntiCompressionPriority">{751, 750}</string>
<string key="NSClassName">NSView</string>
</object>
</array>
<object class="IBObjectContainer" key="IBDocument.Objects">
<array class="NSMutableArray" key="connectionRecords">
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">view</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="595834490"/>
</object>
<int key="connectionID">52</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">passwordTextField</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="670734441"/>
</object>
<int key="connectionID">53</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">keyfilePathControl</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="679285412"/>
</object>
<int key="connectionID">54</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">_change:</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="771851607"/>
</object>
<int key="connectionID">55</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">_cancel:</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="256981522"/>
</object>
<int key="connectionID">56</int>
</object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
<object class="IBObjectRecord">
<int key="objectID">0</int>
<array key="object" id="0"/>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="1001"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="1003"/>
<reference key="parent" ref="0"/>
<string key="objectName">First Responder</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-3</int>
<reference key="object" ref="1004"/>
<reference key="parent" ref="0"/>
<string key="objectName">Application</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">2</int>
<reference key="object" ref="595834490"/>
<array class="NSMutableArray" key="children">
<reference ref="365869599"/>
<reference ref="679285412"/>
<reference ref="670734441"/>
<reference ref="847623533"/>
<reference ref="771851607"/>
<object class="IBNSLayoutConstraint" id="501931119">
<reference key="firstItem" ref="771851607"/>
<int key="firstAttribute">10</int>
<int key="relation">0</int>
<reference key="secondItem" ref="256981522"/>
<int key="secondAttribute">10</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">0.0</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="595834490"/>
<int key="scoringType">9</int>
<float key="scoringTypeFloat">40</float>
<int key="contentType">2</int>
</object>
<object class="IBNSLayoutConstraint" id="1024015372">
<reference key="firstItem" ref="771851607"/>
<int key="firstAttribute">5</int>
<int key="relation">0</int>
<reference key="secondItem" ref="256981522"/>
<int key="secondAttribute">6</int>
<float key="multiplier">1</float>
<object class="IBNSLayoutSymbolicConstant" key="constant">
<double key="value">12</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="595834490"/>
<int key="scoringType">6</int>
<float key="scoringTypeFloat">24</float>
<int key="contentType">3</int>
</object>
<object class="IBNSLayoutConstraint" id="381133690">
<reference key="firstItem" ref="771851607"/>
<int key="firstAttribute">3</int>
<int key="relation">0</int>
<reference key="secondItem" ref="679285412"/>
<int key="secondAttribute">4</int>
<float key="multiplier">1</float>
<object class="IBNSLayoutSymbolicConstant" key="constant">
<double key="value">20</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="595834490"/>
<int key="scoringType">9</int>
<float key="scoringTypeFloat">40</float>
<int key="contentType">3</int>
</object>
<object class="IBNSLayoutConstraint" id="629412806">
<reference key="firstItem" ref="771851607"/>
<int key="firstAttribute">6</int>
<int key="relation">0</int>
<reference key="secondItem" ref="679285412"/>
<int key="secondAttribute">6</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">0.0</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="595834490"/>
<int key="scoringType">6</int>
<float key="scoringTypeFloat">24</float>
<int key="contentType">2</int>
</object>
<object class="IBNSLayoutConstraint" id="176392839">
<reference key="firstItem" ref="595834490"/>
<int key="firstAttribute">4</int>
<int key="relation">1</int>
<reference key="secondItem" ref="771851607"/>
<int key="secondAttribute">4</int>
<float key="multiplier">1</float>
<object class="IBNSLayoutSymbolicConstant" key="constant">
<double key="value">20</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="595834490"/>
<int key="scoringType">9</int>
<float key="scoringTypeFloat">40</float>
<int key="contentType">3</int>
</object>
<object class="IBNSLayoutConstraint" id="340048519">
<reference key="firstItem" ref="679285412"/>
<int key="firstAttribute">5</int>
<int key="relation">0</int>
<reference key="secondItem" ref="365869599"/>
<int key="secondAttribute">6</int>
<float key="multiplier">1</float>
<object class="IBNSLayoutSymbolicConstant" key="constant">
<double key="value">8</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="595834490"/>
<int key="scoringType">6</int>
<float key="scoringTypeFloat">24</float>
<int key="contentType">3</int>
</object>
<object class="IBNSLayoutConstraint" id="33581314">
<reference key="firstItem" ref="679285412"/>
<int key="firstAttribute">6</int>
<int key="relation">0</int>
<reference key="secondItem" ref="670734441"/>
<int key="secondAttribute">6</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">0.0</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="595834490"/>
<int key="scoringType">6</int>
<float key="scoringTypeFloat">24</float>
<int key="contentType">2</int>
</object>
<object class="IBNSLayoutConstraint" id="481322683">
<reference key="firstItem" ref="679285412"/>
<int key="firstAttribute">5</int>
<int key="relation">0</int>
<reference key="secondItem" ref="670734441"/>
<int key="secondAttribute">5</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">0.0</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="595834490"/>
<int key="scoringType">6</int>
<float key="scoringTypeFloat">24</float>
<int key="contentType">2</int>
</object>
<object class="IBNSLayoutConstraint" id="966743814">
<reference key="firstItem" ref="679285412"/>
<int key="firstAttribute">3</int>
<int key="relation">0</int>
<reference key="secondItem" ref="670734441"/>
<int key="secondAttribute">4</int>
<float key="multiplier">1</float>
<object class="IBNSLayoutSymbolicConstant" key="constant">
<double key="value">8</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="595834490"/>
<int key="scoringType">9</int>
<float key="scoringTypeFloat">40</float>
<int key="contentType">3</int>
</object>
<object class="IBNSLayoutConstraint" id="379216952">
<reference key="firstItem" ref="595834490"/>
<int key="firstAttribute">10</int>
<int key="relation">0</int>
<reference key="secondItem" ref="670734441"/>
<int key="secondAttribute">10</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">0.0</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="595834490"/>
<int key="scoringType">9</int>
<float key="scoringTypeFloat">40</float>
<int key="contentType">2</int>
</object>
<object class="IBNSLayoutConstraint" id="612132939">
<reference key="firstItem" ref="670734441"/>
<int key="firstAttribute">5</int>
<int key="relation">0</int>
<reference key="secondItem" ref="847623533"/>
<int key="secondAttribute">6</int>
<float key="multiplier">1</float>
<object class="IBNSLayoutSymbolicConstant" key="constant">
<double key="value">8</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="595834490"/>
<int key="scoringType">9</int>
<float key="scoringTypeFloat">40</float>
<int key="contentType">3</int>
</object>
<object class="IBNSLayoutConstraint" id="485639451">
<reference key="firstItem" ref="595834490"/>
<int key="firstAttribute">9</int>
<int key="relation">0</int>
<reference key="secondItem" ref="670734441"/>
<int key="secondAttribute">9</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">0.0</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="595834490"/>
<int key="scoringType">9</int>
<float key="scoringTypeFloat">40</float>
<int key="contentType">2</int>
</object>
<object class="IBNSLayoutConstraint" id="51218896">
<reference key="firstItem" ref="670734441"/>
<int key="firstAttribute">10</int>
<int key="relation">0</int>
<reference key="secondItem" ref="847623533"/>
<int key="secondAttribute">10</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">0.0</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="595834490"/>
<int key="scoringType">6</int>
<float key="scoringTypeFloat">24</float>
<int key="contentType">2</int>
</object>
<object class="IBNSLayoutConstraint" id="910263208">
<reference key="firstItem" ref="365869599"/>
<int key="firstAttribute">11</int>
<int key="relation">0</int>
<reference key="secondItem" ref="679285412"/>
<int key="secondAttribute">11</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">0.0</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="595834490"/>
<int key="scoringType">6</int>
<float key="scoringTypeFloat">24</float>
<int key="contentType">2</int>
</object>
<object class="IBNSLayoutConstraint" id="575391720">
<reference key="firstItem" ref="762740216"/>
<int key="firstAttribute">3</int>
<int key="relation">0</int>
<reference key="secondItem" ref="595834490"/>
<int key="secondAttribute">3</int>
<float key="multiplier">1</float>
<object class="IBNSLayoutSymbolicConstant" key="constant">
<double key="value">20</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="595834490"/>
<int key="scoringType">8</int>
<float key="scoringTypeFloat">29</float>
<int key="contentType">3</int>
</object>
<object class="IBNSLayoutConstraint" id="335749536">
<reference key="firstItem" ref="762740216"/>
<int key="firstAttribute">9</int>
<int key="relation">0</int>
<reference key="secondItem" ref="670734441"/>
<int key="secondAttribute">9</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">0.0</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="595834490"/>
<int key="scoringType">6</int>
<float key="scoringTypeFloat">24</float>
<int key="contentType">2</int>
</object>
<object class="IBNSLayoutConstraint" id="426619093">
<reference key="firstItem" ref="847623533"/>
<int key="firstAttribute">5</int>
<int key="relation">1</int>
<reference key="secondItem" ref="595834490"/>
<int key="secondAttribute">5</int>
<float key="multiplier">1</float>
<object class="IBNSLayoutSymbolicConstant" key="constant">
<double key="value">20</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="595834490"/>
<int key="scoringType">9</int>
<float key="scoringTypeFloat">40</float>
<int key="contentType">3</int>
</object>
<reference ref="762740216"/>
<reference ref="256981522"/>
</array>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">5</int>
<reference key="object" ref="256981522"/>
<array class="NSMutableArray" key="children">
<reference ref="69579583"/>
</array>
<reference key="parent" ref="595834490"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">6</int>
<reference key="object" ref="365869599"/>
<array class="NSMutableArray" key="children">
<reference ref="324335303"/>
</array>
<reference key="parent" ref="595834490"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">7</int>
<reference key="object" ref="679285412"/>
<array class="NSMutableArray" key="children">
<reference ref="902994558"/>
</array>
<reference key="parent" ref="595834490"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">8</int>
<reference key="object" ref="670734441"/>
<array class="NSMutableArray" key="children">
<object class="IBNSLayoutConstraint" id="318411198">
<reference key="firstItem" ref="670734441"/>
<int key="firstAttribute">7</int>
<int key="relation">0</int>
<nil key="secondItem"/>
<int key="secondAttribute">0</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">191</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="670734441"/>
<int key="scoringType">9</int>
<float key="scoringTypeFloat">40</float>
<int key="contentType">1</int>
</object>
<reference ref="656181976"/>
</array>
<reference key="parent" ref="595834490"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">9</int>
<reference key="object" ref="847623533"/>
<array class="NSMutableArray" key="children">
<reference ref="792960157"/>
</array>
<reference key="parent" ref="595834490"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">10</int>
<reference key="object" ref="771851607"/>
<array class="NSMutableArray" key="children">
<reference ref="251779948"/>
</array>
<reference key="parent" ref="595834490"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">14</int>
<reference key="object" ref="426619093"/>
<reference key="parent" ref="595834490"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">17</int>
<reference key="object" ref="51218896"/>
<reference key="parent" ref="595834490"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">18</int>
<reference key="object" ref="485639451"/>
<reference key="parent" ref="595834490"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">19</int>
<reference key="object" ref="612132939"/>
<reference key="parent" ref="595834490"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">20</int>
<reference key="object" ref="379216952"/>
<reference key="parent" ref="595834490"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">22</int>
<reference key="object" ref="910263208"/>
<reference key="parent" ref="595834490"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">23</int>
<reference key="object" ref="966743814"/>
<reference key="parent" ref="595834490"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">24</int>
<reference key="object" ref="481322683"/>
<reference key="parent" ref="595834490"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">25</int>
<reference key="object" ref="33581314"/>
<reference key="parent" ref="595834490"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">26</int>
<reference key="object" ref="340048519"/>
<reference key="parent" ref="595834490"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">28</int>
<reference key="object" ref="176392839"/>
<reference key="parent" ref="595834490"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">29</int>
<reference key="object" ref="629412806"/>
<reference key="parent" ref="595834490"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">30</int>
<reference key="object" ref="381133690"/>
<reference key="parent" ref="595834490"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">31</int>
<reference key="object" ref="1024015372"/>
<reference key="parent" ref="595834490"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">32</int>
<reference key="object" ref="251779948"/>
<reference key="parent" ref="771851607"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">33</int>
<reference key="object" ref="792960157"/>
<reference key="parent" ref="847623533"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">34</int>
<reference key="object" ref="318411198"/>
<reference key="parent" ref="670734441"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">35</int>
<reference key="object" ref="656181976"/>
<reference key="parent" ref="670734441"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">36</int>
<reference key="object" ref="902994558"/>
<reference key="parent" ref="679285412"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">37</int>
<reference key="object" ref="324335303"/>
<reference key="parent" ref="365869599"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">38</int>
<reference key="object" ref="69579583"/>
<reference key="parent" ref="256981522"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">45</int>
<reference key="object" ref="762740216"/>
<array class="NSMutableArray" key="children">
<reference ref="79241474"/>
</array>
<reference key="parent" ref="595834490"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">46</int>
<reference key="object" ref="79241474"/>
<reference key="parent" ref="762740216"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">48</int>
<reference key="object" ref="335749536"/>
<reference key="parent" ref="595834490"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">49</int>
<reference key="object" ref="575391720"/>
<reference key="parent" ref="595834490"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">59</int>
<reference key="object" ref="501931119"/>
<reference key="parent" ref="595834490"/>
</object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="-3.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="NO" key="10.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
<string key="10.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="14.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="17.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="18.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="19.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<array class="NSMutableArray" key="2.IBNSViewMetadataConstraints">
<reference ref="426619093"/>
<reference ref="335749536"/>
<reference ref="575391720"/>
<reference ref="910263208"/>
<reference ref="51218896"/>
<reference ref="485639451"/>
<reference ref="612132939"/>
<reference ref="379216952"/>
<reference ref="966743814"/>
<reference ref="481322683"/>
<reference ref="33581314"/>
<reference ref="340048519"/>
<reference ref="176392839"/>
<reference ref="629412806"/>
<reference ref="381133690"/>
<reference ref="1024015372"/>
<reference ref="501931119"/>
</array>
<boolean value="NO" key="2.IBNSViewMetadataLastInspectedTranslatesAutoresizingMaskIntoConstraints"/>
<boolean value="NO" key="2.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
<string key="2.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="20.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="22.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="23.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="24.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="25.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="26.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="28.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="29.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="30.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="31.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="32.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="33.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="34.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="35.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="36.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="37.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="38.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="NO" key="45.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
<string key="45.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="46.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="48.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="49.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="NO" key="5.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
<string key="5.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="59.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="NO" key="6.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
<string key="6.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="NO" key="7.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
<string key="7.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<array class="NSMutableArray" key="8.IBNSViewMetadataConstraints">
<reference ref="318411198"/>
</array>
<boolean value="NO" key="8.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
<string key="8.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="NO" key="9.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
<string key="9.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">59</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
<object class="IBPartialClassDescription">
<string key="className">MPPasswordEditViewController</string>
<string key="superclassName">MPViewController</string>
<dictionary class="NSMutableDictionary" key="actions">
<string key="_cancel:">id</string>
<string key="_change:">id</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="actionInfosByName">
<object class="IBActionInfo" key="_cancel:">
<string key="name">_cancel:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo" key="_change:">
<string key="name">_change:</string>
<string key="candidateClassName">id</string>
</object>
</dictionary>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="keyfilePathControl">NSPathControl</string>
<string key="passwordTextField">NSSecureTextField</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="keyfilePathControl">
<string key="name">keyfilePathControl</string>
<string key="candidateClassName">NSPathControl</string>
</object>
<object class="IBToOneOutletInfo" key="passwordTextField">
<string key="name">passwordTextField</string>
<string key="candidateClassName">NSSecureTextField</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/MPPasswordEditViewController.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">MPViewController</string>
<string key="superclassName">NSViewController</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/MPViewController.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSLayoutConstraint</string>
<string key="superclassName">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/NSLayoutConstraint.h</string>
</object>
</object>
</array>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<bool key="IBDocument.UseAutolayout">YES</bool>
</data>
</archive>

File diff suppressed because it is too large Load Diff

View File

@@ -36,7 +36,7 @@
<object class="NSWindowTemplate" id="1005"> <object class="NSWindowTemplate" id="1005">
<int key="NSWindowStyleMask">15</int> <int key="NSWindowStyleMask">15</int>
<int key="NSWindowBacking">2</int> <int key="NSWindowBacking">2</int>
<string key="NSWindowRect">{{196, 240}, {560, 490}}</string> <string key="NSWindowRect">{{196, 240}, {700, 500}}</string>
<int key="NSWTFlags">1618477056</int> <int key="NSWTFlags">1618477056</int>
<string key="NSWindowTitle">Window</string> <string key="NSWindowTitle">Window</string>
<string key="NSWindowClass">NSWindow</string> <string key="NSWindowClass">NSWindow</string>
@@ -46,23 +46,26 @@
<reference key="NSNextResponder"/> <reference key="NSNextResponder"/>
<int key="NSvFlags">256</int> <int key="NSvFlags">256</int>
<array class="NSMutableArray" key="NSSubviews"/> <array class="NSMutableArray" key="NSSubviews"/>
<string key="NSFrameSize">{560, 490}</string> <string key="NSFrameSize">{700, 500}</string>
<reference key="NSSuperview"/> <reference key="NSSuperview"/>
<reference key="NSWindow"/> <reference key="NSWindow"/>
<reference key="NSNextKeyView"/>
</object> </object>
<string key="NSScreenRect">{{0, 0}, {1920, 1058}}</string> <string key="NSScreenRect">{{0, 0}, {2560, 1418}}</string>
<string key="NSMaxSize">{10000000000000, 10000000000000}</string> <string key="NSMaxSize">{10000000000000, 10000000000000}</string>
<string key="NSFrameAutosaveName">DatabaseWindow</string>
<bool key="NSWindowIsRestorable">YES</bool> <bool key="NSWindowIsRestorable">YES</bool>
</object> </object>
<object class="NSSplitView" id="903506498"> <object class="NSSplitView" id="903506498">
<nil key="NSNextResponder"/> <reference key="NSNextResponder"/>
<int key="NSvFlags">268</int> <int key="NSvFlags">268</int>
<array class="NSMutableArray" key="NSSubviews"/> <array class="NSMutableArray" key="NSSubviews"/>
<string key="NSFrameSize">{560, 194}</string> <string key="NSFrameSize">{560, 194}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<string key="NSReuseIdentifierKey">_NS:9</string> <string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="NSIsVertical">YES</bool> <bool key="NSIsVertical">YES</bool>
<int key="NSDividerStyle">2</int> <int key="NSDividerStyle">2</int>
<string key="NSAutosaveName"/>
</object> </object>
</array> </array>
<object class="IBObjectContainer" key="IBDocument.Objects"> <object class="IBObjectContainer" key="IBDocument.Objects">
@@ -158,15 +161,20 @@
<string key="superclassName">NSWindowController</string> <string key="superclassName">NSWindowController</string>
<dictionary class="NSMutableDictionary" key="actions"> <dictionary class="NSMutableDictionary" key="actions">
<string key="editPassword:">id</string> <string key="editPassword:">id</string>
<string key="showDocumentSettings:">id</string> <string key="exportDatabase:">id</string>
<string key="showDatabaseSettings:">id</string>
</dictionary> </dictionary>
<dictionary class="NSMutableDictionary" key="actionInfosByName"> <dictionary class="NSMutableDictionary" key="actionInfosByName">
<object class="IBActionInfo" key="editPassword:"> <object class="IBActionInfo" key="editPassword:">
<string key="name">editPassword:</string> <string key="name">editPassword:</string>
<string key="candidateClassName">id</string> <string key="candidateClassName">id</string>
</object> </object>
<object class="IBActionInfo" key="showDocumentSettings:"> <object class="IBActionInfo" key="exportDatabase:">
<string key="name">showDocumentSettings:</string> <string key="name">exportDatabase:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo" key="showDatabaseSettings:">
<string key="name">showDatabaseSettings:</string>
<string key="candidateClassName">id</string> <string key="candidateClassName">id</string>
</object> </object>
</dictionary> </dictionary>

View File

@@ -57,6 +57,7 @@
<int key="NSvFlags">268</int> <int key="NSvFlags">268</int>
<string key="NSFrame">{{7, 5}, {32, 19}}</string> <string key="NSFrame">{{7, 5}, {32, 19}}</string>
<reference key="NSSuperview" ref="163272962"/> <reference key="NSSuperview" ref="163272962"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView"/> <reference key="NSNextKeyView"/>
<string key="NSReuseIdentifierKey">_NS:9</string> <string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
@@ -85,8 +86,9 @@
<bool key="NSAllowsLogicalLayoutDirection">NO</bool> <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
</object> </object>
</array> </array>
<string key="NSFrameSize">{684, 30}</string> <string key="NSFrameSize">{694, 30}</string>
<reference key="NSSuperview" ref="997686550"/> <reference key="NSSuperview" ref="997686550"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="276578969"/> <reference key="NSNextKeyView" ref="276578969"/>
<string key="NSReuseIdentifierKey">_NS:9</string> <string key="NSReuseIdentifierKey">_NS:9</string>
<string key="NSClassName">HNHGradientView</string> <string key="NSClassName">HNHGradientView</string>
@@ -103,8 +105,9 @@
<reference key="NSNextResponder" ref="262664416"/> <reference key="NSNextResponder" ref="262664416"/>
<int key="NSvFlags">256</int> <int key="NSvFlags">256</int>
<array class="NSMutableArray" key="NSSubviews"/> <array class="NSMutableArray" key="NSSubviews"/>
<string key="NSFrameSize">{684, 548}</string> <string key="NSFrameSize">{694, 548}</string>
<reference key="NSSuperview" ref="262664416"/> <reference key="NSSuperview" ref="262664416"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="788738248"/> <reference key="NSNextKeyView" ref="788738248"/>
<string key="NSReuseIdentifierKey">_NS:13</string> <string key="NSReuseIdentifierKey">_NS:13</string>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
@@ -113,8 +116,9 @@
<object class="NSTableHeaderView" key="NSHeaderView" id="253618752"> <object class="NSTableHeaderView" key="NSHeaderView" id="253618752">
<reference key="NSNextResponder" ref="736877784"/> <reference key="NSNextResponder" ref="736877784"/>
<int key="NSvFlags">256</int> <int key="NSvFlags">256</int>
<string key="NSFrameSize">{684, 17}</string> <string key="NSFrameSize">{694, 17}</string>
<reference key="NSSuperview" ref="736877784"/> <reference key="NSSuperview" ref="736877784"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="262664416"/> <reference key="NSNextKeyView" ref="262664416"/>
<reference key="NSTableView" ref="528076956"/> <reference key="NSTableView" ref="528076956"/>
</object> </object>
@@ -272,7 +276,7 @@
<reference key="NSTableView" ref="528076956"/> <reference key="NSTableView" ref="528076956"/>
</object> </object>
<object class="NSTableColumn" id="683421605"> <object class="NSTableColumn" id="683421605">
<double key="NSWidth">188</double> <double key="NSWidth">198</double>
<double key="NSMinWidth">10</double> <double key="NSMinWidth">10</double>
<double key="NSMaxWidth">3.4028234663852886e+38</double> <double key="NSMaxWidth">3.4028234663852886e+38</double>
<object class="NSTableHeaderCell" key="NSHeaderCell"> <object class="NSTableHeaderCell" key="NSHeaderCell">
@@ -325,8 +329,9 @@
<int key="NSTableViewGroupRowStyle">1</int> <int key="NSTableViewGroupRowStyle">1</int>
</object> </object>
</array> </array>
<string key="NSFrame">{{0, 17}, {684, 548}}</string> <string key="NSFrame">{{0, 17}, {694, 548}}</string>
<reference key="NSSuperview" ref="613995671"/> <reference key="NSSuperview" ref="613995671"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="528076956"/> <reference key="NSNextKeyView" ref="528076956"/>
<string key="NSReuseIdentifierKey">_NS:11</string> <string key="NSReuseIdentifierKey">_NS:11</string>
<reference key="NSDocView" ref="528076956"/> <reference key="NSDocView" ref="528076956"/>
@@ -338,6 +343,7 @@
<int key="NSvFlags">-2147483392</int> <int key="NSvFlags">-2147483392</int>
<string key="NSFrame">{{224, 17}, {15, 102}}</string> <string key="NSFrame">{{224, 17}, {15, 102}}</string>
<reference key="NSSuperview" ref="613995671"/> <reference key="NSSuperview" ref="613995671"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="802411427"/> <reference key="NSNextKeyView" ref="802411427"/>
<string key="NSReuseIdentifierKey">_NS:58</string> <string key="NSReuseIdentifierKey">_NS:58</string>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool> <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
@@ -350,6 +356,7 @@
<int key="NSvFlags">-2147483392</int> <int key="NSvFlags">-2147483392</int>
<string key="NSFrame">{{0, 310}, {480, 16}}</string> <string key="NSFrame">{{0, 310}, {480, 16}}</string>
<reference key="NSSuperview" ref="613995671"/> <reference key="NSSuperview" ref="613995671"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="163272962"/> <reference key="NSNextKeyView" ref="163272962"/>
<string key="NSReuseIdentifierKey">_NS:60</string> <string key="NSReuseIdentifierKey">_NS:60</string>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool> <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
@@ -364,16 +371,18 @@
<array class="NSMutableArray" key="NSSubviews"> <array class="NSMutableArray" key="NSSubviews">
<reference ref="253618752"/> <reference ref="253618752"/>
</array> </array>
<string key="NSFrameSize">{684, 17}</string> <string key="NSFrameSize">{694, 17}</string>
<reference key="NSSuperview" ref="613995671"/> <reference key="NSSuperview" ref="613995671"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="253618752"/> <reference key="NSNextKeyView" ref="253618752"/>
<reference key="NSDocView" ref="253618752"/> <reference key="NSDocView" ref="253618752"/>
<reference key="NSBGColor" ref="136901388"/> <reference key="NSBGColor" ref="136901388"/>
<int key="NScvFlags">4</int> <int key="NScvFlags">4</int>
</object> </object>
</array> </array>
<string key="NSFrame">{{0, 30}, {684, 565}}</string> <string key="NSFrame">{{0, 30}, {694, 565}}</string>
<reference key="NSSuperview" ref="997686550"/> <reference key="NSSuperview" ref="997686550"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="736877784"/> <reference key="NSNextKeyView" ref="736877784"/>
<string key="NSReuseIdentifierKey">_NS:9</string> <string key="NSReuseIdentifierKey">_NS:9</string>
<int key="NSsFlags">133680</int> <int key="NSsFlags">133680</int>
@@ -387,8 +396,9 @@
<double key="NSMagnification">1</double> <double key="NSMagnification">1</double>
</object> </object>
</array> </array>
<string key="NSFrameSize">{684, 594}</string> <string key="NSFrameSize">{694, 594}</string>
<reference key="NSSuperview"/> <reference key="NSSuperview"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="613995671"/> <reference key="NSNextKeyView" ref="613995671"/>
<string key="NSReuseIdentifierKey">_NS:9</string> <string key="NSReuseIdentifierKey">_NS:9</string>
<string key="NSClassName">NSView</string> <string key="NSClassName">NSView</string>
@@ -646,7 +656,7 @@
<object class="NSTextField" id="488604658"> <object class="NSTextField" id="488604658">
<reference key="NSNextResponder" ref="954630866"/> <reference key="NSNextResponder" ref="954630866"/>
<int key="NSvFlags">266</int> <int key="NSvFlags">266</int>
<string key="NSFrameSize">{188, 17}</string> <string key="NSFrameSize">{198, 17}</string>
<reference key="NSSuperview" ref="954630866"/> <reference key="NSSuperview" ref="954630866"/>
<reference key="NSNextKeyView" ref="1037276411"/> <reference key="NSNextKeyView" ref="1037276411"/>
<string key="NSAntiCompressionPriority">{250, 750}</string> <string key="NSAntiCompressionPriority">{250, 750}</string>
@@ -663,7 +673,7 @@
<bool key="NSAllowsLogicalLayoutDirection">NO</bool> <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
</object> </object>
</array> </array>
<string key="NSFrame">{{494, 1}, {188, 17}}</string> <string key="NSFrame">{{494, 1}, {198, 17}}</string>
<reference key="NSNextKeyView" ref="488604658"/> <reference key="NSNextKeyView" ref="488604658"/>
</object> </object>
<reference key="destination" ref="488604658"/> <reference key="destination" ref="488604658"/>
@@ -1565,7 +1575,7 @@
<reference key="parent" ref="276578969"/> <reference key="parent" ref="276578969"/>
</object> </object>
<object class="IBObjectRecord"> <object class="IBObjectRecord">
<int key="objectID">790</int> <int key="objectID">834</int>
<reference key="object" ref="244975730"/> <reference key="object" ref="244975730"/>
<reference key="parent" ref="163272962"/> <reference key="parent" ref="163272962"/>
</object> </object>
@@ -1705,7 +1715,7 @@
<string key="678.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="678.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="679.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="679.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="683.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="683.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<array class="NSMutableArray" key="690.IBNSViewMetadataConstraints"> <array key="690.IBNSViewMetadataConstraints">
<reference ref="337191559"/> <reference ref="337191559"/>
<reference ref="187301323"/> <reference ref="187301323"/>
<reference ref="244975730"/> <reference ref="244975730"/>
@@ -1725,15 +1735,117 @@
<string key="733.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="733.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="741.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="741.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="743.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="743.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="790.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="834.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
</dictionary> </dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/> <dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/> <nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/> <dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/> <nil key="sourceID"/>
<int key="maxID">801</int> <int key="maxID">834</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
<object class="IBPartialClassDescription">
<string key="className">HNHGradientView</string>
<string key="superclassName">NSView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/HNHGradientView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">MPEntryViewController</string>
<string key="superclassName">MPViewController</string>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="addEntryButton">NSButton</string>
<string key="bottomBar">HNHGradientView</string>
<string key="entryTable">NSTableView</string>
<string key="filterBar">NSView</string>
<string key="filterDoneButton">NSButton</string>
<string key="filterLabelTextField">NSTextField</string>
<string key="filterSearchField">NSSearchField</string>
<string key="filterTitleButton">NSButton</string>
<string key="filterURLButton">NSButton</string>
<string key="filterUsernameButton">NSButton</string>
<string key="tableToTop">NSLayoutConstraint</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="addEntryButton">
<string key="name">addEntryButton</string>
<string key="candidateClassName">NSButton</string>
</object>
<object class="IBToOneOutletInfo" key="bottomBar">
<string key="name">bottomBar</string>
<string key="candidateClassName">HNHGradientView</string>
</object>
<object class="IBToOneOutletInfo" key="entryTable">
<string key="name">entryTable</string>
<string key="candidateClassName">NSTableView</string>
</object>
<object class="IBToOneOutletInfo" key="filterBar">
<string key="name">filterBar</string>
<string key="candidateClassName">NSView</string>
</object>
<object class="IBToOneOutletInfo" key="filterDoneButton">
<string key="name">filterDoneButton</string>
<string key="candidateClassName">NSButton</string>
</object>
<object class="IBToOneOutletInfo" key="filterLabelTextField">
<string key="name">filterLabelTextField</string>
<string key="candidateClassName">NSTextField</string>
</object>
<object class="IBToOneOutletInfo" key="filterSearchField">
<string key="name">filterSearchField</string>
<string key="candidateClassName">NSSearchField</string>
</object>
<object class="IBToOneOutletInfo" key="filterTitleButton">
<string key="name">filterTitleButton</string>
<string key="candidateClassName">NSButton</string>
</object>
<object class="IBToOneOutletInfo" key="filterURLButton">
<string key="name">filterURLButton</string>
<string key="candidateClassName">NSButton</string>
</object>
<object class="IBToOneOutletInfo" key="filterUsernameButton">
<string key="name">filterUsernameButton</string>
<string key="candidateClassName">NSButton</string>
</object>
<object class="IBToOneOutletInfo" key="tableToTop">
<string key="name">tableToTop</string>
<string key="candidateClassName">NSLayoutConstraint</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/MPEntryViewController.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">MPTableView</string>
<string key="superclassName">NSTableView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/MPTableView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">MPViewController</string>
<string key="superclassName">NSViewController</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/MPViewController.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSLayoutConstraint</string>
<string key="superclassName">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/NSLayoutConstraint.h</string>
</object>
</object>
</array>
</object> </object>
<object class="IBClassDescriber" key="IBDocument.Classes"/>
<int key="IBDocument.localizationMode">0</int> <int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string> <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool> <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -18,32 +18,32 @@
tree.root = rootGroup; tree.root = rootGroup;
KdbGroup *parentGroup = [tree createGroup:rootGroup]; KdbGroup *parentGroup = [tree createGroup:rootGroup];
parentGroup.name = @"General"; parentGroup.name = NSLocalizedString(@"GENERAL", "General");
parentGroup.image = 48; parentGroup.image = 48;
[rootGroup addGroup:parentGroup]; [rootGroup addGroup:parentGroup];
KdbGroup *group = [tree createGroup:parentGroup]; KdbGroup *group = [tree createGroup:parentGroup];
group.name = @"Windows"; group.name = NSLocalizedString(@"WINDOWS", "Windows");
group.image = 38; group.image = 38;
[parentGroup addGroup:group]; [parentGroup addGroup:group];
group = [tree createGroup:parentGroup]; group = [tree createGroup:parentGroup];
group.name = @"Network"; group.name = NSLocalizedString(@"NETWORK", "Network");
group.image = 3; group.image = 3;
[parentGroup addGroup:group]; [parentGroup addGroup:group];
group = [tree createGroup:parentGroup]; group = [tree createGroup:parentGroup];
group.name = @"Internet"; group.name = NSLocalizedString(@"INTERNET", "Internet");
group.image = 1; group.image = 1;
[parentGroup addGroup:group]; [parentGroup addGroup:group];
group = [tree createGroup:parentGroup]; group = [tree createGroup:parentGroup];
group.name = @"eMail"; group.name = NSLocalizedString(@"EMAIL", "EMail");
group.image = 19; group.image = 19;
[parentGroup addGroup:group]; [parentGroup addGroup:group];
group = [tree createGroup:parentGroup]; group = [tree createGroup:parentGroup];
group.name = @"Homebanking"; group.name = NSLocalizedString(@"HOMEBANKING", "Homebanking");
group.image = 37; group.image = 37;
[parentGroup addGroup:group]; [parentGroup addGroup:group];

View File

@@ -15,5 +15,9 @@
- (void)removeObjectFromStringFieldsAtIndex:(NSUInteger)anIndex; - (void)removeObjectFromStringFieldsAtIndex:(NSUInteger)anIndex;
- (void)insertObject:(StringField *)stringfield inStringFieldsAtIndex:(NSUInteger)anIndex; - (void)insertObject:(StringField *)stringfield inStringFieldsAtIndex:(NSUInteger)anIndex;
- (NSUInteger)countOfBinaries;
- (BinaryRef *)objectInBinariesAtIndex:(NSUInteger)index;
- (void)removeObjectFromBinariesAtIndex:(NSUInteger)index;
- (void)insertObject:(BinaryRef *)binary inBinariesAtIndex:(NSUInteger)index;
@end @end

View File

@@ -10,6 +10,7 @@
@implementation Kdb4Entry (KVOAdditions) @implementation Kdb4Entry (KVOAdditions)
/* Entries */
- (NSUInteger)countOfStringFields { - (NSUInteger)countOfStringFields {
return [self.stringFields count]; return [self.stringFields count];
} }
@@ -26,4 +27,21 @@
[self.stringFields removeObjectAtIndex:anIndex]; [self.stringFields removeObjectAtIndex:anIndex];
} }
/* Binaries */
- (NSUInteger)countOfBinaries {
return [self.binaries count];
}
- (BinaryRef *)objectInBinariesAtIndex:(NSUInteger)index {
return (self.binaries)[index];
}
- (void)insertObject:(BinaryRef *)binary inBinariesAtIndex:(NSUInteger)index {
[self.binaries insertObject:binary atIndex:index];
}
- (void)removeObjectFromBinariesAtIndex:(NSUInteger)index {
[self.binaries removeObjectAtIndex:index];
}
@end @end

View File

@@ -0,0 +1,15 @@
//
// Kdb4Entry+MPAdditions.h
// MacPass
//
// Created by Michael Starke on 19.07.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import "Kdb4Node.h"
@interface Kdb4Entry (MPAdditions)
- (NSString *)uniqueKeyForProposal:(NSString *)key;
@end

View File

@@ -0,0 +1,34 @@
//
// Kdb4Entry+MPAdditions.m
// MacPass
//
// Created by Michael Starke on 19.07.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import "Kdb4Entry+MPAdditions.h"
@implementation Kdb4Entry (MPAdditions)
- (NSString *)uniqueKeyForProposal:(NSString *)key {
/*
FIXME: Introduce some cachin behaviour. We iterate over after every single edit
*/
NSArray *defaultKeys = @[ FIELD_TITLE,
FIELD_USER_NAME,
FIELD_PASSWORD,
FIELD_URL,
FIELD_NOTES ];
NSMutableSet *keys = [[NSMutableSet alloc] initWithArray:defaultKeys];
for(StringField *field in self.stringFields) {
[keys addObject:field.key];
}
NSUInteger counter = 1;
NSString *base = key;
while([keys containsObject:key]) {
key = [NSString stringWithFormat:@"%@-%ld", base, counter++];
}
return key;
}
@end

View File

@@ -11,5 +11,6 @@
@interface Kdb4Tree (NewTree) @interface Kdb4Tree (NewTree)
+(Kdb4Tree *)templateTree; +(Kdb4Tree *)templateTree;
+(Kdb4Tree *)demoTree;
@end @end

View File

@@ -15,7 +15,7 @@
Kdb4Tree *tree = [[Kdb4Tree alloc] init]; Kdb4Tree *tree = [[Kdb4Tree alloc] init];
tree.generator = @"MacPass"; tree.generator = @"MacPass";
tree.databaseName = @""; tree.databaseName = NSLocalizedString(@"DATABASE", "");
tree.databaseNameChanged = currentTime; tree.databaseNameChanged = currentTime;
tree.databaseDescription = @""; tree.databaseDescription = @"";
tree.databaseDescriptionChanged = currentTime; tree.databaseDescriptionChanged = currentTime;
@@ -41,35 +41,81 @@
tree.lastSelectedGroup = [UUID nullUuid]; tree.lastSelectedGroup = [UUID nullUuid];
tree.lastTopVisibleGroup = [UUID nullUuid]; tree.lastTopVisibleGroup = [UUID nullUuid];
KdbGroup *parentGroup = [tree createGroup:nil];
parentGroup.name = NSLocalizedString(@"GENERAL", "General");
parentGroup.image = 48;
tree.root = parentGroup;
KdbGroup *group = [tree createGroup:parentGroup];
group.name = NSLocalizedString(@"WINDOWS", "Windows");
group.image = 38;
[parentGroup addGroup:group];
group = [tree createGroup:parentGroup];
group.name = NSLocalizedString(@"NETWORK", "Network");
group.image = 3;
[parentGroup addGroup:group];
group = [tree createGroup:parentGroup];
group.name = NSLocalizedString(@"INTERNET", "Internet");
group.image = 1;
[parentGroup addGroup:group];
group = [tree createGroup:parentGroup];
group.name = NSLocalizedString(@"EMAIL", "EMail");
group.image = 19;
[parentGroup addGroup:group];
group = [tree createGroup:parentGroup];
group.name = NSLocalizedString(@"HOMEBANKING", "Homebanking");
group.image = 37;
[parentGroup addGroup:group];
return tree;
}
+ (Kdb4Tree *)demoTree {
NSDate *currentTime = [NSDate date];
Kdb4Tree *tree = [[Kdb4Tree alloc] init];
tree.generator = @"MacPass";
tree.databaseName = @"Icon Demonstation";
tree.databaseNameChanged = currentTime;
tree.databaseDescription = @"This database just has all default icons as groups in the tree";
tree.databaseDescriptionChanged = currentTime;
tree.defaultUserName = @"";
tree.defaultUserNameChanged = currentTime;
tree.maintenanceHistoryDays = 365;
tree.color = @"";
tree.masterKeyChanged = currentTime;
tree.masterKeyChangeRec = -1;
tree.masterKeyChangeForce = -1;
tree.protectTitle = NO;
tree.protectUserName = NO;
tree.protectPassword = YES;
tree.protectUrl = NO;
tree.protectNotes = NO;
tree.recycleBinEnabled = YES;
tree.recycleBinUuid = [UUID nullUuid];
tree.recycleBinChanged = currentTime;
tree.entryTemplatesGroup = [UUID nullUuid];
tree.entryTemplatesGroupChanged = currentTime;
tree.historyMaxItems = 10;
tree.historyMaxSize = 6 * 1024 * 1024; // 6 MB
tree.lastSelectedGroup = [UUID nullUuid];
tree.lastTopVisibleGroup = [UUID nullUuid];
KdbGroup *parentGroup = [tree createGroup:nil]; KdbGroup *parentGroup = [tree createGroup:nil];
parentGroup.name = @"General"; parentGroup.name = @"General";
parentGroup.image = 48; parentGroup.image = 48;
tree.root = parentGroup; tree.root = parentGroup;
for(NSUInteger iImageIndex = 0; iImageIndex < 69; iImageIndex++) {
KdbGroup *group = [tree createGroup:parentGroup]; KdbGroup *group = [tree createGroup:parentGroup];
group.name = @"Windows"; group.name = [NSString stringWithFormat:@"Group %ld", iImageIndex];
group.image = 38; group.image = iImageIndex;
[parentGroup addGroup:group];
group = [tree createGroup:parentGroup];
group.name = @"Network";
group.image = 3;
[parentGroup addGroup:group];
group = [tree createGroup:parentGroup];
group.name = @"Internet";
group.image = 1;
[parentGroup addGroup:group];
group = [tree createGroup:parentGroup];
group.name = @"eMail";
group.image = 19;
[parentGroup addGroup:group];
group = [tree createGroup:parentGroup];
group.name = @"Homebanking";
group.image = 37;
[parentGroup addGroup:group]; [parentGroup addGroup:group];
}
return tree; return tree;
} }

View File

@@ -7,6 +7,8 @@
// //
#import "KdbEntry+MPAdditions.h" #import "KdbEntry+MPAdditions.h"
#import "Kdb3Node.h"
#import "Kdb4Node.h"
#import "MPIconHelper.h" #import "MPIconHelper.h"

View File

@@ -17,4 +17,5 @@
return NSNotFound; return NSNotFound;
} }
@end @end

View File

@@ -17,8 +17,6 @@ APPKIT_EXTERN NSString *const MPEntryNotesUndoableKey;
@interface KdbEntry (Undo) @interface KdbEntry (Undo)
+ (NSUndoManager *)undoManager;
- (NSString *)titleUndoable; - (NSString *)titleUndoable;
- (NSString *)usernameUndoable; - (NSString *)usernameUndoable;
- (NSString *)passwordUndoable; - (NSString *)passwordUndoable;
@@ -31,4 +29,8 @@ APPKIT_EXTERN NSString *const MPEntryNotesUndoableKey;
- (void)setUrlUndoable:(NSString *)url; - (void)setUrlUndoable:(NSString *)url;
- (void)setNotesUndoable:(NSString *)notes; - (void)setNotesUndoable:(NSString *)notes;
- (void)deleteUndoable;
- (void)moveToGroupUndoable:(KdbGroup *)group atIndex:(NSUInteger)index;
- (void)moveToTrashUndoable:(KdbGroup *)trash atIndex:(NSUInteger)index;
@end @end

View File

@@ -7,6 +7,8 @@
// //
#import "KdbEntry+Undo.h" #import "KdbEntry+Undo.h"
#import "KdbGroup+Undo.h"
#import "KdbGroup+KVOAdditions.h"
#import "KdbGroup+MPTreeTools.h" #import "KdbGroup+MPTreeTools.h"
NSString *const MPEntryTitleUndoableKey = @"titleUndoable"; NSString *const MPEntryTitleUndoableKey = @"titleUndoable";
@@ -15,9 +17,16 @@ NSString *const MPEntryPasswordUndoableKey = @"passwordUndoable";
NSString *const MPEntryUrlUndoableKey = @"urlUndoable"; NSString *const MPEntryUrlUndoableKey = @"urlUndoable";
NSString *const MPEntryNotesUndoableKey = @"notesUndoable"; NSString *const MPEntryNotesUndoableKey = @"notesUndoable";
#ifndef MPSetActionName
#define MPSetActionName(key, comment) \
if(![[self undoManager] isUndoing]) {\
[[self undoManager] setActionName:[[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:nil]];\
}
#endif
@implementation KdbEntry (Undo) @implementation KdbEntry (Undo)
+ (NSUndoManager *)undoManager { - (NSUndoManager *)undoManager {
return [[[NSDocumentController sharedDocumentController] currentDocument] undoManager]; return [[[NSDocumentController sharedDocumentController] currentDocument] undoManager];
} }
@@ -41,40 +50,110 @@ NSString *const MPEntryNotesUndoableKey = @"notesUndoable";
return [self notes]; return [self notes];
} }
- (void)setTitleUndoable:(NSString *)title { - (void)setTitleUndoable:(NSString *)title {
[[KdbEntry undoManager] registerUndoWithTarget:self selector:@selector(setTitleUndoable:) object:self.title]; [[self undoManager] registerUndoWithTarget:self selector:@selector(setTitleUndoable:) object:self.title];
[[KdbEntry undoManager] setActionName:NSLocalizedString(@"UNDO_SET_TITLE", "Undo set title")];
if(![[self undoManager] isUndoing]) {
[[self undoManager] setActionName:NSLocalizedString(@"SET_TITLE", "Set Title")];
}
[self setLastModificationTime:[NSDate date]]; [self setLastModificationTime:[NSDate date]];
[self setTitle:title]; [self setTitle:title];
} }
- (void)setUsernameUndoable:(NSString *)username { - (void)setUsernameUndoable:(NSString *)username {
[[KdbEntry undoManager] registerUndoWithTarget:self selector:@selector(setUsernameUndoable:) object:self.username]; [[self undoManager] registerUndoWithTarget:self selector:@selector(setUsernameUndoable:) object:self.username];
[[KdbEntry undoManager] setActionName:NSLocalizedString(@"UNDO_SET_USERNAME", "Undo set username")];
if(![[self undoManager] isUndoing]) {
[[self undoManager] setActionName:NSLocalizedString(@"SET_USERNAME", "Undo set username")];
}
[self setLastModificationTime:[NSDate date]]; [self setLastModificationTime:[NSDate date]];
[self setUsername:username]; [self setUsername:username];
} }
- (void)setPasswordUndoable:(NSString *)password { - (void)setPasswordUndoable:(NSString *)password {
[[KdbEntry undoManager] registerUndoWithTarget:self selector:@selector(setPasswordUndoable:) object:self.password]; [[self undoManager] registerUndoWithTarget:self selector:@selector(setPasswordUndoable:) object:self.password];
[[KdbEntry undoManager] setActionName:NSLocalizedString(@"UNDO_SET_PASSWORT", "Undo set password")]; MPSetActionName(@"SET_PASSWORT", "Undo set password");
if(![[self undoManager] isUndoing]) {
[[self undoManager] setActionName:NSLocalizedString(@"SET_TITLE", "Set Title")];
}
[self setLastModificationTime:[NSDate date]]; [self setLastModificationTime:[NSDate date]];
[self setPassword:password]; [self setPassword:password];
} }
- (void)setUrlUndoable:(NSString *)url { - (void)setUrlUndoable:(NSString *)url {
[[KdbEntry undoManager] registerUndoWithTarget:self selector:@selector(setUrlUndoable:) object:self.url]; [[self undoManager] registerUndoWithTarget:self selector:@selector(setUrlUndoable:) object:self.url];
[[KdbEntry undoManager] setActionName:NSLocalizedString(@"UNDO_SET_URL", "Undo set URL")]; MPSetActionName(@"SET_URL", "Undo set URL");
if(![[self undoManager] isUndoing]) {
[[self undoManager] setActionName:NSLocalizedString(@"SET_TITLE", "Set Title")];
}
[self setLastModificationTime:[NSDate date]]; [self setLastModificationTime:[NSDate date]];
[self setUrl:url]; [self setUrl:url];
} }
- (void)setNotesUndoable:(NSString *)notes { - (void)setNotesUndoable:(NSString *)notes {
[[KdbEntry undoManager] registerUndoWithTarget:self selector:@selector(setNotesUndoable:) object:self.notes]; [[self undoManager] registerUndoWithTarget:self selector:@selector(setNotesUndoable:) object:self.notes];
[[KdbEntry undoManager] setActionName:NSLocalizedString(@"UNDO_SET_NOTES", "Undo set notes")]; MPSetActionName(@"SET_NOTES", "Set Notes");
if(![[self undoManager] isUndoing]) {
[[self undoManager] setActionName:NSLocalizedString(@"SET_TITLE", "Set Title")];
}
[self setLastModificationTime:[NSDate date]]; [self setLastModificationTime:[NSDate date]];
[self setNotes:notes]; [self setNotes:notes];
} }
- (void)deleteUndoable {
if(!self.parent) {
return; // No parent to be removed from
}
NSUInteger oldIndex = [self.parent.entries indexOfObject:self];
if(oldIndex == NSNotFound) {
return; // We're not in our parents entries list
}
[[[self undoManager] prepareWithInvocationTarget:self.parent] addEntryUndoable:self atIndex:oldIndex];
if(![[self undoManager] isUndoing]) {
[[self undoManager] setActionName:NSLocalizedString(@"DELETE_ENTRY", "Set Title")];
}
//[[NSNotificationCenter defaultCenter] postNotificationName:@"" object:self userInfo:nil];
[self.parent removeObjectFromEntriesAtIndex:oldIndex];
}
- (void)moveToGroupUndoable:(KdbGroup *)group atIndex:(NSUInteger)index {
[self _moveToGroup:group atIndex:index actionName:NSLocalizedString(@"MOVE_ENTRY", "Move Group")];
}
- (void)moveToTrashUndoable:(KdbGroup *)trash atIndex:(NSUInteger)index {
[self _moveToGroup:trash atIndex:index actionName:NSLocalizedString(@"TRASH_ENTRY", "Move Entry to Trash")];
}
- (void)_moveToGroup:(KdbGroup *)group atIndex:(NSUInteger)index actionName:(NSString *)name {
if(!group || !self.parent) {
return; // Nothing to be moved about
}
NSUInteger oldIndex = [self.parent.entries indexOfObject:self];
if(oldIndex == NSNotFound) {
return; // Not found in entries of parent!
}
[[[self undoManager] prepareWithInvocationTarget:self] _moveToGroup:self.parent atIndex:oldIndex actionName:name];
if(![[self undoManager] isUndoing]) {
[[self undoManager] setActionName:name];
}
[self.parent removeObjectFromEntriesAtIndex:oldIndex];
// Old indices might be wrong, correct them if necessary
index = MIN(index, [group.entries count]);
[group insertObject:self inEntriesAtIndex:index];
}
@end @end

View File

@@ -17,4 +17,10 @@ APPKIT_EXTERN NSString *const MPGroupNameUndoableKey;
- (NSString *)nameUndoable; - (NSString *)nameUndoable;
- (void)setNameUndoable:(NSString *)newName; - (void)setNameUndoable:(NSString *)newName;
- (void)deleteUndoable;
- (void)addGroupUndoable:(KdbGroup *)group atIndex:(NSUInteger)index;
- (void)addEntryUndoable:(KdbEntry *)entry atIndex:(NSUInteger)index;
- (void)moveToGroupUndoable:(KdbGroup *)group atIndex:(NSUInteger)index;
- (void)moveToTrashUndoable:(KdbGroup *)trash atIndex:(NSUInteger)index;
@end @end

View File

@@ -8,6 +8,7 @@
#import "KdbGroup+Undo.h" #import "KdbGroup+Undo.h"
#import "KdbGroup+KVOAdditions.h" #import "KdbGroup+KVOAdditions.h"
#import "KdbEntry+Undo.h"
NSString *const MPGroupNameUndoableKey = @"nameUndoable"; NSString *const MPGroupNameUndoableKey = @"nameUndoable";
@@ -23,8 +24,85 @@ NSString *const MPGroupNameUndoableKey = @"nameUndoable";
- (void)setNameUndoable:(NSString *)newName { - (void)setNameUndoable:(NSString *)newName {
[[self undoManager] registerUndoWithTarget:self selector:@selector(setNameUndoable:) object:self.name]; [[self undoManager] registerUndoWithTarget:self selector:@selector(setNameUndoable:) object:self.name];
[[self undoManager] setActionName:NSLocalizedString(@"UNDO_SET_NAME", "Undo set name")];
if(![[self undoManager] isUndoing]) {
[[self undoManager] setActionName:NSLocalizedString(@"SET_NAME", "Set Name")];
}
self.name = newName; self.name = newName;
} }
- (void)deleteUndoable {
if(!self.parent) {
return;
}
NSUInteger oldIndex = [self.parent.groups indexOfObject:self];
if(oldIndex == NSNotFound) {
return; // Inconsistent data
}
[[[self undoManager] prepareWithInvocationTarget:self.parent] addGroupUndoable:self atIndex:oldIndex];
if(![[self undoManager] isUndoing]) {
[[self undoManager] setActionName:NSLocalizedString(@"DELETE_GROUP", "Delete Group")];
}
[self.parent removeObjectFromGroupsAtIndex:oldIndex];
}
- (void)addGroupUndoable:(KdbGroup *)group atIndex:(NSUInteger)index {
if(!group) {
return;
}
[[[self undoManager] prepareWithInvocationTarget:group] deleteUndoable];
if(![[self undoManager] isUndoing]) {
[[self undoManager] setActionName:NSLocalizedString(@"ADD_GROUP", "Add Group")];
}
index = MIN(index, [group.groups count]);
[self insertObject:group inGroupsAtIndex:index];
}
- (void)addEntryUndoable:(KdbEntry *)entry atIndex:(NSUInteger)index {
if(!entry) {
return;
}
index = MIN(index, [self.entries count]);
[[[self undoManager] prepareWithInvocationTarget:entry] deleteUndoable];
if(![[self undoManager] isUndoing]) {
[[self undoManager] setActionName:NSLocalizedString(@"ADD_ENTRY", "Add Entry")];
}
[self insertObject:entry inEntriesAtIndex:index];
}
- (void)moveToGroupUndoable:(KdbGroup *)group atIndex:(NSUInteger)index {
[self _moveToGroup:group atIndex:index actionName:NSLocalizedString(@"MOVE_GROUP", "Move Group" )];
}
- (void)moveToTrashUndoable:(KdbGroup *)trash atIndex:(NSUInteger)index {
[self _moveToGroup:trash atIndex:index actionName:NSLocalizedString(@"TRASH_GROUP", "Move Group to Trash")];
}
- (void)_moveToGroup:(KdbGroup *)group atIndex:(NSUInteger)index actionName:(NSString *)actionName {
if(!self.parent || !group) {
return; // No target or origin
}
NSUInteger oldIndex = [self.parent.groups indexOfObject:self];
if(oldIndex == NSNotFound) {
return; // We aren't in our parents groups list.
}
[[[self undoManager] prepareWithInvocationTarget:self] moveToGroupUndoable:self.parent atIndex:oldIndex];
if(![[self undoManager] isUndoing]) {
[[self undoManager] setActionName:actionName];
}
[self.parent removeObjectFromGroupsAtIndex:oldIndex];
index = MIN(index, [group.groups count]);
[group insertObject:self inGroupsAtIndex:index];
}
@end @end

View File

@@ -8,6 +8,9 @@
#import "Kdb.h" #import "Kdb.h"
@class BinaryRef;
@class Binary;
@interface KdbTree (MPAdditions) @interface KdbTree (MPAdditions)
- (NSArray *)allEntries; - (NSArray *)allEntries;

View File

@@ -9,6 +9,10 @@
#import "KdbTree+MPAdditions.h" #import "KdbTree+MPAdditions.h"
#import "KdbGroup+MPTreeTools.h" #import "KdbGroup+MPTreeTools.h"
#import "NSMutableData+Base64.h"
#import "Kdb3Node.h"
#import "Kdb4Node.h"
@implementation KdbTree (MPAdditions) @implementation KdbTree (MPAdditions)
- (NSArray *)allGroups { - (NSArray *)allGroups {

View File

@@ -38,16 +38,31 @@
[MPStringLengthValueTransformer registerTransformer]; [MPStringLengthValueTransformer registerTransformer];
} }
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender { - (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender {
return [[NSUserDefaults standardUserDefaults] boolForKey:kMPSettingsKeyOpenEmptyDatabaseOnLaunch]; return [[NSUserDefaults standardUserDefaults] boolForKey:kMPSettingsKeyOpenEmptyDatabaseOnLaunch];
} }
- (void)applicationWillFinishLaunching:(NSNotification *)notification {
BOOL reopen = [[NSUserDefaults standardUserDefaults] boolForKey:kMPSettingsKeyReopenLastDatabaseOnLaunch];
if(reopen) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(_applicationDidFinishRestoringWindows:)
name:NSApplicationDidFinishRestoringWindowsNotification
object:nil];
}
}
- (void)applicationDidFinishLaunching:(NSNotification *)notification { - (void)applicationDidFinishLaunching:(NSNotification *)notification {
serverDaemon = [[MPServerDaemon alloc] init]; serverDaemon = [[MPServerDaemon alloc] init];
lockDaemon = [[MPLockDaemon alloc] init]; lockDaemon = [[MPLockDaemon alloc] init];
} }
- (NSString *)applicationName { - (NSString *)applicationName {
return [[NSBundle mainBundle] infoDictionary][@"CFBundleName"]; return [[NSBundle mainBundle] infoDictionary][@"CFBundleName"];
} }
@@ -93,4 +108,16 @@
} }
} }
- (void)_applicationDidFinishRestoringWindows:(NSNotification *)notification {
NSDocumentController *documentController = [NSDocumentController sharedDocumentController];
NSArray *documents = [documentController documents];
NSArray *recentDocuments = [documentController recentDocumentURLs];
if([documents count] == 0 && [recentDocuments count] > 0) {
NSURL *url = recentDocuments[0];
[documentController openDocumentWithContentsOfURL:url display:YES completionHandler:^(NSDocument *document, BOOL documentWasAlreadyOpen, NSError *error) {
// do nothing
}];
}
}
@end @end

View File

@@ -0,0 +1,17 @@
//
// MPAttachmentTableViewDelegate.h
// MacPass
//
// Created by Michael Starke on 17.07.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import <Foundation/Foundation.h>
@class MPInspectorViewController;
@interface MPAttachmentTableViewDelegate : NSObject <NSTableViewDelegate>
@property (nonatomic, weak) MPInspectorViewController *viewController;
@end

View File

@@ -0,0 +1,65 @@
//
// MPAttachmentTableViewDelegate.m
// MacPass
//
// Created by Michael Starke on 17.07.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import "MPAttachmentTableViewDelegate.h"
#import "MPInspectorViewController.h"
#import "MPSelectedAttachmentTableCellView.h"
#import "Kdb4Node.h"
#import "HNHTableRowView.h"
@implementation MPAttachmentTableViewDelegate
- (void)tableViewSelectionDidChange:(NSNotification *)notification {
NSTableView *tableView = [notification object];
NSIndexSet *allColumns = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [[tableView tableColumns] count])];
Kdb4Entry *entryv4 = (Kdb4Entry *)self.viewController.selectedEntry;
NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [entryv4.binaries count] )];
[tableView reloadDataForRowIndexes:indexSet columnIndexes:allColumns];
}
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
/* Decide what view to use */
NSIndexSet *selectedIndexes = [tableView selectedRowIndexes];
NSTableCellView *view;
if([selectedIndexes containsIndex:row]) {
MPSelectedAttachmentTableCellView *cellView = [tableView makeViewWithIdentifier:@"SelectedCell" owner:tableView];
[cellView.saveButton setTag:row];
[cellView.saveButton setAction:@selector(saveAttachment:)];
[cellView.saveButton setTarget:self.viewController];
[cellView.removeButton setTag:row];
[cellView.removeButton setAction:@selector(removeAttachment:)];
[cellView.removeButton setTarget:self.viewController];
view = cellView;
}
else {
view = [tableView makeViewWithIdentifier:@"NormalCell" owner:tableView];
}
/* Bind view */
if([self.viewController.selectedEntry isKindOfClass:[Kdb4Entry class]]) {
Kdb4Entry *entry = (Kdb4Entry *)self.viewController.selectedEntry;
BinaryRef *binaryRef = entry.binaries[row];
[[view textField] bind:NSValueBinding toObject:binaryRef withKeyPath:@"key" options:nil];
[[view imageView] setImage:[[NSWorkspace sharedWorkspace] iconForFileType:[binaryRef.key pathExtension]]];
}
else {
// Create view to support only one binary!
}
return view;
}
- (NSTableRowView *)tableView:(NSTableView *)tableView rowViewForRow:(NSInteger)row {
HNHTableRowView *view = nil;
view = [[HNHTableRowView alloc] init];
view.selectionCornerRadius = 7;
return view;
}
@end

View File

@@ -10,8 +10,8 @@
@interface MPCustomFieldTableCellView : NSTableCellView @interface MPCustomFieldTableCellView : NSTableCellView
@property (weak) IBOutlet NSTextField *labelTextField; @property (nonatomic, weak) IBOutlet NSTextField *labelTextField;
@property (weak) IBOutlet NSTextField *valueTextField; @property (nonatomic, weak) IBOutlet NSTextField *valueTextField;
@property (weak) IBOutlet NSButton *removeButton; @property (nonatomic, weak) IBOutlet NSButton *removeButton;
@end @end

View File

@@ -0,0 +1,17 @@
//
// MPCustomFieldTableDelegate.h
// MacPass
//
// Created by Michael Starke on 17.07.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import <Foundation/Foundation.h>
@class MPInspectorViewController;
@interface MPCustomFieldTableViewDelegate : NSObject <NSTableViewDelegate>
@property (nonatomic, weak) MPInspectorViewController *viewController;
@end

View File

@@ -0,0 +1,42 @@
//
// MPCustomFieldTableDelegate.m
// MacPass
//
// Created by Michael Starke on 17.07.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import "MPCustomFieldTableViewDelegate.h"
#import "MPInspectorViewController.h"
#import "MPCustomFieldTableCellView.h"
#import "Kdb4Node.h"
#import "StringField+Undo.h"
@implementation MPCustomFieldTableViewDelegate
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
if(![self.viewController.selectedEntry isKindOfClass:[Kdb4Entry class]]) {
return nil;
}
Kdb4Entry *entry = (Kdb4Entry *)self.viewController.selectedEntry;
MPCustomFieldTableCellView *view = [tableView makeViewWithIdentifier:@"SelectedCell" owner:tableView];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_customFieldFrameChanged:) name:NSViewFrameDidChangeNotification object:view];
if([self.viewController.selectedEntry isKindOfClass:[Kdb4Entry class]]) {
StringField *stringField = entry.stringFields[row];
NSDictionary *validateOptions = @{ NSValidatesImmediatelyBindingOption: @YES };
[view.labelTextField bind:NSValueBinding toObject:stringField withKeyPath:MPStringFieldKeyUndoableKey options:validateOptions];
[view.valueTextField bind:NSValueBinding toObject:stringField withKeyPath:MPStringFieldValueUndoableKey options:nil];
[view.removeButton setTarget:self.viewController];
[view.removeButton setAction:@selector(removeCustomField:)];
[view.removeButton setTag:row];
}
return view;
}
- (void)_customFieldFrameChanged:(NSNotification *)notification {
// NSView *sender = [notification object];
// NSLog(@"didChangeFrameFor: %@ to: %@", sender, NSStringFromRect([sender frame]));
}
@end

View File

@@ -8,20 +8,36 @@
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
typedef NS_ENUM(NSUInteger, MPDatabaseSettingsTab) {
MPDatabaseSettingsTabGeneral,
MPDatabaseSettingsTabPassword,
MPDatabaseSettingsTabDisplay,
MPDatabaseSettingsTabAdvanced
};
@class MPDocument; @class MPDocument;
@class HNHRoundedSecureTextField;
@interface MPDocumentSettingsWindowController : NSWindowController @interface MPDatabaseSettingsWindowController : NSWindowController <NSTextFieldDelegate>
@property (weak) IBOutlet NSTabView *sectionTabView; @property (weak) IBOutlet NSTabView *sectionTabView;
@property (weak) IBOutlet NSButton *saveButton;
@property (weak) IBOutlet NSButton *cancelButton;
/* General Tab */ /* General Tab */
@property (weak) IBOutlet NSTextField *databaseNameTextField; @property (weak) IBOutlet NSTextField *databaseNameTextField;
@property (unsafe_unretained) IBOutlet NSTextView *databaseDescriptionTextView; @property (unsafe_unretained) IBOutlet NSTextView *databaseDescriptionTextView;
/* Protection */ /* Protection */
@property (weak) IBOutlet NSTextField *passwordTextField; @property (weak) IBOutlet HNHRoundedSecureTextField *passwordTextField;
@property (weak) IBOutlet HNHRoundedSecureTextField *passwordRepeatTextField;
@property (weak) IBOutlet NSPathControl *keyfilePathControl; @property (weak) IBOutlet NSPathControl *keyfilePathControl;
@property (weak) IBOutlet NSButton *togglePasswordButton;
@property (weak) IBOutlet NSTextField *errorTextField;
- (IBAction)clearKey:(id)sender;
- (IBAction)generateKey:(id)sender;
/* Display Tab */ /* Display Tab */
@property (weak) IBOutlet NSButton *protectTitleCheckButton; @property (weak) IBOutlet NSButton *protectTitleCheckButton;
@@ -30,13 +46,15 @@
@property (weak) IBOutlet NSButton *protectURLCheckButton; @property (weak) IBOutlet NSButton *protectURLCheckButton;
@property (weak) IBOutlet NSButton *protectNotesCheckButton; @property (weak) IBOutlet NSButton *protectNotesCheckButton;
/* Advanced Tab*/ /* Advanced Tab*/
@property (weak) IBOutlet NSButton *enableRecycleBinCheckButton; @property (weak) IBOutlet NSButton *enableRecycleBinCheckButton;
@property (weak) IBOutlet NSButton *emptyRecycleBinOnQuitCheckButton; @property (weak) IBOutlet NSButton *emptyRecycleBinOnQuitCheckButton;
@property (weak) IBOutlet NSPopUpButton *selectRecycleBinGroupPopUpButton; @property (weak) IBOutlet NSPopUpButton *selectRecycleBinGroupPopUpButton;
- (id)initWithDocument:(MPDocument *)document; - (id)initWithDocument:(MPDocument *)document;
- (void)showSettingsTab:(MPDatabaseSettingsTab)tab;
- (void)update; - (void)update;
@end @end

View File

@@ -0,0 +1,247 @@
//
// MPDocumentSettingsWindowController.m
// MacPass
//
// Created by Michael Starke on 26.06.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import "MPDatabaseSettingsWindowController.h"
#import "MPDocument.h"
#import "MPDocumentWindowController.h"
#import "MPDatabaseVersion.h"
#import "MPIconHelper.h"
#import "HNHRoundedSecureTextField.h"
#import "NSString+Empty.h"
#import "Kdb.h"
#import "Kdb4Node.h"
#import "KdbGroup+MPAdditions.h"
@interface MPDatabaseSettingsWindowController () {
MPDocument *_document;
}
@property (nonatomic,assign) BOOL trashEnabled;
@property (nonatomic,assign) BOOL showPassword;
@property (nonatomic,assign) BOOL hasValidPasswordOrKey;
@property (nonatomic,weak) NSURL *keyURL;
@end
@implementation MPDatabaseSettingsWindowController
- (id)init {
return [self initWithDocument:nil];
}
- (id)initWithDocument:(MPDocument *)document {
self = [super initWithWindowNibName:@"DatabaseSettingsWindow"];
if(self) {
_document = document;
_showPassword = NO;
_hasValidPasswordOrKey = NO;
}
return self;
}
- (void)windowDidLoad {
[super windowDidLoad];
NSAssert(_document != nil, @"Document needs to be present");
[self.saveButton bind:NSEnabledBinding toObject:self withKeyPath:@"hasValidPasswordOrKey" options:nil];
[self.cancelButton bind:NSEnabledBinding toObject:self withKeyPath:@"hasValidPasswordOrKey" options:nil];
Kdb4Tree *tree = _document.treeV4;
if( tree ) {
[self _setupDatabase:tree];
[self _setupProtectionTab:tree];
[self _setupAdvancedTab:tree];
[self _setupPasswordTab:tree];
}
else {
// Switch to KdbV3 View
}
}
- (IBAction)save:(id)sender {
/* Protection */
_document.password = [self.passwordTextField stringValue];
_document.key = [self.keyfilePathControl URL];
/* General */
_document.treeV4.databaseDescription = [self.databaseDescriptionTextView string];
_document.treeV4.databaseName = [self.databaseNameTextField stringValue];
/* Display */
/* Advanced */
_document.treeV4.recycleBinEnabled = self.trashEnabled;
NSMenuItem *menuItem = [self.selectRecycleBinGroupPopUpButton selectedItem];
KdbGroup *group = [menuItem representedObject];
[_document useGroupAsTrash:group];
_document.treeV4.protectNotes = [self.protectNotesCheckButton state] == NSOnState;
_document.treeV4.protectPassword = [self.protectPasswortCheckButton state] == NSOnState;
_document.treeV4.protectTitle = [self.protectTitleCheckButton state] == NSOnState;
_document.treeV4.protectUrl = [self.protectURLCheckButton state] == NSOnState;
_document.treeV4.protectUserName = [self.protectUserNameCheckButton state] == NSOnState;
/* Close to finish */
[self close:nil];
}
- (IBAction)close:(id)sender {
[NSApp endSheet:[self window]];
[[self window] orderOut:nil];
}
- (void)update {
/* Update all stuff that might have changed */
Kdb4Tree *tree = _document.treeV4;
if(tree) {
[self _setupDatabase:tree];
[self _setupProtectionTab:tree];
[self _setupAdvancedTab:tree];
[self _setupPasswordTab:tree];
}
}
- (void)showSettingsTab:(MPDatabaseSettingsTab)tab {
self.showPassword = NO;
[self.sectionTabView selectTabViewItemAtIndex:tab];
}
- (void)setShowPassword:(BOOL)showPassword {
if(_showPassword != showPassword) {
_showPassword = showPassword;
[self.passwordRepeatTextField setStringValue:@""];
[self _verifyPasswordAndKey];
}
}
- (void)setKeyURL:(NSURL *)keyURL {
_keyURL = keyURL;
[self _verifyPasswordAndKey];
}
#pragma mark Actions
- (IBAction)clearKey:(id)sender {
self.keyURL = nil;
}
- (IBAction)generateKey:(id)sender {
}
#pragma makr NSTextFieldDelegate
- (void)controlTextDidChange:(NSNotification *)obj {
[self _verifyPasswordAndKey];
}
#pragma mark Private Helper
- (void)_verifyPasswordAndKey {
NSString *password = [self.passwordTextField stringValue];
NSString *repeat = [self.passwordRepeatTextField stringValue];
BOOL hasKey = (self.keyURL != nil);
BOOL keyOk = YES;
if(hasKey) {
keyOk = [self.keyURL checkResourceIsReachableAndReturnError:nil];
}
BOOL hasPassword = ![password isEmpty];
BOOL passwordOk = YES;
if(hasPassword ) {
passwordOk = [password isEqualToString:repeat] || self.showPassword;
}
BOOL hasPasswordOrKey = (hasKey || hasPassword);
keyOk = hasKey ? keyOk : YES;
passwordOk = hasPassword ? passwordOk : YES;
self.hasValidPasswordOrKey = hasPasswordOrKey && passwordOk && keyOk;
if(!hasPasswordOrKey) {
[self.errorTextField setStringValue:NSLocalizedString(@"ERROR_NO_PASSWORD_OR_KEYFILE", "Missing Key or Password")];
return; // alldone
}
if(!passwordOk && !keyOk ) {
[self.errorTextField setStringValue:NSLocalizedString(@"ERROR_PASSWORD_MISSMATCH_INVALID_KEYFILE", "Passwords do not match, keyfile is invalid")];
}
else if(!passwordOk) {
[self.errorTextField setStringValue:NSLocalizedString(@"ERROR_PASSWORD_MISSMATCH", "Passwords do not match")];
}
else {
[self.errorTextField setStringValue:NSLocalizedString(@"ERROR_INVALID_KEYFILE", "Keyfile not valid")];
}
}
- (void)_setupDatabase:(Kdb4Tree *)tree {
[self.databaseNameTextField setStringValue:tree.databaseName];
[self.databaseDescriptionTextView setString:tree.databaseDescription];
}
- (void)_setupProtectionTab:(Kdb4Tree *)tree {
[self.protectNotesCheckButton setState:tree.protectNotes ? NSOnState : NSOffState ];
[self.protectNotesCheckButton setState:tree.protectPassword ? NSOnState : NSOffState];
[self.protectTitleCheckButton setState:tree.protectTitle ? NSOnState : NSOffState];
[self.protectURLCheckButton setState:tree.protectUrl ? NSOnState : NSOffState];
[self.protectUserNameCheckButton setState:tree.protectUserName ? NSOnState : NSOffState];
}
- (void)_setupAdvancedTab:(Kdb4Tree *)tree {
self.trashEnabled = tree.recycleBinEnabled;
[self.enableRecycleBinCheckButton bind:NSValueBinding toObject:self withKeyPath:@"trashEnabled" options:nil];
[self.selectRecycleBinGroupPopUpButton bind:NSEnabledBinding toObject:self withKeyPath:@"trashEnabled" options:nil];
[self _updateTrashFolders:tree];
}
- (void)_setupPasswordTab:(Kdb4Tree *)tree {
[self.passwordTextField setStringValue:_document.password ? _document.password : @""];
[self.passwordRepeatTextField setStringValue:[self.passwordRepeatTextField stringValue]];
self.keyURL = _document.key;
NSDictionary *negateOption = @{ NSValueTransformerNameBindingOption : NSNegateBooleanTransformerName };
[self.passwordTextField bind:@"showPassword" toObject:self withKeyPath:@"showPassword" options:nil];
[self.togglePasswordButton bind:NSValueBinding toObject:self withKeyPath:@"showPassword" options:nil];
[self.passwordRepeatTextField bind:NSEnabledBinding toObject:self withKeyPath:@"showPassword" options:negateOption];
[self.errorTextField bind:NSHiddenBinding toObject:self withKeyPath:@"hasValidPasswordOrKey" options:nil];
[self.keyfilePathControl bind:NSValueBinding toObject:self withKeyPath:@"keyURL" options:nil];
[self.passwordRepeatTextField setDelegate:self];
[self.passwordTextField setDelegate:self];
/* Manually initate the first check */
[self _verifyPasswordAndKey];
}
- (void)_updateTrashFolders:(Kdb4Tree *)tree {
NSMenu *menu = [self _buildTreeMenu:tree];
[self.selectRecycleBinGroupPopUpButton setMenu:menu];
}
- (NSMenu *)_buildTreeMenu:(Kdb4Tree *)tree {
NSMenu *menu = [[NSMenu alloc] init];
[menu setAutoenablesItems:NO];
for(Kdb4Group *group in tree.root.groups) {
NSMenuItem *groupItem = [[NSMenuItem alloc] init];
[groupItem setImage:group.icon];
[groupItem setTitle:group.name];
[groupItem setRepresentedObject:group];
[groupItem setEnabled:YES];
if([group.uuid isEqual:tree.recycleBinUuid]) {
[groupItem setState:NSOnState];
}
[menu addItem:groupItem];
}
NSMenuItem *selectItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"SELECT_RECYCLEBIN", @"Menu item if no reycleBin is selected") action:NULL keyEquivalent:@""];
[selectItem setEnabled:YES];
[menu insertItem:selectItem atIndex:0];
return menu;
}
@end

View File

@@ -0,0 +1,147 @@
//
// MPDocument+Attachments.m
// MacPass
//
// Created by Michael Starke on 05.07.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import "MPDocument.h"
#import "NSMutableData+Base64.h"
#import "NSData+Gzip.h"
#import "Kdb3Node.h"
#import "Kdb4Node.h"
#import "Kdb4Entry+KVOAdditions.h"
@implementation MPDocument (Attachments)
- (void)addAttachment:(NSURL *)location toEntry:(KdbEntry *)anEntry {
NSError *error = nil;
NSString *fileName = [location lastPathComponent];
if([anEntry isKindOfClass:[Kdb3Entry class]]) {
Kdb3Entry *entry = (Kdb3Entry *)anEntry;
NSData *binaryData = [NSData dataWithContentsOfURL:location options:NSDataReadingUncached error:&error];
if(!binaryData) {
[NSApp presentError:error];
binaryData = nil;
error = nil;
return; // failed
}
entry.binary = binaryData;
entry.binaryDesc = fileName;
}
if( [anEntry isKindOfClass:[Kdb4Entry class]]) {
Kdb4Entry *entry = (Kdb4Entry *)anEntry;
NSData *fileData = [NSData dataWithContentsOfURL:location options:NSDataReadingMappedIfSafe error:&error];
if(!fileData) {
[NSApp presentError:error];
fileData = nil;
error = nil;
return; // failed
}
Binary *binary = [[Binary alloc] init];
NSUInteger nextId = [self nextBinaryId];
if(nextId == NSNotFound) {
binary = nil;
return; // No id found. Something went wrong
}
binary.binaryId = nextId;
binary.compressed = (self.treeV4.compressionAlgorithm != KPLCompressionNone);
NSData *encodedData;
if(binary.compressed) {
switch(self.treeV4.compressionAlgorithm) {
case KPLCompressionGzip: {
NSData *compressedData = [fileData gzipDeflate];
encodedData = [NSMutableData mutableDataWithBase64EncodedData:compressedData];
break;
}
default:
NSAssert(NO, @"Unsupported Compression Algorithm");
binary = nil;
encodedData = nil;
fileData = nil;
return;
}
}
else {
encodedData = fileData;
}
binary.data = [[NSString alloc] initWithData:encodedData encoding:NSASCIIStringEncoding];
[self.treeV4.binaries addObject:binary];
BinaryRef *ref = [[BinaryRef alloc] init];
ref.key = fileName;
ref.ref = binary.binaryId;
[entry insertObject:ref inBinariesAtIndex:[entry.binaries count]];
}
}
- (void)saveAttachmentFromEntry:(KdbEntry *)anEntry toLocation:(NSURL *)location {
if([anEntry isKindOfClass:[Kdb3Entry class]]) {
Kdb3Entry *entry = (Kdb3Entry *)anEntry;
NSError *error = nil;
if(! [entry.binary writeToURL:location options:NSDataWritingWithoutOverwriting error:&error] ) {
[NSApp presentError:error];
}
}
return; //
}
- (void)removeAttachment:(BinaryRef *)reference fromEntry:(KdbEntry *)anEntry {
if(self.version != MPDatabaseVersion4) {
return; // Wrong Database version;
}
Binary *binary = [self findBinary:reference];
Kdb4Entry *entry = (Kdb4Entry *)anEntry;
NSUInteger index = [entry.binaries indexOfObject:reference];
if(index == NSNotFound) {
return; // No Reference for this entry found
}
[entry removeObjectFromBinariesAtIndex:index];
[self.treeV4.binaries removeObject:binary];
}
- (Binary *)findBinary:(BinaryRef *)reference {
if(self.version != MPDatabaseVersion4) {
return nil;
}
NSPredicate *filterPredicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
Binary *binaryFile = evaluatedObject;
return (binaryFile.binaryId == reference.ref);
}];
NSArray *filteredBinary = [self.treeV4.binaries filteredArrayUsingPredicate:filterPredicate];
return [filteredBinary lastObject];
}
- (void)saveAttachment:(BinaryRef *)reference toLocation:(NSURL *)location {
Binary *binary = [self findBinary:reference];
NSData *rawData = nil;
if(binary) {
if(binary.compressed) {
rawData = [NSMutableData mutableDataWithBase64DecodedData:[binary.data dataUsingEncoding:NSASCIIStringEncoding]];
rawData = [rawData gzipInflate];
}
else {
rawData = [NSMutableData mutableDataWithBase64DecodedData:[binary.data dataUsingEncoding:NSASCIIStringEncoding]];
}
NSError *error = nil;
if( ![rawData writeToURL:location options:0 error:&error] ) {
[NSApp presentError:error];
}
}
}
- (NSUInteger)nextBinaryId {
if(self.version != MPDatabaseVersion4) {
return NSNotFound;
}
NSUInteger maxKey = 0;
for(Binary *binary in self.treeV4.binaries) {
maxKey = MAX(binary.binaryId, maxKey);
}
return (maxKey + 1);
}
@end

View File

@@ -34,22 +34,26 @@ APPKIT_EXTERN NSString *const MPDocumentGroupKey;
@interface MPDocument : NSDocument @interface MPDocument : NSDocument
/* true, if password and/or keyfile are set */ /* true, if password and/or keyfile are set */
@property (assign, readonly, getter = isSecured) BOOL secured; @property (assign, readonly) BOOL hasPasswordOrKey;
/* true, if lock screen is present (no phyiscal locking) */ /* true, if lock screen is present (no phyiscal locking) */
@property (assign, getter = isLocked) BOOL locked; @property (assign, nonatomic) BOOL locked;
/* true, if document is loaded and decrypted (tree is loaded) */ @property (assign, readonly) BOOL decrypted;
@property (assign, readonly, getter = isDecrypted) BOOL decrypted;
@property (strong, readonly, nonatomic) KdbTree *tree; @property (strong, readonly, nonatomic) KdbTree *tree;
@property (weak, readonly, nonatomic) KdbGroup *root; @property (weak, readonly, nonatomic) KdbGroup *root;
@property (readonly, strong) MPRootAdapter *rootAdapter; @property (readonly, strong) MPRootAdapter *rootAdapter;
@property (nonatomic, strong) NSString *password;
@property (nonatomic, copy) NSString *password;
@property (nonatomic, strong) NSURL *key; @property (nonatomic, strong) NSURL *key;
@property (assign, readonly) MPDatabaseVersion version; @property (assign, readonly) MPDatabaseVersion version;
@property (assign, readonly, getter = isReadOnly) BOOL readOnly; @property (assign, readonly, getter = isReadOnly) BOOL readOnly;
- (id)initWithVersion:(MPDatabaseVersion)version; - (id)initWithVersion:(MPDatabaseVersion)version;
- (BOOL)decryptWithPassword:(NSString *)password keyFileURL:(NSURL *)keyFileURL;
#pragma mark Lock/Decrypt
- (void)lockDatabase:(id)sender;
- (BOOL)unlockWithPassword:(NSString *)password keyFileURL:(NSURL *)keyFileURL;
#pragma mark Data Lookup #pragma mark Data Lookup
/* /*
@@ -57,16 +61,14 @@ APPKIT_EXTERN NSString *const MPDocumentGroupKey;
*/ */
- (KdbEntry *)findEntry:(UUID *)uuid; - (KdbEntry *)findEntry:(UUID *)uuid;
- (KdbGroup *)findGroup:(UUID *)uuid; - (KdbGroup *)findGroup:(UUID *)uuid;
/*
Return the Binary for the given BinaryRef. nil if none was found
*/
- (Binary *)binaryForRef:(BinaryRef *)binaryRef;
- (Kdb4Tree *)treeV4; - (Kdb4Tree *)treeV4;
- (Kdb3Tree *)treeV3; - (Kdb3Tree *)treeV3;
- (void)useGroupAsTrash:(KdbGroup *)group; - (void)useGroupAsTrash:(KdbGroup *)group;
#pragma mark Export
- (void)writeXMLToURL:(NSURL *)url;
#pragma mark Undo Data Manipulation #pragma mark Undo Data Manipulation
/* Undoable Intiialization of elements */ /* Undoable Intiialization of elements */
@@ -77,19 +79,26 @@ APPKIT_EXTERN NSString *const MPDocumentGroupKey;
/* /*
All non-setter undoable actions All non-setter undoable actions
*/ */
- (void)moveGroup:(KdbGroup *)group toGroup:(KdbGroup *)target index:(NSInteger)index;
- (BOOL)group:(KdbGroup *)group isMoveableToGroup:(KdbGroup *)target; - (BOOL)group:(KdbGroup *)group isMoveableToGroup:(KdbGroup *)target;
- (void)moveEntry:(KdbEntry *)entry toGroup:(KdbGroup *)target index:(NSInteger)index;
- (void)group:(KdbGroup *)group addEntry:(KdbEntry *)entry atIndex:(NSUInteger)index; /* TODO in UNDO auslagen */
- (void)group:(KdbGroup *)group addGroup:(KdbGroup *)aGroup atIndex:(NSUInteger)index; - (void)addStringField:(StringField *)field toEntry:(Kdb4Entry *)entry atIndex:(NSUInteger)index;
- (void)group:(KdbGroup *)group removeEntry:(KdbEntry *)entry; - (void)removeStringField:(StringField *)field formEntry:(Kdb4Entry *)entry;
- (void)group:(KdbGroup *)group removeGroup:(KdbGroup *)aGroup;
- (void)entry:(Kdb4Entry *)entry addStringField:(StringField *)field atIndex:(NSUInteger)index; - (void)deleteGroup:(KdbGroup *)group;
- (void)entry:(Kdb4Entry *)entry removeStringField:(StringField *)field; - (void)deleteEntry:(KdbEntry *)entry;
- (void)emptyTrash:(id)sender; - (void)emptyTrash:(id)sender;
@end @end
@interface MPDocument (Attachments)
- (void)addAttachment:(NSURL *)location toEntry:(KdbEntry *)anEntry;
- (void)saveAttachmentFromEntry:(KdbEntry *)anEntry toLocation:(NSURL *)location;
- (void)saveAttachment:(BinaryRef *)reference toLocation:(NSURL *)location;
- (void)removeAttachment:(BinaryRef *)reference fromEntry:(KdbEntry *)anEntry;
- (NSUInteger)nextBinaryId;
- (Binary *)findBinary:(BinaryRef *)reference;
@end

View File

@@ -17,15 +17,24 @@
#import "KdbLib.h" #import "KdbLib.h"
#import "Kdb3Node.h" #import "Kdb3Node.h"
#import "Kdb4Node.h" #import "Kdb4Node.h"
#import "Kdb4Persist.h"
#import "KdbPassword.h" #import "KdbPassword.h"
#import "KdbGroup+Undo.h"
#import "KdbGroup+KVOAdditions.h" #import "KdbGroup+KVOAdditions.h"
#import "Kdb4Entry+KVOAdditions.h" #import "Kdb4Entry+KVOAdditions.h"
#import "KdbGroup+MPTreeTools.h"
#import "KdbGroup+MPAdditions.h"
#import "KdbEntry+Undo.h" #import "KdbEntry+Undo.h"
#import "KdbGroup+Undo.h"
#import "Kdb3Tree+NewTree.h" #import "Kdb3Tree+NewTree.h"
#import "Kdb4Tree+NewTree.h" #import "Kdb4Tree+NewTree.h"
#import "Kdb4Entry+MPAdditions.h"
#import "KdbGroup+MPTreeTools.h"
#import "KdbGroup+MPAdditions.h"
#import "DataOutputStream.h"
#import "DDXMLNode.h"
NSString *const MPDocumentDidAddGroupNotification = @"com.hicknhack.macpass.MPDocumentDidAddGroupNotification"; NSString *const MPDocumentDidAddGroupNotification = @"com.hicknhack.macpass.MPDocumentDidAddGroupNotification";
NSString *const MPDocumentWillDelteGroupNotification = @"com.hicknhack.macpass.MPDocumentDidDelteGroupNotification"; NSString *const MPDocumentWillDelteGroupNotification = @"com.hicknhack.macpass.MPDocumentDidDelteGroupNotification";
@@ -40,6 +49,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
@interface MPDocument () { @interface MPDocument () {
@private @private
BOOL _didLockFile; BOOL _didLockFile;
NSData *_fileData;
} }
@@ -48,7 +58,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
@property (weak, nonatomic, readonly) KdbPassword *passwordHash; @property (weak, nonatomic, readonly) KdbPassword *passwordHash;
@property (assign) MPDatabaseVersion version; @property (assign) MPDatabaseVersion version;
@property (assign, nonatomic) BOOL secured; @property (assign, nonatomic) BOOL hasPasswordOrKey;
@property (assign) BOOL decrypted; @property (assign) BOOL decrypted;
@property (assign) BOOL readOnly; @property (assign) BOOL readOnly;
@@ -56,6 +66,8 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
@property (readonly) BOOL useTrash; @property (readonly) BOOL useTrash;
@property (weak, readonly) KdbGroup *trash; @property (weak, readonly) KdbGroup *trash;
@property (strong) IBOutlet NSView *warningView;
@property (weak) IBOutlet NSImageView *warningViewImage;
@end @end
@@ -70,9 +82,10 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
- (id)initWithVersion:(MPDatabaseVersion)version { - (id)initWithVersion:(MPDatabaseVersion)version {
self = [super init]; self = [super init];
if(self) { if(self) {
_fileData = nil;
_didLockFile = NO; _didLockFile = NO;
_decrypted = YES; _decrypted = YES;
_secured = NO; _hasPasswordOrKey = NO;
_locked = NO; _locked = NO;
_readOnly = NO; _readOnly = NO;
_rootAdapter = [[MPRootAdapter alloc] init]; _rootAdapter = [[MPRootAdapter alloc] init];
@@ -83,6 +96,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
break; break;
case MPDatabaseVersion4: case MPDatabaseVersion4:
self.tree = [Kdb4Tree templateTree]; self.tree = [Kdb4Tree templateTree];
//self.tree = [Kdb4Tree demoTree];
break; break;
default: default:
self = nil; self = nil;
@@ -117,6 +131,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
} }
- (BOOL)readFromURL:(NSURL *)url ofType:(NSString *)typeName error:(NSError **)outError { - (BOOL)readFromURL:(NSURL *)url ofType:(NSString *)typeName error:(NSError **)outError {
/* FIXME: Logfile handling
self.lockFileURL = [url URLByAppendingPathExtension:@"lock"]; self.lockFileURL = [url URLByAppendingPathExtension:@"lock"];
if([[NSFileManager defaultManager] fileExistsAtPath:[_lockFileURL path]]) { if([[NSFileManager defaultManager] fileExistsAtPath:[_lockFileURL path]]) {
self.readOnly = YES; self.readOnly = YES;
@@ -126,6 +141,12 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
_didLockFile = YES; _didLockFile = YES;
self.readOnly = NO; self.readOnly = NO;
} }
*/
/*
Delete our old Tree, and just grab the data
*/
self.tree = nil;
_fileData = [NSData dataWithContentsOfURL:url options:NSDataReadingUncached error:outError];
self.decrypted = NO; self.decrypted = NO;
return YES; return YES;
} }
@@ -148,9 +169,16 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
[super close]; [super close];
} }
#pragma mark Protection - (void)writeXMLToURL:(NSURL *)url {
DataOutputStream *outputStream = [[DataOutputStream alloc] init];
Kdb4Persist *persist = [[Kdb4Persist alloc] initWithTree:self.treeV4 outputStream:outputStream randomStream:nil];
[persist persistWithOptions:DDXMLNodeCompactEmptyElement|DDXMLNodePrettyPrint];
[outputStream.data writeToURL:url atomically:YES];
}
- (BOOL)decryptWithPassword:(NSString *)password keyFileURL:(NSURL *)keyFileURL { #pragma mark Lock/Unlock/Decrypt
- (BOOL)unlockWithPassword:(NSString *)password keyFileURL:(NSURL *)keyFileURL {
self.key = keyFileURL; self.key = keyFileURL;
self.password = [password length] > 0 ? password : nil; self.password = [password length] > 0 ? password : nil;
@try { @try {
@@ -170,17 +198,26 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
return YES; return YES;
} }
- (void)lockDatabase:(id)sender {
// Persist Tree into data
self.tree = nil;
self.locked = YES;
}
#pragma mark Custom Setter
- (void)setPassword:(NSString *)password { - (void)setPassword:(NSString *)password {
if(![_password isEqualToString:password]) { if(![_password isEqualToString:password]) {
_password = password; _password = [password copy];
_secured |= ([_password length] > 0); [self _updateIsSecured];
} }
} }
- (void)setKey:(NSURL *)key { - (void)setKey:(NSURL *)key {
if(![[_key absoluteString] isEqualToString:[key absoluteString]]) { if(![[_key absoluteString] isEqualToString:[key absoluteString]]) {
_key = key; _key = key;
_secured |= (_key != nil); [self _updateIsSecured];
} }
} }
@@ -194,6 +231,19 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
return NO; return NO;
} }
- (BOOL)prepareSavePanel:(NSSavePanel *)savePanel {
if(self.hasPasswordOrKey) {
[savePanel setAccessoryView:nil];
return YES;
}
if(!self.warningView) {
[[NSBundle mainBundle] loadNibNamed:@"UnprotectedWarningView" owner:self topLevelObjects:nil];
[self.warningViewImage setImage:[NSImage imageNamed:NSImageNameCaution]];
}
[savePanel setAccessoryView:self.warningView];
return YES;
}
#pragma mark Data Accesors #pragma mark Data Accesors
- (void)setTree:(KdbTree *)tree { - (void)setTree:(KdbTree *)tree {
if(_tree != tree) { if(_tree != tree) {
@@ -214,23 +264,10 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
return [self.root groupForUUID:uuid]; return [self.root groupForUUID:uuid];
} }
- (Binary *)binaryForRef:(BinaryRef *)binaryRef {
if(self.version != MPDatabaseVersion4) {
return nil;
}
NSPredicate *filterPredicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
Binary *binaryFile = evaluatedObject;
return (binaryFile.binaryId == binaryRef.ref);
}];
Kdb4Tree *tree = (Kdb4Tree *)self.tree;
NSArray *filteredBinary = [tree.binaries filteredArrayUsingPredicate:filterPredicate];
return [filteredBinary lastObject];
}
- (Kdb3Tree *)treeV3 { - (Kdb3Tree *)treeV3 {
switch (_version) { switch (_version) {
case MPDatabaseVersion3: case MPDatabaseVersion3:
NSAssert([self.tree isKindOfClass:[Kdb3Tree class]], @"Tree has to be Version3"); NSAssert(self.tree == nil || [self.tree isKindOfClass:[Kdb3Tree class]], @"Tree has to be Version3");
return (Kdb3Tree *)self.tree; return (Kdb3Tree *)self.tree;
case MPDatabaseVersion4: case MPDatabaseVersion4:
return nil; return nil;
@@ -244,7 +281,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
case MPDatabaseVersion3: case MPDatabaseVersion3:
return nil; return nil;
case MPDatabaseVersion4: case MPDatabaseVersion4:
NSAssert([self.tree isKindOfClass:[Kdb4Tree class]], @"Tree has to be Version4"); NSAssert(self.tree == nil || [self.tree isKindOfClass:[Kdb4Tree class]], @"Tree has to be Version4");
return (Kdb4Tree *)self.tree; return (Kdb4Tree *)self.tree;
default: default:
return nil; return nil;
@@ -289,7 +326,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
if(self.treeV4 && ([self.treeV4.defaultUserName length] > 0)) { if(self.treeV4 && ([self.treeV4.defaultUserName length] > 0)) {
newEntry.title = self.treeV4.defaultUserName; newEntry.title = self.treeV4.defaultUserName;
} }
[self group:parent addEntry:newEntry atIndex:[parent.entries count]]; [parent addEntryUndoable:newEntry atIndex:[parent.entries count]];
NSDictionary *userInfo = @{ MPDocumentEntryKey : newEntry }; NSDictionary *userInfo = @{ MPDocumentEntryKey : newEntry };
[[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidAddEntryNotification object:self userInfo:userInfo]; [[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidAddEntryNotification object:self userInfo:userInfo];
return newEntry; return newEntry;
@@ -301,7 +338,8 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
} }
KdbGroup *newGroup = [self.tree createGroup:parent]; KdbGroup *newGroup = [self.tree createGroup:parent];
newGroup.name = NSLocalizedString(@"DEFAULT_GROUP_NAME", @"Title for a newly created group"); newGroup.name = NSLocalizedString(@"DEFAULT_GROUP_NAME", @"Title for a newly created group");
[self group:parent addGroup:newGroup atIndex:[parent.groups count]]; newGroup.image = MPIconFolder;
[parent addGroupUndoable:newGroup atIndex:[parent.groups count]];
NSDictionary *userInfo = @{ MPDocumentGroupKey : newGroup }; NSDictionary *userInfo = @{ MPDocumentGroupKey : newGroup };
[[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidAddGroupNotification object:self userInfo:userInfo]; [[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidAddGroupNotification object:self userInfo:userInfo];
return newGroup; return newGroup;
@@ -315,12 +353,12 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
Kdb4Entry *entryV4 = (Kdb4Entry *)entry; Kdb4Entry *entryV4 = (Kdb4Entry *)entry;
NSString *title = NSLocalizedString(@"DEFAULT_CUSTOM_FIELD_TITLE", @"Default Titel for new Custom-Fields"); NSString *title = NSLocalizedString(@"DEFAULT_CUSTOM_FIELD_TITLE", @"Default Titel for new Custom-Fields");
NSString *value = NSLocalizedString(@"DEFAULT_CUSTOM_FIELD_VALUE", @"Default Value for new Custom-Fields"); NSString *value = NSLocalizedString(@"DEFAULT_CUSTOM_FIELD_VALUE", @"Default Value for new Custom-Fields");
title = [entryV4 uniqueKeyForProposal:title];
StringField *newStringField = [StringField stringFieldWithKey:title andValue:value]; StringField *newStringField = [StringField stringFieldWithKey:title andValue:value];
[self entry:entryV4 addStringField:newStringField atIndex:[entryV4.stringFields count]]; [self addStringField:newStringField toEntry:entryV4 atIndex:[entryV4.stringFields count]];
return newStringField; return newStringField;
} }
- (void)moveGroup:(KdbGroup *)group toGroup:(KdbGroup *)target index:(NSInteger)index { - (void)moveGroup:(KdbGroup *)group toGroup:(KdbGroup *)target index:(NSInteger)index {
NSInteger oldIndex = [group.parent.groups indexOfObject:group]; NSInteger oldIndex = [group.parent.groups indexOfObject:group];
if(group.parent == target && oldIndex == index) { if(group.parent == target && oldIndex == index) {
@@ -357,112 +395,88 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
return isMovable; return isMovable;
} }
- (void)moveEntry:(KdbEntry *)entry toGroup:(KdbGroup *)target index:(NSInteger)index { - (void)deleteEntry:(KdbEntry *)entry {
NSInteger oldIndex = [entry.parent.entries indexOfObject:entry]; if(self.useTrash) {
if(entry.parent == target && oldIndex == index) { if(!self.trash) {
return; // No changes [self _createTrashGroup];
} }
[[[self undoManager] prepareWithInvocationTarget:self] moveEntry:entry toGroup:entry.parent index:oldIndex]; [entry moveToTrashUndoable:self.trash atIndex:[self.trash.entries count]];
if(self.trash == target || self.trash == entry.parent) {
[[self undoManager] setActionName:@"UNDO_DELETE_ENTRY"];
} }
else { else {
[[self undoManager] setActionName:@"MOVE_ENTRY"]; [entry deleteUndoable];
} }
[entry.parent removeObjectFromEntriesAtIndex:oldIndex];
if(index < 0 || index > [target.groups count] ) {
index = [target.groups count];
}
[target insertObject:entry inEntriesAtIndex:index];
} }
- (void)group:(KdbGroup *)group addEntry:(KdbEntry *)entry atIndex:(NSUInteger)index { - (void)deleteGroup:(KdbGroup *)group {
[[[self undoManager] prepareWithInvocationTarget:self] group:group removeEntry:entry];
[[self undoManager] setActionName:NSLocalizedString(@"UNDO_ADD_ENTRY", "Undo adding of entry")];
[group insertObject:entry inEntriesAtIndex:index];
}
- (void)group:(KdbGroup *)group addGroup:(KdbGroup *)aGroup atIndex:(NSUInteger)index {
[[[self undoManager] prepareWithInvocationTarget:self] group:group removeGroup:aGroup];
[[self undoManager] setActionName:NSLocalizedString(@"UNDO_ADD_GROUP", @"Create Group Undo")];
[group insertObject:aGroup inGroupsAtIndex:index];
}
- (void)group:(KdbGroup *)group removeEntry:(KdbEntry *)entry {
NSInteger index = [group.entries indexOfObject:entry];
if(NSNotFound == index) {
return; // No object found;
}
if(self.useTrash) { if(self.useTrash) {
if(!self.trash) { if(!self.trash) {
[self _createTrashGroup]; [self _createTrashGroup];
} }
[self moveEntry:entry toGroup:self.trash index:[self.trash.entries count]]; [group moveToTrashUndoable:self.trash atIndex:[self.trash.groups count]];
return; }
else {
[group deleteUndoable];
} }
[[[self undoManager] prepareWithInvocationTarget:self] group:group addEntry:entry atIndex:index];
[[self undoManager] setActionName:NSLocalizedString(@"UNDO_DELETE_ENTRY", "Undo deleting of entry")];
[group removeObjectFromEntriesAtIndex:index];
} }
- (void)group:(KdbGroup *)group removeGroup:(KdbGroup *)aGroup { #pragma mark CustomFields
NSInteger index = [group.groups indexOfObject:aGroup];
if(NSNotFound == index) {
return; // No object found
}
if(self.trash == aGroup) {
return;
// delete Trash?
}
/*
Cleaning the recyclebin is not undoable
So we do this in a separate action
*/
if(self.useTrash) {
if(!self.trash) {
[self _createTrashGroup];
}
[self moveGroup:aGroup toGroup:self.trash index:[self.trash.groups count]];
return; // Done!
}
[[[self undoManager] prepareWithInvocationTarget:self] group:group addGroup:aGroup atIndex:index];
[[self undoManager] setActionName:NSLocalizedString(@"UNDO_DELETE_GROUP", @"Delete Group Undo")];
[group removeObjectFromGroupsAtIndex:index];
}
- (void)entry:(Kdb4Entry *)entry addStringField:(StringField *)field atIndex:(NSUInteger)index { - (void)addStringField:(StringField *)field toEntry:(Kdb4Entry *)entry atIndex:(NSUInteger)index {
[[[self undoManager] prepareWithInvocationTarget:self] entry:entry removeStringField:field]; [[[self undoManager] prepareWithInvocationTarget:self] removeStringField:field formEntry:entry];
[[self undoManager] setActionName:NSLocalizedString(@"UNDO_ADD_STRING_FIELD", @"Add Stringfield Undo")]; [[self undoManager] setActionName:NSLocalizedString(@"UNDO_ADD_STRING_FIELD", @"Add Stringfield Undo")];
field.entry = entry;
[entry insertObject:field inStringFieldsAtIndex:index]; [entry insertObject:field inStringFieldsAtIndex:index];
} }
- (void)entry:(Kdb4Entry *)entry removeStringField:(StringField *)field { - (void)removeStringField:(StringField *)field formEntry:(Kdb4Entry *)entry {
NSInteger index = [entry.stringFields indexOfObject:field]; NSInteger index = [entry.stringFields indexOfObject:field];
if(NSNotFound == index) { if(NSNotFound == index) {
return; // Nothing found to be removed return; // Nothing found to be removed
} }
[[[self undoManager] prepareWithInvocationTarget:self] entry:entry addStringField:field atIndex:index]; [[[self undoManager] prepareWithInvocationTarget:self] addStringField:field toEntry:entry atIndex:index];
[[self undoManager] setActionName:NSLocalizedString(@"UNDO_DELETE_STRING_FIELD", @"Delte Stringfield undo")]; [[self undoManager] setActionName:NSLocalizedString(@"UNDO_DELETE_STRING_FIELD", @"Delte Stringfield undo")];
field.entry = nil;
[entry removeObjectFromStringFieldsAtIndex:index]; [entry removeObjectFromStringFieldsAtIndex:index];
} }
#pragma mark Actions #pragma mark Actions
- (void)emptyTrash:(id)sender { - (void)emptyTrash:(id)sender {
[[self undoManager] setActionIsDiscardable:YES]; NSAlert *alert = [[NSAlert alloc] init];
[self.trash clear]; [alert setAlertStyle:NSWarningAlertStyle];
[alert setMessageText:NSLocalizedString(@"WARNING_ON_EMPTY_TRASH_TITLE", "")];
[alert setInformativeText:NSLocalizedString(@"WARNING_ON_EMPTY_TRASH_DESCRIPTION", "Informative Text displayed when clearing the Trash")];
[alert addButtonWithTitle:NSLocalizedString(@"EMPTY_TRASH", "Empty Trash")];
[alert addButtonWithTitle:NSLocalizedString(@"CANCEL", "Cancel")];
[[alert buttons][1] setKeyEquivalent:[NSString stringWithFormat:@"%c", 0x1b]];
NSWindow *window = [[self windowControllers][0] window];
[alert beginSheetModalForWindow:window modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:NULL];
} }
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem { - (void) alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo {
if([menuItem action] == [MPActionHelper actionOfType:MPActionEmptyTrash]) { if(returnCode == NSAlertFirstButtonReturn) {
[self _emptyTrash];
}
}
- (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)anItem {
if([anItem action] == [MPActionHelper actionOfType:MPActionEmptyTrash]) {
BOOL hasGroups = [self.trash.groups count] > 0; BOOL hasGroups = [self.trash.groups count] > 0;
BOOL hasEntries = [self.trash.entries count] > 0; BOOL hasEntries = [self.trash.entries count] > 0;
return (hasEntries || hasGroups); return (hasEntries || hasGroups);
} }
return YES; return [super validateUserInterfaceItem:anItem];
} }
#pragma mark Private #pragma mark Private
- (void)_updateIsSecured {
BOOL securePassword = ([self.password length] > 0);
BOOL secureKey = (nil != self.key);
self.hasPasswordOrKey = (secureKey || securePassword);
}
- (void)_cleanupLock { - (void)_cleanupLock {
if(_didLockFile) { if(_didLockFile) {
[[NSFileManager defaultManager] removeItemAtURL:_lockFileURL error:nil]; [[NSFileManager defaultManager] removeItemAtURL:_lockFileURL error:nil];
@@ -477,7 +491,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
} }
else if(self.version == MPDatabaseVersion4) { else if(self.version == MPDatabaseVersion4) {
KdbGroup *trash = [self.tree createGroup:self.tree.root]; KdbGroup *trash = [self.tree createGroup:self.tree.root];
trash.name = NSLocalizedString(@"TRASH_GROUP", @"Name for the trash group"); trash.name = NSLocalizedString(@"TRASH", @"Name for the trash group");
trash.image = MPIconTrash; trash.image = MPIconTrash;
[self.tree.root insertObject:trash inGroupsAtIndex:[self.tree.root.groups count]]; [self.tree.root insertObject:trash inGroupsAtIndex:[self.tree.root.groups count]];
self.treeV4.recycleBinUuid = ((Kdb4Group *)trash).uuid; self.treeV4.recycleBinUuid = ((Kdb4Group *)trash).uuid;
@@ -489,4 +503,14 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
} }
} }
- (void)_emptyTrash {
for(KdbEntry *entry in [self.trash childEntries]) {
[[self undoManager] removeAllActionsWithTarget:entry];
}
for(KdbGroup *group in [self.trash childGroups]) {
[[self undoManager] removeAllActionsWithTarget:group];
}
[self.trash clear];
}
@end @end

View File

@@ -1,128 +0,0 @@
//
// MPDocumentSettingsWindowController.m
// MacPass
//
// Created by Michael Starke on 26.06.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import "MPDocumentSettingsWindowController.h"
#import "MPDocument.h"
#import "MPDocumentWindowController.h"
#import "MPDatabaseVersion.h"
#import "MPIconHelper.h"
#import "Kdb.h"
#import "Kdb4Node.h"
#import "KdbGroup+MPAdditions.h"
@interface MPDocumentSettingsWindowController () {
MPDocument *_document;
}
@end
@implementation MPDocumentSettingsWindowController
- (id)init {
return [self initWithDocument:nil];
}
- (id)initWithDocument:(MPDocument *)document {
self = [super initWithWindowNibName:@"DocumentSettingsWindow"];
if(self) {
_document = document;
}
return self;
}
- (void)windowDidLoad {
[super windowDidLoad];
NSAssert(_document != nil, @"Document needs to be present");
Kdb4Tree *tree = _document.treeV4;
if( tree ) {
[self _setupDatabase:tree];
[self _setupProtectionTab:tree];
[self _setupAdvancedTab:tree];
[self _setupPasswordTab:tree];
}
else {
// Switch to KdbV3 View
}
}
- (IBAction)close:(id)sender {
[NSApp endSheet:[self window]];
[[self window] orderOut:nil];
}
- (void)update {
/* Update all stuff that might have changed */
Kdb4Tree *tree = _document.treeV4;
if(tree) {
[self _updateTrashFolders:tree];
}
}
#pragma mark Private Helper
- (void)_setupDatabase:(Kdb4Tree *)tree {
[self.databaseNameTextField bind:NSValueBinding toObject:tree withKeyPath:@"databaseName" options:nil];
[self.databaseDescriptionTextView bind:NSValueBinding toObject:tree withKeyPath:@"databaseDescription" options:nil];
}
- (void)_setupProtectionTab:(Kdb4Tree *)tree {
[self.protectNotesCheckButton bind:NSValueBinding toObject:tree withKeyPath:@"protectNotes" options:nil];
[self.protectPasswortCheckButton bind:NSValueBinding toObject:tree withKeyPath:@"protectPassword" options:nil];
[self.protectTitleCheckButton bind:NSValueBinding toObject:tree withKeyPath:@"protectTitle" options:nil];
[self.protectURLCheckButton bind:NSValueBinding toObject:tree withKeyPath:@"protectUrl" options:nil];
[self.protectUserNameCheckButton bind:NSValueBinding toObject:tree withKeyPath:@"protectUserName" options:nil];
}
- (void)_setupAdvancedTab:(Kdb4Tree *)tree {
[self.enableRecycleBinCheckButton bind:NSValueBinding toObject:tree withKeyPath:@"recycleBinEnabled" options:nil];
[self.selectRecycleBinGroupPopUpButton bind:NSEnabledBinding toObject:tree withKeyPath:@"recycleBinEnabled" options:nil];
[self _updateTrashFolders:tree];
}
- (void)_setupPasswordTab:(Kdb4Tree *)tree {
}
- (void)_didSelectTrashFolder:(id)sender {
NSMenuItem *menuItem = sender;
/* if we do not get a group, use nil to reset the trash */
KdbGroup *group = [menuItem representedObject];
[_document useGroupAsTrash:group];
}
- (void)_updateTrashFolders:(Kdb4Tree *)tree {
NSMenu *menu = [self _buildTreeMenu:tree];
[self.selectRecycleBinGroupPopUpButton setMenu:menu];
}
- (NSMenu *)_buildTreeMenu:(Kdb4Tree *)tree {
NSMenu *menu = [[NSMenu alloc] init];
for(Kdb4Group *group in tree.root.groups) {
NSMenuItem *groupItem = [[NSMenuItem alloc] init];
[groupItem setImage:group.icon];
[groupItem setTitle:group.name];
[groupItem setAction:@selector(_didSelectTrashFolder:)];
[groupItem setTarget:self];
[groupItem setRepresentedObject:group];
if([group.uuid isEqual:tree.recycleBinUuid]) {
[groupItem setState:NSOnState];
}
[menu addItem:groupItem];
}
NSMenuItem *selectItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"SELECT_RECYCLEBIN", @"Menu item if no reycleBin is selected") action:NULL keyEquivalent:@""];
[selectItem setAction:@selector(_didSelectTrashFolder:)];
[selectItem setTarget:self];
[menu insertItem:selectItem atIndex:0];
return menu;
}
@end

View File

@@ -11,7 +11,6 @@
@class MPViewController; @class MPViewController;
@class MPEntryViewController; @class MPEntryViewController;
@class MPInspectorViewController; @class MPInspectorViewController;
@class MPPasswordEditViewController;
@class MPPasswordInputController; @class MPPasswordInputController;
@class MPOutlineViewController; @class MPOutlineViewController;
@@ -23,7 +22,6 @@ APPKIT_EXTERN NSString *const MPCurrentItemChangedNotification;
@interface MPDocumentWindowController : NSWindowController <NSWindowDelegate> @interface MPDocumentWindowController : NSWindowController <NSWindowDelegate>
@property (readonly, strong) MPPasswordInputController *passwordInputController; @property (readonly, strong) MPPasswordInputController *passwordInputController;
@property (readonly, strong) MPPasswordEditViewController *passwordEditController;
@property (readonly, strong) MPEntryViewController *entryViewController; @property (readonly, strong) MPEntryViewController *entryViewController;
@property (readonly, strong) MPOutlineViewController *outlineViewController; @property (readonly, strong) MPOutlineViewController *outlineViewController;
@property (readonly, strong) MPInspectorViewController *inspectorViewController; @property (readonly, strong) MPInspectorViewController *inspectorViewController;
@@ -39,7 +37,8 @@ APPKIT_EXTERN NSString *const MPCurrentItemChangedNotification;
- (void)showPasswordInput; - (void)showPasswordInput;
- (void)performFindPanelAction:(id)sender; - (void)performFindPanelAction:(id)sender;
- (IBAction)editPassword:(id)sender; - (IBAction)editPassword:(id)sender;
- (IBAction)showDocumentSettings:(id)sender; - (IBAction)showDatabaseSettings:(id)sender;
- (IBAction)exportDatabase:(id)sender;
- (void)lock:(id)sender; - (void)lock:(id)sender;

View File

@@ -10,14 +10,14 @@
#import "MPDocument.h" #import "MPDocument.h"
#import "MPPasswordInputController.h" #import "MPPasswordInputController.h"
#import "MPEntryViewController.h" #import "MPEntryViewController.h"
#import "MPPasswordEditViewController.h"
#import "MPToolbarDelegate.h" #import "MPToolbarDelegate.h"
#import "MPOutlineViewController.h" #import "MPOutlineViewController.h"
#import "MPInspectorViewController.h" #import "MPInspectorViewController.h"
#import "MPAppDelegate.h" #import "MPAppDelegate.h"
#import "MPActionHelper.h" #import "MPActionHelper.h"
#import "MPDocumentSettingsWindowController.h" #import "MPDatabaseSettingsWindowController.h"
#import "MPConstants.h" #import "MPConstants.h"
#import "MPSettingsHelper.h"
NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCurrentItemChangedNotification"; NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCurrentItemChangedNotification";
@@ -34,11 +34,10 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
@property (unsafe_unretained) KdbEntry *currentEntry; @property (unsafe_unretained) KdbEntry *currentEntry;
@property (strong) MPPasswordInputController *passwordInputController; @property (strong) MPPasswordInputController *passwordInputController;
@property (strong) MPPasswordEditViewController *passwordEditController;
@property (strong) MPEntryViewController *entryViewController; @property (strong) MPEntryViewController *entryViewController;
@property (strong) MPOutlineViewController *outlineViewController; @property (strong) MPOutlineViewController *outlineViewController;
@property (strong) MPInspectorViewController *inspectorViewController; @property (strong) MPInspectorViewController *inspectorViewController;
@property (strong) MPDocumentSettingsWindowController *documentSettingsWindowController; @property (strong) MPDatabaseSettingsWindowController *documentSettingsWindowController;
@property (strong) MPToolbarDelegate *toolbarDelegate; @property (strong) MPToolbarDelegate *toolbarDelegate;
@@ -52,7 +51,6 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
_firstResponder = nil; _firstResponder = nil;
_toolbarDelegate = [[MPToolbarDelegate alloc] init]; _toolbarDelegate = [[MPToolbarDelegate alloc] init];
_outlineViewController = [[MPOutlineViewController alloc] init]; _outlineViewController = [[MPOutlineViewController alloc] init];
_passwordEditController = [[MPPasswordEditViewController alloc] init];
_entryViewController = [[MPEntryViewController alloc] init]; _entryViewController = [[MPEntryViewController alloc] init];
_inspectorViewController = [[MPInspectorViewController alloc] init]; _inspectorViewController = [[MPInspectorViewController alloc] init];
_currentItem = nil; _currentItem = nil;
@@ -65,9 +63,6 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
- (void)dealloc { - (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self]; [[NSNotificationCenter defaultCenter] removeObserver:self];
} }
#pragma mark View Handling #pragma mark View Handling
@@ -97,15 +92,22 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
[_splitView setHoldingPriority:NSLayoutPriorityDefaultLow+2 forSubviewAtIndex:0]; [_splitView setHoldingPriority:NSLayoutPriorityDefaultLow+2 forSubviewAtIndex:0];
[_splitView setHoldingPriority:NSLayoutPriorityDefaultLow+1 forSubviewAtIndex:2]; [_splitView setHoldingPriority:NSLayoutPriorityDefaultLow+1 forSubviewAtIndex:2];
BOOL showInspector = [[NSUserDefaults standardUserDefaults] boolForKey:kMPSettingsKeyShowInspector];
if(!showInspector) {
[inspectorView removeFromSuperview];
}
[[self window] setDelegate:self]; [[self window] setDelegate:self];
MPDocument *document = [self document]; MPDocument *document = [self document];
if(!document.isDecrypted) { if(!document.decrypted) {
[self showPasswordInput]; [self showPasswordInput];
} }
else { else {
[self showEntries]; [self showEntries];
} }
[_splitView setAutosaveName:@"SplitView"];
} }
- (void)_setContentViewController:(MPViewController *)viewController { - (void)_setContentViewController:(MPViewController *)viewController {
@@ -165,23 +167,44 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
} }
#pragma mark Actions #pragma mark Actions
- (void)exportDatabase:(id)sender {
NSSavePanel *savePanel = [NSSavePanel savePanel];
[savePanel setAllowsOtherFileTypes:YES];
[savePanel beginSheetModalForWindow:self.window completionHandler:^(NSInteger result) {
if(result == NSFileHandlingPanelOKButton) {
[[self document] writeXMLToURL:savePanel.URL];
}
}];
}
- (void)performFindPanelAction:(id)sender { - (void)performFindPanelAction:(id)sender {
[self.entryViewController showFilter:sender]; [self.entryViewController showFilter:sender];
} }
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem { - (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
MPDocument *document = [self document]; MPDocument *document = [self document];
return !( document.isLocked || document.isReadOnly ); SEL itemAction = [menuItem action];
if(itemAction == @selector(showDatabaseSettings:)
|| itemAction == @selector(editPassword:)) {
return document.decrypted && !document.isLocked;
}
BOOL enabled = YES;
if(itemAction == @selector(exportDatabase:)) {
enabled = (nil != document.treeV4);
}
enabled &= !( !document.decrypted || document.isLocked || document.isReadOnly );
return enabled;
} }
- (BOOL)validateToolbarItem:(NSToolbarItem *)theItem { - (BOOL)validateToolbarItem:(NSToolbarItem *)theItem {
MPDocument *document = [self document]; MPDocument *document = [self document];
if(document.isLocked || document.isReadOnly) { if(!document.decrypted || document.isLocked || document.isReadOnly) {
return NO; return NO;
} }
SEL itemAction = [theItem action]; SEL itemAction = [theItem action];
if( itemAction == [MPActionHelper actionOfType:MPActionLock]) { if( itemAction == [MPActionHelper actionOfType:MPActionLock]) {
return document.isSecured; return document.hasPasswordOrKey;
} }
if(itemAction == [MPActionHelper actionOfType:MPActionAddEntry]) { if(itemAction == [MPActionHelper actionOfType:MPActionAddEntry]) {
return (nil != _outlineViewController.selectedGroup); return (nil != _outlineViewController.selectedGroup);
@@ -205,23 +228,16 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
} }
- (void)editPassword:(id)sender { - (void)editPassword:(id)sender {
if(!self.passwordEditController) { [self _showDatabaseSetting:MPDatabaseSettingsTabPassword];
_passwordEditController = [[MPPasswordEditViewController alloc] init];
}
[self _setContentViewController:self.passwordEditController];
} }
- (void)showDocumentSettings:(id)sender { - (void)showDatabaseSettings:(id)sender {
if(!self.documentSettingsWindowController) { [self _showDatabaseSetting:MPDatabaseSettingsTabGeneral];
_documentSettingsWindowController = [[MPDocumentSettingsWindowController alloc] initWithDocument:[self document]];
}
[_documentSettingsWindowController update];
[[NSApplication sharedApplication] beginSheet:[_documentSettingsWindowController window] modalForWindow:[self window] modalDelegate:nil didEndSelector:NULL contextInfo:NULL];
} }
- (void)lock:(id)sender { - (void)lock:(id)sender {
MPDocument *document = [self document]; MPDocument *document = [self document];
if(!document.isSecured) { if(!document.hasPasswordOrKey) {
return; // Document needs a password/keyfile to be lockable return; // Document needs a password/keyfile to be lockable
} }
if(document.isLocked) { if(document.isLocked) {
@@ -241,18 +257,21 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
- (void)toggleInspector:(id)sender { - (void)toggleInspector:(id)sender {
NSView *inspectorView = [_inspectorViewController view]; NSView *inspectorView = [_inspectorViewController view];
BOOL inspectorVisible = NO;
if([inspectorView superview]) { if([inspectorView superview]) {
//[inspectorView animator] //[inspectorView animator]
[inspectorView removeFromSuperview]; [inspectorView removeFromSuperview];
} }
else { else {
// Remove contraint on view removal. // Remove contraint on view removal.
inspectorVisible = YES;
[_splitView addSubview:inspectorView]; [_splitView addSubview:inspectorView];
[_splitView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"[inspectorView(>=200)]" [_splitView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"[inspectorView(>=200)]"
options:0 options:0
metrics:nil metrics:nil
views:NSDictionaryOfVariableBindings(inspectorView)]]; views:NSDictionaryOfVariableBindings(inspectorView)]];
} }
[[NSUserDefaults standardUserDefaults] setBool:inspectorVisible forKey:kMPSettingsKeyShowInspector];
} }
- (void)showEntries { - (void)showEntries {
@@ -264,7 +283,7 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
[[contentView subviews][0] removeFromSuperviewWithoutNeedingDisplay]; [[contentView subviews][0] removeFromSuperviewWithoutNeedingDisplay];
} }
[contentView addSubview:_splitView]; [contentView addSubview:_splitView];
[_splitView adjustSubviews]; //[_splitView adjustSubviews];
NSView *outlineView = [_outlineViewController view]; NSView *outlineView = [_outlineViewController view];
NSView *inspectorView = [_inspectorViewController view]; NSView *inspectorView = [_inspectorViewController view];
NSView *entryView = [_entryViewController view]; NSView *entryView = [_entryViewController view];
@@ -310,7 +329,7 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
if(removeInspector) { if(removeInspector) {
[inspectorView removeFromSuperview]; [inspectorView removeFromSuperview];
} }
[contentView layout]; [contentView layoutSubtreeIfNeeded];
MPDocument *document = [self document]; MPDocument *document = [self document];
document.locked = NO; document.locked = NO;
@@ -321,6 +340,7 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
[_outlineViewController showOutline]; [_outlineViewController showOutline];
} }
#pragma mark NSWindowDelegate #pragma mark NSWindowDelegate
- (void)windowDidUpdate:(NSNotification *)notification { - (void)windowDidUpdate:(NSNotification *)notification {
id firstResonder = [[self window] firstResponder]; id firstResonder = [[self window] firstResponder];
@@ -329,12 +349,28 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
} }
_firstResponder = firstResonder; _firstResponder = firstResonder;
if([_firstResponder isKindOfClass:[NSView class]]) { if([_firstResponder isKindOfClass:[NSView class]]) {
[self _updateCurrentItem:[NSNotification notificationWithName:@"dummy" object:_firstResponder ]]; //self _updateCurrentItem:[NSNotification notificationWithName:@"dummy" object:_firstResponder ]];
} }
} }
- (void)windowDidBecomeKey:(NSNotification *)notification {
MPDocument *document = [self document];
if(!document.hasPasswordOrKey && document.decrypted) {
[self performSelector:@selector(editPassword:) withObject:nil afterDelay:0.5];
}
}
#pragma mark Helper #pragma mark Helper
- (void)_showDatabaseSetting:(MPDatabaseSettingsTab)tab {
if(!self.documentSettingsWindowController) {
_documentSettingsWindowController = [[MPDatabaseSettingsWindowController alloc] initWithDocument:[self document]];
}
[self.documentSettingsWindowController update];
[self.documentSettingsWindowController showSettingsTab:tab];
[[NSApplication sharedApplication] beginSheet:[self.documentSettingsWindowController window] modalForWindow:[self window] modalDelegate:nil didEndSelector:NULL contextInfo:NULL];
}
- (NSSearchField *)locateToolbarSearchField { - (NSSearchField *)locateToolbarSearchField {
for(NSToolbarItem *toolbarItem in [[self.window toolbar] items]) { for(NSToolbarItem *toolbarItem in [[self.window toolbar] items]) {
NSView *view = [toolbarItem view]; NSView *view = [toolbarItem view];

View File

@@ -0,0 +1,16 @@
//
// MPEntryMenuDelegate.h
// MacPass
//
// Created by Michael Starke on 17.07.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import <Foundation/Foundation.h>
@class MPEntryViewController;
@interface MPEntryMenuDelegate : NSObject <NSMenuDelegate>
@property (weak) MPEntryViewController *viewController;
@end

View File

@@ -0,0 +1,54 @@
//
// MPEntryMenuDelegate.m
// MacPass
//
// Created by Michael Starke on 17.07.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import "MPEntryMenuDelegate.h"
#import "MPEntryViewController.h"
#import "Kdb4Node.h"
static NSUInteger const kMPCustomFieldMenuItem = 1000;
static NSUInteger const kMPAttachmentsMenuItem = 2000;
@implementation MPEntryMenuDelegate
- (void)menuNeedsUpdate:(NSMenu *)menu {
NSMenuItem *fieldsMenu = [menu itemWithTag:kMPCustomFieldMenuItem];
NSMenuItem *attachmentsMenu = [menu itemWithTag:kMPAttachmentsMenuItem];
if(fieldsMenu) {
[menu removeItem:fieldsMenu];
}
if(attachmentsMenu) {
[menu removeItem:attachmentsMenu];
}
NSMenuItem *lastItem = [[menu itemArray] lastObject];
if([lastItem isSeparatorItem]) {
[menu removeItem:lastItem];
}
if([self.viewController.selectedEntry isKindOfClass:[Kdb4Entry class]]) {
Kdb4Entry *entry = (Kdb4Entry *)self.viewController.selectedEntry;
if([entry.stringFields count] > 0) {
[menu addItem:[NSMenuItem separatorItem]];
NSMenuItem *customFieldsItem = [[NSMenuItem alloc] init];
NSMenu *submenu = [[NSMenu alloc] initWithTitle:@"Fields"];
[customFieldsItem setTitle:NSLocalizedString(@"COPY_CUSTOM_FIELDS", "Submenu to Copy custom fields")];
[customFieldsItem setTag:kMPCustomFieldMenuItem];
for (StringField *field in entry.stringFields) {
NSString *title = [NSString stringWithFormat:NSLocalizedString(@"COPY_FIELD_%@", "Mask for title to copy field value"), field.key];
NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:title action:@selector(copyCustomField:) keyEquivalent:@""];
[item setTag:[entry.stringFields indexOfObject:field]];
[submenu addItem:item];
}
[customFieldsItem setSubmenu:submenu];
[menu addItem:customFieldsItem];
}
}
}
@end

View File

@@ -48,9 +48,11 @@ typedef NS_ENUM( NSUInteger, MPCopyContentTypeTag) {
/* Copy/Paste */ /* Copy/Paste */
- (void)copyUsername:(id)sender; - (void)copyUsername:(id)sender;
- (void)copyPassword:(id)sender; - (void)copyPassword:(id)sender;
- (void)copyCustomField:(id)sender;
- (void)copyURL:(id)sender; - (void)copyURL:(id)sender;
- (void)openURL:(id)sender; - (void)openURL:(id)sender;
/* Entry Handling*/ /* Entry Handling*/
- (void)deleteNode:(id)sender; - (void)deleteNode:(id)sender;

View File

@@ -20,10 +20,12 @@
#import "MPConstants.h" #import "MPConstants.h"
#import "MPEntryTableDataSource.h" #import "MPEntryTableDataSource.h"
#import "MPStringLengthValueTransformer.h" #import "MPStringLengthValueTransformer.h"
#import "MPEntryMenuDelegate.h"
#import "HNHTableHeaderCell.h" #import "HNHTableHeaderCell.h"
#import "HNHGradientView.h" #import "HNHGradientView.h"
#import "Kdb4Node.h"
#import "KdbGroup+MPTreeTools.h" #import "KdbGroup+MPTreeTools.h"
#import "KdbGroup+Undo.h" #import "KdbGroup+Undo.h"
#import "KdbEntry+Undo.h" #import "KdbEntry+Undo.h"
@@ -43,6 +45,7 @@ typedef NS_ENUM(NSUInteger,MPOVerlayInfoType) {
MPOverlayInfoPassword, MPOverlayInfoPassword,
MPOverlayInfoUsername, MPOverlayInfoUsername,
MPOverlayInfoURL, MPOverlayInfoURL,
MPOverlayInfoCustom
}; };
NSString *const MPEntryTableUserNameColumnIdentifier = @"MPUserNameColumnIdentifier"; NSString *const MPEntryTableUserNameColumnIdentifier = @"MPUserNameColumnIdentifier";
@@ -59,7 +62,9 @@ NSString *const _toggleFilterURLButton = @"SearchURL";
NSString *const _toggleFilterTitleButton = @"SearchTitle"; NSString *const _toggleFilterTitleButton = @"SearchTitle";
NSString *const _toggleFilterUsernameButton = @"SearchUsername"; NSString *const _toggleFilterUsernameButton = @"SearchUsername";
@interface MPEntryViewController () @interface MPEntryViewController () {
MPEntryMenuDelegate *_menuDelegate;
}
@property (strong) NSArrayController *entryArrayController; @property (strong) NSArrayController *entryArrayController;
@property (strong) NSArray *filteredEntries; @property (strong) NSArray *filteredEntries;
@@ -103,6 +108,9 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername";
_entryArrayController = [[NSArrayController alloc] init]; _entryArrayController = [[NSArrayController alloc] init];
_dataSource = [[MPEntryTableDataSource alloc] init]; _dataSource = [[MPEntryTableDataSource alloc] init];
_dataSource.viewController = self; _dataSource.viewController = self;
_menuDelegate = [[MPEntryMenuDelegate alloc] init];
_menuDelegate.viewController = self;
_selectedEntry = nil; _selectedEntry = nil;
} }
return self; return self;
@@ -124,7 +132,7 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername";
[self.entryTable setDoubleAction:@selector(_columnDoubleClick:)]; [self.entryTable setDoubleAction:@selector(_columnDoubleClick:)];
[self.entryTable setTarget:self]; [self.entryTable setTarget:self];
[self.entryTable setFloatsGroupRows:NO]; [self.entryTable setFloatsGroupRows:NO];
[self.entryTable registerForDraggedTypes:@[MPPasteBoardType]]; //[self.entryTable registerForDraggedTypes:@[MPPasteBoardType]];
[self _setupEntryMenu]; [self _setupEntryMenu];
NSTableColumn *parentColumn = [self.entryTable tableColumns][0]; NSTableColumn *parentColumn = [self.entryTable tableColumns][0];
@@ -140,6 +148,9 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername";
[passwordColumn setIdentifier:MPEntryTablePasswordColumnIdentifier]; [passwordColumn setIdentifier:MPEntryTablePasswordColumnIdentifier];
[urlColumn setIdentifier:MPEntryTableURLColumnIdentifier]; [urlColumn setIdentifier:MPEntryTableURLColumnIdentifier];
[self.entryTable setAutosaveName:@"EntryTable"];
[self.entryTable setAutosaveTableColumns:YES];
NSSortDescriptor *titleColumSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"title" ascending:YES selector:@selector(compare:)]; NSSortDescriptor *titleColumSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"title" ascending:YES selector:@selector(compare:)];
NSSortDescriptor *userNameSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"username" ascending:YES selector:@selector(compare:)]; NSSortDescriptor *userNameSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"username" ascending:YES selector:@selector(compare:)];
NSSortDescriptor *urlSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"url" ascending:YES selector:@selector(compare:)]; NSSortDescriptor *urlSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"url" ascending:YES selector:@selector(compare:)];
@@ -159,6 +170,7 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername";
[self.entryTable setDataSource:_dataSource]; [self.entryTable setDataSource:_dataSource];
[parentColumn setHidden:YES]; [parentColumn setHidden:YES];
} }
- (void)setupNotifications:(MPDocumentWindowController *)windowController { - (void)setupNotifications:(MPDocumentWindowController *)windowController {
@@ -395,7 +407,7 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername";
} }
} }
- (void)_copyToPasteboard:(NSString *)data overlayInfo:(MPOVerlayInfoType)overlayInfoType { - (void)_copyToPasteboard:(NSString *)data overlayInfo:(MPOVerlayInfoType)overlayInfoType name:(NSString *)name{
if(data) { if(data) {
[[MPPasteBoardController defaultController] copyObjects:@[ data ]]; [[MPPasteBoardController defaultController] copyObjects:@[ data ]];
} }
@@ -416,6 +428,11 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername";
infoImage = [[NSBundle mainBundle] imageForResource:@"09_IdentityTemplate"]; infoImage = [[NSBundle mainBundle] imageForResource:@"09_IdentityTemplate"];
infoText = NSLocalizedString(@"COPIED_USERNAME", @"Username was copied to the pasteboard"); infoText = NSLocalizedString(@"COPIED_USERNAME", @"Username was copied to the pasteboard");
break; break;
case MPOverlayInfoCustom:
infoImage = [[NSBundle mainBundle] imageForResource:@"00_PasswordTemplate"];
infoText = [NSString stringWithFormat:NSLocalizedString(@"COPIED_FIELD_%@", "Field nam that was copied to the pasteboard"), name];
break;
} }
[[MPOverlayWindowController sharedController] displayOverlayImage:infoImage label:infoText atView:self.view]; [[MPOverlayWindowController sharedController] displayOverlayImage:infoImage label:infoText atView:self.view];
} }
@@ -429,7 +446,9 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername";
for(NSMenuItem *item in items) { for(NSMenuItem *item in items) {
[menu addItem:item]; [menu addItem:item];
} }
[menu setDelegate:_menuDelegate];
[self.entryTable setMenu:menu]; [self.entryTable setMenu:menu];
} }
#pragma makr Action Helper #pragma makr Action Helper
@@ -451,21 +470,32 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername";
- (void)copyPassword:(id)sender { - (void)copyPassword:(id)sender {
KdbEntry *selectedEntry = [self _clickedOrSelectedEntry]; KdbEntry *selectedEntry = [self _clickedOrSelectedEntry];
if(selectedEntry) { if(selectedEntry) {
[self _copyToPasteboard:selectedEntry.password overlayInfo:MPOverlayInfoPassword]; [self _copyToPasteboard:selectedEntry.password overlayInfo:MPOverlayInfoPassword name:nil];
} }
} }
- (void)copyUsername:(id)sender { - (void)copyUsername:(id)sender {
KdbEntry *selectedEntry = [self _clickedOrSelectedEntry]; KdbEntry *selectedEntry = [self _clickedOrSelectedEntry];
if(selectedEntry) { if(selectedEntry) {
[self _copyToPasteboard:selectedEntry.username overlayInfo:MPOverlayInfoUsername]; [self _copyToPasteboard:selectedEntry.username overlayInfo:MPOverlayInfoUsername name:nil];
}
}
- (void)copyCustomField:(id)sender {
KdbEntry *selectedEntry = [self _clickedOrSelectedEntry];
if(selectedEntry && [selectedEntry isKindOfClass:[Kdb4Entry class]]) {
Kdb4Entry *entry = (Kdb4Entry *)selectedEntry;
NSUInteger index = [sender tag];
NSAssert((index >= 0) && (index < [entry.stringFields count]), @"Index for custom field needs to be valid");
StringField *field = entry.stringFields[index];
[self _copyToPasteboard:field.value overlayInfo:MPOverlayInfoCustom name:field.key];
} }
} }
- (void)copyURL:(id)sender { - (void)copyURL:(id)sender {
KdbEntry *selectedEntry = [self _clickedOrSelectedEntry]; KdbEntry *selectedEntry = [self _clickedOrSelectedEntry];
if(selectedEntry) { if(selectedEntry) {
[self _copyToPasteboard:selectedEntry.url overlayInfo:MPOverlayInfoURL]; [self _copyToPasteboard:selectedEntry.url overlayInfo:MPOverlayInfoURL name:nil];
} }
} }
@@ -480,7 +510,7 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername";
- (void)deleteNode:(id)sender { - (void)deleteNode:(id)sender {
KdbEntry *entry =[self _clickedOrSelectedEntry]; KdbEntry *entry =[self _clickedOrSelectedEntry];
MPDocument *document = [[self windowController] document]; MPDocument *document = [[self windowController] document];
[document group:entry.parent removeEntry:entry]; [document deleteEntry:entry];
} }
- (void)_toggleFilterSpace:(id)sender { - (void)_toggleFilterSpace:(id)sender {

View File

@@ -1,16 +0,0 @@
//
// MPFirstResonderNotification.h
// MacPass
//
// Created by Michael Starke on 20.06.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import <Foundation/Foundation.h>
@protocol MPFirstResonderNotification <NSObject>
@required
- (BOOL)becomeFirstResponder;
@end

View File

@@ -16,5 +16,6 @@
@property (weak) IBOutlet NSPopUpButton *clearPasteboardTimeoutPopup; @property (weak) IBOutlet NSPopUpButton *clearPasteboardTimeoutPopup;
@property (weak) IBOutlet NSPopUpButton *idleTimeOutPopup; @property (weak) IBOutlet NSPopUpButton *idleTimeOutPopup;
@property (weak) IBOutlet NSButton *lockOnSleepCheckButton; @property (weak) IBOutlet NSButton *lockOnSleepCheckButton;
@property (weak) IBOutlet NSButton *reopenLastDatabase;
@end @end

View File

@@ -32,6 +32,7 @@ NSString *const MPGeneralSetingsIdentifier = @"GeneralSettingsTab";
- (void)didLoadView { - (void)didLoadView {
NSUserDefaultsController *defaultsController = [NSUserDefaultsController sharedUserDefaultsController]; NSUserDefaultsController *defaultsController = [NSUserDefaultsController sharedUserDefaultsController];
NSString *reopenLastFilePath = [NSString stringWithFormat:@"values.%@", kMPSettingsKeyReopenLastDatabaseOnLaunch];
NSString *clearPasteboardKeyPath = [NSString stringWithFormat:@"values.%@", kMPSettingsKeyClearPasteboardOnQuit]; NSString *clearPasteboardKeyPath = [NSString stringWithFormat:@"values.%@", kMPSettingsKeyClearPasteboardOnQuit];
NSString *clearPasteboardTimeOutKeyPath = [NSString stringWithFormat:@"values.%@", kMPSettingsKeyPasteboardClearTimeout]; NSString *clearPasteboardTimeOutKeyPath = [NSString stringWithFormat:@"values.%@", kMPSettingsKeyPasteboardClearTimeout];
NSString *idleTimeOutKeyPath = [NSString stringWithFormat:@"values.%@", kMPSettingsKeyIdleLockTimeOut]; NSString *idleTimeOutKeyPath = [NSString stringWithFormat:@"values.%@", kMPSettingsKeyIdleLockTimeOut];
@@ -40,5 +41,6 @@ NSString *const MPGeneralSetingsIdentifier = @"GeneralSettingsTab";
[self.clearPasteboardTimeoutPopup bind:NSSelectedTagBinding toObject:defaultsController withKeyPath:clearPasteboardTimeOutKeyPath options:nil]; [self.clearPasteboardTimeoutPopup bind:NSSelectedTagBinding toObject:defaultsController withKeyPath:clearPasteboardTimeOutKeyPath options:nil];
[self.lockOnSleepCheckButton bind:NSValueBinding toObject:defaultsController withKeyPath:lockOnSleepKeyPath options:nil]; [self.lockOnSleepCheckButton bind:NSValueBinding toObject:defaultsController withKeyPath:lockOnSleepKeyPath options:nil];
[self.idleTimeOutPopup bind:NSSelectedTagBinding toObject:defaultsController withKeyPath:idleTimeOutKeyPath options:nil]; [self.idleTimeOutPopup bind:NSSelectedTagBinding toObject:defaultsController withKeyPath:idleTimeOutKeyPath options:nil];
[self.reopenLastDatabase bind:NSValueBinding toObject:defaultsController withKeyPath:reopenLastFilePath options:nil];
} }
@end @end

View File

@@ -15,13 +15,23 @@ typedef NS_ENUM(NSUInteger, MPIconType) {
MPIconServer, MPIconServer,
MPIconKlipper, MPIconKlipper,
MPIconLanguages, MPIconLanguages,
MPIconBlockDevice,
MPIconNotepad, MPIconNotepad,
MPIconSocket, MPIconSocket,
MPIconIdentity, MPIconIdentity,
MPIconContact, MPIconContact,
MPIconCamera, MPIconCamera,
MPIconTrash, MPIconRemote,
MPIconInfo MPIconKeys,
MPIconDisplay = 18,
MPIconFileSave = 26,
MPIconTrash = 43,
MPIconFolder = 48,
MPIconPhone = 68,
/* Custom Icons not used in Database */
MPIconInfo = 1000,
MPIconAddFolder,
MPIconHardDisk,
}; };
@interface MPIconHelper : NSObject @interface MPIconHelper : NSObject

View File

@@ -10,13 +10,17 @@
@implementation MPIconHelper @implementation MPIconHelper
static NSDictionary *icons;
+ (NSImage *)icon:(MPIconType)type { + (NSImage *)icon:(MPIconType)type {
NSDictionary *icons = [MPIconHelper availableIconNames]; if(!icons) {
if(type >= [icons count]) { icons = [MPIconHelper availableIconNames];
return [NSImage imageNamed:NSImageNameActionTemplate];
} }
if([[icons allKeys] containsObject:@(type)]) {
NSString *imageName = icons[@(type)]; NSString *imageName = icons[@(type)];
return [[NSBundle mainBundle] imageForResource:imageName]; return [[NSBundle mainBundle] imageForResource:imageName];
}
return [NSImage imageNamed:NSImageNameActionTemplate];
} }
+ (NSArray *)availableIcons { + (NSArray *)availableIcons {
@@ -30,19 +34,35 @@
} }
+ (NSDictionary *)availableIconNames { + (NSDictionary *)availableIconNames {
NSDictionary *imageNames = @{ @(MPIconKlipper): @"04_KlipperTemplate", NSDictionary *imageNames = @{
@(MPIconLanguages): @"05_LanguagesTemplate",
@(MPIconPackageNetwork): @"01_PackageNetworkTemplate",
@(MPIconPassword): @"00_PasswordTemplate", @(MPIconPassword): @"00_PasswordTemplate",
@(MPIconServer): @"03_ServerTemplate", @(MPIconPackageNetwork): @"01_PackageNetworkTemplate",
@(MPIconWarning): @"02_MessageBoxWarningTemplate", @(MPIconWarning): @"02_MessageBoxWarningTemplate",
@(MPIconCamera): @"11_CameraTemplate", @(MPIconServer): @"03_ServerTemplate",
@(MPIconContact): @"10_ContactTemplate", @(MPIconKlipper): @"04_KlipperTemplate",
@(MPIconIdentity): @"09_IdentityTemplate", @(MPIconLanguages): @"05_LanguagesTemplate",
@(MPIconBlockDevice): @"06_BlockDeviceTemplate",
@(MPIconNotepad): @"07_NotepadTemplate", @(MPIconNotepad): @"07_NotepadTemplate",
@(MPIconSocket): @"08_SocketTemplate", @(MPIconSocket): @"08_SocketTemplate",
@(MPIconIdentity): @"09_IdentityTemplate",
@(MPIconContact): @"10_ContactTemplate",
@(MPIconCamera): @"11_CameraTemplate",
@(MPIconRemote): @"12_RemoteTemplate",
@(MPIconKeys): @"13_KeysTemplate",
@(MPIconDisplay): @"18_DisplayTemplate",
@(MPIconFileSave): @"26_FileSaveTemplate",
@(MPIconTrash): @"43_TrashTemplate", @(MPIconTrash): @"43_TrashTemplate",
@(MPIconInfo): @"99_InfoTemplate"
@(MPIconFolder): @"48_FolderTemplate",
@(MPIconPhone): @"68_PhoneTemplate",
@(MPIconInfo): @"99_InfoTemplate",
@(MPIconAddFolder): @"99_AddFolderTemplate",
@(MPIconHardDisk): @"99_HarddiskTemplate"
}; };
return imageNames; return imageNames;
} }

View File

@@ -12,9 +12,10 @@
@class KdbEntry; @class KdbEntry;
@class KdbGroup; @class KdbGroup;
@class HNHGradientView; @class HNHGradientView;
@class HNHRoundedSecureTextField;
@class MPDocumentWindowController; @class MPDocumentWindowController;
@interface MPInspectorViewController : MPViewController <NSPopoverDelegate, NSTableViewDelegate> @interface MPInspectorViewController : MPViewController <NSPopoverDelegate>
@property (weak) IBOutlet MPPopupImageView *itemImageView; @property (weak) IBOutlet MPPopupImageView *itemImageView;
@property (weak) IBOutlet NSTextField *itemNameTextfield; @property (weak) IBOutlet NSTextField *itemNameTextfield;
@@ -22,7 +23,7 @@
@property (weak) IBOutlet NSTextField *titleTextField; @property (weak) IBOutlet NSTextField *titleTextField;
@property (weak) IBOutlet NSTextField *usernameTextField; @property (weak) IBOutlet NSTextField *usernameTextField;
@property (weak) IBOutlet NSTextField *URLTextField; @property (weak) IBOutlet NSTextField *URLTextField;
@property (weak) IBOutlet NSTextField *passwordTextField; @property (weak) IBOutlet HNHRoundedSecureTextField *passwordTextField;
@property (weak) IBOutlet NSTextField *titleOrNameLabel; @property (weak) IBOutlet NSTextField *titleOrNameLabel;
@property (weak) IBOutlet HNHGradientView *bottomBar; @property (weak) IBOutlet HNHGradientView *bottomBar;
@property (weak) IBOutlet NSTextField *createdTextField; @property (weak) IBOutlet NSTextField *createdTextField;
@@ -32,8 +33,12 @@
@property (weak) IBOutlet NSTableView *customFieldsTableView; @property (weak) IBOutlet NSTableView *customFieldsTableView;
@property (unsafe_unretained) IBOutlet NSTextView *notesTextView; @property (unsafe_unretained) IBOutlet NSTextView *notesTextView;
@property (weak) IBOutlet NSTextField *customFieldsTextField; @property (weak) IBOutlet NSTextField *customFieldsTextField;
@property (weak) IBOutlet NSButton *togglePassword;
@property (weak, nonatomic, readonly) KdbEntry *selectedEntry;
@property (weak, nonatomic, readonly) KdbGroup *selectedGroup;
/* Seperate call to ensure alle registered objects are in place */ /* Seperate call to ensure alle registered objects are in place */
- (void)setupNotifications:(MPDocumentWindowController *)windowController; - (void)setupNotifications:(MPDocumentWindowController *)windowController;

View File

@@ -19,6 +19,11 @@
#import "MPCustomFieldView.h" #import "MPCustomFieldView.h"
#import "MPDatabaseVersion.h" #import "MPDatabaseVersion.h"
#import "MPCustomFieldTableCellView.h" #import "MPCustomFieldTableCellView.h"
#import "MPSelectedAttachmentTableCellView.h"
#import "MPAttachmentTableViewDelegate.h"
#import "MPCustomFieldTableViewDelegate.h"
#import "NSDate+Humanized.h"
#import "KdbLib.h" #import "KdbLib.h"
#import "Kdb4Node.h" #import "Kdb4Node.h"
@@ -30,6 +35,8 @@
#import "NSMutableData+Base64.h" #import "NSMutableData+Base64.h"
#import "HNHGradientView.h" #import "HNHGradientView.h"
#import "HNHTableRowView.h"
#import "HNHRoundedSecureTextField.h"
enum { enum {
MPGeneralTab, MPGeneralTab,
@@ -40,6 +47,10 @@ enum {
@interface MPInspectorViewController () { @interface MPInspectorViewController () {
BOOL _visible; BOOL _visible;
NSArrayController *_attachmentsController;
NSArrayController *_customFieldsController;
MPAttachmentTableViewDelegate *_attachmentTableDelegate;
MPCustomFieldTableViewDelegate *_customFieldTableDelegate;
} }
@property (weak, nonatomic) KdbEntry *selectedEntry; @property (weak, nonatomic) KdbEntry *selectedEntry;
@@ -51,13 +62,18 @@ enum {
@property (nonatomic, weak) NSDate *modificationDate; @property (nonatomic, weak) NSDate *modificationDate;
@property (nonatomic, weak) NSDate *creationDate; @property (nonatomic, weak) NSDate *creationDate;
@property (nonatomic, assign) BOOL showPassword;
@property (nonatomic, assign) NSUInteger activeTab; @property (nonatomic, assign) NSUInteger activeTab;
@property (weak) IBOutlet NSTabView *tabView; @property (weak) IBOutlet NSTabView *tabView;
@property (strong) NSArrayController *attachmentsController;
@property (strong) NSArrayController *customFieldsController;
- (IBAction)addCustomField:(id)sender; - (IBAction)addCustomField:(id)sender;
- (IBAction)removeCustomField:(id)sender; - (IBAction)removeCustomField:(id)sender;
- (IBAction)saveAttachment:(id)sender;
- (IBAction)addAttachment:(id)sender;
- (IBAction)removeAttachment:(id)sender;
- (IBAction)edit:(id)sender;
- (IBAction)finishEdit:(id)sender;
@end @end
@@ -70,10 +86,15 @@ enum {
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) { if (self) {
_showPassword = NO;
_selectedEntry = nil; _selectedEntry = nil;
_selectedGroup = nil; _selectedGroup = nil;
_attachmentsController = [[NSArrayController alloc] init]; _attachmentsController = [[NSArrayController alloc] init];
_customFieldsController = [[NSArrayController alloc] init]; _customFieldsController = [[NSArrayController alloc] init];
_attachmentTableDelegate = [[MPAttachmentTableViewDelegate alloc] init];
_attachmentTableDelegate.viewController = self;
_customFieldTableDelegate = [[MPCustomFieldTableViewDelegate alloc] init];
_customFieldTableDelegate.viewController = self;
_activeTab = MPGeneralTab; _activeTab = MPGeneralTab;
} }
return self; return self;
@@ -94,12 +115,15 @@ enum {
/* Set background to clearcolor so we can draw in the scrollview */ /* Set background to clearcolor so we can draw in the scrollview */
[_attachmentTableView setBackgroundColor:[NSColor clearColor]]; [_attachmentTableView setBackgroundColor:[NSColor clearColor]];
[_attachmentTableView bind:NSContentBinding toObject:self.attachmentsController withKeyPath:@"arrangedObjects" options:nil]; [_attachmentTableView bind:NSContentBinding toObject:_attachmentsController withKeyPath:@"arrangedObjects" options:nil];
[_attachmentTableView setDelegate:self]; [_attachmentTableView setDelegate:_attachmentTableDelegate];
/* Set background to clearcolor so we can draw in the scrollview */ /* Set background to clearcolor so we can draw in the scrollview */
[_customFieldsTableView setBackgroundColor:[NSColor clearColor]]; [_customFieldsTableView setBackgroundColor:[NSColor clearColor]];
[_customFieldsTableView bind:NSContentBinding toObject:self.customFieldsController withKeyPath:@"arrangedObjects" options:nil]; [_customFieldsTableView bind:NSContentBinding toObject:_customFieldsController withKeyPath:@"arrangedObjects" options:nil];
[_customFieldsTableView setDelegate:self]; [_customFieldsTableView setDelegate:_customFieldTableDelegate];
[self.passwordTextField bind:@"showPassword" toObject:self withKeyPath:@"showPassword" options:nil];
[self.togglePassword bind:NSValueBinding toObject:self withKeyPath:@"showPassword" options:nil];
[self _clearContent]; [self _clearContent];
} }
@@ -116,6 +140,9 @@ enum {
NSString *modificationString = [NSDateFormatter localizedStringFromDate:modificationDate NSString *modificationString = [NSDateFormatter localizedStringFromDate:modificationDate
dateStyle:NSDateFormatterShortStyle dateStyle:NSDateFormatterShortStyle
timeStyle:NSDateFormatterShortStyle]; timeStyle:NSDateFormatterShortStyle];
modificationString = [modificationDate humanized];
NSString *modifedAtTemplate = NSLocalizedString(@"MODIFED_AT_%@", @"Modifed at template string. %@ is replaced by locaized date and time"); NSString *modifedAtTemplate = NSLocalizedString(@"MODIFED_AT_%@", @"Modifed at template string. %@ is replaced by locaized date and time");
[self.modifiedTextField setStringValue:[NSString stringWithFormat:modifedAtTemplate, modificationString]]; [self.modifiedTextField setStringValue:[NSString stringWithFormat:modifedAtTemplate, modificationString]];
@@ -125,6 +152,7 @@ enum {
NSString *creationString = [NSDateFormatter localizedStringFromDate:creationDate NSString *creationString = [NSDateFormatter localizedStringFromDate:creationDate
dateStyle:NSDateFormatterShortStyle dateStyle:NSDateFormatterShortStyle
timeStyle:NSDateFormatterShortStyle]; timeStyle:NSDateFormatterShortStyle];
creationString = [creationDate humanized];
NSString *createdAtTemplate = NSLocalizedString(@"CREATED_AT_%@", @"Created at template string. %@ is replaced by locaized date and time"); NSString *createdAtTemplate = NSLocalizedString(@"CREATED_AT_%@", @"Created at template string. %@ is replaced by locaized date and time");
[self.createdTextField setStringValue:[NSString stringWithFormat:createdAtTemplate, creationString]]; [self.createdTextField setStringValue:[NSString stringWithFormat:createdAtTemplate, creationString]];
@@ -147,26 +175,26 @@ enum {
- (void)_updateAttachments { - (void)_updateAttachments {
if(self.selectedEntry) { if(self.selectedEntry) {
if([self.selectedEntry isKindOfClass:[Kdb4Entry class]]) { if([self.selectedEntry isKindOfClass:[Kdb4Entry class]]) {
[self.attachmentsController bind:NSContentArrayBinding toObject:self.selectedEntry withKeyPath:@"binaries" options:nil]; [_attachmentsController bind:NSContentArrayBinding toObject:self.selectedEntry withKeyPath:@"binaries" options:nil];
} }
else { else {
/* Use binary from Kdb3Entry */ /* Use binary from Kdb3Entry */
} }
} }
else if([self.attachmentsController content] != nil){ else if([_attachmentsController content] != nil){
[self.attachmentsController unbind:NSContentArrayBinding]; [_attachmentsController unbind:NSContentArrayBinding];
[self.attachmentsController setContent:nil]; [_attachmentsController setContent:nil];
} }
} }
- (void)_updateCustomFields { - (void)_updateCustomFields {
if(self.selectedEntry && [self.selectedEntry isKindOfClass:[Kdb4Entry class]]) { if(self.selectedEntry && [self.selectedEntry isKindOfClass:[Kdb4Entry class]]) {
[self.customFieldsController bind:NSContentArrayBinding toObject:self.selectedEntry withKeyPath:@"stringFields" options:nil]; [_customFieldsController bind:NSContentArrayBinding toObject:self.selectedEntry withKeyPath:@"stringFields" options:nil];
} }
else if([self.customFieldsController content] != nil){ else if([_customFieldsController content] != nil){
[self.customFieldsController unbind:NSContentArrayBinding]; [_customFieldsController unbind:NSContentArrayBinding];
[self.customFieldsController setContent:nil]; [_customFieldsController setContent:nil];
} }
} }
@@ -250,6 +278,7 @@ enum {
enabled &= (self.selectedEntry != nil); enabled &= (self.selectedEntry != nil);
[self.passwordTextField setEnabled:enabled]; [self.passwordTextField setEnabled:enabled];
[self.togglePassword setEnabled:enabled];
[self.usernameTextField setEnabled:enabled]; [self.usernameTextField setEnabled:enabled];
[self.URLTextField setEnabled:enabled]; [self.URLTextField setEnabled:enabled];
[self.generatePasswordButton setEnabled:enabled]; [self.generatePasswordButton setEnabled:enabled];
@@ -310,7 +339,66 @@ enum {
MPDocument *document = [[self windowController] document]; MPDocument *document = [[self windowController] document];
NSUInteger index = [sender tag]; NSUInteger index = [sender tag];
Kdb4Entry *entry = (Kdb4Entry *)self.selectedEntry; Kdb4Entry *entry = (Kdb4Entry *)self.selectedEntry;
[document entry:entry removeStringField:(entry.stringFields)[index]]; [document removeStringField:(entry.stringFields)[index] formEntry:entry];
}
- (IBAction)saveAttachment:(id)sender {
Kdb4Entry *entry = (Kdb4Entry *)self.selectedEntry;
BinaryRef *reference = entry.binaries[[sender tag]];
NSSavePanel *savePanel = [NSSavePanel savePanel];
[savePanel setCanCreateDirectories:YES];
[savePanel setNameFieldStringValue:reference.key];
[savePanel beginSheetModalForWindow:[[self windowController] window] completionHandler:^(NSInteger result) {
if(result == NSFileHandlingPanelOKButton) {
MPDocument *document = [[self windowController] document];
[document saveAttachment:reference toLocation:[savePanel URL]];
}
}];
}
- (IBAction)addAttachment:(id)sender {
NSOpenPanel *openPanel = [NSOpenPanel openPanel];
[openPanel setCanChooseDirectories:NO];
[openPanel setCanChooseFiles:YES];
[openPanel setAllowsMultipleSelection:YES];
[openPanel beginSheetModalForWindow:[[self windowController] window] completionHandler:^(NSInteger result) {
if(result == NSFileHandlingPanelOKButton) {
MPDocument *document = [[self windowController] document];
for (NSURL *attachmentURL in [openPanel URLs]) {
[document addAttachment:attachmentURL toEntry:self.selectedEntry];
}
}
}];
}
- (IBAction)removeAttachment:(id)sender {
MPDocument *document = [[self windowController] document];
if(document.version == MPDatabaseVersion3) {
// Uhhhh :D
}
if(document.version == MPDatabaseVersion4) {
Kdb4Entry *entry = (Kdb4Entry *)self.selectedEntry;
BinaryRef *reference = entry.binaries[[sender tag]];
[document removeAttachment:reference fromEntry:self.selectedEntry];
}
}
- (IBAction)edit:(id)sender {
[self.titleTextField setEditable:YES];
[self.usernameTextField setEditable:YES];
[[[[self windowController] document] undoManager] beginUndoGrouping];
}
- (IBAction)finishEdit:(id)sender {
NSUndoManager *undoManger = [[[self windowController] document] undoManager];
[undoManger setActionName:@"Edit"];
[undoManger endUndoGrouping];
[self.titleTextField setEditable:NO];
[self.usernameTextField setEditable:NO];
} }
#pragma mark Notificiations #pragma mark Notificiations
@@ -332,57 +420,4 @@ enum {
[self _updateContent]; [self _updateContent];
} }
#pragma mark NSTableViewDelegate
/* TODO: Divide this into single delegates */
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
if(tableView == self.attachmentTableView) {
return [self _viewForAttachmentTableColumn:tableColumn row:row];
}
return [self _viewForCustomFieldTableColumn:tableColumn row:row];
}
- (void)tableViewSelectionDidChange:(NSNotification *)notification {
if([notification object] == self.attachmentTableView) {
NSIndexSet *allColumns = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [[self.attachmentTableView tableColumns] count])];
Kdb4Entry *entryv4 = (Kdb4Entry *)self.selectedEntry;
NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [entryv4.binaries count] )];
[self.attachmentTableView reloadDataForRowIndexes:indexSet columnIndexes:allColumns];
}
}
- (NSView *)_viewForAttachmentTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
/* Decide what view to use */
NSIndexSet *selectedIndexes = [self.attachmentTableView selectedRowIndexes];
NSString *viewIdentifyer = [selectedIndexes containsIndex:row] ? @"SelectedCell" : @"NormalCell";
NSTableCellView *view = [_attachmentTableView makeViewWithIdentifier:viewIdentifyer owner:_attachmentTableView];
/* Bind view */
if([self.selectedEntry isKindOfClass:[Kdb4Entry class]]) {
Kdb4Entry *entry = (Kdb4Entry *)self.selectedEntry;
BinaryRef *binaryRef = entry.binaries[row];
[[view textField] bind:NSValueBinding toObject:binaryRef withKeyPath:@"key" options:nil];
[[view imageView] setImage:[[NSWorkspace sharedWorkspace] iconForFileType:[binaryRef.key pathExtension]]];
}
return view;
}
- (NSView *)_viewForCustomFieldTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
MPCustomFieldTableCellView *view = [_customFieldsTableView makeViewWithIdentifier:[tableColumn identifier] owner:_customFieldsTableView];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_customFieldFrameChanged:) name:NSViewFrameDidChangeNotification object:view];
if([self.selectedEntry isKindOfClass:[Kdb4Entry class]]) {
Kdb4Entry *entry = (Kdb4Entry *)self.selectedEntry;
StringField *stringField = entry.stringFields[row];
[view.labelTextField bind:NSValueBinding toObject:stringField withKeyPath:MPStringFieldKeyUndoableKey options:nil];
[view.valueTextField bind:NSValueBinding toObject:stringField withKeyPath:MPStringFieldValueUndoableKey options:nil];
[view.removeButton setTarget:self];
[view.removeButton setAction:@selector(removeCustomField:)];
[view.removeButton setTag:row];
}
return view;
}
- (void)_customFieldFrameChanged:(NSNotification *)notification {
// NSView *sender = [notification object];
// NSLog(@"didChangeFrameFor: %@ to: %@", sender, NSStringFromRect([sender frame]));
}
@end @end

View File

@@ -13,6 +13,7 @@
#import "KdbLib.h" #import "KdbLib.h"
#import "KdbGroup+Undo.h" #import "KdbGroup+Undo.h"
#import "KdbEntry+Undo.h"
#import "KdbGroup+MPTreeTools.h" #import "KdbGroup+MPTreeTools.h"
#import "KdbEntry+MPTreeTools.h" #import "KdbEntry+MPTreeTools.h"
@@ -79,7 +80,7 @@
MPDocument *document = [[[outlineView window] windowController] document]; MPDocument *document = [[[outlineView window] windowController] document];
accepted = [document group:_draggedItem isMoveableToGroup:target]; accepted = [document group:_draggedItem isMoveableToGroup:target];
if( accepted ) { if( accepted ) {
[document moveGroup:_draggedItem toGroup:target index:index]; [_draggedItem moveToGroupUndoable:target atIndex:index];
} }
info.animatesToDestination = !accepted; info.animatesToDestination = !accepted;
return accepted; return accepted;
@@ -94,7 +95,7 @@
KdbEntry *draggedEntry = [rootGroup entryForUUID:uuid]; KdbEntry *draggedEntry = [rootGroup entryForUUID:uuid];
if(draggedEntry) { if(draggedEntry) {
if(draggedEntry.parent != target && index == NSOutlineViewDropOnItemIndex) { if(draggedEntry.parent != target && index == NSOutlineViewDropOnItemIndex) {
[document moveEntry:draggedEntry toGroup:target index:index]; [draggedEntry moveToGroupUndoable:target atIndex:index];
return YES; return YES;
} }
} }

View File

@@ -39,6 +39,8 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
@property (strong) MPOutlineDataSource *datasource; @property (strong) MPOutlineDataSource *datasource;
@property (strong) NSMenu *menu; @property (strong) NSMenu *menu;
@property (copy, nonatomic) NSString *databaseNameWrapper;
@end @end
@implementation MPOutlineViewController @implementation MPOutlineViewController
@@ -53,6 +55,7 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
_treeController = [[NSTreeController alloc] init]; _treeController = [[NSTreeController alloc] init];
_bindingEstablished = NO; _bindingEstablished = NO;
_datasource = [[MPOutlineDataSource alloc] init]; _datasource = [[MPOutlineDataSource alloc] init];
_databaseNameWrapper = NSLocalizedString(@"NEW_DATABASE", "Name for a newly created Database");
} }
return self; return self;
@@ -64,7 +67,7 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
[_outlineView setMenu:[self _contextMenu]]; [_outlineView setMenu:[self _contextMenu]];
[_outlineView setAllowsEmptySelection:YES]; [_outlineView setAllowsEmptySelection:YES];
[_outlineView setFloatsGroupRows:NO]; [_outlineView setFloatsGroupRows:NO];
[_outlineView registerForDraggedTypes:@[ MPPasteBoardType ]]; //[_outlineView registerForDraggedTypes:@[ MPPasteBoardType ]];
[_outlineView setDraggingSourceOperationMask:NSDragOperationEvery forLocal:YES]; [_outlineView setDraggingSourceOperationMask:NSDragOperationEvery forLocal:YES];
[_bottomBar setBorderType:HNHBorderTop]; [_bottomBar setBorderType:HNHBorderTop];
[_addGroupButton setAction:[MPActionHelper actionOfType:MPActionAddGroup]]; [_addGroupButton setAction:[MPActionHelper actionOfType:MPActionAddGroup]];
@@ -76,6 +79,9 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
[_treeController setChildrenKeyPath:@"groups"]; [_treeController setChildrenKeyPath:@"groups"];
[_treeController bind:NSContentBinding toObject:document withKeyPath:@"rootAdapter" options:nil]; [_treeController bind:NSContentBinding toObject:document withKeyPath:@"rootAdapter" options:nil];
[_outlineView bind:NSContentBinding toObject:_treeController withKeyPath:@"arrangedObjects" options:nil]; [_outlineView bind:NSContentBinding toObject:_treeController withKeyPath:@"arrangedObjects" options:nil];
if([document.tree respondsToSelector:@selector(databaseName)]) {
[self bind:@"databaseNameWrapper" toObject:document.tree withKeyPath:@"databaseName" options:nil];
}
[_outlineView setDataSource:self.datasource]; [_outlineView setDataSource:self.datasource];
_bindingEstablished = YES; _bindingEstablished = YES;
} }
@@ -83,7 +89,7 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
[_outlineView expandItem:node expandChildren:YES]; [_outlineView expandItem:node expandChildren:YES];
} }
#pragma makr Notifications #pragma mark Notifications
- (void)setupNotifications:(MPDocumentWindowController *)windowController { - (void)setupNotifications:(MPDocumentWindowController *)windowController {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_didCreateGroup:) name:MPDocumentDidAddGroupNotification object:[windowController document]]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_didCreateGroup:) name:MPDocumentDidAddGroupNotification object:[windowController document]];
} }
@@ -108,6 +114,17 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
} }
} }
- (void)setDatabaseNameWrapper:(NSString *)databaseNameWrapper {
if(![_databaseNameWrapper isEqualToString:databaseNameWrapper]) {
if([databaseNameWrapper length] == 0) {
_databaseNameWrapper = NSLocalizedString(@"DATABASE", "Default name database");
}
else {
_databaseNameWrapper= [databaseNameWrapper copy];
}
}
}
#pragma mark - #pragma mark -
#pragma mark Actions #pragma mark Actions
@@ -121,18 +138,12 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
} }
- (void)createEntry:(id)sender { - (void)createEntry:(id)sender {
KdbGroup *group = [self _clickedOrSelectedGroup];
if(group) {
MPDocument *document = [[self windowController] document]; MPDocument *document = [[self windowController] document];
[document createEntry:group]; [document createEntry:[self _clickedOrSelectedGroup]];
}
} }
- (void)deleteNode:(id)sender { - (void)deleteNode:(id)sender {
KdbGroup *group = [self _clickedOrSelectedGroup]; [[[self windowController] document] deleteGroup:[self _clickedOrSelectedGroup]];
if(group && group.parent) {
[[[self windowController] document] group:group.parent removeGroup:group];
}
} }
#pragma mark NSOutlineViewDelegate #pragma mark NSOutlineViewDelegate
@@ -141,14 +152,14 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
if( [self _itemIsRootNodeAdapter:item] ) { if( [self _itemIsRootNodeAdapter:item] ) {
//NSDictionary *options = @{ NSValueTransformerBindingOption : [NSValueTransformer valueTransformerForName:MPUppsercaseStringValueTransformerName] }; //NSDictionary *options = @{ NSValueTransformerBindingOption : [NSValueTransformer valueTransformerForName:MPUppsercaseStringValueTransformerName] };
view = [outlineView makeViewWithIdentifier:_MPOutlinveViewHeaderViewIdentifier owner:self]; view = [outlineView makeViewWithIdentifier:_MPOutlinveViewHeaderViewIdentifier owner:self];
[view.textField setStringValue:NSLocalizedString(@"GROUPS", @"")]; [view.textField bind:NSValueBinding toObject:self withKeyPath:@"databaseNameWrapper" options:nil];
} }
else { else {
KdbGroup *group = [item representedObject]; KdbGroup *group = [item representedObject];
view = [outlineView makeViewWithIdentifier:_MPOutlineViewDataViewIdentifier owner:self]; view = [outlineView makeViewWithIdentifier:_MPOutlineViewDataViewIdentifier owner:self];
NSImage *icon = [MPIconHelper icon:(MPIconType)[group image]]; NSImage *icon = [MPIconHelper icon:(MPIconType)[group image]];
[view.imageView setImage:icon]; [view.imageView setImage:icon];
[view.textField bind:NSValueBinding toObject:group withKeyPath:@"name" options:nil]; [view.textField bind:NSValueBinding toObject:group withKeyPath:MPGroupNameUndoableKey options:nil];
[view.textField bind:@"count" toObject:group withKeyPath:@"entries.@count" options:nil]; [view.textField bind:@"count" toObject:group withKeyPath:@"entries.@count" options:nil];
} }

View File

@@ -1,13 +0,0 @@
//
// MPPasswordEditViewController.h
// MacPass
//
// Created by Michael Starke on 29.04.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import "MPViewController.h"
@interface MPPasswordEditViewController : MPViewController
@end

View File

@@ -1,67 +0,0 @@
//
// MPPasswordEditViewController.m
// MacPass
//
// Created by Michael Starke on 29.04.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import "MPPasswordEditViewController.h"
#import "MPKeyfilePathControlDelegate.h"
#import "MPDocumentWindowController.h"
#import "MPDocument.h"
@interface MPPasswordEditViewController ()
@property (weak) IBOutlet NSSecureTextField *passwordTextField;
@property (weak) IBOutlet NSPathControl *keyfilePathControl;
@property (strong) MPKeyfilePathControlDelegate *pathControlDelegate;
- (IBAction)_change:(id)sender;
- (IBAction)_cancel:(id)sender;
@end
@implementation MPPasswordEditViewController
- (id)init {
return [self initWithNibName:@"PasswordEditView" bundle:nil];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if(self) {
_pathControlDelegate = [[MPKeyfilePathControlDelegate alloc] init];
}
return self;
}
- (NSResponder *)reconmendedFirstResponder {
return self.passwordTextField;
}
- (void)didLoadView {
[self.keyfilePathControl setDelegate:self.pathControlDelegate];
}
- (IBAction)_change:(id)sender {
MPDocument *document = [[self windowController] document];
if(document) {
document.key = [self.keyfilePathControl URL];
NSString *password = [self.passwordTextField stringValue];
if([password length] > 0) {
document.password = password;
}
else {
document.password = nil;
}
}
id mainWindowController = [[[self view] window] windowController];
[mainWindowController showEntries];
}
- (IBAction)_cancel:(id)sender {
id mainWindowController = [[[self view] window] windowController];
[mainWindowController showEntries];
}
@end

View File

@@ -11,15 +11,20 @@
#import "MPDocument.h" #import "MPDocument.h"
#import "MPKeyfilePathControlDelegate.h" #import "MPKeyfilePathControlDelegate.h"
#import "HNHRoundedSecureTextField.h"
@interface MPPasswordInputController () @interface MPPasswordInputController ()
@property (weak) IBOutlet NSTextField *passwordTextField; @property (weak) IBOutlet HNHRoundedSecureTextField *passwordTextField;
@property (weak) IBOutlet NSPathControl *keyPathControl; @property (weak) IBOutlet NSPathControl *keyPathControl;
@property (strong) MPKeyfilePathControlDelegate *pathControlDelegate; @property (strong) MPKeyfilePathControlDelegate *pathControlDelegate;
@property (weak) IBOutlet NSImageView *errorImageView; @property (weak) IBOutlet NSImageView *errorImageView;
@property (weak) IBOutlet NSTextField *errorInfoTextField; @property (weak) IBOutlet NSTextField *errorInfoTextField;
@property (weak) IBOutlet NSButton *togglePasswordButton;
@property (assign) BOOL showPassword;
- (IBAction)_decrypt:(id)sender; - (IBAction)_decrypt:(id)sender;
- (IBAction)_clearKey:(id)sender;
@end @end
@@ -33,6 +38,8 @@
- (void)didLoadView { - (void)didLoadView {
[self.keyPathControl setDelegate:self.pathControlDelegate]; [self.keyPathControl setDelegate:self.pathControlDelegate];
[self.errorImageView setImage:[NSImage imageNamed:NSImageNameCaution]]; [self.errorImageView setImage:[NSImage imageNamed:NSImageNameCaution]];
[self.passwordTextField bind:@"showPassword" toObject:self withKeyPath:@"showPassword" options:nil];
[self.togglePasswordButton bind:NSValueBinding toObject:self withKeyPath:@"showPassword" options:nil];
[self _reset]; [self _reset];
} }
@@ -44,13 +51,16 @@
// show Warnign if read-only mode! // show Warnign if read-only mode!
[self _reset]; [self _reset];
} }
#pragma mark NSTextViewDelegate
#pragma mark -
#pragma mark Private
- (IBAction)_decrypt:(id)sender { - (IBAction)_decrypt:(id)sender {
id windowController = [[[self view] window] windowController]; id windowController = [[[self view] window] windowController];
MPDocument *document = [windowController document]; MPDocument *document = [windowController document];
if(document) { if(document) {
BOOL isOk = NO; BOOL isOk = NO;
if(document.isDecrypted) { if(document.decrypted) {
// TODO: Fix unlocking to actually test // TODO: Fix unlocking to actually test
BOOL noPassword = !document.password && [[self.passwordTextField stringValue] length] == 0; BOOL noPassword = !document.password && [[self.passwordTextField stringValue] length] == 0;
BOOL passwordOk = [document.password isEqualToString:[self.passwordTextField stringValue]]; BOOL passwordOk = [document.password isEqualToString:[self.passwordTextField stringValue]];
@@ -59,7 +69,7 @@
isOk = (noPassword || passwordOk) && (noKey || keyOk); isOk = (noPassword || passwordOk) && (noKey || keyOk);
} }
else { else {
isOk = [document decryptWithPassword:[self.passwordTextField stringValue] keyFileURL:[self.keyPathControl URL]]; isOk = [document unlockWithPassword:[self.passwordTextField stringValue] keyFileURL:[self.keyPathControl URL]];
} }
if(!isOk) { if(!isOk) {
[self _showError]; [self _showError];
@@ -70,7 +80,12 @@
} }
} }
- (IBAction)_clearKey:(id)sender {
[self.keyPathControl setURL:nil];
}
- (void)_reset { - (void)_reset {
self.showPassword = NO;
[self.passwordTextField setStringValue:@""]; [self.passwordTextField setStringValue:@""];
[self.keyPathControl setURL:nil]; [self.keyPathControl setURL:nil];
[self.errorInfoTextField setHidden:YES]; [self.errorInfoTextField setHidden:YES];

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