2012-03-04 15:31:26 +01:00
|
|
|
//
|
2013-04-24 21:23:53 -04:00
|
|
|
// MPMacAppDelegate.m
|
2012-03-04 15:31:26 +01:00
|
|
|
// MasterPassword
|
|
|
|
//
|
|
|
|
// Created by Maarten Billemont on 04/03/12.
|
|
|
|
// Copyright (c) 2012 Lyndir. All rights reserved.
|
|
|
|
//
|
|
|
|
|
2013-04-24 21:23:53 -04:00
|
|
|
#import "MPMacAppDelegate.h"
|
2012-05-13 10:24:19 +02:00
|
|
|
#import "MPAppDelegate_Key.h"
|
|
|
|
#import "MPAppDelegate_Store.h"
|
2012-05-05 00:15:51 +02:00
|
|
|
#import <Carbon/Carbon.h>
|
2012-03-04 15:31:26 +01:00
|
|
|
|
2013-05-19 16:55:43 -04:00
|
|
|
@interface MPMacAppDelegate()
|
|
|
|
|
|
|
|
@property(nonatomic, strong) NSWindowController *appsWindow;
|
|
|
|
@end
|
|
|
|
|
2013-04-24 21:23:53 -04:00
|
|
|
@implementation MPMacAppDelegate
|
2013-04-20 14:11:19 -04:00
|
|
|
|
2012-06-24 16:29:51 +02:00
|
|
|
#pragma clang diagnostic push
|
|
|
|
#pragma clang diagnostic ignored "-Wfour-char-constants"
|
2013-04-20 14:11:19 -04:00
|
|
|
static EventHotKeyID MPShowHotKey = { .signature = 'show', .id = 1 };
|
|
|
|
static EventHotKeyID MPLockHotKey = { .signature = 'lock', .id = 1 };
|
2012-06-24 16:29:51 +02:00
|
|
|
#pragma clang diagnostic pop
|
2012-05-05 00:15:51 +02:00
|
|
|
|
2012-03-06 01:04:19 +01:00
|
|
|
+ (void)initialize {
|
2012-06-08 23:46:13 +02:00
|
|
|
|
2013-01-17 00:37:20 -05:00
|
|
|
static dispatch_once_t initialize;
|
2013-04-20 14:11:19 -04:00
|
|
|
dispatch_once( &initialize, ^{
|
2013-01-17 00:37:20 -05:00
|
|
|
[MPMacConfig get];
|
2012-06-08 23:46:13 +02:00
|
|
|
|
2013-04-20 14:11:19 -04:00
|
|
|
#ifdef DEBUG
|
2013-01-26 22:05:57 -05:00
|
|
|
[PearlLogger get].printLevel = PearlLogLevelDebug;//Trace;
|
2013-04-20 14:11:19 -04:00
|
|
|
#endif
|
|
|
|
} );
|
2012-03-06 01:04:19 +01:00
|
|
|
}
|
|
|
|
|
2012-06-08 23:46:13 +02:00
|
|
|
static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEvent, void *userData) {
|
|
|
|
|
2012-05-05 00:15:51 +02:00
|
|
|
// Extract the hotkey ID.
|
2012-06-08 23:46:13 +02:00
|
|
|
EventHotKeyID hotKeyID;
|
2013-04-20 14:11:19 -04:00
|
|
|
GetEventParameter( theEvent, kEventParamDirectObject, typeEventHotKeyID,
|
|
|
|
NULL, sizeof(hotKeyID), NULL, &hotKeyID );
|
2012-06-08 23:46:13 +02:00
|
|
|
|
2012-05-05 00:15:51 +02:00
|
|
|
// Check which hotkey this was.
|
|
|
|
if (hotKeyID.signature == MPShowHotKey.signature && hotKeyID.id == MPShowHotKey.id) {
|
2013-05-16 00:19:50 -04:00
|
|
|
[((__bridge MPMacAppDelegate *)userData) showPasswordWindow:nil];
|
2012-05-05 00:15:51 +02:00
|
|
|
return noErr;
|
|
|
|
}
|
2013-01-17 00:37:20 -05:00
|
|
|
if (hotKeyID.signature == MPLockHotKey.signature && hotKeyID.id == MPLockHotKey.id) {
|
2013-04-24 21:23:53 -04:00
|
|
|
[((__bridge MPMacAppDelegate *)userData) lock:nil];
|
2013-01-17 00:37:20 -05:00
|
|
|
return noErr;
|
|
|
|
}
|
2012-06-08 23:46:13 +02:00
|
|
|
|
2012-05-05 00:15:51 +02:00
|
|
|
return eventNotHandledErr;
|
|
|
|
}
|
|
|
|
|
2012-10-30 22:54:34 -04:00
|
|
|
- (void)updateUsers {
|
2013-04-20 14:11:19 -04:00
|
|
|
|
2012-10-30 22:54:34 -04:00
|
|
|
[[[self.usersItem submenu] itemArray] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
|
|
|
|
if (idx > 1)
|
2013-01-17 00:37:20 -05:00
|
|
|
[[self.usersItem submenu] removeItem:obj];
|
2012-10-30 22:54:34 -04:00
|
|
|
}];
|
|
|
|
|
2013-04-24 21:23:53 -04:00
|
|
|
NSManagedObjectContext *moc = [MPMacAppDelegate managedObjectContextForThreadIfReady];
|
2012-10-30 22:54:34 -04:00
|
|
|
if (!moc) {
|
2013-01-17 00:37:20 -05:00
|
|
|
self.createUserItem.title = @"New User (Not ready)";
|
|
|
|
self.createUserItem.enabled = NO;
|
2012-11-01 10:55:11 -04:00
|
|
|
self.createUserItem.toolTip = @"Please wait until the app is fully loaded.";
|
2013-01-17 00:37:20 -05:00
|
|
|
[self.usersItem.submenu addItemWithTitle:@"Loading..." action:NULL keyEquivalent:@""].enabled = NO;
|
|
|
|
|
2012-10-30 22:54:34 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-01-17 00:37:20 -05:00
|
|
|
self.createUserItem.title = @"New User";
|
|
|
|
self.createUserItem.enabled = YES;
|
2012-11-01 10:55:11 -04:00
|
|
|
self.createUserItem.toolTip = nil;
|
2013-04-20 14:11:19 -04:00
|
|
|
|
|
|
|
NSError *error = nil;
|
|
|
|
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPUserEntity class] )];
|
|
|
|
fetchRequest.sortDescriptors = @[ [NSSortDescriptor sortDescriptorWithKey:@"lastUsed" ascending:NO] ];
|
|
|
|
NSArray *users = [moc executeFetchRequest:fetchRequest error:&error];
|
2013-01-31 00:42:32 -05:00
|
|
|
if (!users)
|
2013-04-20 14:11:19 -04:00
|
|
|
err(@"Failed to load users: %@", error);
|
|
|
|
|
2013-01-31 00:42:32 -05:00
|
|
|
if (![users count]) {
|
|
|
|
NSMenuItem *noUsersItem = [self.usersItem.submenu addItemWithTitle:@"No users" action:NULL keyEquivalent:@""];
|
|
|
|
noUsersItem.enabled = NO;
|
|
|
|
noUsersItem.toolTip = @"Use the iOS app to create users and make sure iCloud is enabled in its preferences as well. "
|
2013-04-20 14:11:19 -04:00
|
|
|
@"Then give iCloud some time to sync the new user to your Mac.";
|
2013-01-31 00:42:32 -05:00
|
|
|
}
|
2013-04-20 14:11:19 -04:00
|
|
|
|
2013-05-10 11:13:55 -04:00
|
|
|
MPUserEntity *activeUser = self.activeUserForThread;
|
2013-01-31 00:42:32 -05:00
|
|
|
for (MPUserEntity *user in users) {
|
|
|
|
NSMenuItem *userItem = [[NSMenuItem alloc] initWithTitle:user.name action:@selector(selectUser:) keyEquivalent:@""];
|
|
|
|
[userItem setTarget:self];
|
|
|
|
[userItem setRepresentedObject:[user objectID]];
|
|
|
|
[[self.usersItem submenu] addItem:userItem];
|
2013-04-20 14:11:19 -04:00
|
|
|
|
2013-05-10 11:13:55 -04:00
|
|
|
if (!activeUser && [user.name isEqualToString:[MPMacConfig get].usedUserName])
|
2013-01-31 00:42:32 -05:00
|
|
|
[self selectUser:userItem];
|
|
|
|
}
|
2013-05-10 11:13:55 -04:00
|
|
|
|
|
|
|
[self updateMenuItems];
|
2012-10-30 22:54:34 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)selectUser:(NSMenuItem *)item {
|
2013-04-20 14:11:19 -04:00
|
|
|
|
2013-05-07 00:45:06 -04:00
|
|
|
[self signOutAnimated:NO];
|
|
|
|
|
2013-04-23 20:38:56 -04:00
|
|
|
NSError *error = nil;
|
2013-04-24 21:23:53 -04:00
|
|
|
NSManagedObjectContext *moc = [MPMacAppDelegate managedObjectContextForThreadIfReady];
|
2013-04-23 20:38:56 -04:00
|
|
|
self.activeUser = (MPUserEntity *)[moc existingObjectWithID:[item representedObject] error:&error];
|
|
|
|
|
|
|
|
if (error)
|
|
|
|
err(@"While looking up selected user: %@", error);
|
2012-10-30 22:54:34 -04:00
|
|
|
}
|
|
|
|
|
2012-05-05 13:32:09 +02:00
|
|
|
- (void)showMenu {
|
2012-06-08 23:46:13 +02:00
|
|
|
|
2013-01-17 00:37:20 -05:00
|
|
|
[self updateMenuItems];
|
2012-06-08 23:46:13 +02:00
|
|
|
|
2012-05-05 13:32:09 +02:00
|
|
|
[self.statusItem popUpStatusItemMenu:self.statusMenu];
|
|
|
|
}
|
|
|
|
|
2012-05-08 13:41:54 +02:00
|
|
|
- (IBAction)togglePreference:(NSMenuItem *)sender {
|
2012-06-08 23:46:13 +02:00
|
|
|
|
2013-04-24 00:25:51 -04:00
|
|
|
if (sender == self.useICloudItem)
|
2013-05-30 00:16:03 -04:00
|
|
|
[self storeManager].cloudEnabled = !(sender.state == NSOnState);
|
2013-04-24 00:25:51 -04:00
|
|
|
if (sender == self.rememberPasswordItem)
|
2012-10-30 22:54:34 -04:00
|
|
|
[MPConfig get].rememberLogin = [NSNumber numberWithBool:![[MPConfig get].rememberLogin boolValue]];
|
2013-04-24 00:25:51 -04:00
|
|
|
if (sender == self.savePasswordItem) {
|
2013-05-15 22:42:21 -04:00
|
|
|
[MPMacAppDelegate managedObjectContextPerformBlockAndWait:^(NSManagedObjectContext *context) {
|
|
|
|
MPUserEntity *activeUser = [[MPMacAppDelegate get] activeUserInContext:context];
|
|
|
|
if ((activeUser.saveKey = !activeUser.saveKey))
|
|
|
|
[[MPMacAppDelegate get] storeSavedKeyFor:activeUser];
|
|
|
|
else
|
|
|
|
[[MPMacAppDelegate get] forgetSavedKeyFor:activeUser];
|
|
|
|
[context saveToStore];
|
|
|
|
}];
|
2012-11-01 10:55:11 -04:00
|
|
|
}
|
2013-04-24 00:25:51 -04:00
|
|
|
if (sender == self.dialogStyleRegular)
|
|
|
|
[MPMacConfig get].dialogStyleHUD = @NO;
|
|
|
|
if (sender == self.dialogStyleHUD)
|
|
|
|
[MPMacConfig get].dialogStyleHUD = @YES;
|
2012-10-30 22:54:34 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
- (IBAction)newUser:(NSMenuItem *)sender {
|
2013-05-02 20:40:12 -04:00
|
|
|
|
|
|
|
NSAlert *alert = [NSAlert alertWithMessageText:@"New User"
|
|
|
|
defaultButton:@"Create User" alternateButton:nil otherButton:@"Cancel"
|
|
|
|
informativeTextWithFormat:@"To begin, enter your full name.\n\n"
|
|
|
|
@"IMPORTANT: Enter your name correctly, including the right capitalization, "
|
|
|
|
@"as you would on an official document."];
|
|
|
|
NSTextField *nameField = [[NSTextField alloc] initWithFrame:NSMakeRect( 0, 0, 200, 22 )];
|
|
|
|
[alert setAccessoryView:nameField];
|
|
|
|
[alert layout];
|
|
|
|
[nameField becomeFirstResponder];
|
|
|
|
if ([alert runModal] != NSAlertDefaultReturn)
|
|
|
|
return;
|
|
|
|
|
|
|
|
NSString *name = [(NSSecureTextField *)alert.accessoryView stringValue];
|
|
|
|
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *moc) {
|
|
|
|
MPUserEntity *newUser = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass( [MPUserEntity class] )
|
|
|
|
inManagedObjectContext:moc];
|
|
|
|
newUser.name = name;
|
|
|
|
[moc saveToStore];
|
|
|
|
NSError *error = nil;
|
|
|
|
if (![moc obtainPermanentIDsForObjects:@[ newUser ] error:&error])
|
|
|
|
err(@"Failed to obtain permanent object ID for new user: %@", error);
|
|
|
|
|
|
|
|
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
|
|
|
|
[self updateUsers];
|
|
|
|
[self setActiveUser:newUser];
|
2013-05-16 00:19:50 -04:00
|
|
|
[self showPasswordWindow:nil];
|
2013-05-02 20:40:12 -04:00
|
|
|
}];
|
|
|
|
}];
|
2012-10-30 22:54:34 -04:00
|
|
|
}
|
|
|
|
|
2013-01-26 22:05:57 -05:00
|
|
|
- (IBAction)lock:(id)sender {
|
|
|
|
|
|
|
|
self.key = nil;
|
|
|
|
}
|
|
|
|
|
2013-05-10 11:13:55 -04:00
|
|
|
- (IBAction)rebuildCloud:(id)sender {
|
|
|
|
|
|
|
|
if ([[NSAlert alertWithMessageText:@"iCloud Truth Sync" defaultButton:@"Continue"
|
|
|
|
alternateButton:nil otherButton:@"Cancel"
|
|
|
|
informativeTextWithFormat:@"This action will force all your iCloud enabled devices to revert to this device's version of the truth."
|
|
|
|
@"\n\nThis is only necessary if you notice that your devices aren't syncing properly anymore. "
|
|
|
|
"Any data on other devices not available from here will be lost."] runModal] == NSAlertDefaultReturn)
|
|
|
|
[self.storeManager rebuildCloudContentFromCloudStoreOrLocalStore:NO];
|
|
|
|
}
|
|
|
|
|
2013-05-19 16:55:43 -04:00
|
|
|
- (IBAction)terminate:(id)sender {
|
|
|
|
|
|
|
|
[self.passwordWindow close];
|
|
|
|
self.passwordWindow = nil;
|
|
|
|
|
|
|
|
[NSApp terminate:nil];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (IBAction)iphoneAppStore:(id)sender {
|
|
|
|
|
|
|
|
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://itunes.apple.com/app/id510296984"]];
|
|
|
|
|
|
|
|
[self.appWindowDontShow.window close];
|
|
|
|
self.appWindowDontShow = nil;
|
|
|
|
}
|
|
|
|
|
2012-05-10 01:02:55 +02:00
|
|
|
- (void)didUpdateConfigForKey:(SEL)configKey fromValue:(id)oldValue {
|
|
|
|
|
2013-04-20 14:11:19 -04:00
|
|
|
[[NSNotificationCenter defaultCenter]
|
|
|
|
postNotificationName:MPCheckConfigNotification object:NSStringFromSelector( configKey ) userInfo:nil];
|
2012-05-10 01:02:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#pragma mark - NSApplicationDelegate
|
|
|
|
|
2012-03-05 22:19:05 +01:00
|
|
|
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
|
2013-04-24 00:25:51 -04:00
|
|
|
|
2012-05-08 13:41:54 +02:00
|
|
|
// Setup delegates and listeners.
|
|
|
|
[MPConfig get].delegate = self;
|
2013-01-17 00:37:20 -05:00
|
|
|
__weak id weakSelf = self;
|
2012-11-01 10:55:11 -04:00
|
|
|
[self addObserverBlock:^(NSString *keyPath, id object, NSDictionary *change, void *context) {
|
2013-01-17 00:37:20 -05:00
|
|
|
[weakSelf updateMenuItems];
|
2013-04-20 14:11:19 -04:00
|
|
|
} forKeyPath:@"key" options:NSKeyValueObservingOptionInitial context:nil];
|
2013-01-17 00:37:20 -05:00
|
|
|
[self addObserverBlock:^(NSString *keyPath, id object, NSDictionary *change, void *context) {
|
|
|
|
[weakSelf updateMenuItems];
|
2013-04-20 14:11:19 -04:00
|
|
|
} forKeyPath:@"activeUser" options:NSKeyValueObservingOptionInitial context:nil];
|
2012-06-08 23:46:13 +02:00
|
|
|
|
2012-05-05 00:15:51 +02:00
|
|
|
// Status item.
|
2013-04-20 14:11:19 -04:00
|
|
|
self.statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength];
|
|
|
|
self.statusItem.image = [NSImage imageNamed:@"menu-icon"];
|
2013-01-17 00:37:20 -05:00
|
|
|
self.statusItem.highlightMode = YES;
|
2013-04-20 14:11:19 -04:00
|
|
|
self.statusItem.target = self;
|
|
|
|
self.statusItem.action = @selector(showMenu);
|
2012-11-01 10:55:11 -04:00
|
|
|
|
2013-05-11 08:54:49 -04:00
|
|
|
[[NSNotificationCenter defaultCenter] addObserverForName:USMStoreDidChangeNotification object:nil queue:nil usingBlock:
|
2013-04-20 14:11:19 -04:00
|
|
|
^(NSNotification *note) {
|
|
|
|
[self updateUsers];
|
|
|
|
}];
|
|
|
|
[[NSNotificationCenter defaultCenter]
|
2013-05-11 08:54:49 -04:00
|
|
|
addObserverForName:USMStoreDidImportChangesNotification object:nil queue:nil usingBlock:
|
2013-04-20 14:11:19 -04:00
|
|
|
^(NSNotification *note) {
|
|
|
|
[self updateUsers];
|
|
|
|
}];
|
2013-01-31 00:42:32 -05:00
|
|
|
[[NSNotificationCenter defaultCenter] addObserverForName:MPCheckConfigNotification object:nil queue:nil usingBlock:
|
2013-04-20 14:11:19 -04:00
|
|
|
^(NSNotification *note) {
|
|
|
|
self.rememberPasswordItem.state = [[MPConfig get].rememberLogin boolValue]? NSOnState: NSOffState;
|
2013-04-24 21:23:53 -04:00
|
|
|
self.savePasswordItem.state = [[MPMacAppDelegate get] activeUserForThread].saveKey? NSOnState: NSOffState;
|
2013-04-24 00:25:51 -04:00
|
|
|
self.dialogStyleRegular.state = ![[MPMacConfig get].dialogStyleHUD boolValue]? NSOnState: NSOffState;
|
|
|
|
self.dialogStyleHUD.state = [[MPMacConfig get].dialogStyleHUD boolValue]? NSOnState: NSOffState;
|
2013-04-24 21:23:53 -04:00
|
|
|
|
2013-04-24 00:25:51 -04:00
|
|
|
if ([note.object isEqual:NSStringFromSelector( @selector(dialogStyleHUD) )]) {
|
|
|
|
if (![self.passwordWindow.window isVisible])
|
|
|
|
self.passwordWindow = nil;
|
|
|
|
else {
|
|
|
|
[self.passwordWindow close];
|
|
|
|
self.passwordWindow = nil;
|
2013-05-16 00:19:50 -04:00
|
|
|
[self showPasswordWindow:nil];
|
2013-04-24 00:25:51 -04:00
|
|
|
}
|
|
|
|
}
|
2013-04-20 14:11:19 -04:00
|
|
|
}];
|
2012-10-30 22:54:34 -04:00
|
|
|
[self updateUsers];
|
2012-06-08 23:46:13 +02:00
|
|
|
|
2012-05-05 00:15:51 +02:00
|
|
|
// Global hotkey.
|
|
|
|
EventHotKeyRef hotKeyRef;
|
2013-04-20 14:11:19 -04:00
|
|
|
EventTypeSpec hotKeyEvents[1] = { { .eventClass = kEventClassKeyboard, .eventKind = kEventHotKeyPressed } };
|
|
|
|
OSStatus status = InstallApplicationEventHandler(NewEventHandlerUPP( MPHotKeyHander ), GetEventTypeCount( hotKeyEvents ),
|
2013-05-19 16:55:43 -04:00
|
|
|
hotKeyEvents, (__bridge void *)self, NULL);
|
2012-06-08 23:46:13 +02:00
|
|
|
if (status != noErr)
|
|
|
|
err(@"Error installing application event handler: %d", status);
|
2013-04-20 14:11:19 -04:00
|
|
|
status = RegisterEventHotKey( 35 /* p */, controlKey + cmdKey, MPShowHotKey, GetApplicationEventTarget(), 0, &hotKeyRef );
|
2012-06-08 23:46:13 +02:00
|
|
|
if (status != noErr)
|
2013-01-17 00:37:20 -05:00
|
|
|
err(@"Error registering 'show' hotkey: %d", status);
|
2013-04-20 14:11:19 -04:00
|
|
|
status = RegisterEventHotKey( 35 /* p */, controlKey + optionKey + cmdKey, MPLockHotKey, GetApplicationEventTarget(), 0, &hotKeyRef );
|
2013-01-17 00:37:20 -05:00
|
|
|
if (status != noErr)
|
|
|
|
err(@"Error registering 'lock' hotkey: %d", status);
|
2013-05-19 16:55:43 -04:00
|
|
|
|
|
|
|
// iOS App window
|
|
|
|
if ([[MPMacConfig get].showAppWindow boolValue]) {
|
|
|
|
[self.appsWindow = [[NSWindowController alloc] initWithWindowNibName:@"MPAppsWindow" owner:self] showWindow:self];
|
|
|
|
[[NSNotificationCenter defaultCenter] addObserverForName:NSWindowWillCloseNotification object:self.appsWindow.window queue:nil
|
|
|
|
usingBlock:^(NSNotification *note) {
|
|
|
|
[MPMacConfig get].showAppWindow = @(self.appWindowDontShow.state == NSOffState);
|
|
|
|
}];
|
|
|
|
}
|
2013-01-17 00:37:20 -05:00
|
|
|
}
|
|
|
|
|
2013-04-23 20:38:56 -04:00
|
|
|
- (void)setActiveUser:(MPUserEntity *)activeUser {
|
|
|
|
|
2013-04-24 21:23:53 -04:00
|
|
|
BOOL reopenPasswordWindow = [self.passwordWindow.window isVisible];
|
|
|
|
|
|
|
|
if (![[self activeUserForThread].objectID isEqual:activeUser.objectID]) {
|
|
|
|
[self.passwordWindow close];
|
|
|
|
self.passwordWindow = nil;
|
|
|
|
[super setActiveUser:activeUser];
|
|
|
|
}
|
2013-04-23 20:38:56 -04:00
|
|
|
|
|
|
|
[[[self.usersItem submenu] itemArray] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
|
|
|
|
if ([[obj representedObject] isEqual:[activeUser objectID]])
|
|
|
|
[obj setState:NSOnState];
|
|
|
|
else
|
|
|
|
[obj setState:NSOffState];
|
|
|
|
}];
|
|
|
|
|
|
|
|
[MPMacConfig get].usedUserName = activeUser.name;
|
2013-04-24 21:23:53 -04:00
|
|
|
|
|
|
|
if (reopenPasswordWindow)
|
2013-05-16 00:19:50 -04:00
|
|
|
[self showPasswordWindow:nil];
|
2013-04-23 20:38:56 -04:00
|
|
|
}
|
|
|
|
|
2013-01-17 00:37:20 -05:00
|
|
|
- (void)updateMenuItems {
|
|
|
|
|
2013-04-21 17:05:59 -04:00
|
|
|
MPUserEntity *activeUser = [self activeUserForThread];
|
2013-05-16 00:19:50 -04:00
|
|
|
// if (!(self.showItem.enabled = ![self.passwordWindow.window isVisible])) {
|
|
|
|
// self.showItem.title = @"Show (Showing)";
|
|
|
|
// self.showItem.toolTip = @"Master Password is already showing.";
|
|
|
|
// }
|
|
|
|
// else if (!(self.showItem.enabled = (activeUser != nil))) {
|
|
|
|
// self.showItem.title = @"Show (No user)";
|
|
|
|
// self.showItem.toolTip = @"First select the user to show passwords for.";
|
|
|
|
// }
|
|
|
|
// else {
|
|
|
|
// self.showItem.title = @"Show";
|
|
|
|
// self.showItem.toolTip = nil;
|
|
|
|
// }
|
2013-01-17 00:37:20 -05:00
|
|
|
|
|
|
|
if (self.key) {
|
2013-04-20 14:11:19 -04:00
|
|
|
self.lockItem.title = @"Lock";
|
2013-01-17 00:37:20 -05:00
|
|
|
self.lockItem.enabled = YES;
|
|
|
|
self.lockItem.toolTip = nil;
|
2013-04-20 14:11:19 -04:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
self.lockItem.title = @"Lock (Locked)";
|
2013-01-17 00:37:20 -05:00
|
|
|
self.lockItem.enabled = NO;
|
|
|
|
self.lockItem.toolTip = @"Master Password is currently locked.";
|
|
|
|
}
|
|
|
|
|
|
|
|
self.rememberPasswordItem.state = [[MPConfig get].rememberLogin boolValue]? NSOnState: NSOffState;
|
|
|
|
|
2013-04-21 17:05:59 -04:00
|
|
|
self.savePasswordItem.state = activeUser.saveKey? NSOnState: NSOffState;
|
|
|
|
if (!activeUser) {
|
2013-04-20 14:11:19 -04:00
|
|
|
self.savePasswordItem.title = @"Save Password (No user)";
|
2013-01-17 00:37:20 -05:00
|
|
|
self.savePasswordItem.enabled = NO;
|
|
|
|
self.savePasswordItem.toolTip = @"First select your user and unlock by showing the Master Password window.";
|
2013-04-20 14:11:19 -04:00
|
|
|
}
|
|
|
|
else if (!self.key) {
|
|
|
|
self.savePasswordItem.title = @"Save Password (Locked)";
|
2013-01-17 00:37:20 -05:00
|
|
|
self.savePasswordItem.enabled = NO;
|
|
|
|
self.savePasswordItem.toolTip = @"First unlock by showing the Master Password window.";
|
2013-04-20 14:11:19 -04:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
self.savePasswordItem.title = @"Save Password";
|
2013-01-17 00:37:20 -05:00
|
|
|
self.savePasswordItem.enabled = YES;
|
|
|
|
self.savePasswordItem.toolTip = nil;
|
|
|
|
}
|
|
|
|
|
2013-04-21 17:05:59 -04:00
|
|
|
self.useICloudItem.state = self.storeManager.cloudEnabled? NSOnState: NSOffState;
|
2012-03-12 18:14:01 +01:00
|
|
|
}
|
|
|
|
|
2013-05-16 00:19:50 -04:00
|
|
|
- (IBAction)showPasswordWindow:(id)sender {
|
2012-06-08 23:46:13 +02:00
|
|
|
|
2013-05-11 08:54:49 -04:00
|
|
|
// If no user, can't activate.
|
|
|
|
if (![self activeUserForThread])
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Activate the app if not active.
|
|
|
|
if (![[NSApplication sharedApplication] isActive])
|
|
|
|
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
|
|
|
|
|
2013-04-23 20:38:56 -04:00
|
|
|
// Don't show window if we weren't already running (ie. if we haven't been activated before).
|
2013-05-10 11:13:55 -04:00
|
|
|
if (!self.passwordWindow)
|
|
|
|
self.passwordWindow = [[MPPasswordWindowController alloc] initWithWindowNibName:@"MPPasswordWindowController"];
|
|
|
|
|
|
|
|
[self.passwordWindow showWindow:self];
|
2012-05-08 13:41:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)applicationWillResignActive:(NSNotification *)notification {
|
2012-06-08 23:46:13 +02:00
|
|
|
|
2012-10-30 22:54:34 -04:00
|
|
|
if (![[MPConfig get].rememberLogin boolValue])
|
2013-04-24 21:23:53 -04:00
|
|
|
[self lock:nil];
|
2012-05-08 13:41:54 +02:00
|
|
|
}
|
|
|
|
|
2012-06-08 23:46:13 +02:00
|
|
|
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
|
2012-03-04 15:31:26 +01:00
|
|
|
// Save changes in the application's managed object context before the application terminates.
|
2012-06-08 23:46:13 +02:00
|
|
|
|
2013-04-24 21:23:53 -04:00
|
|
|
NSManagedObjectContext *moc = [MPMacAppDelegate managedObjectContextForThreadIfReady];
|
2013-01-31 00:42:32 -05:00
|
|
|
if (!moc)
|
2012-03-04 15:31:26 +01:00
|
|
|
return NSTerminateNow;
|
2012-06-08 23:46:13 +02:00
|
|
|
|
2013-01-31 00:42:32 -05:00
|
|
|
if (![moc commitEditing])
|
2012-03-04 15:31:26 +01:00
|
|
|
return NSTerminateCancel;
|
2012-06-08 23:46:13 +02:00
|
|
|
|
2013-01-31 00:42:32 -05:00
|
|
|
if (![moc hasChanges])
|
2012-03-04 15:31:26 +01:00
|
|
|
return NSTerminateNow;
|
2012-06-08 23:46:13 +02:00
|
|
|
|
2013-04-21 17:05:59 -04:00
|
|
|
[moc saveToStore];
|
2012-03-04 15:31:26 +01:00
|
|
|
return NSTerminateNow;
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|