summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlouis <louis.braun@gmx.de>2015-01-31 11:46:06 +0100
committerlouis <louis.braun@gmx.de>2015-01-31 11:46:06 +0100
commit1883ac1691f1e6cbe035819c07bbae72bc7748a9 (patch)
treeef3ee83a82ee65d96f1640414e940921936cae9c
parent304f5920045b1d55f093b2a7bb19162de1d2d4db (diff)
downloadvdr-plugin-skindesigner-1883ac1691f1e6cbe035819c07bbae72bc7748a9.tar.gz
vdr-plugin-skindesigner-1883ac1691f1e6cbe035819c07bbae72bc7748a9.tar.bz2
added possibiliy to use submenus in the skin setup menus
-rw-r--r--HISTORY3
-rw-r--r--config.c14
-rw-r--r--config.h5
-rw-r--r--designer.c4
-rw-r--r--dtd/setup.dtd10
-rw-r--r--libcore/skinsetup.c238
-rw-r--r--libcore/skinsetup.h49
-rw-r--r--libtemplate/xmlparser.c127
-rw-r--r--libtemplate/xmlparser.h3
-rw-r--r--setup.c45
-rw-r--r--setup.h14
-rw-r--r--skins/blackhole/setup.xml41
-rw-r--r--skins/metrixhd/setup.xml23
-rw-r--r--skins/nopacity/setup.xml25
-rw-r--r--skinskeleton/setup.xml11
15 files changed, 411 insertions, 201 deletions
diff --git a/HISTORY b/HISTORY
index c62b6b4..c6c9322 100644
--- a/HISTORY
+++ b/HISTORY
@@ -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
diff --git a/config.c b/config.c
index 61ccb55..8b018f7 100644
--- a/config.c
+++ b/config.c
@@ -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();
diff --git a/config.h b/config.h
index ab53c44..a10ad5f 100644
--- a/config.h
+++ b/config.h
@@ -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
diff --git a/designer.c b/designer.c
index 676050f..c279650 100644
--- a/designer.c
+++ b/designer.c
@@ -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);
diff --git a/setup.c b/setup.c
index 4523adf..611cc69 100644
--- a/setup.c
+++ b/setup.c
@@ -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(), &param->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()));
+ }
}
diff --git a/setup.h b/setup.h
index f831d74..c06a5cf 100644
--- a/setup.h
+++ b/setup.h
@@ -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