[evolution] Add EClientComboBox.



commit 977be20ced747224c0e08d565f961f0fa8d0baf8
Author: Matthew Barnes <mbarnes redhat com>
Date:   Fri Mar 1 12:19:40 2013 -0500

    Add EClientComboBox.

 doc/reference/libeutil/libeutil-docs.sgml    |    1 +
 doc/reference/libeutil/libeutil-sections.txt |   24 ++
 doc/reference/libeutil/libeutil.types        |    1 +
 e-util/Makefile.am                           |    2 +
 e-util/e-client-combo-box.c                  |  461 ++++++++++++++++++++++++++
 e-util/e-client-combo-box.h                  |   92 +++++
 e-util/e-util.h                              |    1 +
 7 files changed, 582 insertions(+), 0 deletions(-)
---
diff --git a/doc/reference/libeutil/libeutil-docs.sgml b/doc/reference/libeutil/libeutil-docs.sgml
index 468fb98..701cdce 100644
--- a/doc/reference/libeutil/libeutil-docs.sgml
+++ b/doc/reference/libeutil/libeutil-docs.sgml
@@ -182,6 +182,7 @@
     <xi:include href="xml/e-source-combo-box.xml"/>
     <xi:include href="xml/e-source-util.xml"/>
     <xi:include href="xml/e-client-cache.xml"/>
+    <xi:include href="xml/e-client-combo-box.xml"/>
     <xi:include href="xml/e-client-selector.xml"/>
   </chapter>
 
diff --git a/doc/reference/libeutil/libeutil-sections.txt b/doc/reference/libeutil/libeutil-sections.txt
index bbd1467..cf691bc 100644
--- a/doc/reference/libeutil/libeutil-sections.txt
+++ b/doc/reference/libeutil/libeutil-sections.txt
@@ -1275,6 +1275,30 @@ EClientCachePrivate
 </SECTION>
 
 <SECTION>
+<FILE>e-client-combo-box</FILE>
+<TITLE>EClientComboBox</TITLE>
+EClientComboBox
+e_client_combo_box_new
+e_client_combo_box_ref_client_cache
+e_client_combo_box_set_client_cache
+e_client_combo_box_get_client_sync
+e_client_combo_box_get_client
+e_client_combo_box_get_client_finish
+e_client_combo_box_ref_cached_client
+<SUBSECTION Standard>
+E_CLIENT_COMBO_BOX
+E_IS_CLIENT_COMBO_BOX
+E_TYPE_CLIENT_COMBO_BOX
+E_CLIENT_COMBO_BOX_CLASS
+E_IS_CLIENT_COMBO_BOX_CLASS
+E_CLIENT_COMBO_BOX_GET_CLASS
+EClientComboBoxClass
+e_client_combo_box_get_type
+<SUBSECTION Private>
+EClientComboBoxPrivate
+</SECTION>
+
+<SECTION>
 <FILE>e-client-selector</FILE>
 <TITLE>EClientSelector</TITLE>
 EClientSelector
diff --git a/doc/reference/libeutil/libeutil.types b/doc/reference/libeutil/libeutil.types
index fdf7494..f8bfae4 100644
--- a/doc/reference/libeutil/libeutil.types
+++ b/doc/reference/libeutil/libeutil.types
@@ -54,6 +54,7 @@ e_cell_tree_get_type
 e_cell_vbox_get_type
 e_charset_combo_box_get_type
 e_client_cache_get_type
+e_client_combo_box_get_type
 e_client_selector_get_type
 e_config_get_type
 e_config_hook_get_type
diff --git a/e-util/Makefile.am b/e-util/Makefile.am
index 3eca443..9fa1877 100644
--- a/e-util/Makefile.am
+++ b/e-util/Makefile.am
@@ -159,6 +159,7 @@ eutilinclude_HEADERS =  \
        e-charset-combo-box.h \
        e-charset.h \
        e-client-cache.h \
+       e-client-combo-box.h \
        e-client-selector.h \
        e-config.h \
        e-contact-store.h \
@@ -406,6 +407,7 @@ libeutil_la_SOURCES = \
        e-charset-combo-box.c \
        e-charset.c \
        e-client-cache.c \
+       e-client-combo-box.c \
        e-client-selector.c \
        e-config.c \
        e-contact-store.c \
diff --git a/e-util/e-client-combo-box.c b/e-util/e-client-combo-box.c
new file mode 100644
index 0000000..657b5b6
--- /dev/null
+++ b/e-util/e-client-combo-box.c
@@ -0,0 +1,461 @@
+/*
+ * e-client-combo-box.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-client-combo-box
+ * @include: e-util/e-util.h
+ * @short_description: Combo box of #EClient instances
+ *
+ * #EClientComboBox extends the functionality of #ESourceComboBox by
+ * providing convenient access to #EClient instances with #EClientCache.
+ *
+ * As a future enhancement, this widget may also display status information
+ * about the backends associated with the displayed data sources, similar to
+ * #EClientSelector.
+ **/
+
+#include "e-client-combo-box.h"
+
+#define E_CLIENT_COMBO_BOX_GET_PRIVATE(obj) \
+       (G_TYPE_INSTANCE_GET_PRIVATE \
+       ((obj), E_TYPE_CLIENT_COMBO_BOX, EClientComboBoxPrivate))
+
+struct _EClientComboBoxPrivate {
+       EClientCache *client_cache;
+};
+
+enum {
+       PROP_0,
+       PROP_CLIENT_CACHE
+};
+
+G_DEFINE_TYPE (
+       EClientComboBox,
+       e_client_combo_box,
+       E_TYPE_SOURCE_COMBO_BOX)
+
+static void
+client_combo_box_set_property (GObject *object,
+                               guint property_id,
+                               const GValue *value,
+                               GParamSpec *pspec)
+{
+       switch (property_id) {
+               case PROP_CLIENT_CACHE:
+                       e_client_combo_box_set_client_cache (
+                               E_CLIENT_COMBO_BOX (object),
+                               g_value_get_object (value));
+                       return;
+       }
+
+       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+client_combo_box_get_property (GObject *object,
+                               guint property_id,
+                               GValue *value,
+                               GParamSpec *pspec)
+{
+       switch (property_id) {
+               case PROP_CLIENT_CACHE:
+                       g_value_take_object (
+                               value,
+                               e_client_combo_box_ref_client_cache (
+                               E_CLIENT_COMBO_BOX (object)));
+                       return;
+       }
+
+       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+client_combo_box_dispose (GObject *object)
+{
+       EClientComboBoxPrivate *priv;
+
+       priv = E_CLIENT_COMBO_BOX_GET_PRIVATE (object);
+
+       g_clear_object (&priv->client_cache);
+
+       /* Chain up to parent's dispose() method. */
+       G_OBJECT_CLASS (e_client_combo_box_parent_class)->dispose (object);
+}
+
+static void
+e_client_combo_box_class_init (EClientComboBoxClass *class)
+{
+       GObjectClass *object_class;
+
+       g_type_class_add_private (class, sizeof (EClientComboBoxPrivate));
+
+       object_class = G_OBJECT_CLASS (class);
+       object_class->set_property = client_combo_box_set_property;
+       object_class->get_property = client_combo_box_get_property;
+       object_class->dispose = client_combo_box_dispose;
+
+       /**
+        * EClientComboBox:client-cache:
+        *
+        * Cache of shared #EClient instances.
+        **/
+       /* XXX Don't use G_PARAM_CONSTRUCT_ONLY here.  We need to allow
+        *     for this class to be instantiated by a GtkBuilder with no
+        *     special construct parameters, and then subsequently give
+        *     it an EClientCache. */
+       g_object_class_install_property (
+               object_class,
+               PROP_CLIENT_CACHE,
+               g_param_spec_object (
+                       "client-cache",
+                       "Client Cache",
+                       "Cache of shared EClient instances",
+                       E_TYPE_CLIENT_CACHE,
+                       G_PARAM_READWRITE |
+                       G_PARAM_CONSTRUCT_ONLY |
+                       G_PARAM_STATIC_STRINGS));
+}
+
+static void
+e_client_combo_box_init (EClientComboBox *combo_box)
+{
+       combo_box->priv = E_CLIENT_COMBO_BOX_GET_PRIVATE (combo_box);
+}
+
+/**
+ * e_client_combo_box_new:
+ * @client_cache: an #EClientCache
+ * @extension_name: the name of an #ESource extension
+ *
+ * Creates a new #EClientComboBox widget that lets the user pick an #ESource
+ * from the provided @client_cache.  The displayed sources are restricted to
+ * those which have an @extension_name extension.
+ *
+ * Returns: a new #EClientComboBox
+ **/
+GtkWidget *
+e_client_combo_box_new (EClientCache *client_cache,
+                        const gchar *extension_name)
+{
+       ESourceRegistry *registry;
+       GtkWidget *widget;
+
+       g_return_val_if_fail (E_IS_CLIENT_CACHE (client_cache), NULL);
+       g_return_val_if_fail (extension_name != NULL, NULL);
+
+       registry = e_client_cache_ref_registry (client_cache);
+
+       widget = g_object_new (
+               E_TYPE_CLIENT_COMBO_BOX,
+               "client-cache", client_cache,
+               "extension-name", extension_name,
+               "registry", registry, NULL);
+
+       g_object_unref (registry);
+
+       return widget;
+}
+
+/**
+ * e_client_combo_box_ref_client_cache:
+ * @combo_box: an #EClientComboBox
+ *
+ * Returns the #EClientCache passed to e_client_combo_box_new().
+ *
+ * The returned #EClientCache is referenced for thread-safety and must be
+ * unreferenced with g_object_unref() when finished with it.
+ *
+ * Returns: an #EClientCache
+ **/
+EClientCache *
+e_client_combo_box_ref_client_cache (EClientComboBox *combo_box)
+{
+       g_return_val_if_fail (E_IS_CLIENT_COMBO_BOX (combo_box), NULL);
+
+       return g_object_ref (combo_box->priv->client_cache);
+}
+
+/**
+ * e_client_combo_box_set_client_cache:
+ * @combo_box: an #EClientComboBox
+ *
+ * Simultaneously sets the #EClientComboBox:client-cache and
+ * #ESourceComboBox:registry properties.
+ *
+ * This function is intended for cases where @combo_box is instantiated
+ * by a #GtkBuilder and has to be given an #EClientCache after it is fully
+ * constructed.
+ **/
+void
+e_client_combo_box_set_client_cache (EClientComboBox *combo_box,
+                                     EClientCache *client_cache)
+{
+       ESourceRegistry *registry = NULL;
+
+       g_return_if_fail (E_IS_CLIENT_COMBO_BOX (combo_box));
+
+       if (combo_box->priv->client_cache == client_cache)
+               return;
+
+       if (client_cache != NULL) {
+               g_return_if_fail (E_IS_CLIENT_CACHE (client_cache));
+               g_object_ref (client_cache);
+       }
+
+       if (combo_box->priv->client_cache != NULL)
+               g_object_unref (combo_box->priv->client_cache);
+
+       combo_box->priv->client_cache = client_cache;
+
+       if (client_cache != NULL)
+               registry = e_client_cache_ref_registry (client_cache);
+
+       e_source_combo_box_set_registry (
+               E_SOURCE_COMBO_BOX (combo_box), registry);
+
+       g_clear_object (&registry);
+
+       g_object_notify (G_OBJECT (combo_box), "client-cache");
+}
+
+/**
+ * e_client_combo_box_get_client_sync:
+ * @combo_box: an #EClientComboBox
+ * @source: an #ESource
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Obtains a shared #EClient instance for @source, or else creates a new
+ * #EClient instance to be shared.
+ *
+ * The #ESourceComboBox:extension-name property determines the type of
+ * #EClient to obtain.  See e_client_cache_get_client_sync() for a list
+ * of valid extension names.
+ *
+ * If a request for the same @source and #ESourceComboBox:extension-name
+ * is already in progress when this function is called, this request will
+ * "piggyback" on the in-progress request such that they will both succeed
+ * or fail simultaneously.
+ *
+ * Unreference the returned #EClient with g_object_unref() when finished
+ * with it.  If an error occurs, the function will set @error and return
+ * %NULL.
+ *
+ * Returns: an #EClient, or %NULL
+ **/
+EClient *
+e_client_combo_box_get_client_sync (EClientComboBox *combo_box,
+                                    ESource *source,
+                                    GCancellable *cancellable,
+                                    GError **error)
+{
+       EAsyncClosure *closure;
+       GAsyncResult *result;
+       EClient *client;
+
+       g_return_val_if_fail (E_IS_CLIENT_COMBO_BOX (combo_box), NULL);
+       g_return_val_if_fail (E_IS_SOURCE (source), NULL);
+
+       closure = e_async_closure_new ();
+
+       e_client_combo_box_get_client (
+               combo_box, source, cancellable,
+               e_async_closure_callback, closure);
+
+       result = e_async_closure_wait (closure);
+
+       client = e_client_combo_box_get_client_finish (
+               combo_box, result, error);
+
+       e_async_closure_free (closure);
+
+       return client;
+}
+
+/* Helper for e_client_combo_box_get_client() */
+static void
+client_combo_box_get_client_done_cb (GObject *source_object,
+                                     GAsyncResult *result,
+                                     gpointer user_data)
+{
+       EClient *client;
+       GSimpleAsyncResult *simple;
+       GError *error = NULL;
+
+       simple = G_SIMPLE_ASYNC_RESULT (user_data);
+
+       client = e_client_cache_get_client_finish (
+               E_CLIENT_CACHE (source_object), result, &error);
+
+       /* Sanity check. */
+       g_return_if_fail (
+               ((client != NULL) && (error == NULL)) ||
+               ((client == NULL) && (error != NULL)));
+
+       if (client != NULL) {
+               g_simple_async_result_set_op_res_gpointer (
+                       simple, g_object_ref (client),
+                       (GDestroyNotify) g_object_unref);
+               g_object_unref (client);
+       }
+
+       if (error != NULL)
+               g_simple_async_result_take_error (simple, error);
+
+       g_simple_async_result_complete (simple);
+
+       g_object_unref (simple);
+}
+
+/**
+ * e_client_combo_box_get_client:
+ * @combo_box: an #EClientComboBox
+ * @source: an #ESource
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @callback: a #GAsyncReadyCallback to call when the request is satisfied
+ * @user_data: data to pass to the callback function
+ *
+ * Asynchronously obtains a shared #EClient instance for @source, or else
+ * creates a new #EClient instance to be shared.
+ *
+ * The #ESourceComboBox:extension-name property determines the type of
+ * #EClient to obtain.  See e_client_cache_get_client_sync() for a list
+ * of valid extension names.
+ *
+ * If a request for the same @source and #ESourceComboBox:extension-name
+ * is already in progress when this function is called, this request will
+ * "piggyback" on the in-progress request such that they will both succeed
+ * or fail simultaneously.
+ *
+ * When the operation is finished, @callback will be called.  You can
+ * then call e_client_combo_box_get_client_finish() to get the result of
+ * the operation.
+ **/
+void
+e_client_combo_box_get_client (EClientComboBox *combo_box,
+                               ESource *source,
+                               GCancellable *cancellable,
+                               GAsyncReadyCallback callback,
+                               gpointer user_data)
+{
+       EClientCache *client_cache;
+       GSimpleAsyncResult *simple;
+       const gchar *extension_name;
+
+       g_return_if_fail (E_IS_CLIENT_COMBO_BOX (combo_box));
+       g_return_if_fail (E_IS_SOURCE (source));
+
+       simple = g_simple_async_result_new (
+               G_OBJECT (combo_box), callback,
+               user_data, e_client_combo_box_get_client);
+
+       g_simple_async_result_set_check_cancellable (simple, cancellable);
+
+       extension_name = e_source_combo_box_get_extension_name (
+               E_SOURCE_COMBO_BOX (combo_box));
+
+       client_cache = e_client_combo_box_ref_client_cache (combo_box);
+
+       e_client_cache_get_client (
+               client_cache, source,
+               extension_name, cancellable,
+               client_combo_box_get_client_done_cb,
+               g_object_ref (simple));
+
+       g_object_unref (client_cache);
+
+       g_object_unref (simple);
+}
+
+/**
+ * e_client_combo_box_get_client_finish:
+ * @combo_box: an #EClientComboBox
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes the operation started with e_client_combo_box_get_client().
+ *
+ * Unreference the returned #EClient with g_object_unref() when finished
+ * with it.  If an error occurred, the function will set @error and return
+ * %NULL.
+ *
+ * Returns: an #EClient, or %NULL
+ **/
+EClient *
+e_client_combo_box_get_client_finish (EClientComboBox *combo_box,
+                                      GAsyncResult *result,
+                                      GError **error)
+{
+       GSimpleAsyncResult *simple;
+       EClient *client;
+
+       g_return_val_if_fail (
+               g_simple_async_result_is_valid (
+               result, G_OBJECT (combo_box),
+               e_client_combo_box_get_client), NULL);
+
+       simple = G_SIMPLE_ASYNC_RESULT (result);
+       client = g_simple_async_result_get_op_res_gpointer (simple);
+
+       if (g_simple_async_result_propagate_error (simple, error))
+               return NULL;
+
+       g_return_val_if_fail (client != NULL, NULL);
+
+       return g_object_ref (client);
+}
+
+/**
+ * e_client_combo_box_ref_cached_client:
+ * @combo_box: an #EClientComboBox
+ * @source: an #ESource
+ *
+ * Returns a shared #EClient instance for @source and the value of
+ * #ESourceComboBox:extension-name if such an instance is already cached,
+ * or else %NULL.  This function does not create a new #EClient instance,
+ * and therefore does not block.
+ *
+ * The returned #EClient is referenced for thread-safety and must be
+ * unreferenced with g_object_unref() when finished with it.
+ *
+ * Returns: an #EClient, or %NULL
+ **/
+EClient *
+e_client_combo_box_ref_cached_client (EClientComboBox *combo_box,
+                                      ESource *source)
+{
+       EClient *client;
+       EClientCache *client_cache;
+       const gchar *extension_name;
+
+       g_return_val_if_fail (E_IS_CLIENT_COMBO_BOX (combo_box), NULL);
+       g_return_val_if_fail (E_IS_SOURCE (source), NULL);
+
+       extension_name = e_source_combo_box_get_extension_name (
+               E_SOURCE_COMBO_BOX (combo_box));
+
+       client_cache = e_client_combo_box_ref_client_cache (combo_box);
+
+       client = e_client_cache_ref_cached_client (
+               client_cache, source, extension_name);
+
+       g_object_unref (client_cache);
+
+       return client;
+}
+
diff --git a/e-util/e-client-combo-box.h b/e-util/e-client-combo-box.h
new file mode 100644
index 0000000..e48c9df
--- /dev/null
+++ b/e-util/e-client-combo-box.h
@@ -0,0 +1,92 @@
+/*
+ * e-client-combo-box.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_CLIENT_COMBO_BOX_H
+#define E_CLIENT_COMBO_BOX_H
+
+#include <e-util/e-client-cache.h>
+#include <e-util/e-source-combo-box.h>
+
+/* Standard GObject macros */
+#define E_TYPE_CLIENT_COMBO_BOX \
+       (e_client_combo_box_get_type ())
+#define E_CLIENT_COMBO_BOX(obj) \
+       (G_TYPE_CHECK_INSTANCE_CAST \
+       ((obj), E_TYPE_CLIENT_COMBO_BOX, EClientComboBox))
+#define E_CLIENT_COMBO_BOX_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_CAST \
+       ((cls), E_TYPE_CLIENT_COMBO_BOX, EClientComboBoxClass))
+#define E_IS_CLIENT_COMBO_BOX(obj) \
+       (G_TYPE_CHECK_INSTANCE_TYPE \
+       ((obj), E_TYPE_CLIENT_COMBO_BOX))
+#define E_IS_CLIENT_COMBO_BOX_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_TYPE \
+       ((cls), E_TYPE_CLIENT_COMBO_BOX))
+#define E_CLIENT_COMBO_BOX_GET_CLASS(obj) \
+       (G_TYPE_INSTANCE_GET_CLASS \
+       ((obj), E_TYPE_CLIENT_COMBO_BOX, EClientComboBoxClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EClientComboBox EClientComboBox;
+typedef struct _EClientComboBoxClass EClientComboBoxClass;
+typedef struct _EClientComboBoxPrivate EClientComboBoxPrivate;
+
+struct _EClientComboBox {
+       ESourceComboBox parent;
+       EClientComboBoxPrivate *priv;
+};
+
+struct _EClientComboBoxClass {
+       ESourceComboBoxClass parent_class;
+};
+
+GType          e_client_combo_box_get_type     (void) G_GNUC_CONST;
+GtkWidget *    e_client_combo_box_new          (EClientCache *client_cache,
+                                                const gchar *extension_name);
+EClientCache * e_client_combo_box_ref_client_cache
+                                               (EClientComboBox *combo_box);
+void           e_client_combo_box_set_client_cache
+                                               (EClientComboBox *combo_box,
+                                                EClientCache *client_cache);
+EClient *      e_client_combo_box_get_client_sync
+                                               (EClientComboBox *combo_box,
+                                                ESource *source,
+                                                GCancellable *cancellable,
+                                                GError **error);
+void           e_client_combo_box_get_client   (EClientComboBox *combo_box,
+                                                ESource *source,
+                                                GCancellable *cancellable,
+                                                GAsyncReadyCallback callback,
+                                                gpointer user_data);
+EClient *      e_client_combo_box_get_client_finish
+                                               (EClientComboBox *combo_box,
+                                                GAsyncResult *result,
+                                                GError **error);
+EClient *      e_client_combo_box_ref_cached_client
+                                               (EClientComboBox *combo_box,
+                                                ESource *source);
+
+G_END_DECLS
+
+#endif /* E_CLIENT_COMBO_BOX_H */
+
diff --git a/e-util/e-util.h b/e-util/e-util.h
index cbdc77c..8c897f6 100644
--- a/e-util/e-util.h
+++ b/e-util/e-util.h
@@ -81,6 +81,7 @@
 #include <e-util/e-charset-combo-box.h>
 #include <e-util/e-charset.h>
 #include <e-util/e-client-cache.h>
+#include <e-util/e-client-combo-box.h>
 #include <e-util/e-client-selector.h>
 #include <e-util/e-config.h>
 #include <e-util/e-contact-store.h>


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