/*! \todo Finish function documentation!!! * \brief * \par Function Description * */ void o_copy_start(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y) { TOPLEVEL *toplevel = w_current->toplevel; GList *s_current; /* Copy the objects into the buffer at their current position, * with future motion relative to the mouse origin, (w_x, w_y). */ w_current->first_wx = w_x; w_current->first_wy = w_y; if (!o_select_selected (w_current)) return; s_current = geda_list_get_glist( toplevel->page_current->selection_list ); if (toplevel->page_current->place_list != NULL) { s_delete_object_glist(toplevel, toplevel->page_current->place_list); toplevel->page_current->place_list = NULL; } toplevel->page_current->place_list = o_glist_copy_all (toplevel, s_current, toplevel->page_current->place_list, SELECTION_FLAG); w_current->inside_action = 1; i_set_state(w_current, COPY); o_place_start (w_current, w_x, w_y); }
/*! \todo Finish function documentation!!! * \brief * \par Function Description * */ void o_move_start(GschemToplevel *w_current, int w_x, int w_y) { GList *s_iter; g_return_if_fail (w_current != NULL); GschemPageView *page_view = gschem_toplevel_get_current_page_view (w_current); g_return_if_fail (page_view != NULL); PAGE *page = gschem_page_view_get_page (page_view); g_return_if_fail (page != NULL); g_return_if_fail (w_current->stretch_list == NULL); if (o_select_selected (w_current)) { i_set_state (w_current, MOVEMODE); gboolean net_rubber_band_mode; net_rubber_band_mode = gschem_options_get_net_rubber_band_mode (w_current->options); w_current->last_drawb_mode = LAST_DRAWB_MODE_NONE; w_current->first_wx = w_current->second_wx = w_x; w_current->first_wy = w_current->second_wy = w_y; o_invalidate_glist (w_current, geda_list_get_glist (page->selection_list)); if (net_rubber_band_mode) { o_move_prep_rubberband(w_current); /* Set the dont_redraw flag on rubberbanded objects and invalidate them. * This ensures that they are not drawn (in their un-stretched position) * during screen updates. */ for (s_iter = w_current->stretch_list; s_iter != NULL; s_iter = g_list_next (s_iter)) { STRETCH *stretch = s_iter->data; stretch->object->dont_redraw = TRUE; o_invalidate (w_current, stretch->object); } } o_select_move_to_place_list(w_current); i_action_start (w_current); o_move_invalidate_rubber (w_current, TRUE); } }
/*! \todo Finish function documentation!!! * \brief * \par Function Description * */ void o_copy_start(GschemToplevel *w_current, int w_x, int w_y) { GList *s_current; GschemPageView *page_view = gschem_toplevel_get_current_page_view (w_current); g_return_if_fail (page_view != NULL); PAGE *page = gschem_page_view_get_page (page_view); g_return_if_fail (page != NULL); /* Copy the objects into the buffer at their current position, * with future motion relative to the mouse origin, (w_x, w_y). */ w_current->first_wx = w_x; w_current->first_wy = w_y; if (!o_select_selected (w_current)) return; s_current = geda_list_get_glist (page->selection_list); if (page->place_list != NULL) { s_delete_object_glist (page->toplevel, page->place_list); page->place_list = NULL; } page->place_list = o_glist_copy_all (page->toplevel, s_current, page->place_list); g_run_hook_object_list (w_current, "%copy-objects-hook", page->place_list); o_place_start (w_current, w_x, w_y); }
/*! \todo Finish function documentation!!! * \brief * \par Function Description * */ gint x_event_button_pressed(GschemPageView *page_view, GdkEventButton *event, GschemToplevel *w_current) { PAGE *page = gschem_page_view_get_page (page_view); int w_x, w_y; int unsnapped_wx, unsnapped_wy; g_return_val_if_fail ((w_current != NULL), 0); if (page == NULL) { return TRUE; /* terminate event */ } if (!gtk_widget_has_focus (GTK_WIDGET (page_view))) { gtk_widget_grab_focus (GTK_WIDGET (page_view)); } scm_dynwind_begin ((scm_t_dynwind_flags) 0); g_dynwind_window (w_current); #if DEBUG printf("pressed button %d! \n", event->button); printf("event state: %d \n", event->state); printf("w_current state: %d \n", w_current->event_state); printf("Selection is:\n"); o_selection_print_all(&(page->selection_list)); printf("\n"); #endif gschem_page_view_SCREENtoWORLD (page_view, (int) event->x, (int) event->y, &unsnapped_wx, &unsnapped_wy); w_x = snap_grid (w_current, unsnapped_wx); w_y = snap_grid (w_current, unsnapped_wy); if (event->type == GDK_2BUTTON_PRESS && w_current->event_state == SELECT) { /* Don't re-select an object (lp-912978) */ /* o_find_object(w_current, w_x, w_y, TRUE); */ /* GDK_BUTTON_EVENT is emitted before GDK_2BUTTON_EVENT, which * leads to setting of the inside_action flag. If o_edit() * brings up a modal window (e.g., the edit attribute dialog), * it intercepts the release button event and thus doesn't * allow resetting of the inside_action flag so we do it * manually here before processing the double-click event. */ i_action_stop (w_current); o_edit(w_current, geda_list_get_glist( page->selection_list )); scm_dynwind_end (); return(0); } w_current->SHIFTKEY = (event->state & GDK_SHIFT_MASK ) ? 1 : 0; w_current->CONTROLKEY = (event->state & GDK_CONTROL_MASK) ? 1 : 0; w_current->ALTKEY = (event->state & GDK_MOD1_MASK) ? 1 : 0; /* Huge switch statement to evaluate state transitions. Jump to * end_button_pressed label to escape the state evaluation rather than * returning from the function directly. */ if (event->button == 1) { if (w_current->inside_action) { /* End action */ if (page->place_list != NULL) { switch(w_current->event_state) { case (COMPMODE) : o_place_end(w_current, w_x, w_y, w_current->continue_component_place, "%add-objects-hook"); break; case (TEXTMODE) : o_place_end(w_current, w_x, w_y, FALSE, "%add-objects-hook"); break; case (PASTEMODE) : o_place_end(w_current, w_x, w_y, FALSE, "%paste-objects-hook"); break; default: break; } } else { switch(w_current->event_state) { case (ARCMODE) : o_arc_end1(w_current, w_x, w_y); break; case (BOXMODE) : o_box_end(w_current, w_x, w_y); break; case (BUSMODE) : o_bus_end(w_current, w_x, w_y); break; case (CIRCLEMODE) : o_circle_end(w_current, w_x, w_y); break; case (LINEMODE) : o_line_end(w_current, w_x, w_y); break; case (NETMODE) : o_net_end(w_current, w_x, w_y); break; case (PATHMODE) : o_path_continue (w_current, w_x, w_y); break; case (PICTUREMODE): o_picture_end(w_current, w_x, w_y); break; case (PINMODE) : o_pin_end (w_current, w_x, w_y); break; default: break; } } } else { /* Start action */ switch(w_current->event_state) { case (ARCMODE) : o_arc_start(w_current, w_x, w_y); break; case (BOXMODE) : o_box_start(w_current, w_x, w_y); break; case (BUSMODE) : o_bus_start(w_current, w_x, w_y); break; case (CIRCLEMODE) : o_circle_start(w_current, w_x, w_y); break; case (LINEMODE) : o_line_start(w_current, w_x, w_y); break; case (NETMODE) : o_net_start(w_current, w_x, w_y); break; case (PATHMODE) : o_path_start (w_current, w_x, w_y); break; case (PICTUREMODE): o_picture_start(w_current, w_x, w_y); break; case (PINMODE) : o_pin_start (w_current, w_x, w_y); break; case (ZOOMBOX) : a_zoom_box_start(w_current, unsnapped_wx, unsnapped_wy); break; case (SELECT) : o_select_start(w_current, w_x, w_y); break; case (COPYMODE) : case (MCOPYMODE) : o_copy_start(w_current, w_x, w_y); break; case (MOVEMODE) : o_move_start(w_current, w_x, w_y); break; default: break; } } switch(w_current->event_state) { case(ROTATEMODE): o_rotate_world_update(w_current, w_x, w_y, 90, geda_list_get_glist(page->selection_list)); break; case(MIRRORMODE): o_mirror_world_update(w_current, w_x, w_y, geda_list_get_glist(page->selection_list)); break; case(PAN): gschem_page_view_pan (page_view, w_x, w_y); i_set_state(w_current, SELECT); break; } } else if (event->button == 2) { /* try this out and see how it behaves */ if (w_current->inside_action) { if (!(w_current->event_state == COMPMODE|| w_current->event_state == TEXTMODE|| w_current->event_state == MOVEMODE|| w_current->event_state == COPYMODE || w_current->event_state == MCOPYMODE || w_current->event_state == PASTEMODE )) { i_callback_cancel(w_current, 0, NULL); } goto end_button_pressed; } switch(w_current->middle_button) { case(ACTION): /* don't want to search if shift */ /* key is pressed */ if (!w_current->SHIFTKEY) { o_find_object(w_current, unsnapped_wx, unsnapped_wy, TRUE); } /* make sure the list is not empty */ if (!o_select_selected(w_current)) { /* this means the above find did not * find anything */ i_action_stop (w_current); i_set_state(w_current, SELECT); goto end_button_pressed; } /* determine here if copy or move */ if (w_current->ALTKEY) { i_set_state(w_current, COPYMODE); o_copy_start(w_current, w_x, w_y); } else { o_move_start(w_current, w_x, w_y); } break; case(REPEAT): if (w_current->last_callback != NULL) { (*w_current->last_callback)(w_current, 0, NULL); } break; #ifdef HAVE_LIBSTROKE case(STROKE): DOING_STROKE=TRUE; break; #endif /* HAVE_LIBSTROKE */ case(MID_MOUSEPAN_ENABLED): gschem_page_view_pan_start (page_view, (int) event->x, (int) event->y); break; } } else if (event->button == 3) { if (!w_current->inside_action) { if (w_current->third_button == POPUP_ENABLED) { /* (third-button "popup") */ i_update_menus(w_current); /* update menus before popup */ do_popup(w_current, event); } else { /* (third-button "mousepan") */ gschem_page_view_pan_start (page_view, (int) event->x, (int) event->y); } } else { if ((w_current->third_button == MOUSEPAN_ENABLED) && (!w_current->third_button_cancel)) { gschem_page_view_pan_start (page_view, (int) event->x, (int) event->y); } else { /* this is the default cancel */ /* reset all draw and place actions */ switch (w_current->event_state) { case (ARCMODE) : o_arc_invalidate_rubber (w_current); break; case (BOXMODE) : o_box_invalidate_rubber (w_current); break; case (BUSMODE) : o_bus_invalidate_rubber (w_current); break; case (CIRCLEMODE) : o_circle_invalidate_rubber (w_current); break; case (LINEMODE) : o_line_invalidate_rubber (w_current); break; case (NETMODE) : o_net_reset (w_current); break; case (PATHMODE) : o_path_invalidate_rubber (w_current); break; case (PICTUREMODE): o_picture_invalidate_rubber (w_current); break; case (PINMODE) : o_pin_invalidate_rubber (w_current); break; default: i_callback_cancel(w_current, 0, NULL); break; } } } } end_button_pressed: scm_dynwind_end (); return(0); }
/*! \brief Update sensitivity of relevant menu items * * \par Function Description * Update sensitivity of relevant menu items. * * \param [in] w_current GSCHEM_TOPLEVEL structure */ void i_update_menus(GSCHEM_TOPLEVEL *w_current) { TOPLEVEL *toplevel = w_current->toplevel; /* * This is very simplistic. Right now it just disables all menu * items which get greyed out when a component is not selected. * Eventually what gets enabled/disabled * should be based on what is in the selection list */ g_assert(w_current != NULL); g_assert(toplevel->page_current != NULL); if (o_select_selected (w_current)) { /* since one or more things are selected, we set these TRUE */ /* These strings should NOT be internationalized */ x_menus_sensitivity(w_current, "Edit/Cut Buffer", TRUE); x_menus_sensitivity(w_current, "Edit/Copy Buffer", TRUE); x_menus_sensitivity(w_current, "Edit/Edit...", TRUE); x_menus_sensitivity(w_current, "Edit/Edit Text...", TRUE); x_menus_sensitivity(w_current, "Edit/Copy Mode", TRUE); x_menus_sensitivity(w_current, "Edit/Multiple Copy Mode", TRUE); x_menus_sensitivity(w_current, "Edit/Move Mode", TRUE); x_menus_sensitivity(w_current, "Edit/Delete", TRUE); x_menus_sensitivity(w_current, "Edit/Rotate 90 Mode", TRUE); x_menus_sensitivity(w_current, "Edit/Mirror Mode", TRUE); x_menus_sensitivity(w_current, "Edit/Slot...", TRUE); x_menus_sensitivity(w_current, "Edit/Color...", TRUE); x_menus_sensitivity(w_current, "Edit/Lock", TRUE); x_menus_sensitivity(w_current, "Edit/Unlock", TRUE); x_menus_sensitivity(w_current, "Edit/Line Width & Type...", TRUE); x_menus_sensitivity(w_current, "Edit/Fill Type...", TRUE); x_menus_sensitivity(w_current, "Edit/Embed Component/Picture", TRUE); x_menus_sensitivity(w_current, "Edit/Unembed Component/Picture", TRUE); x_menus_sensitivity(w_current, "Edit/Update Component", TRUE); x_menus_sensitivity(w_current, "Buffer/Copy into 1", TRUE); x_menus_sensitivity(w_current, "Buffer/Copy into 2", TRUE); x_menus_sensitivity(w_current, "Buffer/Copy into 3", TRUE); x_menus_sensitivity(w_current, "Buffer/Copy into 4", TRUE); x_menus_sensitivity(w_current, "Buffer/Copy into 5", TRUE); x_menus_sensitivity(w_current, "Buffer/Cut into 1", TRUE); x_menus_sensitivity(w_current, "Buffer/Cut into 2", TRUE); x_menus_sensitivity(w_current, "Buffer/Cut into 3", TRUE); x_menus_sensitivity(w_current, "Buffer/Cut into 4", TRUE); x_menus_sensitivity(w_current, "Buffer/Cut into 5", TRUE); x_menus_sensitivity(w_current, "Hierarchy/Down Schematic", TRUE); x_menus_sensitivity(w_current, "Hierarchy/Down Symbol", TRUE); x_menus_sensitivity(w_current, "Hierarchy/Documentation...", TRUE); x_menus_sensitivity(w_current, "Attributes/Attach", TRUE); x_menus_sensitivity(w_current, "Attributes/Detach", TRUE); x_menus_sensitivity(w_current, "Attributes/Show Value", TRUE); x_menus_sensitivity(w_current, "Attributes/Show Name", TRUE); x_menus_sensitivity(w_current, "Attributes/Show Both", TRUE); x_menus_sensitivity(w_current, "Attributes/Toggle Visibility", TRUE); /* Menu items for hierarchy added by SDB 1.9.2005. */ x_menus_popup_sensitivity(w_current, "/Down Schematic", TRUE); x_menus_popup_sensitivity(w_current, "/Down Symbol", TRUE); /* x_menus_popup_sensitivity(w_current, "/Up", TRUE); */ } else { /* Nothing is selected, grey these out */ /* These strings should NOT be internationalized */ x_menus_sensitivity(w_current, "Edit/Cut Buffer", FALSE); x_menus_sensitivity(w_current, "Edit/Copy Buffer", FALSE); x_menus_sensitivity(w_current, "Edit/Edit...", FALSE); x_menus_sensitivity(w_current, "Edit/Edit Text...", FALSE); x_menus_sensitivity(w_current, "Edit/Copy Mode", FALSE); x_menus_sensitivity(w_current, "Edit/Multiple Copy Mode", FALSE); x_menus_sensitivity(w_current, "Edit/Move Mode", FALSE); x_menus_sensitivity(w_current, "Edit/Delete", FALSE); x_menus_sensitivity(w_current, "Edit/Rotate 90 Mode", FALSE); x_menus_sensitivity(w_current, "Edit/Mirror Mode", FALSE); x_menus_sensitivity(w_current, "Edit/Slot...", FALSE); x_menus_sensitivity(w_current, "Edit/Color...", FALSE); x_menus_sensitivity(w_current, "Edit/Lock", FALSE); x_menus_sensitivity(w_current, "Edit/Unlock", FALSE); x_menus_sensitivity(w_current, "Edit/Line Width & Type...", FALSE); x_menus_sensitivity(w_current, "Edit/Fill Type...", FALSE); x_menus_sensitivity(w_current, "Edit/Embed Component/Picture", FALSE); x_menus_sensitivity(w_current, "Edit/Unembed Component/Picture", FALSE); x_menus_sensitivity(w_current, "Edit/Update Component", FALSE); x_menus_sensitivity(w_current, "Buffer/Copy into 1", FALSE); x_menus_sensitivity(w_current, "Buffer/Copy into 2", FALSE); x_menus_sensitivity(w_current, "Buffer/Copy into 3", FALSE); x_menus_sensitivity(w_current, "Buffer/Copy into 4", FALSE); x_menus_sensitivity(w_current, "Buffer/Copy into 5", FALSE); x_menus_sensitivity(w_current, "Buffer/Cut into 1", FALSE); x_menus_sensitivity(w_current, "Buffer/Cut into 2", FALSE); x_menus_sensitivity(w_current, "Buffer/Cut into 3", FALSE); x_menus_sensitivity(w_current, "Buffer/Cut into 4", FALSE); x_menus_sensitivity(w_current, "Buffer/Cut into 5", FALSE); x_menus_sensitivity(w_current, "Hierarchy/Down Schematic", FALSE); x_menus_sensitivity(w_current, "Hierarchy/Down Symbol", FALSE); x_menus_sensitivity(w_current, "Hierarchy/Documentation...", FALSE); x_menus_sensitivity(w_current, "Attributes/Attach", FALSE); x_menus_sensitivity(w_current, "Attributes/Detach", FALSE); x_menus_sensitivity(w_current, "Attributes/Show Value", FALSE); x_menus_sensitivity(w_current, "Attributes/Show Name", FALSE); x_menus_sensitivity(w_current, "Attributes/Show Both", FALSE); x_menus_sensitivity(w_current, "Attributes/Toggle Visibility", FALSE); /* Menu items for hierarchy added by SDB 1.9.2005. */ x_menus_popup_sensitivity(w_current, "/Down Schematic", FALSE); x_menus_popup_sensitivity(w_current, "/Down Symbol", FALSE); /* x_menus_popup_sensitivity(w_current, "/Up", FALSE); */ } x_menus_sensitivity(w_current, "Edit/Paste Buffer", (object_buffer[0] != NULL)); x_menus_sensitivity(w_current, "Buffer/Paste from 1", (object_buffer[0] != NULL)); x_menus_sensitivity(w_current, "Buffer/Paste from 2", (object_buffer[1] != NULL)); x_menus_sensitivity(w_current, "Buffer/Paste from 3", (object_buffer[2] != NULL)); x_menus_sensitivity(w_current, "Buffer/Paste from 4", (object_buffer[3] != NULL)); x_menus_sensitivity(w_current, "Buffer/Paste from 5", (object_buffer[4] != NULL)); }
/*! \brief Delete objects from the selection. * \par Function Description * This function deletes the objects selected on the current page of * toplevel \a w_current. * * \param [in] w_current The GschemToplevel object. */ void o_delete_selected (GschemToplevel *w_current) { TOPLEVEL *toplevel = gschem_toplevel_get_toplevel (w_current); SELECTION *selection = toplevel->page_current->selection_list; GList *to_remove; GList *iter; OBJECT *obj; unsigned int locked_num = 0; g_return_if_fail (o_select_selected (w_current)); to_remove = g_list_copy (geda_list_get_glist (selection)); for (iter = to_remove; iter != NULL; iter = g_list_next (iter)) { obj = (OBJECT *) iter->data; if (obj->selectable == FALSE) locked_num++; } if (locked_num > 0) { GList *non_locked = NULL; gint resp; GtkWidget *dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, ngettext ("Delete locked object?", "Delete %u locked objects?", locked_num), locked_num); gtk_dialog_add_buttons (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_YES, GTK_RESPONSE_YES, GTK_STOCK_NO, GTK_RESPONSE_NO, NULL); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_NO); resp = gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); switch (resp) { case GTK_RESPONSE_YES: /* Remove all */ break; case GTK_RESPONSE_NO: /* Remove non locked */ for (iter = to_remove; iter != NULL; iter = g_list_next (iter)) { obj = (OBJECT *) iter->data; if (obj->selectable == TRUE) non_locked = g_list_append (non_locked, iter->data); } g_list_free (to_remove); to_remove = non_locked; break; default: /* Cancel */ g_list_free (to_remove); return; } } for (iter = to_remove; iter != NULL; iter = g_list_next (iter)) { obj = (OBJECT *) iter->data; o_selection_remove (toplevel, selection, obj); s_page_remove (toplevel, toplevel->page_current, obj); } g_run_hook_object_list (w_current, "%remove-objects-hook", to_remove); for (iter = to_remove; iter != NULL; iter = g_list_next (iter)) { obj = (OBJECT *) iter->data; s_delete_object (toplevel, obj); } g_list_free (to_remove); gschem_toplevel_page_content_changed (w_current, toplevel->page_current); w_current->inside_action = 0; o_undo_savestate_old (w_current, UNDO_ALL); i_update_menus (w_current); }