Ejemplo n.º 1
0
/*! \todo Finish function documentation!!!
 *  \brief
 *  \par Function Description
 *  Copy all attributes select to the selection list.
 *
 *  \todo get a better name
 */
void o_attrib_add_selected(GschemToplevel *w_current, SELECTION *selection,
                           OBJECT *selected)
{
  OBJECT *a_current;
  GList *a_iter;
  GList *selected_objects = NULL;

  g_assert( selection != NULL );

  for (a_iter = selected->attribs; a_iter != NULL;
       a_iter = g_list_next (a_iter)) {
    a_current = a_iter->data;

    /* make sure object isn't selected already */
    if (!a_current->selected) {
      o_selection_add (w_current->toplevel, selection, a_current);
      selected_objects = g_list_prepend (selected_objects, a_current);
    }
  }

  if (selected_objects != NULL) {
    /* Run select-objects-hook */
    g_run_hook_object_list (w_current, "%select-objects-hook",
                            selected_objects);
    g_list_free (selected_objects);
  }
}
Ejemplo n.º 2
0
/*! \brief Rotate all objects in list.
 *  \par Function Description
 *  Given an object <B>list</B>, and the center of rotation
 *  (<B>centerx</B>,<B>centery</B>, this function traverses all the selection
 *  list, rotating each object through angle <B>angle</B>.
 *  The list contains a given object and all its attributes
 *  (refdes, pinname, pinlabel, ...).
 *  There is a second pass to run the rotate hooks of non-simple objects,
 *  like pin or complex objects, for example.
 *
 *  \param [in] w_current  The GschemToplevel object.
 *  \param [in] centerx    Center x coordinate of rotation.
 *  \param [in] centery    Center y coordinate of rotation.
 *  \param [in] angle      Angle to rotate the objects through.
 *  \param [in] list       The list of objects to rotate.
 */
void o_rotate_world_update(GschemToplevel *w_current,
                           int centerx, int centery, int angle, GList *list)
{
  TOPLEVEL *toplevel = gschem_toplevel_get_toplevel (w_current);
  OBJECT *o_current;
  GList *o_iter;

  /* this is okay if you just hit rotate and have nothing selected */
  if (list == NULL) {
    i_action_stop (w_current);
    i_set_state(w_current, SELECT);
    return;
  }

  o_invalidate_glist (w_current, list);

  /* Find connected objects, removing each object in turn from the
   * connection list. We only _really_ want those objects connected
   * to the selection, not those within in it.
   */
  for (o_iter = list; o_iter != NULL; o_iter = g_list_next (o_iter)) {
    o_current = o_iter->data;

    s_conn_remove_object_connections (toplevel, o_current);
  }

  o_glist_rotate_world( toplevel, centerx, centery, angle, list );

  /* Find connected objects, adding each object in turn back to the
   * connection list. We only _really_ want those objects connected
   * to the selection, not those within in it.
   */
  for (o_iter = list; o_iter != NULL; o_iter = g_list_next (o_iter)) {
    o_current = o_iter->data;

    s_conn_update_object (o_current->page, o_current);
  }

  o_invalidate_glist (w_current, list);

  /* Run rotate-objects-hook */
  g_run_hook_object_list (w_current, "%rotate-objects-hook", list);

  /* Don't save the undo state if we are inside an action */
  /* This is useful when rotating the selection while moving, for example */
  gschem_toplevel_page_content_changed (w_current, toplevel->page_current);
  if (!w_current->inside_action) {
    o_undo_savestate_old(w_current, UNDO_ALL);
  }

  if (w_current->event_state == ROTATEMODE) {
    i_set_state(w_current, SELECT);
  }
}
Ejemplo n.º 3
0
/*! \todo Finish function documentation!!!
 *  \brief
 *  \par Function Description
 *
 */
void o_place_rotate (GSCHEM_TOPLEVEL *w_current)
{
  TOPLEVEL *toplevel = w_current->toplevel;

  o_glist_rotate_world (toplevel,
                        w_current->first_wx, w_current->first_wy, 90,
                        toplevel->page_current->place_list);


  /* Run rotate-objects-hook */
  g_run_hook_object_list ("%rotate-objects-hook",
                          toplevel->page_current->place_list);
}
Ejemplo n.º 4
0
/*! \todo Finish function documentation!!!
 *  \brief
 *  \par Function Description
 *
 */
void o_mirror_world_update(GschemToplevel *w_current, int centerx, int centery, GList *list)
{
  TOPLEVEL *toplevel = gschem_toplevel_get_toplevel (w_current);
  OBJECT *o_current;
  GList *o_iter;

  if (list == NULL) {
    i_action_stop (w_current);
    i_set_state(w_current, SELECT);
    return;
  }

  o_invalidate_glist (w_current, list);

  /* Find connected objects, removing each object in turn from the
   * connection list. We only _really_ want those objects connected
   * to the selection, not those within in it.
   */
  for (o_iter = list; o_iter != NULL; o_iter = g_list_next (o_iter)) {
    o_current = o_iter->data;

    s_conn_remove_object_connections (toplevel, o_current);
  }

  o_glist_mirror_world( toplevel, centerx, centery, list );

  /* Find connected objects, adding each object in turn back to the
   * connection list. We only _really_ want those objects connected
   * to the selection, not those within in it.
   */
  for (o_iter = list; o_iter != NULL; o_iter = g_list_next (o_iter)) {
    o_current = o_iter->data;

    s_conn_update_object (o_current->page, o_current);
  }

  o_invalidate_glist (w_current, list);

  /* Run mirror-objects-hook */
  g_run_hook_object_list (w_current, "%mirror-objects-hook", list);

  gschem_toplevel_page_content_changed (w_current, toplevel->page_current);
  o_undo_savestate_old(w_current, UNDO_ALL);

  if (w_current->event_state == MIRRORMODE) {
    i_set_state(w_current, SELECT);
  }
}
Ejemplo n.º 5
0
/*! \todo Finish function documentation!!!
 *  \brief
 *  \par Function Description
 *
 */
void o_mirror_world_update(GSCHEM_TOPLEVEL *w_current, int centerx, int centery, GList *list)
{
  TOPLEVEL *toplevel = w_current->toplevel;
  OBJECT *o_current;
  GList *o_iter;

  if (list == NULL) {
    w_current->inside_action = 0;
    i_set_state(w_current, SELECT);
    return;
  }

  o_invalidate_glist (w_current, list);

  /* Find connected objects, removing each object in turn from the
   * connection list. We only _really_ want those objects connected
   * to the selection, not those within in it.
   */
  for (o_iter = list; o_iter != NULL; o_iter = g_list_next (o_iter)) {
    o_current = o_iter->data;

    s_conn_remove_object (toplevel, o_current);
  }

  o_glist_mirror_world( toplevel, centerx, centery, list );

  /* Find connected objects, adding each object in turn back to the
   * connection list. We only _really_ want those objects connected
   * to the selection, not those within in it.
   */
  for (o_iter = list; o_iter != NULL; o_iter = g_list_next (o_iter)) {
    o_current = o_iter->data;

    s_conn_update_object (toplevel, o_current);
  }

  o_invalidate_glist (w_current, list);

  /* Run mirror-objects-hook */
  g_run_hook_object_list ("%mirror-objects-hook", list);

  toplevel->page_current->CHANGED=1;
  o_undo_savestate(w_current, UNDO_ALL);
}
Ejemplo n.º 6
0
/*! \brief Mirror the objects being placed
 *
 *  \par Function Description
 *  This function erases the objects in the place list, mirrors
 *  them, runs %mirror-objects-hook, and redraws the objects after
 *  mirroring.
 *
 *  \param [in] w_current   The GschemToplevel object.
 */
void o_place_mirror (GschemToplevel *w_current)
{
  GschemPageView *page_view = gschem_toplevel_get_current_page_view (w_current);
  g_return_if_fail (page_view != NULL);

  PAGE *page = gschem_page_view_get_page (page_view);
  g_return_if_fail (page != NULL);

  o_place_invalidate_rubber (w_current, FALSE);

  geda_object_list_mirror (page->place_list,
                           w_current->first_wx,
                           w_current->first_wy,
                           page->toplevel);

  /* Run mirror-objects-hook */
  g_run_hook_object_list (w_current, "%mirror-objects-hook", page->place_list);

  o_place_invalidate_rubber (w_current, TRUE);
}
Ejemplo n.º 7
0
/*! \brief Rotate the objects being placed
 *
 *  \par Function Description
 *  This function erases the objects in the place list, rotates
 *  them, runs %rotate-objects-hook, and redraws the objects after
 *  rotating.
 *
 *  \param [in] w_current   The GschemToplevel object.
 */
void o_place_rotate (GschemToplevel *w_current)
{
  GschemPageView *page_view = gschem_toplevel_get_current_page_view (w_current);
  g_return_if_fail (page_view != NULL);

  PAGE *page = gschem_page_view_get_page (page_view);
  g_return_if_fail (page != NULL);

  o_place_invalidate_rubber (w_current, FALSE);

  o_glist_rotate_world (page->toplevel,
                        w_current->first_wx,
                        w_current->first_wy,
                        90,
                        page->place_list);

  /* Run rotate-objects-hook */
  g_run_hook_object_list (w_current, "%rotate-objects-hook", page->place_list);

  o_place_invalidate_rubber (w_current, TRUE);
}
Ejemplo n.º 8
0
/*! \todo Finish function documentation!!!
 *  \brief
 *  \par Function Description
 *
 */
void o_copy_start(GschemToplevel *w_current, int w_x, int w_y)
{
  GList *s_current;

  GschemPageView *page_view = gschem_toplevel_get_current_page_view (w_current);
  g_return_if_fail (page_view != NULL);

  PAGE *page = gschem_page_view_get_page (page_view);
  g_return_if_fail (page != NULL);

  /* Copy the objects into the buffer at their current position,
   * with future motion relative to the mouse origin, (w_x, w_y). */

  w_current->first_wx = w_x;
  w_current->first_wy = w_y;

  if (!o_select_selected (w_current))
    return;

  s_current = geda_list_get_glist (page->selection_list);

  if (page->place_list != NULL) {
    s_delete_object_glist (page->toplevel, page->place_list);
    page->place_list = NULL;
  }

  page->place_list = o_glist_copy_all (page->toplevel,
                                       s_current,
                                       page->place_list);

  g_run_hook_object_list (w_current,
                          "%copy-objects-hook",
                          page->place_list);

  o_place_start (w_current, w_x, w_y);
}
Ejemplo n.º 9
0
/*! \brief End placement action
 *
 *  \par Function Description
 *  This function finishes the current placement action by adding
 *  objects to the current page at the given new world coordinates
 *  and redrawing them on the canvas. It also saves the current
 *  state in the undo list and updates the menus.
 *
 *  If \a continue_placing is TRUE, a copy of the placement list
 *  is saved to start a new place action.
 *
 *  \param [in]  w_current  GschemToplevel which we're drawing for.
 *  \param [in]  w_x        The current world X coordinate.
 *  \param [in]  w_y        The current world Y coordinate.
 *  \param [in]  hook_name  The hook to run after adding the objects.
 */
void o_place_end (GschemToplevel *w_current,
                  int w_x, int w_y,
                  int continue_placing,
                  const char* hook_name)
{
  int w_diff_x, w_diff_y;
  OBJECT *o_current;
  GList *temp_dest_list = NULL;
  GList *connected_objects = NULL;
  GList *iter;

  g_return_if_fail (w_current != NULL);
  g_assert (w_current->inside_action != 0);

  GschemPageView *page_view = gschem_toplevel_get_current_page_view (w_current);
  g_return_if_fail (page_view != NULL);

  PAGE *page = gschem_page_view_get_page (page_view);
  g_return_if_fail (page != NULL);

  /* erase old image */
  /* o_place_invalidate_rubber (w_current, FALSE); */
  w_current->rubber_visible = 0;

  /* Calc final object positions */
  w_current->second_wx = w_x;
  w_current->second_wy = w_y;

  w_diff_x = w_current->second_wx - w_current->first_wx;
  w_diff_y = w_current->second_wy - w_current->first_wy;

  if (continue_placing) {
    /* Make a copy of the place list if we want to keep it afterwards */
    temp_dest_list = o_glist_copy_all (page->toplevel,
                                       page->place_list,
                                       temp_dest_list);
  } else {
    /* Otherwise just take it */
    temp_dest_list = page->place_list;
    page->place_list = NULL;
  }

  geda_object_list_translate (temp_dest_list, w_diff_x, w_diff_y);

  /* Attach each item back onto the page's object list. Update object
   * connectivity and add the new objects to the selection list.*/
  for (iter = temp_dest_list; iter != NULL; iter = g_list_next (iter)) {
    o_current = (OBJECT*) iter->data;

    s_page_append (page->toplevel, page, o_current);

    /* Update object connectivity */
    s_conn_update_object (page, o_current);
    connected_objects = s_conn_return_others (connected_objects, o_current);
  }

  if (hook_name != NULL) {
    g_run_hook_object_list (w_current, hook_name, temp_dest_list);
  }

  o_invalidate_glist (w_current, connected_objects);
  g_list_free (connected_objects);
  connected_objects = NULL;

  gschem_toplevel_page_content_changed (w_current, page);
  o_invalidate_glist (w_current, temp_dest_list); /* only redraw new objects */
  g_list_free (temp_dest_list);

  o_undo_savestate_old (w_current, UNDO_ALL);
  i_update_menus (w_current);

  if (!continue_placing) {
    i_set_state(w_current, SELECT);
    i_action_stop (w_current);
  }
}
Ejemplo n.º 10
0
/*! \brief finish a net drawing action
 * \par Function Description
 * This function finishes the drawing of a net. If we have a visible
 * magnetic marker, we use that instead of the current cursor
 * position.
 *
 * The rubber nets are removed, the nets and cues are drawn and the
 * net is added to the TOPLEVEL structure.
 *
 * The function returns TRUE if it has drawn a net, FALSE otherwise.
 */
void o_net_end(GschemToplevel *w_current, int w_x, int w_y)
{
  int primary_zero_length, secondary_zero_length;
  int found_primary_connection = FALSE;
  int save_wx, save_wy;

  GList *prev_conn_objects;
  OBJECT *new_net = NULL;

  /* Save a list of added objects to run the %add-objects-hook later */
  GList *added_objects = NULL;

  g_assert( w_current->inside_action != 0 );

  GschemPageView *page_view = gschem_toplevel_get_current_page_view (w_current);
  g_return_if_fail (page_view != NULL);

  PAGE *page = gschem_page_view_get_page (page_view);
  g_return_if_fail (page != NULL);

  o_net_invalidate_rubber (w_current);

  if (w_current->magnetic_wx != -1 && w_current->magnetic_wy != -1)
    o_net_finishmagnetic(w_current);

  w_current->rubber_visible = 0;

  /* See if either of the nets are zero length.  We'll only add */
  /* the non-zero ones */
  primary_zero_length = (w_current->first_wx == w_current->second_wx) &&
    (w_current->first_wy == w_current->second_wy);

  secondary_zero_length = (w_current->second_wx == w_current->third_wx) &&
      (w_current->second_wy == w_current->third_wy);

  /* If both nets are zero length... */
  /* this ends the net drawing behavior */
  if ( primary_zero_length && secondary_zero_length ) {
    o_net_reset(w_current);
    return;
  }

  save_wx = w_current->third_wx;
  save_wy = w_current->third_wy;

  if (w_current->third_wx != snap_grid (w_current, w_current->third_wx)
      || w_current->third_wy != snap_grid (w_current, w_current->third_wy))
      s_log_message(_("Warning: Ending net at off grid coordinate\n"));

  if (!primary_zero_length ) {
  /* create primary net */
      new_net = o_net_new(page->toplevel, OBJ_NET, NET_COLOR,
                          w_current->first_wx, w_current->first_wy,
                          w_current->second_wx, w_current->second_wy);
      s_page_append (page->toplevel, page, new_net);

      added_objects = g_list_prepend (added_objects, new_net);

      /* conn stuff */
      /* LEAK CHECK 1 */
      prev_conn_objects = s_conn_return_others (NULL, new_net);
      o_net_add_busrippers (w_current, new_net, prev_conn_objects);
      g_list_free (prev_conn_objects);

#if DEBUG
      printf("primary:\n");
      s_conn_print(new_net->conn_list);
#endif

      /* Go off and search for valid connection on this newly created net */
      found_primary_connection = s_conn_net_search(new_net, 1,
                                                   new_net->conn_list);
      if (found_primary_connection)
      {
      	/* if a net connection is found, reset start point of next net */
	save_wx = w_current->second_wx;
	save_wy = w_current->second_wy;
      }
  }


  /* If the second net is not zero length, add it as well */
  /* Also, a valid net connection from the primary net was not found */
  if (!secondary_zero_length && !found_primary_connection) {

      /* Add secondary net */
      new_net = o_net_new(page->toplevel, OBJ_NET, NET_COLOR,
                          w_current->second_wx, w_current->second_wy,
                          w_current->third_wx, w_current->third_wy);
      s_page_append (page->toplevel, page, new_net);

      added_objects = g_list_prepend (added_objects, new_net);

      /* conn stuff */
      /* LEAK CHECK 2 */
      prev_conn_objects = s_conn_return_others (NULL, new_net);
      o_net_add_busrippers (w_current, new_net, prev_conn_objects);
      g_list_free (prev_conn_objects);
#if DEBUG
      s_conn_print(new_net->conn_list);
#endif
  }

  /* Call add-objects-hook */
  if (added_objects != NULL) {
    g_run_hook_object_list (w_current, "%add-objects-hook", added_objects);
    g_list_free (added_objects);
  }

  w_current->first_wx = save_wx;
  w_current->first_wy = save_wy;

  gschem_toplevel_page_content_changed (w_current, page);
  o_undo_savestate_old(w_current, UNDO_ALL);

  /* Continue net drawing */
  o_net_start(w_current, w_current->first_wx, w_current->first_wy);
}
Ejemplo n.º 11
0
/*! \todo Finish function documentation!!!
 *  \brief
 *  \par Function Description
 *
 */
void o_place_end (GSCHEM_TOPLEVEL *w_current,
                  int w_x, int w_y,
                  int continue_placing,
                  GList **ret_new_objects,
                  const char* hook_name)
{
  TOPLEVEL *toplevel = w_current->toplevel;
  int w_diff_x, w_diff_y;
  OBJECT *o_current;
  PAGE *p_current;
  GList *temp_dest_list = NULL;
  GList *connected_objects = NULL;
  GList *iter;

  /* erase old image */
  /* o_place_invaidate_rubber (w_current, FALSE); */
  w_current->rubber_visible = 0;

  /* Calc final object positions */
  w_current->second_wx = w_x;
  w_current->second_wy = w_y;

  w_diff_x = w_current->second_wx - w_current->first_wx;
  w_diff_y = w_current->second_wy - w_current->first_wy;

  if (continue_placing) {
    /* Make a copy of the place list if we want to keep it afterwards */
    temp_dest_list = o_glist_copy_all (toplevel,
                                       toplevel->page_current->place_list,
                                       temp_dest_list);
  } else {
    /* Otherwise just take it */
    temp_dest_list = toplevel->page_current->place_list;
    toplevel->page_current->place_list = NULL;
  }

  if (ret_new_objects != NULL) {
    *ret_new_objects = g_list_copy (temp_dest_list);
  }

  o_glist_translate_world(toplevel, w_diff_x, w_diff_y, temp_dest_list);

  /* Attach each item back onto the page's object list. Update object
   * connectivity and add the new objects to the selection list.*/
  p_current = toplevel->page_current;

  for (iter = temp_dest_list; iter != NULL; iter = g_list_next (iter)) {
    o_current = iter->data;

    s_page_append (toplevel, p_current, o_current);

    /* Update object connectivity */
    s_conn_update_object (toplevel, o_current);
    connected_objects = s_conn_return_others (connected_objects, o_current);
  }

  if (hook_name != NULL) {
    g_run_hook_object_list (hook_name, temp_dest_list);
  }

  o_invalidate_glist (w_current, connected_objects);
  g_list_free (connected_objects);
  connected_objects = NULL;

  toplevel->page_current->CHANGED = 1;
  o_invalidate_glist (w_current, temp_dest_list); /* only redraw new objects */
  g_list_free (temp_dest_list);

  o_undo_savestate (w_current, UNDO_ALL);
  i_update_menus (w_current);
}
Ejemplo n.º 12
0
/*! \todo Finish function documentation!!!
 *  \brief
 *  \par Function Description
 *
 */
void o_move_end(GschemToplevel *w_current)
{
  GschemPageView *page_view = gschem_toplevel_get_current_page_view (w_current);
  g_return_if_fail (page_view != NULL);

  PAGE *page = gschem_page_view_get_page (page_view);
  g_return_if_fail (page != NULL);

  GList *s_current = NULL;
  OBJECT *object;
  int diff_x, diff_y;
  GList *s_iter;
  GList *rubbernet_objects = NULL;
  gboolean net_rubber_band_mode;

  g_return_if_fail (w_current != NULL);
  g_return_if_fail (page != NULL);

  g_assert (w_current->inside_action != 0);

  object = o_select_return_first_object(w_current);

  if (!object) {
    /* actually this is an error condition hack */
    i_action_stop (w_current);
    i_set_state(w_current, SELECT);
    return;
  }

  diff_x = w_current->second_wx - w_current->first_wx;
  diff_y = w_current->second_wy - w_current->first_wy;

  o_move_invalidate_rubber (w_current, FALSE);
  w_current->rubber_visible = 0;

  net_rubber_band_mode = gschem_options_get_net_rubber_band_mode (w_current->options);

  if (net_rubber_band_mode) {
    o_move_end_rubberband (w_current, diff_x, diff_y, &rubbernet_objects);
  }

  /* Unset the dont_redraw flag on rubberbanded objects.
   * We set this above, in o_move_start(). */
  for (s_iter = w_current->stretch_list;
       s_iter != NULL; s_iter = g_list_next (s_iter)) {
    STRETCH *stretch = s_iter->data;
    stretch->object->dont_redraw = FALSE;
  }

  s_current = geda_list_get_glist( page->selection_list );

  while (s_current != NULL) {

    object = (OBJECT *) s_current->data;

    if (object == NULL) {
      fprintf(stderr, _("ERROR: NULL object in o_move_end!\n"));
      exit(-1);
    }


    switch (object->type) {
      case (OBJ_COMPLEX):
      case (OBJ_PLACEHOLDER):

        /* TODO: Fix so we can just pass the complex to o_move_end_lowlevel,
         * IE.. by falling through the bottom of this case statement. */

        /* this next section of code is from */
        /* o_complex_world_translate_world */
        object->complex->x = object->complex->x + diff_x;
        object->complex->y = object->complex->y + diff_y;

        o_move_end_lowlevel_glist (w_current, object->complex->prim_objs,
                                   diff_x, diff_y);
        object->w_bounds_valid_for = NULL;
        break;

      default:
        o_move_end_lowlevel (w_current, object, diff_x, diff_y);
        break;
    }

    s_current = g_list_next(s_current);
  }

  /* Draw the objects that were moved */
  o_invalidate_glist (w_current, geda_list_get_glist (page->selection_list));

  /* Draw the connected nets/buses that were also changed */
  o_invalidate_glist (w_current, rubbernet_objects);

  /* Call move-objects-hook for moved objects and changed connected
   * nets/buses */
  GList *moved_list = g_list_concat (page->place_list, rubbernet_objects);
  page->place_list = NULL;
  rubbernet_objects = NULL;
  g_run_hook_object_list (w_current, "%move-objects-hook", moved_list);
  g_list_free (moved_list);

  gschem_toplevel_page_content_changed (w_current, page);
  o_undo_savestate_old(w_current, UNDO_ALL);

  s_stretch_destroy_all (w_current->stretch_list);
  w_current->stretch_list = NULL;

  i_set_state(w_current, SELECT);
  i_action_stop (w_current);
}
Ejemplo n.º 13
0
/*! \brief finish a net drawing action 
 * \par Function Description 
 * This function finishes the drawing of a net. If we have a visible
 * magnetic marker, we use that instead of the current cursor
 * position.
 *
 * The rubber nets are removed, the nets and cues are drawn and the
 * net is added to the TOPLEVEL structure.  
 *
 * The function returns TRUE if it has drawn a net, FALSE otherwise.
 */
int o_net_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
{
  TOPLEVEL *toplevel = w_current->toplevel;
  int color;
  int primary_zero_length, secondary_zero_length;
  int found_primary_connection = FALSE;
  int save_wx, save_wy;

  GList *prev_conn_objects;
  OBJECT *new_net = NULL;

  /* Save a list of added objects to run the %add-objects-hook later */
  GList *added_objects = NULL;

  g_assert( w_current->inside_action != 0 );

  o_net_invalidate_rubber (w_current);

  if (w_current->magnetic_wx != -1 && w_current->magnetic_wy != -1)
    o_net_finishmagnetic(w_current);

  w_current->rubber_visible = 0;

  /* See if either of the nets are zero length.  We'll only add */
  /* the non-zero ones */
  primary_zero_length = (w_current->first_wx == w_current->second_wx) &&
    (w_current->first_wy == w_current->second_wy);
 
  secondary_zero_length = (w_current->second_wx == w_current->third_wx) &&
      (w_current->second_wy == w_current->third_wy);

  /* If both nets are zero length... */
  /* this ends the net drawing behavior */
  if ( primary_zero_length && secondary_zero_length ) {
    return FALSE;
  }

  save_wx = w_current->third_wx;
  save_wy = w_current->third_wy;

  if (toplevel->override_net_color == -1) {
    color = NET_COLOR;
  } else {
    color = toplevel->override_net_color;
  }

  if (w_current->third_wx != snap_grid (w_current, w_current->third_wx)
      || w_current->third_wy != snap_grid (w_current, w_current->third_wy))
      s_log_message(_("Warning: Ending net at off grid coordinate\n"));

  if (!primary_zero_length ) {
  /* create primary net */
      new_net = o_net_new(toplevel, OBJ_NET, color,
                          w_current->first_wx, w_current->first_wy,
                          w_current->second_wx, w_current->second_wy);
      s_page_append (toplevel, toplevel->page_current, new_net);

      added_objects = g_list_prepend (added_objects, new_net);

      /* conn stuff */
      /* LEAK CHECK 1 */
      prev_conn_objects = s_conn_return_others (NULL, new_net);
      o_net_add_busrippers (w_current, new_net, prev_conn_objects);
      g_list_free (prev_conn_objects);

#if DEBUG 
      printf("primary:\n"); 
      s_conn_print(new_net->conn_list);
#endif

      /* Go off and search for valid connection on this newly created net */
      found_primary_connection = s_conn_net_search(new_net, 1, 
                                                   new_net->conn_list);
      if (found_primary_connection)
      {
      	/* if a net connection is found, reset start point of next net */
	save_wx = w_current->second_wx;
	save_wy = w_current->second_wy;
      }
  }


  /* If the second net is not zero length, add it as well */
  /* Also, a valid net connection from the primary net was not found */
  if (!secondary_zero_length && !found_primary_connection) {
      
      /* Add secondary net */
      new_net = o_net_new(toplevel, OBJ_NET, color,
                          w_current->second_wx, w_current->second_wy,
                          w_current->third_wx, w_current->third_wy);
      s_page_append (toplevel, toplevel->page_current, new_net);

      added_objects = g_list_prepend (added_objects, new_net);

      /* conn stuff */
      /* LEAK CHECK 2 */
      prev_conn_objects = s_conn_return_others (NULL, new_net);
      o_net_add_busrippers (w_current, new_net, prev_conn_objects);
      g_list_free (prev_conn_objects);
#if DEBUG
      s_conn_print(new_net->conn_list);
#endif
  }

  /* Call add-objects-hook */
  if (added_objects != NULL) {
    g_run_hook_object_list ("%add-objects-hook", added_objects);
    g_list_free (added_objects);
  }

  toplevel->page_current->CHANGED = 1;
  w_current->first_wx = save_wx;
  w_current->first_wy = save_wy;
  o_undo_savestate(w_current, UNDO_ALL);

  return (TRUE);
}
Ejemplo n.º 14
0
/*! \brief Delete objects from the selection.
 *  \par Function Description
 *  This function deletes the objects selected on the current page of
 *  toplevel \a w_current.
 *
 *  \param [in] w_current The GschemToplevel object.
 */
void o_delete_selected (GschemToplevel *w_current)
{
    TOPLEVEL *toplevel = gschem_toplevel_get_toplevel (w_current);
    SELECTION *selection = toplevel->page_current->selection_list;
    GList *to_remove;
    GList *iter;
    OBJECT *obj;
    unsigned int locked_num = 0;

    g_return_if_fail (o_select_selected (w_current));

    to_remove = g_list_copy (geda_list_get_glist (selection));

    for (iter = to_remove; iter != NULL; iter = g_list_next (iter)) {
        obj = (OBJECT *) iter->data;
        if (obj->selectable == FALSE)
            locked_num++;
    }

    if (locked_num > 0) {
        GList *non_locked = NULL;
        gint resp;
        GtkWidget *dialog = gtk_message_dialog_new (NULL,
                            GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
                            GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
                            ngettext ("Delete locked object?", "Delete %u locked objects?",
                                      locked_num), locked_num);
        gtk_dialog_add_buttons (GTK_DIALOG (dialog),
                                GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                GTK_STOCK_YES, GTK_RESPONSE_YES,
                                GTK_STOCK_NO, GTK_RESPONSE_NO, NULL);
        gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_NO);

        resp = gtk_dialog_run (GTK_DIALOG (dialog));
        gtk_widget_destroy (dialog);

        switch (resp) {
        case GTK_RESPONSE_YES:  /* Remove all */
            break;
        case GTK_RESPONSE_NO:   /* Remove non locked */
            for (iter = to_remove; iter != NULL; iter = g_list_next (iter)) {
                obj = (OBJECT *) iter->data;
                if (obj->selectable == TRUE)
                    non_locked = g_list_append (non_locked, iter->data);
            }
            g_list_free (to_remove);
            to_remove = non_locked;
            break;
        default:                /* Cancel */
            g_list_free (to_remove);
            return;
        }
    }

    for (iter = to_remove; iter != NULL; iter = g_list_next (iter)) {
        obj = (OBJECT *) iter->data;
        o_selection_remove (toplevel, selection, obj);
        s_page_remove (toplevel, toplevel->page_current, obj);
    }

    g_run_hook_object_list (w_current, "%remove-objects-hook", to_remove);

    for (iter = to_remove; iter != NULL; iter = g_list_next (iter)) {
        obj = (OBJECT *) iter->data;
        s_delete_object (toplevel, obj);
    }

    g_list_free (to_remove);

    gschem_toplevel_page_content_changed (w_current, toplevel->page_current);
    w_current->inside_action = 0;
    o_undo_savestate_old (w_current, UNDO_ALL);
    i_update_menus (w_current);
}