mirror of
https://github.com/objective-see/TaskExplorer.git
synced 2026-03-22 07:02:39 +00:00
fixed table issues (between outline an normal view)
code cleanup task lookup by row.tag
This commit is contained in:
+5
-11
@@ -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
|
||||
|
||||
+73
-123
@@ -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
|
||||
|
||||
@@ -300,6 +300,9 @@
|
||||
#define SORT_BY_NAME 0x1
|
||||
|
||||
|
||||
//delta for pid tag
|
||||
#define PID_TAG_DELTA 1000
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
+77
-4
@@ -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
|
||||
|
||||
+67
-259
@@ -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">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "Task.m"
|
||||
timestampString = "456217349.500536"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "421"
|
||||
endingLineNumber = "421"
|
||||
landmarkName = "-enumerateDylibs:allDylibs:"
|
||||
startingLineNumber = "343"
|
||||
endingLineNumber = "343"
|
||||
landmarkName = "-removeTask:"
|
||||
landmarkType = "5">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
@@ -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">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "AppDelegate.m"
|
||||
timestampString = "456302892.352739"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "415"
|
||||
endingLineNumber = "415"
|
||||
landmarkName = "-reloadBottomPane:itemView:"
|
||||
landmarkType = "5">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "AppDelegate.m"
|
||||
timestampString = "456303370.767322"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "1380"
|
||||
endingLineNumber = "1380"
|
||||
landmarkName = "-selectBottomPaneContent:"
|
||||
landmarkType = "5">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "AppDelegate.m"
|
||||
timestampString = "456303370.767322"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "1401"
|
||||
endingLineNumber = "1401"
|
||||
landmarkName = "-selectBottomPaneContent:"
|
||||
landmarkType = "5">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "AppDelegate.m"
|
||||
timestampString = "456303370.767322"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "1404"
|
||||
endingLineNumber = "1404"
|
||||
landmarkName = "-selectBottomPaneContent:"
|
||||
landmarkType = "5">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "kkRowCell.m"
|
||||
timestampString = "455918972.792996"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "15"
|
||||
endingLineNumber = "15"
|
||||
landmarkName = "-drawRect:"
|
||||
landmarkType = "5">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "Task.m"
|
||||
timestampString = "455933492.971073"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "95"
|
||||
endingLineNumber = "95"
|
||||
landmarkName = "-initWithPID:andPath:"
|
||||
landmarkType = "5">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "Queue.m"
|
||||
timestampString = "455934198.853999"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "94"
|
||||
endingLineNumber = "94"
|
||||
landmarkName = "-enqueue:"
|
||||
landmarkType = "5">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "InfoWindowController.m"
|
||||
timestampString = "455936252.706327"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "40"
|
||||
endingLineNumber = "40"
|
||||
landmarkName = "-initWithItem:"
|
||||
landmarkType = "5">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "InfoWindowController.m"
|
||||
timestampString = "455936279.739463"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "95"
|
||||
endingLineNumber = "95"
|
||||
landmarkName = "-configure"
|
||||
landmarkType = "5">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "remoteTaskService/remoteTaskService.m"
|
||||
timestampString = "456041912.657924"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "416"
|
||||
endingLineNumber = "416"
|
||||
landmarkName = "-enumerateNetwork:withReply:"
|
||||
landmarkType = "5">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "remoteTaskService/remoteTaskService.m"
|
||||
timestampString = "456041950.399168"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "508"
|
||||
endingLineNumber = "508"
|
||||
landmarkName = "-enumerateNetwork:withReply:"
|
||||
landmarkType = "5">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "Task.m"
|
||||
timestampString = "456217349.500536"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "574"
|
||||
endingLineNumber = "574"
|
||||
landmarkName = "-compare:"
|
||||
landmarkType = "5">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "TreeViewController.m"
|
||||
timestampString = "456305223.712479"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "63"
|
||||
endingLineNumber = "63"
|
||||
landmarkName = "-outlineView:isItemExpandable:"
|
||||
landmarkType = "5">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "TreeViewController.m"
|
||||
timestampString = "456305223.712479"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "82"
|
||||
endingLineNumber = "82"
|
||||
landmarkName = "-outlineView:child:ofItem:"
|
||||
startingLineNumber = "671"
|
||||
endingLineNumber = "671"
|
||||
landmarkName = "-reloadTaskTable"
|
||||
landmarkType = "5">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
@@ -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">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "Yes"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "TreeViewController.m"
|
||||
timestampString = "456305705.729474"
|
||||
filePath = "TaskTableController.m"
|
||||
timestampString = "456474649.232255"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "13"
|
||||
endingLineNumber = "13"
|
||||
landmarkName = "-awakeFromNib"
|
||||
startingLineNumber = "1122"
|
||||
endingLineNumber = "1122"
|
||||
landmarkName = "-outlineView:rowViewForItem:"
|
||||
landmarkType = "5">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "TaskTableController.m"
|
||||
timestampString = "456474649.232255"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "1115"
|
||||
endingLineNumber = "1115"
|
||||
landmarkName = "-outlineView:viewForTableColumn:item:"
|
||||
landmarkType = "5">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "TaskTableController.m"
|
||||
timestampString = "456474649.232255"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "1105"
|
||||
endingLineNumber = "1105"
|
||||
landmarkName = "-outlineViewSelectionDidChange:"
|
||||
landmarkType = "5">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "AppDelegate.m"
|
||||
timestampString = "456474979.625707"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "416"
|
||||
endingLineNumber = "416"
|
||||
landmarkName = "-reloadRow:item:pane:"
|
||||
landmarkType = "5">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
|
||||
@@ -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
|
||||
|
||||
+177
-200
@@ -25,6 +25,8 @@
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
//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
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
|
||||
/* PROPERTIES */
|
||||
|
||||
//tag
|
||||
@property NSInteger tag;
|
||||
|
||||
//color
|
||||
@property(nonatomic, retain)NSColor* color;
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
|
||||
@implementation kkRowCell
|
||||
|
||||
@synthesize tag;
|
||||
|
||||
|
||||
//draw method
|
||||
- (void)drawRect:(NSRect)dirtyRect
|
||||
|
||||
Reference in New Issue
Block a user