Commit 51cb0820 authored by Cosimo Cecchi's avatar Cosimo Cecchi

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
parent 134e7417
......@@ -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 \
......
......@@ -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;
......
......@@ -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);
}
......@@ -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
......
......@@ -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__ */
/*
* gtkappchooseronlinedummy.c: an extension point for online integration
*
* Copyright (C) 2010 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* 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.
*
* Authors: Cosimo Cecchi <ccecchi@redhat.com>
*/
#include <config.h>
#include "gtkappchooseronlinedummy.h"
#include "gtkintl.h"
#include "gtkappchooseronline.h"
#include <gio/gio.h>
#define gtk_app_chooser_online_dummy_get_type _gtk_app_chooser_online_dummy_get_type
static void app_chooser_online_iface_init (GtkAppChooserOnlineInterface *iface);
G_DEFINE_TYPE_WITH_CODE (GtkAppChooserOnlineDummy, gtk_app_chooser_online_dummy,
G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GTK_TYPE_APP_CHOOSER_ONLINE,
app_chooser_online_iface_init)
g_io_extension_point_implement ("gtkappchooser-online",
g_define_type_id,
"dummy", 0));
static void
gtk_app_chooser_online_dummy_class_init (GtkAppChooserOnlineDummyClass *klass)
{
/* do nothing */
}
static void
gtk_app_chooser_online_dummy_init (GtkAppChooserOnlineDummy *self)
{
/* do nothing */
}
static gboolean
dummy_search_mime_finish (GtkAppChooserOnline *obj,
GAsyncResult *res,
GError **error)
{
GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
return !g_simple_async_result_propagate_error (simple, error);
}
static void
dummy_search_mime_async (GtkAppChooserOnline *obj,
const gchar *content_type,
GtkWindow *parent,
GAsyncReadyCallback callback,
gpointer user_data)
{
g_simple_async_report_error_in_idle (G_OBJECT (obj),
callback, user_data,
G_IO_ERROR,
G_IO_ERROR_FAILED,
"%s",
_("Operation not supported"));
}
static void
app_chooser_online_iface_init (GtkAppChooserOnlineInterface *iface)
{
iface->search_for_mimetype_async = dummy_search_mime_async;
iface->search_for_mimetype_finish = dummy_search_mime_finish;
}
/*
* gtkappchooseronlinedummy.h: an extension point for online integration
*
* Copyright (C) 2010 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* 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.
*
* Authors: Cosimo Cecchi <ccecchi@redhat.com>
*/
#ifndef __GTK_APP_CHOOSER_ONLINE_DUMMY_H__
#define __GTK_APP_CHOOSER_ONLINE_DUMMY_H__
#include <gtk/gtkappchooseronline.h>
#include <glib.h>
#define GTK_TYPE_APP_CHOOSER_ONLINE_DUMMY (_gtk_app_chooser_online_dummy_get_type ())
#define GTK_APP_CHOOSER_ONLINE_DUMMY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_APP_CHOOSER_ONLINE_DUMMY, GtkAppChooserOnlineDummy))
#define GTK_APP_CHOOSER_ONLINE_DUMMY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_APP_CHOOSER_ONLINE_DUMMY, GtkAppChooserOnlineDummyClass))
#define GTK_IS_APP_CHOOSER_ONLINE_DUMMY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_APP_CHOOSER_ONLINE_DUMMY))
#define GTK_IS_APP_CHOOSER_ONLINE_DUMMY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_APP_CHOOSER_ONLINE_DUMMY))
#define GTK_APP_CHOOSER_ONLINE_DUMMY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_APP_CHOOSER_ONLINE_DUMMY, GtkAppChooserOnlineDummyClass))
typedef struct _GtkAppChooserOnlineDummy GtkAppChooserOnlineDummy;
typedef struct _GtkAppChooserOnlineDummyClass GtkAppChooserOnlineDummyClass;
typedef struct _GtkAppChooserOnlineDummyPrivate GtkAppChooserOnlineDummyPrivate;
struct _GtkAppChooserOnlineDummy {
GObject parent;
};
struct _GtkAppChooserOnlineDummyClass {
GObjectClass parent_class;
GtkAppChooserOnlineDummy *priv;
};
GType _gtk_app_chooser_online_dummy_get_type (void);
#endif /* __GTK_APP_CHOOSER_ONLINE_DUMMY_H__ */
......@@ -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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment