コード例 #1
0
ファイル: s_object.c プロジェクト: rlutz/geda-gaf
/*! \brief Delete text object
 *
 * Delete the text object pointed to by text_object.  This function
 * was shamelessly stolen from gschem/src/o_delete.c and hacked
 * for gattrib by SDB.
 * \param toplevel TOPLEVEL to be operated on
 * \param test_object text object to be deleted
 */
void
s_object_delete_text_object_in_object (TOPLEVEL *toplevel,
                                       OBJECT * text_object)
{
  s_page_remove (toplevel, toplevel->page_current, text_object);
  s_delete_object (toplevel, text_object);
  toplevel->page_current->CHANGED = 1;
}
コード例 #2
0
/*! \brief Free a gEDA smob.
 * \par Function Description
 * Finalizes a gEDA smob for deletion, removing the weak reference.
 *
 * Used internally to Guile.
 */
static size_t
smob_free (SCM smob)
{
  void *data;

  /* If the weak reference has already been cleared, do nothing */
  if (!EDASCM_SMOB_VALIDP(smob)) return 0;

  data = (void *) SCM_SMOB_DATA (smob);

  /* Otherwise, clear the weak reference */
  switch (EDASCM_SMOB_TYPE (smob)) {
  case GEDA_SMOB_TOPLEVEL:
    s_toplevel_weak_unref ((TOPLEVEL *) data, smob_weakref_notify, smob);
    break;
  case GEDA_SMOB_PAGE:
    s_page_weak_unref ((PAGE *) data, smob_weakref_notify, smob);
    break;
  case GEDA_SMOB_OBJECT:
    /* See edascm_from_object() for an explanation of why OBJECT
     * smobs store a TOPLEVEL in the second data word */
    s_object_weak_unref ((OBJECT *) data, smob_weakref_notify, smob);
    s_toplevel_weak_unref ((TOPLEVEL *) SCM_SMOB_DATA_2 (smob),
                           smob_weakref2_notify, smob);
    break;
  default:
    /* This should REALLY definitely never be run */
    g_critical ("%s: received bad smob flags.", __FUNCTION__);
  }

  /* If the smob is marked as garbage-collectable, destroy its
   * contents.
   *
   * Because PAGEs and TOPLEVELs should never be garbage collected,
   * emit critical warnings if the GC tries to free them.
   */
  if (EDASCM_SMOB_GCP (smob)) {
    switch (EDASCM_SMOB_TYPE (smob)) {
    case GEDA_SMOB_TOPLEVEL:
      g_critical ("%s: Blocked garbage-collection of TOPLEVEL %p",
                 __FUNCTION__, data);
      break;
    case GEDA_SMOB_PAGE:
      g_critical ("%s: Blocked garbage-collection of PAGE %p",
                 __FUNCTION__, data);
      break;
    case GEDA_SMOB_OBJECT:
      /* See edascm_from_object() for an explanation of why OBJECT
       * smobs store a TOPLEVEL in the second data word */
      s_delete_object ((TOPLEVEL *) SCM_SMOB_DATA_2 (smob), (OBJECT *) data);
      break;
    default:
      /* This should REALLY definitely never be run */
      g_critical ("%s: received bad smob flags.", __FUNCTION__);
    }
  }
  return 0;
}
コード例 #3
0
ファイル: o_delete.c プロジェクト: blueantst/geda-gaf
/*! \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);
}
コード例 #4
0
ファイル: s_basic.c プロジェクト: blueantst/geda-gaf
/* deletes everything include the GList */
void
s_delete_object_glist(TOPLEVEL *toplevel, GList *list)
{
  OBJECT *o_current=NULL;
  GList *ptr;

  ptr = g_list_last(list);

  /* do the delete backwards */
  while(ptr != NULL) {
    o_current = (OBJECT *) ptr->data;
    s_delete_object(toplevel, o_current);
    ptr = g_list_previous (ptr);
  }
  g_list_free(list);
}
コード例 #5
0
/*! \brief Delete or hide promotable from the passed OBJECT
 *
 *  \par Function Description
 *  Deletes or hides promotable attributes from the passed OBJECT.
 *  This is used when loading symbols during the load of a schematic from
 *  disk. The schematic will already contain local copies of symbol's
 *  promotable objects, so we delete or hide the symbol's copies.
 *
 *  Deletion / hiding is dependant on the setting of
 *  toplevel->keep_invisible. If true, attributes eligible for
 *  promotion are kept in memory but flagged as invisible.
 *
 *  \param [in]  toplevel The toplevel environment.
 *  \param [in]  object   The complex object being altered.
 */
static void o_complex_remove_promotable_attribs (TOPLEVEL *toplevel, OBJECT *object)
{
  GList *promotable, *iter;

  promotable = o_complex_get_promotable (toplevel, object, FALSE);

  if (promotable == NULL)
    return;

  for (iter = promotable; iter != NULL; iter = g_list_next (iter)) {
    OBJECT *a_object = iter->data;
    if (toplevel->keep_invisible == TRUE) {   /* Hide promotable attributes */
      o_set_visibility (toplevel, a_object, INVISIBLE);
    } else {                                /* Delete promotable attributes */
      object->complex->prim_objs =
        g_list_remove (object->complex->prim_objs, a_object);
      s_delete_object (toplevel, a_object);
    }
  }

  o_bounds_invalidate (toplevel, object);
  g_list_free (promotable);
}
コード例 #6
0
ファイル: o_net_basic.c プロジェクト: fvila/geda-gaf
/*! \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);
}
コード例 #7
0
ファイル: o_misc.c プロジェクト: jaredcasper/geda-gaf
/*! \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;
}
コード例 #8
0
ファイル: scheme_smob.c プロジェクト: gareth8118/geda-gaf
/*! \brief Free a gEDA smob.
 * \par Function Description
 * Finalizes a gEDA smob for deletion, removing the weak reference.
 *
 * Used internally to Guile.
 */
static size_t
smob_free (SCM smob)
{
  void *data;

  /* If the weak reference has already been cleared, do nothing */
  if (!EDASCM_SMOB_VALIDP(smob)) return 0;

  data = (void *) SCM_SMOB_DATA (smob);

  /* If the smob is being finalized, it must not be in the cache! */
  g_warn_if_fail (!smob_cache_contains (data));

  /* Otherwise, clear the weak reference */
  switch (EDASCM_SMOB_TYPE (smob)) {
  case GEDA_SMOB_TOPLEVEL:
    s_toplevel_weak_unref ((TOPLEVEL *) data, smob_weakref_notify,
                           unpack_as_pointer (smob));
    break;
  case GEDA_SMOB_PAGE:
    s_page_weak_unref ((PAGE *) data, smob_weakref_notify,
                       unpack_as_pointer (smob));
    break;
  case GEDA_SMOB_OBJECT:
    /* See edascm_from_object() for an explanation of why OBJECT
     * smobs store a TOPLEVEL in the second data word */
    s_object_weak_unref ((OBJECT *) data, smob_weakref2_notify,
                         unpack_as_pointer (smob));
    break;
  case GEDA_SMOB_CONFIG:
    g_object_unref (G_OBJECT (data));
    break;
  case GEDA_SMOB_CLOSURE:
    break;
  default:
    /* This should REALLY definitely never be run */
    g_critical ("%s: received bad smob flags.", __FUNCTION__);
  }

  /* If the smob is marked as garbage-collectable, destroy its
   * contents.
   *
   * Because PAGEs and TOPLEVELs should never be garbage collected,
   * emit critical warnings if the GC tries to free them.
   */
  if (EDASCM_SMOB_GCP (smob)) {
    switch (EDASCM_SMOB_TYPE (smob)) {
    case GEDA_SMOB_TOPLEVEL:
      g_critical ("%s: Blocked garbage-collection of TOPLEVEL %p",
                 __FUNCTION__, data);
      break;
    case GEDA_SMOB_PAGE:
      g_critical ("%s: Blocked garbage-collection of PAGE %p",
                 __FUNCTION__, data);
      break;
    case GEDA_SMOB_OBJECT:
      /* See edascm_from_object() for an explanation of why OBJECT
       * smobs store a TOPLEVEL in the second data word */
      s_delete_object ((TOPLEVEL *) SCM_SMOB_DATA_2 (smob), (OBJECT *) data);
      break;
    case GEDA_SMOB_CONFIG:
      /* These are reference counted, so the structure will have
       * already been destroyed above if appropriate. */
      break;
    case GEDA_SMOB_CLOSURE:
      break;
    default:
      /* This should REALLY definitely never be run */
      g_critical ("%s: received bad smob flags.", __FUNCTION__);
    }
  }
  return 0;
}
コード例 #9
0
ファイル: o_net_basic.c プロジェクト: jgriessen/geda-gaf
/*! \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);
}
コード例 #10
0
ファイル: o_delete.c プロジェクト: blueantst/geda-gaf
/*! \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);
}