mirror of
https://github.com/MacPass/MacPass.git
synced 2025-12-13 08:52:20 +00:00
Added “everywhere” search option
This commit is contained in:
@@ -1,14 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13196" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13771" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13196"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13771"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="MPContextBarViewController">
|
||||
<connections>
|
||||
<outlet property="emptyTrashButton" destination="szx-Hx-OrV" id="i1Y-qB-TW3"/>
|
||||
<outlet property="everywhereButton" destination="RGg-wK-hz4" id="xIZ-YB-pkm"/>
|
||||
<outlet property="exitHistoryButton" destination="pqx-su-vAh" id="JmV-vC-F48"/>
|
||||
<outlet property="filterLabelTextField" destination="6" id="60"/>
|
||||
<outlet property="historyBar" destination="S8L-rB-h0h" id="6yZ-El-fVs"/>
|
||||
@@ -108,18 +109,27 @@
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="RGg-wK-hz4">
|
||||
<rect key="frame" x="379" y="6" width="86" height="17"/>
|
||||
<buttonCell key="cell" type="recessed" title="Everywhere" bezelStyle="recessed" alignment="center" controlSize="small" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="WMK-bb-ESj">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
|
||||
<font key="font" metaFont="systemBold" size="12"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="centerY" secondItem="O7W-cn-eUP" secondAttribute="centerY" id="2uC-wS-HDi"/>
|
||||
<constraint firstItem="O7W-cn-eUP" firstAttribute="leading" secondItem="6" secondAttribute="trailing" constant="8" symbolic="YES" id="5hN-x3-XlX"/>
|
||||
<constraint firstItem="0R1-PX-dgn" firstAttribute="leading" secondItem="O7W-cn-eUP" secondAttribute="trailing" constant="8" symbolic="YES" id="67f-i6-eOb"/>
|
||||
<constraint firstAttribute="centerY" secondItem="SaV-5p-jIX" secondAttribute="centerY" id="7ch-eZ-Hzh"/>
|
||||
<constraint firstItem="aPQ-t2-bgz" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="SaV-5p-jIX" secondAttribute="trailing" constant="8" symbolic="YES" id="91Q-Aq-ulG"/>
|
||||
<constraint firstItem="RGg-wK-hz4" firstAttribute="leading" secondItem="SaV-5p-jIX" secondAttribute="trailing" constant="8" symbolic="YES" id="Bbh-au-wHa"/>
|
||||
<constraint firstItem="aPQ-t2-bgz" firstAttribute="centerY" secondItem="SaV-5p-jIX" secondAttribute="centerY" id="EUG-hL-jbn"/>
|
||||
<constraint firstAttribute="centerY" secondItem="0R1-PX-dgn" secondAttribute="centerY" id="Huh-PB-cbs"/>
|
||||
<constraint firstItem="aPQ-t2-bgz" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="RGg-wK-hz4" secondAttribute="trailing" constant="8" symbolic="YES" id="QoK-F3-goX"/>
|
||||
<constraint firstItem="6" firstAttribute="leading" secondItem="1" secondAttribute="leading" constant="8" id="Seo-dI-FzX"/>
|
||||
<constraint firstItem="Bn2-iY-mQ3" firstAttribute="leading" secondItem="Uhl-ck-vVQ" secondAttribute="trailing" constant="8" id="TCJ-vg-IIt"/>
|
||||
<constraint firstAttribute="trailing" secondItem="aPQ-t2-bgz" secondAttribute="trailing" constant="20" symbolic="YES" id="XFv-Pv-Bzq"/>
|
||||
<constraint firstItem="RGg-wK-hz4" firstAttribute="centerY" secondItem="1" secondAttribute="centerY" id="hsT-uo-6H8"/>
|
||||
<constraint firstItem="SaV-5p-jIX" firstAttribute="leading" secondItem="Bn2-iY-mQ3" secondAttribute="trailing" constant="8" symbolic="YES" id="pAA-uU-moF"/>
|
||||
<constraint firstAttribute="centerY" secondItem="6" secondAttribute="centerY" id="qak-8F-xbj"/>
|
||||
<constraint firstItem="Uhl-ck-vVQ" firstAttribute="leading" secondItem="0R1-PX-dgn" secondAttribute="trailing" constant="8" id="u8d-C2-O9h"/>
|
||||
@@ -244,7 +254,7 @@
|
||||
</connections>
|
||||
</tabViewItem>
|
||||
</tabViewItems>
|
||||
<point key="canvasLocation" x="104" y="293"/>
|
||||
<point key="canvasLocation" x="-152" y="121"/>
|
||||
</tabView>
|
||||
</objects>
|
||||
</document>
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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<NSControl *> *buttons = @[self.titleButton, self.usernameButton, self.passwordButton, self.notesButton, self.urlButton ];
|
||||
NSInteger tags[] = { MPEntrySearchTitles, MPEntrySearchUsernames, MPEntrySearchPasswords, MPEntrySearchNotes, MPEntrySearchUrls, MPEntrySearchAllAttributes };
|
||||
NSArray<NSControl *> *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;
|
||||
|
||||
@@ -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<NSString *,id> * _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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 )
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user