diff options
author | Matthew Barnes <mbarnes@redhat.com> | 2012-12-10 21:09:59 +0800 |
---|---|---|
committer | Matthew Barnes <mbarnes@redhat.com> | 2012-12-13 03:33:43 +0800 |
commit | d09d8de870b6697c8a8b262e7e077b871a69b315 (patch) | |
tree | 3b718882e7a0bb0a996daf2967a033d91714c9b5 /e-util/e-table-state.c | |
parent | b61331ed03ac1c7a9b8614e25510040b9c60ae02 (diff) | |
download | gsoc2013-evolution-d09d8de870b6697c8a8b262e7e077b871a69b315.tar gsoc2013-evolution-d09d8de870b6697c8a8b262e7e077b871a69b315.tar.gz gsoc2013-evolution-d09d8de870b6697c8a8b262e7e077b871a69b315.tar.bz2 gsoc2013-evolution-d09d8de870b6697c8a8b262e7e077b871a69b315.tar.lz gsoc2013-evolution-d09d8de870b6697c8a8b262e7e077b871a69b315.tar.xz gsoc2013-evolution-d09d8de870b6697c8a8b262e7e077b871a69b315.tar.zst gsoc2013-evolution-d09d8de870b6697c8a8b262e7e077b871a69b315.zip |
Consolidate base utility libraries into libeutil.
Evolution consists of entirely too many small utility libraries, which
increases linking and loading time, places a burden on higher layers of
the application (e.g. modules) which has to remember to link to all the
small in-tree utility libraries, and makes it difficult to generate API
documentation for these utility libraries in one Gtk-Doc module.
Merge the following utility libraries under the umbrella of libeutil,
and enforce a single-include policy on libeutil so we can reorganize
the files as desired without disrupting its pseudo-public API.
libemail-utils/libemail-utils.la
libevolution-utils/libevolution-utils.la
filter/libfilter.la
widgets/e-timezone-dialog/libetimezonedialog.la
widgets/menus/libmenus.la
widgets/misc/libemiscwidgets.la
widgets/table/libetable.la
widgets/text/libetext.la
This also merges libedataserverui from the Evolution-Data-Server module,
since Evolution is its only consumer nowadays, and I'd like to make some
improvements to those APIs without concern for backward-compatibility.
And finally, start a Gtk-Doc module for libeutil. It's going to be a
project just getting all the symbols _listed_ much less _documented_.
But the skeletal structure is in place and I'm off to a good start.
Diffstat (limited to 'e-util/e-table-state.c')
-rw-r--r-- | e-util/e-table-state.c | 320 |
1 files changed, 320 insertions, 0 deletions
diff --git a/e-util/e-table-state.c b/e-util/e-table-state.c new file mode 100644 index 0000000000..e5253be7c9 --- /dev/null +++ b/e-util/e-table-state.c @@ -0,0 +1,320 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Chris Lahey <clahey@ximian.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "e-table-state.h" + +#include <stdlib.h> +#include <string.h> + +#include <libxml/parser.h> +#include <libxml/xmlmemory.h> + +#include <libedataserver/libedataserver.h> + +#include "e-xml-utils.h" + +#define STATE_VERSION 0.1 + +G_DEFINE_TYPE (ETableState, e_table_state, G_TYPE_OBJECT) + +static void +etst_dispose (GObject *object) +{ + ETableState *etst = E_TABLE_STATE (object); + + if (etst->sort_info) { + g_object_unref (etst->sort_info); + etst->sort_info = NULL; + } + + G_OBJECT_CLASS (e_table_state_parent_class)->dispose (object); +} + +static void +etst_finalize (GObject *object) +{ + ETableState *etst = E_TABLE_STATE (object); + + if (etst->columns) { + g_free (etst->columns); + etst->columns = NULL; + } + + if (etst->expansions) { + g_free (etst->expansions); + etst->expansions = NULL; + } + + G_OBJECT_CLASS (e_table_state_parent_class)->finalize (object); +} + +static void +e_table_state_class_init (ETableStateClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->dispose = etst_dispose; + object_class->finalize = etst_finalize; +} + +static void +e_table_state_init (ETableState *state) +{ + state->columns = NULL; + state->expansions = NULL; + state->sort_info = e_table_sort_info_new (); +} + +ETableState * +e_table_state_new (void) +{ + return g_object_new (E_TYPE_TABLE_STATE, NULL); +} + +ETableState * +e_table_state_vanilla (gint col_count) +{ + GString *str; + gint i; + ETableState *res; + + str = g_string_new ("<ETableState>\n"); + for (i = 0; i < col_count; i++) + g_string_append_printf (str, " <column source=\"%d\"/>\n", i); + 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); + + g_string_free (str, TRUE); + return res; +} + +gboolean +e_table_state_load_from_file (ETableState *state, + const gchar *filename) +{ + xmlDoc *doc; + + g_return_val_if_fail (E_IS_TABLE_STATE (state), FALSE); + g_return_val_if_fail (filename != NULL, FALSE); + + doc = e_xml_parse_file (filename); + if (doc) { + xmlNode *node = xmlDocGetRootElement (doc); + e_table_state_load_from_node (state, node); + xmlFreeDoc (doc); + return TRUE; + } + return FALSE; +} + +void +e_table_state_load_from_string (ETableState *state, + const gchar *xml) +{ + xmlDoc *doc; + + g_return_if_fail (E_IS_TABLE_STATE (state)); + g_return_if_fail (xml != NULL); + + doc = xmlParseMemory ((gchar *) xml, strlen (xml)); + if (doc) { + xmlNode *node = xmlDocGetRootElement (doc); + e_table_state_load_from_node (state, node); + xmlFreeDoc (doc); + } +} + +typedef struct { + gint column; + gdouble expansion; +} int_and_double; + +void +e_table_state_load_from_node (ETableState *state, + const xmlNode *node) +{ + xmlNode *children; + GList *list = NULL, *iterator; + gdouble state_version; + gint i; + gboolean can_group = TRUE; + + g_return_if_fail (E_IS_TABLE_STATE (state)); + g_return_if_fail (node != NULL); + + state_version = e_xml_get_double_prop_by_name_with_default ( + node, (const guchar *)"state-version", STATE_VERSION); + + if (state->sort_info) { + can_group = e_table_sort_info_get_can_group (state->sort_info); + g_object_unref (state->sort_info); + } + + state->sort_info = NULL; + children = node->xmlChildrenNode; + for (; children; children = children->next) { + if (!strcmp ((gchar *) children->name, "column")) { + int_and_double *column_info = g_new (int_and_double, 1); + + column_info->column = e_xml_get_integer_prop_by_name ( + children, (const guchar *)"source"); + column_info->expansion = + e_xml_get_double_prop_by_name_with_default ( + children, (const guchar *)"expansion", 1); + + list = g_list_append (list, column_info); + } else if (state->sort_info == NULL && + !strcmp ((gchar *) children->name, "grouping")) { + state->sort_info = e_table_sort_info_new (); + e_table_sort_info_load_from_node ( + state->sort_info, children, state_version); + } + } + g_free (state->columns); + g_free (state->expansions); + state->col_count = g_list_length (list); + state->columns = g_new (int, state->col_count); + state->expansions = g_new (double, state->col_count); + + if (!state->sort_info) + state->sort_info = e_table_sort_info_new (); + e_table_sort_info_set_can_group (state->sort_info, can_group); + + for (iterator = list, i = 0; iterator; i++) { + int_and_double *column_info = iterator->data; + + state->columns[i] = column_info->column; + state->expansions[i] = column_info->expansion; + g_free (column_info); + iterator = g_list_next (iterator); + } + g_list_free (list); +} + +void +e_table_state_save_to_file (ETableState *state, + const gchar *filename) +{ + xmlDoc *doc; + + if ((doc = xmlNewDoc ((const guchar *)"1.0")) == NULL) + return; + + xmlDocSetRootElement (doc, e_table_state_save_to_node (state, NULL)); + + e_xml_save_file (filename, doc); + + xmlFreeDoc (doc); +} + +gchar * +e_table_state_save_to_string (ETableState *state) +{ + gchar *ret_val; + xmlChar *string; + gint length; + xmlDoc *doc; + + g_return_val_if_fail (E_IS_TABLE_STATE (state), NULL); + + doc = xmlNewDoc ((const guchar *)"1.0"); + xmlDocSetRootElement (doc, e_table_state_save_to_node (state, NULL)); + xmlDocDumpMemory (doc, &string, &length); + xmlFreeDoc (doc); + + ret_val = g_strdup ((gchar *) string); + xmlFree (string); + return ret_val; +} + +xmlNode * +e_table_state_save_to_node (ETableState *state, + xmlNode *parent) +{ + gint i; + xmlNode *node; + + g_return_val_if_fail (E_IS_TABLE_STATE (state), NULL); + + if (parent) + node = xmlNewChild ( + parent, NULL, (const guchar *) "ETableState", NULL); + else + node = xmlNewNode (NULL, (const guchar *) "ETableState"); + + e_xml_set_double_prop_by_name ( + node, (const guchar *)"state-version", STATE_VERSION); + + for (i = 0; i < state->col_count; i++) { + gint column = state->columns[i]; + gdouble expansion = state->expansions[i]; + xmlNode *new_node; + + new_node = xmlNewChild ( + node, NULL, (const guchar *) "column", NULL); + e_xml_set_integer_prop_by_name ( + new_node, (const guchar *) "source", column); + if (expansion >= -1) + e_xml_set_double_prop_by_name ( + new_node, (const guchar *) + "expansion", expansion); + } + + e_table_sort_info_save_to_node (state->sort_info, node); + + return node; +} + +/** + * e_table_state_duplicate: + * @state: The ETableState to duplicate + * + * This creates a copy of the %ETableState @state + * + * Returns: The duplicated %ETableState. + */ +ETableState * +e_table_state_duplicate (ETableState *state) +{ + ETableState *new_state; + gchar *copy; + + g_return_val_if_fail (E_IS_TABLE_STATE (state), NULL); + + new_state = e_table_state_new (); + 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)); + + return new_state; +} |