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/gtk/task_manager_gtk.h" | 5 #include "chrome/browser/gtk/task_manager_gtk.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "app/l10n_util.h" | 9 #include "app/l10n_util.h" |
10 #include "base/gfx/gtk_util.h" | 10 #include "base/gfx/gtk_util.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "chrome/browser/gtk/menu_gtk.h" |
12 #include "chrome/common/gtk_util.h" | 13 #include "chrome/common/gtk_util.h" |
13 #include "grit/chromium_strings.h" | 14 #include "grit/chromium_strings.h" |
14 #include "grit/generated_resources.h" | 15 #include "grit/generated_resources.h" |
15 | 16 |
16 namespace { | 17 namespace { |
17 | 18 |
18 // The task manager window default size. | 19 // The task manager window default size. |
19 const int kDefaultWidth = 460; | 20 const int kDefaultWidth = 460; |
20 const int kDefaultHeight = 270; | 21 const int kDefaultHeight = 270; |
21 | 22 |
(...skipping 28 matching lines...) Expand all Loading... |
50 case IDS_TASK_MANAGER_NET_COLUMN: | 51 case IDS_TASK_MANAGER_NET_COLUMN: |
51 return kTaskManagerNetwork; | 52 return kTaskManagerNetwork; |
52 case IDS_TASK_MANAGER_PROCESS_ID_COLUMN: | 53 case IDS_TASK_MANAGER_PROCESS_ID_COLUMN: |
53 return kTaskManagerProcessID; | 54 return kTaskManagerProcessID; |
54 default: | 55 default: |
55 NOTREACHED(); | 56 NOTREACHED(); |
56 return static_cast<TaskManagerColumn>(-1); | 57 return static_cast<TaskManagerColumn>(-1); |
57 } | 58 } |
58 } | 59 } |
59 | 60 |
| 61 int TaskManagerColumnIDToResourceID(int id) { |
| 62 printf("id: %d\n", id); |
| 63 switch (id) { |
| 64 case kTaskManagerPage: |
| 65 return IDS_TASK_MANAGER_PAGE_COLUMN; |
| 66 case kTaskManagerPhysicalMem: |
| 67 return IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN; |
| 68 case kTaskManagerSharedMem: |
| 69 return IDS_TASK_MANAGER_SHARED_MEM_COLUMN; |
| 70 case kTaskManagerPrivateMem: |
| 71 return IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN; |
| 72 case kTaskManagerCPU: |
| 73 return IDS_TASK_MANAGER_CPU_COLUMN; |
| 74 case kTaskManagerNetwork: |
| 75 return IDS_TASK_MANAGER_NET_COLUMN; |
| 76 case kTaskManagerProcessID: |
| 77 return IDS_TASK_MANAGER_PROCESS_ID_COLUMN; |
| 78 default: |
| 79 NOTREACHED(); |
| 80 return -1; |
| 81 } |
| 82 } |
| 83 |
60 // Should be used for all gtk_tree_view functions that require a column index on | 84 // Should be used for all gtk_tree_view functions that require a column index on |
61 // input. | 85 // input. |
62 // | 86 // |
63 // We need colid - 1 because the gtk_tree_view function is asking for the | 87 // We need colid - 1 because the gtk_tree_view function is asking for the |
64 // column index, not the column id, and both kTaskManagerIcon and | 88 // column index, not the column id, and both kTaskManagerIcon and |
65 // kTaskManagerPage are in the same column index, so all column IDs are off by | 89 // kTaskManagerPage are in the same column index, so all column IDs are off by |
66 // one. | 90 // one. |
67 int TreeViewColumnIndexFromID(TaskManagerColumn colid) { | 91 int TreeViewColumnIndexFromID(TaskManagerColumn colid) { |
68 return colid - 1; | 92 return colid - 1; |
69 } | 93 } |
70 | 94 |
71 // Shows or hides a treeview column. | 95 // Shows or hides a treeview column. |
72 void TreeViewColumnSetVisible(GtkWidget* treeview, TaskManagerColumn colid, | 96 void TreeViewColumnSetVisible(GtkWidget* treeview, TaskManagerColumn colid, |
73 bool visible) { | 97 bool visible) { |
74 GtkTreeViewColumn* column = gtk_tree_view_get_column( | 98 GtkTreeViewColumn* column = gtk_tree_view_get_column( |
75 GTK_TREE_VIEW(treeview), TreeViewColumnIndexFromID(colid)); | 99 GTK_TREE_VIEW(treeview), TreeViewColumnIndexFromID(colid)); |
76 gtk_tree_view_column_set_visible(column, visible); | 100 gtk_tree_view_column_set_visible(column, visible); |
77 } | 101 } |
78 | 102 |
| 103 bool TreeViewColumnIsVisible(GtkWidget* treeview, TaskManagerColumn colid) { |
| 104 GtkTreeViewColumn* column = gtk_tree_view_get_column( |
| 105 GTK_TREE_VIEW(treeview), TreeViewColumnIndexFromID(colid)); |
| 106 return gtk_tree_view_column_get_visible(column); |
| 107 } |
| 108 |
79 void TreeViewInsertColumnWithPixbuf(GtkWidget* treeview, int resid) { | 109 void TreeViewInsertColumnWithPixbuf(GtkWidget* treeview, int resid) { |
80 int colid = TaskManagerResourceIDToColumnID(resid); | 110 int colid = TaskManagerResourceIDToColumnID(resid); |
81 GtkTreeViewColumn* column = gtk_tree_view_column_new(); | 111 GtkTreeViewColumn* column = gtk_tree_view_column_new(); |
82 gtk_tree_view_column_set_title(column, | 112 gtk_tree_view_column_set_title(column, |
83 l10n_util::GetStringUTF8(resid).c_str()); | 113 l10n_util::GetStringUTF8(resid).c_str()); |
84 GtkCellRenderer* image_renderer = gtk_cell_renderer_pixbuf_new(); | 114 GtkCellRenderer* image_renderer = gtk_cell_renderer_pixbuf_new(); |
85 gtk_tree_view_column_pack_start(column, image_renderer, FALSE); | 115 gtk_tree_view_column_pack_start(column, image_renderer, FALSE); |
86 gtk_tree_view_column_add_attribute(column, image_renderer, | 116 gtk_tree_view_column_add_attribute(column, image_renderer, |
87 "pixbuf", kTaskManagerIcon); | 117 "pixbuf", kTaskManagerIcon); |
88 GtkCellRenderer* text_renderer = gtk_cell_renderer_text_new(); | 118 GtkCellRenderer* text_renderer = gtk_cell_renderer_text_new(); |
(...skipping 28 matching lines...) Expand all Loading... |
117 gint* indices = gtk_tree_path_get_indices(path); | 147 gint* indices = gtk_tree_path_get_indices(path); |
118 if (!indices) { | 148 if (!indices) { |
119 NOTREACHED(); | 149 NOTREACHED(); |
120 return -1; | 150 return -1; |
121 } | 151 } |
122 return indices[0]; | 152 return indices[0]; |
123 } | 153 } |
124 | 154 |
125 } // namespace | 155 } // namespace |
126 | 156 |
| 157 class TaskManagerGtk::ContextMenuController : public MenuGtk::Delegate { |
| 158 public: |
| 159 explicit ContextMenuController(TaskManagerGtk* task_manager) |
| 160 : task_manager_(task_manager) { |
| 161 menu_.reset(new MenuGtk(this, false)); |
| 162 for (int i = kTaskManagerPage; i < kTaskManagerColumnCount - 1; i++) { |
| 163 menu_->AppendCheckMenuItemWithLabel( |
| 164 i, l10n_util::GetStringUTF8(TaskManagerColumnIDToResourceID(i))); |
| 165 } |
| 166 |
| 167 menu_->AppendCheckMenuItemWithLabel(kTaskManagerGoatsTeleported, |
| 168 "Goats Teleported"); |
| 169 } |
| 170 |
| 171 virtual ~ContextMenuController() {} |
| 172 |
| 173 void RunMenu() { |
| 174 menu_->PopupAsContext(gtk_get_current_event_time()); |
| 175 } |
| 176 |
| 177 void Cancel() { |
| 178 task_manager_ = NULL; |
| 179 menu_->Cancel(); |
| 180 } |
| 181 |
| 182 private: |
| 183 // MenuGtk::Delegate implementation: |
| 184 virtual bool IsCommandEnabled(int command_id) const { |
| 185 if (!task_manager_) |
| 186 return false; |
| 187 |
| 188 return true; |
| 189 } |
| 190 |
| 191 virtual bool IsItemChecked(int command_id) const { |
| 192 if (!task_manager_) |
| 193 return false; |
| 194 |
| 195 TaskManagerColumn colid = static_cast<TaskManagerColumn>(command_id); |
| 196 return TreeViewColumnIsVisible(task_manager_->treeview_, colid); |
| 197 } |
| 198 |
| 199 virtual void ExecuteCommand(int command_id) { |
| 200 if (!task_manager_) |
| 201 return; |
| 202 |
| 203 TaskManagerColumn colid = static_cast<TaskManagerColumn>(command_id); |
| 204 bool visible = !TreeViewColumnIsVisible(task_manager_->treeview_, colid); |
| 205 TreeViewColumnSetVisible(task_manager_->treeview_, colid, visible); |
| 206 } |
| 207 |
| 208 // The context menu. |
| 209 scoped_ptr<MenuGtk> menu_; |
| 210 |
| 211 // The TaskManager the context menu was brought up for. Set to NULL when the |
| 212 // menu is canceled. |
| 213 TaskManagerGtk* task_manager_; |
| 214 |
| 215 DISALLOW_COPY_AND_ASSIGN(ContextMenuController); |
| 216 }; |
| 217 |
127 TaskManagerGtk::TaskManagerGtk() | 218 TaskManagerGtk::TaskManagerGtk() |
128 : task_manager_(TaskManager::GetInstance()), | 219 : task_manager_(TaskManager::GetInstance()), |
129 model_(TaskManager::GetInstance()->model()), | 220 model_(TaskManager::GetInstance()->model()), |
130 dialog_(NULL), | 221 dialog_(NULL), |
131 treeview_(NULL), | 222 treeview_(NULL), |
132 process_list_(NULL), | 223 process_list_(NULL), |
133 process_count_(0) { | 224 process_count_(0) { |
134 Init(); | 225 Init(); |
135 } | 226 } |
136 | 227 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 NULL, | 310 NULL, |
220 GTK_DIALOG_NO_SEPARATOR, | 311 GTK_DIALOG_NO_SEPARATOR, |
221 l10n_util::GetStringUTF8(IDS_TASK_MANAGER_KILL).c_str(), | 312 l10n_util::GetStringUTF8(IDS_TASK_MANAGER_KILL).c_str(), |
222 kTaskManagerResponseKill, | 313 kTaskManagerResponseKill, |
223 NULL); | 314 NULL); |
224 | 315 |
225 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog_)->vbox), | 316 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog_)->vbox), |
226 gtk_util::kContentAreaSpacing); | 317 gtk_util::kContentAreaSpacing); |
227 | 318 |
228 g_signal_connect(G_OBJECT(dialog_), "response", G_CALLBACK(OnResponse), this); | 319 g_signal_connect(G_OBJECT(dialog_), "response", G_CALLBACK(OnResponse), this); |
| 320 g_signal_connect(G_OBJECT(dialog_), "button-release-event", |
| 321 G_CALLBACK(OnButtonReleaseEvent), this); |
| 322 gtk_widget_add_events(dialog_, |
| 323 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK); |
229 | 324 |
230 CreateTaskManagerTreeview(); | 325 CreateTaskManagerTreeview(); |
231 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(treeview_), TRUE); | 326 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(treeview_), TRUE); |
232 gtk_tree_view_set_grid_lines(GTK_TREE_VIEW(treeview_), | 327 gtk_tree_view_set_grid_lines(GTK_TREE_VIEW(treeview_), |
233 GTK_TREE_VIEW_GRID_LINES_HORIZONTAL); | 328 GTK_TREE_VIEW_GRID_LINES_HORIZONTAL); |
| 329 g_signal_connect(G_OBJECT(treeview_), "button-release-event", |
| 330 G_CALLBACK(OnButtonReleaseEvent), this); |
| 331 gtk_widget_add_events(treeview_, |
| 332 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK); |
234 | 333 |
235 // Hide some columns by default | 334 // Hide some columns by default |
236 TreeViewColumnSetVisible(treeview_, kTaskManagerSharedMem, false); | 335 TreeViewColumnSetVisible(treeview_, kTaskManagerSharedMem, false); |
237 TreeViewColumnSetVisible(treeview_, kTaskManagerPrivateMem, false); | 336 TreeViewColumnSetVisible(treeview_, kTaskManagerPrivateMem, false); |
238 TreeViewColumnSetVisible(treeview_, kTaskManagerProcessID, false); | 337 TreeViewColumnSetVisible(treeview_, kTaskManagerProcessID, false); |
239 TreeViewColumnSetVisible(treeview_, kTaskManagerGoatsTeleported, false); | 338 TreeViewColumnSetVisible(treeview_, kTaskManagerGoatsTeleported, false); |
240 | 339 |
241 // |selection| is owned by |treeview_|. | 340 // |selection| is owned by |treeview_|. |
242 GtkTreeSelection* selection = gtk_tree_view_get_selection( | 341 GtkTreeSelection* selection = gtk_tree_view_get_selection( |
243 GTK_TREE_VIEW(treeview_)); | 342 GTK_TREE_VIEW(treeview_)); |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 | 454 |
356 GtkTreeModel* model; | 455 GtkTreeModel* model; |
357 GList* paths = gtk_tree_selection_get_selected_rows(selection, &model); | 456 GList* paths = gtk_tree_selection_get_selected_rows(selection, &model); |
358 for (GList* item = paths; item; item = item->next) { | 457 for (GList* item = paths; item; item = item->next) { |
359 int row = GetRowNumForPath(reinterpret_cast<GtkTreePath*>(item->data)); | 458 int row = GetRowNumForPath(reinterpret_cast<GtkTreePath*>(item->data)); |
360 task_manager_->KillProcess(row); | 459 task_manager_->KillProcess(row); |
361 } | 460 } |
362 g_list_free(paths); | 461 g_list_free(paths); |
363 } | 462 } |
364 | 463 |
| 464 void TaskManagerGtk::ShowContextMenu() { |
| 465 if (!menu_controller_.get()) |
| 466 menu_controller_.reset(new ContextMenuController(this)); |
| 467 |
| 468 menu_controller_->RunMenu(); |
| 469 } |
| 470 |
365 // static | 471 // static |
366 void TaskManagerGtk::OnResponse(GtkDialog* dialog, gint response_id, | 472 void TaskManagerGtk::OnResponse(GtkDialog* dialog, gint response_id, |
367 TaskManagerGtk* task_manager) { | 473 TaskManagerGtk* task_manager) { |
368 if (response_id == GTK_RESPONSE_DELETE_EVENT) { | 474 if (response_id == GTK_RESPONSE_DELETE_EVENT) { |
369 instance_ = NULL; | 475 instance_ = NULL; |
370 delete task_manager; | 476 delete task_manager; |
371 } else if (response_id == kTaskManagerResponseKill) { | 477 } else if (response_id == kTaskManagerResponseKill) { |
372 task_manager->KillSelectedProcesses(); | 478 task_manager->KillSelectedProcesses(); |
373 } | 479 } |
374 } | 480 } |
(...skipping 11 matching lines...) Expand all Loading... |
386 selection_contains_browser_process = true; | 492 selection_contains_browser_process = true; |
387 break; | 493 break; |
388 } | 494 } |
389 } | 495 } |
390 g_list_free(paths); | 496 g_list_free(paths); |
391 | 497 |
392 bool sensitive = (paths != NULL) && !selection_contains_browser_process; | 498 bool sensitive = (paths != NULL) && !selection_contains_browser_process; |
393 gtk_dialog_set_response_sensitive(GTK_DIALOG(task_manager->dialog_), | 499 gtk_dialog_set_response_sensitive(GTK_DIALOG(task_manager->dialog_), |
394 kTaskManagerResponseKill, sensitive); | 500 kTaskManagerResponseKill, sensitive); |
395 } | 501 } |
| 502 |
| 503 // static |
| 504 gboolean TaskManagerGtk::OnButtonReleaseEvent(GtkWidget* widget, |
| 505 GdkEventButton* event, |
| 506 TaskManagerGtk* task_manager) { |
| 507 // We don't want to open the context menu in the treeview. |
| 508 if (widget == task_manager->treeview_) |
| 509 return TRUE; |
| 510 |
| 511 if (event->button == 3) |
| 512 task_manager->ShowContextMenu(); |
| 513 |
| 514 return FALSE; |
| 515 } |
OLD | NEW |