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