/*! \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); }
/*! \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 Search for the parent page of a page in hierarchy. * \par Function Description * This function searches the parent page of page \a page in the * hierarchy. It checks all the pages 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_up_page (GedaPageList *page_list, PAGE *current_page) { if (current_page->up < 0) { s_log_message(_("There are no schematics above the current one!\n")); return NULL; } return s_page_search_by_page_id (page_list, current_page->up); }
/*! * \brief Search for schematic associated source files and load them. * \par Function Description * This function searches the associated source file refered by the * <B>filename</B> and loads it. If the <B>flag</B> is set to * <B>HIERARCHY_NORMAL_LOAD</B> and the page is already in the list of * pages it will return the <B>pid</B> of that page. * If the <B>flag</B> is set to <B>HIERARCHY_FORCE_LOAD</B> then this * function will load the page again with a new page id. The second case * is mainly used by gnetlist where pushed down schematics MUST be unique. * * \param [in] toplevel The TOPLEVEL object. * \param [in] filename Schematic file name. * \param [in] parent The parent page of the schematic. * \param [in] page_control * \param [in] flag sets whether to force load * \param [out] err Location to return a GError on failure. * \return The page loaded, or NULL if failed. * * \note * This function finds the associated source files and * loads all up * It only works for schematic files though * this is basically push * flag can either be HIERARCHY_NORMAL_LOAD or HIERARCHY_FORCE_LOAD * flag is mainly used by gnetlist where pushed down schematics MUST be unique */ PAGE * s_hierarchy_down_schematic_single(TOPLEVEL *toplevel, const gchar *filename, PAGE *parent, int page_control, int flag, GError **err) { gchar *string; PAGE *found = NULL; PAGE *forbear; g_return_val_if_fail ((toplevel != NULL), NULL); g_return_val_if_fail ((filename != NULL), NULL); g_return_val_if_fail ((parent != NULL), NULL); SCM string_s = scm_call_1 (scm_c_public_ref ("geda library", "get-source-library-file"), scm_from_utf8_string (filename)); if (scm_is_false (string_s)) { g_set_error (err, EDA_ERROR, EDA_ERROR_NOLIB, _("Schematic not found in source library.")); return NULL; } string = scm_to_utf8_string (string_s); switch (flag) { case HIERARCHY_NORMAL_LOAD: { gchar *filename = f_normalize_filename (string, NULL); found = s_page_search (toplevel, filename); g_free (filename); if (found) { /* check whether this page is in the parents list */ for (forbear = parent; forbear != NULL && found->pid != forbear->pid && forbear->up >= 0; forbear = s_page_search_by_page_id (toplevel->pages, forbear->up)) ; /* void */ if (forbear != NULL && found->pid == forbear->pid) { g_set_error (err, EDA_ERROR, EDA_ERROR_LOOP, _("Hierarchy contains a circular dependency.")); return NULL; /* error signal */ } s_page_goto (toplevel, found); if (page_control != 0) { found->page_control = page_control; } found->up = parent->pid; g_free (string); return found; } found = s_page_new (toplevel, string); f_open (toplevel, found, s_page_get_filename (found), NULL); } break; case HIERARCHY_FORCE_LOAD: { found = s_page_new (toplevel, string); f_open (toplevel, found, s_page_get_filename (found), NULL); } break; default: g_return_val_if_reached (NULL); } if (page_control == 0) { page_control_counter++; found->page_control = page_control_counter; } else { found->page_control = page_control; } found->up = parent->pid; g_free (string); return found; }
/*! \todo Finish function documentation!!! * \brief Search for schematic associated source files and load them. * \par Function Description * This function searches the associated source file refered by the * <B>filename</B> and loads it. If the <B>flag</B> is set to * <B>HIERARCHY_NORMAL_LOAD</B> and the page is allready in the list of * pages it will return the <B>pid</B> of that page. * If the <B>flag</B> is set to <B>HIERARCHY_FORCE_LOAD</B> then this * function will load the page again with a new page id. The second case * is mainly used by gnetlist where pushed down schematics MUST be unique. * * \param [in] toplevel The TOPLEVEL object. * \param [in] filename Schematic file name. * \param [in] parent The parent page of the schematic. * \param [in] page_control * \param [in] flag * \return The page loaded, or NULL if failed. * * \note * This function goes and finds the associated source files and * loads all up * It only works for schematic files though * this is basically push * flag can either be HIERARCHY_NORMAL_LOAD or HIERARCHY_FORCE_LOAD * flag is mainly used by gnetlist where pushed down schematics MUST be unique */ PAGE * s_hierarchy_down_schematic_single(TOPLEVEL *toplevel, const gchar *filename, PAGE *parent, int page_control, int flag) { gchar *string; PAGE *found = NULL; PAGE *forbear; g_return_val_if_fail ((toplevel != NULL), NULL); g_return_val_if_fail ((filename != NULL), NULL); g_return_val_if_fail ((parent != NULL), NULL); string = s_slib_search_single(filename); if (string == NULL) { return NULL; } switch (flag) { case HIERARCHY_NORMAL_LOAD: { gchar *filename = f_normalize_filename (string, NULL); found = s_page_search (toplevel, filename); g_free (filename); if (found) { /* check whether this page is in the parents list */ for (forbear = parent; forbear != NULL && found->pid != forbear->pid && forbear->up >= 0; forbear = s_page_search_by_page_id (toplevel->pages, forbear->up)) ; /* void */ if (found->pid == forbear->pid) { s_log_message(_("hierarchy loop detected while visiting page:\n" " \"%s\"\n"), found->page_filename); return NULL; /* error signal */ } s_page_goto (toplevel, found); if (page_control != 0) { found->page_control = page_control; } found->up = parent->pid; g_free (string); return found; } found = s_page_new (toplevel, string); f_open (toplevel, found, found->page_filename, NULL); } break; case HIERARCHY_FORCE_LOAD: { found = s_page_new (toplevel, string); f_open (toplevel, found, found->page_filename, NULL); } break; } if (page_control == 0) { page_control_counter++; found->page_control = page_control_counter; } else { found->page_control = page_control; } found->up = parent->pid; g_free (string); return found; }