gimpitemfactory.c 32.4 KB
Newer Older
Elliot Lee's avatar
Elliot Lee committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/* 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
16
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Elliot Lee's avatar
Elliot Lee committed
17 18 19 20
 */
#include <stdlib.h>
#include <string.h>
#include "appenv.h"
21
#include "channels_dialog.h"
Elliot Lee's avatar
Elliot Lee committed
22 23
#include "colormaps.h"
#include "commands.h"
24
#include "dialog_handler.h"
Elliot Lee's avatar
Elliot Lee committed
25
#include "fileops.h"
26
#include "general.h"
Elliot Lee's avatar
Elliot Lee committed
27 28
#include "gimprc.h"
#include "interface.h"
29
#include "layers_dialog.h"
Elliot Lee's avatar
Elliot Lee committed
30
#include "menus.h"
31
#include "paths_dialog.h"
Elliot Lee's avatar
Elliot Lee committed
32 33 34 35
#include "paint_funcs.h"
#include "procedural_db.h"
#include "scale.h"
#include "tools.h"
Manish Singh's avatar
Manish Singh committed
36
#include "gdisplay.h"
Chris Lahey's avatar
Chris Lahey committed
37
#include "docindex.h"
Elliot Lee's avatar
Elliot Lee committed
38

39
#include "config.h"
40
#include "libgimp/gimpintl.h"
Tor Lillqvist's avatar
Tor Lillqvist committed
41
#include "libgimp/gimpenv.h"
42

43
#define MRU_MENU_ENTRY_SIZE (strlen (_("/File/MRU00 ")) + 1)
44 45
#define MRU_MENU_ACCEL_SIZE sizeof ("<control>0")

46 47 48
static char* G_GNUC_UNUSED dummyMenus[] = { N_("/File/MRU00 "),
                                            N_("/File"),
                                            N_("/File/Dialogs"),
Manish Singh's avatar
Manish Singh committed
49
                                            N_("/Image/Transforms"),
50 51 52
                                            N_("/Layers"),
                                            N_("/Tools"),
                                            N_("/Dialogs"),
Manish Singh's avatar
Manish Singh committed
53 54
                                            N_("/View/Zoom"),
                                            N_("/Stack")};
55

Manish Singh's avatar
Manish Singh committed
56 57 58
static void   menus_init        (void);
static gchar* menu_translate    (const gchar *path,
				 gpointer     data);
59 60 61
static void   tearoff_cmd_callback (GtkWidget *widget,
				    gpointer   callback_data,
				    guint      callback_action);
62

63 64
static GSList *last_opened_raw_filenames = NULL;

Manish Singh's avatar
Manish Singh committed
65
static GtkItemFactoryEntry toolbox_entries[] =
Elliot Lee's avatar
Elliot Lee committed
66
{
67
  { N_("/File/tearoff1"), NULL, tearoff_cmd_callback, 0, "<Tearoff>" },
68 69
  { N_("/File/New"), "<control>N", file_new_cmd_callback, 0 },
  { N_("/File/Open"), "<control>O", file_open_cmd_callback, 0 },
70
  { N_("/File/Acquire"), NULL, NULL, 0, "<Branch>" },
71
  { N_("/File/About..."), NULL, about_dialog_cmd_callback, 0 },
72
  { N_("/File/Help..."), NULL, gimp_help_cmd_callback, 0 },
73 74
  { N_("/File/Preferences..."), NULL, file_pref_cmd_callback, 0 },
  { N_("/File/Tip of the day"), NULL, tips_dialog_cmd_callback, 0 },
Michael Natterer's avatar
Michael Natterer committed
75

76 77 78 79 80 81 82 83 84 85
  { 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 },
86
  { N_("/File/Dialogs/Display Filters..."), NULL, dialogs_display_filters_cmd_callback, 0 },
Michael Natterer's avatar
Michael Natterer committed
87

88
  { N_("/Xtns/tearoff1"), NULL, tearoff_cmd_callback, 0, "<Tearoff>" },
89
  { N_("/Xtns/Module Browser"), NULL, dialogs_module_browser_cmd_callback, 0 },
90
  { N_("/File/---"), NULL, NULL, 0, "<Separator>" },
91
  { N_("/File/---"), NULL, NULL, 0, "<Separator>" }
92 93 94 95
};
static guint n_toolbox_entries = sizeof (toolbox_entries) / sizeof (toolbox_entries[0]);
static GtkItemFactory *toolbox_factory = NULL;

Manish Singh's avatar
Manish Singh committed
96 97
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 };
98

Manish Singh's avatar
Manish Singh committed
99
static GtkItemFactoryEntry image_entries[] =
100
{
101 102
  { N_("/tearoff1"), NULL, tearoff_cmd_callback, 0, "<Tearoff>" },
  { N_("/File/tearoff1"), NULL, tearoff_cmd_callback, 0, "<Tearoff>" },
103 104 105 106 107 108
  { 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 },
109
  { N_("/File/---"), NULL, NULL, 0, "<Separator>" },
Michael Natterer's avatar
Michael Natterer committed
110

111 112
  { N_("/File/Close"), "<control>W", file_close_cmd_callback, 0 },
  { N_("/File/Quit"), "<control>Q", file_quit_cmd_callback, 0 },
113
  { N_("/File/---moved"), NULL, NULL, 0, "<Separator>" },
Michael Natterer's avatar
Michael Natterer committed
114

115
  { N_("/Edit/tearoff1"), NULL, tearoff_cmd_callback, 0, "<Tearoff>" },
116 117 118 119
  { 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 },
120 121
  { N_("/Edit/Paste As New"), NULL, edit_paste_as_new_cmd_callback, 0 },
  { N_("/Edit/---"), NULL, NULL, 0, "<Separator>" },
122 123 124 125 126
  { 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 },
127
  { N_("/Edit/Undo history..."), NULL, edit_show_undo_history_cmd_callback, 0},
128
  { N_("/Edit/---"), NULL, NULL, 0, "<Separator>" },
129 130 131
  { 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 },
132
  { N_("/Edit/---"), NULL, NULL, 0, "<Separator>" },
133
  
134
  { N_("/Select/tearoff1"), NULL, tearoff_cmd_callback, 0, "<Tearoff>" },
135 136 137 138
  { 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 },
139
  { N_("/Select/---"), NULL, NULL, 0, "<Separator>" },
140
  { N_("/Select/Feather"), "<control><shift>F", select_feather_cmd_callback, 0 },
141
  { N_("/Select/Sharpen"), "<control><shift>H", select_sharpen_cmd_callback, 0 },
142
  { N_("/Select/Shrink"), NULL, select_shrink_cmd_callback, 0 },
143 144 145
  { 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>" },
146
  { N_("/Select/Save To Channel"), NULL, select_save_cmd_callback, 0 },
147

148
  { N_("/View/tearoff1"), NULL, tearoff_cmd_callback, 0, "<Tearoff>" },
149 150 151 152 153 154 155
  { 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 },
156 157 158 159
  { 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 },
160 161
  { 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 },
162
  { N_("/View/Window Nav..."), NULL, view_window_nav_cmd_callback, 0 },
Michael Natterer's avatar
Michael Natterer committed
163 164

  { N_("/View/---"), NULL, NULL, 0, "<Separator>" },
165
  { N_("/View/Toggle Selection"), "<control>T", view_toggle_selection_cmd_callback, 0, "<ToggleItem>" },
166 167 168 169
  { 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>" },
170
  { N_("/View/---"), NULL, NULL, 0, "<Separator>" },
Michael Natterer's avatar
Michael Natterer committed
171

172 173
  { N_("/View/New View"), NULL, view_new_view_cmd_callback, 0 },
  { N_("/View/Shrink Wrap"), "<control>E", view_shrink_wrap_cmd_callback, 0 },
174

175 176
  { N_("/Image/tearoff1"), NULL, tearoff_cmd_callback, 0, "<Tearoff>" },
  { N_("/Image/Colors/tearoff1"), NULL, tearoff_cmd_callback, 0, "<Tearoff>" },
177 178
  { N_("/Image/Colors/Equalize"), NULL, image_equalize_cmd_callback, 0 },
  { N_("/Image/Colors/Invert"), NULL, image_invert_cmd_callback, 0 },
179
  { N_("/Image/Colors/---"), NULL, NULL, 0, "<Separator>" },
180
  { N_("/Image/Colors/Desaturate"), NULL, image_desaturate_cmd_callback, 0 },
181
  { N_("/Image/Channel Ops/tearoff1"), NULL, tearoff_cmd_callback, 0, "<Tearoff>" },
182 183
  { 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 },
184
  { N_("/Image/Alpha/tearoff1"), NULL, tearoff_cmd_callback, 0, "<Tearoff>" },
185
  { N_("/Image/Alpha/Add Alpha Channel"), NULL, layers_add_alpha_channel_cmd_callback, 0 },
186
  
187
  { N_("/Image/---"), NULL, NULL, 0, "<Separator>" },
188 189 190
  { 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 },
191
  { N_("/Image/---"), NULL, NULL, 0, "<Separator>" },
192 193
  { N_("/Image/Resize"), NULL, image_resize_cmd_callback, 0 },
  { N_("/Image/Scale"), NULL, image_scale_cmd_callback, 0 },
194
  { N_("/Image/---"), NULL, NULL, 0, "<Separator>" },
Michael Natterer's avatar
Michael Natterer committed
195

196
  { N_("/Layers/tearoff1"), NULL, tearoff_cmd_callback, 0, "<Tearoff>" },
197
  { N_("/Layers/Layers & Channels..."), "<control>L", dialogs_lc_cmd_callback, 0 },
198
  { N_("/Layers/Stack/tearoff1"), NULL, tearoff_cmd_callback, 0, "<Tearoff>" },
199 200 201 202 203 204
  { 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 },
205
  { N_("/Layers/---"), NULL, NULL, 0, "<Separator>" },
206 207 208 209 210 211
  { 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 },
212
  { N_("/Layers/---"), NULL, NULL, 0, "<Separator>" },
213
  
214
  { N_("/Tools/tearoff1"), NULL, tearoff_cmd_callback, 0, "<Tearoff>" },
215 216 217
  { 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 },
218 219
  { N_("/Tools/---"), NULL, NULL, 0, "<Separator>" },  

Michael Natterer's avatar
Michael Natterer committed
220 221
  /*  the tool entries themselves are built on the fly  */

222
  { N_("/Filters/tearoff1"), NULL, tearoff_cmd_callback, 0, "<Tearoff>" },
223 224
  { N_("/Filters/Repeat last"), "<alt>F", filters_repeat_cmd_callback, 0x0 },
  { N_("/Filters/Re-show last"), "<alt><shift>F", filters_repeat_cmd_callback, 0x1 },
225
  { N_("/Filters/---"), NULL, NULL, 0, "<Separator>" },
226
  
227
  { N_("/Script-Fu/tearoff1"), NULL, tearoff_cmd_callback, 0, "<Tearoff>" },
228
  { N_("/Script-Fu/"), NULL, NULL, 0 },
229
  
230
  { N_("/Dialogs/tearoff1"), NULL, tearoff_cmd_callback, 0, "<Tearoff>" },
231 232 233 234 235 236 237 238 239
  { 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 },
240
  { N_("/Dialogs/Display Filters..."), NULL, dialogs_display_filters_cmd_callback, 0 }
241 242 243
};
static guint n_image_entries = sizeof (image_entries) / sizeof (image_entries[0]);
static GtkItemFactory *image_factory = NULL;
Elliot Lee's avatar
Elliot Lee committed
244
  
Manish Singh's avatar
Manish Singh committed
245
static GtkItemFactoryEntry load_entries[] =
246
{
247
  { N_("/Automatic"), NULL, file_load_by_extension_callback, 0 },
248 249 250 251
  { "/---", NULL, NULL, 0, "<Separator>" },
};
static guint n_load_entries = sizeof (load_entries) / sizeof (load_entries[0]);
static GtkItemFactory *load_factory = NULL;
Manish Singh's avatar
Manish Singh committed
252
  
Manish Singh's avatar
Manish Singh committed
253
static GtkItemFactoryEntry save_entries[] =
254
{
255
  { N_("/By extension"), NULL, file_save_by_extension_callback, 0 },
256
  { "/---", NULL, NULL, 0, "<Separator>" },
Elliot Lee's avatar
Elliot Lee committed
257
};
258 259
static guint n_save_entries = sizeof (save_entries) / sizeof (save_entries[0]);
static GtkItemFactory *save_factory = NULL;
Elliot Lee's avatar
Elliot Lee committed
260

Manish Singh's avatar
Manish Singh committed
261
static GtkItemFactoryEntry layers_entries[] =
262 263 264 265 266 267 268 269 270 271
{
  { 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 },
Michael Natterer's avatar
Michael Natterer committed
272
  { N_("/Delete Layer"), "<control>X", layers_dialog_delete_layer_callback, 0 },
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289
  { "/---", 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;

Manish Singh's avatar
Manish Singh committed
290
static GtkItemFactoryEntry channels_entries[] =
291 292 293 294 295 296 297 298 299
{
  { 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 },
Michael Natterer's avatar
Michael Natterer committed
300 301 302
  { 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 }
303 304 305 306
};
static guint n_channels_entries = sizeof (channels_entries) / sizeof (channels_entries[0]);
static GtkItemFactory *channels_factory = NULL;

Manish Singh's avatar
Manish Singh committed
307
static GtkItemFactoryEntry paths_entries[] =
308 309 310 311 312
{
  { 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 },
Michael Natterer's avatar
Michael Natterer committed
313
  { N_("/Delete Path"), "<control>X", paths_dialog_delete_path_callback, 0 },
314 315 316 317 318 319 320 321 322
  { "/---", 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;

Elliot Lee's avatar
Elliot Lee committed
323 324 325
static int initialize = TRUE;

void
326 327
menus_get_toolbox_menubar (GtkWidget     **menubar,
			   GtkAccelGroup **accel_group)
Elliot Lee's avatar
Elliot Lee committed
328 329 330
{
  if (initialize)
    menus_init ();
331
  
Elliot Lee's avatar
Elliot Lee committed
332
  if (menubar)
333 334 335
    *menubar = toolbox_factory->widget;
  if (accel_group)
    *accel_group = toolbox_factory->accel_group;
Elliot Lee's avatar
Elliot Lee committed
336 337 338
}

void
339 340
menus_get_image_menu (GtkWidget     **menu,
		      GtkAccelGroup **accel_group)
Elliot Lee's avatar
Elliot Lee committed
341 342 343 344 345
{
  if (initialize)
    menus_init ();

  if (menu)
346 347 348
    *menu = image_factory->widget;
  if (accel_group)
    *accel_group = image_factory->accel_group;
Elliot Lee's avatar
Elliot Lee committed
349 350 351
}

void
352 353
menus_get_load_menu (GtkWidget     **menu,
		     GtkAccelGroup **accel_group)
Elliot Lee's avatar
Elliot Lee committed
354 355 356 357 358
{
  if (initialize)
    menus_init ();

  if (menu)
359 360 361
    *menu = load_factory->widget;
  if (accel_group)
    *accel_group = load_factory->accel_group;
Elliot Lee's avatar
Elliot Lee committed
362 363 364
}

void
365 366
menus_get_save_menu (GtkWidget     **menu,
		     GtkAccelGroup **accel_group)
Elliot Lee's avatar
Elliot Lee committed
367 368 369 370 371
{
  if (initialize)
    menus_init ();

  if (menu)
372 373 374
    *menu = save_factory->widget;
  if (accel_group)
    *accel_group = save_factory->accel_group;
Elliot Lee's avatar
Elliot Lee committed
375 376
}

377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415
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;
}

Elliot Lee's avatar
Elliot Lee committed
416 417
void
menus_create (GtkMenuEntry *entries,
418
	      int           n_menu_entries)
Elliot Lee's avatar
Elliot Lee committed
419
{
420 421 422
  GtkWidget *menu_item;
  int i;
  int redo_image_menu = FALSE;
Manish Singh's avatar
Manish Singh committed
423
  GString *tearoff_path;
424

Elliot Lee's avatar
Elliot Lee committed
425 426 427
  if (initialize)
    menus_init ();

Manish Singh's avatar
Manish Singh committed
428
  tearoff_path = g_string_new ("");
429

430
  for (i = 0; i < n_menu_entries; i++)
Manish Singh's avatar
Manish Singh committed
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445
    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;
446 447
		entry.callback = tearoff_cmd_callback;
		gtk_item_factory_create_items_ac (image_factory, 1, &entry, NULL,2);
Manish Singh's avatar
Manish Singh committed
448 449 450 451 452 453 454 455 456 457 458
	      }

	    p = strchr (p + 1, '/');
	  }

	redo_image_menu = TRUE;
      }

  g_string_free (tearoff_path, TRUE);

  gtk_item_factory_create_menu_entries (n_menu_entries, entries);
459 460 461

  if (redo_image_menu)
    {
Manish Singh's avatar
Manish Singh committed
462 463 464 465 466 467 468 469 470 471 472 473 474 475
      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);
476
    }
Elliot Lee's avatar
Elliot Lee committed
477 478
}

479 480 481 482
void
menus_tools_create (ToolInfo *tool_info)
{
  GtkItemFactoryEntry entry;
483

Manish Singh's avatar
Manish Singh committed
484
  entry.path = tool_info->menu_path;
485 486 487 488
  entry.accelerator = tool_info->menu_accel;
  entry.callback = tools_select_cmd_callback;
  entry.callback_action = tool_info->tool_id;
  entry.item_type = NULL;
Michael Natterer's avatar
Michael Natterer committed
489

490 491
  gtk_item_factory_create_item (image_factory,
				&entry,
Manish Singh's avatar
Manish Singh committed
492
				(gpointer) tool_info,
493 494 495
				2);
}

Elliot Lee's avatar
Elliot Lee committed
496
void
497 498
menus_set_sensitive (gchar *path,
		     gint   sensitive)
Elliot Lee's avatar
Elliot Lee committed
499
{
500 501
  GtkItemFactory *ifactory;
  GtkWidget *widget = NULL;
Elliot Lee's avatar
Elliot Lee committed
502 503 504 505

  if (initialize)
    menus_init ();

506 507 508 509 510
  ifactory = gtk_item_factory_from_path (path);

  if (ifactory)
    {
      widget = gtk_item_factory_get_widget (ifactory, path);
Michael Natterer's avatar
Michael Natterer committed
511

512 513 514
      gtk_widget_set_sensitive (widget, sensitive);
    }
  if (!ifactory || !widget)
515
    g_warning ("Unable to set sensitivity for menu which doesn't exist:\n%s", path);
Michael Natterer's avatar
Michael Natterer committed
516
}
Elliot Lee's avatar
Elliot Lee committed
517

518 519 520 521
/* The following function will enhance our localesystem because
   we don't need to have our menuentries twice in our catalog */ 

void
Sven Neumann's avatar
Sven Neumann committed
522 523 524
menus_set_sensitive_glue (gchar *prepath,
			  gchar *path,
			  gint   sensitive)
525 526
{
  gchar *menupath;
Manish Singh's avatar
Manish Singh committed
527

528
  menupath = g_strdup_printf ("%s%s", prepath, path);
Manish Singh's avatar
Manish Singh committed
529 530
  menus_set_sensitive (menupath, sensitive);
  g_free (menupath); 
531 532
}

Elliot Lee's avatar
Elliot Lee committed
533
void
534 535
menus_set_state (gchar *path,
		 gint   state)
Elliot Lee's avatar
Elliot Lee committed
536
{
537 538
  GtkItemFactory *ifactory;
  GtkWidget *widget = NULL;
Elliot Lee's avatar
Elliot Lee committed
539 540 541 542

  if (initialize)
    menus_init ();

543
  ifactory = gtk_item_factory_from_path (path);
Elliot Lee's avatar
Elliot Lee committed
544

545 546 547
  if (ifactory)
    {
      widget = gtk_item_factory_get_widget (ifactory, path);
Elliot Lee's avatar
Elliot Lee committed
548

549
      if (widget && GTK_IS_CHECK_MENU_ITEM (widget))
550
	gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (widget), state);
551 552 553 554
      else
	widget = NULL;
    }
  if (!ifactory || !widget)
555
    g_warning ("Unable to set state for menu which doesn't exist:\n%s\n", path);
Elliot Lee's avatar
Elliot Lee committed
556 557
}

558
void
Sven Neumann's avatar
Sven Neumann committed
559 560 561
menus_set_state_glue (gchar *prepath,
		      gchar *path,
		      gint   state)
562 563
{
  gchar *menupath;
Manish Singh's avatar
Manish Singh committed
564

565
  menupath = g_strdup_printf ("%s%s", prepath, path);
Manish Singh's avatar
Manish Singh committed
566 567
  menus_set_state (menupath, state);
  g_free (menupath); 
568 569
}

Elliot Lee's avatar
Elliot Lee committed
570 571 572 573 574 575
void
menus_destroy (char *path)
{
  if (initialize)
    menus_init ();

576
  gtk_item_factories_path_delete (NULL, path);
Elliot Lee's avatar
Elliot Lee committed
577 578 579
}

void
Manish Singh's avatar
Manish Singh committed
580
menus_quit (void)
Elliot Lee's avatar
Elliot Lee committed
581
{
582 583
  gchar *filename;

Tor Lillqvist's avatar
Tor Lillqvist committed
584
  filename = gimp_personal_rc_file ("menurc");
585 586
  gtk_item_factory_dump_rc (filename, NULL, TRUE);
  g_free (filename);
Elliot Lee's avatar
Elliot Lee committed
587

scott's avatar
scott committed
588 589
  if (!initialize)
    {
590 591 592 593
      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));
594 595 596
      gtk_object_unref (GTK_OBJECT (layers_factory));
      gtk_object_unref (GTK_OBJECT (channels_factory));
      gtk_object_unref (GTK_OBJECT (paths_factory));
scott's avatar
scott committed
597
    }
Elliot Lee's avatar
Elliot Lee committed
598 599
}

600
void
Manish Singh's avatar
Manish Singh committed
601 602 603
menus_last_opened_cmd_callback (GtkWidget *widget,
                                gpointer   callback_data,
                                guint      num)
604 605
{
  gchar *filename, *raw_filename;
606 607 608 609 610
  guint num_entries;

  num_entries = g_slist_length (last_opened_raw_filenames); 
  if (num >= num_entries)
    return;
611 612

  raw_filename = ((GString *) g_slist_nth_data (last_opened_raw_filenames, num))->str;
613
  filename = g_basename (raw_filename);
614

615
  if (!file_open (raw_filename, raw_filename))
616
    g_message (_("Error opening file: %s\n"), raw_filename);
617 618 619
}

void
Manish Singh's avatar
Manish Singh committed
620
menus_last_opened_update_labels (void)
621
{
Michael Natterer's avatar
Michael Natterer committed
622 623 624 625 626
  GSList    *filename_slist;
  GString   *entry_filename, *path;
  GtkWidget *widget;
  gint	     i;
  guint      num_entries;
627 628 629 630 631

  entry_filename = g_string_new ("");
  path = g_string_new ("");

  filename_slist = last_opened_raw_filenames;
632
  num_entries = g_slist_length (last_opened_raw_filenames); 
633 634 635

  for (i = 1; i <= num_entries; i++)
    {
636
      g_string_sprintf (entry_filename, "%d. %s", i, g_basename (((GString *) filename_slist->data)->str));
637

638
      g_string_sprintf (path, N_("/File/MRU%02d"), i);
639 640

      widget = gtk_item_factory_get_widget (toolbox_factory, path->str);
641 642
      if (widget != NULL) {
	gtk_widget_show (widget);
643

644 645
	gtk_label_set (GTK_LABEL (GTK_BIN (widget)->child), entry_filename->str);
      }
646 647 648 649 650 651 652 653 654 655
      filename_slist = filename_slist->next;
    }

  g_string_free (entry_filename, TRUE);
  g_string_free (path, TRUE);
}

void
menus_last_opened_add (gchar *filename)
{
Michael Natterer's avatar
Michael Natterer committed
656 657 658 659
  GString   *raw_filename;
  GSList    *item;
  GtkWidget *widget;
  guint      num_entries;
660

661 662 663
  /* ignore the add if we've already got the filename on the list */
  item = last_opened_raw_filenames;
  while (item)
Michael Natterer's avatar
Michael Natterer committed
664
    {
665 666
      raw_filename = item->data;
      if (!strcmp (raw_filename->str, filename))
Michael Natterer's avatar
Michael Natterer committed
667
	return;
668
      item = g_slist_next (item);
Michael Natterer's avatar
Michael Natterer committed
669
    }
670

671
  num_entries = g_slist_length (last_opened_raw_filenames);
672 673 674

  if (num_entries == last_opened_size)
    {
675 676
      g_slist_remove_link (last_opened_raw_filenames, 
			   g_slist_last (last_opened_raw_filenames));
677 678 679 680 681 682 683
    }

  raw_filename = g_string_new (filename);
  last_opened_raw_filenames = g_slist_prepend (last_opened_raw_filenames, raw_filename);

  if (num_entries == 0)
    {
684
      widget = gtk_item_factory_get_widget (toolbox_factory, file_menu_separator.path);
685 686 687 688 689 690 691
      gtk_widget_show (widget);
    }

  menus_last_opened_update_labels ();
}

void
692
menus_init_mru (void)
693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719
{
  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;

720
      g_snprintf (path, MRU_MENU_ENTRY_SIZE, N_("/File/MRU%02d"), i + 1);
721 722
      if (accelerator != NULL)
	g_snprintf (accelerator, MRU_MENU_ACCEL_SIZE, "<control>%d", i + 1);
723 724 725 726
    }

  gtk_item_factory_create_items_ac (toolbox_factory, last_opened_size,
  				    last_opened_entries, NULL, 2);
727
  
728 729 730 731 732 733 734
  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);
    }

735
  widget = gtk_item_factory_get_widget (toolbox_factory, file_menu_separator.path);
736 737 738 739 740 741 742 743
  gtk_widget_hide (widget);
  
  g_free (paths);
  g_free (accelerators);
  g_free (last_opened_entries);
}

void
Manish Singh's avatar
Manish Singh committed
744
menus_init_toolbox (void)
745 746
{
  toolbox_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<Toolbox>", NULL);
Manish Singh's avatar
Manish Singh committed
747 748
  gtk_item_factory_set_translate_func (toolbox_factory, menu_translate,
	  			       NULL, NULL);
749
  gtk_item_factory_create_items_ac (toolbox_factory, n_toolbox_entries,
Manish Singh's avatar
Manish Singh committed
750
				    toolbox_entries, NULL, 2);
751
  menus_init_mru ();
752

Manish Singh's avatar
Manish Singh committed
753
  gtk_item_factory_create_item (toolbox_factory, &file_menu_separator, NULL, 2);
754
   
Manish Singh's avatar
Manish Singh committed
755
  gtk_item_factory_create_item (toolbox_factory, &toolbox_end, NULL, 2);
756 757
}

Elliot Lee's avatar
Elliot Lee committed
758
static void
Manish Singh's avatar
Manish Singh committed
759
menus_init (void)
Elliot Lee's avatar
Elliot Lee committed
760
{
761 762
  int i;

Elliot Lee's avatar
Elliot Lee committed
763 764
  if (initialize)
    {
765
      gchar *filename;
Elliot Lee's avatar
Elliot Lee committed
766

767
      initialize = FALSE;
Elliot Lee's avatar
Elliot Lee committed
768

769 770
      menus_init_toolbox ();

771
      image_factory = gtk_item_factory_new (GTK_TYPE_MENU, "<Image>", NULL);
Manish Singh's avatar
Manish Singh committed
772 773 774
      gtk_item_factory_set_translate_func (image_factory,
	  				   menu_translate,
	  				   NULL, NULL);
775 776
      gtk_item_factory_create_items_ac (image_factory,
					n_image_entries,
Manish Singh's avatar
Manish Singh committed
777
					image_entries,
778
					NULL, 2);
779

780
      load_factory = gtk_item_factory_new (GTK_TYPE_MENU, "<Load>", NULL);
Manish Singh's avatar
Manish Singh committed
781 782 783
      gtk_item_factory_set_translate_func (load_factory,
	  				   menu_translate,
	  				   NULL, NULL);
784 785
      gtk_item_factory_create_items_ac (load_factory,
					n_load_entries,
Manish Singh's avatar
Manish Singh committed
786
					load_entries,
787
					NULL, 2);
788

789
      save_factory = gtk_item_factory_new (GTK_TYPE_MENU, "<Save>", NULL);
Manish Singh's avatar
Manish Singh committed
790 791 792
      gtk_item_factory_set_translate_func (save_factory,
	  				   menu_translate,
	  				   NULL, NULL);
793 794
      gtk_item_factory_create_items_ac (save_factory,
					n_save_entries,
Manish Singh's avatar
Manish Singh committed
795
					save_entries,
796
					NULL, 2);
797 798

      layers_factory = gtk_item_factory_new (GTK_TYPE_MENU, "<Layers>", NULL);
Manish Singh's avatar
Manish Singh committed
799 800 801
      gtk_item_factory_set_translate_func (layers_factory,
	  				   menu_translate,
	  				   NULL, NULL);
802 803
      gtk_item_factory_create_items_ac (layers_factory,
					n_layers_entries,
Manish Singh's avatar
Manish Singh committed
804
					layers_entries,
805 806 807
					NULL, 2);

      channels_factory = gtk_item_factory_new (GTK_TYPE_MENU, "<Channels>", NULL);
Manish Singh's avatar
Manish Singh committed
808 809 810
      gtk_item_factory_set_translate_func (channels_factory,
	  				   menu_translate,
	  				   NULL, NULL);
811 812
      gtk_item_factory_create_items_ac (channels_factory,
					n_channels_entries,
Manish Singh's avatar
Manish Singh committed
813
					channels_entries,
814 815 816
					NULL, 2);

      paths_factory = gtk_item_factory_new (GTK_TYPE_MENU, "<Paths>", NULL);
Manish Singh's avatar
Manish Singh committed
817 818 819
      gtk_item_factory_set_translate_func (paths_factory,
	  				   menu_translate,
	  				   NULL, NULL);
820 821
      gtk_item_factory_create_items_ac (paths_factory,
					n_paths_entries,
Manish Singh's avatar
Manish Singh committed
822
					paths_entries,
823 824
					NULL, 2);

825 826 827 828
      for (i = 0; i < num_tools; i++)
	{
	  /* FIXME this need to use access functions to check a flag */
	  if (tool_info[i].menu_path)
Michael Natterer's avatar
Michael Natterer committed
829
	    menus_tools_create (tool_info + i);
830
	}
831

Tor Lillqvist's avatar
Tor Lillqvist committed
832
      filename = gimp_personal_rc_file ("menurc");
833 834
      gtk_item_factory_parse_rc (filename);
      g_free (filename);
Elliot Lee's avatar
Elliot Lee committed
835 836
    }
}
Manish Singh's avatar
Manish Singh committed
837 838 839 840 841

static gchar *
menu_translate (const gchar *path,
    		gpointer     data)
{
842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860
  static gchar menupath[256];
  gchar *retval;

  retval = gettext (path);
  if (!strcmp (path, retval))
    {
      strcpy (menupath, "<Image>");
      strncat (menupath, path, sizeof(menupath) - sizeof("<Image>"));
      retval = dgettext ("gimp-std-plugins", menupath) + strlen ("<Image>");

      if (!strcmp (path, retval))
	{
	  strcpy (menupath, "<Toolbox>");
	  strncat (menupath, path, sizeof(menupath) - sizeof("<Toolbox>"));
	  retval = dgettext ("gimp-std-plugins", menupath) + strlen ("<Toolbox>");
    	}
    }

  return retval;
Manish Singh's avatar
Manish Singh committed
861
}
862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915

static gint
tearoff_delete_cb (GtkWidget *widget, 
		   GdkEvent  *event,
		   gpointer   data)
{
  /* Unregister if dialog is deleted as well */
  dialog_unregister((GtkWidget *)data);
  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;