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