2 Copyright 2004-2007 Chris Tallon
\r
4 This file is part of VOMP.
\r
6 VOMP is free software; you can redistribute it and/or modify
\r
7 it under the terms of the GNU General Public License as published by
\r
8 the Free Software Foundation; either version 2 of the License, or
\r
9 (at your option) any later version.
\r
11 VOMP is distributed in the hope that it will be useful,
\r
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
14 GNU General Public License for more details.
\r
16 You should have received a copy of the GNU General Public License
\r
17 along with VOMP; if not, write to the Free Software
\r
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
\r
21 #include "vrecordinglist.h"
\r
24 #include "directory.h"
\r
25 #include "recording.h"
\r
27 #include "wsymbol.h"
\r
28 #include "boxstack.h"
\r
29 #include "vrecordingmenu.h"
\r
30 #include "vrecording.h"
\r
32 #include "vvideorec.h"
\r
33 #include "vradiorec.h"
\r
37 #include "command.h"
\r
41 VRecordingList::VRecordingList()
\r
43 boxstack = BoxStack::getInstance();
\r
49 if (Video::getInstance()->getFormat() == Video::PAL)
\r
51 setPosition(80, 70);
\r
55 setPosition(70, 35);
\r
59 setTitleBarColour(Colour::TITLEBARBACKGROUND);
\r
61 sl.setPosition(10, 30 + 5);
\r
62 sl.setSize(area.w - 20, area.h - 30 - 15 - 30);
\r
66 VRecordingList::~VRecordingList()
\r
71 void VRecordingList::drawData(bool doIndexPop)
\r
73 int saveIndex = sl.getCurrentOption();
\r
74 int saveTop = sl.getTopOption();
\r
81 char tempA[300]; // FIXME this is guesswork!
\r
82 char tempB[300]; // FIXME
\r
85 Directory* currentSubDir;
\r
86 DirectoryList::iterator i;
\r
87 DirectoryList* dirList = recman->getDirectories();
\r
88 for (i = dirList->begin(); i != dirList->end(); i++)
\r
91 SNPRINTF(tempA, 299, tr("<dir> %lu\t%s"), currentSubDir->getNumRecordings(), currentSubDir->name);
\r
92 currentSubDir->index = sl.addOption(tempA, 0, first);
\r
95 // FIXME convert the whole program to time_t's
\r
97 Recording* currentRec;
\r
98 RecordingList::iterator j;
\r
99 RecordingList* recList = recman->getRecordings();
\r
100 for (j = recList->begin(); j != recList->end(); j++)
\r
103 time_t recStartTime = (time_t)currentRec->getStartTime();
\r
104 btime = localtime(&recStartTime);
\r
105 //NMT does not like this too!
\r
107 // strftime(tempA, 299, "%0d/%0m %0H:%0M ", btime);
\r
109 strftime(tempA, 299, "%d/%m %H:%M ", btime);
\r
111 sprintf(tempB, "%s\t%s", tempA, currentRec->getProgName());
\r
112 currentRec->index = sl.addOption(tempB, 0, first);
\r
118 sl.hintSetCurrent(slIndexStack.top());
\r
119 slIndexStack.pop();
\r
123 sl.hintSetCurrent(saveIndex);
\r
124 sl.hintSetTop(saveTop);
\r
130 void VRecordingList::draw(bool doIndexPop)
\r
134 if (recman->isSubDir())
\r
137 SNPRINTF(title, 299, tr("Recordings - %s"), recman->getCurDirName());
\r
138 setTitleText(title, 364);
\r
142 setTitleText(tr("Recordings"));
\r
150 drawText(tr("Loading..."), 240, 180, Colour::LIGHTTEXT);
\r
154 char freeSpace[50];
\r
155 int gigFree = recman->getFreeSpace() / 1024;
\r
156 SNPRINTF(freeSpace, 49, tr("%lu%% used, %iGB free"), recman->getUsedPercent(), gigFree);
\r
157 drawTextRJ(freeSpace, 560, 5, Colour::LIGHTTEXT);
\r
162 w.nextSymbol = WSymbol::UP;
\r
163 w.setPosition(20, 385);
\r
165 w.nextSymbol = WSymbol::DOWN;
\r
166 w.setPosition(50, 385);
\r
168 w.nextSymbol = WSymbol::SKIPBACK;
\r
169 w.setPosition(85, 385);
\r
171 w.nextSymbol = WSymbol::SKIPFORWARD;
\r
172 w.setPosition(115, 385);
\r
174 w.nextSymbol = WSymbol::PLAY;
\r
175 w.setPosition(150, 385);
\r
177 drawTextRJ(tr("[ok] = menu"), 560, 385, Colour::LIGHTTEXT);
\r
179 // All static stuff done
\r
180 drawData(doIndexPop);
\r
184 void VRecordingList::doShowingBar()
\r
186 int topOption = sl.getTopOption() + 1;
\r
187 if (sl.getNumOptions() == 0) topOption = 0;
\r
189 rectangle(220, 385, 180, 25, Colour::VIEWBACKGROUND);
\r
191 sprintf(showing, tr("%i to %i of %i"), topOption, sl.getBottomOption(), sl.getNumOptions());
\r
192 drawText(showing, 220, 385, Colour::LIGHTTEXT);
\r
195 void VRecordingList::processMessage(Message* m)
\r
197 Log::getInstance()->log("VRecordingList", Log::DEBUG, "Got message value %lu", m->message);
\r
199 if (m->message == Message::MOUSE_MOVE)
\r
201 if (sl.mouseMove((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY()))
\r
205 boxstack->update(this);
\r
208 else if (m->message == Message::MOUSE_LBDOWN)
\r
210 if (sl.mouseLBDOWN((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY()))
\r
212 boxstack->handleCommand(Remote::OK); //simulate OK press
\r
216 //check if press is outside this view! then simulate cancel
\r
217 int x=(m->parameter>>16)-getScreenX();
\r
218 int y=(m->parameter&0xFFFF)-getScreenY();
\r
219 if (x<0 || y <0 || x>(int)getWidth() || y>(int)getHeight())
\r
221 boxstack->handleCommand(Remote::BACK); //simulate cancel press
\r
225 else if (m->message == Message::DELETE_SELECTED_RECORDING)
\r
227 Log::getInstance()->log("VRecordingList", Log::DEBUG, "Doing delete selected");
\r
228 doDeleteSelected();
\r
230 else if (m->message == Message::MOVE_RECORDING)
\r
232 Log::getInstance()->log("VRecordingList", Log::DEBUG, "Doing move recording");
\r
233 doMoveRecording((Directory*)m->parameter);
\r
235 else if (m->message == Message::PLAY_SELECTED_RECORDING)
\r
239 else if (m->message == Message::RESUME_SELECTED_RECORDING)
\r
245 void VRecordingList::doDeleteSelected()
\r
247 Recording* toDelete = getCurrentOptionRecording();
\r
249 if (!toDelete) return;
\r
251 Log::getInstance()->log("VRecordingList", Log::DEBUG, "FOUND: %i %s %s", toDelete->index, toDelete->getProgName(), toDelete->getFileName());
\r
253 int success = recman->deleteRecording(toDelete);
\r
254 if (!VDR::getInstance()->isConnected())
\r
256 Command::getInstance()->connectionLost();
\r
262 VInfo* vi = new VInfo();
\r
263 vi->setSize(360, 200);
\r
264 vi->createBuffer();
\r
265 if (Video::getInstance()->getFormat() == Video::PAL)
\r
266 vi->setPosition(190, 170);
\r
268 vi->setPosition(180, 120);
\r
269 vi->setOneLiner(tr("Failed to delete recording"));
\r
271 vi->setBorderOn(1);
\r
272 vi->setTitleBarColour(Colour::DANGER);
\r
276 boxstack->update(vi);
\r
281 boxstack->update(this);
\r
286 void VRecordingList::doMoveRecording(Directory* toDir)
\r
288 Recording* toMove = getCurrentOptionRecording();
\r
289 if (!toMove || !toDir) return;
\r
291 Log::getInstance()->log("VRecordingList", Log::DEBUG, "MOVE: %s %s", toMove->getProgName(), toDir->name);
\r
293 int success = recman->moveRecording(toMove, toDir);
\r
294 if (!VDR::getInstance()->isConnected())
\r
296 Command::getInstance()->connectionLost();
\r
302 VInfo* vi = new VInfo();
\r
303 vi->setSize(360, 200);
\r
304 vi->createBuffer();
\r
305 if (Video::getInstance()->getFormat() == Video::PAL)
\r
306 vi->setPosition(190, 170);
\r
308 vi->setPosition(180, 120);
\r
309 vi->setOneLiner(tr("Failed to move recording"));
\r
311 vi->setBorderOn(1);
\r
312 vi->setTitleBarColour(Colour::DANGER);
\r
316 boxstack->update(vi);
\r
321 boxstack->update(this);
\r
325 int VRecordingList::doPlay(bool resume)
\r
327 Recording* toPlay = getCurrentOptionRecording();
\r
330 toPlay->loadRecInfo(); // check if still need this
\r
331 toPlay->loadMarks();
\r
334 bool isRadio = toPlay->isRadio(ish264);
\r
338 VRadioRec* radrec = new VRadioRec(toPlay);
\r
340 boxstack->add(radrec);
\r
341 boxstack->update(radrec);
\r
346 if (ish264 && !Video::getInstance()->supportsh264()) {
\r
347 VInfo* vi = new VInfo();
\r
348 vi->setSize(360, 200);
\r
349 vi->createBuffer();
\r
350 if (Video::getInstance()->getFormat() == Video::PAL)
\r
351 vi->setPosition(190, 170);
\r
353 vi->setPosition(180, 120);
\r
354 vi->setOneLiner(tr("H264 video not supported"));
\r
356 vi->setBorderOn(1);
\r
357 vi->setTitleBarColour(Colour::DANGER);
\r
361 boxstack->update(vi);
\r
364 VVideoRec* vidrec = new VVideoRec(toPlay, ish264);
\r
366 boxstack->add(vidrec);
\r
367 boxstack->update(vidrec);
\r
368 vidrec->go(resume);
\r
373 // should not get to here
\r
377 Recording* VRecordingList::getCurrentOptionRecording()
\r
379 Recording* currentRec;
\r
380 RecordingList::iterator j;
\r
381 RecordingList* recList = recman->getRecordings();
\r
382 for (j = recList->begin(); j != recList->end(); j++)
\r
385 if (currentRec->index == sl.getCurrentOption()) return currentRec;
\r
391 int VRecordingList::handleCommand(int command)
\r
395 case Remote::DF_UP:
\r
402 boxstack->update(this);
\r
405 case Remote::DF_DOWN:
\r
412 boxstack->update(this);
\r
415 case Remote::SKIPBACK:
\r
421 boxstack->update(this);
\r
424 case Remote::SKIPFORWARD:
\r
430 boxstack->update(this);
\r
435 if (sl.getNumOptions() == 0) return 2;
\r
437 // Check to see if it is a sub directory
\r
438 Directory* currentSubDir;
\r
439 DirectoryList::iterator i;
\r
440 DirectoryList* dirList = recman->getDirectories();
\r
441 for (i = dirList->begin(); i != dirList->end(); i++)
\r
443 currentSubDir = *i;
\r
444 if (currentSubDir->index == sl.getCurrentOption())
\r
446 if (recman->down(currentSubDir))
\r
448 slIndexStack.push(sl.getCurrentOption());
\r
451 boxstack->update(this);
\r
457 // check to see if it's a recording
\r
458 Recording* current = getCurrentOptionRecording();
\r
461 Log::getInstance()->log("VRecordingList", Log::DEBUG, "Found the option you pointed at. %s %s", current->getProgName(), current->getFileName());
\r
464 VRecordingMenu* v = new VRecordingMenu(recman);
\r
465 v->setParent(this);
\r
466 v->setRecording(current);
\r
469 boxstack->update(v);
\r
471 VRecording* vr = new VRecording(recman, current);
\r
472 vr->setParent(this);
\r
475 boxstack->update(vr);
\r
479 // should not get to here
\r
484 if (recman->isSubDir())
\r
489 boxstack->update(this);
\r
497 case Remote::PLAYPAUSE:
\r
500 if (doPlay(true)) return 2;
\r
504 case Remote::RIGHT:
\r
511 // stop command getting to any more views
\r
515 bool VRecordingList::load()
\r
517 VDR* vdr = VDR::getInstance();
\r
519 recman = new RecMan();
\r
521 bool success = vdr->getRecordingsList(recman);
\r
526 char* defaultSortOrder = vdr->configLoad("General", "Recordings Sort Order");
\r
527 if (defaultSortOrder)
\r
529 if (!STRCASECMP(defaultSortOrder, "Chronological")) recman->setSortOrderChron();
\r
530 delete[] defaultSortOrder;
\r
534 boxstack->update(this);
\r
540 void VRecordingList::reSort()
\r
542 recman->toggleSortOrder();
\r
546 boxstack->update(this);
\r