From 31a8a99440cce715b2e32ca71a6cbf650eab012a Mon Sep 17 00:00:00 2001 From: Emanuele Aina Date: Fri, 15 Mar 2013 17:34:43 +0100 Subject: [PATCH] shell: Let panels have their own commandline flags Add a class method to CcPanel to get a GOptionGroup which will be added to the main commandline parser. This gives panels the chance to have commandline "--flags" in addition to the already available parameters. This changes changes the way parameters are passed to panels: the first entry in the GVariant array is always the a{sv} dictionary of commandline flags, followed by the remaining free-form arguments. https://bugzilla.gnome.org/show_bug.cgi?id=696054 --- panels/keyboard/cc-keyboard-panel.c | 10 ++++++---- panels/network/cc-network-panel.c | 3 ++- .../online-accounts/cc-online-accounts-panel.c | 6 +++--- panels/sound/cc-sound-panel.c | 5 +++-- shell/cc-application.c | 6 ++++++ shell/cc-panel-loader.c | 17 +++++++++++++++++ shell/cc-panel-loader.h | 2 ++ shell/cc-panel.c | 12 ++++++++++++ shell/cc-panel.h | 4 ++++ 9 files changed, 55 insertions(+), 10 deletions(-) diff --git a/panels/keyboard/cc-keyboard-panel.c b/panels/keyboard/cc-keyboard-panel.c index 2a228ed10..6c84fd03e 100644 --- a/panels/keyboard/cc-keyboard-panel.c +++ b/panels/keyboard/cc-keyboard-panel.c @@ -91,17 +91,19 @@ cc_keyboard_panel_set_property (GObject *object, page = section = NULL; switch (g_variant_n_children (parameters)) { - case 2: - g_variant_get_child (parameters, 1, "v", &v); + case 3: + g_variant_get_child (parameters, 2, "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); + case 2: + g_variant_get_child (parameters, 1, "v", &v); page = g_variant_get_string (v, NULL); g_variant_unref (v); cc_keyboard_panel_set_page (panel, page, section); /* fall-through */ + case 1: + /* No flags expected, fall-through */ case 0: break; default: diff --git a/panels/network/cc-network-panel.c b/panels/network/cc-network-panel.c index 7fe634b7d..a23e32578 100644 --- a/panels/network/cc-network-panel.c +++ b/panels/network/cc-network-panel.c @@ -173,7 +173,8 @@ variant_av_to_string_array (GVariant *array) 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)); + if (g_variant_is_of_type (v, G_VARIANT_TYPE_STRING)) + 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 */ diff --git a/panels/online-accounts/cc-online-accounts-panel.c b/panels/online-accounts/cc-online-accounts-panel.c index 67b097e99..52fb05416 100644 --- a/panels/online-accounts/cc-online-accounts-panel.c +++ b/panels/online-accounts/cc-online-accounts-panel.c @@ -108,12 +108,12 @@ cc_goa_panel_set_property (GObject *object, const gchar *first_arg = NULL; parameters = g_value_get_variant (value); - if (parameters == NULL) + if (parameters == NULL || g_variant_n_children (parameters) == 0) return; - if (g_variant_n_children (parameters) > 0) + if (g_variant_n_children (parameters) > 1) { - g_variant_get_child (parameters, 0, "v", &v); + g_variant_get_child (parameters, 1, "v", &v); if (g_variant_is_of_type (v, G_VARIANT_TYPE_STRING)) first_arg = g_variant_get_string (v, NULL); else diff --git a/panels/sound/cc-sound-panel.c b/panels/sound/cc-sound-panel.c index 61cbd4214..1339d8bfb 100644 --- a/panels/sound/cc-sound-panel.c +++ b/panels/sound/cc-sound-panel.c @@ -56,9 +56,10 @@ cc_sound_panel_set_property (GObject *object, GVariant *parameters; parameters = g_value_get_variant (value); - if (parameters && g_variant_n_children (parameters) > 0) { + if (parameters && g_variant_n_children (parameters) > 1) { GVariant *v; - g_variant_get_child (parameters, 0, "v", &v); + /* Skip the first child, we don't expect any flag */ + g_variant_get_child (parameters, 1, "v", &v); gvc_mixer_dialog_set_page (self->dialog, g_variant_get_string (v, NULL)); g_variant_unref (v); } diff --git a/shell/cc-application.c b/shell/cc-application.c index 459152bd6..172345860 100644 --- a/shell/cc-application.c +++ b/shell/cc-application.c @@ -105,18 +105,22 @@ cc_application_command_line (GApplication *application, int retval = 0; GOptionContext *context; GError *error = NULL; + GVariantBuilder *flags_builder; verbose = FALSE; show_overview = FALSE; show_help = FALSE; start_panels = NULL; + flags_builder = g_variant_builder_new (G_VARIANT_TYPE_VARDICT); + argv = g_application_command_line_get_arguments (command_line, &argc); context = g_option_context_new (N_("- Settings")); g_option_context_add_main_entries (context, all_options, GETTEXT_PACKAGE); g_option_context_set_translation_domain(context, GETTEXT_PACKAGE); g_option_context_add_group (context, gtk_get_option_group (TRUE)); + cc_panel_loader_add_option_groups (context, flags_builder); g_option_context_set_help_enabled (context, FALSE); if (g_option_context_parse (context, &argc, &argv, &error) == FALSE) @@ -192,6 +196,8 @@ cc_application_command_line (GApplication *application, g_debug ("No extra argument"); builder = g_variant_builder_new (G_VARIANT_TYPE ("av")); + g_variant_builder_add (builder, "v", g_variant_builder_end (flags_builder)); + 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); diff --git a/shell/cc-panel-loader.c b/shell/cc-panel-loader.c index 733a4dc22..798849360 100644 --- a/shell/cc-panel-loader.c +++ b/shell/cc-panel-loader.c @@ -215,4 +215,21 @@ cc_panel_loader_load_by_name (CcShell *shell, NULL); } +void +cc_panel_loader_add_option_groups (GOptionContext *context, + GVariantBuilder *builder) +{ + int i; + + for (i = 0; i < G_N_ELEMENTS (all_panels); i++) + { + GType (*get_type) (void); + get_type = all_panels[i].get_type; + GOptionGroup *group = cc_panel_get_option_group (get_type(), builder); + if (group == NULL) + continue; + g_option_context_add_group (context, group); + } +} + #endif /* CC_PANEL_LOADER_NO_GTYPES */ diff --git a/shell/cc-panel-loader.h b/shell/cc-panel-loader.h index 499442478..23599cbad 100644 --- a/shell/cc-panel-loader.h +++ b/shell/cc-panel-loader.h @@ -30,6 +30,8 @@ G_BEGIN_DECLS void cc_panel_loader_fill_model (CcShellModel *model); GList *cc_panel_loader_get_panels (void); +void cc_panel_loader_add_option_groups (GOptionContext *context, + GVariantBuilder *builder); CcPanel *cc_panel_loader_load_by_name (CcShell *shell, const char *name, GVariant *parameters); diff --git a/shell/cc-panel.c b/shell/cc-panel.c index 03c25dca1..90b15cb1c 100644 --- a/shell/cc-panel.c +++ b/shell/cc-panel.c @@ -259,3 +259,15 @@ cc_panel_get_help_uri (CcPanel *panel) return NULL; } + +GOptionGroup * +cc_panel_get_option_group (GType panel_type, + GVariantBuilder *builder) +{ + GOptionGroup *options = NULL; + CcPanelClass *class = CC_PANEL_CLASS (g_type_class_ref (panel_type)); + if (class->get_option_group != NULL) + options = class->get_option_group (builder); + g_type_class_unref (class); + return options; +} diff --git a/shell/cc-panel.h b/shell/cc-panel.h index 44ca3483b..2e49ff2dd 100644 --- a/shell/cc-panel.h +++ b/shell/cc-panel.h @@ -75,12 +75,16 @@ struct _CcPanelClass /*< private >*/ GtkBinClass parent_class; + GOptionGroup * (* get_option_group) (GVariantBuilder *builder); GPermission * (* get_permission) (CcPanel *panel); const char * (* get_help_uri) (CcPanel *panel); }; GType cc_panel_get_type (void); +GOptionGroup *cc_panel_get_option_group (GType panel_type, + GVariantBuilder *builder); + CcShell* cc_panel_get_shell (CcPanel *panel); GPermission *cc_panel_get_permission (CcPanel *panel);