--- 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/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, ¤t, 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, ¤t, parent);
gtk_tree_store_set (m_treestore, ¤t,
- 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));