| 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" |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 }; | 82 }; |
| 83 | 83 |
| 84 } // namespace | 84 } // namespace |
| 85 | 85 |
| 86 @interface TaskManagerWindowController (Private) | 86 @interface TaskManagerWindowController (Private) |
| 87 - (NSTableColumn*)addColumnWithId:(int)columnId visible:(BOOL)isVisible; | 87 - (NSTableColumn*)addColumnWithId:(int)columnId visible:(BOOL)isVisible; |
| 88 - (void)setUpTableColumns; | 88 - (void)setUpTableColumns; |
| 89 - (void)setUpTableHeaderContextMenu; | 89 - (void)setUpTableHeaderContextMenu; |
| 90 - (void)toggleColumn:(id)sender; | 90 - (void)toggleColumn:(id)sender; |
| 91 - (void)adjustSelectionAndEndProcessButton; | 91 - (void)adjustSelectionAndEndProcessButton; |
| 92 - (void)deselectRows; |
| 92 @end | 93 @end |
| 93 | 94 |
| 94 //////////////////////////////////////////////////////////////////////////////// | 95 //////////////////////////////////////////////////////////////////////////////// |
| 95 // TaskManagerWindowController implementation: | 96 // TaskManagerWindowController implementation: |
| 96 | 97 |
| 97 @implementation TaskManagerWindowController | 98 @implementation TaskManagerWindowController |
| 98 | 99 |
| 99 - (id)initWithTaskManagerObserver:(TaskManagerMac*)taskManagerObserver { | 100 - (id)initWithTaskManagerObserver:(TaskManagerMac*)taskManagerObserver { |
| 100 NSString* nibpath = [mac_util::MainAppBundle() | 101 NSString* nibpath = [mac_util::MainAppBundle() |
| 101 pathForResource:@"TaskManager" | 102 pathForResource:@"TaskManager" |
| 102 ofType:@"nib"]; | 103 ofType:@"nib"]; |
| 103 if ((self = [super initWithWindowNibPath:nibpath owner:self])) { | 104 if ((self = [super initWithWindowNibPath:nibpath owner:self])) { |
| 104 taskManagerObserver_ = taskManagerObserver; | 105 taskManagerObserver_ = taskManagerObserver; |
| 105 taskManager_ = taskManagerObserver_->task_manager(); | 106 taskManager_ = taskManagerObserver_->task_manager(); |
| 106 model_ = taskManager_->model(); | 107 model_ = taskManager_->model(); |
| 107 | 108 |
| 108 if (g_browser_process && g_browser_process->local_state()) { | 109 if (g_browser_process && g_browser_process->local_state()) { |
| 109 size_saver_.reset([[WindowSizeAutosaver alloc] | 110 size_saver_.reset([[WindowSizeAutosaver alloc] |
| 110 initWithWindow:[self window] | 111 initWithWindow:[self window] |
| 111 prefService:g_browser_process->local_state() | 112 prefService:g_browser_process->local_state() |
| 112 path:prefs::kTaskManagerWindowPlacement | 113 path:prefs::kTaskManagerWindowPlacement |
| 113 state:kSaveWindowRect]); | 114 state:kSaveWindowRect]); |
| 114 } | 115 } |
| 115 [self showWindow:self]; | 116 [self showWindow:self]; |
| 116 } | 117 } |
| 117 return self; | 118 return self; |
| 118 } | 119 } |
| 119 | 120 |
| 120 - (void)sortShuffleArray { | 121 - (void)sortShuffleArray { |
| 121 indexShuffle_.resize(model_->ResourceCount()); | 122 viewToModelMap_.resize(model_->ResourceCount()); |
| 122 for (size_t i = 0; i < indexShuffle_.size(); ++i) | 123 for (size_t i = 0; i < viewToModelMap_.size(); ++i) |
| 123 indexShuffle_[i] = i; | 124 viewToModelMap_[i] = i; |
| 124 | 125 |
| 125 std::sort(indexShuffle_.begin(), indexShuffle_.end(), | 126 std::sort(viewToModelMap_.begin(), viewToModelMap_.end(), |
| 126 SortHelper(model_, currentSortDescriptor_.get())); | 127 SortHelper(model_, currentSortDescriptor_.get())); |
| 128 |
| 129 modelToViewMap_.resize(viewToModelMap_.size()); |
| 130 for (size_t i = 0; i < viewToModelMap_.size(); ++i) |
| 131 modelToViewMap_[viewToModelMap_[i]] = i; |
| 127 } | 132 } |
| 128 | 133 |
| 129 - (void)reloadData { | 134 - (void)reloadData { |
| 135 // Store old view indices, and the model indices they map to. |
| 136 NSIndexSet* viewSelection = [tableView_ selectedRowIndexes]; |
| 137 std::vector<int> modelSelection; |
| 138 for (NSUInteger i = [viewSelection lastIndex]; |
| 139 i != NSNotFound; |
| 140 i = [viewSelection indexLessThanIndex:i]) { |
| 141 modelSelection.push_back(viewToModelMap_[i]); |
| 142 } |
| 143 |
| 144 // Sort. |
| 130 [self sortShuffleArray]; | 145 [self sortShuffleArray]; |
| 146 |
| 147 // Use the model indices to get the new view indices of the selection, and |
| 148 // set selection to that. This assumes that no rows were added or removed |
| 149 // (in that case, the selection is cleared before -reloadData is called). |
| 150 if (modelSelection.size() > 0) |
| 151 DCHECK_EQ([tableView_ numberOfRows], model_->ResourceCount()); |
| 152 NSMutableIndexSet* indexSet = [NSMutableIndexSet indexSet]; |
| 153 for (size_t i = 0; i < modelSelection.size(); ++i) |
| 154 [indexSet addIndex:modelToViewMap_[modelSelection[i]]]; |
| 155 [tableView_ selectRowIndexes:indexSet byExtendingSelection:NO]; |
| 156 |
| 131 [tableView_ reloadData]; | 157 [tableView_ reloadData]; |
| 132 [self adjustSelectionAndEndProcessButton]; | 158 [self adjustSelectionAndEndProcessButton]; |
| 133 } | 159 } |
| 134 | 160 |
| 135 - (IBAction)statsLinkClicked:(id)sender { | 161 - (IBAction)statsLinkClicked:(id)sender { |
| 136 TaskManager::GetInstance()->OpenAboutMemory(); | 162 TaskManager::GetInstance()->OpenAboutMemory(); |
| 137 } | 163 } |
| 138 | 164 |
| 139 - (IBAction)killSelectedProcesses:(id)sender { | 165 - (IBAction)killSelectedProcesses:(id)sender { |
| 140 NSIndexSet* selection = [tableView_ selectedRowIndexes]; | 166 NSIndexSet* selection = [tableView_ selectedRowIndexes]; |
| 141 for (NSUInteger i = [selection lastIndex]; | 167 for (NSUInteger i = [selection lastIndex]; |
| 142 i != NSNotFound; | 168 i != NSNotFound; |
| 143 i = [selection indexLessThanIndex:i]) { | 169 i = [selection indexLessThanIndex:i]) { |
| 144 taskManager_->KillProcess(i); | 170 taskManager_->KillProcess(viewToModelMap_[i]); |
| 145 } | 171 } |
| 146 } | 172 } |
| 147 | 173 |
| 148 - (void)selectDoubleClickedTab:(id)sender { | 174 - (void)selectDoubleClickedTab:(id)sender { |
| 149 NSInteger row = [tableView_ clickedRow]; | 175 NSInteger row = [tableView_ clickedRow]; |
| 150 if (row < 0) | 176 if (row < 0) |
| 151 return; // Happens e.g. if the table header is double-clicked. | 177 return; // Happens e.g. if the table header is double-clicked. |
| 152 taskManager_->ActivateProcess(row); | 178 taskManager_->ActivateProcess(row); |
| 153 } | 179 } |
| 154 | 180 |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 - (void)adjustSelectionAndEndProcessButton { | 317 - (void)adjustSelectionAndEndProcessButton { |
| 292 bool selectionContainsBrowserProcess = false; | 318 bool selectionContainsBrowserProcess = false; |
| 293 | 319 |
| 294 // If a row is selected, make sure that all rows belonging to the same process | 320 // If a row is selected, make sure that all rows belonging to the same process |
| 295 // are selected as well. Also, check if the selection contains the browser | 321 // are selected as well. Also, check if the selection contains the browser |
| 296 // process. | 322 // process. |
| 297 NSIndexSet* selection = [tableView_ selectedRowIndexes]; | 323 NSIndexSet* selection = [tableView_ selectedRowIndexes]; |
| 298 for (NSUInteger i = [selection lastIndex]; | 324 for (NSUInteger i = [selection lastIndex]; |
| 299 i != NSNotFound; | 325 i != NSNotFound; |
| 300 i = [selection indexLessThanIndex:i]) { | 326 i = [selection indexLessThanIndex:i]) { |
| 301 if (taskManager_->IsBrowserProcess(i)) | 327 int modelIndex = viewToModelMap_[i]; |
| 328 if (taskManager_->IsBrowserProcess(modelIndex)) |
| 302 selectionContainsBrowserProcess = true; | 329 selectionContainsBrowserProcess = true; |
| 303 | 330 |
| 304 std::pair<int, int> rangePair = model_->GetGroupRangeForResource(i); | 331 std::pair<int, int> rangePair = |
| 305 NSRange range = NSMakeRange(rangePair.first, rangePair.second); | 332 model_->GetGroupRangeForResource(modelIndex); |
| 306 NSIndexSet* rangeIndexSet = [NSIndexSet indexSetWithIndexesInRange:range]; | 333 NSMutableIndexSet* indexSet = [NSMutableIndexSet indexSet]; |
| 307 [tableView_ selectRowIndexes:rangeIndexSet byExtendingSelection:YES]; | 334 for (int j = 0; j < rangePair.second; ++j) |
| 335 [indexSet addIndex:modelToViewMap_[rangePair.first + j]]; |
| 336 [tableView_ selectRowIndexes:indexSet byExtendingSelection:YES]; |
| 308 } | 337 } |
| 309 | 338 |
| 310 bool enabled = [selection count] > 0 && !selectionContainsBrowserProcess; | 339 bool enabled = [selection count] > 0 && !selectionContainsBrowserProcess; |
| 311 [endProcessButton_ setEnabled:enabled]; | 340 [endProcessButton_ setEnabled:enabled]; |
| 312 } | 341 } |
| 313 | 342 |
| 343 - (void)deselectRows { |
| 344 [tableView_ deselectAll:self]; |
| 345 } |
| 346 |
| 314 // Table view delegate method. | 347 // Table view delegate method. |
| 315 - (void)tableViewSelectionIsChanging:(NSNotification*)aNotification { | 348 - (void)tableViewSelectionIsChanging:(NSNotification*)aNotification { |
| 316 [self adjustSelectionAndEndProcessButton]; | 349 [self adjustSelectionAndEndProcessButton]; |
| 317 } | 350 } |
| 318 | 351 |
| 319 - (void)windowWillClose:(NSNotification*)notification { | 352 - (void)windowWillClose:(NSNotification*)notification { |
| 320 if (taskManagerObserver_) { | 353 if (taskManagerObserver_) { |
| 321 taskManagerObserver_->WindowWasClosed(); | 354 taskManagerObserver_->WindowWasClosed(); |
| 322 taskManagerObserver_ = nil; | 355 taskManagerObserver_ = nil; |
| 323 } | 356 } |
| 324 [self autorelease]; | 357 [self autorelease]; |
| 325 } | 358 } |
| 326 | 359 |
| 327 @end | 360 @end |
| 328 | 361 |
| 329 @implementation TaskManagerWindowController (NSTableDataSource) | 362 @implementation TaskManagerWindowController (NSTableDataSource) |
| 330 | 363 |
| 331 - (NSInteger)numberOfRowsInTableView:(NSTableView*)tableView { | 364 - (NSInteger)numberOfRowsInTableView:(NSTableView*)tableView { |
| 332 DCHECK(tableView == tableView_ || tableView_ == nil); | 365 DCHECK(tableView == tableView_ || tableView_ == nil); |
| 333 return model_->ResourceCount(); | 366 return model_->ResourceCount(); |
| 334 } | 367 } |
| 335 | 368 |
| 336 - (NSString*)modelTextForRow:(int)row column:(int)columnId { | 369 - (NSString*)modelTextForRow:(int)row column:(int)columnId { |
| 337 DCHECK_LT(static_cast<size_t>(row), indexShuffle_.size()); | 370 DCHECK_LT(static_cast<size_t>(row), viewToModelMap_.size()); |
| 338 row = indexShuffle_[row]; | 371 row = viewToModelMap_[row]; |
| 339 switch (columnId) { | 372 switch (columnId) { |
| 340 case IDS_TASK_MANAGER_PAGE_COLUMN: // Process | 373 case IDS_TASK_MANAGER_PAGE_COLUMN: // Process |
| 341 return base::SysWideToNSString(model_->GetResourceTitle(row)); | 374 return base::SysWideToNSString(model_->GetResourceTitle(row)); |
| 342 | 375 |
| 343 case IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN: // Memory | 376 case IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN: // Memory |
| 344 if (!model_->IsResourceFirstInGroup(row)) | 377 if (!model_->IsResourceFirstInGroup(row)) |
| 345 return @""; | 378 return @""; |
| 346 return base::SysWideToNSString(model_->GetResourcePrivateMemory(row)); | 379 return base::SysWideToNSString(model_->GetResourcePrivateMemory(row)); |
| 347 | 380 |
| 348 case IDS_TASK_MANAGER_SHARED_MEM_COLUMN: // Memory | 381 case IDS_TASK_MANAGER_SHARED_MEM_COLUMN: // Memory |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 414 NSCell* cell = [tableColumn dataCellForRow:rowIndex]; | 447 NSCell* cell = [tableColumn dataCellForRow:rowIndex]; |
| 415 | 448 |
| 416 // Set the favicon and title for the task in the name column. | 449 // Set the favicon and title for the task in the name column. |
| 417 if ([[tableColumn identifier] intValue] == IDS_TASK_MANAGER_PAGE_COLUMN) { | 450 if ([[tableColumn identifier] intValue] == IDS_TASK_MANAGER_PAGE_COLUMN) { |
| 418 DCHECK([cell isKindOfClass:[NSButtonCell class]]); | 451 DCHECK([cell isKindOfClass:[NSButtonCell class]]); |
| 419 NSButtonCell* buttonCell = static_cast<NSButtonCell*>(cell); | 452 NSButtonCell* buttonCell = static_cast<NSButtonCell*>(cell); |
| 420 NSString* title = [self modelTextForRow:rowIndex | 453 NSString* title = [self modelTextForRow:rowIndex |
| 421 column:[[tableColumn identifier] intValue]]; | 454 column:[[tableColumn identifier] intValue]]; |
| 422 [buttonCell setTitle:title]; | 455 [buttonCell setTitle:title]; |
| 423 [buttonCell setImage: | 456 [buttonCell setImage: |
| 424 taskManagerObserver_->GetImageForRow(indexShuffle_[rowIndex])]; | 457 taskManagerObserver_->GetImageForRow(viewToModelMap_[rowIndex])]; |
| 425 [buttonCell setRefusesFirstResponder:YES]; // Don't push in like a button. | 458 [buttonCell setRefusesFirstResponder:YES]; // Don't push in like a button. |
| 426 [buttonCell setHighlightsBy:NSNoCellMask]; | 459 [buttonCell setHighlightsBy:NSNoCellMask]; |
| 427 } | 460 } |
| 428 | 461 |
| 429 return cell; | 462 return cell; |
| 430 } | 463 } |
| 431 | 464 |
| 432 - (void) tableView:(NSTableView*)tableView | 465 - (void) tableView:(NSTableView*)tableView |
| 433 sortDescriptorsDidChange:(NSArray*)oldDescriptors { | 466 sortDescriptorsDidChange:(NSArray*)oldDescriptors { |
| 434 NSArray* newDescriptors = [tableView sortDescriptors]; | 467 NSArray* newDescriptors = [tableView sortDescriptors]; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 463 task_manager_->OnWindowClosed(); | 496 task_manager_->OnWindowClosed(); |
| 464 } | 497 } |
| 465 model_->RemoveObserver(this); | 498 model_->RemoveObserver(this); |
| 466 } | 499 } |
| 467 | 500 |
| 468 //////////////////////////////////////////////////////////////////////////////// | 501 //////////////////////////////////////////////////////////////////////////////// |
| 469 // TaskManagerMac, TaskManagerModelObserver implementation: | 502 // TaskManagerMac, TaskManagerModelObserver implementation: |
| 470 | 503 |
| 471 void TaskManagerMac::OnModelChanged() { | 504 void TaskManagerMac::OnModelChanged() { |
| 472 icon_cache_.OnModelChanged(); | 505 icon_cache_.OnModelChanged(); |
| 506 [window_controller_ deselectRows]; |
| 473 [window_controller_ reloadData]; | 507 [window_controller_ reloadData]; |
| 474 } | 508 } |
| 475 | 509 |
| 476 void TaskManagerMac::OnItemsChanged(int start, int length) { | 510 void TaskManagerMac::OnItemsChanged(int start, int length) { |
| 477 icon_cache_.OnItemsChanged(start, length); | 511 icon_cache_.OnItemsChanged(start, length); |
| 478 [window_controller_ reloadData]; | 512 [window_controller_ reloadData]; |
| 479 } | 513 } |
| 480 | 514 |
| 481 void TaskManagerMac::OnItemsAdded(int start, int length) { | 515 void TaskManagerMac::OnItemsAdded(int start, int length) { |
| 482 icon_cache_.OnItemsAdded(start, length); | 516 icon_cache_.OnItemsAdded(start, length); |
| 517 [window_controller_ deselectRows]; |
| 483 [window_controller_ reloadData]; | 518 [window_controller_ reloadData]; |
| 484 } | 519 } |
| 485 | 520 |
| 486 void TaskManagerMac::OnItemsRemoved(int start, int length) { | 521 void TaskManagerMac::OnItemsRemoved(int start, int length) { |
| 487 icon_cache_.OnItemsRemoved(start, length); | 522 icon_cache_.OnItemsRemoved(start, length); |
| 523 [window_controller_ deselectRows]; |
| 488 [window_controller_ reloadData]; | 524 [window_controller_ reloadData]; |
| 489 } | 525 } |
| 490 | 526 |
| 491 NSImage* TaskManagerMac::GetImageForRow(int row) { | 527 NSImage* TaskManagerMac::GetImageForRow(int row) { |
| 492 return icon_cache_.GetImageForRow(row); | 528 return icon_cache_.GetImageForRow(row); |
| 493 } | 529 } |
| 494 | 530 |
| 495 //////////////////////////////////////////////////////////////////////////////// | 531 //////////////////////////////////////////////////////////////////////////////// |
| 496 // TaskManagerMac, public: | 532 // TaskManagerMac, public: |
| 497 | 533 |
| 498 void TaskManagerMac::WindowWasClosed() { | 534 void TaskManagerMac::WindowWasClosed() { |
| 499 delete this; | 535 delete this; |
| 500 instance_ = NULL; | 536 instance_ = NULL; |
| 501 } | 537 } |
| 502 | 538 |
| 503 // static | 539 // static |
| 504 void TaskManagerMac::Show() { | 540 void TaskManagerMac::Show() { |
| 505 if (instance_) { | 541 if (instance_) { |
| 506 // If there's a Task manager window open already, just activate it. | 542 // If there's a Task manager window open already, just activate it. |
| 507 [[instance_->window_controller_ window] | 543 [[instance_->window_controller_ window] |
| 508 makeKeyAndOrderFront:instance_->window_controller_]; | 544 makeKeyAndOrderFront:instance_->window_controller_]; |
| 509 } else { | 545 } else { |
| 510 instance_ = new TaskManagerMac(TaskManager::GetInstance()); | 546 instance_ = new TaskManagerMac(TaskManager::GetInstance()); |
| 511 instance_->model_->StartUpdating(); | 547 instance_->model_->StartUpdating(); |
| 512 } | 548 } |
| 513 } | 549 } |
| OLD | NEW |