/*! \todo Finish function documentation!!! * \brief * \par Function Description * */ void o_edit_hide_specific_text (GschemToplevel *w_current, const GList *o_list, const char *stext) { TOPLEVEL *toplevel = gschem_toplevel_get_toplevel (w_current); OBJECT *o_current; const GList *iter; iter = o_list; while (iter != NULL) { o_current = (OBJECT *)iter->data; if (o_current->type == OBJ_TEXT) { const gchar *str = o_text_get_string (w_current->toplevel, o_current); if (!strncmp (stext, str, strlen (stext))) { if (o_is_visible (toplevel, o_current)) { o_set_visibility (toplevel, o_current, INVISIBLE); o_text_recreate(toplevel, o_current); gschem_toplevel_page_content_changed (w_current, toplevel->page_current); } } } iter = g_list_next (iter); } o_undo_savestate_old(w_current, UNDO_ALL); gschem_page_view_invalidate_all (gschem_toplevel_get_current_page_view (w_current)); }
/*! \brief Handles the press on a mouse button. * \par Function Description * It handles the user inputs. * * Three action are available: zoom in, pan and zoom out on preview display. * * \param [in] widget The preview widget. * \param [in] event The event structure. * \param [in] user_data Unused user data. * \returns FALSE to propagate the event further. */ static gboolean preview_callback_button_press (GtkWidget *widget, GdkEventButton *event, gpointer user_data) { Preview *preview = PREVIEW (widget); GschemToplevel *preview_w_current = preview->preview_w_current; gint wx, wy; if (!preview->active) { return TRUE; } switch (event->button) { case 1: /* left mouse button: zoom in */ a_zoom (preview_w_current, GSCHEM_PAGE_VIEW (preview), ZOOM_IN, HOTKEY); gschem_page_view_invalidate_all (GSCHEM_PAGE_VIEW (widget)); break; case 2: /* middle mouse button: pan */ if (!x_event_get_pointer_position(preview_w_current, FALSE, &wx, &wy)) return FALSE; gschem_page_view_pan (GSCHEM_PAGE_VIEW (preview), wx, wy); break; case 3: /* right mouse button: zoom out */ a_zoom (preview_w_current, GSCHEM_PAGE_VIEW (preview), ZOOM_OUT, HOTKEY); gschem_page_view_invalidate_all (GSCHEM_PAGE_VIEW (widget)); break; } return FALSE; }
/*! \brief Property change notification for any/all settings * * \param [in] w_current */ static void notify_options (GschemToplevel *w_current) { g_return_if_fail (w_current != NULL); /* Events can occur before the drawing area is created */ if (w_current->drawing_area != NULL) { /* maybe remove those two lines * gschem_toplevel_get_toplevel (w_current)->page_current->CHANGED=1; * o_undo_savestate_old(w_current, UNDO_ALL); */ i_update_grid_info (w_current); gschem_page_view_invalidate_all (gschem_toplevel_get_current_page_view (w_current)); } }
/*! \todo Finish function documentation!!! * \brief * \par Function Description * */ void o_edit_show_hidden (GschemToplevel *w_current, const GList *o_list) { /* this function just shows the hidden text, but doesn't toggle it */ /* this function does not change the CHANGED bit, no real changes are */ /* made to the schematic */ /* toggle show_hidden_text variable, which when it is true */ /* means that hidden text IS drawn */ w_current->toplevel->show_hidden_text = !w_current->toplevel->show_hidden_text; i_show_state(w_current, NULL); /* update screen status */ o_edit_show_hidden_lowlevel(w_current, o_list); gschem_page_view_invalidate_all (gschem_toplevel_get_current_page_view (w_current)); if (w_current->toplevel->show_hidden_text) { s_log_message(_("Hidden text is now visible\n")); } else { s_log_message(_("Hidden text is now invisible\n")); } }
/*! \brief Changes the current page. * \par Function Description * This function displays the specified page <B>page</B> in the * window attached to <B>toplevel</B>. * * It changes the <B>toplevel</B>'s current page to <B>page</B>, * draws it and updates the user interface. * * <B>page</B> has to be in the list of PAGEs attached to <B>toplevel</B>. * * \param [in] w_current The toplevel environment. * \param [in] page The page to become current page. */ void x_window_set_current_page (GschemToplevel *w_current, PAGE *page) { GschemPageView *page_view = gschem_toplevel_get_current_page_view (w_current); g_return_if_fail (page != NULL); g_return_if_fail (page_view != NULL); o_redraw_cleanstates (w_current); gschem_page_view_set_page (page_view, page); i_update_menus (w_current); i_set_filename (w_current, page->page_filename); x_pagesel_update (w_current); x_multiattrib_update (w_current); gschem_page_view_update_scroll_adjustments (page_view); gschem_page_view_invalidate_all (page_view); }
/*! \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 Handles all the options of the autonumber text dialog * \par Function Description * This function is the master of all autonumber code. It receives the options of * the the autonumber text dialog in an <B>AUTONUMBER_TEXT</B> structure. * First it collects all pages of a hierarchical schematic. * Second it gets all matching text elements for the searchtext. * Then it renumbers all text elements of all schematic pages. The renumbering * follows the rules of the parameters given in the autonumber text dialog. */ void autonumber_text_autonumber(AUTONUMBER_TEXT *autotext) { GList *pages; GList *searchtext_list=NULL; GList *text_item, *obj_item, *page_item; OBJECT *o_current; GschemToplevel *w_current; gchar *searchtext; gchar *scope_text; gchar *new_searchtext; gint i, number, slot; GList *o_list = NULL; const GList *iter; w_current = autotext->w_current; autotext->current_searchtext = NULL; autotext->root_page = 1; autotext->used_numbers = NULL; autotext->free_slots = NULL; autotext->used_slots = NULL; scope_text = g_list_first(autotext->scope_text)->data; /* Step1: get all pages of the hierarchy */ pages = s_hierarchy_traversepages (w_current->toplevel, w_current->toplevel->page_current, HIERARCHY_NODUPS); /* g_list_foreach(pages, (GFunc) s_hierarchy_print_page, NULL); */ /* Step2: if searchtext has an asterisk at the end we have to find all matching searchtextes. Example: "refdes=*" will match each text that starts with "refdes=" and has a trailing "?" or a trailing number if the "all"-option is set. We get a list of possible prefixes: refdes=R, refdes=C. If there is only one search pattern, it becomes a single item in the searchtext list */ if (strlen(scope_text) == 0) { s_log_message(_("No searchstring given in autonumber text.\n")); return; /* error */ } else if (g_str_has_suffix(scope_text,"?") == TRUE) { /* single searchtext, strip of the "?" */ searchtext = g_strndup(scope_text, strlen(scope_text)-1); searchtext_list=g_list_append (searchtext_list, searchtext); } else if (g_str_has_suffix(scope_text,"*") == TRUE) { /* strip of the "*" */ searchtext = g_strndup(scope_text, strlen(scope_text)-1); /* collect all the possible searchtexts in all pages of the hierarchy */ for (page_item = pages; page_item != NULL; page_item = g_list_next(page_item)) { s_page_goto(w_current->toplevel, page_item->data); gschem_toplevel_page_changed (w_current); /* iterate over all objects an look for matching searchtext's */ for (iter = s_page_objects (w_current->toplevel->page_current); iter != NULL; iter = g_list_next (iter)) { o_current = iter->data; if (o_current->type == OBJ_TEXT) { if (autotext->scope_number == SCOPE_HIERARCHY || autotext->scope_number == SCOPE_PAGE || ((autotext->scope_number == SCOPE_SELECTED) && (o_current->selected))) { const gchar *str = o_text_get_string (w_current->toplevel, o_current); if (g_str_has_prefix (str, searchtext)) { /* the beginnig of the current text matches with the searchtext now */ /* strip of the trailing [0-9?] chars and add it too the searchtext */ for (i = strlen (str)-1; (i >= strlen(searchtext)) && (str[i] == '?' || isdigit( (int) (str[i]) )); i--) ; /* void */ new_searchtext = g_strndup (str, i+1); if (g_list_find_custom(searchtext_list, new_searchtext, (GCompareFunc) strcmp) == NULL ) { searchtext_list = g_list_append(searchtext_list, new_searchtext); } else { g_free(new_searchtext); } } } } } if (autotext->scope_number == SCOPE_SELECTED || autotext->scope_number == SCOPE_PAGE) break; /* search only in the first page */ } g_free(searchtext); } else { s_log_message(_("No '*' or '?' given at the end of the autonumber text.\n")); return; } /* Step3: iterate over the search items in the list */ for (text_item=searchtext_list; text_item !=NULL; text_item=g_list_next(text_item)) { autotext->current_searchtext = text_item->data; /* printf("autonumber_text_autonumber: searchtext %s\n", autotext->current_searchtext); */ /* decide whether to renumber page by page or get a global used-list */ if (autotext->scope_skip == SCOPE_HIERARCHY) { /* whole hierarchy database */ /* renumbering all means that no db is required */ if (!(autotext->scope_number == SCOPE_HIERARCHY && autotext->scope_overwrite)) { for (page_item = pages; page_item != NULL; page_item = g_list_next(page_item)) { autotext->root_page = (pages->data == page_item->data); s_page_goto(w_current->toplevel, page_item->data); gschem_toplevel_page_changed (w_current); autonumber_get_used(w_current, autotext); } } } /* renumber the elements */ for (page_item = pages; page_item != NULL; page_item = g_list_next(page_item)) { s_page_goto(w_current->toplevel, page_item->data); gschem_toplevel_page_changed (w_current); autotext->root_page = (pages->data == page_item->data); /* build a page database if we're numbering pagebypage or selection only*/ if (autotext->scope_skip == SCOPE_PAGE || autotext->scope_skip == SCOPE_SELECTED) { autonumber_get_used(w_current, autotext); } /* RENUMBER CODE FOR ONE PAGE AND ONE SEARCHTEXT*/ /* 1. get objects to renumber */ for (iter = s_page_objects (w_current->toplevel->page_current); iter != NULL; iter = g_list_next (iter)) { o_current = iter->data; if (autonumber_match(autotext, o_current, &number) == AUTONUMBER_RENUMBER) { /* put number into the used list */ o_list = g_list_append(o_list, o_current); } } /* 2. sort object list */ switch (autotext->order) { case AUTONUMBER_SORT_YX: o_list=g_list_sort(o_list, autonumber_sort_yx); break; case AUTONUMBER_SORT_YX_REV: o_list=g_list_sort(o_list, autonumber_sort_yx_rev); break; case AUTONUMBER_SORT_XY: o_list=g_list_sort(o_list, autonumber_sort_xy); break; case AUTONUMBER_SORT_XY_REV: o_list=g_list_sort(o_list, autonumber_sort_xy_rev); break; case AUTONUMBER_SORT_DIAGONAL: o_list=g_list_sort(o_list, autonumber_sort_diagonal); break; default: ; /* unsorted file order */ } /* 3. renumber/reslot the objects */ for(obj_item=o_list; obj_item != NULL; obj_item=g_list_next(obj_item)) { o_current= obj_item->data; if(autotext->removenum) { autonumber_remove_number(autotext, o_current); } else { /* get valid numbers from the database */ autonumber_get_new_numbers(autotext, o_current, &number, &slot); /* and apply it. TODO: join these two functions */ autonumber_apply_new_text(autotext, o_current, number, slot); } } g_list_free(o_list); o_list = NULL; /* destroy the page database */ if (autotext->scope_skip == SCOPE_PAGE || autotext->scope_skip == SCOPE_SELECTED) autonumber_clear_database(autotext); if (autotext->scope_number == SCOPE_SELECTED || autotext->scope_number == SCOPE_PAGE) break; /* only renumber the parent page (the first page) */ } autonumber_clear_database(autotext); /* cleanup */ } /* cleanup and redraw all*/ g_list_foreach(searchtext_list, (GFunc) g_free, NULL); g_list_free(searchtext_list); s_page_goto(w_current->toplevel, pages->data); /* go back to the root page */ gschem_toplevel_page_changed (w_current); gschem_page_view_invalidate_all (gschem_toplevel_get_current_page_view (w_current)); g_list_free(pages); o_undo_savestate_old(w_current, UNDO_ALL); }