Just some CVS ignore stuff.
[dia.git] / app / menus.c
blobdbb7b5e602532b8018a31ae83b590275de40918b
1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 1998 Alexander Larsson
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
23 #include <gtk/gtk.h>
24 #include <gdk/gdkkeysyms.h>
25 #include <string.h>
27 #include "intl.h"
28 #include "menus.h"
29 #include "tool.h"
30 #include "commands.h"
31 #include "message.h"
32 #include "interface.h"
33 #include "display.h"
34 #include "filedlg.h"
35 #include "plugin-manager.h"
36 #include "select.h"
37 #include "dia_dirs.h"
38 #include "diagram_tree_window.h"
39 #include "object_ops.h"
40 #include "sheets.h"
41 #include "dia-app-icons.h"
43 static void plugin_callback (GtkWidget *widget, gpointer data);
45 #define MRU_MENU_ENTRY_SIZE (strlen ("/File/MRU00 ") + 1)
46 #define MRU_MENU_ACCEL_SIZE sizeof ("<control>0")
48 static GtkItemFactoryEntry toolbox_menu_items[] =
50 {N_("/_File"), NULL, NULL, 0, "<Branch>" },
51 { "/File/tearoff", NULL, NULL, 0, "<Tearoff>" },
52 {N_("/File/_New"), "<control>N", file_new_callback, 0,
53 "<StockItem>", GTK_STOCK_NEW },
54 {N_("/File/_Open..."), "<control>O", file_open_callback, 0,
55 "<StockItem>", GTK_STOCK_OPEN },
56 /* {N_("/Open _Recent"), NULL, NULL, 0, "<Branch>"}, */
57 /* { "/Open Recent/tearoff", NULL, NULL, 0, "<Tearoff>" }, */
58 {N_("/File/---"), NULL, NULL, 0, "<Separator>" },
59 {N_("/File/_Diagram tree"), "F8", diagtree_show_callback, 0,
60 "<ToggleItem>" },
61 {N_("/File/Sheets and Objects..."),
62 "F9", sheets_dialog_show_callback, 0 },
63 {N_("/File/---"), NULL, NULL, 0, "<Separator>" },
64 {N_("/File/_Preferences..."),NULL, file_preferences_callback, 0,
65 "<StockItem>", GTK_STOCK_PREFERENCES },
66 {N_("/File/P_lugins..."), NULL, file_plugins_callback, 0,
67 "<StockItem>", GTK_STOCK_EXECUTE },
68 {N_("/File/---"), NULL, NULL, 0, "<Separator>" },
69 /* recent file list is dynamically inserted here */
70 {N_("/File/---"), NULL, NULL, 0, "<Separator>" },
71 {N_("/File/_Quit"), "<control>Q", file_quit_callback, 0,
72 "<StockItem>", GTK_STOCK_QUIT },
73 {N_("/_Help"), NULL, NULL, 0, "<Branch>" },
74 { "/Help/tearoff", NULL, NULL, 0, "<Tearoff>" },
75 {N_("/Help/_Contents"), "F1", help_manual_callback, 0,
76 "<StockItem>", GTK_STOCK_HELP },
77 {N_("/Help/---"), NULL, NULL, 0, "<Separator>" },
78 {N_("/Help/_About..."), NULL, help_about_callback, 0 }
81 /* calculate the number of menu_item's */
82 static int toolbox_nmenu_items = sizeof(toolbox_menu_items) / sizeof(toolbox_menu_items[0]);
84 /* this one is needed while we create the menubar in GTK instead of Gnome */
85 static GtkItemFactoryEntry display_menu_items[] =
87 { "/tearoff", NULL, NULL, 0, "<Tearoff>" },
88 {N_("/_File"), NULL, NULL, 0, "<Branch>"},
89 { "/File/tearoff", NULL, NULL, 0, "<Tearoff>" },
90 {N_("/File/_New"), "<control>N", file_new_callback, 0,
91 "<StockItem>", GTK_STOCK_NEW },
92 {N_("/File/_Open..."), "<control>O", file_open_callback, 0,
93 "<StockItem>", GTK_STOCK_OPEN },
94 /* {N_("/Open _Recent"), NULL, NULL, 0, "<Branch>"}, */
95 /* { "/Open Recent/tearoff", NULL, NULL, 0, "<Tearoff>" }, */
96 {N_("/File/---"), NULL, NULL, 0, "<Separator>"},
97 {N_("/File/_Save"), "<control>S", file_save_callback, 0,
98 "<StockItem>", GTK_STOCK_SAVE },
99 {N_("/File/Save _As..."), "<control><shift>S", file_save_as_callback, 0,
100 "<StockItem>", GTK_STOCK_SAVE_AS },
101 {N_("/File/_Export..."), NULL, file_export_callback, 0,
102 "<StockItem>", GTK_STOCK_CONVERT},
103 {N_("/File/---"), NULL, NULL, 0, "<Separator>"},
104 {N_("/File/Page Set_up..."), NULL, file_pagesetup_callback, 0},
105 {N_("/File/_Print Diagram..."), "<control>P", file_print_callback, 0,
106 "<StockItem>", GTK_STOCK_PRINT },
107 {N_("/File/---"), NULL, NULL, 0, "<Separator>"},
108 {N_("/File/_Close"), "<control>W", file_close_callback, 0,
109 "<StockItem>", GTK_STOCK_CLOSE },
110 { "/File/---MRU", NULL, NULL, 0, "<Separator>"},
111 {N_("/File/_Quit"), "<control>Q", file_quit_callback, 0,
112 "<StockItem>", GTK_STOCK_QUIT},
113 {N_("/_Edit"), NULL, NULL, 0, "<Branch>"},
114 { "/Edit/tearoff", NULL, NULL, 0, "<Tearoff>" },
115 {N_("/Edit/_Undo"), "<control>Z", edit_undo_callback, 0,
116 "<StockItem>", GTK_STOCK_UNDO },
117 {N_("/Edit/_Redo"), "<control><shift>Z", edit_redo_callback, 0,
118 "<StockItem>", GTK_STOCK_REDO },
119 {N_("/Edit/---"), NULL, NULL, 0, "<Separator>" },
120 {N_("/Edit/_Copy"), "<control>C", edit_copy_callback, 0,
121 "<StockItem>", GTK_STOCK_COPY },
122 {N_("/Edit/C_ut"), "<control>X", edit_cut_callback, 0,
123 "<StockItem>", GTK_STOCK_CUT },
124 {N_("/Edit/_Paste"), "<control>V", edit_paste_callback, 0,
125 "<StockItem>", GTK_STOCK_PASTE },
126 {N_("/Edit/_Duplicate"), "<control>D", edit_duplicate_callback, 0, },
127 {N_("/Edit/_Delete"), "Delete", edit_delete_callback, 0,
128 "<StockItem>", GTK_STOCK_DELETE },
129 {N_("/Edit/---"), NULL, NULL, 0, "<Separator>" },
130 /* the following used to bind to <control><shift>C which collides with Unicode input. <control>>alt> doesn't work either */
131 {N_("/Edit/Copy Text"), NULL, edit_copy_text_callback, 0,
132 "<StockItem>", GTK_STOCK_COPY },
133 {N_("/Edit/Cut Text"), "<control><shift>X", edit_cut_text_callback, 0,
134 "<StockItem>", GTK_STOCK_CUT },
135 {N_("/Edit/Paste _Text"), "<control><shift>V", edit_paste_text_callback, 0,
136 "<StockItem>", GTK_STOCK_PASTE },
137 {N_("/_Diagram"), NULL, NULL, 0, "<Branch>"},
138 { "/Diagram/tearoff", NULL, NULL, 0, "<Tearoff>" },
139 {N_("/Diagram/_Properties..."), NULL, view_diagram_properties_callback, 0,
140 "<StockItem>", GTK_STOCK_PROPERTIES},
141 {N_("/Diagram/_Layers..."), NULL, dialogs_layers_callback, 0},
142 {N_("/_View"), NULL, NULL, 0, "<Branch>"},
143 { "/View/tearoff", NULL, NULL, 0, "<Tearoff>" },
144 {N_("/View/Zoom _In"), "<control>+", view_zoom_in_callback, 0,
145 "<StockItem>", GTK_STOCK_ZOOM_IN },
146 {N_("/View/Zoom _Out"), "<control>-", view_zoom_out_callback, 0,
147 "<StockItem>", GTK_STOCK_ZOOM_OUT },
148 {N_("/View/_Zoom"), NULL, NULL, 0, "<Branch>"},
149 { "/View/Zoom/tearoff", NULL, NULL, 0, "<Tearoff>" },
150 {N_("/View/Zoom/1600%"), NULL, view_zoom_set_callback, 16000},
151 {N_("/View/Zoom/800%"), NULL, view_zoom_set_callback, 8000},
152 {N_("/View/Zoom/400%"), "<alt>4", view_zoom_set_callback, 4000},
153 {N_("/View/Zoom/283%"), NULL, view_zoom_set_callback, 2828},
154 {N_("/View/Zoom/200%"), "<alt>2", view_zoom_set_callback, 2000},
155 {N_("/View/Zoom/141%"), NULL, view_zoom_set_callback, 1414},
156 {N_("/View/Zoom/100%"), "<alt>1", view_zoom_set_callback, 1000,
157 "<StockItem>", GTK_STOCK_ZOOM_100 },
158 {N_("/View/Zoom/85%"), NULL, view_zoom_set_callback, 850},
159 {N_("/View/Zoom/70.7%"), NULL, view_zoom_set_callback, 707},
160 {N_("/View/Zoom/50%"), "<alt>5", view_zoom_set_callback, 500},
161 {N_("/View/Zoom/35.4%"), NULL, view_zoom_set_callback, 354},
162 {N_("/View/Zoom/25%"), NULL, view_zoom_set_callback, 250},
163 {N_("/View/---"), NULL, NULL, 0, "<Separator>" },
164 {N_("/View/Fullscr_een"), "F11", view_fullscreen_callback, 0, "<ToggleItem>"},
165 #ifdef HAVE_LIBART
166 {N_("/View/_AntiAliased"), NULL, view_aa_callback, 0, "<ToggleItem>"},
167 #endif
168 {N_("/View/Show _Grid"), NULL, view_visible_grid_callback, 0, "<ToggleItem>"},
169 {N_("/View/_Snap To Grid"), NULL, view_snap_to_grid_callback, 0, "<ToggleItem>"},
170 {N_("/View/Snap To _Objects"), NULL, view_snap_to_objects_callback, 0, "<ToggleItem>"},
171 {N_("/View/Show _Rulers"), NULL, view_toggle_rulers_callback,0, "<ToggleItem>"},
172 {N_("/View/Show _Connection Points"), NULL, view_show_cx_pts_callback, 0, "<ToggleItem>"},
173 {N_("/View/---"), NULL, NULL, 0, "<Separator>"},
174 {N_("/View/New _View"), NULL, view_new_view_callback, 0},
175 {N_("/View/C_lone View"), NULL, view_clone_view_callback, 0},
176 /* Show All, Best Fit. Same as the Gimp, Ctrl+E */
177 {N_("/View/Show _All"), "<control>E", view_show_all_callback, 0,
178 "<StockItem>", GTK_STOCK_ZOOM_FIT },
179 {N_("/View/Re_draw"), NULL, view_redraw_callback, 0,
180 "<StockItem>", GTK_STOCK_REFRESH },
181 {N_("/_Objects"), NULL, NULL, 0, "<Branch>"},
182 { "/Objects/tearoff", NULL, NULL, 0, "<Tearoff>" },
183 {N_("/Objects/Send to _Back"), "<control>B",objects_place_under_callback, 0,
184 "<StockItem>", GTK_STOCK_GOTO_BOTTOM },
185 {N_("/Objects/Bring to _Front"),"<control>F", objects_place_over_callback,0,
186 "<StockItem>", GTK_STOCK_GOTO_TOP},
187 {N_("/Objects/Send Backwards"), NULL, objects_place_down_callback,0,
188 "<StockItem>", GTK_STOCK_GO_DOWN},
189 {N_("/Objects/Bring Forwards"), NULL, objects_place_up_callback,0,
190 "<StockItem>", GTK_STOCK_GO_UP},
191 {N_("/Objects/---"), NULL, NULL, 0, "<Separator>"},
192 {N_("/Objects/_Group"), "<control>G", objects_group_callback, 0,
193 "<ImageItem>", dia_group_icon},
194 /* deliberately not using Ctrl+U for Ungroup */
195 {N_("/Objects/_Ungroup"), "<control><shift>G", objects_ungroup_callback, 0,
196 "<ImageItem>", dia_ungroup_icon},
197 {N_("/Objects/---"), NULL, NULL, 0, "<Separator>"},
198 {N_("/Objects/_Parent"), "<control>L", objects_parent_callback, 0},
199 {N_("/Objects/_Unparent"), "<control><shift>L", objects_unparent_callback, 0},
200 {N_("/Objects/_Unparent Children"), NULL, objects_unparent_children_callback, 0},
201 {N_("/Objects/---"), NULL, NULL, 0, "<Separator>"},
202 {N_("/Objects/Align"), NULL, NULL, 0, "<Branch>"},
203 { "/Objects/Align/tearoff", NULL, NULL, 0, "<Tearoff>" },
204 {N_("/Objects/Align/Left"), NULL, objects_align_h_callback, DIA_ALIGN_LEFT,
205 "<StockItem>", GTK_STOCK_JUSTIFY_LEFT },
206 {N_("/Objects/Align/Center"), NULL, objects_align_h_callback, DIA_ALIGN_CENTER,
207 "<StockItem>", GTK_STOCK_JUSTIFY_CENTER},
208 {N_("/Objects/Align/Right"), NULL, objects_align_h_callback, DIA_ALIGN_RIGHT,
209 "<StockItem>", GTK_STOCK_JUSTIFY_RIGHT},
210 {N_("/Objects/Align/---"), NULL, NULL, 0, "<Separator>"},
211 {N_("/Objects/Align/Top"), NULL, objects_align_v_callback, DIA_ALIGN_TOP},
212 {N_("/Objects/Align/Middle"), NULL, objects_align_v_callback, DIA_ALIGN_CENTER},
213 {N_("/Objects/Align/Bottom"), NULL, objects_align_v_callback, DIA_ALIGN_BOTTOM},
214 {N_("/Objects/Align/---"), NULL, NULL, 0, "<Separator>"},
215 {N_("/Objects/Align/Spread Out Horizontally"), NULL, objects_align_h_callback, DIA_ALIGN_EQUAL},
216 {N_("/Objects/Align/Spread Out Vertically"), NULL, objects_align_v_callback, DIA_ALIGN_EQUAL},
217 {N_("/Objects/Align/Adjacent"), NULL, objects_align_h_callback, DIA_ALIGN_ADJACENT},
218 {N_("/Objects/Align/Stacked"), NULL, objects_align_v_callback, DIA_ALIGN_ADJACENT},
219 {N_("/Objects/---"), NULL, NULL, 0, "<Separator>"},
220 {N_("/Objects/_Properties..."), NULL, dialogs_properties_callback, 0,
221 "<StockItem>", GTK_STOCK_PROPERTIES},
222 {N_("/_Select"), NULL, NULL, 0, "<Branch>"},
223 { "/Select/tearoff", NULL, NULL, 0, "<Tearoff>" },
224 {N_("/Select/All"), "<control>A", select_all_callback, 0},
225 {N_("/Select/None"), NULL, select_none_callback, 0},
226 {N_("/Select/Invert"), "<control>I", select_invert_callback, 0},
227 {N_("/Select/---"), NULL, NULL, 0, "<Separator>"},
228 {N_("/Select/Transitive"), "<control>T", select_transitive_callback, 0},
229 {N_("/Select/Connected"), "<control><shift>T", select_connected_callback, 0},
230 {N_("/Select/Same Type"), NULL, select_same_type_callback, 0},
231 {N_("/Select/---"), NULL, NULL, 0, "<Separator>"},
232 {N_("/Select/Replace"), NULL, select_style_callback,
233 SELECT_REPLACE, "<RadioItem>"},
234 {N_("/Select/Union"), NULL, select_style_callback,
235 SELECT_UNION, "/Select/Replace"},
236 {N_("/Select/Intersection"), NULL, select_style_callback,
237 SELECT_INTERSECTION, "/Select/Replace"},
238 {N_("/Select/Remove"), NULL, select_style_callback,
239 SELECT_REMOVE, "/Select/Replace"},
240 /* Cannot also be called Invert, duplicate names caused keybinding problems */
241 {N_("/Select/Inverse"), NULL, select_style_callback,
242 SELECT_INVERT, "/Select/Replace"},
243 {N_("/_Tools"), NULL, NULL, 0, "<Branch>"},
244 { "/Tools/tearoff", NULL, NULL, 0, "<Tearoff>" },
245 {N_("/Tools/Modify"), "<alt>.", NULL, 0},
246 {N_("/Tools/Magnify"), "<alt>M", NULL, 0},
247 {N_("/Tools/Scroll"), "<alt>S", NULL, 0},
248 {N_("/Tools/Text"), "<alt>T", NULL, 0},
249 {N_("/Tools/Box"), "<alt>R", NULL, 0},
250 {N_("/Tools/Ellipse"), "<alt>E", NULL, 0},
251 {N_("/Tools/Polygon"), "<alt>P", NULL, 0},
252 {N_("/Tools/Beziergon"), "<alt>B", NULL, 0},
253 {N_("/Tools/---"), NULL, NULL, 0, "<Separator>" },
254 {N_("/Tools/Line"), "<alt>L", NULL, 0},
255 {N_("/Tools/Arc"), "<alt>A", NULL, 0},
256 {N_("/Tools/Zigzagline"), "<alt>Z", NULL, 0},
257 {N_("/Tools/Polyline"), NULL, NULL, 0},
258 {N_("/Tools/Bezierline"), "<alt>C", NULL, 0},
259 {N_("/Tools/---"), NULL, NULL, 0, "<Separator>" },
260 {N_("/Tools/Image"), "<alt>I", NULL, 0},
261 {N_("/_Input Methods"), NULL, NULL, 0, "<Branch>"},
262 { "/Input Methods/tearoff", NULL, NULL, 0, "<Tearoff>" },
263 {N_("/_Help"), NULL, NULL, 0, "<Branch>" },
264 { "/Help/tearoff", NULL, NULL, 0, "<Tearoff>" },
265 {N_("/Help/_Contents"), "F1", help_manual_callback, 0,
266 "<StockItem>", GTK_STOCK_HELP },
267 {N_("/Help/---"), NULL, NULL, 0, "<Separator>" },
268 {N_("/Help/_About..."), NULL, help_about_callback, 0,
269 /* FOR 2.6 "<StockItem>", GTK_STOCK_ABOUT */},
272 static int display_nmenu_items = (sizeof(display_menu_items) /
273 sizeof(display_menu_items[0]));
276 /* need initialisation? */
277 static gboolean initialise = TRUE;
279 /* the actual menus */
280 static GtkWidget *toolbox_menubar = NULL;
281 static GtkAccelGroup *toolbox_accels = NULL;
282 static GtkWidget *display_menus = NULL;
283 static GtkAccelGroup *display_accels = NULL;
285 static GtkItemFactory *toolbox_item_factory = NULL;
286 static GtkItemFactory *display_item_factory = NULL;
288 #ifdef ENABLE_NLS
290 static gchar *
291 menu_translate (const gchar *path,
292 gpointer data)
294 static gchar *menupath = NULL;
296 GtkItemFactory *item_factory = NULL;
297 gchar *retval;
298 gchar *factory;
299 gchar *translation;
300 gchar *domain = NULL;
301 gchar *complete = NULL;
302 gchar *p, *t;
304 factory = (gchar *) data;
306 if (menupath)
307 g_free (menupath);
309 retval = menupath = g_strdup (path);
311 if ((strstr (path, "/tearoff1") != NULL) ||
312 (strstr (path, "/---") != NULL) ||
313 (strstr (path, "/MRU") != NULL))
314 return retval;
316 if (factory)
317 item_factory = gtk_item_factory_from_path (factory);
318 if (item_factory)
320 domain = gtk_object_get_data (GTK_OBJECT (item_factory), "textdomain");
321 complete = gtk_object_get_data (GTK_OBJECT (item_factory), "complete");
324 if (domain) /* use the plugin textdomain */
326 g_free (menupath);
327 menupath = g_strconcat (factory, path, NULL);
329 if (complete)
332 * This is a branch, use the complete path for translation,
333 * then strip off entries from the end until it matches.
335 complete = g_strconcat (factory, complete, NULL);
336 translation = g_strdup (dgettext (domain, complete));
338 while (*complete && *translation && strcmp (complete, menupath))
340 p = strrchr (complete, '/');
341 t = strrchr (translation, '/');
342 if (p && t)
344 *p = '\0';
345 *t = '\0';
347 else
348 break;
351 g_free (complete);
353 else
355 translation = dgettext (domain, menupath);
359 * Work around a bug in GTK+ prior to 1.2.7 (similar workaround below)
361 if (strncmp (factory, translation, strlen (factory)) == 0)
363 retval = translation + strlen (factory);
364 if (complete)
366 g_free (menupath);
367 menupath = translation;
370 else
372 g_warning ("bad translation for menupath: %s", menupath);
373 retval = menupath + strlen (factory);
374 if (complete)
375 g_free (translation);
378 else /* use the dia textdomain */
380 if (complete)
383 * This is a branch, use the complete path for translation,
384 * then strip off entries from the end until it matches.
386 complete = g_strdup (complete);
387 translation = g_strdup (gettext (complete));
389 while (*complete && *translation && strcmp (complete, menupath))
391 p = strrchr (complete, '/');
392 t = strrchr (translation, '/');
393 if (p && t)
395 *p = '\0';
396 *t = '\0';
398 else
399 break;
401 g_free (complete);
403 else
404 translation = gettext (menupath);
406 if (*translation == '/')
408 retval = translation;
409 if (complete)
411 g_free (menupath);
412 menupath = translation;
415 else
417 g_warning ("bad translation for menupath: %s", menupath);
418 if (complete)
419 g_free (translation);
423 return retval;
426 #endif /* ENABLE_NLS */
428 static void
429 tool_menu_select(GtkWidget *w, gpointer data) {
430 ToolButtonData *tooldata = (ToolButtonData *) data;
432 if (tooldata == NULL) {
433 g_warning(_("NULL tooldata in tool_menu_select"));
434 return;
437 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tooldata->widget),TRUE);
440 static gint
441 save_accels(gpointer data)
443 gchar *accelfilename;
445 accelfilename = dia_config_filename("menurc");
446 if (accelfilename) {
447 gtk_accel_map_save (accelfilename);
448 g_free (accelfilename);
450 return TRUE;
455 Purpose: set the generic callback for all the items in the menu "Tools"
457 static void
458 menus_set_tools_callback (const char * menu_name, GtkItemFactory *item_factory)
460 gint i, len;
461 GString *path;
462 GtkMenuItem *menuitem;
464 path = g_string_new(menu_name);
465 g_string_append(path, "/Tools/");
466 len = path->len;
467 for (i = 0; i < num_tools; i++) {
468 g_string_append(path, tool_data[i].menuitem_name);
469 menuitem = menus_get_item_from_path(path->str, item_factory);
470 if (menuitem != NULL)
471 g_signal_connect(GTK_OBJECT(menuitem), "activate",
472 G_CALLBACK(tool_menu_select),
473 &tool_data[i].callback_data);
474 else
475 g_warning ("couldn't find tool menu item %s", path->str);
476 g_string_truncate(path, len);
478 g_string_free(path, TRUE);
482 static void
483 menus_init(void)
485 gchar *accelfilename;
486 GList *cblist;
488 if (!initialise)
489 return;
491 initialise = FALSE;
493 /* the toolbox menu */
494 toolbox_accels = gtk_accel_group_new();
495 toolbox_item_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<Toolbox>",
496 toolbox_accels);
497 gtk_object_set_data (GTK_OBJECT (toolbox_item_factory), "factory_path",
498 (gpointer) "toolbox");
499 #ifdef ENABLE_NLS
500 gtk_item_factory_set_translate_func (toolbox_item_factory, menu_translate,
501 "<Toolbox>", NULL);
502 #endif
503 gtk_item_factory_create_items (toolbox_item_factory,
504 toolbox_nmenu_items,
505 toolbox_menu_items,
506 NULL);
508 toolbox_menubar = gtk_item_factory_get_widget(toolbox_item_factory,
509 "<Toolbox>");
511 /* the display menu */
512 display_accels = gtk_accel_group_new();
513 display_item_factory = gtk_item_factory_new(GTK_TYPE_MENU, "<Display>",
514 display_accels);
515 #ifdef ENABLE_NLS
516 gtk_item_factory_set_translate_func (display_item_factory, menu_translate,
517 "<Display>", NULL);
518 #endif
519 gtk_item_factory_create_items (display_item_factory,
520 display_nmenu_items,
521 display_menu_items,
522 NULL);
524 display_menus = gtk_item_factory_get_widget(display_item_factory,
525 "<Display>");
526 gtk_menu_set_accel_path(GTK_MENU(display_menus), "<Display>/");
528 menus_set_tools_callback ("<Display>", NULL);
530 gtk_menu_set_title(GTK_MENU(display_menus), _("Diagram Menu"));
532 /* initialize callbacks from plug-ins */
533 for (cblist = filter_get_callbacks(); cblist; cblist = cblist->next) {
534 DiaCallbackFilter *cbf = cblist->data;
535 GtkWidget *newitem;
537 newitem = menus_add_path(cbf->menupath);
538 if (!newitem) {
539 g_warning("Don't know where to add \"%s\" menu entry.", cbf->menupath);
540 continue;
542 g_signal_connect(GTK_OBJECT(newitem), "activate",
543 G_CALLBACK(plugin_callback), cbf);
544 } /* for filter_callbacks */
546 /* load accelerators and prepare to later save them */
547 accelfilename = dia_config_filename("menurc");
549 if (accelfilename) {
550 gtk_accel_map_load(accelfilename);
551 g_free(accelfilename);
553 gtk_quit_add(1, save_accels, NULL);
557 void
558 menus_get_toolbox_menubar (GtkWidget **menubar,
559 GtkAccelGroup **accel_group)
561 if (initialise)
562 menus_init();
564 if (menubar)
565 *menubar = toolbox_menubar;
566 if (accel_group)
567 *accel_group = toolbox_accels;
570 void
571 menus_get_image_menu (GtkWidget **menu,
572 GtkAccelGroup **accel_group)
574 if (initialise)
575 menus_init();
577 if (menu)
578 *menu = display_menus;
579 if (accel_group)
580 *accel_group = display_accels;
583 void
584 menus_get_image_menubar (GtkWidget **menu, GtkItemFactory **display_mbar_item_factory)
586 if (menu)
588 GtkAccelGroup *display_mbar_accel_group;
589 display_mbar_accel_group = gtk_accel_group_new ();
590 *display_mbar_item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR,
591 "<DisplayMBar>",
592 display_mbar_accel_group);
593 #ifdef ENABLE_NLS
594 gtk_item_factory_set_translate_func (*display_mbar_item_factory,
595 menu_translate,
596 "<DisplayMBar>", NULL);
597 #endif
598 gtk_item_factory_create_items (*display_mbar_item_factory,
599 display_nmenu_items - 1,
600 &(display_menu_items[1]), NULL);
602 *menu = gtk_item_factory_get_widget (*display_mbar_item_factory, "<DisplayMBar>");
603 menus_set_tools_callback ("<DisplayMBar>", *display_mbar_item_factory);
608 GtkWidget *
609 menus_add_path (const gchar *path)
611 GtkItemFactory *item_factory;
612 GtkItemFactoryEntry new_entry = { 0 };
614 new_entry.item_type = "<Item>";
615 new_entry.accelerator = NULL;
616 new_entry.callback = NULL;
617 new_entry.callback_action = 0;
619 if (strncmp(path, "<Display>/", strlen("<Display>/")) == 0) {
620 item_factory = display_item_factory;
621 new_entry.path = (gchar *) (path + strlen("<Display>"));
622 } else if (strncmp(path, "<Toolbox>/", strlen("<Toolbox>/")) == 0) {
623 item_factory = toolbox_item_factory;
624 new_entry.path = (gchar *) (path + strlen("<Toolbox>"));
625 } else {
626 g_warning("bad menu path `%s'", path);
627 return NULL;
630 gtk_item_factory_create_item(item_factory, &new_entry, NULL, 1);
631 return gtk_item_factory_get_widget(item_factory, path);
636 Get a menu item widget from a path.
637 In case of an item in the <DisplayMBar> menu bar, provide the corresponding
638 item factory: ddisp->mbar_item_factory.
640 GtkMenuItem *
641 menus_get_item_from_path (char *path, GtkItemFactory *item_factory)
643 GtkWidget *wid = NULL;
644 GtkMenuItem *widget = NULL;
646 if (display_item_factory) {
647 wid =
648 gtk_item_factory_get_item(display_item_factory, path);
649 if (wid != NULL) widget = GTK_MENU_ITEM(wid);
652 if ((widget == NULL) && (item_factory)) {
653 wid =
654 gtk_item_factory_get_item(item_factory, path);
655 if (wid != NULL) widget = GTK_MENU_ITEM(wid);
658 if (widget == NULL) {
659 wid =
660 gtk_item_factory_get_item(toolbox_item_factory, path);
661 if (wid != NULL) widget = GTK_MENU_ITEM(wid);
664 if (! widget) {
665 g_warning(_("Can't find menu entry '%s'!\nThis is probably a i18n problem "
666 "(try LANG=C)."), path);
669 return widget;
673 void
674 menus_initialize_updatable_items (UpdatableMenuItems *items,
675 GtkItemFactory *factory, const char *display)
677 static GString *path;
679 path = g_string_new (display);
680 g_string_append (path,"/Edit/Copy");
681 items->copy = menus_get_item_from_path(path->str, factory);
682 g_string_append (g_string_assign(path, display),"/Edit/Cut");
683 items->cut = menus_get_item_from_path(path->str, factory);
684 g_string_append (g_string_assign(path, display),"/Edit/Paste");
685 items->paste = menus_get_item_from_path(path->str, factory);
686 g_string_append (g_string_assign(path, display),"/Edit/Delete");
687 items->edit_delete = menus_get_item_from_path(path->str, factory);
689 g_string_append (g_string_assign(path, display),"/Edit/Copy Text");
690 items->copy_text = menus_get_item_from_path(path->str, factory);
691 g_string_append (g_string_assign(path, display),"/Edit/Cut Text");
692 items->cut_text = menus_get_item_from_path(path->str, factory);
693 g_string_append (g_string_assign(path, display),"/Edit/Paste Text");
694 items->paste_text = menus_get_item_from_path(path->str, factory);
696 g_string_append (g_string_assign(path, display),"/Objects/Send to Back");
697 items->send_to_back = menus_get_item_from_path(path->str, factory);
698 g_string_append (g_string_assign(path, display),"/Objects/Bring to Front");
699 items->bring_to_front = menus_get_item_from_path(path->str, factory);
700 g_string_append (g_string_assign(path, display),"/Objects/Send Backwards");
701 items->send_backwards = menus_get_item_from_path(path->str, factory);
702 g_string_append (g_string_assign(path, display),"/Objects/Bring Forwards");
703 items->bring_forwards = menus_get_item_from_path(path->str, factory);
705 g_string_append (g_string_assign(path, display),"/Objects/Group");
706 items->group = menus_get_item_from_path(path->str, factory);
707 g_string_append (g_string_assign(path, display),"/Objects/Ungroup");
708 items->ungroup = menus_get_item_from_path(path->str, factory);
710 g_string_append (g_string_assign(path, display),"/Objects/Parent");
711 items->parent = menus_get_item_from_path(path->str, factory);
712 g_string_append (g_string_assign(path, display),"/Objects/Unparent");
713 items->unparent = menus_get_item_from_path(path->str, factory);
714 g_string_append (g_string_assign(path, display),"/Objects/Unparent Children");
715 items->unparent_children = menus_get_item_from_path(path->str, factory);
717 g_string_append (g_string_assign(path, display),"/Objects/Align/Left");
718 items->align_h_l = menus_get_item_from_path(path->str, factory);
719 g_string_append (g_string_assign(path, display),"/Objects/Align/Center");
720 items->align_h_c = menus_get_item_from_path(path->str, factory);
721 g_string_append (g_string_assign(path, display),"/Objects/Align/Right");
722 items->align_h_r = menus_get_item_from_path(path->str, factory);
723 g_string_append (g_string_assign(path, display),"/Objects/Align/Spread Out Horizontally");
724 items->align_h_e = menus_get_item_from_path(path->str, factory);
725 g_string_append (g_string_assign(path, display),"/Objects/Align/Adjacent");
726 items->align_h_a = menus_get_item_from_path(path->str, factory);
727 g_string_append (g_string_assign(path, display),"/Objects/Align/Top");
728 items->align_v_t = menus_get_item_from_path(path->str, factory);
729 g_string_append (g_string_assign(path, display),"/Objects/Align/Middle");
730 items->align_v_c = menus_get_item_from_path(path->str, factory);
731 g_string_append (g_string_assign(path, display),"/Objects/Align/Bottom");
732 items->align_v_b = menus_get_item_from_path(path->str, factory);
733 g_string_append (g_string_assign(path, display),"/Objects/Align/Spread Out Vertically");
734 items->align_v_e = menus_get_item_from_path(path->str, factory);
735 g_string_append (g_string_assign(path, display),"/Objects/Align/Stacked");
736 items->align_v_a = menus_get_item_from_path(path->str, factory);
737 g_string_append (g_string_assign(path, display),"/Objects/Properties...");
738 items->properties = menus_get_item_from_path(path->str, factory);
740 g_string_free (path,TRUE);
744 static void
745 plugin_callback (GtkWidget *widget, gpointer data)
747 DiaCallbackFilter *cbf = data;
749 /* and finally invoke it */
750 if (cbf->callback) {
751 DDisplay *ddisp = ddisplay_active();
752 DiagramData* diadata = ddisp ? ddisp->diagram->data : NULL;
753 cbf->callback (diadata, 0, cbf->user_data);