libgeda
|
00001 /* gEDA - GPL Electronic Design Automation 00002 * libgeda - gEDA's library 00003 * Copyright (C) 1998-2010 Ales Hvezda 00004 * Copyright (C) 1998-2010 gEDA Contributors (see ChangeLog for details) 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00019 */ 00020 #include <config.h> 00021 00022 #include <stdio.h> 00023 #ifdef HAVE_STRING_H 00024 #include <string.h> 00025 #endif 00026 00027 #include "libgeda_priv.h" 00028 00029 #ifdef HAVE_LIBDMALLOC 00030 #include <dmalloc.h> 00031 #endif 00032 00034 extern int global_sid; 00035 00047 OBJECT *o_object_copy (TOPLEVEL *toplevel, 00048 OBJECT *selected) 00049 { 00050 OBJECT *new_obj; 00051 00052 g_return_val_if_fail (toplevel != NULL, NULL); 00053 g_return_val_if_fail (selected != NULL, NULL); 00054 00055 switch(selected->type) { 00056 00057 case(OBJ_LINE): 00058 new_obj = o_line_copy (toplevel, selected); 00059 break; 00060 00061 case(OBJ_NET): 00062 new_obj = o_net_copy (toplevel, selected); 00063 break; 00064 00065 case(OBJ_BUS): 00066 new_obj = o_bus_copy (toplevel, selected); 00067 break; 00068 00069 case(OBJ_BOX): 00070 new_obj = o_box_copy (toplevel, selected); 00071 break; 00072 00073 case(OBJ_PICTURE): 00074 new_obj = o_picture_copy (toplevel, selected); 00075 break; 00076 00077 case(OBJ_CIRCLE): 00078 new_obj = o_circle_copy (toplevel, selected); 00079 break; 00080 00081 case(OBJ_COMPLEX): 00082 case(OBJ_PLACEHOLDER): 00083 new_obj = o_complex_copy (toplevel, selected); 00084 break; 00085 00086 case(OBJ_TEXT): 00087 new_obj = o_text_copy (toplevel, selected); 00088 break; 00089 00090 case(OBJ_PATH): 00091 new_obj = o_path_copy (toplevel, selected); 00092 break; 00093 00094 case(OBJ_PIN): 00095 new_obj = o_pin_copy (toplevel, selected); 00096 break; 00097 00098 case(OBJ_ARC): 00099 new_obj = o_arc_copy (toplevel, selected); 00100 break; 00101 00102 default: 00103 g_critical ("o_list_copy_to: object %p has bad type '%c'\n", 00104 selected, selected->type); 00105 return NULL; 00106 } 00107 00108 /* Store a reference in the copied object to where it was copied. 00109 * Used to retain associations when copying attributes */ 00110 selected->copied_to = new_obj; 00111 00112 /* make sure sid is the same! */ 00113 if (selected) { 00114 new_obj->sid = selected->sid; 00115 } 00116 00117 return new_obj; 00118 } 00119 00120 00137 GList *o_glist_copy_all (TOPLEVEL *toplevel, 00138 const GList *src_list, 00139 GList *dest_list) 00140 { 00141 const GList *src; 00142 GList *dest; 00143 OBJECT *src_object, *dst_object; 00144 int selected_save; 00145 00146 src = src_list; 00147 /* Reverse any existing items, as we will prepend, then reverse at the end */ 00148 dest = g_list_reverse (dest_list); 00149 00150 if (src == NULL) { 00151 return(NULL); 00152 } 00153 00154 /* first do all NON text items */ 00155 while(src != NULL) { 00156 src_object = (OBJECT *) src->data; 00157 00158 /* unselect the object before the copy */ 00159 selected_save = src_object->selected; 00160 if (selected_save) 00161 o_selection_unselect (toplevel, src_object); 00162 00163 if (src_object->type != OBJ_TEXT) { 00164 dst_object = o_object_copy (toplevel, src_object); 00165 dst_object->sid = global_sid++; 00166 dest = g_list_prepend (dest, dst_object); 00167 } 00168 00169 /* reselect it */ 00170 if (selected_save) 00171 o_selection_select (toplevel, src_object); 00172 00173 src = g_list_next(src); 00174 } 00175 00176 src = src_list; 00177 00178 /* then do all text items */ 00179 while(src != NULL) { 00180 src_object = (OBJECT *) src->data; 00181 00182 /* unselect the object before the copy */ 00183 selected_save = src_object->selected; 00184 if (selected_save) 00185 o_selection_unselect (toplevel, src_object); 00186 00187 if (src_object->type == OBJ_TEXT) { 00188 dst_object = o_object_copy (toplevel, src_object); 00189 dst_object->sid = global_sid++; 00190 dest = g_list_prepend (dest, dst_object); 00191 00192 if (src_object->attached_to != NULL && 00193 src_object->attached_to->copied_to != NULL) { 00194 o_attrib_attach(toplevel, dst_object, 00195 src_object->attached_to->copied_to, FALSE); 00196 /* handle slot= attribute, it's a special case */ 00197 if (g_ascii_strncasecmp (dst_object->text->string, "slot=", 5) == 0) 00198 s_slot_update_object (toplevel, src_object->attached_to->copied_to); 00199 } 00200 } 00201 00202 /* reselect it */ 00203 if (selected_save) 00204 o_selection_select (toplevel, src_object); 00205 00206 src = g_list_next(src); 00207 } 00208 00209 /* Clean up dangling copied_to pointers */ 00210 src = src_list; 00211 while(src != NULL) { 00212 src_object = src->data; 00213 src_object->copied_to = NULL; 00214 src = g_list_next (src); 00215 } 00216 00217 /* Reverse the list to be in the correct order */ 00218 dest = g_list_reverse (dest); 00219 00220 return(dest); 00221 } 00222 00223 00228 void o_glist_translate_world(TOPLEVEL *toplevel, int dx, int dy, const GList *list) 00229 { 00230 const GList *iter = list; 00231 OBJECT *o_current; 00232 00233 while ( iter != NULL ) { 00234 o_current = (OBJECT *)iter->data; 00235 o_translate_world(toplevel, dx, dy, o_current); 00236 iter = g_list_next (iter); 00237 } 00238 } 00239 00240 00245 void o_glist_rotate_world (TOPLEVEL *toplevel, int x, int y, int angle, const GList *list) 00246 { 00247 const GList *iter = list; 00248 OBJECT *o_current; 00249 00250 while ( iter != NULL ) { 00251 o_current = (OBJECT *)iter->data; 00252 o_rotate_world (toplevel, x, y, angle, o_current); 00253 iter = g_list_next (iter); 00254 } 00255 } 00256 00257 00262 void o_glist_mirror_world (TOPLEVEL *toplevel, int x, int y, const GList *list) 00263 { 00264 const GList *iter = list; 00265 OBJECT *o_current; 00266 00267 while ( iter != NULL ) { 00268 o_current = (OBJECT *)iter->data; 00269 o_mirror_world (toplevel, x, y, o_current); 00270 iter = g_list_next (iter); 00271 } 00272 } 00273 00274 00284 void o_glist_set_color (TOPLEVEL *toplevel, const GList *list, int color) 00285 { 00286 const GList *iter; 00287 00288 for (iter = list; iter != NULL; iter = g_list_next (iter)) 00289 o_set_color (toplevel, iter->data, color); 00290 }