From 2a2933ec5cdc0d7afd9b8da5f9146c5d7f1630df Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Fri, 17 Dec 2010 17:45:54 -0500 Subject: Add ESourceConfig widget. Base class for building address book and calendar configuration dialogs. --- widgets/misc/e-source-notebook.c | 359 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 359 insertions(+) create mode 100644 widgets/misc/e-source-notebook.c (limited to 'widgets/misc/e-source-notebook.c') diff --git a/widgets/misc/e-source-notebook.c b/widgets/misc/e-source-notebook.c new file mode 100644 index 0000000000..08d4490839 --- /dev/null +++ b/widgets/misc/e-source-notebook.c @@ -0,0 +1,359 @@ +/* + * e-source-notebook.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 + * + */ + +#include "e-source-notebook.h" + +#define E_SOURCE_NOTEBOOK_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_SOURCE_NOTEBOOK, ESourceNotebookPrivate)) + +#define CHILD_SOURCE_KEY_FORMAT "__e_source_notebook_%p_child_source__" + +struct _ESourceNotebookPrivate { + ESource *active_source; + gchar *child_source_key; +}; + +enum { + PROP_0, + PROP_ACTIVE_SOURCE +}; + +enum { + PROP_CHILD_0, + PROP_CHILD_SOURCE +}; + +G_DEFINE_TYPE ( + ESourceNotebook, + e_source_notebook, + GTK_TYPE_NOTEBOOK) + +static void +source_notebook_set_child_source (ESourceNotebook *notebook, + GtkWidget *child, + ESource *source) +{ + const gchar *key; + + key = notebook->priv->child_source_key; + + if (E_IS_SOURCE (source)) + g_object_set_data_full ( + G_OBJECT (child), key, + g_object_ref (source), + (GDestroyNotify) g_object_unref); + else + g_object_set_data (G_OBJECT (child), key, NULL); +} + +static ESource * +source_notebook_get_child_source (ESourceNotebook *notebook, + GtkWidget *child) +{ + const gchar *key; + + key = notebook->priv->child_source_key; + + return g_object_get_data (G_OBJECT (child), key); +} + +static gboolean +source_notebook_page_num_to_source (GBinding *binding, + const GValue *source_value, + GValue *target_value, + gpointer user_data) +{ + GtkNotebook *notebook; + GtkWidget *child; + ESource *source; + gint page_num; + + /* The binding's source and target are the same instance. */ + notebook = GTK_NOTEBOOK (g_binding_get_source (binding)); + + page_num = g_value_get_int (source_value); + child = gtk_notebook_get_nth_page (notebook, page_num); + + if (child != NULL) + source = source_notebook_get_child_source ( + E_SOURCE_NOTEBOOK (notebook), child); + else + source = NULL; + + g_value_set_object (target_value, source); + + return TRUE; +} + +static gboolean +source_notebook_source_to_page_num (GBinding *binding, + const GValue *source_value, + GValue *target_value, + gpointer user_data) +{ + GtkNotebook *notebook; + ESource *source; + gint n_pages, ii; + + /* The binding's source and target are the same instance. */ + notebook = GTK_NOTEBOOK (g_binding_get_source (binding)); + + source = g_value_get_object (source_value); + n_pages = gtk_notebook_get_n_pages (notebook); + + for (ii = 0; ii < n_pages; ii++) { + GtkWidget *child; + ESource *candidate; + + child = gtk_notebook_get_nth_page (notebook, ii); + candidate = source_notebook_get_child_source ( + E_SOURCE_NOTEBOOK (notebook), child); + + if (e_source_equal (source, candidate)) { + g_value_set_int (target_value, ii); + return TRUE; + } + } + + return FALSE; +} + +static void +source_notebook_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_ACTIVE_SOURCE: + e_source_notebook_set_active_source ( + E_SOURCE_NOTEBOOK (object), + g_value_get_object (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +source_notebook_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_ACTIVE_SOURCE: + g_value_set_object ( + value, + e_source_notebook_get_active_source ( + E_SOURCE_NOTEBOOK (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +source_notebook_dispose (GObject *object) +{ + ESourceNotebookPrivate *priv; + + priv = E_SOURCE_NOTEBOOK_GET_PRIVATE (object); + + if (priv->active_source != NULL) { + g_object_unref (priv->active_source); + priv->active_source = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (e_source_notebook_parent_class)->dispose (object); +} + +static void +source_notebook_finalize (GObject *object) +{ + ESourceNotebookPrivate *priv; + + priv = E_SOURCE_NOTEBOOK_GET_PRIVATE (object); + + g_free (priv->child_source_key); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (e_source_notebook_parent_class)->finalize (object); +} + +static void +source_notebook_constructed (GObject *object) +{ + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (e_source_notebook_parent_class)->constructed (object); + + gtk_notebook_set_show_tabs (GTK_NOTEBOOK (object), FALSE); + + /* Current page is still -1 so skip G_BINDING_SYNC_CREATE. */ + g_object_bind_property_full ( + object, "page", + object, "active-source", + G_BINDING_BIDIRECTIONAL, + source_notebook_page_num_to_source, + source_notebook_source_to_page_num, + NULL, (GDestroyNotify) NULL); +} + +static void +source_notebook_set_child_property (GtkContainer *container, + GtkWidget *child, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_CHILD_SOURCE: + source_notebook_set_child_source ( + E_SOURCE_NOTEBOOK (container), + child, g_value_get_object (value)); + return; + } + + GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID ( + container, property_id, pspec); +} + +static void +source_notebook_get_child_property (GtkContainer *container, + GtkWidget *child, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_CHILD_SOURCE: + g_value_set_object ( + value, + source_notebook_get_child_source ( + E_SOURCE_NOTEBOOK (container), child)); + return; + } + + GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID ( + container, property_id, pspec); +} + +static void +e_source_notebook_class_init (ESourceNotebookClass *class) +{ + GObjectClass *object_class; + GtkContainerClass *container_class; + + g_type_class_add_private (class, sizeof (ESourceNotebookPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = source_notebook_set_property; + object_class->get_property = source_notebook_get_property; + object_class->dispose = source_notebook_dispose; + object_class->finalize = source_notebook_finalize; + object_class->constructed = source_notebook_constructed; + + container_class = GTK_CONTAINER_CLASS (class); + container_class->set_child_property = source_notebook_set_child_property; + container_class->get_child_property = source_notebook_get_child_property; + + g_object_class_install_property ( + object_class, + PROP_ACTIVE_SOURCE, + g_param_spec_object ( + "active-source", + "Active Source", + "The data source for the current page", + E_TYPE_SOURCE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /* Child property for notebook pages. */ + gtk_container_class_install_child_property ( + container_class, + PROP_CHILD_SOURCE, + g_param_spec_object ( + "source", + "Source", + "The data source for this page", + E_TYPE_SOURCE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); +} + +static void +e_source_notebook_init (ESourceNotebook *notebook) +{ + gchar *key; + + notebook->priv = E_SOURCE_NOTEBOOK_GET_PRIVATE (notebook); + + key = g_strdup_printf (CHILD_SOURCE_KEY_FORMAT, notebook); + notebook->priv->child_source_key = key; +} + +GtkWidget * +e_source_notebook_new (void) +{ + return g_object_new (E_TYPE_SOURCE_NOTEBOOK, NULL); +} + +gint +e_source_notebook_add_page (ESourceNotebook *notebook, + ESource *source, + GtkWidget *child) +{ + g_return_val_if_fail (E_IS_SOURCE_NOTEBOOK (notebook), -1); + g_return_val_if_fail (E_IS_SOURCE (source), -1); + g_return_val_if_fail (GTK_IS_WIDGET (child), -1); + + gtk_widget_show (child); + source_notebook_set_child_source (notebook, child, source); + + return gtk_notebook_append_page (GTK_NOTEBOOK (notebook), child, NULL); +} + +ESource * +e_source_notebook_get_active_source (ESourceNotebook *notebook) +{ + g_return_val_if_fail (E_IS_SOURCE_NOTEBOOK (notebook), NULL); + + return notebook->priv->active_source; +} + +void +e_source_notebook_set_active_source (ESourceNotebook *notebook, + ESource *source) +{ + g_return_if_fail (E_IS_SOURCE_NOTEBOOK (notebook)); + + if (source != NULL) { + g_return_if_fail (E_IS_SOURCE (source)); + g_object_ref (source); + } + + if (notebook->priv->active_source != NULL) + g_object_unref (notebook->priv->active_source); + + notebook->priv->active_source = source; + + g_object_notify (G_OBJECT (notebook), "active-source"); +} + -- cgit v1.2.3