Extracted context bar for trash, history and filter browsing. Some regressions in focus handling were introduced. History tab will go away as this will be incorporated in the entry comparable to searching. Code cleanup. Moved copying to KeePassKit

This commit is contained in:
michael starke
2013-12-18 02:29:25 +01:00
parent 21355101ed
commit 92d963a9ef
27 changed files with 800 additions and 577 deletions

2
HNHUi

Submodule HNHUi updated: 435f37c254...61feaeb151

View File

@@ -36,11 +36,11 @@
4C1842C6179BF52100E2F5BC /* KPKLegacyHeaderReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1842C5179BF52000E2F5BC /* KPKLegacyHeaderReader.m */; };
4C1842D0179C64DD00E2F5BC /* KPKLegacyTreeCryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1842CF179C64DD00E2F5BC /* KPKLegacyTreeCryptor.m */; };
4C1842D3179C64F000E2F5BC /* KPKXmlTreeCryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1842D2179C64EF00E2F5BC /* KPKXmlTreeCryptor.m */; };
4C18816C179E06920045C5B7 /* TrashBar.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C18816B179E06920045C5B7 /* TrashBar.xib */; };
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 */; };
4C1DDCDD1711ECEB00C98DA3 /* PasswordCreatorWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C1DDCDC1711ECEB00C98DA3 /* PasswordCreatorWindow.xib */; };
4C1E9885185F71A800943563 /* MPContextBarViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1E9884185F71A800943563 /* MPContextBarViewController.m */; };
4C1FA07B18231900003A3F8C /* MPDocument+Autotype.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1FA07A18231900003A3F8C /* MPDocument+Autotype.m */; };
4C224B4217DFCB2400FF6AEE /* MPNumericalInputFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C224B4117DFCB2400FF6AEE /* MPNumericalInputFormatter.m */; };
4C245B76176E1E3D0086100E /* DDData.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C245A6A176E1E3C0086100E /* DDData.m */; };
@@ -88,7 +88,7 @@
4C3BD51516D276F800389F1F /* MPToolbarDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C3BD51416D276F800389F1F /* MPToolbarDelegate.m */; };
4C3D4C0817594CA40038DAAC /* HNHSeparator.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C3D4C0717594CA40038DAAC /* HNHSeparator.m */; };
4C3F28541791EDFD00703281 /* KPKErrors.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C3F28531791EDFD00703281 /* KPKErrors.m */; };
4C3FFD9E16DAF60600DF9186 /* FilterBar.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C3FFD9D16DAF60600DF9186 /* FilterBar.xib */; };
4C3FFD9E16DAF60600DF9186 /* ContextBar.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C3FFD9D16DAF60600DF9186 /* ContextBar.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 */; };
@@ -194,8 +194,6 @@
4C8A173D1790AA41008B5C17 /* NSData+Keyfile.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8A173C1790AA41008B5C17 /* NSData+Keyfile.m */; };
4C8B36AB17A6ED4B005E1FF1 /* MPOutlineContextMenuDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8B36AA17A6ED4B005E1FF1 /* MPOutlineContextMenuDelegate.m */; };
4C8FECC816D57E3200BF26CF /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C8FECC716D57E3200BF26CF /* QuartzCore.framework */; };
4C964D44184BE8720050B74E /* KPKEntry+TemplateCopy.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C964D43184BE8720050B74E /* KPKEntry+TemplateCopy.m */; };
4C964D47184BE9090050B74E /* KPKGroup+TemplateCopy.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C964D46184BE9090050B74E /* KPKGroup+TemplateCopy.m */; };
4C96D15417A12E4F00D931FA /* 99_CreatedTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4C96D15317A12E4F00D931FA /* 99_CreatedTemplate.pdf */; };
4C9D6AA917615199001C660C /* HNHRoundedSecureTextFieldCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C9D6AA817615199001C660C /* HNHRoundedSecureTextFieldCell.m */; };
4CA08DA017A831B200A6544B /* MPAddEntryContextMenuDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CA08D9F17A831B200A6544B /* MPAddEntryContextMenuDelegate.m */; };
@@ -278,6 +276,7 @@
4CFC873B179DEDF3000DFC03 /* KPKMetaData.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CFC873A179DEDF3000DFC03 /* KPKMetaData.m */; };
4CFC873E179DF200000DFC03 /* KPKTimeInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CFC873D179DF200000DFC03 /* KPKTimeInfo.m */; };
4CFC8743179DFD3E000DFC03 /* KPKTestXmlLoading.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CFC8742179DFD3E000DFC03 /* KPKTestXmlLoading.m */; };
4CFDDDE9185E92A600A9E7F1 /* HNHTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CFDDDE8185E92A600A9E7F1 /* HNHTextView.m */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@@ -340,12 +339,13 @@
4C1842D2179C64EF00E2F5BC /* KPKXmlTreeCryptor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = KPKXmlTreeCryptor.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
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>"; };
4C18816B179E06920045C5B7 /* TrashBar.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = TrashBar.xib; 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>"; };
4C19E502178E2871002F2CD0 /* MPDatabasePasswordAndKeyfile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPDatabasePasswordAndKeyfile.m; sourceTree = "<group>"; };
4C1DDCDC1711ECEB00C98DA3 /* PasswordCreatorWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PasswordCreatorWindow.xib; sourceTree = "<group>"; };
4C1E9883185F71A800943563 /* MPContextBarViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPContextBarViewController.h; sourceTree = "<group>"; };
4C1E9884185F71A800943563 /* MPContextBarViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPContextBarViewController.m; sourceTree = "<group>"; };
4C1FA07918231900003A3F8C /* MPDocument+Autotype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MPDocument+Autotype.h"; sourceTree = "<group>"; };
4C1FA07A18231900003A3F8C /* MPDocument+Autotype.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MPDocument+Autotype.m"; sourceTree = "<group>"; };
4C224B4017DFCB2300FF6AEE /* MPNumericalInputFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPNumericalInputFormatter.h; sourceTree = "<group>"; };
@@ -434,7 +434,7 @@
4C3D4C0717594CA40038DAAC /* HNHSeparator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HNHSeparator.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>"; };
4C3FFD9D16DAF60600DF9186 /* FilterBar.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = FilterBar.xib; sourceTree = "<group>"; };
4C3FFD9D16DAF60600DF9186 /* ContextBar.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ContextBar.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>"; };
@@ -626,10 +626,6 @@
4C8B36A917A6ED4B005E1FF1 /* MPOutlineContextMenuDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPOutlineContextMenuDelegate.h; sourceTree = "<group>"; };
4C8B36AA17A6ED4B005E1FF1 /* MPOutlineContextMenuDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPOutlineContextMenuDelegate.m; sourceTree = "<group>"; };
4C8FECC716D57E3200BF26CF /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
4C964D42184BE8720050B74E /* KPKEntry+TemplateCopy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "KPKEntry+TemplateCopy.h"; sourceTree = "<group>"; };
4C964D43184BE8720050B74E /* KPKEntry+TemplateCopy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "KPKEntry+TemplateCopy.m"; sourceTree = "<group>"; };
4C964D45184BE9090050B74E /* KPKGroup+TemplateCopy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "KPKGroup+TemplateCopy.h"; sourceTree = "<group>"; };
4C964D46184BE9090050B74E /* KPKGroup+TemplateCopy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "KPKGroup+TemplateCopy.m"; sourceTree = "<group>"; };
4C96D15317A12E4F00D931FA /* 99_CreatedTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; name = 99_CreatedTemplate.pdf; path = Icons/99_CreatedTemplate.pdf; sourceTree = "<group>"; };
4C9D6AA717615199001C660C /* HNHRoundedSecureTextFieldCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HNHRoundedSecureTextFieldCell.h; sourceTree = "<group>"; };
4C9D6AA817615199001C660C /* HNHRoundedSecureTextFieldCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HNHRoundedSecureTextFieldCell.m; sourceTree = "<group>"; };
@@ -787,6 +783,8 @@
4CFC873F179DF295000DFC03 /* KPKTimerecording.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KPKTimerecording.h; sourceTree = "<group>"; };
4CFC8741179DFD3E000DFC03 /* KPKTestXmlLoading.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KPKTestXmlLoading.h; sourceTree = "<group>"; };
4CFC8742179DFD3E000DFC03 /* KPKTestXmlLoading.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KPKTestXmlLoading.m; sourceTree = "<group>"; };
4CFDDDE7185E92A600A9E7F1 /* HNHTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HNHTextView.h; sourceTree = "<group>"; };
4CFDDDE8185E92A600A9E7F1 /* HNHTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HNHTextView.m; sourceTree = "<group>"; };
6E719715172058BA00E4C5FC /* MPDatabaseVersion.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MPDatabaseVersion.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
@@ -843,11 +841,10 @@
children = (
4CF78060176E75180032EE71 /* Settings */,
4C25D58616CF0FAA00F6806C /* EntryView.xib */,
4C3FFD9D16DAF60600DF9186 /* ContextBar.xib */,
4C77E37B15B84A240093A587 /* MainMenu.xib */,
4C61EA0416D2FFE200AC519E /* OutlineView.xib */,
4CF78061176E752E0032EE71 /* PasswordInputs */,
4C3FFD9D16DAF60600DF9186 /* FilterBar.xib */,
4C18816B179E06920045C5B7 /* TrashBar.xib */,
4C4B7EF517A46815000234C7 /* Inspector */,
4CE39AC016ECE359000FE29D /* IconSelection.xib */,
4C2C8B331787500E009649F3 /* UnprotectedWarningView.xib */,
@@ -884,10 +881,6 @@
4CC6DB7917D23719002C6091 /* KPKNode+IconImage.m */,
4CEED1C417D7BD0E007180F1 /* NSError+Messages.h */,
4CEED1C517D7BD0E007180F1 /* NSError+Messages.m */,
4C964D42184BE8720050B74E /* KPKEntry+TemplateCopy.h */,
4C964D43184BE8720050B74E /* KPKEntry+TemplateCopy.m */,
4C964D45184BE9090050B74E /* KPKGroup+TemplateCopy.h */,
4C964D46184BE9090050B74E /* KPKGroup+TemplateCopy.m */,
);
name = Categories;
sourceTree = "<group>";
@@ -1386,6 +1379,8 @@
4C4B7EF117A467FC000234C7 /* MPEntryInspectorViewController.m */,
4C0F647917B6BC9C00D9522A /* MPSavePanelAccessoryViewController.h */,
4C0F647A17B6BC9C00D9522A /* MPSavePanelAccessoryViewController.m */,
4C1E9883185F71A800943563 /* MPContextBarViewController.h */,
4C1E9884185F71A800943563 /* MPContextBarViewController.m */,
);
name = "View Controller";
sourceTree = "<group>";
@@ -1482,6 +1477,8 @@
4C52A243177D7B9F0000D88F /* HNHScrollView.m */,
4C2671AB17A7D8FC00F3A645 /* HNHColorWell.h */,
4C2671AC17A7D8FC00F3A645 /* HNHColorWell.m */,
4CFDDDE7185E92A600A9E7F1 /* HNHTextView.h */,
4CFDDDE8185E92A600A9E7F1 /* HNHTextView.m */,
);
path = HNHUi;
sourceTree = "<group>";
@@ -1831,7 +1828,7 @@
4CD78AC016D155FF00768A1D /* 11_CameraTemplate.pdf in Resources */,
4C61EA0516D2FFE200AC519E /* OutlineView.xib in Resources */,
4CB9339916D3A0DD00A13B5D /* Credits.rtf in Resources */,
4C3FFD9E16DAF60600DF9186 /* FilterBar.xib in Resources */,
4C3FFD9E16DAF60600DF9186 /* ContextBar.xib in Resources */,
4C431BCF16E2BAB000700A81 /* OverlayWindow.xib in Resources */,
4C17F105184E630200E85625 /* 14_BatteryTemplate.pdf in Resources */,
4C76156D1764C0E20015A1A6 /* InspectorView.xib in Resources */,
@@ -1854,7 +1851,6 @@
4C52A88F1788628B00868229 /* 13_KeysTemplate.pdf in Resources */,
4C52A8901788628B00868229 /* 18_DisplayTemplate.pdf in Resources */,
4C52A892178863B000868229 /* 68_PhoneTemplate.pdf in Resources */,
4C18816C179E06920045C5B7 /* TrashBar.xib in Resources */,
4C96D15417A12E4F00D931FA /* 99_CreatedTemplate.pdf in Resources */,
4C4B7EEA17A45EC6000234C7 /* DatePickingView.xib in Resources */,
4C4B7EEF17A467E1000234C7 /* GroupInspectorView.xib in Resources */,
@@ -1920,6 +1916,7 @@
files = (
4C77E37315B84A240093A587 /* main.m in Sources */,
4CBA2ABA17074C07006D8139 /* MPSettingsHelper.m in Sources */,
4CFDDDE9185E92A600A9E7F1 /* HNHTextView.m in Sources */,
4C77E37A15B84A240093A587 /* MPAppDelegate.m in Sources */,
4CAD747B15B887FD00104512 /* DDXMLElementAdditions.m in Sources */,
4CAD747C15B887FD00104512 /* NSString+DDXML.m in Sources */,
@@ -1946,7 +1943,6 @@
4C89F524182FB4740069C73C /* MPAutotypeCommand.m in Sources */,
4CFC53BF16E94729007396BE /* MPShadowBox.m in Sources */,
4C888C9316EB6F5E003D34A1 /* MPToolbarItem.m in Sources */,
4C964D47184BE9090050B74E /* KPKGroup+TemplateCopy.m in Sources */,
4C888C9716EB754B003D34A1 /* MPActionHelper.m in Sources */,
4C811C8316ECD06E00C4BAC6 /* MPKeyfilePathControlDelegate.m in Sources */,
4CE39ABF16ECE34A000FE29D /* MPIconSelectViewController.m in Sources */,
@@ -1995,7 +1991,6 @@
4C245BED176E1E3D0086100E /* DDFileLogger.m in Sources */,
4C245BEE176E1E3D0086100E /* DDLog.m in Sources */,
4C245BEF176E1E3D0086100E /* DDTTYLogger.m in Sources */,
4C964D44184BE8720050B74E /* KPKEntry+TemplateCopy.m in Sources */,
4C245BF0176E1E3D0086100E /* ContextFilterLogFormatter.m in Sources */,
4C245BF1176E1E3D0086100E /* DispatchQueueLogFormatter.m in Sources */,
4CF78057176E5CFD0032EE71 /* MPConnection.m in Sources */,
@@ -2056,6 +2051,7 @@
4CCEDE32179F5B6C008402BE /* KPKDataStreamReader.m in Sources */,
4C17D8E517A1C780006C8C1E /* MPDocumentWindowDelegate.m in Sources */,
4C63B8FB17A3154D0091BD72 /* MPContextToolbarButton.m in Sources */,
4C1E9885185F71A800943563 /* MPContextBarViewController.m in Sources */,
4C1FA07B18231900003A3F8C /* MPDocument+Autotype.m in Sources */,
4C4B7EE917A45EC6000234C7 /* MPDatePickingViewController.m in Sources */,
4C4B7EEE17A467E1000234C7 /* MPGroupInspectorViewController.m in Sources */,

224
MacPass/ContextBar.xib Normal file
View File

@@ -0,0 +1,224 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="4514" systemVersion="13A603" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment defaultVersion="1080" identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="4514"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="MPContextBarViewController">
<connections>
<outlet property="filterDoneButton" destination="61" id="o8k-20-QUA"/>
<outlet property="filterLabelTextField" destination="6" id="60"/>
<outlet property="filterPasswordButton" destination="96" id="101"/>
<outlet property="filterSearchField" destination="80" id="95"/>
<outlet property="filterTitleButton" destination="2" id="57"/>
<outlet property="filterURLButton" destination="40" id="59"/>
<outlet property="filterUsernameButton" destination="35" id="58"/>
<outlet property="historyBar" destination="S8L-rB-h0h" id="6yZ-El-fVs"/>
<outlet property="trashBar" destination="DXf-SC-gVG" id="3aZ-Xc-VDk"/>
<outlet property="view" destination="8MB-fC-M2Q" id="wYX-Cc-yoV"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application"/>
<tabView type="noTabsNoBorder" translatesAutoresizingMaskIntoConstraints="NO" id="8MB-fC-M2Q">
<rect key="frame" x="0.0" y="0.0" width="576" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<font key="font" metaFont="system"/>
<tabViewItems>
<tabViewItem label="Filter" identifier="1" id="Ud6-Nz-6PS">
<view key="view" id="caQ-XO-RkM">
<rect key="frame" x="0.0" y="0.0" width="576" height="30"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="1" customClass="HNHGradientView">
<rect key="frame" x="0.0" y="0.0" width="576" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="2">
<rect key="frame" x="57" y="5" width="42" height="19"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="recessed" title="Title" bezelStyle="recessed" alignment="center" controlSize="small" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="3">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="systemBold" size="12"/>
</buttonCell>
<connections>
<action selector="toggleFilterSpace:" target="-2" id="5tf-b0-MfH"/>
</connections>
</button>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="6">
<rect key="frame" x="6" y="7" width="45" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Search:" id="7">
<font key="font" metaFont="smallSystemBold"/>
<color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="35">
<rect key="frame" x="107" y="6" width="77" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="recessed" title="Username" bezelStyle="recessed" alignment="center" controlSize="small" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="36">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="systemBold" size="12"/>
</buttonCell>
<connections>
<action selector="toggleFilterSpace:" target="-2" id="eVq-ir-2ZF"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="40">
<rect key="frame" x="192" y="6" width="38" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="recessed" title="URL" bezelStyle="recessed" alignment="center" controlSize="small" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="41">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="systemBold" size="12"/>
</buttonCell>
<connections>
<action selector="toggleFilterSpace:" target="-2" id="XEz-fj-0wx"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="61">
<rect key="frame" x="526" y="6" width="42" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="roundRect" title="Done" bezelStyle="roundedRect" alignment="center" controlSize="small" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="62">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="smallSystem"/>
</buttonCell>
</button>
<searchField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="80">
<rect key="frame" x="418" y="6" width="100" height="19"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="93"/>
</constraints>
<searchFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="81">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
<connections>
<outlet property="delegate" destination="-2" id="Y78-7K-e9c"/>
</connections>
</searchField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="96">
<rect key="frame" x="238" y="6" width="74" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="recessed" title="Password" bezelStyle="recessed" alignment="center" controlSize="small" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="97">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="systemBold" size="12"/>
</buttonCell>
<connections>
<action selector="toggleFilterSpace:" target="-2" id="Dwh-vl-UhN"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstItem="6" firstAttribute="leading" secondItem="1" secondAttribute="leading" constant="8" id="30"/>
<constraint firstItem="2" firstAttribute="leading" secondItem="6" secondAttribute="trailing" constant="8" symbolic="YES" id="32"/>
<constraint firstItem="6" firstAttribute="baseline" secondItem="2" secondAttribute="baseline" id="34"/>
<constraint firstItem="35" firstAttribute="leading" secondItem="2" secondAttribute="trailing" constant="8" symbolic="YES" id="38"/>
<constraint firstItem="40" firstAttribute="leading" secondItem="35" secondAttribute="trailing" constant="8" symbolic="YES" id="43"/>
<constraint firstAttribute="centerY" secondItem="40" secondAttribute="centerY" id="54"/>
<constraint firstAttribute="centerY" secondItem="2" secondAttribute="centerY" id="55"/>
<constraint firstAttribute="centerY" secondItem="35" secondAttribute="centerY" id="56"/>
<constraint firstAttribute="trailing" secondItem="61" secondAttribute="trailing" constant="8" id="63"/>
<constraint firstItem="6" firstAttribute="bottom" secondItem="35" secondAttribute="bottom" id="66"/>
<constraint firstAttribute="centerY" secondItem="61" secondAttribute="centerY" id="69"/>
<constraint firstItem="35" firstAttribute="baseline" secondItem="40" secondAttribute="baseline" id="73"/>
<constraint firstItem="61" firstAttribute="leading" secondItem="80" secondAttribute="trailing" constant="8" symbolic="YES" id="83"/>
<constraint firstAttribute="centerY" secondItem="80" secondAttribute="centerY" id="86"/>
<constraint firstItem="96" firstAttribute="baseline" secondItem="40" secondAttribute="baseline" id="98"/>
<constraint firstItem="96" firstAttribute="leading" secondItem="40" secondAttribute="trailing" constant="8" symbolic="YES" id="99"/>
<constraint firstItem="80" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="96" secondAttribute="trailing" constant="8" symbolic="YES" id="100"/>
</constraints>
</customView>
</subviews>
<constraints>
<constraint firstItem="1" firstAttribute="leading" secondItem="caQ-XO-RkM" secondAttribute="leading" id="APY-Gx-UHv"/>
<constraint firstAttribute="bottom" secondItem="1" secondAttribute="bottom" id="SAy-YO-CJX"/>
<constraint firstAttribute="trailing" secondItem="1" secondAttribute="trailing" id="l0b-wL-Hgo"/>
<constraint firstItem="1" firstAttribute="top" secondItem="caQ-XO-RkM" secondAttribute="top" id="oAv-6v-o9d"/>
</constraints>
</view>
</tabViewItem>
<tabViewItem label="Trash" identifier="2" id="na6-h9-r9q">
<view key="view" id="F6S-GS-AwI">
<rect key="frame" x="0.0" y="0.0" width="576" height="30"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="DXf-SC-gVG" customClass="HNHGradientView">
<rect key="frame" x="0.0" y="0.0" width="576" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="yBM-0x-EbF">
<rect key="frame" x="476" y="6" width="80" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="roundRect" title="Empty Trash" bezelStyle="roundedRect" alignment="center" controlSize="small" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="h7n-rC-pCN">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="smallSystem"/>
</buttonCell>
</button>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="yBM-0x-EbF" secondAttribute="trailing" constant="20" symbolic="YES" id="Pu4-mQ-gM6"/>
<constraint firstItem="yBM-0x-EbF" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="DXf-SC-gVG" secondAttribute="leading" constant="20" symbolic="YES" id="bSn-n3-rIm"/>
<constraint firstItem="yBM-0x-EbF" firstAttribute="centerY" secondItem="DXf-SC-gVG" secondAttribute="centerY" id="ekW-da-P4m"/>
</constraints>
</customView>
</subviews>
<constraints>
<constraint firstItem="DXf-SC-gVG" firstAttribute="leading" secondItem="F6S-GS-AwI" secondAttribute="leading" id="8z9-Fw-xiU"/>
<constraint firstAttribute="bottom" secondItem="DXf-SC-gVG" secondAttribute="bottom" id="FUk-Mw-Kld"/>
<constraint firstItem="DXf-SC-gVG" firstAttribute="top" secondItem="F6S-GS-AwI" secondAttribute="top" id="j4h-gk-JVJ"/>
<constraint firstAttribute="trailing" secondItem="DXf-SC-gVG" secondAttribute="trailing" id="wap-ZJ-5Rw"/>
</constraints>
</view>
</tabViewItem>
<tabViewItem label="History" identifier="3" id="z4I-cp-nhf">
<view key="view" id="iPb-SZ-Lfm">
<rect key="frame" x="0.0" y="0.0" width="576" height="30"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="S8L-rB-h0h" customClass="HNHGradientView">
<rect key="frame" x="0.0" y="0.0" width="576" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="sPN-Q9-cPQ">
<rect key="frame" x="481" y="6" width="75" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="roundRect" title="Exit History" bezelStyle="roundedRect" alignment="center" controlSize="small" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="e5L-51-aBc">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="smallSystem"/>
</buttonCell>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="gGR-f0-dcr">
<rect key="frame" x="18" y="7" width="38" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Label" id="8LU-cT-rsU">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstItem="sPN-Q9-cPQ" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="gGR-f0-dcr" secondAttribute="trailing" constant="8" symbolic="YES" id="1yk-Sc-5be"/>
<constraint firstAttribute="centerY" secondItem="sPN-Q9-cPQ" secondAttribute="centerY" id="Ioh-QS-vaO"/>
<constraint firstAttribute="centerY" secondItem="gGR-f0-dcr" secondAttribute="centerY" id="KMF-ev-v2h"/>
<constraint firstItem="gGR-f0-dcr" firstAttribute="leading" secondItem="S8L-rB-h0h" secondAttribute="leading" constant="20" symbolic="YES" id="gFm-N8-pwn"/>
<constraint firstAttribute="trailing" secondItem="sPN-Q9-cPQ" secondAttribute="trailing" constant="20" symbolic="YES" id="z4Y-Hr-EiA"/>
</constraints>
</customView>
</subviews>
<constraints>
<constraint firstItem="S8L-rB-h0h" firstAttribute="leading" secondItem="iPb-SZ-Lfm" secondAttribute="leading" id="5jN-VU-DkD"/>
<constraint firstAttribute="trailing" secondItem="S8L-rB-h0h" secondAttribute="trailing" id="VAt-ZA-0A2"/>
<constraint firstAttribute="bottom" secondItem="S8L-rB-h0h" secondAttribute="bottom" id="bz5-FS-Gg2"/>
<constraint firstItem="S8L-rB-h0h" firstAttribute="top" secondItem="iPb-SZ-Lfm" secondAttribute="top" id="mW1-xp-CdF"/>
</constraints>
</view>
</tabViewItem>
</tabViewItems>
</tabView>
</objects>
</document>

View File

@@ -13,6 +13,7 @@
<outlet property="expiresCheckButton" destination="7" id="286"/>
<outlet property="generalView" destination="4" id="270"/>
<outlet property="generatePasswordButton" destination="59" id="282"/>
<outlet property="historyTableView" destination="RRd-aS-bh1" id="gTo-oI-jG1"/>
<outlet property="infoTabControl" destination="82" id="264"/>
<outlet property="notesTextView" destination="73" id="267"/>
<outlet property="passwordTextField" destination="60" id="263"/>
@@ -31,7 +32,7 @@
<autoresizingMask key="autoresizingMask"/>
<subviews>
<segmentedControl verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="82">
<rect key="frame" x="67" y="505" width="158" height="19"/>
<rect key="frame" x="40" y="505" width="213" height="19"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<segmentedCell key="cell" controlSize="small" alignment="left" style="texturedSquare" trackingMode="selectOne" id="238">
<font key="font" metaFont="smallSystem"/>
@@ -39,6 +40,7 @@
<segment label="General" selected="YES"/>
<segment label="Files" tag="1"/>
<segment label="Custom"/>
<segment label="History"/>
</segments>
</segmentedCell>
</segmentedControl>
@@ -430,6 +432,78 @@
<outlet property="initialFirstResponder" destination="179" id="wSu-XB-L1r"/>
</connections>
</tabViewItem>
<tabViewItem label="History" identifier="" id="hK7-Dx-yjH">
<view key="view" id="2py-ab-4ZU">
<rect key="frame" x="0.0" y="0.0" width="293" height="503"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<scrollView autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="X0v-Lt-vra">
<rect key="frame" x="20" y="20" width="253" height="463"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<clipView key="contentView" id="pcm-dD-Buv">
<rect key="frame" x="1" y="17" width="251" height="445"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnSelection="YES" multipleSelection="NO" autosaveColumns="NO" headerView="b0e-MX-sxO" id="RRd-aS-bh1">
<rect key="frame" x="0.0" y="0.0" width="251" height="445"/>
<autoresizingMask key="autoresizingMask"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn width="116" minWidth="40" maxWidth="1000" id="0vc-aZ-jM2">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" white="0.33333298560000002" alpha="1" colorSpace="calibratedWhite"/>
</tableHeaderCell>
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" alignment="left" title="Text Cell" id="5j5-wL-0vG">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
</tableColumn>
<tableColumn width="129" minWidth="40" maxWidth="1000" id="unf-zm-IA8">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" white="0.33333298560000002" alpha="1" colorSpace="calibratedWhite"/>
</tableHeaderCell>
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" alignment="left" title="Text Cell" id="gag-bX-giW">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
</tableColumn>
</tableColumns>
</tableView>
</subviews>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</clipView>
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="Jfw-hJ-Fyy">
<rect key="frame" x="1" y="1" width="0.0" height="16"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="Bcd-2w-TwA">
<rect key="frame" x="-15" y="17" width="16" height="0.0"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<tableHeaderView key="headerView" id="b0e-MX-sxO">
<rect key="frame" x="0.0" y="0.0" width="251" height="17"/>
<autoresizingMask key="autoresizingMask"/>
</tableHeaderView>
</scrollView>
</subviews>
<constraints>
<constraint firstItem="X0v-Lt-vra" firstAttribute="leading" secondItem="2py-ab-4ZU" secondAttribute="leading" constant="20" id="EqN-Fq-8MQ"/>
<constraint firstItem="X0v-Lt-vra" firstAttribute="top" secondItem="2py-ab-4ZU" secondAttribute="top" constant="20" id="WWH-5S-0LQ"/>
<constraint firstAttribute="bottom" secondItem="X0v-Lt-vra" secondAttribute="bottom" constant="20" id="gz9-HC-gNN"/>
<constraint firstAttribute="trailing" secondItem="X0v-Lt-vra" secondAttribute="trailing" constant="20" id="tKq-FB-cMc"/>
</constraints>
</view>
</tabViewItem>
</tabViewItems>
</tabView>
</subviews>
@@ -440,6 +514,8 @@
<constraint firstAttribute="centerX" secondItem="82" secondAttribute="centerX" id="90"/>
<constraint firstItem="83" firstAttribute="bottom" secondItem="3" secondAttribute="bottom" id="254"/>
<constraint firstItem="83" firstAttribute="top" secondItem="3" secondAttribute="top" constant="26" id="279"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="82" secondAttribute="trailing" constant="20" symbolic="YES" id="4df-0Y-ggz"/>
<constraint firstItem="82" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="3" secondAttribute="leading" constant="20" symbolic="YES" id="zU6-5h-Swa"/>
</constraints>
</view>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="4" customClass="HNHScrollDocumentViewAdapter">

View File

@@ -269,11 +269,24 @@
<font key="font" metaFont="cellTitle"/>
</buttonCell>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Dhg-1B-bN3">
<rect key="frame" x="598" y="-2.5" width="82" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="Button" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="HCI-iT-0XJ">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="enterHistoryBrowser:" target="-2" id="W3S-kJ-PS1"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="30" id="697"/>
<constraint firstItem="732" firstAttribute="leading" secondItem="690" secondAttribute="leading" constant="7" id="741"/>
<constraint firstItem="732" firstAttribute="centerY" secondItem="690" secondAttribute="centerY" id="878"/>
<constraint firstAttribute="trailing" secondItem="Dhg-1B-bN3" secondAttribute="trailing" constant="20" id="9jV-U2-Fri"/>
<constraint firstAttribute="centerY" secondItem="Dhg-1B-bN3" secondAttribute="centerY" id="b7s-ji-CeA"/>
</constraints>
</customView>
</subviews>

View File

@@ -1,127 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="4514" systemVersion="13A2093" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment defaultVersion="1080" identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="4514"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="MPEntryViewController">
<connections>
<outlet property="filterBar" destination="1" id="48"/>
<outlet property="filterDoneButton" destination="61" id="76"/>
<outlet property="filterLabelTextField" destination="6" id="60"/>
<outlet property="filterPasswordButton" destination="96" id="101"/>
<outlet property="filterSearchField" destination="80" id="95"/>
<outlet property="filterTitleButton" destination="2" id="57"/>
<outlet property="filterURLButton" destination="40" id="59"/>
<outlet property="filterUsernameButton" destination="35" id="58"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application"/>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="1" customClass="HNHGradientView">
<rect key="frame" x="0.0" y="0.0" width="478" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="2">
<rect key="frame" x="57" y="5" width="42" height="19"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="recessed" title="Title" bezelStyle="recessed" alignment="center" controlSize="small" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="3">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="systemBold" size="12"/>
</buttonCell>
<connections>
<action selector="_toggleFilterSpace:" target="-2" id="79"/>
</connections>
</button>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="6">
<rect key="frame" x="6" y="7" width="45" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Search:" id="7">
<font key="font" metaFont="smallSystemBold"/>
<color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="35">
<rect key="frame" x="107" y="6" width="77" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="recessed" title="Username" bezelStyle="recessed" alignment="center" controlSize="small" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="36">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="systemBold" size="12"/>
</buttonCell>
<connections>
<action selector="_toggleFilterSpace:" target="-2" id="77"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="40">
<rect key="frame" x="192" y="6" width="38" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="recessed" title="URL" bezelStyle="recessed" alignment="center" controlSize="small" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="41">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="systemBold" size="12"/>
</buttonCell>
<connections>
<action selector="_toggleFilterSpace:" target="-2" id="78"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="61">
<rect key="frame" x="428" y="6" width="42" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="roundRect" title="Done" bezelStyle="roundedRect" alignment="center" controlSize="small" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="62">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="smallSystem"/>
</buttonCell>
<connections>
<action selector="clearFilter:" target="-2" id="75"/>
</connections>
</button>
<searchField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="80">
<rect key="frame" x="320" y="6" width="100" height="19"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="93"/>
</constraints>
<searchFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="81">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
<connections>
<outlet property="delegate" destination="-2" id="Y78-7K-e9c"/>
</connections>
</searchField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="96">
<rect key="frame" x="238" y="6" width="74" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="recessed" title="Password" bezelStyle="recessed" alignment="center" controlSize="small" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="97">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="systemBold" size="12"/>
</buttonCell>
<connections>
<action selector="_toggleFilterSpace:" target="-2" id="102"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstItem="6" firstAttribute="leading" secondItem="1" secondAttribute="leading" constant="8" id="30"/>
<constraint firstItem="2" firstAttribute="leading" secondItem="6" secondAttribute="trailing" constant="8" symbolic="YES" id="32"/>
<constraint firstItem="6" firstAttribute="baseline" secondItem="2" secondAttribute="baseline" id="34"/>
<constraint firstItem="35" firstAttribute="leading" secondItem="2" secondAttribute="trailing" constant="8" symbolic="YES" id="38"/>
<constraint firstItem="40" firstAttribute="leading" secondItem="35" secondAttribute="trailing" constant="8" symbolic="YES" id="43"/>
<constraint firstAttribute="centerY" secondItem="40" secondAttribute="centerY" id="54"/>
<constraint firstAttribute="centerY" secondItem="2" secondAttribute="centerY" id="55"/>
<constraint firstAttribute="centerY" secondItem="35" secondAttribute="centerY" id="56"/>
<constraint firstAttribute="trailing" secondItem="61" secondAttribute="trailing" constant="8" id="63"/>
<constraint firstItem="6" firstAttribute="bottom" secondItem="35" secondAttribute="bottom" id="66"/>
<constraint firstAttribute="centerY" secondItem="61" secondAttribute="centerY" id="69"/>
<constraint firstItem="35" firstAttribute="baseline" secondItem="40" secondAttribute="baseline" id="73"/>
<constraint firstItem="61" firstAttribute="leading" secondItem="80" secondAttribute="trailing" constant="8" symbolic="YES" id="83"/>
<constraint firstAttribute="centerY" secondItem="80" secondAttribute="centerY" id="86"/>
<constraint firstItem="96" firstAttribute="baseline" secondItem="40" secondAttribute="baseline" id="98"/>
<constraint firstItem="96" firstAttribute="leading" secondItem="40" secondAttribute="trailing" constant="8" symbolic="YES" id="99"/>
<constraint firstItem="80" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="96" secondAttribute="trailing" constant="8" symbolic="YES" id="100"/>
</constraints>
</customView>
</objects>
</document>

View File

@@ -1,15 +0,0 @@
//
// KPKEntry+TemplateCopy.h
// MacPass
//
// Created by Michael Starke on 01/12/13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import "KPKEntry.h"
@interface KPKEntry (TemplateCopy)
- (instancetype)copyWithTitle:(NSString *)title;
@end

View File

@@ -1,22 +0,0 @@
//
// KPKEntry+TemplateCopy.m
// MacPass
//
// Created by Michael Starke on 01/12/13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import "KPKEntry+TemplateCopy.h"
#import "KPKTimeInfo.h"
@implementation KPKEntry (TemplateCopy)
- (instancetype)copyWithTitle:(NSString *)title {
KPKEntry *copy = [self copy];
copy.uuid = [[NSUUID alloc] init];
copy.timeInfo.creationTime = [NSDate date];
copy.title = title;
return copy;
}
@end

View File

@@ -1,15 +0,0 @@
//
// KPKGroup+TemplateCopy.h
// MacPass
//
// Created by Michael Starke on 01/12/13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import "KPKGroup.h"
@interface KPKGroup (TemplateCopy)
- (instancetype)copyWithName:(NSString *)name;
@end

View File

@@ -1,22 +0,0 @@
//
// KPKGroup+TemplateCopy.m
// MacPass
//
// Created by Michael Starke on 01/12/13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import "KPKGroup+TemplateCopy.h"
#import "KPKTimeInfo.h"
@implementation KPKGroup (TemplateCopy)
- (instancetype)copyWithName:(NSString *)name {
KPKGroup *copy = [self copy];
copy.uuid = [[NSUUID alloc] init];
copy.timeInfo.creationTime = [NSDate date];
copy.name = name;
return copy;
}
@end

View File

@@ -9,18 +9,23 @@
#import "KPKNode+IconImage.h"
#import "KPKIcon.h"
#import "KPKTree.h"
#import "KPKMetaData.h"
#import "MPIconHelper.h"
@implementation KPKNode (IconImage)
+ (NSSet *)keyPathsForValuesAffectingIconImage {
return [NSSet setWithArray:@[@"customIcon", @"iconId"]];
return [NSSet setWithArray:@[@"iconUUID", @"iconId"]];
}
- (NSImage *)iconImage {
if(self.customIcon) {
return self.customIcon.image;
if(self.iconUUID) {
KPKIcon *icon = [self.tree.metaData findIcon:self.iconUUID];
if(icon && icon.image) {
return icon.image;
}
}
return [MPIconHelper icon:(MPIconType)self.iconId];
}

View File

@@ -20,7 +20,7 @@
@(MPActionCopyPassword) : @"copyPassword:",
@(MPActionCopyURL) : @"copyURL:",
@(MPActionCopyUsername) : @"copyUsername:",
@(MPActionDelete) : @"deleteNode:",
@(MPActionDelete) : @"delete:",
@(MPActionEditPassword) : @"editPassword:",
@(MPActionOpenURL) : @"openURL:",
@(MPActionToggleInspector) : @"toggleInspector:",
@@ -45,6 +45,7 @@
NSArray *selectors = [[self _actionDictionary] allValues];
NSUInteger index = [selectors indexOfObject:selectorString];
if(index == NSNotFound) {
// Test for default Actions?
return MPUnkownAction;
}
NSArray *keys = [[self _actionDictionary] allKeysForObject:selectorString];

View File

@@ -0,0 +1,54 @@
//
// MPContextBarViewController.h
// MacPass
//
// Created by Michael Starke on 16/12/13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import "MPViewController.h"
@protocol MPContextBarDelegate <NSObject>
@optional
- (void)contextBarDidChangeFilter;
- (void)contextBarDidExitFilter;
- (void)contextBarDidExitHistory;
- (void)contextBarShouldEmptyTrash;
@end
typedef NS_OPTIONS(NSUInteger, MPFilterModeType) {
MPFilterNone = 0,
MPFilterUrls = (1<<0),
MPFilterUsernames = (1<<1),
MPFilterTitles = (1<<2),
MPFilterPasswords = (1<<3),
};
@class HNHGradientView;
@interface MPContextBarViewController : MPViewController
@property (nonatomic, assign) MPFilterModeType filterMode;
@property (nonatomic, readonly) BOOL hasFilter;
@property (nonatomic, weak) id<MPContextBarDelegate> delegate;
- (NSString *)filterString;
- (NSArray *)filterPredicates;
- (IBAction)toggleFilterSpace:(id)sender;
- (BOOL)showsFilter;
- (BOOL)showsHistory;
- (BOOL)showsTrash;
- (void)exitFilter;
- (void)showFilter;
- (void)showHistory;
- (void)showTrash;
- (void)enable;
- (void)disable;
@end

View File

@@ -0,0 +1,267 @@
//
// MPContextBarViewController.m
// MacPass
//
// Created by Michael Starke on 16/12/13.
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//
#import "MPContextBarViewController.h"
#import "HNHGradientView.h"
typedef NS_ENUM(NSUInteger, MPContextTab) {
MPContextTabFilter,
MPContextTabTrash,
MPContextTabHistory
};
@interface MPContextBarViewController () {
@private
BOOL _delegateRespondsToDidChangeFilter;
BOOL _delegateRespondsToDidExitFilter;
BOOL _delegateRespondsToDidExitHistory;
BOOL _delegateRespondsToShouldEmptyTrash;
}
@property (nonatomic, assign) MPContextTab activeTab;
@property (nonatomic, assign) BOOL hasFilter;
@property (weak) IBOutlet NSButton *filterDoneButton;
@property (weak) IBOutlet NSButton *filterTitleButton;
@property (weak) IBOutlet NSButton *filterUsernameButton;
@property (weak) IBOutlet NSButton *filterURLButton;
@property (weak) IBOutlet NSButton *filterPasswordButton;
@property (weak) IBOutlet NSTextField *filterLabelTextField;
@property (weak) IBOutlet NSSearchField *filterSearchField;
@property (weak) IBOutlet HNHGradientView *historyBar;
@property (weak) IBOutlet HNHGradientView *trashBar;
@end
@implementation MPContextBarViewController
- (instancetype)init {
self = [self initWithNibName:@"ContextBar" bundle:nil];
return self;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
_hasFilter = NO;
_filterMode = MPFilterTitles;
_delegateRespondsToDidExitFilter = NO;
_delegateRespondsToDidExitHistory = NO;
_delegateRespondsToShouldEmptyTrash = NO;
_delegateRespondsToDidChangeFilter = NO;
}
return self;
}
- (void)didLoadView {
[self.filterURLButton setTag:MPFilterUrls];
[self.filterUsernameButton setTag:MPFilterUsernames];
[self.filterTitleButton setTag:MPFilterTitles];
[self.filterPasswordButton setTag:MPFilterPasswords];
[[self.filterLabelTextField cell] setBackgroundStyle:NSBackgroundStyleRaised];
[self.filterDoneButton setAction:@selector(exitFilter)];
[self.filterDoneButton setTarget:self];
[self.filterSearchField setAction:@selector(_didChangeFilter)];
[[self.filterSearchField cell] setSendsSearchStringImmediately:NO];
self.historyBar.activeGradient = [[NSGradient alloc] initWithStartingColor:[NSColor redColor] endingColor:[NSColor greenColor]];
NSArray *activeColors = @[
[NSColor colorWithCalibratedWhite:0.2 alpha:1],
[NSColor colorWithCalibratedWhite:0.4 alpha:1]
];
NSArray *inactiveColors = @[ [NSColor colorWithCalibratedWhite:0.3 alpha:1],
[NSColor colorWithCalibratedWhite:0.6 alpha:1]
];
self.trashBar.activeGradient = [[NSGradient alloc] initWithColors:activeColors];
self.trashBar.inactiveGradient = [[NSGradient alloc] initWithColors:inactiveColors];
[[self view] bind:NSSelectedIndexBinding toObject:self withKeyPath:@"activeTab" options:nil];
}
#pragma mark Properties
- (void)setFilterMode:(MPFilterModeType)newFilterMode {
if(_filterMode != newFilterMode) {
if(newFilterMode == MPFilterNone) {
newFilterMode = MPFilterTitles;
}
_filterMode = newFilterMode;
[self _updateFilterButtons];
[self _didChangeFilter];
}
}
- (void)setDelegate:(id<MPContextBarDelegate>)delegate {
if(self.delegate != delegate) {
_delegate = delegate;
_delegateRespondsToDidChangeFilter = [_delegate respondsToSelector:@selector(contextBarDidChangeFilter)];
_delegateRespondsToDidExitFilter = [_delegate respondsToSelector:@selector(contextBarDidExitFilter)];
_delegateRespondsToDidExitHistory = [_delegate respondsToSelector:@selector(contextBarDidExitHistory)];
_delegateRespondsToShouldEmptyTrash = [_delegate respondsToSelector:@selector(contextBarShouldEmptyTrash)];
}
}
- (void)disable {
[self.filterSearchField setEnabled:NO];
}
- (void)enable {
[self.filterSearchField setEnabled:YES];
/* First responder handling */
switch (self.activeTab) {
case MPContextTabTrash:
break;
case MPContextTabFilter:
[[[self view] window] makeFirstResponder:self.filterSearchField];
break;
case MPContextTabHistory:
break;
default:
break;
}
}
- (NSArray *)filterPredicates {
if(![self hasFilter]) {
return nil;
}
NSMutableArray *prediactes = [[NSMutableArray alloc] initWithCapacity:4];
if([self _shouldFilterTitles]) {
[prediactes addObject:[NSPredicate predicateWithFormat:@"SELF.title CONTAINS[cd] %@", [self filterString]]];
}
if([self _shouldFilterUsernames]) {
[prediactes addObject:[NSPredicate predicateWithFormat:@"SELF.username CONTAINS[cd] %@", [self filterString]]];
}
if([self _shouldFilterURLs]) {
[prediactes addObject:[NSPredicate predicateWithFormat:@"SELF.url CONTAINS[cd] %@", [self filterString]]];
}
if([self _shouldFilterPasswords]) {
[prediactes addObject:[NSPredicate predicateWithFormat:@"SELF.password CONTAINS[cd] %@", [self filterString]]];
}
return prediactes;
}
- (IBAction)toggleFilterSpace:(id)sender {
if(![sender isKindOfClass:[NSButton class]]) {
return; // Wrong sender
}
NSButton *button = sender;
MPFilterModeType toggledMode = [button tag];
switch ([button state]) {
case NSOnState:
self.filterMode |= toggledMode;
break;
case NSOffState:
self.filterMode ^= toggledMode;
break;
default:
break;
}
}
- (void)showFilter {
self.hasFilter = YES;
/* Select text if already visible */
if([self showsFilter]) {
[self.filterSearchField selectText:self];
}
self.activeTab = MPContextTabFilter;
[self _updateFilterButtons];
}
- (void)showHistory {
[self exitFilter];
self.activeTab = MPContextTabHistory;
[self _updateBindings];
}
- (void)showTrash {
[self exitFilter];
self.activeTab = MPContextTabTrash;
[self _updateBindings];
}
- (BOOL)showsFilter {
return self.activeTab == MPContextTabFilter;
}
- (BOOL)showsHistory {
return self.activeTab == MPContextTabHistory;
}
- (BOOL)showsTrash {
return self.activeTab == MPContextTabTrash;
}
- (NSString *)filterString {
return [self.filterSearchField stringValue];
}
- (BOOL)control:(NSControl*)control textView:(NSTextView*)textView doCommandBySelector:(SEL)commandSelector {
if(commandSelector == @selector(insertNewline:)) {
[self _didChangeFilter];
}
return NO;
}
- (void)exitFilter {
if(!self.hasFilter) {
return; // Nothing to do;
}
if(![self showsFilter]) {
return; // We arent displaying the filter view
}
self.hasFilter = NO;
[self.filterSearchField setStringValue:@""];
if(_delegateRespondsToDidExitFilter) {
[self.delegate contextBarDidExitFilter];
}
}
- (void)_didChangeFilter {
if(_delegateRespondsToDidChangeFilter) {
[self.delegate contextBarDidChangeFilter];
}
}
- (void)_updateBindings {
// only the entry view has to be bound, the rest not
}
- (void)_updateFilterButtons {
[self.filterTitleButton setState:[self _shouldFilterTitles] ? NSOnState : NSOffState];
[self.filterURLButton setState:[self _shouldFilterURLs] ? NSOnState : NSOffState ];
[self.filterUsernameButton setState:[self _shouldFilterUsernames] ? NSOnState : NSOffState];
[self.filterPasswordButton setState:[self _shouldFilterPasswords] ? NSOnState : NSOffState];
}
- (BOOL)_shouldFilterTitles {
return (MPFilterNone != (self.filterMode & MPFilterTitles));
}
- (BOOL)_shouldFilterURLs {
return (MPFilterNone != (self.filterMode & MPFilterUrls));
}
- (BOOL)_shouldFilterUsernames {
return (MPFilterNone != (self.filterMode & MPFilterUsernames));
}
- (BOOL)_shouldFilterPasswords {
return (MPFilterNone != (self.filterMode & MPFilterPasswords));
}
@end

View File

@@ -33,7 +33,6 @@
#import "DDXMLNode.h"
#import "KPKEntry.h"
#import "KPKEntry+TemplateCopy.h"
#import "KPKGroup.h"
#import "KPKTree.h"
#import "KPKTree+Serializing.h"
@@ -446,6 +445,7 @@ typedef NS_ENUM(NSUInteger, MPAlertType) {
newEntry.title = self.tree.metaData.defaultUserName;
}
[parent addEntry:newEntry];
[parent.undoManager setActionName:NSLocalizedString(@"ADD_ENTRY", "")];
return newEntry;
}
@@ -540,8 +540,9 @@ typedef NS_ENUM(NSUInteger, MPAlertType) {
if(entryUUID) {
KPKEntry *templateEntry = [self findEntry:entryUUID];
if(templateEntry && self.selectedGroup) {
KPKEntry *copy = [templateEntry copyWithTitle:templateEntry.title];
KPKEntry *copy = [templateEntry copyWithTitle:templateEntry.title options:0];
[self.selectedGroup addEntry:copy];
[self.selectedGroup.undoManager setActionName:NSLocalizedString(@"ADD_TREMPLATE_ENTRY", "")];
}
}
return;

View File

@@ -24,6 +24,7 @@
@property (weak) IBOutlet NSSegmentedControl *infoTabControl;
@property (weak) IBOutlet NSTableView *attachmentTableView;
@property (weak) IBOutlet NSTableView *customFieldsTableView;
@property (weak) IBOutlet NSTableView *historyTableView;
@property (unsafe_unretained) IBOutlet NSTextView *notesTextView;
@property (weak) IBOutlet NSButton *generatePasswordButton;
@property (weak) IBOutlet NSButton *togglePassword;

View File

@@ -24,13 +24,15 @@
typedef NS_ENUM(NSUInteger, MPEntryTab) {
MPEntryTabGeneral,
MPEntryTabFiles,
MPEntryTabCustomFields
MPEntryTabCustomFields,
MPEntryTabHistory
};
@interface MPEntryInspectorViewController () {
@private
NSArrayController *_attachmentsController;
NSArrayController *_customFieldsController;
NSArrayController *_historyController;
MPAttachmentTableViewDelegate *_attachmentTableDelegate;
MPCustomFieldTableViewDelegate *_customFieldTableDelegate;
MPAttachmentTableDataSource *_attachmentDataSource;
@@ -57,6 +59,7 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
_showPassword = NO;
_attachmentsController = [[NSArrayController alloc] init];
_customFieldsController = [[NSArrayController alloc] init];
_historyController = [[NSArrayController alloc] init];
_attachmentTableDelegate = [[MPAttachmentTableViewDelegate alloc] init];
_customFieldTableDelegate = [[MPCustomFieldTableViewDelegate alloc] init];
_attachmentDataSource = [[MPAttachmentTableDataSource alloc] init];
@@ -105,7 +108,7 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
[[self view] layoutSubtreeIfNeeded];
[_infoTabControl bind:NSSelectedIndexBinding toObject:self withKeyPath:@"activeTab" options:nil];
[_tabView bind:NSSelectedIndexBinding toObject:self withKeyPath:@"activeTab" options:nil];
[_tabView bind:NSSelectedIndexBinding toObject:self withKeyPath:@"activeTab" options:nil];
/* Set background to clearcolor so we can draw in the scrollview */
[_attachmentTableView setBackgroundColor:[NSColor clearColor]];
@@ -118,6 +121,7 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
[_customFieldsTableView bind:NSContentBinding toObject:_customFieldsController withKeyPath:@"arrangedObjects" options:nil];
[_customFieldsTableView setDelegate:_customFieldTableDelegate];
[_historyTableView bind:NSContentBinding toObject:_historyController withKeyPath:@"arrangedObjects" options:nil];
[self.passwordTextField bind:@"showPassword" toObject:self withKeyPath:@"showPassword" options:nil];
[self.togglePassword bind:NSValueBinding toObject:self withKeyPath:@"showPassword" options:nil];
@@ -224,6 +228,7 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
[self _bindEntry];
[self _bindAttachments];
[self _bindCustomFields];
[self _bindHistory];
}
- (void)_bindEntry {
@@ -261,4 +266,14 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
[_customFieldsController bind:NSContentArrayBinding toObject:self.entry withKeyPath:@"customAttributes" options:nil];
}
- (void)_bindHistory {
if(self.entry) {
[_historyController bind:NSContentArrayBinding toObject:self.entry withKeyPath:@"history" options:nil];
}
else if([_historyController content] != nil) {
[_historyController unbind:NSContentArrayBinding];
[_historyController setContent:nil];
}
}
@end

View File

@@ -7,6 +7,7 @@
//
#import "MPViewController.h"
#import "MPContextBarViewController.h"
APPKIT_EXTERN NSString *const MPEntryTableUserNameColumnIdentifier;
APPKIT_EXTERN NSString *const MPEntryTableTitleColumnIdentifier;
@@ -26,19 +27,16 @@ typedef NS_ENUM( NSUInteger, MPCopyContentTypeTag) {
@class MPOutlineViewDelegate;
@class MPDocumentWindowController;
@interface MPEntryViewController : MPViewController <NSTableViewDelegate>
@interface MPEntryViewController : MPViewController <NSTableViewDelegate, MPContextBarDelegate>
@property (weak,readonly) NSTableView *entryTable;
@property (readonly, strong) NSArrayController *entryArrayController;
@property (nonatomic, strong) NSString *filter;
/* Call this after alle viewcontroller are loaded */
- (void)setupNotifications:(MPDocumentWindowController *)windowController;
/* Clear the Search filter*/
- (void)showFilter:(id)sender;
- (void)clearFilter:(id)sender;
/* Copy/Paste */
- (void)copyUsername:(id)sender;
@@ -47,8 +45,8 @@ typedef NS_ENUM( NSUInteger, MPCopyContentTypeTag) {
- (void)copyURL:(id)sender;
- (void)openURL:(id)sender;
/* Entry Handling*/
- (void)deleteNode:(id)sender;
/* History*/
- (IBAction)enterHistoryBrowser:(id)sender;
- (IBAction)exitHistoryBrowser:(id)sender;
@end

View File

@@ -14,6 +14,7 @@
#import "MPDocumentWindowController.h"
#import "MPPasteBoardController.h"
#import "MPOverlayWindowController.h"
#import "MPContextBarViewController.h"
#import "MPContextMenuHelper.h"
#import "MPActionHelper.h"
@@ -37,19 +38,11 @@
#define STATUS_BAR_ANIMATION_TIME 0.15
typedef NS_OPTIONS(NSUInteger, MPFilterModeType) {
MPFilterNone = 0,
MPFilterUrls = (1<<0),
MPFilterUsernames = (1<<1),
MPFilterTitles = (1<<2),
MPFilterPasswords = (1<<3),
};
typedef NS_ENUM(NSUInteger,MPOVerlayInfoType) {
MPOverlayInfoPassword,
MPOverlayInfoUsername,
MPOverlayInfoURL,
MPOverlayInfoCustom
MPOverlayInfoCustom,
};
NSString *const MPEntryTableUserNameColumnIdentifier = @"MPUserNameColumnIdentifier";
@@ -67,32 +60,24 @@ NSString *const _MPTAbleSecurCellView = @"PasswordCell";
@interface MPEntryViewController () {
MPEntryContextMenuDelegate *_menuDelegate;
BOOL _isDisplayingContextBar;
}
@property (strong) NSArrayController *entryArrayController;
@property (strong) MPContextBarViewController *contextBarViewController;
@property (strong) NSArray *filteredEntries;
@property (strong) IBOutlet NSView *filterBar;
@property (strong) IBOutlet HNHGradientView *trashBar;
@property (weak) IBOutlet NSTableView *entryTable;
@property (strong) IBOutlet NSLayoutConstraint *tableToTopConstraint;
@property (strong) NSLayoutConstraint *filterbarTopConstraint;
@property (weak) IBOutlet NSButton *filterDoneButton;
@property (weak) IBOutlet NSButton *filterTitleButton;
@property (weak) IBOutlet NSButton *filterUsernameButton;
@property (weak) IBOutlet NSButton *filterURLButton;
@property (weak) IBOutlet NSButton *filterPasswordButton;
@property (weak) IBOutlet NSTextField *filterLabelTextField;
@property (weak) IBOutlet NSSearchField *filterSearchField;
@property (weak) IBOutlet NSTableView *entryTable;
/* Constraints */
@property (strong) IBOutlet NSLayoutConstraint *tableToTopConstraint;
@property (strong) NSLayoutConstraint *contextBarTopConstraint;
@property (weak) IBOutlet HNHGradientView *bottomBar;
@property (weak) IBOutlet NSButton *addEntryButton;
@property (weak) IBOutlet NSTextField *entryCountTextField;
@property (nonatomic, strong) MPEntryTableDataSource *dataSource;
@property (assign, nonatomic) MPFilterModeType filterMode;
@property (assign, nonatomic) BOOL isDisplayingFilterbar;
@end
@implementation MPEntryViewController
@@ -105,12 +90,13 @@ NSString *const _MPTAbleSecurCellView = @"PasswordCell";
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if(self) {
_filterMode = MPFilterTitles;
_isDisplayingFilterbar = NO;
_isDisplayingContextBar = NO;
_entryArrayController = [[NSArrayController alloc] init];
_dataSource = [[MPEntryTableDataSource alloc] init];
_dataSource.viewController = self;
_menuDelegate = [[MPEntryContextMenuDelegate alloc] init];
_contextBarViewController = [[MPContextBarViewController alloc] init];
}
return self;
}
@@ -123,7 +109,6 @@ NSString *const _MPTAbleSecurCellView = @"PasswordCell";
- (void)didLoadView {
[[self view] setWantsLayer:YES];
[self _hideFilterBar];
[_bottomBar setBorderType:HNHBorderTop];
[self.addEntryButton setAction:[MPActionHelper actionOfType:MPActionAddEntry]];
@@ -133,11 +118,13 @@ NSString *const _MPTAbleSecurCellView = @"PasswordCell";
[self.entryTable setTarget:self];
[self.entryTable setFloatsGroupRows:NO];
[self.entryTable registerForDraggedTypes:@[KPKEntryUTI]];
/* First responder notifications */
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(_didBecomFirstResponder:)
name:MPDidActivateViewNotification
object:_entryTable];
/* Filter bar notifications */
self.contextBarViewController.delegate = self;
[self _setupEntryMenu];
NSTableColumn *parentColumn = [self.entryTable tableColumns][0];
@@ -239,7 +226,7 @@ NSString *const _MPTAbleSecurCellView = @"PasswordCell";
[[view imageView] bind:NSValueBinding toObject:entry withKeyPath:@"iconImage" options:nil];
}
else {
assert(entry.parent);
NSAssert(entry.parent != nil, @"Entry needs to have a parent");
[[view textField] bind:NSValueBinding toObject:entry.parent withKeyPath:@"name" options:nil];
[[view imageView] bind:NSValueBinding toObject:entry.parent withKeyPath:@"iconImage" options:nil];
}
@@ -307,19 +294,14 @@ NSString *const _MPTAbleSecurCellView = @"PasswordCell";
return;
}
/*
If a grup is the current item, see if we already show that group
If a group is the current item, see if we already show that group
*/
if(document.selectedItem == document.selectedGroup) {
/*
If we reselect the group, or just another group
we clear the filter and bind to the new selected group
*/
if(self.isDisplayingFilterbar && ![document.selectedItem isKindOfClass:[KPKEntry class]]) {
[self clearFilter:nil];
[self.entryArrayController bind:NSContentArrayBinding toObject:document.selectedGroup withKeyPath:@"entries" options:nil];
return;
/* If we change to a group selection, we should clear the filter */
if(_isDisplayingContextBar) {
[self.contextBarViewController exitFilter];
}
if([[self.entryArrayController content] count] > 0) {
else if([[self.entryArrayController content] count] > 0) {
KPKEntry *entry = [[self.entryArrayController content] lastObject];
if(entry.parent == document.selectedGroup) {
return; // we are showing the correct object right now.
@@ -327,127 +309,35 @@ NSString *const _MPTAbleSecurCellView = @"PasswordCell";
}
[self.entryArrayController bind:NSContentArrayBinding toObject:document.selectedGroup withKeyPath:@"entries" options:nil];
}
[self _updateContextBar];
}
- (void)_didBecomFirstResponder:(NSNotification *)notification {
MPDocument *document = [[self windowController] document];
if(document.selectedEntry.parent == document.selectedGroup || self.isDisplayingFilterbar) {
if(document.selectedEntry.parent == document.selectedGroup || [self.contextBarViewController showsFilter]) {
document.selectedItem = document.selectedEntry;
}
else {
document.selectedEntry = nil;
}
}
#pragma mark Filtering
- (void)showFilter:(id)sender {
if(self.isDisplayingFilterbar) {
[self.filterSearchField selectText:self];
}
BOOL didLoadFilterBar = NO;
if(!self.filterBar) {
[self _setupFilterBar];
didLoadFilterBar = YES;
}
/*
Make sure the buttons are set correctyl every time
*/
[self.filterTitleButton setState:[self _shouldFilterTitles] ? NSOnState : NSOffState];
[self.filterURLButton setState:[self _shouldFilterURLs] ? NSOnState : NSOffState ];
[self.filterUsernameButton setState:[self _shouldFilterUsernames] ? NSOnState : NSOffState];
[self.filterPasswordButton setState:[self _shouldFilterPasswords] ? NSOnState : NSOffState];
if(self.isDisplayingFilterbar) {
return; // nothing to to
}
/* Install any constraints we need for the first time */
self.isDisplayingFilterbar = YES;
if(didLoadFilterBar) {
/* Add the view for the first time */
[[self view] addSubview:self.filterBar];
NSView *scrollView = [_entryTable enclosingScrollView];
NSDictionary *views = NSDictionaryOfVariableBindings(scrollView, _filterBar);
/* Pin to the left */
[[self view] addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_filterBar]|" options:0 metrics:nil views:views]];
/* Pin height and to top of entry table */
[[self view] addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_filterBar(==30)]-0-[scrollView]" options:0 metrics:nil views:views]];
/* Create the top constraint for the filter bar where we can change the contanst instaed of removing/adding constraints all the time */
self.filterbarTopConstraint = [NSLayoutConstraint constraintWithItem:self.filterBar
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:[self view]
attribute:NSLayoutAttributeTop
multiplier:1
constant:-31];
}
[[self view] removeConstraint:self.tableToTopConstraint];
[[self view] addConstraint:self.filterbarTopConstraint];
[[self view] layoutSubtreeIfNeeded];
self.filterbarTopConstraint.constant = 0;
[NSAnimationContext runAnimationGroup:^(NSAnimationContext* context) {
context.duration = STATUS_BAR_ANIMATION_TIME;
context.allowsImplicitAnimation = YES;
[self.view layoutSubtreeIfNeeded];
} completionHandler:^{
[self.filterSearchField setEnabled:YES];
[[[self windowController] window] makeFirstResponder:self.filterSearchField];
}];
}
- (BOOL)hasFilter {
return ([self.filter length] > 0);
}
- (void)setFilter:(NSString *)filter {
if(_filter != filter) {
_filter = filter;
[self updateFilter];
}
}
- (void)clearFilter:(id)sender {
self.filter = nil;
[self.filterSearchField setStringValue:@""];
#pragma mark MPContextBarDelegate
- (void)contextBarDidExitFilter {
[[self.entryTable tableColumnWithIdentifier:MPEntryTableParentColumnIdentifier] setHidden:YES];
[self _hideFilterBar];
MPDocument *document = [[self windowController] document];
document.selectedGroup = document.selectedGroup;
document.selectedItem = document.selectedGroup;
[self _updateContextBar];
}
- (void)updateFilter {
[self showFilter:nil];
if(![self hasFilter]) {
return;
}
- (void)contextBarDidChangeFilter {
dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(backgroundQueue, ^{
MPDocument *document = [[self windowController] document];
if([self hasFilter]) {
NSMutableArray *prediactes = [NSMutableArray arrayWithCapacity:4];
if([self _shouldFilterTitles]) {
[prediactes addObject:[NSPredicate predicateWithFormat:@"SELF.title CONTAINS[cd] %@", self.filter]];
}
if([self _shouldFilterUsernames]) {
[prediactes addObject:[NSPredicate predicateWithFormat:@"SELF.username CONTAINS[cd] %@", self.filter]];
}
if([self _shouldFilterURLs]) {
[prediactes addObject:[NSPredicate predicateWithFormat:@"SELF.url CONTAINS[cd] %@", self.filter]];
}
if([self _shouldFilterPasswords]) {
[prediactes addObject:[NSPredicate predicateWithFormat:@"SELF.password CONTAINS[cd] %@", self.filter]];
}
NSPredicate *fullFilter = [NSCompoundPredicate orPredicateWithSubpredicates:prediactes];
NSArray *predicates = [self.contextBarViewController filterPredicates];
if(predicates) {
NSPredicate *fullFilter = [NSCompoundPredicate orPredicateWithSubpredicates:predicates];
self.filteredEntries = [[document.root childEntries] filteredArrayUsingPredicate:fullFilter];
}
else {
self.filteredEntries = [document.root childEntries];
}
@@ -459,65 +349,90 @@ NSString *const _MPTAbleSecurCellView = @"PasswordCell";
[[self.entryTable tableColumnWithIdentifier:MPEntryTableParentColumnIdentifier] setHidden:NO];
});
});
}
- (void)updateFilterText:(id)sender {
self.filter = [self.filterSearchField stringValue];
- (void)showFilter:(id)sender {
[self.contextBarViewController showFilter];
[self _showContextBar];
}
- (BOOL)control:(NSControl*)control textView:(NSTextView*)textView doCommandBySelector:(SEL)commandSelector
{
if(commandSelector == @selector(insertNewline:))
{
self.filter = [self.filterSearchField stringValue];
#pragma mark ContextBar
- (void)_showTrashBar {
[self.contextBarViewController showTrash];
[self _showContextBar];
}
- (void)_updateContextBar {
MPDocument *document = [[self windowController] document];
if(![self.contextBarViewController hasFilter]) {
BOOL showTrash = (document.selectedGroup == document.trash || [document isItemTrashed:document.selectedItem]);
if(showTrash) {
[self _showTrashBar];
}
else {
[self _hideContextBar];
}
return NO;
}
- (void)_setupFilterBar {
if(!self.filterBar) {
[[NSBundle mainBundle] loadNibNamed:@"FilterBar" owner:self topLevelObjects:nil];
[self.filterURLButton setTag:MPFilterUrls];
[self.filterUsernameButton setTag:MPFilterUsernames];
[self.filterTitleButton setTag:MPFilterTitles];
[self.filterPasswordButton setTag:MPFilterPasswords];
[[self.filterLabelTextField cell] setBackgroundStyle:NSBackgroundStyleRaised];
[self.filterDoneButton setAction:@selector(clearFilter:)];
[self.filterDoneButton setTarget:nil];
[self.filterSearchField setAction:@selector(updateFilterText:)];
[[self.filterSearchField cell] setSendsSearchStringImmediately:NO];
/*
[self bind:@"filterMode"
toObject:[NSUserDefaultsController sharedUserDefaultsController]
withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyEntrySearchFilterMode]
options:nil];
*/
}
}
#pragma mark UI Feedback
- (void)_hideFilterBar {
if(!self.isDisplayingFilterbar) {
return; // nothing to do;
- (void)_showContextBar {
if(_isDisplayingContextBar) {
return;
}
self.filterbarTopConstraint.constant = -31;
[[self view] addConstraint:self.tableToTopConstraint];
_isDisplayingContextBar = YES;
if(![[self.contextBarViewController view] superview]) {
[[self view] addSubview:[self.contextBarViewController view]];
[self.contextBarViewController updateResponderChain];
NSView *contextBar = [self.contextBarViewController view];
NSView *scrollView = [_entryTable enclosingScrollView];
NSDictionary *views = NSDictionaryOfVariableBindings(scrollView, contextBar);
/* Pin to the left */
[[self view] addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[contextBar]|" options:0 metrics:nil views:views]];
/* Pin height and to top of entry table */
[[self view] addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[contextBar(==30)]-0-[scrollView]" options:0 metrics:nil views:views]];
/* Create the top constraint for the filter bar where we can change the contanst instaed of removing/adding constraints all the time */
self.contextBarTopConstraint = [NSLayoutConstraint constraintWithItem:contextBar
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:[self view]
attribute:NSLayoutAttributeTop
multiplier:1
constant:-31];
}
/* Add the view for the first time */
[[self view] removeConstraint:self.tableToTopConstraint];
[[self view] addConstraint:self.contextBarTopConstraint];
[[self view] layout];
self.contextBarTopConstraint.constant = 0;
[NSAnimationContext runAnimationGroup:^(NSAnimationContext* context) {
context.duration = STATUS_BAR_ANIMATION_TIME;
context.allowsImplicitAnimation = YES;
[self.view layoutSubtreeIfNeeded];
} completionHandler:^{
self.isDisplayingFilterbar = NO;
[self.filterSearchField setEnabled:NO];
}] ;
[self.contextBarViewController enable];
}];
}
- (void)_hideContextBar {
if(!_isDisplayingContextBar) {
return; // nothing to do;
}
self.contextBarTopConstraint.constant = -31;
[[self view] addConstraint:self.tableToTopConstraint];
[self.contextBarViewController disable];
[NSAnimationContext runAnimationGroup:^(NSAnimationContext* context) {
context.duration = STATUS_BAR_ANIMATION_TIME;
context.allowsImplicitAnimation = YES;
[self.view layoutSubtreeIfNeeded];
} completionHandler:^{
_isDisplayingContextBar = NO;
}];
}
#pragma mark Copy/Paste Overlays
- (void)_copyToPasteboard:(NSString *)data overlayInfo:(MPOVerlayInfoType)overlayInfoType name:(NSString *)name{
if(data) {
[[MPPasteBoardController defaultController] copyObjects:@[ data ]];
@@ -548,56 +463,6 @@ NSString *const _MPTAbleSecurCellView = @"PasswordCell";
[[MPOverlayWindowController sharedController] displayOverlayImage:infoImage label:infoText atView:self.view];
}
- (void)_showTrashBar {
if([self hasFilter]) {
[self clearFilter:nil];
}
if(!self.trashBar) {
[self _setupTrashBar];
}
NSView *scrollView = [_entryTable enclosingScrollView];
NSDictionary *views = NSDictionaryOfVariableBindings(scrollView, _trashBar);
[[self view] layout];
[[self view] removeConstraint:self.tableToTopConstraint];
[[self view] addSubview:self.trashBar];
[[self view] addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_trashBar]|" options:0 metrics:nil views:views]];
[[self view] addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_trashBar(==30)]-0-[scrollView]" options:0 metrics:nil views:views]];
[NSAnimationContext runAnimationGroup:^(NSAnimationContext* context) {
context.duration = STATUS_BAR_ANIMATION_TIME;
context.allowsImplicitAnimation = YES;
[[self view] layoutSubtreeIfNeeded];
} completionHandler:nil] ;
//[[self view] layoutSubtreeIfNeeded];
}
- (void)_hideTrashBar {
if(![self.trashBar superview]) {
return; // Trahsbar is not visible
}
[self.trashBar removeFromSuperview];
[[self view] addConstraint:self.tableToTopConstraint];
[[self view] layoutSubtreeIfNeeded];
}
- (void)_setupTrashBar {
/* Load the bundle */
[[NSBundle mainBundle] loadNibNamed:@"TrashBar" owner:self topLevelObjects:nil];
NSArray *activeColors = @[
[NSColor colorWithCalibratedWhite:0.2 alpha:1],
[NSColor colorWithCalibratedWhite:0.4 alpha:1]
];
NSArray *inactiveColors = @[ [NSColor colorWithCalibratedWhite:0.3 alpha:1],
[NSColor colorWithCalibratedWhite:0.6 alpha:1]
];
self.trashBar.activeGradient = [[NSGradient alloc] initWithColors:activeColors];
self.trashBar.inactiveGradient = [[NSGradient alloc] initWithColors:inactiveColors];
}
#pragma mark Validation
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
MPDocument *document = [[self windowController] document];
@@ -609,7 +474,6 @@ NSString *const _MPTAbleSecurCellView = @"PasswordCell";
}
#pragma mark ContextMenu
- (void)_setupEntryMenu {
NSMenu *menu = [[NSMenu alloc] init];
@@ -711,35 +575,19 @@ NSString *const _MPTAbleSecurCellView = @"PasswordCell";
}
}
- (void)deleteNode:(id)sender {
- (IBAction)enterHistoryBrowser:(id)sender {
}
- (void)delete:(id)sender {
KPKEntry *entry =[self _clickedOrSelectedEntry];
if(!entry) {
return;
}
MPDocument *document = [[self windowController] document];
[document deleteEntry:entry];
}
//- (void)toggleHeader:(id)sender {
// //
//}
- (IBAction)_toggleFilterSpace:(id)sender {
if(![sender isKindOfClass:[NSButton class]]) {
return; // Wrong sender
}
NSButton *button = sender;
MPFilterModeType toggledMode = [button tag];
switch ([button state]) {
case NSOnState:
self.filterMode |= toggledMode;
break;
case NSOffState:
self.filterMode ^= toggledMode;
break;
default:
break;
}
}
- (void)_columnDoubleClick:(id)sender {
if(0 == [[self.entryArrayController arrangedObjects] count]) {
@@ -766,30 +614,4 @@ NSString *const _MPTAbleSecurCellView = @"PasswordCell";
// TODO: Add more actions for new columns
}
- (void)setFilterMode:(MPFilterModeType)newFilterMode {
if(_filterMode != newFilterMode) {
if(newFilterMode == MPFilterNone) {
newFilterMode = MPFilterTitles;
}
_filterMode = newFilterMode;
[self updateFilter];
}
}
- (BOOL)_shouldFilterTitles {
return (MPFilterNone != (self.filterMode & MPFilterTitles));
}
- (BOOL)_shouldFilterURLs {
return (MPFilterNone != (self.filterMode & MPFilterUrls));
}
- (BOOL)_shouldFilterUsernames {
return (MPFilterNone != (self.filterMode & MPFilterUsernames));
}
- (BOOL)_shouldFilterPasswords {
return (MPFilterNone != (self.filterMode & MPFilterPasswords));
}
@end

View File

@@ -53,7 +53,7 @@
views:views]];
[[self view] layoutSubtreeIfNeeded];
copyAction copyBlock = ^void(NSTextField *textField) {
void(^copyBlock)(NSTextField *textField) = ^void(NSTextField *textField) {
[[MPPasteBoardController defaultController] copyObjects:@[ textField.stringValue ]];
};

View File

@@ -27,7 +27,7 @@
typedef NS_ENUM(NSUInteger, MPContentTab) {
MPEntryTab,
MPGroupTab,
MPEmptyTab
MPEmptyTab,
};
@interface MPInspectorViewController () {

View File

@@ -27,9 +27,6 @@
#import "KPKGroup.h"
#import "KPKEntry.h"
#import "KPKUTIs.h"
#import "KPKEntry+TemplateCopy.h"
#import "KPKGroup+TemplateCopy.h"
#import "NSUUID+KeePassKit.h"
@@ -146,11 +143,7 @@
KPKGroup *targetGroup = (KPKGroup *)targetItem;
if(draggedGroup) {
if(copyItem || (nil == self.localDraggedGroup) ) {
/* Add Copy to title */
NSString *copyTemplate = NSLocalizedString(@"%@_COPY", "");
/* If we copy, we need to update the uuid */
draggedGroup.name = [NSString stringWithFormat:copyTemplate, draggedGroup.name];
draggedGroup.uuid = [NSUUID UUID];
draggedGroup = [draggedGroup copyWithName:nil options:0];
[targetGroup addGroup:draggedGroup atIndex:index];
[targetGroup.undoManager setActionName:NSLocalizedString(@"COPY_GROUP", "")];
return YES;
@@ -166,10 +159,7 @@
}
else if(draggedEntry) {
if(copyItem || (nil == self.localDraggedEntry)) {
/* if we copy, we need to update the uuid */
NSString *copyTemplate = NSLocalizedString(@"%@_COPY", "");
draggedEntry.title = [NSString stringWithFormat:copyTemplate, draggedEntry.title];
draggedEntry.uuid = [NSUUID UUID];
draggedEntry = [draggedEntry copyWithTitle:nil options:0];
[targetGroup addEntry:draggedEntry atIndex:index];
[targetGroup.undoManager setActionName:NSLocalizedString(@"COPY_ENTRY", "")];
return YES;

View File

@@ -25,7 +25,6 @@ APPKIT_EXTERN NSString *const MPOutlineViewDidChangeGroupSelection;
- (void)createGroup:(id)sender;
- (void)createEntry:(id)sender;
- (void)deleteNode:(id)sender;
/**
* Retrieves the current item for the current mouse location
* @return Item under mouse. If the mouse isn't inside the view, nil is returned

View File

@@ -180,7 +180,7 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
[document createEntry:[self _clickedOrSelectedGroup]];
}
- (void)deleteNode:(id)sender {
- (void)delete:(id)sender {
[[[self windowController] document] deleteGroup:[self _clickedOrSelectedGroup]];
}

View File

@@ -1,38 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="4514" systemVersion="13A603" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment defaultVersion="1080" identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="4514"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="MPEntryViewController">
<connections>
<outlet property="trashBar" destination="1" id="22"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application"/>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="1" customClass="HNHGradientView">
<rect key="frame" x="0.0" y="0.0" width="178" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="13">
<rect key="frame" x="72" y="5" width="86" height="19"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="roundRect" title="Empty Trash" bezelStyle="roundedRect" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="14">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="cellTitle"/>
</buttonCell>
<connections>
<action selector="emptyTrash:" target="-1" id="23"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstItem="13" firstAttribute="centerY" secondItem="1" secondAttribute="centerY" id="18"/>
<constraint firstAttribute="trailing" secondItem="13" secondAttribute="trailing" constant="20" symbolic="YES" id="20"/>
<constraint firstItem="13" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="1" secondAttribute="leading" constant="20" symbolic="YES" id="21"/>
</constraints>
</customView>
</objects>
</document>

Binary file not shown.