| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "app/l10n_util_mac.h" |
| 11 #include "base/mac_util.h" | 11 #include "base/mac_util.h" |
| 12 #include "base/sys_string_conversions.h" | 12 #include "base/sys_string_conversions.h" |
| 13 #include "chrome/browser/browser_process.h" | 13 #include "chrome/browser/browser_process.h" |
| 14 #import "chrome/browser/cocoa/window_size_autosaver.h" | 14 #import "chrome/browser/cocoa/window_size_autosaver.h" |
| 15 #include "chrome/common/pref_names.h" | 15 #include "chrome/common/pref_names.h" |
| 16 #include "grit/generated_resources.h" | 16 #include "grit/generated_resources.h" |
| 17 | 17 |
| 18 // TODO(thakis): Column sort comparator | 18 namespace { |
| 19 // TODO(thakis): Clicking column header doesn't sort | |
| 20 // TODO(thakis): Default sort column | |
| 21 | 19 |
| 22 // Width of "a" and most other letters/digits in "small" table views. | 20 // Width of "a" and most other letters/digits in "small" table views. |
| 23 static const int kCharWidth = 6; | 21 const int kCharWidth = 6; |
| 24 | 22 |
| 25 // Some of the strings below have spaces at the end or are missing letters, to | 23 // Some of the strings below have spaces at the end or are missing letters, to |
| 26 // make the columns look nicer, and to take potentially longer localized strings | 24 // make the columns look nicer, and to take potentially longer localized strings |
| 27 // into account. | 25 // into account. |
| 28 static const struct ColumnWidth { | 26 const struct ColumnWidth { |
| 29 int columnId; | 27 int columnId; |
| 30 int minWidth; | 28 int minWidth; |
| 31 int maxWidth; // If this is -1, 1.5*minColumWidth is used as max width. | 29 int maxWidth; // If this is -1, 1.5*minColumWidth is used as max width. |
| 32 } columnWidths[] = { | 30 } columnWidths[] = { |
| 33 // Note that arraysize includes the trailing \0. That's intended. | 31 // Note that arraysize includes the trailing \0. That's intended. |
| 34 { IDS_TASK_MANAGER_PAGE_COLUMN, 120, 600 }, | 32 { IDS_TASK_MANAGER_PAGE_COLUMN, 120, 600 }, |
| 35 { IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN, | 33 { IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN, |
| 36 arraysize("800 MiB") * kCharWidth, -1 }, | 34 arraysize("800 MiB") * kCharWidth, -1 }, |
| 37 { IDS_TASK_MANAGER_SHARED_MEM_COLUMN, | 35 { IDS_TASK_MANAGER_SHARED_MEM_COLUMN, |
| 38 arraysize("800 MiB") * kCharWidth, -1 }, | 36 arraysize("800 MiB") * kCharWidth, -1 }, |
| 39 { IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN, | 37 { IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN, |
| 40 arraysize("800 MiB") * kCharWidth, -1 }, | 38 arraysize("800 MiB") * kCharWidth, -1 }, |
| 41 { IDS_TASK_MANAGER_CPU_COLUMN, | 39 { IDS_TASK_MANAGER_CPU_COLUMN, |
| 42 arraysize("99.9") * kCharWidth, -1 }, | 40 arraysize("99.9") * kCharWidth, -1 }, |
| 43 { IDS_TASK_MANAGER_NET_COLUMN, | 41 { IDS_TASK_MANAGER_NET_COLUMN, |
| 44 arraysize("150 kiB/s") * kCharWidth, -1 }, | 42 arraysize("150 kiB/s") * kCharWidth, -1 }, |
| 45 { IDS_TASK_MANAGER_PROCESS_ID_COLUMN, | 43 { IDS_TASK_MANAGER_PROCESS_ID_COLUMN, |
| 46 arraysize("73099 ") * kCharWidth, -1 }, | 44 arraysize("73099 ") * kCharWidth, -1 }, |
| 47 { IDS_TASK_MANAGER_WEBCORE_IMAGE_CACHE_COLUMN, | 45 { IDS_TASK_MANAGER_WEBCORE_IMAGE_CACHE_COLUMN, |
| 48 arraysize("2000.0K (2000.0 live)") * kCharWidth, -1 }, | 46 arraysize("2000.0K (2000.0 live)") * kCharWidth, -1 }, |
| 49 { IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN, | 47 { IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN, |
| 50 arraysize("2000.0K (2000.0 live)") * kCharWidth, -1 }, | 48 arraysize("2000.0K (2000.0 live)") * kCharWidth, -1 }, |
| 51 { IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN, | 49 { IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN, |
| 52 arraysize("2000.0K (2000.0 live)") * kCharWidth, -1 }, | 50 arraysize("2000.0K (2000.0 live)") * kCharWidth, -1 }, |
| 53 { IDS_TASK_MANAGER_GOATS_TELEPORTED_COLUMN, | 51 { IDS_TASK_MANAGER_GOATS_TELEPORTED_COLUMN, |
| 54 arraysize("15 ") * kCharWidth, -1 }, | 52 arraysize("15 ") * kCharWidth, -1 }, |
| 55 }; | 53 }; |
| 56 | 54 |
| 55 class SortHelper { |
| 56 public: |
| 57 SortHelper(TaskManagerModel* model, NSSortDescriptor* column) |
| 58 : sort_column_([[column key] intValue]), |
| 59 ascending_([column ascending]), |
| 60 model_(model) {} |
| 61 |
| 62 bool operator()(int a, int b) { |
| 63 int cmp_result = model_->CompareValues(a, b, sort_column_ ); |
| 64 if (!ascending_) |
| 65 cmp_result = -cmp_result; |
| 66 // TODO(thakis): Do grouping like on GTK. |
| 67 return cmp_result < 0; |
| 68 } |
| 69 private: |
| 70 int sort_column_; |
| 71 bool ascending_; |
| 72 TaskManagerModel* model_; // weak; |
| 73 }; |
| 74 |
| 75 } // namespace |
| 76 |
| 57 @interface TaskManagerWindowController (Private) | 77 @interface TaskManagerWindowController (Private) |
| 58 - (NSTableColumn*)addColumnWithId:(int)columnId visible:(BOOL)isVisible; | 78 - (NSTableColumn*)addColumnWithId:(int)columnId visible:(BOOL)isVisible; |
| 59 - (void)setUpTableColumns; | 79 - (void)setUpTableColumns; |
| 60 - (void)setUpTableHeaderContextMenu; | 80 - (void)setUpTableHeaderContextMenu; |
| 61 - (void)toggleColumn:(id)sender; | 81 - (void)toggleColumn:(id)sender; |
| 62 - (void)adjustSelectionAndEndProcessButton; | 82 - (void)adjustSelectionAndEndProcessButton; |
| 63 @end | 83 @end |
| 64 | 84 |
| 65 //////////////////////////////////////////////////////////////////////////////// | 85 //////////////////////////////////////////////////////////////////////////////// |
| 66 // TaskManagerWindowController implementation: | 86 // TaskManagerWindowController implementation: |
| 67 | 87 |
| 68 @implementation TaskManagerWindowController | 88 @implementation TaskManagerWindowController |
| 69 | 89 |
| 70 - (id)initWithTaskManagerObserver:(TaskManagerMac*)taskManagerObserver { | 90 - (id)initWithTaskManagerObserver:(TaskManagerMac*)taskManagerObserver { |
| 71 NSString* nibpath = [mac_util::MainAppBundle() | 91 NSString* nibpath = [mac_util::MainAppBundle() |
| 72 pathForResource:@"TaskManager" | 92 pathForResource:@"TaskManager" |
| 73 ofType:@"nib"]; | 93 ofType:@"nib"]; |
| 74 if ((self = [super initWithWindowNibPath:nibpath owner:self])) { | 94 if ((self = [super initWithWindowNibPath:nibpath owner:self])) { |
| 75 taskManagerObserver_ = taskManagerObserver; | 95 taskManagerObserver_ = taskManagerObserver; |
| 76 taskManager_ = taskManagerObserver_->task_manager(); | 96 taskManager_ = taskManagerObserver_->task_manager(); |
| 77 model_ = taskManager_->model(); | 97 model_ = taskManager_->model(); |
| 78 | 98 |
| 79 if (g_browser_process && g_browser_process->local_state()) { | 99 if (g_browser_process && g_browser_process->local_state()) { |
| 80 size_saver_.reset([[WindowSizeAutosaver alloc] | 100 size_saver_.reset([[WindowSizeAutosaver alloc] |
| 81 initWithWindow:[self window] | 101 initWithWindow:[self window] |
| 82 prefService:g_browser_process->local_state() | 102 prefService:g_browser_process->local_state() |
| 83 path:prefs::kTaskManagerWindowPlacement | 103 path:prefs::kTaskManagerWindowPlacement |
| 84 state:kSaveWindowRect]); | 104 state:kSaveWindowRect]); |
| 85 } | 105 } |
| 86 [[self window] makeKeyAndOrderFront:self]; | 106 [self showWindow:self]; |
| 87 } | 107 } |
| 88 return self; | 108 return self; |
| 89 } | 109 } |
| 90 | 110 |
| 111 - (void)sortShuffleArray { |
| 112 indexShuffle_.resize(model_->ResourceCount()); |
| 113 for (size_t i = 0; i < indexShuffle_.size(); ++i) |
| 114 indexShuffle_[i] = i; |
| 115 |
| 116 std::sort(indexShuffle_.begin(), indexShuffle_.end(), |
| 117 SortHelper(model_, currentSortDescriptor_.get())); |
| 118 } |
| 119 |
| 91 - (void)reloadData { | 120 - (void)reloadData { |
| 121 [self sortShuffleArray]; |
| 92 [tableView_ reloadData]; | 122 [tableView_ reloadData]; |
| 93 [self adjustSelectionAndEndProcessButton]; | 123 [self adjustSelectionAndEndProcessButton]; |
| 94 } | 124 } |
| 95 | 125 |
| 96 - (IBAction)statsLinkClicked:(id)sender { | 126 - (IBAction)statsLinkClicked:(id)sender { |
| 97 TaskManager::GetInstance()->OpenAboutMemory(); | 127 TaskManager::GetInstance()->OpenAboutMemory(); |
| 98 } | 128 } |
| 99 | 129 |
| 100 - (IBAction)killSelectedProcesses:(id)sender { | 130 - (IBAction)killSelectedProcesses:(id)sender { |
| 101 NSIndexSet* selection = [tableView_ selectedRowIndexes]; | 131 NSIndexSet* selection = [tableView_ selectedRowIndexes]; |
| 102 for (NSUInteger i = [selection lastIndex]; | 132 for (NSUInteger i = [selection lastIndex]; |
| 103 i != NSNotFound; | 133 i != NSNotFound; |
| 104 i = [selection indexLessThanIndex:i]) { | 134 i = [selection indexLessThanIndex:i]) { |
| 105 taskManager_->KillProcess(i); | 135 taskManager_->KillProcess(i); |
| 106 } | 136 } |
| 107 } | 137 } |
| 108 | 138 |
| 109 - (void)selectDoubleClickedTab:(id)sender { | 139 - (void)selectDoubleClickedTab:(id)sender { |
| 110 NSInteger row = [tableView_ clickedRow]; | 140 NSInteger row = [tableView_ clickedRow]; |
| 111 if (row < 0) | 141 if (row < 0) |
| 112 return; // Happens e.g. if the table header is double-clicked. | 142 return; // Happens e.g. if the table header is double-clicked. |
| 113 taskManager_->ActivateProcess(row); | 143 taskManager_->ActivateProcess(row); |
| 114 } | 144 } |
| 115 | 145 |
| 146 - (NSTableView*)tableView { |
| 147 return tableView_; |
| 148 } |
| 149 |
| 116 - (void)awakeFromNib { | 150 - (void)awakeFromNib { |
| 117 [self setUpTableColumns]; | 151 [self setUpTableColumns]; |
| 118 [self setUpTableHeaderContextMenu]; | 152 [self setUpTableHeaderContextMenu]; |
| 119 [self adjustSelectionAndEndProcessButton]; | 153 [self adjustSelectionAndEndProcessButton]; |
| 120 | 154 |
| 121 [tableView_ setDoubleAction:@selector(selectDoubleClickedTab:)]; | 155 [tableView_ setDoubleAction:@selector(selectDoubleClickedTab:)]; |
| 122 } | 156 } |
| 123 | 157 |
| 124 // Adds a column which has the given string id as title. |isVisible| specifies | 158 // Adds a column which has the given string id as title. |isVisible| specifies |
| 125 // if the column is initially visible. | 159 // if the column is initially visible. |
| 126 - (NSTableColumn*)addColumnWithId:(int)columnId visible:(BOOL)isVisible { | 160 - (NSTableColumn*)addColumnWithId:(int)columnId visible:(BOOL)isVisible { |
| 127 scoped_nsobject<NSTableColumn> column([[NSTableColumn alloc] | 161 scoped_nsobject<NSTableColumn> column([[NSTableColumn alloc] |
| 128 initWithIdentifier:[NSNumber numberWithInt:columnId]]); | 162 initWithIdentifier:[NSNumber numberWithInt:columnId]]); |
| 129 | 163 |
| 130 NSTextAlignment textAlignment = columnId == IDS_TASK_MANAGER_PAGE_COLUMN ? | 164 NSTextAlignment textAlignment = columnId == IDS_TASK_MANAGER_PAGE_COLUMN ? |
| 131 NSLeftTextAlignment : NSRightTextAlignment; | 165 NSLeftTextAlignment : NSRightTextAlignment; |
| 132 | 166 |
| 133 [[column.get() headerCell] | 167 [[column.get() headerCell] |
| 134 setStringValue:l10n_util::GetNSStringWithFixup(columnId)]; | 168 setStringValue:l10n_util::GetNSStringWithFixup(columnId)]; |
| 135 [[column.get() headerCell] setAlignment:textAlignment]; | 169 [[column.get() headerCell] setAlignment:textAlignment]; |
| 136 [[column.get() dataCell] setAlignment:textAlignment]; | 170 [[column.get() dataCell] setAlignment:textAlignment]; |
| 137 | 171 |
| 138 NSFont* font = [NSFont systemFontOfSize:[NSFont smallSystemFontSize]]; | 172 NSFont* font = [NSFont systemFontOfSize:[NSFont smallSystemFontSize]]; |
| 139 [[column.get() dataCell] setFont:font]; | 173 [[column.get() dataCell] setFont:font]; |
| 140 | 174 |
| 141 [column.get() setHidden:!isVisible]; | 175 [column.get() setHidden:!isVisible]; |
| 142 [column.get() setEditable:NO]; | 176 [column.get() setEditable:NO]; |
| 143 | 177 |
| 178 // The page column should by default be sorted ascending. |
| 179 BOOL ascending = columnId == IDS_TASK_MANAGER_PAGE_COLUMN; |
| 180 |
| 181 scoped_nsobject<NSSortDescriptor> sortDescriptor([[NSSortDescriptor alloc] |
| 182 initWithKey:[NSString stringWithFormat:@"%d", columnId] |
| 183 ascending:ascending]); |
| 184 [column.get() setSortDescriptorPrototype:sortDescriptor.get()]; |
| 185 |
| 144 // Default values, only used in release builds if nobody notices the DCHECK | 186 // Default values, only used in release builds if nobody notices the DCHECK |
| 145 // during development when adding new columns. | 187 // during development when adding new columns. |
| 146 int minWidth = 200, maxWidth = 400; | 188 int minWidth = 200, maxWidth = 400; |
| 147 | 189 |
| 148 size_t i; | 190 size_t i; |
| 149 for (i = 0; i < arraysize(columnWidths); ++i) { | 191 for (i = 0; i < arraysize(columnWidths); ++i) { |
| 150 if (columnWidths[i].columnId == columnId) { | 192 if (columnWidths[i].columnId == columnId) { |
| 151 minWidth = columnWidths[i].minWidth; | 193 minWidth = columnWidths[i].minWidth; |
| 152 maxWidth = columnWidths[i].maxWidth; | 194 maxWidth = columnWidths[i].maxWidth; |
| 153 if (maxWidth < 0) | 195 if (maxWidth < 0) |
| (...skipping 20 matching lines...) Expand all Loading... |
| 174 // |nameColumn| displays an icon for every row -- this is done by an | 216 // |nameColumn| displays an icon for every row -- this is done by an |
| 175 // NSButtonCell. | 217 // NSButtonCell. |
| 176 scoped_nsobject<NSButtonCell> nameCell( | 218 scoped_nsobject<NSButtonCell> nameCell( |
| 177 [[NSButtonCell alloc] initTextCell:@""]); | 219 [[NSButtonCell alloc] initTextCell:@""]); |
| 178 [nameCell.get() setImagePosition:NSImageLeft]; | 220 [nameCell.get() setImagePosition:NSImageLeft]; |
| 179 [nameCell.get() setButtonType:NSSwitchButton]; | 221 [nameCell.get() setButtonType:NSSwitchButton]; |
| 180 [nameCell.get() setAlignment:[[nameColumn dataCell] alignment]]; | 222 [nameCell.get() setAlignment:[[nameColumn dataCell] alignment]]; |
| 181 [nameCell.get() setFont:[[nameColumn dataCell] font]]; | 223 [nameCell.get() setFont:[[nameColumn dataCell] font]]; |
| 182 [nameColumn setDataCell:nameCell.get()]; | 224 [nameColumn setDataCell:nameCell.get()]; |
| 183 | 225 |
| 226 // Initially, sort on the tab name. |
| 227 [tableView_ setSortDescriptors: |
| 228 [NSArray arrayWithObject:[nameColumn sortDescriptorPrototype]]]; |
| 229 |
| 184 [self addColumnWithId:IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN visible:YES]; | 230 [self addColumnWithId:IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN visible:YES]; |
| 185 [self addColumnWithId:IDS_TASK_MANAGER_SHARED_MEM_COLUMN visible:NO]; | 231 [self addColumnWithId:IDS_TASK_MANAGER_SHARED_MEM_COLUMN visible:NO]; |
| 186 [self addColumnWithId:IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN visible:NO]; | 232 [self addColumnWithId:IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN visible:NO]; |
| 187 [self addColumnWithId:IDS_TASK_MANAGER_CPU_COLUMN visible:YES]; | 233 [self addColumnWithId:IDS_TASK_MANAGER_CPU_COLUMN visible:YES]; |
| 188 [self addColumnWithId:IDS_TASK_MANAGER_NET_COLUMN visible:YES]; | 234 [self addColumnWithId:IDS_TASK_MANAGER_NET_COLUMN visible:YES]; |
| 189 [self addColumnWithId:IDS_TASK_MANAGER_PROCESS_ID_COLUMN visible:NO]; | 235 [self addColumnWithId:IDS_TASK_MANAGER_PROCESS_ID_COLUMN visible:NO]; |
| 190 [self addColumnWithId:IDS_TASK_MANAGER_WEBCORE_IMAGE_CACHE_COLUMN | 236 [self addColumnWithId:IDS_TASK_MANAGER_WEBCORE_IMAGE_CACHE_COLUMN |
| 191 visible:NO]; | 237 visible:NO]; |
| 192 [self addColumnWithId:IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN | 238 [self addColumnWithId:IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN |
| 193 visible:NO]; | 239 visible:NO]; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 | 299 |
| 254 bool enabled = [selection count] > 0 && !selectionContainsBrowserProcess; | 300 bool enabled = [selection count] > 0 && !selectionContainsBrowserProcess; |
| 255 [endProcessButton_ setEnabled:enabled]; | 301 [endProcessButton_ setEnabled:enabled]; |
| 256 } | 302 } |
| 257 | 303 |
| 258 // Table view delegate method. | 304 // Table view delegate method. |
| 259 - (void)tableViewSelectionIsChanging:(NSNotification*)aNotification { | 305 - (void)tableViewSelectionIsChanging:(NSNotification*)aNotification { |
| 260 [self adjustSelectionAndEndProcessButton]; | 306 [self adjustSelectionAndEndProcessButton]; |
| 261 } | 307 } |
| 262 | 308 |
| 309 - (void)windowWillClose:(NSNotification*)notification { |
| 310 if (taskManagerObserver_) { |
| 311 taskManagerObserver_->WindowWasClosed(); |
| 312 taskManagerObserver_ = nil; |
| 313 } |
| 314 [self autorelease]; |
| 315 } |
| 316 |
| 263 @end | 317 @end |
| 264 | 318 |
| 265 @implementation TaskManagerWindowController (NSTableDataSource) | 319 @implementation TaskManagerWindowController (NSTableDataSource) |
| 266 | 320 |
| 267 - (NSInteger)numberOfRowsInTableView:(NSTableView*)tableView { | 321 - (NSInteger)numberOfRowsInTableView:(NSTableView*)tableView { |
| 268 DCHECK(tableView == tableView_ || tableView_ == nil); | 322 DCHECK(tableView == tableView_ || tableView_ == nil); |
| 269 return model_->ResourceCount(); | 323 return model_->ResourceCount(); |
| 270 } | 324 } |
| 271 | 325 |
| 272 - (NSString*)modelTextForRow:(int)row column:(int)columnId { | 326 - (NSString*)modelTextForRow:(int)row column:(int)columnId { |
| 327 DCHECK_LT(static_cast<size_t>(row), indexShuffle_.size()); |
| 328 row = indexShuffle_[row]; |
| 273 switch (columnId) { | 329 switch (columnId) { |
| 274 case IDS_TASK_MANAGER_PAGE_COLUMN: // Process | 330 case IDS_TASK_MANAGER_PAGE_COLUMN: // Process |
| 275 return base::SysWideToNSString(model_->GetResourceTitle(row)); | 331 return base::SysWideToNSString(model_->GetResourceTitle(row)); |
| 276 | 332 |
| 277 case IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN: // Memory | 333 case IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN: // Memory |
| 278 if (!model_->IsResourceFirstInGroup(row)) | 334 if (!model_->IsResourceFirstInGroup(row)) |
| 279 return @""; | 335 return @""; |
| 280 return base::SysWideToNSString(model_->GetResourcePrivateMemory(row)); | 336 return base::SysWideToNSString(model_->GetResourcePrivateMemory(row)); |
| 281 | 337 |
| 282 case IDS_TASK_MANAGER_SHARED_MEM_COLUMN: // Memory | 338 case IDS_TASK_MANAGER_SHARED_MEM_COLUMN: // Memory |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 column:[[tableColumn identifier] intValue]]; | 411 column:[[tableColumn identifier] intValue]]; |
| 356 [buttonCell setTitle:title]; | 412 [buttonCell setTitle:title]; |
| 357 [buttonCell setImage:taskManagerObserver_->GetImageForRow(rowIndex)]; | 413 [buttonCell setImage:taskManagerObserver_->GetImageForRow(rowIndex)]; |
| 358 [buttonCell setRefusesFirstResponder:YES]; // Don't push in like a button. | 414 [buttonCell setRefusesFirstResponder:YES]; // Don't push in like a button. |
| 359 [buttonCell setHighlightsBy:NSNoCellMask]; | 415 [buttonCell setHighlightsBy:NSNoCellMask]; |
| 360 } | 416 } |
| 361 | 417 |
| 362 return cell; | 418 return cell; |
| 363 } | 419 } |
| 364 | 420 |
| 421 - (void) tableView:(NSTableView*)tableView |
| 422 sortDescriptorsDidChange:(NSArray*)oldDescriptors { |
| 423 NSArray* newDescriptors = [tableView sortDescriptors]; |
| 424 if ([newDescriptors count] < 1) |
| 425 return; |
| 426 |
| 427 currentSortDescriptor_.reset([[newDescriptors objectAtIndex:0] retain]); |
| 428 [self reloadData]; // Sorts. |
| 429 } |
| 430 |
| 365 @end | 431 @end |
| 366 | 432 |
| 367 //////////////////////////////////////////////////////////////////////////////// | 433 //////////////////////////////////////////////////////////////////////////////// |
| 368 // TaskManagerMac implementation: | 434 // TaskManagerMac implementation: |
| 369 | 435 |
| 370 TaskManagerMac::TaskManagerMac() | 436 TaskManagerMac::TaskManagerMac(TaskManager* task_manager) |
| 371 : task_manager_(TaskManager::GetInstance()), | 437 : task_manager_(task_manager), |
| 372 model_(TaskManager::GetInstance()->model()), | 438 model_(task_manager->model()), |
| 373 icon_cache_(this) { | 439 icon_cache_(this) { |
| 374 window_controller_ = | 440 window_controller_ = |
| 375 [[TaskManagerWindowController alloc] initWithTaskManagerObserver:this]; | 441 [[TaskManagerWindowController alloc] initWithTaskManagerObserver:this]; |
| 376 model_->AddObserver(this); | 442 model_->AddObserver(this); |
| 377 } | 443 } |
| 378 | 444 |
| 379 // static | 445 // static |
| 380 TaskManagerMac* TaskManagerMac::instance_ = NULL; | 446 TaskManagerMac* TaskManagerMac::instance_ = NULL; |
| 381 | 447 |
| 382 TaskManagerMac::~TaskManagerMac() { | 448 TaskManagerMac::~TaskManagerMac() { |
| 383 task_manager_->OnWindowClosed(); | 449 if (this == instance_) { |
| 450 // Do not do this when running in unit tests: |StartUpdating()| never got |
| 451 // called in that case. |
| 452 task_manager_->OnWindowClosed(); |
| 453 } |
| 384 model_->RemoveObserver(this); | 454 model_->RemoveObserver(this); |
| 385 } | 455 } |
| 386 | 456 |
| 387 //////////////////////////////////////////////////////////////////////////////// | 457 //////////////////////////////////////////////////////////////////////////////// |
| 388 // TaskManagerMac, TaskManagerModelObserver implementation: | 458 // TaskManagerMac, TaskManagerModelObserver implementation: |
| 389 | 459 |
| 390 void TaskManagerMac::OnModelChanged() { | 460 void TaskManagerMac::OnModelChanged() { |
| 391 icon_cache_.OnModelChanged(); | 461 icon_cache_.OnModelChanged(); |
| 392 [window_controller_ reloadData]; | 462 [window_controller_ reloadData]; |
| 393 } | 463 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 419 instance_ = NULL; | 489 instance_ = NULL; |
| 420 } | 490 } |
| 421 | 491 |
| 422 // static | 492 // static |
| 423 void TaskManagerMac::Show() { | 493 void TaskManagerMac::Show() { |
| 424 if (instance_) { | 494 if (instance_) { |
| 425 // If there's a Task manager window open already, just activate it. | 495 // If there's a Task manager window open already, just activate it. |
| 426 [[instance_->window_controller_ window] | 496 [[instance_->window_controller_ window] |
| 427 makeKeyAndOrderFront:instance_->window_controller_]; | 497 makeKeyAndOrderFront:instance_->window_controller_]; |
| 428 } else { | 498 } else { |
| 429 instance_ = new TaskManagerMac; | 499 instance_ = new TaskManagerMac(TaskManager::GetInstance()); |
| 430 instance_->model_->StartUpdating(); | 500 instance_->model_->StartUpdating(); |
| 431 } | 501 } |
| 432 } | 502 } |
| OLD | NEW |