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 setTitleBarIcon(info);
65 sl.setPosition(10, 30 + 5);
66 sl.setSize(area.w*42/100 - 20, area.h - 30 - 15 - 30);
67 sl.setLinesPerOption(2.4f);
70 Region slarea=sl.getRegionR();
72 epg.setParaMode(true);
73 epg.setPosition(slarea.x +slarea.w+10 ,30+5);
74 epg.setSize(area.w -slarea.x -slarea.w -10, area.h - 30 - 15 - 30);
77 epg.setVideoBackground();
78 epg.setBackgroundColour(DrawStyle::VIEWTRANSPARENTBACKGROUND);
80 epgTVmedia.setPosition(epg.getRegionR().w-100-10,10);
81 epgTVmedia.setSize(100,150/Osd::getInstance()->getPixelAspect());
84 boxRed.setBackgroundColour(DrawStyle::RED);
85 boxRed.setPosition(165 /*54*/, sl.getY2()+8);
86 boxRed.setSize(18, 16);
89 textRed.setPosition(boxRed.getX2(), sl.getY2()+4);
90 textRed.setSize(116, 30);
94 boxGreen.setBackgroundColour(DrawStyle::GREEN);
95 boxGreen.setPosition(165 +1*110, sl.getY2()+8);
96 boxGreen.setSize(18, 16);
99 textGreen.setPosition(boxGreen.getX2(), sl.getY2()+4);
100 textGreen.setSize(116, 30);
103 boxYellow.setBackgroundColour(DrawStyle::YELLOW);
104 boxYellow.setPosition(165 +2*110, sl.getY2()+8);
105 boxYellow.setSize(18, 16);
108 textYellow.setPosition(boxYellow.getX2(), sl.getY2()+4);
109 textYellow.setSize(116, 30);
112 boxBlue.setBackgroundColour(DrawStyle::BLUE);
113 boxBlue.setPosition(165 +3*110, sl.getY2()+8);
114 boxBlue.setSize(18, 16);
117 textBlue.setPosition(boxBlue.getX2(), sl.getY2()+4);
118 textBlue.setSize(116, 30);
124 updateEpgDataChannel();
127 VEpgListAdvanced::~VEpgListAdvanced()
133 void VEpgListAdvanced::setButtonText()
138 textRed.setText(tr("Record"));
139 textGreen.setText(tr("Now"));
140 textYellow.setText(tr("Next"));
141 textBlue.setText(tr("Guide"));
145 textRed.setText(tr("Record"));
146 textGreen.setText(tr("Next"));
147 textYellow.setText(tr("Schedule"));
148 textBlue.setText(tr("Switch"));
151 textRed.setText(tr("Record"));
152 textGreen.setText(tr("Now"));
153 textYellow.setText(tr("Schedule"));
154 textBlue.setText(tr("Switch"));
160 void VEpgListAdvanced::doRed()
165 void VEpgListAdvanced::doGreen()
179 void VEpgListAdvanced::doYellow()
193 void VEpgListAdvanced::doBlue()
207 void VEpgListAdvanced::doNext()
209 Log::getInstance()->log("VEventListAdvanced", Log::DEBUG, "doNext");
210 if (mode!=OneChannel) {
211 Channel * chan=(*chanList)[ sl.getCurrentOptionData()];
212 channelNumber = chan->number;
215 updateEpgDataNowNext(true);
217 TVMediaInfo *info= new TVMediaInfo();
218 info->setStaticArtwork(sa_tv);
219 setTitleBarIcon(info);
221 boxstack->update(this);
223 void VEpgListAdvanced::doNow()
225 Log::getInstance()->log("VEventListAdvanced", Log::DEBUG, "doNow");
226 if (mode!=OneChannel) {
227 Channel * chan=(*chanList)[ sl.getCurrentOptionData()];
228 channelNumber = chan->number;
231 updateEpgDataNowNext(true);
233 TVMediaInfo *info= new TVMediaInfo();
234 info->setStaticArtwork(sa_tv);
235 setTitleBarIcon(info);
237 boxstack->update(this);
240 void VEpgListAdvanced::doProgramm()
242 Log::getInstance()->log("VEventListAdvanced", Log::DEBUG, "doProgram");
245 Channel * chan=(*chanList)[ sl.getCurrentOptionData()];
246 channelNumber = chan->number;
247 updateEpgDataChannel();
249 TVMediaInfo *info= new TVMediaInfo();
250 info->setChannelLogo(channelNumber);
251 setTitleBarIcon(info);
253 boxstack->update(this);
256 void VEpgListAdvanced::doSwitch()
261 if (mode!=OneChannel) {
262 Channel * chan=(*chanList)[ sl.getCurrentOptionData()];
263 channelNumber = chan->number;
265 Log::getInstance()->log("VEventListAdvanced", Log::DEBUG, "doSwitch %d", channelNumber);
266 Message* m = new Message(); // Must be done after this view deleted
269 m->message = Message::CHANNEL_CHANGE;
270 m->parameter = channelNumber;
272 Command::getInstance()->postMessageNoLock(m);
276 void VEpgListAdvanced::doRecord()
279 Event* current = getCurrentOptionEvent(channel);
282 Log::getInstance()->log("VEventListAdvanced", Log::DEBUG, "Found the option you pointed at. %s %d", current->title, current->id);
283 unsigned int chanlistsize=chanList->size();
286 for(listIndex = 0; listIndex < chanlistsize; listIndex++)
288 chan = (*chanList)[listIndex];
289 if (chan->number == channel) break;
292 Log::getInstance()->log("VEpgSummary", Log::DEBUG, "ID %lu TIME %lu DURATION %lu TITLE %s", current->id, current->time,
293 current->duration, current->title);
294 VEpgSetTimer* vs = new VEpgSetTimer(current, chan);
297 boxstack->update(vs);
302 void VEpgListAdvanced::doGrid()
305 if (mode!=OneChannel) {
306 Channel * chan=(*chanList)[ sl.getCurrentOptionData()];
307 channelNumber = chan->number;
310 unsigned int chanlistsize=chanList->size();
312 for(listIndex = 0; listIndex < chanlistsize; listIndex++)
314 chan = (*chanList)[listIndex];
315 if (chan->number == channelNumber) break;
318 VEpg* vepg = new VEpg(videolive, listIndex, chanList);
321 boxstack->update(vepg);
325 void VEpgListAdvanced::clearEventList()
327 std::vector<EventList*>::iterator itty = eventLista.begin();
328 while (itty!= eventLista.end()) {
342 * if (!chanList) return;
344 for(UINT listIndex = 0; listIndex < gridRows; listIndex++)
346 if(listTop + listIndex >= UINT(chanListbox.getBottomOption()))
348 chan = (*chanList)[listTop + listIndex];
349 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
354 void VEpgListAdvanced::updateEpgData()
359 //updateEpgDataChannel();
363 updateEpgDataNowNext(false);
369 void VEpgListAdvanced::updateEpgDataNowNext(bool changeState)
374 unsigned int chanlistsize=chanList->size();
377 eventLista.resize(chanList->size());
379 for(UINT listIndex = 0; listIndex < chanlistsize; listIndex++)
381 if (listIndex < 0) continue;
382 if (listIndex >= chanlistsize) continue;
383 chan = (*chanList)[listIndex];
384 if (chan->number == channelNumber) {
385 startupdate = listIndex-sl.getNumOptionsDisplayable()-2;
386 endupdate = listIndex+sl.getNumOptionsDisplayable()+2;
391 startupdate=sl.getTopOption()-2;
392 endupdate=sl.getBottomOption()+1;
399 for(int listIndex = startupdate; listIndex < endupdate; listIndex++)
401 if (listIndex < 0) continue;
402 if (listIndex >= chanlistsize) continue;
404 chan = (*chanList)[listIndex];
405 if (!eventLista[listIndex]) eventLista[listIndex] = VDR::getInstance()->getChannelSchedule(chan->number, now, 4 * 60 *60);
411 void VEpgListAdvanced::updateEpgDataChannel()
414 eventLista.resize(1);
417 eventLista[0] = VDR::getInstance()->getChannelSchedule(channelNumber, now, 24 * 60 *60 *30); // one month
418 Log::getInstance()->log("VEventListAdvanced", Log::DEBUG, "Eventlist %x %d", eventLista[0],channelNumber);
422 void VEpgListAdvanced::drawData(bool doIndexPop)
427 drawDataChannel(doIndexPop);
430 drawDataNowNext(true, doIndexPop);
433 drawDataNowNext(false, doIndexPop);
439 void VEpgListAdvanced::drawDataChannel(bool doIndexPop)
441 int saveIndex = sl.getCurrentOption();
442 int saveTop = sl.getTopOption();
446 sl.addColumn(25 + 7);
447 sl.addColumn(25 + 7+ 7);
452 char tempA[300]; // FIXME this is guesswork!
453 char tempB[300]; // FIXME
454 char tempC[300]; // FIXME
460 EventList::iterator j;
461 EventList* eventList = eventLista[0];
463 for (j = eventList->begin(); j != eventList->end(); j++)
466 time_t eventStartTime = (time_t)currentEvent->time;
467 time_t eventEndTime = (time_t)(currentEvent->time + currentEvent->duration);
469 btime = localtime(&eventStartTime);
470 strftime(tempA, 299, "%d/%m/%y %H:%M ", btime);
471 btime = localtime(&eventEndTime);
472 strftime(tempB, 299, "- %H:%M ", btime);
474 sprintf(tempC, "\t %s\n \t \t%s%s", currentEvent->title,tempA,tempB);
476 TVMediaInfo *info= new TVMediaInfo();
477 info->setPosterThumb(channelNumber, currentEvent->id);
478 currentEvent->index = sl.addOption(tempC, currentEvent->id, first, info);
485 sl.hintSetCurrent(0);
489 sl.hintSetCurrent(saveIndex);
490 sl.hintSetTop(saveTop);
497 void VEpgListAdvanced::drawDataNowNext(bool next, bool doIndexPop)
499 int saveIndex = sl.getCurrentOption();
500 int saveTop = sl.getTopOption();
508 char tempA[300]; // FIXME this is guesswork!
509 char tempB[300]; // FIXME
510 char tempC[300]; // FIXME
516 EventList::iterator j;
518 if (next) minevents++;
519 int setcurrenthelper =0;
521 unsigned int chanlistsize=chanList->size();
522 for(UINT listIndex = 0; listIndex < chanlistsize; listIndex++)
525 chan = (*chanList)[listIndex];
527 EventList* eventList = eventLista[listIndex];
528 if (eventList && eventList->size()>=minevents) {
529 j = eventList->begin();
531 currentEvent = j[minevents-1];
532 time_t eventStartTime = (time_t)currentEvent->time;
533 time_t eventEndTime = (time_t)(currentEvent->time + currentEvent->duration);
535 btime = localtime(&eventStartTime);
536 strftime(tempA, 299, "%H:%M ", btime);
537 btime = localtime(&eventEndTime);
538 strftime(tempB, 299, "- %H:%M ", btime);
540 sprintf(tempC, "%s\n%s\t %s%s", currentEvent->title, chan->name,tempA,tempB);
543 sprintf(tempC, "\n%s", chan->name);
546 TVMediaInfo *info= new TVMediaInfo();
547 if ((*chanList)[listIndex]->number == channelNumber) {
549 setcurrenthelper = listIndex;
551 info->setChannelLogo((*chanList)[listIndex]->number);
552 currentEvent->index = sl.addOption(tempC, listIndex, first, info);
558 sl.hintSetCurrent(setcurrenthelper);
562 sl.hintSetCurrent(saveIndex);
563 sl.hintSetTop(saveTop);
570 void VEpgListAdvanced::draw(bool doIndexPop)
573 // Single channel mode
577 unsigned int chanlistsize=chanList->size();
580 for(listIndex = 0; listIndex < chanlistsize; listIndex++)
582 chan = (*chanList)[listIndex];
583 if (chan->number == channelNumber) break;
585 sprintf(tempA, tr("Schedule - %s"), (*chanList)[listIndex]->name);
589 setTitleText(tr("Now"));
592 setTitleText(tr("Next"));
611 btime = localtime(&now);
612 strftime(freeSpace, 299, "%d/%m/%y", btime);
614 drawTextRJ(freeSpace, getWidth(), 5, DrawStyle::LIGHTTEXT);
620 w.nextSymbol = WSymbol::UP;
621 w.setPosition(20, area.h-35);
623 w.nextSymbol = WSymbol::DOWN;
624 w.setPosition(50, area.h-35);
626 w.nextSymbol = WSymbol::SKIPBACK;
627 w.setPosition(85, area.h-35);
629 w.nextSymbol = WSymbol::SKIPFORWARD;
630 w.setPosition(115, area.h-35);
633 drawTextRJ(tr("[ok] = info"), 560+70, 385+80, DrawStyle::LIGHTTEXT);
635 // All static stuff done
636 drawData(doIndexPop);
640 Event* VEpgListAdvanced::getCurrentOptionEvent(int& channel)
642 // version for channel
643 Event* currentEvent = NULL;
644 EventList::iterator j;
645 EventList* eventList = NULL;
649 eventList = eventLista[0];
651 channel = channelNumber;
652 for (j = eventList->begin(); j != eventList->end(); j++)
655 if (currentEvent->index == sl.getCurrentOption()) return currentEvent;
661 eventList = eventLista[sl.getCurrentOptionData()];
662 channel = (*chanList)[sl.getCurrentOptionData()]->number;
665 if (eventList && eventList->size()>1) {
666 j = eventList->begin();
673 eventList = eventLista[sl.getCurrentOptionData()];
674 channel = (*chanList)[sl.getCurrentOptionData()]->number;
676 if (eventList && eventList->size()>0) {
677 j = eventList->begin();
692 void VEpgListAdvanced::updateSelection()
696 if (mode==OneChannel) {
697 TVMediaInfo *info= new TVMediaInfo();
698 info->setChannelLogo(channelNumber);
699 setTitleBarIcon(info);
701 Event* toShow = getCurrentOptionEvent(channel);
704 toShow->loadinfos(channel);
705 std::stringstream description;
707 description << "\n"<< toShow->title << "\n\n";
708 description << toShow->subtitle <<"\n";
709 description << toShow->description;
713 if (toShow->movieInfo) {
714 poster=toShow->movieInfo->poster;
716 if (toShow->seriesInfo) {
717 if (toShow->seriesInfo->seasonposter.height) {
718 poster=toShow->seriesInfo->seasonposter;
720 else if (toShow->seriesInfo->posters.size()) {
721 poster=toShow->seriesInfo->posters[0];
725 epgTVmedia.setTVMedia(poster.info, WTVMedia::ZoomHorizontal);
726 epgTVmedia.setVisible(true);
728 if (toShow->epgImage)
731 info.setPosterThumb(channel,toShow->id);
732 epgTVmedia.setTVMedia(info, WTVMedia::ZoomHorizontal);
733 epgTVmedia.setVisible(true);
734 }else if (mode!=OneChannel) {
736 info.setChannelLogo(channel);
737 epgTVmedia.setTVMedia(info, WTVMedia::ZoomHorizontal);
738 epgTVmedia.setVisible(true);
740 epgTVmedia.setVisible(false);
744 epg.setText(description.str().c_str());
747 if (mode!=OneChannel) {
749 info.setChannelLogo(channel);
750 epgTVmedia.setTVMedia(info, WTVMedia::ZoomHorizontal);
751 epgTVmedia.setVisible(true);
753 epgTVmedia.setVisible(false);
759 int VEpgListAdvanced::handleCommand(int command)
769 boxstack->update(this);
772 case Remote::DF_DOWN:
778 boxstack->update(this);
781 case Remote::SKIPBACK:
786 boxstack->update(this);
789 case Remote::SKIPFORWARD:
794 boxstack->update(this);
819 if (sl.getNumOptions() == 0) return 2;
823 Event* current = getCurrentOptionEvent(channel);
826 Log::getInstance()->log("VEventListAdvanced", Log::DEBUG, "Found the option you pointed at. %s %d", current->title, current->id);
827 unsigned int chanlistsize=chanList->size();
830 for(listIndex = 0; listIndex < chanlistsize; listIndex++)
832 chan = (*chanList)[listIndex];
833 if (chan->number == channel) break;
836 VEpgSummary* vr = new VEpgSummary(current, (*chanList)[listIndex]);
839 boxstack->update(vr);
843 // should not get to here
851 // stop command getting to any more views
855 void VEpgListAdvanced::processMessage(Message* m)
857 Log::getInstance()->log("VEpgListAdvanced", Log::DEBUG, "Got message value %lu", m->message);
859 if (m->message == Message::MOUSE_MOVE)
861 if (sl.mouseMove((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY()))
864 boxstack->update(this);
867 else if (m->message == Message::MOUSE_LBDOWN)
869 if (sl.mouseLBDOWN((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY()))
871 boxstack->handleCommand(Remote::OK); //simulate OK press
875 //check if press is outside this view! then simulate cancel
876 int x=(m->parameter>>16)-getScreenX();
877 int y=(m->parameter&0xFFFF)-getScreenY();
878 if (x<0 || y <0 || x>(int)getWidth() || y>(int)getHeight())
880 boxstack->handleCommand(Remote::BACK); //simulate cancel press
888 void VEpgListAdvanced::quickUpdate() { //only quick for plattform that need it!
890 #ifdef GRADIENT_DRAWING