summaryrefslogtreecommitdiff
path: root/libtemplate
diff options
context:
space:
mode:
authorlouis <louis.braun@gmx.de>2014-09-27 09:25:14 +0200
committerlouis <louis.braun@gmx.de>2014-09-27 09:25:14 +0200
commitb0509b5182b6e0d04f05e6b3d5676b0d21f51966 (patch)
tree22b302342f22843e0815eb5f516c85f1478cbf0b /libtemplate
downloadvdr-plugin-skindesigner-0.0.1.tar.gz
vdr-plugin-skindesigner-0.0.1.tar.bz2
initial commit version 0.0.10.0.1
Diffstat (limited to 'libtemplate')
-rw-r--r--libtemplate/globals.c98
-rw-r--r--libtemplate/globals.h38
-rw-r--r--libtemplate/parameter.c394
-rw-r--r--libtemplate/parameter.h138
-rw-r--r--libtemplate/template.c273
-rw-r--r--libtemplate/template.h57
-rw-r--r--libtemplate/templatefunction.c1474
-rw-r--r--libtemplate/templatefunction.h211
-rw-r--r--libtemplate/templateloopfunction.c208
-rw-r--r--libtemplate/templateloopfunction.h33
-rw-r--r--libtemplate/templatepixmap.c473
-rw-r--r--libtemplate/templatepixmap.h82
-rw-r--r--libtemplate/templateview.c1567
-rw-r--r--libtemplate/templateview.h198
-rw-r--r--libtemplate/templateviewelement.c128
-rw-r--r--libtemplate/templateviewelement.h99
-rw-r--r--libtemplate/templateviewlist.c138
-rw-r--r--libtemplate/templateviewlist.h49
-rw-r--r--libtemplate/templateviewtab.c38
-rw-r--r--libtemplate/templateviewtab.h31
-rw-r--r--libtemplate/xmlparser.c728
-rw-r--r--libtemplate/xmlparser.h56
22 files changed, 6511 insertions, 0 deletions
diff --git a/libtemplate/globals.c b/libtemplate/globals.c
new file mode 100644
index 0000000..9e9ce5f
--- /dev/null
+++ b/libtemplate/globals.c
@@ -0,0 +1,98 @@
+#include "globals.h"
+#include "xmlparser.h"
+#include <locale.h>
+
+cGlobals::cGlobals(void) {
+ fonts.insert(pair<string, string>("vdrOsd", Setup.FontOsd));
+ fonts.insert(pair<string, string>("vdrFix", Setup.FontFix));
+ fonts.insert(pair<string, string>("vdrSml", Setup.FontSml));
+
+ string loc = setlocale(LC_NAME, NULL);
+ size_t index = loc.find_first_of(".");
+ string langISO = "";
+ if (index > 0) {
+ langISO = loc.substr(0, index);
+ }
+ if (langISO.size() == 5) {
+ language = langISO.c_str();
+ } else {
+ language = "en_EN";
+ }
+ dsyslog("skindesigner: using language %s", language.c_str());
+}
+
+bool cGlobals::ReadFromXML(void) {
+ std::string xmlFile = "globals.xml";
+ cXmlParser parser;
+ if (!parser.ReadGlobals(this, xmlFile))
+ return false;
+ if (!parser.ParseGlobals())
+ return false;
+ return true;
+}
+
+bool cGlobals::Translate(string text, string &translation) {
+ string transStart = "{tr(";
+ string transEnd = ")}";
+ size_t foundStart = text.find(transStart);
+ size_t foundEnd = text.find(transEnd);
+ bool translated = false;
+
+ while (foundStart != string::npos && foundEnd != string::npos) {
+ string token = text.substr(foundStart + 1, foundEnd - foundStart);
+ string transToken = DoTranslate(token);
+ if (transToken.size() > 0)
+ translated = true;
+ else
+ return false;
+ text.replace(foundStart, foundEnd - foundStart + 2, transToken);
+ foundStart = text.find(transStart);
+ foundEnd = text.find(transEnd);
+ }
+ if (translated)
+ translation = text;
+ return translated;
+}
+
+string cGlobals::DoTranslate(string token) {
+ string translation = "";
+ map <string, map< string, string > >::iterator hit = translations.find(token);
+ if (hit == translations.end()) {
+ esyslog("skindesigner: invalid translation token %s", token.c_str());
+ return translation;
+ }
+ map< string, string > translats = hit->second;
+ map< string, string >::iterator trans = translats.find(language);
+ if (trans != translats.end()) {
+ translation = trans->second;
+ } else {
+ map< string, string >::iterator transDefault = translats.find("en_EN");
+ if (transDefault != translats.end()) {
+ translation = transDefault->second;
+ }
+ }
+ return translation;
+}
+
+void cGlobals::Debug(void) {
+ dsyslog("skindesigner: GLOBAL VARIABLES");
+ for (map <string, tColor>::iterator col = colors.begin(); col != colors.end(); col++) {
+ dsyslog("skindesigner: Color \"%s\": %x", (col->first).c_str(), col->second);
+ }
+ for (map <string, int>::iterator myInt = intVars.begin(); myInt != intVars.end(); myInt++) {
+ dsyslog("skindesigner: Integer Variable \"%s\": %d", (myInt->first).c_str(), myInt->second);
+ }
+ for (map <string, string>::iterator myStr = stringVars.begin(); myStr != stringVars.end(); myStr++) {
+ dsyslog("skindesigner: String Variable \"%s\": \"%s\"", (myStr->first).c_str(), (myStr->second).c_str());
+ }
+ for (map <string, string>::iterator font = fonts.begin(); font != fonts.end(); font++) {
+ dsyslog("skindesigner: Font \"%s\": \"%s\"", (font->first).c_str(), (font->second).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());
+ map< string, string > tokenTrans = trans->second;
+ for (map< string, string >::iterator transTok = tokenTrans.begin(); transTok != tokenTrans.end(); transTok++) {
+ dsyslog("skindesigner: language %s, translation %s", (transTok->first).c_str(), (transTok->second).c_str());
+ }
+ }
+}
diff --git a/libtemplate/globals.h b/libtemplate/globals.h
new file mode 100644
index 0000000..f7a959e
--- /dev/null
+++ b/libtemplate/globals.h
@@ -0,0 +1,38 @@
+#ifndef __XMLGLOBALS_H
+#define __XMLGLOBALS_H
+
+#include <iostream>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string>
+#include <vector>
+#include <map>
+#include <set>
+#include <sstream>
+#include <vdr/plugin.h>
+
+using namespace std;
+
+typedef uint32_t tColor;
+
+// --- cGlobals -------------------------------------------------------------
+
+class cGlobals {
+private:
+ string language;
+ string DoTranslate(string token);
+public:
+ cGlobals(void);
+ virtual ~cGlobals(void) {};
+ map <string, tColor> colors;
+ map <string, int> intVars;
+ map <string, string> stringVars;
+ map <string, string> fonts;
+ map <string, map< string, string > > translations;
+ bool ReadFromXML(void);
+ bool Translate(string text, string &translation);
+ void Debug(void);
+};
+
+#endif //__XMLGLOBALS_H \ No newline at end of file
diff --git a/libtemplate/parameter.c b/libtemplate/parameter.c
new file mode 100644
index 0000000..e7dd30a
--- /dev/null
+++ b/libtemplate/parameter.c
@@ -0,0 +1,394 @@
+#include "parameter.h"
+
+using namespace std;
+
+// --- cNumericParameter -------------------------------------------------------------
+
+cNumericParameter::cNumericParameter(string value) {
+ this->value = value;
+ globals = NULL;
+ isValid = false;
+ width = 0;
+ height = 0;
+ columnWidth = -1;
+ rowHeight = -1;
+ hor = true;
+ defaultValue = 0;
+}
+
+cNumericParameter::~cNumericParameter(void) {
+}
+
+void cNumericParameter::SetAreaSize(int w, int h) {
+ width = w;
+ height = h;
+}
+
+int cNumericParameter::Parse(string &parsedValue) {
+ int retVal = defaultValue;
+
+ if (IsNumber(value)) {
+ isValid = true;
+ retVal = atoi(value.c_str());
+ return retVal;
+ }
+
+ //checking for percent value
+ bool isPercentValue = CheckPercentValue(retVal);
+ if (isPercentValue) {
+ isValid = true;
+ return retVal;
+ }
+
+ //checking for expression
+ bool isValidExpression = CheckExpression(retVal, parsedValue);
+ if (isValidExpression) {
+ isValid = true;
+ return retVal;
+ }
+
+ return retVal;
+}
+
+bool cNumericParameter::IsNumber(const string& s) {
+ string::const_iterator it = s.begin();
+ while (it != s.end() && isdigit(*it)) ++it;
+ return !s.empty() && it == s.end();
+}
+
+bool cNumericParameter::CheckPercentValue(int &val) {
+ bool ok = false;
+ size_t posPercent = value.find('%');
+ if (posPercent != string::npos) {
+ string strPerc = value.substr(0, posPercent);
+ if (!IsNumber(strPerc)) {
+ return ok;
+ }
+ int perc = atoi(strPerc.c_str());
+ if (hor) {
+ val = width * perc / 100;
+ } else {
+ val = height * perc / 100;
+ }
+ ok = true;
+ }
+ return ok;
+}
+
+bool cNumericParameter::CheckExpression(int &val, string &parsedVal) {
+ bool ok = false;
+ string parsedValue = value;
+ //remove white spaces
+ parsedValue.erase( std::remove_if( parsedValue.begin(), parsedValue.end(), ::isspace ), parsedValue.end() );
+
+ //check and replace {areawidth} and {areaheight} tokens
+ string tokenWidth = "{areawidth}";
+ string tokenHeight = "{areaheight}";
+
+ stringstream sw;
+ sw << width;
+ string strWidth = sw.str();
+ stringstream sh;
+ sh << height;
+ string strHeight = sh.str();
+
+ bool foundToken = true;
+ while(foundToken) {
+ size_t foundTokenWidth = parsedValue.find(tokenWidth);
+ if (foundTokenWidth != string::npos) {
+ parsedValue = parsedValue.replace(foundTokenWidth, tokenWidth.size(), strWidth);
+ } else {
+ foundToken = false;
+ }
+ }
+
+ foundToken = true;
+ while(foundToken) {
+ size_t foundTokenHeight = parsedValue.find(tokenHeight);
+ if (foundTokenHeight != string::npos) {
+ parsedValue = parsedValue.replace(foundTokenHeight, tokenHeight.size(), strHeight);
+ } else {
+ foundToken = false;
+ }
+ }
+
+ //check and replace {columnwidth} and {rowheight} tokens for loop functions
+ if (columnWidth > 0 || rowHeight > 0) {
+ tokenWidth = "{columnwidth}";
+ tokenHeight = "{rowheight}";
+ stringstream cw;
+ cw << columnWidth;
+ strWidth = cw.str();
+ stringstream rh;
+ rh << rowHeight;
+ strHeight = rh.str();
+
+ foundToken = true;
+ while(foundToken) {
+ size_t foundTokenWidth = parsedValue.find(tokenWidth);
+ if (foundTokenWidth != string::npos) {
+ parsedValue = parsedValue.replace(foundTokenWidth, tokenWidth.size(), strWidth);
+ } else {
+ foundToken = false;
+ }
+ }
+
+ foundToken = true;
+ while(foundToken) {
+ size_t foundTokenHeight = parsedValue.find(tokenHeight);
+ if (foundTokenHeight != string::npos) {
+ parsedValue = parsedValue.replace(foundTokenHeight, tokenHeight.size(), strHeight);
+ } else {
+ foundToken = false;
+ }
+ }
+ }
+
+ if (globals) {
+ for (map<string, int>::iterator globInt = globals->intVars.begin(); globInt != globals->intVars.end(); globInt++) {
+ stringstream sToken;
+ sToken << "{" << globInt->first << "}";
+ string token = sToken.str();
+ size_t foundToken = parsedValue.find(token);
+ if (foundToken != string::npos) {
+ stringstream st;
+ st << globInt->second;
+ parsedValue = parsedValue.replace(foundToken, token.size(), st.str());
+ }
+ }
+ }
+
+ if (IsNumber(parsedValue)) {
+ ok = true;
+ val = atoi(parsedValue.c_str());
+ return ok;
+ }
+
+ if (!ValidNumericExpression(parsedValue)) {
+ parsedVal = parsedValue;
+ return ok;
+ }
+ ok = true;
+ char * expression = new char[parsedValue.size() + 1];
+ std::copy(parsedValue.begin(), parsedValue.end(), expression);
+ expression[parsedValue.size()] = '\0';
+ int expRes = EvaluateTheExpression(expression);
+ val = expRes;
+ delete[] expression;
+ return ok;
+}
+
+bool cNumericParameter::ValidNumericExpression(string &parsedValue) {
+ string::const_iterator it = parsedValue.begin();
+ while (it != parsedValue.end() && (isdigit(*it) || *it == '.' || *it == ',' || *it == '+' || *it == '-' || *it == '*' || *it == '/')) ++it;
+ return !parsedValue.empty() && it == parsedValue.end();
+}
+
+int cNumericParameter::EvaluateTheExpression(char* expr) {
+ return round(ParseSummands(expr));
+}
+
+double cNumericParameter::ParseAtom(char*& expr) {
+ // Read the number from string
+ char* end_ptr;
+ double res = strtod(expr, &end_ptr);
+ // Advance the pointer and return the result
+ expr = end_ptr;
+ return res;
+}
+
+// Parse multiplication and division
+double cNumericParameter::ParseFactors(char*& expr) {
+ double num1 = ParseAtom(expr);
+ for(;;) {
+ // Save the operation
+ char op = *expr;
+ if(op != '/' && op != '*')
+ return num1;
+ expr++;
+ double num2 = ParseAtom(expr);
+ // Perform the saved operation
+ if(op == '/') {
+ if (num2 != 0) {
+ num1 /= num2;
+ }
+ } else
+ num1 *= num2;
+ }
+}
+
+// Parse addition and subtraction
+double cNumericParameter::ParseSummands(char*& expr) {
+ double num1 = ParseFactors(expr);
+ for(;;) {
+ char op = *expr;
+ if(op != '-' && op != '+')
+ return num1;
+ expr++;
+ double num2 = ParseFactors(expr);
+ if(op == '-')
+ num1 -= num2;
+ else
+ num1 += num2;
+ }
+}
+
+// --- cConditionalParameter -------------------------------------------------------------
+
+cConditionalParameter::cConditionalParameter(cGlobals *globals, string value) {
+ this->globals = globals;
+ isTrue = false;
+ this->value = value;
+ type = cpNone;
+}
+
+cConditionalParameter::~cConditionalParameter(void) {
+}
+
+void cConditionalParameter::Tokenize(void) {
+ size_t posAnd = value.find("++");
+ if (posAnd != string::npos) {
+ type = cpAnd;
+ TokenizeValue("++");
+ } else {
+ size_t posOr = value.find("||");
+ if (posOr != string::npos) {
+ type = cpOr;
+ TokenizeValue("||");
+ }
+ }
+ if (type == cpNone) {
+ InsertCondition(value);
+ }
+}
+
+bool cConditionalParameter::Evaluate(map < string, int > *intTokens, map < string, string > *stringTokens) {
+ isTrue = false;
+ bool first = true;
+ for (vector<sCondition>::iterator cond = conditions.begin(); cond != conditions.end(); cond++) {
+ bool tokenTrue = false;
+
+ if (cond->type == ctStringSet) {
+ if (stringTokens) {
+ map < string, string >::iterator hit = stringTokens->find(cond->tokenName);
+ if (hit != stringTokens->end()) {
+ string value = hit->second;
+ if (value.size() > 0)
+ tokenTrue = true;
+ }
+ }
+ } else {
+ int tokenValue = EvaluateParameter(cond->tokenName, intTokens, stringTokens);
+ if (cond->type == ctBool) {
+ tokenTrue = tokenValue;
+ } else if (cond->type == ctGreater) {
+ tokenTrue = (tokenValue > cond->compareValue) ? true : false;
+ } else if (cond->type == ctLower) {
+ tokenTrue = (tokenValue < cond->compareValue) ? true : false;
+ } else if (cond->type == ctEquals) {
+ tokenTrue = (tokenValue == cond->compareValue) ? true : false;
+ }
+ }
+
+ if (cond->isNegated)
+ tokenTrue = !tokenTrue;
+ if (type == cpAnd) {
+ if (first)
+ isTrue = tokenTrue;
+ else
+ isTrue = isTrue && tokenTrue;
+ } else if (type == cpOr) {
+ isTrue = isTrue || tokenTrue;
+ } else {
+ isTrue = tokenTrue;
+ }
+ first = false;
+ }
+}
+
+int cConditionalParameter::EvaluateParameter(string token, map < string, int > *intTokens, map < string, string > *stringTokens) {
+ //first check globals
+ map < string, int >::iterator hitGlobals = globals->intVars.find(token);
+ if (hitGlobals != globals->intVars.end()) {
+ return hitGlobals->second;
+ } else {
+ //then check tokens
+ if (intTokens) {
+ map < string, int >::iterator hit = intTokens->find(token);
+ if (hit != intTokens->end()) {
+ return hit->second;
+ }
+ }
+ if (stringTokens) {
+ map < string, string >::iterator hit = stringTokens->find(token);
+ if (hit != stringTokens->end()) {
+ string value = hit->second;
+ return atoi(value.c_str());
+ }
+ }
+ }
+ return 0;
+}
+
+void cConditionalParameter::TokenizeValue(string sep) {
+ string buffer = value;
+ bool sepFound = true;
+ while (sepFound) {
+ size_t posSep = buffer.find(sep);
+ if (posSep == string::npos) {
+ InsertCondition(buffer);
+ sepFound = false;
+ }
+ string token = buffer.substr(0, posSep);
+ buffer = buffer.replace(0, posSep + sep.size(), "");
+ InsertCondition(token);
+ }
+}
+
+void cConditionalParameter::InsertCondition(string cond) {
+ cond.erase( std::remove_if( cond.begin(), cond.end(), ::isspace ), cond.end() );
+
+ if (cond.size() < 1)
+ return;
+
+ size_t tokenStart = cond.find('{');
+ size_t tokenEnd = cond.find('}');
+
+ if (tokenStart == string::npos || tokenEnd == string::npos || tokenStart > tokenEnd)
+ return;
+
+ string tokenName = cond.substr(tokenStart + 1, tokenEnd - tokenStart - 1);
+ string rest = cond.replace(tokenStart, tokenEnd - tokenStart + 1, "");
+
+ sCondition sCond;
+ sCond.tokenName = tokenName;
+ sCond.type = ctBool;
+ sCond.compareValue = 0;
+ sCond.isNegated = false;
+ if (!rest.compare("not")) {
+ sCond.isNegated = true;
+ } else if (!rest.compare("isset")) {
+ sCond.type = ctStringSet;
+ } else if (startswith(rest.c_str(), "gt(")) {
+ string compVal = rest.substr(4, rest.size() - 5);
+ sCond.compareValue = atoi(compVal.c_str());
+ sCond.type = ctGreater;
+ } else if (startswith(rest.c_str(), "lt(")) {
+ string compVal = rest.substr(4, rest.size() - 5);
+ sCond.compareValue = atoi(compVal.c_str());
+ sCond.type = ctLower;
+ } else if (startswith(rest.c_str(), "eq(")) {
+ string compVal = rest.substr(4, rest.size() - 5);
+ sCond.compareValue = atoi(compVal.c_str());
+ sCond.type = ctEquals;
+ }
+
+ conditions.push_back(sCond);
+}
+
+void cConditionalParameter::Debug(void) {
+ dsyslog("skindesigner: Condition %s, Type: %s, cond is %s", value.c_str(), (type == cpAnd)?"and combination":((type == cpOr)?"or combination":"single param") , isTrue?"true":"false");
+ for (vector<sCondition>::iterator it = conditions.begin(); it != conditions.end(); it++) {
+ dsyslog("skindesigner: cond token %s, type: %d, compareValue %d, negated: %d", it->tokenName.c_str(), it->type, it->compareValue, it->isNegated);
+ }
+} \ No newline at end of file
diff --git a/libtemplate/parameter.h b/libtemplate/parameter.h
new file mode 100644
index 0000000..914f3fc
--- /dev/null
+++ b/libtemplate/parameter.h
@@ -0,0 +1,138 @@
+#ifndef __TEMPLATEPARAMETER_H
+#define __TEMPLATEPARAMETER_H
+
+#include <iostream>
+#include <stdio.h>
+#include <stdlib.h>
+#include <algorithm>
+#include <math.h>
+#include <string>
+#include <vector>
+#include <map>
+#include <set>
+#include <sstream>
+
+#include "globals.h"
+
+using namespace std;
+
+enum eAlign {
+ alLeft,
+ alCenter,
+ alRight,
+ alTop,
+ alBottom
+};
+
+enum eScrollMode {
+ smNone,
+ smCarriageReturn,
+ smForthAndBack
+};
+
+enum eScrollSpeed {
+ ssNone,
+ ssSlow,
+ ssMedium,
+ ssFast
+};
+
+enum eOrientation {
+ orNone,
+ orHorizontal,
+ orVertical,
+ orAbsolute
+};
+
+// --- cNumericParameter -------------------------------------------------------------
+
+class cNumericParameter {
+private:
+ cGlobals *globals;
+ string value;
+ bool isValid;
+ int width;
+ int height;
+ int columnWidth;
+ int rowHeight;
+ bool hor;
+ int defaultValue;
+ bool IsNumber(const string& s);
+ bool CheckPercentValue(int &val);
+ bool CheckExpression(int &val, string &parsedVal);
+ bool ValidNumericExpression(string &parsedValue);
+ int EvaluateTheExpression(char* expr);
+ double ParseAtom(char*& expr);
+ double ParseFactors(char*& expr);
+ double ParseSummands(char*& expr);
+public:
+ cNumericParameter(string value);
+ virtual ~cNumericParameter(void);
+ void SetGlobals(cGlobals *globals) { this->globals = globals; };
+ void SetAreaSize(int w, int h);
+ void SetLoopContainer(int columnWidth, int rowHeight) { this->columnWidth = columnWidth; this->rowHeight = rowHeight; };
+ void SetDefault(int def) { defaultValue = def; };
+ void SetHorizontal(void) { hor = true; };
+ void SetVertical(void) { hor = false; };
+ int Parse(string &parsedValue);
+ bool Valid(void) { return isValid; };
+};
+
+// --- cTextToken -------------------------------------------------------------
+
+enum eTextTokenType {
+ ttConstString,
+ ttToken,
+ ttConditionalToken
+};
+
+class cTextToken {
+public:
+ eTextTokenType type;
+ string value;
+ vector<cTextToken> subTokens;
+};
+
+// --- cConditionalParameter -------------------------------------------------------------
+
+enum eCondParameterType {
+ cpAnd,
+ cpOr,
+ cpNone
+};
+
+enum eCondType {
+ ctLower,
+ ctGreater,
+ ctEquals,
+ ctBool,
+ ctStringSet,
+ ctNone
+};
+
+struct sCondition {
+ string tokenName;
+ bool isNegated;
+ eCondType type;
+ int compareValue;
+};
+
+class cConditionalParameter {
+private:
+ cGlobals *globals;
+ bool isTrue;
+ string value;
+ eCondParameterType type;
+ vector<sCondition> conditions;
+ void TokenizeValue(string sep);
+ void InsertCondition(string cond);
+ int EvaluateParameter(string token, map < string, int > *intTokens, map < string, string > *stringTokens);
+public:
+ cConditionalParameter(cGlobals *globals, string value);
+ virtual ~cConditionalParameter(void);
+ void Tokenize(void);
+ bool Evaluate(map < string, int > *intTokens, map < string, string > *stringTokens);
+ bool IsTrue(void) { return isTrue; };
+ void Debug(void);
+};
+#endif //__TEMPLATEPARAMETER_H \ No newline at end of file
diff --git a/libtemplate/template.c b/libtemplate/template.c
new file mode 100644
index 0000000..b5889ad
--- /dev/null
+++ b/libtemplate/template.c
@@ -0,0 +1,273 @@
+ #include "template.h"
+#include "xmlparser.h"
+#include "../config.h"
+
+// --- cTemplate -------------------------------------------------------------
+
+cTemplate::cTemplate(eViewType viewType) {
+ globals = NULL;
+ rootView = NULL;
+ this->viewType = viewType;
+ CreateView();
+}
+
+cTemplate::~cTemplate() {
+
+ if (rootView)
+ delete rootView;
+
+}
+
+/*******************************************************************
+* Public Functions
+*******************************************************************/
+bool cTemplate::ReadFromXML(void) {
+ std::string xmlFile;
+ switch (viewType) {
+ case vtDisplayChannel:
+ xmlFile = "displaychannel.xml";
+ break;
+ case vtDisplayMenu:
+ xmlFile = "displaymenu.xml";
+ break;
+ case vtDisplayMessage:
+ xmlFile = "displaymessage.xml";
+ break;
+ case vtDisplayReplay:
+ xmlFile = "displayreplay.xml";
+ break;
+ case vtDisplayVolume:
+ xmlFile = "displayvolume.xml";
+ break;
+ case vtDisplayAudioTracks:
+ xmlFile = "displayaudiotracks.xml";
+ break;
+ default:
+ return false;
+ }
+
+ cXmlParser parser;
+ if (!parser.ReadView(rootView, xmlFile)) {
+ return false;
+ }
+ if (!parser.ParseView()) {
+ return false;
+ }
+ return true;
+}
+
+void cTemplate::SetGlobals(cGlobals *globals) {
+ this->globals = globals;
+ rootView->SetGlobals(globals);
+}
+
+void cTemplate::Translate(void) {
+ rootView->Translate();
+}
+
+
+void cTemplate::PreCache(void) {
+ rootView->PreCache(false);
+}
+
+vector< pair<string, int> > cTemplate::GetUsedFonts(void) {
+ vector< pair<string, int> > usedFonts;
+
+ GetUsedFonts(rootView, usedFonts);
+
+ rootView->InitSubViewIterator();
+ cTemplateView *subView = NULL;
+ while(subView = rootView->GetNextSubView()) {
+ GetUsedFonts(subView, usedFonts);
+ }
+
+ return usedFonts;
+}
+
+
+void cTemplate::CacheImages(void) {
+ CacheImages(rootView);
+
+ rootView->InitSubViewIterator();
+ cTemplateView *subView = NULL;
+ while(subView = rootView->GetNextSubView()) {
+ CacheImages(subView);
+ }
+}
+
+void cTemplate::Debug(void) {
+
+ rootView->Debug();
+
+}
+
+/*******************************************************************
+* Private Functions
+*******************************************************************/
+
+void cTemplate::CreateView(void) {
+ switch (viewType) {
+ case vtDisplayChannel:
+ rootView = new cTemplateViewChannel();
+ break;
+ case vtDisplayMenu:
+ rootView = new cTemplateViewMenu();
+ break;
+ case vtDisplayReplay:
+ rootView = new cTemplateViewReplay();
+ break;
+ case vtDisplayVolume:
+ rootView = new cTemplateViewVolume();
+ break;
+ case vtDisplayAudioTracks:
+ rootView = new cTemplateViewAudioTracks();
+ break;
+ case vtDisplayMessage:
+ rootView = new cTemplateViewMessage();
+ break;
+ default:
+ esyslog("skindesigner: unknown view %d", viewType);
+ }
+}
+
+void cTemplate::GetUsedFonts(cTemplateView *view, vector< pair<string, int> > &usedFonts) {
+ //used fonts in viewElements
+ view->InitViewElementIterator();
+ cTemplateViewElement *viewElement = NULL;
+ while(viewElement = view->GetNextViewElement()) {
+ viewElement->InitIterator();
+ cTemplatePixmap *pix = NULL;
+ while(pix = viewElement->GetNextPixmap()) {
+ pix->InitIterator();
+ cTemplateFunction *func = NULL;
+ while(func = pix->GetNextFunction()) {
+ if (func->GetType() == ftDrawText) {
+ usedFonts.push_back(pair<string,int>(func->GetFontName(), func->GetNumericParameter(ptFontSize)));
+ }
+ }
+ }
+ }
+ //used fonts in viewLists pixmaps
+ view->InitViewListIterator();
+ cTemplateViewList *viewList = NULL;
+ while(viewList = view->GetNextViewList()) {
+ viewList->InitIterator();
+ cTemplatePixmap *pix = NULL;
+ while(pix = viewList->GetNextPixmap()) {
+ pix->InitIterator();
+ cTemplateFunction *func = NULL;
+ while(func = pix->GetNextFunction()) {
+ if (func->GetType() == ftDrawText) {
+ usedFonts.push_back(pair<string,int>(func->GetFontName(), func->GetNumericParameter(ptFontSize)));
+ }
+ }
+ }
+ cTemplateViewElement *listElement = viewList->GetListElement();
+ listElement->InitIterator();
+ while(pix = listElement->GetNextPixmap()) {
+ pix->InitIterator();
+ cTemplateFunction *func = NULL;
+ while(func = pix->GetNextFunction()) {
+ if (func->GetType() == ftDrawText) {
+ usedFonts.push_back(pair<string,int>(func->GetFontName(), func->GetNumericParameter(ptFontSize)));
+ }
+ }
+ }
+ }
+ //used fonts in viewTabs
+ view->InitViewTabIterator();
+ cTemplateViewTab *viewTab = NULL;
+ while(viewTab = view->GetNextViewTab()) {
+ viewTab->InitIterator();
+ cTemplateFunction *func = NULL;
+ while(func = viewTab->GetNextFunction()) {
+ if (func->GetType() == ftDrawText) {
+ usedFonts.push_back(pair<string,int>(func->GetFontName(), func->GetNumericParameter(ptFontSize)));
+ }
+ }
+ }
+}
+
+void cTemplate::CacheImages(cTemplateView *view) {
+ //used images in viewElements
+ view->InitViewElementIterator();
+ cTemplateViewElement *viewElement = NULL;
+ while(viewElement = view->GetNextViewElement()) {
+ viewElement->InitIterator();
+ cTemplatePixmap *pix = NULL;
+ while(pix = viewElement->GetNextPixmap()) {
+ pix->InitIterator();
+ cTemplateFunction *func = NULL;
+ while(func = pix->GetNextFunction()) {
+ if (func->GetType() == ftDrawImage) {
+ CacheImage(func);
+ }
+ }
+ }
+ }
+ //used images in viewLists pixmaps
+ view->InitViewListIterator();
+ cTemplateViewList *viewList = NULL;
+ while(viewList = view->GetNextViewList()) {
+ viewList->InitIterator();
+ cTemplatePixmap *pix = NULL;
+ while(pix = viewList->GetNextPixmap()) {
+ pix->InitIterator();
+ cTemplateFunction *func = NULL;
+ while(func = pix->GetNextFunction()) {
+ if (func->GetType() == ftDrawImage) {
+ CacheImage(func);
+ }
+ }
+ }
+ cTemplateViewElement *listElement = viewList->GetListElement();
+ listElement->InitIterator();
+ while(pix = listElement->GetNextPixmap()) {
+ pix->InitIterator();
+ cTemplateFunction *func = NULL;
+ while(func = pix->GetNextFunction()) {
+ if (func->GetType() == ftDrawImage) {
+ CacheImage(func);
+ }
+ }
+ }
+ }
+ //used logos in viewTabs
+ view->InitViewTabIterator();
+ cTemplateViewTab *viewTab = NULL;
+ while(viewTab = view->GetNextViewTab()) {
+ viewTab->InitIterator();
+ cTemplateFunction *func = NULL;
+ while(func = viewTab->GetNextFunction()) {
+ if (func->GetType() == ftDrawImage) {
+ CacheImage(func);
+ }
+ }
+ }
+}
+
+void cTemplate::CacheImage(cTemplateFunction *func) {
+ eImageType imgType = (eImageType)func->GetNumericParameter(ptImageType);
+ int width = func->GetNumericParameter(ptWidth);
+ int height = func->GetNumericParameter(ptHeight);
+
+ switch (imgType) {
+ case itIcon:
+ case itMenuIcon: {
+ string path = func->GetParameter(ptPath);
+ imgCache->CacheIcon(imgType, path, width, height);
+ break; }
+ case itChannelLogo: {
+ string doCache = func->GetParameter(ptCache);
+ if (!doCache.compare("true")) {
+ imgCache->CacheLogo(width, height);
+ }
+ break; }
+ case itSkinPart: {
+ string path = func->GetParameter(ptPath);
+ imgCache->CacheSkinpart(path, width, height);
+ break; }
+ default:
+ break;
+ }
+}
diff --git a/libtemplate/template.h b/libtemplate/template.h
new file mode 100644
index 0000000..a4ef238
--- /dev/null
+++ b/libtemplate/template.h
@@ -0,0 +1,57 @@
+#ifndef __TEMPLATE_H
+#define __TEMPLATE_H
+
+#include <iostream>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string>
+#include <vector>
+#include <map>
+#include <set>
+#include <sstream>
+
+#include "globals.h"
+#include "templateview.h"
+#include "templateviewelement.h"
+#include "templatepixmap.h"
+#include "templatefunction.h"
+
+using namespace std;
+
+// --- cTemplate -------------------------------------------------------------
+enum eViewType {
+ vtDisplayChannel,
+ vtDisplayMenu,
+ vtDisplayReplay,
+ vtDisplayVolume,
+ vtDisplayAudioTracks,
+ vtDisplayMessage
+};
+
+class cTemplate {
+private:
+ eViewType viewType;
+ void CacheImage(cTemplateFunction *func);
+protected:
+ cGlobals *globals;
+ cTemplateView *rootView;
+ void CreateView(void);
+ void GetUsedFonts(cTemplateView *view, vector< pair<string, int> > &usedFonts);
+ void CacheImages(cTemplateView *view);
+public:
+ cTemplate(eViewType viewType);
+ virtual ~cTemplate(void);
+ bool ReadFromXML(void);
+ void SetGlobals(cGlobals *globals);
+ cTemplateView *GetRootView(void) { return rootView; };
+ void Translate(void);
+ void PreCache(void);
+ //get fonts for pre caching
+ vector< pair<string, int> > GetUsedFonts(void);
+ void CacheImages(void);
+ //Debug
+ void Debug(void);
+};
+
+#endif //__TEMPLATE_H \ No newline at end of file
diff --git a/libtemplate/templatefunction.c b/libtemplate/templatefunction.c
new file mode 100644
index 0000000..9dca94e
--- /dev/null
+++ b/libtemplate/templatefunction.c
@@ -0,0 +1,1474 @@
+#include "templatefunction.h"
+#include "../config.h"
+#include "../libcore/helpers.h"
+
+using namespace std;
+
+// --- cTemplateFunction -------------------------------------------------------------
+
+cTemplateFunction::cTemplateFunction(eFuncType type) {
+ this->type = type;
+ debug = false;
+ containerX = 0;
+ containerY = 0;
+ containerWidth = 0;
+ containerHeight = 0;
+ columnWidth = -1;
+ rowHeight = -1;
+ globals = NULL;
+ condParam = NULL;
+ parsedCompletely = false;
+ updated = false;
+ alreadyCutted = false;
+ parsedTextWidth = 0;
+ fontName = "";
+ imgPath = "";
+ textboxHeight = 0;
+ stringTokens = NULL;
+ intTokens = NULL;
+ parsedText = "";
+ cuttedText = "";
+}
+
+cTemplateFunction::~cTemplateFunction(void) {
+ if (condParam)
+ delete condParam;
+}
+
+/*******************************************************************
+* Public Functions
+*******************************************************************/
+
+void cTemplateFunction::SetParameters(vector<pair<string, string> > params) {
+ for (vector<pair<string, string> >::iterator it = params.begin(); it != params.end(); it++) {
+ string name = it->first;
+ pair< eParamType, string > p;
+ if (!name.compare("debug")) {
+ string value = it->second;
+ if (!value.compare("true")) {
+ debug = true;
+ }
+ continue;
+ } else if (!name.compare("condition")) {
+ p.first = ptCond;
+ } else if (!name.compare("name")) {
+ p.first = ptName;
+ } else if (!name.compare("x")) {
+ p.first = ptX;
+ } else if (!name.compare("y")) {
+ p.first = ptY;
+ } else if (!name.compare("width")) {
+ p.first = ptWidth;
+ } else if (!name.compare("height")) {
+ p.first = ptHeight;
+ } else if (!name.compare("menuitemwidth")) {
+ p.first = ptMenuItemWidth;
+ } else if (!name.compare("fadetime")) {
+ p.first = ptFadeTime;
+ } else if (!name.compare("imagetype")) {
+ p.first = ptImageType;
+ } else if (!name.compare("path")) {
+ p.first = ptPath;
+ } else if (!name.compare("color")) {
+ p.first = ptColor;
+ } else if (!name.compare("font")) {
+ p.first = ptFont;
+ } else if (!name.compare("fontsize")) {
+ p.first = ptFontSize;
+ } else if (!name.compare("text")) {
+ p.first = ptText;
+ } else if (!name.compare("layer")) {
+ p.first = ptLayer;
+ } else if (!name.compare("transparency")) {
+ p.first = ptTransparency;
+ } else if (!name.compare("quadrant")) {
+ p.first = ptQuadrant;
+ } else if (!name.compare("align")) {
+ p.first = ptAlign;
+ } else if (!name.compare("valign")) {
+ p.first = ptValign;
+ } else if (!name.compare("delay")) {
+ p.first = ptDelay;
+ } else if (!name.compare("mode")) {
+ p.first = ptScrollMode;
+ } else if (!name.compare("scrollspeed")) {
+ p.first = ptScrollSpeed;
+ } else if (!name.compare("orientation")) {
+ p.first = ptOrientation;
+ } else if (!name.compare("numlistelements")) {
+ p.first = ptNumElements;
+ } else if (!name.compare("scrollelement")) {
+ p.first = ptScrollElement;
+ } else if (!name.compare("scrollheight")) {
+ p.first = ptScrollHeight;
+ } else if (!name.compare("float")) {
+ p.first = ptFloat;
+ } else if (!name.compare("floatwidth")) {
+ p.first = ptFloatWidth;
+ } else if (!name.compare("floatheight")) {
+ p.first = ptFloatHeight;
+ } else if (!name.compare("maxlines")) {
+ p.first = ptMaxLines;
+ } else if (!name.compare("columnwidth")) {
+ p.first = ptColumnWidth;
+ } else if (!name.compare("rowheight")) {
+ p.first = ptRowHeight;
+ } else if (!name.compare("overflow")) {
+ p.first = ptOverflow;
+ } else if (!name.compare("scaletvx")) {
+ p.first = ptScaleTvX;
+ } else if (!name.compare("scaletvy")) {
+ p.first = ptScaleTvY;
+ } else if (!name.compare("scaletvwidth")) {
+ p.first = ptScaleTvWidth;
+ } else if (!name.compare("scaletvheight")) {
+ p.first = ptScaleTvHeight;
+ } else if (!name.compare("cache")) {
+ p.first = ptCache;
+ } else if (!name.compare("determinatefont")) {
+ p.first = ptDeterminateFont;
+ } else {
+ p.first = ptNone;
+ }
+ p.second = it->second;
+ nativeParameters.insert(p);
+ }
+}
+
+void cTemplateFunction::SetParameter(eParamType type, string value) {
+ nativeParameters.erase(type);
+ nativeParameters.insert(pair<eParamType, string>(type, value));
+}
+
+void cTemplateFunction::SetContainer(int x, int y, int w, int h) {
+ containerX = x;
+ containerY = y;
+ containerWidth = w;
+ containerHeight = h;
+}
+
+void cTemplateFunction::SetLoopContainer(int columnWidth, int rowHeight) {
+ this->columnWidth = columnWidth;
+ this->rowHeight = rowHeight;
+}
+
+void cTemplateFunction::SetWidthManually(string width) {
+ nativeParameters.erase(ptWidth);
+ nativeParameters.insert(pair<eParamType, string>(ptWidth, width));
+}
+
+void cTemplateFunction::SetHeightManually(string height) {
+ nativeParameters.erase(ptHeight);
+ nativeParameters.insert(pair<eParamType, string>(ptHeight, height));
+}
+
+void cTemplateFunction::SetXManually(int newX) {
+ numericParameters.erase(ptX);
+ numericParameters.insert(pair<eParamType, int>(ptX, newX));
+}
+
+void cTemplateFunction::SetYManually(int newY) {
+ numericParameters.erase(ptY);
+ numericParameters.insert(pair<eParamType, int>(ptY, newY));
+}
+
+void cTemplateFunction::SetTextboxHeight(int boxHeight) {
+ numericParameters.erase(ptHeight);
+ numericParameters.insert(pair<eParamType, int>(ptHeight, boxHeight));
+}
+
+void cTemplateFunction::SetTranslatedText(string translation) {
+ if (type != ftDrawText && type != ftDrawTextBox)
+ return;
+ if (translation.size() == 0)
+ return;
+ nativeParameters.erase(ptText);
+ nativeParameters.insert(pair<eParamType, string>(ptText, translation));
+}
+
+void cTemplateFunction::SetMaxTextWidth(int maxWidth) {
+ if (type != ftDrawText)
+ return;
+ numericParameters.erase(ptWidth);
+ numericParameters.insert(pair<eParamType, int>(ptWidth, maxWidth));
+}
+
+bool cTemplateFunction::CalculateParameters(void) {
+ bool paramValid = true;
+ bool paramsValid = true;
+ for (map< eParamType, string >::iterator param = nativeParameters.begin(); param != nativeParameters.end(); param++) {
+ paramValid = true;
+ eParamType type = param->first;
+ string value = param->second;
+ switch (type) {
+ case ptCond:
+ paramValid = SetCondition(value);
+ break;
+ case ptX:
+ case ptY:
+ case ptWidth:
+ case ptHeight:
+ case ptMenuItemWidth:
+ case ptFadeTime:
+ case ptDelay:
+ case ptFontSize:
+ case ptLayer:
+ case ptTransparency:
+ case ptQuadrant:
+ case ptNumElements:
+ case ptFloatWidth:
+ case ptFloatHeight:
+ case ptMaxLines:
+ case ptColumnWidth:
+ case ptRowHeight:
+ case ptScaleTvX:
+ case ptScaleTvY:
+ case ptScaleTvWidth:
+ case ptScaleTvHeight:
+ SetNumericParameter(type, value);
+ break;
+ case ptAlign:
+ case ptValign:
+ paramValid = SetAlign(type, value);
+ break;
+ case ptImageType:
+ paramValid = SetImageType(type, value);
+ break;
+ case ptColor:
+ paramValid = SetColor(type, value);
+ break;
+ case ptFont:
+ paramValid = SetFont(type, value);
+ break;
+ case ptText:
+ paramValid = SetTextTokens(value);
+ break;
+ case ptScrollMode:
+ paramValid = SetScrollMode(value);
+ break;
+ case ptScrollSpeed:
+ paramValid = SetScrollSpeed(value);
+ break;
+ case ptOrientation:
+ paramValid = SetOrientation(value);
+ break;
+ case ptFloat:
+ paramValid = SetFloating(value);
+ break;
+ case ptOverflow:
+ paramValid = SetOverflow(value);
+ default:
+ paramValid = true;
+ break;
+ }
+ if (!paramValid) {
+ paramsValid = false;
+ esyslog("skindesigner: %s: invalid parameter %d, value %s", GetFuncName().c_str(), type, value.c_str());
+ }
+ }
+ return paramsValid;
+}
+
+void cTemplateFunction::CompleteParameters(void) {
+ switch (type) {
+ case ftDrawImage: {
+ //Calculate img size
+ if ((GetNumericParameter(ptImageType) == itChannelLogo)||(GetNumericParameter(ptImageType) == itSepLogo)) {
+ int logoWidthOrig = config.logoWidth;
+ int logoHeightOrig = config.logoHeight;
+ int logoWidth = GetNumericParameter(ptWidth);
+ int logoHeight = GetNumericParameter(ptHeight);
+ if (logoWidth <= 0 && logoHeight <= 0)
+ break;
+ if (logoWidth <= 0 && logoHeightOrig > 0) {
+ logoWidth = logoHeight * logoWidthOrig / logoHeightOrig;
+ numericParameters.erase(ptWidth);
+ numericParameters.insert(pair<eParamType,int>(ptWidth, logoWidth));
+ } else if (logoHeight <= 0 && logoWidthOrig > 0) {
+ logoHeight = logoWidth * logoHeightOrig / logoWidthOrig;
+ numericParameters.erase(ptHeight);
+ numericParameters.insert(pair<eParamType,int>(ptHeight, logoHeight));
+ }
+ }
+ CalculateAlign(GetNumericParameter(ptWidth), GetNumericParameter(ptHeight));
+ if (imgPath.size() == 0) {
+ imgPath = GetParameter(ptPath);
+ }
+ break; }
+ case ftDrawRectangle:
+ CalculateAlign(GetNumericParameter(ptWidth), GetNumericParameter(ptHeight));
+ break;
+ case ftDrawEllipse:
+ CalculateAlign(GetNumericParameter(ptWidth), GetNumericParameter(ptHeight));
+ break;
+ case ftDrawText:
+ CalculateAlign(GetWidth(), GetHeight());
+ break;
+ default:
+ break;
+ }
+}
+
+void cTemplateFunction::ClearDynamicParameters(void) {
+ parsedText = "";
+ cuttedText = "";
+ alreadyCutted = false;
+ parsedTextWidth = 0;
+ textboxHeight = 0;
+
+ //clear dynamically parsed int parameters
+ for (map<eParamType,string>::iterator it = numericDynamicParameters.begin(); it != numericDynamicParameters.end(); it++) {
+ numericParameters.erase(it->first);
+ }
+ //restoring dynamic numeric parameters only if x, y, width or height of other elements is needed dynamically
+ for (map<eParamType,string>::iterator it = nativeParameters.begin(); it != nativeParameters.end(); it++) {
+ eParamType paramType = it->first;
+ if (paramType == ptX ||
+ paramType == ptY ||
+ paramType == ptWidth ||
+ paramType == ptHeight ||
+ paramType == ptFloatWidth ||
+ paramType == ptFloatHeight)
+ {
+ string value = it->second;
+ if (value.find("{width(") != string::npos || value.find("{height(") != string::npos || value.find("{posx(") != string::npos || value.find("{posy(") != string::npos) {
+ numericDynamicParameters.erase(paramType);
+ SetNumericParameter(paramType, value);
+ }
+ }
+ }
+
+}
+
+bool cTemplateFunction::ParseParameters(void) {
+ updated = false;
+ parsedCompletely = true;
+
+ if (stringTokens) {
+ ParseStringParameters();
+ }
+
+ if (intTokens && numericDynamicParameters.size() > 0) {
+ ParseNumericalParameters();
+ }
+
+ if (condParam) {
+ condParam->Evaluate(intTokens, stringTokens);
+ }
+
+ return parsedCompletely;
+}
+
+string cTemplateFunction::GetParameter(eParamType type) {
+ map<eParamType,string>::iterator hit = nativeParameters.find(type);
+ if (hit == nativeParameters.end())
+ return "";
+ return hit->second;
+}
+
+int cTemplateFunction::GetNumericParameter(eParamType type) {
+ map<eParamType,int>::iterator hit = numericParameters.find(type);
+ if (hit == numericParameters.end()) {
+ //Set Default Value for Integer Parameters
+ if (type == ptLayer)
+ return 1;
+ else if (type == ptTransparency)
+ return 0;
+ else if (type == ptDelay)
+ return 0;
+ else if (type == ptFadeTime)
+ return 0;
+ else if (type == ptMenuItemWidth)
+ return 0;
+ return -1;
+ }
+ return hit->second;
+}
+
+string cTemplateFunction::GetText(bool cut) {
+ if (!cut) {
+ return parsedText;
+ }
+ if (alreadyCutted && cuttedText.size() > 0) {
+ return cuttedText;
+ }
+ alreadyCutted = true;
+ int maxWidth = GetNumericParameter(ptWidth);
+ if (maxWidth > 0) {
+ parsedTextWidth = fontManager->Width(fontName, GetNumericParameter(ptFontSize), parsedText.c_str());
+ if (parsedTextWidth > maxWidth) {
+ cuttedText = CutText(parsedText, maxWidth, fontName, GetNumericParameter(ptFontSize));
+ return cuttedText;
+ }
+ }
+ return parsedText;
+}
+
+
+tColor cTemplateFunction::GetColorParameter(eParamType type) {
+ map<eParamType,tColor>::iterator hit = colorParameters.find(type);
+ if (hit == colorParameters.end())
+ return 0x00000000;
+ return hit->second;
+}
+
+int cTemplateFunction::GetWidth(bool cutted) {
+ int funcWidth = 0;
+ switch (type) {
+ case ftDrawText: {
+ if (cutted) {
+ if (!alreadyCutted) {
+ alreadyCutted = true;
+ int maxWidth = GetNumericParameter(ptWidth);
+ if (maxWidth > 0) {
+ parsedTextWidth = fontManager->Width(fontName, GetNumericParameter(ptFontSize), parsedText.c_str());
+ if (parsedTextWidth > maxWidth) {
+ cuttedText = CutText(parsedText, maxWidth, fontName, GetNumericParameter(ptFontSize));
+ }
+ }
+ }
+ if (cuttedText.size() > 0)
+ return fontManager->Width(fontName, GetNumericParameter(ptFontSize), cuttedText.c_str());
+ }
+ if (parsedTextWidth > 0)
+ funcWidth = parsedTextWidth;
+ else
+ funcWidth = fontManager->Width(fontName, GetNumericParameter(ptFontSize), parsedText.c_str());
+ break; }
+ case ftFill:
+ case ftDrawImage:
+ case ftDrawRectangle:
+ case ftDrawEllipse:
+ case ftDrawTextBox:
+ funcWidth = GetNumericParameter(ptWidth);
+ break;
+ default:
+ esyslog("skindesigner: GetWidth not implemented for funcType %d", type);
+ break;
+ }
+ return funcWidth;
+}
+
+int cTemplateFunction::GetHeight(void) {
+ int funcHeight = 0;
+ switch (type) {
+ case ftDrawText:
+ funcHeight = fontManager->Height(fontName, GetNumericParameter(ptFontSize));
+ break;
+ case ftFill:
+ case ftDrawImage:
+ case ftDrawRectangle:
+ case ftDrawEllipse:
+ funcHeight = GetNumericParameter(ptHeight);
+ break;
+ case ftDrawTextBox: {
+ int maxLines = GetNumericParameter(ptMaxLines);
+ int fixedBoxHeight = GetNumericParameter(ptHeight);
+ if (maxLines > 0) {
+ funcHeight = maxLines * fontManager->Height(fontName, GetNumericParameter(ptFontSize));
+ } else if (fixedBoxHeight > 0) {
+ funcHeight = fixedBoxHeight;
+ } else if (textboxHeight > 0) {
+ funcHeight = textboxHeight;
+ } else {
+ funcHeight = CalculateTextBoxHeight();
+ textboxHeight = funcHeight;
+ }
+ break; }
+ case ftLoop:
+ //TODO: to be implemented
+ break;
+ default:
+ esyslog("skindesigner: GetHeight not implemented for funcType %d", type);
+ break;
+ }
+ return funcHeight;
+}
+
+void cTemplateFunction::GetNeededWidths(multimap<eParamType,string> *widths) {
+ for (map<eParamType, string>::iterator param = numericDynamicParameters.begin(); param !=numericDynamicParameters.end(); param++) {
+ string val = param->second;
+ size_t posStart = val.find("{width(");
+ while (posStart != string::npos) {
+ size_t posEnd = val.find(")", posStart+1);
+ if (posEnd != string::npos) {
+ string label = val.substr(posStart+7, posEnd - posStart - 7);
+ widths->insert(pair<eParamType,string>(param->first, label));
+ val = val.replace(posStart, posEnd - posStart, "");
+ } else {
+ break;
+ }
+ posStart = val.find("{width(");
+ }
+ }
+}
+
+void cTemplateFunction::GetNeededHeights(multimap<eParamType,string> *heights) {
+ for (map<eParamType, string>::iterator param = numericDynamicParameters.begin(); param !=numericDynamicParameters.end(); param++) {
+ string val = param->second;
+ size_t posStart = val.find("{height(");
+ while (posStart != string::npos) {
+ size_t posEnd = val.find(")", posStart + 1);
+ if (posEnd != string::npos) {
+ string label = val.substr(posStart + 8, posEnd - posStart - 8);
+ heights->insert(pair<eParamType,string>(param->first, label));
+ val = val.replace(posStart, posEnd - posStart, "");
+ } else {
+ break;
+ }
+ posStart = val.find("{height(");
+ }
+ }
+}
+
+void cTemplateFunction::GetNeededPosX(multimap<eParamType,string> *posXs) {
+ for (map<eParamType, string>::iterator param = numericDynamicParameters.begin(); param !=numericDynamicParameters.end(); param++) {
+ string val = param->second;
+ size_t posStart = val.find("{posx(");
+ while (posStart != string::npos) {
+ size_t posEnd = val.find(")", posStart+1);
+ if (posEnd != string::npos) {
+ string label = val.substr(posStart+6, posEnd - posStart - 6);
+ posXs->insert(pair<eParamType,string>(param->first, label));
+ val = val.replace(posStart, posEnd - posStart, "");
+ } else {
+ break;
+ }
+ posStart = val.find("{posx(");
+ }
+ }
+}
+
+void cTemplateFunction::GetNeededPosY(multimap<eParamType,string> *posYs) {
+ for (map<eParamType, string>::iterator param = numericDynamicParameters.begin(); param !=numericDynamicParameters.end(); param++) {
+ string val = param->second;
+ size_t posStart = val.find("{posy(");
+ while (posStart != string::npos) {
+ size_t posEnd = val.find(")", posStart+1);
+ if (posEnd != string::npos) {
+ string label = val.substr(posStart+6, posEnd - posStart - 6);
+ posYs->insert(pair<eParamType,string>(param->first, label));
+ val = val.replace(posStart, posEnd - posStart, "");
+ } else {
+ break;
+ }
+ posStart = val.find("{posy(");
+ }
+ }
+}
+
+void cTemplateFunction::SetWidth(eParamType type, string label, int funcWidth) {
+ updated = false;
+ map< eParamType, string >::iterator hit = numericDynamicParameters.find(type);
+ if (hit == numericDynamicParameters.end())
+ return;
+ stringstream needle;
+ needle << "{width(" << label << ")}";
+ size_t posFound = (hit->second).find(needle.str());
+ if (posFound == string::npos)
+ return;
+ stringstream repl;
+ repl << funcWidth;
+ string parsedVal = (hit->second).replace(posFound, needle.str().size(), repl.str());
+
+ cNumericParameter param(parsedVal);
+ param.SetAreaSize(containerWidth, containerHeight);
+ param.SetGlobals(globals);
+ int val = param.Parse(parsedVal);
+ if (param.Valid()) {
+ updated = true;
+ numericParameters.insert(pair<eParamType, int>(type, val));
+ } else {
+ numericDynamicParameters.erase(type);
+ numericDynamicParameters.insert(pair<eParamType, string>(type, parsedVal));
+ }
+}
+
+void cTemplateFunction::SetHeight(eParamType type, string label, int funcHeight) {
+ updated = false;
+ map< eParamType, string >::iterator hit = numericDynamicParameters.find(type);
+ if (hit == numericDynamicParameters.end())
+ return;
+ stringstream needle;
+ needle << "{height(" << label << ")}";
+ size_t posFound = (hit->second).find(needle.str());
+ if (posFound == string::npos)
+ return;
+ stringstream repl;
+ repl << funcHeight;
+ string parsedVal = (hit->second).replace(posFound, needle.str().size(), repl.str());
+
+ cNumericParameter param(parsedVal);
+ param.SetAreaSize(containerWidth, containerHeight);
+ param.SetGlobals(globals);
+ int val = param.Parse(parsedVal);
+ if (param.Valid()) {
+ updated = true;
+ numericParameters.insert(pair<eParamType, int>(type, val));
+ } else {
+ numericDynamicParameters.erase(type);
+ numericDynamicParameters.insert(pair<eParamType, string>(type, parsedVal));
+ }
+}
+
+void cTemplateFunction::SetX(eParamType type, string label, int funcX) {
+ updated = false;
+ map< eParamType, string >::iterator hit = numericDynamicParameters.find(type);
+ if (hit == numericDynamicParameters.end())
+ return;
+ stringstream needle;
+ needle << "{posx(" << label << ")}";
+ size_t posFound = (hit->second).find(needle.str());
+ if (posFound == string::npos)
+ return;
+ stringstream repl;
+ repl << funcX;
+ string parsedVal = (hit->second).replace(posFound, needle.str().size(), repl.str());
+
+ cNumericParameter param(parsedVal);
+ param.SetAreaSize(containerWidth, containerHeight);
+ param.SetGlobals(globals);
+ int val = param.Parse(parsedVal);
+ if (param.Valid()) {
+ updated = true;
+ numericParameters.insert(pair<eParamType, int>(type, val));
+ } else {
+ numericDynamicParameters.erase(type);
+ numericDynamicParameters.insert(pair<eParamType, string>(type, parsedVal));
+ }
+}
+
+void cTemplateFunction::SetY(eParamType type, string label, int funcY) {
+ updated = false;
+ map< eParamType, string >::iterator hit = numericDynamicParameters.find(type);
+ if (hit == numericDynamicParameters.end())
+ return;
+ stringstream needle;
+ needle << "{posy(" << label << ")}";
+ size_t posFound = (hit->second).find(needle.str());
+ if (posFound == string::npos)
+ return;
+ stringstream repl;
+ repl << funcY;
+ string parsedVal = (hit->second).replace(posFound, needle.str().size(), repl.str());
+
+ cNumericParameter param(parsedVal);
+ param.SetAreaSize(containerWidth, containerHeight);
+ param.SetGlobals(globals);
+ int val = param.Parse(parsedVal);
+ if (param.Valid()) {
+ updated = true;
+ numericParameters.insert(pair<eParamType, int>(type, val));
+ } else {
+ numericDynamicParameters.erase(type);
+ numericDynamicParameters.insert(pair<eParamType, string>(type, parsedVal));
+ }
+}
+
+bool cTemplateFunction::DoExecute(void) {
+ if (!condParam)
+ return true;
+ return condParam->IsTrue();
+}
+
+/*******************************************************************
+* Private Functions
+*******************************************************************/
+
+bool cTemplateFunction::SetCondition(string cond) {
+ if (condParam)
+ delete condParam;
+ condParam = new cConditionalParameter(globals, cond);
+ condParam->Tokenize();
+ return true;
+}
+
+
+bool cTemplateFunction::SetNumericParameter(eParamType type, string value) {
+ if (config.replaceDecPoint) {
+ if (value.find_first_of('.') != string::npos) {
+ std::replace( value.begin(), value.end(), '.', config.decPoint);
+ }
+ }
+
+ cNumericParameter param(value);
+ param.SetAreaSize(containerWidth, containerHeight);
+ param.SetLoopContainer(columnWidth, rowHeight);
+ param.SetGlobals(globals);
+ switch (type) {
+ case ptX:
+ case ptWidth:
+ case ptMenuItemWidth:
+ case ptScaleTvX:
+ case ptScaleTvWidth:
+ param.SetHorizontal();
+ break;
+ case ptY:
+ case ptHeight:
+ case ptFontSize:
+ case ptScaleTvY:
+ case ptScaleTvHeight:
+ param.SetVertical();
+ break;
+ case ptLayer:
+ param.SetDefault(1);
+ break;
+ default:
+ break;
+ }
+ string parsedValue = "";
+ int val = param.Parse(parsedValue);
+ if (param.Valid()) {
+ if (this->type < ftLoop && type == ptX) {
+ val += containerX;
+ }
+ if (this->type < ftLoop && type == ptY) {
+ val += containerY;
+ }
+ numericParameters.insert(pair<eParamType, int>(type, val));
+ } else {
+ numericDynamicParameters.insert(pair<eParamType, string>(type, parsedValue));
+ }
+ return param.Valid();
+}
+
+bool cTemplateFunction::SetAlign(eParamType type, string value) {
+ eAlign align = alLeft;
+ bool ok = true;
+ if (!value.compare("center")) {
+ align = alCenter;
+ } else if (!value.compare("right")) {
+ align = alRight;
+ } else if (!value.compare("top")) {
+ align = alTop;
+ } else if (!value.compare("bottom")) {
+ align = alBottom;
+ } else if (!value.compare("left")) {
+ align = alLeft;
+ } else {
+ ok = false;
+ }
+ numericParameters.insert(pair<eParamType, int>(type, align));
+ return ok;
+}
+
+bool cTemplateFunction::SetFont(eParamType type, string value) {
+ //check if token
+ if ((value.find("{") == 0) && (value.find("}") == (value.size()-1))) {
+ value = value.substr(1, value.size()-2);
+ map<string,string>::iterator hit = globals->fonts.find(value);
+ if (hit != globals->fonts.end()) {
+ fontName = hit->second;
+ } else {
+ map<string,string>::iterator def = globals->fonts.find("vdrOsd");
+ if (def == globals->fonts.end())
+ return false;
+ fontName = def->second;
+ }
+ } else {
+ //if no token, directly use input
+ fontName = value;
+ }
+ return true;
+}
+
+bool cTemplateFunction::SetImageType(eParamType type, string value) {
+ eImageType imgType = itImage;
+ bool ok = true;
+ if (!value.compare("channellogo")) {
+ imgType = itChannelLogo;
+ } else if (!value.compare("seplogo")) {
+ imgType = itSepLogo;
+ } else if (!value.compare("skinpart")) {
+ imgType = itSkinPart;
+ } else if (!value.compare("menuicon")) {
+ imgType = itMenuIcon;
+ } else if (!value.compare("icon")) {
+ imgType = itIcon;
+ } else if (!value.compare("image")) {
+ imgType = itImage;
+ } else {
+ ok = false;
+ }
+ numericParameters.insert(pair<eParamType, int>(ptImageType, imgType));
+ return ok;
+}
+
+
+bool cTemplateFunction::SetColor(eParamType type, string value) {
+ if (globals) {
+ for (map<string, tColor>::iterator col = globals->colors.begin(); col != globals->colors.end(); col++) {
+ stringstream sColName;
+ sColName << "{" << col->first << "}";
+ string colName = sColName.str();
+ if (!colName.compare(value)) {
+ tColor colVal = col->second;
+ colorParameters.insert(pair<eParamType, tColor>(type, colVal));
+ return true;
+ }
+ }
+ }
+ if (value.size() != 8)
+ return false;
+ std::stringstream str;
+ str << value;
+ tColor colVal;
+ str >> std::hex >> colVal;
+ colorParameters.insert(pair<eParamType, tColor>(type, colVal));
+ return true;
+}
+
+bool cTemplateFunction::SetTextTokens(string value) {
+ textTokens.clear();
+ //first replace globals
+ for (map<string,string>::iterator globStr = globals->stringVars.begin(); globStr != globals->stringVars.end(); globStr++) {
+ stringstream sToken;
+ sToken << "{" << globStr->first << "}";
+ string token = sToken.str();
+ size_t foundToken = value.find(token);
+ if (foundToken != string::npos) {
+ value = value.replace(foundToken, token.size(), globStr->second);
+ }
+ }
+ //now tokenize
+ bool tokenFound = true;
+ while (tokenFound) {
+ //search for conditional token or normal token
+ size_t tokenStart = value.find_first_of('{');
+ size_t conditionStart = value.find_first_of('|');
+ if (tokenStart == string::npos && conditionStart == string::npos) {
+ if (value.size() > 0) {
+ cTextToken token;
+ token.type = ttConstString;
+ token.value = value;
+ textTokens.push_back(token);
+ }
+ tokenFound = false;
+ continue;
+ } else if (tokenStart != string::npos && conditionStart == string::npos) {
+ size_t tokenEnd = value.find_first_of('}');
+ ParseTextToken(value, tokenStart, tokenEnd);
+ } else if (tokenStart != string::npos && conditionStart != string::npos) {
+ if (tokenStart < conditionStart) {
+ size_t tokenEnd = value.find_first_of('}');
+ ParseTextToken(value, tokenStart, tokenEnd);
+ } else {
+ size_t conditionEnd = value.find_first_of('|', conditionStart+1);
+ ParseConditionalTextToken(value, conditionStart, conditionEnd);
+ }
+ }
+ }
+ return true;
+}
+
+void cTemplateFunction::ParseTextToken(string &value, size_t start, size_t end) {
+ cTextToken token;
+ if (start > 0) {
+ string constString = value.substr(0, start);
+ value = value.replace(0, start, "");
+ token.type = ttConstString;
+ token.value = constString;
+ textTokens.push_back(token);
+ } else {
+ string tokenName = value.substr(1, end - start - 1);
+ value = value.replace(0, end - start + 1, "");
+ token.type = ttToken;
+ token.value = tokenName;
+ textTokens.push_back(token);
+ }
+}
+
+void cTemplateFunction::ParseConditionalTextToken(string &value, size_t start, size_t end) {
+ cTextToken token;
+ if (start > 0) {
+ string constString = value.substr(0, start);
+ value = value.replace(0, start, "");
+ token.type = ttConstString;
+ token.value = constString;
+ textTokens.push_back(token);
+ } else {
+ string condToken = value.substr(start + 1, end - start - 1);
+ value = value.replace(0, end - start + 1, "");
+ size_t tokenStart = condToken.find_first_of('{');
+ size_t tokenEnd = condToken.find_first_of('}');
+ vector<cTextToken> subTokens;
+ if (tokenStart > 0) {
+ cTextToken subToken;
+ string constString = condToken.substr(0, tokenStart);
+ condToken = condToken.replace(0, tokenStart, "");
+ subToken.type = ttConstString;
+ subToken.value = constString;
+ subTokens.push_back(subToken);
+ }
+ string tokenName = condToken.substr(1, tokenEnd - tokenStart - 1);
+ condToken = condToken.replace(0, tokenEnd - tokenStart + 1, "");
+
+ cTextToken subToken2;
+ subToken2.type = ttToken;
+ subToken2.value = tokenName;
+ subTokens.push_back(subToken2);
+
+ if (condToken.size() > 0) {
+ cTextToken subToken3;
+ subToken3.type = ttConstString;
+ subToken3.value = condToken;
+ subTokens.push_back(subToken3);
+ }
+
+ token.type = ttConditionalToken;
+ token.value = tokenName;
+ token.subTokens = subTokens;
+ textTokens.push_back(token);
+ }
+
+}
+
+bool cTemplateFunction::SetScrollMode(string value) {
+ eScrollMode mode = smNone;
+ bool ok = true;
+ if (!value.compare("forthandback"))
+ mode = smForthAndBack;
+ else if (!value.compare("carriagereturn"))
+ mode = smCarriageReturn;
+ else
+ ok = false;
+ numericParameters.insert(pair<eParamType, int>(ptScrollMode, mode));
+ return ok;
+}
+
+bool cTemplateFunction::SetScrollSpeed(string value) {
+ eScrollSpeed speed = ssMedium;
+ bool ok = true;
+ if (!value.compare("slow"))
+ speed = ssSlow;
+ else if (!value.compare("fast"))
+ speed = ssFast;
+ else if (!value.compare("medium"))
+ speed = ssMedium;
+ else
+ ok = false;
+ numericParameters.insert(pair<eParamType, int>(ptScrollSpeed, speed));
+ return ok;
+
+}
+
+bool cTemplateFunction::SetOrientation(string value) {
+ eOrientation orientation = orNone;
+ bool ok = true;
+ if (!value.compare("horizontal"))
+ orientation = orHorizontal;
+ else if (!value.compare("vertical"))
+ orientation = orVertical;
+ else if (!value.compare("absolute"))
+ orientation = orAbsolute;
+ else
+ ok = false;
+ numericParameters.insert(pair<eParamType, int>(ptOrientation, orientation));
+ return ok;
+}
+
+bool cTemplateFunction::SetFloating(string value) {
+ eFloatType floatType = flNone;
+ bool ok = true;
+ if (!value.compare("topleft"))
+ floatType = flTopLeft;
+ else if (!value.compare("topright"))
+ floatType = flTopRight;
+ else
+ ok = false;
+ numericParameters.insert(pair<eParamType, int>(ptFloat, floatType));
+ return ok;
+}
+
+bool cTemplateFunction::SetOverflow(string value) {
+ eOverflowType overflowType = otNone;
+ bool ok = true;
+ if (!value.compare("linewrap"))
+ overflowType = otWrap;
+ else if (!value.compare("cut"))
+ overflowType = otCut;
+ else
+ ok = false;
+ numericParameters.insert(pair<eParamType, int>(ptOverflow, overflowType));
+ return ok;
+}
+
+void cTemplateFunction::ParseStringParameters(void) {
+ //first replace stringtokens in Text (drawText)
+ stringstream text;
+ for (vector<cTextToken>::iterator it = textTokens.begin(); it !=textTokens.end(); it++) {
+ updated = true;
+ if ((*it).type == ttConstString) {
+ text << (*it).value;
+ } else if ((*it).type == ttToken) {
+ bool found = false;
+ string tokenName = (*it).value;
+ if (stringTokens) {
+ map < string, string >::iterator hit = stringTokens->find(tokenName);
+ if (hit != stringTokens->end()) {
+ text << hit->second;
+ found = true;
+ }
+ }
+ if (!found && intTokens) {
+ map < string, int >::iterator hitInt = intTokens->find(tokenName);
+ if (hitInt != intTokens->end()) {
+ text << hitInt->second;
+ found = true;
+ }
+ }
+ if (!found) {
+ text << "{" << tokenName << "}";
+ }
+ } else if ((*it).type == ttConditionalToken) {
+ bool found = false;
+ string tokenName = (*it).value;
+ if (stringTokens) {
+ map < string, string >::iterator hit = stringTokens->find(tokenName);
+ if (hit != stringTokens->end()) {
+ string replaceText = hit->second;
+ if (replaceText.size() > 0) {
+ for (vector<cTextToken>::iterator it2 = (*it).subTokens.begin(); it2 != (*it).subTokens.end(); it2++) {
+ if ((*it2).type == ttConstString) {
+ text << (*it2).value;
+ } else {
+ text << replaceText;
+ }
+ }
+ }
+ found = true;
+ }
+ }
+ if (!found && intTokens) {
+ map < string, int >::iterator hitInt = intTokens->find(tokenName);
+ if (hitInt != intTokens->end()) {
+ int intVal = hitInt->second;
+ if (intVal > 0) {
+ for (vector<cTextToken>::iterator it2 = (*it).subTokens.begin(); it2 != (*it).subTokens.end(); it2++) {
+ if ((*it2).type == ttConstString) {
+ text << (*it2).value;
+ } else {
+ text << intVal;
+ }
+ }
+ }
+ found = true;
+ }
+ }
+ }
+ }
+ parsedText = text.str();
+
+ //now check further possible string variables
+ string path = GetParameter(ptPath);
+ if (stringTokens && path.size() > 0 && path.find("{") != string::npos) {
+ for (map < string, string >::iterator it = stringTokens->begin(); it != stringTokens->end(); it++) {
+ size_t found = path.find(it->first);
+ if (found != string::npos) {
+ updated = true;
+ imgPath = path;
+ if (found > 0 && ((it->first).size() + 2 <= imgPath.size()))
+ imgPath.replace(found-1, (it->first).size() + 2, it->second);
+ break;
+ }
+ }
+ }
+}
+
+void cTemplateFunction::ParseNumericalParameters(void) {
+ parsedCompletely = true;
+ for (map<eParamType, string>::iterator param = numericDynamicParameters.begin(); param !=numericDynamicParameters.end(); param++) {
+ string val = param->second;
+ for (map<string,int >::iterator tok = intTokens->begin(); tok != intTokens->end(); tok++) {
+ stringstream sToken;
+ sToken << "{" << tok->first << "}";
+ string token = sToken.str();
+ size_t foundToken = val.find(token);
+ //replace token as often as it appears
+ while (foundToken != string::npos) {
+ stringstream sVal;
+ sVal << tok->second;
+ val = val.replace(foundToken, token.size(), sVal.str());
+ foundToken = val.find(token);
+ }
+ }
+ cNumericParameter p(val);
+ string parsedVal = "";
+ int newVal = p.Parse(parsedVal);
+ if (p.Valid()) {
+ updated = true;
+ numericParameters.insert(pair<eParamType, int>(param->first, newVal));
+ } else {
+ parsedCompletely = false;
+ }
+ }
+}
+
+void cTemplateFunction::CalculateAlign(int elementWidth, int elementHeight) {
+ int align = GetNumericParameter(ptAlign);
+ //if element is used in a loop, use loop box width
+ int boxWidth = (columnWidth > 0) ? columnWidth : containerWidth;
+ int boxHeight = (rowHeight > 0) ? rowHeight : containerHeight;
+ if (align == alCenter) {
+ int xNew = (boxWidth - elementWidth) / 2;
+ numericParameters.erase(ptX);
+ numericParameters.insert(pair<eParamType,int>(ptX, xNew));
+ } else if (align == alRight) {
+ int xNew = boxWidth - elementWidth;
+ numericParameters.erase(ptX);
+ numericParameters.insert(pair<eParamType,int>(ptX, xNew));
+ }
+
+ int vAlign = GetNumericParameter(ptValign);
+ if (vAlign == alCenter) {
+ int yNew = (boxHeight - elementHeight) / 2;
+ numericParameters.erase(ptY);
+ numericParameters.insert(pair<eParamType,int>(ptY, yNew));
+ } else if (vAlign == alBottom) {
+ int yNew = boxHeight - elementHeight;
+ numericParameters.erase(ptY);
+ numericParameters.insert(pair<eParamType,int>(ptY, yNew));
+ }
+}
+
+int cTemplateFunction::CalculateTextBoxHeight(void) {
+ int width = GetNumericParameter(ptWidth);
+ string fontName = GetFontName();
+ int fontSize = GetNumericParameter(ptFontSize);
+ string text = GetText(false);
+ const cFont *font = fontManager->Font(fontName, fontSize);
+ if (!font)
+ return 0;
+
+ int fontHeight = fontManager->Height(fontName, fontSize);
+ int floatType = GetNumericParameter(ptFloat);
+
+ if (floatType == flNone) {
+ cTextWrapper wrapper;
+ wrapper.Set(text.c_str(), font, width);
+ int lines = wrapper.Lines();
+ return (lines * fontHeight);
+ }
+
+ int floatWidth = GetNumericParameter(ptFloatWidth);
+ int floatHeight = GetNumericParameter(ptFloatHeight);
+
+ cTextWrapper wTextTall;
+ cTextWrapper wTextFull;
+
+ int linesNarrow = floatHeight / fontHeight;
+ int widthNarrow = width - floatWidth;
+ int linesDrawn = 0;
+ int curY = 0;
+ bool drawNarrow = true;
+
+ splitstring s(text.c_str());
+ vector<string> flds = s.split('\n', 1);
+
+ if (flds.size() < 1)
+ return 0;
+
+ stringstream sstrTextTall;
+ stringstream sstrTextFull;
+
+ for (int i=0; i<flds.size(); i++) {
+ if (!flds[i].size()) {
+ //empty line
+ linesDrawn++;
+ curY += fontHeight;
+ if (drawNarrow)
+ sstrTextTall << "\n";
+ else
+ sstrTextFull << "\n";
+ } else {
+ cTextWrapper wrapper;
+ if (drawNarrow) {
+ wrapper.Set((flds[i].c_str()), font, widthNarrow);
+ int newLines = wrapper.Lines();
+ //check if wrapper fits completely into narrow area
+ if (linesDrawn + newLines < linesNarrow) {
+ for (int line = 0; line < wrapper.Lines(); line++) {
+ sstrTextTall << wrapper.GetLine(line) << " ";
+ }
+ sstrTextTall << "\n";
+ linesDrawn += newLines;
+ } else {
+ //this wrapper has to be splitted
+ for (int line = 0; line < wrapper.Lines(); line++) {
+ if (line + linesDrawn < linesNarrow) {
+ sstrTextTall << wrapper.GetLine(line) << " ";
+ } else {
+ sstrTextFull << wrapper.GetLine(line) << " ";
+ }
+ }
+ sstrTextFull << "\n";
+ drawNarrow = false;
+ }
+ } else {
+ wrapper.Set((flds[i].c_str()), font, width);
+ for (int line = 0; line < wrapper.Lines(); line++) {
+ sstrTextFull << wrapper.GetLine(line) << " ";
+ }
+ sstrTextFull << "\n";
+ }
+ }
+ }
+ wTextTall.Set(sstrTextTall.str().c_str(), font, widthNarrow);
+ wTextFull.Set(sstrTextFull.str().c_str(), font, width);
+
+ int textLinesTall = wTextTall.Lines();
+ int textLinesFull = wTextFull.Lines();
+
+ return ((textLinesTall+textLinesFull) * fontHeight);
+}
+
+/*******************************************************************
+* Helper Functions
+*******************************************************************/
+
+string cTemplateFunction::GetFuncName(void) {
+ string name;
+ switch (type) {
+ case ftOsd:
+ name = "OSD Parameters";
+ break;
+ case ftView:
+ name = "View Parameters";
+ break;
+ case ftViewElement:
+ name = "View Element Parameters";
+ break;
+ case ftPixmap:
+ name = "Pixmap Parameters";
+ break;
+ case ftPixmapScroll:
+ name = "ScrollPixmap Parameters";
+ break;
+ case ftLoop:
+ name = "Looping Function";
+ break;
+ case ftFill:
+ name = "Function Fill";
+ break;
+ case ftDrawText:
+ name = "Function DrawText";
+ break;
+ case ftDrawTextBox:
+ name = "Function DrawTextBox";
+ break;
+ case ftDrawImage:
+ name = "Function DrawImage";
+ break;
+ case ftDrawRectangle:
+ name = "Function DrawRectangle";
+ break;
+ case ftDrawEllipse:
+ name = "Function DrawEllipse";
+ break;
+ case ftNone:
+ name = "Undefined";
+ break;
+ default:
+ name = "Unknown";
+ break;
+ };
+ return name;
+}
+
+string cTemplateFunction::GetParamName(eParamType pt) {
+ string name;
+ switch (pt) {
+ case ptCond:
+ name = "Condition";
+ break;
+ case ptName:
+ name = "Name";
+ break;
+ case ptX:
+ name = "X";
+ break;
+ case ptY:
+ name = "Y";
+ break;
+ case ptWidth:
+ name = "Width";
+ break;
+ case ptHeight:
+ name = "Height";
+ break;
+ case ptMenuItemWidth:
+ name = "Menu Item Width";
+ break;
+ case ptFadeTime:
+ name = "Fade Time";
+ break;
+ case ptDelay:
+ name = "Delay";
+ break;
+ case ptImageType:
+ name = "Image Type";
+ break;
+ case ptPath:
+ name = "Image Path";
+ break;
+ case ptColor:
+ name = "Color";
+ break;
+ case ptFont:
+ name = "Font";
+ break;
+ case ptFontSize:
+ name = "FontSize";
+ break;
+ case ptText:
+ name = "Text";
+ break;
+ case ptLayer:
+ name = "Layer";
+ break;
+ case ptTransparency:
+ name = "Transparency";
+ break;
+ case ptQuadrant:
+ name = "Quadrant";
+ break;
+ case ptAlign:
+ name = "Align";
+ break;
+ case ptValign:
+ name = "Vertical Align";
+ break;
+ case ptScrollMode:
+ name = "Scroll Mode";
+ break;
+ case ptScrollSpeed:
+ name = "Scroll Speed";
+ break;
+ case ptOrientation:
+ name = "Orientation";
+ break;
+ case ptNumElements:
+ name = "NumElements";
+ break;
+ case ptScrollElement:
+ name = "Scroll Element";
+ break;
+ case ptScrollHeight:
+ name = "Scroll Height";
+ break;
+ case ptFloat:
+ name = "Floating Type";
+ break;
+ case ptFloatWidth:
+ name = "Floating Width";
+ break;
+ case ptFloatHeight:
+ name = "Floating Height";
+ break;
+ case ptMaxLines:
+ name = "Max num of lines";
+ break;
+ case ptColumnWidth:
+ name = "Column Width";
+ break;
+ case ptRowHeight:
+ name = "Row Height";
+ break;
+ case ptOverflow:
+ name = "Overflow Mode";
+ break;
+ case ptScaleTvX:
+ name = "Scale TV Picture X";
+ break;
+ case ptScaleTvY:
+ name = "Scale TV Picture Y";
+ break;
+ case ptScaleTvWidth:
+ name = "Scale TV Picture Width";
+ break;
+ case ptScaleTvHeight:
+ name = "Scale TV Picture Height";
+ break;
+ case ptCache:
+ name = "Cache Image";
+ break;
+ case ptDeterminateFont:
+ name = "Determinate Font";
+ break;
+ default:
+ name = "Unknown";
+ break;
+ };
+ return name;
+}
+
+void cTemplateFunction::Debug(void) {
+ esyslog("skindesigner: Debugging %s, Container: x = %d, y = %d, Size: %dx%d", GetFuncName().c_str(), containerX, containerY, containerWidth, containerHeight);
+ esyslog("skindesigner: --- Native Parameters:");
+
+ if (condParam) {
+ condParam->Debug();
+ }
+ esyslog("skindesigner: --- Native Parameters:");
+ for (map<eParamType,string>::iterator it = nativeParameters.begin(); it != nativeParameters.end(); it++) {
+ esyslog("skindesigner: \"%s\" = \"%s\"", GetParamName(it->first).c_str(), (it->second).c_str());
+ }
+ if (numericParameters.size() > 0) {
+ esyslog("skindesigner: --- Integer Parameters: ");
+ for (map<eParamType,int>::iterator it = numericParameters.begin(); it != numericParameters.end(); it++) {
+ esyslog("skindesigner: %s = %d", GetParamName(it->first).c_str(), it->second);
+ }
+ }
+ if (numericDynamicParameters.size() > 0) {
+ esyslog("skindesigner: --- Dynamic Integer Parameters: ");
+ for (map<eParamType,string>::iterator it = numericDynamicParameters.begin(); it != numericDynamicParameters.end(); it++) {
+ esyslog("skindesigner: %s = %s", GetParamName(it->first).c_str(), (it->second).c_str());
+ }
+ }
+ if (colorParameters.size() > 0) {
+ esyslog("skindesigner: --- Color Parameters:");
+ for (map<eParamType,tColor>::iterator it = colorParameters.begin(); it != colorParameters.end(); it++) {
+ esyslog("skindesigner: %s = %x", GetParamName(it->first).c_str(), it->second);
+ }
+ }
+ if (textTokens.size() > 0) {
+ esyslog("skindesigner: --- Text Tokens:");
+ int i=0;
+ for (vector<cTextToken>::iterator it = textTokens.begin(); it != textTokens.end(); it++) {
+ eTextTokenType tokenType = (*it).type;
+ string tokType = "";
+ if (tokenType == ttConstString)
+ tokType = "Const: ";
+ else if (tokenType == ttToken)
+ tokType = "Token: ";
+ else if (tokenType == ttConditionalToken)
+ tokType = "Conditional Token: ";
+ esyslog("skindesigner: %s %d = \"%s\"", tokType.c_str(), i++, (*it).value.c_str());
+ if (tokenType == ttConditionalToken) {
+ for (vector<cTextToken>::iterator it2 = (*it).subTokens.begin(); it2 != (*it).subTokens.end(); it2++) {
+ eTextTokenType tokenTypeCond = (*it2).type;
+ string tokTypeCond = "";
+ if (tokenTypeCond == ttConstString)
+ tokTypeCond = "Const: ";
+ else if (tokenTypeCond == ttToken)
+ tokTypeCond = "Token: ";
+ esyslog("skindesigner: %s \"%s\"", tokTypeCond.c_str(), (*it2).value.c_str());
+ }
+ }
+ }
+ }
+ if (fontName.size() > 0) {
+ esyslog("skindesigner: --- Font Name: \"%s\"", fontName.c_str());
+ }
+ if (parsedText.size() > 0) {
+ esyslog("skindesigner: --- Parsed Text: \"%s\"", parsedText.c_str());
+ }
+ if (type == ftDrawText) {
+ esyslog("skindesigner: --- Cutted Text: \"%s\"", cuttedText.c_str());
+ esyslog("skindesigner: --- Parsed Text Width: %d", parsedTextWidth);
+ esyslog("skindesigner: --- Already Cutted: %s", alreadyCutted ? "true" : "false");
+ }
+ if (imgPath.size() > 0) {
+ esyslog("skindesigner: --- Image Path: \"%s\"", imgPath.c_str());
+ }
+}
diff --git a/libtemplate/templatefunction.h b/libtemplate/templatefunction.h
new file mode 100644
index 0000000..9a784c5
--- /dev/null
+++ b/libtemplate/templatefunction.h
@@ -0,0 +1,211 @@
+#ifndef __TEMPLATEFUNCTION_H
+#define __TEMPLATEFUNCTION_H
+
+#include <iostream>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string>
+#include <vector>
+#include <map>
+#include <set>
+#include <sstream>
+
+#include "globals.h"
+#include "parameter.h"
+
+using namespace std;
+
+// --- cTemplateFunction -------------------------------------------------------------
+
+enum eFuncType {
+ ftOsd,
+ ftView,
+ ftViewElement,
+ ftViewList,
+ ftPixmap,
+ ftPixmapScroll,
+ ftLoop,
+ ftFill,
+ ftDrawText,
+ ftDrawTextBox,
+ ftDrawImage,
+ ftDrawRectangle,
+ ftDrawEllipse,
+ ftNone
+};
+
+enum eParamType {
+ ptCond,
+ ptName,
+ ptX,
+ ptY,
+ ptWidth,
+ ptHeight,
+ ptMenuItemWidth,
+ ptFadeTime,
+ ptDelay,
+ ptImageType,
+ ptPath,
+ ptColor,
+ ptFont,
+ ptFontSize,
+ ptText,
+ ptLayer,
+ ptTransparency,
+ ptQuadrant,
+ ptAlign,
+ ptValign,
+ ptScrollMode,
+ ptScrollSpeed,
+ ptOrientation,
+ ptNumElements,
+ ptScrollElement,
+ ptScrollHeight,
+ ptFloat,
+ ptFloatWidth,
+ ptFloatHeight,
+ ptMaxLines,
+ ptColumnWidth,
+ ptRowHeight,
+ ptOverflow,
+ ptScaleTvX,
+ ptScaleTvY,
+ ptScaleTvWidth,
+ ptScaleTvHeight,
+ ptCache,
+ ptDeterminateFont,
+ ptNone
+};
+
+enum eImageType {
+ itChannelLogo,
+ itSepLogo,
+ itSkinPart,
+ itMenuIcon,
+ itIcon,
+ itImage
+};
+
+enum eFloatType {
+ flNone,
+ flTopLeft,
+ flTopRight
+};
+
+enum eOverflowType {
+ otNone,
+ otWrap,
+ otCut
+};
+
+class cTemplateFunction {
+protected:
+ eFuncType type;
+ bool debug;
+ int containerX; //X of parent container
+ int containerY; //Y of parent container
+ int containerWidth; //width of parent container
+ int containerHeight; //height of parent container
+ int columnWidth; //if func is executed in a loop, width of loop column
+ int rowHeight; //if func is executed in a loop, height of loop row
+ cGlobals *globals; //globals
+ map< eParamType, string > nativeParameters; //native parameters directly from xml
+ map< eParamType, int > numericParameters; //sucessfully parsed numeric parameters
+ map< eParamType, string > numericDynamicParameters; //numeric parameters with dynamic tokens
+ bool parsedCompletely;
+ bool updated;
+ map< eParamType, tColor > colorParameters;
+ cConditionalParameter *condParam;
+ //drawimage parameters
+ string imgPath;
+ //drawtext parameters
+ string fontName;
+ vector<cTextToken> textTokens;
+ string parsedText;
+ int parsedTextWidth;
+ string cuttedText;
+ bool alreadyCutted;
+ //drawtextbox parameters
+ int textboxHeight;
+ //dynamic tokens
+ map < string, string > *stringTokens;
+ map < string, int > *intTokens;
+ //private functions
+ bool SetCondition(string cond);
+ bool SetNumericParameter(eParamType type, string value);
+ bool SetAlign(eParamType type, string value);
+ bool SetFont(eParamType type, string value);
+ bool SetImageType(eParamType type, string value);
+ bool SetColor(eParamType type, string value);
+ bool SetTextTokens(string value);
+ void ParseTextToken(string &value, size_t start, size_t end);
+ void ParseConditionalTextToken(string &value, size_t start, size_t end);
+ bool SetScrollMode(string value);
+ bool SetScrollSpeed(string value);
+ bool SetOrientation(string value);
+ bool SetFloating(string value);
+ bool SetOverflow(string value);
+ void ParseStringParameters(void);
+ void ParseNumericalParameters(void);
+ void CalculateAlign(int elementWidth, int elementHeight);
+ int CalculateTextBoxHeight(void);
+public:
+ cTemplateFunction(eFuncType type);
+ virtual ~cTemplateFunction(void);
+ //Setter Functions
+ void SetParameters(vector<pair<string, string> > params);
+ void SetParameter(eParamType type, string value);
+ void SetContainer(int x, int y, int w, int h);
+ void SetLoopContainer(int columnWidth, int rowHeight);
+ void SetWidthManually(string width);
+ void SetHeightManually(string height);
+ void SetXManually(int newX);
+ void SetYManually(int newY);
+ void SetMaxTextWidth(int maxWidth);
+ void SetTextboxHeight(int boxHeight);
+ void SetGlobals(cGlobals *globals) { this->globals = globals; };
+ void SetTranslatedText(string translation);
+ //PreCache Parameters
+ bool CalculateParameters(void);
+ void CompleteParameters(void);
+ //Set and Unset Dynamic Tokens from view
+ void SetStringTokens(map < string, string > *tok) { stringTokens = tok; };
+ void SetIntTokens(map < string, int > *tok) { intTokens = tok; };
+ void UnsetIntTokens(void) { intTokens = NULL; };
+ void UnsetStringTokens(void) { stringTokens = NULL; };
+ //Clear dynamically parameters
+ void ClearDynamicParameters(void);
+ //Parse parameters with dynamically set Tokens
+ bool ParseParameters(void);
+ //Getter Functions
+ eFuncType GetType(void) { return type; };
+ bool DoDebug(void) { return debug; };
+ string GetParameter(eParamType type);
+ int GetNumericParameter(eParamType type);
+ string GetText(bool cut = true);
+ string GetImagePath(void) { return imgPath; };
+ tColor GetColorParameter(eParamType type);
+ string GetFontName(void) { return fontName; };
+ string GetFuncName(void);
+ string GetParamName(eParamType pt);
+ //Dynamic width or height parameter
+ int GetWidth(bool cutted = true);
+ int GetHeight(void);
+ void GetNeededWidths(multimap<eParamType,string> *widths);
+ void GetNeededHeights(multimap<eParamType,string> *heights);
+ void GetNeededPosX(multimap<eParamType,string> *posXs);
+ void GetNeededPosY(multimap<eParamType,string> *posYs);
+ void SetWidth(eParamType type, string label, int funcWidth);
+ void SetHeight(eParamType type, string label, int funcHeight);
+ void SetX(eParamType type, string label, int funcX);
+ void SetY(eParamType type, string label, int funcY);
+ //Status Functions
+ bool ParsedCompletely(void) { return parsedCompletely; };
+ bool DoExecute(void);
+ bool Updated(void) { return updated; };
+ //Debug
+ void Debug(void);
+};
+
+#endif //__TEMPLATEFUNCTION_H \ No newline at end of file
diff --git a/libtemplate/templateloopfunction.c b/libtemplate/templateloopfunction.c
new file mode 100644
index 0000000..b0030d3
--- /dev/null
+++ b/libtemplate/templateloopfunction.c
@@ -0,0 +1,208 @@
+#include "templateloopfunction.h"
+#include "../libcore/helpers.h"
+
+using namespace std;
+
+// --- cTemplateFunction -------------------------------------------------------------
+
+cTemplateLoopFunction::cTemplateLoopFunction(void) : cTemplateFunction(ftLoop) {
+}
+
+cTemplateLoopFunction::~cTemplateLoopFunction(void) {
+}
+
+void cTemplateLoopFunction::InitIterator(void) {
+ funcIt = functions.begin();
+}
+
+void cTemplateLoopFunction::AddFunction(string name, vector<pair<string, string> > &params) {
+ eFuncType type = ftNone;
+
+ if (!name.compare("drawtext")) {
+ type = ftDrawText;
+ } else if (!name.compare("drawtextbox")) {
+ type = ftDrawTextBox;
+ } else if (!name.compare("drawimage")) {
+ type = ftDrawImage;
+ } else if (!name.compare("drawrectangle")) {
+ type = ftDrawRectangle;
+ } else if (!name.compare("drawellipse")) {
+ type = ftDrawEllipse;
+ }
+
+ if (type == ftNone) {
+ return;
+ }
+
+ cTemplateFunction *f = new cTemplateFunction(type);
+ f->SetParameters(params);
+ functions.push_back(f);
+}
+
+void cTemplateLoopFunction::CalculateLoopFuncParameters(void) {
+ int columnWidth = GetNumericParameter(ptColumnWidth);
+ int rowHeight = GetNumericParameter(ptRowHeight);
+ for (vector<cTemplateFunction*>::iterator func = functions.begin(); func != functions.end(); func++) {
+ (*func)->SetGlobals(globals);
+ (*func)->SetContainer(0, 0, containerWidth, containerHeight);
+ (*func)->SetLoopContainer(columnWidth, rowHeight);
+ (*func)->CalculateParameters();
+ (*func)->CompleteParameters();
+ }
+}
+
+cTemplateFunction *cTemplateLoopFunction::GetNextFunction(void) {
+ if (funcIt == functions.end())
+ return NULL;
+ cTemplateFunction *func = *funcIt;
+ funcIt++;
+ return func;
+}
+
+void cTemplateLoopFunction::ClearDynamicParameters(void) {
+ InitIterator();
+ cTemplateFunction *func = NULL;
+ while(func = GetNextFunction()) {
+ func->ClearDynamicParameters();
+ }
+}
+
+void cTemplateLoopFunction::ParseDynamicParameters(map <string,string> *tokens) {
+ if (!tokens)
+ return;
+ InitIterator();
+ cTemplateFunction *func = NULL;
+
+ map <string,int> intTokens;
+ for (map <string,string>::iterator it = tokens->begin(); it != tokens->end(); it++) {
+ if (isNumber(it->second))
+ intTokens.insert(pair<string, int>(it->first, atoi((it->second).c_str())));
+ }
+
+ bool completelyParsed = true;
+ while(func = GetNextFunction()) {
+ func->SetStringTokens(tokens);
+ func->SetIntTokens(&intTokens);
+ bool funcCompletelyParsed = func->ParseParameters();
+ if (!funcCompletelyParsed)
+ completelyParsed = false;
+ if (func->Updated())
+ func->CompleteParameters();
+ func->UnsetStringTokens();
+ func->UnsetIntTokens();
+ }
+ if (completelyParsed) {
+ return;
+ }
+
+ ReplaceWidthFunctions();
+ ReplaceHeightFunctions();
+}
+
+int cTemplateLoopFunction::GetLoopElementsWidth(void) {
+ int cW = GetNumericParameter(ptColumnWidth);
+ if (cW > 0) {
+ return cW;
+ }
+ InitIterator();
+ cTemplateFunction *func = NULL;
+ int maxWidth = 1;
+ while(func = GetNextFunction()) {
+ int funcWidth = func->GetWidth(true);
+ if (funcWidth > maxWidth)
+ maxWidth = funcWidth;
+ }
+ return maxWidth;
+}
+
+int cTemplateLoopFunction::GetLoopElementsHeight(void) {
+ int rH = GetNumericParameter(ptRowHeight);
+ if (rH > 0)
+ return rH;
+ InitIterator();
+ cTemplateFunction *func = NULL;
+ int maxHeight = 1;
+ while(func = GetNextFunction()) {
+ int funcY = func->GetNumericParameter(ptY);
+ int funcHeight = func->GetHeight();
+ int totalHeight = funcY + funcHeight;
+ if (totalHeight > maxHeight)
+ maxHeight = totalHeight;
+ }
+ return maxHeight;
+}
+
+void cTemplateLoopFunction::ReplaceWidthFunctions(void) {
+ InitIterator();
+ cTemplateFunction *func = NULL;
+ while(func = GetNextFunction()) {
+ if (func->ParsedCompletely()) {
+ continue;
+ }
+ multimap<eParamType,string> widths;
+ func->GetNeededWidths(&widths);
+ for (map<eParamType, string>::iterator names = widths.begin(); names !=widths.end(); names++) {
+ eParamType type = names->first;
+ string label = names->second;
+ int funcWidth = 0;
+ for (vector<cTemplateFunction*>::iterator it = functions.begin(); it != functions.end(); it++) {
+ cTemplateFunction *myFunc = *it;
+ string myFuncName = myFunc->GetParameter(ptName);
+ if (!myFuncName.compare(label)) {
+ funcWidth = myFunc->GetWidth();
+ func->SetWidth(type, label, funcWidth);
+ if (func->Updated()) {
+ func->CompleteParameters();
+ }
+ }
+ }
+ }
+ }
+}
+
+void cTemplateLoopFunction::ReplaceHeightFunctions(void) {
+ InitIterator();
+ cTemplateFunction *func = NULL;
+ while(func = GetNextFunction()) {
+ if (func->ParsedCompletely()) {
+ continue;
+ }
+ multimap<eParamType,string> heights;
+ func->GetNeededHeights(&heights);
+ for (map<eParamType, string>::iterator names = heights.begin(); names !=heights.end(); names++) {
+ eParamType type = names->first;
+ string label = names->second;
+ int funcHeight = 0;
+ for (vector<cTemplateFunction*>::iterator it = functions.begin(); it != functions.end(); it++) {
+ cTemplateFunction *myFunc = *it;
+ string myFuncName = myFunc->GetParameter(ptName);
+ if (!myFuncName.compare(label)) {
+ funcHeight = myFunc->GetHeight();
+ func->SetHeight(type, label, funcHeight);
+ if (func->Updated()) {
+ func->CompleteParameters();
+ }
+ }
+ }
+ }
+ }
+}
+
+bool cTemplateLoopFunction::Ready(void) {
+ bool isReady = true;
+ map< eParamType, string >::iterator hit = numericDynamicParameters.find(ptColumnWidth);
+ if (hit != numericDynamicParameters.end())
+ isReady = false;
+ hit = numericDynamicParameters.find(ptRowHeight);
+ if (hit != numericDynamicParameters.end())
+ isReady = false;
+ return isReady;
+}
+
+void cTemplateLoopFunction::Debug(void) {
+ cTemplateFunction::Debug();
+ esyslog("skindesigner: functions to be looped:");
+ for (vector<cTemplateFunction*>::iterator func = functions.begin(); func != functions.end(); func++) {
+ (*func)->Debug();
+ }
+} \ No newline at end of file
diff --git a/libtemplate/templateloopfunction.h b/libtemplate/templateloopfunction.h
new file mode 100644
index 0000000..5335279
--- /dev/null
+++ b/libtemplate/templateloopfunction.h
@@ -0,0 +1,33 @@
+#ifndef __TEMPLATELOOPFUNCTION_H
+#define __TEMPLATELOOPFUNCTION_H
+
+#include "templatefunction.h"
+
+using namespace std;
+
+// --- cTemplateLoopFunction -------------------------------------------------------------
+
+class cTemplateLoopFunction : public cTemplateFunction {
+private:
+ vector<cTemplateFunction*> functions;
+ vector<cTemplateFunction*>::iterator funcIt;
+ void ReplaceWidthFunctions(void);
+ void ReplaceHeightFunctions(void);
+public:
+ cTemplateLoopFunction(void);
+ virtual ~cTemplateLoopFunction(void);
+ void AddFunction(string name, vector<pair<string, string> > &params);
+ void CalculateLoopFuncParameters(void);
+ void InitIterator(void);
+ cTemplateFunction *GetNextFunction(void);
+ void ClearDynamicParameters(void);
+ void ParseDynamicParameters(map <string,string> *tokens);
+ int GetLoopElementsWidth(void);
+ int GetLoopElementsHeight(void);
+ int GetContainerWidth(void) { return containerWidth; };
+ int GetContainerHeight(void) { return containerHeight; };
+ bool Ready(void);
+ void Debug(void);
+};
+
+#endif //__TEMPLATELOOPFUNCTION_H
diff --git a/libtemplate/templatepixmap.c b/libtemplate/templatepixmap.c
new file mode 100644
index 0000000..8aaa4f3
--- /dev/null
+++ b/libtemplate/templatepixmap.c
@@ -0,0 +1,473 @@
+#include "templatepixmap.h"
+
+using namespace std;
+
+// --- cTemplatePixmap -------------------------------------------------------------
+
+cTemplatePixmap::cTemplatePixmap(void) {
+ parameters = NULL;
+ containerX = 0;
+ containerY = 0;
+ containerWidth = 0;
+ containerHeight = 0;
+ globals = NULL;
+ scrolling = false;
+}
+
+cTemplatePixmap::~cTemplatePixmap() {
+ for (vector<cTemplateFunction*>::iterator it = functions.begin(); it != functions.end(); it++) {
+ delete (*it);
+ }
+ if (parameters)
+ delete parameters;
+}
+
+void cTemplatePixmap::SetParameters(vector<pair<string, string> > &params) {
+ parameters = new cTemplateFunction(ftPixmap);
+ parameters->SetGlobals(globals);
+ parameters->SetParameters(params);
+}
+
+void cTemplatePixmap::SetContainer(int x, int y, int w, int h) {
+ containerX = x;
+ containerY = y;
+ containerWidth = w;
+ containerHeight = h;
+}
+
+void cTemplatePixmap::SetWidth(int width) {
+ cString pWidth = cString::sprintf("%d", width);
+ parameters->SetWidthManually(*pWidth);
+}
+
+void cTemplatePixmap::SetHeight(int height) {
+ cString pHeight = cString::sprintf("%d", height);
+ parameters->SetHeightManually(*pHeight);
+}
+
+void cTemplatePixmap::SetX(int x) {
+ parameters->SetXManually(x);
+}
+
+void cTemplatePixmap::SetY(int y) {
+ parameters->SetYManually(y);
+}
+
+void cTemplatePixmap::ClearDynamicParameters(void) {
+ parameters->ClearDynamicParameters();
+}
+
+void cTemplatePixmap::ParseDynamicParameters(map <string,int> *intTokens, bool initFuncs) {
+ parameters->ClearDynamicParameters();
+ parameters->SetIntTokens(intTokens);
+ parameters->ParseParameters();
+ parameters->UnsetIntTokens();
+
+ if (!DoExecute()) {
+ parameters->ClearDynamicParameters();
+ return;
+ }
+
+ if (!initFuncs || !Ready())
+ return;
+
+ int x = parameters->GetNumericParameter(ptX);
+ int y = parameters->GetNumericParameter(ptY);
+ int width = parameters->GetNumericParameter(ptWidth);
+ int height = parameters->GetNumericParameter(ptHeight);
+
+ for (vector<cTemplateFunction*>::iterator func = functions.begin(); func != functions.end(); func++) {
+ (*func)->SetContainer(x, y, width, height);
+ (*func)->CalculateParameters();
+ (*func)->CompleteParameters();
+ if ((*func)->GetType() == ftLoop) {
+ cTemplateLoopFunction *loopFunc = dynamic_cast<cTemplateLoopFunction*>(*func);
+ if (!loopFunc->Ready()) {
+ loopFunc->SetIntTokens(intTokens);
+ loopFunc->ParseParameters();
+ loopFunc->UnsetIntTokens();
+ }
+ loopFunc->CalculateLoopFuncParameters();
+ }
+ }
+}
+
+void cTemplatePixmap::AddFunction(string name, vector<pair<string, string> > &params) {
+ eFuncType type = ftNone;
+
+ if (!name.compare("fill")) {
+ type = ftFill;
+ } else if (!name.compare("drawtext")) {
+ type = ftDrawText;
+ } else if (!name.compare("drawtextbox")) {
+ type = ftDrawTextBox;
+ } else if (!name.compare("drawimage")) {
+ type = ftDrawImage;
+ } else if (!name.compare("drawrectangle")) {
+ type = ftDrawRectangle;
+ } else if (!name.compare("drawellipse")) {
+ type = ftDrawEllipse;
+ }
+
+ if (type == ftNone) {
+ return;
+ }
+
+ cTemplateFunction *f = new cTemplateFunction(type);
+ f->SetParameters(params);
+ functions.push_back(f);
+}
+
+void cTemplatePixmap::AddLoopFunction(cTemplateLoopFunction *lf) {
+ functions.push_back(lf);
+}
+
+
+bool cTemplatePixmap::CalculateParameters(void) {
+ bool paramsValid = true;
+ //Calculate Pixmap Size
+ parameters->SetContainer(containerX, containerY, containerWidth, containerHeight);
+ parameters->SetGlobals(globals);
+ paramsValid = parameters->CalculateParameters();
+
+ int pixWidth = parameters->GetNumericParameter(ptWidth);
+ int pixHeight = parameters->GetNumericParameter(ptHeight);
+
+ for (vector<cTemplateFunction*>::iterator func = functions.begin(); func != functions.end(); func++) {
+ (*func)->SetGlobals(globals);
+ if (!Ready())
+ continue;
+ (*func)->SetContainer(0, 0, pixWidth, pixHeight);
+ paramsValid = (*func)->CalculateParameters();
+ (*func)->CompleteParameters();
+ if ((*func)->GetType() == ftLoop) {
+ cTemplateLoopFunction *loopFunc = dynamic_cast<cTemplateLoopFunction*>(*func);
+ loopFunc->CalculateLoopFuncParameters();
+ }
+ }
+
+ return paramsValid;
+}
+
+void cTemplatePixmap::ClearDynamicFunctionParameters(void) {
+ InitIterator();
+ cTemplateFunction *func = NULL;
+ while(func = GetNextFunction()) {
+ func->ClearDynamicParameters();
+ }
+}
+
+void cTemplatePixmap::ParseDynamicFunctionParameters(map <string,string> *stringTokens, map <string,int> *intTokens) {
+ InitIterator();
+ cTemplateFunction *func = NULL;
+ bool completelyParsed = true;
+ bool updated = false;
+ while(func = GetNextFunction()) {
+ func->SetStringTokens(stringTokens);
+ func->SetIntTokens(intTokens);
+ bool funcCompletelyParsed = func->ParseParameters();
+ if (!funcCompletelyParsed)
+ completelyParsed = false;
+ if (func->Updated())
+ func->CompleteParameters();
+ func->UnsetIntTokens();
+ func->UnsetStringTokens();
+ }
+
+ if (completelyParsed) {
+ return;
+ }
+
+ ReplaceWidthFunctions();
+ ReplaceHeightFunctions();
+ ReplacePosXFunctions();
+ ReplacePosYFunctions();
+}
+
+bool cTemplatePixmap::CalculateDrawPortSize(cSize &size, map < string, vector< map< string, string > > > *loopTokens) {
+ int pixWidth = parameters->GetNumericParameter(ptWidth);
+ int pixHeight = parameters->GetNumericParameter(ptHeight);
+ int orientation = parameters->GetNumericParameter(ptOrientation);
+ if (orientation < 0)
+ orientation = orVertical;
+ if (orientation == orHorizontal) {
+ //get function which determinates drawport width
+ cTemplateFunction *scrollFunc = GetScrollFunction();
+ if (!scrollFunc)
+ return false;
+ int drawportWidth = scrollFunc->GetWidth(false) + scrollFunc->GetNumericParameter(ptX) + 10;
+ if (drawportWidth > pixWidth) {
+ size.SetWidth(drawportWidth);
+ size.SetHeight(pixHeight);
+ return true;
+ }
+ } else if (orientation == orVertical) {
+ //check "last" element height
+ InitIterator();
+ cTemplateFunction *f = NULL;
+ int drawportHeight = 1;
+ while (f = GetNextFunction()) {
+ if (f->GetType() == ftLoop) {
+ cTemplateLoopFunction *loopFunc = dynamic_cast<cTemplateLoopFunction*>(f);
+ //get number of loop tokens
+ string loopTokenName = loopFunc->GetParameter(ptName);
+ int numLoopTokens = 0;
+ map < string, vector< map< string, string > > >::iterator hit = loopTokens->find(loopTokenName);
+ if (hit != loopTokens->end()) {
+ vector< map<string,string> > loopToken = hit->second;
+ numLoopTokens = loopToken.size();
+ //parse first loop token element to get correct height
+ vector< map<string,string> >::iterator firstLoopToken = loopToken.begin();
+ loopFunc->ClearDynamicParameters();
+ loopFunc->ParseDynamicParameters(&(*firstLoopToken));
+ }
+ int orientation = loopFunc->GetNumericParameter(ptOrientation);
+ int yFunc = loopFunc->GetNumericParameter(ptY);
+ int heightFunc = loopFunc->GetLoopElementsHeight();
+ if (loopTokens && orientation == orVertical) {
+ //height is height of loop elements times num loop elements
+ heightFunc = heightFunc * numLoopTokens;
+ } else if (loopTokens && orientation == orHorizontal) {
+ int overflow = loopFunc->GetNumericParameter(ptOverflow);
+ if (overflow == otCut) {
+ //do nothing, height is only height of one line
+ } else if (overflow == otWrap) {
+ int widthFunc = loopFunc->GetLoopElementsWidth();
+ if (widthFunc <= 0)
+ continue;
+ int loopWidth = loopFunc->GetNumericParameter(ptWidth);
+ if (loopWidth <= 0)
+ loopWidth = loopFunc->GetContainerWidth();
+ int elementsPerRow = loopWidth / widthFunc;
+ int rest = loopWidth % widthFunc;
+ if (rest > 0)
+ elementsPerRow++;
+ if (elementsPerRow <= 0)
+ continue;
+ int lines = numLoopTokens / elementsPerRow;
+ rest = numLoopTokens % elementsPerRow;
+ if (rest > 0)
+ lines++;
+ heightFunc = heightFunc * lines;
+ }
+ }
+ int neededHeight = heightFunc + yFunc;
+ if (neededHeight > drawportHeight)
+ drawportHeight = neededHeight;
+ } else {
+ int yFunc = f->GetNumericParameter(ptY);
+ int heightFunc = f->GetHeight();
+ int neededHeight = heightFunc + yFunc;
+ if (neededHeight > drawportHeight)
+ drawportHeight = neededHeight;
+ }
+ }
+ if (drawportHeight > pixHeight) {
+ size.SetWidth(pixWidth);
+ size.SetHeight(drawportHeight);
+ return true;
+ }
+ }
+ size.SetWidth(0);
+ size.SetHeight(0);
+ return false;
+}
+
+void cTemplatePixmap::SetScrollingTextWidth(void) {
+ int orientation = parameters->GetNumericParameter(ptOrientation);
+ if (orientation != orHorizontal)
+ return;
+ int pixWidth = parameters->GetNumericParameter(ptWidth);
+ InitIterator();
+ cTemplateFunction *func = NULL;
+ while(func = GetNextFunction()) {
+ if (func->GetType() == ftDrawText) {
+ int offset = func->GetNumericParameter(ptX);
+ func->SetMaxTextWidth(pixWidth - offset);
+ }
+ }
+}
+
+
+cTemplateFunction *cTemplatePixmap::GetScrollFunction(void) {
+ string scrollElement = parameters->GetParameter(ptScrollElement);
+ if (scrollElement.size() == 0)
+ return NULL;
+ InitIterator();
+ cTemplateFunction *f = NULL;
+ bool foundElement = false;
+ while (f = GetNextFunction()) {
+ string funcName = f->GetParameter(ptName);
+ if (!funcName.compare(scrollElement)) {
+ return f;
+ }
+ }
+ return NULL;
+}
+
+cRect cTemplatePixmap::GetPixmapSize(void) {
+ cRect size;
+ size.SetX(GetNumericParameter(ptX));
+ size.SetY(GetNumericParameter(ptY));
+ size.SetWidth(GetNumericParameter(ptWidth));
+ size.SetHeight(GetNumericParameter(ptHeight));
+ return size;
+}
+
+int cTemplatePixmap::GetNumericParameter(eParamType type) {
+ if (!parameters)
+ return -1;
+ return parameters->GetNumericParameter(type);
+}
+
+void cTemplatePixmap::InitIterator(void) {
+ funcIt = functions.begin();
+}
+
+cTemplateFunction *cTemplatePixmap::GetNextFunction(void) {
+ if (funcIt == functions.end())
+ return NULL;
+ cTemplateFunction *func = *funcIt;
+ funcIt++;
+ return func;
+}
+
+bool cTemplatePixmap::Ready(void) {
+ int myX = parameters->GetNumericParameter(ptX);
+ if (myX < 0)
+ return false;
+ int myY = parameters->GetNumericParameter(ptY);
+ if (myY < 0)
+ return false;
+ int myWidth = parameters->GetNumericParameter(ptWidth);
+ if (myWidth < 1)
+ return false;
+ int myHeight = parameters->GetNumericParameter(ptHeight);
+ if (myHeight < 1)
+ return false;
+ return true;
+}
+
+void cTemplatePixmap::ReplaceWidthFunctions(void) {
+ InitIterator();
+ cTemplateFunction *func = NULL;
+ while(func = GetNextFunction()) {
+ if (func->ParsedCompletely()) {
+ continue;
+ }
+ multimap<eParamType,string> widths;
+ func->GetNeededWidths(&widths);
+ for (map<eParamType, string>::iterator names = widths.begin(); names !=widths.end(); names++) {
+ eParamType type = names->first;
+ string label = names->second;
+ int funcWidth = 0;
+ for (vector<cTemplateFunction*>::iterator it = functions.begin(); it != functions.end(); it++) {
+ cTemplateFunction *myFunc = *it;
+ string myFuncName = myFunc->GetParameter(ptName);
+ if (!myFuncName.compare(label)) {
+ funcWidth = myFunc->GetWidth();
+ func->SetWidth(type, label, funcWidth);
+ if (func->Updated()) {
+ func->CompleteParameters();
+ }
+ }
+ }
+ }
+ }
+}
+
+void cTemplatePixmap::ReplaceHeightFunctions(void) {
+ InitIterator();
+ cTemplateFunction *func = NULL;
+ while(func = GetNextFunction()) {
+ if (func->ParsedCompletely()) {
+ continue;
+ }
+ multimap<eParamType,string> heights;
+ func->GetNeededHeights(&heights);
+ for (map<eParamType, string>::iterator names = heights.begin(); names !=heights.end(); names++) {
+ eParamType type = names->first;
+ string label = names->second;
+ int funcHeight = 0;
+ for (vector<cTemplateFunction*>::iterator it = functions.begin(); it != functions.end(); it++) {
+ cTemplateFunction *myFunc = *it;
+ string myFuncName = myFunc->GetParameter(ptName);
+ if (!myFuncName.compare(label)) {
+ funcHeight = myFunc->GetHeight();
+ func->SetHeight(type, label, funcHeight);
+ if (func->Updated()) {
+ func->CompleteParameters();
+ }
+ }
+ }
+ }
+ }
+}
+
+void cTemplatePixmap::ReplacePosXFunctions(void) {
+ InitIterator();
+ cTemplateFunction *func = NULL;
+ while(func = GetNextFunction()) {
+ if (func->ParsedCompletely()) {
+ continue;
+ }
+ multimap<eParamType,string> posXs;
+ func->GetNeededPosX(&posXs);
+ for (map<eParamType, string>::iterator names = posXs.begin(); names !=posXs.end(); names++) {
+ eParamType type = names->first;
+ string label = names->second;
+ int funcX = 0;
+ for (vector<cTemplateFunction*>::iterator it = functions.begin(); it != functions.end(); it++) {
+ cTemplateFunction *myFunc = *it;
+ string myFuncName = myFunc->GetParameter(ptName);
+ if (!myFuncName.compare(label)) {
+ funcX = myFunc->GetNumericParameter(ptX);
+ if (funcX > -1) {
+ func->SetX(type, label, funcX);
+ if (func->Updated()) {
+ func->CompleteParameters();
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void cTemplatePixmap::ReplacePosYFunctions(void) {
+ InitIterator();
+ cTemplateFunction *func = NULL;
+ while(func = GetNextFunction()) {
+ if (func->ParsedCompletely()) {
+ continue;
+ }
+ multimap<eParamType,string> posYs;
+ func->GetNeededPosY(&posYs);
+ for (map<eParamType, string>::iterator names = posYs.begin(); names !=posYs.end(); names++) {
+ eParamType type = names->first;
+ string label = names->second;
+ int funcY = 0;
+ for (vector<cTemplateFunction*>::iterator it = functions.begin(); it != functions.end(); it++) {
+ cTemplateFunction *myFunc = *it;
+ string myFuncName = myFunc->GetParameter(ptName);
+ if (!myFuncName.compare(label)) {
+ funcY = myFunc->GetNumericParameter(ptY);
+ if (funcY > -1) {
+ func->SetY(type, label, funcY);
+ if (func->Updated()) {
+ func->CompleteParameters();
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void cTemplatePixmap::Debug(void) {
+ esyslog("skindesigner: pixmap container size x: %d, y: %d, width: %d, height %d", containerX, containerY, containerWidth, containerHeight);
+ parameters->Debug();
+ for (vector<cTemplateFunction*>::iterator it = functions.begin(); it != functions.end(); it++) {
+ (*it)->Debug();
+ }
+}
diff --git a/libtemplate/templatepixmap.h b/libtemplate/templatepixmap.h
new file mode 100644
index 0000000..6cf3bd5
--- /dev/null
+++ b/libtemplate/templatepixmap.h
@@ -0,0 +1,82 @@
+#ifndef __TEMPLATEPIXMAP_H
+#define __TEMPLATEPIXMAP_H
+
+#include <iostream>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string>
+#include <vector>
+#include <map>
+#include <set>
+#include <sstream>
+
+#include "globals.h"
+#include "templateloopfunction.h"
+
+using namespace std;
+
+// --- cTemplatePixmap -------------------------------------------------------------
+
+class cTemplatePixmap {
+protected:
+ bool scrolling;
+ cTemplateFunction *parameters;
+ vector<cTemplateFunction*> functions;
+ vector<cTemplateFunction*>::iterator funcIt;
+ int containerX;
+ int containerY;
+ int containerWidth;
+ int containerHeight;
+ cGlobals *globals;
+ //functions replacing {width(label)} and {height(label)} tokens
+ void ReplaceWidthFunctions(void);
+ void ReplaceHeightFunctions(void);
+ //functions replacing {posx(label)} and {posy(label)} tokens
+ void ReplacePosXFunctions(void);
+ void ReplacePosYFunctions(void);
+ //Get Scrolling Function
+ cTemplateFunction *GetScrollFunction(void);
+public:
+ cTemplatePixmap(void);
+ virtual ~cTemplatePixmap(void);
+ //Setter Functions
+ void SetScrolling(void) { scrolling = true; };
+ void SetParameters(vector<pair<string, string> > &params);
+ void SetWidth(int width);
+ void SetHeight(int height);
+ void SetX(int x);
+ void SetY(int y);
+ void SetContainer(int x, int y, int w, int h);
+ void SetGlobals(cGlobals *globals) { this->globals = globals; };
+ void AddFunction(string name, vector<pair<string, string> > &params);
+ void AddLoopFunction(cTemplateLoopFunction *lf);
+ //PreCache Parameters
+ bool CalculateParameters(void);
+ //clear dynamically set function parameters
+ void ClearDynamicFunctionParameters(void);
+ //Clear dynamically set pixmap parameters
+ void ClearDynamicParameters(void);
+ //Parse pixmap parameters with dynamically set Tokens
+ void ParseDynamicParameters(map <string,int> *intTokens, bool initFuncs);
+ //Parse all function parameters with dynamically set Tokens
+ void ParseDynamicFunctionParameters(map <string,string> *stringTokens, map <string,int> *intTokens);
+ //Calculate size of drawport in case area scrolls
+ bool CalculateDrawPortSize(cSize &size, map < string, vector< map< string, string > > > *loopTokens = NULL);
+ //Set max width for text in scrollarea
+ void SetScrollingTextWidth(void);
+ //Getter Functions
+ cRect GetPixmapSize(void);
+ int GetNumericParameter(eParamType type);
+ bool Scrolling(void) { return scrolling; };
+ bool DoExecute(void) { return parameters->DoExecute(); };
+ bool DoDebug(void) { return parameters->DoDebug(); };
+ bool Ready(void);
+ //Traverse Functions
+ void InitIterator(void);
+ cTemplateFunction *GetNextFunction(void);
+ //Debug
+ void Debug(void);
+};
+
+#endif //__TEMPLATEPIXMAP_H \ No newline at end of file
diff --git a/libtemplate/templateview.c b/libtemplate/templateview.c
new file mode 100644
index 0000000..abaedc8
--- /dev/null
+++ b/libtemplate/templateview.c
@@ -0,0 +1,1567 @@
+#include "templateview.h"
+
+// --- cTemplateView -------------------------------------------------------------
+
+cTemplateView::cTemplateView(void) {
+ globals = NULL;
+ parameters = NULL;
+ containerX = 0;
+ containerY = 0;
+ containerWidth = 0;
+ containerHeight = 0;
+ SetFunctionDefinitions();
+}
+
+cTemplateView::~cTemplateView() {
+
+ for (map < eViewElement, cTemplateViewElement* >::iterator it = viewElements.begin(); it != viewElements.end(); it++) {
+ delete it->second;
+ }
+
+ for (map < eViewList, cTemplateViewList* >::iterator it = viewLists.begin(); it != viewLists.end(); it++) {
+ delete it->second;
+ }
+
+ for (vector < cTemplateViewTab* >::iterator it = viewTabs.begin(); it != viewTabs.end(); it++) {
+ delete *it;
+ }
+
+ if (parameters)
+ delete parameters;
+
+}
+
+/*******************************************************************
+* Public Functions
+*******************************************************************/
+
+void cTemplateView::SetParameters(vector<pair<string, string> > &params) {
+ parameters = new cTemplateFunction(ftView);
+ parameters->SetGlobals(globals);
+ parameters->SetParameters(params);
+}
+
+void cTemplateView::SetContainer(int x, int y, int width, int height) {
+ containerX = x;
+ containerY = y;
+ containerWidth = width;
+ containerHeight = height;
+}
+
+cTemplateViewElement *cTemplateView::GetViewElement(eViewElement ve) {
+ map < eViewElement, cTemplateViewElement* >::iterator hit = viewElements.find(ve);
+ if (hit == viewElements.end())
+ return NULL;
+ return hit->second;
+}
+
+void cTemplateView::InitViewElementIterator(void) {
+ veIt = viewElements.begin();
+}
+
+cTemplateViewElement *cTemplateView::GetNextViewElement(void) {
+ if (veIt == viewElements.end())
+ return NULL;
+ cTemplateViewElement *viewElement = veIt->second;
+ veIt++;
+ return viewElement;
+}
+
+cTemplateViewList *cTemplateView::GetViewList(eViewList vl) {
+ map < eViewList, cTemplateViewList* >::iterator hit = viewLists.find(vl);
+ if (hit == viewLists.end())
+ return NULL;
+ return hit->second;
+}
+
+void cTemplateView::InitViewListIterator(void) {
+ vlIt = viewLists.begin();
+}
+
+cTemplateViewList *cTemplateView::GetNextViewList(void) {
+ if (vlIt == viewLists.end())
+ return NULL;
+ cTemplateViewList *viewList = vlIt->second;
+ vlIt++;
+ return viewList;
+}
+
+cTemplateView *cTemplateView::GetSubView(eSubView sv) {
+ map < eSubView, cTemplateView* >::iterator hit = subViews.find(sv);
+ if (hit == subViews.end())
+ return NULL;
+ return hit->second;
+}
+
+void cTemplateView::InitViewTabIterator(void) {
+ vtIt = viewTabs.begin();
+}
+
+cTemplateViewTab *cTemplateView::GetNextViewTab(void) {
+ if (vtIt == viewTabs.end()) {
+ return NULL;
+ }
+ cTemplateViewTab *tab = *vtIt;
+ vtIt++;
+ return tab;
+}
+
+void cTemplateView::InitSubViewIterator(void) {
+ svIt = subViews.begin();
+}
+
+cTemplateView *cTemplateView::GetNextSubView(void) {
+ if (svIt == subViews.end())
+ return NULL;
+ cTemplateView *subView = svIt->second;
+ svIt++;
+ return subView;
+}
+
+int cTemplateView::GetNumericParameter(eParamType type) {
+ if (!parameters)
+ return 0;
+ return parameters->GetNumericParameter(type);
+}
+
+cRect cTemplateView::GetOsdSize(void) {
+ cRect osdSize;
+ if (!parameters) {
+ return osdSize;
+ }
+ osdSize.SetX(parameters->GetNumericParameter(ptX));
+ osdSize.SetY(parameters->GetNumericParameter(ptY));
+ osdSize.SetWidth(parameters->GetNumericParameter(ptWidth));
+ osdSize.SetHeight(parameters->GetNumericParameter(ptHeight));
+ return osdSize;
+}
+
+int cTemplateView::GetNumPixmaps(void) {
+ int numPixmaps = 0;
+ for (map < eViewElement, cTemplateViewElement* >::iterator it = viewElements.begin(); it != viewElements.end(); it++) {
+ cTemplateViewElement *viewElement = it->second;
+ numPixmaps += viewElement->GetNumPixmaps();
+ }
+ return numPixmaps;
+}
+
+int cTemplateView::GetNumPixmapsViewElement(eViewElement ve) {
+ map < eViewElement, cTemplateViewElement* >::iterator hit = viewElements.find(ve);
+ if (hit == viewElements.end())
+ return 0;
+ cTemplateViewElement *viewElement = hit->second;
+ return viewElement->GetNumPixmaps();
+}
+
+int cTemplateView::GetNumListViewMenuItems(void) {
+ int numElements = 0;
+ cTemplateViewList *menuList = GetViewList(vlMenuItem);
+ if (!menuList)
+ return numElements;
+ return menuList->GetNumericParameter(ptNumElements);
+}
+
+bool cTemplateView::GetScalingWindow(cRect &scalingWindow) {
+ if (!parameters)
+ return false;
+ bool doScale = false;
+ int scaleX = parameters->GetNumericParameter(ptScaleTvX);
+ int scaleY = parameters->GetNumericParameter(ptScaleTvY);
+ int scaleWidth = parameters->GetNumericParameter(ptScaleTvWidth);
+ int scaleHeight = parameters->GetNumericParameter(ptScaleTvHeight);
+ if (scaleX > -1 && scaleY > -1 && scaleWidth > -1 && scaleHeight > -1) {
+ cRect suggestedScaleWindow(scaleX, scaleY, scaleWidth, scaleHeight);
+ scalingWindow = cDevice::PrimaryDevice()->CanScaleVideo(suggestedScaleWindow);
+ doScale = true;
+ } else {
+ scalingWindow = cDevice::PrimaryDevice()->CanScaleVideo(cRect::Null);
+ }
+ return doScale;
+}
+
+bool cTemplateView::ValidViewElement(const char *viewElement) {
+ set<string>::iterator hit = viewElementsAllowed.find(viewElement);
+ if (hit == viewElementsAllowed.end())
+ return false;
+ return true;
+}
+
+bool cTemplateView::ValidSubView(const char *subView) {
+ set<string>::iterator hit = subViewsAllowed.find(subView);
+ if (hit == subViewsAllowed.end())
+ return false;
+ return true;
+}
+
+bool cTemplateView::ValidViewList(const char *viewList) {
+ set<string>::iterator hit = viewListsAllowed.find(viewList);
+ if (hit == viewListsAllowed.end())
+ return false;
+ return true;
+}
+
+bool cTemplateView::ValidFunction(const char *func) {
+ map < string, set < string > >::iterator hit = funcsAllowed.find(func);
+ if (hit == funcsAllowed.end())
+ return false;
+ return true;
+}
+
+bool cTemplateView::ValidAttribute(const char *func, const char *att) {
+ map < string, set < string > >::iterator hit = funcsAllowed.find(func);
+ if (hit == funcsAllowed.end())
+ return false;
+
+ set<string>::iterator hitAtt = (hit->second).find(att);
+ if (hitAtt == (hit->second).end())
+ return false;
+
+ return true;
+}
+
+void cTemplateView::Translate(void) {
+ //Translate ViewElements
+ InitViewElementIterator();
+ cTemplateViewElement *viewElement = NULL;
+ while(viewElement = GetNextViewElement()) {
+ viewElement->InitIterator();
+ cTemplatePixmap *pix = NULL;
+ while(pix = viewElement->GetNextPixmap()) {
+ pix->InitIterator();
+ cTemplateFunction *func = NULL;
+ while(func = pix->GetNextFunction()) {
+ if (func->GetType() == ftDrawText || func->GetType() == ftDrawTextBox) {
+ string text = func->GetParameter(ptText);
+ string translation;
+ bool translated = globals->Translate(text, translation);
+ if (translated) {
+ func->SetTranslatedText(translation);
+ }
+ }
+ }
+ }
+ }
+ //Translate viewLists
+ InitViewListIterator();
+ cTemplateViewList *viewList = NULL;
+ while(viewList = GetNextViewList()) {
+ viewList->InitIterator();
+ cTemplatePixmap *pix = NULL;
+ while(pix = viewList->GetNextPixmap()) {
+ pix->InitIterator();
+ cTemplateFunction *func = NULL;
+ while(func = pix->GetNextFunction()) {
+ if (func->GetType() == ftDrawText || func->GetType() == ftDrawTextBox) {
+ string text = func->GetParameter(ptText);
+ string translation;
+ bool translated = globals->Translate(text, translation);
+ if (translated) {
+ func->SetTranslatedText(translation);
+ }
+ }
+ }
+ }
+ cTemplateViewElement *listElement = viewList->GetListElement();
+ listElement->InitIterator();
+ while(pix = listElement->GetNextPixmap()) {
+ pix->InitIterator();
+ cTemplateFunction *func = NULL;
+ while(func = pix->GetNextFunction()) {
+ if (func->GetType() == ftDrawText || func->GetType() == ftDrawTextBox) {
+ string text = func->GetParameter(ptText);
+ string translation;
+ bool translated = globals->Translate(text, translation);
+ if (translated) {
+ func->SetTranslatedText(translation);
+ }
+ }
+ }
+ }
+
+ cTemplateViewElement *listElementCurrent = viewList->GetListElementCurrent();
+ if (listElementCurrent) {
+ listElementCurrent->InitIterator();
+ while(pix = listElementCurrent->GetNextPixmap()) {
+ pix->InitIterator();
+ cTemplateFunction *func = NULL;
+ while(func = pix->GetNextFunction()) {
+ if (func->GetType() == ftDrawText || func->GetType() == ftDrawTextBox) {
+ string text = func->GetParameter(ptText);
+ string translation;
+ bool translated = globals->Translate(text, translation);
+ if (translated) {
+ func->SetTranslatedText(translation);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ //Translate viewTabs
+ InitViewTabIterator();
+ cTemplateViewTab *viewTab = NULL;
+ while(viewTab = GetNextViewTab()) {
+ string tabName = viewTab->GetName();
+ string tabTrans;
+ bool translated = globals->Translate(tabName, tabTrans);
+ if (translated) {
+ viewTab->SetName(tabTrans);
+ }
+ viewTab->InitIterator();
+ cTemplateFunction *func = NULL;
+ while(func = viewTab->GetNextFunction()) {
+ if (func->GetType() == ftDrawText || func->GetType() == ftDrawTextBox) {
+ string text = func->GetParameter(ptText);
+ string translation;
+ translated = globals->Translate(text, translation);
+ if (translated) {
+ func->SetTranslatedText(translation);
+ }
+ }
+ }
+ }
+
+ //Translate Subviews
+ InitSubViewIterator();
+ cTemplateView *subView = NULL;
+ while(subView = GetNextSubView()) {
+ subView->Translate();
+ }
+}
+
+void cTemplateView::PreCache(bool isSubview) {
+
+ if (!isSubview) {
+ int osdW = cOsd::OsdWidth();
+ int osdH = cOsd::OsdHeight();
+ parameters->SetContainer(0, 0, osdW, osdH);
+ } else {
+ parameters->SetContainer(containerX, containerY, containerWidth, containerHeight);
+ }
+ //Calculate OSD Size
+ parameters->CalculateParameters();
+
+ int osdX = parameters->GetNumericParameter(ptX);
+ int osdY = parameters->GetNumericParameter(ptY);
+ int osdWidth = parameters->GetNumericParameter(ptWidth);
+ int osdHeight = parameters->GetNumericParameter(ptHeight);
+ int pixOffset = 0;
+
+ //Cache ViewElements
+ for (map < eViewElement, cTemplateViewElement* >::iterator it = viewElements.begin(); it != viewElements.end(); it++) {
+ cTemplateViewElement *viewElement = it->second;
+ viewElement->SetGlobals(globals);
+ viewElement->SetContainer(0, 0, osdWidth, osdHeight);
+ viewElement->CalculatePixmapParameters();
+ viewElement->SetPixOffset(pixOffset);
+ pixOffset += viewElement->GetNumPixmaps();
+ }
+
+ //Cache ViewLists
+ for (map < eViewList, cTemplateViewList* >::iterator it = viewLists.begin(); it != viewLists.end(); it++) {
+ cTemplateViewList *viewList = it->second;
+ viewList->SetGlobals(globals);
+ viewList->SetContainer(0, 0, osdWidth, osdHeight);
+ viewList->CalculateListParameters();
+ }
+
+ //Cache ViewTabs
+ for (vector<cTemplateViewTab*>::iterator tab = viewTabs.begin(); tab != viewTabs.end(); tab++) {
+ (*tab)->SetContainer(containerX, containerY, containerWidth, containerHeight);
+ (*tab)->SetGlobals(globals);
+ (*tab)->CalculateParameters();
+ }
+
+ //Cache Subviews
+ for (map < eSubView, cTemplateView* >::iterator it = subViews.begin(); it != subViews.end(); it++) {
+ cTemplateView *subView = it->second;
+ subView->SetContainer(0, 0, osdWidth, osdHeight);
+ subView->PreCache(true);
+ }
+
+}
+
+void cTemplateView::Debug(void) {
+
+ esyslog("skindesigner: TemplateView %s", viewName.c_str());;
+
+ parameters->Debug();
+
+ for (map < eViewElement, cTemplateViewElement* >::iterator it = viewElements.begin(); it != viewElements.end(); it++) {
+ esyslog("skindesigner: ++++++++ ViewElement: %s", GetViewElementName(it->first).c_str());
+ cTemplateViewElement *viewElement = it->second;
+ viewElement->Debug();
+ }
+
+ for (map < eViewList, cTemplateViewList* >::iterator it = viewLists.begin(); it != viewLists.end(); it++) {
+ esyslog("skindesigner: ++++++++ ViewList: %s", GetViewListName(it->first).c_str());
+ cTemplateViewList *viewList = it->second;
+ viewList->Debug();
+ }
+
+ for (vector<cTemplateViewTab*>::iterator tab = viewTabs.begin(); tab != viewTabs.end(); tab++) {
+ esyslog("skindesigner: ++++++++ ViewTab");
+ (*tab)->Debug();
+ }
+
+ for (map < eSubView, cTemplateView* >::iterator it = subViews.begin(); it!= subViews.end(); it++) {
+ esyslog("skindesigner: ++++++++ SubView: %s", GetSubViewName(it->first).c_str());
+ cTemplateView *subView = it->second;
+ subView->Debug();
+ }
+
+}
+
+
+void cTemplateView::SetFunctionDefinitions(void) {
+
+ string name = "area";
+ set<string> attributes;
+ attributes.insert("debug");
+ attributes.insert("condition");
+ attributes.insert("x");
+ attributes.insert("y");
+ attributes.insert("width");
+ attributes.insert("height");
+ attributes.insert("layer");
+ attributes.insert("transparency");
+ funcsAllowed.insert(pair< string, set<string> >(name, attributes));
+
+ name = "areascroll";
+ attributes.clear();
+ attributes.insert("debug");
+ attributes.insert("orientation");
+ attributes.insert("delay");
+ attributes.insert("mode");
+ attributes.insert("scrollspeed");
+ attributes.insert("condition");
+ attributes.insert("scrollelement");
+ attributes.insert("x");
+ attributes.insert("y");
+ attributes.insert("width");
+ attributes.insert("height");
+ attributes.insert("layer");
+ attributes.insert("transparency");
+ funcsAllowed.insert(pair< string, set<string> >(name, attributes));
+
+ name = "loop";
+ attributes.clear();
+ attributes.insert("debug");
+ attributes.insert("name");
+ attributes.insert("orientation");
+ attributes.insert("condition");
+ attributes.insert("x");
+ attributes.insert("y");
+ attributes.insert("width");
+ attributes.insert("height");
+ attributes.insert("columnwidth");
+ attributes.insert("rowheight");
+ attributes.insert("overflow");
+ attributes.insert("maxitems");
+ funcsAllowed.insert(pair< string, set<string> >(name, attributes));
+
+ name = "fill";
+ attributes.clear();
+ attributes.insert("debug");
+ attributes.insert("condition");
+ attributes.insert("color");
+ funcsAllowed.insert(pair< string, set<string> >(name, attributes));
+
+ name = "drawtext";
+ attributes.clear();
+ attributes.insert("debug");
+ attributes.insert("condition");
+ attributes.insert("name");
+ attributes.insert("x");
+ attributes.insert("y");
+ attributes.insert("width");
+ attributes.insert("align");
+ attributes.insert("valign");
+ attributes.insert("font");
+ attributes.insert("fontsize");
+ attributes.insert("color");
+ attributes.insert("text");
+ funcsAllowed.insert(pair< string, set<string> >(name, attributes));
+
+ name = "drawtextbox";
+ attributes.clear();
+ attributes.insert("debug");
+ attributes.insert("condition");
+ attributes.insert("name");
+ attributes.insert("x");
+ attributes.insert("y");
+ attributes.insert("width");
+ attributes.insert("height");
+ attributes.insert("align");
+ attributes.insert("maxlines");
+ attributes.insert("font");
+ attributes.insert("fontsize");
+ attributes.insert("color");
+ attributes.insert("text");
+ attributes.insert("float");
+ attributes.insert("floatwidth");
+ attributes.insert("floatheight");
+ funcsAllowed.insert(pair< string, set<string> >(name, attributes));
+
+ name = "drawimage";
+ attributes.clear();
+ attributes.insert("debug");
+ attributes.insert("condition");
+ attributes.insert("name");
+ attributes.insert("x");
+ attributes.insert("y");
+ attributes.insert("align");
+ attributes.insert("valign");
+ attributes.insert("width");
+ attributes.insert("height");
+ attributes.insert("imagetype");
+ attributes.insert("path");
+ attributes.insert("align");
+ attributes.insert("valign");
+ attributes.insert("cache");
+ funcsAllowed.insert(pair< string, set<string> >(name, attributes));
+
+ name = "drawrectangle";
+ attributes.clear();
+ attributes.insert("debug");
+ attributes.insert("condition");
+ attributes.insert("name");
+ attributes.insert("x");
+ attributes.insert("y");
+ attributes.insert("align");
+ attributes.insert("valign");
+ attributes.insert("width");
+ attributes.insert("height");
+ attributes.insert("color");
+ funcsAllowed.insert(pair< string, set<string> >(name, attributes));
+
+ name = "drawellipse";
+ attributes.clear();
+ attributes.insert("debug");
+ attributes.insert("condition");
+ attributes.insert("name");
+ attributes.insert("x");
+ attributes.insert("y");
+ attributes.insert("align");
+ attributes.insert("valign");
+ attributes.insert("width");
+ attributes.insert("height");
+ attributes.insert("color");
+ attributes.insert("quadrant");
+ funcsAllowed.insert(pair< string, set<string> >(name, attributes));
+
+}
+
+/************************************************************************************
+* cTemplateViewChannel
+************************************************************************************/
+
+cTemplateViewChannel::cTemplateViewChannel(void) {
+
+ viewName = "displaychannel";
+ //definition of allowed parameters for class itself
+ set<string> attributes;
+ attributes.insert("x");
+ attributes.insert("y");
+ attributes.insert("width");
+ attributes.insert("height");
+ attributes.insert("fadetime");
+ attributes.insert("scaletvx");
+ attributes.insert("scaletvy");
+ attributes.insert("scaletvwidth");
+ attributes.insert("scaletvheight");
+ funcsAllowed.insert(pair< string, set<string> >(viewName, attributes));
+
+ SetViewElements();
+}
+
+cTemplateViewChannel::~cTemplateViewChannel() {
+}
+
+void cTemplateViewChannel::SetViewElements(void) {
+ viewElementsAllowed.insert("background");
+ viewElementsAllowed.insert("channelinfo");
+ viewElementsAllowed.insert("channelgroup");
+ viewElementsAllowed.insert("epginfo");
+ viewElementsAllowed.insert("progressbar");
+ viewElementsAllowed.insert("progressbarback");
+ viewElementsAllowed.insert("statusinfo");
+ viewElementsAllowed.insert("screenresolution");
+ viewElementsAllowed.insert("signalquality");
+ viewElementsAllowed.insert("signalqualityback");
+ viewElementsAllowed.insert("scrapercontent");
+ viewElementsAllowed.insert("datetime");
+ viewElementsAllowed.insert("message");
+}
+
+string cTemplateViewChannel::GetViewElementName(eViewElement ve) {
+ string name;
+ switch (ve) {
+ case veBackground:
+ name = "Background";
+ break;
+ case veChannelInfo:
+ name = "ChannelInfo";
+ break;
+ case veChannelGroup:
+ name = "ChannelGroup";
+ break;
+ case veEpgInfo:
+ name = "EpgInfo";
+ break;
+ case veProgressBar:
+ name = "ProgressBar";
+ break;
+ case veProgressBarBack:
+ name = "ProgressBar Background";
+ break;
+ case veStatusInfo:
+ name = "StatusInfo";
+ break;
+ case veScreenResolution:
+ name = "Screen Resolution";
+ break;
+ case veSignalQuality:
+ name = "Signal Quality";
+ break;
+ case veSignalQualityBack:
+ name = "Signal Quality Background";
+ break;
+ case veScraperContent:
+ name = "Scraper Content";
+ break;
+ case veDateTime:
+ name = "DateTime";
+ break;
+ case veMessage:
+ name = "Message";
+ break;
+ default:
+ name = "Unknown";
+ break;
+ };
+ return name;
+}
+
+void cTemplateViewChannel::AddPixmap(string sViewElement, cTemplatePixmap *pix, bool debugViewElement) {
+ eViewElement ve = veUndefined;
+
+ if (!sViewElement.compare("background")) {
+ ve = veBackground;
+ } else if (!sViewElement.compare("channelinfo")) {
+ ve = veChannelInfo;
+ } else if (!sViewElement.compare("channelgroup")) {
+ ve = veChannelGroup;
+ } else if (!sViewElement.compare("epginfo")) {
+ ve = veEpgInfo;
+ } else if (!sViewElement.compare("progressbar")) {
+ ve = veProgressBar;
+ } else if (!sViewElement.compare("progressbarback")) {
+ ve = veProgressBarBack;
+ } else if (!sViewElement.compare("statusinfo")) {
+ ve = veStatusInfo;
+ } else if (!sViewElement.compare("screenresolution")) {
+ ve = veScreenResolution;
+ } else if (!sViewElement.compare("signalquality")) {
+ ve = veSignalQuality;
+ } else if (!sViewElement.compare("signalqualityback")) {
+ ve = veSignalQualityBack;
+ } else if (!sViewElement.compare("scrapercontent")) {
+ ve = veScraperContent;
+ } else if (!sViewElement.compare("datetime")) {
+ ve = veDateTime;
+ } else if (!sViewElement.compare("message")) {
+ ve = veMessage;
+ }
+
+ if (ve == veUndefined) {
+ esyslog("skindesigner: unknown ViewElement in displaychannel: %s", sViewElement.c_str());
+ return;
+ }
+
+ pix->SetGlobals(globals);
+
+ map < eViewElement, cTemplateViewElement* >::iterator hit = viewElements.find(ve);
+ if (hit == viewElements.end()) {
+ cTemplateViewElement *viewElement = new cTemplateViewElement();
+ viewElement->AddPixmap(pix);
+ viewElements.insert(pair< eViewElement, cTemplateViewElement*>(ve, viewElement));
+ if (debugViewElement)
+ viewElement->ActivateDebugTokens();
+ } else {
+ (hit->second)->AddPixmap(pix);
+ }
+}
+
+/************************************************************************************
+* cTemplateViewMenu
+************************************************************************************/
+
+cTemplateViewMenu::cTemplateViewMenu(void) {
+
+ viewName = "displaymenu";
+ //definition of allowed parameters for class itself
+ set<string> attributes;
+ attributes.insert("x");
+ attributes.insert("y");
+ attributes.insert("width");
+ attributes.insert("height");
+ attributes.insert("fadetime");
+ funcsAllowed.insert(pair< string, set<string> >(viewName, attributes));
+
+ string subViewName = "menudefault";
+ //definition of allowed parameters for subtemplate menumain
+ attributes.clear();
+ attributes.insert("x");
+ attributes.insert("y");
+ attributes.insert("width");
+ attributes.insert("height");
+ attributes.insert("fadetime");
+ attributes.insert("scaletvx");
+ attributes.insert("scaletvy");
+ attributes.insert("scaletvwidth");
+ attributes.insert("scaletvheight");
+ funcsAllowed.insert(pair< string, set<string> >(subViewName, attributes));
+
+ subViewName = "menumain";
+ //definition of allowed parameters for subtemplate menumain
+ attributes.clear();
+ attributes.insert("x");
+ attributes.insert("y");
+ attributes.insert("width");
+ attributes.insert("height");
+ attributes.insert("fadetime");
+ attributes.insert("scaletvx");
+ attributes.insert("scaletvy");
+ attributes.insert("scaletvwidth");
+ attributes.insert("scaletvheight");
+ funcsAllowed.insert(pair< string, set<string> >(subViewName, attributes));
+
+ subViewName = "menusetup";
+ //definition of allowed parameters for subtemplate menumain
+ attributes.clear();
+ attributes.insert("x");
+ attributes.insert("y");
+ attributes.insert("width");
+ attributes.insert("height");
+ attributes.insert("fadetime");
+ attributes.insert("scaletvx");
+ attributes.insert("scaletvy");
+ attributes.insert("scaletvwidth");
+ attributes.insert("scaletvheight");
+ funcsAllowed.insert(pair< string, set<string> >(subViewName, attributes));
+
+ subViewName = "menuschedules";
+ //definition of allowed parameters for subtemplate menumain
+ attributes.clear();
+ attributes.insert("x");
+ attributes.insert("y");
+ attributes.insert("width");
+ attributes.insert("height");
+ attributes.insert("fadetime");
+ attributes.insert("scaletvx");
+ attributes.insert("scaletvy");
+ attributes.insert("scaletvwidth");
+ attributes.insert("scaletvheight");
+ funcsAllowed.insert(pair< string, set<string> >(subViewName, attributes));
+
+ subViewName = "menuchannels";
+ //definition of allowed parameters for subtemplate menumain
+ attributes.clear();
+ attributes.insert("x");
+ attributes.insert("y");
+ attributes.insert("width");
+ attributes.insert("height");
+ attributes.insert("fadetime");
+ attributes.insert("scaletvx");
+ attributes.insert("scaletvy");
+ attributes.insert("scaletvwidth");
+ attributes.insert("scaletvheight");
+ funcsAllowed.insert(pair< string, set<string> >(subViewName, attributes));
+
+ subViewName = "menutimers";
+ //definition of allowed parameters for subtemplate menumain
+ attributes.clear();
+ attributes.insert("x");
+ attributes.insert("y");
+ attributes.insert("width");
+ attributes.insert("height");
+ attributes.insert("fadetime");
+ attributes.insert("scaletvx");
+ attributes.insert("scaletvy");
+ attributes.insert("scaletvwidth");
+ attributes.insert("scaletvheight");
+ funcsAllowed.insert(pair< string, set<string> >(subViewName, attributes));
+
+ subViewName = "menurecordings";
+ //definition of allowed parameters for subtemplate menumain
+ attributes.clear();
+ attributes.insert("x");
+ attributes.insert("y");
+ attributes.insert("width");
+ attributes.insert("height");
+ attributes.insert("fadetime");
+ attributes.insert("scaletvx");
+ attributes.insert("scaletvy");
+ attributes.insert("scaletvwidth");
+ attributes.insert("scaletvheight");
+ funcsAllowed.insert(pair< string, set<string> >(subViewName, attributes));
+
+ subViewName = "menudetailedepg";
+ //definition of allowed parameters for subtemplate menumain
+ attributes.clear();
+ attributes.insert("x");
+ attributes.insert("y");
+ attributes.insert("width");
+ attributes.insert("height");
+ attributes.insert("fadetime");
+ attributes.insert("scaletvx");
+ attributes.insert("scaletvy");
+ attributes.insert("scaletvwidth");
+ attributes.insert("scaletvheight");
+ funcsAllowed.insert(pair< string, set<string> >(subViewName, attributes));
+
+ subViewName = "menudetailedrecording";
+ //definition of allowed parameters for subtemplate menumain
+ attributes.clear();
+ attributes.insert("x");
+ attributes.insert("y");
+ attributes.insert("width");
+ attributes.insert("height");
+ attributes.insert("fadetime");
+ attributes.insert("scaletvx");
+ attributes.insert("scaletvy");
+ attributes.insert("scaletvwidth");
+ attributes.insert("scaletvheight");
+ funcsAllowed.insert(pair< string, set<string> >(subViewName, attributes));
+
+ subViewName = "menudetailedtext";
+ //definition of allowed parameters for subtemplate menumain
+ attributes.clear();
+ attributes.insert("x");
+ attributes.insert("y");
+ attributes.insert("width");
+ attributes.insert("height");
+ attributes.insert("fadetime");
+ attributes.insert("scaletvx");
+ attributes.insert("scaletvy");
+ attributes.insert("scaletvwidth");
+ attributes.insert("scaletvheight");
+ funcsAllowed.insert(pair< string, set<string> >(subViewName, attributes));
+
+ //definition of allowed parameters for timerlist viewlist
+ attributes.clear();
+ attributes.insert("x");
+ attributes.insert("y");
+ attributes.insert("width");
+ attributes.insert("height");
+ attributes.insert("orientation");
+ attributes.insert("align");
+ attributes.insert("numlistelements");
+ funcsAllowed.insert(pair< string, set<string> >("timerlist", attributes));
+
+ //definition of allowed parameters for menuitems viewlist
+ attributes.clear();
+ attributes.insert("x");
+ attributes.insert("y");
+ attributes.insert("width");
+ attributes.insert("height");
+ attributes.insert("orientation");
+ attributes.insert("align");
+ attributes.insert("menuitemwidth");
+ attributes.insert("determinatefont");
+ attributes.insert("numlistelements");
+ funcsAllowed.insert(pair< string, set<string> >("menuitems", attributes));
+
+ //definition of allowed parameters for currentitems viewlist
+ attributes.clear();
+ attributes.insert("delay");
+ attributes.insert("fadetime");
+ funcsAllowed.insert(pair< string, set<string> >("currentelement", attributes));
+
+ //definition of allowed parameters for viewtab
+ attributes.clear();
+ attributes.insert("debug");
+ attributes.insert("name");
+ attributes.insert("condition");
+ attributes.insert("x");
+ attributes.insert("y");
+ attributes.insert("width");
+ attributes.insert("height");
+ attributes.insert("layer");
+ attributes.insert("transparency");
+ attributes.insert("scrollheight");
+ funcsAllowed.insert(pair< string, set<string> >("tab", attributes));
+
+ SetSubViews();
+ SetViewElements();
+ SetViewLists();
+
+}
+
+cTemplateViewMenu::~cTemplateViewMenu() {
+}
+
+void cTemplateViewMenu::SetSubViews(void) {
+ subViewsAllowed.insert("menudefault");
+ subViewsAllowed.insert("menumain");
+ subViewsAllowed.insert("menusetup");
+ subViewsAllowed.insert("menuschedules");
+ subViewsAllowed.insert("menutimers");
+ subViewsAllowed.insert("menurecordings");
+ subViewsAllowed.insert("menuchannels");
+ subViewsAllowed.insert("menudetailedepg");
+ subViewsAllowed.insert("menudetailedrecording");
+ subViewsAllowed.insert("menudetailedtext");
+}
+
+void cTemplateViewMenu::SetViewElements(void) {
+ viewElementsAllowed.insert("background");
+ viewElementsAllowed.insert("datetime");
+ viewElementsAllowed.insert("header");
+ viewElementsAllowed.insert("colorbuttons");
+ viewElementsAllowed.insert("message");
+ viewElementsAllowed.insert("discusage");
+ viewElementsAllowed.insert("systemload");
+ viewElementsAllowed.insert("timers");
+ viewElementsAllowed.insert("devices");
+ viewElementsAllowed.insert("scrollbar");
+ viewElementsAllowed.insert("detailheader");
+ viewElementsAllowed.insert("tablabels");
+}
+
+void cTemplateViewMenu::SetViewLists(void) {
+ viewListsAllowed.insert("timerlist");
+ viewListsAllowed.insert("menuitems");
+}
+
+string cTemplateViewMenu::GetSubViewName(eSubView sv) {
+ string name;
+ switch (sv) {
+ case svMenuDefault:
+ name = "Default Menu";
+ break;
+ case svMenuMain:
+ name = "Main Menu";
+ break;
+ case svMenuSetup:
+ name = "Setup Menu";
+ break;
+ case svMenuSchedules:
+ name = "Schedules Menu";
+ break;
+ case svMenuTimers:
+ name = "Timers Menu";
+ break;
+ case svMenuRecordings:
+ name = "Recordings Menu";
+ break;
+ case svMenuChannels:
+ name = "Channels Menu";
+ break;
+ case svMenuDetailedEpg:
+ name = "Detailed EPG";
+ break;
+ case svMenuDetailedRecording:
+ name = "Detailed Recording";
+ break;
+ case svMenuDetailedText:
+ name = "Detailed Text";
+ break;
+ default:
+ name = "Unknown";
+ break;
+ };
+ return name;
+}
+
+
+string cTemplateViewMenu::GetViewElementName(eViewElement ve) {
+ string name;
+ switch (ve) {
+ case veBackground:
+ name = "Background";
+ break;
+ case veDateTime:
+ name = "DateTime";
+ break;
+ case veHeader:
+ name = "Header";
+ break;
+ case veButtons:
+ name = "Color Buttons";
+ break;
+ case veMessage:
+ name = "Message";
+ break;
+ case veDiscUsage:
+ name = "Disc Usage";
+ break;
+ case veSystemLoad:
+ name = "System Load";
+ break;
+ case veTimers:
+ name = "Timers";
+ break;
+ case veDevices:
+ name = "Devices";
+ break;
+ case veMenuItem:
+ name = "Menu Item";
+ break;
+ case veMenuCurrentItemDetail:
+ name = "Menu Current Item Detail";
+ break;
+ case veScrollbar:
+ name = "Scrollbar";
+ break;
+ case veDetailHeader:
+ name = "Detail header";
+ break;
+ case veTabLabels:
+ name = "tab labels";
+ break;
+ default:
+ name = "Unknown";
+ break;
+ };
+ return name;
+}
+
+string cTemplateViewMenu::GetViewListName(eViewList vl) {
+ string name;
+ switch (vl) {
+ case vlTimerList:
+ name = "Timer List";
+ break;
+ case vlMenuItem:
+ name = "Menu Item";
+ break;
+ default:
+ name = "Unknown";
+ break;
+ };
+ return name;
+}
+
+void cTemplateViewMenu::AddSubView(string sSubView, cTemplateView *subView) {
+ eSubView sv = svUndefined;
+
+ if (!sSubView.compare("menumain")) {
+ sv = svMenuMain;
+ } else if (!sSubView.compare("menudefault")) {
+ sv = svMenuDefault;
+ } else if (!sSubView.compare("menuschedules")) {
+ sv = svMenuSchedules;
+ } else if (!sSubView.compare("menusetup")) {
+ sv = svMenuSetup;
+ } else if (!sSubView.compare("menuschedules")) {
+ sv = svMenuSchedules;
+ } else if (!sSubView.compare("menutimers")) {
+ sv = svMenuTimers;
+ } else if (!sSubView.compare("menurecordings")) {
+ sv = svMenuRecordings;
+ } else if (!sSubView.compare("menuchannels")) {
+ sv = svMenuChannels;
+ } else if (!sSubView.compare("menudetailedepg")) {
+ sv = svMenuDetailedEpg;
+ } else if (!sSubView.compare("menudetailedrecording")) {
+ sv = svMenuDetailedRecording;
+ } else if (!sSubView.compare("menudetailedtext")) {
+ sv = svMenuDetailedText;
+ }
+
+ if (sv == svUndefined) {
+ esyslog("skindesigner: unknown SubView in displayMenu: %s", sSubView.c_str());
+ return;
+ }
+ subView->SetGlobals(globals);
+ subViews.insert(pair<eSubView, cTemplateView*>(sv, subView));
+}
+
+void cTemplateViewMenu::AddPixmap(string sViewElement, cTemplatePixmap *pix, bool debugViewElement) {
+ eViewElement ve = veUndefined;
+
+ if (!sViewElement.compare("background")) {
+ ve = veBackground;
+ } else if (!sViewElement.compare("datetime")) {
+ ve = veDateTime;
+ } else if (!sViewElement.compare("header")) {
+ ve = veHeader;
+ } else if (!sViewElement.compare("colorbuttons")) {
+ ve = veButtons;
+ } else if (!sViewElement.compare("message")) {
+ ve = veMessage;
+ } else if (!sViewElement.compare("discusage")) {
+ ve = veDiscUsage;
+ } else if (!sViewElement.compare("systemload")) {
+ ve = veSystemLoad;
+ } else if (!sViewElement.compare("timers")) {
+ ve = veTimers;
+ } else if (!sViewElement.compare("devices")) {
+ ve = veDevices;
+ } else if (!sViewElement.compare("scrollbar")) {
+ ve = veScrollbar;
+ } else if (!sViewElement.compare("detailheader")) {
+ ve = veDetailHeader;
+ } else if (!sViewElement.compare("tablabels")) {
+ ve = veTabLabels;
+ }
+
+ if (ve == veUndefined) {
+ esyslog("skindesigner: unknown ViewElement in displayMenu: %s", sViewElement.c_str());
+ return;
+ }
+
+ pix->SetGlobals(globals);
+
+ map < eViewElement, cTemplateViewElement* >::iterator hit = viewElements.find(ve);
+ if (hit == viewElements.end()) {
+ cTemplateViewElement *viewElement = new cTemplateViewElement();
+ viewElement->AddPixmap(pix);
+ viewElements.insert(pair< eViewElement, cTemplateViewElement*>(ve, viewElement));
+ if (debugViewElement)
+ viewElement->ActivateDebugTokens();
+ } else {
+ (hit->second)->AddPixmap(pix);
+ }
+}
+
+void cTemplateViewMenu::AddViewList(string sViewList, cTemplateViewList *viewList) {
+
+ eViewList vl = vlUndefined;
+ if (!sViewList.compare("timerlist")) {
+ vl = vlTimerList;
+ } else if (!sViewList.compare("menuitems")) {
+ vl = vlMenuItem;
+ }
+
+ if (vl == vlUndefined) {
+ esyslog("skindesigner: unknown ViewList in displaymenu: %s", sViewList.c_str());
+ return;
+ }
+
+ viewList->SetGlobals(globals);
+ viewLists.insert(pair< eViewList, cTemplateViewList*>(vl, viewList));
+}
+
+void cTemplateViewMenu::AddViewTab(cTemplateViewTab *viewTab) {
+ viewTabs.push_back(viewTab);
+}
+
+/************************************************************************************
+* cTemplateViewMessage
+************************************************************************************/
+
+cTemplateViewMessage::cTemplateViewMessage(void) {
+
+ viewName = "displaymessage";
+ //definition of allowed parameters for class itself
+ set<string> attributes;
+ attributes.insert("x");
+ attributes.insert("y");
+ attributes.insert("width");
+ attributes.insert("height");
+ attributes.insert("fadetime");
+ attributes.insert("scaletvx");
+ attributes.insert("scaletvy");
+ attributes.insert("scaletvwidth");
+ attributes.insert("scaletvheight");
+ funcsAllowed.insert(pair< string, set<string> >(viewName, attributes));
+
+ SetViewElements();
+}
+
+cTemplateViewMessage::~cTemplateViewMessage() {
+}
+
+void cTemplateViewMessage::SetViewElements(void) {
+ viewElementsAllowed.insert("background");
+ viewElementsAllowed.insert("message");
+}
+
+string cTemplateViewMessage::GetViewElementName(eViewElement ve) {
+ string name;
+ switch (ve) {
+ case veBackground:
+ name = "Background";
+ break;
+ case veMessage:
+ name = "Message";
+ break;
+ default:
+ name = "Unknown";
+ break;
+ };
+ return name;
+}
+
+void cTemplateViewMessage::AddPixmap(string sViewElement, cTemplatePixmap *pix, bool debugViewElement) {
+ eViewElement ve = veUndefined;
+
+ if (!sViewElement.compare("background")) {
+ ve = veBackground;
+ } else if (!sViewElement.compare("message")) {
+ ve = veMessage;
+ }
+
+ if (ve == veUndefined) {
+ esyslog("skindesigner: unknown ViewElement in displaymessage: %s", sViewElement.c_str());
+ return;
+ }
+
+ pix->SetGlobals(globals);
+
+ map < eViewElement, cTemplateViewElement* >::iterator hit = viewElements.find(ve);
+ if (hit == viewElements.end()) {
+ cTemplateViewElement *viewElement = new cTemplateViewElement();
+ viewElement->AddPixmap(pix);
+ viewElements.insert(pair< eViewElement, cTemplateViewElement*>(ve, viewElement));
+ if (debugViewElement)
+ viewElement->ActivateDebugTokens();
+ } else {
+ (hit->second)->AddPixmap(pix);
+ }
+}
+
+/************************************************************************************
+* cTemplateViewReplay
+************************************************************************************/
+
+cTemplateViewReplay::cTemplateViewReplay(void) {
+
+ viewName = "displayreplay";
+ //definition of allowed parameters for class itself
+ set<string> attributes;
+ attributes.insert("x");
+ attributes.insert("y");
+ attributes.insert("width");
+ attributes.insert("height");
+ attributes.insert("fadetime");
+ attributes.insert("scaletvx");
+ attributes.insert("scaletvy");
+ attributes.insert("scaletvwidth");
+ attributes.insert("scaletvheight");
+ funcsAllowed.insert(pair< string, set<string> >(viewName, attributes));
+
+ SetViewElements();
+}
+
+cTemplateViewReplay::~cTemplateViewReplay() {
+}
+
+void cTemplateViewReplay::SetViewElements(void) {
+ viewElementsAllowed.insert("background");
+ viewElementsAllowed.insert("backgroundmodeonly");
+ viewElementsAllowed.insert("datetime");
+ viewElementsAllowed.insert("rectitle");
+ viewElementsAllowed.insert("recinfo");
+ viewElementsAllowed.insert("scrapercontent");
+ viewElementsAllowed.insert("currenttime");
+ viewElementsAllowed.insert("totaltime");
+ viewElementsAllowed.insert("progressbar");
+ viewElementsAllowed.insert("cutmarks");
+ viewElementsAllowed.insert("controlicons");
+ viewElementsAllowed.insert("controliconsmodeonly");
+ viewElementsAllowed.insert("jump");
+ viewElementsAllowed.insert("message");
+}
+
+string cTemplateViewReplay::GetViewElementName(eViewElement ve) {
+ string name;
+ switch (ve) {
+ case veBackground:
+ name = "Background";
+ break;
+ case veDateTime:
+ name = "DateTime";
+ break;
+ case veRecTitle:
+ name = "Recording Title";
+ break;
+ case veRecInfo:
+ name = "Recording Information";
+ break;
+ case veRecCurrent:
+ name = "Recording current Time";
+ break;
+ case veRecTotal:
+ name = "Recording total Time";
+ break;
+ case veRecProgressBar:
+ name = "Rec Progress Bar";
+ break;
+ case veCuttingMarks:
+ name = "Cutting Marks";
+ break;
+ case veControlIcons:
+ name = "Control Icons";
+ break;
+ case veControlIconsModeOnly:
+ name = "Control Icons Mode only";
+ break;
+ case veBackgroundModeOnly:
+ name = "Background Mode only";
+ break;
+ case veRecJump:
+ name = "Recording Jump";
+ break;
+ case veScraperContent:
+ name = "Scraper Content";
+ break;
+ default:
+ name = "Unknown";
+ break;
+ };
+ return name;
+}
+
+void cTemplateViewReplay::AddPixmap(string sViewElement, cTemplatePixmap *pix, bool debugViewElement) {
+ eViewElement ve = veUndefined;
+
+ if (!sViewElement.compare("background")) {
+ ve = veBackground;
+ } else if (!sViewElement.compare("datetime")) {
+ ve = veDateTime;
+ } else if (!sViewElement.compare("rectitle")) {
+ ve = veRecTitle;
+ } else if (!sViewElement.compare("recinfo")) {
+ ve = veRecInfo;
+ } else if (!sViewElement.compare("scrapercontent")) {
+ ve = veScraperContent;
+ } else if (!sViewElement.compare("currenttime")) {
+ ve = veRecCurrent;
+ } else if (!sViewElement.compare("totaltime")) {
+ ve = veRecTotal;
+ } else if (!sViewElement.compare("progressbar")) {
+ ve = veRecProgressBar;
+ } else if (!sViewElement.compare("cutmarks")) {
+ ve = veCuttingMarks;
+ } else if (!sViewElement.compare("controlicons")) {
+ ve = veControlIcons;
+ } else if (!sViewElement.compare("controliconsmodeonly")) {
+ ve = veControlIconsModeOnly;
+ } else if (!sViewElement.compare("backgroundmodeonly")) {
+ ve = veBackgroundModeOnly;
+ } else if (!sViewElement.compare("jump")) {
+ ve = veRecJump;
+ } else if (!sViewElement.compare("message")) {
+ ve = veMessage;
+ }
+
+ if (ve == veUndefined) {
+ esyslog("skindesigner: unknown ViewElement in displayreplay: %s", sViewElement.c_str());
+ return;
+ }
+
+ pix->SetGlobals(globals);
+
+ map < eViewElement, cTemplateViewElement* >::iterator hit = viewElements.find(ve);
+ if (hit == viewElements.end()) {
+ cTemplateViewElement *viewElement = new cTemplateViewElement();
+ viewElement->AddPixmap(pix);
+ viewElements.insert(pair< eViewElement, cTemplateViewElement*>(ve, viewElement));
+ if (debugViewElement)
+ viewElement->ActivateDebugTokens();
+ } else {
+ (hit->second)->AddPixmap(pix);
+ }
+}
+
+
+/************************************************************************************
+* cTemplateViewVolume
+************************************************************************************/
+
+cTemplateViewVolume::cTemplateViewVolume(void) {
+
+ viewName = "displayvolume";
+ //definition of allowed parameters for class itself
+ set<string> attributes;
+ attributes.insert("x");
+ attributes.insert("y");
+ attributes.insert("width");
+ attributes.insert("height");
+ attributes.insert("fadetime");
+ attributes.insert("scaletvx");
+ attributes.insert("scaletvy");
+ attributes.insert("scaletvwidth");
+ attributes.insert("scaletvheight");
+ funcsAllowed.insert(pair< string, set<string> >(viewName, attributes));
+
+ SetViewElements();
+}
+
+cTemplateViewVolume::~cTemplateViewVolume() {
+}
+
+void cTemplateViewVolume::SetViewElements(void) {
+ viewElementsAllowed.insert("background");
+ viewElementsAllowed.insert("volume");
+}
+
+string cTemplateViewVolume::GetViewElementName(eViewElement ve) {
+ string name;
+ switch (ve) {
+ case veBackground:
+ name = "Background";
+ break;
+ case veVolume:
+ name = "Volume";
+ break;
+ default:
+ name = "Unknown";
+ break;
+ };
+ return name;
+}
+
+void cTemplateViewVolume::AddPixmap(string sViewElement, cTemplatePixmap *pix, bool debugViewElement) {
+ eViewElement ve = veUndefined;
+
+ if (!sViewElement.compare("background")) {
+ ve = veBackground;
+ } else if (!sViewElement.compare("volume")) {
+ ve = veVolume;
+ }
+
+ if (ve == veUndefined) {
+ esyslog("skindesigner: unknown ViewElement in displayvolume: %s", sViewElement.c_str());
+ return;
+ }
+
+ pix->SetGlobals(globals);
+
+ map < eViewElement, cTemplateViewElement* >::iterator hit = viewElements.find(ve);
+ if (hit == viewElements.end()) {
+ cTemplateViewElement *viewElement = new cTemplateViewElement();
+ viewElement->AddPixmap(pix);
+ viewElements.insert(pair< eViewElement, cTemplateViewElement*>(ve, viewElement));
+ if (debugViewElement)
+ viewElement->ActivateDebugTokens();
+ } else {
+ (hit->second)->AddPixmap(pix);
+ }
+}
+
+/************************************************************************************
+* cTemplateViewAudioTracks
+************************************************************************************/
+
+cTemplateViewAudioTracks::cTemplateViewAudioTracks(void) {
+
+ viewName = "displayaudiotracks";
+ //definition of allowed parameters for class itself
+ set<string> attributes;
+ attributes.insert("x");
+ attributes.insert("y");
+ attributes.insert("width");
+ attributes.insert("height");
+ attributes.insert("fadetime");
+ attributes.insert("scaletvx");
+ attributes.insert("scaletvy");
+ attributes.insert("scaletvwidth");
+ attributes.insert("scaletvheight");
+ funcsAllowed.insert(pair< string, set<string> >(viewName, attributes));
+
+ //definition of allowed parameters for menuitems viewlist
+ attributes.clear();
+ attributes.insert("x");
+ attributes.insert("y");
+ attributes.insert("width");
+ attributes.insert("height");
+ attributes.insert("orientation");
+ attributes.insert("align");
+ attributes.insert("menuitemwidth");
+ attributes.insert("numlistelements");
+ funcsAllowed.insert(pair< string, set<string> >("menuitems", attributes));
+
+ SetViewElements();
+ SetViewLists();
+}
+
+cTemplateViewAudioTracks::~cTemplateViewAudioTracks() {
+}
+
+void cTemplateViewAudioTracks::SetViewElements(void) {
+ viewElementsAllowed.insert("background");
+ viewElementsAllowed.insert("header");
+}
+
+void cTemplateViewAudioTracks::SetViewLists(void) {
+ viewListsAllowed.insert("menuitems");
+}
+
+string cTemplateViewAudioTracks::GetViewElementName(eViewElement ve) {
+ string name;
+ switch (ve) {
+ case veBackground:
+ name = "Background";
+ break;
+ case veHeader:
+ name = "Header";
+ break;
+ default:
+ name = "Unknown";
+ break;
+ };
+ return name;
+}
+
+string cTemplateViewAudioTracks::GetViewListName(eViewList vl) {
+ string name;
+ switch (vl) {
+ case vlMenuItem:
+ name = "Menu Item";
+ break;
+ default:
+ name = "Unknown";
+ break;
+ };
+ return name;
+}
+
+void cTemplateViewAudioTracks::AddPixmap(string sViewElement, cTemplatePixmap *pix, bool debugViewElement) {
+ eViewElement ve = veUndefined;
+
+ if (!sViewElement.compare("background")) {
+ ve = veBackground;
+ } else if(!sViewElement.compare("header")) {
+ ve = veHeader;
+ }
+
+ if (ve == veUndefined) {
+ esyslog("skindesigner: unknown ViewElement in displayaudiotracks: %s", sViewElement.c_str());
+ return;
+ }
+
+ pix->SetGlobals(globals);
+
+ map < eViewElement, cTemplateViewElement* >::iterator hit = viewElements.find(ve);
+ if (hit == viewElements.end()) {
+ cTemplateViewElement *viewElement = new cTemplateViewElement();
+ viewElement->AddPixmap(pix);
+ viewElements.insert(pair< eViewElement, cTemplateViewElement*>(ve, viewElement));
+ if (debugViewElement)
+ viewElement->ActivateDebugTokens();
+ } else {
+ (hit->second)->AddPixmap(pix);
+ }
+}
+
+void cTemplateViewAudioTracks::AddViewList(string sViewList, cTemplateViewList *viewList) {
+
+ eViewList vl = vlUndefined;
+ if (!sViewList.compare("menuitems")) {
+ vl = vlMenuItem;
+ }
+
+ if (vl == vlUndefined) {
+ esyslog("skindesigner: unknown ViewList in displaymenu: %s", sViewList.c_str());
+ return;
+ }
+
+ viewList->SetGlobals(globals);
+ viewLists.insert(pair< eViewList, cTemplateViewList*>(vl, viewList));
+}
diff --git a/libtemplate/templateview.h b/libtemplate/templateview.h
new file mode 100644
index 0000000..414deaa
--- /dev/null
+++ b/libtemplate/templateview.h
@@ -0,0 +1,198 @@
+#ifndef __TEMPLATEVIEW_H
+#define __TEMPLATEVIEW_H
+
+#include <iostream>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string>
+#include <vector>
+#include <map>
+#include <set>
+#include <sstream>
+
+#include "templateviewelement.h"
+#include "templateviewlist.h"
+#include "templatepixmap.h"
+#include "templateviewtab.h"
+#include "templatefunction.h"
+
+using namespace std;
+
+// --- cTemplateView -------------------------------------------------------------
+
+enum eSubView {
+ svUndefined,
+ svMenuDefault,
+ svMenuMain,
+ svMenuSetup,
+ svMenuSchedules,
+ svMenuTimers,
+ svMenuRecordings,
+ svMenuChannels,
+ svMenuDetailedEpg,
+ svMenuDetailedRecording,
+ svMenuDetailedText
+};
+
+class cTemplateView {
+private:
+protected:
+ cGlobals *globals;
+ //view parameters
+ string viewName;
+ cTemplateFunction *parameters;
+ int containerX;
+ int containerY;
+ int containerWidth;
+ int containerHeight;
+ //basic view data structures
+ map < eViewElement, cTemplateViewElement* > viewElements;
+ map < eViewList, cTemplateViewList* > viewLists;
+ map < eSubView, cTemplateView* > subViews;
+ vector< cTemplateViewTab* > viewTabs;
+ //helpers to iterate data structures
+ map < eViewElement, cTemplateViewElement* >::iterator veIt;
+ map < eViewList, cTemplateViewList* >::iterator vlIt;
+ map < eSubView, cTemplateView* >::iterator svIt;
+ vector< cTemplateViewTab* >::iterator vtIt;
+ //helpers to check valid xml templates
+ set<string> subViewsAllowed;
+ set<string> viewElementsAllowed;
+ set<string> viewListsAllowed;
+ map < string, set < string > > funcsAllowed;
+ void SetFunctionDefinitions(void);
+public:
+ cTemplateView(void);
+ virtual ~cTemplateView(void);
+ virtual string GetSubViewName(eSubView sv) { return ""; };
+ virtual string GetViewElementName(eViewElement ve) { return ""; };
+ virtual string GetViewListName(eViewList vl) { return ""; };
+ virtual void AddSubView(string sSubView, cTemplateView *subView) {};
+ virtual void AddPixmap(string sViewElement, cTemplatePixmap *pix, bool debugViewElement) {};
+ virtual void AddViewList(string sViewList, cTemplateViewList *viewList) {};
+ virtual void AddViewTab(cTemplateViewTab *viewTab) {};
+ //Setter Functions
+ void SetGlobals(cGlobals *globals) { this->globals = globals; };
+ void SetParameters(vector<pair<string, string> > &params);
+ void SetContainer(int x, int y, int width, int height);
+ //access view elements
+ cTemplateViewElement *GetViewElement(eViewElement ve);
+ void InitViewElementIterator(void);
+ cTemplateViewElement *GetNextViewElement(void);
+ //access list elements
+ cTemplateViewList *GetViewList(eViewList vl);
+ void InitViewListIterator(void);
+ cTemplateViewList *GetNextViewList(void);
+ //access tabs
+ void InitViewTabIterator(void);
+ cTemplateViewTab *GetNextViewTab(void);
+ //access sub views
+ cTemplateView *GetSubView(eSubView sv);
+ void InitSubViewIterator(void);
+ cTemplateView *GetNextSubView(void);
+ //Getter Functions
+ const char *GetViewName(void) { return viewName.c_str(); };
+ int GetNumericParameter(eParamType type);
+ cRect GetOsdSize(void);
+ int GetNumPixmaps(void);
+ int GetNumPixmapsViewElement(eViewElement ve);
+ int GetNumListViewMenuItems(void);
+ bool GetScalingWindow(cRect &scalingWindow);
+ //Checks for parsing template XML files
+ bool ValidSubView(const char *subView);
+ bool ValidViewElement(const char *viewElement);
+ bool ValidViewList(const char *viewList);
+ bool ValidFunction(const char *func);
+ bool ValidAttribute(const char *func, const char *att);
+ //Caching
+ void Translate(void);
+ void PreCache(bool isSubview);
+ //Debug
+ void Debug(void);
+};
+
+// --- cTemplateViewChannel -------------------------------------------------------------
+
+class cTemplateViewChannel : public cTemplateView {
+private:
+ void SetViewElements(void);
+ void SetViewLists(void);
+public:
+ cTemplateViewChannel(void);
+ virtual ~cTemplateViewChannel(void);
+ string GetViewElementName(eViewElement ve);
+ void AddPixmap(string viewElement, cTemplatePixmap *pix, bool debugViewElement);
+};
+
+// --- cTemplateViewMenu -------------------------------------------------------------
+
+class cTemplateViewMenu : public cTemplateView {
+private:
+ void SetSubViews(void);
+ void SetViewElements(void);
+ void SetViewLists(void);
+public:
+ cTemplateViewMenu(void);
+ virtual ~cTemplateViewMenu(void);
+ string GetSubViewName(eSubView sv);
+ string GetViewElementName(eViewElement ve);
+ string GetViewListName(eViewList vl);
+ void AddSubView(string sSubView, cTemplateView *subView);
+ void AddPixmap(string viewElement, cTemplatePixmap *pix, bool debugViewElement);
+ void AddViewList(string sViewList, cTemplateViewList *viewList);
+ void AddViewTab(cTemplateViewTab *viewTab);
+};
+
+// --- cTemplateViewMessage -------------------------------------------------------------
+
+class cTemplateViewMessage : public cTemplateView {
+private:
+ void SetViewElements(void);
+public:
+ cTemplateViewMessage(void);
+ virtual ~cTemplateViewMessage(void);
+ string GetViewElementName(eViewElement ve);
+ void AddPixmap(string viewElement, cTemplatePixmap *pix, bool debugViewElement);
+};
+
+// --- cTemplateViewReplay -------------------------------------------------------------
+
+class cTemplateViewReplay : public cTemplateView {
+private:
+ void SetViewElements(void);
+public:
+ cTemplateViewReplay(void);
+ virtual ~cTemplateViewReplay(void);
+ string GetViewElementName(eViewElement ve);
+ void AddPixmap(string viewElement, cTemplatePixmap *pix, bool debugViewElement);
+};
+
+// --- cTemplateViewVolume -------------------------------------------------------------
+
+class cTemplateViewVolume : public cTemplateView {
+private:
+ void SetViewElements(void);
+public:
+ cTemplateViewVolume(void);
+ virtual ~cTemplateViewVolume(void);
+ string GetViewElementName(eViewElement ve);
+ void AddPixmap(string viewElement, cTemplatePixmap *pix, bool debugViewElement);
+};
+
+// --- cTemplateViewAudioTracks -------------------------------------------------------------
+
+class cTemplateViewAudioTracks : public cTemplateView {
+private:
+ void SetViewElements(void);
+ void SetViewLists(void);
+public:
+ cTemplateViewAudioTracks(void);
+ virtual ~cTemplateViewAudioTracks(void);
+ string GetViewElementName(eViewElement ve);
+ string GetViewListName(eViewList vl);
+ void AddPixmap(string viewElement, cTemplatePixmap *pix, bool debugViewElement);
+ void AddViewList(string sViewList, cTemplateViewList *viewList);
+};
+
+#endif //__TEMPLATEVIEW_H
diff --git a/libtemplate/templateviewelement.c b/libtemplate/templateviewelement.c
new file mode 100644
index 0000000..87aeade
--- /dev/null
+++ b/libtemplate/templateviewelement.c
@@ -0,0 +1,128 @@
+#include "templateviewelement.h"
+#include "../config.h"
+
+cTemplateViewElement::cTemplateViewElement(void) {
+ debugTokens = false;
+ parameters = NULL;
+ containerX = 0;
+ containerY = 0;
+ containerWidth = 0;
+ containerHeight = 0;
+ pixOffset = -1;
+}
+
+cTemplateViewElement::~cTemplateViewElement(void) {
+ if (parameters)
+ delete parameters;
+ for (vector<cTemplatePixmap*>::iterator it = viewPixmaps.begin(); it != viewPixmaps.end(); it++) {
+ delete (*it);
+ }
+}
+
+void cTemplateViewElement::SetContainer(int x, int y, int width, int height) {
+ containerX = x;
+ containerY = y;
+ containerWidth = width;
+ containerHeight = height;
+}
+
+void cTemplateViewElement::SetGlobals(cGlobals *globals) {
+ this->globals = globals;
+ for (vector<cTemplatePixmap*>::iterator pix = viewPixmaps.begin(); pix != viewPixmaps.end(); pix++) {
+ (*pix)->SetGlobals(globals);
+ }
+}
+
+void cTemplateViewElement::SetParameters(vector<pair<string, string> > &params) {
+ parameters = new cTemplateFunction(ftViewElement);
+ parameters->SetGlobals(globals);
+ parameters->SetParameters(params);
+}
+
+bool cTemplateViewElement::CalculateParameters(void) {
+ if (!parameters)
+ return true;
+ bool paramsValid = true;
+ parameters->SetContainer(containerX, containerY, containerWidth, containerHeight);
+ parameters->SetGlobals(globals);
+ paramsValid = parameters->CalculateParameters();
+
+ return paramsValid;
+}
+
+bool cTemplateViewElement::CalculatePixmapParameters(void) {
+ bool paramsValid = true;
+ for (vector<cTemplatePixmap*>::iterator pix = viewPixmaps.begin(); pix != viewPixmaps.end(); pix++) {
+ (*pix)->SetContainer(containerX, containerY, containerWidth, containerHeight);
+ (*pix)->SetGlobals(globals);
+ paramsValid = paramsValid && (*pix)->CalculateParameters();
+ }
+ return paramsValid;
+}
+
+bool cTemplateViewElement::CalculatePixmapParametersList(int orientation, int numElements) {
+ bool paramsValid = true;
+ for (vector<cTemplatePixmap*>::iterator pix = viewPixmaps.begin(); pix != viewPixmaps.end(); pix++) {
+ (*pix)->SetContainer(containerX, containerY, containerWidth, containerHeight);
+ (*pix)->SetGlobals(globals);
+ if (orientation == orHorizontal) {
+ if (numElements > 0) {
+ int width = containerWidth / numElements;
+ (*pix)->SetWidth(width);
+ }
+ } else if (orientation == orVertical) {
+ if (numElements > 0) {
+ int height = containerHeight / numElements;
+ (*pix)->SetHeight(height);
+ }
+ }
+ paramsValid = paramsValid && (*pix)->CalculateParameters();
+ }
+ return paramsValid;
+}
+
+int cTemplateViewElement::GetNumericParameter(eParamType type) {
+ if (!parameters)
+ return -1;
+ return parameters->GetNumericParameter(type);
+}
+
+void cTemplateViewElement::InitIterator(void) {
+ pixIterator = viewPixmaps.begin();
+}
+
+cTemplatePixmap *cTemplateViewElement::GetNextPixmap(void) {
+ if (pixIterator == viewPixmaps.end())
+ return NULL;
+ cTemplatePixmap *pix = *pixIterator;
+ pixIterator++;
+ return pix;
+}
+
+cTemplateFunction *cTemplateViewElement::GetFunction(string name) {
+ InitIterator();
+ cTemplatePixmap *pix = NULL;
+ while (pix = GetNextPixmap()) {
+ pix->InitIterator();
+ cTemplateFunction *func = NULL;
+ while(func = pix->GetNextFunction()) {
+ if (func->GetType() == ftDrawText) {
+ string funcName = func->GetParameter(ptName);
+ if (!funcName.compare(name))
+ return func;
+ } else {
+ continue;
+ }
+ }
+ }
+ return NULL;
+}
+
+void cTemplateViewElement::Debug(void) {
+ esyslog("skindesigner: viewelement container size x: %d, y: %d, width: %d, height %d", containerX, containerY, containerWidth, containerHeight);
+ if (parameters)
+ parameters->Debug();
+ for (vector<cTemplatePixmap*>::iterator it = viewPixmaps.begin(); it != viewPixmaps.end(); it++) {
+ (*it)->Debug();
+ }
+} \ No newline at end of file
diff --git a/libtemplate/templateviewelement.h b/libtemplate/templateviewelement.h
new file mode 100644
index 0000000..84db627
--- /dev/null
+++ b/libtemplate/templateviewelement.h
@@ -0,0 +1,99 @@
+#ifndef __TEMPLATEVIEWELEMENT_H
+#define __TEMPLATEVIEWELEMENT_H
+
+#include <iostream>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string>
+#include <vector>
+#include <map>
+#include <set>
+#include <sstream>
+
+#include "templatepixmap.h"
+#include "templatefunction.h"
+
+using namespace std;
+
+// --- cTemplateViewElement -------------------------------------------------------------
+
+enum eViewElement {
+ //Common ViewElements
+ veUndefined,
+ veBackground,
+ veDateTime,
+ veMessage,
+ //DisplayChannel ViewElements
+ veChannelInfo,
+ veChannelGroup,
+ veEpgInfo,
+ veProgressBar,
+ veProgressBarBack,
+ veStatusInfo,
+ veScreenResolution,
+ veSignalQuality,
+ veSignalQualityBack,
+ veScraperContent,
+ //DisplayMenu ViewElements
+ veHeader,
+ veButtons,
+ veDiscUsage,
+ veSystemLoad,
+ veTimers,
+ veDevices,
+ veMenuItem,
+ veMenuCurrentItemDetail,
+ veScrollbar,
+ veDetailHeader,
+ veTabLabels,
+ //DisplayReplay ViewElements
+ veRecTitle,
+ veRecInfo,
+ veRecCurrent,
+ veRecTotal,
+ veRecProgressBar,
+ veCuttingMarks,
+ veControlIcons,
+ veControlIconsModeOnly,
+ veBackgroundModeOnly,
+ veRecJump,
+ //DisplayVolume ViewElements
+ veVolume
+};
+
+class cTemplateViewElement {
+protected:
+ bool debugTokens;
+ cGlobals *globals;
+ cTemplateFunction *parameters;
+ int containerX;
+ int containerY;
+ int containerWidth;
+ int containerHeight;
+ vector<cTemplatePixmap*> viewPixmaps;
+ vector<cTemplatePixmap*>::iterator pixIterator;
+ int pixOffset;
+public:
+ cTemplateViewElement(void);
+ virtual ~cTemplateViewElement(void);
+ void SetParameters(vector<pair<string, string> > &params);
+ bool CalculateParameters(void);
+ bool CalculatePixmapParameters(void);
+ bool CalculatePixmapParametersList(int orientation, int numElements);
+ int GetNumericParameter(eParamType type);
+ void AddPixmap(cTemplatePixmap *pix) { viewPixmaps.push_back(pix); };
+ virtual void SetGlobals(cGlobals *globals);
+ void SetContainer(int x, int y, int width, int height);
+ void SetPixOffset(int offset) { pixOffset = offset; };
+ int GetPixOffset(void) { return pixOffset; };
+ virtual int GetNumPixmaps(void) { return viewPixmaps.size(); };
+ void InitIterator(void);
+ cTemplatePixmap *GetNextPixmap(void);
+ cTemplateFunction *GetFunction(string name);
+ void ActivateDebugTokens(void) {debugTokens = true; };
+ bool DebugTokens(void) { return debugTokens; };
+ virtual void Debug(void);
+};
+
+#endif //__TEMPLATEVIEWELEMENT_H \ No newline at end of file
diff --git a/libtemplate/templateviewlist.c b/libtemplate/templateviewlist.c
new file mode 100644
index 0000000..808a89f
--- /dev/null
+++ b/libtemplate/templateviewlist.c
@@ -0,0 +1,138 @@
+#include "templateviewlist.h"
+#include "../config.h"
+
+cTemplateViewList::cTemplateViewList(void) : cTemplateViewElement() {
+ listElement = NULL;
+ currentElement = NULL;
+}
+
+cTemplateViewList::~cTemplateViewList(void) {
+ if (listElement)
+ delete listElement;
+ if (currentElement)
+ delete currentElement;
+}
+
+void cTemplateViewList::SetGlobals(cGlobals *globals) {
+ cTemplateViewElement::SetGlobals(globals);
+ if (listElement)
+ listElement->SetGlobals(globals);
+ if (currentElement)
+ currentElement->SetGlobals(globals);
+}
+
+bool cTemplateViewList::CalculateListParameters(void) {
+ if (!parameters)
+ return false;
+ parameters->SetContainer(containerX, containerY, containerWidth, containerHeight);
+ parameters->SetGlobals(globals);
+ bool paramsValid = parameters->CalculateParameters();
+ if (!listElement)
+ return false;
+ listElement->SetContainer(parameters->GetNumericParameter(ptX),
+ parameters->GetNumericParameter(ptY),
+ parameters->GetNumericParameter(ptWidth),
+ parameters->GetNumericParameter(ptHeight));
+ paramsValid = listElement->CalculateParameters();
+ paramsValid = listElement->CalculatePixmapParametersList(parameters->GetNumericParameter(ptOrientation),
+ parameters->GetNumericParameter(ptNumElements));
+ if (!currentElement)
+ return paramsValid;
+ currentElement->SetContainer(parameters->GetNumericParameter(ptX),
+ parameters->GetNumericParameter(ptY),
+ parameters->GetNumericParameter(ptWidth),
+ parameters->GetNumericParameter(ptHeight));
+ paramsValid = currentElement->CalculateParameters();
+ paramsValid = currentElement->CalculatePixmapParameters();
+ currentElement->SetPixOffset(0);
+ return paramsValid;
+}
+
+bool cTemplateViewList::CalculateListParameters(map < string, int > *intTokens) {
+ if (!parameters)
+ return false;
+ parameters->ClearDynamicParameters();
+ parameters->SetIntTokens(intTokens);
+ parameters->ParseParameters();
+ parameters->UnsetIntTokens();
+
+ listElement->SetContainer(parameters->GetNumericParameter(ptX),
+ parameters->GetNumericParameter(ptY),
+ parameters->GetNumericParameter(ptWidth),
+ parameters->GetNumericParameter(ptHeight));
+ bool paramsValid = listElement->CalculateParameters();
+ paramsValid = listElement->CalculatePixmapParametersList(parameters->GetNumericParameter(ptOrientation),
+ parameters->GetNumericParameter(ptNumElements));
+ return paramsValid;
+}
+
+int cTemplateViewList::GetAverageFontWidth(void) {
+ int defaultAverageFontWidth = 20;
+
+ if (!listElement)
+ return defaultAverageFontWidth;
+
+ int numItems = GetNumericParameter(ptNumElements);
+ int listHeight = GetNumericParameter(ptHeight);
+ if (listHeight <= 0)
+ return defaultAverageFontWidth;
+ int itemHeight = (double)listHeight / (double)numItems;
+ string fontFuncName = parameters->GetParameter(ptDeterminateFont);
+
+ cTemplateFunction *fontFunc = listElement->GetFunction(fontFuncName);
+ if (!fontFunc)
+ return defaultAverageFontWidth;
+
+ string fontNameToken = fontFunc->GetParameter(ptFont);
+ string paramFontSize = fontFunc->GetParameter(ptFontSize);
+
+ string fontName = "";
+ if ((fontNameToken.find("{") == 0) && (fontNameToken.find("}") == (fontNameToken.size()-1))) {
+ fontNameToken = fontNameToken.substr(1, fontNameToken.size()-2);
+ map<string,string>::iterator hit = globals->fonts.find(fontNameToken);
+ if (hit != globals->fonts.end()) {
+ fontName = hit->second;
+ } else {
+ map<string,string>::iterator def = globals->fonts.find("vdrOsd");
+ if (def == globals->fonts.end())
+ return defaultAverageFontWidth;
+ fontName = def->second;
+ }
+ } else {
+ //if no token, directly use input
+ fontName = fontNameToken;
+ }
+
+ cNumericParameter pFontSize(paramFontSize);
+ pFontSize.SetGlobals(globals);
+ pFontSize.SetAreaSize(1000, itemHeight);
+ pFontSize.SetVertical();
+ int fontSize = pFontSize.Parse(paramFontSize);
+ if (!pFontSize.Valid())
+ return defaultAverageFontWidth;
+
+ int averageFontWidth = fontManager->Width(fontName, fontSize, "x") + 3;
+ return averageFontWidth;
+}
+
+int cTemplateViewList::GetMenuItemWidth(void) {
+ return GetNumericParameter(ptMenuItemWidth);
+}
+
+
+int cTemplateViewList::GetNumPixmaps(void) {
+ if (!listElement)
+ return 0;
+ return listElement->GetNumPixmaps();
+}
+
+void cTemplateViewList::Debug(void) {
+ if (parameters)
+ parameters->Debug();
+ esyslog("skindesigner: --- listelement: ");
+ if (listElement)
+ listElement->Debug();
+ esyslog("skindesigner: --- currentelement: ");
+ if (currentElement)
+ currentElement->Debug();
+} \ No newline at end of file
diff --git a/libtemplate/templateviewlist.h b/libtemplate/templateviewlist.h
new file mode 100644
index 0000000..8998384
--- /dev/null
+++ b/libtemplate/templateviewlist.h
@@ -0,0 +1,49 @@
+#ifndef __TEMPLATEVIEWLIST_H
+#define __TEMPLATEVIEWLIST_H
+
+#include <iostream>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string>
+#include <vector>
+#include <map>
+#include <set>
+#include <sstream>
+
+#include "templateviewelement.h"
+
+using namespace std;
+
+// --- cTemplateViewList -------------------------------------------------------------
+
+enum eViewList {
+ vlUndefined,
+ //DisplayChannel ViewLists
+ vlDvbDeviceInfoList,
+ //DisplayMenu ViewLists
+ vlTimerList,
+ vlMenuItem
+};
+
+class cTemplateViewList : public cTemplateViewElement {
+private:
+ cTemplateViewElement *listElement;
+ cTemplateViewElement *currentElement;
+public:
+ cTemplateViewList(void);
+ ~cTemplateViewList(void);
+ void SetGlobals(cGlobals *globals);
+ void AddListElement(cTemplateViewElement *listElement) { this->listElement = listElement; };
+ void AddCurrentElement(cTemplateViewElement *currentElement) { this->currentElement = currentElement; };
+ bool CalculateListParameters(void);
+ bool CalculateListParameters(map < string, int > *intTokens);
+ cTemplateViewElement *GetListElement(void) { return listElement; };
+ cTemplateViewElement *GetListElementCurrent(void) { return currentElement; };
+ int GetAverageFontWidth(void);
+ int GetMenuItemWidth(void);
+ int GetNumPixmaps(void);
+ void Debug(void);
+};
+
+#endif //__TEMPLATEVIEWLIST_H \ No newline at end of file
diff --git a/libtemplate/templateviewtab.c b/libtemplate/templateviewtab.c
new file mode 100644
index 0000000..1e9f463
--- /dev/null
+++ b/libtemplate/templateviewtab.c
@@ -0,0 +1,38 @@
+#include "templateviewtab.h"
+
+cTemplateViewTab::cTemplateViewTab(void) : cTemplatePixmap() {
+ scrollStep = -1;
+}
+
+cTemplateViewTab::~cTemplateViewTab(void) {
+}
+
+int cTemplateViewTab::GetScrollStep(void) {
+ if (scrollStep > 0)
+ return scrollStep;
+ int pixWidth = GetNumericParameter(ptWidth);
+ int pixHeight = GetNumericParameter(ptHeight);
+ string scrollHeight = parameters->GetParameter(ptScrollHeight);
+
+ cNumericParameter p(scrollHeight);
+ p.SetAreaSize(pixWidth, pixHeight);
+ string parsedValue = "";
+ scrollStep = p.Parse(parsedValue);
+ if (scrollStep < 1)
+ scrollStep = 50;
+ return scrollStep;
+}
+
+string cTemplateViewTab::GetName(void) {
+ return parameters->GetParameter(ptName);
+}
+
+void cTemplateViewTab::SetName(string trans) {
+ parameters->SetParameter(ptName, trans);
+}
+
+void cTemplateViewTab::Debug(void) {
+ esyslog("skindesigner: cTemplateViewTab Debug %s", GetName().c_str());
+ cTemplatePixmap::Debug();
+ esyslog("skindesigner: -------------------------------------------------------");
+}
diff --git a/libtemplate/templateviewtab.h b/libtemplate/templateviewtab.h
new file mode 100644
index 0000000..8514cad
--- /dev/null
+++ b/libtemplate/templateviewtab.h
@@ -0,0 +1,31 @@
+#ifndef __TEMPLATEVIEWTAB_H
+#define __TEMPLATEVIEWTAB_H
+
+#include <iostream>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string>
+#include <vector>
+#include <map>
+#include <set>
+
+#include "templatepixmap.h"
+
+using namespace std;
+
+// --- cTemplateViewTab -------------------------------------------------------------
+
+class cTemplateViewTab : public cTemplatePixmap {
+private:
+ int scrollStep;
+public:
+ cTemplateViewTab(void);
+ ~cTemplateViewTab(void);
+ int GetScrollStep(void);
+ string GetName(void);
+ void SetName(string trans);
+ void Debug(void);
+};
+
+#endif //__TEMPLATEVIEWTAB_H \ No newline at end of file
diff --git a/libtemplate/xmlparser.c b/libtemplate/xmlparser.c
new file mode 100644
index 0000000..f9a723a
--- /dev/null
+++ b/libtemplate/xmlparser.c
@@ -0,0 +1,728 @@
+#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) {
+ return *cString::sprintf("%s%s/xmlfiles/%s", *config.skinPath, Setup.OSDTheme, 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;
+}
diff --git a/libtemplate/xmlparser.h b/libtemplate/xmlparser.h
new file mode 100644
index 0000000..ecdcca3
--- /dev/null
+++ b/libtemplate/xmlparser.h
@@ -0,0 +1,56 @@
+#ifndef __XMLPARSER_H
+#define __XMLPARSER_H
+
+#include <iostream>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string>
+#include <vector>
+#include <map>
+#include <set>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <libxml/xmlerror.h>
+#include <vdr/plugin.h>
+
+#include "templateview.h"
+#include "templateviewlist.h"
+#include "templateviewtab.h"
+
+using namespace std;
+
+// --- cXmlParser -------------------------------------------------------------
+
+class cXmlParser {
+private:
+ cTemplateView *view;
+ cGlobals *globals;
+ xmlParserCtxtPtr ctxt;
+ xmlDocPtr doc;
+ xmlNodePtr root;
+ string GetPath(string xmlFile);
+ void ParseGlobalColors(xmlNodePtr node);
+ void InsertColor(string name, string value);
+ void ParseGlobalVariables(xmlNodePtr node);
+ void InsertVariable(string name, string type, string value);
+ void ParseGlobalFonts(xmlNodePtr node);
+ void ParseTranslations(xmlNodePtr node);
+ bool ParseSubView(xmlNodePtr node);
+ void ParseViewElement(const xmlChar * viewElement, xmlNodePtr node, bool debugVE, cTemplateView *subView = NULL);
+ void ParseViewList(xmlNodePtr parentNode, cTemplateView *subView = NULL);
+ void ParseViewTab(xmlNodePtr parentNode, cTemplateView *subView);
+ void ParseFunctionCalls(xmlNodePtr node, cTemplatePixmap *pix);
+ void ParseLoopFunctionCalls(xmlNodePtr node, cTemplateLoopFunction *loopFunc);
+ bool ParseAttributes(xmlAttrPtr attr, xmlNodePtr node, vector<pair<string, string> > &attribs);
+ bool DebugViewElement(xmlNodePtr node);
+public:
+ cXmlParser(void);
+ virtual ~cXmlParser(void);
+ bool ReadView(cTemplateView *view, string xmlFile);
+ bool ReadGlobals(cGlobals *globals, string xmlFile);
+ bool ParseView(void);
+ bool ParseGlobals(void);
+ void DeleteDocument(void);
+};
+
+#endif //__XMLPARSER_H \ No newline at end of file