2 Copyright 2004-2019 Chris Tallon
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, see <https://www.gnu.org/licenses/>.
20 #include "vrecording.h"
24 #include "vquestion.h"
30 #include "messagequeue.h"
34 #include "vrecordinglist.h"
35 #include "recording.h"
38 #include "wmovieview.h"
39 #include "wseriesview.h"
40 #include "wpictureview.h"
42 VRecording::VRecording(RecMan* trecman, Recording* trec)
49 Log::getInstance()->log("VRecording", Log::DEBUG, "%s", rec->getProgName());
51 Log::getInstance()->log("VRecording", Log::DEBUG, "%s", rec->getProgName());
54 if (Video::getInstance()->getFormat() == Video::PAL)
68 if (rec->recInfo && strlen(rec->recInfo->title))
69 setTitleText(rec->recInfo->title);
71 setTitleText(rec->getProgName());
72 setTitleBarColour(DrawStyle::TITLEBARBACKGROUND);
74 tabbar.setPosition(10+130+10, 30 + 5);
75 tabbar.setSize(area.w - 20-10-130, area.h - 30 - 10);
80 epgSummaryTextBox = new WTextbox();
82 epgSummaryTextBox->setParaMode(true);
85 epgSummaryTextBox->setText(rec->recInfo->buildSummaryWithDetails());
87 epgSummaryTextBox->setText(tr("Summary unavailable"));
89 OsdVector *osdv=dynamic_cast<OsdVector*>(Osd::getInstance());
91 tabbar.addTab(tr("EPG"), epgSummaryTextBox);
93 WMovieView *movieview = new WMovieView(rec->movieInfo);
94 movieview->setParaMode(true);
95 tabbar.addTab(tr("TheTVDB Info"), movieview);
97 if (rec->movieInfo->actors.size() > 0 && osdv)
99 WActorGallery *gallery= new WActorGallery(rec->movieInfo->actors);
100 tabbar.addTab(tr("Cast"),gallery);
102 WArtworkGallery *artgallery= new WArtworkGallery(*rec->movieInfo);
103 tabbar.addTab(tr("Gallery"),artgallery);
105 } else if (rec->seriesInfo) {
106 WSeriesView *seriesview = new WSeriesView(rec->seriesInfo);
107 seriesview->setParaMode(true);
108 tabbar.addTab(tr("TheTVDB Info"), seriesview);
110 if (rec->seriesInfo->actors.size() > 0 && osdv)
112 WActorGallery *gallery= new WActorGallery(rec->seriesInfo->actors);
113 tabbar.addTab(tr("Cast"),gallery);
115 WArtworkGallery *artgallery= new WArtworkGallery(*rec->seriesInfo);
116 tabbar.addTab(tr("Gallery"),artgallery);
123 int sfh = getFontHeight();
125 buttonRegion.y = 10+30;
126 buttonRegion.w = 130;
127 buttonRegion.h = sfh*2*last;
129 button[PLAY].setText(tr("Play"));
130 button[RESUME].setText(tr("Resume"));
131 button[MARKASNEW].setText(tr("Mark as new"));
132 button[MOVE].setText(tr("Move"));
133 button[A_DELETE].setText(tr("Delete"));
135 for (int i=PLAY, ver=10+30; i<last; i++, ver+= sfh*2)
137 button[i].setPosition(10, ver);
138 button[i].setSize(130, sfh);
143 button[selected].setActive(1);
144 tabbar.activateFocus(false);
147 VRecording::~VRecording()
151 void VRecording::setParent(VRecordingList* tvRecList)
153 vRecList = tvRecList;
156 void VRecording::draw()
159 OsdVector *osdv=dynamic_cast<OsdVector*>(Osd::getInstance());
162 if (rec->movieInfo) {
163 poster=rec->movieInfo->poster;
165 if (rec->seriesInfo) {
166 if (rec->seriesInfo->seasonposter.height) {
167 poster=rec->seriesInfo->seasonposter;
170 if (rec->seriesInfo->posters.size()) {
171 poster=rec->seriesInfo->posters[0];
175 // float aspect=((float)poster.height)/((float)poster.width)/Osd::getInstance()->getPixelAspect();
176 drawTVMedia(poster.info,buttonRegion.x,
178 buttonRegion.w,/*buttonRegion.w*aspect*/0.f,BottomLeft);
184 int VRecording::handleCommand(int command)
186 if (command==Remote::BACK) {
195 tabbar.activateFocus(false);
200 case Remote::DF_DOWN:
203 tabbar.activateFocus(false);
208 case Remote::DF_LEFT:
210 case Remote::DF_RIGHT:
213 button[selected].setActive(0);
214 tabbar.activateFocus(true);
215 button[selected].draw();
217 BoxStack::getInstance()->update(this);
223 if (selected == PLAY)
225 Message* m = new Message(); // Must be done after this view deleted
228 m->message = Message::PLAY_SELECTED_RECORDING;
229 MessageQueue::getInstance()->postMessageNoLock(m);
233 if (selected == RESUME)
235 Message* m = new Message(); // Must be done after this view deleted
238 m->message = Message::RESUME_SELECTED_RECORDING;
239 MessageQueue::getInstance()->postMessageNoLock(m);
243 if (selected == MARKASNEW)
245 int ret = rec->resetResume();
247 VInfo* vi = new VInfo();
248 vi->setSize(400, 150);
252 vi->setTitleBarOn(0);
254 if (Video::getInstance()->getFormat() == Video::PAL)
255 vi->setPosition(170, 200);
257 vi->setPosition(160, 150);
259 if (ret == 1) vi->setOneLiner(tr("Success"));
260 else if (ret == 2) vi->setOneLiner(tr("No resume point exists"));
261 else if (ret == 4) vi->setOneLiner(tr("Failure deleting resume point"));
262 else if (ret == 5) vi->setOneLiner(tr("Not supported with VDR < 2.4.0"));
265 Message* m = new Message();
266 m->message = Message::ADD_VIEW;
267 m->to = BoxStack::getInstance();
268 m->parameter = (ULONG)vi;
269 MessageQueue::getInstance()->postMessageNoLock(m);
273 // Change Resume at text in summary
274 rec->recInfo->resumePoint = 0;
275 epgSummaryTextBox->setText(rec->recInfo->buildSummaryWithDetails(true));
277 BoxStack::getInstance()->update(this);
279 // Update vrecordingslist to remove the * for new
281 Message* m2 = new Message();
284 m2->message = Message::REDRAW;
285 MessageQueue::getInstance()->postMessageNoLock(m2);
291 if (selected == MOVE)
293 VRecMove* vrm = new VRecMove(recman);
294 vrm->setParent(this);
296 BoxStack::getInstance()->add(vrm);
297 BoxStack::getInstance()->update(vrm);
301 if (selected == A_DELETE)
303 VQuestion* v = new VQuestion(this);
304 v->setSize(260, 180);
306 v->setTitleBarColour(DrawStyle::DANGER);
309 v->setTitleText(tr("Delete recording"));
310 v->setMainText(tr("Are you sure you want to delete this recording?"));
311 v->setDefault(VQuestion::NO);
312 if (Video::getInstance()->getFormat() == Video::PAL)
314 v->setPosition(230, 160);
318 v->setPosition(220, 140);
322 BoxStack::getInstance()->add(v);
323 BoxStack::getInstance()->update(v);
330 int retval = tabbar.handleCommand(command);
333 BoxStack::getInstance()->update(this);
336 else if (retval == 2)
338 // command was taken and actively ignored
339 if (command==Remote::LEFT || command==Remote::DF_LEFT
340 || command==Remote::RIGHT || command==Remote::DF_RIGHT)
343 button[selected].setActive(1);
344 tabbar.activateFocus(false);
345 button[selected].draw();
347 BoxStack::getInstance()->update(this);
354 // stop command getting to any more views
358 void VRecording::moveCursor(Direction direction)
360 button[selected].setActive(0);
361 button[selected].draw();
362 if (direction == RIGHT)
364 if (++selected == last) selected = PLAY;
368 if (--selected < 0) selected = last - 1;
370 button[selected].setActive(1);
371 button[selected].draw();
372 BoxStack::getInstance()->update(this, &buttonRegion);
375 void VRecording::processMessage(Message* m)
377 if (m->message == Message::MOUSE_MOVE)
379 for (int i = PLAY; i < last; i++)
381 if (button[i].mouseMove((m->parameter >> 16) - getScreenX(), (m->parameter & 0xFFFF) - getScreenY()))
383 for (int j = PLAY; j < last; j++)
384 button[j].setActive(0);
385 button[i].setActive(1);
386 tabbar.activateFocus(false);
390 BoxStack::getInstance()->update(this);
394 if (tabbar.mouseMove((m->parameter >> 16) - getScreenX(), (m->parameter & 0xFFFF) - getScreenY()))
396 BoxStack::getInstance()->update(this);
400 else if (m->message == Message::MOUSE_SCROLL)
402 if (tabbar.mouseAndroidScroll((m->tag >> 16) - getScreenX(), (m->tag & 0xFFFF) - getScreenY(),
403 (short)(m->parameter >> 16), (short) (m->parameter & 0xFFFF)))
405 BoxStack::getInstance()->update(this);
409 else if (m->message == Message::MOUSE_LBDOWN)
412 for (int i = PLAY; i < last; i++)
414 if (button[i].mouseLBDOWN((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY()))
416 BoxStack::getInstance()->handleCommand(Remote::OK); //simulate OK press
422 if (cancel && tabbar.mouseLBDOWN((m->parameter >> 16) - getScreenX(), (m->parameter & 0xFFFF) - getScreenY()))
425 button[selected].setActive(0);
427 BoxStack::getInstance()->update(this);
432 //check if press is outside this view! then simulate cancel
433 int x=(m->parameter>>16)-getScreenX();
434 int y=(m->parameter&0xFFFF)-getScreenY();
435 if (x<0 || y <0 || x>(int)getWidth() || y>(int)getHeight())
437 BoxStack::getInstance()->handleCommand(Remote::BACK); //simulate cancel press
441 else if (m->message == Message::QUESTION_YES)
443 if (selected == A_DELETE)
445 Message* m2 = new Message(); // Delete self
447 m2->to = BoxStack::getInstance();
448 m2->message = Message::CLOSE_ME;
449 MessageQueue::getInstance()->postMessageNoLock(m2);
451 m2 = new Message(); // OK. Want this to delete before this message does its job
454 m2->message = Message::DELETE_SELECTED_RECORDING;
455 MessageQueue::getInstance()->postMessageNoLock(m2);
458 else if (m->message == Message::MOVE_RECORDING)
460 Message* m2 = new Message(); // Delete self
462 m2->to = BoxStack::getInstance();
463 m2->message = Message::CLOSE_ME;
464 MessageQueue::getInstance()->postMessageNoLock(m2);
469 m2->message = Message::MOVE_RECORDING;
470 m2->parameter = m->parameter;
471 MessageQueue::getInstance()->postMessageNoLock(m2);