]> Pileus Git - ~andy/gtk/blob - gtk/gtkappchooseronlinepk.c
stylecontext: Do invalidation on first resize container
[~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 this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  * Authors: Cosimo Cecchi <ccecchi@redhat.com>
20  */
21
22 #include "config.h"
23
24 #include "gtkappchooseronlinepk.h"
25
26 #include "gtkappchooseronline.h"
27 #ifdef GDK_WINDOWING_X11
28 #include "x11/gdkx.h"
29 #endif
30
31 #include <gio/gio.h>
32
33 #define gtk_app_chooser_online_pk_get_type _gtk_app_chooser_online_pk_get_type
34 static void app_chooser_online_iface_init (GtkAppChooserOnlineInterface *iface);
35 static void app_chooser_online_pk_async_initable_init (GAsyncInitableIface *iface);
36
37 G_DEFINE_TYPE_WITH_CODE (GtkAppChooserOnlinePk, gtk_app_chooser_online_pk,
38                          G_TYPE_OBJECT,
39                          G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE,
40                                                 app_chooser_online_pk_async_initable_init)
41                          G_IMPLEMENT_INTERFACE (GTK_TYPE_APP_CHOOSER_ONLINE,
42                                                 app_chooser_online_iface_init)
43                          g_io_extension_point_implement ("gtkappchooser-online",
44                                                          g_define_type_id,
45                                                          "packagekit", 10));
46
47 struct _GtkAppChooserOnlinePkPrivate {
48   GSimpleAsyncResult *init_result;
49   guint watch_id;
50
51   GDBusProxy *proxy;
52   GSimpleAsyncResult *result;
53   GtkWindow *parent;
54 };
55
56 static void
57 gtk_app_chooser_online_pk_dispose (GObject *obj)
58 {
59   GtkAppChooserOnlinePk *self = GTK_APP_CHOOSER_ONLINE_PK (obj);
60
61   g_clear_object (&self->priv->result);
62   g_clear_object (&self->priv->proxy);
63
64   G_OBJECT_CLASS (gtk_app_chooser_online_pk_parent_class)->dispose (obj);
65 }
66
67 static void
68 gtk_app_chooser_online_pk_class_init (GtkAppChooserOnlinePkClass *klass)
69 {
70   GObjectClass *oclass = G_OBJECT_CLASS (klass);
71
72   oclass->dispose = gtk_app_chooser_online_pk_dispose;
73
74   g_type_class_add_private (klass, sizeof (GtkAppChooserOnlinePkPrivate));
75 }
76
77 static void
78 gtk_app_chooser_online_pk_init (GtkAppChooserOnlinePk *self)
79 {
80   self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTK_TYPE_APP_CHOOSER_ONLINE_PK,
81                                             GtkAppChooserOnlinePkPrivate);
82 }
83
84 static gboolean
85 pk_search_mime_finish (GtkAppChooserOnline *obj,
86                        GAsyncResult *res,
87                        GError **error)
88 {
89   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
90
91   return !g_simple_async_result_propagate_error (simple, error);
92 }
93
94 static void
95 install_mime_types_ready_cb (GObject      *source,
96                              GAsyncResult *res,
97                              gpointer      user_data)
98 {
99   GtkAppChooserOnlinePk *self = user_data;
100   GDBusProxy *proxy = G_DBUS_PROXY (source);
101   GError *error = NULL;
102   GVariant *variant;
103
104   variant = g_dbus_proxy_call_finish (proxy, res, &error);
105
106   if (variant == NULL)
107     {
108       /* don't show errors if the user cancelled the installation explicitely
109        * or if PK wasn't able to find any apps
110        */
111       if (g_strcmp0 (g_dbus_error_get_remote_error (error), "org.freedesktop.PackageKit.Modify.Cancelled") != 0 &&
112           g_strcmp0 (g_dbus_error_get_remote_error (error), "org.freedesktop.PackageKit.Modify.NoPackagesFound") != 0)
113         g_simple_async_result_set_from_error (self->priv->result, error);
114
115       g_error_free (error);
116     }
117
118   g_simple_async_result_complete (self->priv->result);
119   g_clear_object (&self->priv->result);
120 }
121
122 static void
123 pk_search_mime_async (GtkAppChooserOnline *obj,
124                       const gchar         *content_type,
125                       GtkWindow           *parent,
126                       GCancellable        *cancellable,
127                       GAsyncReadyCallback  callback,
128                       gpointer             user_data)
129 {
130   GtkAppChooserOnlinePk *self = GTK_APP_CHOOSER_ONLINE_PK (obj);
131   guint xid = 0;
132   GdkWindow *window;
133   const gchar *mime_types[2];
134
135   self->priv->result = g_simple_async_result_new (G_OBJECT (self),
136                                                   callback, user_data,
137                                                   _gtk_app_chooser_online_search_for_mimetype_async);
138
139 #ifdef GDK_WINDOWING_X11
140   window = gtk_widget_get_window (GTK_WIDGET (parent));
141   if (GDK_IS_X11_WINDOW (window))
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 }