mirror of
https://github.com/objective-see/TaskExplorer.git
synced 2026-03-22 07:02:39 +00:00
373 lines
7.9 KiB
Objective-C
373 lines
7.9 KiB
Objective-C
//
|
|
// FlaggedItems.m
|
|
// TaskExplorer
|
|
//
|
|
// Created by Patrick Wardle on 8/14/15.
|
|
// Copyright (c) 2015 Objective-See. All rights reserved.
|
|
//
|
|
|
|
#import "KKRow.h"
|
|
#import "ItemView.h"
|
|
#import "Utilities.h"
|
|
#import "AppDelegate.h"
|
|
#import "FlaggedItemWindowController.h"
|
|
|
|
@interface FlaggedItems ()
|
|
|
|
@end
|
|
|
|
@implementation FlaggedItems
|
|
|
|
@synthesize didInit;
|
|
@synthesize flaggedItems;
|
|
@synthesize flaggedItemTable;
|
|
@synthesize vtWindowController;
|
|
@synthesize infoWindowController;
|
|
|
|
//automatically called when nib is loaded
|
|
// ->first time (when outlets aren't nil), init UI
|
|
-(void)awakeFromNib
|
|
{
|
|
//single time init
|
|
if(YES != self.didInit)
|
|
{
|
|
//init UI
|
|
[self initUI];
|
|
|
|
//set flag
|
|
self.didInit = YES;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
//init/prepare
|
|
// ->make sure everything is cleanly init'd before displaying
|
|
-(void)prepare
|
|
{
|
|
//array of flagged tasks
|
|
NSMutableArray* flaggedTasks = nil;
|
|
|
|
//init array for flagged items
|
|
flaggedItems = [NSMutableArray array];
|
|
|
|
//first time outlets are nil
|
|
// ->thus 'initUI' method called in 'awakeFromNib'
|
|
if(nil != self.window)
|
|
{
|
|
//can init UI
|
|
// ->center window, etc
|
|
[self initUI];
|
|
|
|
//set flag
|
|
self.didInit = YES;
|
|
}
|
|
|
|
//populate flagged items array
|
|
for(Binary* flaggedItem in taskEnumerator.flaggedItems)
|
|
{
|
|
//when binary is task binary
|
|
// ->find/save all tasks instances
|
|
if(YES == flaggedItem.isTaskBinary)
|
|
{
|
|
//get all tasks instances
|
|
flaggedTasks = [taskEnumerator tasksForBinary:flaggedItem];
|
|
|
|
//sync to save
|
|
@synchronized(self.flaggedItems)
|
|
{
|
|
//save all tasks
|
|
[self.flaggedItems addObjectsFromArray:flaggedTasks];
|
|
}
|
|
}
|
|
//when binary is dylib
|
|
// ->just add, since will be processed as single item
|
|
else
|
|
{
|
|
//sync to save
|
|
@synchronized(self.flaggedItems)
|
|
{
|
|
//add
|
|
[self.flaggedItems addObject:flaggedItem];
|
|
}
|
|
}
|
|
}
|
|
|
|
//always reload
|
|
[self.flaggedItemTable reloadData];
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
//init the UI
|
|
// ->each time window is shown, reset, show spinner if needed, etc
|
|
-(void)initUI
|
|
{
|
|
//center
|
|
[self.window center];
|
|
|
|
//table reload
|
|
// ->make sure all is reset
|
|
[self.flaggedItemTable reloadData];
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
//table delegate
|
|
// ->return number of rows, which is just number of items in the currently selected plugin
|
|
-(NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
|
|
{
|
|
return self.flaggedItems.count;
|
|
}
|
|
|
|
//table delegate method
|
|
// ->return cell for row
|
|
-(NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
|
|
{
|
|
//row view
|
|
NSView* rowView = nil;
|
|
|
|
//sanity check
|
|
// ->make sure there is table item for row
|
|
if(row >= self.flaggedItems.count)
|
|
{
|
|
//bail
|
|
goto bail;
|
|
}
|
|
|
|
//create the view
|
|
// ->inits row w/ all required info
|
|
rowView = createItemView(tableView, self, [self.flaggedItems objectAtIndex:row]);
|
|
|
|
//bail
|
|
bail:
|
|
|
|
return rowView;
|
|
}
|
|
|
|
//automatically invoked
|
|
// ->create custom (sub-classed) NSTableRowView
|
|
-(NSTableRowView *)tableView:(NSTableView *)tableView rowViewForRow:(NSInteger)row
|
|
{
|
|
//row view
|
|
KKRow* rowView = nil;
|
|
|
|
//row ID
|
|
static NSString* const kRowIdentifier = @"TableRowView";
|
|
|
|
//try grab existing row view
|
|
rowView = [tableView makeViewWithIdentifier:kRowIdentifier owner:self];
|
|
|
|
//make new if needed
|
|
if(nil == rowView)
|
|
{
|
|
//create new
|
|
// ->size doesn't matter
|
|
rowView = [[KKRow alloc] initWithFrame:NSZeroRect];
|
|
|
|
//set row ID
|
|
rowView.identifier = kRowIdentifier;
|
|
}
|
|
|
|
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
|
|
{
|
|
//item
|
|
id item = nil;
|
|
|
|
//binary
|
|
Binary* binary = 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 binary
|
|
if(YES == [item isKindOfClass:[Task class]])
|
|
{
|
|
//get binary
|
|
binary = ((Task*)item).binary;
|
|
}
|
|
//binaries
|
|
// ->can use as is
|
|
else if(YES == [item isKindOfClass:[Binary class]])
|
|
{
|
|
//set
|
|
binary = item;
|
|
}
|
|
|
|
//sanity check
|
|
if(nil == binary)
|
|
{
|
|
//bail
|
|
goto bail;
|
|
}
|
|
|
|
//alloc/init info window
|
|
vtWindowController = [[VTInfoWindowController alloc] initWithItem:binary];
|
|
|
|
//show it
|
|
[self.vtWindowController.windowController showWindow:self];
|
|
|
|
|
|
//bail
|
|
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;
|
|
|
|
//file open error alert
|
|
NSAlert* errorAlert = nil;
|
|
|
|
//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 item in Finder
|
|
// ->error alert shown if file open fails
|
|
if(YES != [[NSWorkspace sharedWorkspace] selectFile:path inFileViewerRootedAtPath:@""])
|
|
{
|
|
//alloc/init alert
|
|
errorAlert = [NSAlert alertWithMessageText:[NSString stringWithFormat:@"ERROR:\nfailed to open %@", path] defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@"errno value: %d", errno];
|
|
|
|
//show it
|
|
[errorAlert runModal];
|
|
}
|
|
|
|
//bail
|
|
bail:
|
|
|
|
return;
|
|
}
|
|
|
|
@end
|