From be5889c5b13fd585af7b4616d2e2731e407dfb7d Mon Sep 17 00:00:00 2001 From: michael starke Date: Wed, 27 Aug 2014 19:43:03 +0200 Subject: [PATCH] Search criteriy is objetified. Can be stored and saved in preferences. This is a first step to enable saved searches inside the Keepass database via use of custom data. --- HNHUi | 2 +- MacPass/ContextBar.xib | 27 ++++++--- MacPass/MPContextBarViewController.h | 1 + MacPass/MPContextBarViewController.m | 32 ++++++++++- MacPass/MPDocument+Search.h | 4 +- MacPass/MPDocument+Search.m | 81 ++++++++++++++------------- MacPass/MPDocument.h | 3 +- MacPass/MPDocument.m | 4 ++ MacPass/MPEntrySearchContext.h | 25 +++++++-- MacPass/MPEntrySearchContext.m | 45 ++++++++++++--- MacPass/MPSettingsHelper.m | 16 +++++- MacPass/OutlineView.xib | 4 +- MacPass/en.lproj/Localizable.strings | Bin 10544 -> 10806 bytes 13 files changed, 170 insertions(+), 74 deletions(-) diff --git a/HNHUi b/HNHUi index 330a06a8..08252931 160000 --- a/HNHUi +++ b/HNHUi @@ -1 +1 @@ -Subproject commit 330a06a8316d889eb4aae97a4c7300a6131e392b +Subproject commit 08252931b9a9cae3f2947adad34def666071f23f diff --git a/MacPass/ContextBar.xib b/MacPass/ContextBar.xib index 04dffb30..5621f982 100644 --- a/MacPass/ContextBar.xib +++ b/MacPass/ContextBar.xib @@ -7,7 +7,6 @@ - @@ -15,6 +14,7 @@ + @@ -102,31 +102,38 @@ - + + + + + + + + + - + + - + - @@ -135,6 +142,8 @@ + + diff --git a/MacPass/MPContextBarViewController.h b/MacPass/MPContextBarViewController.h index 4eeadb6a..0ed45c0d 100644 --- a/MacPass/MPContextBarViewController.h +++ b/MacPass/MPContextBarViewController.h @@ -20,6 +20,7 @@ @property (weak) IBOutlet NSButton *urlButton; @property (weak) IBOutlet NSButton *notesButton; @property (weak) IBOutlet NSButton *duplicatePasswordsButton; +@property (weak) IBOutlet NSPopUpButton *specialFilterPopUpButton; - (void)registerNotificationsForDocument:(MPDocument *)document; diff --git a/MacPass/MPContextBarViewController.m b/MacPass/MPContextBarViewController.m index 75538098..66a1163f 100644 --- a/MacPass/MPContextBarViewController.m +++ b/MacPass/MPContextBarViewController.m @@ -70,12 +70,24 @@ typedef NS_ENUM(NSUInteger, MPContextTab) { self.emptyTrashButton.textColor = [NSColor whiteColor]; - NSInteger tags[] = { MPEntrySearchTitles, MPEntrySearchUsernames, MPEntrySearchPasswords, MPEntrySearchNotes, MPEntrySearchUrls, MPEntrySearchDoublePasswords }; - NSArray *buttons = @[self.titleButton, self.usernameButton, self.passwordButton, self.notesButton, self.urlButton, self.duplicatePasswordsButton ]; + NSInteger tags[] = { MPEntrySearchTitles, MPEntrySearchUsernames, MPEntrySearchPasswords, MPEntrySearchNotes, MPEntrySearchUrls }; + NSArray *buttons = @[self.titleButton, self.usernameButton, self.passwordButton, self.notesButton, self.urlButton ]; for(NSUInteger iIndex = 0; iIndex < [buttons count]; iIndex++) { [buttons[iIndex] setAction:@selector(toggleSearchFlags:)]; [buttons[iIndex] setTag:tags[iIndex]]; } + NSInteger specialTags[] = { MPEntrySearchDoublePasswords, MPEntrySearchExpiredEntries }; + NSArray *titles = @[ NSLocalizedString(@"SEARCH_DUPLICATE_PASSWORDS", ""), NSLocalizedString(@"SEARCH_EXPIRED_ENTRIES", "") ]; + NSMenu *specialMenu = [[NSMenu alloc] initWithTitle:@"Special Filters Menu"]; + [specialMenu addItemWithTitle:NSLocalizedString(@"SELECT_FILTER_WITH_DOTS", "") action:NULL keyEquivalent:@""]; + [[specialMenu itemAtIndex:0] setEnabled:NO]; + [[specialMenu itemAtIndex:0] setTag:MPEntrySearchNone]; + for(NSInteger iIndex = 0; iIndex < [titles count]; iIndex++) { + NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:titles[iIndex] action:@selector(toggleSearchFlags:) keyEquivalent:@""]; + [item setTag:specialTags[iIndex]]; + [specialMenu addItem:item]; + } + [self.specialFilterPopUpButton setMenu:specialMenu]; [self _updateFilterButtons]; } @@ -131,6 +143,22 @@ typedef NS_ENUM(NSUInteger, MPContextTab) { [self.titleButton setState:HNHStateForBool(MPTestFlagInOptions(MPEntrySearchTitles, currentFlags))]; [self.urlButton setState:HNHStateForBool(MPTestFlagInOptions(MPEntrySearchUrls, currentFlags))]; [self.usernameButton setState:HNHStateForBool(MPTestFlagInOptions(MPEntrySearchUsernames, currentFlags))]; + NSInteger selectedTag = MPEntrySearchNone; + for(NSMenuItem *item in [[self.specialFilterPopUpButton menu] itemArray]) { + MPEntrySearchFlags flag = [item tag]; + if(flag == MPEntrySearchNone) { + [item setState:NSOffState]; + [item setEnabled:NO]; + } + else { + BOOL isActive = MPTestFlagInOptions(flag, currentFlags); + if(isActive) { + selectedTag = flag; + } + [item setState:HNHStateForBool(isActive)]; + } + } + [self.specialFilterPopUpButton selectItemWithTag:selectedTag]; } @end diff --git a/MacPass/MPDocument+Search.h b/MacPass/MPDocument+Search.h index f290c4f7..ca211af2 100644 --- a/MacPass/MPDocument+Search.h +++ b/MacPass/MPDocument+Search.h @@ -25,6 +25,8 @@ FOUNDATION_EXTERN NSString *const kMPDocumentSearchResultsKey; @interface MPDocument (Search) +- (void)enterSearchWithContext:(MPEntrySearchContext *)context; + /* Should be called by the NSSearchTextField to update the search string */ - (IBAction)updateSearch:(id)sender; /* exits searching mode */ @@ -32,6 +34,4 @@ FOUNDATION_EXTERN NSString *const kMPDocumentSearchResultsKey; /* called by the filter toggle buttons */ - (IBAction)toggleSearchFlags:(id)sender; -- (NSArray *)entriesMatchingSearch:(MPEntrySearchContext *)search; - @end diff --git a/MacPass/MPDocument+Search.m b/MacPass/MPDocument+Search.m index 078520fc..288016dc 100644 --- a/MacPass/MPDocument+Search.m +++ b/MacPass/MPDocument+Search.m @@ -12,6 +12,7 @@ #import "KPKGroup.h" #import "KPKEntry.h" +#import "KPKTimeInfo.h" #import "MPFlagsHelper.h" @@ -26,25 +27,30 @@ NSString *const kMPDocumentSearchResultsKey = @"kMPDocumentSearchResul @implementation MPDocument (Search) -#pragma mark Actions -- (void)performFindPanelAction:(id)sender { - self.hasSearch = YES; +- (void)enterSearchWithContext:(MPEntrySearchContext *)context { /* the search context is loaded via defaults */ - self.searchContext = [[MPEntrySearchContext alloc] init]; + self.searchContext = context; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateSearch:) name:NSUndoManagerDidRedoChangeNotification object:self.undoManager]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateSearch:) name:NSUndoManagerDidUndoChangeNotification object:self.undoManager]; [[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidEnterSearchNotification object:self]; [self updateSearch:self]; } +#pragma mark Actions + +- (void)performFindPanelAction:(id)sender { + [self enterSearchWithContext:[MPEntrySearchContext userContext]]; +} + - (void)updateSearch:(id)sender { + if(NO == self.hasSearch) { + [self enterSearchWithContext:[MPEntrySearchContext userContext]]; + return; // We get called back! + } MPDocumentWindowController *windowController = [self windowControllers][0]; NSString *searchString = [windowController.searchField stringValue]; - /* Update the search string */ - self.searchContext = [[MPEntrySearchContext alloc] initWithString:searchString flags:self.searchContext.searchFlags]; - if(NO == self.hasSearch) { - [[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidEnterSearchNotification object:self]; - } - self.hasSearch = YES; + self.searchContext.searchString = searchString; MPDocument __weak *weakSelf = self; dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async(backgroundQueue, ^{ @@ -57,10 +63,9 @@ NSString *const kMPDocumentSearchResultsKey = @"kMPDocumentSearchResul } - (void)exitSearch:(id)sender { + [[NSNotificationCenter defaultCenter] removeObserver:self name:NSUndoManagerDidUndoChangeNotification object:self.undoManager]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:NSUndoManagerDidRedoChangeNotification object:self.undoManager]; self.searchContext = nil; - /*self.searchString = nil; - self.hasSearch = NO; - */ [[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidExitSearchNotification object:self]; } @@ -75,29 +80,30 @@ NSString *const kMPDocumentSearchResultsKey = @"kMPDocumentSearchResul MPEntrySearchFlags toggleFlag = [sender tag]; MPEntrySearchFlags newFlags = MPEntrySearchNone; BOOL isDoublePasswordFlag = (toggleFlag == MPEntrySearchDoublePasswords); + BOOL isExpiredFlag = (toggleFlag == MPEntrySearchExpiredEntries); NSButton *button = sender; switch([button state]) { case NSOffState: toggleFlag ^= MPEntrySearchAllFlags; - newFlags = isDoublePasswordFlag ? oldFlags : (self.activeFlags & toggleFlag); + newFlags = isDoublePasswordFlag ? oldFlags : (self.searchContext.searchFlags & toggleFlag); break; case NSOnState: - if(isDoublePasswordFlag) { - oldFlags = self.activeFlags; - newFlags = MPEntrySearchDoublePasswords; + if(isDoublePasswordFlag || isExpiredFlag ) { + oldFlags = self.searchContext.searchFlags; + newFlags = toggleFlag;//MPEntrySearchDoublePasswords; } else { /* always mask the double passwords in case another button was pressed */ - self.activeFlags &= (MPEntrySearchDoublePasswords ^ MPEntrySearchAllFlags); - newFlags = self.activeFlags | toggleFlag; + self.searchContext.searchFlags &= ((MPEntrySearchDoublePasswords | MPEntrySearchExpiredEntries) ^ MPEntrySearchAllFlags); + newFlags = self.searchContext.searchFlags | toggleFlag; } break; default: NSAssert(NO, @"Internal state is inconsistent"); return; } - if(newFlags != self.activeFlags) { - self.activeFlags = (newFlags == MPEntrySearchNone) ? MPEntrySearchTitles : newFlags; + if(newFlags != self.searchContext.searchFlags) { + self.searchContext.searchFlags = (newFlags == MPEntrySearchNone) ? MPEntrySearchTitles : newFlags; [[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidChangeSearchFlags object:self]; [self updateSearch:self]; } @@ -110,7 +116,7 @@ NSString *const kMPDocumentSearchResultsKey = @"kMPDocumentSearchResul #pragma mark Search - (NSArray *)_findEntriesMatchingCurrentSearch { /* Filter double passwords */ - if(MPTestFlagInOptions(MPEntrySearchDoublePasswords, self.activeFlags)) { + if(MPTestFlagInOptions(MPEntrySearchDoublePasswords, self.searchContext.searchFlags)) { __block NSMutableDictionary *passwordToEntryMap = [[NSMutableDictionary alloc] initWithCapacity:100]; /* Build up a usage map */ [[self.root childEntries] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { @@ -136,8 +142,15 @@ NSString *const kMPDocumentSearchResultsKey = @"kMPDocumentSearchResul }]; return doublePasswords; } + if(MPTestFlagInOptions(MPEntrySearchExpiredEntries, self.searchContext.searchFlags)) { + NSPredicate *expiredPredicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) { + KPKNode *node = evaluatedObject; + return node.timeInfo.isExpired; + }]; + return [[self.root childEntries] filteredArrayUsingPredicate:expiredPredicate]; + } /* Filter using predicates */ - NSArray *predicates = [self _filterPredicatesWithString:self.searchString]; + NSArray *predicates = [self _filterPredicatesWithString:self.searchContext.searchString]; if(predicates) { NSPredicate *fullFilter = [NSCompoundPredicate orPredicateWithSubpredicates:predicates]; return [[self.root childEntries] filteredArrayUsingPredicate:fullFilter]; @@ -146,34 +159,22 @@ NSString *const kMPDocumentSearchResultsKey = @"kMPDocumentSearchResul return [self.root childEntries]; } -- (NSArray *)optionsEnabledInMode:(MPEntrySearchFlags)mode { - NSArray *allOptions = @[ @(MPEntrySearchUrls), @(MPEntrySearchUsernames), - @(MPEntrySearchTitles), @(MPEntrySearchPasswords) , - @(MPEntrySearchNotes), @(MPEntrySearchDoublePasswords) ]; - - NSIndexSet *indexes = [allOptions indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) { - MPEntrySearchFlags flag = [obj integerValue]; - return MPTestFlagInOptions(flag, mode); - }]; - return [allOptions objectsAtIndexes:indexes]; -} - - (NSArray *)_filterPredicatesWithString:(NSString *)string{ NSMutableArray *prediactes = [[NSMutableArray alloc] initWithCapacity:4]; - if(MPTestFlagInOptions(MPEntrySearchTitles, self.activeFlags)) { + if(MPTestFlagInOptions(MPEntrySearchTitles, self.searchContext.searchFlags)) { [prediactes addObject:[NSPredicate predicateWithFormat:@"SELF.title CONTAINS[cd] %@", string]]; } - if(MPTestFlagInOptions(MPEntrySearchUsernames, self.activeFlags)) { + if(MPTestFlagInOptions(MPEntrySearchUsernames, self.searchContext.searchFlags)) { [prediactes addObject:[NSPredicate predicateWithFormat:@"SELF.username CONTAINS[cd] %@", string]]; } - if(MPTestFlagInOptions(MPEntrySearchUrls, self.activeFlags)) { + if(MPTestFlagInOptions(MPEntrySearchUrls, self.searchContext.searchFlags)) { [prediactes addObject:[NSPredicate predicateWithFormat:@"SELF.url CONTAINS[cd] %@", string]]; } - if(MPTestFlagInOptions(MPEntrySearchPasswords, self.activeFlags)) { + if(MPTestFlagInOptions(MPEntrySearchPasswords, self.searchContext.searchFlags)) { [prediactes addObject:[NSPredicate predicateWithFormat:@"SELF.password CONTAINS[cd] %@", string]]; } - if(MPTestFlagInOptions(MPEntrySearchNotes, self.activeFlags)) { + if(MPTestFlagInOptions(MPEntrySearchNotes, self.searchContext.searchFlags)) { [prediactes addObject:[NSPredicate predicateWithFormat:@"SELF.notes CONTAINS[cd] %@", string]]; } return prediactes; diff --git a/MacPass/MPDocument.h b/MacPass/MPDocument.h index 443d9a7a..26a66bcd 100644 --- a/MacPass/MPDocument.h +++ b/MacPass/MPDocument.h @@ -61,6 +61,7 @@ APPKIT_EXTERN NSString *const MPDocumentGroupKey; @interface MPDocument : NSDocument + @property (nonatomic, readonly, assign) BOOL encrypted; @property (nonatomic, readonly, assign) NSUInteger unlockCount; // Amount of times the Document was unlocked; @@ -85,7 +86,7 @@ APPKIT_EXTERN NSString *const MPDocumentGroupKey; /* Search - see MPDocument+Search for further details */ -@property (nonatomic, readonly, assign) BOOL hasSearch; +@property (nonatomic, readonly) BOOL hasSearch; @property (nonatomic, copy) MPEntrySearchContext *searchContext; @property (nonatomic, strong) NSArray *searchResult; diff --git a/MacPass/MPDocument.m b/MacPass/MPDocument.m index 51843699..a0e0106b 100644 --- a/MacPass/MPDocument.m +++ b/MacPass/MPDocument.m @@ -354,6 +354,10 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey return [self findGroup:self.tree.metaData.entryTemplatesGroup]; } +- (BOOL)hasSearch { + return self.searchContext != nil; +} + - (void)setTrash:(KPKGroup *)trash { if(self.useTrash) { if(![self.tree.metaData.recycleBinUuid isEqual:trash.uuid]) { diff --git a/MacPass/MPEntrySearchContext.h b/MacPass/MPEntrySearchContext.h index 8f1c7ef2..370d9a8d 100644 --- a/MacPass/MPEntrySearchContext.h +++ b/MacPass/MPEntrySearchContext.h @@ -16,8 +16,11 @@ typedef NS_OPTIONS(NSUInteger, MPEntrySearchFlags) { MPEntrySearchPasswords = (1<<3), MPEntrySearchNotes = (1<<4), MPEntrySearchAllAttributes = (1<<5), - MPEntrySearchDoublePasswords = (1<<6), // Unused in GUI for now - MPEntrySearchExpiredEntries = (1<<7), // Unused for now + /* The following two flags should be used like enums. + They are not intented to be used in conjunktion with any other flag */ + MPEntrySearchDoublePasswords = (1<<6), + MPEntrySearchExpiredEntries = (1<<7), + /* All search flags that are combineable combined */ MPEntrySearchAllFlags = (MPEntrySearchDoublePasswords | MPEntrySearchExpiredEntries | MPEntrySearchNotes | @@ -30,12 +33,24 @@ typedef NS_OPTIONS(NSUInteger, MPEntrySearchFlags) { /* Wrap serach criteria to be able to store them */ -@interface MPEntrySearchContext : NSObject +@interface MPEntrySearchContext : NSObject +/** + * Returns a default search context initalized with sane values. + * + * @return The default search context + */ + (instancetype)defaultContext; +/** + * Returns the search context using the users preferences. If none are found, a default context is created + * + * @return Search context configured to the users data. If nothing is configures, defaultContext is used + */ ++ (instancetype)userContext; + - (instancetype)initWithString:(NSString *)searchString flags:(MPEntrySearchFlags)flags; -@property (readonly, assign) NSInteger searchFlags; -@property (readonly, copy) NSString *searchString; +@property (nonatomic, assign) NSInteger searchFlags; +@property (nonatomic, copy) NSString *searchString; @end diff --git a/MacPass/MPEntrySearchContext.m b/MacPass/MPEntrySearchContext.m index 19fabc54..56a15fb0 100644 --- a/MacPass/MPEntrySearchContext.m +++ b/MacPass/MPEntrySearchContext.m @@ -7,13 +7,7 @@ // #import "MPEntrySearchContext.h" - -@interface MPEntrySearchContext () - -@property (assign) NSInteger searchFlags; -@property (copy) NSString *searchString; - -@end +#import "MPSettingsHelper.h" @implementation MPEntrySearchContext @@ -22,11 +16,19 @@ } + (instancetype)defaultContext { - + return [[MPEntrySearchContext alloc] init]; +} + ++ (instancetype)userContext { + NSData *data = [[NSUserDefaults standardUserDefaults] dataForKey:kMPSettingsKeyEntrySearchFilterContext]; + if(data) { + return [NSKeyedUnarchiver unarchiveObjectWithData:data]; + } + return [self defaultContext]; } - (instancetype)init { - self = [self initWithString:nil flags:MPEntrySearchNone]; + self = [self initWithString:nil flags:MPEntrySearchTitles|MPEntrySearchUsernames]; return self; } @@ -40,6 +42,7 @@ } +#pragma mark NSSecureCoding - (void)encodeWithCoder:(NSCoder *)aCoder { [aCoder encodeInteger:self.searchFlags forKey:NSStringFromSelector(@selector(searchFlags))]; [aCoder encodeObject:self.searchString forKey:NSStringFromSelector(@selector(searchString))]; @@ -52,4 +55,28 @@ return self; } +#pragma mark NSCopying +- (id)copyWithZone:(NSZone *)zone { + return [[MPEntrySearchContext alloc] initWithString:self.searchString flags:self.searchFlags]; +} + +- (void)setSearchFlags:(NSInteger)searchFlags { + if(_searchFlags != searchFlags) { + _searchFlags = searchFlags; + [self _updatePreferences]; + } +} + +- (void)setSearchString:(NSString *)searchString { + if(![_searchString isEqualToString:searchString]) { + _searchString = [searchString copy]; + [self _updatePreferences]; + } +} + +- (void )_updatePreferences { + NSData *myData = [NSKeyedArchiver archivedDataWithRootObject:self]; + [[NSUserDefaults standardUserDefaults] setObject:myData forKey:kMPSettingsKeyEntrySearchFilterContext]; + [[NSUserDefaults standardUserDefaults] synchronize]; +} @end diff --git a/MacPass/MPSettingsHelper.m b/MacPass/MPSettingsHelper.m index 3e6240ed..1e35260e 100644 --- a/MacPass/MPSettingsHelper.m +++ b/MacPass/MPSettingsHelper.m @@ -49,7 +49,6 @@ NSString *const kMPSettingsKeyPasswordCharacterFlags = @"Passwo NSString *const kMPSettingsKeyPasswordUseCustomString = @"PasswordUseCustomString"; NSString *const kMPSettingsKeyPasswordCustomString = @"PasswordCustomString"; -/* Depricated */ NSString *const kMPSettingsKeyDoubleClickURLAction = @"DoubleClickURLAction"; NSString *const kMPSettingsKeyDoubleClickTitleAction = @"DoubleClickTitleAction"; @@ -58,6 +57,7 @@ NSString *const kMPDeprecatedSettingsKeyRememberKeyFilesForDatabases = @"kM NSString *const kMPDeprecatedSettingsKeyLastDatabasePath = @"MPLastDatabasePath"; NSString *const kMPDeprecatedSettingsKeyDocumentsAutotypeFixNoteWasShown = @"DocumentsAutotypeFixNoteWasShown"; NSString *const kMPDeprecatedSettingsKeyDoubleClickURLToLaunch = @"DoubleClickURLToLaunch"; +NSString *const kMPDeprecatedSettingsKeyEntrySearchFilterMode = @"EntrySearchFilterMode"; @implementation MPSettingsHelper @@ -68,6 +68,7 @@ NSString *const kMPDeprecatedSettingsKeyDoubleClickURLToLaunch = @"Do + (void)migrateDefaults { [self _fixEntryTableSortDescriptors]; [self _migrateURLDoubleClickPreferences]; + [self _migrateEntrySearchFlags]; [self _removeDeprecatedValues]; } @@ -97,7 +98,6 @@ NSString *const kMPDeprecatedSettingsKeyDoubleClickURLToLaunch = @"Do kMPSettingsKeyLegacyHideUsername: @NO, kMPSettingsKeyRememberKeyFilesForDatabases: @NO, kMPSettingsKeySendCommandForControlKey: @YES, - kMPSettingsKeyEntrySearchFilterMode: @0, kMPSettingsKeyEnableGlobalAutotype: @NO, kMPSettingsKeyEnableQuicklookPreview: @NO, kMPSettingsKeyCopyGeneratedPasswordToClipboard: @NO, @@ -120,7 +120,8 @@ NSString *const kMPDeprecatedSettingsKeyDoubleClickURLToLaunch = @"Do deprecatedSettings = @[ kMPDeprecatedSettingsKeyRememberKeyFilesForDatabases, kMPDeprecatedSettingsKeyLastDatabasePath, kMPDeprecatedSettingsKeyDocumentsAutotypeFixNoteWasShown, - kMPDeprecatedSettingsKeyDoubleClickURLToLaunch ]; + kMPDeprecatedSettingsKeyDoubleClickURLToLaunch, + kMPDeprecatedSettingsKeyEntrySearchFilterMode]; }); return deprecatedSettings; } @@ -160,4 +161,13 @@ NSString *const kMPDeprecatedSettingsKeyDoubleClickURLToLaunch = @"Do } } ++ (void)_migrateEntrySearchFlags { + NSInteger flags = [[NSUserDefaults standardUserDefaults] integerForKey:kMPDeprecatedSettingsKeyEntrySearchFilterMode]; + if(flags != 0) { + MPEntrySearchContext *context = [[MPEntrySearchContext alloc] initWithString:nil flags:flags]; + NSData *contextData = [NSKeyedArchiver archivedDataWithRootObject:context]; + [[NSUserDefaults standardUserDefaults] setObject:contextData forKey:kMPSettingsKeyEntrySearchFilterContext]; + } +} + @end diff --git a/MacPass/OutlineView.xib b/MacPass/OutlineView.xib index 1de84ec2..1ef91d5a 100644 --- a/MacPass/OutlineView.xib +++ b/MacPass/OutlineView.xib @@ -1,8 +1,8 @@ - + - + diff --git a/MacPass/en.lproj/Localizable.strings b/MacPass/en.lproj/Localizable.strings index 6ee18d0d7e343669ab4a521896a558000b494586..6d7f7e5d1a2ece28e7a5f78dacd819b025c40bbb 100644 GIT binary patch delta 145 zcmdlGv@K-A18!L*hF}I)21kY<24@BjhIj@ShERq81|J4bAm4HFL_vQH6|M{sKoy=q z9j**6llvv5^<5b%7z!9N8HyNE8B!RO7_1q%fF#IVA0T#S2mzYw2GrpLWVtc~O)lhD W