missing NULL terminator in set_config_x
[geda-gaf.git] / gschem / src / o_attrib.c
blobc86a8b44116efda9e7b892bdeec3bd3a9c165f50
1 /* gEDA - GPL Electronic Design Automation
2 * gschem - gEDA Schematic Capture
3 * Copyright (C) 1998-2010 Ales Hvezda
4 * Copyright (C) 1998-2020 gEDA Contributors (see ChangeLog for details)
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 #include <config.h>
22 #include <stdio.h>
23 #ifdef HAVE_STRING_H
24 #include <string.h>
25 #endif
26 #include <math.h>
28 #include "gschem.h"
32 #define SPACING_FROM_END 100
33 #define SPACING_PERPENDICULAR 50
36 /* No special type for attributes */
37 /* You can only edit text attributes */
39 /* be sure in o_copy o_move o_delete you maintain the attributes */
40 /* delete is a bare, because you will have to unattach the other end */
41 /* and in o_save o_read as well */
42 /* and in o_select when selecting objects, select the attributes */
44 /* there needs to be a modifier (in struct.h, such as a flag) which
45 * signifies that this is an attribute */
47 /*! \todo Finish function documentation!!!
48 * \brief
49 * \par Function Description
50 * Copy all attributes select to the selection list.
52 * \todo get a better name
54 void o_attrib_add_selected(GschemToplevel *w_current, SELECTION *selection,
55 OBJECT *selected)
57 OBJECT *a_current;
58 GList *a_iter;
59 GList *selected_objects = NULL;
61 g_assert( selection != NULL );
63 for (a_iter = selected->attribs; a_iter != NULL;
64 a_iter = g_list_next (a_iter)) {
65 a_current = a_iter->data;
67 /* make sure object isn't selected already */
68 if (!a_current->selected) {
69 o_selection_add (w_current->toplevel, selection, a_current);
70 selected_objects = g_list_prepend (selected_objects, a_current);
74 if (selected_objects != NULL) {
75 /* Run select-objects-hook */
76 g_run_hook_object_list (w_current, "%select-objects-hook",
77 selected_objects);
78 g_list_free (selected_objects);
82 /*! \brief Remove invisible attributes of an object from the selection list.
83 * \par Function Description
85 * Remove all invisible attributes attached to the given object
86 * from the selection list. If hidden text is being shown, this
87 * function returns immediately.
89 * \param [in] w_current The GschemToplevel object.
90 * \param [in,out] selection The SELECTION list to remove from.
91 * \param [in] object The OBJECT whose invisible attributes to remove.
93 void o_attrib_deselect_invisible (GschemToplevel *w_current,
94 SELECTION *selection,
95 OBJECT *selected)
97 OBJECT *a_current;
98 GList *a_iter;
100 g_assert( selection != NULL );
102 if (w_current->toplevel->show_hidden_text) {
103 return;
106 for (a_iter = selected->attribs; a_iter != NULL;
107 a_iter = g_list_next (a_iter)) {
108 a_current = a_iter->data;
110 if (a_current->selected && !o_is_visible(a_current)) {
111 o_selection_remove (w_current->toplevel, selection, a_current);
116 /*! \brief Add invisible attributes of an object to the selection list.
117 * \par Function Description
119 * Add all invisible attributes attached to the given object
120 * to the selection list. If hidden text is being shown, this
121 * function returns immediately.
123 * \param [in] w_current The GschemToplevel object.
124 * \param [in,out] selection The SELECTION list to add to.
125 * \param [in] object The OBJECT whose invisible attributes to add.
127 void o_attrib_select_invisible (GschemToplevel *w_current,
128 SELECTION *selection,
129 OBJECT *selected)
131 OBJECT *a_current;
132 GList *a_iter;
134 g_assert( selection != NULL );
136 if (w_current->toplevel->show_hidden_text) {
137 return;
140 for (a_iter = selected->attribs; a_iter != NULL;
141 a_iter = g_list_next (a_iter)) {
142 a_current = a_iter->data;
144 if (!a_current->selected && !o_is_visible(a_current)) {
145 o_selection_add (w_current->toplevel, selection, a_current);
150 /*! \brief Change visibility status of attribute object.
151 * \par Function Description
152 * This function toggles the visibility status of the attribute \a
153 * object and updates it. The object is erased or redrawn if
154 * necessary.
156 * \param [in] w_current The GschemToplevel object.
157 * \param [in] object The attribute object.
159 void o_attrib_toggle_visibility(GschemToplevel *w_current, OBJECT *object)
161 TOPLEVEL *toplevel = gschem_toplevel_get_toplevel (w_current);
163 g_return_if_fail (object != NULL && object->type == OBJ_TEXT);
165 if (o_is_visible (object)) {
166 /* only erase if we are not showing hidden text */
167 if (!toplevel->show_hidden_text) {
168 o_invalidate (w_current, object);
171 o_set_visibility (toplevel, object, INVISIBLE);
173 if (toplevel->show_hidden_text) {
174 /* draw text so that little I is drawn */
175 o_invalidate (w_current, object);
178 } else {
179 /* if we are in the special show hidden mode, then erase text first */
180 /* to get rid of the little I */
181 if (toplevel->show_hidden_text) {
182 o_invalidate (w_current, object);
185 o_set_visibility (toplevel, object, VISIBLE);
186 o_text_recreate(toplevel, object);
190 /*! \brief Set what part of an attribute is shown.
191 * \par Function Description
192 * This function changes what part (name, value or both) of an
193 * attribute is shown by its attribute object. The attribute object
194 * is erased, updated and finally redrawn.
196 * \param [in] w_current The GschemToplevel object.
197 * \param [in] object The attribute object.
198 * \param [in] show_name_value The new display flag for attribute.
200 void o_attrib_toggle_show_name_value(GschemToplevel *w_current,
201 OBJECT *object, int show_name_value)
203 TOPLEVEL *toplevel = gschem_toplevel_get_toplevel (w_current);
205 g_return_if_fail (object != NULL && object->type == OBJ_TEXT);
207 o_invalidate (w_current, object);
208 object->show_name_value = show_name_value;
209 o_text_recreate(toplevel, object);
213 /*! \todo Finish function documentation!!!
214 * \brief
215 * \par Function Description
218 /* This function no longer returns NULL, but will always return the new */
219 /* text item */
220 OBJECT *o_attrib_add_attrib(GschemToplevel *w_current,
221 const char *text_string, int visibility,
222 int show_name_value, OBJECT *object)
224 TOPLEVEL *toplevel = gschem_toplevel_get_toplevel (w_current);
225 OBJECT *new_obj;
226 int world_x = - 1, world_y = -1;
227 int align = LOWER_LEFT;
228 int angle = 0;
229 int color;
230 int left, right, top, bottom;
231 OBJECT *o_current;
233 color = DETACHED_ATTRIBUTE_COLOR;
235 o_current = object;
237 /* creating a toplevel or unattached attribute */
238 if (o_current) {
239 /* get coordinates of where to place the text object */
240 switch(o_current->type) {
241 case(OBJ_COMPLEX):
242 case(OBJ_PLACEHOLDER):
243 world_x = o_current->complex->x;
244 world_y = o_current->complex->y;
245 align = LOWER_LEFT;
246 angle = 0;
247 color = ATTRIBUTE_COLOR;
248 break;
250 case(OBJ_ARC):
251 world_x = o_current->arc->x;
252 world_y = o_current->arc->y;
253 align = LOWER_LEFT;
254 angle = 0;
255 color = ATTRIBUTE_COLOR;
256 break;
258 case(OBJ_CIRCLE):
259 world_x = o_current->circle->center_x;
260 world_y = o_current->circle->center_y;
261 align = LOWER_LEFT;
262 angle = 0;
263 color = ATTRIBUTE_COLOR;
264 break;
266 case(OBJ_BOX):
267 world_x = o_current->box->upper_x;
268 world_y = o_current->box->upper_y;
269 align = LOWER_LEFT;
270 angle = 0;
271 color = ATTRIBUTE_COLOR;
272 break;
274 case(OBJ_LINE):
275 case(OBJ_NET):
276 case(OBJ_PIN):
277 case(OBJ_BUS):
279 int dx = o_current->line->x[1] - o_current->line->x[0];
280 int dy = o_current->line->y[1] - o_current->line->y[0];
282 if (dy == 0) {
283 if (dx > 0) {
284 world_x = o_current->line->x[0] + SPACING_FROM_END;
285 world_y = o_current->line->y[0] + SPACING_PERPENDICULAR;
287 align = LOWER_LEFT;
288 angle = 0;
290 else {
291 world_x = o_current->line->x[0] - SPACING_FROM_END;
292 world_y = o_current->line->y[0] + SPACING_PERPENDICULAR;
294 align = LOWER_RIGHT;
295 angle = 0;
298 else if (dx == 0) {
299 if (dy > 0) {
300 world_x = o_current->line->x[0] - SPACING_PERPENDICULAR;
301 world_y = o_current->line->y[0] + SPACING_FROM_END;
303 align = LOWER_LEFT;
304 angle = 90;
306 else {
307 world_x = o_current->line->x[0] - SPACING_PERPENDICULAR;
308 world_y = o_current->line->y[0] - SPACING_FROM_END;
310 align = LOWER_RIGHT;
311 angle = 90;
314 else {
315 world_x = o_current->line->x[0];
316 world_y = o_current->line->y[0];
318 align = LOWER_LEFT;
319 angle = 0;
322 color = ATTRIBUTE_COLOR;
324 break;
326 case(OBJ_TEXT):
327 world_x = o_current->text->x;
328 world_y = o_current->text->y;
329 color = DETACHED_ATTRIBUTE_COLOR;
330 align = LOWER_LEFT;
331 angle = 0;
332 o_current = NULL;
333 break;
335 } else {
336 world_get_object_glist_bounds (toplevel,
337 s_page_objects (toplevel->page_current),
338 &left, &top, &right, &bottom);
340 /* this really is the lower left hand corner */
341 world_x = left;
342 world_y = top;
344 /* printf("%d %d\n", world_x, world_y); */
345 align = LOWER_LEFT;
346 angle = 0;
347 color = DETACHED_ATTRIBUTE_COLOR;
350 /* first create text item */
351 new_obj = o_text_new(toplevel, color, world_x, world_y,
352 align, angle, text_string,
353 w_current->text_size, /* current text size */
354 visibility, show_name_value);
355 s_page_append (toplevel, toplevel->page_current, new_obj);
357 /* now attach the attribute to the object (if o_current is not NULL) */
358 /* remember that o_current contains the object to get the attribute */
359 if (o_current) {
360 o_attrib_attach (toplevel, new_obj, o_current, FALSE);
363 o_selection_add (toplevel, toplevel->page_current->selection_list, new_obj);
365 /* handle slot= attribute, it's a special case */
366 if (o_current != NULL &&
367 g_ascii_strncasecmp (text_string, "slot=", 5) == 0) {
368 o_slot_end (w_current, o_current, text_string);
371 /* Call add-objects-hook. */
372 g_run_hook_object (w_current, "%add-objects-hook", new_obj);
373 g_run_hook_object (w_current, "%select-objects-hook", new_obj);
375 return new_obj;