mirror of
https://github.com/MacPass/MacPass.git
synced 2026-01-31 07:08:17 +00:00
Update KeePassKit (Fixed Group order and Icon issue)
Enhanced database locking to actually encrypt the data although the file is not stored before (so changes might get lost) Changed version handling a bit to make future export/save as possible
This commit is contained in:
Submodule KeePassKit updated: f17f876537...81be5c4921
@@ -13,5 +13,8 @@
|
|||||||
|
|
||||||
FOUNDATION_EXPORT NSString *const MPPasteBoardType;
|
FOUNDATION_EXPORT NSString *const MPPasteBoardType;
|
||||||
FOUNDATION_EXPORT NSString *const MPErrorDomain;
|
FOUNDATION_EXPORT NSString *const MPErrorDomain;
|
||||||
|
FOUNDATION_EXPORT NSString *const MPLegacyDocumentUTI;
|
||||||
|
FOUNDATION_EXPORT NSString *const MPXMLDocumentUTI;
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -10,3 +10,5 @@
|
|||||||
|
|
||||||
NSString *const MPPasteBoardType = @"com.hicknhack.macpass.pasteboard";
|
NSString *const MPPasteBoardType = @"com.hicknhack.macpass.pasteboard";
|
||||||
NSString *const MPErrorDomain = @"com.hicknhack.macpass.error";
|
NSString *const MPErrorDomain = @"com.hicknhack.macpass.error";
|
||||||
|
NSString *const MPLegacyDocumentUTI = @"com.hicknhack.macpass.kdb";
|
||||||
|
NSString *const MPXMLDocumentUTI = @"com.hicknhack.macpass.kdbx";
|
||||||
@@ -7,8 +7,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#import "MPDatabaseVersion.h"
|
#import "KPKVersion.h"
|
||||||
|
|
||||||
|
|
||||||
APPKIT_EXTERN NSString *const MPDocumentDidAddGroupNotification;
|
APPKIT_EXTERN NSString *const MPDocumentDidAddGroupNotification;
|
||||||
APPKIT_EXTERN NSString *const MPDocumentDidRevertNotifiation;
|
APPKIT_EXTERN NSString *const MPDocumentDidRevertNotifiation;
|
||||||
@@ -32,9 +31,7 @@ APPKIT_EXTERN NSString *const MPDocumnetDidChangeCurrentEntryNotification;
|
|||||||
|
|
||||||
/* true, if password and/or keyfile are set */
|
/* true, if password and/or keyfile are set */
|
||||||
@property (assign, readonly) BOOL hasPasswordOrKey;
|
@property (assign, readonly) BOOL hasPasswordOrKey;
|
||||||
/* true, if lock screen is present (no phyiscal locking) */
|
@property (nonatomic, readonly, assign) BOOL encrypted;
|
||||||
@property (assign, nonatomic) BOOL locked;
|
|
||||||
@property (assign, readonly) BOOL decrypted;
|
|
||||||
|
|
||||||
@property (strong, readonly, nonatomic) KPKTree *tree;
|
@property (strong, readonly, nonatomic) KPKTree *tree;
|
||||||
@property (weak, readonly, nonatomic) KPKGroup *root;
|
@property (weak, readonly, nonatomic) KPKGroup *root;
|
||||||
@@ -55,7 +52,7 @@ APPKIT_EXTERN NSString *const MPDocumnetDidChangeCurrentEntryNotification;
|
|||||||
@property (nonatomic, weak) id selectedItem;
|
@property (nonatomic, weak) id selectedItem;
|
||||||
|
|
||||||
|
|
||||||
- (id)initWithVersion:(MPDatabaseVersion)version;
|
+ (KPKVersion)versionForFileType:(NSString *)fileType;
|
||||||
|
|
||||||
#pragma mark Lock/Decrypt
|
#pragma mark Lock/Decrypt
|
||||||
- (void)lockDatabase:(id)sender;
|
- (void)lockDatabase:(id)sender;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#import "MPActionHelper.h"
|
#import "MPActionHelper.h"
|
||||||
#import "MPSettingsHelper.h"
|
#import "MPSettingsHelper.h"
|
||||||
#import "MPNotifications.h"
|
#import "MPNotifications.h"
|
||||||
|
#import "MPConstants.h"
|
||||||
#import "MPSavePanelAccessoryViewController.h"
|
#import "MPSavePanelAccessoryViewController.h"
|
||||||
|
|
||||||
#import "DDXMLNode.h"
|
#import "DDXMLNode.h"
|
||||||
@@ -48,7 +49,6 @@ typedef NS_ENUM(NSUInteger, MPAlertType) {
|
|||||||
@property (weak, nonatomic) KPKGroup *root;
|
@property (weak, nonatomic) KPKGroup *root;
|
||||||
|
|
||||||
@property (assign, nonatomic) BOOL hasPasswordOrKey;
|
@property (assign, nonatomic) BOOL hasPasswordOrKey;
|
||||||
@property (assign) BOOL decrypted;
|
|
||||||
@property (assign) BOOL readOnly;
|
@property (assign) BOOL readOnly;
|
||||||
|
|
||||||
@property (strong) NSURL *lockFileURL;
|
@property (strong) NSURL *lockFileURL;
|
||||||
@@ -62,23 +62,28 @@ typedef NS_ENUM(NSUInteger, MPAlertType) {
|
|||||||
|
|
||||||
@implementation MPDocument
|
@implementation MPDocument
|
||||||
|
|
||||||
|
+ (KPKVersion)versionForFileType:(NSString *)fileType {
|
||||||
|
if( NSOrderedSame == [fileType compare:MPLegacyDocumentUTI options:NSCaseInsensitiveSearch]) {
|
||||||
|
return KPKLegacyVersion;
|
||||||
|
}
|
||||||
|
if( NSOrderedSame == [fileType compare:MPXMLDocumentUTI options:NSCaseInsensitiveSearch]) {
|
||||||
|
return KPKXmlVersion;
|
||||||
|
}
|
||||||
|
return KPKUnknownVersion;
|
||||||
|
}
|
||||||
|
|
||||||
+ (BOOL)autosavesInPlace {
|
+ (BOOL)autosavesInPlace {
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)init {
|
- (id)init {
|
||||||
return [self initWithVersion:MPDatabaseVersion4];
|
|
||||||
}
|
|
||||||
#pragma mark NSDocument essentials
|
|
||||||
- (id)initWithVersion:(MPDatabaseVersion)version {
|
|
||||||
self = [super init];
|
self = [super init];
|
||||||
if(self) {
|
if(self) {
|
||||||
_encryptedData = nil;
|
_encryptedData = nil;
|
||||||
_didLockFile = NO;
|
_didLockFile = NO;
|
||||||
_decrypted = YES;
|
|
||||||
_hasPasswordOrKey = NO;
|
_hasPasswordOrKey = NO;
|
||||||
_locked = NO;
|
|
||||||
_readOnly = NO;
|
_readOnly = NO;
|
||||||
|
[self setFileType:MPXMLDocumentUTI];
|
||||||
self.tree = [KPKTree templateTree];
|
self.tree = [KPKTree templateTree];
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
@@ -99,11 +104,15 @@ typedef NS_ENUM(NSUInteger, MPAlertType) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)writeToURL:(NSURL *)url ofType:(NSString *)typeName error:(NSError **)outError {
|
- (BOOL)writeToURL:(NSURL *)url ofType:(NSString *)typeName error:(NSError **)outError {
|
||||||
/*
|
KPKPassword *password = [[KPKPassword alloc] initWithPassword:self.password key:self.key];
|
||||||
Move this to data:ofType: method with KeePassKit
|
KPKVersion version = [[self class] versionForFileType:(NSString *)typeName];
|
||||||
*/
|
if(version == KPKUnknownVersion) {
|
||||||
KPKPassword *password = nil;
|
if(outError != NULL) {
|
||||||
NSData *treeData = [self.tree encryptWithPassword:password forVersion:KPKXmlVersion error:outError];
|
*outError = [NSError errorWithDomain:MPErrorDomain code:0 userInfo:nil];
|
||||||
|
}
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
NSData *treeData = [self.tree encryptWithPassword:password forVersion:version error:outError];
|
||||||
if([treeData writeToURL:url options:NSDataWritingAtomic error:outError]) {
|
if([treeData writeToURL:url options:NSDataWritingAtomic error:outError]) {
|
||||||
NSLog(@"%@", [*outError localizedDescription]);
|
NSLog(@"%@", [*outError localizedDescription]);
|
||||||
return NO;
|
return NO;
|
||||||
@@ -128,7 +137,6 @@ typedef NS_ENUM(NSUInteger, MPAlertType) {
|
|||||||
*/
|
*/
|
||||||
self.tree = nil;
|
self.tree = nil;
|
||||||
_encryptedData = [NSData dataWithContentsOfURL:url options:NSDataReadingUncached error:outError];
|
_encryptedData = [NSData dataWithContentsOfURL:url options:NSDataReadingUncached error:outError];
|
||||||
self.decrypted = NO;
|
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,7 +150,7 @@ typedef NS_ENUM(NSUInteger, MPAlertType) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)isEntireFileLoaded {
|
- (BOOL)isEntireFileLoaded {
|
||||||
return _decrypted;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)close {
|
- (void)close {
|
||||||
@@ -183,14 +191,11 @@ typedef NS_ENUM(NSUInteger, MPAlertType) {
|
|||||||
|
|
||||||
self.key = keyFileURL;
|
self.key = keyFileURL;
|
||||||
self.password = [password length] > 0 ? password : nil;
|
self.password = [password length] > 0 ? password : nil;
|
||||||
|
|
||||||
NSError *error;
|
NSError *error;
|
||||||
self.tree = [[KPKTree alloc] initWithData:_encryptedData password:passwordData error:&error];
|
self.tree = [[KPKTree alloc] initWithData:_encryptedData password:passwordData error:&error];
|
||||||
if(self.tree) {
|
|
||||||
self.decrypted = YES;
|
return (self.tree != nil);
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
self.decrypted = NO;
|
|
||||||
return NO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)lockDatabase:(id)sender {
|
- (void)lockDatabase:(id)sender {
|
||||||
@@ -199,10 +204,18 @@ typedef NS_ENUM(NSUInteger, MPAlertType) {
|
|||||||
/* Locking needs to be lossless hence just use the XML format */
|
/* Locking needs to be lossless hence just use the XML format */
|
||||||
_encryptedData = [self.tree encryptWithPassword:password forVersion:KPKXmlVersion error:&error];
|
_encryptedData = [self.tree encryptWithPassword:password forVersion:KPKXmlVersion error:&error];
|
||||||
self.tree = nil;
|
self.tree = nil;
|
||||||
self.locked = YES;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark Custom Setter
|
#pragma mark Properties
|
||||||
|
|
||||||
|
- (BOOL)encrypted {
|
||||||
|
return (self.tree == nil);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (KPKGroup *)root {
|
||||||
|
return self.tree.root;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)setPassword:(NSString *)password {
|
- (void)setPassword:(NSString *)password {
|
||||||
if(![_password isEqualToString:password]) {
|
if(![_password isEqualToString:password]) {
|
||||||
_password = [password copy];
|
_password = [password copy];
|
||||||
@@ -237,8 +250,6 @@ typedef NS_ENUM(NSUInteger, MPAlertType) {
|
|||||||
[[NSNotificationCenter defaultCenter] postNotificationName:MPCurrentItemChangedNotification object:self];
|
[[NSNotificationCenter defaultCenter] postNotificationName:MPCurrentItemChangedNotification object:self];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark Data Accesors
|
|
||||||
- (void)setTree:(KPKTree *)tree {
|
- (void)setTree:(KPKTree *)tree {
|
||||||
if(_tree != tree) {
|
if(_tree != tree) {
|
||||||
_tree = tree;
|
_tree = tree;
|
||||||
@@ -246,9 +257,7 @@ typedef NS_ENUM(NSUInteger, MPAlertType) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (KPKGroup *)root {
|
#pragma mark Data Accesors
|
||||||
return self.tree.root;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (KPKEntry *)findEntry:(NSUUID *)uuid {
|
- (KPKEntry *)findEntry:(NSUUID *)uuid {
|
||||||
return [self.root entryForUUID:uuid];
|
return [self.root entryForUUID:uuid];
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#import "MPDocumentWindowDelegate.h"
|
#import "MPDocumentWindowDelegate.h"
|
||||||
|
|
||||||
#import "MPContextToolbarButton.h"
|
#import "MPContextToolbarButton.h"
|
||||||
|
#import "KPKTree.h"
|
||||||
|
|
||||||
@interface MPDocumentWindowController () {
|
@interface MPDocumentWindowController () {
|
||||||
@private
|
@private
|
||||||
@@ -107,7 +108,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
MPDocument *document = [self document];
|
MPDocument *document = [self document];
|
||||||
if(!document.decrypted) {
|
if(document.encrypted) {
|
||||||
[self showPasswordInput];
|
[self showPasswordInput];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -157,6 +158,23 @@
|
|||||||
#pragma mark Actions
|
#pragma mark Actions
|
||||||
- (void)saveDocument:(id)sender {
|
- (void)saveDocument:(id)sender {
|
||||||
MPDocument *document = [self document];
|
MPDocument *document = [self document];
|
||||||
|
NSString *fileType = [document fileType];
|
||||||
|
/* we did open as legacy */
|
||||||
|
if([fileType isEqualToString:MPLegacyDocumentUTI]) {
|
||||||
|
if(document.tree.minimumVersion != KPKLegacyVersion) {
|
||||||
|
NSAlert *alert = [[NSAlert alloc] init];
|
||||||
|
[alert setAlertStyle:NSWarningAlertStyle];
|
||||||
|
[alert setMessageText:NSLocalizedString(@"WARNING_ON_LOSSY_SAVE", "")];
|
||||||
|
[alert setInformativeText:NSLocalizedString(@"WARNING_ON_LOSSY_SAVE_DESCRIPTION", "Informative Text displayed when saving woudl yield data loss")];
|
||||||
|
[alert addButtonWithTitle:NSLocalizedString(@"SAVE", "Save lossy")];
|
||||||
|
[alert addButtonWithTitle:NSLocalizedString(@"CANCEL", "Cancel")];
|
||||||
|
|
||||||
|
[[alert buttons][1] setKeyEquivalent:[NSString stringWithFormat:@"%c", 0x1b]];
|
||||||
|
|
||||||
|
[alert beginSheetModalForWindow:[self window] modalDelegate:nil didEndSelector:NULL contextInfo:NULL];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
if(!document.hasPasswordOrKey) {
|
if(!document.hasPasswordOrKey) {
|
||||||
// warning if no password ist set!
|
// warning if no password ist set!
|
||||||
}
|
}
|
||||||
@@ -180,7 +198,7 @@
|
|||||||
SEL itemAction = [menuItem action];
|
SEL itemAction = [menuItem action];
|
||||||
if(itemAction == @selector(showDatabaseSettings:)
|
if(itemAction == @selector(showDatabaseSettings:)
|
||||||
|| itemAction == @selector(editPassword:)) {
|
|| itemAction == @selector(editPassword:)) {
|
||||||
return document.decrypted && !document.isLocked;
|
return !document.encrypted;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL enabled = YES;
|
BOOL enabled = YES;
|
||||||
@@ -188,13 +206,13 @@
|
|||||||
enabled &= (nil != document.selectedItem) && (document.selectedItem != document.trash);
|
enabled &= (nil != document.selectedItem) && (document.selectedItem != document.trash);
|
||||||
}
|
}
|
||||||
|
|
||||||
enabled &= !( !document.decrypted || document.isLocked || document.isReadOnly );
|
enabled &= !( !document.encrypted || document.isReadOnly );
|
||||||
return enabled;
|
return enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)validateToolbarItem:(NSToolbarItem *)theItem {
|
- (BOOL)validateToolbarItem:(NSToolbarItem *)theItem {
|
||||||
MPDocument *document = [self document];
|
MPDocument *document = [self document];
|
||||||
if(!document.decrypted || document.isLocked || document.isReadOnly) {
|
if(document.encrypted || document.isReadOnly) {
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
MPActionType actionType = [MPActionHelper typeForAction:[theItem action]];
|
MPActionType actionType = [MPActionHelper typeForAction:[theItem action]];
|
||||||
@@ -222,7 +240,7 @@
|
|||||||
|
|
||||||
- (BOOL)validateAction:(SEL)action forItem:(id)item {
|
- (BOOL)validateAction:(SEL)action forItem:(id)item {
|
||||||
MPDocument *document = [self document];
|
MPDocument *document = [self document];
|
||||||
if(!document.decrypted || document.isLocked || document.isReadOnly) {
|
if(document.encrypted || document.isReadOnly) {
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
MPActionType actionType = [MPActionHelper typeForAction:action];
|
MPActionType actionType = [MPActionHelper typeForAction:action];
|
||||||
@@ -281,11 +299,11 @@
|
|||||||
if(!document.hasPasswordOrKey) {
|
if(!document.hasPasswordOrKey) {
|
||||||
return; // Document needs a password/keyfile to be lockable
|
return; // Document needs a password/keyfile to be lockable
|
||||||
}
|
}
|
||||||
if(document.isLocked) {
|
if(document.encrypted) {
|
||||||
return; // Document already locked
|
return; // Document already locked
|
||||||
}
|
}
|
||||||
document.locked = YES;
|
|
||||||
[self showPasswordInput];
|
[self showPasswordInput];
|
||||||
|
[document lockDatabase:sender];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)createGroup:(id)sender {
|
- (void)createGroup:(id)sender {
|
||||||
@@ -372,9 +390,6 @@
|
|||||||
}
|
}
|
||||||
[contentView layoutSubtreeIfNeeded];
|
[contentView layoutSubtreeIfNeeded];
|
||||||
|
|
||||||
MPDocument *document = [self document];
|
|
||||||
document.locked = NO;
|
|
||||||
|
|
||||||
[_entryViewController updateResponderChain];
|
[_entryViewController updateResponderChain];
|
||||||
[_inspectorViewController updateResponderChain];
|
[_inspectorViewController updateResponderChain];
|
||||||
[_outlineViewController updateResponderChain];
|
[_outlineViewController updateResponderChain];
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender {
|
- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender {
|
||||||
|
|
||||||
MPDocument *document = [[[sender draggingDestinationWindow] windowController] document];
|
MPDocument *document = [[[sender draggingDestinationWindow] windowController] document];
|
||||||
if(document.isLocked || !document.decrypted) {
|
if(document.encrypted) {
|
||||||
return NSDragOperationNone;
|
return NSDragOperationNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,19 +60,8 @@
|
|||||||
id windowController = [[[self view] window] windowController];
|
id windowController = [[[self view] window] windowController];
|
||||||
MPDocument *document = [windowController document];
|
MPDocument *document = [windowController document];
|
||||||
if(document) {
|
if(document) {
|
||||||
BOOL isOk = NO;
|
if(![document unlockWithPassword:[self.passwordTextField stringValue]
|
||||||
if(document.decrypted) {
|
keyFileURL:[self.keyPathControl URL]]) {
|
||||||
// TODO: Fix unlocking to actually test
|
|
||||||
BOOL noPassword = !document.password && [[self.passwordTextField stringValue] length] == 0;
|
|
||||||
BOOL passwordOk = [document.password isEqualToString:[self.passwordTextField stringValue]];
|
|
||||||
BOOL noKey = document.key == [self.keyPathControl URL];
|
|
||||||
BOOL keyOk = [document.key isEqualTo:[self.keyPathControl URL]];
|
|
||||||
isOk = (noPassword || passwordOk) && (noKey || keyOk);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
isOk = [document unlockWithPassword:[self.passwordTextField stringValue] keyFileURL:[self.keyPathControl URL]];
|
|
||||||
}
|
|
||||||
if(!isOk) {
|
|
||||||
[self _showError];
|
[self _showError];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -7,12 +7,15 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import "MPViewController.h"
|
#import "MPViewController.h"
|
||||||
|
#import "KPKVersion.h"
|
||||||
|
|
||||||
@class MPDocument;
|
@class MPDocument;
|
||||||
|
|
||||||
@interface MPSavePanelAccessoryViewController : MPViewController
|
@interface MPSavePanelAccessoryViewController : MPViewController
|
||||||
|
|
||||||
@property (nonatomic, assign) NSSavePanel *savePanel;
|
@property (nonatomic, assign) NSSavePanel *savePanel;
|
||||||
@property (nonatomic, assign) MPDocument *document;
|
@property (nonatomic, assign) MPDocument *document;
|
||||||
|
@property (nonatomic, assign, readonly) KPKVersion selectedVersion;
|
||||||
|
|
||||||
@property (nonatomic, weak) IBOutlet NSPopUpButton *fileTypePopupButton;
|
@property (nonatomic, weak) IBOutlet NSPopUpButton *fileTypePopupButton;
|
||||||
@property (nonatomic, weak) IBOutlet NSTextField *infoTextField;
|
@property (nonatomic, weak) IBOutlet NSTextField *infoTextField;
|
||||||
|
|||||||
@@ -8,12 +8,13 @@
|
|||||||
|
|
||||||
#import "MPSavePanelAccessoryViewController.h"
|
#import "MPSavePanelAccessoryViewController.h"
|
||||||
#import "MPDocument.h"
|
#import "MPDocument.h"
|
||||||
|
#import "MPConstants.h"
|
||||||
|
|
||||||
#import "KPKUTIs.h"
|
#import "KPKUTIs.h"
|
||||||
#import "KPKTree.h"
|
#import "KPKTree.h"
|
||||||
|
|
||||||
@interface MPSavePanelAccessoryViewController ()
|
@interface MPSavePanelAccessoryViewController ()
|
||||||
|
@property (readwrite, assign) KPKVersion selectedVersion;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation MPSavePanelAccessoryViewController
|
@implementation MPSavePanelAccessoryViewController
|
||||||
@@ -45,7 +46,13 @@
|
|||||||
|
|
||||||
- (IBAction)setFileType:(id)sender {
|
- (IBAction)setFileType:(id)sender {
|
||||||
NSString *uti = [[self.fileTypePopupButton selectedItem] representedObject];
|
NSString *uti = [[self.fileTypePopupButton selectedItem] representedObject];
|
||||||
BOOL showInfoText = (self.document.tree.minimumVersion == KPKLegacyVersion && [uti isEqualToString:@"com.hicknhack.macpass.kdb"]);
|
if([uti isEqualToString:MPLegacyDocumentUTI]) {
|
||||||
|
self.selectedVersion = KPKLegacyVersion;
|
||||||
|
}
|
||||||
|
else if([uti isEqualToString:MPLegacyDocumentUTI]) {
|
||||||
|
self.selectedVersion = KPKXmlVersion;
|
||||||
|
}
|
||||||
|
BOOL showInfoText = (self.document.tree.minimumVersion == KPKLegacyVersion && [uti isEqualToString:MPLegacyDocumentUTI]);
|
||||||
[self.infoTextField setHidden:!showInfoText];
|
[self.infoTextField setHidden:!showInfoText];
|
||||||
[self.savePanel setAllowedFileTypes:@[uti]];
|
[self.savePanel setAllowedFileTypes:@[uti]];
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user