r23351 - gnucash/trunk/src - Re-implement state save/restore functionality in gnc_tree_view
Geert Janssens
gjanssens at code.gnucash.org
Tue Oct 29 15:26:25 EDT 2013
Author: gjanssens
Date: 2013-10-29 15:26:23 -0400 (Tue, 29 Oct 2013)
New Revision: 23351
Trac: http://svn.gnucash.org/trac/changeset/23351
Modified:
gnucash/trunk/src/business/business-gnome/gnc-plugin-page-owner-tree.c
gnucash/trunk/src/gnome-utils/gnc-file.c
gnucash/trunk/src/gnome-utils/gnc-tree-view.c
gnucash/trunk/src/gnome/gnc-budget-view.c
gnucash/trunk/src/gnome/gnc-plugin-page-account-tree.c
gnucash/trunk/src/gnome/top-level.c
Log:
Re-implement state save/restore functionality in gnc_tree_view
The new implementation uses the gnucash metafile in .gnucash/books
to save gui state for any page that is based on gnc_tree_view.
Think Account Hierarchy, Budgets, Vendor/Customer/Employee overviews.
Each of these sets a unique name for a state section that the tree view
will use to store column width/visibility, sort column, sort order.
Modified: gnucash/trunk/src/business/business-gnome/gnc-plugin-page-owner-tree.c
===================================================================
--- gnucash/trunk/src/business/business-gnome/gnc-plugin-page-owner-tree.c 2013-10-29 19:26:02 UTC (rev 23350)
+++ gnucash/trunk/src/business/business-gnome/gnc-plugin-page-owner-tree.c 2013-10-29 19:26:23 UTC (rev 23351)
@@ -66,7 +66,6 @@
static QofLogModule log_module = GNC_MOD_GUI;
#define PLUGIN_PAGE_ACCT_TREE_CM_CLASS "plugin-page-owner-tree"
-#define STATE_SECTION_PREFIX "window/pages/"
#define DELETE_DIALOG_FILTER "filter"
#define DELETE_DIALOG_OWNER "owner"
@@ -559,7 +558,7 @@
GtkTreeView *tree_view;
GtkWidget *scrolled_window;
GtkTreeViewColumn *col;
- gchar *state_section = NULL;
+ const gchar *state_section = NULL;
gchar* label = "";
ENTER("page %p", plugin_page);
@@ -607,26 +606,25 @@
break;
case GNC_OWNER_CUSTOMER :
label = N_("Customers");
- state_section = g_strconcat(STATE_SECTION_PREFIX, "customer_tree", NULL);
+ state_section = "Customers Overview";
break;
case GNC_OWNER_JOB :
label = N_("Jobs");
- state_section = g_strconcat(STATE_SECTION_PREFIX, "job_tree", NULL);
+ state_section = "Jobs Overview";
break;
case GNC_OWNER_VENDOR :
label = N_("Vendors");
- state_section = g_strconcat(STATE_SECTION_PREFIX, "vendor_tree", NULL);
+ state_section = "Vendors Overview";
break;
case GNC_OWNER_EMPLOYEE :
label = N_("Employees");
- state_section = g_strconcat(STATE_SECTION_PREFIX, "job_tree", NULL);
+ state_section = "Employees Overview";
break;
}
g_object_set(G_OBJECT(tree_view), "state-section", state_section,
"show-column-menu", TRUE,
NULL);
- g_free (state_section);
g_object_set(G_OBJECT(plugin_page), "page-name", label, NULL);
Modified: gnucash/trunk/src/gnome/gnc-budget-view.c
===================================================================
--- gnucash/trunk/src/gnome/gnc-budget-view.c 2013-10-29 19:26:02 UTC (rev 23350)
+++ gnucash/trunk/src/gnome/gnc-budget-view.c 2013-10-29 19:26:23 UTC (rev 23351)
@@ -68,7 +68,7 @@
static QofLogModule log_module = GNC_MOD_BUDGET;
#define PLUGIN_PAGE_BUDGET_CM_CLASS "budget-view"
-#define STATE_SECTION_PREFIX "window/pages/budget"
+#define STATE_SECTION_PREFIX "Budget"
typedef struct GncBudgetViewPrivate GncBudgetViewPrivate;
@@ -313,7 +313,7 @@
tree_view = gnc_tree_view_account_new(FALSE);
gtk_container_add(GTK_CONTAINER(inner_scrolled_window), GTK_WIDGET(tree_view));
- state_section = g_strjoin("/", STATE_SECTION_PREFIX, guid_to_string(&priv->key), NULL);
+ state_section = g_strjoin(" ", STATE_SECTION_PREFIX, guid_to_string(&priv->key), NULL);
g_object_set(G_OBJECT(tree_view), "state-section", state_section, NULL);
g_free (state_section);
Modified: gnucash/trunk/src/gnome/gnc-plugin-page-account-tree.c
===================================================================
--- gnucash/trunk/src/gnome/gnc-plugin-page-account-tree.c 2013-10-29 19:26:02 UTC (rev 23350)
+++ gnucash/trunk/src/gnome/gnc-plugin-page-account-tree.c 2013-10-29 19:26:23 UTC (rev 23351)
@@ -71,7 +71,7 @@
static QofLogModule log_module = GNC_MOD_GUI;
#define PLUGIN_PAGE_ACCT_TREE_CM_CLASS "plugin-page-acct-tree"
-#define STATE_SECTION "window/pages/account_tree"
+#define STATE_SECTION "Account Hierarchy"
#define DELETE_DIALOG_FILTER "filter"
#define DELETE_DIALOG_ACCOUNT "account"
Modified: gnucash/trunk/src/gnome/top-level.c
===================================================================
--- gnucash/trunk/src/gnome/top-level.c 2013-10-29 19:26:02 UTC (rev 23350)
+++ gnucash/trunk/src/gnome/top-level.c 2013-10-29 19:26:23 UTC (rev 23351)
@@ -347,7 +347,7 @@
#endif
/* Write it all out to disk */
- gnc_state_save (session);
+ //gnc_state_save (session);
LEAVE("");
}
Modified: gnucash/trunk/src/gnome-utils/gnc-file.c
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-file.c 2013-10-29 19:26:02 UTC (rev 23350)
+++ gnucash/trunk/src/gnome-utils/gnc-file.c 2013-10-29 19:26:23 UTC (rev 23351)
@@ -47,6 +47,7 @@
#include "qof.h"
#include "TransLog.h"
#include "gnc-session.h"
+#include "gnc-state.h"
#include "gnc-autosave.h"
@@ -530,6 +531,7 @@
gnc_hook_run(HOOK_BOOK_CLOSED, session);
gnc_close_gui_component_by_session (session);
+ gnc_state_save (session);
gnc_clear_current_session();
qof_event_resume ();
}
@@ -707,6 +709,7 @@
qof_session_call_close_hooks(current_session);
gnc_hook_run(HOOK_BOOK_CLOSED, current_session);
gnc_close_gui_component_by_session (current_session);
+ gnc_state_save (current_session);
gnc_clear_current_session();
}
@@ -1557,6 +1560,7 @@
qof_session_call_close_hooks(session);
gnc_hook_run(HOOK_BOOK_CLOSED, session);
gnc_close_gui_component_by_session (session);
+ gnc_state_save (session);
gnc_clear_current_session();
qof_event_resume ();
Modified: gnucash/trunk/src/gnome-utils/gnc-tree-view.c
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-tree-view.c 2013-10-29 19:26:02 UTC (rev 23350)
+++ gnucash/trunk/src/gnome-utils/gnc-tree-view.c 2013-10-29 19:26:23 UTC (rev 23351)
@@ -43,6 +43,7 @@
#include "gnc-gnome-utils.h"
#include "gnc-gobject-utils.h"
#include "gnc-cell-renderer-date.h"
+#include "gnc-state.h"
/* The actual state key for a particular column visibility. This is
* attached to the menu items that are in the column selection menu.
@@ -57,8 +58,8 @@
/* Partial state keys within this particular saved state section. These
are appended to the various column names to create the actual
keys. */
-#define STATE_KEY_VISIBLE "visible"
-#define STATE_KEY_WIDTH "width"
+#define STATE_KEY_SUFF_VISIBLE "visible"
+#define STATE_KEY_SUFF_WIDTH "width"
enum
{
@@ -93,6 +94,10 @@
static void gnc_tree_view_build_column_menu (GncTreeView *view);
static void gnc_tree_view_select_column_cb (GtkTreeViewColumn *column,
GncTreeView *view);
+static gchar *gnc_tree_view_get_sort_order (GncTreeView *view);
+static gchar *gnc_tree_view_get_sort_column (GncTreeView *view);
+static gchar **gnc_tree_view_get_column_order (GncTreeView *view,
+ gsize *length);
/** Private Data Structure ***********************************************/
@@ -333,6 +338,64 @@
priv = GNC_TREE_VIEW_GET_PRIVATE(view);
+ if (priv->state_section)
+ {
+ /* Save state */
+ GList *column_list, *tmp;
+ GKeyFile *state_file = gnc_state_get_current();
+ gsize num_cols = 0;
+ gchar *sort_column = gnc_tree_view_get_sort_column (view);
+ gchar *sort_order = gnc_tree_view_get_sort_order (view);
+ gchar **col_order = gnc_tree_view_get_column_order (view, &num_cols);
+
+ if (sort_column)
+ g_key_file_set_string (state_file, priv->state_section, STATE_KEY_SORT_COLUMN, sort_column);
+ else if (g_key_file_has_key (state_file, priv->state_section, STATE_KEY_SORT_COLUMN, NULL))
+ g_key_file_remove_key (state_file, priv->state_section, STATE_KEY_SORT_COLUMN, NULL);
+
+ if (sort_order)
+ g_key_file_set_string (state_file, priv->state_section, STATE_KEY_SORT_ORDER, sort_order);
+ else if (g_key_file_has_key (state_file, priv->state_section, STATE_KEY_SORT_ORDER, NULL))
+ g_key_file_remove_key (state_file, priv->state_section, STATE_KEY_SORT_ORDER, NULL);
+
+ if (col_order && (num_cols > 0))
+ g_key_file_set_string_list (state_file, priv->state_section, STATE_KEY_COLUMN_ORDER,
+ (const gchar**) col_order, num_cols);
+ else if (g_key_file_has_key (state_file, priv->state_section, STATE_KEY_COLUMN_ORDER, NULL))
+ g_key_file_remove_key (state_file, priv->state_section, STATE_KEY_COLUMN_ORDER, NULL);
+
+
+ // ENTER("view %p, wanted %s", view, wanted);
+ column_list = gtk_tree_view_get_columns (GTK_TREE_VIEW (view));
+ for (tmp = column_list; tmp; tmp = g_list_next (tmp))
+ {
+ GtkTreeViewColumn *column = tmp->data;
+ gchar *key=NULL;
+ const gchar *name = g_object_get_data (G_OBJECT (column), PREF_NAME);
+ if (!name)
+ continue;
+
+ if (!g_object_get_data (G_OBJECT (column), ALWAYS_VISIBLE))
+ {
+ key = g_strjoin ("_", name, STATE_KEY_SUFF_VISIBLE, NULL);
+ g_key_file_set_boolean (state_file, priv->state_section, key,
+ gtk_tree_view_column_get_visible (column));
+ g_free (key);
+ }
+
+ key = g_strjoin ("_", name, STATE_KEY_SUFF_WIDTH, NULL);
+ if (gtk_tree_view_column_get_fixed_width (column)
+ != gtk_tree_view_column_get_width (column))
+ {
+ g_key_file_set_integer (state_file, priv->state_section, key,
+ gtk_tree_view_column_get_width (column));
+ }
+ else if (g_key_file_has_key (state_file, priv->state_section, key, NULL))
+ g_key_file_remove_key (state_file, priv->state_section, key, NULL);
+ g_free (key);
+ }
+ g_list_free(column_list);
+ }
g_free(priv->state_section);
priv->state_section = NULL;
@@ -427,6 +490,46 @@
/** @name Gnc Tree View Auxiliary Functions
@{ */
+/** Find a tree column given a column id number from the underlying
+ * data model. This function should only be called by code that has
+ * visibility into the data model. The column id numbers shouldn't
+ * be used for any other purpose.
+ *
+ * This function simply runs the list of all (visible and invisible)
+ * columns looking for a match. Column id numbers were attached to
+ * each column at the time the column was created.
+ *
+ * @param view The visible tree widget.
+ *
+ * @param wanted The column id number to find.
+ *
+ * @internal
+ */
+static GtkTreeViewColumn *
+view_column_find_by_model_id (GncTreeView *view,
+ const gint wanted)
+{
+ GtkTreeViewColumn *column, *found = NULL;
+ GList *column_list, *tmp;
+ gint id;
+
+ // ENTER("view %p, name %s", view, name);
+ column_list = gtk_tree_view_get_columns(GTK_TREE_VIEW(view));
+ for (tmp = column_list; tmp; tmp = g_list_next(tmp))
+ {
+ column = tmp->data;
+ id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(column), MODEL_COLUMN));
+ if (id != wanted)
+ continue;
+ found = column;
+ break;
+ }
+ g_list_free(column_list);
+
+ // LEAVE("column %p", found);
+ return found;
+}
+
/** Find a tree column given the "pref name" used with saved state. This
* function simply runs the list of all (visible and invisible)
* columns looking for a match. Column names were attached to each
@@ -541,12 +644,10 @@
/** Determine the visibility of a column. This function first looks
* for columns specially marked to be always visible, or columns
* without a preference name. These are always shown. Next, this
- * function checks to see if the column should be visible by default.
- * If so this column will be shown as well.
+ * function checks if visibility is stored in saved state. If so
+ * use the value found there. If none of the above the default
+ * visibility for the column is used.
*
- * FIXME This should be improved when saved state functionality is
- * added again.
- *
* @param view A GncTreeView.
*
* @param column The GtkTreeViewColumn in question. Either this
@@ -555,7 +656,7 @@
* @param pref_name The name of the column in question. Either this
* value or the column parameter must be non-NULL.
*
- * @returns TRUE if the column should be visible. FALSE otherwise.
+ * @return TRUE if the column should be visible. FALSE otherwise.
*
* @internal
*/
@@ -566,7 +667,7 @@
{
GncTreeViewPrivate *priv;
gboolean visible;
- gchar *key;
+ const gchar *col_name = pref_name;
ENTER("column %p, name %s", column, pref_name ? pref_name : "(null)");
priv = GNC_TREE_VIEW_GET_PRIVATE(view);
@@ -577,11 +678,11 @@
LEAVE("1, first column");
return TRUE;
}
- pref_name = (gchar *)g_object_get_data(G_OBJECT(column), PREF_NAME);
- DEBUG("pref_name is %s", pref_name ? pref_name : "(null)");
+ col_name = g_object_get_data(G_OBJECT(column), PREF_NAME);
+ DEBUG("col_name is %s", col_name ? col_name : "(null)");
}
- if (!pref_name)
+ if (!col_name)
{
LEAVE("1, no pref name");
return TRUE;
@@ -590,10 +691,16 @@
/* Using saved state ? */
if (priv->state_section)
{
- visible = column ?
- (g_object_get_data(G_OBJECT(column), DEFAULT_VISIBLE) != NULL) : FALSE;
- LEAVE("%d, saved state but using defaults", visible);
- return visible;
+ GKeyFile *state_file = gnc_state_get_current ();
+ gchar *key = g_strdup_printf("%s_%s", col_name, STATE_KEY_SUFF_VISIBLE);
+
+ if (g_key_file_has_key (state_file, priv->state_section, key, NULL))
+ {
+ visible = g_key_file_get_boolean (state_file, priv->state_section, key, NULL);
+ g_free(key);
+ LEAVE("%d, state defined visibility", visible);
+ return visible;
+ }
}
/* Check the default columns list */
@@ -628,33 +735,269 @@
priv = GNC_TREE_VIEW_GET_PRIVATE(view);
visible = gnc_tree_view_column_visible(view, column, NULL);
gtk_tree_view_column_set_visible(column, visible);
- if (priv->state_section)
+ LEAVE("made %s", visible ? "visible" : "invisible");
+}
+
+/** Get the sort order for the sort column, converted into a string.
+ *
+ * @param view The tree view.
+ *
+ * @return a string representing the sort order. NULL if not sorted, else
+ * either "ascending" or "descending".
+ * Should be freed with g_free if no longer needed.
+ *
+ * @internal
+ */
+static gchar *
+gnc_tree_view_get_sort_order (GncTreeView *view)
+{
+ GncTreeViewPrivate *priv;
+ GtkTreeModel *s_model;
+ GtkSortType order;
+ gint current;
+ gchar *order_str = NULL;
+
+ priv = GNC_TREE_VIEW_GET_PRIVATE(view);
+ s_model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
+ if (!s_model)
+ return NULL; /* no model, so sort order doesn't make sense */
+
+ if (!gtk_tree_sortable_get_sort_column_id(GTK_TREE_SORTABLE(s_model),
+ ¤t, &order))
+ return NULL; /* Model is not sorted, return */
+
+ gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(s_model),
+ current, order);
+ order_str = g_strdup (order == GTK_SORT_ASCENDING ? "ascending" : "descending");
+ DEBUG("current sort_order is %s", order_str);
+ return order_str;
+}
+
+/** Get the current sort column.
+ *
+ * @param view The tree view.
+ *
+ * @return a string with the name of the sort column, or NULL if not sorted.
+ * Should be freed with g_free if no longer needed.
+ *
+ * @internal
+ */
+static gchar *
+gnc_tree_view_get_sort_column (GncTreeView *view)
+{
+ GtkTreeModel *s_model;
+ GtkTreeViewColumn *column;
+ GtkSortType order;
+ gint model_column, current;
+ const gchar *name;
+
+ s_model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
+ if (!s_model)
+ return NULL; /* no model -> no sort column */
+
+ if (!gtk_tree_sortable_get_sort_column_id(GTK_TREE_SORTABLE(s_model),
+ ¤t, &order))
+ return NULL; /* model not sorted */
+
+ column = view_column_find_by_model_id (view, current);
+ if (!column)
+ return NULL; /* column not visible, can't be used for sorting */
+
+ name = g_object_get_data(G_OBJECT(column), PREF_NAME);
+ DEBUG("current sort column is %s", name ? name : "(NULL)");
+ return g_strdup (name);
+}
+
+
+
+/** Get the current column order.
+ *
+ * @param view The tree view.
+ *
+ * @return an array of strings with the names of the columns in the order
+ * they are currently ordered.
+ * Should be freed with g_free if no longer needed.
+ *
+ * @internal
+ */
+static gchar **
+gnc_tree_view_get_column_order (GncTreeView *view,
+ gsize *length)
+{
+ const GList *tmp;
+ GList *columns;
+ gsize num_cols = 0;
+ gchar *col_names = NULL;
+ gchar **col_str_list;
+
+ /* First, convert from names to pointers */
+ ENTER(" ");
+
+ columns = gtk_tree_view_get_columns (GTK_TREE_VIEW(view));
+ for (tmp = columns; tmp; tmp = g_list_next(tmp))
{
- name = (gchar *)g_object_get_data(G_OBJECT(column), PREF_NAME);
- if (!name)
+ GtkTreeViewColumn *column = tmp->data;
+ const gchar *name = g_object_get_data(G_OBJECT(column), PREF_NAME);
+ if (!col_names)
+ col_names = g_strdup (name);
+ else
{
- LEAVE("no pref name");
- return;
+ gchar *col_names_prev = col_names;
+ col_names = g_strjoin (";", col_names_prev, name, NULL);
+ g_free (col_names_prev);
}
- LEAVE("made %s, set state key", visible ? "visible" : "invisible");
+ num_cols++;
+ }
+ DEBUG ("got %lu columns: %s", num_cols, col_names);
+ col_str_list = g_strsplit (col_names, ";", 0);
+
+ /* Clean up */
+ g_list_free(columns);
+ g_free (col_names);
+
+ LEAVE("column order get");
+ *length = num_cols;
+ return col_str_list;
+}
+
+/** Set the sort order for the sort column (if there is one)
+ * of this tree view.
+ *
+ * @param view The tree view.
+ *
+ * @param name The sort order enum (in string form). Either
+ * "ascending" or "descending".
+ *
+ * @internal
+ */
+static void
+gnc_tree_view_set_sort_order (GncTreeView *view,
+ const gchar *name)
+{
+ GncTreeViewPrivate *priv;
+ GtkTreeModel *s_model;
+ GtkSortType order = GTK_SORT_ASCENDING;
+ gint current;
+
+ priv = GNC_TREE_VIEW_GET_PRIVATE(view);
+ s_model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
+ if (!s_model)
return;
+ if (g_strcmp0 (name, "descending") == 0)
+ order = GTK_SORT_DESCENDING;
+ if (!gtk_tree_sortable_get_sort_column_id(GTK_TREE_SORTABLE(s_model),
+ ¤t, NULL))
+ current = GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID;
+ gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(s_model),
+ current, order);
+ DEBUG("sort_order set to %s", order == GTK_SORT_ASCENDING ? "ascending" : "descending");
+}
+
+/** Set the sort column for this tree view.
+ *
+ * @param view The tree view.
+ *
+ * @param name The name of the column that should be made the sort column.
+ *
+ * @internal
+ */
+static void
+gnc_tree_view_set_sort_column (GncTreeView *view,
+ const gchar *name)
+{
+ GtkTreeModel *s_model;
+ GtkTreeViewColumn *column;
+ GtkSortType order;
+ gint model_column, current;
+
+ s_model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
+ if (!s_model)
+ return;
+
+ column = gnc_tree_view_find_column_by_name(view, name);
+ if (!column)
+ {
+ gtk_tree_sortable_set_sort_column_id(
+ GTK_TREE_SORTABLE(s_model), GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
+ GTK_SORT_ASCENDING);
+ return;
}
- LEAVE("made %s", visible ? "visible" : "invisible");
+
+ model_column =
+ GPOINTER_TO_INT(g_object_get_data(G_OBJECT(column), MODEL_COLUMN));
+ if (model_column == GNC_TREE_VIEW_COLUMN_DATA_NONE)
+ return;
+
+ if (!gtk_tree_sortable_get_sort_column_id(GTK_TREE_SORTABLE(s_model),
+ ¤t, &order))
+ order = GTK_SORT_ASCENDING;
+
+ gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(s_model),
+ model_column, order);
+ DEBUG("sort column set to %s", name);
}
-/** This function is called to completely wipe the treeview's state
- * information (column visibility, width, sorting order,..). This function may
- * be called at any time; either when the user wants to disconnect or
+/** Set the order of the columns (visible and invisible) for this
+ * tree view.
+ *
+ * @param view The tree view.
+ *
+ * @param column_names An array of strings. These strings are the
+ * names of the columns in the order they should appear.
+ *
+ * @param length The number of strings in the array.
+ *
+ * @internal
+ */
+static void
+gnc_tree_view_set_column_order (GncTreeView *view,
+ gchar **column_names,
+ gsize length)
+{
+ GncTreeViewPrivate *priv;
+ GtkTreeViewColumn *column, *prev;
+ const GSList *tmp;
+ GSList *columns;
+ gsize idx;
+
+ /* First, convert from names to pointers */
+ ENTER(" ");
+ priv = GNC_TREE_VIEW_GET_PRIVATE(view);
+ columns = NULL;
+ for (idx = 0; idx < length; idx++)
+ {
+ const gchar *name = column_names[idx];
+ column = gnc_tree_view_find_column_by_name(view, name);
+ if (!column)
+ continue;
+ columns = g_slist_append(columns, column);
+ }
+
+ /* Then reorder the columns */
+ for (prev = NULL, tmp = columns; tmp; tmp = g_slist_next(tmp))
+ {
+ column = tmp->data;
+ gtk_tree_view_move_column_after(GTK_TREE_VIEW(view), column, prev);
+ prev = column;
+ }
+
+ /* Clean up */
+ g_slist_free(columns);
+ LEAVE("column order set");
+}
+
+/** Completely wipe the treeview's state information (column visibility, width,
+ * sorting order,..). This function may be called at any time;
+ * either when the user wants to disconnect or
* when the view object is being destroyed.
*
- * FIXME this currently does nothing because state info is not saved yet
- *
* @param view The tree view.
*/
void gnc_tree_view_remove_state_information(GncTreeView *view)
{
GncTreeViewPrivate *priv;
+ GKeyFile *state_file = gnc_state_get_current ();
ENTER(" ");
priv = GNC_TREE_VIEW_GET_PRIVATE(view);
@@ -664,18 +1007,17 @@
return;
}
+ g_key_file_remove_group (state_file, priv->state_section, NULL);
g_free(priv->state_section);
priv->state_section = NULL;
LEAVE(" ");
}
-/** This function is called to set up or remove an association between
- * a saved state section and the display of a view. It will first remove
- * any existing association, and then install the new one.
+/** Set up or remove an association between a saved state section
+ * and the display of a view. It will first remove any existing association,
+ * and then install the new one. If the new section has state
+ * information, update the view with this information.
*
- * FIXME this currently does almost nothing because state information
- * is currently not stored
- *
* Parameters are defined in gnc-tree-view.h
*/
void
@@ -683,17 +1025,18 @@
const gchar *section)
{
GncTreeViewPrivate *priv;
- GtkTreeModel *model;
- gulong id;
+ GKeyFile *state_file;
g_return_if_fail(GNC_IS_TREE_VIEW(view));
ENTER("view %p, section %s", view, section);
priv = GNC_TREE_VIEW_GET_PRIVATE(view);
- g_free(priv->state_section);
- priv->state_section = NULL;
+ /* Drop any previous state section */
+ if (priv->state_section)
+ gnc_tree_view_remove_state_information (view);
+
if (!section)
{
LEAVE("cleared state section");
@@ -703,16 +1046,83 @@
/* Catch changes in state. Propagate to view. */
priv->state_section = g_strdup(section);
+ state_file = gnc_state_get_current ();
+ if (g_key_file_has_group (state_file, priv->state_section))
+ {
+ gsize num_keys, idx;
+ gchar **keys = g_key_file_get_keys (state_file, priv->state_section, &num_keys, NULL);
+ for (idx = 0; idx < num_keys; idx++)
+ {
+ gchar *key = keys[idx];
+ if (g_strcmp0 (key, STATE_KEY_SORT_COLUMN) == 0)
+ {
+ gnc_tree_view_set_sort_column (view,
+ g_key_file_get_string (state_file, priv->state_section, key, NULL));
+ }
+ else if (g_strcmp0 (key, STATE_KEY_SORT_ORDER) == 0)
+ {
+ gnc_tree_view_set_sort_order (view,
+ g_key_file_get_string (state_file, priv->state_section, key, NULL));
+ }
+ else if (g_strcmp0 (key, STATE_KEY_COLUMN_ORDER) == 0)
+ {
+ gsize length;
+ gchar **columns = g_key_file_get_string_list (state_file, priv->state_section,
+ key, &length, NULL);
+ gnc_tree_view_set_column_order (view, columns, length);
+ g_strfreev (columns);
+ }
+ else
+ {
+ /* Make a copy of the local part of the key so it can be split
+ * into column name and key type */
+ gboolean known = FALSE;
+ gchar *column_name = g_strdup (key);
+ gchar *type_name = g_strrstr (column_name, "_");
+ *type_name++ = '\0';
+ if (g_strcmp0 (type_name, STATE_KEY_SUFF_VISIBLE) == 0)
+ {
+ GtkTreeViewColumn *column = gnc_tree_view_find_column_by_name (view, column_name);
+ if (column)
+ {
+ known = TRUE;
+ if (!g_object_get_data (G_OBJECT (column), ALWAYS_VISIBLE))
+ {
+ gtk_tree_view_column_set_visible (column,
+ g_key_file_get_boolean (state_file, priv->state_section, key, NULL));
+ }
+ }
+ }
+ else if (g_strcmp0 (type_name, STATE_KEY_SUFF_WIDTH) == 0)
+ {
+ gint width = g_key_file_get_integer (state_file, priv->state_section, key, NULL);
+ GtkTreeViewColumn *column = gnc_tree_view_find_column_by_name (view, column_name);
+ if (column)
+ {
+ known = TRUE;
+ if (width && (width != gtk_tree_view_column_get_width (column)))
+ {
+ gtk_tree_view_column_set_fixed_width (column, width);
+ }
+ }
+ }
+ if (!known)
+ DEBUG ("Ignored key %s", key);
+
+ g_free (column_name);
+ }
+ }
+ }
+
/* Rebuild the column visibility menu */
- gnc_tree_view_build_column_menu(view);
- LEAVE("set state section");
+ gnc_tree_view_build_column_menu (view);
+ LEAVE ("set state section");
}
-/** This function is called to get the current association between a
- * state section and the display of a view. It returns the same
- * value passed to gnc_tree_view_set_state_section(); i.e. a string
- * like "dialogs/edit_prices".
+/** Get the name of the state section this tree view is associated with.
+ * It returns the same value passed to gnc_tree_view_set_state_section();
+ * i.e. a string like "dialogs/edit_prices".
*
* Parameters are defined in gnc-tree-view.h
*/
@@ -721,10 +1131,10 @@
{
GncTreeViewPrivate *priv;
- g_return_val_if_fail(GNC_IS_TREE_VIEW(view), NULL);
+ g_return_val_if_fail (GNC_IS_TREE_VIEW (view), NULL);
- priv = GNC_TREE_VIEW_GET_PRIVATE(view);
- return(priv->state_section);
+ priv = GNC_TREE_VIEW_GET_PRIVATE (view);
+ return priv->state_section;
}
@@ -802,7 +1212,7 @@
g_object_set_data (G_OBJECT (widget), "column-binding", binding);
/* Store data on the widget for callbacks */
- key = g_strdup_printf("%s_%s", pref_name, STATE_KEY_VISIBLE);
+ key = g_strdup_printf("%s_%s", pref_name, STATE_KEY_SUFF_VISIBLE);
g_object_set_data_full(G_OBJECT(widget), STATE_KEY, key, g_free);
// LEAVE(" ");
}
More information about the gnucash-changes
mailing list