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
28 *------------------------------------------------------------------ */
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
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
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
);
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
)
88 /*------------------------------------------------------------------
89 * This fcn adds a new attrib to o_current, when o_current is a
90 * pin. It does it in the following
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
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
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
);
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
)
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. */
161 "In s_object_replace_attrib_in_object, we have failed to find the attrib %s on the component. Exiting . . .\n",
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
)
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. */
191 printf("In s_object_remove_attrib_in_object, removing attrib with name = %s\n", old_attrib_name
);
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. */
210 "In s_object_remove_attrib_in_object, we have failed to find the attrib %s on the component. Exiting . . .\n",
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
,
226 int world_x
= -1, world_y
= -1;
228 int left
, right
, top
, bottom
;
231 color
= pr_current
->detachedattr_color
;
235 /* creating a toplevel or unattached attribute */
237 /* get coordinates of where to place the text object */
238 switch (o_current
->type
) {
240 world_x
= o_current
->complex->x
;
241 world_y
= o_current
->complex->y
;
242 color
= pr_current
->attribute_color
;
246 world_x
= o_current
->complex->x
;
247 world_y
= o_current
->complex->y
;
248 color
= pr_current
->attribute_color
;
252 fprintf(stderr
, "In s_object_attrib_add_attrib_in_object, trying to add attrib to non-complex or non-net!\n");
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 */
264 /* printf("%d %d\n", world_x, world_y); */
265 color
= pr_current
->detachedattr_color
;
268 /* first create text item */
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
);
278 pr_current
->page_current
->object_tail
= o_text_add(pr_current
,
279 pr_current
->page_current
->object_tail
,
285 0, /* zero is angle */
287 pr_current
->text_size
, /* current text size */
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 */
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;
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
);