fixes/improvements to flagged items & search views

variable length 'loaded in' field
	mouse over for buttons (+refactor)
	files now searched
This commit is contained in:
Patrick Wardle
2015-08-19 20:52:36 -10:00
parent 197c40908a
commit fda6bfc61e
12 changed files with 426 additions and 351 deletions
+3
View File
@@ -1758,6 +1758,9 @@ bail:
//alloc/init
flagItemsWindowController = [[FlaggedItems alloc] initWithWindowNibName:@"FlaggedItems"];
}
//init/prep it
[self.flagItemsWindowController prepare];
//show it
[self.flagItemsWindowController showWindow:self];
+14 -1
View File
@@ -7,10 +7,11 @@
//
#import <Cocoa/Cocoa.h>
#import "InfoWindowController.h"
@interface FlaggedItems : NSWindowController
//PROPERTIES
/* PROPERTIES */
//flag for first time init's
@property BOOL didInit;
@@ -18,7 +19,19 @@
//table
@property (weak) IBOutlet NSTableView *flaggedItemTable;
//table items
@property(nonatomic, retain)NSMutableArray* flaggedItems;
//vt window controller
@property (nonatomic, retain)VTInfoWindowController* vtWindowController;
//info window controller
@property(retain, nonatomic)InfoWindowController* infoWindowController;
/* METHODS */
//init/prepare
// ->make sure everything is cleanly init'd before displaying
-(void)prepare;
@end
+167 -34
View File
@@ -10,8 +10,7 @@
#import "FlaggedItems.h"
#import "ItemView.h"
#import "KKRow.h"
//TODO: mouse over for info/show in finder buttons!
#import "Utilities.h"
@interface FlaggedItems ()
@@ -20,8 +19,10 @@
@implementation FlaggedItems
@synthesize didInit;
@synthesize flaggedItems;
@synthesize flaggedItemTable;
@synthesize vtWindowController;
@synthesize infoWindowController;
//automatically called when nib is loaded
// ->center window
@@ -40,51 +41,67 @@
return;
}
//automatically invoked when window is loaded
// ->set to white
-(void)windowDidLoad
//init/prepare
// ->make sure everything is cleanly init'd before displaying
-(void)prepare
{
//super
[super windowDidLoad];
//array of flagged tasks
NSMutableArray* flaggedTasks = nil;
//table reload
//init array for flagged items
flaggedItems = [NSMutableArray array];
//table reload w/ blank array
// ->make sure all is reset
[self.flaggedItemTable reloadData];
//populate flagged items array
for(Binary* flaggedItem in ((AppDelegate*)[[NSApplication sharedApplication] delegate]).flaggedItems)
{
//when binary is task binary
// ->find/save all tasks instances
if(YES == flaggedItem.isTaskBinary)
{
//get all tasks instances
flaggedTasks = [((AppDelegate*)[[NSApplication sharedApplication] delegate]).taskEnumerator tasksForBinary:flaggedItem];
//save all tasks
[self.flaggedItems addObjectsFromArray:flaggedTasks];
}
//when binary is dylib
// ->just add, since will be processed as single item
else
{
//add
[self.flaggedItems addObject:flaggedItem];
}
}
//always reload
[self.flaggedItemTable reloadData];
}
//TODO: don't need
//automatically invoked when window is closing
// ->make ourselves unmodal
-(void)windowWillClose:(NSNotification *)notification
{
//make un-modal
//[[NSApplication sharedApplication] stopModal];
return;
}
//table delegate
// ->return number of rows, which is just number of items in the currently selected plugin
-(NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
{
return ((AppDelegate*)[[NSApplication sharedApplication] delegate]).flaggedItems.count;
return self.flaggedItems.count;
}
//table delegate method
// ->return cell for row
-(NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
//flagged items
NSMutableArray* flaggedItems = nil;
//row view
NSView* rowView = nil;
//grab flagged items
flaggedItems = ((AppDelegate*)[[NSApplication sharedApplication] delegate]).flaggedItems;
//sanity check
// ->make sure there is table item for row
if(row >= flaggedItems.count)
if(row >= self.flaggedItems.count)
{
//bail
goto bail;
@@ -92,7 +109,7 @@
//create the view
// ->inits row w/ all required info
rowView = createItemView(tableView, self, [flaggedItems objectAtIndex:row]);
rowView = createItemView(tableView, self, [self.flaggedItems objectAtIndex:row]);
//bail
bail:
@@ -127,6 +144,28 @@ bail:
return rowView;
}
//automatically invoked when mouse entered
// ->highlight button
-(void)mouseEntered:(NSEvent*)theEvent
{
//mouse entered
// ->highlight (visual) state
buttonAppearance(self.flaggedItemTable, theEvent, NO);
return;
}
//automatically invoked when mouse exits
// ->unhighlight/reset button
-(void)mouseExited:(NSEvent*)theEvent
{
//mouse exited
// ->so reset button to original (visual) state
buttonAppearance(self.flaggedItemTable, theEvent, YES);
return;
}
//invoked when the user clicks 'virus total' icon
// ->launch browser and browse to virus total's page
-(void)showVTInfo:(id)sender
@@ -137,26 +176,20 @@ bail:
//row
NSInteger itemRow = 0;
//flagged items
NSMutableArray* flaggedItems = nil;
//grab flagged items
flaggedItems = ((AppDelegate*)[[NSApplication sharedApplication] delegate]).flaggedItems;
//grab sender's row
itemRow = [self.flaggedItemTable rowForView:sender];
//sanity check(s)
// ->make sure row is decent
if( (-1 == itemRow) ||
(itemRow >= flaggedItems.count) )
(itemRow >= self.flaggedItems.count) )
{
//bail
goto bail;
}
//extract item for row
item = flaggedItems[itemRow];
item = self.flaggedItems[itemRow];
//alloc/init info window
vtWindowController = [[VTInfoWindowController alloc] initWithItem:item];
@@ -171,4 +204,104 @@ bail:
return;
}
//automatically invoked when user clicks the 'info' icon
// ->create/configure/display info window for task/dylib/file/etc
-(IBAction)showInfo:(id)sender
{
//item
// ->task, dylib, file, etc
id item = nil;
//row
NSInteger itemRow = 0;
//grab sender's row
itemRow = [self.flaggedItemTable rowForView:sender];
//sanity check(s)
// ->make sure row is decent
if( (-1 == itemRow) ||
(itemRow >= self.flaggedItems.count) )
{
//bail
goto bail;
}
//grab item
item = self.flaggedItems[itemRow];
//alloc/init info window
infoWindowController = [[InfoWindowController alloc] initWithItem:item];
//show it
[self.infoWindowController.windowController showWindow:self];
//bail
bail:
return;
}
//automatically invoked when user clicks the 'show in finder' icon
// ->open Finder to show item
-(IBAction)showInFinder:(id)sender
{
//item
// ->task, dylib, or file
id item = nil;
//path to item
NSString* path = nil;
//row
NSInteger itemRow = 0;
//grab sender's row
itemRow = [self.flaggedItemTable rowForView:sender];
//sanity check(s)
// ->make sure row is decent
if( (-1 == itemRow) ||
(itemRow >= self.flaggedItems.count) )
{
//bail
goto bail;
}
//extract item for row
item = self.flaggedItems[itemRow];
//tasks
// ->grab path from binary
if(YES == [item isKindOfClass:[Task class]])
{
//get path
path = ((Task*)item).binary.path;
}
//dylib
// ->use as is, to extract path
else if(YES == [item isKindOfClass:[Binary class]])
{
//get path
path = [item path];
}
//sanity check
if(nil == path)
{
//bail
goto bail;
}
//open Finder
// ->will reveal binary
[[NSWorkspace sharedWorkspace] selectFile:path inFileViewerRootedAtPath:nil];
//bail
bail:
return;
}
@end
+4 -145
View File
@@ -14,7 +14,6 @@
#import "SearchWindowController.h"
#import "3rdParty/OrderedDictionary.h"
//create customize item view
NSTableCellView* createItemView(NSTableView* tableView, id owner, id item)
{
@@ -148,6 +147,7 @@ NSImage* getCodeSigningIcon(Binary* binary)
}
//create & customize global dylib/file view
// ->has 'loaded in...' string
NSTableCellView* createLoadedItemView(NSTableView* tableView, id owner, id item)
{
//item cell
@@ -210,8 +210,7 @@ NSTableCellView* createLoadedItemView(NSTableView* tableView, id owner, id item)
//brand new cells need tracking areas
// ->determine if new, by checking default (.xib/IB) value
if( (YES == [loadedItemCell.textField.stringValue isEqualToString:@"Task Name"]) ||
(YES == [loadedItemCell.textField.stringValue isEqualToString:@"File Name"]) )
if(YES == [loadedItemCell.textField.stringValue isEqualToString:@"Name"])
{
//only dylibs have VT button
if(YES == [item isKindOfClass:[Binary class]])
@@ -282,147 +281,6 @@ bail:
return loadedItemCell;
}
//TODO: for search, each task is unique, so same for flagged tasks? YES, get args etc :)
//create & customize flagged item view
NSTableCellView* createFlaggedItemView(NSTableView* tableView, id owner, Binary* binary)
{
//item cell
NSTableCellView* flaggedItemCell = nil;
//matching or host tasks
NSMutableArray* tasks = nil;
//pid or 'loaded in' string
NSMutableString* pidString = nil;
//task's name frame
CGRect nameFrame = {0};
//for main (task) binaries
// ->just need task's pid
if(YES == binary.isTaskBinary)
{
//get all matching tasks
tasks = [((AppDelegate*)[[NSApplication sharedApplication] delegate]).taskEnumerator tasksForBinary:binary];
//start 'tasks: ...' str
pidString = [NSMutableString stringWithFormat:@"(tasks:"];
//add all tasks
for(Task* task in tasks)
{
//append name
[pidString appendFormat:@" %@,", task.pid];
}
//remove last ','
if(YES == [pidString hasSuffix:@","])
{
//remove
[pidString deleteCharactersInRange:NSMakeRange([pidString length]-1, 1)];
}
//terminate list/output
[pidString appendString:@")"];
}
//for dylibs
// ->list all tasks the flagged dylib is loaded in
else
{
//get host tasks
tasks = [((AppDelegate*)[[NSApplication sharedApplication] delegate]).taskEnumerator loadedIn:binary];
//start 'loaded in: ...' str
pidString = [NSMutableString stringWithFormat:@"(loaded in:"];
//add all tasks
for(Task* task in tasks)
{
//append name
[pidString appendFormat:@" %@,", task.binary.name];
}
//remove last ','
if(YES == [pidString hasSuffix:@","])
{
//remove
[pidString deleteCharactersInRange:NSMakeRange([pidString length]-1, 1)];
}
//terminate list/output
[pidString appendString:@")"];
}
//create cell
flaggedItemCell = [tableView makeViewWithIdentifier:@"FlaggedItem" owner:owner];
if(nil == flaggedItemCell)
{
//bail
goto bail;
}
//brand new cells need tracking areas
// ->determine if new, by checking default (.xib/IB) value
if(YES == [flaggedItemCell.textField.stringValue isEqualToString:@"Flagged Item Name"])
{
//add tracking area
// ->'vt' button
addTrackingArea(flaggedItemCell, TABLE_ROW_VT_BUTTON, owner);
//add tracking area
// ->'info' button
addTrackingArea(flaggedItemCell, TABLE_ROW_INFO_BUTTON, owner);
//add tracking area
// ->'show' button
addTrackingArea(flaggedItemCell, TABLE_ROW_SHOW_BUTTON, owner);
}
//set icon
flaggedItemCell.imageView.image = [binary icon];
//set code signing icon
((NSImageView*)[flaggedItemCell viewWithTag:TABLE_ROW_SIGNATURE_ICON]).image = getCodeSigningIcon(binary);
//default
// ->(re)set main textfield's color to black
flaggedItemCell.textField.textColor = [NSColor blackColor];
//set main text
// ->name
[flaggedItemCell.textField setStringValue:binary.name];
//get name frame
nameFrame = flaggedItemCell.textField.frame;
//adjust width to fit text
nameFrame.size.width = [flaggedItemCell.textField.stringValue sizeWithAttributes: @{NSFontAttributeName: flaggedItemCell.textField.font}].width + 5;
//disable autolayout for name
flaggedItemCell.textField.translatesAutoresizingMaskIntoConstraints = YES;
//update name frame
// ->should now be exact size of text
flaggedItemCell.textField.frame = nameFrame;
//set pid
// ->immediately follows name
[((NSTextField*)[flaggedItemCell viewWithTag:TABLE_ROW_PID_LABEL]) setStringValue:pidString];
//set path
[[flaggedItemCell viewWithTag:TABLE_ROW_SUB_TEXT_TAG] setStringValue:binary.path];
//config VT button
configVTButton(flaggedItemCell, owner, binary);
//bail
bail:
return flaggedItemCell;
}
//create & customize Task view
NSTableCellView* createTaskView(NSTableView* tableView, id owner, Task* task)
{
@@ -449,7 +307,8 @@ NSTableCellView* createTaskView(NSTableView* tableView, id owner, Task* task)
//brand new cells need tracking areas
// ->determine if new, by checking default (.xib/IB) value
if(YES == [taskCell.textField.stringValue isEqualToString:@"Task Name"])
if( (YES == [taskCell.textField.stringValue isEqualToString:@"Task Name"]) ||
(YES == [taskCell.textField.stringValue isEqualToString:@"Name"]) )
{
//add tracking area
// ->'vt' button
+1
View File
@@ -42,6 +42,7 @@
@property(retain, nonatomic)InfoWindowController* infoWindowController;
//TODO: remove!
//tasks
@property(nonatomic, retain)NSMutableDictionary* tasks;
+80 -19
View File
@@ -15,7 +15,8 @@
#import "ItemView.h"
#import "KKRow.h"
#import "Filter.h"
#import "SearchResult.h"
#import "SearchResult.h"]
#import "Utilities.h"
@implementation SearchWindowController
@@ -49,6 +50,8 @@
return;
}
//TODO: center window each time?
/*
//automatically invoked when window is loaded
// ->set to white
@@ -71,6 +74,7 @@
}
*/
//TODO: delete/remove
//automatically invoked when window is closing
// ->make ourselves unmodal
-(void)windowWillClose:(NSNotification *)notification
@@ -82,7 +86,7 @@
}
//init/prepare
// ->make sure everything is cleanly init'd
// ->make sure everything is cleanly init'd before displaying
-(void)prepare
{
//init filter obj
@@ -233,9 +237,32 @@ bail:
return rowView;
}
//automatically invoked when mouse entered
// ->highlight button
-(void)mouseEntered:(NSEvent*)theEvent
{
//mouse entered
// ->highlight (visual) state
buttonAppearance(self.searchTable, theEvent, NO);
return;
}
//automatically invoked when mouse exits
// ->unhighlight/reset button
-(void)mouseExited:(NSEvent*)theEvent
{
//mouse exited
// ->so reset button to original (visual) state
buttonAppearance(self.searchTable, theEvent, YES);
return;
}
//automatically invoked when user presses 'Enter' in search box
// ->search!
- (IBAction)search:(id)sender
-(IBAction)search:(id)sender
{
//search string
NSString* searchString = nil;
@@ -252,12 +279,12 @@ bail:
//matching dylibs
NSMutableDictionary* matchingDylibs = nil;
//matching files
NSMutableDictionary* matchingFiles = nil;
//task
Task* task = nil;
//search result
//SearchResult* searchResult = nil;
//alloc array for matching items
matchingItems = [NSMutableArray array];
@@ -267,6 +294,9 @@ bail:
//alloc dictionary for matching dylibs
matchingDylibs = [NSMutableDictionary dictionary];
//alloc dictionary for matching files
matchingFiles = [NSMutableDictionary dictionary];
//reset search results
[self.searchResults removeAllObjects];
@@ -288,24 +318,16 @@ bail:
}
}
//first; search for all matching tasks
//1st: search for all matching tasks
[self.filterObj filterTasks:searchString items:allTasks results:matchingTasks];
//TODO: don't need for loop for this?
//convert/save into search result objects
for(Task* task in matchingTasks)
{
//init
//searchResult = [[SearchResult alloc] initWithItem:task];
//add to table items
[self.searchResults addObject:task];
}
//add all tasks
[self.searchResults addObjectsFromArray:matchingTasks];
//refresh table to display task matches
[self.searchTable reloadData];
//second; search for all matching dylibs
//2nd: search for all matching dylibs
//sync
@synchronized(allTasks)
{
@@ -345,6 +367,45 @@ bail:
//refresh table to display dylib
[self.searchTable reloadData];
//3rd: search for all matching files
//sync
@synchronized(allTasks)
{
//walk all tasks
// ->scan each for file matches, only processing first match
for(NSNumber* taskPid in allTasks)
{
//extract task
task = allTasks[taskPid];
//filter
[self.filterObj filterFiles:searchString items:task.files results:matchingItems];
//process all matching dylibs
// ->but first check if processed due to matching in another task already
for(File* file in matchingItems)
{
//ignore if already seen/processed
if(nil != matchingFiles[file.path])
{
//skip
continue;
}
//process
[self.searchResults addObject:file];
//save
matchingFiles[file.path] = file;
}
}//all tasks
}//sync
//refresh table to display dylib
[self.searchTable reloadData];
//bail
bail:
@@ -510,7 +571,7 @@ bail:
//show it
[self.infoWindowController.windowController showWindow:self];
//bail
//bail
bail:
return;
+22 -4
View File
@@ -70,9 +70,15 @@
//new tasks
OrderedDictionary* newTasks = nil;
//xpc connection
NSXPCConnection* xpcConnection = nil;
//determine if network is connected
// ->sets 'isConnected' flag
((AppDelegate*)[[NSApplication sharedApplication] delegate]).isConnected = isNetworkConnected();
//get xpc connection
xpcConnection = ((AppDelegate*)[[NSApplication sharedApplication] delegate]).xpcConnection;
//get all tasks
// ->pids and binary obj with just path/name
@@ -170,13 +176,25 @@
}//signing info for all new tasks
//begin dylib enumeration
// ->this is really just for search/filter views since they are re-gen'd per task on each bottom-pane click
for(NSNumber* key in newTasks)
{
//get task
newTask = newTasks[key];
//enumerate
[newTask enumerateDylibs:((AppDelegate*)[[NSApplication sharedApplication] delegate]).xpcConnection allDylibs:self.dylibs];
[newTask enumerateDylibs:xpcConnection allDylibs:self.dylibs];
}
//begin file enumeration
// ->for search view
for(NSNumber* key in newTasks)
{
//get task
newTask = newTasks[key];
//enumerate
[newTask enumerateFiles:xpcConnection];
}
return;
@@ -464,12 +482,12 @@ bail:
}
//get all tasks that host the flagged dylib
taskHosts = [self tasksForBinary:dylib];
taskHosts = [self loadedIn:dylib];
//skip dylibs that are hosted in more than one task
// or aren't hosted in dead task
if( (1 != taskHosts.count) ||
(taskHosts.firstObject != deadTask.binary) )
(taskHosts.firstObject != deadTask.binary) )
{
//skip
continue;
@@ -592,7 +610,7 @@ bail:
//sync
@synchronized(self.tasks)
{
//reload each row w/ new VT info
//iterate over all tasks
for(NSNumber* taskPid in self.tasks)
{
//extract task
+5 -102
View File
@@ -274,120 +274,23 @@ bail:
//automatically invoked when mouse entered
// ->highlight button
-(void)mouseEntered:(NSEvent*)theEvent
{
//mouse entered
// ->highlight (visual) state
[self buttonAppearance:theEvent shouldReset:NO];
buttonAppearance(self.itemView, theEvent, NO);
return;
}
//automaticall invoked when mouse exits
//automatically invoked when mouse exits
// ->unhighlight/reset button
-(void)mouseExited:(NSEvent*)theEvent
{
//mouse exited
// ->so reset button to original (visual) state
[self buttonAppearance:theEvent shouldReset:YES];
return;
}
//set or unset button's highlight
-(void)buttonAppearance:(NSEvent*)theEvent shouldReset:(BOOL)shouldReset
{
//mouse point
NSPoint mousePoint = {0};
//row index
NSUInteger rowIndex = -1;
//current row
NSTableCellView* currentRow = nil;
//tag
NSUInteger tag = 0;
//button
NSButton* button = nil;
//button's label
NSTextField* label = nil;
//image name
NSString* imageName = nil;
//extract tag
tag = [((NSDictionary*)theEvent.userData)[@"tag"] unsignedIntegerValue];
//restore button back to default (visual) state
if(YES == shouldReset)
{
//set image name
// ->'info'
if(TABLE_ROW_INFO_BUTTON == tag)
{
//set
imageName = @"info";
}
//set image name
// ->'info'
else if(TABLE_ROW_SHOW_BUTTON == tag)
{
//set
imageName = @"show";
}
}
//highlight button
else
{
//set image name
// ->'info'
if(TABLE_ROW_INFO_BUTTON == tag)
{
//set
imageName = @"infoOver";
}
//set image name
// ->'info'
else if(TABLE_ROW_SHOW_BUTTON == tag)
{
//set
imageName = @"showOver";
}
}
//grab mouse point
mousePoint = [self.itemView convertPoint:[theEvent locationInWindow] fromView:nil];
//compute row indow
rowIndex = [self.itemView rowAtPoint:mousePoint];
//sanity check
if(-1 == rowIndex)
{
//bail
goto bail;
}
//get row that's about to be selected
currentRow = [self.itemView viewAtColumn:0 row:rowIndex makeIfNecessary:YES];
//get button
// ->tag id of button, passed in userData var
button = [currentRow viewWithTag:[((NSDictionary*)theEvent.userData)[@"tag"] unsignedIntegerValue]];
label = [currentRow viewWithTag: 1 + [((NSDictionary*)theEvent.userData)[@"tag"] unsignedIntegerValue]];
//restore default button image
// ->for 'info' and 'show' buttons
if(nil != imageName)
{
//set image
[button setImage:[NSImage imageNamed:imageName]];
}
//bail
bail:
buttonAppearance(self.itemView, theEvent, YES);
return;
}
+11 -5
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14F27" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/>
@@ -17,7 +17,7 @@
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="95" y="481" width="1304" height="322"/>
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1057"/>
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1080"/>
<value key="minSize" type="size" width="800" height="250"/>
<view key="contentView" id="se5-gp-TjO">
<rect key="frame" x="0.0" y="0.0" width="1304" height="322"/>
@@ -71,7 +71,7 @@
</imageView>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" ambiguous="YES" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="SI4-HT-3LO">
<rect key="frame" x="46" y="20" width="225" height="19"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" title="Flagged Item Name" id="t89-gZ-pCr">
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" title="Name" id="t89-gZ-pCr">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
@@ -87,6 +87,9 @@
<behavior key="behavior" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="showInFinder:" target="-2" id="M4Z-ZW-tpF"/>
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="108" translatesAutoresizingMaskIntoConstraints="NO" id="Ska-cO-ibK">
<rect key="frame" x="1258" y="4" width="25" height="12"/>
@@ -141,6 +144,9 @@
<behavior key="behavior" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="showInfo:" target="-2" id="yVu-Qv-GRl"/>
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="106" translatesAutoresizingMaskIntoConstraints="NO" id="JeV-w6-lMk">
<rect key="frame" x="1220" y="4" width="25" height="12"/>
@@ -155,9 +161,8 @@
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="102" translatesAutoresizingMaskIntoConstraints="NO" id="HUg-RC-ApX">
<rect key="frame" x="264" y="20" width="504" height="18"/>
<rect key="frame" x="264" y="20" width="868" height="18"/>
<constraints>
<constraint firstAttribute="width" constant="500" id="GZp-g5-nIv"/>
<constraint firstAttribute="height" constant="18" id="p2j-Rg-UCM"/>
</constraints>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="pid" id="g8r-Fj-UsA">
@@ -170,6 +175,7 @@
<constraints>
<constraint firstItem="Ska-cO-ibK" firstAttribute="leading" secondItem="JeV-w6-lMk" secondAttribute="trailing" constant="17" id="CYN-Mk-OYX"/>
<constraint firstItem="4pP-3r-LmH" firstAttribute="leading" secondItem="LL3-Mq-2hG" secondAttribute="leading" constant="4" id="Lwa-4l-9kr"/>
<constraint firstAttribute="trailing" secondItem="HUg-RC-ApX" secondAttribute="trailing" constant="171" id="Vgm-3I-yka"/>
<constraint firstItem="CXT-MY-otd" firstAttribute="leading" secondItem="lSO-MV-z6s" secondAttribute="trailing" constant="8" id="ZSp-vP-YLC"/>
<constraint firstItem="JeV-w6-lMk" firstAttribute="leading" secondItem="CXT-MY-otd" secondAttribute="trailing" constant="11" id="e7R-yR-yTc"/>
<constraint firstItem="4pP-3r-LmH" firstAttribute="top" secondItem="LL3-Mq-2hG" secondAttribute="top" constant="7" id="efk-9Z-3l9"/>
+17 -41
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14F27" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/>
@@ -72,7 +72,7 @@
</imageView>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" ambiguous="YES" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="n1s-T9-NPU">
<rect key="frame" x="46" y="20" width="225" height="19"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" title="Task Name" id="5KE-Dr-geL">
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" title="Name" id="5KE-Dr-geL">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
@@ -106,7 +106,7 @@
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="101" translatesAutoresizingMaskIntoConstraints="NO" id="NrX-dv-Ndg">
<rect key="frame" x="31" y="2" width="1118" height="21"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" title="item path" id="q9H-hQ-BE4">
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" title="task/dylib path" id="q9H-hQ-BE4">
<font key="font" size="11" name="Menlo-Regular"/>
<color key="textColor" white="0.5" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
@@ -162,11 +162,11 @@
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="102" translatesAutoresizingMaskIntoConstraints="NO" id="SQO-cM-V2f">
<rect key="frame" x="295" y="20" width="675" height="18"/>
<rect key="frame" x="264" y="20" width="868" height="18"/>
<constraints>
<constraint firstAttribute="height" constant="18" id="gMv-w4-pQh"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="pid" id="Lm4-16-Zlv">
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="pid/loaded in" id="Lm4-16-Zlv">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" white="0.49295236009999999" alpha="0.84999999999999998" colorSpace="calibratedWhite"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
@@ -185,6 +185,7 @@
<constraint firstItem="bfy-Vt-ur5" firstAttribute="leading" secondItem="pYR-xm-B9a" secondAttribute="trailing" constant="17" id="gWw-co-H34"/>
<constraint firstItem="KGc-fT-NHo" firstAttribute="top" secondItem="sUk-Ix-Ica" secondAttribute="top" constant="7" id="ixB-HB-XNH"/>
<constraint firstItem="Gb3-Kp-uki" firstAttribute="leading" secondItem="NrX-dv-Ndg" secondAttribute="trailing" constant="8" id="jOh-lG-rMG"/>
<constraint firstAttribute="trailing" secondItem="SQO-cM-V2f" secondAttribute="trailing" constant="171" id="yB9-Yn-my4"/>
</constraints>
<connections>
<outlet property="imageView" destination="KGc-fT-NHo" id="fjH-oS-Ttv"/>
@@ -203,9 +204,9 @@
</constraints>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="NSActionTemplate" id="6gv-k4-mdi"/>
</imageView>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" ambiguous="YES" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ugh-bk-muU">
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ugh-bk-muU">
<rect key="frame" x="31" y="20" width="225" height="19"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" title="File Name" id="fgN-p7-FWL">
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" title="Name" id="fgN-p7-FWL">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
@@ -239,35 +240,12 @@
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="101" translatesAutoresizingMaskIntoConstraints="NO" id="4c4-WA-4rL">
<rect key="frame" x="31" y="2" width="1118" height="21"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" title="item path" id="1An-1Z-a3L">
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" title="file" id="1An-1Z-a3L">
<font key="font" size="11" name="Menlo-Regular"/>
<color key="textColor" white="0.5" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button toolTip="show virustotal info" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="103" translatesAutoresizingMaskIntoConstraints="NO" id="i6u-9C-uXr" customClass="VTButton">
<rect key="frame" x="1155" y="17" width="49" height="20"/>
<constraints>
<constraint firstAttribute="height" constant="29" id="dZK-av-f0h"/>
<constraint firstAttribute="width" constant="49" id="pSZ-XT-150"/>
</constraints>
<buttonCell key="cell" type="bevel" title="▪ ▪ ▪" bezelStyle="regularSquare" imagePosition="overlaps" alignment="center" enabled="NO" refusesFirstResponder="YES" state="on" imageScaling="proportionallyDown" inset="2" id="GbW-1n-cPa">
<behavior key="behavior" lightByContents="YES"/>
<font key="font" size="8" name="Menlo-Bold"/>
</buttonCell>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="104" translatesAutoresizingMaskIntoConstraints="NO" id="PDw-rS-77D">
<rect key="frame" x="1148" y="4" width="65" height="12"/>
<constraints>
<constraint firstAttribute="height" constant="12" id="BOb-he-sMX"/>
<constraint firstAttribute="width" constant="61" id="Lfq-Ws-PxQ"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="virustotal" id="knf-Fq-SXI">
<font key="font" size="9" name="Menlo-Regular"/>
<color key="textColor" white="0.5" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button toolTip="show file info" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="105" translatesAutoresizingMaskIntoConstraints="NO" id="UgY-KO-I4K">
<rect key="frame" x="1226" y="17" width="15" height="15"/>
<constraints>
@@ -295,12 +273,11 @@
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="102" translatesAutoresizingMaskIntoConstraints="NO" id="fnp-rh-Inz">
<rect key="frame" x="295" y="20" width="79" height="18"/>
<rect key="frame" x="264" y="20" width="868" height="18"/>
<constraints>
<constraint firstAttribute="width" constant="75" id="Mgt-VY-xK3"/>
<constraint firstAttribute="height" constant="18" id="uzP-Cn-LZW"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="pid" id="JT7-PU-YPp">
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="loaded in" id="JT7-PU-YPp">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" white="0.49295236009999999" alpha="0.84999999999999998" colorSpace="calibratedWhite"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
@@ -308,15 +285,12 @@
</textField>
</subviews>
<constraints>
<constraint firstItem="PDw-rS-77D" firstAttribute="leading" secondItem="4c4-WA-4rL" secondAttribute="trailing" constant="8" id="1SS-3r-UgX"/>
<constraint firstItem="IIS-fl-0Bl" firstAttribute="top" secondItem="62p-Yk-Jl3" secondAttribute="top" constant="7" id="8c5-Z7-Olg"/>
<constraint firstItem="5kn-qs-yNV" firstAttribute="leading" secondItem="PDw-rS-77D" secondAttribute="trailing" constant="11" id="DGY-Ua-MhO"/>
<constraint firstAttribute="trailing" secondItem="Xsx-qZ-Zpb" secondAttribute="trailing" constant="20" id="Nyw-Bs-k6x"/>
<constraint firstItem="vr7-eK-3Bt" firstAttribute="leading" secondItem="UgY-KO-I4K" secondAttribute="trailing" constant="22" id="PkR-9T-0we"/>
<constraint firstAttribute="trailing" secondItem="fnp-rh-Inz" secondAttribute="trailing" constant="171" id="V3B-Vz-Pzp"/>
<constraint firstItem="4c4-WA-4rL" firstAttribute="leading" secondItem="IIS-fl-0Bl" secondAttribute="trailing" constant="2" id="bEr-bp-efR"/>
<constraint firstItem="fnp-rh-Inz" firstAttribute="leading" secondItem="ugh-bk-muU" secondAttribute="trailing" constant="8" id="cFH-UH-bLJ"/>
<constraint firstItem="IIS-fl-0Bl" firstAttribute="leading" secondItem="62p-Yk-Jl3" secondAttribute="leading" constant="4" id="dM0-v7-57a"/>
<constraint firstItem="UgY-KO-I4K" firstAttribute="leading" secondItem="i6u-9C-uXr" secondAttribute="trailing" constant="22" id="eBy-TC-Ohr"/>
<constraint firstItem="Xsx-qZ-Zpb" firstAttribute="leading" secondItem="5kn-qs-yNV" secondAttribute="trailing" constant="17" id="icg-9v-1Px"/>
<constraint firstAttribute="trailing" secondItem="vr7-eK-3Bt" secondAttribute="trailing" constant="20" id="sgF-8e-pVL"/>
</constraints>
@@ -330,7 +304,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView ambiguous="YES" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="71C-gs-Mno">
<rect key="frame" x="5" y="9" width="26" height="23"/>
<rect key="frame" x="1" y="9" width="26" height="23"/>
<constraints>
<constraint firstAttribute="height" constant="20" id="5cY-lj-s0H"/>
<constraint firstAttribute="width" constant="20" id="RFz-62-vLF"/>
@@ -412,8 +386,8 @@
<autoresizingMask key="autoresizingMask"/>
</scroller>
</scrollView>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="BB9-Xc-q8T">
<rect key="frame" x="20" y="372" width="927" height="42"/>
<textField verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="BB9-Xc-q8T">
<rect key="frame" x="20" y="372" width="1264" height="42"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" state="on" borderStyle="bezel" placeholderString="type search term, then press enter" drawsBackground="YES" id="L1f-RR-fvk">
<font key="font" metaFont="system" size="30"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
@@ -428,8 +402,10 @@
<constraints>
<constraint firstItem="8GA-gp-lIa" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="70" id="IAH-UM-GVX"/>
<constraint firstAttribute="bottom" secondItem="8GA-gp-lIa" secondAttribute="bottom" constant="-1" id="RJ1-AT-aVI"/>
<constraint firstAttribute="trailing" secondItem="BB9-Xc-q8T" secondAttribute="trailing" constant="20" id="aKm-xj-RF5"/>
<constraint firstItem="8GA-gp-lIa" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="-1" id="bVx-kV-QU1"/>
<constraint firstAttribute="trailing" secondItem="8GA-gp-lIa" secondAttribute="trailing" constant="-1" id="hYI-5Z-VSU"/>
<constraint firstItem="BB9-Xc-q8T" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="20" id="sZv-PY-ckN"/>
</constraints>
</view>
<connections>
+3
View File
@@ -71,4 +71,7 @@ BOOL isAlive(pid_t targetPID);
//check if computer has network connection
BOOL isNetworkConnected();
//set or unset button's highlight
void buttonAppearance(NSTableView* table, NSEvent* event, BOOL shouldReset);
#endif
+99
View File
@@ -772,3 +772,102 @@ bail:
return isConnected;
}
//set or unset button's highlight
void buttonAppearance(NSTableView* table, NSEvent* event, BOOL shouldReset)
{
//mouse point
NSPoint mousePoint = {0};
//row index
NSUInteger rowIndex = -1;
//current row
NSTableCellView* currentRow = nil;
//tag
NSUInteger tag = 0;
//button
NSButton* button = nil;
//button's label
NSTextField* label = nil;
//image name
NSString* imageName = nil;
//extract tag
tag = [((NSDictionary*)event.userData)[@"tag"] unsignedIntegerValue];
//restore button back to default (visual) state
if(YES == shouldReset)
{
//set image name
// ->'info'
if(TABLE_ROW_INFO_BUTTON == tag)
{
//set
imageName = @"info";
}
//set image name
// ->'info'
else if(TABLE_ROW_SHOW_BUTTON == tag)
{
//set
imageName = @"show";
}
}
//highlight button
else
{
//set image name
// ->'info'
if(TABLE_ROW_INFO_BUTTON == tag)
{
//set
imageName = @"infoOver";
}
//set image name
// ->'info'
else if(TABLE_ROW_SHOW_BUTTON == tag)
{
//set
imageName = @"showOver";
}
}
//grab mouse point
mousePoint = [table convertPoint:[event locationInWindow] fromView:nil];
//compute row indow
rowIndex = [table rowAtPoint:mousePoint];
//sanity check
if(-1 == rowIndex)
{
//bail
goto bail;
}
//get row that's about to be selected
currentRow = [table viewAtColumn:0 row:rowIndex makeIfNecessary:YES];
//get button
// ->tag id of button, passed in userData var
button = [currentRow viewWithTag:[((NSDictionary*)event.userData)[@"tag"] unsignedIntegerValue]];
label = [currentRow viewWithTag: 1 + [((NSDictionary*)event.userData)[@"tag"] unsignedIntegerValue]];
//restore default button image
// ->for 'info' and 'show' buttons
if(nil != imageName)
{
//set image
[button setImage:[NSImage imageNamed:imageName]];
}
//bail
bail:
return;
}