Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(38)

Side by Side Diff: chrome/browser/gtk/task_manager_gtk.cc

Issue 151154: Implement the core functionality of the gtk task manager.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/gtk/task_manager_gtk.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/logging.h" 10 #include "base/logging.h"
11 #include "chrome/common/gtk_util.h" 11 #include "chrome/common/gtk_util.h"
12 #include "grit/chromium_strings.h" 12 #include "grit/chromium_strings.h"
13 #include "grit/generated_resources.h" 13 #include "grit/generated_resources.h"
14 14
15 namespace { 15 namespace {
16 16
17 // The task manager window default size. 17 // The task manager window default size.
18 const int kDefaultWidth = 460; 18 const int kDefaultWidth = 460;
19 const int kDefaultHeight = 270; 19 const int kDefaultHeight = 270;
20 20
21 // The resource id for the 'End process' button. 21 // The resource id for the 'End process' button.
22 const gint kTaskManagerResponseKill = 1; 22 const gint kTaskManagerResponseKill = 1;
23 23
24 enum TaskManagerColumns { 24 enum TaskManagerColumn {
25 kTaskManagerPage, 25 kTaskManagerPage,
26 kTaskManagerPhysicalMem, 26 kTaskManagerPhysicalMem,
27 kTaskManagerSharedMem, 27 kTaskManagerSharedMem,
28 kTaskManagerPrivateMem, 28 kTaskManagerPrivateMem,
29 kTaskManagerCPU, 29 kTaskManagerCPU,
30 kTaskManagerNetwork, 30 kTaskManagerNetwork,
31 kTaskManagerProcessID, 31 kTaskManagerProcessID,
32 kTaskManagerGoatsTeleported,
32 kTaskManagerColumnCount, 33 kTaskManagerColumnCount,
33 }; 34 };
34 35
35 void TreeViewColumnSetVisible(GtkWidget* treeview, TaskManagerColumns colid, 36 TaskManagerColumn TaskManagerResourceIDToColumnID(int id) {
37 switch (id) {
38 case IDS_TASK_MANAGER_PAGE_COLUMN:
39 return kTaskManagerPage;
40 case IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN:
41 return kTaskManagerPhysicalMem;
42 case IDS_TASK_MANAGER_SHARED_MEM_COLUMN:
43 return kTaskManagerSharedMem;
44 case IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN:
45 return kTaskManagerPrivateMem;
46 case IDS_TASK_MANAGER_CPU_COLUMN:
47 return kTaskManagerCPU;
48 case IDS_TASK_MANAGER_NET_COLUMN:
49 return kTaskManagerNetwork;
50 case IDS_TASK_MANAGER_PROCESS_ID_COLUMN:
51 return kTaskManagerProcessID;
52 default:
53 NOTREACHED();
54 return static_cast<TaskManagerColumn>(-1);
55 }
56 }
57
58 // Shows or hides a treeview column.
59 void TreeViewColumnSetVisible(GtkWidget* treeview, TaskManagerColumn colid,
36 bool visible) { 60 bool visible) {
37 GtkTreeViewColumn* column = gtk_tree_view_get_column(GTK_TREE_VIEW(treeview), 61 GtkTreeViewColumn* column = gtk_tree_view_get_column(GTK_TREE_VIEW(treeview),
38 colid); 62 colid);
39 gtk_tree_view_column_set_visible(column, visible); 63 gtk_tree_view_column_set_visible(column, visible);
40 } 64 }
41 65
42 void TreeViewInsertColumn(GtkWidget* treeview, 66 // Inserts a column with a column id of |colid| and |name|.
43 TaskManagerColumns colid, int str) { 67 void TreeViewInsertColumnWithName(GtkWidget* treeview,
68 int colid, const char* name) {
44 GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); 69 GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
45 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), -1, 70 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), -1,
46 l10n_util::GetStringUTF8(str).c_str(), 71 name, renderer, "text",
47 renderer, "text", colid, NULL); 72 colid, NULL);
48 } 73 }
49 74
50 GtkWidget* CreateTaskManagerTreeview() { 75 // Loads the column name from |resid| and uses the corresponding
51 GtkWidget* treeview = gtk_tree_view_new(); 76 // TaskManagerColumn value as the column id to insert into the treeview.
77 void TreeViewInsertColumn(GtkWidget* treeview, int resid) {
78 TreeViewInsertColumnWithName(treeview, TaskManagerResourceIDToColumnID(resid),
79 l10n_util::GetStringUTF8(resid).c_str());
80 }
52 81
53 TreeViewInsertColumn(treeview, kTaskManagerPage, 82 // Get the row number corresponding to |path|.
54 IDS_TASK_MANAGER_PAGE_COLUMN); 83 gint GetRowNumForPath(GtkTreePath* path) {
55 TreeViewInsertColumn(treeview, kTaskManagerPhysicalMem, 84 gint* indices = gtk_tree_path_get_indices(path);
56 IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN); 85 if (!indices) {
57 TreeViewInsertColumn(treeview, kTaskManagerSharedMem, 86 NOTREACHED();
58 IDS_TASK_MANAGER_SHARED_MEM_COLUMN); 87 return -1;
59 TreeViewInsertColumn(treeview, kTaskManagerPrivateMem, 88 }
60 IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN); 89 return indices[0];
61 TreeViewInsertColumn(treeview, kTaskManagerCPU,
62 IDS_TASK_MANAGER_CPU_COLUMN);
63 TreeViewInsertColumn(treeview, kTaskManagerNetwork,
64 IDS_TASK_MANAGER_NET_COLUMN);
65 TreeViewInsertColumn(treeview, kTaskManagerProcessID,
66 IDS_TASK_MANAGER_PROCESS_ID_COLUMN);
67
68 GtkListStore* store = gtk_list_store_new(kTaskManagerColumnCount,
69 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT,
70 G_TYPE_STRING, G_TYPE_UINT);
71
72 gtk_tree_view_set_model(GTK_TREE_VIEW(treeview), GTK_TREE_MODEL(store));
73 return treeview;
74 } 90 }
75 91
76 } // namespace 92 } // namespace
77 93
78 TaskManagerGtk::TaskManagerGtk() 94 TaskManagerGtk::TaskManagerGtk()
79 : task_manager_(TaskManager::GetInstance()), 95 : task_manager_(TaskManager::GetInstance()),
80 model_(TaskManager::GetInstance()->model()), 96 model_(TaskManager::GetInstance()->model()),
81 dialog_(NULL), 97 dialog_(NULL),
82 treeview_(NULL) { 98 treeview_(NULL),
99 process_list_(NULL),
100 process_count_(0) {
83 Init(); 101 Init();
84 } 102 }
85 103
86 // static 104 // static
87 TaskManagerGtk* TaskManagerGtk::instance_ = NULL; 105 TaskManagerGtk* TaskManagerGtk::instance_ = NULL;
88 106
89 TaskManagerGtk::~TaskManagerGtk() { 107 TaskManagerGtk::~TaskManagerGtk() {
108 task_manager_->OnWindowClosed();
90 } 109 }
91 110
111 ////////////////////////////////////////////////////////////////////////////////
112 // TaskManagerGtk, TaskManagerModelObserver implementation:
113
114 void TaskManagerGtk::OnModelChanged() {
115 // Nothing to do.
116 }
117
118 void TaskManagerGtk::OnItemsChanged(int start, int length) {
119 GtkTreeIter iter;
120 gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(process_list_), &iter,
121 NULL, start);
122
123 for (int i = start; i < start + length; i++) {
124 SetRowDataFromModel(i, &iter);
125 gtk_tree_model_iter_next(GTK_TREE_MODEL(process_list_), &iter);
126 }
127 }
128
129 void TaskManagerGtk::OnItemsAdded(int start, int length) {
130 GtkTreeIter iter;
131 if (start == 0) {
132 gtk_list_store_prepend(process_list_, &iter);
133 } else if (start >= process_count_) {
134 gtk_list_store_append(process_list_, &iter);
135 } else {
136 GtkTreeIter sibling;
137 gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(process_list_), &sibling,
138 NULL, start);
139 gtk_list_store_insert_before(process_list_, &iter, &sibling);
140 }
141
142 SetRowDataFromModel(start, &iter);
143
144 for (int i = start + 1; i < start + length; i++) {
145 gtk_list_store_insert_after(process_list_, &iter, &iter);
146 SetRowDataFromModel(i, &iter);
147 }
148
149 process_count_ += length;
150 }
151
152 void TaskManagerGtk::OnItemsRemoved(int start, int length) {
153 GtkTreeIter iter;
154 gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(process_list_), &iter,
155 NULL, start);
156
157 for (int i = 0; i < length; i++) {
158 // |iter| is moved to the next valid node when the current node is removed.
159 gtk_list_store_remove(process_list_, &iter);
160 }
161
162 process_count_ -= length;
163 }
164
165 ////////////////////////////////////////////////////////////////////////////////
166 // TaskManagerGtk, public:
167
168 // static
169 void TaskManagerGtk::Show() {
170 if (instance_) {
171 // If there's a Task manager window open already, just activate it.
172 gtk_window_present(GTK_WINDOW(instance_->dialog_));
173 } else {
174 instance_ = new TaskManagerGtk;
175 instance_->model_->StartUpdating();
176 }
177 }
178
179 ////////////////////////////////////////////////////////////////////////////////
180 // TaskManagerGtk, private:
181
92 void TaskManagerGtk::Init() { 182 void TaskManagerGtk::Init() {
93 dialog_ = gtk_dialog_new_with_buttons( 183 dialog_ = gtk_dialog_new_with_buttons(
94 l10n_util::GetStringUTF8(IDS_TASK_MANAGER_TITLE).c_str(), 184 l10n_util::GetStringUTF8(IDS_TASK_MANAGER_TITLE).c_str(),
95 // Task Manager window is shared between all browsers. 185 // Task Manager window is shared between all browsers.
96 NULL, 186 NULL,
97 GTK_DIALOG_NO_SEPARATOR, 187 GTK_DIALOG_NO_SEPARATOR,
98 l10n_util::GetStringUTF8(IDS_TASK_MANAGER_KILL).c_str(), 188 l10n_util::GetStringUTF8(IDS_TASK_MANAGER_KILL).c_str(),
99 kTaskManagerResponseKill, 189 kTaskManagerResponseKill,
100 NULL); 190 NULL);
101 191
102 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog_)->vbox), 192 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog_)->vbox),
103 gtk_util::kContentAreaSpacing); 193 gtk_util::kContentAreaSpacing);
104 194
105 g_signal_connect(G_OBJECT(dialog_), "response", G_CALLBACK(OnResponse), this); 195 g_signal_connect(G_OBJECT(dialog_), "response", G_CALLBACK(OnResponse), this);
106 196
107 treeview_ = CreateTaskManagerTreeview(); 197 CreateTaskManagerTreeview();
108 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(treeview_), TRUE); 198 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(treeview_), TRUE);
109 gtk_tree_view_set_grid_lines(GTK_TREE_VIEW(treeview_), 199 gtk_tree_view_set_grid_lines(GTK_TREE_VIEW(treeview_),
110 GTK_TREE_VIEW_GRID_LINES_HORIZONTAL); 200 GTK_TREE_VIEW_GRID_LINES_HORIZONTAL);
111 201
112 // Hide some columns by default 202 // Hide some columns by default
113 TreeViewColumnSetVisible(treeview_, kTaskManagerSharedMem, false); 203 TreeViewColumnSetVisible(treeview_, kTaskManagerSharedMem, false);
114 TreeViewColumnSetVisible(treeview_, kTaskManagerPrivateMem, false); 204 TreeViewColumnSetVisible(treeview_, kTaskManagerPrivateMem, false);
115 TreeViewColumnSetVisible(treeview_, kTaskManagerProcessID, false); 205 TreeViewColumnSetVisible(treeview_, kTaskManagerProcessID, false);
206 TreeViewColumnSetVisible(treeview_, kTaskManagerGoatsTeleported, false);
207
208 // |selection| is owned by |treeview_|.
209 GtkTreeSelection* selection = gtk_tree_view_get_selection(
210 GTK_TREE_VIEW(treeview_));
211 gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
212 g_signal_connect(G_OBJECT(selection), "changed",
213 G_CALLBACK(OnSelectionChanged), this);
116 214
117 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog_)->vbox), treeview_); 215 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog_)->vbox), treeview_);
118 216
119 gtk_window_resize(GTK_WINDOW(dialog_), kDefaultWidth, kDefaultHeight); 217 gtk_window_resize(GTK_WINDOW(dialog_), kDefaultWidth, kDefaultHeight);
120 gtk_widget_show_all(dialog_); 218 gtk_widget_show_all(dialog_);
121 219
122 // TODO(jhawkins): mode_->SetObserver() and implement OnItems*. 220 model_->SetObserver(this);
123 } 221 }
124 222
125 void TaskManagerGtk::OnModelChanged() { 223 void TaskManagerGtk::CreateTaskManagerTreeview() {
126 NOTIMPLEMENTED(); 224 treeview_ = gtk_tree_view_new();
225
226 TreeViewInsertColumn(treeview_, IDS_TASK_MANAGER_PAGE_COLUMN);
227 TreeViewInsertColumn(treeview_, IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN);
228 TreeViewInsertColumn(treeview_, IDS_TASK_MANAGER_SHARED_MEM_COLUMN);
229 TreeViewInsertColumn(treeview_, IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN);
230 TreeViewInsertColumn(treeview_, IDS_TASK_MANAGER_CPU_COLUMN);
231 TreeViewInsertColumn(treeview_, IDS_TASK_MANAGER_NET_COLUMN);
232 TreeViewInsertColumn(treeview_, IDS_TASK_MANAGER_PROCESS_ID_COLUMN);
233
234 TreeViewInsertColumnWithName(treeview_, kTaskManagerGoatsTeleported,
235 "Goats Teleported");
236
237 process_list_ = gtk_list_store_new(kTaskManagerColumnCount,
238 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
239 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
240
241 gtk_tree_view_set_model(GTK_TREE_VIEW(treeview_),
242 GTK_TREE_MODEL(process_list_));
243 g_object_unref(process_list_);
127 } 244 }
128 245
129 void TaskManagerGtk::OnItemsChanged(int start, int length) { 246 std::string TaskManagerGtk::GetModelText(int row, int col_id) {
130 NOTIMPLEMENTED(); 247 switch (col_id) {
248 case IDS_TASK_MANAGER_PAGE_COLUMN: // Process
249 return WideToUTF8(model_->GetResourceTitle(row));
250
251 case IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN: // Memory
252 if (!model_->IsResourceFirstInGroup(row))
253 return std::string();
254 return WideToUTF8(model_->GetResourcePrivateMemory(row));
255
256 case IDS_TASK_MANAGER_SHARED_MEM_COLUMN: // Memory
257 if (!model_->IsResourceFirstInGroup(row))
258 return std::string();
259 return WideToUTF8(model_->GetResourceSharedMemory(row));
260
261 case IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN: // Memory
262 if (!model_->IsResourceFirstInGroup(row))
263 return std::string();
264 return WideToUTF8(model_->GetResourcePhysicalMemory(row));
265
266 case IDS_TASK_MANAGER_CPU_COLUMN: // CPU
267 if (!model_->IsResourceFirstInGroup(row))
268 return std::string();
269 return WideToUTF8(model_->GetResourceCPUUsage(row));
270
271 case IDS_TASK_MANAGER_NET_COLUMN: // Net
272 return WideToUTF8(model_->GetResourceNetworkUsage(row));
273
274 case IDS_TASK_MANAGER_PROCESS_ID_COLUMN: // Process ID
275 if (!model_->IsResourceFirstInGroup(row))
276 return std::string();
277 return WideToUTF8(model_->GetResourceProcessId(row));
278
279 case kTaskManagerGoatsTeleported: // Goats Teleported!
280 return WideToUTF8(model_->GetResourceGoatsTeleported(row));
281
282 default:
283 return WideToUTF8(model_->GetResourceStatsValue(row, col_id));
284 }
131 } 285 }
132 286
133 void TaskManagerGtk::OnItemsAdded(int start, int length) { 287 void TaskManagerGtk::SetRowDataFromModel(int row, GtkTreeIter* iter) {
134 NOTIMPLEMENTED(); 288 std::string page = GetModelText(row, IDS_TASK_MANAGER_PAGE_COLUMN);
289 std::string phys_mem = GetModelText(
290 row, IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN);
291 std::string shared_mem = GetModelText(
292 row, IDS_TASK_MANAGER_SHARED_MEM_COLUMN);
293 std::string priv_mem = GetModelText(row, IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN);
294 std::string cpu = GetModelText(row, IDS_TASK_MANAGER_CPU_COLUMN);
295 std::string net = GetModelText(row, IDS_TASK_MANAGER_NET_COLUMN);
296 std::string procid = GetModelText(row, IDS_TASK_MANAGER_PROCESS_ID_COLUMN);
297 std::string goats = GetModelText(row, kTaskManagerGoatsTeleported);
298 gtk_list_store_set(process_list_, iter,
299 kTaskManagerPage, page.c_str(),
300 kTaskManagerPhysicalMem, phys_mem.c_str(),
301 kTaskManagerSharedMem, shared_mem.c_str(),
302 kTaskManagerPrivateMem, priv_mem.c_str(),
303 kTaskManagerCPU, cpu.c_str(),
304 kTaskManagerNetwork, net.c_str(),
305 kTaskManagerProcessID, procid.c_str(),
306 kTaskManagerGoatsTeleported, goats.c_str(),
307 -1);
135 } 308 }
136 309
137 void TaskManagerGtk::OnItemsRemoved(int start, int length) { 310 void TaskManagerGtk::KillSelectedProcesses() {
138 NOTIMPLEMENTED(); 311 GtkTreeSelection* selection = gtk_tree_view_get_selection(
312 GTK_TREE_VIEW(treeview_));
313
314 GtkTreeModel* model;
315 GList* paths = gtk_tree_selection_get_selected_rows(selection, &model);
316 for (GList* item = paths; item; item = item->next) {
317 int row = GetRowNumForPath(reinterpret_cast<GtkTreePath*>(item->data));
318 task_manager_->KillProcess(row);
319 }
320 g_list_free(paths);
139 } 321 }
140 322
141 // static 323 // static
142 void TaskManagerGtk::OnResponse(GtkDialog* dialog, gint response_id, 324 void TaskManagerGtk::OnResponse(GtkDialog* dialog, gint response_id,
143 TaskManagerGtk* task_manager) { 325 TaskManagerGtk* task_manager) {
144 if (response_id == GTK_RESPONSE_DELETE_EVENT) { 326 if (response_id == GTK_RESPONSE_DELETE_EVENT) {
145 instance_ = NULL; 327 instance_ = NULL;
146 task_manager->task_manager_->OnWindowClosed();
147 delete task_manager; 328 delete task_manager;
329 } else if (response_id == kTaskManagerResponseKill) {
330 task_manager->KillSelectedProcesses();
148 } 331 }
149 } 332 }
150 333
151 // static 334 // static
152 void TaskManagerGtk::Show() { 335 void TaskManagerGtk::OnSelectionChanged(GtkTreeSelection* selection,
153 if (instance_) { 336 TaskManagerGtk* task_manager) {
154 // If there's a Task manager window open already, just activate it. 337 bool selection_contains_browser_process = false;
155 gtk_window_present(GTK_WINDOW(instance_->dialog_)); 338
156 } else { 339 GtkTreeModel* model;
157 instance_ = new TaskManagerGtk; 340 GList* paths = gtk_tree_selection_get_selected_rows(selection, &model);
158 instance_->model_->StartUpdating(); 341 for (GList* item = paths; item; item = item->next) {
342 int row = GetRowNumForPath(reinterpret_cast<GtkTreePath*>(item->data));
343 if (task_manager->task_manager_->IsBrowserProcess(row)) {
344 selection_contains_browser_process = true;
345 break;
346 }
159 } 347 }
348 g_list_free(paths);
349
350 gtk_dialog_set_response_sensitive(GTK_DIALOG(task_manager->dialog_),
351 kTaskManagerResponseKill,
352 !selection_contains_browser_process);
160 } 353 }
OLDNEW
« no previous file with comments | « chrome/browser/gtk/task_manager_gtk.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698