Commit c9ff53e5 authored by Stefano Facchini's avatar Stefano Facchini

Make a GsmTreeView widget out of a few scattered functions

parent 9776a209
......@@ -37,7 +37,8 @@ gnome_system_monitor_cpp_files = \
gnome_system_monitor_c_files = \
e_date.c \
gsm_color_button.c
gsm_color_button.c \
treeview.c
gnome_system_monitor_h_files = \
$(gnome_system_monitor_cpp_files:.cpp=.h) \
......
......@@ -15,7 +15,6 @@
#include "settings-keys.h"
#include "argv.h"
#include "util.h"
#include "cgroups.h"
#include "lsof.h"
#include "disks.h"
......@@ -249,172 +248,6 @@ void GsmApplication::on_activate()
gtk_window_present (GTK_WINDOW (main_window));
}
static void
cb_header_menu_position_function (GtkMenu* menu, gint *x, gint *y, gboolean *push_in, gpointer data)
{
GdkEventButton* event = (GdkEventButton *) data;
gint wx, wy, ww, wh;
gdk_window_get_geometry(event->window, &wx, &wy, &ww, &wh);
gdk_window_get_origin(event->window, &wx, &wy);
*x = wx + event->x;
*y = wy + wh;
*push_in = TRUE;
}
static gboolean
cb_column_header_clicked (GtkTreeViewColumn* column, GdkEvent* event, gpointer data)
{
GtkMenu *menu = (GtkMenu *) data;
if (event->button.button == GDK_BUTTON_SECONDARY) {
gtk_menu_popup(GTK_MENU(menu), NULL, NULL, cb_header_menu_position_function, &(event->button), event->button.button, event->button.time);
return TRUE;
}
return FALSE;
}
gboolean
procman_get_tree_state (GSettings *settings, GtkWidget *tree, const gchar *child_schema)
{
GtkTreeModel *model;
GList *columns, *it;
gint sort_col;
GtkSortType order;
GtkWidget *header_menu;
g_assert(tree);
g_assert(child_schema);
GSettings *pt_settings = g_settings_get_child (settings, child_schema);
model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree));
sort_col = g_settings_get_int (pt_settings, "sort-col");
order = static_cast<GtkSortType>(g_settings_get_int (pt_settings, "sort-order"));
if (sort_col != -1)
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model),
sort_col,
order);
columns = gtk_tree_view_get_columns (GTK_TREE_VIEW (tree));
if(!g_strcmp0(child_schema, "proctree") ||
!g_strcmp0(child_schema, "disktreenew"))
{
header_menu = gtk_menu_new();
for(it = columns; it; it = it->next)
{
GtkTreeViewColumn *column;
int id;
const gchar *title;
GtkWidget* column_item;
GtkWidget* button;
column = static_cast<GtkTreeViewColumn*>(it->data);
id = gtk_tree_view_column_get_sort_column_id (column);
if ((id == COL_CGROUP) && (!cgroups_enabled()))
continue;
if ((id == COL_UNIT ||
id == COL_SESSION ||
id == COL_SEAT ||
id == COL_OWNER)
#ifdef HAVE_SYSTEMD
&& !LOGIND_RUNNING()
#endif
)
continue;
// set the states for the columns visibility menu available by header right click
title = gtk_tree_view_column_get_title (column);
if (!title)
title = _("Icon");
button = gtk_tree_view_column_get_button(column);
g_signal_connect(G_OBJECT(button), "button_press_event", G_CALLBACK(cb_column_header_clicked), header_menu);
column_item = gtk_check_menu_item_new_with_label(title);
g_object_bind_property (column, "visible", column_item, "active",
(GBindingFlags) (G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE));
gtk_menu_shell_append(GTK_MENU_SHELL(header_menu), column_item);
}
gtk_widget_show_all(header_menu);
GVariant *value;
GVariantIter iter;
int sortIndex;
GSList *order = NULL;
value = g_settings_get_value(pt_settings, "columns-order");
g_variant_iter_init(&iter, value);
while (g_variant_iter_loop (&iter, "i", &sortIndex))
order = g_slist_append(order, GINT_TO_POINTER(sortIndex));
proctable_set_columns_order(GTK_TREE_VIEW(tree), order);
g_variant_unref(value);
g_slist_free(order);
}
g_object_unref(pt_settings);
pt_settings = NULL;
g_list_free(columns);
return TRUE;
}
void
procman_save_tree_state (GSettings *settings, GtkWidget *tree, const gchar *child_schema)
{
GtkTreeModel *model;
GList *columns;
gint sort_col;
GtkSortType order;
g_assert(tree);
g_assert(child_schema);
GSettings *pt_settings = g_settings_get_child (settings, child_schema);
model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree));
if (gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (model), &sort_col,
&order)) {
g_settings_set_int (pt_settings, "sort-col", sort_col);
g_settings_set_int (pt_settings, "sort-order", order);
}
columns = gtk_tree_view_get_columns (GTK_TREE_VIEW (tree));
if(!g_strcmp0(child_schema, "proctree") || !g_strcmp0(child_schema, "disktreenew"))
{
GSList *order;
GSList *order_node;
GVariantBuilder *builder;
GVariant *order_variant;
order = proctable_get_columns_order(GTK_TREE_VIEW(tree));
builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
for(order_node = order; order_node; order_node = order_node->next)
g_variant_builder_add(builder, "i", GPOINTER_TO_INT(order_node->data));
order_variant = g_variant_new("ai", builder);
g_settings_set_value(pt_settings, "columns-order", order_variant);
g_variant_builder_unref(builder);
g_slist_free(order);
}
g_list_free(columns);
}
void
GsmApplication::save_config ()
{
......
......@@ -211,10 +211,4 @@ struct KillArgs
int signal;
};
void procman_save_tree_state (GSettings *settings, GtkWidget *tree, const gchar *prefix);
gboolean procman_get_tree_state (GSettings *settings, GtkWidget *tree, const gchar *prefix);
#endif /* _GSM_APPLICATION_H_ */
......@@ -13,6 +13,7 @@
#include "util.h"
#include "iconthemewrapper.h"
#include "settings-keys.h"
#include "treeview.h"
enum DiskColumns
{
......@@ -38,9 +39,7 @@ cb_sort_changed (GtkTreeSortable *model, gpointer data)
{
GsmApplication *app = (GsmApplication *) data;
procman_save_tree_state (app->settings,
GTK_WIDGET (app->disk_list),
GSM_SETTINGS_CHILD_DISKS);
gsm_tree_view_save_state (GSM_TREE_VIEW (app->disk_list));
}
static void
......@@ -298,11 +297,7 @@ disks_reset_timeout (GsmApplication *app)
static void
cb_disk_columns_changed(GtkTreeView *treeview, gpointer data)
{
GsmApplication *app = static_cast<GsmApplication *>(data);
procman_save_tree_state (app->settings,
GTK_WIDGET (treeview),
GSM_SETTINGS_CHILD_DISKS);
gsm_tree_view_save_state (GSM_TREE_VIEW (treeview));
}
......@@ -395,8 +390,9 @@ create_disk_view(GsmApplication *app, GtkBuilder *builder)
GDK_TYPE_PIXBUF, /* DISK_ICON */
G_TYPE_INT /* DISK_USED_PERCENTAGE */
);
disk_tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model));
disk_tree = gsm_tree_view_new (settings, TRUE);
gtk_tree_view_set_model (GTK_TREE_VIEW (disk_tree), GTK_TREE_MODEL (model));
g_signal_connect(G_OBJECT(disk_tree), "row-activated", G_CALLBACK(open_dir), NULL);
app->disk_list = disk_tree;
gtk_container_add(GTK_CONTAINER(scrolled), disk_tree);
......@@ -418,11 +414,10 @@ create_disk_view(GsmApplication *app, GtkBuilder *builder)
NULL);
gtk_tree_view_column_set_title(col, _(titles[DISK_DEVICE]));
gtk_tree_view_column_set_sort_column_id(col, DISK_DEVICE);
bind_column_to_gsetting (settings, col);
gtk_tree_view_column_set_reorderable(col, TRUE);
gtk_tree_view_column_set_resizable(col, TRUE);
gtk_tree_view_column_set_sizing(col, GTK_TREE_VIEW_COLUMN_FIXED);
gtk_tree_view_append_column(GTK_TREE_VIEW(disk_tree), col);
gsm_tree_view_append_and_bind_column (GSM_TREE_VIEW (disk_tree), col);
/* sizes - used */
......@@ -434,10 +429,9 @@ create_disk_view(GsmApplication *app, GtkBuilder *builder)
gtk_tree_view_column_set_title(col, _(titles[i]));
gtk_tree_view_column_set_resizable(col, TRUE);
gtk_tree_view_column_set_sort_column_id(col, i);
bind_column_to_gsetting (settings, col);
gtk_tree_view_column_set_reorderable(col, TRUE);
gtk_tree_view_column_set_sizing(col, GTK_TREE_VIEW_COLUMN_FIXED);
gtk_tree_view_append_column(GTK_TREE_VIEW(disk_tree), col);
gsm_tree_view_append_and_bind_column (GSM_TREE_VIEW (disk_tree), col);
switch (i) {
case DISK_TOTAL:
case DISK_FREE:
......@@ -474,17 +468,14 @@ create_disk_view(GsmApplication *app, GtkBuilder *builder)
gtk_tree_view_column_pack_start(col, cell, TRUE);
gtk_tree_view_column_set_attributes(col, cell, "value",
DISK_USED_PERCENTAGE, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(disk_tree), col);
gtk_tree_view_column_set_resizable(col, TRUE);
gtk_tree_view_column_set_sort_column_id(col, DISK_USED);
bind_column_to_gsetting (settings, col);
gtk_tree_view_column_set_reorderable(col, TRUE);
gsm_tree_view_append_and_bind_column (GSM_TREE_VIEW (disk_tree), col);
/* numeric sort */
procman_get_tree_state (app->settings, disk_tree,
GSM_SETTINGS_CHILD_DISKS);
gsm_tree_view_load_state (GSM_TREE_VIEW (disk_tree));
g_signal_connect (G_OBJECT(disk_tree), "destroy",
G_CALLBACK(cb_disk_list_destroying),
app);
......
......@@ -19,6 +19,7 @@ using std::string;
#include "memmaps.h"
#include "proctable.h"
#include "settings-keys.h"
#include "treeview.h"
#include "util.h"
......@@ -158,23 +159,19 @@ namespace
public:
guint timer;
GtkWidget *tree;
GSettings *settings;
ProcInfo *info;
OffsetFormater format;
mutable InodeDevices devices;
const char * const schema;
MemMapsData(GtkWidget *a_tree, GSettings *a_settings)
: tree(a_tree),
settings(a_settings),
schema(GSM_SETTINGS_CHILD_MEMMAP)
MemMapsData(GtkWidget *a_tree)
: tree(a_tree)
{
procman_get_tree_state(this->settings, this->tree, this->schema);
gsm_tree_view_load_state (GSM_TREE_VIEW (this->tree));
}
~MemMapsData()
{
procman_save_tree_state(this->settings, this->tree, this->schema);
gsm_tree_view_save_state (GSM_TREE_VIEW (this->tree));
}
};
}
......@@ -379,7 +376,10 @@ create_memmapsdata (GsmApplication *app)
G_TYPE_UINT64 /* MMAP_COL_INODE */
);
tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
GSettings *settings = g_settings_get_child (app->settings, GSM_SETTINGS_CHILD_MEMMAP);
tree = gsm_tree_view_new (settings, FALSE);
gtk_tree_view_set_model (GTK_TREE_VIEW (tree), GTK_TREE_MODEL (model));
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (tree), TRUE);
g_object_unref (G_OBJECT (model));
......@@ -427,7 +427,7 @@ create_memmapsdata (GsmApplication *app)
}
}
return new MemMapsData(tree, app->settings);
return new MemMapsData(tree);
}
......
......@@ -15,6 +15,7 @@
#include "proctable.h"
#include "util.h"
#include "settings-keys.h"
#include "treeview.h"
#ifndef NI_IDN
#define NI_IDN 0
......@@ -221,11 +222,9 @@ static void
close_openfiles_dialog (GtkDialog *dialog, gint id, gpointer data)
{
GtkWidget *tree = static_cast<GtkWidget*>(data);
GSettings *settings;
guint timer;
settings = static_cast<GSettings*>(g_object_get_data (G_OBJECT (tree), "settings"));
procman_save_tree_state (settings, tree, GSM_SETTINGS_CHILD_OPEN_FILES);
gsm_tree_view_save_state (GSM_TREE_VIEW (tree));
timer = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (tree), "timer"));
g_source_remove (timer);
......@@ -261,7 +260,10 @@ create_openfiles_tree (GsmApplication *app)
G_TYPE_POINTER /* open_files_entry */
);
tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
GSettings *settings = g_settings_get_child (app->settings, GSM_SETTINGS_CHILD_OPEN_FILES);
tree = gsm_tree_view_new (settings, FALSE);
gtk_tree_view_set_model (GTK_TREE_VIEW (tree), GTK_TREE_MODEL (model));
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (tree), TRUE);
g_object_unref (G_OBJECT (model));
......@@ -283,18 +285,7 @@ create_openfiles_tree (GsmApplication *app)
gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
}
#if 0
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (model),
COL_VMSZ,
sort_ints,
GINT_TO_POINTER (COL_FD),
NULL);
/*gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model),
0,
GTK_SORT_ASCENDING);*/
#endif
procman_get_tree_state (app->settings, tree, GSM_SETTINGS_CHILD_OPEN_FILES);
gsm_tree_view_load_state (GSM_TREE_VIEW (tree));
return tree;
......@@ -354,7 +345,6 @@ create_single_openfiles_dialog (GtkTreeModel *model, GtkTreePath *path,
tree = create_openfiles_tree (app);
gtk_container_add (GTK_CONTAINER (scrolled), tree);
g_object_set_data (G_OBJECT (tree), "selected_info", GUINT_TO_POINTER (info->pid));
g_object_set_data (G_OBJECT (tree), "settings", app->settings);
g_signal_connect (G_OBJECT (openfilesdialog), "response",
G_CALLBACK (close_openfiles_dialog), tree);
......
......@@ -62,6 +62,7 @@
#include "selinux.h"
#include "settings-keys.h"
#include "cgroups.h"
#include "treeview.h"
ProcInfo::UserMap ProcInfo::users;
ProcInfo::List ProcInfo::all;
......@@ -79,79 +80,7 @@ cb_save_tree_state(gpointer, gpointer data)
{
GsmApplication * const app = static_cast<GsmApplication *>(data);
procman_save_tree_state (app->settings,
GTK_WIDGET (app->tree),
GSM_SETTINGS_CHILD_PROCESSES);
}
static GtkTreeViewColumn*
my_gtk_tree_view_get_column_with_sort_column_id(GtkTreeView *treeview, int id)
{
GList *columns, *it;
GtkTreeViewColumn *col = NULL;
columns = gtk_tree_view_get_columns(treeview);
for(it = columns; it; it = it->next)
{
if(gtk_tree_view_column_get_sort_column_id(static_cast<GtkTreeViewColumn*>(it->data)) == id)
{
col = static_cast<GtkTreeViewColumn*>(it->data);
break;
}
}
g_list_free(columns);
return col;
}
void
proctable_set_columns_order(GtkTreeView *treeview, GSList *order)
{
GtkTreeViewColumn* last = NULL;
GSList *it;
for(it = order; it; it = it->next)
{
int id;
GtkTreeViewColumn *cur;
id = GPOINTER_TO_INT(it->data);
g_assert(id >= 0 && id < NUM_COLUMNS);
cur = my_gtk_tree_view_get_column_with_sort_column_id(treeview, id);
if(cur && cur != last)
{
gtk_tree_view_move_column_after(treeview, cur, last);
last = cur;
}
}
}
GSList*
proctable_get_columns_order(GtkTreeView *treeview)
{
GList *columns, *col;
GSList *order = NULL;
columns = gtk_tree_view_get_columns(treeview);
for(col = columns; col; col = col->next)
{
int id;
id = gtk_tree_view_column_get_sort_column_id(static_cast<GtkTreeViewColumn*>(col->data));
order = g_slist_prepend(order, GINT_TO_POINTER(id));
}
g_list_free(columns);
order = g_slist_reverse(order);
return order;
gsm_tree_view_save_state (GSM_TREE_VIEW (app->tree));
}
static void
......@@ -446,7 +375,9 @@ proctable_new (GsmApplication * const app)
model_sort = GTK_TREE_MODEL_SORT (gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (model_filter)));
proctree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model_sort));
proctree = gsm_tree_view_new (settings, TRUE);
gtk_tree_view_set_model (GTK_TREE_VIEW (proctree), GTK_TREE_MODEL (model_sort));
gtk_tree_view_set_tooltip_column (GTK_TREE_VIEW (proctree), COL_TOOLTIP);
gtk_tree_view_set_show_expanders (GTK_TREE_VIEW (proctree),
g_settings_get_boolean (app->settings, GSM_SETTING_SHOW_DEPENDENCIES));
......@@ -470,12 +401,12 @@ proctable_new (GsmApplication * const app)
gtk_tree_view_column_set_title (column, _(titles[0]));
gtk_tree_view_column_set_sort_column_id (column, COL_NAME);
bind_column_to_gsetting (settings, column);
gtk_tree_view_column_set_resizable (column, TRUE);
gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
gtk_tree_view_column_set_min_width (column, 1);
gtk_tree_view_column_set_reorderable(column, TRUE);
gtk_tree_view_append_column (GTK_TREE_VIEW (proctree), column);
gsm_tree_view_append_and_bind_column (GSM_TREE_VIEW (proctree), column);
gtk_tree_view_set_expander_column (GTK_TREE_VIEW (proctree), column);
for (i = COL_USER; i <= COL_PRIORITY; i++) {
......@@ -496,9 +427,8 @@ proctable_new (GsmApplication * const app)
gtk_tree_view_column_set_title(col, _(titles[i]));
gtk_tree_view_column_set_resizable(col, TRUE);
gtk_tree_view_column_set_sort_column_id(col, i);
bind_column_to_gsetting (settings, col);
gtk_tree_view_column_set_reorderable(col, TRUE);
gtk_tree_view_append_column(GTK_TREE_VIEW(proctree), col);
gsm_tree_view_append_and_bind_column (GSM_TREE_VIEW (proctree), col);
// type
switch (i) {
......@@ -611,18 +541,33 @@ proctable_new (GsmApplication * const app)
app->last_vscroll_max = 0;
app->last_vscroll_value = 0;
procman_get_tree_state (app->settings, proctree, "proctree");
if (!cgroups_enabled ())
gsm_tree_view_add_excluded_column (GSM_TREE_VIEW (proctree), COL_CGROUP);
#ifdef HAVE_SYSTEMD
if (!LOGIND_RUNNING ()) {
#else
{
#endif
gsm_tree_view_add_excluded_column (GSM_TREE_VIEW (proctree), COL_UNIT);
gsm_tree_view_add_excluded_column (GSM_TREE_VIEW (proctree), COL_SESSION);
gsm_tree_view_add_excluded_column (GSM_TREE_VIEW (proctree), COL_SEAT);
gsm_tree_view_add_excluded_column (GSM_TREE_VIEW (proctree), COL_OWNER);
}
gsm_tree_view_load_state (GSM_TREE_VIEW (proctree));
/* Override column settings by hiding this column if it's meaningless: */
if (!can_show_security_context_column ()) {
GtkTreeViewColumn *column;
column = my_gtk_tree_view_get_column_with_sort_column_id (GTK_TREE_VIEW (proctree), COL_SECURITYCONTEXT);
column = gsm_tree_view_get_column_from_id (GSM_TREE_VIEW (proctree), COL_SECURITYCONTEXT);
gtk_tree_view_column_set_visible (column, FALSE);
}
if (!cgroups_enabled()) {
GtkTreeViewColumn *column;
column = my_gtk_tree_view_get_column_with_sort_column_id(GTK_TREE_VIEW(proctree), COL_CGROUP);
column = gsm_tree_view_get_column_from_id (GSM_TREE_VIEW(proctree), COL_CGROUP);
gtk_tree_view_column_set_visible(column, FALSE);
}
......@@ -636,7 +581,7 @@ proctable_new (GsmApplication * const app)
GtkTreeViewColumn *column;
for (i = COL_UNIT; i <= COL_OWNER; i++) {
column = my_gtk_tree_view_get_column_with_sort_column_id(GTK_TREE_VIEW(proctree), i);
column = gsm_tree_view_get_column_from_id (GSM_TREE_VIEW(proctree), i);
gtk_tree_view_column_set_visible(column, FALSE);
}
}
......
......@@ -64,9 +64,6 @@ void proctable_freeze (GsmApplication *app);
void proctable_thaw (GsmApplication *app);
void proctable_reset_timeout (GsmApplication *app);
GSList* proctable_get_columns_order(GtkTreeView *treeview);
void proctable_set_columns_order(GtkTreeView *treeview, GSList *order);
char* make_loadavg_string(void);
void get_process_memory_writable (ProcInfo *info);
......
......@@ -7,7 +7,7 @@
#define GSM_SETTINGS_CHILD_OPEN_FILES "openfilestree"
#define GSM_SETTINGS_CHILD_DISKS "disktreenew"
#define GSM_SETTINGS_CHILD_PROCESSES "proctree"
#define GSM_SETTINGS_CHILD_MEMMAP "memmaptree"
#define GSM_SETTINGS_CHILD_MEMMAP "memmapstree"
#define GSM_SETTING_WINDOW_STATE "window-state"
#define GSM_SETTING_MAXIMIZED "maximized"
......
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
#include <config.h>
#include "treeview.h"
typedef struct
{
GSettings *settings;
gboolean store_column_order;
GHashTable *excluded_columns;
} GsmTreeViewPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (GsmTreeView, gsm_tree_view, GTK_TYPE_TREE_VIEW)
static void
gsm_tree_view_finalize (GObject *object)
{
GsmTreeViewPrivate *priv = gsm_tree_view_get_instance_private (GSM_TREE_VIEW (object));
g_hash_table_destroy (priv->excluded_columns);
priv->excluded_columns = NULL;
G_OBJECT_CLASS (gsm_tree_view_parent_class)->finalize (object);
}
static void
gsm_tree_view_class_init (GsmTreeViewClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = gsm_tree_view_finalize;
}
static void
gsm_tree_view_init (GsmTreeView *self)
{
GsmTreeViewPrivate *priv = gsm_tree_view_get_instance_private (self);
priv->excluded_columns = g_hash_table_new (g_direct_hash, g_direct_equal);
}
void
gsm_tree_view_save_state (GsmTreeView *tree_view)
{
GsmTreeViewPrivate *priv;
g_return_if_fail (GSM_IS_TREE_VIEW (tree_view));
priv = gsm_tree_view_get_instance_private (tree_view);
GtkTreeModel *model;
gint sort_col;
GtkSortType sort_type;
model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
if (gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (model),
&sort_col,
&sort_type)) {
g_settings_set_int (priv->settings, "sort-col", sort_col);
g_settings_set_int (priv->settings, "sort-order", sort_type);
}
if (priv->store_column_order) {
GList *columns = gtk_tree_view_get_columns (GTK_TREE_VIEW (tree_view));
GList *iter;
GVariantBuilder builder;
g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
for (iter = columns; iter != NULL; iter = iter->next) {
gint id = gtk_tree_view_column_get_sort_column_id (GTK_TREE_VIEW_COLUMN (iter->data));
g_variant_builder_add (&builder, "i", id);
}
g_settings_set_value (priv->settings, "columns-order",
g_variant_new ("ai", builder));
g_list_free (columns);
}
}
GtkTreeViewColumn *
gsm_tree_view_get_column_from_id (GsmTreeView *tree_view, gint sort_id)
{
GList *columns;
GList *iter;
GtkTreeViewColumn *col = NULL;
g_return_val_if_fail (GSM_IS_TREE_VIEW (tree_view), NULL);
columns = gtk_tree_view_get_columns (GTK_TREE_VIEW (tree_view));
for (iter = columns; iter != NULL; iter = iter->next) {
col = GTK_TREE_VIEW_COLUMN (iter->data);
if (gtk_tree_view_column_get_sort_column_id (col) == sort_id)
break;
}
g_list_free (columns);
return col;
}
static gboolean
cb_column_header_clicked (GtkTreeViewColumn* column, GdkEvent* event, gpointer data)
{
GtkMenu *menu = GTK_MENU (data);
if (event->button.button == GDK_BUTTON_SECONDARY) {
gtk_menu_popup (menu, NULL, NULL,
NULL,
&(event->button),
event->button.button,
event->button.time);
return TRUE;
}
return FALSE;
}
void
gsm_tree_view_load_state (GsmTreeView *tree_view)
{
GsmTreeViewPrivate *priv;
GtkTreeModel *model;
gint sort_col;
GtkSortType sort_type;
g_return_if_fail (GSM_IS_TREE_VIEW (tree_view));
priv = gsm_tree_view_get_instance_private (tree_view);
model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
sort_col = g_settings_get_int (priv->settings, "sort-col");
sort_type = g_settings_get_int (priv->settings, "sort-order");
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model),
sort_col,
sort_type);
if (priv->store_column_order) {
GtkWidget *header_menu = gtk_menu_new ();
GList *columns = gtk_tree_view_get_columns (GTK_TREE_VIEW (tree_view));
GList *iter;
GVariantIter *var_iter;
GtkTreeViewColumn *col, *last;
gint sort_id;
for (iter = columns; iter != NULL; iter = iter->next) {