From b0509b5182b6e0d04f05e6b3d5676b0d21f51966 Mon Sep 17 00:00:00 2001 From: louis Date: Sat, 27 Sep 2014 09:25:14 +0200 Subject: initial commit version 0.0.1 --- libtemplate/globals.c | 98 +++ libtemplate/globals.h | 38 + libtemplate/parameter.c | 394 +++++++++ libtemplate/parameter.h | 138 ++++ libtemplate/template.c | 273 +++++++ libtemplate/template.h | 57 ++ libtemplate/templatefunction.c | 1474 +++++++++++++++++++++++++++++++++ libtemplate/templatefunction.h | 211 +++++ libtemplate/templateloopfunction.c | 208 +++++ libtemplate/templateloopfunction.h | 33 + libtemplate/templatepixmap.c | 473 +++++++++++ libtemplate/templatepixmap.h | 82 ++ libtemplate/templateview.c | 1567 ++++++++++++++++++++++++++++++++++++ libtemplate/templateview.h | 198 +++++ libtemplate/templateviewelement.c | 128 +++ libtemplate/templateviewelement.h | 99 +++ libtemplate/templateviewlist.c | 138 ++++ libtemplate/templateviewlist.h | 49 ++ libtemplate/templateviewtab.c | 38 + libtemplate/templateviewtab.h | 31 + libtemplate/xmlparser.c | 728 +++++++++++++++++ libtemplate/xmlparser.h | 56 ++ 22 files changed, 6511 insertions(+) create mode 100644 libtemplate/globals.c create mode 100644 libtemplate/globals.h create mode 100644 libtemplate/parameter.c create mode 100644 libtemplate/parameter.h create mode 100644 libtemplate/template.c create mode 100644 libtemplate/template.h create mode 100644 libtemplate/templatefunction.c create mode 100644 libtemplate/templatefunction.h create mode 100644 libtemplate/templateloopfunction.c create mode 100644 libtemplate/templateloopfunction.h create mode 100644 libtemplate/templatepixmap.c create mode 100644 libtemplate/templatepixmap.h create mode 100644 libtemplate/templateview.c create mode 100644 libtemplate/templateview.h create mode 100644 libtemplate/templateviewelement.c create mode 100644 libtemplate/templateviewelement.h create mode 100644 libtemplate/templateviewlist.c create mode 100644 libtemplate/templateviewlist.h create mode 100644 libtemplate/templateviewtab.c create mode 100644 libtemplate/templateviewtab.h create mode 100644 libtemplate/xmlparser.c create mode 100644 libtemplate/xmlparser.h (limited to 'libtemplate') 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 + +cGlobals::cGlobals(void) { + fonts.insert(pair("vdrOsd", Setup.FontOsd)); + fonts.insert(pair("vdrFix", Setup.FontFix)); + fonts.insert(pair("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 >::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 ::iterator col = colors.begin(); col != colors.end(); col++) { + dsyslog("skindesigner: Color \"%s\": %x", (col->first).c_str(), col->second); + } + for (map ::iterator myInt = intVars.begin(); myInt != intVars.end(); myInt++) { + dsyslog("skindesigner: Integer Variable \"%s\": %d", (myInt->first).c_str(), myInt->second); + } + for (map ::iterator myStr = stringVars.begin(); myStr != stringVars.end(); myStr++) { + dsyslog("skindesigner: String Variable \"%s\": \"%s\"", (myStr->first).c_str(), (myStr->second).c_str()); + } + for (map ::iterator font = fonts.begin(); font != fonts.end(); font++) { + dsyslog("skindesigner: Font \"%s\": \"%s\"", (font->first).c_str(), (font->second).c_str()); + } + for (map >::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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +typedef uint32_t tColor; + +// --- cGlobals ------------------------------------------------------------- + +class cGlobals { +private: + string language; + string DoTranslate(string token); +public: + cGlobals(void); + virtual ~cGlobals(void) {}; + map colors; + map intVars; + map stringVars; + map fonts; + map > 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::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::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::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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 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 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 > cTemplate::GetUsedFonts(void) { + vector< pair > 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 > &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(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(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(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(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 +#include +#include +#include +#include +#include +#include +#include +#include + +#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 > &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 > 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 > params) { + for (vector >::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(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(ptWidth, width)); +} + +void cTemplateFunction::SetHeightManually(string height) { + nativeParameters.erase(ptHeight); + nativeParameters.insert(pair(ptHeight, height)); +} + +void cTemplateFunction::SetXManually(int newX) { + numericParameters.erase(ptX); + numericParameters.insert(pair(ptX, newX)); +} + +void cTemplateFunction::SetYManually(int newY) { + numericParameters.erase(ptY); + numericParameters.insert(pair(ptY, newY)); +} + +void cTemplateFunction::SetTextboxHeight(int boxHeight) { + numericParameters.erase(ptHeight); + numericParameters.insert(pair(ptHeight, boxHeight)); +} + +void cTemplateFunction::SetTranslatedText(string translation) { + if (type != ftDrawText && type != ftDrawTextBox) + return; + if (translation.size() == 0) + return; + nativeParameters.erase(ptText); + nativeParameters.insert(pair(ptText, translation)); +} + +void cTemplateFunction::SetMaxTextWidth(int maxWidth) { + if (type != ftDrawText) + return; + numericParameters.erase(ptWidth); + numericParameters.insert(pair(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(ptWidth, logoWidth)); + } else if (logoHeight <= 0 && logoWidthOrig > 0) { + logoHeight = logoWidth * logoHeightOrig / logoWidthOrig; + numericParameters.erase(ptHeight); + numericParameters.insert(pair(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::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::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::iterator hit = nativeParameters.find(type); + if (hit == nativeParameters.end()) + return ""; + return hit->second; +} + +int cTemplateFunction::GetNumericParameter(eParamType type) { + map::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::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 *widths) { + for (map::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(param->first, label)); + val = val.replace(posStart, posEnd - posStart, ""); + } else { + break; + } + posStart = val.find("{width("); + } + } +} + +void cTemplateFunction::GetNeededHeights(multimap *heights) { + for (map::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(param->first, label)); + val = val.replace(posStart, posEnd - posStart, ""); + } else { + break; + } + posStart = val.find("{height("); + } + } +} + +void cTemplateFunction::GetNeededPosX(multimap *posXs) { + for (map::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(param->first, label)); + val = val.replace(posStart, posEnd - posStart, ""); + } else { + break; + } + posStart = val.find("{posx("); + } + } +} + +void cTemplateFunction::GetNeededPosY(multimap *posYs) { + for (map::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(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(type, val)); + } else { + numericDynamicParameters.erase(type); + numericDynamicParameters.insert(pair(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(type, val)); + } else { + numericDynamicParameters.erase(type); + numericDynamicParameters.insert(pair(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(type, val)); + } else { + numericDynamicParameters.erase(type); + numericDynamicParameters.insert(pair(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(type, val)); + } else { + numericDynamicParameters.erase(type); + numericDynamicParameters.insert(pair(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(type, val)); + } else { + numericDynamicParameters.insert(pair(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(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::iterator hit = globals->fonts.find(value); + if (hit != globals->fonts.end()) { + fontName = hit->second; + } else { + map::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(ptImageType, imgType)); + return ok; +} + + +bool cTemplateFunction::SetColor(eParamType type, string value) { + if (globals) { + for (map::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(type, colVal)); + return true; + } + } + } + if (value.size() != 8) + return false; + std::stringstream str; + str << value; + tColor colVal; + str >> std::hex >> colVal; + colorParameters.insert(pair(type, colVal)); + return true; +} + +bool cTemplateFunction::SetTextTokens(string value) { + textTokens.clear(); + //first replace globals + for (map::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 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(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(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(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(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(ptOverflow, overflowType)); + return ok; +} + +void cTemplateFunction::ParseStringParameters(void) { + //first replace stringtokens in Text (drawText) + stringstream text; + for (vector::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::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::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::iterator param = numericDynamicParameters.begin(); param !=numericDynamicParameters.end(); param++) { + string val = param->second; + for (map::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(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(ptX, xNew)); + } else if (align == alRight) { + int xNew = boxWidth - elementWidth; + numericParameters.erase(ptX); + numericParameters.insert(pair(ptX, xNew)); + } + + int vAlign = GetNumericParameter(ptValign); + if (vAlign == alCenter) { + int yNew = (boxHeight - elementHeight) / 2; + numericParameters.erase(ptY); + numericParameters.insert(pair(ptY, yNew)); + } else if (vAlign == alBottom) { + int yNew = boxHeight - elementHeight; + numericParameters.erase(ptY); + numericParameters.insert(pair(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 flds = s.split('\n', 1); + + if (flds.size() < 1) + return 0; + + stringstream sstrTextTall; + stringstream sstrTextFull; + + for (int i=0; iDebug(); + } + esyslog("skindesigner: --- Native Parameters:"); + for (map::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::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::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::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::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::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 +#include +#include +#include +#include +#include +#include +#include +#include + +#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 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 > 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 *widths); + void GetNeededHeights(multimap *heights); + void GetNeededPosX(multimap *posXs); + void GetNeededPosY(multimap *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 > ¶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::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 *tokens) { + if (!tokens) + return; + InitIterator(); + cTemplateFunction *func = NULL; + + map intTokens; + for (map ::iterator it = tokens->begin(); it != tokens->end(); it++) { + if (isNumber(it->second)) + intTokens.insert(pair(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 widths; + func->GetNeededWidths(&widths); + for (map::iterator names = widths.begin(); names !=widths.end(); names++) { + eParamType type = names->first; + string label = names->second; + int funcWidth = 0; + for (vector::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 heights; + func->GetNeededHeights(&heights); + for (map::iterator names = heights.begin(); names !=heights.end(); names++) { + eParamType type = names->first; + string label = names->second; + int funcHeight = 0; + for (vector::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::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 functions; + vector::iterator funcIt; + void ReplaceWidthFunctions(void); + void ReplaceHeightFunctions(void); +public: + cTemplateLoopFunction(void); + virtual ~cTemplateLoopFunction(void); + void AddFunction(string name, vector > ¶ms); + void CalculateLoopFuncParameters(void); + void InitIterator(void); + cTemplateFunction *GetNextFunction(void); + void ClearDynamicParameters(void); + void ParseDynamicParameters(map *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::iterator it = functions.begin(); it != functions.end(); it++) { + delete (*it); + } + if (parameters) + delete parameters; +} + +void cTemplatePixmap::SetParameters(vector > ¶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 *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::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(*func); + if (!loopFunc->Ready()) { + loopFunc->SetIntTokens(intTokens); + loopFunc->ParseParameters(); + loopFunc->UnsetIntTokens(); + } + loopFunc->CalculateLoopFuncParameters(); + } + } +} + +void cTemplatePixmap::AddFunction(string name, vector > ¶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::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(*func); + loopFunc->CalculateLoopFuncParameters(); + } + } + + return paramsValid; +} + +void cTemplatePixmap::ClearDynamicFunctionParameters(void) { + InitIterator(); + cTemplateFunction *func = NULL; + while(func = GetNextFunction()) { + func->ClearDynamicParameters(); + } +} + +void cTemplatePixmap::ParseDynamicFunctionParameters(map *stringTokens, map *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(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 > loopToken = hit->second; + numLoopTokens = loopToken.size(); + //parse first loop token element to get correct height + vector< map >::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 widths; + func->GetNeededWidths(&widths); + for (map::iterator names = widths.begin(); names !=widths.end(); names++) { + eParamType type = names->first; + string label = names->second; + int funcWidth = 0; + for (vector::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 heights; + func->GetNeededHeights(&heights); + for (map::iterator names = heights.begin(); names !=heights.end(); names++) { + eParamType type = names->first; + string label = names->second; + int funcHeight = 0; + for (vector::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 posXs; + func->GetNeededPosX(&posXs); + for (map::iterator names = posXs.begin(); names !=posXs.end(); names++) { + eParamType type = names->first; + string label = names->second; + int funcX = 0; + for (vector::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 posYs; + func->GetNeededPosY(&posYs); + for (map::iterator names = posYs.begin(); names !=posYs.end(); names++) { + eParamType type = names->first; + string label = names->second; + int funcY = 0; + for (vector::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::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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "globals.h" +#include "templateloopfunction.h" + +using namespace std; + +// --- cTemplatePixmap ------------------------------------------------------------- + +class cTemplatePixmap { +protected: + bool scrolling; + cTemplateFunction *parameters; + vector functions; + vector::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 > ¶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 > ¶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 *intTokens, bool initFuncs); + //Parse all function parameters with dynamically set Tokens + void ParseDynamicFunctionParameters(map *stringTokens, map *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 > ¶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::iterator hit = viewElementsAllowed.find(viewElement); + if (hit == viewElementsAllowed.end()) + return false; + return true; +} + +bool cTemplateView::ValidSubView(const char *subView) { + set::iterator hit = subViewsAllowed.find(subView); + if (hit == subViewsAllowed.end()) + return false; + return true; +} + +bool cTemplateView::ValidViewList(const char *viewList) { + set::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::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::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::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 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 >(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 >(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 >(name, attributes)); + + name = "fill"; + attributes.clear(); + attributes.insert("debug"); + attributes.insert("condition"); + attributes.insert("color"); + funcsAllowed.insert(pair< string, set >(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 >(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 >(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 >(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 >(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 >(name, attributes)); + +} + +/************************************************************************************ +* cTemplateViewChannel +************************************************************************************/ + +cTemplateViewChannel::cTemplateViewChannel(void) { + + viewName = "displaychannel"; + //definition of allowed parameters for class itself + set 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 >(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 attributes; + attributes.insert("x"); + attributes.insert("y"); + attributes.insert("width"); + attributes.insert("height"); + attributes.insert("fadetime"); + funcsAllowed.insert(pair< string, set >(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 >(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 >(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 >(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 >(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 >(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 >(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 >(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 >(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 >(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 >(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 >("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 >("menuitems", attributes)); + + //definition of allowed parameters for currentitems viewlist + attributes.clear(); + attributes.insert("delay"); + attributes.insert("fadetime"); + funcsAllowed.insert(pair< string, set >("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 >("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(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 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 >(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 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 >(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 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 >(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 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 >(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 >("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 +#include +#include +#include +#include +#include +#include +#include +#include + +#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 subViewsAllowed; + set viewElementsAllowed; + set 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 > ¶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::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::iterator pix = viewPixmaps.begin(); pix != viewPixmaps.end(); pix++) { + (*pix)->SetGlobals(globals); + } +} + +void cTemplateViewElement::SetParameters(vector > ¶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::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::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::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 +#include +#include +#include +#include +#include +#include +#include +#include + +#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 viewPixmaps; + vector::iterator pixIterator; + int pixOffset; +public: + cTemplateViewElement(void); + virtual ~cTemplateViewElement(void); + void SetParameters(vector > ¶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::iterator hit = globals->fonts.find(fontNameToken); + if (hit != globals->fonts.end()) { + fontName = hit->second; + } else { + map::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 +#include +#include +#include +#include +#include +#include +#include +#include + +#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 +#include +#include +#include +#include +#include +#include +#include + +#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 > 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(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(name, val)); + } else if (!type.compare("string")) { + globals->stringVars.insert(pair(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((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((const char*)language, (const char*)value)); + if (language) + xmlFree(language); + if (value) + xmlFree(value); + nodeTrans = nodeTrans->next; + } + globals->translations.insert(pair >((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 > 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 > 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 > 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 > attribsCur; + ParseAttributes(attrCur, node, attribsCur); + currentElement->SetGlobals(globals); + currentElement->SetParameters(attribsCur); + bool debugCurrent = false; + for (vector >::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 > 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 > 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 > 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 > 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 > 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 > 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 > &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((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((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 > attribs; + ParseAttributes(attr, node, attribs); + for (vector >::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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 > &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 -- cgit v1.2.3