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