MythTV  master
exitprompt.cpp
Go to the documentation of this file.
1 // Qt
2 #include <QCoreApplication>
3 
4 // MythTV
5 #include "libmyth/mythcontext.h"
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 
50 void 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 
87 void 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 
123 void 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 
155 void 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));
307  else if (Action == MythPower::FeatureRestart)
308  connect(dlg, &MythConfirmationDialog::haveResult, this, qOverload<bool>(&ExitPrompter::DoReboot));
309  else if (Action == MythPower::FeatureSuspend)
310  connect(dlg, &MythConfirmationDialog::haveResult, this, qOverload<bool>(&ExitPrompter::DoSuspend));
311  ss->AddScreen(dlg);
312 }
ExitPrompter::m_confirm
bool m_confirm
Definition: exitprompt.h:34
MythDialogBox::SetReturnEvent
void SetReturnEvent(QObject *retobject, const QString &resultid)
Definition: mythdialogbox.cpp:303
ExitPrompter::ConfirmHalt
void ConfirmHalt()
Definition: exitprompt.cpp:45
ExitPrompter::m_dialog
MythDialogBox * m_dialog
Definition: exitprompt.h:38
MythPower
Definition: mythpower.h:19
exitprompt.h
MythCoreContext::IsFrontendOnly
bool IsFrontendOnly(void)
is there a frontend, but no backend, running on this host
Definition: mythcorecontext.cpp:751
mythscreenstack.h
ExitPrompter::m_power
MythPower * m_power
Definition: exitprompt.h:33
MythConfirmationDialog::haveResult
void haveResult(bool)
mythdialogbox.h
MythScreenStack
Definition: mythscreenstack.h:16
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MythDialogBox::Closed
void Closed(QString, int)
ExitPrompter::~ExitPrompter
~ExitPrompter() override
Definition: exitprompt.cpp:28
ExitPrompter::DoReboot
void DoReboot()
Definition: exitprompt.h:22
myth_system
uint myth_system(const QString &command, uint flags, std::chrono::seconds timeout)
Definition: mythsystemlegacy.cpp:506
MythPower::IsFeatureSupported
bool IsFeatureSupported(Feature Supported)
Definition: mythpower.cpp:162
ExitPrompter::DoQuit
void DoQuit()
Definition: exitprompt.cpp:39
true
VERBOSE_PREAMBLE Most true
Definition: verbosedefs.h:95
Action
An action (for this plugin) consists of a description, and a set of key sequences.
Definition: action.h:40
mythsystemlegacy.h
ExitPrompter::m_suspendCommand
QString m_suspendCommand
Definition: exitprompt.h:37
ExitPrompter::MainDialogClosed
void MainDialogClosed(const QString &, int Id)
Definition: exitprompt.cpp:155
mythlogging.h
MythPower::Feature
Feature
Definition: mythpower.h:35
ExitPrompter::m_rebootCommand
QString m_rebootCommand
Definition: exitprompt.h:36
MythDialogBox::AddButton
void AddButton(const QString &title)
Definition: mythdialogbox.h:197
GENERIC_EXIT_OK
@ GENERIC_EXIT_OK
Exited with no error.
Definition: exitcodes.h:13
MythDialogBox
Basic menu dialog, message and a list of options.
Definition: mythdialogbox.h:165
MythPower::AcquireRelease
static MythPower * AcquireRelease(void *Reference, bool Acquire, std::chrono::seconds MinimumDelay=0s)
Definition: mythpower.cpp:72
MythDialogBox::Create
bool Create(void) override
Definition: mythdialogbox.cpp:127
ExitPrompter::DoStandby
void DoStandby()
Definition: exitprompt.cpp:149
MythPower::RequestFeature
virtual bool RequestFeature(Feature Request, bool Delay=true)
Definition: mythpower.cpp:180
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:57
MythPower::FeatureSuspend
@ FeatureSuspend
Definition: mythpower.h:39
MythCoreContext::GetNumSetting
int GetNumSetting(const QString &key, int defaultval=0)
Definition: mythcorecontext.cpp:918
ExitPrompter::Confirm
void Confirm(MythPower::Feature Action)
Definition: exitprompt.cpp:277
ExitPrompter::DoSuspend
void DoSuspend()
Definition: exitprompt.h:25
ExitPrompter::m_haltCommand
QString m_haltCommand
Definition: exitprompt.h:35
ExitPrompter::DoHalt
void DoHalt()
Definition: exitprompt.h:20
MythConfirmationDialog
Dialog asking for user confirmation. Ok and optional Cancel button.
Definition: mythdialogbox.h:271
MythPower::FeatureRestart
@ FeatureRestart
Definition: mythpower.h:41
mythcorecontext.h
MythPower::FeatureShutdown
@ FeatureShutdown
Definition: mythpower.h:38
ExitPrompter::ConfirmReboot
void ConfirmReboot()
Definition: exitprompt.cpp:82
mythcontext.h
GetMythMainWindow
MythMainWindow * GetMythMainWindow(void)
Definition: mythmainwindow.cpp:104
ExitPrompter::HandleExit
void HandleExit()
Definition: exitprompt.cpp:163
MythMainWindow::GetStack
MythScreenStack * GetStack(const QString &Stackname)
Definition: mythmainwindow.cpp:322
MythMainWindow::IdleTimeout
void IdleTimeout()
Definition: mythmainwindow.cpp:2177
exitcodes.h
mythmainwindow.h
MythScreenStack::AddScreen
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Definition: mythscreenstack.cpp:52
ExitPrompter::ConfirmSuspend
void ConfirmSuspend()
Definition: exitprompt.cpp:118
ExitPrompter::ExitPrompter
ExitPrompter()
Definition: exitprompt.cpp:17
uint
unsigned int uint
Definition: freesurround.h:24