// Ryzom - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #include #include "nel/misc/rgba.h" #include "nel/gui/interface_parser.h" #include "nel/misc/i_xml.h" #include "nel/misc/file.h" #include "nel/misc/algo.h" #include "nel/misc/mem_stream.h" #include "nel/misc/factory.h" #include "nel/misc/big_file.h" #include "nel/misc/xml_auto_ptr.h" #include "nel/gui/interface_options.h" #include "nel/gui/interface_anim.h" #include "nel/gui/interface_expr.h" #include "nel/gui/view_pointer.h" #include "nel/gui/group_modal.h" #include "nel/gui/group_list.h" #include "nel/gui/group_container.h" #include "nel/gui/interface_link.h" #include "nel/gui/lua_helper.h" #include "nel/gui/lua_ihm.h" #include "nel/gui/lua_manager.h" #ifdef LUA_NEVRAX_VERSION #include "lua_ide_dll_nevrax/include/lua_ide_dll/ide_interface.h" // external debugger #endif const uint32 UI_CACHE_SERIAL_CHECK = (uint32) 'IUG_'; using namespace NLMISC; using namespace std; namespace NLGUI { void saveXMLTree(COFile &f, xmlNodePtr node) { // save node name std::string name = (const char *) node->name; f.serial(name); // save properties uint32 numProp = 0; xmlAttrPtr currProp = node->properties; while (currProp) { ++ numProp; currProp = currProp->next; } f.serial(numProp); currProp = node->properties; while (currProp) { std::string name = (const char *) currProp->name; f.serial(name); CXMLAutoPtr ptr(xmlGetProp(node, currProp->name)); std::string value = (const char *) ptr; f.serial(value); currProp = currProp->next; } uint32 numChildren = 0; xmlNodePtr currChild = node->children; while (currChild) { ++ numChildren; currChild = currChild->next; } f.serial(numChildren); currChild = node->children; while (currChild) { saveXMLTree(f, currChild); currChild = currChild->next; } } xmlNodePtr buildTree(CIFile &f) { // load node name std::string name; f.serial(name); xmlNodePtr node = xmlNewNode(NULL, (const xmlChar *) name.c_str()); // slod properties uint32 numProp; f.serial(numProp); for(uint k = 0; k < numProp; ++k) { std::string name, value; f.serial(name, value); xmlSetProp(node, (const xmlChar *) name.c_str(), (const xmlChar *) value.c_str()); } uint32 numChildren; f.serial(numChildren); for(uint k = 0; k < numChildren; ++k) { xmlAddChild(node, buildTree(f)); } return node; } // ---------------------------------------------------------------------------- // CRootGroup // ---------------------------------------------------------------------------- class CRootGroup : public CInterfaceGroup { public: CRootGroup(const TCtorParam ¶m) : CInterfaceGroup(param) { } /// Destructor virtual ~CRootGroup() { } virtual CInterfaceElement* getElement (const std::string &id) { if (_Id == id) return this; if (id.substr(0, _Id.size()) != _Id) return NULL; vector::const_iterator itv; for (itv = _Views.begin(); itv != _Views.end(); itv++) { CViewBase *pVB = *itv; if (pVB->getId() == id) return pVB; } vector::const_iterator itc; for (itc = _Controls.begin(); itc != _Controls.end(); itc++) { CCtrlBase* ctrl = *itc; if (ctrl->getId() == id) return ctrl; } // Accelerate string sTmp = id; sTmp = sTmp.substr(_Id.size()+1,sTmp.size()); string::size_type pos = sTmp.find(':'); if (pos != string::npos) sTmp = sTmp.substr(0,pos); map::iterator it = _Accel.find(sTmp); if (it != _Accel.end()) { CInterfaceGroup *pIG = it->second; return pIG->getElement(id); } return NULL; } virtual void addGroup (CInterfaceGroup *child, sint eltOrder = -1) { string sTmp = child->getId(); sTmp = sTmp.substr(_Id.size()+1,sTmp.size()); _Accel.insert(pair(sTmp, child)); CInterfaceGroup::addGroup(child,eltOrder); } virtual bool delGroup (CInterfaceGroup *child, bool dontDelete = false) { string sTmp = child->getId(); sTmp = sTmp.substr(_Id.size()+1,sTmp.size()); map::iterator it = _Accel.find(sTmp); if (it != _Accel.end()) { _Accel.erase(it); } return CInterfaceGroup::delGroup(child,dontDelete); } private: map _Accel; }; // ---------------------------------------------------------------------------- // CInterfaceParser // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- CInterfaceParser::CInterfaceParser() { luaInitialized = false; cacheUIParsing = false; linkId = 0; editorMode = false; setupCallback = NULL; } CInterfaceParser::~CInterfaceParser() { _ParentPositionsMap.clear(); _ParentSizesMap.clear(); _ParentSizesMaxMap.clear(); _LuaClassAssociation.clear(); _Templates.clear(); removeAllModules(); setupCallback = NULL; } /** Convert a string into a memstream */ static void interfaceScriptAsMemStream(const std::string &script, CMemStream &destStream) { NLMISC::contReset(destStream); if (destStream.isReading()) // we must be sure that we are reading the stream { destStream.invert(); } destStream.seek(0, NLMISC::IStream::begin); if (script.empty()) return; destStream.serialBuffer(const_cast((const uint8 *) &script[0]), (uint)script.size()); destStream.invert(); destStream.seek(0, NLMISC::IStream::begin); } // ---------------------------------------------------------------------------- bool CInterfaceParser::parseInterface (const std::vector & strings, bool reload, bool isFilename, bool checkInData) { bool ok; bool needCheck = false; #if !FINAL_VERSION needCheck = false; #endif // TestYoyo. UnHide For Parsing Profile /* NLMISC::CHTimer::startBench(); { H_AUTO(parseInterface); */ //ignore the content of tags containing only white space xmlKeepBlanksDefault(0); //parse all interface files and build a single xml document xmlNodePtr globalEnclosing; nlassert (strings.size()); CIXml read; string nextFileName; static const char *SCRIPT_AS_STRING = "