/* -*- c++ -*- Copyright (C) 2004-2012 Christian Wieninger This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html The author can be reached at cwieninger@gmx.de The project's page is at http://winni.vdr-developer.org/epgsearch */ #include #include "templatefile.h" #include "epgsearchcfg.h" #include "epgsearchtools.h" std::set cTemplFile::menuTemplates; char** cTemplFile::SearchTemplates = NULL; bool cMenuTemplate::PrepareTemplate(const char* templateLine) { if (!templateLine || strlen(templateLine) == 0) return true; char *pstrSearchToken, *pptr; char *pstrSearch=strdup(templateLine); pstrSearchToken=strtok_r(pstrSearch, "|", &pptr); cString stripped; int iToken = 0; while(pstrSearchToken) { char* tmp = strchr(pstrSearchToken,':'); if (tmp) { int tabWidth = atoi(tmp+1); if (tabWidth == 0) { LogFile.eSysLog("warning - tab width in \"%s\" is 0, set to min value 1!", Name()); tabWidth = 1; } menuTabs[iToken++] = tabWidth; } else { free(pstrSearch); LogFile.eSysLog("error parsing entry \"%s\", falling back to default entries.", Name()); return false; } *tmp = 0; if (isempty(stripped)) stripped = strdup(pstrSearchToken); else { cString tmp = stripped; stripped = cString::sprintf("%s|%s", *tmp, pstrSearchToken); } pstrSearchToken=strtok_r(NULL, "|", &pptr); } free(pstrSearch); // no limit for the last column if (iToken>0) menuTabs[iToken-1] = 0; if (!isempty(stripped)) { menuTemplate = strdup(stripped); // the status variables are handled in menu_whatson.c itself // to speedup the var-parser we 'hide' them here in renaming them menuTemplate = strreplacei(menuTemplate, "%status%", "$status$"); menuTemplate = strreplacei(menuTemplate, "%t_status%", "$t_status$"); menuTemplate = strreplacei(menuTemplate, "%v_status%", "$v_status$"); menuTemplate = strreplacei(menuTemplate, "%r_status%", "$r_status$"); } return true; } cTemplLine::cTemplLine(void) { name = value = NULL; } cTemplLine::cTemplLine(const char *Name, const char *Value) { name = strdup(Name); value = strdup(Value); } cTemplLine::~cTemplLine() { free(name); free(value); } bool cTemplLine::Parse(char *s) { if (!s) return false; if (s[0] == '#') return true; char *p = strchr(s, '='); if (p) { *p = 0; char *Name = compactspace(s); char *Value = compactspace(p + 1); if (*Name) { name = strdup(Name); value = strdup(Value); return true; } } return false; } cTemplFile::cTemplFile() { Reset(); } void cTemplFile::Reset() { std::set::iterator it; for (it = menuTemplates.begin(); it != menuTemplates.end(); ++it) delete (*it); menuTemplates.clear(); } cMenuTemplate* cTemplFile::GetTemplateByName(const char* Name) { std::set::iterator it; for (it = menuTemplates.begin(); it != menuTemplates.end(); ++it) if (!strcasecmp(Name, (*it)->Name())) return (*it); return NULL; } bool cTemplFile::Load(const char *FileName) { // auto-enable WarEagle-Icons if VDRSymbols font is used if (strstr(Setup.FontOsd, "VDRSymbols") == Setup.FontOsd) EPGSearchConfig.WarEagle = 1; if (cConfig::Load(FileName, true)) { bool result = true; for (cTemplLine *l = First(); l; l = Next(l)) { bool error = false; if (!Parse(l->Name(), l->Value())) error = true; if (error) { result = false; } } return result; } return false; } bool cTemplFile::Parse(const char *Name, const char *Value) { if (Name && Name[0] == '#') return true; if (!strcasecmp(Name, "WarEagleIcons")) { EPGSearchConfig.WarEagle = atoi(Value); return true; } if (!strcasecmp(Name, "MenuWhatsOnNow") || !strcasecmp(Name, "MenuWhatsOnNext") || !strcasecmp(Name, "MenuWhatsOnElse") || !strcasecmp(Name, "MenuSchedule") || !strncasecmp(Name, "MenuSearchResults", strlen("MenuSearchResults")) || !strcasecmp(Name, "MenuFavorites")) { cMenuTemplate* menuTemplate = new cMenuTemplate(Name); if (menuTemplate->PrepareTemplate(Value)) { LogFile.Log(3, "loaded menu template: %s", Name); cMenuTemplate* TemplOld = GetTemplateByName(Name); if (TemplOld) { LogFile.Log(1, "menu template '%s' gets overwritten", Name); menuTemplates.erase(TemplOld); delete TemplOld; } menuTemplates.insert(menuTemplate); return true; } } else { LogFile.eSysLog("ERROR: unknown parameter: %s = %s", Name, Value); return false; } return true; } void cTemplFile::PrepareDefaultTemplates() { char channelnr[20] = ""; sprintf(channelnr, "%%chnr%%:%d|", CHNUMWIDTH); bool text2skin = !(strcmp(Setup.OSDSkin, "soppalusikka") == 0 || strcmp(Setup.OSDSkin, "classic") == 0 || strcmp(Setup.OSDSkin, "sttng") == 0); char menutemplate[MAXTEMPLLEN] = ""; // What's on now cMenuTemplate* WhatsOnNow = GetTemplateByName("MenuWhatsOnNow"); if (!WhatsOnNow) { WhatsOnNow = new cMenuTemplate("MenuWhatsOnNow"); menuTemplates.insert(WhatsOnNow); } if (WhatsOnNow && WhatsOnNow->MenuTemplate() == 0) { sprintf(menutemplate, "%s%%chsh%%:12|%%time%%:6|%s%s$status$:3|%%title%% ~ %%subtitle%%:30", EPGSearchConfig.showChannelNr?channelnr:"", EPGSearchConfig.showProgress==0?"":(EPGSearchConfig.showProgress==1?"%progrT2S%:4|":"%progr%:5|"), text2skin?" ":""); WhatsOnNow->PrepareTemplate(menutemplate); } // What's on next and else sprintf(menutemplate, "%s%%chsh%%:12|%%time%%:7|$status$:4|%%title%% ~ %%subtitle%%:30", EPGSearchConfig.showChannelNr?channelnr:""); cMenuTemplate* WhatsOnNext = GetTemplateByName("MenuWhatsOnNext"); if (!WhatsOnNext) { WhatsOnNext = new cMenuTemplate("MenuWhatsOnNext"); menuTemplates.insert(WhatsOnNext); } if (WhatsOnNext && WhatsOnNext->MenuTemplate() == 0) WhatsOnNext->PrepareTemplate(menutemplate); cMenuTemplate* WhatsOnElse = GetTemplateByName("MenuWhatsOnElse"); if (!WhatsOnElse) { WhatsOnElse = new cMenuTemplate("MenuWhatsOnElse"); menuTemplates.insert(WhatsOnElse); } if (WhatsOnElse && WhatsOnElse->MenuTemplate() == 0) WhatsOnElse->PrepareTemplate(menutemplate); // Schedule cMenuTemplate* Schedule = GetTemplateByName("MenuSchedule"); if (!Schedule) { Schedule = new cMenuTemplate("MenuSchedule"); menuTemplates.insert(Schedule); } if (Schedule && Schedule->MenuTemplate() == 0) { strcpy(menutemplate, "%time_w% %time_d%:7|%time%:6|$status$:4|%title% ~ %subtitle%:30"); Schedule->PrepareTemplate(menutemplate); } // Search results cMenuTemplate* SearchResults = GetTemplateByName("MenuSearchResults"); if (!SearchResults) { SearchResults = new cMenuTemplate("MenuSearchResults"); menuTemplates.insert(SearchResults); } if (SearchResults && SearchResults->MenuTemplate() == 0) { sprintf(menutemplate, "%s%%chsh%%:12|%%datesh%%:6|%%time%%:6|$status$:3|%%title%% ~ %%subtitle%%:30", EPGSearchConfig.showChannelNr?channelnr:""); SearchResults->PrepareTemplate(menutemplate); } // Favorites cMenuTemplate* Favorites = GetTemplateByName("MenuFavorites"); if (!Favorites) { Favorites = new cMenuTemplate("MenuFavorites"); menuTemplates.insert(Favorites); } if (Favorites && Favorites->MenuTemplate() == 0) { sprintf(menutemplate, "%s%%chsh%%:12|%%time%%:6|%%timespan%%:7|$status$:3|%%title%% ~ %%subtitle%%:30", EPGSearchConfig.showChannelNr?channelnr:""); Favorites->PrepareTemplate(menutemplate); } // create an array of all search template names if (SearchTemplates) delete [] SearchTemplates; SearchTemplates = new char*[CountSearchResultsTemplates()]; std::set::iterator it; int Count = 0; for (it = menuTemplates.begin(); it != menuTemplates.end(); ++it) if (!strncasecmp("MenuSearchResults", (*it)->Name(), strlen("MenuSearchResults"))) { char* templateName = strdup((*it)->Name() + strlen("MenuSearchResults")); if (*templateName == 0) templateName = strdup(tr("Standard")); SearchTemplates[Count++] = templateName; } } int cTemplFile::CountSearchResultsTemplates() { int Count = 0; std::set::iterator it; for (it = menuTemplates.begin(); it != menuTemplates.end(); ++it) if (!strncasecmp("MenuSearchResults", (*it)->Name(), strlen("MenuSearchResults"))) Count++; return Count; } cMenuTemplate* cTemplFile::GetSearchTemplateByPos(int iPos) { int Count = 0; std::set::iterator it; for (it = menuTemplates.begin(); it != menuTemplates.end(); ++it) if (!strncasecmp("MenuSearchResults", (*it)->Name(), strlen("MenuSearchResults"))) if(Count++ == iPos) return (*it); return NULL; }