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"
44 VEpgListAdvanced::VEpgListAdvanced(VVideoLiveTV *tvideolive, ChannelList* tchanList,ULONG initialChannelNumber)
46 channelNumber = initialChannelNumber;
48 videolive = tvideolive;
49 boxstack = BoxStack::getInstance();
53 setSize(640+40, 500+40); //old setSize(570, 420);
59 setTitleBarColour(DrawStyle::TITLEBARBACKGROUND);
61 sl.setPosition(10, 30 + 5);
62 sl.setSize(area.w*42/100 - 20, area.h - 30 - 15 - 30);
63 sl.setLinesPerOption(2.4f);
66 Region slarea=sl.getRegionR();
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);
73 epg.setVideoBackground();
74 epg.setBackgroundColour(DrawStyle::VIEWTRANSPARENTBACKGROUND);
76 epgTVmedia.setPosition(epg.getRegionR().w-100-10,10);
77 epgTVmedia.setSize(100,150/Osd::getInstance()->getPixelAspect());
80 boxRed.setBackgroundColour(DrawStyle::RED);
81 boxRed.setPosition(165 /*54*/, sl.getY2()+8);
82 boxRed.setSize(18, 16);
85 textRed.setPosition(boxRed.getX2(), sl.getY2()+4);
86 textRed.setSize(116, 30);
90 boxGreen.setBackgroundColour(DrawStyle::GREEN);
91 boxGreen.setPosition(165 +1*110, sl.getY2()+8);
92 boxGreen.setSize(18, 16);
95 textGreen.setPosition(boxGreen.getX2(), sl.getY2()+4);
96 textGreen.setSize(116, 30);
99 boxYellow.setBackgroundColour(DrawStyle::YELLOW);
100 boxYellow.setPosition(165 +2*110, sl.getY2()+8);
101 boxYellow.setSize(18, 16);
104 textYellow.setPosition(boxYellow.getX2(), sl.getY2()+4);
105 textYellow.setSize(116, 30);
108 boxBlue.setBackgroundColour(DrawStyle::BLUE);
109 boxBlue.setPosition(165 +3*110, sl.getY2()+8);
110 boxBlue.setSize(18, 16);
113 textBlue.setPosition(boxBlue.getX2(), sl.getY2()+4);
114 textBlue.setSize(116, 30);
120 updateEpgDataChannel();
123 VEpgListAdvanced::~VEpgListAdvanced()
129 void VEpgListAdvanced::setButtonText()
134 textRed.setText(tr("Record"));
135 textGreen.setText(tr("Now"));
136 textYellow.setText(tr("Next"));
137 textBlue.setText(tr("Guide"));
141 textRed.setText(tr("Record"));
142 textGreen.setText(tr("Next"));
143 textYellow.setText(tr("Schedule"));
144 textBlue.setText(tr("Switch"));
147 textRed.setText(tr("Record"));
148 textGreen.setText(tr("Now"));
149 textYellow.setText(tr("Schedule"));
150 textBlue.setText(tr("Switch"));
156 void VEpgListAdvanced::doRed()
161 void VEpgListAdvanced::doGreen()
175 void VEpgListAdvanced::doYellow()
189 void VEpgListAdvanced::doBlue()
203 void VEpgListAdvanced::doNext()
205 Log::getInstance()->log("VEventListAdvanced", Log::DEBUG, "doNext");
206 if (mode!=OneChannel) {
207 Channel * chan=(*chanList)[ sl.getCurrentOptionData()];
208 channelNumber = chan->number;
211 updateEpgDataNowNext(true);
214 boxstack->update(this);
216 void VEpgListAdvanced::doNow()
218 Log::getInstance()->log("VEventListAdvanced", Log::DEBUG, "doNow");
219 if (mode!=OneChannel) {
220 Channel * chan=(*chanList)[ sl.getCurrentOptionData()];
221 channelNumber = chan->number;
224 updateEpgDataNowNext(true);
227 boxstack->update(this);
230 void VEpgListAdvanced::doProgramm()
232 Log::getInstance()->log("VEventListAdvanced", Log::DEBUG, "doProgram");
235 Channel * chan=(*chanList)[ sl.getCurrentOptionData()];
236 channelNumber = chan->number;
237 updateEpgDataChannel();
240 boxstack->update(this);
243 void VEpgListAdvanced::doSwitch()
248 if (mode!=OneChannel) {
249 Channel * chan=(*chanList)[ sl.getCurrentOptionData()];
250 channelNumber = chan->number;
252 Log::getInstance()->log("VEventListAdvanced", Log::DEBUG, "doSwitch %d", channelNumber);
253 Message* m = new Message(); // Must be done after this view deleted
256 m->message = Message::CHANNEL_CHANGE;
257 m->parameter = channelNumber;
259 Command::getInstance()->postMessageNoLock(m);
263 void VEpgListAdvanced::doRecord()
266 Event* current = getCurrentOptionEvent(channel);
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();
273 for(listIndex = 0; listIndex < chanlistsize; listIndex++)
275 chan = (*chanList)[listIndex];
276 if (chan->number == channel) break;
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);
284 boxstack->update(vs);
289 void VEpgListAdvanced::doGrid()
292 if (mode!=OneChannel) {
293 Channel * chan=(*chanList)[ sl.getCurrentOptionData()];
294 channelNumber = chan->number;
297 unsigned int chanlistsize=chanList->size();
299 for(listIndex = 0; listIndex < chanlistsize; listIndex++)
301 chan = (*chanList)[listIndex];
302 if (chan->number == channelNumber) break;
305 VEpg* vepg = new VEpg(videolive, listIndex, chanList);
308 boxstack->update(vepg);
312 void VEpgListAdvanced::clearEventList()
314 std::vector<EventList*>::iterator itty = eventLista.begin();
315 while (itty!= eventLista.end()) {
329 * if (!chanList) return;
331 for(UINT listIndex = 0; listIndex < gridRows; listIndex++)
333 if(listTop + listIndex >= UINT(chanListbox.getBottomOption()))
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
341 void VEpgListAdvanced::updateEpgData()
346 //updateEpgDataChannel();
350 updateEpgDataNowNext(false);
356 void VEpgListAdvanced::updateEpgDataNowNext(bool changeState)
361 unsigned int chanlistsize=chanList->size();
364 eventLista.resize(chanList->size());
366 for(UINT listIndex = 0; listIndex < chanlistsize; listIndex++)
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;
378 startupdate=sl.getTopOption()-2;
379 endupdate=sl.getBottomOption()+1;
386 for(int listIndex = startupdate; listIndex < endupdate; listIndex++)
388 if (listIndex < 0) continue;
389 if (listIndex >= chanlistsize) continue;
391 chan = (*chanList)[listIndex];
392 if (!eventLista[listIndex]) eventLista[listIndex] = VDR::getInstance()->getChannelSchedule(chan->number, now, 4 * 60 *60);
398 void VEpgListAdvanced::updateEpgDataChannel()
401 eventLista.resize(1);
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);
409 void VEpgListAdvanced::drawData(bool doIndexPop)
414 drawDataChannel(doIndexPop);
417 drawDataNowNext(true, doIndexPop);
420 drawDataNowNext(false, doIndexPop);
426 void VEpgListAdvanced::drawDataChannel(bool doIndexPop)
428 int saveIndex = sl.getCurrentOption();
429 int saveTop = sl.getTopOption();
433 sl.addColumn(25 + 7);
434 sl.addColumn(25 + 7+ 7);
439 char tempA[300]; // FIXME this is guesswork!
440 char tempB[300]; // FIXME
441 char tempC[300]; // FIXME
447 EventList::iterator j;
448 EventList* eventList = eventLista[0];
450 for (j = eventList->begin(); j != eventList->end(); j++)
453 time_t eventStartTime = (time_t)currentEvent->time;
454 time_t eventEndTime = (time_t)(currentEvent->time + currentEvent->duration);
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);
461 sprintf(tempC, "\t %s\n \t \t%s%s", currentEvent->title,tempA,tempB);
463 TVMediaInfo *info= new TVMediaInfo();
464 info->setPosterThumb(channelNumber, currentEvent->id);
465 currentEvent->index = sl.addOption(tempC, currentEvent->id, first, info);
472 sl.hintSetCurrent(0);
476 sl.hintSetCurrent(saveIndex);
477 sl.hintSetTop(saveTop);
484 void VEpgListAdvanced::drawDataNowNext(bool next, bool doIndexPop)
486 int saveIndex = sl.getCurrentOption();
487 int saveTop = sl.getTopOption();
495 char tempA[300]; // FIXME this is guesswork!
496 char tempB[300]; // FIXME
497 char tempC[300]; // FIXME
503 EventList::iterator j;
505 if (next) minevents++;
506 int setcurrenthelper =0;
508 unsigned int chanlistsize=chanList->size();
509 for(UINT listIndex = 0; listIndex < chanlistsize; listIndex++)
512 chan = (*chanList)[listIndex];
514 EventList* eventList = eventLista[listIndex];
515 if (eventList && eventList->size()>=minevents) {
516 j = eventList->begin();
518 currentEvent = j[minevents-1];
519 time_t eventStartTime = (time_t)currentEvent->time;
520 time_t eventEndTime = (time_t)(currentEvent->time + currentEvent->duration);
522 btime = localtime(&eventStartTime);
523 strftime(tempA, 299, "%H:%M ", btime);
524 btime = localtime(&eventEndTime);
525 strftime(tempB, 299, "- %H:%M ", btime);
527 sprintf(tempC, "%s\n%s\t %s%s", currentEvent->title, chan->name,tempA,tempB);
530 sprintf(tempC, "\n%s", chan->name);
533 TVMediaInfo *info= new TVMediaInfo();
534 if ((*chanList)[listIndex]->number == channelNumber) {
536 setcurrenthelper = listIndex;
538 info->setChannelLogo((*chanList)[listIndex]->number);
539 currentEvent->index = sl.addOption(tempC, listIndex, first, info);
545 sl.hintSetCurrent(setcurrenthelper);
549 sl.hintSetCurrent(saveIndex);
550 sl.hintSetTop(saveTop);
557 void VEpgListAdvanced::draw(bool doIndexPop)
560 // Single channel mode
564 unsigned int chanlistsize=chanList->size();
567 for(listIndex = 0; listIndex < chanlistsize; listIndex++)
569 chan = (*chanList)[listIndex];
570 if (chan->number == channelNumber) break;
572 sprintf(tempA, tr("Schedule - %s"), (*chanList)[listIndex]->name);
576 setTitleText(tr("Now"));
579 setTitleText(tr("Next"));
590 info.setChannelLogo(channelNumber);
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);
604 drawTextRJ(freeSpace, getWidth(), 5, DrawStyle::LIGHTTEXT);
610 w.nextSymbol = WSymbol::UP;
611 w.setPosition(20, area.h-35);
613 w.nextSymbol = WSymbol::DOWN;
614 w.setPosition(50, area.h-35);
616 w.nextSymbol = WSymbol::SKIPBACK;
617 w.setPosition(85, area.h-35);
619 w.nextSymbol = WSymbol::SKIPFORWARD;
620 w.setPosition(115, area.h-35);
623 drawTextRJ(tr("[ok] = info"), 560+70, 385+80, DrawStyle::LIGHTTEXT);
625 // All static stuff done
626 drawData(doIndexPop);
630 Event* VEpgListAdvanced::getCurrentOptionEvent(int& channel)
632 // version for channel
633 Event* currentEvent = NULL;
634 EventList::iterator j;
635 EventList* eventList = NULL;
639 eventList = eventLista[0];
641 channel = channelNumber;
642 for (j = eventList->begin(); j != eventList->end(); j++)
645 if (currentEvent->index == sl.getCurrentOption()) return currentEvent;
651 eventList = eventLista[sl.getCurrentOptionData()];
652 channel = (*chanList)[sl.getCurrentOptionData()]->number;
655 if (eventList && eventList->size()>1) {
656 j = eventList->begin();
663 eventList = eventLista[sl.getCurrentOptionData()];
664 channel = (*chanList)[sl.getCurrentOptionData()]->number;
666 if (eventList && eventList->size()>0) {
667 j = eventList->begin();
682 void VEpgListAdvanced::updateSelection()
686 Event* toShow = getCurrentOptionEvent(channel);
689 toShow->loadinfos(channel);
690 std::stringstream description;
692 description << "\n"<< toShow->title << "\n\n";
693 description << toShow->subtitle <<"\n";
694 description << toShow->description;
698 if (toShow->movieInfo) {
699 poster=toShow->movieInfo->poster;
701 if (toShow->seriesInfo) {
702 if (toShow->seriesInfo->seasonposter.height) {
703 poster=toShow->seriesInfo->seasonposter;
705 else if (toShow->seriesInfo->posters.size()) {
706 poster=toShow->seriesInfo->posters[0];
710 epgTVmedia.setTVMedia(poster.info, WTVMedia::ZoomHorizontal);
711 epgTVmedia.setVisible(true);
713 if (toShow->epgImage)
716 info.setPosterThumb(channel,toShow->id);
717 epgTVmedia.setTVMedia(info, WTVMedia::ZoomHorizontal);
718 epgTVmedia.setVisible(true);
719 }else if (mode!=OneChannel) {
721 info.setChannelLogo(channel);
722 epgTVmedia.setTVMedia(info, WTVMedia::ZoomHorizontal);
723 epgTVmedia.setVisible(true);
725 epgTVmedia.setVisible(false);
729 epg.setText(description.str().c_str());
732 if (mode!=OneChannel) {
734 info.setChannelLogo(channel);
735 epgTVmedia.setTVMedia(info, WTVMedia::ZoomHorizontal);
736 epgTVmedia.setVisible(true);
738 epgTVmedia.setVisible(false);
744 int VEpgListAdvanced::handleCommand(int command)
754 boxstack->update(this);
757 case Remote::DF_DOWN:
763 boxstack->update(this);
766 case Remote::SKIPBACK:
771 boxstack->update(this);
774 case Remote::SKIPFORWARD:
779 boxstack->update(this);
804 if (sl.getNumOptions() == 0) return 2;
808 Event* current = getCurrentOptionEvent(channel);
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();
815 for(listIndex = 0; listIndex < chanlistsize; listIndex++)
817 chan = (*chanList)[listIndex];
818 if (chan->number == channel) break;
821 VEpgSummary* vr = new VEpgSummary(current, (*chanList)[listIndex]);
824 boxstack->update(vr);
828 // should not get to here
836 // stop command getting to any more views
840 void VEpgListAdvanced::processMessage(Message* m)
842 Log::getInstance()->log("VEpgListAdvanced", Log::DEBUG, "Got message value %lu", m->message);
844 if (m->message == Message::MOUSE_MOVE)
846 if (sl.mouseMove((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY()))
849 boxstack->update(this);
852 else if (m->message == Message::MOUSE_LBDOWN)
854 if (sl.mouseLBDOWN((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY()))
856 boxstack->handleCommand(Remote::OK); //simulate OK press
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())
865 boxstack->handleCommand(Remote::BACK); //simulate cancel press
873 void VEpgListAdvanced::quickUpdate() { //only quick for plattform that need it!
875 #ifdef GRADIENT_DRAWING