diff --git a/AppDelegate.h b/AppDelegate.h
index e015e38..2c5a6b4 100755
--- a/AppDelegate.h
+++ b/AppDelegate.h
@@ -32,7 +32,7 @@
}
//@property (readonly) NSViewController *currentViewController;
-@property(nonatomic, retain)NSViewController *currentViewController;
+//@property(nonatomic, retain)NSViewController *currentViewController;
//(current) bottom view controller
@property(nonatomic, retain)TaskTableController *bottomViewController;
@@ -125,20 +125,10 @@
// ->provide mouse over effects
-(void)initTrackingAreas;
-//create instances of all registered plugins
-//-(NSMutableArray*)instantiatePlugins;
-
-//callback method, invoked by plugin(s) when item is found
-// ->update the 'total' count and the item table (if active plugin is selected in UI)
--(void)itemFound:(Task*)task;
-
//callback method, invoked by virus total when plugin's items have been processed
// ->reload table if plugin matches active plugin
//-(void)itemsProcessed:(PluginBase*)plugin;
-//callback method, invoked by category table controller when user selects category
-// ->save the selected plugin & reload the item table
--(void)categorySelected:(NSUInteger)rowIndex;
//callback when user has updated prefs
// ->reload table, etc
@@ -182,5 +172,9 @@
//begin task enumeration
-(void)exploreTasks;
+//sort tasks
+// ->either name (flat view) or pid (tree view)
+-(void)sortTasksForView:(OrderedDictionary*)tasks;
+
@end
diff --git a/AppDelegate.m b/AppDelegate.m
index 4baf3a5..276a9a4 100755
--- a/AppDelegate.m
+++ b/AppDelegate.m
@@ -40,7 +40,7 @@
@synthesize topPane;
@synthesize taskEnumerator;
//@synthesize treeViewController;
-@synthesize currentViewController;
+//@synthesize currentViewController;
@synthesize viewSelector;
@@ -317,10 +317,10 @@
-(void)changeViewController
{
//remove old view
- if([self.currentViewController view] != nil)
+ if([self.taskTableController view] != nil)
{
//remove
- [[self.currentViewController view] removeFromSuperview];
+ [[self.taskTableController view] removeFromSuperview];
}
switch(self.taskViewFormat)
@@ -329,35 +329,39 @@
{
//alloc/init
taskTableController = [[TaskTableController alloc] initWithNibName:@"FlatView" bundle:nil];
- if(self.taskTableController != nil)
+ /*if(self.taskTableController != nil)
{
//update iVar
self.currentViewController = self.taskTableController;
- }
+ }*/
break;
}
case TREE_VIEW:
{
//alloc/init
taskTableController = [[TaskTableController alloc] initWithNibName:@"TreeView" bundle:nil];
- if(self.taskTableController != nil)
+
+
+
+ /*if(self.taskTableController != nil)
{
//update iVar
self.currentViewController = self.taskTableController;
- }
+ }*/
break;
}
}
//add subview
- [self.topPane addSubview:[self.currentViewController view]];
+ [self.topPane addSubview:[self.taskTableController view]];
//set frame
- [[self.currentViewController view] setFrame:[self.topPane bounds]];
+ [[self.taskTableController view] setFrame:[self.topPane bounds]];
return;
}
+//TODO: add checks to make sure or handle switch to tree view!!!!
//reload (to re-draw) a specific row in table
-(void)reloadRow:(Task*)task item:(ItemBase*)item pane:(NSUInteger)pane
{
@@ -371,32 +375,56 @@
if(PANE_TOP == pane)
{
//get row that task is loaded in
- tableView = [((id)self.currentViewController) itemView];
+ tableView = [((id)self.taskTableController) itemView];
- //get index where task is
- // TODO: doesn't account for filtering, etc!!!
- row = [self.taskEnumerator.tasks indexOfKey:task.pid];
- if(NSNotFound == row)
+ //reloadItem
+ // ->flat view
+ if(YES != [tableView isKindOfClass:[NSOutlineView class]])
{
- //bail
- goto bail;
+ //get index where task is
+ // TODO: doesn't account for filtering, etc!!!
+ row = [self.taskEnumerator.tasks indexOfKey:task.pid];
+ if(NSNotFound == row)
+ {
+ //bail
+ goto bail;
+ }
+
+ //reload just the row
+ // ->on main thread
+ dispatch_async(dispatch_get_main_queue(), ^{
+
+ //begin updates
+ [tableView beginUpdates];
+
+ //reload row
+ [tableView reloadDataForRowIndexes:[NSIndexSet indexSetWithIndex:(row)] columnIndexes:[NSIndexSet indexSetWithIndex:0]];
+
+ //end updates
+ [tableView endUpdates];
+
+ });
}
-
- //dbg msg
- //NSLog(@"updating row: %d", row);
-
- //reload just the row
- // ->on main thread
- dispatch_async(dispatch_get_main_queue(), ^{
+ //reload item
+ // ->tree view
+ else
+ {
+ //begin updates
+ [tableView beginUpdates];
- //reload row
- [tableView reloadDataForRowIndexes:[NSIndexSet indexSetWithIndex:(row)] columnIndexes:[NSIndexSet indexSetWithIndex:0]];
+ //reload
+ [(NSOutlineView*)tableView reloadItem:task];
- });
+ //end updates
+ [tableView endUpdates];
+ }
}
+ //TODO: bottom pane
+
+
//bail
bail:
@@ -410,10 +438,11 @@ bail:
//tag
NSUInteger segmentTag = 0;
+ /*
if(YES == [task.binary.name isEqualToString:@"launchd"])
{
NSLog(@"asdf");
- }
+ }*/
//get segment tag
segmentTag = [[self.bottomPaneBtn selectedCell] tagForSegment:[self.bottomPaneBtn selectedSegment]];
@@ -614,25 +643,35 @@ bail:
return;
}
-//reload task table
-// invoke custom refresh method on main thread
--(void)reloadTaskTable
+//TODO: don't think we need to sort by pid, since tree view, just uses kids!!!
+//sort tasks
+// ->either name (flat view) or pid (tree view)
+-(void)sortTasksForView:(OrderedDictionary*)tasks;
{
//sort tasks
// ->flat view, sort by name
if(FLAT_VIEW == self.taskViewFormat)
{
//sort
- [self.taskEnumerator.tasks sort:SORT_BY_NAME];
+ [tasks sort:SORT_BY_NAME];
}
//sort tasks
// ->tree view, sort by pid
else
{
//sort
- [self.taskEnumerator.tasks sort:SORT_BY_PID];
+ [tasks sort:SORT_BY_PID];
}
+ return;
+}
+
+//reload task table
+// invoke custom refresh method on main thread
+-(void)reloadTaskTable
+{
+ //sort tasks
+ [self sortTasksForView:self.taskEnumerator.tasks];
//when exec'ing on background thread
// ->exec on main thread
@@ -643,7 +682,7 @@ bail:
//refresh
//[self.taskTableController refresh];
- [(id)self.currentViewController refresh];
+ [(id)self.taskTableController refresh];
});
}
@@ -655,86 +694,12 @@ bail:
//TODO: currentViewCont?!?
//refresh
//[(id)self.taskTableController refresh];
- [(id)self.currentViewController refresh];
+ [(id)self.taskTableController refresh];
}
return;
}
-//callback method, invoked by plugin(s) when item is found
-// ->update the 'total' count and the item table (if it's selected)
--(void)itemFound:(Task*)task
-{
- //active plugin object
- //PluginBase* activePlugin = nil;
-
- //item
- //ItemBase* uncoveredItem = nil;
-
- //item backing item table
- // ->depending on flilter status, either all items, or just known ones
- //NSArray* = nil;
-
- //grab active plugin object
- //activePlugin = self.plugins[self.activePluginIndex];
-
- //extract uncovered item
- // ->either File obj, Command obj, or Extension obj
- //uncoveredItem = [activePlugin.allItems lastObject];
-
- //only show refresh table if
- // a) filter is not enabled (e.g. show all)
- // b) filtering is enable, but item is unknown
- //if( (YES == self.prefsWindowController.showTrustedItems) ||
- // ((YES != self.prefsWindowController.showTrustedItems) && (YES != uncoveredItem.isTrusted)) )
- //{
- /*
- //set table item array
- // ->case: all
- if(YES == self.prefsWindowController.showTrustedItems)
- {
- //set to all items
- tableItems = activePlugin.allItems;
- }
- //set table item array
- // ->case: unknown items
- else
- {
- //set to unknown items
- tableItems = activePlugin.unknownItems;
- }
- */
- //reload category table (on main thread)
- // ->this will result in the 'total' being updated
- dispatch_sync(dispatch_get_main_queue(), ^{
-
- //begin updates
- [[((id)self.currentViewController) itemView] beginUpdates];
-
- //update category table row
- // ->this will result in the 'total' being updated
- //[self.categoryTableController.categoryTableView reloadDataForRowIndexes:[NSIndexSet indexSetWithIndex:self.activePluginIndex] columnIndexes:[NSIndexSet indexSetWithIndex:0]];
-
- //if this plugin is currently the selected one (in the category table)
- // ->update the item row
- //if(self.selectedPlugin == activePlugin)
- //{
- //first tell item table the # of items have changed
- //[self.taskTableController.itemView noteNumberOfRowsChanged];
- [[((id)self.currentViewController) itemView] noteNumberOfRowsChanged];
-
- //reload just the new row
- // [self.itemTableController.itemTableView reloadDataForRowIndexes:[NSIndexSet indexSetWithIndex:(tableItems.count-1)] columnIndexes:[NSIndexSet indexSetWithIndex:0]];
- //}
-
- //end updates
- //[self.taskTableController.itemView endUpdates];
- [[((id)self.currentViewController) itemView] beginUpdates];
- });
- //}
-
- return;
-}
/*
//callback method, invoked by virus total when plugin's items have been processed
@@ -813,21 +778,6 @@ bail:
*/
-//callback method, invoked by category table controller when OS/user clicks a row
-// ->lookup/save the selected plugin & reload the item table
--(void)categorySelected:(NSUInteger)rowIndex
-{
- //save selected plugin
- //self.selectedPlugin = self.plugins[rowIndex];
-
- //scroll to top of item table
- [self.taskTableController scrollToTop];
-
- //reload item table
- [self.taskTableController.itemView reloadData];
-
- return;
-}
//callback when user has updated prefs
// ->reload table, etc
diff --git a/Consts.h b/Consts.h
index 4d2488b..a11e27d 100644
--- a/Consts.h
+++ b/Consts.h
@@ -300,6 +300,9 @@
#define SORT_BY_NAME 0x1
+//delta for pid tag
+#define PID_TAG_DELTA 1000
+
diff --git a/ItemView.m b/ItemView.m
index bf61b04..a97634f 100644
--- a/ItemView.m
+++ b/ItemView.m
@@ -10,6 +10,7 @@
#import "ItemView.h"
#import "VTButton.h"
#import "AppDelegate.h"
+#import "kkRowCell.h"
#import "3rdParty/OrderedDictionary.h"
//create customize item view
@@ -68,6 +69,10 @@ NSTableCellView* createItemView(NSTableView* tableView, id owner, id item)
{
//create & config view
itemCell = createTaskView(tableView, owner, item);
+
+ //set tag
+ // ->task pid (allows lookup later)
+ ((kkRowCell*)itemCell).tag = [((Task*)item).pid integerValue] + PID_TAG_DELTA;
}
//logic to create dylib view
@@ -91,6 +96,8 @@ NSTableCellView* createItemView(NSTableView* tableView, id owner, id item)
itemCell = createNetworkView(tableView, owner, item);
}
+
+
return itemCell;
diff --git a/KKRow.h b/KKRow.h
index e4c4c93..76c902e 100644
--- a/KKRow.h
+++ b/KKRow.h
@@ -10,4 +10,5 @@
@interface KKRow : NSTableRowView
+
@end
diff --git a/TaskEnumerator.h b/TaskEnumerator.h
index 5fec2a9..b956adb 100644
--- a/TaskEnumerator.h
+++ b/TaskEnumerator.h
@@ -61,5 +61,13 @@
// ->generally yes, unless the first enumeration (of all tasks) is not complete
//-(BOOL)shouldEnumDylibs;
+//remove a task
+// ->contain extra logic to remove children, etc
+-(void)removeTask:(Task*)task;
+
+//given a task
+// ->get list of all child pids
+-(void)getAllChildren:(Task*)parent children:(NSMutableArray*)children;
+
@end
diff --git a/TaskEnumerator.m b/TaskEnumerator.m
index 0516a57..cdd0446 100644
--- a/TaskEnumerator.m
+++ b/TaskEnumerator.m
@@ -130,14 +130,15 @@
continue;
}
- //enumerate task's dylibs
- //[newTask enumerateDylibs:self.xpcConnection allDylibs:self.dylibs];
-
//add new task
[self.tasks setObject:newTask forKey:newTask.pid];
}//add new tasks
+ //sort tasks
+ // ->ensures that signing info etc w/ be generated for (top) visible tasks
+ [((AppDelegate*)[[NSApplication sharedApplication] delegate]) sortTasksForView:newTasks];
+
//reload task table
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) reloadTaskTable];
@@ -294,7 +295,17 @@ bail:
NSUInteger childIndex = 0;
//init comparator
- comparator = ^(id obj1, id obj2) { return NSOrderedSame; };
+ // ->sort pids
+ comparator = ^(id obj1, id obj2)
+ {
+ if (obj1 < obj2)
+ return NSOrderedAscending;
+
+ if (obj1 > obj2)
+ return NSOrderedDescending;
+
+ return NSOrderedSame;
+ };
//interate over all task
// ->insert task into parent's *ordered* child array
@@ -327,4 +338,66 @@ bail:
return;
}
+//remove a task
+// ->contain extra logic to remove children, etc
+-(void)removeTask:(Task*)task
+{
+ //parent
+ Task* parent = nil;
+
+ //children
+ NSMutableArray* children = nil;
+
+ //alloc array for children
+ children = [NSMutableArray array];
+
+ //get all children
+ [self getAllChildren:task children:children];
+
+ //remove all child tasks
+ for(NSNumber* childPid in children)
+ {
+ //remove
+ [self.tasks removeObjectForKey:childPid];
+ }
+
+ //remove task
+ [self.tasks removeObjectForKey:task.pid];
+
+ //get parent
+ parent = [self.tasks objectForKey:task.ppid];
+
+ //remove task from parent's list of children
+ [parent.children removeObject:task.pid];
+
+ return;
+
+}
+
+//given a task
+// ->get list of all child pids
+-(void)getAllChildren:(Task*)parent children:(NSMutableArray*)children
+{
+ //child task
+ Task* childTask = nil;
+
+ //add parent's children
+ [children addObjectsFromArray:parent.children];
+
+ for(NSNumber* childPid in parent.children)
+ {
+ //get child task
+ childTask = self.tasks[childPid];
+
+ if(0 != [childTask.children count])
+ {
+ //recurse
+ [self getAllChildren:childTask children:children];
+ }
+ }
+
+ return;
+}
+
+
@end
diff --git a/TaskExplorer.xcodeproj/xcuserdata/patrick.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/TaskExplorer.xcodeproj/xcuserdata/patrick.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
index b0bb648..ca56366 100644
--- a/TaskExplorer.xcodeproj/xcuserdata/patrick.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
+++ b/TaskExplorer.xcodeproj/xcuserdata/patrick.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
@@ -19,29 +19,13 @@
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
- filePath = "Task.m"
- timestampString = "456217349.500536"
+ filePath = "TaskEnumerator.m"
+ timestampString = "456469787.454434"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
- startingLineNumber = "551"
- endingLineNumber = "551"
- landmarkName = "-enumerateNetworking:"
- landmarkType = "5">
-
-
-
-
@@ -52,236 +36,12 @@
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "AppDelegate.m"
- timestampString = "456302892.352739"
+ timestampString = "456474906.073599"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
- startingLineNumber = "408"
- endingLineNumber = "408"
- landmarkName = "-reloadBottomPane:itemView:"
- landmarkType = "5">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -292,28 +52,76 @@
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "TaskTableController.m"
- timestampString = "456305690.622084"
+ timestampString = "456474649.232255"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
- startingLineNumber = "40"
- endingLineNumber = "40"
- landmarkName = "-awakeFromNib"
+ startingLineNumber = "711"
+ endingLineNumber = "711"
+ landmarkName = "-refresh"
landmarkType = "5">
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/TaskTableController.h b/TaskTableController.h
index 432f354..8bb5bba 100644
--- a/TaskTableController.h
+++ b/TaskTableController.h
@@ -20,6 +20,9 @@
}
+//flag for first time init's
+@property BOOL didInit;
+
//tasks
// ->updated by task enumerator
//@property(nonatomic, retain)OrderedDictionary* tasks;
@@ -77,5 +80,9 @@
// ->for now, just looks at 'tableItems' iVar
-(BOOL)isTopPane;
+//handle when user clicks row
+// ->update bottom pane w/ task's dylibs/files/etc
+-(void)handleRowSelection;
+
@end
diff --git a/TaskTableController.m b/TaskTableController.m
index 38e59c3..ddbda8b 100644
--- a/TaskTableController.m
+++ b/TaskTableController.m
@@ -25,6 +25,8 @@
#import
+//TODO: need to do some sync or logic to handle swaps -otherwise crashes!!!
+
@implementation TaskTableController
@synthesize itemView;
@@ -34,13 +36,33 @@
@synthesize vtWindowController;
@synthesize infoWindowController;
-
+@synthesize didInit;
//@synthesize tasks;
+
+//TODO: called many timesss
-(void)awakeFromNib
{
- self.selectedRow = -1;
+ if(YES != didInit)
+ {
+ self.selectedRow = -1;
+
+ //for outline (tree) view
+ // ->expand
+ if(YES == [self.itemView isKindOfClass:[NSOutlineView class]])
+ {
+ [(NSOutlineView*)self.itemView expandItem:nil expandChildren:YES];
+ }
+
+ //set flag
+ self.didInit = YES;
+
+ }
+
+ //self.selectedRow = -1;
+
+ /*
//for outline (tree) view
// ->expand
if(YES == [self.itemView isKindOfClass:[NSOutlineView class]])
@@ -50,9 +72,9 @@
//TODO: do this in IB?
//[itemView setTarget:self];
}
+ */
- NSLog(@"item view: %@", self.itemView);
-
+
/*
NSString *title = @"[ all tasks ]";
NSTableColumn *yourColumn = self.itemView.tableColumns.lastObject;
@@ -114,103 +136,9 @@
// ->only care about for top pane, trigger load bottom view
-(void)tableViewSelectionDidChange:(NSNotification *)notification
{
- //tasks
- __block OrderedDictionary* tasks = nil;
+ //handle selection
+ [self handleRowSelection];
- //task
- Task* task = nil;
-
- //newly selected row (index)
- __block NSInteger newlySelectedRow = -1;
-
- //selected row cell
- NSTableCellView* selectedView = nil;
-
- //ignore events for bottom-pane
- if(YES == self.isBottomPane)
- {
- //ignore
- goto bail;
- }
-
- //get index of newly selected row
- newlySelectedRow = [self.itemView selectedRow];
-
- //get row that's about to be selected
- selectedView = [self.itemView viewAtColumn:0 row:newlySelectedRow makeIfNecessary:YES];
-
- //grab task
- task = [self taskForRow:nil];
-
- //check if task is dead
- if(YES != isAlive([task.pid intValue]))
- {
- //make it red
- ((kkRowCell*)selectedView).color = [NSColor redColor];
-
- //draw
- [selectedView setNeedsDisplay:YES];
-
- //make hide it after 1/4th second
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
-
- //reset color
- ((kkRowCell*)selectedView).color = nil;
-
- //get tasks
- tasks = ((AppDelegate*)[[NSApplication sharedApplication] delegate]).taskEnumerator.tasks;
-
- //remove (now dead) task
- [tasks removeObjectForKey:task.pid];
-
- //reload table
- [self.itemView reloadData];
-
- //sanity check
- // ->make sure removed task wasn't last
- if(tasks.count <= newlySelectedRow)
- {
- //reset to (new) last
- newlySelectedRow = tasks.count - 1;
- }
- //sanity check
- // ->reset to first item on other errors
- else if(-1 == newlySelectedRow)
- {
- //set to first
- newlySelectedRow = 0;
- }
-
- //re-select
- [self.itemView selectRowIndexes:[NSIndexSet indexSetWithIndex:newlySelectedRow] byExtendingSelection:NO];
-
- });
-
- //bail
- goto bail;
-
- }
-
- //ignore if row selection didn't change
- if([self.itemView selectedRow] == self.selectedRow)
- {
- //ignore
- goto bail;
- }
-
- //save newly selected row index
- self.selectedRow = [self.itemView selectedRow];
-
- //save currently selected task
- ((AppDelegate*)[[NSApplication sharedApplication] delegate]).currentTask = task;
-
- //reload bottom pane
- [((AppDelegate*)[[NSApplication sharedApplication] delegate]) selectBottomPaneContent:nil];
-
-
-//bail
-bail:
-
return;
}
@@ -811,20 +739,31 @@ bail:
// ->but only if task still exists (e.g. didn't exit)
if(NSNotFound != taskIndex)
{
+ //begin updates
+ [self.itemView beginUpdates];
+
//(re)select
[self.itemView selectRowIndexes:[NSIndexSet indexSetWithIndex:taskIndex] byExtendingSelection:NO];
+
+ //end updates
+ [self.itemView endUpdates];
}
}
return;
}
+
+//TODO: make sure this works for outline view!!!
//grab a task at a row
-(Task*)taskForRow:(id)sender
{
//index of row
NSInteger taskRow = 0;
+ //selected row cell
+ NSTableCellView* rowView = nil;
+
//tasks
OrderedDictionary* tasks = nil;
@@ -845,6 +784,7 @@ bail:
{
//grab row
taskRow = [self.itemView selectedRow];
+
}
//sanity check(s)
@@ -858,7 +798,14 @@ bail:
//get task object
// ->by index to get key, then by key
- task = tasks[[tasks keyAtIndex:taskRow]];
+ //task = tasks[[tasks keyAtIndex:taskRow]];
+
+ //get row that's about to be selected
+ rowView = [self.itemView viewAtColumn:0 row:taskRow makeIfNecessary:YES];
+
+ //extract task
+ // ->pid of task is view's id :)
+ task = tasks[[NSNumber numberWithInteger:(rowView.tag - PID_TAG_DELTA)]];
//bail
bail:
@@ -866,7 +813,7 @@ bail:
return task;
}
-
+
//grab an item at a row
-(ItemBase*)itemForRow:(id)sender
{
@@ -1122,7 +1069,7 @@ bail:
//return !item ? YES : [[item children] count] != 0;
}
-//TODO: sort children!!!
+
//return child
-(id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item
@@ -1153,105 +1100,12 @@ bail:
}
-//TODO: combine logic - and make taskForRow method work for flat and tree views :)
+//TODO: combine logic -
+//TODO: when combine, use pid of task is view's id - to lookup task :)
- (void)outlineViewSelectionDidChange:(NSNotification *)notification
{
- //tasks
- __block OrderedDictionary* tasks = nil;
-
- //task
- Task* task = nil;
-
- //newly selected row (index)
- __block NSInteger newlySelectedRow = -1;
-
- //selected row cell
- NSTableCellView* selectedView = nil;
-
- //ignore events for bottom-pane
- if(YES == self.isBottomPane)
- {
- //ignore
- goto bail;
- }
-
- //get index of newly selected row
- newlySelectedRow = [self.itemView selectedRow];
-
- //get row that's about to be selected
- selectedView = [self.itemView viewAtColumn:0 row:newlySelectedRow makeIfNecessary:YES];
-
- //grab task
- task = [self taskForRow:nil];
-
- //check if task is dead
- if(YES != isAlive([task.pid intValue]))
- {
- //make it red
- ((kkRowCell*)selectedView).color = [NSColor redColor];
-
- //draw
- [selectedView setNeedsDisplay:YES];
-
- //make hide it after 1/4th second
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
-
- //reset color
- ((kkRowCell*)selectedView).color = nil;
-
- //get tasks
- tasks = ((AppDelegate*)[[NSApplication sharedApplication] delegate]).taskEnumerator.tasks;
-
- //remove (now dead) task
- [tasks removeObjectForKey:task.pid];
-
- //reload table
- [self.itemView reloadData];
-
- //sanity check
- // ->make sure removed task wasn't last
- if(tasks.count <= newlySelectedRow)
- {
- //reset to (new) last
- newlySelectedRow = tasks.count - 1;
- }
- //sanity check
- // ->reset to first item on other errors
- else if(-1 == newlySelectedRow)
- {
- //set to first
- newlySelectedRow = 0;
- }
-
- //re-select
- [self.itemView selectRowIndexes:[NSIndexSet indexSetWithIndex:newlySelectedRow] byExtendingSelection:NO];
-
- });
-
- //bail
- goto bail;
-
- }
-
- //ignore if row selection didn't change
- if([self.itemView selectedRow] == self.selectedRow)
- {
- //ignore
- goto bail;
- }
-
- //save newly selected row index
- self.selectedRow = [self.itemView selectedRow];
-
- //save currently selected task
- ((AppDelegate*)[[NSApplication sharedApplication] delegate]).currentTask = task;
-
- //reload bottom pane
- [((AppDelegate*)[[NSApplication sharedApplication] delegate]) selectBottomPaneContent:nil];
-
-
- //bail
-bail:
+ //handle selection
+ [self handleRowSelection];
return;
}
@@ -1290,4 +1144,127 @@ bail:
return rowView;
}
+/* LOGIC FOR BOTH */
+
+//handle when user clicks row
+// ->update bottom pane w/ task's dylibs/files/etc
+-(void)handleRowSelection
+{
+ //tasks
+ __block OrderedDictionary* tasks = nil;
+
+ //task
+ Task* task = nil;
+
+ //newly selected row (index)
+ __block NSInteger newlySelectedRow = -1;
+
+ //selected row cell
+ NSTableCellView* selectedView = nil;
+
+ //ignore events for bottom-pane
+ if(YES == self.isBottomPane)
+ {
+ //ignore
+ goto bail;
+ }
+
+ //grab tasks
+ tasks = ((AppDelegate*)[[NSApplication sharedApplication] delegate]).taskEnumerator.tasks;
+
+ //get index of newly selected row
+ newlySelectedRow = [self.itemView selectedRow];
+
+ //sanity check
+ if( (-1 == newlySelectedRow) ||
+ (newlySelectedRow >= tasks.count) )
+ {
+ //bail
+ goto bail;
+ }
+
+ //get row that's about to be selected
+ selectedView = [self.itemView viewAtColumn:0 row:newlySelectedRow makeIfNecessary:YES];
+
+ //extract task
+ // ->pid of task is view's id :)
+ task = tasks[[NSNumber numberWithInteger:(selectedView.tag - PID_TAG_DELTA)]];
+
+ //check if task is dead
+ if(YES != isAlive([task.pid intValue]))
+ {
+ //make it red
+ ((kkRowCell*)selectedView).color = [NSColor redColor];
+
+ //draw
+ [selectedView setNeedsDisplay:YES];
+
+ //make hide it after 1/4th second
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+
+ //reset color
+ ((kkRowCell*)selectedView).color = nil;
+
+ //remove task
+ [((AppDelegate*)[[NSApplication sharedApplication] delegate]).taskEnumerator removeTask:task];
+
+ //reload table
+ [self.itemView reloadData];
+
+ //sanity check
+ // ->make sure removed task wasn't last
+ if(tasks.count <= newlySelectedRow)
+ {
+ //reset to (new) last
+ newlySelectedRow = tasks.count - 1;
+ }
+ //sanity check
+ // ->reset to first item on other errors
+ else if(-1 == newlySelectedRow)
+ {
+ //set to first
+ newlySelectedRow = 0;
+ }
+
+ //begin updates
+ [self.itemView beginUpdates];
+
+ //re-select
+ [self.itemView selectRowIndexes:[NSIndexSet indexSetWithIndex:newlySelectedRow] byExtendingSelection:NO];
+
+ //end updates
+ [self.itemView endUpdates];
+ });
+
+ //bail
+ goto bail;
+
+ }
+
+
+ //ignore if row selection didn't change
+ if([self.itemView selectedRow] == self.selectedRow)
+ {
+ //ignore
+ goto bail;
+ }
+
+ //save newly selected row index
+ self.selectedRow = [self.itemView selectedRow];
+
+ //save currently selected task
+ ((AppDelegate*)[[NSApplication sharedApplication] delegate]).currentTask = task;
+
+ //reload bottom pane
+ [((AppDelegate*)[[NSApplication sharedApplication] delegate]) selectBottomPaneContent:nil];
+
+
+//bail
+bail:
+
+ ;
+
+}
+
+
@end
diff --git a/kkRowCell.h b/kkRowCell.h
index c6b01bf..067a6d1 100644
--- a/kkRowCell.h
+++ b/kkRowCell.h
@@ -15,6 +15,9 @@
/* PROPERTIES */
+//tag
+@property NSInteger tag;
+
//color
@property(nonatomic, retain)NSColor* color;
diff --git a/kkRowCell.m b/kkRowCell.m
index 639bba1..a3bbea1 100644
--- a/kkRowCell.m
+++ b/kkRowCell.m
@@ -10,6 +10,8 @@
@implementation kkRowCell
+@synthesize tag;
+
//draw method
- (void)drawRect:(NSRect)dirtyRect
diff --git a/main.m b/main.m
index 8e94c27..110a5cf 100755
--- a/main.m
+++ b/main.m
@@ -8,6 +8,8 @@
#import
+
+//TODO: add [tableView beginUpdates];
int main(int argc, char *argv[])
{
return NSApplicationMain(argc, (const char **)argv);