1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_UI_GTK_TASK_MANAGER_GTK_H_
6#define CHROME_BROWSER_UI_GTK_TASK_MANAGER_GTK_H_
7
8#include <gtk/gtk.h>
9
10#include <string>
11
12#include "base/compiler_specific.h"
13#include "base/memory/scoped_ptr.h"
14#include "chrome/browser/task_manager/task_manager.h"
15#include "grit/generated_resources.h"
16#include "ui/base/gtk/gtk_signal.h"
17
18namespace gfx {
19class Point;
20}
21
22class TaskManagerGtk : public TaskManagerModelObserver {
23 public:
24  TaskManagerGtk();
25  virtual ~TaskManagerGtk();
26
27  // TaskManagerModelObserver
28  virtual void OnModelChanged() OVERRIDE;
29  virtual void OnItemsChanged(int start, int length) OVERRIDE;
30  virtual void OnItemsAdded(int start, int length) OVERRIDE;
31  virtual void OnItemsRemoved(int start, int length) OVERRIDE;
32
33  // Closes the task manager window.
34  void Close();
35
36  // Creates the task manager if it doesn't exist; otherwise, it activates the
37  // existing task manager window.
38  static void Show();
39
40 private:
41  class ContextMenuController;
42  friend class ContextMenuController;
43
44  // Initializes the task manager dialog.
45  void Init();
46
47  // Set |dialog_|'s initial size, using its previous size if that was saved.
48  void SetInitialDialogSize();
49
50  // Connects the ctrl-w accelerator to the dialog.
51  void ConnectAccelerators();
52
53  // Sets up the treeview widget.
54  void CreateTaskManagerTreeview();
55
56  // Returns the model data for a given |row| and |col_id|.
57  std::string GetModelText(int row, int col_id);
58
59  // Retrieves the resource icon from the model for |row|.
60  GdkPixbuf* GetModelIcon(int row);
61
62  // Sets the treeview row data.  |row| is an index into the model and |iter|
63  // is the current position in the treeview.
64  void SetRowDataFromModel(int row, GtkTreeIter* iter);
65
66  // Queries the treeview for the selected rows, and kills those processes.
67  void KillSelectedProcesses();
68
69  // Opens the context menu used to select the task manager columns.
70  void ShowContextMenu(const gfx::Point& point, guint32 event_time);
71
72  // Opens about:memory in a new foreground tab.
73  void OnLinkActivated();
74
75  // Compare implementation used for sorting columns.
76  gint CompareImpl(GtkTreeModel* tree_model, GtkTreeIter* a,
77                   GtkTreeIter* b, int id);
78
79  // Response signal handler that notifies us of dialog destruction.
80  CHROMEGTK_CALLBACK_0(TaskManagerGtk, void, OnDestroy);
81
82  // Response signal handler that notifies us of dialog responses.
83  CHROMEGTK_CALLBACK_1(TaskManagerGtk, void, OnResponse, int);
84
85  // Realize signal handler to set the task column's initial size.
86  CHROMEG_CALLBACK_0(TaskManagerGtk, void, OnTreeViewRealize, GtkTreeView*);
87
88  // Changed signal handler that is sent when the treeview selection changes.
89  CHROMEG_CALLBACK_0(TaskManagerGtk, void, OnSelectionChanged,
90                     GtkTreeSelection*);
91
92  // row-activated handler that foregrounds a process on activation (e.g.,
93  // double-click).
94  CHROMEGTK_CALLBACK_2(TaskManagerGtk, void, OnRowActivated,
95                       GtkTreePath*, GtkTreeViewColumn*);
96
97  // button-event handler that opens the right-click context menu.
98  // Note: GTK does menu on mouse-up while views does menu on mouse-down;
99  // this handler is used for both.
100  CHROMEGTK_CALLBACK_1(TaskManagerGtk, gboolean, OnButtonEvent,
101                       GdkEventButton*);
102
103  // Handles an accelerator being pressed.
104  CHROMEG_CALLBACK_3(TaskManagerGtk, gboolean, OnGtkAccelerator,
105                     GtkAccelGroup*, GObject*, guint, GdkModifierType);
106
107  // Page sorting callback.
108  static gint ComparePage(GtkTreeModel* model, GtkTreeIter* a,
109                          GtkTreeIter* b, gpointer task_manager) {
110    return reinterpret_cast<TaskManagerGtk*>(task_manager)->
111        CompareImpl(model, a, b, IDS_TASK_MANAGER_TASK_COLUMN);
112  }
113
114  // Profile name sorting callback.
115  static gint CompareProfileName(GtkTreeModel* model, GtkTreeIter* a,
116                                 GtkTreeIter* b, gpointer task_manager) {
117    return reinterpret_cast<TaskManagerGtk*>(task_manager)->
118        CompareImpl(model, a, b, IDS_TASK_MANAGER_PROFILE_NAME_COLUMN);
119  }
120
121  // Shared memory sorting callback.
122  static gint CompareSharedMemory(GtkTreeModel* model, GtkTreeIter* a,
123                                  GtkTreeIter* b, gpointer task_manager) {
124    return reinterpret_cast<TaskManagerGtk*>(task_manager)->
125        CompareImpl(model, a, b, IDS_TASK_MANAGER_SHARED_MEM_COLUMN);
126  }
127
128  // Private memory sorting callback.
129  static gint ComparePrivateMemory(GtkTreeModel* model, GtkTreeIter* a,
130                                   GtkTreeIter* b, gpointer task_manager) {
131    return reinterpret_cast<TaskManagerGtk*>(task_manager)->
132        CompareImpl(model, a, b, IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN);
133  }
134
135  // Javascript memory sorting callback.
136  static gint CompareV8Memory(GtkTreeModel* model, GtkTreeIter* a,
137                              GtkTreeIter* b, gpointer task_manager) {
138    return reinterpret_cast<TaskManagerGtk*>(task_manager)->
139        CompareImpl(model, a, b,
140                    IDS_TASK_MANAGER_JAVASCRIPT_MEMORY_ALLOCATED_COLUMN);
141  }
142
143  // CPU sorting callback.
144  static gint CompareCPU(GtkTreeModel* model, GtkTreeIter* a,
145                         GtkTreeIter* b, gpointer task_manager) {
146    return reinterpret_cast<TaskManagerGtk*>(task_manager)->
147        CompareImpl(model, a, b, IDS_TASK_MANAGER_CPU_COLUMN);
148  }
149
150  // Network sorting callback.
151  static gint CompareNetwork(GtkTreeModel* model, GtkTreeIter* a,
152                             GtkTreeIter* b, gpointer task_manager) {
153    return reinterpret_cast<TaskManagerGtk*>(task_manager)->
154        CompareImpl(model, a, b, IDS_TASK_MANAGER_NET_COLUMN);
155  }
156
157  // Process ID sorting callback.
158  static gint CompareProcessID(GtkTreeModel* model, GtkTreeIter* a,
159                               GtkTreeIter* b, gpointer task_manager) {
160    return reinterpret_cast<TaskManagerGtk*>(task_manager)->
161        CompareImpl(model, a, b, IDS_TASK_MANAGER_PROCESS_ID_COLUMN);
162  }
163
164  // WebCore Image Cache sorting callback.
165  static gint CompareWebCoreImageCache(GtkTreeModel* model, GtkTreeIter* a,
166                                       GtkTreeIter* b, gpointer task_manager) {
167    return reinterpret_cast<TaskManagerGtk*>(task_manager)->
168        CompareImpl(model, a, b, IDS_TASK_MANAGER_WEBCORE_IMAGE_CACHE_COLUMN);
169  }
170
171  // WebCore Scripts Cache sorting callback.
172  static gint CompareWebCoreScriptsCache(GtkTreeModel* model, GtkTreeIter* a,
173                                         GtkTreeIter* b,
174                                         gpointer task_manager) {
175    return reinterpret_cast<TaskManagerGtk*>(task_manager)->
176        CompareImpl(model, a, b, IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN);
177  }
178
179  // WebCore CSS Cache sorting callback.
180  static gint CompareWebCoreCssCache(GtkTreeModel* model, GtkTreeIter* a,
181                                     GtkTreeIter* b, gpointer task_manager) {
182    return reinterpret_cast<TaskManagerGtk*>(task_manager)->
183        CompareImpl(model, a, b, IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN);
184  }
185
186  // Video memory sorting callback.
187  static gint CompareVideoMemory(GtkTreeModel* model, GtkTreeIter* a,
188                                 GtkTreeIter* b, gpointer task_manager) {
189    return reinterpret_cast<TaskManagerGtk*>(task_manager)->
190        CompareImpl(model, a, b, IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN);
191  }
192
193  // FPS sorting callback.
194  static gint CompareFPS(GtkTreeModel* model, GtkTreeIter* a,
195                         GtkTreeIter* b, gpointer task_manager) {
196    return reinterpret_cast<TaskManagerGtk*>(task_manager)->
197        CompareImpl(model, a, b, IDS_TASK_MANAGER_FPS_COLUMN);
198  }
199
200  // Sqlite memory sorting callback.
201  static gint CompareSqliteMemoryUsed(GtkTreeModel* model, GtkTreeIter* a,
202                                      GtkTreeIter* b, gpointer task_manager) {
203    return reinterpret_cast<TaskManagerGtk*>(task_manager)->
204        CompareImpl(model, a, b, IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN);
205  }
206
207  // Goats Teleported sorting callback.
208  static gint CompareGoatsTeleported(GtkTreeModel* model, GtkTreeIter* a,
209                                     GtkTreeIter* b, gpointer task_manager) {
210    return reinterpret_cast<TaskManagerGtk*>(task_manager)->
211        CompareImpl(model, a, b, IDS_TASK_MANAGER_GOATS_TELEPORTED_COLUMN);
212  }
213
214  // The task manager.
215  TaskManager* task_manager_;
216
217  // Our model.
218  TaskManagerModel* model_;
219
220  // The task manager dialog window.
221  GtkWidget* dialog_;
222
223  // The treeview that contains the process list.
224  GtkWidget* treeview_;
225
226  // The list of processes.
227  GtkListStore* process_list_;
228  GtkTreeModel* process_list_sort_;
229
230  // The number of processes in |process_list_|.
231  int process_count_;
232
233  // The id of the |dialog_| destroy signal handler.
234  gulong destroy_handler_id_;
235
236  // The context menu controller.
237  scoped_ptr<ContextMenuController> menu_controller_;
238
239  GtkAccelGroup* accel_group_;
240
241  // An open task manager window. There can only be one open at a time. This
242  // is reset to NULL when the window is closed.
243  static TaskManagerGtk* instance_;
244
245  // We edit the selection in the OnSelectionChanged handler, and we use this
246  // variable to prevent ourselves from handling further changes that we
247  // ourselves caused.
248  bool ignore_selection_changed_;
249
250  DISALLOW_COPY_AND_ASSIGN(TaskManagerGtk);
251};
252
253#endif  // CHROME_BROWSER_UI_GTK_TASK_MANAGER_GTK_H_
254