Beispiel #1
0
/*! \brief Create a copy of a COMPLEX object
 *  \par Function Description
 *  This function creates a copy of the complex object \a o_current.
 *
 *  \param [in] toplevel     The TOPLEVEL object
 *  \param [in] o_current    The object that is copied
 *  \return a new COMPLEX object
 */
OBJECT *o_complex_copy(TOPLEVEL *toplevel, OBJECT *o_current)
{
  OBJECT *o_new;
  GList *iter;

  g_return_val_if_fail(o_current != NULL, NULL);

  o_new = s_basic_new_object(o_current->type, "complex");
  o_new->color = o_current->color;
  o_new->selectable = o_current->selectable;
  o_new->complex_basename = g_strdup(o_current->complex_basename);
  o_new->complex_embedded = o_current->complex_embedded;

  o_new->complex = g_malloc0(sizeof(COMPLEX));
  o_new->complex->x = o_current->complex->x;
  o_new->complex->y = o_current->complex->y;
  o_new->complex->angle = o_current->complex->angle;
  o_new->complex->mirror = o_current->complex->mirror;

  /* Copy contents and set the parent pointers on the copied objects. */
  o_new->complex->prim_objs =
    o_glist_copy_all (toplevel, o_current->complex->prim_objs,
                      NULL);

  for (iter = o_new->complex->prim_objs;
       iter != NULL;
       iter = g_list_next (iter)) {
    ((OBJECT*) iter->data)->parent = o_new;
  }

  /* Recalculate bounds */
  o_complex_recalc(toplevel, o_new);

  /* Delete or hide attributes eligible for promotion inside the complex */
  o_complex_remove_promotable_attribs (toplevel, o_new);

  s_slot_update_object (toplevel, o_new);

  /* deal with stuff that has changed */

  /* here you need to create a list of attributes which need to be
   * connected to the new list, probably make an attribute list and
   * fill it with sid's of the attributes */

  return o_new;
}
Beispiel #2
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;
}
Beispiel #3
0
/*! \todo Finish function documentation!!!
 *  \brief
 *  \par Function Description
 *
 */
void o_slot_end(GSCHEM_TOPLEVEL *w_current, OBJECT *object, const char *string)
{
  TOPLEVEL *toplevel = w_current->toplevel;
  OBJECT *new_obj;
  char *slot_value;
  char *numslots_value;
  OBJECT *o_slot;
  char *value = NULL;
  int numslots;
  int new_slot_number;
  int status;

  g_return_if_fail (object != NULL);

  status = o_attrib_string_get_name_value (string, NULL, &value);
  if (!status) {
    s_log_message (_("Slot attribute malformed\n"));
    return;
  }

  numslots_value =
    o_attrib_search_object_attribs_by_name (object, "numslots", 0);

  if (!numslots_value) {
    s_log_message (_("numslots attribute missing\n"));
    s_log_message (_("Slotting not allowed for this component\n"));
    g_free (value);
    return;
  }

  numslots = atoi (numslots_value);
  g_free (numslots_value);

  new_slot_number = atoi (value);

#if DEBUG
  printf ("numslots = %d\n", numslots);
#endif

  if (new_slot_number > numslots || new_slot_number <=0 ) {
    s_log_message (_("New slot number out of range\n"));
    g_free (value);
    return;
  }

  /* first see if slot attribute already exists outside
   * complex */
  slot_value = s_slot_search_slot (object, &o_slot);
  g_free (slot_value);

  if (o_slot != NULL && !o_attrib_is_inherited (o_slot)) {
    o_text_set_string (toplevel, o_slot, string);
  } else {
    /* here you need to do the add the slot
       attribute since it doesn't exist */
    new_obj = o_text_new (toplevel, OBJ_TEXT, ATTRIBUTE_COLOR,
                          object->complex->x, object->complex->y,
                          LOWER_LEFT, 0, /* zero is angle */
                          string, 10, INVISIBLE, SHOW_NAME_VALUE);
    s_page_append (toplevel, toplevel->page_current, new_obj);

    /* manually attach attribute */
    o_attrib_attach (toplevel, new_obj, object, FALSE);
  }

  s_slot_update_object (toplevel, object);

  toplevel->page_current->CHANGED = 1;
  g_free (value);
}