aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Kerr <charles.kerr@canonical.com>2013-07-30 19:35:58 +0000
committerTarmac <Unknown>2013-07-30 19:35:58 +0000
commitae7687cc9ac0f0399830500656371e803b1fbf95 (patch)
tree4c1de4cc867cf3b28702bd580c7dd35126cadedc
parentce7a42fafa9df7b37eea53120aa3a35d368bdea9 (diff)
parente430061e28eafe90e423201b528265071815771b (diff)
downloadlibayatana-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.c469
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;
}