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 <QtGlobal>
10#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
11#include <QtSystemDetection>
12#endif
13#include <QEvent>
14#include <QGuiApplication>
15#include <QKeyEvent>
16
17// myth
18#include "libmythbase/compat.h"
26#include "libmythtv/tv.h"
27
28// mythwelcome
29#include "welcomedialog.h"
30#include "welcomesettings.h"
31
32static constexpr std::chrono::milliseconds UPDATE_STATUS_INTERVAL { 30s };
33static constexpr std::chrono::milliseconds UPDATE_SCREEN_INTERVAL { 15s };
34
35
37 :MythScreenType(parent, name),
38 m_updateStatusTimer(new QTimer(this)),
39 m_updateScreenTimer(new QTimer(this))
40{
42
44 m_preRollSeconds = gCoreContext->GetDurSetting<std::chrono::seconds>("RecordPreRoll");
46 gCoreContext->GetDurSetting<std::chrono::minutes>("idleWaitForRecordingTime", 15min);
47 m_idleTimeoutSecs = gCoreContext->GetDurSetting<std::chrono::seconds>("idleTimeoutSecs", 0s);
48
49 // if idleTimeoutSecs is 0, the user disabled the auto-shutdown feature
51
55
58}
59
61{
62 // Load the theme for this screen
63 bool foundtheme = LoadWindowFromXML("welcome-ui.xml", "welcome_screen", this);
64 if (!foundtheme)
65 return false;
66
67 bool err = false;
68 UIUtilE::Assign(this, m_statusText, "status_text", &err);
69 UIUtilE::Assign(this, m_recordingText, "recording_text", &err);
70 UIUtilE::Assign(this, m_scheduledText, "scheduled_text", &err);
71 UIUtilE::Assign(this, m_warningText, "conflicts_text", &err);
72 UIUtilE::Assign(this, m_startFrontendButton, "startfrontend_button", &err);
73
74 if (err)
75 {
76 LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'welcome_screen'");
77 return false;
78 }
79
81
82 m_startFrontendButton->SetText(tr("Start Frontend"));
85
87
89
92
93 return true;
94}
95
97{
98 QString startFECmd = gCoreContext->GetSetting("MythWelcomeStartFECmd",
99 m_appBinDir + "mythfrontend");
100
101 // Ensure we use the same platform for mythfrontend
102 QStringList args;
103 if (!startFECmd.contains("platform"))
104 args << QString("--platform %1").arg(QGuiApplication::platformName());
106 updateAll();
107 m_frontendIsRunning = false;
108}
109
111{
113 return;
114
115 m_frontendIsRunning = true;
116
117 // this makes sure the button appears to click properly
118 QTimer::singleShot(500ms, this, &WelcomeDialog::startFrontend);
119}
120
122{
123 // mythshutdown --startup returns 0 for automatic startup
124 // 1 for manual startup
125 QString command = m_appBinDir + "mythshutdown --startup";
126 command += logPropagateArgs;
127 uint state = myth_system(command, kMSDontBlockInputDevs);
128
129 LOG(VB_GENERAL, LOG_NOTICE,
130 QString("mythshutdown --startup returned: %1").arg(state));
131
132 bool bAutoStartFrontend = gCoreContext->GetBoolSetting("AutoStartFrontend", true);
133
134 if (state == 1 && bAutoStartFrontend)
136
137 // update status now
138 updateAll();
139}
140
142{
143 if (e->type() == MythEvent::kMythEventMessage)
144 {
145 auto *me = dynamic_cast<MythEvent *>(e);
146 if (me == nullptr)
147 return;
148
149 if (me->Message().startsWith("RECORDING_LIST_CHANGE") ||
150 me->Message() == "UPDATE_PROG_INFO")
151 {
152 LOG(VB_GENERAL, LOG_NOTICE,
153 "MythWelcome received a recording list change event");
154
155 QMutexLocker lock(&m_recListUpdateMuxtex);
156
158 {
159 LOG(VB_GENERAL, LOG_NOTICE,
160 " [deferred to pending handler]");
161 }
162 else
163 {
164 // we can't query the backend from inside a customEvent
165 QTimer::singleShot(500ms, this, &WelcomeDialog::updateRecordingList);
167 }
168 }
169 else if (me->Message().startsWith("SCHEDULE_CHANGE"))
170 {
171 LOG(VB_GENERAL, LOG_NOTICE,
172 "MythWelcome received a SCHEDULE_CHANGE event");
173
174 QMutexLocker lock(&m_schedUpdateMuxtex);
175
176 if (pendingSchedUpdate())
177 {
178 LOG(VB_GENERAL, LOG_NOTICE,
179 " [deferred to pending handler]");
180 }
181 else
182 {
183 QTimer::singleShot(500ms, this, &WelcomeDialog::updateScheduledList);
185 }
186 }
187 else if (me->Message().startsWith("SHUTDOWN_COUNTDOWN"))
188 {
189#if 0
190 LOG(VB_GENERAL, LOG_NOTICE,
191 "MythWelcome received a SHUTDOWN_COUNTDOWN event");
192#endif
193 QString secs = me->Message().mid(19);
194 m_secondsToShutdown = secs.toInt();
196 updateScreen();
197 }
198 else if (me->Message().startsWith("SHUTDOWN_NOW"))
199 {
200 LOG(VB_GENERAL, LOG_NOTICE,
201 "MythWelcome received a SHUTDOWN_NOW event");
203 {
204 // does the user want to shutdown this frontend only machine
205 // when the BE shuts down?
206 if (gCoreContext->GetNumSetting("ShutdownWithMasterBE", 0) == 1)
207 {
208 LOG(VB_GENERAL, LOG_NOTICE,
209 "MythWelcome is shutting this computer down now");
210 QString poweroff_cmd = gCoreContext->GetSetting("MythShutdownPowerOff", "");
211 if (!poweroff_cmd.isEmpty())
212 myth_system(poweroff_cmd, kMSDontBlockInputDevs);
213 }
214 }
215 }
216 }
217}
218
220{
222 auto *ssd = new StandardSettingDialog(mainStack, "settings", screen);
223 if (ssd->Create())
224 mainStack->AddScreen(ssd);
225 else
226 delete ssd;
227}
228
229bool WelcomeDialog::keyPressEvent(QKeyEvent *event)
230{
231 if (GetFocusWidget()->keyPressEvent(event))
232 return true;
233
234 QStringList actions;
235 bool handled = GetMythMainWindow()->TranslateKeyPress("Welcome", event, actions);
236
237 for (int i = 0; i < actions.size() && !handled; i++)
238 {
239 const QString& action = actions[i];
240 handled = true;
241
242 if (action == "ESCAPE")
243 {
244 return true; // eat escape key
245 }
246 if (action == "MENU")
247 {
248 ShowMenu();
249 }
250 else if (action == "NEXTVIEW")
251 {
252 Close();
253 }
254 else if (action == "INFO")
255 {
257 }
258 else if (action == "SHOWSETTINGS")
259 {
261 }
262 else if (action == "0")
263 {
264 QString mythshutdown_status =
265 m_appBinDir + "mythshutdown --status 0";
266 QString mythshutdown_unlock =
267 m_appBinDir + "mythshutdown --unlock";
268 QString mythshutdown_lock =
269 m_appBinDir + "mythshutdown --lock";
270
271 uint statusCode =
272 myth_system(mythshutdown_status + logPropagateArgs, kMSDontBlockInputDevs);
273
274 // is shutdown locked by a user
275 if (!(statusCode & 0xFF00) && statusCode & 16)
276 {
277 myth_system(mythshutdown_unlock + logPropagateArgs, kMSDontBlockInputDevs);
278 }
279 else
280 {
282 }
283
285 updateScreen();
286 }
287 else if (action == "STARTXTERM")
288 {
289 QString cmd = gCoreContext->GetSetting("MythShutdownXTermCmd", "");
290 if (!cmd.isEmpty())
292 }
293 else if (action == "STARTSETUP")
294 {
295 QString mythtv_setup = m_appBinDir + "mythtv-setup";
296 myth_system(mythtv_setup + logPropagateArgs);
297 }
298 else
299 {
300 handled = false;
301 }
302 }
303
304 if (!handled && MythScreenType::keyPressEvent(event))
305 handled = true;
306
307 return handled;
308}
309
311{
312 Close();
313}
314
316{
318
320 m_updateStatusTimer->disconnect();
321
323 m_updateScreenTimer->disconnect();
324}
325
327{
329
331}
332
334{
335 QString status;
336
338 {
339 m_recordingText->SetText(tr("Cannot connect to server!"));
340 m_scheduledText->SetText(tr("Cannot connect to server!"));
342 }
343 else
344 {
345 // update recording
346 if (m_isRecording && !m_tunerList.empty())
347 {
349
350 while (!tuner.isRecording)
351 {
352 if (m_screenTunerNo < m_tunerList.size() - 1)
354 else
355 m_screenTunerNo = 0;
357 }
358
359 status = tr("Tuner %1 is recording:").arg(tuner.id);
360 status += "\n";
361 status += tuner.channame;
362 status += "\n" + tuner.title;
363 if (!tuner.subtitle.isEmpty())
364 status += "\n("+tuner.subtitle+")";
365
366 status += "\n" +
367 tr("%1 to %2", "Time period, 'starttime to endtime'")
370 }
371 else
372 {
373 status = tr("There are no recordings currently taking place");
374 }
375
376 m_recordingText->SetText(status);
377
378 // update scheduled
379 if (!m_scheduledList.empty())
380 {
383
385
386 InfoMap infomap;
387 progInfo.ToMap(infomap);
388
389 //status = QString("%1 of %2\n").arg(m_screenScheduledNo + 1)
390 // .arg(m_scheduledList.size());
391 status = infomap["channame"] + "\n";
392 status += infomap["title"];
393 if (!infomap["subtitle"].isEmpty())
394 status += "\n(" + infomap["subtitle"] + ")";
395
396 status += "\n" + infomap["timedate"];
397
398 if (m_screenScheduledNo < m_scheduledList.size() - 1)
400 else
402 }
403 else
404 {
405 status = tr("There are no scheduled recordings");
406 }
407
408 m_scheduledText->SetText(status);
409 }
410
411 // update status message
412 if (m_statusList.empty())
413 status = tr("Please Wait...");
414 else
415 {
416 if ((int)m_statusListNo >= m_statusList.count())
417 m_statusListNo = 0;
418
420 if (m_statusList.count() > 1)
421 status += "...";
422 m_statusText->SetText(status);
423
424 if ((int)m_statusListNo < m_statusList.count() - 1)
426 else
427 m_statusListNo = 0;
428 }
429
430 m_updateScreenTimer->stop();
431 m_updateScreenTimer->setSingleShot(true);
433}
434
435// taken from housekeeper.cpp
437{
438 QString command;
439
440 QString mfpath = gCoreContext->GetSetting("MythFillDatabasePath",
441 "mythfilldatabase");
442 QString mfarg = gCoreContext->GetSetting("MythFillDatabaseArgs", "");
443
444 command = QString("%1 %2").arg(mfpath, mfarg);
445 command += logPropagateArgs;
446
447 command += "&";
448
449 LOG(VB_GENERAL, LOG_INFO, QString("Grabbing EPG data using command: %1\n")
450 .arg(command));
451
453}
454
456{
459}
460
462{
463 {
464 // clear pending flag early in case something happens while
465 // we're updating
466 QMutexLocker lock(&m_recListUpdateMuxtex);
468 }
469
470 m_tunerList.clear();
471 m_isRecording = false;
472 m_screenTunerNo = 0;
473
475 return false;
476
478
479 return true;
480}
481
483{
484 {
485 // clear pending flag early in case something happens while
486 // we're updating
487 QMutexLocker lock(&m_schedUpdateMuxtex);
489 }
490
491 m_scheduledList.clear();
493
495 {
497 return false;
498 }
499
502
503 updateStatus();
504 updateScreen();
505
506 return true;
507}
508
510{
511 m_statusList.clear();
512
513 QDateTime curtime = MythDate::current();
514
515 if (!m_isRecording && !m_nextRecordingStart.isNull() &&
516 std::chrono::seconds(curtime.secsTo(m_nextRecordingStart)) - m_preRollSeconds <
518 {
519 m_statusList.append(tr("MythTV is about to start recording."));
520 }
521
522 if (m_isRecording)
523 {
524 m_statusList.append(tr("MythTV is busy recording."));
525 }
526
527 QString mythshutdown_status = m_appBinDir + "mythshutdown --status 0";
528 uint statusCode = myth_system(mythshutdown_status + logPropagateArgs, kMSDontBlockInputDevs);
529
530 if (!(statusCode & 0xFF00))
531 {
532 if (statusCode & 1)
533 m_statusList.append(tr("MythTV is busy transcoding."));
534 if (statusCode & 2)
535 m_statusList.append(tr("MythTV is busy flagging commercials."));
536 if (statusCode & 4)
537 m_statusList.append(tr("MythTV is busy grabbing EPG data."));
538 if (statusCode & 16)
539 m_statusList.append(tr("MythTV is locked by a user."));
540 if (statusCode & 32)
541 m_statusList.append(tr("MythTV has running or pending jobs."));
542 if (statusCode & 64)
543 m_statusList.append(tr("MythTV is in a daily wakeup/shutdown period."));
544 if (statusCode & 128)
545 m_statusList.append(tr("MythTV is about to start a wakeup/shutdown period."));
546 }
547
548 if (m_statusList.empty())
549 {
551 {
552 m_statusList.append(tr("MythTV is idle and will shutdown in %n "
553 "second(s).", "", m_secondsToShutdown));
554 }
555 else
556 {
557 m_statusList.append(tr("MythTV is idle."));
558 }
559 }
560
562}
563
565{
566 m_updateStatusTimer->stop();
567
568 bool bRes = false;
569
571 bRes = true;
572 else
573 {
575 {
576 bRes = true;
577 updateAll();
578 }
579 else
580 {
581 updateScreen();
582 }
583 }
584
585 if (bRes)
587 else
588 m_updateStatusTimer->start(5s);
589
590 return bRes;
591}
592
594{
595 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
596
597 m_menuPopup = new MythDialogBox("Menu", popupStack, "actionmenu");
598
599 if (m_menuPopup->Create())
600 popupStack->AddScreen(m_menuPopup);
601
602 m_menuPopup->SetReturnEvent(this, "action");
603
604 QString mythshutdown_status = m_appBinDir + "mythshutdown --status 0";
605 uint statusCode = myth_system(mythshutdown_status + logPropagateArgs, kMSDontBlockInputDevs);
606
607 if (!(statusCode & 0xFF00) && statusCode & 16)
608 m_menuPopup->AddButton(tr("Unlock Shutdown"), &WelcomeDialog::unlockShutdown);
609 else
610 m_menuPopup->AddButton(tr("Lock Shutdown"), &WelcomeDialog::lockShutdown);
611
612 m_menuPopup->AddButton(tr("Run mythfilldatabase"), &WelcomeDialog::runEPGGrabber);
613 m_menuPopup->AddButton(tr("Shutdown Now"), &WelcomeDialog::shutdownNow);
615 m_menuPopup->AddButton(tr("Cancel"));
616}
617
619{
620 QString command = m_appBinDir + "mythshutdown --lock";
621 command += logPropagateArgs;
624 updateScreen();
625}
626
628{
629 QString command = m_appBinDir + "mythshutdown --unlock";
630 command += logPropagateArgs;
633 updateScreen();
634}
635
637{
639 sleep(1);
641 updateScreen();
642}
643
645{
646 // if this is a frontend only machine just shut down now
648 {
649 LOG(VB_GENERAL, LOG_INFO,
650 "MythWelcome is shutting this computer down now");
651 QString poweroff_cmd = gCoreContext->GetSetting("MythShutdownPowerOff", "");
652 if (!poweroff_cmd.isEmpty())
653 myth_system(poweroff_cmd, kMSDontBlockInputDevs);
654 return;
655 }
656
657 // don't shutdown if we are recording
658 if (m_isRecording)
659 {
660 ShowOkPopup(tr("Cannot shutdown because MythTV is currently recording"));
661 return;
662 }
663
664 QDateTime curtime = MythDate::current();
665
666 // don't shutdown if we are about to start recording
667 if (!m_nextRecordingStart.isNull() &&
668 std::chrono::seconds(curtime.secsTo(m_nextRecordingStart)) - m_preRollSeconds <
670 {
671 ShowOkPopup(tr("Cannot shutdown because MythTV is about to start recording"));
672 return;
673 }
674
675 // don't shutdown if we are about to start a wakeup/shutdown period
676 QString command = m_appBinDir + "mythshutdown --status 0";
677 command += logPropagateArgs;
678
679 uint statusCode = myth_system(command, kMSDontBlockInputDevs);
680 if (!(statusCode & 0xFF00) && statusCode & 128)
681 {
682 ShowOkPopup(tr("Cannot shutdown because MythTV is about to start "
683 "a wakeup/shutdown period."));
684 return;
685 }
686
687 // set the wakeup time for the next scheduled recording
688 if (!m_nextRecordingStart.isNull())
689 {
690 QDateTime restarttime = m_nextRecordingStart.addSecs((-1) * m_preRollSeconds.count());
691
692 int add = gCoreContext->GetNumSetting("StartupSecsBeforeRecording", 240);
693 if (add)
694 restarttime = restarttime.addSecs((-1LL) * add);
695
696 QString wakeup_timeformat = gCoreContext->GetSetting("WakeupTimeFormat",
697 "yyyy-MM-ddThh:mm");
698 QString setwakeup_cmd = gCoreContext->GetSetting("SetWakeuptimeCommand",
699 "echo \'Wakeuptime would "
700 "be $time if command "
701 "set.\'");
702
703 if (wakeup_timeformat == "time_t")
704 {
705 QString time_ts;
706 setwakeup_cmd.replace("$time",
707 time_ts.setNum(restarttime.toSecsSinceEpoch())
708 );
709 }
710 else
711 {
712 setwakeup_cmd.replace(
713 "$time", restarttime.toLocalTime().toString(wakeup_timeformat));
714 }
715
716 if (!setwakeup_cmd.isEmpty())
717 {
718 myth_system(setwakeup_cmd, kMSDontBlockInputDevs);
719 }
720 }
721
722 // run command to set wakeuptime in bios and shutdown the system
723 command = QString();
724
725#ifndef Q_OS_WINDOWS
726 command = "sudo ";
727#endif
728
729 command += m_appBinDir + "mythshutdown --shutdown" + logPropagateArgs;
730
732}
733
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:74
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:85
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:282
#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