Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b2c688a1ce | ||
|
|
aee1030758 | ||
|
|
f665aeccc4 | ||
|
|
e58b9ef34f | ||
|
|
968de6026f |
@@ -3024,7 +3024,6 @@
|
|||||||
CLANG_WARN_OBJC_RECEIVER_WEAK = NO;
|
CLANG_WARN_OBJC_RECEIVER_WEAK = NO;
|
||||||
CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = NO;
|
CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = NO;
|
||||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
|
||||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
|
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
|
||||||
@@ -3126,7 +3125,6 @@
|
|||||||
CLANG_WARN_OBJC_RECEIVER_WEAK = NO;
|
CLANG_WARN_OBJC_RECEIVER_WEAK = NO;
|
||||||
CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = NO;
|
CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = NO;
|
||||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
|
||||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
|
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
|
||||||
@@ -3202,7 +3200,7 @@
|
|||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CLANG_ENABLE_OBJC_ARC = YES;
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = Source/Mac/MasterPassword.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Source/Mac/MasterPassword.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "-";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
GCC_PREFIX_HEADER = "Source/MasterPassword-Prefix.pch";
|
GCC_PREFIX_HEADER = "Source/MasterPassword-Prefix.pch";
|
||||||
@@ -3242,7 +3240,7 @@
|
|||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CLANG_ENABLE_OBJC_ARC = YES;
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = Source/Mac/MasterPassword.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Source/Mac/MasterPassword.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "-";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
GCC_PREFIX_HEADER = "Source/MasterPassword-Prefix.pch";
|
GCC_PREFIX_HEADER = "Source/MasterPassword-Prefix.pch";
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ static NSOperationQueue *_mpwQueue = nil;
|
|||||||
- (BOOL)tryMigrateUser:(MPUserEntity *)user inContext:(NSManagedObjectContext *)moc {
|
- (BOOL)tryMigrateUser:(MPUserEntity *)user inContext:(NSManagedObjectContext *)moc {
|
||||||
|
|
||||||
NSError *error = nil;
|
NSError *error = nil;
|
||||||
NSFetchRequest *migrationRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPSiteEntity class] )];
|
NSFetchRequest *migrationRequest = [MPSiteEntity fetchRequest];
|
||||||
migrationRequest.predicate = [NSPredicate predicateWithFormat:@"version_ < %d AND user == %@", self.version, user];
|
migrationRequest.predicate = [NSPredicate predicateWithFormat:@"version_ < %d AND user == %@", self.version, user];
|
||||||
NSArray *migrationSites = [moc executeFetchRequest:migrationRequest error:&error];
|
NSArray *migrationSites = [moc executeFetchRequest:migrationRequest error:&error];
|
||||||
if (!migrationSites) {
|
if (!migrationSites) {
|
||||||
|
|||||||
@@ -51,7 +51,6 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
|||||||
|
|
||||||
+ (NSManagedObjectContext *)managedObjectContextForMainThreadIfReady {
|
+ (NSManagedObjectContext *)managedObjectContextForMainThreadIfReady {
|
||||||
|
|
||||||
NSAssert( [[NSThread currentThread] isMainThread], @"Can only access main MOC from the main thread." );
|
|
||||||
NSManagedObjectContext *mainManagedObjectContext = [[self get] mainManagedObjectContextIfReady];
|
NSManagedObjectContext *mainManagedObjectContext = [[self get] mainManagedObjectContextIfReady];
|
||||||
if (!mainManagedObjectContext || ![[NSThread currentThread] isMainThread])
|
if (!mainManagedObjectContext || ![[NSThread currentThread] isMainThread])
|
||||||
return nil;
|
return nil;
|
||||||
@@ -155,7 +154,42 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
|||||||
|
|
||||||
- (NSManagedObjectContext *)mainManagedObjectContextIfReady {
|
- (NSManagedObjectContext *)mainManagedObjectContextIfReady {
|
||||||
|
|
||||||
|
NSAssert( [[NSThread currentThread] isMainThread], @"Can only access main MOC from the main thread." );
|
||||||
|
|
||||||
[self loadStore];
|
[self loadStore];
|
||||||
|
|
||||||
|
if (!self.mainManagedObjectContext && self.privateManagedObjectContext.persistentStoreCoordinator) {
|
||||||
|
self.mainManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
|
||||||
|
self.mainManagedObjectContext.parentContext = self.privateManagedObjectContext;
|
||||||
|
if (@available( iOS 10.0, macOS 10.12, * ))
|
||||||
|
self.mainManagedObjectContext.automaticallyMergesChangesFromParent = YES;
|
||||||
|
else
|
||||||
|
// When privateManagedObjectContext is saved, import the changes into mainManagedObjectContext.
|
||||||
|
PearlAddNotificationObserverTo( self.mainManagedObjectContext, NSManagedObjectContextDidSaveNotification,
|
||||||
|
self.privateManagedObjectContext, nil, ^(NSManagedObjectContext *mainContext, NSNotification *note) {
|
||||||
|
[mainContext performBlock:^{
|
||||||
|
@try {
|
||||||
|
[mainContext mergeChangesFromContextDidSaveNotification:note];
|
||||||
|
}
|
||||||
|
@catch (NSException *exception) {
|
||||||
|
err( @"While merging changes:\n%@", [exception fullDescription] );
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
} );
|
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
|
PearlAddNotificationObserver( UIApplicationWillResignActiveNotification, UIApp, [NSOperationQueue mainQueue],
|
||||||
|
^(MPAppDelegate_Shared *self, NSNotification *note) {
|
||||||
|
[self.mainManagedObjectContext saveToStore];
|
||||||
|
} );
|
||||||
|
#else
|
||||||
|
PearlAddNotificationObserver( NSApplicationWillResignActiveNotification, NSApp, [NSOperationQueue mainQueue],
|
||||||
|
^(MPAppDelegate_Shared *self, NSNotification *note) {
|
||||||
|
[self.mainManagedObjectContext saveToStore];
|
||||||
|
} );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
return self.mainManagedObjectContext;
|
return self.mainManagedObjectContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,12 +217,12 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
|||||||
} );
|
} );
|
||||||
|
|
||||||
// Do nothing if already fully set up, otherwise (re-)load the store.
|
// Do nothing if already fully set up, otherwise (re-)load the store.
|
||||||
if (self.mainManagedObjectContext && self.privateManagedObjectContext)
|
if ([self.storeCoordinator.persistentStores count])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
[self.storeQueue addOperationWithBlock:^{
|
NSOperation *storeOperation = [NSBlockOperation blockOperationWithBlock:^{
|
||||||
// Do nothing if already fully set up, otherwise (re-)load the store.
|
// Do nothing if already fully set up, otherwise (re-)load the store.
|
||||||
if (self.mainManagedObjectContext && self.privateManagedObjectContext)
|
if ([self.storeCoordinator.persistentStores count])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Unregister any existing observers and contexts.
|
// Unregister any existing observers and contexts.
|
||||||
@@ -201,12 +235,6 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
|||||||
[self.privateManagedObjectContext reset];
|
[self.privateManagedObjectContext reset];
|
||||||
self.privateManagedObjectContext = nil;
|
self.privateManagedObjectContext = nil;
|
||||||
}];
|
}];
|
||||||
NSError *error = nil;
|
|
||||||
for (NSPersistentStore *store in self.storeCoordinator.persistentStores)
|
|
||||||
if (![self.storeCoordinator removePersistentStore:store error:&error] || error) {
|
|
||||||
MPError( error, @"Couldn't remove persistence store from coordinator." );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't load when the store is corrupted.
|
// Don't load when the store is corrupted.
|
||||||
if ([self.storeCorrupted boolValue])
|
if ([self.storeCorrupted boolValue])
|
||||||
@@ -217,12 +245,10 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
|||||||
|
|
||||||
// Create a new store coordinator.
|
// Create a new store coordinator.
|
||||||
NSURL *localStoreURL = [self localStoreURL];
|
NSURL *localStoreURL = [self localStoreURL];
|
||||||
|
NSError *error = nil;
|
||||||
if (![[NSFileManager defaultManager] createDirectoryAtURL:[localStoreURL URLByDeletingLastPathComponent]
|
if (![[NSFileManager defaultManager] createDirectoryAtURL:[localStoreURL URLByDeletingLastPathComponent]
|
||||||
withIntermediateDirectories:YES attributes:nil error:&error]) {
|
withIntermediateDirectories:YES attributes:nil error:&error]) {
|
||||||
MPError( error, @"Couldn't create our application support directory." );
|
MPError( error, @"Couldn't create our application support directory." );
|
||||||
PearlRemoveNotificationObserversFrom( self.mainManagedObjectContext );
|
|
||||||
self.mainManagedObjectContext = nil;
|
|
||||||
self.privateManagedObjectContext = nil;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (![self.storeCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:localStoreURL
|
if (![self.storeCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:localStoreURL
|
||||||
@@ -232,9 +258,6 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
|||||||
STORE_OPTIONS
|
STORE_OPTIONS
|
||||||
} error:&error]) {
|
} error:&error]) {
|
||||||
MPError( error, @"Failed to open store." );
|
MPError( error, @"Failed to open store." );
|
||||||
PearlRemoveNotificationObserversFrom( self.mainManagedObjectContext );
|
|
||||||
self.mainManagedObjectContext = nil;
|
|
||||||
self.privateManagedObjectContext = nil;
|
|
||||||
self.storeCorrupted = @YES;
|
self.storeCorrupted = @YES;
|
||||||
[self handleCoordinatorError:error];
|
[self handleCoordinatorError:error];
|
||||||
return;
|
return;
|
||||||
@@ -246,42 +269,14 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
|||||||
self.privateManagedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
|
self.privateManagedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
|
||||||
self.privateManagedObjectContext.persistentStoreCoordinator = self.storeCoordinator;
|
self.privateManagedObjectContext.persistentStoreCoordinator = self.storeCoordinator;
|
||||||
|
|
||||||
self.mainManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
|
|
||||||
self.mainManagedObjectContext.parentContext = self.privateManagedObjectContext;
|
|
||||||
if (@available( iOS 10.0, macOS 10.12, * ))
|
|
||||||
self.mainManagedObjectContext.automaticallyMergesChangesFromParent = YES;
|
|
||||||
else
|
|
||||||
// When privateManagedObjectContext is saved, import the changes into mainManagedObjectContext.
|
|
||||||
PearlAddNotificationObserverTo( self.mainManagedObjectContext, NSManagedObjectContextDidSaveNotification,
|
|
||||||
self.privateManagedObjectContext, nil, ^(NSManagedObjectContext *mainContext, NSNotification *note) {
|
|
||||||
[mainContext performBlock:^{
|
|
||||||
@try {
|
|
||||||
[mainContext mergeChangesFromContextDidSaveNotification:note];
|
|
||||||
}
|
|
||||||
@catch (NSException *exception) {
|
|
||||||
err( @"While merging changes:\n%@", [exception fullDescription] );
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
} );
|
|
||||||
|
|
||||||
#if TARGET_OS_IPHONE
|
|
||||||
PearlAddNotificationObserver( UIApplicationWillResignActiveNotification, UIApp, [NSOperationQueue mainQueue],
|
|
||||||
^(MPAppDelegate_Shared *self, NSNotification *note) {
|
|
||||||
[self.mainManagedObjectContext saveToStore];
|
|
||||||
} );
|
|
||||||
#else
|
|
||||||
PearlAddNotificationObserver( NSApplicationWillResignActiveNotification, NSApp, [NSOperationQueue mainQueue],
|
|
||||||
^(MPAppDelegate_Shared *self, NSNotification *note) {
|
|
||||||
[self.mainManagedObjectContext saveToStore];
|
|
||||||
} );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Perform a data sanity check on the newly loaded store to find and fix any issues.
|
// Perform a data sanity check on the newly loaded store to find and fix any issues.
|
||||||
if ([[MPConfig get].checkInconsistency boolValue])
|
if ([[MPConfig get].checkInconsistency boolValue])
|
||||||
[MPAppDelegate_Shared managedObjectContextPerformBlockAndWait:^(NSManagedObjectContext *context) {
|
[MPAppDelegate_Shared managedObjectContextPerformBlockAndWait:^(NSManagedObjectContext *context) {
|
||||||
[self findAndFixInconsistenciesSaveInContext:context];
|
[self findAndFixInconsistenciesSaveInContext:context];
|
||||||
}];
|
}];
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
[self.storeQueue addOperations:@[ storeOperation ] waitUntilFinished:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)retryCorruptStore {
|
- (void)retryCorruptStore {
|
||||||
@@ -623,7 +618,7 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
|||||||
|
|
||||||
// Find an existing user to update.
|
// Find an existing user to update.
|
||||||
NSError *error = nil;
|
NSError *error = nil;
|
||||||
NSFetchRequest *userFetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPUserEntity class] )];
|
NSFetchRequest *userFetchRequest = [MPUserEntity fetchRequest];
|
||||||
userFetchRequest.predicate = [NSPredicate predicateWithFormat:@"name == %@", @(importUser->fullName)];
|
userFetchRequest.predicate = [NSPredicate predicateWithFormat:@"name == %@", @(importUser->fullName)];
|
||||||
NSArray *users = [context executeFetchRequest:userFetchRequest error:&error];
|
NSArray *users = [context executeFetchRequest:userFetchRequest error:&error];
|
||||||
if (!users)
|
if (!users)
|
||||||
@@ -661,7 +656,7 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
|||||||
MPMarshalledSite *importSite = &importUser->sites[s];
|
MPMarshalledSite *importSite = &importUser->sites[s];
|
||||||
|
|
||||||
// Find an existing site to update.
|
// Find an existing site to update.
|
||||||
NSFetchRequest *siteFetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPSiteEntity class] )];
|
NSFetchRequest *siteFetchRequest = [MPSiteEntity fetchRequest];
|
||||||
siteFetchRequest.predicate = [NSPredicate predicateWithFormat:@"name == %@ AND user == %@", @(importSite->siteName), user];
|
siteFetchRequest.predicate = [NSPredicate predicateWithFormat:@"name == %@ AND user == %@", @(importSite->siteName), user];
|
||||||
NSArray *existingSites = [context executeFetchRequest:siteFetchRequest error:&error];
|
NSArray *existingSites = [context executeFetchRequest:siteFetchRequest error:&error];
|
||||||
if (!existingSites)
|
if (!existingSites)
|
||||||
@@ -735,9 +730,9 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
|||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (NSString *feature in @[MPProductGenerateLogins, MPProductGenerateAnswers, MPProductOSIntegration, MPProductTouchID])
|
for (NSString *feature in @[ MPProductGenerateLogins, MPProductGenerateAnswers, MPProductOSIntegration, MPProductTouchID ])
|
||||||
if ([[MPAppDelegate_Shared get] isFeatureUnlocked:feature])
|
if ([[MPAppDelegate_Shared get] isFeatureUnlocked:feature])
|
||||||
mpw_marshal_data_set_str( digest( strf( @"%@/%@", user.name, feature )).UTF8String, exportFile->data,
|
mpw_marshal_data_set_str( digest( strf( @"%@/%@", user.name, feature ) ).UTF8String, exportFile->data,
|
||||||
"user", "_ext_mpw", feature.UTF8String, nil );
|
"user", "_ext_mpw", feature.UTF8String, nil );
|
||||||
|
|
||||||
MPKey *key = [[MPKey alloc] initForFullName:user.name withMasterPassword:masterPassword];
|
MPKey *key = [[MPKey alloc] initForFullName:user.name withMasterPassword:masterPassword];
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="16096" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="16097.3" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="macosx"/>
|
<deployment identifier="macosx"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="16096"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="16097.3"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<objects>
|
<objects>
|
||||||
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
||||||
@@ -199,6 +199,7 @@
|
|||||||
</attributedString>
|
</attributedString>
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
|
<menuItem isSeparatorItem="YES" id="lhE-aV-1P4"/>
|
||||||
<menuItem title="Diagnostics" id="GSN-f0-q7s">
|
<menuItem title="Diagnostics" id="GSN-f0-q7s">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<connections>
|
<connections>
|
||||||
@@ -216,6 +217,23 @@
|
|||||||
</attributedString>
|
</attributedString>
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
|
<menuItem title="Copy Device Identifier" id="c2c-Vy-iqg">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="copyIdentifier:" target="494" id="dDF-fR-z6h"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Your anonymous device identifier allows support to find your diagnostic reports." enabled="NO" id="xMa-pq-Bqg">
|
||||||
|
<attributedString key="attributedTitle">
|
||||||
|
<fragment content="Your anonymous device identifier allows support to find your diagnostic reports.">
|
||||||
|
<attributes>
|
||||||
|
<font key="NSFont" size="11" name="Helvetica"/>
|
||||||
|
<paragraphStyle key="NSParagraphStyle" alignment="natural" lineBreakMode="wordWrapping" baseWritingDirection="natural" firstLineHeadIndent="8"/>
|
||||||
|
</attributes>
|
||||||
|
</fragment>
|
||||||
|
</attributedString>
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
</menuItem>
|
||||||
</items>
|
</items>
|
||||||
</menu>
|
</menu>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
- (IBAction)showPasswordWindow:(id)sender;
|
- (IBAction)showPasswordWindow:(id)sender;
|
||||||
- (void)setLoginItemEnabled:(BOOL)enabled;
|
- (void)setLoginItemEnabled:(BOOL)enabled;
|
||||||
- (IBAction)togglePreference:(id)sender;
|
- (IBAction)togglePreference:(id)sender;
|
||||||
|
- (IBAction)copyIdentifier:(id)sender;
|
||||||
- (IBAction)newUser:(NSMenuItem *)sender;
|
- (IBAction)newUser:(NSMenuItem *)sender;
|
||||||
- (IBAction)lock:(id)sender;
|
- (IBAction)lock:(id)sender;
|
||||||
- (IBAction)terminate:(id)sender;
|
- (IBAction)terminate:(id)sender;
|
||||||
|
|||||||
@@ -435,6 +435,12 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
|
|||||||
[self updateMenuItems];
|
[self updateMenuItems];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (IBAction)copyIdentifier:(id)sender {
|
||||||
|
[[NSPasteboard generalPasteboard] declareTypes:@[ NSStringPboardType ] owner:nil];
|
||||||
|
if (![[NSPasteboard generalPasteboard] setString:[PearlKeyChain deviceIdentifier] forType:NSPasteboardTypeString])
|
||||||
|
wrn( @"Couldn't copy device identifier to pasteboard." );
|
||||||
|
}
|
||||||
|
|
||||||
- (IBAction)newUser:(NSMenuItem *)sender {
|
- (IBAction)newUser:(NSMenuItem *)sender {
|
||||||
|
|
||||||
NSAlert *alert = [NSAlert new];
|
NSAlert *alert = [NSAlert new];
|
||||||
@@ -646,7 +652,7 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
|
|||||||
self.deleteUserItem.toolTip = mainActiveUser? nil: @"First select the user to delete.";
|
self.deleteUserItem.toolTip = mainActiveUser? nil: @"First select the user to delete.";
|
||||||
|
|
||||||
NSError *error = nil;
|
NSError *error = nil;
|
||||||
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPUserEntity class] )];
|
NSFetchRequest *fetchRequest = [MPUserEntity fetchRequest];
|
||||||
fetchRequest.sortDescriptors = @[ [NSSortDescriptor sortDescriptorWithKey:@"lastUsed" ascending:NO] ];
|
fetchRequest.sortDescriptors = @[ [NSSortDescriptor sortDescriptorWithKey:@"lastUsed" ascending:NO] ];
|
||||||
NSArray *users = [mainContext executeFetchRequest:fetchRequest error:&error];
|
NSArray *users = [mainContext executeFetchRequest:fetchRequest error:&error];
|
||||||
if (!users)
|
if (!users)
|
||||||
|
|||||||
@@ -213,12 +213,12 @@
|
|||||||
|
|
||||||
- (BOOL)generated {
|
- (BOOL)generated {
|
||||||
|
|
||||||
return self.type & MPResultTypeClassTemplate;
|
return (self.type & MPResultTypeClassTemplate) == MPResultTypeClassTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)stored {
|
- (BOOL)stored {
|
||||||
|
|
||||||
return self.type & MPResultTypeClassStateful;
|
return (self.type & MPResultTypeClassStateful) == MPResultTypeClassStateful;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)transient {
|
- (BOOL)transient {
|
||||||
|
|||||||
@@ -628,7 +628,7 @@
|
|||||||
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
||||||
prof_rewind( @"moc" );
|
prof_rewind( @"moc" );
|
||||||
|
|
||||||
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPSiteEntity class] )];
|
NSFetchRequest *fetchRequest = [MPSiteEntity fetchRequest];
|
||||||
fetchRequest.sortDescriptors = @[ [[NSSortDescriptor alloc] initWithKey:@"lastUsed" ascending:NO] ];
|
fetchRequest.sortDescriptors = @[ [[NSSortDescriptor alloc] initWithKey:@"lastUsed" ascending:NO] ];
|
||||||
fetchRequest.predicate =
|
fetchRequest.predicate =
|
||||||
[NSPredicate predicateWithFormat:@"name LIKE[cd] %@ AND user == %@", queryPattern, [MPMacAppDelegate get].activeUserOID];
|
[NSPredicate predicateWithFormat:@"name LIKE[cd] %@ AND user == %@", queryPattern, [MPMacAppDelegate get].activeUserOID];
|
||||||
|
|||||||
@@ -423,6 +423,7 @@ typedef NS_OPTIONS( NSUInteger, MPPasswordsTips ) {
|
|||||||
fetchRequest.sortDescriptors = @[
|
fetchRequest.sortDescriptors = @[
|
||||||
[[NSSortDescriptor alloc] initWithKey:NSStringFromSelector( @selector( lastUsed ) ) ascending:NO]
|
[[NSSortDescriptor alloc] initWithKey:NSStringFromSelector( @selector( lastUsed ) ) ascending:NO]
|
||||||
];
|
];
|
||||||
|
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"user == %@", [MPiOSAppDelegate get].activeUserOID];
|
||||||
|
|
||||||
(self.fetchedResultsController = [[NSFetchedResultsController alloc]
|
(self.fetchedResultsController = [[NSFetchedResultsController alloc]
|
||||||
initWithFetchRequest:fetchRequest managedObjectContext:mainContext
|
initWithFetchRequest:fetchRequest managedObjectContext:mainContext
|
||||||
|
|||||||
@@ -696,7 +696,7 @@ referenceSizeForFooterInSection:(NSInteger)section {
|
|||||||
|
|
||||||
[self afterUpdatesMainQueue:^{
|
[self afterUpdatesMainQueue:^{
|
||||||
if (![MPiOSAppDelegate managedObjectContextForMainThreadPerformBlockAndWait:^(NSManagedObjectContext *mainContext) {
|
if (![MPiOSAppDelegate managedObjectContextForMainThreadPerformBlockAndWait:^(NSManagedObjectContext *mainContext) {
|
||||||
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPUserEntity class] )];
|
NSFetchRequest *fetchRequest = [MPUserEntity fetchRequest];
|
||||||
fetchRequest.sortDescriptors = @[
|
fetchRequest.sortDescriptors = @[
|
||||||
[NSSortDescriptor sortDescriptorWithKey:NSStringFromSelector( @selector( lastUsed ) ) ascending:NO]
|
[NSSortDescriptor sortDescriptorWithKey:NSStringFromSelector( @selector( lastUsed ) ) ascending:NO]
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -475,8 +475,7 @@ MP_LIBS_END
|
|||||||
for (NSURLQueryItem *item in [NSURLComponents componentsWithString:[url absoluteString]].queryItems)
|
for (NSURLQueryItem *item in [NSURLComponents componentsWithString:[url absoluteString]].queryItems)
|
||||||
if ([item.name isEqualToString:@"fullName"]) {
|
if ([item.name isEqualToString:@"fullName"]) {
|
||||||
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
||||||
NSFetchRequest
|
NSFetchRequest *fetchRequest = [MPUserEntity fetchRequest];
|
||||||
*fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPUserEntity class] )];
|
|
||||||
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"name == %@", item.value];
|
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"name == %@", item.value];
|
||||||
NSArray *users = [context executeFetchRequest:fetchRequest error:nil];
|
NSArray *users = [context executeFetchRequest:fetchRequest error:nil];
|
||||||
[self migrateFor:users.firstObject];
|
[self migrateFor:users.firstObject];
|
||||||
|
|||||||
Reference in New Issue
Block a user