mirror of
https://github.com/MacPass/MacPass.git
synced 2025-12-13 21:42:32 +00:00
Enhanced Context menu on outline view
This commit is contained in:
Submodule KeePassKit updated: a5840cdee0...e1edcc115b
@@ -126,6 +126,7 @@
|
||||
4C5AA591179549A1008ECAD7 /* KPKXmlTreeWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C5AA590179549A1008ECAD7 /* KPKXmlTreeWriter.m */; };
|
||||
4C5BF67B175C01F300D53DF7 /* MPUppercaseStringValueTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C5BF67A175C01F300D53DF7 /* MPUppercaseStringValueTransformer.m */; };
|
||||
4C5EC302177B700D00DA955B /* MPRootAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C5EC301177B700D00DA955B /* MPRootAdapter.m */; };
|
||||
4C5FA86D17A5F26800C781C9 /* KPKDataStreamWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C5FA86C17A5F26800C781C9 /* KPKDataStreamWriter.m */; };
|
||||
4C5FE9AE17843CE20001D5A8 /* MPSelectedAttachmentTableCellView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C5FE9AD17843CE20001D5A8 /* MPSelectedAttachmentTableCellView.m */; };
|
||||
4C61EA0316D2FD0800AC519E /* MPOutlineViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C61EA0216D2FD0800AC519E /* MPOutlineViewController.m */; };
|
||||
4C61EA0516D2FFE200AC519E /* OutlineView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C61EA0416D2FFE200AC519E /* OutlineView.xib */; };
|
||||
@@ -195,6 +196,7 @@
|
||||
4C888C9316EB6F5E003D34A1 /* MPToolbarItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C888C9216EB6F5E003D34A1 /* MPToolbarItem.m */; };
|
||||
4C888C9716EB754B003D34A1 /* MPActionHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C888C9616EB754B003D34A1 /* MPActionHelper.m */; };
|
||||
4C8A173D1790AA41008B5C17 /* NSData+Keyfile.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8A173C1790AA41008B5C17 /* NSData+Keyfile.m */; };
|
||||
4C8B36AB17A6ED4B005E1FF1 /* MPOutlineMenuDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8B36AA17A6ED4B005E1FF1 /* MPOutlineMenuDelegate.m */; };
|
||||
4C8FECC816D57E3200BF26CF /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C8FECC716D57E3200BF26CF /* QuartzCore.framework */; };
|
||||
4C96D15417A12E4F00D931FA /* 99_CreatedTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4C96D15317A12E4F00D931FA /* 99_CreatedTemplate.pdf */; };
|
||||
4C9D6AA917615199001C660C /* HNHRoundedSecureTextFieldCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C9D6AA817615199001C660C /* HNHRoundedSecureTextFieldCell.m */; };
|
||||
@@ -224,7 +226,7 @@
|
||||
4CC7EA1B17807E7E0089D4F3 /* HNHRoundedTextFieldCellHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CC7EA1A17807E7E0089D4F3 /* HNHRoundedTextFieldCellHelper.m */; };
|
||||
4CCEDE2A179F203B008402BE /* MPOutlineView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CCEDE29179F203B008402BE /* MPOutlineView.m */; };
|
||||
4CCEDE2E179F213B008402BE /* MPNotifications.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CCEDE2D179F213B008402BE /* MPNotifications.m */; };
|
||||
4CCEDE32179F5B6C008402BE /* KPKDataStreamer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CCEDE31179F5B6C008402BE /* KPKDataStreamer.m */; };
|
||||
4CCEDE32179F5B6C008402BE /* KPKDataStreamReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CCEDE31179F5B6C008402BE /* KPKDataStreamReader.m */; };
|
||||
4CD3ABBA178F71B50073F5C5 /* KPKTree.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD3ABB4178F71B50073F5C5 /* KPKTree.m */; };
|
||||
4CD3ABBF178F72610073F5C5 /* KPKEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD3ABBE178F72610073F5C5 /* KPKEntry.m */; };
|
||||
4CD3ABC2178F72720073F5C5 /* KPKGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD3ABC1178F72720073F5C5 /* KPKGroup.m */; };
|
||||
@@ -484,6 +486,8 @@
|
||||
4C5BF67A175C01F300D53DF7 /* MPUppercaseStringValueTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPUppercaseStringValueTransformer.m; sourceTree = "<group>"; };
|
||||
4C5EC300177B700D00DA955B /* MPRootAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPRootAdapter.h; sourceTree = "<group>"; };
|
||||
4C5EC301177B700D00DA955B /* MPRootAdapter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPRootAdapter.m; sourceTree = "<group>"; };
|
||||
4C5FA86B17A5F26800C781C9 /* KPKDataStreamWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KPKDataStreamWriter.h; sourceTree = "<group>"; };
|
||||
4C5FA86C17A5F26800C781C9 /* KPKDataStreamWriter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KPKDataStreamWriter.m; sourceTree = "<group>"; };
|
||||
4C5FE9AC17843CE20001D5A8 /* MPSelectedAttachmentTableCellView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPSelectedAttachmentTableCellView.h; sourceTree = "<group>"; };
|
||||
4C5FE9AD17843CE20001D5A8 /* MPSelectedAttachmentTableCellView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPSelectedAttachmentTableCellView.m; sourceTree = "<group>"; };
|
||||
4C61EA0116D2FD0800AC519E /* MPOutlineViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPOutlineViewController.h; sourceTree = "<group>"; };
|
||||
@@ -621,6 +625,8 @@
|
||||
4C888C9616EB754B003D34A1 /* MPActionHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPActionHelper.m; sourceTree = "<group>"; };
|
||||
4C8A173B1790AA41008B5C17 /* NSData+Keyfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+Keyfile.h"; sourceTree = "<group>"; };
|
||||
4C8A173C1790AA41008B5C17 /* NSData+Keyfile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+Keyfile.m"; sourceTree = "<group>"; };
|
||||
4C8B36A917A6ED4B005E1FF1 /* MPOutlineMenuDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPOutlineMenuDelegate.h; sourceTree = "<group>"; };
|
||||
4C8B36AA17A6ED4B005E1FF1 /* MPOutlineMenuDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPOutlineMenuDelegate.m; sourceTree = "<group>"; };
|
||||
4C8FECC716D57E3200BF26CF /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
|
||||
4C96D15317A12E4F00D931FA /* 99_CreatedTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 99_CreatedTemplate.pdf; sourceTree = "<group>"; };
|
||||
4C9D6AA717615199001C660C /* HNHRoundedSecureTextFieldCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HNHRoundedSecureTextFieldCell.h; sourceTree = "<group>"; };
|
||||
@@ -680,8 +686,8 @@
|
||||
4CCEDE2C179F2122008402BE /* MPNotifications.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MPNotifications.h; sourceTree = "<group>"; };
|
||||
4CCEDE2D179F213B008402BE /* MPNotifications.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPNotifications.m; sourceTree = "<group>"; };
|
||||
4CCEDE2F179F550D008402BE /* KPKTreeReading.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KPKTreeReading.h; sourceTree = "<group>"; };
|
||||
4CCEDE30179F5B6C008402BE /* KPKDataStreamer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KPKDataStreamer.h; sourceTree = "<group>"; };
|
||||
4CCEDE31179F5B6C008402BE /* KPKDataStreamer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KPKDataStreamer.m; sourceTree = "<group>"; };
|
||||
4CCEDE30179F5B6C008402BE /* KPKDataStreamReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KPKDataStreamReader.h; sourceTree = "<group>"; };
|
||||
4CCEDE31179F5B6C008402BE /* KPKDataStreamReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KPKDataStreamReader.m; sourceTree = "<group>"; };
|
||||
4CD3ABB2178F71B50073F5C5 /* KPKVersion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KPKVersion.h; path = Format/KPKVersion.h; sourceTree = "<group>"; };
|
||||
4CD3ABB3178F71B50073F5C5 /* KPKTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KPKTree.h; sourceTree = "<group>"; };
|
||||
4CD3ABB4178F71B50073F5C5 /* KPKTree.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KPKTree.m; sourceTree = "<group>"; };
|
||||
@@ -1105,6 +1111,8 @@
|
||||
4CC0D2D017974A5A000B4BDA /* MPAttachmentTableViewDelegate.m */,
|
||||
4C17D8E317A1C780006C8C1E /* MPDocumentWindowDelegate.h */,
|
||||
4C17D8E417A1C780006C8C1E /* MPDocumentWindowDelegate.m */,
|
||||
4C8B36A917A6ED4B005E1FF1 /* MPOutlineMenuDelegate.h */,
|
||||
4C8B36AA17A6ED4B005E1FF1 /* MPOutlineMenuDelegate.m */,
|
||||
);
|
||||
name = Delegates;
|
||||
sourceTree = "<group>";
|
||||
@@ -1585,8 +1593,10 @@
|
||||
4C1842D4179C6DE400E2F5BC /* KPKHeaderReading.h */,
|
||||
4C1842D5179C6F1800E2F5BC /* KPKHeaderWriting.h */,
|
||||
4CCEDE2F179F550D008402BE /* KPKTreeReading.h */,
|
||||
4CCEDE30179F5B6C008402BE /* KPKDataStreamer.h */,
|
||||
4CCEDE31179F5B6C008402BE /* KPKDataStreamer.m */,
|
||||
4CCEDE30179F5B6C008402BE /* KPKDataStreamReader.h */,
|
||||
4CCEDE31179F5B6C008402BE /* KPKDataStreamReader.m */,
|
||||
4C5FA86B17A5F26800C781C9 /* KPKDataStreamWriter.h */,
|
||||
4C5FA86C17A5F26800C781C9 /* KPKDataStreamWriter.m */,
|
||||
);
|
||||
path = IO;
|
||||
sourceTree = "<group>";
|
||||
@@ -2013,13 +2023,15 @@
|
||||
4CFC873E179DF200000DFC03 /* KPKTimeInfo.m in Sources */,
|
||||
4CCEDE2A179F203B008402BE /* MPOutlineView.m in Sources */,
|
||||
4CCEDE2E179F213B008402BE /* MPNotifications.m in Sources */,
|
||||
4CCEDE32179F5B6C008402BE /* KPKDataStreamer.m in Sources */,
|
||||
4CCEDE32179F5B6C008402BE /* KPKDataStreamReader.m in Sources */,
|
||||
4C17D8E517A1C780006C8C1E /* MPDocumentWindowDelegate.m in Sources */,
|
||||
4C63B8FB17A3154D0091BD72 /* MPContextToolbarButton.m in Sources */,
|
||||
4C4B7EE917A45EC6000234C7 /* MPDatePickingViewController.m in Sources */,
|
||||
4C4B7EEE17A467E1000234C7 /* MPGroupInspectorViewController.m in Sources */,
|
||||
4C4B7EF317A467FC000234C7 /* MPEntryInspectorViewController.m in Sources */,
|
||||
4C4B7EF817A4B335000234C7 /* MPUniqueCharactersFormatter.m in Sources */,
|
||||
4C5FA86D17A5F26800C781C9 /* KPKDataStreamWriter.m in Sources */,
|
||||
4C8B36AB17A6ED4B005E1FF1 /* MPOutlineMenuDelegate.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
||||
@@ -10,9 +10,13 @@
|
||||
#import "KdbGroup+KVOAdditions.h"
|
||||
#import "MPIconHelper.h"
|
||||
|
||||
#import "Kdb4Node.h"
|
||||
|
||||
@implementation KdbGroup (MPAdditions)
|
||||
|
||||
- (NSImage *)icon {
|
||||
if([self respondsToSelector:@selector(customIconUuid)]) {
|
||||
}
|
||||
return [MPIconHelper icon:(MPIconType)self.image];
|
||||
}
|
||||
|
||||
|
||||
@@ -17,9 +17,17 @@
|
||||
- (NSArray *)childEntries;
|
||||
/* Returns the entry with the UUID */
|
||||
- (KdbEntry *)entryForUUID:(UUID *)uuid;
|
||||
/* Returns the group with the UUID */
|
||||
/**
|
||||
* Searches through all subgroups and loactes the Group with the given UUID
|
||||
* @param uuid UUID of the searched group
|
||||
* @return group with matching UUID, otherwise nil
|
||||
*/
|
||||
- (KdbGroup *)groupForUUID:(UUID *)uuid;
|
||||
|
||||
/**
|
||||
* Determines, if the reciever is an anchestor of the given group
|
||||
* @param group The group to test for anchestry
|
||||
* @return YES, if the receiver is an anchestor of group
|
||||
*/
|
||||
- (BOOL)isAnchestorOfGroup:(KdbGroup *)group;
|
||||
|
||||
@end
|
||||
@@ -9,7 +9,7 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
typedef NS_ENUM(NSUInteger, MPActionType) {
|
||||
MPUnkownAction, // Netural element to be used for returns
|
||||
MPUnkownAction, // Neutral element to be used for returns
|
||||
MPActionAddEntry, // Add an new entry
|
||||
MPActionAddGroup, // Add a new group
|
||||
MPActionDelete, // Delete entry or group
|
||||
@@ -19,12 +19,24 @@ typedef NS_ENUM(NSUInteger, MPActionType) {
|
||||
MPActionOpenURL, // open url in default browser
|
||||
MPActionToggleInspector,
|
||||
MPActionLock, // show the lock screen
|
||||
MPActionEmptyTrash // empties the trashcan, if there is one
|
||||
MPActionEmptyTrash, // empties the trashcan, if there is one
|
||||
MPActionDatabaseSettings // Show the settings for the database
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper to retrieve commonly used actions
|
||||
*/
|
||||
@interface MPActionHelper : NSObject
|
||||
|
||||
/**
|
||||
* Call this to retrieve a selector for a common used action
|
||||
* @param type The action type as MPActionType
|
||||
* @return selector for this action type
|
||||
*/
|
||||
+ (SEL)actionOfType:(MPActionType)type;
|
||||
/**
|
||||
* Helper to retrieve the MPActionType for a given selection
|
||||
* @param action Selector to find the type for
|
||||
* @return MPActionTpype for action, if no match was found MPUnknownAction is returned
|
||||
*/
|
||||
+ (MPActionType)typeForAction:(SEL)action;
|
||||
|
||||
@end
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
@(MPActionOpenURL) : @"openURL:",
|
||||
@(MPActionToggleInspector) : @"toggleInspector:",
|
||||
@(MPActionLock) : @"lock:",
|
||||
@(MPActionEmptyTrash) : @"emptyTrash:"
|
||||
@(MPActionEmptyTrash) : @"emptyTrash:",
|
||||
@(MPActionDatabaseSettings) : @"showDatabaseSettings:"
|
||||
};
|
||||
});
|
||||
return actionDict;
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)notification {
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)notification {
|
||||
serverDaemon = [[MPServerDaemon alloc] init];
|
||||
lockDaemon = [[MPLockDaemon alloc] init];
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
[self setFocusRingType:NSFocusRingTypeNone];
|
||||
[self setSegmentCount:1];
|
||||
//[[self cell] setWidth:15 forSegment:1];
|
||||
[self setSegmentCount:2];
|
||||
[[self cell] setWidth:15 forSegment:1];
|
||||
[[self cell] setTrackingMode:NSSegmentSwitchTrackingMomentary];
|
||||
[self setSegmentStyle:NSSegmentStyleTexturedSquare];
|
||||
}
|
||||
@@ -32,7 +32,7 @@
|
||||
}
|
||||
|
||||
- (void)setSegmentCount:(NSInteger)count {
|
||||
if(count == 1) {
|
||||
if(count == 2) {
|
||||
[super setSegmentCount:count];
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,4 @@
|
||||
[self setImage:image forSegment:0];
|
||||
}
|
||||
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@@ -14,7 +14,7 @@ typedef NS_ENUM(NSUInteger, MPDatabaseSettingsTab) {
|
||||
MPDatabaseSettingsTabPassword,
|
||||
MPDatabaseSettingsTabDisplay,
|
||||
MPDatabaseSettingsTabAdvanced,
|
||||
MPDatabaseSettingsTemplatesTab,
|
||||
MPDatabaseSettingsTabTemplates,
|
||||
};
|
||||
|
||||
@class MPDocument;
|
||||
|
||||
@@ -207,7 +207,7 @@
|
||||
|
||||
case MPDatabaseSettingsTabAdvanced:
|
||||
case MPDatabaseSettingsTabGeneral:
|
||||
case MPDatabaseSettingsTemplatesTab:
|
||||
case MPDatabaseSettingsTabTemplates:
|
||||
return (_document.version == MPDatabaseVersion4);
|
||||
|
||||
default:
|
||||
@@ -346,7 +346,7 @@
|
||||
[[self window] makeFirstResponder:self.passwordTextField];
|
||||
break;
|
||||
|
||||
case MPDatabaseSettingsTemplatesTab:
|
||||
case MPDatabaseSettingsTabTemplates:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ APPKIT_EXTERN NSString *const MPDocumnetDidChangeCurrentEntryNotification;
|
||||
@property (weak, readonly, nonatomic) KdbGroup *root;
|
||||
@property (readonly, strong) MPRootAdapter *rootAdapter;
|
||||
@property (weak, readonly) KdbGroup *trash;
|
||||
@property (weak, readonly) KdbGroup *templates;
|
||||
|
||||
@property (nonatomic, copy) NSString *password;
|
||||
@property (nonatomic, strong) NSURL *key;
|
||||
|
||||
@@ -51,6 +51,10 @@ NSString *const MPDocumentRequestPasswordSaveNotification = @"com.hicknhack.macp
|
||||
NSString *const MPDocumentEntryKey = @"MPDocumentEntryKey";
|
||||
NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
|
||||
|
||||
typedef NS_ENUM(NSUInteger, MPAlertType) {
|
||||
MPAlertTypeEmptryTrash,
|
||||
MPAlertTypeDeleteTrashed
|
||||
};
|
||||
|
||||
@interface MPDocument () {
|
||||
@private
|
||||
@@ -349,6 +353,15 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (KdbGroup *)templates {
|
||||
static KdbGroup *_templates = nil;
|
||||
BOOL templateValid = [((Kdb4Group *)_templates).uuid isEqual:self.treeV4.entryTemplatesGroup];
|
||||
if(!templateValid) {
|
||||
_templates = [self findGroup:self.treeV4.entryTemplatesGroup];
|
||||
}
|
||||
return _templates;
|
||||
}
|
||||
|
||||
- (BOOL)isItemTrashed:(id)item {
|
||||
BOOL validItem = [item isKindOfClass:[KdbEntry class]] || [item isKindOfClass:[KdbGroup class]];
|
||||
if(!item) {
|
||||
@@ -510,7 +523,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey
|
||||
[alert beginSheetModalForWindow:window modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:NULL];
|
||||
}
|
||||
|
||||
- (void) alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo {
|
||||
- (void)alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo {
|
||||
if(returnCode == NSAlertFirstButtonReturn) {
|
||||
[self _emptyTrash];
|
||||
}
|
||||
|
||||
@@ -35,8 +35,12 @@
|
||||
- (void)showEntries;
|
||||
- (void)showPasswordInput;
|
||||
- (void)performFindPanelAction:(id)sender;
|
||||
|
||||
- (IBAction)editPassword:(id)sender;
|
||||
- (IBAction)showDatabaseSettings:(id)sender;
|
||||
- (IBAction)editTemplateGroup:(id)sender;
|
||||
- (IBAction)editTrashGroup:(id)sender;
|
||||
|
||||
- (IBAction)exportDatabase:(id)sender;
|
||||
|
||||
- (IBAction)lock:(id)sender;
|
||||
|
||||
@@ -252,11 +252,19 @@
|
||||
}
|
||||
|
||||
- (void)editPassword:(id)sender {
|
||||
[self _showDatabaseSetting:MPDatabaseSettingsTabPassword saveDocument:NO];
|
||||
[self _showDatabaseSetting:MPDatabaseSettingsTabPassword];
|
||||
}
|
||||
|
||||
- (void)showDatabaseSettings:(id)sender {
|
||||
[self _showDatabaseSetting:MPDatabaseSettingsTabGeneral saveDocument:NO];
|
||||
[self _showDatabaseSetting:MPDatabaseSettingsTabGeneral];
|
||||
}
|
||||
|
||||
- (void)editTemplateGroup:(id)sender {
|
||||
[self _showDatabaseSetting:MPDatabaseSettingsTabTemplates];
|
||||
}
|
||||
|
||||
- (void)editTrashGroup:(id)sender {
|
||||
[self _showDatabaseSetting:MPDatabaseSettingsTabAdvanced];
|
||||
}
|
||||
|
||||
- (IBAction)lock:(id)sender {
|
||||
@@ -383,7 +391,7 @@
|
||||
[self editPassword:nil];
|
||||
}
|
||||
|
||||
- (void)_showDatabaseSetting:(MPDatabaseSettingsTab)tab saveDocument:(BOOL)save{
|
||||
- (void)_showDatabaseSetting:(MPDatabaseSettingsTab)tab {
|
||||
if(!self.documentSettingsWindowController) {
|
||||
_documentSettingsWindowController = [[MPDatabaseSettingsWindowController alloc] initWithDocument:[self document]];
|
||||
[_documentSettingsWindowController setDelegate:self];
|
||||
|
||||
@@ -416,8 +416,10 @@ NSString *const _toggleFilterUsernameButton = @"SearchUsername";
|
||||
context.duration = STATUS_BAR_ANIMATION_TIME;
|
||||
context.allowsImplicitAnimation = YES;
|
||||
[self.view layoutSubtreeIfNeeded];
|
||||
} completionHandler:nil] ;
|
||||
[[[self windowController] window] makeFirstResponder:self.filterSearchField];
|
||||
} completionHandler:^{
|
||||
[[[self windowController] window] makeFirstResponder:self.filterSearchField];
|
||||
}];
|
||||
|
||||
}
|
||||
|
||||
- (void)_hideFilterBarAnimated {
|
||||
|
||||
@@ -66,9 +66,9 @@
|
||||
|
||||
- (void)_updateBindings {
|
||||
if(self.group) {
|
||||
[self.titleTextField bind:NSValueBinding toObject:self.group withKeyPath:@"name" options:nil];
|
||||
[self.titleTextField bind:NSValueBinding toObject:self.group withKeyPath:@"nameUndoable" options:nil];
|
||||
if([self.group respondsToSelector:@selector(notes:)]) {
|
||||
[self.notesTextView bind:NSValueBinding toObject:self.group withKeyPath:@"notes" options:nil];
|
||||
[self.notesTextView bind:NSValueBinding toObject:self.group withKeyPath:@"notesUndoable" options:nil];
|
||||
}
|
||||
else {
|
||||
[self.notesTextView unbind:NSValueBinding];
|
||||
|
||||
@@ -7,7 +7,11 @@
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
/**
|
||||
* Available IconTypes
|
||||
* Every Icon after MPCustomIconTypeBegin
|
||||
* is not suitable for usage as KDB Icon
|
||||
*/
|
||||
typedef NS_ENUM(NSUInteger, MPIconType) {
|
||||
MPIconPassword,
|
||||
MPIconPackageNetwork,
|
||||
@@ -29,30 +33,37 @@ typedef NS_ENUM(NSUInteger, MPIconType) {
|
||||
MPIconFolder = 48,
|
||||
MPIconPhone = 68,
|
||||
/* Custom Icons not used in Database */
|
||||
MPIconInfo = 1000,
|
||||
MPCustomIconTypeBegin = 1000,
|
||||
MPIconInfo,
|
||||
MPIconAddFolder,
|
||||
MPIconHardDisk,
|
||||
MPIconCreated,
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper class to retrieve Icons for Keys. KDB sortes Icons as an Integer
|
||||
* The Helper maps those numbers to icons.
|
||||
* It can furthermore be used to retrieve other Icons, that are non-Database Icons
|
||||
*/
|
||||
@interface MPIconHelper : NSObject
|
||||
|
||||
/*
|
||||
@param type Icon identifier typ MPIconTyp
|
||||
@returns Icon for given identifier
|
||||
/**
|
||||
* Returns the Icon Image for a given type
|
||||
* @param type Icontype
|
||||
* @return Image for the IconType
|
||||
*/
|
||||
+ (NSImage *)icon:(MPIconType)type;
|
||||
/*
|
||||
Available Icons, Use the MPDatabaseIconType to access a individual icon;
|
||||
@returns all availble Icons
|
||||
|
||||
/**
|
||||
* Available Icon names (all)
|
||||
* @return Dictioary with MPIconType keys and NSString values containing their names
|
||||
*/
|
||||
+ (NSDictionary *)availableIconNames;
|
||||
|
||||
+ (NSArray *)availableIcons;
|
||||
|
||||
/*
|
||||
@returns a random Icon image
|
||||
/**
|
||||
* List of all availabel DatabaseIcons as Images. Sorted by IconIndex
|
||||
* @return Array of Icons as NSImage objects
|
||||
*/
|
||||
+ (NSImage *)randomIcon;
|
||||
+ (NSArray *)databaseIcons;
|
||||
|
||||
@end
|
||||
|
||||
@@ -23,10 +23,13 @@ static NSDictionary *icons;
|
||||
return [NSImage imageNamed:NSImageNameActionTemplate];
|
||||
}
|
||||
|
||||
+ (NSArray *)availableIcons {
|
||||
+ (NSArray *)databaseIcons {
|
||||
NSDictionary *imageNames = [MPIconHelper availableIconNames];
|
||||
NSMutableArray *icons = [[NSMutableArray alloc] initWithCapacity:[imageNames count]];
|
||||
for(NSNumber *iconNumber in [imageNames allKeys]) {
|
||||
if([iconNumber integerValue] > MPCustomIconTypeBegin) {
|
||||
continue; // Skip all non-db Keys
|
||||
}
|
||||
MPIconType iconType = (MPIconType)[iconNumber integerValue];
|
||||
[icons addObject:[MPIconHelper icon:iconType]];
|
||||
}
|
||||
@@ -67,16 +70,4 @@ static NSDictionary *icons;
|
||||
};
|
||||
return imageNames;
|
||||
}
|
||||
|
||||
+ (NSImage *)randomIcon {
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
srandom([[NSDate date] timeIntervalSince1970]);
|
||||
});
|
||||
|
||||
NSArray *types = [[MPIconHelper availableIconNames] allKeys];
|
||||
NSUInteger randomIndex = random() % [types count];
|
||||
return [MPIconHelper icon:(MPIconType)randomIndex];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
[self.iconCollectionView setBackgroundColors:@[[NSColor clearColor]]];
|
||||
[self.iconCollectionView setSelectable:YES];
|
||||
[self.iconCollectionView setAllowsMultipleSelection:NO];
|
||||
[self.iconCollectionView setContent:[MPIconHelper availableIcons]];
|
||||
[self.iconCollectionView setContent:[MPIconHelper databaseIcons]];
|
||||
|
||||
}
|
||||
|
||||
|
||||
17
MacPass/MPOutlineMenuDelegate.h
Normal file
17
MacPass/MPOutlineMenuDelegate.h
Normal file
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// MPOutlineMenuDelegate.h
|
||||
// MacPass
|
||||
//
|
||||
// Created by Michael Starke on 29.07.13.
|
||||
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class MPOutlineViewController;
|
||||
|
||||
@interface MPOutlineMenuDelegate : NSObject <NSMenuDelegate>
|
||||
|
||||
@property (weak) MPOutlineViewController *viewController;
|
||||
|
||||
@end
|
||||
114
MacPass/MPOutlineMenuDelegate.m
Normal file
114
MacPass/MPOutlineMenuDelegate.m
Normal file
@@ -0,0 +1,114 @@
|
||||
//
|
||||
// MPOutlineMenuDelegate.m
|
||||
// MacPass
|
||||
//
|
||||
// Created by Michael Starke on 29.07.13.
|
||||
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MPOutlineMenuDelegate.h"
|
||||
#import "MPOutlineViewController.h"
|
||||
|
||||
#import "MPRootAdapter.h"
|
||||
#import "MPDocument.h"
|
||||
|
||||
#import "MPActionHelper.h"
|
||||
#import "MPContextMenuHelper.h"
|
||||
|
||||
#import "Kdb.h"
|
||||
|
||||
NSString *const _MPOutlineMenuDefault = @"Default";
|
||||
NSString *const _MPOutlineMenuTrash = @"Trash";
|
||||
NSString *const _MPOutlineMenuTrashItem = @"TrashItem";
|
||||
NSString *const _MPOutlineMenuRoot = @"Root";
|
||||
NSString *const _MPOutlineMenuTemplate = @"Template";
|
||||
|
||||
@implementation MPOutlineMenuDelegate
|
||||
|
||||
- (void)menuNeedsUpdate:(NSMenu *)menu {
|
||||
/*
|
||||
Scenarios are
|
||||
|
||||
1. Root adapter
|
||||
2. Normal Group
|
||||
3. Template Group
|
||||
4. Trash Group
|
||||
5. Trashed Item
|
||||
*/
|
||||
|
||||
id item = [self.viewController itemUnderMouse];
|
||||
if( [item isKindOfClass:[MPRootAdapter class]]) {
|
||||
[self _updateRootMenu:menu];
|
||||
}
|
||||
|
||||
if( [item isKindOfClass:[KdbGroup class]]) {
|
||||
KdbGroup *group = (KdbGroup *)item;
|
||||
MPDocument *document = [[NSDocumentController sharedDocumentController] currentDocument];
|
||||
if(group && document.trash == group) {
|
||||
[self _updateTrashMenu:menu];
|
||||
}
|
||||
else if([document isItemTrashed:group]) {
|
||||
[self _updateTrashItemMenu:menu];
|
||||
}
|
||||
else {
|
||||
[self _updateDefaultMenu:menu];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_updateRootMenu:(NSMenu *)menu {
|
||||
if([[menu title] isEqualToString:_MPOutlineMenuRoot]) {
|
||||
return; // nothing to do, all fine
|
||||
}
|
||||
[menu removeAllItems];
|
||||
[menu addItemWithTitle:NSLocalizedString(@"CHANGE_DATABASE_NAME", "")
|
||||
action:[MPActionHelper actionOfType:MPActionDatabaseSettings]
|
||||
keyEquivalent:@""];
|
||||
|
||||
[menu setTitle:_MPOutlineMenuRoot];
|
||||
}
|
||||
|
||||
- (void)_updateTrashMenu:(NSMenu *)menu {
|
||||
if([[menu title] isEqualToString:_MPOutlineMenuTrash]) {
|
||||
return; // nothing to do, all fine
|
||||
}
|
||||
[menu removeAllItems];
|
||||
[menu addItemWithTitle:NSLocalizedString(@"CHANGE_TRASH_GROUP", "")
|
||||
action:@selector(editTrashGroup:)
|
||||
keyEquivalent:@""];
|
||||
[menu addItem:[NSMenuItem separatorItem]];
|
||||
[menu addItemWithTitle:NSLocalizedString(@"EMPTY_TRASH", "")
|
||||
action:[MPActionHelper actionOfType:MPActionEmptyTrash]
|
||||
keyEquivalent:@""];
|
||||
|
||||
[menu setTitle:_MPOutlineMenuTrash];
|
||||
}
|
||||
|
||||
- (void)_updateTrashItemMenu:(NSMenu *)menu {
|
||||
if([[menu title] isEqualToString:_MPOutlineMenuTrashItem]) {
|
||||
return; // nothing to do, all fine
|
||||
}
|
||||
[menu removeAllItems];
|
||||
[menu addItemWithTitle:NSLocalizedString(@"DELETE", "")
|
||||
action:[MPActionHelper actionOfType:MPActionDelete]
|
||||
keyEquivalent:@""];
|
||||
[menu addItem:[NSMenuItem separatorItem]];
|
||||
[menu addItemWithTitle:NSLocalizedString(@"EMPTY_TRASH", "")
|
||||
action:[MPActionHelper actionOfType:MPActionEmptyTrash]
|
||||
keyEquivalent:@""];
|
||||
|
||||
[menu setTitle:_MPOutlineMenuTrashItem];
|
||||
}
|
||||
|
||||
|
||||
- (void)_updateDefaultMenu:(NSMenu *)menu {
|
||||
if([[menu title] isEqualToString:_MPOutlineMenuDefault]) {
|
||||
return; // nothing to do, all fine
|
||||
}
|
||||
[menu removeAllItems];
|
||||
for(NSMenuItem *item in [MPContextMenuHelper contextMenuItemsWithItems:MPContextMenuMinimal]) {
|
||||
[menu addItem:item];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -15,7 +15,7 @@ APPKIT_EXTERN NSString *const MPOutlineViewDidChangeGroupSelection;
|
||||
@class HNHGradientView;
|
||||
@class MPDocumentWindowController;
|
||||
|
||||
@interface MPOutlineViewController : MPViewController <NSOutlineViewDelegate>
|
||||
@interface MPOutlineViewController : MPViewController <NSOutlineViewDelegate, NSMenuDelegate>
|
||||
|
||||
|
||||
@property (weak) IBOutlet HNHGradientView *bottomBar;
|
||||
@@ -27,5 +27,10 @@ APPKIT_EXTERN NSString *const MPOutlineViewDidChangeGroupSelection;
|
||||
- (void)createGroup:(id)sender;
|
||||
- (void)createEntry:(id)sender;
|
||||
- (void)deleteNode:(id)sender;
|
||||
/**
|
||||
* Retrieves the current item for the current mouse location
|
||||
* @return Item under mouse. If the mouse isn't inside the view, nil is returned
|
||||
*/
|
||||
- (id)itemUnderMouse;
|
||||
|
||||
@end
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#import "MPUppercaseStringValueTransformer.h"
|
||||
#import "MPRootAdapter.h"
|
||||
#import "MPNotifications.h"
|
||||
#import "MPOutlineMenuDelegate.h"
|
||||
|
||||
#import "KdbLib.h"
|
||||
#import "Kdb4Node.h"
|
||||
@@ -31,6 +32,8 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
|
||||
|
||||
@interface MPOutlineViewController () {
|
||||
BOOL _bindingEstablished;
|
||||
MPOutlineMenuDelegate *_menuDelegate;
|
||||
|
||||
}
|
||||
@property (weak) IBOutlet NSOutlineView *outlineView;
|
||||
@property (weak) IBOutlet NSButton *addGroupButton;
|
||||
@@ -56,6 +59,8 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
|
||||
_bindingEstablished = NO;
|
||||
_datasource = [[MPOutlineDataSource alloc] init];
|
||||
_databaseNameWrapper = NSLocalizedString(@"NEW_DATABASE", "Name for a newly created Database");
|
||||
_menuDelegate = [[MPOutlineMenuDelegate alloc] init];
|
||||
_menuDelegate.viewController = self;
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -138,6 +143,16 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
|
||||
document.selectedItem = document.selectedGroup;
|
||||
}
|
||||
|
||||
- (id)itemUnderMouse {
|
||||
NSPoint mouseLocation = [[self.outlineView window] mouseLocationOutsideOfEventStream];
|
||||
NSPoint localPoint = [self.outlineView convertPoint:mouseLocation fromView:[[self.outlineView window] contentView]];
|
||||
NSInteger row = [self.outlineView rowAtPoint:localPoint];
|
||||
if(row == -1) {
|
||||
return nil; // No row was hit
|
||||
}
|
||||
return [[self.outlineView itemAtRow:row] representedObject];
|
||||
}
|
||||
|
||||
#pragma mark Validation
|
||||
|
||||
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
|
||||
@@ -234,10 +249,7 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
|
||||
|
||||
- (NSMenu *)_contextMenu {
|
||||
NSMenu *menu = [[NSMenu alloc] init];
|
||||
NSArray *items = [MPContextMenuHelper contextMenuItemsWithItems:MPContextMenuMinimal];
|
||||
for(NSMenuItem *item in items) {
|
||||
[menu addItem:item];
|
||||
}
|
||||
[menu setDelegate:_menuDelegate];
|
||||
return menu;
|
||||
}
|
||||
|
||||
|
||||
@@ -84,18 +84,12 @@ NSString *const MPToolbarItemInspector = @"TOOLBAR_INSPECTOR";
|
||||
}
|
||||
else if( [itemIdentifier isEqualToString:MPToolbarItemAddEntry]) {
|
||||
MPContextToolbarButton *button = [[MPContextToolbarButton alloc] initWithFrame:NSMakeRect(0, 0, 32, 32)];
|
||||
[button setAction:[self _actionForToolbarItemIdentifier:itemIdentifier]];
|
||||
NSImage *image = self.toolbarImages[itemIdentifier];
|
||||
[image setSize:NSMakeSize(16, 16)];
|
||||
[button setImage:image];
|
||||
[button sizeToFit];
|
||||
[button setAction:[self _actionForToolbarItemIdentifier:itemIdentifier]];
|
||||
|
||||
NSMenu *menu = [[NSMenu allocWithZone:[NSMenu menuZone]] init];
|
||||
[menu addItemWithTitle:@"Test" action:NULL keyEquivalent:@""];
|
||||
[menu addItemWithTitle:@"More" action:NULL keyEquivalent:@""];
|
||||
[button setMenu:menu];
|
||||
|
||||
|
||||
|
||||
NSRect fittingRect = [button frame];
|
||||
fittingRect.size.width = MAX( (CGFloat)32.0,fittingRect.size.width);
|
||||
[button setFrame:fittingRect];
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user