make the iteration code more flexible. add tooltips to gtk config store
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Wed, 14 May 2008 13:33:55 -0700
changeset 3069 4730d8d6d63c
parent 3068 95ea2e729bf5
child 3070 45d8e899c535
make the iteration code more flexible. add tooltips to gtk config store
src/contrib/attribute-iterator.cc
src/contrib/attribute-iterator.h
src/contrib/gtk-config-store.cc
--- a/src/contrib/attribute-iterator.cc	Wed May 14 10:06:04 2008 -0700
+++ b/src/contrib/attribute-iterator.cc	Wed May 14 13:33:55 2008 -0700
@@ -24,7 +24,9 @@
   for (uint32_t i = 0; i < Config::GetRootNamespaceObjectN (); ++i)
     {
       Ptr<Object> object = Config::GetRootNamespaceObject (i);
+      StartVisitObject (object);
       DoIterate (object);
+      EndVisitObject ();
     }
   NS_ASSERT (m_currentPath.empty ());
   NS_ASSERT (m_examined.empty ());
@@ -59,22 +61,104 @@
   return oss.str ();
 }
 
+std::string
+AttributeIterator::GetCurrentPath (void) const
+{
+  std::ostringstream oss;
+  for (uint32_t i = 0; i < m_currentPath.size (); ++i)
+    {
+      oss << "/" << m_currentPath[i];
+    }
+  return oss.str ();
+}
+
 void 
-AttributeIterator::Push (std::string name)
+AttributeIterator::DoStartVisitObject (Ptr<Object> object)
+{}
+void 
+AttributeIterator::DoEndVisitObject (void)
+{}
+void 
+AttributeIterator::DoStartVisitPointerAttribute (Ptr<Object> object, std::string name, Ptr<Object> item)
+{}
+void 
+AttributeIterator::DoEndVisitPointerAttribute (void)
+{}
+void 
+AttributeIterator::DoStartVisitArrayAttribute (Ptr<Object> object, std::string name, const ObjectVectorValue &vector)
+{}
+void 
+AttributeIterator::DoEndVisitArrayAttribute (void)
+{}
+void 
+AttributeIterator::DoStartVisitArrayItem (const ObjectVectorValue &vector, uint32_t index, Ptr<Object> item)
+{}
+void 
+AttributeIterator::DoEndVisitArrayItem (void)
+{}
+
+void 
+AttributeIterator::VisitAttribute (Ptr<Object> object, std::string name)
 {
   m_currentPath.push_back (name);
-  DoPush (name, GetCurrentPath (""));
+  DoVisitAttribute (object, name);
+  m_currentPath.pop_back ();
+}
+
+void 
+AttributeIterator::StartVisitObject (Ptr<Object> object)
+{
+  m_currentPath.push_back ("$" + object->GetInstanceTypeId ().GetName ());
+  DoStartVisitObject (object);
 }
 void 
-AttributeIterator::Pop (void)
+AttributeIterator::EndVisitObject (void)
+{
+  m_currentPath.pop_back ();
+  DoEndVisitObject ();
+}
+void 
+AttributeIterator::StartVisitPointerAttribute (Ptr<Object> object, std::string name, Ptr<Object> value)
 {
-  DoPop ();
+  m_currentPath.push_back (name);
+  m_currentPath.push_back ("$" + value->GetInstanceTypeId ().GetName ());
+  DoStartVisitPointerAttribute (object, name, value);
+}
+void 
+AttributeIterator::EndVisitPointerAttribute (void)
+{
   m_currentPath.pop_back ();
+  m_currentPath.pop_back ();
+  DoEndVisitPointerAttribute ();
 }
-void
-AttributeIterator::Visit (Ptr<Object> object, std::string name)
+void 
+AttributeIterator::StartVisitArrayAttribute (Ptr<Object> object, std::string name, const ObjectVectorValue &vector)
+{
+  m_currentPath.push_back (name);
+  DoStartVisitArrayAttribute (object, name, vector);
+}
+void 
+AttributeIterator::EndVisitArrayAttribute (void)
 {
-  DoVisit (object, name, GetCurrentPath (name));
+  m_currentPath.pop_back ();
+  DoEndVisitArrayAttribute ();
+}
+
+void 
+AttributeIterator::StartVisitArrayItem (const ObjectVectorValue &vector, uint32_t index, Ptr<Object> item)
+{
+  std::ostringstream oss;
+  oss << index;
+  m_currentPath.push_back (oss.str ());
+  m_currentPath.push_back ("$" + item->GetInstanceTypeId ().GetName ());
+  DoStartVisitArrayItem (vector, index, item);
+}
+void 
+AttributeIterator::EndVisitArrayItem (void)
+{
+  m_currentPath.pop_back ();
+  m_currentPath.pop_back ();
+  DoEndVisitArrayItem ();
 }
 
 
@@ -86,7 +170,6 @@
       return;
     }
   TypeId tid = object->GetInstanceTypeId ();
-  Push ("$" + tid.GetName ());
   NS_LOG_DEBUG ("store " << tid.GetName ());
   for (uint32_t i = 0; i < tid.GetAttributeN (); ++i)
     {
@@ -100,11 +183,11 @@
 	  Ptr<Object> tmp = ptr.Get<Object> ();
 	  if (tmp != 0)
 	    {
-	      Push (tid.GetAttributeName (i));
+	      StartVisitPointerAttribute (object, tid.GetAttributeName (i), tmp);
 	      m_examined.push_back (object);
 	      DoIterate (tmp);
 	      m_examined.pop_back ();
-	      Pop ();
+	      EndVisitPointerAttribute ();
 	    }
 	  continue;
 	}
@@ -115,20 +198,18 @@
 	  NS_LOG_DEBUG ("vector attribute " << tid.GetAttributeName (i));
 	  ObjectVectorValue vector;
 	  object->GetAttribute (tid.GetAttributeName (i), vector);
-	  Push (tid.GetAttributeName (i));
+	  StartVisitArrayAttribute (object, tid.GetAttributeName (i), vector);
 	  for (uint32_t j = 0; j < vector.GetN (); ++j)
 	    {
 	      NS_LOG_DEBUG ("vector attribute item " << j);
 	      Ptr<Object> tmp = vector.Get (j);
-	      std::ostringstream oss;
-	      oss << j;
-	      Push (oss.str ());
+	      StartVisitArrayItem (vector, j, tmp);
 	      m_examined.push_back (object);
 	      DoIterate (tmp);
 	      m_examined.pop_back ();
-	      Pop ();
+	      EndVisitArrayItem ();
 	    }
-	  Pop ();
+	  EndVisitArrayAttribute ();
 	  continue;
 	}
       uint32_t flags = tid.GetAttributeFlags (i);
@@ -136,7 +217,7 @@
       if ((flags & TypeId::ATTR_GET) && accessor->HasGetter () &&
 	  (flags & TypeId::ATTR_SET) && accessor->HasSetter ())
 	{
-	  Visit (object, tid.GetAttributeName (i));
+	  VisitAttribute (object, tid.GetAttributeName (i));
 	}
       else
 	{
@@ -159,32 +240,25 @@
       while (iter.HasNext ())
 	{
 	  Ptr<Object> tmp = const_cast<Object *> (PeekPointer (iter.Next ()));
+	  StartVisitObject (tmp);
 	  m_examined.push_back (object);
 	  DoIterate (tmp);
 	  m_examined.pop_back ();
+	  EndVisitObject ();
 	}
     }
-  Pop ();
 }
 
-
-
 TextFileAttributeIterator::TextFileAttributeIterator (std::ostream &os)
   : m_os (os)
 {}
 void 
-TextFileAttributeIterator::DoVisit (Ptr<Object> object, std::string name, std::string path)
+TextFileAttributeIterator::DoVisitAttribute (Ptr<Object> object, std::string name)
 {
   StringValue str;
   object->GetAttribute (name, str);
-  m_os << path << " " << str.Get () << std::endl;
+  m_os << GetCurrentPath () << " " << str.Get () << std::endl;
 }
-void 
-TextFileAttributeIterator::DoPush (std::string name, std::string path)
-{}
-void 
-TextFileAttributeIterator::DoPop (void)
-{}
 
 void 
 TextFileAttributeIterator::Save (void)
--- a/src/contrib/attribute-iterator.h	Wed May 14 10:06:04 2008 -0700
+++ b/src/contrib/attribute-iterator.h	Wed May 14 13:33:55 2008 -0700
@@ -7,6 +7,8 @@
 
 namespace ns3 {
 
+class ObjectVectorValue;
+
 class AttributeIterator
 {
 public:
@@ -14,17 +16,32 @@
   virtual ~AttributeIterator ();
 
   void Iterate (void);
+protected:
+  std::string GetCurrentPath (void) const;
 private:
-  virtual void DoVisit (Ptr<Object> object, std::string name, std::string path) = 0;
-  virtual void DoPush (std::string name, std::string path) = 0;
-  virtual void DoPop (void) = 0;
+  virtual void DoVisitAttribute (Ptr<Object> object, std::string name) = 0;
+  virtual void DoStartVisitObject (Ptr<Object> object);
+  virtual void DoEndVisitObject (void);
+  virtual void DoStartVisitPointerAttribute (Ptr<Object> object, std::string name, Ptr<Object> value);
+  virtual void DoEndVisitPointerAttribute (void);
+  virtual void DoStartVisitArrayAttribute (Ptr<Object> object, std::string name, const ObjectVectorValue &vector);
+  virtual void DoEndVisitArrayAttribute (void);
+  virtual void DoStartVisitArrayItem (const ObjectVectorValue &vector, uint32_t index, Ptr<Object> item);
+  virtual void DoEndVisitArrayItem (void);
 
   void DoIterate (Ptr<Object> object);
   bool IsExamined (Ptr<const Object> object);
   std::string GetCurrentPath (std::string attr) const;
-  void Push (std::string name);
-  void Pop (void);
-  void Visit (Ptr<Object> object, std::string name);
+
+  void VisitAttribute (Ptr<Object> object, std::string name);
+  void StartVisitObject (Ptr<Object> object);
+  void EndVisitObject (void);
+  void StartVisitPointerAttribute (Ptr<Object> object, std::string name, Ptr<Object> value);
+  void EndVisitPointerAttribute (void);
+  void StartVisitArrayAttribute (Ptr<Object> object, std::string name, const ObjectVectorValue &vector);
+  void EndVisitArrayAttribute (void);
+  void StartVisitArrayItem (const ObjectVectorValue &vector, uint32_t index, Ptr<Object> item);
+  void EndVisitArrayItem (void);
 
 
   std::vector<Ptr<Object> > m_examined;
@@ -37,9 +54,7 @@
   TextFileAttributeIterator (std::ostream &os);
   void Save (void);
 private:
-  virtual void DoVisit (Ptr<Object> object, std::string name, std::string path);
-  virtual void DoPush (std::string name, std::string path);
-  virtual void DoPop (void);
+  virtual void DoVisitAttribute (Ptr<Object> object, std::string name);
   std::ostream &m_os;
 };
 
--- a/src/contrib/gtk-config-store.cc	Wed May 14 10:06:04 2008 -0700
+++ b/src/contrib/gtk-config-store.cc	Wed May 14 13:33:55 2008 -0700
@@ -2,6 +2,7 @@
 #include "attribute-iterator.h"
 #include "ns3/config.h"
 #include "ns3/string.h"
+#include "ns3/pointer.h"
 #include <gtk/gtk.h>
 #include <fstream>
 
@@ -9,16 +10,27 @@
 namespace ns3 {
 
 enum {
-  COL_NAME = 0,
-  COL_VALUE,
+  COL_NODE = 0,
   COL_LAST
 };
 
-struct AttributeNode
+struct ModelNode
 {
+  enum {
+    // store object + attribute name
+    NODE_ATTRIBUTE,
+    // store object + attribute name
+    NODE_POINTER,
+    // store object + attribute name
+    NODE_VECTOR,
+    // store index + value (object)
+    NODE_VECTOR_ITEM,
+    // store object
+    NODE_OBJECT
+  } type;
   std::string name;
-  std::string path;
   Ptr<Object> object;
+  uint32_t index;
 };
 
 class ModelCreator : public AttributeIterator
@@ -28,9 +40,15 @@
 
   void Build (GtkTreeStore *treestore);
 private:
-  virtual void DoVisit (Ptr<Object> object, std::string name, std::string path);
-  virtual void DoPush (std::string name, std::string path);
-  virtual void DoPop (void);
+  virtual void DoVisitAttribute (Ptr<Object> object, std::string name);
+  virtual void DoStartVisitObject (Ptr<Object> object);
+  virtual void DoEndVisitObject (void);
+  virtual void DoStartVisitPointerAttribute (Ptr<Object> object, std::string name, Ptr<Object> value);
+  virtual void DoEndVisitPointerAttribute (void);
+  virtual void DoStartVisitArrayAttribute (Ptr<Object> object, std::string name, const ObjectVectorValue &vector);
+  virtual void DoEndVisitArrayAttribute (void);
+  virtual void DoStartVisitArrayItem (const ObjectVectorValue &vector, uint32_t index, Ptr<Object> item);
+  virtual void DoEndVisitArrayItem (void);
 
   GtkTreeStore *m_treestore;
   std::vector<GtkTreeIter *> m_iters;
@@ -46,65 +64,165 @@
   Iterate ();
   NS_ASSERT (m_iters.size () == 1);
 }
+
 void 
-ModelCreator::DoVisit (Ptr<Object> object, std::string name, std::string path)
+ModelCreator::DoVisitAttribute (Ptr<Object> object, std::string name)
 {
-  StringValue str;
-  object->GetAttribute (name, str);
   GtkTreeIter *parent = m_iters.back ();
   GtkTreeIter current;
-  gtk_tree_store_append (m_treestore, &current, parent);
-  AttributeNode *node = new AttributeNode ();
-  node->name = name;
-  node->path = path + "/" + str.Get ();
+  ModelNode *node = new ModelNode ();
+  node->type = ModelNode::NODE_ATTRIBUTE;
   node->object = object;
+  node->name = name;
+  gtk_tree_store_append (m_treestore, &current, parent);
   gtk_tree_store_set (m_treestore, &current,
-		      COL_NAME, g_strdup (name.c_str ()), 
-		      COL_VALUE, node,
-		      -1);
+		      COL_NODE, node,
+                     -1);
 }
 void 
-ModelCreator::DoPush (std::string name, std::string path)
+ModelCreator::DoStartVisitObject (Ptr<Object> object)
 {
   GtkTreeIter *parent = m_iters.back ();
   GtkTreeIter *current = g_new (GtkTreeIter, 1);
+  ModelNode *node = new ModelNode ();
+  node->type = ModelNode::NODE_OBJECT;
+  node->object = object;
   gtk_tree_store_append (m_treestore, current, parent);
   gtk_tree_store_set (m_treestore, current,
-		      COL_NAME, g_strdup (name.c_str ()),
-		      COL_VALUE, NULL, 
+		      COL_NODE, node,
+                     -1);
+  m_iters.push_back (current);
+}
+void 
+ModelCreator::DoEndVisitObject (void)
+{
+  GtkTreeIter *iter = m_iters.back ();
+  g_free (iter);
+  m_iters.pop_back ();
+}
+void 
+ModelCreator::DoStartVisitPointerAttribute (Ptr<Object> object, std::string name, Ptr<Object> value)
+{
+  GtkTreeIter *parent = m_iters.back ();
+  GtkTreeIter *current = g_new (GtkTreeIter, 1);
+  ModelNode *node = new ModelNode ();
+  node->type = ModelNode::NODE_POINTER;
+  node->object = object;
+  node->name = name;
+  gtk_tree_store_append (m_treestore, current, parent);
+  gtk_tree_store_set (m_treestore, current,
+		      COL_NODE, node,
+                     -1);
+  m_iters.push_back (current);
+}
+void 
+ModelCreator::DoEndVisitPointerAttribute (void)
+{
+  GtkTreeIter *iter = m_iters.back ();
+  g_free (iter);
+  m_iters.pop_back ();  
+}
+void 
+ModelCreator::DoStartVisitArrayAttribute (Ptr<Object> object, std::string name, const ObjectVectorValue &vector)
+{
+  GtkTreeIter *parent = m_iters.back ();
+  GtkTreeIter *current = g_new (GtkTreeIter, 1);
+  ModelNode *node = new ModelNode ();
+  node->type = ModelNode::NODE_VECTOR;
+  node->object = object;
+  node->name = name;
+  gtk_tree_store_append (m_treestore, current, parent);
+  gtk_tree_store_set (m_treestore, current,
+		      COL_NODE, node,
                      -1);
   m_iters.push_back (current);
 }
 void 
-ModelCreator::DoPop (void)
+ModelCreator::DoEndVisitArrayAttribute (void)
+{
+  GtkTreeIter *iter = m_iters.back ();
+  g_free (iter);
+  m_iters.pop_back ();  
+}
+void 
+ModelCreator::DoStartVisitArrayItem (const ObjectVectorValue &vector, uint32_t index, Ptr<Object> item)
 {
-  GtkTreeIter *current = m_iters.back ();
-  g_free (current);
-  m_iters.pop_back ();
+  GtkTreeIter *parent = m_iters.back ();
+  GtkTreeIter *current = g_new (GtkTreeIter, 1);
+  ModelNode *node = new ModelNode ();
+  node->type = ModelNode::NODE_VECTOR_ITEM;
+  node->object = item;
+  node->index = index;
+  gtk_tree_store_append (m_treestore, current, parent);
+  gtk_tree_store_set (m_treestore, current,
+		      COL_NODE, node,
+                     -1);
+  m_iters.push_back (current);
+}
+void 
+ModelCreator::DoEndVisitArrayItem (void)
+{
+  GtkTreeIter *iter = m_iters.back ();
+  g_free (iter);
+  m_iters.pop_back ();  
 }
 
 static void
-attribute_cell_data_function (GtkTreeViewColumn *col,
-			      GtkCellRenderer   *renderer,
-			      GtkTreeModel      *model,
-			      GtkTreeIter       *iter,
-			      gpointer           user_data)
+cell_data_function_col_1 (GtkTreeViewColumn *col,
+			  GtkCellRenderer   *renderer,
+			  GtkTreeModel      *model,
+			  GtkTreeIter       *iter,
+			  gpointer           user_data)
 {
-  AttributeNode *node = 0;
-  gtk_tree_model_get (model, iter, COL_VALUE, &node, -1);
-  if (node != 0)
+  ModelNode *node;
+  gtk_tree_model_get (model, iter, COL_NODE, &node, -1);
+  if (node->type == ModelNode::NODE_ATTRIBUTE)
     {
       StringValue str;
       node->object->GetAttribute (node->name, str);
       g_object_set(renderer, "text", str.Get ().c_str (), NULL);
+      g_object_set(renderer, "editable", TRUE, NULL);
     }
   else
     {
       g_object_set(renderer, "text", "", NULL);
+      g_object_set(renderer, "editable", FALSE, NULL);
     }
 }
 
 static void
+cell_data_function_col_0 (GtkTreeViewColumn *col,
+			  GtkCellRenderer   *renderer,
+			  GtkTreeModel      *model,
+			  GtkTreeIter       *iter,
+			  gpointer           user_data)
+{
+  ModelNode *node;
+  gtk_tree_model_get (model, iter, COL_NODE, &node, -1);
+  g_object_set (renderer, "editable", FALSE, NULL);
+  switch (node->type) {
+  case ModelNode::NODE_OBJECT:
+    g_object_set(renderer, "text", node->object->GetInstanceTypeId ().GetName ().c_str (), NULL);
+    break;
+  case ModelNode::NODE_POINTER:
+    g_object_set(renderer, "text", node->name.c_str (), NULL);
+    break;
+  case ModelNode::NODE_VECTOR:
+    g_object_set(renderer, "text", node->name.c_str (), NULL);
+    break;
+  case ModelNode::NODE_VECTOR_ITEM: {
+    std::stringstream oss;
+    oss << node->index;
+    g_object_set(renderer, "text", oss.str ().c_str (), NULL);
+  } break;
+  case ModelNode::NODE_ATTRIBUTE:
+    g_object_set(renderer, "text", node->name.c_str (), NULL);
+    break;
+  }
+}
+
+
+static void
 cell_edited_callback (GtkCellRendererText *cell,
 		      gchar               *path_string,
 		      gchar               *new_text,
@@ -113,11 +231,114 @@
   GtkTreeModel *model = GTK_TREE_MODEL (user_data);
   GtkTreeIter iter;
   gtk_tree_model_get_iter_from_string (model, &iter, path_string);
-  AttributeNode *node;
-  gtk_tree_model_get (model, &iter, COL_VALUE, &node, -1);
+  ModelNode *node;
+  gtk_tree_model_get (model, &iter, COL_NODE, &node, -1);
+  NS_ASSERT (node->type == ModelNode::NODE_ATTRIBUTE);
   node->object->SetAttribute (node->name, StringValue (new_text));
 }
 
+static int
+get_col_number_from_tree_view_column (GtkTreeViewColumn *col)
+{
+  GList *cols;
+  int   num;
+  g_return_val_if_fail ( col != NULL, -1 );
+  g_return_val_if_fail ( col->tree_view != NULL, -1 );
+  cols = gtk_tree_view_get_columns(GTK_TREE_VIEW(col->tree_view));
+  num = g_list_index(cols, (gpointer) col);
+  g_list_free(cols);
+  return num;
+}
+
+static gboolean
+cell_tooltip_callback (GtkWidget  *widget,
+		       gint        x,
+		       gint        y,
+		       gboolean    keyboard_tip,
+		       GtkTooltip *tooltip,
+		       gpointer    user_data)
+{
+  GtkTreeModel *model;
+  GtkTreeIter iter;
+  GtkTreeViewColumn * column;
+  if (!gtk_tree_view_get_tooltip_context (GTK_TREE_VIEW (widget), 
+					  &x, &y, keyboard_tip,
+					  &model, NULL, &iter))
+    {
+      return FALSE;
+    }
+  if (!gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget),
+				      x, y, NULL, &column, NULL, NULL))
+    {
+      return FALSE;
+    }  
+  int col = get_col_number_from_tree_view_column (column);
+
+  ModelNode *node;
+  gtk_tree_model_get (model, &iter, COL_NODE, &node, -1);
+
+  switch (node->type) {
+  case ModelNode::NODE_OBJECT:
+    if (col == 0)
+      {
+	std::string tip = "This object is of type " + node->object->GetInstanceTypeId ().GetName ();
+	gtk_tooltip_set_text (tooltip, tip.c_str ());
+	return TRUE;
+      }
+    break;
+  case ModelNode::NODE_POINTER:
+    if (col == 0)
+      {
+	PointerValue ptr;
+	node->object->GetAttribute (node->name, ptr);
+	std::string tip = "This object is of type " + ptr.GetObject ()->GetInstanceTypeId ().GetName ();
+	gtk_tooltip_set_text (tooltip, tip.c_str ());
+	return TRUE;
+      }
+    break;
+  case ModelNode::NODE_VECTOR:
+    break;
+  case ModelNode::NODE_VECTOR_ITEM:
+    if (col == 0)
+      {
+	std::string tip = "This object is of type " + node->object->GetInstanceTypeId ().GetName ();
+	gtk_tooltip_set_text (tooltip, tip.c_str ());
+	return TRUE;
+      }
+    break;
+  case ModelNode::NODE_ATTRIBUTE: {
+    TypeId tid = node->object->GetInstanceTypeId ();
+    uint32_t attrIndex;
+    for (uint32_t i = 0; i < tid.GetAttributeN (); ++i)
+      {
+	if (tid.GetAttributeName (i) == node->name)
+	  {
+	    attrIndex = i;
+	    break;
+	  }
+      }
+    if (col == 0)
+      {
+	std::string tip = tid.GetAttributeHelp (attrIndex);
+	gtk_tooltip_set_text (tooltip, tip.c_str ());
+      }
+    else
+      {
+	Ptr<const AttributeChecker> checker = tid.GetAttributeChecker (attrIndex);
+	std::string tip;
+	tip = "This attribute is of type " + checker->GetValueTypeName ();
+	if (checker->HasUnderlyingTypeInformation ())
+	  {
+	    tip += " " + checker->GetUnderlyingTypeInformation ();
+	  }
+	gtk_tooltip_set_text (tooltip, tip.c_str ());
+      }
+    return TRUE;
+  } break;
+  }
+  return FALSE;
+}
+
 
 static GtkWidget *
 create_view_and_model (void)
@@ -126,12 +347,15 @@
   GtkCellRenderer     *renderer;
   GtkWidget           *view;
 
-  GtkTreeStore *model = gtk_tree_store_new (COL_LAST, G_TYPE_STRING, G_TYPE_POINTER);
+  GtkTreeStore *model = gtk_tree_store_new (COL_LAST, G_TYPE_POINTER);
   ModelCreator creator;
   creator.Build (model);
 
 
   view = gtk_tree_view_new();
+  g_object_set (view, "has-tooltip", TRUE, NULL);
+  g_signal_connect (view, "query-tooltip", (GCallback) cell_tooltip_callback, NULL);
+  
   gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), GTK_TREE_VIEW_GRID_LINES_BOTH);
   gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE);
 
@@ -140,16 +364,16 @@
   gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
   renderer = gtk_cell_renderer_text_new ();
   gtk_tree_view_column_pack_start(col, renderer, TRUE);
-  gtk_tree_view_column_add_attribute(col, renderer, "text", COL_NAME);
+  gtk_tree_view_column_set_cell_data_func(col, renderer, cell_data_function_col_0, NULL, NULL);
+  g_object_set(renderer, "editable", FALSE, NULL);
 
   col = gtk_tree_view_column_new();
   gtk_tree_view_column_set_title(col, "Attribute Value");
   gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
   renderer = gtk_cell_renderer_text_new();
-  g_object_set(renderer, "editable", TRUE, NULL);
   g_signal_connect(renderer, "edited", (GCallback) cell_edited_callback, model);
   gtk_tree_view_column_pack_start(col, renderer, TRUE);
-  gtk_tree_view_column_set_cell_data_func(col, renderer, attribute_cell_data_function, NULL, NULL);
+  gtk_tree_view_column_set_cell_data_func(col, renderer, cell_data_function_col_1, NULL, NULL);
 
 
   gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL (model));