aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/reference/evolution-util/evolution-util-sections.txt1
-rw-r--r--e-util/e-table-specification.c31
-rw-r--r--e-util/e-table-state.c125
-rw-r--r--e-util/e-table-state.h9
-rw-r--r--e-util/e-table.c10
-rw-r--r--e-util/e-tree.c8
-rw-r--r--e-util/gal-view-etable.c9
-rw-r--r--mail/e-mail-paned-view.c2
8 files changed, 145 insertions, 50 deletions
diff --git a/doc/reference/evolution-util/evolution-util-sections.txt b/doc/reference/evolution-util/evolution-util-sections.txt
index 25fada5207..d5193113b4 100644
--- a/doc/reference/evolution-util/evolution-util-sections.txt
+++ b/doc/reference/evolution-util/evolution-util-sections.txt
@@ -3933,6 +3933,7 @@ e_table_specification_get_type
ETableState
e_table_state_new
e_table_state_vanilla
+e_table_state_ref_specification
e_table_state_load_from_file
e_table_state_load_from_string
e_table_state_load_from_node
diff --git a/e-util/e-table-specification.c b/e-util/e-table-specification.c
index 713e0575d5..03c160ba74 100644
--- a/e-util/e-table-specification.c
+++ b/e-util/e-table-specification.c
@@ -187,8 +187,8 @@ e_table_specification_load_from_node (ETableSpecification *specification,
{
gchar *temp;
xmlNode *children;
- GList *list = NULL, *list2;
- gint i;
+ GQueue columns = G_QUEUE_INIT;
+ guint ii = 0;
specification->no_headers = e_xml_get_bool_prop_by_name (node, (const guchar *)"no-headers");
specification->click_to_add = e_xml_get_bool_prop_by_name (node, (const guchar *)"click-to-add");
@@ -244,8 +244,8 @@ e_table_specification_load_from_node (ETableSpecification *specification,
g_object_unref (specification->state);
specification->state = NULL;
if (specification->columns) {
- for (i = 0; specification->columns[i]; i++) {
- g_object_unref (specification->columns[i]);
+ for (ii = 0; specification->columns[ii] != NULL; ii++) {
+ g_object_unref (specification->columns[ii]);
}
g_free (specification->columns);
}
@@ -256,24 +256,23 @@ e_table_specification_load_from_node (ETableSpecification *specification,
ETableColumnSpecification *col_spec = e_table_column_specification_new ();
e_table_column_specification_load_from_node (col_spec, children);
- list = g_list_append (list, col_spec);
+ g_queue_push_tail (&columns, col_spec);
} else if (specification->state == NULL && !strcmp ((gchar *) children->name, "ETableState")) {
- specification->state = e_table_state_new ();
+ specification->state = e_table_state_new (specification);
e_table_state_load_from_node (specification->state, children);
e_table_sort_info_set_can_group (specification->state->sort_info, specification->allow_grouping);
}
}
- if (specification->state == NULL) {
- /* Make the default state. */
- specification->state = e_table_state_vanilla (g_list_length (list));
- }
+ ii = 0;
+ specification->columns = g_new0 (
+ ETableColumnSpecification *,
+ g_queue_get_length (&columns) + 1);
+ while (!g_queue_is_empty (&columns))
+ specification->columns[ii++] = g_queue_pop_head (&columns);
- specification->columns = g_new (ETableColumnSpecification *, g_list_length (list) + 1);
- for (list2 = list, i = 0; list2; list2 = g_list_next (list2), i++) {
- specification->columns[i] = list2->data;
- }
- specification->columns[i] = NULL;
- g_list_free (list);
+ /* e_table_state_vanilla() uses the columns array we just created. */
+ if (specification->state == NULL)
+ specification->state = e_table_state_vanilla (specification);
}
diff --git a/e-util/e-table-state.c b/e-util/e-table-state.c
index cbde70b554..77903c7ac8 100644
--- a/e-util/e-table-state.c
+++ b/e-util/e-table-state.c
@@ -26,6 +26,7 @@
#include <libedataserver/libedataserver.h>
+#include "e-table-specification.h"
#include "e-xml-utils.h"
#define E_TABLE_STATE_GET_PRIVATE(obj) \
@@ -35,17 +36,67 @@
#define STATE_VERSION 0.1
struct _ETableStatePrivate {
- gint placeholder;
+ GWeakRef specification;
+};
+
+enum {
+ PROP_0,
+ PROP_SPECIFICATION
};
G_DEFINE_TYPE (ETableState, e_table_state, G_TYPE_OBJECT)
static void
+table_state_set_specification (ETableState *state,
+ ETableSpecification *specification)
+{
+ g_return_if_fail (E_IS_TABLE_SPECIFICATION (specification));
+
+ g_weak_ref_set (&state->priv->specification, specification);
+}
+
+static void
+table_state_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SPECIFICATION:
+ table_state_set_specification (
+ E_TABLE_STATE (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+table_state_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SPECIFICATION:
+ g_value_take_object (
+ value,
+ e_table_state_ref_specification (
+ E_TABLE_STATE (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
table_state_dispose (GObject *object)
{
ETableState *state = E_TABLE_STATE (object);
g_clear_object (&state->sort_info);
+ g_weak_ref_set (&state->priv->specification, NULL);
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (e_table_state_parent_class)->dispose (object);
@@ -83,9 +134,23 @@ e_table_state_class_init (ETableStateClass *class)
g_type_class_add_private (class, sizeof (ETableStatePrivate));
object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = table_state_set_property;
+ object_class->get_property = table_state_get_property;
object_class->dispose = table_state_dispose;
object_class->finalize = table_state_finalize;
object_class->constructed = table_state_constructed;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SPECIFICATION,
+ g_param_spec_object (
+ "specification",
+ "Table Specification",
+ "Specification for the table state",
+ E_TYPE_TABLE_SPECIFICATION,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
}
static void
@@ -95,29 +160,56 @@ e_table_state_init (ETableState *state)
}
ETableState *
-e_table_state_new (void)
+e_table_state_new (ETableSpecification *specification)
{
- return g_object_new (E_TYPE_TABLE_STATE, NULL);
+ g_return_val_if_fail (E_IS_TABLE_SPECIFICATION (specification), NULL);
+
+ return g_object_new (
+ E_TYPE_TABLE_STATE,
+ "specification", specification, NULL);
}
ETableState *
-e_table_state_vanilla (gint col_count)
+e_table_state_vanilla (ETableSpecification *specification)
{
+ ETableState *state;
GString *str;
- gint i;
- ETableState *res;
+ gint ii;
+
+ g_return_val_if_fail (E_IS_TABLE_SPECIFICATION (specification), NULL);
+ g_return_val_if_fail (specification->columns != NULL, NULL);
str = g_string_new ("<ETableState>\n");
- for (i = 0; i < col_count; i++)
- g_string_append_printf (str, " <column source=\"%d\"/>\n", i);
+ for (ii = 0; specification->columns[ii] != NULL; ii++)
+ g_string_append_printf (str, " <column source=\"%d\"/>\n", ii);
g_string_append (str, " <grouping></grouping>\n");
g_string_append (str, "</ETableState>\n");
- res = e_table_state_new ();
- e_table_state_load_from_string (res, str->str);
+ state = e_table_state_new (specification);
+ e_table_state_load_from_string (state, str->str);
g_string_free (str, TRUE);
- return res;
+
+ return state;
+}
+
+/**
+ * e_table_state_ref_specification:
+ * @state: an #ETableState
+ *
+ * Returns the #ETableSpecification passed to e_table_state_new().
+ *
+ * The returned #ETableSpecification is referenced for thread-safety and must
+ * be unreferenced with g_object_unref() when finished with it.
+ *
+ * Returns: an #ETableSpecification
+ **/
+ETableSpecification *
+e_table_state_ref_specification (ETableState *state)
+{
+ g_return_val_if_fail (E_IS_TABLE_STATE (state), NULL);
+
+ return g_weak_ref_get (&state->priv->specification);
}
gboolean
@@ -317,19 +409,22 @@ ETableState *
e_table_state_duplicate (ETableState *state)
{
ETableState *new_state;
+ ETableSpecification *specification;
+ gboolean can_group;
gchar *copy;
g_return_val_if_fail (E_IS_TABLE_STATE (state), NULL);
- new_state = e_table_state_new ();
+ specification = e_table_state_ref_specification (state);
+ new_state = e_table_state_new (specification);
+ g_object_unref (specification);
copy = e_table_state_save_to_string (state);
e_table_state_load_from_string (new_state, copy);
g_free (copy);
- e_table_sort_info_set_can_group
- (new_state->sort_info,
- e_table_sort_info_get_can_group (state->sort_info));
+ can_group = e_table_sort_info_get_can_group (state->sort_info);
+ e_table_sort_info_set_can_group (new_state->sort_info, can_group);
return new_state;
}
diff --git a/e-util/e-table-state.h b/e-util/e-table-state.h
index 27bda8440e..cd5d3e97fe 100644
--- a/e-util/e-table-state.h
+++ b/e-util/e-table-state.h
@@ -48,6 +48,9 @@
G_BEGIN_DECLS
+/* Avoid a circular dependency. */
+struct _ETableSpecification;
+
typedef struct _ETableState ETableState;
typedef struct _ETableStateClass ETableStateClass;
typedef struct _ETableStatePrivate ETableStatePrivate;
@@ -67,8 +70,10 @@ struct _ETableStateClass {
};
GType e_table_state_get_type (void) G_GNUC_CONST;
-ETableState * e_table_state_new (void);
-ETableState * e_table_state_vanilla (gint col_count);
+ETableState * e_table_state_new (struct _ETableSpecification *specification);
+ETableState * e_table_state_vanilla (struct _ETableSpecification *specification);
+struct _ETableSpecification *
+ e_table_state_ref_specification (ETableState *state);
gboolean e_table_state_load_from_file (ETableState *state,
const gchar *filename);
void e_table_state_load_from_string (ETableState *state,
diff --git a/e-util/e-table.c b/e-util/e-table.c
index a4c809a99c..24ee13f38c 100644
--- a/e-util/e-table.c
+++ b/e-util/e-table.c
@@ -1625,7 +1625,7 @@ e_table_set_state (ETable *e_table,
g_return_if_fail (E_IS_TABLE (e_table));
g_return_if_fail (state_str != NULL);
- state = e_table_state_new ();
+ state = e_table_state_new (e_table->spec);
e_table_state_load_from_string (state, state_str);
if (state->col_count > 0)
@@ -1651,7 +1651,7 @@ e_table_load_state (ETable *e_table,
g_return_if_fail (E_IS_TABLE (e_table));
g_return_if_fail (filename != NULL);
- state = e_table_state_new ();
+ state = e_table_state_new (e_table->spec);
e_table_state_load_from_file (state, filename);
if (state->col_count > 0)
@@ -1677,7 +1677,7 @@ e_table_get_state_object (ETable *e_table)
gint full_col_count;
gint i, j;
- state = e_table_state_new ();
+ state = e_table_state_new (e_table->spec);
if (state->sort_info)
g_object_unref (state->sort_info);
state->sort_info = e_table->sort_info;
@@ -1924,7 +1924,7 @@ e_table_construct (ETable *e_table,
}
if (state_str) {
- state = e_table_state_new ();
+ state = e_table_state_new (specification);
g_object_ref (state);
e_table_state_load_from_string (state, state_str);
if (state->col_count <= 0) {
@@ -1982,7 +1982,7 @@ e_table_construct_from_spec_file (ETable *e_table,
}
if (state_fn) {
- state = e_table_state_new ();
+ state = e_table_state_new (specification);
if (!e_table_state_load_from_file (state, state_fn)) {
g_object_unref (state);
state = specification->state;
diff --git a/e-util/e-tree.c b/e-util/e-tree.c
index d8fb95e6d2..91caea7c43 100644
--- a/e-util/e-tree.c
+++ b/e-util/e-tree.c
@@ -1355,7 +1355,7 @@ e_tree_set_state (ETree *tree,
g_return_if_fail (E_IS_TREE (tree));
g_return_if_fail (state_str != NULL);
- state = e_table_state_new ();
+ state = e_table_state_new (tree->priv->spec);
e_table_state_load_from_string (state, state_str);
if (state->col_count > 0)
@@ -1381,7 +1381,7 @@ e_tree_get_state_object (ETree *tree)
gint full_col_count;
gint i, j;
- state = e_table_state_new ();
+ state = e_table_state_new (tree->priv->spec);
state->sort_info = tree->priv->sort_info;
if (state->sort_info)
g_object_ref (state->sort_info);
@@ -1646,7 +1646,7 @@ e_tree_construct (ETree *tree,
return FALSE;
}
if (state_str) {
- state = e_table_state_new ();
+ state = e_table_state_new (specification);
e_table_state_load_from_string (state, state_str);
if (state->col_count <= 0) {
g_object_unref (state);
@@ -1707,7 +1707,7 @@ e_tree_construct_from_spec_file (ETree *tree,
return FALSE;
}
if (state_fn) {
- state = e_table_state_new ();
+ state = e_table_state_new (specification);
if (!e_table_state_load_from_file (state, state_fn)) {
g_object_unref (state);
state = specification->state;
diff --git a/e-util/gal-view-etable.c b/e-util/gal-view-etable.c
index 3f50e2881a..1dc8f5d357 100644
--- a/e-util/gal-view-etable.c
+++ b/e-util/gal-view-etable.c
@@ -137,13 +137,10 @@ gal_view_etable_clone (GalView *view)
gve = GAL_VIEW_ETABLE (view);
new = g_object_new (GAL_TYPE_VIEW_ETABLE, NULL);
- new->spec = gve->spec;
+ new->spec = g_object_ref (gve->spec);
new->title = g_strdup (gve->title);
- g_object_unref (new->state);
new->state = e_table_state_duplicate (gve->state);
- g_object_ref (new->spec);
-
return GAL_VIEW (new);
}
@@ -189,9 +186,6 @@ gal_view_etable_class_init (GalViewEtableClass *class)
static void
gal_view_etable_init (GalViewEtable *gve)
{
- gve->spec = NULL;
- gve->state = e_table_state_new ();
- gve->title = NULL;
}
/**
@@ -237,6 +231,7 @@ gal_view_etable_construct (GalViewEtable *view,
g_return_val_if_fail (E_IS_TABLE_SPECIFICATION (spec), NULL);
view->spec = g_object_ref (spec);
+ view->state = e_table_state_new (spec);
if (view->state)
g_object_unref (view->state);
diff --git a/mail/e-mail-paned-view.c b/mail/e-mail-paned-view.c
index 67cf5b90b1..c491db7150 100644
--- a/mail/e-mail-paned-view.c
+++ b/mail/e-mail-paned-view.c
@@ -934,7 +934,7 @@ mail_paned_view_update_view_instance (EMailView *view)
spec, spec_filename);
g_free (spec_filename);
- state = e_table_state_new ();
+ state = e_table_state_new (spec);
view = gal_view_etable_new (spec, "");
e_table_state_load_from_file (