mirror of
https://github.com/MacPass/MacPass.git
synced 2025-12-14 18:42:24 +00:00
Refactored key file storing into the document.
This commit is contained in:
@@ -74,7 +74,7 @@
|
|||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="width" constant="165" id="877"/>
|
<constraint firstAttribute="width" constant="165" id="877"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="420">
|
<popUpButtonCell key="cell" type="push" title="after 1 Minute" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" tag="60" imageScaling="proportionallyDown" inset="2" selectedItem="424" id="420">
|
||||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||||
<font key="font" metaFont="menu"/>
|
<font key="font" metaFont="menu"/>
|
||||||
<menu key="menu" title="ClipboardClearInterval" id="421">
|
<menu key="menu" title="ClipboardClearInterval" id="421">
|
||||||
@@ -84,7 +84,7 @@
|
|||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="after 10 Seconds" tag="10" id="422"/>
|
<menuItem title="after 10 Seconds" tag="10" id="422"/>
|
||||||
<menuItem title="after 30 Seconds" tag="30" id="423"/>
|
<menuItem title="after 30 Seconds" tag="30" id="423"/>
|
||||||
<menuItem title="after 1 Minute" tag="60" id="424"/>
|
<menuItem title="after 1 Minute" state="on" tag="60" id="424"/>
|
||||||
</items>
|
</items>
|
||||||
</menu>
|
</menu>
|
||||||
</popUpButtonCell>
|
</popUpButtonCell>
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
<rect key="frame" x="0.0" y="0.0" width="524" height="303"/>
|
<rect key="frame" x="0.0" y="0.0" width="524" height="303"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<button translatesAutoresizingMaskIntoConstraints="NO" id="2">
|
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="2">
|
||||||
<rect key="frame" x="320" y="65" width="83" height="32"/>
|
<rect key="frame" x="320" y="65" width="83" height="32"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<buttonCell key="cell" type="push" title="Unlock" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="3">
|
<buttonCell key="cell" type="push" title="Unlock" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="3">
|
||||||
@@ -111,7 +111,7 @@ DQ
|
|||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
</buttonCell>
|
</buttonCell>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="_clearKey:" target="-2" id="494"/>
|
<action selector="resetKeyFile:" target="-2" id="2Zh-0g-L0i"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
</subviews>
|
</subviews>
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#import "KPKVersion.h"
|
#import "KPKVersion.h"
|
||||||
|
|
||||||
|
APPKIT_EXTERN NSString *const MPDocumentDidChangeStoredKeyFilesSettings;
|
||||||
|
|
||||||
APPKIT_EXTERN NSString *const MPDocumentDidAddGroupNotification;
|
APPKIT_EXTERN NSString *const MPDocumentDidAddGroupNotification;
|
||||||
APPKIT_EXTERN NSString *const MPDocumentDidRevertNotifiation;
|
APPKIT_EXTERN NSString *const MPDocumentDidRevertNotifiation;
|
||||||
|
|
||||||
@@ -55,6 +57,14 @@ APPKIT_EXTERN NSString *const MPDocumentGroupKey;
|
|||||||
#pragma mark Lock/Decrypt
|
#pragma mark Lock/Decrypt
|
||||||
- (void)lockDatabase:(id)sender;
|
- (void)lockDatabase:(id)sender;
|
||||||
- (BOOL)unlockWithPassword:(NSString *)password keyFileURL:(NSURL *)keyFileURL error:(NSError *__autoreleasing*)error;
|
- (BOOL)unlockWithPassword:(NSString *)password keyFileURL:(NSURL *)keyFileURL error:(NSError *__autoreleasing*)error;
|
||||||
|
/**
|
||||||
|
* Returns the suggest key URL for this document. This might be nil.
|
||||||
|
* If the user did disable remeberKeyFiles in the settings, this always returns nil
|
||||||
|
* Otherwise the preferences are searched to locate the last know key url for this document
|
||||||
|
*
|
||||||
|
* @return The suggested key URL if one was found and the settings are allowing suggesting key locations
|
||||||
|
*/
|
||||||
|
- (NSURL *)suggestedKeyURL;
|
||||||
|
|
||||||
#pragma mark Data Lookup
|
#pragma mark Data Lookup
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -26,6 +26,8 @@
|
|||||||
#import "KPKMetaData.h"
|
#import "KPKMetaData.h"
|
||||||
#import "KPKAttribute.h"
|
#import "KPKAttribute.h"
|
||||||
|
|
||||||
|
NSString *const MPDocumentDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDocumentDidChangeStoredKeyFilesSettings";
|
||||||
|
|
||||||
NSString *const MPDocumentDidAddGroupNotification = @"com.hicknhack.macpass.MPDocumentDidAddGroupNotification";
|
NSString *const MPDocumentDidAddGroupNotification = @"com.hicknhack.macpass.MPDocumentDidAddGroupNotification";
|
||||||
NSString *const MPDocumentDidRevertNotifiation = @"com.hicknhack.macpass.MPDocumentDidRevertNotifiation";
|
NSString *const MPDocumentDidRevertNotifiation = @"com.hicknhack.macpass.MPDocumentDidRevertNotifiation";
|
||||||
|
|
||||||
@@ -52,8 +54,8 @@ typedef NS_ENUM(NSUInteger, MPAlertType) {
|
|||||||
@property (weak, nonatomic) KPKGroup *root;
|
@property (weak, nonatomic) KPKGroup *root;
|
||||||
|
|
||||||
@property (assign) BOOL readOnly;
|
@property (assign) BOOL readOnly;
|
||||||
|
|
||||||
@property (strong) NSURL *lockFileURL;
|
@property (strong) NSURL *lockFileURL;
|
||||||
|
@property (nonatomic, assign) BOOL isAllowedToStoreKeyFile;
|
||||||
|
|
||||||
@property (readonly) BOOL useTrash;
|
@property (readonly) BOOL useTrash;
|
||||||
@property (strong) IBOutlet NSView *warningView;
|
@property (strong) IBOutlet NSView *warningView;
|
||||||
@@ -97,12 +99,18 @@ typedef NS_ENUM(NSUInteger, MPAlertType) {
|
|||||||
_encryptedData = nil;
|
_encryptedData = nil;
|
||||||
_didLockFile = NO;
|
_didLockFile = NO;
|
||||||
_readOnly = NO;
|
_readOnly = NO;
|
||||||
|
_isAllowedToStoreKeyFile = NO;
|
||||||
self.tree = [KPKTree templateTree];
|
self.tree = [KPKTree templateTree];
|
||||||
|
[self bind:@"isAllowedToStoreKeyFile"
|
||||||
|
toObject:[NSUserDefaultsController sharedUserDefaultsController]
|
||||||
|
withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyRememberKeyFilesForDatabases]
|
||||||
|
options:nil];
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)dealloc {
|
- (void)dealloc {
|
||||||
|
[self unbind:@"isAllowedToStoreKeyFile"];
|
||||||
[self _cleanupLock];
|
[self _cleanupLock];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,6 +220,13 @@ typedef NS_ENUM(NSUInteger, MPAlertType) {
|
|||||||
|
|
||||||
#pragma mark Lock/Unlock/Decrypt
|
#pragma mark Lock/Unlock/Decrypt
|
||||||
|
|
||||||
|
- (void)lockDatabase:(id)sender {
|
||||||
|
NSError *error;
|
||||||
|
/* Locking needs to be lossless hence just use the XML format */
|
||||||
|
_encryptedData = [self.tree encryptWithPassword:self.compositeKey forVersion:KPKXmlVersion error:&error];
|
||||||
|
self.tree = nil;
|
||||||
|
}
|
||||||
|
|
||||||
- (BOOL)unlockWithPassword:(NSString *)password keyFileURL:(NSURL *)keyFileURL error:(NSError *__autoreleasing*)error{
|
- (BOOL)unlockWithPassword:(NSString *)password keyFileURL:(NSURL *)keyFileURL error:(NSError *__autoreleasing*)error{
|
||||||
self.compositeKey = [[KPKCompositeKey alloc] initWithPassword:password key:keyFileURL];
|
self.compositeKey = [[KPKCompositeKey alloc] initWithPassword:password key:keyFileURL];
|
||||||
self.tree = [[KPKTree alloc] initWithData:_encryptedData password:self.compositeKey error:error];
|
self.tree = [[KPKTree alloc] initWithData:_encryptedData password:self.compositeKey error:error];
|
||||||
@@ -219,6 +234,9 @@ typedef NS_ENUM(NSUInteger, MPAlertType) {
|
|||||||
BOOL isUnlocked = (nil != self.tree);
|
BOOL isUnlocked = (nil != self.tree);
|
||||||
if(isUnlocked) {
|
if(isUnlocked) {
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidUnlockDatabaseNotification object:self];
|
[[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidUnlockDatabaseNotification object:self];
|
||||||
|
if([password length] > 0 && self.isAllowedToStoreKeyFile) {
|
||||||
|
[self _storeKeyURL:keyFileURL];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
self.compositeKey = nil; // clear the key?
|
self.compositeKey = nil; // clear the key?
|
||||||
@@ -226,11 +244,16 @@ typedef NS_ENUM(NSUInteger, MPAlertType) {
|
|||||||
return isUnlocked;
|
return isUnlocked;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)lockDatabase:(id)sender {
|
- (NSURL *)suggestedKeyURL {
|
||||||
NSError *error;
|
if(!self.isAllowedToStoreKeyFile) {
|
||||||
/* Locking needs to be lossless hence just use the XML format */
|
return nil;
|
||||||
_encryptedData = [self.tree encryptWithPassword:self.compositeKey forVersion:KPKXmlVersion error:&error];
|
}
|
||||||
self.tree = nil;
|
NSDictionary *keysForFiles = [[NSUserDefaults standardUserDefaults] dictionaryForKey:kMPSettingsKeyRememeberdKeysForDatabases];
|
||||||
|
NSString *keyPath = keysForFiles[[[self fileURL] path]];
|
||||||
|
if(!keyPath) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
return [NSURL fileURLWithPath:keyPath];
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark Properties
|
#pragma mark Properties
|
||||||
@@ -273,6 +296,17 @@ typedef NS_ENUM(NSUInteger, MPAlertType) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)setIsAllowedToStoreKeyFile:(BOOL)isAllowedToStoreKeyFile {
|
||||||
|
if(_isAllowedToStoreKeyFile != isAllowedToStoreKeyFile) {
|
||||||
|
_isAllowedToStoreKeyFile = isAllowedToStoreKeyFile;
|
||||||
|
if(!self.isAllowedToStoreKeyFile) {
|
||||||
|
[[NSUserDefaults standardUserDefaults] removeObjectForKey:kMPSettingsKeyRememeberdKeysForDatabases];
|
||||||
|
}
|
||||||
|
/* Inform anyone that might be interested that we can now no longer/ or can use keyfiles */
|
||||||
|
[[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidChangeStoredKeyFilesSettings object:self];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark Data Accesors
|
#pragma mark Data Accesors
|
||||||
|
|
||||||
- (KPKEntry *)findEntry:(NSUUID *)uuid {
|
- (KPKEntry *)findEntry:(NSUUID *)uuid {
|
||||||
@@ -474,6 +508,16 @@ typedef NS_ENUM(NSUInteger, MPAlertType) {
|
|||||||
return [super validateUserInterfaceItem:anItem];
|
return [super validateUserInterfaceItem:anItem];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)_storeKeyURL:(NSURL *)keyURL {
|
||||||
|
NSAssert(self.isAllowedToStoreKeyFile, @"We can only store if we are allowed to do so!");
|
||||||
|
NSMutableDictionary *keysForFiles = [[[NSUserDefaults standardUserDefaults] dictionaryForKey:kMPSettingsKeyRememeberdKeysForDatabases] mutableCopy];
|
||||||
|
if(nil == keysForFiles) {
|
||||||
|
keysForFiles = [[NSMutableDictionary alloc] initWithCapacity:1];
|
||||||
|
}
|
||||||
|
keysForFiles[[[self fileURL] path]] = [keyURL path];
|
||||||
|
[[NSUserDefaults standardUserDefaults] setObject:keysForFiles forKey:kMPSettingsKeyRememeberdKeysForDatabases];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)_cleanupLock {
|
- (void)_cleanupLock {
|
||||||
if(_didLockFile) {
|
if(_didLockFile) {
|
||||||
[[NSFileManager defaultManager] removeItemAtURL:_lockFileURL error:nil];
|
[[NSFileManager defaultManager] removeItemAtURL:_lockFileURL error:nil];
|
||||||
|
|||||||
@@ -283,10 +283,6 @@ typedef NS_ENUM(NSUInteger, MPAlertContext) {
|
|||||||
- (void)showPasswordInput {
|
- (void)showPasswordInput {
|
||||||
if(!self.passwordInputController) {
|
if(!self.passwordInputController) {
|
||||||
self.passwordInputController = [[MPPasswordInputController alloc] init];
|
self.passwordInputController = [[MPPasswordInputController alloc] init];
|
||||||
self.passwordInputController.showLastUsedKeyFile = YES;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
self.passwordInputController.showLastUsedKeyFile = NO;
|
|
||||||
}
|
}
|
||||||
[self _setContentViewController:self.passwordInputController];
|
[self _setContentViewController:self.passwordInputController];
|
||||||
[self.passwordInputController requestPassword];
|
[self.passwordInputController requestPassword];
|
||||||
|
|||||||
@@ -10,8 +10,6 @@
|
|||||||
|
|
||||||
@interface MPPasswordInputController : MPViewController
|
@interface MPPasswordInputController : MPViewController
|
||||||
|
|
||||||
@property (nonatomic, assign) BOOL showLastUsedKeyFile;
|
|
||||||
|
|
||||||
- (void)requestPassword;
|
- (void)requestPassword;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -24,12 +24,8 @@
|
|||||||
@property (weak) IBOutlet NSTextField *errorInfoTextField;
|
@property (weak) IBOutlet NSTextField *errorInfoTextField;
|
||||||
@property (weak) IBOutlet NSButton *togglePasswordButton;
|
@property (weak) IBOutlet NSButton *togglePasswordButton;
|
||||||
|
|
||||||
@property (nonatomic, assign) BOOL shouldRememberKeyURL;
|
|
||||||
@property (assign) BOOL showPassword;
|
@property (assign) BOOL showPassword;
|
||||||
|
|
||||||
- (IBAction)_decrypt:(id)sender;
|
|
||||||
- (IBAction)_clearKey:(id)sender;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation MPPasswordInputController
|
@implementation MPPasswordInputController
|
||||||
@@ -42,21 +38,20 @@
|
|||||||
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
|
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
|
||||||
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
|
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
|
||||||
if(self) {
|
if(self) {
|
||||||
_showLastUsedKeyFile = NO;
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_selectKeyURL) name:MPDocumentDidChangeStoredKeyFilesSettings object:nil];
|
||||||
_shouldRememberKeyURL = NO;
|
|
||||||
NSUserDefaultsController *defaultsController = [NSUserDefaultsController sharedUserDefaultsController];
|
|
||||||
[self bind:@"shouldRememberKeyURL" toObject:defaultsController withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyRememberKeyFilesForDatabases ] options:nil];
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)dealloc {
|
||||||
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)didLoadView {
|
- (void)didLoadView {
|
||||||
[self.keyPathControl setDelegate:self.pathControlDelegate];
|
[self.keyPathControl setDelegate:self.pathControlDelegate];
|
||||||
[self.errorImageView setImage:[NSImage imageNamed:NSImageNameCaution]];
|
[self.errorImageView setImage:[NSImage imageNamed:NSImageNameCaution]];
|
||||||
[self.passwordTextField bind:@"showPassword" toObject:self withKeyPath:@"showPassword" options:nil];
|
[self.passwordTextField bind:@"showPassword" toObject:self withKeyPath:@"showPassword" options:nil];
|
||||||
[self.togglePasswordButton bind:NSValueBinding toObject:self withKeyPath:@"showPassword" options:nil];
|
[self.togglePasswordButton bind:NSValueBinding toObject:self withKeyPath:@"showPassword" options:nil];
|
||||||
|
|
||||||
[self _reset];
|
[self _reset];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,20 +62,6 @@
|
|||||||
- (void)requestPassword {
|
- (void)requestPassword {
|
||||||
// show Warnign if read-only mode!
|
// show Warnign if read-only mode!
|
||||||
[self _reset];
|
[self _reset];
|
||||||
if(self.showLastUsedKeyFile) {
|
|
||||||
[self _selectRecentKeyFile];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark Properties
|
|
||||||
- (void)setShouldRememberKeyURL:(BOOL)shouldSelectKeyFile {
|
|
||||||
if(_shouldRememberKeyURL != shouldSelectKeyFile) {
|
|
||||||
_shouldRememberKeyURL = shouldSelectKeyFile;
|
|
||||||
if(!self.shouldRememberKeyURL) {
|
|
||||||
/* Remove any old settings to clean them up */
|
|
||||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:kMPSettingsKeyRememeberdKeysForDatabases];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
@@ -89,53 +70,29 @@
|
|||||||
MPDocument *document = [[self windowController] document];
|
MPDocument *document = [[self windowController] document];
|
||||||
if(document) {
|
if(document) {
|
||||||
NSError *error = nil;
|
NSError *error = nil;
|
||||||
NSURL *keyURL = [self.keyPathControl URL];
|
if(![document unlockWithPassword:[self.passwordTextField stringValue]
|
||||||
if([document unlockWithPassword:[self.passwordTextField stringValue] keyFileURL:keyURL error:&error]) {
|
keyFileURL:[self.keyPathControl URL]
|
||||||
[self _setUsedKeyURL:keyURL forDocument:document];
|
error:&error]) {
|
||||||
}
|
|
||||||
else {
|
|
||||||
[self _showError:error];
|
[self _showError:error];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)_clearKey:(id)sender {
|
- (IBAction)resetKeyFile:(id)sender {
|
||||||
[self.keyPathControl setURL:nil];
|
[self _selectKeyURL];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_reset {
|
- (void)_reset {
|
||||||
self.showPassword = NO;
|
self.showPassword = NO;
|
||||||
[self.passwordTextField setStringValue:@""];
|
[self.passwordTextField setStringValue:@""];
|
||||||
[self.keyPathControl setURL:nil];
|
|
||||||
[self.errorInfoTextField setHidden:YES];
|
[self.errorInfoTextField setHidden:YES];
|
||||||
[self.errorImageView setHidden:YES];
|
[self.errorImageView setHidden:YES];
|
||||||
|
[self resetKeyFile:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_selectRecentKeyFile {
|
- (void)_selectKeyURL {
|
||||||
if(!self.shouldRememberKeyURL) {
|
|
||||||
[self.keyPathControl setURL:nil];
|
|
||||||
return; // If we aren't supposed to preselect paths, clear them!
|
|
||||||
}
|
|
||||||
NSDictionary *keysForFiles = [[NSUserDefaults standardUserDefaults] dictionaryForKey:kMPSettingsKeyRememeberdKeysForDatabases];
|
|
||||||
MPDocument *document = [[self windowController] document];
|
MPDocument *document = [[self windowController] document];
|
||||||
if(document) {
|
[self.keyPathControl setURL:document.suggestedKeyURL];
|
||||||
NSString *keyPath = keysForFiles[[[document fileURL] path]];
|
|
||||||
NSURL *keyURL = keyPath != nil ? [NSURL fileURLWithPath:keyPath] : nil;
|
|
||||||
[self.keyPathControl setURL:keyURL];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_setUsedKeyURL:(NSURL *)keyURL forDocument:(NSDocument *)document {
|
|
||||||
if(!self.shouldRememberKeyURL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
NSMutableDictionary *keysForFiles = [[[NSUserDefaults standardUserDefaults] dictionaryForKey:kMPSettingsKeyRememeberdKeysForDatabases] mutableCopy];
|
|
||||||
if(nil == keysForFiles) {
|
|
||||||
keysForFiles = [[NSMutableDictionary alloc] initWithCapacity:1];
|
|
||||||
}
|
|
||||||
//NSLog(@"remembering keyfile %@ for document %@ at URL %@", keyURL, [document displayName], [document fileURL]);
|
|
||||||
keysForFiles[[[document fileURL] path]] = [keyURL path];
|
|
||||||
[[NSUserDefaults standardUserDefaults] setObject:keysForFiles forKey:kMPSettingsKeyRememeberdKeysForDatabases];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_showError:(NSError *)error {
|
- (void)_showError:(NSError *)error {
|
||||||
|
|||||||
@@ -10,6 +10,17 @@
|
|||||||
|
|
||||||
@interface MPPasteBoardController : NSObject
|
@interface MPPasteBoardController : NSObject
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The PasteBoardController did copy new items to the pasteboard
|
||||||
|
* The userInfo dictionary is empty. You can optain the timeout via the clearTimeout property
|
||||||
|
*/
|
||||||
|
FOUNDATION_EXPORT NSString *const MPPasteBoardControllerDidCopyObjects;
|
||||||
|
/**
|
||||||
|
* The PasteBoardController did clear the clipboard.
|
||||||
|
* The userInfo dictionary is empty
|
||||||
|
*/
|
||||||
|
FOUNDATION_EXPORT NSString *const MPPasteBoardControllerDidClearClipboard;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This time sets the time interval after which a copied entry shoudl be purged from the pasteboard
|
This time sets the time interval after which a copied entry shoudl be purged from the pasteboard
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -9,6 +9,10 @@
|
|||||||
#import "MPPasteBoardController.h"
|
#import "MPPasteBoardController.h"
|
||||||
#import "MPSettingsHelper.h"
|
#import "MPSettingsHelper.h"
|
||||||
|
|
||||||
|
/* Notifications */
|
||||||
|
NSString *const MPPasteBoardControllerDidCopyObjects = @"com.hicknhack.macpass.MPPasteBoardControllerDidCopyObjects";
|
||||||
|
NSString *const MPPasteBoardControllerDidClearClipboard = @"com.hicknhack.macpass.MPPasteBoardControllerDidCopyObjects";
|
||||||
|
|
||||||
@interface MPPasteBoardController ()
|
@interface MPPasteBoardController ()
|
||||||
|
|
||||||
@property (assign) BOOL isEmpty;
|
@property (assign) BOOL isEmpty;
|
||||||
@@ -69,16 +73,21 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)copyObjects:(NSArray *)objects {
|
- (void)copyObjects:(NSArray *)objects {
|
||||||
|
/* Should we save the old content ?*/
|
||||||
[[NSPasteboard generalPasteboard] clearContents];
|
[[NSPasteboard generalPasteboard] clearContents];
|
||||||
[[NSPasteboard generalPasteboard] writeObjects:objects];
|
[[NSPasteboard generalPasteboard] writeObjects:objects];
|
||||||
self.isEmpty = NO;
|
self.isEmpty = NO;
|
||||||
|
if(self.clearTimeout != 0) {
|
||||||
|
[[NSNotificationCenter defaultCenter] postNotificationName:MPPasteBoardControllerDidCopyObjects object:self];
|
||||||
[self performSelector:@selector(_clearPasteboardContents) withObject:nil afterDelay:self.clearTimeout];
|
[self performSelector:@selector(_clearPasteboardContents) withObject:nil afterDelay:self.clearTimeout];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void)_clearPasteboardContents {
|
- (void)_clearPasteboardContents {
|
||||||
/* Only clear stuff we might have put there */
|
/* Only clear stuff we might have put there */
|
||||||
if(!self.isEmpty) {
|
if(!self.isEmpty) {
|
||||||
[[NSPasteboard generalPasteboard] clearContents];
|
[[NSPasteboard generalPasteboard] clearContents];
|
||||||
|
[[NSNotificationCenter defaultCenter] postNotificationName:MPPasteBoardControllerDidClearClipboard object:self];
|
||||||
}
|
}
|
||||||
self.isEmpty = YES;
|
self.isEmpty = YES;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user