]> git.vomp.tv Git - vompclient.git/blob - vrecordinglist.cc
Dongle 13, fix for 2 segfaults
[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(VRecordingList* tparent)
24 {
25   myParent = tparent;
26   dataInvalid = 0;
27
28   create(570, 420);
29   if (Video::getInstance()->getFormat() == Video::PAL)
30   {
31     setScreenPos(80, 70);
32   }
33   else
34   {
35     setScreenPos(70, 35);
36   }
37
38   setBackgroundColour(Colour::VIEWBACKGROUND);
39   setTitleBarOn(1);
40   setTitleBarColour(Colour::TITLEBARBACKGROUND);
41
42   sl.setSurface(surface);
43   sl.setSurfaceOffset(10, 30 + 5);
44   sl.setDimensions(width - 20, height - 30 - 15 - 30);
45 }
46
47 VRecordingList::~VRecordingList()
48 {
49   // if this is a child window, inform the parent of our destruct
50   if (myParent)
51   {
52     Message* m = new Message();
53     m->to = myParent;
54     m->message = Message::CHILD_CLOSE;
55     ViewMan::getInstance()->postMessage(m);
56   }
57
58   // only delete the list if this is not a sub dir window
59   if (recDir->isRoot)
60   {
61     delete recDir;
62   }
63 }
64
65 void VRecordingList::setDir(Directory* tdir)
66 {
67   recDir = tdir;
68
69   drawData();
70
71   char title[300];
72   if (!recDir->isRoot)
73   {
74     snprintf(title, 299, "Recordings - %s", recDir->name);
75     setTitleText(title);
76   }
77   else
78   {
79     setTitleText("Recordings");
80   }
81 }
82
83 void VRecordingList::drawData()
84 {
85   sl.clear();
86   sl.addColumn(0);
87   sl.addColumn(110);
88
89   int first = 1;
90
91   char tempA[300]; // FIXME  this is guesswork!
92   char tempB[300]; // FIXME
93   struct tm* btime;
94
95   Directory* dir;
96   DirectoryList::iterator i;
97
98   if (dataInvalid == 2) // special case, a child list has closed, check for 0 dir entries
99   {
100
101     // First go through to delete 1 empty dir if necessary
102
103     for (i = recDir->dirList.begin(); i != recDir->dirList.end(); i++)
104     {
105       dir = *i;
106       if (dir->getNumRecordings() == 0)
107       {
108         delete dir;
109         recDir->dirList.erase(i);
110         break;
111       }
112     }
113   }
114
115   // Then go through again to draw data. Don't merge these two loops!
116
117   for (i = recDir->dirList.begin(); i != recDir->dirList.end(); i++)
118   {
119     dir = *i;
120     snprintf(tempA, 299, "<dir> %lu\t%s", dir->getNumRecordings(), dir->name);
121     dir->index = sl.addOption(tempA, first);
122     first = 0;
123   }
124
125   // FIXME convert the whole program to time_t's
126
127
128   Recording* rec;
129   for (UINT j = 0; j < recDir->recList.size(); j++)
130   {
131     rec = recDir->recList[j];
132     btime = localtime((time_t*)&rec->start);
133     strftime(tempA, 299, "%0d/%0m %0H:%0M ", btime);
134     sprintf(tempB, "%s\t%s", tempA, rec->getProgName());
135     rec->index = sl.addOption(tempB, first);
136     first = 0;
137   }
138
139   dataInvalid = 0;
140 }
141
142 void VRecordingList::draw()
143 {
144   View::draw();
145
146   if (dataInvalid) drawData();
147
148   sl.draw();
149
150   // Put the status stuff at the bottom
151
152   WSymbol w;
153   w.setSurface(surface);
154
155   w.nextSymbol = WSymbol::UP;
156   w.setSurfaceOffset(20, 385);
157   w.draw();
158
159   w.nextSymbol = WSymbol::DOWN;
160   w.setSurfaceOffset(50, 385);
161   w.draw();
162
163   w.nextSymbol = WSymbol::SKIPBACK;
164   w.setSurfaceOffset(85, 385);
165   w.draw();
166
167   w.nextSymbol = WSymbol::SKIPFORWARD;
168   w.setSurfaceOffset(115, 385);
169   w.draw();
170
171   w.nextSymbol = WSymbol::PLAY;
172   w.setSurfaceOffset(150, 385);
173   w.draw();
174
175   // FIXME Right justify this!
176   drawText("[ok] = menu", 450, 385, Colour::LIGHTTEXT);
177
178   doShowingBar();
179
180   char freeSpace[50];
181   int gigFree = Directory::freeSpace / 1024;
182   snprintf(freeSpace, 49, "%lu%% used, %iGB free", Directory::usedPercent, gigFree);
183   drawTextRJ(freeSpace, 560, 5, Colour::LIGHTTEXT);
184 }
185
186 void VRecordingList::doShowingBar()
187 {
188   int topOption = sl.getTopOption() + 1;
189   if (sl.getNumOptions() == 0) topOption = 0;
190
191   char showing[200];
192   sprintf(showing, "%i to %i of %i", topOption, sl.getBottomOption(), sl.getNumOptions());
193
194 //  Box b;
195 //  b.setSurfaceOffset(220, 385);
196 //  b.setDimensions(160, 25);
197 //  b.fillColour(Colour::VIEWBACKGROUND);
198 //  b.drawText(showing, 0, 0, Colour::LIGHTTEXT);
199
200   rectangle(220, 385, 220+160, 385+25, Colour::VIEWBACKGROUND);
201   drawText(showing, 220, 385, Colour::LIGHTTEXT);
202 }
203
204
205
206 void VRecordingList::processMessage(Message* m)
207 {
208   Log::getInstance()->log("VRecordingList", Log::DEBUG, "Got message value %lu", m->message);
209   if (m->message == Message::DELETE_SELECTED_RECORDING)
210   {
211     Log::getInstance()->log("VRecordingList", Log::DEBUG, "Doing delete selected");
212     doDeleteSelected();
213     return;
214   }
215
216   if (m->message == Message::PLAY_SELECTED_RECORDING)
217   {
218     doPlay();
219     return;
220   }
221
222   if (m->message == Message::RESUME_SELECTED_RECORDING)
223   {
224     doResume();
225     return;
226   }
227
228   if (m->message == Message::REDRAW_DATA)
229   {
230     dataInvalid = 1;
231     draw();
232     return;
233   }
234
235   if (m->message == Message::CHILD_CLOSE)
236   {
237     dataInvalid = 2;
238     draw();
239     show();
240     return;
241   }
242 }
243
244 void VRecordingList::doDeleteSelected()
245 {
246   Recording* toDelete = getCurrentOptionRecording();
247
248   int saveIndex;
249   int saveTop;
250
251   if (toDelete)
252   {
253     saveIndex = toDelete->index;
254     saveTop = sl.getTopOption();
255     Log::getInstance()->log("VRecordingList", Log::DEBUG, "FOUND: %i %s %s", toDelete->index, toDelete->getProgName(), toDelete->fileName);
256
257     VDR* vdr = VDR::getInstance();
258     vdr->deleteRecording(toDelete->fileName);
259
260     delete toDelete;
261
262     for(RecordingList::iterator i = recDir->recList.begin(); i != recDir->recList.end(); i++)
263     {
264       if (*i == toDelete)
265       {
266         recDir->recList.erase(i);
267         break;
268       }
269     }
270
271     sl.clear();
272     setDir(recDir);
273     sl.hintSetCurrent(saveIndex);
274     sl.hintSetTop(saveTop);
275     draw();
276   }
277
278   if (myParent) // if this is not root send a message to parent to say redraw data
279   { // FIXME not really necessary any more ?
280     Message* m1 = new Message();
281     m1->to = myParent;
282     m1->message = Message::REDRAW_DATA;
283     ViewMan::getInstance()->postMessage(m1);
284   }
285
286   show();
287
288 /*
289   Message* m2 = new Message();
290   m2->from = this;
291   m2->to = ViewMan::getInstance();
292   m2->message = Message::UPDATE_SCREEN;
293   ViewMan::getInstance()->postMessage(m2);
294 */
295 }
296
297 int VRecordingList::doPlay()
298 {
299   Recording* toPlay = getCurrentOptionRecording();
300   if (toPlay)
301   {
302     VVideoRec* vidrec = new VVideoRec(toPlay);
303     ViewMan::getInstance()->addNoLock(vidrec);
304     vidrec->draw();
305     vidrec->show();
306     vidrec->go(0);
307     return 1;
308   }
309   // should not get to here
310   return 0;
311 }
312
313 int VRecordingList::doResume()
314 {
315   Recording* toResume = getCurrentOptionRecording();
316   if (toResume)
317   {
318     ULLONG position = VDR::getInstance()->getResumePoint(toResume->fileName);
319
320     VVideoRec* vidrec = new VVideoRec(toResume);
321     ViewMan::getInstance()->addNoLock(vidrec);
322     vidrec->draw();
323     vidrec->show();
324     vidrec->go(position);
325     return 1;
326   }
327   // should not get to here
328   return 0;
329 }
330
331 Recording* VRecordingList::getCurrentOptionRecording()
332 {
333   Recording* current;
334   for (UINT i = 0; i < recDir->recList.size(); i++)
335   {
336     current = recDir->recList[i];
337     if (current->index == sl.getCurrentOption()) return current;
338   }
339   return NULL;
340 }
341
342 int VRecordingList::handleCommand(int command)
343 {
344   switch(command)
345   {
346     case Remote::DF_UP:
347     case Remote::UP:
348     {
349       sl.up();
350       sl.draw();
351
352       doShowingBar();
353       show();
354       return 2;
355     }
356     case Remote::DF_DOWN:
357     case Remote::DOWN:
358     {
359       sl.down();
360       sl.draw();
361
362       doShowingBar();
363       show();
364       return 2;
365     }
366     case Remote::SKIPBACK:
367     {
368       sl.pageUp();
369       sl.draw();
370
371       doShowingBar();
372       show();
373       return 2;
374     }
375     case Remote::SKIPFORWARD:
376     {
377       sl.pageDown();
378       sl.draw();
379
380       doShowingBar();
381       show();
382       return 2;
383     }
384     case Remote::OK:
385     {
386       if (sl.getNumOptions() == 0) return 2;
387
388       // Check to see if it is a sub directory
389       Directory* curDir;
390       for(UINT i = 0; i < recDir->dirList.size(); i++)
391       {
392         curDir = recDir->dirList[i];
393         if (curDir->index == sl.getCurrentOption())
394         {
395           VRecordingList* sub = new VRecordingList(this);
396           sub->setDir(curDir);
397           ViewMan::getInstance()->addNoLock(sub);
398
399           sub->draw();
400           sub->show();
401
402           return 2;
403         }
404       }
405
406       // check to see if it's a recording
407       Recording* current = getCurrentOptionRecording();
408       if (current)
409       {
410         Log::getInstance()->log("VRecordingList", Log::DEBUG, "Found the option you pointed at. %s %s", current->getProgName(), current->fileName);
411
412         VRecordingMenu* v = new VRecordingMenu();
413         v->setParent(this);
414         v->setRecording(current);
415         ViewMan::getInstance()->addNoLock(v);
416         v->draw();
417         v->show();
418         return 2;
419       }
420       // should not get to here
421       return 1;
422     }
423     case Remote::BACK:
424     {
425       return 4;
426     }
427     case Remote::PLAY:
428     {
429       if (doPlay()) return 2;
430       return 1;
431     }
432
433   }
434   // stop command getting to any more views
435   return 1;
436 }