// ****************************************************************************
int CSessionBrowserImpl::luaJoinRingSession(CLuaState &ls)
{
    nldebug("SB: luaJoinRingSession");
    const char *funcName = "joinRingSession";
    CLuaIHM::checkArgCount(ls, funcName, 1);
    CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);

    CInterfaceManager *pIM = CInterfaceManager::getInstance();
    CSessionBrowserImpl & sessionBrowser = CSessionBrowserImpl::getInstance();
    sessionBrowser.joinSession(getCharId(), (TSessionId)(uint32) ls.toNumber(1), ClientCfg.ConfigFile.getVar("Application").asString(0));

    if(!sessionBrowser.waitOneMessage(sessionBrowser.getMessageName("on_joinSessionResult")))
    {
        nlwarning("joinSession callback return false");
    }

    if(sessionBrowser._LastJoinSessionResult == 20)
    {
        CViewText* pVT = dynamic_cast<CViewText*>(pIM->getElementFromId("ui:interface:warning_free_trial:text"));
        if (pVT != NULL)
            pVT->setText(CI18N::get("uiRingWarningFreeTrial"));
        pIM->runActionHandler("enter_modal", NULL, "group=ui:interface:warning_free_trial");
    }

    return 0;
}
Esempio n. 2
0
// ***************************************************************************
void addMacroLine (CGroupList *pParent, uint macNb, const CMacroCmd &macro)
{
	CInterfaceManager	*pIM = CInterfaceManager::getInstance();

	vector< pair<string, string> > vParams;
	vParams.push_back(pair<string,string>("id", "m"+toString(macNb)));
	CInterfaceGroup *pNewMacro = CWidgetManager::getInstance()->getParser()->createGroupInstance(TEMPLATE_MACRO_ELT, pParent->getId(), vParams);
	if (pNewMacro == NULL) return;

	CViewText *pVT = dynamic_cast<CViewText*>(pNewMacro->getView(TEMPLATE_MACRO_ELT_TEXT));
	if (pVT != NULL) pVT->setText(macro.Name);

	CDBCtrlSheet *pCS = dynamic_cast<CDBCtrlSheet*>(pNewMacro->getCtrl(TEMPLATE_MACRO_ELT_ICON));
	if (pCS != NULL) pCS->readFromMacro(macro);

	pVT = dynamic_cast<CViewText*>(pNewMacro->getView(TEMPLATE_MACRO_ELT_KEYTEXT));
	if (pVT != NULL)
	{
		if (macro.Combo.Key != KeyCount)
			pVT->setText(macro.Combo.toUCString());
		else
			pVT->setText(CI18N::get(VIEW_EDITCMD_TEXT_KEY_DEFAULT));
	}

	pNewMacro->setParent (pParent);
	pParent->addChild (pNewMacro);
}
Esempio n. 3
0
// ***************************************************************************
void addCommandLine (CGroupList *pParent, uint cmdNb, const ucstring &cmdName)
{
	CInterfaceManager	*pIM = CInterfaceManager::getInstance();

	vector< pair<string, string> > vParams;
	vParams.push_back(pair<string,string>("id", "c"+toString(cmdNb)));
	CInterfaceGroup *pNewCmd = CWidgetManager::getInstance()->getParser()->createGroupInstance(TEMPLATE_NEWMACRO_COMMAND, pParent->getId(), vParams);
	if (pNewCmd == NULL) return;

	CViewText *pVT = dynamic_cast<CViewText*>(pNewCmd->getView(TEMPLATE_NEWMACRO_COMMAND_TEXT));
	if (pVT != NULL) pVT->setText(cmdName);

	pNewCmd->setParent (pParent);
	pParent->addChild (pNewCmd);
}
Esempio n. 4
0
// ***************************************************************************
void CEncyclopediaManager::rebuildAlbumPage(uint32 albumName)
{
	uint32 i;
	CEncyMsgAlbum *pAlbum = NULL;
	// Select the right album
	for (i = 0; i < _Albums.size(); ++i)
	{
		if (_Albums[i].Name == albumName)
		{
			_AlbumNameSelected = _Albums[i].Name;
			pAlbum = &_Albums[i];
			break;
		}
	}

	if (pAlbum == NULL)
		return;

	// Update the right page
	CInterfaceManager *pIM = CInterfaceManager::getInstance();

	// Hide and show good group
	CInterfaceElement *pIE = pIM->getElementFromId(PAGE_ENCY_ALBUM);
	nlassert(pIE != NULL);
	pIE->setActive(true);
	pIE = pIM->getElementFromId(PAGE_ENCY_HELP);
	pIE->setActive(false);
	pIE = pIM->getElementFromId(PAGE_ENCY_THEMA);
	pIE->setActive(false);

	// Setup title
	CViewTextID *pVT = dynamic_cast<CViewTextID*>(pIM->getElementFromId(PAGE_ENCY_ALBUM ":title"));
	nlassert(pVT != NULL);
	pVT->setTextId(pAlbum->Name);

	// Setup brick reward
	pIM->getDbProp("UI:VARIABLES:ENCY:ALBUMBRICK:SHEET")->setValue32(pAlbum->RewardBrick);
	CViewText *pRBVT = dynamic_cast<CViewText*>(pIM->getElementFromId(PAGE_ENCY_ALBUM ":reward:desc"));
	if (pRBVT != NULL)
	{
		STRING_MANAGER::CStringManagerClient *pSMC = STRING_MANAGER::CStringManagerClient::instance();
		const ucstring desc(pSMC->getSBrickLocalizedDescription(CSheetId(pAlbum->RewardBrick)));
		pRBVT->setText(desc);
	}
}
Esempio n. 5
0
	virtual void execute(CCtrlBase * /* pCaller */, const string &/* Params */)
	{
		// Init 'new_macro' container from the global current macro (gCurrentEditMacro)
		CInterfaceManager *pIM = CInterfaceManager::getInstance();
		CMacroCmdManager *pMCM = CMacroCmdManager::getInstance();
		// Icon
		CDBCtrlSheet *pCS = dynamic_cast<CDBCtrlSheet*>(CWidgetManager::getInstance()->getElementFromId(CTRL_NEWMACRO_ICON));
		if (pCS != NULL) pCS->readFromMacro(pMCM->CurrentEditMacro);
		// Name
		CGroupEditBox *pEB = dynamic_cast<CGroupEditBox*>(CWidgetManager::getInstance()->getElementFromId(GROUP_NEWMACRO_EDIT_NAME));
		if (pEB != NULL) pEB->setInputString(pMCM->CurrentEditMacro.Name);
		// Commands
		CGroupList *pList = dynamic_cast<CGroupList*>(CWidgetManager::getInstance()->getElementFromId(GROUP_NEWMACRO_COMMANDS));
		if (pList == NULL) return;
		// Key Shortcut
		CViewText *pVT = dynamic_cast<CViewText*>(CWidgetManager::getInstance()->getElementFromId(VIEW_NEWMACRO_KEY));
		if (pVT != NULL)
		{
			if (pMCM->CurrentEditMacro.Combo.Key == KeyCount)
				pVT->setText(CI18N::get(VIEW_EDITCMD_TEXT_KEY_DEFAULT));
			else
				pVT->setText(pMCM->CurrentEditMacro.Combo.toUCString());
		}

		pList->clearGroups();
		pList->setDynamicDisplaySize(true);

		for (uint i = 0; i < pMCM->CurrentEditMacro.Commands.size(); ++i)
		{
			ucstring commandName;
			for (uint j = 0; j < pMCM->ActionManagers.size(); ++j)
			{
				CAction::CName c(pMCM->CurrentEditMacro.Commands[i].Name.c_str(), pMCM->CurrentEditMacro.Commands[i].Params.c_str());
				if (pMCM->ActionManagers[j]->getBaseAction(c) != NULL)
				{
					commandName = pMCM->ActionManagers[j]->getBaseAction(c)->getActionLocalizedText(c);
					break;
				}
			}

			addCommandLine(pList, i, commandName);
		}
		pMCM->EditCmd->CurAM = pMCM->ActionManagers[0];
	}
Esempio n. 6
0
// --------------------------------------------------------------------------------------------------------------------
void CViewPointer::setString (const ucstring &str, CInterfaceGroup *target)
{
	if (target)
	{
		CInterfaceElement *element = target->getView ("fake_txt");
		if (element)
		{
			CViewText *text = dynamic_cast<CViewText*> (element);
			if (text)
				text->setText(str);
		}
		element = target->getView ("real_txt");
		if (element)
		{
			CViewText *text = dynamic_cast<CViewText*> (element);
			if (text)
				text->setText(str);
		}
		target->updateCoords();
		target->updateCoords();
		_ContextString = str;
	}
}
Esempio n. 7
0
//=================================================================================
CViewBase *CChatTextManager::createMsgText(const ucstring &cstMsg, NLMISC::CRGBA col, bool justified /*=false*/)
{
	ucstring msg = cstMsg;
	CInterfaceGroup *commandGroup = parseCommandTag(msg);
	CViewText *vt = new CViewText(CViewText::TCtorParam());
	// get parameters from config.xml
	vt->setShadow(isTextShadowed());
	vt->setFontSize(getTextFontSize());
	vt->setMultiLine(true);
	vt->setTextMode(justified ? CViewText::Justified : CViewText::DontClipWord);
	vt->setMultiLineSpace(getTextMultiLineSpace());
	vt->setModulateGlobalColor(false);

	ucstring cur_time;
	if (showTimestamps())
	{
		cur_time = CInterfaceManager::getTimestampHuman();
	}

	// if text contain any color code, set the text formated and white,
	// otherwise, set text normal and apply global color
	size_t codePos = msg.find(ucstring("@{"));
	if (codePos != ucstring::npos)
	{
		// Prepend the current time (do it after the color if the color at first position.
		if (codePos == 0)
		{
			codePos = msg.find(ucstring("}"));
			msg = msg.substr(0, codePos + 1) + cur_time + msg.substr(codePos + 1, msg.length() - codePos);
		}
		else
		{
			msg = cur_time + msg;
		}
		
		vt->setTextFormatTaged(msg);
		vt->setColor(NLMISC::CRGBA::White);
	}
	else
	{
		msg = cur_time + msg;
		vt->setText(msg);
		vt->setColor(col);
	}

	if (!commandGroup)
	{
		return vt;
	}
	else
	{
		return buildLineWithCommand(commandGroup, vt);
	}
}
Esempio n. 8
0
// ***************************************************************************
void CEncyclopediaManager::rebuildThemaPage(uint32 themaName)
{
	uint32 i;
	CEncyMsgThema *pThema = NULL;
	// Select the right album
	for (i = 0; i < _Albums.size(); ++i)
	{
		pThema = _Albums[i].getThema(themaName);
		if (pThema != NULL)
		{
			_AlbumNameSelected = _Albums[i].Name;
			break;
		}
	}

	if (pThema == NULL)
		return;

	// Update the right page
	CInterfaceManager *pIM = CInterfaceManager::getInstance();

	// Hide and show good group
	CInterfaceElement *pIE = pIM->getElementFromId(PAGE_ENCY_ALBUM);
	nlassert(pIE != NULL);
	pIE->setActive(false);
	pIE = pIM->getElementFromId(PAGE_ENCY_HELP);
	pIE->setActive(false);
	pIE = pIM->getElementFromId(PAGE_ENCY_THEMA);
	pIE->setActive(true);

	// Setup title
	CViewTextID *pVT = dynamic_cast<CViewTextID*>(pIM->getElementFromId(PAGE_ENCY_THEMA ":title"));
	nlassert(pVT != NULL);
	pVT->setTextId(pThema->Name);

	// Setup rewards
	pVT = dynamic_cast<CViewTextID*>(pIM->getElementFromId(PAGE_ENCY_THEMA ":reward_text:desc"));
	nlassert(pVT != NULL);
	pVT->setTextId(pThema->RewardText);

	// Setup brick reward
	pIM->getDbProp("UI:VARIABLES:ENCY:REWARDBRICK:SHEET")->setValue32(pThema->RewardSheet);
	CViewText *pRBVT = dynamic_cast<CViewText*>(pIM->getElementFromId(PAGE_ENCY_THEMA ":reward:desc"));
	nlassert(pRBVT != NULL);
	STRING_MANAGER::CStringManagerClient *pSMC = STRING_MANAGER::CStringManagerClient::instance();
	CEntitySheet *pES = SheetMngr.get(CSheetId(pThema->RewardSheet));
	if (pES != NULL)
	{
		if (pES->type() == CEntitySheet::ITEM)
		{
			const ucstring desc(pSMC->getItemLocalizedDescription(CSheetId(pThema->RewardSheet)));
			pRBVT->setText(desc);
		}
		else if (pES->type() == CEntitySheet::SBRICK)
		{
			const ucstring desc(pSMC->getSBrickLocalizedDescription(CSheetId(pThema->RewardSheet)));
			pRBVT->setText(desc);
		}
		else if (pES->type() == CEntitySheet::SPHRASE)
		{
			const ucstring desc(pSMC->getSPhraseLocalizedDescription(CSheetId(pThema->RewardSheet)));
			pRBVT->setText(desc);
		}
	}

	// Setup the total number of steps
	uint32 nNbSteps = pThema->NbTask - 1; // 0th is the rite
	pIM->getDbProp("UI:VARIABLES:ENCY:STEPS")->setValue32(nNbSteps);

	// Count number of tasks done
	uint32 nNbTaskDone = 0;
	for (i = 0; i < pThema->NbTask; ++i)
		if (pThema->getTaskState((uint8)i) == 2) // 2 == finished
			++nNbTaskDone;
	pIM->getDbProp("UI:VARIABLES:ENCY:DONE")->setValue32(nNbTaskDone);

	// setup rite & tasks
	for (i = 0; i < pThema->NbTask; ++i)
	{
		string sTmp;
		if (i == 0)
			sTmp = PAGE_ENCY_THEMA ":todo2:rite";
		else
			sTmp = PAGE_ENCY_THEMA ":todo:task" + toString(i);

		// setup task description
		CViewTextID *pText = dynamic_cast<CViewTextID*>(pIM->getElementFromId(sTmp+":desc"));
		nlassert(pText != NULL);
		pText->setTextId(pThema->TaskName[i]);

		// setup task NPC name
		CStringPostProcessNPCRemoveTitle *pSPPRT = new CStringPostProcessNPCRemoveTitle;
		pIM->addServerID (sTmp+":npc:uc_hardtext", pThema->TaskNPCName[i], pSPPRT);

		// If the task is not known gray it
		if (pThema->getTaskState((uint8)i) == 0)
			pText->setAlpha(80);
		else
			pText->setAlpha(160);

		// If the task is finished toggle it
		CViewBitmap *pBitmap = dynamic_cast<CViewBitmap*>(pIM->getElementFromId(sTmp+":done"));
		nlassert(pBitmap != NULL);
		if (pThema->getTaskState((uint8)i) == 2)
			pBitmap->setActive(true);
		else
			pBitmap->setActive(false);
	}

}
	void get(const std::string &url)
	{
		if(!Curl) return;
		curlresult.clear();
		//nlinfo("get '%s'", url.c_str());
		curl_easy_setopt(Curl, CURLOPT_URL, url.c_str());
		CURLcode res = curl_easy_perform(Curl);
		long r;
		curl_easy_getinfo(Curl, CURLINFO_RESPONSE_CODE, &r);
		//nlwarning("result : '%s'", curlresult.c_str());

		vector<string> notifs;
		explode(curlresult, string("|"), notifs);

		// Update the mail notification icon

		uint32 nbmail = 0;
		if(notifs.size() > 0 && fromString(notifs[0], nbmail))
		{
			//nlinfo("nb mail is a number %d", nbmail);
			CInterfaceManager *pIM = CInterfaceManager::getInstance();
			if(pIM)
			{
				CCDBNodeLeaf *_CheckMailNode = pIM->getDbProp("UI:VARIABLES:MAIL_WAITING");
				if(_CheckMailNode)
				{
					_CheckMailNode->setValue32(nbmail==0?0:1);
					CInterfaceElement *elm = pIM->getElementFromId("ui:interface:compass:mail:mail_nb");
					if (elm)
					{
						CViewText *vt = dynamic_cast<CViewText*>(elm);
						vt->setText(toString("%d", nbmail));
					}
				}
			}
		}
		else
		{
			nlwarning("this is not a number '%s'", curlresult.c_str());
		}

		// Update the forum notification icon

		uint32 nbforum = 0;
		if(notifs.size() > 1 && fromString(notifs[1], nbforum))
		{
			//nlinfo("nb forum this is a number %d", nbforum);
			CInterfaceManager *pIM = CInterfaceManager::getInstance();
			if(pIM)
			{
				CCDBNodeLeaf *_CheckForumNode = pIM->getDbProp("UI:VARIABLES:FORUM_UPDATED");
				if(_CheckForumNode)
				{
					_CheckForumNode->setValue32(nbforum==0?0:1);
					CInterfaceElement *elm = pIM->getElementFromId("ui:interface:compass:forum:forum_nb");
					if (elm)
					{
						CViewText *vt = dynamic_cast<CViewText*>(elm);
						vt->setText(toString("%d", nbforum));
					}
				}
			}
		}
		else
		{
			nlwarning("this is not a number '%s'", curlresult.c_str());
		}
	}
Esempio n. 10
0
// ***************************************************************************
void CGuildManager::update()
{
	CInterfaceManager *pIM = CInterfaceManager::getInstance();
	STRING_MANAGER::CStringManagerClient *pSMC = STRING_MANAGER::CStringManagerClient::instance();

	// *** Need to rebuild the guild data?
	if (_NeedRebuild)
	{
		_NeedUpdate = true;
		_NeedRebuild = false;

		// Rebuild transfert the database to the local structure

		// Guild stuff
		uint32 oldName = _Guild.NameID;
		_Guild.NameID = pIM->getDbProp("SERVER:GUILD:NAME")->getValue32();
		_Guild.Name = "";
		_InGuild = (_Guild.NameID != 0);
		if (!_InGuild)
			closeAllInterfaces();
		_Guild.Icon = pIM->getDbProp("SERVER:GUILD:ICON")->getValue64();
		_Guild.QuitGuildAvailable = true;

		// Guild Members
		if(_NeedRebuildMembers)
		{
			_NeedUpdateMembers = true;
			_NeedRebuildMembers = false;

			_GuildMembers.clear();
			for (uint32 i = 0; i < MAX_GUILD_MEMBER; ++i)
			{
				sint32 name = pIM->getDbProp("SERVER:GUILD:MEMBERS:"+toString(i)+":NAME")->getValue32();
				if (name != 0)
				{
					SGuildMember gm;
					gm.NameID = name;
					gm.Index = i;
					gm.Grade = (EGSPD::CGuildGrade::TGuildGrade)(pIM->getDbProp("SERVER:GUILD:MEMBERS:"+toString(i)+":GRADE")->getValue32());
					gm.Online = (TCharConnectionState)(pIM->getDbProp("SERVER:GUILD:MEMBERS:"+toString(i)+":ONLINE")->getValue32());
					gm.EnterDate = pIM->getDbProp("SERVER:GUILD:MEMBERS:"+toString(i)+":ENTER_DATE")->getValue32();
					_GuildMembers.push_back(gm);
				}
			}
		}

		// Does the player are newcomer ?
		// Boris 01/09/2006 : removed : now the guild interface is open if
		// is was active before OR if the EGS ask it to the client

		bool playerNewToTheGuild = _NewToTheGuild &&(oldName != _Guild.NameID) && _InGuild;
		if (playerNewToTheGuild)
		{
			// reset the flag
			_NewToTheGuild = false;
			// Don't pop the guild window in ring mode.
			// NB nico : this test should not be necessary, as the guild infos should be filled during the init of the db
			// However, there are situation where this db info is filled after init (should only happen at guild creation time ...)
			// Maybe an EGS  bug ?
			if (R2::getEditor().getMode() == R2::CEditor::NotInitialized)
			{
				CInterfaceElement *pElt;
				// Open the guild info if we are not in the init phase
				if (!IngameDbMngr.initInProgress())
				{
					pElt = pIM->getElementFromId(WIN_GUILD);
					if (pElt != NULL)
						pElt->setActive(true);
				}
				// Browse the forum
				pElt = pIM->getElementFromId(WIN_GUILD_FORUM":content:html");
				if (pElt != NULL)
				{
					CGroupHTML *html = dynamic_cast<CGroupHTML*>(pElt);
					if (html)
						html->browse("home");
				}
			}
		}
	}

	// *** Need to update Names?
	if (_NeedUpdate)
	{
		bool bAllValid = true;
		// Update wait until all the name of members, name of the guild and description are valid

		if (!pSMC->getString (_Guild.NameID, _Guild.Name)) bAllValid = false;

		for (uint i = 0; i < _GuildMembers.size(); ++i)
		{
			if (!pSMC->getString (_GuildMembers[i].NameID, _GuildMembers[i].Name)) bAllValid = false;
			else _GuildMembers[i].Name = CEntityCL::removeTitleAndShardFromName(_GuildMembers[i].Name);
		}

		// If all is valid no more need update and if guild is opened update the interface
		if (bAllValid)
		{
			// Search for UserEntity to find our own grade
			if ((UserEntity != NULL) && (_GuildMembers.size() > 0))
			{
				uint i;
				_Grade = EGSPD::CGuildGrade::Member;
				string sUserName = strlwr(UserEntity->getEntityName().toString());
				for (i = 0; i < _GuildMembers.size(); ++i)
				{
					if (strlwr(_GuildMembers[i].Name.toString()) == sUserName)
					{
						_Grade = _GuildMembers[i].Grade;
						break;
					}
				}
			}

			// set this value in the database
			pIM->getDbProp("UI:VARIABLES:USER:GUILD_GRADE")->setValue32(_Grade);

			// update the guild display
			CGroupContainer *pGuild = dynamic_cast<CGroupContainer*>(pIM->getElementFromId(WIN_GUILD));
			if (pGuild != NULL)
			{
				// if the guild window is visible
				if (pGuild->isOpen() && pGuild->getActive())
				{
					// Close the modal window if the member list will change
					if(pIM->getModalWindow()!=NULL && _NeedUpdateMembers)
					{
						if (pIM->getModalWindow()->getId() == MENU_GUILD_MEMBER )
							pIM->disableModalWindow();
					}

					// Rebuild interface. Rebuild members only if needed
					pIM->runActionHandler("guild_sheet_open", NULL, toString("update_members=%d", (uint)_NeedUpdateMembers) );
				}
			}

			// guild updated
			_NeedUpdate = false;
			_NeedUpdateMembers= false;
		}
	}

	// *** Join proposal handling
	if (_JoinPropUpdate)
	{
		bool bAllValid = true;
		if (!pSMC->getDynString (_JoinPropPhraseID, _JoinPropPhrase)) bAllValid = false;
		// If all is valid no more need update and update the interface
		if (bAllValid)
		{
			_JoinPropUpdate = false;
			CGroupContainer *pJoinProp = dynamic_cast<CGroupContainer*>(pIM->getElementFromId(WIN_JOIN_PROPOSAL));
			if (pJoinProp != NULL)
			{
				CViewText *pJoinPropPhraseView = dynamic_cast<CViewText*>(pIM->getElementFromId(VIEW_JOIN_PROPOSAL_PHRASE));
				if (pJoinPropPhraseView != NULL)
					pJoinPropPhraseView->setText(_JoinPropPhrase);

				pJoinProp->setActive(true);
				pIM->setTopWindow(pJoinProp);
				pJoinProp->updateCoords();
				pJoinProp->center();
				pJoinProp->enableBlink(2);
			}
		}
	}
}
Esempio n. 11
0
void CGroupSkills::createAllTreeNodes()
{
	CInterfaceManager *pIM = CInterfaceManager::getInstance();
	CSkillManager *pSM = CSkillManager::getInstance();

	// Construct the snode hierarchy structure
	_TreeRoot = new CGroupTree::SNode;
	_AllNodes.resize(SKILLS::NUM_SKILLS, NULL);
	bool bQuit = false;
	uint nCounter = 0;

	// local variable (avoid realloc in loop)
	vector< pair<string, string> > tempVec(2);
	ucstring	sSkillName;

	while ((!bQuit) && (nCounter < 32)) // Counter is used to not infinitly loop
	{
		nCounter++;
		bQuit = true;
		// Try to create a skill
		for (uint32 i = 0; i < SKILLS::NUM_SKILLS; ++i)
		if (_AllNodes[i] == NULL) // not already created
		{
			if (pSM->isUnknown((SKILLS::ESkills)i)) continue;

			// Create all skills
			SKILLS::ESkills		parentSkill= pSM->getParent((SKILLS::ESkills)i);

			// if parent, the parent node must be created
			if (parentSkill != SKILLS::unknown)
			{
				if (_AllNodes[parentSkill] == NULL)
				{
					bQuit = false;
					continue;
				}
			}

			// Ok lets create it
			CGroupTree::SNode *pNode = new CGroupTree::SNode;
			pNode->Id = NLMISC::toString(i);

			// get Skill Name
			sSkillName = STRING_MANAGER::CStringManagerClient::getSkillLocalizedName((SKILLS::ESkills)i);

			// just text or template?
			if(_TemplateSkill.empty())
			{
				pNode->DisplayText = true;
				pNode->Template = NULL;
				pNode->Text= sSkillName;
			}
			else
			{
				pNode->DisplayText = false;

				// create the template
				tempVec[0].first="id"; tempVec[0].second= pNode->Id;
				tempVec[1].first="skillid"; tempVec[1].second= NLMISC::toString(i);
				CInterfaceGroup	*pIG = CWidgetManager::getInstance()->getParser()->createGroupInstance(_TemplateSkill, getId() + ":" + WIN_TREE_LIST, tempVec);
				if (pIG == NULL)
					nlwarning("error");
				// Set Skill Name
				CViewText *pViewSkillName = dynamic_cast<CViewText*>(pIG->getView("name"));
				if (pViewSkillName != NULL)
					pViewSkillName->setText (sSkillName);
				// Set Skill Max Value
				CViewText *pViewSkillMax = dynamic_cast<CViewText*>(pIG->getView("max"));
				if (pViewSkillMax != NULL)
					pViewSkillMax->setText (toString(pSM->getMaxSkillValue((SKILLS::ESkills)i)));
				pNode->Template = pIG;
			}


			// Action handler?
			if(!_AHCtrlNode.empty())
			{
				pNode->AHName= _AHCtrlNode;
				pNode->AHParams= NLMISC::toString(i);
			}

			// bkup
			_AllNodes[i] = pNode;

			// not opened by default
			pNode->Opened= false;

			// Attach to the good parent
			if (parentSkill == SKILLS::unknown)
				_TreeRoot->addChild(pNode);
			else
				_AllNodes[parentSkill]->addChild(pNode);
		}
	}

	// Sort the First level in this order: Combat/Magic/Craft/Forage/Others.
	vector<CSortNode>	sortNodes;
	sortNodes.resize(_TreeRoot->Children.size());
	uint	i;
	for(i=0;i<_TreeRoot->Children.size();i++)
	{
		sortNodes[i].Node= _TreeRoot->Children[i];
		// get the skill value of this node
		sint	skillValue;
		fromString(_TreeRoot->Children[i]->Id, skillValue);
		// Special sort:
		if(skillValue==SKILLS::SF)
			skillValue= -4;
		if(skillValue==SKILLS::SM)
			skillValue= -3;
		if(skillValue==SKILLS::SC)
			skillValue= -2;
		if(skillValue==SKILLS::SH)
			skillValue= -1;
		// prepare tri
		sortNodes[i].Value= skillValue;
	}
	sort(sortNodes.begin(), sortNodes.end());
	// store sorted values
	for(i=0;i<_TreeRoot->Children.size();i++)
	{
		_TreeRoot->Children[i]= sortNodes[i].Node;
	}
}