gschem

o_complex.c

Go to the documentation of this file.
00001 /* gEDA - GPL Electronic Design Automation
00002  * gschem - gEDA Schematic Capture
00003  * Copyright (C) 1998-2010 Ales Hvezda
00004  * Copyright (C) 1998-2011 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 #include <math.h>
00024 #ifdef HAVE_UNISTD_H
00025 #include <unistd.h>
00026 #endif
00027 
00028 #include "gschem.h"
00029 #include <missing.h>
00030 
00031 #ifdef HAVE_LIBDMALLOC
00032 #include <dmalloc.h>
00033 #endif
00034 
00040 void o_complex_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
00041 {
00042   g_return_if_fail (o_current != NULL); 
00043   g_return_if_fail (o_current->complex != NULL);
00044 
00045   o_redraw(w_current, o_current->complex->prim_objs, TRUE);
00046 }
00047 
00048 
00054 void o_complex_draw_place (GSCHEM_TOPLEVEL *w_current, int dx, int dy, OBJECT *object)
00055 {
00056   g_assert( (object->type == OBJ_COMPLEX ||
00057              object->type == OBJ_PLACEHOLDER) );
00058 
00059   o_glist_draw_place (w_current, dx, dy, object->complex->prim_objs);
00060 }
00061 
00062 
00068 void o_complex_prepare_place(GSCHEM_TOPLEVEL *w_current, const CLibSymbol *sym)
00069 {
00070   TOPLEVEL *toplevel = w_current->toplevel;
00071   GList *temp_list;
00072   OBJECT *o_current;
00073   char *buffer;
00074   const gchar *sym_name = s_clib_symbol_get_name (sym);
00075   GError *err = NULL;
00076 
00077   /* remove the old place list if it exists */
00078   s_delete_object_glist(toplevel, toplevel->page_current->place_list);
00079   toplevel->page_current->place_list = NULL;
00080 
00081   /* Insert the new object into the buffer at world coordinates (0,0).
00082    * It will be translated to the mouse coordinates during placement. */
00083 
00084   w_current->first_wx = 0;
00085   w_current->first_wy = 0;
00086 
00087   if (w_current->include_complex) {
00088 
00089     temp_list = NULL;
00090 
00091     buffer = s_clib_symbol_get_data (sym);
00092     temp_list = o_read_buffer (toplevel,
00093                                temp_list,
00094                                buffer, -1,
00095                                sym_name,
00096                                &err);
00097     g_free (buffer);
00098 
00099     if (err) {
00100       /* If an error occurs here, we can assume that the preview also has failed to load,
00101          and the error message is displayed there. We therefore ignore this error, but
00102          end the component insertion.
00103          */
00104 
00105       g_error_free(err);
00106       i_set_state (w_current, SELECT);
00107       return;
00108     }
00109 
00110     /* Take the added objects */
00111     toplevel->page_current->place_list =
00112       g_list_concat (toplevel->page_current->place_list, temp_list);
00113 
00114   } else { /* if (w_current->include_complex) {..} else { */
00115     OBJECT *new_object;
00116 
00117     new_object = o_complex_new (toplevel, OBJ_COMPLEX, DEFAULT_COLOR,
00118                                 0, 0, 0, 0, sym, sym_name, 1);
00119 
00120     if (new_object->type == OBJ_PLACEHOLDER) {
00121       /* If created object is a placeholder, the loading failed and we end the insert action */
00122 
00123       s_delete_object(toplevel, new_object);
00124       i_set_state (w_current, SELECT);
00125       return;
00126     }
00127     else {
00128 
00129       toplevel->page_current->place_list =
00130           g_list_concat (toplevel->page_current->place_list,
00131                          o_complex_promote_attribs (toplevel, new_object));
00132       toplevel->page_current->place_list =
00133           g_list_append (toplevel->page_current->place_list, new_object);
00134 
00135       /* Flag the symbol as embedded if necessary */
00136       o_current = (g_list_last (toplevel->page_current->place_list))->data;
00137       if (w_current->embed_complex) {
00138         o_current->complex_embedded = TRUE;
00139       }
00140     }
00141   }
00142 
00143   /* Run the complex place list changed hook without redrawing */
00144   /* since the place list is going to be redrawn afterwards */
00145   o_complex_place_changed_run_hook (w_current);
00146  
00147   w_current->inside_action = 1;
00148   i_set_state (w_current, ENDCOMP);
00149 }
00150 
00151 
00160 void o_complex_place_changed_run_hook(GSCHEM_TOPLEVEL *w_current) {
00161   TOPLEVEL *toplevel = w_current->toplevel;
00162   GList *ptr = NULL;
00163 
00164   /* Run the complex place list changed hook */
00165   if (scm_is_false (scm_hook_empty_p (complex_place_list_changed_hook)) &&
00166       toplevel->page_current->place_list != NULL) {
00167     ptr = toplevel->page_current->place_list;
00168 
00169     scm_dynwind_begin (0);
00170     g_dynwind_window (w_current);
00171     while (ptr) {
00172       SCM expr = scm_list_3 (scm_from_utf8_symbol ("run-hook"),
00173                              complex_place_list_changed_hook,
00174                              edascm_from_object ((OBJECT *) ptr->data));
00175       g_scm_eval_protected (expr, scm_interaction_environment ());
00176       ptr = g_list_next(ptr);
00177     }
00178     scm_dynwind_end ();
00179   }
00180 }
00181 
00182 
00190 void o_complex_translate_all(GSCHEM_TOPLEVEL *w_current, int offset)
00191 {
00192   TOPLEVEL *toplevel = w_current->toplevel;
00193   int w_rleft, w_rtop, w_rright, w_rbottom;
00194   OBJECT *o_current;
00195   const GList *iter;
00196   int x, y;
00197 
00198   /* first zoom extents */
00199   a_zoom_extents (w_current, s_page_objects (toplevel->page_current),
00200                   A_PAN_DONT_REDRAW);
00201   o_invalidate_all (w_current);
00202 
00203   world_get_object_glist_bounds (toplevel,
00204                                  s_page_objects (toplevel->page_current),
00205                                  &w_rleft,  &w_rtop,
00206                                  &w_rright, &w_rbottom);
00207 
00209   x = snap_grid (w_current, w_rleft);
00210   /* WARNING: w_rtop isn't the top of the bounds, it is the smaller
00211    * y_coordinate, which represents in the bottom in world coords.
00212    * These variables are as named from when screen-coords (which had 
00213    * the correct sense) were in use . */
00214   y = snap_grid (w_current, w_rtop);
00215 
00216   for (iter = s_page_objects (toplevel->page_current);
00217        iter != NULL; iter = g_list_next (iter)) {
00218     o_current = iter->data;
00219     s_conn_remove_object (toplevel, o_current);
00220   }
00221 
00222   if (offset == 0) {
00223     s_log_message(_("Translating schematic [%d %d]\n"), -x, -y);
00224     o_glist_translate_world (toplevel, -x, -y,
00225                              s_page_objects (toplevel->page_current));
00226   } else {
00227     s_log_message(_("Translating schematic [%d %d]\n"),
00228                   offset, offset);
00229     o_glist_translate_world (toplevel, offset, offset,
00230                              s_page_objects (toplevel->page_current));
00231   }
00232 
00233   for (iter = s_page_objects (toplevel->page_current);
00234        iter != NULL;  iter = g_list_next (iter)) {
00235     o_current = iter->data;
00236     s_conn_update_object (toplevel, o_current);
00237   }
00238 
00239   /* this is an experimental mod, to be able to translate to all
00240    * places */
00241   a_zoom_extents (w_current, s_page_objects (toplevel->page_current),
00242                  A_PAN_DONT_REDRAW);
00243   if (!w_current->SHIFTKEY) o_select_unselect_all(w_current);
00244   o_invalidate_all (w_current);
00245   toplevel->page_current->CHANGED=1;
00246   o_undo_savestate(w_current, UNDO_ALL);
00247   i_update_menus(w_current);
00248 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines