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; |
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) |
| 10 | | Assuming 'SearchResults' is non-null | |
|
| |
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) |
| 13 | | Assuming 'Favorites' is non-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); |
295 | } |
296 | |
297 | |
298 | if (SearchTemplates) |
| 16 | | Assuming 'SearchTemplates' is null | |
|
| |
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) |
| 18 | | Loop condition is true. Entering loop body | |
|
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; |
| 22 | | Potential leak of memory pointed to by '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 | } |