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