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