diff options
author | louis <louis.braun@gmx.de> | 2016-01-26 18:32:38 +0100 |
---|---|---|
committer | louis <louis.braun@gmx.de> | 2016-01-26 18:32:38 +0100 |
commit | 809fbda03c5014ba9cd361f5113d1d717cd41ea6 (patch) | |
tree | 264bbc5640375f1bcb165fc7f4a3e595adcc26ca /coreengine/xmlparser.c | |
parent | 196dd7eb9965a405bb16b51dc870fbbb31aeef87 (diff) | |
download | vdr-plugin-skindesigner-809fbda03c5014ba9cd361f5113d1d717cd41ea6.tar.gz vdr-plugin-skindesigner-809fbda03c5014ba9cd361f5113d1d717cd41ea6.tar.bz2 |
Version 0.8.0 beta
Diffstat (limited to 'coreengine/xmlparser.c')
-rw-r--r-- | coreengine/xmlparser.c | 744 |
1 files changed, 744 insertions, 0 deletions
diff --git a/coreengine/xmlparser.c b/coreengine/xmlparser.c new file mode 100644 index 0000000..617313a --- /dev/null +++ b/coreengine/xmlparser.c @@ -0,0 +1,744 @@ +#include "xmlparser.h" +#include "../config.h" +#include "../extensions/helpers.h" + +using namespace std; + +cXmlParser::cXmlParser(void) { + sdOsd = NULL; + view = NULL; + globals = NULL; + skinSetup = NULL; +} + +cXmlParser::~cXmlParser() { +} + +/********************************************************************* +* PUBLIC Functions +*********************************************************************/ +bool cXmlParser::ReadView(cView *view, string xmlFile) { + if (!view) + return false; + this->view = view; + string xmlPath = GetPath(xmlFile); + if (! ReadXMLFile(xmlPath.c_str()) ) + return false; + if (! Validate() ) + return false; + if (! SetDocument() ) + return false; + if (! CheckNodeName( view->GetViewName() )) + return false; + return true; +} + +bool cXmlParser::ParseView(void) { + if (!view) + return false; + vector<stringpair> rootAttribs = ParseAttributes(); + view->SetAttributes(rootAttribs); + + cViewMenu *menuView = dynamic_cast<cViewMenu*>(view); + cViewTracks *tracksView = dynamic_cast<cViewTracks*>(view); + + if (!LevelDown()) + return false; + + do { + if (view->ValidViewElement(NodeName())) { + ParseViewElement(NodeName()); + } else if (menuView) { + if (menuView->ValidSubView(NodeName())) { + ParseSubView(NodeName()); + } else if (view->ValidViewList(NodeName())) { + ParseViewList(); + } else { + esyslog("skindesigner: unknown node %s", NodeName()); + return false; + } + } else if (tracksView) { + if (view->ValidViewList(NodeName())) { + ParseViewList(); + } else { + esyslog("skindesigner: unknown node %s", NodeName()); + return false; + } + } else { + esyslog("skindesigner: unknown view %s", NodeName()); + return false; + } + } while (NextNode()); + + return true; +} + +bool cXmlParser::ParsePluginView(void) { + if (!view) + return false; + vector<stringpair> rootAttribs = ParseAttributes(); + view->SetAttributes(rootAttribs); + + if (!LevelDown()) + return false; + + do { + if (CheckNodeName("viewelement")) { + ParsePluginViewElement(); + } else if (CheckNodeName("grid")) { + ParseGrid(); + } else if (CheckNodeName("tab")) { + ParseViewTabPlugin(); + } else if (CheckNodeName("scrollbar")) { + ParsePluginViewElement(true, false); + } else if (CheckNodeName("tablabels")) { + ParsePluginViewElement(false, true); + } else { + esyslog("skindesigner: unknown node %s in plugin view", NodeName()); + } + } while (NextNode()); + + return true; +} + +bool cXmlParser::ReadPluginView(string templateName) { + string xmlPath = GetPath(templateName); + DeleteDocument(); + if (! ReadXMLFile(xmlPath.c_str()) ) + return false; + if (! Validate() ) + return false; + if (! SetDocument() ) + return false; + return true; +} + +bool cXmlParser::ParsePluginView(string plugName, int plugId, int menuNumber, int menuType) { + if (!view) + return false; + cViewMenu *menuView = dynamic_cast<cViewMenu*>(view); + if (!menuView) { + return false; + } + vector<pair<string, string> > attribs = ParseAttributes(); + + if (!LevelDown()) + return false; + + cSubView *plugView = cViewMenu::CreatePluginview(plugName.c_str(), plugId, menuNumber, menuType); + plugView->SetAttributes(attribs); + menuView->AddPluginview(plugView); + do { + if (plugView->ValidViewElement(NodeName())) { + ParseViewElement(NodeName(), plugView); + } else if (plugView->ValidViewList(NodeName())) { + ParseViewList(plugView); + } else if (CheckNodeName("tab")) { + ParseViewTab(plugView); + } else { + esyslog("skindesigner: error - unknown %s", NodeName()); + return false; + } + } while (NextNode()); + LevelUp(); + return true; +} + +bool cXmlParser::ReadGlobals(cGlobals *globals, string xmlFile) { + this->globals = globals; + string xmlPath = GetPath(xmlFile); + DeleteDocument(); + if (! ReadXMLFile(xmlPath.c_str()) ) + return false; + if (! Validate() ) + return false; + if (! SetDocument() ) + return false; + if (! CheckNodeName("globals") ) + return false; + return true; +} + +bool cXmlParser::ParseGlobals(void) { + if (!LevelDown()) + return false; + do { + if (CheckNodeName("colors")) { + ParseGlobalColors(); + } else if (CheckNodeName("variables")) { + ParseGlobalVariables(); + } else if (CheckNodeName("fonts")) { + ParseGlobalFonts(); + } else if (CheckNodeName("translations")) { + ParseTranslations(); + } + } while (NextNode()); + return true; +} + +bool cXmlParser::ReadSkinSetup(cSkinSetup *skinSetup, string xmlFile) { + this->skinSetup = skinSetup; + if (! ReadXMLFile(xmlFile.c_str()) ) + return false; + if (! Validate() ) + return false; + if (! SetDocument() ) + return false; + if (! CheckNodeName("setup") ) + return false; + return true; +} + +bool cXmlParser::ParseSkinSetup(string skin) { + if (!LevelDown()) + return false; + do { + if (CheckNodeName("menu")) { + ParseSetupMenu(); + } else if (CheckNodeName("translations")) { + ParseTranslations(); + } + } while (NextNode()); + return true; +} +/********************************************************************* +* PRIVATE Functions +*********************************************************************/ +bool cXmlParser::ParseSubView(string name) { + if (!view) + return false; + cViewMenu *menuView = dynamic_cast<cViewMenu*>(view); + if (!menuView) { + return false; + } + vector<pair<string, string> > attribs = ParseAttributes(); + + if (!LevelDown()) + return false; + + cSubView *subView = cViewMenu::CreateSubview(name.c_str()); + subView->SetAttributes(attribs); + menuView->AddSubview(name.c_str(), subView); + + do { + if (subView->ValidViewElement(NodeName())) { + ParseViewElement(NodeName(), subView); + } else if (subView->ValidViewList(NodeName())) { + ParseViewList(subView); + } else if (CheckNodeName("tab")) { + ParseViewTab(subView); + } else { + return false; + } + } while (NextNode()); + LevelUp(); + return true; +} + +void cXmlParser::ParseViewElement(string name, cView *subView) { + if (!view) + return; + const char *viewElementName = NodeName(); + vector<stringpair> attributes = ParseAttributes(); + + if (!LevelDown()) + return; + + //correct detailheader name + if (subView) { + if (!strcmp(subView->GetViewName(), "menudetailedepg") && !name.compare("detailheader")) { + name = "detailheaderepg"; + } else if (!strcmp(subView->GetViewName(), "menudetailedrecording") && !name.compare("detailheader")) { + name = "detailheaderrec"; + } else if (startswith(subView->GetViewName(), "menuplugin") && !name.compare("detailheader")) { + name = "detailheaderplugin"; + } + } + + cViewElement *viewElement = cViewElement::CreateViewElement(name.c_str(), view->GetViewName()); + if (!viewElement) { + LevelUp(); + return; + } + + viewElement->SetOsd(sdOsd); + viewElement->SetAttributes(attributes); + do { + if (!CheckNodeName("areacontainer") && !CheckNodeName("area") && !CheckNodeName("areascroll")) { + esyslog("skindesigner: invalid tag \"%s\" in viewelement", NodeName()); + continue; + } + cAreaNode *area = NULL; + if (CheckNodeName("area") || CheckNodeName("areascroll")) { + area = ParseArea(); + } else { + area = ParseAreaContainer(); + } + viewElement->AddArea(area); + } while (NextNode()); + + LevelUp(); + + if (subView) + subView->AddViewElement(viewElementName, viewElement); + else + view->AddViewElement(viewElementName, viewElement); + +} + +void cXmlParser::ParsePluginViewElement(bool isScrollbar, bool isTabLabels) { + if (!view) + return; + cViewPlugin *pluginView = dynamic_cast<cViewPlugin*>(view); + if (!pluginView) + return; + + vector<stringpair> attributes = ParseAttributes(); + + if (!LevelDown()) + return; + + cViewElement *viewElement = NULL; + if (isScrollbar) { + viewElement = new cVeDmScrollbar(); + } else if (isTabLabels) { + viewElement = new cVeDmTablabels(); + } else { + viewElement = new cVePlugin(); + } + + viewElement->SetOsd(sdOsd); + viewElement->SetAttributes(attributes); + do { + if (!CheckNodeName("areacontainer") && !CheckNodeName("area") && !CheckNodeName("areascroll")) { + esyslog("skindesigner: invalid tag \"%s\" in viewelement", NodeName()); + continue; + } + cAreaNode *area = NULL; + if (CheckNodeName("area") || CheckNodeName("areascroll")) { + area = ParseArea(); + } else { + area = ParseAreaContainer(); + } + viewElement->AddArea(area); + } while (NextNode()); + + LevelUp(); + + if (isScrollbar) { + pluginView->AddScrollbar(dynamic_cast<cVeDmScrollbar*>(viewElement)); + } else if (isTabLabels) { + pluginView->AddTablabels(dynamic_cast<cVeDmTablabels*>(viewElement)); + } else { + pluginView->AddViewElement(dynamic_cast<cVePlugin*>(viewElement)); + } +} + +void cXmlParser::ParseViewList(cView *subView) { + if (!view) + return; + + const char *name = NULL; + if (subView) + name = subView->GetViewName(); + else + name = view->GetViewName(); + + vector<stringpair> attribs = ParseAttributes(); + cViewList *viewList = cViewList::CreateViewList(name); + viewList->SetAttributes(attribs); + + if (!LevelDown()) + return; + + do { + if (CheckNodeName("currentelement")) { + cViewElement *currentElement = cViewList::CreateCurrentElement(name); + currentElement->SetOsd(sdOsd); + vector<stringpair> attribsList = ParseAttributes(); + currentElement->SetAttributes(attribsList); + if (!LevelDown()) + continue; + do { + if (!CheckNodeName("areacontainer") && !CheckNodeName("area") && !CheckNodeName("areascroll")) { + esyslog("skindesigner: invalid tag \"%s\" in viewelement", NodeName()); + continue; + } + cAreaNode *area = NULL; + if (CheckNodeName("area") || CheckNodeName("areascroll")) { + area = ParseArea(); + } else { + area = ParseAreaContainer(); + } + currentElement->AddArea(area); + } while (NextNode()); + LevelUp(); + viewList->AddCurrentElement(currentElement); + } else if (CheckNodeName("listelement")) { + cViewElement *listElement = cViewList::CreateListElement(name); + listElement->SetOsd(sdOsd); + vector<stringpair> attribsList = ParseAttributes(); + listElement->SetAttributes(attribsList); + if (!LevelDown()) + return; + do { + if (!CheckNodeName("areacontainer") && !CheckNodeName("area") && !CheckNodeName("areascroll")) { + esyslog("skindesigner: invalid tag \"%s\" in viewelement", NodeName()); + continue; + } + cAreaNode *area = NULL; + if (CheckNodeName("area") || CheckNodeName("areascroll")) { + area = ParseArea(); + } else { + area = ParseAreaContainer(); + } + listElement->AddArea(area); + } while (NextNode()); + LevelUp(); + viewList->AddListElement(listElement); + } + } while (NextNode()); + LevelUp(); + + if (subView) + subView->AddViewList(viewList); + else + view->AddViewList(viewList); + +} + +void cXmlParser::ParseViewTab(cView *subView) { + if (!view || !subView) + return; + cSubView *menuSubView = dynamic_cast<cSubView*>(subView); + if (!menuSubView) { + return; + } + vector<stringpair> attribs = ParseAttributes(); + cArea *tab = new cArea(); + tab->SetOsd(sdOsd); + tab->SetTab(); + tab->SetAttributes(attribs); + ParseFunctionCalls(tab); + menuSubView->AddTab(tab); +} + +void cXmlParser::ParseViewTabPlugin(void) { + if (!view) + return; + cViewPlugin *plugView = dynamic_cast<cViewPlugin*>(view); + if (!plugView) { + return; + } + vector<stringpair> attribs = ParseAttributes(); + cArea *tab = new cArea(); + tab->SetOsd(sdOsd); + tab->SetTab(); + tab->SetAttributes(attribs); + ParseFunctionCalls(tab); + plugView->AddTab(tab); +} + +void cXmlParser::ParseGrid(void) { + if (!view) + return; + cViewPlugin *pluginView = dynamic_cast<cViewPlugin*>(view); + if (!pluginView) + return; + + vector<stringpair> attributes = ParseAttributes(); + + if (!LevelDown()) + return; + + cViewGrid *viewGrid = new cViewGrid(); + viewGrid->SetAttributes(attributes); + cGridElement *gridElement = new cGridElement(); + gridElement->SetOsd(sdOsd); + + do { + if (!CheckNodeName("areacontainer") && !CheckNodeName("area") && !CheckNodeName("areascroll")) { + esyslog("skindesigner: invalid tag \"%s\" in grid", NodeName()); + continue; + } + cAreaNode *area = NULL; + if (CheckNodeName("area") || CheckNodeName("areascroll")) { + area = ParseArea(); + } else { + area = ParseAreaContainer(); + } + gridElement->AddArea(area); + } while (NextNode()); + LevelUp(); + + viewGrid->AddGridElement(gridElement); + pluginView->AddViewGrid(viewGrid); +} + +cArea *cXmlParser::ParseArea(void) { + vector<stringpair> attribs = ParseAttributes(); + cArea *area = new cArea(); + area->SetOsd(sdOsd); + if (CheckNodeName("areascroll")) { + area->SetScrolling(); + } + area->SetAttributes(attribs); + ParseFunctionCalls(area); + return area; +} + +cAreaContainer *cXmlParser::ParseAreaContainer(void) { + vector<stringpair> attribs = ParseAttributes(); + + cAreaContainer *areaContainer = new cAreaContainer(); + areaContainer->SetAttributes(attribs); + + if (!LevelDown()) + return areaContainer; + do { + if (!CheckNodeName("area") && !CheckNodeName("areascroll")) { + esyslog("skindesigner: invalid tag \"%s\" in areacontainer", NodeName()); + continue; + } + cArea *area = ParseArea(); + areaContainer->AddArea(area); + } while (NextNode()); + LevelUp(); + return areaContainer; +} + +void cXmlParser::ParseFunctionCalls(cArea *area) { + if (!view) + return; + if (!LevelDown()) + return; + do { + if (CheckNodeName("loop")) { + vector<stringpair> attribs = ParseAttributes(); + cFunction *f = area->AddFunction(NodeName(), attribs); + cFuncLoop *loopFunc = dynamic_cast<cFuncLoop*>(f); + if (!loopFunc) + continue; + ParseLoopFunctionCalls(area, loopFunc); + } else if (area->ValidFunction(NodeName())) { + vector<stringpair> attribs = ParseAttributes(); + area->AddFunction(NodeName(), attribs); + } + } while (NextNode()); + LevelUp(); +} + +void cXmlParser::ParseLoopFunctionCalls(cArea *area, cFuncLoop *loopFunc) { + if (!view) + return; + if (!LevelDown()) + return; + do { + if (area->ValidFunction(NodeName())) { + vector<stringpair> attribs = ParseAttributes(); + area->AddFunction(NodeName(), attribs, loopFunc); + } + } while (NextNode()); + LevelUp(); +} + +void cXmlParser::ParseGlobalColors(void) { + if (!LevelDown()) + return; + do { + if (!CheckNodeName("color")) { + continue; + } + string attributeName = "name"; + string colorName = ""; + string colorValue = ""; + bool ok = GetAttribute(attributeName, colorName); + if (ok) { + ok = GetNodeValue(colorValue); + if (ok) + InsertColor(colorName, colorValue); + } + } while (NextNode()); + LevelUp(); +} + +void cXmlParser::InsertColor(string name, string value) { + if (value.size() != 8) + return; + std::stringstream str; + str << value; + tColor colVal; + str >> std::hex >> colVal; + globals->AddColor(name, colVal); +} + +void cXmlParser::ParseGlobalVariables(void) { + if (!LevelDown()) + return; + do { + if (!CheckNodeName("var")) { + continue; + } + string attributeName = "name"; + string attributeType = "type"; + string varName = ""; + string varType = ""; + string varValue = ""; + + bool ok1 = GetAttribute(attributeName, varName); + bool ok2 = GetAttribute(attributeType, varType); + + if (ok1 && ok2) { + bool ok = GetNodeValue(varValue); + if (ok) + InsertVariable(varName, varType, varValue); + } + } while (NextNode()); + LevelUp(); +} + +void cXmlParser::InsertVariable(string name, string type, string value) { + if (!type.compare("int")) { + int val = atoi(value.c_str()); + globals->AddInt(name, val); + } else if (!type.compare("double")) { + globals->AddDouble(name, value); + } else if (!type.compare("string")) { + globals->AddString(name, value); + } +} + +void cXmlParser::ParseGlobalFonts(void) { + if (!LevelDown()) + return; + do { + if (!CheckNodeName("font")) { + continue; + } + string attributeName = "name"; + string fontName = ""; + string fontValue = ""; + + bool ok = GetAttribute(attributeName, fontName); + if (ok) { + ok = GetNodeValue(fontValue); + if (ok) { + globals->AddFont(fontName, fontValue); + } + } + } while (NextNode()); + LevelUp(); +} + +void cXmlParser::ParseTranslations(void) { + if (!LevelDown()) + return; + do { + if (!CheckNodeName("token")) { + continue; + } + string attributeName = "name"; + string tokenName = ""; + + if (!GetAttribute(attributeName, tokenName)) + continue; + + if (!LevelDown()) + continue; + + stringmap tokenTranslations; + do { + if (!CheckNodeName("trans")) { + continue; + } + string attributeName = "lang"; + string language = ""; + if (!GetAttribute(attributeName, language)) + continue; + string translation = ""; + if (!GetNodeValue(translation)) + continue; + tokenTranslations.insert(stringpair(language, translation)); + } while (NextNode()); + LevelUp(); + + if (globals) { + globals->AddTranslation(tokenName, tokenTranslations); + } else if (skinSetup) { + skinSetup->SetTranslation(tokenName, tokenTranslations); + } + + } while (NextNode()); + LevelUp(); +} + +void cXmlParser::ParseSetupMenu(void) { + if (!skinSetup) + return; + if (!LevelDown()) + return; + do { + if (CheckNodeName("parameter")) { + ParseSetupParameter(); + } else if (CheckNodeName("submenu")) { + string attributeName = "name"; + string subMenuName = ""; + string attributeDisplayText = "displaytext"; + string subDisplayText = ""; + GetAttribute(attributeName, subMenuName); + GetAttribute(attributeDisplayText, subDisplayText); + skinSetup->SetSubMenu(subMenuName, subDisplayText); + ParseSetupMenu(); + } + } while (NextNode()); + skinSetup->SubMenuDone(); + LevelUp(); +} + +void cXmlParser::ParseSetupParameter(void) { + if (!skinSetup) + return; + string attributeType = "type"; + string paramType = ""; + string attributeName = "name"; + string paramName = ""; + string attributeDisplayText = "displaytext"; + string paramDisplayText = ""; + string attributeHelpText = "helptext"; + string paramHelpText = ""; + string attributeMin = "min"; + string paramMin = ""; + string attributeMax = "max"; + string paramMax = ""; + string paramValue = ""; + string attributeOptions = "options"; + string paramOptions=""; + + GetAttribute(attributeType, paramType); + GetAttribute(attributeName, paramName); + GetAttribute(attributeDisplayText, paramDisplayText); + GetAttribute(attributeHelpText, paramHelpText); + GetAttribute(attributeMin, paramMin); + GetAttribute(attributeMax, paramMax); + GetAttribute(attributeOptions, paramOptions); + GetNodeValue(paramValue); + + skinSetup->SetParameter(paramType, paramName, paramDisplayText, paramHelpText, paramMin, paramMax, paramValue, paramOptions); +} + +string cXmlParser::GetPath(string xmlFile) { + string activeSkin = Setup.OSDSkin; + string activeTheme = Setup.OSDTheme; + string path = ""; + if (!xmlFile.compare("globals.xml")) { + path = *cString::sprintf("%s%s/%s", *config.GetSkinPath(activeSkin), activeSkin.c_str(), xmlFile.c_str()); + } else if (!xmlFile.compare("theme.xml")) { + path = *cString::sprintf("%s%s/themes/%s/%s", *config.GetSkinPath(activeSkin), activeSkin.c_str(), activeTheme.c_str(), xmlFile.c_str()); + } else if (!xmlFile.compare("setup.xml")) { + path = *cString::sprintf("%s%s/%s", *config.GetSkinPath(activeSkin), activeSkin.c_str(), xmlFile.c_str()); + } else { + path = *cString::sprintf("%s%s/xmlfiles/%s", *config.GetSkinPath(activeSkin), activeSkin.c_str(), xmlFile.c_str()); + } + return path; +} + |