Author |
Topic |
|
TreeNode
64 Posts |
Posted - 01/19/2011 : 1:14:32 PM
|
Origin Ver. and Service Release Origin8 SR6 Operating System:Win XP
Hi all,
I want to search in a Tree for TreeNode with special Attribute. For example the Attribute Label is "myID", and value is 7.
I want to check all TreeNodes in this Tree, if one of them got this Attribute and the adequate value.
When TreeNode was found, a Reference should be returned, so that I can manipulate this node.
The reason for my intention is, that I am using GETN macros for User-Interface. When user change values in GetnBox-Dialog or something like that, event function should react on that. In the event function I found out, that the parameter: (..., int nRow, ...) points to the row of GetnBox-Dialog, in which user changed something.
When for example I want to react on user changed value of Drop-Down-List, and this List is in the 5th row, I can check in event_function: if(nRow == 5) -> do something...
The annoying thing is, when I redesign my dialog, I have to adjust all the numbers I used for checking in which row the dialog-element is positioned. So I want to use IDs, that point to special dialog-elements (TreeNodes of the GetNBox-Tree)
The first problem that came up is, that I could not find a function, that checks ALL nodes of a Tree, or a TreeNode, for example in OriginC Reference -> Global Functions -> Tree And what is more, I need the function to return a reference to the found TreeNode, so that I can manipulate it.
I dont want to use a recursiv function to walk the tree, cause I got error message from Origin while runtime: "Error found in pop stack" - but it found the TreeNode. The code for recursiv function:
TreeNode& find_attr_tree_recursiv(const TreeNode& tr, int nID)
{
bool bRet;
int nVal = -1;
// Search in all children of a TreeNode, childrens-childs and so on...
foreach(TreeNode tn in tr.Children)
{
bRet = tn.GetAttribute("myID", nVal);
if(nVal == nID)
return tn;
if(tn.Children.Count() != 0)
find_attr_tree_recursiv(tn, nID); // call function itself -> recursion
}
return tn;
}
void test_recursiv_find_method()
{
Tree tr;
TreeNode tn11, tn12, tn13, tn14, tn15,
tn21, tn22, tn23, tn24, tn25,
tnFound;
// construct example tree
tn11 = tr.AddTextNode("abcd11", "node11", 1);
tn12 = tr.AddTextNode("abcd12", "node12", 1);
tn13 = tr.AddTextNode("abcd13", "node13", 1);
tn14 = tr.AddTextNode("abcd14", "node14", 1);
tn15 = tr.AddTextNode("abcd15", "node15", 1);
tn21 = tn11.AddTextNode("abcd21", "node21", 1);
tn22 = tn12.AddTextNode("abcd22", "node22", 1);
tn23 = tn13.AddTextNode("abcd23", "node23", 1);
tn24 = tn14.AddTextNode("abcd24", "node24", 1);
tn25 = tn15.AddTextNode("abcd25", "node25", 1);
// set special "myID" Attribute to one TreeNode
tn13.SetAttribute("myID", 7);
// show found TreeNode
tnFound = find_attr_tree_recursiv(tr, 7);
out_tree(tnFound);
}
Code for iterativ function, that behaves not as I would expect:
bool walk_tree_iterativ_stack(const TreeNode& tr, int nID)
{
TreeNode tn, tnTmp;
Array<TreeNode&> tnArray;
//tnArray.SetAsOwner(true); --> program crashes if Array set as owner
int nRet, nVal = -1, nIndex = 0, nElements;
bool bRet;
nRet = tnArray.Add(tr);
// Check all TreeNodes stored in Array, if one of them
// has special "myID"-Attribute
while(nIndex < tnArray.GetSize() )
{
// check for "myID"-Attribute
tnTmp = tnArray.GetAt(nIndex);
bRet = tnTmp.GetAttribute("myID", nVal);
if(nVal == nID)
return true; // TreeNode found
// If TreeNode has Childs --> put them into Array
if(tnArray.GetAt(nIndex).Children.Count() != 0)
{
foreach(tn in tnArray.GetAt(nIndex).Children)
{
nRet = tnArray.Add(tn);
}
}
nElements = tnArray.GetSize();
// Increment "Stack-Pointer"
nIndex++;
}
return false; // TreeNode not found
}
void test_walk_tree_iterativ_stack_method()
{
Tree tr;
TreeNode tn11, tn12, tn13, tn14, tn15,
tn21, tn22, tn23, tn24, tn25,
tnFound;
// Construct a example Tree with some nodes...
tn11 = tr.AddTextNode("abcd11", "node11", 11);
tn12 = tr.AddTextNode("abcd12", "node12", 12);
tn13 = tr.AddTextNode("abcd13", "node13", 13);
tn14 = tr.AddTextNode("abcd14", "node14", 14);
tn15 = tr.AddTextNode("abcd15", "node15", 15);
tn21 = tn11.AddTextNode("abcd21", "node21", 21);
tn22 = tn12.AddTextNode("abcd22", "node22", 22);
tn23 = tn13.AddTextNode("abcd23", "node23", 23);
tn24 = tn14.AddTextNode("abcd24", "node24", 24);
tn25 = tn15.AddTextNode("abcd25", "node25", 25);
// Set "myID"-Attribute for one TreeNode
tn13.SetAttribute("myID", 7);
// search for TreeNode with special "myID"-Attribute
bool bRet = walk_tree_iterativ_stack(tr, 7);
// check if TreeNode was found
if(bRet)
out_str("TreeNode found!");
else
out_str("TreeNode NOT found!");
}
Something is wrong with behaviour of Array<TreeNode&>. Adding elements to it seems to work. But when variable nIndex has value: "2", and gets the Element at this position in Array, it gets an element, which I not expect at that index.
...pls have a look at it in debug mode.
|-- TreeNode ...|-- a?? ...|-- ha!! |
|
Iris_Bai
China
Posts |
Posted - 01/19/2011 : 10:50:48 PM
|
Hi,
Please use "DataID" (STR_DATAID_ATTRIB) as attribute name, then use function tree_get_node_by_dataid to find "DataID = 7" tree node recursively.
TreeNode trN;
bool bRecursive = true;
trN = tree_get_node_by_dataid( tr, 7, bRecursive );
Iris |
|
|
TreeNode
64 Posts |
Posted - 01/20/2011 : 1:12:37 PM
|
Hi Iris,
I overlooked, that this function returns the TreeNode, that it found. I am using this fuction for my issue now, and it works fine.
Found also the macros, to add this ID to a TreeNode in GetN-Tree: GETN_ID and GETN_ID_BRANCH for a branch.
Thank you very much!
|-- TreeNode ...|-- a?? ...|-- ha!! |
|
|
|
Topic |
|
|
|