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