Updated copyright text/header in most source files.
[geda-gaf/peter-b.git] / gschem / src / o_complex.c
blob826bb8f4cd6bfac0ed487036ba6543ce77bbb682
1 /* gEDA - GPL Electronic Design Automation
2 * gschem - gEDA Schematic Capture
3 * Copyright (C) 1998-2010 Ales Hvezda
4 * Copyright (C) 1998-2010 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., 59 Temple Place, Suite 330, Boston, MA 02111 USA
20 #include <config.h>
22 #include <stdio.h>
23 #include <math.h>
24 #ifdef HAVE_UNISTD_H
25 #include <unistd.h>
26 #endif
28 #include "gschem.h"
30 #ifdef HAVE_LIBDMALLOC
31 #include <dmalloc.h>
32 #endif
34 /*! \todo Finish function documentation!!!
35 * \brief
36 * \par Function Description
39 void o_complex_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
41 g_return_if_fail (o_current != NULL);
42 g_return_if_fail (o_current->complex != NULL);
44 if (!w_current->toplevel->DONT_REDRAW) {
45 o_redraw(w_current, o_current->complex->prim_objs, TRUE);
50 /*! \todo Finish function documentation!!!
51 * \brief
52 * \par Function Description
55 void o_complex_draw_place (GSCHEM_TOPLEVEL *w_current, int dx, int dy, OBJECT *object)
57 g_assert( (object->type == OBJ_COMPLEX ||
58 object->type == OBJ_PLACEHOLDER) );
60 o_glist_draw_place (w_current, dx, dy, object->complex->prim_objs);
64 /*! \todo Finish function documentation!!!
65 * \brief
66 * \par Function Description
69 void o_complex_prepare_place(GSCHEM_TOPLEVEL *w_current, const CLibSymbol *sym)
71 TOPLEVEL *toplevel = w_current->toplevel;
72 GList *temp_list;
73 OBJECT *o_current;
74 char *buffer;
75 const gchar *sym_name = s_clib_symbol_get_name (sym);
76 int redraw_state;
78 /* remove the old place list if it exists */
79 s_delete_object_glist(toplevel, toplevel->page_current->place_list);
80 toplevel->page_current->place_list = NULL;
82 /* Insert the new object into the buffer at world coordinates (0,0).
83 * It will be translated to the mouse coordinates during placement. */
85 w_current->first_wx = 0;
86 w_current->first_wy = 0;
88 if (w_current->include_complex) {
90 temp_list = NULL;
92 toplevel->ADDING_SEL=1;
93 buffer = s_clib_symbol_get_data (sym);
94 temp_list = o_read_buffer (toplevel,
95 temp_list,
96 buffer, -1,
97 sym_name);
98 g_free (buffer);
99 toplevel->ADDING_SEL=0;
101 /* Take the added objects */
102 toplevel->page_current->place_list =
103 g_list_concat (toplevel->page_current->place_list, temp_list);
105 } else { /* if (w_current->include_complex) {..} else { */
106 OBJECT *new_object;
108 toplevel->ADDING_SEL = 1; /* reuse this flag, rename later hack */
109 new_object = o_complex_new (toplevel, OBJ_COMPLEX, DEFAULT_COLOR,
110 0, 0, 0, 0, sym, sym_name, 1);
112 toplevel->page_current->place_list =
113 g_list_concat (toplevel->page_current->place_list,
114 o_complex_promote_attribs (toplevel, new_object));
115 toplevel->page_current->place_list =
116 g_list_append (toplevel->page_current->place_list, new_object);
118 toplevel->ADDING_SEL = 0;
120 /* Flag the symbol as embedded if necessary */
121 o_current = (g_list_last (toplevel->page_current->place_list))->data;
122 if (w_current->embed_complex) {
123 o_current->complex_embedded = TRUE;
127 /* Run the complex place list changed hook without redrawing */
128 /* since the place list is going to be redrawn afterwards */
129 redraw_state = toplevel->DONT_REDRAW;
130 toplevel->DONT_REDRAW = 1;
131 o_complex_place_changed_run_hook (w_current);
132 toplevel->DONT_REDRAW = redraw_state;
134 w_current->inside_action = 1;
135 i_set_state (w_current, ENDCOMP);
139 /*! \brief Run the complex place list changed hook.
140 * \par Function Description
141 * The complex place list is usually used when placing new components
142 * in the schematic. This function should be called whenever that list
143 * is modified.
144 * \param [in] w_current GSCHEM_TOPLEVEL structure.
147 void o_complex_place_changed_run_hook(GSCHEM_TOPLEVEL *w_current) {
148 TOPLEVEL *toplevel = w_current->toplevel;
149 GList *ptr = NULL;
151 /* Run the complex place list changed hook */
152 if (scm_hook_empty_p(complex_place_list_changed_hook) == SCM_BOOL_F &&
153 toplevel->page_current->place_list != NULL) {
154 ptr = toplevel->page_current->place_list;
155 while (ptr) {
156 scm_run_hook(complex_place_list_changed_hook,
157 scm_cons (g_make_object_smob
158 (toplevel,
159 (OBJECT *) ptr->data), SCM_EOL));
160 ptr = g_list_next(ptr);
167 /*! \todo Finish function documentation!!!
168 * \brief
169 * \par Function Description
172 void o_complex_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y, int continue_placing)
174 GList *new_objects;
175 GList *iter;
176 OBJECT *o_current;
178 o_place_end (w_current, w_x, w_y, continue_placing, &new_objects);
180 if (w_current->include_complex) {
181 g_list_free (new_objects);
182 return;
185 /* Run the add component hook for the new component */
186 for (iter = new_objects;
187 iter != NULL;
188 iter = g_list_next (iter)) {
189 o_current = iter->data;
191 if (scm_hook_empty_p(add_component_hook) == SCM_BOOL_F) {
192 scm_run_hook(add_component_hook,
193 scm_cons(g_make_attrib_smob_list(w_current, o_current),
194 SCM_EOL));
197 if (scm_hook_empty_p(add_component_object_hook) == SCM_BOOL_F) {
198 scm_run_hook(add_component_object_hook,
199 scm_cons(g_make_object_smob(w_current->toplevel,
200 o_current), SCM_EOL));
204 g_list_free (new_objects);
208 /*! \todo Finish function documentation!!!
209 * \brief
210 * \par Function Description
212 * \note
213 * don't know if this belongs yet
215 void o_complex_translate_all(GSCHEM_TOPLEVEL *w_current, int offset)
217 TOPLEVEL *toplevel = w_current->toplevel;
218 int w_rleft, w_rtop, w_rright, w_rbottom;
219 OBJECT *o_current;
220 const GList *iter;
221 int x, y;
223 /* first zoom extents */
224 a_zoom_extents (w_current, s_page_objects (toplevel->page_current),
225 A_PAN_DONT_REDRAW);
226 o_invalidate_all (w_current);
228 world_get_object_glist_bounds (toplevel,
229 s_page_objects (toplevel->page_current),
230 &w_rleft, &w_rtop,
231 &w_rright, &w_rbottom);
233 /*! \todo do we want snap grid here? */
234 x = snap_grid (w_current, w_rleft);
235 /* WARNING: w_rtop isn't the top of the bounds, it is the smaller
236 * y_coordinate, which represents in the bottom in world coords.
237 * These variables are as named from when screen-coords (which had
238 * the correct sense) were in use . */
239 y = snap_grid (w_current, w_rtop);
241 iter = s_page_objects (toplevel->page_current);
242 while (iter != NULL) {
243 o_current = iter->data;
244 s_conn_remove_object (toplevel, o_current);
245 iter = g_list_next (iter);
248 if (offset == 0) {
249 s_log_message(_("Translating schematic [%d %d]\n"), -x, -y);
250 o_glist_translate_world (toplevel, -x, -y,
251 s_page_objects (toplevel->page_current));
252 } else {
253 s_log_message(_("Translating schematic [%d %d]\n"),
254 offset, offset);
255 o_glist_translate_world (toplevel, offset, offset,
256 s_page_objects (toplevel->page_current));
259 iter = s_page_objects (toplevel->page_current);
260 while (iter != NULL) {
261 o_current = iter->data;
262 if (o_current->type != OBJ_COMPLEX && o_current->type != OBJ_PLACEHOLDER) {
263 s_conn_update_object (toplevel, o_current);
264 } else {
265 s_conn_update_object (toplevel, o_current);
267 iter = g_list_next (iter);
270 /* this is an experimental mod, to be able to translate to all
271 * places */
272 a_zoom_extents (w_current, s_page_objects (toplevel->page_current),
273 A_PAN_DONT_REDRAW);
274 if (!w_current->SHIFTKEY) o_select_unselect_all(w_current);
275 o_invalidate_all (w_current);
276 toplevel->page_current->CHANGED=1;
277 o_undo_savestate(w_current, UNDO_ALL);
278 i_update_menus(w_current);