]> git.vomp.tv Git - vompclient.git/blob - vepglistadvanced.cc
Reformat VEPGListAdvanced except getCurrentOptionEvent()
[vompclient.git] / vepglistadvanced.cc
1 /*
2     Copyright 2004-2020 Chris Tallon, 2014 Marten Richter
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP.  If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 #include <sstream>
21
22 #include "boxstack.h"
23 #include "input.h"
24 #include "wsymbol.h"
25 #include "boxstack.h"
26 #include "vdr.h"
27 #include "colour.h"
28 #include "video.h"
29 #include "i18n.h"
30 #include "messagequeue.h"
31 #include "log.h"
32 #include "movieinfo.h"
33 #include "seriesinfo.h"
34 #include "event.h"
35 #include "channel.h"
36 #include "vepgsummary.h"
37 #include "vepgsettimer.h"
38 #include "vepg.h"
39 #include "staticartwork.h"
40
41 #include "vepglistadvanced.h"
42
43 VEpgListAdvanced::VEpgListAdvanced(VVideoLiveTV* tvideolive, ChannelList* tchanList, ULONG initialChannelNumber)
44 {
45   channelNumber = initialChannelNumber;
46   chanList = tchanList;
47   videolive = tvideolive;
48   boxstack = BoxStack::getInstance();
49
50   mode = OneChannel;
51
52   setSize(640 + 40, 500 + 40); //old   setSize(570, 420);
53   createBuffer();
54
55   setPosition(20, 20);
56
57   setTitleBarOn(1);
58   setTitleBarColour(DrawStyle::TITLEBARBACKGROUND);
59   TVMediaInfo* info = new TVMediaInfo();
60   info->setChannelLogo(channelNumber);
61   info->setStaticFallback(sa_tv);
62   setTitleBarIcon(info);
63
64   sl.setPosition(10, 30 + 5);
65   sl.setSize(area.w * 42 / 100 - 20, area.h - 30 - 15 - 30);
66   sl.setLinesPerOption(2.4f);
67   add(&sl);
68
69   Region slarea = sl.getRegionR();
70
71   epg.setParaMode(true);
72   epg.setPosition(slarea.x  + slarea.w + 10, 30 + 5);
73   epg.setSize(area.w - slarea.x - slarea.w - 10, area.h - 30 - 15 - 30);
74   add(&epg);
75   epg.setText("");
76   epg.setVideoBackground();
77   epg.setBackgroundColour(DrawStyle::VIEWTRANSPARENTBACKGROUND);
78
79   epgTVmedia.setPosition(epg.getRegionR().w - 100 - 10, 10);
80   epgTVmedia.setSize(100, (UINT)(150 / Osd::getInstance()->getPixelAspect()));
81   epg.add(&epgTVmedia);
82
83   boxRed.setBackgroundColour(DrawStyle::RED);
84   boxRed.setPosition(165 /*54*/, sl.getY2() + 8);
85   boxRed.setSize(18, 16);
86   add(&boxRed);
87
88   textRed.setPosition(boxRed.getX2(), sl.getY2() + 4);
89   textRed.setSize(116, 30);
90
91   add(&textRed);
92
93   boxGreen.setBackgroundColour(DrawStyle::GREEN);
94   boxGreen.setPosition(165 + 1 * 110, sl.getY2() + 8);
95   boxGreen.setSize(18, 16);
96   add(&boxGreen);
97
98   textGreen.setPosition(boxGreen.getX2(), sl.getY2() + 4);
99   textGreen.setSize(116, 30);
100   add(&textGreen);
101
102   boxYellow.setBackgroundColour(DrawStyle::YELLOW);
103   boxYellow.setPosition(165 + 2 * 110, sl.getY2() + 8);
104   boxYellow.setSize(18, 16);
105   add(&boxYellow);
106
107   textYellow.setPosition(boxYellow.getX2(), sl.getY2() + 4);
108   textYellow.setSize(116, 30);
109   add(&textYellow);
110
111   boxBlue.setBackgroundColour(DrawStyle::BLUE);
112   boxBlue.setPosition(165 + 3 * 110, sl.getY2() + 8);
113   boxBlue.setSize(18, 16);
114   add(&boxBlue);
115
116   textBlue.setPosition(boxBlue.getX2(), sl.getY2() + 4);
117   textBlue.setSize(116, 30);
118   add(&textBlue);
119
120   setButtonText();
121
122   updateEpgDataChannel();
123 }
124
125 VEpgListAdvanced::~VEpgListAdvanced()
126 {
127   clearEventList();
128 }
129
130 void VEpgListAdvanced::setButtonText()
131 {
132   switch (mode)
133   {
134     case OneChannel:
135     {
136       textRed.setText(tr("Record"));
137       textGreen.setText(tr("Now"));
138       textYellow.setText(tr("Next"));
139       textBlue.setText(tr("Guide"));
140       break;
141     }
142     case Now:
143     {
144       textRed.setText(tr("Record"));
145       textGreen.setText(tr("Next"));
146       textYellow.setText(tr("Schedule"));
147       textBlue.setText(tr("Switch"));
148       break;
149     }
150     case Next:
151     {
152       textRed.setText(tr("Record"));
153       textGreen.setText(tr("Now"));
154       textYellow.setText(tr("Schedule"));
155       textBlue.setText(tr("Switch"));
156       break;
157     }
158   };
159 }
160
161 void VEpgListAdvanced::doRed()
162 {
163   doRecord();
164 }
165
166 void VEpgListAdvanced::doGreen()
167 {
168   switch (mode)
169   {
170     case Now:
171     {
172       doNext();
173       break;
174     }
175     case OneChannel:
176     case Next:
177     {
178       doNow();
179       break;
180     }
181   };
182 }
183
184 void VEpgListAdvanced::doYellow()
185 {
186   switch (mode)
187   {
188     case OneChannel:
189     {
190       doNext();
191       break;
192     }
193     case Next:
194     case Now:
195     {
196       doProgramm();
197       break;
198     }
199   };
200 }
201
202 void VEpgListAdvanced::doBlue()
203 {
204   switch (mode)
205   {
206     case OneChannel:
207     {
208       doGrid();
209       break;
210     }
211     case Next:
212     case Now:
213     {
214       doSwitch();
215       break;
216     }
217   };
218 }
219
220 void VEpgListAdvanced::doNext()
221 {
222   Log::getInstance()->log("VEventListAdvanced", Log::DEBUG, "doNext");
223   ULONG slCurrentOption = reinterpret_cast<ULONG>(sl.getCurrentOptionData());
224
225   if (mode != OneChannel)
226   {
227     Channel* chan = (*chanList)[slCurrentOption];
228     channelNumber = chan->number;
229   }
230
231   mode = Next;
232   updateEpgDataNowNext(true);
233   setButtonText();
234   TVMediaInfo* info = new TVMediaInfo();
235   info->setStaticArtwork(sa_tv);
236   setTitleBarIcon(info);
237   draw(true);
238   boxstack->update(this);
239 }
240 void VEpgListAdvanced::doNow()
241 {
242   Log::getInstance()->log("VEventListAdvanced", Log::DEBUG, "doNow");
243   ULONG slCurrentOption = reinterpret_cast<ULONG>(sl.getCurrentOptionData());
244
245   if (mode != OneChannel)
246   {
247     Channel* chan = (*chanList)[slCurrentOption];
248     channelNumber = chan->number;
249   }
250
251   mode = Now;
252   updateEpgDataNowNext(true);
253   setButtonText();
254   TVMediaInfo* info = new TVMediaInfo();
255   info->setStaticArtwork(sa_tv);
256   setTitleBarIcon(info);
257   draw(true);
258   boxstack->update(this);
259 }
260
261 void VEpgListAdvanced::doProgramm()
262 {
263   Log::getInstance()->log("VEventListAdvanced", Log::DEBUG, "doProgram");
264   mode = OneChannel;
265   ULONG slCurrentOption = reinterpret_cast<ULONG>(sl.getCurrentOptionData());
266   Channel* chan = (*chanList)[slCurrentOption];
267   channelNumber = chan->number;
268   updateEpgDataChannel();
269   setButtonText();
270   TVMediaInfo* info = new TVMediaInfo();
271   info->setChannelLogo(channelNumber);
272   info->setStaticFallback(sa_tv);
273   setTitleBarIcon(info);
274   draw(true);
275   boxstack->update(this);
276 }
277
278 void VEpgListAdvanced::doSwitch()
279 {
280   if (videolive)
281   {
282     if (mode != OneChannel)
283     {
284       ULONG slCurrentOption = reinterpret_cast<ULONG>(sl.getCurrentOptionData());
285       Channel* chan = (*chanList)[slCurrentOption];
286       channelNumber = chan->number;
287     }
288
289     Log::getInstance()->log("VEventListAdvanced", Log::DEBUG, "doSwitch %d", channelNumber);
290     Message* m = new Message(); // Must be done after this view deleted
291     m->from = this;
292     m->to = videolive;
293     m->message = Message::CHANNEL_CHANGE;
294     m->parameter = channelNumber;
295     m->tag = 0;
296     MessageQueue::getInstance()->postMessage(m);
297   }
298 }
299
300 #if WIN32
301   // FIXME win pragma
302   #pragma warning(disable : 4703)
303 #endif
304
305 void VEpgListAdvanced::doRecord()
306 {
307   int channel;
308   Event* current = getCurrentOptionEvent(channel);
309
310   if (current)
311   {
312     Log::getInstance()->log("VEventListAdvanced", Log::DEBUG, "Found the option you pointed at. %s %d", current->title, current->id);
313     unsigned int chanlistsize = chanList->size();
314     Channel* chan;
315     UINT listIndex;
316
317     for (listIndex = 0; listIndex < chanlistsize; listIndex++)
318     {
319       chan = (*chanList)[listIndex];
320
321       if ((int)chan->number == channel) break;
322     }
323
324     Log::getInstance()->log("VEpgSummary", Log::DEBUG, "ID %lu TIME %lu DURATION %lu TITLE %s",
325                             current->id, current->time, current->duration, current->title);
326     VEpgSetTimer* vs = new VEpgSetTimer(current, chan);
327     vs->draw();
328     boxstack->add(vs);
329     boxstack->update(vs);
330   }
331
332 }
333
334 void VEpgListAdvanced::doGrid()
335 {
336   if (mode != OneChannel)
337   {
338     ULONG slCurrentOption = reinterpret_cast<ULONG>(sl.getCurrentOptionData());
339     Channel* chan = (*chanList)[slCurrentOption];
340     channelNumber = chan->number;
341   }
342
343   UINT listIndex;
344   unsigned int chanlistsize = chanList->size();
345   Channel* chan;
346
347   for (listIndex = 0; listIndex < chanlistsize; listIndex++)
348   {
349     chan = (*chanList)[listIndex];
350     if (chan->number == channelNumber) break;
351   }
352
353   VEpg* vepg = new VEpg(videolive, listIndex, chanList);
354   vepg->draw();
355   boxstack->add(vepg);
356   boxstack->update(vepg);
357 }
358
359 void VEpgListAdvanced::clearEventList()
360 {
361   std::vector<EventList*>::iterator itty = eventLista.begin();
362
363   while (itty != eventLista.end())
364   {
365     if (*itty)
366     {
367       (*itty)->clear();
368       delete (*itty);
369     }
370
371     itty++;
372   }
373
374   eventLista.clear();
375 }
376
377 /* Prototype
378  *
379  *   if (!chanList) return;
380   Channel* chan;
381   for(UINT listIndex = 0; listIndex < gridRows; listIndex++)
382   {
383     if(listTop + listIndex >= UINT(chanListbox.getBottomOption()))
384       continue;
385     chan = (*chanList)[listTop + listIndex];
386     eventLista[listIndex] = VDR::getInstance()->getChannelSchedule(chan->number, ltime - 1, window_width * 60 + 2); // ltime - 1 to get prog before window (allows cursor left past ltime). + 2 to get prog after window
387   }
388
389  */
390
391 void VEpgListAdvanced::updateEpgData()
392 {
393   switch (mode)
394   {
395     case OneChannel:
396     {
397       //updateEpgDataChannel();
398       break;
399     }
400     case Next:
401     case Now:
402     {
403       updateEpgDataNowNext(false);
404       break;
405     }
406   };
407 }
408
409 void VEpgListAdvanced::updateEpgDataNowNext(bool changeState)
410 {
411   int startupdate = 0;
412   int endupdate = 0;
413
414   unsigned int chanlistsize = chanList->size();
415
416   if (changeState)
417   {
418     clearEventList();
419     eventLista.resize(chanList->size());
420     Channel* chan;
421
422     for (UINT listIndex = 0; listIndex < chanlistsize; listIndex++)
423     {
424       if (listIndex < 0) continue;
425       if (listIndex >= chanlistsize) continue;
426
427       chan = (*chanList)[listIndex];
428
429       if (chan->number == channelNumber)
430       {
431         startupdate = listIndex - sl.getNumOptionsDisplayable() - 2;
432         endupdate = listIndex + sl.getNumOptionsDisplayable() + 2;
433         break;
434       }
435     }
436   }
437   else
438   {
439     startupdate = sl.getTopOption() - 2;
440     endupdate = sl.getBottomOption() + 1;
441   }
442
443   time_t now;
444   time(&now);
445
446   Channel* chan;
447
448   for (int listIndex = startupdate; listIndex < endupdate; listIndex++)
449   {
450     if (listIndex < 0) continue;
451     if (listIndex >= (int)chanlistsize) continue;
452
453     chan = (*chanList)[listIndex];
454
455     if (!eventLista[listIndex]) eventLista[listIndex] = VDR::getInstance()->getChannelSchedule(chan->number, now, 4 * 60 * 60);
456   }
457 }
458
459 void VEpgListAdvanced::updateEpgDataChannel()
460 {
461   clearEventList();
462   eventLista.resize(1);
463   time_t now;
464   time(&now);
465   eventLista[0] = VDR::getInstance()->getChannelSchedule(channelNumber, now, 24 * 60 * 60 * 30); // one month
466   Log::getInstance()->log("VEventListAdvanced", Log::DEBUG, "Eventlist %x %d", eventLista[0], channelNumber);
467 }
468
469 void VEpgListAdvanced::drawData(bool doIndexPop)
470 {
471   switch (mode)
472   {
473     case OneChannel:
474     {
475       drawDataChannel(doIndexPop);
476       break;
477     }
478     case Next:
479     {
480       drawDataNowNext(true, doIndexPop);
481       break;
482     }
483     case Now:
484     {
485       drawDataNowNext(false, doIndexPop);
486       break;
487     }
488   };
489
490 }
491
492 void VEpgListAdvanced::drawDataChannel(bool doIndexPop)
493 {
494   int saveIndex = sl.getCurrentOption();
495   int saveTop = sl.getTopOption();
496   sl.clear();
497   sl.addColumn(0);
498   sl.addColumn(25 );
499   sl.addColumn(25 + 7);
500   sl.addColumn(25 + 7 + 7);
501   //sl.addColumn(118);
502
503   int first = 1;
504
505   char tempA[300]; // FIXME  this is guesswork!
506   char tempB[300]; // FIXME
507   char tempC[300]; // FIXME
508   struct tm btime;
509
510   Event* currentEvent = NULL;
511   EventList::iterator j;
512   EventList* eventList = eventLista[0];
513
514   if (eventList)
515   {
516     for (j = eventList->begin(); j != eventList->end(); j++)
517     {
518       currentEvent = *j;
519       time_t eventStartTime = (time_t)currentEvent->time;
520       time_t eventEndTime = (time_t)(currentEvent->time + currentEvent->duration);
521
522       LOCALTIME_R(&eventStartTime, &btime);
523       strftime(tempA, 300, "%d/%m/%y %H:%M ", &btime);
524       LOCALTIME_R(&eventEndTime, &btime);
525       strftime(tempB, 300, "- %H:%M ", &btime);
526       int check = SNPRINTF(tempC, 300, "\t %s\n \t \t%s%s", currentEvent->title, tempA, tempB);
527
528       if ((check < 0) || (check > 299)) Log::getInstance()->log("VEventListAdvanced", Log::DEBUG, "String too big");
529
530       // New TVMedia stuff
531       TVMediaInfo* info = new TVMediaInfo();
532       info->setPosterThumb(channelNumber, currentEvent->id);
533       info->setStaticFallback(sa_defposter);
534       currentEvent->index = sl.addOption(tempC, reinterpret_cast<void*>(currentEvent->id), first, info);
535       first = 0;
536     }
537   }
538
539   if (doIndexPop)
540   {
541     sl.hintSetCurrent(0);
542   }
543   else
544   {
545     sl.hintSetCurrent(saveIndex);
546     sl.hintSetTop(saveTop);
547   }
548
549   updateSelection();
550 }
551
552 void VEpgListAdvanced::drawDataNowNext(bool next, bool doIndexPop)
553 {
554   int saveIndex = sl.getCurrentOption();
555   int saveTop = sl.getTopOption();
556   sl.clear();
557   sl.addColumn(0);
558   sl.addColumn(42 );
559   sl.addColumn(160);
560
561   int first = 1;
562
563   char tempA[300]; // FIXME  this is guesswork!
564   char tempB[300]; // FIXME
565   char tempC[300]; // FIXME
566   struct tm btime;
567
568   Event* currentEvent = NULL;
569   EventList::iterator j;
570   int minevents = 1;
571
572   if (next) minevents++;
573
574   int setcurrenthelper = 0;
575
576   unsigned int chanlistsize = chanList->size();
577
578   for (UINT listIndex = 0; listIndex < chanlistsize; listIndex++)
579   {
580     Channel* chan;
581     chan = (*chanList)[listIndex];
582
583     EventList* eventList = eventLista[listIndex];
584
585     if (eventList && ((int)eventList->size() >= minevents))
586     {
587       j = eventList->begin();
588
589       currentEvent = j[minevents - 1];
590       time_t eventStartTime = (time_t)currentEvent->time;
591       time_t eventEndTime = (time_t)(currentEvent->time + currentEvent->duration);
592
593       LOCALTIME_R(&eventStartTime, &btime);
594       strftime(tempA, 300, "%H:%M ", &btime);
595       LOCALTIME_R(&eventEndTime, &btime);
596       strftime(tempB, 300, "- %H:%M ", &btime);
597       int check = SNPRINTF(tempC, 300, "%s\n%s\t %s%s", currentEvent->title, chan->name, tempA, tempB);
598
599       if ((check < 0) || (check > 299)) Log::getInstance()->log("VEventListAdvanced", Log::DEBUG, "String too big");
600     }
601     else
602     {
603       sprintf(tempC, "\n%s", chan->name);
604     }
605
606     TVMediaInfo* info = new TVMediaInfo();
607
608     if ((*chanList)[listIndex]->number == channelNumber)
609     {
610       first = 1;
611       setcurrenthelper = listIndex;
612     }
613
614     info->setChannelLogo((*chanList)[listIndex]->number);
615     info->setStaticFallback(sa_tv);
616     int index = sl.addOption(tempC, reinterpret_cast<void*>(listIndex), first, info);
617
618     if (currentEvent) currentEvent->index = index;
619
620     first = 0;
621   }
622
623   if (doIndexPop)
624   {
625     sl.hintSetCurrent(setcurrenthelper);
626   }
627   else
628   {
629     sl.hintSetCurrent(saveIndex);
630     sl.hintSetTop(saveTop);
631   }
632
633   updateSelection();
634 }
635
636 void VEpgListAdvanced::draw(bool doIndexPop)
637 {
638   // Single channel mode
639   switch (mode)
640   {
641     case OneChannel:
642     {
643       char tempA[300];
644       unsigned int chanlistsize = chanList->size();
645       Channel* chan;
646       UINT listIndex;
647
648       for (listIndex = 0; listIndex < chanlistsize; listIndex++)
649       {
650         chan = (*chanList)[listIndex];
651
652         if (chan->number == channelNumber) break;
653       }
654
655       sprintf(tempA, tr("Schedule - %s"), (*chanList)[listIndex]->name);
656       setTitleText(tempA);
657       break;
658     }
659     case Now:
660     {
661       setTitleText(tr("Now"));
662       break;
663     }
664     case Next:
665     {
666       setTitleText(tr("Next"));
667       break;
668     }
669   };
670
671   drawData(doIndexPop);
672
673   TBBoxx::draw();
674
675
676   char freeSpace[50];
677   struct tm btime;
678   time_t now;
679
680   time(&now);
681   LOCALTIME_R(&now, &btime);
682   strftime(freeSpace, 299, "%d/%m/%y", &btime);
683   drawTextRJ(freeSpace, getWidth(), 5, DrawStyle::LIGHTTEXT);
684
685   // Symbols
686
687   WSymbol w;
688   TEMPADD(&w);
689
690   w.nextSymbol = WSymbol::UP;
691   w.setPosition(20, area.h - 35);
692   w.draw();
693
694   w.nextSymbol = WSymbol::DOWN;
695   w.setPosition(50, area.h - 35);
696   w.draw();
697
698   w.nextSymbol = WSymbol::SKIPBACK;
699   w.setPosition(85, area.h - 35);
700   w.draw();
701
702   w.nextSymbol = WSymbol::SKIPFORWARD;
703   w.setPosition(115, area.h - 35);
704   w.draw();
705
706   drawTextRJ(tr("[ok] = info"), 560 + 70, sl.getY2() + 4, DrawStyle::LIGHTTEXT);
707
708   // All static stuff done
709 }
710
711 Event* VEpgListAdvanced::getCurrentOptionEvent(int& channel)
712 {
713         // version for channel
714         Event* currentEvent = NULL;
715         EventList::iterator j;
716         EventList* eventList = NULL;
717     ULONG slCurrentOption = reinterpret_cast<ULONG>(sl.getCurrentOptionData());
718
719         switch (mode)
720         {
721         case OneChannel: {
722                 eventList = eventLista[0];
723                 if (eventList) {
724                         channel = channelNumber;
725                         for (j = eventList->begin(); j != eventList->end(); j++)
726                         {
727                                 currentEvent = *j;
728                                 if (currentEvent->index == slCurrentOption) return currentEvent;
729                         }
730
731
732                 } break;
733         case Next: {
734                 eventList = eventLista[slCurrentOption];
735                 channel = (*chanList)[slCurrentOption]->number;
736
737
738                 if (eventList && eventList->size()>1) {
739                         j = eventList->begin();
740                         currentEvent = j[1];
741                 } else {
742                         currentEvent = NULL;
743                 }
744         } break;
745         case Now: {
746                 eventList = eventLista[slCurrentOption];
747                 channel = (*chanList)[slCurrentOption]->number;
748
749                 if (eventList && eventList->size()>0) {
750                         j = eventList->begin();
751                         currentEvent = j[0];
752                 } else {
753                         currentEvent = NULL;
754                 }
755         } break;
756         };
757
758
759   }
760   return currentEvent;
761 }
762
763 void VEpgListAdvanced::updateSelection()
764 {
765   int channel = 0;
766
767   if (mode == OneChannel)
768   {
769     TVMediaInfo* info = new TVMediaInfo();
770     info->setChannelLogo(channelNumber);
771     info->setStaticFallback(sa_tv);
772     setTitleBarIcon(info);
773   }
774
775   Event* toShow = getCurrentOptionEvent(channel);
776
777   if (toShow)
778   {
779     toShow->loadinfos(channel);
780     std::stringstream description;
781
782     description << "\n" << toShow->title  << "\n\n";
783     description << toShow->subtitle << "\n";
784     description << toShow->description;
785
786     TVMedia poster;
787     poster.height = 0;
788
789     if (toShow->movieInfo)
790     {
791       poster = toShow->movieInfo->poster;
792     }
793
794     if (toShow->seriesInfo)
795     {
796       if (toShow->seriesInfo->seasonposter.height)
797       {
798         poster = toShow->seriesInfo->seasonposter;
799       }
800       else if (toShow->seriesInfo->posters.size())
801       {
802         poster = toShow->seriesInfo->posters[0];
803       }
804     }
805
806     if (poster.height)
807     {
808       epgTVmedia.setTVMedia(poster.info, WTVMedia::ZoomHorizontal);
809       epgTVmedia.setVisible(true);
810     }
811     else
812     {
813       if (toShow->epgImage)
814       {
815         TVMediaInfo info;
816         info.setPosterThumb(channel, toShow->id);
817         epgTVmedia.setTVMedia(info, WTVMedia::ZoomHorizontal);
818         epgTVmedia.setVisible(true);
819       }
820       else if (mode != OneChannel)
821       {
822         TVMediaInfo info;
823         info.setChannelLogo(channel);
824         epgTVmedia.setTVMedia(info, WTVMedia::ZoomHorizontal);
825         epgTVmedia.setVisible(true);
826       }
827       else
828       {
829         epgTVmedia.setVisible(false);
830       }
831     }
832
833     epg.setText(description.str().c_str());
834   }
835   else
836   {
837     epg.setText("");
838
839     if (mode != OneChannel)
840     {
841       TVMediaInfo info;
842       info.setChannelLogo(channel);
843       epgTVmedia.setTVMedia(info, WTVMedia::ZoomHorizontal);
844       epgTVmedia.setVisible(true);
845     }
846     else
847     {
848       epgTVmedia.setVisible(false);
849     }
850   }
851 }
852
853 int VEpgListAdvanced::handleCommand(int command)
854 {
855   switch (command)
856   {
857     case Input::UP:
858     {
859       sl.up();
860       quickUpdate();
861
862       boxstack->update(this);
863       return 2;
864     }
865
866     case Input::DOWN:
867     {
868       sl.down();
869       quickUpdate();
870
871       boxstack->update(this);
872       return 2;
873     }
874
875     case Input::SKIPBACK:
876     {
877       sl.pageUp();
878       quickUpdate();
879
880       boxstack->update(this);
881       return 2;
882     }
883
884     case Input::SKIPFORWARD:
885     {
886       sl.pageDown();
887       quickUpdate();
888
889       boxstack->update(this);
890       return 2;
891     }
892
893     case Input::RED:
894     {
895       doRed();
896       return 2;
897     }
898
899     case Input::GREEN:
900     {
901       doGreen();
902       return 2;
903     }
904
905     case Input::YELLOW:
906     {
907       doYellow();
908       return 2;
909     }
910
911     case Input::BLUE:
912     {
913       doBlue();
914       return 2;
915     }
916
917     case Input::OK:
918     {
919       if (sl.getNumOptions() == 0) return 2;
920
921       int channel;
922       Event* current = getCurrentOptionEvent(channel);
923
924       if (current)
925       {
926         Log::getInstance()->log("VEventListAdvanced", Log::DEBUG, "Found the option you pointed at. %s %d", current->title, current->id);
927         unsigned int chanlistsize = chanList->size();
928         Channel* chan;
929         UINT listIndex;
930
931         for (listIndex = 0; listIndex < chanlistsize; listIndex++)
932         {
933           chan = (*chanList)[listIndex];
934           if ((int)chan->number == channel) break;
935         }
936
937         VEpgSummary* vr = new VEpgSummary(current, (*chanList)[listIndex]);
938         vr->draw();
939         boxstack->add(vr);
940         boxstack->update(vr);
941
942         return 2;
943       }
944
945       // should not get to here
946       return 1;
947     }
948
949     case Input::BACK:
950     {
951       return 4;
952     }
953   }
954
955   // stop command getting to any more views
956   return 1;
957 }
958
959 void VEpgListAdvanced::processMessage(Message* m)
960 {
961   Log::getInstance()->log("VEpgListAdvanced", Log::DEBUG, "Got message value %lu", m->message);
962
963   if (m->message == Message::MOUSE_MOVE)
964   {
965     if (sl.mouseMove((m->parameter >> 16) - getScreenX(), (m->parameter & 0xFFFF) - getScreenY()))
966     {
967       quickUpdate();
968       boxstack->update(this);
969     }
970   }
971   else if (m->message == Message::MOUSE_LBDOWN)
972   {
973     if (sl.mouseLBDOWN((m->parameter >> 16) - getScreenX(), (m->parameter & 0xFFFF) - getScreenY()))
974     {
975       boxstack->handleCommand(Input::OK); //simulate OK press
976     }
977     else if (boxRed.mouseLBDOWN((m->parameter >> 16) - getScreenX(), (m->parameter & 0xFFFF) - getScreenY()))
978     {
979       boxstack->handleCommand(Input::RED);
980     }
981     else if (boxGreen.mouseLBDOWN((m->parameter >> 16) - getScreenX(), (m->parameter & 0xFFFF) - getScreenY()))
982     {
983       boxstack->handleCommand(Input::GREEN);
984     }
985     else if (boxYellow.mouseLBDOWN((m->parameter >> 16) - getScreenX(), (m->parameter & 0xFFFF) - getScreenY()))
986     {
987       boxstack->handleCommand(Input::GREEN);
988     }
989     else if (boxBlue.mouseLBDOWN((m->parameter >> 16) - getScreenX(), (m->parameter & 0xFFFF) - getScreenY()))
990     {
991       boxstack->handleCommand(Input::GREEN);
992     }
993     else
994     {
995       if (coordsOutsideBox(m))
996       {
997         boxstack->handleCommand(Input::BACK); //simulate cancel press
998       }
999     }
1000   }
1001 }
1002
1003 void VEpgListAdvanced::quickUpdate()   //only quick for plattform that need it!
1004 {
1005   updateEpgData();
1006   updateSelection();
1007 #ifdef GRADIENT_DRAWING
1008   draw();
1009 #else
1010   sl.draw();
1011   epg.draw();
1012 #endif
1013 }