File: | changrp.c |
Location: | line 276, column 6 |
Description: | Value stored to 'chIntEnd' is never read |
1 | /* -*- c++ -*- |
2 | Copyright (C) 2004-2013 Christian Wieninger |
3 | |
4 | This program is free software; you can redistribute it and/or |
5 | modify it under the terms of the GNU General Public License |
6 | as published by the Free Software Foundation; either version 2 |
7 | of the License, or (at your option) any later version. |
8 | |
9 | This program is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | GNU General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU General Public License |
15 | along with this program; if not, write to the Free Software |
16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
17 | Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html |
18 | |
19 | The author can be reached at cwieninger@gmx.de |
20 | |
21 | The project's page is at http://winni.vdr-developer.org/epgsearch |
22 | */ |
23 | |
24 | #include "changrp.h" |
25 | #include "epgsearchtools.h" |
26 | #include "epgsearchcfg.h" |
27 | #include "epgsearchext.h" |
28 | #include <vdr/interface.h> |
29 | |
30 | // -- cChannelGroup ----------------------------------------------------------------- |
31 | cChannelGroup::cChannelGroup(void) |
32 | { |
33 | strcpy(name, ""); |
34 | channels.Clear(); |
35 | } |
36 | |
37 | cChannelGroup::~cChannelGroup(void) |
38 | { |
39 | channels.Clear(); |
40 | } |
41 | |
42 | bool cChannelGroup::Parse(const char *s) |
43 | { |
44 | char *line; |
45 | char *pos; |
46 | char *pos_next; |
47 | int parameter = 1; |
48 | int valuelen; |
49 | #define MAXVALUELEN(10 * 255) (10 * MaxFileName255) |
50 | |
51 | char value[MAXVALUELEN(10 * 255)]; |
52 | |
53 | pos = line = strdup(s); |
54 | pos_next = pos + strlen(pos); |
55 | if (*pos_next == '\n') *pos_next = 0; |
56 | while (*pos) { |
57 | while (*pos == ' ') pos++; |
58 | if (*pos) { |
59 | if (*pos != '|') { |
60 | pos_next = strchr(pos, '|'); |
61 | if (!pos_next) |
62 | pos_next = pos + strlen(pos); |
63 | valuelen = pos_next - pos + 1; |
64 | if (valuelen > MAXVALUELEN(10 * 255)) |
65 | { |
66 | LogFile.eSysLog("entry '%s' is too long. Will be truncated!", pos); |
67 | valuelen = MAXVALUELEN(10 * 255); |
68 | } |
69 | strn0cpy(value, pos, valuelen); |
70 | pos = pos_next; |
71 | switch (parameter) { |
72 | case 1: strcpy(name,value); |
73 | break; |
74 | default: |
75 | { |
76 | #ifdef __FreeBSD__ |
77 | char *channelbuffer = MALLOC(char, 32)(char *)malloc(sizeof(char) * (32)); |
78 | int numChannels = sscanf(value, "%31[^|]", channelbuffer); |
79 | #else |
80 | char *channelbuffer = NULL__null; |
81 | int numChannels = sscanf(value, "%m[^|]", &channelbuffer); |
82 | #endif |
83 | if (numChannels == 1) |
84 | { |
85 | cChannel* channel = Channels.GetByChannelID(tChannelID::FromString(channelbuffer), true, true); |
86 | if (channel) |
87 | { |
88 | cChannelGroupItem* channelitem = new cChannelGroupItem(channel); |
89 | channels.Add(channelitem); |
90 | } |
91 | } |
92 | free(channelbuffer); |
93 | } |
94 | break; |
95 | } //switch |
96 | } |
97 | parameter++; |
98 | } |
99 | if (*pos) pos++; |
100 | } //while |
101 | |
102 | free(line); |
103 | return (parameter >= 1) ? true : false; |
104 | } |
105 | |
106 | const char *cChannelGroup::ToText(void) |
107 | { |
108 | char* channelbuffer = NULL__null; |
109 | cChannelGroupItem* ChannelGroupItem = channels.First(); |
110 | int index = 0; |
111 | while (ChannelGroupItem) |
112 | { |
113 | cChannel* channel = ChannelGroupItem->channel; |
114 | if (index++ == 0) |
115 | channelbuffer = strdup(CHANNELSTRING(channel)(*channel->GetChannelID().ToString())); |
116 | else |
117 | { |
118 | char* temp = channelbuffer; |
119 | msprintf(&channelbuffer, "%s|%s", channelbuffer, CHANNELSTRING(channel)(*channel->GetChannelID().ToString())); |
120 | free(temp); |
121 | } |
122 | ChannelGroupItem = channels.Next(ChannelGroupItem); |
123 | } |
124 | char* buffer = NULL__null; |
125 | msprintf(&buffer, "%s|%s", name, channelbuffer); |
126 | free(channelbuffer); |
127 | return buffer; |
128 | } |
129 | |
130 | int* cChannelGroup::CreateChannelSel() |
131 | { |
132 | int* channelSel = (int*) malloc(Channels.Count() * sizeof(int)); |
133 | cChannel* channel = Channels.First(); |
134 | int index = 0; |
135 | while (channel) |
136 | { |
137 | if (channel->GroupSep()) |
138 | { |
139 | channel = Channels.Next(channel); |
140 | continue; |
141 | } |
142 | channelSel[index] = 0; |
143 | cChannelGroupItem* channelInGroup = channels.First(); |
144 | while (channelInGroup) |
145 | { |
146 | if (channel == channelInGroup->channel) |
147 | { |
148 | channelSel[index] = 1; |
149 | break; |
150 | } |
151 | channelInGroup = channels.Next(channelInGroup); |
152 | } |
153 | index++; |
154 | channel = Channels.Next(channel); |
155 | } |
156 | return channelSel; |
157 | } |
158 | |
159 | void cChannelGroup::CreateChannelList(int* channelSel) |
160 | { |
161 | channels.Clear(); |
162 | cChannel* channel = Channels.First(); |
163 | int index = 0; |
164 | while (channel) |
165 | { |
166 | if (!channel->GroupSep()) |
167 | { |
168 | if (channelSel[index] == 1) |
169 | channels.Add(new cChannelGroupItem(channel)); |
170 | index++; |
171 | } |
172 | channel = Channels.Next(channel); |
173 | } |
174 | } |
175 | |
176 | bool cChannelGroup::Save(FILE *f) |
177 | { |
178 | return fprintf(f, "%s\n", ToText()) > 0; |
179 | } |
180 | |
181 | bool cChannelGroup::ChannelInGroup(cChannel* channel) |
182 | { |
183 | cChannelGroupItem* channelInGroup = channels.First(); |
184 | while (channelInGroup) |
185 | { |
186 | if (channel == channelInGroup->channel) |
187 | return true; |
188 | channelInGroup = channels.Next(channelInGroup); |
189 | } |
190 | return false; |
191 | } |
192 | |
193 | // -- cChannelGroups ----------------------------------------------------------------- |
194 | int cChannelGroups::GetIndex(char* channelGroup) |
195 | { |
196 | if (!channelGroup) |
197 | return -1; |
198 | cChannelGroup* ChannelGroup = First(); |
199 | int index = 0; |
200 | while (ChannelGroup) |
201 | { |
202 | if (strcmp(channelGroup, ChannelGroup->name) == 0) |
203 | return index; |
204 | index++; |
205 | ChannelGroup = Next(ChannelGroup); |
206 | } |
207 | return -1; |
208 | } |
209 | |
210 | cChannelGroup* cChannelGroups::GetGroupByName(const char* channelGroup) |
211 | { |
212 | if (!channelGroup) |
213 | return NULL__null; |
214 | cChannelGroup* ChannelGroup = First(); |
215 | while (ChannelGroup) |
216 | { |
217 | if (strcmp(channelGroup, ChannelGroup->name) == 0) |
218 | return ChannelGroup; |
219 | ChannelGroup = Next(ChannelGroup); |
220 | } |
221 | return NULL__null; |
222 | } |
223 | |
224 | cSearchExt* cChannelGroups::Used(cChannelGroup* group) |
225 | { |
226 | if (!group) |
227 | return NULL__null; |
228 | |
229 | if (SearchExts.Count() == 0) |
230 | SearchExts.Load(AddDirectory(CONFIGDIR(!ConfigDir?cPlugin::ConfigDirectory():ConfigDir), "epgsearch.conf")); |
231 | |
232 | cMutexLock SearchExtsLock(&SearchExts); |
233 | cSearchExt *SearchExt = SearchExts.First(); |
234 | while (SearchExt) |
235 | { |
236 | if (SearchExt->useChannel == 2 && strcmp(SearchExt->channelGroup, group->name) == 0) |
237 | return SearchExt; |
238 | SearchExt = SearchExts.Next(SearchExt); |
239 | } |
240 | return NULL__null; |
241 | } |
242 | |
243 | char** cChannelGroups::CreateMenuitemsList() |
244 | { |
245 | char** menuitemsChGr = new char*[ChannelGroups.Count()+1]; |
246 | cChannelGroup* ChannelGroup = First(); |
247 | menuitemsChGr[0] = strdup(""); |
248 | int index = 1; |
249 | while (ChannelGroup) |
250 | { |
251 | menuitemsChGr[index++] = ChannelGroup->name; |
252 | ChannelGroup = Next(ChannelGroup); |
253 | } |
254 | return menuitemsChGr; |
255 | } |
256 | |
257 | // -- cMenuChannelGroupItem ----------------------------------------------------------------- |
258 | cMenuChannelGroupItem::cMenuChannelGroupItem(cChannelGroup* Group) |
259 | { |
260 | group = Group; |
261 | Set(); |
262 | } |
263 | |
264 | void cMenuChannelGroupItem::Set(void) |
265 | { |
266 | cString channelbuffer; |
267 | |
268 | cChannelGroupItem* channelInGroup = group->channels.First(); |
269 | int channelNr, chIntBegin = -1, chIntEnd = -1, chLast = -1; |
270 | while (channelInGroup) |
271 | { |
272 | channelNr = channelInGroup->channel->Number(); |
273 | if (chIntBegin == -1) |
274 | chIntBegin = channelNr; |
275 | if (chIntEnd == -1) |
276 | chIntEnd = channelNr; |
Value stored to 'chIntEnd' is never read | |
277 | |
278 | if (chLast == channelNr-1) |
279 | chIntEnd = channelNr; |
280 | else |
281 | { |
282 | chIntEnd = chLast; |
283 | if(chIntBegin == chIntEnd) |
284 | channelbuffer = cString::sprintf("%s %d", *channelbuffer?*channelbuffer:"", chIntBegin); |
285 | else if (chIntEnd != -1) |
286 | channelbuffer = cString::sprintf("%s %d-%d", *channelbuffer?*channelbuffer:"", chIntBegin, chIntEnd); |
287 | chIntBegin = chIntEnd = channelNr; |
288 | } |
289 | |
290 | chLast = channelNr; |
291 | channelInGroup = group->channels.Next(channelInGroup); |
292 | if (!channelInGroup) |
293 | { |
294 | if(chLast == chIntBegin) |
295 | channelbuffer = cString::sprintf("%s %d", *channelbuffer?*channelbuffer:"", chIntBegin); |
296 | else |
297 | channelbuffer = cString::sprintf("%s %d-%d", *channelbuffer?*channelbuffer:"", chIntBegin, chLast); |
298 | } |
299 | } |
300 | |
301 | SetText(cString::sprintf("%s\t%s", group->name, *channelbuffer?*channelbuffer:"")); |
302 | } |
303 | |
304 | // --- cMenuChannelGroups ---------------------------------------------------------- |
305 | cMenuChannelGroups::cMenuChannelGroups(char** GroupName) |
306 | :cOsdMenu(tr("Channel groups")I18nTranslate("Channel groups", "vdr-" "epgsearch"),20) |
307 | { |
308 | #if VDRVERSNUM20005 >= 10734 |
309 | SetMenuCategory(mcSetupPlugins); |
310 | #endif |
311 | groupSel = -1; |
312 | groupName = GroupName; |
313 | if (groupName && *groupName) |
314 | groupSel = ChannelGroups.GetIndex(*groupName); |
315 | |
316 | cChannelGroup* ChannelGroup = ChannelGroups.First(); |
317 | int index = 0; |
318 | while (ChannelGroup) |
319 | { |
320 | Add(new cMenuChannelGroupItem(ChannelGroup), (index == groupSel?true:false)); |
321 | ChannelGroup = ChannelGroups.Next(ChannelGroup); |
322 | index++; |
323 | } |
324 | |
325 | if (groupName && *groupName) |
326 | SetHelp(trVDR("Button$Edit")I18nTranslate("Button$Edit"), trVDR("Button$New")I18nTranslate("Button$New"), trVDR("Button$Delete")I18nTranslate("Button$Delete"), tr("Button$Select")I18nTranslate("Button$Select", "vdr-" "epgsearch")); |
327 | else |
328 | SetHelp(trVDR("Button$Edit")I18nTranslate("Button$Edit"), trVDR("Button$New")I18nTranslate("Button$New"), trVDR("Button$Delete")I18nTranslate("Button$Delete"), NULL__null); |
329 | Sort(); |
330 | Display(); |
331 | } |
332 | |
333 | cChannelGroup *cMenuChannelGroups::CurrentGroup(void) |
334 | { |
335 | cMenuChannelGroupItem *item = (cMenuChannelGroupItem *)Get(Current()); |
336 | return item ? item->group : NULL__null; |
337 | } |
338 | |
339 | eOSState cMenuChannelGroups::New(void) |
340 | { |
341 | if (HasSubMenu()) |
342 | return osContinue; |
343 | return AddSubMenu(new cMenuEditChannelGroup(new cChannelGroup, true)); |
344 | } |
345 | |
346 | eOSState cMenuChannelGroups::Delete(void) |
347 | { |
348 | cChannelGroup *curGroup = CurrentGroup(); |
349 | if (curGroup) { |
350 | cSearchExt* search = ChannelGroups.Used(curGroup); |
351 | if (search) |
352 | { |
353 | cString Message = cString::sprintf("%s %s", tr("Channel group used by:")I18nTranslate("Channel group used by:", "vdr-" "epgsearch"), search->search); |
354 | INFO(Message)Skins.Message(mtInfo, Message); |
355 | return osContinue; |
356 | } |
357 | if (Interface->Confirm(tr("Edit$Delete group?")I18nTranslate("Edit$Delete group?", "vdr-" "epgsearch"))) { |
358 | ChannelGroups.Del(curGroup); |
359 | ChannelGroups.Save(); |
360 | cOsdMenu::Del(Current()); |
361 | Display(); |
362 | } |
363 | } |
364 | return osContinue; |
365 | } |
366 | |
367 | eOSState cMenuChannelGroups::ProcessKey(eKeys Key) |
368 | { |
369 | int GroupNumber = HasSubMenu() ? Count() : -1; |
370 | |
371 | eOSState state = cOsdMenu::ProcessKey(Key); |
372 | if (state == osUnknown) |
373 | { |
374 | if (HasSubMenu()) |
375 | return osContinue; |
376 | switch (Key) |
377 | { |
378 | case kRed: |
379 | if (CurrentGroup()) |
380 | state = AddSubMenu(new cMenuEditChannelGroup(CurrentGroup())); |
381 | else |
382 | state = osContinue; |
383 | break; |
384 | case kGreen: state = New(); break; |
385 | case kYellow: state = Delete(); break; |
386 | |
387 | case kOk: |
388 | case kBlue: |
389 | if (groupName && *groupName) |
390 | { |
391 | free(*groupName); |
392 | *groupName = strdup(CurrentGroup()->name); |
393 | return osBack; |
394 | } |
395 | default: break; |
396 | } |
397 | } |
398 | if (GroupNumber >= 0 && !HasSubMenu() && ChannelGroups.Get(GroupNumber)) |
399 | { |
400 | // a newly created group was confirmed with Ok |
401 | cChannelGroup* group = ChannelGroups.Get(GroupNumber); |
402 | Add(new cMenuChannelGroupItem(group), true); |
403 | Display(); |
404 | } |
405 | |
406 | return state; |
407 | } |
408 | |
409 | // --- cMenuEditChannelGroup -------------------------------------------------------- |
410 | cMenuEditChannelGroup::cMenuEditChannelGroup(cChannelGroup *Group, bool New) |
411 | :cOsdMenu(tr("Edit channel group")I18nTranslate("Edit channel group", "vdr-" "epgsearch"),30) |
412 | { |
413 | #if VDRVERSNUM20005 >= 10734 |
414 | SetMenuCategory(mcSetupPlugins); |
415 | #endif |
416 | group = Group; |
417 | channelSel = group->CreateChannelSel(); |
418 | strcpy(name, group->name); |
419 | addIfConfirmed = New; |
420 | Set(); |
421 | } |
422 | |
423 | cMenuEditChannelGroup::~cMenuEditChannelGroup() |
424 | { |
425 | free(channelSel); |
426 | } |
427 | |
428 | void cMenuEditChannelGroup::Set() |
429 | { |
430 | int current = Current(); |
431 | Clear(); |
432 | |
433 | Add(new cMenuEditStrItem( tr("Group name")I18nTranslate("Group name", "vdr-" "epgsearch"), name, sizeof(group->name), trVDR(FileNameChars)I18nTranslate(FileNameChars))); |
434 | cChannel* channel = Channels.First(); |
435 | int index = 0; |
436 | while (channel) |
437 | { |
438 | if (channel->GroupSep()) |
439 | { |
440 | channel = Channels.Next(channel); |
441 | continue; |
442 | } |
443 | Add(new cMenuEditBoolItem( CHANNELNAME(channel)(channel ? channel->ShortName(true) : ""), &channelSel[index++], trVDR("no")I18nTranslate("no"), trVDR("yes")I18nTranslate("yes"))); |
444 | channel = Channels.Next(channel); |
445 | } |
446 | |
447 | SetCurrent(Get(current)); |
448 | |
449 | } |
450 | |
451 | eOSState cMenuEditChannelGroup::ProcessKey(eKeys Key) |
452 | { |
453 | eOSState state = cOsdMenu::ProcessKey(Key); |
454 | |
455 | const char* ItemText = Get(Current())->Text(); |
456 | if (strlen(ItemText) > 0 && strstr(ItemText, tr("Group name")I18nTranslate("Group name", "vdr-" "epgsearch")) != ItemText) |
457 | SetHelp(tr("Button$Invert selection")I18nTranslate("Button$Invert selection", "vdr-" "epgsearch"), tr("Button$All yes")I18nTranslate("Button$All yes", "vdr-" "epgsearch"), tr("Button$All no")I18nTranslate("Button$All no", "vdr-" "epgsearch"), NULL__null); |
458 | else if (!InEditMode(ItemText, tr("Group name")I18nTranslate("Group name", "vdr-" "epgsearch"), name)) |
459 | SetHelp(NULL__null, NULL__null, NULL__null, NULL__null); |
460 | |
461 | if (state == osUnknown) { |
462 | switch (Key) { |
463 | case kOk: |
464 | if (strlen(name) == 0) |
465 | { |
466 | ERROR(tr("Group name is empty!"))Skins.Message(mtError, I18nTranslate("Group name is empty!", "vdr-" "epgsearch")); |
467 | return osContinue; |
468 | } |
469 | if (addIfConfirmed && ChannelGroups.GetGroupByName(name)) |
470 | { |
471 | ERROR(tr("Group name already exists!"))Skins.Message(mtError, I18nTranslate("Group name already exists!" , "vdr-" "epgsearch")); |
472 | return osContinue; |
473 | } |
474 | |
475 | { |
476 | bool saveSearchExts = false; |
477 | if (strcmp(group->name, name) != 0 && !addIfConfirmed) // if group name changed, update searches |
478 | { |
479 | cMutexLock SearchExtsLock(&SearchExts); |
480 | cSearchExt *SearchExt = SearchExts.First(); |
481 | while (SearchExt) { |
482 | if (SearchExt->useChannel == 2 && |
483 | SearchExt->channelGroup && |
484 | strcmp(SearchExt->channelGroup, group->name) == 0) |
485 | { |
486 | free(SearchExt->channelGroup); |
487 | SearchExt->channelGroup = strdup(name); |
488 | } |
489 | SearchExt = SearchExts.Next(SearchExt); |
490 | } |
491 | saveSearchExts = true; // save them after groups are saved! |
492 | } |
493 | |
494 | strcpy(group->name, name); |
495 | group->CreateChannelList(channelSel); |
496 | if (addIfConfirmed) |
497 | ChannelGroups.Add(group); |
498 | ChannelGroups.Save(); |
499 | if (saveSearchExts) |
500 | SearchExts.Save(); |
501 | } |
502 | addIfConfirmed = false; |
503 | return osBack; |
504 | break; |
505 | case kRed: |
506 | case kGreen: |
507 | case kYellow: |
508 | { |
509 | cChannel* channel = Channels.First(); |
510 | int index = 0; |
511 | while (channel) |
512 | { |
513 | if (channel->GroupSep()) |
514 | { |
515 | channel = Channels.Next(channel); |
516 | continue; |
517 | } |
518 | |
519 | channelSel[index] = (Key == kGreen?1:(Key == kRed?1-channelSel[index]:0)); |
520 | index++; |
521 | channel = Channels.Next(channel); |
522 | } |
523 | Set(); |
524 | Display(); |
525 | return osContinue; |
526 | } |
527 | |
528 | default: break; |
529 | } |
530 | } |
531 | return state; |
532 | } |