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