| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/cocoa/task_manager_mac.h" | 5 #include "chrome/browser/cocoa/task_manager_mac.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "app/l10n_util_mac.h" |
| 10 #include "base/mac_util.h" | 11 #include "base/mac_util.h" |
| 12 #include "base/sys_string_conversions.h" |
| 13 #include "grit/generated_resources.h" |
| 14 |
| 15 // TODO(thakis): Autoremember window size/pos (and selected columns?) |
| 16 // TODO(thakis): Link that opens about:memory |
| 17 // TODO(thakis): Activate button iff something is selected, hook it up |
| 18 // TODO(thakis): Column sort comparator |
| 19 // TODO(thakis): Clicking column header doesn't sort |
| 20 // TODO(thakis): Double-clicking a row seems to do something on win/linux |
| 21 // TODO(thakis): On window close, stop updating |
| 22 // TODO(thakis): Favicons in rows |
| 23 // TODO(thakis): Default sort column |
| 24 // TODO(thakis): Metrics are all wrong (some fixed when about:memory lands?) |
| 25 |
| 26 @interface TaskManagerWindowController (Private) |
| 27 - (void)addColumnWithId:(int)columnId visible:(BOOL)isVisible; |
| 28 - (void)setUpTableColumns; |
| 29 - (void)setUpTableHeaderContextMenu; |
| 30 - (void)toggleColumn:(id)sender; |
| 31 @end |
| 11 | 32 |
| 12 //////////////////////////////////////////////////////////////////////////////// | 33 //////////////////////////////////////////////////////////////////////////////// |
| 13 // TaskManagerWindowController implementation: | 34 // TaskManagerWindowController implementation: |
| 14 | 35 |
| 15 @implementation TaskManagerWindowController | 36 @implementation TaskManagerWindowController |
| 16 | 37 |
| 17 - (id)init { | 38 - (id)initWithModel:(TaskManagerModel*)model { |
| 18 NSString* nibpath = [mac_util::MainAppBundle() | 39 NSString* nibpath = [mac_util::MainAppBundle() |
| 19 pathForResource:@"TaskManager" | 40 pathForResource:@"TaskManager" |
| 20 ofType:@"nib"]; | 41 ofType:@"nib"]; |
| 21 if ((self = [super initWithWindowNibPath:nibpath owner:self])) { | 42 if ((self = [super initWithWindowNibPath:nibpath owner:self])) { |
| 43 model_ = model; |
| 22 [[self window] makeKeyAndOrderFront:self]; | 44 [[self window] makeKeyAndOrderFront:self]; |
| 23 } | 45 } |
| 24 return self; | 46 return self; |
| 25 } | 47 } |
| 26 | 48 |
| 49 - (void)reloadData { |
| 50 [tableView_ reloadData]; |
| 51 } |
| 52 |
| 53 - (void)awakeFromNib { |
| 54 [self setUpTableColumns]; |
| 55 [self setUpTableHeaderContextMenu]; |
| 56 } |
| 57 |
| 58 // Adds a column which has the given string id as title. |isVisible| specifies |
| 59 // if the column is initially visible. |
| 60 - (void)addColumnWithId:(int)columnId visible:(BOOL)isVisible { |
| 61 scoped_nsobject<NSTableColumn> column([[NSTableColumn alloc] |
| 62 initWithIdentifier:[NSNumber numberWithInt:columnId]]); |
| 63 |
| 64 NSTextAlignment textAlignment = columnId == IDS_TASK_MANAGER_PAGE_COLUMN ? |
| 65 NSLeftTextAlignment : NSRightTextAlignment; |
| 66 |
| 67 [[column.get() headerCell] |
| 68 setStringValue:l10n_util::GetNSStringWithFixup(columnId)]; |
| 69 [[column.get() headerCell] setAlignment:textAlignment]; |
| 70 [[column.get() dataCell] setAlignment:textAlignment]; |
| 71 |
| 72 [column.get() setHidden:!isVisible]; |
| 73 [column.get() setEditable:NO]; |
| 74 [tableView_ addTableColumn:column.get()]; |
| 75 } |
| 76 |
| 77 // Adds all the task manager's columns to the table. |
| 78 - (void)setUpTableColumns { |
| 79 for (NSTableColumn* column in [tableView_ tableColumns]) |
| 80 [tableView_ removeTableColumn:column]; |
| 81 [self addColumnWithId:IDS_TASK_MANAGER_PAGE_COLUMN visible:YES]; |
| 82 [self addColumnWithId:IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN visible:YES]; |
| 83 [self addColumnWithId:IDS_TASK_MANAGER_SHARED_MEM_COLUMN visible:NO]; |
| 84 [self addColumnWithId:IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN visible:NO]; |
| 85 [self addColumnWithId:IDS_TASK_MANAGER_CPU_COLUMN visible:YES]; |
| 86 [self addColumnWithId:IDS_TASK_MANAGER_NET_COLUMN visible:YES]; |
| 87 [self addColumnWithId:IDS_TASK_MANAGER_PROCESS_ID_COLUMN visible:NO]; |
| 88 [self addColumnWithId:IDS_TASK_MANAGER_GOATS_TELEPORTED_COLUMN visible:NO]; |
| 89 } |
| 90 |
| 91 // Creates a context menu for the table header that allows the user to toggle |
| 92 // which columns should be shown and which should be hidden (like e.g. |
| 93 // Task Manager.app's table header context menu). |
| 94 - (void)setUpTableHeaderContextMenu { |
| 95 scoped_nsobject<NSMenu> contextMenu( |
| 96 [[NSMenu alloc] initWithTitle:@"Task Manager context menu"]); |
| 97 for (NSTableColumn* column in [tableView_ tableColumns]) { |
| 98 NSMenuItem* item = [contextMenu.get() |
| 99 addItemWithTitle:[[column headerCell] stringValue] |
| 100 action:@selector(toggleColumn:) |
| 101 keyEquivalent:@""]; |
| 102 [item setTarget:self]; |
| 103 [item setRepresentedObject:column]; |
| 104 [item setState:[column isHidden] ? NSOffState : NSOnState]; |
| 105 } |
| 106 [[tableView_ headerView] setMenu:contextMenu.get()]; |
| 107 } |
| 108 |
| 109 // Callback for the table header context menu. Toggles visibility of the table |
| 110 // column associated with the clicked menu item. |
| 111 - (void)toggleColumn:(id)item { |
| 112 DCHECK([item isKindOfClass:[NSMenuItem class]]); |
| 113 if (![item isKindOfClass:[NSMenuItem class]]) |
| 114 return; |
| 115 |
| 116 NSTableColumn* column = [item representedObject]; |
| 117 DCHECK(column); |
| 118 NSInteger oldState = [item state]; |
| 119 NSInteger newState = oldState == NSOnState ? NSOffState : NSOnState; |
| 120 [column setHidden:newState == NSOffState]; |
| 121 [item setState:newState]; |
| 122 [tableView_ sizeToFit]; |
| 123 [tableView_ setNeedsDisplay]; |
| 124 } |
| 125 |
| 126 @end |
| 127 |
| 128 @implementation TaskManagerWindowController (NSTableDataSource) |
| 129 |
| 130 - (NSInteger)numberOfRowsInTableView:(NSTableView*)tableView { |
| 131 DCHECK(tableView == tableView_ || tableView_ == nil); |
| 132 return model_->ResourceCount(); |
| 133 } |
| 134 |
| 135 - (NSString*)modelTextForRow:(int)row column:(int)columnId { |
| 136 switch (columnId) { |
| 137 case IDS_TASK_MANAGER_PAGE_COLUMN: // Process |
| 138 return base::SysWideToNSString(model_->GetResourceTitle(row)); |
| 139 |
| 140 case IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN: // Memory |
| 141 if (!model_->IsResourceFirstInGroup(row)) |
| 142 return @""; |
| 143 return base::SysWideToNSString(model_->GetResourcePrivateMemory(row)); |
| 144 |
| 145 case IDS_TASK_MANAGER_SHARED_MEM_COLUMN: // Memory |
| 146 if (!model_->IsResourceFirstInGroup(row)) |
| 147 return @""; |
| 148 return base::SysWideToNSString(model_->GetResourceSharedMemory(row)); |
| 149 |
| 150 case IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN: // Memory |
| 151 if (!model_->IsResourceFirstInGroup(row)) |
| 152 return @""; |
| 153 return base::SysWideToNSString(model_->GetResourcePhysicalMemory(row)); |
| 154 |
| 155 case IDS_TASK_MANAGER_CPU_COLUMN: // CPU |
| 156 if (!model_->IsResourceFirstInGroup(row)) |
| 157 return @""; |
| 158 return base::SysWideToNSString(model_->GetResourceCPUUsage(row)); |
| 159 |
| 160 case IDS_TASK_MANAGER_NET_COLUMN: // Net |
| 161 return base::SysWideToNSString(model_->GetResourceNetworkUsage(row)); |
| 162 |
| 163 case IDS_TASK_MANAGER_PROCESS_ID_COLUMN: // Process ID |
| 164 if (!model_->IsResourceFirstInGroup(row)) |
| 165 return @""; |
| 166 return base::SysWideToNSString(model_->GetResourceProcessId(row)); |
| 167 |
| 168 case IDS_TASK_MANAGER_GOATS_TELEPORTED_COLUMN: // Goats Teleported! |
| 169 return base::SysWideToNSString(model_->GetResourceGoatsTeleported(row)); |
| 170 |
| 171 default: |
| 172 return base::SysWideToNSString( |
| 173 model_->GetResourceStatsValue(row, columnId)); |
| 174 } |
| 175 } |
| 176 |
| 177 - (id)tableView:(NSTableView*)tableView |
| 178 objectValueForTableColumn:(NSTableColumn*)tableColumn |
| 179 row:(NSInteger)rowIndex { |
| 180 return [self modelTextForRow:rowIndex |
| 181 column:[[tableColumn identifier] intValue]]; |
| 182 } |
| 183 |
| 27 @end | 184 @end |
| 28 | 185 |
| 29 //////////////////////////////////////////////////////////////////////////////// | 186 //////////////////////////////////////////////////////////////////////////////// |
| 30 // TaskManagerMac implementation: | 187 // TaskManagerMac implementation: |
| 31 | 188 |
| 32 TaskManagerMac::TaskManagerMac() | 189 TaskManagerMac::TaskManagerMac() |
| 33 : task_manager_(TaskManager::GetInstance()), | 190 : task_manager_(TaskManager::GetInstance()), |
| 34 model_(TaskManager::GetInstance()->model()) { | 191 model_(TaskManager::GetInstance()->model()) { |
| 35 window_controller_.reset([[TaskManagerWindowController alloc] init]); | 192 window_controller_.reset( |
| 193 [[TaskManagerWindowController alloc] initWithModel:model_]); |
| 194 model_->AddObserver(this); |
| 36 } | 195 } |
| 37 | 196 |
| 38 // static | 197 // static |
| 39 TaskManagerMac* TaskManagerMac::instance_ = NULL; | 198 TaskManagerMac* TaskManagerMac::instance_ = NULL; |
| 40 | 199 |
| 41 TaskManagerMac::~TaskManagerMac() { | 200 TaskManagerMac::~TaskManagerMac() { |
| 42 task_manager_->OnWindowClosed(); | 201 task_manager_->OnWindowClosed(); |
| 43 model_->RemoveObserver(this); | 202 model_->RemoveObserver(this); |
| 44 } | 203 } |
| 45 | 204 |
| 46 //////////////////////////////////////////////////////////////////////////////// | 205 //////////////////////////////////////////////////////////////////////////////// |
| 47 // TaskManagerMac, TaskManagerModelObserver implementation: | 206 // TaskManagerMac, TaskManagerModelObserver implementation: |
| 48 | 207 |
| 49 void TaskManagerMac::OnModelChanged() { | 208 void TaskManagerMac::OnModelChanged() { |
| 209 [window_controller_.get() reloadData]; |
| 50 } | 210 } |
| 51 | 211 |
| 52 void TaskManagerMac::OnItemsChanged(int start, int length) { | 212 void TaskManagerMac::OnItemsChanged(int start, int length) { |
| 213 [window_controller_.get() reloadData]; |
| 53 } | 214 } |
| 54 | 215 |
| 55 void TaskManagerMac::OnItemsAdded(int start, int length) { | 216 void TaskManagerMac::OnItemsAdded(int start, int length) { |
| 217 [window_controller_.get() reloadData]; |
| 56 } | 218 } |
| 57 | 219 |
| 58 void TaskManagerMac::OnItemsRemoved(int start, int length) { | 220 void TaskManagerMac::OnItemsRemoved(int start, int length) { |
| 221 [window_controller_.get() reloadData]; |
| 59 } | 222 } |
| 60 | 223 |
| 61 //////////////////////////////////////////////////////////////////////////////// | 224 //////////////////////////////////////////////////////////////////////////////// |
| 62 // TaskManagerMac, public: | 225 // TaskManagerMac, public: |
| 63 | 226 |
| 64 // static | 227 // static |
| 65 void TaskManagerMac::Show() { | 228 void TaskManagerMac::Show() { |
| 66 if (instance_) { | 229 if (instance_) { |
| 67 // If there's a Task manager window open already, just activate it. | 230 // If there's a Task manager window open already, just activate it. |
| 68 [[instance_->window_controller_ window] | 231 [[instance_->window_controller_ window] |
| 69 makeKeyAndOrderFront:instance_->window_controller_]; | 232 makeKeyAndOrderFront:instance_->window_controller_]; |
| 70 } else { | 233 } else { |
| 71 instance_ = new TaskManagerMac; | 234 instance_ = new TaskManagerMac; |
| 72 instance_->model_->StartUpdating(); | 235 instance_->model_->StartUpdating(); |
| 73 } | 236 } |
| 74 } | 237 } |
| OLD | NEW |