diff --git a/.gitmodules b/.gitmodules index 19491809..15d5bd0a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,3 +16,6 @@ [submodule "Sparkle"] path = Sparkle url = https://github.com/mstarke/Sparkle.git +[submodule "TransformerKit"] + path = TransformerKit + url = https://github.com/mattt/TransformerKit.git diff --git a/MacPass.xcodeproj/project.pbxproj b/MacPass.xcodeproj/project.pbxproj index 3ccae12b..f2935183 100644 --- a/MacPass.xcodeproj/project.pbxproj +++ b/MacPass.xcodeproj/project.pbxproj @@ -88,6 +88,13 @@ 4C37A84015B8B474005EF8EE /* MPOutlineDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C37A83F15B8B474005EF8EE /* MPOutlineDataSource.m */; }; 4C39B3F5178FEFAE0027DC7C /* KPKNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C39B3F4178FEFAE0027DC7C /* KPKNode.m */; }; 4C3BD51516D276F800389F1F /* MPToolbarDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C3BD51416D276F800389F1F /* MPToolbarDelegate.m */; }; + 4C3C4EA218D6FEA100153127 /* NSValueTransformer+TransformerKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C3C4E9618D6FEA100153127 /* NSValueTransformer+TransformerKit.m */; }; + 4C3C4EA318D6FEA100153127 /* TTTCryptographyTransformers.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C3C4E9918D6FEA100153127 /* TTTCryptographyTransformers.m */; }; + 4C3C4EA418D6FEA100153127 /* TTTDateTransformers.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C3C4E9B18D6FEA100153127 /* TTTDateTransformers.m */; }; + 4C3C4EA518D6FEA100153127 /* TTTImageTransformers.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C3C4E9D18D6FEA100153127 /* TTTImageTransformers.m */; }; + 4C3C4EA618D6FEA100153127 /* TTTJSONTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C3C4E9F18D6FEA100153127 /* TTTJSONTransformer.m */; }; + 4C3C4EA718D6FEA100153127 /* TTTStringTransformers.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C3C4EA118D6FEA100153127 /* TTTStringTransformers.m */; }; + 4C3C4EAF18D7039300153127 /* MPValueTransformerHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C3C4EAE18D7039300153127 /* MPValueTransformerHelper.m */; }; 4C3D4C0817594CA40038DAAC /* HNHSeparator.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C3D4C0717594CA40038DAAC /* HNHSeparator.m */; }; 4C3F28541791EDFD00703281 /* KPKErrors.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C3F28531791EDFD00703281 /* KPKErrors.m */; }; 4C3FFD9E16DAF60600DF9186 /* ContextBar.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C3FFD9D16DAF60600DF9186 /* ContextBar.xib */; }; @@ -130,7 +137,6 @@ 4C5A11FE1708DE8700223D8A /* MPPasswordCreatorViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C5A11FC1708DE8700223D8A /* MPPasswordCreatorViewController.m */; }; 4C5A11FF1708DE8800223D8A /* PasswordCreatorView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C5A11FD1708DE8700223D8A /* PasswordCreatorView.xib */; }; 4C5AA591179549A1008ECAD7 /* KPKXmlTreeWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C5AA590179549A1008ECAD7 /* KPKXmlTreeWriter.m */; }; - 4C5BF67B175C01F300D53DF7 /* MPUppercaseStringValueTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C5BF67A175C01F300D53DF7 /* MPUppercaseStringValueTransformer.m */; }; 4C5CD35517D15DBD000B7F38 /* NSData+Gzip.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C5CD34A17D15DBD000B7F38 /* NSData+Gzip.m */; }; 4C5CD35617D15DBD000B7F38 /* NSData+Random.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C5CD34C17D15DBD000B7F38 /* NSData+Random.m */; }; 4C5CD35717D15DBD000B7F38 /* NSDate+Packed.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C5CD34E17D15DBD000B7F38 /* NSDate+Packed.m */; }; @@ -160,7 +166,6 @@ 4C68456F17BC2A0700FCDBFC /* WelcomeWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C68456E17BC2A0700FCDBFC /* WelcomeWindow.xib */; }; 4C69A73A16D589DF00EC1B1A /* HNHGradientView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C69A73916D589DF00EC1B1A /* HNHGradientView.m */; }; 4C6B7C7D18BE7EB0001D5D77 /* MPDocument+HistoryBrowsing.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C6B7C7C18BE7EB0001D5D77 /* MPDocument+HistoryBrowsing.m */; }; - 4C6BEA3117A88E6C00CF69A8 /* MPStripLineBreaksTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C6BEA3017A88E6C00CF69A8 /* MPStripLineBreaksTransformer.m */; }; 4C6C72C417C01E4200768849 /* NSMutableData+KeePassKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C6C72C317C01E4200768849 /* NSMutableData+KeePassKit.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 */; }; @@ -499,6 +504,21 @@ 4C39B3F4178FEFAE0027DC7C /* KPKNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KPKNode.m; sourceTree = ""; }; 4C3BD51316D276F800389F1F /* MPToolbarDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPToolbarDelegate.h; sourceTree = ""; }; 4C3BD51416D276F800389F1F /* MPToolbarDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPToolbarDelegate.m; sourceTree = ""; }; + 4C3C4E9518D6FEA100153127 /* NSValueTransformer+TransformerKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSValueTransformer+TransformerKit.h"; sourceTree = ""; }; + 4C3C4E9618D6FEA100153127 /* NSValueTransformer+TransformerKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSValueTransformer+TransformerKit.m"; sourceTree = ""; }; + 4C3C4E9718D6FEA100153127 /* TransformerKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TransformerKit.h; sourceTree = ""; }; + 4C3C4E9818D6FEA100153127 /* TTTCryptographyTransformers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TTTCryptographyTransformers.h; sourceTree = ""; }; + 4C3C4E9918D6FEA100153127 /* TTTCryptographyTransformers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TTTCryptographyTransformers.m; sourceTree = ""; }; + 4C3C4E9A18D6FEA100153127 /* TTTDateTransformers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TTTDateTransformers.h; sourceTree = ""; }; + 4C3C4E9B18D6FEA100153127 /* TTTDateTransformers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TTTDateTransformers.m; sourceTree = ""; }; + 4C3C4E9C18D6FEA100153127 /* TTTImageTransformers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TTTImageTransformers.h; sourceTree = ""; }; + 4C3C4E9D18D6FEA100153127 /* TTTImageTransformers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TTTImageTransformers.m; sourceTree = ""; }; + 4C3C4E9E18D6FEA100153127 /* TTTJSONTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TTTJSONTransformer.h; sourceTree = ""; }; + 4C3C4E9F18D6FEA100153127 /* TTTJSONTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TTTJSONTransformer.m; sourceTree = ""; }; + 4C3C4EA018D6FEA100153127 /* TTTStringTransformers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TTTStringTransformers.h; sourceTree = ""; }; + 4C3C4EA118D6FEA100153127 /* TTTStringTransformers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TTTStringTransformers.m; sourceTree = ""; }; + 4C3C4EAD18D7039300153127 /* MPValueTransformerHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPValueTransformerHelper.h; sourceTree = ""; }; + 4C3C4EAE18D7039300153127 /* MPValueTransformerHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPValueTransformerHelper.m; sourceTree = ""; }; 4C3D4C0617594CA40038DAAC /* HNHSeparator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HNHSeparator.h; sourceTree = ""; }; 4C3D4C0717594CA40038DAAC /* HNHSeparator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HNHSeparator.m; sourceTree = ""; }; 4C3F28521791EDE800703281 /* KPKErrors.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KPKErrors.h; sourceTree = ""; }; @@ -568,8 +588,6 @@ 4C5AA590179549A1008ECAD7 /* KPKXmlTreeWriter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KPKXmlTreeWriter.m; sourceTree = ""; }; 4C5ADC2E17830AFB004E1E8D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InspectorView.strings; sourceTree = ""; }; 4C5ADC3017830B09004E1E8D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InspectorView.strings; sourceTree = ""; }; - 4C5BF679175C01F300D53DF7 /* MPUppercaseStringValueTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPUppercaseStringValueTransformer.h; sourceTree = ""; }; - 4C5BF67A175C01F300D53DF7 /* MPUppercaseStringValueTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPUppercaseStringValueTransformer.m; sourceTree = ""; }; 4C5CD34017D158DE000B7F38 /* fr */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; }; 4C5CD34117D158DE000B7F38 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = fr; path = fr.lproj/Credits.rtf; sourceTree = ""; }; 4C5CD34217D158DE000B7F38 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; @@ -630,8 +648,6 @@ 4C69A73916D589DF00EC1B1A /* HNHGradientView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HNHGradientView.m; sourceTree = ""; }; 4C6B7C7B18BE7EB0001D5D77 /* MPDocument+HistoryBrowsing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MPDocument+HistoryBrowsing.h"; sourceTree = ""; }; 4C6B7C7C18BE7EB0001D5D77 /* MPDocument+HistoryBrowsing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MPDocument+HistoryBrowsing.m"; sourceTree = ""; }; - 4C6BEA2F17A88E6C00CF69A8 /* MPStripLineBreaksTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPStripLineBreaksTransformer.h; sourceTree = ""; }; - 4C6BEA3017A88E6C00CF69A8 /* MPStripLineBreaksTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPStripLineBreaksTransformer.m; sourceTree = ""; }; 4C6C72C217C01E4200768849 /* NSMutableData+KeePassKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableData+KeePassKit.h"; sourceTree = ""; }; 4C6C72C317C01E4200768849 /* NSMutableData+KeePassKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMutableData+KeePassKit.m"; sourceTree = ""; }; 4C6D1D24178579570014C5A5 /* 48_FolderTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 48_FolderTemplate.pdf; sourceTree = ""; }; @@ -1156,12 +1172,8 @@ 4C2E382016D141F700037A9D /* Helper */ = { isa = PBXGroup; children = ( - 4C5BF679175C01F300D53DF7 /* MPUppercaseStringValueTransformer.h */, - 4C5BF67A175C01F300D53DF7 /* MPUppercaseStringValueTransformer.m */, 4CF6C70F176F4533007A811D /* MPStringLengthValueTransformer.h */, 4CF6C710176F4533007A811D /* MPStringLengthValueTransformer.m */, - 4C6BEA2F17A88E6C00CF69A8 /* MPStripLineBreaksTransformer.h */, - 4C6BEA3017A88E6C00CF69A8 /* MPStripLineBreaksTransformer.m */, 4C888C9516EB754B003D34A1 /* MPActionHelper.h */, 4C888C9616EB754B003D34A1 /* MPActionHelper.m */, 4C2E382116D1421B00037A9D /* MPIconHelper.h */, @@ -1177,6 +1189,8 @@ 4C224B4017DFCB2300FF6AEE /* MPNumericalInputFormatter.h */, 4C224B4117DFCB2400FF6AEE /* MPNumericalInputFormatter.m */, 4CB63A6018986530002DEC4C /* MPFlagsHelper.h */, + 4C3C4EAD18D7039300153127 /* MPValueTransformerHelper.h */, + 4C3C4EAE18D7039300153127 /* MPValueTransformerHelper.m */, ); name = Helper; sourceTree = ""; @@ -1240,6 +1254,27 @@ name = Model; sourceTree = ""; }; + 4C3C4E9418D6FEA100153127 /* TransformerKit */ = { + isa = PBXGroup; + children = ( + 4C3C4E9518D6FEA100153127 /* NSValueTransformer+TransformerKit.h */, + 4C3C4E9618D6FEA100153127 /* NSValueTransformer+TransformerKit.m */, + 4C3C4E9718D6FEA100153127 /* TransformerKit.h */, + 4C3C4E9818D6FEA100153127 /* TTTCryptographyTransformers.h */, + 4C3C4E9918D6FEA100153127 /* TTTCryptographyTransformers.m */, + 4C3C4E9A18D6FEA100153127 /* TTTDateTransformers.h */, + 4C3C4E9B18D6FEA100153127 /* TTTDateTransformers.m */, + 4C3C4E9C18D6FEA100153127 /* TTTImageTransformers.h */, + 4C3C4E9D18D6FEA100153127 /* TTTImageTransformers.m */, + 4C3C4E9E18D6FEA100153127 /* TTTJSONTransformer.h */, + 4C3C4E9F18D6FEA100153127 /* TTTJSONTransformer.m */, + 4C3C4EA018D6FEA100153127 /* TTTStringTransformers.h */, + 4C3C4EA118D6FEA100153127 /* TTTStringTransformers.m */, + ); + name = TransformerKit; + path = TransformerKit/TransformerKit; + sourceTree = ""; + }; 4C45FB1E178E09ED0010007D /* MacPassTests */ = { isa = PBXGroup; children = ( @@ -1356,6 +1391,7 @@ 4CC5D35218A1162100AF7FA8 /* Sparkle.xcodeproj */, 4C00E33917D8FA3B00F37192 /* DDHotKey */, 4C245A64176E1E3C0086100E /* CocoaHTTPServer */, + 4C3C4E9418D6FEA100153127 /* TransformerKit */, 4CC3AAB6175F4983003EF01B /* HNHUi */, 4CD3ABAD178F71B50073F5C5 /* KeePassKit */, 4CAD745415B887FD00104512 /* KissXML */, @@ -2136,7 +2172,6 @@ 4C5A11FE1708DE8700223D8A /* MPPasswordCreatorViewController.m in Sources */, 4CE5B54B173AFBA700207B39 /* MPDocument.m in Sources */, 4C3D4C0817594CA40038DAAC /* HNHSeparator.m in Sources */, - 4C5BF67B175C01F300D53DF7 /* MPUppercaseStringValueTransformer.m in Sources */, 4CC3AABD175F4983003EF01B /* HNHRoundedTextFieldCell.m in Sources */, 4C9D6AA917615199001C660C /* HNHRoundedSecureTextFieldCell.m in Sources */, 4C4A100F176286FD00BBF2CA /* MPTableView.m in Sources */, @@ -2150,6 +2185,7 @@ 4C569DA117652BFE00595B62 /* MPEntryTableDataSource.m in Sources */, 4C79DF2A176685870083708F /* HNHRoundedTextField.m in Sources */, 4C46E09E17673A0A00DA62E8 /* HNHShadowBox.m in Sources */, + 4C3C4EA318D6FEA100153127 /* TTTCryptographyTransformers.m in Sources */, 4C37A6731769393300AD0A40 /* HNHTableHeaderCell.m in Sources */, 4C89F521182F9FDD0069C73C /* NSString+Commands.m in Sources */, 4CA2335A176DBFE100F0B6AC /* MPLockDaemon.m in Sources */, @@ -2157,10 +2193,13 @@ 4C245B76176E1E3D0086100E /* DDData.m in Sources */, 4C245B77176E1E3D0086100E /* DDNumber.m in Sources */, 4C245B78176E1E3D0086100E /* DDRange.m in Sources */, + 4C3C4EA618D6FEA100153127 /* TTTJSONTransformer.m in Sources */, 4C245B79176E1E3D0086100E /* HTTPAuthenticationRequest.m in Sources */, 4C245B7A176E1E3D0086100E /* HTTPConnection.m in Sources */, 4C245B7B176E1E3D0086100E /* HTTPMessage.m in Sources */, + 4C3C4EA718D6FEA100153127 /* TTTStringTransformers.m in Sources */, 4C245B7C176E1E3D0086100E /* HTTPServer.m in Sources */, + 4C3C4EAF18D7039300153127 /* MPValueTransformerHelper.m in Sources */, 4C245B7D176E1E3D0086100E /* MultipartFormDataParser.m in Sources */, 4C245B7E176E1E3D0086100E /* MultipartMessageHeader.m in Sources */, 4C245B7F176E1E3D0086100E /* MultipartMessageHeaderField.m in Sources */, @@ -2169,6 +2208,7 @@ 4C245B82176E1E3D0086100E /* HTTPDynamicFileResponse.m in Sources */, 4C245B83176E1E3D0086100E /* HTTPErrorResponse.m in Sources */, 4C245B84176E1E3D0086100E /* HTTPFileResponse.m in Sources */, + 4C3C4EA218D6FEA100153127 /* NSValueTransformer+TransformerKit.m in Sources */, 4C245B85176E1E3D0086100E /* HTTPRedirectResponse.m in Sources */, 4C245B86176E1E3D0086100E /* WebSocket.m in Sources */, 4C245BE9176E1E3D0086100E /* GCDAsyncSocket.m in Sources */, @@ -2204,6 +2244,7 @@ 4CD3ABC2178F72720073F5C5 /* KPKGroup.m in Sources */, 4C591B57178F897A0080B16B /* KPKBinary.m in Sources */, 4C0C59F118B17F10009C7B76 /* DDHotKeyUtilities.m in Sources */, + 4C3C4EA418D6FEA100153127 /* TTTDateTransformers.m in Sources */, 4CEE46DD181C301D006BF1E5 /* MPAutotypeDaemon.m in Sources */, 4CA3530B18A53CB800839B0F /* MPKeyMapper.m in Sources */, 4C39B3F5178FEFAE0027DC7C /* KPKNode.m in Sources */, @@ -2252,7 +2293,6 @@ 4CD7223B17A7CB0700F5A1E1 /* MPWorkflowSettingsController.m in Sources */, 4C2671AD17A7D8FC00F3A645 /* HNHColorWell.m in Sources */, 4CA08DA017A831B200A6544B /* MPAddEntryContextMenuDelegate.m in Sources */, - 4C6BEA3117A88E6C00CF69A8 /* MPStripLineBreaksTransformer.m in Sources */, 4C79E80317A9187400AC6CD2 /* KPKXmlHeaderWriter.m in Sources */, 4CE3E62617AB0D2D00D9E4B4 /* MPAttachmentTableDataSource.m in Sources */, 4C6366AC17AF1E0100AAF17D /* NSColor+KeePassKit.m in Sources */, @@ -2277,6 +2317,7 @@ 4C5CD36117D15DCA000B7F38 /* KPKArc4RandomStream.m in Sources */, 4C5CD36217D15DCA000B7F38 /* KPKRandomStream.m in Sources */, 4C5CD36317D15DCA000B7F38 /* KPKSalsa20RandomStream.m in Sources */, + 4C3C4EA518D6FEA100153127 /* TTTImageTransformers.m in Sources */, 4CC6DB7A17D23719002C6091 /* KPKNode+IconImage.m in Sources */, 4CC6DB7D17D23DCE002C6091 /* KPKUTIs.m in Sources */, 4C15B74618BCA3B1003F8008 /* MPDocument+Search.m in Sources */, diff --git a/MacPass/Base.lproj/InspectorView.xib b/MacPass/Base.lproj/InspectorView.xib index 00fd3eb4..83f4142c 100644 --- a/MacPass/Base.lproj/InspectorView.xib +++ b/MacPass/Base.lproj/InspectorView.xib @@ -70,7 +70,7 @@ - + diff --git a/MacPass/DatePickingView.xib b/MacPass/DatePickingView.xib index 7c698356..074267ae 100644 --- a/MacPass/DatePickingView.xib +++ b/MacPass/DatePickingView.xib @@ -15,11 +15,11 @@ - + - + @@ -49,10 +49,11 @@ AQABAAEAAQAB//+dkAEA//+PgAAE//+dkAEI//+dkAEMUERUAFBTVABQV1QAUFBUAAAAAAEAAAABA + - + @@ -61,7 +62,7 @@ AQABAAEAAQAB//+dkAEA//+PgAAE//+dkAEI//+dkAEMUERUAFBTVABQV1QAUFBUAAAAAAEAAAABA - @@ -661,6 +662,7 @@ + diff --git a/MacPass/GroupInspectorView.xib b/MacPass/GroupInspectorView.xib index 9a245879..c2b05037 100644 --- a/MacPass/GroupInspectorView.xib +++ b/MacPass/GroupInspectorView.xib @@ -9,7 +9,7 @@ - + @@ -47,24 +47,27 @@ - - @@ -125,6 +128,7 @@ + @@ -157,7 +161,6 @@ - diff --git a/MacPass/MPAppDelegate.m b/MacPass/MPAppDelegate.m index 1b1ab11d..206540b2 100644 --- a/MacPass/MPAppDelegate.m +++ b/MacPass/MPAppDelegate.m @@ -25,9 +25,8 @@ #import "MPSettingsWindowController.h" #import "MPPasswordCreatorViewController.h" #import "MPSettingsHelper.h" -#import "MPUppercaseStringValueTransformer.h" #import "MPStringLengthValueTransformer.h" -#import "MPStripLineBreaksTransformer.h" +#import "MPValueTransformerHelper.h" #import "MPServerDaemon.h" #import "MPLockDaemon.h" #import "MPAutotypeDaemon.h" @@ -57,9 +56,8 @@ NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDi + (void)initialize { [MPSettingsHelper setupDefaults]; [MPSettingsHelper migrateDefaults]; - [MPUppercaseStringValueTransformer registerTransformer]; [MPStringLengthValueTransformer registerTransformer]; - [MPStripLineBreaksTransformer registerTransformer]; + [MPValueTransformerHelper registerValueTransformer]; } - (void)dealloc { diff --git a/MacPass/MPDatePickingViewController.h b/MacPass/MPDatePickingViewController.h index 731d06a0..b9162806 100644 --- a/MacPass/MPDatePickingViewController.h +++ b/MacPass/MPDatePickingViewController.h @@ -16,5 +16,6 @@ - (IBAction)useDate:(id)sender; - (IBAction)cancel:(id)sender; +- (IBAction)setDatePreset:(id)sender; @end diff --git a/MacPass/MPDatePickingViewController.m b/MacPass/MPDatePickingViewController.m index 059e3427..8199916b 100644 --- a/MacPass/MPDatePickingViewController.m +++ b/MacPass/MPDatePickingViewController.m @@ -8,7 +8,11 @@ #import "MPDatePickingViewController.h" -typedef NS_ENUM(NSUInteger, MPDatePresets) { +#import "MPDocument.h" +#import "KPKNode.h" +#import "KPKTimeInfo.h" + +typedef NS_ENUM(NSUInteger, MPDatePreset) { MPDatePresetTomorrow, MPDatePresetOneWeek, MPDatePresetOneMonth, @@ -30,16 +34,18 @@ typedef NS_ENUM(NSUInteger, MPDatePresets) { - (void)awakeFromNib { NSMenu *presetMenu = [[NSMenu alloc] init]; - NSDictionary *dateItems = @{ @(MPDatePresetTomorrow): NSLocalizedString(@"TOMORROW", ""), - @(MPDatePresetOneWeek): NSLocalizedString(@"ONE_WEEK", ""), - @(MPDatePresetOneMonth): NSLocalizedString(@"ONE_MONTH", ""), - @(MPDatePresetOneYear): NSLocalizedString(@"ONE_YEAR", "") }; - for(NSNumber *tagNumber in dateItems) { - NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:dateItems[tagNumber] action:NULL keyEquivalent:@""]; - [item setTag:[tagNumber integerValue]]; + NSUInteger tags[] = { MPDatePresetTomorrow, MPDatePresetOneWeek, MPDatePresetOneMonth, MPDatePresetOneYear }; + NSArray *dateItems = @[ NSLocalizedString(@"TOMORROW", ""), NSLocalizedString(@"ONE_WEEK", ""), NSLocalizedString(@"ONE_MONTH", ""), NSLocalizedString(@"ONE_YEAR", "") ]; + for(NSInteger iIndex = 0; iIndex < sizeof(tags)/sizeof(NSUInteger); iIndex++) { + NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:dateItems[iIndex] action:NULL keyEquivalent:@""]; + [item setTag:tags[iIndex]]; [presetMenu addItem:item]; } + MPDocument *document = [[self windowController] document]; + + [self.datePicker setDateValue:document.selectedItem.timeInfo.expiryTime]; + [self.presetPopupButton setAction:@selector(setDatePreset:)]; [self.presetPopupButton setMenu:presetMenu]; } @@ -54,4 +60,30 @@ typedef NS_ENUM(NSUInteger, MPDatePresets) { id target = [NSApp targetForAction:@selector(performClose:)]; [target performClose:sender]; } + +- (IBAction)setDatePreset:(id)sender { + NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; + NSDateComponents *offsetComponents = [[NSDateComponents alloc] init]; + + MPDatePreset preset = [[sender selectedItem] tag]; + switch(preset) { + case MPDatePresetTomorrow: + [offsetComponents setDay:1]; + break; + case MPDatePresetOneWeek: + [offsetComponents setWeek:1]; + break; + case MPDatePresetOneMonth: + [offsetComponents setMonth:1]; + break; + case MPDatePresetOneYear: + [offsetComponents setYear:1]; + break; + default: + break; + } + NSDate *newDate = [gregorian dateByAddingComponents:offsetComponents toDate:[NSDate date] options:0]; + [self.datePicker setDateValue:newDate]; +} + @end diff --git a/MacPass/MPDocument.h b/MacPass/MPDocument.h index 1beb3b36..387a5d1d 100644 --- a/MacPass/MPDocument.h +++ b/MacPass/MPDocument.h @@ -95,7 +95,7 @@ typedef NS_OPTIONS(NSUInteger, MPEntrySearchFlags) { + (NSString *)fileTypeForVersion:(KPKVersion)version; #pragma mark Lock/Decrypt -- (void)lockDatabase:(id)sender; +- (IBAction)lockDatabase:(id)sender; /** * Decrypts the databse with the given password and keyfile * diff --git a/MacPass/MPDocumentWindowController.h b/MacPass/MPDocumentWindowController.h index 7743a1dc..0fecb78f 100644 --- a/MacPass/MPDocumentWindowController.h +++ b/MacPass/MPDocumentWindowController.h @@ -43,9 +43,11 @@ - (IBAction)importFromXML:(id)sender; - (IBAction)lock:(id)sender; - - (IBAction)createGroup:(id)sender; +- (IBAction)pickIcon:(id)sender; +- (IBAction)pickExpiryDate:(id)sender; + #pragma mark View Actions - (IBAction)toggleInspector:(id)sender; - (IBAction)focusGroups:(id)sender; diff --git a/MacPass/MPDocumentWindowController.m b/MacPass/MPDocumentWindowController.m index 566fa6c0..e4b9a0df 100644 --- a/MacPass/MPDocumentWindowController.m +++ b/MacPass/MPDocumentWindowController.m @@ -288,6 +288,14 @@ typedef void (^MPPasswordChangedBlock)(void); [_outlineViewController createEntry:nil]; } +- (void)pickIcon:(id)sender { + [self.inspectorViewController pickIcon:sender]; +} + +- (void)pickExpiryDate:(id)sender { + [self.inspectorViewController pickExpiryDate:sender]; +} + - (void)toggleInspector:(id)sender { NSView *inspectorView = [_inspectorViewController view]; BOOL inspectorVisible = NO; @@ -303,6 +311,7 @@ typedef void (^MPPasswordChangedBlock)(void); options:0 metrics:nil views:NSDictionaryOfVariableBindings(inspectorView)]]; + [self.inspectorViewController updateResponderChain]; } [[NSUserDefaults standardUserDefaults] setBool:inspectorVisible forKey:kMPSettingsKeyShowInspector]; } @@ -328,7 +337,6 @@ typedef void (^MPPasswordChangedBlock)(void); [[contentView subviews][0] removeFromSuperviewWithoutNeedingDisplay]; } [contentView addSubview:_splitView]; - //[_splitView adjustSubviews]; NSView *outlineView = [_outlineViewController view]; NSView *inspectorView = [_inspectorViewController view]; NSView *entryView = [_entryViewController view]; diff --git a/MacPass/MPEntryInspectorViewController.m b/MacPass/MPEntryInspectorViewController.m index 4f11bd7c..28087531 100644 --- a/MacPass/MPEntryInspectorViewController.m +++ b/MacPass/MPEntryInspectorViewController.m @@ -15,10 +15,12 @@ #import "MPDocument.h" #import "MPIconHelper.h" +#import "MPValueTransformerHelper.h" #import "KPKEntry.h" #import "KPKBinary.h" #import "KPKAutotype.h" +#import "KPKTimeInfo.h" #import "KPKWindowAssociation.h" #import "HNHScrollView.h" @@ -266,12 +268,15 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) { } - (void)_bindEntry { - if(self.entry) { [self.titleTextField bind:NSValueBinding toObject:self.entry withKeyPath:@"title" options:nil]; [self.passwordTextField bind:NSValueBinding toObject:self.entry withKeyPath:@"password" options:nil]; [self.usernameTextField bind:NSValueBinding toObject:self.entry withKeyPath:@"username" options:nil]; [self.URLTextField bind:NSValueBinding toObject:self.entry withKeyPath:@"url" options:nil]; + [self.expiresCheckButton bind:NSTitleBinding + toObject:self.entry.timeInfo + withKeyPath:NSStringFromSelector(@selector(expiryTime)) + options:@{ NSValueTransformerNameBindingOption:MPExpiryDateValueTransformer }]; [self.expiresCheckButton bind:NSValueBinding toObject:self.entry.timeInfo withKeyPath:@"expires" options:nil]; [self.tagsTokenField bind:NSValueBinding toObject:self.entry withKeyPath:@"tags" options:nil]; } @@ -281,6 +286,7 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) { [self.usernameTextField unbind:NSValueBinding]; [self.URLTextField unbind:NSValueBinding]; [self.expiresCheckButton unbind:NSValueBinding]; + [self.expiresCheckButton unbind:NSTitleBinding]; } } diff --git a/MacPass/MPEntryViewController.m b/MacPass/MPEntryViewController.m index dd8cd0d5..c540d133 100644 --- a/MacPass/MPEntryViewController.m +++ b/MacPass/MPEntryViewController.m @@ -24,7 +24,7 @@ #import "MPSettingsHelper.h" #import "MPEntryTableDataSource.h" #import "MPStringLengthValueTransformer.h" -#import "MPStripLineBreaksTransformer.h" +#import "MPValueTransformerHelper.h" #import "MPEntryContextMenuDelegate.h" #import "KPKUTIs.h" @@ -32,6 +32,7 @@ #import "KPKEntry.h" #import "KPKNode+IconImage.h" #import "KPKAttribute.h" +#import "KPKTimeInfo.h" #import "HNHTableHeaderCell.h" #import "HNHGradientView.h" @@ -149,11 +150,13 @@ NSString *const _MPTAbleSecurCellView = @"PasswordCell"; [self.entryTable setAutosaveName:@"EntryTable"]; [self.entryTable setAutosaveTableColumns:YES]; - NSSortDescriptor *titleColumSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"title" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)]; - NSSortDescriptor *userNameSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"username" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)]; - NSSortDescriptor *urlSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"url" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)]; - NSSortDescriptor *groupnameSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"parent.name" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)]; - NSSortDescriptor *dateSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"timeInfo.lastModificationTime" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)]; + NSString *parentNameKeyPath = [[NSString alloc] initWithFormat:@"%@.%@", NSStringFromSelector(@selector(parent)), NSStringFromSelector(@selector(name))]; + NSString *timeInfoModificationTimeKeyPath = [[NSString alloc] initWithFormat:@"%@.%@", NSStringFromSelector(@selector(timeInfo)), NSStringFromSelector(@selector(lastModificationTime))]; + NSSortDescriptor *titleColumSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:NSStringFromSelector(@selector(title))ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)]; + NSSortDescriptor *userNameSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:NSStringFromSelector(@selector(username)) ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)]; + NSSortDescriptor *urlSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:NSStringFromSelector(@selector(url)) ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)]; + NSSortDescriptor *groupnameSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:parentNameKeyPath ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)]; + NSSortDescriptor *dateSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:timeInfoModificationTimeKeyPath ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)]; [titleColumn setSortDescriptorPrototype:titleColumSortDescriptor]; [userNameColumn setSortDescriptorPrototype:userNameSortDescriptor]; @@ -270,18 +273,18 @@ NSString *const _MPTAbleSecurCellView = @"PasswordCell"; }); [textField setFormatter:formatter]; } - [textField bind:NSValueBinding toObject:entry.timeInfo withKeyPath:@"lastModificationTime" options:nil]; + [textField bind:NSValueBinding toObject:entry.timeInfo withKeyPath:NSStringFromSelector(@selector(lastModificationTime)) options:nil]; return view; } else if(isURLColumn) { - [textField bind:NSValueBinding toObject:entry withKeyPath:@"url" options:nil]; + [textField bind:NSValueBinding toObject:entry withKeyPath:NSStringFromSelector(@selector(url)) options:nil]; } else if(isUsernameColumn) { - [textField bind:NSValueBinding toObject:entry withKeyPath:@"username" options:nil]; + [textField bind:NSValueBinding toObject:entry withKeyPath:NSStringFromSelector(@selector(username)) options:nil]; } else if(isNotesColumn) { NSDictionary *options = @{ NSValueTransformerNameBindingOption : MPStripLineBreaksTransformerName }; - [textField bind:NSValueBinding toObject:entry withKeyPath:@"notes" options:options]; + [textField bind:NSValueBinding toObject:entry withKeyPath:NSStringFromSelector(@selector(notes)) options:options]; } else if(isAttachmentColumn) { [textField bind:NSValueBinding toObject:entry withKeyPath:@"binaries.@count" options:nil]; @@ -322,7 +325,7 @@ NSString *const _MPTAbleSecurCellView = @"PasswordCell"; return; // we are showing the correct object right now. } } - [self.entryArrayController bind:NSContentArrayBinding toObject:document.selectedGroup withKeyPath:@"entries" options:nil]; + [self.entryArrayController bind:NSContentArrayBinding toObject:document.selectedGroup withKeyPath:NSStringFromSelector(@selector(entries)) options:nil]; } [self _updateContextBar]; } diff --git a/MacPass/MPGroupInspectorViewController.m b/MacPass/MPGroupInspectorViewController.m index 558d97ba..826e84cc 100644 --- a/MacPass/MPGroupInspectorViewController.m +++ b/MacPass/MPGroupInspectorViewController.m @@ -9,6 +9,7 @@ #import "MPGroupInspectorViewController.h" #import "MPDocument.h" #import "MPPasteBoardController.h" +#import "MPValueTransformerHelper.h" #import "KPKGroup.h" #import "KPKTimeInfo.h" @@ -16,6 +17,7 @@ #import "HNHScrollView.h" #import "HNHRoundedTextField.h" + @interface MPGroupInspectorViewController () @property (nonatomic, weak) KPKGroup *group; @@ -54,7 +56,6 @@ metrics:nil views:views]]; [[self view] layoutSubtreeIfNeeded]; - /* void(^copyBlock)(NSTextField *textField) = ^void(NSTextField *textField) { [[MPPasteBoardController defaultController] copyObjects:@[ textField.stringValue ]]; @@ -79,6 +80,10 @@ if(self.group) { [self.titleTextField bind:NSValueBinding toObject:self.group withKeyPath:NSStringFromSelector(@selector(name)) options:nil]; [self.expiresCheckButton bind:NSValueBinding toObject:self.group.timeInfo withKeyPath:NSStringFromSelector(@selector(expires)) options:nil]; + [self.expiresCheckButton bind:NSTitleBinding + toObject:self.group.timeInfo + withKeyPath:NSStringFromSelector(@selector(expiryTime)) + options:@{ NSValueTransformerNameBindingOption:MPExpiryDateValueTransformer }]; [self.expireDateSelectButton bind:NSHiddenBinding toObject:self.group.timeInfo withKeyPath:NSStringFromSelector(@selector(expires)) @@ -90,6 +95,8 @@ [self.titleTextField unbind:NSValueBinding]; [self.expiresCheckButton unbind:NSValueBinding]; + [self.expiresCheckButton unbind:NSTitleBinding]; + [self.expiresCheckButton setTitle:NSLocalizedString(@"EXPIRES", "")]; [self.expireDateSelectButton unbind:NSHiddenBinding]; [self.autotypePopupButton unbind:NSSelectedTagBinding]; [self.searchPopupButton unbind:NSSelectedTagBinding]; diff --git a/MacPass/MPInspectorViewController.h b/MacPass/MPInspectorViewController.h index ce5481ee..53f5761f 100644 --- a/MacPass/MPInspectorViewController.h +++ b/MacPass/MPInspectorViewController.h @@ -22,7 +22,7 @@ @property (weak) IBOutlet NSButton *editButton; @property (weak) IBOutlet NSButton *cancelEditButton; -- (IBAction)showImagePopup:(id)sender; +- (IBAction)pickIcon:(id)sender; - (IBAction)pickExpiryDate:(id)sender; - (IBAction)toggleEdit:(id)sender; diff --git a/MacPass/MPInspectorViewController.m b/MacPass/MPInspectorViewController.m index b2d45ed0..1a008763 100644 --- a/MacPass/MPInspectorViewController.m +++ b/MacPass/MPInspectorViewController.m @@ -28,6 +28,7 @@ #import "HNHGradientView.h" #import "MPPopupImageView.h" + typedef NS_ENUM(NSUInteger, MPContentTab) { MPEntryTab, MPGroupTab, @@ -45,6 +46,7 @@ typedef NS_ENUM(NSUInteger, MPContentTab) { @property (nonatomic, strong) NSDate *modificationDate; @property (nonatomic, strong) NSDate *creationDate; +@property (copy) NSString *expiryDateText; @property (nonatomic, assign) NSUInteger activeTab; @property (weak) IBOutlet NSTabView *tabView; @@ -78,13 +80,6 @@ typedef NS_ENUM(NSUInteger, MPContentTab) { return [self view]; } -#pragma mark Properties -- (void)setActiveTab:(NSUInteger)activeTab { - if(_activeTab != activeTab) { - _activeTab = activeTab; - } -} - - (void)awakeFromNib { [self.bottomBar setBorderType:HNHBorderTop|HNHBorderHighlight]; @@ -95,28 +90,26 @@ typedef NS_ENUM(NSUInteger, MPContentTab) { NSView *entryView = [_entryViewController view]; NSView *groupView = [_groupViewController view]; - NSView *entryTabView = [[self.tabView tabViewItemAtIndex:MPEntryTab] view]; + + NSTabViewItem *entryTabItem = [self.tabView tabViewItemAtIndex:MPEntryTab]; + NSView *entryTabView = [entryTabItem view]; [entryTabView addSubview:entryView]; NSDictionary *views = NSDictionaryOfVariableBindings(entryView, groupView); [entryTabView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[entryView]|" options:0 metrics:nil views:views]]; [entryTabView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[entryView]|" options:0 metrics:nil views:views]]; + [entryTabItem setInitialFirstResponder:entryTabView]; - NSView *groupTabView = [[self.tabView tabViewItemAtIndex:MPGroupTab] view]; + NSTabViewItem *groupTabItem = [self.tabView tabViewItemAtIndex:MPGroupTab]; + NSView *groupTabView = [groupTabItem view]; [groupTabView addSubview:groupView]; [groupTabView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[groupView]|" options:0 metrics:nil views:views]]; [groupTabView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[groupView]|" options:0 metrics:nil views:views]]; - - [_groupViewController updateResponderChain]; - [_entryViewController updateResponderChain]; + [groupTabItem setInitialFirstResponder:groupView]; [[self view] layout]; [self _updateBindings:nil]; } -- (void)didLoadView { - -} - - (void)regsiterNotificationsForDocument:(MPDocument *)document { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_didChangeCurrentItem:) @@ -124,7 +117,20 @@ typedef NS_ENUM(NSUInteger, MPContentTab) { object:document]; [_entryViewController setupBindings:document]; [_groupViewController setupBindings:document]; - +} + +- (void)updateResponderChain { + [super updateResponderChain]; + [_groupViewController updateResponderChain]; + [_entryViewController updateResponderChain]; +} + +#pragma mark - +#pragma mark Properties +- (void)setActiveTab:(NSUInteger)activeTab { + if(_activeTab != activeTab) { + _activeTab = activeTab; + } } - (void)setModificationDate:(NSDate *)modificationDate { @@ -190,19 +196,32 @@ typedef NS_ENUM(NSUInteger, MPContentTab) { #pragma mark - #pragma mark Popup -- (IBAction)showImagePopup:(id)sender { - - NSAssert(_popover == nil, @"Popover hast to be niled out"); - _popover = [[NSPopover alloc] init]; - _popover.delegate = self; - _popover.behavior = NSPopoverBehaviorTransient; +- (IBAction)pickIcon:(id)sender { + if(self.popover) { + return; // There is still a popover so do nothing + } + self.popover = [[NSPopover alloc] init]; + self.popover.delegate = self; + self.popover.behavior = NSPopoverBehaviorTransient; if(!self.iconSelectionViewController) { self.iconSelectionViewController = [[MPIconSelectViewController alloc] init]; } [self.iconSelectionViewController reset]; self.iconSelectionViewController.popover = _popover; - _popover.contentViewController = self.iconSelectionViewController; - [_popover showRelativeToRect:NSZeroRect ofView:self.itemImageView preferredEdge:NSMinYEdge]; + self.popover.contentViewController = self.iconSelectionViewController; + [self.popover showRelativeToRect:NSZeroRect ofView:sender preferredEdge:NSMinYEdge]; +} + +- (IBAction)pickExpiryDate:(id)sender { + if(self.popover) { + return; // Popover still active, abort + } + NSAssert([sender isKindOfClass:[NSView class]], @""); + self.popover = [[NSPopover alloc] init]; + self.popover.delegate = self; + self.popover.behavior = NSPopoverBehaviorTransient; + self.popover.contentViewController = [[MPDatePickingViewController alloc] init]; + [self.popover showRelativeToRect:NSZeroRect ofView:sender preferredEdge:NSMinYEdge]; } - (void)popoverDidClose:(NSNotification *)notification { @@ -220,16 +239,6 @@ typedef NS_ENUM(NSUInteger, MPContentTab) { self.popover = nil; } -- (IBAction)pickExpiryDate:(id)sender { - NSAssert(self.popover == nil, @"Popover hast to be niled out"); - NSAssert([sender isKindOfClass:[NSView class]], @""); - self.popover = [[NSPopover alloc] init]; - self.popover.delegate = self; - self.popover.behavior = NSPopoverBehaviorTransient; - self.popover.contentViewController = [[MPDatePickingViewController alloc] init]; - [self.popover showRelativeToRect:NSZeroRect ofView:sender preferredEdge:NSMinYEdge]; -} - - (void)_setIcon:(NSInteger)iconId { MPDocument *document = [[self windowController] document]; BOOL useDefault = (iconId == -1); @@ -279,7 +288,7 @@ typedef NS_ENUM(NSUInteger, MPContentTab) { } #pragma mark - -#pragma mark Notificiations +#pragma mark MPDocument Notifications - (void)_didChangeCurrentItem:(NSNotification *)notification { MPDocument *document = [notification object]; diff --git a/MacPass/MPOutlineView.m b/MacPass/MPOutlineView.m index 56473753..812c231d 100644 --- a/MacPass/MPOutlineView.m +++ b/MacPass/MPOutlineView.m @@ -32,4 +32,8 @@ return YES; } +- (BOOL)resignFirstResponder { + return [super resignFirstResponder]; +} + @end diff --git a/MacPass/MPOutlineViewController.m b/MacPass/MPOutlineViewController.m index 16586280..fb39a40c 100644 --- a/MacPass/MPOutlineViewController.m +++ b/MacPass/MPOutlineViewController.m @@ -14,7 +14,6 @@ #import "MPConstants.h" #import "MPActionHelper.h" #import "MPIconHelper.h" -#import "MPUppercaseStringValueTransformer.h" #import "MPNotifications.h" #import "MPOutlineContextMenuDelegate.h" @@ -188,7 +187,6 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell"; - (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item { NSTableCellView *view; if( [self _itemIsRootNode:item] ) { - //NSDictionary *options = @{ NSValueTransformerBindingOption : [NSValueTransformer valueTransformerForName:MPUppsercaseStringValueTransformerName] }; view = [outlineView makeViewWithIdentifier:_MPOutlinveViewHeaderViewIdentifier owner:self]; [view.textField bind:NSValueBinding toObject:self withKeyPath:@"databaseNameWrapper" options:nil]; } diff --git a/MacPass/MPStringLengthValueTransformer.h b/MacPass/MPStringLengthValueTransformer.h index 9571c492..e8da06e5 100644 --- a/MacPass/MPStringLengthValueTransformer.h +++ b/MacPass/MPStringLengthValueTransformer.h @@ -1,5 +1,5 @@ -// // MPStringLengthValueTransformer.h +// // MacPass // // Created by Michael Starke on 17.06.13. diff --git a/MacPass/MPStripLineBreaksTransformer.h b/MacPass/MPStripLineBreaksTransformer.h deleted file mode 100644 index 75c983cd..00000000 --- a/MacPass/MPStripLineBreaksTransformer.h +++ /dev/null @@ -1,17 +0,0 @@ -// -// MPStripLineBreaksTransformer.h -// MacPass -// -// Created by Michael Starke on 31.07.13. -// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved. -// - -#import - -FOUNDATION_EXPORT NSString *const MPStripLineBreaksTransformerName; - -@interface MPStripLineBreaksTransformer : NSValueTransformer - -+ (void)registerTransformer; - -@end diff --git a/MacPass/MPStripLineBreaksTransformer.m b/MacPass/MPStripLineBreaksTransformer.m deleted file mode 100644 index 26c96305..00000000 --- a/MacPass/MPStripLineBreaksTransformer.m +++ /dev/null @@ -1,37 +0,0 @@ -// -// MPStripLineBreaksTransformer.m -// MacPass -// -// Created by Michael Starke on 31.07.13. -// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved. -// - -#import "MPStripLineBreaksTransformer.h" - -NSString *const MPStripLineBreaksTransformerName = @"com.hicknhack.macpass.MPStripLineBreaksTransformerName"; - -@implementation MPStripLineBreaksTransformer - -+ (Class)transformedValueClass { - return [NSString class]; -} - -+ (BOOL)allowsReverseTransformation { - return NO; -} - -+ (void)registerTransformer { - MPStripLineBreaksTransformer *transformer = [[MPStripLineBreaksTransformer alloc] init]; - [NSValueTransformer setValueTransformer:transformer - forName:MPStripLineBreaksTransformerName]; -} - -- (id)transformedValue:(id)value { - if(![value isKindOfClass:[NSString class]]) { - return nil; - } - NSArray *elements = [value componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]]; - return [elements componentsJoinedByString:@" "]; -} - -@end diff --git a/MacPass/MPUppercaseStringValueTransformer.h b/MacPass/MPUppercaseStringValueTransformer.h deleted file mode 100644 index efba0053..00000000 --- a/MacPass/MPUppercaseStringValueTransformer.h +++ /dev/null @@ -1,17 +0,0 @@ -// -// MPUppercaseStringValueTransformer.h -// MacPass -// -// Created by Michael Starke on 03.06.13. -// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved. -// - -APPKIT_EXTERN NSString *const MPUppsercaseStringValueTransformerName; - -#import - -@interface MPUppercaseStringValueTransformer : NSValueTransformer - -+ (void)registerTransformer; - -@end diff --git a/MacPass/MPUppercaseStringValueTransformer.m b/MacPass/MPUppercaseStringValueTransformer.m deleted file mode 100644 index 55c84ca0..00000000 --- a/MacPass/MPUppercaseStringValueTransformer.m +++ /dev/null @@ -1,36 +0,0 @@ -// -// MPUppercaseStringValueTransformer.m -// MacPass -// -// Created by Michael Starke on 03.06.13. -// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved. -// - -#import "MPUppercaseStringValueTransformer.h" - -NSString *const MPUppsercaseStringValueTransformerName = @"com.hicknhack.macpass.StringToUppercaseStringTransformer"; - -@implementation MPUppercaseStringValueTransformer - -+ (Class)transformedValueClass { - return [NSString class]; -} - -+ (BOOL)allowsReverseTransformation { - return NO; -} - -+ (void)registerTransformer { - MPUppercaseStringValueTransformer *transformer = [[MPUppercaseStringValueTransformer alloc] init]; - [NSValueTransformer setValueTransformer:transformer - forName:MPUppsercaseStringValueTransformerName]; -} - -- (id)transformedValue:(id)value { - if([value respondsToSelector:@selector(uppercaseString)]) { - return [value uppercaseString]; - } - return value; -} - -@end diff --git a/MacPass/MPValueTransformerHelper.h b/MacPass/MPValueTransformerHelper.h new file mode 100644 index 00000000..cc73b679 --- /dev/null +++ b/MacPass/MPValueTransformerHelper.h @@ -0,0 +1,18 @@ +// +// MPValueTransformerHelper.h +// MacPass +// +// Created by Michael Starke on 17/03/14. +// Copyright (c) 2014 HicknHack Software GmbH. All rights reserved. +// + +#import + +FOUNDATION_EXPORT NSString *const MPStripLineBreaksTransformerName; +FOUNDATION_EXPORT NSString *const MPExpiryDateValueTransformer; + +@interface MPValueTransformerHelper : NSObject + ++ (void)registerValueTransformer; + +@end diff --git a/MacPass/MPValueTransformerHelper.m b/MacPass/MPValueTransformerHelper.m new file mode 100644 index 00000000..61697f8a --- /dev/null +++ b/MacPass/MPValueTransformerHelper.m @@ -0,0 +1,46 @@ +// +// MPValueTransformerHelper.m +// MacPass +// +// Created by Michael Starke on 17/03/14. +// Copyright (c) 2014 HicknHack Software GmbH. All rights reserved. +// + +#import "MPValueTransformerHelper.h" +#import "NSValueTransformer+TransformerKit.h" + +NSString *const MPStripLineBreaksTransformerName = @"com.hicknhack.macpass.MPStripLineBreaksTransformerName"; +NSString *const MPExpiryDateValueTransformer = @"com.hicknhack.macpass.kMPExpiryDateValueTransformer"; + +@implementation MPValueTransformerHelper + ++ (void)registerValueTransformer { + [NSValueTransformer registerValueTransformerWithName:MPStripLineBreaksTransformerName + transformedValueClass:[NSString class] + returningTransformedValueWithBlock:^id(id value) { + if(![value isKindOfClass:[NSString class]]) { + return @""; + } + NSArray *elements = [value componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]]; + return [elements componentsJoinedByString:@" "]; + }]; + + + [NSValueTransformer registerValueTransformerWithName:MPExpiryDateValueTransformer + transformedValueClass:[NSString class] + returningTransformedValueWithBlock:^id(id value) { + if(![value isKindOfClass:[NSDate class]]) { + return @""; // Wrong input + } + static NSDateFormatter *formatter; + if(!formatter) { + formatter = [[NSDateFormatter alloc] init]; + [formatter setDateStyle:NSDateFormatterFullStyle]; + [formatter setTimeStyle:NSDateFormatterNoStyle]; + } + NSString *template = NSLocalizedString(@"EXPIRES_AT_DATE_%@", ""); + return [[NSString alloc] initWithFormat:template, [formatter stringFromDate:value]]; + }]; +} + +@end diff --git a/MacPass/en.lproj/Localizable.strings b/MacPass/en.lproj/Localizable.strings index b485c972..1fb25131 100644 Binary files a/MacPass/en.lproj/Localizable.strings and b/MacPass/en.lproj/Localizable.strings differ diff --git a/README.md b/README.md index 1d78282a..da90fa05 100644 --- a/README.md +++ b/README.md @@ -119,10 +119,12 @@ This Project is based upon the following work: [KSPasswordField](https://github.com/karelia/SecurityInterface) Copyright 2012 Mike Abdullah, Karelia Software. All rights reserved. -[DDHotKey](https://github.com/davedelong/DDHotKey) Copyright Dave DeLong http://www.davedelong.com. All rights reserved. +[DDHotKey](https://github.com/davedelong/DDHotKey) Copyright [Dave DeLong](http://www.davedelong.com). All rights reserved. [Sparkle](http://sparkle.andymatuschak.org) Copyright 2006 Andy Matuschak +[TransformerKit](https://github.com/mattt/TransformerKit) Copyright 2012 [Mattt Thompson](http://mattt.me/). All rights reseverd + See submodules for additional Licenses ##Feedback diff --git a/TransformerKit b/TransformerKit new file mode 160000 index 00000000..a1f3d663 --- /dev/null +++ b/TransformerKit @@ -0,0 +1 @@ +Subproject commit a1f3d663240d879f5341e1a97cee8413477a4e44