Initial import of gattrib 20040806
[geda-gaf/whiteaudio.git] / gattrib / src / s_object.c
blob66a2d7cd62c9beed81f6ac000598ee6d85b2e90f
1 /* gEDA - GPL Electronic Design Automation
2 * gattrib -- gEDA component and net attribute manipulation using spreadsheet.
3 * Copyright (C) 2003 Stuart D. Brorson.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
20 /*------------------------------------------------------------------
21 * This file holds fcns involved in manipulating the OBJECT data
22 * structure. OBJECT is defined in libgeda. An OBJECT is a graphical
23 * primitive normally used in gschem. Example OBJECTs: some text,
24 * a component (complex), a pin, a line, etc.
26 * The fcns herein are fcns which I wrote as wrappers to the
27 * fcns in libgeda.
28 *------------------------------------------------------------------ */
30 #include <config.h>
32 #include <stdio.h>
33 #ifdef HAVE_STRING_H
34 #include <string.h>
35 #endif
36 #include <math.h>
38 /*------------------------------------------------------------------
39 * Gattrib specific includes
40 *------------------------------------------------------------------*/
41 #include <libgeda/libgeda.h> /* geda library fcns */
42 #include "../include/struct.h" /* typdef and struct declarations */
43 #include "../include/prototype.h" /* function prototypes */
44 #include "../include/globals.h"
48 /* =================== Public Functions ====================== */
50 /*------------------------------------------------------------------
51 * This fcn adds a new attrib to o_current, when o_current is a
52 * component. It does it in the following
53 * way:
54 * 1. It creates an object -- "attrib_graphic" -- and fills it in.
55 * 2. It gets the position info from o_current's refdes attrib and
56 * calls o_text_add to add pos info and name=value string
57 * to attrib_graphic.
58 * 3. It calls o_attrib_add to wrap attrib_graphic with (ATTRIB )
59 *------------------------------------------------------------------ */
60 void s_object_add_comp_attrib_to_object(OBJECT *o_current, char *new_attrib_name,
61 char *new_attrib_value)
63 char *name_value_pair;
64 OBJECT *attrib_graphic_object;
66 /* One last sanity check */
67 if (strlen(new_attrib_value) != 0) {
68 name_value_pair = u_basic_strdup_multiple(new_attrib_name, "=", new_attrib_value, NULL);
69 attrib_graphic_object = s_object_attrib_add_attrib_in_object(pr_current, name_value_pair, INVISIBLE,
70 SHOW_NAME_VALUE, o_current);
73 return;
78 /*------------------------------------------------------------------*
79 * This needs to be filled in.
80 *------------------------------------------------------------------*/
81 void s_object_add_net_attrib_to_object(OBJECT *o_current, char *new_attrib_name,
82 char *new_attrib_value)
84 /* TBD */
88 /*------------------------------------------------------------------
89 * This fcn adds a new attrib to o_current, when o_current is a
90 * pin. It does it in the following
91 * way:
92 * 1. It creates an object -- "attrib_graphic" -- and fills it in.
93 * 2. It gets the position info from o_current's refdes attrib and
94 * calls o_text_add to add pos info and name=value string
95 * to attrib_graphic.
96 * 3. It calls o_attrib_add to wrap attrib_graphic with (ATTRIB )
97 * Question: Do I really need separate fcns for comps, nets, and
98 * pins???
99 *------------------------------------------------------------------ */
100 void s_object_add_pin_attrib_to_object(OBJECT *o_current, char *new_attrib_name,
101 char *new_attrib_value)
103 char *name_value_pair;
104 OBJECT *attrib_graphic_object;
106 /* One last sanity check */
107 if (strlen(new_attrib_value) != 0) {
108 name_value_pair = u_basic_strdup_multiple(new_attrib_name, "=", new_attrib_value, NULL);
109 attrib_graphic_object = s_object_attrib_add_attrib_in_object(pr_current, name_value_pair, INVISIBLE,
110 SHOW_NAME_VALUE, o_current);
113 return;
120 /*------------------------------------------------------------------
121 * This fcn finds the instance of attrib_name on o_current, and
122 * replaces it's value wiht new_attrib_value.
123 *------------------------------------------------------------------*/
124 void s_object_replace_attrib_in_object(OBJECT *o_current, char *new_attrib_name,
125 char *new_attrib_value)
127 ATTRIB *a_current;
128 char *old_attrib_text;
129 char *old_attrib_name;
130 char *new_attrib_text;
132 a_current = o_current->attribs;
133 while (a_current != NULL) {
134 if (a_current->object->type == OBJ_TEXT
135 && a_current->object->text != NULL) { /* found an attribute */
137 /* may need to check more thoroughly here. . . . */
138 old_attrib_text = u_basic_strdup(a_current->object->text->string);
139 old_attrib_name = u_basic_breakup_string(old_attrib_text, '=', 0);
141 if (strcmp(old_attrib_name, new_attrib_name) == 0) {
142 /* create attrib=value text string & stuff it back into pr_current */
143 new_attrib_text = u_basic_strdup_multiple(new_attrib_name, "=", new_attrib_value, NULL);
144 free(a_current->object->text->string); /* remove old attrib string */
145 a_current->object->text->string = u_basic_strdup(new_attrib_text); /* insert new attrib string */
146 free(new_attrib_text);
147 free(old_attrib_text);
148 free(old_attrib_name);
149 return; /* we are done -- leave. */
151 free(old_attrib_text);
152 free(old_attrib_name);
153 } /* if (a_current . . . . */
155 a_current = a_current->next;
158 /* if we get here, it's because we have failed to find the attrib on the component.
159 * This is an error condition. */
160 fprintf(stderr,
161 "In s_object_replace_attrib_in_object, we have failed to find the attrib %s on the component. Exiting . . .\n",
162 new_attrib_name);
163 exit(-1);
167 /*------------------------------------------------------------------
168 * This fcn removes attrib from o_current.
169 *------------------------------------------------------------------*/
170 void s_object_remove_attrib_in_object(OBJECT *o_current, char *new_attrib_name)
173 ATTRIB *a_current;
174 OBJECT *attribute_object;
175 char *old_attrib_text;
176 char *old_attrib_name;
178 a_current = o_current->attribs;
179 while (a_current != NULL) {
180 if (a_current->object->type == OBJ_TEXT
181 && a_current->object->text != NULL) { /* found an attribute */
183 /* may need to check more thoroughly here. . . . */
184 old_attrib_text = u_basic_strdup(a_current->object->text->string);
185 old_attrib_name = u_basic_breakup_string(old_attrib_text, '=', 0);
187 if (strcmp(old_attrib_name, new_attrib_name) == 0) {
188 /* We've found the attrib. Delete it and then return. */
190 #ifdef DEBUG
191 printf("In s_object_remove_attrib_in_object, removing attrib with name = %s\n", old_attrib_name);
192 #endif
194 attribute_object = a_current->object;
195 s_object_delete_text_object_in_object(pr_current, attribute_object);
197 free(old_attrib_text);
198 free(old_attrib_name);
199 return; /* we are done -- leave. */
201 free(old_attrib_text);
202 free(old_attrib_name);
204 a_current = a_current->next;
207 /* if we get here, it's because we have failed to find the attrib on the component.
208 * This is an error condition. */
209 fprintf(stderr,
210 "In s_object_remove_attrib_in_object, we have failed to find the attrib %s on the component. Exiting . . .\n",
211 new_attrib_name);
212 exit(-1);
217 /*------------------------------------------------------------------
218 * This fcn attaches the name=value pair to the OBJECT "object" It
219 * was stolen from gschem/src/o_attrib.c:o_attrib_add_attrib and
220 * hacked for gattrib. Does it need to return OBJECT?
221 *------------------------------------------------------------------*/
222 OBJECT *s_object_attrib_add_attrib_in_object(TOPLEVEL * pr_current, char *text_string,
223 int visibility, int show_name_value,
224 OBJECT * object)
226 int world_x = -1, world_y = -1;
227 int color;
228 int left, right, top, bottom;
229 OBJECT *o_current;
231 color = pr_current->detachedattr_color;
233 o_current = object;
235 /* creating a toplevel or unattached attribute */
236 if (o_current) {
237 /* get coordinates of where to place the text object */
238 switch (o_current->type) {
239 case (OBJ_COMPLEX):
240 world_x = o_current->complex->x;
241 world_y = o_current->complex->y;
242 color = pr_current->attribute_color;
243 break;
245 case (OBJ_NET):
246 world_x = o_current->complex->x;
247 world_y = o_current->complex->y;
248 color = pr_current->attribute_color;
249 break;
251 default:
252 fprintf(stderr, "In s_object_attrib_add_attrib_in_object, trying to add attrib to non-complex or non-net!\n");
253 exit(-1);
255 } else { /* This must be a floating attrib, but what is that !?!?!?!?! */
256 world_get_complex_bounds(pr_current,
257 pr_current->page_current->object_head,
258 &left, &top, &right, &bottom);
260 /* this really is the lower left hand corner */
261 world_x = left;
262 world_y = top;
264 /* printf("%d %d\n", world_x, world_y); */
265 color = pr_current->detachedattr_color;
268 /* first create text item */
269 #if DEBUG
270 printf("=== In s_object_attrib_add_attrib_in_object, about to attach new text attrib with properties:\n");
271 printf(" color = %d\n", color);
272 printf(" text_string = %s \n", text_string);
273 printf(" text_size = %d \n", pr_current->text_size);
274 printf(" visibility = %d \n", visibility);
275 printf(" show_name_value = %d \n", show_name_value);
276 #endif
278 pr_current->page_current->object_tail = o_text_add(pr_current,
279 pr_current->page_current->object_tail,
280 OBJ_TEXT,
281 color,
282 world_x,
283 world_y,
284 LOWER_LEFT,
285 0, /* zero is angle */
286 text_string,
287 pr_current->text_size, /* current text size */
288 visibility,
289 show_name_value);
291 /* now pr_current->page_current->object_tail contains new text item */
293 /* now attach the attribute to the object (if o_current is not NULL) */
294 /* remember that o_current contains the object to get the attribute */
295 if (o_current) {
296 o_attrib_attach(pr_current, pr_current->page_current->object_head,
297 pr_current->page_current->object_tail, o_current);
300 o_selection_add(pr_current->page_current->selection2_head,
301 pr_current->page_current->object_tail);
304 pr_current->page_current->CHANGED = 1;
306 return (pr_current->page_current->object_tail);
312 /*------------------------------------------------------------------
313 * This fcn deletes the text object pointed to by text_object. It
314 * was shamelessly stolen from gschem/src/o_delete.c and hacked
315 * for gattrib by SDB.
316 *------------------------------------------------------------------*/
317 void s_object_delete_text_object_in_object(TOPLEVEL * pr_current, OBJECT * text_object)
319 s_delete(pr_current, text_object);
320 pr_current->page_current->CHANGED = 1;
322 #if 0
323 /* What does this do?!?!? Maybe I don't need it!!! */
324 pr_current->page_current->object_tail =
325 (OBJECT *) return_tail(pr_current->page_current->object_head);
326 #endif