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