Ejemplo n.º 1
0
/*! \brief Delete an object.
 *  \par Function Description
 *  This function erases the object \a object before deleting it. It
 *  deals with connection and object connected to it.
 *
 *  \param [in] w_current The GschemToplevel object.
 *  \param [in] object    The object to delete.
 */
void o_delete (GschemToplevel *w_current, OBJECT *object)
{
    TOPLEVEL *toplevel = gschem_toplevel_get_toplevel (w_current);

    g_return_if_fail (object != NULL);

    o_selection_remove (toplevel, toplevel->page_current->selection_list, object);
    s_page_remove (toplevel, toplevel->page_current, object);
    g_run_hook_object (w_current, "%remove-objects-hook", object);
    s_delete_object (toplevel, object);

    gschem_toplevel_page_content_changed (w_current, toplevel->page_current);
}
Ejemplo n.º 2
0
/*! \brief Remove invisible attributes of an object from the selection list.
 *  \par Function Description
 *
 *  Remove all invisible attributes attached to the given object
 *  from the selection list. If hidden text is being shown, this
 *  function returns immediately.
 *
 *  \param [in]     w_current  The GschemToplevel object.
 *  \param [in,out] selection  The SELECTION list to remove from.
 *  \param [in]     object     The OBJECT whose invisible attributes to remove.
 */
void o_attrib_deselect_invisible (GschemToplevel *w_current,
                                  SELECTION *selection,
                                  OBJECT *selected)
{
  OBJECT *a_current;
  GList *a_iter;

  g_assert( selection != NULL );

  if (w_current->toplevel->show_hidden_text) {
    return;
  }

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

    if (a_current->selected && !o_is_visible(a_current)) {
      o_selection_remove (w_current->toplevel, selection, a_current);
    }
  }
}
Ejemplo n.º 3
0
/*! \brief try to consolidate a net object
 *  \par Function Description
 *  This function tries to consolidate a net with any other object
 *  that is connected to the current \a object.
 *  
 *  \param toplevel   The TOPLEVEL object
 *  \param object     The object to consolidate
 *  \return 0 if no consolidation was possible, -1 otherwise
 *
 */
static int o_net_consolidate_segments (TOPLEVEL *toplevel, OBJECT *object)
{
  int object_orient;
  int other_orient;
  GList *c_current;
  CONN *conn;
  OBJECT *other_object;
  PAGE *page;
  int changed = 0;

  g_return_val_if_fail ((toplevel != NULL), 0);
  g_return_val_if_fail ((object != NULL), 0);
  g_return_val_if_fail ((object->type == OBJ_NET), 0);

  /* It's meaningless to do anything here if the object isn't in a page. */
  page = o_get_page (toplevel, object);
  g_return_val_if_fail ((page != NULL), 0);

  object_orient = o_net_orientation(object);

  c_current = object->conn_list;
  while(c_current != NULL) {
    conn = (CONN *) c_current->data;
    other_object = conn->other_object;

    /* only look at end points which have a valid end on the other side */
    if (other_object != NULL && conn->type == CONN_ENDPOINT &&
        conn->other_whichone != -1 && conn->whichone != -1 &&
        o_net_consolidate_nomidpoint(object, conn->x, conn->y) ) {

      if (other_object->type == OBJ_NET) {
        other_orient = o_net_orientation(other_object);

        /* - both objects have the same orientation (either vert or horiz) */
        /* - it's not the same object */
        if (object_orient == other_orient &&
            object->sid != other_object->sid &&
            other_orient != NEITHER) {

#if DEBUG
          printf("consolidating %s to %s\n", object->name, other_object->name);
#endif

          o_net_consolidate_lowlevel(object, other_object, other_orient);

          changed++;
          if (other_object->selected == TRUE ) {
            o_selection_remove (toplevel, page->selection_list, other_object);

            /* If we're consolidating with a selected object,
             * ensure we select the resulting object.
             */
            if (object->selected == FALSE) {
              o_selection_add (toplevel, page->selection_list, object);
            }
          }

          s_delete_object (toplevel, other_object);
          o_net_recalc(toplevel, object);
          s_tile_update_object(toplevel, object);
          s_conn_update_object (toplevel, object);
          return(-1);
        }
      }
      
    }

    c_current = g_list_next (c_current);
  }

  return(0);
}
Ejemplo n.º 4
0
/*! \brief Update a component.
 *
 * \par Function Description
 * Updates \a o_current to the latest version of the symbol available
 * in the symbol library, while preserving any attributes set in the
 * current schematic. On success, returns the new OBJECT which
 * replaces \a o_current on the page; \a o_current is deleted. On
 * failure, returns NULL, and \a o_current is left unchanged.
 *
 * \param [in]     w_current The GSCHEM_TOPLEVEL object.
 * \param [in,out] o_current The OBJECT to be updated.
 *
 * \return the new OBJECT that replaces \a o_current.
 */
OBJECT *
o_update_component (GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
{
  TOPLEVEL *toplevel = w_current->toplevel;
  OBJECT *o_new;
  PAGE *page;
  GList *new_attribs;
  GList *old_attribs;
  GList *iter;
  const CLibSymbol *clib;

  g_return_val_if_fail (o_current != NULL, NULL);
  g_return_val_if_fail (o_current->type == OBJ_COMPLEX, NULL);
  g_return_val_if_fail (o_current->complex_basename != NULL, NULL);

  page = o_get_page (toplevel, o_current);

  /* This should be replaced with API to invalidate only the specific
   * symbol name we want to update */
  s_clib_flush_symbol_cache ();
  clib = s_clib_get_symbol_by_name (o_current->complex_basename);

  if (clib == NULL) {
    s_log_message (_("Could not find symbol [%s] in library. Update failed.\n"),
                   o_current->complex_basename);
    return NULL;
  }

  /* Unselect the old object. */
  o_selection_remove (toplevel, page->selection_list, o_current);

  /* Create new object and set embedded */
  o_new = o_complex_new (toplevel, OBJ_COMPLEX, DEFAULT_COLOR,
                         o_current->complex->x,
                         o_current->complex->y,
                         o_current->complex->angle,
                         o_current->complex->mirror,
                         clib, o_current->complex_basename,
                         1);
  if (o_complex_is_embedded (o_current)) {
    o_embed (toplevel, o_new);
  }

  new_attribs = o_complex_promote_attribs (toplevel, o_new);

  /* Cull any attributes from new COMPLEX that are already attached to
   * old COMPLEX. Note that the new_attribs list is kept consistent by
   * setting GList data pointers to NULL if their OBJECTs are
   * culled. At the end, the new_attribs list is updated by removing
   * all list items with NULL data. This is slightly magic, but
   * works. */
  for (iter = new_attribs; iter != NULL; iter = g_list_next (iter)) {
    OBJECT *attr_new = iter->data;
    gchar *name;
    gchar *value;

    g_assert (attr_new->type == OBJ_TEXT);

    o_attrib_get_name_value (attr_new, &name, NULL);

    value = o_attrib_search_attached_attribs_by_name (o_current, name, 0);
    if (value != NULL) {
      o_attrib_remove (toplevel, &o_new->attribs, attr_new);
      s_delete_object (toplevel, attr_new);
      iter->data = NULL;
    }

    g_free (name);
    g_free (value);
  }
  new_attribs = g_list_remove_all (new_attribs, NULL);

  /* Detach attributes from old OBJECT and attach to new OBJECT */
  old_attribs = g_list_copy (o_current->attribs);
  o_attrib_detach_all (toplevel, o_current);
  o_attrib_attach_list (toplevel, old_attribs, o_new, 1);
  g_list_free (old_attribs);

  /* Add new attributes to page */
  s_page_append_list (toplevel, page, new_attribs);

  /* Update pinnumbers for current slot */
  s_slot_update_object (toplevel, o_new);

  /* Replace old OBJECT with new OBJECT */
  s_page_replace (toplevel, page, o_current, o_new);
  s_delete_object (toplevel, o_current);

  /* Select new OBJECT */
  o_selection_add (toplevel, page->selection_list, o_new);

  /* mark the page as modified */
  toplevel->page_current->CHANGED = 1;
  o_undo_savestate (w_current, UNDO_ALL);

  return o_new;
}
Ejemplo n.º 5
0
/*! \brief try to consolidate a net object
 *  \par Function Description
 *  This function tries to consolidate a net with any other object
 *  that is connected to the current \a object.
 *  
 *  \param toplevel   The TOPLEVEL object
 *  \param object     The object to consolidate
 *  \return 0 if no consolidation was possible, -1 otherwise
 *
 */
int o_net_consolidate_segments(TOPLEVEL *toplevel, OBJECT *object)
{
  int object_orient;
  int other_orient;
  GList *c_current;
  CONN *conn;
  OBJECT *other_object;
  int changed = 0;
  int reselect_new=FALSE;

  if (object == NULL) {
    return(0);
  }

  if (object->type != OBJ_NET) {
    return(0);
  }

  object_orient = o_net_orientation(object);

  c_current = object->conn_list;
  while(c_current != NULL) {
    conn = (CONN *) c_current->data;
    other_object = conn->other_object;

    /* only look at end points which have a valid end on the other side */
    if (other_object != NULL && conn->type == CONN_ENDPOINT &&
        conn->other_whichone != -1 && conn->whichone != -1 &&
        o_net_consolidate_nomidpoint(object, conn->x, conn->y) ) {

      if (other_object->type == OBJ_NET) {
        other_orient = o_net_orientation(other_object);

        /* - both objects have the same orientation (either vert or horiz) */
        /* - it's not the same object */
        if (object_orient == other_orient &&
            object->sid != other_object->sid &&
            other_orient != NEITHER) {

#if DEBUG
          printf("consolidating %s to %s\n", object->name, other_object->name);
#endif

          o_net_consolidate_lowlevel(object, other_object, other_orient);

          changed++;
          if (other_object->selected == TRUE ) {
            o_selection_remove( toplevel->page_current->selection_list, other_object );
            reselect_new=TRUE;
          }

          if (reselect_new == TRUE) {
            o_selection_remove( toplevel->page_current->selection_list, object );
            o_selection_add( toplevel->page_current->selection_list, object );
          }

          s_conn_remove_object (toplevel, other_object);
          s_page_remove (toplevel->page_current, other_object);
          s_delete_object (toplevel, other_object);
          o_net_recalc(toplevel, object);
          s_tile_update_object(toplevel, object);
          s_conn_update_object (toplevel, object);
          return(-1);
        }
      }
      
    }

    c_current = g_list_next (c_current);
  }

  return(0);
}
Ejemplo n.º 6
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);
}