diff options
author | louis <louis.braun@gmx.de> | 2015-01-31 11:46:06 +0100 |
---|---|---|
committer | louis <louis.braun@gmx.de> | 2015-01-31 11:46:06 +0100 |
commit | 1883ac1691f1e6cbe035819c07bbae72bc7748a9 (patch) | |
tree | ef3ee83a82ee65d96f1640414e940921936cae9c | |
parent | 304f5920045b1d55f093b2a7bb19162de1d2d4db (diff) | |
download | vdr-plugin-skindesigner-1883ac1691f1e6cbe035819c07bbae72bc7748a9.tar.gz vdr-plugin-skindesigner-1883ac1691f1e6cbe035819c07bbae72bc7748a9.tar.bz2 |
added possibiliy to use submenus in the skin setup menus
-rw-r--r-- | HISTORY | 3 | ||||
-rw-r--r-- | config.c | 14 | ||||
-rw-r--r-- | config.h | 5 | ||||
-rw-r--r-- | designer.c | 4 | ||||
-rw-r--r-- | dtd/setup.dtd | 10 | ||||
-rw-r--r-- | libcore/skinsetup.c | 238 | ||||
-rw-r--r-- | libcore/skinsetup.h | 49 | ||||
-rw-r--r-- | libtemplate/xmlparser.c | 127 | ||||
-rw-r--r-- | libtemplate/xmlparser.h | 3 | ||||
-rw-r--r-- | setup.c | 45 | ||||
-rw-r--r-- | setup.h | 14 | ||||
-rw-r--r-- | skins/blackhole/setup.xml | 41 | ||||
-rw-r--r-- | skins/metrixhd/setup.xml | 23 | ||||
-rw-r--r-- | skins/nopacity/setup.xml | 25 | ||||
-rw-r--r-- | skinskeleton/setup.xml | 11 |
15 files changed, 411 insertions, 201 deletions
@@ -193,3 +193,6 @@ Version 0.2.1 - fixed bug that global tokens were not parsed correctly - added finnish translation - some more nopacity optimizations - thanx@utility +- added possibiliy to use submenus in the skin setup menus +- reloading active skin directly after closing setup menu so that + changes of setup parameters are immediately in use @@ -25,6 +25,7 @@ cDesignerConfig::cDesignerConfig() { SetOSDSize(); SetOSDFonts(); osdLanguage = ""; + setupCloseDoReload = false; } cDesignerConfig::~cDesignerConfig() { @@ -88,7 +89,7 @@ void cDesignerConfig::DebugSkinSetups(void) { dsyslog("skindesigner: skin setups:"); InitSetupIterator(); cSkinSetup *skinSetup = NULL; - while (skinSetup = GetSkinSetup()) { + while (skinSetup = GetNextSkinSetup()) { skinSetup->Debug(); } } @@ -125,7 +126,7 @@ cSkinSetup* cDesignerConfig::GetSkinSetup(string &skin) { return NULL; } -cSkinSetup* cDesignerConfig::GetSkinSetup(void) { +cSkinSetup* cDesignerConfig::GetNextSkinSetup(void) { if (setupIt == skinSetups.end()) { return NULL; } @@ -134,6 +135,15 @@ cSkinSetup* cDesignerConfig::GetSkinSetup(void) { return skinSetup; } +cSkinSetupMenu* cDesignerConfig::GetSkinSetupMenu(string &skin, string &menu) { + cSkinSetup *skinSetup = GetSkinSetup(skin); + if (!skinSetup) + return NULL; + esyslog("skindesigner: skinsetup found"); + return skinSetup->GetMenu(menu); +} + + void cDesignerConfig::TranslateSetup(void) { for (map< string, cSkinSetup* >::iterator it = skinSetups.begin(); it != skinSetups.end(); it++) { (it->second)->TranslateSetup(); @@ -49,7 +49,8 @@ public: void DebugSkinSetups(void); void DebugSkinSetupParameters(void); cSkinSetup* GetSkinSetup(string &skin); - cSkinSetup* GetSkinSetup(void); + cSkinSetup* GetNextSkinSetup(void); + cSkinSetupMenu* GetSkinSetupMenu(string &skin, string &menu); void InitSetupIterator(void) { setupIt = skinSetups.begin(); }; void TranslateSetup(void); void SetSkinSetupParameters(void); @@ -85,6 +86,8 @@ public: int rerunDistance; int rerunMaxChannel; int blockFlush; + //TemplateReload on Setup Close + bool setupCloseDoReload; }; #ifdef DEFINE_CONFIG @@ -163,8 +163,8 @@ void cSkinDesigner::ListCustomTokens(void) { * PRIVATE FUNCTIONS *********************************************************************************/ void cSkinDesigner::Init(void) { - if (init || config.OsdSizeChanged() || config.SkinChanged() || config.OsdLanguageChanged()) { - + if (init || config.OsdSizeChanged() || config.SkinChanged() || config.OsdLanguageChanged() || config.setupCloseDoReload) { + config.setupCloseDoReload = false; if (init) { config.SetSkin(); config.SetOSDSize(); diff --git a/dtd/setup.dtd b/dtd/setup.dtd index a0c7c86..d56fc40 100644 --- a/dtd/setup.dtd +++ b/dtd/setup.dtd @@ -1,9 +1,15 @@ <?xml encoding="UTF-8"?>
-<!ELEMENT setup (parameters,translations)>
-<!ELEMENT parameters (parameter)*>
+<!ELEMENT setup (menu,translations)>
+<!ELEMENT menu (submenu | parameter)*>
<!ELEMENT translations (token)*>
+<!ELEMENT submenu (submenu | parameter)*>
+<!ATTLIST submenu
+ name NMTOKEN #REQUIRED
+ displaytext CDATA #REQUIRED
+ >
+
<!ELEMENT parameter (#PCDATA)>
<!ATTLIST parameter
name NMTOKEN #REQUIRED
diff --git a/libcore/skinsetup.c b/libcore/skinsetup.c index d678243..88901c8 100644 --- a/libcore/skinsetup.c +++ b/libcore/skinsetup.c @@ -1,4 +1,5 @@ #include "skinsetup.h" +#include "../config.h" #include "../libtemplate/xmlparser.h" // --- cSkinSetupParameter ----------------------------------------------------------- @@ -23,75 +24,191 @@ void cSkinSetupParameter::Debug(void) { dsyslog("skindesigner: min %d, max %d", min, max); } +// --- cSkinSetupMenu ----------------------------------------------------------- +cSkinSetupMenu::cSkinSetupMenu(void) { + name = ""; + displayText = ""; + parent = NULL; +} + +cSkinSetupMenu::~cSkinSetupMenu(void) { + for (map < string, cSkinSetupParameter* >::iterator p = parameters.begin(); p != parameters.end(); p++) { + delete p->second; + } + for (vector < cSkinSetupMenu* >::iterator s = subMenus.begin(); s != subMenus.end(); s++) { + delete (*s); + } +} + +cSkinSetupParameter *cSkinSetupMenu::GetNextParameter(bool deep) { + cSkinSetupParameter *param = NULL; + if (paramIt != parameters.end()) { + param = paramIt->second; + paramIt++; + return param; + } + if (!deep) + return NULL; + + if (subMenuIt != subMenus.end()) { + param = (*subMenuIt)->GetNextParameter(); + if (!param) { + subMenuIt++; + if (subMenuIt != subMenus.end()) { + (*subMenuIt)->InitIterators(); + param = (*subMenuIt)->GetNextParameter(); + } + } + } + return param; +} + +cSkinSetupParameter *cSkinSetupMenu::GetParameter(string name) { + map < string, cSkinSetupParameter* >::iterator hit = parameters.find(name); + if (hit != parameters.end()) + return hit->second; + + cSkinSetupParameter *paramHit = NULL; + for (vector < cSkinSetupMenu* >::iterator subMenu = subMenus.begin(); subMenu != subMenus.end(); subMenu++) { + paramHit = (*subMenu)->GetParameter(name); + if (paramHit) + return paramHit; + } + return NULL; +} + +void cSkinSetupMenu::InitIterators(void) { + paramIt = parameters.begin(); + subMenuIt = subMenus.begin(); + while (subMenuIt != subMenus.end()) { + (*subMenuIt)->InitIterators(); + subMenuIt++; + } + subMenuIt = subMenus.begin(); +} + +void cSkinSetupMenu::SetParameter(eSetupParameterType paramType, xmlChar *name, xmlChar* displayText, xmlChar *min, xmlChar *max, xmlChar *value) { + cSkinSetupParameter *param = new cSkinSetupParameter(); + param->type = paramType; + param->name = (const char*)name; + param->displayText = (const char*)displayText; + + if (min && paramType == sptInt) { + param->min = atoi((const char*)min); + } + if (max && paramType == sptInt) { + param->max = atoi((const char*)max); + } + param->value = atoi((const char*)value); + + parameters.insert(pair< string, cSkinSetupParameter* >(param->name, param)); +} + +cSkinSetupMenu *cSkinSetupMenu::GetMenu(string &name) { + for (vector<cSkinSetupMenu*>::iterator m = subMenus.begin(); m != subMenus.end(); m++) { + cSkinSetupMenu *menu = (*m); + if (!name.compare(menu->GetName())) + return menu; + menu = menu->GetMenu(name); + if (menu) + return menu; + } + return NULL; +} + +cSkinSetupMenu *cSkinSetupMenu::GetNextSubMenu(bool deep) { + cSkinSetupMenu *menu = NULL; + if (subMenuIt != subMenus.end()) { + if (deep) { + menu = (*subMenuIt)->GetNextSubMenu(deep); + if (menu) + return menu; + } + menu = *subMenuIt; + subMenuIt++; + return menu; + } + return NULL; +} + + +void cSkinSetupMenu::Debug(bool deep) { + dsyslog("skindesigner: Menu %s Setup Parameters", name.c_str()); + for (map < string, cSkinSetupParameter* >::iterator p = parameters.begin(); p != parameters.end(); p++) { + (p->second)->Debug(); + } + if (subMenus.empty()) + return; + for (vector < cSkinSetupMenu* >::iterator s = subMenus.begin(); s != subMenus.end(); s++) { + dsyslog("skindesigner: SubMenu %s, Parent %s", ((*s)->GetName()).c_str(), ((*s)->GetParent()->GetName()).c_str()); + if (deep) + (*s)->Debug(); + } +} // --- cSkinSetup ----------------------------------------------------------- cSkinSetup::cSkinSetup(string skin) { this->skin = skin; + rootMenu = new cSkinSetupMenu(); + rootMenu->SetName("root"); + currentMenu = rootMenu; } cSkinSetup::~cSkinSetup() { - for (map < string, cSkinSetupParameter* >::iterator p = parameters.begin(); p != parameters.end(); p++) { - delete p->second; - } + delete rootMenu; } bool cSkinSetup::ReadFromXML(void) { - string xmlFile = "setup.xml"; + string xmlPath = *cString::sprintf("%s%s/setup.xml", *config.skinPath, skin.c_str()); cXmlParser parser; - if (!parser.ReadSkinSetup(this, skin, xmlFile)) { + if (!parser.ReadSkinSetup(this, xmlPath)) { return false; } parser.ParseSkinSetup(skin); return true; } -void cSkinSetup::SetParameter(xmlChar *type, xmlChar *name, xmlChar* displayText, xmlChar *min, xmlChar *max, xmlChar *value) { - if (!type || !name || !displayText || !value) { - esyslog("skindesigner: invalid setup parameter for skin %s", skin.c_str()); - return; - } - eSetupParameterType paramType = sptUnknown; - if (!xmlStrcmp(type, (const xmlChar *) "int")) { - paramType = sptInt; - } else if (!xmlStrcmp(type, (const xmlChar *) "bool")) { - paramType = sptBool; - } - if (paramType == sptUnknown) { - esyslog("skindesigner: invalid setup parameter for skin %s", skin.c_str()); - return; - } - - cSkinSetupParameter *param = new cSkinSetupParameter(); - param->type = paramType; - param->name = (const char*)name; - param->displayText = (const char*)displayText; - - if (min && paramType == sptInt) { - param->min = atoi((const char*)min); - } - if (max && paramType == sptInt) { - param->max = atoi((const char*)max); - } - param->value = atoi((const char*)value); +void cSkinSetup::SetSubMenu(xmlChar *name, xmlChar *displayText) { + cSkinSetupMenu *subMenu = new cSkinSetupMenu(); + subMenu->SetName((const char*)name); + subMenu->SetDisplayText((const char*)displayText); + subMenu->SetParent(currentMenu); + currentMenu->AddSubMenu(subMenu); + currentMenu = subMenu; +} - parameters.insert(pair< string, cSkinSetupParameter* >(param->name, param)); +void cSkinSetup::SubMenuDone(void) { + cSkinSetupMenu *parent = currentMenu->GetParent(); + if (parent) { + currentMenu = parent; + } } -cSkinSetupParameter *cSkinSetup::GetParameter(void) { - if (paramIt == parameters.end()) - return NULL; - cSkinSetupParameter *param = paramIt->second; - paramIt++; - return param; +void cSkinSetup::SetParameter(xmlChar *type, xmlChar *name, xmlChar* displayText, xmlChar *min, xmlChar *max, xmlChar *value) { + if (!type || !name || !displayText || !value) { + esyslog("skindesigner: invalid setup parameter for skin %s", skin.c_str()); + return; + } + eSetupParameterType paramType = sptUnknown; + if (!xmlStrcmp(type, (const xmlChar *) "int")) { + paramType = sptInt; + } else if (!xmlStrcmp(type, (const xmlChar *) "bool")) { + paramType = sptBool; + } + if (paramType == sptUnknown) { + esyslog("skindesigner: invalid setup parameter for skin %s", skin.c_str()); + return; + } + currentMenu->SetParameter(paramType, name, displayText, min, max, value); } -cSkinSetupParameter *cSkinSetup::GetParameter(string name) { - map < string, cSkinSetupParameter* >::iterator hit = parameters.find(name); - if (hit != parameters.end()) - return hit->second; - return NULL; +cSkinSetupParameter *cSkinSetup::GetNextParameter(void) { + return rootMenu->GetNextParameter(); } +cSkinSetupParameter *cSkinSetup::GetParameter(string name) { + return rootMenu->GetParameter(name); +} void cSkinSetup::SetTranslation(string translationToken, map < string, string > transl) { translations.insert(pair<string, map < string, string > >(translationToken, transl)); @@ -100,21 +217,37 @@ void cSkinSetup::SetTranslation(string translationToken, map < string, string > void cSkinSetup::AddToGlobals(cGlobals *globals) { if (!globals) return; - for (map < string, cSkinSetupParameter* >::iterator p = parameters.begin(); p != parameters.end(); p++) { - cSkinSetupParameter *param = p->second; + rootMenu->InitIterators(); + cSkinSetupParameter *param = NULL; + while (param = rootMenu->GetNextParameter()) { globals->AddInt(param->name, param->value); } } void cSkinSetup::TranslateSetup(void) { - InitParameterIterator(); + rootMenu->InitIterators(); cSkinSetupParameter *param = NULL; - while (param = GetParameter()) { + while (param = rootMenu->GetNextParameter()) { string transl = ""; if (Translate(param->displayText, transl)) { param->displayText = transl; } } + + rootMenu->InitIterators(); + cSkinSetupMenu *subMenu = NULL; + while (subMenu = rootMenu->GetNextSubMenu()) { + string transl = ""; + if (Translate(subMenu->GetDisplayText(), transl)) { + subMenu->SetDisplayText(transl); + } + } +} + +cSkinSetupMenu *cSkinSetup::GetMenu(string &name) { + if (name.size() == 0) + return rootMenu; + return rootMenu->GetMenu(name); } bool cSkinSetup::Translate(string text, string &translation) { @@ -161,11 +294,8 @@ string cSkinSetup::DoTranslate(string token) { } void cSkinSetup::Debug(void) { - dsyslog("skindesigner: Skin \"%s\" Setup Parameters", skin.c_str()); - for (map < string, cSkinSetupParameter* >::iterator p = parameters.begin(); p != parameters.end(); p++) { - (p->second)->Debug(); - } - + rootMenu->Debug(); + return; dsyslog("skindesigner: Skin \"%s\" Setup Parameter Translations", skin.c_str()); for (map<string, map<string,string> >::iterator trans = translations.begin(); trans != translations.end(); trans++) { dsyslog("skindesigner: translation token %s", (trans->first).c_str()); diff --git a/libcore/skinsetup.h b/libcore/skinsetup.h index 4b0082d..6e99799 100644 --- a/libcore/skinsetup.h +++ b/libcore/skinsetup.h @@ -34,28 +34,63 @@ public: void Debug(void); }; +// --- cSkinSetupMenu ----------------------------------------------------------- + +class cSkinSetupMenu { +private: + string name; + string displayText; + cSkinSetupMenu *parent; + vector < cSkinSetupMenu* > subMenus; + vector < cSkinSetupMenu* >::iterator subMenuIt; + map < string, cSkinSetupParameter* > parameters; + map < string, cSkinSetupParameter* >::iterator paramIt; +public: + cSkinSetupMenu(void); + virtual ~cSkinSetupMenu(void); + void SetName(string name) { this->name = name; }; + void SetDisplayText(string displayText) { this->displayText = displayText; }; + string GetName(void) { return name; }; + string GetDisplayText(void) { return displayText; }; + void SetParent(cSkinSetupMenu *p) { parent = p; }; + cSkinSetupMenu *GetParent(void) { return parent; }; + void AddSubMenu(cSkinSetupMenu *sub) { subMenus.push_back(sub); }; + void SetParameter(eSetupParameterType paramType, xmlChar *name, xmlChar* displayText, xmlChar *min, xmlChar *max, xmlChar *value); + void InitIterators(void); + void InitParameterIterator(void) { paramIt = parameters.begin(); }; + cSkinSetupParameter *GetNextParameter(bool deep = true); + cSkinSetupParameter *GetParameter(string name); + void InitSubmenuIterator(void) { subMenuIt = subMenus.begin(); }; + cSkinSetupMenu *GetNextSubMenu(bool deep = true); + cSkinSetupMenu *GetMenu(string &name); + void Debug(bool deep = true); +}; + // --- cSkinSetup ----------------------------------------------------------- class cSkinSetup { private: - string skin; - map < string, cSkinSetupParameter* > parameters; - map < string, cSkinSetupParameter* >::iterator paramIt; - map < string, map< string, string > > translations; + string skin; + cSkinSetupMenu *rootMenu; + cSkinSetupMenu *currentMenu; + map < string, map< string, string > > translations; string DoTranslate(string token); bool Translate(string text, string &translation); public: cSkinSetup(string skin); virtual ~cSkinSetup(void); bool ReadFromXML(void); + void SetSubMenu(xmlChar *name, xmlChar *displayText); + void SubMenuDone(void); void SetParameter(xmlChar *type, xmlChar *name, xmlChar* displayText, xmlChar *min, xmlChar *max, xmlChar *value); + void InitParameterIterator(void) { rootMenu->InitIterators(); }; + cSkinSetupParameter *GetNextParameter(void); + cSkinSetupParameter *GetParameter(string name); void SetTranslation(string translationToken, map < string, string > transl); void AddToGlobals(cGlobals *globals); void TranslateSetup(void); - void InitParameterIterator(void) { paramIt = parameters.begin(); }; - cSkinSetupParameter *GetParameter(void); - cSkinSetupParameter *GetParameter(string name); string GetSkin(void) { return skin; }; + cSkinSetupMenu *GetMenu(string &name); void Debug(void); }; diff --git a/libtemplate/xmlparser.c b/libtemplate/xmlparser.c index 9e095a4..dd5a39b 100644 --- a/libtemplate/xmlparser.c +++ b/libtemplate/xmlparser.c @@ -134,28 +134,27 @@ bool cXmlParser::ReadGlobals(cGlobals *globals, string xmlFile, bool mandatory) return true; } -bool cXmlParser::ReadSkinSetup(cSkinSetup *skinSetup, string skin, string xmlFile) { +bool cXmlParser::ReadSkinSetup(cSkinSetup *skinSetup, string xmlFile) { this->skinSetup = skinSetup; - string xmlPath = *cString::sprintf("%s%s/%s", *config.skinPath, skin.c_str(), xmlFile.c_str()); - if (!FileExists(xmlPath)) + if (!FileExists(xmlFile)) return false; 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); + doc = xmlCtxtReadFile(ctxt, xmlFile.c_str(), NULL, XML_PARSE_NOENT | XML_PARSE_DTDVALID); if (doc == NULL ) { - esyslog("skindesigner: ERROR: skin setup %s not parsed successfully.", xmlPath.c_str()); + esyslog("skindesigner: ERROR: skin setup %s not parsed successfully.", xmlFile.c_str()); return false; } root = xmlDocGetRootElement(doc); if (ctxt->valid == 0) { - esyslog("skindesigner: Failed to validate %s", xmlPath.c_str()); + esyslog("skindesigner: Failed to validate %s", xmlFile.c_str()); return false; } if (root == NULL) { @@ -281,8 +280,8 @@ bool cXmlParser::ParseSkinSetup(string skin) { node = node->next; continue; } - if (!xmlStrcmp(node->name, (const xmlChar *) "parameters")) { - ParseSetupParameter(node->xmlChildrenNode); + if (!xmlStrcmp(node->name, (const xmlChar *) "menu")) { + ParseSetupMenu(node->xmlChildrenNode); node = node->next; continue; } else if (!xmlStrcmp(node->name, (const xmlChar *) "translations")) { @@ -324,64 +323,88 @@ string cXmlParser::GetPath(string xmlFile) { return path; } -void cXmlParser::ParseSetupParameter(xmlNodePtr node) { +void cXmlParser::ParseSetupMenu(xmlNodePtr node) { if (!node) return; if (!skinSetup) return; while (node != NULL) { - if (node->type != XML_ELEMENT_NODE) { node = node->next; continue; } - if (xmlStrcmp(node->name, (const xmlChar *) "parameter")) { - node = node->next; - continue; - } - xmlAttrPtr attr = node->properties; - if (attr == NULL) { - node = node->next; - continue; - } - xmlChar *paramType = NULL; - xmlChar *paramName = NULL; - xmlChar *paramDisplayText = NULL; - xmlChar *paramMin = NULL; - xmlChar *paramMax = NULL; - xmlChar *paramValue = NULL; - while (NULL != attr) { - if (!xmlStrcmp(attr->name, (const xmlChar *) "type")) { - paramType = xmlGetProp(node, attr->name); - } else if (!xmlStrcmp(attr->name, (const xmlChar *) "name")) { - paramName = xmlGetProp(node, attr->name); - } else if (!xmlStrcmp(attr->name, (const xmlChar *) "displaytext")) { - paramDisplayText = xmlGetProp(node, attr->name); - } else if (!xmlStrcmp(attr->name, (const xmlChar *) "min")) { - paramMin = xmlGetProp(node, attr->name); - } else if (!xmlStrcmp(attr->name, (const xmlChar *) "max")) { - paramMax = xmlGetProp(node, attr->name); + + if (!xmlStrcmp(node->name, (const xmlChar *) "parameter")) { + ParseSetupParameter(node); + } else if (!xmlStrcmp(node->name, (const xmlChar *) "submenu")) { + xmlAttrPtr attr = node->properties; + xmlChar *subMenuName = NULL; + xmlChar *subDisplayText = NULL; + while (NULL != attr) { + if (!xmlStrcmp(attr->name, (const xmlChar *) "name")) { + subMenuName = xmlGetProp(node, attr->name); + } else if (!xmlStrcmp(attr->name, (const xmlChar *) "displaytext")) { + subDisplayText = xmlGetProp(node, attr->name); + } + attr = attr->next; } - attr = attr->next; + skinSetup->SetSubMenu(subMenuName, subDisplayText); + ParseSetupMenu(node->xmlChildrenNode); + if (subMenuName) + xmlFree(subMenuName); + if (subDisplayText) + xmlFree(subDisplayText); } - paramValue = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); - skinSetup->SetParameter(paramType, paramName, paramDisplayText, paramMin, paramMax, paramValue); - - if (paramType) - xmlFree(paramType); - if (paramName) - xmlFree(paramName); - if (paramDisplayText) - xmlFree(paramDisplayText); - if (paramMin) - xmlFree(paramMin); - if (paramMax) - xmlFree(paramMax); - if (paramValue) - xmlFree(paramValue); node = node->next; } + skinSetup->SubMenuDone(); +} + +void cXmlParser::ParseSetupParameter(xmlNodePtr node) { + if (!node) + return; + if (!skinSetup) + return; + + xmlAttrPtr attr = node->properties; + if (attr == NULL) { + return; + } + xmlChar *paramType = NULL; + xmlChar *paramName = NULL; + xmlChar *paramDisplayText = NULL; + xmlChar *paramMin = NULL; + xmlChar *paramMax = NULL; + xmlChar *paramValue = NULL; + while (NULL != attr) { + if (!xmlStrcmp(attr->name, (const xmlChar *) "type")) { + paramType = xmlGetProp(node, attr->name); + } else if (!xmlStrcmp(attr->name, (const xmlChar *) "name")) { + paramName = xmlGetProp(node, attr->name); + } else if (!xmlStrcmp(attr->name, (const xmlChar *) "displaytext")) { + paramDisplayText = xmlGetProp(node, attr->name); + } else if (!xmlStrcmp(attr->name, (const xmlChar *) "min")) { + paramMin = xmlGetProp(node, attr->name); + } else if (!xmlStrcmp(attr->name, (const xmlChar *) "max")) { + paramMax = xmlGetProp(node, attr->name); + } + attr = attr->next; + } + paramValue = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); + skinSetup->SetParameter(paramType, paramName, paramDisplayText, paramMin, paramMax, paramValue); + if (paramType) + xmlFree(paramType); + if (paramName) + xmlFree(paramName); + if (paramDisplayText) + xmlFree(paramDisplayText); + if (paramMin) + xmlFree(paramMin); + if (paramMax) + xmlFree(paramMax); + if (paramValue) + xmlFree(paramValue); } void cXmlParser::ParseGlobalColors(xmlNodePtr node) { diff --git a/libtemplate/xmlparser.h b/libtemplate/xmlparser.h index 27399bd..20f6763 100644 --- a/libtemplate/xmlparser.h +++ b/libtemplate/xmlparser.h @@ -31,6 +31,7 @@ private: xmlDocPtr doc; xmlNodePtr root; string GetPath(string xmlFile); + void ParseSetupMenu(xmlNodePtr node); void ParseSetupParameter(xmlNodePtr node); void ParseGlobalColors(xmlNodePtr node); void InsertColor(string name, string value); @@ -51,7 +52,7 @@ public: bool ReadView(cTemplateView *view, string xmlFile); bool ReadPluginView(string plugName, int templateNumber, string templateName); bool ReadGlobals(cGlobals *globals, string xmlFile, bool mandatory); - bool ReadSkinSetup(cSkinSetup *skinSetup, string skin, string xmlFile); + bool ReadSkinSetup(cSkinSetup *skinSetup, string xmlFile); bool ParseView(void); bool ParsePluginView(string plugName, int templateNumber); bool ParseGlobals(void); @@ -15,6 +15,7 @@ cSkinDesignerSetup::cSkinDesignerSetup() { } cSkinDesignerSetup::~cSkinDesignerSetup() { + config.setupCloseDoReload = true; } @@ -44,7 +45,7 @@ eOSState cSkinDesignerSetup::ProcessKey(eKeys Key) { size_t hit = itemText.find(tr("Skin")); if (hit == 0) { string skin = itemText.substr(strlen(tr("Skin"))+1); - state = AddSubMenu(new cSkindesignerSkinSetup(skin)); + state = AddSubMenu(new cSkindesignerSkinSetup(skin, "")); } break; } default: @@ -67,11 +68,11 @@ void cSkinDesignerSetup::Store(void) { config.InitSetupIterator(); cSkinSetup *skinSetup = NULL; - while (skinSetup = config.GetSkinSetup()) { + while (skinSetup = config.GetNextSkinSetup()) { string skin = skinSetup->GetSkin(); skinSetup->InitParameterIterator(); cSkinSetupParameter *param = NULL; - while (param = skinSetup->GetParameter()) { + while (param = skinSetup->GetNextParameter()) { cString paramName = cString::sprintf("%s.%s", skin.c_str(), param->name.c_str()); SetupStore(*paramName, param->value); config.UpdateSkinSetupParameter(*paramName, param->value); @@ -157,10 +158,18 @@ void cSkinDesignerSetup::ImageCacheStatistics(void) { cList<cOsdItem>::Last()->SetSelectable(false); } +// --- cSkinSetupSubMenu ----------------------------------------------------------- + +cSkinSetupSubMenu::cSkinSetupSubMenu(string name, string displayText) : cOsdItem(displayText.c_str()) { + this->name = name; +} + // --- cSkindesignerSkinSetup ----------------------------------------------------------- -cSkindesignerSkinSetup::cSkindesignerSkinSetup(string skin) : cOsdMenu(*cString::sprintf("%s: %s \"%s\"", trVDR("Setup"), tr("Skin"), skin.c_str()), 30) { +cSkindesignerSkinSetup::cSkindesignerSkinSetup(string skin, string name) : +cOsdMenu(*cString::sprintf("%s: %s \"%s\" %s", trVDR("Setup"), tr("Skin"), skin.c_str(), name.c_str()), 30) { this->skin = skin; + this->name = name; Set(); } @@ -171,9 +180,16 @@ eOSState cSkindesignerSkinSetup::ProcessKey(eKeys Key) { eOSState state = cOsdMenu::ProcessKey(Key); if (state == osUnknown) { switch (Key) { - case kOk: - return osBack; - default: + case kOk: { + cOsdItem *current = Get(Current()); + cSkinSetupSubMenu *subMenuItem = dynamic_cast<cSkinSetupSubMenu*>(current); + if (subMenuItem) { + state = AddSubMenu(new cSkindesignerSkinSetup(skin, subMenuItem->GetName())); + break; + } else { + return osBack; + } + } default: break; } } @@ -181,13 +197,13 @@ eOSState cSkindesignerSkinSetup::ProcessKey(eKeys Key) { } void cSkindesignerSkinSetup::Set(void) { - cSkinSetup *skinSetup = config.GetSkinSetup(skin); - if (!skinSetup) + cSkinSetupMenu *menu = config.GetSkinSetupMenu(skin, name); + if (!menu) { return; - - skinSetup->InitParameterIterator(); + } + menu->InitParameterIterator(); cSkinSetupParameter *param = NULL; - while (param = skinSetup->GetParameter()) { + while (param = menu->GetNextParameter(false)) { if (param->type == sptInt) { Add(new cMenuEditIntItem(param->displayText.c_str(), ¶m->value, param->min, param->max)); } else if (param->type == sptBool) { @@ -195,4 +211,9 @@ void cSkindesignerSkinSetup::Set(void) { } } + menu->InitSubmenuIterator(); + cSkinSetupMenu *subMenu = NULL; + while (subMenu = menu->GetNextSubMenu(false)) { + Add(new cSkinSetupSubMenu(subMenu->GetName(), subMenu->GetDisplayText())); + } } @@ -29,16 +29,28 @@ public: virtual ~cSkinDesignerSetup(); }; +// --- cSkinSetupSubMenu ----------------------------------------------------------- + +class cSkinSetupSubMenu : public cOsdItem { +private: + string name; +public: + cSkinSetupSubMenu(string name, string displayText); + virtual ~cSkinSetupSubMenu() {}; + string GetName(void) { return name; }; +}; + // --- cSkindesignerSkinSetup ----------------------------------------------------------- class cSkindesignerSkinSetup : public cOsdMenu { private: string skin; + string name; protected: virtual eOSState ProcessKey(eKeys Key); void Set(void); public: - cSkindesignerSkinSetup(string skin); + cSkindesignerSkinSetup(string skin, string menu); virtual ~cSkindesignerSkinSetup(); }; diff --git a/skins/blackhole/setup.xml b/skins/blackhole/setup.xml index d9b8875..e590344 100644 --- a/skins/blackhole/setup.xml +++ b/skins/blackhole/setup.xml @@ -2,17 +2,7 @@ <!DOCTYPE setup SYSTEM "../../dtd/setup.dtd"> <setup> - <!-- - define all your parameters here which should be configurable via - OSD and the skindesigner setup menu. - Parameters must have type "bool" or "integer". For "bool" Parameters - a choice yes/no is shown in the setup menu, a "integer" parameter - can be configured to a value between "min" and "max". If "min" is not - set, "0" is the minimum, if "max" is not set, "1000" is maximum. - "displayname" is used to display the option in the setup menu. - The configured parameter value is the default value. - --> - <parameters> + <menu> <parameter type="bool" name="showdevices" displaytext="{tr(showdevices)}">0</parameter> <parameter type="bool" name="showposter" displaytext="{tr(showpostertext)}">1</parameter> <parameter type="bool" name="showmainmenuicons" displaytext="{tr(showmainmenuicons)}">1</parameter> @@ -21,11 +11,8 @@ <parameter type="int" name="nummenuitems" min="6" max="30" displaytext="{tr(nummenuitems)}">10</parameter> <parameter type="int" name="nummenuitemsdefault" min="6" max="30" displaytext="{tr(nummenuitemsdefault)}">16</parameter> <parameter type="bool" name="showsubtitle" displaytext="{tr(showsubtitle)}">1</parameter> - </parameters> + </menu> - <!-- - translations of displaytexts - --> <translations> <token name="tr(showdevices)"> <trans lang="en_EN">Show DVB device info when switching channel</trans> @@ -43,24 +30,24 @@ <trans lang="fi_FI">Näytä ikonit päävalikossa</trans> </token> <token name="tr(fadetext)"> - <trans lang="en_EN">Fade time in ms (needs VDR restart)</trans> - <trans lang="de_DE">Einblendzeit in ms (erfordert VDR Neustart)</trans> - <trans lang="fi_FI">Häivytyksen kesto [ms] (uud.käynnistys)</trans> + <trans lang="en_EN">Fade time in ms</trans> + <trans lang="de_DE">Einblendzeit in ms</trans> + <trans lang="fi_FI">Häivytyksen kesto [ms]</trans> </token> <token name="tr(nummenuitemsmain)"> - <trans lang="en_EN">Items in main menu (needs VDR restart)</trans> - <trans lang="de_DE">Elemente im Hauptmenü (erfordert VDR Neustart)</trans> - <trans lang="fi_FI">Valinnat päävalikossa (uud.käynnistys)</trans> + <trans lang="en_EN">Items in main menu</trans> + <trans lang="de_DE">Elemente im Hauptmenü</trans> + <trans lang="fi_FI">Valinnat päävalikossa</trans> </token> <token name="tr(nummenuitems)"> - <trans lang="en_EN">Items in schedules, timers, ... menus (needs VDR restart)</trans> - <trans lang="de_DE">Elemente in Programm, Timer, ... Menüs (erfordert VDR Neustart)</trans> - <trans lang="fi_FI">Valinnat alivalikoissa (uud.käynnistys)</trans> + <trans lang="en_EN">Items in schedules, timers, ... menus</trans> + <trans lang="de_DE">Elemente in Programm, Timer, ... Menüs</trans> + <trans lang="fi_FI">Valinnat alivalikoissa</trans> </token> <token name="tr(nummenuitemsdefault)"> - <trans lang="en_EN">Items in default list menu (needs VDR restart)</trans> - <trans lang="de_DE">Elemente im Standard ListenMenü (erfordert VDR Neustart)</trans> - <trans lang="fi_FI">Valinnat valikkolistoissa (uud.käynnistys)</trans> + <trans lang="en_EN">Items in default list menu</trans> + <trans lang="de_DE">Elemente im Standard ListenMenü</trans> + <trans lang="fi_FI">Valinnat valikkolistoissa</trans> </token> <token name="tr(showsubtitle)"> <trans lang="en_EN">Show shorttexts in schedules menus</trans> diff --git a/skins/metrixhd/setup.xml b/skins/metrixhd/setup.xml index 034d0c0..abaf1c6 100644 --- a/skins/metrixhd/setup.xml +++ b/skins/metrixhd/setup.xml @@ -2,29 +2,16 @@ <!DOCTYPE setup SYSTEM "../../dtd/setup.dtd"> <setup> - <!-- - define all your parameters here which should be configurable via - OSD and the skindesigner setup menu. - Parameters must have type "bool" or "integer". For "bool" Parameters - a choice yes/no is shown in the setup menu, a "integer" parameter - can be configured to a value between "min" and "max". If "min" is not - set, "0" is the minimum, if "max" is not set, "1000" is maximum. - "displayname" is used to display the option in the setup menu. - The configured parameter value is the default value. - --> - <parameters> + <menu> <parameter type="int" name="fadetime" min="0" max="1000" displaytext="{tr(fadetext)}">0</parameter> <parameter type="bool" name="showdevices" displaytext="{tr(showdevices)}">0</parameter> - </parameters> + </menu> - <!-- - translations of displaytexts - --> <translations> <token name="tr(fadetext)"> - <trans lang="en_EN">Fade time in ms (needs VDR restart)</trans> - <trans lang="de_DE">Einblendzeit in ms (erfordert VDR Neustart)</trans> - <trans lang="fi_FI">Häivytyksen kesto [ms] (uud.käynnistys)</trans> + <trans lang="en_EN">Fade time in ms</trans> + <trans lang="de_DE">Einblendzeit in ms</trans> + <trans lang="fi_FI">Häivytyksen kesto [ms]</trans> </token> <token name="tr(showdevices)"> <trans lang="en_EN">Show DVB device info when switching channel</trans> diff --git a/skins/nopacity/setup.xml b/skins/nopacity/setup.xml index 7252c47..6482021 100644 --- a/skins/nopacity/setup.xml +++ b/skins/nopacity/setup.xml @@ -2,26 +2,13 @@ <!DOCTYPE setup SYSTEM "../../dtd/setup.dtd"> <setup> - <!-- - define all your parameters here which should be configurable via - OSD and the skindesigner setup menu. - Parameters must have type "bool" or "integer". For "bool" Parameters - a choice yes/no is shown in the setup menu, a "integer" parameter - can be configured to a value between "min" and "max". If "min" is not - set, "0" is the minimum, if "max" is not set, "1000" is maximum. - "displayname" is used to display the option in the setup menu. - The configured parameter value is the default value. - --> - <parameters> + <menu> <parameter type="bool" name="showposter" displaytext="{tr(showpostertext)}">1</parameter> <parameter type="bool" name="showweather" displaytext="{tr(showweather)}">1</parameter> <parameter type="int" name="fadeTime" min="0" max="1000" displaytext="{tr(fadeText)}">300</parameter> <parameter type="int" name="transparency" min="0" max="30" displaytext="{tr(transparency)}">20</parameter> - </parameters> + </menu> - <!-- - translations of displaytexts - --> <translations> <token name="tr(showpostertext)"> <trans lang="en_EN">Show Poster when switching channel</trans> @@ -32,12 +19,12 @@ <trans lang="de_DE">Wetter in Infobar anzeigen</trans> </token> <token name="tr(fadeText)"> - <trans lang="en_EN">Fade time in ms (needs VDR restart)</trans> - <trans lang="de_DE">Einblendzeit in ms (erfordert VDR Neustart)</trans> + <trans lang="en_EN">Fade time in ms</trans> + <trans lang="de_DE">Einblendzeit in ms</trans> </token> <token name="tr(transparency)"> - <trans lang="en_EN">Transpareny channel, replay and volume (needs VDR restart)</trans> - <trans lang="de_DE">Transparenz bei Kanal,Wiedergabe und Lautstärke (erfordert VDR Neustart)</trans> + <trans lang="en_EN">Transpareny channel, replay and volume</trans> + <trans lang="de_DE">Transparenz bei Kanal,Wiedergabe und Lautstärke</trans> </token> </translations> </setup> diff --git a/skinskeleton/setup.xml b/skinskeleton/setup.xml index a0e5a97..c73d6d4 100644 --- a/skinskeleton/setup.xml +++ b/skinskeleton/setup.xml @@ -5,15 +5,20 @@ <!-- define all your parameters here which should be configurable via OSD and the skindesigner setup menu. + <submenu> and <parameter> tags are allowed, <submenu> can be nested + with arbitrary depth. + Submenus must carry the attributes "name" and "displaytext". "name" + is for internal usage, "displaytext" is used for displaying the submenu + in the menu and can be an translation token Parameters must have type "bool" or "integer". For "bool" Parameters a choice yes/no is shown in the setup menu, a "integer" parameter can be configured to a value between "min" and "max". If "min" is not set, "0" is the minimum, if "max" is not set, "1000" is maximum. - "displayname" is used to display the option in the setup menu. + "displaytext" is used to display the option in the setup menu. The configured parameter value is the default value. --> - <parameters> - </parameters> + <menu> + </menu> <!-- translations of displaytexts |