[gtk+/open-with-dialog] app-chooser-online: rework of the online module



commit 51cb082022994634e8639443c9f2463ac4c822e8
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Mon Nov 29 18:10:06 2010 +0100

    app-chooser-online: rework of the online module
    
    - the _get_default() method is now async
    - the PackageKit module will return NULL in case PackageKit is not
      available in the session bus
    - the dummy module doesn't exist anymore
    - the dialog won't display the online button in case there's no module
      available

 gtk/Makefile.am                |    2 -
 gtk/gtkappchooserdialog.c      |   69 ++++++++++++-----
 gtk/gtkappchoosermodule.c      |   15 ++--
 gtk/gtkappchooseronline.c      |   32 +++++---
 gtk/gtkappchooseronline.h      |   12 ++-
 gtk/gtkappchooseronlinedummy.c |   86 --------------------
 gtk/gtkappchooseronlinedummy.h |   53 -------------
 gtk/gtkappchooseronlinepk.c    |  170 ++++++++++++++++++++++++++++------------
 8 files changed, 203 insertions(+), 236 deletions(-)
---
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 4448b47..ebd7118 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -392,7 +392,6 @@ gtk_private_h_sources =		\
 	gtkmountoperationprivate.h \
 	gtkappchooserprivate.h	\
 	gtkappchoosermodule.h 	\
-	gtkappchooseronlinedummy.h \
 	gtkpango.h		\
 	gtkpathbar.h		\
 	gtkplugprivate.h	\
@@ -543,7 +542,6 @@ gtk_base_c_sources =            \
 	gtkappchooserdialog.c	\
 	gtkappchoosermodule.c	\
 	gtkappchooseronline.c	\
-	gtkappchooseronlinedummy.c \
 	gtkorientable.c		\
 	gtkpagesetup.c		\
 	gtkpaned.c		\
diff --git a/gtk/gtkappchooserdialog.c b/gtk/gtkappchooserdialog.c
index 4959ca9..73dc7a2 100644
--- a/gtk/gtkappchooserdialog.c
+++ b/gtk/gtkappchooserdialog.c
@@ -60,6 +60,8 @@ struct _GtkAppChooserDialogPrivate {
   GtkWidget *app_chooser_widget;
   GtkWidget *show_more_button;
 
+  GtkAppChooserOnline *online;
+
   gboolean show_more_clicked;
 };
 
@@ -118,26 +120,53 @@ search_for_mimetype_ready_cb (GObject      *source,
     {
       gtk_app_chooser_refresh (GTK_APP_CHOOSER (self->priv->app_chooser_widget));
     }
-
-  g_object_unref (online);
 }
 
 static void
 online_button_clicked_cb (GtkButton *b,
                           gpointer   user_data)
 {
-  GtkAppChooserOnline *online;
   GtkAppChooserDialog *self = user_data;
 
-  online = gtk_app_chooser_online_get_default ();
-
-  gtk_app_chooser_online_search_for_mimetype_async (online,
+  gtk_app_chooser_online_search_for_mimetype_async (self->priv->online,
                                                     self->priv->content_type,
                                                     GTK_WINDOW (self),
                                                     search_for_mimetype_ready_cb,
                                                     self);
 }
 
+static void
+app_chooser_online_get_default_ready_cb (GObject *source,
+                                         GAsyncResult *res,
+                                         gpointer user_data)
+{
+  GtkAppChooserDialog *self = user_data;
+
+  self->priv->online = gtk_app_chooser_online_get_default_finish (source, res);
+
+  if (self->priv->online != NULL)
+    {
+      GtkWidget *action_area;
+
+      action_area = gtk_dialog_get_action_area (GTK_DIALOG (self));
+      self->priv->online_button = gtk_button_new_with_label (_("Find applications online"));
+      gtk_box_pack_start (GTK_BOX (action_area), self->priv->online_button,
+                          FALSE, FALSE, 0);
+      gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (action_area), self->priv->online_button,
+                                          TRUE);
+      g_signal_connect (self->priv->online_button, "clicked",
+                        G_CALLBACK (online_button_clicked_cb), self);
+
+      gtk_widget_show (self->priv->online_button);
+    }
+}
+
+static void
+ensure_online_button (GtkAppChooserDialog *self)
+{
+  gtk_app_chooser_online_get_default_async (app_chooser_online_get_default_ready_cb, self);
+}
+
 /* An application is valid if:
  *
  * 1) The file exists
@@ -415,7 +444,7 @@ build_dialog_ui (GtkAppChooserDialog *self)
   GtkWidget *vbox;
   GtkWidget *vbox2;
   GtkWidget *label;
-  GtkWidget *action_area, *button, *w;
+  GtkWidget *button, *w;
 
   gtk_container_set_border_width (GTK_CONTAINER (self), 5);
 
@@ -482,16 +511,6 @@ build_dialog_ui (GtkAppChooserDialog *self)
   gtk_dialog_add_action_widget (GTK_DIALOG (self),
                                 self->priv->button, GTK_RESPONSE_OK);
 
-  action_area = gtk_dialog_get_action_area (GTK_DIALOG (self));
-  self->priv->online_button = gtk_button_new_with_label (_("Find applications online"));
-  gtk_box_pack_start (GTK_BOX (action_area), self->priv->online_button,
-                      FALSE, FALSE, 0);
-  gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (action_area), self->priv->online_button,
-                                      TRUE);
-  gtk_widget_show (self->priv->online_button);
-  g_signal_connect (self->priv->online_button, "clicked",
-                    G_CALLBACK (online_button_clicked_cb), self);
-
   gtk_dialog_set_default_response (GTK_DIALOG (self),
                                    GTK_RESPONSE_OK);
 }
@@ -548,15 +567,24 @@ gtk_app_chooser_dialog_constructed (GObject *object)
 
   build_dialog_ui (self);
   set_dialog_properties (self);
+  ensure_online_button (self);
 }
 
 static void
-gtk_app_chooser_dialog_finalize (GObject *object)
+gtk_app_chooser_dialog_dispose (GObject *object)
 {
   GtkAppChooserDialog *self = GTK_APP_CHOOSER_DIALOG (object);
+  
+  g_clear_object (&self->priv->gfile);
+  g_clear_object (&self->priv->online);
 
-  if (self->priv->gfile)
-    g_object_unref (self->priv->gfile);
+  G_OBJECT_CLASS (gtk_app_chooser_dialog_parent_class)->dispose (object);
+}
+
+static void
+gtk_app_chooser_dialog_finalize (GObject *object)
+{
+  GtkAppChooserDialog *self = GTK_APP_CHOOSER_DIALOG (object);
 
   g_free (self->priv->content_type);
 
@@ -624,6 +652,7 @@ gtk_app_chooser_dialog_class_init (GtkAppChooserDialogClass *klass)
   GParamSpec *pspec;
 
   gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->dispose = gtk_app_chooser_dialog_dispose;
   gobject_class->finalize = gtk_app_chooser_dialog_finalize;
   gobject_class->set_property = gtk_app_chooser_dialog_set_property;
   gobject_class->get_property = gtk_app_chooser_dialog_get_property;
diff --git a/gtk/gtkappchoosermodule.c b/gtk/gtkappchoosermodule.c
index bc5c0e7..afcf3de 100644
--- a/gtk/gtkappchoosermodule.c
+++ b/gtk/gtkappchoosermodule.c
@@ -28,7 +28,6 @@
 #include <gio/gio.h>
 
 #include "gtkappchooseronline.h"
-#include "gtkappchooseronlinedummy.h"
 
 #ifdef ENABLE_PACKAGEKIT
 #include "gtkappchooseronlinepk.h"
@@ -45,18 +44,16 @@ _gtk_app_chooser_module_ensure (void)
   G_LOCK (registered_ep);
 
   if (!registered_ep)
-{
-    registered_ep = TRUE;
-
-    ep = g_io_extension_point_register ("gtkappchooser-online");
-    g_io_extension_point_set_required_type (ep, GTK_TYPE_APP_CHOOSER_ONLINE);
+    {
+      registered_ep = TRUE;
 
-    _gtk_app_chooser_online_dummy_get_type ();
+      ep = g_io_extension_point_register ("gtkappchooser-online");
+      g_io_extension_point_set_required_type (ep, GTK_TYPE_APP_CHOOSER_ONLINE);
 
 #ifdef ENABLE_PACKAGEKIT
-    _gtk_app_chooser_online_pk_get_type ();
+      _gtk_app_chooser_online_pk_get_type ();
 #endif
-  }
+    }
 
   G_UNLOCK (registered_ep);
 }
diff --git a/gtk/gtkappchooseronline.c b/gtk/gtkappchooseronline.c
index 34849d8..71267ca 100644
--- a/gtk/gtkappchooseronline.c
+++ b/gtk/gtkappchooseronline.c
@@ -25,12 +25,15 @@
 
 #include "gtkappchooseronline.h"
 
-#include "gtkappchooseronlinedummy.h"
 #include "gtkappchoosermodule.h"
+#include "gtkintl.h"
 
 #include <gio/gio.h>
 
-G_DEFINE_INTERFACE (GtkAppChooserOnline, gtk_app_chooser_online, G_TYPE_OBJECT);
+#define gtk_app_chooser_online_get_type _gtk_app_chooser_online_get_type
+static void gtk_app_chooser_online_default_init (GtkAppChooserOnlineInterface *iface);
+G_DEFINE_INTERFACE_WITH_CODE (GtkAppChooserOnline, gtk_app_chooser_online, G_TYPE_OBJECT,
+                              g_type_interface_add_prerequisite (g_define_type_id, G_TYPE_ASYNC_INITABLE);)
 
 static void
 gtk_app_chooser_online_default_init (GtkAppChooserOnlineInterface *iface)
@@ -39,12 +42,24 @@ gtk_app_chooser_online_default_init (GtkAppChooserOnlineInterface *iface)
 }
 
 GtkAppChooserOnline *
-gtk_app_chooser_online_get_default (void)
+gtk_app_chooser_online_get_default_finish (GObject *source,
+                                           GAsyncResult *result)
+{
+  GtkAppChooserOnline *retval;
+
+  retval = GTK_APP_CHOOSER_ONLINE (g_async_initable_new_finish (G_ASYNC_INITABLE (source),
+                                                                result, NULL));
+
+  return retval;
+}  
+
+void
+gtk_app_chooser_online_get_default_async (GAsyncReadyCallback callback,
+                                          gpointer user_data)
 {
   GIOExtensionPoint *ep;
   GIOExtension *extension;
   GList *extensions;
-  GtkAppChooserOnline *retval;
 
   _gtk_app_chooser_module_ensure ();
 
@@ -55,14 +70,9 @@ gtk_app_chooser_online_get_default (void)
     {
       /* pick the first */
       extension = extensions->data;
-      retval = g_object_new (g_io_extension_get_type (extension), NULL);
-    }
-  else
-    {
-      retval = g_object_new (GTK_TYPE_APP_CHOOSER_ONLINE_DUMMY, NULL);
+      g_async_initable_new_async (g_io_extension_get_type (extension), G_PRIORITY_DEFAULT,
+                                  NULL, callback, user_data, NULL);
     }
-
-  return retval;
 }
 
 void
diff --git a/gtk/gtkappchooseronline.h b/gtk/gtkappchooseronline.h
index 87ebc08..d0eca3b 100644
--- a/gtk/gtkappchooseronline.h
+++ b/gtk/gtkappchooseronline.h
@@ -31,7 +31,7 @@
 
 G_BEGIN_DECLS
 
-#define GTK_TYPE_APP_CHOOSER_ONLINE           (gtk_app_chooser_online_get_type ())
+#define GTK_TYPE_APP_CHOOSER_ONLINE           (_gtk_app_chooser_online_get_type ())
 #define GTK_APP_CHOOSER_ONLINE(o)             (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_APP_CHOOSER_ONLINE, GtkAppChooserOnline))
 #define GTK_IS_APP_CHOOSER_ONLINE(o)          (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTK_TYPE_APP_CHOOSER_ONLINE))
 #define GTK_APP_CHOOSER_ONLINE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GTK_TYPE_APP_CHOOSER_ONLINE, GtkAppChooserOnlineInterface))
@@ -54,7 +54,13 @@ struct _GtkAppChooserOnlineInterface {
                                           GError              **error);
 };
 
-GType                 gtk_app_chooser_online_get_type                   (void) G_GNUC_CONST;
+GType                 _gtk_app_chooser_online_get_type                  (void) G_GNUC_CONST;
+
+void                  gtk_app_chooser_online_get_default_async          (GAsyncReadyCallback   callback,
+                                                                         gpointer              user_data);
+GtkAppChooserOnline * gtk_app_chooser_online_get_default_finish          (GObject             *source,
+                                                                          GAsyncResult        *result);
+
 void                  gtk_app_chooser_online_search_for_mimetype_async  (GtkAppChooserOnline  *self,
                                                                          const gchar          *content_type,
                                                                          GtkWindow            *parent,
@@ -64,6 +70,4 @@ gboolean              gtk_app_chooser_online_search_for_mimetype_finish (GtkAppC
                                                                          GAsyncResult         *res,
                                                                          GError              **error);
 
-GtkAppChooserOnline * gtk_app_chooser_online_get_default                (void);
-
 #endif /* __GTK_APP_CHOOSER_ONLINE_H__ */
diff --git a/gtk/gtkappchooseronlinepk.c b/gtk/gtkappchooseronlinepk.c
index d307fb8..c498546 100644
--- a/gtk/gtkappchooseronlinepk.c
+++ b/gtk/gtkappchooseronlinepk.c
@@ -34,9 +34,12 @@
 
 #define gtk_app_chooser_online_pk_get_type _gtk_app_chooser_online_pk_get_type
 static void app_chooser_online_iface_init (GtkAppChooserOnlineInterface *iface);
+static void app_chooser_online_pk_async_initable_init (GAsyncInitableIface *iface);
 
 G_DEFINE_TYPE_WITH_CODE (GtkAppChooserOnlinePk, gtk_app_chooser_online_pk,
                          G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE,
+                                                app_chooser_online_pk_async_initable_init)
                          G_IMPLEMENT_INTERFACE (GTK_TYPE_APP_CHOOSER_ONLINE,
                                                 app_chooser_online_iface_init)
                          g_io_extension_point_implement ("gtkappchooser-online",
@@ -44,20 +47,23 @@ G_DEFINE_TYPE_WITH_CODE (GtkAppChooserOnlinePk, gtk_app_chooser_online_pk,
                                                          "packagekit", 10));
 
 struct _GtkAppChooserOnlinePkPrivate {
+  GSimpleAsyncResult *init_result;
+  guint watch_id;
+
+  GDBusProxy *proxy;
   GSimpleAsyncResult *result;
   GtkWindow *parent;
-  gchar *content_type;
 };
 
 static void
-gtk_app_chooser_online_pk_finalize (GObject *obj)
+gtk_app_chooser_online_pk_dispose (GObject *obj)
 {
   GtkAppChooserOnlinePk *self = GTK_APP_CHOOSER_ONLINE_PK (obj);
 
-  g_free (self->priv->content_type);
   g_clear_object (&self->priv->result);
+  g_clear_object (&self->priv->proxy);
 
-  G_OBJECT_CLASS (gtk_app_chooser_online_pk_parent_class)->finalize (obj);
+  G_OBJECT_CLASS (gtk_app_chooser_online_pk_parent_class)->dispose (obj);
 }
 
 static void
@@ -65,7 +71,7 @@ gtk_app_chooser_online_pk_class_init (GtkAppChooserOnlinePkClass *klass)
 {
   GObjectClass *oclass = G_OBJECT_CLASS (klass);
 
-  oclass->finalize = gtk_app_chooser_online_pk_finalize;
+  oclass->dispose = gtk_app_chooser_online_pk_dispose;
 
   g_type_class_add_private (klass, sizeof (GtkAppChooserOnlinePkPrivate));
 }
@@ -115,40 +121,30 @@ install_mime_types_ready_cb (GObject      *source,
 }
 
 static void
-pk_proxy_appeared_cb (GObject      *source,
-                      GAsyncResult *res,
-                      gpointer      user_data)
+pk_search_mime_async (GtkAppChooserOnline *obj,
+                      const gchar         *content_type,
+                      GtkWindow           *parent,
+                      GAsyncReadyCallback  callback,
+                      gpointer             user_data)
 {
-  GtkAppChooserOnlinePk *self = user_data;
-  GDBusProxy *proxy;
-  GError *error = NULL;
+  GtkAppChooserOnlinePk *self = GTK_APP_CHOOSER_ONLINE_PK (obj);
   guint xid = 0;
   GdkWindow *window;
   const gchar *mime_types[2];
 
-  proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
-
-  if (error != NULL)
-    {
-      g_simple_async_result_set_from_error (self->priv->result, error);
-      g_error_free (error);
-
-      g_simple_async_result_complete (self->priv->result);
-
-      return;
-    }
+  self->priv->result = g_simple_async_result_new (G_OBJECT (self),
+                                                  callback, user_data,
+                                                  gtk_app_chooser_online_search_for_mimetype_async);
 
 #ifdef GDK_WINDOWING_X11
-  window = gtk_widget_get_window (GTK_WIDGET (self->priv->parent));
+  window = gtk_widget_get_window (GTK_WIDGET (parent));
   xid = GDK_WINDOW_XID (window);
-#else
-  xid = 0;
 #endif
 
-  mime_types[0] = self->priv->content_type;
+  mime_types[0] = content_type;
   mime_types[1] = NULL;
 
-  g_dbus_proxy_call (proxy,
+  g_dbus_proxy_call (self->priv->proxy,
                      "InstallMimeTypes",
                      g_variant_new ("(u^ass)",
                                     xid,
@@ -162,34 +158,106 @@ pk_proxy_appeared_cb (GObject      *source,
 }
 
 static void
-pk_search_mime_async (GtkAppChooserOnline *obj,
-                      const gchar         *content_type,
-                      GtkWindow           *parent,
-                      GAsyncReadyCallback  callback,
-                      gpointer             user_data)
+app_chooser_online_iface_init (GtkAppChooserOnlineInterface *iface)
 {
-  GtkAppChooserOnlinePk *self = GTK_APP_CHOOSER_ONLINE_PK (obj);
+  iface->search_for_mimetype_async = pk_search_mime_async;
+  iface->search_for_mimetype_finish = pk_search_mime_finish;
+}
 
-  self->priv->result = g_simple_async_result_new (G_OBJECT (self),
-                                                  callback, user_data,
-                                                  gtk_app_chooser_online_search_for_mimetype_async);
-  self->priv->parent = parent;
-  self->priv->content_type = g_strdup (content_type);
-
-  g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
-                            G_DBUS_PROXY_FLAGS_NONE,
-                            NULL,
-                            "org.freedesktop.PackageKit",
-                            "/org/freedesktop/PackageKit",
-                            "org.freedesktop.PackageKit.Modify",
-                            NULL,
-                            pk_proxy_appeared_cb,
-                            self);
+static void
+pk_proxy_created_cb (GObject *source,
+                     GAsyncResult *result,
+                     gpointer user_data)
+{
+  GtkAppChooserOnlinePk *self = user_data;
+  GDBusProxy *proxy;
+
+  proxy = g_dbus_proxy_new_finish (result, NULL);
+
+  if (proxy == NULL)
+    {
+      g_simple_async_result_set_op_res_gboolean (self->priv->init_result, FALSE);
+    }
+  else
+    {
+      g_simple_async_result_set_op_res_gboolean (self->priv->init_result, TRUE);
+      self->priv->proxy = proxy;
+    }
+
+  g_simple_async_result_complete (self->priv->init_result);
+  g_clear_object (&self->priv->init_result);
 }
 
 static void
-app_chooser_online_iface_init (GtkAppChooserOnlineInterface *iface)
+pk_appeared_cb (GDBusConnection *conn,
+                const gchar *name,
+                const gchar *owner,
+                gpointer user_data)
 {
-  iface->search_for_mimetype_async = pk_search_mime_async;
-  iface->search_for_mimetype_finish = pk_search_mime_finish;
+  GtkAppChooserOnlinePk *self = user_data;
+
+  /* create the proxy */
+  g_dbus_proxy_new (conn, 0, NULL,
+                    "org.freedesktop.PackageKit",
+                    "/org/freedesktop/PackageKit",
+                    "org.freedesktop.PackageKit.Modify",
+                    NULL,
+                    pk_proxy_created_cb,
+                    self);
+
+  g_bus_unwatch_name (self->priv->watch_id);
+}
+
+static void
+pk_vanished_cb (GDBusConnection *conn,
+                const gchar *name,
+                gpointer user_data)
+{
+  GtkAppChooserOnlinePk *self = user_data;
+
+  /* just return */
+  g_simple_async_result_set_op_res_gboolean (self->priv->init_result, FALSE);
+  g_simple_async_result_complete (self->priv->init_result);
+
+  g_bus_unwatch_name (self->priv->watch_id);
+
+  g_clear_object (&self->priv->init_result);
+}
+
+static gboolean
+app_chooser_online_pk_init_finish (GAsyncInitable *init,
+                                   GAsyncResult *res,
+                                   GError **error)
+{
+  return g_simple_async_result_get_op_res_gboolean (G_SIMPLE_ASYNC_RESULT (res));
+}
+
+static void
+app_chooser_online_pk_init_async (GAsyncInitable *init,
+                                  int io_priority,
+                                  GCancellable *cancellable,
+                                  GAsyncReadyCallback callback,
+                                  gpointer user_data)
+{
+  GtkAppChooserOnlinePk *self = GTK_APP_CHOOSER_ONLINE_PK (init);
+
+  self->priv->init_result = g_simple_async_result_new (G_OBJECT (self),
+                                                       callback, user_data,
+                                                       gtk_app_chooser_online_get_default_async);
+
+  self->priv->watch_id =
+    g_bus_watch_name (G_BUS_TYPE_SESSION,
+                      "org.freedesktop.PackageKit",
+                      G_BUS_NAME_WATCHER_FLAGS_AUTO_START,
+                      pk_appeared_cb,
+                      pk_vanished_cb,
+                      self,
+                      NULL);
+}
+
+static void
+app_chooser_online_pk_async_initable_init (GAsyncInitableIface *iface)
+{
+  iface->init_async = app_chooser_online_pk_init_async;
+  iface->init_finish = app_chooser_online_pk_init_finish;
 }



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