31 Commits

Author SHA1 Message Date
michael starke
9ced3fce0b Changed password/keyfile requesting. No password/keyfile is enforced until you want to save the file. 2013-07-22 00:02:14 +02:00
michael starke
acc800c9e6 Fixed #59 Password length input is nu read only. Not a nice solution but for now working
Attachments for Kdb and Kdbx Databases are now supported. Save, Add, Delete
2013-07-21 23:23:45 +02:00
michael starke
45cb4a2652 Updated Credits 2013-07-21 14:41:37 +02:00
michael starke
1f94a626bb Create new on activate disabled. There's a annoying bug in there :( 2013-07-21 14:22:44 +02:00
michael starke
a6afe0bcf4 Fixed #29 Application now stores the last open database by itself. If window restoration in OS X is disabled, the app also reopens the last db. 2013-07-21 14:14:05 +02:00
michael starke
1fd89bfab6 Updated submodules 2013-07-21 04:29:22 +02:00
michael starke
db0640840f Updated Submodules 2013-07-21 01:01:23 +02:00
michael starke
fb735d9e41 Reduced PDF file sizes 2013-07-21 00:54:19 +02:00
michael starke
862cbe839e Updated Submodule 2013-07-20 20:00:16 +02:00
michael starke
cb5a71dfee Updated submodule 2013-07-20 19:46:31 +02:00
michael starke
30697648b9 Updated localization
Fixed an issue that automatically set the first group to be the trashcan
2013-07-20 17:04:13 +02:00
michael starke
e5e8d01dff Removed unused Code 2013-07-20 16:42:35 +02:00
michael starke
030dbd5be7 Fixed #46 Binaries get now deleted when entries are delete on trans cleaning
MenuEntries are validated and disabled to fix #58. Model still doesn't do any testing
2013-07-20 16:31:20 +02:00
michael starke
e306b2b3f2 Updated submodule 2013-07-20 12:26:53 +02:00
michael starke
0fe99cda97 Updated Submodules 2013-07-20 12:23:19 +02:00
michael starke
c207b2b24a Experiments with token filed in Inspector 2013-07-20 03:23:18 +02:00
michael starke
dc51c60c19 Attachments on Kdb1 Entries are now supported. Saving not implemented. Attach/detach works. 2013-07-19 23:30:45 +02:00
michael starke
86d983f776 Subbed Kdb3 Entry attachment handling. 2013-07-19 22:45:04 +02:00
michael starke
efa727eaba Settings now work with KDB1 Files and do not trap the Application in the modal dialog
Added user base settings to hide/show passwords at KDB1 field. The settings are stored but not considered ;)
2013-07-19 22:25:40 +02:00
michael starke
5e6d2bed3d Removed commented code 2013-07-19 18:42:18 +02:00
michael starke
5e6e31fb47 Fixed Issue with non-initalized password repeat filed on first load of the databaseSettings window 2013-07-19 18:26:42 +02:00
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
64 changed files with 3844 additions and 1287 deletions

2
HNHUi

Submodule HNHUi updated: a4186af409...c32f87da30

View File

@@ -10,8 +10,21 @@
4C01C23F1764D2980016D5D0 /* KdbEntry+Undo.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C01C23E1764D2980016D5D0 /* KdbEntry+Undo.m */; };
4C01C2421764D8980016D5D0 /* MPContextMenuHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C01C2411764D8980016D5D0 /* MPContextMenuHelper.m */; };
4C01C245176500C40016D5D0 /* HNHLevelIndicatorCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C01C244176500C40016D5D0 /* HNHLevelIndicatorCell.m */; };
4C055E74179620BF00BD2BAB /* NSString+CommandString.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C055E73179620BF00BD2BAB /* NSString+CommandString.m */; };
4C10412C178CDD44001B5239 /* NSDate+Humanized.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C10412B178CDD44001B5239 /* NSDate+Humanized.m */; };
4C16BA6217879A3C002B42BD /* MPPasswordStringFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C16BA6117879A3C002B42BD /* MPPasswordStringFormatter.m */; };
4C1842AB179B027800E2F5BC /* KPKDeletedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1842AA179B027800E2F5BC /* KPKDeletedNode.m */; };
4C1842AF179B211C00E2F5BC /* KPKXmlTreeReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1842AE179B211C00E2F5BC /* KPKXmlTreeReader.m */; };
4C1842B2179B28C400E2F5BC /* KPKBinaryTreeReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1842B1179B28C400E2F5BC /* KPKBinaryTreeReader.m */; };
4C1842B5179B28D400E2F5BC /* KPKBinaryTreeWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1842B4179B28D400E2F5BC /* KPKBinaryTreeWriter.m */; };
4C1842B8179B348600E2F5BC /* KPKTreeLoadingTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1842B7179B348600E2F5BC /* KPKTreeLoadingTest.m */; };
4C1842BC179B434C00E2F5BC /* KPKXmlHeaderReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1842BB179B434C00E2F5BC /* KPKXmlHeaderReader.m */; };
4C1842C0179B5BFD00E2F5BC /* NSData+CommonCrypto.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1842BF179B5BFD00E2F5BC /* NSData+CommonCrypto.m */; };
4C1842C3179B69E700E2F5BC /* NSData+HashedData.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1842C2179B69E700E2F5BC /* NSData+HashedData.m */; };
4C1842C6179BF52100E2F5BC /* KPKLegacyHeaderReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1842C5179BF52000E2F5BC /* KPKLegacyHeaderReader.m */; };
4C1842CA179C616700E2F5BC /* KPKTreeCryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1842C9179C616700E2F5BC /* KPKTreeCryptor.m */; };
4C1842D0179C64DD00E2F5BC /* KPKLegacyTreeCryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1842CF179C64DD00E2F5BC /* KPKLegacyTreeCryptor.m */; };
4C1842D3179C64F000E2F5BC /* KPKXmlTreeCryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1842D2179C64EF00E2F5BC /* KPKXmlTreeCryptor.m */; };
4C18F9AB178E122500890BCE /* Test_Password_1234.kdb in Resources */ = {isa = PBXBuildFile; fileRef = 4C18F9AA178E122500890BCE /* Test_Password_1234.kdb */; };
4C19E500178E26EF002F2CD0 /* Test_Password_1234.kdbx in Resources */ = {isa = PBXBuildFile; fileRef = 4C19E4FF178E26EF002F2CD0 /* Test_Password_1234.kdbx */; };
4C19E503178E2871002F2CD0 /* MPDatabasePasswordAndKeyfile.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C19E502178E2871002F2CD0 /* MPDatabasePasswordAndKeyfile.m */; };
@@ -56,6 +69,9 @@
4C2E381F16D11FF900037A9D /* 05_LanguagesTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4C2E381C16D11FF900037A9D /* 05_LanguagesTemplate.pdf */; };
4C2E382316D1421B00037A9D /* MPIconHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C2E382216D1421B00037A9D /* MPIconHelper.m */; };
4C2E382616D1470200037A9D /* MPViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C2E382516D1470200037A9D /* MPViewController.m */; };
4C305F36179A0BD70082334F /* KPKIcon.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C305F35179A0BD70082334F /* KPKIcon.m */; };
4C305F3C179A19F90082334F /* KPKIconLoading.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C305F3B179A19F90082334F /* KPKIconLoading.m */; };
4C305F3E179A1A760082334F /* image.png in Resources */ = {isa = PBXBuildFile; fileRef = 4C305F3D179A1A760082334F /* image.png */; };
4C3666411787327E00B249F1 /* MPDocument+Attachments.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C3666401787327E00B249F1 /* MPDocument+Attachments.m */; };
4C366643178748F500B249F1 /* 99_HarddiskTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4C366642178748F500B249F1 /* 99_HarddiskTemplate.pdf */; };
4C36E5B4177CD4FB00152132 /* Kdb4Tree+KVOAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C36E5B3177CD4FB00152132 /* Kdb4Tree+KVOAdditions.m */; };
@@ -66,11 +82,12 @@
4C3D4C0817594CA40038DAAC /* HNHSeparator.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C3D4C0717594CA40038DAAC /* HNHSeparator.m */; };
4C3E1CC0177DEFB3003BD9BD /* StringField+Undo.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C3E1CBF177DEFB3003BD9BD /* StringField+Undo.m */; };
4C3F28541791EDFD00703281 /* KPKErrors.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C3F28531791EDFD00703281 /* KPKErrors.m */; };
4C3F28581791F04F00703281 /* LocalizableErrors.strings in Resources */ = {isa = PBXBuildFile; fileRef = 4C3F28571791F04F00703281 /* LocalizableErrors.strings */; };
4C3FFD9E16DAF60600DF9186 /* FilterBar.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C3FFD9D16DAF60600DF9186 /* FilterBar.xib */; };
4C431BCD16E2A82800700A81 /* MPPasteBoardController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C431BCC16E2A82700700A81 /* MPPasteBoardController.m */; };
4C431BCF16E2BAB000700A81 /* OverlayWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C431BCE16E2BAB000700A81 /* OverlayWindow.xib */; };
4C4436771792BE810099E220 /* KPKFormat.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C4436761792BE810099E220 /* KPKFormat.m */; };
4C4510091798C53700219998 /* StringField+Validation.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C4510081798C53700219998 /* StringField+Validation.m */; };
4C45100C1798C65C00219998 /* Kdb4Entry+MPAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C45100B1798C65C00219998 /* Kdb4Entry+MPAdditions.m */; };
4C45FB1C178E09ED0010007D /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C45FB1B178E09ED0010007D /* SenTestingKit.framework */; };
4C45FB1D178E09ED0010007D /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C77E36615B84A240093A587 /* Cocoa.framework */; };
4C45FB23178E09ED0010007D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 4C45FB21178E09ED0010007D /* InfoPlist.strings */; };
@@ -137,12 +154,13 @@
4C669B9F16760ED100DD0774 /* RandomStream.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C669B7516760ED100DD0774 /* RandomStream.m */; };
4C669BA016760ED100DD0774 /* Salsa20RandomStream.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C669B7716760ED100DD0774 /* Salsa20RandomStream.m */; };
4C669BA216760ED100DD0774 /* UUID.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C669B7B16760ED100DD0774 /* UUID.m */; };
4C67D33017981A2B00A7BDFC /* HNHTokenField.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C67D32F17981A2B00A7BDFC /* HNHTokenField.m */; };
4C67D33317981ABA00A7BDFC /* HNHTokenFieldCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C67D33217981ABA00A7BDFC /* HNHTokenFieldCell.m */; };
4C69A73A16D589DF00EC1B1A /* HNHGradientView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C69A73916D589DF00EC1B1A /* HNHGradientView.m */; };
4C6D1D25178579570014C5A5 /* 48_FolderTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4C6D1D24178579570014C5A5 /* 48_FolderTemplate.pdf */; };
4C6D1D27178586CA0014C5A5 /* 99_AddFolderTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4C6D1D26178586CA0014C5A5 /* 99_AddFolderTemplate.pdf */; };
4C6D1D2B17858A250014C5A5 /* MacPass.icns in Resources */ = {isa = PBXBuildFile; fileRef = 4C6D1D2A17858A250014C5A5 /* MacPass.icns */; };
4C701CBC178618A000581B88 /* 12_RemoteTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4C701CBB178618A000581B88 /* 12_RemoteTemplate.pdf */; };
4C70D0FD1790924700652EE9 /* KPKParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C70D0FC1790924700652EE9 /* KPKParser.m */; };
4C70D100179092F200652EE9 /* KPKPassword.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C70D0FF179092F200652EE9 /* KPKPassword.m */; };
4C74DD07177BD1640034A9DB /* MPCustomFieldView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C74DD06177BD1640034A9DB /* MPCustomFieldView.m */; };
4C76155C1764C04C0015A1A6 /* GeneralSettings.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C76155E1764C04C0015A1A6 /* GeneralSettings.xib */; };
@@ -176,6 +194,7 @@
4CA0B2FC15BCAF8600654E32 /* MPSettingsWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CA0B2FB15BCAF8600654E32 /* MPSettingsWindowController.m */; };
4CA0E3A7176FAF99004D18CB /* MPDocumentQueryService.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CA0E3A6176FAF99004D18CB /* MPDocumentQueryService.m */; };
4CA2335A176DBFE100F0B6AC /* MPLockDaemon.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CA23359176DBFE100F0B6AC /* MPLockDaemon.m */; };
4CA7C36C179A98140099C34B /* NSString+Base64.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CA7C36B179A98140099C34B /* NSString+Base64.m */; };
4CAD747B15B887FD00104512 /* DDXMLElementAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CAD745715B887FD00104512 /* DDXMLElementAdditions.m */; };
4CAD747C15B887FD00104512 /* NSString+DDXML.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CAD745A15B887FD00104512 /* NSString+DDXML.m */; };
4CAD747D15B887FD00104512 /* DDXMLDocument.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CAD745D15B887FD00104512 /* DDXMLDocument.m */; };
@@ -186,6 +205,8 @@
4CAF62FC1763604000CD7084 /* HNHBadgedTextFieldCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CAF62FB1763604000CD7084 /* HNHBadgedTextFieldCell.m */; };
4CB9339916D3A0DD00A13B5D /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 4CB9339716D3A0DD00A13B5D /* Credits.rtf */; };
4CBA2ABA17074C07006D8139 /* MPSettingsHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CBA2AB917074C07006D8139 /* MPSettingsHelper.m */; };
4CC0D2CE17974A47000B4BDA /* MPCustomFieldTableViewDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CC0D2CD17974A47000B4BDA /* MPCustomFieldTableViewDelegate.m */; };
4CC0D2D117974A5A000B4BDA /* MPAttachmentTableViewDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CC0D2D017974A5A000B4BDA /* MPAttachmentTableViewDelegate.m */; };
4CC1AEBE16D4467C006D2AAB /* KdbTree+MPAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CC1AEBD16D4467C006D2AAB /* KdbTree+MPAdditions.m */; };
4CC299FF176F99E50050C939 /* MPRequestHandlerService.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CC299FE176F99E50050C939 /* MPRequestHandlerService.m */; };
4CC29A02176F9D140050C939 /* MPTestAssociateRequestHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CC29A01176F9D140050C939 /* MPTestAssociateRequestHandler.m */; };
@@ -225,6 +246,7 @@
4CF7805F176E75110032EE71 /* ServerSettings.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4CF7805E176E75110032EE71 /* ServerSettings.xib */; };
4CF78064176E75AD0032EE71 /* MPServerSettingsController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CF78063176E75AD0032EE71 /* MPServerSettingsController.m */; };
4CFC53BF16E94729007396BE /* MPShadowBox.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CFC53BE16E94729007396BE /* MPShadowBox.m */; };
4CFEB36E1799D9CF00AF1868 /* Kdb3Entry+KVOAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CFEB36D1799D9CF00AF1868 /* Kdb3Entry+KVOAdditions.m */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@@ -234,10 +256,40 @@
4C01C2411764D8980016D5D0 /* MPContextMenuHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPContextMenuHelper.m; sourceTree = "<group>"; };
4C01C243176500C40016D5D0 /* HNHLevelIndicatorCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HNHLevelIndicatorCell.h; sourceTree = "<group>"; };
4C01C244176500C40016D5D0 /* HNHLevelIndicatorCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HNHLevelIndicatorCell.m; sourceTree = "<group>"; };
4C055E72179620BF00BD2BAB /* NSString+CommandString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+CommandString.h"; sourceTree = "<group>"; };
4C055E73179620BF00BD2BAB /* NSString+CommandString.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+CommandString.m"; sourceTree = "<group>"; };
4C10412A178CDD44001B5239 /* NSDate+Humanized.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDate+Humanized.h"; sourceTree = "<group>"; };
4C10412B178CDD44001B5239 /* NSDate+Humanized.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDate+Humanized.m"; sourceTree = "<group>"; };
4C16BA6017879A3C002B42BD /* MPPasswordStringFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPasswordStringFormatter.h; sourceTree = "<group>"; };
4C16BA6117879A3C002B42BD /* MPPasswordStringFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPPasswordStringFormatter.m; sourceTree = "<group>"; };
4C1842A9179B027700E2F5BC /* KPKDeletedNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KPKDeletedNode.h; sourceTree = "<group>"; };
4C1842AA179B027800E2F5BC /* KPKDeletedNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KPKDeletedNode.m; sourceTree = "<group>"; };
4C1842AD179B211C00E2F5BC /* KPKXmlTreeReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KPKXmlTreeReader.h; sourceTree = "<group>"; };
4C1842AE179B211C00E2F5BC /* KPKXmlTreeReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KPKXmlTreeReader.m; sourceTree = "<group>"; };
4C1842B0179B28C400E2F5BC /* KPKBinaryTreeReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KPKBinaryTreeReader.h; sourceTree = "<group>"; };
4C1842B1179B28C400E2F5BC /* KPKBinaryTreeReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KPKBinaryTreeReader.m; sourceTree = "<group>"; };
4C1842B3179B28D400E2F5BC /* KPKBinaryTreeWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KPKBinaryTreeWriter.h; sourceTree = "<group>"; };
4C1842B4179B28D400E2F5BC /* KPKBinaryTreeWriter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KPKBinaryTreeWriter.m; sourceTree = "<group>"; };
4C1842B6179B348600E2F5BC /* KPKTreeLoadingTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KPKTreeLoadingTest.h; sourceTree = "<group>"; };
4C1842B7179B348600E2F5BC /* KPKTreeLoadingTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KPKTreeLoadingTest.m; sourceTree = "<group>"; };
4C1842B9179B3A1700E2F5BC /* KPKHeaderFields.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = KPKHeaderFields.h; path = Format/KPKHeaderFields.h; sourceTree = "<group>"; };
4C1842BA179B434C00E2F5BC /* KPKXmlHeaderReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KPKXmlHeaderReader.h; sourceTree = "<group>"; };
4C1842BB179B434C00E2F5BC /* KPKXmlHeaderReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KPKXmlHeaderReader.m; sourceTree = "<group>"; };
4C1842BE179B5BFD00E2F5BC /* NSData+CommonCrypto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+CommonCrypto.h"; sourceTree = "<group>"; };
4C1842BF179B5BFD00E2F5BC /* NSData+CommonCrypto.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+CommonCrypto.m"; sourceTree = "<group>"; };
4C1842C1179B69E600E2F5BC /* NSData+HashedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+HashedData.h"; sourceTree = "<group>"; };
4C1842C2179B69E700E2F5BC /* NSData+HashedData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+HashedData.m"; sourceTree = "<group>"; };
4C1842C4179BF51F00E2F5BC /* KPKLegacyHeaderReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KPKLegacyHeaderReader.h; sourceTree = "<group>"; };
4C1842C5179BF52000E2F5BC /* KPKLegacyHeaderReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KPKLegacyHeaderReader.m; sourceTree = "<group>"; };
4C1842C7179BF6A100E2F5BC /* KPKLegacyHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = KPKLegacyHeader.h; path = Format/KPKLegacyHeader.h; sourceTree = "<group>"; };
4C1842C8179C616600E2F5BC /* KPKTreeCryptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KPKTreeCryptor.h; sourceTree = "<group>"; };
4C1842C9179C616700E2F5BC /* KPKTreeCryptor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KPKTreeCryptor.m; sourceTree = "<group>"; };
4C1842CE179C64DC00E2F5BC /* KPKLegacyTreeCryptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KPKLegacyTreeCryptor.h; sourceTree = "<group>"; };
4C1842CF179C64DD00E2F5BC /* KPKLegacyTreeCryptor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KPKLegacyTreeCryptor.m; sourceTree = "<group>"; };
4C1842D1179C64EF00E2F5BC /* KPKXmlTreeCryptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KPKXmlTreeCryptor.h; sourceTree = "<group>"; };
4C1842D2179C64EF00E2F5BC /* KPKXmlTreeCryptor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KPKXmlTreeCryptor.m; sourceTree = "<group>"; };
4C1842D4179C6DE400E2F5BC /* KPKHeaderReading.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KPKHeaderReading.h; sourceTree = "<group>"; };
4C1842D5179C6F1800E2F5BC /* KPKHeaderWriting.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KPKHeaderWriting.h; sourceTree = "<group>"; };
4C18F9AA178E122500890BCE /* Test_Password_1234.kdb */ = {isa = PBXFileReference; lastKnownFileType = file; name = Test_Password_1234.kdb; path = Databases/Test_Password_1234.kdb; sourceTree = "<group>"; };
4C19E4FF178E26EF002F2CD0 /* Test_Password_1234.kdbx */ = {isa = PBXFileReference; lastKnownFileType = file; name = Test_Password_1234.kdbx; path = Databases/Test_Password_1234.kdbx; sourceTree = "<group>"; };
4C19E501178E2871002F2CD0 /* MPDatabasePasswordAndKeyfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPDatabasePasswordAndKeyfile.h; sourceTree = "<group>"; };
@@ -320,6 +372,11 @@
4C2E382216D1421B00037A9D /* MPIconHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPIconHelper.m; sourceTree = "<group>"; };
4C2E382416D1470200037A9D /* MPViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPViewController.h; sourceTree = "<group>"; };
4C2E382516D1470200037A9D /* MPViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPViewController.m; sourceTree = "<group>"; };
4C305F34179A0BD70082334F /* KPKIcon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KPKIcon.h; sourceTree = "<group>"; };
4C305F35179A0BD70082334F /* KPKIcon.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KPKIcon.m; sourceTree = "<group>"; };
4C305F3A179A19F90082334F /* KPKIconLoading.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KPKIconLoading.h; sourceTree = "<group>"; };
4C305F3B179A19F90082334F /* KPKIconLoading.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KPKIconLoading.m; sourceTree = "<group>"; };
4C305F3D179A1A760082334F /* image.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = image.png; path = Images/image.png; sourceTree = "<group>"; };
4C3666401787327E00B249F1 /* MPDocument+Attachments.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MPDocument+Attachments.m"; sourceTree = "<group>"; };
4C366642178748F500B249F1 /* 99_HarddiskTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 99_HarddiskTemplate.pdf; sourceTree = "<group>"; };
4C36E5B2177CD4FB00152132 /* Kdb4Tree+KVOAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Kdb4Tree+KVOAdditions.h"; sourceTree = "<group>"; };
@@ -338,13 +395,16 @@
4C3E1CBF177DEFB3003BD9BD /* StringField+Undo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "StringField+Undo.m"; sourceTree = "<group>"; };
4C3F28521791EDE800703281 /* KPKErrors.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KPKErrors.h; sourceTree = "<group>"; };
4C3F28531791EDFD00703281 /* KPKErrors.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KPKErrors.m; sourceTree = "<group>"; };
4C3F28571791F04F00703281 /* LocalizableErrors.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = LocalizableErrors.strings; path = Resources/LocalizableErrors.strings; sourceTree = "<group>"; };
4C3FFD9D16DAF60600DF9186 /* FilterBar.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = FilterBar.xib; sourceTree = "<group>"; };
4C431BCB16E2A82700700A81 /* MPPasteBoardController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPasteBoardController.h; sourceTree = "<group>"; };
4C431BCC16E2A82700700A81 /* MPPasteBoardController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPPasteBoardController.m; sourceTree = "<group>"; };
4C431BCE16E2BAB000700A81 /* OverlayWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = OverlayWindow.xib; sourceTree = "<group>"; };
4C4436751792BE810099E220 /* KPKFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KPKFormat.h; sourceTree = "<group>"; };
4C4436761792BE810099E220 /* KPKFormat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KPKFormat.m; sourceTree = "<group>"; };
4C4436751792BE810099E220 /* KPKFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KPKFormat.h; path = Format/KPKFormat.h; sourceTree = "<group>"; };
4C4436761792BE810099E220 /* KPKFormat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = KPKFormat.m; path = Format/KPKFormat.m; sourceTree = "<group>"; };
4C4510071798C53700219998 /* StringField+Validation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "StringField+Validation.h"; sourceTree = "<group>"; };
4C4510081798C53700219998 /* StringField+Validation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "StringField+Validation.m"; sourceTree = "<group>"; };
4C45100A1798C65C00219998 /* Kdb4Entry+MPAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Kdb4Entry+MPAdditions.h"; sourceTree = "<group>"; };
4C45100B1798C65C00219998 /* Kdb4Entry+MPAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "Kdb4Entry+MPAdditions.m"; sourceTree = "<group>"; };
4C45FB1A178E09ED0010007D /* MacPassTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MacPassTests.octest; sourceTree = BUILT_PRODUCTS_DIR; };
4C45FB1B178E09ED0010007D /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; };
4C45FB20178E09ED0010007D /* MacPassTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "MacPassTests-Info.plist"; sourceTree = "<group>"; };
@@ -472,14 +532,16 @@
4C669B7716760ED100DD0774 /* Salsa20RandomStream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Salsa20RandomStream.m; sourceTree = "<group>"; };
4C669B7A16760ED100DD0774 /* UUID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UUID.h; sourceTree = "<group>"; };
4C669B7B16760ED100DD0774 /* UUID.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UUID.m; sourceTree = "<group>"; };
4C67D32E17981A2B00A7BDFC /* HNHTokenField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HNHTokenField.h; sourceTree = "<group>"; };
4C67D32F17981A2B00A7BDFC /* HNHTokenField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HNHTokenField.m; sourceTree = "<group>"; };
4C67D33117981ABA00A7BDFC /* HNHTokenFieldCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HNHTokenFieldCell.h; sourceTree = "<group>"; };
4C67D33217981ABA00A7BDFC /* HNHTokenFieldCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HNHTokenFieldCell.m; sourceTree = "<group>"; };
4C69A73816D589DF00EC1B1A /* HNHGradientView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HNHGradientView.h; sourceTree = "<group>"; };
4C69A73916D589DF00EC1B1A /* HNHGradientView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HNHGradientView.m; sourceTree = "<group>"; };
4C6D1D24178579570014C5A5 /* 48_FolderTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 48_FolderTemplate.pdf; sourceTree = "<group>"; };
4C6D1D26178586CA0014C5A5 /* 99_AddFolderTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 99_AddFolderTemplate.pdf; sourceTree = "<group>"; };
4C6D1D2A17858A250014C5A5 /* MacPass.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = MacPass.icns; path = "../Assets/App icon/MacPass.icns"; sourceTree = "<group>"; };
4C701CBB178618A000581B88 /* 12_RemoteTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 12_RemoteTemplate.pdf; sourceTree = "<group>"; };
4C70D0FB1790924700652EE9 /* KPKParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KPKParser.h; sourceTree = "<group>"; };
4C70D0FC1790924700652EE9 /* KPKParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KPKParser.m; sourceTree = "<group>"; };
4C70D0FE179092F200652EE9 /* KPKPassword.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KPKPassword.h; sourceTree = "<group>"; };
4C70D0FF179092F200652EE9 /* KPKPassword.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KPKPassword.m; sourceTree = "<group>"; };
4C74DD05177BD1640034A9DB /* MPCustomFieldView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPCustomFieldView.h; sourceTree = "<group>"; };
@@ -489,7 +551,6 @@
4C76156B1764C0C80015A1A6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/PasswordInputView.xib; sourceTree = "<group>"; };
4C76156C1764C0CC0015A1A6 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/PasswordInputView.strings; sourceTree = "<group>"; };
4C7615701764C0E80015A1A6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/InspectorView.xib; sourceTree = "<group>"; };
4C7615721764C4A40015A1A6 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/GeneralSettings.strings; sourceTree = "<group>"; };
4C7615751764C4A40015A1A6 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/PasswordInputView.strings; sourceTree = "<group>"; };
4C7615771764C4A40015A1A6 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = "<group>"; };
4C7615781764C4A50015A1A6 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = de; path = de.lproj/Credits.rtf; sourceTree = "<group>"; };
@@ -545,9 +606,10 @@
4CA0B30D15BCB6FD00654E32 /* MPSettingsTab.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MPSettingsTab.h; sourceTree = "<group>"; };
4CA0E3A5176FAF99004D18CB /* MPDocumentQueryService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPDocumentQueryService.h; sourceTree = "<group>"; };
4CA0E3A6176FAF99004D18CB /* MPDocumentQueryService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPDocumentQueryService.m; sourceTree = "<group>"; };
4CA23357176DB8F000F0B6AC /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/GeneralSettings.strings; sourceTree = "<group>"; };
4CA23358176DBFE100F0B6AC /* MPLockDaemon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPLockDaemon.h; sourceTree = "<group>"; };
4CA23359176DBFE100F0B6AC /* MPLockDaemon.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPLockDaemon.m; sourceTree = "<group>"; };
4CA7C36A179A98140099C34B /* NSString+Base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+Base64.h"; sourceTree = "<group>"; };
4CA7C36B179A98140099C34B /* NSString+Base64.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+Base64.m"; sourceTree = "<group>"; };
4CAAFDD51787AED60013FCF9 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/MainMenu.strings; sourceTree = "<group>"; };
4CAD745615B887FD00104512 /* DDXMLElementAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDXMLElementAdditions.h; sourceTree = "<group>"; };
4CAD745715B887FD00104512 /* DDXMLElementAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDXMLElementAdditions.m; sourceTree = "<group>"; };
@@ -568,6 +630,10 @@
4CB9339816D3A0DD00A13B5D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = "<group>"; };
4CBA2AB617074B59006D8139 /* MPSettingsHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPSettingsHelper.h; sourceTree = "<group>"; };
4CBA2AB917074C07006D8139 /* MPSettingsHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPSettingsHelper.m; sourceTree = "<group>"; };
4CC0D2CC17974A47000B4BDA /* MPCustomFieldTableViewDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPCustomFieldTableViewDelegate.h; sourceTree = "<group>"; };
4CC0D2CD17974A47000B4BDA /* MPCustomFieldTableViewDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPCustomFieldTableViewDelegate.m; sourceTree = "<group>"; };
4CC0D2CF17974A5A000B4BDA /* MPAttachmentTableViewDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAttachmentTableViewDelegate.h; sourceTree = "<group>"; };
4CC0D2D017974A5A000B4BDA /* MPAttachmentTableViewDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAttachmentTableViewDelegate.m; sourceTree = "<group>"; };
4CC1AEBC16D4467C006D2AAB /* KdbTree+MPAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "KdbTree+MPAdditions.h"; sourceTree = "<group>"; };
4CC1AEBD16D4467C006D2AAB /* KdbTree+MPAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "KdbTree+MPAdditions.m"; sourceTree = "<group>"; };
4CC299FD176F99E50050C939 /* MPRequestHandlerService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPRequestHandlerService.h; sourceTree = "<group>"; };
@@ -582,7 +648,9 @@
4CC6727B1781D0D2006DEDCF /* KdbEntry+MPAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "KdbEntry+MPAdditions.m"; sourceTree = "<group>"; };
4CC7EA1917807E7E0089D4F3 /* HNHRoundendTextFieldCellHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HNHRoundendTextFieldCellHelper.h; sourceTree = "<group>"; };
4CC7EA1A17807E7E0089D4F3 /* HNHRoundendTextFieldCellHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HNHRoundendTextFieldCellHelper.m; sourceTree = "<group>"; };
4CD3ABB2178F71B50073F5C5 /* KPKVersion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KPKVersion.h; sourceTree = "<group>"; };
4CCA7EEC1797866F00B0B55E /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/GeneralSettings.strings; sourceTree = "<group>"; };
4CCA7EEE1797867200B0B55E /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/GeneralSettings.strings; sourceTree = "<group>"; };
4CD3ABB2178F71B50073F5C5 /* KPKVersion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KPKVersion.h; path = Format/KPKVersion.h; sourceTree = "<group>"; };
4CD3ABB3178F71B50073F5C5 /* KPKTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KPKTree.h; sourceTree = "<group>"; };
4CD3ABB4178F71B50073F5C5 /* KPKTree.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KPKTree.m; sourceTree = "<group>"; };
4CD3ABBD178F72610073F5C5 /* KPKEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KPKEntry.h; sourceTree = "<group>"; };
@@ -600,8 +668,9 @@
4CD78ABA16D155FF00768A1D /* 10_ContactTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 10_ContactTemplate.pdf; sourceTree = "<group>"; };
4CD78ABB16D155FF00768A1D /* 11_CameraTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 11_CameraTemplate.pdf; sourceTree = "<group>"; };
4CD884B615BD47080042BBF8 /* DocumentWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = DocumentWindow.xib; sourceTree = "<group>"; };
4CDB5C401794AA4F0017667E /* KPKTree+Serializing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "KPKTree+Serializing.h"; path = "../Core/KPKTree+Serializing.h"; sourceTree = "<group>"; };
4CDB5C411794AA4F0017667E /* KPKTree+Serializing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "KPKTree+Serializing.m"; path = "../Core/KPKTree+Serializing.m"; sourceTree = "<group>"; };
4CDB5C401794AA4F0017667E /* KPKTree+Serializing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "KPKTree+Serializing.h"; sourceTree = "<group>"; };
4CDB5C411794AA4F0017667E /* KPKTree+Serializing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "KPKTree+Serializing.m"; sourceTree = "<group>"; };
4CDE28D0179C8E010036C771 /* MPDatabaseSettingsDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MPDatabaseSettingsDelegate.h; sourceTree = "<group>"; };
4CDF01A116D1B76700D0AC08 /* MPEntryViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPEntryViewController.h; sourceTree = "<group>"; };
4CDF01A216D1B76700D0AC08 /* MPEntryViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPEntryViewController.m; sourceTree = "<group>"; };
4CE298E91795FC2A00DF7BDB /* MPEntryMenuDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPEntryMenuDelegate.h; sourceTree = "<group>"; };
@@ -638,6 +707,8 @@
4CF78063176E75AD0032EE71 /* MPServerSettingsController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPServerSettingsController.m; sourceTree = "<group>"; };
4CFC53BD16E94729007396BE /* MPShadowBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPShadowBox.h; sourceTree = "<group>"; };
4CFC53BE16E94729007396BE /* MPShadowBox.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPShadowBox.m; sourceTree = "<group>"; };
4CFEB36C1799D9CF00AF1868 /* Kdb3Entry+KVOAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Kdb3Entry+KVOAdditions.h"; sourceTree = "<group>"; };
4CFEB36D1799D9CF00AF1868 /* Kdb3Entry+KVOAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "Kdb3Entry+KVOAdditions.m"; sourceTree = "<group>"; };
6E719715172058BA00E4C5FC /* MPDatabaseVersion.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MPDatabaseVersion.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
@@ -715,6 +786,18 @@
name = ValueTransformer;
sourceTree = "<group>";
};
4C1842D6179C716100E2F5BC /* Format */ = {
isa = PBXGroup;
children = (
4C4436751792BE810099E220 /* KPKFormat.h */,
4C4436761792BE810099E220 /* KPKFormat.m */,
4CD3ABB2178F71B50073F5C5 /* KPKVersion.h */,
4C1842C7179BF6A100E2F5BC /* KPKLegacyHeader.h */,
4C1842B9179B3A1700E2F5BC /* KPKHeaderFields.h */,
);
name = Format;
sourceTree = "<group>";
};
4C18F9AC178E123200890BCE /* Databases */ = {
isa = PBXGroup;
children = (
@@ -883,6 +966,8 @@
4C2724D917790E7C00FD8456 /* NSMutableData+Base64.m */,
4C801AFA179310E2002821E3 /* NSString+Hexdata.h */,
4C801AFB179310E2002821E3 /* NSString+Hexdata.m */,
4CA7C36A179A98140099C34B /* NSString+Base64.h */,
4CA7C36B179A98140099C34B /* NSString+Base64.m */,
);
name = Categories;
sourceTree = "<group>";
@@ -912,10 +997,16 @@
4C36E5B3177CD4FB00152132 /* Kdb4Tree+KVOAdditions.m */,
4C4FCE16177D03D700BBF7AE /* Kdb4Entry+KVOAdditions.h */,
4C4FCE17177D03D700BBF7AE /* Kdb4Entry+KVOAdditions.m */,
4CFEB36C1799D9CF00AF1868 /* Kdb3Entry+KVOAdditions.h */,
4CFEB36D1799D9CF00AF1868 /* Kdb3Entry+KVOAdditions.m */,
4C83F4A81774B155006C5FC0 /* Kdb3Tree+NewTree.h */,
4C83F4A91774B155006C5FC0 /* Kdb3Tree+NewTree.m */,
4C83F4AB1774B25F006C5FC0 /* Kdb4Tree+NewTree.h */,
4C83F4AC1774B25F006C5FC0 /* Kdb4Tree+NewTree.m */,
4C4510071798C53700219998 /* StringField+Validation.h */,
4C4510081798C53700219998 /* StringField+Validation.m */,
4C45100A1798C65C00219998 /* Kdb4Entry+MPAdditions.h */,
4C45100B1798C65C00219998 /* Kdb4Entry+MPAdditions.m */,
);
name = "KeePassLib Categories";
sourceTree = "<group>";
@@ -944,6 +1035,14 @@
name = Helper;
sourceTree = "<group>";
};
4C305F3F179A1A790082334F /* Images */ = {
isa = PBXGroup;
children = (
4C305F3D179A1A760082334F /* image.png */,
);
name = Images;
sourceTree = "<group>";
};
4C37A84115B8B47D005EF8EE /* Delegates */ = {
isa = PBXGroup;
children = (
@@ -955,6 +1054,10 @@
4C811C8216ECD06E00C4BAC6 /* MPKeyfilePathControlDelegate.m */,
4CE298E91795FC2A00DF7BDB /* MPEntryMenuDelegate.h */,
4CE298EA1795FC2A00DF7BDB /* MPEntryMenuDelegate.m */,
4CC0D2CC17974A47000B4BDA /* MPCustomFieldTableViewDelegate.h */,
4CC0D2CD17974A47000B4BDA /* MPCustomFieldTableViewDelegate.m */,
4CC0D2CF17974A5A000B4BDA /* MPAttachmentTableViewDelegate.h */,
4CC0D2D017974A5A000B4BDA /* MPAttachmentTableViewDelegate.m */,
);
name = Delegates;
sourceTree = "<group>";
@@ -976,17 +1079,10 @@
name = Model;
sourceTree = "<group>";
};
4C3F28591791F05400703281 /* Resources */ = {
isa = PBXGroup;
children = (
4C3F28571791F04F00703281 /* LocalizableErrors.strings */,
);
name = Resources;
sourceTree = "<group>";
};
4C45FB1E178E09ED0010007D /* MacPassTests */ = {
isa = PBXGroup;
children = (
4C305F3F179A1A790082334F /* Images */,
4C18F9AC178E123200890BCE /* Databases */,
4C45FB2B178E0BCB0010007D /* MPDatabaseLoading.h */,
4C45FB2C178E0BCB0010007D /* MPDatabaseLoading.m */,
@@ -995,6 +1091,10 @@
4C19E501178E2871002F2CD0 /* MPDatabasePasswordAndKeyfile.h */,
4C19E502178E2871002F2CD0 /* MPDatabasePasswordAndKeyfile.m */,
4C45FB1F178E09ED0010007D /* Supporting Files */,
4C305F3A179A19F90082334F /* KPKIconLoading.h */,
4C305F3B179A19F90082334F /* KPKIconLoading.m */,
4C1842B6179B348600E2F5BC /* KPKTreeLoadingTest.h */,
4C1842B7179B348600E2F5BC /* KPKTreeLoadingTest.m */,
);
path = MacPassTests;
sourceTree = "<group>";
@@ -1253,6 +1353,7 @@
children = (
4CF6C715176F5183007A811D /* MPServerRequestHandler.h */,
4CA0B30D15BCB6FD00654E32 /* MPSettingsTab.h */,
4CDE28D0179C8E010036C771 /* MPDatabaseSettingsDelegate.h */,
);
name = Protocolls;
sourceTree = "<group>";
@@ -1316,6 +1417,10 @@
4CC3AAB9175F4983003EF01B /* HNHRoundedTextFieldCell.m */,
4C9D6AA717615199001C660C /* HNHRoundedSecureTextFieldCell.h */,
4C9D6AA817615199001C660C /* HNHRoundedSecureTextFieldCell.m */,
4C67D32E17981A2B00A7BDFC /* HNHTokenField.h */,
4C67D32F17981A2B00A7BDFC /* HNHTokenField.m */,
4C67D33117981ABA00A7BDFC /* HNHTokenFieldCell.h */,
4C67D33217981ABA00A7BDFC /* HNHTokenFieldCell.m */,
4C58BD4D176370B100B8178C /* HNHBadgedTextField.h */,
4C58BD4E176370B100B8178C /* HNHBadgedTextField.m */,
4CAF62FA1763604000CD7084 /* HNHBadgedTextFieldCell.h */,
@@ -1341,7 +1446,7 @@
4CD3ABAD178F71B50073F5C5 /* KeePassKit */ = {
isa = PBXGroup;
children = (
4C3F28591791F05400703281 /* Resources */,
4C1842D6179C716100E2F5BC /* Format */,
4CD3ABAF178F71B50073F5C5 /* Categories */,
4CD3ABB1178F71B50073F5C5 /* Core */,
4CD3ABB5178F71B50073F5C5 /* IO */,
@@ -1352,12 +1457,16 @@
4CD3ABAF178F71B50073F5C5 /* Categories */ = {
isa = PBXGroup;
children = (
4C1842BE179B5BFD00E2F5BC /* NSData+CommonCrypto.h */,
4C1842BF179B5BFD00E2F5BC /* NSData+CommonCrypto.m */,
4C2724D51778FF1A00FD8456 /* NSUUID+KeePassKit.h */,
4C2724D61778FF1A00FD8456 /* NSUUID+KeePassKit.m */,
4C8A173B1790AA41008B5C17 /* NSData+Keyfile.h */,
4C8A173C1790AA41008B5C17 /* NSData+Keyfile.m */,
4CDB5C401794AA4F0017667E /* KPKTree+Serializing.h */,
4CDB5C411794AA4F0017667E /* KPKTree+Serializing.m */,
4C055E72179620BF00BD2BAB /* NSString+CommandString.h */,
4C055E73179620BF00BD2BAB /* NSString+CommandString.m */,
4C1842C1179B69E600E2F5BC /* NSData+HashedData.h */,
4C1842C2179B69E700E2F5BC /* NSData+HashedData.m */,
);
path = Categories;
sourceTree = "<group>";
@@ -1367,11 +1476,6 @@
children = (
4C70D0FE179092F200652EE9 /* KPKPassword.h */,
4C70D0FF179092F200652EE9 /* KPKPassword.m */,
4C70D0FB1790924700652EE9 /* KPKParser.h */,
4C70D0FC1790924700652EE9 /* KPKParser.m */,
4C4436751792BE810099E220 /* KPKFormat.h */,
4C4436761792BE810099E220 /* KPKFormat.m */,
4CD3ABB2178F71B50073F5C5 /* KPKVersion.h */,
4CD3ABB3178F71B50073F5C5 /* KPKTree.h */,
4CD3ABB4178F71B50073F5C5 /* KPKTree.m */,
4CD3ABBD178F72610073F5C5 /* KPKEntry.h */,
@@ -1386,8 +1490,10 @@
4C3F28531791EDFD00703281 /* KPKErrors.m */,
4CF62B84179385D700B660B6 /* KPKAttribute.h */,
4CF62B85179385D700B660B6 /* KPKAttribute.m */,
4C5AA58F179549A1008ECAD7 /* KPKXmlTreeWriter.h */,
4C5AA590179549A1008ECAD7 /* KPKXmlTreeWriter.m */,
4C305F34179A0BD70082334F /* KPKIcon.h */,
4C305F35179A0BD70082334F /* KPKIcon.m */,
4C1842A9179B027700E2F5BC /* KPKDeletedNode.h */,
4C1842AA179B027800E2F5BC /* KPKDeletedNode.m */,
);
path = Core;
sourceTree = "<group>";
@@ -1395,6 +1501,28 @@
4CD3ABB5178F71B50073F5C5 /* IO */ = {
isa = PBXGroup;
children = (
4CDB5C401794AA4F0017667E /* KPKTree+Serializing.h */,
4CDB5C411794AA4F0017667E /* KPKTree+Serializing.m */,
4C5AA58F179549A1008ECAD7 /* KPKXmlTreeWriter.h */,
4C5AA590179549A1008ECAD7 /* KPKXmlTreeWriter.m */,
4C1842AD179B211C00E2F5BC /* KPKXmlTreeReader.h */,
4C1842AE179B211C00E2F5BC /* KPKXmlTreeReader.m */,
4C1842B0179B28C400E2F5BC /* KPKBinaryTreeReader.h */,
4C1842B1179B28C400E2F5BC /* KPKBinaryTreeReader.m */,
4C1842B3179B28D400E2F5BC /* KPKBinaryTreeWriter.h */,
4C1842B4179B28D400E2F5BC /* KPKBinaryTreeWriter.m */,
4C1842BA179B434C00E2F5BC /* KPKXmlHeaderReader.h */,
4C1842BB179B434C00E2F5BC /* KPKXmlHeaderReader.m */,
4C1842C4179BF51F00E2F5BC /* KPKLegacyHeaderReader.h */,
4C1842C5179BF52000E2F5BC /* KPKLegacyHeaderReader.m */,
4C1842C8179C616600E2F5BC /* KPKTreeCryptor.h */,
4C1842C9179C616700E2F5BC /* KPKTreeCryptor.m */,
4C1842CE179C64DC00E2F5BC /* KPKLegacyTreeCryptor.h */,
4C1842CF179C64DD00E2F5BC /* KPKLegacyTreeCryptor.m */,
4C1842D1179C64EF00E2F5BC /* KPKXmlTreeCryptor.h */,
4C1842D2179C64EF00E2F5BC /* KPKXmlTreeCryptor.m */,
4C1842D4179C6DE400E2F5BC /* KPKHeaderReading.h */,
4C1842D5179C6F1800E2F5BC /* KPKHeaderWriting.h */,
);
path = IO;
sourceTree = "<group>";
@@ -1541,6 +1669,7 @@
4C45FB23178E09ED0010007D /* InfoPlist.strings in Resources */,
4C18F9AB178E122500890BCE /* Test_Password_1234.kdb in Resources */,
4C19E500178E26EF002F2CD0 /* Test_Password_1234.kdbx in Resources */,
4C305F3E179A1A760082334F /* image.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1591,7 +1720,6 @@
4C52A88F1788628B00868229 /* 13_KeysTemplate.pdf in Resources */,
4C52A8901788628B00868229 /* 18_DisplayTemplate.pdf in Resources */,
4C52A892178863B000868229 /* 68_PhoneTemplate.pdf in Resources */,
4C3F28581791F04F00703281 /* LocalizableErrors.strings in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1621,6 +1749,8 @@
4C45FB2D178E0BCB0010007D /* MPDatabaseLoading.m in Sources */,
4C45FB30178E0CE20010007D /* MPDatabaseCreation.m in Sources */,
4C19E503178E2871002F2CD0 /* MPDatabasePasswordAndKeyfile.m in Sources */,
4C305F3C179A19F90082334F /* KPKIconLoading.m in Sources */,
4C1842B8179B348600E2F5BC /* KPKTreeLoadingTest.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1780,7 +1910,6 @@
4CD3ABC2178F72720073F5C5 /* KPKGroup.m in Sources */,
4C591B57178F897A0080B16B /* KPKAttachment.m in Sources */,
4C39B3F5178FEFAE0027DC7C /* KPKNode.m in Sources */,
4C70D0FD1790924700652EE9 /* KPKParser.m in Sources */,
4C70D100179092F200652EE9 /* KPKPassword.m in Sources */,
4C8A173D1790AA41008B5C17 /* NSData+Keyfile.m in Sources */,
4C3F28541791EDFD00703281 /* KPKErrors.m in Sources */,
@@ -1790,6 +1919,27 @@
4CDB5C421794AA4F0017667E /* KPKTree+Serializing.m in Sources */,
4C5AA591179549A1008ECAD7 /* KPKXmlTreeWriter.m in Sources */,
4CE298EB1795FC2A00DF7BDB /* MPEntryMenuDelegate.m in Sources */,
4C055E74179620BF00BD2BAB /* NSString+CommandString.m in Sources */,
4CC0D2CE17974A47000B4BDA /* MPCustomFieldTableViewDelegate.m in Sources */,
4CC0D2D117974A5A000B4BDA /* MPAttachmentTableViewDelegate.m in Sources */,
4C67D33017981A2B00A7BDFC /* HNHTokenField.m in Sources */,
4C67D33317981ABA00A7BDFC /* HNHTokenFieldCell.m in Sources */,
4C4510091798C53700219998 /* StringField+Validation.m in Sources */,
4C45100C1798C65C00219998 /* Kdb4Entry+MPAdditions.m in Sources */,
4CFEB36E1799D9CF00AF1868 /* Kdb3Entry+KVOAdditions.m in Sources */,
4C305F36179A0BD70082334F /* KPKIcon.m in Sources */,
4CA7C36C179A98140099C34B /* NSString+Base64.m in Sources */,
4C1842AB179B027800E2F5BC /* KPKDeletedNode.m in Sources */,
4C1842AF179B211C00E2F5BC /* KPKXmlTreeReader.m in Sources */,
4C1842B2179B28C400E2F5BC /* KPKBinaryTreeReader.m in Sources */,
4C1842B5179B28D400E2F5BC /* KPKBinaryTreeWriter.m in Sources */,
4C1842BC179B434C00E2F5BC /* KPKXmlHeaderReader.m in Sources */,
4C1842C0179B5BFD00E2F5BC /* NSData+CommonCrypto.m in Sources */,
4C1842C3179B69E700E2F5BC /* NSData+HashedData.m in Sources */,
4C1842C6179BF52100E2F5BC /* KPKLegacyHeaderReader.m in Sources */,
4C1842CA179C616700E2F5BC /* KPKTreeCryptor.m in Sources */,
4C1842D0179C64DD00E2F5BC /* KPKLegacyTreeCryptor.m in Sources */,
4C1842D3179C64F000E2F5BC /* KPKXmlTreeCryptor.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1808,8 +1958,8 @@
isa = PBXVariantGroup;
children = (
4C76155F1764C0590015A1A6 /* Base */,
4C7615721764C4A40015A1A6 /* de */,
4CA23357176DB8F000F0B6AC /* en */,
4CCA7EEC1797866F00B0B55E /* de */,
4CCA7EEE1797867200B0B55E /* en */,
);
name = GeneralSettings.xib;
sourceTree = "<group>";

File diff suppressed because it is too large Load Diff

View File

@@ -32,6 +32,8 @@
<string>NSTextField</string>
<string>NSTextFieldCell</string>
<string>NSTextView</string>
<string>NSTokenField</string>
<string>NSTokenFieldCell</string>
<string>NSView</string>
</array>
<array key="IBDocument.PluginDependencies">
@@ -133,65 +135,11 @@
<object class="NSCustomView" id="816254670">
<reference key="NSNextResponder" ref="87082330"/>
<int key="NSvFlags">268</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="NSButton" id="277685969">
<reference key="NSNextResponder" ref="816254670"/>
<int key="NSvFlags">-2147483380</int>
<string key="NSFrame">{{184, 5}, {45, 19}}</string>
<reference key="NSSuperview" ref="816254670"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="442762067"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="740692320">
<int key="NSCellFlags">-2080374784</int>
<int key="NSCellFlags2">134217728</int>
<string key="NSContents">Done</string>
<object class="NSFont" key="NSSupport" id="323604925">
<string key="NSName">LucidaGrande</string>
<double key="NSSize">12</double>
<int key="NSfFlags">16</int>
</object>
<string key="NSCellIdentifier">_NS:9</string>
<reference key="NSControlView" ref="277685969"/>
<int key="NSButtonFlags">-2038153216</int>
<int key="NSButtonFlags2">164</int>
<string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/>
<int key="NSPeriodicDelay">400</int>
<int key="NSPeriodicInterval">75</int>
</object>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
</object>
<object class="NSButton" id="442762067">
<reference key="NSNextResponder" ref="816254670"/>
<int key="NSvFlags">-2147483380</int>
<string key="NSFrame">{{237, 5}, {36, 19}}</string>
<reference key="NSSuperview" ref="816254670"/>
<reference key="NSWindow"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="669709526">
<int key="NSCellFlags">-2080374784</int>
<int key="NSCellFlags2">134217728</int>
<string key="NSContents">Edit</string>
<reference key="NSSupport" ref="323604925"/>
<string key="NSCellIdentifier">_NS:9</string>
<reference key="NSControlView" ref="442762067"/>
<int key="NSButtonFlags">-2038153216</int>
<int key="NSButtonFlags2">164</int>
<string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/>
<int key="NSPeriodicDelay">400</int>
<int key="NSPeriodicInterval">75</int>
</object>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
</object>
</array>
<array class="NSMutableArray" key="NSSubviews"/>
<string key="NSFrameSize">{293, 30}</string>
<reference key="NSSuperview" ref="87082330"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="277685969"/>
<reference key="NSNextKeyView"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<string key="NSClassName">HNHGradientView</string>
</object>
@@ -446,7 +394,7 @@
<string key="NSFrame">{{20, 152}, {253, 19}}</string>
<reference key="NSSuperview" ref="726109125"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="13391205"/>
<reference key="NSNextKeyView" ref="1027186598"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<string key="NSHuggingPriority">{250, 750}</string>
<bool key="NSEnabled">YES</bool>
@@ -454,7 +402,11 @@
<int key="NSCellFlags">-2080374784</int>
<int key="NSCellFlags2">134217728</int>
<string key="NSContents">Generate</string>
<reference key="NSSupport" ref="323604925"/>
<object class="NSFont" key="NSSupport" id="323604925">
<string key="NSName">LucidaGrande</string>
<double key="NSSize">12</double>
<int key="NSfFlags">16</int>
</object>
<string key="NSCellIdentifier">_NS:9</string>
<reference key="NSControlView" ref="172507372"/>
<int key="NSButtonFlags">-2038153216</int>
@@ -566,6 +518,54 @@
</object>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
</object>
<object class="NSTokenField" id="908063476">
<reference key="NSNextResponder" ref="726109125"/>
<int key="NSvFlags">268</int>
<set class="NSMutableSet" key="NSDragTypes">
<string>NSStringPboardType</string>
</set>
<string key="NSFrame">{{20, 73}, {253, 50}}</string>
<reference key="NSSuperview" ref="726109125"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="13391205"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="NSEnabled">YES</bool>
<object class="NSTokenFieldCell" key="NSCell" id="416219844">
<int key="NSCellFlags">337641472</int>
<int key="NSCellFlags2">32768</int>
<reference key="NSSupport" ref="323604925"/>
<string key="NSCellIdentifier">_NS:9</string>
<reference key="NSControlView" ref="908063476"/>
<reference key="NSBackgroundColor" ref="955209345"/>
<reference key="NSTextColor" ref="345368012"/>
<reference key="NSDelegate" ref="908063476"/>
<double key="NSCompletionDelay">0.0</double>
<int key="NSTokenStyle">0</int>
</object>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
<int key="NSTokenFieldVersion">2</int>
</object>
<object class="NSTextField" id="1027186598">
<reference key="NSNextResponder" ref="726109125"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{17, 131}, {38, 14}}</string>
<reference key="NSSuperview" ref="726109125"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="908063476"/>
<string key="NSReuseIdentifierKey">_NS:1535</string>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="391470272">
<int key="NSCellFlags">68157504</int>
<int key="NSCellFlags2">272761856</int>
<string key="NSContents">Tags</string>
<reference key="NSSupport" ref="26"/>
<string key="NSCellIdentifier">_NS:1535</string>
<reference key="NSControlView" ref="1027186598"/>
<reference key="NSBackgroundColor" ref="533509460"/>
<reference key="NSTextColor" ref="1062890562"/>
</object>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
</object>
</array>
<string key="NSFrameSize">{293, 399}</string>
<reference key="NSSuperview" ref="166081160"/>
@@ -596,7 +596,7 @@
<int key="NSvFlags">2322</int>
<string key="NSFrameSize">{251, 332}</string>
<reference key="NSSuperview" ref="454120122"/>
<reference key="NSNextKeyView" ref="942541726"/>
<reference key="NSNextKeyView" ref="657519150"/>
<string key="NSReuseIdentifierKey">_NS:13</string>
<object class="NSTextContainer" key="NSTextContainer" id="77792568">
<object class="NSLayoutManager" key="NSLayoutManager">
@@ -688,7 +688,6 @@
<int key="NSvFlags">256</int>
<string key="NSFrame">{{236, 1}, {16, 332}}</string>
<reference key="NSSuperview" ref="850153963"/>
<reference key="NSNextKeyView" ref="894571713"/>
<string key="NSReuseIdentifierKey">_NS:83</string>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
<reference key="NSTarget" ref="850153963"/>
@@ -713,7 +712,7 @@
</array>
<string key="NSFrame">{{20, 20}, {253, 334}}</string>
<reference key="NSSuperview" ref="13134025"/>
<reference key="NSNextKeyView" ref="657519150"/>
<reference key="NSNextKeyView" ref="454120122"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<int key="NSsFlags">133138</int>
<reference key="NSVScroller" ref="942541726"/>
@@ -926,7 +925,6 @@
<int key="NSvFlags">-2147483392</int>
<string key="NSFrame">{{1, 147}, {52, 16}}</string>
<reference key="NSSuperview" ref="994354248"/>
<reference key="NSNextKeyView" ref="894571713"/>
<string key="NSReuseIdentifierKey">_NS:60</string>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
<int key="NSsFlags">1</int>
@@ -1105,7 +1103,6 @@
<int key="NSvFlags">-2147483392</int>
<string key="NSFrame">{{1, 119}, {223, 15}}</string>
<reference key="NSSuperview" ref="892620201"/>
<reference key="NSNextKeyView" ref="894571713"/>
<string key="NSReuseIdentifierKey">_NS:60</string>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
<int key="NSsFlags">1</int>
@@ -1463,7 +1460,7 @@
<int key="NSvFlags">268</int>
<string key="NSFrame">{{223, 11}, {32, 19}}</string>
<reference key="NSSuperview" ref="291769955"/>
<reference key="NSNextKeyView" ref="101606984"/>
<reference key="NSNextKeyView" ref="511009648"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="26197670">
@@ -1653,6 +1650,72 @@
</object>
<int key="connectionID">2260</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">valueTextField</string>
<object class="NSTableCellView" key="source" id="511009648">
<nil key="NSNextResponder"/>
<int key="NSvFlags">274</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="NSTextField" id="781002733">
<reference key="NSNextResponder" ref="511009648"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{3, 10}, {250, 22}}</string>
<reference key="NSSuperview" ref="511009648"/>
<reference key="NSNextKeyView" ref="101606984"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="991080261">
<int key="NSCellFlags">-1805647871</int>
<int key="NSCellFlags2">272629760</int>
<string key="NSContents"/>
<reference key="NSSupport" ref="308723166"/>
<string key="NSPlaceholderString">Value</string>
<string key="NSCellIdentifier">_NS:9</string>
<reference key="NSControlView" ref="781002733"/>
<bool key="NSDrawsBackground">YES</bool>
<reference key="NSBackgroundColor" ref="955209345"/>
<reference key="NSTextColor" ref="412903852"/>
</object>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
</object>
<object class="NSTextField" id="632623009">
<reference key="NSNextResponder" ref="511009648"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{0, 40}, {258, 14}}</string>
<reference key="NSSuperview" ref="511009648"/>
<reference key="NSNextKeyView" ref="781002733"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="304318757">
<int key="NSCellFlags">-1808793535</int>
<int key="NSCellFlags2">272761856</int>
<string key="NSContents"/>
<reference key="NSSupport" ref="26"/>
<string key="NSPlaceholderString">Title</string>
<string key="NSCellIdentifier">_NS:9</string>
<reference key="NSControlView" ref="632623009"/>
<reference key="NSBackgroundColor" ref="955209345"/>
<reference key="NSTextColor" ref="1062890562"/>
</object>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
</object>
</array>
<string key="NSFrame">{{1, 57}, {256, 54}}</string>
<reference key="NSNextKeyView" ref="632623009"/>
</object>
<reference key="destination" ref="781002733"/>
</object>
<int key="connectionID">2365</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">labelTextField</string>
<reference key="source" ref="511009648"/>
<reference key="destination" ref="632623009"/>
</object>
<int key="connectionID">2366</int>
</object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
@@ -2003,70 +2066,6 @@
<int key="objectID">662</int>
<reference key="object" ref="816254670"/>
<array class="NSMutableArray" key="children">
<object class="IBNSLayoutConstraint" id="34368549">
<reference key="firstItem" ref="442762067"/>
<int key="firstAttribute">5</int>
<int key="relation">0</int>
<reference key="secondItem" ref="277685969"/>
<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="816254670"/>
<int key="scoringType">6</int>
<float key="scoringTypeFloat">24</float>
<int key="contentType">3</int>
</object>
<object class="IBNSLayoutConstraint" id="752675649">
<reference key="firstItem" ref="816254670"/>
<int key="firstAttribute">6</int>
<int key="relation">0</int>
<reference key="secondItem" ref="442762067"/>
<int key="secondAttribute">6</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="816254670"/>
<int key="scoringType">8</int>
<float key="scoringTypeFloat">29</float>
<int key="contentType">3</int>
</object>
<object class="IBNSLayoutConstraint" id="824671915">
<reference key="firstItem" ref="277685969"/>
<int key="firstAttribute">11</int>
<int key="relation">0</int>
<reference key="secondItem" ref="442762067"/>
<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="816254670"/>
<int key="scoringType">6</int>
<float key="scoringTypeFloat">24</float>
<int key="contentType">2</int>
</object>
<object class="IBNSLayoutConstraint" id="1053370990">
<reference key="firstItem" ref="277685969"/>
<int key="firstAttribute">10</int>
<int key="relation">0</int>
<reference key="secondItem" ref="816254670"/>
<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="816254670"/>
<int key="scoringType">5</int>
<float key="scoringTypeFloat">22</float>
<int key="contentType">2</int>
</object>
<object class="IBNSLayoutConstraint" id="574545128">
<reference key="firstItem" ref="816254670"/>
<int key="firstAttribute">8</int>
@@ -2083,8 +2082,6 @@
<float key="scoringTypeFloat">40</float>
<int key="contentType">1</int>
</object>
<reference ref="442762067"/>
<reference ref="277685969"/>
</array>
<reference key="parent" ref="87082330"/>
</object>
@@ -2335,7 +2332,7 @@
<reference key="firstItem" ref="13391205"/>
<int key="firstAttribute">3</int>
<int key="relation">1</int>
<reference key="secondItem" ref="172507372"/>
<reference key="secondItem" ref="908063476"/>
<int key="secondAttribute">4</int>
<float key="multiplier">1</float>
<object class="IBNSLayoutSymbolicConstant" key="constant">
@@ -2411,6 +2408,86 @@
<float key="scoringTypeFloat">29</float>
<int key="contentType">3</int>
</object>
<object class="IBNSLayoutConstraint" id="1016066557">
<reference key="firstItem" ref="908063476"/>
<int key="firstAttribute">3</int>
<int key="relation">0</int>
<reference key="secondItem" ref="1027186598"/>
<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="726109125"/>
<int key="scoringType">6</int>
<float key="scoringTypeFloat">24</float>
<int key="contentType">3</int>
</object>
<object class="IBNSLayoutConstraint" id="565410329">
<reference key="firstItem" ref="908063476"/>
<int key="firstAttribute">5</int>
<int key="relation">0</int>
<reference key="secondItem" ref="726109125"/>
<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="726109125"/>
<int key="scoringType">8</int>
<float key="scoringTypeFloat">29</float>
<int key="contentType">3</int>
</object>
<object class="IBNSLayoutConstraint" id="20584493">
<reference key="firstItem" ref="726109125"/>
<int key="firstAttribute">6</int>
<int key="relation">0</int>
<reference key="secondItem" ref="908063476"/>
<int key="secondAttribute">6</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="726109125"/>
<int key="scoringType">8</int>
<float key="scoringTypeFloat">29</float>
<int key="contentType">3</int>
</object>
<object class="IBNSLayoutConstraint" id="833644028">
<reference key="firstItem" ref="1027186598"/>
<int key="firstAttribute">3</int>
<int key="relation">0</int>
<reference key="secondItem" ref="172507372"/>
<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="726109125"/>
<int key="scoringType">6</int>
<float key="scoringTypeFloat">24</float>
<int key="contentType">3</int>
</object>
<object class="IBNSLayoutConstraint" id="517799648">
<reference key="firstItem" ref="1027186598"/>
<int key="firstAttribute">5</int>
<int key="relation">0</int>
<reference key="secondItem" ref="726109125"/>
<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="726109125"/>
<int key="scoringType">8</int>
<float key="scoringTypeFloat">29</float>
<int key="contentType">3</int>
</object>
<object class="IBNSLayoutConstraint" id="319543535">
<reference key="firstItem" ref="172507372"/>
<int key="firstAttribute">3</int>
@@ -2807,6 +2884,8 @@
<reference ref="212627618"/>
<reference ref="1035439471"/>
<reference ref="685310174"/>
<reference ref="1027186598"/>
<reference ref="908063476"/>
</array>
<reference key="parent" ref="1002013291"/>
</object>
@@ -3841,6 +3920,7 @@
<array class="NSMutableArray" key="children">
<reference ref="559416629"/>
<reference ref="291769955"/>
<reference ref="511009648"/>
</array>
<reference key="parent" ref="441697535"/>
</object>
@@ -4680,56 +4760,348 @@
<reference key="parent" ref="726109125"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2313</int>
<reference key="object" ref="442762067"/>
<int key="objectID">2345</int>
<reference key="object" ref="511009648"/>
<array class="NSMutableArray" key="children">
<reference ref="669709526"/>
<reference ref="781002733"/>
<reference ref="632623009"/>
<object class="IBNSLayoutConstraint" id="346165127">
<reference key="firstItem" ref="511009648"/>
<int key="firstAttribute">6</int>
<int key="relation">0</int>
<reference key="secondItem" ref="781002733"/>
<int key="secondAttribute">6</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">3</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="511009648"/>
<int key="scoringType">8</int>
<float key="scoringTypeFloat">29</float>
<int key="contentType">3</int>
</object>
<object class="IBNSLayoutConstraint" id="590616446">
<reference key="firstItem" ref="511009648"/>
<int key="firstAttribute">4</int>
<int key="relation">0</int>
<reference key="secondItem" ref="781002733"/>
<int key="secondAttribute">4</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">10</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="511009648"/>
<int key="scoringType">9</int>
<float key="scoringTypeFloat">40</float>
<int key="contentType">3</int>
</object>
<object class="IBNSLayoutConstraint" id="179229956">
<reference key="firstItem" ref="781002733"/>
<int key="firstAttribute">3</int>
<int key="relation">0</int>
<reference key="secondItem" ref="632623009"/>
<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="511009648"/>
<int key="scoringType">9</int>
<float key="scoringTypeFloat">40</float>
<int key="contentType">3</int>
</object>
<object class="IBNSLayoutConstraint" id="302253341">
<reference key="firstItem" ref="781002733"/>
<int key="firstAttribute">5</int>
<int key="relation">0</int>
<reference key="secondItem" ref="511009648"/>
<int key="secondAttribute">5</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">3</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="511009648"/>
<int key="scoringType">9</int>
<float key="scoringTypeFloat">40</float>
<int key="contentType">3</int>
</object>
<object class="IBNSLayoutConstraint" id="901474527">
<reference key="firstItem" ref="632623009"/>
<int key="firstAttribute">3</int>
<int key="relation">0</int>
<reference key="secondItem" ref="511009648"/>
<int key="secondAttribute">3</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="511009648"/>
<int key="scoringType">9</int>
<float key="scoringTypeFloat">40</float>
<int key="contentType">3</int>
</object>
<object class="IBNSLayoutConstraint" id="283957064">
<reference key="firstItem" ref="632623009"/>
<int key="firstAttribute">5</int>
<int key="relation">0</int>
<reference key="secondItem" ref="511009648"/>
<int key="secondAttribute">5</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">3</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="511009648"/>
<int key="scoringType">8</int>
<float key="scoringTypeFloat">29</float>
<int key="contentType">3</int>
</object>
</array>
<reference key="parent" ref="816254670"/>
<reference key="parent" ref="330991171"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2314</int>
<reference key="object" ref="669709526"/>
<reference key="parent" ref="442762067"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2315</int>
<reference key="object" ref="752675649"/>
<reference key="parent" ref="816254670"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2317</int>
<reference key="object" ref="277685969"/>
<int key="objectID">2347</int>
<reference key="object" ref="781002733"/>
<array class="NSMutableArray" key="children">
<reference ref="740692320"/>
<object class="IBNSLayoutConstraint" id="796932488">
<reference key="firstItem" ref="781002733"/>
<int key="firstAttribute">7</int>
<int key="relation">1</int>
<nil key="secondItem"/>
<int key="secondAttribute">0</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">80</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="781002733"/>
<int key="scoringType">9</int>
<float key="scoringTypeFloat">40</float>
<int key="contentType">1</int>
</object>
<object class="IBNSLayoutConstraint" id="893684750">
<reference key="firstItem" ref="781002733"/>
<int key="firstAttribute">8</int>
<int key="relation">1</int>
<nil key="secondItem"/>
<int key="secondAttribute">0</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">22</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="781002733"/>
<int key="scoringType">9</int>
<float key="scoringTypeFloat">40</float>
<int key="contentType">1</int>
</object>
<reference ref="991080261"/>
</array>
<reference key="parent" ref="816254670"/>
<reference key="parent" ref="511009648"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2318</int>
<reference key="object" ref="740692320"/>
<reference key="parent" ref="277685969"/>
<int key="objectID">2348</int>
<reference key="object" ref="632623009"/>
<array class="NSMutableArray" key="children">
<object class="IBNSLayoutConstraint" id="680263316">
<reference key="firstItem" ref="632623009"/>
<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">252</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="632623009"/>
<int key="scoringType">3</int>
<float key="scoringTypeFloat">9</float>
<int key="contentType">1</int>
</object>
<object class="IBNSLayoutConstraint" id="867937555">
<reference key="firstItem" ref="632623009"/>
<int key="firstAttribute">8</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">14</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="632623009"/>
<int key="scoringType">9</int>
<float key="scoringTypeFloat">40</float>
<int key="contentType">1</int>
</object>
<reference ref="304318757"/>
</array>
<reference key="parent" ref="511009648"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2319</int>
<reference key="object" ref="34368549"/>
<reference key="parent" ref="816254670"/>
<int key="objectID">2349</int>
<reference key="object" ref="283957064"/>
<reference key="parent" ref="511009648"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2320</int>
<reference key="object" ref="1053370990"/>
<reference key="parent" ref="816254670"/>
<int key="objectID">2351</int>
<reference key="object" ref="901474527"/>
<reference key="parent" ref="511009648"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2321</int>
<reference key="object" ref="824671915"/>
<reference key="parent" ref="816254670"/>
<int key="objectID">2352</int>
<reference key="object" ref="302253341"/>
<reference key="parent" ref="511009648"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2322</int>
<int key="objectID">2353</int>
<reference key="object" ref="179229956"/>
<reference key="parent" ref="511009648"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2354</int>
<reference key="object" ref="590616446"/>
<reference key="parent" ref="511009648"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2358</int>
<reference key="object" ref="867937555"/>
<reference key="parent" ref="632623009"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2359</int>
<reference key="object" ref="304318757"/>
<reference key="parent" ref="632623009"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2360</int>
<reference key="object" ref="893684750"/>
<reference key="parent" ref="781002733"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2361</int>
<reference key="object" ref="796932488"/>
<reference key="parent" ref="781002733"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2362</int>
<reference key="object" ref="991080261"/>
<reference key="parent" ref="781002733"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2369</int>
<reference key="object" ref="680263316"/>
<reference key="parent" ref="632623009"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2370</int>
<reference key="object" ref="346165127"/>
<reference key="parent" ref="511009648"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2371</int>
<reference key="object" ref="908063476"/>
<array class="NSMutableArray" key="children">
<reference ref="416219844"/>
<object class="IBNSLayoutConstraint" id="462547709">
<reference key="firstItem" ref="908063476"/>
<int key="firstAttribute">8</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">50</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="908063476"/>
<int key="scoringType">3</int>
<float key="scoringTypeFloat">9</float>
<int key="contentType">1</int>
</object>
</array>
<reference key="parent" ref="726109125"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2372</int>
<reference key="object" ref="416219844"/>
<reference key="parent" ref="908063476"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2380</int>
<reference key="object" ref="775474818"/>
<reference key="parent" ref="726109125"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2384</int>
<reference key="object" ref="1027186598"/>
<array class="NSMutableArray" key="children">
<reference ref="391470272"/>
<object class="IBNSLayoutConstraint" id="707273412">
<reference key="firstItem" ref="1027186598"/>
<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">32</double>
</object>
<float key="priority">1000</float>
<reference key="containingView" ref="1027186598"/>
<int key="scoringType">3</int>
<float key="scoringTypeFloat">9</float>
<int key="contentType">1</int>
</object>
</array>
<reference key="parent" ref="726109125"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2385</int>
<reference key="object" ref="391470272"/>
<reference key="parent" ref="1027186598"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2388</int>
<reference key="object" ref="20584493"/>
<reference key="parent" ref="726109125"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2389</int>
<reference key="object" ref="565410329"/>
<reference key="parent" ref="726109125"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2391</int>
<reference key="object" ref="707273412"/>
<reference key="parent" ref="1027186598"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2397</int>
<reference key="object" ref="517799648"/>
<reference key="parent" ref="726109125"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2398</int>
<reference key="object" ref="833644028"/>
<reference key="parent" ref="726109125"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2400</int>
<reference key="object" ref="1016066557"/>
<reference key="parent" ref="726109125"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2401</int>
<reference key="object" ref="462547709"/>
<reference key="parent" ref="908063476"/>
</object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
@@ -4786,7 +5158,7 @@
<reference ref="171913043"/>
</array>
<string key="1396.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<array key="1397.IBNSViewMetadataConstraints">
<array class="NSMutableArray" key="1397.IBNSViewMetadataConstraints">
<reference ref="866470549"/>
<reference ref="496215318"/>
<reference ref="644631459"/>
@@ -4811,6 +5183,11 @@
<reference ref="806657697"/>
<reference ref="404436173"/>
<reference ref="319543535"/>
<reference ref="517799648"/>
<reference ref="833644028"/>
<reference ref="20584493"/>
<reference ref="565410329"/>
<reference ref="1016066557"/>
<reference ref="1048935945"/>
<reference ref="849686715"/>
<reference ref="989194529"/>
@@ -4975,6 +5352,7 @@
<boolean value="YES" key="2014.isInViewBasedMode"/>
<array key="2014.prototypeCellViews">
<reference ref="291769955"/>
<reference ref="511009648"/>
</array>
<string key="2017.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2020.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -4994,6 +5372,7 @@
<reference ref="243564120"/>
</array>
<string key="2024.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2024.userInterfaceItemIdentifier">SelectedCell</string>
<array key="2042.IBNSViewMetadataConstraints">
<reference ref="788011316"/>
<reference ref="268050676"/>
@@ -5107,17 +5486,62 @@
<string key="2275.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2276.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2278.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="NO" key="2313.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
<string key="2313.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2314.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2315.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="NO" key="2317.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
<string key="2317.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2318.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2319.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2320.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2321.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2322.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2345.CustomClassName">MPCustomFieldTableCellView</string>
<array key="2345.IBNSViewMetadataConstraints">
<reference ref="283957064"/>
<reference ref="901474527"/>
<reference ref="302253341"/>
<reference ref="179229956"/>
<reference ref="590616446"/>
<reference ref="346165127"/>
</array>
<string key="2345.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2345.userInterfaceItemIdentifier">NormalCell</string>
<array class="NSMutableArray" key="2347.IBNSViewMetadataConstraints">
<reference ref="893684750"/>
<reference ref="796932488"/>
</array>
<boolean value="NO" key="2347.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
<string key="2347.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<array key="2348.IBNSViewMetadataConstraints">
<reference ref="867937555"/>
<reference ref="680263316"/>
</array>
<boolean value="NO" key="2348.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
<string key="2348.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2349.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2351.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2352.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2353.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2354.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2358.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2359.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2360.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2361.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2362.CustomClassName">HNHRoundedTextFieldCell</string>
<string key="2362.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2369.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2370.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<array class="NSMutableArray" key="2371.IBNSViewMetadataConstraints">
<reference ref="462547709"/>
</array>
<boolean value="NO" key="2371.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
<string key="2371.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2372.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2380.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<array key="2384.IBNSViewMetadataConstraints">
<reference ref="707273412"/>
</array>
<boolean value="NO" key="2384.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
<string key="2384.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2385.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2388.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2389.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2391.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2397.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2398.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2400.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="2401.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<array key="455.IBNSViewMetadataConstraints">
<reference ref="222939184"/>
<reference ref="1058743908"/>
@@ -5152,10 +5576,6 @@
<string key="651.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<array class="NSMutableArray" key="662.IBNSViewMetadataConstraints">
<reference ref="574545128"/>
<reference ref="1053370990"/>
<reference ref="824671915"/>
<reference ref="752675649"/>
<reference ref="34368549"/>
</array>
<boolean value="NO" key="662.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
<string key="662.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -5168,7 +5588,7 @@
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">2322</int>
<int key="maxID">2401</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">

View File

@@ -235,6 +235,15 @@
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
<object class="NSMenuItem" id="919874146">
<reference key="NSMenu" ref="720053764"/>
<string key="NSTitle">Lock</string>
<string key="NSKeyEquiv">L</string>
<int key="NSKeyEquivModMask">262144</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
<object class="NSMenuItem" id="776162233">
<reference key="NSMenu" ref="720053764"/>
<string key="NSTitle">Close</string>
@@ -828,6 +837,14 @@
</object>
<int key="connectionID">1260</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">lock:</string>
<reference key="source" ref="1014"/>
<reference key="destination" ref="919874146"/>
</object>
<int key="connectionID">1263</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">showPreferences:</string>
@@ -932,6 +949,7 @@
<reference ref="544639599"/>
<reference ref="663106531"/>
<reference ref="438377242"/>
<reference ref="919874146"/>
</array>
<reference key="parent" ref="379814623"/>
</object>
@@ -1272,6 +1290,11 @@
<reference key="object" ref="438377242"/>
<reference key="parent" ref="720053764"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">1261</int>
<reference key="object" ref="919874146"/>
<reference key="parent" ref="720053764"/>
</object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
@@ -1291,6 +1314,7 @@
<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="1261.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="131.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -1346,7 +1370,7 @@
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">1260</int>
<int key="maxID">1263</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -1407,6 +1431,7 @@
<dictionary class="NSMutableDictionary" key="actions">
<string key="editPassword:">id</string>
<string key="exportDatabase:">id</string>
<string key="lock:">id</string>
<string key="showDatabaseSettings:">id</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="actionInfosByName">
@@ -1418,6 +1443,10 @@
<string key="name">exportDatabase:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo" key="lock:">
<string key="name">lock:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo" key="showDatabaseSettings:">
<string key="name">showDatabaseSettings:</string>
<string key="candidateClassName">id</string>

View File

@@ -286,7 +286,7 @@
<object class="NSButton" id="769513826">
<reference key="NSNextResponder" ref="1005"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{281, 65}, {83, 32}}</string>
<string key="NSFrame">{{320, 65}, {83, 32}}</string>
<reference key="NSSuperview" ref="1005"/>
<reference key="NSWindow"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
@@ -526,6 +526,22 @@
<float key="scoringTypeFloat">24</float>
<int key="contentType">2</int>
</object>
<object class="IBNSLayoutConstraint" id="875982455">
<reference key="firstItem" ref="769513826"/>
<int key="firstAttribute">6</int>
<int key="relation">0</int>
<reference key="secondItem" ref="594061862"/>
<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="1005"/>
<int key="scoringType">6</int>
<float key="scoringTypeFloat">24</float>
<int key="contentType">2</int>
</object>
<object class="IBNSLayoutConstraint" id="641552480">
<reference key="firstItem" ref="769513826"/>
<int key="firstAttribute">3</int>
@@ -542,22 +558,6 @@
<float key="scoringTypeFloat">24</float>
<int key="contentType">3</int>
</object>
<object class="IBNSLayoutConstraint" id="875982455">
<reference key="firstItem" ref="769513826"/>
<int key="firstAttribute">6</int>
<int key="relation">0</int>
<reference key="secondItem" ref="1034097047"/>
<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="1005"/>
<int key="scoringType">6</int>
<float key="scoringTypeFloat">24</float>
<int key="contentType">2</int>
</object>
<object class="IBNSLayoutConstraint" id="1001566026">
<reference key="firstItem" ref="1005"/>
<int key="firstAttribute">4</int>
@@ -804,9 +804,9 @@
<reference ref="1034097047"/>
<reference ref="333885704"/>
<reference ref="662046682"/>
<reference ref="769513826"/>
<reference ref="594061862"/>
<reference ref="660673733"/>
<reference ref="769513826"/>
</array>
<reference key="parent" ref="0"/>
</object>
@@ -1027,11 +1027,6 @@
<reference key="object" ref="72235716"/>
<reference key="parent" ref="1005"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">465</int>
<reference key="object" ref="875982455"/>
<reference key="parent" ref="1005"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">286</int>
<reference key="object" ref="912203343"/>
@@ -1105,13 +1100,18 @@
<reference key="object" ref="1041224580"/>
<reference key="parent" ref="1005"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">496</int>
<reference key="object" ref="875982455"/>
<reference key="parent" ref="1005"/>
</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>
<array key="1.IBNSViewMetadataConstraints">
<array class="NSMutableArray" key="1.IBNSViewMetadataConstraints">
<reference ref="781301592"/>
<reference ref="335819100"/>
<reference ref="915913759"/>
@@ -1127,8 +1127,8 @@
<reference ref="273022298"/>
<reference ref="912203343"/>
<reference ref="1001566026"/>
<reference ref="875982455"/>
<reference ref="641552480"/>
<reference ref="875982455"/>
<reference ref="466444110"/>
<reference ref="72235716"/>
<reference ref="1041224580"/>
@@ -1187,7 +1187,6 @@
<string key="456.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="459.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="462.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="465.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="476.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="478.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="479.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -1200,12 +1199,13 @@
<string key="489.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="490.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="492.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="496.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">495</int>
<int key="maxID">497</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">

File diff suppressed because it is too large Load Diff

View File

@@ -50,8 +50,9 @@
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
</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="NSFrameAutosaveName">DatabaseWindow</string>
<bool key="NSWindowIsRestorable">YES</bool>
</object>
<object class="NSSplitView" id="903506498">
@@ -64,6 +65,7 @@
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="NSIsVertical">YES</bool>
<int key="NSDividerStyle">2</int>
<string key="NSAutosaveName"/>
</object>
</array>
<object class="IBObjectContainer" key="IBDocument.Objects">
@@ -159,6 +161,7 @@
<string key="superclassName">NSWindowController</string>
<dictionary class="NSMutableDictionary" key="actions">
<string key="editPassword:">id</string>
<string key="exportDatabase:">id</string>
<string key="showDatabaseSettings:">id</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="actionInfosByName">
@@ -166,6 +169,10 @@
<string key="name">editPassword:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo" key="exportDatabase:">
<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>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,18 @@
//
// Kdb3Entry+KVOAdditions.h
// MacPass
//
// Created by Michael Starke on 19.07.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import "Kdb3Node.h"
@interface Kdb3Entry (KVOAdditions)
- (NSUInteger)countOfBinaries;
- (id)objectInBinariesAtIndex:(NSUInteger)index;
- (void)removeObjectFromBinariesAtIndex:(NSUInteger)index;
- (void)insertObject:(id)binary inBinariesAtIndex:(NSUInteger)index;
@end

View File

@@ -0,0 +1,31 @@
//
// Kdb3Entry+KVOAdditions.m
// MacPass
//
// Created by Michael Starke on 19.07.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import "Kdb3Entry+KVOAdditions.h"
@implementation Kdb3Entry (KVOAdditions)
- (NSUInteger)countOfBinaries {
return (self.binary != nil ? 1 : 0);
}
- (id)objectInBinariesAtIndex:(NSUInteger)index {
return self.binary;
}
- (void)removeObjectFromBinariesAtIndex:(NSUInteger)index {
if(self.binary ) {
self.binary = nil;
self.binaryDesc = nil;
}
}
- (void)insertObject:(id)binary inBinariesAtIndex:(NSUInteger)index {
return;//
}
@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

@@ -20,4 +20,6 @@
/* Returns the group with the UUID */
- (KdbGroup *)groupForUUID:(UUID *)uuid;
- (BOOL)isAnchestorOfGroup:(KdbGroup *)group;
@end

View File

@@ -49,4 +49,18 @@
return [filteredGroups lastObject];
}
- (BOOL)isAnchestorOfGroup:(KdbGroup *)group {
if(group == nil) {
return NO;
}
KdbGroup *ancestor = self.parent;
while(ancestor.parent) {
if(group == self) {
return YES;
}
ancestor = ancestor.parent;
}
return NO;
}
@end

View File

@@ -9,9 +9,9 @@
#import <Foundation/Foundation.h>
typedef NS_ENUM(NSUInteger, MPActionType) {
MPUnkownAction, // Netural element to be used for returns
MPActionAddEntry, // Add an new entry
MPActionAddGroup, // Add a new group
MPActionEdit, // Edit entry or group
MPActionDelete, // Delete entry or group
MPActionCopyUsername, // copy username to pasteboard
MPActionCopyPassword, // copy password to pasteboard
@@ -25,5 +25,6 @@ typedef NS_ENUM(NSUInteger, MPActionType) {
@interface MPActionHelper : NSObject
+ (SEL)actionOfType:(MPActionType)type;
+ (MPActionType)typeForAction:(SEL)action;
@end

View File

@@ -10,25 +10,42 @@
@implementation MPActionHelper
+ (SEL)actionOfType:(MPActionType)type {
+ (NSDictionary *)_actionDictionary {
static NSDictionary *actionDict;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
actionDict = @{
@(MPActionAddEntry) : @"createEntry:",
@(MPActionAddGroup) : @"createGroup:",
@(MPActionCopyPassword) : @"copyPassword:",
@(MPActionCopyURL) : @"copyURL:",
@(MPActionCopyUsername) : @"copyUsername:",
@(MPActionDelete) : @"deleteNode:",
@(MPActionEdit) : @"editEntry:",
@(MPActionOpenURL) : @"openURL:",
@(MPActionToggleInspector) : @"toggleInspector:",
@(MPActionLock) : @"lock:",
@(MPActionEmptyTrash) : @"emptyTrash:"
};
@(MPActionAddEntry) : @"createEntry:",
@(MPActionAddGroup) : @"createGroup:",
@(MPActionCopyPassword) : @"copyPassword:",
@(MPActionCopyURL) : @"copyURL:",
@(MPActionCopyUsername) : @"copyUsername:",
@(MPActionDelete) : @"deleteNode:",
@(MPActionOpenURL) : @"openURL:",
@(MPActionToggleInspector) : @"toggleInspector:",
@(MPActionLock) : @"lock:",
@(MPActionEmptyTrash) : @"emptyTrash:"
};
});
return actionDict;
}
+ (SEL)actionOfType:(MPActionType)type {
NSDictionary *actionDict = [self _actionDictionary];
return NSSelectorFromString(actionDict[@(type)]);
}
+ (MPActionType)typeForAction:(SEL)action {
NSString *selectorString = NSStringFromSelector(action);
NSArray *selectors = [[self _actionDictionary] allValues];
NSUInteger index = [selectors indexOfObject:selectorString];
if(index == NSNotFound) {
return MPUnkownAction;
}
NSArray *keys = [[self _actionDictionary] allKeysForObject:selectorString];
NSAssert([keys count] == 1, @"There should only be one object for the specified key");
return [[keys lastObject] integerValue];
}
@end

View File

@@ -38,16 +38,31 @@
[MPStringLengthValueTransformer registerTransformer];
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender {
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 {
serverDaemon = [[MPServerDaemon alloc] init];
lockDaemon = [[MPLockDaemon alloc] init];
}
- (NSString *)applicationName {
return [[NSBundle mainBundle] infoDictionary][@"CFBundleName"];
}
@@ -93,4 +108,26 @@
}
}
- (void)_applicationDidFinishRestoringWindows:(NSNotification *)notification {
NSDocumentController *documentController = [NSDocumentController sharedDocumentController];
NSArray *documents = [documentController documents];
NSArray *recentDocuments = [documentController recentDocumentURLs];
if([documents count] > 0 ) {
return; // There's already a document restored
}
NSURL *documentUrl;
if([recentDocuments count] > 0) {
documentUrl = recentDocuments[0];
}
else {
NSString *lastPath = [[NSUserDefaults standardUserDefaults] stringForKey:kMPSettingsKeyLastDatabasePath];
documentUrl = [NSURL URLWithString:lastPath];
}
if([documentUrl isFileURL]) {
[documentController openDocumentWithContentsOfURL:documentUrl display:YES
completionHandler:^(NSDocument *document, BOOL documentWasAlreadyOpen, NSError *error) {}];
}
}
@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,75 @@
//
// 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 "Kdb3Node.h"
#import "HNHTableRowView.h"
@implementation MPAttachmentTableViewDelegate
- (void)tableViewSelectionDidChange:(NSNotification *)notification {
NSTableView *tableView = [notification object];
NSIndexSet *allColumns = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [[tableView tableColumns] count])];
if([self.viewController.selectedEntry isKindOfClass:[Kdb4Entry class]]) {
Kdb4Entry *entryv4 = (Kdb4Entry *)self.viewController.selectedEntry;
NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [entryv4.binaries count] )];
[tableView reloadDataForRowIndexes:indexSet columnIndexes:allColumns];
}
if([self.viewController.selectedEntry isKindOfClass:[Kdb3Entry class]]) {
Kdb3Entry *entryv3 = (Kdb3Entry *)self.viewController.selectedEntry;
NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, (entryv3.binary ? 1 : 0 ))];
[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 {
Kdb3Entry *entry= (Kdb3Entry *)self.viewController.selectedEntry;
[[view textField] bind:NSValueBinding toObject:entry withKeyPath:@"binaryDesc" options:nil];
[[view imageView] setImage:[[NSWorkspace sharedWorkspace] iconForFileType:[entry.binaryDesc pathExtension]]];
}
return view;
}
- (NSTableRowView *)tableView:(NSTableView *)tableView rowViewForRow:(NSInteger)row {
HNHTableRowView *view = nil;
view = [[HNHTableRowView alloc] init];
view.selectionCornerRadius = 7;
return view;
}
@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

@@ -0,0 +1,17 @@
//
// MPDatabaseSettingsDelegate.h
// MacPass
//
// Created by Michael Starke on 21.07.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import <Foundation/Foundation.h>
@protocol MPDatabaseSettingsDelegate <NSObject>
@optional
- (void)didCancelDatabaseSettings;
- (void)didSaveDatabaseSettings;
@end

View File

@@ -7,20 +7,27 @@
//
#import <Cocoa/Cocoa.h>
#import "MPDatabaseSettingsDelegate.h"
typedef NS_ENUM(NSUInteger, MPDatabaseSettingsTab) {
MPDatabaseSettingsTabGeneral,
MPDatabaseSettingsTabPassword,
MPDatabaseSettingsTabDisplay,
MPDatabaseSettingsTabAdvanced
MPDatabaseSettingsTabAdvanced,
MPDatabaseSettingsTemplatesTab,
};
@class MPDocument;
@class HNHRoundendTextField;
@class HNHRoundedSecureTextField;
@interface MPDatabaseSettingsWindowController : NSWindowController
@interface MPDatabaseSettingsWindowController : NSWindowController <NSTextFieldDelegate, NSTabViewDelegate>
@property (nonatomic,weak) id<MPDatabaseSettingsDelegate> delegate;
@property (weak) IBOutlet NSTabView *sectionTabView;
@property (weak) IBOutlet NSButton *saveButton;
@property (weak) IBOutlet NSButton *cancelButton;
/* General Tab */
@property (weak) IBOutlet NSTextField *databaseNameTextField;
@@ -28,8 +35,11 @@ typedef NS_ENUM(NSUInteger, MPDatabaseSettingsTab) {
/* Protection */
@property (weak) IBOutlet HNHRoundedSecureTextField *passwordTextField;
@property (weak) IBOutlet HNHRoundedSecureTextField *passwordRepeatTextField;
@property (weak) IBOutlet NSPathControl *keyfilePathControl;
@property (weak) IBOutlet NSButton *togglePasswordButton;
@property (weak) IBOutlet NSTextField *errorTextField;
- (IBAction)clearKey:(id)sender;
- (IBAction)generateKey:(id)sender;
@@ -46,10 +56,19 @@ typedef NS_ENUM(NSUInteger, MPDatabaseSettingsTab) {
@property (weak) IBOutlet NSButton *emptyRecycleBinOnQuitCheckButton;
@property (weak) IBOutlet NSPopUpButton *selectRecycleBinGroupPopUpButton;
/* Templates Tab */
@property (weak) IBOutlet HNHRoundendTextField *defaultUsernameTextField;
@property (weak) IBOutlet NSPopUpButton *templateGroupPopUpButton;
- (id)initWithDocument:(MPDocument *)document;
- (void)showSettingsTab:(MPDatabaseSettingsTab)tab;
- (void)update;
@end

View File

@@ -11,19 +11,26 @@
#import "MPDocumentWindowController.h"
#import "MPDatabaseVersion.h"
#import "MPIconHelper.h"
#import "MPSettingsHelper.h"
#import "HNHRoundedTextField.h"
#import "HNHRoundedSecureTextField.h"
#import "NSString+Empty.h"
#import "Kdb.h"
#import "Kdb4Node.h"
#import "KdbGroup+MPAdditions.h"
@interface MPDatabaseSettingsWindowController () {
MPDocument *_document;
NSString *_missingFeature;
}
@property (nonatomic,assign) BOOL trashEnabled;
@property (nonatomic,assign) BOOL showPassword;
@property (nonatomic,assign) BOOL hasValidPasswordOrKey;
@property (nonatomic,weak) NSURL *keyURL;
@end
@@ -38,6 +45,8 @@
if(self) {
_document = document;
_showPassword = NO;
_hasValidPasswordOrKey = NO;
_missingFeature = NSLocalizedString(@"KDBX_ONLX_FEATURE", "Feature only available in kdbx databases");
}
return self;
}
@@ -47,15 +56,22 @@
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
[self.saveButton bind:NSEnabledBinding toObject:self withKeyPath:@"hasValidPasswordOrKey" options:nil];
[self.sectionTabView setDelegate:self];
[self update];
}
- (void)setDelegate:(id<MPDatabaseSettingsDelegate>)delegate {
if(_delegate != delegate) {
if([delegate conformsToProtocol:@protocol(MPDatabaseSettingsDelegate)]) {
_delegate = delegate;
}
else{
NSAssert(NO, @"Delegate needs to conform to MPDatabaseSettingsDelegate protocoll");
}
}
}
@@ -72,85 +88,296 @@
/* Display */
/* Advanced */
_document.treeV4.recycleBinEnabled = self.trashEnabled;
NSMenuItem *menuItem = [self.selectRecycleBinGroupPopUpButton selectedItem];
KdbGroup *group = [menuItem representedObject];
[_document useGroupAsTrash:group];
_document.treeV4.recycleBinEnabled = self.trashEnabled;
NSMenuItem *trashMenuItem = [self.selectRecycleBinGroupPopUpButton selectedItem];
KdbGroup *trashGroup = [trashMenuItem representedObject];
[_document useGroupAsTrash:trashGroup];
_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;
NSMenuItem *templateMenuItem = [self.templateGroupPopUpButton selectedItem];
KdbGroup *templateGroup = [templateMenuItem representedObject];
[_document useGroupAsTemplate:templateGroup];
/* Close to finish */
[self close:nil];
BOOL protectNotes = [self.protectNotesCheckButton state] == NSOnState;
BOOL protectPassword = [self.protectPasswortCheckButton state] == NSOnState;
BOOL protectTitle = [self.protectTitleCheckButton state] == NSOnState;
BOOL protectURL = [self.protectURLCheckButton state] == NSOnState;
BOOL protectUsername = [self.protectUserNameCheckButton state] == NSOnState;
if(_document.version == MPDatabaseVersion4) {
_document.treeV4.protectNotes = protectNotes;
_document.treeV4.protectPassword = protectPassword;
_document.treeV4.protectTitle = protectTitle;
_document.treeV4.protectUrl = protectURL;
_document.treeV4.protectUserName = protectUsername;
}
else {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setBool:protectNotes forKey:kMPSettingsKeyLegacyHideNotes];
[defaults setBool:protectPassword forKey:kMPSettingsKeyLegacyHidePassword];
[defaults setBool:protectTitle forKey:kMPSettingsKeyLegacyHideTitle];
[defaults setBool:protectURL forKey:kMPSettingsKeyLegacyHideURL];
[defaults setBool:protectUsername forKey:kMPSettingsKeyLegacyHideUsername];
[defaults synchronize];
}
[self closeDidSave:YES];
}
- (IBAction)close:(id)sender {
- (IBAction)cancel:(id)sender {
[self closeDidSave:NO];
}
- (void)closeDidSave:(BOOL)didSave {
/* Remove the window first */
[NSApp endSheet:[self window]];
[[self window] orderOut:nil];
/* Then notify the delegate */
if(self.delegate) {
if(didSave && [self.delegate respondsToSelector:@selector(didSaveDatabaseSettings)]) {
[self.delegate didSaveDatabaseSettings];
}
else if(!didSave && [self.delegate respondsToSelector:@selector(didCancelDatabaseSettings)]) {
[self.delegate didCancelDatabaseSettings];
}
}
}
- (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];
}
[self _setupPasswordTab:tree];
[self _setupDatabase:tree];
[self _setupProtectionTab:tree];
[self _setupAdvancedTab:tree];
[self _setupTemplatesTab:tree];
}
- (void)showSettingsTab:(MPDatabaseSettingsTab)tab {
/*
We need to make sure the window is loaded
so we just call the the getter and led teh loading commence
*/
if(![self window]) {
return;
}
self.showPassword = NO;
NSTabViewItem *tabViewItem = [self.sectionTabView tabViewItemAtIndex:tab];
BOOL canSelectTab = [self tabView:self.sectionTabView shouldSelectTabViewItem:tabViewItem];
if(!canSelectTab) {
[self.sectionTabView selectTabViewItemAtIndex:MPDatabaseSettingsTabPassword];
}
[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.keyfilePathControl setURL:nil];
self.keyURL = nil;
}
- (IBAction)generateKey:(id)sender {
}
#pragma mark NSTextFieldDelegate
- (void)controlTextDidChange:(NSNotification *)obj {
[self _verifyPasswordAndKey];
}
#pragma mark NSTableViewDelegate
- (BOOL)tabView:(NSTabView *)tabView shouldSelectTabViewItem:(NSTabViewItem *)tabViewItem {
NSUInteger index = [tabView indexOfTabViewItem:tabViewItem];
switch ((MPDatabaseSettingsTab)index) {
case MPDatabaseSettingsTabPassword:
case MPDatabaseSettingsTabDisplay:
return YES;
case MPDatabaseSettingsTabAdvanced:
case MPDatabaseSettingsTabGeneral:
case MPDatabaseSettingsTemplatesTab:
return (_document.version == MPDatabaseVersion4);
default:
return NO;
}
}
#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 = ![NSString isEmptyString:password];
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];
BOOL isKdbx = (nil != tree);
[self.databaseDescriptionTextView setEditable:isKdbx];
[self.databaseNameTextField setEnabled:isKdbx];
if(isKdbx) {
[self.databaseNameTextField setStringValue:tree.databaseName];
[self.databaseDescriptionTextView setString:tree.databaseDescription];
}
else {
[self.databaseNameTextField setStringValue:_missingFeature];
[self.databaseDescriptionTextView setString:_missingFeature];
}
}
- (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];
BOOL isKdbX = (nil != tree);
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
BOOL protectNotes = isKdbX ? tree.protectNotes : [defaults boolForKey:kMPSettingsKeyLegacyHideNotes];
BOOL protectPassword = isKdbX ? tree.protectPassword : [defaults boolForKey:kMPSettingsKeyLegacyHidePassword];
BOOL protectTitle = isKdbX ? tree.protectTitle : [defaults boolForKey:kMPSettingsKeyLegacyHideTitle];
BOOL protectUrl = isKdbX ? tree.protectUrl : [defaults boolForKey:kMPSettingsKeyLegacyHideURL];
BOOL protectUsername = isKdbX ? tree.protectUserName : [defaults boolForKey:kMPSettingsKeyLegacyHideUsername];
[self.protectNotesCheckButton setState:protectNotes ? NSOnState : NSOffState ];
[self.protectPasswortCheckButton setState:protectPassword ? NSOnState : NSOffState];
[self.protectTitleCheckButton setState:protectTitle ? NSOnState : NSOffState];
[self.protectURLCheckButton setState:protectUrl ? NSOnState : NSOffState];
[self.protectUserNameCheckButton setState:protectUsername ? NSOnState : NSOffState];
}
- (void)_setupAdvancedTab:(Kdb4Tree *)tree {
self.trashEnabled = tree.recycleBinEnabled;
BOOL isKdbX = (nil != tree);
self.trashEnabled = isKdbX ? tree.recycleBinEnabled : NO;
[self.enableRecycleBinCheckButton bind:NSValueBinding toObject:self withKeyPath:@"trashEnabled" options:nil];
[self.enableRecycleBinCheckButton setEnabled:isKdbX];
[self.selectRecycleBinGroupPopUpButton bind:NSEnabledBinding toObject:self withKeyPath:@"trashEnabled" options:nil];
[self _updateTrashFolders:tree];
if(isKdbX) {
[self _updateTrashFolders:tree];
}
}
- (void)_setupPasswordTab:(Kdb4Tree *)tree {
[self.passwordTextField setStringValue:_document.password ? _document.password : @""];
[self.keyfilePathControl setURL:_document.key];
[self.passwordRepeatTextField setStringValue:[self.passwordTextField 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)_setupTemplatesTab:(Kdb4Tree *)tree {
}
- (void)_updateFirstResponder {
NSTabViewItem *selected = [self.sectionTabView selectedTabViewItem];
MPDatabaseSettingsTab tab = [[self.sectionTabView tabViewItems] indexOfObject:selected];
switch(tab) {
case MPDatabaseSettingsTabAdvanced:
[[self window] makeFirstResponder:self.databaseNameTextField];
break;
case MPDatabaseSettingsTabDisplay:
[[self window] makeFirstResponder:self.protectTitleCheckButton];
break;
case MPDatabaseSettingsTabGeneral:
[[self window] makeFirstResponder:self.databaseNameTextField];
break;
case MPDatabaseSettingsTabPassword:
[[self window] makeFirstResponder:self.passwordTextField];
break;
case MPDatabaseSettingsTemplatesTab:
break;
}
}
- (void)_updateTrashFolders:(Kdb4Tree *)tree {
NSMenu *menu = [self _buildTreeMenu:tree];
NSMenu *menu = [self _buildTrashTreeMenu:tree];
[self.selectRecycleBinGroupPopUpButton setMenu:menu];
}
- (void)_updateTemplateGroup:(Kdb4Tree *)tree {
//
}
- (NSMenu *)_buildTrashTreeMenu:(Kdb4Tree *)tree {
NSMenu *menu = [self _buildTreeMenu:tree];
NSMenuItem *selectItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"AUTOCREATE_TRASH_FOLDER", @"Menu item for automatic trash creation")
action:NULL
keyEquivalent:@""];
[selectItem setEnabled:YES];
[menu insertItem:selectItem atIndex:0];
return menu;
}
- (NSMenu *)_buildTemplateTreeMenu:(Kdb4Tree *)tree {
NSMenu *menu = [self _buildTreeMenu:tree];
NSMenuItem *selectItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"NO_TEMPLATE_GROUP", @"Menu item to reset the template groups")
action:NULL
keyEquivalent:@""];
[selectItem setEnabled:YES];
[menu insertItem:selectItem atIndex:0];
return menu;
}
- (NSMenu *)_buildTreeMenu:(Kdb4Tree *)tree {
NSMenu *menu = [[NSMenu alloc] init];
[menu setAutoenablesItems:NO];
@@ -166,10 +393,7 @@
}
[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

@@ -12,6 +12,7 @@
#import "NSData+Gzip.h"
#import "Kdb3Node.h"
#import "Kdb3Entry+KVOAdditions.h"
#import "Kdb4Node.h"
#import "Kdb4Entry+KVOAdditions.h"
@@ -31,6 +32,7 @@
}
entry.binary = binaryData;
entry.binaryDesc = fileName;
[entry insertObject:@"" inBinariesAtIndex:1];
}
if( [anEntry isKindOfClass:[Kdb4Entry class]]) {
Kdb4Entry *entry = (Kdb4Entry *)anEntry;
@@ -68,7 +70,7 @@
else {
encodedData = fileData;
}
binary.data = [[NSString alloc] initWithData:encodedData encoding:NSASCIIStringEncoding];
binary.data = [[NSString alloc] initWithData:encodedData encoding:NSUTF8StringEncoding];
[self.treeV4.binaries addObject:binary];
BinaryRef *ref = [[BinaryRef alloc] init];
@@ -78,17 +80,6 @@
}
}
- (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;
@@ -103,6 +94,14 @@
[self.treeV4.binaries removeObject:binary];
}
- (void)removeAttachmentFromEntry:(KdbEntry *)anEntry {
if(self.version != MPDatabaseVersion3) {
return;
}
Kdb3Entry *entry = (Kdb3Entry *)anEntry;
[entry removeObjectFromBinariesAtIndex:0];
}
- (Binary *)findBinary:(BinaryRef *)reference {
if(self.version != MPDatabaseVersion4) {
return nil;
@@ -115,22 +114,35 @@
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]];
}
- (void)saveAttachmentForItem:(id)item toLocation:(NSURL *)location {
if([item isKindOfClass:[Kdb3Entry class]]) {
Kdb3Entry *entry = (Kdb3Entry *)item;
NSError *error = nil;
if( ![rawData writeToURL:location options:0 error:&error] ) {
if(! [entry.binary writeToURL:location options:NSDataWritingAtomic error:&error] ) {
[NSApp presentError:error];
}
}
else if([item isKindOfClass:[BinaryRef class]]) {
Binary *binary = [self findBinary:item];
NSData *rawData = nil;
if(binary) {
if(binary.compressed) {
rawData = [NSMutableData mutableDataWithBase64DecodedData:[binary.data dataUsingEncoding:NSUTF8StringEncoding]];
rawData = [rawData gzipInflate];
}
else {
rawData = [NSMutableData mutableDataWithBase64DecodedData:[binary.data dataUsingEncoding:NSUTF8StringEncoding]];
}
NSError *error = nil;
if( ![rawData writeToURL:location options:NSDataWritingAtomic error:&error] ) {
[NSApp presentError:error];
}
}
}
else {
NSAssert(NO, @"Item is neither BinaryRef nor Kdb3Entry");
return;
}
}
- (NSUInteger)nextBinaryId {

View File

@@ -19,6 +19,8 @@ APPKIT_EXTERN NSString *const MPDocumentDidRevertNotifiation;
APPKIT_EXTERN NSString *const MPDocumentEntryKey;
APPKIT_EXTERN NSString *const MPDocumentGroupKey;
APPKIT_EXTERN NSString *const MPDocumentRequestPasswordSaveNotification;
@class KdbGroup;
@class KdbEntry;
@class KdbTree;
@@ -42,6 +44,7 @@ APPKIT_EXTERN NSString *const MPDocumentGroupKey;
@property (strong, readonly, nonatomic) KdbTree *tree;
@property (weak, readonly, nonatomic) KdbGroup *root;
@property (readonly, strong) MPRootAdapter *rootAdapter;
@property (weak, readonly) KdbGroup *trash;
@property (nonatomic, copy) NSString *password;
@property (nonatomic, strong) NSURL *key;
@@ -49,6 +52,7 @@ APPKIT_EXTERN NSString *const MPDocumentGroupKey;
@property (assign, readonly) MPDatabaseVersion version;
@property (assign, readonly, getter = isReadOnly) BOOL readOnly;
- (id)initWithVersion:(MPDatabaseVersion)version;
#pragma mark Lock/Decrypt
@@ -66,6 +70,9 @@ APPKIT_EXTERN NSString *const MPDocumentGroupKey;
- (Kdb3Tree *)treeV3;
- (void)useGroupAsTrash:(KdbGroup *)group;
- (void)useGroupAsTemplate:(KdbGroup *)group;
- (BOOL)isItemTrashed:(id)item;
#pragma mark Export
- (void)writeXMLToURL:(NSURL *)url;
@@ -79,7 +86,6 @@ APPKIT_EXTERN NSString *const MPDocumentGroupKey;
/*
All non-setter undoable actions
*/
- (BOOL)group:(KdbGroup *)group isMoveableToGroup:(KdbGroup *)target;
/* TODO in UNDO auslagen */
- (void)addStringField:(StringField *)field toEntry:(Kdb4Entry *)entry atIndex:(NSUInteger)index;
@@ -95,9 +101,12 @@ APPKIT_EXTERN NSString *const MPDocumentGroupKey;
@interface MPDocument (Attachments)
- (void)addAttachment:(NSURL *)location toEntry:(KdbEntry *)anEntry;
- (void)saveAttachmentFromEntry:(KdbEntry *)anEntry toLocation:(NSURL *)location;
- (void)saveAttachment:(BinaryRef *)reference toLocation:(NSURL *)location;
/**
item can be either a BinaryRef or an Kdb3Entry.
*/
- (void)saveAttachmentForItem:(id)item toLocation:(NSURL *)location;
- (void)removeAttachment:(BinaryRef *)reference fromEntry:(KdbEntry *)anEntry;
- (void)removeAttachmentFromEntry:(KdbEntry *)anEntry;
- (NSUInteger)nextBinaryId;
- (Binary *)findBinary:(BinaryRef *)reference;

View File

@@ -13,33 +13,40 @@
#import "MPRootAdapter.h"
#import "MPIconHelper.h"
#import "MPActionHelper.h"
#import "MPSettingsHelper.h"
#import "KdbLib.h"
#import "Kdb3Node.h"
#import "Kdb4Node.h"
#import "Kdb4Persist.h"
#import "KdbPassword.h"
#import "KdbGroup+Undo.h"
#import "KdbGroup+KVOAdditions.h"
#import "Kdb4Entry+KVOAdditions.h"
#import "KdbGroup+MPTreeTools.h"
#import "KdbGroup+MPAdditions.h"
#import "KdbEntry+Undo.h"
#import "KdbGroup+Undo.h"
#import "Kdb3Tree+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 MPDocumentWillDelteGroupNotification = @"com.hicknhack.macpass.MPDocumentDidDelteGroupNotification";
NSString *const MPDocumentDidAddEntryNotification = @"com.hicknhack.macpass.MPDocumentDidAddEntryNotification";
NSString *const MPDocumentWillDeleteEntryNotification = @"com.hicknhack.macpass.MPDocumentDidDeleteEntryNotification";
NSString *const MPDocumentDidRevertNotifiation = @"com.hicknhack.macpass.MPDocumentDidRevertNotifiation";
NSString *const MPDocumentDidAddGroupNotification = @"com.hicknhack.macpass.MPDocumentDidAddGroupNotification";
NSString *const MPDocumentWillDelteGroupNotification = @"com.hicknhack.macpass.MPDocumentDidDelteGroupNotification";
NSString *const MPDocumentDidAddEntryNotification = @"com.hicknhack.macpass.MPDocumentDidAddEntryNotification";
NSString *const MPDocumentWillDeleteEntryNotification = @"com.hicknhack.macpass.MPDocumentDidDeleteEntryNotification";
NSString *const MPDocumentDidRevertNotifiation = @"com.hicknhack.macpass.MPDocumentDidRevertNotifiation";
NSString *const MPDocumentRequestPasswordSaveNotification = @"com.hicknhack.macpass.MPDocumentRequestPasswordSaveNotification";
NSString *const MPDocumentEntryKey = @"MPDocumentEntryKey";
NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
NSString *const MPDocumentEntryKey = @"MPDocumentEntryKey";
NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
@interface MPDocument () {
@@ -61,7 +68,6 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
@property (strong) NSURL *lockFileURL;
@property (readonly) BOOL useTrash;
@property (weak, readonly) KdbGroup *trash;
@property (strong) IBOutlet NSView *warningView;
@property (weak) IBOutlet NSImageView *warningViewImage;
@@ -162,6 +168,13 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
- (void)close {
[self _cleanupLock];
/*
We store the last url. Restored windows are automatically handeld.
If closeAllDocuments is set, all docs get this messgae
*/
if([[self fileURL] isFileURL]) {
[[NSUserDefaults standardUserDefaults] setObject:[self.fileURL absoluteString] forKey:kMPSettingsKeyLastDatabasePath];
}
[super close];
}
@@ -227,17 +240,21 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
return NO;
}
- (void)saveDocument:(id)sender {
if(self.hasPasswordOrKey) {
[super saveDocument:sender];
}
else {
[[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentRequestPasswordSaveNotification object:self userInfo:nil];
}
}
- (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;
return NO;
}
#pragma mark Data Accesors
@@ -263,7 +280,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
- (Kdb3Tree *)treeV3 {
switch (_version) {
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;
case MPDatabaseVersion4:
return nil;
@@ -277,7 +294,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
case MPDatabaseVersion3:
return nil;
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;
default:
return nil;
@@ -303,6 +320,26 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
return nil;
}
- (BOOL)isItemTrashed:(id)item {
BOOL validItem = [item isKindOfClass:[KdbEntry class]] || [item isKindOfClass:[KdbGroup class]];
if(!item) {
return NO;
}
if(item == self.trash) {
return NO; // No need to look further as this is the trashcan
}
if(validItem) {
BOOL isTrashed = NO;
id parent = [item parent];
while( parent && !isTrashed ) {
isTrashed = (parent == self.trash);
parent = [parent parent];
}
return isTrashed;
}
return NO;
}
- (void)useGroupAsTrash:(KdbGroup *)group {
if(self.useTrash) {
Kdb4Group *groupv4 = (Kdb4Group *)group;
@@ -312,11 +349,24 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
}
}
- (void)useGroupAsTemplate:(KdbGroup *)group {
Kdb4Group *groupv4 = (Kdb4Group *)group;
if([self.treeV4.entryTemplatesGroup isEqual:groupv4.uuid]) {
self.treeV4.entryTemplatesGroup = groupv4.uuid;
}
}
#pragma mark Data manipulation
- (KdbEntry *)createEntry:(KdbGroup *)parent {
if(!parent) {
return nil; // No parent
}
if(parent == self.trash) {
return nil; // no new Groups in trash
}
if([self isItemTrashed:parent]) {
return nil;
}
KdbEntry *newEntry = [self.tree createEntry:parent];
newEntry.title = NSLocalizedString(@"DEFAULT_ENTRY_TITLE", @"Title for a newly created entry");
if(self.treeV4 && ([self.treeV4.defaultUserName length] > 0)) {
@@ -332,6 +382,12 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
if(!parent) {
return nil; // no parent!
}
if(parent == self.trash) {
return nil; // no new Groups in trash
}
if([self isItemTrashed:parent]) {
return nil;
}
KdbGroup *newGroup = [self.tree createGroup:parent];
newGroup.name = NSLocalizedString(@"DEFAULT_GROUP_NAME", @"Title for a newly created group");
newGroup.image = MPIconFolder;
@@ -349,53 +405,20 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
Kdb4Entry *entryV4 = (Kdb4Entry *)entry;
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");
title = [entryV4 uniqueKeyForProposal:title];
StringField *newStringField = [StringField stringFieldWithKey:title andValue:value];
[self addStringField:newStringField toEntry:entryV4 atIndex:[entryV4.stringFields count]];
return newStringField;
}
- (void)moveGroup:(KdbGroup *)group toGroup:(KdbGroup *)target index:(NSInteger)index {
NSInteger oldIndex = [group.parent.groups indexOfObject:group];
if(group.parent == target && oldIndex == index) {
return; // No changes
}
[[[self undoManager] prepareWithInvocationTarget:self] moveGroup:group toGroup:group.parent index:oldIndex];
if(self.trash == target) {
[[self undoManager] setActionName:@"UNDO_DELETE_GROUP"];
}
else {
[[self undoManager] setActionName:@"MOVE_GROUP"];
}
[group.parent removeObjectFromGroupsAtIndex:oldIndex];
if(index < 0 || index > [target.groups count] ) {
index = [target.groups count];
}
[target insertObject:group inGroupsAtIndex:index];
}
- (BOOL)group:(KdbGroup *)group isMoveableToGroup:(KdbGroup *)target {
if(target == nil) {
return NO;
}
BOOL isMovable = YES;
KdbGroup *ancestor = target.parent;
while(ancestor.parent) {
if(ancestor == group) {
isMovable = NO;
break;
}
ancestor = ancestor.parent;
}
return isMovable;
}
- (void)deleteEntry:(KdbEntry *)entry {
if(self.useTrash) {
if(!self.trash) {
[self _createTrashGroup];
}
if([self isItemTrashed:entry]) {
return; // Entry is already trashed
}
[entry moveToTrashUndoable:self.trash atIndex:[self.trash.entries count]];
}
else {
@@ -408,6 +431,9 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
if(!self.trash) {
[self _createTrashGroup];
}
if( (group == self.trash) || [self isItemTrashed:group] ) {
return; //Groups already trashed cannot be deleted
}
[group moveToTrashUndoable:self.trash atIndex:[self.trash.groups count]];
}
else {
@@ -420,6 +446,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
- (void)addStringField:(StringField *)field toEntry:(Kdb4Entry *)entry atIndex:(NSUInteger)index {
[[[self undoManager] prepareWithInvocationTarget:self] removeStringField:field formEntry:entry];
[[self undoManager] setActionName:NSLocalizedString(@"UNDO_ADD_STRING_FIELD", @"Add Stringfield Undo")];
field.entry = entry;
[entry insertObject:field inStringFieldsAtIndex:index];
}
@@ -430,12 +457,16 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
}
[[[self undoManager] prepareWithInvocationTarget:self] addStringField:field toEntry:entry atIndex:index];
[[self undoManager] setActionName:NSLocalizedString(@"UNDO_DELETE_STRING_FIELD", @"Delte Stringfield undo")];
field.entry = nil;
[entry removeObjectFromStringFieldsAtIndex:index];
}
#pragma mark Actions
- (void)emptyTrash:(id)sender {
if(self.version != MPDatabaseVersion4) {
return; // We have no trash on those file types
}
NSAlert *alert = [[NSAlert alloc] init];
[alert setAlertStyle:NSWarningAlertStyle];
[alert setMessageText:NSLocalizedString(@"WARNING_ON_EMPTY_TRASH_TITLE", "")];
@@ -455,13 +486,14 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
}
}
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
if([menuItem action] == [MPActionHelper actionOfType:MPActionEmptyTrash]) {
- (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)anItem {
if([anItem action] == [MPActionHelper actionOfType:MPActionEmptyTrash]) {
BOOL hasGroups = [self.trash.groups count] > 0;
BOOL hasEntries = [self.trash.entries count] > 0;
return (hasEntries || hasGroups);
}
return YES;
return [super validateUserInterfaceItem:anItem];
}
#pragma mark Private
@@ -504,7 +536,24 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
for(KdbGroup *group in [self.trash childGroups]) {
[[self undoManager] removeAllActionsWithTarget:group];
}
[self _cleanTrashedBinaries];
[self.trash clear];
}
- (void)_cleanTrashedBinaries {
NSMutableSet *clearKeys = [[NSMutableSet alloc] initWithCapacity:20];
NSMutableArray *clearBinaries = [[NSMutableArray alloc] initWithCapacity:[self.treeV4.binaries count]];
for(Kdb4Entry *entry in [self.trash childEntries]) {
for(BinaryRef *binaryRef in entry.binaries) {
[clearKeys addObject:@(binaryRef.ref)];
}
}
for(Binary *binary in self.treeV4.binaries) {
if([clearKeys containsObject:@(binary.binaryId)]) {
[clearBinaries addObject:binary];
}
}
[self.treeV4.binaries removeObjectsInArray:clearBinaries];
}
@end

View File

@@ -7,6 +7,7 @@
//
#import <Cocoa/Cocoa.h>
#import "MPDatabaseSettingsDelegate.h"
@class MPViewController;
@class MPEntryViewController;
@@ -19,7 +20,7 @@
APPKIT_EXTERN NSString *const MPCurrentItemChangedNotification;
@interface MPDocumentWindowController : NSWindowController <NSWindowDelegate>
@interface MPDocumentWindowController : NSWindowController <NSWindowDelegate, MPDatabaseSettingsDelegate>
@property (readonly, strong) MPPasswordInputController *passwordInputController;
@property (readonly, strong) MPEntryViewController *entryViewController;
@@ -32,6 +33,12 @@ APPKIT_EXTERN NSString *const MPCurrentItemChangedNotification;
@property (readonly, unsafe_unretained) KdbGroup *currentGroup;
@property (readonly, unsafe_unretained) KdbEntry *currentEntry;
/**
@param action The action that should be validatet
@param item The item that the action affects. Pass nil to fall back for default item
@returns YES if the action is valid, NO otherwise
*/
- (BOOL)validateAction:(SEL)action forItem:(id)item;
- (void)showEntries;
- (void)showPasswordInput;
@@ -40,7 +47,7 @@ APPKIT_EXTERN NSString *const MPCurrentItemChangedNotification;
- (IBAction)showDatabaseSettings:(id)sender;
- (IBAction)exportDatabase:(id)sender;
- (void)lock:(id)sender;
- (IBAction)lock:(id)sender;
- (void)createGroup:(id)sender;
- (void)toggleInspector:(id)sender;

View File

@@ -17,12 +17,14 @@
#import "MPActionHelper.h"
#import "MPDatabaseSettingsWindowController.h"
#import "MPConstants.h"
#import "MPSettingsHelper.h"
NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCurrentItemChangedNotification";
@interface MPDocumentWindowController () {
@private
id _firstResponder;
BOOL _saveAfterPasswordEdit; // Flag to indicat that the document needs to be saved after password edit did finish
}
@property (strong) IBOutlet NSSplitView *splitView;
@@ -53,6 +55,7 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
_entryViewController = [[MPEntryViewController alloc] init];
_inspectorViewController = [[MPInspectorViewController alloc] init];
_currentItem = nil;
_saveAfterPasswordEdit = NO;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_updateCurrentItem:) name:MPOutlineViewDidChangeGroupSelection object:_outlineViewController];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_updateCurrentItem:) name:MPDidChangeSelectedEntryNotification object:_entryViewController];
@@ -62,15 +65,13 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
#pragma mark View Handling
- (void)windowDidLoad {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_didRevertDocument:) name:MPDocumentDidRevertNotifiation object:[self document]];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_setPasswordAndSave) name:MPDocumentRequestPasswordSaveNotification object:[self document]];
[_entryViewController setupNotifications:self];
[_inspectorViewController setupNotifications:self];
@@ -94,6 +95,11 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
[_splitView setHoldingPriority:NSLayoutPriorityDefaultLow+2 forSubviewAtIndex:0];
[_splitView setHoldingPriority:NSLayoutPriorityDefaultLow+1 forSubviewAtIndex:2];
BOOL showInspector = [[NSUserDefaults standardUserDefaults] boolForKey:kMPSettingsKeyShowInspector];
if(!showInspector) {
[inspectorView removeFromSuperview];
}
[[self window] setDelegate:self];
MPDocument *document = [self document];
@@ -103,6 +109,8 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
else {
[self showEntries];
}
[_splitView setAutosaveName:@"SplitView"];
}
- (void)_setContentViewController:(MPViewController *)viewController {
@@ -176,34 +184,79 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
}
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
BOOL enabled = YES;
MPDocument *document = [self document];
if([menuItem action] == @selector(exportDatabase:)) {
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.isLocked || document.isReadOnly );
if(itemAction == [MPActionHelper actionOfType:MPActionDelete]) {
enabled &= (nil != _currentItem) && (_currentItem != document.trash);
}
enabled &= !( !document.decrypted || document.isLocked || document.isReadOnly );
return enabled;
}
- (BOOL)validateToolbarItem:(NSToolbarItem *)theItem {
MPDocument *document = [self document];
if(document.isLocked || document.isReadOnly) {
if(!document.decrypted || document.isLocked || document.isReadOnly) {
return NO;
}
SEL itemAction = [theItem action];
if( itemAction == [MPActionHelper actionOfType:MPActionLock]) {
return document.hasPasswordOrKey;
}
if(itemAction == [MPActionHelper actionOfType:MPActionAddEntry]) {
return (nil != _outlineViewController.selectedGroup);
}
if(itemAction == [MPActionHelper actionOfType:MPActionDelete]) {
return (nil != _currentItem);
}
if(itemAction == [MPActionHelper actionOfType:MPActionToggleInspector]) {
return (nil != [_splitView superview]);
}
MPActionType actionType = [MPActionHelper typeForAction:[theItem action]];
switch (actionType) {
case MPActionAddGroup:
case MPActionAddEntry:
return (nil != _outlineViewController.selectedGroup);
case MPActionDelete: {
BOOL valid = (nil != _currentItem);
valid &= (_currentItem != document.trash);
valid &= ![document isItemTrashed:_currentItem];
return valid;
}
case MPActionLock:
return document.hasPasswordOrKey;
case MPActionToggleInspector:
return (nil != [_splitView superview]);
default:
return YES;
}
return YES;
}
- (BOOL)validateAction:(SEL)action forItem:(id)item {
MPDocument *document = [self document];
if(!document.decrypted || document.isLocked || document.isReadOnly) {
return NO;
}
MPActionType actionType = [MPActionHelper typeForAction:action];
switch (actionType) {
case MPActionAddGroup:
case MPActionAddEntry:
// test if Group is in trash
return (nil != _outlineViewController.selectedGroup);
case MPActionDelete: {
BOOL valid = (nil != _currentItem);
valid &= (_currentItem != document.trash);
valid &= ![document isItemTrashed:_currentItem];
return valid;
}
case MPActionLock:
return document.hasPasswordOrKey;
case MPActionToggleInspector:
return (nil != [_splitView superview]);
default:
return YES;
}
return YES;
}
@@ -216,14 +269,14 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
}
- (void)editPassword:(id)sender {
[self _showDatabaseSetting:MPDatabaseSettingsTabPassword];
[self _showDatabaseSetting:MPDatabaseSettingsTabPassword saveDocument:NO];
}
- (void)showDatabaseSettings:(id)sender {
[self _showDatabaseSetting:MPDatabaseSettingsTabGeneral];
[self _showDatabaseSetting:MPDatabaseSettingsTabGeneral saveDocument:NO];
}
- (void)lock:(id)sender {
- (IBAction)lock:(id)sender {
MPDocument *document = [self document];
if(!document.hasPasswordOrKey) {
return; // Document needs a password/keyfile to be lockable
@@ -245,18 +298,21 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
- (void)toggleInspector:(id)sender {
NSView *inspectorView = [_inspectorViewController view];
BOOL inspectorVisible = NO;
if([inspectorView superview]) {
//[inspectorView animator]
[inspectorView removeFromSuperview];
}
else {
// Remove contraint on view removal.
inspectorVisible = YES;
[_splitView addSubview:inspectorView];
[_splitView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"[inspectorView(>=200)]"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(inspectorView)]];
}
[[NSUserDefaults standardUserDefaults] setBool:inspectorVisible forKey:kMPSettingsKeyShowInspector];
}
- (void)showEntries {
@@ -268,7 +324,7 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
[[contentView subviews][0] removeFromSuperviewWithoutNeedingDisplay];
}
[contentView addSubview:_splitView];
[_splitView adjustSubviews];
//[_splitView adjustSubviews];
NSView *outlineView = [_outlineViewController view];
NSView *inspectorView = [_inspectorViewController view];
NSView *entryView = [_entryViewController view];
@@ -314,7 +370,7 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
if(removeInspector) {
[inspectorView removeFromSuperview];
}
[contentView layout];
[contentView layoutSubtreeIfNeeded];
MPDocument *document = [self document];
document.locked = NO;
@@ -325,6 +381,7 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
[_outlineViewController showOutline];
}
#pragma mark NSWindowDelegate
- (void)windowDidUpdate:(NSNotification *)notification {
id firstResonder = [[self window] firstResponder];
@@ -337,16 +394,49 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
}
}
//- (void)windowDidBecomeKey:(NSNotification *)notification {
// if(!_requestPassword) {
// return; // Nothing to do;
// }
// MPDocument *document = [self document];
// if(!document.hasPasswordOrKey && document.decrypted) {
// _requestPassword = NO;
// [self performSelector:@selector(editPassword:) withObject:nil afterDelay:0.5];
// }
//}
#pragma mark MPDatabaseSettingsDelegate
- (void)didCancelDatabaseSettings {
_saveAfterPasswordEdit = NO; // Just Reset the flag
}
- (void)didSaveDatabaseSettings {
if (_saveAfterPasswordEdit) {
_saveAfterPasswordEdit = NO;
}
[[self document] saveDocument:nil];
}
#pragma mark Helper
- (void)_showDatabaseSetting:(MPDatabaseSettingsTab)tab {
if(!self.documentSettingsWindowController) {
_documentSettingsWindowController = [[MPDatabaseSettingsWindowController alloc] initWithDocument:[self document]];
}
[self.documentSettingsWindowController update];
- (void)_setPasswordAndSave {
_saveAfterPasswordEdit = YES;
[self editPassword:nil];
}
- (void)_showDatabaseSetting:(MPDatabaseSettingsTab)tab saveDocument:(BOOL)save{
if(!self.documentSettingsWindowController) {
_documentSettingsWindowController = [[MPDatabaseSettingsWindowController alloc] initWithDocument:[self document]];
[_documentSettingsWindowController setDelegate:self];
}
[self.documentSettingsWindowController update];
[self.documentSettingsWindowController showSettingsTab:tab];
[[NSApplication sharedApplication] beginSheet:[self.documentSettingsWindowController window] modalForWindow:[self window] modalDelegate:nil didEndSelector:NULL contextInfo:NULL];
[[NSApplication sharedApplication] beginSheet:[self.documentSettingsWindowController window]
modalForWindow:[self window]
modalDelegate:nil
didEndSelector:NULL
contextInfo:NULL];
}
- (NSSearchField *)locateToolbarSearchField {

View File

@@ -148,6 +148,9 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername";
[passwordColumn setIdentifier:MPEntryTablePasswordColumnIdentifier];
[urlColumn setIdentifier:MPEntryTableURLColumnIdentifier];
[self.entryTable setAutosaveName:@"EntryTable"];
[self.entryTable setAutosaveTableColumns:YES];
NSSortDescriptor *titleColumSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"title" 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:)];
@@ -510,6 +513,11 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername";
[document deleteEntry:entry];
}
#pragma mark Validation
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
return YES;
}
- (void)_toggleFilterSpace:(id)sender {
NSButton *button = sender;
NSNumber *value = self.filterButtonToMode[[button identifier]];

View File

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

View File

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

View File

@@ -15,7 +15,7 @@
@class HNHRoundedSecureTextField;
@class MPDocumentWindowController;
@interface MPInspectorViewController : MPViewController <NSPopoverDelegate, NSTableViewDelegate>
@interface MPInspectorViewController : MPViewController <NSPopoverDelegate>
@property (weak) IBOutlet MPPopupImageView *itemImageView;
@property (weak) IBOutlet NSTextField *itemNameTextfield;
@@ -36,6 +36,9 @@
@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 */
- (void)setupNotifications:(MPDocumentWindowController *)windowController;

View File

@@ -20,6 +20,8 @@
#import "MPDatabaseVersion.h"
#import "MPCustomFieldTableCellView.h"
#import "MPSelectedAttachmentTableCellView.h"
#import "MPAttachmentTableViewDelegate.h"
#import "MPCustomFieldTableViewDelegate.h"
#import "NSDate+Humanized.h"
@@ -45,6 +47,10 @@ enum {
@interface MPInspectorViewController () {
BOOL _visible;
NSArrayController *_attachmentsController;
NSArrayController *_customFieldsController;
MPAttachmentTableViewDelegate *_attachmentTableDelegate;
MPCustomFieldTableViewDelegate *_customFieldTableDelegate;
}
@property (weak, nonatomic) KdbEntry *selectedEntry;
@@ -53,15 +59,13 @@ enum {
@property (strong) NSPopover *activePopover;
@property (weak) IBOutlet NSButton *generatePasswordButton;
@property (nonatomic, weak) NSDate *modificationDate;
@property (nonatomic, weak) NSDate *creationDate;
@property (nonatomic, strong) NSDate *modificationDate;
@property (nonatomic, strong) NSDate *creationDate;
@property (nonatomic, assign) BOOL showPassword;
@property (nonatomic, assign) NSUInteger activeTab;
@property (weak) IBOutlet NSTabView *tabView;
@property (strong) NSArrayController *attachmentsController;
@property (strong) NSArrayController *customFieldsController;
- (IBAction)addCustomField:(id)sender;
- (IBAction)removeCustomField:(id)sender;
@@ -87,6 +91,10 @@ enum {
_selectedGroup = nil;
_attachmentsController = [[NSArrayController alloc] init];
_customFieldsController = [[NSArrayController alloc] init];
_attachmentTableDelegate = [[MPAttachmentTableViewDelegate alloc] init];
_attachmentTableDelegate.viewController = self;
_customFieldTableDelegate = [[MPCustomFieldTableViewDelegate alloc] init];
_customFieldTableDelegate.viewController = self;
_activeTab = MPGeneralTab;
}
return self;
@@ -107,12 +115,12 @@ enum {
/* Set background to clearcolor so we can draw in the scrollview */
[_attachmentTableView setBackgroundColor:[NSColor clearColor]];
[_attachmentTableView bind:NSContentBinding toObject:self.attachmentsController withKeyPath:@"arrangedObjects" options:nil];
[_attachmentTableView setDelegate:self];
[_attachmentTableView bind:NSContentBinding toObject:_attachmentsController withKeyPath:@"arrangedObjects" options:nil];
[_attachmentTableView setDelegate:_attachmentTableDelegate];
/* Set background to clearcolor so we can draw in the scrollview */
[_customFieldsTableView setBackgroundColor:[NSColor clearColor]];
[_customFieldsTableView bind:NSContentBinding toObject:self.customFieldsController withKeyPath:@"arrangedObjects" options:nil];
[_customFieldsTableView setDelegate:self];
[_customFieldsTableView bind:NSContentBinding toObject:_customFieldsController withKeyPath:@"arrangedObjects" options:nil];
[_customFieldsTableView setDelegate:_customFieldTableDelegate];
[self.passwordTextField bind:@"showPassword" toObject:self withKeyPath:@"showPassword" options:nil];
[self.togglePassword bind:NSValueBinding toObject:self withKeyPath:@"showPassword" options:nil];
@@ -129,25 +137,32 @@ enum {
}
- (void)setModificationDate:(NSDate *)modificationDate {
NSString *modificationString = [NSDateFormatter localizedStringFromDate:modificationDate
dateStyle:NSDateFormatterShortStyle
timeStyle:NSDateFormatterShortStyle];
modificationString = [modificationDate humanized];
NSString *modifedAtTemplate = NSLocalizedString(@"MODIFED_AT_%@", @"Modifed at template string. %@ is replaced by locaized date and time");
[self.modifiedTextField setStringValue:[NSString stringWithFormat:modifedAtTemplate, modificationString]];
_modificationDate = modificationDate;
[self _updateDateStrings];
}
- (void)setCreationDate:(NSDate *)creationDate {
NSString *creationString = [NSDateFormatter localizedStringFromDate:creationDate
dateStyle:NSDateFormatterShortStyle
timeStyle:NSDateFormatterShortStyle];
creationString = [creationDate humanized];
_creationDate = creationDate;
[self _updateDateStrings];
}
- (void)_updateDateStrings {
if(!self.creationDate || !self.modificationDate ) {
[self.modifiedTextField setStringValue:@""];
[self.createdTextField setStringValue:@""];
return; // No dates, just clear
}
NSString *creationString = [self.creationDate humanized];
NSString *modificationString = [self.modificationDate humanized];
NSString *modifedAtTemplate = NSLocalizedString(@"MODIFED_AT_%@", @"Modifed 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.modifiedTextField setStringValue:[NSString stringWithFormat:modifedAtTemplate, modificationString]];
[self.createdTextField setStringValue:[NSString stringWithFormat:createdAtTemplate, creationString]];
}
- (void)_updateContent {
@@ -167,26 +182,26 @@ enum {
- (void)_updateAttachments {
if(self.selectedEntry) {
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 {
/* Use binary from Kdb3Entry */
[_attachmentsController bind:NSContentArrayBinding toObject:self.selectedEntry withKeyPath:@"binaries" options:nil];
}
}
else if([self.attachmentsController content] != nil){
[self.attachmentsController unbind:NSContentArrayBinding];
[self.attachmentsController setContent:nil];
else if([_attachmentsController content] != nil){
[_attachmentsController unbind:NSContentArrayBinding];
[_attachmentsController setContent:nil];
}
}
- (void)_updateCustomFields {
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){
[self.customFieldsController unbind:NSContentArrayBinding];
[self.customFieldsController setContent:nil];
else if([_customFieldsController content] != nil){
[_customFieldsController unbind:NSContentArrayBinding];
[_customFieldsController setContent:nil];
}
}
@@ -335,18 +350,26 @@ enum {
}
- (IBAction)saveAttachment:(id)sender {
Kdb4Entry *entry = (Kdb4Entry *)self.selectedEntry;
BinaryRef *reference = entry.binaries[[sender tag]];
BOOL isVersion4 = [self.selectedEntry isKindOfClass:[Kdb4Entry class]];
id item = self.selectedEntry;
NSString *fileName = nil;
if(isVersion4) {
Kdb4Entry *entry= (Kdb4Entry *)self.selectedEntry;
item = entry.binaries[[sender tag]];
fileName = ((BinaryRef *)item).key;
}
else {
fileName = ((Kdb3Entry *)item).binaryDesc;
}
NSSavePanel *savePanel = [NSSavePanel savePanel];
[savePanel setCanCreateDirectories:YES];
[savePanel setNameFieldStringValue:reference.key];
[savePanel setNameFieldStringValue:fileName];
[savePanel beginSheetModalForWindow:[[self windowController] window] completionHandler:^(NSInteger result) {
if(result == NSFileHandlingPanelOKButton) {
MPDocument *document = [[self windowController] document];
[document saveAttachment:reference toLocation:[savePanel URL]];
[document saveAttachmentForItem:item toLocation:[savePanel URL]];
}
}];
}
@@ -369,9 +392,9 @@ enum {
- (IBAction)removeAttachment:(id)sender {
MPDocument *document = [[self windowController] document];
if(document.version == MPDatabaseVersion3) {
// Uhhhh :D
[document removeAttachmentFromEntry:self.selectedEntry];
}
if(document.version == MPDatabaseVersion4) {
else if(document.version == MPDatabaseVersion4) {
Kdb4Entry *entry = (Kdb4Entry *)self.selectedEntry;
BinaryRef *reference = entry.binaries[[sender tag]];
[document removeAttachment:reference fromEntry:self.selectedEntry];
@@ -412,78 +435,4 @@ enum {
[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];
NSTableCellView *view;
if([selectedIndexes containsIndex:row]) {
MPSelectedAttachmentTableCellView *cellView = [_attachmentTableView makeViewWithIdentifier:@"SelectedCell" owner:_attachmentTableView];
[cellView.saveButton setTag:row];
[cellView.saveButton setAction:@selector(saveAttachment:)];
[cellView.saveButton setTarget:self];
[cellView.removeButton setTag:row];
[cellView.removeButton setAction:@selector(removeAttachment:)];
[cellView.removeButton setTarget:self];
view = cellView;
}
else {
view = [_attachmentTableView makeViewWithIdentifier:@"NormalCell" 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;
}
- (NSTableRowView *)tableView:(NSTableView *)tableView rowViewForRow:(NSInteger)row {
HNHTableRowView *view = nil;
if(tableView == self.attachmentTableView) {
view = [[HNHTableRowView alloc] init];
view.selectionCornerRadius = 7;
}
return view;
}
- (void)_customFieldFrameChanged:(NSNotification *)notification {
// NSView *sender = [notification object];
// NSLog(@"didChangeFrameFor: %@ to: %@", sender, NSStringFromRect([sender frame]));
}
@end

View File

@@ -77,8 +77,7 @@
accepted &= index != NSOutlineViewDropOnItemIndex;
accepted &= index != [_draggedItem.parent.groups indexOfObject:_draggedItem];
}
MPDocument *document = [[[outlineView window] windowController] document];
accepted = [document group:_draggedItem isMoveableToGroup:target];
accepted = ![_draggedItem isAnchestorOfGroup:target];
if( accepted ) {
[_draggedItem moveToGroupUndoable:target atIndex:index];
}

View File

@@ -19,7 +19,7 @@ APPKIT_EXTERN NSString *const MPOutlineViewDidChangeGroupSelection;
@property (readonly, weak) NSOutlineView *outlineView;
@property (weak) IBOutlet HNHGradientView *bottomBar;
@property (weak, readonly) KdbGroup *selectedGroup;
@property (weak, readonly, nonatomic) KdbGroup *selectedGroup;
- (void)clearSelection;
- (void)showOutline;

View File

@@ -33,7 +33,7 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
}
@property (weak) IBOutlet NSOutlineView *outlineView;
@property (weak) IBOutlet NSButton *addGroupButton;
@property (weak) KdbGroup *selectedGroup;
@property (nonatomic, weak) KdbGroup *selectedGroup;
@property (strong) NSTreeController *treeController;
@property (strong) MPOutlineDataSource *datasource;
@@ -89,6 +89,29 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
[_outlineView expandItem:node expandChildren:YES];
}
#pragma mark Custom Setter/Getter
- (void)setDatabaseNameWrapper:(NSString *)databaseNameWrapper {
if(![_databaseNameWrapper isEqualToString:databaseNameWrapper]) {
if([databaseNameWrapper length] == 0) {
_databaseNameWrapper = NSLocalizedString(@"DATABASE", "Default name database");
}
else {
_databaseNameWrapper= [databaseNameWrapper copy];
}
}
}
//- (void)setSelectedGroup:(KdbGroup *)selectedGroup {
// if(_selectedGroup != selectedGroup) {
// _selectedGroup = selectedGroup;
// if([selectedGroup isKindOfClass:[Kdb4Group class]]) {
// MPDocument *document = [[self windowController] document];
// document.treeV4.lastSelectedGroup = ((Kdb4Group *)selectedGroup).uuid;
// }
// }
//}
#pragma mark Notifications
- (void)setupNotifications:(MPDocumentWindowController *)windowController {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_didCreateGroup:) name:MPDocumentDidAddGroupNotification object:[windowController document]];
@@ -114,14 +137,26 @@ 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 Validation
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
MPActionType actionType = [MPActionHelper typeForAction:[menuItem action]];
switch(actionType) {
case MPActionAddEntry:
case MPActionAddGroup:
case MPActionDelete: {
MPDocument *document = [[self windowController] document];
id selected = [self _clickedOrSelectedGroup];
if(!selected) {
return NO;
}
if(selected == document.trash) {
return NO;
}
return ![document isItemTrashed:selected];
}
default:
return YES; // We are only validated for three targets
}
}

View File

@@ -15,6 +15,7 @@ APPKIT_EXTERN NSString *const kMPSettingsKeyClearPasteboardOnQuit;
/* Behaviour */
APPKIT_EXTERN NSString *const kMPSettingsKeyPasswordEncoding;
APPKIT_EXTERN NSString *const kMPSettingsKeyOpenEmptyDatabaseOnLaunch;
APPKIT_EXTERN NSString *const kMPSettingsKeyReopenLastDatabaseOnLaunch;
/* Server Settings */
APPKIT_EXTERN NSString *const kMPSettingsKeyHttpPort;
@@ -25,6 +26,22 @@ APPKIT_EXTERN NSString *const kMPSettingsKeyShowMenuItem;
APPKIT_EXTERN NSString *const kMPSettingsKeyLockOnSleep;
APPKIT_EXTERN NSString *const kMPSettingsKeyIdleLockTimeOut;
/* Autosaving states */
APPKIT_EXTERN NSString *const kMPSettingsKeyShowInspector;
/* Kdb Hide/Show settings */
APPKIT_EXTERN NSString *const kMPSettingsKeyLegacyHideTitle;
APPKIT_EXTERN NSString *const kMPSettingsKeyLegacyHideUsername;
APPKIT_EXTERN NSString *const kMPSettingsKeyLegacyHidePassword;
APPKIT_EXTERN NSString *const kMPSettingsKeyLegacyHideNotes;
APPKIT_EXTERN NSString *const kMPSettingsKeyLegacyHideURL;
/* Document/Key Location store */
APPKIT_EXTERN NSString *const kMPSettingsKeyLastDatabasePath;
/*
APPKIT_EXTERN NSString *const kMPSettingsKeyLastKeyURL;
APPKIT_EXTERN NSString *const kMPSettingsKeyRememberLastKey;
*/
typedef NS_ENUM(NSUInteger, MPPasswordEncoding) {
MPPasswordEncodingUTF8,

View File

@@ -11,11 +11,21 @@
NSString *const kMPSettingsKeyPasteboardClearTimeout = @"ClipboardClearTimeout";
NSString *const kMPSettingsKeyClearPasteboardOnQuit = @"ClearClipboardOnQuit";
NSString *const kMPSettingsKeyOpenEmptyDatabaseOnLaunch = @"OpenEmptyDatabaseOnLaunch";
NSString *const kMPSettingsKeyReopenLastDatabaseOnLaunch = @"ReopenLastDatabaseOnLaunch";
NSString *const kMPSettingsKeyHttpPort =@"HttpPort";
NSString *const kMPSettingsKeyEnableHttpServer = @"EnableHttpServer";
NSString *const kMPSettingsKeyShowMenuItem = @"ShowMenuItem";
NSString *const kMPSettingsKeyLockOnSleep = @"LockOnSleep";
NSString *const kMPSettingsKeyIdleLockTimeOut = @"IdleLockTimeOut";
NSString *const kMPSettingsKeyShowInspector = @"ShowInspector";
NSString *const kMPSettingsKeyLegacyHideTitle = @"LegacyHideTitle";
NSString *const kMPSettingsKeyLegacyHideUsername = @"LegacyHideUsername ";
NSString *const kMPSettingsKeyLegacyHidePassword = @"LegacyHidePassword";
NSString *const kMPSettingsKeyLegacyHideNotes = @"LegacyHideNotes";
NSString *const kMPSettingsKeyLegacyHideURL = @"LegacyHideURL";
NSString *const kMPSettingsKeyLastDatabasePath = @"MPLastDatabasePath";
@implementation MPSettingsHelper
@@ -25,14 +35,21 @@ NSString *const kMPSettingsKeyIdleLockTimeOut = @"IdleLockTimeOut";
+ (NSDictionary *)_standardDefaults {
return @{
kMPSettingsKeyShowInspector: @YES, // Show the Inspector by default
kMPSettingsKeyPasteboardClearTimeout: @30, // 30 seconds
kMPSettingsKeyClearPasteboardOnQuit: @YES,
kMPSettingsKeyOpenEmptyDatabaseOnLaunch: @YES,
kMPSettingsKeyOpenEmptyDatabaseOnLaunch: @NO,
kMPSettingsKeyReopenLastDatabaseOnLaunch: @YES,
kMPSettingsKeyHttpPort: @19455,
kMPSettingsKeyEnableHttpServer: @NO,
kMPSettingsKeyShowMenuItem: @YES,
kMPSettingsKeyLockOnSleep: @YES,
kMPSettingsKeyIdleLockTimeOut: @0 // 5 minutes
kMPSettingsKeyIdleLockTimeOut: @0, // 5 minutes
kMPSettingsKeyLegacyHideNotes: @NO,
kMPSettingsKeyLegacyHidePassword: @YES,
kMPSettingsKeyLegacyHideTitle: @NO,
kMPSettingsKeyLegacyHideURL: @NO,
kMPSettingsKeyLegacyHideUsername: @NO
};
}

View File

@@ -17,7 +17,6 @@
NSString *const MPToolbarItemLock = @"TOOLBAR_LOCK";
NSString *const MPToolbarItemAddGroup = @"TOOLBAR_ADD_GROUP";
NSString *const MPToolbarItemAddEntry = @"TOOLBAR_ADD_ENTRY";
NSString *const MPToolbarItemEdit = @"TOOLBAR_EDIT";
NSString *const MPToolbarItemDelete =@"TOOLBAR_DELETE";
NSString *const MPToolbarItemAction = @"TOOLBAR_ACTION";
NSString *const MPToolbarItemInspector = @"TOOLBAR_INSPECTOR";
@@ -135,7 +134,6 @@ NSString *const MPToolbarItemInspector = @"TOOLBAR_INSPECTOR";
MPToolbarItemAddEntry: NSLocalizedString(@"ADD_ENTRY", @""),
MPToolbarItemAddGroup: NSLocalizedString(@"ADD_GROUP", @""),
MPToolbarItemDelete: NSLocalizedString(@"DELETE", @""),
MPToolbarItemEdit: NSLocalizedString(@"EDIT", @""),
MPToolbarItemInspector: NSLocalizedString(@"INSPECTOR", @"")
};
return labelDict[identifier];
@@ -146,7 +144,6 @@ NSString *const MPToolbarItemInspector = @"TOOLBAR_INSPECTOR";
MPToolbarItemAddEntry: @(MPActionAddEntry),
MPToolbarItemAddGroup: @(MPActionAddGroup),
MPToolbarItemDelete: @(MPActionDelete),
MPToolbarItemEdit: @(MPActionEdit),
MPToolbarItemInspector: @(MPActionToggleInspector)
};
MPActionType actionType = (MPActionType)[actionDict[identifier] integerValue];

View File

@@ -44,11 +44,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.3.2</string>
<string>0.3.7</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>2506</string>
<string>2521</string>
<key>LSMinimumSystemVersion</key>
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
<key>NSHumanReadableCopyright</key>

View File

@@ -16,15 +16,38 @@
- (NSString *)humanized {
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [calendar components:NSMinuteCalendarUnit|NSHourCalendarUnit|NSDayCalendarUnit fromDate:self toDate:[NSDate date] options:0];
if([components day] > 1) {
NSDateComponents *components = [calendar components:NSMinuteCalendarUnit|NSHourCalendarUnit|NSDayCalendarUnit|NSWeekCalendarUnit|NSMonthCalendarUnit fromDate:self toDate:[NSDate date] options:0];
/* More than one month in the past, give full date */
if([components month] > 1) {
return [NSDateFormatter localizedStringFromDate:self
dateStyle:NSDateFormatterShortStyle
timeStyle:NSDateFormatterShortStyle];
}
if([components day] == 1) {
NSUInteger weeks = [components week];
/* More than one week, less than a month */
if(weeks > 1) {
NSString *weekTemplate = NSLocalizedString(@"%ld_WEEKS_AGO", "% Weeks ago");
return [NSString stringWithFormat:weekTemplate, weeks];
}
/* One week or more */
if( weeks == 1) {
return NSLocalizedString(@"ONE_WEEK_AGO", "one week ago");
}
/* Last week */
NSUInteger days = [components day];
if(days > 3) {
return NSLocalizedString(@"LAST_WEEK", "last week");
}
/* 1-3 days */
if(days > 1 ) {
NSString *daysTemplate = NSLocalizedString(@"%ld_DAYS_AGO", "% days ago");
return [NSString stringWithFormat:daysTemplate, days];
}
/* Yesterday */
if(days == 1) {
return NSLocalizedString(@"YESTERDAY", "Yesterday");
}
/* Hours ago */
if([components hour] > 1) {
NSString *hourTemplate = NSLocalizedString(@"%ld_HOURS_AGO", "% Hours ago");
return [NSString stringWithFormat:hourTemplate, [components hour]];

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1070</int>
<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>
@@ -381,8 +381,8 @@
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="608946496">
<int key="NSCellFlags">-1804599231</int>
<int key="NSCellFlags2">272630784</int>
<int key="NSCellFlags">-2075131840</int>
<int key="NSCellFlags2">-1874852864</int>
<string key="NSContents"/>
<reference key="NSSupport" ref="510117885"/>
<string key="NSCellIdentifier">_NS:9</string>
@@ -1189,6 +1189,7 @@
<object class="IBObjectRecord">
<int key="objectID">183</int>
<reference key="object" ref="608946496"/>
<array class="NSMutableArray" key="children"/>
<reference key="parent" ref="240019321"/>
</object>
<object class="IBObjectRecord">
@@ -1987,7 +1988,7 @@
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">623</int>
<int key="maxID">626</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -2003,11 +2004,16 @@
<string key="className">MPPasswordCreatorViewController</string>
<string key="superclassName">MPViewController</string>
<dictionary class="NSMutableDictionary" key="actions">
<string key="_cancel:">id</string>
<string key="_generatePassword:">id</string>
<string key="_toggleCharacters:">id</string>
<string key="_usePassword:">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="_generatePassword:">
<string key="name">_generatePassword:</string>
<string key="candidateClassName">id</string>
@@ -2022,7 +2028,6 @@
</object>
</dictionary>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="_cancel">NSButton</string>
<string key="addPasswordToPasteboardButton">NSButton</string>
<string key="customButton">NSButton</string>
<string key="customCharactersTextField">NSTextField</string>
@@ -2035,10 +2040,6 @@
<string key="upperCaseButton">NSButton</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="_cancel">
<string key="name">_cancel</string>
<string key="candidateClassName">NSButton</string>
</object>
<object class="IBToOneOutletInfo" key="addPasswordToPasteboardButton">
<string key="name">addPasswordToPasteboardButton</string>
<string key="candidateClassName">NSButton</string>
@@ -2105,9 +2106,9 @@
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
<integer value="1070" key="NS.object.0"/>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3</string>
<real value="4600" key="NS.object.0"/>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>

View File

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

View File

@@ -0,0 +1,19 @@
//
// StringField+Validation.m
// MacPass
//
// Created by Michael Starke on 19.07.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import "StringField+Validation.h"
#import "Kdb4Entry+MPAdditions.h"
@implementation StringField (Validation)
- (BOOL)validateValue:(inout __autoreleasing id *)ioValue forKey:(NSString *)inKey error:(out NSError *__autoreleasing *)outError {
*ioValue = [self.entry uniqueKeyForProposal:*ioValue];
return YES;
}
@end

View File

@@ -1,7 +1,7 @@
{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;\red52\green110\blue183;\red38\green38\blue38;}
\paperw11900\paperh16840\vieww28040\viewh7240\viewkind0
\paperw11900\paperh16840\vieww19440\viewh14240\viewkind0
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720
\f0\b\fs24 \cf0 Projekt Webseite:\
@@ -37,6 +37,7 @@ You should have received a copy of the GNU General Public License along with thi
\b0 \cf3 \
Copyright \'a9 2012 Robbie Hanson. Alle Rechte vorbehalten.\
\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720
{\field{\*\fldinst{HYPERLINK "https://github.com/MiniKeePass/MiniKeePass"}}{\fldrslt \cf2 MiniKeePass}}\
Copyright \'a9 2011 Jason Rush und John Flanagan. Alle Rechte vorbehalten.\
\
@@ -50,9 +51,20 @@ Copyright \'a9 2011, Alex Rozanski. Alle Rechte vorbehalten.\
\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720
{\field{\*\fldinst{HYPERLINK "http://stackoverflow.com/questions/11386876/how-to-encode-and-decode-files-as-base64-in-cocoa-objective-c"}}{\fldrslt \cf3 Base64 Encoding Category}}\
Copyright @2013, {\field{\*\fldinst{HYPERLINK "http://stackoverflow.com/users/200321/denis2342"}}{\fldrslt denis2342}}\
Copyright \'a92013, {\field{\*\fldinst{HYPERLINK "http://stackoverflow.com/users/200321/denis2342"}}{\fldrslt denis2342}}\
\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720
{\field{\*\fldinst{HYPERLINK "http://www.cocoadev.com/index.pl?NSDataCategory"}}{\fldrslt \cf3 NSData+Gzip}}\
Basierend auf dem Code im CocoaDev Wiki\
}
\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720
{\field{\*\fldinst{HYPERLINK "https://github.com/karelia/SecurityInterface"}}{\fldrslt \cf3 KSPasswordField}}\cf3 \kerning1\expnd0\expndtw3
\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720
\cf3 \kerning1\expnd0\expndtw0 Quelltext wird in HNHRoundedSecureTextField verwendet\cf3 \kerning1\expnd0\expndtw3
\
\cf3 \kerning1\expnd0\expndtw0 Copyright \'a92012 Mike Abdullah, Karelia Software. Alle Rechte vorbehalten.\
\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720
{\field{\*\fldinst{HYPERLINK "https://github.com/AlanQuatermain/aqtoolkit"}}{\fldrslt \cf3 NSData+CommonCrypto}}\
Copyright \'a92008-2009 Jim Dovey, Alle Rechte vorbehalten.}

View File

@@ -1,30 +1,48 @@
/* Class = "NSMenu"; title = "OtherViews"; ObjectID = "421"; */
"421.title" = "OtherViews";
/* Class = "NSMenu"; title = "ClipboardClearInterval"; ObjectID = "421"; */
"421.title" = "ClipboardClearInterval";
/* Class = "NSMenuItem"; title = "10 Seconds"; ObjectID = "422"; */
"422.title" = "10 Sekunden";
/* Class = "NSMenuItem"; title = "after 10 Seconds"; ObjectID = "422"; */
"422.title" = "nach 10 Sekunden";
/* Class = "NSMenuItem"; title = "30 Seconds"; ObjectID = "423"; */
"423.title" = "30 Sekunden";
/* Class = "NSMenuItem"; title = "after 30 Seconds"; ObjectID = "423"; */
"423.title" = "nach 30 Sekunden";
/* Class = "NSMenuItem"; title = "1 Minute"; ObjectID = "424"; */
"424.title" = "1 Minute";
/* Class = "NSMenuItem"; title = "after 1 Minute"; ObjectID = "424"; */
"424.title" = "nach 1 Minute";
/* Class = "NSMenuItem"; title = "Never"; ObjectID = "429"; */
"429.title" = "Nie";
/* Class = "NSTextFieldCell"; title = "Clear Copied Items"; ObjectID = "432"; */
"432.title" = "Zwischenablage Leere";
"432.title" = "Leere Zwischenablage";
/* Class = "NSButtonCell"; title = "Clear Clipboard on Quit"; ObjectID = "448"; */
"448.title" = "Zwischenablage beim Beenden leeren";
/* Class = "NSBox"; title = "Clipboard"; ObjectID = "465"; */
"465.title" = "Zwischenablage";
/* Class = "NSBox"; title = "Security"; ObjectID = "465"; */
"465.title" = "Sicherheit";
/* Class = "NSButtonCell"; title = "Open empty database on launch"; ObjectID = "527"; */
"527.title" = "Leere Datenbank beim Programmstart öffnen";
/* Class = "NSButtonCell"; title = "Reopen last Database after Launch"; ObjectID = "531"; */
"531.title" = "Letzte Datenbank beim Start wieder öffnen";
/* Class = "NSButtonCell"; title = "Open empty database on activate"; ObjectID = "531"; */
"531.title" = "Lerre Datenbank beim Aktiveren öffnen";
/* Class = "NSMenu"; title = "LockTimes"; ObjectID = "586"; */
"586.title" = "LockTimes";
/* Class = "NSMenuItem"; title = "for 1 Minute"; ObjectID = "588"; */
"588.title" = "für 1 Minute";
/* Class = "NSMenuItem"; title = "for 5 Minutes"; ObjectID = "589"; */
"589.title" = "für 5 Minuten";
/* Class = "NSMenuItem"; title = "for 15 Minutes"; ObjectID = "603"; */
"603.title" = "für 15 Minuten";
/* Class = "NSButtonCell"; title = "Lock after sleep"; ObjectID = "631"; */
"631.title" = "Datenbank im Ruhezustand sperren";
/* Class = "NSMenuItem"; title = "Never"; ObjectID = "804"; */
"804.title" = "Nie";
/* Class = "NSTextFieldCell"; title = "Lock while idle"; ObjectID = "806"; */
"806.title" = "Sperren nach Inaktivität";

Binary file not shown.

View File

@@ -40,6 +40,7 @@ You should have received a copy of the GNU General Public License along with thi
{\field{\*\fldinst{HYPERLINK "https://github.com/robbiehanson/KissXML"}}{\fldrslt \cf2 KissXML}}\cf3 \
Copyright \'a9 2012 Robbie Hanson. All rights reserved.\
\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720
{\field{\*\fldinst{HYPERLINK "https://github.com/MiniKeePass/MiniKeePass"}}{\fldrslt \cf2 MiniKeePass}}\
Copyright \'a9 2011 Jason Rush and John Flanagan. All rights reserved.\
\
@@ -53,9 +54,17 @@ Copyright \'a9 2011, Alex Rozanski. All rights reserved.\
\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720
{\field{\*\fldinst{HYPERLINK "http://stackoverflow.com/questions/11386876/how-to-encode-and-decode-files-as-base64-in-cocoa-objective-c"}}{\fldrslt \cf3 NSData+Base64}}\
Copyright @2013, {\field{\*\fldinst{HYPERLINK "http://stackoverflow.com/users/200321/denis2342"}}{\fldrslt denis2342}}\
Copyright \'a92013, {\field{\*\fldinst{HYPERLINK "http://stackoverflow.com/users/200321/denis2342"}}{\fldrslt denis2342}}\
\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720
{\field{\*\fldinst{HYPERLINK "http://www.cocoadev.com/index.pl?NSDataCategory"}}{\fldrslt \cf3 NSData+Gzip}}\
Extracted from code on the CocoaDev Wiki\
}
\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720
{\field{\*\fldinst{HYPERLINK "https://github.com/karelia/SecurityInterface"}}{\fldrslt \cf3 KSPasswordField}}\
Code reused in HNHRoundedSecureTextField\
Copyright \'a92012 Mike Abdullah, Karelia Software. All rights reserved.\
\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720
{\field{\*\fldinst{HYPERLINK "https://github.com/AlanQuatermain/aqtoolkit"}}{\fldrslt \cf3 NSData+CommonCrypto}}\
Copyright \'a92008-2009 Jim Dovey, All rights reserved.}

View File

@@ -2,14 +2,14 @@
/* Class = "NSMenu"; title = "ClipboardClearInterval"; ObjectID = "421"; */
"421.title" = "ClipboardClearInterval";
/* Class = "NSMenuItem"; title = "10 Seconds"; ObjectID = "422"; */
"422.title" = "10 Seconds";
/* Class = "NSMenuItem"; title = "after 10 Seconds"; ObjectID = "422"; */
"422.title" = "after 10 Seconds";
/* Class = "NSMenuItem"; title = "30 Seconds"; ObjectID = "423"; */
"423.title" = "30 Seconds";
/* Class = "NSMenuItem"; title = "after 30 Seconds"; ObjectID = "423"; */
"423.title" = "after 30 Seconds";
/* Class = "NSMenuItem"; title = "1 Minute"; ObjectID = "424"; */
"424.title" = "1 Minute";
/* Class = "NSMenuItem"; title = "after 1 Minute"; ObjectID = "424"; */
"424.title" = "after 1 Minute";
/* Class = "NSMenuItem"; title = "Never"; ObjectID = "429"; */
"429.title" = "Never";
@@ -23,26 +23,26 @@
/* Class = "NSBox"; title = "Security"; ObjectID = "465"; */
"465.title" = "Security";
/* Class = "NSButtonCell"; title = "Open empty database on launch"; ObjectID = "527"; */
"527.title" = "Open empty database on launch";
/* Class = "NSButtonCell"; title = "Open empty database on activate"; ObjectID = "531"; */
"531.title" = "Open empty database on activate";
/* Class = "NSButtonCell"; title = "Reopen last Database after Launch"; ObjectID = "531"; */
"531.title" = "Reopen last Database after Launch";
/* Class = "NSMenu"; title = "LockTimes"; ObjectID = "586"; */
"586.title" = "LockTimes";
/* Class = "NSMenuItem"; title = "1 Minute"; ObjectID = "588"; */
"588.title" = "1 Minute";
/* Class = "NSMenuItem"; title = "for 1 Minute"; ObjectID = "588"; */
"588.title" = "for 1 Minute";
/* Class = "NSMenuItem"; title = "5 Minutes"; ObjectID = "589"; */
"589.title" = "5 Minutes";
/* Class = "NSMenuItem"; title = "for 5 Minutes"; ObjectID = "589"; */
"589.title" = "for 5 Minutes";
/* Class = "NSMenuItem"; title = "15 Minutes"; ObjectID = "603"; */
"603.title" = "15 Minutes";
/* Class = "NSButtonCell"; title = "Lock while idle for"; ObjectID = "606"; */
"606.title" = "Lock while idle for";
/* Class = "NSMenuItem"; title = "for 15 Minutes"; ObjectID = "603"; */
"603.title" = "for 15 Minutes";
/* Class = "NSButtonCell"; title = "Lock after sleep"; ObjectID = "631"; */
"631.title" = "Lock after sleep";
/* Class = "NSMenuItem"; title = "Never"; ObjectID = "804"; */
"804.title" = "Never";
/* Class = "NSTextFieldCell"; title = "Lock while idle"; ObjectID = "806"; */
"806.title" = "Lock while idle";

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 803 B

View File

@@ -0,0 +1,16 @@
//
// KPKIconLoading.h
// MacPass
//
// Created by Michael Starke on 20.07.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import <SenTestingKit/SenTestingKit.h>
@interface KPKIconLoading : SenTestCase {
NSImage *_image;
NSData *_imageData;
}
@end

View File

@@ -0,0 +1,43 @@
//
// KPKIconLoading.m
// MacPass
//
// Created by Michael Starke on 20.07.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import "KPKIconLoading.h"
#import "KPKIcon.h"
@implementation KPKIconLoading
- (void)setUp {
NSBundle *myBundle = [NSBundle bundleForClass:[self class]];
_image = [myBundle imageForResource:@"image.png"];
_imageData = [[[_image representations] lastObject] representationUsingType:NSPNGFileType properties:nil];
}
- (void)tearDown {
_image = nil;
_imageData = nil;
}
- (void)testLoading {
NSBundle *myBundle = [NSBundle bundleForClass:[self class]];
NSURL *imageURL = [myBundle URLForImageResource:@"image.png"];
KPKIcon *icon = [[KPKIcon alloc] initWithImageAtURL:imageURL];
STAssertNotNil(icon, @"Icon should have been loaded");
NSString *iconString = [icon encodedString];
KPKIcon *iconFromString = [[KPKIcon alloc] initWithUUID:[NSUUID UUID] encodedString:iconString];
STAssertTrue([iconString isEqualToString:[iconFromString encodedString]], @"Encoding and Decoding should result in the same string");
Class repClass = [NSBitmapImageRep class];
NSImageRep *imageRep = [[icon.image representations] lastObject];
STAssertNotNil(imageRep, @"One image rep shoudl be there");
STAssertTrue([imageRep isKindOfClass:repClass], @"Representation should be bitmap");
NSBitmapImageRep *bitmapRep = (NSBitmapImageRep *)imageRep;
NSData *pngData = [bitmapRep representationUsingType:NSPNGFileType properties:nil];
STAssertTrue([pngData isEqualToData:_imageData], @"Image and PNG data shoudl be identical");
}
@end

View File

@@ -0,0 +1,19 @@
//
// KPKTreeLoadingTest.h
// MacPass
//
// Created by Michael Starke on 20.07.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import <SenTestingKit/SenTestingKit.h>
@class KPKPassword;
@interface KPKTreeLoadingTest : SenTestCase {
@private
NSData *_data;
KPKPassword *_password;
}
@end

View File

@@ -0,0 +1,33 @@
//
// KPKTreeLoadingTest.m
// MacPass
//
// Created by Michael Starke on 20.07.13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import "KPKTreeLoadingTest.h"
#import "KPKTreeLoader.h"
#import "KPKPassword.h"
@implementation KPKTreeLoadingTest
- (void)setUp {
NSBundle *myBundle = [NSBundle bundleForClass:[self class]];
NSURL *url = [myBundle URLForResource:@"Test_Password_1234" withExtension:@"kdbx"];
_data = [NSData dataWithContentsOfURL:url];
_password = [[KPKPassword alloc] initWithPassword:@"1234" key:nil];
}
- (void)tearDown {
_data = nil;
_password = nil;
}
- (void)testLoading {
KPKTreeLoader *loader = [[KPKTreeLoader alloc] initWithData:_data password:_password];
KPKTree *tree = [loader loadTree:NULL];
STAssertNil(tree, @"Loading should broken");
}
@end

View File

@@ -83,3 +83,5 @@ This Project is based upon the following work:
[CocoaHTTPServer](https://github.com/robbiehanson/CocoaHTTPServer ) Copyright 2011, Deusty, LLC. All rights reserved.
[KSPasswordField](https://github.com/karelia/SecurityInterface) Copyright 2012 Mike Abdullah, Karelia Software. All rights reserved.
See submodules for additional Licenses