diff options
author | Charles Kerr <charles.kerr@canonical.com> | 2013-07-30 19:35:58 +0000 |
---|---|---|
committer | Tarmac <Unknown> | 2013-07-30 19:35:58 +0000 |
commit | ae7687cc9ac0f0399830500656371e803b1fbf95 (patch) | |
tree | 4c1de4cc867cf3b28702bd580c7dd35126cadedc | |
parent | ce7a42fafa9df7b37eea53120aa3a35d368bdea9 (diff) | |
parent | e430061e28eafe90e423201b528265071815771b (diff) | |
download | libayatana-indicator-ae7687cc9ac0f0399830500656371e803b1fbf95.tar.gz libayatana-indicator-ae7687cc9ac0f0399830500656371e803b1fbf95.tar.bz2 libayatana-indicator-ae7687cc9ac0f0399830500656371e803b1fbf95.zip |
in indicator-loader3, if we're looking at an ng-style indicator, show all of its profiles instead of just one.
Approved by Ted Gould, PS Jenkins bot.
-rw-r--r-- | tools/indicator-loader.c | 469 |
1 files changed, 283 insertions, 186 deletions
diff --git a/tools/indicator-loader.c b/tools/indicator-loader.c index ff3a71b..153cca7 100644 --- a/tools/indicator-loader.c +++ b/tools/indicator-loader.c @@ -1,248 +1,345 @@ /* -A small test loader for loading indicators in test suites -and during development of them. - -Copyright 2009 Canonical Ltd. - -Authors: - Ted Gould <ted@canonical.com> - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -version 3.0 as published by the Free Software Foundation. - -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 General Public License version 3.0 for more details. - -You should have received a copy of the GNU General Public -License along with this library. If not, see -<http://www.gnu.org/licenses/>. -*/ - + * A small test loader for loading indicators in test suites + * and during development of them. + * + * Copyright 2009 Canonical Ltd. + * + * Authors: + * Ted Gould <ted@canonical.com> + * Lars Uebernickel <lars.uebernickel@canonical.com> + * Charles Kerr <charles.kerr@canonical.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 3.0 as published by the Free Software Foundation. + * + * 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 General Public License version 3.0 for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + */ #include <gtk/gtk.h> -#include <libindicator/indicator-object.h> #include <libido/libido.h> - -#if GTK_MAJOR_VERSION == 3 -#include <libindicator/indicator-ng.h> +#include <libindicator/indicator-object.h> +#if GTK_CHECK_VERSION (3,0,0) + #include <libindicator/indicator-ng.h> #endif -static gchar * profile = "desktop"; -static gchar * title = NULL; +static GHashTable * entry_to_menu_item = NULL; -static GOptionEntry entries[] = -{ - { "profile", 'p', 0, G_OPTION_ARG_STRING, &profile, "Profile [default: 'desktop']", NULL }, - { NULL } -}; - -static GHashTable * entry_to_menuitem = NULL; - -#define ENTRY_DATA_NAME "indicator-custom-entry-data" +G_DEFINE_QUARK (indicator_loader, entry_data) static void activate_entry (GtkWidget * widget, gpointer user_data) { - g_return_if_fail(INDICATOR_IS_OBJECT(user_data)); - gpointer entry = g_object_get_data(G_OBJECT(widget), ENTRY_DATA_NAME); - if (entry == NULL) { - g_debug("Activation on: (null)"); - } - - indicator_object_entry_activate(INDICATOR_OBJECT(user_data), (IndicatorObjectEntry *)entry, gtk_get_current_event_time()); - return; + gpointer entry; + + g_return_if_fail (INDICATOR_IS_OBJECT(user_data)); + + entry = g_object_get_qdata (G_OBJECT(widget), entry_data_quark()); + + if (entry == NULL) + { + g_debug("Activation on: (null)"); + } + else + { + indicator_object_entry_activate (INDICATOR_OBJECT(user_data), + entry, + gtk_get_current_event_time()); + } } static GtkWidget* create_menu_item (IndicatorObjectEntry * entry) { - GtkWidget * hbox; - GtkWidget * menuitem; + GtkWidget * menu_item; + GtkWidget * hbox; + gpointer w; - menuitem = gtk_menu_item_new(); + menu_item = gtk_menu_item_new(); -#if GTK_CHECK_VERSION(3,0,0) - hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3); +#if GTK_CHECK_VERSION (3,0,0) + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3); #else - hbox = gtk_hbox_new(FALSE, 3); + hbox = gtk_hbox_new (FALSE, 3); #endif - if (entry->image != NULL) { - gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(entry->image), FALSE, FALSE, 0); - } - if (entry->label != NULL) { - gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(entry->label), FALSE, FALSE, 0); - } - gtk_container_add(GTK_CONTAINER(menuitem), hbox); - gtk_widget_show(hbox); + if ((w = entry->image)) + gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET(w), FALSE, FALSE, 0); + if ((w = entry->label)) + gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET(w), FALSE, FALSE, 0); - if (entry->menu != NULL) { - gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), GTK_WIDGET(entry->menu)); - } + gtk_container_add (GTK_CONTAINER(menu_item), hbox); + gtk_widget_show (hbox); - return menuitem; + if ((w = entry->menu)) + gtk_menu_item_set_submenu (GTK_MENU_ITEM(menu_item), GTK_WIDGET(w)); + + return menu_item; } static void -entry_added (IndicatorObject * io, IndicatorObjectEntry * entry, gpointer user_data) +entry_added (IndicatorObject * io, + IndicatorObjectEntry * entry, + gpointer user_data) { - GtkWidget * menuitem; + GtkWidget * menu_item; - g_debug("Signal: Entry Added"); + g_debug ("Signal: Entry Added"); - if (entry->parent_object == NULL) { - g_warning("Entry '%p' does not have a parent object", entry); - } + g_warn_if_fail (entry->parent_object != NULL); - menuitem = g_hash_table_lookup (entry_to_menuitem, entry); - if (menuitem == NULL) { - g_debug ("This is the first time this entry's been added -- creating a new menuitem for it"); - menuitem = create_menu_item (entry); - g_hash_table_insert (entry_to_menuitem, entry, menuitem); + menu_item = g_hash_table_lookup (entry_to_menu_item, entry); - g_object_set_data(G_OBJECT(menuitem), ENTRY_DATA_NAME, entry); - g_signal_connect (G_OBJECT(menuitem), "activate", G_CALLBACK(activate_entry), io); + if (menu_item == NULL) + { + g_debug ("creating a menuitem for new entry %p", entry); + menu_item = create_menu_item (entry); + g_hash_table_insert (entry_to_menu_item, entry, menu_item); - gtk_menu_shell_append (GTK_MENU_SHELL(user_data), menuitem); + g_object_set_qdata (G_OBJECT(menu_item), entry_data_quark(), entry); + g_signal_connect (menu_item, "activate", G_CALLBACK(activate_entry), io); - } - gtk_widget_show (menuitem); + gtk_menu_shell_append (GTK_MENU_SHELL(user_data), menu_item); + } - return; + gtk_widget_show (menu_item); } static void -entry_removed (IndicatorObject * io, IndicatorObjectEntry * entry, gpointer user_data) +entry_removed (IndicatorObject * io, + IndicatorObjectEntry * entry, + gpointer user_data) { - g_debug("Signal: Entry Removed"); + GtkWidget * w; - GtkWidget * menuitem = g_hash_table_lookup (entry_to_menuitem, entry); - if (menuitem != NULL) - gtk_widget_hide (menuitem); + g_debug ("Signal: Entry Removed"); - return; + if ((w = g_hash_table_lookup (entry_to_menu_item, entry))) + gtk_widget_hide (w); } static void -menu_show (IndicatorObject * io, IndicatorObjectEntry * entry, guint timestamp, gpointer user_data) +menu_show (IndicatorObject * io, + IndicatorObjectEntry * entry, + guint timestamp, + gpointer user_data) { - if (entry != NULL) { - g_debug("Show Menu: %s", entry->label != NULL ? gtk_label_get_text(entry->label) : "No Label"); - } else { - g_debug("Show Menu: (null)"); - } - return; + const char * text; + + if (entry == NULL) + text = "(null)"; + else if (entry->label == NULL) + text = "(no label)"; + else + text = gtk_label_get_text (entry->label); + + g_debug ("Show Menu: %s", text); } -static gboolean -load_module (const gchar * name, GtkWidget * menu) +/*** +**** +***/ + +static IndicatorObject * +load_module (const gchar * file_name) { - g_debug("Looking at Module: %s", name); - g_return_val_if_fail(name != NULL, FALSE); - - g_debug("Loading Module: %s", name); - - /* Build the object for the module */ - IndicatorObject *io; - if (g_str_has_suffix(name, G_MODULE_SUFFIX)) { - io = indicator_object_new_from_file(name); - } -#if GTK_MAJOR_VERSION == 3 - else { - GError *error = NULL; - - io = INDICATOR_OBJECT (indicator_ng_new_for_profile (name, profile, &error)); - if (!io) { - g_warning ("could not load indicator from '%s': %s", name, error->message); - g_error_free (error); - return FALSE; - } - - title = g_strdup_printf ("%s %s", profile, name); - } -#else - else - return FALSE; -#endif + IndicatorObject * io = NULL; - /* Connect to it's signals */ - g_signal_connect(G_OBJECT(io), INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED, G_CALLBACK(entry_added), menu); - g_signal_connect(G_OBJECT(io), INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED, G_CALLBACK(entry_removed), menu); - g_signal_connect(G_OBJECT(io), INDICATOR_OBJECT_SIGNAL_MENU_SHOW, G_CALLBACK(menu_show), NULL); + if (file_name && g_str_has_suffix (file_name, G_MODULE_SUFFIX)) + { + io = indicator_object_new_from_file (file_name); - /* Work on the entries */ - GList * entries = indicator_object_get_entries(io); - GList * entry = NULL; + if (io == NULL) + g_warning ("could not load indicator from '%s'", file_name); + } - for (entry = entries; entry != NULL; entry = g_list_next(entry)) { - IndicatorObjectEntry * entrydata = (IndicatorObjectEntry *)entry->data; - entry_added(io, entrydata, menu); - } + return io; +} + +static IndicatorObject * +load_profile (const char * file_name, const char * profile) +{ + IndicatorObject * io = NULL; + +#if GTK_CHECK_VERSION (3,0,0) + + GError * error = NULL; - g_list_free(entries); + io = INDICATOR_OBJECT (indicator_ng_new_for_profile (file_name, + profile, + &error)); + if (error != NULL) + { + g_warning ("couldn't load profile '%s' from '%s': %s", + profile, file_name, error->message); + g_error_free (error); + } - return TRUE; +#endif + + return io; } +/*** +**** +***/ + static void -destroy (gpointer data) +add_indicator_to_menu (GtkMenuShell * menu_shell, IndicatorObject * io) { - gtk_main_quit(); - return; + GList * entries; + GList * entry; + + g_return_if_fail (INDICATOR_IS_OBJECT (io)); + + /* connect to its signals */ + g_signal_connect (io, INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED, + G_CALLBACK(entry_added), menu_shell); + g_signal_connect (io, INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED, + G_CALLBACK(entry_removed), menu_shell); + g_signal_connect (io, INDICATOR_OBJECT_SIGNAL_MENU_SHOW, + G_CALLBACK(menu_show), NULL); + + /* process the entries */ + entries = indicator_object_get_entries(io); + for (entry=entries; entry!=NULL; entry=entry->next) + entry_added (io, entry->data, menu_shell); + g_list_free (entries); } +static void +add_menu_to_grid (GtkGrid * grid, + int top, + const char * text_, + GtkWidget * menu) +{ + gchar * text; + GtkWidget * label; + + text = g_strdup_printf ("%s:", text_); + label = gtk_label_new (text); + g_free (text); + + gtk_grid_attach (GTK_GRID(grid), label, 0, top, 1, 1); + gtk_grid_attach (GTK_GRID(grid), menu, 1, top, 1, 1); + + g_object_set (label, "halign", GTK_ALIGN_START, + "hexpand", FALSE, + "margin-right", 6, + "valign", GTK_ALIGN_CENTER, + NULL); + + g_object_set (menu, "halign", GTK_ALIGN_START, + "hexpand", TRUE, + NULL); +} + +/*** +**** +***/ + int main (int argc, char ** argv) { - /* Parse the command line options */ - GError * error = NULL; - GOptionContext * context; - context = g_option_context_new ("/path/to/file.indicator"); - g_option_context_add_main_entries (context, entries, NULL); - g_option_context_add_group (context, gtk_get_option_group (TRUE)); - if (!g_option_context_parse (context, &argc, &argv, &error)) { - g_print ("option parsing failed: %s\n", error->message); - g_error_free (error); - return 1; - } - - /* Make sure we don't proxy to ourselves */ - g_unsetenv("UBUNTU_MENUPROXY"); - - gtk_init(&argc, &argv); - ido_init (); - - entry_to_menuitem = g_hash_table_new (g_direct_hash, g_direct_equal); - - if (argc != 2) { - g_error("Need filename"); - return 1; - } - - GtkWidget * menubar = gtk_menu_bar_new(); - if (!load_module(argv[1], menubar)) { - g_error("Unable to load module"); - return 1; - } - - GtkWidget * window = gtk_window_new(GTK_WINDOW_TOPLEVEL); - if (title != NULL) - gtk_window_set_title (GTK_WINDOW(window), title); - g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(destroy), NULL); - - gtk_container_add(GTK_CONTAINER(window), menubar); - - gtk_widget_show(menubar); - gtk_widget_show(window); - - gtk_main(); - - /* cleanup */ - g_hash_table_destroy (entry_to_menuitem); - g_free (title); - g_option_context_free (context); - return 0; + int menu_count = 0; + const gchar * file_name; + gchar * base_name; + GtkWidget * grid; + + if (argc != 2) + { + base_name = g_path_get_basename (argv[0]); + g_warning ("Use: %s filename", base_name); + g_free (base_name); + return 0; + } + + /* make sure we don't proxy to ourselves */ + g_setenv ("UBUNTU_MENUPROXY", "0", TRUE); + + gtk_init (&argc, &argv); + ido_init (); + + entry_to_menu_item = g_hash_table_new (g_direct_hash, g_direct_equal); + + file_name = argv[1]; + + grid = g_object_new (GTK_TYPE_GRID, "margin", 4, + "column-spacing", 6, + "row-spacing", 12, + NULL); + + /* if it's an old-style indicator... */ + if (g_str_has_suffix (file_name, G_MODULE_SUFFIX)) + { + IndicatorObject * io = load_module (file_name); + GtkWidget * menu = gtk_menu_bar_new (); + add_indicator_to_menu (GTK_MENU_SHELL(menu), io); + base_name = g_path_get_basename (file_name); + add_menu_to_grid (GTK_GRID(grid), menu_count++, base_name, menu); + g_free (base_name); + } + else /* treat it as a GMenu indicator's keyfile */ + { + GError * error; + GKeyFile * key_file; + + key_file = g_key_file_new (); + error = NULL; + g_key_file_load_from_file (key_file, file_name, G_KEY_FILE_NONE, &error); + if (error != NULL) + { + g_warning ("loading '%s' failed: %s", file_name, error->message); + g_error_free (error); + } + else + { + gchar ** groups; + int i; + + groups = g_key_file_get_groups (key_file, NULL); + for (i=0; groups && groups[i]; i++) + { + const gchar * const profile = groups[i]; + IndicatorObject * io; + + if (!g_strcmp0 (profile, "Indicator Service")) + continue; + + if ((io = load_profile (file_name, profile))) + { + GtkWidget * menu = gtk_menu_bar_new (); + add_indicator_to_menu (GTK_MENU_SHELL(menu), io); + add_menu_to_grid (GTK_GRID(grid), menu_count++, profile, menu); + } + } + + g_strfreev (groups); + } + + g_key_file_free (key_file); + } + + if (menu_count > 0) + { + GtkWidget * window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + base_name = g_path_get_basename (file_name); + gtk_window_set_title (GTK_WINDOW(window), base_name); + g_free (base_name); + g_signal_connect (window, "destroy", G_CALLBACK(gtk_main_quit), NULL); + gtk_container_add (GTK_CONTAINER(window), grid); + gtk_widget_show_all (window); + gtk_main (); + } + + /* cleanup */ + g_hash_table_destroy (entry_to_menu_item); + return 0; } |