From 6f37b98d92ec5b70f95db940429cb972829ca41e Mon Sep 17 00:00:00 2001 From: Michael Starke Date: Fri, 9 Mar 2018 17:43:31 +0100 Subject: [PATCH] =?UTF-8?q?Added=20=E2=80=9Ceverywhere=E2=80=9D=20search?= =?UTF-8?q?=20option?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MacPass/Base.lproj/ContextBar.xib | 18 ++++++++++++---- MacPass/MPContextBarViewController.h | 1 + MacPass/MPContextBarViewController.m | 9 ++++---- MacPass/MPDocument+Search.m | 32 ++++++++++++++++++++++------ MacPass/MPEntrySearchContext.h | 12 +++++------ MacPass/MPEntrySearchContext.m | 8 +++---- 6 files changed, 55 insertions(+), 25 deletions(-) diff --git a/MacPass/Base.lproj/ContextBar.xib b/MacPass/Base.lproj/ContextBar.xib index abfc710e..9e442ae4 100644 --- a/MacPass/Base.lproj/ContextBar.xib +++ b/MacPass/Base.lproj/ContextBar.xib @@ -1,14 +1,15 @@ - + - + + @@ -108,18 +109,27 @@ + - + + + @@ -244,7 +254,7 @@ - + diff --git a/MacPass/MPContextBarViewController.h b/MacPass/MPContextBarViewController.h index 7f031e1e..1c8a842a 100644 --- a/MacPass/MPContextBarViewController.h +++ b/MacPass/MPContextBarViewController.h @@ -35,6 +35,7 @@ @property (weak) IBOutlet NSButton *notesButton; @property (weak) IBOutlet NSButton *duplicatePasswordsButton; @property (weak) IBOutlet NSPopUpButton *specialFilterPopUpButton; +@property (weak) IBOutlet NSButton *everywhereButton; - (void)registerNotificationsForDocument:(MPDocument *)document; diff --git a/MacPass/MPContextBarViewController.m b/MacPass/MPContextBarViewController.m index d5ea5dc3..62373cb4 100644 --- a/MacPass/MPContextBarViewController.m +++ b/MacPass/MPContextBarViewController.m @@ -85,8 +85,8 @@ typedef NS_ENUM(NSUInteger, MPContextTab) { [self.view bind:NSSelectedIndexBinding toObject:self withKeyPath:NSStringFromSelector(@selector(activeTab)) options:nil]; /* Setup Filter Bar buttons and menu */ - NSInteger tags[] = { MPEntrySearchTitles, MPEntrySearchUsernames, MPEntrySearchPasswords, MPEntrySearchNotes, MPEntrySearchUrls }; - NSArray *buttons = @[self.titleButton, self.usernameButton, self.passwordButton, self.notesButton, self.urlButton ]; + NSInteger tags[] = { MPEntrySearchTitles, MPEntrySearchUsernames, MPEntrySearchPasswords, MPEntrySearchNotes, MPEntrySearchUrls, MPEntrySearchAllAttributes }; + NSArray *buttons = @[self.titleButton, self.usernameButton, self.passwordButton, self.notesButton, self.urlButton, self.everywhereButton ]; for(NSUInteger iIndex = 0; iIndex < buttons.count; iIndex++) { buttons[iIndex].action = @selector(toggleSearchFlags:); buttons[iIndex].tag = tags[iIndex]; @@ -103,7 +103,7 @@ typedef NS_ENUM(NSUInteger, MPContextTab) { item.tag = specialTags[iIndex]; [specialMenu addItem:item]; } - [self.specialFilterPopUpButton setMenu:specialMenu]; + self.specialFilterPopUpButton.menu = specialMenu; [self _updateFilterButtons]; } @@ -154,8 +154,9 @@ typedef NS_ENUM(NSUInteger, MPContextTab) { self.titleButton.state = HNHUIStateForBool(MPIsFlagSetInOptions(MPEntrySearchTitles, currentFlags)); self.urlButton.state = HNHUIStateForBool(MPIsFlagSetInOptions(MPEntrySearchUrls, currentFlags)); self.usernameButton.state = HNHUIStateForBool(MPIsFlagSetInOptions(MPEntrySearchUsernames, currentFlags)); + self.everywhereButton.state = HNHUIStateForBool(MPIsFlagSetInOptions(MPEntrySearchAllAttributes, currentFlags)); NSInteger selectedTag = MPEntrySearchNone; - for(NSMenuItem *item in [[self.specialFilterPopUpButton menu] itemArray]) { + for(NSMenuItem *item in self.specialFilterPopUpButton.menu.itemArray) { MPEntrySearchFlags flag = item.tag; if(flag == MPEntrySearchNone) { item.state = NSOffState; diff --git a/MacPass/MPDocument+Search.m b/MacPass/MPDocument+Search.m index 8e660e6a..e491f27a 100644 --- a/MacPass/MPDocument+Search.m +++ b/MacPass/MPDocument+Search.m @@ -65,16 +65,16 @@ NSString *const kMPDocumentSearchResultsKey = @"kMPDocumentSearchResul dispatch_async(backgroundQueue, ^{ NSArray *results = [weakSelf _findEntriesMatchingCurrentSearch]; dispatch_sync(dispatch_get_main_queue(), ^{ - [[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidChangeSearchResults object:weakSelf userInfo:@{ kMPDocumentSearchResultsKey: results }]; + [NSNotificationCenter.defaultCenter postNotificationName:MPDocumentDidChangeSearchResults object:weakSelf userInfo:@{ kMPDocumentSearchResultsKey: results }]; }); }); } - (void)exitSearch:(id)sender { - [[NSNotificationCenter defaultCenter] removeObserver:self name:NSUndoManagerDidUndoChangeNotification object:self.undoManager]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:NSUndoManagerDidRedoChangeNotification object:self.undoManager]; + [NSNotificationCenter.defaultCenter removeObserver:self name:NSUndoManagerDidUndoChangeNotification object:self.undoManager]; + [NSNotificationCenter.defaultCenter removeObserver:self name:NSUndoManagerDidRedoChangeNotification object:self.undoManager]; self.searchContext = nil; - [[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidExitSearchNotification object:self]; + [NSNotificationCenter.defaultCenter postNotificationName:MPDocumentDidExitSearchNotification object:self]; } - (void)toggleSearchFlags:(id)sender { @@ -88,7 +88,7 @@ NSString *const kMPDocumentSearchResultsKey = @"kMPDocumentSearchResul MPEntrySearchFlags newFlags = MPEntrySearchNone; BOOL isSingleFlag = toggleFlag & MPEntrySearchSingleFlags; NSButton *button = sender; - switch([button state]) { + switch(button.state) { case NSOffState: toggleFlag ^= MPEntrySearchAllCombineableFlags; newFlags = isSingleFlag ? MPEntrySearchNone : (self.searchContext.searchFlags & toggleFlag); @@ -109,7 +109,7 @@ NSString *const kMPDocumentSearchResultsKey = @"kMPDocumentSearchResul } if(newFlags != self.searchContext.searchFlags) { self.searchContext.searchFlags = (newFlags == MPEntrySearchNone) ? MPEntrySearchTitles : newFlags; - [[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidChangeSearchFlags object:self]; + [NSNotificationCenter.defaultCenter postNotificationName:MPDocumentDidChangeSearchFlags object:self]; [self updateSearch:self]; } } @@ -166,6 +166,9 @@ NSString *const kMPDocumentSearchResultsKey = @"kMPDocumentSearchResul - (NSArray *)_filterPredicatesWithString:(NSString *)string{ NSMutableArray *prediactes = [[NSMutableArray alloc] initWithCapacity:4]; + BOOL searchInAllAttributes = MPIsFlagSetInOptions(MPEntrySearchAllAttributes, self.searchContext.searchFlags); + + if(MPIsFlagSetInOptions(MPEntrySearchTitles, self.searchContext.searchFlags)) { [prediactes addObject:[NSPredicate predicateWithFormat:@"SELF.title CONTAINS[cd] %@", string]]; } @@ -181,6 +184,23 @@ NSString *const kMPDocumentSearchResultsKey = @"kMPDocumentSearchResul if(MPIsFlagSetInOptions(MPEntrySearchNotes, self.searchContext.searchFlags)) { [prediactes addObject:[NSPredicate predicateWithFormat:@"SELF.notes CONTAINS[cd] %@", string]]; } + if(searchInAllAttributes) { + [prediactes addObject:[NSPredicate predicateWithFormat:@"SELF.tags CONTAINS[cd] %@", string]]; + [prediactes addObject:[NSPredicate predicateWithFormat:@"SELF.uuid.UUIDString CONTAINS[cd] %@", string]]; + + NSPredicate *allAttributesPredicate = [NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject, NSDictionary * _Nullable bindings) { + KPKEntry *entry = evaluatedObject; + for(KPKAttribute *attribute in entry.attributes) { + if([attribute.value rangeOfString:string options:NSCaseInsensitiveSearch].location != NSNotFound) { + return YES; + } + } + return NO; + }]; + + [prediactes addObject:allAttributesPredicate]; + } + return prediactes; } diff --git a/MacPass/MPEntrySearchContext.h b/MacPass/MPEntrySearchContext.h index cf327cda..42d1dfdd 100644 --- a/MacPass/MPEntrySearchContext.h +++ b/MacPass/MPEntrySearchContext.h @@ -30,10 +30,9 @@ typedef NS_OPTIONS(NSUInteger, MPEntrySearchFlags) { MPEntrySearchPasswords = (1<<3), MPEntrySearchNotes = (1<<4), MPEntrySearchAllAttributes = (1<<5), - /* The following two flags should be used like enums. - They are not intended to be used in conjunction with any other flag */ - MPEntrySearchDoublePasswords = (1<<6), - MPEntrySearchExpiredEntries = (1<<7), + MPEntrySearchDoublePasswords = (1<<6), // do not combine with others. Exclusive flag + MPEntrySearchExpiredEntries = (1<<7), // do not combine with others. Exclusive flag + /* All combine-able search flags combined */ MPEntrySearchAllCombineableFlags = (MPEntrySearchDoublePasswords | MPEntrySearchExpiredEntries | @@ -41,9 +40,8 @@ typedef NS_OPTIONS(NSUInteger, MPEntrySearchFlags) { MPEntrySearchPasswords | MPEntrySearchTitles | MPEntrySearchUrls | - MPEntrySearchUsernames | - MPEntrySearchAllAttributes), - MPEntrySearchSingleFlags = (MPEntrySearchDoublePasswords | MPEntrySearchExpiredEntries), + MPEntrySearchUsernames), + MPEntrySearchSingleFlags = (MPEntrySearchDoublePasswords | MPEntrySearchExpiredEntries | MPEntrySearchAllAttributes ), MPEntrySearchAllFlags = (MPEntrySearchAllCombineableFlags | MPEntrySearchSingleFlags ) }; diff --git a/MacPass/MPEntrySearchContext.m b/MacPass/MPEntrySearchContext.m index 1ccfc0af..6d8cf764 100644 --- a/MacPass/MPEntrySearchContext.m +++ b/MacPass/MPEntrySearchContext.m @@ -34,7 +34,7 @@ } + (instancetype)userContext { - NSData *data = [[NSUserDefaults standardUserDefaults] dataForKey:kMPSettingsKeyEntrySearchFilterContext]; + NSData *data = [NSUserDefaults.standardUserDefaults dataForKey:kMPSettingsKeyEntrySearchFilterContext]; if(data) { return [NSKeyedUnarchiver unarchiveObjectWithData:data]; } @@ -64,7 +64,7 @@ - (instancetype)initWithCoder:(NSCoder *)aDecoder { self = [self init]; - self.searchString = [aDecoder decodeObjectOfClass:[NSString class] forKey:NSStringFromSelector(@selector(searchString))]; + self.searchString = [aDecoder decodeObjectOfClass:NSString.class forKey:NSStringFromSelector(@selector(searchString))]; self.searchFlags = [aDecoder decodeIntegerForKey:NSStringFromSelector(@selector(searchFlags))]; return self; } @@ -90,7 +90,7 @@ - (void )_updatePreferences { NSData *myData = [NSKeyedArchiver archivedDataWithRootObject:self]; - [[NSUserDefaults standardUserDefaults] setObject:myData forKey:kMPSettingsKeyEntrySearchFilterContext]; - [[NSUserDefaults standardUserDefaults] synchronize]; + [NSUserDefaults.standardUserDefaults setObject:myData forKey:kMPSettingsKeyEntrySearchFilterContext]; + [NSUserDefaults.standardUserDefaults synchronize]; } @end