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