2 Copyright 2004-2007 Chris Tallon, 2014 Marten Richter
4 This file is part of VOMP.
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.
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.
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.
21 #include "vepglistadvanced.h"
33 #include "movieinfo.h"
34 #include "seriesinfo.h"
37 #include "vepgsummary.h"
38 #include "vepgsettimer.h"
40 #include "staticartwork.h"
45 VEpgListAdvanced::VEpgListAdvanced(VVideoLiveTV *tvideolive, ChannelList* tchanList,ULONG initialChannelNumber)
47 channelNumber = initialChannelNumber;
49 videolive = tvideolive;
50 boxstack = BoxStack::getInstance();
54 setSize(640+40, 500+40); //old setSize(570, 420);
60 setTitleBarColour(DrawStyle::TITLEBARBACKGROUND);
61 TVMediaInfo *info= new TVMediaInfo();
62 info->setChannelLogo(channelNumber);
63 info->setStaticFallback(sa_tv);
64 setTitleBarIcon(info);
66 sl.setPosition(10, 30 + 5);
67 sl.setSize(area.w*42/100 - 20, area.h - 30 - 15 - 30);
68 sl.setLinesPerOption(2.4f);
71 Region slarea=sl.getRegionR();
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);
78 epg.setVideoBackground();
79 epg.setBackgroundColour(DrawStyle::VIEWTRANSPARENTBACKGROUND);
81 epgTVmedia.setPosition(epg.getRegionR().w-100-10,10);
82 epgTVmedia.setSize(100,(UINT)(150/Osd::getInstance()->getPixelAspect()));
85 boxRed.setBackgroundColour(DrawStyle::RED);
86 boxRed.setPosition(165 /*54*/, sl.getY2()+8);
87 boxRed.setSize(18, 16);
90 textRed.setPosition(boxRed.getX2(), sl.getY2()+4);
91 textRed.setSize(116, 30);
95 boxGreen.setBackgroundColour(DrawStyle::GREEN);
96 boxGreen.setPosition(165 +1*110, sl.getY2()+8);
97 boxGreen.setSize(18, 16);
100 textGreen.setPosition(boxGreen.getX2(), sl.getY2()+4);
101 textGreen.setSize(116, 30);
104 boxYellow.setBackgroundColour(DrawStyle::YELLOW);
105 boxYellow.setPosition(165 +2*110, sl.getY2()+8);
106 boxYellow.setSize(18, 16);
109 textYellow.setPosition(boxYellow.getX2(), sl.getY2()+4);
110 textYellow.setSize(116, 30);
113 boxBlue.setBackgroundColour(DrawStyle::BLUE);
114 boxBlue.setPosition(165 +3*110, sl.getY2()+8);
115 boxBlue.setSize(18, 16);
118 textBlue.setPosition(boxBlue.getX2(), sl.getY2()+4);
119 textBlue.setSize(116, 30);
125 updateEpgDataChannel();
128 VEpgListAdvanced::~VEpgListAdvanced()
134 void VEpgListAdvanced::setButtonText()
139 textRed.setText(tr("Record"));
140 textGreen.setText(tr("Now"));
141 textYellow.setText(tr("Next"));
142 textBlue.setText(tr("Guide"));
146 textRed.setText(tr("Record"));
147 textGreen.setText(tr("Next"));
148 textYellow.setText(tr("Schedule"));
149 textBlue.setText(tr("Switch"));
152 textRed.setText(tr("Record"));
153 textGreen.setText(tr("Now"));
154 textYellow.setText(tr("Schedule"));
155 textBlue.setText(tr("Switch"));
161 void VEpgListAdvanced::doRed()
166 void VEpgListAdvanced::doGreen()
180 void VEpgListAdvanced::doYellow()
194 void VEpgListAdvanced::doBlue()
208 void VEpgListAdvanced::doNext()
210 Log::getInstance()->log("VEventListAdvanced", Log::DEBUG, "doNext");
211 if (mode!=OneChannel) {
212 Channel * chan=(*chanList)[ sl.getCurrentOptionData()];
213 channelNumber = chan->number;
216 updateEpgDataNowNext(true);
218 TVMediaInfo *info= new TVMediaInfo();
219 info->setStaticArtwork(sa_tv);
220 setTitleBarIcon(info);
222 boxstack->update(this);
224 void VEpgListAdvanced::doNow()
226 Log::getInstance()->log("VEventListAdvanced", Log::DEBUG, "doNow");
227 if (mode!=OneChannel) {
228 Channel * chan=(*chanList)[ sl.getCurrentOptionData()];
229 channelNumber = chan->number;
232 updateEpgDataNowNext(true);
234 TVMediaInfo *info= new TVMediaInfo();
235 info->setStaticArtwork(sa_tv);
236 setTitleBarIcon(info);
238 boxstack->update(this);
241 void VEpgListAdvanced::doProgramm()
243 Log::getInstance()->log("VEventListAdvanced", Log::DEBUG, "doProgram");
246 Channel * chan=(*chanList)[ sl.getCurrentOptionData()];
247 channelNumber = chan->number;
248 updateEpgDataChannel();
250 TVMediaInfo *info= new TVMediaInfo();
251 info->setChannelLogo(channelNumber);
252 info->setStaticFallback(sa_tv);
253 setTitleBarIcon(info);
255 boxstack->update(this);
258 void VEpgListAdvanced::doSwitch()
263 if (mode!=OneChannel) {
264 Channel * chan=(*chanList)[ sl.getCurrentOptionData()];
265 channelNumber = chan->number;
267 Log::getInstance()->log("VEventListAdvanced", Log::DEBUG, "doSwitch %d", channelNumber);
268 Message* m = new Message(); // Must be done after this view deleted
271 m->message = Message::CHANNEL_CHANGE;
272 m->parameter.num = channelNumber;
274 Command::getInstance()->postMessageNoLock(m);
280 #pragma warning(disable : 4703)
283 void VEpgListAdvanced::doRecord()
286 Event* current = getCurrentOptionEvent(channel);
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();
293 for(listIndex = 0; listIndex < chanlistsize; listIndex++)
295 chan = (*chanList)[listIndex];
296 if ((int)chan->number == channel) break;
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);
304 boxstack->update(vs);
309 void VEpgListAdvanced::doGrid()
312 if (mode!=OneChannel) {
313 Channel * chan=(*chanList)[ sl.getCurrentOptionData()];
314 channelNumber = chan->number;
317 unsigned int chanlistsize=chanList->size();
319 for(listIndex = 0; listIndex < chanlistsize; listIndex++)
321 chan = (*chanList)[listIndex];
322 if (chan->number == channelNumber) break;
325 VEpg* vepg = new VEpg(videolive, listIndex, chanList);
328 boxstack->update(vepg);
332 void VEpgListAdvanced::clearEventList()
334 std::vector<EventList*>::iterator itty = eventLista.begin();
335 while (itty!= eventLista.end()) {
349 * if (!chanList) return;
351 for(UINT listIndex = 0; listIndex < gridRows; listIndex++)
353 if(listTop + listIndex >= UINT(chanListbox.getBottomOption()))
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
361 void VEpgListAdvanced::updateEpgData()
366 //updateEpgDataChannel();
370 updateEpgDataNowNext(false);
376 void VEpgListAdvanced::updateEpgDataNowNext(bool changeState)
381 unsigned int chanlistsize=chanList->size();
384 eventLista.resize(chanList->size());
386 for(UINT listIndex = 0; listIndex < chanlistsize; listIndex++)
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;
398 startupdate=sl.getTopOption()-2;
399 endupdate=sl.getBottomOption()+1;
406 for(int listIndex = startupdate; listIndex < endupdate; listIndex++)
408 if (listIndex < 0) continue;
409 if (listIndex >= (int)chanlistsize) continue;
411 chan = (*chanList)[listIndex];
412 if (!eventLista[listIndex]) eventLista[listIndex] = VDR::getInstance()->getChannelSchedule(chan->number, now, 4 * 60 *60);
418 void VEpgListAdvanced::updateEpgDataChannel()
421 eventLista.resize(1);
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);
429 void VEpgListAdvanced::drawData(bool doIndexPop)
434 drawDataChannel(doIndexPop);
437 drawDataNowNext(true, doIndexPop);
440 drawDataNowNext(false, doIndexPop);
446 void VEpgListAdvanced::drawDataChannel(bool doIndexPop)
448 int saveIndex = sl.getCurrentOption();
449 int saveTop = sl.getTopOption();
453 sl.addColumn(25 + 7);
454 sl.addColumn(25 + 7+ 7);
459 char tempA[300]; // FIXME this is guesswork!
460 char tempB[300]; // FIXME
461 char tempC[300]; // FIXME
467 Event* currentEvent = NULL;
468 EventList::iterator j;
469 EventList* eventList = eventLista[0];
471 for (j = eventList->begin(); j != eventList->end(); j++)
474 time_t eventStartTime = (time_t)currentEvent->time;
475 time_t eventEndTime = (time_t)(currentEvent->time + currentEvent->duration);
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);
482 sprintf(tempC, "\t %s\n \t \t%s%s", currentEvent->title,tempA,tempB);
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);
494 sl.hintSetCurrent(0);
498 sl.hintSetCurrent(saveIndex);
499 sl.hintSetTop(saveTop);
505 void VEpgListAdvanced::drawDataNowNext(bool next, bool doIndexPop)
507 int saveIndex = sl.getCurrentOption();
508 int saveTop = sl.getTopOption();
516 char tempA[300]; // FIXME this is guesswork!
517 char tempB[300]; // FIXME
518 char tempC[300]; // FIXME
524 Event* currentEvent = NULL;
525 EventList::iterator j;
527 if (next) minevents++;
528 int setcurrenthelper =0;
530 unsigned int chanlistsize=chanList->size();
531 for(UINT listIndex = 0; listIndex < chanlistsize; listIndex++)
534 chan = (*chanList)[listIndex];
536 EventList* eventList = eventLista[listIndex];
537 if (eventList && ((int)eventList->size() >= minevents)) {
538 j = eventList->begin();
540 currentEvent = j[minevents-1];
541 time_t eventStartTime = (time_t)currentEvent->time;
542 time_t eventEndTime = (time_t)(currentEvent->time + currentEvent->duration);
544 LOCALTIME_R(&eventStartTime, &btime);
545 strftime(tempA, 299, "%H:%M ", &btime);
546 LOCALTIME_R(&eventEndTime, &btime);
547 strftime(tempB, 299, "- %H:%M ", &btime);
549 sprintf(tempC, "%s\n%s\t %s%s", currentEvent->title, chan->name,tempA,tempB);
552 sprintf(tempC, "\n%s", chan->name);
555 TVMediaInfo *info= new TVMediaInfo();
556 if ((*chanList)[listIndex]->number == channelNumber) {
558 setcurrenthelper = listIndex;
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;
569 sl.hintSetCurrent(setcurrenthelper);
573 sl.hintSetCurrent(saveIndex);
574 sl.hintSetTop(saveTop);
579 void VEpgListAdvanced::draw(bool doIndexPop)
582 // Single channel mode
586 unsigned int chanlistsize=chanList->size();
589 for(listIndex = 0; listIndex < chanlistsize; listIndex++)
591 chan = (*chanList)[listIndex];
592 if (chan->number == channelNumber) break;
594 sprintf(tempA, tr("Schedule - %s"), (*chanList)[listIndex]->name);
598 setTitleText(tr("Now"));
601 setTitleText(tr("Next"));
607 drawData(doIndexPop);
621 LOCALTIME_R(&now, &btime);
622 strftime(freeSpace, 299, "%d/%m/%y", &btime);
624 drawTextRJ(freeSpace, getWidth(), 5, DrawStyle::LIGHTTEXT);
630 w.nextSymbol = WSymbol::UP;
631 w.setPosition(20, area.h-35);
633 w.nextSymbol = WSymbol::DOWN;
634 w.setPosition(50, area.h-35);
636 w.nextSymbol = WSymbol::SKIPBACK;
637 w.setPosition(85, area.h-35);
639 w.nextSymbol = WSymbol::SKIPFORWARD;
640 w.setPosition(115, area.h-35);
643 drawTextRJ(tr("[ok] = info"), 560+70, sl.getY2()+4, DrawStyle::LIGHTTEXT);
645 // All static stuff done
650 Event* VEpgListAdvanced::getCurrentOptionEvent(int& channel)
652 // version for channel
653 Event* currentEvent = NULL;
654 EventList::iterator j;
655 EventList* eventList = NULL;
659 eventList = eventLista[0];
661 channel = channelNumber;
662 for (j = eventList->begin(); j != eventList->end(); j++)
665 if (currentEvent->index == sl.getCurrentOption()) return currentEvent;
671 eventList = eventLista[sl.getCurrentOptionData()];
672 channel = (*chanList)[sl.getCurrentOptionData()]->number;
675 if (eventList && eventList->size()>1) {
676 j = eventList->begin();
683 eventList = eventLista[sl.getCurrentOptionData()];
684 channel = (*chanList)[sl.getCurrentOptionData()]->number;
686 if (eventList && eventList->size()>0) {
687 j = eventList->begin();
702 void VEpgListAdvanced::updateSelection()
705 if (mode==OneChannel) {
706 TVMediaInfo *info= new TVMediaInfo();
707 info->setChannelLogo(channelNumber);
708 info->setStaticFallback(sa_tv);
709 setTitleBarIcon(info);
711 Event* toShow = getCurrentOptionEvent(channel);
714 toShow->loadinfos(channel);
715 std::stringstream description;
717 description << "\n"<< toShow->title << "\n\n";
718 description << toShow->subtitle <<"\n";
719 description << toShow->description;
723 if (toShow->movieInfo) {
724 poster=toShow->movieInfo->poster;
726 if (toShow->seriesInfo) {
727 if (toShow->seriesInfo->seasonposter.height) {
728 poster=toShow->seriesInfo->seasonposter;
730 else if (toShow->seriesInfo->posters.size()) {
731 poster=toShow->seriesInfo->posters[0];
735 epgTVmedia.setTVMedia(poster.info, WTVMedia::ZoomHorizontal);
736 epgTVmedia.setVisible(true);
738 if (toShow->epgImage)
741 info.setPosterThumb(channel,toShow->id);
742 epgTVmedia.setTVMedia(info, WTVMedia::ZoomHorizontal);
743 epgTVmedia.setVisible(true);
744 }else if (mode!=OneChannel) {
746 info.setChannelLogo(channel);
747 epgTVmedia.setTVMedia(info, WTVMedia::ZoomHorizontal);
748 epgTVmedia.setVisible(true);
750 epgTVmedia.setVisible(false);
754 epg.setText(description.str().c_str());
757 if (mode!=OneChannel) {
759 info.setChannelLogo(channel);
760 epgTVmedia.setTVMedia(info, WTVMedia::ZoomHorizontal);
761 epgTVmedia.setVisible(true);
763 epgTVmedia.setVisible(false);
769 int VEpgListAdvanced::handleCommand(int command)
779 boxstack->update(this);
782 case Remote::DF_DOWN:
788 boxstack->update(this);
791 case Remote::SKIPBACK:
796 boxstack->update(this);
799 case Remote::SKIPFORWARD:
804 boxstack->update(this);
829 if (sl.getNumOptions() == 0) return 2;
833 Event* current = getCurrentOptionEvent(channel);
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();
840 for(listIndex = 0; listIndex < chanlistsize; listIndex++)
842 chan = (*chanList)[listIndex];
843 if ((int)chan->number == channel) break;
846 VEpgSummary* vr = new VEpgSummary(current, (*chanList)[listIndex]);
849 boxstack->update(vr);
853 // should not get to here
861 // stop command getting to any more views
865 void VEpgListAdvanced::processMessage(Message* m)
867 Log::getInstance()->log("VEpgListAdvanced", Log::DEBUG, "Got message value %lu", m->message);
869 if (m->message == Message::MOUSE_MOVE)
871 if (sl.mouseMove((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY()))
874 boxstack->update(this);
877 else if (m->message == Message::MOUSE_LBDOWN)
879 if (sl.mouseLBDOWN((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY()))
881 boxstack->handleCommand(Remote::OK); //simulate OK press
883 else if (boxRed.mouseLBDOWN((m->parameter.num >> 16) - getScreenX(), (m->parameter.num & 0xFFFF) - getScreenY()))
885 boxstack->handleCommand(Remote::RED);
887 else if (boxGreen.mouseLBDOWN((m->parameter.num >> 16) - getScreenX(), (m->parameter.num & 0xFFFF) - getScreenY()))
889 boxstack->handleCommand(Remote::GREEN);
891 else if (boxYellow.mouseLBDOWN((m->parameter.num >> 16) - getScreenX(), (m->parameter.num & 0xFFFF) - getScreenY()))
893 boxstack->handleCommand(Remote::GREEN);
895 else if (boxBlue.mouseLBDOWN((m->parameter.num >> 16) - getScreenX(), (m->parameter.num & 0xFFFF) - getScreenY()))
897 boxstack->handleCommand(Remote::GREEN);
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())
906 boxstack->handleCommand(Remote::BACK); //simulate cancel press
914 void VEpgListAdvanced::quickUpdate() { //only quick for plattform that need it!
917 #ifdef GRADIENT_DRAWING