mirror of
https://gitlab.gnome.org/GNOME/gimp
synced 2024-10-23 04:51:44 +00:00
2557c517b1
Thu Aug 12 21:38:53 BST 1999 Andy Thomas <alt@gimp.org> * app/commands.c * app/commands.h * app/disp_callbacks.c * app/gdisplay.c * app/gdisplay.h * app/info_dialog.c * app/info_dialog.h * app/info_window.c * app/info_window.h * app/menus.c * app/scale.c * app/scroll.c * app/scroll.h * app/nav_window.c (new) * app/nav_window.h (new) * pixmap/dropper.xpm (new) New "navigator" image (accessed via <Image>/Window Nav..). This gives an outline of the location of the current view on an image. Eg if your image window is only showing part of an image then the Window Navigation window will outline the area viewed. You can "drag" the outlined square around the viewport and the main image will scroll. Additional a single click outside the square will center the image at that location. Also started to add additional information to a new page inside the Window information dialog (currently only pixel value is shown). Both these features are currently work in progress and unfinished. In particular the Navigator does not keep in step with changes to the basic image (however it does keep in step with image size changes and if you modify the size of the image viewing window). It also does not display the transparent areas of images very nicely.
825 lines
29 KiB
C
825 lines
29 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 <stdlib.h>
|
|
#include <string.h>
|
|
#include "appenv.h"
|
|
#include "channels_dialog.h"
|
|
#include "colormaps.h"
|
|
#include "commands.h"
|
|
#include "fileops.h"
|
|
#include "general.h"
|
|
#include "gimprc.h"
|
|
#include "interface.h"
|
|
#include "layers_dialog.h"
|
|
#include "menus.h"
|
|
#include "paths_dialog.h"
|
|
#include "paint_funcs.h"
|
|
#include "procedural_db.h"
|
|
#include "scale.h"
|
|
#include "tools.h"
|
|
#include "gdisplay.h"
|
|
#include "docindex.h"
|
|
|
|
#include "config.h"
|
|
#include "libgimp/gimpintl.h"
|
|
#include "libgimp/gimpenv.h"
|
|
|
|
#define MRU_MENU_ENTRY_SIZE (strlen (_("/File/MRU00 ")) + 1)
|
|
#define MRU_MENU_ACCEL_SIZE sizeof ("<control>0")
|
|
|
|
static char* G_GNUC_UNUSED dummyMRU = N_("/File/MRU00 ");
|
|
|
|
static void menus_init (void);
|
|
static gchar* menu_translate (const gchar *path,
|
|
gpointer data);
|
|
|
|
static GSList *last_opened_raw_filenames = NULL;
|
|
|
|
static GtkItemFactoryEntry toolbox_entries[] =
|
|
{
|
|
{ N_("/File/tearoff1"), NULL, NULL, 0, "<Tearoff>" },
|
|
{ N_("/File/New"), "<control>N", file_new_cmd_callback, 0 },
|
|
{ N_("/File/Open"), "<control>O", file_open_cmd_callback, 0 },
|
|
{ N_("/File/About..."), NULL, about_dialog_cmd_callback, 0 },
|
|
{ N_("/File/Preferences..."), NULL, file_pref_cmd_callback, 0 },
|
|
{ N_("/File/Tip of the day"), NULL, tips_dialog_cmd_callback, 0 },
|
|
|
|
{ N_("/File/Dialogs/Brushes..."), "<control><shift>B", dialogs_brushes_cmd_callback, 0 },
|
|
{ N_("/File/Dialogs/Patterns..."), "<control><shift>P", dialogs_patterns_cmd_callback, 0 },
|
|
{ N_("/File/Dialogs/Palette..."), "<control>P", dialogs_palette_cmd_callback, 0 },
|
|
{ N_("/File/Dialogs/Gradient..."), "<control>G", dialogs_gradient_editor_cmd_callback, 0 },
|
|
{ N_("/File/Dialogs/Layers & Channels..."), "<control>L", dialogs_lc_cmd_callback, 0 },
|
|
{ N_("/File/Dialogs/Tool Options..."), "<control><shift>T", dialogs_tools_options_cmd_callback, 0 },
|
|
{ N_("/File/Dialogs/Input Devices..."), NULL, dialogs_input_devices_cmd_callback, 0 },
|
|
{ N_("/File/Dialogs/Device Status..."), NULL, dialogs_device_status_cmd_callback, 0 },
|
|
{ N_("/File/Dialogs/Document Index..."), NULL, raise_idea_callback, 0 },
|
|
{ N_("/File/Dialogs/Error Console..."), NULL, dialogs_error_console_cmd_callback, 0 },
|
|
|
|
{ N_("/Xtns/tearoff1"), NULL, NULL, 0, "<Tearoff>" },
|
|
{ N_("/Xtns/Module Browser"), NULL, dialogs_module_browser_cmd_callback, 0 },
|
|
{ N_("/File/---"), NULL, NULL, 0, "<Separator>" },
|
|
{ N_("/File/---"), NULL, NULL, 0, "<Separator>" }
|
|
};
|
|
static guint n_toolbox_entries = sizeof (toolbox_entries) / sizeof (toolbox_entries[0]);
|
|
static GtkItemFactory *toolbox_factory = NULL;
|
|
|
|
static GtkItemFactoryEntry file_menu_separator = { N_("/File/---"), NULL, NULL, 0, "<Separator>" };
|
|
static GtkItemFactoryEntry toolbox_end = { N_("/File/Quit"), "<control>Q", file_quit_cmd_callback, 0 };
|
|
|
|
static GtkItemFactoryEntry image_entries[] =
|
|
{
|
|
{ N_("/tearoff1"), NULL, NULL, 0, "<Tearoff>" },
|
|
{ N_("/File/tearoff1"), NULL, NULL, 0, "<Tearoff>" },
|
|
{ N_("/File/New"), "<control>N", file_new_cmd_callback, 1 },
|
|
{ N_("/File/Open"), "<control>O", file_open_cmd_callback, 0 },
|
|
{ N_("/File/Save"), "<control>S", file_save_cmd_callback, 0 },
|
|
{ N_("/File/Save as"), NULL, file_save_as_cmd_callback, 0 },
|
|
{ N_("/File/Revert"), NULL, file_revert_cmd_callback, 0 },
|
|
{ N_("/File/Preferences..."), NULL, file_pref_cmd_callback, 0 },
|
|
{ N_("/File/---"), NULL, NULL, 0, "<Separator>" },
|
|
|
|
{ N_("/File/Close"), "<control>W", file_close_cmd_callback, 0 },
|
|
{ N_("/File/Quit"), "<control>Q", file_quit_cmd_callback, 0 },
|
|
{ N_("/File/---moved"), NULL, NULL, 0, "<Separator>" },
|
|
|
|
{ N_("/Edit/tearoff1"), NULL, NULL, 0, "<Tearoff>" },
|
|
{ N_("/Edit/Cut"), "<control>X", edit_cut_cmd_callback, 0 },
|
|
{ N_("/Edit/Copy"), "<control>C", edit_copy_cmd_callback, 0 },
|
|
{ N_("/Edit/Paste"), "<control>V", edit_paste_cmd_callback, 0 },
|
|
{ N_("/Edit/Paste Into"), NULL, edit_paste_into_cmd_callback, 0 },
|
|
{ N_("/Edit/Paste As New"), NULL, edit_paste_as_new_cmd_callback, 0 },
|
|
{ N_("/Edit/---"), NULL, NULL, 0, "<Separator>" },
|
|
{ N_("/Edit/Clear"), "<control>K", edit_clear_cmd_callback, 0 },
|
|
{ N_("/Edit/Fill"), "<control>period", edit_fill_cmd_callback, 0 },
|
|
{ N_("/Edit/Stroke"), NULL, edit_stroke_cmd_callback, 0 },
|
|
{ N_("/Edit/Undo"), "<control>Z", edit_undo_cmd_callback, 0 },
|
|
{ N_("/Edit/Redo"), "<control>R", edit_redo_cmd_callback, 0 },
|
|
{ N_("/Edit/---"), NULL, NULL, 0, "<Separator>" },
|
|
{ N_("/Edit/Cut Named"), "<control><shift>X", edit_named_cut_cmd_callback, 0 },
|
|
{ N_("/Edit/Copy Named"), "<control><shift>C", edit_named_copy_cmd_callback, 0 },
|
|
{ N_("/Edit/Paste Named"), "<control><shift>V", edit_named_paste_cmd_callback, 0 },
|
|
{ N_("/Edit/---"), NULL, NULL, 0, "<Separator>" },
|
|
|
|
{ N_("/Select/tearoff1"), NULL, NULL, 0, "<Tearoff>" },
|
|
{ N_("/Select/Invert"), "<control>I", select_invert_cmd_callback, 0 },
|
|
{ N_("/Select/All"), "<control>A", select_all_cmd_callback, 0 },
|
|
{ N_("/Select/None"), "<control><shift>A", select_none_cmd_callback, 0 },
|
|
{ N_("/Select/Float"), "<control><shift>L", select_float_cmd_callback, 0 },
|
|
{ N_("/Select/---"), NULL, NULL, 0, "<Separator>" },
|
|
{ N_("/Select/Feather"), "<control><shift>F", select_feather_cmd_callback, 0 },
|
|
{ N_("/Select/Sharpen"), "<control><shift>H", select_sharpen_cmd_callback, 0 },
|
|
{ N_("/Select/Shrink"), NULL, select_shrink_cmd_callback, 0 },
|
|
{ N_("/Select/Grow"), NULL, select_grow_cmd_callback, 0 },
|
|
{ N_("/Select/Border"), "<control><shift>B", select_border_cmd_callback, 0 },
|
|
{ N_("/Select/---"), NULL, NULL, 0, "<Separator>" },
|
|
{ N_("/Select/Save To Channel"), NULL, select_save_cmd_callback, 0 },
|
|
|
|
{ N_("/View/tearoff1"), NULL, NULL, 0, "<Tearoff>" },
|
|
{ N_("/View/Zoom In"), "equal", view_zoomin_cmd_callback, 0 },
|
|
{ N_("/View/Zoom Out"), "minus", view_zoomout_cmd_callback, 0 },
|
|
{ N_("/View/Zoom/16:1"), NULL, view_zoom_16_1_callback, 0 },
|
|
{ N_("/View/Zoom/8:1"), NULL, view_zoom_8_1_callback, 0 },
|
|
{ N_("/View/Zoom/4:1"), NULL, view_zoom_4_1_callback, 0 },
|
|
{ N_("/View/Zoom/2:1"), NULL, view_zoom_2_1_callback, 0 },
|
|
{ N_("/View/Zoom/1:1"), "1", view_zoom_1_1_callback, 0 },
|
|
{ N_("/View/Zoom/1:2"), NULL, view_zoom_1_2_callback, 0 },
|
|
{ N_("/View/Zoom/1:4"), NULL, view_zoom_1_4_callback, 0 },
|
|
{ N_("/View/Zoom/1:8"), NULL, view_zoom_1_8_callback, 0 },
|
|
{ N_("/View/Zoom/1:16"), NULL, view_zoom_1_16_callback, 0 },
|
|
{ N_("/View/Dot for dot"), NULL, view_dot_for_dot_callback, 0, "<ToggleItem>"},
|
|
{ N_("/View/Window Info..."), "<control><shift>I", view_window_info_cmd_callback, 0 },
|
|
{ N_("/View/Window Nav..."), NULL, view_window_nav_cmd_callback, 0 },
|
|
|
|
{ N_("/View/---"), NULL, NULL, 0, "<Separator>" },
|
|
{ N_("/View/Toggle Selection"), "<control>T", view_toggle_selection_cmd_callback, 0, "<ToggleItem>" },
|
|
{ N_("/View/Toggle Rulers"), "<control><shift>R", view_toggle_rulers_cmd_callback, 0, "<ToggleItem>" },
|
|
{ N_("/View/Toggle Statusbar"), "<control><shift>S", view_toggle_statusbar_cmd_callback, 0, "<ToggleItem>" },
|
|
{ N_("/View/Toggle Guides"), "<control><shift>T", view_toggle_guides_cmd_callback, 0, "<ToggleItem>" },
|
|
{ N_("/View/Snap To Guides"), NULL, view_snap_to_guides_cmd_callback, 0, "<ToggleItem>" },
|
|
{ N_("/View/---"), NULL, NULL, 0, "<Separator>" },
|
|
|
|
{ N_("/View/New View"), NULL, view_new_view_cmd_callback, 0 },
|
|
{ N_("/View/Shrink Wrap"), "<control>E", view_shrink_wrap_cmd_callback, 0 },
|
|
|
|
{ N_("/Image/tearoff1"), NULL, NULL, 0, "<Tearoff>" },
|
|
{ N_("/Image/Colors/tearoff1"), NULL, NULL, 0, "<Tearoff>" },
|
|
{ N_("/Image/Colors/Equalize"), NULL, image_equalize_cmd_callback, 0 },
|
|
{ N_("/Image/Colors/Invert"), NULL, image_invert_cmd_callback, 0 },
|
|
{ N_("/Image/Colors/---"), NULL, NULL, 0, "<Separator>" },
|
|
{ N_("/Image/Colors/Desaturate"), NULL, image_desaturate_cmd_callback, 0 },
|
|
{ N_("/Image/Channel Ops/tearoff1"), NULL, NULL, 0, "<Tearoff>" },
|
|
{ N_("/Image/Channel Ops/Duplicate"), "<control>D", channel_ops_duplicate_cmd_callback, 0 },
|
|
{ N_("/Image/Channel Ops/Offset"), "<control><shift>O", channel_ops_offset_cmd_callback, 0 },
|
|
{ N_("/Image/Alpha/tearoff1"), NULL, NULL, 0, "<Tearoff>" },
|
|
{ N_("/Image/Alpha/Add Alpha Channel"), NULL, layers_add_alpha_channel_cmd_callback, 0 },
|
|
|
|
{ N_("/Image/---"), NULL, NULL, 0, "<Separator>" },
|
|
{ N_("/Image/RGB"), NULL, image_convert_rgb_cmd_callback, 0 },
|
|
{ N_("/Image/Grayscale"), NULL, image_convert_grayscale_cmd_callback, 0 },
|
|
{ N_("/Image/Indexed"), NULL, image_convert_indexed_cmd_callback, 0 },
|
|
{ N_("/Image/---"), NULL, NULL, 0, "<Separator>" },
|
|
{ N_("/Image/Resize"), NULL, image_resize_cmd_callback, 0 },
|
|
{ N_("/Image/Scale"), NULL, image_scale_cmd_callback, 0 },
|
|
{ N_("/Image/---"), NULL, NULL, 0, "<Separator>" },
|
|
|
|
{ N_("/Layers/tearoff1"), NULL, NULL, 0, "<Tearoff>" },
|
|
{ N_("/Layers/Layers & Channels..."), "<control>L", dialogs_lc_cmd_callback, 0 },
|
|
{ N_("/Layers/Stack/tearoff1"), NULL, NULL, 0, "<Tearoff>" },
|
|
{ N_("/Layers/Stack/Previous Layer"), "Prior", layers_previous_cmd_callback, 0 },
|
|
{ N_("/Layers/Stack/Next Layer"), "Next", layers_next_cmd_callback, 0 },
|
|
{ N_("/Layers/Stack/Raise Layer"), "<shift>Prior", layers_raise_cmd_callback, 0 },
|
|
{ N_("/Layers/Stack/Lower Layer"), "<shift>Next", layers_lower_cmd_callback, 0 },
|
|
{ N_("/Layers/Stack/Layer to Top"), "<control>Prior", layers_raise_to_top_cmd_callback, 0 },
|
|
{ N_("/Layers/Stack/Layer to Bottom"), "<control>Next", layers_lower_to_bottom_cmd_callback, 0 },
|
|
{ N_("/Layers/---"), NULL, NULL, 0, "<Separator>" },
|
|
{ N_("/Layers/Anchor Layer"), "<control>H", layers_anchor_cmd_callback, 0 },
|
|
{ N_("/Layers/Merge Visible Layers"), "<control>M", layers_merge_cmd_callback, 0 },
|
|
{ N_("/Layers/Flatten Image"), NULL, layers_flatten_cmd_callback, 0 },
|
|
{ N_("/Layers/Alpha To Selection"), NULL, layers_alpha_select_cmd_callback, 0 },
|
|
{ N_("/Layers/Mask To Selection"), NULL, layers_mask_select_cmd_callback, 0 },
|
|
{ N_("/Layers/Add Alpha Channel"), NULL, layers_add_alpha_channel_cmd_callback, 0 },
|
|
{ N_("/Layers/---"), NULL, NULL, 0, "<Separator>" },
|
|
|
|
{ N_("/Tools/tearoff1"), NULL, NULL, 0, "<Tearoff>" },
|
|
{ N_("/Tools/Toolbox"), NULL, toolbox_raise_callback, 0 },
|
|
{ N_("/Tools/Default Colors"), "D", tools_default_colors_cmd_callback, 0 },
|
|
{ N_("/Tools/Swap Colors"), "X", tools_swap_colors_cmd_callback, 0 },
|
|
{ N_("/Tools/---"), NULL, NULL, 0, "<Separator>" },
|
|
|
|
/* the tool entries themselves are built on the fly */
|
|
|
|
{ N_("/Filters/tearoff1"), NULL, NULL, 0, "<Tearoff>" },
|
|
{ N_("/Filters/Repeat last"), "<alt>F", filters_repeat_cmd_callback, 0x0 },
|
|
{ N_("/Filters/Re-show last"), "<alt><shift>F", filters_repeat_cmd_callback, 0x1 },
|
|
{ N_("/Filters/---"), NULL, NULL, 0, "<Separator>" },
|
|
|
|
{ N_("/Script-Fu/tearoff1"), NULL, NULL, 0, "<Tearoff>" },
|
|
{ N_("/Script-Fu/"), NULL, NULL, 0 },
|
|
|
|
{ N_("/Dialogs/tearoff1"), NULL, NULL, 0, "<Tearoff>" },
|
|
{ N_("/Dialogs/Brushes..."), "<control><shift>B", dialogs_brushes_cmd_callback, 0 },
|
|
{ N_("/Dialogs/Patterns..."), "<control><shift>P", dialogs_patterns_cmd_callback, 0 },
|
|
{ N_("/Dialogs/Palette..."), "<control>P", dialogs_palette_cmd_callback, 0 },
|
|
{ N_("/Dialogs/Gradient..."), "<control>G", dialogs_gradient_editor_cmd_callback, 0 },
|
|
{ N_("/Dialogs/Layers & Channels..."), "<control>L", dialogs_lc_cmd_callback, 0 },
|
|
{ N_("/Dialogs/Indexed Palette..."), NULL, dialogs_indexed_palette_cmd_callback, 0 },
|
|
{ N_("/Dialogs/Tool Options..."), NULL, dialogs_tools_options_cmd_callback, 0 },
|
|
{ N_("/Dialogs/Input Devices..."), NULL, dialogs_input_devices_cmd_callback, 0 },
|
|
{ N_("/Dialogs/Device Status..."), NULL, dialogs_device_status_cmd_callback, 0 },
|
|
};
|
|
static guint n_image_entries = sizeof (image_entries) / sizeof (image_entries[0]);
|
|
static GtkItemFactory *image_factory = NULL;
|
|
|
|
static GtkItemFactoryEntry load_entries[] =
|
|
{
|
|
{ N_("/Automatic"), NULL, file_load_by_extension_callback, 0 },
|
|
{ "/---", NULL, NULL, 0, "<Separator>" },
|
|
};
|
|
static guint n_load_entries = sizeof (load_entries) / sizeof (load_entries[0]);
|
|
static GtkItemFactory *load_factory = NULL;
|
|
|
|
static GtkItemFactoryEntry save_entries[] =
|
|
{
|
|
{ N_("/By extension"), NULL, file_save_by_extension_callback, 0 },
|
|
{ "/---", NULL, NULL, 0, "<Separator>" },
|
|
};
|
|
static guint n_save_entries = sizeof (save_entries) / sizeof (save_entries[0]);
|
|
static GtkItemFactory *save_factory = NULL;
|
|
|
|
static GtkItemFactoryEntry layers_entries[] =
|
|
{
|
|
{ N_("/New Layer"), "<control>N", layers_dialog_new_layer_callback, 0 },
|
|
{ N_("/Stack/Previous Layer"), "Prior", layers_dialog_previous_layer_callback, 0 },
|
|
{ N_("/Stack/Next Layer"), "Next", layers_dialog_next_layer_callback, 0 },
|
|
{ N_("/Stack/Raise Layer"), "<shift>Prior", layers_dialog_raise_layer_callback, 0 },
|
|
{ N_("/Stack/Lower Layer"), "<shift>Next", layers_dialog_lower_layer_callback, 0 },
|
|
{ N_("/Stack/Layer to Top"), "<control>Prior", layers_dialog_raise_layer_to_top_callback, 0 },
|
|
{ N_("/Stack/Layer to Bottom"), "<control>Next", layers_dialog_lower_layer_to_bottom_callback, 0 },
|
|
{ N_("/Duplicate Layer"), "<control>C", layers_dialog_duplicate_layer_callback, 0 },
|
|
{ N_("/Anchor Layer"), "<control>H", layers_dialog_anchor_layer_callback, 0 },
|
|
{ N_("/Delete Layer"), "<control>X", layers_dialog_delete_layer_callback, 0 },
|
|
{ "/---", NULL, NULL, 0, "<Separator>" },
|
|
{ N_("/Scale Layer"), "<control>S", layers_dialog_scale_layer_callback, 0 },
|
|
{ N_("/Resize Layer"), "<control>R", layers_dialog_resize_layer_callback, 0 },
|
|
{ "/---", NULL, NULL, 0, "<Separator>" },
|
|
{ N_("/Merge Visible Layers"), "<control>M", layers_dialog_merge_layers_callback, 0 },
|
|
{ N_("/Merge Down"), "<control><shift>M", layers_dialog_merge_down_callback, 0 },
|
|
{ N_("/Flatten Image"), NULL, layers_dialog_flatten_image_callback, 0 },
|
|
{ "/---", NULL, NULL, 0, "<Separator>" },
|
|
{ N_("/Add Layer Mask"), NULL, layers_dialog_add_layer_mask_callback, 0 },
|
|
{ N_("/Apply Layer Mask"), NULL, layers_dialog_apply_layer_mask_callback, 0 },
|
|
{ N_("/Alpha to Selection"), NULL, layers_dialog_alpha_select_callback, 0 },
|
|
{ N_("/Mask to Selection"), NULL, layers_dialog_mask_select_callback, 0 },
|
|
{ N_("/Add Alpha Channel"), NULL, layers_dialog_add_alpha_channel_callback, 0 }
|
|
};
|
|
static guint n_layers_entries = sizeof (layers_entries) / sizeof (layers_entries[0]);
|
|
static GtkItemFactory *layers_factory = NULL;
|
|
|
|
static GtkItemFactoryEntry channels_entries[] =
|
|
{
|
|
{ N_("/New Channel"), "<control>N", channels_dialog_new_channel_callback, 0 },
|
|
{ N_("/Raise Channel"), "<control>F", channels_dialog_raise_channel_callback, 0 },
|
|
{ N_("/Lower Channel"), "<control>B", channels_dialog_lower_channel_callback, 0 },
|
|
{ N_("/Duplicate Channel"), "<control>C", channels_dialog_duplicate_channel_callback, 0 },
|
|
{ "/---", NULL, NULL, 0, "<Separator>" },
|
|
{ N_("/Channel to Selection"), "<control>S", channels_dialog_channel_to_sel_callback, 0 },
|
|
{ N_("/Add to Selection"), NULL, channels_dialog_add_channel_to_sel_callback, 0 },
|
|
{ N_("/Subtract From Selection"), NULL, channels_dialog_sub_channel_from_sel_callback, 0 },
|
|
{ N_("/Intersect With Selection"), NULL, channels_dialog_sub_channel_from_sel_callback, 0 },
|
|
{ "/---", NULL, NULL, 0, "<Separator>" },
|
|
{ N_("/Delete Channel"), "<control>X", channels_dialog_delete_channel_callback, 0 }
|
|
};
|
|
static guint n_channels_entries = sizeof (channels_entries) / sizeof (channels_entries[0]);
|
|
static GtkItemFactory *channels_factory = NULL;
|
|
|
|
static GtkItemFactoryEntry paths_entries[] =
|
|
{
|
|
{ N_("/New Path"), "<control>N", paths_dialog_new_path_callback, 0 },
|
|
{ N_("/Duplicate Path"), "<control>U", paths_dialog_dup_path_callback, 0 },
|
|
{ N_("/Path to Selection"), "<control>S", paths_dialog_path_to_sel_callback, 0 },
|
|
{ N_("/Stroke Path"), "<control>T", paths_dialog_stroke_path_callback, 0 },
|
|
{ N_("/Delete Path"), "<control>X", paths_dialog_delete_path_callback, 0 },
|
|
{ "/---", NULL, NULL, 0, "<Separator>" },
|
|
{ N_("/Copy Path"), "<control>C", paths_dialog_copy_path_callback, 0 },
|
|
{ N_("/Paste Path"), "<control>V", paths_dialog_paste_path_callback, 0 },
|
|
{ N_("/Import Path"), "<control>I", paths_dialog_import_path_callback, 0 },
|
|
{ N_("/Export Path"), "<control>E", paths_dialog_export_path_callback, 0 }
|
|
};
|
|
static guint n_paths_entries = sizeof (paths_entries) / sizeof (paths_entries[0]);
|
|
static GtkItemFactory *paths_factory = NULL;
|
|
|
|
static int 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 (GtkMenuEntry *entries,
|
|
int n_menu_entries)
|
|
{
|
|
GtkWidget *menu_item;
|
|
int i;
|
|
int redo_image_menu = FALSE;
|
|
GString *tearoff_path;
|
|
|
|
if (initialize)
|
|
menus_init ();
|
|
|
|
tearoff_path = g_string_new ("");
|
|
|
|
for (i = 0; i < n_menu_entries; i++)
|
|
if (! strncmp (entries[i].path, "<Image>", 7))
|
|
{
|
|
char *p;
|
|
|
|
p = strchr (entries[i].path + 8, '/');
|
|
while (p)
|
|
{
|
|
g_string_assign (tearoff_path, entries[i].path + 7);
|
|
g_string_truncate (tearoff_path, p - entries[i].path + 1 - 7);
|
|
g_string_append (tearoff_path, "tearoff1");
|
|
|
|
if (! gtk_item_factory_get_widget (image_factory, tearoff_path->str))
|
|
{
|
|
GtkItemFactoryEntry entry = { NULL, NULL, NULL, 0, "<Tearoff>" };
|
|
entry.path = tearoff_path->str;
|
|
gtk_item_factory_create_items (image_factory, 1, &entry, NULL);
|
|
}
|
|
|
|
p = strchr (p + 1, '/');
|
|
}
|
|
|
|
redo_image_menu = TRUE;
|
|
}
|
|
|
|
g_string_free (tearoff_path, TRUE);
|
|
|
|
gtk_item_factory_create_menu_entries (n_menu_entries, entries);
|
|
|
|
if (redo_image_menu)
|
|
{
|
|
menu_item = gtk_item_factory_get_widget (image_factory,
|
|
"<Image>/File/---moved");
|
|
if (menu_item && menu_item->parent)
|
|
gtk_menu_reorder_child (GTK_MENU (menu_item->parent), menu_item, -1);
|
|
|
|
menu_item = gtk_item_factory_get_widget (image_factory,
|
|
"<Image>/File/Close");
|
|
if (menu_item && menu_item->parent)
|
|
gtk_menu_reorder_child (GTK_MENU (menu_item->parent), menu_item, -1);
|
|
|
|
menu_item = gtk_item_factory_get_widget (image_factory,
|
|
"<Image>/File/Quit");
|
|
if (menu_item && menu_item->parent)
|
|
gtk_menu_reorder_child (GTK_MENU (menu_item->parent), menu_item, -1);
|
|
}
|
|
}
|
|
|
|
void
|
|
menus_tools_create (ToolInfo *tool_info)
|
|
{
|
|
GtkItemFactoryEntry entry;
|
|
|
|
entry.path = tool_info->menu_path;
|
|
entry.accelerator = tool_info->menu_accel;
|
|
entry.callback = tools_select_cmd_callback;
|
|
entry.callback_action = tool_info->tool_id;
|
|
entry.item_type = NULL;
|
|
|
|
gtk_item_factory_create_item (image_factory,
|
|
&entry,
|
|
(gpointer) tool_info,
|
|
2);
|
|
}
|
|
|
|
void
|
|
menus_set_sensitive (gchar *path,
|
|
gint 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);
|
|
|
|
gtk_widget_set_sensitive (widget, sensitive);
|
|
}
|
|
if (!ifactory || !widget)
|
|
g_warning ("Unable to set sensitivity for menu which doesn't exist:\n%s", path);
|
|
}
|
|
|
|
/* The following function will enhance our localesystem because
|
|
we don't need to have our menuentries twice in our catalog */
|
|
|
|
void
|
|
menus_set_sensitive_locale (gchar *prepath,
|
|
gchar *path,
|
|
gint sensitive)
|
|
{
|
|
gchar *menupath;
|
|
|
|
menupath = g_strdup_printf ("%s%s", prepath, _(path));
|
|
menus_set_sensitive (menupath, sensitive);
|
|
g_free (menupath);
|
|
}
|
|
|
|
void
|
|
menus_set_state (gchar *path,
|
|
gint 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_set_state_locale (gchar *prepath,
|
|
gchar *path,
|
|
gint state)
|
|
{
|
|
gchar *menupath;
|
|
|
|
menupath = g_strdup_printf ("%s%s", prepath, _(path));
|
|
menus_set_state (menupath, state);
|
|
g_free (menupath);
|
|
}
|
|
|
|
void
|
|
menus_destroy (char *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));
|
|
}
|
|
}
|
|
|
|
void
|
|
menus_last_opened_cmd_callback (GtkWidget *widget,
|
|
gpointer callback_data,
|
|
guint num)
|
|
{
|
|
gchar *filename, *raw_filename;
|
|
guint num_entries;
|
|
|
|
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);
|
|
|
|
if (!file_open (raw_filename, filename))
|
|
g_message (_("Error opening file: %s\n"), raw_filename);
|
|
}
|
|
|
|
void
|
|
menus_last_opened_update_labels (void)
|
|
{
|
|
GSList *filename_slist;
|
|
GString *entry_filename, *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);
|
|
gtk_widget_show (widget);
|
|
|
|
gtk_label_set (GTK_LABEL (GTK_BIN (widget)->child), entry_filename->str);
|
|
|
|
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 *item;
|
|
GtkWidget *widget;
|
|
guint num_entries;
|
|
|
|
/* ignore the add if we've already got the filename on the list */
|
|
item = last_opened_raw_filenames;
|
|
while (item)
|
|
{
|
|
raw_filename = item->data;
|
|
if (!strcmp (raw_filename->str, filename))
|
|
return;
|
|
item = g_slist_next (item);
|
|
}
|
|
|
|
num_entries = g_slist_length (last_opened_raw_filenames);
|
|
|
|
if (num_entries == last_opened_size)
|
|
{
|
|
g_slist_remove_link (last_opened_raw_filenames,
|
|
g_slist_last (last_opened_raw_filenames));
|
|
}
|
|
|
|
raw_filename = g_string_new (filename);
|
|
last_opened_raw_filenames = g_slist_prepend (last_opened_raw_filenames, raw_filename);
|
|
|
|
if (num_entries == 0)
|
|
{
|
|
widget = gtk_item_factory_get_widget (toolbox_factory, gettext(file_menu_separator.path));
|
|
gtk_widget_show (widget);
|
|
}
|
|
|
|
menus_last_opened_update_labels ();
|
|
}
|
|
|
|
void
|
|
menus_init_mru (void)
|
|
{
|
|
gchar *paths, *accelerators;
|
|
gint i;
|
|
GtkItemFactoryEntry *last_opened_entries;
|
|
GtkWidget *widget;
|
|
|
|
last_opened_entries = g_new (GtkItemFactoryEntry, 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].path = path;
|
|
last_opened_entries[i].accelerator = accelerator;
|
|
last_opened_entries[i].callback = (GtkItemFactoryCallback) menus_last_opened_cmd_callback;
|
|
last_opened_entries[i].callback_action = i;
|
|
last_opened_entries[i].item_type = 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);
|
|
}
|
|
|
|
gtk_item_factory_create_items_ac (toolbox_factory, last_opened_size,
|
|
last_opened_entries, NULL, 2);
|
|
|
|
for (i=0; i < last_opened_size; i++)
|
|
{
|
|
widget = gtk_item_factory_get_widget (toolbox_factory,
|
|
last_opened_entries[i].path);
|
|
gtk_widget_hide (widget);
|
|
}
|
|
|
|
widget = gtk_item_factory_get_widget (toolbox_factory, gettext(file_menu_separator.path));
|
|
gtk_widget_hide (widget);
|
|
|
|
g_free (paths);
|
|
g_free (accelerators);
|
|
g_free (last_opened_entries);
|
|
}
|
|
|
|
void
|
|
menus_init_toolbox (void)
|
|
{
|
|
toolbox_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<Toolbox>", NULL);
|
|
gtk_item_factory_set_translate_func (toolbox_factory, menu_translate,
|
|
NULL, NULL);
|
|
gtk_item_factory_create_items_ac (toolbox_factory, n_toolbox_entries,
|
|
toolbox_entries, NULL, 2);
|
|
menus_init_mru ();
|
|
|
|
gtk_item_factory_create_item (toolbox_factory, &file_menu_separator, NULL, 2);
|
|
|
|
gtk_item_factory_create_item (toolbox_factory, &toolbox_end, NULL, 2);
|
|
}
|
|
|
|
static void
|
|
menus_init (void)
|
|
{
|
|
int i;
|
|
|
|
if (initialize)
|
|
{
|
|
gchar *filename;
|
|
|
|
initialize = FALSE;
|
|
|
|
menus_init_toolbox ();
|
|
|
|
image_factory = gtk_item_factory_new (GTK_TYPE_MENU, "<Image>", NULL);
|
|
gtk_item_factory_set_translate_func (image_factory,
|
|
menu_translate,
|
|
NULL, NULL);
|
|
gtk_item_factory_create_items_ac (image_factory,
|
|
n_image_entries,
|
|
image_entries,
|
|
NULL, 2);
|
|
|
|
load_factory = gtk_item_factory_new (GTK_TYPE_MENU, "<Load>", NULL);
|
|
gtk_item_factory_set_translate_func (load_factory,
|
|
menu_translate,
|
|
NULL, NULL);
|
|
gtk_item_factory_create_items_ac (load_factory,
|
|
n_load_entries,
|
|
load_entries,
|
|
NULL, 2);
|
|
|
|
save_factory = gtk_item_factory_new (GTK_TYPE_MENU, "<Save>", NULL);
|
|
gtk_item_factory_set_translate_func (save_factory,
|
|
menu_translate,
|
|
NULL, NULL);
|
|
gtk_item_factory_create_items_ac (save_factory,
|
|
n_save_entries,
|
|
save_entries,
|
|
NULL, 2);
|
|
|
|
layers_factory = gtk_item_factory_new (GTK_TYPE_MENU, "<Layers>", NULL);
|
|
gtk_item_factory_set_translate_func (layers_factory,
|
|
menu_translate,
|
|
NULL, NULL);
|
|
gtk_item_factory_create_items_ac (layers_factory,
|
|
n_layers_entries,
|
|
layers_entries,
|
|
NULL, 2);
|
|
|
|
channels_factory = gtk_item_factory_new (GTK_TYPE_MENU, "<Channels>", NULL);
|
|
gtk_item_factory_set_translate_func (channels_factory,
|
|
menu_translate,
|
|
NULL, NULL);
|
|
gtk_item_factory_create_items_ac (channels_factory,
|
|
n_channels_entries,
|
|
channels_entries,
|
|
NULL, 2);
|
|
|
|
paths_factory = gtk_item_factory_new (GTK_TYPE_MENU, "<Paths>", NULL);
|
|
gtk_item_factory_set_translate_func (paths_factory,
|
|
menu_translate,
|
|
NULL, NULL);
|
|
gtk_item_factory_create_items_ac (paths_factory,
|
|
n_paths_entries,
|
|
paths_entries,
|
|
NULL, 2);
|
|
|
|
for (i = 0; i < num_tools; i++)
|
|
{
|
|
/* FIXME this need to use access functions to check a flag */
|
|
if (tool_info[i].menu_path)
|
|
menus_tools_create (tool_info + i);
|
|
}
|
|
|
|
filename = gimp_personal_rc_file ("menurc");
|
|
gtk_item_factory_parse_rc (filename);
|
|
g_free (filename);
|
|
}
|
|
}
|
|
|
|
static gchar *
|
|
menu_translate (const gchar *path,
|
|
gpointer data)
|
|
{
|
|
return gettext (path);
|
|
}
|