gattrib
|
00001 /* gEDA - GPL Electronic Design Automation 00002 * gattrib -- gEDA component and net attribute manipulation using spreadsheet. 00003 * Copyright (C) 2003-2010 Stuart D. Brorson. 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software 00017 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00018 */ 00019 00020 /*------------------------------------------------------------------*/ 00033 #include <config.h> 00034 00035 #include <stdio.h> 00036 #ifdef HAVE_STRING_H 00037 #include <string.h> 00038 #endif 00039 #include <math.h> 00040 00041 /*------------------------------------------------------------------ 00042 * Gattrib specific includes 00043 *------------------------------------------------------------------*/ 00044 #include <libgeda/libgeda.h> /* geda library fcns */ 00045 #include "../include/struct.h" /* typdef and struct declarations */ 00046 #include "../include/prototype.h" /* function prototypes */ 00047 #include "../include/globals.h" 00048 00049 #ifdef HAVE_LIBDMALLOC 00050 #include <dmalloc.h> 00051 #endif 00052 00053 00054 /*------------------------------------------------------------------ 00055 * Gattrib specific defines 00056 *------------------------------------------------------------------*/ 00057 #define DEFAULT_TEXT_SIZE 10 00058 00059 00060 /* =================== Public Functions ====================== */ 00061 00062 /*------------------------------------------------------------------*/ 00080 void 00081 s_object_add_comp_attrib_to_object (TOPLEVEL *toplevel, 00082 OBJECT *o_current, 00083 char *new_attrib_name, 00084 char *new_attrib_value, 00085 gint visibility, 00086 gint show_name_value) 00087 { 00088 char *name_value_pair; 00089 00090 00091 /* One last sanity check, then add attrib */ 00092 if (strlen(new_attrib_value) != 0) { 00093 name_value_pair = g_strconcat(new_attrib_name, "=", new_attrib_value, NULL); 00094 s_object_attrib_add_attrib_in_object (toplevel, 00095 name_value_pair, 00096 visibility, 00097 show_name_value, 00098 o_current); 00099 } 00100 00101 return; 00102 00103 } 00104 00105 00106 /*------------------------------------------------------------------*/ 00110 void 00111 s_object_add_net_attrib_to_object (TOPLEVEL *toplevel, 00112 OBJECT *o_current, 00113 char *new_attrib_name, 00114 char *new_attrib_value) 00115 { 00116 /* TBD */ 00117 } 00118 00119 00120 /*------------------------------------------------------------------*/ 00138 void 00139 s_object_add_pin_attrib_to_object (TOPLEVEL *toplevel, 00140 OBJECT *o_current, 00141 char *new_attrib_name, 00142 char *new_attrib_value) 00143 { 00144 char *name_value_pair; 00145 00146 /* One last sanity check */ 00147 if (strlen(new_attrib_value) != 0) { 00148 name_value_pair = g_strconcat(new_attrib_name, "=", new_attrib_value, NULL); 00149 s_object_attrib_add_attrib_in_object (toplevel, 00150 name_value_pair, 00151 INVISIBLE, 00152 SHOW_NAME_VALUE, 00153 o_current); 00154 } 00155 00156 return; 00157 } 00158 00159 00160 /*------------------------------------------------------------------*/ 00172 void s_object_replace_attrib_in_object(TOPLEVEL *toplevel, 00173 OBJECT *o_current, 00174 char *new_attrib_name, 00175 char *new_attrib_value, 00176 gint visibility, 00177 gint show_name_value) 00178 { 00179 GList *a_iter; 00180 OBJECT *a_current; 00181 char *old_attrib_text; 00182 char *old_attrib_name; 00183 char *new_attrib_text; 00184 00185 00186 a_iter = o_current->attribs; 00187 while (a_iter != NULL) { 00188 a_current = a_iter->data; 00189 if (a_current->type == OBJ_TEXT 00190 && a_current->text != NULL) { /* found an attribute */ 00191 00192 /* may need to check more thoroughly here. . . . */ 00193 old_attrib_text = g_strdup(a_current->text->string); 00194 old_attrib_name = u_basic_breakup_string(old_attrib_text, '=', 0); 00195 00196 if (strcmp(old_attrib_name, new_attrib_name) == 0) { 00197 /* create attrib=value text string & stuff it back into toplevel */ 00198 new_attrib_text = g_strconcat(new_attrib_name, "=", new_attrib_value, NULL); 00199 g_free(a_current->text->string); /* remove old attrib string */ 00200 a_current->text->string = g_strdup(new_attrib_text); /* insert new attrib string */ 00201 if (visibility != LEAVE_VISIBILITY_ALONE) 00202 o_set_visibility (toplevel, a_current, visibility); 00203 if (show_name_value != LEAVE_NAME_VALUE_ALONE) 00204 a_current->show_name_value = show_name_value; 00205 g_free(new_attrib_text); 00206 g_free(old_attrib_text); 00207 g_free(old_attrib_name); 00208 return; /* we are done -- leave. */ 00209 } else { 00210 g_free(old_attrib_text); 00211 g_free(old_attrib_name); 00212 } /* if (strcmp . . . . */ 00213 } /* if (a_current . . . . */ 00214 00215 a_iter = g_list_next (a_iter); 00216 } /* while */ 00217 00218 /* if we get here, it's because we have failed to find the attrib on the component. 00219 * This is an error condition. */ 00220 fprintf(stderr, 00221 "In s_object_replace_attrib_in_object, we have failed to find the attrib %s on the component. Exiting . . .\n", 00222 new_attrib_name); 00223 exit(-1); 00224 } 00225 00226 00227 /*------------------------------------------------------------------*/ 00236 void 00237 s_object_remove_attrib_in_object (TOPLEVEL *toplevel, 00238 OBJECT *o_current, 00239 char *new_attrib_name) 00240 { 00241 GList *a_iter; 00242 OBJECT *a_current; 00243 OBJECT *attribute_object; 00244 char *old_attrib_text; 00245 char *old_attrib_name; 00246 00247 a_iter = o_current->attribs; 00248 while (a_iter != NULL) { 00249 a_current = a_iter->data; 00250 if (a_current->type == OBJ_TEXT 00251 && a_current->text != NULL) { /* found an attribute */ 00252 00253 /* may need to check more thoroughly here. . . . */ 00254 old_attrib_text = g_strdup(a_current->text->string); 00255 old_attrib_name = u_basic_breakup_string(old_attrib_text, '=', 0); 00256 00257 if (strcmp(old_attrib_name, new_attrib_name) == 0) { 00258 /* We've found the attrib. Delete it and then return. */ 00259 00260 #ifdef DEBUG 00261 printf("In s_object_remove_attrib_in_object, removing attrib with name = %s\n", old_attrib_name); 00262 #endif 00263 00264 attribute_object = a_current; 00265 s_object_delete_text_object_in_object (toplevel, attribute_object); 00266 00267 g_free(old_attrib_text); 00268 g_free(old_attrib_name); 00269 return; /* we are done -- leave. */ 00270 } 00271 g_free(old_attrib_text); 00272 g_free(old_attrib_name); 00273 } 00274 a_iter = g_list_next (a_iter); 00275 } 00276 00277 /* if we get here, it's because we have failed to find the attrib on the component. 00278 * This is an error condition. */ 00279 fprintf(stderr, 00280 "In s_object_remove_attrib_in_object, we have failed to find the attrib %s on the component. Exiting . . .\n", 00281 new_attrib_name); 00282 exit(-1); 00283 } 00284 00285 00286 00287 /*------------------------------------------------------------------*/ 00301 OBJECT * 00302 s_object_attrib_add_attrib_in_object (TOPLEVEL *toplevel, 00303 char *text_string, 00304 int visibility, 00305 int show_name_value, 00306 OBJECT * object) 00307 { 00308 int world_x = -1, world_y = -1; 00309 int color; 00310 int left, right, top, bottom; 00311 OBJECT *o_current; 00312 OBJECT *new_obj; 00313 00314 color = DETACHED_ATTRIBUTE_COLOR; 00315 00316 o_current = object; 00317 00318 /* creating a toplevel or unattached attribute */ 00319 if (o_current) { 00320 /* get coordinates of where to place the text object */ 00321 switch (o_current->type) { 00322 case (OBJ_COMPLEX): 00323 world_x = o_current->complex->x; 00324 world_y = o_current->complex->y; 00325 color = ATTRIBUTE_COLOR; 00326 break; 00327 00328 case (OBJ_NET): 00329 world_x = o_current->complex->x; 00330 world_y = o_current->complex->y; 00331 color = ATTRIBUTE_COLOR; 00332 break; 00333 00334 default: 00335 fprintf(stderr, "In s_object_attrib_add_attrib_in_object, trying to add attrib to non-complex or non-net!\n"); 00336 exit(-1); 00337 } 00338 } else { /* This must be a floating attrib, but what is that !?!?!?!?! */ 00339 world_get_object_glist_bounds (toplevel, 00340 s_page_objects (toplevel->page_current), 00341 &left, &top, &right, &bottom); 00342 00343 /* this really is the lower left hand corner */ 00344 world_x = left; 00345 world_y = top; 00346 00347 /* printf("%d %d\n", world_x, world_y); */ 00348 color = DETACHED_ATTRIBUTE_COLOR; 00349 } 00350 00351 /* first create text item */ 00352 #if DEBUG 00353 printf("=== In s_object_attrib_add_attrib_in_object, about to attach new text attrib with properties:\n"); 00354 printf(" color = %d\n", color); 00355 printf(" text_string = %s \n", text_string); 00356 printf(" text_size = %d \n", toplevel->text_size); 00357 printf(" visibility = %d \n", visibility); 00358 printf(" show_name_value = %d \n", show_name_value); 00359 #endif 00360 00361 new_obj = o_text_new (toplevel, OBJ_TEXT, color, world_x, world_y, 00362 LOWER_LEFT, 0, /* zero is angle */ 00363 text_string, DEFAULT_TEXT_SIZE, 00364 visibility, show_name_value); 00365 s_page_append (toplevel, toplevel->page_current, new_obj); 00366 00367 /* now toplevel->page_current->object_tail contains new text item */ 00368 00369 /* now attach the attribute to the object (if o_current is not NULL) */ 00370 /* remember that o_current contains the object to get the attribute */ 00371 if (o_current) { 00372 o_attrib_attach (toplevel, new_obj, o_current, FALSE); 00373 } 00374 00375 o_selection_add (toplevel, 00376 toplevel->page_current->selection_list, new_obj); 00377 00378 00379 toplevel->page_current->CHANGED = 1; 00380 00381 return new_obj; 00382 } 00383 00384 00385 00386 00387 /*------------------------------------------------------------------*/ 00396 void 00397 s_object_delete_text_object_in_object (TOPLEVEL *toplevel, 00398 OBJECT * text_object) 00399 { 00400 s_page_remove (toplevel, toplevel->page_current, text_object); 00401 s_delete_object (toplevel, text_object); 00402 toplevel->page_current->CHANGED = 1; 00403 } 00404 00405 00406 /*------------------------------------------------------------------*/ 00413 int s_object_has_sym_file(OBJECT *object) 00414 { 00415 char *filename; 00416 00417 filename = object->complex_basename; 00418 if (filename != NULL) { 00419 #ifdef DEBUG 00420 printf("In s_object_has_sym_file, object has sym file = %s.\n", filename); 00421 #endif 00422 return 0; 00423 } else { 00424 #ifdef DEBUG 00425 printf("In s_object_has_sym_file, found object with no attached symbol file.\n"); 00426 #endif 00427 return 1; 00428 } 00429 }