MythTV master
welcomedialog.cpp
Go to the documentation of this file.
1// POSIX
2#include <unistd.h>
3
4// C++
5#include <chrono>
6#include <cstdlib>
7
8// qt
9#include <QEvent>
10#include <QGuiApplication>
11#include <QKeyEvent>
12
13// myth
14#include "libmythbase/compat.h"
22#include "libmythtv/tv.h"
23
24// mythwelcome
25#include "welcomedialog.h"
26#include "welcomesettings.h"
27
28static constexpr std::chrono::milliseconds UPDATE_STATUS_INTERVAL { 30s };
29static constexpr std::chrono::milliseconds UPDATE_SCREEN_INTERVAL { 15s };
30
31
33 :MythScreenType(parent, name),
34 m_updateStatusTimer(new QTimer(this)),
35 m_updateScreenTimer(new QTimer(this))
36{
38
40 m_preRollSeconds = gCoreContext->GetDurSetting<std::chrono::seconds>("RecordPreRoll");
42 gCoreContext->GetDurSetting<std::chrono::minutes>("idleWaitForRecordingTime", 15min);
43 m_idleTimeoutSecs = gCoreContext->GetDurSetting<std::chrono::seconds>("idleTimeoutSecs", 0s);
44
45 // if idleTimeoutSecs is 0, the user disabled the auto-shutdown feature
47
51
54}
55
57{
58 // Load the theme for this screen
59 bool foundtheme = LoadWindowFromXML("welcome-ui.xml", "welcome_screen", this);
60 if (!foundtheme)
61 return false;
62
63 bool err = false;
64 UIUtilE::Assign(this, m_statusText, "status_text", &err);
65 UIUtilE::Assign(this, m_recordingText, "recording_text", &err);
66 UIUtilE::Assign(this, m_scheduledText, "scheduled_text", &err);
67 UIUtilE::Assign(this, m_warningText, "conflicts_text", &err);
68 UIUtilE::Assign(this, m_startFrontendButton, "startfrontend_button", &err);
69
70 if (err)
71 {
72 LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'welcome_screen'");
73 return false;
74 }
75
77
78 m_startFrontendButton->SetText(tr("Start Frontend"));
81
83
85
88
89 return true;
90}
91
93{
94 QString startFECmd = gCoreContext->GetSetting("MythWelcomeStartFECmd",
95 m_appBinDir + "mythfrontend");
96
97 // Ensure we use the same platform for mythfrontend
98 QStringList args;
99 if (!startFECmd.contains("platform"))
100 args << QString("--platform %1").arg(QGuiApplication::platformName());
102 updateAll();
103 m_frontendIsRunning = false;
104}
105
107{
109 return;
110
111 m_frontendIsRunning = true;
112
113 // this makes sure the button appears to click properly
114 QTimer::singleShot(500ms, this, &WelcomeDialog::startFrontend);
115}
116
118{
119 // mythshutdown --startup returns 0 for automatic startup
120 // 1 for manual startup
121 QString command = m_appBinDir + "mythshutdown --startup";
122 command += logPropagateArgs;
123 uint state = myth_system(command, kMSDontBlockInputDevs);
124
125 LOG(VB_GENERAL, LOG_NOTICE,
126 QString("mythshutdown --startup returned: %1").arg(state));
127
128 bool bAutoStartFrontend = gCoreContext->GetBoolSetting("AutoStartFrontend", true);
129
130 if (state == 1 && bAutoStartFrontend)
132
133 // update status now
134 updateAll();
135}
136
138{
139 if (e->type() == MythEvent::kMythEventMessage)
140 {
141 auto *me = dynamic_cast<MythEvent *>(e);
142 if (me == nullptr)
143 return;
144
145 if (me->Message().startsWith("RECORDING_LIST_CHANGE") ||
146 me->Message() == "UPDATE_PROG_INFO")
147 {
148 LOG(VB_GENERAL, LOG_NOTICE,
149 "MythWelcome received a recording list change event");
150
151 QMutexLocker lock(&m_recListUpdateMuxtex);
152
154 {
155 LOG(VB_GENERAL, LOG_NOTICE,
156 " [deferred to pending handler]");
157 }
158 else
159 {
160 // we can't query the backend from inside a customEvent
161 QTimer::singleShot(500ms, this, &WelcomeDialog::updateRecordingList);
163 }
164 }
165 else if (me->Message().startsWith("SCHEDULE_CHANGE"))
166 {
167 LOG(VB_GENERAL, LOG_NOTICE,
168 "MythWelcome received a SCHEDULE_CHANGE event");
169
170 QMutexLocker lock(&m_schedUpdateMuxtex);
171
172 if (pendingSchedUpdate())
173 {
174 LOG(VB_GENERAL, LOG_NOTICE,
175 " [deferred to pending handler]");
176 }
177 else
178 {
179 QTimer::singleShot(500ms, this, &WelcomeDialog::updateScheduledList);
181 }
182 }
183 else if (me->Message().startsWith("SHUTDOWN_COUNTDOWN"))
184 {
185#if 0
186 LOG(VB_GENERAL, LOG_NOTICE,
187 "MythWelcome received a SHUTDOWN_COUNTDOWN event");
188#endif
189 QString secs = me->Message().mid(19);
190 m_secondsToShutdown = secs.toInt();
192 updateScreen();
193 }
194 else if (me->Message().startsWith("SHUTDOWN_NOW"))
195 {
196 LOG(VB_GENERAL, LOG_NOTICE,
197 "MythWelcome received a SHUTDOWN_NOW event");
199 {
200 // does the user want to shutdown this frontend only machine
201 // when the BE shuts down?
202 if (gCoreContext->GetNumSetting("ShutdownWithMasterBE", 0) == 1)
203 {
204 LOG(VB_GENERAL, LOG_NOTICE,
205 "MythWelcome is shutting this computer down now");
206 QString poweroff_cmd = gCoreContext->GetSetting("MythShutdownPowerOff", "");
207 if (!poweroff_cmd.isEmpty())
208 myth_system(poweroff_cmd, kMSDontBlockInputDevs);
209 }
210 }
211 }
212 }
213}
214
216{
218 auto *ssd = new StandardSettingDialog(mainStack, "settings", screen);
219 if (ssd->Create())
220 mainStack->AddScreen(ssd);
221 else
222 delete ssd;
223}
224
225bool WelcomeDialog::keyPressEvent(QKeyEvent *event)
226{
227 if (GetFocusWidget()->keyPressEvent(event))
228 return true;
229
230 QStringList actions;
231 bool handled = GetMythMainWindow()->TranslateKeyPress("Welcome", event, actions);
232
233 for (int i = 0; i < actions.size() && !handled; i++)
234 {
235 const QString& action = actions[i];
236 handled = true;
237
238 if (action == "ESCAPE")
239 {
240 return true; // eat escape key
241 }
242 if (action == "MENU")
243 {
244 ShowMenu();
245 }
246 else if (action == "NEXTVIEW")
247 {
248 Close();
249 }
250 else if (action == "INFO")
251 {
253 }
254 else if (action == "SHOWSETTINGS")
255 {
257 }
258 else if (action == "0")
259 {
260 QString mythshutdown_status =
261 m_appBinDir + "mythshutdown --status 0";
262 QString mythshutdown_unlock =
263 m_appBinDir + "mythshutdown --unlock";
264 QString mythshutdown_lock =
265 m_appBinDir + "mythshutdown --lock";
266
267 uint statusCode =
268 myth_system(mythshutdown_status + logPropagateArgs, kMSDontBlockInputDevs);
269
270 // is shutdown locked by a user
271 if (!(statusCode & 0xFF00) && statusCode & 16)
272 {
273 myth_system(mythshutdown_unlock + logPropagateArgs, kMSDontBlockInputDevs);
274 }
275 else
276 {
278 }
279
281 updateScreen();
282 }
283 else if (action == "STARTXTERM")
284 {
285 QString cmd = gCoreContext->GetSetting("MythShutdownXTermCmd", "");
286 if (!cmd.isEmpty())
288 }
289 else if (action == "STARTSETUP")
290 {
291 QString mythtv_setup = m_appBinDir + "mythtv-setup";
292 myth_system(mythtv_setup + logPropagateArgs);
293 }
294 else
295 {
296 handled = false;
297 }
298 }
299
300 if (!handled && MythScreenType::keyPressEvent(event))
301 handled = true;
302
303 return handled;
304}
305
307{
308 Close();
309}
310
312{
314
316 m_updateStatusTimer->disconnect();
317
319 m_updateScreenTimer->disconnect();
320}
321
323{
325
327}
328
330{
331 QString status;
332
334 {
335 m_recordingText->SetText(tr("Cannot connect to server!"));
336 m_scheduledText->SetText(tr("Cannot connect to server!"));
338 }
339 else
340 {
341 // update recording
342 if (m_isRecording && !m_tunerList.empty())
343 {
345
346 while (!tuner.isRecording)
347 {
348 if (m_screenTunerNo < m_tunerList.size() - 1)
350 else
351 m_screenTunerNo = 0;
353 }
354
355 status = tr("Tuner %1 is recording:").arg(tuner.id);
356 status += "\n";
357 status += tuner.channame;
358 status += "\n" + tuner.title;
359 if (!tuner.subtitle.isEmpty())
360 status += "\n("+tuner.subtitle+")";
361
362 status += "\n" +
363 tr("%1 to %2", "Time period, 'starttime to endtime'")
366 }
367 else
368 {
369 status = tr("There are no recordings currently taking place");
370 }
371
372 m_recordingText->SetText(status);
373
374 // update scheduled
375 if (!m_scheduledList.empty())
376 {
379
381
382 InfoMap infomap;
383 progInfo.ToMap(infomap);
384
385 //status = QString("%1 of %2\n").arg(m_screenScheduledNo + 1)
386 // .arg(m_scheduledList.size());
387 status = infomap["channame"] + "\n";
388 status += infomap["title"];
389 if (!infomap["subtitle"].isEmpty())
390 status += "\n(" + infomap["subtitle"] + ")";
391
392 status += "\n" + infomap["timedate"];
393
394 if (m_screenScheduledNo < m_scheduledList.size() - 1)
396 else
398 }
399 else
400 {
401 status = tr("There are no scheduled recordings");
402 }
403
404 m_scheduledText->SetText(status);
405 }
406
407 // update status message
408 if (m_statusList.empty())
409 status = tr("Please Wait...");
410 else
411 {
412 if ((int)m_statusListNo >= m_statusList.count())
413 m_statusListNo = 0;
414
416 if (m_statusList.count() > 1)
417 status += "...";
418 m_statusText->SetText(status);
419
420 if ((int)m_statusListNo < m_statusList.count() - 1)
422 else
423 m_statusListNo = 0;
424 }
425
426 m_updateScreenTimer->stop();
427 m_updateScreenTimer->setSingleShot(true);
429}
430
431// taken from housekeeper.cpp
433{
434 QString command;
435
436 QString mfpath = gCoreContext->GetSetting("MythFillDatabasePath",
437 "mythfilldatabase");
438 QString mfarg = gCoreContext->GetSetting("MythFillDatabaseArgs", "");
439
440 command = QString("%1 %2").arg(mfpath, mfarg);
441 command += logPropagateArgs;
442
443 command += "&";
444
445 LOG(VB_GENERAL, LOG_INFO, QString("Grabbing EPG data using command: %1\n")
446 .arg(command));
447
449}
450
452{
455}
456
458{
459 {
460 // clear pending flag early in case something happens while
461 // we're updating
462 QMutexLocker lock(&m_recListUpdateMuxtex);
464 }
465
466 m_tunerList.clear();
467 m_isRecording = false;
468 m_screenTunerNo = 0;
469
471 return false;
472
474
475 return true;
476}
477
479{
480 {
481 // clear pending flag early in case something happens while
482 // we're updating
483 QMutexLocker lock(&m_schedUpdateMuxtex);
485 }
486
487 m_scheduledList.clear();
489
491 {
493 return false;
494 }
495
498
499 updateStatus();
500 updateScreen();
501
502 return true;
503}
504
506{
507 m_statusList.clear();
508
509 QDateTime curtime = MythDate::current();
510
511 if (!m_isRecording && !m_nextRecordingStart.isNull() &&
512 std::chrono::seconds(curtime.secsTo(m_nextRecordingStart)) - m_preRollSeconds <
514 {
515 m_statusList.append(tr("MythTV is about to start recording."));
516 }
517
518 if (m_isRecording)
519 {
520 m_statusList.append(tr("MythTV is busy recording."));
521 }
522
523 QString mythshutdown_status = m_appBinDir + "mythshutdown --status 0";
524 uint statusCode = myth_system(mythshutdown_status + logPropagateArgs, kMSDontBlockInputDevs);
525
526 if (!(statusCode & 0xFF00))
527 {
528 if (statusCode & 1)
529 m_statusList.append(tr("MythTV is busy transcoding."));
530 if (statusCode & 2)
531 m_statusList.append(tr("MythTV is busy flagging commercials."));
532 if (statusCode & 4)
533 m_statusList.append(tr("MythTV is busy grabbing EPG data."));
534 if (statusCode & 16)
535 m_statusList.append(tr("MythTV is locked by a user."));
536 if (statusCode & 32)
537 m_statusList.append(tr("MythTV has running or pending jobs."));
538 if (statusCode & 64)
539 m_statusList.append(tr("MythTV is in a daily wakeup/shutdown period."));
540 if (statusCode & 128)
541 m_statusList.append(tr("MythTV is about to start a wakeup/shutdown period."));
542 }
543
544 if (m_statusList.empty())
545 {
547 {
548 m_statusList.append(tr("MythTV is idle and will shutdown in %n "
549 "second(s).", "", m_secondsToShutdown));
550 }
551 else
552 {
553 m_statusList.append(tr("MythTV is idle."));
554 }
555 }
556
558}
559
561{
562 m_updateStatusTimer->stop();
563
564 bool bRes = false;
565
567 bRes = true;
568 else
569 {
571 {
572 bRes = true;
573 updateAll();
574 }
575 else
576 {
577 updateScreen();
578 }
579 }
580
581 if (bRes)
583 else
584 m_updateStatusTimer->start(5s);
585
586 return bRes;
587}
588
590{
591 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
592
593 m_menuPopup = new MythDialogBox("Menu", popupStack, "actionmenu");
594
595 if (m_menuPopup->Create())
596 popupStack->AddScreen(m_menuPopup);
597
598 m_menuPopup->SetReturnEvent(this, "action");
599
600 QString mythshutdown_status = m_appBinDir + "mythshutdown --status 0";
601 uint statusCode = myth_system(mythshutdown_status + logPropagateArgs, kMSDontBlockInputDevs);
602
603 if (!(statusCode & 0xFF00) && statusCode & 16)
604 m_menuPopup->AddButton(tr("Unlock Shutdown"), &WelcomeDialog::unlockShutdown);
605 else
606 m_menuPopup->AddButton(tr("Lock Shutdown"), &WelcomeDialog::lockShutdown);
607
608 m_menuPopup->AddButton(tr("Run mythfilldatabase"), &WelcomeDialog::runEPGGrabber);
609 m_menuPopup->AddButton(tr("Shutdown Now"), &WelcomeDialog::shutdownNow);
611 m_menuPopup->AddButton(tr("Cancel"));
612}
613
615{
616 QString command = m_appBinDir + "mythshutdown --lock";
617 command += logPropagateArgs;
620 updateScreen();
621}
622
624{
625 QString command = m_appBinDir + "mythshutdown --unlock";
626 command += logPropagateArgs;
629 updateScreen();
630}
631
633{
635 sleep(1);
637 updateScreen();
638}
639
641{
642 // if this is a frontend only machine just shut down now
644 {
645 LOG(VB_GENERAL, LOG_INFO,
646 "MythWelcome is shutting this computer down now");
647 QString poweroff_cmd = gCoreContext->GetSetting("MythShutdownPowerOff", "");
648 if (!poweroff_cmd.isEmpty())
649 myth_system(poweroff_cmd, kMSDontBlockInputDevs);
650 return;
651 }
652
653 // don't shutdown if we are recording
654 if (m_isRecording)
655 {
656 ShowOkPopup(tr("Cannot shutdown because MythTV is currently recording"));
657 return;
658 }
659
660 QDateTime curtime = MythDate::current();
661
662 // don't shutdown if we are about to start recording
663 if (!m_nextRecordingStart.isNull() &&
664 std::chrono::seconds(curtime.secsTo(m_nextRecordingStart)) - m_preRollSeconds <
666 {
667 ShowOkPopup(tr("Cannot shutdown because MythTV is about to start recording"));
668 return;
669 }
670
671 // don't shutdown if we are about to start a wakeup/shutdown period
672 QString command = m_appBinDir + "mythshutdown --status 0";
673 command += logPropagateArgs;
674
675 uint statusCode = myth_system(command, kMSDontBlockInputDevs);
676 if (!(statusCode & 0xFF00) && statusCode & 128)
677 {
678 ShowOkPopup(tr("Cannot shutdown because MythTV is about to start "
679 "a wakeup/shutdown period."));
680 return;
681 }
682
683 // set the wakeup time for the next scheduled recording
684 if (!m_nextRecordingStart.isNull())
685 {
686 QDateTime restarttime = m_nextRecordingStart.addSecs((-1) * m_preRollSeconds.count());
687
688 int add = gCoreContext->GetNumSetting("StartupSecsBeforeRecording", 240);
689 if (add)
690 restarttime = restarttime.addSecs((-1LL) * add);
691
692 QString wakeup_timeformat = gCoreContext->GetSetting("WakeupTimeFormat",
693 "yyyy-MM-ddThh:mm");
694 QString setwakeup_cmd = gCoreContext->GetSetting("SetWakeuptimeCommand",
695 "echo \'Wakeuptime would "
696 "be $time if command "
697 "set.\'");
698
699 if (wakeup_timeformat == "time_t")
700 {
701 QString time_ts;
702 setwakeup_cmd.replace("$time",
703 time_ts.setNum(restarttime.toSecsSinceEpoch())
704 );
705 }
706 else
707 {
708 setwakeup_cmd.replace(
709 "$time", restarttime.toLocalTime().toString(wakeup_timeformat));
710 }
711
712 if (!setwakeup_cmd.isEmpty())
713 {
714 myth_system(setwakeup_cmd, kMSDontBlockInputDevs);
715 }
716 }
717
718 // run command to set wakeuptime in bios and shutdown the system
719 command = QString();
720
721#ifndef _WIN32
722 command = "sudo ";
723#endif
724
725 command += m_appBinDir + "mythshutdown --shutdown" + logPropagateArgs;
726
728}
729
bool IsConnectedToMaster(void)
bool SafeConnectToMasterServer(bool blockingClient=true, bool openEventSocket=true)
QString GetSetting(const QString &key, const QString &defaultval="")
bool IsFrontendOnly(void)
is there a frontend, but no backend, running on this host
int GetNumSetting(const QString &key, int defaultval=0)
std::enable_if_t< std::chrono::__is_duration< T >::value, T > GetDurSetting(const QString &key, T defaultval=T::zero())
bool GetBoolSetting(const QString &key, bool defaultval=false)
Basic menu dialog, message and a list of options.
void AddButton(const QString &title)
void SetReturnEvent(QObject *retobject, const QString &resultid)
bool Create(void) override
This class is used as a container for messages.
Definition: mythevent.h:17
static const Type kMythEventMessage
Definition: mythevent.h:79
MythScreenStack * GetMainStack()
bool TranslateKeyPress(const QString &Context, QKeyEvent *Event, QStringList &Actions, bool AllowJumps=true)
Get a list of actions for a keypress in the given context.
MythScreenStack * GetStack(const QString &Stackname)
void addListener(QObject *listener)
Add a listener to the observable.
void removeListener(QObject *listener)
Remove a listener to the observable.
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Screen in which all other widgets are contained and rendered.
void BuildFocusList(void)
MythUIType * GetFocusWidget(void) const
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
bool SetFocusWidget(MythUIType *widget=nullptr)
virtual void Close()
void SetText(const QString &msg)
void Clicked()
virtual void SetText(const QString &text)
Definition: mythuitext.cpp:115
virtual void SetVisible(bool visible)
Holds information on recordings and videos.
Definition: programinfo.h:70
virtual void ToMap(InfoMap &progMap, bool showrerecord=false, uint star_range=10, uint date_format=0) const
Converts ProgramInfo into QString QHash containing each field in ProgramInfo converted into localized...
recording status stuff
Definition: tvremoteutil.h:17
bool isRecording
Definition: tvremoteutil.h:20
QDateTime endTime
Definition: tvremoteutil.h:25
QString subtitle
Definition: tvremoteutil.h:23
QString channame
Definition: tvremoteutil.h:21
QString title
Definition: tvremoteutil.h:22
QDateTime startTime
Definition: tvremoteutil.h:24
QTimer * m_updateScreenTimer
Definition: welcomedialog.h:66
QString m_appBinDir
Definition: welcomedialog.h:68
void setPendingSchedUpdate(bool newState)
Definition: welcomedialog.h:96
std::vector< TunerStatus > m_tunerList
Definition: welcomedialog.h:83
void lockShutdown(void)
bool checkConnectionToServer(void)
QDateTime m_nextRecordingStart
Definition: welcomedialog.h:73
void checkAutoStart(void)
void ShowMenu(void) override
bool updateRecordingList(void)
void customEvent(QEvent *e) override
bool pendingSchedUpdate() const
Definition: welcomedialog.h:95
static void ShowSettings(GroupSetting *screen)
MythUIText * m_recordingText
Definition: welcomedialog.h:57
uint m_screenScheduledNo
Definition: welcomedialog.h:78
std::chrono::seconds m_preRollSeconds
Definition: welcomedialog.h:74
QTimer * m_updateStatusTimer
Definition: welcomedialog.h:65
MythUIButton * m_startFrontendButton
Definition: welcomedialog.h:61
uint m_screenTunerNo
Definition: welcomedialog.h:77
std::chrono::seconds m_idleWaitForRecordingTime
Definition: welcomedialog.h:75
void startFrontendClick(void)
void setPendingRecListUpdate(bool newState)
Definition: welcomedialog.h:90
QMutex m_recListUpdateMuxtex
Definition: welcomedialog.h:86
std::chrono::seconds m_idleTimeoutSecs
Definition: welcomedialog.h:76
MythUIText * m_warningText
Definition: welcomedialog.h:59
void runEPGGrabber(void)
int m_secondsToShutdown
Definition: welcomedialog.h:72
MythUIText * m_statusText
Definition: welcomedialog.h:56
QMutex m_schedUpdateMuxtex
Definition: welcomedialog.h:92
void updateStatus(void)
bool Create(void) override
~WelcomeDialog() override
void updateAll(void)
QStringList m_statusList
Definition: welcomedialog.h:80
bool m_frontendIsRunning
Definition: welcomedialog.h:81
void shutdownNow(void)
std::vector< ProgramInfo > m_scheduledList
Definition: welcomedialog.h:84
WelcomeDialog(MythScreenStack *parent, const char *name)
void updateScreen(void)
static void runMythFillDatabase(void)
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
MythDialogBox * m_menuPopup
Definition: welcomedialog.h:63
MythUIText * m_scheduledText
Definition: welcomedialog.h:58
bool updateScheduledList(void)
void updateStatusMessage(void)
bool pendingRecListUpdate() const
Definition: welcomedialog.h:89
void startFrontend(void)
void unlockShutdown(void)
void closeDialog(void)
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
unsigned int uint
Definition: compat.h:68
QString logPropagateArgs
Definition: logging.cpp:82
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
MythConfirmationDialog * ShowOkPopup(const QString &message, bool showCancel)
Non-blocking version of MythPopupBox::showOkPopup()
QString GetAppBinDir(void)
Definition: mythdirs.cpp:260
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MythMainWindow * GetMythMainWindow(void)
@ kMSDontBlockInputDevs
avoid blocking LIRC & Joystick Menu
Definition: mythsystem.h:36
@ kMSProcessEvents
process events while waiting
Definition: mythsystem.h:39
@ kMSDisableUDPListener
disable MythMessage UDP listener for the duration of application.
Definition: mythsystem.h:50
uint myth_system(const QString &command, uint flags, std::chrono::seconds timeout)
QHash< QString, QString > InfoMap
Definition: mythtypes.h:15
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
Definition: mythdate.cpp:93
@ kTime
Default local time.
Definition: mythdate.h:22
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:15
bool GetNextRecordingList(QDateTime &nextRecordingStart, bool *hasConflicts, std::vector< ProgramInfo > *list)
static bool Assign(ContainerType *container, UIType *&item, const QString &name, bool *err=nullptr)
Definition: mythuiutils.h:27
bool RemoteGetRecordingStatus(std::vector< TunerStatus > *tunerList, bool list_inactive)
static constexpr std::chrono::milliseconds UPDATE_SCREEN_INTERVAL
static constexpr std::chrono::milliseconds UPDATE_STATUS_INTERVAL