[evolution] Add ETableColumnSelector.



commit c4a37c155a57c99d736dc8ae25ae4b77d0f82024
Author: Matthew Barnes <mbarnes redhat com>
Date:   Mon Jul 1 09:08:12 2013 -0400

    Add ETableColumnSelector.
    
    A new ETable column selection and ordering widget that looks like
    it was written in the 21st century.  Derives from ETreeViewFrame.

 .../evolution-util/evolution-util-docs.sgml        |    1 +
 .../evolution-util/evolution-util-sections.txt     |   20 +
 doc/reference/evolution-util/evolution-util.types  |    1 +
 e-util/Makefile.am                                 |    2 +
 e-util/e-table-column-selector.c                   |  463 ++++++++++++++++++++
 e-util/e-table-column-selector.h                   |   81 ++++
 e-util/e-util.h                                    |    1 +
 7 files changed, 569 insertions(+), 0 deletions(-)
---
diff --git a/doc/reference/evolution-util/evolution-util-docs.sgml 
b/doc/reference/evolution-util/evolution-util-docs.sgml
index 57917bd..a9a889e 100644
--- a/doc/reference/evolution-util/evolution-util-docs.sgml
+++ b/doc/reference/evolution-util/evolution-util-docs.sgml
@@ -114,6 +114,7 @@
     <xi:include href="xml/e-table.xml"/>
     <xi:include href="xml/e-table-click-to-add.xml"/>
     <xi:include href="xml/e-table-col.xml"/>
+    <xi:include href="xml/e-table-column-selector.xml"/>
     <xi:include href="xml/e-table-column-specification.xml"/>
     <xi:include href="xml/e-table-config.xml"/>
     <xi:include href="xml/e-table-extras.xml"/>
diff --git a/doc/reference/evolution-util/evolution-util-sections.txt 
b/doc/reference/evolution-util/evolution-util-sections.txt
index 4337854..79204d8 100644
--- a/doc/reference/evolution-util/evolution-util-sections.txt
+++ b/doc/reference/evolution-util/evolution-util-sections.txt
@@ -3393,6 +3393,26 @@ e_table_col_get_type
 </SECTION>
 
 <SECTION>
+<FILE>e-table-column-selector</FILE>
+<TITLE>ETableColumnSelector</TITLE>
+ETableColumnSelector
+e_table_column_selector_new
+e_table_column_selector_get_state
+e_table_column_selector_apply
+<SUBSECTION Standard>
+E_TABLE_COLUMN_SELECTOR
+E_IS_TABLE_COLUMN_SELECTOR
+E_TYPE_TABLE_COLUMN_SELECTOR
+E_TABLE_COLUMN_SELECTOR_CLASS
+E_IS_TABLE_COLUMN_SELECTOR_CLASS
+E_TABLE_COLUMN_SELECTOR_GET_CLASS
+ETableColumnSelectorClass
+e_table_column_selector_get_type
+<SUBSECTION Private>
+ETableColumnSelectorPrivate
+</SECTION>
+
+<SECTION>
 <FILE>e-table-column-specification</FILE>
 <TITLE>ETableColumnSpecification</TITLE>
 ETableColumnSpecification
diff --git a/doc/reference/evolution-util/evolution-util.types 
b/doc/reference/evolution-util/evolution-util.types
index 764fd3c..576dfcb 100644
--- a/doc/reference/evolution-util/evolution-util.types
+++ b/doc/reference/evolution-util/evolution-util.types
@@ -123,6 +123,7 @@ e_spell_entry_get_type
 e_stock_request_get_type
 e_table_click_to_add_get_type
 e_table_col_get_type
+e_table_column_selector_get_type
 e_table_column_specification_get_type
 e_table_config_get_type
 e_table_extras_get_type
diff --git a/e-util/Makefile.am b/e-util/Makefile.am
index a7123bb..894392a 100644
--- a/e-util/Makefile.am
+++ b/e-util/Makefile.am
@@ -254,6 +254,7 @@ evolution_util_include_HEADERS =  \
        e-table-click-to-add.h \
        e-table-col-dnd.h \
        e-table-col.h \
+       e-table-column-selector.h \
        e-table-column-specification.h \
        e-table-config.h \
        e-table-defines.h \
@@ -499,6 +500,7 @@ libevolution_util_la_SOURCES = \
        e-stock-request.c \
        e-table-click-to-add.c \
        e-table-col.c \
+       e-table-column-selector.c \
        e-table-column-specification.c \
        e-table-config.c \
        e-table-extras.c \
diff --git a/e-util/e-table-column-selector.c b/e-util/e-table-column-selector.c
new file mode 100644
index 0000000..80cceef
--- /dev/null
+++ b/e-util/e-table-column-selector.c
@@ -0,0 +1,463 @@
+/*
+ * e-table-column-selector.c
+ *
+ * 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/>
+ *
+ */
+
+/**
+ * SECTION: e-table-column-selector
+ * @include: e-util/e-util.h
+ * @short_description: Select columns for an #ETable or #ETree
+ *
+ * #ETableColumnSelector is a widget for choosing and ordering the
+ * available columns of an #ETable or #ETree.
+ **/
+
+#include "e-table-column-selector.h"
+
+#include <config.h>
+#include <glib/gi18n-lib.h>
+
+#include "e-util/e-table-specification.h"
+
+#define E_TABLE_COLUMN_SELECTOR_GET_PRIVATE(obj) \
+       (G_TYPE_INSTANCE_GET_PRIVATE \
+       ((obj), E_TYPE_TABLE_COLUMN_SELECTOR, ETableColumnSelectorPrivate))
+
+struct _ETableColumnSelectorPrivate {
+       ETableState *state;
+};
+
+enum {
+       PROP_0,
+       PROP_STATE
+};
+
+enum {
+       COLUMN_ACTIVE,
+       COLUMN_TITLE,
+       COLUMN_SPECIFICATION,
+       COLUMN_EXPANSION,
+       NUM_COLUMNS
+};
+
+G_DEFINE_TYPE (
+       ETableColumnSelector,
+       e_table_column_selector,
+       E_TYPE_TREE_VIEW_FRAME)
+
+static void
+table_column_selector_toggled_cb (GtkCellRendererToggle *renderer,
+                                  const gchar *path_string,
+                                  GtkTreeView *tree_view)
+{
+       GtkTreeModel *tree_model;
+       GtkTreeIter iter;
+       gboolean active;
+
+       tree_model = gtk_tree_view_get_model (tree_view);
+       gtk_tree_model_get_iter_from_string (tree_model, &iter, path_string);
+
+       gtk_tree_model_get (tree_model, &iter, COLUMN_ACTIVE, &active, -1);
+
+       gtk_list_store_set (
+               GTK_LIST_STORE (tree_model),
+               &iter, COLUMN_ACTIVE, !active, -1);
+}
+
+static GtkTreeModel *
+table_column_selector_build_model (ETableColumnSelector *selector)
+{
+       GtkListStore *list_store;
+       GtkTreeIter iter;
+       ETableState *state;
+       ETableSpecification *specification;
+       GPtrArray *columns;
+       GHashTable *columns_added;
+       guint ii;
+
+       state = e_table_column_selector_get_state (selector);
+       specification = e_table_state_ref_specification (state);
+       columns = e_table_specification_ref_columns (specification);
+
+       /* Set of ETableColumnSpecifications to help keep track
+        * of which ones are already added to the list store. */
+       columns_added = g_hash_table_new (NULL, NULL);
+
+       list_store = gtk_list_store_new (
+               NUM_COLUMNS,
+               G_TYPE_BOOLEAN,
+               G_TYPE_STRING,
+               E_TYPE_TABLE_COLUMN_SPECIFICATION,
+               G_TYPE_DOUBLE);
+
+       /* Add selected columns from ETableState first. */
+
+       for (ii = 0; ii < state->col_count; ii++) {
+               ETableColumnSpecification *column_spec;
+               gdouble expansion;
+
+               column_spec = state->column_specs[ii];
+               expansion = state->expansions[ii];
+
+               gtk_list_store_append (list_store, &iter);
+
+               gtk_list_store_set (
+                       list_store, &iter,
+                       COLUMN_ACTIVE, TRUE,
+                       COLUMN_TITLE, column_spec->title,
+                       COLUMN_SPECIFICATION, column_spec,
+                       COLUMN_EXPANSION, expansion,
+                       -1);
+
+               g_hash_table_add (columns_added, column_spec);
+       }
+
+       /* Add the rest of the columns from ETableSpecification. */
+
+       for (ii = 0; ii < columns->len; ii++) {
+               ETableColumnSpecification *column_spec;
+
+               column_spec = g_ptr_array_index (columns, ii);
+
+               if (g_hash_table_contains (columns_added, column_spec))
+                       continue;
+
+               /* XXX We have this unfortunate "disabled" flag because
+                *     past developers made the mistake of having table
+                *     config files reference columns by number instead
+                *     of name so removing a column would break all the
+                *     table config files out in the wild. */
+               if (column_spec->disabled)
+                       continue;
+
+               gtk_list_store_append (list_store, &iter);
+
+               gtk_list_store_set (
+                       list_store, &iter,
+                       COLUMN_ACTIVE, FALSE,
+                       COLUMN_TITLE, column_spec->title,
+                       COLUMN_SPECIFICATION, column_spec,
+                       COLUMN_EXPANSION, 1.0,
+                       -1);
+
+               g_hash_table_add (columns_added, column_spec);
+       }
+
+       g_hash_table_destroy (columns_added);
+
+       g_object_unref (specification);
+       g_ptr_array_unref (columns);
+
+       return GTK_TREE_MODEL (list_store);
+}
+
+static void
+table_column_selector_set_state (ETableColumnSelector *selector,
+                                 ETableState *state)
+{
+       g_return_if_fail (E_IS_TABLE_STATE (state));
+       g_return_if_fail (selector->priv->state == NULL);
+
+       selector->priv->state = g_object_ref (state);
+}
+
+static void
+table_column_selector_set_property (GObject *object,
+                                    guint property_id,
+                                    const GValue *value,
+                                    GParamSpec *pspec)
+{
+       switch (property_id) {
+               case PROP_STATE:
+                       table_column_selector_set_state (
+                               E_TABLE_COLUMN_SELECTOR (object),
+                               g_value_get_object (value));
+                       return;
+       }
+
+       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+table_column_selector_get_property (GObject *object,
+                                    guint property_id,
+                                    GValue *value,
+                                    GParamSpec *pspec)
+{
+       switch (property_id) {
+               case PROP_STATE:
+                       g_value_set_object (
+                               value,
+                               e_table_column_selector_get_state (
+                               E_TABLE_COLUMN_SELECTOR (object)));
+                       return;
+       }
+
+       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+table_column_selector_dispose (GObject *object)
+{
+       ETableColumnSelectorPrivate *priv;
+
+       priv = E_TABLE_COLUMN_SELECTOR_GET_PRIVATE (object);
+
+       g_clear_object (&priv->state);
+
+       /* Chain up to parent's dispose() method. */
+       G_OBJECT_CLASS (e_table_column_selector_parent_class)->
+               dispose (object);
+}
+
+static void
+table_column_selector_constructed (GObject *object)
+{
+       ETableColumnSelector *selector;
+       ETreeViewFrame *tree_view_frame;
+       GtkAction *action;
+       GtkTreeView *tree_view;
+       GtkTreeModel *tree_model;
+       GtkTreeSelection *selection;
+       GtkTreeViewColumn *column;
+       GtkCellRenderer *renderer;
+       const gchar *tooltip;
+
+       selector = E_TABLE_COLUMN_SELECTOR (object);
+
+       /* Chain up to parent's constructed() method. */
+       G_OBJECT_CLASS (e_table_column_selector_parent_class)->
+               constructed (object);
+
+       tree_view_frame = E_TREE_VIEW_FRAME (object);
+       tree_view = e_tree_view_frame_get_tree_view (tree_view_frame);
+
+       gtk_tree_view_set_reorderable (tree_view, TRUE);
+       gtk_tree_view_set_headers_visible (tree_view, FALSE);
+
+       selection = gtk_tree_view_get_selection (tree_view);
+       gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
+
+       /* Configure the toolbar actions. */
+
+       action = e_tree_view_frame_lookup_toolbar_action (
+               tree_view_frame, E_TREE_VIEW_FRAME_ACTION_ADD);
+       gtk_action_set_visible (action, FALSE);
+
+       action = e_tree_view_frame_lookup_toolbar_action (
+               tree_view_frame, E_TREE_VIEW_FRAME_ACTION_REMOVE);
+       gtk_action_set_visible (action, FALSE);
+
+       action = e_tree_view_frame_lookup_toolbar_action (
+               tree_view_frame, E_TREE_VIEW_FRAME_ACTION_MOVE_TOP);
+       tooltip = _("Move selected column names to top");
+       gtk_action_set_tooltip (action, tooltip);
+
+       action = e_tree_view_frame_lookup_toolbar_action (
+               tree_view_frame, E_TREE_VIEW_FRAME_ACTION_MOVE_UP);
+       tooltip = _("Move selected column names up one row");
+       gtk_action_set_tooltip (action, tooltip);
+
+       action = e_tree_view_frame_lookup_toolbar_action (
+               tree_view_frame, E_TREE_VIEW_FRAME_ACTION_MOVE_DOWN);
+       tooltip = _("Move selected column names down one row");
+       gtk_action_set_tooltip (action, tooltip);
+
+       action = e_tree_view_frame_lookup_toolbar_action (
+               tree_view_frame, E_TREE_VIEW_FRAME_ACTION_MOVE_BOTTOM);
+       tooltip = _("Move selected column names to bottom");
+       gtk_action_set_tooltip (action, tooltip);
+
+       action = e_tree_view_frame_lookup_toolbar_action (
+               tree_view_frame, E_TREE_VIEW_FRAME_ACTION_SELECT_ALL);
+       tooltip = _("Select all column names");
+       gtk_action_set_tooltip (action, tooltip);
+
+       /* Configure the tree view columns. */
+
+       column = gtk_tree_view_column_new ();
+       renderer = gtk_cell_renderer_toggle_new ();
+       gtk_tree_view_column_pack_start (column, renderer, FALSE);
+       gtk_tree_view_column_add_attribute (
+               column, renderer, "active", COLUMN_ACTIVE);
+       gtk_tree_view_append_column (tree_view, column);
+
+       g_signal_connect (
+               renderer, "toggled",
+               G_CALLBACK (table_column_selector_toggled_cb),
+               tree_view);
+
+       column = gtk_tree_view_column_new ();
+       renderer = gtk_cell_renderer_text_new ();
+       gtk_tree_view_column_pack_start (column, renderer, FALSE);
+       gtk_tree_view_column_add_attribute (
+               column, renderer, "text", COLUMN_TITLE);
+       gtk_tree_view_append_column (tree_view, column);
+
+       /* Create and populate the tree model. */
+
+       tree_model = table_column_selector_build_model (selector);
+       gtk_tree_view_set_model (tree_view, tree_model);
+       g_object_unref (tree_model);
+}
+
+static void
+e_table_column_selector_class_init (ETableColumnSelectorClass *class)
+{
+       GObjectClass *object_class;
+
+       g_type_class_add_private (class, sizeof (ETableColumnSelectorPrivate));
+
+       object_class = G_OBJECT_CLASS (class);
+       object_class->set_property = table_column_selector_set_property;
+       object_class->get_property = table_column_selector_get_property;
+       object_class->dispose = table_column_selector_dispose;
+       object_class->constructed = table_column_selector_constructed;
+
+       g_object_class_install_property (
+               object_class,
+               PROP_STATE,
+               g_param_spec_object (
+                       "state",
+                       "Table State",
+                       "Column state of the source table",
+                       E_TYPE_TABLE_STATE,
+                       G_PARAM_READWRITE |
+                       G_PARAM_CONSTRUCT_ONLY |
+                       G_PARAM_STATIC_STRINGS));
+}
+
+static void
+e_table_column_selector_init (ETableColumnSelector *selector)
+{
+       selector->priv = E_TABLE_COLUMN_SELECTOR_GET_PRIVATE (selector);
+}
+
+/**
+ * e_table_column_selector_new:
+ * @state: an #ETableState
+ *
+ * Creates a new #ETableColumnSelector, obtaining the initial column
+ * selection content from @state.
+ *
+ * Note that @state remains unmodified until e_table_column_selector_apply()
+ * is called.
+ *
+ * Returns: an #ETableColumnSelector
+ **/
+GtkWidget *
+e_table_column_selector_new (ETableState *state)
+{
+       g_return_val_if_fail (E_IS_TABLE_STATE (state), NULL);
+
+       return g_object_new (
+               E_TYPE_TABLE_COLUMN_SELECTOR,
+               "state", state, NULL);
+}
+
+/**
+ * e_table_column_selector_get_state:
+ * @selector: an #ETableColumnSelector
+ *
+ * Returns the #ETableState passed to e_table_column_selector_new().
+ *
+ * Returns: an #ETableState
+ **/
+ETableState *
+e_table_column_selector_get_state (ETableColumnSelector *selector)
+{
+       g_return_val_if_fail (E_IS_TABLE_COLUMN_SELECTOR (selector), NULL);
+
+       return selector->priv->state;
+}
+
+/**
+ * e_table_column_selector_apply:
+ * @selector: an #ETableColumnSelector
+ *
+ * Applies the user's column preferences to the @selector's
+ * #ETableColumnSelector:state instance.
+ **/
+void
+e_table_column_selector_apply (ETableColumnSelector *selector)
+{
+       ETableState *state;
+       ETreeViewFrame *tree_view_frame;
+       GtkTreeView *tree_view;
+       GtkTreeModel *tree_model;
+       GArray *active_iters;
+       GtkTreeIter iter;
+       gboolean iter_valid;
+       guint ii;
+
+       g_return_if_fail (E_IS_TABLE_COLUMN_SELECTOR (selector));
+
+       tree_view_frame = E_TREE_VIEW_FRAME (selector);
+       tree_view = e_tree_view_frame_get_tree_view (tree_view_frame);
+       tree_model = gtk_tree_view_get_model (tree_view);
+
+       /* Collect all the "active" rows into an array of iterators. */
+
+       active_iters = g_array_new (FALSE, TRUE, sizeof (GtkTreeIter));
+
+       iter_valid = gtk_tree_model_get_iter_first (tree_model, &iter);
+
+       while (iter_valid) {
+               gboolean active;
+
+               gtk_tree_model_get (
+                       tree_model, &iter, COLUMN_ACTIVE, &active, -1);
+
+               if (active)
+                       g_array_append_val (active_iters, iter);
+
+               iter_valid = gtk_tree_model_iter_next (tree_model, &iter);
+       }
+
+       /* Reconstruct the ETableState from the array of iterators. */
+
+       state = e_table_column_selector_get_state (selector);
+
+       for (ii = 0; ii < state->col_count; ii++)
+               g_object_unref (state->column_specs[ii]);
+       g_free (state->column_specs);
+       g_free (state->expansions);
+
+       state->col_count = active_iters->len;
+       state->column_specs = g_new0 (
+               ETableColumnSpecification *, active_iters->len);
+       state->expansions = g_new0 (gdouble, active_iters->len);
+
+       for (ii = 0; ii < active_iters->len; ii++) {
+               ETableColumnSpecification *column_spec;
+               gdouble expansion;
+
+               iter = g_array_index (active_iters, GtkTreeIter, ii);
+
+               gtk_tree_model_get (
+                       tree_model, &iter,
+                       COLUMN_SPECIFICATION, &column_spec,
+                       COLUMN_EXPANSION, &expansion,
+                       -1);
+
+               state->column_specs[ii] = g_object_ref (column_spec);
+               state->expansions[ii] = expansion;
+
+               g_object_unref (column_spec);
+       }
+
+       g_array_free (active_iters, TRUE);
+}
diff --git a/e-util/e-table-column-selector.h b/e-util/e-table-column-selector.h
new file mode 100644
index 0000000..810b370
--- /dev/null
+++ b/e-util/e-table-column-selector.h
@@ -0,0 +1,81 @@
+/*
+ * e-table-column-selector.h
+ *
+ * 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/>
+ *
+ */
+
+#if !defined (__E_UTIL_H_INSIDE__) && !defined (LIBEUTIL_COMPILATION)
+#error "Only <e-util/e-util.h> should be included directly."
+#endif
+
+#ifndef E_TABLE_COLUMN_SELECTOR_H
+#define E_TABLE_COLUMN_SELECTOR_H
+
+#include <e-util/e-table-state.h>
+#include <e-util/e-tree-view-frame.h>
+
+/* Standard GObject macros */
+#define E_TYPE_TABLE_COLUMN_SELECTOR \
+       (e_table_column_selector_get_type ())
+#define E_TABLE_COLUMN_SELECTOR(obj) \
+       (G_TYPE_CHECK_INSTANCE_CAST \
+       ((obj), E_TYPE_TABLE_COLUMN_SELECTOR, ETableColumnSelector))
+#define E_TABLE_COLUMN_SELECTOR_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_CAST \
+       ((cls), E_TYPE_TABLE_COLUMN_SELECTOR, ETableColumnSelectorClass))
+#define E_IS_TABLE_COLUMN_SELECTOR(obj) \
+       (G_TYPE_CHECK_INSTANCE_TYPE \
+       ((obj), E_TYPE_TABLE_COLUMN_SELECTOR))
+#define E_IS_TABLE_COLUMN_SELECTOR_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_TYPE \
+       ((cls), E_TYPE_TABLE_COLUMN_SELECTOR))
+#define E_TABLE_COLUMN_SELECTOR_GET_CLASS(obj) \
+       (G_TYPE_INSTANCE_GET_CLASS \
+       ((obj), E_TYPE_TABLE_COLUMN_SELECTOR, ETableColumnSelectorClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ETableColumnSelector ETableColumnSelector;
+typedef struct _ETableColumnSelectorClass ETableColumnSelectorClass;
+typedef struct _ETableColumnSelectorPrivate ETableColumnSelectorPrivate;
+
+/**
+ * ETableColumnSelector:
+ *
+ * Contains only private data that should be read and manipulated using the
+ * functions below.
+ **/
+struct _ETableColumnSelector {
+       ETreeViewFrame parent;
+       ETableColumnSelectorPrivate *priv;
+};
+
+struct _ETableColumnSelectorClass {
+       ETreeViewFrameClass parent_class;
+};
+
+GType          e_table_column_selector_get_type
+                                       (void) G_GNUC_CONST;
+GtkWidget *    e_table_column_selector_new
+                                       (ETableState *state);
+ETableState *  e_table_column_selector_get_state
+                                       (ETableColumnSelector *selector);
+void           e_table_column_selector_apply
+                                       (ETableColumnSelector *selector);
+
+G_END_DECLS
+
+#endif /* E_TABLE_COLUMN_SELECTOR_H */
+
diff --git a/e-util/e-util.h b/e-util/e-util.h
index 980c279..eef8830 100644
--- a/e-util/e-util.h
+++ b/e-util/e-util.h
@@ -169,6 +169,7 @@
 #include <e-util/e-table-click-to-add.h>
 #include <e-util/e-table-col-dnd.h>
 #include <e-util/e-table-col.h>
+#include <e-util/e-table-column-selector.h>
 #include <e-util/e-table-column-specification.h>
 #include <e-util/e-table-config.h>
 #include <e-util/e-table-defines.h>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]