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/templatefunction.c | 1474 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1474 insertions(+) create mode 100644 libtemplate/templatefunction.c (limited to 'libtemplate/templatefunction.c') 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()); + } +} -- cgit v1.2.3