GApplication: Add a menu example to the docs
[platform/upstream/glib.git] / gio / gapplication.c
index e97bf2e..fe94183 100644 (file)
@@ -27,6 +27,7 @@
 #include "gapplicationcommandline.h"
 #include "gapplicationimpl.h"
 #include "gactiongroup.h"
+#include "gmenumodel.h"
 #include "gsettings.h"
 
 #include "gioenumtypes.h"
  * GApplication also implements the #GActionGroup interface and lets you
  * easily export actions by adding them with g_application_set_action_group().
  * When invoking an action by calling g_action_group_activate_action() on
- * the application, it is always invoked in the primary instance.
+ * the application, it is always invoked in the primary instance. The actions
+ * are also exported on the session bus, and GIO provides the #GDBusActionGroup
+ * wrapper to conveniently access them remotely. Additionally,
+ * g_application_set_menu() can be used to export representation data
+ * for the actions, in the form of a  #GMenuModel.
  *
  * There is a number of different entry points into a #GApplication:
  * <itemizedlist>
  * </xi:include>
  * </programlisting>
  * </example>
+ *
+ * <example id="gapplication-example-menu"><title>A GApplication with menus</title>
+ * <programlisting>
+ * <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../gio/tests/gapplication-example-menu.c">
+ *   <xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback>
+ * </xi:include>
+ * </programlisting>
+ * </example>
  */
 
 struct _GApplicationPrivate
@@ -149,6 +162,7 @@ struct _GApplicationPrivate
   gchar             *id;
 
   GActionGroup      *actions;
+  GMenuModel        *menu;
 
   guint              inactivity_timeout_id;
   guint              inactivity_timeout;
@@ -159,7 +173,7 @@ struct _GApplicationPrivate
   guint              did_startup : 1;
   guint              did_shutdown : 1;
 
-  GHashTable        *remote_actions;  /* string -> RemoteActionInfo */
+  GActionGroup      *remote_actions;
   GApplicationImpl  *impl;
 };
 
@@ -171,7 +185,8 @@ enum
   PROP_IS_REGISTERED,
   PROP_IS_REMOTE,
   PROP_INACTIVITY_TIMEOUT,
-  PROP_ACTION_GROUP
+  PROP_ACTION_GROUP,
+  PROP_MENU
 };
 
 enum
@@ -393,6 +408,11 @@ g_application_set_property (GObject      *object,
                                       g_value_get_object (value));
       break;
 
+    case PROP_MENU:
+      g_application_set_menu (application,
+                              g_value_get_object (value));
+      break;
+
     default:
       g_assert_not_reached ();
     }
@@ -405,7 +425,7 @@ g_application_set_property (GObject      *object,
  *
  * Sets or unsets the group of actions associated with the application.
  *
- * These actions are the actions that can be remotely invoked.
+ * These actions can be invoked remotely.
  *
  * It is an error to call this function after the application has been
  * registered.
@@ -428,6 +448,54 @@ g_application_set_action_group (GApplication *application,
     g_object_ref (application->priv->actions);
 }
 
+/**
+ * g_application_set_menu:
+ * @application: a #GApplication
+ * @menu: (allow-none): a #GMenuModel, or %NULL
+ *
+ * Sets or unsets the menu associated with the application. The menu
+ * provides representation data for the exported actions of @application.
+ *
+ * It is an error to call this function after the application has been
+ * registered.
+ *
+ * Since: 2.32
+ */
+void
+g_application_set_menu (GApplication *application,
+                        GMenuModel   *menu)
+{
+  g_return_if_fail (G_IS_APPLICATION (application));
+  g_return_if_fail (!application->priv->is_registered);
+
+  if (application->priv->menu != NULL)
+    g_object_unref (application->priv->menu);
+
+  application->priv->menu = menu;
+
+  if (application->priv->menu != NULL)
+    g_object_ref (application->priv->menu);
+}
+
+/**
+ * g_application_get_menu:
+ * @application: a #GApplication
+ *
+ * Returns the menu model that has been set
+ * with g_application_set_menu().
+ *
+ * Returns: the #GMenuModel associated with @application
+ *
+ * Since: 2.32
+ */
+GMenuModel *
+g_application_get_menu (GApplication *application)
+{
+  g_return_val_if_fail (G_IS_APPLICATION (application), NULL);
+
+  return application->priv->menu;
+}
+
 static void
 g_application_get_property (GObject    *object,
                             guint       prop_id,
@@ -563,6 +631,13 @@ g_application_class_init (GApplicationClass *class)
                          G_TYPE_ACTION_GROUP,
                          G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
 
+  g_object_class_install_property (object_class, PROP_MENU,
+    g_param_spec_object ("menu",
+                         P_("Menu model"),
+                         P_("The menu that the application exports"),
+                         G_TYPE_MENU_MODEL,
+                         G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
+
   /**
    * GApplication::startup:
    * @application: the application
@@ -1361,23 +1436,7 @@ g_application_list_actions (GActionGroup *action_group)
   g_return_val_if_fail (application->priv->is_registered, NULL);
 
   if (application->priv->remote_actions != NULL)
-    {
-      GHashTableIter iter;
-      gint n, i = 0;
-      gchar **keys;
-      gpointer key;
-
-      n = g_hash_table_size (application->priv->remote_actions);
-      keys = g_new (gchar *, n + 1);
-
-      g_hash_table_iter_init (&iter, application->priv->remote_actions);
-      while (g_hash_table_iter_next (&iter, &key, NULL))
-        keys[i++] = g_strdup (key);
-      g_assert_cmpint (i, ==, n);
-      keys[n] = NULL;
-
-      return keys;
-    }
+    return g_action_group_list_actions (application->priv->remote_actions);
 
   else if (application->priv->actions != NULL)
     return g_action_group_list_actions (application->priv->actions);
@@ -1398,43 +1457,25 @@ g_application_query_action (GActionGroup        *group,
 {
   GApplication *application = G_APPLICATION (group);
 
-  if (application->priv->remote_actions != NULL)
-    {
-      RemoteActionInfo *info;
-
-      info = g_hash_table_lookup (application->priv->remote_actions,
-                                  action_name);
-
-      if (info == NULL)
-        return FALSE;
-
-      if (enabled)
-        *enabled = info->enabled;
-
-      if (parameter_type)
-        *parameter_type = info->parameter_type;
-
-      if (state_type)
-        *state_type = info->state ? g_variant_get_type (info->state) : NULL;
-
-      if (state_hint)
-        *state_hint = NULL;
+  g_return_val_if_fail (application->priv->is_registered, FALSE);
 
-      if (state)
-        *state = info->state ? g_variant_ref (info->state) : NULL;
+  if (application->priv->remote_actions != NULL)
+    return g_action_group_query_action (application->priv->remote_actions,
+                                        action_name,
+                                        enabled,
+                                        parameter_type,
+                                        state_type,
+                                        state_hint,
+                                        state);
 
-      return TRUE;
-    }
-  else if (application->priv->actions != NULL)
-    {
-      return g_action_group_query_action (application->priv->actions,
-                                          action_name,
-                                          enabled,
-                                          parameter_type,
-                                          state_type,
-                                          state_hint,
-                                          state);
-    }
+  if (application->priv->actions != NULL)
+    return g_action_group_query_action (application->priv->actions,
+                                        action_name,
+                                        enabled,
+                                        parameter_type,
+                                        state_type,
+                                        state_hint,
+                                        state);
 
   return FALSE;
 }
@@ -1450,10 +1491,8 @@ g_application_change_action_state (GActionGroup *action_group,
                     application->priv->actions != NULL);
   g_return_if_fail (application->priv->is_registered);
 
-  if (application->priv->is_remote)
-    g_application_impl_change_action_state (application->priv->impl,
-                                            action_name, value,
-                                            get_platform_data (application));
+  if (application->priv->remote_actions)
+    return g_action_group_change_action_state (application->priv->remote_actions, action_name, value);
 
   else
     g_action_group_change_action_state (application->priv->actions,
@@ -1471,10 +1510,8 @@ g_application_activate_action (GActionGroup *action_group,
                     application->priv->actions != NULL);
   g_return_if_fail (application->priv->is_registered);
 
-  if (application->priv->is_remote)
-    g_application_impl_activate_action (application->priv->impl,
-                                        action_name, parameter,
-                                        get_platform_data (application));
+  if (application->priv->remote_actions)
+    return g_action_group_change_action_state (application->priv->remote_actions, action_name, parameter);
 
   else
     g_action_group_activate_action (application->priv->actions,