removed #ifndef GNOME that broke the GNOME build
[dia.git] / app / menus.c
blob48d4130760008f6d426c2156e7d3f2617d5543e3
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 <string.h>
26 #ifdef GNOME
27 #include <gnome.h>
28 #endif
29 #include "intl.h"
30 #include "menus.h"
31 #include "tool.h"
32 #include "commands.h"
33 #include "message.h"
34 #include "interface.h"
35 #include "display.h"
36 #include "filedlg.h"
37 #include "plugin-manager.h"
38 #include "select.h"
39 #include "dia_dirs.h"
41 static void plugin_callback_cb ( gpointer data, guint action, GtkWidget *widget);
43 #ifdef GNOME
44 static GnomeUIInfo toolbox_filemenu[] = {
45 GNOMEUIINFO_MENU_NEW_ITEM(N_("_New diagram"), N_("Create new diagram"),
46 file_new_callback, NULL),
47 GNOMEUIINFO_MENU_OPEN_ITEM(file_open_callback, NULL),
48 GNOMEUIINFO_MENU_PREFERENCES_ITEM(file_preferences_callback, NULL),
49 GNOMEUIINFO_ITEM_NONE(N_("Plug-ins"), NULL, file_plugins_callback),
50 GNOMEUIINFO_SEPARATOR,
51 GNOMEUIINFO_MENU_EXIT_ITEM(file_quit_callback, NULL),
52 GNOMEUIINFO_END
55 static GnomeUIInfo filemenu[] = {
56 GNOMEUIINFO_MENU_NEW_ITEM(N_("_New diagram"), N_("Create new diagram"),
57 file_new_callback, NULL),
58 GNOMEUIINFO_MENU_OPEN_ITEM(file_open_callback, NULL),
59 GNOMEUIINFO_MENU_SAVE_ITEM(file_save_callback, NULL),
60 GNOMEUIINFO_MENU_PREFERENCES_ITEM(file_preferences_callback, NULL),
61 GNOMEUIINFO_MENU_SAVE_AS_ITEM(file_save_as_callback, NULL),
63 { GNOME_APP_UI_ITEM, N_("_Export..."), NULL,
64 file_export_callback, NULL, NULL },
66 GNOMEUIINFO_SEPARATOR,
67 { GNOME_APP_UI_ITEM, N_("Page Set_up..."), NULL,
68 file_pagesetup_callback, NULL, NULL },
69 { GNOME_APP_UI_ITEM, N_("_Print Diagram..."), NULL,
70 file_print_callback, NULL, NULL,
71 GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_PRINT,
72 GDK_P, GDK_CONTROL_MASK},
74 GNOMEUIINFO_SEPARATOR,
75 GNOMEUIINFO_MENU_CLOSE_ITEM(file_close_callback, NULL),
76 GNOMEUIINFO_MENU_EXIT_ITEM(file_quit_callback, NULL),
77 GNOMEUIINFO_END
80 static GnomeUIInfo editmenu[] = {
81 GNOMEUIINFO_MENU_COPY_ITEM(edit_copy_callback, NULL),
82 GNOMEUIINFO_MENU_CUT_ITEM(edit_cut_callback, NULL),
83 GNOMEUIINFO_MENU_PASTE_ITEM(edit_paste_callback, NULL),
84 { GNOME_APP_UI_ITEM, N_("_Delete"), NULL,
85 edit_delete_callback, NULL, NULL,
86 GNOME_APP_PIXMAP_STOCK, "Menu_Clear",
87 GDK_D, GDK_CONTROL_MASK },
88 GNOMEUIINFO_MENU_UNDO_ITEM(edit_undo_callback, NULL),
89 GNOMEUIINFO_MENU_REDO_ITEM(edit_redo_callback, NULL),
90 GNOMEUIINFO_ITEM_NONE(N_("Copy Text"), NULL, edit_copy_text_callback),
91 GNOMEUIINFO_ITEM_NONE(N_("Cut Text"), NULL, edit_cut_text_callback),
92 GNOMEUIINFO_ITEM_NONE(N_("Paste _Text"), NULL, edit_paste_text_callback),
93 GNOMEUIINFO_END
96 #define GNOMEUIINFO_ITEM_NONE_DATA(label, tooltip, callback, user_data) \
97 { GNOME_APP_UI_ITEM, label, tooltip, (gpointer)callback, GINT_TO_POINTER(user_data), \
98 NULL, GNOME_APP_PIXMAP_NONE, NULL, 0, (GdkModifierType) 0, NULL }
100 static GnomeUIInfo zoommenu[] = {
101 GNOMEUIINFO_ITEM_NONE_DATA("400%", NULL, view_zoom_set_callback, 4000),
102 GNOMEUIINFO_ITEM_NONE_DATA("283%", NULL, view_zoom_set_callback, 2828),
103 GNOMEUIINFO_ITEM_NONE_DATA("200%", NULL, view_zoom_set_callback, 2000),
104 GNOMEUIINFO_ITEM_NONE_DATA("141%", NULL, view_zoom_set_callback, 1414),
105 GNOMEUIINFO_ITEM_NONE_DATA("100%", NULL, view_zoom_set_callback, 1000),
106 GNOMEUIINFO_ITEM_NONE_DATA("85%", NULL, view_zoom_set_callback, 850),
107 GNOMEUIINFO_ITEM_NONE_DATA("70.7%", NULL, view_zoom_set_callback, 707),
108 GNOMEUIINFO_ITEM_NONE_DATA("50%", NULL, view_zoom_set_callback, 500),
109 GNOMEUIINFO_ITEM_NONE_DATA("35.4%", NULL, view_zoom_set_callback, 354),
110 GNOMEUIINFO_ITEM_NONE_DATA("25%", NULL, view_zoom_set_callback, 250),
111 GNOMEUIINFO_END
114 static GnomeUIInfo viewmenu[] = {
115 GNOMEUIINFO_ITEM_NONE(N_("Zoom _In"), N_("Zoom in 50%"), view_zoom_in_callback),
116 GNOMEUIINFO_ITEM_NONE(N_("Zoom _Out"), N_("Zoom out 50%"), view_zoom_out_callback),
117 GNOMEUIINFO_SUBTREE(N_("_Zoom"), zoommenu),
118 GNOMEUIINFO_ITEM_NONE(N_("Diagram Properties..."), NULL, view_diagram_properties_callback),
119 #ifdef HAVE_LIBART
120 GNOMEUIINFO_TOGGLEITEM(N_("_AntiAliased"), NULL,
121 view_aa_callback, NULL),
122 #endif
123 GNOMEUIINFO_TOGGLEITEM(N_("_Visible Grid"), NULL,
124 view_visible_grid_callback, NULL),
125 GNOMEUIINFO_TOGGLEITEM(N_("_Snap To Grid"), NULL,
126 view_snap_to_grid_callback, NULL),
127 GNOMEUIINFO_TOGGLEITEM(N_("Show _Rulers"), NULL,
128 view_toggle_rulers_callback, NULL),
129 GNOMEUIINFO_TOGGLEITEM(N_("Show _Connection Points"), NULL,
130 view_show_cx_pts_callback, NULL),
131 GNOMEUIINFO_SEPARATOR,
132 GNOMEUIINFO_ITEM_NONE(N_("New _View"), NULL, view_new_view_callback),
133 GNOMEUIINFO_ITEM_NONE(N_("Show _All"), NULL, view_show_all_callback),
134 GNOMEUIINFO_END
137 static GnomeUIInfo selecttype_radiolist[] = {
138 GNOMEUIINFO_RADIOITEM_DATA(N_("Replace"), NULL, select_style_callback,
139 GUINT_TO_POINTER(SELECT_REPLACE), NULL),
140 GNOMEUIINFO_RADIOITEM_DATA(N_("Union"), NULL, select_style_callback,
141 GUINT_TO_POINTER(SELECT_UNION), NULL),
142 GNOMEUIINFO_RADIOITEM_DATA(N_("Intersect"), NULL, select_style_callback,
143 GUINT_TO_POINTER(SELECT_INTERSECTION), NULL),
144 GNOMEUIINFO_RADIOITEM_DATA(N_("Remove"), NULL, select_style_callback,
145 GUINT_TO_POINTER(SELECT_REMOVE), NULL),
146 GNOMEUIINFO_RADIOITEM_DATA(N_("Invert"), NULL, select_style_callback,
147 GUINT_TO_POINTER(SELECT_INVERT), NULL),
148 GNOMEUIINFO_END
151 static GnomeUIInfo selectmenu[] = {
152 GNOMEUIINFO_ITEM_NONE_DATA(N_("All"), NULL, select_all_callback, 0),
153 GNOMEUIINFO_ITEM_NONE_DATA(N_("None"), NULL, select_none_callback, 0),
154 GNOMEUIINFO_ITEM_NONE_DATA(N_("Invert"), NULL, select_invert_callback, 0),
155 GNOMEUIINFO_ITEM_NONE_DATA(N_("Connected"), NULL, select_connected_callback, 0),
156 GNOMEUIINFO_ITEM_NONE_DATA(N_("Transitive"), NULL, select_transitive_callback, 0),
157 GNOMEUIINFO_ITEM_NONE_DATA(N_("Same Type"), NULL, select_same_type_callback, 0),
158 GNOMEUIINFO_SEPARATOR,
159 GNOMEUIINFO_RADIOLIST(selecttype_radiolist),
160 GNOMEUIINFO_END
163 static GnomeUIInfo objects_align_h[] = {
164 GNOMEUIINFO_ITEM_NONE_DATA(N_("Left"), NULL, objects_align_h_callback, 0),
165 GNOMEUIINFO_ITEM_NONE_DATA(N_("Center"), NULL, objects_align_h_callback, 1),
166 GNOMEUIINFO_ITEM_NONE_DATA(N_("Right"), NULL, objects_align_h_callback, 2),
167 GNOMEUIINFO_ITEM_NONE_DATA(N_("Equal Distance"), NULL, objects_align_h_callback, 4),
168 GNOMEUIINFO_ITEM_NONE_DATA(N_("Adjacent"), NULL, objects_align_h_callback,5),
169 GNOMEUIINFO_END
172 static GnomeUIInfo objects_align_v[] = {
173 GNOMEUIINFO_ITEM_NONE_DATA(N_("Top"), NULL, objects_align_v_callback, 0),
174 GNOMEUIINFO_ITEM_NONE_DATA(N_("Center"), NULL, objects_align_v_callback, 1),
175 GNOMEUIINFO_ITEM_NONE_DATA(N_("Bottom"), NULL, objects_align_v_callback, 2),
176 GNOMEUIINFO_ITEM_NONE_DATA(N_("Equal Distance"), NULL, objects_align_v_callback, 4),
177 GNOMEUIINFO_ITEM_NONE_DATA(N_("Adjacent"), NULL, objects_align_h_callback,5),
178 GNOMEUIINFO_END
181 static GnomeUIInfo objectsmenu[] = {
182 GNOMEUIINFO_ITEM_NONE(N_("Send to _Back"), NULL, objects_place_under_callback),
183 GNOMEUIINFO_ITEM_NONE(N_("Bring to _Front"), NULL, objects_place_over_callback),
184 GNOMEUIINFO_SEPARATOR,
185 GNOMEUIINFO_ITEM_NONE(N_("_Group"), NULL, objects_group_callback),
186 GNOMEUIINFO_ITEM_NONE(N_("_Ungroup"), NULL, objects_ungroup_callback),
187 GNOMEUIINFO_SEPARATOR,
188 GNOMEUIINFO_SUBTREE(N_("Align _Horizontal"), objects_align_h),
189 GNOMEUIINFO_SUBTREE(N_("Align _Vertical"), objects_align_v),
190 GNOMEUIINFO_END
193 static GnomeUIInfo toolsmenu[] = {
194 GNOMEUIINFO_ITEM_NONE_DATA(N_("Modify"), NULL, NULL, 0),
195 GNOMEUIINFO_ITEM_NONE_DATA(N_("Magnify"), NULL, NULL, 0),
196 GNOMEUIINFO_ITEM_NONE_DATA(N_("Scroll"), NULL, NULL, 0),
197 GNOMEUIINFO_ITEM_NONE_DATA(N_("Text"), NULL, NULL, 0),
198 GNOMEUIINFO_ITEM_NONE_DATA(N_("Box"), NULL, NULL, 0),
199 GNOMEUIINFO_ITEM_NONE_DATA(N_("Ellipse"), NULL, NULL, 0),
200 GNOMEUIINFO_ITEM_NONE_DATA(N_("Polygon"), NULL, NULL, 0),
201 GNOMEUIINFO_ITEM_NONE_DATA(N_("Beziergon"), NULL, NULL, 0),
202 GNOMEUIINFO_ITEM_NONE_DATA(N_("Line"), NULL, NULL, 0),
203 GNOMEUIINFO_ITEM_NONE_DATA(N_("Arc"), NULL, NULL, 0),
204 GNOMEUIINFO_ITEM_NONE_DATA(N_("Zigzagline"), NULL, NULL, 0),
205 GNOMEUIINFO_ITEM_NONE_DATA(N_("Polyline"), NULL, NULL, 0),
206 GNOMEUIINFO_ITEM_NONE_DATA(N_("Bezierline"), NULL, NULL, 0),
207 GNOMEUIINFO_ITEM_NONE_DATA(N_("Image"), NULL, NULL, 0),
208 GNOMEUIINFO_END
211 static GnomeUIInfo dialogsmenu[] = {
212 GNOMEUIINFO_ITEM_NONE(N_("_Properties"), NULL, dialogs_properties_callback),
213 GNOMEUIINFO_ITEM_NONE(N_("_Layers"), NULL, dialogs_layers_callback),
214 GNOMEUIINFO_END
217 static GnomeUIInfo helpmenu[] = {
218 GNOMEUIINFO_HELP("dia"),
219 GNOMEUIINFO_SEPARATOR,
220 GNOMEUIINFO_MENU_ABOUT_ITEM(help_about_callback, NULL),
221 GNOMEUIINFO_END
224 static GnomeUIInfo toolbox_menu[] = {
225 GNOMEUIINFO_MENU_FILE_TREE(toolbox_filemenu),
226 GNOMEUIINFO_MENU_HELP_TREE(helpmenu),
227 GNOMEUIINFO_END
230 static GnomeUIInfo display_menu[] = {
231 GNOMEUIINFO_MENU_FILE_TREE(filemenu),
232 GNOMEUIINFO_MENU_EDIT_TREE(editmenu),
233 GNOMEUIINFO_MENU_VIEW_TREE(viewmenu),
234 GNOMEUIINFO_SUBTREE(N_("_Select"), selectmenu),
235 GNOMEUIINFO_SUBTREE(N_("_Objects"), objectsmenu),
236 GNOMEUIINFO_SUBTREE(N_("_Tools"), toolsmenu),
237 GNOMEUIINFO_SUBTREE(N_("_Dialogs"), dialogsmenu),
238 GNOMEUIINFO_END
241 #else /* !GNOME */
243 #define MRU_MENU_ENTRY_SIZE (strlen ("/File/MRU00 ") + 1)
244 #define MRU_MENU_ACCEL_SIZE sizeof ("<control>0")
246 static GtkItemFactoryEntry toolbox_menu_items[] =
248 {N_("/_File"), NULL, NULL, 0, "<Branch>" },
249 { "/File/tearoff", NULL, NULL, 0, "<Tearoff>" },
250 {N_("/File/_New"), "<control>N", file_new_callback, 0 },
251 {N_("/File/_Open"), "<control>O", file_open_callback, 0 },
252 {N_("/File/Open _Recent"), NULL, NULL, 0, "<Branch>" },
253 {N_("/File/Open Recent/---"),
254 NULL, NULL, 0, "<Separator>" },
255 {N_("/File/_Preferences..."),NULL, file_preferences_callback, 0 },
256 {N_("/File/P_lugins"), NULL, file_plugins_callback, 0 },
257 {N_("/File/---"), NULL, NULL, 0, "<Separator>" },
258 {N_("/File/_Quit"), "<control>Q", file_quit_callback, 0 },
259 {N_("/_Help"), NULL, NULL, 0, "<Branch>" },
260 { "/Help/tearoff", NULL, NULL, 0, "<Tearoff>" },
261 {N_("/Help/_Manual"), NULL, help_manual_callback, 0 },
262 {N_("/Help/---"), NULL, NULL, 0, "<Separator>" },
263 {N_("/Help/_About"), NULL, help_about_callback, 0 },
266 static GtkItemFactoryEntry display_menu_items[] =
268 { "/tearoff", NULL, NULL, 0, "<Tearoff>" },
269 {N_("/_File"), NULL, NULL, 0, "<Branch>"},
270 { "/File/tearoff", NULL, NULL, 0, "<Tearoff>" },
271 {N_("/File/_New"), "<control>N", file_new_callback, 0},
272 {N_("/File/_Open"), "<control>O", file_open_callback, 0},
273 {N_("/File/_Save"), "<control>S", file_save_callback, 0},
274 {N_("/File/Save _As..."), "<control>W", file_save_as_callback, 0},
275 {N_("/File/_Export..."), NULL, file_export_callback, 0},
276 {N_("/File/---"), NULL, NULL, 0, "<Separator>"},
277 {N_("/File/Page Set_up..."), NULL, file_pagesetup_callback, 0},
278 {N_("/File/_Print Diagram..."), "<control>P", file_print_callback, 0},
279 {N_("/File/---"), NULL, NULL, 0, "<Separator>"},
280 {N_("/File/_Close"), NULL, file_close_callback, 0},
281 { "/File/---MRU", NULL, NULL, 0, "<Separator>"},
282 {N_("/File/_Quit"), "<control>Q", file_quit_callback, 0},
283 {N_("/_Edit"), NULL, NULL, 0, "<Branch>"},
284 { "/Edit/tearoff", NULL, NULL, 0, "<Tearoff>" },
285 {N_("/Edit/_Copy"), "<control>C", edit_copy_callback, 0},
286 {N_("/Edit/C_ut"), "<control>X", edit_cut_callback, 0},
287 {N_("/Edit/_Paste"), "<control>V", edit_paste_callback, 0},
288 {N_("/Edit/_Delete"), "<control>D", edit_delete_callback, 0},
289 {N_("/Edit/_Undo"), "<control>Z", edit_undo_callback, 0},
290 {N_("/Edit/_Redo"), "<control>R", edit_redo_callback, 0},
291 {N_("/Edit/Copy Text"), NULL, edit_copy_text_callback, 0},
292 {N_("/Edit/Cut Text"), NULL, edit_cut_text_callback, 0},
293 {N_("/Edit/Paste _Text"), NULL, edit_paste_text_callback, 0},
294 {N_("/_View"), NULL, NULL, 0, "<Branch>"},
295 { "/View/tearoff", NULL, NULL, 0, "<Tearoff>" },
296 {N_("/View/Zoom _In"), NULL, view_zoom_in_callback, 0},
297 {N_("/View/Zoom _Out"), NULL, view_zoom_out_callback, 0},
298 {N_("/View/_Zoom"), NULL, NULL, 0, "<Branch>"},
299 { "/View/Zoom/tearoff", NULL, NULL, 0, "<Tearoff>" },
300 {N_("/View/Zoom/400%"), NULL, view_zoom_set_callback, 4000},
301 {N_("/View/Zoom/283%"), NULL, view_zoom_set_callback, 2828},
302 {N_("/View/Zoom/200%"), NULL, view_zoom_set_callback, 2000},
303 {N_("/View/Zoom/141%"), NULL, view_zoom_set_callback, 1414},
304 {N_("/View/Zoom/100%"), "1", view_zoom_set_callback, 1000},
305 {N_("/View/Zoom/85%"), NULL, view_zoom_set_callback, 850},
306 {N_("/View/Zoom/70.7%"), NULL, view_zoom_set_callback, 707},
307 {N_("/View/Zoom/50%"), NULL, view_zoom_set_callback, 500},
308 {N_("/View/Zoom/35.4%"), NULL, view_zoom_set_callback, 354},
309 {N_("/View/Zoom/25%"), NULL, view_zoom_set_callback, 250},
310 {N_("/View/Diagram Properties"),NULL, view_diagram_properties_callback, 0},
311 #ifdef HAVE_LIBART
312 {N_("/View/_AntiAliased"), NULL, view_aa_callback, 0, "<ToggleItem>"},
313 #endif
314 {N_("/View/_Visible Grid"), NULL, view_visible_grid_callback, 0, "<ToggleItem>"},
315 {N_("/View/_Snap To Grid"), "G", view_snap_to_grid_callback, 0, "<ToggleItem>"},
316 {N_("/View/Show _Rulers"), NULL, view_toggle_rulers_callback,0, "<ToggleItem>"},
317 {N_("/View/Show _Connection Points"), NULL, view_show_cx_pts_callback, 0, "<ToggleItem>"},
318 {N_("/View/---"), NULL, NULL, 0, "<Separator>"},
319 {N_("/View/New _View"), "<control>I", view_new_view_callback, 0},
320 {N_("/View/Show _All"), "<control>A", view_show_all_callback, 0},
321 {N_("/_Select"), NULL, NULL, 0, "<Branch>"},
322 { "/Select/tearoff", NULL, NULL, 0, "<Tearoff>" },
323 {N_("/Select/All"), NULL, select_all_callback, 0},
324 {N_("/Select/None"), NULL, select_none_callback, 0},
325 {N_("/Select/Invert"), NULL, select_invert_callback, 0},
326 {N_("/Select/Connected"), NULL, select_connected_callback, 0},
327 {N_("/Select/Transitive"), NULL, select_transitive_callback, 0},
328 {N_("/Select/Same Type"), NULL, select_same_type_callback, 0},
329 {N_("/Select/---"), NULL, NULL, 0, "<Separator>"},
330 {N_("/Select/Replace"), NULL, select_style_callback,
331 SELECT_REPLACE, "<RadioItem>"},
332 {N_("/Select/Union"), NULL, select_style_callback,
333 SELECT_UNION, "/Select/Replace"},
334 {N_("/Select/Intersect"), NULL, select_style_callback,
335 SELECT_INTERSECTION, "/Select/Replace"},
336 {N_("/Select/Remove"), NULL, select_style_callback,
337 SELECT_REMOVE, "/Select/Replace"},
338 {N_("/Select/Invert"), NULL, select_style_callback,
339 SELECT_INVERT, "/Select/Replace"},
340 {N_("/_Objects"), NULL, NULL, 0, "<Branch>"},
341 { "/Objects/tearoff", NULL, NULL, 0, "<Tearoff>" },
342 {N_("/Objects/Send to _Back"), "<control>B",objects_place_under_callback,0},
343 {N_("/Objects/Bring to _Front"),"<control>F", objects_place_over_callback,0},
344 {N_("/Objects/---"), NULL, NULL, 0, "<Separator>"},
345 {N_("/Objects/_Group"), "<control>G", objects_group_callback, 0},
346 {N_("/Objects/_Ungroup"), "<control>U", objects_ungroup_callback, 0},
347 {N_("/Objects/---"), NULL, NULL, 0, "<Separator>"},
348 {N_("/Objects/Align _Horizontal"), NULL, NULL, 0, "<Branch>"},
349 { "/Objects/Align Horizontal/tearoff", NULL, NULL, 0, "<Tearoff>" },
350 {N_("/Objects/Align Horizontal/Left"), NULL, objects_align_h_callback, 0},
351 {N_("/Objects/Align Horizontal/Center"), NULL, objects_align_h_callback, 1},
352 {N_("/Objects/Align Horizontal/Right"), NULL, objects_align_h_callback, 2},
353 {N_("/Objects/Align Horizontal/Equal Distance"), NULL, objects_align_h_callback, 4},
354 {N_("/Objects/Align Horizontal/Adjacent"), NULL, objects_align_h_callback, 5},
355 {N_("/Objects/Align _Vertical"), NULL, NULL, 0, "<Branch>"},
356 { "/Objects/Align Vertical/tearoff", NULL, NULL, 0, "<Tearoff>" },
357 {N_("/Objects/Align Vertical/Top"), NULL, objects_align_v_callback, 0},
358 {N_("/Objects/Align Vertical/Center"), NULL, objects_align_v_callback, 1},
359 {N_("/Objects/Align Vertical/Bottom"), NULL, objects_align_v_callback, 2},
360 {N_("/Objects/Align Vertical/Equal Distance"), NULL, objects_align_v_callback, 4},
361 {N_("/Objects/Align Vertical/Adjacent"), NULL, objects_align_v_callback, 5},
363 {N_("/_Tools"), NULL, NULL, 0, "<Branch>"},
364 { "/Tools/tearoff", NULL, NULL, 0, "<Tearoff>" },
365 {N_("/Tools/Modify"), NULL, NULL, 0},
366 {N_("/Tools/Magnify"), NULL, NULL, 0},
367 {N_("/Tools/Scroll"), NULL, NULL, 0},
368 {N_("/Tools/Text"), NULL, NULL, 0},
369 {N_("/Tools/Box"), NULL, NULL, 0},
370 {N_("/Tools/Ellipse"), NULL, NULL, 0},
371 {N_("/Tools/Polygon"), NULL, NULL, 0},
372 {N_("/Tools/Beziergon"), NULL, NULL, 0},
373 {N_("/Tools/Line"), NULL, NULL, 0},
374 {N_("/Tools/Arc"), NULL, NULL, 0},
375 {N_("/Tools/Zigzagline"), NULL, NULL, 0},
376 {N_("/Tools/Polyline"), NULL, NULL, 0},
377 {N_("/Tools/Bezierline"), NULL, NULL, 0},
378 {N_("/Tools/Image"), NULL, NULL, 0},
380 {N_("/_Dialogs"), NULL, NULL, 0, "<Branch>"},
381 { "/Dialogs/tearoff", NULL, NULL, 0, "<Tearoff>" },
382 {N_("/Dialogs/_Properties"), NULL, dialogs_properties_callback, 0},
383 {N_("/Dialogs/_Layers"), NULL, dialogs_layers_callback, 0},
386 /* calculate the number of menu_item's */
387 static int toolbox_nmenu_items = (sizeof(toolbox_menu_items) /
388 sizeof(toolbox_menu_items[0]));
389 static int display_nmenu_items = (sizeof(display_menu_items) /
390 sizeof(display_menu_items[0]));
392 #endif /* !GNOME */
394 /* need initialisation? */
395 static gboolean initialise = TRUE;
397 /* the actual menus */
398 static GtkWidget *toolbox_menubar = NULL;
399 static GtkAccelGroup *toolbox_accels = NULL;
400 static GtkWidget *display_menus = NULL;
401 static GtkAccelGroup *display_accels = NULL;
403 static GtkItemFactory *toolbox_item_factory = NULL;
404 static GtkItemFactory *display_item_factory = NULL;
406 #ifndef GNOME
407 #ifdef ENABLE_NLS
409 static gchar *
410 menu_translate (const gchar *path,
411 gpointer data)
413 static gchar *menupath = NULL;
415 GtkItemFactory *item_factory = NULL;
416 gchar *retval;
417 gchar *factory;
418 gchar *translation;
419 gchar *domain = NULL;
420 gchar *complete = NULL;
421 gchar *p, *t;
423 factory = (gchar *) data;
425 if (menupath)
426 g_free (menupath);
428 retval = menupath = g_strdup (path);
430 if ((strstr (path, "/tearoff1") != NULL) ||
431 (strstr (path, "/---") != NULL) ||
432 (strstr (path, "/MRU") != NULL))
433 return retval;
435 if (factory)
436 item_factory = gtk_item_factory_from_path (factory);
437 if (item_factory)
439 domain = gtk_object_get_data (GTK_OBJECT (item_factory), "textdomain");
440 complete = gtk_object_get_data (GTK_OBJECT (item_factory), "complete");
443 if (domain) /* use the plugin textdomain */
445 g_free (menupath);
446 menupath = g_strconcat (factory, path, NULL);
448 if (complete)
451 * This is a branch, use the complete path for translation,
452 * then strip off entries from the end until it matches.
454 complete = g_strconcat (factory, complete, NULL);
455 translation = g_strdup (dgettext (domain, complete));
457 while (*complete && *translation && strcmp (complete, menupath))
459 p = strrchr (complete, '/');
460 t = strrchr (translation, '/');
461 if (p && t)
463 *p = '\0';
464 *t = '\0';
466 else
467 break;
470 g_free (complete);
472 else
474 translation = dgettext (domain, menupath);
478 * Work around a bug in GTK+ prior to 1.2.7 (similar workaround below)
480 if (strncmp (factory, translation, strlen (factory)) == 0)
482 retval = translation + strlen (factory);
483 if (complete)
485 g_free (menupath);
486 menupath = translation;
489 else
491 g_warning ("bad translation for menupath: %s", menupath);
492 retval = menupath + strlen (factory);
493 if (complete)
494 g_free (translation);
497 else /* use the dia textdomain */
499 if (complete)
502 * This is a branch, use the complete path for translation,
503 * then strip off entries from the end until it matches.
505 complete = g_strdup (complete);
506 translation = g_strdup (gettext (complete));
508 while (*complete && *translation && strcmp (complete, menupath))
510 p = strrchr (complete, '/');
511 t = strrchr (translation, '/');
512 if (p && t)
514 *p = '\0';
515 *t = '\0';
517 else
518 break;
520 g_free (complete);
522 else
523 translation = gettext (menupath);
525 if (*translation == '/')
527 retval = translation;
528 if (complete)
530 g_free (menupath);
531 menupath = translation;
534 else
536 g_warning ("bad translation for menupath: %s", menupath);
537 if (complete)
538 g_free (translation);
542 return retval;
545 #endif /* ENABLE_NLS */
546 #endif /* !GNOME */
548 static void
549 tool_menu_select(GtkWidget *w, gpointer data) {
550 ToolButtonData *tooldata = (ToolButtonData *) data;
552 if (tooldata == NULL) {
553 g_warning(_("NULL tooldata in tool_menu_select"));
554 return;
557 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tooldata->widget),TRUE);
560 static gint
561 save_accels(gpointer data)
563 gchar *accelfilename;
565 accelfilename = dia_config_filename("menurc");
566 if (accelfilename) {
567 gtk_item_factory_dump_rc (accelfilename, NULL, TRUE);
568 g_free (accelfilename);
570 return TRUE;
573 #ifdef GNOME
574 /* create the GnomeUIBuilderData structure that connects the callbacks
575 * so that they have the same signature as type 1 GtkItemFactory
576 * callbacks */
578 static void
579 dia_menu_signal_proxy (GtkWidget *widget, GnomeUIInfo *uiinfo)
581 GtkItemFactoryCallback1 signal_handler =
582 (GtkItemFactoryCallback1)uiinfo->moreinfo;
583 guint action = GPOINTER_TO_UINT (uiinfo->user_data);
585 (* signal_handler) (NULL, action, widget);
588 static void
589 dia_menu_signal_connect_func (GnomeUIInfo *uiinfo, gchar *signal_name,
590 GnomeUIBuilderData *uibdata)
592 gtk_signal_connect (GTK_OBJECT(uiinfo->widget), signal_name,
593 GTK_SIGNAL_FUNC(dia_menu_signal_proxy), uiinfo);
596 static GnomeUIBuilderData dia_menu_uibdata = {
597 dia_menu_signal_connect_func, /* connect_func */
598 NULL, /* data */
599 FALSE, /* is_interp */
600 (GtkCallbackMarshal) 0, /* relay_func */
601 (GtkDestroyNotify) 0 /* destroy_func */
603 #endif
605 static void
606 menus_init(void)
608 GtkWidget *menuitem;
609 GString *path;
610 gchar *accelfilename;
611 gint i, len;
612 GList *filter_callbacks;
614 if (!initialise)
615 return;
617 initialise = FALSE;
619 #ifdef GNOME
620 /* the toolbox menu */
621 toolbox_accels = gtk_accel_group_new();
622 toolbox_menubar = gtk_menu_bar_new();
623 gnome_app_fill_menu_custom(GTK_MENU_SHELL(toolbox_menubar), toolbox_menu,
624 &dia_menu_uibdata, toolbox_accels, TRUE, 0);
626 /* the display menu */
627 display_menus = gtk_menu_new();
628 display_accels = gtk_accel_group_new();
629 gtk_menu_set_accel_group(GTK_MENU(display_menus), display_accels);
630 menuitem = gtk_tearoff_menu_item_new();
631 gtk_menu_prepend(GTK_MENU(display_menus), menuitem);
632 gnome_app_fill_menu_custom(GTK_MENU_SHELL(display_menus), display_menu,
633 &dia_menu_uibdata, display_accels, FALSE, 0);
634 /* and the tearoff ... */
635 menuitem = gtk_tearoff_menu_item_new();
636 gtk_menu_prepend(GTK_MENU(display_menus), menuitem);
637 gtk_widget_show(menuitem);
638 #else
639 /* the toolbox menu */
640 toolbox_accels = gtk_accel_group_new();
641 toolbox_item_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<Toolbox>",
642 toolbox_accels);
643 gtk_object_set_data (GTK_OBJECT (toolbox_item_factory), "factory_path",
644 (gpointer) "toolbox");
645 #ifdef ENABLE_NLS
646 gtk_item_factory_set_translate_func (toolbox_item_factory, menu_translate,
647 "<Toolbox>", NULL);
648 #endif
649 gtk_item_factory_create_items (toolbox_item_factory,
650 toolbox_nmenu_items,
651 toolbox_menu_items,
652 NULL);
654 toolbox_menubar = gtk_item_factory_get_widget(toolbox_item_factory,
655 "<Toolbox>");
657 /* the display menu */
658 display_accels = gtk_accel_group_new();
659 display_item_factory = gtk_item_factory_new(GTK_TYPE_MENU, "<Display>",
660 display_accels);
661 #ifdef ENABLE_NLS
662 gtk_item_factory_set_translate_func (display_item_factory, menu_translate,
663 "<Display>", NULL);
664 #endif
665 gtk_item_factory_create_items (display_item_factory,
666 display_nmenu_items,
667 display_menu_items,
668 NULL);
670 display_menus = gtk_item_factory_get_widget(display_item_factory,
671 "<Display>");
672 #endif
674 path = g_string_new("<Display>/Tools/");
675 len = path->len;
676 for (i = 0; i < num_tools; i++) {
677 g_string_append(path, tool_data[i].menuitem_name);
678 menuitem = menus_get_item_from_path(path->str);
679 if (menuitem != NULL)
680 gtk_signal_connect(GTK_OBJECT(menuitem), "activate",
681 GTK_SIGNAL_FUNC(tool_menu_select),
682 &tool_data[i].callback_data);
683 g_string_truncate(path, len);
685 g_string_free(path, TRUE);
687 gtk_menu_set_title(GTK_MENU(display_menus), _("Diagram Menu"));
689 accelfilename = dia_config_filename("menurc");
691 if (accelfilename) {
692 gtk_item_factory_parse_rc(accelfilename);
693 g_free(accelfilename);
695 gtk_quit_add(1, save_accels, NULL);
697 /* initialize callbacks from plug-ins */
698 filter_callbacks = filter_get_callbacks();
699 if (filter_callbacks) {
700 GtkItemFactoryEntry new_entry;
701 GList *cblist;
702 gint cbcount = 0;
704 new_entry.callback = plugin_callback_cb;
705 new_entry.item_type = "<Item>";
706 new_entry.accelerator = NULL;
708 for (cblist = filter_callbacks; cblist != NULL; cblist = cblist->next) {
709 char *new_menupath;
710 DiaCallbackFilter *cbf = cblist->data;
712 /* It would be faster to directly connect the cbf to the menu entry
713 * but using action_data with a counter should improve error handling.
715 cbcount++; /* increase always, because it's the index into the list */
716 new_menupath = strstr (cbf->menupath, "<Display>");
717 if (new_menupath) {
718 new_entry.path = new_menupath + strlen("<Display>");
719 new_entry.callback_action = cbcount;
720 gtk_item_factory_create_item(display_item_factory, &new_entry, NULL,1);
721 continue;
723 new_menupath = strstr (cbf->menupath, "<Toolbox>");
724 if (new_menupath) {
725 new_entry.path = new_menupath + strlen("<Toolbox>");
726 new_entry.callback_action = cbcount;
727 gtk_item_factory_create_item(toolbox_item_factory, &new_entry, NULL,1);
728 continue;
730 g_warning ("Don't know where to add \"%s\" menu entry.", cbf->menupath);
731 } /* for filter_callbacks */
732 } /* if filter_callbacks */
735 void
736 menus_get_toolbox_menubar (GtkWidget **menubar,
737 GtkAccelGroup **accel_group)
739 if (initialise)
740 menus_init();
742 if (menubar)
743 *menubar = toolbox_menubar;
744 if (accel_group)
745 *accel_group = toolbox_accels;
748 void
749 menus_get_image_menu (GtkWidget **menu,
750 GtkAccelGroup **accel_group)
752 if (initialise)
753 menus_init();
755 if (menu)
756 *menu = display_menus;
757 if (accel_group)
758 *accel_group = display_accels;
761 #ifdef GNOME
762 /* a function that performs a similar task to gnome_app_find_menu_pos,
763 * but works from the GnomeUIInfo structures, and takes an untranslated path. It ignores
765 * but doesn't perform any translation of the menu items, and removes
766 * underscores when performing the string comparisons */
767 static GtkWidget *
768 dia_gnome_menu_get_widget (GnomeUIInfo *uiinfo, const gchar *path)
770 GtkWidget *ret;
771 gchar *name_end;
772 gint path_len, label_len, i, j;
773 gboolean label_matches;
775 g_return_val_if_fail (uiinfo != NULL, NULL);
776 g_return_val_if_fail (path != NULL, NULL);
778 name_end = strchr(path, '/');
779 if (name_end == NULL)
780 path_len = strlen(path);
781 else
782 path_len = name_end - path;
784 if (path_len == 0)
785 return NULL; /* zero path component */
787 for (; uiinfo->type != GNOME_APP_UI_ENDOFINFO; uiinfo++)
788 switch (uiinfo->type) {
789 case GNOME_APP_UI_BUILDER_DATA:
790 case GNOME_APP_UI_HELP:
791 case GNOME_APP_UI_ITEM_CONFIGURABLE:
792 /* we won't bother handling these two options */
793 break;
795 case GNOME_APP_UI_RADIOITEMS:
796 /* descend the radioitem list, without trimming the path */
797 ret = dia_gnome_menu_get_widget((GnomeUIInfo *)uiinfo->moreinfo,
798 path);
799 if (ret)
800 return ret;
801 break;
803 case GNOME_APP_UI_SEPARATOR:
804 case GNOME_APP_UI_ITEM:
805 case GNOME_APP_UI_TOGGLEITEM:
806 /* check for matching label */
807 if (!uiinfo->label)
808 break;
809 /* check the path component against the label, ignoring underscores */
810 label_matches = TRUE;
811 label_len = strlen(uiinfo->label);
812 for (i = 0, j = 0; i < label_len; i++) {
813 if (uiinfo->label[i] == '_') {
814 /* nothing */;
815 } else if (uiinfo->label[i] != path[j]) {
816 label_matches = FALSE;
817 break;
818 } else {
819 j++;
822 if (label_matches && j == path_len && i == label_len)
823 return uiinfo->widget;
824 break;
826 case GNOME_APP_UI_SUBTREE:
827 case GNOME_APP_UI_SUBTREE_STOCK:
828 /* descend if label matches, trimming off the start of the path */
829 if (!uiinfo->label)
830 break;
831 /* check the path component against the label, ignoring underscores */
832 label_matches = TRUE;
833 label_len = strlen(uiinfo->label);
834 for (i = 0, j = 0; i < label_len; i++) {
835 if (uiinfo->label[i] == '_') {
836 /* nothing */;
837 } else if (uiinfo->label[i] != path[j]) {
838 label_matches = FALSE;
839 break;
840 } else {
841 j++;
844 /* does the stripped label match? then recurse. */
845 if (label_matches && j == path_len && i == label_len) {
846 ret = dia_gnome_menu_get_widget((GnomeUIInfo *)uiinfo->moreinfo,
847 path + path_len + 1);
848 if (ret)
849 return ret;
851 break;
852 default:
853 g_warning ("unexpected GnomeUIInfo element type %d", (int) uiinfo->type);
854 break;
856 /* if we fall through, return NULL */
857 return NULL;
859 #endif
861 GtkWidget *
862 menus_get_item_from_path (char *path)
864 GtkWidget *widget = NULL;
866 # ifdef GNOME
867 char *menu_name;
868 DDisplay *ddisp;
870 /* drop the "<Display>/" or "<Toolbox>/" at the start */
871 menu_name = path;
872 if (! (path = strchr (path, '/'))) return NULL;
873 path ++; /* move past the / */
875 if (strncmp(menu_name, "<Display>", strlen("<Display>")) == 0) {
876 ddisp = ddisplay_active ();
877 if (! ddisp)
878 return NULL;
879 widget = dia_gnome_menu_get_widget(display_menu, path);
880 } else if (strncmp(menu_name, "<Toolbox>", strlen("<Toolbox>")) == 0) {
881 widget = dia_gnome_menu_get_widget(toolbox_menu, path);
883 # else
885 if (display_item_factory) {
886 widget = gtk_item_factory_get_widget(display_item_factory, path);
889 if (widget == NULL) {
890 widget = gtk_item_factory_get_widget(toolbox_item_factory, path);
892 # endif
894 if (! widget) {
895 g_warning("Can't find menu entry '%s'!\nThis is probably a i18n problem "
896 "(try LANG=C).", path);
899 return widget;
902 static void
903 plugin_callback_cb ( gpointer data, guint action, GtkWidget *widget)
905 GList *cbfilters = filter_get_callbacks();
906 DiaCallbackFilter *cbf;
908 /* find the corresponding CallbackFilter */
909 if (!cbfilters) {
910 g_warning ("Huh? Callback callback called without any callbacks registered.");
911 return;
914 cbfilters = g_list_nth (cbfilters, action - 1);
915 cbf = cbfilters ? (DiaCallbackFilter *)cbfilters->data : NULL;
916 if (!cbf) {
917 g_warning ("Can't find callback No. %d.", action);
918 return;
921 /* and finally invoke it */
922 if (cbf->callback) {
923 DDisplay *ddisp = ddisplay_active();
924 DiagramData* diadata = ddisp ? ddisp->diagram->data : NULL;
925 cbf->callback (diadata, 0, cbf->user_data);
927 else
928 g_warning ("Can't find callback function for No. %d.", action);