/*! \brief Attach list of existing attributes to an object. * \par Function Description * Attach list of existing attributes to an object. * * \param [in] toplevel The TOPLEVEL object. * \param [in] attr_list The list of attributes to be added. * \param [out] object The object where you want to add item as an attribute. * \param [in] set_color Whether or not we should set the new attribute's color. */ void o_attrib_attach_list (TOPLEVEL *toplevel, GList *attr_list, OBJECT *object, int set_color) { GList *iter; for (iter = attr_list; iter != NULL; iter = g_list_next (iter)) o_attrib_attach (toplevel, iter->data, object, set_color); }
/*! \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; }
/*! \brief Attach attribute to object. * * Attach the name=value pair to the OBJECT "object". This function * was stolen from gschem/src/o_attrib.c:o_attrib_add_attrib and * hacked for gattrib. * \param toplevel TOPLEVEL to operate on * \param text_string * \param visibility * \param show_name_value * \param object * \returns pointer to the object * \todo Does it need to return OBJECT? */ OBJECT * s_object_attrib_add_attrib_in_object (TOPLEVEL *toplevel, char *text_string, int visibility, int show_name_value, OBJECT * object) { int world_x = -1, world_y = -1; int color; int left, right, top, bottom; OBJECT *o_current; OBJECT *new_obj; o_current = object; /* creating a toplevel or unattached attribute */ if (o_current) { /* get coordinates of where to place the text object */ switch (o_current->type) { case (OBJ_COMPLEX): world_x = o_current->complex->x; world_y = o_current->complex->y; color = ATTRIBUTE_COLOR; break; case (OBJ_NET): world_x = o_current->complex->x; world_y = o_current->complex->y; color = ATTRIBUTE_COLOR; break; default: fprintf(stderr, _("In s_object_attrib_add_attrib_in_object, trying to add attrib to non-complex or non-net!\n")); exit(-1); } } else { /* This must be a floating attrib, but what is that !?!?!?!?! */ world_get_object_glist_bounds (toplevel, s_page_objects (toplevel->page_current), &left, &top, &right, &bottom); /* this really is the lower left hand corner */ world_x = left; world_y = top; /* printf("%d %d\n", world_x, world_y); */ color = DETACHED_ATTRIBUTE_COLOR; } /* first create text item */ #if DEBUG printf("=== In s_object_attrib_add_attrib_in_object, about to attach new text attrib with properties:\n"); printf(" color = %d\n", color); printf(" text_string = %s \n", text_string); printf(" text_size = %d \n", toplevel->text_size); printf(" visibility = %d \n", visibility); printf(" show_name_value = %d \n", show_name_value); #endif new_obj = o_text_new (toplevel, color, world_x, world_y, LOWER_LEFT, 0, /* zero is angle */ text_string, DEFAULT_TEXT_SIZE, visibility, show_name_value); s_page_append (toplevel, toplevel->page_current, new_obj); /* now toplevel->page_current->object_tail contains new text item */ /* now attach the attribute to the object (if o_current is not NULL) */ /* remember that o_current contains the object to get the attribute */ if (o_current) { o_attrib_attach (toplevel, new_obj, o_current, FALSE); } o_selection_add (toplevel, toplevel->page_current->selection_list, new_obj); toplevel->page_current->CHANGED = 1; return new_obj; }
/*! \brief Read attributes from a buffer. * \par Function Description * Read attributes from a TextBuffer. * * \param [in] toplevel The TOPLEVEL object. * \param [out] list Storage for attributes. * \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. */ GList *o_read_attribs (TOPLEVEL *toplevel, GList *list, OBJECT *object_to_get_attribs, TextBuffer *tb, unsigned int release_ver, unsigned int fileformat_ver) { GList *object_list; OBJECT *new_obj; char *line = NULL; char objtype; int ATTACH=FALSE; object_list = g_list_reverse (list); while (1) { line = s_textbuffer_next_line (tb); if (line == NULL) break; sscanf(line, "%c", &objtype); switch (objtype) { case(OBJ_LINE): new_obj = o_line_read (toplevel, line, release_ver, fileformat_ver); object_list = g_list_prepend (object_list, new_obj); break; case(OBJ_NET): new_obj = o_net_read (toplevel, line, release_ver, fileformat_ver); object_list = g_list_prepend (object_list, new_obj); break; case(OBJ_BUS): new_obj = o_bus_read (toplevel, line, release_ver, fileformat_ver); object_list = g_list_prepend (object_list, new_obj); break; case(OBJ_BOX): new_obj = o_box_read (toplevel, line, release_ver, fileformat_ver); object_list = g_list_prepend (object_list, new_obj); break; case(OBJ_CIRCLE): new_obj = o_circle_read (toplevel, line, release_ver, fileformat_ver); object_list = g_list_prepend (object_list, new_obj); break; case(OBJ_COMPLEX): case(OBJ_PLACEHOLDER): new_obj = o_complex_read (toplevel, line, release_ver, fileformat_ver); object_list = g_list_prepend (object_list, new_obj); break; case(OBJ_PATH): line = g_strdup (line); new_obj = o_path_read (toplevel, line, tb, release_ver, fileformat_ver); g_free (line); object_list = g_list_prepend (object_list, new_obj); break; case(OBJ_PIN): new_obj = o_pin_read (toplevel, line, release_ver, fileformat_ver); object_list = g_list_prepend (object_list, new_obj); break; case(OBJ_ARC): new_obj = o_arc_read (toplevel, line, release_ver, fileformat_ver); object_list = g_list_prepend (object_list, new_obj); break; case(OBJ_TEXT): line = g_strdup (line); new_obj = o_text_read (toplevel, line, tb, release_ver, fileformat_ver); g_free (line); object_list = g_list_prepend (object_list, new_obj); ATTACH=TRUE; break; case(ENDATTACH_ATTR): object_list = g_list_reverse (object_list); return(object_list); break; } if (ATTACH) { o_attrib_attach (toplevel, new_obj, object_to_get_attribs, FALSE); ATTACH=FALSE; } else { fprintf(stderr, "Tried to attach a non-text item as an attribute\n"); } } object_list = g_list_reverse (object_list); return(object_list); }
/*! \todo Finish function documentation!!! * \brief * \par Function Description * */ void o_slot_end(GSCHEM_TOPLEVEL *w_current, const char *string, int len) { TOPLEVEL *toplevel = w_current->toplevel; OBJECT *new_obj; OBJECT *object; OBJECT *temp; char *slot_value; char *numslots_value; OBJECT *slot_text_object; char *value = NULL; int numslots; int new_slot_number; int status; status = o_attrib_get_name_value(string, NULL, &value); if (!status) { s_log_message(_("Slot attribute malformed\n")); return; } object = o_select_return_first_object(w_current); /* get the parent object if the selection is only a text object */ if (object != NULL && object->type == OBJ_TEXT) { if (object->attached_to != NULL) { object = object->attached_to; } } /* now find the slot attribute on the outside first */ if (object != NULL) { numslots_value = o_attrib_search_numslots(object, NULL); if (!numslots_value) { s_log_message(_("numslots attribute missing\n")); s_log_message( _("Slotting not allowed for this component\n")); g_free(value); return; } numslots = atoi(numslots_value); g_free(numslots_value); new_slot_number = atoi(value); #if DEBUG printf("numslots = %d\n", numslots); #endif if (new_slot_number > numslots || new_slot_number <=0 ) { s_log_message(_("New slot number out of range\n")); g_free(value); return; } /* first see if slot attribute already exists outside * complex */ slot_value = o_attrib_search_slot(object, &slot_text_object); if (slot_value) { o_text_set_string (toplevel, slot_text_object, string); temp = slot_text_object; if (temp->visibility == VISIBLE || (temp->visibility == INVISIBLE && toplevel->show_hidden_text)) { o_invalidate (w_current,temp); } o_text_recreate(toplevel, temp); /* this doesn't deal with the selection list * item */ if (temp->visibility == VISIBLE || (temp->visibility == INVISIBLE && toplevel->show_hidden_text)) { o_invalidate (w_current,temp); } g_free(slot_value); } else { /* here you need to do the add the slot attribute since it doesn't exist */ new_obj = o_text_new (toplevel, OBJ_TEXT, ATTRIBUTE_COLOR, object->complex->x, object->complex->y, LOWER_LEFT, 0, /* zero is angle */ string, 10, INVISIBLE, SHOW_NAME_VALUE); s_page_append (toplevel->page_current, new_obj); /* manually attach attribute */ o_attrib_attach (toplevel, new_obj, object, FALSE); slot_text_object = new_obj; } o_invalidate (w_current, object); o_attrib_slot_update(toplevel, object); o_invalidate (w_current,object); toplevel->page_current->CHANGED = 1; g_free(value); } else { fprintf(stderr, _("uggg! you tried to slot edit something that doesn't exist!\n")); g_free(value); exit(-1); } }
/* text item */ OBJECT *o_attrib_add_attrib(GschemToplevel *w_current, const char *text_string, int visibility, int show_name_value, OBJECT *object) { TOPLEVEL *toplevel = gschem_toplevel_get_toplevel (w_current); OBJECT *new_obj; int world_x = - 1, world_y = -1; int align = LOWER_LEFT; int angle = 0; int color; int left, right, top, bottom; OBJECT *o_current; color = DETACHED_ATTRIBUTE_COLOR; o_current = object; /* creating a toplevel or unattached attribute */ if (o_current) { /* get coordinates of where to place the text object */ switch(o_current->type) { case(OBJ_COMPLEX): case(OBJ_PLACEHOLDER): world_x = o_current->complex->x; world_y = o_current->complex->y; align = LOWER_LEFT; angle = 0; color = ATTRIBUTE_COLOR; break; case(OBJ_ARC): world_x = o_current->arc->x; world_y = o_current->arc->y; align = LOWER_LEFT; angle = 0; color = ATTRIBUTE_COLOR; break; case(OBJ_CIRCLE): world_x = o_current->circle->center_x; world_y = o_current->circle->center_y; align = LOWER_LEFT; angle = 0; color = ATTRIBUTE_COLOR; break; case(OBJ_BOX): world_x = o_current->box->upper_x; world_y = o_current->box->upper_y; align = LOWER_LEFT; angle = 0; color = ATTRIBUTE_COLOR; break; case(OBJ_LINE): case(OBJ_NET): case(OBJ_PIN): case(OBJ_BUS): { int dx = o_current->line->x[1] - o_current->line->x[0]; int dy = o_current->line->y[1] - o_current->line->y[0]; if (dy == 0) { if (dx > 0) { world_x = o_current->line->x[0] + SPACING_FROM_END; world_y = o_current->line->y[0] + SPACING_PERPENDICULAR; align = LOWER_LEFT; angle = 0; } else { world_x = o_current->line->x[0] - SPACING_FROM_END; world_y = o_current->line->y[0] + SPACING_PERPENDICULAR; align = LOWER_RIGHT; angle = 0; } } else if (dx == 0) { if (dy > 0) { world_x = o_current->line->x[0] - SPACING_PERPENDICULAR; world_y = o_current->line->y[0] + SPACING_FROM_END; align = LOWER_LEFT; angle = 90; } else { world_x = o_current->line->x[0] - SPACING_PERPENDICULAR; world_y = o_current->line->y[0] - SPACING_FROM_END; align = LOWER_RIGHT; angle = 90; } } else { world_x = o_current->line->x[0]; world_y = o_current->line->y[0]; align = LOWER_LEFT; angle = 0; } color = ATTRIBUTE_COLOR; } break; case(OBJ_TEXT): world_x = o_current->text->x; world_y = o_current->text->y; color = DETACHED_ATTRIBUTE_COLOR; align = LOWER_LEFT; angle = 0; o_current = NULL; break; } } else { world_get_object_glist_bounds (toplevel, s_page_objects (toplevel->page_current), &left, &top, &right, &bottom); /* this really is the lower left hand corner */ world_x = left; world_y = top; /* printf("%d %d\n", world_x, world_y); */ align = LOWER_LEFT; angle = 0; color = DETACHED_ATTRIBUTE_COLOR; } /* first create text item */ new_obj = o_text_new(toplevel, color, world_x, world_y, align, angle, text_string, w_current->text_size, /* current text size */ visibility, show_name_value); s_page_append (toplevel, toplevel->page_current, new_obj); /* now attach the attribute to the object (if o_current is not NULL) */ /* remember that o_current contains the object to get the attribute */ if (o_current) { o_attrib_attach (toplevel, new_obj, o_current, FALSE); } o_selection_add (toplevel, toplevel->page_current->selection_list, new_obj); /* handle slot= attribute, it's a special case */ if (o_current != NULL && g_ascii_strncasecmp (text_string, "slot=", 5) == 0) { o_slot_end (w_current, o_current, text_string); } /* Call add-objects-hook. */ g_run_hook_object (w_current, "%add-objects-hook", new_obj); g_run_hook_object (w_current, "%select-objects-hook", new_obj); gschem_toplevel_page_content_changed (w_current, toplevel->page_current); return new_obj; }
/*! \todo Finish function documentation!!! * \brief * \par Function Description * */ void o_slot_end(GSCHEM_TOPLEVEL *w_current, OBJECT *object, const char *string) { TOPLEVEL *toplevel = w_current->toplevel; OBJECT *new_obj; char *slot_value; char *numslots_value; OBJECT *o_slot; char *value = NULL; int numslots; int new_slot_number; int status; g_return_if_fail (object != NULL); status = o_attrib_string_get_name_value (string, NULL, &value); if (!status) { s_log_message (_("Slot attribute malformed\n")); return; } numslots_value = o_attrib_search_object_attribs_by_name (object, "numslots", 0); if (!numslots_value) { s_log_message (_("numslots attribute missing\n")); s_log_message (_("Slotting not allowed for this component\n")); g_free (value); return; } numslots = atoi (numslots_value); g_free (numslots_value); new_slot_number = atoi (value); #if DEBUG printf ("numslots = %d\n", numslots); #endif if (new_slot_number > numslots || new_slot_number <=0 ) { s_log_message (_("New slot number out of range\n")); g_free (value); return; } /* first see if slot attribute already exists outside * complex */ slot_value = s_slot_search_slot (object, &o_slot); g_free (slot_value); if (o_slot != NULL && !o_attrib_is_inherited (o_slot)) { o_text_set_string (toplevel, o_slot, string); } else { /* here you need to do the add the slot attribute since it doesn't exist */ new_obj = o_text_new (toplevel, OBJ_TEXT, ATTRIBUTE_COLOR, object->complex->x, object->complex->y, LOWER_LEFT, 0, /* zero is angle */ string, 10, INVISIBLE, SHOW_NAME_VALUE); s_page_append (toplevel, toplevel->page_current, new_obj); /* manually attach attribute */ o_attrib_attach (toplevel, new_obj, object, FALSE); } s_slot_update_object (toplevel, object); toplevel->page_current->CHANGED = 1; g_free (value); }