aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/indicator-loader.c426
1 files changed, 247 insertions, 179 deletions
diff --git a/tools/indicator-loader.c b/tools/indicator-loader.c
index ff3a71b..833e8ea 100644
--- a/tools/indicator-loader.c
+++ b/tools/indicator-loader.c
@@ -1,248 +1,316 @@
/*
-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>
-
+#include <libindicator/indicator-object.h>
#if GTK_MAJOR_VERSION == 3
-#include <libindicator/indicator-ng.h>
+ #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;
- 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 (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(menu_item), hbox);
+ gtk_widget_show (hbox);
- if (entry->menu != NULL) {
- gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), GTK_WIDGET(entry->menu));
- }
+ if (entry->menu != NULL)
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM(menu_item), GTK_WIDGET(entry->menu));
- return menuitem;
+ return menu_item;
}
static void
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);
- }
+ if (entry->parent_object == NULL)
+ {
+ g_warning("Entry '%p' does not have a parent object", entry);
+ }
- 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 ("This is the first time this entry's been added -- creating a new menuitem for it");
+ 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 (G_OBJECT(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)
{
- g_debug("Signal: Entry Removed");
+ g_debug("Signal: Entry Removed");
- GtkWidget * menuitem = g_hash_table_lookup (entry_to_menuitem, entry);
- if (menuitem != NULL)
- gtk_widget_hide (menuitem);
-
- return;
+ GtkWidget * menuitem = g_hash_table_lookup (entry_to_menu_item, entry);
+ if (menuitem != NULL)
+ gtk_widget_hide (menuitem);
}
static void
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;
+ if (entry == NULL)
+ g_debug("Show Menu: (null)");
+ else
+ g_debug("Show Menu: %s", entry->label != NULL ? gtk_label_get_text(entry->label) : "No Label");
}
-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);
+ IndicatorObject * io = NULL;
- g_debug("Loading Module: %s", name);
+ if (file_name && g_str_has_suffix (file_name, G_MODULE_SUFFIX))
+ {
+ io = indicator_object_new_from_file (file_name);
+
+ if (io == NULL)
+ g_warning ("could not load indicator from '%s'", file_name);
+ }
+
+ return io;
+}
+
+static IndicatorObject *
+load_profile (const char * file_name, const char * profile)
+{
+ IndicatorObject * io = NULL;
- /* 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;
+
+ GError * error = NULL;
+
+ io = INDICATOR_OBJECT (indicator_ng_new_for_profile (file_name, profile, &error));
+ if (error != NULL)
+ {
+ g_warning ("could not load indicator from '%s': %s", file_name, error->message);
+ g_error_free (error);
+ }
+
#endif
- /* 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);
+ return io;
+}
+
+/***
+****
+***/
- /* Work on the entries */
- GList * entries = indicator_object_get_entries(io);
- GList * entry = NULL;
+static void
+add_indicator_to_menu (GtkMenuShell * menu_shell, IndicatorObject * io)
+{
+ GList * entries;
+ GList * entry;
- for (entry = entries; entry != NULL; entry = g_list_next(entry)) {
- IndicatorObjectEntry * entrydata = (IndicatorObjectEntry *)entry->data;
- entry_added(io, entrydata, menu);
- }
+ g_return_if_fail (INDICATOR_IS_OBJECT (io));
- g_list_free(entries);
+ /* 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);
- return TRUE;
+ /* 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
-destroy (gpointer data)
+add_menu_to_grid (GtkGrid * grid, int top, const char * text_, GtkWidget * menu)
{
- gtk_main_quit();
- return;
+ 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;
+ const gchar * file_name;
+ gchar * base_name;
+ GtkWidget * window;
+ GtkWidget * grid;
+
+ /* make sure we don't proxy to ourselves */
+ g_unsetenv ("UBUNTU_MENUPROXY");
+
+ gtk_init (&argc, &argv);
+ ido_init ();
+
+ entry_to_menu_item = g_hash_table_new (g_direct_hash, g_direct_equal);
+ if (argc != 2)
+ {
+ base_name = g_path_get_basename (argv[0]);
+ g_warning ("Use: %s filename", base_name);
+ g_free (base_name);
+ return 0;
+ }
+
+ file_name = argv[1];
+
+ 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);
+ grid = g_object_new (GTK_TYPE_GRID, "margin", 4,
+ "column-spacing", 6,
+ "row-spacing", 12,
+ NULL);
+ gtk_container_add (GTK_CONTAINER(window), grid);
+
+ /* 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), 0, base_name, menu);
+ g_free (base_name);
+ }
+ else /* treat it as a GMenu indicator's keyfile */
+ {
+ GError * error;
+ GKeyFile * key_file;
+ gchar ** groups;
+ int i;
+ int menu_count = 0;
+
+ 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 ("parsing '%s' failed: %s", file_name, error->message);
+ g_error_free (error);
+ return 1;
+ }
+
+ 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;
+
+ io = load_profile (file_name, profile);
+ if (io != NULL)
+ {
+ 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);
+ }
+ }
+ }
+
+ gtk_widget_show_all (window);
+ gtk_main ();
+
+ /* cleanup */
+ g_hash_table_destroy (entry_to_menu_item);
+ return 0;
}