]> git.vomp.tv Git - vompclient.git/blob - vtimerlist.cc
Preparations for dynamic mode switching
[vompclient.git] / vtimerlist.cc
1 /*\r
2     Copyright 2004-2005 Chris Tallon\r
3 \r
4     This file is part of VOMP.\r
5 \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
10 \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
15 \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
19 */\r
20 \r
21 #include "vtimerlist.h"\r
22 \r
23 #include "message.h"\r
24 #include "remote.h"\r
25 #include "wsymbol.h"\r
26 #include "colour.h"\r
27 #include "video.h"\r
28 #include "i18n.h"\r
29 #include "timers.h"\r
30 #include "vtimeredit.h"\r
31 #include "command.h"\r
32 #include "boxstack.h"\r
33 #include "vdr.h"\r
34 #include "vinfo.h"\r
35 #include "log.h"\r
36 \r
37 VTimerList::VTimerList()\r
38 {\r
39   recTimerList = NULL;\r
40 \r
41   clockRegion.x = 420;\r
42   clockRegion.y = 0;\r
43   clockRegion.w = 150;\r
44   clockRegion.h = 30;\r
45 \r
46 \r
47 \r
48   flipflop = true;\r
49 \r
50   setSize(570, 420);\r
51   createBuffer();\r
52 \r
53   indicatorsRegion.x = 6;\r
54   indicatorsRegion.y = 44;\r
55   indicatorsRegion.w = 18;\r
56   indicatorsRegion.h = 15 * (getFontHeight() + 1);\r
57 \r
58   if (Video::getInstance()->getFormat() == Video::PAL)\r
59   {\r
60     setPosition(80, 70);\r
61   }\r
62   else\r
63   {\r
64     setPosition(70, 35);\r
65   }\r
66 \r
67   setTitleBarOn(1);\r
68   setTitleText(tr("Timers"));\r
69   setTitleBarColour(DrawStyle::TITLEBARBACKGROUND);\r
70 \r
71   sl.setPosition(30, 30 + 5);\r
72   sl.setSize(area.w - 40, area.h - 30 - 15 - 30);\r
73   add(&sl);\r
74 }\r
75 \r
76 void VTimerList::preDelete()\r
77 {\r
78   Timers::getInstance()->cancelTimer(this, 1);\r
79 }\r
80 \r
81 VTimerList::~VTimerList()\r
82 {\r
83   if (recTimerList)\r
84   {\r
85     for (UINT i = 0; i < recTimerList->size(); i++)\r
86     {\r
87       delete (*recTimerList)[i];\r
88     }\r
89 \r
90     recTimerList->clear();\r
91     delete recTimerList;\r
92   }\r
93 }\r
94 \r
95 void VTimerList::draw()\r
96 {\r
97   // Draw statics\r
98 \r
99   TBBoxx::draw();\r
100 \r
101   WSymbol w;\r
102   TEMPADD(&w);\r
103 \r
104   w.nextSymbol = WSymbol::UP;\r
105   w.setPosition(20, 385);\r
106   w.draw();\r
107 \r
108   w.nextSymbol = WSymbol::DOWN;\r
109   w.setPosition(50, 385);\r
110   w.draw();\r
111 \r
112   w.nextSymbol = WSymbol::SKIPBACK;\r
113   w.setPosition(85, 385);\r
114   w.draw();\r
115 \r
116   w.nextSymbol = WSymbol::SKIPFORWARD;\r
117   w.setPosition(115, 385);\r
118   w.draw();\r
119 \r
120   drawTextRJ("[ok] = edit", 560, 385, DrawStyle::LIGHTTEXT);\r
121 \r
122   drawClock();\r
123   drawShowing();\r
124   drawIndicators();\r
125 }\r
126 \r
127 bool VTimerList::load()\r
128 {\r
129   recTimerList = VDR::getInstance()->getRecTimersList();\r
130 \r
131   if (!recTimerList) return false;\r
132 \r
133   char strA[300];\r
134   char strB[300];\r
135 \r
136   struct tm* btime;\r
137 \r
138   // FIXME all drawing stuff in this class and sl.clear somewhere?!\r
139 \r
140   sl.addColumn(0);\r
141   sl.addColumn(110);\r
142 \r
143   RecTimer* recTimer;\r
144   int first = 1;\r
145 \r
146   for (UINT i = 0; i < recTimerList->size(); i++)\r
147   {\r
148     recTimer = (*recTimerList)[i];\r
149 \r
150     btime = localtime((time_t*)&recTimer->startTime);\r
151     strftime(strA, 299, "%d/%m %H:%M ", btime);\r
152     SNPRINTF(strB, 299, "%s\t%s", strA, recTimer->getName());\r
153     sl.addOption(strB, (ULONG)recTimer, first);\r
154     first = 0;\r
155   }\r
156 \r
157   return true;\r
158 }\r
159 \r
160 void VTimerList::drawClock()\r
161 {\r
162   // Blank the area first\r
163   rectangle(area.w - 150, 0, 150, 30, titleBarColour);\r
164 \r
165   char timeString[20];\r
166   time_t t;\r
167   time(&t);\r
168   struct tm* tms = localtime(&t);\r
169   strftime(timeString, 19, "%d/%m %H:%M:%S", tms);\r
170   drawTextRJ(timeString, 560, 5, DrawStyle::LIGHTTEXT);\r
171 \r
172   Timers::getInstance()->setTimerT(this, 1, t + 1);\r
173 }\r
174 \r
175 void VTimerList::drawShowing()\r
176 {\r
177   int topOption = sl.getTopOption() + 1;\r
178   if (sl.getNumOptions() == 0) topOption = 0;\r
179 \r
180   rectangle(220, 385, 180, 25, DrawStyle::VIEWBACKGROUND);\r
181   char showing[200];\r
182   sprintf(showing, tr("%i to %i of %i"), topOption, sl.getBottomOption(), sl.getNumOptions());\r
183   drawText(showing, 220, 385, DrawStyle::LIGHTTEXT);\r
184 }\r
185 \r
186 void VTimerList::drawIndicators()\r
187 {\r
188   int top = sl.getTopOption();\r
189   int bottom = sl.getBottomOption();\r
190   int yinc = getFontHeight() + 1;\r
191   RecTimer* recTimer;\r
192 \r
193   rectangle(6, 44, 18, 15*yinc, DrawStyle::VIEWBACKGROUND);\r
194 \r
195   // The indexes recorded from the wselectlist into the index member of the RecTimer\r
196   // Is the same as the position in the vector of RecTimers\r
197   // Because they are in order, they don't change order and wselectlist starts from 0 up consecutively\r
198 \r
199   int ypos = 44;\r
200   for (int current = top; current < bottom; current++)\r
201   {\r
202     recTimer = (*recTimerList)[current];\r
203 \r
204     if (recTimer->recording) // Flashing red square\r
205     {\r
206       if (flipflop)\r
207       {\r
208         rectangle(6, ypos, 18, 16, DrawStyle::RED);\r
209         drawText("R", 8, ypos-3, DrawStyle::LIGHTTEXT);\r
210       }\r
211     }\r
212     else if (recTimer->pending)\r
213     {\r
214       rectangle(6, ypos, 18, 16, DrawStyle::RED);\r
215       drawText("X", 8, ypos-3, DrawStyle::BLACK);\r
216     }\r
217     else if (recTimer->active == 0)\r
218     {\r
219       rectangle(6, ypos, 18, 16, DrawStyle::SELECTHIGHLIGHT);\r
220       drawText("X", 8, ypos-3, DrawStyle::BLACK);\r
221     }\r
222     else\r
223     {\r
224 //      if (flipflop) rectangle(6, ypos, 18, 16, DrawStyle::GREEN);\r
225     }\r
226 \r
227     ypos += yinc;\r
228   }\r
229 }\r
230 \r
231 void VTimerList::timercall(int clientReference)\r
232 {\r
233   drawClock();\r
234   BoxStack::getInstance()->update(this, &clockRegion);\r
235 \r
236   flipflop = !flipflop;\r
237   drawIndicators();\r
238   BoxStack::getInstance()->update(this, &indicatorsRegion);\r
239 }\r
240 \r
241 int VTimerList::handleCommand(int command)\r
242 {\r
243   switch(command)\r
244   {\r
245     case Remote::DF_UP:\r
246     case Remote::UP:\r
247     {\r
248       sl.up();\r
249       sl.draw();\r
250       drawShowing();\r
251       drawIndicators();\r
252       BoxStack::getInstance()->update(this);\r
253       return 2;\r
254     }\r
255     case Remote::DF_DOWN:\r
256     case Remote::DOWN:\r
257     {\r
258       sl.down();\r
259       sl.draw();\r
260       drawShowing();\r
261       drawIndicators();\r
262       BoxStack::getInstance()->update(this);\r
263       return 2;\r
264     }\r
265     case Remote::SKIPBACK:\r
266     {\r
267       sl.pageUp();\r
268       sl.draw();\r
269       drawShowing();\r
270       drawIndicators();\r
271       BoxStack::getInstance()->update(this);\r
272       return 2;\r
273     }\r
274     case Remote::SKIPFORWARD:\r
275     {\r
276       sl.pageDown();\r
277       sl.draw();\r
278       drawShowing();\r
279       drawIndicators();\r
280       BoxStack::getInstance()->update(this);\r
281       return 2;\r
282     }\r
283     case Remote::OK:\r
284     {\r
285       RecTimer* recTimer = NULL;\r
286       if (recTimerList) recTimer = (RecTimer*)sl.getCurrentOptionData();\r
287       if (recTimer == NULL) return 2;\r
288 \r
289       VTimerEdit* v = new VTimerEdit(recTimer);\r
290       v->setParent(this);\r
291       v->draw();\r
292       BoxStack::getInstance()->add(v);\r
293       BoxStack::getInstance()->update(v);\r
294 \r
295       return 2;\r
296     }\r
297     case Remote::BACK:\r
298     {\r
299       return 4;\r
300     }\r
301   }\r
302   // stop command getting to any more views\r
303   return 1;\r
304 }\r
305 \r
306 void VTimerList::processMessage(Message* m)\r
307 {\r
308   if (m->message == Message::MOUSE_MOVE)\r
309   {\r
310     if (sl.mouseMove((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY()))\r
311     {\r
312       sl.draw();\r
313       BoxStack::getInstance()->update(this);\r
314     }\r
315   }\r
316   else if (m->message == Message::MOUSE_LBDOWN)\r
317   {\r
318     if (sl.mouseLBDOWN((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY()))\r
319     {\r
320       BoxStack::getInstance()->handleCommand(Remote::OK); //simulate OK press\r
321     }\r
322     else\r
323     {\r
324       //check if press is outside this view! then simulate cancel\r
325       int x=(m->parameter>>16)-getScreenX();\r
326       int y=(m->parameter&0xFFFF)-getScreenY();\r
327       if (x<0 || y <0 || x>(int)getWidth() || y>(int)getHeight())\r
328       {\r
329         BoxStack::getInstance()->handleCommand(Remote::BACK); //simulate cancel press\r
330       }\r
331     }\r
332   }\r
333   else if (m->message == Message::DELETE_SELECTED_TIMER)\r
334   {\r
335     RecTimer* recTimer = (RecTimer*)sl.getCurrentOptionData();\r
336     if (recTimer == NULL) return;\r
337     Log::getInstance()->log("VTimerList", Log::DEBUG, "Got timer to delete");\r
338 \r
339   \r
340     ULONG retval = VDR::getInstance()->deleteTimer(recTimer);\r
341     if (!VDR::getInstance()->isConnected()) { Command::getInstance()->connectionLost(); return; }\r
342     Log::getInstance()->log("VTimerList", Log::DEBUG, "Got return fron delete timer: %lu", retval);\r
343     \r
344     if (retval != 10)\r
345     {\r
346       VInfo* errorBox = new VInfo();\r
347       errorBox->setSize(360, 200);\r
348       errorBox->createBuffer();\r
349       if (Video::getInstance()->getFormat() == Video::PAL)\r
350         errorBox->setPosition(190, 170);\r
351       else\r
352         errorBox->setPosition(180, 120);\r
353 \r
354     \r
355       if (retval == 1) errorBox->setOneLiner(tr("Timers being edited at VDR, please try later"));\r
356       else if (retval == 3)  errorBox->setOneLiner(tr("Unable to delete timer - timer is running"));\r
357       else if (retval == 4)  errorBox->setOneLiner(tr("Error - timer not found at VDR"));\r
358       else                   errorBox->setOneLiner(tr("Unknown error"));\r
359 \r
360       errorBox->setExitable();\r
361       errorBox->setBorderOn(1);\r
362       errorBox->setTitleBarColour(DrawStyle::DANGER);\r
363       errorBox->okButton();\r
364       errorBox->draw();\r
365       BoxStack::getInstance()->add(errorBox);\r
366       BoxStack::getInstance()->update(errorBox);\r
367     }\r
368     \r
369     int saveIndex = sl.getCurrentOption();\r
370     int saveTop = sl.getTopOption();\r
371      \r
372     if (recTimerList)\r
373     {\r
374       for (UINT i = 0; i < recTimerList->size(); i++)\r
375       {\r
376         delete (*recTimerList)[i];\r
377       }\r
378 \r
379       recTimerList->clear();\r
380       delete recTimerList;\r
381     }\r
382 \r
383     sl.clear();\r
384     load();\r
385 \r
386     sl.hintSetCurrent(saveIndex);\r
387     sl.hintSetTop(saveTop);\r
388     draw();\r
389     BoxStack::getInstance()->update(this);\r
390   }\r
391 }\r
392 \r