summaryrefslogtreecommitdiff
path: root/settings
diff options
context:
space:
mode:
authorDarkTrick <notebook22312@gmail.com>2020-08-27 18:21:50 +0900
committerSimon Steinbeiss <simon.steinbeiss@elfenbeinturm.at>2020-10-22 23:09:20 +0200
commita502da4f37259451bfe173824c002bc4d806744c (patch)
treef2c6771bc2edfc6fd2f1b83ee9cb41a88b5019c1 /settings
parentc5b48d10059e412426dcf758506534651cf4d53f (diff)
downloadxfce4-session-a502da4f37259451bfe173824c002bc4d806744c.tar.gz
settings: Make 'App Autostart' columns sortable
1) Added: Sort interface to XfaeModel (GTK_TYPE_TREE_SORTABLE) 2) Added: Sort function for each column 3) Renamed: xface_model_sort_items() -> xface_item_sort_default() 4) Fixed GTK bug to not realize column width correctly Closes !12
Diffstat (limited to 'settings')
-rw-r--r--settings/xfae-model.c326
-rw-r--r--settings/xfae-window.c24
2 files changed, 292 insertions, 58 deletions
diff --git a/settings/xfae-model.c b/settings/xfae-model.c
index 25afe5ef..ca8fa1a5 100644
--- a/settings/xfae-model.c
+++ b/settings/xfae-model.c
@@ -38,42 +38,69 @@ typedef struct _XfaeItem XfaeItem;
-static void xfae_model_tree_model_init (GtkTreeModelIface *iface);
-static void xfae_model_finalize (GObject *object);
-static GtkTreeModelFlags xfae_model_get_flags (GtkTreeModel *tree_model);
-static gint xfae_model_get_n_columns (GtkTreeModel *tree_model);
-static GType xfae_model_get_column_type (GtkTreeModel *tree_model,
- gint index_);
-static gboolean xfae_model_get_iter (GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- GtkTreePath *path);
-static GtkTreePath *xfae_model_get_path (GtkTreeModel *tree_model,
- GtkTreeIter *iter);
-static void xfae_model_get_value (GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- gint column,
- GValue *value);
-static gboolean xfae_model_iter_next (GtkTreeModel *tree_model,
- GtkTreeIter *iter);
-static gboolean xfae_model_iter_children (GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- GtkTreeIter *parent);
-static gboolean xfae_model_iter_has_child (GtkTreeModel *tree_model,
- GtkTreeIter *iter);
-static gint xfae_model_iter_n_children (GtkTreeModel *tree_model,
- GtkTreeIter *iter);
-static gboolean xfae_model_iter_nth_child (GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- GtkTreeIter *parent,
- gint n);
-static gboolean xfae_model_iter_parent (GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- GtkTreeIter *child);
-static gint xfae_model_sort_items (gconstpointer a,
- gconstpointer b);
+static void xfae_model_tree_model_init (GtkTreeModelIface *iface);
+static void xfae_model_tree_sortable_init (GtkTreeSortableIface *iface);
+static void xfae_model_finalize (GObject *object);
+static GtkTreeModelFlags xfae_model_get_flags (GtkTreeModel *tree_model);
+static gint xfae_model_get_n_columns (GtkTreeModel *tree_model);
+static GType xfae_model_get_column_type (GtkTreeModel *tree_model,
+ gint index_);
+static gboolean xfae_model_get_iter (GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ GtkTreePath *path);
+static GtkTreePath *xfae_model_get_path (GtkTreeModel *tree_model,
+ GtkTreeIter *iter);
+static void xfae_model_get_value (GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ gint column,
+ GValue *value);
+static gboolean xfae_model_iter_next (GtkTreeModel *tree_model,
+ GtkTreeIter *iter);
+static gboolean xfae_model_iter_children (GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ GtkTreeIter *parent);
+static gboolean xfae_model_iter_has_child (GtkTreeModel *tree_model,
+ GtkTreeIter *iter);
+static gint xfae_model_iter_n_children (GtkTreeModel *tree_model,
+ GtkTreeIter *iter);
+static gboolean xfae_model_iter_nth_child (GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ GtkTreeIter *parent,
+ gint n);
+static gboolean xfae_model_iter_parent (GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ GtkTreeIter *child);
+static gboolean xfae_model_get_sort_column_id (GtkTreeSortable *sortable,
+ int *sort_column_id,
+ GtkSortType *sort_order);
+static void xfae_model_set_sort_column_id (GtkTreeSortable *sortable,
+ int sort_column_id,
+ GtkSortType order);
+static void xfae_model_set_sort_func (GtkTreeSortable *sortable,
+ int sort_column_id,
+ GtkTreeIterCompareFunc func,
+ gpointer data,
+ GDestroyNotify destroy);
+static void xfae_model_set_default_sort_func (GtkTreeSortable *sortable,
+ GtkTreeIterCompareFunc func,
+ gpointer data,
+ GDestroyNotify destroy);
+static gboolean xfae_model_has_default_sort_func (GtkTreeSortable *sortable);
+static void xfae_model_sort (XfaeModel *model);
+
+
static XfaeItem *xfae_item_new (const gchar *relpath);
static void xfae_item_free (XfaeItem *item);
static gboolean xfae_item_is_removable (XfaeItem *item);
+static gboolean xfae_item_is_enabled (const XfaeItem *item);
+static gint xfae_item_sort_default (gconstpointer a,
+ gconstpointer b);
+static gint xfae_item_sort_name (gconstpointer a,
+ gconstpointer b);
+static gint xfae_item_sort_enabled (gconstpointer a,
+ gconstpointer b);
+static gint xfae_item_sort_hook (gconstpointer a,
+ gconstpointer b);
GType
xfsm_run_hook_get_type (void)
@@ -108,8 +135,10 @@ struct _XfaeModel
{
GObject __parent__;
- gint stamp;
- GList *items;
+ gint stamp;
+ GList *items;
+ int sort_column_id;
+ GtkSortType sort_order;
};
struct _XfaeItem
@@ -132,7 +161,9 @@ G_DEFINE_TYPE_WITH_CODE (XfaeModel,
xfae_model,
G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,
- xfae_model_tree_model_init));
+ xfae_model_tree_model_init);
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_SORTABLE,
+ xfae_model_tree_sortable_init));
@@ -154,6 +185,9 @@ xfae_model_init (XfaeModel *model)
gchar **files;
guint n;
+ model->sort_column_id = GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID;
+ model->sort_order = GTK_SORT_DESCENDING;
+
model->stamp = g_random_int ();
files = xfce_resource_match (XFCE_RESOURCE_CONFIG, "autostart/*.desktop", TRUE);
@@ -165,7 +199,132 @@ xfae_model_init (XfaeModel *model)
}
g_strfreev (files);
- model->items = g_list_sort (model->items, xfae_model_sort_items);
+ model->items = g_list_sort (model->items, xfae_item_sort_default);
+}
+
+
+
+static gboolean
+xfae_model_get_sort_column_id (GtkTreeSortable *sortable,
+ int *sort_column_id,
+ GtkSortType *sort_order)
+{
+ XfaeModel * model = XFAE_MODEL (sortable);
+ if (sort_column_id)
+ *sort_column_id = model->sort_column_id;
+ if (sort_order)
+ *sort_order = model->sort_order;
+
+ if (model->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID ||
+ model->sort_column_id == GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID)
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+
+static void
+xfae_model_set_sort_column_id (GtkTreeSortable *sortable,
+ int sort_column_id,
+ GtkSortType order)
+{
+ XfaeModel *model = XFAE_MODEL (sortable);
+
+ if ((model->sort_column_id == sort_column_id) &&
+ (model->sort_order == order))
+ return;
+
+ if ((GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID == sort_column_id) ||
+ (GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID == sort_column_id))
+ {
+ // This path is probably never hit
+ return;
+ }
+
+ model->sort_column_id = sort_column_id;
+ model->sort_order = order;
+
+ xfae_model_sort (model);
+
+ gtk_tree_sortable_sort_column_changed (sortable);
+}
+
+
+
+static void
+xfae_model_set_sort_func (GtkTreeSortable *sortable,
+ int sort_column_id,
+ GtkTreeIterCompareFunc func,
+ gpointer data,
+ GDestroyNotify destroy)
+{
+ g_printerr ("xfae_model_set_sort_func not supported\n");
+ return;
+}
+
+
+
+static void
+xfae_model_set_default_sort_func (GtkTreeSortable *sortable,
+ GtkTreeIterCompareFunc func,
+ gpointer data,
+ GDestroyNotify destroy)
+{
+ g_printerr ("xfae_model_set_default_sort_func not supported\n");
+ return;
+}
+
+
+
+static gboolean
+xfae_model_has_default_sort_func (GtkTreeSortable *sortable)
+{
+ return FALSE;
+}
+
+
+
+static void
+xfae_model_sort (XfaeModel *model)
+{
+ // sort ASC
+ switch (model->sort_column_id)
+ {
+ case XFAE_MODEL_COLUMN_NAME:
+ model->items = g_list_sort (model->items, xfae_item_sort_name);
+ break;
+ case XFAE_MODEL_COLUMN_ENABLED:
+ model->items = g_list_sort (model->items, xfae_item_sort_enabled);
+ break;
+ case XFAE_MODEL_RUN_HOOK:
+ model->items = g_list_sort (model->items, xfae_item_sort_hook);
+ break;
+ default:
+ return;
+ }
+
+ // If necessary, reverse so we have DESC.
+ // This implementation is inefficient, but this is only rarely called.
+ if (GTK_SORT_DESCENDING == model->sort_order)
+ {
+ model->items = g_list_reverse (model->items);
+ }
+
+}
+
+
+
+static void
+xfae_model_tree_sortable_init (GtkTreeSortableIface *iface)
+{
+ iface->get_sort_column_id = xfae_model_get_sort_column_id;
+ iface->set_sort_column_id = xfae_model_set_sort_column_id;
+ iface->set_sort_func = xfae_model_set_sort_func;
+ iface->set_default_sort_func = xfae_model_set_default_sort_func;
+ iface->has_default_sort_func = xfae_model_has_default_sort_func;
}
@@ -360,11 +519,7 @@ xfae_model_get_value (GtkTreeModel *tree_model,
case XFAE_MODEL_COLUMN_ENABLED:
g_value_init (value, G_TYPE_BOOLEAN);
-
- if (item->show_in_xfce)
- g_value_set_boolean (value, !item->hidden);
- else
- g_value_set_boolean (value, !item->hidden && item->show_in_override);
+ g_value_set_boolean (value, xfae_item_is_enabled (item));
break;
case XFAE_MODEL_COLUMN_REMOVABLE:
@@ -483,22 +638,6 @@ xfae_model_iter_parent (GtkTreeModel *tree_model,
-static gint
-xfae_model_sort_items (gconstpointer a,
- gconstpointer b)
-{
- const XfaeItem *item_a = a;
- const XfaeItem *item_b = b;
-
- /* sort non-xfce items below */
- if (item_a->show_in_xfce != item_b->show_in_xfce)
- return item_a->show_in_xfce ? -1 : 1;
-
- return g_utf8_collate (item_a->name, item_b->name);
-}
-
-
-
static XfaeItem*
xfae_item_new (const gchar *relpath)
{
@@ -691,6 +830,77 @@ xfae_item_remove (XfaeItem *item,
/**
+ * Essentially determines, if the "toggle" value in the treeview
+ * is true or false
+ **/
+static gboolean
+xfae_item_is_enabled (const XfaeItem * item)
+{
+ if (item->show_in_xfce)
+ return !item->hidden;
+
+ return !item->hidden && item->show_in_override;
+}
+
+
+
+/**
+ * Initial sorting given, when list is created first
+ **/
+static gint
+xfae_item_sort_default (gconstpointer a,
+ gconstpointer b)
+{
+ const XfaeItem *item_a = a;
+ const XfaeItem *item_b = b;
+
+ /* sort non-xfce items below */
+ if (item_a->show_in_xfce != item_b->show_in_xfce)
+ return item_a->show_in_xfce ? -1 : 1;
+
+ return g_utf8_collate (item_a->name, item_b->name);
+}
+
+
+
+static gint
+xfae_item_sort_name (gconstpointer a,
+ gconstpointer b)
+{
+ const XfaeItem *item_a = a;
+ const XfaeItem *item_b = b;
+
+ return g_utf8_collate (item_a->name, item_b->name);
+}
+
+
+
+static gint
+xfae_item_sort_enabled (gconstpointer a,
+ gconstpointer b)
+{
+ const XfaeItem *item_a = a;
+ const XfaeItem *item_b = b;
+
+ /* Ordering: ASC = true,false; DESC = false,true */
+ return (xfae_item_is_enabled (item_b) - xfae_item_is_enabled (item_a));
+}
+
+
+
+static gint
+xfae_item_sort_hook (gconstpointer a,
+ gconstpointer b)
+{
+ const XfaeItem *item_a = a;
+ const XfaeItem *item_b = b;
+
+ return (item_a->run_hook - item_b->run_hook);
+}
+
+
+
+/**
* xfae_model_new:
*
* Allocates a new #XfaeModel instance.
diff --git a/settings/xfae-window.c b/settings/xfae-window.c
index a4dc0edc..a9ebd376 100644
--- a/settings/xfae-window.c
+++ b/settings/xfae-window.c
@@ -41,6 +41,8 @@ static void xfae_window_item_toggled (XfaeWindow
gchar *path_string);
static void xfae_window_selection_changed (GtkTreeSelection *selection,
GtkWidget *remove_button);
+static void xfae_window_correct_treeview_column_size (GtkWidget *treeview,
+ gpointer user_data);
static GtkTreeModel* xfae_window_create_run_hooks_combo_model (void);
@@ -105,6 +107,15 @@ run_hook_changed (GtkCellRenderer *render,
static void
+xfae_window_correct_treeview_column_size (GtkWidget *treeview,
+ gpointer user_data)
+{
+ gtk_tree_view_columns_autosize (GTK_TREE_VIEW (treeview));
+}
+
+
+
+static void
xfae_window_init (XfaeWindow *window)
{
GtkTreeViewColumn *column;
@@ -139,6 +150,10 @@ xfae_window_init (XfaeWindow *window)
NULL);
g_signal_connect (G_OBJECT (window->treeview), "button-press-event",
G_CALLBACK (xfae_window_button_press_event), window);
+ // fix buggy sizing behavior of gtk
+ g_signal_connect (G_OBJECT (window->treeview), "realize",
+ G_CALLBACK(xfae_window_correct_treeview_column_size), NULL);
+
gtk_container_add (GTK_CONTAINER (swin), window->treeview);
gtk_widget_show (window->treeview);
@@ -151,6 +166,7 @@ xfae_window_init (XfaeWindow *window)
window->selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window->treeview));
gtk_tree_selection_set_mode (window->selection, GTK_SELECTION_SINGLE);
+ // Column "toggled"
column = g_object_new (GTK_TYPE_TREE_VIEW_COLUMN,
"reorderable", FALSE,
"resizable", FALSE,
@@ -163,7 +179,9 @@ xfae_window_init (XfaeWindow *window)
"active", XFAE_MODEL_COLUMN_ENABLED,
NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (window->treeview), column);
+ gtk_tree_view_column_set_sort_column_id(column, XFAE_MODEL_COLUMN_ENABLED);
+ // Column "Program"
column = g_object_new (GTK_TYPE_TREE_VIEW_COLUMN,
"reorderable", FALSE,
"resizable", FALSE,
@@ -184,8 +202,12 @@ xfae_window_init (XfaeWindow *window)
"markup", XFAE_MODEL_COLUMN_NAME,
NULL);
+ gtk_tree_view_column_set_sort_column_id(column, XFAE_MODEL_COLUMN_NAME);
+
gtk_tree_view_append_column (GTK_TREE_VIEW (window->treeview), column);
+
+ // Column "Trigger"
column = g_object_new (GTK_TYPE_TREE_VIEW_COLUMN,
"reorderable", FALSE,
"resizable", FALSE,
@@ -207,6 +229,8 @@ xfae_window_init (XfaeWindow *window)
"text", XFAE_MODEL_RUN_HOOK,
NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (window->treeview), column);
+ gtk_tree_view_column_set_sort_column_id(column, XFAE_MODEL_RUN_HOOK);
+
g_object_unref (model);
bbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);