1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2015 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013-2014 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
6 // Copyright (C) 2013-2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as
10 // published by the Free Software Foundation, either version 3 of the
11 // License, or (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "nel/misc/rgba.h"
25 #include "nel/gui/interface_parser.h"
26 #include "nel/misc/i_xml.h"
27 #include "nel/misc/file.h"
28 #include "nel/misc/algo.h"
29 #include "nel/misc/mem_stream.h"
30 #include "nel/misc/factory.h"
31 #include "nel/misc/big_file.h"
32 #include "nel/misc/xml_auto_ptr.h"
33 #include "nel/gui/interface_options.h"
34 #include "nel/gui/interface_anim.h"
35 #include "nel/gui/interface_expr.h"
36 #include "nel/gui/view_pointer.h"
37 #include "nel/gui/group_modal.h"
38 #include "nel/gui/group_list.h"
39 #include "nel/gui/group_container.h"
40 #include "nel/gui/interface_link.h"
41 #include "nel/gui/lua_helper.h"
42 #include "nel/gui/lua_ihm.h"
43 #include "nel/gui/lua_manager.h"
44 #include "nel/gui/root_group.h"
46 #ifdef LUA_NEVRAX_VERSION
47 #include "lua_ide_dll_nevrax/include/lua_ide_dll/ide_interface.h" // external debugger
54 const uint32 UI_CACHE_SERIAL_CHECK
= NELID("IUG_");
56 using namespace NLMISC
;
62 void saveXMLTree(COFile
&f
, xmlNodePtr node
)
65 std::string name
= (const char *) node
->name
;
69 xmlAttrPtr currProp
= node
->properties
;
73 currProp
= currProp
->next
;
76 currProp
= node
->properties
;
79 std::string name
= (const char *) currProp
->name
;
81 CXMLAutoPtr
ptr(xmlGetProp(node
, currProp
->name
));
82 std::string value
= (const char *) ptr
;
84 currProp
= currProp
->next
;
86 uint32 numChildren
= 0;
87 xmlNodePtr currChild
= node
->children
;
91 currChild
= currChild
->next
;
93 f
.serial(numChildren
);
94 currChild
= node
->children
;
97 saveXMLTree(f
, currChild
);
98 currChild
= currChild
->next
;
102 xmlNodePtr
buildTree(CIFile
&f
)
107 xmlNodePtr node
= xmlNewNode(NULL
, (const xmlChar
*) name
.c_str());
111 for(uint k
= 0; k
< numProp
; ++k
)
113 std::string name
, value
;
114 f
.serial(name
, value
);
115 xmlSetProp(node
, (const xmlChar
*) name
.c_str(), (const xmlChar
*) value
.c_str());
118 f
.serial(numChildren
);
119 for(uint k
= 0; k
< numChildren
; ++k
)
121 xmlAddChild(node
, buildTree(f
));
126 // ----------------------------------------------------------------------------
128 // ----------------------------------------------------------------------------
130 // ----------------------------------------------------------------------------
131 CInterfaceParser::CInterfaceParser()
133 luaInitialized
= false;
134 cacheUIParsing
= false;
137 setupCallback
= NULL
;
140 CInterfaceParser::~CInterfaceParser()
142 _ParentPositionsMap
.clear();
143 _ParentSizesMap
.clear();
144 _ParentSizesMaxMap
.clear();
145 _LuaClassAssociation
.clear();
148 setupCallback
= NULL
;
150 /** Convert a string into a memstream
152 static void interfaceScriptAsMemStream(const std::string
&script
, CMemStream
&destStream
)
154 NLMISC::contReset(destStream
);
155 if (destStream
.isReading()) // we must be sure that we are reading the stream
159 destStream
.seek(0, NLMISC::IStream::begin
);
160 if (script
.empty()) return;
161 destStream
.serialBuffer(const_cast<uint8
*>((const uint8
*) &script
[0]), (uint
)script
.size());
163 destStream
.seek(0, NLMISC::IStream::begin
);
166 std::string
CInterfaceParser::lookup( const std::string
&file
)
168 std::string filename
;
170 if( editorMode
&& !_WorkDir
.empty() )
172 std::string wdpath
= CPath::standardizePath( _WorkDir
) + file
;
173 if( CFile::fileExists( wdpath
) )
176 if( filename
.empty() )
177 filename
= CPath::lookup( file
);
182 // ----------------------------------------------------------------------------
183 bool CInterfaceParser::parseInterface (const std::vector
<std::string
> & strings
, bool reload
, bool isFilename
, bool checkInData
)
187 bool needCheck
= false;
193 // TestYoyo. UnHide For Parsing Profile
195 NLMISC::CHTimer::startBench();
198 H_AUTO(parseInterface);
201 //ignore the content of tags containing only white space
202 xmlKeepBlanksDefault(0);
203 //parse all interface files and build a single xml document
204 xmlNodePtr globalEnclosing
;
205 nlassert (!strings
.empty());
208 static const char *SCRIPT_AS_STRING
= "<script as string>";
212 CMemStream scriptStream
;
213 string firstFileName
;
214 vector
<string
>::const_iterator it
= strings
.begin();
217 //get the first file document pointer
219 string filename
= lookup( firstFileName
);
220 bool isInData
= false;
221 string::size_type pos
= filename
.find ("@");
222 if (pos
!= string::npos
)
224 vector
<string
> bigFilePaths
;
225 CBigFile::getInstance().getBigFilePaths(bigFilePaths
);
226 if (CBigFile::getInstance().getBigFileName(filename
.substr(0, pos
)) != "data/"+filename
.substr(0, pos
))
232 if ((needCheck
&& !isInData
) || !file
.open (lookup(firstFileName
)))
234 // todo hulud interface syntax error
235 nlwarning ("could not open file %s, skipping xml parsing",firstFileName
.c_str());
242 firstFileName
= SCRIPT_AS_STRING
; // for error msg
243 interfaceScriptAsMemStream(*it
, scriptStream
);
244 read
.init(scriptStream
);
246 //get the enclosing element (<interface config>)
247 globalEnclosing
= read
.getRootNode();
248 if (!globalEnclosing
)
250 // todo hulud interface syntax error
251 nlwarning ("no root element in xml file %s, skipping xml parsing",firstFileName
.c_str());
254 if (strcmp( (char*)globalEnclosing
->name
,"interface_config") )
256 // todo hulud interface syntax error
257 nlwarning ("wrong root element in xml file %s, skipping xml parsing",firstFileName
.c_str());
265 // Get all other xml files, and add their nodes to the first xml document
268 for (; it
!= strings
.end(); it
++)
270 //nlwarning("Parsing interface file : %s", it->c_str());
273 xmlNodePtr cur
= NULL
;
274 bool saveParseResult
= false;
275 bool readFromUncompressedXML
= true;
276 if( isFilename
&& cacheUIParsing
)
278 saveParseResult
= true;
279 std::string archive
= CPath::lookup(nextFileName
+ "_compressed", false, false);
280 std::string current
= lookup(nextFileName
);
281 if (!archive
.empty() && !current
.empty())
283 if (CFile::getFileModificationDate(current
) <= CFile::getFileModificationDate(archive
))
287 input
.serialCheck(UI_CACHE_SERIAL_CHECK
);
288 input
.serialVersion(0);
289 cur
= buildTree(input
);
290 input
.serialCheck(UI_CACHE_SERIAL_CHECK
);
291 readFromUncompressedXML
= false;
292 saveParseResult
= false;
300 if (!file
.open(lookup(nextFileName
)))
302 // todo hulud interface syntax error
303 nlwarning ("could not open file %s, skipping xml parsing",nextFileName
.c_str());
306 nextRead
.init (file
);
310 interfaceScriptAsMemStream(nextFileName
, scriptStream
);
311 nextFileName
= SCRIPT_AS_STRING
; // for error MSG
312 read
.init(scriptStream
);
314 cur
= nextRead
.getRootNode();
317 // todo hulud interface syntax error
318 nlwarning ("no root element in xml file %s, skipping xml parsing", it
->c_str() );
324 nlassert(isFilename
);
325 std::string outputFilename
= CPath::standardizePath("data") + CFile::getFilename(nextFileName
) + std::string("_compressed");
327 f
.open(outputFilename
);
328 f
.serialCheck(UI_CACHE_SERIAL_CHECK
);
331 f
.serialCheck(UI_CACHE_SERIAL_CHECK
);
333 if (strcmp( (char*)cur
->name
,"interface_config") )
335 // todo hulud interface syntax error
336 nlwarning ("wrong root element in xml file %s. should be interface config, skipping xml parsing", nextFileName
.c_str());
339 xmlNodePtr curSon
= cur
->children
;
342 xmlNodePtr bufNode
= xmlCopyNode (curSon
, 1);
343 xmlAddChild (globalEnclosing
,bufNode
);
344 curSon
= curSon
->next
;
346 if (!readFromUncompressedXML
)
348 freeXMLNodeAndSibblings(cur
);
357 catch (const Exception
&e
)
360 // todo hulud interface syntax error
361 nlwarning ("CInterfaceParser: Error while loading the xml interface file %s, skipping xml parsing : %s", nextFileName
.c_str(), e
.what());
362 if (testWildCard(nextFileName
, "save/keys_?*.xml"))
364 // if file matches 'save/keys_?*.xml', move this file as a backup
365 string backup
= nextFileName
+".backup";
366 if (CFile::fileExists(backup
))
367 CFile::deleteFile(backup
);
368 CFile::moveFile(backup
, nextFileName
);
372 //parse the built doc
373 ok
= parseXMLDocument(globalEnclosing
, reload
);
374 // freeXMLNodeAndSibblings(globalEnclosing); // Done by the ~CIXml
377 // TestYoyo. UnHide for Parsing Profile
380 NLMISC::CHTimer::endBench();
381 // Display and save profile to a File.
383 CFileDisplayer fileDisplayer(NLMISC::CFile::findNewFile(getLogDirectory() + "profile_parseInterface.log"));
384 log.addDisplayer(&fileDisplayer);
386 NLMISC::CHTimer::displayHierarchicalByExecutionPathSorted(&log, CHTimer::TotalTime, true, 48, 2);
387 NLMISC::CHTimer::display(&log, CHTimer::TotalTime);
392 if( CWidgetManager::getInstance()->getPointer() == NULL
)
394 CViewPointer
*pointer
= dynamic_cast< CViewPointer
* >( NLMISC_GET_FACTORY(CViewBase
, std::string
).createObject( "generic_pointer", CViewBase::TCtorParam() ) );
395 CWidgetManager::getInstance()->setPointer( pointer
);
404 // ----------------------------------------------------------------------------
405 bool CInterfaceParser::parseXMLDocument(xmlNodePtr root
, bool reload
)
408 CWidgetManager::SMasterGroup
*curRoot
= NULL
;
409 CInterfaceGroup
*rootGroup
= NULL
;
411 xmlNodePtr curNode
= root
->children
;
413 std::vector
< CWidgetManager::SMasterGroup
> &_MasterGroups
= CWidgetManager::getInstance()->getAllMasterGroup();
417 // first solve define for the xml node and his sons
418 if(!solveDefine(curNode
))
420 // todo hulud interface syntax error
421 nlwarning ("could not read all define");
423 // then try to solve Style for the xml node and his sons
424 else if (!solveStyle(curNode
))
426 // todo hulud interface syntax error
427 nlwarning ("could not read all styles");
429 if( !strcmp((char*)curNode
->name
,"key" ) && editorMode
)
431 saveKeySettings( curNode
);
433 // If define and style oks, try to parse "1st pass" objets (define, options....).
434 else if ( !strcmp((char*)curNode
->name
,"template") )
436 // Check there is a valid name for this template
437 CXMLAutoPtr
ptr((const char*) xmlGetProp( curNode
, (xmlChar
*)"name" ));
440 // remove any template with the same name in the list (useful when using 'loadui' command)
441 for(uint k
= 0; k
< _Templates
.size(); ++k
)
443 CXMLAutoPtr
otherTemplName((const char*) xmlGetProp( _Templates
[k
], (xmlChar
*)"name" ));
444 if (strcmp((const char *) otherTemplName
, (const char *) ptr
) == 0)
446 nlwarning("Replacing template %s with new version", (const char *) ptr
);
447 xmlFreeNode(_Templates
[k
]);
448 _Templates
[k
] = NULL
;
451 _Templates
.erase(std::remove(_Templates
.begin(), _Templates
.end(), (xmlNodePtr
) NULL
), _Templates
.end());
452 _Templates
.push_back(curNode
);
455 // todo hulud interface syntax error
456 nlwarning ("no name in a template node");
458 else if ( !strcmp((char*)curNode
->name
,"options") )
460 if (!parseOptions(curNode
,rootGroup
))
461 // todo hulud interface syntax error
462 nlwarning ("could not parse options");
464 else if ( !strcmp((char*)curNode
->name
,"define") )
466 if (!parseDefine(curNode
))
467 // todo hulud interface syntax error
468 nlwarning ("could not parse define");
470 else if ( !strcmp((char*)curNode
->name
,"style") )
472 if (!parseStyle(curNode
))
473 // todo hulud interface syntax error
474 nlwarning ("could not parse 'style'");
478 IParserModule
*module
= getModuleFor( (char*)( curNode
->name
) );
479 if( module
!= NULL
){
480 if( module
->canParseInStage( IParserModule::Unresolved
) )
481 module
->parse( curNode
, rootGroup
);
485 curNode
= curNode
->next
;
489 if (!reload
) // TMP : crahs when doing the setup twice (old pointer on the text manager ...)
495 //parse filters , groups and eventually instances
496 // vector that are on top of the xml hierarchy
497 root
= root
->children
;
500 if ( !strcmp((char*)root
->name
,"root") )
502 CXMLAutoPtr
ptr((const char*)xmlGetProp (root
, (xmlChar
*)"id"));
505 rootGroup
= CWidgetManager::getInstance()->getMasterGroupFromId (string("ui:") + (const char*)ptr
);
506 if (rootGroup
== NULL
)
508 rootGroup
= (CInterfaceGroup
*)(new CRootGroup(CViewBase::TCtorParam()));
509 rootGroup
->parse (root
, NULL
);
510 CWidgetManager::SMasterGroup mg
;
511 mg
.Group
= rootGroup
;
512 _MasterGroups
.push_back (mg
);
514 for (uint32 i
= 0; i
< _MasterGroups
.size(); ++i
)
515 if (_MasterGroups
[i
].Group
== rootGroup
)
516 curRoot
= &_MasterGroups
[i
];
520 // todo hulud interface syntax error
521 nlwarning ("could not parse root");
524 else if (!strcmp((char*)root
->name
,"group"))
526 if (!parseGroup(root
,rootGroup
, reload
))
527 // todo hulud interface syntax error
528 nlwarning ("could not parse group");
530 else if (!strcmp((char*)root
->name
,"instance"))
532 if (!parseInstance(root
))
533 // todo hulud interface syntax error
534 nlwarning ("could not parse instance");
536 else if (!strcmp((char*)root
->name
,"view"))
538 if (!parseView(root
,rootGroup
, reload
))
539 // todo hulud interface syntax error
540 nlwarning ("could not parse view");
542 else if (!strcmp((char*)root
->name
,"ctrl"))
544 if (!parseControl(root
,rootGroup
, reload
))
545 // todo hulud interface syntax error
546 nlwarning ("could not parse control");
548 else if ( !strcmp((char*)root
->name
,"vector") )
550 if (!parseVector(root
))
551 // todo hulud interface syntax error
552 nlwarning ("could not parse vector");
554 else if ( !strcmp((char*)root
->name
,"link") )
556 if (!parseLink(root
,rootGroup
))
557 // todo hulud interface syntax error
558 nlwarning ("could not parse link");
560 else if ( !strcmp((char*)root
->name
,"variable") )
562 if (!parseVariable(root
,rootGroup
))
563 // todo hulud interface syntax error
564 nlwarning ("could not parse variable");
566 else if ( !strcmp((char*)root
->name
,"tree") )
568 if (!parseTree(root
,curRoot
))
569 // todo hulud interface syntax error
570 nlwarning ("could not parse tree");
571 /* if (!setupTree(root,curRoot))
572 nlwarning ("could not setup tree"); */
574 else if ( !strcmp((char*)root
->name
,"proc") )
576 if (!parseProcedure(root
, reload
))
577 // todo hulud interface syntax error
578 nlwarning ("could not parse procedure");
580 else if ( !strcmp((char*)root
->name
,"sheet_selection") )
582 if (!parseSheetSelection(root
))
583 // todo hulud interface syntax error
584 nlwarning ("could not parse sheet selection");
586 else if ( !strcmp((char*)root
->name
,"anim") )
588 if (!parseAnim(root
,rootGroup
))
589 // todo hulud interface syntax error
590 nlwarning ("could not parse 'anim'");
592 else if ( !strcmp((char*)root
->name
,"lua") )
594 if(!parseLUAScript(root
))
596 nlerror ("could not parse 'lua'");
601 IParserModule
*module
= getModuleFor( (char*)( root
->name
) );
604 if( module
->canParseInStage( IParserModule::Resolved
) )
605 module
->parse( root
, rootGroup
);
612 // add all modals group to the window list
613 for (uint32 i
= 0; i
< _MasterGroups
.size(); ++i
)
616 CWidgetManager::SMasterGroup
&rMG
= _MasterGroups
[i
];
618 for (uint32 j
= 0; j
< rMG
.Group
->getGroups().size(); ++j
)
620 CGroupModal
*pIG
= dynamic_cast<CGroupModal
*>(rMG
.Group
->getGroups()[j
]);
621 // if it is a modal group
624 // add to the window list
625 CWidgetManager::getInstance()->addWindowToMasterGroup(rMG
.Group
->getId(), pIG
);
630 // init all the elements coords, and Lua Script
631 if (!initCoordsAndLuaScript())
634 std::vector
<xmlNodePtr
> keptTemplates
;
636 // keep template that have the "keep" flag if we are not reloading
637 // if reloading, always keep the template
640 for(uint k
= 0; k
< _Templates
.size(); ++k
)
642 CXMLAutoPtr
ptr(xmlGetProp(_Templates
[k
], (const xmlChar
*) "keep"));
643 if (reload
|| (ptr
&& nlstricmp((const char *) ptr
, "true") == 0))
645 // xmlUnsetProp(_Templates[k], (const xmlChar *) "keep");
646 xmlNodePtr copy
= xmlCopyNode(_Templates
[k
], 1);
648 keptTemplates
.push_back(copy
);
651 // free the original node, whether we kept a copy or not
652 xmlUnlinkNode( _Templates
[k
] );
653 xmlFreeNode( _Templates
[k
] );
654 _Templates
[k
] = NULL
;
657 _Templates
.swap(keptTemplates
);
662 // ----------------------------------------------------------------------------
663 bool CInterfaceParser::parseTemplateNode(xmlNodePtr node
,xmlNodePtr instance
,xmlNodePtr templ
)
666 //get the node properties
667 xmlAttrPtr props
= node
->properties
;
670 //get the property value
671 ptr
= (char*)xmlGetProp( node
, props
->name
);
673 //if it begins with a #, it is a reference in the instance attribute
674 if (strchr(ptr
, '#') != NULL
)
676 string LastProp
= ptr
.str();
680 while (!LastProp
.empty())
682 string::size_type diesPos
= LastProp
.find("#");
683 if (diesPos
!= string::npos
)
687 NewProp
+= LastProp
.substr(0, LastProp
.find("#"));
688 LastProp
= LastProp
.substr(LastProp
.find("#"),LastProp
.size());
691 CXMLAutoPtr instanceProp
;
692 for (uint32 i
= 0; i
< LastProp
.size(); ++i
)
694 RepProp
= LastProp
.substr(0, LastProp
.size()-i
);
695 instanceProp
= xmlGetProp (instance
, (const xmlChar
*)(RepProp
.c_str() + 1));
698 instanceProp
= xmlGetProp (templ
, (const xmlChar
*)(RepProp
.c_str() + 1));
704 CXMLAutoPtr
ptr2((const char*)xmlGetProp( instance
, (xmlChar
*)"id"));
706 if (ptr2
.getDatas() != NULL
)
707 sTmp
= string("cannot parse template node property: ") + ((const char *) ptr
+ 1) + string(" in instance : ") + string((const char*)ptr2
);
709 sTmp
= string("cannot parse template node property: ") + ((const char *) ptr
+ 1) + string(" in instance : NULL");
710 // todo hulud interface syntax error
711 nlinfo(sTmp
.c_str());
715 NewProp
+= string((const char*)instanceProp
);
716 LastProp
= LastProp
.substr (RepProp
.size(), LastProp
.size());
724 xmlSetProp(node
,props
->name
, (const xmlChar
*)NewProp
.c_str());
728 //parse the node children
729 node
= node
->children
;
732 if (!parseTemplateNode(node
,instance
,templ
))
739 // ----------------------------------------------------------------------------
740 bool CInterfaceParser::parseInstance(xmlNodePtr cur
)
744 //try to find the instance template in our template vector. If the template doesn't exist, return false
745 CXMLAutoPtr
templ((const char*) xmlGetProp( cur
, (xmlChar
*)"template" ));
748 // todo hulud interface syntax error
749 nlinfo("parse error : no referenced template in an instance");
752 vector
<xmlNodePtr
>::const_iterator it
;
753 for (it
= _Templates
.begin(); it
!= _Templates
.end();it
++)
755 ptr
= (char*) xmlGetProp( *it
, (xmlChar
*)"name" );
758 // todo hulud interface syntax error
759 nlinfo("no name in a template node");
762 if ( !strcmp(templ
,ptr
) )
767 if ( it
== _Templates
.end() )
769 // todo hulud interface syntax error
770 nlinfo("the template %s was not found", (const char*)templ
);
774 xmlNodePtr templNode
= *it
;
775 //for each child of the template, create the appropriate node
776 xmlNodePtr child
= (*it
)->children
;
777 xmlNodePtr nextSibling
=cur
;
780 //copy the template child node
781 xmlNodePtr node
= xmlCopyNode (child
, 1);
784 //node = xmlAddChild(cur->parent,node);
785 node
= xmlAddNextSibling (nextSibling
, node
);
786 nextSibling
= nextSibling
->next
;
789 if (!parseTemplateNode(node
, cur
, templNode
))
796 // ----------------------------------------------------------------------------
797 bool CInterfaceParser::parseVector(xmlNodePtr cur
)
799 //get the number of elements
800 CXMLAutoPtr
cSize((const char*) xmlGetProp( cur
, (xmlChar
*)"_size" ));
803 // todo hulud interface syntax error
804 nlinfo("no _size in a vector");
808 fromString(cSize
.str(), size
);
811 // todo hulud interface syntax error
817 bool bGroupVector
= true;
819 //get the first position reference
820 CXMLAutoPtr
firstpos((const char*) xmlGetProp( cur
, (xmlChar
*)"_firstpos" ));
823 bGroupVector
= false;
825 //get the next position reference
826 CXMLAutoPtr
nextpos((const char*) xmlGetProp( cur
, (xmlChar
*)"_nextpos" ));
829 bGroupVector
= false;
833 //get the first index value
834 CXMLAutoPtr
indexChar((const char*) xmlGetProp( cur
, (xmlChar
*)"_firstindex" ));
837 fromString((const char*)indexChar
, index
);
841 //get the step for the indices
842 CXMLAutoPtr
stepChar((const char*) xmlGetProp( cur
, (xmlChar
*)"_step" ));
845 fromString((const char*)stepChar
, step
);
849 //get the x and y of the first element
850 CXMLAutoPtr
xfirst((const char*) xmlGetProp( cur
, (xmlChar
*)"_xfirst" ));
851 CXMLAutoPtr
yfirst((const char*) xmlGetProp( cur
, (xmlChar
*)"_yfirst" ));
855 xmlNodePtr nextSibling
= cur
;
856 //now we can add all the following elements
858 for (i
= index
;; i
+= step
)
862 if (i
>= index
+ size
) break;
866 if (i
<= index
- size
) break;
869 node
= xmlCopyNode(cur
,1);
870 //set the name and posref
876 xmlSetProp(node
,(xmlChar
*)"posref",(const xmlChar
*)firstpos
);
879 xmlSetProp(node
,(xmlChar
*)"x",(const xmlChar
*)xfirst
);
883 xmlSetProp(node
,(xmlChar
*)"y",(const xmlChar
*)yfirst
);
888 xmlSetProp(node
,(xmlChar
*)"posref",(const xmlChar
*)nextpos
);
889 xmlSetProp(node
,(xmlChar
*)"posparent",(const xmlChar
*)id
);
893 xmlNodeSetName(node
,(xmlChar
*)"instance");
896 xmlAttrPtr attr
= node
->properties
;
899 CXMLAutoPtr
prop((const char*) xmlGetProp( node
, attr
->name
));
900 string
str((const char*)prop
);
901 string::size_type pos
= str
.find("$i");
902 while (pos
!= string::npos
)
904 str
.replace(pos
,2,toString(i
));
905 pos
= str
.find("$i",pos
);
907 xmlSetProp(node
,attr
->name
,(xmlChar
*)str
.c_str());
911 //add the new instance to our tree, just near us.
912 xmlAddNextSibling (nextSibling
, node
);
915 //get the node id, used in the next iteration
918 id
= (char*) xmlGetProp( node
, (xmlChar
*)"id" );
921 // todo hulud interface syntax error
922 nlinfo("no id in a vector");
928 return step
> 0 ? (i
== index
+ size
) : (i
== index
- size
);
931 // ----------------------------------------------------------------------------
932 bool CInterfaceParser::parseLink(xmlNodePtr cur
, CInterfaceGroup
* parentGroup
)
934 CXMLAutoPtr
ptr((const char*) xmlGetProp (cur
, (xmlChar
*)"expr"));
937 // todo hulud interface syntax error
938 nlwarning("<CInterfaceParser::parseLink> Can't read the expression for a link node");
941 std::string expr
= ptr
.str();
944 std::vector
<CInterfaceLink::CTargetInfo
> targets
;
945 std::vector
<CInterfaceLink::CCDBTargetInfo
> cdbTargets
;
947 ptr
= (char*) xmlGetProp (cur
, (xmlChar
*)"target");
951 target
= std::string( (const char*)ptr
);
953 CInterfaceLink::splitLinkTargetsExt(std::string((const char*)ptr
), parentGroup
, targets
, cdbTargets
);
956 // optional action handler
960 ptr
= (char*) xmlGetProp (cur
, (xmlChar
*)"action");
961 if (ptr
) action
= (const char *) ptr
;
962 ptr
= (char*) xmlGetProp (cur
, (xmlChar
*)"params");
963 if (ptr
) params
= (const char *) ptr
;
964 ptr
= (char*) xmlGetProp (cur
, (xmlChar
*)"cond");
965 if (ptr
) cond
= (const char *) ptr
;
970 CInterfaceLink
*il
= new CInterfaceLink
;
971 il
->init(targets
, cdbTargets
, expr
, action
, params
, cond
, parentGroup
); // init will add 'il' in the list of link present in 'elm'
976 linkData
.parent
= parentGroup
->getId();
977 linkData
.expr
= expr
;
978 linkData
.target
= target
;
979 linkData
.action
= action
;
980 linkData
.cond
= cond
;
981 linkData
.params
= params
;
983 addLinkData( linkData
);
989 // ----------------------------------------------------------------------------
990 bool CInterfaceParser::parseVariable (xmlNodePtr cur
, CInterfaceGroup
* /* parentGroup */)
993 CXMLAutoPtr
ptr((const char*) xmlGetProp (cur
, (xmlChar
*)"entry"));
996 // todo hulud interface syntax error
997 nlinfo ("no entry in a variable tag");
1000 string
entry((const char*)ptr
);
1002 ptr
= (char*) xmlGetProp (cur
, (xmlChar
*)"type");
1005 // todo hulud interface syntax error
1006 nlinfo ("no type in a variable tag");
1009 string
type((const char*)ptr
);
1012 ptr
= (char*) xmlGetProp (cur
, (xmlChar
*)"value");
1015 //if no value is specified, try to get the db entry directly
1020 value
= string((const char*)ptr
);
1025 bool ArrayMode
= false;
1028 ptr
= (char*) xmlGetProp (cur
, (xmlChar
*)"size");
1032 fromString((const char*)ptr
, size
);
1034 string::size_type pos
= entry
.find("$i");
1035 if( pos
==string::npos
)
1037 // todo hulud interface syntax error
1038 nlinfo ("no $i found in a 'variable' tag with 'size' defined ");
1043 entryPrefix
= entry
.substr(0, pos
);
1044 entrySuffix
= entry
.substr(pos
+2);
1048 // loop all variables
1049 for(sint index
= 0;index
<size
;index
++)
1051 // If array variable, build the variable name
1054 entry
= entryPrefix
+ toString(index
) + entrySuffix
;
1057 // access the database
1058 CInterfaceProperty prop
;
1060 if (type
== "sint64")
1061 prop
.readSInt64(value
.c_str(),entry
);
1062 else if (type
== "sint32")
1063 prop
.readSInt32(value
.c_str(),entry
);
1064 else if (type
== "float" || type
== "double")
1065 prop
.readDouble(value
.c_str(),entry
);
1066 else if (type
== "bool")
1067 prop
.readBool(value
.c_str(),entry
);
1068 else if (type
== "rgba")
1069 prop
.readRGBA(value
.c_str(),entry
);
1070 else if (type
== "hotspot")
1071 prop
.readHotSpot(value
.c_str(),entry
);
1072 else if (type
== "text")
1074 /*uint textId = addText(value);
1075 prop.readSInt32(toString(textId),entry);*/
1083 ptr
= xmlGetProp( cur
, BAD_CAST
"entry" );
1085 data
.entry
= std::string( (const char*)ptr
);
1089 ptr
= xmlGetProp( cur
, BAD_CAST
"value" );
1091 data
.value
= std::string( (const char*)ptr
);
1093 ptr
= xmlGetProp( cur
, BAD_CAST
"size" );
1095 fromString( std::string( (const char*)ptr
), data
.size
);
1097 variableCache
[ data
.entry
] = data
;
1103 // ----------------------------------------------------------------------------
1104 bool CInterfaceParser::parseOptions (xmlNodePtr cur
, CInterfaceGroup
* /* parentGroup */)
1106 // build the options from type
1107 CInterfaceOptions
*options
= NULL
;
1108 CXMLAutoPtr
ptr((const char*) xmlGetProp( cur
, (xmlChar
*)"type" ));
1111 options
= NLMISC_GET_FACTORY( CInterfaceOptions
, std::string
).createObject( std::string( (const char*)ptr
), CInterfaceOptions::TCtorParam() );
1113 if( options
== NULL
)
1114 options
= new CInterfaceOptions( CInterfaceOptions::TCtorParam() );
1118 options
= new CInterfaceOptions( CInterfaceOptions::TCtorParam() );
1121 CWidgetManager
*wm
= CWidgetManager::getInstance();
1124 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"name" );
1127 // todo hulud interface syntax error
1128 nlinfo ("options has no name");
1131 string optionsName
= ptr
.str();
1133 // herit if possible
1134 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"herit" );
1137 string optionsParentName
= ptr
.str();
1138 CInterfaceOptions
*io
= wm
->getOptions( optionsParentName
);
1140 options
->copyBasicMap( *io
);
1144 if (options
->parse (cur
))
1147 wm
->removeOptions( optionsName
);
1148 wm
->addOptions( optionsName
, options
);
1158 // ----------------------------------------------------------------------------
1159 bool CInterfaceParser::parseGroup (xmlNodePtr cur
, CInterfaceGroup
* parentGroup
, bool reload
)
1161 CInterfaceGroup
* group
;
1162 CXMLAutoPtr
ptr((const char*) xmlGetProp( cur
, (xmlChar
*)"type" ));
1165 group
= dynamic_cast<CInterfaceGroup
*>( NLMISC_GET_FACTORY(CViewBase
, std::string
).createObject(string((const char*)ptr
), CViewBase::TCtorParam()) );
1168 group
= dynamic_cast<CInterfaceGroup
*>(NLMISC_GET_FACTORY(CViewBase
, std::string
).createObject("interface_group", CViewBase::TCtorParam()));
1173 group
= dynamic_cast<CInterfaceGroup
*>(NLMISC_GET_FACTORY(CViewBase
, std::string
).createObject("interface_group", CViewBase::TCtorParam()));
1175 // parse the group attributes
1176 if (!group
->parse(cur
,parentGroup
))
1179 // todo hulud interface syntax error
1180 nlwarning ("cannot parse group attributes");
1186 CGroupList
*pList
= dynamic_cast<CGroupList
*>(parentGroup
);
1187 if (parentGroup
->getElement(group
->getId()) != NULL
)
1189 // Remove old groupe and replace
1192 // Remove from the parent
1193 parentGroup
->delElement (group
->getId(), true);
1197 // todo hulud interface syntax error
1198 nlwarning ("id already exists for %s in %s", group
->getId().c_str(), parentGroup
->getId().c_str());
1205 pList
->addChild (group
);
1207 parentGroup
->addGroup (group
);
1211 // todo hulud interface syntax error
1212 nlinfo ("no parent for %s", group
->getId().c_str());
1217 //parse the children
1218 bool ok
= parseGroupChildren(cur
, group
, reload
);
1222 string tmp
= "cannot parse group "+group
->getId();
1223 // todo hulud interface syntax error
1224 nlinfo (tmp
.c_str());
1229 // ----------------------------------------------------------------------------
1230 bool CInterfaceParser::parseGroupChildren(xmlNodePtr cur
, CInterfaceGroup
* parentGroup
, bool reload
)
1232 cur
= cur
->children
;
1236 if ( !strcmp((char*)cur
->name
,"view") )
1237 ok
= ok
&& parseView(cur
,parentGroup
, reload
);
1238 else if ( !strcmp((char*)cur
->name
,"ctrl") )
1239 ok
= ok
&& parseControl(cur
,parentGroup
, reload
);
1240 else if ( !strcmp((char*)cur
->name
,"group") )
1241 ok
= ok
&& parseGroup(cur
,parentGroup
, reload
);
1242 else if ( !strcmp((char*)cur
->name
,"instance") )
1243 ok
= ok
&& parseInstance(cur
);
1244 else if ( !strcmp((char*)cur
->name
,"vector") )
1245 ok
= ok
&& parseVector(cur
);
1246 else if ( !strcmp((char*)cur
->name
,"link") )
1247 ok
= ok
&& parseLink(cur
,parentGroup
);
1250 IParserModule
*module
= getModuleFor( (char*)( cur
->name
) );
1251 if( module
!= NULL
)
1253 if( module
->canParseInStage( IParserModule::GroupChildren
) )
1254 ok
= ok
&& module
->parse( cur
, parentGroup
);
1264 // ----------------------------------------------------------------------------
1265 bool CInterfaceParser::parseControl (xmlNodePtr cur
, CInterfaceGroup
* parentGroup
, bool reload
)
1267 CCtrlBase
* ctrl
= NULL
;
1268 CXMLAutoPtr
ptr((const char*) xmlGetProp( cur
, (xmlChar
*)"type" ));
1271 // todo hulud interface syntax error
1272 nlinfo ("no type in a control tag");
1276 ctrl
= dynamic_cast<CCtrlBase
*>(NLMISC_GET_FACTORY(CViewBase
, std::string
).createObject(string((const char*)ptr
), CViewBase::TCtorParam()));
1280 if (!ctrl
->parse(cur
,parentGroup
))
1285 if (parentGroup
->getElement(ctrl
->getId()) != NULL
)
1287 // Remove old groupe and replace
1289 parentGroup
->delElement (ctrl
->getId());
1292 // todo hulud interface syntax error
1293 nlwarning ("id already exists for %s in %s", ctrl
->getId().c_str(), parentGroup
->getId().c_str());
1298 // Add the ctrl to the parent group
1299 parentGroup
->addCtrl(ctrl
);
1305 // ----------------------------------------------------------------------------
1306 bool CInterfaceParser::parseView(xmlNodePtr cur
, CInterfaceGroup
* parentGroup
, bool reload
)
1308 CViewBase
* view
=NULL
;
1309 CXMLAutoPtr
ptr((const char*) xmlGetProp( cur
, (xmlChar
*)"type" ));
1312 // todo hulud interface syntax error
1313 nlinfo("no type in a view");
1317 view
= NLMISC_GET_FACTORY(CViewBase
, std::string
).createObject(string((const char*)ptr
), CViewBase::TCtorParam());
1319 if ( !strcmp(ptr
,"pointer"))
1322 savePointerSettings( cur
);
1324 CWidgetManager::getInstance()->setPointer( dynamic_cast<CViewPointer
*>(view
) );
1327 //nlinfo("view type %s mem : %d",ptr,view->getMemory());
1330 if (!view
->parse(cur
,parentGroup
))
1335 if (parentGroup
->getElement(view
->getId()) != NULL
)
1337 // Remove old groupe and replace
1339 parentGroup
->delElement (view
->getId());
1342 // todo hulud interface syntax error
1343 nlwarning ("id already exists for %s in %s", view
->getId().c_str(), parentGroup
->getId().c_str());
1349 //add the view to the parent group
1350 CGroupList
*pList
= dynamic_cast<CGroupList
*>(parentGroup
);
1353 pList
->addChild (view
);
1357 parentGroup
->addView(view
);
1361 // todo hulud interface syntax error
1362 nlinfo("unknown view type %s", (const char*)ptr
);
1366 // ----------------------------------------------------------------------------
1367 bool CInterfaceParser::parseTreeNode (xmlNodePtr cur
, CGroupContainer
*parentGroup
)
1369 CXMLAutoPtr
ptr((const char*) xmlGetProp( cur
, (xmlChar
*)"node" ));
1370 if (!ptr
) return false;
1372 string stmp2
= toLowerAscii(string((const char*)ptr
));
1374 CInterfaceElement
*pEltFound
= NULL
;
1375 std::vector
< CWidgetManager::SMasterGroup
> &_MasterGroups
= CWidgetManager::getInstance()->getAllMasterGroup();
1376 for (uint32 i
= 0; i
< _MasterGroups
.size(); ++i
)
1378 CWidgetManager::SMasterGroup
&rMG
= _MasterGroups
[i
];
1379 for (uint32 j
= 0; j
< rMG
.Group
->getGroups().size(); ++j
)
1381 CInterfaceGroup
*pIG
= rMG
.Group
->getGroups()[j
];
1382 string stmp
= toLowerAscii(pIG
->getId().substr(pIG
->getId().rfind(':')+1,pIG
->getId().size()));
1390 if (pEltFound
!= NULL
)
1393 if (pEltFound
== NULL
)
1395 string stmp
= string("element not found for tree : ") + string((const char*)ptr
);
1396 // todo hulud interface syntax error
1397 nlinfo(stmp
.c_str());
1400 CGroupContainer
*pIC
= dynamic_cast<CGroupContainer
*>(pEltFound
);
1403 string stmp
= string("not a container : ") + pEltFound
->getId();
1404 // todo hulud interface syntax error
1405 nlinfo(stmp
.c_str());
1408 parentGroup
->attachContainer (pIC
);
1409 cur
= cur
->children
;
1412 parseTreeNode(cur
, pIC
);
1418 // ----------------------------------------------------------------------------
1419 bool CInterfaceParser::setupTreeNode (xmlNodePtr cur
, CGroupContainer
* /* parentGroup */)
1421 CXMLAutoPtr
ptr((const char*) xmlGetProp( cur
, (xmlChar
*)"node" ));
1422 if (!ptr
) return false;
1424 string stmp2
= toLowerAscii(string((const char*)ptr
));
1426 std::vector
< CWidgetManager::SMasterGroup
> &_MasterGroups
= CWidgetManager::getInstance()->getAllMasterGroup();
1427 CInterfaceElement
*pEltFound
= NULL
;
1428 for (uint32 i
= 0; i
< _MasterGroups
.size(); ++i
)
1430 CWidgetManager::SMasterGroup
&rMG
= _MasterGroups
[i
];
1431 for (uint32 j
= 0; j
< rMG
.Group
->getGroups().size(); ++j
)
1433 CInterfaceGroup
*pIG
= rMG
.Group
->getGroups()[j
];
1434 string stmp
= toLowerAscii(pIG
->getId().substr(pIG
->getId().rfind(':')+1,pIG
->getId().size()));
1441 if (pEltFound
!= NULL
)
1444 if (pEltFound
== NULL
)
1446 string stmp
= string("element not found for tree : ") + string((const char*)ptr
);
1447 // todo hulud interface syntax error
1448 nlinfo(stmp
.c_str());
1451 CGroupContainer
*pIC
= dynamic_cast<CGroupContainer
*>(pEltFound
);
1454 string stmp
= string("not a container : ") + pEltFound
->getId();
1455 // todo hulud interface syntax error
1456 nlinfo(stmp
.c_str());
1459 // See if the group should be docked.
1460 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"docked" );
1461 if (nlstricmp((const char *) ptr
, "true") == 0)
1463 // dock the container
1464 pIC
->popupCurrentPos();
1465 // compute position on screen
1466 sint32 x
= 0, y
= 0, w
= 200, h
= 100;
1467 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"x" );
1471 if (fromString((const char*)ptr
, value
))
1476 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"y" );
1480 if (fromString((const char*)ptr
, value
))
1485 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"w" );
1489 if (fromString((const char*)ptr
, value
))
1494 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"h" );
1498 if (fromString((const char*)ptr
, value
))
1507 pIC
->invalidateCoords();
1512 setupTreeNode(cur
, pIC
);
1518 void CInterfaceParser::savePointerSettings( xmlNodePtr node
)
1523 xmlAttrPtr prop
= node
->properties
;
1528 while( prop
!= NULL
)
1530 key
= std::string( reinterpret_cast< const char* >( prop
->name
) );
1531 value
= std::string( reinterpret_cast< char* >( prop
->children
->content
) );
1533 pointerSettings
[ key
] = value
;
1539 void CInterfaceParser::saveKeySettings( xmlNodePtr node
)
1544 xmlAttrPtr prop
= node
->properties
;
1546 std::string
name( reinterpret_cast< char* >( xmlGetProp( node
, BAD_CAST
"name" ) ) );
1552 std::map
< std::string
, std::string
> propMap
;
1554 while( prop
!= NULL
)
1556 key
= std::string( reinterpret_cast< const char* >( prop
->name
) );
1557 value
= std::string( reinterpret_cast< char* >( prop
->children
->content
) );
1565 propMap
[ key
] = value
;
1570 if( propMap
.empty() )
1573 keySettings
[ name
] = propMap
;
1576 void CInterfaceParser::addModule( std::string name
, IParserModule
*module
)
1578 std::map
< std::string
, IParserModule
* >::iterator itr
=
1579 moduleMap
.find( name
);
1581 if( itr
!= moduleMap
.end() )
1583 nlwarning( "Tried to add parser module %s, which already exists.",name
.c_str() );
1588 module
->setParser( this );
1589 moduleMap
[ name
] = module
;
1592 CInterfaceParser::IParserModule
* CInterfaceParser::getModuleFor( std::string name
) const
1594 std::map
< std::string
, IParserModule
* >::const_iterator itr
=
1595 moduleMap
.find( name
);
1596 if( itr
== moduleMap
.end() )
1602 void CInterfaceParser::removeAllModules()
1604 std::map
< std::string
, IParserModule
* >::iterator itr
;
1605 for( itr
= moduleMap
.begin(); itr
!= moduleMap
.end(); ++itr
)
1612 // ----------------------------------------------------------------------------
1613 bool CInterfaceParser::setupTree (xmlNodePtr cur
, CWidgetManager::SMasterGroup
* /* parentGroup */)
1615 CXMLAutoPtr
ptr((const char*) xmlGetProp( cur
, (xmlChar
*)"node" ));
1616 if (!ptr
) return false;
1618 string stmp2
= toLowerAscii(string((const char*)ptr
));
1620 std::vector
< CWidgetManager::SMasterGroup
> &_MasterGroups
= CWidgetManager::getInstance()->getAllMasterGroup();
1621 CInterfaceElement
*pEltFound
= NULL
;
1622 for (uint32 i
= 0; i
< _MasterGroups
.size(); ++i
)
1624 CWidgetManager::SMasterGroup
&rMG
= _MasterGroups
[i
];
1625 for (uint32 j
= 0; j
< rMG
.Group
->getGroups().size(); ++j
)
1627 CInterfaceGroup
*pIG
= rMG
.Group
->getGroups()[j
];
1628 string stmp
= toLowerAscii(pIG
->getId().substr(pIG
->getId().rfind(':')+1,pIG
->getId().size()));
1636 if (pEltFound
!= NULL
)
1640 if (pEltFound
== NULL
)
1642 string stmp
= string("no group found for ") + string((const char*)ptr
);
1643 // todo hulud interface syntax error
1644 nlinfo(stmp
.c_str());
1648 // the element must be a group
1649 CInterfaceGroup
*pIG
= dynamic_cast<CInterfaceGroup
*>(pEltFound
);
1652 string stmp
= string("not a group !") + pEltFound
->getId();
1653 // todo hulud interface syntax error
1654 nlinfo(stmp
.c_str());
1658 // but must not be a group modal
1659 if (dynamic_cast<CGroupModal
*>(pIG
))
1661 string stmp
= string("tree can't have modal group !") + pEltFound
->getId();
1662 // todo hulud interface syntax error
1663 nlinfo(stmp
.c_str());
1668 CGroupContainer
*pIC
= dynamic_cast<CGroupContainer
*>(pEltFound
);
1671 cur
= cur
->children
;
1674 setupTreeNode(cur
, pIC
);
1683 // ----------------------------------------------------------------------------
1684 bool CInterfaceParser::parseTree (xmlNodePtr cur
, CWidgetManager::SMasterGroup
*parentGroup
)
1686 CXMLAutoPtr
ptr((const char*) xmlGetProp( cur
, (xmlChar
*)"node" ));
1687 if (!ptr
) return false;
1688 std::vector
< CWidgetManager::SMasterGroup
> &_MasterGroups
= CWidgetManager::getInstance()->getAllMasterGroup();
1689 CInterfaceElement
*pEltFound
= NULL
;
1690 for (uint32 i
= 0; i
< _MasterGroups
.size(); ++i
)
1692 CWidgetManager::SMasterGroup
&rMG
= _MasterGroups
[i
];
1693 for (uint32 j
= 0; j
< rMG
.Group
->getGroups().size(); ++j
)
1695 CInterfaceGroup
*pIG
= rMG
.Group
->getGroups()[j
];
1696 string stmp
= NLMISC::toLowerAscii(pIG
->getId().substr(pIG
->getId().rfind(':')+1,pIG
->getId().size()));
1697 string stmp2
= NLMISC::toLowerAscii(string((const char*)ptr
));
1704 if (pEltFound
!= NULL
)
1708 if (pEltFound
== NULL
)
1710 string stmp
= string("no group found for ") + string((const char*)ptr
);
1711 // todo hulud interface syntax error
1712 nlinfo(stmp
.c_str());
1716 // the element must be a group
1717 CInterfaceGroup
*pIG
= dynamic_cast<CInterfaceGroup
*>(pEltFound
);
1720 string stmp
= string("not a group !") + pEltFound
->getId();
1721 // todo hulud interface syntax error
1722 nlinfo(stmp
.c_str());
1726 // but must not be a group modal
1727 if (dynamic_cast<CGroupModal
*>(pIG
))
1729 string stmp
= string("tree can't have modal group !") + pEltFound
->getId();
1730 // todo hulud interface syntax error
1731 nlinfo(stmp
.c_str());
1736 CWidgetManager::getInstance()->addWindowToMasterGroup(parentGroup
->Group
->getId(), pIG
);
1738 CGroupContainer
*pIC
= dynamic_cast<CGroupContainer
*>(pEltFound
);
1741 cur
= cur
->children
;
1744 parseTreeNode(cur
, pIC
);
1751 // ----------------------------------------------------------------------------
1752 bool CInterfaceParser::parseDefine(xmlNodePtr cur
)
1754 CXMLAutoPtr
ptr((const char*) xmlGetProp( cur
, (xmlChar
*)"id" ));
1755 if (!ptr
|| *ptr
==0)
1757 // todo hulud interface syntax error
1758 nlinfo ("no id in a define");
1761 CXMLAutoPtr ptrVal2
;
1762 CXMLAutoPtr
ptrVal((const char*) xmlGetProp( cur
, (xmlChar
*)"value" ));
1765 ptrVal2
= (char*) xmlGetProp( cur
, (xmlChar
*)"value_from_code" );
1768 // todo hulud interface syntax error
1769 nlwarning ("<parseDefine> : no value nor value_from_code in a define");
1775 string id
= (const char*)ptr
;
1776 for(uint i
=0;i
<id
.size();i
++)
1778 if(!validDefineChar(id
[i
]))
1780 // todo hulud interface syntax error
1781 nlwarning ("<parseDefine> : bad id in a define. Bad char found: %c", id
[i
]);
1786 // Check if we have to execute some code
1789 CInterfaceExprValue res
;
1791 if (CInterfaceExpr::eval(ptrVal2
.str(), res
))
1793 if (!res
.toString())
1795 // todo hulud interface syntax error
1796 nlwarning ("<parseDefine> : cant eval to string value_from_code : %s", (const char*)ptrVal2
);
1799 setDefine(id
, res
.getString().c_str());
1803 // todo hulud interface syntax error
1804 nlwarning ("<parseDefine> : cant eval value_from_code : %s", (const char*)ptrVal2
);
1811 setDefine (id
, (const char*)ptrVal
);
1817 // ----------------------------------------------------------------------------
1818 bool CInterfaceParser::parseProcedure(xmlNodePtr cur
, bool reload
)
1820 CXMLAutoPtr
ptr((const char*) xmlGetProp( cur
, (xmlChar
*)"id" ));
1821 if (!ptr
|| *ptr
==0)
1823 // todo hulud interface syntax error
1824 nlwarning ("no id in a procedure");
1827 string procId
= ptr
.str();
1829 if (_ProcedureMap
.find(procId
) != _ProcedureMap
.end())
1831 // If reloading the interface, remove the old proc
1834 _ProcedureMap
.erase (procId
);
1838 // todo hulud interface syntax error
1839 nlwarning ("id already exists for procedure %s", procId
.c_str());
1844 // build the procedure
1848 cur
= cur
->children
;
1851 if (stricmp((char*)cur
->name
,"action") == 0)
1853 CXMLAutoPtr
name((const char*) xmlGetProp (cur
, (xmlChar
*)"handler"));
1854 CXMLAutoPtr
params((const char*) xmlGetProp (cur
, (xmlChar
*)"params"));
1855 CXMLAutoPtr
cond((const char*) xmlGetProp (cur
, (xmlChar
*)"cond"));
1859 // todo hulud interface syntax error
1860 nlinfo("no action name in a action of procedure %s", procId
.c_str());
1864 action
.Action
= (const char*)name
;
1867 action
.Parameters
= (const char*)params
;
1868 action
.buildParamBlock((const char*)params
);
1872 action
.Conditions
= (const char*)cond
;
1873 action
.buildCondBlock ((const char*)cond
);
1875 newProc
.Actions
.push_back(action
);
1877 else if (!strcmp((char*)cur
->name
,"instance"))
1879 if (!parseInstance(cur
))
1880 // todo hulud interface syntax error
1881 nlwarning ("could not parse instance");
1883 else if (!strcmp((char*)cur
->name
,"vector"))
1885 if (!parseVector(cur
))
1886 // todo hulud interface syntax error
1887 nlwarning ("could not parse vector");
1892 // add/replace the procedure
1893 _ProcedureMap
[procId
]= newProc
;
1898 void CInterfaceParser::setupOptions()
1900 if( setupCallback
!= NULL
)
1901 setupCallback
->setupOptions();
1904 // ----------------------------------------------------------------------------
1905 bool CInterfaceParser::initCoordsAndLuaScript()
1907 // set all position associations
1908 for (map
<CInterfaceElement
*,string
>::const_iterator it
= _ParentPositionsMap
.begin(); it
!= _ParentPositionsMap
.end();it
++)
1910 CInterfaceElement
*pIEL
= it
->first
;
1911 string EltName
= it
->second
;
1913 CInterfaceGroup
*parent
= pIEL
->getParent();
1914 CInterfaceElement
*parentpos
;
1915 //if the element has a parent check the parent's children
1917 parentpos
= parent
->getElement(EltName
);
1918 //if the element has no parent, check the windows
1920 parentpos
= CWidgetManager::getInstance()->getWindowFromId(EltName
);
1922 if (parentpos
== NULL
)
1924 // todo hulud interface syntax error
1925 nlinfo(" the element %s was not found as %s position reference ", EltName
.c_str(), pIEL
->getId().c_str());
1929 pIEL
->setParentPos (parentpos
);
1933 for (map
<CInterfaceElement
*,string
>::const_iterator it2
= _ParentSizesMap
.begin(); it2
!= _ParentSizesMap
.end(); it2
++)
1935 CInterfaceElement
*pIEL
= it2
->first
;
1936 string EltName
= it2
->second
;
1938 CInterfaceGroup
*parent
= pIEL
->getParent();
1939 CInterfaceElement
*parentsize
;
1940 if (EltName
== "parent")
1942 parentsize
= pIEL
->getParent();
1946 //if the element has a parent check the parent's children
1948 parentsize
= parent
->getElement(EltName
);
1949 //if the element has no parent, check the windows
1951 parentsize
= CWidgetManager::getInstance()->getWindowFromId(EltName
);
1954 if (parentsize
== NULL
)
1956 // todo hulud interface syntax error
1957 nlinfo(" the element %s was not found as %s size reference ", EltName
.c_str(), pIEL
->getId().c_str());
1961 pIEL
->setParentSize (parentsize
);
1964 // Same for size max
1965 for (map
<CInterfaceElement
*,string
>::const_iterator it3
= _ParentSizesMaxMap
.begin(); it3
!= _ParentSizesMaxMap
.end(); it3
++)
1967 CInterfaceGroup
*pIEL
= dynamic_cast<CInterfaceGroup
*>(it3
->first
);
1968 if (pIEL
== NULL
) continue;
1969 string EltName
= it3
->second
;
1971 CInterfaceGroup
*parent
= pIEL
->getParent();
1972 CInterfaceElement
*parentsizemax
;
1973 if (EltName
== "parent")
1975 parentsizemax
= parent
;
1979 //if the element has a parent check the parent's children
1981 parentsizemax
= parent
->getElement(EltName
);
1982 //if the element has no parent, check the windows
1984 parentsizemax
= CWidgetManager::getInstance()->getWindowFromId(EltName
);
1987 if (parentsizemax
== NULL
)
1989 // todo hulud interface syntax error
1990 nlinfo(" the element %s was not found as %s sizemax reference ", EltName
.c_str(), pIEL
->getId().c_str());
1994 pIEL
->setParentSizeMax (parentsizemax
);
1998 // Same For LUA Class association
1999 for (map
<CInterfaceGroup
*,string
>::const_iterator itLua
= _LuaClassAssociation
.begin(); itLua
!= _LuaClassAssociation
.end(); itLua
++)
2001 // execute the script on this group
2002 CAHManager::getInstance()->runActionHandler("lua", itLua
->first
, itLua
->second
);
2006 // Clear all structures used only for init
2007 NLMISC::contReset (_ParentPositionsMap
);
2008 NLMISC::contReset (_ParentSizesMap
);
2009 NLMISC::contReset (_ParentSizesMaxMap
);
2010 NLMISC::contReset (_LuaClassAssociation
);
2014 // ----------------------------------------------------------------------------
2015 void CInterfaceParser::addParentPositionAssociation(CInterfaceElement
* element
, const std::string
& parent
)
2017 _ParentPositionsMap
.insert (std::map
<CInterfaceElement
*,std::string
>::value_type(element
, parent
));
2020 std::string
CInterfaceParser::getParentPosAssociation( CInterfaceElement
*element
) const
2022 std::map
< CInterfaceElement
*, std::string
>::const_iterator itr
=
2023 _ParentPositionsMap
.find( element
);
2024 if( itr
== _ParentPositionsMap
.end() )
2027 return CInterfaceElement::stripId( itr
->second
);
2030 // ----------------------------------------------------------------------------
2031 void CInterfaceParser::addParentSizeAssociation(CInterfaceElement
* element
, const std::string
& parent
)
2033 _ParentSizesMap
.insert (std::map
<CInterfaceElement
*,std::string
>::value_type(element
, parent
));
2036 std::string
CInterfaceParser::getParentSizeAssociation( CInterfaceElement
*element
) const
2038 std::map
< CInterfaceElement
*, std::string
>::const_iterator itr
=
2039 _ParentSizesMap
.find( element
);
2040 if( itr
== _ParentSizesMap
.end() )
2043 return CInterfaceElement::stripId( itr
->second
);
2046 // ----------------------------------------------------------------------------
2047 void CInterfaceParser::addParentSizeMaxAssociation (CInterfaceElement
*element
, const std::string
&parent
)
2049 _ParentSizesMaxMap
.insert (std::map
<CInterfaceElement
*,std::string
>::value_type(element
, parent
));
2052 std::string
CInterfaceParser::getParentSizeMaxAssociation( CInterfaceElement
*element
) const
2054 std::map
< CInterfaceElement
*, std::string
>::const_iterator itr
=
2055 _ParentSizesMap
.find( element
);
2056 if( itr
== _ParentSizesMap
.end() )
2059 return CInterfaceElement::stripId( itr
->second
);
2062 // ----------------------------------------------------------------------------
2063 void CInterfaceParser::addLuaClassAssociation (CInterfaceGroup
*group
, const std::string
&luaScript
)
2065 _LuaClassAssociation
.insert (std::map
<CInterfaceGroup
*,std::string
>::value_type(group
, luaScript
));
2068 std::string
CInterfaceParser::getLuaClassAssociation( CInterfaceGroup
*group
) const
2070 std::map
< CInterfaceGroup
*, std::string
>::const_iterator itr
=
2071 _LuaClassAssociation
.find( group
);
2072 if( itr
== _LuaClassAssociation
.end() )
2078 // ***************************************************************************
2079 const std::string
&CInterfaceParser::getDefine(const std::string
&id
) const
2081 static string NullStr
;
2082 CstItVarMap it
= _DefineMap
.find(id
);
2083 if(it
==_DefineMap
.end())
2089 // ***************************************************************************
2090 bool CInterfaceParser::isDefineExist(const std::string
&id
) const
2092 CstItVarMap it
= _DefineMap
.find(id
);
2093 return it
!=_DefineMap
.end();
2097 // ***************************************************************************
2098 void CInterfaceParser::setDefine(const std::string
&id
, const std::string
&value
)
2100 _DefineMap
[id
]= value
;
2104 // ***************************************************************************
2105 bool CInterfaceParser::validDefineChar(char c
) const
2107 if(c
>='A' && c
<='Z')
2109 if(c
>='a' && c
<='z')
2111 if(c
>='0' && c
<='9')
2119 #define DEFINE_IDENT '%'
2121 // ***************************************************************************
2122 bool CInterfaceParser::solveDefine(const std::string
&propVal
, std::string
&newPropVal
, std::string
&defError
)
2124 string::size_type curPos
= 0;
2125 string::size_type lastPos
= 0;
2127 //if it has some % then solve define value
2128 while( (curPos
=propVal
.find(DEFINE_IDENT
, curPos
)) != string::npos
)
2130 // If it is end of line
2131 if(curPos
==propVal
.size()-1)
2134 curPos
= propVal
.size();
2136 // If it is a double %%
2137 else if(propVal
[curPos
+1]==DEFINE_IDENT
)
2139 // copy from last to cur included
2141 newPropVal
+= propVal
.substr(lastPos
, curPos
-lastPos
);
2142 // both % are skipped
2146 // else parse define value
2149 // copy the last not define sub string.
2150 newPropVal
+= propVal
.substr(lastPos
, curPos
-lastPos
);
2156 uint startIdPos
= (uint
)curPos
;
2157 while( curPos
<propVal
.size() && validDefineChar(propVal
[curPos
]) )
2160 string defineId
= propVal
.substr(startIdPos
, curPos
-startIdPos
);
2161 if(!isDefineExist(defineId
))
2166 // Add the define value to the string
2167 newPropVal
+= getDefine(defineId
);
2169 // valid pos is current pos
2174 newPropVal
+= propVal
.substr(lastPos
, propVal
.size()-lastPos
);
2179 // ***************************************************************************
2180 bool CInterfaceParser::solveDefine(xmlNodePtr cur
)
2184 //get the node properties
2185 xmlAttrPtr props
= cur
->properties
;
2188 //get the property value
2189 ptr
= (char*)xmlGetProp( cur
, props
->name
);
2191 string propVal
= ptr
.str();
2194 // solve define of this prop
2196 if(!solveDefine(propVal
, newPropVal
, defError
))
2198 // todo hulud interface syntax error
2199 nlinfo("can't find define: %s", defError
.c_str());
2204 xmlSetProp(cur
, props
->name
, (const xmlChar
*)newPropVal
.c_str());
2207 props
= props
->next
;
2210 // recurs to node children
2214 if(!solveDefine(cur
))
2222 // ***************************************************************************
2223 bool CInterfaceParser::parseSheetSelection(xmlNodePtr cur
)
2226 prop
= (char*) xmlGetProp( cur
, (xmlChar
*)"name" );
2229 // todo hulud interface syntax error
2230 nlwarning("<CInterfaceParser::parseSheetSelection> can't get name of a selection");
2233 std::string groupName
= (const char *) prop
;
2234 prop
= (char*) xmlGetProp( cur
, (xmlChar
*)"texture" );
2237 // todo hulud interface syntax error
2238 nlwarning("<CInterfaceParser::parseSheetSelection> can't get texture name for selection %s", groupName
.c_str());
2241 std::string texName
= (const char *) prop
;
2242 prop
= (char*) xmlGetProp( cur
, (xmlChar
*)"color" );
2243 CRGBA color
= CRGBA::White
;
2246 color
= CInterfaceElement::convertColor(prop
);
2248 bool globalColor
= true;
2249 prop
= (char*) xmlGetProp( cur
, (xmlChar
*)"global_color" );
2250 if (prop
) globalColor
= CInterfaceElement::convertBool(prop
);
2251 sint groupIndex
= _CtrlSheetSelection
.addGroup(groupName
);
2252 if (groupIndex
!= -1)
2254 CSheetSelectionGroup
*csg
= _CtrlSheetSelection
.getGroup(groupIndex
);
2255 csg
->setTexture(texName
);
2256 csg
->setColor(color
);
2257 csg
->enableGlobalColor(globalColor
);
2262 // ***************************************************************************
2263 bool CInterfaceParser::addLink(CInterfaceLink
*link
, const std::string
&id
)
2267 // todo hulud interface syntax error
2268 nlwarning("link empty");
2271 TLinkMap::const_iterator it
= _LinkMap
.find(id
);
2272 if (it
!= _LinkMap
.end())
2274 // todo hulud interface syntax error
2275 nlwarning("<CInterfaceParser::addLink> link %s added twice", id
.c_str());
2279 link
->LinkName
= id
;
2281 _LinkMap
[id
] = link
;
2285 // ***************************************************************************
2286 bool CInterfaceParser::removeLink(const std::string
&id
)
2288 TLinkMap::iterator it
= _LinkMap
.find(id
);
2289 if (it
== _LinkMap
.end())
2291 // todo hulud interface syntax error
2292 nlwarning("<CInterfaceParser::removeLink> unknown link %s", id
.c_str());
2295 CSmartPtr
<CInterfaceLink
> &link
= it
->second
; // dont need to copy a smart ptr on link since still in map
2296 for (uint k
= 0; k
< link
->getNumTargets(); ++k
)
2298 link
->getTarget(k
)->removeLink(link
); // remove the link from the list & delete it
2300 it
->second
->uninit();
2301 _LinkMap
.erase(it
); // NB : the link is holded by a smart ptr, to do this decrease the ref count
2306 // ***************************************************************************
2307 xmlNodePtr
CInterfaceParser::searchTreeNodeInHierarchy(xmlNodePtr root
, const char *node
)
2310 CXMLAutoPtr
prop((const char*) xmlGetProp( root
, (xmlChar
*)"node" ));
2311 // not a valide tree node? abort.
2312 if (!prop
) return NULL
;
2314 if ( !strcmp((const char*)prop
, node
) )
2317 // No, try with sons.
2318 xmlNodePtr cur
= root
->children
;
2321 xmlNodePtr candidate
= searchTreeNodeInHierarchy(cur
, node
);
2322 // if found in this branch.
2334 //==================================================================
2335 bool CInterfaceParser::parseAnim(xmlNodePtr cur
, CInterfaceGroup
* parentGroup
)
2337 CInterfaceAnim
*pAnim
;
2341 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"id" );
2344 // todo hulud interface syntax error
2345 nlinfo ("anim has no id");
2348 string animId
= ptr
.str();
2349 pAnim
= new CInterfaceAnim
;
2351 if (pAnim
->parse (cur
, parentGroup
))
2353 if (_AnimMap
.count(animId
))
2355 nlwarning("Anim %s already exists, replacing with new one", animId
.c_str());
2357 _AnimMap
[animId
] = pAnim
;
2367 //==================================================================
2368 void CInterfaceParser::freeXMLNodeAndSibblings(xmlNodePtr node
)
2373 xmlNodePtr currNode
= node
;
2375 xmlFreeNode(currNode
);
2380 // ***************************************************************************
2381 CInterfaceGroup
*CInterfaceParser::createGroupInstance(const std::string
&templateName
, const std::string
&parentID
, const std::pair
<std::string
,std::string
> *templateParams
, uint numParams
, bool updateLinks
/* = true */)
2383 // create basic xml node that contains infos for the template
2384 xmlNodePtr instance
= xmlNewNode(NULL
, (const xmlChar
*) "instance");
2387 // todo hulud interface syntax error
2388 nlwarning("<CInterfaceParser::createGroupInstance> Can't create xml node ");
2391 for(uint k
= 0; k
< numParams
; ++k
)
2393 xmlSetProp(instance
, (const xmlChar
*) templateParams
[k
].first
.c_str(), (const xmlChar
*) templateParams
[k
].second
.c_str());
2395 xmlSetProp(instance
, (const xmlChar
*) "template", (const xmlChar
*) templateName
.c_str());
2396 if (!parseInstance(instance
))
2398 // todo hulud interface syntax error
2399 nlwarning("<CInterfaceParser::createGroupInstance> cannot create instance from template %s", templateName
.c_str());
2400 freeXMLNodeAndSibblings(instance
);
2404 // result should contain a group
2405 xmlNodePtr currNode
= instance
->next
;
2408 if (strcmp((const char *) currNode
->name
, "group") == 0 && currNode
->type
== XML_ELEMENT_NODE
)
2410 // TODO nico : build a struct from that mess
2411 std::map
<CInterfaceElement
*,std::string
> localParentPositionsMap
;
2412 std::map
<CInterfaceElement
*,std::string
> localParentSizesMap
;
2413 std::map
<CInterfaceElement
*,std::string
> localParentSizesMaxMap
;
2414 std::map
<CInterfaceGroup
*,std::string
> localLuaClassAssociation
;
2416 localParentPositionsMap
.swap(_ParentPositionsMap
);
2417 localParentSizesMap
.swap(_ParentSizesMap
);
2418 localParentSizesMaxMap
.swap(_ParentSizesMaxMap
);
2419 localLuaClassAssociation
.swap(_LuaClassAssociation
);
2421 CViewBase::TCtorParam params
;
2422 CInterfaceGroup
dummyGroup(params
);
2423 dummyGroup
.setId(parentID
);
2424 if (!parseGroup(currNode
, &dummyGroup
, false))
2426 localParentPositionsMap
.swap(_ParentPositionsMap
);
2427 localParentSizesMap
.swap(_ParentSizesMap
);
2428 localParentSizesMaxMap
.swap(_ParentSizesMaxMap
);
2429 localLuaClassAssociation
.swap(_LuaClassAssociation
);
2430 freeXMLNodeAndSibblings(instance
);
2433 freeXMLNodeAndSibblings(instance
);
2434 CInterfaceGroup
*group
= dummyGroup
.getGroup((uint
) 0);
2435 dummyGroup
.delGroup(group
, true);
2436 group
->setParent(NULL
);
2437 group
->setParentPos(NULL
);
2438 initCoordsAndLuaScript();
2439 localParentPositionsMap
.swap(_ParentPositionsMap
);
2440 localParentSizesMap
.swap(_ParentSizesMap
);
2441 localParentSizesMaxMap
.swap(_ParentSizesMaxMap
);
2442 localLuaClassAssociation
.swap(_LuaClassAssociation
);
2443 if ((group
!= NULL
) && updateLinks
)
2445 group
->updateAllLinks();
2447 CGroupContainer
*pGC
= dynamic_cast<CGroupContainer
*>(group
);
2452 currNode
= currNode
->next
;
2454 // todo hulud interface syntax error
2455 CXMLAutoPtr
ptr(xmlGetProp(instance
, (const xmlChar
*) templateName
.c_str()));
2456 nlwarning("<CInterfaceParser::createGroupInstance> no group found in template %s", (const char*)ptr
);
2457 freeXMLNodeAndSibblings(instance
);
2461 // ***************************************************************************
2462 CInterfaceElement
*CInterfaceParser::createUIElement(const std::string
&templateName
, const std::string
&parentID
, const std::pair
<std::string
,std::string
> *templateParams
, uint numParams
, bool updateLinks
/* = true */)
2464 std::string elementId
;
2466 // create basic xml node that contains infos for the template
2467 xmlNodePtr instance
= xmlNewNode(NULL
, (const xmlChar
*) "instance");
2470 // todo hulud interface syntax error
2471 nlwarning("<CInterfaceParser::addUIElement> Can't create xml node ");
2474 for(uint k
= 0; k
< numParams
; ++k
)
2476 xmlSetProp(instance
, (const xmlChar
*) templateParams
[k
].first
.c_str(), (const xmlChar
*) templateParams
[k
].second
.c_str());
2477 if (!strcmp(templateParams
[k
].first
.c_str(), "id"))
2479 elementId
= templateParams
[k
].second
;
2482 xmlSetProp(instance
, (const xmlChar
*) "template", (const xmlChar
*) templateName
.c_str());
2483 if (!parseInstance(instance
))
2485 // todo hulud interface syntax error
2486 nlwarning("<CInterfaceParser::addUIElement> cannot create instance from template %s", templateName
.c_str());
2487 freeXMLNodeAndSibblings(instance
);
2491 CInterfaceElement
*pIE
= CWidgetManager::getInstance()->getElementFromId(parentID
);
2492 CInterfaceGroup
* parentGroup
= dynamic_cast<CInterfaceGroup
*>(pIE
);
2496 nlwarning("<CInterfaceParser::addUIElement> no parent group %s found ", parentID
.c_str());
2497 freeXMLNodeAndSibblings(instance
);
2501 // result should contain a group
2502 xmlNodePtr currNode
= instance
->next
;
2503 CInterfaceElement
* newElement
= NULL
;
2506 if (strcmp((const char *) currNode
->name
, "group") == 0 && currNode
->type
== XML_ELEMENT_NODE
)
2508 if (!parseGroup(currNode
, parentGroup
, false))
2510 freeXMLNodeAndSibblings(instance
);
2513 freeXMLNodeAndSibblings(instance
);
2514 newElement
= parentGroup
->getGroup(elementId
);
2515 parentGroup
->delGroup((CInterfaceGroup
*)newElement
, true);
2517 else if (strcmp((const char *) currNode
->name
, "ctrl") == 0 && currNode
->type
== XML_ELEMENT_NODE
)
2519 if (!parseControl(currNode
, parentGroup
, false))
2521 freeXMLNodeAndSibblings(instance
);
2524 freeXMLNodeAndSibblings(instance
);
2525 newElement
= parentGroup
->getCtrl(elementId
);
2526 parentGroup
->delCtrl((CCtrlBase
*)newElement
, true);
2529 if(newElement
!= NULL
)
2531 initCoordsAndLuaScript();
2534 newElement
->updateAllLinks();
2539 currNode
= currNode
->next
;
2541 // todo hulud interface syntax error
2542 CXMLAutoPtr
ptr(xmlGetProp(instance
, (const xmlChar
*) templateName
.c_str()));
2543 nlwarning("<CInterfaceParser::addUIElement> no group found in template %s", (const char *)ptr
);
2544 freeXMLNodeAndSibblings(instance
);
2548 // ***************************************************************************
2549 void CInterfaceParser::removeAllLinks()
2556 // ***************************************************************************
2557 void CInterfaceParser::removeAllProcedures()
2559 _ProcedureMap
.clear();
2562 // ***************************************************************************
2563 void CInterfaceParser::removeAllDefines()
2568 // ***************************************************************************
2569 void CInterfaceParser::removeAllTemplates()
2571 for (uint i
= 0; i
< _Templates
.size(); ++i
)
2572 xmlFreeNode(_Templates
[i
]);
2576 // ***************************************************************************
2577 void CInterfaceParser::removeAllAnims()
2579 TAnimMap::iterator it
= _AnimMap
.begin();
2580 while (it
!= _AnimMap
.end())
2582 CInterfaceAnim
*pAnim
= it
->second
;
2589 // ***************************************************************************
2592 // ***************************************************************************
2593 void CInterfaceParser::removeAll()
2596 CWidgetManager::getInstance()->removeAllOptions();
2597 removeAllProcedures();
2599 removeAllTemplates();
2601 CWidgetManager::getInstance()->removeAllMasterGroups();
2603 _CtrlSheetSelection
.deleteGroups();
2604 NLMISC::contReset (_ParentPositionsMap
);
2605 NLMISC::contReset (_ParentSizesMap
);
2606 NLMISC::contReset (_ParentSizesMaxMap
);
2607 NLMISC::contReset (_LuaClassAssociation
);
2608 variableCache
.clear();
2609 pointerSettings
.clear();
2613 // ------------------------------------------------------------------------------------------------
2614 uint
CInterfaceParser::getProcedureNumActions(const std::string
&procName
) const
2616 CstItProcedureMap it
= _ProcedureMap
.find(procName
);
2617 if(it
!=_ProcedureMap
.end())
2619 const CProcedure
&proc
= it
->second
;
2620 return (uint
)proc
.Actions
.size();
2626 // ------------------------------------------------------------------------------------------------
2627 bool CInterfaceParser::getProcedureAction(const std::string
&procName
, uint actionIndex
, std::string
&ah
, std::string
¶ms
) const
2629 CstItProcedureMap it
= _ProcedureMap
.find(procName
);
2630 if(it
!=_ProcedureMap
.end())
2632 const CProcedure
&proc
= it
->second
;
2633 if(actionIndex
<proc
.Actions
.size())
2635 const CProcAction
&action
= proc
.Actions
[actionIndex
];
2636 // if not a variable parametrized Params
2637 if(action
.ParamBlocks
.size()==1 && action
.ParamBlocks
[0].NumParam
==-1)
2640 params
= action
.ParamBlocks
[0].String
;
2649 CInterfaceAnim
* CInterfaceParser::getAnim( const std::string
&name
) const
2651 TAnimMap::const_iterator it
= _AnimMap
.find( name
);
2652 if( it
== _AnimMap
.end() )
2654 nlwarning( "anim %s not found", name
.c_str() );
2661 CProcedure
* CInterfaceParser::getProc( const std::string
&name
)
2663 TProcedureMap::iterator itr
= _ProcedureMap
.find( name
);
2664 if( itr
== _ProcedureMap
.end() )
2667 return &itr
->second
;
2670 // ***************************************************************************
2671 bool CInterfaceParser::parseStyle(xmlNodePtr cur
)
2676 prop
= xmlGetProp (cur
, (xmlChar
*)"style");
2678 styleId
= (const char*)prop
;
2681 // todo hulud interface syntax error
2682 nlwarning("'style' not found in 'style'");
2686 // create or replace style
2689 //get the node properties
2690 xmlAttrPtr props
= cur
->properties
;
2693 // if not the "style" property
2694 if( nlstricmp((const char*)props
->name
, "style") != 0 )
2697 newStyle
.Properties
.push_back(CStyleProperty());
2698 newStyle
.Properties
.back().Name
= (const char*)props
->name
;
2700 CXMLAutoPtr
ptr(xmlGetProp( cur
, props
->name
));
2701 newStyle
.Properties
.back().Value
= (const char*)ptr
;
2708 _StyleMap
[styleId
]= newStyle
;
2713 // ***************************************************************************
2714 bool CInterfaceParser::parseLUAScript (xmlNodePtr cur
)
2719 prop
= xmlGetProp (cur
, (xmlChar
*)"file");
2721 fileName
= (const char*)prop
;
2724 nlwarning("'file' not found in 'lua'");
2728 // Append to set of reloadable FileScripts
2729 _LuaFileScripts
.insert(fileName
);
2731 // just display warning here.
2733 return loadLUA(fileName
, dummyError
);
2736 // ***************************************************************************
2737 bool CInterfaceParser::solveStyle(xmlNodePtr cur
)
2741 // if the node is a style, abort (not recrusive because use "style" as param name)
2742 if ( !strcmp((char*)cur
->name
,"style") )
2745 // try to read a "style" param.
2746 ptr
= (char*)xmlGetProp( cur
, (xmlChar
*)"style");
2750 TStyleMap::iterator it
= _StyleMap
.find((const char*)ptr
);
2751 if( it
==_StyleMap
.end() )
2753 // todo hulud interface syntax error
2754 nlwarning("style '%s' not found", (const char*)ptr
);
2759 CStyle
&style
= it
->second
;
2761 // for all properties of the style, set them in the node
2762 for(uint i
=0;i
<style
.Properties
.size();i
++)
2764 const char *propName
= style
.Properties
[i
].Name
.c_str();
2765 const char *propValue
= style
.Properties
[i
].Value
.c_str();
2767 // replace it only if the property is not already defined, (=> user can overide style properties)
2768 CXMLAutoPtr
ptr2(xmlGetProp( cur
, (xmlChar
*)propName
));
2771 xmlSetProp(cur
, (xmlChar
*)propName
, (xmlChar
*)propValue
);
2776 // recurs to node children
2780 if(!solveStyle(cur
))
2788 // ***************************************************************************
2790 #ifdef LUA_NEVRAX_VERSION
2792 class CLuaDebugBreakScreen
: public IDebuggedAppMainLoop
2795 // called by external lua debugger when application is breaked
2796 virtual void breakEventLoop()
2798 Driver
->clearBuffers(CRGBA(90, 90, 90));
2799 TextContext
->setShaded(true);
2800 TextContext
->setFontSize(40);
2801 TextContext
->setColor(CRGBA::White
);
2805 TextContext
->setHotSpot(NL3D::UTextContext::MiddleMiddle
);
2806 TextContext
->printfAt(0.5f
, 0.5f
, "Break in LUA code");
2807 Driver
->swapBuffers();
2810 static CLuaDebugBreakScreen LuaDebugBreakScreen
;
2815 // ***************************************************************************
2816 void CInterfaceParser::initLUA()
2818 CLuaManager::enableLuaDebugging();
2820 #ifdef LUA_NEVRAX_VERSION
2821 extern ILuaIDEInterface
*LuaDebuggerIDE
;
2822 if (LuaDebuggerIDE
) LuaDebuggerIDE
->setDebuggedAppMainLoop(&LuaDebugBreakScreen
);
2825 // register LUA methods
2826 CLuaIHM::registerAll( *( CLuaManager::getInstance().getLuaState() ) );
2827 luaInitialized
= true;
2830 // ***************************************************************************
2831 void CInterfaceParser::uninitLUA()
2833 _LuaFileScripts
.clear();
2834 CLuaManager::getInstance().ResetLuaState();
2835 luaInitialized
= false;
2838 // ***************************************************************************
2839 bool CInterfaceParser::loadLUA(const std::string
&fileName
, std::string
&error
)
2843 bool needCheck
= false;
2849 string pathName
= CPath::lookup(fileName
, false);
2850 if(pathName
.empty())
2852 nlwarning("LUA Script '%s' not found", fileName
.c_str());
2856 bool isInData
= false;
2857 std::string::size_type pos
= pathName
.find("@");
2858 if (pos
!= string::npos
)
2860 if (CBigFile::getInstance().getBigFileName(pathName
.substr(0, pos
)) != "data/"+pathName
.substr(0, pos
))
2866 if (needCheck
&& !isInData
)
2868 nlwarning("You are not allowed to modify the lua files");
2869 // return true so it'll not generate a message box, we just ignore the file
2876 CLuaManager::getInstance().getLuaState()->executeFile(pathName
);
2878 catch(const ELuaError
&e
)
2880 nlwarning(e
.luaWhat().c_str());
2888 void CInterfaceParser::reloadAllLuaFileScripts()
2890 std::set
< std::string
>::const_iterator it
;
2891 for( it
= _LuaFileScripts
.begin(); it
!= _LuaFileScripts
.end(); ++it
)
2894 // if fail to reload a script, display the error code
2895 if( !loadLUA( *it
, error
) )
2897 nlwarning( LuaHelperStuff::formatLuaErrorSysInfo( error
).c_str() );
2902 bool CInterfaceParser::hasProc( const std::string
&name
) const
2904 TProcedureMap::const_iterator itr
2905 = _ProcedureMap
.find( name
);
2906 if( itr
!= _ProcedureMap
.end() )
2912 bool CInterfaceParser::addProc( const std::string
&name
)
2914 if( hasProc( name
) )
2917 _ProcedureMap
[ name
] = CProcedure();
2922 bool CInterfaceParser::removeProc( const std::string
&name
)
2924 TProcedureMap::iterator itr
=
2925 _ProcedureMap
.find( name
);
2926 if( itr
== _ProcedureMap
.end() )
2929 _ProcedureMap
.erase( itr
);
2933 uint32
CInterfaceParser::addLinkData( SLinkData
&linkData
)
2935 linkData
.id
= ++linkId
;
2936 links
[ linkData
.id
] = linkData
;
2940 void CInterfaceParser::removeLinkData( uint32 id
)
2942 std::map
< uint32
, SLinkData
>::iterator itr
=
2944 if( itr
== links
.end() )
2950 bool CInterfaceParser::getLinkData( uint32 id
, SLinkData
&linkData
)
2952 std::map
< uint32
, SLinkData
>::iterator itr
=
2954 if( itr
== links
.end() )
2957 linkData
= itr
->second
;
2962 void CInterfaceParser::updateLinkData( uint32 id
, const SLinkData
&linkData
)
2964 std::map
< uint32
, SLinkData
>::iterator itr
=
2966 if( itr
== links
.end() )
2968 itr
->second
= linkData
;
2971 void CInterfaceParser::setVariable( const VariableData
&v
)
2973 CInterfaceProperty prop
;
2974 const std::string
&type
= v
.type
;
2975 const std::string
&value
= v
.value
;
2976 const std::string
&entry
= v
.entry
;
2978 if( type
== "sint64" )
2979 prop
.readSInt64( value
.c_str(), entry
);
2981 if( type
== "sint32" )
2982 prop
.readSInt32( value
.c_str(), entry
);
2984 if( type
== "float" || type
== "double" )
2985 prop
.readDouble( value
.c_str(), entry
);
2987 if( type
== "bool" )
2988 prop
.readBool( value
.c_str(), entry
);
2990 if( type
== "rgba" )
2991 prop
.readRGBA( value
.c_str(), entry
);
2993 if( type
== "hotspot" )
2994 prop
.readHotSpot( value
.c_str(), entry
);
2996 variableCache
[ entry
] = v
;
3000 bool CInterfaceParser::serializeVariables( xmlNodePtr parentNode
) const
3002 if( parentNode
== NULL
)
3005 xmlNodePtr node
= NULL
;
3007 std::map
< std::string
, VariableData
>::const_iterator itr
;
3008 for( itr
= variableCache
.begin(); itr
!= variableCache
.end(); ++itr
)
3010 const VariableData
&data
= itr
->second
;
3012 node
= xmlNewNode( NULL
, BAD_CAST
"variable" );
3016 xmlAddChild( parentNode
, node
);
3018 xmlSetProp( node
, BAD_CAST
"entry", BAD_CAST data
.entry
.c_str() );
3019 xmlSetProp( node
, BAD_CAST
"type", BAD_CAST data
.type
.c_str() );
3021 if( !data
.value
.empty() )
3022 xmlSetProp( node
, BAD_CAST
"value", BAD_CAST data
.value
.c_str() );
3024 if( data
.size
!= 0 )
3025 xmlSetProp( node
, BAD_CAST
"size", BAD_CAST
toString( data
.size
).c_str() );
3033 bool CInterfaceParser::serializeProcs( xmlNodePtr parentNode
) const
3035 if( parentNode
== NULL
)
3038 xmlNodePtr procNode
= NULL
;
3039 xmlNodePtr actionNode
= NULL
;
3041 TProcedureMap::const_iterator itr
;
3042 for( itr
= _ProcedureMap
.begin(); itr
!= _ProcedureMap
.end(); ++itr
)
3044 procNode
= xmlNewNode( NULL
, BAD_CAST
"proc" );
3045 if( procNode
== NULL
)
3048 xmlAddChild( parentNode
, procNode
);
3050 const CProcedure
&proc
= itr
->second
;
3052 xmlSetProp( procNode
, BAD_CAST
"id", BAD_CAST itr
->first
.c_str() );
3054 std::vector
< CProcAction
>::const_iterator itr2
;
3055 for( itr2
= proc
.Actions
.begin(); itr2
!= proc
.Actions
.end(); ++itr2
)
3057 actionNode
= xmlNewNode( NULL
, BAD_CAST
"action" );
3058 if( actionNode
== NULL
)
3061 xmlAddChild( procNode
, actionNode
);
3063 const CProcAction
&action
= *itr2
;
3065 xmlSetProp( actionNode
, BAD_CAST
"handler", BAD_CAST action
.Action
.c_str() );
3067 if( !action
.Parameters
.empty() )
3068 xmlSetProp( actionNode
, BAD_CAST
"params", BAD_CAST action
.Parameters
.c_str() );
3070 if( !action
.Conditions
.empty() )
3071 xmlSetProp( actionNode
, BAD_CAST
"cond", BAD_CAST action
.Conditions
.c_str() );
3080 bool CInterfaceParser::serializePointerSettings( xmlNodePtr parentNode
) const
3082 if( parentNode
== NULL
)
3085 xmlNodePtr node
= xmlNewNode( NULL
, BAD_CAST
"view" );
3089 xmlAddChild( parentNode
, node
);
3091 std::map
< std::string
, std::string
>::const_iterator itr
;
3092 for( itr
= pointerSettings
.begin(); itr
!= pointerSettings
.end(); ++itr
)
3094 const std::string
&key
= itr
->first
;
3095 const std::string
&value
= itr
->second
;
3097 xmlSetProp( node
, BAD_CAST key
.c_str(), BAD_CAST value
.c_str() );
3104 bool CInterfaceParser::serializeKeySettings( xmlNodePtr parentNode
) const
3106 if( parentNode
== NULL
)
3109 std::map
< std::string
, std::map
< std::string
, std::string
> >::const_iterator itr
;
3110 for( itr
= keySettings
.begin(); itr
!= keySettings
.end(); ++itr
)
3112 xmlNodePtr node
= xmlNewNode( NULL
, BAD_CAST
"key" );
3116 xmlAddChild( parentNode
, node
);
3117 xmlSetProp( node
, BAD_CAST
"name", BAD_CAST itr
->first
.c_str() );
3119 const std::map
< std::string
, std::string
> &settings
= itr
->second
;
3121 std::map
< std::string
, std::string
>::const_iterator itr2
;
3122 for( itr2
= settings
.begin(); itr2
!= settings
.end(); ++itr2
)
3124 const std::string
&key
= itr2
->first
;
3125 const std::string
&value
= itr2
->second
;
3127 xmlSetProp( node
, BAD_CAST key
.c_str(), BAD_CAST value
.c_str() );
3134 CViewBase
* CInterfaceParser::createClass( const std::string
&name
)
3136 return NLMISC_GET_FACTORY( CViewBase
, std::string
).createObject( std::string( name
) , CViewBase::TCtorParam() );