mirror of
				https://projects.vdr-developer.org/git/vdr-plugin-skindesigner.git
				synced 2023-10-19 15:58:31 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			734 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			734 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include "xmlparser.h"
 | |
| #include "../config.h"
 | |
| 
 | |
| using namespace std;
 | |
| 
 | |
| void SkinDesignerXMLErrorHandler (void * userData, xmlErrorPtr error) {
 | |
|     esyslog("skindesigner: Error in XML: %s", error->message);
 | |
| }
 | |
| 
 | |
| cXmlParser::cXmlParser(void) {
 | |
|     doc = NULL;
 | |
|     root = NULL;
 | |
|     ctxt = NULL;
 | |
| 
 | |
|     xmlInitParser();
 | |
|     initGenericErrorDefaultFunc(NULL);
 | |
|     xmlSetStructuredErrorFunc(NULL, SkinDesignerXMLErrorHandler);
 | |
|     ctxt = xmlNewParserCtxt();
 | |
| }
 | |
| 
 | |
| cXmlParser::~cXmlParser() {
 | |
|     DeleteDocument();
 | |
|     xmlFreeParserCtxt(ctxt);
 | |
|     xmlCleanupParser();
 | |
| }
 | |
| 
 | |
| /*********************************************************************
 | |
| * PUBLIC Functions
 | |
| *********************************************************************/
 | |
| bool cXmlParser::ReadView(cTemplateView *view, string xmlFile) {
 | |
|     this->view = view;
 | |
| 
 | |
|     string xmlPath = GetPath(xmlFile);
 | |
|     
 | |
|     if (ctxt == NULL) {
 | |
|         esyslog("skindesigner: Failed to allocate parser context");
 | |
|         return false;
 | |
|     }
 | |
|     
 | |
|     doc = xmlCtxtReadFile(ctxt, xmlPath.c_str(), NULL, XML_PARSE_NOENT | XML_PARSE_DTDVALID);
 | |
|     
 | |
|     if (doc == NULL) {
 | |
|         esyslog("skindesigner: ERROR: TemplateView %s not parsed successfully.", xmlPath.c_str());
 | |
|         return false;
 | |
|     }
 | |
|     if (ctxt->valid == 0) {
 | |
|         esyslog("skindesigner: Failed to validate %s", xmlPath.c_str());
 | |
|         return false;
 | |
|     }
 | |
| 
 | |
|     root = xmlDocGetRootElement(doc);
 | |
| 
 | |
|     if (root == NULL) {
 | |
|         esyslog("skindesigner: ERROR: TemplateView %s is empty", xmlPath.c_str());
 | |
|         return false;
 | |
|     }
 | |
| 
 | |
|     if (xmlStrcmp(root->name, (const xmlChar *) view->GetViewName())) {
 | |
|         return false;
 | |
|     }
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| bool cXmlParser::ReadGlobals(cGlobals *globals, string xmlFile) {
 | |
|     this->globals = globals;
 | |
|     
 | |
|     string xmlPath = GetPath(xmlFile);
 | |
| 
 | |
|     if (ctxt == NULL) {
 | |
|         esyslog("skindesigner: Failed to allocate parser context");
 | |
|         return false;
 | |
|     }
 | |
|     
 | |
|     doc = xmlCtxtReadFile(ctxt, xmlPath.c_str(), NULL, XML_PARSE_NOENT | XML_PARSE_DTDVALID);
 | |
| 
 | |
|     if (doc == NULL ) {
 | |
|         esyslog("skindesigner: ERROR: Globals %s not parsed successfully.", xmlPath.c_str());
 | |
|         return false;
 | |
|     }
 | |
| 
 | |
|     root = xmlDocGetRootElement(doc);
 | |
| 
 | |
|     if (ctxt->valid == 0) {
 | |
|         esyslog("skindesigner: Failed to validate %s", xmlPath.c_str());
 | |
|         return false;
 | |
|     }
 | |
| 
 | |
|     if (root == NULL) {
 | |
|         esyslog("skindesigner: ERROR: Globals %s is empty", xmlPath.c_str());
 | |
|         return false;
 | |
|     }
 | |
| 
 | |
|     if (xmlStrcmp(root->name, (const xmlChar *) "globals")) {
 | |
|         return false;
 | |
|     }
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| bool cXmlParser::ParseView(void) {
 | |
|     vector<pair<string, string> > rootAttribs;
 | |
|     ParseAttributes(root->properties, root, rootAttribs);
 | |
| 
 | |
|     if (!view)
 | |
|         return false;
 | |
| 
 | |
|     view->SetParameters(rootAttribs);
 | |
| 
 | |
|     xmlNodePtr node = root->xmlChildrenNode;
 | |
| 
 | |
|     while (node != NULL) {
 | |
| 
 | |
|         if (node->type != XML_ELEMENT_NODE) {
 | |
|             node = node->next;
 | |
|             continue;
 | |
|         }
 | |
| 
 | |
|         if (view->ValidSubView((const char*)node->name)) {
 | |
|             ParseSubView(node);
 | |
|         } else if (view->ValidViewElement((const char*)node->name)) {
 | |
|             bool debugViewElement = DebugViewElement(node);
 | |
|             ParseViewElement(node->name, node->xmlChildrenNode, debugViewElement);
 | |
|         } else if (view->ValidViewList((const char*)node->name)) {
 | |
|             ParseViewList(node);
 | |
|         } else {
 | |
|             return false;
 | |
|         }
 | |
| 
 | |
|         node = node->next;
 | |
|     }
 | |
| 
 | |
|     return true;
 | |
|     
 | |
| }
 | |
| 
 | |
| bool cXmlParser::ParseGlobals(void) {
 | |
|     xmlNodePtr node = root->xmlChildrenNode;
 | |
|     
 | |
|     while (node != NULL) {
 | |
|         if (node->type != XML_ELEMENT_NODE) {
 | |
|             node = node->next;
 | |
|             continue;
 | |
|         }
 | |
|         if (!xmlStrcmp(node->name, (const xmlChar *) "colors")) {
 | |
|             ParseGlobalColors(node->xmlChildrenNode);
 | |
|             node = node->next;
 | |
|             continue;
 | |
|         } else if (!xmlStrcmp(node->name, (const xmlChar *) "variables")) {
 | |
|             ParseGlobalVariables(node->xmlChildrenNode);
 | |
|             node = node->next;
 | |
|             continue;
 | |
|         } else if (!xmlStrcmp(node->name, (const xmlChar *) "fonts")) {
 | |
|             ParseGlobalFonts(node->xmlChildrenNode);
 | |
|             node = node->next;
 | |
|             continue;
 | |
|         } else if (!xmlStrcmp(node->name, (const xmlChar *) "translations")) {
 | |
|             ParseTranslations(node->xmlChildrenNode);
 | |
|             node = node->next;
 | |
|             continue;
 | |
|         }
 | |
|         node = node->next;
 | |
|     }
 | |
| 
 | |
|     return true;
 | |
| 
 | |
| }
 | |
| 
 | |
| void cXmlParser::DeleteDocument(void) {
 | |
|     if (doc) {
 | |
|         xmlFreeDoc(doc);
 | |
|         doc = NULL;
 | |
|     }
 | |
| }
 | |
| 
 | |
| /*********************************************************************
 | |
| * PRIVATE Functions
 | |
| *********************************************************************/
 | |
| 
 | |
| string cXmlParser::GetPath(string xmlFile) {
 | |
|     string activeSkin = Setup.OSDSkin;
 | |
|     string theme = "default";
 | |
|     if (!activeSkin.compare("skindesigner")) {
 | |
|         theme = Setup.OSDTheme;
 | |
|     }
 | |
|     return *cString::sprintf("%s%s/xmlfiles/%s", *config.skinPath, theme.c_str(), xmlFile.c_str());
 | |
| }
 | |
| 
 | |
| void cXmlParser::ParseGlobalColors(xmlNodePtr node) {
 | |
|     if (!node)
 | |
|         return;
 | |
|     
 | |
|     while (node != NULL) {
 | |
| 
 | |
|         if (node->type != XML_ELEMENT_NODE) {
 | |
|             node = node->next;
 | |
|             continue;
 | |
|         }
 | |
|         if (xmlStrcmp(node->name, (const xmlChar *) "color")) {
 | |
|             node = node->next;
 | |
|             continue;
 | |
|         }
 | |
|         xmlAttrPtr attr = node->properties;
 | |
|         if (attr == NULL) {
 | |
|             node = node->next;
 | |
|             continue;
 | |
|         }
 | |
|         xmlChar *colName = NULL;
 | |
|         xmlChar *colValue = NULL;
 | |
|         bool ok = false;
 | |
|         while (NULL != attr) {
 | |
|             if (xmlStrcmp(attr->name, (const xmlChar *) "name")) {
 | |
|                 attr = attr->next;
 | |
|                 continue;
 | |
|             }
 | |
|             ok = true;
 | |
|             colName = xmlGetProp(node, attr->name);
 | |
|             attr = attr->next;
 | |
|         }
 | |
|         if (ok) {
 | |
|             colValue = xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
 | |
|             if (colName && colValue)
 | |
|                 InsertColor((const char*)colName, (const char*)colValue);
 | |
|         }
 | |
|         if (colName)
 | |
|             xmlFree(colName);
 | |
|         if (colValue)
 | |
|             xmlFree(colValue);
 | |
|         node = node->next;
 | |
|     }
 | |
| }
 | |
| 
 | |
| void cXmlParser::InsertColor(string name, string value) {
 | |
|     if (value.size() != 8)
 | |
|         return;
 | |
|     std::stringstream str;
 | |
|     str << value;
 | |
|     tColor colVal;
 | |
|     str >> std::hex >> colVal;
 | |
|     globals->colors.insert(pair<string, tColor>(name, colVal));
 | |
| }
 | |
| 
 | |
| void cXmlParser::ParseGlobalVariables(xmlNodePtr node) {
 | |
|     if (!node)
 | |
|         return;
 | |
|     
 | |
|     while (node != NULL) {
 | |
| 
 | |
|         if (node->type != XML_ELEMENT_NODE) {
 | |
|             node = node->next;
 | |
|             continue;
 | |
|         }
 | |
|         if (xmlStrcmp(node->name, (const xmlChar *) "var")) {
 | |
|             node = node->next;
 | |
|             continue;
 | |
|         }
 | |
|         xmlAttrPtr attr = node->properties;
 | |
|         if (attr == NULL) {
 | |
|             node = node->next;
 | |
|             continue;
 | |
|         }
 | |
|         xmlChar *varName = NULL;
 | |
|         xmlChar *varType = NULL;
 | |
|         xmlChar *varValue = NULL;
 | |
|         while (NULL != attr) {
 | |
|             if (!xmlStrcmp(attr->name, (const xmlChar *) "name")) {
 | |
|                 varName = xmlGetProp(node, attr->name);
 | |
|             } else if (!xmlStrcmp(attr->name, (const xmlChar *) "type")) {
 | |
|                 varType = xmlGetProp(node, attr->name);
 | |
|             } else {
 | |
|                 attr = attr->next;
 | |
|                 continue;               
 | |
|             }
 | |
|             attr = attr->next;
 | |
|         }
 | |
|         varValue = xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
 | |
|         if (varName && varType && varValue)
 | |
|             InsertVariable((const char*)varName, (const char*)varType, (const char*)varValue);
 | |
|         if (varName)
 | |
|             xmlFree(varName);
 | |
|         if (varType)
 | |
|             xmlFree(varType);
 | |
|         if (varValue)
 | |
|             xmlFree(varValue);
 | |
|         node = node->next;
 | |
|     }
 | |
| }
 | |
| 
 | |
| void cXmlParser::InsertVariable(string name, string type, string value) {
 | |
|     if (!type.compare("int")) {
 | |
|         int val = atoi(value.c_str());
 | |
|         globals->intVars.insert(pair<string, int>(name, val));
 | |
|     } else if (!type.compare("string")) {
 | |
|         globals->stringVars.insert(pair<string, string>(name, value));
 | |
|     }
 | |
| }
 | |
| 
 | |
| void cXmlParser::ParseGlobalFonts(xmlNodePtr node) {
 | |
|     if (!node)
 | |
|         return;
 | |
|     
 | |
|     while (node != NULL) {
 | |
| 
 | |
|         if (node->type != XML_ELEMENT_NODE) {
 | |
|             node = node->next;
 | |
|             continue;
 | |
|         }
 | |
|         if (xmlStrcmp(node->name, (const xmlChar *) "font")) {
 | |
|             node = node->next;
 | |
|             continue;
 | |
|         }
 | |
|         xmlAttrPtr attr = node->properties;
 | |
|         if (attr == NULL) {
 | |
|             node = node->next;
 | |
|             continue;
 | |
|         }
 | |
|         xmlChar *fontName = NULL;
 | |
|         xmlChar *fontValue = NULL;
 | |
|         bool ok = false;
 | |
|         while (NULL != attr) {
 | |
|             if (xmlStrcmp(attr->name, (const xmlChar *) "name")) {
 | |
|                 attr = attr->next;
 | |
|                 continue;
 | |
|             }
 | |
|             ok = true;
 | |
|             fontName = xmlGetProp(node, attr->name);
 | |
|             attr = attr->next;
 | |
|         }
 | |
|         if (ok) {
 | |
|             fontValue = xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
 | |
|             if (fontName && fontValue)
 | |
|                 globals->fonts.insert(pair<string, string>((const char*)fontName, (const char*)fontValue));
 | |
|         }
 | |
|         if (fontName)
 | |
|             xmlFree(fontName);
 | |
|         if (fontValue)
 | |
|             xmlFree(fontValue);
 | |
|         node = node->next;
 | |
|     }
 | |
| }
 | |
| 
 | |
| void cXmlParser::ParseTranslations(xmlNodePtr node) {
 | |
|     if (!node)
 | |
|         return;
 | |
|     
 | |
|     while (node != NULL) {
 | |
| 
 | |
|         if (node->type != XML_ELEMENT_NODE) {
 | |
|             node = node->next;
 | |
|             continue;
 | |
|         }
 | |
|         if (xmlStrcmp(node->name, (const xmlChar *) "token")) {
 | |
|             node = node->next;
 | |
|             continue;
 | |
|         }
 | |
|         xmlAttrPtr attr = node->properties;
 | |
|         if (attr == NULL) {
 | |
|             node = node->next;
 | |
|             continue;
 | |
|         }
 | |
|         xmlChar *tokenName;
 | |
|         bool ok = false;
 | |
|         while (NULL != attr) {
 | |
|             if (xmlStrcmp(attr->name, (const xmlChar *) "name")) {
 | |
|                 attr = attr->next;
 | |
|                 continue;
 | |
|             }
 | |
|             ok = true;
 | |
|             tokenName = xmlGetProp(node, attr->name);
 | |
|             attr = attr->next;
 | |
|         }
 | |
|         if (!ok)
 | |
|             continue;
 | |
|         map < string, string > tokenTranslations;
 | |
|         xmlNodePtr nodeTrans = node->xmlChildrenNode;
 | |
|         while (nodeTrans != NULL) {
 | |
|             if (nodeTrans->type != XML_ELEMENT_NODE) {
 | |
|                 nodeTrans = nodeTrans->next;
 | |
|                 continue;
 | |
|             }
 | |
|             xmlChar *language = NULL;
 | |
|             if (xmlStrcmp(nodeTrans->name, (const xmlChar *) "trans")) {
 | |
|                 nodeTrans = nodeTrans->next;
 | |
|                 continue;
 | |
|             }
 | |
|             xmlAttrPtr attrTrans = nodeTrans->properties;
 | |
|             if (attrTrans == NULL) {
 | |
|                 nodeTrans = nodeTrans->next;
 | |
|                 continue;
 | |
|             }
 | |
|             ok = false;
 | |
|             
 | |
|             while (NULL != attrTrans) {
 | |
|                 if (!ok && xmlStrcmp(attrTrans->name, (const xmlChar *) "lang")) {
 | |
|                     attrTrans = attrTrans->next;
 | |
|                     continue;
 | |
|                 }
 | |
|                 ok = true;
 | |
|                 language = xmlGetProp(nodeTrans, attrTrans->name);
 | |
|                 attrTrans = attrTrans->next;
 | |
|             }
 | |
|             if (!ok)
 | |
|                 continue;
 | |
|             xmlChar *value = NULL;
 | |
|             value = xmlNodeListGetString(doc, nodeTrans->xmlChildrenNode, 1);
 | |
|             if (language && value)
 | |
|                 tokenTranslations.insert(pair<string, string>((const char*)language, (const char*)value));
 | |
|             if (language)
 | |
|                 xmlFree(language);
 | |
|             if (value)
 | |
|                 xmlFree(value);
 | |
|             nodeTrans = nodeTrans->next;
 | |
|         }
 | |
|         globals->translations.insert(pair<string, map < string, string > >((const char*)tokenName, tokenTranslations));
 | |
|         xmlFree(tokenName);
 | |
|         node = node->next;
 | |
|     }
 | |
| }
 | |
| 
 | |
| bool cXmlParser::ParseSubView(xmlNodePtr node) {
 | |
|     if (!node)
 | |
|         return false;
 | |
|     
 | |
|     if (!view)
 | |
|         return false;
 | |
| 
 | |
|     cTemplateView *subView = new cTemplateViewMenu();
 | |
|     view->AddSubView((const char*)node->name, subView);
 | |
| 
 | |
|     vector<pair<string, string> > subViewAttribs;
 | |
|     ParseAttributes(node->properties, node, subViewAttribs);
 | |
| 
 | |
|     subView->SetParameters(subViewAttribs);
 | |
| 
 | |
|     xmlNodePtr childNode = node->xmlChildrenNode;
 | |
| 
 | |
|     while (childNode != NULL) {
 | |
| 
 | |
|         if (childNode->type != XML_ELEMENT_NODE) {
 | |
|             childNode = childNode->next;
 | |
|             continue;
 | |
|         }
 | |
| 
 | |
|         if (subView->ValidViewElement((const char*)childNode->name)) {
 | |
|             bool debugViewElement = DebugViewElement(childNode);
 | |
|             ParseViewElement(childNode->name, childNode->xmlChildrenNode, debugViewElement, subView);
 | |
|         } else if (subView->ValidViewList((const char*)childNode->name)) {
 | |
|             ParseViewList(childNode, subView);
 | |
|         } else if (!xmlStrcmp(childNode->name, (const xmlChar *) "tab")) {
 | |
|             ParseViewTab(childNode, subView);           
 | |
|         } else {
 | |
|             return false;
 | |
|         }
 | |
| 
 | |
|         childNode = childNode->next;
 | |
|     }
 | |
| 
 | |
|     
 | |
| 
 | |
|     return true;
 | |
| 
 | |
| }
 | |
| 
 | |
| void cXmlParser::ParseViewElement(const xmlChar * viewElement, xmlNodePtr node, bool debugVE, cTemplateView *subView) {
 | |
|     if (!node)
 | |
|         return;
 | |
|     
 | |
|     if (!view)
 | |
|         return;
 | |
| 
 | |
|     if (debugVE) {
 | |
|         dsyslog("skindesigner: activating debugging of viewElement %s", (const char*)viewElement);
 | |
|     }
 | |
| 
 | |
|     while (node != NULL) {
 | |
| 
 | |
|         if (node->type != XML_ELEMENT_NODE) {
 | |
|             node = node->next;
 | |
|             continue;
 | |
|         }
 | |
| 
 | |
|         if (xmlStrcmp(node->name, (const xmlChar *) "area") && xmlStrcmp(node->name, (const xmlChar *) "areascroll")) {
 | |
|             esyslog("skindesigner: invalid tag \"%s\"", node->name);
 | |
|             node = node->next;
 | |
|             continue;
 | |
|         }
 | |
| 
 | |
|         xmlAttrPtr attr = node->properties;
 | |
|         vector<pair<string, string> > attribs;
 | |
|         ParseAttributes(attr, node, attribs);
 | |
| 
 | |
|         cTemplatePixmap *pix = new cTemplatePixmap();
 | |
|         if (!xmlStrcmp(node->name, (const xmlChar *) "areascroll")) {
 | |
|             pix->SetScrolling();
 | |
|         }
 | |
|         pix->SetParameters(attribs);
 | |
|         ParseFunctionCalls(node->xmlChildrenNode, pix);
 | |
|         if (subView)
 | |
|             subView->AddPixmap((const char*)viewElement, pix, debugVE);
 | |
|         else
 | |
|             view->AddPixmap((const char*)viewElement, pix, debugVE);
 | |
|         
 | |
|         node = node->next;
 | |
|     }
 | |
| }
 | |
| 
 | |
| void cXmlParser::ParseViewList(xmlNodePtr parentNode, cTemplateView *subView) {
 | |
|     if (!parentNode || !view)
 | |
|         return;
 | |
|     
 | |
|     xmlAttrPtr attr = parentNode->properties;
 | |
|     vector<pair<string, string> > attribs;
 | |
|     ParseAttributes(attr, parentNode, attribs);
 | |
| 
 | |
|     cTemplateViewList *viewList = new cTemplateViewList();
 | |
|     viewList->SetGlobals(globals);
 | |
|     viewList->SetParameters(attribs);
 | |
| 
 | |
|     xmlNodePtr node = parentNode->xmlChildrenNode;
 | |
| 
 | |
|     while (node != NULL) {
 | |
| 
 | |
|         if (node->type != XML_ELEMENT_NODE) {
 | |
|             node = node->next;
 | |
|             continue;
 | |
|         }
 | |
| 
 | |
|         if (!xmlStrcmp(node->name, (const xmlChar *) "currentelement")) {
 | |
|             xmlNodePtr childNode = node->xmlChildrenNode;
 | |
|             if (!childNode)
 | |
|                 continue;
 | |
|             cTemplateViewElement *currentElement = new cTemplateViewElement();
 | |
|             xmlAttrPtr attrCur = node->properties;
 | |
|             vector<pair<string, string> > attribsCur;
 | |
|             ParseAttributes(attrCur, node, attribsCur);
 | |
|             currentElement->SetGlobals(globals);
 | |
|             currentElement->SetParameters(attribsCur);
 | |
|             bool debugCurrent = false;
 | |
|             for (vector<pair<string, string> >::iterator it = attribsCur.begin(); it != attribsCur.end(); it++) {
 | |
|                 if (!(it->first).compare("debug")) {
 | |
|                     debugCurrent = true;
 | |
|                     break;
 | |
|                 }
 | |
|             }
 | |
|             if (debugCurrent)
 | |
|                 currentElement->ActivateDebugTokens();
 | |
|             while (childNode != NULL) {
 | |
|                 if (childNode->type != XML_ELEMENT_NODE) {
 | |
|                     childNode = childNode->next;
 | |
|                     continue;
 | |
|                 }
 | |
|                 if ((!xmlStrcmp(childNode->name, (const xmlChar *) "area")) || (!xmlStrcmp(childNode->name, (const xmlChar *) "areascroll"))) {
 | |
|                     xmlAttrPtr attrPix = childNode->properties;
 | |
|                     vector<pair<string, string> > attribsPix;
 | |
|                     ParseAttributes(attrPix, childNode, attribsPix);
 | |
|                     cTemplatePixmap *pix = new cTemplatePixmap();
 | |
|                     pix->SetParameters(attribsPix);
 | |
|                     ParseFunctionCalls(childNode->xmlChildrenNode, pix);
 | |
|                     if (!xmlStrcmp(childNode->name, (const xmlChar *) "areascroll")) {
 | |
|                         pix->SetScrolling();
 | |
|                     }
 | |
|                     currentElement->AddPixmap(pix);
 | |
|                 }
 | |
|                 childNode = childNode->next;
 | |
|             }
 | |
|             viewList->AddCurrentElement(currentElement);
 | |
|         } else if (!xmlStrcmp(node->name, (const xmlChar *) "listelement")) {
 | |
|             bool debugViewList = DebugViewElement(node);
 | |
|             xmlNodePtr childNode = node->xmlChildrenNode;
 | |
|             if (!childNode)
 | |
|                 continue;
 | |
|             cTemplateViewElement *listElement = new cTemplateViewElement();
 | |
|             if (debugViewList)
 | |
|                 listElement->ActivateDebugTokens();
 | |
|             while (childNode != NULL) {
 | |
|                 if (childNode->type != XML_ELEMENT_NODE) {
 | |
|                     childNode = childNode->next;
 | |
|                     continue;
 | |
|                 }
 | |
|                 if ((!xmlStrcmp(childNode->name, (const xmlChar *) "area")) || (!xmlStrcmp(childNode->name, (const xmlChar *) "areascroll"))) {
 | |
|                     xmlAttrPtr attrPix = childNode->properties;
 | |
|                     vector<pair<string, string> > attribsPix;
 | |
|                     ParseAttributes(attrPix, childNode, attribsPix);
 | |
|                     cTemplatePixmap *pix = new cTemplatePixmap();
 | |
|                     pix->SetParameters(attribsPix);
 | |
|                     ParseFunctionCalls(childNode->xmlChildrenNode, pix);
 | |
|                     if (!xmlStrcmp(childNode->name, (const xmlChar *) "areascroll")) {
 | |
|                         pix->SetScrolling();
 | |
|                     }
 | |
|                     listElement->AddPixmap(pix);
 | |
|                 }
 | |
|                 childNode = childNode->next;
 | |
|             }
 | |
|             viewList->AddListElement(listElement);
 | |
|         } else {
 | |
|             node = node->next;
 | |
|             continue;
 | |
|         }
 | |
|         node = node->next;
 | |
|     }
 | |
|     if (subView)
 | |
|         subView->AddViewList((const char*)parentNode->name, viewList);
 | |
|     else
 | |
|         view->AddViewList((const char*)parentNode->name, viewList);
 | |
| }
 | |
| 
 | |
| void cXmlParser::ParseViewTab(xmlNodePtr parentNode, cTemplateView *subView) {
 | |
|     if (!parentNode || !view || !subView)
 | |
|         return;
 | |
| 
 | |
|     xmlAttrPtr attr = parentNode->properties;
 | |
|     vector<pair<string, string> > attribs;
 | |
|     ParseAttributes(attr, parentNode, attribs);
 | |
| 
 | |
|     cTemplateViewTab *viewTab = new cTemplateViewTab();
 | |
|     viewTab->SetGlobals(globals);
 | |
|     viewTab->SetParameters(attribs);
 | |
|     viewTab->SetScrolling();
 | |
|     xmlNodePtr node = parentNode->xmlChildrenNode;
 | |
|     ParseFunctionCalls(node, viewTab);
 | |
| 
 | |
|     subView->AddViewTab(viewTab);
 | |
| }
 | |
| 
 | |
| void cXmlParser::ParseFunctionCalls(xmlNodePtr node, cTemplatePixmap *pix) {
 | |
|     if (!node)
 | |
|         return;
 | |
| 
 | |
|     if (!view)
 | |
|         return;
 | |
| 
 | |
|     while (node != NULL) {
 | |
| 
 | |
|         if (node->type != XML_ELEMENT_NODE) {
 | |
|             node = node->next;
 | |
|             continue;
 | |
|         }
 | |
| 
 | |
|         if (!xmlStrcmp(node->name, (const xmlChar *) "loop")) {
 | |
|             xmlNodePtr childNode = node->xmlChildrenNode;
 | |
|             if (!childNode)
 | |
|                 continue;
 | |
|             xmlAttrPtr attr = node->properties;
 | |
|             vector<pair<string, string> > attribs;
 | |
|             ParseAttributes(attr, node, attribs);
 | |
|             cTemplateLoopFunction *loopFunc = new cTemplateLoopFunction();
 | |
|             loopFunc->SetParameters(attribs);
 | |
|             ParseLoopFunctionCalls(childNode, loopFunc);
 | |
|             pix->AddLoopFunction(loopFunc);
 | |
|             node = node->next;
 | |
|         } else if (view->ValidFunction((const char*)node->name)) {
 | |
|             xmlAttrPtr attr = node->properties;
 | |
|             vector<pair<string, string> > attribs;
 | |
|             ParseAttributes(attr, node, attribs);
 | |
|             pix->AddFunction((const char*)node->name, attribs);
 | |
|             node = node->next;
 | |
|         } else {
 | |
|             node = node->next;
 | |
|             continue;           
 | |
|         }
 | |
| 
 | |
|     }
 | |
| }
 | |
| 
 | |
| void cXmlParser::ParseLoopFunctionCalls(xmlNodePtr node, cTemplateLoopFunction *loopFunc) {
 | |
|     if (!node)
 | |
|         return;
 | |
| 
 | |
|     if (!view)
 | |
|         return;
 | |
| 
 | |
|     while (node != NULL) {
 | |
| 
 | |
|         if (node->type != XML_ELEMENT_NODE) {
 | |
|             node = node->next;
 | |
|             continue;
 | |
|         }
 | |
|         if (view->ValidFunction((const char*)node->name)) {
 | |
|             xmlAttrPtr attr = node->properties;
 | |
|             vector<pair<string, string> > attribs;
 | |
|             ParseAttributes(attr, node, attribs);
 | |
|             loopFunc->AddFunction((const char*)node->name, attribs);
 | |
|             node = node->next;
 | |
|         } else {
 | |
|             node = node->next;
 | |
|             continue;           
 | |
|         }
 | |
| 
 | |
|     }
 | |
| }
 | |
| 
 | |
| bool cXmlParser::ParseAttributes(xmlAttrPtr attr, xmlNodePtr node, vector<pair<string, string> > &attribs) {
 | |
|     if (attr == NULL) {
 | |
|         return false;
 | |
|     }
 | |
| 
 | |
|     if (!view)
 | |
|         return false;
 | |
| 
 | |
|     while (NULL != attr) {
 | |
| 
 | |
|         string name = (const char*)attr->name;
 | |
|         if (!name.compare("debug")) {
 | |
|             attribs.push_back(pair<string, string>((const char*)attr->name, "true"));
 | |
|             attr = attr->next;
 | |
|             continue;
 | |
|         }
 | |
| 
 | |
|         xmlChar *value = NULL;
 | |
|         value = xmlGetProp(node, attr->name);
 | |
|         if (!view->ValidAttribute((const char*)node->name, (const char*)attr->name)) {
 | |
|             attr = attr->next;
 | |
|             if (value)
 | |
|                 xmlFree(value);
 | |
|             continue;
 | |
|         }
 | |
|         if (value)
 | |
|             attribs.push_back(pair<string, string>((const char*)attr->name, (const char*)value));
 | |
|         attr = attr->next;
 | |
|         if (value)
 | |
|             xmlFree(value);
 | |
|     }
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| bool cXmlParser::DebugViewElement(xmlNodePtr node) {
 | |
|     xmlAttrPtr attr = node->properties;
 | |
|     vector<pair<string, string> > attribs;
 | |
|     ParseAttributes(attr, node, attribs);
 | |
|     for (vector<pair<string, string> >::iterator it = attribs.begin(); it != attribs.end(); it++) {
 | |
|         if (!(it->first).compare("debug"))
 | |
|             return true;
 | |
|     }
 | |
|     return false;
 | |
| }
 |