]> git.vomp.tv Git - vompclient.git/blob - vrecordinglist.cc
*** empty log message ***
[vompclient.git] / vrecordinglist.cc
1 /*
2     Copyright 2004-2005 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 #include "vrecordinglist.h"
22
23 VRecordingList::VRecordingList()
24 {
25   viewman = ViewMan::getInstance();
26   recman = NULL;
27   loading = true;
28
29   create(570, 420);
30   if (Video::getInstance()->getFormat() == Video::PAL)
31   {
32     setScreenPos(80, 70);
33   }
34   else
35   {
36     setScreenPos(70, 35);
37   }
38
39   setBackgroundColour(Colour::VIEWBACKGROUND);
40   setTitleBarOn(1);
41   setTitleBarColour(Colour::TITLEBARBACKGROUND);
42
43   sl.setSurface(surface);
44   sl.setSurfaceOffset(10, 30 + 5);
45   sl.setDimensions(area.w - 20, area.h - 30 - 15 - 30);
46 }
47
48 VRecordingList::~VRecordingList()
49 {
50   delete recman;
51 }
52
53 void VRecordingList::drawData(bool doIndexPop)
54 {
55   int saveIndex = sl.getCurrentOption();
56   int saveTop = sl.getTopOption();
57
58   sl.clear();
59   sl.addColumn(0);
60   sl.addColumn(110);
61
62   int first = 1;
63
64   char tempA[300]; // FIXME  this is guesswork!
65   char tempB[300]; // FIXME
66   struct tm* btime;
67
68   Directory* currentSubDir;
69   DirectoryList::iterator i;
70   DirectoryList* dirList = recman->getDirectories();
71   for (i = dirList->begin(); i != dirList->end(); i++)
72   {
73     currentSubDir = *i;
74     SNPRINTF(tempA, 299, tr("<dir> %lu\t%s"), currentSubDir->getNumRecordings(), currentSubDir->name);
75     currentSubDir->index = sl.addOption(tempA, 0, first);
76     first = 0;
77   }
78
79   // FIXME convert the whole program to time_t's
80
81   Recording* currentRec;
82   RecordingList::iterator j;
83   RecordingList* recList = recman->getRecordings();
84   for (j = recList->begin(); j != recList->end(); j++)
85   {
86     currentRec = *j;
87     time_t recStartTime = (time_t)currentRec->getStartTime();
88     btime = localtime(&recStartTime);
89 #ifndef _MSC_VER
90     strftime(tempA, 299, "%0d/%0m %0H:%0M ", btime);
91 #else
92     strftime(tempA, 299, "%d/%m %H:%M ", btime);
93 #endif
94     sprintf(tempB, "%s\t%s", tempA, currentRec->getProgName());
95     currentRec->index = sl.addOption(tempB, 0, first);
96     first = 0;
97   }
98
99   if (doIndexPop)
100   {
101     sl.hintSetCurrent(slIndexStack.top());
102     slIndexStack.pop();
103   }
104   else
105   {
106     sl.hintSetCurrent(saveIndex);
107     sl.hintSetTop(saveTop);
108   }
109   sl.draw();
110   doShowingBar();
111 }
112
113 void VRecordingList::draw(bool doIndexPop)
114 {
115   if (!loading)
116   {
117     if (recman->isSubDir())
118     {
119       char title[300];
120       SNPRINTF(title, 299, tr("Recordings - %s"), recman->getCurDirName());
121       setTitleText(title);
122     }
123     else
124     {
125       setTitleText(tr("Recordings"));
126     }
127   }
128
129   View::draw();
130
131   if (loading)
132   {
133     drawText(tr("Loading..."), 240, 180, Colour::LIGHTTEXT);
134   }
135   else
136   {
137     char freeSpace[50];
138     int gigFree = recman->getFreeSpace() / 1024;
139     SNPRINTF(freeSpace, 49, tr("%lu%% used, %iGB free"), recman->getUsedPercent(), gigFree);
140     drawTextRJ(freeSpace, 560, 5, Colour::LIGHTTEXT);
141
142     // Symbols
143
144     WSymbol w;
145     w.setSurface(surface);
146
147     w.nextSymbol = WSymbol::UP;
148     w.setSurfaceOffset(20, 385);
149     w.draw();
150
151     w.nextSymbol = WSymbol::DOWN;
152     w.setSurfaceOffset(50, 385);
153     w.draw();
154
155     w.nextSymbol = WSymbol::SKIPBACK;
156     w.setSurfaceOffset(85, 385);
157     w.draw();
158
159     w.nextSymbol = WSymbol::SKIPFORWARD;
160     w.setSurfaceOffset(115, 385);
161     w.draw();
162
163     w.nextSymbol = WSymbol::PLAY;
164     w.setSurfaceOffset(150, 385);
165     w.draw();
166
167     drawTextRJ(tr("[ok] = menu"), 560, 385, Colour::LIGHTTEXT);
168
169     // All static stuff done
170
171     drawData(doIndexPop);
172   }
173 }
174
175 void VRecordingList::doShowingBar()
176 {
177   int topOption = sl.getTopOption() + 1;
178   if (sl.getNumOptions() == 0) topOption = 0;
179
180   rectangle(220, 385, 180, 25, Colour::VIEWBACKGROUND);
181   char showing[200];
182   sprintf(showing, tr("%i to %i of %i"), topOption, sl.getBottomOption(), sl.getNumOptions());
183   drawText(showing, 220, 385, Colour::LIGHTTEXT);
184 }
185
186 void VRecordingList::processMessage(Message* m)
187 {
188   Log::getInstance()->log("VRecordingList", Log::DEBUG, "Got message value %lu", m->message);
189
190   if (m->message == Message::MOUSE_MOVE)
191   {
192     if (sl.mouseMove((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY()))
193     {
194       sl.draw();
195       doShowingBar();
196       viewman->updateView(this);
197     }
198   }
199   else if (m->message == Message::MOUSE_LBDOWN)
200   {
201     if (sl.mouseLBDOWN((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY()))
202     {
203       viewman->handleCommand(Remote::OK); //simulate OK press
204     }
205     else
206     {
207       //check if press is outside this view! then simulate cancel
208       int x=(m->parameter>>16)-getScreenX();
209       int y=(m->parameter&0xFFFF)-getScreenY();
210       if (x<0 || y <0 || x>getWidth() || y>getHeight())
211       {
212         viewman->handleCommand(Remote::BACK); //simulate cancel press
213       }
214     }
215   }
216   else if (m->message == Message::DELETE_SELECTED_RECORDING)
217   {
218     Log::getInstance()->log("VRecordingList", Log::DEBUG, "Doing delete selected");
219     doDeleteSelected();
220   }
221   else if (m->message == Message::MOVE_RECORDING)
222   {
223     Log::getInstance()->log("VRecordingList", Log::DEBUG, "Doing move recording");
224     doMoveRecording((Directory*)m->parameter);
225   }
226   else if (m->message == Message::PLAY_SELECTED_RECORDING)
227   {
228     doPlay(false);
229   }
230   else if (m->message == Message::RESUME_SELECTED_RECORDING)
231   {
232     doPlay(true);
233   }
234 }
235
236 void VRecordingList::doDeleteSelected()
237 {
238   Recording* toDelete = getCurrentOptionRecording();
239
240   if (!toDelete) return;
241
242   Log::getInstance()->log("VRecordingList", Log::DEBUG, "FOUND: %i %s %s", toDelete->index, toDelete->getProgName(), toDelete->getFileName());
243
244   int success = recman->deleteRecording(toDelete);
245   if (!VDR::getInstance()->isConnected())
246   {
247     Command::getInstance()->connectionLost();
248     return;
249   }
250
251   if (success != 1)
252   {
253     VInfo* vi = new VInfo();
254     vi->create(360, 200);
255     if (Video::getInstance()->getFormat() == Video::PAL)
256       vi->setScreenPos(190, 170);
257     else
258       vi->setScreenPos(180, 120);
259     vi->setOneLiner(tr("Failed to delete recording"));
260     vi->setExitable();
261     vi->setBorderOn(1);
262     vi->setTitleBarColour(Colour::DANGER);
263     vi->okButton();
264     vi->draw();
265     viewman->add(vi);
266     viewman->updateView(vi);
267   }
268   else
269   {
270     draw();
271     viewman->updateView(this);
272   }
273
274 }
275
276 void VRecordingList::doMoveRecording(Directory* toDir)
277 {
278   Recording* toMove = getCurrentOptionRecording();
279   if (!toMove || !toDir) return;
280
281   Log::getInstance()->log("VRecordingList", Log::DEBUG, "MOVE: %s %s", toMove->getProgName(), toDir->name);
282
283   int success = recman->moveRecording(toMove, toDir);
284   if (!VDR::getInstance()->isConnected())
285   {
286     Command::getInstance()->connectionLost();
287     return;
288   }
289
290   if (success != 1)
291   {
292     VInfo* vi = new VInfo();
293     vi->create(360, 200);
294     if (Video::getInstance()->getFormat() == Video::PAL)
295       vi->setScreenPos(190, 170);
296     else
297       vi->setScreenPos(180, 120);
298     vi->setOneLiner(tr("Failed to move recording"));
299     vi->setExitable();
300     vi->setBorderOn(1);
301     vi->setTitleBarColour(Colour::DANGER);
302     vi->okButton();
303     vi->draw();
304     viewman->add(vi);
305     viewman->updateView(vi);
306   }
307   else
308   {
309     draw();
310     viewman->updateView(this);
311   }
312 }
313
314 int VRecordingList::doPlay(bool resume)
315 {
316   Recording* toPlay = getCurrentOptionRecording();
317   if (toPlay)
318   {
319     toPlay->loadRecInfo(); // check if still need this
320     toPlay->loadMarks();
321
322     bool isRadio = toPlay->isRadio();
323
324     if (isRadio)
325     {
326       VRadioRec* radrec = new VRadioRec(toPlay);
327       radrec->draw();
328       viewman->add(radrec);
329       viewman->updateView(radrec);
330       radrec->go();
331     }
332     else
333     {
334       VVideoRec* vidrec = new VVideoRec(toPlay);
335       vidrec->draw();
336       viewman->add(vidrec);
337       viewman->updateView(vidrec);
338       vidrec->go(resume);
339     }
340     return 1;
341   }
342   // should not get to here
343   return 0;
344 }
345
346 Recording* VRecordingList::getCurrentOptionRecording()
347 {
348   Recording* currentRec;
349   RecordingList::iterator j;
350   RecordingList* recList = recman->getRecordings();
351   for (j = recList->begin(); j != recList->end(); j++)
352   {
353     currentRec = *j;
354     if (currentRec->index == sl.getCurrentOption()) return currentRec;
355   }
356
357   return NULL;
358 }
359
360 int VRecordingList::handleCommand(int command)
361 {
362   switch(command)
363   {
364     case Remote::DF_UP:
365     case Remote::UP:
366     {
367       sl.up();
368       sl.draw();
369
370       doShowingBar();
371       viewman->updateView(this);
372       return 2;
373     }
374     case Remote::DF_DOWN:
375     case Remote::DOWN:
376     {
377       Log::getInstance()->log("P", Log::DEBUG, "1");
378       sl.down();
379       Log::getInstance()->log("P", Log::DEBUG, "1.5");
380       sl.draw();
381       Log::getInstance()->log("P", Log::DEBUG, "2");
382
383       doShowingBar();
384       Log::getInstance()->log("P", Log::DEBUG, "3");
385       viewman->updateView(this);
386       Log::getInstance()->log("P", Log::DEBUG, "4");
387       return 2;
388     }
389     case Remote::SKIPBACK:
390     {
391       sl.pageUp();
392       sl.draw();
393
394       doShowingBar();
395       viewman->updateView(this);
396       return 2;
397     }
398     case Remote::SKIPFORWARD:
399     {
400       sl.pageDown();
401       sl.draw();
402
403       doShowingBar();
404       viewman->updateView(this);
405       return 2;
406     }
407     case Remote::OK:
408     {
409       if (sl.getNumOptions() == 0) return 2;
410
411       // Check to see if it is a sub directory
412       Directory* currentSubDir;
413       DirectoryList::iterator i;
414       DirectoryList* dirList = recman->getDirectories();
415       for (i = dirList->begin(); i != dirList->end(); i++)
416       {
417         currentSubDir = *i;
418         if (currentSubDir->index == sl.getCurrentOption())
419         {
420           if (recman->down(currentSubDir))
421           {
422             slIndexStack.push(sl.getCurrentOption());
423             sl.clear();
424             draw();
425             viewman->updateView(this);
426           }
427           return 2;
428         }
429       }
430
431       // check to see if it's a recording
432       Recording* current = getCurrentOptionRecording();
433       if (current)
434       {
435         Log::getInstance()->log("VRecordingList", Log::DEBUG, "Found the option you pointed at. %s %s", current->getProgName(), current->getFileName());
436
437         VRecordingMenu* v = new VRecordingMenu(recman);
438         v->setParent(this);
439         v->setRecording(current);
440         v->draw();
441         viewman->add(v);
442         viewman->updateView(v);
443         return 2;
444       }
445       // should not get to here
446       return 1;
447     }
448     case Remote::BACK:
449     {
450       if (recman->isSubDir())
451       {
452         recman->up();
453         sl.clear();
454         draw(true);
455         viewman->updateView(this);
456         return 2;
457       }
458       else
459       {
460         return 4;
461       }
462     }
463     case Remote::PLAY:
464     {
465       if (doPlay(true)) return 2;
466       return 1;
467     }
468     case Remote::LEFT:
469     case Remote::RIGHT:
470     case Remote::ZERO:
471     {
472       reSort();
473       return 2;
474     }
475   }
476   // stop command getting to any more views
477   return 1;
478 }
479
480 bool VRecordingList::load()
481 {
482   VDR* vdr = VDR::getInstance();
483
484   recman = new RecMan();
485   bool success = vdr->getRecordingsList(recman);
486   if (success)
487   {
488     loading = false;
489
490     char* defaultSortOrder = vdr->configLoad("General", "Recordings Sort Order");
491     if (defaultSortOrder)
492     {
493       if (!STRCASECMP(defaultSortOrder, "Chronological")) recman->setSortOrderChron();
494       delete[] defaultSortOrder;
495     }
496
497     recman->sort();
498
499     draw();
500     viewman->updateView(this);
501   }
502
503   return success;
504 }
505
506 void VRecordingList::reSort()
507 {
508   recman->toggleSortOrder();
509   recman->sort();
510   sl.clear();
511   draw();
512   viewman->updateView(this);
513 }