コード例 #1
0
ファイル: o_place.c プロジェクト: jaredcasper/geda-gaf
/*! \todo Finish function documentation!!!
 *  \brief
 *  \par Function Description
 *
 */
void o_place_end (GSCHEM_TOPLEVEL *w_current,
                  int w_x, int w_y,
                  int continue_placing,
                  GList **ret_new_objects,
                  const char* hook_name)
{
  TOPLEVEL *toplevel = w_current->toplevel;
  int w_diff_x, w_diff_y;
  OBJECT *o_current;
  PAGE *p_current;
  GList *temp_dest_list = NULL;
  GList *connected_objects = NULL;
  GList *iter;

  /* erase old image */
  /* o_place_invaidate_rubber (w_current, FALSE); */
  w_current->rubber_visible = 0;

  /* Calc final object positions */
  w_current->second_wx = w_x;
  w_current->second_wy = w_y;

  w_diff_x = w_current->second_wx - w_current->first_wx;
  w_diff_y = w_current->second_wy - w_current->first_wy;

  if (continue_placing) {
    /* Make a copy of the place list if we want to keep it afterwards */
    temp_dest_list = o_glist_copy_all (toplevel,
                                       toplevel->page_current->place_list,
                                       temp_dest_list);
  } else {
    /* Otherwise just take it */
    temp_dest_list = toplevel->page_current->place_list;
    toplevel->page_current->place_list = NULL;
  }

  if (ret_new_objects != NULL) {
    *ret_new_objects = g_list_copy (temp_dest_list);
  }

  o_glist_translate_world(toplevel, w_diff_x, w_diff_y, temp_dest_list);

  /* Attach each item back onto the page's object list. Update object
   * connectivity and add the new objects to the selection list.*/
  p_current = toplevel->page_current;

  for (iter = temp_dest_list; iter != NULL; iter = g_list_next (iter)) {
    o_current = iter->data;

    s_page_append (toplevel, p_current, o_current);

    /* Update object connectivity */
    s_conn_update_object (toplevel, o_current);
    connected_objects = s_conn_return_others (connected_objects, o_current);
  }

  if (hook_name != NULL) {
    g_run_hook_object_list (hook_name, temp_dest_list);
  }

  o_invalidate_glist (w_current, connected_objects);
  g_list_free (connected_objects);
  connected_objects = NULL;

  toplevel->page_current->CHANGED = 1;
  o_invalidate_glist (w_current, temp_dest_list); /* only redraw new objects */
  g_list_free (temp_dest_list);

  o_undo_savestate (w_current, UNDO_ALL);
  i_update_menus (w_current);
}
コード例 #2
0
ファイル: o_path.c プロジェクト: dmay31/geda-gaf
/*! \brief End the input of a path.
 *  \par Function Description
 *  This function ends the process of interactively adding a path to the
 *  current sheet.
 *
 *  It first erases the last temporary path displayed, calculates the
 *  corresponding world coordinates of the two ends of the path and finally
 *  adds a new initialized path object to the list of object of the current
 *  sheet.
 *
 *  \param [in] w_current  The GschemToplevel object.
 *  \param [in] w_x        (unused)
 *  \param [in] w_y        (unused)
 */
gboolean
o_path_end(GschemToplevel *w_current, int w_x, int w_y)
{
  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);
  gboolean close_path, end_path, start_path;
  PATH *p;
  PATH_SECTION *section, *prev_section;
  int x1, y1, x2, y2;

  g_assert (w_current);
  g_assert (w_current->toplevel);
  g_assert (w_current->temp_path != NULL);
  g_assert (w_current->temp_path->sections != NULL);
  g_assert (toplevel != NULL);
  g_assert (page != NULL);

  o_path_invalidate_rubber (w_current);

  x1 = w_current->first_wx;
  y1 = w_current->first_wy;
  x2 = w_current->second_wx;
  y2 = w_current->second_wy;
  p = w_current->temp_path;

  /* Check whether the section that's being added is the initial
   * MOVETO.  This is detected if the path is currently empty. */
  start_path = (p->num_sections == 0);

  prev_section = start_path ? NULL : &p->sections[p->num_sections - 1];

  /* Check whether the section that's being added closes the path.
   * This is detected if the location of the node is the same as the
   * location of the starting node, and there is at least one section
   * in the path in addition to the initial MOVETO section. */
  section = &p->sections[0];
  close_path = (!start_path
                && x1 == section->x3
                && y1 == section->y3);

  /* Check whether the section that's being added ends the path. This
   * is detected if the location of the node is the same as the
   * location of the previous node. */
  end_path = (!start_path
              && x1 == prev_section->x3
              && y1 == prev_section->y3);

  /* Add predicted next sections */
  path_next_sections (w_current);

  if (end_path || close_path) {
    /* Add object to page and clean up path drawing state */
    OBJECT *obj = o_path_new_take_path (toplevel, OBJ_PATH,
                                        GRAPHIC_COLOR, p);
    w_current->temp_path = NULL;
    w_current->first_wx = -1;
    w_current->first_wy = -1;
    w_current->second_wx = -1;
    w_current->second_wy = -1;
    w_current->third_wx = -1;
    w_current->third_wy = -1;

    s_page_append (toplevel, page, obj);
    g_run_hook_object (w_current, "%add-objects-hook", obj);
    gschem_toplevel_page_content_changed (w_current, page);
    o_undo_savestate (w_current, page, UNDO_ALL);

    w_current->rubber_visible = FALSE;

    return FALSE;
  } else {
    /* Leave state as it is and continue path drawing... */

    /* Save the control point coordinates for the next section */
    w_current->third_wx = x2;
    w_current->third_wy = y2;

    return TRUE;
  }
}
コード例 #3
0
ファイル: x_window.c プロジェクト: jgriessen/geda-gaf
/*! \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] toplevel 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, (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 {
      recent_files_add (fn);
    }
  } else {
    if (!quiet_mode)
      s_log_message (_("New file [%s]\n"),
                     toplevel->page_current->page_filename);
  }

  if (scm_hook_empty_p (new_page_hook) == SCM_BOOL_F)
    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;
}
コード例 #4
0
ファイル: o_net.c プロジェクト: jaredcasper/geda-gaf
/*! \brief finish a net drawing action 
 * \par Function Description 
 * This function finishes the drawing of a net. If we have a visible
 * magnetic marker, we use that instead of the current cursor
 * position.
 *
 * The rubber nets are removed, the nets and cues are drawn and the
 * net is added to the TOPLEVEL structure.  
 *
 * The function returns TRUE if it has drawn a net, FALSE otherwise.
 */
int o_net_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
{
  TOPLEVEL *toplevel = w_current->toplevel;
  int color;
  int primary_zero_length, secondary_zero_length;
  int found_primary_connection = FALSE;
  int save_wx, save_wy;

  GList *prev_conn_objects;
  OBJECT *new_net = NULL;

  /* Save a list of added objects to run the %add-objects-hook later */
  GList *added_objects = NULL;

  g_assert( w_current->inside_action != 0 );

  o_net_invalidate_rubber (w_current);

  if (w_current->magnetic_wx != -1 && w_current->magnetic_wy != -1)
    o_net_finishmagnetic(w_current);

  w_current->rubber_visible = 0;

  /* See if either of the nets are zero length.  We'll only add */
  /* the non-zero ones */
  primary_zero_length = (w_current->first_wx == w_current->second_wx) &&
    (w_current->first_wy == w_current->second_wy);
 
  secondary_zero_length = (w_current->second_wx == w_current->third_wx) &&
      (w_current->second_wy == w_current->third_wy);

  /* If both nets are zero length... */
  /* this ends the net drawing behavior */
  if ( primary_zero_length && secondary_zero_length ) {
    return FALSE;
  }

  save_wx = w_current->third_wx;
  save_wy = w_current->third_wy;

  if (toplevel->override_net_color == -1) {
    color = NET_COLOR;
  } else {
    color = toplevel->override_net_color;
  }

  if (w_current->third_wx != snap_grid (w_current, w_current->third_wx)
      || w_current->third_wy != snap_grid (w_current, w_current->third_wy))
      s_log_message(_("Warning: Ending net at off grid coordinate\n"));

  if (!primary_zero_length ) {
  /* create primary net */
      new_net = o_net_new(toplevel, OBJ_NET, color,
                          w_current->first_wx, w_current->first_wy,
                          w_current->second_wx, w_current->second_wy);
      s_page_append (toplevel, toplevel->page_current, new_net);

      added_objects = g_list_prepend (added_objects, new_net);

      /* conn stuff */
      /* LEAK CHECK 1 */
      prev_conn_objects = s_conn_return_others (NULL, new_net);
      o_net_add_busrippers (w_current, new_net, prev_conn_objects);
      g_list_free (prev_conn_objects);

#if DEBUG 
      printf("primary:\n"); 
      s_conn_print(new_net->conn_list);
#endif

      /* Go off and search for valid connection on this newly created net */
      found_primary_connection = s_conn_net_search(new_net, 1, 
                                                   new_net->conn_list);
      if (found_primary_connection)
      {
      	/* if a net connection is found, reset start point of next net */
	save_wx = w_current->second_wx;
	save_wy = w_current->second_wy;
      }
  }


  /* If the second net is not zero length, add it as well */
  /* Also, a valid net connection from the primary net was not found */
  if (!secondary_zero_length && !found_primary_connection) {
      
      /* Add secondary net */
      new_net = o_net_new(toplevel, OBJ_NET, color,
                          w_current->second_wx, w_current->second_wy,
                          w_current->third_wx, w_current->third_wy);
      s_page_append (toplevel, toplevel->page_current, new_net);

      added_objects = g_list_prepend (added_objects, new_net);

      /* conn stuff */
      /* LEAK CHECK 2 */
      prev_conn_objects = s_conn_return_others (NULL, new_net);
      o_net_add_busrippers (w_current, new_net, prev_conn_objects);
      g_list_free (prev_conn_objects);
#if DEBUG
      s_conn_print(new_net->conn_list);
#endif
  }

  /* Call add-objects-hook */
  if (added_objects != NULL) {
    g_run_hook_object_list ("%add-objects-hook", added_objects);
    g_list_free (added_objects);
  }

  toplevel->page_current->CHANGED = 1;
  w_current->first_wx = save_wx;
  w_current->first_wy = save_wy;
  o_undo_savestate(w_current, UNDO_ALL);

  return (TRUE);
}