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

gEDA-cvs: gaf.git: branch: master updated (1.5.2-20090328-20-g3d8c6f9)



The branch, master has been updated
       via  3d8c6f9e7e5be0728d43b6fba0d366a92a0cdf40 (commit)
       via  85f601b363eac1541d06c47fd1a121b6ff1e2950 (commit)
       via  824ad0acd7d27087690c8eaeb59a1f3806b64d58 (commit)
       via  ff9e5a377265e1960359bb290a159e1db5b6f59a (commit)
       via  57362274fcbe133d9fa545b761fc104310325d0f (commit)
      from  20164638241324a3ff92197cea9d8c2ae3dea0c3 (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/x_multiattrib.h      |    2 +
 gschem/src/g_hook.c                 |   37 +++--
 gschem/src/x_multiattrib.c          |  295 +++++++++++++++++++++++++++++++----
 libgeda/include/libgeda/prototype.h |    5 +-
 libgeda/src/o_attrib.c              |  125 ++++++++-------
 5 files changed, 353 insertions(+), 111 deletions(-)


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

commit 3d8c6f9e7e5be0728d43b6fba0d366a92a0cdf40
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    gschem: Add support for viewing inherited attributes in x_multiattrib.c
    
    Inherited attributes (those from inside the symbol itself) are not
    editable, and are shown greyed out. The context popup menu for an
    inherited attribute shows a single option, "promote", which will make
    an attached (and editable) copy of that attribute in the schematic.

:100644 100644 90010f0... a9aff6d... M	gschem/include/x_multiattrib.h
:100644 100644 d431d3e... 4fde1ac... M	gschem/src/x_multiattrib.c

commit 85f601b363eac1541d06c47fd1a121b6ff1e2950
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    libgeda: Add o_attrib_find_floating_attribs()
    
    This routine will return a GList of floating attributes in the
    passed OBJECT list. It will be useful to identify inherited
    attributes from inside a symbol.

:100644 100644 a4569e7... 1a827be... M	libgeda/include/libgeda/prototype.h
:100644 100644 89d8af0... 7137087... M	libgeda/src/o_attrib.c

commit 824ad0acd7d27087690c8eaeb59a1f3806b64d58
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    libgeda: Add test for whether a given attribute OBJECT is "inherited"
    
    An "inherited" attribute is a floating attribute which lives inside
    a complex object. Its OBJECT.attached_to member will be NULL, and
    its OBJECT.complex_parent will be non NULL.

:100644 100644 63001e7... a4569e7... M	libgeda/include/libgeda/prototype.h
:100644 100644 e177d57... 89d8af0... M	libgeda/src/o_attrib.c

commit ff9e5a377265e1960359bb290a159e1db5b6f59a
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Make g_make_attrib_smob_list() use o_attrib_return_attribs()
    
    Get the list of attributes from a common place, so if we want
    to make that list based on aggregation of attached and inherited
    attributes in the future, we won't have so many places to change.

:100644 100644 3c96847... 2a3ea32... M	gschem/src/g_hook.c

commit 57362274fcbe133d9fa545b761fc104310325d0f
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Make o_attrib_return_attribs() return a GList, not an array
    
    This fits better with our GList centric view of list data.
    
    Also validate the attributes in o_attrib_return_attribs(), so
    we aren't passing potentially malformed attributes to our
    callers.

:100644 100644 bbc2b84... d431d3e... M	gschem/src/x_multiattrib.c
:100644 100644 23a30e0... 63001e7... M	libgeda/include/libgeda/prototype.h
:100644 100644 c94d10f... e177d57... M	libgeda/src/o_attrib.c

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

commit 3d8c6f9e7e5be0728d43b6fba0d366a92a0cdf40
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    gschem: Add support for viewing inherited attributes in x_multiattrib.c
    
    Inherited attributes (those from inside the symbol itself) are not
    editable, and are shown greyed out. The context popup menu for an
    inherited attribute shows a single option, "promote", which will make
    an attached (and editable) copy of that attribute in the schematic.

diff --git a/gschem/include/x_multiattrib.h b/gschem/include/x_multiattrib.h
index 90010f0..a9aff6d 100644
--- a/gschem/include/x_multiattrib.h
+++ b/gschem/include/x_multiattrib.h
@@ -48,6 +48,7 @@ struct _Multiattrib {
 
   GtkTreeView    *treeview;
 
+  GtkWidget      *show_inherited;
   GtkCombo       *combo_name;
   GtkTextView    *textview_value;
   GtkCheckButton *button_visible;
@@ -56,6 +57,7 @@ struct _Multiattrib {
   GtkWidget      *frame_add;
 
   GdkColor       value_normal_text_color;   /* Workaround for lameness in GtkTextView */
+  GdkColor       insensitive_text_color;
 };
 
 
diff --git a/gschem/src/x_multiattrib.c b/gschem/src/x_multiattrib.c
index d431d3e..4fde1ac 100644
--- a/gschem/src/x_multiattrib.c
+++ b/gschem/src/x_multiattrib.c
@@ -658,6 +658,39 @@ static void multiattrib_action_duplicate_attribute(GSCHEM_TOPLEVEL *w_current,
  *  \par Function Description
  *
  */
+static void multiattrib_action_promote_attribute (GSCHEM_TOPLEVEL *w_current,
+                                                  OBJECT *object,
+                                                  OBJECT *o_attrib)
+{
+  TOPLEVEL *toplevel = w_current->toplevel;
+  OBJECT *o_new;
+
+  if (o_attrib->visibility) {
+    /* If the attribute we're promoting is visible, don't clone its location */
+    o_new = o_attrib_add_attrib (w_current,
+                                 o_text_get_string (w_current->toplevel, o_attrib),
+                                 o_attrib->visibility,
+                                 o_attrib->show_name_value,
+                                 object);
+  } else {
+      /* make a copy of the attribute object */
+      o_new = o_object_copy (toplevel, o_attrib, NORMAL_FLAG);
+      s_page_append (toplevel->page_current, o_new);
+      /* add the attribute its parent */
+      o_attrib_attach (toplevel, o_new, object, TRUE);
+      /* redraw the attribute object */
+      o_invalidate (w_current, o_new);
+      /* note: this object is unselected (not added to selection). */
+  }
+  w_current->toplevel->page_current->CHANGED = 1;
+  o_undo_savestate (w_current, UNDO_ALL);
+}
+
+/*! \todo Finish function documentation
+ *  \brief
+ *  \par Function Description
+ *
+ */
 static void multiattrib_action_delete_attribute(GSCHEM_TOPLEVEL *w_current,
 						OBJECT *o_attrib) 
 {
@@ -684,6 +717,7 @@ static void multiattrib_column_set_data_name(GtkTreeViewColumn *tree_column,
   gchar *name;
   Multiattrib *dialog = (Multiattrib *) data;
   const gchar *str = NULL;
+  int inherited;
 
   gtk_tree_model_get (tree_model, iter,
                       COLUMN_ATTRIBUTE, &o_attrib,
@@ -692,10 +726,13 @@ static void multiattrib_column_set_data_name(GtkTreeViewColumn *tree_column,
 
   str = o_text_get_string (GSCHEM_DIALOG(dialog)->w_current->toplevel,
                            o_attrib);
+  inherited = o_attrib_is_inherited (o_attrib);
 
   o_attrib_get_name_value (str, &name, NULL);
   g_object_set (cell,
                 "text", name,
+                "foreground-gdk", inherited ? &dialog->insensitive_text_color : NULL,
+                "editable", !inherited,
                 NULL);
   g_free (name);
   
@@ -716,6 +753,7 @@ static void multiattrib_column_set_data_value(GtkTreeViewColumn *tree_column,
   gchar *value;
   Multiattrib *dialog = (Multiattrib *) data;
   const gchar *str = NULL;
+  int inherited;
 
   gtk_tree_model_get (tree_model, iter,
                       COLUMN_ATTRIBUTE, &o_attrib,
@@ -724,10 +762,13 @@ static void multiattrib_column_set_data_value(GtkTreeViewColumn *tree_column,
 
   str = o_text_get_string (GSCHEM_DIALOG(dialog)->w_current->toplevel,
                            o_attrib);
+  inherited = o_attrib_is_inherited (o_attrib);
 
   o_attrib_get_name_value (str, NULL, &value);
   g_object_set (cell,
                 "text", value,
+                "foreground-gdk", inherited ? &dialog->insensitive_text_color : NULL,
+                "editable", !inherited,
                 NULL);
   g_free (value);
   
@@ -745,14 +786,19 @@ static void multiattrib_column_set_data_visible(GtkTreeViewColumn *tree_column,
 						gpointer data)
 {
   OBJECT *o_attrib;
+  int inherited;
 
   gtk_tree_model_get (tree_model, iter,
                       COLUMN_ATTRIBUTE, &o_attrib,
                       -1);
   g_assert (o_attrib->type == OBJ_TEXT);
   
+  inherited = o_attrib_is_inherited (o_attrib);
+
   g_object_set (cell,
                 "active", (o_attrib->visibility == VISIBLE),
+                "sensitive",   !inherited,
+                "activatable", !inherited,
                 NULL);
   
 }
@@ -769,15 +815,20 @@ static void multiattrib_column_set_data_show_name(GtkTreeViewColumn *tree_column
 						  gpointer data)
 {
   OBJECT *o_attrib;
+  int inherited;
 
   gtk_tree_model_get (tree_model, iter,
                       COLUMN_ATTRIBUTE, &o_attrib,
                       -1);
   g_assert (o_attrib->type == OBJ_TEXT);
   
+  inherited = o_attrib_is_inherited (o_attrib);
+
   g_object_set (cell,
                 "active", (o_attrib->show_name_value == SHOW_NAME_VALUE ||
                            o_attrib->show_name_value == SHOW_NAME),
+                "sensitive",   !inherited,
+                "activatable", !inherited,
                 NULL);
   
 }
@@ -794,15 +845,20 @@ static void multiattrib_column_set_data_show_value(GtkTreeViewColumn *tree_colum
 						   gpointer data)
 {
   OBJECT *o_attrib;
+  int inherited;
 
   gtk_tree_model_get (tree_model, iter,
                       COLUMN_ATTRIBUTE, &o_attrib,
                       -1);
   g_assert (o_attrib->type == OBJ_TEXT);
   
+  inherited = o_attrib_is_inherited (o_attrib);
+
   g_object_set (cell,
                 "active", (o_attrib->show_name_value == SHOW_NAME_VALUE ||
                            o_attrib->show_name_value == SHOW_VALUE),
+                "sensitive",   !inherited,
+                "activatable", !inherited,
                 NULL);
   
 }
@@ -1099,6 +1155,7 @@ static gboolean multiattrib_callback_key_pressed(GtkWidget *widget,
     GtkTreeModel *model;
     GtkTreeIter iter;
     OBJECT *o_attrib;
+    int inherited;
     /* delete the currently selected attribute */
 
     if (!gtk_tree_selection_get_selected (
@@ -1113,6 +1170,11 @@ static gboolean multiattrib_callback_key_pressed(GtkWidget *widget,
                         -1);
     g_assert (o_attrib->type == OBJ_TEXT);
     
+    inherited = o_attrib_is_inherited (o_attrib);
+    /* We can't delete inherited attribtes */
+    if (inherited)
+      return FALSE;
+
     multiattrib_action_delete_attribute (GSCHEM_DIALOG (multiattrib)->w_current,
                                          o_attrib);
     
@@ -1194,6 +1256,42 @@ static void multiattrib_callback_popup_duplicate(GtkMenuItem *menuitem,
   
 }
 
+
+/*! \todo Finish function documentation
+ *  \brief
+ *  \par Function Description
+ *
+ */
+static void multiattrib_callback_popup_promote (GtkMenuItem *menuitem,
+                                                gpointer user_data)
+{
+  Multiattrib *multiattrib = user_data;
+  GtkTreeModel *model;
+  GtkTreeIter iter;
+  GSCHEM_TOPLEVEL *w_current;
+  OBJECT *object, *o_attrib;
+
+  if (!gtk_tree_selection_get_selected (
+         gtk_tree_view_get_selection (multiattrib->treeview),
+         &model, &iter)) {
+    /* nothing selected, nothing to do */
+    return;
+  }
+
+  w_current = GSCHEM_DIALOG (multiattrib)->w_current;
+  object = multiattrib->object;
+
+  gtk_tree_model_get (model, &iter,
+                      COLUMN_ATTRIBUTE, &o_attrib,
+                      -1);
+  g_assert (o_attrib->type == OBJ_TEXT);
+
+  multiattrib_action_promote_attribute (w_current, object, o_attrib);
+
+  /* update the treeview contents */
+  multiattrib_update (multiattrib);
+}
+
 /*! \todo Finish function documentation
  *  \brief
  *  \par Function Description
@@ -1396,27 +1494,51 @@ static void multiattrib_popup_menu(Multiattrib *multiattrib,
     gchar *label;
     GCallback callback;
   };
-  struct menuitem_t menuitems[] = {
+
+  struct menuitem_t menuitems_inherited[] = {
+    { N_("Promote"),   G_CALLBACK (multiattrib_callback_popup_promote)   },
+    { NULL,            NULL                                              } };
+
+  struct menuitem_t menuitems_noninherited[] = {
     { N_("Duplicate"), G_CALLBACK (multiattrib_callback_popup_duplicate) },
     { N_("Delete"),    G_CALLBACK (multiattrib_callback_popup_delete)    },
     { NULL,            NULL                                              } };
+
+  struct menuitem_t *item_list;
   struct menuitem_t *tmp;
-  
+  int inherited;
+  GtkTreeModel *model;
+  GtkTreeIter iter;
+  GtkTreeSelection *selection;
+  OBJECT *o_attrib;
+
+  selection = gtk_tree_view_get_selection (multiattrib->treeview);
+
   if (event != NULL &&
       gtk_tree_view_get_path_at_pos (multiattrib->treeview,
                                      (gint)event->x, 
                                      (gint)event->y,
                                      &path, NULL, NULL, NULL)) {
-    GtkTreeSelection *selection;
-    selection = gtk_tree_view_get_selection (multiattrib->treeview);
     gtk_tree_selection_unselect_all (selection);
     gtk_tree_selection_select_path (selection, path);
     gtk_tree_path_free (path);
   }
 
+  /* if nothing is selected, nothing to do */
+  if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+    return;
+
+  gtk_tree_model_get (model, &iter,
+                      COLUMN_ATTRIBUTE, &o_attrib,
+                      -1);
+  g_assert (o_attrib->type == OBJ_TEXT);
+
+  inherited = o_attrib_is_inherited (o_attrib);
+  item_list = inherited ? menuitems_inherited : menuitems_noninherited;
+
   /* create the context menu */
   menu = gtk_menu_new();
-  for (tmp = menuitems; tmp->label != NULL; tmp++) {
+  for (tmp = item_list; tmp->label != NULL; tmp++) {
     GtkWidget *menuitem;
     if (g_strcasecmp (tmp->label, "-") == 0) {
       menuitem = gtk_separator_menu_item_new ();
@@ -1438,6 +1560,60 @@ static void multiattrib_popup_menu(Multiattrib *multiattrib,
 }
 
 
+/*! \brief GschemDialog "geometry_save" class method handler
+ *
+ *  \par Function Description
+ *  Chain up to our parent's method to save the dialog's size and
+ *  position, then save the dialog's current internal geometry.
+ *
+ *  \param [in] dialog     The GschemDialog to save the geometry of.
+ *  \param [in] key_file   The GKeyFile to save the geometry data to.
+ *  \param [in] group_name The group name in the key file to store the data under.
+ */
+static void
+multiattrib_geometry_save (GschemDialog *dialog, GKeyFile *key_file, gchar *group_name)
+{
+  gboolean show_inherited;
+
+  /* Call the parent's geometry_save method */
+  GSCHEM_DIALOG_CLASS (multiattrib_parent_class)->
+    geometry_save (dialog, key_file, group_name);
+
+  show_inherited =
+    gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (MULTIATTRIB (dialog)->show_inherited));
+  g_key_file_set_boolean (key_file, group_name, "show_inherited", show_inherited);
+}
+
+
+/*! \brief GschemDialog "geometry_restore" class method handler
+ *
+ *  \par Function Description
+ *  Chain up to our parent's method to restore the dialog's size and
+ *  position, then restore the dialog's current internal geometry.
+ *
+ *  \param [in] dialog     The GschemDialog to restore the geometry of.
+ *  \param [in] key_file   The GKeyFile to save the geometry data to.
+ *  \param [in] group_name The group name in the key file to store the data under.
+ */
+static void
+multiattrib_geometry_restore (GschemDialog *dialog, GKeyFile *key_file, gchar *group_name)
+{
+  gboolean show_inherited;
+  GError *error = NULL;
+
+  /* Call the parent's geometry_restore method */
+  GSCHEM_DIALOG_CLASS (multiattrib_parent_class)->
+    geometry_restore (dialog, key_file, group_name);
+
+  show_inherited = g_key_file_get_boolean (key_file, group_name, "show_inherited", &error);
+  if (error != NULL) {
+    show_inherited = TRUE;
+    g_error_free (error);
+  }
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (MULTIATTRIB (dialog)->show_inherited), show_inherited);
+}
+
+
 /*! \brief Function to retrieve Multiattrib's GType identifier.
  *
  *  \par Function Description
@@ -1485,12 +1661,16 @@ GType multiattrib_get_type()
 static void multiattrib_class_init(MultiattribClass *klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+  GschemDialogClass *gschem_dialog_class = GSCHEM_DIALOG_CLASS (klass);
 
-  multiattrib_parent_class = g_type_class_peek_parent (klass);
+  gschem_dialog_class->geometry_save    = multiattrib_geometry_save;
+  gschem_dialog_class->geometry_restore = multiattrib_geometry_restore;
 
   gobject_class->set_property = multiattrib_set_property;
   gobject_class->get_property = multiattrib_get_property;
 
+  multiattrib_parent_class = g_type_class_peek_parent (klass);
+
   g_object_class_install_property (
     gobject_class, PROP_OBJECT,
     g_param_spec_pointer ("object",
@@ -1499,6 +1679,18 @@ static void multiattrib_class_init(MultiattribClass *klass)
                           G_PARAM_READWRITE));
 }
 
+/*! \brief Regenerate the attribute list when the visibility
+ *         setting for inherited attributes changes
+ */
+static void multiattrib_show_inherited_toggled (GtkToggleButton *button,
+                                                gpointer user_data)
+{
+  Multiattrib *multiattrib = user_data;
+
+  /* update the treeview contents */
+  multiattrib_update (multiattrib);
+}
+
 
 /*! \brief GType instance initialiser for Multiattrib
  *
@@ -1513,6 +1705,7 @@ static void multiattrib_init(Multiattrib *multiattrib)
 {
   GtkWidget *frame, *label, *scrolled_win, *treeview;
   GtkWidget *table, *textview, *combo, *optionm, *button;
+  GtkWidget *attrib_vbox, *show_inherited;
   GtkTreeModel *store;
   GtkCellRenderer *renderer;
   GtkTreeViewColumn *column;
@@ -1537,11 +1730,13 @@ static void multiattrib_init(Multiattrib *multiattrib)
 
   multiattrib->object   = NULL;
 
+  gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (multiattrib)->vbox), 5);
+
   /* create the attribute list frame */
   frame = GTK_WIDGET (g_object_new (GTK_TYPE_FRAME,
-				    /* GtkFrame */
-				    "label", _("Attributes"),
-				    NULL));
+                                    /* GtkFrame */
+                                    "shadow", GTK_SHADOW_NONE,
+                                    NULL));
   multiattrib->frame_add = frame;
   /*   - create the model for the treeview */
   store = (GtkTreeModel*)gtk_list_store_new (NUM_COLUMNS,
@@ -1586,7 +1781,6 @@ static void multiattrib_init(Multiattrib *multiattrib)
   renderer = GTK_CELL_RENDERER (
 				g_object_new (GTK_TYPE_CELL_RENDERER_TEXT,
 					      /* GtkCellRendererText */
-					      "editable",  TRUE,
 					      /* unknown in GTK 2.4 */
 					      /* "ellipsize",
 					       * PANGO_ELLIPSIZE_END, */
@@ -1611,7 +1805,6 @@ static void multiattrib_init(Multiattrib *multiattrib)
   renderer = GTK_CELL_RENDERER (
 				g_object_new (TYPE_CELL_RENDERER_MULTI_LINE_TEXT,
 					      /* GtkCellRendererText */
-					      "editable",  TRUE,
 					      /* unknown in GTK 2.4 */
 					      /* "ellipsize",
 						 PANGO_ELLIPSIZE_END, */
@@ -1635,8 +1828,6 @@ static void multiattrib_init(Multiattrib *multiattrib)
   /*       - column 3: visibility */
   renderer = GTK_CELL_RENDERER (
 				g_object_new (GTK_TYPE_CELL_RENDERER_TOGGLE,
-					      /* GtkCellRendererToggle */
-					      "activatable", TRUE,
 					      NULL));
   g_signal_connect (renderer,
 		    "toggled",
@@ -1655,8 +1846,6 @@ static void multiattrib_init(Multiattrib *multiattrib)
   /*       - column 4: show name */
   renderer = GTK_CELL_RENDERER (
 				g_object_new (GTK_TYPE_CELL_RENDERER_TOGGLE,
-					      /* GtkCellRendererToggle */
-					      "activatable", TRUE,
 					      NULL));
   g_signal_connect (renderer,
 		    "toggled",
@@ -1675,8 +1864,6 @@ static void multiattrib_init(Multiattrib *multiattrib)
   /*       - column 5: show value */
   renderer = GTK_CELL_RENDERER (
 				g_object_new (GTK_TYPE_CELL_RENDERER_TOGGLE,
-					      /* GtkCellRendererToggle */
-					      "activatable", TRUE,
 					      NULL));
   g_signal_connect (renderer,
 		    "toggled",
@@ -1697,13 +1884,30 @@ static void multiattrib_init(Multiattrib *multiattrib)
   gtk_container_add (GTK_CONTAINER (scrolled_win), treeview);
   /* set treeview of multiattrib */
   multiattrib->treeview = GTK_TREE_VIEW (treeview);
-  /* add the scrolled window to frame */
-  gtk_container_add (GTK_CONTAINER (frame), scrolled_win);
+
+  attrib_vbox = gtk_vbox_new (FALSE, 0);
+
+  /* Pack the vbox into the frame */
+  gtk_container_add (GTK_CONTAINER (frame), attrib_vbox);
+
+  /* add the scrolled window to box */
+  gtk_box_pack_start (GTK_BOX (attrib_vbox), scrolled_win, TRUE, TRUE, 0);
+
+  /* create the show inherited button */
+  show_inherited = gtk_check_button_new_with_label (_("Show inherited attributes"));
+  multiattrib->show_inherited = show_inherited;
+  gtk_box_pack_start (GTK_BOX (attrib_vbox), show_inherited, FALSE, FALSE, 0);
+
+  g_signal_connect (show_inherited,
+                    "toggled",
+                    G_CALLBACK (multiattrib_show_inherited_toggled),
+                    multiattrib);
+
   /* pack the frame */
   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (multiattrib)->vbox), frame,
 		      TRUE, TRUE, 1);
   gtk_widget_show_all (frame);
-  
+
   /* create the add/edit frame */
   frame = GTK_WIDGET (g_object_new (GTK_TYPE_FRAME,
 				    "label", _("Add Attribute"),
@@ -1768,6 +1972,12 @@ static void multiattrib_init(Multiattrib *multiattrib)
   style = gtk_widget_get_style (textview);
   multiattrib->value_normal_text_color = style->text[ GTK_STATE_NORMAL ];
 
+  /* Save this one so we can pick it as a sensible colour to show the
+   * inherited attributes dimmed.
+   */
+  style = gtk_widget_get_style (treeview);
+  multiattrib->insensitive_text_color = style->text[ GTK_STATE_INSENSITIVE ];
+
   gtk_container_add (GTK_CONTAINER (scrolled_win), textview);
   multiattrib->textview_value = GTK_TEXT_VIEW (textview);
   gtk_table_attach (GTK_TABLE (table), label,
@@ -1807,7 +2017,7 @@ static void multiattrib_init(Multiattrib *multiattrib)
   gtk_container_add (GTK_CONTAINER (frame), table);
   /* pack the frame in the dialog */
   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (multiattrib)->vbox), frame,
-		      FALSE, TRUE, 4);
+		      FALSE, TRUE, 1);
   gtk_widget_show_all (frame);
   
   
@@ -1896,6 +2106,7 @@ void multiattrib_update (Multiattrib *multiattrib)
   OBJECT *a_current;
   gboolean sensitive;
   GtkStyle *style;
+  gboolean show_inherited;
 
   g_assert (GSCHEM_DIALOG (multiattrib)->w_current != NULL);
   toplevel = GSCHEM_DIALOG (multiattrib)->w_current->toplevel;
@@ -1936,4 +2147,25 @@ void multiattrib_update (Multiattrib *multiattrib)
   /* delete the list of attribute objects */
   g_list_free (object_attribs);
 
+  show_inherited =
+    gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (multiattrib->show_inherited));
+
+  /* get list of inherited attributes from inside the symbol */
+  if (show_inherited && (multiattrib->object->type == OBJ_COMPLEX ||
+                         multiattrib->object->type == OBJ_PLACEHOLDER)) {
+    object_attribs =
+      o_attrib_find_floating_attribs (multiattrib->object->complex->prim_objs);
+
+    for (a_iter = object_attribs; a_iter != NULL;
+         a_iter = g_list_next (a_iter)) {
+      a_current = a_iter->data;
+
+      gtk_list_store_append (liststore, &iter);
+      gtk_list_store_set (liststore, &iter,
+                          COLUMN_ATTRIBUTE, a_current,
+                          -1);
+    }
+    g_list_free (object_attribs);
+  }
+
 }

commit 85f601b363eac1541d06c47fd1a121b6ff1e2950
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    libgeda: Add o_attrib_find_floating_attribs()
    
    This routine will return a GList of floating attributes in the
    passed OBJECT list. It will be useful to identify inherited
    attributes from inside a symbol.

diff --git a/libgeda/include/libgeda/prototype.h b/libgeda/include/libgeda/prototype.h
index a4569e7..1a827be 100644
--- a/libgeda/include/libgeda/prototype.h
+++ b/libgeda/include/libgeda/prototype.h
@@ -101,6 +101,7 @@ void o_attrib_detach_all(TOPLEVEL *toplevel, GList *list);
 void o_attrib_print(GList *attributes);
 void o_attrib_remove(GList **list, OBJECT *remove);
 gboolean o_attrib_get_name_value (const gchar *string, gchar **name_ptr, gchar **value_ptr);
+GList *o_attrib_find_floating_attribs (const GList *list);
 char *o_attrib_search_name(const GList *list, char *name, int counter);
 OBJECT *o_attrib_search_string_list(GList *list, char *string);
 char *o_attrib_search_string_partial(OBJECT *object, char *search_for, int counter);
diff --git a/libgeda/src/o_attrib.c b/libgeda/src/o_attrib.c
index 89d8af0..7137087 100644
--- a/libgeda/src/o_attrib.c
+++ b/libgeda/src/o_attrib.c
@@ -423,6 +423,40 @@ o_attrib_get_name_value (const gchar *string, gchar **name_ptr, gchar **value_pt
 }
 
 
+/*! \brief Find all floating attributes in the given object list.
+ *  \par Function Description
+ *  Find all floating attributes in the given object list.
+ *
+ *  \param [in] list     GList of OBJECTs to search.
+ *  \return GList of floating attributes from the input list
+ *
+ *  \warning
+ *  Caller must g_list_free returned list.
+ */
+GList *o_attrib_find_floating_attribs (const GList *list)
+{
+  GList *floating_attributes = NULL;
+  const GList *iter;
+  OBJECT *o_current;
+
+  for (iter = list; iter != NULL; iter = g_list_next (iter)) {
+    o_current = iter->data;
+
+    /* Skip non text objects, attached attributes and text which doesn't
+     * constitute a valid attributes (e.g. general text placed on the page)
+     */
+    if (o_current->type == OBJ_TEXT &&
+        o_current->attached_to == NULL &&
+        o_attrib_get_name_value (o_current->text->string, NULL, NULL)) {
+
+      floating_attributes = g_list_prepend (floating_attributes, o_current);
+    }
+  }
+
+  return g_list_reverse (floating_attributes);
+}
+
+
 /*! \brief Search for attibute by name.
  *  \par Function Description
  *  Search for attribute by name.

commit 824ad0acd7d27087690c8eaeb59a1f3806b64d58
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    libgeda: Add test for whether a given attribute OBJECT is "inherited"
    
    An "inherited" attribute is a floating attribute which lives inside
    a complex object. Its OBJECT.attached_to member will be NULL, and
    its OBJECT.complex_parent will be non NULL.

diff --git a/libgeda/include/libgeda/prototype.h b/libgeda/include/libgeda/prototype.h
index 63001e7..a4569e7 100644
--- a/libgeda/include/libgeda/prototype.h
+++ b/libgeda/include/libgeda/prototype.h
@@ -118,6 +118,7 @@ void o_attrib_slot_update(TOPLEVEL *toplevel, OBJECT *object);
 void o_attrib_slot_copy(TOPLEVEL *toplevel, OBJECT *original, OBJECT *target);
 char *o_attrib_search_toplevel_all(GedaPageList *page_list, char *name);
 GList *o_attrib_return_attribs(OBJECT *object);
+int o_attrib_is_inherited(OBJECT *attrib);
 
 /* o_basic.c */
 int inside_region(int xmin, int ymin, int xmax, int ymax, int x, int y);
diff --git a/libgeda/src/o_attrib.c b/libgeda/src/o_attrib.c
index e177d57..89d8af0 100644
--- a/libgeda/src/o_attrib.c
+++ b/libgeda/src/o_attrib.c
@@ -1532,3 +1532,18 @@ GList * o_attrib_return_attribs (OBJECT *object)
   attribs = g_list_reverse (attribs);
   return attribs;
 }
+
+
+/*! \brief Query whether a given attribute OBJECT is "inherited"
+ *  \par Function Description
+ *  This function returns TRUE if the given attribute OBJECT is a
+ *  toplevel un-attached attribute inside a complex's prim_objs.
+ *
+ *  \param [in] object       OBJECT who's status to query.
+ *  \return TRUE if the given attribute is inside a symbol
+ */
+int o_attrib_is_inherited (OBJECT *attrib)
+{
+  return (attrib->attached_to == NULL &&
+          attrib->complex_parent != NULL);
+}

commit ff9e5a377265e1960359bb290a159e1db5b6f59a
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Make g_make_attrib_smob_list() use o_attrib_return_attribs()
    
    Get the list of attributes from a common place, so if we want
    to make that list based on aggregation of attached and inherited
    attributes in the future, we won't have so many places to change.

diff --git a/gschem/src/g_hook.c b/gschem/src/g_hook.c
index 3c96847..2a3ea32 100644
--- a/gschem/src/g_hook.c
+++ b/gschem/src/g_hook.c
@@ -50,35 +50,36 @@ static void custom_world_get_object_glist_bounds
  *  \par Function Description
  *
  */
-/* Makes a list of all attributes currently connected to object. *
- * Principle stolen from o_attrib_return_attribs */
-SCM g_make_attrib_smob_list(GSCHEM_TOPLEVEL *w_current, OBJECT *object)
+/* Makes a list of all attributes currently connected to object.
+ * Uses the attribute list returned by o_attrib_return_attribs()
+ */
+SCM g_make_attrib_smob_list (GSCHEM_TOPLEVEL *w_current, OBJECT *object)
 {
-  OBJECT *a_current;
+  GList *attrib_list;
   GList *a_iter;
+  OBJECT *a_current;
   SCM smob_list = SCM_EOL;
 
-  if (!object) {
-    return(SCM_EOL);   
+  if (object == NULL) {
+    return SCM_EOL;
   }
 
-  if (!object->attribs) {
-    return(SCM_EOL);
-  }
+  attrib_list = o_attrib_return_attribs (object);
+
+  if (attrib_list == NULL)
+    return SCM_EOL;
 
   /* go through attribs */
-  a_iter = object->attribs;
-  while(a_iter != NULL) {
+  for (a_iter = attrib_list; a_iter != NULL;
+       a_iter = g_list_next (a_iter)) {
     a_current = a_iter->data;
-    if (a_current->type == OBJ_TEXT) {
-      if (o_text_get_string (w_current->toplevel, a_current)) {
-        smob_list = scm_cons (g_make_attrib_smob (w_current->toplevel, a_current),
-                              smob_list);
-      }
-    }
-    a_iter = g_list_next (a_iter);
+
+    smob_list = scm_cons (g_make_attrib_smob (w_current->toplevel, a_current),
+                          smob_list);
   }
 
+  g_list_free (attrib_list);
+
   return smob_list;
 }
 

commit 57362274fcbe133d9fa545b761fc104310325d0f
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Make o_attrib_return_attribs() return a GList, not an array
    
    This fits better with our GList centric view of list data.
    
    Also validate the attributes in o_attrib_return_attribs(), so
    we aren't passing potentially malformed attributes to our
    callers.

diff --git a/gschem/src/x_multiattrib.c b/gschem/src/x_multiattrib.c
index bbc2b84..d431d3e 100644
--- a/gschem/src/x_multiattrib.c
+++ b/gschem/src/x_multiattrib.c
@@ -1891,8 +1891,9 @@ void multiattrib_update (Multiattrib *multiattrib)
   TOPLEVEL *toplevel;
   GtkListStore *liststore;
   GtkTreeIter iter;
-  OBJECT **object_attribs, *o_current;
-  gint i;
+  GList *object_attribs;
+  GList *a_iter;
+  OBJECT *a_current;
   gboolean sensitive;
   GtkStyle *style;
 
@@ -1923,22 +1924,16 @@ void multiattrib_update (Multiattrib *multiattrib)
   /* get list of attributes */
   object_attribs = o_attrib_return_attribs (multiattrib->object);
   /* populate the store with attributes */
-  if (object_attribs) {
-    for (i = 0, o_current = object_attribs[i];
-         o_current != NULL;
-         i++, o_current = object_attribs[i]) {
-
-      /* Don't add invalid attributes to the list */
-      if (!o_attrib_get_name_value (o_text_get_string (toplevel, o_current),
-                                    NULL, NULL))
-        continue;
-
-      gtk_list_store_append (liststore, &iter);
-      gtk_list_store_set (liststore, &iter,
-                          COLUMN_ATTRIBUTE, o_current,
-                          -1);
-    }
+  for (a_iter = object_attribs; a_iter != NULL;
+       a_iter = g_list_next (a_iter)) {
+    a_current = a_iter->data;
+
+    gtk_list_store_append (liststore, &iter);
+    gtk_list_store_set (liststore, &iter,
+                        COLUMN_ATTRIBUTE, a_current,
+                        -1);
   }
   /* delete the list of attribute objects */
-  o_attrib_free_returned (object_attribs);
+  g_list_free (object_attribs);
+
 }
diff --git a/libgeda/include/libgeda/prototype.h b/libgeda/include/libgeda/prototype.h
index 23a30e0..63001e7 100644
--- a/libgeda/include/libgeda/prototype.h
+++ b/libgeda/include/libgeda/prototype.h
@@ -117,8 +117,7 @@ char *o_attrib_search_component(OBJECT *object, char *name);
 void o_attrib_slot_update(TOPLEVEL *toplevel, OBJECT *object);
 void o_attrib_slot_copy(TOPLEVEL *toplevel, OBJECT *original, OBJECT *target);
 char *o_attrib_search_toplevel_all(GedaPageList *page_list, char *name);
-OBJECT **o_attrib_return_attribs(OBJECT *object);
-void o_attrib_free_returned(OBJECT **found_objects);
+GList *o_attrib_return_attribs(OBJECT *object);
 
 /* o_basic.c */
 int inside_region(int xmin, int ymin, int xmax, int ymax, int x, int y);
diff --git a/libgeda/src/o_attrib.c b/libgeda/src/o_attrib.c
index c94d10f..e177d57 100644
--- a/libgeda/src/o_attrib.c
+++ b/libgeda/src/o_attrib.c
@@ -1491,82 +1491,44 @@ char *o_attrib_search_toplevel_all(GedaPageList *page_list, char *name)
   return(NULL);
 }
 
-/*! \brief Get all attached attributes to specified OBJECT.
+/*! \brief Get all attached attributes of the specified OBJECT.
  *  \par Function Description
- *  This function returns all attached attribute objects to the
- *  specified object.
- *  The returned list is an array of objects and should be freed using the
- *  #o_attrib_free_returned() function.
- *  This function will only look for attached attributes and not
- *  unattached free floating attribs.
+ *  This function returns all attached attributes of the specified object.
+ *
+ *  The returned GList should be freed using the #g_list_free().
+ *
+ *  This function does not look for inherited attributes. (Inherited
+ *  attributes are those which live as toplevel un-attached attributes
+ *  inside in a complex OBJECT's prim_objs).
  *
  *  \param [in] object       OBJECT whos attributes to return.
- *  \return An array of objects that attached to object, NULL otherwise.
+ *  \return A GList of attributes belinging to the passed object.
  */
-OBJECT ** o_attrib_return_attribs(OBJECT *object)
+GList * o_attrib_return_attribs (OBJECT *object)
 {
-  OBJECT **found_objects;
-  int num_attribs=0;
-  int i=0;
+  GList *attribs = NULL;
   OBJECT *a_current;
   GList *a_iter;
+  char *name;
 
-  if (!object || !object->attribs) {
-    return(NULL);
-  }
-
-  /* first count the number of attribs */
-  num_attribs = g_list_length (object->attribs);
-
-  found_objects = (OBJECT **) g_malloc(sizeof(OBJECT *)*(num_attribs+1));
+  g_return_val_if_fail (object != NULL, NULL);
 
-  /* now actually fill the array of objects */
-  a_iter = object->attribs;
-  while(a_iter != NULL) {
+  /* Directly attached attributes */
+  for (a_iter = object->attribs; a_iter != NULL;
+       a_iter = g_list_next (a_iter)) {
     a_current = a_iter->data;
-    if (a_current->type == OBJ_TEXT &&
-        a_current->text->string) {
-      found_objects[i] = a_current;
-      i++;
-    }
-    a_iter = g_list_next (a_iter);
-  }
 
-  found_objects[i] = NULL;
+    if (a_current->type != OBJ_TEXT)
+      continue;
 
-#if DEBUG 
-  i=0;
-  while(found_objects[i] != NULL) {
-    /*for (i = 0 ; i < num_attribs; i++) {*/
-    printf("%d : %s\n", i, found_objects[i]->text->string);
-    i++;
-  }
-#endif
-
-  return(found_objects);
-}
+    /* Don't add invalid attributes to the list */
+    if (!o_attrib_get_name_value (a_current->text->string, &name, NULL))
+      continue;
 
-/*! \brief Free attached attribute list.
- *  \par Function Description
- *  Free attached attribute list. Use only on a list created
- *  by #o_attrib_return_attribs().
- *
- *  \param [in] found_objects  List returned by #o_attrib_return_attribs().
- */
-void o_attrib_free_returned(OBJECT **found_objects)
-{
-  int i=0;
-
-  if (!found_objects) {
-    return;
-  }
+    attribs = g_list_prepend (attribs, a_current);
 
-  /* don't free the insides of found_objects, since the contents are */
-  /* just pointers into the real object list */
-  while(found_objects[i] != NULL) {
-    found_objects[i] = NULL;
-    i++;	
   }
 
-  g_free(found_objects);
+  attribs = g_list_reverse (attribs);
+  return attribs;
 }




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