Mac support for user handling and iCloud improvements.
[MOVED] Extract user migration out of iOS specific codebase. [UPDATED] iCloud persistence manager. [ADDED] Mac: Hotkey for signing the user out. [IMPROVED] Mac: Menu item handling and usability.
This commit is contained in:
parent
32f870406c
commit
4c19a29897
Binary file not shown.
Binary file not shown.
2
External/iCloudStoreManager
vendored
2
External/iCloudStoreManager
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 8c7894a983f1c1e0795a6e3d5ee7a223a5e01a54
|
Subproject commit 20e2a1dec08fef1e99433f9a8b3a2310bb00717d
|
@ -7,6 +7,8 @@
|
|||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
93D39C24C655D0FD48DCA1C3 /* menu-icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 93D39E6D20434649192464E0 /* menu-icon.png */; };
|
||||||
|
93D39DEE2F9E55DAA206FD6E /* menu-icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 93D39F808A2C83E35C5C0411 /* menu-icon@2x.png */; };
|
||||||
DA34F0CC163B8C31006FFC95 /* NSArray+Indexing.h in Headers */ = {isa = PBXBuildFile; fileRef = DA34F08D163B8C31006FFC95 /* NSArray+Indexing.h */; };
|
DA34F0CC163B8C31006FFC95 /* NSArray+Indexing.h in Headers */ = {isa = PBXBuildFile; fileRef = DA34F08D163B8C31006FFC95 /* NSArray+Indexing.h */; };
|
||||||
DA34F0CD163B8C31006FFC95 /* NSArray+Indexing.m in Sources */ = {isa = PBXBuildFile; fileRef = DA34F08E163B8C31006FFC95 /* NSArray+Indexing.m */; };
|
DA34F0CD163B8C31006FFC95 /* NSArray+Indexing.m in Sources */ = {isa = PBXBuildFile; fileRef = DA34F08E163B8C31006FFC95 /* NSArray+Indexing.m */; };
|
||||||
DA34F0CE163B8C31006FFC95 /* NSBundle+PearlMutableInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = DA34F08F163B8C31006FFC95 /* NSBundle+PearlMutableInfo.h */; };
|
DA34F0CE163B8C31006FFC95 /* NSBundle+PearlMutableInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = DA34F08F163B8C31006FFC95 /* NSBundle+PearlMutableInfo.h */; };
|
||||||
@ -662,6 +664,8 @@
|
|||||||
/* End PBXCopyFilesBuildPhase section */
|
/* End PBXCopyFilesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
|
93D39E6D20434649192464E0 /* menu-icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "menu-icon.png"; sourceTree = "<group>"; };
|
||||||
|
93D39F808A2C83E35C5C0411 /* menu-icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "menu-icon@2x.png"; sourceTree = "<group>"; };
|
||||||
DA34F08D163B8C31006FFC95 /* NSArray+Indexing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+Indexing.h"; sourceTree = "<group>"; };
|
DA34F08D163B8C31006FFC95 /* NSArray+Indexing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+Indexing.h"; sourceTree = "<group>"; };
|
||||||
DA34F08E163B8C31006FFC95 /* NSArray+Indexing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+Indexing.m"; sourceTree = "<group>"; };
|
DA34F08E163B8C31006FFC95 /* NSArray+Indexing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+Indexing.m"; sourceTree = "<group>"; };
|
||||||
DA34F08F163B8C31006FFC95 /* NSBundle+PearlMutableInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSBundle+PearlMutableInfo.h"; sourceTree = "<group>"; };
|
DA34F08F163B8C31006FFC95 /* NSBundle+PearlMutableInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSBundle+PearlMutableInfo.h"; sourceTree = "<group>"; };
|
||||||
@ -2565,6 +2569,8 @@
|
|||||||
DA600E9615057F10008E9AB6 /* Lock */,
|
DA600E9615057F10008E9AB6 /* Lock */,
|
||||||
DA600EA015057F10008E9AB6 /* logo-bare.png */,
|
DA600EA015057F10008E9AB6 /* logo-bare.png */,
|
||||||
DA600EA115057F10008E9AB6 /* Tooltips */,
|
DA600EA115057F10008E9AB6 /* Tooltips */,
|
||||||
|
93D39E6D20434649192464E0 /* menu-icon.png */,
|
||||||
|
93D39F808A2C83E35C5C0411 /* menu-icon@2x.png */,
|
||||||
);
|
);
|
||||||
path = Resources;
|
path = Resources;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -5719,6 +5725,8 @@
|
|||||||
DAF236BA163B24D5008AF5B5 /* MainMenu.xib in Resources */,
|
DAF236BA163B24D5008AF5B5 /* MainMenu.xib in Resources */,
|
||||||
DAF236BD163B24D5008AF5B5 /* MasterPassword.entitlements in Resources */,
|
DAF236BD163B24D5008AF5B5 /* MasterPassword.entitlements in Resources */,
|
||||||
DAF236C0163B24D5008AF5B5 /* MPPasswordWindowController.xib in Resources */,
|
DAF236C0163B24D5008AF5B5 /* MPPasswordWindowController.xib in Resources */,
|
||||||
|
93D39C24C655D0FD48DCA1C3 /* menu-icon.png in Resources */,
|
||||||
|
93D39DEE2F9E55DAA206FD6E /* menu-icon@2x.png in Resources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@ -5935,7 +5943,7 @@
|
|||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
LD_DYLIB_INSTALL_NAME = "@rpath/$(EXECUTABLE_PATH)";
|
LD_DYLIB_INSTALL_NAME = "@rpath/$(EXECUTABLE_PATH)";
|
||||||
LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks";
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE = "";
|
PROVISIONING_PROFILE = "";
|
||||||
@ -5994,7 +6002,7 @@
|
|||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
LD_DYLIB_INSTALL_NAME = "@rpath/$(EXECUTABLE_PATH)";
|
LD_DYLIB_INSTALL_NAME = "@rpath/$(EXECUTABLE_PATH)";
|
||||||
LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks";
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE = "";
|
PROVISIONING_PROFILE = "";
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
|
@ -56,12 +56,6 @@
|
|||||||
ReferencedContainer = "container:MasterPassword-Mac.xcodeproj">
|
ReferencedContainer = "container:MasterPassword-Mac.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</BuildableProductRunnable>
|
</BuildableProductRunnable>
|
||||||
<CommandLineArguments>
|
|
||||||
<CommandLineArgument
|
|
||||||
argument = "-com.apple.coredata.ubiquity.logLevel 3"
|
|
||||||
isEnabled = "NO">
|
|
||||||
</CommandLineArgument>
|
|
||||||
</CommandLineArguments>
|
|
||||||
<AdditionalOptions>
|
<AdditionalOptions>
|
||||||
</AdditionalOptions>
|
</AdditionalOptions>
|
||||||
</LaunchAction>
|
</LaunchAction>
|
||||||
|
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.2 MiB |
Binary file not shown.
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 37 KiB |
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
@required
|
@required
|
||||||
- (NSUInteger)version;
|
- (NSUInteger)version;
|
||||||
|
- (void)migrateUser:(MPUserEntity *)user completion:(void(^)(BOOL userRequiresNewMigration))completion;
|
||||||
- (BOOL)migrateElement:(MPElementEntity *)element explicit:(BOOL)explicit;
|
- (BOOL)migrateElement:(MPElementEntity *)element explicit:(BOOL)explicit;
|
||||||
|
|
||||||
- (MPKey *)keyForPassword:(NSString *)password ofUserNamed:(NSString *)userName;
|
- (MPKey *)keyForPassword:(NSString *)password ofUserNamed:(NSString *)userName;
|
||||||
|
@ -31,6 +31,31 @@
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)migrateUser:(MPUserEntity *)user completion:(void(^)(BOOL userRequiresNewMigration))completion {
|
||||||
|
|
||||||
|
BOOL didRequireExplicitMigration = user.requiresExplicitMigration;
|
||||||
|
[user.managedObjectContext performBlock:^void() {
|
||||||
|
NSError *error = nil;
|
||||||
|
NSFetchRequest *migrationRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass([MPElementEntity class])];
|
||||||
|
migrationRequest.predicate = [NSPredicate predicateWithFormat:@"version_ < %d", MPAlgorithmDefaultVersion];
|
||||||
|
NSArray *migrationElements = [user.managedObjectContext executeFetchRequest:migrationRequest error:&error];
|
||||||
|
if (!migrationElements) {
|
||||||
|
err(@"While looking for elements to migrate: %@", error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (didRequireExplicitMigration)
|
||||||
|
user.requiresExplicitMigration = NO;
|
||||||
|
for (MPElementEntity *migrationElement in migrationElements)
|
||||||
|
if (![migrationElement migrateExplicitly:NO])
|
||||||
|
user.requiresExplicitMigration = YES;
|
||||||
|
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
completion(!didRequireExplicitMigration && user.requiresExplicitMigration);
|
||||||
|
});
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
- (BOOL)migrateElement:(MPElementEntity *)element explicit:(BOOL)explicit {
|
- (BOOL)migrateElement:(MPElementEntity *)element explicit:(BOOL)explicit {
|
||||||
|
|
||||||
if (element.version != [self version] - 1)
|
if (element.version != [self version] - 1)
|
||||||
|
@ -20,6 +20,4 @@
|
|||||||
|
|
||||||
+ (MPAppDelegate_Shared *)get;
|
+ (MPAppDelegate_Shared *)get;
|
||||||
|
|
||||||
- (NSURL *)applicationFilesDirectory;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -28,23 +28,6 @@
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSURL *)applicationFilesDirectory {
|
|
||||||
|
|
||||||
#if TARGET_OS_IPHONE
|
|
||||||
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
|
|
||||||
#else
|
|
||||||
NSURL *appSupportURL = [[[NSFileManager defaultManager] URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask] lastObject];
|
|
||||||
NSURL *applicationFilesDirectory = [appSupportURL URLByAppendingPathComponent:@"com.lyndir.lhunath.MasterPassword"];
|
|
||||||
|
|
||||||
NSError *error = nil;
|
|
||||||
[[NSFileManager defaultManager] createDirectoryAtURL:applicationFilesDirectory withIntermediateDirectories:YES attributes:nil error:&error];
|
|
||||||
if (error)
|
|
||||||
err(@"Couldn't create application directory: %@, error occurred: %@", applicationFilesDirectory, error);
|
|
||||||
|
|
||||||
return applicationFilesDirectory;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
- (MPUserEntity *)activeUser {
|
- (MPUserEntity *)activeUser {
|
||||||
|
|
||||||
if (!self.activeUserID)
|
if (!self.activeUserID)
|
||||||
|
@ -21,9 +21,7 @@ typedef enum {
|
|||||||
@interface MPAppDelegate_Shared (Store)<UbiquityStoreManagerDelegate>
|
@interface MPAppDelegate_Shared (Store)<UbiquityStoreManagerDelegate>
|
||||||
|
|
||||||
+ (NSManagedObjectContext *)managedObjectContextIfReady;
|
+ (NSManagedObjectContext *)managedObjectContextIfReady;
|
||||||
+ (NSManagedObjectModel *)managedObjectModel;
|
|
||||||
- (NSManagedObjectContext *)managedObjectContextIfReady;
|
- (NSManagedObjectContext *)managedObjectContextIfReady;
|
||||||
- (NSManagedObjectModel *)managedObjectModel;
|
|
||||||
|
|
||||||
- (UbiquityStoreManager *)storeManager;
|
- (UbiquityStoreManager *)storeManager;
|
||||||
- (void)saveContext;
|
- (void)saveContext;
|
||||||
|
@ -6,10 +6,15 @@
|
|||||||
// Copyright (c) 2011 Lyndir. All rights reserved.
|
// Copyright (c) 2011 Lyndir. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#import <objc/runtime.h>
|
||||||
#import "MPAppDelegate_Store.h"
|
#import "MPAppDelegate_Store.h"
|
||||||
|
#import
|
||||||
|
#import
|
||||||
|
|
||||||
@implementation MPAppDelegate_Shared (Store)
|
@implementation MPAppDelegate_Shared (Store)
|
||||||
|
|
||||||
|
static char managedObjectContextKey;
|
||||||
|
|
||||||
#pragma mark - Core Data setup
|
#pragma mark - Core Data setup
|
||||||
|
|
||||||
+ (NSManagedObjectContext *)managedObjectContextIfReady {
|
+ (NSManagedObjectContext *)managedObjectContextIfReady {
|
||||||
@ -17,37 +22,21 @@
|
|||||||
return [[self get] managedObjectContextIfReady];
|
return [[self get] managedObjectContextIfReady];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSManagedObjectModel *)managedObjectModel {
|
|
||||||
|
|
||||||
return [[self get] managedObjectModel];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSManagedObjectModel *)managedObjectModel {
|
|
||||||
|
|
||||||
static NSManagedObjectModel *managedObjectModel = nil;
|
|
||||||
if (managedObjectModel)
|
|
||||||
return managedObjectModel;
|
|
||||||
|
|
||||||
return managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSManagedObjectContext *)managedObjectContextIfReady {
|
- (NSManagedObjectContext *)managedObjectContextIfReady {
|
||||||
|
|
||||||
if (![self storeManager].isReady)
|
NSManagedObjectContext *managedObjectContext = objc_getAssociatedObject(self, &managedObjectContextKey);
|
||||||
return nil;
|
|
||||||
|
|
||||||
static NSManagedObjectContext *managedObjectContext = nil;
|
|
||||||
if (!managedObjectContext) {
|
if (!managedObjectContext) {
|
||||||
managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
|
managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
|
||||||
[managedObjectContext performBlockAndWait:^{
|
[managedObjectContext performBlockAndWait:^{
|
||||||
managedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
|
managedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
|
||||||
managedObjectContext.undoManager = [NSUndoManager new];
|
|
||||||
managedObjectContext.persistentStoreCoordinator = self.storeManager.persistentStoreCoordinator;
|
managedObjectContext.persistentStoreCoordinator = self.storeManager.persistentStoreCoordinator;
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
objc_setAssociatedObject(self, &managedObjectContextKey, managedObjectContext, OBJC_ASSOCIATION_RETAIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[self storeManager] persistentStoreCoordinator];
|
if (![managedObjectContext.persistentStoreCoordinator.persistentStores count])
|
||||||
if (![self storeManager].isReady)
|
// Store not available yet.
|
||||||
return nil;
|
return nil;
|
||||||
|
|
||||||
return managedObjectContext;
|
return managedObjectContext;
|
||||||
@ -59,34 +48,86 @@
|
|||||||
if (storeManager)
|
if (storeManager)
|
||||||
return storeManager;
|
return storeManager;
|
||||||
|
|
||||||
storeManager = [[UbiquityStoreManager alloc] initWithManagedObjectModel:[self managedObjectModel]
|
storeManager = [[UbiquityStoreManager alloc] initStoreNamed:nil withManagedObjectModel:nil localStoreURL:nil
|
||||||
localStoreURL:[[self applicationFilesDirectory] URLByAppendingPathComponent:@"MasterPassword.sqlite"]
|
containerIdentifier:@"HL3Q45LX9N.com.lyndir.lhunath.MasterPassword.shared"
|
||||||
containerIdentifier:@"HL3Q45LX9N.com.lyndir.lhunath.MasterPassword.shared"
|
|
||||||
#if TARGET_OS_IPHONE
|
#if TARGET_OS_IPHONE
|
||||||
additionalStoreOptions:@{
|
additionalStoreOptions:@{
|
||||||
NSPersistentStoreFileProtectionKey: NSFileProtectionComplete
|
NSPersistentStoreFileProtectionKey : NSFileProtectionComplete
|
||||||
}
|
}];
|
||||||
#else
|
#else
|
||||||
additionalStoreOptions:nil
|
additionalStoreOptions:nil];
|
||||||
#endif
|
#endif
|
||||||
];
|
|
||||||
storeManager.delegate = self;
|
storeManager.delegate = self;
|
||||||
#ifdef DEBUG
|
|
||||||
storeManager.hardResetEnabled = YES;
|
// Migrate old store to new store location.
|
||||||
#endif
|
NSNumber *cloudEnabled = [[NSUserDefaults standardUserDefaults] objectForKey:@"iCloudEnabledKey"];
|
||||||
#if TARGET_OS_IPHONE
|
if (cloudEnabled) {
|
||||||
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillEnterForegroundNotification
|
if ([cloudEnabled boolValue]) {
|
||||||
object:[UIApplication sharedApplication] queue:nil
|
NSString *uuid = [[NSUserDefaults standardUserDefaults] stringForKey:@"LocalUUIDKey"];
|
||||||
|
NSURL *cloudContainerURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:@"HL3Q45LX9N.com.lyndir.lhunath.MasterPassword.shared"];
|
||||||
|
NSURL *oldCloudContentURL = [[cloudContainerURL URLByAppendingPathComponent:@"Data" isDirectory:YES]
|
||||||
|
URLByAppendingPathComponent:uuid isDirectory:YES];
|
||||||
|
NSURL *oldCloudStoreURL = [[[cloudContainerURL URLByAppendingPathComponent:@"Database.nosync" isDirectory:YES]
|
||||||
|
URLByAppendingPathComponent:uuid isDirectory:NO]
|
||||||
|
URLByAppendingPathExtension:@"sqlite"];
|
||||||
|
NSURL *newCloudContentURL = [storeManager URLForCloudContent];
|
||||||
|
NSURL *newCloudStoreURL = [storeManager URLForCloudStore];
|
||||||
|
|
||||||
|
if ([[NSFileManager defaultManager] fileExistsAtPath:oldCloudStoreURL.path isDirectory:NO] &&
|
||||||
|
![[NSFileManager defaultManager] fileExistsAtPath:newCloudStoreURL.path isDirectory:NO]) {
|
||||||
|
NSError *error = nil;
|
||||||
|
NSDictionary *options = @{
|
||||||
|
NSPersistentStoreUbiquitousContentNameKey : uuid,
|
||||||
|
NSPersistentStoreUbiquitousContentURLKey : oldCloudContentURL,
|
||||||
|
NSMigratePersistentStoresAutomaticallyOption : @YES,
|
||||||
|
NSInferMappingModelAutomaticallyOption : @YES};
|
||||||
|
NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];
|
||||||
|
NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
|
||||||
|
NSPersistentStore *oldStore = [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil
|
||||||
|
URL:oldCloudStoreURL options:options error:&error];
|
||||||
|
if (oldStore)
|
||||||
|
[psc migratePersistentStore:oldStore toURL:newCloudStoreURL options:options withType:NSSQLiteStoreType error:&error];
|
||||||
|
if (error)
|
||||||
|
err(@"While migrating cloud store from %@ -> %@: %@", oldCloudStoreURL, newCloudStoreURL, error);
|
||||||
|
else {
|
||||||
|
[psc removePersistentStore:[psc.persistentStores lastObject] error:nil];
|
||||||
|
[[NSFileManager defaultManager] removeItemAtURL:oldCloudStoreURL error:nil];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
NSURL *applicationFilesDirectory = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory
|
||||||
|
inDomains:NSUserDomainMask] lastObject];
|
||||||
|
NSURL *oldLocalStoreURL = [[applicationFilesDirectory URLByAppendingPathComponent:@"MasterPassword" isDirectory:NO]
|
||||||
|
URLByAppendingPathExtension:@"sqlite"];
|
||||||
|
NSURL *newLocalStoreURL = [storeManager URLForLocalStore];
|
||||||
|
if ([[NSFileManager defaultManager] fileExistsAtPath:oldLocalStoreURL.path isDirectory:NO] &&
|
||||||
|
![[NSFileManager defaultManager] fileExistsAtPath:newLocalStoreURL.path isDirectory:NO]) {
|
||||||
|
NSError *error = nil;
|
||||||
|
NSDictionary *options = @{
|
||||||
|
NSMigratePersistentStoresAutomaticallyOption : @YES,
|
||||||
|
NSInferMappingModelAutomaticallyOption : @YES};
|
||||||
|
NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];
|
||||||
|
NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
|
||||||
|
NSPersistentStore *oldStore = [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil
|
||||||
|
URL:oldLocalStoreURL options:options error:&error];
|
||||||
|
if (oldStore)
|
||||||
|
[psc migratePersistentStore:oldStore toURL:newLocalStoreURL options:options withType:NSSQLiteStoreType error:&error];
|
||||||
|
if (error)
|
||||||
|
err(@"While migrating local store from %@ -> %@: %@", oldLocalStoreURL, newLocalStoreURL, error);
|
||||||
|
else {
|
||||||
|
[psc removePersistentStore:[psc.persistentStores lastObject] error:nil];
|
||||||
|
[[NSFileManager defaultManager] removeItemAtURL:oldLocalStoreURL error:nil];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"iCloudEnabledKey"];
|
||||||
|
|
||||||
|
[[NSNotificationCenter defaultCenter] addObserverForName:UbiquityManagedStoreDidChangeNotification
|
||||||
|
object:storeManager queue:nil
|
||||||
usingBlock:^(NSNotification *note) {
|
usingBlock:^(NSNotification *note) {
|
||||||
[storeManager checkiCloudStatus];
|
objc_setAssociatedObject(self, &managedObjectContextKey, nil, OBJC_ASSOCIATION_RETAIN);
|
||||||
}];
|
}];
|
||||||
#else
|
|
||||||
[[NSNotificationCenter defaultCenter] addObserverForName:NSApplicationWillBecomeActiveNotification
|
|
||||||
object:[NSApplication sharedApplication] queue:nil
|
|
||||||
usingBlock:^(NSNotification *note) {
|
|
||||||
[storeManager checkiCloudStatus];
|
|
||||||
}];
|
|
||||||
#endif
|
|
||||||
#if TARGET_OS_IPHONE
|
#if TARGET_OS_IPHONE
|
||||||
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillTerminateNotification
|
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillTerminateNotification
|
||||||
object:[UIApplication sharedApplication] queue:nil
|
object:[UIApplication sharedApplication] queue:nil
|
||||||
@ -128,16 +169,16 @@
|
|||||||
|
|
||||||
- (void)ubiquityStoreManager:(UbiquityStoreManager *)manager didSwitchToiCloud:(BOOL)iCloudEnabled {
|
- (void)ubiquityStoreManager:(UbiquityStoreManager *)manager didSwitchToiCloud:(BOOL)iCloudEnabled {
|
||||||
|
|
||||||
// manager.iCloudEnabled is more reliable (eg. iOS' MPAppDelegate tampers with didSwitch a bit)
|
// manager.cloudEnabled is more reliable (eg. iOS' MPAppDelegate tampers with didSwitch a bit)
|
||||||
iCloudEnabled = manager.iCloudEnabled;
|
iCloudEnabled = manager.cloudEnabled;
|
||||||
inf(@"Using iCloud? %@", iCloudEnabled? @"YES": @"NO");
|
inf(@"Using iCloud? %@", iCloudEnabled? @"YES": @"NO");
|
||||||
|
|
||||||
#ifdef TESTFLIGHT_SDK_VERSION
|
#ifdef TESTFLIGHT_SDK_VERSION
|
||||||
[TestFlight passCheckpoint:iCloudEnabled? MPCheckpointCloudEnabled: MPCheckpointCloudDisabled];
|
[TestFlight passCheckpoint:cloudEnabled? MPCheckpointCloudEnabled: MPCheckpointCloudDisabled];
|
||||||
#endif
|
#endif
|
||||||
#ifdef LOCALYTICS
|
#ifdef LOCALYTICS
|
||||||
[[LocalyticsSession sharedLocalyticsSession] tagEvent:MPCheckpointCloud attributes:@{
|
[[LocalyticsSession sharedLocalyticsSession] tagEvent:MPCheckpointCloud attributes:@{
|
||||||
@"enabled": iCloudEnabled? @"YES": @"NO"
|
@"enabled": cloudEnabled? @"YES": @"NO"
|
||||||
}];
|
}];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -162,7 +203,6 @@
|
|||||||
|
|
||||||
switch (cause) {
|
switch (cause) {
|
||||||
case UbiquityStoreManagerErrorCauseDeleteStore:
|
case UbiquityStoreManagerErrorCauseDeleteStore:
|
||||||
case UbiquityStoreManagerErrorCauseDeleteLogs:
|
|
||||||
case UbiquityStoreManagerErrorCauseCreateStorePath:
|
case UbiquityStoreManagerErrorCauseCreateStorePath:
|
||||||
case UbiquityStoreManagerErrorCauseClearStore:
|
case UbiquityStoreManagerErrorCauseClearStore:
|
||||||
break;
|
break;
|
||||||
@ -178,13 +218,12 @@
|
|||||||
#ifdef LOCALYTICS
|
#ifdef LOCALYTICS
|
||||||
[[LocalyticsSession sharedLocalyticsSession] tagEvent:MPCheckpointLocalStoreReset attributes:nil];
|
[[LocalyticsSession sharedLocalyticsSession] tagEvent:MPCheckpointLocalStoreReset attributes:nil];
|
||||||
#endif
|
#endif
|
||||||
manager.hardResetEnabled = YES;
|
[manager deleteLocalStore];
|
||||||
[manager hardResetLocalStorage];
|
|
||||||
|
|
||||||
Throw(@"Local store was reset, application must be restarted to use it.");
|
Throw(@"Local store was reset, application must be restarted to use it.");
|
||||||
} else
|
} else
|
||||||
// Try again.
|
// Try again.
|
||||||
[[self storeManager] persistentStoreCoordinator];
|
[manager persistentStoreCoordinator];
|
||||||
}
|
}
|
||||||
case UbiquityStoreManagerErrorCauseOpenCloudStore: {
|
case UbiquityStoreManagerErrorCauseOpenCloudStore: {
|
||||||
wrn(@"iCloud store could not be opened: %@", error);
|
wrn(@"iCloud store could not be opened: %@", error);
|
||||||
@ -198,13 +237,17 @@
|
|||||||
#ifdef LOCALYTICS
|
#ifdef LOCALYTICS
|
||||||
[[LocalyticsSession sharedLocalyticsSession] tagEvent:MPCheckpointCloudStoreReset attributes:nil];
|
[[LocalyticsSession sharedLocalyticsSession] tagEvent:MPCheckpointCloudStoreReset attributes:nil];
|
||||||
#endif
|
#endif
|
||||||
manager.hardResetEnabled = YES;
|
[manager deleteCloudStore];
|
||||||
[manager hardResetCloudStorage];
|
|
||||||
break;
|
break;
|
||||||
} else
|
} else
|
||||||
// Try again.
|
// Try again.
|
||||||
[[self storeManager] persistentStoreCoordinator];
|
[manager persistentStoreCoordinator];
|
||||||
}
|
}
|
||||||
|
case UbiquityStoreManagerErrorCauseMigrateLocalToCloudStore: {
|
||||||
|
wrn(@"Couldn't migrate local store to the cloud: %@", error);
|
||||||
|
wrn(@"Resetting the iCloud store.");
|
||||||
|
[manager deleteCloudStore];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,8 +9,6 @@
|
|||||||
#import "MPAppDelegate.h"
|
#import "MPAppDelegate.h"
|
||||||
#import "MPAppDelegate_Key.h"
|
#import "MPAppDelegate_Key.h"
|
||||||
#import "MPAppDelegate_Store.h"
|
#import "MPAppDelegate_Store.h"
|
||||||
#import "MPConfig.h"
|
|
||||||
#import "MPElementEntity.h"
|
|
||||||
#import <Carbon/Carbon.h>
|
#import <Carbon/Carbon.h>
|
||||||
|
|
||||||
|
|
||||||
@ -29,15 +27,19 @@
|
|||||||
#pragma clang diagnostic push
|
#pragma clang diagnostic push
|
||||||
#pragma clang diagnostic ignored "-Wfour-char-constants"
|
#pragma clang diagnostic ignored "-Wfour-char-constants"
|
||||||
static EventHotKeyID MPShowHotKey = {.signature = 'show', .id = 1};
|
static EventHotKeyID MPShowHotKey = {.signature = 'show', .id = 1};
|
||||||
|
static EventHotKeyID MPLockHotKey = {.signature = 'lock', .id = 1};
|
||||||
#pragma clang diagnostic pop
|
#pragma clang diagnostic pop
|
||||||
|
|
||||||
+ (void)initialize {
|
+ (void)initialize {
|
||||||
|
|
||||||
[MPMacConfig get];
|
static dispatch_once_t initialize;
|
||||||
|
dispatch_once(&initialize, ^{
|
||||||
|
[MPMacConfig get];
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
[PearlLogger get].printLevel = PearlLogLevelTrace;
|
[PearlLogger get].printLevel = PearlLogLevelTrace;
|
||||||
#endif
|
#endif
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (MPAppDelegate *)get {
|
+ (MPAppDelegate *)get {
|
||||||
@ -57,6 +59,10 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
|
|||||||
[((__bridge MPAppDelegate *)userData) activate:nil];
|
[((__bridge MPAppDelegate *)userData) activate:nil];
|
||||||
return noErr;
|
return noErr;
|
||||||
}
|
}
|
||||||
|
if (hotKeyID.signature == MPLockHotKey.signature && hotKeyID.id == MPLockHotKey.id) {
|
||||||
|
[((__bridge MPAppDelegate *)userData) signOut:nil];
|
||||||
|
return noErr;
|
||||||
|
}
|
||||||
|
|
||||||
return eventNotHandledErr;
|
return eventNotHandledErr;
|
||||||
}
|
}
|
||||||
@ -65,19 +71,21 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
|
|||||||
|
|
||||||
[[[self.usersItem submenu] itemArray] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
|
[[[self.usersItem submenu] itemArray] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
|
||||||
if (idx > 1)
|
if (idx > 1)
|
||||||
[[self.usersItem submenu] removeItemAtIndex:(NSInteger)idx];
|
[[self.usersItem submenu] removeItem:obj];
|
||||||
}];
|
}];
|
||||||
|
|
||||||
NSManagedObjectContext *moc = [MPAppDelegate managedObjectContextIfReady];
|
NSManagedObjectContext *moc = [MPAppDelegate managedObjectContextIfReady];
|
||||||
if (!moc) {
|
if (!moc) {
|
||||||
[self.createUserItem setEnabled:NO];
|
self.createUserItem.title = @"New User (Not ready)";
|
||||||
|
self.createUserItem.enabled = NO;
|
||||||
self.createUserItem.toolTip = @"Please wait until the app is fully loaded.";
|
self.createUserItem.toolTip = @"Please wait until the app is fully loaded.";
|
||||||
[[self.usersItem.submenu addItemWithTitle:@"Loading..." action:NULL keyEquivalent:@""] setEnabled:NO];
|
[self.usersItem.submenu addItemWithTitle:@"Loading..." action:NULL keyEquivalent:@""].enabled = NO;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
[self.createUserItem setEnabled:YES];
|
self.createUserItem.title = @"New User";
|
||||||
|
self.createUserItem.enabled = YES;
|
||||||
self.createUserItem.toolTip = nil;
|
self.createUserItem.toolTip = nil;
|
||||||
|
|
||||||
[moc performBlockAndWait:^{
|
[moc performBlockAndWait:^{
|
||||||
@ -88,6 +96,13 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
|
|||||||
users = [moc executeFetchRequest:fetchRequest error:&error];
|
users = [moc executeFetchRequest:fetchRequest error:&error];
|
||||||
if (!users)
|
if (!users)
|
||||||
err(@"Failed to load users: %@", error);
|
err(@"Failed to load users: %@", error);
|
||||||
|
|
||||||
|
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. "
|
||||||
|
@"Then give iCloud some time to sync the new user to your Mac.";
|
||||||
|
}
|
||||||
|
|
||||||
for (MPUserEntity *user in users) {
|
for (MPUserEntity *user in users) {
|
||||||
NSMenuItem *userItem = [[NSMenuItem alloc] initWithTitle:user.name action:@selector(selectUser:) keyEquivalent:@""];
|
NSMenuItem *userItem = [[NSMenuItem alloc] initWithTitle:user.name action:@selector(selectUser:) keyEquivalent:@""];
|
||||||
@ -110,18 +125,17 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
|
|||||||
|
|
||||||
- (void)showMenu {
|
- (void)showMenu {
|
||||||
|
|
||||||
self.rememberPasswordItem.state = [[MPConfig get].rememberLogin boolValue]? NSOnState: NSOffState;
|
[self updateMenuItems];
|
||||||
self.savePasswordItem.state = [MPAppDelegate get].activeUser.saveKey? NSOnState: NSOffState;
|
|
||||||
if (!(self.showItem.enabled = ![self.passwordWindow.window isVisible]))
|
|
||||||
self.showItem.toolTip = @"Master Password is already showing.";
|
|
||||||
else
|
|
||||||
self.showItem.toolTip = nil;
|
|
||||||
|
|
||||||
[self.statusItem popUpStatusItemMenu:self.statusMenu];
|
[self.statusItem popUpStatusItemMenu:self.statusMenu];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)activate:(id)sender {
|
- (IBAction)activate:(id)sender {
|
||||||
|
|
||||||
|
if (!self.activeUser)
|
||||||
|
// No user, can't activate.
|
||||||
|
return;
|
||||||
|
|
||||||
if ([[NSApplication sharedApplication] isActive])
|
if ([[NSApplication sharedApplication] isActive])
|
||||||
[self applicationDidBecomeActive:nil];
|
[self applicationDidBecomeActive:nil];
|
||||||
else
|
else
|
||||||
@ -131,7 +145,7 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
|
|||||||
- (IBAction)togglePreference:(NSMenuItem *)sender {
|
- (IBAction)togglePreference:(NSMenuItem *)sender {
|
||||||
|
|
||||||
if (sender == useICloudItem)
|
if (sender == useICloudItem)
|
||||||
[self.storeManager useiCloudStore:sender.state == NSOffState alertUser:YES];
|
self.storeManager.cloudEnabled = (sender.state == NSOnState);
|
||||||
if (sender == rememberPasswordItem)
|
if (sender == rememberPasswordItem)
|
||||||
[MPConfig get].rememberLogin = [NSNumber numberWithBool:![[MPConfig get].rememberLogin boolValue]];
|
[MPConfig get].rememberLogin = [NSNumber numberWithBool:![[MPConfig get].rememberLogin boolValue]];
|
||||||
if (sender == savePasswordItem) {
|
if (sender == savePasswordItem) {
|
||||||
@ -165,34 +179,24 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
|
|||||||
|
|
||||||
// Setup delegates and listeners.
|
// Setup delegates and listeners.
|
||||||
[MPConfig get].delegate = self;
|
[MPConfig get].delegate = self;
|
||||||
|
__weak id weakSelf = self;
|
||||||
[self addObserverBlock:^(NSString *keyPath, id object, NSDictionary *change, void *context) {
|
[self addObserverBlock:^(NSString *keyPath, id object, NSDictionary *change, void *context) {
|
||||||
if (self.key) {
|
[weakSelf updateMenuItems];
|
||||||
[self.lockItem setEnabled:YES];
|
|
||||||
self.lockItem.toolTip = nil;
|
|
||||||
|
|
||||||
[self.savePasswordItem setEnabled:YES];
|
|
||||||
self.savePasswordItem.toolTip = nil;
|
|
||||||
} else {
|
|
||||||
[self.lockItem setEnabled:NO];
|
|
||||||
self.lockItem.toolTip = @"Master Password is currently locked.";
|
|
||||||
|
|
||||||
[self.savePasswordItem setEnabled:NO];
|
|
||||||
self.savePasswordItem.toolTip = @"First unlock by selecting your user and showing the Master Password window.";
|
|
||||||
|
|
||||||
[self.passwordWindow close];
|
|
||||||
}
|
|
||||||
} forKeyPath:@"key" options:NSKeyValueObservingOptionInitial context:nil];
|
} forKeyPath:@"key" options:NSKeyValueObservingOptionInitial context:nil];
|
||||||
|
[self addObserverBlock:^(NSString *keyPath, id object, NSDictionary *change, void *context) {
|
||||||
|
[weakSelf updateMenuItems];
|
||||||
|
} forKeyPath:@"activeUser" options:NSKeyValueObservingOptionInitial context:nil];
|
||||||
|
|
||||||
// Initially, use iCloud.
|
// Initially, use iCloud.
|
||||||
if ([[MPConfig get].firstRun boolValue])
|
if ([[MPConfig get].firstRun boolValue])
|
||||||
[[self storeManager] useiCloudStore:YES alertUser:YES];
|
[self storeManager].cloudEnabled = YES;
|
||||||
|
|
||||||
// Status item.
|
// Status item.
|
||||||
self.statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength];
|
self.statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength];
|
||||||
self.statusItem.title = @"•••";
|
self.statusItem.image = [NSImage imageNamed:@"menu-icon"];
|
||||||
self.statusItem.highlightMode = YES;
|
self.statusItem.highlightMode = YES;
|
||||||
self.statusItem.target = self;
|
self.statusItem.target = self;
|
||||||
self.statusItem.action = @selector(showMenu);
|
self.statusItem.action = @selector(showMenu);
|
||||||
|
|
||||||
[self addObserverBlock:^(NSString *keyPath, id object, NSDictionary *change, void *context) {
|
[self addObserverBlock:^(NSString *keyPath, id object, NSDictionary *change, void *context) {
|
||||||
[[[self.usersItem submenu] itemArray] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
|
[[[self.usersItem submenu] itemArray] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
|
||||||
@ -204,14 +208,15 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
|
|||||||
|
|
||||||
[MPMacConfig get].usedUserName = self.activeUser.name;
|
[MPMacConfig get].usedUserName = self.activeUser.name;
|
||||||
} forKeyPath:@"activeUser" options:0 context:nil];
|
} forKeyPath:@"activeUser" options:0 context:nil];
|
||||||
[[NSNotificationCenter defaultCenter] addObserverForName:PersistentStoreDidChange object:nil queue:nil usingBlock:
|
[[NSNotificationCenter defaultCenter] addObserverForName:UbiquityManagedStoreDidChangeNotification object:nil queue:nil usingBlock:
|
||||||
^(NSNotification *note) {
|
|
||||||
[self updateUsers];
|
|
||||||
}];
|
|
||||||
[[NSNotificationCenter defaultCenter] addObserverForName:PersistentStoreDidMergeChanges object:nil queue:nil usingBlock:
|
|
||||||
^(NSNotification *note) {
|
^(NSNotification *note) {
|
||||||
[self updateUsers];
|
[self updateUsers];
|
||||||
}];
|
}];
|
||||||
|
[[NSNotificationCenter defaultCenter] addObserverForName:UbiquityManagedStoreDidImportChangesNotification object:nil queue:nil
|
||||||
|
usingBlock:
|
||||||
|
^(NSNotification *note) {
|
||||||
|
[self updateUsers];
|
||||||
|
}];
|
||||||
[self updateUsers];
|
[self updateUsers];
|
||||||
|
|
||||||
// Global hotkey.
|
// Global hotkey.
|
||||||
@ -224,7 +229,61 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
|
|||||||
err(@"Error installing application event handler: %d", status);
|
err(@"Error installing application event handler: %d", status);
|
||||||
status = RegisterEventHotKey(35 /* p */, controlKey + cmdKey, MPShowHotKey, GetApplicationEventTarget(), 0, &hotKeyRef);
|
status = RegisterEventHotKey(35 /* p */, controlKey + cmdKey, MPShowHotKey, GetApplicationEventTarget(), 0, &hotKeyRef);
|
||||||
if (status != noErr)
|
if (status != noErr)
|
||||||
err(@"Error registering hotkey: %d", status);
|
err(@"Error registering 'show' hotkey: %d", status);
|
||||||
|
status = RegisterEventHotKey(35 /* p */, controlKey + optionKey + cmdKey, MPLockHotKey, GetApplicationEventTarget(), 0, &hotKeyRef);
|
||||||
|
if (status != noErr)
|
||||||
|
err(@"Error registering 'lock' hotkey: %d", status);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)updateMenuItems {
|
||||||
|
|
||||||
|
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 = (self.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self.key) {
|
||||||
|
self.lockItem.title = @"Lock";
|
||||||
|
self.lockItem.enabled = YES;
|
||||||
|
self.lockItem.toolTip = nil;
|
||||||
|
} else {
|
||||||
|
self.lockItem.title = @"Lock (Locked)";
|
||||||
|
self.lockItem.enabled = NO;
|
||||||
|
self.lockItem.toolTip = @"Master Password is currently locked.";
|
||||||
|
}
|
||||||
|
|
||||||
|
self.rememberPasswordItem.state = [[MPConfig get].rememberLogin boolValue]? NSOnState: NSOffState;
|
||||||
|
|
||||||
|
self.savePasswordItem.state = [MPAppDelegate get].activeUser.saveKey? NSOnState: NSOffState;
|
||||||
|
if (!self.activeUser) {
|
||||||
|
self.savePasswordItem.title = @"Save Password (No user)";
|
||||||
|
self.savePasswordItem.enabled = NO;
|
||||||
|
self.savePasswordItem.toolTip = @"First select your user and unlock by showing the Master Password window.";
|
||||||
|
} else if (!self.key) {
|
||||||
|
self.savePasswordItem.title = @"Save Password (Locked)";
|
||||||
|
self.savePasswordItem.enabled = NO;
|
||||||
|
self.savePasswordItem.toolTip = @"First unlock by showing the Master Password window.";
|
||||||
|
} else {
|
||||||
|
self.savePasswordItem.title = @"Save Password";
|
||||||
|
self.savePasswordItem.enabled = YES;
|
||||||
|
self.savePasswordItem.toolTip = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.useICloudItem.state = [[MPMacConfig get].iCloud boolValue]? NSOnState: NSOffState;
|
||||||
|
if (!(self.useICloudItem.enabled = ![[MPMacConfig get].iCloud boolValue])) {
|
||||||
|
self.useICloudItem.title = @"Use iCloud (Required)";
|
||||||
|
self.useICloudItem.toolTip = @"iCloud is required in this version. Future versions will work without iCloud as well.";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self.useICloudItem.title = @"Use iCloud (Required)";
|
||||||
|
self.useICloudItem.toolTip = nil;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)applicationWillBecomeActive:(NSNotification *)notification {
|
- (void)applicationWillBecomeActive:(NSNotification *)notification {
|
||||||
@ -295,12 +354,8 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
|
|||||||
|
|
||||||
[super ubiquityStoreManager:manager didSwitchToiCloud:iCloudEnabled];
|
[super ubiquityStoreManager:manager didSwitchToiCloud:iCloudEnabled];
|
||||||
|
|
||||||
self.useICloudItem.state = iCloudEnabled? NSOnState: NSOffState;
|
[self updateMenuItems];
|
||||||
if (!(self.useICloudItem.enabled = !iCloudEnabled))
|
|
||||||
self.useICloudItem.toolTip = @"iCloud is required in this version. Future versions will work without iCloud as well.";
|
|
||||||
else
|
|
||||||
self.useICloudItem.toolTip = nil;
|
|
||||||
|
|
||||||
if (![[MPConfig get].iCloudDecided boolValue]) {
|
if (![[MPConfig get].iCloudDecided boolValue]) {
|
||||||
if (iCloudEnabled)
|
if (iCloudEnabled)
|
||||||
return;
|
return;
|
||||||
@ -310,7 +365,7 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
|
|||||||
informativeTextWithFormat:@"It is highly recommended you enable iCloud."] runModal]) {
|
informativeTextWithFormat:@"It is highly recommended you enable iCloud."] runModal]) {
|
||||||
case NSAlertDefaultReturn: {
|
case NSAlertDefaultReturn: {
|
||||||
[MPConfig get].iCloudDecided = @YES;
|
[MPConfig get].iCloudDecided = @YES;
|
||||||
[manager useiCloudStore:YES alertUser:NO];
|
manager.cloudEnabled = YES;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
@property (nonatomic, weak) IBOutlet NSTextField *tipField;
|
@property (nonatomic, weak) IBOutlet NSTextField *tipField;
|
||||||
@property (nonatomic, weak) IBOutlet NSView *contentContainer;
|
@property (nonatomic, weak) IBOutlet NSView *contentContainer;
|
||||||
@property (nonatomic, weak) IBOutlet NSProgressIndicator *progressView;
|
@property (nonatomic, weak) IBOutlet NSProgressIndicator *progressView;
|
||||||
|
@property (nonatomic, weak) IBOutlet NSTextField *userLabel;
|
||||||
|
|
||||||
- (void)unlock;
|
- (void)unlock;
|
||||||
|
|
||||||
|
@ -10,8 +10,6 @@
|
|||||||
#import "MPAppDelegate.h"
|
#import "MPAppDelegate.h"
|
||||||
#import "MPAppDelegate_Key.h"
|
#import "MPAppDelegate_Key.h"
|
||||||
#import "MPAppDelegate_Store.h"
|
#import "MPAppDelegate_Store.h"
|
||||||
#import "MPElementEntity.h"
|
|
||||||
#import "MPElementGeneratedEntity.h"
|
|
||||||
|
|
||||||
@interface MPPasswordWindowController ()
|
@interface MPPasswordWindowController ()
|
||||||
|
|
||||||
@ -35,6 +33,19 @@
|
|||||||
[self setContent:@""];
|
[self setContent:@""];
|
||||||
[self.tipField setStringValue:@""];
|
[self.tipField setStringValue:@""];
|
||||||
|
|
||||||
|
[[MPAppDelegate get] addObserverBlock:^(NSString *keyPath, id object, NSDictionary *change, void *context) {
|
||||||
|
[self.userLabel setStringValue:PearlString(@"%@'s password for:", [MPAppDelegate get].activeUser.name)];
|
||||||
|
} forKeyPath:@"activeUser" options:NSKeyValueObservingOptionInitial context:nil];
|
||||||
|
[[MPAppDelegate get] addObserverBlock:^(NSString *keyPath, id object, NSDictionary *change, void *context) {
|
||||||
|
if ([MPAppDelegate get].activeUser && [MPAppDelegate get].key)
|
||||||
|
[MPAlgorithmDefault migrateUser:[MPAppDelegate get].activeUser completion:^(BOOL userRequiresNewMigration) {
|
||||||
|
if (userRequiresNewMigration)
|
||||||
|
[NSAlert alertWithMessageText:@"Migration Needed" defaultButton:@"OK" alternateButton:nil otherButton:nil
|
||||||
|
informativeTextWithFormat:@"Certain sites require explicit migration to get updated to the latest version of the "
|
||||||
|
@"Master Password algorithm. For these sites, a migration button will appear. Migrating these sites will cause "
|
||||||
|
@"their passwords to change. You'll need to update your profile for that site with the new password."];
|
||||||
|
}];
|
||||||
|
} forKeyPath:@"key" options:NSKeyValueObservingOptionInitial context:nil];
|
||||||
[[NSNotificationCenter defaultCenter] addObserverForName:NSWindowDidBecomeKeyNotification object:self.window queue:nil
|
[[NSNotificationCenter defaultCenter] addObserverForName:NSWindowDidBecomeKeyNotification object:self.window queue:nil
|
||||||
usingBlock:^(NSNotification *note) {
|
usingBlock:^(NSNotification *note) {
|
||||||
if (!self.inProgress)
|
if (!self.inProgress)
|
||||||
@ -57,6 +68,10 @@
|
|||||||
if (shouldComplete)
|
if (shouldComplete)
|
||||||
[[[note userInfo] objectForKey:@"NSFieldEditor"] complete:nil];
|
[[[note userInfo] objectForKey:@"NSFieldEditor"] complete:nil];
|
||||||
}];
|
}];
|
||||||
|
[[NSNotificationCenter defaultCenter] addObserverForName:MPNotificationSignedOut object:nil queue:nil
|
||||||
|
usingBlock:^(NSNotification *note) {
|
||||||
|
[self.window close];
|
||||||
|
}];
|
||||||
|
|
||||||
[super windowDidLoad];
|
[super windowDidLoad];
|
||||||
}
|
}
|
||||||
@ -98,8 +113,11 @@
|
|||||||
@"If you log in with a different master password, your current sites will be unavailable.\n\n"
|
@"If you log in with a different master password, your current sites will be unavailable.\n\n"
|
||||||
@"You can always change back to your current master password later.\n"
|
@"You can always change back to your current master password later.\n"
|
||||||
@"Your current sites and passwords will then become available again."] runModal]
|
@"Your current sites and passwords will then become available again."] runModal]
|
||||||
== 1)
|
== 1) {
|
||||||
|
[MPAppDelegate get].activeUser.keyID = nil;
|
||||||
[[MPAppDelegate get] forgetSavedKeyFor:[MPAppDelegate get].activeUser];
|
[[MPAppDelegate get] forgetSavedKeyFor:[MPAppDelegate get].activeUser];
|
||||||
|
[[MPAppDelegate get] signOutAnimated:YES];
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NSAlertOtherReturn:
|
case NSAlertOtherReturn:
|
||||||
@ -126,6 +144,9 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,8 +185,8 @@
|
|||||||
[[NSPasteboard generalPasteboard] declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil];
|
[[NSPasteboard generalPasteboard] declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil];
|
||||||
if ([[NSPasteboard generalPasteboard] setString:self.content forType:NSPasteboardTypeString]) {
|
if ([[NSPasteboard generalPasteboard] setString:self.content forType:NSPasteboardTypeString]) {
|
||||||
self.tipField.alphaValue = 1;
|
self.tipField.alphaValue = 1;
|
||||||
[self.tipField setStringValue:@"Copied!"];
|
[self.tipField setStringValue:@"Copied! Hit ⎋ (ESC) to close window."];
|
||||||
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0f * NSEC_PER_SEC));
|
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0f * NSEC_PER_SEC));
|
||||||
dispatch_after(popTime, dispatch_get_main_queue(), ^{
|
dispatch_after(popTime, dispatch_get_main_queue(), ^{
|
||||||
[NSAnimationContext beginGrouping];
|
[NSAnimationContext beginGrouping];
|
||||||
[[NSAnimationContext currentContext] setDuration:0.2f];
|
[[NSAnimationContext currentContext] setDuration:0.2f];
|
||||||
@ -197,18 +218,12 @@
|
|||||||
|
|
||||||
_content = content;
|
_content = content;
|
||||||
|
|
||||||
NSShadow *shadow = [NSShadow new];
|
|
||||||
shadow.shadowColor = [NSColor colorWithDeviceWhite:0.0f alpha:0.6f];
|
|
||||||
shadow.shadowOffset = NSMakeSize(1.0f, -1.0f);
|
|
||||||
shadow.shadowBlurRadius = 1.2f;
|
|
||||||
|
|
||||||
NSMutableParagraphStyle *paragraph = [NSMutableParagraphStyle new];
|
NSMutableParagraphStyle *paragraph = [NSMutableParagraphStyle new];
|
||||||
paragraph.alignment = NSCenterTextAlignment;
|
paragraph.alignment = NSCenterTextAlignment;
|
||||||
|
|
||||||
[self.contentField setAttributedStringValue:
|
[self.contentField setAttributedStringValue:
|
||||||
[[NSAttributedString alloc] initWithString:_content
|
[[NSAttributedString alloc] initWithString:_content
|
||||||
attributes:[[NSMutableDictionary alloc] initWithObjectsAndKeys:
|
attributes:[[NSMutableDictionary alloc] initWithObjectsAndKeys:
|
||||||
shadow, NSShadowAttributeName,
|
|
||||||
paragraph, NSParagraphStyleAttributeName,
|
paragraph, NSParagraphStyleAttributeName,
|
||||||
nil]]];
|
nil]]];
|
||||||
}
|
}
|
||||||
@ -222,6 +237,8 @@
|
|||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dbg(@"element:\n%@", [result debugDescription]);
|
||||||
|
|
||||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
|
||||||
NSString *description = [result.content description];
|
NSString *description = [result.content description];
|
||||||
if (!description)
|
if (!description)
|
||||||
@ -229,7 +246,7 @@
|
|||||||
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
[self setContent:description];
|
[self setContent:description];
|
||||||
[self.tipField setStringValue:@"Hit enter to copy the password."];
|
[self.tipField setStringValue:@"Hit ⌤ (ENTER) to copy the password."];
|
||||||
self.tipField.alphaValue = 1;
|
self.tipField.alphaValue = 1;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
<object class="NSWindowTemplate" id="45434518">
|
<object class="NSWindowTemplate" id="45434518">
|
||||||
<int key="NSWindowStyleMask">287</int>
|
<int key="NSWindowStyleMask">287</int>
|
||||||
<int key="NSWindowBacking">2</int>
|
<int key="NSWindowBacking">2</int>
|
||||||
<string key="NSWindowRect">{{600, 530}, {480, 159}}</string>
|
<string key="NSWindowRect">{{600, 530}, {480, 200}}</string>
|
||||||
<int key="NSWTFlags">611845120</int>
|
<int key="NSWTFlags">611845120</int>
|
||||||
<string key="NSWindowTitle">Master Password</string>
|
<string key="NSWindowTitle">Master Password</string>
|
||||||
<string key="NSWindowClass">NSPanel</string>
|
<string key="NSWindowClass">NSPanel</string>
|
||||||
@ -56,24 +56,25 @@
|
|||||||
<reference key="NSNextResponder" ref="258451033"/>
|
<reference key="NSNextResponder" ref="258451033"/>
|
||||||
<int key="NSvFlags">268</int>
|
<int key="NSvFlags">268</int>
|
||||||
<array class="NSMutableArray" key="NSSubviews">
|
<array class="NSMutableArray" key="NSSubviews">
|
||||||
<object class="NSTextField" id="49669222">
|
<object class="NSTextField" id="642967193">
|
||||||
<reference key="NSNextResponder" ref="1072816887"/>
|
<reference key="NSNextResponder" ref="1072816887"/>
|
||||||
<int key="NSvFlags">268</int>
|
<int key="NSvFlags">268</int>
|
||||||
<string key="NSFrame">{{17, 20}, {446, 17}}</string>
|
<string key="NSFrame">{{131, 163}, {219, 17}}</string>
|
||||||
<reference key="NSSuperview" ref="1072816887"/>
|
<reference key="NSSuperview" ref="1072816887"/>
|
||||||
<string key="NSReuseIdentifierKey">_NS:1505</string>
|
<reference key="NSNextKeyView" ref="402376051"/>
|
||||||
|
<string key="NSReuseIdentifierKey">_NS:1535</string>
|
||||||
<bool key="NSEnabled">YES</bool>
|
<bool key="NSEnabled">YES</bool>
|
||||||
<object class="NSTextFieldCell" key="NSCell" id="249851874">
|
<object class="NSTextFieldCell" key="NSCell" id="406294418">
|
||||||
<int key="NSCellFlags">68157504</int>
|
<int key="NSCellFlags">68157504</int>
|
||||||
<int key="NSCellFlags2">138413056</int>
|
<int key="NSCellFlags2">272630784</int>
|
||||||
<string key="NSContents">Hit enter to copy the password.</string>
|
<string key="NSContents">Maarten Billemont's password for:</string>
|
||||||
<object class="NSFont" key="NSSupport" id="590895625">
|
<object class="NSFont" key="NSSupport" id="590895625">
|
||||||
<string key="NSName">LucidaGrande</string>
|
<string key="NSName">LucidaGrande</string>
|
||||||
<double key="NSSize">13</double>
|
<double key="NSSize">13</double>
|
||||||
<int key="NSfFlags">1044</int>
|
<int key="NSfFlags">1044</int>
|
||||||
</object>
|
</object>
|
||||||
<string key="NSCellIdentifier">_NS:1505</string>
|
<string key="NSCellIdentifier">_NS:1535</string>
|
||||||
<reference key="NSControlView" ref="49669222"/>
|
<reference key="NSControlView" ref="642967193"/>
|
||||||
<object class="NSColor" key="NSBackgroundColor" id="245864165">
|
<object class="NSColor" key="NSBackgroundColor" id="245864165">
|
||||||
<int key="NSColorSpace">6</int>
|
<int key="NSColorSpace">6</int>
|
||||||
<string key="NSCatalogName">System</string>
|
<string key="NSCatalogName">System</string>
|
||||||
@ -83,6 +84,34 @@
|
|||||||
<bytes key="NSWhite">MC42NjY2NjY2NjY3AA</bytes>
|
<bytes key="NSWhite">MC42NjY2NjY2NjY3AA</bytes>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
|
<object class="NSColor" key="NSTextColor">
|
||||||
|
<int key="NSColorSpace">6</int>
|
||||||
|
<string key="NSCatalogName">System</string>
|
||||||
|
<string key="NSColorName">controlTextColor</string>
|
||||||
|
<object class="NSColor" key="NSColor" id="714751679">
|
||||||
|
<int key="NSColorSpace">3</int>
|
||||||
|
<bytes key="NSWhite">MAA</bytes>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
|
||||||
|
</object>
|
||||||
|
<object class="NSTextField" id="49669222">
|
||||||
|
<reference key="NSNextResponder" ref="1072816887"/>
|
||||||
|
<int key="NSvFlags">268</int>
|
||||||
|
<string key="NSFrame">{{17, 20}, {446, 17}}</string>
|
||||||
|
<reference key="NSSuperview" ref="1072816887"/>
|
||||||
|
<reference key="NSNextKeyView" ref="104294954"/>
|
||||||
|
<string key="NSReuseIdentifierKey">_NS:1505</string>
|
||||||
|
<bool key="NSEnabled">YES</bool>
|
||||||
|
<object class="NSTextFieldCell" key="NSCell" id="249851874">
|
||||||
|
<int key="NSCellFlags">68157504</int>
|
||||||
|
<int key="NSCellFlags2">138413056</int>
|
||||||
|
<string key="NSContents">Hit enter to copy the password.</string>
|
||||||
|
<reference key="NSSupport" ref="590895625"/>
|
||||||
|
<string key="NSCellIdentifier">_NS:1505</string>
|
||||||
|
<reference key="NSControlView" ref="49669222"/>
|
||||||
|
<reference key="NSBackgroundColor" ref="245864165"/>
|
||||||
<object class="NSColor" key="NSTextColor">
|
<object class="NSColor" key="NSTextColor">
|
||||||
<int key="NSColorSpace">6</int>
|
<int key="NSColorSpace">6</int>
|
||||||
<string key="NSCatalogName">System</string>
|
<string key="NSCatalogName">System</string>
|
||||||
@ -98,7 +127,7 @@
|
|||||||
<object class="NSTextField" id="402376051">
|
<object class="NSTextField" id="402376051">
|
||||||
<reference key="NSNextResponder" ref="1072816887"/>
|
<reference key="NSNextResponder" ref="1072816887"/>
|
||||||
<int key="NSvFlags">268</int>
|
<int key="NSvFlags">268</int>
|
||||||
<string key="NSFrame">{{140, 117}, {200, 22}}</string>
|
<string key="NSFrame">{{140, 133}, {200, 22}}</string>
|
||||||
<reference key="NSSuperview" ref="1072816887"/>
|
<reference key="NSSuperview" ref="1072816887"/>
|
||||||
<reference key="NSNextKeyView" ref="139778114"/>
|
<reference key="NSNextKeyView" ref="139778114"/>
|
||||||
<string key="NSReuseIdentifierKey">_NS:9</string>
|
<string key="NSReuseIdentifierKey">_NS:9</string>
|
||||||
@ -106,7 +135,7 @@
|
|||||||
<object class="NSTextFieldCell" key="NSCell" id="961966865">
|
<object class="NSTextFieldCell" key="NSCell" id="961966865">
|
||||||
<int key="NSCellFlags">-1804599231</int>
|
<int key="NSCellFlags">-1804599231</int>
|
||||||
<int key="NSCellFlags2">138413120</int>
|
<int key="NSCellFlags2">138413120</int>
|
||||||
<string key="NSContents"/>
|
<string key="NSContents">apple.com</string>
|
||||||
<reference key="NSSupport" ref="590895625"/>
|
<reference key="NSSupport" ref="590895625"/>
|
||||||
<string key="NSPlaceholderString">Site name</string>
|
<string key="NSPlaceholderString">Site name</string>
|
||||||
<string key="NSCellIdentifier">_NS:9</string>
|
<string key="NSCellIdentifier">_NS:9</string>
|
||||||
@ -122,10 +151,7 @@
|
|||||||
<int key="NSColorSpace">6</int>
|
<int key="NSColorSpace">6</int>
|
||||||
<string key="NSCatalogName">System</string>
|
<string key="NSCatalogName">System</string>
|
||||||
<string key="NSColorName">textColor</string>
|
<string key="NSColorName">textColor</string>
|
||||||
<object class="NSColor" key="NSColor">
|
<reference key="NSColor" ref="714751679"/>
|
||||||
<int key="NSColorSpace">3</int>
|
|
||||||
<bytes key="NSWhite">MAA</bytes>
|
|
||||||
</object>
|
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
|
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
|
||||||
@ -133,9 +159,18 @@
|
|||||||
<object class="NSTextField" id="139778114">
|
<object class="NSTextField" id="139778114">
|
||||||
<reference key="NSNextResponder" ref="1072816887"/>
|
<reference key="NSNextResponder" ref="1072816887"/>
|
||||||
<int key="NSvFlags">268</int>
|
<int key="NSvFlags">268</int>
|
||||||
<string key="NSFrame">{{17, 45}, {446, 64}}</string>
|
<string key="NSFrame">{{17, 61}, {446, 64}}</string>
|
||||||
<reference key="NSSuperview" ref="1072816887"/>
|
<reference key="NSSuperview" ref="1072816887"/>
|
||||||
<reference key="NSNextKeyView" ref="49669222"/>
|
<reference key="NSNextKeyView" ref="49669222"/>
|
||||||
|
<object class="NSShadow" key="NSViewShadow">
|
||||||
|
<double key="NSShadowHoriz">1</double>
|
||||||
|
<double key="NSShadowVert">1</double>
|
||||||
|
<double key="NSShadowBlurRadius">1</double>
|
||||||
|
<object class="NSColor" key="NSShadowColor" id="444840817">
|
||||||
|
<int key="NSColorSpace">3</int>
|
||||||
|
<bytes key="NSWhite">MCAwLjYAA</bytes>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
<string key="NSReuseIdentifierKey">_NS:9</string>
|
<string key="NSReuseIdentifierKey">_NS:9</string>
|
||||||
<string key="NSAntiCompressionPriority">{250, 750}</string>
|
<string key="NSAntiCompressionPriority">{250, 750}</string>
|
||||||
<bool key="NSEnabled">YES</bool>
|
<bool key="NSEnabled">YES</bool>
|
||||||
@ -160,24 +195,26 @@
|
|||||||
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
|
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
|
||||||
</object>
|
</object>
|
||||||
</array>
|
</array>
|
||||||
<string key="NSFrameSize">{480, 159}</string>
|
<string key="NSFrameSize">{480, 200}</string>
|
||||||
<reference key="NSSuperview" ref="258451033"/>
|
<reference key="NSSuperview" ref="258451033"/>
|
||||||
|
<reference key="NSNextKeyView" ref="642967193"/>
|
||||||
<string key="NSReuseIdentifierKey">_NS:9</string>
|
<string key="NSReuseIdentifierKey">_NS:9</string>
|
||||||
<string key="NSClassName">NSView</string>
|
<string key="NSClassName">NSView</string>
|
||||||
</object>
|
</object>
|
||||||
<object class="NSProgressIndicator" id="104294954">
|
<object class="NSProgressIndicator" id="104294954">
|
||||||
<reference key="NSNextResponder" ref="258451033"/>
|
<reference key="NSNextResponder" ref="258451033"/>
|
||||||
<int key="NSvFlags">268</int>
|
<int key="NSvFlags">268</int>
|
||||||
<string key="NSFrame">{{224, 63}, {32, 32}}</string>
|
<string key="NSFrame">{{224, 84}, {32, 32}}</string>
|
||||||
<reference key="NSSuperview" ref="258451033"/>
|
<reference key="NSSuperview" ref="258451033"/>
|
||||||
|
<reference key="NSNextKeyView"/>
|
||||||
<string key="NSReuseIdentifierKey">_NS:945</string>
|
<string key="NSReuseIdentifierKey">_NS:945</string>
|
||||||
<int key="NSpiFlags">28682</int>
|
<int key="NSpiFlags">28682</int>
|
||||||
<double key="NSMaxValue">100</double>
|
<double key="NSMaxValue">100</double>
|
||||||
</object>
|
</object>
|
||||||
</array>
|
</array>
|
||||||
<string key="NSFrameSize">{480, 159}</string>
|
<string key="NSFrameSize">{480, 200}</string>
|
||||||
<reference key="NSSuperview"/>
|
<reference key="NSSuperview"/>
|
||||||
<reference key="NSNextKeyView"/>
|
<reference key="NSNextKeyView" ref="1072816887"/>
|
||||||
<bool key="NSViewIsLayerTreeHost">YES</bool>
|
<bool key="NSViewIsLayerTreeHost">YES</bool>
|
||||||
<string key="NSReuseIdentifierKey">_NS:21</string>
|
<string key="NSReuseIdentifierKey">_NS:21</string>
|
||||||
</object>
|
</object>
|
||||||
@ -213,6 +250,38 @@
|
|||||||
</object>
|
</object>
|
||||||
<int key="connectionID">215</int>
|
<int key="connectionID">215</int>
|
||||||
</object>
|
</object>
|
||||||
|
<object class="IBConnectionRecord">
|
||||||
|
<object class="IBOutletConnection" key="connection">
|
||||||
|
<string key="label">userLabel</string>
|
||||||
|
<reference key="source" ref="1001"/>
|
||||||
|
<reference key="destination" ref="642967193"/>
|
||||||
|
</object>
|
||||||
|
<int key="connectionID">223</int>
|
||||||
|
</object>
|
||||||
|
<object class="IBConnectionRecord">
|
||||||
|
<object class="IBOutletConnection" key="connection">
|
||||||
|
<string key="label">siteField</string>
|
||||||
|
<reference key="source" ref="1001"/>
|
||||||
|
<reference key="destination" ref="402376051"/>
|
||||||
|
</object>
|
||||||
|
<int key="connectionID">224</int>
|
||||||
|
</object>
|
||||||
|
<object class="IBConnectionRecord">
|
||||||
|
<object class="IBOutletConnection" key="connection">
|
||||||
|
<string key="label">contentField</string>
|
||||||
|
<reference key="source" ref="1001"/>
|
||||||
|
<reference key="destination" ref="139778114"/>
|
||||||
|
</object>
|
||||||
|
<int key="connectionID">225</int>
|
||||||
|
</object>
|
||||||
|
<object class="IBConnectionRecord">
|
||||||
|
<object class="IBOutletConnection" key="connection">
|
||||||
|
<string key="label">tipField</string>
|
||||||
|
<reference key="source" ref="1001"/>
|
||||||
|
<reference key="destination" ref="49669222"/>
|
||||||
|
</object>
|
||||||
|
<int key="connectionID">226</int>
|
||||||
|
</object>
|
||||||
<object class="IBConnectionRecord">
|
<object class="IBConnectionRecord">
|
||||||
<object class="IBOutletConnection" key="connection">
|
<object class="IBOutletConnection" key="connection">
|
||||||
<string key="label">delegate</string>
|
<string key="label">delegate</string>
|
||||||
@ -379,38 +448,6 @@
|
|||||||
<int key="objectID">143</int>
|
<int key="objectID">143</int>
|
||||||
<reference key="object" ref="1072816887"/>
|
<reference key="object" ref="1072816887"/>
|
||||||
<array class="NSMutableArray" key="children">
|
<array class="NSMutableArray" key="children">
|
||||||
<object class="IBNSLayoutConstraint" id="645313537">
|
|
||||||
<reference key="firstItem" ref="402376051"/>
|
|
||||||
<int key="firstAttribute">3</int>
|
|
||||||
<int key="relation">0</int>
|
|
||||||
<reference key="secondItem" ref="1072816887"/>
|
|
||||||
<int key="secondAttribute">3</int>
|
|
||||||
<float key="multiplier">1</float>
|
|
||||||
<object class="IBNSLayoutSymbolicConstant" key="constant">
|
|
||||||
<double key="value">20</double>
|
|
||||||
</object>
|
|
||||||
<float key="priority">1000</float>
|
|
||||||
<reference key="containingView" ref="1072816887"/>
|
|
||||||
<int key="scoringType">8</int>
|
|
||||||
<float key="scoringTypeFloat">29</float>
|
|
||||||
<int key="contentType">3</int>
|
|
||||||
</object>
|
|
||||||
<object class="IBNSLayoutConstraint" id="1033518145">
|
|
||||||
<reference key="firstItem" ref="402376051"/>
|
|
||||||
<int key="firstAttribute">9</int>
|
|
||||||
<int key="relation">0</int>
|
|
||||||
<reference key="secondItem" ref="139778114"/>
|
|
||||||
<int key="secondAttribute">9</int>
|
|
||||||
<float key="multiplier">1</float>
|
|
||||||
<object class="IBLayoutConstant" key="constant">
|
|
||||||
<double key="value">0.0</double>
|
|
||||||
</object>
|
|
||||||
<float key="priority">1000</float>
|
|
||||||
<reference key="containingView" ref="1072816887"/>
|
|
||||||
<int key="scoringType">6</int>
|
|
||||||
<float key="scoringTypeFloat">24</float>
|
|
||||||
<int key="contentType">2</int>
|
|
||||||
</object>
|
|
||||||
<object class="IBNSLayoutConstraint" id="314583816">
|
<object class="IBNSLayoutConstraint" id="314583816">
|
||||||
<reference key="firstItem" ref="1072816887"/>
|
<reference key="firstItem" ref="1072816887"/>
|
||||||
<int key="firstAttribute">4</int>
|
<int key="firstAttribute">4</int>
|
||||||
@ -459,7 +496,71 @@
|
|||||||
<float key="scoringTypeFloat">29</float>
|
<float key="scoringTypeFloat">29</float>
|
||||||
<int key="contentType">3</int>
|
<int key="contentType">3</int>
|
||||||
</object>
|
</object>
|
||||||
|
<object class="IBNSLayoutConstraint" id="310034208">
|
||||||
|
<reference key="firstItem" ref="642967193"/>
|
||||||
|
<int key="firstAttribute">9</int>
|
||||||
|
<int key="relation">0</int>
|
||||||
|
<reference key="secondItem" ref="402376051"/>
|
||||||
|
<int key="secondAttribute">9</int>
|
||||||
|
<float key="multiplier">1</float>
|
||||||
|
<object class="IBLayoutConstant" key="constant">
|
||||||
|
<double key="value">0.0</double>
|
||||||
|
</object>
|
||||||
|
<float key="priority">1000</float>
|
||||||
|
<reference key="containingView" ref="1072816887"/>
|
||||||
|
<int key="scoringType">6</int>
|
||||||
|
<float key="scoringTypeFloat">24</float>
|
||||||
|
<int key="contentType">2</int>
|
||||||
|
</object>
|
||||||
|
<object class="IBNSLayoutConstraint" id="645313537">
|
||||||
|
<reference key="firstItem" ref="642967193"/>
|
||||||
|
<int key="firstAttribute">3</int>
|
||||||
|
<int key="relation">0</int>
|
||||||
|
<reference key="secondItem" ref="1072816887"/>
|
||||||
|
<int key="secondAttribute">3</int>
|
||||||
|
<float key="multiplier">1</float>
|
||||||
|
<object class="IBNSLayoutSymbolicConstant" key="constant">
|
||||||
|
<double key="value">20</double>
|
||||||
|
</object>
|
||||||
|
<float key="priority">1000</float>
|
||||||
|
<reference key="containingView" ref="1072816887"/>
|
||||||
|
<int key="scoringType">8</int>
|
||||||
|
<float key="scoringTypeFloat">29</float>
|
||||||
|
<int key="contentType">3</int>
|
||||||
|
</object>
|
||||||
<object class="IBNSLayoutConstraint" id="884917592">
|
<object class="IBNSLayoutConstraint" id="884917592">
|
||||||
|
<reference key="firstItem" ref="402376051"/>
|
||||||
|
<int key="firstAttribute">3</int>
|
||||||
|
<int key="relation">0</int>
|
||||||
|
<reference key="secondItem" ref="642967193"/>
|
||||||
|
<int key="secondAttribute">4</int>
|
||||||
|
<float key="multiplier">1</float>
|
||||||
|
<object class="IBNSLayoutSymbolicConstant" key="constant">
|
||||||
|
<double key="value">8</double>
|
||||||
|
</object>
|
||||||
|
<float key="priority">1000</float>
|
||||||
|
<reference key="containingView" ref="1072816887"/>
|
||||||
|
<int key="scoringType">6</int>
|
||||||
|
<float key="scoringTypeFloat">24</float>
|
||||||
|
<int key="contentType">3</int>
|
||||||
|
</object>
|
||||||
|
<object class="IBNSLayoutConstraint" id="1033518145">
|
||||||
|
<reference key="firstItem" ref="402376051"/>
|
||||||
|
<int key="firstAttribute">9</int>
|
||||||
|
<int key="relation">0</int>
|
||||||
|
<reference key="secondItem" ref="139778114"/>
|
||||||
|
<int key="secondAttribute">9</int>
|
||||||
|
<float key="multiplier">1</float>
|
||||||
|
<object class="IBLayoutConstant" key="constant">
|
||||||
|
<double key="value">0.0</double>
|
||||||
|
</object>
|
||||||
|
<float key="priority">1000</float>
|
||||||
|
<reference key="containingView" ref="1072816887"/>
|
||||||
|
<int key="scoringType">6</int>
|
||||||
|
<float key="scoringTypeFloat">24</float>
|
||||||
|
<int key="contentType">2</int>
|
||||||
|
</object>
|
||||||
|
<object class="IBNSLayoutConstraint" id="566883659">
|
||||||
<reference key="firstItem" ref="139778114"/>
|
<reference key="firstItem" ref="139778114"/>
|
||||||
<int key="firstAttribute">3</int>
|
<int key="firstAttribute">3</int>
|
||||||
<int key="relation">0</int>
|
<int key="relation">0</int>
|
||||||
@ -508,8 +609,9 @@
|
|||||||
<int key="contentType">3</int>
|
<int key="contentType">3</int>
|
||||||
</object>
|
</object>
|
||||||
<reference ref="49669222"/>
|
<reference ref="49669222"/>
|
||||||
<reference ref="402376051"/>
|
<reference ref="642967193"/>
|
||||||
<reference ref="139778114"/>
|
<reference ref="139778114"/>
|
||||||
|
<reference ref="402376051"/>
|
||||||
</array>
|
</array>
|
||||||
<reference key="parent" ref="258451033"/>
|
<reference key="parent" ref="258451033"/>
|
||||||
</object>
|
</object>
|
||||||
@ -629,20 +731,43 @@
|
|||||||
<reference key="parent" ref="1072816887"/>
|
<reference key="parent" ref="1072816887"/>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBObjectRecord">
|
<object class="IBObjectRecord">
|
||||||
<int key="objectID">210</int>
|
<int key="objectID">216</int>
|
||||||
<reference key="object" ref="1033518145"/>
|
<reference key="object" ref="642967193"/>
|
||||||
|
<array class="NSMutableArray" key="children">
|
||||||
|
<reference ref="406294418"/>
|
||||||
|
</array>
|
||||||
<reference key="parent" ref="1072816887"/>
|
<reference key="parent" ref="1072816887"/>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBObjectRecord">
|
<object class="IBObjectRecord">
|
||||||
<int key="objectID">212</int>
|
<int key="objectID">217</int>
|
||||||
|
<reference key="object" ref="406294418"/>
|
||||||
|
<reference key="parent" ref="642967193"/>
|
||||||
|
</object>
|
||||||
|
<object class="IBObjectRecord">
|
||||||
|
<int key="objectID">218</int>
|
||||||
<reference key="object" ref="645313537"/>
|
<reference key="object" ref="645313537"/>
|
||||||
<reference key="parent" ref="1072816887"/>
|
<reference key="parent" ref="1072816887"/>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBObjectRecord">
|
<object class="IBObjectRecord">
|
||||||
<int key="objectID">213</int>
|
<int key="objectID">219</int>
|
||||||
|
<reference key="object" ref="310034208"/>
|
||||||
|
<reference key="parent" ref="1072816887"/>
|
||||||
|
</object>
|
||||||
|
<object class="IBObjectRecord">
|
||||||
|
<int key="objectID">221</int>
|
||||||
<reference key="object" ref="884917592"/>
|
<reference key="object" ref="884917592"/>
|
||||||
<reference key="parent" ref="1072816887"/>
|
<reference key="parent" ref="1072816887"/>
|
||||||
</object>
|
</object>
|
||||||
|
<object class="IBObjectRecord">
|
||||||
|
<int key="objectID">222</int>
|
||||||
|
<reference key="object" ref="566883659"/>
|
||||||
|
<reference key="parent" ref="1072816887"/>
|
||||||
|
</object>
|
||||||
|
<object class="IBObjectRecord">
|
||||||
|
<int key="objectID">210</int>
|
||||||
|
<reference key="object" ref="1033518145"/>
|
||||||
|
<reference key="parent" ref="1072816887"/>
|
||||||
|
</object>
|
||||||
</array>
|
</array>
|
||||||
</object>
|
</object>
|
||||||
<dictionary class="NSMutableDictionary" key="flattenedProperties">
|
<dictionary class="NSMutableDictionary" key="flattenedProperties">
|
||||||
@ -652,12 +777,14 @@
|
|||||||
<array class="NSMutableArray" key="143.IBNSViewMetadataConstraints">
|
<array class="NSMutableArray" key="143.IBNSViewMetadataConstraints">
|
||||||
<reference ref="865006730"/>
|
<reference ref="865006730"/>
|
||||||
<reference ref="831384658"/>
|
<reference ref="831384658"/>
|
||||||
|
<reference ref="566883659"/>
|
||||||
|
<reference ref="1033518145"/>
|
||||||
<reference ref="884917592"/>
|
<reference ref="884917592"/>
|
||||||
|
<reference ref="645313537"/>
|
||||||
|
<reference ref="310034208"/>
|
||||||
<reference ref="63384401"/>
|
<reference ref="63384401"/>
|
||||||
<reference ref="602857839"/>
|
<reference ref="602857839"/>
|
||||||
<reference ref="314583816"/>
|
<reference ref="314583816"/>
|
||||||
<reference ref="1033518145"/>
|
|
||||||
<reference ref="645313537"/>
|
|
||||||
</array>
|
</array>
|
||||||
<boolean value="NO" key="143.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
|
<boolean value="NO" key="143.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
|
||||||
<string key="143.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
<string key="143.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
@ -667,11 +794,19 @@
|
|||||||
<string key="150.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
<string key="150.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
<boolean value="NO" key="181.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
|
<boolean value="NO" key="181.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
|
||||||
<string key="181.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
<string key="181.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
|
<real value="1" key="181.IBViewIntegration.shadowBlurRadius"/>
|
||||||
|
<reference key="181.IBViewIntegration.shadowColor" ref="444840817"/>
|
||||||
|
<real value="1" key="181.IBViewIntegration.shadowOffsetHeight"/>
|
||||||
|
<real value="1" key="181.IBViewIntegration.shadowOffsetWidth"/>
|
||||||
<array class="NSMutableArray" key="182.IBNSViewMetadataConstraints">
|
<array class="NSMutableArray" key="182.IBNSViewMetadataConstraints">
|
||||||
<reference ref="102475933"/>
|
<reference ref="102475933"/>
|
||||||
</array>
|
</array>
|
||||||
<boolean value="NO" key="182.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
|
<boolean value="NO" key="182.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
|
||||||
<string key="182.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
<string key="182.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
|
<real value="0.0" key="182.IBViewIntegration.shadowBlurRadius"/>
|
||||||
|
<reference key="182.IBViewIntegration.shadowColor" ref="714751679"/>
|
||||||
|
<real value="0.0" key="182.IBViewIntegration.shadowOffsetHeight"/>
|
||||||
|
<real value="0.0" key="182.IBViewIntegration.shadowOffsetWidth"/>
|
||||||
<boolean value="NO" key="183.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
|
<boolean value="NO" key="183.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
|
||||||
<string key="183.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
<string key="183.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
<string key="184.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
<string key="184.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
@ -686,12 +821,17 @@
|
|||||||
<string key="208.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
<string key="208.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
<string key="209.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
<string key="209.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
<string key="210.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
<string key="210.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
<string key="212.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
<boolean value="NO" key="216.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
|
||||||
<string key="213.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
<string key="216.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
|
<string key="217.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
|
<string key="218.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
|
<string key="219.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
<boolean value="YES" key="22.IBNSWindowAutoPositionCentersHorizontal"/>
|
<boolean value="YES" key="22.IBNSWindowAutoPositionCentersHorizontal"/>
|
||||||
<boolean value="YES" key="22.IBNSWindowAutoPositionCentersVertical"/>
|
<boolean value="YES" key="22.IBNSWindowAutoPositionCentersVertical"/>
|
||||||
<string key="22.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
<string key="22.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
<boolean value="NO" key="22.NSWindowTemplate.visibleAtLaunch"/>
|
<boolean value="NO" key="22.NSWindowTemplate.visibleAtLaunch"/>
|
||||||
|
<string key="221.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
|
<string key="222.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
<array key="23.IBNSViewMetadataConstraints">
|
<array key="23.IBNSViewMetadataConstraints">
|
||||||
<reference ref="216428540"/>
|
<reference ref="216428540"/>
|
||||||
<reference ref="265452638"/>
|
<reference ref="265452638"/>
|
||||||
@ -708,7 +848,7 @@
|
|||||||
<nil key="activeLocalization"/>
|
<nil key="activeLocalization"/>
|
||||||
<dictionary class="NSMutableDictionary" key="localizations"/>
|
<dictionary class="NSMutableDictionary" key="localizations"/>
|
||||||
<nil key="sourceID"/>
|
<nil key="sourceID"/>
|
||||||
<int key="maxID">215</int>
|
<int key="maxID">230</int>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBClassDescriber" key="IBDocument.Classes"/>
|
<object class="IBClassDescriber" key="IBDocument.Classes"/>
|
||||||
<int key="IBDocument.localizationMode">0</int>
|
<int key="IBDocument.localizationMode">0</int>
|
||||||
|
@ -47,27 +47,19 @@
|
|||||||
<object class="NSMenu" id="764588027">
|
<object class="NSMenu" id="764588027">
|
||||||
<string key="NSTitle"/>
|
<string key="NSTitle"/>
|
||||||
<array class="NSMutableArray" key="NSMenuItems">
|
<array class="NSMutableArray" key="NSMenuItems">
|
||||||
<object class="NSMenuItem" id="846612332">
|
|
||||||
<reference key="NSMenu" ref="764588027"/>
|
|
||||||
<string key="NSTitle">Show</string>
|
|
||||||
<string key="NSKeyEquiv"/>
|
|
||||||
<int key="NSMnemonicLoc">2147483647</int>
|
|
||||||
<object class="NSCustomResource" key="NSOnImage" id="552246001">
|
|
||||||
<string key="NSClassName">NSImage</string>
|
|
||||||
<string key="NSResourceName">NSMenuCheckmark</string>
|
|
||||||
</object>
|
|
||||||
<object class="NSCustomResource" key="NSMixedImage" id="752047669">
|
|
||||||
<string key="NSClassName">NSImage</string>
|
|
||||||
<string key="NSResourceName">NSMenuMixedState</string>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
<object class="NSMenuItem" id="11982480">
|
<object class="NSMenuItem" id="11982480">
|
||||||
<reference key="NSMenu" ref="764588027"/>
|
<reference key="NSMenu" ref="764588027"/>
|
||||||
<string key="NSTitle">Users</string>
|
<string key="NSTitle">Users</string>
|
||||||
<string key="NSKeyEquiv"/>
|
<string key="NSKeyEquiv"/>
|
||||||
<int key="NSMnemonicLoc">2147483647</int>
|
<int key="NSMnemonicLoc">2147483647</int>
|
||||||
<reference key="NSOnImage" ref="552246001"/>
|
<object class="NSCustomResource" key="NSOnImage" id="269450960">
|
||||||
<reference key="NSMixedImage" ref="752047669"/>
|
<string key="NSClassName">NSImage</string>
|
||||||
|
<string key="NSResourceName">NSMenuCheckmark</string>
|
||||||
|
</object>
|
||||||
|
<object class="NSCustomResource" key="NSMixedImage" id="977440657">
|
||||||
|
<string key="NSClassName">NSImage</string>
|
||||||
|
<string key="NSResourceName">NSMenuMixedState</string>
|
||||||
|
</object>
|
||||||
<string key="NSAction">submenuAction:</string>
|
<string key="NSAction">submenuAction:</string>
|
||||||
<object class="NSMenu" key="NSSubmenu" id="934187555">
|
<object class="NSMenu" key="NSSubmenu" id="934187555">
|
||||||
<string key="NSTitle">Users</string>
|
<string key="NSTitle">Users</string>
|
||||||
@ -78,8 +70,8 @@
|
|||||||
<string key="NSTitle">New User</string>
|
<string key="NSTitle">New User</string>
|
||||||
<string key="NSKeyEquiv"/>
|
<string key="NSKeyEquiv"/>
|
||||||
<int key="NSMnemonicLoc">2147483647</int>
|
<int key="NSMnemonicLoc">2147483647</int>
|
||||||
<reference key="NSOnImage" ref="552246001"/>
|
<reference key="NSOnImage" ref="269450960"/>
|
||||||
<reference key="NSMixedImage" ref="752047669"/>
|
<reference key="NSMixedImage" ref="977440657"/>
|
||||||
</object>
|
</object>
|
||||||
<object class="NSMenuItem" id="925131766">
|
<object class="NSMenuItem" id="925131766">
|
||||||
<reference key="NSMenu" ref="934187555"/>
|
<reference key="NSMenu" ref="934187555"/>
|
||||||
@ -88,8 +80,8 @@
|
|||||||
<string key="NSTitle"/>
|
<string key="NSTitle"/>
|
||||||
<string key="NSKeyEquiv"/>
|
<string key="NSKeyEquiv"/>
|
||||||
<int key="NSMnemonicLoc">2147483647</int>
|
<int key="NSMnemonicLoc">2147483647</int>
|
||||||
<reference key="NSOnImage" ref="552246001"/>
|
<reference key="NSOnImage" ref="269450960"/>
|
||||||
<reference key="NSMixedImage" ref="752047669"/>
|
<reference key="NSMixedImage" ref="977440657"/>
|
||||||
</object>
|
</object>
|
||||||
</array>
|
</array>
|
||||||
</object>
|
</object>
|
||||||
@ -99,8 +91,8 @@
|
|||||||
<string key="NSTitle">Preferences</string>
|
<string key="NSTitle">Preferences</string>
|
||||||
<string key="NSKeyEquiv"/>
|
<string key="NSKeyEquiv"/>
|
||||||
<int key="NSMnemonicLoc">2147483647</int>
|
<int key="NSMnemonicLoc">2147483647</int>
|
||||||
<reference key="NSOnImage" ref="552246001"/>
|
<reference key="NSOnImage" ref="269450960"/>
|
||||||
<reference key="NSMixedImage" ref="752047669"/>
|
<reference key="NSMixedImage" ref="977440657"/>
|
||||||
<string key="NSAction">submenuAction:</string>
|
<string key="NSAction">submenuAction:</string>
|
||||||
<object class="NSMenu" key="NSSubmenu" id="800575174">
|
<object class="NSMenu" key="NSSubmenu" id="800575174">
|
||||||
<string key="NSTitle">Preferences</string>
|
<string key="NSTitle">Preferences</string>
|
||||||
@ -110,8 +102,8 @@
|
|||||||
<string key="NSTitle">Use iCloud</string>
|
<string key="NSTitle">Use iCloud</string>
|
||||||
<string key="NSKeyEquiv"/>
|
<string key="NSKeyEquiv"/>
|
||||||
<int key="NSMnemonicLoc">2147483647</int>
|
<int key="NSMnemonicLoc">2147483647</int>
|
||||||
<reference key="NSOnImage" ref="552246001"/>
|
<reference key="NSOnImage" ref="269450960"/>
|
||||||
<reference key="NSMixedImage" ref="752047669"/>
|
<reference key="NSMixedImage" ref="977440657"/>
|
||||||
</object>
|
</object>
|
||||||
<object class="NSMenuItem" id="461686112">
|
<object class="NSMenuItem" id="461686112">
|
||||||
<reference key="NSMenu" ref="800575174"/>
|
<reference key="NSMenu" ref="800575174"/>
|
||||||
@ -119,8 +111,8 @@
|
|||||||
<string key="NSTitle">Synchronize available sites from your iCloud account.</string>
|
<string key="NSTitle">Synchronize available sites from your iCloud account.</string>
|
||||||
<string key="NSKeyEquiv"/>
|
<string key="NSKeyEquiv"/>
|
||||||
<int key="NSMnemonicLoc">2147483647</int>
|
<int key="NSMnemonicLoc">2147483647</int>
|
||||||
<reference key="NSOnImage" ref="552246001"/>
|
<reference key="NSOnImage" ref="269450960"/>
|
||||||
<reference key="NSMixedImage" ref="752047669"/>
|
<reference key="NSMixedImage" ref="977440657"/>
|
||||||
<object class="NSAttributedString" key="NSAttributedTitle">
|
<object class="NSAttributedString" key="NSAttributedTitle">
|
||||||
<string key="NSString">Synchronize available sites from your iCloud account.</string>
|
<string key="NSString">Synchronize available sites from your iCloud account.</string>
|
||||||
<dictionary key="NSAttributes" id="583461090">
|
<dictionary key="NSAttributes" id="583461090">
|
||||||
@ -141,8 +133,8 @@
|
|||||||
<string key="NSTitle">Remember Password</string>
|
<string key="NSTitle">Remember Password</string>
|
||||||
<string key="NSKeyEquiv"/>
|
<string key="NSKeyEquiv"/>
|
||||||
<int key="NSMnemonicLoc">2147483647</int>
|
<int key="NSMnemonicLoc">2147483647</int>
|
||||||
<reference key="NSOnImage" ref="552246001"/>
|
<reference key="NSOnImage" ref="269450960"/>
|
||||||
<reference key="NSMixedImage" ref="752047669"/>
|
<reference key="NSMixedImage" ref="977440657"/>
|
||||||
</object>
|
</object>
|
||||||
<object class="NSMenuItem" id="907921953">
|
<object class="NSMenuItem" id="907921953">
|
||||||
<reference key="NSMenu" ref="800575174"/>
|
<reference key="NSMenu" ref="800575174"/>
|
||||||
@ -150,8 +142,8 @@
|
|||||||
<string key="NSTitle">Remember the password while the application is running.</string>
|
<string key="NSTitle">Remember the password while the application is running.</string>
|
||||||
<string key="NSKeyEquiv"/>
|
<string key="NSKeyEquiv"/>
|
||||||
<int key="NSMnemonicLoc">2147483647</int>
|
<int key="NSMnemonicLoc">2147483647</int>
|
||||||
<reference key="NSOnImage" ref="552246001"/>
|
<reference key="NSOnImage" ref="269450960"/>
|
||||||
<reference key="NSMixedImage" ref="752047669"/>
|
<reference key="NSMixedImage" ref="977440657"/>
|
||||||
<object class="NSAttributedString" key="NSAttributedTitle">
|
<object class="NSAttributedString" key="NSAttributedTitle">
|
||||||
<string key="NSString">Remember the password while the application is running.</string>
|
<string key="NSString">Remember the password while the application is running.</string>
|
||||||
<reference key="NSAttributes" ref="583461090"/>
|
<reference key="NSAttributes" ref="583461090"/>
|
||||||
@ -162,8 +154,8 @@
|
|||||||
<string key="NSTitle">Save Password</string>
|
<string key="NSTitle">Save Password</string>
|
||||||
<string key="NSKeyEquiv"/>
|
<string key="NSKeyEquiv"/>
|
||||||
<int key="NSMnemonicLoc">2147483647</int>
|
<int key="NSMnemonicLoc">2147483647</int>
|
||||||
<reference key="NSOnImage" ref="552246001"/>
|
<reference key="NSOnImage" ref="269450960"/>
|
||||||
<reference key="NSMixedImage" ref="752047669"/>
|
<reference key="NSMixedImage" ref="977440657"/>
|
||||||
</object>
|
</object>
|
||||||
<object class="NSMenuItem" id="123831322">
|
<object class="NSMenuItem" id="123831322">
|
||||||
<reference key="NSMenu" ref="800575174"/>
|
<reference key="NSMenu" ref="800575174"/>
|
||||||
@ -171,8 +163,8 @@
|
|||||||
<string key="NSTitle">Save the password in your keychain so you don't need to enter it again.</string>
|
<string key="NSTitle">Save the password in your keychain so you don't need to enter it again.</string>
|
||||||
<string key="NSKeyEquiv"/>
|
<string key="NSKeyEquiv"/>
|
||||||
<int key="NSMnemonicLoc">2147483647</int>
|
<int key="NSMnemonicLoc">2147483647</int>
|
||||||
<reference key="NSOnImage" ref="552246001"/>
|
<reference key="NSOnImage" ref="269450960"/>
|
||||||
<reference key="NSMixedImage" ref="752047669"/>
|
<reference key="NSMixedImage" ref="977440657"/>
|
||||||
<object class="NSAttributedString" key="NSAttributedTitle">
|
<object class="NSAttributedString" key="NSAttributedTitle">
|
||||||
<string key="NSString">Save the password in your keychain so you don't need to enter it again.</string>
|
<string key="NSString">Save the password in your keychain so you don't need to enter it again.</string>
|
||||||
<reference key="NSAttributes" ref="583461090"/>
|
<reference key="NSAttributes" ref="583461090"/>
|
||||||
@ -189,25 +181,35 @@
|
|||||||
<string key="NSTitle"/>
|
<string key="NSTitle"/>
|
||||||
<string key="NSKeyEquiv"/>
|
<string key="NSKeyEquiv"/>
|
||||||
<int key="NSMnemonicLoc">2147483647</int>
|
<int key="NSMnemonicLoc">2147483647</int>
|
||||||
<reference key="NSOnImage" ref="552246001"/>
|
<reference key="NSOnImage" ref="269450960"/>
|
||||||
<reference key="NSMixedImage" ref="752047669"/>
|
<reference key="NSMixedImage" ref="977440657"/>
|
||||||
|
</object>
|
||||||
|
<object class="NSMenuItem" id="846612332">
|
||||||
|
<reference key="NSMenu" ref="764588027"/>
|
||||||
|
<string key="NSTitle">Show</string>
|
||||||
|
<string key="NSKeyEquiv">p</string>
|
||||||
|
<int key="NSKeyEquivModMask">1310720</int>
|
||||||
|
<int key="NSMnemonicLoc">2147483647</int>
|
||||||
|
<reference key="NSOnImage" ref="269450960"/>
|
||||||
|
<reference key="NSMixedImage" ref="977440657"/>
|
||||||
</object>
|
</object>
|
||||||
<object class="NSMenuItem" id="229948989">
|
<object class="NSMenuItem" id="229948989">
|
||||||
<reference key="NSMenu" ref="764588027"/>
|
<reference key="NSMenu" ref="764588027"/>
|
||||||
<bool key="NSIsDisabled">YES</bool>
|
<bool key="NSIsDisabled">YES</bool>
|
||||||
<string key="NSTitle">Lock</string>
|
<string key="NSTitle">Lock</string>
|
||||||
<string key="NSKeyEquiv"/>
|
<string key="NSKeyEquiv">p</string>
|
||||||
|
<int key="NSKeyEquivModMask">1835008</int>
|
||||||
<int key="NSMnemonicLoc">2147483647</int>
|
<int key="NSMnemonicLoc">2147483647</int>
|
||||||
<reference key="NSOnImage" ref="552246001"/>
|
<reference key="NSOnImage" ref="269450960"/>
|
||||||
<reference key="NSMixedImage" ref="752047669"/>
|
<reference key="NSMixedImage" ref="977440657"/>
|
||||||
</object>
|
</object>
|
||||||
<object class="NSMenuItem" id="291035877">
|
<object class="NSMenuItem" id="291035877">
|
||||||
<reference key="NSMenu" ref="764588027"/>
|
<reference key="NSMenu" ref="764588027"/>
|
||||||
<string key="NSTitle">Quit</string>
|
<string key="NSTitle">Quit</string>
|
||||||
<string key="NSKeyEquiv"/>
|
<string key="NSKeyEquiv"/>
|
||||||
<int key="NSMnemonicLoc">2147483647</int>
|
<int key="NSMnemonicLoc">2147483647</int>
|
||||||
<reference key="NSOnImage" ref="552246001"/>
|
<reference key="NSOnImage" ref="269450960"/>
|
||||||
<reference key="NSMixedImage" ref="752047669"/>
|
<reference key="NSMixedImage" ref="977440657"/>
|
||||||
</object>
|
</object>
|
||||||
</array>
|
</array>
|
||||||
<bool key="NSNoAutoenable">YES</bool>
|
<bool key="NSNoAutoenable">YES</bool>
|
||||||
@ -392,9 +394,9 @@
|
|||||||
<array class="NSMutableArray" key="children">
|
<array class="NSMutableArray" key="children">
|
||||||
<reference ref="291035877"/>
|
<reference ref="291035877"/>
|
||||||
<reference ref="466252869"/>
|
<reference ref="466252869"/>
|
||||||
<reference ref="846612332"/>
|
|
||||||
<reference ref="229948989"/>
|
<reference ref="229948989"/>
|
||||||
<reference ref="851296005"/>
|
<reference ref="851296005"/>
|
||||||
|
<reference ref="846612332"/>
|
||||||
<reference ref="11982480"/>
|
<reference ref="11982480"/>
|
||||||
</array>
|
</array>
|
||||||
<reference key="parent" ref="0"/>
|
<reference key="parent" ref="0"/>
|
||||||
|
@ -178,30 +178,11 @@
|
|||||||
}];
|
}];
|
||||||
|
|
||||||
if ([MPAppDelegate get].activeUser)
|
if ([MPAppDelegate get].activeUser)
|
||||||
[[MPAppDelegate get].managedObjectContextIfReady performBlock:^void() {
|
[MPAlgorithmDefault migrateUser:[MPAppDelegate get].activeUser completion:^(BOOL userRequiresNewMigration) {
|
||||||
NSError *error = nil;
|
if (userRequiresNewMigration)
|
||||||
NSFetchRequest *migrationRequest = [NSFetchRequest
|
|
||||||
fetchRequestWithEntityName:NSStringFromClass([MPElementEntity class])];
|
|
||||||
migrationRequest.predicate = [NSPredicate predicateWithFormat:@"version_ < %d", MPAlgorithmDefaultVersion];
|
|
||||||
NSArray *migrationElements = [[MPAppDelegate get].managedObjectContextIfReady executeFetchRequest:migrationRequest
|
|
||||||
error:&error];
|
|
||||||
if (!migrationElements) {
|
|
||||||
err(@"While looking for elements to migrate: %@", error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL didRequireExplicitMigration = [MPAppDelegate_Shared get].activeUser.requiresExplicitMigration;
|
|
||||||
if (didRequireExplicitMigration)
|
|
||||||
[MPAppDelegate_Shared get].activeUser.requiresExplicitMigration = NO;
|
|
||||||
for (MPElementEntity *migrationElement in migrationElements)
|
|
||||||
if (![migrationElement migrateExplicitly:NO])
|
|
||||||
[MPAppDelegate_Shared get].activeUser.requiresExplicitMigration = YES;
|
|
||||||
|
|
||||||
if (!didRequireExplicitMigration && [MPAppDelegate_Shared get].activeUser.requiresExplicitMigration)
|
|
||||||
[UIView animateWithDuration:0.3f animations:^{
|
[UIView animateWithDuration:0.3f animations:^{
|
||||||
self.outdatedAlertContainer.alpha = 1;
|
self.outdatedAlertContainer.alpha = 1;
|
||||||
}];
|
}];
|
||||||
|
|
||||||
}];
|
}];
|
||||||
|
|
||||||
[[LocalyticsSession sharedLocalyticsSession] tagScreen:@"Main"];
|
[[LocalyticsSession sharedLocalyticsSession] tagScreen:@"Main"];
|
||||||
@ -794,6 +775,7 @@
|
|||||||
- (void)didSelectElement:(MPElementEntity *)element {
|
- (void)didSelectElement:(MPElementEntity *)element {
|
||||||
|
|
||||||
inf(@"Selected: %@", element.name);
|
inf(@"Selected: %@", element.name);
|
||||||
|
dbg(@"Element:\n%@", [element debugDescription]);
|
||||||
|
|
||||||
[self closeAlert];
|
[self closeAlert];
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user