[gnome-control-center] shell: Use GVariant to convey panel arguments instead of a string array



commit 9977bb200ea66b2e8ee1d52d0400c4e27bf4b352
Author: Emanuele Aina <emanuele aina collabora com>
Date:   Fri Mar 1 11:18:08 2013 +0100

    shell: Use GVariant to convey panel arguments instead of a string array
    
    By using a GVariant of type "av" we can potentially pass more structured
    data to panels, which will become relevant with the ability to invoke
    them by GAction-based DBus-activation introduced in the following patch.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=696054

 panels/keyboard/cc-keyboard-panel.c               |   38 +++++++++++++++-----
 panels/network/cc-network-panel.c                 |   36 ++++++++++++++++----
 panels/online-accounts/cc-online-accounts-panel.c |   31 ++++++++++++----
 panels/sound/cc-sound-panel.c                     |   20 ++++++-----
 shell/cc-application.c                            |    9 ++++-
 shell/cc-panel-loader.c                           |    4 +-
 shell/cc-panel-loader.h                           |    2 +-
 shell/cc-panel.c                                  |   24 +++++++------
 shell/cc-shell.c                                  |    7 ++--
 shell/cc-shell.h                                  |    4 +-
 shell/cc-window.c                                 |   18 +++++-----
 11 files changed, 130 insertions(+), 63 deletions(-)
---
diff --git a/panels/keyboard/cc-keyboard-panel.c b/panels/keyboard/cc-keyboard-panel.c
index c2bbdc2..2a228ed 100644
--- a/panels/keyboard/cc-keyboard-panel.c
+++ b/panels/keyboard/cc-keyboard-panel.c
@@ -37,7 +37,7 @@ struct _CcKeyboardPanelPrivate
 
 enum {
   PROP_0,
-  PROP_ARGV
+  PROP_PARAMETERS
 };
 
 enum {
@@ -81,14 +81,32 @@ cc_keyboard_panel_set_property (GObject      *object,
 
   switch (property_id)
     {
-    case PROP_ARGV: {
-      gchar **args;
-
-      args = g_value_get_boxed (value);
-
-      if (args && args[0]) {
-        cc_keyboard_panel_set_page (panel, args[0], args[1]);
-      }
+    case PROP_PARAMETERS: {
+      GVariant *parameters, *v;
+      const gchar *page, *section;
+
+      parameters = g_value_get_variant (value);
+      if (!parameters)
+        break;
+      page = section = NULL;
+      switch (g_variant_n_children (parameters))
+        {
+          case 2:
+            g_variant_get_child (parameters, 1, "v", &v);
+            section = g_variant_get_string (v, NULL);
+            g_variant_unref (v);
+            /* fall-through */
+          case 1:
+            g_variant_get_child (parameters, 0, "v", &v);
+            page = g_variant_get_string (v, NULL);
+            g_variant_unref (v);
+            cc_keyboard_panel_set_page (panel, page, section);
+            /* fall-through */
+          case 0:
+            break;
+          default:
+            g_warning ("Unexpected parameters found, ignore request");
+        }
       break;
     }
 
@@ -164,7 +182,7 @@ cc_keyboard_panel_class_init (CcKeyboardPanelClass *klass)
   object_class->dispose = cc_keyboard_panel_dispose;
   object_class->finalize = cc_keyboard_panel_finalize;
 
-  g_object_class_override_property (object_class, PROP_ARGV, "argv");
+  g_object_class_override_property (object_class, PROP_PARAMETERS, "parameters");
 }
 
 static void
diff --git a/panels/network/cc-network-panel.c b/panels/network/cc-network-panel.c
index b276b96..7fe634b 100644
--- a/panels/network/cc-network-panel.c
+++ b/panels/network/cc-network-panel.c
@@ -102,7 +102,7 @@ enum {
 
 enum {
         PROP_0,
-        PROP_ARGV
+        PROP_PARAMETERS
 };
 
 static NetObject *find_in_model_by_id (CcNetworkPanel *panel, const gchar *id, GtkTreeIter *iter_out);
@@ -163,6 +163,23 @@ verify_argv (CcNetworkPanel *self,
        }
 }
 
+static GPtrArray *
+variant_av_to_string_array (GVariant *array)
+{
+        GVariantIter iter;
+        GVariant *v;
+        GPtrArray *strv;
+        gsize count;
+        count = g_variant_iter_init (&iter, array);
+        strv = g_ptr_array_sized_new (count + 1);
+        while (g_variant_iter_next (&iter, "v", &v)) {
+                g_ptr_array_add (strv, (gpointer *)g_variant_get_string (v, NULL));
+                g_variant_unref (v);
+        }
+        g_ptr_array_add (strv, NULL); /* NULL-terminate the strv data array */
+        return strv;
+}
+
 static void
 cc_network_panel_set_property (GObject      *object,
                                guint         property_id,
@@ -173,14 +190,18 @@ cc_network_panel_set_property (GObject      *object,
         CcNetworkPanelPrivate *priv = self->priv;
 
         switch (property_id) {
-        case PROP_ARGV: {
-                gchar **args;
+        case PROP_PARAMETERS: {
+                GVariant *parameters;
 
                 reset_command_line_args (self);
 
-                args = g_value_get_boxed (value);
+                parameters = g_value_get_variant (value);
+                if (parameters) {
+                        GPtrArray *array;
+                        const gchar **args;
+                        array = variant_av_to_string_array (parameters);
+                        args = array->pdata;
 
-                if (args) {
                         g_debug ("Invoked with operation %s", args[0]);
 
                         if (args[0])
@@ -192,9 +213,10 @@ cc_network_panel_set_property (GObject      *object,
 
                         if (verify_argv (self, (const char **) args) == FALSE) {
                                 reset_command_line_args (self);
+                                g_ptr_array_unref (array);
                                 return;
                         }
-
+                        g_ptr_array_unref (array);
                         g_debug ("Calling handle_argv() after setting property");
                         handle_argv (self);
                 }
@@ -377,7 +399,7 @@ cc_network_panel_class_init (CcNetworkPanelClass *klass)
         object_class->finalize = cc_network_panel_finalize;
         object_class->constructed = cc_network_panel_constructed;
 
-        g_object_class_override_property (object_class, PROP_ARGV, "argv");
+        g_object_class_override_property (object_class, PROP_PARAMETERS, "parameters");
 }
 
 static NetObject *
diff --git a/panels/online-accounts/cc-online-accounts-panel.c 
b/panels/online-accounts/cc-online-accounts-panel.c
index 3afb808..67b097e 100644
--- a/panels/online-accounts/cc-online-accounts-panel.c
+++ b/panels/online-accounts/cc-online-accounts-panel.c
@@ -91,7 +91,7 @@ CC_PANEL_REGISTER (CcGoaPanel, cc_goa_panel);
 
 enum {
   PROP_0,
-  PROP_ARGV
+  PROP_PARAMETERS
 };
 
 static void
@@ -102,14 +102,29 @@ cc_goa_panel_set_property (GObject *object,
 {
   switch (property_id)
     {
-      case PROP_ARGV:
+      case PROP_PARAMETERS:
         {
-          gchar **args;
+          GVariant *parameters, *v;
+          const gchar *first_arg = NULL;
 
-          args = g_value_get_boxed (value);
+          parameters = g_value_get_variant (value);
+          if (parameters == NULL)
+            return;
+
+          if (g_variant_n_children (parameters) > 0)
+            {
+                g_variant_get_child (parameters, 0, "v", &v);
+                if (g_variant_is_of_type (v, G_VARIANT_TYPE_STRING))
+                  first_arg = g_variant_get_string (v, NULL);
+                else
+                  g_warning ("Wrong type for the second argument GVariant, expected 's' but got '%s'",
+                             (gchar *)g_variant_get_type (v));
+                g_variant_unref (v);
+            }
+
+          if (first_arg != NULL)
+            select_account_by_id (CC_GOA_PANEL (object), first_arg);
 
-          if (args != NULL && *args != '\0')
-            select_account_by_id (CC_GOA_PANEL (object), args[0]);
           return;
         }
     }
@@ -280,7 +295,7 @@ cc_goa_panel_class_init (CcGoaPanelClass *klass)
   object_class->set_property = cc_goa_panel_set_property;
   object_class->finalize = cc_goa_panel_finalize;
 
-  g_object_class_override_property (object_class, PROP_ARGV, "argv");
+  g_object_class_override_property (object_class, PROP_PARAMETERS, "parameters");
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
diff --git a/panels/sound/cc-sound-panel.c b/panels/sound/cc-sound-panel.c
index c60916d..61cbd42 100644
--- a/panels/sound/cc-sound-panel.c
+++ b/panels/sound/cc-sound-panel.c
@@ -38,7 +38,7 @@ CC_PANEL_REGISTER (CcSoundPanel, cc_sound_panel)
 
 enum {
         PROP_0,
-        PROP_ARGV
+        PROP_PARAMETERS
 };
 
 static void cc_sound_panel_finalize (GObject *object);
@@ -52,13 +52,15 @@ cc_sound_panel_set_property (GObject      *object,
         CcSoundPanel *self = CC_SOUND_PANEL (object);
 
         switch (property_id) {
-        case PROP_ARGV: {
-                gchar **args;
-
-                args = g_value_get_boxed (value);
-
-                if (args && args[0]) {
-                        gvc_mixer_dialog_set_page (self->dialog, args[0]);
+        case PROP_PARAMETERS: {
+                GVariant *parameters;
+
+                parameters = g_value_get_variant (value);
+                if (parameters && g_variant_n_children (parameters) > 0) {
+                        GVariant *v;
+                        g_variant_get_child (parameters, 0, "v", &v);
+                        gvc_mixer_dialog_set_page (self->dialog, g_variant_get_string (v, NULL));
+                        g_variant_unref (v);
                 }
                 break;
         }
@@ -84,7 +86,7 @@ cc_sound_panel_class_init (CcSoundPanelClass *klass)
         object_class->finalize = cc_sound_panel_finalize;
         object_class->set_property = cc_sound_panel_set_property;
 
-        g_object_class_override_property (object_class, PROP_ARGV, "argv");
+        g_object_class_override_property (object_class, PROP_PARAMETERS, "parameters");
 }
 
 static void
diff --git a/shell/cc-application.c b/shell/cc-application.c
index 74f101a..459152b 100644
--- a/shell/cc-application.c
+++ b/shell/cc-application.c
@@ -180,6 +180,9 @@ cc_application_command_line (GApplication *application,
     {
       const char *start_id;
       GError *err = NULL;
+      GVariant *parameters;
+      GVariantBuilder *builder;
+      int i;
 
       start_id = start_panels[0];
 
@@ -188,7 +191,11 @@ cc_application_command_line (GApplication *application,
       else
         g_debug ("No extra argument");
 
-      if (!cc_shell_set_active_panel_from_id (CC_SHELL (self->priv->window), start_id, (const 
gchar**)start_panels+1, &err))
+      builder = g_variant_builder_new (G_VARIANT_TYPE ("av"));
+      for (i = 1; start_panels[i] != NULL; i++)
+        g_variant_builder_add (builder, "v", g_variant_new_string (start_panels[i]));
+      parameters = g_variant_builder_end (builder);
+      if (!cc_shell_set_active_panel_from_id (CC_SHELL (self->priv->window), start_id, parameters, &err))
         {
           g_warning ("Could not load setting panel \"%s\": %s", start_id,
                      (err) ? err->message : "Unknown error");
diff --git a/shell/cc-panel-loader.c b/shell/cc-panel-loader.c
index 20a5262..733a4dc 100644
--- a/shell/cc-panel-loader.c
+++ b/shell/cc-panel-loader.c
@@ -200,7 +200,7 @@ ensure_panel_types (void)
 CcPanel *
 cc_panel_loader_load_by_name (CcShell     *shell,
                               const char  *name,
-                              const char **argv)
+                              GVariant    *parameters)
 {
   GType (*get_type) (void);
 
@@ -211,7 +211,7 @@ cc_panel_loader_load_by_name (CcShell     *shell,
 
   return g_object_new (get_type (),
                        "shell", shell,
-                       "argv", argv,
+                       "parameters", parameters,
                        NULL);
 }
 
diff --git a/shell/cc-panel-loader.h b/shell/cc-panel-loader.h
index bee1657..4994424 100644
--- a/shell/cc-panel-loader.h
+++ b/shell/cc-panel-loader.h
@@ -32,7 +32,7 @@ void     cc_panel_loader_fill_model     (CcShellModel  *model);
 GList   *cc_panel_loader_get_panels     (void);
 CcPanel *cc_panel_loader_load_by_name   (CcShell       *shell,
                                          const char    *name,
-                                         const char   **argv);
+                                         GVariant      *parameters);
 
 G_END_DECLS
 
diff --git a/shell/cc-panel.c b/shell/cc-panel.c
index 8c327a2..03c25dc 100644
--- a/shell/cc-panel.c
+++ b/shell/cc-panel.c
@@ -58,7 +58,7 @@ enum
 {
     PROP_0,
     PROP_SHELL,
-    PROP_ARGV
+    PROP_PARAMETERS
 };
 
 G_DEFINE_ABSTRACT_TYPE (CcPanel, cc_panel, GTK_TYPE_BIN)
@@ -80,11 +80,12 @@ cc_panel_set_property (GObject      *object,
       panel->priv->shell = g_value_get_object (value);
       break;
 
-    case PROP_ARGV:
+    case PROP_PARAMETERS:
       {
-        gchar **argv = g_value_get_boxed (value);
-        if (argv && argv[0])
-          g_warning ("Ignoring additional argument %s", argv[0]);
+        GVariant *parameters = g_value_get_variant (value);
+
+        if (parameters)
+          g_warning ("Ignoring additional parameters");
         break;
       }
     default:
@@ -208,12 +209,13 @@ cc_panel_class_init (CcPanelClass *klass)
                                | G_PARAM_CONSTRUCT_ONLY);
   g_object_class_install_property (object_class, PROP_SHELL, pspec);
 
-  pspec = g_param_spec_boxed ("argv",
-                              "Argument vector",
-                              "Additional arguments passed on the command line",
-                              G_TYPE_STRV,
-                              G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS);
-  g_object_class_install_property (object_class, PROP_ARGV, pspec);
+  pspec = g_param_spec_variant ("parameters",
+                                "Structured parameters",
+                                "Additional parameters passed externally (ie. command line, dbus 
activation)",
+                                G_VARIANT_TYPE ("av"),
+                                NULL,
+                                G_PARAM_WRITABLE);
+  g_object_class_install_property (object_class, PROP_PARAMETERS, pspec);
 }
 
 static void
diff --git a/shell/cc-shell.c b/shell/cc-shell.c
index 86c0215..81de92a 100644
--- a/shell/cc-shell.c
+++ b/shell/cc-shell.c
@@ -89,7 +89,8 @@ cc_shell_set_active_panel (CcShell *shell,
 /**
  * cc_shell_set_active_panel_from_id:
  * @shell: A #CcShell
- * @id: the ID of the panel to set as active
+ * @id: The ID of the panel to set as active
+ * @parameters: A #GVariant with additional parameters
  * @error: A #GError
  *
  * Find a panel corresponding to the specified id and set it as active.
@@ -99,7 +100,7 @@ cc_shell_set_active_panel (CcShell *shell,
 gboolean
 cc_shell_set_active_panel_from_id (CcShell      *shell,
                                    const gchar  *id,
-                                   const gchar **argv,
+                                   GVariant     *parameters,
                                    GError      **error)
 {
   CcShellInterface *iface;
@@ -117,7 +118,7 @@ cc_shell_set_active_panel_from_id (CcShell      *shell,
     }
   else
     {
-      return iface->set_active_panel_from_id (shell, id, argv, error);
+      return iface->set_active_panel_from_id (shell, id, parameters, error);
     }
 }
 
diff --git a/shell/cc-shell.h b/shell/cc-shell.h
index 01f101a..1786aed 100644
--- a/shell/cc-shell.h
+++ b/shell/cc-shell.h
@@ -52,7 +52,7 @@ struct _CcShellInterface
   /* methods */
   gboolean    (*set_active_panel_from_id) (CcShell      *shell,
                                            const gchar  *id,
-                                           const gchar **argv,
+                                           GVariant     *parameters,
                                            GError      **error);
   GtkWidget * (*get_toplevel)             (CcShell      *shell);
   void        (*embed_widget_in_header)   (CcShell      *shell,
@@ -66,7 +66,7 @@ void            cc_shell_set_active_panel         (CcShell      *shell,
                                                    CcPanel      *panel);
 gboolean        cc_shell_set_active_panel_from_id (CcShell      *shell,
                                                    const gchar  *id,
-                                                   const gchar **argv,
+                                                   GVariant     *parameters,
                                                    GError      **error);
 GtkWidget *     cc_shell_get_toplevel             (CcShell      *shell);
 
diff --git a/shell/cc-window.c b/shell/cc-window.c
index c2ef30c..4c980fd 100644
--- a/shell/cc-window.c
+++ b/shell/cc-window.c
@@ -108,7 +108,7 @@ enum
 
 static gboolean cc_window_set_active_panel_from_id (CcShell      *shell,
                                                     const gchar  *start_id,
-                                                    const gchar **argv,
+                                                    GVariant     *parameters,
                                                     GError      **err);
 
 static const gchar *
@@ -136,7 +136,7 @@ get_icon_name_from_g_icon (GIcon *gicon)
 static gboolean
 activate_panel (CcWindow           *self,
                 const gchar        *id,
-                const gchar       **argv,
+                GVariant           *parameters,
                 const gchar        *name,
                 GIcon              *gicon)
 {
@@ -147,7 +147,7 @@ activate_panel (CcWindow           *self,
   if (!id)
     return FALSE;
 
-  priv->current_panel = GTK_WIDGET (cc_panel_loader_load_by_name (CC_SHELL (self), id, argv));
+  priv->current_panel = GTK_WIDGET (cc_panel_loader_load_by_name (CC_SHELL (self), id, parameters));
   cc_shell_set_active_panel (CC_SHELL (self), CC_PANEL (priv->current_panel));
   gtk_widget_show (priv->current_panel);
 
@@ -933,7 +933,7 @@ _shell_embed_widget_in_header (CcShell      *shell,
 static gboolean
 cc_window_set_active_panel_from_id (CcShell      *shell,
                                     const gchar  *start_id,
-                                    const gchar **argv,
+                                    GVariant     *parameters,
                                     GError      **err)
 {
   GtkTreeIter iter;
@@ -943,10 +943,10 @@ cc_window_set_active_panel_from_id (CcShell      *shell,
   CcWindowPrivate *priv = CC_WINDOW (shell)->priv;
   GtkWidget *old_panel;
 
-  /* When loading the same panel again, just set the argv */
+  /* When loading the same panel again, just set its parameters */
   if (g_strcmp0 (priv->current_panel_id, start_id) == 0)
     {
-      g_object_set (G_OBJECT (priv->current_panel), "argv", argv, NULL);
+      g_object_set (G_OBJECT (priv->current_panel), "parameters", parameters, NULL);
       return TRUE;
     }
 
@@ -994,7 +994,7 @@ cc_window_set_active_panel_from_id (CcShell      *shell,
     {
       g_warning ("Could not find settings panel \"%s\"", start_id);
     }
-  else if (activate_panel (CC_WINDOW (shell), start_id, argv,
+  else if (activate_panel (CC_WINDOW (shell), start_id, parameters,
                            name, gicon) == FALSE)
     {
       /* Failed to activate the panel for some reason,
@@ -1020,11 +1020,11 @@ cc_window_set_active_panel_from_id (CcShell      *shell,
 static gboolean
 _shell_set_active_panel_from_id (CcShell      *shell,
                                  const gchar  *start_id,
-                                 const gchar **argv,
+                                 GVariant     *parameters,
                                  GError      **err)
 {
   add_current_panel_to_history (shell, start_id);
-  return cc_window_set_active_panel_from_id (shell, start_id, argv, err);
+  return cc_window_set_active_panel_from_id (shell, start_id, parameters, err);
 }
 
 static GtkWidget *


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]