]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkappchooseronlinepk.c
filechooserbutton: Emit 'selection-changed' when changing the selection programmatically
[~andy/gtk] / gtk / gtkappchooseronlinepk.c
index d307fb89be799509bd9dcdfb60ffd114eaf23346..5b70a5d75cd74efb62bab555b1eb742beca44322 100644 (file)
@@ -14,9 +14,7 @@
  * Library General Public License for more details.
  *
  * You should have received a copy of the GNU Library General Public
- * License along with the Gnome Library; see the file COPYING.LIB.  If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  *
  * Authors: Cosimo Cecchi <ccecchi@redhat.com>
  */
 
 #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 +45,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 +69,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));
 }
@@ -112,43 +116,36 @@ install_mime_types_ready_cb (GObject      *source,
     }
 
   g_simple_async_result_complete (self->priv->result);
+  g_clear_object (&self->priv->result);
 }
 
 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,
+                      GCancellable        *cancellable,
+                      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));
-  xid = GDK_WINDOW_XID (window);
-#else
-  xid = 0;
+  window = gtk_widget_get_window (GTK_WIDGET (parent));
+  if (GDK_IS_X11_WINDOW (window))
+    xid = GDK_WINDOW_XID (window);
 #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,
@@ -156,40 +153,112 @@ pk_proxy_appeared_cb (GObject      *source,
                                     "hide-confirm-search"),
                      G_DBUS_CALL_FLAGS_NONE,
                      G_MAXINT, /* no timeout */
-                     NULL,
+                     cancellable,
                      install_mime_types_ready_cb,
                      self);
 }
 
 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;
 }