]> git.vomp.tv Git - vompclient.git/blob - src/vrecordinglistadvanced.cc
Switch to cmake
[vompclient.git] / src / vrecordinglistadvanced.cc
1 /*
2     Copyright 2004-2020 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 <cstdio>
21 #include <sstream>
22 #include <fmt/core.h>
23
24 #include "recman.h"
25 #include "directory.h"
26 #include "recording.h"
27 #include "recinfo.h"
28 #include "input.h"
29 #include "wsymbol.h"
30 #include "boxstack.h"
31 #include "vrecordingmenu.h"
32 #include "vrecording.h"
33 #include "vdr.h"
34 #include "vvideorec.h"
35 #include "vradiorec.h"
36 #include "colour.h"
37 #include "video.h"
38 #include "i18n.h"
39 #include "control.h"
40 #include "vinfo.h"
41 #include "log.h"
42 #include "movieinfo.h"
43 #include "seriesinfo.h"
44 #include "staticartwork.h"
45 #include "image.h"
46 #include "imageloader.h"
47 #include "osd.h"
48
49 #include "vrecordinglistadvanced.h"
50
51
52 VRecordingListAdvanced::VRecordingListAdvanced()
53 {
54   setSize(640, 500);
55   createBuffer();
56
57   setPosition(40, 40);
58
59   setTitleBarOn(1);
60   setTitleBarColour(DrawStyle::TITLEBARBACKGROUND);
61
62   Image icon = ImageLoader::getInstance()->createStatic(sa_recordings);
63   setTitleBarIcon(icon);
64
65   sl.setPosition(10, 30 + 5);
66   sl.setSize(area.w*42/100 - 20, area.h - 30 - 15 - 30);
67   sl.setLinesPerOption(2.4f);
68   add(&sl);
69
70   Region slarea = sl.getRegionR();
71
72   epg.setParaMode(true);
73   epg.setPosition(slarea.x  +slarea.w+10 ,30+5);
74   epg.setSize(area.w -slarea.x -slarea.w -10, area.h - 30 - 15 - 30);
75   add(&epg);
76   epg.setText("");
77   epg.setBackgroundColour(DrawStyle::VIEWBACKGROUND);
78
79   epgTVmedia.setPosition(epg.getRegionR().w-100-10,10);
80   epgTVmedia.setSize(100, static_cast<UINT>(150/Osd::getInstance()->getPixelAspect()));
81   epg.add(&epgTVmedia);
82 }
83
84 VRecordingListAdvanced::~VRecordingListAdvanced()
85 {
86 }
87
88 void VRecordingListAdvanced::drawData(bool doIndexPop)
89 {
90   int saveIndex = sl.getCurrentOption();
91   int saveTop = sl.getTopOption();
92   sl.clear();
93   sl.addColumn(0);
94   sl.addColumn(25 );
95   sl.addColumn(25 + 7);
96   //sl.addColumn(118);
97
98   int first = 1;
99
100   char timeString[16]; // "dd/mm/yy hh:mm"
101   struct tm btime;
102
103   Directory* currentSubDir;
104   DirectoryList::iterator i;
105   DirectoryList* dirList = recman->getDirectories();
106   for (i = dirList->begin(); i != dirList->end(); i++)
107   {
108     currentSubDir = *i;
109     std::string dirString = fmt::format("\t{} \n \t <dir> {}/{}", currentSubDir->name, currentSubDir->getNumNewRecordings(), currentSubDir->getNumRecordings());
110
111     Image icon;
112     if (currentSubDir->recList.begin() != currentSubDir->recList.end())
113     {
114       icon = ImageLoader::getInstance()->createRecFolder((*currentSubDir->recList.begin())->getFileName());
115     }
116     currentSubDir->index = sl.addOption(dirString, 0, first, icon);
117     first = 0;
118
119   }
120   // FIXME convert the whole program to time_t's
121
122   Recording* currentRec;
123   RecordingList::iterator j;
124   RecordingList* recList = recman->getRecordings();
125   for (j = recList->begin(); j != recList->end(); j++)
126   {
127     currentRec = *j;
128     time_t recStartTime = static_cast<time_t>(currentRec->getStartTime());
129     LOCALTIME_R(&recStartTime, &btime);
130     strftime(timeString, 16, "%d/%m/%y %H:%M", &btime);
131     std::string fileString = fmt::format("{}\t{}\n \t{}", (currentRec->getNew() ? '*': ' '), currentRec->getProgName(), timeString);
132
133     Image icon = ImageLoader::getInstance()->createRecThumb(currentRec->getFileName());
134     currentRec->index = sl.addOption(fileString, 0, first, icon);
135     first = 0;
136   }
137
138   if (doIndexPop)
139   {
140     sl.hintSetCurrent(slIndexStack.top());
141     slIndexStack.pop();
142   }
143   else
144   {
145     sl.hintSetCurrent(saveIndex);
146     sl.hintSetTop(saveTop);
147   }
148   updateSelection();
149 }
150
151 void VRecordingListAdvanced::draw(bool doIndexPop)
152 {
153   if (!loading)
154   {
155     if (recman->isSubDir())
156     {
157       char title[300];
158       SNPRINTF(title, 300, tr("Recordings - %s"), recman->getCurDirName());
159       setTitleText(title, 364);
160     }
161     else
162     {
163       setTitleText(tr("Recordings"));
164     }
165     drawData(doIndexPop);
166   }
167
168   TBBoxx::draw();
169
170   if (loading)
171   {
172     drawText(tr("Loading..."), area.w*22/100-90, 180, DrawStyle::LIGHTTEXT);
173   }
174   else
175   {
176     char freeSpace[50];
177     int gigFree = recman->getFreeSpace() / 1024;
178     SNPRINTF(freeSpace, 50, tr("%lu%% used, %iGB free"), recman->getUsedPercent(), gigFree);
179     drawTextRJ(freeSpace, 560+70, 5, DrawStyle::LIGHTTEXT);
180     // Symbols
181
182     WSymbol w;
183     TEMPADD(&w);
184     w.nextSymbol = WSymbol::UP;
185     w.setPosition(20, area.h-35);
186     w.draw();
187     w.nextSymbol = WSymbol::DOWN;
188     w.setPosition(50, area.h-35);
189     w.draw();
190     w.nextSymbol = WSymbol::SKIPBACK;
191     w.setPosition(85, area.h-35);
192     w.draw();
193     w.nextSymbol = WSymbol::SKIPFORWARD;
194     w.setPosition(115, area.h-35);
195     w.draw();
196     w.nextSymbol = WSymbol::PLAY;
197     w.setPosition(150, area.h-35);
198     w.draw();
199     drawTextRJ(tr("[ok] = menu"), 560+70, 385+80, DrawStyle::LIGHTTEXT);
200
201     // All static stuff done
202     doShowingBar();
203   }
204 }
205
206 void VRecordingListAdvanced::doShowingBar()
207 { //setSize(640, 500); //old   setSize(570, 420);
208   int topOption = sl.getTopOption() + 1;
209   if (sl.getNumOptions() == 0) topOption = 0;
210 #ifndef GRADIENT_DRAWING
211   rectangle(area.w/2-65, area.h-115, 180, 25, DrawStyle::VIEWBACKGROUND);
212 #endif
213   char showing[200];
214   SNPRINTF(showing, 200, tr("%i to %i of %i"), topOption, sl.getBottomOption(), sl.getNumOptions());
215   drawText(showing, area.w/2-65, area.h-35, DrawStyle::LIGHTTEXT);
216 }
217
218 void VRecordingListAdvanced::updateSelection()
219 {
220         Recording* toShow = getCurrentOptionRecording();
221         if (toShow)
222         {
223                 toShow->loadRecInfo();
224                 std::stringstream description;
225                 if (toShow->recInfo && strlen(toShow->recInfo->summary)){
226                         description << "\n"<< toShow->recInfo->title  << "\n\n";
227                         description << toShow->recInfo->summary;
228                 }else {
229                         description << "\n" << std::string(toShow->getProgName()) << "\n\n";
230                         description << tr("Summary unavailable");
231
232                 }
233                 TVMediaStruct poster;
234                 poster.height=0;
235                 if (toShow->movieInfo) {
236                         poster=toShow->movieInfo->poster;
237                 }
238                 if (toShow->seriesInfo) {
239                         if (toShow->seriesInfo->seasonposter.height) {
240                                 poster=toShow->seriesInfo->seasonposter;
241                         }
242                         else
243                                 if (toShow->seriesInfo->posters.size()) {
244                                         poster=toShow->seriesInfo->posters[0];
245                                 }
246                 }
247                 if (poster.height) {
248                         epgTVmedia.setImage(poster.image, WTVMedia::ZoomHorizontal);
249                         epgTVmedia.setVisible(true);
250                 } else {
251                         epgTVmedia.setVisible(false);
252                 }
253
254                 epg.setText(description.str().c_str());
255         } else {
256                 Directory* toShowDir = getCurrentOptionDirectory();
257                 if (toShowDir)
258                 {
259                         std::stringstream description;
260                         description << "\n"<< std::string(toShowDir->name) << "\n\n";
261
262                         Directory* currentSubDir;
263                         DirectoryList::iterator i;
264                         DirectoryList & dirList = toShowDir->dirList;
265                         for (i = dirList.begin(); i != dirList.end(); i++)
266                         {
267                                 currentSubDir = *i;
268                                 description << tr("<dir> ") <<  std::string(currentSubDir->name) << " "
269                                                 << currentSubDir->getNumNewRecordings() <<"/"<< currentSubDir->getNumRecordings() <<"\n";
270                         }
271                         Recording* currentRec;
272                         RecordingList::iterator j;
273                         RecordingList & recList = toShowDir->recList;
274                         char tempA[300];
275                         struct tm btime;
276                         for (j = recList.begin(); j != recList.end(); j++)
277                         {
278                                 currentRec = *j;
279
280                                 time_t recStartTime = static_cast<time_t>(currentRec->getStartTime());
281                                 LOCALTIME_R(&recStartTime, &btime);
282                                 strftime(tempA, 299, "%d/%m/%y %H:%M ", &btime);
283
284                                 description<< tempA <<" "<< std::string(currentRec->getProgName()) << "\n";
285
286                         }
287                         epgTVmedia.setVisible(false);
288                         epg.setText(description.str().c_str());
289
290
291                 }
292         }
293
294 }
295
296
297
298 void VRecordingListAdvanced::quickUpdate() { //only quick for plattform that need it!
299         updateSelection();
300 #ifdef GRADIENT_DRAWING
301       draw();
302 #else
303       sl.draw();
304       doShowingBar();
305       epg.draw();
306 #endif
307 }