[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

gEDA-cvs: gaf.git: branch: master updated (1.5.0-20080706-41-gb02d954)



The branch, master has been updated
       via  b02d9540d1bc0cdcfd5935f84bf8ee2f52dde2bd (commit)
       via  1aaf6613a7c6991d858c1143ed3917675a115a5a (commit)
       via  95923f7de815ec58819eaf94ab9332d51a28fbb9 (commit)
       via  ac56af89f55594a3739c16692bec4e5974848dc1 (commit)
       via  1cc266bbe45846030205aa8931cea40fe2dbdf3b (commit)
       via  7e4d443eea54c8fc19833aa67ae64ed1ffba0e80 (commit)
       via  e2278f9ed3c49d6226e3e721e55a940cbaed53f3 (commit)
       via  4ad46d1b431bceb665fdd45778345118dfc1d414 (commit)
       via  67bb084eef2f0e97bd9573fdea0faa5dfd2e53bc (commit)
       via  d96ad3c39121d6c7e32128493d5445f0825f1751 (commit)
       via  19aab8901a7519879231c680060f89a69c125e85 (commit)
       via  306d5722847b4d8c152bd369bc68846b9a19abb0 (commit)
       via  658516c080eae8d78685113e48290bb291af0715 (commit)
       via  64a6741c858de019ab26058afcc417b821d37117 (commit)
       via  0cdcdf4cfe8bf3c6aa078b91e5696a26f7a60f23 (commit)
       via  37eaad0765b34e85275706b6cffbc73ec9b5c4cd (commit)
       via  83de2270e9d0f159975e833e1fec213f952c7315 (commit)
      from  b86ffc45f699781c220153e2390a54f8b823a930 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


=========
 Summary
=========

 gschem/include/prototype.h     |   26 ++--
 gschem/include/x_multiattrib.h |    3 -
 gschem/src/gschem.c            |   20 +--
 gschem/src/i_basic.c           |    2 +-
 gschem/src/i_callbacks.c       |  106 ++++++++----
 gschem/src/o_attrib.c          |  118 +++++--------
 gschem/src/o_basic.c           |   29 +++
 gschem/src/o_buffer.c          |    2 +-
 gschem/src/o_copy.c            |    3 +-
 gschem/src/o_cue.c             |   69 ++++----
 gschem/src/o_delete.c          |  308 +++++-----------------------------
 gschem/src/o_move.c            |    6 +-
 gschem/src/x_autonumber.c      |    2 +-
 gschem/src/x_color.c           |   49 ++++++-
 gschem/src/x_dialog.c          |   14 +--
 gschem/src/x_event.c           |   51 +-----
 gschem/src/x_multiattrib.c     |  367 ++++++++++++++++++++--------------------
 gschem/src/x_stroke.c          |  178 +++++++++++---------
 gschem/src/x_window.c          |   42 -----
 libgeda/include/prototype.h    |    7 +-
 libgeda/include/struct.h       |    7 +-
 libgeda/src/o_bus_basic.c      |    4 +-
 libgeda/src/o_complex_basic.c  |   24 ---
 libgeda/src/o_net_basic.c      |    4 +-
 libgeda/src/o_pin_basic.c      |    4 +-
 libgeda/src/s_basic.c          |    6 +-
 libgeda/src/s_conn.c           |   21 +--
 libgeda/src/s_page.c           |   21 +--
 libgeda/src/s_tile.c           |  137 +++------------
 29 files changed, 624 insertions(+), 1006 deletions(-)


=================
 Commit Messages
=================

commit b02d9540d1bc0cdcfd5935f84bf8ee2f52dde2bd
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:41 2008 +0200

    Use functions from o_select.c rather than low-level geda_list functions.

:100644 100644 3381aa4... 232dd61... M	gschem/src/i_basic.c
:100644 100644 7bc27ab... 66ae525... M	gschem/src/i_callbacks.c
:100644 100644 72b7710... c423734... M	gschem/src/o_copy.c
:100644 100644 93da77d... 13470d7... M	gschem/src/o_move.c
:100644 100644 0d0db44... fa580b5... M	gschem/src/x_dialog.c
:100644 100644 a1015c7... 34816ae... M	gschem/src/x_event.c

commit 1aaf6613a7c6991d858c1143ed3917675a115a5a
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:40 2008 +0200

    Move selection monitoring out of the multi attrib widget.
    
    Reinstated the 'object' property for multi attrib widget in place of
    the 'selection' one: the widget does not have to mess with selections,
    it is only interested in objects. Moved the selection watch stuff
    outside.

:100644 100644 4190bcf... 90010f0... M	gschem/include/x_multiattrib.h
:100644 100644 6519fb0... a858cf4... M	gschem/src/x_multiattrib.c

commit 95923f7de815ec58819eaf94ab9332d51a28fbb9
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:39 2008 +0200

    Simplify prototype of s_tile_remove_object().

:100644 100644 93a3d22... fa05ce9... M	libgeda/include/prototype.h
:100644 100644 c84e439... 998a8a5... M	libgeda/src/s_basic.c
:100644 100644 19c40fa... bbec414... M	libgeda/src/s_page.c
:100644 100644 5a63a85... c6e350d... M	libgeda/src/s_tile.c

commit ac56af89f55594a3739c16692bec4e5974848dc1
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:38 2008 +0200

    Replace TILE_LOC structure with list of references to TILEs.
    
    Removed structure TILE_LOC: now objects have a list of references to
    TILE structures.

:100644 100644 a7df60d... 93a3d22... M	libgeda/include/prototype.h
:100644 100644 98cfbc8... 8a9ad2f... M	libgeda/include/struct.h
:100644 100644 8bce75c... c84e439... M	libgeda/src/s_basic.c
:100644 100644 da1e10b... 085bf1d... M	libgeda/src/s_conn.c
:100644 100644 5e6268f... 5a63a85... M	libgeda/src/s_tile.c

commit 1cc266bbe45846030205aa8931cea40fe2dbdf3b
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:37 2008 +0200

    Rename s_tile_add_object() to s_tile_add_line_object() and simplify prototype.

:100644 100644 b034ea5... a7df60d... M	libgeda/include/prototype.h
:100644 100644 987472e... 9a4d8e6... M	libgeda/src/o_bus_basic.c
:100644 100644 bf6c919... 1538a0b... M	libgeda/src/o_net_basic.c
:100644 100644 7e7f258... e58e1f7... M	libgeda/src/o_pin_basic.c
:100644 100644 a161fc5... 5e6268f... M	libgeda/src/s_tile.c

commit 7e4d443eea54c8fc19833aa67ae64ed1ffba0e80
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:36 2008 +0200

    Rename s_tile_remove_object_all() to s_tile_remove_object().

:100644 100644 f9717b5... b034ea5... M	libgeda/include/prototype.h
:100644 100644 468bca4... 8bce75c... M	libgeda/src/s_basic.c
:100644 100644 cca15c6... 19c40fa... M	libgeda/src/s_page.c
:100644 100644 09ad19d... a161fc5... M	libgeda/src/s_tile.c

commit e2278f9ed3c49d6226e3e721e55a940cbaed53f3
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:35 2008 +0200

    Remove unused function s_tile_remove_object_all_crude().

:100644 100644 1f6743e... f9717b5... M	libgeda/include/prototype.h
:100644 100644 8ed1ff3... 09ad19d... M	libgeda/src/s_tile.c

commit 4ad46d1b431bceb665fdd45778345118dfc1d414
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:34 2008 +0200

    Limit scope of gschem x_color_allocate_all().

:100644 100644 e4405f5... fb34a70... M	gschem/include/prototype.h
:100644 100644 7ca51a2... aa51d14... M	gschem/src/x_color.c

commit 67bb084eef2f0e97bd9573fdea0faa5dfd2e53bc
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:33 2008 +0200

    Move color-related stuff from x_window.c to x_color.c.
    
    Renamed x_window_setup_colors() and x_window_free_colors() to
    x_color_init() and x_color_free() respectively. And moved them to
    x_color.c

:100644 100644 e2d71c3... e4405f5... M	gschem/include/prototype.h
:100644 100644 80ebd06... 2ae8d51... M	gschem/src/gschem.c
:100644 100644 8205c65... 7ca51a2... M	gschem/src/x_color.c
:100644 100644 814cf1d... afafbb6... M	gschem/src/x_window.c

commit d96ad3c39121d6c7e32128493d5445f0825f1751
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:32 2008 +0200

    Cleanup the stroke interface.
    
    Improved the API and memory allocation, added documentation.

:100644 100644 a9628b8... e2d71c3... M	gschem/include/prototype.h
:100644 100644 d350903... 80ebd06... M	gschem/src/gschem.c
:100644 100644 d087a57... a1015c7... M	gschem/src/x_event.c
:100644 100644 a557761... fe247a8... M	gschem/src/x_stroke.c

commit 19aab8901a7519879231c680060f89a69c125e85
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:31 2008 +0200

    Modify o_attrib_toggle_show_name_value() to work on a single object.

:100644 100644 edf3b53... a9628b8... M	gschem/include/prototype.h
:100644 100644 8838b01... 7bc27ab... M	gschem/src/i_callbacks.c
:100644 100644 952599c... 48c971a... M	gschem/src/o_attrib.c

commit 306d5722847b4d8c152bd369bc68846b9a19abb0
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:30 2008 +0200

    Modify o_attrib_toggle_visibility() to work on a single object.

:100644 100644 c8c4185... edf3b53... M	gschem/include/prototype.h
:100644 100644 d2c2553... 8838b01... M	gschem/src/i_callbacks.c
:100644 100644 ab1dd2c... 952599c... M	gschem/src/o_attrib.c

commit 658516c080eae8d78685113e48290bb291af0715
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:29 2008 +0200

    Add new function to delete any object.
    
    Added o_delete() as replacement for individual object deletion
    function. Adapted o_delete_selected() accordingly.

:100644 100644 1bdc549... c8c4185... M	gschem/include/prototype.h
:100644 100644 a11fef1... d2c2553... M	gschem/src/i_callbacks.c
:100644 100644 3103ef3... d3e9ed2... M	gschem/src/o_delete.c
:100644 100644 1054f06... 93da77d... M	gschem/src/o_move.c
:100644 100644 b58b3f5... 318e05e... M	gschem/src/x_autonumber.c
:100644 100644 679d428... 6519fb0... M	gschem/src/x_multiattrib.c

commit 64a6741c858de019ab26058afcc417b821d37117
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:28 2008 +0200

    Merge cue undrawing functions for complex and objects.
    
    Merged o_cue_undraw() and o_cue_undraw_complex(). Also added
    documentation.

:100644 100644 718c530... 1bdc549... M	gschem/include/prototype.h
:100644 100644 99c5fec... b3ecde5... M	gschem/src/o_cue.c
:100644 100644 9d9b2dd... 3103ef3... M	gschem/src/o_delete.c

commit 0cdcdf4cfe8bf3c6aa078b91e5696a26f7a60f23
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:27 2008 +0200

    Add new function to erase grips on any object.

:100644 100644 f4fe3e1... 718c530... M	gschem/include/prototype.h
:100644 100644 73e1c4b... b727d00... M	gschem/src/o_basic.c

commit 37eaad0765b34e85275706b6cffbc73ec9b5c4cd
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:26 2008 +0200

    Rename o_delete() to o_delete_selected().

:100644 100644 6c7e568... f4fe3e1... M	gschem/include/prototype.h
:100644 100644 dcb75fb... a11fef1... M	gschem/src/i_callbacks.c
:100644 100644 809c02c... c8fda91... M	gschem/src/o_buffer.c
:100644 100644 e482d03... 9d9b2dd... M	gschem/src/o_delete.c

commit 83de2270e9d0f159975e833e1fec213f952c7315
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:25 2008 +0200

    Remove o_complex_delete().
    
    Removed function as s_delete() does the same thing.

:100644 100644 df45421... e482d03... M	gschem/src/o_delete.c
:100644 100644 0fb548c... 1f6743e... M	libgeda/include/prototype.h
:100644 100644 a4fb831... 7ee9d69... M	libgeda/src/o_complex_basic.c

=========
 Changes
=========

commit b02d9540d1bc0cdcfd5935f84bf8ee2f52dde2bd
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:41 2008 +0200

    Use functions from o_select.c rather than low-level geda_list functions.

diff --git a/gschem/src/i_basic.c b/gschem/src/i_basic.c
index 3381aa4..232dd61 100644
--- a/gschem/src/i_basic.c
+++ b/gschem/src/i_basic.c
@@ -382,7 +382,7 @@ void i_update_menus(GSCHEM_TOPLEVEL *w_current)
   g_assert(w_current != NULL);
   g_assert(toplevel->page_current != NULL);
 
-  if ( geda_list_get_glist( toplevel->page_current->selection_list ) != NULL ) {
+  if (o_select_selected (w_current)) {
     /* since one or more things are selected, we set these TRUE */
     /* These strings should NOT be internationalized */
     x_menus_sensitivity(w_current, "Edit/Cut Buffer", TRUE);
diff --git a/gschem/src/i_callbacks.c b/gschem/src/i_callbacks.c
index 7bc27ab..66ae525 100644
--- a/gschem/src/i_callbacks.c
+++ b/gschem/src/i_callbacks.c
@@ -1859,7 +1859,7 @@ DEFINE_I_CALLBACK(buffer_copy1)
 
   exit_if_null(w_current);
 
-  if ( geda_list_get_glist( w_current->toplevel->page_current->selection_list ) == NULL )
+  if (!o_select_selected (w_current))
     return;
 
   i_update_middle_button(w_current, i_callback_buffer_copy1, _("Copy 1"));
@@ -1878,7 +1878,7 @@ DEFINE_I_CALLBACK(buffer_copy2)
 
   exit_if_null(w_current);
 
-  if ( geda_list_get_glist( w_current->toplevel->page_current->selection_list ) == NULL )
+  if (!o_select_selected (w_current))
     return;
 
   i_update_middle_button(w_current, i_callback_buffer_copy2, _("Copy 2"));
@@ -1897,7 +1897,7 @@ DEFINE_I_CALLBACK(buffer_copy3)
 
   exit_if_null(w_current);
 
-  if ( geda_list_get_glist( w_current->toplevel->page_current->selection_list ) == NULL )
+  if (!o_select_selected (w_current))
     return;
 
   i_update_middle_button(w_current, i_callback_buffer_copy3, _("Copy 3"));
@@ -1916,7 +1916,7 @@ DEFINE_I_CALLBACK(buffer_copy4)
 
   exit_if_null(w_current);
 
-  if ( geda_list_get_glist( w_current->toplevel->page_current->selection_list ) == NULL )
+  if (!o_select_selected (w_current))
     return;
 
   i_update_middle_button(w_current, i_callback_buffer_copy4, _("Copy 4"));
@@ -1935,7 +1935,7 @@ DEFINE_I_CALLBACK(buffer_copy5)
 
   exit_if_null(w_current);
 
-  if ( geda_list_get_glist( w_current->toplevel->page_current->selection_list ) == NULL )
+  if (!o_select_selected (w_current))
     return;
 
   i_update_middle_button(w_current, i_callback_buffer_copy5, _("Copy 5"));
@@ -1954,7 +1954,7 @@ DEFINE_I_CALLBACK(buffer_cut1)
 
   exit_if_null(w_current);
 
-  if ( geda_list_get_glist( w_current->toplevel->page_current->selection_list ) == NULL )
+  if (!o_select_selected (w_current))
     return;
 
   i_update_middle_button(w_current, i_callback_buffer_cut1, _("Cut 1"));
@@ -1973,7 +1973,7 @@ DEFINE_I_CALLBACK(buffer_cut2)
 
   exit_if_null(w_current);
 
-  if ( geda_list_get_glist( w_current->toplevel->page_current->selection_list ) == NULL )
+  if (!o_select_selected (w_current))
     return;
 
   i_update_middle_button(w_current, i_callback_buffer_cut2, _("Cut 2"));
@@ -1992,7 +1992,7 @@ DEFINE_I_CALLBACK(buffer_cut3)
 
   exit_if_null(w_current);
 
-  if ( geda_list_get_glist( w_current->toplevel->page_current->selection_list ) == NULL )
+  if (!o_select_selected (w_current))
     return;
 
   i_update_middle_button(w_current, i_callback_buffer_cut3, _("Cut 3"));
@@ -2011,7 +2011,7 @@ DEFINE_I_CALLBACK(buffer_cut4)
 
   exit_if_null(w_current);
 
-  if ( geda_list_get_glist( w_current->toplevel->page_current->selection_list ) == NULL )
+  if (!o_select_selected (w_current))
     return;
 
   i_update_middle_button(w_current, i_callback_buffer_cut4, _("Cut 4"));
@@ -2030,7 +2030,7 @@ DEFINE_I_CALLBACK(buffer_cut5)
 
   exit_if_null(w_current);
 
-  if ( geda_list_get_glist( w_current->toplevel->page_current->selection_list ) == NULL )
+  if (!o_select_selected (w_current))
     return;
 
   i_update_middle_button(w_current, i_callback_buffer_cut5, _("Cut 5"));
diff --git a/gschem/src/o_copy.c b/gschem/src/o_copy.c
index 72b7710..c423734 100644
--- a/gschem/src/o_copy.c
+++ b/gschem/src/o_copy.c
@@ -39,8 +39,7 @@
  */
 void o_copy_start(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 {
-  TOPLEVEL *toplevel = w_current->toplevel;
-  if (geda_list_get_glist( toplevel->page_current->selection_list ) != NULL) {
+  if (o_select_selected (w_current)) {
 
   /* This is commented out since it breaks the copy of objects.  See below. */
 #if 0
diff --git a/gschem/src/o_move.c b/gschem/src/o_move.c
index 93da77d..13470d7 100644
--- a/gschem/src/o_move.c
+++ b/gschem/src/o_move.c
@@ -39,7 +39,7 @@
 void o_move_start(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
-  if ( geda_list_get_glist( toplevel->page_current->selection_list ) != NULL) {
+  if (o_select_selected (w_current)) {
 
     /* Save the current state. When rotating the selection when moving,
        we have to come back to here */
diff --git a/gschem/src/x_dialog.c b/gschem/src/x_dialog.c
index 0d0db44..fa580b5 100644
--- a/gschem/src/x_dialog.c
+++ b/gschem/src/x_dialog.c
@@ -2272,23 +2272,13 @@ static GtkWidget *create_color_menu (GSCHEM_TOPLEVEL * w_current, int * select_i
   /* first lets see if we have a selected object, if so select its color */
   int select_col = -1;
   int item_index = 0;
-  GList *s_current = NULL;
   OBJECT *object = NULL;
 
   menu = gtk_menu_new ();
   group = NULL;
 
-  s_current = geda_list_get_glist( w_current->toplevel->page_current->selection_list );
-
-  if (s_current != NULL) {
-
-    object = (OBJECT *) s_current->data;
-    if (object == NULL) {
-      fprintf(stderr, "no object selected - WHEE!\n");
-    }else{
-      select_col = object->saved_color;
-      /* fprintf(stderr, "setting object color %d\n", select_col); */
-    }
+  if ((object = o_select_return_first_object (w_current)) != NULL) {
+    select_col = object->saved_color;
   }else /*fprintf(stderr, "no object selected\n")*/;
 
   for (index=0; index < MAX_COLORS;index++) {
diff --git a/gschem/src/x_event.c b/gschem/src/x_event.c
index a1015c7..34816ae 100644
--- a/gschem/src/x_event.c
+++ b/gschem/src/x_event.c
@@ -110,7 +110,7 @@ gint x_event_button_pressed(GtkWidget *widget, GdkEventButton *event,
       (w_current->event_state == STARTSELECT ||
        w_current->event_state == SELECT)) {
     o_find_object(w_current, w_x, w_y, TRUE);
-    if ( geda_list_get_glist( toplevel->page_current->selection_list )) {
+    if (o_select_selected (w_current)) {
        o_edit(w_current, geda_list_get_glist( toplevel->page_current->selection_list ));
        return(0);
     }

commit 1aaf6613a7c6991d858c1143ed3917675a115a5a
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:40 2008 +0200

    Move selection monitoring out of the multi attrib widget.
    
    Reinstated the 'object' property for multi attrib widget in place of
    the 'selection' one: the widget does not have to mess with selections,
    it is only interested in objects. Moved the selection watch stuff
    outside.

diff --git a/gschem/include/x_multiattrib.h b/gschem/include/x_multiattrib.h
index 4190bcf..90010f0 100644
--- a/gschem/include/x_multiattrib.h
+++ b/gschem/include/x_multiattrib.h
@@ -44,7 +44,6 @@ struct _MultiattribClass {
 struct _Multiattrib {
   GschemDialog parent_instance;
 
-  SELECTION *selection;
   OBJECT *object;
 
   GtkTreeView    *treeview;
@@ -57,8 +56,6 @@ struct _Multiattrib {
   GtkWidget      *frame_add;
 
   GdkColor       value_normal_text_color;   /* Workaround for lameness in GtkTextView */
-
-  gulong selection_changed_id;
 };
 
 
diff --git a/gschem/src/x_multiattrib.c b/gschem/src/x_multiattrib.c
index 6519fb0..a858cf4 100644
--- a/gschem/src/x_multiattrib.c
+++ b/gschem/src/x_multiattrib.c
@@ -42,6 +42,146 @@
 #include "../include/gschem_dialog.h"
 #include "../include/x_multiattrib.h"
 
+/*! \brief Update the multiattrib editor dialog when the page's
+ *         selection changes.
+ *  \par Function Description
+ *  When the page's selection changes this function identifies how
+ *  many objects which can have attributes are currently selected. If
+ *  this number is 1, the dialog is set to edit the attributes of the
+ *  first selected object..
+ *
+ *  \param [in] selection  The SELECTION object of page being edited.
+ *  \param [in] user_data  The multi-attribute editor dialog.
+ */
+static void callback_selection_changed (SELECTION *selection,
+                                        gpointer   user_data)
+{
+  Multiattrib *multiattrib = MULTIATTRIB (user_data);
+  GList *iter;
+  OBJECT *object;
+  gint object_count = 0;
+
+  for (iter = geda_list_get_glist (selection);
+       iter != NULL;
+       iter = g_list_next (iter)) {
+    object = (OBJECT *)iter->data;
+    g_assert (object != NULL);
+
+    if (object->type == OBJ_COMPLEX ||
+        object->type == OBJ_PLACEHOLDER ||
+        object->type == OBJ_NET ||
+        object->type == OBJ_BUS ||
+        object->type == OBJ_PIN) {
+      object_count++;
+    }
+  }
+
+  if (object_count == 0) {
+    /* TODO: If the user selects a single attribute which is
+     *       not floating, should we find its parent object and
+     *       display the multi-attribute editor for that?
+     *       Bonus marks for making it jump to the correct attrib.
+     */
+    object = NULL;
+  } else if (object_count == 1) {
+    object = (OBJECT *)((geda_list_get_glist (selection))->data);
+  } else {
+    /* TODO: Something clever with multiple objects selected */
+    object = NULL;
+  }
+
+  g_object_set (multiattrib,
+                "object", object,
+                NULL);
+}
+
+#define DIALOG_DATA_SELECTION "current-selection"
+
+/*! \brief Update the dialog when the current page's SELECTION object
+ *         is destroyed
+ *  \par Function Description
+ *  This handler is called when the g_object_weak_ref() on the
+ *  SELECTION object we're watching expires. We reset our
+ *  multiattrib->selection pointer to NULL to avoid attempting to
+ *  access the destroyed object.
+ *
+ *  \note
+ *  Our signal handlers were automatically disconnected during the
+ *  destruction process.
+ *
+ *  \param [in] data                  Pointer to the multi-attrib dialog
+ *  \param [in] where_the_object_was  Pointer to where the object was
+ *                                    just destroyed
+ */
+static void callback_selection_finalized (gpointer data,
+                                          GObject *where_the_object_was)
+{
+  Multiattrib *multiattrib = MULTIATTRIB (data);
+  g_object_set (multiattrib,
+                "object", NULL,
+                NULL);
+  g_object_set_data (G_OBJECT (multiattrib), DIALOG_DATA_SELECTION, NULL);
+}
+
+/*! \brief Add link between multiattrib dialog and current selection.
+ *  \par Function Description
+ *  This function connects a handler to the "changed" signal of
+ *  current selection to let the dialog watch it. It also adds a weak
+ *  reference on the selection.
+ *
+ *  \param [in] multiattrib  The Multiattrib dialog.
+ *  \param [in] selection    The selection to watch.
+ */
+static void connect_selection (Multiattrib *multiattrib,
+                               SELECTION   *selection)
+{
+  g_assert (g_object_get_data (G_OBJECT (multiattrib),
+                               DIALOG_DATA_SELECTION) == NULL);
+  g_object_set_data (G_OBJECT (multiattrib), DIALOG_DATA_SELECTION, selection);
+  g_object_weak_ref (G_OBJECT (selection),
+                     callback_selection_finalized,
+                     multiattrib);
+  g_signal_connect (selection,
+                    "changed",
+                    (GCallback)callback_selection_changed,
+                    multiattrib);
+  /* Synthesise a selection changed update to refresh the view */
+  callback_selection_changed (selection, multiattrib);
+}
+
+/*! \brief Remove the link between multiattrib dialog and selection.
+ *  \par Function Description
+ *  If the dialog is watching a selection, this function disconnects
+ *  the "changed" signal and removes the weak reference it previously
+ *  added on it.
+ *
+ *  \param [in] multiattrib  The Multiattrib dialog.
+ */
+static void disconnect_selection (Multiattrib *multiattrib) {
+  SELECTION *selection;
+
+  /* get selection watched from dialog data */
+  selection = (SELECTION*)g_object_get_data (G_OBJECT (multiattrib),
+                                             DIALOG_DATA_SELECTION);
+  if (selection == NULL) {
+    /* no selection watched */
+    return;
+  }
+
+  g_signal_handlers_disconnect_matched (selection,
+                                        G_SIGNAL_MATCH_FUNC |
+                                        G_SIGNAL_MATCH_DATA,
+                                        0, 0, NULL,
+                                        callback_selection_changed,
+                                        multiattrib);
+  g_object_weak_unref (G_OBJECT (selection),
+                       callback_selection_finalized,
+                       multiattrib);
+
+  /* reset dialog data */
+  g_object_set_data (G_OBJECT (multiattrib), DIALOG_DATA_SELECTION, NULL);
+}
+
 /*! \brief Process the response returned by the multi-attribte dialog.
  *  \par Function Description
  *  This function handles the response <B>arg1</B> of the multi-attribute
@@ -61,6 +201,8 @@ multiattrib_callback_response (GtkDialog *dialog,
   switch (arg1) {
       case GTK_RESPONSE_CLOSE:
       case GTK_RESPONSE_DELETE_EVENT:
+        /* cut link from dialog to selection */
+        disconnect_selection (MULTIATTRIB (w_current->mawindow));
         gtk_widget_destroy (GTK_WIDGET (dialog));
         w_current->mawindow = NULL;
         break;
@@ -76,20 +218,23 @@ multiattrib_callback_response (GtkDialog *dialog,
 void x_multiattrib_open (GSCHEM_TOPLEVEL *w_current)
 {
   if ( w_current->mawindow == NULL ) {
-    w_current->mawindow = GTK_WIDGET (g_object_new (TYPE_MULTIATTRIB,
-                                     "selection", w_current->toplevel->page_current->selection_list,
-                                      /* GschemDialog */
-                                      "settings-name", "multiattrib",
-                                      "gschem-toplevel", w_current,
-                                      NULL));
-
-      g_signal_connect (w_current->mawindow,
-                        "response",
-                        G_CALLBACK (multiattrib_callback_response),
-                        w_current);
-
-    gtk_window_set_transient_for (GTK_WINDOW(w_current->mawindow),
-                                  GTK_WINDOW(w_current->main_window));
+    w_current->mawindow =
+      GTK_WIDGET (g_object_new (TYPE_MULTIATTRIB,
+                                "object", NULL,
+                                /* GschemDialog */
+                                "settings-name", "multiattrib",
+                                "gschem-toplevel", w_current,
+                                /* GtkWindow */
+                                "transient-for", w_current->main_window,
+                                NULL));
+
+    g_signal_connect (w_current->mawindow,
+                      "response",
+                      G_CALLBACK (multiattrib_callback_response),
+                      w_current);
+
+    /* attach dialog to selection of current page */
+    x_multiattrib_update (w_current);
 
     gtk_widget_show (w_current->mawindow);
   } else {
@@ -109,12 +254,13 @@ void x_multiattrib_open (GSCHEM_TOPLEVEL *w_current)
 void x_multiattrib_close (GSCHEM_TOPLEVEL *w_current)
 {
   if (w_current->mawindow != NULL) {
+    /* cut link from dialog to selection */
+    disconnect_selection (MULTIATTRIB (w_current->mawindow));
     gtk_widget_destroy (w_current->mawindow);
     w_current->mawindow = NULL;
   }
 }
 
-
 /*! \brief Update the multiattrib editor dialog for a GSCHEM_TOPLEVEL.
  *
  *  \par Function Description
@@ -126,10 +272,15 @@ void x_multiattrib_close (GSCHEM_TOPLEVEL *w_current)
  */
 void x_multiattrib_update( GSCHEM_TOPLEVEL *w_current )
 {
-  if (w_current->mawindow != NULL) {
-    g_object_set (G_OBJECT (w_current->mawindow), "selection",
-                  w_current->toplevel->page_current->selection_list, NULL);
+  if (!IS_MULTIATTRIB (w_current->mawindow)) {
+    return;
   }
+
+  /* disconnect dialog from previous selection */
+  disconnect_selection (MULTIATTRIB (w_current->mawindow));
+  /* connect the dialog to the selection of the current page */
+  connect_selection (MULTIATTRIB (w_current->mawindow),
+                     w_current->toplevel->page_current->selection_list);
 }
 
 
@@ -428,7 +579,7 @@ static void cellrenderermultilinetext_class_init(CellRendererMultiLineTextClass
 
 
 enum {
-  PROP_SELECTION = 1
+  PROP_OBJECT = 1
 };
 
 enum {
@@ -1314,154 +1465,6 @@ GType multiattrib_get_type()
   return multiattrib_type;
 }
 
-
-/*! \brief Update the multiattrib editor dialog when the page's selection changes.
- *
- *  \par Function Description
- *
- *  When the page's selection changes this function identifies how many objects
- *  which can have attributes are currently selected. If this number is 1, the
- *  dialog is set to edit its attributes.
- *
- *  \todo The dialog doesn't currently support editing multiple objects at once
- *
- *  \param [in] selection    The SELECTION object of page being edited.
- *  \param [in] multiattrib  The multi-attribute editor dialog.
- */
-static void selection_changed_cb (SELECTION *selection, Multiattrib *multiattrib)
-{
-  int object_count = 0;
-  GList *selection_glist;
-  GList *iter;
-  OBJECT *object;
-
-  selection_glist = geda_list_get_glist (selection);
-
-  for ( iter = selection_glist;
-        iter != NULL;
-        iter = g_list_next (iter) ) {
-    object = (OBJECT *)iter->data;
-    g_assert( object != NULL );
-
-    if (object->type == OBJ_COMPLEX ||
-        object->type == OBJ_PLACEHOLDER ||
-        object->type == OBJ_NET ||
-        object->type == OBJ_BUS ||
-        object->type == OBJ_PIN) {
-      object_count++;
-    }
-  }
-
-  if (object_count == 0) {
-    /* TODO: If the user selects a single attribute which is
-     *       not floating, should we find its parent object and
-     *       display the multi-attribute editor for that?
-     *       Bonus marks for making it jump to the correct attrib.
-     */
-    multiattrib->object = NULL;
-  } else if (object_count == 1) {
-    multiattrib->object = (OBJECT *)selection_glist->data;
-  } else {
-    /* TODO: Something clever with multiple objects selected */
-    multiattrib->object = NULL;
-  }
-
-  multiattrib_update (multiattrib);
-}
-
-
-/*! \brief Update the dialog when the current page's SELECTION object is destroyed
- *
- *  \par Function Description
- *
- *  This handler is called when the g_object_weak_ref() on the SELECTION object
- *  we're watching expires. We reset our multiattrib->selection pointer to NULL
- *  to avoid attempting to access the destroyed object. NB: Our signal handlers
- *  were automatically disconnected during the destruction process.
- *
- *  \param [in] data                  Pointer to the multi-attrib dialog
- *  \param [in] where_the_object_was  Pointer to where the object was just destroyed
- */
-static void selection_weak_ref_cb (gpointer data, GObject *where_the_object_was)
-{
-  Multiattrib *multiattrib = (Multiattrib *)data;
-
-  multiattrib->selection = NULL;
-  multiattrib_update (multiattrib);
-}
-
-
-/*! \brief Connect signal handler and weak_ref on the SELECTION object
- *
- *  \par Function Description
- *
- *  Connect the "changed" signal and add a weak reference
- *  on the SELECTION object we are going to watch.
- *
- *  \param [in] multiattrib  The Multiattrib dialog.
- *  \param [in] selection    The SELECTION object to watch.
- */
-static void connect_selection( Multiattrib *multiattrib, SELECTION *selection )
-{
-  multiattrib->selection = selection;
-  if (multiattrib->selection != NULL) {
-    g_object_weak_ref (G_OBJECT (multiattrib->selection),
-                       selection_weak_ref_cb,
-                       multiattrib);
-    multiattrib->selection_changed_id =
-      g_signal_connect (G_OBJECT (multiattrib->selection),
-                        "changed",
-                        G_CALLBACK (selection_changed_cb),
-                        multiattrib);
-    /* Synthesise a selection changed update to refresh the view */
-    selection_changed_cb (multiattrib->selection, multiattrib);
-  } else {
-    /* Call an update to set the sensitivities */
-    multiattrib_update (multiattrib);
-  }
-}
-
-
-/*! \brief Disconnect signal handler and weak_ref on the SELECTION object
- *
- *  \par Function Description
- *
- *  If the dialog is watching a SELECTION object, disconnect the
- *  "changed" signal and remove our weak reference on the object.
- *
- *  \param [in] multiattrib  The Multiattrib dialog.
- */
-static void disconnect_selection( Multiattrib *multiattrib )
-{
-  if (multiattrib->selection != NULL) {
-    g_signal_handler_disconnect (multiattrib->selection,
-                                 multiattrib->selection_changed_id);
-    g_object_weak_unref(G_OBJECT( multiattrib->selection ),
-                        selection_weak_ref_cb,
-                        multiattrib );
-  }
-}
-
-
-/*! \brief GObject finalise handler
- *
- *  \par Function Description
- *
- *  Just before the Multiattrib GObject is finalized, disconnect from
- *  the SELECTION object being watched and then chain up to the parent
- *  class's finalize handler.
- *
- *  \param [in] object  The GObject being finalized.
- */
-static void multiattrib_finalize (GObject *object)
-{
-  Multiattrib *multiattrib = MULTIATTRIB(object);
-
-  disconnect_selection( multiattrib );
-  G_OBJECT_CLASS (multiattrib_parent_class)->finalize (object);
-}
-
-
 /*! \brief GType class initialiser for Multiattrib
  *
  *  \par Function Description
@@ -1479,11 +1482,10 @@ static void multiattrib_class_init(MultiattribClass *klass)
 
   gobject_class->set_property = multiattrib_set_property;
   gobject_class->get_property = multiattrib_get_property;
-  gobject_class->finalize     = multiattrib_finalize;
 
   g_object_class_install_property (
-    gobject_class, PROP_SELECTION,
-    g_param_spec_pointer ("selection",
+    gobject_class, PROP_OBJECT,
+    g_param_spec_pointer ("object",
                           "",
                           "",
                           G_PARAM_READWRITE));
@@ -1811,7 +1813,7 @@ static void multiattrib_init(Multiattrib *multiattrib)
 /*! \brief GObject property setter function
  *
  *  \par Function Description
- *  Setter function for Multiattrib's GObject property, "selection".
+ *  Setter function for Multiattrib's GObject property, "object".
  *
  *  \param [in]  object       The GObject whose properties we are setting
  *  \param [in]  property_id  The numeric id. under which the property was
@@ -1828,9 +1830,9 @@ static void multiattrib_set_property (GObject *object,
   Multiattrib *multiattrib = MULTIATTRIB (object);
 
   switch(property_id) {
-      case PROP_SELECTION:
-        disconnect_selection (multiattrib);
-        connect_selection (multiattrib, g_value_get_pointer (value));
+      case PROP_OBJECT:
+        multiattrib->object = (OBJECT*)g_value_get_pointer (value);
+        multiattrib_update (multiattrib);
         break;
       default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -1841,7 +1843,7 @@ static void multiattrib_set_property (GObject *object,
 /*! \brief GObject property getter function
  *
  *  \par Function Description
- *  Getter function for Multiattrib's GObject property, "selection".
+ *  Getter function for Multiattrib's GObject property, "object".
  *
  *  \param [in]  object       The GObject whose properties we are getting
  *  \param [in]  property_id  The numeric id. under which the property was
@@ -1857,8 +1859,8 @@ static void multiattrib_get_property (GObject *object,
   Multiattrib *multiattrib = MULTIATTRIB (object);
 
   switch(property_id) {
-      case PROP_SELECTION:
-        g_value_set_pointer (value, (gpointer)multiattrib->selection);
+      case PROP_OBJECT:
+        g_value_set_pointer (value, (gpointer)multiattrib->object);
         break;
       default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -1871,11 +1873,8 @@ static void multiattrib_get_property (GObject *object,
  *
  *  \par Function Description
  *
- *  Update the dialog to reflect the attributes of the currently selected
- *  object. If no (or multiple) objects are selected, the dialog's controls
- *  are set insensitive.
- *
- *  \todo The dialog doesn't currently support editing multiple objects at once
+ *  Update the dialog to reflect the attributes of the object. If
+ *  there is no object set, the dialog's controls are set insensitive.
  *
  *  \param [in] multiattrib  The multi-attribute editor dialog.
  */
@@ -1895,7 +1894,7 @@ void multiattrib_update (Multiattrib *multiattrib)
   gtk_list_store_clear (liststore);
 
   /* Update sensitivities */
-  sensitive = (multiattrib->selection != NULL && multiattrib->object != NULL);
+  sensitive = (multiattrib->object != NULL);
   gtk_widget_set_sensitive (GTK_WIDGET (multiattrib->frame_attributes), sensitive);
   gtk_widget_set_sensitive (GTK_WIDGET (multiattrib->frame_add), sensitive);
 

commit 95923f7de815ec58819eaf94ab9332d51a28fbb9
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:39 2008 +0200

    Simplify prototype of s_tile_remove_object().

diff --git a/libgeda/include/prototype.h b/libgeda/include/prototype.h
index 93a3d22..fa05ce9 100644
--- a/libgeda/include/prototype.h
+++ b/libgeda/include/prototype.h
@@ -478,7 +478,7 @@ void s_stretch_destroy_all(STRETCH *head);
 /* s_tile.c */
 void s_tile_init(TOPLEVEL *toplevel, PAGE *p_current);
 void s_tile_add_line_object(TOPLEVEL *toplevel, OBJECT *object);
-void s_tile_remove_object(TOPLEVEL *toplevel, PAGE *page, OBJECT *object);
+void s_tile_remove_object(OBJECT *object);
 void s_tile_update_object(TOPLEVEL *toplevel, OBJECT *object);
 GList *s_tile_get_objectlists(TOPLEVEL *toplevel, int world_x1, int world_y1, int world_x2, int world_y2);
 void s_tile_print(TOPLEVEL *toplevel);
diff --git a/libgeda/src/s_basic.c b/libgeda/src/s_basic.c
index c84e439..998a8a5 100644
--- a/libgeda/src/s_basic.c
+++ b/libgeda/src/s_basic.c
@@ -313,9 +313,7 @@ s_delete_object(TOPLEVEL *toplevel, OBJECT *o_current)
       g_free(o_current->line);
 
       /* yes this object might be in the tile system */
-      s_tile_remove_object(toplevel,
-                           toplevel->page_current,
-                           o_current);
+      s_tile_remove_object(o_current);
     }
     o_current->line = NULL;
 
diff --git a/libgeda/src/s_page.c b/libgeda/src/s_page.c
index 19c40fa..bbec414 100644
--- a/libgeda/src/s_page.c
+++ b/libgeda/src/s_page.c
@@ -138,21 +138,9 @@ PAGE *s_page_new (TOPLEVEL *toplevel, const gchar *filename)
  */
 void s_page_delete (TOPLEVEL *toplevel, PAGE *page)
 {
-  PAGE *tmp;
   gchar *backup_filename;
   gchar *real_filename;
 
-  /* we need to play with page_current because s_delete_list_fromstart() */
-  /* make use of it (see s_tile_remove_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);
   
@@ -218,15 +206,10 @@ void s_page_delete (TOPLEVEL *toplevel, PAGE *page)
   o_complex_free_filename(toplevel);
 #endif
 
-  /* restore page_current */
-  if (tmp != NULL) {
-    s_page_goto (toplevel, tmp);
-  } else {
-    /* page was page_current */
+  if (toplevel->page_current == page) {
+    /* page was page_current, page_current must be updated */
     toplevel->page_current = NULL;
-    /* page_current must be updated by calling function */
   }
-  
 }
 
 
diff --git a/libgeda/src/s_tile.c b/libgeda/src/s_tile.c
index 5a63a85..c6e350d 100644
--- a/libgeda/src/s_tile.c
+++ b/libgeda/src/s_tile.c
@@ -281,11 +281,8 @@ void s_tile_add_line_object (TOPLEVEL *toplevel, OBJECT *object)
  *  \brief
  *  \par Function Description
  *
- *  \bug
- *  this is still wrong, p_current needs to be the page the object is on 
- *  doesn't work if the current page isn't where the object lives
  */
-void s_tile_remove_object(TOPLEVEL *toplevel, PAGE *page, OBJECT *object)
+void s_tile_remove_object(OBJECT *object)
 {
   GList *tl_current;
 
@@ -310,7 +307,7 @@ void s_tile_remove_object(TOPLEVEL *toplevel, PAGE *page, OBJECT *object)
  */
 void s_tile_update_object(TOPLEVEL * toplevel, OBJECT * object)
 {
-  s_tile_remove_object(toplevel, toplevel->page_current, object);
+  s_tile_remove_object(object);
   s_tile_add_line_object(toplevel, object);
 }
 

commit ac56af89f55594a3739c16692bec4e5974848dc1
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:38 2008 +0200

    Replace TILE_LOC structure with list of references to TILEs.
    
    Removed structure TILE_LOC: now objects have a list of references to
    TILE structures.

diff --git a/libgeda/include/prototype.h b/libgeda/include/prototype.h
index a7df60d..93a3d22 100644
--- a/libgeda/include/prototype.h
+++ b/libgeda/include/prototype.h
@@ -477,7 +477,6 @@ void s_stretch_destroy_all(STRETCH *head);
 
 /* s_tile.c */
 void s_tile_init(TOPLEVEL *toplevel, PAGE *p_current);
-TILE_LOC *s_tile_new_loc(int i, int j);
 void s_tile_add_line_object(TOPLEVEL *toplevel, OBJECT *object);
 void s_tile_remove_object(TOPLEVEL *toplevel, PAGE *page, OBJECT *object);
 void s_tile_update_object(TOPLEVEL *toplevel, OBJECT *object);
diff --git a/libgeda/include/struct.h b/libgeda/include/struct.h
index 98cfbc8..8a9ad2f 100644
--- a/libgeda/include/struct.h
+++ b/libgeda/include/struct.h
@@ -42,7 +42,6 @@ typedef struct st_toplevel TOPLEVEL;
 typedef struct st_color COLOR;
 typedef struct st_undo UNDO;
 typedef struct st_tile TILE;
-typedef struct st_tile_loc TILE_LOC;
 
 typedef struct st_conn CONN;
 typedef struct st_bus_ripper BUS_RIPPER;
@@ -205,7 +204,7 @@ struct st_object {
   TEXT *text;
   PICTURE *picture;
 
-  GList *tile_locs;			/* tile locations */
+  GList *tiles;			/* tiles */
 
   GList *conn_list;			/* List of connections */
   /* to and from this object */
@@ -336,10 +335,6 @@ struct st_tile {
   int top, left, right, bottom;
 };
 
-struct st_tile_loc {
-  int i, j;	/* these are the indices into the tile structure */
-};
-
 struct st_page {
 
   int pid;
diff --git a/libgeda/src/s_basic.c b/libgeda/src/s_basic.c
index 8bce75c..c84e439 100644
--- a/libgeda/src/s_basic.c
+++ b/libgeda/src/s_basic.c
@@ -137,7 +137,7 @@ OBJECT *s_basic_init_object( char *name )
   new_node->text = NULL;
   new_node->complex = NULL;
 
-  new_node->tile_locs = NULL;
+  new_node->tiles = NULL;
 
   new_node->conn_list = NULL;
 
diff --git a/libgeda/src/s_conn.c b/libgeda/src/s_conn.c
index da1e10b..085bf1d 100644
--- a/libgeda/src/s_conn.c
+++ b/libgeda/src/s_conn.c
@@ -271,31 +271,22 @@ OBJECT *s_conn_check_midpoint(OBJECT *o_current, int x, int y)
 void s_conn_update_object(TOPLEVEL * toplevel, OBJECT * object)
 {
   TILE *t_current;
-  TILE_LOC *tl_current;
-  GList *tloc_list;
+  GList *tl_current;
   GList *object_list;
   OBJECT *other_object;
   OBJECT *found;
   CONN *new_conn;
-  int i, j;
   int k;
   int add_conn;
 
   /* loop over all tiles which object appears in */
-  tloc_list = object->tile_locs;
-  while (tloc_list != NULL) {
-    tl_current = (TILE_LOC *) tloc_list->data;
+  for (tl_current = object->tiles;
+       tl_current != NULL;
+       tl_current = g_list_next (tl_current)) {
+    t_current = (TILE*)tl_current->data;
 
     add_conn = FALSE;
     
-    i = tl_current->i;
-    j = tl_current->j;
-
-#if DEBUG
-    printf("\nInside tile: %d %d\n\n", i, j);
-#endif
-    
-    t_current = &toplevel->page_current->world_tiles[i][j];
     object_list = t_current->objects;
     while (object_list != NULL) {
       other_object = (OBJECT *) object_list->data;
@@ -670,8 +661,6 @@ void s_conn_update_object(TOPLEVEL * toplevel, OBJECT * object)
 
       object_list = g_list_next(object_list);
     } 
-
-    tloc_list = g_list_next(tloc_list);
   }
 
 #if DEBUG
diff --git a/libgeda/src/s_tile.c b/libgeda/src/s_tile.c
index 5e6268f..5a63a85 100644
--- a/libgeda/src/s_tile.c
+++ b/libgeda/src/s_tile.c
@@ -87,29 +87,11 @@ void s_tile_init(TOPLEVEL * toplevel, PAGE * p_current)
  *  \par Function Description
  *
  */
-TILE_LOC *s_tile_new_loc(int i, int j)
-{
-  TILE_LOC *tile_loc;
-
-  tile_loc = (TILE_LOC *) g_malloc(sizeof(TILE_LOC));
-
-  tile_loc->i = i;
-  tile_loc->j = j;
-
-  return (tile_loc);
-}
-
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
- */
 void s_tile_add_line_object (TOPLEVEL *toplevel, OBJECT *object)
 {
   TILE *t_current;
   PAGE *p_current;
   GList *found;
-  TILE_LOC *tile_loc;
   int i, j;
   int v, w;
   double x1, y1, x2, y2;
@@ -168,10 +150,7 @@ void s_tile_add_line_object (TOPLEVEL *toplevel, OBJECT *object)
           /*printf("%d %d\n", v, w);*/
           t_current->objects = g_list_append(t_current->objects,
                                              object);
-
-          tile_loc = s_tile_new_loc(v, w);
-          object->tile_locs = g_list_append(object->tile_locs,
-                                            tile_loc);
+          object->tiles = g_list_append(object->tiles, t_current);
         }
 
         v = (int) x;
@@ -187,9 +166,7 @@ void s_tile_add_line_object (TOPLEVEL *toplevel, OBJECT *object)
           /*printf("%d %d\n", v, w);*/
           t_current->objects = g_list_append(t_current->objects,
                                              object);
-          tile_loc = s_tile_new_loc(v, w);
-          object->tile_locs = g_list_append(object->tile_locs,
-                                            tile_loc);
+          object->tiles = g_list_append(object->tiles, t_current);
         }
 
       } else {
@@ -206,9 +183,7 @@ void s_tile_add_line_object (TOPLEVEL *toplevel, OBJECT *object)
           /*printf("%d %d\n", v, w);*/
           t_current->objects = g_list_append(t_current->objects,
                                              object);
-          tile_loc = s_tile_new_loc(v, w);
-          object->tile_locs = g_list_append(object->tile_locs,
-                                            tile_loc);
+          object->tiles = g_list_append(object->tiles, t_current);
         }
       }
     }
@@ -234,9 +209,7 @@ void s_tile_add_line_object (TOPLEVEL *toplevel, OBJECT *object)
             /*printf("%d %d\n", v, w);*/
             t_current->objects =
               g_list_append(t_current->objects, object);
-            tile_loc = s_tile_new_loc(v, w);
-            object->tile_locs =
-              g_list_append(object->tile_locs, tile_loc);
+            object->tiles = g_list_append(object->tiles, t_current);
           }
 
           w = (int) y;
@@ -253,9 +226,7 @@ void s_tile_add_line_object (TOPLEVEL *toplevel, OBJECT *object)
             /*printf("%d %d\n", v, w);*/
             t_current->objects =
               g_list_append(t_current->objects, object);
-            tile_loc = s_tile_new_loc(v, w);
-            object->tile_locs =
-              g_list_append(object->tile_locs, tile_loc);
+            object->tiles = g_list_append(object->tiles, t_current);
           }
 
         } else {
@@ -273,9 +244,7 @@ void s_tile_add_line_object (TOPLEVEL *toplevel, OBJECT *object)
             /*printf("%d %d\n", v, w);*/
             t_current->objects =
               g_list_append(t_current->objects, object);
-            tile_loc = s_tile_new_loc(v, w);
-            object->tile_locs =
-              g_list_append(object->tile_locs, tile_loc);
+            object->tiles = g_list_append(object->tiles, t_current);
           }
         }
       }
@@ -301,9 +270,7 @@ void s_tile_add_line_object (TOPLEVEL *toplevel, OBJECT *object)
         /*printf("%d %d\n", v, w);*/
         t_current->objects = g_list_append(t_current->objects,
                                            object);
-        tile_loc = s_tile_new_loc(v, w);
-        object->tile_locs = g_list_append(object->tile_locs,
-                                          tile_loc);
+        object->tiles = g_list_append(object->tiles, t_current);
       }
 
     }
@@ -320,37 +287,20 @@ void s_tile_add_line_object (TOPLEVEL *toplevel, OBJECT *object)
  */
 void s_tile_remove_object(TOPLEVEL *toplevel, PAGE *page, OBJECT *object)
 {
-  TILE *t_current;
-  TILE_LOC *tl_current;
-  GList *tloc_list;
-  GList *found;
-  int i, j;
-
-  tloc_list = object->tile_locs;
-  while (tloc_list != NULL) {
-
-    tl_current = (TILE_LOC *) tloc_list->data;
-        
-    i = tl_current->i;
-    j = tl_current->j;
-
-    g_free(tl_current);
+  GList *tl_current;
 
-    t_current = &page->world_tiles[i][j];
-    t_current->objects = g_list_remove(t_current->objects, object);
-
-#if 1 
-    found = g_list_find(t_current->objects, object);
-    if (found) {
-      printf("found an object left over %s in %d, %d\nPlease e-mail ahvezda@xxxxxxxxxxxxx with this error message and .sch\n", object->name, i, j);
-    }
-#endif
+  for (tl_current = object->tiles;
+       tl_current != NULL;
+       tl_current = g_list_next (tl_current)) {
+    TILE *t_current = (TILE*)tl_current->data;
     
-    tloc_list = g_list_next(tloc_list);
+    /* remove object from the list of objects for this tile */
+    t_current->objects = g_list_remove(t_current->objects, object);
   }
 
-  g_list_free(tloc_list);
-  object->tile_locs = NULL;
+  /* reset the list of tiles for this object appears in */
+  g_list_free(object->tiles);
+  object->tiles = NULL;
 }
 
 /*! \todo Finish function documentation!!!
@@ -426,9 +376,7 @@ void s_tile_print(TOPLEVEL * toplevel)
 {
   TILE *t_current;
   GList *temp;
-  GList *temp2;
   OBJECT *o_current;
-  TILE_LOC *tloc;
   int i, j;
 
   for (j = 0; j < MAX_TILES_Y; j++) {
@@ -442,12 +390,6 @@ void s_tile_print(TOPLEVEL * toplevel)
         o_current = (OBJECT *) temp->data;
 
         printf("%s\n", o_current->name);
-        temp2 = o_current->tile_locs;
-        while (temp2 != NULL) {
-          tloc = (TILE_LOC *) temp2->data;
-          printf("	%d %d\n", tloc->i, tloc->j);
-          temp2 = g_list_next(temp2);
-        }
 
         temp = g_list_next(temp);
       }

commit 1cc266bbe45846030205aa8931cea40fe2dbdf3b
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:37 2008 +0200

    Rename s_tile_add_object() to s_tile_add_line_object() and simplify prototype.

diff --git a/libgeda/include/prototype.h b/libgeda/include/prototype.h
index b034ea5..a7df60d 100644
--- a/libgeda/include/prototype.h
+++ b/libgeda/include/prototype.h
@@ -478,7 +478,7 @@ void s_stretch_destroy_all(STRETCH *head);
 /* s_tile.c */
 void s_tile_init(TOPLEVEL *toplevel, PAGE *p_current);
 TILE_LOC *s_tile_new_loc(int i, int j);
-void s_tile_add_object(TOPLEVEL *toplevel, OBJECT *object, int world_x1, int world_y1, int world_x2, int world_y2);
+void s_tile_add_line_object(TOPLEVEL *toplevel, OBJECT *object);
 void s_tile_remove_object(TOPLEVEL *toplevel, PAGE *page, OBJECT *object);
 void s_tile_update_object(TOPLEVEL *toplevel, OBJECT *object);
 GList *s_tile_get_objectlists(TOPLEVEL *toplevel, int world_x1, int world_y1, int world_x2, int world_y2);
diff --git a/libgeda/src/o_bus_basic.c b/libgeda/src/o_bus_basic.c
index 987472e..9a4d8e6 100644
--- a/libgeda/src/o_bus_basic.c
+++ b/libgeda/src/o_bus_basic.c
@@ -80,9 +80,7 @@ OBJECT *o_bus_add(TOPLEVEL *toplevel, OBJECT *object_list,
 
   object_list = (OBJECT *) s_basic_link_object(new_node, object_list);
 
-  s_tile_add_object(toplevel, object_list,
-                    new_node->line->x[0], new_node->line->y[0], 
-                    new_node->line->x[1], new_node->line->y[1]);
+  s_tile_add_line_object(toplevel, object_list);
 
   if (!toplevel->ADDING_SEL) {
     s_conn_update_object(toplevel, object_list);
diff --git a/libgeda/src/o_net_basic.c b/libgeda/src/o_net_basic.c
index bf6c919..1538a0b 100644
--- a/libgeda/src/o_net_basic.c
+++ b/libgeda/src/o_net_basic.c
@@ -93,9 +93,7 @@ OBJECT *o_net_add(TOPLEVEL *toplevel, OBJECT *object_list, char type,
 
 
   if (!toplevel->ADDING_SEL) {
-    s_tile_add_object(toplevel, object_list,
-		      new_node->line->x[0], new_node->line->y[0],
-		      new_node->line->x[1], new_node->line->y[1]);
+    s_tile_add_line_object(toplevel, object_list);
     s_conn_update_object(toplevel, object_list);
   }
 
diff --git a/libgeda/src/o_pin_basic.c b/libgeda/src/o_pin_basic.c
index 7e7f258..e58e1f7 100644
--- a/libgeda/src/o_pin_basic.c
+++ b/libgeda/src/o_pin_basic.c
@@ -79,9 +79,7 @@ OBJECT *o_pin_add(TOPLEVEL *toplevel, OBJECT *object_list,
   object_list = (OBJECT *) s_basic_link_object(new_node, object_list);
 
   if (!toplevel->ADDING_SEL) {
-    s_tile_add_object(toplevel, object_list,
-                      new_node->line->x[0], new_node->line->y[0], 
-                      new_node->line->x[1], new_node->line->y[1]);
+    s_tile_add_line_object(toplevel, object_list);
     s_conn_update_object(toplevel, object_list);
   }
 
diff --git a/libgeda/src/s_tile.c b/libgeda/src/s_tile.c
index a161fc5..5e6268f 100644
--- a/libgeda/src/s_tile.c
+++ b/libgeda/src/s_tile.c
@@ -104,8 +104,7 @@ TILE_LOC *s_tile_new_loc(int i, int j)
  *  \par Function Description
  *
  */
-void s_tile_add_object(TOPLEVEL * toplevel, OBJECT * object, int world_x1,
-		       int world_y1, int world_x2, int world_y2)
+void s_tile_add_line_object (TOPLEVEL *toplevel, OBJECT *object)
 {
   TILE *t_current;
   PAGE *p_current;
@@ -124,6 +123,9 @@ void s_tile_add_object(TOPLEVEL * toplevel, OBJECT * object, int world_x1,
   printf("name: %s\n", object->name);
 #endif
 
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (object->line != NULL);
+
   if (toplevel->ADDING_SEL) {
 #if DEBUG    
     printf("s_tile_add_object, adding sel TRUE\n");
@@ -134,10 +136,10 @@ void s_tile_add_object(TOPLEVEL * toplevel, OBJECT * object, int world_x1,
   x_size = (double) toplevel->init_right / (double) MAX_TILES_X;
   y_size = (double) toplevel->init_bottom / (double) MAX_TILES_Y;
 
-  x1 = (int) (world_x1 / x_size);
-  x2 = (int) (world_x2 / x_size);
-  y1 = (int) (world_y1 / y_size);
-  y2 = (int) (world_y2 / y_size);
+  x1 = (int) (object->line->x[0] / x_size);
+  x2 = (int) (object->line->x[1] / x_size);
+  y1 = (int) (object->line->y[0] / y_size);
+  y2 = (int) (object->line->y[1] / y_size);
 
   bottom = x2 - x1;
   p_current = toplevel->page_current;
@@ -359,9 +361,7 @@ void s_tile_remove_object(TOPLEVEL *toplevel, PAGE *page, OBJECT *object)
 void s_tile_update_object(TOPLEVEL * toplevel, OBJECT * object)
 {
   s_tile_remove_object(toplevel, toplevel->page_current, object);
-  s_tile_add_object(toplevel, object,
-                    object->line->x[0], object->line->y[0],
-                    object->line->x[1], object->line->y[1]);
+  s_tile_add_line_object(toplevel, object);
 }
 
 

commit 7e4d443eea54c8fc19833aa67ae64ed1ffba0e80
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:36 2008 +0200

    Rename s_tile_remove_object_all() to s_tile_remove_object().

diff --git a/libgeda/include/prototype.h b/libgeda/include/prototype.h
index f9717b5..b034ea5 100644
--- a/libgeda/include/prototype.h
+++ b/libgeda/include/prototype.h
@@ -479,7 +479,7 @@ void s_stretch_destroy_all(STRETCH *head);
 void s_tile_init(TOPLEVEL *toplevel, PAGE *p_current);
 TILE_LOC *s_tile_new_loc(int i, int j);
 void s_tile_add_object(TOPLEVEL *toplevel, OBJECT *object, int world_x1, int world_y1, int world_x2, int world_y2);
-void s_tile_remove_object_all(TOPLEVEL *toplevel, PAGE *p_current, OBJECT *object);
+void s_tile_remove_object(TOPLEVEL *toplevel, PAGE *page, OBJECT *object);
 void s_tile_update_object(TOPLEVEL *toplevel, OBJECT *object);
 GList *s_tile_get_objectlists(TOPLEVEL *toplevel, int world_x1, int world_y1, int world_x2, int world_y2);
 void s_tile_print(TOPLEVEL *toplevel);
diff --git a/libgeda/src/s_basic.c b/libgeda/src/s_basic.c
index 468bca4..8bce75c 100644
--- a/libgeda/src/s_basic.c
+++ b/libgeda/src/s_basic.c
@@ -313,9 +313,9 @@ s_delete_object(TOPLEVEL *toplevel, OBJECT *o_current)
       g_free(o_current->line);
 
       /* yes this object might be in the tile system */
-      s_tile_remove_object_all(toplevel,
-                               toplevel->page_current,
-                               o_current);
+      s_tile_remove_object(toplevel,
+                           toplevel->page_current,
+                           o_current);
     }
     o_current->line = NULL;
 
diff --git a/libgeda/src/s_page.c b/libgeda/src/s_page.c
index cca15c6..19c40fa 100644
--- a/libgeda/src/s_page.c
+++ b/libgeda/src/s_page.c
@@ -143,7 +143,7 @@ void s_page_delete (TOPLEVEL *toplevel, PAGE *page)
   gchar *real_filename;
 
   /* we need to play with page_current because s_delete_list_fromstart() */
-  /* make use of it (see s_tile_remove_object_all) */
+  /* make use of it (see s_tile_remove_object) */
 
   /* save page_current and switch to page */
   if (page == toplevel->page_current) {
diff --git a/libgeda/src/s_tile.c b/libgeda/src/s_tile.c
index 09ad19d..a161fc5 100644
--- a/libgeda/src/s_tile.c
+++ b/libgeda/src/s_tile.c
@@ -316,8 +316,7 @@ void s_tile_add_object(TOPLEVEL * toplevel, OBJECT * object, int world_x1,
  *  this is still wrong, p_current needs to be the page the object is on 
  *  doesn't work if the current page isn't where the object lives
  */
-void s_tile_remove_object_all(TOPLEVEL * toplevel, PAGE *p_current,
-                              OBJECT * object)
+void s_tile_remove_object(TOPLEVEL *toplevel, PAGE *page, OBJECT *object)
 {
   TILE *t_current;
   TILE_LOC *tl_current;
@@ -335,7 +334,7 @@ void s_tile_remove_object_all(TOPLEVEL * toplevel, PAGE *p_current,
 
     g_free(tl_current);
 
-    t_current = &p_current->world_tiles[i][j];
+    t_current = &page->world_tiles[i][j];
     t_current->objects = g_list_remove(t_current->objects, object);
 
 #if 1 
@@ -359,7 +358,7 @@ void s_tile_remove_object_all(TOPLEVEL * toplevel, PAGE *p_current,
  */
 void s_tile_update_object(TOPLEVEL * toplevel, OBJECT * object)
 {
-  s_tile_remove_object_all(toplevel, toplevel->page_current, object);
+  s_tile_remove_object(toplevel, toplevel->page_current, object);
   s_tile_add_object(toplevel, object,
                     object->line->x[0], object->line->y[0],
                     object->line->x[1], object->line->y[1]);

commit e2278f9ed3c49d6226e3e721e55a940cbaed53f3
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:35 2008 +0200

    Remove unused function s_tile_remove_object_all_crude().

diff --git a/libgeda/include/prototype.h b/libgeda/include/prototype.h
index 1f6743e..f9717b5 100644
--- a/libgeda/include/prototype.h
+++ b/libgeda/include/prototype.h
@@ -479,7 +479,6 @@ void s_stretch_destroy_all(STRETCH *head);
 void s_tile_init(TOPLEVEL *toplevel, PAGE *p_current);
 TILE_LOC *s_tile_new_loc(int i, int j);
 void s_tile_add_object(TOPLEVEL *toplevel, OBJECT *object, int world_x1, int world_y1, int world_x2, int world_y2);
-void s_tile_remove_object_all_crude(TOPLEVEL *toplevel, OBJECT *object);
 void s_tile_remove_object_all(TOPLEVEL *toplevel, PAGE *p_current, OBJECT *object);
 void s_tile_update_object(TOPLEVEL *toplevel, OBJECT *object);
 GList *s_tile_get_objectlists(TOPLEVEL *toplevel, int world_x1, int world_y1, int world_x2, int world_y2);
diff --git a/libgeda/src/s_tile.c b/libgeda/src/s_tile.c
index 8ed1ff3..09ad19d 100644
--- a/libgeda/src/s_tile.c
+++ b/libgeda/src/s_tile.c
@@ -312,25 +312,6 @@ void s_tile_add_object(TOPLEVEL * toplevel, OBJECT * object, int world_x1,
  *  \brief
  *  \par Function Description
  *
- */
-void s_tile_remove_object_all_crude(TOPLEVEL * toplevel, OBJECT * object)
-{
-  TILE *t_current;
-
-  int i, j;
-
-  for (j = 0; j < MAX_TILES_Y; j++) {
-    for (i = 0; i < MAX_TILES_X; i++) {
-      t_current = &toplevel->page_current->world_tiles[i][j];
-      t_current->objects = g_list_remove(t_current->objects, object);
-    }
-  }
-}
-
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
  *  \bug
  *  this is still wrong, p_current needs to be the page the object is on 
  *  doesn't work if the current page isn't where the object lives

commit 4ad46d1b431bceb665fdd45778345118dfc1d414
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:34 2008 +0200

    Limit scope of gschem x_color_allocate_all().

diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index e4405f5..fb34a70 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -736,7 +736,6 @@ void x_vscrollbar_update(GSCHEM_TOPLEVEL *w_current);
 void x_scrollbars_update(GSCHEM_TOPLEVEL *w_current);
 void x_basic_warp_cursor(GtkWidget *widget, gint x, gint y, gboolean relative);
 /* x_color.c */
-void x_color_allocate_all(void);
 void x_color_init (void);
 void x_color_free (void);
 GdkColor *x_get_color(int color);
diff --git a/gschem/src/x_color.c b/gschem/src/x_color.c
index 7ca51a2..aa51d14 100644
--- a/gschem/src/x_color.c
+++ b/gschem/src/x_color.c
@@ -37,6 +37,7 @@
 
 extern COLOR colors[MAX_COLORS];
 
+static void x_color_allocate_all(void);
 
 /*! \brief Initializes the color system for the application.
  *  \par Function Documentation
@@ -88,7 +89,7 @@ x_color_free (void)
  *  \par Function Documentation
  *
  */
-void x_color_allocate_all(void)
+static void x_color_allocate_all(void)
 {
   int error;
   int i;		

commit 67bb084eef2f0e97bd9573fdea0faa5dfd2e53bc
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:33 2008 +0200

    Move color-related stuff from x_window.c to x_color.c.
    
    Renamed x_window_setup_colors() and x_window_free_colors() to
    x_color_init() and x_color_free() respectively. And moved them to
    x_color.c

diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index e2d71c3..e4405f5 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -737,6 +737,8 @@ void x_scrollbars_update(GSCHEM_TOPLEVEL *w_current);
 void x_basic_warp_cursor(GtkWidget *widget, gint x, gint y, gboolean relative);
 /* x_color.c */
 void x_color_allocate_all(void);
+void x_color_init (void);
+void x_color_free (void);
 GdkColor *x_get_color(int color);
 GdkColor *x_get_darkcolor(int color);
 gchar *x_color_get_name(int index);
@@ -847,8 +849,6 @@ void x_stroke_record (GSCHEM_TOPLEVEL *w_current, gint x, gint y);
 gint x_stroke_translate_and_execute (GSCHEM_TOPLEVEL *w_current);
 /* x_window.c */
 void x_window_setup (GSCHEM_TOPLEVEL *w_current);
-void x_window_setup_colors(void);
-void x_window_free_colors();
 void x_window_setup_gc(GSCHEM_TOPLEVEL *w_current);
 void x_window_free_gc(GSCHEM_TOPLEVEL *w_current);
 void x_window_create_drawing(GtkWidget *drawbox, GSCHEM_TOPLEVEL *w_current);
diff --git a/gschem/src/gschem.c b/gschem/src/gschem.c
index 80ebd06..2ae8d51 100644
--- a/gschem/src/gschem.c
+++ b/gschem/src/gschem.c
@@ -248,7 +248,7 @@ void main_prog(void *closure, int argc, char *argv[])
 
   /* At end, complete set up of window. */
   colormap = gdk_colormap_get_system ();
-  x_window_setup_colors();
+  x_color_init();
   x_window_setup (w_current);
 
   /* Repaint the background in-case we have to throw up a "restore backup?"
diff --git a/gschem/src/x_color.c b/gschem/src/x_color.c
index 8205c65..7ca51a2 100644
--- a/gschem/src/x_color.c
+++ b/gschem/src/x_color.c
@@ -37,6 +37,52 @@
 
 extern COLOR colors[MAX_COLORS];
 
+
+/*! \brief Initializes the color system for the application.
+ *  \par Function Documentation
+ *  This function initializes the default \b black and \b white color.
+ *
+ *  It also allocates the colormap.
+ */
+void
+x_color_init (void)
+{
+  gdk_color_parse ("black", &black);
+  if (!gdk_colormap_alloc_color (colormap,
+                                 &black,
+                                 FALSE,
+                                 TRUE)) {
+    fprintf (stderr, _("Could not allocate the color %s!\n"), _("black"));
+    exit (-1);
+  }
+
+  gdk_color_parse ("white", &white);
+  if (!gdk_colormap_alloc_color (colormap,
+                                 &white,
+                                 FALSE,
+                                 TRUE)) {
+    fprintf (stderr, _("Could not allocate the color %s!\n"), _("white"));
+    exit (-1);
+  }
+
+  x_color_allocate_all ();
+
+}
+
+/*! \brief Frees memory used by the color system.
+ *  \par Function Documentation
+ *  This function frees the colors from colormap along with
+ *  \b black and \b white.
+ */
+void
+x_color_free (void)
+{
+  GdkColor *colors[] = { &black, &white };
+
+  gdk_colormap_free_colors (colormap, *colors, 2);
+
+}
+
 /*! \todo Finish function documentation!!!
  *  \brief
  *  \par Function Documentation
diff --git a/gschem/src/x_window.c b/gschem/src/x_window.c
index 814cf1d..afafbb6 100644
--- a/gschem/src/x_window.c
+++ b/gschem/src/x_window.c
@@ -76,48 +76,6 @@ void x_window_setup (GSCHEM_TOPLEVEL *w_current)
  *  \par Function Description
  *
  */
-void x_window_setup_colors(void)
-{
-  gdk_color_parse ("black", &black);
-  if (!gdk_colormap_alloc_color (colormap,
-                                 &black,
-                                 FALSE,
-                                 TRUE)) {
-    fprintf (stderr, _("Could not allocate the color %s!\n"), _("black"));
-    exit (-1);
-  }
-
-  gdk_color_parse ("white", &white);
-  if (!gdk_colormap_alloc_color (colormap,
-                                 &white,
-                                 FALSE,
-                                 TRUE)) {
-    fprintf (stderr, _("Could not allocate the color %s!\n"), _("white"));
-    exit (-1);
-  }
-
-  x_color_allocate_all ();
-
-}
-
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
- */
-void x_window_free_colors()
-{
-  GdkColor *colors[] = { &black, &white };
-  
-  gdk_colormap_free_colors (colormap, *colors, 2);
-  
-}
-
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
- */
 void x_window_setup_gc(GSCHEM_TOPLEVEL *w_current)
 {
   GdkGCValues     values;

commit d96ad3c39121d6c7e32128493d5445f0825f1751
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:32 2008 +0200

    Cleanup the stroke interface.
    
    Improved the API and memory allocation, added documentation.

diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index a9628b8..e2d71c3 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -841,10 +841,10 @@ void x_print_setup(GSCHEM_TOPLEVEL *w_current, char *filename);
 /* x_script.c */
 void setup_script_selector(GSCHEM_TOPLEVEL *w_current);
 /* x_stroke.c */
-void x_stroke_add_point(GSCHEM_TOPLEVEL *w_current, int x, int y);
-void x_stroke_erase_all(GSCHEM_TOPLEVEL *w_current);
-void x_stroke_free_all(void);
-int x_stroke_search_execute(char *sequence);
+void x_stroke_init (void);
+void x_stroke_free (void);
+void x_stroke_record (GSCHEM_TOPLEVEL *w_current, gint x, gint y);
+gint x_stroke_translate_and_execute (GSCHEM_TOPLEVEL *w_current);
 /* x_window.c */
 void x_window_setup (GSCHEM_TOPLEVEL *w_current);
 void x_window_setup_colors(void);
diff --git a/gschem/src/gschem.c b/gschem/src/gschem.c
index d350903..80ebd06 100644
--- a/gschem/src/gschem.c
+++ b/gschem/src/gschem.c
@@ -44,11 +44,6 @@
 #include <locale.h>
 #endif
 
-#ifdef HAS_LIBSTROKE
-/* libstroke prototype */
-void stroke_init(void);
-#endif
-
 typedef struct {
   gschem_atexit_func func;
   gpointer arg;
@@ -103,7 +98,9 @@ void gschem_quit(void)
   /* o_text_freeallfonts();*/
   s_attrib_free();
   s_papersizes_free();
-  x_stroke_free_all();
+#ifdef HAS_LIBSTROKE
+  x_stroke_free ();
+#endif /* HAS_LIBSTROKE */
   s_color_destroy_all();
   o_undo_cleanup();
   /* s_stroke_free(); no longer needed */
@@ -177,11 +174,6 @@ void main_prog(void *closure, int argc, char *argv[])
   s_log_init (filename);
   g_free (filename);
 
-#ifdef HAS_LIBSTROKE
-  stroke_init(); /* libstroke function */
-  /* s_stroke_init(); no longer needed libgeda function */
-#endif
-	
   s_log_message(
                 _("gEDA/gschem version %s%s.%s\n"), PREPEND_VERSION_STRING,
                 DOTTED_VERSION, DATE_VERSION);
@@ -268,6 +260,10 @@ void main_prog(void *closure, int argc, char *argv[])
   x_repaint_background (w_current);
   w_current->grid = save_grid;
 
+#ifdef HAS_LIBSTROKE
+  x_stroke_init ();
+#endif /* HAS_LIBSTROKE */
+
   for (i = argv_index; i < argc; i++) {
 
     if (g_path_is_absolute(argv[i]))
diff --git a/gschem/src/x_event.c b/gschem/src/x_event.c
index d087a57..a1015c7 100644
--- a/gschem/src/x_event.c
+++ b/gschem/src/x_event.c
@@ -42,16 +42,8 @@ int throttle = 0;
 
 /* used for the stroke stuff */
 #ifdef HAS_LIBSTROKE
-
-#define MAX_SEQUENCE 20
 static int DOING_STROKE = FALSE;
-char sequence[MAX_SEQUENCE+1];
-
-/* libstroke prototypes */
-void stroke_init (void);
-void stroke_record (int x, int y);
-int stroke_trans (char *sequence);
-#endif
+#endif /* HAS_LIBSTROKE */
 
 /*! \todo Finish function documentation!!!
  *  \brief
@@ -426,8 +418,8 @@ gint x_event_button_pressed(GtkWidget *widget, GdkEventButton *event,
       case(STROKE):
       DOING_STROKE=TRUE;
       break;
+#endif /* HAS_LIBSTROKE */
 
-#endif
       case(MID_MOUSEPAN_ENABLED):
       w_current->event_state = MOUSEPAN; /* start */
       w_current->inside_action = 1;
@@ -717,37 +709,10 @@ gint x_event_button_released(GtkWidget *widget, GdkEventButton *event,
 
 #ifdef HAS_LIBSTROKE
       case(STROKE):
-
       DOING_STROKE = FALSE;
-
-      if (stroke_trans (sequence) == TRUE) {
-        if (stroke_info_mode) {
-          printf ("LibStroke Translation"
-                  " succeeded: ");
-        }
-      } else {
-        if (stroke_info_mode) {
-          printf ("LibStroke Translation"
-                  " failed: ");
-        }
-      }
-
-      if (stroke_info_mode) {
-        printf ("Sequence=\"%s\"\n",sequence);
-      }
-
-      x_stroke_erase_all(w_current);
-
-                                /* new way written by Stefan Petersen */
-                                /* much better */
-      if (x_stroke_search_execute(sequence)) {
-
-        if (stroke_info_mode) {
-          printf("Sequence understood\n");
-        }
-      }
+      x_stroke_translate_and_execute (w_current);
       break;
-#endif
+#endif /* HAS_LIBSTROKE */
 
       case(MID_MOUSEPAN_ENABLED):
       w_current->doing_pan=FALSE;
@@ -811,12 +776,10 @@ gint x_event_motion(GtkWidget *widget, GdkEventMotion *event,
 
 #ifdef HAS_LIBSTROKE
   if (DOING_STROKE == TRUE) {
-    x_stroke_add_point(w_current, (int) event->x, (int) event->y);
-
-    stroke_record ((int) event->x, (int) event->y);
+    x_stroke_record (w_current, event->x, event->y);
     return(0);
   }
-#endif
+#endif /* HAS_LIBSTROKE */
 
   /* skip the moving event if there are other moving events in the
      gdk event queue (Werner)
diff --git a/gschem/src/x_stroke.c b/gschem/src/x_stroke.c
index a557761..fe247a8 100644
--- a/gschem/src/x_stroke.c
+++ b/gschem/src/x_stroke.c
@@ -19,8 +19,6 @@
  */
 #include <config.h>
 
-#include <math.h>
-
 #include <libgeda/libgeda.h>
 
 #include "../include/gschem_struct.h"
@@ -31,118 +29,140 @@
 #include <dmalloc.h>
 #endif
 
-typedef struct st_stroke_point STROKE_POINT;
+#ifdef HAS_LIBSTROKE
+#include <stroke.h>
+
+/*
+ * <B>stroke_points</B> is an array of points for the stroke
+ * footprints. The points of the stroke are displayed over the display
+ * area of the main window. They have to be erased when the stroke is
+ * translated and the sequence evaluated.
+ *
+ * Its size will never exceed <B>STROKE_MAX_POINTS</B> (the limit in
+ * number of points of a stroke provided by libstroke).
+ */
+typedef struct {
+  gint x, y;
+} StrokePoint;
 
-struct st_stroke_point {
-        int x, y;
-        STROKE_POINT *next;
-};
+static GArray *stroke_points = NULL;
 
-static STROKE_POINT *stroke_points = NULL;
 
-/*! \todo Finish function documentation!!!
- *  \brief
+/*! \brief Initializes the stroke interface.
  *  \par Function Description
+ *  This is the initialization function for the stroke interface. It
+ *  initializes the libstroke library and prepare an array of points
+ *  for the mouse footprints.
  *
+ *  This function has to be called only once at application
+ *  initialization before any use of the stroke interface.
  */
-void x_stroke_add_point(GSCHEM_TOPLEVEL *w_current, int x, int y)
+void
+x_stroke_init (void)
 {
-  STROKE_POINT *new_point;
+  g_return_if_fail (stroke_points == NULL);
 
-  new_point = (STROKE_POINT *) g_malloc(sizeof(STROKE_POINT));
+  stroke_init ();
 
-  new_point->x = x;
-  new_point->y = y;
-
-  if (stroke_points == NULL) {
-    stroke_points = new_point;
-    stroke_points->next = NULL;
-  } else {
-    new_point->next = stroke_points;
-    stroke_points = new_point;
-  }
+  stroke_points = g_array_new (FALSE,
+                               FALSE,
+                               sizeof (StrokePoint));
+}
 
-  gdk_gc_set_foreground(w_current->gc,
-                        x_get_color(w_current->stroke_color));
+/*! \brief Frees memory of the stroke interface.
+ *  \par Function Description
+ *  This function frees the memory used for the mouse footprint
+ *  points. It terminates the use of the stroke interface.
+ */
+void
+x_stroke_free (void)
+{
+  g_return_if_fail (stroke_points != NULL);
 
-  gdk_draw_point(w_current->backingstore, w_current->gc, x, y);
-  o_invalidate_rect (w_current, x, y, x, y);
+  g_array_free (stroke_points, TRUE);
+  stroke_points = NULL;
 }
 
-/*! \todo Finish function documentation!!!
- *  \brief
+/*! \brief Records a new point for the stroke.
  *  \par Function Description
+ *  This function adds the point (<B>x</B>,<B>y</B>) as a new point in
+ *  the stroke.
  *
- *  \note
- *  traverse list as well as free each point as you go along
+ * The footprint is updated and the new point is drawn on the drawing area.
+ *
+ *  \param [in] w_current The GSCHEM_TOPLEVEL object.
+ *  \param [in] x        The X coord of the new point.
+ *  \param [in] Y        The X coord of the new point.
  */
-void x_stroke_erase_all(GSCHEM_TOPLEVEL *w_current)
+void
+x_stroke_record (GSCHEM_TOPLEVEL *w_current, gint x, gint y)
 {
-  STROKE_POINT *temp;
-
-  while(stroke_points != NULL) {
+  g_assert (stroke_points != NULL);
 
-#if DEBUG
-    printf("%d %d\n", stroke_points->x, stroke_points->y);
-#endif
+  stroke_record (x, y);
 
-    /* was xor, wasn't working out... see above note */
-    gdk_gc_set_foreground(
-                          w_current->gc,
-                          x_get_color(w_current->toplevel->background_color));
+  if (stroke_points->len < STROKE_MAX_POINTS) {
+    StrokePoint point = { x, y };
 
-    gdk_draw_point(w_current->backingstore, w_current->gc,
-                   stroke_points->x, stroke_points->y);
-    o_invalidate_rect (w_current, stroke_points->x, stroke_points->y,
-                                  stroke_points->x, stroke_points->y);
+    g_array_append_val (stroke_points, point);
 
-    temp = stroke_points;
-    stroke_points = stroke_points->next;
-    g_free(temp);
+    gdk_gc_set_foreground (w_current->gc,
+                           x_get_color (w_current->stroke_color));
+    gdk_draw_point (w_current->window, w_current->gc, x, y);
   }
 
-  stroke_points = NULL;
 }
 
-/*! \todo Finish function documentation!!!
- *  \brief
+/*! \brief Evaluates the stroke.
  *  \par Function Description
+ *  This function transforms the stroke input so far in an action.
+ *
+ *  It makes use of the guile procedure <B>eval-stroke</B> to evaluate
+ *  the stroke sequence into a possible action. The mouse footprint is
+ *  erased in this function.
  *
+ *  It returns 1 if the stroke has been successfully evaluated as an
+ *  action. It returns 0 if libstroke failed to transform the stroke
+ *  or there is no action attached to the stroke.
+ *
+ *  \param [in] w_current The GSCHEM_TOPLEVEL object.
+ *  \returns 1 on success, 0 otherwise.
  */
-void x_stroke_free_all(void)
+gint
+x_stroke_translate_and_execute (GSCHEM_TOPLEVEL *w_current)
 {
-  STROKE_POINT *temp;
+  gchar sequence[STROKE_MAX_SEQUENCE];
+  gint i;
 
-  while(stroke_points != NULL) {
-#if DEBUG
-    printf("%d %d\n", stroke_points->x, stroke_points->y);
-#endif
+  g_assert (stroke_points != NULL);
 
-    temp = stroke_points;
-    stroke_points = stroke_points->next;
-    g_free(temp);
+  /* erase footprint */
+  for (i = 0; i < stroke_points->len; i++) {
+    StrokePoint *point = &g_array_index (stroke_points, StrokePoint, i);
+
+    gdk_gc_set_foreground (w_current->gc,
+                           x_get_color (
+                             w_current->toplevel->background_color));
+    gdk_draw_point (w_current->window, w_current->gc,
+                    point->x, point->y);
   }
+  /* resets length of array */
+  stroke_points->len = 0;
 
-  stroke_points = NULL;
-}
+  /* try evaluating stroke */
+  if (stroke_trans ((char*)&sequence)) {
+    gchar *guile_string =
+      g_strdup_printf("(eval-stroke \"%s\")", sequence);
+    SCM ret;
 
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
- *  \note
- *  this is the function that does the actual work of the strokes
- *  by executing the right guile function which is associated with the stroke
- */
-int x_stroke_search_execute(char *sequence)
-{
-  gchar *guile_string; 
-  SCM eval;
+    ret = scm_c_eval_string (guile_string);
 
-  guile_string = g_strdup_printf("(eval-stroke \"%s\")", sequence);
+    g_free (guile_string);
 
-  eval = scm_c_eval_string (guile_string);
-  g_free(guile_string);
+    return (SCM_NFALSEP (ret));
+  }
 
-  return (SCM_FALSEP (eval)) ? 0 : 1;
+  return 0;
 }
+
+#endif /* HAS_LIBSTROKE */

commit 19aab8901a7519879231c680060f89a69c125e85
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:31 2008 +0200

    Modify o_attrib_toggle_show_name_value() to work on a single object.

diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index edf3b53..a9628b8 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -469,7 +469,7 @@ void o_arc_erase_grips(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
 /* o_attrib.c */
 void o_attrib_add_selected(GSCHEM_TOPLEVEL *w_current, SELECTION *selection, OBJECT *selected);
 void o_attrib_toggle_visibility(GSCHEM_TOPLEVEL *w_current, OBJECT *object);
-void o_attrib_toggle_show_name_value(GSCHEM_TOPLEVEL *w_current, GList *list, int new_show_name_value);
+void o_attrib_toggle_show_name_value(GSCHEM_TOPLEVEL *w_current, OBJECT *object, int new_show_name_value);
 OBJECT *o_attrib_add_attrib(GSCHEM_TOPLEVEL *w_current, char *text_string, int visibility, int show_name_value, OBJECT *object);
 /* o_basic.c */
 void o_redraw_all(GSCHEM_TOPLEVEL *w_current);
diff --git a/gschem/src/i_callbacks.c b/gschem/src/i_callbacks.c
index 8838b01..7bc27ab 100644
--- a/gschem/src/i_callbacks.c
+++ b/gschem/src/i_callbacks.c
@@ -3114,12 +3114,10 @@ DEFINE_I_CALLBACK(attributes_detach)
 DEFINE_I_CALLBACK(attributes_show_name)
 {
   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
-  OBJECT *object;
+  TOPLEVEL *toplevel = w_current->toplevel;
 
   exit_if_null(w_current);
 
-  object = o_select_return_first_object(w_current);
-
   /* This is a new addition 3/15 to prevent this from executing
    * inside an action */
   if (w_current->inside_action) {
@@ -3129,10 +3127,19 @@ DEFINE_I_CALLBACK(attributes_show_name)
   i_update_middle_button(w_current, i_callback_attributes_show_name,
                          _("ShowN"));
 
-  if (object != NULL) {
-    o_attrib_toggle_show_name_value(w_current,
-                                    geda_list_get_glist( w_current->toplevel->page_current->selection_list ),
-                                    SHOW_NAME);
+  if (o_select_selected (w_current)) {
+    SELECTION *selection = toplevel->page_current->selection_list;
+    GList *s_current;
+
+    for (s_current = geda_list_get_glist (selection);
+         s_current != NULL;
+         s_current = g_list_next (s_current)) {
+      OBJECT *object = (OBJECT*)s_current->data;
+      o_attrib_toggle_show_name_value (w_current, object, SHOW_NAME);
+    }
+
+    toplevel->page_current->CHANGED=1;
+    o_undo_savestate (w_current, UNDO_ALL);
   }
 }
 
@@ -3144,12 +3151,10 @@ DEFINE_I_CALLBACK(attributes_show_name)
 DEFINE_I_CALLBACK(attributes_show_value)
 {
   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
-  OBJECT *object;
+  TOPLEVEL *toplevel = w_current->toplevel;
 
   exit_if_null(w_current);
 
-  object = o_select_return_first_object(w_current);
-
   /* This is a new addition 3/15 to prevent this from executing
    * inside an action */
   if (w_current->inside_action) {
@@ -3159,10 +3164,19 @@ DEFINE_I_CALLBACK(attributes_show_value)
   i_update_middle_button(w_current, i_callback_attributes_show_value,
                          _("ShowV"));
 
-  if (object != NULL) {
-    o_attrib_toggle_show_name_value(w_current,
-                                    geda_list_get_glist( w_current->toplevel->page_current->selection_list ),
-                                    SHOW_VALUE);
+  if (o_select_selected (w_current)) {
+    SELECTION *selection = toplevel->page_current->selection_list;
+    GList *s_current;
+
+    for (s_current = geda_list_get_glist (selection);
+         s_current != NULL;
+         s_current = g_list_next (s_current)) {
+      OBJECT *object = (OBJECT*)s_current->data;
+      o_attrib_toggle_show_name_value (w_current, object, SHOW_VALUE);
+    }
+
+    toplevel->page_current->CHANGED=1;
+    o_undo_savestate (w_current, UNDO_ALL);
   }
 }
 
@@ -3174,12 +3188,10 @@ DEFINE_I_CALLBACK(attributes_show_value)
 DEFINE_I_CALLBACK(attributes_show_both)
 {
   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
-  OBJECT *object;
+  TOPLEVEL *toplevel = w_current->toplevel;
 
   exit_if_null(w_current);
 
-  object = o_select_return_first_object(w_current);
-
   /* This is a new addition 3/15 to prevent this from executing
    * inside an action */
   if (w_current->inside_action) {
@@ -3189,10 +3201,19 @@ DEFINE_I_CALLBACK(attributes_show_both)
   i_update_middle_button(w_current, i_callback_attributes_show_both,
                          _("ShowB"));
 
-  if (object != NULL) {
-    o_attrib_toggle_show_name_value(w_current,
-                                    geda_list_get_glist( w_current->toplevel->page_current->selection_list ),
-                                    SHOW_NAME_VALUE);
+  if (o_select_selected (w_current)) {
+    SELECTION *selection = toplevel->page_current->selection_list;
+    GList *s_current;
+
+    for (s_current = geda_list_get_glist (selection);
+         s_current != NULL;
+         s_current = g_list_next (s_current)) {
+      OBJECT *object = (OBJECT*)s_current->data;
+      o_attrib_toggle_show_name_value (w_current, object, SHOW_NAME_VALUE);
+    }
+
+    toplevel->page_current->CHANGED=1;
+    o_undo_savestate (w_current, UNDO_ALL);
   }
 }
 
@@ -3204,12 +3225,10 @@ DEFINE_I_CALLBACK(attributes_show_both)
 DEFINE_I_CALLBACK(attributes_visibility_toggle)
 {
   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
-  OBJECT *object;
+  TOPLEVEL *toplevel = w_current->toplevel;
 
   exit_if_null(w_current);
 
-  object = o_select_return_first_object(w_current);
-
   /* This is a new addition 3/15 to prevent this from executing
    * inside an action */
   if (w_current->inside_action) {
diff --git a/gschem/src/o_attrib.c b/gschem/src/o_attrib.c
index 952599c..48c971a 100644
--- a/gschem/src/o_attrib.c
+++ b/gschem/src/o_attrib.c
@@ -133,42 +133,27 @@ void o_attrib_toggle_visibility(GSCHEM_TOPLEVEL *w_current, OBJECT *object)
   }
 }
 
-/*! \todo Finish function documentation!!!
- *  \brief
+/*! \brief Set what part of an attribute is shown.
  *  \par Function Description
+ *  This function changes what part (name, value or both) of an
+ *  attribute is shown by its attribute object. The attribute object
+ *  is erased, updated and finally redrawn.
  *
+ *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
+ *  \param [in] object     The attribute object.
+ *  \param [in] show_name_value  The new display flag for attribute.
  */
 void o_attrib_toggle_show_name_value(GSCHEM_TOPLEVEL *w_current,
-				     GList *list, int new_show_name_value)
+                                     OBJECT *object, int show_name_value)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
-  GList *s_current = NULL;
-  OBJECT *object = NULL;
-
-  if (list == NULL) {
-    return;
-  }
-
-  s_current = list;
-
-  while(s_current != NULL) {
-    object = (OBJECT *) s_current->data;
 
-    if (object == NULL) {
-      fprintf(stderr, _("Got NULL in o_attrib_toggle_show_name_value\n"));
-      exit(-1);
-    }
+  g_return_if_fail (object != NULL && object->type == OBJ_TEXT);
 
-    if (object->type == OBJ_TEXT) {
-      o_erase_single(w_current, object);
-      object->show_name_value = new_show_name_value;
-      o_text_recreate(toplevel, object);
-      o_text_draw(w_current, object);
-      toplevel->page_current->CHANGED=1;
-    }
-    s_current = g_list_next(s_current);
-  }
-  o_undo_savestate(w_current, UNDO_ALL);
+  o_erase_single(w_current, object);
+  object->show_name_value = show_name_value;
+  o_text_recreate(toplevel, object);
+  o_text_draw(w_current, object);
 }
 
 

commit 306d5722847b4d8c152bd369bc68846b9a19abb0
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:30 2008 +0200

    Modify o_attrib_toggle_visibility() to work on a single object.

diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index c8c4185..edf3b53 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -468,7 +468,7 @@ void o_arc_draw_grips(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
 void o_arc_erase_grips(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
 /* o_attrib.c */
 void o_attrib_add_selected(GSCHEM_TOPLEVEL *w_current, SELECTION *selection, OBJECT *selected);
-void o_attrib_toggle_visibility(GSCHEM_TOPLEVEL *w_current, GList *list);
+void o_attrib_toggle_visibility(GSCHEM_TOPLEVEL *w_current, OBJECT *object);
 void o_attrib_toggle_show_name_value(GSCHEM_TOPLEVEL *w_current, GList *list, int new_show_name_value);
 OBJECT *o_attrib_add_attrib(GSCHEM_TOPLEVEL *w_current, char *text_string, int visibility, int show_name_value, OBJECT *object);
 /* o_basic.c */
diff --git a/gschem/src/i_callbacks.c b/gschem/src/i_callbacks.c
index d2c2553..8838b01 100644
--- a/gschem/src/i_callbacks.c
+++ b/gschem/src/i_callbacks.c
@@ -3220,9 +3220,19 @@ DEFINE_I_CALLBACK(attributes_visibility_toggle)
                          i_callback_attributes_visibility_toggle,
                          _("VisToggle"));
 
-  if (object != NULL) {
-    o_attrib_toggle_visibility(w_current,
-                               geda_list_get_glist( w_current->toplevel->page_current->selection_list ) );
+  if (o_select_selected (w_current)) {
+    SELECTION *selection = toplevel->page_current->selection_list;
+    GList *s_current;
+
+    for (s_current = geda_list_get_glist (selection);
+         s_current != NULL;
+         s_current = g_list_next (s_current)) {
+      OBJECT *object = (OBJECT*)s_current->data;
+      o_attrib_toggle_visibility (w_current, object);
+    }
+
+    toplevel->page_current->CHANGED=1;
+    o_undo_savestate (w_current, UNDO_ALL);
   }
 }
 
diff --git a/gschem/src/o_attrib.c b/gschem/src/o_attrib.c
index ab1dd2c..952599c 100644
--- a/gschem/src/o_attrib.c
+++ b/gschem/src/o_attrib.c
@@ -86,68 +86,51 @@ void o_attrib_add_selected(GSCHEM_TOPLEVEL *w_current, SELECTION *selection,
   return;
 }
 
-/*! \todo Finish function documentation!!!
- *  \brief
+/*! \brief Change visibility status of attribute object.
  *  \par Function Description
+ *  This function toggles the visibility status of the attribute \a
+ *  object and updates it. The object is erased or redrawn if
+ *  necessary.
  *
+ *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
+ *  \param [in] object     The attribute object.
  */
-void o_attrib_toggle_visibility(GSCHEM_TOPLEVEL *w_current, GList *list)
+void o_attrib_toggle_visibility(GSCHEM_TOPLEVEL *w_current, OBJECT *object)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
-  GList *s_current = NULL;
-  OBJECT *object = NULL;
 
-  if (list == NULL) {
-    return;
-  }
+  g_return_if_fail (object != NULL && object->type == OBJ_TEXT);
 
-  s_current = list;
-
-  while(s_current != NULL) {
-    object = (OBJECT *) s_current->data;
-    if (object == NULL) {
-      fprintf(stderr, _("Got NULL in o_attrib_toggle_visibility\n"));
-      exit(-1);
+  if (object->visibility == VISIBLE) {
+    /* only erase if we are not showing hidden text */
+    if (!toplevel->show_hidden_text) {
+      o_erase_single(w_current, object);
     }
 
-    if (object->type == OBJ_TEXT) {
-      if (object->visibility == VISIBLE) {
+    object->visibility = INVISIBLE;
 
-        /* only erase if we are not showing hidden text */
-        if (!toplevel->show_hidden_text) {
-          o_erase_single(w_current, object);
-        }
-        
-        object->visibility = INVISIBLE;
-
-        if (toplevel->show_hidden_text) {
-          /* draw text so that little I is drawn */
-          o_text_draw(w_current, object); 
-        }
+    if (toplevel->show_hidden_text) {
+      /* draw text so that little I is drawn */
+      o_text_draw(w_current, object);
+    }
 
-        toplevel->page_current->CHANGED=1;
-      } else {
-        /* if we are in the special show hidden mode, then erase text first */
-        /* to get rid of the little I */
-        if (toplevel->show_hidden_text) {
-          o_erase_single(w_current, object);
-        }
+  } else {
+    /* if we are in the special show hidden mode, then erase text first */
+    /* to get rid of the little I */
+    if (toplevel->show_hidden_text) {
+      o_erase_single(w_current, object);
+    }
 
-        object->visibility = VISIBLE;
-        
-        /* you must do this since real->text->complex */
-        /* might be null when text is invisible */
-        if (object->text->prim_objs == NULL)
-          o_text_recreate(toplevel, object);
+    object->visibility = VISIBLE;
 
-        
-        o_text_draw(w_current, object);
-        toplevel->page_current->CHANGED = 1;
-      }
+    /* you must do this since real->text->complex */
+    /* might be null when text is invisible */
+    if (object->text->prim_objs == NULL) {
+      o_text_recreate(toplevel, object);
     }
-    s_current = g_list_next(s_current);
+
+    o_text_draw(w_current, object);
   }
-  o_undo_savestate(w_current, UNDO_ALL);
 }
 
 /*! \todo Finish function documentation!!!

commit 658516c080eae8d78685113e48290bb291af0715
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:29 2008 +0200

    Add new function to delete any object.
    
    Added o_delete() as replacement for individual object deletion
    function. Adapted o_delete_selected() accordingly.

diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index 1bdc549..c8c4185 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -566,10 +566,7 @@ void o_cue_draw_list(GSCHEM_TOPLEVEL *w_current, GList *object_list);
 void o_cue_undraw_list(GSCHEM_TOPLEVEL *w_current, GList *object_list);
 void o_cue_undraw_objects(GSCHEM_TOPLEVEL *w_current, OBJECT *list);
 /* o_delete.c */
-void o_delete_net(GSCHEM_TOPLEVEL *w_current, OBJECT *obj);
-void o_delete_bus(GSCHEM_TOPLEVEL *w_current, OBJECT *obj);
-void o_delete_complex(GSCHEM_TOPLEVEL *w_current, OBJECT *obj);
-void o_delete_text(GSCHEM_TOPLEVEL *w_current, OBJECT *obj);
+void o_delete(GSCHEM_TOPLEVEL *w_current, OBJECT *object);
 void o_delete_selected(GSCHEM_TOPLEVEL *w_current);
 /* o_find.c */
 gboolean o_find_object(GSCHEM_TOPLEVEL *w_current, int x, int y,
diff --git a/gschem/src/i_callbacks.c b/gschem/src/i_callbacks.c
index a11fef1..d2c2553 100644
--- a/gschem/src/i_callbacks.c
+++ b/gschem/src/i_callbacks.c
@@ -721,6 +721,7 @@ DEFINE_I_CALLBACK(edit_delete)
     w_current->inside_action = 0;
     i_set_state(w_current, SELECT);
     i_update_toolbar(w_current);
+    i_update_menus(w_current);
   }
 }
 
diff --git a/gschem/src/o_delete.c b/gschem/src/o_delete.c
index 3103ef3..d3e9ed2 100644
--- a/gschem/src/o_delete.c
+++ b/gschem/src/o_delete.c
@@ -31,293 +31,71 @@
 #include <dmalloc.h>
 #endif
 
-/*! \todo Finish function documentation!!!
- *  \brief
+/*! \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 GSCHEM_TOPLEVEL object.
+ *  \param [in] object    The object to delete.
  */
-void o_delete_net(GSCHEM_TOPLEVEL *w_current, OBJECT *obj)
+void o_delete (GSCHEM_TOPLEVEL *w_current, OBJECT *object)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
   GList *other_objects = NULL;
+  gboolean do_conn;
 
-  o_cue_undraw(w_current, obj);
+  g_return_if_fail (object != NULL);
 
-  o_erase_single(w_current, obj);
-  o_line_erase_grips(w_current, obj);
-
-  other_objects = s_conn_return_others(other_objects, obj);
-       
-  s_delete(toplevel, obj);
-
-  toplevel->page_current->object_tail =
-    (OBJECT *) return_tail(toplevel->page_current->object_head);
-
-  o_cue_undraw_list(w_current, other_objects);
-  o_cue_draw_list(w_current, other_objects);
-  g_list_free(other_objects);
-}
-
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
- */
-void o_delete_bus(GSCHEM_TOPLEVEL *w_current, OBJECT *obj)
-{
-  TOPLEVEL *toplevel = w_current->toplevel;
-  GList *other_objects = NULL;
-        
-  o_cue_undraw(w_current, obj);
-  o_erase_single(w_current, obj);
-  o_line_erase_grips(w_current, obj);
-
-  other_objects = s_conn_return_others(other_objects, obj);
-
-  s_delete(toplevel, obj);
-
-  toplevel->page_current->object_tail =
-    (OBJECT *) return_tail(toplevel->page_current->object_head);
-
-  o_cue_undraw_list(w_current, other_objects);
-  o_cue_draw_list(w_current, other_objects);
-  g_list_free(other_objects);
-
-}
-
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
- */
-static void o_delete_pin(GSCHEM_TOPLEVEL *w_current, OBJECT *obj)
-{
-  TOPLEVEL *toplevel = w_current->toplevel;
-  GList *other_objects = NULL;
-        
-  o_cue_undraw(w_current, obj);
-  o_erase_single(w_current, obj);
-  o_line_erase_grips(w_current, obj);
-        
-  other_objects = s_conn_return_others(other_objects, obj);
-        
-  s_delete(toplevel, obj);
-  toplevel->page_current->object_tail =
-    (OBJECT *) return_tail(toplevel->page_current->object_head);
-
-  o_cue_undraw_list(w_current, other_objects);
-  o_cue_draw_list(w_current, other_objects);
-  g_list_free(other_objects);
-
-}
-
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
- */
-void o_delete_complex(GSCHEM_TOPLEVEL *w_current, OBJECT *obj)
-{
-  TOPLEVEL *toplevel = w_current->toplevel;
-  GList *other_objects = NULL;
-
-  o_cue_undraw(w_current, obj);
-  o_erase_single(w_current, obj);
-
-  other_objects = s_conn_return_complex_others(other_objects, obj);
-
-  s_delete(toplevel, obj);
-
-  /*! \todo special case hack no return_tail. why? */
-  o_cue_undraw_list(w_current, other_objects);
-  o_cue_draw_list(w_current, other_objects);
-  g_list_free(other_objects);
-}
-
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
- */
-static void o_delete_line(GSCHEM_TOPLEVEL *w_current, OBJECT *obj)
-{
-  TOPLEVEL *toplevel = w_current->toplevel;
-  o_erase_single(w_current, obj);
-  o_line_erase_grips(w_current, obj);
+  do_conn =
+    object->type == OBJ_NET || object->type == OBJ_BUS ||
+    object->type == OBJ_PIN || object->type == OBJ_COMPLEX;
   
-  s_delete(toplevel, obj);
-  toplevel->page_current->object_tail =
-    (OBJECT *) return_tail(toplevel->page_current->object_head);
-}
-
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
- */
-static void o_delete_box(GSCHEM_TOPLEVEL *w_current, OBJECT *obj)
-{
-  TOPLEVEL *toplevel = w_current->toplevel;
-  o_erase_single(w_current, obj);
-  o_box_erase_grips(w_current, obj);
-
-  s_delete(toplevel, obj);
-  toplevel->page_current->object_tail =
-  (OBJECT *) return_tail(toplevel->page_current->object_head);
-}
-
-
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
- */
-static void o_delete_picture(GSCHEM_TOPLEVEL *w_current, OBJECT *obj)
-{
-  TOPLEVEL *toplevel = w_current->toplevel;
-  o_erase_single(w_current, obj);
-  o_picture_erase_grips(w_current, obj);
-
-  s_delete(toplevel, obj);
-  toplevel->page_current->object_tail =
-  (OBJECT *) return_tail(toplevel->page_current->object_head);
-}
-
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
- */
-static void o_delete_circle(GSCHEM_TOPLEVEL *w_current, OBJECT *obj)
-{
-  TOPLEVEL *toplevel = w_current->toplevel;
-	o_erase_single(w_current, obj);
-	o_circle_erase_grips(w_current, obj);
-
-	s_delete(toplevel, obj);
-
-	toplevel->page_current->object_tail =
-		(OBJECT *) return_tail(toplevel->page_current->object_head);
-}
-
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
- */
-void o_delete_text(GSCHEM_TOPLEVEL *w_current, OBJECT *obj)
-{
-  TOPLEVEL *toplevel = w_current->toplevel;
-  OBJECT *o_parent = obj->attached_to;
-
-  o_erase_single(w_current, obj);
-
-  s_delete(toplevel, obj);
-  toplevel->page_current->object_tail =
-    (OBJECT *) return_tail(toplevel->page_current->object_head);
+  if (do_conn) {
+    o_cue_undraw (w_current, object);
+    other_objects = s_conn_return_others (other_objects, object);
+  }
+  o_erase_single (w_current, object);
+  o_erase_grips (w_current, object);
 
-  if (o_parent != NULL && o_parent->type == OBJ_COMPLEX)
-    o_attrib_slot_update(toplevel, o_parent);
-}
+  s_delete (toplevel, object);
 
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
- */
-static void o_delete_arc(GSCHEM_TOPLEVEL *w_current, OBJECT *obj)
-{
-  TOPLEVEL *toplevel = w_current->toplevel;
-  o_erase_single(w_current, obj);
+  if (do_conn) {
+    o_cue_undraw_list (w_current, other_objects);
+    o_cue_draw_list (w_current, other_objects);
+    g_list_free (other_objects);
+  }
 
-  s_delete(toplevel, obj);
-  toplevel->page_current->object_tail =
-  (OBJECT *) return_tail(toplevel->page_current->object_head);
+  toplevel->page_current->CHANGED = 1;
+   toplevel->page_current->object_tail =
+     (OBJECT *) return_tail(toplevel->page_current->object_head);
 }
 
-/*! \todo Finish function documentation!!!
- *  \brief
+/*! \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 GSCHEM_TOPLEVEL object.
  */
-void o_delete_selected(GSCHEM_TOPLEVEL *w_current)
+void o_delete_selected (GSCHEM_TOPLEVEL *w_current)
 {
-  TOPLEVEL *toplevel = w_current->toplevel;
-  GList *s_current = NULL;
-  OBJECT *object = NULL;
-
-  object = o_select_return_first_object(w_current);
-  if (object == NULL) {
-    /*! \todo error condition */
-    w_current->inside_action = 0;
-    i_set_state(w_current, SELECT);
-    return;
-  }
-
-
-  /* skip over head node */
-  s_current = geda_list_get_glist( toplevel->page_current->selection_list );
+  SELECTION *selection = w_current->toplevel->page_current->selection_list;
+  GList *s_current;
 
-  while(s_current != NULL) {
+  g_return_if_fail (o_select_selected (w_current));
 
-    object = (OBJECT *) s_current->data;
-    g_assert (object != NULL);
 
-    switch(object->type) {
-      case(OBJ_LINE):
-        o_delete_line(w_current, object);
-        break;
-
-      case(OBJ_NET):
-        o_delete_net(w_current, object);
-        break;
-
-      case(OBJ_BUS):
-        o_delete_bus(w_current, object);
-        break;
-
-      case(OBJ_BOX):
-        o_delete_box(w_current, object);
-        break;
-
-      case(OBJ_PICTURE):
-        o_delete_picture(w_current, object);
-        break;
-
-      case(OBJ_CIRCLE):
-        o_delete_circle(w_current, object);
-        break;
-
-      case(OBJ_COMPLEX):
-      case(OBJ_PLACEHOLDER):
-        o_delete_complex(w_current, object);
-        break;
-
-      case(OBJ_PIN):
-        o_delete_pin(w_current, object);
-        break;
-
-      case(OBJ_TEXT):
-        o_delete_text(w_current, object);
-        break;
-
-      case(OBJ_ARC):
-        o_delete_arc(w_current, object);
-        break;
-    }
-    s_current = g_list_next(s_current);
+  for (s_current = geda_list_get_glist (selection);
+       s_current != NULL;
+       s_current = g_list_next (s_current)) {
+    o_delete (w_current, (OBJECT*)s_current->data);
   }
+  /* Objects in the selection list have been deleted. */
+  /* Empty the list without touching the objects */
+  geda_list_remove_all (selection);
 
   w_current->inside_action = 0;
-
-  /* Objects in the selection list have been deleted. Empty the list without touching the objects */
-  geda_list_remove_all( toplevel->page_current->selection_list );
-
-  toplevel->page_current->CHANGED=1;
-
-  /* no longer needed */
-  /* o_redraw(w_current, toplevel->page_current->object_head);*/
-
-  o_undo_savestate(w_current, UNDO_ALL);
-  i_update_menus(w_current);
+  o_undo_savestate (w_current, UNDO_ALL);
+  i_update_menus (w_current);
 }
diff --git a/gschem/src/o_move.c b/gschem/src/o_move.c
index 1054f06..93da77d 100644
--- a/gschem/src/o_move.c
+++ b/gschem/src/o_move.c
@@ -500,7 +500,7 @@ void o_move_end_rubberband(GSCHEM_TOPLEVEL *w_current, int world_diff_x,
 
 
           if (o_move_zero_length(object)) {
-            o_delete_net(w_current, object);
+            o_delete(w_current, object);
           } else {
             o_net_recalc(toplevel, object);
             s_tile_update_object(toplevel, object);
@@ -542,7 +542,7 @@ void o_move_end_rubberband(GSCHEM_TOPLEVEL *w_current, int world_diff_x,
           object->line->y[whichone] = y;
 
           if (o_move_zero_length(object)) {
-            o_delete_bus(w_current, object);
+            o_delete(w_current, object);
           } else {
             o_bus_recalc(toplevel, object);
             s_tile_update_object(toplevel, object);
diff --git a/gschem/src/x_autonumber.c b/gschem/src/x_autonumber.c
index b58b3f5..318e05e 100644
--- a/gschem/src/x_autonumber.c
+++ b/gschem/src/x_autonumber.c
@@ -586,7 +586,7 @@ void autonumber_remove_number(AUTONUMBER_TEXT * autotext, OBJECT *o_current)
 	g_free(slot_str);
 	/* delete the slot attribute */
 	o_selection_remove (autotext->w_current->toplevel->page_current->selection_list, o_slot);
-	o_delete_text (autotext->w_current, o_slot);
+	o_delete (autotext->w_current, o_slot);
       }
     }
   }
diff --git a/gschem/src/x_multiattrib.c b/gschem/src/x_multiattrib.c
index 679d428..6519fb0 100644
--- a/gschem/src/x_multiattrib.c
+++ b/gschem/src/x_multiattrib.c
@@ -518,7 +518,7 @@ static void multiattrib_action_delete_attribute(GSCHEM_TOPLEVEL *w_current,
 {
   /* actually deletes the attribute */
   o_selection_remove ( w_current->toplevel->page_current->selection_list, o_attrib);
-  o_delete_text (w_current, o_attrib);
+  o_delete (w_current, o_attrib);
   w_current->toplevel->page_current->CHANGED=1;
   o_undo_savestate (w_current, UNDO_ALL);
 

commit 64a6741c858de019ab26058afcc417b821d37117
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:28 2008 +0200

    Merge cue undrawing functions for complex and objects.
    
    Merged o_cue_undraw() and o_cue_undraw_complex(). Also added
    documentation.

diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index 718c530..1bdc549 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -562,7 +562,6 @@ void o_cue_draw_lowlevel_midpoints(GSCHEM_TOPLEVEL *w_current, OBJECT *object);
 void o_cue_draw_single(GSCHEM_TOPLEVEL *w_current, OBJECT *object);
 void o_cue_erase_single(GSCHEM_TOPLEVEL *w_current, OBJECT *object);
 void o_cue_undraw(GSCHEM_TOPLEVEL *w_current, OBJECT *object);
-void o_cue_undraw_complex(GSCHEM_TOPLEVEL *w_current, OBJECT *object);
 void o_cue_draw_list(GSCHEM_TOPLEVEL *w_current, GList *object_list);
 void o_cue_undraw_list(GSCHEM_TOPLEVEL *w_current, GList *object_list);
 void o_cue_undraw_objects(GSCHEM_TOPLEVEL *w_current, OBJECT *list);
diff --git a/gschem/src/o_cue.c b/gschem/src/o_cue.c
index 99c5fec..b3ecde5 100644
--- a/gschem/src/o_cue.c
+++ b/gschem/src/o_cue.c
@@ -432,12 +432,15 @@ void o_cue_erase_single(GSCHEM_TOPLEVEL *w_current, OBJECT *object)
   }
 }
 
-/*! \todo Finish function documentation!!!
- *  \brief
+/*! \brief Erase the cues of an object and redraw connected objects.
  *  \par Function Description
+ *  This function erases the cues on object \a object. It then redraws
+ *  the cues of its connected objects.
  *
+ *  \param [in] w_current The GSCHEM_TOPLEVEL object.
+ *  \param [in] object    The object to redraw with no cue.
  */
-void o_cue_undraw(GSCHEM_TOPLEVEL *w_current, OBJECT *object)
+static void o_cue_undraw_lowlevel(GSCHEM_TOPLEVEL *w_current, OBJECT *object)
 {
   GList *cl_current;
   CONN *conn;
@@ -454,47 +457,41 @@ void o_cue_undraw(GSCHEM_TOPLEVEL *w_current, OBJECT *object)
 
     cl_current = g_list_next(cl_current);
   }
-
-  o_redraw_single(w_current, object);
 }
 
-/*! \brief Undraw complex OBJECT.
+/*! \brief Hide the cues of an object.
  *  \par Function Description
- *  This function undraws complex objects (pass in the GSCHEM_TOPLEVEL object)
+ *  This function takes an object and redraws it without its cues. It
+ *  also manages the redraw of connected objects.
  *
- *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
- *  \param [in] object     OBJECT to undraw.
+ *  \note
+ *  The connections of the object are unchanged by this function.
+ *
+ *  \param [in] w_current The GSCHEM_TOPLEVEL object.
+ *  \param [in] object    The object to redraw with no cue.
  */
-void o_cue_undraw_complex(GSCHEM_TOPLEVEL *w_current, OBJECT *object)
+void o_cue_undraw(GSCHEM_TOPLEVEL *w_current, OBJECT *object)
 {
-  GList *cl_current;
-  CONN *conn;
-  OBJECT *o_current;
-
-  if (object->type != OBJ_COMPLEX && object->type != OBJ_PLACEHOLDER) {
-    return;
-  }
-
-  o_current = object->complex->prim_objs;
-  while(o_current != NULL) {
-
-    if (o_current->type == OBJ_PIN || o_current->type == OBJ_NET ||
-        o_current->type == OBJ_BUS) {
-      
-      o_cue_erase_single(w_current, o_current);
-      
-      cl_current = o_current->conn_list;
-      while(cl_current != NULL) {
-        conn = (CONN *) cl_current->data;
-
-        if (conn->other_object) {
-          o_redraw_single(w_current, conn->other_object);
+  switch (object->type) {
+      case OBJ_PIN:
+      case OBJ_NET:
+      case OBJ_BUS:
+        o_cue_undraw_lowlevel (w_current, object);
+        break;
+      case OBJ_COMPLEX:
+      case OBJ_PLACEHOLDER:
+      {
+        OBJECT *o_current;
+        for (o_current = object->complex->prim_objs;
+             o_current != NULL;
+             o_current = o_current->next) {
+          if (o_current->type == OBJ_PIN ||
+              o_current->type == OBJ_NET ||
+              o_current->type == OBJ_BUS) {
+            o_cue_undraw_lowlevel (w_current, o_current);
+          }
         }
-
-        cl_current = g_list_next(cl_current);
       }
-    }
-    o_current = o_current->next;
   }
 
   o_redraw_single(w_current, object);
diff --git a/gschem/src/o_delete.c b/gschem/src/o_delete.c
index 9d9b2dd..3103ef3 100644
--- a/gschem/src/o_delete.c
+++ b/gschem/src/o_delete.c
@@ -121,7 +121,7 @@ void o_delete_complex(GSCHEM_TOPLEVEL *w_current, OBJECT *obj)
   TOPLEVEL *toplevel = w_current->toplevel;
   GList *other_objects = NULL;
 
-  o_cue_undraw_complex(w_current, obj);
+  o_cue_undraw(w_current, obj);
   o_erase_single(w_current, obj);
 
   other_objects = s_conn_return_complex_others(other_objects, obj);

commit 0cdcdf4cfe8bf3c6aa078b91e5696a26f7a60f23
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:27 2008 +0200

    Add new function to erase grips on any object.

diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index f4fe3e1..718c530 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -487,6 +487,7 @@ void o_draw_xor(GSCHEM_TOPLEVEL *w_current, int dx, int dy, OBJECT *object);
 void o_list_draw_xor(GSCHEM_TOPLEVEL *w_current, int dx, int dy, OBJECT *list);
 void o_glist_draw_xor(GSCHEM_TOPLEVEL *w_current, int dx, int dy, GList *list);
 void o_invalidate_rect(GSCHEM_TOPLEVEL *w_current, int x1, int y1, int x2, int y2);
+void o_erase_grips (GSCHEM_TOPLEVEL *w_current, OBJECT *object);
 /* o_box.c */
 void o_box_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
 void o_box_draw_solid(GdkDrawable *w, GdkGC *gc, GdkColor *color, GdkCapStyle cap, gint filled, gint x, gint y, gint width, gint height, gint line_width, gint length, gint space);
diff --git a/gschem/src/o_basic.c b/gschem/src/o_basic.c
index 73e1c4b..b727d00 100644
--- a/gschem/src/o_basic.c
+++ b/gschem/src/o_basic.c
@@ -699,3 +699,32 @@ void o_invalidate_rect( GSCHEM_TOPLEVEL *w_current,
   rect.height = 1 + abs( y1 - y2 ) + 2 * INVALIDATE_MARGIN;
   gdk_window_invalidate_rect( w_current->window, &rect, FALSE );
 }
+
+/*! \brief Erase grip marks on object.
+ *  \par Function Description
+ *  This function erases the grips on the object \a object.
+ *
+ *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
+ *  \param [in] object     The object of which to erase the grips.
+ */
+void o_erase_grips (GSCHEM_TOPLEVEL *w_current, OBJECT *object)
+{
+  void (*func) (GSCHEM_TOPLEVEL*, OBJECT*) = NULL;
+
+  g_return_if_fail (object != NULL);
+
+  switch (object->type) {
+      case OBJ_ARC:     func = o_arc_erase_grips;     break;
+      case OBJ_BOX:     func = o_box_erase_grips;     break;
+      case OBJ_BUS:
+      case OBJ_LINE:
+      case OBJ_NET:
+      case OBJ_PIN:     func = o_line_erase_grips;    break;
+      case OBJ_CIRCLE:  func = o_circle_erase_grips;  break;
+      case OBJ_PICTURE: func = o_picture_erase_grips; break;
+  }
+
+  if (func != NULL) {
+    (*func) (w_current, object);
+  }
+}

commit 37eaad0765b34e85275706b6cffbc73ec9b5c4cd
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:26 2008 +0200

    Rename o_delete() to o_delete_selected().

diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index 6c7e568..f4fe3e1 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -570,7 +570,7 @@ void o_delete_net(GSCHEM_TOPLEVEL *w_current, OBJECT *obj);
 void o_delete_bus(GSCHEM_TOPLEVEL *w_current, OBJECT *obj);
 void o_delete_complex(GSCHEM_TOPLEVEL *w_current, OBJECT *obj);
 void o_delete_text(GSCHEM_TOPLEVEL *w_current, OBJECT *obj);
-void o_delete(GSCHEM_TOPLEVEL *w_current);
+void o_delete_selected(GSCHEM_TOPLEVEL *w_current);
 /* o_find.c */
 gboolean o_find_object(GSCHEM_TOPLEVEL *w_current, int x, int y,
 		       gboolean deselect_afterwards);
diff --git a/gschem/src/i_callbacks.c b/gschem/src/i_callbacks.c
index dcb75fb..a11fef1 100644
--- a/gschem/src/i_callbacks.c
+++ b/gschem/src/i_callbacks.c
@@ -715,7 +715,7 @@ DEFINE_I_CALLBACK(edit_delete)
 
   if (o_select_return_first_object(w_current)) {
     o_redraw_cleanstates(w_current);	
-    o_delete(w_current);
+    o_delete_selected(w_current);
     /* if you delete the objects you must go into select
      * mode after the delete */
     w_current->inside_action = 0;
diff --git a/gschem/src/o_buffer.c b/gschem/src/o_buffer.c
index 809c02c..c8fda91 100644
--- a/gschem/src/o_buffer.c
+++ b/gschem/src/o_buffer.c
@@ -86,7 +86,7 @@ void o_buffer_cut(GSCHEM_TOPLEVEL *w_current, int buf_num)
     o_glist_copy_all_to_glist(toplevel, s_current,
                               object_buffer[buf_num], SELECTION_FLAG);
   toplevel->ADDING_SEL = 0;
-  o_delete(w_current);
+  o_delete_selected(w_current);
 }
 
 /*! \todo Finish function documentation!!!
diff --git a/gschem/src/o_delete.c b/gschem/src/o_delete.c
index e482d03..9d9b2dd 100644
--- a/gschem/src/o_delete.c
+++ b/gschem/src/o_delete.c
@@ -240,7 +240,7 @@ static void o_delete_arc(GSCHEM_TOPLEVEL *w_current, OBJECT *obj)
  *  \par Function Description
  *
  */
-void o_delete(GSCHEM_TOPLEVEL *w_current)
+void o_delete_selected(GSCHEM_TOPLEVEL *w_current)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
   GList *s_current = NULL;

commit 83de2270e9d0f159975e833e1fec213f952c7315
Author: Patrick Bernaud <b-patrick@xxxxxxxxxx>
Date:   Fri Jul 25 17:52:25 2008 +0200

    Remove o_complex_delete().
    
    Removed function as s_delete() does the same thing.

diff --git a/gschem/src/o_delete.c b/gschem/src/o_delete.c
index df45421..e482d03 100644
--- a/gschem/src/o_delete.c
+++ b/gschem/src/o_delete.c
@@ -126,7 +126,7 @@ void o_delete_complex(GSCHEM_TOPLEVEL *w_current, OBJECT *obj)
 
   other_objects = s_conn_return_complex_others(other_objects, obj);
 
-  o_complex_delete(toplevel, obj);
+  s_delete(toplevel, obj);
 
   /*! \todo special case hack no return_tail. why? */
   o_cue_undraw_list(w_current, other_objects);
diff --git a/libgeda/include/prototype.h b/libgeda/include/prototype.h
index 0fb548c..1f6743e 100644
--- a/libgeda/include/prototype.h
+++ b/libgeda/include/prototype.h
@@ -201,7 +201,6 @@ void o_complex_free_filename(TOPLEVEL *toplevel);
 void o_complex_translate_world(TOPLEVEL *toplevel, int x1, int y1, OBJECT *object);
 OBJECT *o_complex_copy(TOPLEVEL *toplevel, OBJECT *list_tail, OBJECT *o_current);
 OBJECT *o_complex_copy_embedded(TOPLEVEL *toplevel, OBJECT *list_tail, OBJECT *o_current);
-void o_complex_delete(TOPLEVEL *toplevel, OBJECT *delete);
 void o_complex_set_color(OBJECT *prim_objs, int color);
 void o_complex_set_color_single(OBJECT *o_current, int color);
 void o_complex_set_color_save(OBJECT *complex, int color);
diff --git a/libgeda/src/o_complex_basic.c b/libgeda/src/o_complex_basic.c
index a4fb831..7ee9d69 100644
--- a/libgeda/src/o_complex_basic.c
+++ b/libgeda/src/o_complex_basic.c
@@ -929,30 +929,6 @@ OBJECT *o_complex_copy_embedded(TOPLEVEL *toplevel, OBJECT *list_tail,
  *  \par Function Description
  *
  */
-void o_complex_delete(TOPLEVEL *toplevel, OBJECT *delete)
-{
-  g_return_if_fail(delete != NULL);
-
-  /* first remove complex pointer */
-  if (delete->complex) {
-    if (delete->complex->prim_objs) {
-      s_delete_list_fromstart(toplevel,
-                              delete->complex->prim_objs);
-    }
-    delete->complex->prim_objs = NULL;
-  }
-
-  /* then remove the actual node */	
-  s_delete(toplevel, delete);
-  delete = NULL;
-  toplevel->page_current->object_tail = (OBJECT *)
-  return_tail(toplevel->page_current->object_head);
-}
-
-/*! \brief
- *  \par Function Description
- *
- */
 void o_complex_set_color(OBJECT *prim_objs, int color)
 {
   OBJECT *o_current=NULL;




_______________________________________________
geda-cvs mailing list
geda-cvs@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-cvs