| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| 11 | |
| 12 | |
| 13 | |
| 14 | |
| 15 | |
| 16 | |
| 17 | |
| 18 | |
| 19 | |
| 20 | |
| 21 | |
| 22 | |
| 23 | |
| 24 | #include <set> |
| 25 | #include "templatefile.h" |
| 26 | #include "epgsearchcfg.h" |
| 27 | #include "epgsearchtools.h" |
| 28 | |
| 29 | std::set<cMenuTemplate*> cTemplFile::menuTemplates; |
| 30 | char** cTemplFile::SearchTemplates = NULL__null; |
| 31 | |
| 32 | bool cMenuTemplate::PrepareTemplate(const char* templateLine) |
| 33 | { |
| 34 | if (!templateLine || strlen(templateLine) == 0) return true; |
| 35 | |
| 36 | char *pstrSearchToken, *pptr; |
| 37 | char *pstrSearch=strdup(templateLine); |
| 38 | pstrSearchToken=strtok_r(pstrSearch, "|", &pptr); |
| 39 | cString stripped; |
| 40 | int iToken = 0; |
| 41 | while(pstrSearchToken) |
| 42 | { |
| 43 | char* tmp = strchr(pstrSearchToken,':'); |
| 44 | if (tmp) |
| 45 | { |
| 46 | int tabWidth = atoi(tmp+1); |
| 47 | if (tabWidth == 0) |
| 48 | { |
| 49 | LogFile.eSysLog("warning - tab width in \"%s\" is 0, set to min value 1!", Name()); |
| 50 | tabWidth = 1; |
| 51 | } |
| 52 | menuTabs[iToken++] = tabWidth; |
| 53 | } |
| 54 | else |
| 55 | { |
| 56 | free(pstrSearch); |
| 57 | LogFile.eSysLog("error parsing entry \"%s\", falling back to default entries.", Name()); |
| 58 | return false; |
| 59 | } |
| 60 | *tmp = 0; |
| 61 | if (isempty(stripped)) |
| 62 | stripped = strdup(pstrSearchToken); |
| 63 | else |
| 64 | { |
| 65 | cString tmp = stripped; |
| 66 | stripped = cString::sprintf("%s|%s", *tmp, pstrSearchToken); |
| 67 | } |
| 68 | pstrSearchToken=strtok_r(NULL__null, "|", &pptr); |
| 69 | } |
| 70 | free(pstrSearch); |
| 71 | |
| 72 | |
| 73 | if (iToken>0) menuTabs[iToken-1] = 0; |
| 74 | |
| 75 | if (!isempty(stripped)) |
| 76 | { |
| 77 | menuTemplate = strdup(stripped); |
| 78 | |
| 79 | |
| 80 | menuTemplate = strreplacei(menuTemplate, "%status%", "$status$"); |
| 81 | menuTemplate = strreplacei(menuTemplate, "%t_status%", "$t_status$"); |
| 82 | menuTemplate = strreplacei(menuTemplate, "%v_status%", "$v_status$"); |
| 83 | menuTemplate = strreplacei(menuTemplate, "%r_status%", "$r_status$"); |
| 84 | } |
| 85 | return true; |
| 86 | } |
| 87 | |
| 88 | cTemplLine::cTemplLine(void) |
| 89 | { |
| 90 | name = value = NULL__null; |
| 91 | } |
| 92 | |
| 93 | cTemplLine::cTemplLine(const char *Name, const char *Value) |
| 94 | { |
| 95 | name = strdup(Name); |
| 96 | value = strdup(Value); |
| 97 | } |
| 98 | |
| 99 | cTemplLine::~cTemplLine() |
| 100 | { |
| 101 | free(name); |
| 102 | free(value); |
| 103 | } |
| 104 | |
| 105 | bool cTemplLine::Parse(char *s) |
| 106 | { |
| 107 | if (!s) return false; |
| 108 | if (s[0] == '#') |
| 109 | return true; |
| 110 | char *p = strchr(s, '='); |
| 111 | if (p) |
| 112 | { |
| 113 | *p = 0; |
| 114 | char *Name = compactspace(s); |
| 115 | char *Value = compactspace(p + 1); |
| 116 | if (*Name) |
| 117 | { |
| 118 | name = strdup(Name); |
| 119 | value = strdup(Value); |
| 120 | return true; |
| 121 | } |
| 122 | } |
| 123 | return false; |
| 124 | } |
| 125 | |
| 126 | cTemplFile::cTemplFile() |
| 127 | { |
| 128 | Reset(); |
| 129 | } |
| 130 | |
| 131 | void cTemplFile::Reset() |
| 132 | { |
| 133 | std::set<cMenuTemplate*>::iterator it; |
| 134 | for (it = menuTemplates.begin(); it != menuTemplates.end(); ++it) |
| 135 | delete (*it); |
| 136 | menuTemplates.clear(); |
| 137 | } |
| 138 | |
| 139 | cMenuTemplate* cTemplFile::GetTemplateByName(const char* Name) |
| 140 | { |
| 141 | std::set<cMenuTemplate*>::iterator it; |
| 142 | for (it = menuTemplates.begin(); it != menuTemplates.end(); ++it) |
| 143 | if (!strcasecmp(Name, (*it)->Name())) return (*it); |
| 144 | return NULL__null; |
| 145 | } |
| 146 | |
| 147 | bool cTemplFile::Load(const char *FileName) |
| 148 | { |
| 149 | |
| 150 | if (strstr(Setup.FontOsd, "VDRSymbols") == Setup.FontOsd) |
| 151 | EPGSearchConfig.WarEagle = 1; |
| 152 | |
| 153 | if (cConfig<cTemplLine>::Load(FileName, true)) |
| 154 | { |
| 155 | bool result = true; |
| 156 | for (cTemplLine *l = First(); l; l = Next(l)) |
| 157 | { |
| 158 | bool error = false; |
| 159 | if (!Parse(l->Name(), l->Value())) |
| 160 | error = true; |
| 161 | if (error) |
| 162 | { |
| 163 | result = false; |
| 164 | } |
| 165 | } |
| 166 | return result; |
| 167 | } |
| 168 | return false; |
| 169 | } |
| 170 | |
| 171 | bool cTemplFile::Parse(const char *Name, const char *Value) |
| 172 | { |
| 173 | if (Name && Name[0] == '#') return true; |
| 1 | Assuming pointer value is null | |
|
| 174 | if (!strcasecmp(Name, "WarEagleIcons")) |
| 2 | | Null pointer passed as an argument to a 'nonnull' parameter |
|
| 175 | { |
| 176 | EPGSearchConfig.WarEagle = atoi(Value); |
| 177 | return true; |
| 178 | } |
| 179 | |
| 180 | if (!strcasecmp(Name, "MenuWhatsOnNow") || |
| 181 | !strcasecmp(Name, "MenuWhatsOnNext") || |
| 182 | !strcasecmp(Name, "MenuWhatsOnElse") || |
| 183 | !strcasecmp(Name, "MenuSchedule") || |
| 184 | !strncasecmp(Name, "MenuSearchResults", strlen("MenuSearchResults")) || |
| 185 | !strcasecmp(Name, "MenuFavorites")) |
| 186 | { |
| 187 | cMenuTemplate* menuTemplate = new cMenuTemplate(Name); |
| 188 | if (menuTemplate->PrepareTemplate(Value)) |
| 189 | { |
| 190 | LogFile.Log(3, "loaded menu template: %s", Name); |
| 191 | cMenuTemplate* TemplOld = GetTemplateByName(Name); |
| 192 | if (TemplOld) |
| 193 | { |
| 194 | LogFile.Log(1, "menu template '%s' gets overwritten", Name); |
| 195 | menuTemplates.erase(TemplOld); |
| 196 | delete TemplOld; |
| 197 | } |
| 198 | menuTemplates.insert(menuTemplate); |
| 199 | return true; |
| 200 | } |
| 201 | } |
| 202 | else |
| 203 | { |
| 204 | LogFile.eSysLog("ERROR: unknown parameter: %s = %s", Name, Value); |
| 205 | return false; |
| 206 | } |
| 207 | return true; |
| 208 | } |
| 209 | |
| 210 | void cTemplFile::PrepareDefaultTemplates() |
| 211 | { |
| 212 | char channelnr[20] = ""; |
| 213 | sprintf(channelnr, "%%chnr%%:%d|", CHNUMWIDTH(numdigits(Channels.MaxNumber()) + 2)); |
| 214 | |
| 215 | bool text2skin = !(strcmp(Setup.OSDSkin, "soppalusikka") == 0 || |
| 216 | strcmp(Setup.OSDSkin, "classic") == 0 || |
| 217 | strcmp(Setup.OSDSkin, "sttng") == 0); |
| 218 | |
| 219 | char menutemplate[MAXTEMPLLEN2000] = ""; |
| 220 | |
| 221 | cMenuTemplate* WhatsOnNow = GetTemplateByName("MenuWhatsOnNow"); |
| 222 | if (!WhatsOnNow) |
| 223 | { |
| 224 | WhatsOnNow = new cMenuTemplate("MenuWhatsOnNow"); |
| 225 | menuTemplates.insert(WhatsOnNow); |
| 226 | } |
| 227 | if (WhatsOnNow && WhatsOnNow->MenuTemplate() == 0) |
| 228 | { |
| 229 | sprintf(menutemplate, "%s%%chsh%%:12|%%time%%:6|%s%s$status$:3|%%title%% ~ %%subtitle%%:30", |
| 230 | EPGSearchConfig.showChannelNr?channelnr:"", |
| 231 | EPGSearchConfig.showProgress==0?"":(EPGSearchConfig.showProgress==1?"%progrT2S%:4|":"%progr%:5|"), |
| 232 | text2skin?" ":""); |
| 233 | WhatsOnNow->PrepareTemplate(menutemplate); |
| 234 | } |
| 235 | |
| 236 | |
| 237 | sprintf(menutemplate, "%s%%chsh%%:12|%%time%%:7|$status$:4|%%title%% ~ %%subtitle%%:30", |
| 238 | EPGSearchConfig.showChannelNr?channelnr:""); |
| 239 | cMenuTemplate* WhatsOnNext = GetTemplateByName("MenuWhatsOnNext"); |
| 240 | if (!WhatsOnNext) |
| 241 | { |
| 242 | WhatsOnNext = new cMenuTemplate("MenuWhatsOnNext"); |
| 243 | menuTemplates.insert(WhatsOnNext); |
| 244 | } |
| 245 | if (WhatsOnNext && WhatsOnNext->MenuTemplate() == 0) |
| 246 | WhatsOnNext->PrepareTemplate(menutemplate); |
| 247 | cMenuTemplate* WhatsOnElse = GetTemplateByName("MenuWhatsOnElse"); |
| 248 | if (!WhatsOnElse) |
| 249 | { |
| 250 | WhatsOnElse = new cMenuTemplate("MenuWhatsOnElse"); |
| 251 | menuTemplates.insert(WhatsOnElse); |
| 252 | } |
| 253 | if (WhatsOnElse && WhatsOnElse->MenuTemplate() == 0) |
| 254 | WhatsOnElse->PrepareTemplate(menutemplate); |
| 255 | |
| 256 | |
| 257 | cMenuTemplate* Schedule = GetTemplateByName("MenuSchedule"); |
| 258 | if (!Schedule) |
| 259 | { |
| 260 | Schedule = new cMenuTemplate("MenuSchedule"); |
| 261 | menuTemplates.insert(Schedule); |
| 262 | } |
| 263 | if (Schedule && Schedule->MenuTemplate() == 0) |
| 264 | { |
| 265 | strcpy(menutemplate, "%time_w% %time_d%:7|%time%:6|$status$:4|%title% ~ %subtitle%:30"); |
| 266 | Schedule->PrepareTemplate(menutemplate); |
| 267 | } |
| 268 | |
| 269 | |
| 270 | cMenuTemplate* SearchResults = GetTemplateByName("MenuSearchResults"); |
| 271 | if (!SearchResults) |
| 272 | { |
| 273 | SearchResults = new cMenuTemplate("MenuSearchResults"); |
| 274 | menuTemplates.insert(SearchResults); |
| 275 | } |
| 276 | if (SearchResults && SearchResults->MenuTemplate() == 0) |
| 277 | { |
| 278 | sprintf(menutemplate, "%s%%chsh%%:12|%%datesh%%:6|%%time%%:6|$status$:3|%%title%% ~ %%subtitle%%:30", |
| 279 | EPGSearchConfig.showChannelNr?channelnr:""); |
| 280 | SearchResults->PrepareTemplate(menutemplate); |
| 281 | } |
| 282 | |
| 283 | |
| 284 | cMenuTemplate* Favorites = GetTemplateByName("MenuFavorites"); |
| 285 | if (!Favorites) |
| 286 | { |
| 287 | Favorites = new cMenuTemplate("MenuFavorites"); |
| 288 | menuTemplates.insert(Favorites); |
| 289 | } |
| 290 | if (Favorites && Favorites->MenuTemplate() == 0) |
| 291 | { |
| 292 | sprintf(menutemplate, "%s%%chsh%%:12|%%time%%:6|%%timespan%%:7|$status$:3|%%title%% ~ %%subtitle%%:30", |
| 293 | EPGSearchConfig.showChannelNr?channelnr:""); |
| 294 | Favorites->PrepareTemplate(menutemplate); |
| 295 | } |
| 296 | |
| 297 | |
| 298 | if (SearchTemplates) |
| 299 | delete [] SearchTemplates; |
| 300 | SearchTemplates = new char*[CountSearchResultsTemplates()]; |
| 301 | std::set<cMenuTemplate*>::iterator it; |
| 302 | int Count = 0; |
| 303 | for (it = menuTemplates.begin(); it != menuTemplates.end(); ++it) |
| 304 | if (!strncasecmp("MenuSearchResults", (*it)->Name(), strlen("MenuSearchResults"))) |
| 305 | { |
| 306 | char* templateName = strdup((*it)->Name() + strlen("MenuSearchResults")); |
| 307 | if (*templateName == 0) templateName = strdup(tr("Standard")I18nTranslate("Standard", "vdr-" "epgsearch")); |
| 308 | SearchTemplates[Count++] = templateName; |
| 309 | } |
| 310 | } |
| 311 | |
| 312 | int cTemplFile::CountSearchResultsTemplates() |
| 313 | { |
| 314 | int Count = 0; |
| 315 | std::set<cMenuTemplate*>::iterator it; |
| 316 | for (it = menuTemplates.begin(); it != menuTemplates.end(); ++it) |
| 317 | if (!strncasecmp("MenuSearchResults", (*it)->Name(), strlen("MenuSearchResults"))) Count++; |
| 318 | return Count; |
| 319 | } |
| 320 | |
| 321 | cMenuTemplate* cTemplFile::GetSearchTemplateByPos(int iPos) |
| 322 | { |
| 323 | int Count = 0; |
| 324 | std::set<cMenuTemplate*>::iterator it; |
| 325 | for (it = menuTemplates.begin(); it != menuTemplates.end(); ++it) |
| 326 | if (!strncasecmp("MenuSearchResults", (*it)->Name(), strlen("MenuSearchResults"))) |
| 327 | if(Count++ == iPos) |
| 328 | return (*it); |
| 329 | return NULL__null; |
| 330 | } |