Files
TaskExplorer/FlaggedItemWindowController.m
T
2018-12-18 21:13:23 -10:00

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