MythTV  master
mythfrontend/exitprompt.cpp
Go to the documentation of this file.
1 // Qt
2 #include <QCoreApplication>
3 
4 // MythTV
5 #include "config.h"
6 #include "exitprompt.h"
7 #include "mythcontext.h"
8 #include "mythdialogbox.h"
9 #include "mythmainwindow.h"
10 #include "mythscreenstack.h"
11 #include "mythsystemlegacy.h"
12 #include "mythlogging.h"
13 #include "exitcodes.h"
14 
16  : m_power(MythPower::AcquireRelease(this, true)),
17  m_confirm(gCoreContext->GetBoolSetting("ConfirmPowerEvent", true)),
18  m_haltCommand(gCoreContext->GetSetting("HaltCommand", "")),
19  m_rebootCommand(gCoreContext->GetSetting("RebootCommand", "")),
20  m_suspendCommand(gCoreContext->GetSetting("SuspendCommand", ""))
21 {
22  // Log to confirm we are not leaking prompters...
23  LOG(VB_GENERAL, LOG_INFO, "Created ExitPrompter");
24 }
25 
27 {
28  if (m_power)
29  MythPower::AcquireRelease(this, false);
30  LOG(VB_GENERAL, LOG_INFO, "Deleted ExitPrompter");
31 }
32 
34 {
35  qApp->exit();
36  deleteLater();
37 }
38 
40 {
42 }
43 
44 void ExitPrompter::DoHalt(bool Confirmed)
45 {
46  if (Confirmed)
47  {
48  bool handled = false;
49  // Use user specified command if it exists
50  if (!m_haltCommand.isEmpty())
51  {
53  if (ret == GENERIC_EXIT_OK)
54  {
55  handled = true;
56  }
57  else
58  {
59  LOG(VB_GENERAL, LOG_ERR, "User defined HaltCommand failed, falling back to "
60  "alternative methods.");
61  }
62  }
63 
64  // Otherwise use MythPower
67  handled = true;
68 
69  // halt of last resort
70  if (!handled)
71  myth_system("sudo /sbin/halt -p");
72  }
73  deleteLater();
74 }
75 
77 {
79 }
80 
81 void ExitPrompter::DoReboot(bool Confirmed)
82 {
83  if (Confirmed)
84  {
85  bool handled = false;
86  if (!m_rebootCommand.isEmpty())
87  {
89  if (ret == GENERIC_EXIT_OK)
90  {
91  handled = true;
92  }
93  else
94  {
95  LOG(VB_GENERAL, LOG_ERR, "User defined RebootCommand failed, falling back to "
96  "alternative methods.");
97  }
98  }
99 
100  // Otherwise use MythPower
103  handled = true;
104 
105  // reboot of last resort
106  if (!handled)
107  myth_system("sudo /sbin/reboot");
108  }
109  deleteLater();
110 }
111 
113 {
115 }
116 
117 void ExitPrompter::DoSuspend(bool Confirmed)
118 {
119  if (Confirmed)
120  {
121  bool handled = false;
122  // Use user specified command if it exists
123  if (!m_suspendCommand.isEmpty())
124  {
126  if (ret == GENERIC_EXIT_OK)
127  {
128  handled = true;
129  }
130  else
131  {
132  LOG(VB_GENERAL, LOG_ERR,
133  "User defined SuspendCommand failed, falling back to alternative methods.");
134  }
135  }
136 
139  }
140  deleteLater();
141 }
142 
144 {
146  deleteLater();
147 }
148 
149 void ExitPrompter::MainDialogClosed(const QString& /*unused*/, int Id)
150 {
151  // If the dialog box was closed without a result - or the result was no, then
152  // delete
153  if (Id < 1)
154  deleteLater();
155 }
156 
158 {
159  // HACK IsFrontendOnly() triggers a popup if there is no BE connection.
160  // We really don't need that right now. This hack prevents it.
162 
163  // first of all find out, if this is a frontend only host...
164  bool frontendOnly = gCoreContext->IsFrontendOnly();
165 
166  // HACK Undo the hack, just in case we _don't_ quit:
168 
169  // how do you want to quit today?
170  bool allowExit = false;
171  bool allowReboot = false;
172  bool allowShutdown = false;
173  bool allowStandby = false;
174  bool allowSuspend = false;
175 
176  bool haveshutdown = !m_haltCommand.isEmpty();
177  bool havereboot = !m_rebootCommand.isEmpty();
178  bool havesuspend = !m_suspendCommand.isEmpty();
179 
180 #ifdef Q_OS_ANDROID
181  haveshutdown = false;
182  havereboot = false;
183  havesuspend = false;
184 #endif
185 
186  if (m_power)
187  {
191  }
192 
193  switch (gCoreContext->GetNumSetting("OverrideExitMenu", 0))
194  {
195  case 0:
196  allowExit = true;
197  if (frontendOnly)
198  allowShutdown = haveshutdown;
199  break;
200  case 1:
201  allowExit = true;
202  break;
203  case 2:
204  allowExit = true;
205  allowShutdown = haveshutdown;
206  break;
207  case 3:
208  allowExit = true;
209  allowReboot = havereboot;
210  allowShutdown = haveshutdown;
211  break;
212  case 4:
213  allowShutdown = haveshutdown;
214  break;
215  case 5:
216  allowReboot = havereboot;
217  break;
218  case 6:
219  allowReboot = havereboot;
220  allowShutdown = haveshutdown;
221  break;
222  case 7:
223  allowStandby = true;
224  break;
225  case 8:
226  allowSuspend = havesuspend;
227  break;
228  case 9:
229  allowExit = true;
230  allowSuspend = havesuspend;
231  break;
232  case 10:
233  allowExit = true;
234  allowReboot = havereboot;
235  allowShutdown = haveshutdown;
236  allowSuspend = havesuspend;
237  break;
238  }
239 
240  MythScreenStack *ss = GetMythMainWindow()->GetStack("popup stack");
241  auto *dlg = new MythDialogBox(tr("Do you really want to exit MythTV?"), ss,
242  "exit prompt");
243 
244  if (!dlg->Create())
245  {
246  LOG(VB_GENERAL, LOG_ERR, "Can't create Exit Prompt dialog?");
247  delete dlg;
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  dlg->AddButton(QCoreApplication::translate("(Common)", "No"));
258  if (allowExit)
259  dlg->AddButton(tr("Yes, Exit now"), &ExitPrompter::DoQuit);
260  if (allowReboot)
261  dlg->AddButton(tr("Yes, Exit and Reboot"),
262  confirm ? &ExitPrompter::ConfirmReboot : qOverload<>(&ExitPrompter::DoReboot));
263  if (allowShutdown)
264  dlg->AddButton(tr("Yes, Exit and Shutdown"),
265  confirm ? &ExitPrompter::ConfirmHalt : qOverload<>(&ExitPrompter::DoHalt));
266  if (allowStandby)
267  dlg->AddButton(tr("Yes, Enter Standby Mode"), &ExitPrompter::DoStandby);
268  if (allowSuspend)
269  dlg->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  dlg->SetReturnEvent(this, QString());
274 
275  ss->AddScreen(dlg);
276 }
277 
279 {
280  MythScreenStack *ss = GetMythMainWindow()->GetStack("popup stack");
281 
282  QString msg;
283  switch (Action)
284  {
285  case MythPower::FeatureShutdown: msg = tr("Are you sure you want to shutdown?"); break;
286  case MythPower::FeatureRestart: msg = tr("Are you sure you want to reboot?"); break;
287  case MythPower::FeatureSuspend: msg = tr("Are you sure you want to suspend?"); break;
288  default: break;
289  }
290 
293  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 
312  ss->AddScreen(dlg);
313 }
ExitPrompter::m_confirm
bool m_confirm
Definition: mythfrontend/exitprompt.h:32
ExitPrompter::ConfirmHalt
void ConfirmHalt()
Definition: mythfrontend/exitprompt.cpp:39
myth_system
uint myth_system(const QString &command, uint flags, uint timeout)
Definition: mythsystemlegacy.cpp:501
GENERIC_EXIT_OK
#define GENERIC_EXIT_OK
Exited with no error.
Definition: exitcodes.h:10
MythPower
Definition: mythpower.h:19
MythPower::FeatureSuspend
@ FeatureSuspend
Definition: mythpower.h:38
MythCoreContext::IsFrontendOnly
bool IsFrontendOnly(void)
is there a frontend, but no backend, running on this host
Definition: mythcorecontext.cpp:766
mythscreenstack.h
ExitPrompter::m_power
MythPower * m_power
Definition: mythfrontend/exitprompt.h:31
MythContext::SetDisableEventPopup
void SetDisableEventPopup(bool check)
Definition: mythcontext.cpp:1672
MythConfirmationDialog::haveResult
void haveResult(bool)
mythdialogbox.h
MythScreenStack
Definition: mythscreenstack.h:16
MythPower::FeatureShutdown
@ FeatureShutdown
Definition: mythpower.h:37
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
MythDialogBox::Closed
void Closed(QString, int)
ExitPrompter::~ExitPrompter
~ExitPrompter() override
Definition: mythfrontend/exitprompt.cpp:26
ExitPrompter::DoReboot
void DoReboot()
Definition: mythfrontend/exitprompt.h:20
MythPower::IsFeatureSupported
bool IsFeatureSupported(Feature Supported)
Definition: mythpower.cpp:160
MythMainWindow::GetStack
MythScreenStack * GetStack(const QString &stackname)
Definition: mythmainwindow.cpp:329
ExitPrompter::DoQuit
void DoQuit()
Definition: mythfrontend/exitprompt.cpp:33
true
VERBOSE_PREAMBLE Most true
Definition: verbosedefs.h:91
Action
An action (for this plugin) consists of a description, and a set of key sequences.
Definition: action.h:41
mythsystemlegacy.h
ExitPrompter::m_suspendCommand
QString m_suspendCommand
Definition: mythfrontend/exitprompt.h:35
ExitPrompter::MainDialogClosed
void MainDialogClosed(const QString &, int Id)
Definition: mythfrontend/exitprompt.cpp:149
mythlogging.h
ExitPrompter::m_rebootCommand
QString m_rebootCommand
Definition: mythfrontend/exitprompt.h:34
MythDialogBox
Basic menu dialog, message and a list of options.
Definition: mythdialogbox.h:167
ExitPrompter::DoStandby
void DoStandby()
Definition: mythfrontend/exitprompt.cpp:143
MythPower::RequestFeature
virtual bool RequestFeature(Feature Request, bool Delay=true)
Definition: mythpower.cpp:178
GetSetting
t<< doc.toString(4);f.close();LOG(VB_JOBQUEUE, LOG_INFO, "Copying video file");bool res=copyFile(filename, saveDirectory+title+"/"+baseName);if(!res) return 0;if(QFile::exists(filename+".png")) { LOG(VB_JOBQUEUE, LOG_INFO, "Copying preview image");res=copyFile(filename+".png", saveDirectory+title+"/"+baseName+".png");if(!res) return 0;} LOG(VB_JOBQUEUE, LOG_INFO, "Item Archived OK");return 1;}int NativeArchive::exportVideo(QDomElement &itemNode, const QString &saveDirectory){ QString dbVersion=gCoreContext-> GetSetting("DBSchemaVer", "")
uint
unsigned int uint
Definition: compat.h:141
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:60
MythCoreContext::GetNumSetting
int GetNumSetting(const QString &key, int defaultval=0)
Definition: mythcorecontext.cpp:933
MythPower::Feature
Feature
Definition: mythpower.h:35
ExitPrompter::Confirm
void Confirm(MythPower::Feature Action)
Definition: mythfrontend/exitprompt.cpp:278
ExitPrompter::DoSuspend
void DoSuspend()
Definition: mythfrontend/exitprompt.h:23
ExitPrompter::m_haltCommand
QString m_haltCommand
Definition: mythfrontend/exitprompt.h:33
MythPower::AcquireRelease
static MythPower * AcquireRelease(void *Reference, bool Acquire, uint MinimumDelay=0)
Definition: mythpower.cpp:70
ExitPrompter::DoHalt
void DoHalt()
Definition: mythfrontend/exitprompt.h:18
MythConfirmationDialog
Dialog asking for user confirmation.
Definition: mythdialogbox.h:271
MythPower::FeatureRestart
@ FeatureRestart
Definition: mythpower.h:40
ExitPrompter::ConfirmReboot
void ConfirmReboot()
Definition: mythfrontend/exitprompt.cpp:76
mythcontext.h
GetMythMainWindow
MythMainWindow * GetMythMainWindow(void)
Definition: mythmainwindow.cpp:108
ExitPrompter::HandleExit
void HandleExit()
Definition: mythfrontend/exitprompt.cpp:157
MythMainWindow::IdleTimeout
void IdleTimeout()
Definition: mythmainwindow.cpp:2221
exitcodes.h
mythmainwindow.h
MythScreenStack::AddScreen
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Definition: mythscreenstack.cpp:52
ExitPrompter::ConfirmSuspend
void ConfirmSuspend()
Definition: mythfrontend/exitprompt.cpp:112
gContext
MythContext * gContext
This global variable contains the MythContext instance for the application.
Definition: mythcontext.cpp:64
ExitPrompter::ExitPrompter
ExitPrompter()
Definition: mythfrontend/exitprompt.cpp:15
exitprompt.h