]> git.vomp.tv Git - vompclient.git/blob - vrecordinglist.cc
Fix VRecording showing graphic at bottom left when it shouldn't
[vompclient.git] / vrecordinglist.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, see <https://www.gnu.org/licenses/>.
18 */
19
20 #include "vrecordinglist.h"
21
22 #include "log.h"
23 #include "recman.h"
24 #include "directory.h"
25 #include "recording.h"
26 #include "input.h"
27 #include "wsymbol.h"
28 #include "boxstack.h"
29 #include "vrecordingmenu.h"
30 #include "vrecording.h"
31 #include "vdr.h"
32 #include "vvideorec.h"
33 #include "vradiorec.h"
34 #include "colour.h"
35 #include "video.h"
36 #include "i18n.h"
37 #include "control.h"
38 #include "vinfo.h"
39
40 static const char* TAG = "VRecordingList";
41
42 VRecordingList::VRecordingList()
43 {
44   boxstack = BoxStack::getInstance();
45   recman = NULL;
46   loading = true;
47   MessageQueue::getInstance()->addReceiver(this);
48 }
49
50 VRecordingList::~VRecordingList()
51 {
52   MessageQueue::getInstance()->removeReceiver(this);
53   delete recman;
54 }
55
56 void VRecordingList::processMessage(Message* m)
57 {
58   LogNT::getInstance()->debug(TAG, "Got message value {}", m->message);
59
60   if (m->message == Message::MOUSE_MOVE)
61   {
62     if (sl.mouseMove(m->parameter - getScreenX(), m->tag - getScreenY()))
63     {
64       quickUpdate();
65       boxstack->update(this);
66     }
67   }
68   else if (m->message == Message::MOUSE_LBDOWN)
69   {
70     if (sl.mouseLBDOWN(m->parameter - getScreenX(), m->tag - getScreenY()))
71     {
72       Input::sendInputKey(Input::OK);
73     }
74     else if (coordsOutsideBox(m))
75     {
76       Input::sendInputKey(Input::BACK);
77     }
78   }
79   else if (m->message == Message::DELETE_SELECTED_RECORDING)
80   {
81     LogNT::getInstance()->debug(TAG, "Doing delete selected");
82     doDeleteSelected();
83   }
84   else if (m->message == Message::MOVE_RECORDING)
85   {
86     LogNT::getInstance()->debug(TAG, "Doing move recording");
87     doMoveRecording(reinterpret_cast<Directory*>(m->parameter));
88   }
89   else if (m->message == Message::PLAY_SELECTED_RECORDING)
90   {
91     doPlay(false);
92   }
93   else if (m->message == Message::RESUME_SELECTED_RECORDING)
94   {
95     doPlay(true);
96   }
97   else if (m->message == Message::REDRAW)
98   {
99     draw();
100     BoxStack::getInstance()->update(this);
101   }
102 }
103
104 void VRecordingList::doDeleteSelected()
105 {
106   Recording* toDelete = getCurrentOptionRecording();
107
108   if (!toDelete) return;
109
110   LogNT::getInstance()->debug(TAG, "FOUND: {} {} {}", toDelete->index, toDelete->getProgName(), toDelete->getFileName());
111
112   int success = recman->deleteRecording(toDelete);
113   if (!VDR::getInstance()->isConnected())
114   {
115     Control::getInstance()->connectionLost();
116     return;
117   }
118
119   if (success != 1)
120   {
121     VInfo* vi = new VInfo();
122     vi->setSize(360, 200);
123     vi->createBuffer();
124     if (Video::getInstance()->getFormat() == Video::PAL)
125       vi->setPosition(190, 170);
126     else
127       vi->setPosition(180, 120);
128     vi->setOneLiner(tr("Failed to delete recording"));
129     vi->setExitable();
130     vi->setBorderOn(1);
131     vi->setTitleBarColour(DrawStyle::DANGER);
132     vi->okButton();
133     vi->draw();
134     boxstack->add(vi);
135     boxstack->update(vi);
136   }
137   else
138   {
139     draw();
140     boxstack->update(this);
141   }
142
143 }
144
145 void VRecordingList::doMoveRecording(Directory* toDir)
146 {
147   Recording* toMove = getCurrentOptionRecording();
148   if (!toMove || !toDir) return;
149
150   LogNT::getInstance()->debug(TAG, "MOVE: {} {}", toMove->getProgName(), toDir->name);
151
152   int success = recman->moveRecording(toMove, toDir);
153   if (!VDR::getInstance()->isConnected())
154   {
155     Control::getInstance()->connectionLost();
156     return;
157   }
158
159   if (success != 1)
160   {
161     VInfo* vi = new VInfo();
162     vi->setSize(360, 200);
163     vi->createBuffer();
164     if (Video::getInstance()->getFormat() == Video::PAL)
165       vi->setPosition(190, 170);
166     else
167       vi->setPosition(180, 120);
168     vi->setOneLiner(tr("Failed to move recording"));
169     vi->setExitable();
170     vi->setBorderOn(1);
171     vi->setTitleBarColour(DrawStyle::DANGER);
172     vi->okButton();
173     vi->draw();
174     boxstack->add(vi);
175     boxstack->update(vi);
176   }
177   else
178   {
179     draw();
180     boxstack->update(this);
181   }
182 }
183
184 int VRecordingList::doPlay(bool resume)
185 {
186   Recording* toPlay = getCurrentOptionRecording();
187
188   if (toPlay)
189   {
190     toPlay->loadRecInfo();
191
192     if (toPlay->recInfo == NULL)
193     {
194       VInfo* vi = new VInfo();
195       vi->setSize(360, 200);
196       vi->createBuffer();
197       if (Video::getInstance()->getFormat() == Video::PAL)
198         vi->setPosition(190, 170);
199       else
200         vi->setPosition(180, 120);
201       vi->setOneLiner(tr("Error playing recording"));
202       vi->setExitable();
203       vi->setBorderOn(1);
204       vi->setTitleBarColour(DrawStyle::DANGER);
205       vi->okButton();
206       vi->draw();
207       boxstack->add(vi);
208       boxstack->update(vi);
209       return 0;
210     }
211
212     toPlay->loadMarks();
213     bool ish264;
214     bool isRadio = toPlay->isRadio(ish264);
215
216     if (isRadio)
217     {
218       VRadioRec* radrec = new VRadioRec(toPlay);
219       radrec->draw();
220       boxstack->add(radrec);
221       boxstack->update(radrec);
222       radrec->go(resume);
223       
224       toPlay->setNew(false);
225       draw();
226       boxstack->update(this);
227     }
228     else
229     {
230       if (ish264 && !Video::getInstance()->supportsh264())
231       {
232         VInfo* vi = new VInfo();
233         vi->setSize(360, 200);
234         vi->createBuffer();
235         if (Video::getInstance()->getFormat() == Video::PAL)
236           vi->setPosition(190, 170);
237         else
238           vi->setPosition(180, 120);
239         vi->setOneLiner(tr("H264 video not supported"));
240         vi->setExitable();
241         vi->setBorderOn(1);
242         vi->setTitleBarColour(DrawStyle::DANGER);
243         vi->okButton();
244         vi->draw();
245         boxstack->add(vi);
246         boxstack->update(vi);
247       }
248       else if (!ish264 && !Video::getInstance()->supportsmpeg2())
249       {
250         VInfo* vi = new VInfo();
251         vi->setSize(360, 200);
252         vi->createBuffer();
253         if (Video::getInstance()->getFormat() == Video::PAL)
254           vi->setPosition(190, 170);
255         else
256           vi->setPosition(180, 120);
257         vi->setOneLiner(tr("Mpeg2 video not supported"));
258         vi->setExitable();
259         vi->setBorderOn(1);
260         vi->setTitleBarColour(DrawStyle::DANGER);
261         vi->okButton();
262         vi->draw();
263         boxstack->add(vi);
264         boxstack->update(vi);
265       }
266       else
267       {
268         VVideoRec* vidrec = new VVideoRec(toPlay, ish264);
269         vidrec->draw();
270         boxstack->add(vidrec);
271         boxstack->update(vidrec);
272         vidrec->go(resume);
273
274         toPlay->setNew(false);
275         draw();
276         boxstack->update(this);
277       }
278     }
279     return 1;
280   }
281   // should not get to here
282   return 0;
283 }
284
285 Recording* VRecordingList::getCurrentOptionRecording()
286 {
287   Recording* currentRec;
288   RecordingList::iterator j;
289   RecordingList* recList = recman->getRecordings();
290   for (j = recList->begin(); j != recList->end(); j++)
291   {
292     currentRec = *j;
293     if (currentRec->index == sl.getCurrentOption()) return currentRec;
294   }
295
296   return NULL;
297 }
298
299 Directory* VRecordingList::getCurrentOptionDirectory()
300 {
301         Directory* currentSubDir;
302         DirectoryList::iterator i;
303         DirectoryList* dirList = recman->getDirectories();
304         for (i = dirList->begin(); i != dirList->end(); i++)
305         {
306                 currentSubDir = *i;
307                 if (currentSubDir->index == sl.getCurrentOption())
308                 {
309
310                         return currentSubDir;
311                 }
312         }
313
314         return NULL;
315 }
316
317 int VRecordingList::handleCommand(int command)
318 {
319   switch(command)
320   {
321     case Input::UP:
322     {
323       sl.up();
324       quickUpdate();
325
326       boxstack->update(this);
327       return BoxStack::COMMAND_HANDLED;
328     }
329     case Input::DOWN:
330     {
331       sl.down();
332       quickUpdate();
333
334       boxstack->update(this);
335       return BoxStack::COMMAND_HANDLED;
336     }
337     case Input::SKIPBACK:
338     {
339       sl.pageUp();
340       quickUpdate();
341
342       boxstack->update(this);
343       return BoxStack::COMMAND_HANDLED;
344     }
345     case Input::SKIPFORWARD:
346     {
347       sl.pageDown();
348       quickUpdate();
349
350       boxstack->update(this);
351       return BoxStack::COMMAND_HANDLED;
352     }
353     case Input::OK:
354     {
355       if (sl.getNumOptions() == 0) return BoxStack::COMMAND_HANDLED;
356
357       // Check to see if it is a sub directory
358       Directory* currentSubDir=getCurrentOptionDirectory();
359
360       if (currentSubDir)
361       {
362           if (recman->down(currentSubDir))
363           {
364                   slIndexStack.push(sl.getCurrentOption());
365                   sl.clear();
366                   draw();
367                   boxstack->update(this);
368           }
369           return BoxStack::COMMAND_HANDLED;
370       }
371
372
373       // check to see if it's a recording
374       Recording* current = getCurrentOptionRecording();
375       if (current)
376       {
377         LogNT::getInstance()->debug(TAG, "Found the option you pointed at. {} {}", current->getProgName(), current->getFileName());
378
379 /*
380         VRecordingMenu* v = new VRecordingMenu(recman);
381         v->setParent(this);
382         v->setRecording(current);
383         v->draw();
384         boxstack->add(v);
385         boxstack->update(v);
386 */        
387         VRecording* vr = new VRecording(recman, current);
388         vr->setParent(this);
389         vr->draw();
390         boxstack->add(vr);
391         boxstack->update(vr);
392         
393         return BoxStack::COMMAND_HANDLED;
394       }
395       // should not get to here
396       return BoxStack::ABANDON_COMMAND;
397     }
398     case Input::BACK:
399     {
400       if (recman->isSubDir())
401       {
402         recman->up();
403         sl.clear();
404         draw(true);
405         boxstack->update(this);
406         return BoxStack::COMMAND_HANDLED;
407       }
408       else
409       {
410         return BoxStack::DELETE_ME;
411       }
412     }
413     case Input::PLAYPAUSE:
414     case Input::PLAY:
415     {
416       if (doPlay(true)) return BoxStack::COMMAND_HANDLED;
417       return BoxStack::ABANDON_COMMAND;
418     }
419     case Input::LEFT:
420     case Input::RIGHT:
421     case Input::ZERO:
422     {
423       reSort();
424       return BoxStack::COMMAND_HANDLED;
425     }
426   }
427   // stop command getting to any more views
428   return BoxStack::ABANDON_COMMAND;
429 }
430
431 bool VRecordingList::load()
432 {
433   VDR* vdr = VDR::getInstance();
434
435   recman = new RecMan();
436
437   bool success = vdr->getRecordingsList(recman);
438
439   if (success)
440   {
441     loading = false;
442     char* defaultSortOrder = vdr->configLoad("General", "Recordings Sort Order");
443     if (defaultSortOrder)
444     {
445       if (!STRCASECMP(defaultSortOrder, "Chronological")) recman->setSortOrderChron();
446       delete[] defaultSortOrder;
447     }
448     recman->sort();
449     draw();
450     boxstack->update(this);
451   }
452
453   return success;
454 }
455
456 void VRecordingList::reSort()
457 {
458   recman->toggleSortOrder();
459   recman->sort();
460   sl.clear();
461   draw();
462   boxstack->update(this);
463 }
464