summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Soriano <csoriano@gnome.org>2015-07-05 19:54:35 +0200
committerCarlos Soriano <csoriano@gnome.org>2015-07-05 19:54:35 +0200
commit19f74cb5677f29a87d26346535833382c0c48877 (patch)
tree37cd1c6284d3e9d596a1f0ceeca6c11047487201
parent5f55f24a4ab2fcb007dde5837f2fc31836091052 (diff)
downloadgtk+-19f74cb5677f29a87d26346535833382c0c48877.tar.gz
f
-rw-r--r--gtk/gtkcloudprovider.c201
-rw-r--r--gtk/gtkcloudprovider.h5
-rw-r--r--gtk/gtkcloudprovidermanager.c10
-rw-r--r--tests/testcloudproviderclient.c67
-rw-r--r--tests/testcloudproviderserver.c231
5 files changed, 466 insertions, 48 deletions
diff --git a/gtk/gtkcloudprovider.c b/gtk/gtkcloudprovider.c
index 9e29d9e371..ebc22de547 100644
--- a/gtk/gtkcloudprovider.c
+++ b/gtk/gtkcloudprovider.c
@@ -29,6 +29,12 @@ static const gchar provider_xml[] =
" <method name='GetStatus'>"
" <arg type='i' name='name' direction='out'/>"
" </method>"
+ " <method name='GetIcon'>"
+ " <arg type='v' name='icon' direction='out'/>"
+ " </method>"
+ " <method name='GetPath'>"
+ " <arg type='s' name='path' direction='out'/>"
+ " </method>"
" </interface>"
"</node>";
@@ -38,11 +44,14 @@ typedef struct
gchar *name;
GtkCloudProviderStatus status;
GIcon *icon;
- GMenuModel *menu;
+ GMenuModel *menu_model;
+ GActionGroup *action_group;
+ GDBusConnection *bus;
GDBusProxy *proxy;
gchar *bus_name;
gchar *object_path;
+ GCancellable *cancellable;
} GtkCloudProviderPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (GtkCloudProvider, gtk_cloud_provider, G_TYPE_OBJECT)
@@ -54,6 +63,42 @@ enum {
static guint gSignals [LAST_SIGNAL];
+static void connect_to_items_changed (GMenuModel *model,
+ GCallback callback,
+ gpointer data);
+static void
+on_get_icon (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GtkCloudProvider *self = GTK_CLOUD_PROVIDER (user_data);
+ GtkCloudProviderPrivate *priv = gtk_cloud_provider_get_instance_private (self);
+ GError *error = NULL;
+ GVariant *variant_tuple;
+ GVariant *variant_dict;
+ GVariant *variant;
+
+ g_clear_object (&priv->icon);
+
+ variant_tuple = g_dbus_proxy_call_finish (priv->proxy, res, &error);
+ g_print ("variant tuple %s\n", g_variant_print (variant_tuple, TRUE));
+ if (error != NULL)
+ {
+ g_warning ("Error getting the provider icon %s", error->message);
+ goto out;
+ }
+
+ variant_dict = g_variant_get_child_value (variant_tuple, 0);
+ variant = g_variant_get_child_value (variant_dict, 0);
+ priv->icon = g_icon_deserialize (variant);
+ g_variant_unref (variant);
+ g_variant_unref (variant_dict);
+
+out:
+ g_variant_unref (variant_tuple);
+ g_signal_emit_by_name (self, "changed");
+}
+
static void
on_get_name (GObject *source_object,
GAsyncResult *res,
@@ -65,6 +110,9 @@ on_get_name (GObject *source_object,
GVariant *variant_tuple;
GVariant *variant;
+ if (priv->name != NULL)
+ g_free (priv->name);
+
variant_tuple = g_dbus_proxy_call_finish (priv->proxy, res, &error);
if (error != NULL)
{
@@ -108,6 +156,48 @@ out:
g_signal_emit_by_name (self, "changed");
}
+static void
+on_items_changed (GMenuModel *model,
+ gint position,
+ gint removed,
+ gint added,
+ gpointer user_data)
+{
+ GtkCloudProvider *self = GTK_CLOUD_PROVIDER (user_data);
+ GtkCloudProviderPrivate *priv = gtk_cloud_provider_get_instance_private (self);
+
+ g_print ("items changed\n");
+ connect_to_items_changed (model, G_CALLBACK (on_items_changed), self);
+ g_signal_emit_by_name (self, "changed");
+}
+
+static void
+connect_to_items_changed (GMenuModel *model,
+ GCallback callback,
+ gpointer data)
+{
+ gint i;
+ GMenuModel *m;
+ GMenuLinkIter *iter;
+
+ if (!g_object_get_data (G_OBJECT (model), "handler-connected"))
+ {
+ g_signal_connect (model, "items-changed", callback, data);
+ g_object_set_data (G_OBJECT (model), "handler-connected", GINT_TO_POINTER (1));
+ }
+ for (i = 0; i < g_menu_model_get_n_items (model); i++)
+ {
+ iter = g_menu_model_iterate_item_links (model, i);
+ while (g_menu_link_iter_next (iter))
+ {
+ m = g_menu_link_iter_get_value (iter);
+ connect_to_items_changed (m, callback, data);
+ g_object_unref (m);
+ }
+ g_object_unref (iter);
+ }
+}
+
void
gtk_cloud_provider_update (GtkCloudProvider *self)
{
@@ -132,6 +222,28 @@ gtk_cloud_provider_update (GtkCloudProvider *self)
NULL,
(GAsyncReadyCallback) on_get_status,
self);
+
+ g_dbus_proxy_call (priv->proxy,
+ "GetIcon",
+ g_variant_new ("()"),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ (GAsyncReadyCallback) on_get_icon,
+ self);
+
+ priv->menu_model = (GMenuModel*) g_dbus_menu_model_get (priv->bus,
+ priv->bus_name,
+ priv->object_path);
+ connect_to_items_changed (priv->menu_model,
+ G_CALLBACK (on_items_changed),
+ self);
+
+ g_print ("n items %d\n", g_menu_model_get_n_items (priv->menu_model));
+ priv->action_group = (GActionGroup*) g_dbus_action_group_get (priv->bus,
+ priv->bus_name,
+ priv->object_path);
+
}
}
@@ -141,45 +253,81 @@ on_proxy_created (GObject *source_object,
gpointer user_data)
{
GError *error = NULL;
- GtkCloudProvider *self = GTK_CLOUD_PROVIDER (user_data);
- GtkCloudProviderPrivate *priv = gtk_cloud_provider_get_instance_private (self);
+ GtkCloudProvider *self;
+ GtkCloudProviderPrivate *priv;
+ GDBusProxy *proxy;
- priv->proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
+ proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
if (error != NULL)
{
- g_warning ("Error creating proxy for cloud provider %s", error->message);
+ if (error->code != G_IO_ERROR_CANCELLED)
+ g_warning ("Error creating proxy for cloud provider %s", error->message);
return;
}
+ self = GTK_CLOUD_PROVIDER (user_data);
+ priv = gtk_cloud_provider_get_instance_private (self);
+
+ priv->proxy = proxy;
gtk_cloud_provider_update (self);
}
+static void
+on_bus_acquired (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GError *error = NULL;
+ GtkCloudProvider *self;
+ GDBusConnection *bus;
+ GtkCloudProviderPrivate *priv;
+ GDBusInterfaceInfo *interface_info;
+ GDBusNodeInfo *proxy_info;
+
+ bus = g_bus_get_finish (res, &error);
+ if (error != NULL)
+ {
+ if (error->code != G_IO_ERROR_CANCELLED)
+ g_warning ("Error acdquiring bus for cloud provider %s", error->message);
+ return;
+ }
+
+ self = GTK_CLOUD_PROVIDER (user_data);
+ priv = gtk_cloud_provider_get_instance_private (user_data);
+ priv->bus = bus;
+ proxy_info = g_dbus_node_info_new_for_xml (provider_xml, &error);
+ interface_info = g_dbus_node_info_lookup_interface (proxy_info, "org.gtk.CloudProvider");
+ g_clear_object (&priv->cancellable);
+ priv->cancellable = g_cancellable_new ();
+ g_dbus_proxy_new (priv->bus,
+ G_DBUS_PROXY_FLAGS_NONE,
+ interface_info,
+ priv->bus_name,
+ priv->object_path,
+ "org.gtk.CloudProvider",
+ priv->cancellable,
+ on_proxy_created,
+ self);
+}
+
GtkCloudProvider*
gtk_cloud_provider_new (const gchar *bus_name,
const gchar *object_path)
{
GtkCloudProvider *self;
GtkCloudProviderPrivate *priv;
- GDBusNodeInfo *proxy_info;
- GDBusInterfaceInfo *interface_info;
- GError *error = NULL;
self = g_object_new (GTK_TYPE_CLOUD_PROVIDER, NULL);
priv = gtk_cloud_provider_get_instance_private (self);
- proxy_info = g_dbus_node_info_new_for_xml (provider_xml, &error);
- interface_info = g_dbus_node_info_lookup_interface (proxy_info, "org.gtk.CloudProvider");
priv->bus_name = g_strdup (bus_name);
priv->object_path = g_strdup (object_path);
- g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
- G_DBUS_PROXY_FLAGS_NONE,
- interface_info,
- bus_name,
- object_path,
- "org.gtk.CloudProvider",
- NULL,
- on_proxy_created,
- self);
+ priv->cancellable = g_cancellable_new ();
+ priv->status = GTK_CLOUD_PROVIDER_STATUS_INVALID;
+ g_bus_get (G_BUS_TYPE_SESSION,
+ priv->cancellable,
+ on_bus_acquired,
+ self);
return self;
}
@@ -190,9 +338,13 @@ gtk_cloud_provider_finalize (GObject *object)
GtkCloudProvider *self = (GtkCloudProvider *)object;
GtkCloudProviderPrivate *priv = gtk_cloud_provider_get_instance_private (self);
+ g_cancellable_cancel (priv->cancellable);
+ g_clear_object (&priv->cancellable);
g_free (priv->name);
g_clear_object (&priv->icon);
- g_clear_object (&priv->menu);
+ g_clear_object (&priv->menu_model);
+ g_clear_object (&priv->action_group);
+ g_clear_object (&priv->bus);
g_clear_object (&priv->proxy);
g_free (priv->bus_name);
g_free (priv->object_path);
@@ -222,9 +374,12 @@ gtk_cloud_provider_class_init (GtkCloudProviderClass *klass)
static void
gtk_cloud_provider_init (GtkCloudProvider *self)
{
+ GtkCloudProviderPrivate *priv = gtk_cloud_provider_get_instance_private (self);
+
+ priv->status = GTK_CLOUD_PROVIDER_STATUS_INVALID;
}
-const gchar*
+gchar*
gtk_cloud_provider_get_name (GtkCloudProvider *self)
{
GtkCloudProviderPrivate *priv = gtk_cloud_provider_get_instance_private (self);
@@ -249,10 +404,10 @@ gtk_cloud_provider_get_icon (GtkCloudProvider *self)
}
GMenuModel*
-gtk_cloud_provider_get_menu (GtkCloudProvider *self)
+gtk_cloud_provider_get_menu_model (GtkCloudProvider *self)
{
GtkCloudProviderPrivate *priv = gtk_cloud_provider_get_instance_private (self);
- return priv->menu;
+ return priv->menu_model;
}
diff --git a/gtk/gtkcloudprovider.h b/gtk/gtkcloudprovider.h
index 198a3211a1..0e02c0100a 100644
--- a/gtk/gtkcloudprovider.h
+++ b/gtk/gtkcloudprovider.h
@@ -29,6 +29,7 @@
G_BEGIN_DECLS
typedef enum {
+ GTK_CLOUD_PROVIDER_STATUS_INVALID,
GTK_CLOUD_PROVIDER_STATUS_IDLE,
GTK_CLOUD_PROVIDER_STATUS_SYNCING,
GTK_CLOUD_PROVIDER_STATUS_ERROR
@@ -61,13 +62,13 @@ GDK_AVAILABLE_IN_3_18
GtkCloudProvider *gtk_cloud_provider_new (const gchar *bus_name,
const gchar *object_path);
GDK_AVAILABLE_IN_3_18
-const gchar* gtk_cloud_provider_get_name (GtkCloudProvider *self);
+gchar* gtk_cloud_provider_get_name (GtkCloudProvider *self);
GDK_AVAILABLE_IN_3_18
GtkCloudProviderStatus gtk_cloud_provider_get_status (GtkCloudProvider *self);
GDK_AVAILABLE_IN_3_18
GIcon *gtk_cloud_provider_get_icon (GtkCloudProvider *self);
GDK_AVAILABLE_IN_3_18
-GMenuModel *gtk_cloud_provider_get_menu (GtkCloudProvider *self);
+GMenuModel *gtk_cloud_provider_get_menu_model (GtkCloudProvider *self);
G_END_DECLS
diff --git a/gtk/gtkcloudprovidermanager.c b/gtk/gtkcloudprovidermanager.c
index 09d81d6ab2..9a161b615c 100644
--- a/gtk/gtkcloudprovidermanager.c
+++ b/gtk/gtkcloudprovidermanager.c
@@ -199,6 +199,16 @@ static void
on_cloud_provider_changed (GtkCloudProvider *cloud_provider,
GtkCloudProviderManager *self)
{
+ GIcon *icon;
+ gchar *name;
+ guint status;
+
+ name = gtk_cloud_provider_get_name (cloud_provider);
+ icon = gtk_cloud_provider_get_icon (cloud_provider);
+ status = gtk_cloud_provider_get_status (cloud_provider);
+ if (name == NULL || icon == NULL || status == GTK_CLOUD_PROVIDER_STATUS_INVALID)
+ return;
+
g_signal_emit_by_name (self, "changed", NULL);
}
diff --git a/tests/testcloudproviderclient.c b/tests/testcloudproviderclient.c
index 0cabf6c88a..8b9882c403 100644
--- a/tests/testcloudproviderclient.c
+++ b/tests/testcloudproviderclient.c
@@ -2,11 +2,40 @@
#include <glib.h>
#include <gtk/gtk.h>
-enum {
- IDLE,
- SYNCING,
- ERROR
-};
+static void
+print_gmenu_model (GMenuModel *model)
+{
+ gint i, n_items;
+ GMenuModel *submodel = NULL;
+ gchar *label;
+
+ n_items = g_menu_model_get_n_items (model);
+ g_print ("n items %d\n", n_items);
+
+ for (i = 0; i < n_items; i++)
+ {
+ label = NULL;
+ if (g_menu_model_get_item_attribute (model, i, G_MENU_ATTRIBUTE_LABEL, "s", &label))
+ {
+ g_print ("Menu item - %s\n", label);
+ if (label != NULL)
+ g_free (label);
+ }
+
+ submodel = g_menu_model_get_item_link (model, i, G_MENU_LINK_SECTION);
+ if (!submodel)
+ submodel = g_menu_model_get_item_link (model, i, G_MENU_LINK_SUBMENU);
+
+ if (!submodel)
+ {
+ g_print ("no submodel\n");
+ continue;
+ }
+
+ print_gmenu_model (submodel);
+ g_clear_object (&submodel);
+ }
+}
static void
on_manager_changed (GtkCloudProviderManager *manager)
@@ -15,6 +44,9 @@ on_manager_changed (GtkCloudProviderManager *manager)
GList *l;
gint provider_status;
gchar *status_string;
+ GIcon *icon;
+ gchar *icon_representation;
+ GMenuModel *menu_model;
providers = gtk_cloud_provider_manager_get_providers (manager);
g_print ("Providers data\n");
@@ -24,15 +56,19 @@ on_manager_changed (GtkCloudProviderManager *manager)
provider_status = gtk_cloud_provider_get_status (GTK_CLOUD_PROVIDER (l->data));
switch (provider_status)
{
- case IDLE:
+ case GTK_CLOUD_PROVIDER_STATUS_INVALID:
+ status_string = "invalid";
+ break;
+
+ case GTK_CLOUD_PROVIDER_STATUS_IDLE:
status_string = "idle";
break;
- case SYNCING:
+ case GTK_CLOUD_PROVIDER_STATUS_SYNCING:
status_string = "syncing";
break;
- case ERROR:
+ case GTK_CLOUD_PROVIDER_STATUS_ERROR:
status_string = "error";
break;
@@ -40,9 +76,18 @@ on_manager_changed (GtkCloudProviderManager *manager)
g_assert_not_reached ();
}
- g_print ("Name - %s Status - %s\n",
+ icon = gtk_cloud_provider_get_icon (l->data);
+ icon_representation = g_icon_to_string (icon);
+
+ g_print ("Name - %s Status - %s Icon - %s\n",
gtk_cloud_provider_get_name (GTK_CLOUD_PROVIDER (l->data)),
- status_string);
+ status_string,
+ icon_representation);
+
+ g_free (icon_representation);
+
+ menu_model = gtk_cloud_provider_get_menu_model (l->data);
+ print_gmenu_model (menu_model);
}
g_print ("\n");
}
@@ -59,9 +104,7 @@ main (gint argc,
//gtk_cloud_provider_manager_update (manager);
loop = g_main_loop_new (NULL, FALSE);
- g_print ("before loop\n");
g_main_loop_run (loop);
- g_print ("after\n");
return 0;
}
diff --git a/tests/testcloudproviderserver.c b/tests/testcloudproviderserver.c
index 3b61e1e8f2..926f9af743 100644
--- a/tests/testcloudproviderserver.c
+++ b/tests/testcloudproviderserver.c
@@ -1,13 +1,8 @@
#include <gio/gio.h>
#include <stdlib.h>
+#include <gtk/gtk.h>
-#define TIMEOUT 1000
-
-enum {
- IDLE,
- SYNCING,
- ERROR
-};
+#define TIMEOUT 2000
typedef struct _CloudProviderClass CloudProviderClass;
typedef struct _CloudProvider CloudProvider;
@@ -23,6 +18,7 @@ struct _CloudProvider
gchar *name;
gint status;
+ GIcon *icon;
GDBusProxy *manager_proxy;
guint timeout_handler;
};
@@ -37,6 +33,8 @@ cloud_provider_finalize (GObject *object)
CloudProvider *self = (CloudProvider*)object;
g_free (self->name);
+ g_clear_object (&self->icon);
+ g_clear_object (&self->manager_proxy);
G_OBJECT_CLASS (cloud_provider_parent_class)->finalize (object);
}
@@ -44,8 +42,17 @@ cloud_provider_finalize (GObject *object)
static void
cloud_provider_init (CloudProvider *self)
{
+ GFile *icon_file;
+ gchar *uri;
+
self->name = "MyCloud";
- self->status = SYNCING;
+ self->status = GTK_CLOUD_PROVIDER_STATUS_INVALID;
+ uri = g_build_filename (g_get_current_dir (), "apple-red.png", NULL);
+ icon_file = g_file_new_for_uri (uri);
+ self->icon = g_file_icon_new (icon_file);
+
+ g_object_unref (icon_file);
+ g_free (uri);
}
static void
@@ -60,7 +67,7 @@ static void
cloud_provider_set_status (CloudProvider *self,
gint status)
{
- /* Inform manager that the provider changed */
+ /* Inform the manager that the provider changed */
self->status = status;
g_dbus_proxy_call (self->manager_proxy,
"CloudProviderChanged",
@@ -86,6 +93,9 @@ static const gchar provider_xml[] =
" <method name='GetStatus'>"
" <arg type='i' name='status' direction='out'/>"
" </method>"
+ " <method name='GetIcon'>"
+ " <arg type='v' name='icon' direction='out'/>"
+ " </method>"
" </interface>"
"</node>";
@@ -97,6 +107,196 @@ static const gchar manager_xml[] =
" </interface>"
"</node>";
+static const gchar menu_markup[] =
+ "<interface>\n"
+ "<menu id='menu'>\n"
+ " <section>\n"
+ " <item>\n"
+ " <attribute name='label' translatable='yes'>MyCloud website</attribute>\n"
+ " <attribute name='action'>website</attribute>\n"
+ " </item>\n"
+ " <item>\n"
+ " <attribute name='label' translatable='yes'>MyCloud Photos</attribute>\n"
+ " <attribute name='action'>photos</attribute>\n"
+ " </item>\n"
+ " <item>\n"
+ " <attribute name='label' translatable='yes'>MyCloud Notes</attribute>\n"
+ " <attribute name='action'>notes</attribute>\n"
+ " </item>\n"
+ " </section>\n"
+ " <section>\n"
+ " <item>\n"
+ " <attribute name='label' translatable='yes'>Allow Synchronization</attribute>\n"
+ " <attribute name='action'>allow-sync</attribute>\n"
+ " </item>\n"
+ " <submenu>\n"
+ " <attribute name='label' translatable='yes'>Buy Storage</attribute>\n"
+ " <item>\n"
+ " <attribute name='label' translatable='yes'>5GB for 200CZK</attribute>\n"
+ " <attribute name='action'>buy</attribute>\n"
+ " <attribute name='target'>5</attribute>\n"
+ " </item>\n"
+ " <item>\n"
+ " <attribute name='label' translatable='yes'>10GB for 500CZK</attribute>\n"
+ " <attribute name='action'>buy</attribute>\n"
+ " <attribute name='target'>10</attribute>\n"
+ " </item>\n"
+ " <item>\n"
+ " <attribute name='label' translatable='yes'>30GB for 600CZK</attribute>\n"
+ " <attribute name='action'>buy</attribute>\n"
+ " <attribute name='target'>30</attribute>\n"
+ " </item>\n"
+ " </submenu>\n"
+ " </section>\n"
+ "</menu>\n"
+ "</interface>\n";
+
+static void
+activate_action (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ g_print ("Action %s activated\n", g_action_get_name (G_ACTION (action)));
+}
+
+static void
+activate_toggle (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ GVariant *old_state, *new_state;
+
+ old_state = g_action_get_state (G_ACTION (action));
+ new_state = g_variant_new_boolean (!g_variant_get_boolean (old_state));
+
+ g_print ("Toggle action %s activated, state changes from %d to %d\n",
+ g_action_get_name (G_ACTION (action)),
+ g_variant_get_boolean (old_state),
+ g_variant_get_boolean (new_state));
+
+ g_simple_action_set_state (action, new_state);
+ g_variant_unref (old_state);
+}
+
+static void
+activate_radio (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ GVariant *old_state, *new_state;
+
+ old_state = g_action_get_state (G_ACTION (action));
+ new_state = g_variant_new_string (g_variant_get_string (parameter, NULL));
+
+ g_print ("Radio action %s activated, state changes from %s to %s\n",
+ g_action_get_name (G_ACTION (action)),
+ g_variant_get_string (old_state, NULL),
+ g_variant_get_string (new_state, NULL));
+
+ g_simple_action_set_state (action, new_state);
+ g_variant_unref (old_state);
+}
+
+static GActionEntry actions[] = {
+ { "website", activate_action, NULL, NULL, NULL },
+ { "photos", activate_action, NULL, NULL, NULL },
+ { "notes", activate_action, NULL, NULL, NULL },
+ { "allow-sync", activate_toggle, NULL, "true", NULL },
+ { "buy", activate_radio, "s", NULL, NULL },
+};
+
+static void
+print_gmenu_model (GMenuModel *model)
+{
+ gint i, n_items;
+ GMenuModel *submodel = NULL;
+ gchar *label;
+
+ n_items = g_menu_model_get_n_items (model);
+ g_print ("n items %d\n", n_items);
+
+ for (i = 0; i < n_items; i++)
+ {
+ label = NULL;
+ if (g_menu_model_get_item_attribute (model, i, G_MENU_ATTRIBUTE_LABEL, "s", &label))
+ {
+ g_print ("Menu item - %s\n", label);
+ if (label != NULL)
+ g_free (label);
+ }
+
+ submodel = g_menu_model_get_item_link (model, i, G_MENU_LINK_SECTION);
+ if (!submodel)
+ submodel = g_menu_model_get_item_link (model, i, G_MENU_LINK_SUBMENU);
+
+ if (!submodel)
+ {
+ g_print ("no submodel\n");
+ continue;
+ }
+
+ print_gmenu_model (submodel);
+ g_clear_object (&submodel);
+ }
+}
+
+static GMenuModel *
+get_model (void)
+{
+ GError *error = NULL;
+ GtkBuilder *builder;
+ GMenuModel *menu;
+
+ builder = gtk_builder_new ();
+ gtk_builder_add_from_string (builder, menu_markup, -1, &error);
+ g_assert_no_error (error);
+
+ menu = g_object_ref (gtk_builder_get_object (builder, "menu"));
+ g_object_unref (builder);
+
+ return menu;
+}
+
+static GActionGroup *
+get_action_group (void)
+{
+ GSimpleActionGroup *group;
+
+ group = g_simple_action_group_new ();
+
+ g_action_map_add_action_entries (G_ACTION_MAP (group),
+ actions,
+ G_N_ELEMENTS (actions), NULL);
+
+ return G_ACTION_GROUP (group);
+}
+
+static void
+export_menu (GDBusConnection *bus,
+ gchar *object_path)
+{
+ GMenuModel *model;
+ GActionGroup *action_group;
+ GError *error;
+
+ model = get_model ();
+ action_group = get_action_group ();
+ print_gmenu_model (model);
+
+ g_print ("Exporting menus on the bus...\n");
+ if (!g_dbus_connection_export_menu_model (bus, object_path, model, &error))
+ {
+ g_warning ("Menu export failed: %s", error->message);
+ exit (1);
+ }
+ g_print ("Exporting actions on the bus...\n");
+ if (!g_dbus_connection_export_action_group (bus, object_path, action_group, &error))
+ {
+ g_warning ("Action export failed: %s", error->message);
+ exit (1);
+ }
+}
+
static void
handle_method_call (GDBusConnection *connection,
const gchar *sender,
@@ -120,6 +320,11 @@ handle_method_call (GDBusConnection *connection,
g_dbus_method_invocation_return_value (invocation,
g_variant_new ("(i)", cloud_provider->status));
}
+ else if (g_strcmp0 (method_name, "GetIcon") == 0)
+ {
+ g_dbus_method_invocation_return_value (invocation,
+ g_variant_new ("(v)", g_icon_serialize (cloud_provider->icon)));
+ }
}
static const GDBusInterfaceVTable interface_vtable =
@@ -135,7 +340,7 @@ on_bus_acquired (GDBusConnection *connection,
CloudProvider *cloud_provider = user_data;
guint registration_id;
- g_print ("Registering cloud provider server 'MyCloud'\n");
+ g_debug ("Registering cloud provider server 'MyCloud'\n");
registration_id = g_dbus_connection_register_object (connection,
"/org/gtk/CloudProviderServerExample",
introspection_data->interfaces[0],
@@ -144,6 +349,8 @@ on_bus_acquired (GDBusConnection *connection,
NULL, /* user_data_free_func */
NULL); /* GError** */
g_assert (registration_id > 0);
+ /* Export a menu for our own application */
+ export_menu (connection, "/org/gtk/CloudProviderServerExample");
}
static void
@@ -169,7 +376,9 @@ change_provider (gpointer user_data)
gint new_status;
rand = g_rand_new ();
- new_status = g_rand_int_range (rand, IDLE, ERROR + 1);
+ new_status = g_rand_int_range (rand,
+ GTK_CLOUD_PROVIDER_STATUS_IDLE,
+ GTK_CLOUD_PROVIDER_STATUS_ERROR + 1);
cloud_provider_set_status (cloud_provider, new_status);