Beispiel #1
0
/*! \todo Finish function documentation!!!
 *  \brief
 *  \par Function Description
 *
 */
void o_text_prepare_place(GschemToplevel *w_current, char *text, int color, int align, int rotate, int size)
{
  GschemPageView *page_view = gschem_toplevel_get_current_page_view (w_current);
  TOPLEVEL *toplevel = gschem_page_view_get_toplevel (page_view);
  PAGE *page = gschem_page_view_get_page (page_view);

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

  /* Insert the new object into the buffer at world coordinates (0,0).
   * It will be translated to the mouse coordinates during placement. */

  w_current->first_wx = 0;
  w_current->first_wy = 0;

  w_current->last_drawb_mode = LAST_DRAWB_MODE_NONE;

  /* remove the old place list if it exists */
  s_delete_object_glist(toplevel, page->place_list);
  page->place_list = NULL;

  /* here you need to add OBJ_TEXT when it's done */
  page->place_list =
    g_list_append(page->place_list,
                  o_text_new (toplevel, OBJ_TEXT, color,
                              0, 0, align, rotate, /* zero is angle */
                              text,
                              size,
                              /* has to be visible so you can place it */
                              /* visibility is set when you create the object */
                              VISIBLE, SHOW_NAME_VALUE));

  w_current->inside_action = 1;
  i_set_state (w_current, ENDTEXT);
}
Beispiel #2
0
/*! \todo Finish function documentation!!!
 *  \brief
 *  \par Function Description
 *
 */
void o_copy_start(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
{
  TOPLEVEL *toplevel = w_current->toplevel;
  GList *s_current;

  /* 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( toplevel->page_current->selection_list );

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

  toplevel->page_current->place_list =
    o_glist_copy_all (toplevel, s_current,
                      toplevel->page_current->place_list,
                      SELECTION_FLAG);

  w_current->inside_action = 1;
  i_set_state(w_current, COPY);
  o_place_start (w_current, w_x, w_y);
}
Beispiel #3
0
static void
clip_clear (GtkClipboard *cb, gpointer user_data_or_owner)
{
  GSCHEM_TOPLEVEL *w_current = user_data_or_owner;
  TOPLEVEL *toplevel = w_current->toplevel;

  /* Free the objects in the clipboard buffer */
  s_delete_object_glist (toplevel, w_current->clipboard_buffer);
  w_current->clipboard_buffer = NULL;
}
Beispiel #4
0
/*! \brief Remove and free all OBJECTs from the PAGE
 *
 *  \par Function Description
 *  Removes and frees all OBJECTs from the PAGE.
 *
 *  \param [in] toplevel  The TOPLEVEL object.
 *  \param [in] page      The PAGE being cleared.
 */
void s_page_delete_objects (TOPLEVEL *toplevel, PAGE *page)
{
  GList *objects = page->_object_list;
  GList *iter;
  for (iter = objects; iter != NULL; iter = g_list_next (iter)) {
    pre_object_removed (toplevel, page, iter->data);
  }
  page->_object_list = NULL;
  s_delete_object_glist (toplevel, objects);
}
Beispiel #5
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);
}
Beispiel #6
0
/*! \brief Read attributes from a buffer.
 *  \par Function Description
 *  Read attributes from a TextBuffer.
 *
 *  \param [in]  toplevel               The TOPLEVEL object.
 *  \param [in]  object_to_get_attribs  Object which gets these attribs.
 *  \param [in]  tb                     The text buffer to read from.
 *  \param [in]  release_ver            libgeda release version number.
 *  \param [in]  fileformat_ver         file format version number.
 *  \return GList of attributes read, or NULL on error.
 */
GList *o_read_attribs (TOPLEVEL *toplevel,
                       OBJECT *object_to_get_attribs,
                       TextBuffer *tb,
                       unsigned int release_ver, unsigned int fileformat_ver, GError ** err)
{
  GList *object_list = NULL;
  OBJECT *new_obj;
  const char *line = NULL;
  char objtype;
  int ATTACH=FALSE;

  while (1) {

    line = s_textbuffer_next_line (tb);
    if (line == NULL) break;

    sscanf(line, "%c", &objtype);
    switch (objtype) {

      case(OBJ_LINE):
        if ((new_obj = o_line_read (toplevel, line, release_ver, fileformat_ver, err)) == NULL)
          goto error;
        object_list = g_list_prepend (object_list, new_obj);
        break;


      case(OBJ_NET):
        if ((new_obj = o_net_read (toplevel, line, release_ver, fileformat_ver, err)) == NULL)
          goto error;
        object_list = g_list_prepend (object_list, new_obj);
        break;

      case(OBJ_BUS):
        if ((new_obj = o_bus_read (toplevel, line, release_ver, fileformat_ver, err)) == NULL)
          goto error;
        object_list = g_list_prepend (object_list, new_obj);
        break;

      case(OBJ_BOX):
        if ((new_obj = o_box_read (toplevel, line, release_ver, fileformat_ver, err)) == NULL)
          goto error;
        object_list = g_list_prepend (object_list, new_obj);
        break;

      case(OBJ_CIRCLE):
        if ((new_obj = o_circle_read (toplevel, line, release_ver, fileformat_ver, err)) == NULL)
          goto error;
        object_list = g_list_prepend (object_list, new_obj);
        break;

      case(OBJ_COMPLEX):
      case(OBJ_PLACEHOLDER):
        if ((new_obj = o_complex_read (toplevel, line, release_ver, fileformat_ver, err)) == NULL)
          goto error;
        object_list = g_list_prepend (object_list, new_obj);
        break;

      case(OBJ_PATH):
        new_obj = o_path_read (toplevel, line, tb, release_ver, fileformat_ver, err);
        if (new_obj == NULL)
          goto error;
        object_list = g_list_prepend (object_list, new_obj);
        break;

      case(OBJ_PIN):
        if ((new_obj = o_pin_read (toplevel, line, release_ver, fileformat_ver, err)) == NULL)
          goto error;
        object_list = g_list_prepend (object_list, new_obj);
        break;

      case(OBJ_ARC):
        if ((new_obj = o_arc_read (toplevel, line, release_ver, fileformat_ver, err)) == NULL)
          goto error;
        object_list = g_list_prepend (object_list, new_obj);
        break;

      case(OBJ_TEXT):
        new_obj = o_text_read (toplevel, line, tb, release_ver, fileformat_ver, err);
        if (new_obj == NULL)
          goto error;
        object_list = g_list_prepend (object_list, new_obj);
        ATTACH=TRUE;

        break;

      case(ENDATTACH_ATTR):
        return object_list;
        break;
    }

    if (ATTACH) {
      o_attrib_attach (toplevel, new_obj, object_to_get_attribs, FALSE);
      ATTACH=FALSE;
    } else {
      g_set_error(err, EDA_ERROR, EDA_ERROR_PARSE, _("Tried to attach a non-text item as an attribute"));
      goto error;
    }
  }

  /* The attribute list wasn't terminated, so it's a parse error! */
  g_set_error (err, EDA_ERROR, EDA_ERROR_PARSE,
               _("Unexpected end-of-file in attribute list"));

error:
  s_delete_object_glist(toplevel, object_list);
  return NULL;
}
Beispiel #7
0
/*! \todo Finish function documentation!!!
 *  \brief
 *  \par Function Description
 *
 *  
 *  <B>flag</B> can be one of the following values:
 *  <DL>
 *    <DT>*</DT><DD>UNDO_ALL
 *    <DT>*</DT><DD>UNDO_VIEWPORT_ONLY
 *  </DL>
 */
void o_undo_savestate(GSCHEM_TOPLEVEL *w_current, int flag)
{
  TOPLEVEL *toplevel = w_current->toplevel;
  char *filename = NULL;
  GList *object_list = NULL;
  int levels;
  UNDO *u_current;
  UNDO *u_current_next;

  /* save autosave backups if necessary */
  o_autosave_backups(w_current);

  if (w_current->undo_control == FALSE) {
    return;
  }

  if (flag == UNDO_ALL) {

    /* Increment the number of operations since last backup if 
       auto-save is enabled */
    if (toplevel->auto_save_interval != 0) {
      toplevel->page_current->ops_since_last_backup++;
    }

    /* HACK */
    /* Before we save the undo state, consolidate nets as necessary */

    /* This is where the net consolidation call would have been
     * triggered before it was removed from o_save_buffer().
     */
    if (toplevel->net_consolidate == TRUE)
      o_net_consolidate (toplevel, toplevel->page_current);
  }

  if (w_current->undo_type == UNDO_DISK && flag == UNDO_ALL) {

    filename = g_strdup_printf("%s%cgschem.save%d_%d.sch",
                               tmp_path, G_DIR_SEPARATOR,
                               prog_pid, undo_file_index++);

    /* Changed from f_save to o_save when adding backup copy creation. */
    /* f_save manages the creaton of backup copies. 
       This way, f_save is called only when saving a file, and not when
       saving an undo backup copy */
    o_save (toplevel, s_page_objects (toplevel->page_current), filename, NULL);

  } else if (w_current->undo_type == UNDO_MEMORY && flag == UNDO_ALL) {
    object_list = o_glist_copy_all (toplevel,
                                    s_page_objects (toplevel->page_current),
                                    object_list);
  }

  /* Clear Anything above current */
  if (toplevel->page_current->undo_current) {
    s_undo_remove_rest(toplevel,
                       toplevel->page_current->undo_current->next);
    toplevel->page_current->undo_current->next = NULL;
  } else { /* undo current is NULL */
    s_undo_remove_rest(toplevel,
                       toplevel->page_current->undo_bottom);
    toplevel->page_current->undo_bottom = NULL;
  }

  toplevel->page_current->undo_tos = toplevel->page_current->undo_current;

  toplevel->page_current->undo_tos =
  s_undo_add(toplevel->page_current->undo_tos,
             flag, filename, object_list,
             toplevel->page_current->left,
             toplevel->page_current->top,
             toplevel->page_current->right,
             toplevel->page_current->bottom,
             toplevel->page_current->page_control,
             toplevel->page_current->up);

  toplevel->page_current->undo_current =
      toplevel->page_current->undo_tos;

  if (toplevel->page_current->undo_bottom == NULL) {
    toplevel->page_current->undo_bottom =
        toplevel->page_current->undo_tos;
  }

#if DEBUG
  printf("\n\n---Undo----\n");
  s_undo_print_all(toplevel->page_current->undo_bottom);
  printf("BOTTOM: %s\n", toplevel->page_current->undo_bottom->filename);
  printf("TOS: %s\n", toplevel->page_current->undo_tos->filename);
  printf("CURRENT: %s\n", toplevel->page_current->undo_current->filename);
  printf("----\n");
#endif

  g_free(filename);

  /* Now go through and see if we need to free/remove some undo levels */ 
  /* so we stay within the limits */

  /* only check history every 10 undo savestates */
  if (undo_file_index % 10) {
    return;
  }

  levels = s_undo_levels(toplevel->page_current->undo_bottom);

#if DEBUG
  printf("levels: %d\n", levels);
#endif

  if (levels >= w_current->undo_levels + UNDO_PADDING) {
    levels = levels - w_current->undo_levels;

#if DEBUG
    printf("Trimming: %d levels\n", levels);
#endif

    u_current = toplevel->page_current->undo_bottom;
    while(u_current && levels > 0) {
      u_current_next = u_current->next;

      if (u_current->filename) {
#if DEBUG
        printf("Freeing: %s\n", u_current->filename);
#endif
        unlink(u_current->filename);
        g_free(u_current->filename);
      }

      if (u_current->object_list) {
        s_delete_object_glist (toplevel, u_current->object_list);
        u_current->object_list = NULL;
      }

      u_current->next = NULL;
      u_current->prev = NULL;
      g_free(u_current);

      u_current = u_current_next;
      levels--;
    }

    /* Because we use a pad you are always garanteed to never */
    /* exhaust the list */
    u_current->prev = NULL;
    toplevel->page_current->undo_bottom = u_current;

#if DEBUG
    printf("New current is: %s\n", u_current->filename);
#endif
  }

#if DEBUG
  printf("\n\n---Undo----\n");
  s_undo_print_all(toplevel->page_current->undo_bottom);
  printf("BOTTOM: %s\n", toplevel->page_current->undo_bottom->filename);
  printf("TOS: %s\n", toplevel->page_current->undo_tos->filename);
  printf("CURRENT: %s\n", toplevel->page_current->undo_current->filename);
  printf("----\n");
#endif

}
Beispiel #8
0
/*! \brief Remove and free all OBJECTs from the PAGE
 *
 *  \par Function Description
 *  Removes and frees all OBJECTs from the PAGE.
 *
 *  \param [in] toplevel  The TOPLEVEL object.
 *  \param [in] page      The PAGE being cleared.
 */
void s_page_delete_objects (TOPLEVEL *toplevel, PAGE *page)
{
  s_delete_object_glist (toplevel, page->_object_list);
  page->_object_list = NULL;
}
Beispiel #9
0
/*! \brief delete a page and it's contents
 *  \par Function Description
 *  Deletes a single page <B>page</B> from <B>toplevel</B>'s list of pages.
 *
 *  See #s_page_delete_list() to delete all pages of a <B>toplevel</B>
 *
 *  If the current page of toplevel is given as parameter <B>page</B>,
 *  the function sets the field <B>page_current</B> of the TOPLEVEL
 *  struct to NULL.
 */
void s_page_delete (TOPLEVEL *toplevel, PAGE *page)
{
  PAGE *tmp;
  gchar *backup_filename;
  gchar *real_filename;

  /* We need to temporarily make the page being deleted current because
   * various functions called below (some indirectly) assume they are
   * deleting objects from the current page.
   *
   * These functions are known to include:
   *   s_delete_object ()
   */

  /* save page_current and switch to page */
  if (page == toplevel->page_current) {
    tmp = NULL;
  } else {
    tmp = toplevel->page_current;
    s_page_goto (toplevel, page);
  }

  /* Get the real filename and file permissions */
  real_filename = follow_symlinks (page->page_filename, NULL);
  
  if (real_filename == NULL) {
    s_log_message (_("s_page_delete: Can't get the real filename of %s."),
                   page->page_filename);
  }
  else {
    backup_filename = f_get_autosave_filename (real_filename);

    /* Delete the backup file */
    if ( (g_file_test (backup_filename, G_FILE_TEST_EXISTS)) && 
	 (!g_file_test(backup_filename, G_FILE_TEST_IS_DIR)) )
    {
      if (unlink(backup_filename) != 0) {
	s_log_message(_("s_page_delete: Unable to delete backup file %s."),
                      backup_filename);
      }
    }
    g_free (backup_filename);
  }
  g_free(real_filename);

  /* Free the selection object */
  g_object_unref( page->selection_list );

  /* then delete objects of page */
  s_page_delete_objects (toplevel, page);

  /* Free the objects in the place list. */
  s_delete_object_glist (toplevel, page->place_list);
  page->place_list = NULL;

#if DEBUG
  printf("Freeing page: %s\n", page->page_filename);
  s_tile_print(toplevel);
#endif
  s_tile_free_all (page);

  s_stretch_destroy_all (page->stretch_list);

  /* free current page undo structs */
  s_undo_free_all (toplevel, page); 

  /* ouch, deal with parents going away and the children still around */
  page->up = -2;
  g_free (page->page_filename);

  geda_list_remove( toplevel->pages, page );

#if DEBUG
  s_tile_print (toplevel);
#endif

  g_free (page);

  /* restore page_current */
  if (tmp != NULL) {
    s_page_goto (toplevel, tmp);
  } else {
    /* page was page_current */
    toplevel->page_current = NULL;
    /* page_current must be updated by calling function */
  }

}
Beispiel #10
0
/*! \brief delete a page and it's contents
 *  \par Function Description
 *  Deletes a single page <B>page</B> from <B>toplevel</B>'s list of pages.
 *
 *  See #s_page_delete_list() to delete all pages of a <B>toplevel</B>
 *
 *  If the current page of toplevel is given as parameter <B>page</B>,
 *  the function sets the field <B>page_current</B> of the TOPLEVEL
 *  struct to NULL.
 */
void s_page_delete (TOPLEVEL *toplevel, PAGE *page)
{
  PAGE *tmp;
  gchar *backup_filename;
  gchar *real_filename;

  /* We need to temporarily make the page being deleted current because
   * various functions called below (some indirectly) assume they are
   * deleting objects from the current page.
   *
   * These functions are known to include:
   *   s_delete_object ()
   */

  /* save page_current and switch to page */
  if (page == toplevel->page_current) {
    tmp = NULL;
  } else {
    tmp = toplevel->page_current;
    s_page_goto (toplevel, page);
  }

  /* Get the real filename and file permissions */
  real_filename = follow_symlinks (page->page_filename, NULL);
  
  if (real_filename == NULL) {
    s_log_message (_("s_page_delete: Can't get the real filename of %s."),
                   page->page_filename);
  }
  else {
    backup_filename = f_get_autosave_filename (real_filename);

    /* Delete the backup file */
    if ( (g_file_test (backup_filename, G_FILE_TEST_EXISTS)) && 
	 (!g_file_test(backup_filename, G_FILE_TEST_IS_DIR)) )
    {
      if (unlink(backup_filename) != 0) {
	s_log_message(_("s_page_delete: Unable to delete backup file %s."),
                      backup_filename);
      }
    }
    g_free (backup_filename);
  }
  g_free(real_filename);

  /* Free the selection object */
  g_object_unref( page->selection_list );

  /* then delete objects of page */
  s_page_delete_objects (toplevel, page);

  /* Free the objects in the place list. */
  s_delete_object_glist (toplevel, page->place_list);
  page->place_list = NULL;

  /*  This removes all objects from the list of connectible objects
   *  of the given \a page. */
  if (g_list_length (page->connectible_list) != 0) {
    fprintf (stderr,
            "OOPS! page->connectible_list had something in it when it was freed!\n");
    fprintf (stderr, "Length: %d\n", g_list_length (page->connectible_list));
  }

  g_list_free (page->connectible_list);
  page->connectible_list = NULL;

  /* free current page undo structs */
  s_undo_free_all (toplevel, page); 

  /* ouch, deal with parents going away and the children still around */
  page->up = -2;
  g_free (page->page_filename);

  geda_list_remove( toplevel->pages, page );

  s_weakref_notify (page, page->weak_refs);

  g_free (page);

  /* restore page_current */
  if (tmp != NULL) {
    s_page_goto (toplevel, tmp);
  } else {
    /* page was page_current */
    s_toplevel_set_page_current (toplevel, NULL);
    /* page_current must be updated by calling function */
  }

}
Beispiel #11
0
/*! \todo Finish function documentation!!!
 *  \brief
 *  \par Function Description
 *
 */
void
s_delete_object(TOPLEVEL *toplevel, OBJECT *o_current)
{
  if (o_current != NULL) {
    /* If currently attached to a page, remove it from the page */
    if (o_current->page != NULL) {
      s_page_remove (toplevel, o_current->page, o_current);
    }

    s_conn_remove_object (toplevel, o_current);

    if (o_current->attached_to != NULL) {
      /* do the actual remove */
      o_attrib_remove(toplevel, &o_current->attached_to->attribs, o_current);
    }

    if (o_current->line) {
      /*	printf("sdeleting line\n");*/
      g_free(o_current->line);
    }
    o_current->line = NULL;

    if (o_current->path) {
      g_free(o_current->path);
    }
    o_current->path = NULL;

    /*	printf("sdeleting circle\n");*/
    g_free(o_current->circle);
    o_current->circle = NULL;

    /*	printf("sdeleting arc\n");*/
    g_free(o_current->arc);
    o_current->arc = NULL;

    /*	printf("sdeleting box\n");*/
    g_free(o_current->box);
    o_current->box = NULL;

    if (o_current->picture) {
      /*	printf("sdeleting picture\n");*/

      g_free(o_current->picture->file_content);
      if (o_current->picture->pixbuf)
        g_object_unref (o_current->picture->pixbuf);

      g_free(o_current->picture->filename);
      g_free(o_current->picture);
    }
    o_current->picture = NULL;

    if (o_current->text) {
      /*printf("sdeleting text->string\n");*/
      g_free(o_current->text->string); 
      o_current->text->string = NULL;
      g_free(o_current->text->disp_string);
      /*	printf("sdeleting text\n");*/
      g_free(o_current->text);
    }
    o_current->text = NULL;

    /*	printf("sdeleting name\n");*/
    g_free(o_current->name);
    o_current->name = NULL;


    /*	printf("sdeleting complex_basename\n");*/
    g_free(o_current->complex_basename); 
    o_current->complex_basename = NULL;

    if (o_current->complex) {

      if (o_current->complex->prim_objs) {
        /* printf("sdeleting complex->primitive_objects\n");*/
        s_delete_object_glist (toplevel, o_current->complex->prim_objs);
        o_current->complex->prim_objs = NULL;
      }

      g_free(o_current->complex);
      o_current->complex = NULL;
    }

    o_attrib_detach_all (toplevel, o_current);

    s_weakref_notify (o_current, o_current->weak_refs);

    g_free(o_current);	/* assuming it is not null */

    o_current=NULL;		/* misc clean up */
  }
}