diff options
Diffstat (limited to 'libtemplate')
-rw-r--r-- | libtemplate/globals.c | 98 | ||||
-rw-r--r-- | libtemplate/globals.h | 38 | ||||
-rw-r--r-- | libtemplate/parameter.c | 394 | ||||
-rw-r--r-- | libtemplate/parameter.h | 138 | ||||
-rw-r--r-- | libtemplate/template.c | 273 | ||||
-rw-r--r-- | libtemplate/template.h | 57 | ||||
-rw-r--r-- | libtemplate/templatefunction.c | 1474 | ||||
-rw-r--r-- | libtemplate/templatefunction.h | 211 | ||||
-rw-r--r-- | libtemplate/templateloopfunction.c | 208 | ||||
-rw-r--r-- | libtemplate/templateloopfunction.h | 33 | ||||
-rw-r--r-- | libtemplate/templatepixmap.c | 473 | ||||
-rw-r--r-- | libtemplate/templatepixmap.h | 82 | ||||
-rw-r--r-- | libtemplate/templateview.c | 1567 | ||||
-rw-r--r-- | libtemplate/templateview.h | 198 | ||||
-rw-r--r-- | libtemplate/templateviewelement.c | 128 | ||||
-rw-r--r-- | libtemplate/templateviewelement.h | 99 | ||||
-rw-r--r-- | libtemplate/templateviewlist.c | 138 | ||||
-rw-r--r-- | libtemplate/templateviewlist.h | 49 | ||||
-rw-r--r-- | libtemplate/templateviewtab.c | 38 | ||||
-rw-r--r-- | libtemplate/templateviewtab.h | 31 | ||||
-rw-r--r-- | libtemplate/xmlparser.c | 728 | ||||
-rw-r--r-- | libtemplate/xmlparser.h | 56 |
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> > ¶ms) { + 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> > ¶ms); + 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> > ¶ms) {
+ 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> > ¶ms) {
+ 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> > ¶ms); + 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> > ¶ms); + 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> > ¶ms) { + 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> > ¶ms); + 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> > ¶ms) {
+ 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> > ¶ms);
+ 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 |