static void selection_changed (Diagram* dia, int n, DDisplay* ddisp) { GtkStatusbar *statusbar; guint context_id; /* nothing to do if there is no display with the diagram anymore */ if (g_slist_length(dia->displays) < 1) return; statusbar = GTK_STATUSBAR (ddisp->modified_status); context_id = gtk_statusbar_get_context_id (statusbar, "Selection"); if (n > 1) { gchar *msg; /* http://www.gnu.org/software/gettext/manual/html_chapter/gettext_10.html#SEC150 * Althoug the single objects wont get triggered here some languages have variations on the other numbers */ msg = g_strdup_printf (ngettext ("Selection of %d object", "Selection of %d objects", n), n); gtk_statusbar_pop (statusbar, context_id); gtk_statusbar_push (statusbar, context_id, msg); g_free (msg); } else if (n == 1) { /* find the selected objects name - and display it */ DiaObject *object = (DiaObject *)ddisp->diagram->data->selected->data; gchar *name = object_get_displayname (object); gchar *msg = g_strdup_printf (_("Selected '%s'"), name); gtk_statusbar_pop (statusbar, context_id); gtk_statusbar_push (statusbar, context_id, msg); g_free (name); g_free (msg); } else { gtk_statusbar_pop (statusbar, context_id); } /* selection-changed signal can also be emitted from outside of the dia core */ ddisplay_do_update_menu_sensitivity (ddisp); }
void display_update_menu_state(DDisplay *ddisp) { GtkToggleAction *rulers; GtkToggleAction *visible_grid; GtkToggleAction *snap_to_grid; GtkToggleAction *show_cx_pts; GtkToggleAction *antialiased; gboolean scrollbars_shown; rulers = GTK_TOGGLE_ACTION (menus_get_action ("ViewShowrulers")); visible_grid = GTK_TOGGLE_ACTION (menus_get_action ("ViewShowgrid")); snap_to_grid = GTK_TOGGLE_ACTION (menus_get_action ("ViewSnaptogrid")); show_cx_pts = GTK_TOGGLE_ACTION (menus_get_action ("ViewShowconnectionpoints")); antialiased = GTK_TOGGLE_ACTION (menus_get_action ("ViewAntialiased")); gtk_action_set_sensitive (menus_get_action ("ViewAntialiased"), g_type_from_name ("DiaCairoInteractiveRenderer") != 0 || g_type_from_name ("DiaLibartRenderer") != 0); ddisplay_do_update_menu_sensitivity (ddisp); gtk_toggle_action_set_active (rulers, display_get_rulers_showing(ddisp)); #if GTK_CHECK_VERSION(2,20,0) scrollbars_shown = gtk_widget_get_visible (ddisp->hsb); #else scrollbars_shown = GTK_WIDGET_VISIBLE (ddisp->hsb); #endif gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (menus_get_action ("ViewShowscrollbars")), scrollbars_shown); gtk_toggle_action_set_active (visible_grid, ddisp->grid.visible); gtk_toggle_action_set_active (snap_to_grid, ddisp->grid.snap); gtk_toggle_action_set_active (show_cx_pts, ddisp->show_cx_pts); gtk_toggle_action_set_active (antialiased, ddisp->aa_renderer); }
static void modify_button_release(ModifyTool *tool, GdkEventButton *event, DDisplay *ddisp) { Point *dest_pos, to; GList *list; int i; ObjectChange *objchange; tool->break_connections = FALSE; ddisplay_set_all_cursor(default_cursor); /* remove position from status bar */ { GtkStatusbar *statusbar = GTK_STATUSBAR (ddisp->modified_status); guint context_id = gtk_statusbar_get_context_id (statusbar, "ObjectPos"); gtk_statusbar_pop (statusbar, context_id); } switch (tool->state) { case STATE_MOVE_OBJECT: /* Return to normal state */ gdk_pointer_ungrab (event->time); ddisplay_untransform_coords(ddisp, event->x, event->y, &to.x, &to.y); if (!modify_move_already(tool, ddisp, &to)) { tool->orig_pos = NULL; tool->state = STATE_NONE; return; } diagram_update_connections_selection(ddisp->diagram); if (tool->orig_pos != NULL) { /* consider the non-selected children affected */ list = parent_list_affected(ddisp->diagram->data->selected); dest_pos = g_new(Point, g_list_length(list)); i=0; while (list != NULL) { DiaObject *obj = (DiaObject *) list->data; dest_pos[i] = obj->position; list = g_list_next(list); i++; } undo_move_objects(ddisp->diagram, tool->orig_pos, dest_pos, parent_list_affected(ddisp->diagram->data->selected)); } ddisplay_connect_selected(ddisp); /* pushes UNDO info */ diagram_update_extents(ddisp->diagram); diagram_modified(ddisp->diagram); diagram_flush(ddisp->diagram); undo_set_transactionpoint(ddisp->diagram->undo); tool->orig_pos = NULL; tool->state = STATE_NONE; break; case STATE_MOVE_HANDLE: gdk_pointer_ungrab (event->time); tool->state = STATE_NONE; if (tool->orig_pos != NULL) { undo_move_handle(ddisp->diagram, tool->handle, tool->object, *tool->orig_pos, tool->last_to, gdk_event_to_dia_ModifierKeys(event->state)); } /* Final move: */ object_add_updates(tool->object, ddisp->diagram); objchange = tool->object->ops->move_handle(tool->object, tool->handle, &tool->last_to, NULL, HANDLE_MOVE_USER_FINAL,gdk_event_to_dia_ModifierKeys(event->state)); if (objchange != NULL) { undo_object_change(ddisp->diagram, tool->object, objchange); } object_add_updates(tool->object, ddisp->diagram); /* Connect if possible: */ if (tool->handle->connect_type != HANDLE_NONCONNECTABLE) { object_connect_display(ddisp, tool->object, tool->handle, TRUE); /* pushes UNDO info */ diagram_update_connections_selection(ddisp->diagram); } highlight_reset_all(ddisp->diagram); diagram_flush(ddisp->diagram); diagram_modified(ddisp->diagram); diagram_update_extents(ddisp->diagram); undo_set_transactionpoint(ddisp->diagram->undo); if (tool->orig_pos != NULL) { g_free(tool->orig_pos); tool->orig_pos = NULL; } break; case STATE_BOX_SELECT: gdk_pointer_ungrab (event->time); /* Remove last box: */ dia_interactive_renderer_set_selection (ddisp->renderer, FALSE, 0, 0, 0, 0); { GList *list, *list_to_free; list = list_to_free = find_selected_objects(ddisp, tool); if (selection_style == SELECT_REPLACE && !(event->state & GDK_SHIFT_MASK)) { /* Not Multi-select => Remove all selected */ diagram_remove_all_selected(ddisp->diagram, TRUE); } if (selection_style == SELECT_INTERSECTION) { GList *intersection = NULL; while (list != NULL) { DiaObject *obj = (DiaObject *)list->data; if (diagram_is_selected(ddisp->diagram, obj)) { intersection = g_list_append(intersection, obj); } list = g_list_next(list); } list = intersection; diagram_remove_all_selected(ddisp->diagram, TRUE); while (list != NULL) { DiaObject *obj = (DiaObject *)list->data; diagram_select(ddisp->diagram, obj); list = g_list_next(list); } g_list_free(intersection); } else { while (list != NULL) { DiaObject *obj = (DiaObject *)list->data; if (selection_style == SELECT_REMOVE) { if (diagram_is_selected(ddisp->diagram, obj)) diagram_unselect_object(ddisp->diagram, obj); } else if (selection_style == SELECT_INVERT) { if (diagram_is_selected(ddisp->diagram, obj)) diagram_unselect_object(ddisp->diagram, obj); else diagram_select(ddisp->diagram, obj); } else { if (!diagram_is_selected(ddisp->diagram, obj)) diagram_select(ddisp->diagram, obj); } list = g_list_next(list); } } g_list_free(list_to_free); } ddisplay_do_update_menu_sensitivity(ddisp); ddisplay_flush(ddisp); tool->state = STATE_NONE; break; case STATE_NONE: break; default: message_error("Internal error: Strange state in modify_tool\n"); } }
static DiaObject * click_select_object(DDisplay *ddisp, Point *clickedpoint, GdkEventButton *event) { Diagram *diagram; real click_distance; DiaObject *obj; diagram = ddisp->diagram; /* Find the closest object to select it: */ click_distance = ddisplay_untransform_length(ddisp, 3.0); obj = diagram_find_clicked_object(diagram, clickedpoint, click_distance); if (obj!=NULL) { /* Selected an object. */ GList *already; /*printf("Selected object!\n");*/ already = g_list_find(diagram->data->selected, obj); if (already == NULL) { /* Not already selected */ /*printf("Not already selected\n");*/ if (!(event->state & GDK_SHIFT_MASK)) { /* Not Multi-select => remove current selection */ diagram_remove_all_selected(diagram, TRUE); } diagram_select(diagram, obj); /* To be removed once text edit mode is stable. By then, * we don't want to automatically edit selected objects. textedit_activate_object(ddisp, obj, clickedpoint); */ ddisplay_do_update_menu_sensitivity(ddisp); object_add_updates_list(diagram->data->selected, diagram); diagram_flush(diagram); return obj; } else { /* Clicked on already selected. */ /*printf("Already selected\n");*/ /* To be removed once text edit mode is stable. By then, * we don't want to automatically edit selected objects. textedit_activate_object(ddisp, obj, clickedpoint); */ object_add_updates_list(diagram->data->selected, diagram); diagram_flush(diagram); if (event->state & GDK_SHIFT_MASK) { /* Multi-select */ /* Remove the selected selected */ ddisplay_do_update_menu_sensitivity(ddisp); diagram_unselect_object(diagram, (DiaObject *)already->data); diagram_flush(ddisp->diagram); } else { return obj; } } } /* Else part moved to allow union/intersection select */ return NULL; }
static void create_object_button_press(CreateObjectTool *tool, GdkEventButton *event, DDisplay *ddisp) { Point clickedpoint, origpoint; Handle *handle1; Handle *handle2; DiaObject *obj; real click_distance; ddisplay_untransform_coords(ddisp, (int)event->x, (int)event->y, &clickedpoint.x, &clickedpoint.y); origpoint = clickedpoint; snap_to_grid(ddisp, &clickedpoint.x, &clickedpoint.y); click_distance = ddisplay_untransform_length(ddisp, 3.0); obj = dia_object_default_create (tool->objtype, &clickedpoint, tool->user_data, &handle1, &handle2); tool->obj = obj; /* ensure that tool->obj is initialised in case we return early. */ if (!obj) { tool->moving = FALSE; tool->handle = NULL; message_error(_("'%s' creation failed"), tool->objtype ? tool->objtype->name : "NULL"); return; } diagram_add_object(ddisp->diagram, obj); /* Try a connect */ if (handle1 != NULL && handle1->connect_type != HANDLE_NONCONNECTABLE) { ConnectionPoint *connectionpoint; connectionpoint = object_find_connectpoint_display(ddisp, &origpoint, obj, TRUE); if (connectionpoint != NULL) { (obj->ops->move)(obj, &origpoint); } } if (!(event->state & GDK_SHIFT_MASK)) { /* Not Multi-select => remove current selection */ diagram_remove_all_selected(ddisp->diagram, TRUE); } diagram_select(ddisp->diagram, obj); /* Connect first handle if possible: */ if ((handle1!= NULL) && (handle1->connect_type != HANDLE_NONCONNECTABLE)) { object_connect_display(ddisp, obj, handle1, TRUE); } object_add_updates(obj, ddisp->diagram); ddisplay_do_update_menu_sensitivity(ddisp); diagram_flush(ddisp->diagram); if (handle2 != NULL) { tool->handle = handle2; tool->moving = TRUE; tool->last_to = handle2->pos; gdk_pointer_grab (gtk_widget_get_window(ddisp->canvas), FALSE, GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, NULL, NULL, event->time); ddisplay_set_all_cursor(get_cursor(CURSOR_SCROLL)); } else { diagram_update_extents(ddisp->diagram); tool->moving = FALSE; } }
static void create_object_button_release(CreateObjectTool *tool, GdkEventButton *event, DDisplay *ddisp) { GList *list = NULL; DiaObject *obj = tool->obj; gboolean reset; GList *parent_candidates; g_return_if_fail (obj != NULL); if (!obj) /* not sure if this isn't enough */ return; /* could be a legal invariant */ if (tool->moving) { gdk_pointer_ungrab (event->time); object_add_updates(tool->obj, ddisp->diagram); tool->obj->ops->move_handle(tool->obj, tool->handle, &tool->last_to, NULL, HANDLE_MOVE_CREATE_FINAL, 0); object_add_updates(tool->obj, ddisp->diagram); } parent_candidates = layer_find_objects_containing_rectangle(obj->parent_layer, &obj->bounding_box); /* whole object must be within another object to parent it */ for (; parent_candidates != NULL; parent_candidates = g_list_next(parent_candidates)) { DiaObject *parent_obj = (DiaObject *) parent_candidates->data; if (obj != parent_obj && object_within_parent(obj, parent_obj)) { Change *change = undo_parenting(ddisp->diagram, parent_obj, obj, TRUE); (change->apply)(change, ddisp->diagram); break; /* obj->parent = parent_obj; parent_obj->children = g_list_append(parent_obj->children, obj); */ } } g_list_free(parent_candidates); list = g_list_prepend(list, tool->obj); undo_insert_objects(ddisp->diagram, list, 1); if (tool->moving) { if (tool->handle->connect_type != HANDLE_NONCONNECTABLE) { object_connect_display(ddisp, tool->obj, tool->handle, TRUE); diagram_update_connections_selection(ddisp->diagram); diagram_flush(ddisp->diagram); } tool->moving = FALSE; tool->handle = NULL; tool->obj = NULL; } { /* remove position from status bar */ GtkStatusbar *statusbar = GTK_STATUSBAR (ddisp->modified_status); guint context_id = gtk_statusbar_get_context_id (statusbar, "ObjectPos"); gtk_statusbar_pop (statusbar, context_id); } highlight_reset_all(ddisp->diagram); reset = prefs.reset_tools_after_create != tool->invert_persistence; /* kind of backward: first starting editing to see if it is possible at all, than GUI reflection */ if (textedit_activate_object(ddisp, obj, NULL) && reset) { gtk_action_activate (menus_get_action ("ToolsTextedit")); reset = FALSE; /* don't switch off textedit below */ } diagram_update_extents(ddisp->diagram); diagram_modified(ddisp->diagram); undo_set_transactionpoint(ddisp->diagram->undo); if (reset) tool_reset(); ddisplay_set_all_cursor(default_cursor); ddisplay_do_update_menu_sensitivity(ddisp); }
/** Make updates to menus associated with undo. * Currently just changes sensitivity, but should in the future also * include changing the labels. */ void undo_update_menus(UndoStack *stack) { ddisplay_do_update_menu_sensitivity(ddisplay_active()); }