diff --git a/AppDelegate.h b/AppDelegate.h index 4dfd3bd..db17fc2 100755 --- a/AppDelegate.h +++ b/AppDelegate.h @@ -159,22 +159,22 @@ @property(nonatomic, retain)NSLayoutConstraint* trailingConstraint; //remote XPC interface -@property(nonatomic, retain) NSXPCConnection* xpcConnection; +@property(nonatomic, retain)NSXPCConnection* xpcConnection; //flagged items -@property(nonatomic, retain) NSMutableArray* flaggedItems; - -//array of autocomplete keywords -//@property NSMutableArray *builtInKeywords; +@property(nonatomic, retain)NSMutableArray* flaggedItems; +//flag for filter field (autocomplete) @property BOOL completePosting; + +//flag for filter field (autocomplete) @property BOOL commandHandling; //custom search field for tasks -@property CustomTextField* customTasksFilter; +@property(nonatomic, retain)CustomTextField* customTasksFilter; //custom search field for items -@property CustomTextField* customItemsFilter; +@property(nonatomic, retain)CustomTextField* customItemsFilter; /* METHODS */ diff --git a/AppDelegate.m b/AppDelegate.m index d86ce48..70fc2a5 100755 --- a/AppDelegate.m +++ b/AppDelegate.m @@ -109,9 +109,15 @@ //alloc/init custom search field for tasks customTasksFilter = [[CustomTextField alloc] init]; + //set owner + self.customTasksFilter.owner = self; + //alloc/init custom search field for items customItemsFilter = [[CustomTextField alloc] init]; + //set owner + self.customItemsFilter.owner = self; + //set field editor for tasks [self.customTasksFilter setFieldEditor:YES]; @@ -880,7 +886,6 @@ bail: return; } - //display alert about OS not being supported -(void)showUnsupportedAlert { diff --git a/Consts.h b/Consts.h index a30c8f2..fb8be94 100644 --- a/Consts.h +++ b/Consts.h @@ -304,8 +304,9 @@ //delta for pid tag #define PID_TAG_DELTA 1000 +//TODO: CHANGE B4 RELEASE //search wait time (from app's launch) -#define SEARCH_WAIT_TIME 30 +#define SEARCH_WAIT_TIME 1 //pls wait (search) message #define PLS_WAIT_MESSAGE @"completing (intial) task/dylib/file enumeration please wait" diff --git a/CustomTextField.h b/CustomTextField.h index cbc1e5a..9c45e60 100644 --- a/CustomTextField.h +++ b/CustomTextField.h @@ -16,4 +16,7 @@ } +//'owner' +@property (nonatomic, retain)id owner; + @end diff --git a/CustomTextField.m b/CustomTextField.m index b920626..6b0ccab 100644 --- a/CustomTextField.m +++ b/CustomTextField.m @@ -11,6 +11,7 @@ @implementation CustomTextField +@synthesize owner; //subclass override // ->see: http://stackoverflow.com/questions/5163646/how-to-make-nssearchfield-send-action-upon-autocompletion/5360535#5360535 @@ -41,8 +42,9 @@ // ->call up into app delegate to process (filter) if(movement == NSReturnTextMovement) { - //call up//filterAutoComplete - [((AppDelegate*)[[NSApplication sharedApplication] delegate]) filterAutoComplete:self]; + //call up into owner to process + [owner filterAutoComplete:self]; + //[((AppDelegate*)[[NSApplication sharedApplication] delegate]) filterAutoComplete:self]; } //bail diff --git a/SearchWindowController.h b/SearchWindowController.h index 1ea844e..08fa153 100644 --- a/SearchWindowController.h +++ b/SearchWindowController.h @@ -8,16 +8,12 @@ #import +#import "CustomTextField.h" #import "InfoWindowController.h" #import "VTInfoWindowController.h" - -@interface SearchWindowController : NSWindowController - -//automatically invoked when user presses 'Enter' in search box -// ->search! --(IBAction)search:(id)sender; +@interface SearchWindowController : NSWindowController //PROPERTIES @@ -54,6 +50,14 @@ //overlay view @property (weak) IBOutlet NSView *overlayView; +//flag for filter field (autocomplete) +@property BOOL completePosting; + +//flag for filter field (autocomplete) +@property BOOL commandHandling; + +//custom search field +@property (nonatomic, retain)CustomTextField* customSearchField; /* METHODS */ @@ -62,5 +66,8 @@ // ->make sure everything is cleanly init'd -(void)prepare; +//search +-(void)search; + @end diff --git a/SearchWindowController.m b/SearchWindowController.m index 163d2ff..ec6b3de 100644 --- a/SearchWindowController.m +++ b/SearchWindowController.m @@ -28,6 +28,9 @@ @synthesize searchTable; @synthesize searchResults; @synthesize plsWaitMessage; +@synthesize commandHandling; +@synthesize completePosting; +@synthesize customSearchField; @synthesize vtWindowController; @synthesize infoWindowController; @@ -59,6 +62,12 @@ //init array for search results searchResults = [NSMutableArray array]; + //alloc/init custom search field for items + customSearchField = [[CustomTextField alloc] init]; + + //set owner + self.customSearchField.owner = self; + //first time outlets are nil // ->thus 'initUI' method called in 'awakeFromNib' if(nil != self.window) @@ -204,7 +213,6 @@ self.activityIndicatorLabel.stringValue = [NSString stringWithFormat:@"%@ (%d)", PLS_WAIT_MESSAGE, (int)timeRemaining]; }); - } //update UI on main thread @@ -231,6 +239,164 @@ return; } +//automatically invoked when user enters text in filter search boxes +// ->filter tasks and/or items +-(void)controlTextDidChange:(NSNotification *)aNotification +{ + //prevent calling "complete" too often + if( (YES != self.completePosting) && + (YES != self.commandHandling) ) + { + //set flag + self.completePosting = YES; + + //invoke complete + [aNotification.userInfo[@"NSFieldEditor"] complete:nil]; + + //unset flag + self.completePosting = NO; + } + + return; +} + +//delegate method, automatically called +// ->generate list of matches to return for drop-down +-(NSArray *)control:(NSControl *)control textView:(NSTextView *)textView completions:(NSArray *)words forPartialWordRange:(NSRange)charRange indexOfSelectedItem:(NSInteger *)index +{ + //matches + NSMutableArray *matches = nil; + + //range options + NSUInteger rangeOptions = {0}; + + //init array for matches + matches = [[NSMutableArray alloc] init]; + + //init range options + rangeOptions = NSAnchoredSearch | NSCaseInsensitiveSearch; + + //check all filters + // note: really check Binary ones, but this should include all! + for(NSString* filter in self.filterObj.binaryFilters) + { + //check if found + // ->add to match when found + if([filter rangeOfString:textView.string options:rangeOptions range:NSMakeRange(0, filter.length)].location != NSNotFound) + { + //add + [matches addObject:filter]; + } + } + + //sort matches + [matches sortUsingComparator:^(NSString *a, NSString *b) + { + //sort + return [a localizedStandardCompare:b]; + }]; + +//bail +bail: + + return matches; +} + +//delegate method, automatically invoked +// ->handle invocations for text view +- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector +{ + //flag + BOOL didPerformRequestedSelectorOnTextView = NO; + + //invocation + NSInvocation *textViewInvocationForSelector = nil; + + //check if text view can handle selector + if(YES != [textView respondsToSelector:commandSelector]) + { + //bail + goto bail; + } + + //first handle 'enter' + // ->trigger a search + if(commandSelector == @selector(insertNewline:)) + { + //search + [self search]; + } + //handle all others + else + { + //set iVar flag + self.commandHandling = YES; + + //init invocation + textViewInvocationForSelector = [NSInvocation invocationWithMethodSignature:[textView methodSignatureForSelector:commandSelector]]; + + //set target + [textViewInvocationForSelector setTarget:textView]; + + //set selector + [textViewInvocationForSelector setSelector:commandSelector]; + + //invoke selector + [textViewInvocationForSelector invoke]; + + //unset iVar + self.commandHandling = NO; + } + + //indicate that selector was performed + didPerformRequestedSelectorOnTextView = YES; + +//bail +bail: + + return didPerformRequestedSelectorOnTextView; +} + + +//callback for custom search fields +// ->handle auto-complete filterings +-(void)filterAutoComplete:(NSTextView*)textView +{ + //just call search method + // ->has logic to handle searching + [self search]; + + return; +} + +//automatically invoked +// ->set all NSSearchFields to be instances of our custom NSTextView +-(id)windowWillReturnFieldEditor:(NSWindow *)sender toObject:(id)client +{ + //field editor + id fieldEditor = nil; + + //ignore non-NSSearchField classes + if(YES != [client isKindOfClass:[NSTextField class]]) + { + //ingnore + goto bail; + } + + //set task's filter search field + if(client == self.searchBox) + { + //assign for return + fieldEditor = self.customSearchField; + } + + +//bail +bail: + + return fieldEditor; +} + //table delegate // ->return number of rows -(NSInteger)numberOfRowsInTableView:(NSTableView *)tableView @@ -314,9 +480,10 @@ bail: return; } -//automatically invoked when user presses 'Enter' in search box -// ->search! --(IBAction)search:(id)sender +//search +//TODO: SYNC DYLIBS etc +//TODO: search network conns +-(void)search { //search string NSString* searchString = nil; @@ -359,7 +526,7 @@ bail: [self.searchTable reloadData]; //grab search string - searchString = [sender stringValue]; + searchString = [self.searchBox stringValue]; //grab all tasks allTasks = ((AppDelegate*)[[NSApplication sharedApplication] delegate]).taskEnumerator.tasks; @@ -374,8 +541,8 @@ bail: //ignore goto bail; } - } - + } + //1st: search for all matching tasks //sync @synchronized(allTasks) @@ -397,6 +564,7 @@ bail: @synchronized(allTasks) { + //TODO: B4 RELEASE! SYNC DYLIBS ARRAY!!! //walk all tasks // ->scan each for dylib matches, only processing first match for(NSNumber* taskPid in allTasks) @@ -471,6 +639,8 @@ bail: //refresh table to display dylib [self.searchTable reloadData]; + //TODO: search network conns + //bail bail: diff --git a/TaskEnumerator.m b/TaskEnumerator.m index 26c9a6e..0f68380 100644 --- a/TaskEnumerator.m +++ b/TaskEnumerator.m @@ -206,7 +206,20 @@ [NSThread sleepForTimeInterval:0.01f]; } - //TODO: add network connection filtering + //begin network enumeration + // ->for search view + for(NSNumber* key in newTasks) + { + //get task + newTask = newTasks[key]; + + //enumerate + [newTask enumerateNetworking:xpcConnection]; + + //nap + // ->helps with UI + [NSThread sleepForTimeInterval:0.01f]; + } return; } diff --git a/TaskExplorer.xcodeproj/project.xcworkspace/xcuserdata/patrickw.xcuserdatad/UserInterfaceState.xcuserstate b/TaskExplorer.xcodeproj/project.xcworkspace/xcuserdata/patrickw.xcuserdatad/UserInterfaceState.xcuserstate index 33e98a9..3809cf0 100644 Binary files a/TaskExplorer.xcodeproj/project.xcworkspace/xcuserdata/patrickw.xcuserdatad/UserInterfaceState.xcuserstate and b/TaskExplorer.xcodeproj/project.xcworkspace/xcuserdata/patrickw.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/TaskExplorer.xcodeproj/xcuserdata/patrickw.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/TaskExplorer.xcodeproj/xcuserdata/patrickw.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist index ab3133b..277cd05 100644 --- a/TaskExplorer.xcodeproj/xcuserdata/patrickw.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ b/TaskExplorer.xcodeproj/xcuserdata/patrickw.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -3,22 +3,6 @@ type = "1" version = "2.0"> - - - - @@ -122,11 +106,11 @@ ignoreCount = "0" continueAfterRunningActions = "No" filePath = "AppDelegate.m" - timestampString = "462785295.692202" + timestampString = "462870109.066579" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "1537" - endingLineNumber = "1537" + startingLineNumber = "1544" + endingLineNumber = "1544" landmarkName = "-selectBottomPaneContent:" landmarkType = "5"> @@ -186,11 +170,11 @@ ignoreCount = "0" continueAfterRunningActions = "No" filePath = "AppDelegate.m" - timestampString = "462695042.305349" + timestampString = "462870109.066579" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "206" - endingLineNumber = "206" + startingLineNumber = "214" + endingLineNumber = "214" landmarkName = "-registerKeypressHandler" landmarkType = "5"> @@ -202,11 +186,11 @@ ignoreCount = "0" continueAfterRunningActions = "No" filePath = "AppDelegate.m" - timestampString = "462695042.305349" + timestampString = "462870109.066579" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "223" - endingLineNumber = "223" + startingLineNumber = "231" + endingLineNumber = "231" landmarkName = "-handleKeypress:" landmarkType = "5"> @@ -218,11 +202,11 @@ ignoreCount = "0" continueAfterRunningActions = "No" filePath = "AppDelegate.m" - timestampString = "462695042.305349" + timestampString = "462870109.066579" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "244" - endingLineNumber = "244" + startingLineNumber = "252" + endingLineNumber = "252" landmarkName = "-handleKeypress:" landmarkType = "5"> diff --git a/UI/SearchWindow.xib b/UI/SearchWindow.xib index 020d610..f38089c 100644 --- a/UI/SearchWindow.xib +++ b/UI/SearchWindow.xib @@ -21,7 +21,7 @@ - + @@ -393,13 +393,12 @@ - + - diff --git a/en.lproj/MainMenu.xib b/en.lproj/MainMenu.xib index 03381ee..11bc0ff 100755 --- a/en.lproj/MainMenu.xib +++ b/en.lproj/MainMenu.xib @@ -41,7 +41,7 @@ - +