mirror of
https://gitlab.gnome.org/GNOME/gimp
synced 2024-10-22 20:41:43 +00:00
27a4faa0b2
2000-10-22 Sven Neumann <sven@gimp.org> * app/edit_selection.[ch]: plugged memleak (similar to the one that was present in gtkutil_compress_motion()) in the key snooper. Round moves to nearest integer instead of truncating the value. This seems to fix the reported redraw problems when moving selections at low zoom levels. Cleaned up the code a little and converted enum values to uppercase. * app/bezier_select.c * app/free_select.c * app/fuzzy_select.c * app/move.c * app/rect_select.c * app/text_tool.c: updated to use the new EditType enum values. * app/gimprc.c: minor optimization in the GList handling. * app/layer.[ch]: removed unused functions. * app/menus.c: removed "Dump Items (Debug)" menu entry.
2041 lines
62 KiB
C
2041 lines
62 KiB
C
/* The GIMP -- an image manipulation program
|
|
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
|
*
|
|
* 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.
|
|
*/
|
|
#include "config.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <gdk/gdkkeysyms.h>
|
|
|
|
#include "appenv.h"
|
|
#include "channels_dialog.h"
|
|
#include "commands.h"
|
|
#include "dialog_handler.h"
|
|
#include "fileops.h"
|
|
#include "gimprc.h"
|
|
#include "gimpui.h"
|
|
#include "interface.h"
|
|
#include "layers_dialog.h"
|
|
#include "menus.h"
|
|
#include "paths_dialog.h"
|
|
#include "paint_funcs.h"
|
|
#include "preferences_dialog.h"
|
|
#include "procedural_db.h"
|
|
#include "scale.h"
|
|
#include "tools.h"
|
|
#include "gdisplay.h"
|
|
|
|
#include "libgimp/gimpenv.h"
|
|
|
|
#include "libgimp/gimpintl.h"
|
|
|
|
|
|
#define MRU_MENU_ENTRY_SIZE (strlen ("/File/MRU00 ") + 1)
|
|
#define MRU_MENU_ACCEL_SIZE sizeof ("<control>0")
|
|
|
|
static void menus_create_item (GtkItemFactory *item_factory,
|
|
GimpItemFactoryEntry *entry,
|
|
gpointer callback_data,
|
|
guint callback_type);
|
|
static void menus_create_items (GtkItemFactory *item_factory,
|
|
guint n_entries,
|
|
GimpItemFactoryEntry *entries,
|
|
gpointer callback_data,
|
|
guint callback_type);
|
|
static void menus_create_branches (GtkItemFactory *item_factory,
|
|
GimpItemFactoryEntry *entry);
|
|
static void menus_init (void);
|
|
|
|
#ifdef ENABLE_NLS
|
|
static gchar *menu_translate (const gchar *path,
|
|
gpointer data);
|
|
#else
|
|
#define menu_translate NULL
|
|
#endif
|
|
|
|
static void tearoff_cmd_callback (GtkWidget *widget,
|
|
gpointer callback_data,
|
|
guint callback_action);
|
|
static gint tearoff_delete_cb (GtkWidget *widget,
|
|
GdkEvent *event,
|
|
gpointer data);
|
|
#ifdef ENABLE_DEBUG_ENTRY
|
|
static void menus_debug_recurse_menu (GtkWidget *menu,
|
|
gint depth,
|
|
gchar *path);
|
|
static void menus_debug_cmd_callback (GtkWidget *widget,
|
|
gpointer callback_data,
|
|
guint callback_action);
|
|
#endif /* ENABLE_DEBUG_ENTRY */
|
|
|
|
static GSList *last_opened_raw_filenames = NULL;
|
|
|
|
/***** <Toolbox> *****/
|
|
|
|
static GimpItemFactoryEntry toolbox_entries[] =
|
|
{
|
|
/* <Toolbox>/File */
|
|
|
|
/* the underscore installs an accelerator using the character that follows */
|
|
{ { N_("/_File"), NULL, NULL, 0, "<Branch>" },
|
|
NULL, NULL },
|
|
{ { N_("/File/New..."), "<control>N", file_new_cmd_callback, 0 },
|
|
"file/dialogs/file_new.html", NULL },
|
|
{ { N_("/File/Open..."), "<control>O", file_open_cmd_callback, 0 },
|
|
"file/dialogs/file_open.html", NULL },
|
|
|
|
/* <Toolbox>/File/Acquire */
|
|
|
|
{ { "/File/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/File/Acquire"), NULL, NULL, 0, "<Branch>" },
|
|
NULL, NULL },
|
|
|
|
{ { "/File/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/File/Preferences..."), NULL, prefs_cmd_callback, 0 },
|
|
"file/dialogs/preferences/preferences.html", NULL },
|
|
|
|
/* <Toolbox>/File/Dialogs */
|
|
|
|
{ { "/File/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/File/Dialogs/Layers, Channels & Paths..."), "<control>L", dialogs_lc_cmd_callback, 0 },
|
|
"file/dialogs/layers_and_channels.html", NULL },
|
|
{ { N_("/File/Dialogs/Tool Options..."), "<control><shift>T", dialogs_tool_options_cmd_callback, 0 },
|
|
"file/dialogs/tool_options.html", NULL },
|
|
|
|
{ { "/File/Dialogs/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/File/Dialogs/Brushes..."), "<control><shift>B", dialogs_brushes_cmd_callback, 0 },
|
|
"file/dialogs/brush_selection.html", NULL },
|
|
{ { N_("/File/Dialogs/Patterns..."), "<control><shift>P", dialogs_patterns_cmd_callback, 0 },
|
|
"file/dialogs/pattern_selection.html", NULL },
|
|
{ { N_("/File/Dialogs/Gradients..."), "<control>G", dialogs_gradients_cmd_callback, 0 },
|
|
"file/dialogs/gradient_selection.html", NULL },
|
|
{ { N_("/File/Dialogs/Palette..."), "<control>P", dialogs_palette_cmd_callback, 0 },
|
|
"file/dialogs/palette_selection.html", NULL },
|
|
{ { N_("/File/Dialogs/Indexed Palette..."), NULL, dialogs_indexed_palette_cmd_callback, 0 },
|
|
"file/dialogs/indexed_palette.html", NULL },
|
|
|
|
{ { "/File/Dialogs/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/File/Dialogs/Input Devices..."), NULL, dialogs_input_devices_cmd_callback, 0 },
|
|
"file/dialogs/input_devices.html", NULL },
|
|
{ { N_("/File/Dialogs/Device Status..."), NULL, dialogs_device_status_cmd_callback, 0 },
|
|
"file/dialogs/device_status.html", NULL },
|
|
|
|
{ { "/File/Dialogs/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/File/Dialogs/Document Index..."), NULL, dialogs_document_index_cmd_callback, 0 },
|
|
"file/dialogs/document_index.html", NULL },
|
|
{ { N_("/File/Dialogs/Error Console..."), NULL, dialogs_error_console_cmd_callback, 0 },
|
|
"file/dialogs/error_console.html", NULL },
|
|
{ { N_("/File/Dialogs/Display Filters..."), NULL, dialogs_display_filters_cmd_callback, 0 },
|
|
"file/dialogs/display_filters/display_filters.html", NULL },
|
|
|
|
{ { "/File/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
|
|
/* MRU entries are inserted here */
|
|
|
|
{ { "/File/---MRU", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/File/Quit"), "<control>Q", file_quit_cmd_callback, 0 },
|
|
"file/quit.html", NULL },
|
|
|
|
/* <Toolbox>/Xtns */
|
|
|
|
/* the underscore installs an accelerator using the character that follows */
|
|
{ { N_("/_Xtns"), NULL, NULL, 0, "<Branch>" },
|
|
NULL, NULL },
|
|
{ { N_("/Xtns/Module Browser..."), NULL, dialogs_module_browser_cmd_callback, 0 },
|
|
"dialogs/module_browser.html", NULL },
|
|
|
|
{ { "/Xtns/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
|
|
/* <Toolbox>/Help */
|
|
|
|
/* the underscore installs an accelerator using the character that follows */
|
|
{ { N_("/_Help"), NULL, NULL, 0, "<Branch>" },
|
|
NULL, NULL },
|
|
{ { N_("/Help/Help..."), "F1", help_help_cmd_callback, 0 },
|
|
"help/dialogs/help.html", NULL },
|
|
{ { N_("/Help/Context Help..."), "<shift>F1", help_context_help_cmd_callback, 0 },
|
|
"help/context_help.html", NULL },
|
|
{ { N_("/Help/Tip of the Day..."), NULL, help_tips_cmd_callback, 0 },
|
|
"help/dialogs/tip_of_the_day.html", NULL },
|
|
{ { N_("/Help/About..."), NULL, help_about_cmd_callback, 0 },
|
|
"help/dialogs/about.html", NULL },
|
|
#ifdef ENABLE_DEBUG_ENTRY
|
|
{ { N_("/Help/Dump Items (Debug)"), NULL, menus_debug_cmd_callback, 0 },
|
|
NULL, NULL }
|
|
#endif
|
|
};
|
|
|
|
static guint n_toolbox_entries = (sizeof (toolbox_entries) /
|
|
sizeof (toolbox_entries[0]));
|
|
static GtkItemFactory *toolbox_factory = NULL;
|
|
|
|
/***** <Image> *****/
|
|
|
|
static GimpItemFactoryEntry image_entries[] =
|
|
{
|
|
{ { "/tearoff1", NULL, tearoff_cmd_callback, 0, "<Tearoff>" },
|
|
NULL, NULL },
|
|
|
|
/* <Image>/File */
|
|
|
|
{ { N_("/File/New..."), "<control>N", file_new_cmd_callback, 1 },
|
|
"file/dialogs/file_new.html", NULL },
|
|
{ { N_("/File/Open..."), "<control>O", file_open_cmd_callback, 0 },
|
|
"file/dialogs/file_open.html", NULL },
|
|
{ { N_("/File/Save"), "<control>S", file_save_cmd_callback, 0 },
|
|
"file/dialogs/file_save.html", NULL },
|
|
{ { N_("/File/Save As..."), NULL, file_save_as_cmd_callback, 0 },
|
|
"file/dialogs/file_save.html", NULL },
|
|
{ { N_("/File/Revert"), NULL, file_revert_cmd_callback, 0 },
|
|
"file/revert.html", NULL },
|
|
|
|
{ { "/File/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_( "/File/Close"), "<control>W", file_close_cmd_callback, 0 },
|
|
"file/close.html", NULL },
|
|
{ { N_("/File/Quit"), "<control>Q", file_quit_cmd_callback, 0 },
|
|
"file/quit.html", NULL },
|
|
|
|
{ { "/File/---moved", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
|
|
/* <Image>/Edit */
|
|
|
|
{ { N_("/Edit/Undo"), "<control>Z", edit_undo_cmd_callback, 0 },
|
|
"edit/undo.html", NULL },
|
|
{ { N_("/Edit/Redo"), "<control>R", edit_redo_cmd_callback, 0 },
|
|
"edit/redo.html", NULL },
|
|
|
|
{ { "/Edit/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/Edit/Cut"), "<control>X", edit_cut_cmd_callback, 0 },
|
|
"edit/cut.html", NULL },
|
|
{ { N_("/Edit/Copy"), "<control>C", edit_copy_cmd_callback, 0 },
|
|
"edit/copy.html", NULL },
|
|
{ { N_("/Edit/Paste"), "<control>V", edit_paste_cmd_callback, 0 },
|
|
"edit/paste.html", NULL },
|
|
{ { N_("/Edit/Paste Into"), NULL, edit_paste_into_cmd_callback, 0 },
|
|
"edit/paste_into.html", NULL },
|
|
{ { N_("/Edit/Paste as New"), NULL, edit_paste_as_new_cmd_callback, 0 },
|
|
"edit/paste_as_new.html", NULL },
|
|
|
|
/* <Image>/Edit/Buffer */
|
|
|
|
{ { N_("/Edit/Buffer/Cut Named..."), "<control><shift>X", edit_named_cut_cmd_callback, 0 },
|
|
"edit/dialogs/cut_named.html", NULL },
|
|
{ { N_("/Edit/Buffer/Copy Named..."), "<control><shift>C", edit_named_copy_cmd_callback, 0 },
|
|
"edit/dialogs/copy_named.html", NULL },
|
|
{ { N_("/Edit/Buffer/Paste Named..."), "<control><shift>V", edit_named_paste_cmd_callback, 0 },
|
|
"edit/dialogs/paste_named.html", NULL },
|
|
|
|
{ { "/Edit/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/Edit/Clear"), "<control>K", edit_clear_cmd_callback, 0 },
|
|
"edit/clear.html", NULL },
|
|
{ { N_("/Edit/Fill with FG Color"), "<control>comma", edit_fill_cmd_callback, (guint)FOREGROUND_FILL },
|
|
"edit/fill.html", NULL },
|
|
{ { N_("/Edit/Fill with BG Color"), "<control>period", edit_fill_cmd_callback, (guint)BACKGROUND_FILL },
|
|
"edit/fill.html", NULL },
|
|
{ { N_("/Edit/Stroke"), NULL, edit_stroke_cmd_callback, 0 },
|
|
"edit/stroke.html", NULL },
|
|
|
|
{ { "/Edit/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
|
|
/* <Image>/Select */
|
|
|
|
{ { N_("/Select/Invert"), "<control>I", select_invert_cmd_callback, 0 },
|
|
"select/invert.html", NULL },
|
|
{ { N_("/Select/All"), "<control>A", select_all_cmd_callback, 0 },
|
|
"select/all.html", NULL },
|
|
{ { N_("/Select/None"), "<control><shift>A", select_none_cmd_callback, 0 },
|
|
"select/none.html", NULL },
|
|
{ { N_("/Select/Float"), "<control><shift>L", select_float_cmd_callback, 0 },
|
|
"select/float.html", NULL },
|
|
|
|
{ { "/Select/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/Select/Feather..."), "<control><shift>F", select_feather_cmd_callback, 0 },
|
|
"select/dialogs/feather_selection.html", NULL },
|
|
{ { N_("/Select/Sharpen"), "<control><shift>H", select_sharpen_cmd_callback, 0 },
|
|
"select/sharpen.html", NULL },
|
|
{ { N_("/Select/Shrink..."), NULL, select_shrink_cmd_callback, 0 },
|
|
"select/dialogs/shrink_selection.html", NULL },
|
|
{ { N_("/Select/Grow..."), NULL, select_grow_cmd_callback, 0 },
|
|
"select/dialogs/grow_selection.html", NULL },
|
|
{ { N_("/Select/Border..."), "<control><shift>B", select_border_cmd_callback, 0 },
|
|
"select/dialogs/border_selection.html", NULL },
|
|
|
|
{ { "/Select/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/Select/Save to Channel"), NULL, select_save_cmd_callback, 0 },
|
|
"select/save_to_channel.html", NULL },
|
|
|
|
/* <Image>/View */
|
|
|
|
{ { N_("/View/Zoom In"), "equal", view_zoomin_cmd_callback, 0 },
|
|
"view/zoom.html", NULL },
|
|
{ { N_("/View/Zoom Out"), "minus", view_zoomout_cmd_callback, 0 },
|
|
"view/zoom.html", NULL },
|
|
|
|
/* <Image>/View/Zoom */
|
|
|
|
{ { N_("/View/Zoom/16:1"), NULL, view_zoom_16_1_cmd_callback, 0 },
|
|
"view/zoom.html", NULL },
|
|
{ { N_("/View/Zoom/8:1"), NULL, view_zoom_8_1_cmd_callback, 0 },
|
|
"view/zoom.html", NULL },
|
|
{ { N_("/View/Zoom/4:1"), NULL, view_zoom_4_1_cmd_callback, 0 },
|
|
"view/zoom.html", NULL },
|
|
{ { N_("/View/Zoom/2:1"), NULL, view_zoom_2_1_cmd_callback, 0 },
|
|
"view/zoom.html", NULL },
|
|
{ { N_("/View/Zoom/1:1"), "1", view_zoom_1_1_cmd_callback, 0 },
|
|
"view/zoom.html", NULL },
|
|
{ { N_("/View/Zoom/1:2"), NULL, view_zoom_1_2_cmd_callback, 0 },
|
|
"view/zoom.html", NULL },
|
|
{ { N_("/View/Zoom/1:4"), NULL, view_zoom_1_4_cmd_callback, 0 },
|
|
"view/zoom.html", NULL },
|
|
{ { N_("/View/Zoom/1:8"), NULL, view_zoom_1_8_cmd_callback, 0 },
|
|
"view/zoom.html", NULL },
|
|
{ { N_("/View/Zoom/1:16"), NULL, view_zoom_1_16_cmd_callback, 0 },
|
|
"view/zoom.html", NULL },
|
|
|
|
{ { N_("/View/Dot for Dot"), NULL, view_dot_for_dot_cmd_callback, 0, "<ToggleItem>" },
|
|
"view/dot_for_dot.html", NULL },
|
|
|
|
{ { "/View/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/View/Info Window..."), "<control><shift>I", view_info_window_cmd_callback, 0 },
|
|
"view/dialogs/info_window.html", NULL },
|
|
{ { N_("/View/Nav. Window..."), "<control><shift>N", view_nav_window_cmd_callback, 0 },
|
|
"view/dialogs/navigation_window.html", NULL },
|
|
|
|
{ { "/View/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/View/Toggle Selection"), "<control>T", view_toggle_selection_cmd_callback, 0, "<ToggleItem>" },
|
|
"view/toggle_selection.html", NULL },
|
|
{ { N_("/View/Toggle Rulers"), "<control><shift>R", view_toggle_rulers_cmd_callback, 0, "<ToggleItem>" },
|
|
"view/toggle_rulers.html", NULL },
|
|
{ { N_("/View/Toggle Statusbar"), "<control><shift>S", view_toggle_statusbar_cmd_callback, 0, "<ToggleItem>" },
|
|
"view/toggle_statusbar.html", NULL },
|
|
{ { N_("/View/Toggle Guides"), "<control><shift>T", view_toggle_guides_cmd_callback, 0, "<ToggleItem>" },
|
|
"view/toggle_guides.html", NULL },
|
|
{ { N_("/View/Snap to Guides"), NULL, view_snap_to_guides_cmd_callback, 0, "<ToggleItem>" },
|
|
"view/snap_to_guides.html", NULL },
|
|
|
|
{ { "/View/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/View/New View"), NULL, view_new_view_cmd_callback, 0 },
|
|
"view/new_view.html", NULL },
|
|
{ { N_("/View/Shrink Wrap"), "<control>E", view_shrink_wrap_cmd_callback, 0 },
|
|
"view/shrink_wrap.html", NULL },
|
|
|
|
/* <Image>/Image/Mode */
|
|
|
|
{ { N_("/Image/Mode/RGB"), "<alt>R", image_convert_rgb_cmd_callback, 0 },
|
|
"image/mode/convert_to_rgb.html", NULL },
|
|
{ { N_("/Image/Mode/Grayscale"), "<alt>G", image_convert_grayscale_cmd_callback, 0 },
|
|
"image/mode/convert_to_grayscale.html", NULL },
|
|
{ { N_("/Image/Mode/Indexed..."), "<alt>I", image_convert_indexed_cmd_callback, 0 },
|
|
"image/mode/dialogs/convert_to_indexed.html", NULL },
|
|
|
|
{ { "/Image/Mode/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
|
|
/* <Image>/Image/Colors */
|
|
|
|
{ { N_("/Image/Colors/Desaturate"), NULL, image_desaturate_cmd_callback, 0 },
|
|
"image/colors/desaturate.html", NULL },
|
|
{ { N_("/Image/Colors/Invert"), NULL, image_invert_cmd_callback, 0 },
|
|
"image/colors/invert.html", NULL },
|
|
|
|
{ { "/Image/Colors/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
|
|
/* <Image>/Image/Colors/Auto */
|
|
|
|
{ { N_("/Image/Colors/Auto/Equalize"), NULL, image_equalize_cmd_callback, 0 },
|
|
"image/colors/auto/equalize.html", NULL },
|
|
|
|
{ { "/Image/Colors/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
|
|
/* <Image>/Image/Alpha */
|
|
|
|
{ { N_("/Image/Alpha/Add Alpha Channel"), NULL, layers_add_alpha_channel_cmd_callback, 0 },
|
|
"layers/add_alpha_channel.html", NULL },
|
|
|
|
/* <Image>/Image/Transforms */
|
|
|
|
{ { N_("/Image/Transforms/Offset..."), "<control><shift>O", image_offset_cmd_callback, 0 },
|
|
"image/transforms/dialogs/offset.html", NULL },
|
|
{ { N_("/Image/Transforms/Rotate"), NULL, NULL, 0, "<Branch>" },
|
|
NULL, NULL },
|
|
{ { "/Image/Transforms/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
|
|
{ { "/Image/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/Image/Canvas Size..."), NULL, image_resize_cmd_callback, 0 },
|
|
"image/dialogs/set_canvas_size.html", NULL },
|
|
{ { N_("/Image/Scale Image..."), NULL, image_scale_cmd_callback, 0 },
|
|
"image/dialogs/scale_image.html", NULL },
|
|
{ { N_("/Image/Duplicate"), "<control>D", image_duplicate_cmd_callback, 0 },
|
|
"image/duplicate.html", NULL },
|
|
|
|
{ { "/Image/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
|
|
/* <Image>/Layers */
|
|
|
|
{ { N_("/Layers/Layers, Channels & Paths..."), "<control>L", dialogs_lc_cmd_callback, 0 },
|
|
"dialogs/layers_and_channels.html", NULL },
|
|
{ { "/Layers/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/Layers/Layer to Imagesize"), NULL, layers_resize_to_image_cmd_callback, 0 },
|
|
"layers/layer_to_image_size.html", NULL },
|
|
|
|
/* <Image>/Layers/Stack */
|
|
|
|
{ { N_("/Layers/Stack/Previous Layer"), "Prior", layers_previous_cmd_callback, 0 },
|
|
"layers/stack/stack.html#previous_layer", NULL },
|
|
{ { N_("/Layers/Stack/Next Layer"), "Next", layers_next_cmd_callback, 0 },
|
|
"layers/stack/stack.html#next_layer", NULL },
|
|
{ { N_("/Layers/Stack/Raise Layer"), "<shift>Prior", layers_raise_cmd_callback, 0 },
|
|
"layers/stack/stack.html#raise_layer", NULL },
|
|
{ { N_("/Layers/Stack/Lower Layer"), "<shift>Next", layers_lower_cmd_callback, 0 },
|
|
"layers/stack/stack.html#lower_layer", NULL },
|
|
{ { N_("/Layers/Stack/Layer to Top"), "<control>Prior", layers_raise_to_top_cmd_callback, 0 },
|
|
"layers/stack/stack.html#layer_to_top", NULL },
|
|
{ { N_("/Layers/Stack/Layer to Bottom"), "<control>Next", layers_lower_to_bottom_cmd_callback, 0 },
|
|
"layers/stack/stack.html#layer_to_bottom", NULL },
|
|
{ { "/Layers/Stack/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
|
|
/* <Image>/Layers/Rotate */
|
|
|
|
{ { N_("/Layers/Rotate"), NULL, NULL, 0, "<Branch>" },
|
|
NULL, NULL },
|
|
|
|
{ { "/Layers/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/Layers/Anchor Layer"), "<control>H", layers_anchor_cmd_callback, 0 },
|
|
"layers/anchor_layer.html", NULL },
|
|
{ { N_("/Layers/Merge Visible Layers..."), "<control>M", layers_merge_cmd_callback, 0 },
|
|
"layers/dialogs/merge_visible_layers.html", NULL },
|
|
{ { N_("/Layers/Flatten Image"), NULL, layers_flatten_cmd_callback, 0 },
|
|
"layers/flatten_image.html", NULL },
|
|
|
|
{ { "/Layers/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/Layers/Mask to Selection"), NULL, layers_mask_select_cmd_callback, 0 },
|
|
"layers/mask_to_selection.html", NULL },
|
|
|
|
{ { "/Layers/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/Layers/Add Alpha Channel"), NULL, layers_add_alpha_channel_cmd_callback, 0 },
|
|
"layers/add_alpha_channel.html", NULL },
|
|
{ { N_("/Layers/Alpha to Selection"), NULL, layers_alpha_select_cmd_callback, 0 },
|
|
"layers/alpha_to_selection.html", NULL },
|
|
|
|
{ { "/Layers/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
|
|
/* <Image>/Tools */
|
|
|
|
{ { N_("/Tools/Toolbox"), NULL, toolbox_raise_callback, 0 },
|
|
"toolbox/toolbox.html", NULL },
|
|
{ { N_("/Tools/Default Colors"), "D", tools_default_colors_cmd_callback, 0 },
|
|
"toolbox/toolbox.html#default_colors", NULL },
|
|
{ { N_("/Tools/Swap Colors"), "X", tools_swap_colors_cmd_callback, 0 },
|
|
"toolbox/toolbox.html#swap_colors", NULL },
|
|
{ { "/Tools/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
|
|
/* <Image>/Dialogs */
|
|
|
|
{ { N_("/Dialogs/Layers, Channels & Paths..."), "<control>L", dialogs_lc_cmd_callback, 0 },
|
|
"dialogs/layers_and_channels.html", NULL },
|
|
{ { N_("/Dialogs/Tool Options..."), NULL, dialogs_tool_options_cmd_callback, 0 },
|
|
"dialogs/tool_options.html", NULL },
|
|
|
|
{ { "/Dialogs/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/Dialogs/Brushes..."), "<control><shift>B", dialogs_brushes_cmd_callback, 0 },
|
|
"dialogs/brush_selection.html", NULL },
|
|
{ { N_("/Dialogs/Patterns..."), "<control><shift>P", dialogs_patterns_cmd_callback, 0 },
|
|
"dialogs/pattern_selection.html", NULL },
|
|
{ { N_("/Dialogs/Gradients..."), "<control>G", dialogs_gradients_cmd_callback, 0 },
|
|
"dialogs/gradient_selection.html", NULL },
|
|
{ { N_("/Dialogs/Palette..."), "<control>P", dialogs_palette_cmd_callback, 0 },
|
|
"dialogs/palette_selection.html", NULL },
|
|
{ { N_("/Dialogs/Indexed Palette..."), NULL, dialogs_indexed_palette_cmd_callback, 0 },
|
|
"dialogs/indexed_palette.html", NULL },
|
|
|
|
{ { "/Dialogs/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/Dialogs/Input Devices..."), NULL, dialogs_input_devices_cmd_callback, 0 },
|
|
"dialogs/input_devices.html", NULL },
|
|
{ { N_("/Dialogs/Device Status..."), NULL, dialogs_device_status_cmd_callback, 0 },
|
|
"dialogs/device_status.html", NULL },
|
|
|
|
{ { "/Dialogs/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/Dialogs/Document Index..."), NULL, dialogs_document_index_cmd_callback, 0 },
|
|
"dialogs/document_index.html", NULL },
|
|
{ { N_("/Dialogs/Error Console..."), NULL, dialogs_error_console_cmd_callback, 0 },
|
|
"dialogs/error_console.html", NULL },
|
|
{ { N_("/Dialogs/Display Filters..."), NULL, dialogs_display_filters_cmd_callback, 0 },
|
|
"dialogs/display_filters/display_filters.html", NULL },
|
|
{ { N_("/Dialogs/Undo History..."), NULL, dialogs_undo_history_cmd_callback, 0},
|
|
"dialogs/undo_history.html", NULL },
|
|
|
|
|
|
{ { "/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
|
|
/* <Image>/Filters */
|
|
|
|
{ { N_("/Filters/Repeat Last"), "<alt>F", filters_repeat_cmd_callback, 0x0 },
|
|
"filters/repeat_last.html", NULL },
|
|
{ { N_("/Filters/Re-Show Last"), "<alt><shift>F", filters_repeat_cmd_callback, 0x1 },
|
|
"filters/reshow_last.html", NULL },
|
|
|
|
{ { "/Filters/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/Filters/Blur"), NULL, NULL, 0, "<Branch>" },
|
|
NULL, NULL },
|
|
{ { N_("/Filters/Colors"), NULL, NULL, 0, "<Branch>" },
|
|
NULL, NULL },
|
|
{ { N_("/Filters/Noise"), NULL, NULL, 0, "<Branch>" },
|
|
NULL, NULL },
|
|
{ { N_("/Filters/Edge-Detect"), NULL, NULL, 0, "<Branch>" },
|
|
NULL, NULL },
|
|
{ { N_("/Filters/Enhance"), NULL, NULL, 0, "<Branch>" },
|
|
NULL, NULL },
|
|
{ { N_("/Filters/Generic"), NULL, NULL, 0, "<Branch>" },
|
|
NULL, NULL },
|
|
|
|
{ { "/Filters/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/Filters/Glass Effects"), NULL, NULL, 0, "<Branch>" },
|
|
NULL, NULL },
|
|
{ { N_("/Filters/Light Effects"), NULL, NULL, 0, "<Branch>" },
|
|
NULL, NULL },
|
|
{ { N_("/Filters/Distorts"), NULL, NULL, 0, "<Branch>" },
|
|
NULL, NULL },
|
|
{ { N_("/Filters/Artistic"), NULL, NULL, 0, "<Branch>" },
|
|
NULL, NULL },
|
|
{ { N_("/Filters/Map"), NULL, NULL, 0, "<Branch>" },
|
|
NULL, NULL },
|
|
{ { N_("/Filters/Render"), NULL, NULL, 0, "<Branch>" },
|
|
NULL, NULL },
|
|
{ { N_("/Filters/Web"), NULL, NULL, 0, "<Branch>" },
|
|
NULL, NULL },
|
|
|
|
{ { "/Filters/---INSERT", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/Filters/Animation"), NULL, NULL, 0, "<Branch>" },
|
|
NULL, NULL },
|
|
{ { N_("/Filters/Combine"), NULL, NULL, 0, "<Branch>" },
|
|
NULL, NULL },
|
|
|
|
{ { "/Filters/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/Filters/Toys"), NULL, NULL, 0, "<Branch>" },
|
|
NULL, NULL },
|
|
};
|
|
static guint n_image_entries = (sizeof (image_entries) /
|
|
sizeof (image_entries[0]));
|
|
static GtkItemFactory *image_factory = NULL;
|
|
|
|
/***** <Load> *****/
|
|
|
|
static GimpItemFactoryEntry load_entries[] =
|
|
{
|
|
{ { N_("/Automatic"), NULL, file_open_by_extension_callback, 0 },
|
|
"open_by_extension.html", NULL },
|
|
|
|
{ { "/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL }
|
|
};
|
|
static guint n_load_entries = (sizeof (load_entries) /
|
|
sizeof (load_entries[0]));
|
|
static GtkItemFactory *load_factory = NULL;
|
|
|
|
/***** <Save> *****/
|
|
|
|
static GimpItemFactoryEntry save_entries[] =
|
|
{
|
|
{ { N_("/By Extension"), NULL, file_save_by_extension_callback, 0 },
|
|
"save_by_extension.html", NULL },
|
|
|
|
{ { "/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
};
|
|
static guint n_save_entries = (sizeof (save_entries) /
|
|
sizeof (save_entries[0]));
|
|
static GtkItemFactory *save_factory = NULL;
|
|
|
|
/***** <Layers> *****/
|
|
|
|
static GimpItemFactoryEntry layers_entries[] =
|
|
{
|
|
{ { N_("/New Layer..."), "<control>N", layers_dialog_new_layer_callback, 0 },
|
|
"dialogs/new_layer.html", NULL },
|
|
|
|
/* <Layers>/Stack */
|
|
|
|
{ { N_("/Stack/Raise Layer"), "<control>F", layers_dialog_raise_layer_callback, 0 },
|
|
"stack/stack.html#raise_layer", NULL },
|
|
{ { N_("/Stack/Lower Layer"), "<control>B", layers_dialog_lower_layer_callback, 0 },
|
|
"stack/stack.html#lower_layer", NULL },
|
|
{ { N_("/Stack/Layer to Top"), "<shift><control>F", layers_dialog_raise_layer_to_top_callback, 0 },
|
|
"stack/stack.html#later_to_top", NULL },
|
|
{ { N_("/Stack/Layer to Bottom"), "<shift><control>B", layers_dialog_lower_layer_to_bottom_callback, 0 },
|
|
"stack/stack.html#layer_to_bottom", NULL },
|
|
|
|
{ { N_("/Duplicate Layer"), "<control>C", layers_dialog_duplicate_layer_callback, 0 },
|
|
"duplicate_layer.html", NULL },
|
|
{ { N_("/Anchor Layer"), "<control>H", layers_dialog_anchor_layer_callback, 0 },
|
|
"anchor_layer.html", NULL },
|
|
{ { N_("/Delete Layer"), "<control>X", layers_dialog_delete_layer_callback, 0 },
|
|
"delete_layer.html", NULL },
|
|
|
|
{ { "/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/Layer Boundary Size..."), "<control>R", layers_dialog_resize_layer_callback, 0 },
|
|
"dialogs/resize_layer.html", NULL },
|
|
{ { N_("/Layer to Imagesize"), NULL, layers_dialog_resize_to_image_callback, 0 },
|
|
"layer_to_image_size.html", NULL },
|
|
{ { N_("/Scale Layer..."), "<control>S", layers_dialog_scale_layer_callback, 0 },
|
|
"dialogs/scale_layer.html", NULL },
|
|
|
|
{ { "/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/Merge Visible Layers..."), "<control>M", layers_dialog_merge_layers_callback, 0 },
|
|
"dialogs/merge_visible_layers.html", NULL },
|
|
{ { N_("/Merge Down"), "<control><shift>M", layers_dialog_merge_down_callback, 0 },
|
|
"merge_down.html", NULL },
|
|
{ { N_("/Flatten Image"), NULL, layers_dialog_flatten_image_callback, 0 },
|
|
"flatten_image.html", NULL },
|
|
|
|
{ { "/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/Add Layer Mask..."), NULL, layers_dialog_add_layer_mask_callback, 0 },
|
|
"dialogs/add_mask.html", NULL },
|
|
{ { N_("/Apply Layer Mask"), NULL, layers_dialog_apply_layer_mask_callback, 0 },
|
|
"apply_mask.html", NULL },
|
|
{ { N_("/Delete Layer Mask"), NULL, layers_dialog_delete_layer_mask_callback, 0 },
|
|
"delete_mask.html", NULL },
|
|
{ { N_("/Mask to Selection"), NULL, layers_dialog_mask_select_callback, 0 },
|
|
"mask_to_selection.html", NULL },
|
|
|
|
{ { "/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/Add Alpha Channel"), NULL, layers_dialog_add_alpha_channel_callback, 0 },
|
|
"add_alpha_channel.html", NULL },
|
|
{ { N_("/Alpha to Selection"), NULL, layers_dialog_alpha_select_callback, 0 },
|
|
"alpha_to_selection.html", NULL },
|
|
|
|
{ { "/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/Edit Layer Attributes..."), NULL, layers_dialog_edit_layer_attributes_callback, 0 },
|
|
"dialogs/edit_layer_attributes.html", NULL }
|
|
};
|
|
static guint n_layers_entries = (sizeof (layers_entries) /
|
|
sizeof (layers_entries[0]));
|
|
static GtkItemFactory *layers_factory = NULL;
|
|
|
|
/***** <Channels> *****/
|
|
|
|
static GimpItemFactoryEntry channels_entries[] =
|
|
{
|
|
{ { N_("/New Channel..."), "<control>N", channels_dialog_new_channel_callback, 0 },
|
|
"dialogs/new_channel.html", NULL },
|
|
{ { N_("/Raise Channel"), "<control>F", channels_dialog_raise_channel_callback, 0 },
|
|
"raise_channel.html", NULL },
|
|
{ { N_("/Lower Channel"), "<control>B", channels_dialog_lower_channel_callback, 0 },
|
|
"lower_channel.html", NULL },
|
|
{ { N_("/Duplicate Channel"), "<control>C", channels_dialog_duplicate_channel_callback, 0 },
|
|
"duplicate_channel.html", NULL },
|
|
|
|
{ { "/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/Channel to Selection"), "<control>S", channels_dialog_channel_to_sel_callback, 0 },
|
|
"channel_to_selection.html", NULL },
|
|
{ { N_("/Add to Selection"), NULL, channels_dialog_add_channel_to_sel_callback, 0 },
|
|
"channel_to_selection.html#add", NULL },
|
|
{ { N_("/Subtract from Selection"), NULL, channels_dialog_sub_channel_from_sel_callback, 0 },
|
|
"channel_to_selection.html#subtract", NULL },
|
|
{ { N_("/Intersect with Selection"), NULL, channels_dialog_intersect_channel_with_sel_callback, 0 },
|
|
"channel_to_selection.html#intersect", NULL },
|
|
|
|
{ { "/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/Delete Channel"), "<control>X", channels_dialog_delete_channel_callback, 0 },
|
|
"delete_channel.html", NULL },
|
|
|
|
{ { "/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/Edit Channel Attributes..."), NULL, channels_dialog_edit_channel_attributes_callback, 0 },
|
|
"dialogs/edit_channel_attributes.html", NULL }
|
|
};
|
|
static guint n_channels_entries = (sizeof (channels_entries) /
|
|
sizeof (channels_entries[0]));
|
|
static GtkItemFactory *channels_factory = NULL;
|
|
|
|
/***** <Paths> *****/
|
|
|
|
static GimpItemFactoryEntry paths_entries[] =
|
|
{
|
|
{ { N_("/New Path"), "<control>N", paths_dialog_new_path_callback, 0 },
|
|
"new_path.html", NULL },
|
|
{ { N_("/Duplicate Path"), "<control>U", paths_dialog_dup_path_callback, 0 },
|
|
"duplicate_path.html", NULL },
|
|
{ { N_("/Path to Selection"), "<control>S", paths_dialog_path_to_sel_callback, 0 },
|
|
"path_to_selection.html", NULL },
|
|
{ { N_("/Selection to Path"), "<control>P", paths_dialog_sel_to_path_callback, 0 },
|
|
"filters/sel2path.html", NULL },
|
|
{ { N_("/Stroke Path"), "<control>T", paths_dialog_stroke_path_callback, 0 },
|
|
"stroke_path.html", NULL },
|
|
{ { N_("/Delete Path"), "<control>X", paths_dialog_delete_path_callback, 0 },
|
|
"delete_path.html", NULL },
|
|
|
|
{ { "/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/Copy Path"), "<control>C", paths_dialog_copy_path_callback, 0 },
|
|
"copy_path.html", NULL },
|
|
{ { N_("/Paste Path"), "<control>V", paths_dialog_paste_path_callback, 0 },
|
|
"paste_path.html", NULL },
|
|
{ { N_("/Import Path..."), "<control>I", paths_dialog_import_path_callback, 0 },
|
|
"dialogs/import_path.html", NULL },
|
|
{ { N_("/Export Path..."), "<control>E", paths_dialog_export_path_callback, 0 },
|
|
"dialogs/export_path.html", NULL },
|
|
|
|
{ { "/---", NULL, NULL, 0, "<Separator>" },
|
|
NULL, NULL },
|
|
{ { N_("/Edit Path Attributes..."), NULL, paths_dialog_edit_path_attributes_callback, 0 },
|
|
"dialogs/edit_path_attributes.html", NULL }
|
|
};
|
|
static guint n_paths_entries = (sizeof (paths_entries) /
|
|
sizeof (paths_entries[0]));
|
|
static GtkItemFactory *paths_factory = NULL;
|
|
|
|
static gboolean initialize = TRUE;
|
|
|
|
void
|
|
menus_get_toolbox_menubar (GtkWidget **menubar,
|
|
GtkAccelGroup **accel_group)
|
|
{
|
|
if (initialize)
|
|
menus_init ();
|
|
|
|
if (menubar)
|
|
*menubar = toolbox_factory->widget;
|
|
if (accel_group)
|
|
*accel_group = toolbox_factory->accel_group;
|
|
}
|
|
|
|
void
|
|
menus_get_image_menu (GtkWidget **menu,
|
|
GtkAccelGroup **accel_group)
|
|
{
|
|
if (initialize)
|
|
menus_init ();
|
|
|
|
if (menu)
|
|
*menu = image_factory->widget;
|
|
if (accel_group)
|
|
*accel_group = image_factory->accel_group;
|
|
}
|
|
|
|
void
|
|
menus_get_load_menu (GtkWidget **menu,
|
|
GtkAccelGroup **accel_group)
|
|
{
|
|
if (initialize)
|
|
menus_init ();
|
|
|
|
if (menu)
|
|
*menu = load_factory->widget;
|
|
if (accel_group)
|
|
*accel_group = load_factory->accel_group;
|
|
}
|
|
|
|
void
|
|
menus_get_save_menu (GtkWidget **menu,
|
|
GtkAccelGroup **accel_group)
|
|
{
|
|
if (initialize)
|
|
menus_init ();
|
|
|
|
if (menu)
|
|
*menu = save_factory->widget;
|
|
if (accel_group)
|
|
*accel_group = save_factory->accel_group;
|
|
}
|
|
|
|
void
|
|
menus_get_layers_menu (GtkWidget **menu,
|
|
GtkAccelGroup **accel_group)
|
|
{
|
|
if (initialize)
|
|
menus_init ();
|
|
|
|
if (menu)
|
|
*menu = layers_factory->widget;
|
|
if (accel_group)
|
|
*accel_group = layers_factory->accel_group;
|
|
}
|
|
|
|
void
|
|
menus_get_channels_menu (GtkWidget **menu,
|
|
GtkAccelGroup **accel_group)
|
|
{
|
|
if (initialize)
|
|
menus_init ();
|
|
|
|
if (menu)
|
|
*menu = channels_factory->widget;
|
|
if (accel_group)
|
|
*accel_group = channels_factory->accel_group;
|
|
}
|
|
|
|
void
|
|
menus_get_paths_menu (GtkWidget **menu,
|
|
GtkAccelGroup **accel_group)
|
|
{
|
|
if (initialize)
|
|
menus_init ();
|
|
|
|
if (menu)
|
|
*menu = paths_factory->widget;
|
|
if (accel_group)
|
|
*accel_group = paths_factory->accel_group;
|
|
}
|
|
|
|
void
|
|
menus_create_item_from_full_path (GimpItemFactoryEntry *entry,
|
|
gchar *domain_name,
|
|
gpointer callback_data)
|
|
{
|
|
GtkItemFactory *item_factory;
|
|
gchar *path;
|
|
|
|
if (initialize)
|
|
menus_init ();
|
|
|
|
path = entry->entry.path;
|
|
item_factory = gtk_item_factory_from_path (path);
|
|
|
|
if (!item_factory)
|
|
{
|
|
g_warning ("entry refers to unknown item factory: \"%s\"", path);
|
|
return;
|
|
}
|
|
|
|
gtk_object_set_data (GTK_OBJECT (item_factory), "textdomain", domain_name);
|
|
|
|
while (*path != '>')
|
|
path++;
|
|
path++;
|
|
|
|
entry->entry.path = path;
|
|
|
|
menus_create_item (item_factory, entry, callback_data, 2);
|
|
}
|
|
|
|
static void
|
|
menus_create_branches (GtkItemFactory *item_factory,
|
|
GimpItemFactoryEntry *entry)
|
|
{
|
|
GString *tearoff_path;
|
|
gint factory_length;
|
|
gchar *p;
|
|
gchar *path;
|
|
|
|
tearoff_path = g_string_new ("");
|
|
|
|
path = entry->entry.path;
|
|
p = strchr (path, '/');
|
|
factory_length = p - path;
|
|
|
|
/* skip the first slash */
|
|
if (p)
|
|
p = strchr (p + 1, '/');
|
|
|
|
while (p)
|
|
{
|
|
g_string_assign (tearoff_path, path + factory_length);
|
|
g_string_truncate (tearoff_path, p - path - factory_length);
|
|
|
|
if (!gtk_item_factory_get_widget (item_factory, tearoff_path->str))
|
|
{
|
|
GimpItemFactoryEntry branch_entry =
|
|
{
|
|
{ NULL, NULL, NULL, 0, "<Branch>" },
|
|
NULL,
|
|
NULL
|
|
};
|
|
|
|
branch_entry.entry.path = tearoff_path->str;
|
|
gtk_object_set_data (GTK_OBJECT (item_factory), "complete", path);
|
|
menus_create_item (item_factory, &branch_entry, NULL, 2);
|
|
gtk_object_remove_data (GTK_OBJECT (item_factory), "complete");
|
|
}
|
|
|
|
g_string_append (tearoff_path, "/tearoff1");
|
|
|
|
if (!gtk_item_factory_get_widget (item_factory, tearoff_path->str))
|
|
{
|
|
GimpItemFactoryEntry tearoff_entry =
|
|
{
|
|
{ NULL, NULL, tearoff_cmd_callback, 0, "<Tearoff>" },
|
|
NULL,
|
|
NULL
|
|
};
|
|
|
|
tearoff_entry.entry.path = tearoff_path->str;
|
|
menus_create_item (item_factory, &tearoff_entry, NULL, 2);
|
|
}
|
|
|
|
p = strchr (p + 1, '/');
|
|
}
|
|
|
|
g_string_free (tearoff_path, TRUE);
|
|
}
|
|
|
|
static void
|
|
menus_filters_subdirs_to_top (GtkMenu *menu)
|
|
{
|
|
GtkMenuItem *menu_item;
|
|
GList *list;
|
|
gboolean submenus_passed = FALSE;
|
|
gint pos;
|
|
gint items;
|
|
|
|
pos = 1;
|
|
items = 0;
|
|
|
|
for (list = GTK_MENU_SHELL (menu)->children; list; list = g_list_next (list))
|
|
{
|
|
menu_item = GTK_MENU_ITEM (list->data);
|
|
items++;
|
|
|
|
if (menu_item->submenu)
|
|
{
|
|
if (submenus_passed)
|
|
{
|
|
menus_filters_subdirs_to_top (GTK_MENU (menu_item->submenu));
|
|
gtk_menu_reorder_child (menu, GTK_WIDGET (menu_item), pos++);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
submenus_passed = TRUE;
|
|
}
|
|
}
|
|
|
|
if (pos > 1 && items > pos)
|
|
{
|
|
GtkWidget *separator;
|
|
|
|
separator = gtk_menu_item_new ();
|
|
gtk_menu_insert (menu, separator, pos);
|
|
gtk_widget_show (separator);
|
|
}
|
|
}
|
|
|
|
void
|
|
menus_reorder_plugins (void)
|
|
{
|
|
static gchar *rotate_plugins[] = { "90 degrees",
|
|
"180 degrees",
|
|
"270 degrees" };
|
|
static gint n_rotate_plugins = (sizeof (rotate_plugins) /
|
|
sizeof (rotate_plugins[0]));
|
|
|
|
static gchar *image_file_entries[] = { "---moved",
|
|
"Close",
|
|
"Quit" };
|
|
static gint n_image_file_entries = (sizeof (image_file_entries) /
|
|
sizeof (image_file_entries[0]));
|
|
|
|
static gchar *reorder_submenus[] = { "<Image>/Video",
|
|
"<Image>/Script-Fu" };
|
|
static gint n_reorder_submenus = (sizeof (reorder_submenus) /
|
|
sizeof (reorder_submenus[0]));
|
|
|
|
static gchar *reorder_subsubmenus[] = { "<Image>/Filters",
|
|
"<Toolbox>/Xtns" };
|
|
static gint n_reorder_subsubmenus = (sizeof (reorder_subsubmenus) /
|
|
sizeof (reorder_subsubmenus[0]));
|
|
|
|
GtkItemFactory *item_factory;
|
|
GtkWidget *menu_item;
|
|
GtkWidget *menu;
|
|
GList *list;
|
|
gchar *path;
|
|
gint i, pos;
|
|
|
|
/* Move all menu items under "<Toolbox>/Xtns" which are not submenus or
|
|
* separators to the top of the menu
|
|
*/
|
|
pos = 1;
|
|
menu_item = gtk_item_factory_get_widget (toolbox_factory,
|
|
"/Xtns/Module Browser...");
|
|
if (menu_item && menu_item->parent && GTK_IS_MENU (menu_item->parent))
|
|
{
|
|
menu = menu_item->parent;
|
|
|
|
for (list = g_list_nth (GTK_MENU_SHELL (menu)->children, pos); list;
|
|
list = g_list_next (list))
|
|
{
|
|
menu_item = GTK_WIDGET (list->data);
|
|
|
|
if (! GTK_MENU_ITEM (menu_item)->submenu &&
|
|
GTK_IS_LABEL (GTK_BIN (menu_item)->child))
|
|
{
|
|
gtk_menu_reorder_child (GTK_MENU (menu_item->parent),
|
|
menu_item, pos);
|
|
list = g_list_nth (GTK_MENU_SHELL (menu)->children, pos);
|
|
pos++;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Move all menu items under "<Image>/Filters" which are not submenus or
|
|
* separators to the top of the menu
|
|
*/
|
|
pos = 3;
|
|
menu_item = gtk_item_factory_get_widget (image_factory,
|
|
"/Filters/Filter all Layers...");
|
|
if (menu_item && menu_item->parent && GTK_IS_MENU (menu_item->parent))
|
|
{
|
|
menu = menu_item->parent;
|
|
|
|
for (list = g_list_nth (GTK_MENU_SHELL (menu)->children, pos); list;
|
|
list = g_list_next (list))
|
|
{
|
|
menu_item = GTK_WIDGET (list->data);
|
|
|
|
if (! GTK_MENU_ITEM (menu_item)->submenu &&
|
|
GTK_IS_LABEL (GTK_BIN (menu_item)->child))
|
|
{
|
|
gtk_menu_reorder_child (GTK_MENU (menu_item->parent),
|
|
menu_item, pos);
|
|
list = g_list_nth (GTK_MENU_SHELL (menu)->children, pos);
|
|
pos++;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Reorder Rotate plugin menu entries */
|
|
pos = 2;
|
|
for (i = 0; i < n_rotate_plugins; i++)
|
|
{
|
|
path = g_strconcat ("/Image/Transforms/Rotate/", rotate_plugins[i], NULL);
|
|
menu_item = gtk_item_factory_get_widget (image_factory, path);
|
|
g_free (path);
|
|
|
|
if (menu_item && menu_item->parent)
|
|
{
|
|
gtk_menu_reorder_child (GTK_MENU (menu_item->parent), menu_item, pos);
|
|
pos++;
|
|
}
|
|
}
|
|
|
|
pos = 2;
|
|
for (i = 0; i < n_rotate_plugins; i++)
|
|
{
|
|
path = g_strconcat ("/Layers/Rotate/", rotate_plugins[i], NULL);
|
|
menu_item = gtk_item_factory_get_widget (image_factory, path);
|
|
g_free (path);
|
|
|
|
if (menu_item && menu_item->parent)
|
|
{
|
|
gtk_menu_reorder_child (GTK_MENU (menu_item->parent), menu_item, pos);
|
|
pos++;
|
|
}
|
|
}
|
|
|
|
/* Reorder "<Image>/File" */
|
|
for (i = 0; i < n_image_file_entries; i++)
|
|
{
|
|
path = g_strconcat ("/File/", image_file_entries[i], NULL);
|
|
menu_item = gtk_item_factory_get_widget (image_factory, path);
|
|
g_free (path);
|
|
|
|
if (menu_item && menu_item->parent)
|
|
gtk_menu_reorder_child (GTK_MENU (menu_item->parent), menu_item, -1);
|
|
}
|
|
|
|
/* Reorder menus where plugins registered submenus */
|
|
for (i = 0; i < n_reorder_submenus; i++)
|
|
{
|
|
item_factory = gtk_item_factory_from_path (reorder_submenus[i]);
|
|
menu = gtk_item_factory_get_widget (item_factory,
|
|
reorder_submenus[i]);
|
|
|
|
if (menu && GTK_IS_MENU (menu))
|
|
{
|
|
menus_filters_subdirs_to_top (GTK_MENU (menu));
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < n_reorder_subsubmenus; i++)
|
|
{
|
|
item_factory = gtk_item_factory_from_path (reorder_subsubmenus[i]);
|
|
menu = gtk_item_factory_get_widget (item_factory,
|
|
reorder_subsubmenus[i]);
|
|
|
|
if (menu && GTK_IS_MENU (menu))
|
|
{
|
|
for (list = GTK_MENU_SHELL (menu)->children; list;
|
|
list = g_list_next (list))
|
|
{
|
|
GtkMenuItem *menu_item;
|
|
|
|
menu_item = GTK_MENU_ITEM (list->data);
|
|
|
|
if (menu_item->submenu)
|
|
menus_filters_subdirs_to_top (GTK_MENU (menu_item->submenu));
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Move all submenus which registered after "<Image>/Filters/Toys"
|
|
* before the separator after "<Image>/Filters/Web"
|
|
*/
|
|
menu_item = gtk_item_factory_get_widget (image_factory,
|
|
"/Filters/---INSERT");
|
|
|
|
if (menu_item && menu_item->parent && GTK_IS_MENU (menu_item->parent))
|
|
{
|
|
menu = menu_item->parent;
|
|
pos = g_list_index (GTK_MENU_SHELL (menu)->children, menu_item);
|
|
|
|
menu_item = gtk_item_factory_get_widget (image_factory,
|
|
"/Filters/Toys");
|
|
|
|
if (menu_item && GTK_IS_MENU (menu_item))
|
|
{
|
|
GList *list;
|
|
gint index = 1;
|
|
|
|
for (list = GTK_MENU_SHELL (menu)->children; list;
|
|
list = g_list_next (list))
|
|
{
|
|
if (GTK_MENU_ITEM (list->data)->submenu == menu_item)
|
|
break;
|
|
|
|
index++;
|
|
}
|
|
|
|
while ((menu_item = g_list_nth_data (GTK_MENU_SHELL (menu)->children,
|
|
index)))
|
|
{
|
|
gtk_menu_reorder_child (GTK_MENU (menu), menu_item, pos);
|
|
|
|
pos++;
|
|
index++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
menus_tools_create (ToolInfo *tool_info)
|
|
{
|
|
GimpItemFactoryEntry entry;
|
|
|
|
if (tool_info->menu_path == NULL)
|
|
return;
|
|
|
|
entry.entry.path = tool_info->menu_path;
|
|
entry.entry.accelerator = tool_info->menu_accel;
|
|
entry.entry.callback = tools_select_cmd_callback;
|
|
entry.entry.callback_action = tool_info->tool_id;
|
|
entry.entry.item_type = NULL;
|
|
entry.help_page = tool_info->private_tip;
|
|
entry.description = NULL;
|
|
|
|
menus_create_item (image_factory, &entry, (gpointer) tool_info, 2);
|
|
}
|
|
|
|
void
|
|
menus_set_sensitive (gchar *path,
|
|
gboolean sensitive)
|
|
{
|
|
GtkItemFactory *ifactory;
|
|
GtkWidget *widget = NULL;
|
|
|
|
if (initialize)
|
|
menus_init ();
|
|
|
|
ifactory = gtk_item_factory_from_path (path);
|
|
|
|
if (ifactory)
|
|
{
|
|
widget = gtk_item_factory_get_widget (ifactory, path);
|
|
|
|
if (widget)
|
|
gtk_widget_set_sensitive (widget, sensitive);
|
|
}
|
|
|
|
if (!ifactory || !widget)
|
|
g_warning ("Unable to set sensitivity for menu which doesn't exist:\n%s",
|
|
path);
|
|
}
|
|
|
|
void
|
|
menus_set_state (gchar *path,
|
|
gboolean state)
|
|
{
|
|
GtkItemFactory *ifactory;
|
|
GtkWidget *widget = NULL;
|
|
|
|
if (initialize)
|
|
menus_init ();
|
|
|
|
ifactory = gtk_item_factory_from_path (path);
|
|
|
|
if (ifactory)
|
|
{
|
|
widget = gtk_item_factory_get_widget (ifactory, path);
|
|
|
|
if (widget && GTK_IS_CHECK_MENU_ITEM (widget))
|
|
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (widget), state);
|
|
else
|
|
widget = NULL;
|
|
}
|
|
|
|
if (!ifactory || !widget)
|
|
g_warning ("Unable to set state for menu which doesn't exist:\n%s\n",
|
|
path);
|
|
}
|
|
|
|
void
|
|
menus_destroy (gchar *path)
|
|
{
|
|
if (initialize)
|
|
menus_init ();
|
|
|
|
gtk_item_factories_path_delete (NULL, path);
|
|
}
|
|
|
|
void
|
|
menus_quit (void)
|
|
{
|
|
gchar *filename;
|
|
|
|
filename = gimp_personal_rc_file ("menurc");
|
|
gtk_item_factory_dump_rc (filename, NULL, TRUE);
|
|
g_free (filename);
|
|
|
|
if (!initialize)
|
|
{
|
|
gtk_object_unref (GTK_OBJECT (toolbox_factory));
|
|
gtk_object_unref (GTK_OBJECT (image_factory));
|
|
gtk_object_unref (GTK_OBJECT (load_factory));
|
|
gtk_object_unref (GTK_OBJECT (save_factory));
|
|
gtk_object_unref (GTK_OBJECT (layers_factory));
|
|
gtk_object_unref (GTK_OBJECT (channels_factory));
|
|
gtk_object_unref (GTK_OBJECT (paths_factory));
|
|
}
|
|
}
|
|
|
|
static void
|
|
menus_last_opened_cmd_callback (GtkWidget *widget,
|
|
gpointer callback_data,
|
|
guint num)
|
|
{
|
|
gchar *filename, *raw_filename;
|
|
guint num_entries;
|
|
gint status;
|
|
|
|
num_entries = g_slist_length (last_opened_raw_filenames);
|
|
if (num >= num_entries)
|
|
return;
|
|
|
|
raw_filename =
|
|
((GString *) g_slist_nth_data (last_opened_raw_filenames, num))->str;
|
|
filename = g_basename (raw_filename);
|
|
|
|
status = file_open (raw_filename, raw_filename);
|
|
|
|
if (status != PDB_SUCCESS &&
|
|
status != PDB_CANCEL)
|
|
{
|
|
g_message (_("Error opening file: %s\n"), raw_filename);
|
|
}
|
|
}
|
|
|
|
static void
|
|
menus_last_opened_update_labels (void)
|
|
{
|
|
GSList *filename_slist;
|
|
GString *entry_filename;
|
|
GString *path;
|
|
GtkWidget *widget;
|
|
gint i;
|
|
guint num_entries;
|
|
|
|
entry_filename = g_string_new ("");
|
|
path = g_string_new ("");
|
|
|
|
filename_slist = last_opened_raw_filenames;
|
|
num_entries = g_slist_length (last_opened_raw_filenames);
|
|
|
|
for (i = 1; i <= num_entries; i++)
|
|
{
|
|
g_string_sprintf (entry_filename, "%d. %s", i,
|
|
g_basename (((GString *) filename_slist->data)->str));
|
|
|
|
g_string_sprintf (path, "/File/MRU%02d", i);
|
|
|
|
widget = gtk_item_factory_get_widget (toolbox_factory, path->str);
|
|
if (widget)
|
|
{
|
|
gtk_widget_show (widget);
|
|
|
|
gtk_label_set_text (GTK_LABEL (GTK_BIN (widget)->child),
|
|
entry_filename->str);
|
|
gimp_help_set_help_data (widget,
|
|
((GString *) filename_slist->data)->str, NULL);
|
|
}
|
|
filename_slist = filename_slist->next;
|
|
}
|
|
|
|
g_string_free (entry_filename, TRUE);
|
|
g_string_free (path, TRUE);
|
|
}
|
|
|
|
void
|
|
menus_last_opened_add (gchar *filename)
|
|
{
|
|
GString *raw_filename;
|
|
GSList *list;
|
|
GtkWidget *menu_item;
|
|
guint num_entries;
|
|
|
|
/* do nothing if we've already got the filename on the list */
|
|
for (list = last_opened_raw_filenames; list; list = g_slist_next (list))
|
|
{
|
|
raw_filename = list->data;
|
|
|
|
if (strcmp (raw_filename->str, filename) == 0)
|
|
{
|
|
/* the following lines would move the entry to the top
|
|
*
|
|
* last_opened_raw_filenames = g_slist_remove_link (last_opened_raw_filenames, list);
|
|
* last_opened_raw_filenames = g_slist_concat (list, last_opened_raw_filenames);
|
|
* menus_last_opened_update_labels ();
|
|
*/
|
|
return;
|
|
}
|
|
}
|
|
|
|
num_entries = g_slist_length (last_opened_raw_filenames);
|
|
|
|
if (num_entries == last_opened_size)
|
|
{
|
|
list = g_slist_last (last_opened_raw_filenames);
|
|
if (list)
|
|
{
|
|
g_string_free ((GString *)list->data, TRUE);
|
|
last_opened_raw_filenames =
|
|
g_slist_remove (last_opened_raw_filenames, list);
|
|
}
|
|
}
|
|
|
|
raw_filename = g_string_new (filename);
|
|
last_opened_raw_filenames = g_slist_prepend (last_opened_raw_filenames,
|
|
raw_filename);
|
|
|
|
if (num_entries == 0)
|
|
{
|
|
menu_item = gtk_item_factory_get_widget (toolbox_factory,
|
|
"/File/---MRU");
|
|
gtk_widget_show (menu_item);
|
|
}
|
|
|
|
menus_last_opened_update_labels ();
|
|
}
|
|
|
|
static void
|
|
menus_init_mru (void)
|
|
{
|
|
GimpItemFactoryEntry *last_opened_entries;
|
|
GtkWidget *menu_item;
|
|
gchar *paths;
|
|
gchar *accelerators;
|
|
gint i;
|
|
|
|
last_opened_entries = g_new (GimpItemFactoryEntry, last_opened_size);
|
|
|
|
paths = g_new (gchar, last_opened_size * MRU_MENU_ENTRY_SIZE);
|
|
accelerators = g_new (gchar, 9 * MRU_MENU_ACCEL_SIZE);
|
|
|
|
for (i = 0; i < last_opened_size; i++)
|
|
{
|
|
gchar *path, *accelerator;
|
|
|
|
path = &paths[i * MRU_MENU_ENTRY_SIZE];
|
|
if (i < 9)
|
|
accelerator = &accelerators[i * MRU_MENU_ACCEL_SIZE];
|
|
else
|
|
accelerator = NULL;
|
|
|
|
last_opened_entries[i].entry.path = path;
|
|
last_opened_entries[i].entry.accelerator = accelerator;
|
|
last_opened_entries[i].entry.callback =
|
|
(GtkItemFactoryCallback) menus_last_opened_cmd_callback;
|
|
last_opened_entries[i].entry.callback_action = i;
|
|
last_opened_entries[i].entry.item_type = NULL;
|
|
last_opened_entries[i].help_page = "file/last_opened.html";
|
|
last_opened_entries[i].description = NULL;
|
|
|
|
g_snprintf (path, MRU_MENU_ENTRY_SIZE, "/File/MRU%02d", i + 1);
|
|
if (accelerator != NULL)
|
|
g_snprintf (accelerator, MRU_MENU_ACCEL_SIZE, "<control>%d", i + 1);
|
|
}
|
|
|
|
menus_create_items (toolbox_factory, last_opened_size,
|
|
last_opened_entries, NULL, 2);
|
|
|
|
for (i=0; i < last_opened_size; i++)
|
|
{
|
|
menu_item =
|
|
gtk_item_factory_get_widget (toolbox_factory,
|
|
last_opened_entries[i].entry.path);
|
|
gtk_widget_hide (menu_item);
|
|
}
|
|
|
|
menu_item = gtk_item_factory_get_widget (toolbox_factory, "/File/---MRU");
|
|
if (menu_item && menu_item->parent)
|
|
gtk_menu_reorder_child (GTK_MENU (menu_item->parent), menu_item, -1);
|
|
gtk_widget_hide (menu_item);
|
|
|
|
menu_item = gtk_item_factory_get_widget (toolbox_factory, "/File/Quit");
|
|
if (menu_item && menu_item->parent)
|
|
gtk_menu_reorder_child (GTK_MENU (menu_item->parent), menu_item, -1);
|
|
|
|
g_free (paths);
|
|
g_free (accelerators);
|
|
g_free (last_opened_entries);
|
|
}
|
|
|
|
/* This function gets called while browsing a menu created
|
|
* by a GtkItemFactory
|
|
*/
|
|
static gint
|
|
menus_item_key_press (GtkWidget *widget,
|
|
GdkEventKey *kevent,
|
|
gpointer data)
|
|
{
|
|
GtkItemFactory *item_factory = NULL;
|
|
GtkWidget *active_menu_item = NULL;
|
|
gchar *factory_path = NULL;
|
|
gchar *help_path = NULL;
|
|
gchar *help_page = NULL;
|
|
|
|
item_factory = (GtkItemFactory *) data;
|
|
active_menu_item = GTK_MENU_SHELL (widget)->active_menu_item;
|
|
|
|
/* first, check if the user tries to assign a shortcut to the help
|
|
* menu items and ignore it...
|
|
*/
|
|
if (active_menu_item)
|
|
{
|
|
help_page = (gchar *) gtk_object_get_data (GTK_OBJECT (active_menu_item),
|
|
"help_page");
|
|
|
|
if (help_page &&
|
|
*help_page &&
|
|
item_factory == toolbox_factory &&
|
|
(strcmp (help_page, "help/dialogs/help.html") == 0 ||
|
|
strcmp (help_page, "help/context_help.html") == 0))
|
|
{
|
|
gtk_signal_emit_stop_by_name (GTK_OBJECT (widget),
|
|
"key_press_event");
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
/* ...otherwise, for any key except F1, continue with the standard
|
|
* GtkItemFactory callback and assign a new shortcut...
|
|
*/
|
|
if (kevent->keyval != GDK_F1)
|
|
return FALSE;
|
|
|
|
/* ...finally, if F1 was pressed over any menu, show it's help page...
|
|
*/
|
|
gtk_signal_emit_stop_by_name (GTK_OBJECT (widget), "key_press_event");
|
|
|
|
factory_path = (gchar *) gtk_object_get_data (GTK_OBJECT (item_factory),
|
|
"factory_path");
|
|
|
|
if (! help_page ||
|
|
! *help_page)
|
|
help_page = "index.html";
|
|
|
|
if (factory_path && help_page)
|
|
{
|
|
gchar *help_string;
|
|
gchar *at;
|
|
|
|
help_page = g_strdup (help_page);
|
|
|
|
at = strchr (help_page, '@'); /* HACK: locale subdir */
|
|
|
|
if (at)
|
|
{
|
|
*at = '\0';
|
|
help_path = g_strdup (help_page);
|
|
help_string = g_strdup (at + 1);
|
|
}
|
|
else
|
|
{
|
|
help_string = g_strdup_printf ("%s/%s", factory_path, help_page);
|
|
}
|
|
|
|
gimp_help (help_path, help_string);
|
|
|
|
g_free (help_string);
|
|
g_free (help_page);
|
|
}
|
|
else
|
|
{
|
|
gimp_standard_help_func (NULL);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/* set up the callback to catch the "F1" key */
|
|
static void
|
|
menus_item_realize (GtkWidget *widget,
|
|
gpointer data)
|
|
{
|
|
if (GTK_IS_MENU_SHELL (widget->parent))
|
|
{
|
|
if (! gtk_object_get_data (GTK_OBJECT (widget->parent),
|
|
"menus_key_press_connected"))
|
|
{
|
|
gtk_signal_connect (GTK_OBJECT (widget->parent), "key_press_event",
|
|
GTK_SIGNAL_FUNC (menus_item_key_press),
|
|
(gpointer) data);
|
|
|
|
gtk_object_set_data (GTK_OBJECT (widget->parent),
|
|
"menus_key_press_connected",
|
|
(gpointer) TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
menus_create_item (GtkItemFactory *item_factory,
|
|
GimpItemFactoryEntry *entry,
|
|
gpointer callback_data,
|
|
guint callback_type)
|
|
{
|
|
GtkWidget *menu_item;
|
|
|
|
if (!(strstr (entry->entry.path, "tearoff1")))
|
|
menus_create_branches (item_factory, entry);
|
|
|
|
gtk_item_factory_create_item (item_factory,
|
|
(GtkItemFactoryEntry *) entry,
|
|
callback_data,
|
|
callback_type);
|
|
|
|
menu_item = gtk_item_factory_get_item (item_factory,
|
|
((GtkItemFactoryEntry *) entry)->path);
|
|
|
|
if (menu_item)
|
|
{
|
|
gtk_signal_connect_after (GTK_OBJECT (menu_item), "realize",
|
|
GTK_SIGNAL_FUNC (menus_item_realize),
|
|
(gpointer) item_factory);
|
|
|
|
gtk_object_set_data (GTK_OBJECT (menu_item), "help_page",
|
|
(gpointer) entry->help_page);
|
|
}
|
|
}
|
|
|
|
static void
|
|
menus_create_items (GtkItemFactory *item_factory,
|
|
guint n_entries,
|
|
GimpItemFactoryEntry *entries,
|
|
gpointer callback_data,
|
|
guint callback_type)
|
|
{
|
|
gint i;
|
|
|
|
for (i = 0; i < n_entries; i++)
|
|
{
|
|
menus_create_item (item_factory,
|
|
entries + i,
|
|
callback_data,
|
|
callback_type);
|
|
}
|
|
}
|
|
|
|
static void
|
|
menus_init (void)
|
|
{
|
|
GtkWidget *menu_item;
|
|
gchar *filename;
|
|
gint i;
|
|
|
|
if (! initialize)
|
|
return;
|
|
|
|
initialize = FALSE;
|
|
|
|
toolbox_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<Toolbox>",
|
|
NULL);
|
|
gtk_object_set_data (GTK_OBJECT (toolbox_factory), "factory_path",
|
|
(gpointer) "toolbox");
|
|
gtk_item_factory_set_translate_func (toolbox_factory, menu_translate,
|
|
"<Toolbox>", NULL);
|
|
menus_create_items (toolbox_factory,
|
|
n_toolbox_entries,
|
|
toolbox_entries,
|
|
NULL, 2);
|
|
|
|
menus_init_mru ();
|
|
|
|
image_factory = gtk_item_factory_new (GTK_TYPE_MENU, "<Image>", NULL);
|
|
gtk_object_set_data (GTK_OBJECT (image_factory), "factory_path",
|
|
(gpointer) "image");
|
|
gtk_item_factory_set_translate_func (image_factory, menu_translate,
|
|
"<Image>", NULL);
|
|
menus_create_items (image_factory,
|
|
n_image_entries,
|
|
image_entries,
|
|
NULL, 2);
|
|
|
|
load_factory = gtk_item_factory_new (GTK_TYPE_MENU, "<Load>", NULL);
|
|
gtk_object_set_data (GTK_OBJECT (load_factory), "factory_path",
|
|
(gpointer) "open");
|
|
gtk_item_factory_set_translate_func (load_factory, menu_translate,
|
|
"<Load>", NULL);
|
|
menus_create_items (load_factory,
|
|
n_load_entries,
|
|
load_entries,
|
|
NULL, 2);
|
|
|
|
save_factory = gtk_item_factory_new (GTK_TYPE_MENU, "<Save>", NULL);
|
|
gtk_object_set_data (GTK_OBJECT (save_factory), "factory_path",
|
|
(gpointer) "save");
|
|
gtk_item_factory_set_translate_func (save_factory, menu_translate,
|
|
"<Save>", NULL);
|
|
menus_create_items (save_factory,
|
|
n_save_entries,
|
|
save_entries,
|
|
NULL, 2);
|
|
|
|
layers_factory = gtk_item_factory_new (GTK_TYPE_MENU, "<Layers>", NULL);
|
|
gtk_object_set_data (GTK_OBJECT (layers_factory), "factory_path",
|
|
(gpointer) "layers");
|
|
gtk_item_factory_set_translate_func (layers_factory, menu_translate,
|
|
"<Layers>", NULL);
|
|
menus_create_items (layers_factory,
|
|
n_layers_entries,
|
|
layers_entries,
|
|
NULL, 2);
|
|
|
|
channels_factory = gtk_item_factory_new (GTK_TYPE_MENU, "<Channels>", NULL);
|
|
gtk_object_set_data (GTK_OBJECT (channels_factory), "factory_path",
|
|
(gpointer) "channels");
|
|
gtk_item_factory_set_translate_func (channels_factory, menu_translate,
|
|
"<Channels>", NULL);
|
|
menus_create_items (channels_factory,
|
|
n_channels_entries,
|
|
channels_entries,
|
|
NULL, 2);
|
|
|
|
paths_factory = gtk_item_factory_new (GTK_TYPE_MENU, "<Paths>", NULL);
|
|
gtk_object_set_data (GTK_OBJECT (paths_factory), "factory_path",
|
|
(gpointer) "paths");
|
|
gtk_item_factory_set_translate_func (paths_factory, menu_translate,
|
|
"<Paths>", NULL);
|
|
menus_create_items (paths_factory,
|
|
n_paths_entries,
|
|
paths_entries,
|
|
NULL, 2);
|
|
|
|
for (i = 0; i < num_tools; i++)
|
|
{
|
|
menus_tools_create (&tool_info[i]);
|
|
}
|
|
|
|
/* reorder <Image>/Image/Colors */
|
|
menu_item = gtk_item_factory_get_widget (image_factory,
|
|
tool_info[POSTERIZE].menu_path);
|
|
if (menu_item && menu_item->parent)
|
|
gtk_menu_reorder_child (GTK_MENU (menu_item->parent), menu_item, 3);
|
|
|
|
{
|
|
static ToolType color_tools[] = { COLOR_BALANCE,
|
|
HUE_SATURATION,
|
|
BRIGHTNESS_CONTRAST,
|
|
THRESHOLD,
|
|
LEVELS,
|
|
CURVES };
|
|
static gint n_color_tools = (sizeof (color_tools) /
|
|
sizeof (color_tools[0]));
|
|
GtkWidget *separator;
|
|
gint i, pos;
|
|
|
|
pos = 1;
|
|
|
|
for (i = 0; i < n_color_tools; i++)
|
|
{
|
|
menu_item =
|
|
gtk_item_factory_get_widget (image_factory,
|
|
tool_info[color_tools[i]].menu_path);
|
|
if (menu_item && menu_item->parent)
|
|
{
|
|
gtk_menu_reorder_child (GTK_MENU (menu_item->parent),
|
|
menu_item, pos);
|
|
pos++;
|
|
}
|
|
}
|
|
|
|
if (menu_item && menu_item->parent)
|
|
{
|
|
separator = gtk_menu_item_new ();
|
|
gtk_menu_insert (GTK_MENU (menu_item->parent), separator, pos);
|
|
gtk_widget_show (separator);
|
|
}
|
|
}
|
|
|
|
filename = gimp_personal_rc_file ("menurc");
|
|
gtk_item_factory_parse_rc (filename);
|
|
g_free (filename);
|
|
}
|
|
|
|
#ifdef ENABLE_NLS
|
|
|
|
static gchar *
|
|
menu_translate (const gchar *path,
|
|
gpointer data)
|
|
{
|
|
static gchar *menupath = NULL;
|
|
|
|
GtkItemFactory *item_factory = NULL;
|
|
gchar *retval;
|
|
gchar *factory;
|
|
gchar *translation;
|
|
gchar *domain = NULL;
|
|
gchar *complete = NULL;
|
|
gchar *p, *t;
|
|
|
|
factory = (gchar *) data;
|
|
|
|
if (menupath)
|
|
g_free (menupath);
|
|
|
|
retval = menupath = g_strdup (path);
|
|
|
|
if ((strstr (path, "/tearoff1") != NULL) ||
|
|
(strstr (path, "/---") != NULL) ||
|
|
(strstr (path, "/MRU") != NULL))
|
|
return retval;
|
|
|
|
if (factory)
|
|
item_factory = gtk_item_factory_from_path (factory);
|
|
if (item_factory)
|
|
{
|
|
domain = gtk_object_get_data (GTK_OBJECT (item_factory), "textdomain");
|
|
complete = gtk_object_get_data (GTK_OBJECT (item_factory), "complete");
|
|
}
|
|
|
|
if (domain) /* use the plugin textdomain */
|
|
{
|
|
g_free (menupath);
|
|
menupath = g_strconcat (factory, path, NULL);
|
|
|
|
if (complete)
|
|
{
|
|
/*
|
|
* This is a branch, use the complete path for translation,
|
|
* then strip off entries from the end until it matches.
|
|
*/
|
|
complete = g_strconcat (factory, complete, NULL);
|
|
translation = g_strdup (dgettext (domain, complete));
|
|
|
|
while (*complete && *translation && strcmp (complete, menupath))
|
|
{
|
|
p = strrchr (complete, '/');
|
|
t = strrchr (translation, '/');
|
|
if (p && t)
|
|
{
|
|
*p = '\0';
|
|
*t = '\0';
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
|
|
g_free (complete);
|
|
}
|
|
else
|
|
{
|
|
translation = dgettext (domain, menupath);
|
|
}
|
|
|
|
/*
|
|
* Work around a bug in GTK+ prior to 1.2.7 (similar workaround below)
|
|
*/
|
|
if (strncmp (factory, translation, strlen (factory)) == 0)
|
|
{
|
|
retval = translation + strlen (factory);
|
|
if (complete)
|
|
{
|
|
g_free (menupath);
|
|
menupath = translation;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
g_warning ("bad translation for menupath: %s", menupath);
|
|
retval = menupath + strlen (factory);
|
|
if (complete)
|
|
g_free (translation);
|
|
}
|
|
}
|
|
else /* use the gimp textdomain */
|
|
{
|
|
if (complete)
|
|
{
|
|
/*
|
|
* This is a branch, use the complete path for translation,
|
|
* then strip off entries from the end until it matches.
|
|
*/
|
|
complete = g_strdup (complete);
|
|
translation = g_strdup (gettext (complete));
|
|
|
|
while (*complete && *translation && strcmp (complete, menupath))
|
|
{
|
|
p = strrchr (complete, '/');
|
|
t = strrchr (translation, '/');
|
|
if (p && t)
|
|
{
|
|
*p = '\0';
|
|
*t = '\0';
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
g_free (complete);
|
|
}
|
|
else
|
|
translation = gettext (menupath);
|
|
|
|
if (*translation == '/')
|
|
{
|
|
retval = translation;
|
|
if (complete)
|
|
{
|
|
g_free (menupath);
|
|
menupath = translation;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
g_warning ("bad translation for menupath: %s", menupath);
|
|
if (complete)
|
|
g_free (translation);
|
|
}
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
#endif /* ENABLE_NLS */
|
|
|
|
static gint
|
|
tearoff_delete_cb (GtkWidget *widget,
|
|
GdkEvent *event,
|
|
gpointer data)
|
|
{
|
|
/* Unregister if dialog is deleted as well */
|
|
dialog_unregister (widget);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
tearoff_cmd_callback (GtkWidget *widget,
|
|
gpointer callback_data,
|
|
guint callback_action)
|
|
{
|
|
if (GTK_IS_TEAROFF_MENU_ITEM (widget))
|
|
{
|
|
GtkTearoffMenuItem *tomi = (GtkTearoffMenuItem *) widget;
|
|
|
|
if (tomi->torn_off)
|
|
{
|
|
GtkWidget *top = gtk_widget_get_toplevel (widget);
|
|
|
|
/* This should be a window */
|
|
if (!GTK_IS_WINDOW (top))
|
|
{
|
|
g_message ("tearoff menu not in top level window");
|
|
}
|
|
else
|
|
{
|
|
dialog_register (top);
|
|
gtk_signal_connect (GTK_OBJECT (top), "delete_event",
|
|
GTK_SIGNAL_FUNC (tearoff_delete_cb),
|
|
NULL);
|
|
|
|
gtk_object_set_data (GTK_OBJECT (widget), "tearoff_menu_top",
|
|
top);
|
|
|
|
gimp_dialog_set_icon (GTK_WINDOW (top));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
GtkWidget *top;
|
|
|
|
top = (GtkWidget *) gtk_object_get_data (GTK_OBJECT (widget),
|
|
"tearoff_menu_top");
|
|
|
|
if (!top)
|
|
g_message ("can't unregister tearoff menu top level window");
|
|
else
|
|
dialog_unregister (top);
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef ENABLE_DEBUG_ENTRY
|
|
static void
|
|
menus_debug_recurse_menu (GtkWidget *menu,
|
|
gint depth,
|
|
gchar *path)
|
|
{
|
|
GtkItemFactoryItem *item;
|
|
GtkItemFactoryClass *class;
|
|
GtkWidget *menu_item;
|
|
GList *list;
|
|
gchar *label;
|
|
gchar *help_page;
|
|
gchar *full_path;
|
|
gchar *accel;
|
|
gchar *format_str;
|
|
|
|
for (list = GTK_MENU_SHELL (menu)->children; list; list = g_list_next (list))
|
|
{
|
|
menu_item = GTK_WIDGET (list->data);
|
|
|
|
if (GTK_IS_LABEL (GTK_BIN (menu_item)->child))
|
|
{
|
|
gtk_label_get (GTK_LABEL (GTK_BIN (menu_item)->child), &label);
|
|
help_page = (gchar *) gtk_object_get_data (GTK_OBJECT (menu_item),
|
|
"help_page");
|
|
|
|
full_path = g_strconcat (path, "/", label, NULL);
|
|
class = gtk_type_class (GTK_TYPE_ITEM_FACTORY);
|
|
item = g_hash_table_lookup (class->item_ht, full_path);
|
|
if (item)
|
|
accel = gtk_accelerator_name (item->accelerator_key,
|
|
item->accelerator_mods);
|
|
else
|
|
accel = NULL;
|
|
|
|
format_str = g_strdup_printf ("%%%ds%%%ds %%-20s %%s\n",
|
|
depth * 2, depth * 2 - 40);
|
|
g_print (format_str,
|
|
"", label, accel ? accel : "", help_page ? help_page : "");
|
|
g_free (format_str);
|
|
|
|
if (GTK_MENU_ITEM (menu_item)->submenu)
|
|
menus_debug_recurse_menu (GTK_MENU_ITEM (menu_item)->submenu,
|
|
depth + 1, full_path);
|
|
|
|
g_free (full_path);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
menus_debug_cmd_callback (GtkWidget *widget,
|
|
gpointer callback_data,
|
|
guint callback_action)
|
|
{
|
|
gint n_factories = 7;
|
|
GtkItemFactory *factories[7];
|
|
GimpItemFactoryEntry *entries[7];
|
|
|
|
GtkWidget *menu_item;
|
|
gint i;
|
|
|
|
factories[0] = toolbox_factory;
|
|
factories[1] = image_factory;
|
|
factories[2] = layers_factory;
|
|
factories[3] = channels_factory;
|
|
factories[4] = paths_factory;
|
|
factories[5] = load_factory;
|
|
factories[6] = save_factory;
|
|
|
|
entries[0] = toolbox_entries;
|
|
entries[1] = image_entries;
|
|
entries[2] = layers_entries;
|
|
entries[3] = channels_entries;
|
|
entries[4] = paths_entries;
|
|
entries[5] = load_entries;
|
|
entries[6] = save_entries;
|
|
|
|
/* toolbox needs special treatment */
|
|
g_print ("%s\n", factories[0]->path);
|
|
|
|
menu_item = gtk_item_factory_get_item (factories[0], "/File");
|
|
if (menu_item && menu_item->parent && GTK_IS_MENU_BAR (menu_item->parent))
|
|
menus_debug_recurse_menu (menu_item->parent, 1, factories[0]->path);
|
|
|
|
g_print ("\n");
|
|
|
|
for (i = 1; i < n_factories; i++)
|
|
{
|
|
g_print ("%s\n", factories[i]->path);
|
|
|
|
menu_item = gtk_item_factory_get_item (factories[i], entries[i][0].entry.path);
|
|
if (menu_item && menu_item->parent && GTK_IS_MENU (menu_item->parent))
|
|
menus_debug_recurse_menu (menu_item->parent, 1, factories[i]->path);
|
|
|
|
g_print ("\n");
|
|
}
|
|
}
|
|
#endif /* ENABLE_DEBUG_ENTRY */
|