]> Pileus Git - ~andy/gtk/blob - gtk/gtkappchooseronlinepk.c
testgtk: Use symbolic names for button numbers
[~andy/gtk] / gtk / gtkappchooseronlinepk.c
1 /*
2  * gtkappchooseronlinepk.c: packagekit module for app-chooser
3  *
4  * Copyright (C) 2010 Red Hat, Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public License as
8  * published by the Free Software Foundation; either version 2 of the
9  * License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with the Gnome Library; see the file COPYING.LIB.  If not,
18  * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  *
21  * Authors: Cosimo Cecchi <ccecchi@redhat.com>
22  */
23
24 #include "config.h"
25
26 #include "gtkappchooseronlinepk.h"
27
28 #include "gtkappchooseronline.h"
29 #ifdef GDK_WINDOWING_X11
30 #include "x11/gdkx.h"
31 #endif
32
33 #include <gio/gio.h>
34
35 #define gtk_app_chooser_online_pk_get_type _gtk_app_chooser_online_pk_get_type
36 static void app_chooser_online_iface_init (GtkAppChooserOnlineInterface *iface);
37 static void app_chooser_online_pk_async_initable_init (GAsyncInitableIface *iface);
38
39 G_DEFINE_TYPE_WITH_CODE (GtkAppChooserOnlinePk, gtk_app_chooser_online_pk,
40                          G_TYPE_OBJECT,
41                          G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE,
42                                                 app_chooser_online_pk_async_initable_init)
43                          G_IMPLEMENT_INTERFACE (GTK_TYPE_APP_CHOOSER_ONLINE,
44                                                 app_chooser_online_iface_init)
45                          g_io_extension_point_implement ("gtkappchooser-online",
46                                                          g_define_type_id,
47                                                          "packagekit", 10));
48
49 struct _GtkAppChooserOnlinePkPrivate {
50   GSimpleAsyncResult *init_result;
51   guint watch_id;
52
53   GDBusProxy *proxy;
54   GSimpleAsyncResult *result;
55   GtkWindow *parent;
56 };
57
58 static void
59 gtk_app_chooser_online_pk_dispose (GObject *obj)
60 {
61   GtkAppChooserOnlinePk *self = GTK_APP_CHOOSER_ONLINE_PK (obj);
62
63   g_clear_object (&self->priv->result);
64   g_clear_object (&self->priv->proxy);
65
66   G_OBJECT_CLASS (gtk_app_chooser_online_pk_parent_class)->dispose (obj);
67 }
68
69 static void
70 gtk_app_chooser_online_pk_class_init (GtkAppChooserOnlinePkClass *klass)
71 {
72   GObjectClass *oclass = G_OBJECT_CLASS (klass);
73
74   oclass->dispose = gtk_app_chooser_online_pk_dispose;
75
76   g_type_class_add_private (klass, sizeof (GtkAppChooserOnlinePkPrivate));
77 }
78
79 static void
80 gtk_app_chooser_online_pk_init (GtkAppChooserOnlinePk *self)
81 {
82   self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTK_TYPE_APP_CHOOSER_ONLINE_PK,
83                                             GtkAppChooserOnlinePkPrivate);
84 }
85
86 static gboolean
87 pk_search_mime_finish (GtkAppChooserOnline *obj,
88                        GAsyncResult *res,
89                        GError **error)
90 {
91   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
92
93   return !g_simple_async_result_propagate_error (simple, error);
94 }
95
96 static void
97 install_mime_types_ready_cb (GObject      *source,
98                              GAsyncResult *res,
99                              gpointer      user_data)
100 {
101   GtkAppChooserOnlinePk *self = user_data;
102   GDBusProxy *proxy = G_DBUS_PROXY (source);
103   GError *error = NULL;
104   GVariant *variant;
105
106   variant = g_dbus_proxy_call_finish (proxy, res, &error);
107
108   if (variant == NULL)
109     {
110       /* don't show errors if the user cancelled the installation explicitely
111        * or if PK wasn't able to find any apps
112        */
113       if (g_strcmp0 (g_dbus_error_get_remote_error (error), "org.freedesktop.PackageKit.Modify.Cancelled") != 0 &&
114           g_strcmp0 (g_dbus_error_get_remote_error (error), "org.freedesktop.PackageKit.Modify.NoPackagesFound") != 0)
115         g_simple_async_result_set_from_error (self->priv->result, error);
116
117       g_error_free (error);
118     }
119
120   g_simple_async_result_complete (self->priv->result);
121 }
122
123 static void
124 pk_search_mime_async (GtkAppChooserOnline *obj,
125                       const gchar         *content_type,
126                       GtkWindow           *parent,
127                       GCancellable        *cancellable,
128                       GAsyncReadyCallback  callback,
129                       gpointer             user_data)
130 {
131   GtkAppChooserOnlinePk *self = GTK_APP_CHOOSER_ONLINE_PK (obj);
132   guint xid = 0;
133   GdkWindow *window;
134   const gchar *mime_types[2];
135
136   self->priv->result = g_simple_async_result_new (G_OBJECT (self),
137                                                   callback, user_data,
138                                                   _gtk_app_chooser_online_search_for_mimetype_async);
139
140 #ifdef GDK_WINDOWING_X11
141   window = gtk_widget_get_window (GTK_WIDGET (parent));
142   xid = GDK_WINDOW_XID (window);
143 #endif
144
145   mime_types[0] = content_type;
146   mime_types[1] = NULL;
147
148   g_dbus_proxy_call (self->priv->proxy,
149                      "InstallMimeTypes",
150                      g_variant_new ("(u^ass)",
151                                     xid,
152                                     mime_types,
153                                     "hide-confirm-search"),
154                      G_DBUS_CALL_FLAGS_NONE,
155                      G_MAXINT, /* no timeout */
156                      cancellable,
157                      install_mime_types_ready_cb,
158                      self);
159 }
160
161 static void
162 app_chooser_online_iface_init (GtkAppChooserOnlineInterface *iface)
163 {
164   iface->search_for_mimetype_async = pk_search_mime_async;
165   iface->search_for_mimetype_finish = pk_search_mime_finish;
166 }
167
168 static void
169 pk_proxy_created_cb (GObject *source,
170                      GAsyncResult *result,
171                      gpointer user_data)
172 {
173   GtkAppChooserOnlinePk *self = user_data;
174   GDBusProxy *proxy;
175
176   proxy = g_dbus_proxy_new_finish (result, NULL);
177
178   if (proxy == NULL)
179     {
180       g_simple_async_result_set_op_res_gboolean (self->priv->init_result, FALSE);
181     }
182   else
183     {
184       g_simple_async_result_set_op_res_gboolean (self->priv->init_result, TRUE);
185       self->priv->proxy = proxy;
186     }
187
188   g_simple_async_result_complete (self->priv->init_result);
189   g_clear_object (&self->priv->init_result);
190 }
191
192 static void
193 pk_appeared_cb (GDBusConnection *conn,
194                 const gchar *name,
195                 const gchar *owner,
196                 gpointer user_data)
197 {
198   GtkAppChooserOnlinePk *self = user_data;
199
200   /* create the proxy */
201   g_dbus_proxy_new (conn, 0, NULL,
202                     "org.freedesktop.PackageKit",
203                     "/org/freedesktop/PackageKit",
204                     "org.freedesktop.PackageKit.Modify",
205                     NULL,
206                     pk_proxy_created_cb,
207                     self);
208
209   g_bus_unwatch_name (self->priv->watch_id);
210 }
211
212 static void
213 pk_vanished_cb (GDBusConnection *conn,
214                 const gchar *name,
215                 gpointer user_data)
216 {
217   GtkAppChooserOnlinePk *self = user_data;
218
219   /* just return */
220   g_simple_async_result_set_op_res_gboolean (self->priv->init_result, FALSE);
221   g_simple_async_result_complete (self->priv->init_result);
222
223   g_bus_unwatch_name (self->priv->watch_id);
224
225   g_clear_object (&self->priv->init_result);
226 }
227
228 static gboolean
229 app_chooser_online_pk_init_finish (GAsyncInitable *init,
230                                    GAsyncResult *res,
231                                    GError **error)
232 {
233   return g_simple_async_result_get_op_res_gboolean (G_SIMPLE_ASYNC_RESULT (res));
234 }
235
236 static void
237 app_chooser_online_pk_init_async (GAsyncInitable *init,
238                                   int io_priority,
239                                   GCancellable *cancellable,
240                                   GAsyncReadyCallback callback,
241                                   gpointer user_data)
242 {
243   GtkAppChooserOnlinePk *self = GTK_APP_CHOOSER_ONLINE_PK (init);
244
245   self->priv->init_result = g_simple_async_result_new (G_OBJECT (self),
246                                                        callback, user_data,
247                                                        _gtk_app_chooser_online_get_default_async);
248
249   self->priv->watch_id =
250     g_bus_watch_name (G_BUS_TYPE_SESSION,
251                       "org.freedesktop.PackageKit",
252                       G_BUS_NAME_WATCHER_FLAGS_AUTO_START,
253                       pk_appeared_cb,
254                       pk_vanished_cb,
255                       self,
256                       NULL);
257 }
258
259 static void
260 app_chooser_online_pk_async_initable_init (GAsyncInitableIface *iface)
261 {
262   iface->init_async = app_chooser_online_pk_init_async;
263   iface->init_finish = app_chooser_online_pk_init_finish;
264 }