]> git.vomp.tv Git - vompclient.git/blob - vrecording.cc
Display channel name, duration, resume point and size on recording info screen
[vompclient.git] / vrecording.cc
1 /*
2     Copyright 2004-2019 Chris Tallon
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 "vrecording.h"
22
23 #include "remote.h"
24 #include "recinfo.h"
25 #include "vquestion.h"
26 #include "vinfo.h"
27 #include "vdr.h"
28 #include "colour.h"
29 #include "video.h"
30 #include "i18n.h"
31 #include "command.h"
32 #include "vrecmove.h"
33 #include "boxstack.h"
34 #include "recman.h"
35 #include "vrecordinglist.h"
36 #include "recording.h"
37 #include "message.h"
38 #include "log.h"
39 #include "wmovieview.h"
40 #include "wseriesview.h"
41 #include "wpictureview.h"
42
43 VRecording::VRecording(RecMan* trecman, Recording* trec)
44 {
45   rec = trec;
46   recman = trecman;
47   buttons = true;
48   selected = RESUME;
49   
50   Log::getInstance()->log("VRecording", Log::DEBUG, "%s", rec->getProgName());
51   rec->loadRecInfo();
52   Log::getInstance()->log("VRecording", Log::DEBUG, "%s", rec->getProgName());
53
54
55   if (Video::getInstance()->getFormat() == Video::PAL)
56   {
57     setSize(640, 500);
58         createBuffer();
59   }
60   else
61   {
62         setSize(560, 400);
63         createBuffer();
64   }
65   setPosition(40, 40);
66
67   setTitleBarOn(1);
68   setBorderOn(1);
69   if (rec->recInfo && strlen(rec->recInfo->title))
70           setTitleText(rec->recInfo->title);
71   else
72           setTitleText(rec->getProgName());
73   setTitleBarColour(DrawStyle::TITLEBARBACKGROUND);
74
75   tabbar.setPosition(10+130+10, 30 + 5);
76   tabbar.setSize(area.w - 20-10-130, area.h - 30 - 10);
77   add(&tabbar);
78
79
80
81
82   WTextbox * summary=new WTextbox();
83   summary->setParaMode(true);
84
85   if (rec->recInfo)
86     summary->setText(rec->recInfo->buildSummaryWithDetails());
87   else
88     summary->setText(tr("Summary unavailable"));
89
90   OsdVector *osdv=dynamic_cast<OsdVector*>(Osd::getInstance());
91
92   tabbar.addTab(tr("EPG"), summary);
93   if (rec->movieInfo) {
94           WMovieView *movieview = new WMovieView(rec->movieInfo);
95           movieview->setParaMode(true);
96           tabbar.addTab(tr("TheTVDB Info"), movieview);
97           if (osdv) {
98                   if (rec->movieInfo->actors.size() > 0 && osdv)
99                   {
100                           WActorGallery *gallery= new WActorGallery(rec->movieInfo->actors);
101                           tabbar.addTab(tr("Cast"),gallery);
102                   }
103                   WArtworkGallery *artgallery= new WArtworkGallery(*rec->movieInfo);
104                   tabbar.addTab(tr("Gallery"),artgallery);
105           }
106   } else if (rec->seriesInfo) {
107           WSeriesView *seriesview = new WSeriesView(rec->seriesInfo);
108           seriesview->setParaMode(true);
109           tabbar.addTab(tr("TheTVDB Info"), seriesview);
110           if (osdv) {
111                   if (rec->seriesInfo->actors.size() > 0 && osdv)
112                   {
113                           WActorGallery *gallery= new WActorGallery(rec->seriesInfo->actors);
114                           tabbar.addTab(tr("Cast"),gallery);
115                   }
116                   WArtworkGallery *artgallery= new WArtworkGallery(*rec->seriesInfo);
117                   tabbar.addTab(tr("Gallery"),artgallery);
118           }
119
120   }
121
122
123   
124   int sfh = getFontHeight();
125   buttonRegion.x = 10;
126   buttonRegion.y = 10+30;
127   buttonRegion.w = 130;
128   buttonRegion.h = sfh*2*last;
129
130   button[PLAY].setText(tr("Play"));
131   button[RESUME].setText(tr("Resume"));
132   button[MARKASNEW].setText(tr("Mark as new"));
133   button[MOVE].setText(tr("Move"));
134   button[A_DELETE].setText(tr("Delete"));
135   
136   for (int i=PLAY, ver=10+30; i<last; i++, ver+= sfh*2)
137   {
138     button[i].setPosition(10, ver);
139     button[i].setSize(130, sfh);
140     add(&button[i]);
141   }
142   
143
144   button[selected].setActive(1);
145   tabbar.activateFocus(false);
146 }
147
148 VRecording::~VRecording()
149 {
150 }
151
152 void VRecording::setParent(VRecordingList* tvRecList)
153 {
154   vRecList = tvRecList;
155 }
156
157 void VRecording::draw()
158 {
159   TBBoxx::draw();
160   OsdVector *osdv=dynamic_cast<OsdVector*>(Osd::getInstance());
161   if (osdv) {
162           TVMedia poster;
163           if (rec->movieInfo) {
164                   poster=rec->movieInfo->poster;
165           }
166           if (rec->seriesInfo) {
167                   if (rec->seriesInfo->seasonposter.height) {
168                           poster=rec->seriesInfo->seasonposter;
169                   }
170                   else
171                   if (rec->seriesInfo->posters.size()) {
172                           poster=rec->seriesInfo->posters[0];
173                   }
174           }
175           if (poster.height) {
176                  // float aspect=((float)poster.height)/((float)poster.width)/Osd::getInstance()->getPixelAspect();
177                   drawTVMedia(poster.info,buttonRegion.x,
178                                          tabbar.getY2()-3,
179                                                 buttonRegion.w,/*buttonRegion.w*aspect*/0.f,BottomLeft);
180           }
181   }
182
183 }
184
185 int VRecording::handleCommand(int command)
186 {
187         if (command==Remote::BACK) {
188                 return 4;
189         }
190         if (buttons) {
191                 switch(command)
192                 {
193                 case Remote::DF_UP:
194                 case Remote::UP:
195                 {
196                         tabbar.activateFocus(false);
197                         moveCursor(LEFT);
198                         return 2;
199                 }
200
201                 case Remote::DF_DOWN:
202                 case Remote::DOWN:
203                 {
204                         tabbar.activateFocus(false);
205                         moveCursor(RIGHT);
206                         return 2;
207                 }
208                 case Remote::LEFT:
209                 case Remote::DF_LEFT:
210                 case Remote::RIGHT:
211                 case Remote::DF_RIGHT:
212                 {
213                         buttons = false;
214                         button[selected].setActive(0);
215                         tabbar.activateFocus(true);
216                         button[selected].draw();
217                         tabbar.draw();
218                         BoxStack::getInstance()->update(this);
219                         return 2;
220                 }
221                 case Remote::OK:
222                 {
223
224                         if (selected == PLAY)
225                         {
226                                 Message* m = new Message(); // Must be done after this view deleted
227                                 m->from = this;
228                                 m->to = vRecList;
229                                 m->message = Message::PLAY_SELECTED_RECORDING;
230                                 Command::getInstance()->postMessageNoLock(m);
231                                 return 4;
232                         }
233
234                         if (selected == RESUME)
235                         {
236                                 Message* m = new Message(); // Must be done after this view deleted
237                                 m->from = this;
238                                 m->to = vRecList;
239                                 m->message = Message::RESUME_SELECTED_RECORDING;
240                                 Command::getInstance()->postMessageNoLock(m);
241                                 return 4;
242                         }
243
244                         if (selected == MARKASNEW)
245             {
246               rec->resetResume();
247               return 2;
248             }
249
250                         if (selected == MOVE)
251                         {
252                                 VRecMove* vrm = new VRecMove(recman);
253                                 vrm->setParent(this);
254                                 vrm->draw();
255                                 BoxStack::getInstance()->add(vrm);
256                                 BoxStack::getInstance()->update(vrm);
257                                 return 2;
258                         }
259
260                         if (selected == A_DELETE)
261                         {
262                                 VQuestion* v = new VQuestion(this);
263                                 v->setSize(260, 180);
264                                 v->createBuffer();
265                                 v->setTitleBarColour(DrawStyle::DANGER);
266                                 v->setTitleBarOn(1);
267                                 v->setBorderOn(1);
268                                 v->setTitleText(tr("Delete recording"));
269                                 v->setMainText(tr("Are you sure you want to delete this recording?"));
270                                 v->setDefault(VQuestion::NO);
271                                 if (Video::getInstance()->getFormat() == Video::PAL)
272                                 {
273                                         v->setPosition(230, 160);
274                                 }
275                                 else
276                                 {
277                                         v->setPosition(220, 140);
278                                 }
279
280                                 v->draw();
281                                 BoxStack::getInstance()->add(v);
282                                 BoxStack::getInstance()->update(v);
283                                 return 2;
284                         }
285                 }
286                 }
287         } else {
288                 // Pass to tabbar
289                 int retval = tabbar.handleCommand(command);
290                 if (retval == 1)
291                 {
292                         BoxStack::getInstance()->update(this);
293                         return 2;
294                 }
295                 else if (retval == 2)
296                 {
297                         // command was taken and actively ignored
298                         if (command==Remote::LEFT || command==Remote::DF_LEFT
299                                         || command==Remote::RIGHT || command==Remote::DF_RIGHT)
300                         {
301                                 buttons=true;
302                                 button[selected].setActive(1);
303                                 tabbar.activateFocus(false);
304                                 button[selected].draw();
305                                 tabbar.draw();
306                                 BoxStack::getInstance()->update(this);
307                         }
308                         return 2;
309                 }
310         }
311
312
313         // stop command getting to any more views
314         return 1;
315 }
316
317 void VRecording::moveCursor(Direction direction)
318 {
319   button[selected].setActive(0);
320   button[selected].draw();
321   if (direction == RIGHT)
322   { 
323     if (++selected == last) selected = PLAY;
324   }
325   else
326   {
327     if (--selected < 0) selected = last - 1;
328   }
329   button[selected].setActive(1);
330   button[selected].draw();
331   BoxStack::getInstance()->update(this, &buttonRegion);
332 }
333
334 void VRecording::processMessage(Message* m)
335 {
336   if (m->message == Message::MOUSE_MOVE)
337   {
338     for (int i = PLAY; i < last; i++)
339     {
340           if (button[i].mouseMove((m->parameter.num >> 16) - getScreenX(), (m->parameter.num & 0xFFFF) - getScreenY()))
341       {
342         for (int j = PLAY; j < last; j++)
343           button[j].setActive(0);
344         button[i].setActive(1);
345                 tabbar.activateFocus(false);
346                 buttons = true;
347         selected=i;
348         draw();
349         BoxStack::getInstance()->update(this);
350         break;
351       }
352     }
353         if (tabbar.mouseMove((m->parameter.num >> 16) - getScreenX(), (m->parameter.num & 0xFFFF) - getScreenY()))
354         {
355                 BoxStack::getInstance()->update(this);
356                 return;
357         }
358   }
359   else if (m->message == Message::MOUSE_SCROLL)
360   {
361           if (tabbar.mouseAndroidScroll((m->tag >> 16) - getScreenX(), (m->tag & 0xFFFF) - getScreenY(),
362                   (short)(m->parameter.num >> 16), (short) (m->parameter.num & 0xFFFF)))
363           {
364                   BoxStack::getInstance()->update(this);
365                   return;
366           }
367   }
368   else if (m->message == Message::MOUSE_LBDOWN)
369   {
370     int cancel = true;
371     for (int i = PLAY; i < last; i++)
372     {
373       if (button[i].mouseLBDOWN((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY()))
374       {
375         BoxStack::getInstance()->handleCommand(Remote::OK); //simulate OK press
376                 buttons = true;
377         cancel = false;
378         break;
379       }
380     }
381         if (cancel && tabbar.mouseLBDOWN((m->parameter.num >> 16) - getScreenX(), (m->parameter.num & 0xFFFF) - getScreenY()))
382         {
383                 buttons = false;
384                 button[selected].setActive(0);
385
386                 BoxStack::getInstance()->update(this);
387                 cancel = false;
388         }
389     if (cancel)
390     {
391       //check if press is outside this view! then simulate cancel
392       int x=(m->parameter.num>>16)-getScreenX();
393       int y=(m->parameter.num&0xFFFF)-getScreenY();
394       if (x<0 || y <0 || x>(int)getWidth() || y>(int)getHeight())
395       {
396         BoxStack::getInstance()->handleCommand(Remote::BACK); //simulate cancel press
397       }
398     }
399   }
400   else if (m->message == Message::QUESTION_YES)
401   {
402     if (selected == A_DELETE)
403     {
404       Message* m2 = new Message(); // Delete self
405       m2->from = this;
406       m2->to = BoxStack::getInstance();
407       m2->message = Message::CLOSE_ME;
408       Command::getInstance()->postMessageNoLock(m2);
409
410       m2 = new Message(); // OK. Want this to delete before this message does its job
411       m2->from = this;
412       m2->to = vRecList;
413       m2->message = Message::DELETE_SELECTED_RECORDING;
414       Command::getInstance()->postMessageNoLock(m2);
415     }
416   }
417   else if (m->message == Message::MOVE_RECORDING)
418   {
419     Message* m2 = new Message(); // Delete self
420     m2->from = this;
421     m2->to = BoxStack::getInstance();
422     m2->message = Message::CLOSE_ME;
423     Command::getInstance()->postMessageNoLock(m2);
424
425     m2 = new Message();
426     m2->from = this;
427     m2->to = vRecList;
428     m2->message = Message::MOVE_RECORDING;
429     m2->parameter.num = m->parameter.num;
430     Command::getInstance()->postMessageNoLock(m2);
431   }
432 }
433