void ChangeNodeHeirarchy::StorePreviousParents()
{
	for (HierarchyTreeNode::HIERARCHYTREENODESIDLIST::iterator iter = items.begin();
		 iter != items.end();
		 ++iter)
	{
		HierarchyTreeNode* node = HierarchyTreeController::Instance()->GetTree().GetNode((*iter));
		if (!node)
		{
			continue;
		}
		
		HierarchyTreeNode* parentNode = node->GetParent();
		if (!parentNode)
		{
			continue;
		}
		
		HierarchyTreeNode::HIERARCHYTREENODEID addAfter = HierarchyTreeNode::HIERARCHYTREENODEID_EMPTY;
		HierarchyTreeNode::HIERARCHYTREENODEID lastId = HierarchyTreeNode::HIERARCHYTREENODEID_EMPTY;
		const HierarchyTreeNode::HIERARCHYTREENODESLIST& childs = parentNode->GetChildNodes();
		for (HierarchyTreeNode::HIERARCHYTREENODESLIST::const_iterator citer = childs.begin();
			 citer != childs.end();
			 ++citer)
		{
			if (node == (*citer))
				addAfter = lastId;
			lastId = (*citer)->GetId();
		}
		
		// The Previous Parents are stored in the "item ID - parent ID" map.
		this->previousParents.insert(std::make_pair(*iter, PreviousState(parentNode->GetId(), addAfter)));
	}
}
// Initialize the control(s) attached.
void UIButtonMetadata::InitializeControl(const String& controlName, const Vector2& position)
{
    BaseMetadata::InitializeControl(controlName, position);

    int paramsCount = this->GetParamsCount();
    for (BaseMetadataParams::METADATAPARAMID i = 0; i < paramsCount; i ++)
    {
        UIButton* button = dynamic_cast<UIButton*>(this->treeNodeParams[i].GetUIControl());

        WideString controlText = StringToWString(button->GetName());
        HierarchyTreeNode* activeNode = GetTreeNode(i);
    
        // Initialize the button for all states.
        int statesCount = UIControlStateHelper::GetUIControlStatesCount();
        for (int stateID = 0; stateID < statesCount; stateID ++)
        {
            UIControl::eControlState state = UIControlStateHelper::GetUIControlState(stateID);
            button->SetStateFont(state, EditorFontManager::Instance()->GetDefaultFont());
            button->SetStateText(state, controlText);

            // Button is state-aware.
            activeNode->GetExtraData().SetLocalizationKey(controlText, state);
        }
        
        // Define some properties for the reference state.
        button->SetStateDrawType(GetReferenceState(), UIControlBackground::DRAW_SCALE_TO_RECT);
    }
}
void DeleteSelectedNodeCommand::DecrementUnsavedChanges()
{
	switch (type)
	{
		case TYPE_PLATFORM:
		case TYPE_SCREEN:
			HierarchyTreeController::Instance()->GetTree().GetNode((parentId))->DecrementUnsavedChanges();
			break;

		case TYPE_AGGREGATOR:
			HierarchyTreeController::Instance()->GetTree().GetNode((parentId))->DecrementUnsavedChanges();
			for (Set<HierarchyTreeNode::HIERARCHYTREENODEID>::iterator it = parentsOfRemovingAggregatorControls.begin();
				 it != parentsOfRemovingAggregatorControls.end();
				 ++it)
			{
				HierarchyTreeNode* node = HierarchyTreeController::Instance()->GetTree().GetNode(*it);
				if (node)
				{
					node->DecrementUnsavedChanges();
				}
			}
			break;

		case TYPE_CONTROLS:
		default:
			BaseCommand::DecrementUnsavedChanges();
			break;
	}
}
void HierarchyTreeControl::HandleDropHierarchyMimeData(QDropEvent *event, const HierarchyTreeControlMimeData* mimeData)
{
	HierarchyTreeNode::HIERARCHYTREENODEID insertInTo = HierarchyTreeNode::HIERARCHYTREENODEID_EMPTY;
	HierarchyTreeNode::HIERARCHYTREENODEID insertAfter = HierarchyTreeNode::HIERARCHYTREENODEID_EMPTY;
	if (!GetMoveItemID(event, insertInTo, insertAfter))
		return;
	
	HierarchyTreeNode* parentNode = HierarchyTreeController::Instance()->GetTree().GetNode(insertInTo);
	if (!parentNode)
	{
		parentNode = (HierarchyTreeNode*) HierarchyTreeController::Instance()->GetTree().GetRootNode();
		insertInTo = parentNode->GetId();
	}
	
	if (!mimeData->IsDropEnable(parentNode))
	{
		return;
	}
		
	//Copy current selected item(s) if ctrl key is pressed during drag
	if (event->keyboardModifiers() == Qt::ControlModifier)
	{
		CopyPasteController::Instance()->CopyControls(HierarchyTreeController::Instance()->GetActiveControlNodes());
		CopyPasteController::Instance()->Paste(parentNode);
	}
	else //Otherwise move item(s)
	{
		HierarchyTreeNode::HIERARCHYTREENODESIDLIST items = mimeData->GetItems();
		ChangeNodeHeirarchy* cmd = new ChangeNodeHeirarchy(insertInTo, insertAfter, items);
		CommandsController::Instance()->ExecuteCommand(cmd);
		SafeRelease(cmd);
	}
}
Beispiel #5
0
void HierarchyTreeController::ReturnNodeToScene(const HierarchyTreeNode::HIERARCHYTREENODESLIST& nodesToReturn)
{
	
	for (HierarchyTreeNode::HIERARCHYTREENODESLIST::const_iterator iter = nodesToReturn.begin();
		 iter != nodesToReturn.end(); iter ++)
	{
		HierarchyTreeNode* nodeToReturn = (*iter);
		if (nodeToReturn)
		{
			nodeToReturn->ReturnTreeNodeToScene();
			UnregisterNodeDeletedFromScene(nodeToReturn);
		}
	}

	emit HierarchyTreeUpdated();
	ResetSelectedControl();

	// Select the first one, if any.
	if (nodesToReturn.size() == 0 )
	{
		return;
	}

	HierarchyTreeControlNode* controlNode = dynamic_cast<HierarchyTreeControlNode*>(nodesToReturn.front());
	if (controlNode)
	{
		SelectControl(controlNode);
	}
}
void HierarchyTreeNode::PrepareRemoveFromSceneInformation()
{
	if (!GetParent())
	{
		this->redoParentNode = NULL;
		this->redoPreviousNode = NULL;
		return;
	}

	this->redoParentNode = GetParent();
	this->redoPreviousNode = NULL;

	HierarchyTreeNode* parentNode = GetParent();
	// Look for the Redo Node in the Children List, and remember the previous one.
	// This is needed to restore the previous node position in case of Redo.
	for (List<HierarchyTreeNode*>::const_iterator iter = parentNode->GetChildNodes().begin();
		 iter != parentNode->GetChildNodes().end(); iter ++)
	{
		if ((*iter == this) && (iter != parentNode->GetChildNodes().begin()))
		{
			iter --;
			this->redoPreviousNode = (*iter);
			break;
		}
	}
}
void ChangeNodeHeirarchy::IncrementUnsavedChanges()
{
	HierarchyTreeNode* sourceNode = 0;
	HierarchyTreeNode* targetNode = HierarchyTreeController::Instance()->GetTree().GetNode(targetNodeID);

	switch (this->type)
	{
		case TYPE_PLATFORM:
			// The Platform nodes could only be moved within root node
			targetNode->IncrementUnsavedChanges();
			break;

		case TYPE_SCREEN:
		case TYPE_AGGREGATOR:
			// If Screen nodes are moved within one platform, it's enough to increment unsaved changes only in this platform...
			targetNode->IncrementUnsavedChanges();

			// ...Otherwise we need more complicated handling
			sourceNode = HierarchyTreeController::Instance()->GetTree().GetNode(items.front());
			if (sourceNode != targetNode)
			{
				sourceNode->IncrementUnsavedChanges();

				// Need to mark all screens which being moved to other platform.
				// Otherwise they won't be saved to files at the new location
				// Before mark, need to store current mark state for correct rollback.
				storedMarks.clear();
				for (HierarchyTreeNode::HIERARCHYTREENODESIDLIST::iterator it = items.begin(); it != items.end(); ++it)
				{
					HierarchyTreeNode* node = HierarchyTreeController::Instance()->GetTree().GetNode(*it);
					storedMarks[*it] = node->IsMarked();

					node->SetMarked(true);
				}
			}

			break;

		case TYPE_CONTROLS:
			targetNode->IncrementUnsavedChanges();

			sourceNode = HierarchyTreeController::Instance()->GetScreenNodeForNode(HierarchyTreeController::Instance()->GetTree().GetNode(items.front()));
			if (sourceNode != targetNode)
			{
				sourceNode->IncrementUnsavedChanges();
			}
			break;

		default:
			break;
	}
}
void ChangeNodeHeirarchy::Execute()
{
	HierarchyTreeNode* targetNode = HierarchyTreeController::Instance()->GetTree().GetNode(targetNodeID);
	HierarchyTreeNode* insertAfterNode = HierarchyTreeController::Instance()->GetTree().GetNode(afterNodeID);
	if (!targetNode)
	{
		// Possible in Redo case if some changes in tree were made.
		return;
	}

	
	for (HierarchyTreeNode::HIERARCHYTREENODESIDLIST::iterator iter = items.begin();
		 iter != items.end();
		 ++iter)
	{
		HierarchyTreeNode* node = HierarchyTreeController::Instance()->GetTree().GetNode((*iter));
		if (node)
		{
			if (dynamic_cast<HierarchyTreeScreenNode*>(node))
			{
				HierarchyTreeNode* sourceNode = node->GetParent();

				if (sourceNode != targetNode)
				{
					HierarchyTreeNode::HIERARCHYTREENODESLIST screens;
					screens.push_back(node);
					HierarchyTreeController::Instance()->DeleteNodesFiles(screens);
				}
			}

			//YZ backlight parent rect
			bool isNodeSelected = false;
			HierarchyTreeControlNode* controlNode = dynamic_cast<HierarchyTreeControlNode*>(node);
			if (controlNode)
			{
				isNodeSelected = HierarchyTreeController::Instance()->IsControlSelected(controlNode);
				HierarchyTreeController::Instance()->UnselectControl(controlNode);
			}

			node->SetParent(targetNode, insertAfterNode);
			//insertAfterNode = node;
			
			if (isNodeSelected)
			{
				HierarchyTreeController::Instance()->SelectControl(controlNode);
			}
		}
	}
	
	HierarchyTreeController::Instance()->EmitHierarchyTreeUpdated(false);
	HierarchyTreeController::Instance()->ResetSelectedControl();
}
void CreateControlCommand::PrepareRedoInformation()
{
	// Clone the current control node, remember the pointer to the previous node in the list
	// to restore the position of the node removed in case of Redo.
	HierarchyTreeNode* createdNode = HierarchyTreeController::Instance()->GetTree().GetNode(this->createdControlID);
	if (!createdNode || !createdNode->GetParent())
	{
		this->redoNode = NULL;
		return;
	}
	
	createdNode->PrepareRemoveFromSceneInformation();
	this->redoNode = createdNode;
}
void DeleteSelectedNodeCommand::PrepareRedoInformation()
{
	// Remember the nodes which will be removed from the scene.
	for (HierarchyTreeNode::HIERARCHYTREENODESLIST::iterator iter = this->nodes.begin();
		 iter != this->nodes.end(); iter ++)
	{
		HierarchyTreeNode* nodeToRedo = (*iter);
		if (!nodeToRedo || !nodeToRedo->GetParent())
		{
			continue;
		}

		nodeToRedo->PrepareRemoveFromSceneInformation();
		this->redoNodes.push_back(nodeToRedo);
	}
}
void BaseMetadata::SetStateDirtyForProperty(UIControl::eControlState controlState, const QString& propertyName,
                                            bool value)
{
    // Perform set for all nodes.
    int paramsCount = this->GetParamsCount();
    for (BaseMetadataParams::METADATAPARAMID i = 0; i < paramsCount; i ++)
    {
        HierarchyTreeNode* treeNode = GetTreeNode(i);
        if (!treeNode)
        {
            continue;
        }
        
        treeNode->GetExtraData().SetStatePropertyDirty(controlState, propertyName, value);
    }
}
DeleteSelectedNodeCommand::DeleteSelectedNodeCommand(const HierarchyTreeNode::HIERARCHYTREENODESLIST& nodes, bool needDeleteFiles)
{
	this->nodes = nodes;
	this->deleteFiles = needDeleteFiles;

	DVASSERT(nodes.empty() == false);
	HierarchyTreeNode* itemNode = nodes.front();

	DetectType(itemNode);

	if (type == TYPE_AGGREGATOR)
	{
		StoreParentsOfRemovingAggregatorControls(nodes);
	}

	parentId = itemNode->GetParent()->GetId();
}
void ChangeNodeHeirarchy::Rollback()
{
	for (PARENTNODESMAPITER iter = previousParents.begin(); iter != previousParents.end(); iter ++)
	{
		HierarchyTreeNode* currentNode = HierarchyTreeController::Instance()->GetTree().GetNode(iter->first);
		HierarchyTreeNode* prevParentNode = HierarchyTreeController::Instance()->GetTree().GetNode(iter->second.parent);
		HierarchyTreeNode* prevAddedAfter = HierarchyTreeController::Instance()->GetTree().GetNode(iter->second.addedAfter);
		
		if (!currentNode || !prevParentNode)
		{
			continue;
		}
		
		currentNode->SetParent(prevParentNode, prevAddedAfter);
	}
	
	HierarchyTreeController::Instance()->EmitHierarchyTreeUpdated();
}
Beispiel #14
0
bool HierarchyTreePlatformNode::IsAggregatorOrScreenNamePresent(const QString& candidatName)
{
	for (HIERARCHYTREENODESLIST::iterator iter = childNodes.begin(); iter != childNodes.end(); ++iter)
	{
		HierarchyTreeNode* node = (*iter);
		
		HierarchyTreeAggregatorNode* aggregator = dynamic_cast<HierarchyTreeAggregatorNode*>(node);
		HierarchyTreeScreenNode* screen = dynamic_cast<HierarchyTreeScreenNode*>(node);
		if (NULL == aggregator && NULL == screen)
		{
			continue;
		}
		if(node->GetName().compare(candidatName) == 0)
		{
			return true;
		}
	}
	return false;
}
void ChangeNodeHeirarchy::DecrementUnsavedChanges()
{
	HierarchyTreeNode* sourceNode = 0;
	HierarchyTreeNode* targetNode = HierarchyTreeController::Instance()->GetTree().GetNode(targetNodeID);

	switch (this->type)
	{
		case TYPE_PLATFORM:
			targetNode->DecrementUnsavedChanges();
			break;

		case TYPE_SCREEN:
		case TYPE_AGGREGATOR:
			targetNode->DecrementUnsavedChanges();

			sourceNode = HierarchyTreeController::Instance()->GetTree().GetNode(items.front());
			if (sourceNode != targetNode)
			{
				sourceNode->DecrementUnsavedChanges();
			}

			// Restore mark state. See comments in IncrementUnsavedChanges()
			for (HierarchyTreeNode::HIERARCHYTREENODESIDLIST::iterator it = items.begin(); it != items.end(); ++it)
			{
				HierarchyTreeNode* node = HierarchyTreeController::Instance()->GetTree().GetNode(*it);

				if (storedMarks.find(*it) != storedMarks.end())
				{
					node->SetMarked(storedMarks[*it]);
				}
			}
			break;

		case TYPE_CONTROLS:
			targetNode->DecrementUnsavedChanges();

			sourceNode = HierarchyTreeController::Instance()->GetScreenNodeForNode(HierarchyTreeController::Instance()->GetTree().GetNode(items.front()));
			if (sourceNode != targetNode)
			{
				sourceNode->DecrementUnsavedChanges();
			}
			break;

		default:
			break;
	}
}
bool BaseMetadata::IsStateDirtyForProperty(UIControl::eControlState controlState, const QString& propertyName)
{
    // If at least one state for the Metadata attached is dirty - return true.
    int paramsCount = this->GetParamsCount();
    for (BaseMetadataParams::METADATAPARAMID i = 0; i < paramsCount; i ++)
    {
        HierarchyTreeNode* treeNode = GetTreeNode(i);
        if (!treeNode)
        {
            continue;
        }

        if (treeNode->GetExtraData().IsStatePropertyDirty(controlState, propertyName))
        {
            return true;
        }
    }
    
    return false;
}
bool HierarchyTreeScreenNode::IsNameExist(const QString &name, const HierarchyTreeNode *parent) const
{
	if (!parent)
		return false;
	
	const HIERARCHYTREENODESLIST& items = parent->GetChildNodes();
	for (HIERARCHYTREENODESLIST::const_iterator iter = items.begin();
		 iter != items.end();
		 ++iter)
	{
		HierarchyTreeNode* node = (*iter);
		if (node->GetName().compare(name) == 0)
			return true;

		if (IsNameExist(name, node))
			return true;
	}
	
	return false;
}
void UIButtonMetadata::SetLocalizedTextKey(const QString& value)
{
    if (!VerifyActiveParamID() || !this->GetActiveTreeNode())
    {
        return;
    }

    // Update the control with the value.
	WideString localizationValue = LocalizationSystem::Instance()->GetLocalizedString(QStrint2WideString(value));
    HierarchyTreeNode* node = this->GetActiveTreeNode();

	for(uint32 i = 0; i < GetStatesCount(); ++i)
	{
		// Update both key and value for all the states requested.
		node->GetExtraData().SetLocalizationKey(QStrint2WideString(value), this->uiControlStates[i]);
		GetActiveUIButton()->SetStateText(this->uiControlStates[i], localizationValue);
	}

    UpdatePropertyDirtyFlagForLocalizedText();
}
Beispiel #19
0
// Initialize the control(s) attached.
void UITextFieldMetadata::InitializeControl(const String& controlName, const Vector2& position)
{
    UIControlMetadata::InitializeControl(controlName, position);
    
    int paramsCount = this->GetParamsCount();
    for (BaseMetadataParams::METADATAPARAMID i = 0; i < paramsCount; i ++)
    {
        UITextField* textField = dynamic_cast<UITextField*>(this->treeNodeParams[i].GetUIControl());
        
        textField->SetFont(EditorFontManager::Instance()->GetDefaultFont());
        textField->GetBackground()->SetDrawType(UIControlBackground::DRAW_ALIGNED);
        
        // Initialize both control text and localization key.
        WideString controlText = StringToWString(textField->GetName());
        
        HierarchyTreeNode* activeNode = GetTreeNode(i);
        textField->SetText(controlText);
        
        activeNode->GetExtraData().SetLocalizationKey(controlText, this->GetReferenceState());
    }
}
bool BaseMetadata::IsStateDirty(UIControl::eControlState controlState)
{
    // If at least one state for the Metadata attached is dirty - return true.
    int paramsCount = this->GetParamsCount();
    for (BaseMetadataParams::METADATAPARAMID i = 0; i < paramsCount; i ++)
    {
        HierarchyTreeNode* treeNode = GetTreeNode(i);
        if (!treeNode)
        {
            continue;
        }
        
        // State is dirty if at least one property exist in the dirty map.
        if (treeNode->GetExtraData().IsStatePropertyDirtyMapEmpty(controlState) == false)
        {
            return true;
        }
    }

    return false;
}
Beispiel #21
0
HierarchyTreeScreenNode* HierarchyTreeController::GetScreenNodeForNode(HierarchyTreeNode* node)
{
	bool foundScreen = false;
	HierarchyTreeNode* screen = node->GetParent();
	do
	{
		if (dynamic_cast<HierarchyTreeScreenNode*>(screen))
		{
			foundScreen = true;
		}
		else
		{
			screen = screen->GetParent();
		}
	} while (!foundScreen && screen);

	if (foundScreen)
	{
		return dynamic_cast<HierarchyTreeScreenNode*>(screen);
	}

	return NULL;
}
Beispiel #22
0
void HierarchyTreeWidget::OnDeleteControlAction()
{
	QList<QTreeWidgetItem*> items = ui->treeWidget->selectedItems();
	if (!items.size())
		return;

	bool needConfirm = false;
	bool needDeleteFiles = false;

	// DF-1273 - Remove all child nodes. We don't have to remove them here.
	QList<QTreeWidgetItem*> parentItems(items);
	for (QList<QTreeWidgetItem*>::iterator iter = items.begin(); iter != items.end(); ++iter)
	{
		HierarchyTreeNode* node = GetNodeFromTreeItem(*iter);
		
		if (!node)
			continue;
				
		for (QList<QTreeWidgetItem*>::iterator innerIter = items.begin(); innerIter != items.end(); ++innerIter)
		{
			HierarchyTreeNode* innerNode = GetNodeFromTreeItem(*innerIter);
				
			if (node->IsHasChild(innerNode))
			{
				parentItems.removeOne(*innerIter);
			}
		}
	}	

	HierarchyTreeNode::HIERARCHYTREENODESLIST nodes;
	for (QList<QTreeWidgetItem*>::iterator iter = parentItems.begin(); iter != parentItems.end(); ++iter)
	{
		HierarchyTreeNode* node = GetNodeFromTreeItem(*iter);
		
		HierarchyTreeAggregatorNode* aggregatorNode = dynamic_cast<HierarchyTreeAggregatorNode*>(node);
		if (aggregatorNode)
		{
			const HierarchyTreeAggregatorNode::CHILDS& childs = aggregatorNode->GetChilds();
			needConfirm |= (childs.size() > 0);
			for (HierarchyTreeAggregatorNode::CHILDS::const_iterator iter = childs.begin(); iter != childs.end(); ++iter)
			{
				nodes.push_back((*iter));
			}
		}

		if (aggregatorNode ||
			dynamic_cast<HierarchyTreeScreenNode*>(node) ||
			dynamic_cast<HierarchyTreePlatformNode*>(node))
		{
			QMessageBox messageBox;
			messageBox.setText(tr("Delete nodes"));
			messageBox.setInformativeText(tr("Do you want to remove selected nodes only from project, or delete their files from disk?"));
			QAbstractButton* removeFromProjectButton = (QAbstractButton*)messageBox.addButton(tr("Remove from project"),
																							  QMessageBox::YesRole);
			QAbstractButton* deleteFromProjectButton = (QAbstractButton*)messageBox.addButton(tr("Delete from disk"),
																							  QMessageBox::YesRole);
			QAbstractButton* cancelButton = (QAbstractButton*)messageBox.addButton(tr("Cancel"),
																				   QMessageBox::RejectRole);
			messageBox.setDefaultButton((QPushButton*)removeFromProjectButton);
			messageBox.setIcon(QMessageBox::Question);
			messageBox.exec();

			if (messageBox.clickedButton() == removeFromProjectButton)
			{
				Logger::Debug("removeFromProjectButton");
			}
			if (messageBox.clickedButton() == deleteFromProjectButton)
			{
				needDeleteFiles = true;
				Logger::Debug("deleteFromProjectButton");
			}
			if (messageBox.clickedButton() == cancelButton)
			{
				Logger::Debug("cancelButton");
				return;
			}
		}
		
		nodes.push_front(node);
	}
	
	if (needConfirm)
	{
		if (QMessageBox::No == QMessageBox::information(this,
								 "",
								 "Selected aggregator control has child controls. Do you want delete aggregator with all child controls?",
								 QMessageBox::Yes | QMessageBox::No))
			return;
	}
	
	DeleteSelectedNodeCommand* cmd = new DeleteSelectedNodeCommand(nodes, needDeleteFiles);
	CommandsController::Instance()->ExecuteCommand(cmd);
	SafeRelease(cmd);
}
HierarchyTreeControlNode* LibraryController::CreateNewControl(HierarchyTreeNode* parentNode, const QString& strType, const QString& name, const Vector2& position)
{
	String type = strType.toStdString();

	HierarchyTreeControlNode* controlNode = NULL;
	UIControl* control = NULL;
	CONTROLS::iterator iter;
	
	for (iter = controls.begin(); iter != controls.end(); ++iter)
	{
		HierarchyTreeNode* node = iter->first;
		if (strType == node->GetName())
			break;
	}
	
	if (iter == controls.end() ||
		dynamic_cast<HierarchyTreeControlNode*>(iter->first))
	{
		//create standart control
		BaseObject* object = ObjectFactory::Instance()->New(type);
		control = dynamic_cast<UIControl*>(object);
		if (!control)
		{
			SafeRelease(object);
			return NULL;
		}
		 
		controlNode = new HierarchyTreeControlNode(parentNode, control, name);
	}
	else
	{
		//create aggregator
		HierarchyTreeAggregatorNode* aggregator = dynamic_cast<HierarchyTreeAggregatorNode*>(iter->first);
		if (aggregator)
		{
			controlNode = aggregator->CreateChild(parentNode, name);
			control = controlNode->GetUIObject();
		}
	}
	
	parentNode->AddTreeNode(controlNode);
	
	// In case the control has subcontrols - they should be added to the control node too.
	if (control && !control->GetSubcontrols().empty())
	{
		List<UIControl*> subControls = control->GetSubcontrols();
		for (List<UIControl*>::iterator iter = subControls.begin(); iter != subControls.end(); iter ++)
		{
			UIControl* subControl = (*iter);
			if (!subControl)
			{
				continue;
			}

			HierarchyTreeControlNode* subControlNode =
				new HierarchyTreeControlNode(controlNode, subControl,
											 QString::fromStdString(subControl->GetName()));
			controlNode->AddTreeNode(subControlNode);
		}
	}

	// Initialize a control through its metadata.
	BaseMetadata* newControlMetadata = MetadataFactory::Instance()->GetMetadataForUIControl(control);

	METADATAPARAMSVECT params;
	params.push_back(BaseMetadataParams(controlNode->GetId(), control));
	newControlMetadata->SetupParams(params);

	// Ready to do initialization!
	newControlMetadata->InitializeControl(name.toStdString(), position);

	SAFE_DELETE(newControlMetadata);

	SafeRelease(control);
	return controlNode;
}