Bug 683785 - Add e_source_new_with_uid()
authorMatthew Barnes <mbarnes@redhat.com>
Wed, 12 Sep 2012 02:56:08 +0000 (22:56 -0400)
committerMatthew Barnes <mbarnes@redhat.com>
Wed, 12 Sep 2012 12:13:32 +0000 (08:13 -0400)
Variation of e_source_new() which allows a predetermined UID to be
specified for a scratch source.  This changes the "uid" property from
read-only to read/write + construct-only, and eliminates the need for
EServerSideSource to override the property.

docs/reference/libedataserver/libedataserver-sections.txt
libebackend/e-server-side-source.c
libedataserver/e-source.c
libedataserver/e-source.h

index 54f9b28..a963209 100644 (file)
@@ -240,6 +240,7 @@ e_proxy_get_type
 <TITLE>ESource</TITLE>
 ESource
 e_source_new
+e_source_new_with_uid
 e_source_hash
 e_source_equal
 e_source_changed
index 893d925..5838ad5 100644 (file)
@@ -48,7 +48,6 @@ struct _EServerSideSourcePrivate {
 
        GNode node;
        GFile *file;
-       gchar *uid;
 
        /* For comparison. */
        gchar *file_contents;
@@ -72,7 +71,6 @@ enum {
        PROP_REMOTE_DELETABLE,
        PROP_REMOVABLE,
        PROP_SERVER,
-       PROP_UID,
        PROP_WRITABLE,
        PROP_WRITE_DIRECTORY
 };
@@ -437,19 +435,6 @@ server_side_source_set_server (EServerSideSource *source,
 }
 
 static void
-server_side_source_set_uid (EServerSideSource *source,
-                            const gchar *uid)
-{
-       g_return_if_fail (source->priv->uid == NULL);
-
-       /* It's okay for this to be NULL, in fact if we're given a
-        * GFile the UID is derived from its basename anyway.  This
-        * is just for memory-only sources in a collection backend,
-        * which don't have a GFile. */
-       source->priv->uid = g_strdup (uid);
-}
-
-static void
 server_side_source_set_property (GObject *object,
                                  guint property_id,
                                  const GValue *value,
@@ -492,12 +477,6 @@ server_side_source_set_property (GObject *object,
                                g_value_get_object (value));
                        return;
 
-               case PROP_UID:
-                       server_side_source_set_uid (
-                               E_SERVER_SIDE_SOURCE (object),
-                               g_value_get_string (value));
-                       return;
-
                case PROP_WRITABLE:
                        e_server_side_source_set_writable (
                                E_SERVER_SIDE_SOURCE (object),
@@ -570,13 +549,6 @@ server_side_source_get_property (GObject *object,
                                E_SERVER_SIDE_SOURCE (object)));
                        return;
 
-               case PROP_UID:
-                       g_value_take_string (
-                               value,
-                               e_source_dup_uid (
-                               E_SOURCE (object)));
-                       return;
-
                case PROP_WRITABLE:
                        g_value_set_boolean (
                                value,
@@ -626,7 +598,6 @@ server_side_source_finalize (GObject *object)
 
        g_node_unlink (&priv->node);
 
-       g_free (priv->uid);
        g_free (priv->file_contents);
        g_free (priv->write_directory);
 
@@ -1020,25 +991,17 @@ server_side_source_initable_init (GInitable *initable,
        EServerSideSource *source;
        GDBusObject *dbus_object;
        EDBusSource *dbus_source;
-       GFile *file;
+       gchar *uid;
 
        source = E_SERVER_SIDE_SOURCE (initable);
-       file = e_server_side_source_get_file (source);
-
-       if (file != NULL) {
-               g_warn_if_fail (source->priv->uid == NULL);
-               source->priv->uid =
-                       e_server_side_source_uid_from_file (file, error);
-               if (source->priv->uid == NULL)
-                       return FALSE;
-       }
-
-       if (source->priv->uid == NULL)
-               source->priv->uid = e_uid_new ();
 
        dbus_source = e_dbus_source_skeleton_new ();
 
-       e_dbus_source_set_uid (dbus_source, source->priv->uid);
+       uid = e_source_dup_uid (E_SOURCE (source));
+       if (uid == NULL)
+               uid = e_uid_new ();
+       e_dbus_source_set_uid (dbus_source, uid);
+       g_free (uid);
 
        dbus_object = e_source_ref_dbus_object (E_SOURCE (source));
        e_dbus_object_skeleton_set_source (
@@ -1172,20 +1135,6 @@ e_server_side_source_class_init (EServerSideSourceClass *class)
                        G_PARAM_CONSTRUCT_ONLY |
                        G_PARAM_STATIC_STRINGS));
 
-       /* This overrides the "uid" property in
-        * ESourceClass with a construct-only version. */
-       g_object_class_install_property (
-               object_class,
-               PROP_UID,
-               g_param_spec_string (
-                       "uid",
-                       "UID",
-                       "The unique identity of the data source",
-                       NULL,
-                       G_PARAM_READWRITE |
-                       G_PARAM_CONSTRUCT_ONLY |
-                       G_PARAM_STATIC_STRINGS));
-
        /* This overrides the "writable" property
         * in ESourceClass with a writable version. */
        g_object_class_install_property (
@@ -1363,10 +1312,18 @@ e_server_side_source_new (ESourceRegistryServer *server,
 {
        EDBusObjectSkeleton *dbus_object;
        ESource *source;
+       gchar *uid = NULL;
 
        g_return_val_if_fail (E_IS_SOURCE_REGISTRY_SERVER (server), NULL);
        g_return_val_if_fail (file == NULL || G_IS_FILE (file), NULL);
 
+       /* Extract a UID from the GFile, if we were given one. */
+       if (file != NULL) {
+               uid = e_server_side_source_uid_from_file (file, error);
+               if (uid == NULL)
+                       return NULL;
+       }
+
        /* XXX This is an awkward way of initializing the "dbus-object"
         *     property, but e_source_ref_dbus_object() needs to work. */
        dbus_object = e_dbus_object_skeleton_new (DBUS_OBJECT_PATH);
@@ -1374,7 +1331,8 @@ e_server_side_source_new (ESourceRegistryServer *server,
        source = g_initable_new (
                E_TYPE_SERVER_SIDE_SOURCE, NULL, error,
                "dbus-object", dbus_object,
-               "file", file, "server", server, NULL);
+               "file", file, "server", server,
+               "uid", uid, NULL);
 
        g_object_unref (dbus_object);
 
index 1ed8d25..29318cd 100644 (file)
@@ -712,6 +712,19 @@ source_set_main_context (ESource *source,
 }
 
 static void
+source_set_uid (ESource *source,
+                const gchar *uid)
+{
+       /* The "uid" argument will usually be NULL unless called
+        * from e_source_new_with_uid().  If NULL, we'll pick up
+        * a UID in source_initable_init(). */
+
+       g_return_if_fail (source->priv->uid == NULL);
+
+       source->priv->uid = g_strdup (uid);
+}
+
+static void
 source_set_property (GObject *object,
                      guint property_id,
                      const GValue *value,
@@ -747,6 +760,12 @@ source_set_property (GObject *object,
                                E_SOURCE (object),
                                g_value_get_string (value));
                        return;
+
+               case PROP_UID:
+                       source_set_uid (
+                               E_SOURCE (object),
+                               g_value_get_string (value));
+                       return;
        }
 
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -1302,7 +1321,13 @@ source_initable_init (GInitable *initable,
                        e_dbus_source_call_allow_auth_prompt_sync (
                                dbus_source, cancellable, NULL);
 
-               /* The UID never changes, so we can cache a copy. */
+               /* The UID never changes, so we can cache a copy.
+                *
+                * XXX Note, EServerSideSource may have already set this
+                *     by way of the "uid" construct-only property, hence
+                *     the g_free() call.  Not a problem, we'll just free
+                *     our UID string and set it to the same value again. */
+               g_free (source->priv->uid);
                source->priv->uid = e_dbus_source_dup_uid (dbus_source);
 
                g_signal_connect (
@@ -1314,8 +1339,9 @@ source_initable_init (GInitable *initable,
                g_object_unref (dbus_source);
 
        /* No D-Bus object implies we're configuring a new source,
-        * so generate a new unique identifier (UID) for it. */
-       } else {
+        * so generate a new unique identifier (UID) unless one was
+        * explicitly provided through e_source_new_with_uid(). */
+       } else if (source->priv->uid == NULL) {
                source->priv->uid = e_uid_new ();
        }
 
@@ -1465,7 +1491,8 @@ e_source_class_init (ESourceClass *class)
                        "UID",
                        "The unique identity of the data source",
                        NULL,
-                       G_PARAM_READABLE |
+                       G_PARAM_READWRITE |
+                       G_PARAM_CONSTRUCT_ONLY |
                        G_PARAM_STATIC_STRINGS));
 
        g_object_class_install_property (
@@ -1593,6 +1620,35 @@ e_source_new (GDBusObject *dbus_object,
 }
 
 /**
+ * e_source_new_with_uid:
+ * @uid: a new unique identifier string
+ * @main_context: (allow-none): a #GMainContext or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Creates a new "scratch" #ESource with a predetermined unique identifier.
+ *
+ * The #ESource::changed signal will be emitted from @main_context if given,
+ * or else from the thread-default #GMainContext at the time this function is
+ * called.
+ *
+ * Returns: a new scratch #ESource, or %NULL on error
+ *
+ * Since: 3.6
+ **/
+ESource *
+e_source_new_with_uid (const gchar *uid,
+                       GMainContext *main_context,
+                       GError **error)
+{
+       g_return_val_if_fail (uid != NULL, NULL);
+
+       return g_initable_new (
+               E_TYPE_SOURCE, NULL, error,
+               "main-context", main_context,
+               "uid", uid, NULL);
+}
+
+/**
  * e_source_hash:
  * @source: an #ESource
  *
index be808c0..a4675ab 100644 (file)
@@ -132,6 +132,9 @@ GType               e_source_get_type               (void) G_GNUC_CONST;
 ESource *      e_source_new                    (GDBusObject *dbus_object,
                                                 GMainContext *main_context,
                                                 GError **error);
+ESource *      e_source_new_with_uid           (const gchar *uid,
+                                                GMainContext *main_context,
+                                                GError **error);
 guint          e_source_hash                   (ESource *source);
 gboolean       e_source_equal                  (ESource *source1,
                                                 ESource *source2);