/*! \brief Copy data from gtksheet into TOPLEVEL struct * * Called when the user invokes "save". It first * places all data from gtksheet into SHEET_DATA. Then it * loops through all pages & calls s_toplevel_sheetdata_to_toplevel() * to place all * stuff in SHEET_DATA into the libgeda TOPLEVEL structure. */ void s_toplevel_gtksheet_to_toplevel(TOPLEVEL *toplevel) { GList *iter; PAGE *p_current; #if DEBUG printf("--------------------- Entering s_toplevel_gtksheet_to_toplevel -------------------\n"); #endif s_sheet_data_gtksheet_to_sheetdata(); /* read data from gtksheet into SHEET_DATA */ #if DEBUG printf("In s_toplevel_gtksheet_to_toplevel -- done writing stuff from gtksheet into SHEET_DATA.\n"); #endif /* must iterate over all pages in design */ for ( iter = geda_list_get_glist( toplevel->pages ); iter != NULL; iter = g_list_next( iter ) ) { p_current = (PAGE *)iter->data; toplevel->page_current = p_current; /* only traverse pages which are toplevel */ if (p_current->page_control == 0) { s_toplevel_sheetdata_to_toplevel (toplevel, p_current); /* adds all objects from page */ } } #if DEBUG printf("In s_toplevel_gtksheet_to_toplevel -- done writing SHEEET_DATA text back into pr_currnet.\n"); #endif return; }
/* otherwise unembed all components in all pages */ void s_util_embed(TOPLEVEL *pr_current, int embed_mode) { GList *p_iter, *o_iter; for (p_iter = geda_list_get_glist (pr_current->pages); p_iter != NULL; p_iter = g_list_next (p_iter)) { PAGE *p_current = p_iter->data; /* Cast removes const qualifier from return value of * s_page_objects() */ for (o_iter = (GList *) s_page_objects (p_current); o_iter != NULL; o_iter = g_list_next (o_iter)) { OBJECT *o_current = o_iter->data; if (o_current->type == OBJ_COMPLEX || o_current->type == OBJ_PICTURE) { if (embed_mode == TRUE) { o_embed(pr_current, o_current); } else { o_unembed(pr_current, o_current); } } } } }
/*! \brief Verify the entire design * * This function loops through all components in the * design looking for components which are placeholders. * * Placeholders are inserted into the object list when * no symbol file is found. If this function finds a * placeholder, it warns the user. * * \param toplevel pointer to the toplevel object to be verified */ void s_toplevel_verify_design (TOPLEVEL *toplevel) { GList *p_iter; const GList *o_iter; int missing_sym_flag = 0; for (p_iter = geda_list_get_glist (toplevel->pages); p_iter != NULL; p_iter = g_list_next (p_iter)) { PAGE *p_current = p_iter->data; for (o_iter = s_page_objects (p_current); o_iter != NULL; o_iter = g_list_next (o_iter)) { OBJECT *o_current = o_iter->data; /* --- look for object, and verify that it has a symbol file attached. ---- */ if (o_current->type == OBJ_PLACEHOLDER) { missing_sym_flag = 1; /* flag to signal that problem exists. */ } } } if (missing_sym_flag) { x_dialog_missing_sym(); /* dialog gives user option to quit */ } }
/*! \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); }
/*! \brief Update tree model of <B>pagesel</B>'s treeview. * \par Function Description * Updates the tree model of <B>pagesel</B>\'s treeview. * * Right now, each time it is called, it rebuilds all the model from the * list of pages passed in. * It is a recursive function to populate the tree store * * \param [in] model GtkTreeModel to update. * \param [in] parent GtkTreeIter pointer to tree root. * \param [in] pages GedaPageList of pages for this toplevel. * \param [in] page The PAGE object to update tree model from. */ static void add_page (GtkTreeModel *model, GtkTreeIter *parent, GedaPageList *pages, PAGE *page) { GtkTreeIter iter; PAGE *p_current; GList *p_iter; /* add the page to the store */ gtk_tree_store_append (GTK_TREE_STORE (model), &iter, parent); gtk_tree_store_set (GTK_TREE_STORE (model), &iter, COLUMN_PAGE, page, COLUMN_NAME, page->page_filename, COLUMN_CHANGED, page->CHANGED, -1); /* search a page that has a up field == p_current->pid */ for ( p_iter = geda_list_get_glist( pages ); p_iter != NULL; p_iter = g_list_next( p_iter ) ) { p_current = (PAGE *)p_iter->data; if (p_current->up == page->pid) { add_page (model, &iter, pages, p_current); } } }
/*! \todo Finish function documentation!!! * \brief * \par Function Description * */ void pagesel_update (Pagesel *pagesel) { GtkTreeModel *model; TOPLEVEL *toplevel; PAGE *p_current; GList *iter; g_assert (IS_PAGESEL (pagesel)); g_return_if_fail (GSCHEM_DIALOG (pagesel)->w_current); toplevel = GSCHEM_DIALOG (pagesel)->w_current->toplevel; model = gtk_tree_view_get_model (pagesel->treeview); /* wipe out every thing in the store */ gtk_tree_store_clear (GTK_TREE_STORE (model)); /* now rebuild */ for ( iter = geda_list_get_glist( toplevel->pages ); iter != NULL; iter = g_list_next( iter ) ) { p_current = (PAGE *)iter->data; /* find every page that is not a hierarchy-down of another page */ if (p_current->up < 0 || s_page_search_by_page_id (toplevel->pages, p_current->up) == NULL) { add_page (model, NULL, toplevel->pages, p_current); } } /* select the current page in the treeview */ select_page (pagesel->treeview, NULL, toplevel->page_current); }
static void export_pdf (void) { cairo_surface_t *surface; cairo_rectangle_t extents; cairo_matrix_t mtx; cairo_t *cr; GList *iter; /* Create a surface. To begin with, we don't know the size. */ surface = cairo_pdf_surface_create (settings.outfile, 1, 1); cr = cairo_create (surface); g_object_set (renderer, "cairo-context", cr, NULL); for (iter = geda_list_get_glist (toplevel->pages); iter != NULL; iter = g_list_next (iter)) { PAGE *page = (PAGE *) iter->data; export_layout_page (page, &extents, &mtx); cairo_pdf_surface_set_size (surface, extents.width, extents.height); cairo_set_matrix (cr, &mtx); export_draw_page (page); cairo_show_page (cr); } cairo_surface_finish (surface); export_cairo_check_error (cairo_surface_status (surface)); }
/*! \brief Replace all selected pictures with a new picture * \par Function Description * Replaces all pictures in the current selection with a new image. * * \param [in] w_current The GschemToplevel object * \param [in] filename The filename of the new picture * \param [out] error The location to return error information. * \return TRUE on success, FALSE on failure. */ gboolean o_picture_exchange (GschemToplevel *w_current, const gchar *filename, GError **error) { TOPLEVEL *toplevel = gschem_toplevel_get_toplevel (w_current); GList *iter; for (iter = geda_list_get_glist (toplevel->page_current->selection_list); iter != NULL; iter = g_list_next (iter)) { OBJECT *object = (OBJECT *) iter->data; g_assert (object != NULL); if (object->type == OBJ_PICTURE) { gboolean status; /* Erase previous picture */ o_invalidate (w_current, object); status = o_picture_set_from_file (toplevel, object, filename, error); if (!status) return FALSE; /* Draw new picture */ o_invalidate (w_current, object); } } return TRUE; }
/* this cannot be called recursively */ void o_unlock(GSCHEM_TOPLEVEL *w_current) { OBJECT *object = NULL; GList *s_current = NULL; s_current = geda_list_get_glist( w_current->toplevel->page_current->selection_list ); while(s_current != NULL) { object = (OBJECT *) s_current->data; if (object) { /* only unlock if the object is locked */ if (object->selectable == FALSE) { object->selectable = TRUE; object->color = object->locked_color; object->locked_color = -1; w_current->toplevel->page_current->CHANGED = 1; } else { s_log_message(_("Object already unlocked\n")); } } s_current = g_list_next(s_current); } o_undo_savestate(w_current, UNDO_ALL); }
/*! \brief Saves all the pages of a TOPLEVEL object. * \par Function Description * Saves all the pages in the <B>toplevel</B> parameter. * * \param [in] toplevel The TOPLEVEL to save pages from. * \return The number of failed tries to save a page. */ gint s_page_save_all (TOPLEVEL *toplevel) { const GList *iter; PAGE *p_current; gint status = 0; for ( iter = geda_list_get_glist( toplevel->pages ); iter != NULL; iter = g_list_next( iter ) ) { p_current = (PAGE *)iter->data; if (f_save (toplevel, p_current, p_current->page_filename, NULL)) { s_log_message (_("Saved [%s]\n"), p_current->page_filename); /* reset the CHANGED flag of p_current */ p_current->CHANGED = 0; } else { s_log_message (_("Could NOT save [%s]\n"), p_current->page_filename); /* increase the error counter */ status++; } } return status; }
/* 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); }
/* Actually draws a page. If page is NULL, uses the first open page. */ static void export_draw_page (PAGE *page) { const GList *contents; GList *iter; cairo_t *cr; cr = eda_renderer_get_cairo_context (renderer); if (page == NULL) { const GList *pages = geda_list_get_glist (toplevel->pages); g_assert (pages != NULL && pages->data != NULL); page = (PAGE *) pages->data; } /* Draw background */ eda_cairo_set_source_color (cr, OUTPUT_BACKGROUND_COLOR, eda_renderer_get_color_map (renderer)); cairo_paint (cr); /* Draw objects & cues */ contents = s_page_objects (page); for (iter = (GList *) contents; iter != NULL; iter = g_list_next (iter)) eda_renderer_draw (renderer, (OBJECT *) iter->data); for (iter = (GList *) contents; iter != NULL; iter = g_list_next (iter)) eda_renderer_draw_cues (renderer, (OBJECT *) iter->data); }
void s_traverse_start(TOPLEVEL * pr_current) { GList *iter; PAGE *p_current; for ( iter = geda_list_get_glist( pr_current->pages ); iter != NULL; iter = g_list_next( iter ) ) { p_current = (PAGE *)iter->data; /* only traverse pages which are toplevel, ie not underneath */ if (p_current->page_control == 0) { pr_current->page_current = p_current; s_traverse_sheet (pr_current, s_page_objects (p_current), NULL); } } /* now that all the sheets have been read, go through and do the */ /* post processing work */ s_netlist_post_process(pr_current, netlist_head); /* Now match the graphical netlist with the net names already assigned */ s_netlist_name_named_nets(pr_current, netlist_head, graphical_netlist_head); if (verbose_mode) { printf("\nInternal netlist representation:\n\n"); s_netlist_print(netlist_head); } }
/*! \brief Complete the text edit * * \par Function Description * This function completes the text edit by setting all the selected text * objects to the desired values. * * \param [in] w_current The topleval gschem struct. * \param [in] string The text to set the selected text objects to. If this * string is NULL or has zero length, then this function * leaves the text unchanged. * \param [in] color The color to set the selected text to. If the color * is less than zero, then this function leaves the color * unchanged. * \param [in] align The text alignment to set the selected text to. If * the alignment is less than zero, this function leaves * the alignment unchanged. * \param [in] rotate The rotation angle to set the selected text to. If * the rotation angle is less than zero, this function * leaves the rotation angle unchanged. * \param [in] size The size to set all the selected text to. If the * size is less than or equal to zero, this function * leaves the size unchanged. */ void o_text_edit_end(GschemToplevel *w_current, char *string, int color, int align, int rotate, int size) { GschemPageView *page_view = gschem_toplevel_get_current_page_view (w_current); TOPLEVEL *toplevel = gschem_page_view_get_toplevel (page_view); PAGE *page = gschem_page_view_get_page (page_view); OBJECT *object; GList *s_current; char *textstr = string; g_return_if_fail (toplevel != NULL); g_return_if_fail (page != NULL); if ((textstr != NULL) && (g_utf8_strlen(textstr, -1) == 0)) { textstr = NULL; } /* skip over head */ s_current = geda_list_get_glist (page->selection_list); while(s_current != NULL) { object = (OBJECT *) s_current->data; if (object) { if (object->type == OBJ_TEXT) { if (size > 0) { object->text->size = size; } if (align >= 0) { object->text->alignment = align; } if (color >= 0) { object->color = color; } if (rotate >= 0) { object->text->angle = rotate; } if (textstr != NULL) { o_text_set_string (toplevel, object, textstr); /* handle slot= attribute, it's a special case */ if (object->attached_to != NULL && g_ascii_strncasecmp (textstr, "slot=", 5) == 0) { o_slot_end (w_current, object->attached_to, textstr); } } o_text_recreate(toplevel, object); } } s_current = g_list_next(s_current); } gschem_toplevel_page_content_changed (w_current, page); o_undo_savestate(w_current, page, UNDO_ALL); }
/* this cannot be called recursively */ void o_unlock(GschemToplevel *w_current) { OBJECT *object = NULL; GList *s_current = NULL; s_current = geda_list_get_glist( w_current->toplevel->page_current->selection_list ); while(s_current != NULL) { object = (OBJECT *) s_current->data; if (object) { /* only unlock if the object is locked */ if (object->selectable == FALSE) { object->selectable = TRUE; object->color = object->locked_color; object->locked_color = -1; gschem_toplevel_page_content_changed (w_current, w_current->toplevel->page_current); } else { s_log_message(_("Object already unlocked\n")); } } s_current = g_list_next(s_current); } o_undo_savestate_old(w_current, UNDO_ALL); }
/*! \brief Autosave callback function. * \par Function Description * This function is a callback of the glib g_timeout functions. * It is called every "interval" milliseconds and it sets a flag to save * a backup copy of the opened pages. * * \param [in] toplevel The TOPLEVEL object. * \return The length in milliseconds to set for next interval. */ gint s_page_autosave (TOPLEVEL *toplevel) { const GList *iter; PAGE *p_current; if (toplevel == NULL) { return 0; } /* Do nothing if the interval is 0 */ if (toplevel->auto_save_interval == 0) { return toplevel->auto_save_interval; } /* Should we just disable the autosave timeout returning 0 or just wait for more pages to be added? */ if ( toplevel->pages == NULL) return toplevel->auto_save_interval; for ( iter = geda_list_get_glist( toplevel->pages ); iter != NULL; iter = g_list_next( iter ) ) { p_current = (PAGE *)iter->data; if (p_current->ops_since_last_backup != 0) { /* Real autosave is done in o_undo_savestate */ p_current->do_autosave_backup = 1; } } return toplevel->auto_save_interval; }
/*! \brief Closes a page. * \par Function Description * This function closes the page <B>page</B> of toplevel * <B>toplevel</B>. * * If necessary, the current page of <B>toplevel</B> is changed to * the next valid page or to a new untitled page. * * \param [in] w_current The toplevel environment. * \param [in] page The page to close. */ void x_window_close_page (GSCHEM_TOPLEVEL *w_current, PAGE *page) { TOPLEVEL *toplevel = w_current->toplevel; PAGE *new_current = NULL; GList *iter; g_return_if_fail (toplevel != NULL); g_return_if_fail (page != NULL); g_assert (page->pid != -1); /* If we're closing whilst inside a move action, re-wind the * page contents back to their state before we started */ if (w_current->inside_action && (w_current->event_state == MOVE || w_current->event_state == ENDMOVE)) { o_move_cancel (w_current); } if (page == toplevel->page_current) { /* as it will delete current page, select new current page */ /* first look up in page hierarchy */ new_current = s_page_search_by_page_id (toplevel->pages, page->up); if (new_current == NULL) { /* no up in hierarchy, choice is prev, next, new page */ iter = g_list_find( geda_list_get_glist( toplevel->pages ), page ); if ( g_list_previous( iter ) ) { new_current = (PAGE *)g_list_previous( iter )->data; } else if ( g_list_next( iter ) ) { new_current = (PAGE *)g_list_next( iter )->data; } else { /* need to add a new untitled page */ new_current = NULL; } } /* new_current will be the new current page at the end of the function */ } s_log_message (page->CHANGED ? _("Discarding page [%s]\n") : _("Closing [%s]\n"), page->page_filename); /* remove page from toplevel list of page and free */ s_page_delete (toplevel, page); /* Switch to a different page if we just removed the current */ if (toplevel->page_current == NULL) { /* Create a new page if there wasn't another to switch to */ if (new_current == NULL) { new_current = x_window_open_page (w_current, NULL); } /* change to new_current and update display */ x_window_set_current_page (w_current, new_current); } }
/*! \brief Get a list of symbols used. * \par Function Description * * Scan a #TOPLEVEL structure's object list looking for symbols, and * return them in a list. * * \warning The #CLibSymbol instances in the \b GList returned belong * to the component library, and should be considered constants; they * should not be manipulated or free()'d. On the other hand, the \b * GList returned must be freed with \b g_list_free() when no longer * needed. Note that the values returned will be invalidated by a * call to s_clib_free() or s_clib_refresh(). * * \bug Only includes components which are not embedded, but they * should (probably) also appear in the list. * * \param toplevel #TOPLEVEL structure to scan. * \return GList of symbols. */ GList *s_toplevel_get_symbols (const TOPLEVEL *toplevel) { GList *result = NULL; GList *iter = NULL; OBJECT *o = NULL; PAGE *page; GList *symlist = NULL; CLibSymbol *sym = NULL; const GList *p_iter; const GList *o_iter; g_return_val_if_fail ((toplevel != NULL), NULL); for ( p_iter = geda_list_get_glist( toplevel->pages ); p_iter != NULL; p_iter = g_list_next( p_iter )) { page = (PAGE *)p_iter->data; for (o_iter = s_page_objects (page); o_iter != NULL; o_iter = g_list_next (o_iter)) { o = (OBJECT *)o_iter->data; if (o->type != OBJ_COMPLEX) continue; if (o->complex_basename == NULL) continue; /* Since we're not looking at embedded symbols, the first * component with the given name will be the one we need. * N.b. we don't use s_clib_get_symbol_by_name() because it's * spammeh. */ symlist = s_clib_search (o->complex_basename, CLIB_EXACT); if (symlist == NULL) continue; sym = (CLibSymbol *) symlist->data; g_list_free (symlist); /* We do the list insertion by evilly comparing pointers. This * is okay, because we always take the first symbol with the * given name, and symbol pointers don't change while this * function is running (we hope). Note that this creates a * sorted list.*/ for (iter = result; iter != NULL; iter = g_list_next(iter)) { if (iter->data == sym) { break; /* Already in list */ } if (compare_symbol_name (iter->data, sym) > 0) { /* not in list yet, and gone past point where it should go */ result = g_list_insert_before (result, iter, sym); break; } } if (iter == NULL) { /* not in list yet, and at end of list */ result = g_list_append (result, sym); } } } return result; }
/*! \brief Reset the CHANGED flag of all pages. * \par Function Description * This function resets the CHANGED flag of each page following \a head. * * \param [in,out] list PAGE list to set CHANGED flags in. */ void s_page_clear_changed (GedaPageList *list) { const GList *iter; PAGE *p_current; for ( iter = geda_list_get_glist( list ); iter != NULL; iter = g_list_next( iter ) ) { p_current = (PAGE *)iter->data; p_current->CHANGED = 0; } }
/*! \brief Print full TOPLEVEL structure. * \par Function Description * This function prints the internal structure of <B>toplevel</B>'s * list of pages. * * \param [in] toplevel The TOPLEVEL object to print. */ void s_page_print_all (TOPLEVEL *toplevel) { const GList *iter; PAGE *page; for ( iter = geda_list_get_glist( toplevel->pages ); iter != NULL; iter = g_list_next( iter ) ) { page = (PAGE *)iter->data; printf ("FILENAME: %s\n", page->page_filename); print_struct_forw (page->_object_list); } }
/*! \brief Search for pages by filename. * \par Function Description * Searches in \a toplevel's list of pages for a page with a filename * equal to \a filename. * * \param toplevel The TOPLEVEL object * \param filename The filename string to search for * * \return PAGE pointer to a matching page, NULL otherwise. */ PAGE *s_page_search (TOPLEVEL *toplevel, const gchar *filename) { const GList *iter; PAGE *page; for ( iter = geda_list_get_glist( toplevel->pages ); iter != NULL; iter = g_list_next( iter ) ) { page = (PAGE *)iter->data; if ( g_strcasecmp( page->page_filename, filename ) == 0 ) return page; } return NULL; }
/*! \brief Search for a page given its page id in a page list. * \par Function Description * This functions returns the page that have the page id \a pid in * the list of pages starting at \a page_list, or NULL if there is no * such page. * * \param [in] list The list of page to search the page in. * \param [in] pid The ID of the page to find. * \returns A pointer on the page found or NULL if not found. */ PAGE *s_page_search_by_page_id (GedaPageList *list, int pid) { const GList *iter; for ( iter = geda_list_get_glist (list); iter != NULL; iter = g_list_next (iter) ) { PAGE *page = (PAGE *)iter->data; if (page->pid == pid) { return page; } } return NULL; }
/*! \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); } }
/*! \brief Check if CHANGED flag is set for any page in list. * \par Function Description * This function checks the CHANGED flag for all pages in the <B>list</B> * object. * * \param [in] list GedaPageList to check CHANGED flag in. * \return 1 if any page has the CHANGED flag set, 0 otherwise. */ gboolean s_page_check_changed (GedaPageList *list) { const GList *iter; PAGE *p_current; for ( iter = geda_list_get_glist( list ); iter != NULL; iter = g_list_next( iter ) ) { p_current = (PAGE *)iter->data; if (p_current->CHANGED) { return TRUE; } } return FALSE; }
/*! \brief Updates the display when drawing area is configured. * \par Function Description * This is the callback function connected to the configure event of * the GschemPageView of the main window. * * It re-pans each of its pages to keep their contents centered in the * GschemPageView. * * When the window is maximised, the zoom of every page is changed to * best fit the previously displayed area of the page in the new * area. Otherwise the current zoom level is left unchanged. * * \param [in] widget The GschemPageView which received the signal. * \param [in] event The event structure of signal configure-event. * \param [in] unused * \returns FALSE to propagate the event further. */ gboolean x_event_configure (GschemPageView *page_view, GdkEventConfigure *event, gpointer unused) { GtkAllocation current_allocation; GList *iter; PAGE *p_current = gschem_page_view_get_page (page_view); if (p_current == NULL) { /* don't want to call this if the current page isn't setup yet */ return FALSE; } g_return_val_if_fail (p_current->toplevel != NULL, FALSE); gtk_widget_get_allocation (GTK_WIDGET(page_view), ¤t_allocation); if ((current_allocation.width == page_view->previous_allocation.width) && (current_allocation.height == page_view->previous_allocation.height)) { /* the size of the drawing area has not changed -- nothing to do here */ return FALSE; } page_view->previous_allocation = current_allocation; /* re-pan each page of the TOPLEVEL */ for ( iter = geda_list_get_glist (p_current->toplevel->pages); iter != NULL; iter = g_list_next (iter) ) { gschem_page_view_set_page (page_view, (PAGE *)iter->data); if (page_view->configured) { gschem_page_view_pan_mouse (page_view, 0, 0); } else { gschem_page_view_zoom_extents (page_view, NULL); } } page_view->configured = TRUE; gschem_page_view_set_page (page_view, p_current); return FALSE; }
/*! \brief Search for a page following a given page in hierarchy. * \par Function Description * This function searches the next sibling of page \a page in the * hierarchy. It checks all the pages following \a page in the list * \a page_list. * * It returns a pointer on the page if found, NULL otherwise. * * \note * The page \a current_page must be in the list \a page_list. * * \param [in] page_list The list of pages in which to search. * \param [in] current_page The reference page for the search. * \returns A pointer on the page found or NULL if not found. */ PAGE * s_hierarchy_find_next_page (GedaPageList *page_list, PAGE *current_page) { const GList *iter; iter = g_list_find (geda_list_get_glist (page_list), current_page); for (iter = g_list_next (iter); iter != NULL; iter = g_list_next (iter)) { PAGE *page = (PAGE *)iter->data; if (page->page_control == current_page->page_control) { return page; } } return NULL; }
/*! \brief Deletes the list of pages of <B>toplevel</B>. * \par Function Description * Deletes the list of pages of <B>toplevel</B>. * This function should only be called when you are finishing up. * * \param toplevel The TOPLEVEL object. */ void s_page_delete_list(TOPLEVEL *toplevel) { GList *list_copy, *iter; PAGE *page; /* s_page_delete removes items from the page list, so make a copy */ list_copy = g_list_copy (geda_list_get_glist (toplevel->pages)); for (iter = list_copy; iter != NULL; iter = g_list_next (iter)) { page = (PAGE *)iter->data; s_page_delete (toplevel, page); } g_list_free (list_copy); /* reset toplevel fields */ toplevel->page_current = NULL; }
/*! \brief Saves all the pages of a TOPLEVEL object. * \par Function Description * Saves all the pages in the <B>toplevel</B> parameter. * * \param [in] toplevel The TOPLEVEL to save pages from. * \return The number of failed tries to save a page. */ gint s_page_save_all (TOPLEVEL *toplevel) { const GList *iter; PAGE *p_save, *p_current; gint status = 0; /* save current page */ p_save = toplevel->page_current; for ( iter = geda_list_get_glist( toplevel->pages ); iter != NULL; iter = g_list_next( iter ) ) { p_current = (PAGE *)iter->data; /* make p_current the current page of toplevel */ s_page_goto (toplevel, p_current); if (f_save (toplevel, p_current->page_filename)) { s_log_message (_("Saved [%s]\n"), toplevel->page_current->page_filename); /* reset the CHANGED flag of p_current */ p_current->CHANGED = 0; } else { s_log_message (_("Could NOT save [%s]\n"), toplevel->page_current->page_filename); /* increase the error counter */ status++; } } /* restore current page */ if (p_save != NULL) { s_page_goto (toplevel, p_save); } return status; }
/*! \todo Finish function documentation!!! * \brief * \par Function Description * */ void o_move_prep_rubberband(GschemToplevel *w_current) { GList *s_current; OBJECT *object; OBJECT *o_current; GList *iter; 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); for (s_current = geda_list_get_glist (page->selection_list); s_current != NULL; s_current = g_list_next (s_current)) { object = s_current->data; if (object == NULL) continue; switch (object->type) { case (OBJ_NET): case (OBJ_PIN): case (OBJ_BUS): o_move_check_endpoint (w_current, object); break; case (OBJ_COMPLEX): case (OBJ_PLACEHOLDER): for (iter = object->complex->prim_objs; iter != NULL; iter = g_list_next (iter)) { o_current = iter->data; if (o_current->type == OBJ_PIN) { o_move_check_endpoint (w_current, o_current); } } break; } } }
/* still highly temp and doesn't work right */ SCM g_get_toplevel_attribute(SCM scm_wanted_attrib) { const GList *p_iter; PAGE *p_current; char *wanted_attrib; char *attrib_value = NULL; SCM scm_return_value; TOPLEVEL *toplevel = edascm_c_current_toplevel (); SCM_ASSERT(scm_is_string (scm_wanted_attrib), scm_wanted_attrib, SCM_ARG1, "gnetlist:get-toplevel-attribute"); wanted_attrib = scm_to_utf8_string (scm_wanted_attrib); for (p_iter = geda_list_get_glist (toplevel->pages); p_iter != NULL; p_iter = g_list_next (p_iter)) { p_current = p_iter->data; /* only look for first occurrance of the attribute on each page */ attrib_value = o_attrib_search_floating_attribs_by_name (s_page_objects (p_current), wanted_attrib, 0); /* Stop when we find the first one */ if (attrib_value != NULL) break; } free (wanted_attrib); if (attrib_value != NULL) { scm_return_value = scm_from_utf8_string (attrib_value); g_free (attrib_value); } else { scm_return_value = scm_from_utf8_string ("not found"); } return (scm_return_value); }