/* This locks the entire selected list. It does lock components, but does NOT * change the color (of primatives of the components) though * this cannot be called recursively */ void o_lock(GSCHEM_TOPLEVEL *w_current) { OBJECT *object = NULL; GList *s_current = NULL; /* skip over head */ s_current = geda_list_get_glist( w_current->toplevel->page_current->selection_list ); while(s_current != NULL) { object = (OBJECT *) s_current->data; if (object) { /* check to see if locked_color is already being used */ if (object->locked_color == -1) { object->selectable = FALSE; object->locked_color = object->color; object->color = LOCK_COLOR; w_current->toplevel->page_current->CHANGED=1; } else { s_log_message(_("Object already locked\n")); } } s_current = g_list_next(s_current); } if (!w_current->SHIFTKEY) o_select_unselect_all(w_current); o_undo_savestate(w_current, UNDO_ALL); i_update_menus(w_current); }
/*! \todo Finish function documentation!!! * \brief * \par Function Description * * <B>type</B> can be one of the following values: * <DL> * <DT>*</DT><DD>UNDO_ACTION * <DT>*</DT><DD>REDO_ACTION * </DL> */ void o_undo_callback (GschemToplevel *w_current, PAGE *page, int type) { TOPLEVEL *toplevel = gschem_toplevel_get_toplevel (w_current); UNDO *u_current; UNDO *u_next; UNDO *save_bottom; UNDO *save_tos; UNDO *save_current; int save_logging; int find_prev_data=FALSE; char *save_filename; g_return_if_fail (w_current != NULL); g_return_if_fail (page != NULL); if (w_current->undo_control == FALSE) { s_log_message(_("Undo/Redo disabled in rc file\n")); return; } if (page->undo_current == NULL) { return; } if (type == UNDO_ACTION) { u_current = page->undo_current->prev; } else { u_current = page->undo_current->next; } u_next = page->undo_current; if (u_current == NULL) { return; } if (u_next->type == UNDO_ALL && u_current->type == UNDO_VIEWPORT_ONLY) { #if DEBUG printf("Type: %d\n", u_current->type); printf("Current is an undo all, next is viewport only!\n"); #endif find_prev_data = TRUE; if (w_current->undo_type == UNDO_DISK) { u_current->filename = o_undo_find_prev_filename(u_current); } else { u_current->object_list = o_undo_find_prev_object_head (u_current); } } /* save filename */ save_filename = g_strdup (page->page_filename); /* save structure so it's not nuked */ save_bottom = page->undo_bottom; save_tos = page->undo_tos; save_current = page->undo_current; page->undo_bottom = NULL; page->undo_tos = NULL; page->undo_current = NULL; o_select_unselect_all (w_current); if (w_current->undo_type == UNDO_DISK && u_current->filename) { /* delete objects of page */ s_page_delete_objects (toplevel, page); /* Free the objects in the place list. */ geda_object_list_delete (toplevel, page->place_list); page->place_list = NULL; gschem_toplevel_page_content_changed (w_current, page); } else if (w_current->undo_type == UNDO_MEMORY && u_current->object_list) { /* delete objects of page */ s_page_delete_objects (toplevel, page); /* Free the objects in the place list. */ geda_object_list_delete (toplevel, page->place_list); page->place_list = NULL; gschem_toplevel_page_content_changed (w_current, page); } /* temporarily disable logging */ save_logging = do_logging; do_logging = FALSE; if (w_current->undo_type == UNDO_DISK && u_current->filename) { f_open(toplevel, page, u_current->filename, NULL); } else if (w_current->undo_type == UNDO_MEMORY && u_current->object_list) { s_page_append_list (toplevel, page, o_glist_copy_all (toplevel, u_current->object_list, NULL)); } page->page_control = u_current->page_control; page->up = u_current->up; gschem_toplevel_page_content_changed (w_current, page); GschemPageView *view = gschem_toplevel_get_current_page_view (w_current); g_return_if_fail (view != NULL); GschemPageGeometry *geometry = gschem_page_view_get_page_geometry (view); if (u_current->scale != 0) { gschem_page_geometry_set_viewport (geometry, u_current->x, u_current->y, u_current->scale); gschem_page_view_invalidate_all (view); } else { gschem_page_view_zoom_extents (view, u_current->object_list); } /* restore logging */ do_logging = save_logging; /* set filename right */ g_free(page->page_filename); page->page_filename = save_filename; /* final redraw */ x_pagesel_update (w_current); x_multiattrib_update (w_current); i_update_menus(w_current); /* restore saved undo structures */ page->undo_bottom = save_bottom; page->undo_tos = save_tos; page->undo_current = save_current; if (type == UNDO_ACTION) { if (page->undo_current) { page->undo_current = page->undo_current->prev; if (page->undo_current == NULL) { page->undo_current = page->undo_bottom; } } } else { /* type is REDO_ACTION */ if (page->undo_current) { page->undo_current = page->undo_current->next; if (page->undo_current == NULL) { page->undo_current = page->undo_tos; } } } /* don't have to free data here since filename, object_list are */ /* just pointers to the real data (lower in the stack) */ if (find_prev_data) { u_current->filename = NULL; u_current->object_list = NULL; } #if DEBUG printf("\n\n---Undo----\n"); s_undo_print_all(page->undo_bottom); printf("TOS: %s\n", page->undo_tos->filename); printf("CURRENT: %s\n", page->undo_current->filename); printf("----\n"); #endif }
/*! \brief Find an OBJECT at a given set of coordinates * * \par Function Description * Tests for OBJECTS hit at a given set of coordinates. If * change_selection is TRUE, it updates the page's selection. * * Find operations resume searching after the last object which was * found, so multiple find operations at the same point will cycle * through any objects on top of each other at this location. * * \param [in] w_current The GschemToplevel object. * \param [in] w_x The X coordinate to test (in world coords). * \param [in] w_y The Y coordinate to test (in world coords). * \param [in] change_selection Whether to select the found object or not. * \returns TRUE if the object was hit at the given coordinates, * otherwise FALSE. */ gboolean o_find_object (GschemToplevel *w_current, int w_x, int w_y, gboolean change_selection) { GschemPageView *page_view = gschem_toplevel_get_current_page_view (w_current); g_return_val_if_fail (page_view != NULL, FALSE); TOPLEVEL *toplevel = gschem_toplevel_get_toplevel (w_current); g_return_val_if_fail (toplevel != NULL, FALSE); int w_slack; const GList *iter = NULL; w_slack = gschem_page_view_WORLDabs (page_view, w_current->select_slack_pixels); /* Decide whether to iterate over all object or start at the last found object. If there is more than one object below the (w_x/w_y) position, this will select the next object below the position point. You can change the selected object by clicking at the same place multiple times. */ if (toplevel->page_current->object_lastplace != NULL) { /* NB: g_list_find doesn't declare its input const, so we cast */ iter = g_list_find ((GList *)s_page_objects (toplevel->page_current), toplevel->page_current->object_lastplace); iter = g_list_next (iter); } /* do first search (if we found any objects after the last found object) */ while (iter != NULL) { OBJECT *o_current = iter->data; if (find_single_object (w_current, o_current, w_x, w_y, w_slack, change_selection)) { return TRUE; } iter = g_list_next (iter); } /* now search from the beginning up until the object_lastplace */ for (iter = s_page_objects (toplevel->page_current); iter != NULL; iter = g_list_next (iter)) { OBJECT *o_current = iter->data; if (find_single_object (w_current, o_current, w_x, w_y, w_slack, change_selection)) { return TRUE; } /* break once we've inspected up to where we started the first loop */ if (o_current == toplevel->page_current->object_lastplace) break; } /* didn't find anything.... reset lastplace */ toplevel->page_current->object_lastplace = NULL; /* deselect everything only if shift key isn't pressed and the caller allows it */ if (change_selection && (!w_current->SHIFTKEY)) { o_select_unselect_all (w_current); } i_update_menus(w_current); return FALSE; }