MythTV master
exitprompt.cpp
Go to the documentation of this file.
1// Qt
2#include <QCoreApplication>
3
4// MythTV
13
14// MythFrontend
15#include "exitprompt.h"
16
18 : m_power(MythPower::AcquireRelease(this, true)),
19 m_confirm(gCoreContext->GetBoolSetting("ConfirmPowerEvent", true)),
20 m_haltCommand(gCoreContext->GetSetting("HaltCommand", "")),
21 m_rebootCommand(gCoreContext->GetSetting("RebootCommand", "")),
22 m_suspendCommand(gCoreContext->GetSetting("SuspendCommand", ""))
23{
24 // Log to confirm we are not leaking prompters...
25 LOG(VB_GENERAL, LOG_INFO, "Created ExitPrompter");
26}
27
29{
30 // Ensure additional actions are not processed after we are deleted
31 if (m_dialog && GetMythMainWindow()->GetStack("popup stack")->GetTopScreen() == m_dialog)
32 m_dialog->SetReturnEvent(nullptr, QString());
33
34 if (m_power)
35 MythPower::AcquireRelease(this, false);
36 LOG(VB_GENERAL, LOG_INFO, "Deleted ExitPrompter");
37}
38
40{
41 qApp->exit();
42 deleteLater();
43}
44
46{
48}
49
50void ExitPrompter::DoHalt(bool Confirmed)
51{
52 if (Confirmed)
53 {
54 bool handled = false;
55 // Use user specified command if it exists
56 if (!m_haltCommand.isEmpty())
57 {
59 if (ret == GENERIC_EXIT_OK)
60 {
61 handled = true;
62 }
63 else
64 {
65 LOG(VB_GENERAL, LOG_ERR, "User defined HaltCommand failed, falling back to "
66 "alternative methods.");
67 }
68 }
69
70 // Otherwise use MythPower
73 handled = true;
74
75 // halt of last resort
76 if (!handled)
77 myth_system("sudo /sbin/halt -p");
78 }
79 deleteLater();
80}
81
83{
85}
86
87void ExitPrompter::DoReboot(bool Confirmed)
88{
89 if (Confirmed)
90 {
91 bool handled = false;
92 if (!m_rebootCommand.isEmpty())
93 {
95 if (ret == GENERIC_EXIT_OK)
96 {
97 handled = true;
98 }
99 else
100 {
101 LOG(VB_GENERAL, LOG_ERR, "User defined RebootCommand failed, falling back to "
102 "alternative methods.");
103 }
104 }
105
106 // Otherwise use MythPower
109 handled = true;
110
111 // reboot of last resort
112 if (!handled)
113 myth_system("sudo /sbin/reboot");
114 }
115 deleteLater();
116}
117
119{
121}
122
123void ExitPrompter::DoSuspend(bool Confirmed)
124{
125 if (Confirmed)
126 {
127 bool handled = false;
128 // Use user specified command if it exists
129 if (!m_suspendCommand.isEmpty())
130 {
132 if (ret == GENERIC_EXIT_OK)
133 {
134 handled = true;
135 }
136 else
137 {
138 LOG(VB_GENERAL, LOG_ERR,
139 "User defined SuspendCommand failed, falling back to alternative methods.");
140 }
141 }
142
145 }
146 deleteLater();
147}
148
150{
152 deleteLater();
153}
154
155void ExitPrompter::MainDialogClosed(const QString& /*unused*/, int Id)
156{
157 // If the dialog box was closed without a result - or the result was no, then
158 // delete
159 if (Id < 1)
160 deleteLater();
161}
162
164{
165 // first of all find out, if this is a frontend only host...
166 bool frontendOnly = gCoreContext->IsFrontendOnly();
167
168 // how do you want to quit today?
169 bool allowExit = false;
170 bool allowReboot = false;
171 bool allowShutdown = false;
172 bool allowStandby = false;
173 bool allowSuspend = false;
174
175 bool haveshutdown = !m_haltCommand.isEmpty();
176 bool havereboot = !m_rebootCommand.isEmpty();
177 bool havesuspend = !m_suspendCommand.isEmpty();
178
179#ifdef Q_OS_ANDROID
180 haveshutdown = false;
181 havereboot = false;
182 havesuspend = false;
183#endif
184
185 if (m_power)
186 {
190 }
191
192 switch (gCoreContext->GetNumSetting("OverrideExitMenu", 0))
193 {
194 case 0:
195 allowExit = true;
196 if (frontendOnly)
197 allowShutdown = haveshutdown;
198 break;
199 case 1:
200 allowExit = true;
201 break;
202 case 2:
203 allowExit = true;
204 allowShutdown = haveshutdown;
205 break;
206 case 3:
207 allowExit = true;
208 allowReboot = havereboot;
209 allowShutdown = haveshutdown;
210 break;
211 case 4:
212 allowShutdown = haveshutdown;
213 break;
214 case 5:
215 allowReboot = havereboot;
216 break;
217 case 6:
218 allowReboot = havereboot;
219 allowShutdown = haveshutdown;
220 break;
221 case 7:
222 allowStandby = true;
223 break;
224 case 8:
225 allowSuspend = havesuspend;
226 break;
227 case 9:
228 allowExit = true;
229 allowSuspend = havesuspend;
230 break;
231 case 10:
232 allowExit = true;
233 allowReboot = havereboot;
234 allowShutdown = haveshutdown;
235 allowSuspend = havesuspend;
236 break;
237 }
238
239 delete m_dialog;
240 MythScreenStack *ss = GetMythMainWindow()->GetStack("popup stack");
241 m_dialog = new MythDialogBox(tr("Do you really want to exit MythTV?"), ss,
242 "exit prompt");
243
244 if (!m_dialog->Create())
245 {
246 LOG(VB_GENERAL, LOG_ERR, "Can't create Exit Prompt dialog?");
247 delete m_dialog;
248 DoQuit();
249 return;
250 }
251
252 // ensure ExitPrompt is deleted if the dialog is not actioned
254
255 bool confirm = m_confirm || !frontendOnly;
256
257 m_dialog->AddButton(QCoreApplication::translate("(Common)", "No"));
258 if (allowExit)
259 m_dialog->AddButton(tr("Yes, Exit now"), &ExitPrompter::DoQuit);
260 if (allowReboot)
261 m_dialog->AddButton(tr("Yes, Exit and Reboot"),
262 confirm ? &ExitPrompter::ConfirmReboot : qOverload<>(&ExitPrompter::DoReboot));
263 if (allowShutdown)
264 m_dialog->AddButton(tr("Yes, Exit and Shutdown"),
265 confirm ? &ExitPrompter::ConfirmHalt : qOverload<>(&ExitPrompter::DoHalt));
266 if (allowStandby)
267 m_dialog->AddButton(tr("Yes, Enter Standby Mode"), &ExitPrompter::DoStandby);
268 if (allowSuspend)
269 m_dialog->AddButton(tr("Yes, Suspend"),
270 confirm ? &ExitPrompter::ConfirmSuspend : qOverload<>(&ExitPrompter::DoSuspend));
271
272 // This is a hack so that the button clicks target the correct slot
273 m_dialog->SetReturnEvent(this, QString());
274 ss->AddScreen(m_dialog);
275}
276
278{
279 // Main dialog will now be deleted
280 m_dialog = nullptr;
281
282 MythScreenStack *ss = GetMythMainWindow()->GetStack("popup stack");
283
284 QString msg;
285 switch (Action)
286 {
287 case MythPower::FeatureShutdown: msg = tr("Are you sure you want to shutdown?"); break;
288 case MythPower::FeatureRestart: msg = tr("Are you sure you want to reboot?"); break;
289 case MythPower::FeatureSuspend: msg = tr("Are you sure you want to suspend?"); break;
290 default: break;
291 }
292
294 msg.prepend(tr("Mythbackend is running on this system. "));
295
296 auto *dlg = new MythConfirmationDialog(ss, msg);
297
298 if (!dlg->Create())
299 {
300 delete dlg;
301 DoQuit();
302 return;
303 }
304
306 connect(dlg, &MythConfirmationDialog::haveResult, this, qOverload<bool>(&ExitPrompter::DoHalt));
308 connect(dlg, &MythConfirmationDialog::haveResult, this, qOverload<bool>(&ExitPrompter::DoReboot));
310 connect(dlg, &MythConfirmationDialog::haveResult, this, qOverload<bool>(&ExitPrompter::DoSuspend));
311 ss->AddScreen(dlg);
312}
An action (for this plugin) consists of a description, and a set of key sequences.
Definition: action.h:41
QString m_rebootCommand
Definition: exitprompt.h:36
void HandleExit()
Definition: exitprompt.cpp:163
QString m_suspendCommand
Definition: exitprompt.h:37
void ConfirmSuspend()
Definition: exitprompt.cpp:118
QString m_haltCommand
Definition: exitprompt.h:35
~ExitPrompter() override
Definition: exitprompt.cpp:28
void ConfirmReboot()
Definition: exitprompt.cpp:82
void DoReboot()
Definition: exitprompt.h:22
void DoSuspend()
Definition: exitprompt.h:25
MythPower * m_power
Definition: exitprompt.h:33
void DoHalt()
Definition: exitprompt.h:20
void DoQuit()
Definition: exitprompt.cpp:39
void DoStandby()
Definition: exitprompt.cpp:149
void MainDialogClosed(const QString &, int Id)
Definition: exitprompt.cpp:155
MythDialogBox * m_dialog
Definition: exitprompt.h:38
void Confirm(MythPower::Feature Action)
Definition: exitprompt.cpp:277
bool m_confirm
Definition: exitprompt.h:34
void ConfirmHalt()
Definition: exitprompt.cpp:45
Dialog asking for user confirmation.
bool IsFrontendOnly(void)
is there a frontend, but no backend, running on this host
int GetNumSetting(const QString &key, int defaultval=0)
Basic menu dialog, message and a list of options.
void AddButton(const QString &title)
void SetReturnEvent(QObject *retobject, const QString &resultid)
void Closed(QString, int)
bool Create(void) override
MythScreenStack * GetStack(const QString &Stackname)
@ FeatureRestart
Definition: mythpower.h:41
@ FeatureShutdown
Definition: mythpower.h:38
@ FeatureSuspend
Definition: mythpower.h:39
virtual bool RequestFeature(Feature Request, bool Delay=true)
Definition: mythpower.cpp:182
bool IsFeatureSupported(Feature Supported)
Definition: mythpower.cpp:164
static MythPower * AcquireRelease(void *Reference, bool Acquire, std::chrono::seconds MinimumDelay=0s)
Definition: mythpower.cpp:74
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
@ GENERIC_EXIT_OK
Exited with no error.
Definition: exitcodes.h:13
unsigned int uint
Definition: freesurround.h:24
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MythMainWindow * GetMythMainWindow(void)
uint myth_system(const QString &command, uint flags, std::chrono::seconds timeout)
VERBOSE_PREAMBLE Most true
Definition: verbosedefs.h:95