]> git.vomp.tv Git - vompclient.git/blob - vepgsettimer.cc
Fix segfault in boxstack.cc
[vompclient.git] / vepgsettimer.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 "vepgsettimer.h"
22
23 #include "event.h"
24 #include "channel.h"
25 #include "boxstack.h"
26 #include "vdr.h"
27 #include "log.h"
28 #include "vinfo.h"
29 #include "message.h"
30 #include "command.h"
31 #include "video.h"
32 #include "remote.h"
33 #include "i18n.h"
34
35 VEpgSetTimer::VEpgSetTimer(Event* tevent, Channel* tchannel)
36 {
37   boxstack = BoxStack::getInstance();
38   vdr = VDR::getInstance();
39   logger = Log::getInstance();
40
41   event = tevent;
42   channel = tchannel;
43
44   setSize(400, 240);
45   createBuffer();
46   if (Video::getInstance()->getFormat() == Video::PAL)
47   {
48     setPosition(150, 170);
49   }
50   else
51   {
52     setPosition(140, 140);
53   }
54
55   setTitleBarOn(1);
56   setTitleBarColour(DrawStyle::TITLEBARBACKGROUND);
57   setBorderOn(true);
58   setTitleText(tr("Set Timer"));
59
60   add(&buttonYes);
61   add(&buttonNo);
62
63   buttonYes.setPosition(80, 40 + (7 * getFontHeight()));
64   buttonNo.setPosition(220, 40 + (7 * getFontHeight()));
65
66   buttonYes.setText(tr("Yes"));
67   buttonNo.setText(tr("No"));
68   buttonYes.setActive(1);
69   selectedOption = YES;
70
71   logger->log("VEPGST", Log::DEBUG, "Title: %s", event->title);
72   logger->log("VEPGST", Log::DEBUG, "Time: %lu", event->time);
73   logger->log("VEPGST", Log::DEBUG, "Duration: %lu", event->duration);
74   logger->log("VEPGST", Log::DEBUG, "Channel: %i", channel->number);
75 }
76
77 VEpgSetTimer::~VEpgSetTimer()
78 {
79 }
80
81 char* VEpgSetTimer::genTimerString()
82 {
83   // Allocate to return
84   char* timerString = new char[1024];
85
86   // Other
87   struct tm* btime;
88   int flags;
89   char dateString[20];
90   char startMargin[10];
91   time_t startTime;
92   char startString[10];
93   char endMargin[10];
94   time_t endTime;
95   char endString[10];
96   char priority[10];
97   char lifetime[10];
98   char* eventTitle;
99
100   flags = 1; // hard coded active timer flag
101
102   char* startMarginConfig = vdr->configLoad("Timers", "Start margin");
103   if (startMarginConfig)
104   {
105     strncpy(startMargin, startMarginConfig, 9);
106     delete[] startMarginConfig;
107   }
108   else strcpy(startMargin, "5");
109
110   startTime = event->time - (atoi(startMargin) * 60);
111   btime = localtime(&startTime);
112   strftime(dateString, 19, "%Y-%m-%d", btime);
113   strftime(startString, 9, "%H%M", btime);
114
115   char* endMarginConfig = vdr->configLoad("Timers", "End margin");
116   if (endMarginConfig)
117   {
118     strncpy(endMargin, endMarginConfig, 9);
119     delete[] endMarginConfig;
120   }
121   else strcpy(endMargin, "5");
122
123   endTime = event->time + event->duration + (atoi(endMargin) * 60);
124   btime = localtime(&endTime);
125   strftime(endString, 9, "%H%M", btime);
126
127   char* priorityConfig = vdr->configLoad("Timers", "Priority");
128   if (priorityConfig)
129   {
130     strncpy(priority, priorityConfig, 9);
131     delete[] priorityConfig;
132   }
133   else strcpy(priority, "99");
134
135   char* lifetimeConfig = vdr->configLoad("Timers", "Lifetime");
136   if (lifetimeConfig)
137   {
138     strncpy(lifetime, lifetimeConfig, 9);
139     delete[] lifetimeConfig;
140   }
141   else strcpy(lifetime, "99");
142
143   eventTitle = new char[strlen(event->title) + 1];
144   strcpy(eventTitle, event->title);
145   for(UINT i=0; i < strlen(eventTitle); i++) if (eventTitle[i] == ':') eventTitle[i] = '|';
146
147   SNPRINTF(timerString, 1023, "%i:%lu:%s:%s:%s:%s:%s:%s:",
148     flags, channel->number, dateString,
149     startString, endString,
150     priority, lifetime, eventTitle);
151
152   delete[] eventTitle;
153
154   return timerString;
155 }
156
157 void VEpgSetTimer::swap()
158 {
159   if (selectedOption == NO)
160   {
161     selectedOption = YES;
162     buttonYes.setActive(1);
163     buttonNo.setActive(0);
164   }
165   else if (selectedOption == YES)
166   {
167     selectedOption = NO;
168     buttonYes.setActive(0);
169     buttonNo.setActive(1);
170   }
171 }
172
173 void VEpgSetTimer::draw()
174 {
175   TBBoxx::draw();
176   drawPara(event->title, 10, 40, DrawStyle::LIGHTTEXT);
177   drawText(channel->name, 10, 40 + (2 * getFontHeight()), DrawStyle::LIGHTTEXT);
178
179   char fullString[20];
180   time_t t;
181   struct tm* btime;
182   char timeString[10];
183   btime = localtime((time_t*)&event->time);
184 #ifndef _MSC_VER
185   strftime(timeString, 9, "%0H:%0M - ", btime); // and format it as hh:mm -
186 #else
187    strftime(timeString, 9, "%H:%M - ", btime); // and format it as hh:mm -
188 #endif
189   strcpy(fullString, timeString); // put it in our buffer
190   t = event->time + event->duration; //get programme end time
191   btime = localtime(&t);
192 #ifndef _MSC_VER
193   strftime(timeString, 9, "%0H:%0M", btime); // and format it as hh:mm -
194 #else
195    strftime(timeString, 9, "%H:%M", btime); // and format it as hh:mm -
196 #endif
197
198   strcat(fullString, timeString); // put it in our buffer
199
200   drawText(fullString, 10, 40 + (3 * getFontHeight()), DrawStyle::LIGHTTEXT);
201   drawText(tr("Create this timer?"), 10, 40 + (5 * getFontHeight()), DrawStyle::LIGHTTEXT);
202
203   buttonYes.draw();
204   buttonNo.draw();
205 }
206
207 int VEpgSetTimer::handleCommand(int command)
208 {
209   switch(command)
210   {
211     case Remote::DF_LEFT:
212     case Remote::LEFT:
213     {
214       swap();
215       draw();
216       boxstack->update(this);
217       return 2;
218     }
219     case Remote::DF_RIGHT:
220     case Remote::RIGHT:
221     {
222       swap();
223       draw();
224       boxstack->update(this);
225       return 2;
226     }
227     case Remote::BACK:
228     {
229       return 4;
230     }
231     case Remote::OK:
232     {
233       if (selectedOption != YES) return 4;
234       doit();
235       return 4;
236     }
237   }
238
239   return 1;
240 }
241
242
243 void VEpgSetTimer::doit()
244 {
245   char* timerString = genTimerString();
246   logger->log("VEPGST", Log::DEBUG, "%s", timerString);
247
248   ULONG ret = vdr->setEventTimer(timerString);
249   delete[] timerString;
250
251   if (!vdr->isConnected())
252   {
253     Command::getInstance()->connectionLost();
254   }
255
256   if (ret == 0) logger->log("VEPGST", Log::DEBUG, "Success");
257   else if (ret == 1) logger->log("VEPGST", Log::DEBUG, "Fail: Timer already set for this event");
258   else if (ret == 2) logger->log("VEPGST", Log::DEBUG, "Fail: General failure setting timer");
259
260   VInfo* vi = new VInfo();
261   vi->setSize(400, 150);
262   vi->createBuffer();
263   vi->setExitable();
264   vi->setBorderOn(1);
265   vi->setTitleBarOn(0);
266
267   if (Video::getInstance()->getFormat() == Video::PAL)
268     vi->setPosition(170, 200);
269   else
270     vi->setPosition(160, 150);
271
272   if (ret == 0) vi->setOneLiner(tr("Timer set successfully"));
273   else if (ret == 1) vi->setOneLiner(tr("There is already a timer for this event"));
274   else if (ret == 2) vi->setOneLiner(tr("Failure setting timer"));
275   vi->draw();
276
277   Message* m = new Message();
278   m->message = Message::ADD_VIEW;
279   m->to = boxstack;
280   m->parameter = (ULONG)vi;
281   Command::getInstance()->postMessageNoLock(m);
282 }
283
284 void VEpgSetTimer::processMessage(Message* m)
285 {
286   if (m->message == Message::MOUSE_MOVE)
287   {
288     if (buttonYes.mouseMove((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY()))
289     {
290       buttonNo.setActive(0);
291       selectedOption = YES;
292       draw();
293       boxstack->update(this);
294     }
295     else if (buttonNo.mouseMove((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY()))
296     {
297       buttonYes.setActive(0);
298       selectedOption = NO;
299       draw();
300       boxstack->update(this);
301     }
302   }
303   else if (m->message == Message::MOUSE_LBDOWN)
304   {
305     if (buttonYes.mouseLBDOWN((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY()))
306     {
307       boxstack->handleCommand(Remote::OK); //simulate OK press
308     }
309     else if (buttonNo.mouseLBDOWN((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY()))
310     {
311       boxstack->handleCommand(Remote::OK); //simulate OK press
312     }
313     else
314     {
315       //check if press is outside this view! then simulate cancel
316       int x=(m->parameter>>16)-getScreenX();
317       int y=(m->parameter&0xFFFF)-getScreenY();
318       if (x<0 || y <0 || x>(int)getWidth() || y>(int)getHeight())
319       {
320         boxstack->handleCommand(Remote::BACK); //simulate cancel press
321       }
322     }
323   }
324 }