Turned the view into a tree view. Still only the top level is shown, though.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31746 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2009-07-25 00:22:41 +00:00
parent 20e4297b61
commit c31af1b060
2 changed files with 222 additions and 47 deletions

View File

@ -23,6 +23,105 @@
#include "Variable.h" #include "Variable.h"
class VariablesView::ValueNode : Referenceable {
public:
ValueNode(ValueNode* parent, Variable* variable, TypeComponentPath* path,
const BString& name, Type* type)
:
fParent(parent),
fVariable(variable),
fPath(path),
fName(name),
fType(type)
{
fVariable->AcquireReference();
fPath->AcquireReference();
fType->AcquireReference();
}
~ValueNode()
{
for (int32 i = 0; ValueNode* child = fChildren.ItemAt(i); i++)
child->ReleaseReference();
fVariable->ReleaseReference();
fPath->ReleaseReference();
fType->ReleaseReference();
}
ValueNode* Parent() const
{
return fParent;
}
Variable* GetVariable() const
{
return fVariable;
}
TypeComponentPath* Path() const
{
return fPath;
}
const BString& Name() const
{
return fName;
}
Type* GetType() const
{
return fType;
}
const BVariant& Value() const
{
return fValue;
}
void SetValue(const BVariant& value)
{
fValue = value;
}
int32 CountChildren() const
{
return fChildren.CountItems();
}
ValueNode* ChildAt(int32 index) const
{
return fChildren.ItemAt(index);
}
int32 IndexOf(ValueNode* child) const
{
return fChildren.IndexOf(child);
}
bool AddChild(ValueNode* child)
{
if (!fChildren.AddItem(child))
return false;
child->AcquireReference();
return true;
}
private:
typedef BObjectList<ValueNode> ChildList;
private:
ValueNode* fParent;
Variable* fVariable;
TypeComponentPath* fPath;
BString fName;
Type* fType;
BVariant fValue;
ChildList fChildren;
};
// #pragma mark - VariableValueColumn // #pragma mark - VariableValueColumn
@ -118,12 +217,12 @@ private:
// #pragma mark - VariableTableModel // #pragma mark - VariableTableModel
class VariablesView::VariableTableModel : public TableModel { class VariablesView::VariableTableModel : public TreeTableModel {
public: public:
VariableTableModel() VariableTableModel()
: :
fStackFrame(NULL), fStackFrame(NULL),
fValues(NULL) fNodes(20, true)
{ {
} }
@ -134,44 +233,48 @@ public:
void SetStackFrame(Thread* thread, StackFrame* stackFrame) void SetStackFrame(Thread* thread, StackFrame* stackFrame)
{ {
if (fValues != NULL) { if (!fNodes.IsEmpty()) {
fValues->ReleaseReference(); int32 count = fNodes.CountItems();
fValues = NULL; fNodes.MakeEmpty();
} NotifyNodesRemoved(TreeTablePath(), 0, count);
if (fStackFrame != NULL) {
int32 rowCount = CountRows();
fStackFrame = NULL;
NotifyRowsRemoved(0, rowCount);
} }
fStackFrame = stackFrame; fStackFrame = stackFrame;
fThread = thread; fThread = thread;
if (fStackFrame != NULL) { if (fStackFrame != NULL) {
try { for (int32 i = 0; Variable* variable = fStackFrame->ParameterAt(i);
AutoLocker<Team> locker(fThread->GetTeam()); i++) {
fValues = new StackFrameValues(*fStackFrame->Values()); _AddNode(variable);
} catch (std::bad_alloc) {
} }
NotifyRowsAdded(0, CountRows()); for (int32 i = 0; Variable* variable
= fStackFrame->LocalVariableAt(i); i++) {
_AddNode(variable);
}
if (!fNodes.IsEmpty())
NotifyNodesAdded(TreeTablePath(), 0, fNodes.CountItems());
} }
} }
void StackFrameValueRetrieved(StackFrame* stackFrame, Variable* variable, void StackFrameValueRetrieved(StackFrame* stackFrame, Variable* variable,
TypeComponentPath* path) TypeComponentPath* path)
{ {
if (stackFrame != fStackFrame || fValues == NULL) if (stackFrame != fStackFrame)
return; return;
// update the respective value // update the respective node's value
AutoLocker<Team> locker(fThread->GetTeam()); AutoLocker<Team> locker(fThread->GetTeam());
BVariant value; BVariant value;
if (fStackFrame->Values()->GetValue(variable->ID(), path, value)) { if (fStackFrame->Values()->GetValue(variable->ID(), path, value)) {
fValues->SetValue(variable->ID(), path, value); ValueNode* node = _GetNode(variable, path);
NotifyRowsChanged(0, CountRows()); TreeTablePath treePath;
// TODO: Only notify for the respective node. if (node != NULL && _GetTreePath(node, treePath)) {
node->SetValue(value);
int32 index = treePath.RemoveLastComponent();
NotifyNodesChanged(treePath, index, 1);
}
} }
} }
@ -180,44 +283,115 @@ public:
return 2; return 2;
} }
virtual int32 CountRows() const virtual void* Root() const
{ {
return fStackFrame != NULL return (void*)this;
? fStackFrame->CountParameters()
+ fStackFrame->CountLocalVariables()
: 0;
} }
virtual bool GetValueAt(int32 rowIndex, int32 columnIndex, BVariant& _value) virtual int32 CountChildren(void* parent) const
{ {
if (fStackFrame == NULL) if (parent == this)
return false; return fNodes.CountItems();
int32 parameterCount = fStackFrame->CountParameters(); return ((ValueNode*)parent)->CountChildren();
const Variable* variable = rowIndex < parameterCount }
? fStackFrame->ParameterAt(rowIndex)
: fStackFrame->LocalVariableAt(rowIndex - parameterCount); virtual void* ChildAt(void* parent, int32 index) const
if (variable == NULL) {
return false; if (parent == this)
return fNodes.ItemAt(index);
return ((ValueNode*)parent)->ChildAt(index);
}
virtual bool GetValueAt(void* object, int32 columnIndex, BVariant& _value)
{
ValueNode* node = (ValueNode*)object;
switch (columnIndex) { switch (columnIndex) {
case 0: case 0:
_value.SetTo(variable->Name(), B_VARIANT_DONT_COPY_DATA); _value.SetTo(node->Name(), B_VARIANT_DONT_COPY_DATA);
return true; return true;
case 1: case 1:
if (fValues == NULL) if (node->Value().Type() == 0)
return false; return false;
return fValues->GetValue(variable->ID(), TypeComponentPath(),
_value); _value = node->Value();
return true;
default: default:
return false; return false;
} }
} }
private:
typedef BObjectList<ValueNode> ValueList;
private:
void _AddNode(Variable* variable)
{
TypeComponentPath* path = new(std::nothrow) TypeComponentPath;
if (path == NULL)
return;
Reference<TypeComponentPath> pathReference(path, true);
ValueNode* node = new(std::nothrow) ValueNode(NULL, variable, path,
variable->Name(), variable->GetType());
if (node == NULL || !fNodes.AddItem(node)) {
delete node;
return;
}
}
ValueNode* _GetNode(Variable* variable, TypeComponentPath* path) const
{
// find the variable node
ValueNode* node;
for (int32 i = 0; (node = fNodes.ItemAt(i)) != NULL; i++) {
if (node->GetVariable() == variable)
break;
}
if (node == NULL)
return NULL;
// now walk along the path, finding the respective child node for each
// component
int32 componentCount = path->CountComponents();
for (int32 i = 0; i < componentCount; i++) {
ValueNode* childNode = NULL;
TypeComponent typeComponent = path->ComponentAt(i);
for (int32 k = 0; (childNode = node->ChildAt(k)) != NULL; k++) {
if (childNode->Path()->ComponentAt(i) == typeComponent)
break;
}
if (childNode == NULL)
return NULL;
node = childNode;
}
return node;
}
bool _GetTreePath(ValueNode* node, TreeTablePath& _path) const
{
// recurse, if the node has a parent
if (ValueNode* parent = node->Parent()) {
if (!_GetTreePath(parent, _path))
return false;
return _path.AddComponent(parent->IndexOf(node));
}
// no parent -- get the index and start the path
int32 index = fNodes.IndexOf(node);
_path.Clear();
return index >= 0 && _path.AddComponent(index);
}
private: private:
Thread* fThread; Thread* fThread;
StackFrame* fStackFrame; StackFrame* fStackFrame;
StackFrameValues* fValues; ValueList fNodes;
}; };
@ -240,7 +414,7 @@ VariablesView::VariablesView(Listener* listener)
VariablesView::~VariablesView() VariablesView::~VariablesView()
{ {
SetStackFrame(NULL, NULL); SetStackFrame(NULL, NULL);
fVariableTable->SetTableModel(NULL); fVariableTable->SetTreeTableModel(NULL);
delete fVariableTableModel; delete fVariableTableModel;
} }
@ -308,7 +482,7 @@ VariablesView::StackFrameValueRetrieved(StackFrame* stackFrame,
void void
VariablesView::_Init() VariablesView::_Init()
{ {
fVariableTable = new Table("variable list", 0, B_FANCY_BORDER); fVariableTable = new TreeTable("variable list", 0, B_FANCY_BORDER);
AddChild(fVariableTable->ToView()); AddChild(fVariableTable->ToView());
// columns // columns
@ -318,9 +492,9 @@ VariablesView::_Init()
B_TRUNCATE_END, B_ALIGN_RIGHT)); B_TRUNCATE_END, B_ALIGN_RIGHT));
fVariableTableModel = new VariableTableModel; fVariableTableModel = new VariableTableModel;
fVariableTable->SetTableModel(fVariableTableModel); fVariableTable->SetTreeTableModel(fVariableTableModel);
fVariableTable->AddTableListener(this); fVariableTable->AddTreeTableListener(this);
} }

View File

@ -8,7 +8,7 @@
#include <GroupView.h> #include <GroupView.h>
#include "table/Table.h" #include "table/TreeTable.h"
class StackFrame; class StackFrame;
@ -17,7 +17,7 @@ class TypeComponentPath;
class Variable; class Variable;
class VariablesView : public BGroupView, private TableListener { class VariablesView : public BGroupView, private TreeTableListener {
public: public:
class Listener; class Listener;
@ -35,6 +35,7 @@ public:
TypeComponentPath* path); TypeComponentPath* path);
private: private:
class ValueNode;
class VariableValueColumn; class VariableValueColumn;
class VariableTableModel; class VariableTableModel;
@ -46,7 +47,7 @@ private:
private: private:
Thread* fThread; Thread* fThread;
StackFrame* fStackFrame; StackFrame* fStackFrame;
Table* fVariableTable; TreeTable* fVariableTable;
VariableTableModel* fVariableTableModel; VariableTableModel* fVariableTableModel;
Listener* fListener; Listener* fListener;
}; };