/*! \todo Finish function documentation!!! * \brief * \par Function Description * */ void o_text_prepare_place(GschemToplevel *w_current, char *text, 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); g_return_if_fail (toplevel != NULL); g_return_if_fail (page != NULL); /* Insert the new object into the buffer at world coordinates (0,0). * It will be translated to the mouse coordinates during placement. */ w_current->first_wx = 0; w_current->first_wy = 0; w_current->last_drawb_mode = LAST_DRAWB_MODE_NONE; /* remove the old place list if it exists */ s_delete_object_glist(toplevel, page->place_list); page->place_list = NULL; /* here you need to add OBJ_TEXT when it's done */ page->place_list = g_list_append(page->place_list, o_text_new (toplevel, OBJ_TEXT, color, 0, 0, align, rotate, /* zero is angle */ text, size, /* has to be visible so you can place it */ /* visibility is set when you create the object */ VISIBLE, SHOW_NAME_VALUE)); w_current->inside_action = 1; i_set_state (w_current, ENDTEXT); }
/*! \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); }
static void clip_clear (GtkClipboard *cb, gpointer user_data_or_owner) { GSCHEM_TOPLEVEL *w_current = user_data_or_owner; TOPLEVEL *toplevel = w_current->toplevel; /* Free the objects in the clipboard buffer */ s_delete_object_glist (toplevel, w_current->clipboard_buffer); w_current->clipboard_buffer = NULL; }
/*! \brief Remove and free all OBJECTs from the PAGE * * \par Function Description * Removes and frees all OBJECTs from the PAGE. * * \param [in] toplevel The TOPLEVEL object. * \param [in] page The PAGE being cleared. */ void s_page_delete_objects (TOPLEVEL *toplevel, PAGE *page) { GList *objects = page->_object_list; GList *iter; for (iter = objects; iter != NULL; iter = g_list_next (iter)) { pre_object_removed (toplevel, page, iter->data); } page->_object_list = NULL; s_delete_object_glist (toplevel, objects); }
/*! \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); }
/*! \brief Read attributes from a buffer. * \par Function Description * Read attributes from a TextBuffer. * * \param [in] toplevel The TOPLEVEL object. * \param [in] object_to_get_attribs Object which gets these attribs. * \param [in] tb The text buffer to read from. * \param [in] release_ver libgeda release version number. * \param [in] fileformat_ver file format version number. * \return GList of attributes read, or NULL on error. */ GList *o_read_attribs (TOPLEVEL *toplevel, OBJECT *object_to_get_attribs, TextBuffer *tb, unsigned int release_ver, unsigned int fileformat_ver, GError ** err) { GList *object_list = NULL; OBJECT *new_obj; const char *line = NULL; char objtype; int ATTACH=FALSE; while (1) { line = s_textbuffer_next_line (tb); if (line == NULL) break; sscanf(line, "%c", &objtype); switch (objtype) { case(OBJ_LINE): if ((new_obj = o_line_read (toplevel, line, release_ver, fileformat_ver, err)) == NULL) goto error; object_list = g_list_prepend (object_list, new_obj); break; case(OBJ_NET): if ((new_obj = o_net_read (toplevel, line, release_ver, fileformat_ver, err)) == NULL) goto error; object_list = g_list_prepend (object_list, new_obj); break; case(OBJ_BUS): if ((new_obj = o_bus_read (toplevel, line, release_ver, fileformat_ver, err)) == NULL) goto error; object_list = g_list_prepend (object_list, new_obj); break; case(OBJ_BOX): if ((new_obj = o_box_read (toplevel, line, release_ver, fileformat_ver, err)) == NULL) goto error; object_list = g_list_prepend (object_list, new_obj); break; case(OBJ_CIRCLE): if ((new_obj = o_circle_read (toplevel, line, release_ver, fileformat_ver, err)) == NULL) goto error; object_list = g_list_prepend (object_list, new_obj); break; case(OBJ_COMPLEX): case(OBJ_PLACEHOLDER): if ((new_obj = o_complex_read (toplevel, line, release_ver, fileformat_ver, err)) == NULL) goto error; object_list = g_list_prepend (object_list, new_obj); break; case(OBJ_PATH): new_obj = o_path_read (toplevel, line, tb, release_ver, fileformat_ver, err); if (new_obj == NULL) goto error; object_list = g_list_prepend (object_list, new_obj); break; case(OBJ_PIN): if ((new_obj = o_pin_read (toplevel, line, release_ver, fileformat_ver, err)) == NULL) goto error; object_list = g_list_prepend (object_list, new_obj); break; case(OBJ_ARC): if ((new_obj = o_arc_read (toplevel, line, release_ver, fileformat_ver, err)) == NULL) goto error; object_list = g_list_prepend (object_list, new_obj); break; case(OBJ_TEXT): new_obj = o_text_read (toplevel, line, tb, release_ver, fileformat_ver, err); if (new_obj == NULL) goto error; object_list = g_list_prepend (object_list, new_obj); ATTACH=TRUE; break; case(ENDATTACH_ATTR): return object_list; break; } if (ATTACH) { o_attrib_attach (toplevel, new_obj, object_to_get_attribs, FALSE); ATTACH=FALSE; } else { g_set_error(err, EDA_ERROR, EDA_ERROR_PARSE, _("Tried to attach a non-text item as an attribute")); goto error; } } /* The attribute list wasn't terminated, so it's a parse error! */ g_set_error (err, EDA_ERROR, EDA_ERROR_PARSE, _("Unexpected end-of-file in attribute list")); error: s_delete_object_glist(toplevel, object_list); return NULL; }
/*! \todo Finish function documentation!!! * \brief * \par Function Description * * * <B>flag</B> can be one of the following values: * <DL> * <DT>*</DT><DD>UNDO_ALL * <DT>*</DT><DD>UNDO_VIEWPORT_ONLY * </DL> */ void o_undo_savestate(GSCHEM_TOPLEVEL *w_current, int flag) { TOPLEVEL *toplevel = w_current->toplevel; char *filename = NULL; GList *object_list = NULL; int levels; UNDO *u_current; UNDO *u_current_next; /* save autosave backups if necessary */ o_autosave_backups(w_current); if (w_current->undo_control == FALSE) { return; } if (flag == UNDO_ALL) { /* Increment the number of operations since last backup if auto-save is enabled */ if (toplevel->auto_save_interval != 0) { toplevel->page_current->ops_since_last_backup++; } /* HACK */ /* Before we save the undo state, consolidate nets as necessary */ /* This is where the net consolidation call would have been * triggered before it was removed from o_save_buffer(). */ if (toplevel->net_consolidate == TRUE) o_net_consolidate (toplevel, toplevel->page_current); } if (w_current->undo_type == UNDO_DISK && flag == UNDO_ALL) { filename = g_strdup_printf("%s%cgschem.save%d_%d.sch", tmp_path, G_DIR_SEPARATOR, prog_pid, undo_file_index++); /* Changed from f_save to o_save when adding backup copy creation. */ /* f_save manages the creaton of backup copies. This way, f_save is called only when saving a file, and not when saving an undo backup copy */ o_save (toplevel, s_page_objects (toplevel->page_current), filename, NULL); } else if (w_current->undo_type == UNDO_MEMORY && flag == UNDO_ALL) { object_list = o_glist_copy_all (toplevel, s_page_objects (toplevel->page_current), object_list); } /* Clear Anything above current */ if (toplevel->page_current->undo_current) { s_undo_remove_rest(toplevel, toplevel->page_current->undo_current->next); toplevel->page_current->undo_current->next = NULL; } else { /* undo current is NULL */ s_undo_remove_rest(toplevel, toplevel->page_current->undo_bottom); toplevel->page_current->undo_bottom = NULL; } toplevel->page_current->undo_tos = toplevel->page_current->undo_current; toplevel->page_current->undo_tos = s_undo_add(toplevel->page_current->undo_tos, flag, filename, object_list, toplevel->page_current->left, toplevel->page_current->top, toplevel->page_current->right, toplevel->page_current->bottom, toplevel->page_current->page_control, toplevel->page_current->up); toplevel->page_current->undo_current = toplevel->page_current->undo_tos; if (toplevel->page_current->undo_bottom == NULL) { toplevel->page_current->undo_bottom = toplevel->page_current->undo_tos; } #if DEBUG printf("\n\n---Undo----\n"); s_undo_print_all(toplevel->page_current->undo_bottom); printf("BOTTOM: %s\n", toplevel->page_current->undo_bottom->filename); printf("TOS: %s\n", toplevel->page_current->undo_tos->filename); printf("CURRENT: %s\n", toplevel->page_current->undo_current->filename); printf("----\n"); #endif g_free(filename); /* Now go through and see if we need to free/remove some undo levels */ /* so we stay within the limits */ /* only check history every 10 undo savestates */ if (undo_file_index % 10) { return; } levels = s_undo_levels(toplevel->page_current->undo_bottom); #if DEBUG printf("levels: %d\n", levels); #endif if (levels >= w_current->undo_levels + UNDO_PADDING) { levels = levels - w_current->undo_levels; #if DEBUG printf("Trimming: %d levels\n", levels); #endif u_current = toplevel->page_current->undo_bottom; while(u_current && levels > 0) { u_current_next = u_current->next; if (u_current->filename) { #if DEBUG printf("Freeing: %s\n", u_current->filename); #endif unlink(u_current->filename); g_free(u_current->filename); } if (u_current->object_list) { s_delete_object_glist (toplevel, u_current->object_list); u_current->object_list = NULL; } u_current->next = NULL; u_current->prev = NULL; g_free(u_current); u_current = u_current_next; levels--; } /* Because we use a pad you are always garanteed to never */ /* exhaust the list */ u_current->prev = NULL; toplevel->page_current->undo_bottom = u_current; #if DEBUG printf("New current is: %s\n", u_current->filename); #endif } #if DEBUG printf("\n\n---Undo----\n"); s_undo_print_all(toplevel->page_current->undo_bottom); printf("BOTTOM: %s\n", toplevel->page_current->undo_bottom->filename); printf("TOS: %s\n", toplevel->page_current->undo_tos->filename); printf("CURRENT: %s\n", toplevel->page_current->undo_current->filename); printf("----\n"); #endif }
/*! \brief Remove and free all OBJECTs from the PAGE * * \par Function Description * Removes and frees all OBJECTs from the PAGE. * * \param [in] toplevel The TOPLEVEL object. * \param [in] page The PAGE being cleared. */ void s_page_delete_objects (TOPLEVEL *toplevel, PAGE *page) { s_delete_object_glist (toplevel, page->_object_list); page->_object_list = NULL; }
/*! \brief delete a page and it's contents * \par Function Description * Deletes a single page <B>page</B> from <B>toplevel</B>'s list of pages. * * See #s_page_delete_list() to delete all pages of a <B>toplevel</B> * * If the current page of toplevel is given as parameter <B>page</B>, * the function sets the field <B>page_current</B> of the TOPLEVEL * struct to NULL. */ void s_page_delete (TOPLEVEL *toplevel, PAGE *page) { PAGE *tmp; gchar *backup_filename; gchar *real_filename; /* We need to temporarily make the page being deleted current because * various functions called below (some indirectly) assume they are * deleting objects from the current page. * * These functions are known to include: * s_delete_object () */ /* save page_current and switch to page */ if (page == toplevel->page_current) { tmp = NULL; } else { tmp = toplevel->page_current; s_page_goto (toplevel, page); } /* Get the real filename and file permissions */ real_filename = follow_symlinks (page->page_filename, NULL); if (real_filename == NULL) { s_log_message (_("s_page_delete: Can't get the real filename of %s."), page->page_filename); } else { backup_filename = f_get_autosave_filename (real_filename); /* Delete the backup file */ if ( (g_file_test (backup_filename, G_FILE_TEST_EXISTS)) && (!g_file_test(backup_filename, G_FILE_TEST_IS_DIR)) ) { if (unlink(backup_filename) != 0) { s_log_message(_("s_page_delete: Unable to delete backup file %s."), backup_filename); } } g_free (backup_filename); } g_free(real_filename); /* Free the selection object */ g_object_unref( page->selection_list ); /* then delete objects of page */ s_page_delete_objects (toplevel, page); /* Free the objects in the place list. */ s_delete_object_glist (toplevel, page->place_list); page->place_list = NULL; #if DEBUG printf("Freeing page: %s\n", page->page_filename); s_tile_print(toplevel); #endif s_tile_free_all (page); s_stretch_destroy_all (page->stretch_list); /* free current page undo structs */ s_undo_free_all (toplevel, page); /* ouch, deal with parents going away and the children still around */ page->up = -2; g_free (page->page_filename); geda_list_remove( toplevel->pages, page ); #if DEBUG s_tile_print (toplevel); #endif g_free (page); /* restore page_current */ if (tmp != NULL) { s_page_goto (toplevel, tmp); } else { /* page was page_current */ toplevel->page_current = NULL; /* page_current must be updated by calling function */ } }
/*! \brief delete a page and it's contents * \par Function Description * Deletes a single page <B>page</B> from <B>toplevel</B>'s list of pages. * * See #s_page_delete_list() to delete all pages of a <B>toplevel</B> * * If the current page of toplevel is given as parameter <B>page</B>, * the function sets the field <B>page_current</B> of the TOPLEVEL * struct to NULL. */ void s_page_delete (TOPLEVEL *toplevel, PAGE *page) { PAGE *tmp; gchar *backup_filename; gchar *real_filename; /* We need to temporarily make the page being deleted current because * various functions called below (some indirectly) assume they are * deleting objects from the current page. * * These functions are known to include: * s_delete_object () */ /* save page_current and switch to page */ if (page == toplevel->page_current) { tmp = NULL; } else { tmp = toplevel->page_current; s_page_goto (toplevel, page); } /* Get the real filename and file permissions */ real_filename = follow_symlinks (page->page_filename, NULL); if (real_filename == NULL) { s_log_message (_("s_page_delete: Can't get the real filename of %s."), page->page_filename); } else { backup_filename = f_get_autosave_filename (real_filename); /* Delete the backup file */ if ( (g_file_test (backup_filename, G_FILE_TEST_EXISTS)) && (!g_file_test(backup_filename, G_FILE_TEST_IS_DIR)) ) { if (unlink(backup_filename) != 0) { s_log_message(_("s_page_delete: Unable to delete backup file %s."), backup_filename); } } g_free (backup_filename); } g_free(real_filename); /* Free the selection object */ g_object_unref( page->selection_list ); /* then delete objects of page */ s_page_delete_objects (toplevel, page); /* Free the objects in the place list. */ s_delete_object_glist (toplevel, page->place_list); page->place_list = NULL; /* This removes all objects from the list of connectible objects * of the given \a page. */ if (g_list_length (page->connectible_list) != 0) { fprintf (stderr, "OOPS! page->connectible_list had something in it when it was freed!\n"); fprintf (stderr, "Length: %d\n", g_list_length (page->connectible_list)); } g_list_free (page->connectible_list); page->connectible_list = NULL; /* free current page undo structs */ s_undo_free_all (toplevel, page); /* ouch, deal with parents going away and the children still around */ page->up = -2; g_free (page->page_filename); geda_list_remove( toplevel->pages, page ); s_weakref_notify (page, page->weak_refs); g_free (page); /* restore page_current */ if (tmp != NULL) { s_page_goto (toplevel, tmp); } else { /* page was page_current */ s_toplevel_set_page_current (toplevel, NULL); /* page_current must be updated by calling function */ } }
/*! \todo Finish function documentation!!! * \brief * \par Function Description * */ void s_delete_object(TOPLEVEL *toplevel, OBJECT *o_current) { if (o_current != NULL) { /* If currently attached to a page, remove it from the page */ if (o_current->page != NULL) { s_page_remove (toplevel, o_current->page, o_current); } s_conn_remove_object (toplevel, o_current); if (o_current->attached_to != NULL) { /* do the actual remove */ o_attrib_remove(toplevel, &o_current->attached_to->attribs, o_current); } if (o_current->line) { /* printf("sdeleting line\n");*/ g_free(o_current->line); } o_current->line = NULL; if (o_current->path) { g_free(o_current->path); } o_current->path = NULL; /* printf("sdeleting circle\n");*/ g_free(o_current->circle); o_current->circle = NULL; /* printf("sdeleting arc\n");*/ g_free(o_current->arc); o_current->arc = NULL; /* printf("sdeleting box\n");*/ g_free(o_current->box); o_current->box = NULL; if (o_current->picture) { /* printf("sdeleting picture\n");*/ g_free(o_current->picture->file_content); if (o_current->picture->pixbuf) g_object_unref (o_current->picture->pixbuf); g_free(o_current->picture->filename); g_free(o_current->picture); } o_current->picture = NULL; if (o_current->text) { /*printf("sdeleting text->string\n");*/ g_free(o_current->text->string); o_current->text->string = NULL; g_free(o_current->text->disp_string); /* printf("sdeleting text\n");*/ g_free(o_current->text); } o_current->text = NULL; /* printf("sdeleting name\n");*/ g_free(o_current->name); o_current->name = NULL; /* printf("sdeleting complex_basename\n");*/ g_free(o_current->complex_basename); o_current->complex_basename = NULL; if (o_current->complex) { if (o_current->complex->prim_objs) { /* printf("sdeleting complex->primitive_objects\n");*/ s_delete_object_glist (toplevel, o_current->complex->prim_objs); o_current->complex->prim_objs = NULL; } g_free(o_current->complex); o_current->complex = NULL; } o_attrib_detach_all (toplevel, o_current); s_weakref_notify (o_current, o_current->weak_refs); g_free(o_current); /* assuming it is not null */ o_current=NULL; /* misc clean up */ } }