diff --git a/src/process-tree-view.c b/src/process-tree-view.c index 7fb7374..736c12a 100644 --- a/src/process-tree-view.c +++ b/src/process-tree-view.c @@ -21,6 +21,21 @@ +/* Static positions of columns in tree view */ +// TODO get the columns reorderable (more tree view hell) +enum +{ + COLUMN_COMMAND = 0, + COLUMN_PID, + COLUMN_PPID, + COLUMN_STATE, + COLUMN_VSZ, + COLUMN_RSS, + COLUMN_UID, + COLUMN_CPU, + COLUMN_PRIORITY, +}; + typedef struct _XtmProcessTreeViewClass XtmProcessTreeViewClass; struct _XtmProcessTreeViewClass { @@ -31,20 +46,21 @@ struct _XtmProcessTreeView GtkTreeView parent; /**/ GtkListStore * model; + GtkTreeModel * model_filter; + GtkTreeViewColumn * sort_column; XtmSettings * settings; }; G_DEFINE_TYPE (XtmProcessTreeView, xtm_process_tree_view, GTK_TYPE_TREE_VIEW) static gboolean treeview_clicked (XtmProcessTreeView *treeview, GdkEventButton *event); +static void column_clicked (GtkTreeViewColumn *column, XtmProcessTreeView *treeview); static void settings_changed (GObject *object, GParamSpec *pspec, XtmProcessTreeView *treeview); -static int sort_by_string (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data); static void xtm_process_tree_view_class_init (XtmProcessTreeViewClass *klass) { - GObjectClass *class = G_OBJECT_CLASS (klass); xtm_process_tree_view_parent_class = g_type_class_peek_parent (klass); } @@ -54,18 +70,20 @@ xtm_process_tree_view_init (XtmProcessTreeView *treeview) GtkCellRenderer *cell_text, *cell_right_aligned, *cell_cmdline; GtkTreeViewColumn *column; gboolean visible; - guint sort_column_id; - GtkSortType sort_type; treeview->settings = xtm_settings_get_default (); - g_object_get (treeview->settings, "sort-column-id", &sort_column_id, "sort-type", &sort_type, NULL); g_signal_connect (treeview->settings, "notify", G_CALLBACK (settings_changed), treeview); + /* Create tree view model */ treeview->model = gtk_list_store_new (XTM_PTV_N_COLUMNS, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_UINT64, G_TYPE_STRING, G_TYPE_UINT64, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_FLOAT, G_TYPE_STRING, G_TYPE_INT); - g_object_set (treeview, "search-column", XTM_PTV_COLUMN_COMMAND, "model", treeview->model, NULL); + treeview->model_filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (treeview->model), NULL); + //gtk_tree_model_filter_set_visible_func (treeview->model_filter, ...); + g_object_set (treeview, "search-column", XTM_PTV_COLUMN_COMMAND, "model", treeview->model_filter, NULL); + + /* Create cell renderer for tree view columns */ cell_text = gtk_cell_renderer_text_new(); cell_right_aligned = gtk_cell_renderer_text_new (); @@ -74,61 +92,95 @@ xtm_process_tree_view_init (XtmProcessTreeView *treeview) cell_cmdline = gtk_cell_renderer_text_new (); g_object_set (cell_cmdline, "ellipsize", PANGO_ELLIPSIZE_END, NULL); + /* Create tree view columns */ +#define COLUMN_PROPERTIES "expand", TRUE, "clickable", TRUE, "reorderable", FALSE, "resizable", TRUE, "visible", TRUE column = gtk_tree_view_column_new_with_attributes (_("Task"), cell_cmdline, "text", XTM_PTV_COLUMN_COMMAND, NULL); - g_object_set (column, "expand", TRUE, "reorderable", FALSE, "resizable", TRUE, "visible", TRUE, NULL); - gtk_tree_view_column_set_sort_column_id (GTK_TREE_VIEW_COLUMN (column), XTM_PTV_COLUMN_COMMAND); + g_object_set (column, COLUMN_PROPERTIES, NULL); + g_object_set_data (G_OBJECT (column), "sort-column-id", GINT_TO_POINTER (XTM_PTV_COLUMN_COMMAND)); + g_object_set_data (G_OBJECT (column), "column-id", GINT_TO_POINTER (COLUMN_COMMAND)); + g_signal_connect (column, "clicked", G_CALLBACK (column_clicked), treeview); gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); +#undef COLUMN_PROPERTIES +#define COLUMN_PROPERTIES "expand", FALSE, "clickable", TRUE, "reorderable", FALSE, "resizable", TRUE, "visible", visible g_object_get (treeview->settings, "column-pid", &visible, NULL); column = gtk_tree_view_column_new_with_attributes (_("PID"), cell_right_aligned, "text", XTM_PTV_COLUMN_PID, NULL); - g_object_set (column, "expand", FALSE, "reorderable", FALSE, "resizable", TRUE, "visible", visible, NULL); - gtk_tree_view_column_set_sort_column_id (GTK_TREE_VIEW_COLUMN (column), XTM_PTV_COLUMN_PID); + g_object_set (column, COLUMN_PROPERTIES, NULL); + g_object_set_data (G_OBJECT (column), "sort-column-id", GINT_TO_POINTER (XTM_PTV_COLUMN_PID)); + g_object_set_data (G_OBJECT (column), "column-id", GINT_TO_POINTER (COLUMN_PID)); + g_signal_connect (column, "clicked", G_CALLBACK (column_clicked), treeview); gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); g_object_get (treeview->settings, "column-ppid", &visible, NULL); column = gtk_tree_view_column_new_with_attributes (_("PPID"), cell_right_aligned, "text", XTM_PTV_COLUMN_PPID, NULL); - g_object_set (column, "expand", FALSE, "reorderable", FALSE, "resizable", TRUE, "visible", visible, NULL); - gtk_tree_view_column_set_sort_column_id (GTK_TREE_VIEW_COLUMN (column), XTM_PTV_COLUMN_PPID); + g_object_set (column, COLUMN_PROPERTIES, NULL); + g_object_set_data (G_OBJECT (column), "sort-column-id", GINT_TO_POINTER (XTM_PTV_COLUMN_PPID)); + g_object_set_data (G_OBJECT (column), "column-id", GINT_TO_POINTER (COLUMN_PPID)); + g_signal_connect (column, "clicked", G_CALLBACK (column_clicked), treeview); gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); g_object_get (treeview->settings, "column-state", &visible, NULL); column = gtk_tree_view_column_new_with_attributes (_("State"), cell_text, "text", XTM_PTV_COLUMN_STATE, NULL); - g_object_set (column, "expand", FALSE, "reorderable", FALSE, "resizable", TRUE, "visible", visible, NULL); - gtk_tree_view_column_set_sort_column_id (GTK_TREE_VIEW_COLUMN (column), XTM_PTV_COLUMN_STATE); + gtk_tree_view_column_set_min_width (GTK_TREE_VIEW_COLUMN (column), 32); + g_object_set (column, COLUMN_PROPERTIES, NULL); + g_object_set_data (G_OBJECT (column), "sort-column-id", GINT_TO_POINTER (XTM_PTV_COLUMN_STATE)); + g_object_set_data (G_OBJECT (column), "column-id", GINT_TO_POINTER (COLUMN_STATE)); + g_signal_connect (column, "clicked", G_CALLBACK (column_clicked), treeview); gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); g_object_get (treeview->settings, "column-vsz", &visible, NULL); column = gtk_tree_view_column_new_with_attributes (_("VSZ"), cell_right_aligned, "text", XTM_PTV_COLUMN_VSZ_STR, NULL); - g_object_set (column, "expand", FALSE, "reorderable", FALSE, "resizable", TRUE, "visible", visible, NULL); - gtk_tree_view_column_set_sort_column_id (GTK_TREE_VIEW_COLUMN (column), XTM_PTV_COLUMN_VSZ); + g_object_set (column, COLUMN_PROPERTIES, NULL); + g_object_set_data (G_OBJECT (column), "sort-column-id", GINT_TO_POINTER (XTM_PTV_COLUMN_VSZ)); + g_object_set_data (G_OBJECT (column), "column-id", GINT_TO_POINTER (COLUMN_VSZ)); + g_signal_connect (column, "clicked", G_CALLBACK (column_clicked), treeview); gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); g_object_get (treeview->settings, "column-rss", &visible, NULL); column = gtk_tree_view_column_new_with_attributes (_("RSS"), cell_right_aligned, "text", XTM_PTV_COLUMN_RSS_STR, NULL); - g_object_set (column, "expand", FALSE, "reorderable", FALSE, "resizable", TRUE, "visible", visible, NULL); - gtk_tree_view_column_set_sort_column_id (GTK_TREE_VIEW_COLUMN (column), XTM_PTV_COLUMN_RSS); + g_object_set (column, COLUMN_PROPERTIES, NULL); + g_object_set_data (G_OBJECT (column), "sort-column-id", GINT_TO_POINTER (XTM_PTV_COLUMN_RSS)); + g_object_set_data (G_OBJECT (column), "column-id", GINT_TO_POINTER (COLUMN_RSS)); + g_signal_connect (column, "clicked", G_CALLBACK (column_clicked), treeview); gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); g_object_get (treeview->settings, "column-uid", &visible, NULL); column = gtk_tree_view_column_new_with_attributes (_("UID"), cell_text, "text", XTM_PTV_COLUMN_UID, NULL); - g_object_set (column, "expand", FALSE, "reorderable", FALSE, "resizable", TRUE, "visible", visible, NULL); - gtk_tree_view_column_set_sort_column_id (GTK_TREE_VIEW_COLUMN (column), XTM_PTV_COLUMN_UID); + g_object_set (column, COLUMN_PROPERTIES, NULL); + g_object_set_data (G_OBJECT (column), "sort-column-id", GINT_TO_POINTER (XTM_PTV_COLUMN_UID)); + g_object_set_data (G_OBJECT (column), "column-id", GINT_TO_POINTER (COLUMN_UID)); + g_signal_connect (column, "clicked", G_CALLBACK (column_clicked), treeview); gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); g_object_get (treeview->settings, "column-cpu", &visible, NULL); column = gtk_tree_view_column_new_with_attributes (_("CPU"), cell_right_aligned, "text", XTM_PTV_COLUMN_CPU_STR, NULL); - g_object_set (column, "expand", FALSE, "reorderable", FALSE, "resizable", TRUE, "visible", visible, NULL); - gtk_tree_view_column_set_sort_column_id (GTK_TREE_VIEW_COLUMN (column), XTM_PTV_COLUMN_CPU); + g_object_set (column, COLUMN_PROPERTIES, NULL); + g_object_set_data (G_OBJECT (column), "sort-column-id", GINT_TO_POINTER (XTM_PTV_COLUMN_CPU)); + g_object_set_data (G_OBJECT (column), "column-id", GINT_TO_POINTER (COLUMN_CPU)); + g_signal_connect (column, "clicked", G_CALLBACK (column_clicked), treeview); gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); g_object_get (treeview->settings, "column-priority", &visible, NULL); /* TRANSLATORS: “Prio.” is short for Priority, it appears in the tree view header. */ column = gtk_tree_view_column_new_with_attributes (_("Prio."), cell_right_aligned, "text", XTM_PTV_COLUMN_PRIORITY, NULL); - g_object_set (column, "expand", FALSE, "reorderable", FALSE, "resizable", TRUE, "visible", visible, NULL); - gtk_tree_view_column_set_sort_column_id (GTK_TREE_VIEW_COLUMN (column), XTM_PTV_COLUMN_PRIORITY); + g_object_set (column, COLUMN_PROPERTIES, NULL); + g_object_set_data (G_OBJECT (column), "sort-column-id", GINT_TO_POINTER (XTM_PTV_COLUMN_PRIORITY)); + g_object_set_data (G_OBJECT (column), "column-id", GINT_TO_POINTER (COLUMN_PRIORITY)); + g_signal_connect (column, "clicked", G_CALLBACK (column_clicked), treeview); gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); - gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (treeview->model), sort_column_id, sort_type); + /* Set initial sort column */ + { + guint sort_column_id; + GtkSortType sort_type; + + g_object_get (treeview->settings, "sort-column-id", &sort_column_id, "sort-type", &sort_type, NULL); + treeview->sort_column = gtk_tree_view_get_column (GTK_TREE_VIEW (treeview), sort_column_id); + gtk_tree_view_column_set_sort_indicator (treeview->sort_column, TRUE); + gtk_tree_view_column_set_sort_order (treeview->sort_column, sort_type); + sort_column_id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (treeview->sort_column), "sort-column-id")); + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (treeview->model), sort_column_id, sort_type); + } g_signal_connect (treeview, "button-press-event", G_CALLBACK (treeview_clicked), NULL); } @@ -264,7 +316,7 @@ treeview_clicked (XtmProcessTreeView *treeview, GdkEventButton *event) gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (treeview), (gint)event->x, (gint)event->y, &path, NULL, NULL, NULL); if (path == NULL) - return; + return FALSE; gtk_tree_model_get_iter (model, &iter, path); gtk_tree_model_get (model, &iter, XTM_PTV_COLUMN_PID, &pid, -1); @@ -282,6 +334,38 @@ treeview_clicked (XtmProcessTreeView *treeview, GdkEventButton *event) return TRUE; } +static void +column_clicked (GtkTreeViewColumn *column, XtmProcessTreeView *treeview) +{ + gint sort_column_id; + GtkSortType sort_type; + + gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (treeview->model), &sort_column_id, &sort_type); +#if DEBUG + g_debug ("Last sort column %d; sort type: %d", sort_column_id, sort_type); +#endif + + if (treeview->sort_column != column) + { + gtk_tree_view_column_set_sort_indicator (treeview->sort_column, FALSE); + gtk_tree_view_column_set_sort_indicator (column, TRUE); + sort_column_id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (column), "sort-column-id")); + sort_type = GTK_SORT_ASCENDING; + } + else + { + sort_type = (sort_type == GTK_SORT_ASCENDING) ? GTK_SORT_DESCENDING : GTK_SORT_ASCENDING; + } + +#if DEBUG + g_debug ("New sort column %d; sort type: %d", sort_column_id, sort_type); +#endif + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (treeview->model), sort_column_id, sort_type); + gtk_tree_view_column_set_sort_order (column, sort_type); + + treeview->sort_column = column; +} + static void settings_changed (GObject *object, GParamSpec *pspec, XtmProcessTreeView *treeview) { @@ -291,26 +375,26 @@ settings_changed (GObject *object, GParamSpec *pspec, XtmProcessTreeView *treevi gushort column_id; if (!g_strcmp0 (pspec->name, "column-uid")) - column_id = XTM_PTV_COLUMN_UID; + column_id = COLUMN_UID; else if (!g_strcmp0 (pspec->name, "column-pid")) - column_id = XTM_PTV_COLUMN_PID; + column_id = COLUMN_PID; else if (!g_strcmp0 (pspec->name, "column-ppid")) - column_id = XTM_PTV_COLUMN_PPID; + column_id = COLUMN_PPID; else if (!g_strcmp0 (pspec->name, "column-state")) - column_id = XTM_PTV_COLUMN_STATE; + column_id = COLUMN_STATE; else if (!g_strcmp0 (pspec->name, "column-vsz")) - column_id = XTM_PTV_COLUMN_VSZ_STR; + column_id = COLUMN_VSZ; else if (!g_strcmp0 (pspec->name, "column-rss")) - column_id = XTM_PTV_COLUMN_RSS_STR; + column_id = COLUMN_RSS; else if (!g_strcmp0 (pspec->name, "column-cpu")) - column_id = XTM_PTV_COLUMN_CPU_STR; + column_id = COLUMN_CPU; else if (!g_strcmp0 (pspec->name, "column-priority")) - column_id = XTM_PTV_COLUMN_PRIORITY; + column_id = COLUMN_PRIORITY; g_object_get (object, pspec->name, &visible, NULL); gtk_tree_view_column_set_visible (gtk_tree_view_get_column (GTK_TREE_VIEW (treeview), column_id), visible); } - else if (!g_strcmp0 (pspec->name, "show-system-processes")) + else if (!g_strcmp0 (pspec->name, "show-all-processes")) { gboolean visible; g_object_get (object, pspec->name, &visible, NULL); @@ -326,3 +410,10 @@ xtm_process_tree_view_new () return g_object_new (XTM_TYPE_PROCESS_TREE_VIEW, NULL); } +void +xtm_process_tree_view_get_sort_column_id (XtmProcessTreeView *treeview, gint *sort_column_id, GtkSortType *sort_type) +{ + *sort_column_id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (treeview->sort_column), "column-id")); + *sort_type = gtk_tree_view_column_get_sort_order (treeview->sort_column); +} + diff --git a/src/process-tree-view.h b/src/process-tree-view.h index 481c552..2619142 100644 --- a/src/process-tree-view.h +++ b/src/process-tree-view.h @@ -44,5 +44,6 @@ typedef struct _XtmProcessTreeView XtmProcessTreeView; GType xtm_process_tree_view_get_type (void); GtkWidget * xtm_process_tree_view_new (); +void xtm_process_tree_view_get_sort_column_id (XtmProcessTreeView *treeview, gint *sort_column_id, GtkSortType *sort_type); #endif /* !PROCESS_TREE_VIEW_H */ diff --git a/src/process-window.c b/src/process-window.c index 38aa419..307a135 100644 --- a/src/process-window.c +++ b/src/process-window.c @@ -137,8 +137,7 @@ xtm_process_window_finalize (GObject *object) GtkSortType sort_type; gtk_window_get_size (GTK_WINDOW (priv->window), &width, &height); - gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview))), - &sort_column_id, &sort_type); + xtm_process_tree_view_get_sort_column_id (XTM_PROCESS_TREE_VIEW (priv->treeview), &sort_column_id, &sort_type); g_object_set (priv->settings, "window-width", width, "window-height", height, "sort-column-id", sort_column_id, "sort-type", sort_type, NULL); @@ -269,7 +268,7 @@ show_menu_preferences (XtmProcessWindow *window) } menu = gtk_menu_new (); - menu_preferences_append_item (GTK_MENU (menu), _("Show system processes"), "show-system-processes", window->priv->settings); + menu_preferences_append_item (GTK_MENU (menu), _("Show all processes"), "show-all-processes", window->priv->settings); mi = gtk_separator_menu_item_new (); gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi); @@ -366,7 +365,7 @@ xtm_process_window_get_model (XtmProcessWindow *window) { g_return_val_if_fail (G_LIKELY (XTM_IS_PROCESS_WINDOW (window)), NULL); g_return_val_if_fail (G_LIKELY (GTK_IS_TREE_VIEW (window->priv->treeview)), NULL); - return gtk_tree_view_get_model (GTK_TREE_VIEW (window->priv->treeview)); + return gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (gtk_tree_view_get_model (GTK_TREE_VIEW (window->priv->treeview)))); } void diff --git a/src/settings.c b/src/settings.c index 8591443..0a0aa8f 100644 --- a/src/settings.c +++ b/src/settings.c @@ -23,7 +23,7 @@ enum { - PROP_SHOW_SYSTEM_PROCESSES = 1, + PROP_SHOW_ALL_PROCESSES = 1, PROP_COLUMN_UID, PROP_COLUMN_PID, PROP_COLUMN_PPID, @@ -67,8 +67,8 @@ xtm_settings_class_init (XtmSettingsClass *klass) xtm_settings_parent_class = g_type_class_peek_parent (klass); class->get_property = xtm_settings_get_property; class->set_property = xtm_settings_set_property; - g_object_class_install_property (class, PROP_SHOW_SYSTEM_PROCESSES, - g_param_spec_boolean ("show-system-processes", "ShowSystemProcesses", "Show system processes", FALSE, G_PARAM_READWRITE)); + g_object_class_install_property (class, PROP_SHOW_ALL_PROCESSES, + g_param_spec_boolean ("show-all-processes", "ShowAllProcesses", "Show all processes", FALSE, G_PARAM_READWRITE)); g_object_class_install_property (class, PROP_COLUMN_UID, g_param_spec_boolean ("column-uid", "ColumnUID", "Show column UID", FALSE, G_PARAM_READWRITE)); g_object_class_install_property (class, PROP_COLUMN_PID,