.cvsignores added.
[dia.git] / app / commands.c
blob1e9c3997b21464261a193e1daa135cf539b081cf
1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 1998 Alexander Larsson *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 #include <config.h>
20 #ifdef HAVE_UNISTD_H
21 # include <unistd.h>
22 #endif
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <math.h>
29 #include <glib.h>
31 #include <gdk-pixbuf/gdk-pixbuf.h>
32 #include <gtk/gtk.h>
34 #ifdef GNOME
35 # include <gnome.h>
36 #endif
38 #ifdef G_OS_WIN32
40 * Instead of polluting the Dia namespace with windoze headers, declare the
41 * required prototype here. This is bad style, but not as bad as namespace
42 * clashes to be resolved without C++ --hb
44 long __stdcall
45 ShellExecuteA (long hwnd,
46 const char* lpOperation,
47 const char* lpFile,
48 const char* lpParameters,
49 const char* lpDirectory,
50 int nShowCmd);
51 #endif
53 #include "paginate_psprint.h"
54 #ifdef G_OS_WIN32
55 # include "paginate_gdiprint.h"
56 #endif
57 #include "intl.h"
58 #include "commands.h"
59 #include "app_procs.h"
60 #include "diagram.h"
61 #include "display.h"
62 #include "object_ops.h"
63 #include "cut_n_paste.h"
64 #include "load_save.h"
65 #include "utils.h"
66 #include "message.h"
67 #include "grid.h"
68 #include "properties.h"
69 #include "propinternals.h"
70 #include "preferences.h"
71 #include "layer_dialog.h"
72 #include "connectionpoint_ops.h"
73 #include "undo.h"
74 #include "pagesetup.h"
75 #include "text.h"
76 #include "dia_dirs.h"
77 #include "focus.h"
78 #include <gdk/gdk.h>
79 #include <gdk/gdkkeysyms.h>
80 #include "lib/properties.h"
81 #include "dia-props.h"
82 #include "diagram_tree_window.h"
83 #include "authors.h" /* master contributors data */
85 void
86 file_quit_callback (GtkAction *action)
88 app_exit();
91 void
92 file_pagesetup_callback (GtkAction *action)
94 Diagram *dia;
96 dia = ddisplay_active_diagram();
97 if (!dia) return;
98 create_page_setup_dlg(dia);
101 void
102 file_print_callback (GtkAction *action)
104 Diagram *dia;
106 dia = ddisplay_active_diagram();
107 if (!dia) return;
108 #ifdef G_OS_WIN32
109 /* This option could be used with Gnome too. Does it make sense there ? */
110 if (!prefs.prefer_psprint)
111 diagram_print_gdi(dia);
112 else
113 #endif
114 diagram_print_ps(dia);
117 void
118 file_close_callback (GtkAction *action)
120 /* some people use tear-off menus and insist to close non existing displays */
121 if (ddisplay_active())
122 ddisplay_close(ddisplay_active());
125 void
126 file_new_callback (GtkAction *action)
128 Diagram *dia;
129 DDisplay *ddisp;
130 static int untitled_nr = 1;
131 gchar *name, *filename;
133 name = g_strdup_printf(_("Diagram%d.dia"), untitled_nr++);
134 filename = g_filename_from_utf8(name, -1, NULL, NULL, NULL);
135 dia = new_diagram(filename);
136 ddisp = new_display(dia);
137 diagram_tree_add(diagram_tree(), dia);
138 g_free (name);
139 g_free (filename);
142 void
143 file_preferences_callback (GtkAction *action)
145 prefs_show();
149 void
150 edit_copy_callback (GtkAction *action)
152 GList *copy_list;
153 DDisplay *ddisp;
155 ddisp = ddisplay_active();
156 if (!ddisp) return;
157 copy_list = parent_list_affected(diagram_get_sorted_selected(ddisp->diagram));
159 cnp_store_objects(object_copy_list(copy_list));
160 g_list_free(copy_list);
162 ddisplay_do_update_menu_sensitivity(ddisp);
165 void
166 edit_cut_callback (GtkAction *action)
168 GList *cut_list;
169 DDisplay *ddisp;
170 Change *change;
172 ddisp = ddisplay_active();
173 if (!ddisp) return;
175 diagram_selected_break_external(ddisp->diagram);
177 cut_list = parent_list_affected(diagram_get_sorted_selected(ddisp->diagram));
179 cnp_store_objects(object_copy_list(cut_list));
181 change = undo_delete_objects_children(ddisp->diagram, cut_list);
182 (change->apply)(change, ddisp->diagram);
184 ddisplay_do_update_menu_sensitivity(ddisp);
185 diagram_flush(ddisp->diagram);
188 diagram_modified(ddisp->diagram);
189 undo_set_transactionpoint(ddisp->diagram->undo);
193 void
194 edit_paste_callback (GtkAction *action)
196 GList *paste_list;
197 DDisplay *ddisp;
198 Point paste_corner;
199 Point delta;
200 Change *change;
202 ddisp = ddisplay_active();
203 if (!ddisp) return;
205 if (!cnp_exist_stored_objects()) {
206 message_warning(_("No existing object to paste.\n"));
207 return;
210 paste_list = cnp_get_stored_objects(); /* Gets a copy */
212 paste_corner = object_list_corner(paste_list);
214 delta.x = ddisp->visible.left - paste_corner.x;
215 delta.y = ddisp->visible.top - paste_corner.y;
217 /* Move down some 10% of the visible area. */
218 delta.x += (ddisp->visible.right - ddisp->visible.left)*0.1;
219 delta.y += (ddisp->visible.bottom - ddisp->visible.top)*0.1;
221 object_list_move_delta(paste_list, &delta);
223 change = undo_insert_objects(ddisp->diagram, paste_list, 0);
224 (change->apply)(change, ddisp->diagram);
226 diagram_modified(ddisp->diagram);
227 undo_set_transactionpoint(ddisp->diagram->undo);
229 diagram_remove_all_selected(ddisp->diagram, TRUE);
230 diagram_select_list(ddisp->diagram, paste_list);
232 diagram_flush(ddisp->diagram);
236 * ALAN: Paste should probably paste to different position, feels
237 * wrong somehow. ALAN: The offset should increase a little each time
238 * if you paste/duplicate several times in a row, because it is
239 * clearer what is happening than if you were to piling them all in
240 * one place.
242 * completely untested, basically it is copy+paste munged together
244 void
245 edit_duplicate_callback (GtkAction *action)
247 GList *duplicate_list;
248 DDisplay *ddisp;
249 Point duplicate_corner;
250 Point delta;
251 Change *change;
253 ddisp = ddisplay_active();
254 if (!ddisp) return;
255 duplicate_list = object_copy_list(diagram_get_sorted_selected(ddisp->diagram));
256 duplicate_corner = object_list_corner(duplicate_list);
258 /* Move down some 10% of the visible area. */
259 delta.x = (ddisp->visible.right - ddisp->visible.left)*0.05;
260 delta.y = (ddisp->visible.bottom - ddisp->visible.top)*0.05;
262 object_list_move_delta(duplicate_list, &delta);
264 change = undo_insert_objects(ddisp->diagram, duplicate_list, 0);
265 (change->apply)(change, ddisp->diagram);
267 diagram_modified(ddisp->diagram);
268 undo_set_transactionpoint(ddisp->diagram->undo);
270 diagram_remove_all_selected(ddisp->diagram, TRUE);
271 diagram_select_list(ddisp->diagram, duplicate_list);
273 diagram_flush(ddisp->diagram);
275 ddisplay_do_update_menu_sensitivity(ddisp);
281 /* Signal handler for getting the clipboard contents */
282 /* Note that the clipboard is for M$-style cut/copy/paste copying, while
283 the selection is for Unix-style mark-and-copy. We can't really do
284 mark-and-copy.
287 static void
288 insert_text(DDisplay *ddisp, Focus *focus, const gchar *text)
290 ObjectChange *change = NULL;
291 int modified = FALSE, any_modified = FALSE;
292 DiaObject *obj = focus_get_object(focus);
294 while (text != NULL) {
295 gchar *next_line = g_utf8_strchr(text, -1, '\n');
296 if (next_line != text) {
297 gint len = g_utf8_strlen(text, (next_line-text));
298 modified = (*focus->key_event)(focus, GDK_A, text, len, &change);
300 if (next_line != NULL) {
301 modified = (*focus->key_event)(focus, GDK_Return, "\n", 1, &change);
302 text = g_utf8_next_char(next_line);
303 } else {
304 text = NULL;
306 { /* Make sure object updates its data: */
307 Point p = obj->position;
308 (obj->ops->move)(obj,&p); }
310 /* Perhaps this can be improved */
311 object_add_updates(obj, ddisp->diagram);
313 if (modified && (change != NULL)) {
314 undo_object_change(ddisp->diagram, obj, change);
315 any_modified = TRUE;
318 diagram_flush(ddisp->diagram);
321 if (any_modified) {
322 diagram_modified(ddisp->diagram);
323 undo_set_transactionpoint(ddisp->diagram->undo);
328 static void
329 received_clipboard_handler(GtkClipboard *clipboard,
330 const gchar *text,
331 gpointer data) {
332 Focus *focus = active_focus();
333 DDisplay *ddisp = (DDisplay *)data;
335 if (text == NULL) return;
337 if ((focus == NULL) || (!focus->has_focus)) return;
339 if (!g_utf8_validate(text, -1, NULL)) {
340 message_error("Not valid UTF8");
341 return;
344 insert_text(ddisp, focus, text);
347 static PropDescription text_prop_singleton_desc[] = {
348 { "text", PROP_TYPE_TEXT },
349 PROP_DESC_END};
351 static void
352 make_text_prop_singleton(GPtrArray **props, TextProperty **prop)
354 *props = prop_list_from_descs(text_prop_singleton_desc,pdtpp_true);
355 g_assert((*props)->len == 1);
357 *prop = g_ptr_array_index((*props),0);
358 g_free((*prop)->text_data);
359 (*prop)->text_data = NULL;
363 void
364 edit_copy_text_callback (GtkAction *action)
366 Focus *focus = active_focus();
367 DDisplay *ddisp;
368 DiaObject *obj;
369 GPtrArray *textprops;
370 TextProperty *prop;
372 if ((focus == NULL) || (!focus->has_focus)) return;
374 ddisp = ddisplay_active();
375 if (!ddisp) return;
377 obj = focus_get_object(focus);
379 if (obj->ops->get_props == NULL)
380 return;
382 make_text_prop_singleton(&textprops,&prop);
383 /* Get the first text property */
384 obj->ops->get_props(obj, textprops);
386 /* GTK docs claim the selection clipboard is ignored on Win32.
387 * The "clipboard" clipboard is mostly ignored in Unix
389 #ifdef G_OS_WIN32
390 gtk_clipboard_set_text(gtk_clipboard_get(GDK_NONE),
391 prop->text_data, -1);
392 #else
393 gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY),
394 prop->text_data, -1);
395 #endif
396 prop_list_free(textprops);
399 void
400 edit_cut_text_callback (GtkAction *action)
402 Focus *focus = active_focus();
403 DDisplay *ddisp;
404 DiaObject *obj;
405 Text *text;
406 GPtrArray *textprops;
407 TextProperty *prop;
408 ObjectChange *change;
410 if ((focus == NULL) || (!focus->has_focus)) return;
412 ddisp = ddisplay_active();
413 if (!ddisp) return;
415 obj = focus_get_object(focus);
416 text = (Text*)focus->user_data;
418 if (obj->ops->get_props == NULL)
419 return;
421 make_text_prop_singleton(&textprops,&prop);
422 /* Get the first text property */
423 obj->ops->get_props(obj, textprops);
425 /* GTK docs claim the selection clipboard is ignored on Win32.
426 * The "clipboard" clipboard is mostly ignored in Unix
428 #ifdef G_OS_WIN32
429 gtk_clipboard_set_text(gtk_clipboard_get(GDK_NONE),
430 prop->text_data, -1);
431 #else
432 gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY),
433 prop->text_data, -1);
434 #endif
436 prop_list_free(textprops);
438 if (text_delete_all(text, &change)) {
439 object_add_updates(obj, ddisp->diagram);
440 undo_object_change(ddisp->diagram, obj, change);
441 undo_set_transactionpoint(ddisp->diagram->undo);
442 diagram_modified(ddisp->diagram);
443 diagram_flush(ddisp->diagram);
447 void
448 edit_paste_text_callback (GtkAction *action)
450 DDisplay *ddisp;
452 ddisp = ddisplay_active();
453 if (!ddisp) return;
455 #ifdef G_OS_WIN32
456 gtk_clipboard_request_text(gtk_clipboard_get(GDK_NONE),
457 received_clipboard_handler, ddisp);
458 #else
459 gtk_clipboard_request_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY),
460 received_clipboard_handler, ddisp);
461 #endif
464 void
465 edit_delete_callback (GtkAction *action)
467 GList *delete_list;
468 DDisplay *ddisp;
470 Change *change;
472 ddisp = ddisplay_active();
473 if (!ddisp) return;
475 diagram_selected_break_external(ddisp->diagram);
477 delete_list = diagram_get_sorted_selected(ddisp->diagram);
478 change = undo_delete_objects_children(ddisp->diagram, delete_list);
479 (change->apply)(change, ddisp->diagram);
480 g_list_free(delete_list);
482 diagram_modified(ddisp->diagram);
484 ddisplay_do_update_menu_sensitivity(ddisp);
485 diagram_flush(ddisp->diagram);
487 undo_set_transactionpoint(ddisp->diagram->undo);
490 void
491 edit_undo_callback (GtkAction *action)
493 Diagram *dia;
495 dia = ddisplay_active_diagram();
496 if (!dia) return;
498 undo_revert_to_last_tp(dia->undo);
499 diagram_modified(dia);
501 diagram_flush(dia);
504 void
505 edit_redo_callback (GtkAction *action)
507 Diagram *dia;
509 dia = ddisplay_active_diagram();
510 if (!dia) return;
512 undo_apply_to_next_tp(dia->undo);
513 diagram_modified(dia);
515 diagram_flush(dia);
518 void
519 help_manual_callback (GtkAction *action)
521 #ifdef GNOME
522 gnome_help_display("dia", NULL, NULL);
523 #else
524 char *helpdir, *helpindex = NULL, *command;
525 guint bestscore = G_MAXINT;
526 GDir *dp;
527 const char *dentry;
528 GError *error = NULL;
530 helpdir = dia_get_data_directory("help");
531 if (!helpdir) {
532 message_warning(_("Could not find help directory"));
533 return;
536 /* search through helpdir for the helpfile that matches the user's locale */
537 dp = g_dir_open (helpdir, 0, &error);
538 if (!dp) {
539 message_warning(_("Could not open help directory:\n%s"),
540 error->message);
541 g_error_free (error);
542 return;
545 while ((dentry = g_dir_read_name(dp)) != NULL) {
546 guint score;
548 score = intl_score_locale(dentry);
549 if (score < bestscore) {
550 if (helpindex)
551 g_free(helpindex);
552 #ifdef G_OS_WIN32
553 /* use HTML Help on win32 if available */
554 helpindex = g_strconcat(helpdir, G_DIR_SEPARATOR_S, dentry,
555 G_DIR_SEPARATOR_S "dia-manual.chm", NULL);
556 if (!g_file_test(helpindex, G_FILE_TEST_EXISTS)) {
557 helpindex = g_strconcat(helpdir, G_DIR_SEPARATOR_S, dentry,
558 G_DIR_SEPARATOR_S "index.html", NULL);
560 #else
561 helpindex = g_strconcat(helpdir, G_DIR_SEPARATOR_S, dentry,
562 G_DIR_SEPARATOR_S "index.html", NULL);
563 #endif
564 bestscore = score;
567 g_dir_close (dp);
568 g_free(helpdir);
569 if (!helpindex) {
570 message_warning(_("Could not find help directory"));
571 return;
574 #ifdef G_OS_WIN32
575 # define SW_SHOWNORMAL 1
576 ShellExecuteA (0, "open", helpindex, NULL, helpdir, SW_SHOWNORMAL);
577 #else
578 command = getenv("BROWSER");
579 command = g_strdup_printf("%s 'file://%s' &", command ? command : "gnome-open", helpindex);
580 system(command);
581 g_free(command);
582 #endif
584 g_free(helpindex);
585 #endif
588 static void
589 activate_url (GtkAboutDialog *about,
590 const gchar *link,
591 gpointer data)
593 #ifdef G_OS_WIN32
594 ShellExecuteA (0, "open", link, NULL, NULL, SW_SHOWNORMAL);
595 #else
596 gchar *command = getenv("BROWSER");
597 command = g_strdup_printf("%s '%s' &", command ? command : "gnome-open", link);
598 system(command);
599 g_free(command);
600 #endif
603 void
604 help_about_callback (GtkAction *action)
606 const gchar *translators = _("translator_credits-PLEASE_ADD_YOURSELF_HERE");
607 const gchar *license = _(
608 "This program is free software; you can redistribute it and/or modify\n"
609 "it under the terms of the GNU General Public License as published by\n"
610 "the Free Software Foundation; either version 2 of the License, or\n"
611 "(at your option) any later version.\n"
612 "\n"
613 "This program is distributed in the hope that it will be useful,\n"
614 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
615 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
616 "GNU General Public License for more details.\n"
617 "\n"
618 "You should have received a copy of the GNU General Public License\n"
619 "along with this program; if not, write to the Free Software\n"
620 "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n");
622 gchar *dirname = dia_get_data_directory("");
623 gchar *filename = g_build_filename (dirname, "dia_logo.png", NULL);
624 GdkPixbuf *logo = gdk_pixbuf_new_from_file(filename, NULL);
626 gtk_about_dialog_set_url_hook (activate_url, NULL, NULL);
627 gtk_show_about_dialog (NULL,
628 "logo", logo,
629 "name", "Dia",
630 "version", VERSION,
631 "comments", _("A program for drawing structured diagrams."),
632 "copyright", "(C) 1998-2006 The Free Software Foundation and the authors",
633 "website", "http://www.gnome.org/projects/dia/",
634 "authors", authors,
635 "documenters", documentors,
636 "translator-credits", strcmp (translators, "translator_credits-PLEASE_ADD_YOURSELF_HERE")
637 ? translators : NULL,
638 "license", license,
639 NULL);
640 g_free (dirname);
641 g_free (filename);
642 if (logo)
643 g_object_unref (logo);
646 void
647 view_zoom_in_callback (GtkAction *action)
649 DDisplay *ddisp;
650 Point middle;
651 Rectangle *visible;
653 ddisp = ddisplay_active();
654 if (!ddisp) return;
655 visible = &ddisp->visible;
656 middle.x = visible->left*0.5 + visible->right*0.5;
657 middle.y = visible->top*0.5 + visible->bottom*0.5;
659 ddisplay_zoom(ddisp, &middle, M_SQRT2);
662 void
663 view_zoom_out_callback (GtkAction *action)
665 DDisplay *ddisp;
666 Point middle;
667 Rectangle *visible;
669 ddisp = ddisplay_active();
670 if (!ddisp) return;
671 visible = &ddisp->visible;
672 middle.x = visible->left*0.5 + visible->right*0.5;
673 middle.y = visible->top*0.5 + visible->bottom*0.5;
675 ddisplay_zoom(ddisp, &middle, M_SQRT1_2);
678 void
679 view_zoom_set_callback (GtkAction *action)
681 DDisplay *ddisp;
682 real scale;
683 Point middle;
684 Rectangle *visible;
685 int factor;
687 ddisp = ddisplay_active();
688 if (!ddisp) return;
690 /* HACK the actual factor is a suffix to the action name */
691 factor = atoi (gtk_action_get_name (action) + strlen ("ViewZoom"));
693 visible = &ddisp->visible;
694 middle.x = visible->left*0.5 + visible->right*0.5;
695 middle.y = visible->top*0.5 + visible->bottom*0.5;
697 scale = ((real) factor)/1000.0 * DDISPLAY_NORMAL_ZOOM;
699 ddisplay_zoom(ddisp, &middle, scale / ddisp->zoom_factor);
702 void
703 view_show_cx_pts_callback (GtkToggleAction *action)
705 DDisplay *ddisp;
706 int old_val;
708 ddisp = ddisplay_active();
709 if (!ddisp) return;
711 old_val = ddisp->show_cx_pts;
712 ddisp->show_cx_pts = gtk_toggle_action_get_active (action);
714 if (old_val != ddisp->show_cx_pts) {
715 ddisplay_add_update_all(ddisp);
716 ddisplay_flush(ddisp);
720 void
721 view_unfullscreen (void)
723 DDisplay *ddisp;
724 GtkToggleAction *item;
726 ddisp = ddisplay_active();
727 if (!ddisp) return;
729 /* find the menuitem */
730 item = GTK_TOGGLE_ACTION (menus_get_action ("ViewFullscreen"));
731 if (item && gtk_toggle_action_get_active (item)) {
732 gtk_toggle_action_set_active (item, FALSE);
736 void
737 view_fullscreen_callback (GtkToggleAction *action)
739 DDisplay *ddisp;
740 int fs;
742 ddisp = ddisplay_active();
743 if (!ddisp) return;
745 fs = gtk_toggle_action_get_active (action);
747 if (fs) /* it is already toggled */
748 gtk_window_fullscreen(GTK_WINDOW(ddisp->shell));
749 else
750 gtk_window_unfullscreen(GTK_WINDOW(ddisp->shell));
753 void
754 view_aa_callback (GtkToggleAction *action)
756 DDisplay *ddisp;
757 int aa;
759 ddisp = ddisplay_active();
760 if (!ddisp) return;
762 aa = gtk_toggle_action_get_active (action);
764 if (aa != ddisp->aa_renderer) {
765 ddisplay_set_renderer(ddisp, aa);
766 ddisplay_add_update_all(ddisp);
767 ddisplay_flush(ddisp);
771 void
772 view_visible_grid_callback (GtkToggleAction *action)
774 DDisplay *ddisp;
775 int old_val;
777 ddisp = ddisplay_active();
778 if (!ddisp) return;
780 old_val = ddisp->grid.visible;
781 ddisp->grid.visible = gtk_toggle_action_get_active (action);
783 if (old_val != ddisp->grid.visible) {
784 ddisplay_add_update_all(ddisp);
785 ddisplay_flush(ddisp);
789 void
790 view_snap_to_grid_callback (GtkToggleAction *action)
792 DDisplay *ddisp;
794 ddisp = ddisplay_active();
795 if (!ddisp) return;
797 ddisplay_set_snap_to_grid(ddisp, gtk_toggle_action_get_active (action));
800 void
801 view_snap_to_objects_callback (GtkToggleAction *action)
803 DDisplay *ddisp;
805 ddisp = ddisplay_active();
806 if (!ddisp) return;
808 ddisplay_set_snap_to_objects(ddisp, gtk_toggle_action_get_active (action));
811 void
812 view_toggle_rulers_callback (GtkToggleAction *action)
814 DDisplay *ddisp;
816 ddisp = ddisplay_active();
817 if (!ddisp) return;
819 if (!gtk_toggle_action_get_active (action)) {
820 if (GTK_WIDGET_VISIBLE (ddisp->origin)) {
821 gtk_widget_unmap (ddisp->origin);
822 gtk_widget_unmap (ddisp->hrule);
823 gtk_widget_unmap (ddisp->vrule);
825 GTK_WIDGET_UNSET_FLAGS (ddisp->origin, GTK_VISIBLE);
826 GTK_WIDGET_UNSET_FLAGS (ddisp->hrule, GTK_VISIBLE);
827 GTK_WIDGET_UNSET_FLAGS (ddisp->vrule, GTK_VISIBLE);
829 gtk_widget_queue_resize (GTK_WIDGET (ddisp->origin->parent));
831 } else {
832 if (!GTK_WIDGET_VISIBLE (ddisp->origin)) {
833 GTK_WIDGET_SET_FLAGS (ddisp->origin, GTK_VISIBLE);
834 GTK_WIDGET_SET_FLAGS (ddisp->hrule, GTK_VISIBLE);
835 GTK_WIDGET_SET_FLAGS (ddisp->vrule, GTK_VISIBLE);
837 gtk_widget_map (ddisp->origin);
838 gtk_widget_map (ddisp->hrule);
839 gtk_widget_map (ddisp->vrule);
841 gtk_widget_queue_resize (GTK_WIDGET (ddisp->origin->parent));
846 extern void
847 view_new_view_callback (GtkAction *action)
849 Diagram *dia;
851 dia = ddisplay_active_diagram();
852 if (!dia) return;
854 new_display(dia);
857 extern void
858 view_clone_view_callback (GtkAction *action)
860 DDisplay *ddisp;
862 ddisp = ddisplay_active();
863 if (!ddisp) return;
865 copy_display(ddisp);
868 void
869 view_show_all_callback (GtkAction *action)
871 DDisplay *ddisp;
872 Diagram *dia;
873 real magnify_x, magnify_y;
874 int width, height;
875 Point middle;
877 ddisp = ddisplay_active();
878 if (!ddisp) return;
879 dia = ddisp->diagram;
881 width = dia_renderer_get_width_pixels (ddisp->renderer);
882 height = dia_renderer_get_height_pixels (ddisp->renderer);
884 /* if there is something selected show that instead of all exisiting objects */
885 if (dia->data->selected) {
886 GList *list = dia->data->selected;
887 Rectangle extents = ((DiaObject*)list->data)->bounding_box;
888 list = g_list_next(list);
889 while (list) {
890 DiaObject *obj = (DiaObject *)list->data;
891 rectangle_union(&extents, &(obj->bounding_box));
892 list = g_list_next(list);
894 magnify_x = (real)width / (extents.right - extents.left) / ddisp->zoom_factor;
895 magnify_y = (real)height / (extents.bottom - extents.top) / ddisp->zoom_factor;
896 middle.x = extents.left + (extents.right - extents.left) / 2.0;
897 middle.y = extents.top + (extents.bottom - extents.top) / 2.0;
898 } else {
899 magnify_x = (real)width /
900 (dia->data->extents.right - dia->data->extents.left) / ddisp->zoom_factor;
901 magnify_y = (real)height /
902 (dia->data->extents.bottom - dia->data->extents.top) / ddisp->zoom_factor;
904 middle.x = dia->data->extents.left +
905 (dia->data->extents.right - dia->data->extents.left) / 2.0;
906 middle.y = dia->data->extents.top +
907 (dia->data->extents.bottom - dia->data->extents.top) / 2.0;
910 ddisplay_zoom (ddisp, &middle,
911 ((magnify_x<magnify_y)?magnify_x:magnify_y)/1.05);
913 ddisplay_update_scrollbars(ddisp);
914 ddisplay_add_update_all(ddisp);
915 ddisplay_flush(ddisp);
918 void
919 view_redraw_callback (GtkAction *action)
921 DDisplay *ddisp;
922 ddisp = ddisplay_active();
923 if (!ddisp) return;
924 ddisplay_add_update_all(ddisp);
925 ddisplay_flush(ddisp);
928 void
929 view_diagram_properties_callback (GtkAction *action)
931 DDisplay *ddisp;
933 ddisp = ddisplay_active();
934 if (!ddisp) return;
935 diagram_properties_show(ddisp->diagram);
939 void
940 objects_place_over_callback (GtkAction *action)
942 diagram_place_over_selected(ddisplay_active_diagram());
945 void
946 objects_place_under_callback (GtkAction *action)
948 diagram_place_under_selected(ddisplay_active_diagram());
951 void
952 objects_place_up_callback (GtkAction *action)
954 diagram_place_up_selected(ddisplay_active_diagram());
957 void
958 objects_place_down_callback (GtkAction *action)
960 diagram_place_down_selected(ddisplay_active_diagram());
963 void
964 objects_parent_callback (GtkAction *action)
966 diagram_parent_selected(ddisplay_active_diagram());
969 void
970 objects_unparent_callback (GtkAction *action)
972 diagram_unparent_selected(ddisplay_active_diagram());
975 void
976 objects_unparent_children_callback (GtkAction *action)
978 diagram_unparent_children_selected(ddisplay_active_diagram());
981 void
982 objects_group_callback (GtkAction *action)
984 DDisplay *ddisp;
986 ddisp = ddisplay_active();
987 if (!ddisp) return;
988 diagram_group_selected(ddisplay_active_diagram());
989 ddisplay_do_update_menu_sensitivity(ddisp);
992 void
993 objects_ungroup_callback (GtkAction *action)
995 DDisplay *ddisp;
997 ddisp = ddisplay_active();
998 if (!ddisp) return;
999 diagram_ungroup_selected(ddisplay_active_diagram());
1000 ddisplay_do_update_menu_sensitivity(ddisp);
1003 void
1004 dialogs_properties_callback (GtkAction *action)
1006 Diagram *dia;
1007 DiaObject *selected;
1009 dia = ddisplay_active_diagram();
1010 if (!dia) return;
1012 if (dia->data->selected != NULL) {
1013 selected = dia->data->selected->data;
1014 properties_show(dia, selected);
1015 } else {
1016 diagram_properties_show(dia);
1020 void
1021 dialogs_layers_callback (GtkAction *action)
1023 layer_dialog_set_diagram(ddisplay_active_diagram());
1024 layer_dialog_show();
1028 void
1029 objects_align_h_callback (GtkAction *action)
1031 const gchar *a;
1032 int align = DIA_ALIGN_LEFT;
1033 Diagram *dia;
1034 GList *objects;
1036 /* HACK align is suffix to action name */
1037 a = gtk_action_get_name (action) + strlen ("ObjectsAlign");
1038 if (0 == strcmp ("Left", a)) {
1039 align = DIA_ALIGN_LEFT;
1041 else if (0 == strcmp ("Center", a)) {
1042 align = DIA_ALIGN_CENTER;
1044 else if (0 == strcmp ("Right", a)) {
1045 align = DIA_ALIGN_RIGHT;
1047 else if (0 == strcmp ("Spreadouthorizontally", a)) {
1048 align = DIA_ALIGN_EQUAL;
1050 else if (0 == strcmp ("Adjacent", a)) {
1051 align = DIA_ALIGN_ADJACENT;
1053 else {
1054 g_warning ("objects_align_v_callback() called without appropriate align");
1055 return;
1058 dia = ddisplay_active_diagram();
1059 if (!dia) return;
1060 objects = dia->data->selected;
1062 object_add_updates_list(objects, dia);
1063 object_list_align_h(objects, dia, align);
1064 diagram_update_connections_selection(dia);
1065 object_add_updates_list(objects, dia);
1066 diagram_modified(dia);
1067 diagram_flush(dia);
1069 undo_set_transactionpoint(dia->undo);
1072 void
1073 objects_align_v_callback (GtkAction *action)
1075 const gchar *a;
1076 int align;
1077 Diagram *dia;
1078 GList *objects;
1080 /* HACK align is suffix to action name */
1081 a = gtk_action_get_name (action) + strlen ("ObjectsAlign");
1082 if (0 == strcmp ("Top", a)) {
1083 align = DIA_ALIGN_TOP;
1085 else if (0 == strcmp ("Middle", a)) {
1086 align = DIA_ALIGN_CENTER;
1088 else if (0 == strcmp ("Bottom", a)) {
1089 align = DIA_ALIGN_BOTTOM;
1091 else if (0 == strcmp ("Spreadoutvertically", a)) {
1092 align = DIA_ALIGN_EQUAL;
1094 else if (0 == strcmp ("Stacked", a)) {
1095 align = DIA_ALIGN_ADJACENT;
1097 else {
1098 g_warning ("objects_align_v_callback() called without appropriate align");
1099 return;
1102 dia = ddisplay_active_diagram();
1103 if (!dia) return;
1104 objects = dia->data->selected;
1106 object_add_updates_list(objects, dia);
1107 object_list_align_v(objects, dia, align);
1108 diagram_update_connections_selection(dia);
1109 object_add_updates_list(objects, dia);
1110 diagram_modified(dia);
1111 diagram_flush(dia);
1113 undo_set_transactionpoint(dia->undo);