fixed table issues (between outline an normal view)

code cleanup
task lookup by row.tag
This commit is contained in:
Patrick Wardle
2015-06-19 20:43:59 -10:00
parent ee9b80ddb9
commit df5bba18e6
13 changed files with 432 additions and 597 deletions
+5 -11
View File
@@ -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
View File
@@ -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
+3
View File
@@ -300,6 +300,9 @@
#define SORT_BY_NAME 0x1
//delta for pid tag
#define PID_TAG_DELTA 1000
+7
View File
@@ -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;
+1
View File
@@ -10,4 +10,5 @@
@interface KKRow : NSTableRowView
@end
+8
View File
@@ -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
View File
@@ -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
@@ -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>
+7
View File
@@ -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
View File
@@ -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
+3
View File
@@ -15,6 +15,9 @@
/* PROPERTIES */
//tag
@property NSInteger tag;
//color
@property(nonatomic, retain)NSColor* color;
+2
View File
@@ -10,6 +10,8 @@
@implementation kkRowCell
@synthesize tag;
//draw method
- (void)drawRect:(NSRect)dirtyRect
+2
View File
@@ -8,6 +8,8 @@
#import <Cocoa/Cocoa.h>
//TODO: add [tableView beginUpdates];
int main(int argc, char *argv[])
{
return NSApplicationMain(argc, (const char **)argv);