summaryrefslogtreecommitdiff
path: root/tools/glade/glade/glade_gnome.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/glade/glade/glade_gnome.c')
-rw-r--r--tools/glade/glade/glade_gnome.c1032
1 files changed, 1032 insertions, 0 deletions
diff --git a/tools/glade/glade/glade_gnome.c b/tools/glade/glade/glade_gnome.c
new file mode 100644
index 00000000..36665ea2
--- /dev/null
+++ b/tools/glade/glade/glade_gnome.c
@@ -0,0 +1,1032 @@
+
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998-1999 Damon Chaplin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * This file contains general Gnome-related declarations & code.
+ */
+
+#include <config.h>
+
+#ifdef USE_GNOME
+
+#include <gnome.h>
+
+#include "glade_gnome.h"
+#include "glade_project.h"
+#include "source.h"
+#include "utils.h"
+
+
+static void glade_gnome_write_menu_item_standard_source (GtkMenuItem * widget,
+ GbWidgetWriteSourceData * data);
+static void glade_gnome_write_radio_menu_item_source (GtkMenuItem * widget,
+ GbWidgetWriteSourceData * data,
+ GString *source_buffer,
+ gchar *label,
+ gchar *tooltip,
+ gchar *handler,
+ gchar *accel_key_buffer,
+ gchar *accel_mods);
+static void glade_gnome_finish_radio_menu_item_group_source (GtkMenuShell * menu_shell,
+ GbWidgetWriteSourceData *data);
+static gboolean glade_gnome_is_first_radio_menu_item_in_group (GtkMenuItem *menuitem);
+
+
+
+/*
+ * I intend to tidy up all the code for choice properties at some point,
+ * so we don't duplicate them and we use simple convenience functions for them.
+ */
+
+/* Choices for the BonoboDockItem placement. */
+const gint GladePlacementValues[] =
+{
+ BONOBO_DOCK_TOP,
+ BONOBO_DOCK_RIGHT,
+ BONOBO_DOCK_BOTTOM,
+ BONOBO_DOCK_LEFT,
+ BONOBO_DOCK_FLOATING
+};
+const gint GladePlacementSize = sizeof (GladePlacementValues) / sizeof (gint);
+const gchar *GladePlacementSymbols[] =
+{
+ "BONOBO_DOCK_TOP",
+ "BONOBO_DOCK_RIGHT",
+ "BONOBO_DOCK_BOTTOM",
+ "BONOBO_DOCK_LEFT",
+ "BONOBO_DOCK_FLOATING"
+};
+
+
+/* Choices for the BonoboDockItem Orientation. */
+const gchar *GladeOrientationChoices[] =
+{
+ "Horizontal",
+ "Vertical",
+ NULL
+};
+const gint GladeOrientationValues[] =
+{
+ GTK_ORIENTATION_HORIZONTAL,
+ GTK_ORIENTATION_VERTICAL
+};
+const gint GladeOrientationSize = sizeof (GladeOrientationValues) / sizeof (GladeOrientationValues[0]);
+const gchar *GladeOrientationSymbols[] =
+{
+ "GTK_ORIENTATION_HORIZONTAL",
+ "GTK_ORIENTATION_VERTICAL"
+};
+
+
+/*************************************************************************
+ * Stock Gnome Menu Items.
+ *************************************************************************/
+
+/* These are indices of a few special items, so if you change the
+ GladeStockMenuItemValues array be sure to update this. */
+const gint GladeStockMenuItemNew = 3;
+const gint GladeStockMenuHelpTree = 37;
+
+/* These are copied from gnome-libs/libgnomeui/gnome-app-helper.h
+ The first item is 'None' to indicate no stock item is being used. */
+GnomeUIInfo GladeStockMenuItemValues[] =
+{
+ /* 0 */
+ {
+ GNOME_APP_UI_ITEM, N_("None"), NULL, NULL, NULL, NULL,
+ GNOME_APP_PIXMAP_NONE, NULL, 0, 0, NULL
+ },
+ /* 1 */
+ GNOMEUIINFO_SEPARATOR,
+
+ /* 2 */
+ GNOMEUIINFO_MENU_FILE_TREE (NULL),
+ /* 3 - see GladeStockMenuItemNew above. */
+ GNOMEUIINFO_MENU_NEW_ITEM (N_("_New"), NULL, NULL, NULL),
+ GNOMEUIINFO_MENU_OPEN_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_SAVE_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_SAVE_AS_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_REVERT_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_PRINT_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_PRINT_SETUP_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_CLOSE_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_QUIT_ITEM (NULL, NULL),
+ GNOMEUIINFO_SEPARATOR,
+
+ /* 13 */
+ GNOMEUIINFO_MENU_EDIT_TREE (NULL),
+ GNOMEUIINFO_MENU_CUT_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_COPY_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_PASTE_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_SELECT_ALL_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_CLEAR_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_UNDO_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_REDO_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_FIND_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_FIND_AGAIN_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_REPLACE_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_PROPERTIES_ITEM (NULL, NULL),
+ GNOMEUIINFO_SEPARATOR,
+
+ /* 26 */
+ GNOMEUIINFO_MENU_VIEW_TREE (NULL),
+ GNOMEUIINFO_SEPARATOR,
+
+ /* 28 */
+ GNOMEUIINFO_MENU_SETTINGS_TREE (NULL),
+ GNOMEUIINFO_MENU_PREFERENCES_ITEM (NULL, NULL),
+ GNOMEUIINFO_SEPARATOR,
+
+ /* 31 */
+ GNOMEUIINFO_MENU_FILES_TREE (NULL),
+ GNOMEUIINFO_SEPARATOR,
+
+ /* 33 */
+ GNOMEUIINFO_MENU_WINDOWS_TREE (NULL),
+ GNOMEUIINFO_MENU_NEW_WINDOW_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_CLOSE_WINDOW_ITEM (NULL, NULL),
+ GNOMEUIINFO_SEPARATOR,
+
+ /* 37 */
+ GNOMEUIINFO_MENU_HELP_TREE (NULL),
+ GNOMEUIINFO_MENU_ABOUT_ITEM (NULL, NULL),
+ GNOMEUIINFO_SEPARATOR,
+
+ /* 40 */
+ GNOMEUIINFO_MENU_GAME_TREE (NULL),
+ GNOMEUIINFO_MENU_NEW_GAME_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_PAUSE_GAME_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_RESTART_GAME_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_UNDO_MOVE_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_REDO_MOVE_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_HINT_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_SCORES_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_END_GAME_ITEM (NULL, NULL),
+ GNOMEUIINFO_END
+};
+
+
+/* These were created by a perl script using the above. */
+const gchar* GladeStockMenuItemSymbols[] =
+{
+ NULL,
+ NULL,
+ "GNOMEUIINFO_MENU_FILE_TREE",
+ "GNOMEUIINFO_MENU_NEW_ITEM",
+ "GNOMEUIINFO_MENU_OPEN_ITEM",
+ "GNOMEUIINFO_MENU_SAVE_ITEM",
+ "GNOMEUIINFO_MENU_SAVE_AS_ITEM",
+ "GNOMEUIINFO_MENU_REVERT_ITEM",
+ "GNOMEUIINFO_MENU_PRINT_ITEM",
+ "GNOMEUIINFO_MENU_PRINT_SETUP_ITEM",
+ "GNOMEUIINFO_MENU_CLOSE_ITEM",
+ "GNOMEUIINFO_MENU_EXIT_ITEM",
+ NULL,
+ "GNOMEUIINFO_MENU_EDIT_TREE",
+ "GNOMEUIINFO_MENU_CUT_ITEM",
+ "GNOMEUIINFO_MENU_COPY_ITEM",
+ "GNOMEUIINFO_MENU_PASTE_ITEM",
+ "GNOMEUIINFO_MENU_SELECT_ALL_ITEM",
+ "GNOMEUIINFO_MENU_CLEAR_ITEM",
+ "GNOMEUIINFO_MENU_UNDO_ITEM",
+ "GNOMEUIINFO_MENU_REDO_ITEM",
+ "GNOMEUIINFO_MENU_FIND_ITEM",
+ "GNOMEUIINFO_MENU_FIND_AGAIN_ITEM",
+ "GNOMEUIINFO_MENU_REPLACE_ITEM",
+ "GNOMEUIINFO_MENU_PROPERTIES_ITEM",
+ NULL,
+ "GNOMEUIINFO_MENU_VIEW_TREE",
+ NULL,
+ "GNOMEUIINFO_MENU_SETTINGS_TREE",
+ "GNOMEUIINFO_MENU_PREFERENCES_ITEM",
+ NULL,
+ "GNOMEUIINFO_MENU_FILES_TREE",
+ NULL,
+ "GNOMEUIINFO_MENU_WINDOWS_TREE",
+ "GNOMEUIINFO_MENU_NEW_WINDOW_ITEM",
+ "GNOMEUIINFO_MENU_CLOSE_WINDOW_ITEM",
+ NULL,
+ "GNOMEUIINFO_MENU_HELP_TREE",
+ "GNOMEUIINFO_MENU_ABOUT_ITEM",
+ NULL,
+ "GNOMEUIINFO_MENU_GAME_TREE",
+ "GNOMEUIINFO_MENU_NEW_GAME_ITEM",
+ "GNOMEUIINFO_MENU_PAUSE_GAME_ITEM",
+ "GNOMEUIINFO_MENU_RESTART_GAME_ITEM",
+ "GNOMEUIINFO_MENU_UNDO_MOVE_ITEM",
+ "GNOMEUIINFO_MENU_REDO_MOVE_ITEM",
+ "GNOMEUIINFO_MENU_HINT_ITEM",
+ "GNOMEUIINFO_MENU_SCORES_ITEM",
+ "GNOMEUIINFO_MENU_END_GAME_ITEM",
+ NULL
+};
+
+const gint GladeStockMenuItemSize = sizeof (GladeStockMenuItemSymbols) / sizeof (GladeStockMenuItemSymbols[0]);
+
+
+/*************************************************************************
+ * Functions to output GnomeUIInfo structs in the source code.
+ *************************************************************************/
+
+/* This creates the start of the GnomeUIInfo structs, and is called by the
+ write_source functions of menus and menubars if we are building a Gnome
+ application. The menuitems call glade_gnome_write_menu_item_source() to
+ add to this, and the entire structure is added to one of the main source
+ buffers at the end of gb_widget_write_source (), by calling
+ glade_gnome_finish_menu_source(). */
+void
+glade_gnome_start_menu_source (GtkMenuShell * menu_shell,
+ GbWidgetWriteSourceData * data)
+{
+ GString *source_buffer;
+ GtkWidget *parent_item;
+ gint uiinfo_index = 0, stock_item_index;
+
+ source_buffer = g_string_sized_new (1024);
+ g_string_sprintf (source_buffer, "static GnomeUIInfo %s_uiinfo[] =\n{\n",
+ data->real_wname);
+ gtk_object_set_data (GTK_OBJECT (menu_shell), "glade-uiinfo", source_buffer);
+ gtk_object_set_data (GTK_OBJECT (menu_shell), "glade-uiinfo-name",
+ g_strdup (data->real_wname));
+
+ /* See if this is the start of the 'Help' menu, and if it is output the
+ GNOMEUIINFO_HELP item which inserts all the topics from topic.dat. */
+ if (glade_project_get_gnome_help_support (data->project)
+ && GTK_IS_MENU (menu_shell))
+ {
+ parent_item = gtk_menu_get_attach_widget (GTK_MENU (menu_shell));
+
+ if (parent_item)
+ {
+ stock_item_index = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (parent_item), GladeMenuItemStockIndexKey));
+ if (stock_item_index == GladeStockMenuHelpTree)
+ {
+ g_string_sprintfa (source_buffer, " GNOMEUIINFO_HELP (%s),\n",
+ source_make_string (data->program_name,
+ FALSE));
+ uiinfo_index++;
+ }
+ }
+ }
+
+ gtk_object_set_data (GTK_OBJECT (menu_shell), "glade-uiinfo-index",
+ GINT_TO_POINTER (uiinfo_index));
+}
+
+
+/* This is called after a menu or menubar has been output. It finishes off
+ the GnomeUIInfo struct and adds it to the GLADE_UIINFO source buffer. */
+void
+glade_gnome_finish_menu_source (GtkMenuShell * menu_shell,
+ GbWidgetWriteSourceData * data)
+{
+ GString *source_buffer;
+ gchar *uiinfo_name;
+
+ /* Finish off any radio group. */
+ glade_gnome_finish_radio_menu_item_group_source (menu_shell, data);
+
+ source_buffer = gtk_object_get_data (GTK_OBJECT (menu_shell),
+ "glade-uiinfo");
+ g_return_if_fail (source_buffer != NULL);
+
+ uiinfo_name = gtk_object_get_data (GTK_OBJECT (menu_shell),
+ "glade-uiinfo-name");
+ g_return_if_fail (uiinfo_name != NULL);
+
+ g_string_append (source_buffer, " GNOMEUIINFO_END\n};\n\n");
+ g_string_append (data->source_buffers[GLADE_UIINFO], source_buffer->str);
+ g_string_free (source_buffer, TRUE);
+ gtk_object_set_data (GTK_OBJECT (menu_shell), "glade-uiinfo", NULL);
+
+ g_free (uiinfo_name);
+ gtk_object_set_data (GTK_OBJECT (menu_shell), "glade-uiinfo-name", NULL);
+}
+
+
+/* This is called by the write_source functions of all menu items when
+ outputting Gnome source code. It adds to the GnomeUIInfo structs stored
+ in the parent menu/menubar. */
+void
+glade_gnome_write_menu_item_source (GtkMenuItem * widget,
+ GbWidgetWriteSourceData * data)
+{
+ GString *source_buffer;
+ gint stock_item_index;
+ gboolean has_child_menu = FALSE;
+ GList *tmp_list;
+ GladeSignal *activate_signal = NULL;
+ GladeAccelerator *activate_accel = NULL;
+ gchar *handler = NULL, *child_uiinfo_name = NULL;
+
+ source_buffer = gtk_object_get_data (GTK_OBJECT (GTK_WIDGET (widget)->parent), "glade-uiinfo");
+ g_return_if_fail (source_buffer != NULL);
+
+ /* First check if it is a separator, since they are simple. */
+ if (GTK_IS_SEPARATOR_MENU_ITEM (widget) || GTK_BIN (widget)->child == NULL)
+ {
+ g_string_append (source_buffer, " GNOMEUIINFO_SEPARATOR,\n");
+ glade_gnome_write_menu_item_standard_source (widget, data);
+ return;
+ }
+
+ if (widget->submenu)
+ {
+ const char *child_menu_name = gtk_widget_get_name (widget->submenu);
+
+ has_child_menu = TRUE;
+ child_uiinfo_name = source_create_valid_identifier (child_menu_name);
+ }
+
+
+ /* Find 'activate' handler in widget data. */
+ tmp_list = data->widget_data->signals;
+ while (tmp_list)
+ {
+ GladeSignal *signal = (GladeSignal *) tmp_list->data;
+ if (!strcmp (signal->name, "activate"))
+ {
+ activate_signal = signal;
+ handler = source_create_valid_identifier (signal->handler);
+ break;
+ }
+ tmp_list = tmp_list->next;
+ }
+
+ /* Find 'activate' accelerator in widget data. */
+ tmp_list = data->widget_data->accelerators;
+ while (tmp_list)
+ {
+ GladeAccelerator *accel = (GladeAccelerator *) tmp_list->data;
+ if (!strcmp (accel->signal, "activate"))
+ {
+ activate_accel = accel;
+ break;
+ }
+ tmp_list = tmp_list->next;
+ }
+
+ /* See if it is a stock item. */
+ stock_item_index = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
+ GladeMenuItemStockIndexKey));
+ if (stock_item_index > 0)
+ {
+ GnomeUIInfo *uiinfo;
+
+ uiinfo = &GladeStockMenuItemValues[stock_item_index];
+
+ /* Special code for the New item. If it has children it is
+ GNOMEUIINFO_MENU_NEW_SUBTREE, else it is GNOMEUIINFO_MENU_NEW_ITEM
+ and we must also output the label and tooltip. */
+ if (stock_item_index == GladeStockMenuItemNew)
+ {
+ if (has_child_menu)
+ {
+ g_string_sprintfa (source_buffer,
+ " GNOMEUIINFO_MENU_NEW_SUBTREE (%s_uiinfo),\n",
+ child_uiinfo_name);
+ }
+ else
+ {
+ gchar *label, *tooltip;
+
+ label = glade_util_get_label_text (GTK_BIN (widget)->child);
+ tooltip = data->widget_data->tooltip ? g_strdup (source_make_static_string (data->widget_data->tooltip, data->use_gettext)) : NULL;
+
+ g_string_sprintfa (source_buffer,
+ " GNOMEUIINFO_MENU_NEW_ITEM (%s, %s, %s, NULL),\n",
+ source_make_static_string (label, data->use_gettext),
+ tooltip ? tooltip : "NULL",
+ handler ? handler : "NULL");
+ g_free (tooltip);
+ g_free (label);
+ }
+ }
+ /* See if it is a subtree item. */
+ else if (uiinfo->type == GNOME_APP_UI_SUBTREE_STOCK)
+ {
+ if (has_child_menu)
+ {
+ g_string_sprintfa (source_buffer, " %s (%s_uiinfo),\n",
+ GladeStockMenuItemSymbols[stock_item_index],
+ child_uiinfo_name);
+ }
+ else
+ {
+ /* The stock subtree item should really have children, but if it
+ doesn't, we just output an empty GnomeUIInfo struct here. */
+ g_string_sprintfa (source_buffer, " %s (%s_uiinfo),\n",
+ GladeStockMenuItemSymbols[stock_item_index],
+ data->real_wname);
+ g_string_sprintfa (data->source_buffers[GLADE_UIINFO],
+ "static GnomeUIInfo %s_uiinfo[] =\n{\n"
+ " GNOMEUIINFO_END\n};\n\n",
+ data->real_wname);
+ }
+ }
+ /* It must be a normal stock item. */
+ else
+ {
+ g_string_sprintfa (source_buffer, " %s (%s, NULL),\n",
+ GladeStockMenuItemSymbols[stock_item_index],
+ handler ? handler : "NULL");
+ }
+ }
+ else
+ /* It is an ordinary menu item, so we need to output its type, label,
+ tooltip, accelerator, and icon (stock or ordinary), and also check
+ if it has a child menu. */
+ {
+ gchar *type, *label, *tooltip, *icon_name = NULL, *accel_mods;
+ gchar *pixmap_type, *pixmap_info, *pixmap_filename;
+ gchar accel_key_buffer[128];
+ gboolean free_pixmap_info;
+
+ label = glade_util_get_label_text (GTK_BIN (widget)->child);
+ tooltip = data->widget_data->tooltip ? g_strdup (source_make_static_string (data->widget_data->tooltip, data->use_gettext)) : NULL;
+
+ /* Determine if the item has an icon and if it is a stock icon or an
+ xpm file. */
+ free_pixmap_info = FALSE;
+ if (GTK_IS_IMAGE_MENU_ITEM (widget))
+ {
+ GtkWidget *image;
+ image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (widget));
+ if (image)
+ icon_name = gtk_object_get_data (GTK_OBJECT (image), GladeIconKey);
+ }
+ if (icon_name && icon_name[0])
+ {
+ if (glade_util_check_is_stock_id (icon_name))
+ {
+ pixmap_type = "GNOME_APP_PIXMAP_STOCK";
+ pixmap_info = g_strdup (source_make_string (icon_name, FALSE));
+ free_pixmap_info = TRUE;
+ }
+ else
+ {
+ pixmap_type = "GNOME_APP_PIXMAP_FILENAME";
+ pixmap_filename = g_strdup_printf ("%s%c%s", data->program_name,
+ G_DIR_SEPARATOR,
+ g_basename (icon_name));
+ pixmap_info = g_strdup (source_make_string (pixmap_filename,
+ FALSE));
+ g_free (pixmap_filename);
+ free_pixmap_info = TRUE;
+ }
+ }
+ else
+ {
+ pixmap_type = "GNOME_APP_PIXMAP_NONE";
+ pixmap_info = "NULL";
+ }
+
+ strcpy (accel_key_buffer, "0");
+ accel_mods = "0";
+ if (activate_accel)
+ {
+ /* Make sure we don't overflow the buffer. */
+ if (strlen (activate_accel->key) < 100)
+ {
+ strcpy (accel_key_buffer, "GDK_");
+ strcat (accel_key_buffer, activate_accel->key);
+ }
+ else
+ g_warning ("Overflow of accel_key_buffer");
+
+ accel_mods = glade_util_create_modifiers_string (activate_accel->modifiers);
+ }
+
+ if (has_child_menu)
+ {
+ type = "GNOME_APP_UI_SUBTREE";
+ g_string_sprintfa (source_buffer,
+ " {\n"
+ " %s, %s,\n"
+ " %s,\n"
+ " %s_uiinfo, NULL, NULL,\n"
+ " %s, %s,\n"
+ " %s, (GdkModifierType) %s, NULL\n"
+ " },\n",
+ type,
+ source_make_static_string (label,
+ data->use_gettext),
+ tooltip ? tooltip : "NULL",
+ child_uiinfo_name,
+ pixmap_type, pixmap_info,
+ accel_key_buffer, accel_mods);
+
+ }
+ else
+ {
+ if (GTK_IS_RADIO_MENU_ITEM (widget))
+ {
+ glade_gnome_write_radio_menu_item_source (widget, data,
+ source_buffer, label,
+ tooltip, handler,
+ accel_key_buffer,
+ accel_mods);
+ }
+ else
+ {
+ if (GTK_IS_CHECK_MENU_ITEM (widget))
+ {
+ type = "GNOME_APP_UI_TOGGLEITEM";
+ pixmap_type = "GNOME_APP_PIXMAP_NONE";
+ if (free_pixmap_info)
+ g_free (pixmap_info);
+ pixmap_info = "NULL";
+ free_pixmap_info = FALSE;
+ }
+ else
+ type = "GNOME_APP_UI_ITEM";
+
+ g_string_sprintfa (source_buffer,
+ " {\n"
+ " %s, %s,\n"
+ " %s,\n"
+ " (gpointer) %s, NULL, NULL,\n"
+ " %s, %s,\n"
+ " %s, (GdkModifierType) %s, NULL\n"
+ " },\n",
+ type,
+ source_make_static_string (label,
+ data->use_gettext),
+ tooltip ? tooltip : "NULL",
+ handler ? handler : "NULL",
+ pixmap_type, pixmap_info,
+ accel_key_buffer, accel_mods);
+ }
+ }
+
+ if (free_pixmap_info)
+ g_free (pixmap_info);
+ g_free (tooltip);
+ g_free (label);
+ }
+
+ glade_gnome_write_menu_item_standard_source (widget, data);
+
+
+ /* If there is an "activate" signal handler, we may need to output the empty
+ handler function and declaration, depending on its last modification
+ time. */
+ if (activate_signal)
+ {
+ /* Check if we need to output it. */
+ if (data->creating_callback_files
+ || (activate_signal->last_modification_time > data->last_write_time))
+ {
+ gb_widget_write_signal_handler_source (GTK_WIDGET (widget), data,
+ "activate", handler);
+ }
+ }
+
+ g_free (handler);
+ g_free (child_uiinfo_name);
+}
+
+
+/* This outputs code to save the pointer to the widget and possibly set its
+ name, using the index into the GnomeUIInfo struct. */
+static void
+glade_gnome_write_menu_item_standard_source (GtkMenuItem * widget,
+ GbWidgetWriteSourceData * data)
+{
+ GladeWidgetData *wdata = data->widget_data;
+ gchar *uiinfo_name, *uiinfo_name_key, *uiinfo_index_key;
+ gint uiinfo_index;
+
+ if (GTK_IS_RADIO_MENU_ITEM (widget))
+ {
+ uiinfo_name_key = "glade-radio-group-uiinfo-name";
+ uiinfo_index_key = "glade-radio-group-uiinfo-index";
+ }
+ else
+ {
+ uiinfo_name_key = "glade-uiinfo-name";
+ uiinfo_index_key = "glade-uiinfo-index";
+ }
+
+ uiinfo_name = gtk_object_get_data (GTK_OBJECT (GTK_WIDGET (widget)->parent),
+ uiinfo_name_key);
+ g_return_if_fail (uiinfo_name != NULL);
+
+ uiinfo_index = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (GTK_WIDGET (widget)->parent), uiinfo_index_key));
+
+ if (data->set_widget_names)
+ source_add (data,
+ " gtk_widget_set_name (%s_uiinfo[%i].widget, \"%s\");\n",
+ uiinfo_name, uiinfo_index, data->real_wname);
+
+ if (!data->use_component_struct)
+ {
+ source_add_to_buffer (data, GLADE_OBJECT_HOOKUP,
+ " GLADE_HOOKUP_OBJECT (%s, %s_uiinfo[%i].widget, %s);\n",
+ data->component_name,
+ uiinfo_name, uiinfo_index,
+ source_make_string (data->real_wname, FALSE));
+ }
+
+ if (GTK_IS_CHECK_MENU_ITEM (widget) && wdata->flags & GLADE_ACTIVE)
+ source_add (data,
+ " gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (%s_uiinfo[%i].widget), TRUE);\n",
+ uiinfo_name, uiinfo_index);
+
+ if (!(wdata->flags & GLADE_SENSITIVE))
+ source_add (data,
+ " gtk_widget_set_sensitive (%s_uiinfo[%i].widget, FALSE);\n",
+ uiinfo_name, uiinfo_index);
+
+ gtk_object_set_data (GTK_OBJECT (GTK_WIDGET (widget)->parent),
+ uiinfo_index_key, GINT_TO_POINTER (uiinfo_index + 1));
+}
+
+
+/* This outputs the source for a radio menu item. The group of radio items
+ is placed in a separate GnomeUIInfo struct, and a pointer to that is added
+ in the menus GnomeUIInfo.
+ First we check if the radio item is the start of a new group.
+ If it is, we finish off any previous group and start a new one. */
+static void
+glade_gnome_write_radio_menu_item_source (GtkMenuItem * widget,
+ GbWidgetWriteSourceData * data,
+ GString *source_buffer,
+ gchar *label,
+ gchar *tooltip,
+ gchar *handler,
+ gchar *accel_key_buffer,
+ gchar *accel_mods)
+{
+ GString *group_source_buffer;
+ gint uiinfo_index;
+
+ if (glade_gnome_is_first_radio_menu_item_in_group (widget))
+ {
+ /* Finish off any existing group. */
+ glade_gnome_finish_radio_menu_item_group_source (GTK_MENU_SHELL (GTK_WIDGET (widget)->parent), data);
+
+ /* Start the new group. */
+ group_source_buffer = g_string_sized_new (1024);
+ g_string_sprintf (group_source_buffer,
+ "static GnomeUIInfo %s_uiinfo[] =\n{\n",
+ data->real_wname);
+ gtk_object_set_data (GTK_OBJECT (GTK_WIDGET (widget)->parent),
+ "glade-radio-group-uiinfo", group_source_buffer);
+ gtk_object_set_data (GTK_OBJECT (GTK_WIDGET (widget)->parent),
+ "glade-radio-group-uiinfo-name",
+ g_strdup (data->real_wname));
+ gtk_object_set_data (GTK_OBJECT (GTK_WIDGET (widget)->parent),
+ "glade-radio-group-uiinfo-index",
+ GINT_TO_POINTER (0));
+
+ /* Insert the radio group into the menu's GnomeUIInfo struct. */
+ g_string_sprintfa (source_buffer,
+ " {\n"
+ " GNOME_APP_UI_RADIOITEMS, NULL, NULL, %s_uiinfo,\n"
+ " NULL, NULL, GNOME_APP_PIXMAP_NONE, NULL, 0,\n"
+ " (GdkModifierType) 0, NULL\n"
+ " },\n",
+ data->real_wname);
+
+ /* We need to increment the index of the parent uiinfo, so that the
+ GNOME_APP_UI_RADIOITEMS element is skipped. */
+ uiinfo_index = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (GTK_WIDGET (widget)->parent), "glade-uiinfo-index"));
+ gtk_object_set_data (GTK_OBJECT (GTK_WIDGET (widget)->parent),
+ "glade-uiinfo-index",
+ GINT_TO_POINTER (uiinfo_index + 1));
+ }
+ else
+ {
+ group_source_buffer = gtk_object_get_data (GTK_OBJECT (GTK_WIDGET (widget)->parent),
+ "glade-radio-group-uiinfo");
+ g_return_if_fail (group_source_buffer != NULL);
+ }
+
+ g_string_sprintfa (group_source_buffer,
+ " {\n"
+ " GNOME_APP_UI_ITEM, %s,\n"
+ " %s,\n"
+ " (gpointer) %s, NULL, NULL,\n"
+ " GNOME_APP_PIXMAP_NONE, NULL,\n"
+ " %s, (GdkModifierType) %s, NULL\n"
+ " },\n",
+ source_make_static_string (label,
+ data->use_gettext),
+ tooltip ? tooltip : "NULL",
+ handler ? handler : "NULL",
+ accel_key_buffer, accel_mods);
+}
+
+
+/* This checks if the menu has any unfinished radio group GnomeUIInfo struct
+ attached. If it does it is added to the final source buffer and freed. */
+static void
+glade_gnome_finish_radio_menu_item_group_source (GtkMenuShell * menu_shell,
+ GbWidgetWriteSourceData *data)
+{
+ GString *group_source_buffer;
+ gchar *group_uiinfo_name;
+
+ group_source_buffer = gtk_object_get_data (GTK_OBJECT (menu_shell),
+ "glade-radio-group-uiinfo");
+ if (!group_source_buffer)
+ return;
+
+ group_uiinfo_name = gtk_object_get_data (GTK_OBJECT (menu_shell),
+ "glade-radio-group-uiinfo-name");
+ g_return_if_fail (group_uiinfo_name != NULL);
+
+ /* Finish the struct and add it onto the final source buffer. */
+ g_string_append (group_source_buffer, " GNOMEUIINFO_END\n};\n\n");
+ g_string_append (data->source_buffers[GLADE_UIINFO],
+ group_source_buffer->str);
+
+ /* Now free it and reset the pointer. */
+ g_string_free (group_source_buffer, TRUE);
+ gtk_object_set_data (GTK_OBJECT (menu_shell), "glade-radio-group-uiinfo",
+ NULL);
+
+ g_free (group_uiinfo_name);
+ gtk_object_set_data (GTK_OBJECT (menu_shell),
+ "glade-radio-group-uiinfo-name", NULL);
+}
+
+
+/* This returns TRUE if the given radio menu item is the first item in a
+ radio group. FIXME: radio items must be next to each other in GNOME menus,
+ but we don't enforce that in the menu editor. */
+static gboolean
+glade_gnome_is_first_radio_menu_item_in_group (GtkMenuItem *menuitem)
+{
+ GList *children, *elem;
+ GtkWidget *prev_item;
+ GSList *group, *prev_group;
+
+ children = GTK_MENU_SHELL (GTK_WIDGET (menuitem)->parent)->children;
+
+ elem = g_list_find (children, menuitem);
+ g_return_val_if_fail (elem != NULL, FALSE);
+
+ /* If the item is the first item, it must start a new group. */
+ if (elem == children)
+ return TRUE;
+
+ /* If the previous item is not a radio item, it must be in a new group. */
+ prev_item = GTK_WIDGET (elem->prev->data);
+ if (!GTK_IS_RADIO_MENU_ITEM (prev_item))
+ return TRUE;
+
+ /* If the item's group isn't the same as the previous item's, it must start
+ a new group. */
+ group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (menuitem));
+ prev_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (prev_item));
+
+ if (group != prev_group)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+
+/*************************************************************************
+ * Utility Functions.
+ *************************************************************************/
+
+/* If the given widget is a dock item inside a GnomeApp it returns the
+ GnomeApp, otherwise it returns NULL. */
+GnomeApp*
+glade_gnome_is_app_dock_item (GtkWidget *widget)
+{
+ GtkWidget *dock, *app;
+
+ if (!BONOBO_IS_DOCK_ITEM (widget))
+ return NULL;
+
+ if (!widget->parent)
+ return NULL;
+
+ /* Floating items are direct children of a BonoboDock.
+ Other items are children of a BonoboDockBand. */
+ if (BONOBO_IS_DOCK (widget->parent))
+ {
+ dock = widget->parent;
+ }
+ else
+ {
+ if (!BONOBO_IS_DOCK_BAND (widget->parent))
+ return NULL;
+ dock = widget->parent->parent;
+ if (!dock || !BONOBO_IS_DOCK (dock))
+ return NULL;
+ }
+
+ if (!dock->parent || !GTK_IS_VBOX (dock->parent))
+ return NULL;
+
+ app = dock->parent->parent;
+ if (!app || !GNOME_IS_APP (app))
+ return NULL;
+
+ return GNOME_APP (app);
+}
+
+
+/* Tries to translate the text in Glade's domain, and if there is no
+ translation try the gnome-libs domain. */
+gchar*
+glade_gnome_gettext (const gchar *text)
+{
+#ifdef ENABLE_NLS
+ char *s;
+
+ s = gettext (text);
+ if (s == text)
+ s = dgettext (GLADE_LIBGNOMEUI_GETTEXT_PACKAGE, text);
+
+ return s;
+#else
+ return text;
+#endif
+}
+
+
+/* The indices come from GladeStockMenuItemValues in glade_gnome.c */
+static gint FileMenuIndices[] = { 3, 4, 5, 6, -1, 11 };
+static GnomeUIInfo FileMenu[] =
+{
+ GNOMEUIINFO_MENU_NEW_ITEM (N_("_New"), N_("Create a new file"),
+ NULL, NULL),
+ GNOMEUIINFO_MENU_OPEN_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_SAVE_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_SAVE_AS_ITEM (NULL, NULL),
+ GNOMEUIINFO_SEPARATOR,
+ GNOMEUIINFO_MENU_QUIT_ITEM (NULL, NULL),
+ GNOMEUIINFO_END
+};
+
+static gint EditMenuIndices[] = { 14, 15, 16, 18, -1, 24, -1, 29 };
+static GnomeUIInfo EditMenu[] =
+{
+ GNOMEUIINFO_MENU_CUT_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_COPY_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_PASTE_ITEM (NULL, NULL),
+ GNOMEUIINFO_MENU_CLEAR_ITEM (NULL, NULL),
+ GNOMEUIINFO_SEPARATOR,
+ GNOMEUIINFO_MENU_PROPERTIES_ITEM (NULL, NULL),
+ GNOMEUIINFO_SEPARATOR,
+ GNOMEUIINFO_MENU_PREFERENCES_ITEM (NULL, NULL),
+ GNOMEUIINFO_END
+};
+
+static gint ViewMenuIndices[] = { -1 };
+static GnomeUIInfo ViewMenu[] =
+{
+ GNOMEUIINFO_END
+};
+
+static gint HelpMenuIndices[] = { 38 };
+static GnomeUIInfo HelpMenu[] =
+{
+ GNOMEUIINFO_MENU_ABOUT_ITEM (NULL, NULL),
+ GNOMEUIINFO_END
+};
+
+static gint MainMenuIndices[] = { 2, 13, 26, 37 };
+static GnomeUIInfo MainMenu[] =
+{
+ GNOMEUIINFO_MENU_FILE_TREE (FileMenu),
+ GNOMEUIINFO_MENU_EDIT_TREE (EditMenu),
+ GNOMEUIINFO_MENU_VIEW_TREE (ViewMenu),
+ GNOMEUIINFO_MENU_HELP_TREE (HelpMenu),
+ GNOMEUIINFO_END
+};
+
+
+static void
+glade_gnome_setup_menu_items (GnomeUIInfo *uiinfo, gint *indices)
+{
+ gint i = 0;
+ gchar *name, *dest;
+ const gchar *src;
+
+ while (uiinfo->type != GNOME_APP_UI_ENDOFINFO)
+ {
+ if (uiinfo->widget)
+ {
+ if (indices[i] == -1)
+ {
+ gb_widget_create_from (uiinfo->widget, "separator");
+ }
+ else
+ {
+ name = g_malloc (strlen (uiinfo->label));
+ /* Convert spaces to underscores, and ignore periods (e.g. in
+ "Open...") and underscores (e.g. in "_Open"). */
+ for (src = uiinfo->label, dest = name; *src; src++)
+ {
+ if (*src == ' ')
+ *dest++ = '_';
+ else if (*src == '.')
+ continue;
+ else if (*src == '_')
+ continue;
+ else
+ *dest++ = *src;
+ }
+ *dest = '\0';
+
+ gb_widget_create_from (uiinfo->widget, name);
+
+ gtk_object_set_data (GTK_OBJECT (uiinfo->widget),
+ GladeMenuItemStockIndexKey,
+ GINT_TO_POINTER (indices[i]));
+
+ /* If the item has a child menu, turn it into a GbWidget.
+ If not, add a default handler to the item. */
+ if (GTK_IS_MENU_ITEM (uiinfo->widget)
+ && GTK_MENU_ITEM (uiinfo->widget)->submenu)
+ {
+ gchar *submenu_name;
+
+ submenu_name = g_strdup_printf ("%s_menu",
+ uiinfo->widget->name);
+ gtk_widget_set_name (GTK_MENU_ITEM (uiinfo->widget)->submenu,
+ submenu_name);
+ g_free (submenu_name);
+ gb_widget_create_from (GTK_MENU_ITEM (uiinfo->widget)->submenu, NULL);
+ }
+ else
+ {
+ GladeWidgetData *wdata;
+ GladeSignal *signal;
+ gchar *start = "on_", *end = "_activate";
+
+ signal = g_new (GladeSignal, 1);
+ signal->name = g_strdup ("activate");
+ /* Generate a default handler name. */
+ signal->handler = g_malloc (strlen (uiinfo->widget->name) + 1
+ + strlen (start) + strlen (end));
+ strcpy (signal->handler, start);
+ strcat (signal->handler, uiinfo->widget->name);
+ strcat (signal->handler, end);
+
+ signal->object = NULL;
+ signal->after = FALSE;
+ signal->data = NULL;
+ signal->last_modification_time = time (NULL);
+
+ wdata = gtk_object_get_data (GTK_OBJECT (uiinfo->widget),
+ GB_WIDGET_DATA_KEY);
+ wdata->signals = g_list_append (wdata->signals, signal);
+ }
+ }
+ }
+ uiinfo++;
+ i++;
+ }
+}
+
+
+/* This sets up defaults menus for GtkMenuBar and GnomeApp widgets. */
+void
+glade_gnome_setup_initial_menus (GtkWidget *widget)
+{
+ /* We create a standard menubar and toolbar which the user can edit or
+ simply delete anything they don't want. */
+ if (GNOME_IS_APP (widget))
+ gnome_app_create_menus (GNOME_APP (widget), MainMenu);
+ else if (GTK_IS_MENU_BAR (widget))
+ gnome_app_fill_menu (GTK_MENU_SHELL (widget), MainMenu, NULL, TRUE, 0);
+ else
+ g_assert_not_reached ();
+
+ /* Turn all the menus & menuitems into GbWidgets and add default
+ handlers. */
+ glade_gnome_setup_menu_items (FileMenu, FileMenuIndices);
+ glade_gnome_setup_menu_items (EditMenu, EditMenuIndices);
+ glade_gnome_setup_menu_items (ViewMenu, ViewMenuIndices);
+ glade_gnome_setup_menu_items (HelpMenu, HelpMenuIndices);
+ glade_gnome_setup_menu_items (MainMenu, MainMenuIndices);
+}
+
+
+
+
+#endif /* USE_GNOME */