Exemple #1
0
/*! \brief Temporary function to notify of page content change
 *
 *  This function is temporary until library functions can emit signals.
 *
 *  \param [in] w_current The current gschem toplevel.
 *  \param [in] page      The page that underwent changes.
 */
void
gschem_toplevel_page_content_changed (GschemToplevel *w_current, PAGE *page)
{
  g_return_if_fail (page != NULL);
  g_return_if_fail (w_current != NULL);

  page->CHANGED = 1;

  x_pagesel_update (w_current);
}
Exemple #2
0
/*! \brief Changes the current page.
 *  \par Function Description
 *  This function displays the specified page <B>page</B> in the
 *  window attached to <B>toplevel</B>.
 *
 *  It changes the <B>toplevel</B>'s current page to <B>page</B>,
 *  draws it and updates the user interface.
 *
 *  <B>page</B> has to be in the list of PAGEs attached to <B>toplevel</B>.
 *
 *  \param [in] w_current The toplevel environment.
 *  \param [in] page      The page to become current page.
 */
void
x_window_set_current_page (GschemToplevel *w_current, PAGE *page)
{
  GschemPageView *page_view = gschem_toplevel_get_current_page_view (w_current);

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

  o_redraw_cleanstates (w_current);

  gschem_page_view_set_page (page_view, page);

  i_update_menus (w_current);
  i_set_filename (w_current, page->page_filename);

  x_pagesel_update (w_current);
  x_multiattrib_update (w_current);

  gschem_page_view_update_scroll_adjustments (page_view);
  gschem_page_view_invalidate_all (page_view);
}
Exemple #3
0
/*! \brief Changes the current page.
 *  \par Function Description
 *  This function displays the specified page <B>page</B> in the
 *  window attached to <B>toplevel</B>.
 *
 *  It changes the <B>toplevel</B>'s current page to <B>page</B>,
 *  draws it and updates the user interface.
 *
 *  <B>page</B> has to be in the list of PAGEs attached to <B>toplevel</B>.
 *
 *  \param [in] w_current The toplevel environment.
 *  \param [in] page      The page to become current page.
 */
void
x_window_set_current_page (GSCHEM_TOPLEVEL *w_current, PAGE *page)
{
  TOPLEVEL *toplevel = w_current->toplevel;

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

  o_redraw_cleanstates (w_current);

  s_page_goto (toplevel, page);

  i_update_menus (w_current);
  i_set_filename (w_current, page->page_filename);

  x_pagesel_update (w_current);
  x_multiattrib_update (w_current);

  x_manual_resize (w_current);
  x_hscrollbar_update (w_current);
  x_vscrollbar_update (w_current);

  o_invalidate_all (w_current);
}
Exemple #4
0
/*! \brief Saves a page to a file.
 *  \par Function Description
 *  This function saves the page <B>page</B> to a file named
 *  <B>filename</B>.
 *
 *  It returns the value returned by function <B>f_save()</B> trying
 *  to save page <B>page</B> to file <B>filename</B> (1 on success, 0
 *  on failure).
 *
 *  <B>page</B> may not be the current page of <B>toplevel</B>. The
 *  current page of <B>toplevel</B> is not affected by this function.
 *
 *  \param [in] w_current The toplevel environment.
 *  \param [in] page      The page to save.
 *  \param [in] filename  The name of the file in which to save page.
 *  \returns 1 on success, 0 otherwise.
 */
gint
x_window_save_page (GschemToplevel *w_current, PAGE *page, const gchar *filename)
{
  TOPLEVEL *toplevel = gschem_toplevel_get_toplevel (w_current);
  const gchar *log_msg, *state_msg;
  gint ret;
  GError *err = NULL;

  g_return_val_if_fail (toplevel != NULL, 0);
  g_return_val_if_fail (page     != NULL, 0);
  g_return_val_if_fail (filename != NULL, 0);

  /* try saving page to filename */
  ret = (gint)f_save (toplevel, page, filename, &err);

  if (ret != 1) {
    log_msg   = _("Could NOT save page [%s]\n");
    state_msg = _("Error while trying to save");

    GtkWidget *dialog;

    dialog = gtk_message_dialog_new (GTK_WINDOW (w_current->main_window),
                                     GTK_DIALOG_DESTROY_WITH_PARENT,
                                     GTK_MESSAGE_ERROR,
                                     GTK_BUTTONS_CLOSE,
                                     "%s",
                                     err->message);
    gtk_window_set_title (GTK_WINDOW (dialog), _("Failed to save file"));
    gtk_dialog_run (GTK_DIALOG (dialog));
    gtk_widget_destroy (dialog);
    g_clear_error (&err);
  } else {
    /* successful save of page to file, update page... */
    /* change page name if necessary and prepare log message */
    if (g_ascii_strcasecmp (page->page_filename, filename) != 0) {
      g_free (page->page_filename);
      page->page_filename = g_strdup (filename);

      log_msg = _("Saved as [%s]\n");
    } else {
      log_msg = _("Saved [%s]\n");
    }
    state_msg = _("Saved");

    /* reset page CHANGED flag */
    page->CHANGED = 0;

    /* add to recent file list */
    gtk_recent_manager_add_item (recent_manager, g_filename_to_uri(filename, NULL, NULL));

    i_set_filename (w_current, page->page_filename);
    x_pagesel_update (w_current);
  }

  /* log status of operation */
  s_log_message (log_msg, filename);

  i_set_state_msg  (w_current, SELECT, state_msg);

  return ret;
}
Exemple #5
0
/*! \brief Opens a new page from a file.
 *  \par Function Description
 *  This function opens the file whose name is <B>filename</B> in a
 *  new PAGE of <B>toplevel</B>.
 *
 *  If there is no page for <B>filename</B> in <B>toplevel</B>'s list
 *  of pages, it creates a new PAGE, loads the file in it and returns
 *  a pointer on the new page. Otherwise it returns a pointer on the
 *  existing page.
 *
 *  If the filename passed is NULL, this function creates an empty,
 *  untitled page.  The name of the untitled page is build from
 *  configuration data ('untitled-name') and a counter for uniqueness.
 *
 *  The opened page becomes the current page of <B>toplevel</B>.
 *
 *  \param [in] w_current The toplevel environment.
 *  \param [in] filename The name of the file to open or NULL for a blank page.
 *  \returns A pointer on the new page.
 *
 *  \bug This code should check to make sure any untitled filename
 *  does not conflict with a file on disk.
 */
PAGE*
x_window_open_page (GschemToplevel *w_current, const gchar *filename)
{
  TOPLEVEL *toplevel = gschem_toplevel_get_toplevel (w_current);
  GschemPageView *page_view = gschem_toplevel_get_current_page_view (w_current);
  PAGE *page;
  gchar *fn;

  g_return_val_if_fail (toplevel != NULL, NULL);

  /* Generate untitled filename if none was specified */
  if (filename == NULL) {
    gchar *cwd, *tmp, *untitled_name;
    EdaConfig *cfg;
    cwd = g_get_current_dir ();
    cfg = eda_config_get_context_for_path (cwd);
    untitled_name = eda_config_get_string (cfg, "gschem", "default-filename", NULL);
    tmp = g_strdup_printf ("%s_%d.sch",
                           untitled_name,
                           ++w_current->num_untitled);
    fn = g_build_filename (cwd, tmp, NULL);
    g_free (untitled_name);
    g_free(cwd);
    g_free(tmp);
  } else {
    fn = g_strdup (filename);
  }

  /* Return existing page if it is already loaded */
  page = s_page_search (toplevel, fn);
  if ( page != NULL ) {
    g_free(fn);
    return page;
  }

  page = s_page_new (toplevel, fn);
  s_page_goto (toplevel, page);
  gschem_toplevel_page_changed (w_current);

  /* Load from file if necessary, otherwise just print a message */
  if (filename != NULL) {
    GError *err = NULL;
    if (!quiet_mode)
      s_log_message (_("Loading schematic [%s]\n"), fn);

    if (!f_open (toplevel, page, (gchar *) fn, &err)) {
      GtkWidget *dialog;

      g_warning ("%s\n", err->message);
      dialog = gtk_message_dialog_new_with_markup
        (GTK_WINDOW (w_current->main_window),
         GTK_DIALOG_DESTROY_WITH_PARENT,
         GTK_MESSAGE_ERROR,
         GTK_BUTTONS_CLOSE,
         _("<b>An error occurred while loading the requested file.</b>\n\nLoading from '%s' failed: %s. The gschem log may contain more information."),
         fn, err->message);
      gtk_window_set_title (GTK_WINDOW (dialog), _("Failed to load file"));
      gtk_dialog_run (GTK_DIALOG (dialog));
      gtk_widget_destroy (dialog);
      g_error_free (err);
    } else {
      gtk_recent_manager_add_item (recent_manager, g_filename_to_uri(fn, NULL, NULL));
    }
  } else {
    if (!quiet_mode)
      s_log_message (_("New file [%s]\n"),
                     toplevel->page_current->page_filename);

    g_run_hook_page (w_current, "%new-page-hook", toplevel->page_current);
  }

  gschem_page_view_set_page (page_view,
                             toplevel->page_current);

  o_undo_savestate (w_current, toplevel->page_current, UNDO_ALL);

  /* This line is generally un-needed, however if some code
   * wants to open a page, yet not bring it to the front, it is
   * needed needed to add it into the page manager. Otherwise,
   * it will get done in x_window_set_current_page(...)
   */
  x_pagesel_update (w_current); /* ??? */

  g_free (fn);

  return page;
}
Exemple #6
0
/*! \brief Opens a new page from a file.
 *  \par Function Description
 *  This function opens the file whose name is <B>filename</B> in a
 *  new PAGE of <B>toplevel</B>.
 *
 *  If there is no page for <B>filename</B> in <B>toplevel</B>'s list
 *  of pages, it creates a new PAGE, loads the file in it and returns
 *  a pointer on the new page. Otherwise it returns a pointer on the
 *  existing page.
 *
 *  If the filename passed is NULL, this function creates an empty,
 *  untitled page.  The name of the untitled page is build from
 *  configuration data ('untitled-name') and a counter for uniqueness.
 *
 *  The opened page becomes the current page of <B>toplevel</B>.
 *
 *  \param [in] w_current The toplevel environment.
 *  \param [in] filename The name of the file to open or NULL for a blank page.
 *  \returns A pointer on the new page.
 *
 *  \bug This code should check to make sure any untitled filename
 *  does not conflict with a file on disk.
 */
PAGE*
x_window_open_page (GSCHEM_TOPLEVEL *w_current, const gchar *filename)
{
  TOPLEVEL *toplevel = w_current->toplevel;
  PAGE *old_current, *page;
  gchar *fn;

  g_return_val_if_fail (toplevel != NULL, NULL);

  /* Generate untitled filename if none was specified */
  if (filename == NULL) {
    gchar *cwd, *tmp;
    cwd = g_get_current_dir ();
    tmp = g_strdup_printf ("%s_%d.sch",
                           toplevel->untitled_name,
                           ++w_current->num_untitled);
    fn = g_build_filename (cwd, tmp, NULL);
    g_free(cwd);
    g_free(tmp);
  } else {
    fn = g_strdup (filename);
  }

  /* Return existing page if it is already loaded */
  page = s_page_search (toplevel, fn);
  if ( page != NULL ) {
    g_free(fn);
    return page;
  }

  old_current = toplevel->page_current;
  page = s_page_new (toplevel, fn);
  s_page_goto (toplevel, page);

  /* Load from file if necessary, otherwise just print a message */
  if (filename != NULL) {
    GError *err = NULL;
    if (!quiet_mode)
      s_log_message (_("Loading schematic [%s]\n"), fn);

    if (!f_open (toplevel, page, (gchar *) fn, &err)) {
      GtkWidget *dialog;

      g_warning ("%s\n", err->message);
      dialog = gtk_message_dialog_new (GTK_WINDOW (w_current->main_window),
                                       GTK_DIALOG_DESTROY_WITH_PARENT,
                                       GTK_MESSAGE_ERROR,
                                       GTK_BUTTONS_CLOSE,
                                       "%s",
                                       err->message);
      gtk_window_set_title (GTK_WINDOW (dialog), _("Failed to load file"));
      gtk_dialog_run (GTK_DIALOG (dialog));
      gtk_widget_destroy (dialog);
      g_error_free (err);
    } else {
      gtk_recent_manager_add_item (recent_manager, g_filename_to_uri(fn, NULL, NULL));
    }
  } else {
    if (!quiet_mode)
      s_log_message (_("New file [%s]\n"),
                     toplevel->page_current->page_filename);
  }

  if (scm_is_false (scm_hook_empty_p (new_page_hook)))
    scm_run_hook (new_page_hook,
                  scm_cons (g_make_page_smob (toplevel, page), SCM_EOL));

  a_zoom_extents (w_current,
                  s_page_objects (toplevel->page_current),
                  A_PAN_DONT_REDRAW);

  o_undo_savestate (w_current, UNDO_ALL);

  if ( old_current != NULL )
    s_page_goto (toplevel, old_current);

  /* This line is generally un-needed, however if some code
   * wants to open a page, yet not bring it to the front, it is
   * needed needed to add it into the page manager. Otherwise,
   * it will get done in x_window_set_current_page(...)
   */
  x_pagesel_update (w_current); /* ??? */

  g_free (fn);

  return page;
}
Exemple #7
0
/*! \todo Finish function documentation!!!
 *  \brief
 *  \par Function Description
 *
 *  <B>type</B> can be one of the following values:
 *  <DL>
 *    <DT>*</DT><DD>UNDO_ACTION
 *    <DT>*</DT><DD>REDO_ACTION
 *  </DL>
 */
void
o_undo_callback (GschemToplevel *w_current, PAGE *page, int type)
{
  TOPLEVEL *toplevel = gschem_toplevel_get_toplevel (w_current);
  UNDO *u_current;
  UNDO *u_next;
  UNDO *save_bottom;
  UNDO *save_tos;
  UNDO *save_current;
  int save_logging;
  int find_prev_data=FALSE;

  char *save_filename;

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

  if (w_current->undo_control == FALSE) {
    s_log_message(_("Undo/Redo disabled in rc file\n"));
    return;
  }

  if (page->undo_current == NULL) {
    return;
  }

  if (type == UNDO_ACTION) {
    u_current = page->undo_current->prev;
  } else {
    u_current = page->undo_current->next;
  }

  u_next = page->undo_current;

  if (u_current == NULL) {
    return;
  }

  if (u_next->type == UNDO_ALL && u_current->type == UNDO_VIEWPORT_ONLY) {
#if DEBUG
    printf("Type: %d\n", u_current->type);
    printf("Current is an undo all, next is viewport only!\n");
#endif
    find_prev_data = TRUE;

    if (w_current->undo_type == UNDO_DISK) {
      u_current->filename = o_undo_find_prev_filename(u_current);
    } else {
      u_current->object_list = o_undo_find_prev_object_head (u_current);
    }
  }

  /* save filename */
  save_filename = g_strdup (page->page_filename);

  /* save structure so it's not nuked */
  save_bottom = page->undo_bottom;
  save_tos = page->undo_tos;
  save_current = page->undo_current;
  page->undo_bottom = NULL;
  page->undo_tos = NULL;
  page->undo_current = NULL;

  o_select_unselect_all (w_current);

  if (w_current->undo_type == UNDO_DISK && u_current->filename) {
    /* delete objects of page */
    s_page_delete_objects (toplevel, page);

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

    gschem_toplevel_page_content_changed (w_current, page);
  } else if (w_current->undo_type == UNDO_MEMORY && u_current->object_list) {
    /* delete objects of page */
    s_page_delete_objects (toplevel, page);

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

    gschem_toplevel_page_content_changed (w_current, page);
  }


  /* temporarily disable logging */
  save_logging = do_logging;
  do_logging = FALSE;

  if (w_current->undo_type == UNDO_DISK && u_current->filename) {

    f_open(toplevel, page, u_current->filename, NULL);

  } else if (w_current->undo_type == UNDO_MEMORY && u_current->object_list) {

    s_page_append_list (toplevel, page,
                        o_glist_copy_all (toplevel, u_current->object_list,
                                          NULL));
  }

  page->page_control = u_current->page_control;
  page->up = u_current->up;
  gschem_toplevel_page_content_changed (w_current, page);

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

  GschemPageGeometry *geometry = gschem_page_view_get_page_geometry (view);

  if (u_current->scale != 0) {
    gschem_page_geometry_set_viewport (geometry,
                                       u_current->x,
                                       u_current->y,
                                       u_current->scale);
    gschem_page_view_invalidate_all (view);
  } else {
    gschem_page_view_zoom_extents (view, u_current->object_list);
  }

  /* restore logging */
  do_logging = save_logging;

  /* set filename right */
  g_free(page->page_filename);
  page->page_filename = save_filename;

  /* final redraw */
  x_pagesel_update (w_current);
  x_multiattrib_update (w_current);
  i_update_menus(w_current);

  /* restore saved undo structures */
  page->undo_bottom = save_bottom;
  page->undo_tos = save_tos;
  page->undo_current = save_current;

  if (type == UNDO_ACTION) {
    if (page->undo_current) {
      page->undo_current = page->undo_current->prev;
      if (page->undo_current == NULL) {
        page->undo_current = page->undo_bottom;
      }
    }
  } else { /* type is REDO_ACTION */
    if (page->undo_current) {
      page->undo_current = page->undo_current->next;
      if (page->undo_current == NULL) {
        page->undo_current = page->undo_tos;
      }
    }
  }

  /* don't have to free data here since filename, object_list are */
  /* just pointers to the real data (lower in the stack) */
  if (find_prev_data) {
    u_current->filename = NULL;
    u_current->object_list = NULL;
  }

#if DEBUG
  printf("\n\n---Undo----\n");
  s_undo_print_all(page->undo_bottom);
  printf("TOS: %s\n", page->undo_tos->filename);
  printf("CURRENT: %s\n", page->undo_current->filename);
  printf("----\n");
#endif
}
Exemple #8
0
/*! \todo Finish function documentation!!!
 *  \brief
 *  \par Function Description
 *
 *  <B>type</B> can be one of the following values:
 *  <DL>
 *    <DT>*</DT><DD>UNDO_ACTION
 *    <DT>*</DT><DD>REDO_ACTION
 *  </DL>
 */
void o_undo_callback(GSCHEM_TOPLEVEL *w_current, int type)
{
  TOPLEVEL *toplevel = w_current->toplevel;
  UNDO *u_current;
  UNDO *u_next;
  UNDO *save_bottom;
  UNDO *save_tos;
  UNDO *save_current;
  int save_logging;
  int find_prev_data=FALSE;

  char *save_filename;

  if (w_current->undo_control == FALSE) {
    s_log_message(_("Undo/Redo disabled in rc file\n"));
    return;
  }

  if (toplevel->page_current->undo_current == NULL) {
    return;
  }

  if (type == UNDO_ACTION) {
    u_current = toplevel->page_current->undo_current->prev;
  } else {
    u_current = toplevel->page_current->undo_current->next;
  }

  u_next = toplevel->page_current->undo_current;

  if (u_current == NULL) {
    return;
  }

  if (u_next->type == UNDO_ALL && u_current->type == UNDO_VIEWPORT_ONLY) {
#if DEBUG
    printf("Type: %d\n", u_current->type);
    printf("Current is an undo all, next is viewport only!\n");
#endif
    find_prev_data = TRUE;

    if (w_current->undo_type == UNDO_DISK) {
      u_current->filename = o_undo_find_prev_filename(u_current);
    } else {
      u_current->object_list = o_undo_find_prev_object_head (u_current);
    }
  }

  /* save filename */
  save_filename = g_strdup (toplevel->page_current->page_filename);

  /* save structure so it's not nuked */
  save_bottom = toplevel->page_current->undo_bottom;
  save_tos = toplevel->page_current->undo_tos;
  save_current = toplevel->page_current->undo_current;
  toplevel->page_current->undo_bottom = NULL;
  toplevel->page_current->undo_tos = NULL;
  toplevel->page_current->undo_current = NULL;

  if (w_current->undo_type == UNDO_DISK && u_current->filename) {
    PAGE *p_new;
    s_page_delete (toplevel, toplevel->page_current);
    p_new = s_page_new(toplevel, u_current->filename);
    s_page_goto (toplevel, p_new);
  } else if (w_current->undo_type == UNDO_MEMORY && u_current->object_list) {
    PAGE *p_new;
    s_page_delete (toplevel, toplevel->page_current);
    p_new = s_page_new (toplevel, save_filename);
    s_page_goto (toplevel, p_new);
  }

  /* temporarily disable logging */
  save_logging = do_logging;
  do_logging = FALSE;

  if (w_current->undo_type == UNDO_DISK && u_current->filename) {

    f_open(toplevel, toplevel->page_current, u_current->filename, NULL);

    x_manual_resize(w_current);
    toplevel->page_current->page_control = u_current->page_control;
    toplevel->page_current->up = u_current->up;
    toplevel->page_current->CHANGED=1;

  } else if (w_current->undo_type == UNDO_MEMORY && u_current->object_list) {

    s_page_delete_objects (toplevel, toplevel->page_current);

    s_page_append_list (toplevel, toplevel->page_current,
                        o_glist_copy_all (toplevel, u_current->object_list,
                                          NULL));

    x_manual_resize(w_current);
    toplevel->page_current->page_control = u_current->page_control;
    toplevel->page_current->up = u_current->up;
    toplevel->page_current->CHANGED=1;
  }

  /* do misc setups */
  set_window(toplevel, toplevel->page_current,
             u_current->left, u_current->right,
             u_current->top, u_current->bottom);
  x_hscrollbar_update(w_current);
  x_vscrollbar_update(w_current);

  /* restore logging */
  do_logging = save_logging;

  /* set filename right */
  g_free(toplevel->page_current->page_filename);
  toplevel->page_current->page_filename = save_filename;

  /* final redraw */
  x_pagesel_update (w_current);
  x_multiattrib_update (w_current);

  /* Let the caller to decide if redraw or not */
  o_invalidate_all (w_current);
  i_update_menus(w_current);

  /* restore saved undo structures */
  toplevel->page_current->undo_bottom = save_bottom;
  toplevel->page_current->undo_tos = save_tos;
  toplevel->page_current->undo_current = save_current;

  if (type == UNDO_ACTION) {
    if (toplevel->page_current->undo_current) {
      toplevel->page_current->undo_current =
          toplevel->page_current->undo_current->prev;
      if (toplevel->page_current->undo_current == NULL) {
        toplevel->page_current->undo_current =
            toplevel->page_current->undo_bottom;
      }
    }
  } else { /* type is REDO_ACTION */
    if (toplevel->page_current->undo_current) {
      toplevel->page_current->undo_current =
          toplevel->page_current->undo_current->next;
      if (toplevel->page_current->undo_current == NULL) {
        toplevel->page_current->undo_current =
            toplevel->page_current->undo_tos;
      }
    }
  }

  /* don't have to free data here since filename, object_list are */
  /* just pointers to the real data (lower in the stack) */
  if (find_prev_data) {
    u_current->filename = NULL;
    u_current->object_list = NULL;
  }

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