2 Copyright 2004-2020 Chris Tallon
4 This file is part of VOMP.
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.
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.
16 You should have received a copy of the GNU General Public License
17 along with VOMP. If not, see <https://www.gnu.org/licenses/>.
31 #include "vtimeredit.h"
36 #include "staticartwork.h"
37 #include "imageloader.h"
39 #include "vtimerlist.h"
41 static const char* TAG = "VTimerList";
43 VTimerList::VTimerList()
53 indicatorsRegion.x = 6;
54 indicatorsRegion.y = 44;
55 indicatorsRegion.w = 18;
56 indicatorsRegion.h = 15 * (getFontHeight() + 1);
58 if (Video::getInstance()->getFormat() == Video::PAL)
68 setTitleText(tr("Timers"));
69 setTitleBarColour(DrawStyle::TITLEBARBACKGROUND);
70 Image icon = ImageLoader::getInstance()->createStatic(sa_timers);
71 setTitleBarIcon(icon);
73 sl.setPosition(30, 30 + 5);
74 sl.setSize(area.w - 40, area.h - 30 - 15 - 30);
77 MessageQueue::getInstance()->addReceiver(this);
80 void VTimerList::preDelete()
82 Timers::getInstance()->cancelTimer(this, 1);
85 VTimerList::~VTimerList()
87 MessageQueue::getInstance()->removeReceiver(this);
91 for (u4 i = 0; i < recTimerList->size(); i++)
93 delete (*recTimerList)[i];
96 recTimerList->clear();
101 void VTimerList::draw()
110 w.nextSymbol = WSymbol::UP;
111 w.setPosition(20, 385);
114 w.nextSymbol = WSymbol::DOWN;
115 w.setPosition(50, 385);
118 w.nextSymbol = WSymbol::SKIPBACK;
119 w.setPosition(85, 385);
122 w.nextSymbol = WSymbol::SKIPFORWARD;
123 w.setPosition(115, 385);
126 drawTextRJ("[ok] = edit", 560, 385, DrawStyle::LIGHTTEXT);
133 bool VTimerList::load()
135 recTimerList = VDR::getInstance()->getRecTimersList();
137 if (!recTimerList) return false;
144 // FIXME all drawing stuff in this class and sl.clear somewhere?!
152 for (u4 i = 0; i < recTimerList->size(); i++)
154 recTimer = (*recTimerList)[i];
155 time_t rectime = recTimer->startTime;
156 LOCALTIME_R(&rectime, &btime);
157 strftime(strA, 299, "%d/%m %H:%M ", &btime);
158 int check = SNPRINTF(strB, 300, "%s\t%s", strA, recTimer->getName());
159 if ((check < 0) || (check > 299)) LogNT::getInstance()->error(TAG, "String too big");
160 sl.addOption(strB, recTimer, first);
167 void VTimerList::drawClock()
169 // Blank the area first
170 #ifndef GRADIENT_DRAWING
171 rectangle(area.w - 150, 0, 150, 30, titleBarColour);
178 LOCALTIME_R(&t, &tms);
179 strftime(timeString, 19, "%d/%m %H:%M:%S", &tms);
180 drawTextRJ(timeString, 560, 5, DrawStyle::LIGHTTEXT);
182 Timers::getInstance()->setTimerT(this, 1, t + 1);
185 void VTimerList::drawShowing()
187 int topOption = sl.getTopOption() + 1;
188 if (sl.getNumOptions() == 0) topOption = 0;
189 #ifndef GRADIENT_DRAWING
190 rectangle(220, 385, 180, 25, DrawStyle::VIEWBACKGROUND);
193 sprintf(showing, tr("%i to %i of %i"), topOption, sl.getBottomOption(), sl.getNumOptions());
194 drawText(showing, 220, 385, DrawStyle::LIGHTTEXT);
197 void VTimerList::quickUpdate() { //only quick for plattform that need it!
198 #ifdef GRADIENT_DRAWING
207 void VTimerList::drawIndicators()
209 int top = sl.getTopOption();
210 int bottom = sl.getBottomOption();
211 int yinc = getFontHeight() + 1;
213 #ifndef GRADIENT_DRAWING
214 rectangle(6, 44, 18, 15*yinc, DrawStyle::VIEWBACKGROUND);
216 // The indexes recorded from the wselectlist into the index member of the RecTimer
217 // Is the same as the position in the vector of RecTimers
218 // Because they are in order, they don't change order and wselectlist starts from 0 up consecutively
221 for (int current = top; current < bottom; current++)
223 recTimer = (*recTimerList)[current];
225 if (recTimer->recording) // Flashing red square
229 rectangle(6, ypos, 18, 16, DrawStyle::RED);
230 drawText("R", 8, ypos-3, DrawStyle::LIGHTTEXT);
233 else if (recTimer->pending)
235 rectangle(6, ypos, 18, 16, DrawStyle::RED);
236 drawText("X", 8, ypos-3, DrawStyle::BLACK);
238 else if (recTimer->active == 0)
240 rectangle(6, ypos, 18, 16, DrawStyle::SELECTHIGHLIGHT);
241 drawText("X", 8, ypos-3, DrawStyle::BLACK);
245 // if (flipflop) rectangle(6, ypos, 18, 16, DrawStyle::GREEN);
252 void VTimerList::timercall(int /* clientReference */)
254 flipflop = !flipflop;
255 #ifndef GRADIENT_DRAWING
257 BoxStack::getInstance()->update(this, &clockRegion);
260 BoxStack::getInstance()->update(this, &indicatorsRegion);
263 BoxStack::getInstance()->update(this);
267 int VTimerList::handleCommand(int command)
275 BoxStack::getInstance()->update(this);
276 return BoxStack::COMMAND_HANDLED;
282 BoxStack::getInstance()->update(this);
283 return BoxStack::COMMAND_HANDLED;
285 case Input::SKIPBACK:
289 BoxStack::getInstance()->update(this);
290 return BoxStack::COMMAND_HANDLED;
292 case Input::SKIPFORWARD:
296 BoxStack::getInstance()->update(this);
297 return BoxStack::COMMAND_HANDLED;
301 RecTimer* recTimer = NULL;
302 if (recTimerList) recTimer = reinterpret_cast<RecTimer*>(sl.getCurrentOptionData());
303 if (recTimer == NULL) return BoxStack::COMMAND_HANDLED;
305 VTimerEdit* v = new VTimerEdit(recTimer);
308 BoxStack::getInstance()->add(v);
309 BoxStack::getInstance()->update(v);
311 return BoxStack::COMMAND_HANDLED;
315 return BoxStack::DELETE_ME;
318 // stop command getting to any more views
319 return BoxStack::ABANDON_COMMAND;
322 void VTimerList::processMessage(Message* m)
324 if (m->message == Message::MOUSE_MOVE)
326 if (sl.mouseMove(m->parameter - getScreenX(), m->tag - getScreenY()))
329 BoxStack::getInstance()->update(this);
332 else if (m->message == Message::MOUSE_LBDOWN)
334 if (sl.mouseLBDOWN(m->parameter - getScreenX(), m->tag - getScreenY()))
336 Input::sendInputKey(Input::OK);
338 else if (coordsOutsideBox(m))
340 Input::sendInputKey(Input::BACK);
343 else if (m->message == Message::DELETE_SELECTED_TIMER)
345 RecTimer* recTimer = reinterpret_cast<RecTimer*>(sl.getCurrentOptionData());
346 if (recTimer == NULL) return;
347 LogNT::getInstance()->debug(TAG, "Got timer to delete");
350 u4 retval = VDR::getInstance()->deleteTimer(recTimer);
351 if (!VDR::getInstance()->isConnected()) { Control::getInstance()->connectionLost(); return; }
352 LogNT::getInstance()->debug(TAG, "Got return fron delete timer: {}", retval);
356 VInfo* errorBox = new VInfo();
357 errorBox->setSize(360, 200);
358 errorBox->createBuffer();
359 if (Video::getInstance()->getFormat() == Video::PAL)
360 errorBox->setPosition(190, 170);
362 errorBox->setPosition(180, 120);
365 if (retval == 1) errorBox->setOneLiner(tr("Timers being edited at VDR, please try later"));
366 else if (retval == 3) errorBox->setOneLiner(tr("Unable to delete timer - timer is running"));
367 else if (retval == 4) errorBox->setOneLiner(tr("Error - timer not found at VDR"));
368 else errorBox->setOneLiner(tr("Unknown error"));
370 errorBox->setExitable();
371 errorBox->setBorderOn(1);
372 errorBox->setTitleBarColour(DrawStyle::DANGER);
373 errorBox->okButton();
375 BoxStack::getInstance()->add(errorBox);
376 BoxStack::getInstance()->update(errorBox);
379 int saveIndex = sl.getCurrentOption();
380 int saveTop = sl.getTopOption();
384 for (u4 i = 0; i < recTimerList->size(); i++)
386 delete (*recTimerList)[i];
389 recTimerList->clear();
396 sl.hintSetCurrent(saveIndex);
397 sl.hintSetTop(saveTop);
399 BoxStack::getInstance()->update(this);