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.
26 #include <sys/types.h>
31 #include <gdk-pixbuf/gdk-pixbuf.h>
34 /* Added by Andrew Ferrier: for use of gnome_about_new() */
42 * Instead of polluting the Dia namespace with windoze headers, declare the
43 * required prototype here. This is bad style, but not as bad as namespace
44 * clashes to be resolved without C++ --hb
47 ShellExecuteA (long hwnd
,
48 const char* lpOperation
,
50 const char* lpParameters
,
51 const char* lpDirectory
,
55 #include "paginate_psprint.h"
57 # include "paginate_gdiprint.h"
61 #include "app_procs.h"
64 #include "object_ops.h"
65 #include "cut_n_paste.h"
66 #include "load_save.h"
70 #include "properties.h"
71 #include "propinternals.h"
72 #include "preferences.h"
73 #include "layer_dialog.h"
74 #include "connectionpoint_ops.h"
76 #include "pagesetup.h"
81 #include <gdk/gdkkeysyms.h>
82 #include "lib/properties.h"
83 #include "dia-props.h"
84 #include "diagram_tree_window.h"
85 #include "authors.h" /* master contributors data */
89 void file_quit_callback(gpointer data
, guint action
, GtkWidget
*widget
)
95 file_pagesetup_callback(gpointer data
, guint action
, GtkWidget
*widget
)
99 dia
= ddisplay_active_diagram();
101 create_page_setup_dlg(dia
);
105 file_print_callback(gpointer data
, guint action
, GtkWidget
*widget
)
109 dia
= ddisplay_active_diagram();
112 /* This option could be used with Gnome too. Does it make sense there ? */
113 if (!prefs
.prefer_psprint
)
114 diagram_print_gdi(dia
);
117 diagram_print_ps(dia
);
121 file_close_callback(gpointer data
, guint action
, GtkWidget
*widget
)
123 /* some people use tear-off menus and insist to close non existing displays */
124 if (ddisplay_active())
125 ddisplay_close(ddisplay_active());
129 file_new_callback(gpointer data
, guint action
, GtkWidget
*widget
)
133 static int untitled_nr
= 1;
136 g_snprintf(buffer
, 24, _("Diagram%d.dia"), untitled_nr
++);
138 dia
= new_diagram(buffer
);
139 ddisp
= new_display(dia
);
140 diagram_tree_add(diagram_tree(), dia
);
144 file_preferences_callback(gpointer data
, guint action
, GtkWidget
*widget
)
151 edit_copy_callback(gpointer data
, guint action
, GtkWidget
*widget
)
156 ddisp
= ddisplay_active();
158 copy_list
= parent_list_affected(diagram_get_sorted_selected(ddisp
->diagram
));
160 cnp_store_objects(object_copy_list(copy_list
));
161 g_list_free(copy_list
);
163 ddisplay_do_update_menu_sensitivity(ddisp
);
167 edit_cut_callback(gpointer data
, guint action
, GtkWidget
*widget
)
173 ddisp
= ddisplay_active();
176 diagram_selected_break_external(ddisp
->diagram
);
178 cut_list
= parent_list_affected(diagram_get_sorted_selected(ddisp
->diagram
));
180 cnp_store_objects(object_copy_list(cut_list
));
182 change
= undo_delete_objects_children(ddisp
->diagram
, cut_list
);
183 (change
->apply
)(change
, ddisp
->diagram
);
185 ddisplay_do_update_menu_sensitivity(ddisp
);
186 diagram_flush(ddisp
->diagram
);
189 diagram_modified(ddisp
->diagram
);
190 undo_set_transactionpoint(ddisp
->diagram
->undo
);
195 edit_paste_callback(gpointer data
, guint action
, GtkWidget
*widget
)
203 ddisp
= ddisplay_active();
206 if (!cnp_exist_stored_objects()) {
207 message_warning(_("No existing object to paste.\n"));
211 paste_list
= cnp_get_stored_objects(); /* Gets a copy */
213 paste_corner
= object_list_corner(paste_list
);
215 delta
.x
= ddisp
->visible
.left
- paste_corner
.x
;
216 delta
.y
= ddisp
->visible
.top
- paste_corner
.y
;
218 /* Move down some 10% of the visible area. */
219 delta
.x
+= (ddisp
->visible
.right
- ddisp
->visible
.left
)*0.1;
220 delta
.y
+= (ddisp
->visible
.bottom
- ddisp
->visible
.top
)*0.1;
222 object_list_move_delta(paste_list
, &delta
);
224 change
= undo_insert_objects(ddisp
->diagram
, paste_list
, 0);
225 (change
->apply
)(change
, ddisp
->diagram
);
227 diagram_modified(ddisp
->diagram
);
228 undo_set_transactionpoint(ddisp
->diagram
->undo
);
230 diagram_remove_all_selected(ddisp
->diagram
, TRUE
);
231 diagram_select_list(ddisp
->diagram
, paste_list
);
233 diagram_flush(ddisp
->diagram
);
237 * ALAN: Paste should probably paste to different position, feels
238 * wrong somehow. ALAN: The offset should increase a little each time
239 * if you paste/duplicate several times in a row, because it is
240 * clearer what is happening than if you were to piling them all in
243 * completely untested, basically it is copy+paste munged together
246 edit_duplicate_callback(gpointer data
, guint action
, GtkWidget
*widget
)
248 GList
*duplicate_list
;
250 Point duplicate_corner
;
254 ddisp
= ddisplay_active();
256 duplicate_list
= object_copy_list(diagram_get_sorted_selected(ddisp
->diagram
));
257 duplicate_corner
= object_list_corner(duplicate_list
);
259 /* Move down some 10% of the visible area. */
260 delta
.x
= (ddisp
->visible
.right
- ddisp
->visible
.left
)*0.05;
261 delta
.y
= (ddisp
->visible
.bottom
- ddisp
->visible
.top
)*0.05;
263 object_list_move_delta(duplicate_list
, &delta
);
265 change
= undo_insert_objects(ddisp
->diagram
, duplicate_list
, 0);
266 (change
->apply
)(change
, ddisp
->diagram
);
268 diagram_modified(ddisp
->diagram
);
269 undo_set_transactionpoint(ddisp
->diagram
->undo
);
271 diagram_remove_all_selected(ddisp
->diagram
, TRUE
);
272 diagram_select_list(ddisp
->diagram
, duplicate_list
);
274 diagram_flush(ddisp
->diagram
);
276 ddisplay_do_update_menu_sensitivity(ddisp
);
282 /* Signal handler for getting the clipboard contents */
283 /* Note that the clipboard is for M$-style cut/copy/paste copying, while
284 the selection is for Unix-style mark-and-copy. We can't really do
289 insert_text(DDisplay
*ddisp
, Focus
*focus
, const gchar
*text
)
291 ObjectChange
*change
= NULL
;
292 int modified
= FALSE
, any_modified
= FALSE
;
293 DiaObject
*obj
= focus_get_object(focus
);
295 while (text
!= NULL
) {
296 gchar
*next_line
= g_utf8_strchr(text
, -1, '\n');
297 if (next_line
!= text
) {
298 gint len
= g_utf8_strlen(text
, (next_line
-text
));
299 modified
= (*focus
->key_event
)(focus
, GDK_A
, text
, len
, &change
);
301 if (next_line
!= NULL
) {
302 modified
= (*focus
->key_event
)(focus
, GDK_Return
, "\n", 1, &change
);
303 text
= g_utf8_next_char(next_line
);
307 { /* Make sure object updates its data: */
308 Point p
= obj
->position
;
309 (obj
->ops
->move
)(obj
,&p
); }
311 /* Perhaps this can be improved */
312 object_add_updates(obj
, ddisp
->diagram
);
314 if (modified
&& (change
!= NULL
)) {
315 undo_object_change(ddisp
->diagram
, obj
, change
);
319 diagram_flush(ddisp
->diagram
);
323 diagram_modified(ddisp
->diagram
);
324 undo_set_transactionpoint(ddisp
->diagram
->undo
);
330 received_clipboard_handler(GtkClipboard
*clipboard
,
333 Focus
*focus
= active_focus();
334 DDisplay
*ddisp
= (DDisplay
*)data
;
336 if (text
== NULL
) return;
338 if ((focus
== NULL
) || (!focus
->has_focus
)) return;
340 if (!g_utf8_validate(text
, -1, NULL
)) {
341 message_error("Not valid UTF8");
345 insert_text(ddisp
, focus
, text
);
348 static PropDescription text_prop_singleton_desc
[] = {
349 { "text", PROP_TYPE_TEXT
},
353 make_text_prop_singleton(GPtrArray
**props
, TextProperty
**prop
)
355 *props
= prop_list_from_descs(text_prop_singleton_desc
,pdtpp_true
);
356 g_assert((*props
)->len
== 1);
358 *prop
= g_ptr_array_index((*props
),0);
359 g_free((*prop
)->text_data
);
360 (*prop
)->text_data
= NULL
;
365 edit_copy_text_callback(gpointer data
, guint action
, GtkWidget
*widget
)
367 Focus
*focus
= active_focus();
370 GPtrArray
*textprops
;
373 if ((focus
== NULL
) || (!focus
->has_focus
)) return;
375 ddisp
= ddisplay_active();
378 obj
= focus_get_object(focus
);
380 if (obj
->ops
->get_props
== NULL
)
383 make_text_prop_singleton(&textprops
,&prop
);
384 /* Get the first text property */
385 obj
->ops
->get_props(obj
, textprops
);
387 /* GTK docs claim the selection clipboard is ignored on Win32.
388 * The "clipboard" clipboard is mostly ignored in Unix
391 gtk_clipboard_set_text(gtk_clipboard_get(GDK_NONE
),
392 prop
->text_data
, -1);
394 gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY
),
395 prop
->text_data
, -1);
397 prop_list_free(textprops
);
401 edit_cut_text_callback(gpointer data
, guint action
, GtkWidget
*widget
)
403 Focus
*focus
= active_focus();
407 GPtrArray
*textprops
;
409 ObjectChange
*change
;
411 if ((focus
== NULL
) || (!focus
->has_focus
)) return;
413 ddisp
= ddisplay_active();
416 obj
= focus_get_object(focus
);
417 text
= (Text
*)focus
->user_data
;
419 if (obj
->ops
->get_props
== NULL
)
422 make_text_prop_singleton(&textprops
,&prop
);
423 /* Get the first text property */
424 obj
->ops
->get_props(obj
, textprops
);
426 /* GTK docs claim the selection clipboard is ignored on Win32.
427 * The "clipboard" clipboard is mostly ignored in Unix
430 gtk_clipboard_set_text(gtk_clipboard_get(GDK_NONE
),
431 prop
->text_data
, -1);
433 gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY
),
434 prop
->text_data
, -1);
437 prop_list_free(textprops
);
439 if (text_delete_all(text
, &change
)) {
440 object_add_updates(obj
, ddisp
->diagram
);
441 undo_object_change(ddisp
->diagram
, obj
, change
);
442 undo_set_transactionpoint(ddisp
->diagram
->undo
);
443 diagram_modified(ddisp
->diagram
);
444 diagram_flush(ddisp
->diagram
);
449 edit_paste_text_callback(gpointer data
, guint action
, GtkWidget
*widget
)
453 ddisp
= ddisplay_active();
457 gtk_clipboard_request_text(gtk_clipboard_get(GDK_NONE
),
458 received_clipboard_handler
, ddisp
);
460 gtk_clipboard_request_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY
),
461 received_clipboard_handler
, ddisp
);
466 edit_delete_callback(gpointer data
, guint action
, GtkWidget
*widget
)
473 ddisp
= ddisplay_active();
476 diagram_selected_break_external(ddisp
->diagram
);
478 delete_list
= diagram_get_sorted_selected(ddisp
->diagram
);
479 change
= undo_delete_objects_children(ddisp
->diagram
, delete_list
);
480 (change
->apply
)(change
, ddisp
->diagram
);
481 g_list_free(delete_list
);
483 diagram_modified(ddisp
->diagram
);
485 ddisplay_do_update_menu_sensitivity(ddisp
);
486 diagram_flush(ddisp
->diagram
);
488 undo_set_transactionpoint(ddisp
->diagram
->undo
);
492 edit_undo_callback(gpointer data
, guint action
, GtkWidget
*widget
)
496 dia
= ddisplay_active_diagram();
499 undo_revert_to_last_tp(dia
->undo
);
500 diagram_modified(dia
);
506 edit_redo_callback(gpointer data
, guint action
, GtkWidget
*widget
)
510 dia
= ddisplay_active_diagram();
513 undo_apply_to_next_tp(dia
->undo
);
514 diagram_modified(dia
);
520 help_manual_callback(gpointer data
, guint action
, GtkWidget
*widget
)
523 gnome_help_display("dia", NULL
, NULL
);
525 char *helpdir
, *helpindex
= NULL
, *command
;
526 guint bestscore
= G_MAXINT
;
529 GError
*error
= NULL
;
531 helpdir
= dia_get_data_directory("help");
533 message_warning(_("Could not find help directory"));
537 /* search through helpdir for the helpfile that matches the user's locale */
538 dp
= g_dir_open (helpdir
, 0, &error
);
540 message_warning(_("Could not open help directory:\n%s"),
542 g_error_free (error
);
546 while ((dentry
= g_dir_read_name(dp
)) != NULL
) {
549 score
= intl_score_locale(dentry
);
550 if (score
< bestscore
) {
554 /* use HTML Help on win32 if available */
555 helpindex
= g_strconcat(helpdir
, G_DIR_SEPARATOR_S
, dentry
,
556 G_DIR_SEPARATOR_S
"dia-manual.chm", NULL
);
557 if (!g_file_test(helpindex
, G_FILE_TEST_EXISTS
)) {
558 helpindex
= g_strconcat(helpdir
, G_DIR_SEPARATOR_S
, dentry
,
559 G_DIR_SEPARATOR_S
"index.html", NULL
);
562 helpindex
= g_strconcat(helpdir
, G_DIR_SEPARATOR_S
, dentry
,
563 G_DIR_SEPARATOR_S
"index.html", NULL
);
571 message_warning(_("Could not find help directory"));
576 # define SW_SHOWNORMAL 1
577 ShellExecuteA (0, "open", helpindex
, NULL
, helpdir
, SW_SHOWNORMAL
);
579 command
= getenv("BROWSER");
580 command
= g_strdup_printf("%s 'file://%s' &", command
? command
: "gnome-open", helpindex
);
590 help_about_callback(gpointer data
, guint action
, GtkWidget
*widget
)
594 /* Take advantage of gnome_about_new(),
595 * which is much cleaner and GNOME2 HIG compliant,
596 * Originally implemented by Xing Wang, modified
599 * Note: in this function there is no need to discriminate
600 * between the different kinds of 'authors'.
603 static GtkWidget
*about
;
606 * Translators should localize the following string
607 * which will give them credit in the About box.
608 * E.g. "Fulano de Tal <fulano@detal.com>"
611 gchar
*translators
= _("translator_credits-PLEASE_ADD_YOURSELF_HERE");
612 gchar logo_file
[100];
617 gchar
* datadir
= dia_get_data_directory("");
618 g_snprintf(logo_file
, sizeof(logo_file
),
619 "%s%sdia_logo.png", datadir
, G_DIR_SEPARATOR_S
);
621 logo
= gdk_pixbuf_new_from_file(logo_file
, NULL
);
624 about
= gnome_about_new(
627 _("Copyright (C) 1998-2005 The Free Software Foundation and the authors"),
628 _("Dia is a program for drawing structured diagrams.\n"
629 "Please visit http://www.gnome.org/projects/dia for more information."),
632 (strcmp (translators
, "translator_credits-PLEASE_ADD_YOURSELF_HERE")
633 ? translators
: NULL
),
637 g_object_unref (logo
);
639 g_signal_connect (about
, "destroy",
640 G_CALLBACK (gtk_widget_destroyed
),
644 gtk_widget_show_now (about
);
648 /* No GNOME, fall back to the old GTK method */
650 const gint nauthors
= (sizeof(authors
) / sizeof(authors
[0])) - 1;
651 const gint ndocumentors
= (sizeof(documentors
) / sizeof(documentors
[0])) - 1;
665 dialog
= gtk_dialog_new ();
666 gtk_window_set_role (GTK_WINDOW (dialog
), "about_dialog");
667 gtk_window_set_title (GTK_WINDOW (dialog
), _("About Dia"));
668 gtk_window_set_resizable (GTK_WINDOW (dialog
), FALSE
);
669 gtk_window_set_position (GTK_WINDOW (dialog
), GTK_WIN_POS_CENTER
);
670 g_signal_connect (GTK_OBJECT (dialog
), "destroy",
671 G_CALLBACK (gtk_widget_destroy
),
672 GTK_OBJECT (dialog
));
674 vbox
= gtk_vbox_new (FALSE
, 1);
675 gtk_container_set_border_width (GTK_CONTAINER (vbox
), 5);
676 gtk_container_add (GTK_CONTAINER(GTK_DIALOG(dialog
)->vbox
), vbox
);
679 gchar
* datadir
= dia_get_data_directory("");
680 g_snprintf(str
, sizeof(str
), "%s%sdia_logo.png", datadir
, G_DIR_SEPARATOR_S
);
681 logo
= gdk_pixbuf_new_from_file(str
, NULL
);
689 frame
= gtk_frame_new (NULL
);
690 gtk_frame_set_shadow_type (GTK_FRAME (frame
), GTK_SHADOW_IN
);
691 gtk_container_set_border_width (GTK_CONTAINER (frame
), 1);
692 gtk_box_pack_start(GTK_BOX(vbox
), frame
, FALSE
, TRUE
, 1);
694 gdk_pixbuf_render_pixmap_and_mask(logo
, &pixmap
, &bitmap
, 128);
695 gpixmap
= gtk_pixmap_new(pixmap
, bitmap
);
696 gdk_pixmap_unref(pixmap
);
697 if (bitmap
) gdk_bitmap_unref(bitmap
);
698 gtk_container_add (GTK_CONTAINER(frame
), gpixmap
);
701 frame
= gtk_frame_new (NULL
);
702 gtk_frame_set_shadow_type (GTK_FRAME (frame
), GTK_SHADOW_IN
);
703 gtk_container_set_border_width (GTK_CONTAINER (frame
), 1);
704 gtk_box_pack_start(GTK_BOX(vbox
), frame
, FALSE
, TRUE
, 1);
706 table
= gtk_table_new(3, 2, FALSE
);
707 gtk_container_set_border_width (GTK_CONTAINER (table
), 1);
708 gtk_container_add (GTK_CONTAINER (frame
), table
);
710 g_snprintf(str
, sizeof(str
), _("Dia v %s by Alexander Larsson"), VERSION
);
711 label
= gtk_label_new (str
);
712 gtk_table_attach(GTK_TABLE(table
), label
, 0,2, 0,1,
713 GTK_FILL
|GTK_EXPAND
, GTK_FILL
, 0,2);
715 /* Exact spelling is Chépélov (using *ML entities) */
716 label
= gtk_label_new(_("Maintainers: Lars Clausen and Cyrille Chepelov"));
717 gtk_table_attach(GTK_TABLE(table
), label
, 0,2, 1,2,
718 GTK_FILL
|GTK_EXPAND
, GTK_FILL
, 0,2);
720 label
= gtk_label_new (_("Please visit http://www.gnome.org/projects/dia "
721 "for more information"));
722 gtk_table_attach(GTK_TABLE(table
), label
, 0,2, 2,3,
723 GTK_FILL
|GTK_EXPAND
, GTK_FILL
, 0,2);
725 label
= gtk_label_new (_("Contributors:"));
726 gtk_table_attach(GTK_TABLE(table
), label
, 0,2, 3,4,
727 GTK_FILL
|GTK_EXPAND
, GTK_FILL
, 0,2);
729 for (i
= 0; i
< nauthors
; i
++) {
730 label
= gtk_label_new(authors
[i
]);
731 gtk_table_attach(GTK_TABLE(table
), label
, i
%2,i
%2+1, i
/2+4,i
/2+5,
732 GTK_FILL
|GTK_EXPAND
, GTK_FILL
, 0,0);
735 for (i
= nauthors
; i
< nauthors
+ ndocumentors
; i
++) {
736 label
= gtk_label_new(documentors
[i
- nauthors
]);
737 gtk_table_attach(GTK_TABLE(table
), label
, i
%2,i
%2+1, i
/2+4,i
/2+5,
738 GTK_FILL
|GTK_EXPAND
, GTK_FILL
, 0,0);
741 gtk_table_set_col_spacings(GTK_TABLE(table
), 1);
742 gtk_table_set_row_spacings(GTK_TABLE(table
), 1);
744 bbox
= gtk_hbutton_box_new();
745 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog
)->action_area
), bbox
, TRUE
, TRUE
, 5);
746 gtk_button_box_set_child_size(GTK_BUTTON_BOX(bbox
), 80, 0);
747 gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox
), 10);
749 button
= gtk_button_new_from_stock(GTK_STOCK_OK
);
750 gtk_container_add(GTK_CONTAINER(bbox
), button
);
751 g_signal_connect_swapped(GTK_OBJECT (button
), "clicked",
752 G_CALLBACK(gtk_widget_destroy
),
755 gtk_widget_show_all (dialog
);
761 view_zoom_in_callback(gpointer data
, guint action
, GtkWidget
*widget
)
767 ddisp
= ddisplay_active();
769 visible
= &ddisp
->visible
;
770 middle
.x
= visible
->left
*0.5 + visible
->right
*0.5;
771 middle
.y
= visible
->top
*0.5 + visible
->bottom
*0.5;
773 ddisplay_zoom(ddisp
, &middle
, M_SQRT2
);
777 view_zoom_out_callback(gpointer data
, guint action
, GtkWidget
*widget
)
783 ddisp
= ddisplay_active();
785 visible
= &ddisp
->visible
;
786 middle
.x
= visible
->left
*0.5 + visible
->right
*0.5;
787 middle
.y
= visible
->top
*0.5 + visible
->bottom
*0.5;
789 ddisplay_zoom(ddisp
, &middle
, M_SQRT1_2
);
793 view_zoom_set_callback(gpointer data
, guint action
, GtkWidget
*widget
)
800 ddisp
= ddisplay_active();
802 visible
= &ddisp
->visible
;
803 middle
.x
= visible
->left
*0.5 + visible
->right
*0.5;
804 middle
.y
= visible
->top
*0.5 + visible
->bottom
*0.5;
806 scale
= ((real
) action
)/1000.0 * DDISPLAY_NORMAL_ZOOM
;
808 ddisplay_zoom(ddisp
, &middle
, scale
/ ddisp
->zoom_factor
);
812 view_show_cx_pts_callback(gpointer data
, guint action
, GtkWidget
*widget
)
817 ddisp
= ddisplay_active();
820 old_val
= ddisp
->show_cx_pts
;
821 ddisp
->show_cx_pts
= GTK_CHECK_MENU_ITEM(widget
)->active
;
823 if (old_val
!= ddisp
->show_cx_pts
) {
824 ddisplay_add_update_all(ddisp
);
825 ddisplay_flush(ddisp
);
830 view_unfullscreen(void)
835 ddisp
= ddisplay_active();
838 /* find the menuitem */
839 item
= menus_get_item_from_path ("<Display>/View/Fullscreen", NULL
);
840 if (item
&& GTK_CHECK_MENU_ITEM(item
)->active
) {
841 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(item
), FALSE
);
846 view_fullscreen_callback(gpointer data
, guint action
, GtkWidget
*widget
)
851 ddisp
= ddisplay_active();
854 fs
= GTK_CHECK_MENU_ITEM(widget
)->active
;
856 if (fs
) /* it is already toggled */
857 gtk_window_fullscreen(GTK_WINDOW(ddisp
->shell
));
859 gtk_window_unfullscreen(GTK_WINDOW(ddisp
->shell
));
863 view_aa_callback(gpointer data
, guint action
, GtkWidget
*widget
)
868 ddisp
= ddisplay_active();
871 aa
= GTK_CHECK_MENU_ITEM(widget
)->active
;
873 if (aa
!= ddisp
->aa_renderer
) {
874 ddisplay_set_renderer(ddisp
, aa
);
875 ddisplay_add_update_all(ddisp
);
876 ddisplay_flush(ddisp
);
881 view_visible_grid_callback(gpointer data
, guint action
, GtkWidget
*widget
)
886 ddisp
= ddisplay_active();
889 old_val
= ddisp
->grid
.visible
;
890 ddisp
->grid
.visible
= GTK_CHECK_MENU_ITEM(widget
)->active
;
892 if (old_val
!= ddisp
->grid
.visible
) {
893 ddisplay_add_update_all(ddisp
);
894 ddisplay_flush(ddisp
);
899 view_snap_to_grid_callback(gpointer data
, guint action
, GtkWidget
*widget
)
903 ddisp
= ddisplay_active();
906 ddisplay_set_snap_to_grid(ddisp
, GTK_CHECK_MENU_ITEM(widget
)->active
);
910 view_snap_to_objects_callback(gpointer data
, guint action
, GtkWidget
*widget
)
914 ddisp
= ddisplay_active();
917 ddisplay_set_snap_to_objects(ddisp
, GTK_CHECK_MENU_ITEM(widget
)->active
);
920 void view_toggle_rulers_callback(gpointer data
, guint action
, GtkWidget
*widget
)
924 ddisp
= ddisplay_active();
927 /* The following is borrowed straight from the Gimp: */
929 /* This routine use promiscuous knowledge of gtk internals
930 * in order to hide and show the rulers "smoothly". This
931 * is kludgy and a hack and may break if gtk is changed
934 if (!GTK_CHECK_MENU_ITEM(widget
)->active
) {
935 if (GTK_WIDGET_VISIBLE (ddisp
->origin
)) {
936 gtk_widget_unmap (ddisp
->origin
);
937 gtk_widget_unmap (ddisp
->hrule
);
938 gtk_widget_unmap (ddisp
->vrule
);
940 GTK_WIDGET_UNSET_FLAGS (ddisp
->origin
, GTK_VISIBLE
);
941 GTK_WIDGET_UNSET_FLAGS (ddisp
->hrule
, GTK_VISIBLE
);
942 GTK_WIDGET_UNSET_FLAGS (ddisp
->vrule
, GTK_VISIBLE
);
944 gtk_widget_queue_resize (GTK_WIDGET (ddisp
->origin
->parent
));
947 if (!GTK_WIDGET_VISIBLE (ddisp
->origin
)) {
948 GTK_WIDGET_SET_FLAGS (ddisp
->origin
, GTK_VISIBLE
);
949 GTK_WIDGET_SET_FLAGS (ddisp
->hrule
, GTK_VISIBLE
);
950 GTK_WIDGET_SET_FLAGS (ddisp
->vrule
, GTK_VISIBLE
);
952 gtk_widget_map (ddisp
->origin
);
953 gtk_widget_map (ddisp
->hrule
);
954 gtk_widget_map (ddisp
->vrule
);
956 gtk_widget_queue_resize (GTK_WIDGET (ddisp
->origin
->parent
));
962 view_new_view_callback(gpointer data
, guint action
, GtkWidget
*widget
)
966 dia
= ddisplay_active_diagram();
973 view_show_all_callback(gpointer data
, guint action
, GtkWidget
*widget
)
977 real magnify_x
, magnify_y
;
981 ddisp
= ddisplay_active();
983 dia
= ddisp
->diagram
;
985 width
= dia_renderer_get_width_pixels (ddisp
->renderer
);
986 height
= dia_renderer_get_height_pixels (ddisp
->renderer
);
988 /* if there is something selected show that instead of all exisiting objects */
989 if (dia
->data
->selected
) {
990 GList
*list
= dia
->data
->selected
;
991 Rectangle extents
= ((DiaObject
*)list
->data
)->bounding_box
;
992 list
= g_list_next(list
);
994 DiaObject
*obj
= (DiaObject
*)list
->data
;
995 rectangle_union(&extents
, &(obj
->bounding_box
));
996 list
= g_list_next(list
);
998 magnify_x
= (real
)width
/ (extents
.right
- extents
.left
) / ddisp
->zoom_factor
;
999 magnify_y
= (real
)height
/ (extents
.bottom
- extents
.top
) / ddisp
->zoom_factor
;
1000 middle
.x
= extents
.left
+ (extents
.right
- extents
.left
) / 2.0;
1001 middle
.y
= extents
.top
+ (extents
.bottom
- extents
.top
) / 2.0;
1003 magnify_x
= (real
)width
/
1004 (dia
->data
->extents
.right
- dia
->data
->extents
.left
) / ddisp
->zoom_factor
;
1005 magnify_y
= (real
)height
/
1006 (dia
->data
->extents
.bottom
- dia
->data
->extents
.top
) / ddisp
->zoom_factor
;
1008 middle
.x
= dia
->data
->extents
.left
+
1009 (dia
->data
->extents
.right
- dia
->data
->extents
.left
) / 2.0;
1010 middle
.y
= dia
->data
->extents
.top
+
1011 (dia
->data
->extents
.bottom
- dia
->data
->extents
.top
) / 2.0;
1014 ddisplay_zoom (ddisp
, &middle
,
1015 ((magnify_x
<magnify_y
)?magnify_x
:magnify_y
)/1.05);
1017 ddisplay_update_scrollbars(ddisp
);
1018 ddisplay_add_update_all(ddisp
);
1019 ddisplay_flush(ddisp
);
1023 view_redraw_callback(gpointer data
, guint action
, GtkWidget
*widget
)
1026 ddisp
= ddisplay_active();
1028 ddisplay_add_update_all(ddisp
);
1029 ddisplay_flush(ddisp
);
1033 view_diagram_properties_callback(gpointer data
, guint action
, GtkWidget
*widget
)
1037 ddisp
= ddisplay_active();
1039 diagram_properties_show(ddisp
->diagram
);
1044 objects_place_over_callback(gpointer data
, guint action
, GtkWidget
*widget
)
1046 diagram_place_over_selected(ddisplay_active_diagram());
1050 objects_place_under_callback(gpointer data
, guint action
, GtkWidget
*widget
)
1052 diagram_place_under_selected(ddisplay_active_diagram());
1056 objects_place_up_callback(gpointer data
, guint action
, GtkWidget
*widget
)
1058 diagram_place_up_selected(ddisplay_active_diagram());
1062 objects_place_down_callback(gpointer data
, guint action
, GtkWidget
*widget
)
1064 diagram_place_down_selected(ddisplay_active_diagram());
1068 objects_parent_callback(gpointer data
, guint action
, GtkWidget
*widget
)
1070 diagram_parent_selected(ddisplay_active_diagram());
1074 objects_unparent_callback(gpointer data
, guint action
, GtkWidget
*widget
)
1076 diagram_unparent_selected(ddisplay_active_diagram());
1080 objects_unparent_children_callback(gpointer data
, guint action
, GtkWidget
*widget
)
1082 diagram_unparent_children_selected(ddisplay_active_diagram());
1086 objects_group_callback(gpointer data
, guint action
, GtkWidget
*widget
)
1090 ddisp
= ddisplay_active();
1092 diagram_group_selected(ddisplay_active_diagram());
1093 ddisplay_do_update_menu_sensitivity(ddisp
);
1097 objects_ungroup_callback(gpointer data
, guint action
, GtkWidget
*widget
)
1101 ddisp
= ddisplay_active();
1103 diagram_ungroup_selected(ddisplay_active_diagram());
1104 ddisplay_do_update_menu_sensitivity(ddisp
);
1108 dialogs_properties_callback(gpointer data
, guint action
, GtkWidget
*widget
)
1111 DiaObject
*selected
;
1113 dia
= ddisplay_active_diagram();
1116 if (dia
->data
->selected
!= NULL
) {
1117 selected
= dia
->data
->selected
->data
;
1118 properties_show(dia
, selected
);
1120 diagram_properties_show(dia
);
1125 dialogs_layers_callback(gpointer data
, guint action
, GtkWidget
*widget
)
1127 layer_dialog_set_diagram(ddisplay_active_diagram());
1128 layer_dialog_show();
1133 objects_align_h_callback(gpointer data
, guint action
, GtkWidget
*widget
)
1141 dia
= ddisplay_active_diagram();
1143 objects
= dia
->data
->selected
;
1145 object_add_updates_list(objects
, dia
);
1146 object_list_align_h(objects
, dia
, align
);
1147 diagram_update_connections_selection(dia
);
1148 object_add_updates_list(objects
, dia
);
1149 diagram_modified(dia
);
1152 undo_set_transactionpoint(dia
->undo
);
1156 objects_align_v_callback(gpointer data
, guint action
, GtkWidget
*widget
)
1164 dia
= ddisplay_active_diagram();
1166 objects
= dia
->data
->selected
;
1168 object_add_updates_list(objects
, dia
);
1169 object_list_align_v(objects
, dia
, align
);
1170 diagram_update_connections_selection(dia
);
1171 object_add_updates_list(objects
, dia
);
1172 diagram_modified(dia
);
1175 undo_set_transactionpoint(dia
->undo
);