| 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   | 
                
                
                 
                 
                 
                 
                 
                 | 
               
             
           | 
         
       
     |