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