2014-09-27 09:25:14 +02:00
|
|
|
#include <string>
|
|
|
|
#include <sstream>
|
|
|
|
#include <vector>
|
|
|
|
#include "helpers.h"
|
|
|
|
#include <vdr/skins.h>
|
|
|
|
|
|
|
|
cPlugin *GetScraperPlugin(void) {
|
|
|
|
static cPlugin *pScraper = cPluginManager::GetPlugin("scraper2vdr");
|
|
|
|
if( !pScraper ) // if it doesn't exit, try tvscraper
|
|
|
|
pScraper = cPluginManager::GetPlugin("tvscraper");
|
|
|
|
return pScraper;
|
|
|
|
}
|
|
|
|
|
|
|
|
cSize ScaleToFit(int widthMax, int heightMax, int widthOriginal, int heightOriginal) {
|
|
|
|
int width = 1;
|
|
|
|
int height = 1;
|
|
|
|
|
|
|
|
if ((widthMax == 0)||(heightMax==0)||(widthOriginal==0)||(heightOriginal==0))
|
|
|
|
return cSize(width, height);
|
|
|
|
|
|
|
|
if ((widthOriginal <= widthMax) && (heightOriginal <= heightMax)) {
|
|
|
|
width = widthOriginal;
|
|
|
|
height = heightOriginal;
|
|
|
|
} else if ((widthOriginal > widthMax) && (heightOriginal <= heightMax)) {
|
|
|
|
width = widthMax;
|
|
|
|
height = (double)width/(double)widthOriginal * heightOriginal;
|
|
|
|
} else if ((widthOriginal <= widthMax) && (heightOriginal > heightMax)) {
|
|
|
|
height = heightMax;
|
|
|
|
width = (double)height/(double)heightOriginal * widthOriginal;
|
|
|
|
} else {
|
|
|
|
width = widthMax;
|
|
|
|
height = (double)width/(double)widthOriginal * heightOriginal;
|
|
|
|
if (height > heightMax) {
|
|
|
|
height = heightMax;
|
|
|
|
width = (double)height/(double)heightOriginal * widthOriginal;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return cSize(width, height);
|
|
|
|
}
|
|
|
|
|
|
|
|
int Minimum(int a, int b, int c, int d, int e, int f) {
|
|
|
|
int min = a;
|
|
|
|
if (b < min) min = b;
|
|
|
|
if (c < min) min = c;
|
|
|
|
if (d < min) min = d;
|
|
|
|
if (e < min) min = e;
|
|
|
|
if (f < min) min = f;
|
|
|
|
return min;
|
|
|
|
}
|
|
|
|
|
|
|
|
string CutText(string &text, int width, string fontName, int fontSize) {
|
|
|
|
if (width <= fontManager->Font(fontName, fontSize)->Size())
|
|
|
|
return text.c_str();
|
2015-04-06 09:58:33 +02:00
|
|
|
fontManager->Lock();
|
2014-09-27 09:25:14 +02:00
|
|
|
cTextWrapper twText;
|
|
|
|
twText.Set(text.c_str(), fontManager->Font(fontName, fontSize), width);
|
2015-04-06 09:58:33 +02:00
|
|
|
fontManager->Unlock();
|
2014-09-27 09:25:14 +02:00
|
|
|
string cuttedTextNative = twText.GetLine(0);
|
|
|
|
stringstream sstrText;
|
|
|
|
sstrText << cuttedTextNative << "...";
|
|
|
|
string cuttedText = sstrText.str();
|
|
|
|
int actWidth = fontManager->Width(fontName, fontSize, cuttedText.c_str());
|
|
|
|
if (actWidth > width) {
|
|
|
|
int overlap = actWidth - width;
|
|
|
|
int charWidth = fontManager->Width(fontName, fontSize, ".");
|
|
|
|
if (charWidth == 0)
|
|
|
|
charWidth = 1;
|
|
|
|
int cutChars = overlap / charWidth;
|
|
|
|
if (cutChars > 0) {
|
|
|
|
cuttedTextNative = cuttedTextNative.substr(0, cuttedTextNative.length() - cutChars);
|
|
|
|
stringstream sstrText2;
|
|
|
|
sstrText2 << cuttedTextNative << "...";
|
|
|
|
cuttedText = sstrText2.str();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return cuttedText;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
string StrToLowerCase(string str) {
|
|
|
|
string lowerCase = str;
|
|
|
|
const int length = lowerCase.length();
|
|
|
|
for(int i=0; i < length; ++i) {
|
|
|
|
lowerCase[i] = std::tolower(lowerCase[i]);
|
|
|
|
}
|
|
|
|
return lowerCase;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isNumber(const string& s) {
|
|
|
|
string::const_iterator it = s.begin();
|
|
|
|
while (it != s.end() && std::isdigit(*it)) ++it;
|
|
|
|
return !s.empty() && it == s.end();
|
|
|
|
}
|
|
|
|
|
2015-01-24 10:47:47 +01:00
|
|
|
bool IsToken(const string& token) {
|
|
|
|
if ((token.find("{") == 0) && (token.find("}") == (token.size()-1)))
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-10-26 08:47:24 +01:00
|
|
|
bool FileExists(const string &fullpath) {
|
|
|
|
struct stat buffer;
|
2015-04-11 16:48:58 +02:00
|
|
|
if (stat (fullpath.c_str(), &buffer) == 0) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (config.debugImageLoading) {
|
|
|
|
dsyslog("skindesigner: did not found %s", fullpath.c_str());
|
|
|
|
}
|
|
|
|
return false;
|
2014-10-26 08:47:24 +01:00
|
|
|
}
|
|
|
|
|
2014-09-27 09:25:14 +02:00
|
|
|
bool FileExists(const string &path, const string &name, const string &ext) {
|
|
|
|
stringstream fileName;
|
|
|
|
fileName << path << name << "." << ext;
|
|
|
|
struct stat buffer;
|
2015-04-11 16:48:58 +02:00
|
|
|
if (stat (fileName.str().c_str(), &buffer) == 0) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (config.debugImageLoading) {
|
|
|
|
dsyslog("skindesigner: did not found %s", fileName.str().c_str());
|
|
|
|
}
|
|
|
|
return false;
|
2014-09-27 09:25:14 +02:00
|
|
|
}
|
|
|
|
|
2014-10-03 15:54:23 +02:00
|
|
|
bool FolderExists(const string &path) {
|
|
|
|
struct stat buffer;
|
|
|
|
return stat(path.c_str(), &buffer) == 0 && S_ISDIR(buffer.st_mode);
|
|
|
|
}
|
|
|
|
|
2014-09-27 09:25:14 +02:00
|
|
|
bool FirstFileInFolder(string &path, string &extension, string &fileName) {
|
|
|
|
DIR *folder = NULL;
|
|
|
|
struct dirent *file;
|
|
|
|
folder = opendir(path.c_str());
|
|
|
|
if (!folder)
|
|
|
|
return false;
|
|
|
|
while (file = readdir(folder)) {
|
|
|
|
if (endswith(file->d_name, extension.c_str())) {
|
|
|
|
string currentFileName = file->d_name;
|
|
|
|
int strlength = currentFileName.size();
|
|
|
|
if (strlength < 8)
|
|
|
|
continue;
|
|
|
|
fileName = currentFileName;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-10-11 16:31:39 +02:00
|
|
|
// trim from start
|
|
|
|
string <rim(string &s) {
|
|
|
|
s.erase(s.begin(), find_if(s.begin(), s.end(), not1(ptr_fun<int, int>(isspace))));
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
// trim from end
|
|
|
|
string &rtrim(string &s) {
|
|
|
|
s.erase(find_if(s.rbegin(), s.rend(), not1(ptr_fun<int, int>(isspace))).base(), s.end());
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
// trim from both ends
|
|
|
|
string &trim(string &s) {
|
|
|
|
return ltrim(rtrim(s));
|
|
|
|
}
|
|
|
|
|
2014-09-27 09:25:14 +02:00
|
|
|
// split: receives a char delimiter; returns a vector of strings
|
|
|
|
// By default ignores repeated delimiters, unless argument rep == 1.
|
|
|
|
vector<string>& splitstring::split(char delim, int rep) {
|
|
|
|
if (!flds.empty()) flds.clear(); // empty vector if necessary
|
|
|
|
string work = data();
|
|
|
|
string buf = "";
|
|
|
|
int i = 0;
|
2015-04-02 11:57:19 +02:00
|
|
|
while (i < (int)work.length()) {
|
2014-09-27 09:25:14 +02:00
|
|
|
if (work[i] != delim)
|
|
|
|
buf += work[i];
|
|
|
|
else if (rep == 1) {
|
|
|
|
flds.push_back(buf);
|
|
|
|
buf = "";
|
|
|
|
} else if (buf.length() > 0) {
|
|
|
|
flds.push_back(buf);
|
|
|
|
buf = "";
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
if (!buf.empty())
|
|
|
|
flds.push_back(buf);
|
|
|
|
return flds;
|
|
|
|
}
|
|
|
|
|
2014-11-02 17:32:22 +01:00
|
|
|
cStopWatch::cStopWatch(const char* message) {
|
2014-09-27 09:25:14 +02:00
|
|
|
start = cTimeMs::Now();
|
|
|
|
last = start;
|
2014-11-02 17:32:22 +01:00
|
|
|
if (message) {
|
|
|
|
dsyslog("skindesigner: Starting StopWatch %s", message);
|
|
|
|
}
|
2014-09-27 09:25:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void cStopWatch::Report(const char* message) {
|
|
|
|
dsyslog("skindesigner: %s - needed %d ms", message, (int)(cTimeMs::Now() - last));
|
|
|
|
last = cTimeMs::Now();
|
|
|
|
}
|
|
|
|
|
|
|
|
void cStopWatch::Stop(const char* message) {
|
|
|
|
dsyslog("skindesigner: %s - needed %d ms", message, (int)(cTimeMs::Now() - start));
|
|
|
|
}
|
2014-10-20 17:35:52 +02:00
|
|
|
|
|
|
|
//View Helpers
|
|
|
|
string GetScreenResolutionString(int width, int height, bool *isHD) {
|
|
|
|
string name = "";
|
|
|
|
switch (width) {
|
|
|
|
case 1920:
|
|
|
|
case 1440:
|
|
|
|
name = "hd1080i";
|
|
|
|
*isHD = true;
|
|
|
|
break;
|
|
|
|
case 1280:
|
|
|
|
if (height == 720)
|
|
|
|
name = "hd720p";
|
|
|
|
else
|
|
|
|
name = "hd1080i";
|
|
|
|
*isHD = true;
|
|
|
|
break;
|
|
|
|
case 720:
|
|
|
|
name = "sd576i";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
name = "sd576i";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
|
|
|
string GetScreenAspectString(double aspect, bool *isWideScreen) {
|
|
|
|
string name = "";
|
|
|
|
*isWideScreen = false;
|
|
|
|
if (aspect == 4.0/3.0) {
|
|
|
|
name = "4:3";
|
|
|
|
*isWideScreen = false;
|
|
|
|
} else if (aspect == 16.0/9.0) {
|
|
|
|
name = "16:9";
|
|
|
|
*isWideScreen = true;
|
|
|
|
} else if (aspect == 2.21) {
|
|
|
|
name = "21:9";
|
|
|
|
*isWideScreen = true;
|
|
|
|
}
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|