| 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) | 
 | 17  |  | Loop condition is true.  Entering loop body |  |  
  | 
| 42 |     { | 
| 43 | 	char* tmp = strchr(pstrSearchToken,':'); | 
| 44 | 	if (tmp) | 
 | 18  |  | Assuming 'tmp' is non-null |  |  
  | 
 |  | 
| 45 | 	{ | 
| 46 | 	    int tabWidth = atoi(tmp+1); | 
| 47 | 	    if (tabWidth == 0) | 
 | 20  |  | Assuming 'tabWidth' is not equal to 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; | 
| 174 |     if (!strcasecmp(Name, "WarEagleIcons")) | 
| 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) | 
 | 11  |  | Assuming 'Favorites' is null |  |  
  | 
 |  | 
| 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); | 
 | 15  |  | Calling 'cMenuTemplate::PrepareTemplate' |  |  
  | 
| 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 | } |