diff --git a/MacPass.xcodeproj/project.pbxproj b/MacPass.xcodeproj/project.pbxproj index 4a2aef4e..f1dfa1ea 100644 --- a/MacPass.xcodeproj/project.pbxproj +++ b/MacPass.xcodeproj/project.pbxproj @@ -7,7 +7,6 @@ objects = { /* Begin PBXBuildFile section */ - 4C16854416D704980027ECBC /* MPPathBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C16854316D704980027ECBC /* MPPathBar.m */; }; 4C25D58516CF0F8800F6806C /* WelcomeView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C25D58416CF0F8800F6806C /* WelcomeView.xib */; }; 4C25D58716CF0FAA00F6806C /* EntryView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C25D58616CF0FAA00F6806C /* EntryView.xib */; }; 4C2C4C2C16D3BE3700D49295 /* KdbGroup+MPAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C2C4C2B16D3BE3700D49295 /* KdbGroup+MPAdditions.m */; }; @@ -25,7 +24,6 @@ 4C586F9E16D07ABD00E7DB57 /* 00_PasswordTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4C586F9D16D07ABD00E7DB57 /* 00_PasswordTemplate.pdf */; }; 4C586FA016D07D7200E7DB57 /* 01_PackageNetworkTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4C586F9F16D07D7200E7DB57 /* 01_PackageNetworkTemplate.pdf */; }; 4C586FA216D07F6A00E7DB57 /* 02_MessageBoxWarningTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4C586FA116D07F6A00E7DB57 /* 02_MessageBoxWarningTemplate.pdf */; }; - 4C587F2E16E0257B0003718D /* MPButtonBarButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C587F2D16E0257B0003718D /* MPButtonBarButton.m */; }; 4C61EA0316D2FD0800AC519E /* MPOutlineViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C61EA0216D2FD0800AC519E /* MPOutlineViewController.m */; }; 4C61EA0516D2FFE200AC519E /* OutlineView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C61EA0416D2FFE200AC519E /* OutlineView.xib */; }; 4C65C79C16DD283900E32CFF /* MPToolbarButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C65C79B16DD283900E32CFF /* MPToolbarButton.m */; }; @@ -67,7 +65,6 @@ 4C669BA216760ED100DD0774 /* UUID.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C669B7B16760ED100DD0774 /* UUID.m */; }; 4C69A73A16D589DF00EC1B1A /* MPGradientView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C69A73916D589DF00EC1B1A /* MPGradientView.m */; }; 4C6B0E8C16C9B99B00A9ED23 /* PasswordInputView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C6B0E8B16C9B99B00A9ED23 /* PasswordInputView.xib */; }; - 4C6DA0F916D81B8A0011224B /* MPPathBarItemView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C6DA0F816D81B8A0011224B /* MPPathBarItemView.m */; }; 4C75CE3C16CB128700F61A4D /* MPDatabaseController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C75CE3B16CB128700F61A4D /* MPDatabaseController.m */; }; 4C77547516E55FE800970E02 /* MPInspectorTabViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C77547416E55FE800970E02 /* MPInspectorTabViewController.m */; }; 4C77547716E55FFC00970E02 /* InspectorTabView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C77547616E55FFC00970E02 /* InspectorTabView.xib */; }; @@ -77,6 +74,9 @@ 4C77E37A15B84A240093A587 /* MPAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C77E37915B84A240093A587 /* MPAppDelegate.m */; }; 4C77E37D15B84A240093A587 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C77E37B15B84A240093A587 /* MainMenu.xib */; }; 4C83814215BF4677001AE468 /* MPMainWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C83814115BF4677001AE468 /* MPMainWindowController.m */; }; + 4C888C9016EB6C91003D34A1 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 4C888C8E16EB6C91003D34A1 /* Localizable.strings */; }; + 4C888C9316EB6F5E003D34A1 /* MPToolbarItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C888C9216EB6F5E003D34A1 /* MPToolbarItem.m */; }; + 4C888C9716EB754B003D34A1 /* MPActionHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C888C9616EB754B003D34A1 /* MPActionHelper.m */; }; 4C8FECC816D57E3200BF26CF /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C8FECC716D57E3200BF26CF /* QuartzCore.framework */; }; 4C920E2A16DCDFA00083839B /* MPLoggerProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C920E2916DCDFA00083839B /* MPLoggerProxy.m */; }; 4CA0B2ED15BCADAC00654E32 /* SettingsWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4CA0B2EC15BCADAC00654E32 /* SettingsWindow.xib */; }; @@ -101,17 +101,13 @@ 4CD78ABF16D155FF00768A1D /* 10_ContactTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4CD78ABA16D155FF00768A1D /* 10_ContactTemplate.pdf */; }; 4CD78AC016D155FF00768A1D /* 11_CameraTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4CD78ABB16D155FF00768A1D /* 11_CameraTemplate.pdf */; }; 4CD884B715BD47080042BBF8 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4CD884B615BD47080042BBF8 /* MainWindow.xib */; }; - 4CDB556416E29A7C00635918 /* MPPathControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CDB556316E29A7C00635918 /* MPPathControl.m */; }; 4CDF01A316D1B76700D0AC08 /* MPEntryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CDF01A216D1B76700D0AC08 /* MPEntryViewController.m */; }; - 4CE06D7D16DEF3FE00840E3A /* MPButtonBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CE06D7C16DEF3FE00840E3A /* MPButtonBar.m */; }; 4CE8246F16E2E93400573141 /* MPOverlayWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CE8246E16E2E93400573141 /* MPOverlayWindowController.m */; }; 4CE8247516E2F2B900573141 /* MPOverlayView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CE8247416E2F2B900573141 /* MPOverlayView.m */; }; 4CFC53BF16E94729007396BE /* MPShadowBox.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CFC53BE16E94729007396BE /* MPShadowBox.m */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ - 4C16854216D704980027ECBC /* MPPathBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPathBar.h; sourceTree = ""; }; - 4C16854316D704980027ECBC /* MPPathBar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPPathBar.m; sourceTree = ""; }; 4C25D58416CF0F8800F6806C /* WelcomeView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = WelcomeView.xib; sourceTree = ""; }; 4C25D58616CF0FAA00F6806C /* EntryView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = EntryView.xib; sourceTree = ""; }; 4C2C4C2A16D3BE3700D49295 /* KdbGroup+MPAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "KdbGroup+MPAdditions.h"; sourceTree = ""; }; @@ -135,8 +131,6 @@ 4C586F9D16D07ABD00E7DB57 /* 00_PasswordTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 00_PasswordTemplate.pdf; sourceTree = ""; }; 4C586F9F16D07D7200E7DB57 /* 01_PackageNetworkTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 01_PackageNetworkTemplate.pdf; sourceTree = ""; }; 4C586FA116D07F6A00E7DB57 /* 02_MessageBoxWarningTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 02_MessageBoxWarningTemplate.pdf; sourceTree = ""; }; - 4C587F2C16E0257B0003718D /* MPButtonBarButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPButtonBarButton.h; sourceTree = ""; }; - 4C587F2D16E0257B0003718D /* MPButtonBarButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPButtonBarButton.m; sourceTree = ""; }; 4C61EA0116D2FD0800AC519E /* MPOutlineViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPOutlineViewController.h; sourceTree = ""; }; 4C61EA0216D2FD0800AC519E /* MPOutlineViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPOutlineViewController.m; sourceTree = ""; }; 4C61EA0416D2FFE200AC519E /* OutlineView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = OutlineView.xib; sourceTree = ""; }; @@ -220,8 +214,6 @@ 4C69A73816D589DF00EC1B1A /* MPGradientView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPGradientView.h; sourceTree = ""; }; 4C69A73916D589DF00EC1B1A /* MPGradientView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPGradientView.m; sourceTree = ""; }; 4C6B0E8B16C9B99B00A9ED23 /* PasswordInputView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PasswordInputView.xib; sourceTree = ""; }; - 4C6DA0F716D81B8A0011224B /* MPPathBarItemView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPathBarItemView.h; sourceTree = ""; }; - 4C6DA0F816D81B8A0011224B /* MPPathBarItemView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPPathBarItemView.m; sourceTree = ""; }; 4C75CE3A16CB128700F61A4D /* MPDatabaseController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPDatabaseController.h; sourceTree = ""; }; 4C75CE3B16CB128700F61A4D /* MPDatabaseController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPDatabaseController.m; sourceTree = ""; }; 4C77547316E55FE800970E02 /* MPInspectorTabViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPInspectorTabViewController.h; sourceTree = ""; }; @@ -241,6 +233,11 @@ 4C77E37C15B84A240093A587 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainMenu.xib; sourceTree = ""; }; 4C83814015BF4677001AE468 /* MPMainWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPMainWindowController.h; sourceTree = ""; }; 4C83814115BF4677001AE468 /* MPMainWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPMainWindowController.m; sourceTree = ""; }; + 4C888C8F16EB6C91003D34A1 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; + 4C888C9116EB6F5E003D34A1 /* MPToolbarItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPToolbarItem.h; sourceTree = ""; }; + 4C888C9216EB6F5E003D34A1 /* MPToolbarItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPToolbarItem.m; sourceTree = ""; }; + 4C888C9516EB754B003D34A1 /* MPActionHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPActionHelper.h; sourceTree = ""; }; + 4C888C9616EB754B003D34A1 /* MPActionHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPActionHelper.m; sourceTree = ""; }; 4C8FECC716D57E3200BF26CF /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 4C920E2816DCDFA00083839B /* MPLoggerProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPLoggerProxy.h; sourceTree = ""; }; 4C920E2916DCDFA00083839B /* MPLoggerProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPLoggerProxy.m; sourceTree = ""; }; @@ -280,12 +277,8 @@ 4CD78ABA16D155FF00768A1D /* 10_ContactTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 10_ContactTemplate.pdf; sourceTree = ""; }; 4CD78ABB16D155FF00768A1D /* 11_CameraTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 11_CameraTemplate.pdf; sourceTree = ""; }; 4CD884B615BD47080042BBF8 /* MainWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = ""; }; - 4CDB556216E29A7C00635918 /* MPPathControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPathControl.h; sourceTree = ""; }; - 4CDB556316E29A7C00635918 /* MPPathControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPPathControl.m; sourceTree = ""; }; 4CDF01A116D1B76700D0AC08 /* MPEntryViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPEntryViewController.h; sourceTree = ""; }; 4CDF01A216D1B76700D0AC08 /* MPEntryViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPEntryViewController.m; sourceTree = ""; }; - 4CE06D7B16DEF3FE00840E3A /* MPButtonBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPButtonBar.h; sourceTree = ""; }; - 4CE06D7C16DEF3FE00840E3A /* MPButtonBar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPButtonBar.m; sourceTree = ""; }; 4CE8246D16E2E93400573141 /* MPOverlayWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPOverlayWindowController.h; sourceTree = ""; }; 4CE8246E16E2E93400573141 /* MPOverlayWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPOverlayWindowController.m; sourceTree = ""; }; 4CE8247316E2F2B900573141 /* MPOverlayView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPOverlayView.h; sourceTree = ""; }; @@ -559,6 +552,7 @@ 4C77E36D15B84A240093A587 /* Supporting Files */ = { isa = PBXGroup; children = ( + 4C888C8E16EB6C91003D34A1 /* Localizable.strings */, 4CB9339716D3A0DD00A13B5D /* Credits.rtf */, 4C77E36E15B84A240093A587 /* MacPass-Info.plist */, 4C77E36F15B84A240093A587 /* InfoPlist.strings */, @@ -598,6 +592,8 @@ 4CA0B30F15BCB85D00654E32 /* General */ = { isa = PBXGroup; children = ( + 4C888C9516EB754B003D34A1 /* MPActionHelper.h */, + 4C888C9616EB754B003D34A1 /* MPActionHelper.m */, ); name = General; sourceTree = ""; @@ -656,18 +652,10 @@ 4CDB556616E29A8A00635918 /* Controls */ = { isa = PBXGroup; children = ( - 4C16854216D704980027ECBC /* MPPathBar.h */, - 4C16854316D704980027ECBC /* MPPathBar.m */, - 4C6DA0F716D81B8A0011224B /* MPPathBarItemView.h */, - 4C6DA0F816D81B8A0011224B /* MPPathBarItemView.m */, 4C65C79A16DD283900E32CFF /* MPToolbarButton.h */, 4C65C79B16DD283900E32CFF /* MPToolbarButton.m */, - 4CE06D7B16DEF3FE00840E3A /* MPButtonBar.h */, - 4CE06D7C16DEF3FE00840E3A /* MPButtonBar.m */, - 4C587F2C16E0257B0003718D /* MPButtonBarButton.h */, - 4C587F2D16E0257B0003718D /* MPButtonBarButton.m */, - 4CDB556216E29A7C00635918 /* MPPathControl.h */, - 4CDB556316E29A7C00635918 /* MPPathControl.m */, + 4C888C9116EB6F5E003D34A1 /* MPToolbarItem.h */, + 4C888C9216EB6F5E003D34A1 /* MPToolbarItem.m */, ); name = Controls; sourceTree = ""; @@ -785,6 +773,7 @@ 4C4E1DC716DC6536007B9B47 /* PathBar.xib in Resources */, 4C431BCF16E2BAB000700A81 /* OverlayWindow.xib in Resources */, 4C77547716E55FFC00970E02 /* InspectorTabView.xib in Resources */, + 4C888C9016EB6C91003D34A1 /* Localizable.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -870,18 +859,15 @@ 4C2C4C2C16D3BE3700D49295 /* KdbGroup+MPAdditions.m in Sources */, 4CC1AEBE16D4467C006D2AAB /* KdbTree+MPAdditions.m in Sources */, 4C69A73A16D589DF00EC1B1A /* MPGradientView.m in Sources */, - 4C16854416D704980027ECBC /* MPPathBar.m in Sources */, - 4C6DA0F916D81B8A0011224B /* MPPathBarItemView.m in Sources */, 4C920E2A16DCDFA00083839B /* MPLoggerProxy.m in Sources */, 4C65C79C16DD283900E32CFF /* MPToolbarButton.m in Sources */, - 4CE06D7D16DEF3FE00840E3A /* MPButtonBar.m in Sources */, - 4C587F2E16E0257B0003718D /* MPButtonBarButton.m in Sources */, - 4CDB556416E29A7C00635918 /* MPPathControl.m in Sources */, 4C431BCD16E2A82800700A81 /* MPPasteBoardController.m in Sources */, 4CE8246F16E2E93400573141 /* MPOverlayWindowController.m in Sources */, 4CE8247516E2F2B900573141 /* MPOverlayView.m in Sources */, 4C77547516E55FE800970E02 /* MPInspectorTabViewController.m in Sources */, 4CFC53BF16E94729007396BE /* MPShadowBox.m in Sources */, + 4C888C9316EB6F5E003D34A1 /* MPToolbarItem.m in Sources */, + 4C888C9716EB754B003D34A1 /* MPActionHelper.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -904,6 +890,14 @@ name = MainMenu.xib; sourceTree = ""; }; + 4C888C8E16EB6C91003D34A1 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 4C888C8F16EB6C91003D34A1 /* en */, + ); + name = Localizable.strings; + sourceTree = ""; + }; 4CB9339716D3A0DD00A13B5D /* Credits.rtf */ = { isa = PBXVariantGroup; children = ( diff --git a/MacPass/MPActionHelper.h b/MacPass/MPActionHelper.h new file mode 100644 index 00000000..14ce02ff --- /dev/null +++ b/MacPass/MPActionHelper.h @@ -0,0 +1,28 @@ +// +// MPActionHelper.h +// MacPass +// +// Created by Michael Starke on 09.03.13. +// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved. +// + +#import + +typedef enum { + MPActionAddEntry, // Add an new entry + MPActionAddGroup, // Add a new group + MPActionEdit, // Edit entry or group + MPActionDelete, // Delete entry or group + MPActionCopyUsername, // copy username to pasteboard + MPActionCopyPassword, // copy password to pasteboard + MPActionCopyURL, // copy url to pasteboard + MPActionOpenURL, // open url in default browser + MPActionToggleInspector, +} +MPActionType; + +@interface MPActionHelper : NSObject + ++ (SEL)actionOfType:(MPActionType)type; + +@end diff --git a/MacPass/MPActionHelper.m b/MacPass/MPActionHelper.m new file mode 100644 index 00000000..40d0ced5 --- /dev/null +++ b/MacPass/MPActionHelper.m @@ -0,0 +1,32 @@ +// +// MPActionHelper.m +// MacPass +// +// Created by Michael Starke on 09.03.13. +// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved. +// + +#import "MPActionHelper.h" + +@implementation MPActionHelper + ++ (SEL)actionOfType:(MPActionType)type { + static NSDictionary *actionDict; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + actionDict = [@{ + @(MPActionAddEntry) : @"createEntry:", + @(MPActionAddGroup) : @"createGroup:", + @(MPActionCopyPassword) : @"copyPassword:", + @(MPActionCopyURL) : @"copyURL:", + @(MPActionCopyUsername) : @"copyUsername:", + @(MPActionDelete) : @"deleteEntry:", + @(MPActionEdit) : @"editEntry:", + @(MPActionOpenURL) : @"openURL:", + @(MPActionToggleInspector) : @"toggleInspector:" + } retain]; + }); + return NSSelectorFromString(actionDict[@(type)]); +} + +@end diff --git a/MacPass/MPAppDelegate.m b/MacPass/MPAppDelegate.m index a1e73189..ef09ccc9 100644 --- a/MacPass/MPAppDelegate.m +++ b/MacPass/MPAppDelegate.m @@ -11,6 +11,7 @@ #import "MPMainWindowController.h" #import "MPSettingsController.h" #import "MPDatabaseController.h" +#import "MPActionHelper.h" @interface MPAppDelegate () @@ -70,8 +71,14 @@ NSMutableArray *items = [NSMutableArray arrayWithCapacity:7]; if(insertCreate) { - NSMenuItem *newGroup = [[NSMenuItem alloc] initWithTitle:@"New Group" action:@selector(createGroup:) keyEquivalent:@"G"]; - NSMenuItem *newEntry = [[NSMenuItem alloc] initWithTitle:@"New Entry" action:@selector(createEntry:) keyEquivalent:@"E"]; + + NSMenuItem *newGroup = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"ADD_GROUP", @"") + action:[MPActionHelper actionOfType:MPActionAddGroup] + keyEquivalent:@"G"]; + NSMenuItem *newEntry = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"ADD_ENTRY", @"") + action:[MPActionHelper actionOfType:MPActionAddEntry] + keyEquivalent:@"E"]; + [items addObjectsFromArray:@[ newGroup, newEntry ]]; [newEntry release]; [newGroup release]; @@ -80,7 +87,9 @@ if([items count] > 0) { [items addObject:[NSMenuItem separatorItem]]; } - NSMenuItem *delete = [[NSMenuItem alloc] initWithTitle:@"Delete" action:@selector(deleteEntry:) keyEquivalent:@""]; + NSMenuItem *delete = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"DELETE", @"") + action:[MPActionHelper actionOfType:MPActionDelete] + keyEquivalent:@""]; [items addObject:delete]; [delete release]; } @@ -88,13 +97,34 @@ if([items count] > 0) { [items addObject:[NSMenuItem separatorItem]]; } - NSMenuItem *copyUsername = [[NSMenuItem alloc] initWithTitle:@"Copy Username" action:@selector(copyUsername:) keyEquivalent:@"C"]; - NSMenuItem *copyPassword = [[NSMenuItem alloc] initWithTitle:@"Copy Password" action:@selector(copyPassword:) keyEquivalent:@"c"]; - NSMenuItem *openURL = [[NSMenuItem alloc] initWithTitle:@"Open URL" action:@selector(openURL:) keyEquivalent:@"U"]; - [items addObjectsFromArray:@[ copyUsername, copyPassword, openURL]]; + NSMenuItem *copyUsername = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"COPY_USERNAME", @"") + action:[MPActionHelper actionOfType:MPActionCopyUsername] + keyEquivalent:@"C"]; + NSMenuItem *copyPassword = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"COPY_PASSWORD", @"") + action:[MPActionHelper actionOfType:MPActionCopyPassword] + keyEquivalent:@"c"]; + NSMenu *urlMenu = [[NSMenu alloc] init]; + NSMenuItem *urlItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"URL", @"") + action:0 + keyEquivalent:@""]; + [urlItem setSubmenu:urlMenu]; + [urlMenu release]; + + NSMenuItem *copyURL = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"COPY_URL", @"") + action:[MPActionHelper actionOfType:MPActionCopyURL] + keyEquivalent:@"u"]; + NSMenuItem *openURL = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"OPEN_URL", @"") + action:[MPActionHelper actionOfType:MPActionOpenURL] + keyEquivalent:@"U"]; + [urlMenu addItem:copyURL]; + [urlMenu addItem:openURL]; + [openURL release]; + [copyURL release]; + + [items addObjectsFromArray:@[ copyUsername, copyPassword, urlItem]]; + [urlItem release]; [copyPassword release]; [copyUsername release]; - [openURL release]; } return items; } diff --git a/MacPass/MPButtonBar.h b/MacPass/MPButtonBar.h deleted file mode 100644 index 1f12a45a..00000000 --- a/MacPass/MPButtonBar.h +++ /dev/null @@ -1,52 +0,0 @@ -// -// MPButtonBar.h -// MacPass -// -// Created by michael starke on 28.02.13. -// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved. -// - -#import "MPGradientView.h" - -/* - Notifications and userInfo dictionary keys - */ -APPKIT_EXTERN NSString *const MPButtonBarSelectionChangedNotification; -/* - Key in for the Index of the new selection. NSNumber with NSUInteger - */ -APPKIT_EXTERN NSString *const MPButtonBarSelectionIndexKey; - -/* - Exception thrown if an illegal delegate is used. - */ -APPKIT_EXTERN NSString *const MPButtonBarInvalidDelegateException; - -@class MPButtonBar; - -@protocol MPButtonBarDelegate - -@required -- (NSUInteger)buttonsInButtonBar:(MPButtonBar *)buttonBar; -@optional -- (NSImage *)buttonBar:(MPButtonBar *)buttonBar imageAtIndex:(NSUInteger)index; -- (NSString *)buttonBar:(MPButtonBar *)buttonBar labelAtIndex:(NSUInteger)index; - -/* - A delegate that implements this function automatically gets registred to recive MPButtonBarSelectionDidChangeNotification - The object in the notification is the buttonbar, - The userDictionary contrains the following keys: - MPButtonBarSelectionIndexKey; - */ -- (void)didChangeButtonSelection:(NSNotification *)notification; - -@end - -@interface MPButtonBar : MPGradientView - -@property (nonatomic, assign) id delegate; -@property (nonatomic, readonly) NSUInteger selectedIndex; -@property (nonatomic, readonly) BOOL hasSelection; - - -@end diff --git a/MacPass/MPButtonBar.m b/MacPass/MPButtonBar.m deleted file mode 100644 index bdddd658..00000000 --- a/MacPass/MPButtonBar.m +++ /dev/null @@ -1,131 +0,0 @@ -// -// MPButtonBar.m -// MacPass -// -// Created by michael starke on 28.02.13. -// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved. -// - -#import "MPButtonBar.h" -#import "MPButtonBarButton.h" - -#define MPBUTTONBAR_BUTTON_MARGIN 5.0; - -NSString *const MPButtonBarSelectionChangedNotification = @"MPButtonBarSelectionChangedNotification"; -NSString *const MPButtonBarSelectionIndexKey = @"MPButtonBarSelectionIndexKey"; - -NSString *const MPButtonBarInvalidDelegateException = @"MPButtonBarInvalidDelegateException"; - - -@interface MPButtonBar () - -@property (retain) NSMutableArray *buttons; -@property (nonatomic, assign) NSUInteger selectedIndex; -@property (assign) BOOL delegateSupportsImage; -@property (assign) BOOL delegateSupportsLabel; - -- (void)_updateButtons; -- (void)_didClickButton:(id)sender; - -@end - -@implementation MPButtonBar - -- (id)initWithFrame:(NSRect)frame { - self = [super initWithFrame:frame]; - if (self) { - self.selectedIndex = NSNotFound; - self.buttons = [NSMutableArray arrayWithCapacity:5]; - self.delegateSupportsImage = NO; - self.delegateSupportsLabel = NO; - [self _updateButtons]; - } - return self; -} - -# pragma mark Layout - -- (void)_updateButtons { - NSUInteger currentButtonCount = [self.buttons count]; - NSUInteger newButtonCount = 5;//[self.delegate buttonsInButtonBar:self]; - /* - remove unused buttons - */ - if(currentButtonCount > newButtonCount) { - NSRange removalRange = NSMakeRange(newButtonCount - 1, currentButtonCount - newButtonCount); - NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:removalRange]; - NSArray *obsolteButtons = [self.buttons objectsAtIndexes:indexSet]; - for(NSButton *button in obsolteButtons) { - [button removeFromSuperviewWithoutNeedingDisplay]; - } - [self.buttons removeObjectsInRange:NSMakeRange(newButtonCount - 1, currentButtonCount - newButtonCount)]; - } - CGFloat startPosition = MPBUTTONBAR_BUTTON_MARGIN; - for(NSUInteger buttonIndex = 0; buttonIndex < newButtonCount ; buttonIndex++) { - BOOL needsDisplay = NO; - if(buttonIndex >= currentButtonCount) { - NSButton *newButton= [[MPButtonBarButton alloc] initWithFrame:NSMakeRect(0, 0, 30, 30)]; - [self addSubview:newButton]; - [self.buttons addObject:newButton]; - [newButton release]; - [newButton setTarget:self]; - [newButton setImage:[NSImage imageNamed:NSImageNameActionTemplate]]; - [newButton setAction:@selector(_didClickButton:)]; - needsDisplay = YES; - } - NSButton *currentButton = self.buttons[buttonIndex]; - if (self.delegateSupportsImage) { - [currentButton setImage:[self.delegate buttonBar:self imageAtIndex:buttonIndex]]; - needsDisplay = YES; - } - if(self.delegateSupportsLabel) { - [currentButton setStringValue:[self.delegate buttonBar:self labelAtIndex:buttonIndex]]; - needsDisplay = YES; - } - [currentButton sizeToFit]; - NSRect frame = [currentButton frame]; - frame.size.width += 20; - frame.origin.x = startPosition; - [currentButton setFrame:frame]; - startPosition += frame.size.width + MPBUTTONBAR_BUTTON_MARGIN; - [self setNeedsDisplay:needsDisplay]; - } -} - -#pragma mark Button Events - -- (void)_didClickButton:(id)sender { - NSUInteger index = [[self subviews] indexOfObject:sender]; - if(index == NSNotFound) { - return; // Nothing we need to know about happened; - } - NSDictionary *userInfo = @{ MPButtonBarSelectionIndexKey: @(index) }; - [[NSNotificationCenter defaultCenter] postNotificationName:MPButtonBarSelectionChangedNotification object:self userInfo:userInfo]; -} - -# pragma mark Properties - -- (void)setDelegate:(id)delegate { - if( ![delegate conformsToProtocol:@protocol(MPButtonBarDelegate)]) { - NSException *invalidDelegateException = [NSException exceptionWithName:MPButtonBarInvalidDelegateException reason:@"The Delegate does not conform to the MPButtonBarDelegate protocoll" userInfo:nil]; - @throw invalidDelegateException; - } - if(_delegate != delegate) { - if([_delegate respondsToSelector:@selector(didChangeButtonSelection:)]) { - [[NSNotificationCenter defaultCenter] removeObserver:_delegate]; - } - _delegate = delegate; - self.delegateSupportsLabel = [delegate respondsToSelector:@selector(buttonBar:labelAtIndex:)]; - self.delegateSupportsImage = [delegate respondsToSelector:@selector(buttonBar:imageAtIndex:)]; - if([delegate respondsToSelector:@selector(selectionDidChanged:)]) { - [[NSNotificationCenter defaultCenter] addObserver:self.delegate selector:@selector(didChangeButtonSelection:) name:MPButtonBarSelectionChangedNotification object:self]; - } - [self _updateButtons]; - } -} - -- (BOOL)hasSelection { - return self.selectedIndex != NSNotFound; -} - -@end \ No newline at end of file diff --git a/MacPass/MPButtonBarButton.h b/MacPass/MPButtonBarButton.h deleted file mode 100644 index 2c0bac33..00000000 --- a/MacPass/MPButtonBarButton.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// MPButtonBarButton.h -// MacPass -// -// Created by Michael Starke on 01.03.13. -// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved. -// - -#import - -@interface MPButtonBarButton : NSButton - -@end diff --git a/MacPass/MPButtonBarButton.m b/MacPass/MPButtonBarButton.m deleted file mode 100644 index bd33ef8e..00000000 --- a/MacPass/MPButtonBarButton.m +++ /dev/null @@ -1,42 +0,0 @@ -// -// MPButtonBarButton.m -// MacPass -// -// Created by Michael Starke on 01.03.13. -// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved. -// - -#import "MPButtonBarButton.h" - -@implementation MPButtonBarButton - -- (id)initWithFrame:(NSRect)frame -{ - self = [super initWithFrame:frame]; - if (self) { - [self setButtonType:NSPushOnPushOffButton]; - [self setBordered:NO]; - - [[self cell] setHighlightsBy:NSContentsCellMask]; - [[self cell] setShowsStateBy:NSNoCellMask]; - [[self cell] setBackgroundStyle:NSBackgroundStyleRaised]; - } - return self; -} - -- (void)drawRect:(NSRect)dirtyRect { - if(self.state == NSOnState) { - NSRect drawingRect = [self bounds]; - NSColor *edgeColor = [NSColor colorWithCalibratedWhite:0.0 alpha:0.2]; - NSColor *middelColor = [NSColor colorWithCalibratedWhite:0.0 alpha:0]; - NSGradient *borderGradient = [[NSGradient alloc] initWithColors:@[edgeColor, middelColor]]; - drawingRect.size.width = 5; - [borderGradient drawInRect:drawingRect relativeCenterPosition:NSMakePoint(-1.0, 0)]; - drawingRect.origin.x = [self bounds].size.width - 5; - [borderGradient drawInRect:drawingRect relativeCenterPosition:NSMakePoint(1.0, 0)]; - [borderGradient release]; - } - [super drawRect:dirtyRect]; -} - -@end diff --git a/MacPass/MPDatabaseDocument.m b/MacPass/MPDatabaseDocument.m index 10043dc6..80b37332 100644 --- a/MacPass/MPDatabaseDocument.m +++ b/MacPass/MPDatabaseDocument.m @@ -126,7 +126,7 @@ NSString *const MPDidLoadDatabaseNotification = @"DidLoadDataBaseNotification"; } - (KdbPassword *)passwordHash { - return [[KdbPassword alloc] initWithPassword:self.password passwordEncoding:NSUTF8StringEncoding keyFile:[self.key path]]; + return [[[KdbPassword alloc] initWithPassword:self.password passwordEncoding:NSUTF8StringEncoding keyFile:[self.key path]] autorelease]; } @end diff --git a/MacPass/MPEntryViewController.h b/MacPass/MPEntryViewController.h index 245ead2b..ed5910e2 100644 --- a/MacPass/MPEntryViewController.h +++ b/MacPass/MPEntryViewController.h @@ -43,8 +43,8 @@ typedef enum { - (void)copyUsername:(id)sender; - (void)copyPassword:(id)sender; -//- (void)copyURL:(id)sender; -//- (void)createEntry:(id)sender; +- (void)copyURL:(id)sender; +- (void)openURL:(id)sender; - (void)deleteEntry:(id)sender; @end diff --git a/MacPass/MPEntryViewController.m b/MacPass/MPEntryViewController.m index fbe0e302..bc32c247 100644 --- a/MacPass/MPEntryViewController.m +++ b/MacPass/MPEntryViewController.m @@ -28,6 +28,12 @@ typedef enum { MPFilterTitles = 8, } MPFilterModeType; +typedef enum { + MPOverlayInfoPassword, + MPOverlayInfoUsername, + MPOverlayInfoURL, +} MPOVerlayInfoType; + NSString *const MPEntryTableUserNameColumnIdentifier = @"MPUserNameColumnIdentifier"; NSString *const MPEntryTableTitleColumnIdentifier = @"MPTitleColumnIdentifier"; NSString *const MPEntryTablePasswordColumnIdentifier = @"MPPasswordColumnIdentifier"; @@ -81,7 +87,8 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername"; - (void)_showFilterBarAnimated:(BOOL)animate; - (void)_hideStatusBarAnimated:(BOOL)animate; -- (void)_quickCopyEntryData:(id)sender; +- (void)_columnDoubleClick:(id)sender; +- (void)_copyToPasteboard:(NSString *)data overlayInfo:(MPOVerlayInfoType)overlayInfoType; - (KdbEntry *)_clickedOrSelectedEntry; @end @@ -127,7 +134,7 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername"; [self _hideStatusBarAnimated:NO]; [self.entryTable setDelegate:self]; - [self.entryTable setDoubleAction:@selector(_quickCopyEntryData:)]; + [self.entryTable setDoubleAction:@selector(_columnDoubleClick:)]; [self.entryTable setTarget:self]; [self _setupEntryMenu]; @@ -210,6 +217,7 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername"; } MPOutlineViewDelegate *delegate = [notification object]; KdbGroup *group = delegate.selectedGroup; + [self.entryTable deselectAll:nil]; if(group) { [self.entryArrayController setContent:nil]; [self.entryArrayController addObjects:group.entries]; @@ -235,7 +243,7 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername"; } - (void)deselectAll:(id)sender { - [self.entryTable deselectAll:self]; + [self.entryTable deselectAll:nil]; } - (void)clearFilter { @@ -298,7 +306,7 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername"; } } -#pragma mark Animation +#pragma mark UI Feedback - (void)_showFilterBarAnimated:(BOOL)animate { @@ -365,6 +373,29 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername"; } } +- (void)_copyToPasteboard:(NSString *)data overlayInfo:(MPOVerlayInfoType)overlayInfoType { + [[MPPasteBoardController defaultController] copyObjects:@[ data ]]; + NSImage *infoImage = nil; + NSString *infoText = nil; + switch (overlayInfoType) { + case MPOverlayInfoPassword: + infoImage = [[NSBundle mainBundle] imageForResource:@"00_PasswordTemplate"]; + infoText = NSLocalizedString(@"COPIED_PASSWORD", @"Password was copied to the pasteboard"); + break; + + case MPOverlayInfoURL: + infoImage = [[NSBundle mainBundle] imageForResource:@"01_PackageNetworkTemplate"]; + infoText = NSLocalizedString(@"COPIED_URL", @"URL was copied to the pasteboard"); + break; + + case MPOverlayInfoUsername: + infoImage = [[NSBundle mainBundle] imageForResource:@"09_IdentityTemplate"]; + infoText = NSLocalizedString(@"COPIED_USERNAME", @"Username was copied to the pasteboard"); + break; + } + [[MPOverlayWindowController sharedController] displayOverlayImage:infoImage label:infoText atView:self.view]; +} + #pragma mark EntryMenu - (void)_setupEntryMenu { @@ -394,48 +425,40 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername"; #pragma mark Actions -- (void)_quickCopyEntryData:(id)sender { - NSTableColumn *column = [self.entryTable tableColumns][[self.entryTable clickedColumn]]; - NSString *identifier = [column identifier]; - if([identifier isEqualToString:MPEntryTablePasswordColumnIdentifier]) { - [self copyPassword:nil]; - } - else if([identifier isEqualToString:MPEntryTableUserNameColumnIdentifier]) { - [self copyUsername:nil]; - } -} - - (void)copyPassword:(id)sender { KdbEntry *selectedEntry = [self _clickedOrSelectedEntry]; - if(!selectedEntry) { - return; // nothing found to work with; + if(selectedEntry) { + [self _copyToPasteboard:selectedEntry.password overlayInfo:MPOverlayInfoPassword]; } - [[MPPasteBoardController defaultController] copyObjects:@[ selectedEntry.password ]]; - NSImage *image = [[NSBundle mainBundle] imageForResource:@"00_PasswordTemplate"]; - NSString *lable = @"Password copied!"; - [[MPOverlayWindowController sharedController] displayOverlayImage:image label:lable atView:self.view]; } - (void)copyUsername:(id)sender { KdbEntry *selectedEntry = [self _clickedOrSelectedEntry]; - if(!selectedEntry) { - return; // No entry to work with; + if(selectedEntry) { + [self _copyToPasteboard:selectedEntry.username overlayInfo:MPOverlayInfoUsername]; + } +} + +- (void)copyURL:(id)sender { + KdbEntry *selectedEntry = [self _clickedOrSelectedEntry]; + if(selectedEntry) { + [self _copyToPasteboard:selectedEntry.url overlayInfo:MPOverlayInfoURL]; + } +} + +- (void)openURL:(id)sender { + KdbEntry *selectedEntry = [self _clickedOrSelectedEntry]; + if(selectedEntry && [selectedEntry.url length] > 0) { + NSURL *webURL = [NSURL URLWithString:selectedEntry.url]; + [[NSWorkspace sharedWorkspace] openURL:webURL]; } - [[MPPasteBoardController defaultController] copyObjects:@[ selectedEntry.username ] ]; - - [[MPPasteBoardController defaultController] copyObjects:@[ selectedEntry.username ]]; - NSImage *image = [[NSBundle mainBundle] imageForResource:@"09_IdentityTemplate"]; - NSString *lable = @"Username copied!"; - [[MPOverlayWindowController sharedController] displayOverlayImage:image label:lable atView:self.view]; } - (void)deleteEntry:(id)sender { KdbEntry *selectedEntry = [self _clickedOrSelectedEntry]; - if(!selectedEntry) { - return; // no entry selected + if(selectedEntry) { + [self.entryArrayController removeObject:selectedEntry]; } - //[[selectedEntry parent] removeEntry:selectedEntry]; - [self.entryArrayController removeObject:selectedEntry]; } - (void)_toggleFilterSpace:(id)sender { @@ -456,6 +479,20 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername"; } } +- (void)_columnDoubleClick:(id)sender { + NSTableColumn *column = [self.entryTable tableColumns][[self.entryTable clickedColumn]]; + NSString *identifier = [column identifier]; + if([identifier isEqualToString:MPEntryTablePasswordColumnIdentifier]) { + [self copyPassword:nil]; + } + else if([identifier isEqualToString:MPEntryTableUserNameColumnIdentifier]) { + [self copyUsername:nil]; + } + else if([identifier isEqualToString:MPEntryTableURLColumnIdentifier]) { + [self copyURL:nil]; + } +} + - (void)setFilterMode:(MPFilterModeType)newFilterMode { if(_filterMode != newFilterMode) { if(newFilterMode == MPFilterNone) { diff --git a/MacPass/MPInspectorTabViewController.m b/MacPass/MPInspectorTabViewController.m index 2bcf8182..bf889379 100644 --- a/MacPass/MPInspectorTabViewController.m +++ b/MacPass/MPInspectorTabViewController.m @@ -8,6 +8,8 @@ #import "MPInspectorTabViewController.h" #import "MPEntryViewController.h" +#import "MPOutlineViewDelegate.h" +#import "MPDatabaseController.h" #import "MPShadowBox.h" #import "MPIconHelper.h" #import "KdbLib.h" @@ -42,6 +44,11 @@ return self; } +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [super dealloc]; +} + - (void)didLoadView { for( NSTabViewItem *item in [self.tabView tabViewItems]){ @@ -55,6 +62,7 @@ selector:@selector(_didChangeSelectedEntry:) name:MPDidChangeSelectedEntryNotification object:nil]; + [self _clearContent]; } @@ -94,7 +102,6 @@ - (void)setSelectedEntry:(KdbEntry *)selectedEntry { if(_selectedEntry != selectedEntry) { _selectedEntry = selectedEntry; - if(_selectedEntry) {} [self _updateContent]; } } diff --git a/MacPass/MPMainWindowController.m b/MacPass/MPMainWindowController.m index b401ff5d..f25ff4c7 100644 --- a/MacPass/MPMainWindowController.m +++ b/MacPass/MPMainWindowController.m @@ -217,25 +217,26 @@ static CGFloat _outlineSplitterPosition; if(menuAction == @selector(toggleOutlineView:)) { NSView *outlineView = [self.splitView subviews][MPSplitViewOutlineViewIndex]; BOOL outlineIsHidden = [self.splitView isSubviewCollapsed:outlineView]; - if(outlineIsHidden) { - [menuItem setTitle:@"Show Outline View"]; - } - [menuItem setTitle:@"Hide Outline View"]; + NSString *title = outlineIsHidden ? NSLocalizedString(@"SHOW_OUTLINE_VIEW", @"") : NSLocalizedString(@"HIDE_OUTLINE_VIEW", @"Hide the Outline View"); + + [menuItem setTitle:title]; return YES; } - if( menuAction == @selector(toggleInspector:) ) { NSView *inspectorView = [self.splitView subviews][MPSplitViewInspectorViewIndex]; BOOL inspectorIsHidden = [self.splitView isSubviewCollapsed:inspectorView]; - if(inspectorIsHidden) { - [menuItem setTitle:@"Show Inspecotr"]; - } - [menuItem setTitle:@"Hide Inspector"]; + NSString *title = inspectorIsHidden ? NSLocalizedString(@"SHOW_INSPECTOR", @"Show the Inspector") : NSLocalizedString(@"HIDE_INSPECTOR", @"Hide the Inspector"); + + [menuItem setTitle:title]; return YES; } return YES; } +- (BOOL)validateToolbarItem:(NSToolbarItem *)theItem { + return [self.toolbarDelegate validateToolbarItem:theItem]; +} + - (void)performFindPanelAction:(id)sender { [self.window makeFirstResponder:[self.toolbarDelegate.searchItem view]]; } diff --git a/MacPass/MPOutlineViewController.m b/MacPass/MPOutlineViewController.m index 5501c613..41fcd526 100644 --- a/MacPass/MPOutlineViewController.m +++ b/MacPass/MPOutlineViewController.m @@ -71,6 +71,7 @@ - (void)_didOpenDocument:(NSNotification *)notification { + [self.outlineView deselectAll:nil]; [self.outlineView reloadData]; MPDatabaseController *dbContoller = [MPDatabaseController defaultController]; if(dbContoller.database) { diff --git a/MacPass/MPPathBar.h b/MacPass/MPPathBar.h deleted file mode 100644 index a41043d2..00000000 --- a/MacPass/MPPathBar.h +++ /dev/null @@ -1,32 +0,0 @@ -// -// MPPathBar.h -// MacPass -// -// Created by michael starke on 22.02.13. -// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved. -// - -#import "MPGradientView.h" - -@class MPPathBar; -/* - Delegate protocoll - */ -@protocol MPPathBarDelegateProtocoll - -@required -- (NSUInteger)numberOfItemsInPathBar:(MPPathBar *)pathBar; -- (NSString *)pathbar:(MPPathBar *)pathbar stringAtIndex:(NSUInteger)index; - -@optional -- (NSImage *)pathbar:(MPPathBar *)pathbar imageAtIndex:(NSUInteger)index; - -@end - - -@interface MPPathBar : MPGradientView - -@property (assign, nonatomic) id delegate; - -@end - diff --git a/MacPass/MPPathBar.m b/MacPass/MPPathBar.m deleted file mode 100644 index 864211ac..00000000 --- a/MacPass/MPPathBar.m +++ /dev/null @@ -1,92 +0,0 @@ -// -// MPPathBar.m -// MacPass -// -// Created by michael starke on 22.02.13. -// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved. -// - -#import "MPPathBar.h" -#import "MPPathBarItemView.h" - -#define INTER_BUTTON_SPACING 5.0 - -@interface MPPathBar () - -@property (retain) NSMutableArray *itemViews; -@property (assign) BOOL delegateSupportsImage; - -- (void)update; -- (void)createViews; -- (MPPathBarItemView *)viewForIndex:(NSUInteger)index; - -@end - -@implementation MPPathBar - -- (id)initWithFrame:(NSRect)frame activeGradient:(NSGradient *)activeGradient inactiveGradient:(NSGradient *)inactiveGradient { - self = [super initWithFrame:frame activeGradient:activeGradient inactiveGradient:inactiveGradient]; - if(self) { - _itemViews = [[NSMutableArray alloc] initWithCapacity:5]; - _delegateSupportsImage = NO; - [self createViews]; - } - return self; -} - -- (void)dealloc { - self.itemViews = nil; - [super dealloc]; -} - -- (void)drawRect:(NSRect)dirtyRect { - [super drawRect:dirtyRect]; - [self update]; -} - -- (void)createViews { - NSUInteger items = 5;//[self.delegate numberOfItemsInPathBar:self]; - CGFloat startPosition = 0; - for (NSUInteger iIndex = 0; iIndex < items; iIndex++) { - MPPathBarItemView *textField = [self viewForIndex:iIndex]; - [textField setFrame:NSMakeRect(startPosition, 0, 20, 20)]; - [self addSubview:textField]; - } - [self update]; -} - -- (void)update { - CGFloat startPosition = 0; - for(MPPathBarItemView *view in self.itemViews) { - [view sizeToFit]; - NSRect newFrame = [view frame]; - newFrame.origin.x = startPosition; - [view setFrame:newFrame]; - startPosition += newFrame.size.width + INTER_BUTTON_SPACING; - } -} - -- (void)setDelegate:(id)delegate { - if(_delegate != delegate) { - _delegate = delegate; - self.delegateSupportsImage = [_delegate respondsToSelector:@selector(pathbar:imageAtIndex:)]; - [self update]; - } -} - - -- (MPPathBarItemView *)viewForIndex:(NSUInteger)index { - MPPathBarItemView *itemView = nil; - if([self.itemViews count] > index) { - itemView = self.itemViews[index]; - } - if(!itemView) { - itemView = [[[MPPathBarItemView alloc] initWithFrame:NSMakeRect(0, 0, 50, 24)] autorelease]; - } - itemView.text = [NSString stringWithFormat:@"Button %ld", (unsigned long)index ]; - itemView.image = [NSImage imageNamed:NSImageNameActionTemplate]; - //[itemView setStringValue:[self.delegate pathbar:self stringAtIndex:index]]; - [self.itemViews addObject:itemView]; - return itemView; -} -@end diff --git a/MacPass/MPPathBarItemView.h b/MacPass/MPPathBarItemView.h deleted file mode 100644 index ff97825b..00000000 --- a/MacPass/MPPathBarItemView.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// MPPathBarItemView.h -// MacPass -// -// Created by michael starke on 22.02.13. -// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved. -// - -#import - -@interface MPPathBarItemView : NSView - -@property (retain, nonatomic) NSImage *image; -@property (retain, nonatomic) NSString *text; - -- (void)sizeToFit; - -@end diff --git a/MacPass/MPPathBarItemView.m b/MacPass/MPPathBarItemView.m deleted file mode 100644 index c4485813..00000000 --- a/MacPass/MPPathBarItemView.m +++ /dev/null @@ -1,105 +0,0 @@ -// -// MPPathBarItemView.m -// MacPass -// -// Created by michael starke on 22.02.13. -// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved. -// - -#import "MPPathBarItemView.h" - -#define IMAGE_TO_TEXT_MARGIN 5.0 - -@interface MPPathBarItemView () - -@property (retain) NSImageView *imageView; -@property (retain) NSTextField *textField; - -@end - -@implementation MPPathBarItemView - -- (id)initWithFrame:(NSRect)frameRect { - self = [super initWithFrame:frameRect]; - if(self) { - - _imageView = [[NSImageView alloc] initWithFrame:NSMakeRect(0, 0, 20, 24)]; - [[_imageView cell] setImageAlignment:NSImageAlignCenter]; - [[_imageView cell] setBackgroundStyle:NSBackgroundStyleRaised]; - [[_imageView cell] setBordered:NO]; - [[_imageView cell] setDrawsBackground:NO]; - [_imageView setImage:[NSImage imageNamed:NSImageNameActionTemplate ]]; - - _textField = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 20, 24)]; - [_textField setBordered:NO]; - [_textField setFont:[NSFont systemFontOfSize:13]]; - [_textField setDrawsBackground:NO]; - [_textField setEditable:NO]; - [_textField setSelectable:NO]; - [[_textField cell] setBackgroundStyle:NSBackgroundStyleRaised]; - [_textField setStringValue:@"Boo"]; - - - [self addSubview:_textField]; - [self addSubview:_imageView]; - - - [self sizeToFit]; - - [self needsLayout]; - } - return self; -} - -- (void)setText:(NSString *)text { - if(_text != text) { - [_text release]; - _text = [text retain]; - [self.textField setStringValue:text]; - [self sizeToFit]; - } -} - -- (void)setImage:(NSImage *)image { - if(_image != image) { - [_image release]; - _image = [image retain]; - [_imageView setImage:image]; - [self sizeToFit]; - } -} - -- (void)sizeToFit { - - const BOOL isAutoResize = [self autoresizesSubviews];/* Disable autoresizing */ - [self setAutoresizesSubviews:NO]; - NSRect superFrame = [self frame]; - /* - Let our subviews calculate their sizes - */ - [self.textField sizeToFit]; - //[self.imageView sizeToFit]; - NSRect textFrame = [self.textField frame]; - NSRect imageFrame = [self.imageView frame]; - /* - Determine our size - */ - CGFloat height = MAX(textFrame.size.height, imageFrame.size.height); - CGFloat width = textFrame.size.width + IMAGE_TO_TEXT_MARGIN + imageFrame.size.width; - - [self setFrame:NSMakeRect(superFrame.origin.x, superFrame.origin.y, width, height)]; - - imageFrame.origin.x = 0; - imageFrame.origin.y = 0; - imageFrame.size.height = height; - textFrame.origin.x = imageFrame.size.width + IMAGE_TO_TEXT_MARGIN; - textFrame.origin.y = 0; - textFrame.size.height = height; - - [self.textField setFrame:textFrame]; - [self.imageView setFrame:imageFrame]; - /* Reset the autoresizing */ - [self setAutoresizesSubviews:isAutoResize]; -} - -@end diff --git a/MacPass/MPPathControl.m b/MacPass/MPPathControl.m deleted file mode 100644 index 78620d52..00000000 --- a/MacPass/MPPathControl.m +++ /dev/null @@ -1,22 +0,0 @@ -// -// MPPathControl.m -// MacPass -// -// Created by Michael Starke on 02.03.13. -// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved. -// - -#import "MPPathControl.h" - -@implementation MPPathControl - -- (id)initWithFrame:(NSRect)frame -{ - self = [super initWithFrame:frame]; - if (self) { - [[self cell] setShowsStateBy:NSNoCellMask]; - } - return self; -} - -@end diff --git a/MacPass/MPToolbarButton.m b/MacPass/MPToolbarButton.m index 6c8786a5..25efefcd 100644 --- a/MacPass/MPToolbarButton.m +++ b/MacPass/MPToolbarButton.m @@ -10,6 +10,14 @@ @implementation MPToolbarButton +- (id)initWithFrame:(NSRect)frameRect { + self = [super initWithFrame:frameRect]; + if(self) { + [self setFocusRingType:NSFocusRingTypeNone]; + } + return self; +} + - (void)setControlSize:(NSControlSize)controlSize { [[self cell] setControlSize:controlSize]; switch (controlSize) { diff --git a/MacPass/MPToolbarDelegate.m b/MacPass/MPToolbarDelegate.m index 39f59935..2c6bee84 100644 --- a/MacPass/MPToolbarDelegate.m +++ b/MacPass/MPToolbarDelegate.m @@ -10,14 +10,16 @@ #import "MPIconHelper.h" #import "MPAppDelegate.h" #import "MPToolbarButton.h" +#import "MPToolbarItem.h" +#import "MPActionHelper.h" -NSString *const MPToolbarItemAddGroup = @"AddGroup"; -NSString *const MPToolbarItemAddEntry = @"AddEntry"; -NSString *const MPToolbarItemEdit = @"Edit"; -NSString *const MPToolbarItemDelete =@"Delete"; -NSString *const MPToolbarItemAction = @"Action"; -NSString *const MPToolbarItemSearch = @"Search"; -NSString *const MPToolbarItemInspector = @"Inspector"; +NSString *const MPToolbarItemAddGroup = @"TOOLBAR_ADD_GROUP"; +NSString *const MPToolbarItemAddEntry = @"TOOLBAR_ADD_ENTRY"; +NSString *const MPToolbarItemEdit = @"TOOLBAR_EDIT"; +NSString *const MPToolbarItemDelete =@"TOOLBAR_DELETE"; +NSString *const MPToolbarItemAction = @"TOOLBAR_ACTION"; +NSString *const MPToolbarItemSearch = @"TOOLBAR_SEARCH"; +NSString *const MPToolbarItemInspector = @"TOOLBAR_INSPECTOR"; @interface MPToolbarDelegate() @@ -25,6 +27,9 @@ NSString *const MPToolbarItemInspector = @"Inspector"; @property (retain) NSArray *toolbarIdentifiers; @property (retain) NSDictionary *toolbarImages; +- (NSString *)_localizedLabelForToolbarItemIdentifier:(NSString *)identifier; +- (SEL)_actionForToolbarItemIdentifier:(NSString *)identifier; + @end @implementation MPToolbarDelegate @@ -33,7 +38,7 @@ NSString *const MPToolbarItemInspector = @"Inspector"; - (id)init { self = [super init]; if (self) { - _toolbarIdentifiers = [@[ MPToolbarItemAddEntry, MPToolbarItemDelete, MPToolbarItemEdit, MPToolbarItemAddGroup, MPToolbarItemAction, NSToolbarFlexibleSpaceItemIdentifier, NSToolbarSpaceItemIdentifier, MPToolbarItemInspector, MPToolbarItemSearch ] retain]; + _toolbarIdentifiers = [@[ MPToolbarItemAddEntry, MPToolbarItemDelete, MPToolbarItemAddGroup, MPToolbarItemAction, NSToolbarFlexibleSpaceItemIdentifier, NSToolbarSpaceItemIdentifier, MPToolbarItemInspector, MPToolbarItemSearch ] retain]; _toolbarImages = [[self createToolbarImages] retain]; _toolbarItems = [[NSMutableDictionary alloc] initWithCapacity:[self.toolbarIdentifiers count]]; } @@ -50,9 +55,9 @@ NSString *const MPToolbarItemInspector = @"Inspector"; - (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag { NSToolbarItem *item = self.toolbarItems[itemIdentifier]; - if(!item) { - item = [[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier]; - NSString *label = NSLocalizedString(itemIdentifier, @""); + if(!item) { + item = [[MPToolbarItem alloc] initWithItemIdentifier:itemIdentifier]; + NSString *label = [self _localizedLabelForToolbarItemIdentifier:itemIdentifier]; [item setLabel:label]; if([itemIdentifier isEqualToString:MPToolbarItemSearch]) { @@ -71,7 +76,7 @@ NSString *const MPToolbarItemInspector = @"Inspector"; [[popupButton cell] setImageScaling:NSImageScaleProportionallyDown]; [popupButton setTitle:@""]; [popupButton sizeToFit]; - + NSRect newFrame = [popupButton frame]; newFrame.size.width += 20; @@ -104,13 +109,7 @@ NSString *const MPToolbarItemInspector = @"Inspector"; [button setImage:image]; [button setImagePosition:NSImageOnly]; [button sizeToFit]; - if([itemIdentifier isEqualToString:MPToolbarItemEdit]) { - [button setTarget:nil]; - [button setAction:@selector(showEditForm:)]; - } - else if( [itemIdentifier isEqualToString:MPToolbarItemInspector]) { - [button setAction:@selector(toggleInspector:)]; - } + [button setAction:[self _actionForToolbarItemIdentifier:itemIdentifier]]; NSRect fittingRect = [button frame]; fittingRect.size.width = MAX( (CGFloat)32.0,fittingRect.size.width); @@ -137,11 +136,35 @@ NSString *const MPToolbarItemInspector = @"Inspector"; NSDictionary *imageDict = @{ MPToolbarItemAddEntry: [MPIconHelper icon:MPIconPassword], MPToolbarItemAddGroup: [MPIconHelper icon:MPIconPassword], MPToolbarItemDelete: [NSImage imageNamed:NSImageNameRemoveTemplate], - MPToolbarItemEdit: [MPIconHelper icon:MPIconNotepad], MPToolbarItemAction: [NSImage imageNamed:NSImageNameActionTemplate], MPToolbarItemInspector: [NSImage imageNamed:NSImageNameInfo], }; return imageDict; } +- (NSString *)_localizedLabelForToolbarItemIdentifier:(NSString *)identifier { + NSDictionary *labelDict = @{ + MPToolbarItemAction: NSLocalizedString(@"ACTION", @""), + MPToolbarItemAddEntry: NSLocalizedString(@"ADD_ENTRY", @""), + MPToolbarItemAddGroup: NSLocalizedString(@"ADD_GROUP", @""), + MPToolbarItemDelete: NSLocalizedString(@"DELETE", @""), + MPToolbarItemEdit: NSLocalizedString(@"EDIT", @""), + MPToolbarItemInspector: NSLocalizedString(@"TOGGLE_INSPECTOR", @""), + MPToolbarItemSearch: NSLocalizedString(@"SEARCH", @"") + }; + return labelDict[identifier]; +} + +- (SEL)_actionForToolbarItemIdentifier:(NSString *)identifier { + NSDictionary *actionDict = @{ + MPToolbarItemAddEntry: @(MPActionAddEntry), + MPToolbarItemAddGroup: @(MPActionAddGroup), + MPToolbarItemDelete: @(MPActionDelete), + MPToolbarItemEdit: @(MPActionEdit), + MPToolbarItemInspector: @(MPActionToggleInspector) + }; + MPActionType actionType = (MPActionType)[actionDict[identifier] integerValue]; + return [MPActionHelper actionOfType:actionType]; +} + @end diff --git a/MacPass/MPPathControl.h b/MacPass/MPToolbarItem.h similarity index 53% rename from MacPass/MPPathControl.h rename to MacPass/MPToolbarItem.h index 0a633e99..42adb800 100644 --- a/MacPass/MPPathControl.h +++ b/MacPass/MPToolbarItem.h @@ -1,13 +1,13 @@ // -// MPPathControl.h +// MPToolbarItem.h // MacPass // -// Created by Michael Starke on 02.03.13. +// Created by Michael Starke on 09.03.13. // Copyright (c) 2013 HicknHack Software GmbH. All rights reserved. // #import -@interface MPPathControl : NSPathControl +@interface MPToolbarItem : NSToolbarItem @end diff --git a/MacPass/MPToolbarItem.m b/MacPass/MPToolbarItem.m new file mode 100644 index 00000000..91a6529b --- /dev/null +++ b/MacPass/MPToolbarItem.m @@ -0,0 +1,20 @@ +// +// MPToolbarItem.m +// MacPass +// +// Created by Michael Starke on 09.03.13. +// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved. +// + +#import "MPToolbarItem.h" +#import "MPActionHelper.h" + +@implementation MPToolbarItem + +- (void)validate { + if(![self.view menu]) { + id target = [NSApp targetForAction:[self action] to:nil from:self]; + [self setEnabled:( nil != target )]; + } +} +@end diff --git a/MacPass/MacPass-Info.plist b/MacPass/MacPass-Info.plist index beef99cc..1257d0f2 100644 --- a/MacPass/MacPass-Info.plist +++ b/MacPass/MacPass-Info.plist @@ -21,7 +21,7 @@ CFBundleSignature ???? CFBundleVersion - 48A + 4B8 LSMinimumSystemVersion ${MACOSX_DEPLOYMENT_TARGET} NSHumanReadableCopyright diff --git a/MacPass/MainWindow.xib b/MacPass/MainWindow.xib index a1144e32..b9a1b01a 100644 --- a/MacPass/MainWindow.xib +++ b/MacPass/MainWindow.xib @@ -56,7 +56,7 @@ 268 - {209, 449} + {200, 449} @@ -67,7 +67,7 @@ 256 - {{210, 0}, {383, 449}} + {{201, 0}, {325, 449}} @@ -77,7 +77,7 @@ 268 - {{594, 0}, {133, 449}} + {{527, 0}, {200, 449}} _NS:9 diff --git a/MacPass/en.lproj/Localizable.strings b/MacPass/en.lproj/Localizable.strings new file mode 100644 index 00000000..7d866716 Binary files /dev/null and b/MacPass/en.lproj/Localizable.strings differ