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.
27 #include <gdk/gdkkeysyms.h>
35 #include "interface.h"
37 #include "object_ops.h"
38 #include "connectionpoint_ops.h"
44 #include "preferences.h"
45 #include "scroll_tool.h"
47 /* This contains the point that was clicked to get this menu */
48 static Point object_menu_clicked_point
;
51 object_menu_proxy(GtkWidget
*widget
, gpointer data
)
53 DiaMenuItem
*dia_menu_item
;
54 ObjectChange
*obj_change
;
56 DDisplay
*ddisp
= ddisplay_active();
57 Object
*obj
= (Object
*)ddisp
->diagram
->data
->selected
->data
;
59 dia_menu_item
= (DiaMenuItem
*) data
;
62 object_add_updates(obj
, ddisp
->diagram
);
63 obj_change
= (dia_menu_item
->callback
)(obj
, &object_menu_clicked_point
,
64 dia_menu_item
->callback_data
);
65 object_add_updates(obj
, ddisp
->diagram
);
66 diagram_update_connections_object(ddisp
->diagram
, obj
, TRUE
);
68 if (obj_change
!= NULL
) {
69 undo_object_change(ddisp
->diagram
, obj
, obj_change
);
71 diagram_modified(ddisp
->diagram
);
73 diagram_update_extents(ddisp
->diagram
);
75 if (obj_change
!= NULL
) {
76 undo_set_transactionpoint(ddisp
->diagram
->undo
);
78 message_warning(_("This object doesn't support Undo/Redo.\n"
79 "Undo information erased."));
80 undo_clear(ddisp
->diagram
->undo
);
84 diagram_flush(ddisp
->diagram
);
88 dia_menu_free(DiaMenu
*dia_menu
) {
89 if (dia_menu
->app_data
)
90 gtk_object_destroy((GtkObject
*)dia_menu
->app_data
);
91 dia_menu
->app_data
= NULL
;
92 dia_menu
->app_data_free
= NULL
;
96 create_object_menu(DiaMenu
*dia_menu
)
100 GtkWidget
*menu_item
;
102 menu
= gtk_menu_new();
103 //FIXME?: gtk_menu_ensure_uline_accel_group (GTK_MENU (menu)) ;
105 if ( dia_menu
->title
) {
106 menu_item
= gtk_menu_item_new_with_label(gettext(dia_menu
->title
));
107 gtk_widget_set_sensitive(menu_item
, FALSE
);
108 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), menu_item
);
109 gtk_widget_show(menu_item
);
112 menu_item
= gtk_menu_item_new();
113 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), menu_item
);
114 gtk_widget_show(menu_item
);
116 for (i
=0;i
<dia_menu
->num_items
;i
++) {
117 DiaMenuItem
*item
= &dia_menu
->items
[i
];
119 if (item
->active
& DIAMENU_TOGGLE
) {
121 menu_item
= gtk_check_menu_item_new_with_label(gettext(item
->text
));
123 menu_item
= gtk_check_menu_item_new();
124 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_item
),
125 item
->active
& DIAMENU_TOGGLE_ON
);
126 gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_item
),
130 menu_item
= gtk_menu_item_new_with_label(gettext(item
->text
));
132 menu_item
= gtk_menu_item_new();
134 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), menu_item
);
135 gtk_widget_show(menu_item
);
136 item
->app_data
= menu_item
;
137 if ( dia_menu
->items
[i
].callback
) {
138 /* only connect signal handler if there is actually a callback */
139 gtk_signal_connect(GTK_OBJECT(menu_item
), "activate",
140 (GtkSignalFunc
)object_menu_proxy
, &dia_menu
->items
[i
]);
142 if ( item
->callback_data
) {
143 /* This menu item is a submenu if it has no callback, but does
144 * Have callback_data. In this case the callback_data is a
145 * DiaMenu pointer for the submenu. */
146 if ( ((DiaMenu
*)item
->callback_data
)->app_data
== NULL
) {
147 /* Create the popup menu items for the submenu. */
148 create_object_menu((DiaMenu
*)(item
->callback_data
) ) ;
149 gtk_menu_item_set_submenu( GTK_MENU_ITEM (menu_item
),
150 GTK_WIDGET(((DiaMenu
*)(item
->callback_data
))->app_data
));
156 dia_menu
->app_data
= menu
;
157 dia_menu
->app_data_free
= dia_menu_free
;
161 popup_object_menu(DDisplay
*ddisp
, GdkEventButton
*bevent
)
165 GtkMenu
*menu
= NULL
;
166 DiaMenu
*dia_menu
= NULL
;
167 GtkWidget
*menu_item
;
168 GList
*selected_list
;
169 static GtkWidget
*no_menu
= NULL
;
172 diagram
= ddisp
->diagram
;
173 if (diagram
->data
->selected_count
!= 1)
176 selected_list
= diagram
->data
->selected
;
178 /* Have to have exactly one selected object */
179 if (selected_list
== NULL
|| g_list_next(selected_list
) != NULL
) {
180 message_error("Selected list is %s while selected_count is %d\n",
181 (selected_list
?"long":"empty"), diagram
->data
->selected_count
);
185 obj
= (Object
*)g_list_first(selected_list
)->data
;
187 /* Possibly react differently at a handle? */
190 if (obj
->ops
->get_object_menu
== NULL
) {
193 dia_menu
= (obj
->ops
->get_object_menu
)(obj
, &object_menu_clicked_point
);
196 if (dia_menu
!= NULL
) {
197 if (dia_menu
->app_data
== NULL
)
198 create_object_menu(dia_menu
);
200 /* Update active/nonactive menuitems */
201 for (i
=0;i
<dia_menu
->num_items
;i
++) {
202 DiaMenuItem
*item
= &dia_menu
->items
[i
];
203 gtk_widget_set_sensitive(GTK_WIDGET(item
->app_data
),
204 item
->active
& DIAMENU_ACTIVE
);
205 if (item
->active
& DIAMENU_TOGGLE
) {
206 g_signal_handlers_block_by_func(GTK_CHECK_MENU_ITEM(item
->app_data
),
207 (GtkSignalFunc
)object_menu_proxy
, item
);
208 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item
->app_data
),
209 item
->active
& DIAMENU_TOGGLE_ON
);
210 g_signal_handlers_unblock_by_func(GTK_CHECK_MENU_ITEM(item
->app_data
),
211 (GtkSignalFunc
)object_menu_proxy
, item
);
215 menu
= GTK_MENU(dia_menu
->app_data
);
217 if (no_menu
== NULL
) {
218 no_menu
= gtk_menu_new();
220 menu_item
= gtk_menu_item_new_with_label(_("No object menu"));
221 gtk_menu_shell_append (GTK_MENU_SHELL (no_menu
), menu_item
);
222 gtk_widget_show(menu_item
);
223 gtk_widget_set_sensitive(menu_item
, FALSE
);
225 menu
= GTK_MENU(no_menu
);
228 popup_shell
= ddisp
->shell
;
229 gtk_menu_popup(menu
, NULL
, NULL
, NULL
, NULL
, bevent
->button
, bevent
->time
);
233 ddisplay_focus_in_event(GtkWidget
*widget
, GdkEventFocus
*event
, gpointer data
)
237 g_return_val_if_fail (widget
!= NULL
, FALSE
);
238 g_return_val_if_fail (event
!= NULL
, FALSE
);
239 g_return_val_if_fail (data
!= NULL
, FALSE
);
241 ddisp
= (DDisplay
*)data
;
243 GTK_WIDGET_SET_FLAGS(widget
, GTK_HAS_FOCUS
);
244 /* FIXME?: gtk_widget_draw_focus(widget); */
245 gtk_im_context_focus_in(GTK_IM_CONTEXT(ddisp
->im_context
));
251 ddisplay_focus_out_event(GtkWidget
*widget
, GdkEventFocus
*event
,gpointer data
)
256 g_return_val_if_fail (widget
!= NULL
, FALSE
);
257 g_return_val_if_fail (event
!= NULL
, FALSE
);
258 g_return_val_if_fail (data
!= NULL
, FALSE
);
262 ddisp
= (DDisplay
*)data
;
264 GTK_WIDGET_UNSET_FLAGS (widget
, GTK_HAS_FOCUS
);
266 gtk_im_context_focus_out(GTK_IM_CONTEXT(ddisp
->im_context
));
272 ddisplay_realize(GtkWidget
*widget
, gpointer data
)
276 g_return_if_fail(widget
!= NULL
);
277 g_return_if_fail(data
!= NULL
);
279 ddisp
= (DDisplay
*)data
;
281 gtk_im_context_set_client_window(GTK_IM_CONTEXT(ddisp
->im_context
),
282 GDK_WINDOW(ddisp
->shell
->window
));
286 ddisplay_unrealize (GtkWidget
*widget
, gpointer data
)
290 g_return_if_fail (widget
!= NULL
);
291 g_return_if_fail (data
!= NULL
);
293 ddisp
= (DDisplay
*) data
;
295 if (ddisp
->im_context
)
296 gtk_im_context_set_client_window(GTK_IM_CONTEXT(ddisp
->im_context
),
297 GDK_WINDOW(ddisp
->shell
->window
));
301 ddisplay_size_allocate (GtkWidget
*widget
,
302 GtkAllocation
*allocation
,
307 g_return_if_fail (widget
!= NULL
);
308 g_return_if_fail (allocation
!= NULL
);
309 g_return_if_fail (data
!= NULL
);
311 widget
->allocation
= *allocation
;
312 ddisp
= (DDisplay
*)data
;
316 ddisplay_popup_menu(DDisplay
*ddisp
, GdkEventButton
*event
)
320 popup_shell
= ddisp
->shell
;
321 menus_get_image_menu(&menu
, NULL
);
323 gtk_menu_popup(GTK_MENU(menu
), NULL
, NULL
, NULL
, NULL
,
324 event
->button
, event
->time
);
327 static void handle_key_event(DDisplay
*ddisp
, Focus
*focus
, guint keysym
,
328 const gchar
*str
, int strlen
) {
329 Object
*obj
= focus
->obj
;
330 Point p
= obj
->position
;
331 ObjectChange
*obj_change
= NULL
;
334 object_add_updates(obj
, ddisp
->diagram
);
336 modified
= (focus
->key_event
)(focus
, keysym
, str
, strlen
,
339 /* Make sure object updates its data and its connected: */
341 (obj
->ops
->move
)(obj
,&p
);
342 diagram_update_connections_object(ddisp
->diagram
,obj
,TRUE
);
344 object_add_updates(obj
, ddisp
->diagram
);
347 diagram_modified(ddisp
->diagram
);
348 if (obj_change
!= NULL
) {
349 undo_object_change(ddisp
->diagram
, obj
, obj_change
);
350 undo_set_transactionpoint(ddisp
->diagram
->undo
);
354 diagram_flush(ddisp
->diagram
);
358 void ddisplay_im_context_commit(GtkIMContext
*context
, const gchar
*str
,
360 /* When using IM, we'll not get many key events past the IM filter,
363 regardless of the platform, "str" should be a clean UTF8 string
364 (the default IM on X should perform the local->UTF8 conversion)
367 handle_key_event(ddisp
, active_focus(), 0, str
, g_utf8_strlen(str
,-1));
370 void ddisplay_im_context_preedit_changed(GtkIMContext
*context
,
373 PangoAttrList *attrs;
376 gtk_im_context_get_preedit_string(ddisp->im_context,
377 &str,&attrs,&cursor_pos);
379 g_message("received a 'preedit changed'; str=%s cursor_pos=%i",
383 pango_attr_list_unref(attrs);
388 ddisplay_canvas_events (GtkWidget
*canvas
,
392 GdkEventExpose
*eevent
;
393 GdkEventMotion
*mevent
;
394 GdkEventButton
*bevent
;
396 GdkEventScroll
*sevent
;
398 GdkModifierType tmask
;
417 eevent
= (GdkEventExpose
*) event
;
418 ddisplay_add_display_area(ddisp
,
419 eevent
->area
.x
, eevent
->area
.y
,
420 eevent
->area
.x
+ eevent
->area
.width
,
421 eevent
->area
.y
+ eevent
->area
.height
);
422 ddisplay_flush(ddisp
);
426 sevent
= (GdkEventScroll
*) event
;
428 switch (sevent
->direction
)
431 if (sevent
->state
& GDK_SHIFT_MASK
)
432 ddisplay_scroll_left(ddisp
);
433 else if (sevent
->state
& GDK_CONTROL_MASK
) {
434 ddisplay_untransform_coords(ddisp
, sevent
->x
, sevent
->y
, &middle
.x
, &middle
.y
);
435 ddisplay_zoom(ddisp
, &middle
, 2);
438 ddisplay_scroll_up(ddisp
);
440 case GDK_SCROLL_DOWN
:
441 if (sevent
->state
& GDK_SHIFT_MASK
)
442 ddisplay_scroll_right(ddisp
);
443 else if (sevent
->state
& GDK_CONTROL_MASK
) {
444 ddisplay_untransform_coords(ddisp
, sevent
->x
, sevent
->y
, &middle
.x
, &middle
.y
);
445 ddisplay_zoom(ddisp
, &middle
, 0.5);
448 ddisplay_scroll_down(ddisp
);
450 case GDK_SCROLL_LEFT
:
451 ddisplay_scroll_left(ddisp
);
453 case GDK_SCROLL_RIGHT
:
454 ddisplay_scroll_right(ddisp
);
459 ddisplay_flush (ddisp
);
463 if (ddisp
->renderer
!= NULL
) {
464 width
= dia_renderer_get_width_pixels (ddisp
->renderer
);
465 height
= dia_renderer_get_height_pixels (ddisp
->renderer
);
466 new_size
= ((width
!= ddisp
->canvas
->allocation
.width
) ||
467 (height
!= ddisp
->canvas
->allocation
.height
));
472 ddisplay_resize_canvas(ddisp
,
473 ddisp
->canvas
->allocation
.width
,
474 ddisp
->canvas
->allocation
.height
);
475 ddisplay_update_scrollbars(ddisp
);
477 display_set_active(ddisp
);
480 case GDK_FOCUS_CHANGE
: {
481 GdkEventFocus
*focus
= (GdkEventFocus
*)event
;
483 display_set_active(ddisp
);
484 ddisplay_do_update_menu_sensitivity(ddisp
);
488 case GDK_2BUTTON_PRESS
:
489 display_set_active(ddisp
);
490 bevent
= (GdkEventButton
*) event
;
491 state
= bevent
->state
;
493 switch (bevent
->button
)
498 if (*active_tool
->double_click_func
)
499 (*active_tool
->double_click_func
) (active_tool
, bevent
, ddisp
);
513 case GDK_BUTTON_PRESS
:
514 display_set_active(ddisp
);
515 bevent
= (GdkEventButton
*) event
;
516 state
= bevent
->state
;
518 ddisplay_untransform_coords(ddisp
,
519 (int)bevent
->x
, (int)bevent
->y
,
520 &object_menu_clicked_point
.x
,
521 &object_menu_clicked_point
.y
);
523 switch (bevent
->button
)
528 /* get the focus again, may be lost by zoom combo */
529 gtk_widget_grab_focus(canvas
);
530 if (*active_tool
->button_press_func
)
531 (*active_tool
->button_press_func
) (active_tool
, bevent
, ddisp
);
535 if (ddisp
->menu_bar
== NULL
) {
536 popup_object_menu(ddisp
, bevent
);
538 else if (!transient_tool
) {
539 gtk_widget_grab_focus(canvas
);
540 transient_tool
= create_scroll_tool();
541 (*transient_tool
->button_press_func
) (transient_tool
, bevent
, ddisp
);
548 if (ddisp
->menu_bar
== NULL
) {
549 if (bevent
->state
& GDK_CONTROL_MASK
) {
550 /* for two button mouse users ... */
551 popup_object_menu(ddisp
, bevent
);
554 ddisplay_popup_menu(ddisp
, bevent
);
558 popup_object_menu(ddisp
, bevent
);
566 case GDK_BUTTON_RELEASE
:
567 display_set_active(ddisp
);
568 bevent
= (GdkEventButton
*) event
;
569 state
= bevent
->state
;
571 switch (bevent
->button
)
574 if (*active_tool
->button_release_func
)
575 (*active_tool
->button_release_func
) (active_tool
,
580 if (transient_tool
) {
581 (*transient_tool
->button_release_func
) (transient_tool
,
584 tool_free(transient_tool
);
585 transient_tool
= NULL
;
597 case GDK_MOTION_NOTIFY
:
598 /* get the pointer position */
599 gdk_window_get_pointer (canvas
->window
, &tx
, &ty
, &tmask
);
601 mevent
= (GdkEventMotion
*) event
;
602 state
= mevent
->state
;
604 if (mevent
->is_hint
) {
607 mevent
->state
= tmask
;
608 mevent
->is_hint
= FALSE
;
610 if (transient_tool
&& (*transient_tool
->motion_func
))
611 (*transient_tool
->motion_func
) (transient_tool
, mevent
, ddisp
);
612 else if (*active_tool
->motion_func
)
613 (*active_tool
->motion_func
) (active_tool
, mevent
, ddisp
);
617 display_set_active(ddisp
);
618 kevent
= (GdkEventKey
*)event
;
619 state
= kevent
->state
;
622 focus
= active_focus();
623 if ((focus
!= NULL
) &&
624 !(state
& (GDK_CONTROL_MASK
| GDK_MOD1_MASK
)) ) {
625 /* Keys goes to the active focus. */
627 if (diagram_is_selected(ddisp
->diagram
, obj
)) {
629 if (!gtk_im_context_filter_keypress(
630 GTK_IM_CONTEXT(ddisp
->im_context
), kevent
)) {
632 /*! key event not swallowed by the input method ? */
633 handle_key_event(ddisp
, focus
, kevent
->keyval
,
634 kevent
->string
, kevent
->length
);
636 diagram_flush(ddisp
->diagram
);
639 return_val
= key_handled
= TRUE
;
643 /* No focus to receive keys, take care of it ourselves. */
645 gtk_im_context_reset(GTK_IM_CONTEXT(ddisp
->im_context
));
647 switch(kevent
->keyval
) {
649 ddisplay_scroll_up(ddisp
);
650 ddisplay_flush(ddisp
);
653 ddisplay_scroll_down(ddisp
);
654 ddisplay_flush(ddisp
);
657 ddisplay_scroll_left(ddisp
);
658 ddisplay_flush(ddisp
);
661 ddisplay_scroll_right(ddisp
);
662 ddisplay_flush(ddisp
);
666 visible
= &ddisp
->visible
;
667 middle
.x
= visible
->left
*0.5 + visible
->right
*0.5;
668 middle
.y
= visible
->top
*0.5 + visible
->bottom
*0.5;
670 ddisplay_zoom(ddisp
, &middle
, M_SQRT2
);
672 case GDK_KP_Subtract
:
674 visible
= &ddisp
->visible
;
675 middle
.x
= visible
->left
*0.5 + visible
->right
*0.5;
676 middle
.y
= visible
->top
*0.5 + visible
->bottom
*0.5;
678 ddisplay_zoom(ddisp
, &middle
, M_SQRT1_2
);
682 if (active_tool
->type
== MAGNIFY_TOOL
)
683 set_zoom_out(active_tool
);
686 if (kevent
->string
&& 0 == strcmp(" ",kevent
->string
)) {
687 tool_select_former();
695 case GDK_KEY_RELEASE
:
696 kevent
= (GdkEventKey
*) event
;
697 state
= kevent
->state
;
698 if (gtk_im_context_filter_keypress(GTK_IM_CONTEXT(ddisp
->im_context
),
702 switch(kevent
->keyval
) {
705 if (active_tool
->type
== MAGNIFY_TOOL
)
706 set_zoom_in(active_tool
);
722 ddisplay_hsb_update (GtkAdjustment
*adjustment
,
725 ddisplay_set_origo(ddisp
, adjustment
->value
, ddisp
->origo
.y
);
726 ddisplay_add_update_all(ddisp
);
727 ddisplay_flush(ddisp
);
732 ddisplay_vsb_update (GtkAdjustment
*adjustment
,
735 ddisplay_set_origo(ddisp
, ddisp
->origo
.x
, adjustment
->value
);
736 ddisplay_add_update_all(ddisp
);
737 ddisplay_flush(ddisp
);
742 ddisplay_delete (GtkWidget
*widget
, GdkEvent
*event
, gpointer data
)
746 ddisp
= (DDisplay
*)data
;
748 ddisplay_close(ddisp
);
753 ddisplay_destroy (GtkWidget
*widget
, gpointer data
)
757 ddisp
= (DDisplay
*) data
;
759 if (popup_shell
== ddisp
->shell
) {
763 ddisplay_really_destroy(ddisp
);
769 if (x
- (int) x
> 0.001)
776 /* returns NULL if object cannot be created */
778 ddisplay_drop_object(DDisplay
*ddisp
, gint x
, gint y
, ObjectType
*otype
,
782 Point droppoint_orig
;
783 Handle
*handle1
, *handle2
;
788 ddisplay_untransform_coords(ddisp
, x
, y
, &droppoint
.x
, &droppoint
.y
);
790 /* save it before snap_to_grid modifies it */
791 droppoint_orig
= droppoint
;
793 snap_to_grid(ddisp
, &droppoint
.x
, &droppoint
.y
);
795 obj
= dia_object_default_create (otype
, &droppoint
,
800 click_distance
= ddisplay_untransform_length(ddisp
, 3.0);
802 p_obj
= diagram_find_clicked_object(ddisp
->diagram
, &droppoint_orig
,
805 if (p_obj
&& p_obj
->can_parent
) /* the tool was dropped inside an object that takes children*/
807 Rectangle
*p_ext
, *c_ext
;
808 int new_height
= 0, new_width
= 0;
809 real parent_height
, child_height
, parent_width
, child_width
;
813 p_obj
->children
= g_list_append(p_obj
->children
, obj
);
815 p_ext
= parent_handle_extents(p_obj
);
816 c_ext
= parent_handle_extents(obj
);
818 parent_height
= p_ext
->bottom
- p_ext
->top
;
819 child_height
= c_ext
->bottom
- c_ext
->top
;
821 parent_width
= p_ext
->right
- p_ext
->left
;
822 child_width
= c_ext
->right
- c_ext
->left
;
824 /* we need the pre-snap position */
825 c_ext
->left
= droppoint_orig
.x
;
826 c_ext
->top
= droppoint_orig
.y
;
827 c_ext
->right
= c_ext
->left
+ child_width
;
828 c_ext
->bottom
= c_ext
->top
+ child_height
;
830 /* check if the top of the child is inside the parent, but the bottom is not */
831 if (c_ext
->top
< p_ext
->bottom
&& c_ext
->bottom
> p_ext
->bottom
)
833 /* check if child is smaller than parent height wise */
834 if (child_height
< parent_height
)
835 new_height
= child_height
;
836 /* check if parent is bigger than 1 in height */
837 else if (parent_height
> 1)
838 new_height
= round_up(parent_height
) - 1;
842 new_height
= child_height
;
844 /* check if the left of the child is inside the partent, but the right is not */
845 if (c_ext
->left
< p_ext
->right
&& c_ext
->right
> p_ext
->right
)
847 /* check if child is smaller than parent width wise */
848 if (child_width
< parent_width
)
849 new_width
= child_width
;
850 /* check if parent is bigger than 1 in width */
851 else if (parent_width
> 1)
852 new_width
= round_up(parent_width
) - 1;
856 new_width
= child_width
;
862 /* if we can't fit in both directions, produce an error */
863 if (!new_height
&& !new_width
)
865 message_error(_("The object you dropped cannot fit into its parent. \nEither expand the parent object, or drop the object elsewhere."));
866 obj
->parent
->children
= g_list_remove(obj
->parent
->children
, obj
);
867 obj
->ops
->destroy (obj
);
870 /* if we can't fit height wise, make height same as of the parent */
871 else if (!new_height
)
872 new_height
= parent_height
;
873 /* if we can't fit width wise, make the width same as of the parent */
875 new_width
= parent_width
;
877 new_pos
.x
= droppoint
.x
+ new_width
;
878 new_pos
.y
= droppoint
.y
+ new_height
;
879 obj
->ops
->move_handle(obj
, handle2
, &new_pos
, NULL
,
880 HANDLE_MOVE_USER
, 0);
885 diagram_add_object(ddisp
->diagram
, obj
);
886 diagram_remove_all_selected(ddisp
->diagram
, TRUE
); /* unselect all */
887 diagram_select(ddisp
->diagram
, obj
);
888 obj
->ops
->selectf(obj
, &droppoint
, ddisp
->renderer
);
890 /* Connect first handle if possible: */
891 if ((handle1
!= NULL
) &&
892 (handle1
->connect_type
!= HANDLE_NONCONNECTABLE
)) {
893 object_connect_display(ddisp
, obj
, handle1
);
895 object_add_updates(obj
, ddisp
->diagram
);
896 ddisplay_do_update_menu_sensitivity(ddisp
);
897 diagram_flush(ddisp
->diagram
);
899 list
= g_list_prepend(NULL
, obj
);
900 undo_insert_objects(ddisp
->diagram
, list
, 1);
901 diagram_update_extents(ddisp
->diagram
);
902 diagram_modified(ddisp
->diagram
);
904 undo_set_transactionpoint(ddisp
->diagram
->undo
);
905 if (prefs
.reset_tools_after_create
)