mirror of
https://github.com/MacPass/MacPass.git
synced 2025-12-18 00:19:23 +00:00
277 lines
9.4 KiB
Objective-C
277 lines
9.4 KiB
Objective-C
//
|
|
// MPDocumentSettingsWindowController.m
|
|
// MacPass
|
|
//
|
|
// Created by Michael Starke on 26.06.13.
|
|
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
|
|
//
|
|
|
|
#import "MPDatabaseSettingsWindowController.h"
|
|
#import "MPDocument.h"
|
|
#import "MPDocumentWindowController.h"
|
|
#import "MPDatabaseVersion.h"
|
|
#import "MPIconHelper.h"
|
|
#import "MPSettingsHelper.h"
|
|
#import "MPNumericalInputFormatter.h"
|
|
|
|
#import "KPKXmlFormat.h"
|
|
#import "KPKGroup.h"
|
|
#import "KPKTree.h"
|
|
#import "KPKMetaData.h"
|
|
#import "KPKNode+IconImage.h"
|
|
#import "KPKCompositeKey.h"
|
|
|
|
#import "HNHRoundedTextField.h"
|
|
#import "HNHRoundedSecureTextField.h"
|
|
|
|
#import "NSString+Empty.h"
|
|
|
|
|
|
@interface MPDatabaseSettingsWindowController () {
|
|
MPDocument *_document;
|
|
NSString *_missingFeature;
|
|
}
|
|
@property (nonatomic,assign) BOOL trashEnabled;
|
|
|
|
@end
|
|
|
|
@implementation MPDatabaseSettingsWindowController
|
|
|
|
- (id)init {
|
|
self = [self initWithDocument:nil];
|
|
return self;
|
|
}
|
|
|
|
- (id)initWithDocument:(MPDocument *)document {
|
|
self = [super initWithWindowNibName:@"DatabaseSettingsWindow"];
|
|
if(self) {
|
|
_document = document;
|
|
_missingFeature = NSLocalizedString(@"KDBX_ONLY_FEATURE", "Feature only available in kdbx databases");
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)windowDidLoad {
|
|
[super windowDidLoad];
|
|
|
|
NSAssert(_document != nil, @"Document needs to be present");
|
|
|
|
[self.sectionTabView setDelegate:self];
|
|
[self.encryptionRoundsTextField setFormatter:[[MPNumericalInputFormatter alloc] init]];
|
|
}
|
|
|
|
#pragma mark Actions
|
|
|
|
- (IBAction)save:(id)sender {
|
|
/* General */
|
|
KPKMetaData *metaData = _document.tree.metaData;
|
|
metaData.databaseDescription = [self.databaseDescriptionTextView string];
|
|
metaData.databaseName = [self.databaseNameTextField stringValue];
|
|
|
|
NSInteger compressionIndex = [self.databaseCompressionPopupButton indexOfSelectedItem];
|
|
if(compressionIndex >= KPKCompressionNone && compressionIndex < KPKCompressionCount) {
|
|
metaData.compressionAlgorithm = compressionIndex;
|
|
}
|
|
NSColor *databaseColor = [self.databaseColorColorWell color];
|
|
if([databaseColor isEqual:[NSColor clearColor]]) {
|
|
metaData.color = nil;
|
|
}
|
|
else {
|
|
metaData.color = databaseColor;
|
|
}
|
|
|
|
/* Advanced */
|
|
metaData.recycleBinEnabled = self.trashEnabled;
|
|
NSMenuItem *trashMenuItem = [self.selectRecycleBinGroupPopUpButton selectedItem];
|
|
KPKGroup *trashGroup = [trashMenuItem representedObject];
|
|
_document.trash = trashGroup;
|
|
|
|
NSMenuItem *templateMenuItem = [self.templateGroupPopUpButton selectedItem];
|
|
KPKGroup *templateGroup = [templateMenuItem representedObject];
|
|
_document.templates = templateGroup;
|
|
|
|
BOOL protectNotes = [self.protectNotesCheckButton state] == NSOnState;
|
|
BOOL protectPassword = [self.protectPasswortCheckButton state] == NSOnState;
|
|
BOOL protectTitle = [self.protectTitleCheckButton state] == NSOnState;
|
|
BOOL protectURL = [self.protectURLCheckButton state] == NSOnState;
|
|
BOOL protectUsername = [self.protectUserNameCheckButton state] == NSOnState;
|
|
|
|
metaData.protectNotes = protectNotes;
|
|
metaData.protectPassword = protectPassword;
|
|
metaData.protectTitle = protectTitle;
|
|
metaData.protectUrl = protectURL;
|
|
metaData.protectUserName = protectUsername;
|
|
metaData.defaultUserName = [self.defaultUsernameTextField stringValue];
|
|
|
|
/*
|
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
|
[defaults setBool:protectNotes forKey:kMPSettingsKeyLegacyHideNotes];
|
|
[defaults setBool:protectPassword forKey:kMPSettingsKeyLegacyHidePassword];
|
|
[defaults setBool:protectTitle forKey:kMPSettingsKeyLegacyHideTitle];
|
|
[defaults setBool:protectURL forKey:kMPSettingsKeyLegacyHideURL];
|
|
[defaults setBool:protectUsername forKey:kMPSettingsKeyLegacyHideUsername];
|
|
[defaults synchronize];
|
|
*/
|
|
[self close:nil];
|
|
}
|
|
|
|
- (IBAction)close:(id)sender {
|
|
[self dismissSheet:0];
|
|
}
|
|
|
|
- (IBAction)benchmarkRounds:(id)sender {
|
|
[self.benchmarkButton setEnabled:NO];
|
|
[KPKCompositeKey benchmarkTransformationRounds:1 completionHandler:^(NSUInteger rounds) {
|
|
[self.encryptionRoundsTextField setIntegerValue:rounds];
|
|
[self.benchmarkButton setEnabled:YES];
|
|
}];
|
|
}
|
|
|
|
- (void)updateView {
|
|
if(!self.isDirty) {
|
|
return;
|
|
}
|
|
/* Update all stuff that might have changed */
|
|
KPKMetaData *metaData = _document.tree.metaData;
|
|
[self _setupDatabaseTab:metaData];
|
|
[self _setupProtectionTab:metaData];
|
|
[self _setupAdvancedTab:_document.tree];
|
|
self.isDirty = NO;
|
|
}
|
|
|
|
- (void)showSettingsTab:(MPDatabaseSettingsTab)tab {
|
|
/*
|
|
We need to make sure the window is loaded
|
|
so we just call the the getter and led the loading commence
|
|
*/
|
|
if(![self window]) {
|
|
return;
|
|
}
|
|
[self.sectionTabView selectTabViewItemAtIndex:tab];
|
|
}
|
|
|
|
#pragma mark NSTableViewDelegate
|
|
- (BOOL)tabView:(NSTabView *)tabView shouldSelectTabViewItem:(NSTabViewItem *)tabViewItem {
|
|
NSUInteger index = [tabView indexOfTabViewItem:tabViewItem];
|
|
switch ((MPDatabaseSettingsTab)index) {
|
|
case MPDatabaseSettingsTabSecurity:
|
|
case MPDatabaseSettingsTabAdvanced:
|
|
case MPDatabaseSettingsTabGeneral:
|
|
return YES;
|
|
|
|
default:
|
|
return NO;
|
|
}
|
|
}
|
|
|
|
#pragma mark Private Helper
|
|
- (void)_setupDatabaseTab:(KPKMetaData *)metaData {
|
|
[self.databaseNameTextField setStringValue:metaData.databaseName];
|
|
[self.databaseDescriptionTextView setString:metaData.databaseDescription];
|
|
[self.databaseCompressionPopupButton selectItemAtIndex:metaData.compressionAlgorithm];
|
|
NSColor *databaseColor = metaData.color ? metaData.color : [NSColor clearColor];
|
|
[self.databaseColorColorWell setColor:databaseColor];
|
|
}
|
|
|
|
- (void)_setupProtectionTab:(KPKMetaData *)metaData {
|
|
[self.protectNotesCheckButton setState:metaData.protectNotes ? NSOnState : NSOffState ];
|
|
[self.protectPasswortCheckButton setState:metaData.protectPassword ? NSOnState : NSOffState];
|
|
[self.protectTitleCheckButton setState:metaData.protectTitle ? NSOnState : NSOffState];
|
|
[self.protectURLCheckButton setState:metaData.protectUrl ? NSOnState : NSOffState];
|
|
[self.protectUserNameCheckButton setState:metaData.protectUserName ? NSOnState : NSOffState];
|
|
[self.encryptionRoundsTextField setIntegerValue:metaData.rounds];
|
|
[self.benchmarkButton setEnabled:YES];
|
|
}
|
|
|
|
- (void)_setupAdvancedTab:(KPKTree *)tree {
|
|
[self bind:@"trashEnabled" toObject:tree.metaData withKeyPath:@"recycleBinEnabled" options:nil];
|
|
[self.enableRecycleBinCheckButton bind:NSValueBinding toObject:self withKeyPath:@"trashEnabled" options:nil];
|
|
[self.selectRecycleBinGroupPopUpButton bind:NSEnabledBinding toObject:self withKeyPath:@"trashEnabled" options:nil];
|
|
[self _updateTrashFolders:tree];
|
|
|
|
[self.defaultUsernameTextField setStringValue:tree.metaData.defaultUserName];
|
|
[self.defaultUsernameTextField setEditable:YES];
|
|
[self _updateTemplateGroup:tree];
|
|
}
|
|
|
|
- (void)_updateFirstResponder {
|
|
NSTabViewItem *selected = [self.sectionTabView selectedTabViewItem];
|
|
MPDatabaseSettingsTab tab = [[self.sectionTabView tabViewItems] indexOfObject:selected];
|
|
|
|
switch(tab) {
|
|
case MPDatabaseSettingsTabAdvanced:
|
|
[[self window] makeFirstResponder:self.defaultUsernameTextField];
|
|
break;
|
|
|
|
case MPDatabaseSettingsTabSecurity:
|
|
[[self window] makeFirstResponder:self.protectTitleCheckButton];
|
|
break;
|
|
|
|
case MPDatabaseSettingsTabGeneral:
|
|
[[self window] makeFirstResponder:self.databaseNameTextField];
|
|
break;
|
|
}
|
|
}
|
|
|
|
- (void)_updateTrashFolders:(KPKTree *)tree {
|
|
NSMenu *menu = [self _buildTrashTreeMenu:tree];
|
|
[self.selectRecycleBinGroupPopUpButton setMenu:menu];
|
|
}
|
|
|
|
- (void)_updateTemplateGroup:(KPKTree *)tree {
|
|
NSMenu *menu = [self _buildTemplateTreeMenu:tree];
|
|
[self.templateGroupPopUpButton setMenu:menu];
|
|
}
|
|
|
|
- (NSMenu *)_buildTrashTreeMenu:(KPKTree *)tree {
|
|
NSMenu *menu = [self _buildTreeMenu:tree preselect:tree.metaData.recycleBinUuid];
|
|
|
|
NSMenuItem *selectItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"AUTOCREATE_TRASH_FOLDER", @"Menu item for automatic trash creation")
|
|
action:NULL
|
|
keyEquivalent:@""];
|
|
[selectItem setEnabled:YES];
|
|
[menu insertItem:selectItem atIndex:0];
|
|
|
|
return menu;
|
|
}
|
|
|
|
- (NSMenu *)_buildTemplateTreeMenu:(KPKTree *)tree {
|
|
NSMenu *menu = [self _buildTreeMenu:tree preselect:tree.metaData.entryTemplatesGroup];
|
|
|
|
NSMenuItem *selectItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"NO_TEMPLATE_GROUP", @"Menu item to reset the template groups")
|
|
action:NULL
|
|
keyEquivalent:@""];
|
|
[selectItem setEnabled:YES];
|
|
[menu insertItem:selectItem atIndex:0];
|
|
|
|
return menu;
|
|
}
|
|
|
|
|
|
- (NSMenu *)_buildTreeMenu:(KPKTree *)tree preselect:(NSUUID *)uuid {
|
|
NSMenu *menu = [[NSMenu alloc] init];
|
|
[menu setAutoenablesItems:NO];
|
|
for(KPKGroup *group in tree.root.groups) {
|
|
[self _insertMenuItemsForGroup:group atLevel:0 inMenu:menu preselect:uuid];
|
|
}
|
|
return menu;
|
|
}
|
|
|
|
- (void)_insertMenuItemsForGroup:(KPKGroup *)group atLevel:(NSUInteger)level inMenu:(NSMenu *)menu preselect:(NSUUID *)uuid{
|
|
NSMenuItem *groupItem = [[NSMenuItem alloc] init];
|
|
[groupItem setImage:group.iconImage];
|
|
[groupItem setTitle:group.name];
|
|
[groupItem setRepresentedObject:group];
|
|
[groupItem setEnabled:YES];
|
|
if(uuid && [group.uuid isEqual:uuid]) {
|
|
[groupItem setState:NSOnState];
|
|
}
|
|
[groupItem setIndentationLevel:level];
|
|
[menu addItem:groupItem];
|
|
for(KPKGroup *childGroup in group.groups) {
|
|
[self _insertMenuItemsForGroup:childGroup atLevel:level + 1 inMenu:menu preselect:uuid];
|
|
}
|
|
}
|
|
|
|
@end
|