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

gEDA-cvs: gaf.git: branch: master updated (1.6.1-20100214-75-g42c4df5)



The branch, master has been updated
       via  42c4df51736485b164323304f59bcdb0f18fef61 (commit)
       via  9b24bf40fd35e0954acaa89a1aa8f73ce4f3233a (commit)
      from  ace44e31ae453dc7f1fe7c55e514c3435d70932f (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
=========

 libgeda/include/libgeda/prototype.h |    1 +
 libgeda/include/libgeda/struct.h    |    2 +
 libgeda/include/prototype_priv.h    |    1 +
 libgeda/src/o_basic.c               |   54 +++++++++++++++++++++++++++++++++++
 libgeda/src/s_basic.c               |   12 +++++--
 libgeda/src/s_page.c                |   44 +++++++++++++++++++++++++++-
 6 files changed, 109 insertions(+), 5 deletions(-)


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

commit 42c4df51736485b164323304f59bcdb0f18fef61
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Commit: Peter TB Brett <peter@xxxxxxxxxxxxx>

    libgeda: Clear PAGE.object_lastplace on OBJECT removal.
    
    Clear the current page's object_lastplace magic pointer (which
    actually should be in gschem somewhere) when removing an OBJECT from
    the page, instead of doing it on OBJECT deletion.

:100644 100644 f3e727e... df0fc66... M	libgeda/src/s_basic.c
:100644 100644 9df568c... dcbb6ab... M	libgeda/src/s_page.c

commit 9b24bf40fd35e0954acaa89a1aa8f73ce4f3233a
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Commit: Peter TB Brett <peter@xxxxxxxxxxxxx>

    libgeda: Add parent PAGE pointer to OBJECT structure.
    
    There are numerous examples of libgeda & gschem code that assumes,
    when operating on an OBJECT, that it is part of the "current" PAGE as
    set in the TOPLEVEL structure.  This has a number of disadvantages,
    including the need for regular frobbing of the ADDING_SEL flag and
    page_current pointers, but most importantly restricting the ability to
    work with more than one PAGE at once. Furthermore, it is not
    convenient or practical to add a PAGE argument to all functions that
    may eventually need to manipulate or update the current page based on
    changes to OBJECTs.
    
    Instead, this patch adds a parent PAGE pointer that is updated *only*
    when adding or removing an OBJECT to a PAGE.
    
    In order to ensure consistency in the case of compound objects, only
    the "top-level" compound object has its page pointer set; in general,
    *either* OBJECT.parent *or* OBJECT.page may be non-NULL.

:100644 100644 1e47b5e... e738ce1... M	libgeda/include/libgeda/prototype.h
:100644 100644 7f9afb6... 16552d7... M	libgeda/include/libgeda/struct.h
:100644 100644 b5d35e8... ac52e70... M	libgeda/include/prototype_priv.h
:100644 100644 c8a4e6c... 0d7aa78... M	libgeda/src/o_basic.c
:100644 100644 69f8e42... f3e727e... M	libgeda/src/s_basic.c
:100644 100644 0306da1... 9df568c... M	libgeda/src/s_page.c

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

commit 42c4df51736485b164323304f59bcdb0f18fef61
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Commit: Peter TB Brett <peter@xxxxxxxxxxxxx>

    libgeda: Clear PAGE.object_lastplace on OBJECT removal.
    
    Clear the current page's object_lastplace magic pointer (which
    actually should be in gschem somewhere) when removing an OBJECT from
    the page, instead of doing it on OBJECT deletion.

diff --git a/libgeda/src/s_basic.c b/libgeda/src/s_basic.c
index f3e727e..df0fc66 100644
--- a/libgeda/src/s_basic.c
+++ b/libgeda/src/s_basic.c
@@ -237,10 +237,6 @@ s_delete_object(TOPLEVEL *toplevel, OBJECT *o_current)
       o_attrib_remove(toplevel, &o_current->attached_to->attribs, o_current);
     }
 
-    if (toplevel->page_current->object_lastplace == o_current) {
-      toplevel->page_current->object_lastplace = NULL;
-    }
-
     if (o_current->line) {
       /*	printf("sdeleting line\n");*/
       g_free(o_current->line);
diff --git a/libgeda/src/s_page.c b/libgeda/src/s_page.c
index 9df568c..dcbb6ab 100644
--- a/libgeda/src/s_page.c
+++ b/libgeda/src/s_page.c
@@ -82,6 +82,11 @@ object_removed (TOPLEVEL *toplevel, PAGE *page, OBJECT *object)
   }
 #endif
   object->page = NULL;
+
+  /* Clear page's object_lastplace pointer if set */
+  if (page->object_lastplace == object) {
+    page->object_lastplace = NULL;
+  }
 }
 
 /*! \brief create a new page object

commit 9b24bf40fd35e0954acaa89a1aa8f73ce4f3233a
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Commit: Peter TB Brett <peter@xxxxxxxxxxxxx>

    libgeda: Add parent PAGE pointer to OBJECT structure.
    
    There are numerous examples of libgeda & gschem code that assumes,
    when operating on an OBJECT, that it is part of the "current" PAGE as
    set in the TOPLEVEL structure.  This has a number of disadvantages,
    including the need for regular frobbing of the ADDING_SEL flag and
    page_current pointers, but most importantly restricting the ability to
    work with more than one PAGE at once. Furthermore, it is not
    convenient or practical to add a PAGE argument to all functions that
    may eventually need to manipulate or update the current page based on
    changes to OBJECTs.
    
    Instead, this patch adds a parent PAGE pointer that is updated *only*
    when adding or removing an OBJECT to a PAGE.
    
    In order to ensure consistency in the case of compound objects, only
    the "top-level" compound object has its page pointer set; in general,
    *either* OBJECT.parent *or* OBJECT.page may be non-NULL.

diff --git a/libgeda/include/libgeda/prototype.h b/libgeda/include/libgeda/prototype.h
index 1e47b5e..e738ce1 100644
--- a/libgeda/include/libgeda/prototype.h
+++ b/libgeda/include/libgeda/prototype.h
@@ -124,6 +124,7 @@ void o_rotate_world(TOPLEVEL *toplevel, int world_centerx, int world_centery, in
 void o_mirror_world(TOPLEVEL *toplevel, int world_centerx, int world_centery, OBJECT *object);
 double o_shortest_distance(OBJECT *object, int x, int y);
 void o_set_color(TOPLEVEL *toplevel, OBJECT *object, int color);
+PAGE *o_get_page (TOPLEVEL *toplevel, OBJECT *object);
 
 /* o_box_basic.c */
 OBJECT *o_box_new(TOPLEVEL *toplevel, char type, int color, int x1, int y1, int x2, int y2);
diff --git a/libgeda/include/libgeda/struct.h b/libgeda/include/libgeda/struct.h
index 7f9afb6..16552d7 100644
--- a/libgeda/include/libgeda/struct.h
+++ b/libgeda/include/libgeda/struct.h
@@ -218,6 +218,8 @@ struct st_object {
   int sid;
   char *name;
 
+  PAGE *page; /* Parent page */
+
   int w_top;				/* Bounding box information */
   int w_left;				/* in world coords */
   int w_right;
diff --git a/libgeda/include/prototype_priv.h b/libgeda/include/prototype_priv.h
index b5d35e8..ac52e70 100644
--- a/libgeda/include/prototype_priv.h
+++ b/libgeda/include/prototype_priv.h
@@ -111,6 +111,7 @@ OBJECT *o_attrib_find_attrib_by_name(const GList *list, char *name, int count);
 /* o_basic.c */
 void o_bounds_invalidate(TOPLEVEL *toplevel, OBJECT *object);
 double o_shortest_distance_full(OBJECT *object, int x, int y, int force_solid);
+PAGE *o_get_page_compat (TOPLEVEL *toplevel, OBJECT *object);
 
 /* o_box_basic.c */
 OBJECT *o_box_read(TOPLEVEL *toplevel, char buf[], unsigned int release_ver, unsigned int fileformat_ver);
diff --git a/libgeda/src/o_basic.c b/libgeda/src/o_basic.c
index c8a4e6c..0d7aa78 100644
--- a/libgeda/src/o_basic.c
+++ b/libgeda/src/o_basic.c
@@ -583,3 +583,57 @@ void o_set_color (TOPLEVEL *toplevel, OBJECT *object, int color)
       object->type == OBJ_PLACEHOLDER)
     o_glist_set_color (toplevel, object->complex->prim_objs, color);
 }
+
+
+/*! \brief Get an object's parent PAGE.
+ *
+ * \par Function Description
+ * Returns the PAGE structure which owns \a object. If \a object is
+ * not currently associated with a PAGE, returns NULL. If \a object is
+ * part of a compound object, recurses upward.
+ *
+ * \param [in] toplevel  The TOPLEVEL structure.
+ * \param [in] object    The OBJECT for which to retrieve the parent PAGE.
+ * \return The PAGE which owns \a object or NULL.
+ *
+ * \sa s_page_append_object() s_page_append() s_page_remove()
+ */
+PAGE *
+o_get_page (TOPLEVEL *toplevel, OBJECT *object)
+{
+  if (object->parent != NULL) {
+    return o_get_page (toplevel, object->parent);
+  }
+  return object->page;
+}
+
+/*! \brief Get an object's parent PAGE, or fall back to global current page.
+ *
+ * \par Function Description
+ * If set, returns the PAGE structure which owns \a object.  If \a
+ * object does not have a parent page set, returns the global current
+ * page from \a toplevel.  If the object parent page is inconsistent
+ * with the global current page, a critical-level error message is
+ * emitted.
+ *
+ * \warning This function is primarily intended to assist in the
+ * migration of code from using the TOPLEVEL current page to using the
+ * o_get_page().  It should not be used in new code.
+ *
+ * \deprecated Use o_get_page() in new code.
+ *
+ * \param [in] toplevel  The TOPLEVEL structure.
+ * \param [in] object    The OBJECT for which to retrieve the parent PAGE.
+ * \return The PAGE which owns \a object, the global current PAGE, or NULL.
+ */
+PAGE *
+o_get_page_compat (TOPLEVEL *toplevel, OBJECT *object) {
+  PAGE *page = o_get_page (*toplevel, *object);
+  if (page != toplevel->page_current) {
+    g_critical ("o_get_page_compat: OBJECT.page = %p, TOPLEVEL.page_current = %p",
+                page, toplevel->page_current);
+    return toplevel->page_current;
+  } else {
+    return page;
+  }
+}
diff --git a/libgeda/src/s_basic.c b/libgeda/src/s_basic.c
index 69f8e42..f3e727e 100644
--- a/libgeda/src/s_basic.c
+++ b/libgeda/src/s_basic.c
@@ -81,6 +81,9 @@ OBJECT *s_basic_init_object(OBJECT *new_node, int type, char const *name)
   /* Setup the name */
   new_node->name = g_strdup_printf("%s.%d", name, new_node->sid);
 
+  /* Don't associate with a page, initially */
+  new_node->page = NULL;
+
   /* Setup the bounding box */
   new_node->w_top = 0;
   new_node->w_left = 0;
@@ -222,6 +225,11 @@ void
 s_delete_object(TOPLEVEL *toplevel, OBJECT *o_current)
 {
   if (o_current != NULL) {
+    /* If currently attached to a page, remove it from the page */
+    if (o_current->page != NULL) {
+      s_page_remove (toplevel, o_current->page, o_current);
+    }
+
     s_conn_remove_object (toplevel, o_current);
 
     if (o_current->attached_to != NULL) {
diff --git a/libgeda/src/s_page.c b/libgeda/src/s_page.c
index 0306da1..9df568c 100644
--- a/libgeda/src/s_page.c
+++ b/libgeda/src/s_page.c
@@ -58,6 +58,32 @@
 
 static gint global_pid = 0;
 
+/* Called just before removing an OBJECT from a PAGE. */
+static void
+object_added (TOPLEVEL *toplevel, PAGE *page, OBJECT *object)
+{
+  /* Set up object parent pointer */
+#ifndef NDEBUG
+  if (object->page != NULL) {
+    g_critical ("Object %p already has parent page %p!", object, object->page);
+  }
+#endif
+  object->page = page;
+}
+
+/* Called just after removing an OBJECT from a PAGE. */
+static void
+object_removed (TOPLEVEL *toplevel, PAGE *page, OBJECT *object)
+{
+  /* Clear object parent pointer */
+#ifndef NDEBUG
+  if (object->page == NULL) {
+    g_critical ("Object %p has NULL parent page!", object);
+  }
+#endif
+  object->page = NULL;
+}
+
 /*! \brief create a new page object
  *  \par Function Description
  *  Creates a new page and add it to <B>toplevel</B>'s list of pages.
@@ -520,6 +546,7 @@ gint s_page_autosave (TOPLEVEL *toplevel)
 void s_page_append (TOPLEVEL *toplevel, PAGE *page, OBJECT *object)
 {
   page->_object_list = g_list_append (page->_object_list, object);
+  object_added (toplevel, page, object);
 }
 
 /*! \brief Append a GList of OBJECTs to the PAGE
@@ -534,7 +561,11 @@ void s_page_append (TOPLEVEL *toplevel, PAGE *page, OBJECT *object)
  */
 void s_page_append_list (TOPLEVEL *toplevel, PAGE *page, GList *obj_list)
 {
+  GList *iter;
   page->_object_list = g_list_concat (page->_object_list, obj_list);
+  for (iter = obj_list; iter != NULL; iter = g_list_next (iter)) {
+    object_added (toplevel, page, iter->data);
+  }
 }
 
 /*! \brief Remove an OBJECT from the PAGE
@@ -550,6 +581,7 @@ void s_page_append_list (TOPLEVEL *toplevel, PAGE *page, GList *obj_list)
 void s_page_remove (TOPLEVEL *toplevel, PAGE *page, OBJECT *object)
 {
   page->_object_list = g_list_remove (page->_object_list, object);
+  object_removed (toplevel, page, object);
 }
 
 /*! \brief Remove and free all OBJECTs from the PAGE
@@ -562,8 +594,13 @@ void s_page_remove (TOPLEVEL *toplevel, PAGE *page, OBJECT *object)
  */
 void s_page_delete_objects (TOPLEVEL *toplevel, PAGE *page)
 {
-  s_delete_object_glist (toplevel, page->_object_list);
+  GList *objects = page->_object_list;
+  GList *iter;
   page->_object_list = NULL;
+  for (iter = objects; iter != NULL; iter = g_list_next (iter)) {
+    object_removed (toplevel, page, iter->data);
+  }
+  s_delete_object_glist (toplevel, objects);
 }
 
 




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