MythTV  master
mythmainwindow.cpp
Go to the documentation of this file.
1 #include "mythmainwindow.h"
3 
4 // C headers
5 #include <cmath>
6 
7 // C++ headers
8 #include <algorithm>
9 #include <chrono>
10 #include <utility>
11 #include <vector>
12 
13 // QT
14 #include <QWaitCondition>
15 #include <QApplication>
16 #include <QHash>
17 #include <QFile>
18 #include <QDir>
19 #include <QEvent>
20 #include <QKeyEvent>
21 #include <QKeySequence>
22 #include <QInputMethodEvent>
23 #include <QSize>
24 #include <QWindow>
25 
26 // Platform headers
27 #include "unistd.h"
28 
29 // libmythbase headers
30 #include "libmythbase/compat.h"
32 #include "libmythbase/mythdate.h"
33 #include "libmythbase/mythdb.h"
34 #include "libmythbase/mythdirs.h"
35 #include "libmythbase/mythevent.h"
37 #include "libmythbase/mythmedia.h"
39 
40 // libmythui headers
41 #include "myththemebase.h"
42 #include "mythudplistener.h"
43 #include "mythrender_base.h"
44 #include "mythuistatetracker.h"
45 #include "mythuiactions.h"
46 #include "mythrect.h"
47 #include "mythdisplay.h"
48 #include "mythscreentype.h"
49 #include "mythpainter.h"
50 #include "mythpainterwindow.h"
51 #include "mythgesture.h"
52 #include "mythuihelper.h"
53 #include "mythdialogbox.h"
54 #include "mythscreensaver.h"
56 
57 
58 #ifdef Q_OS_ANDROID
59 #include <QtAndroid>
60 #endif
61 
62 static constexpr std::chrono::milliseconds GESTURE_TIMEOUT { 1s };
63 static constexpr std::chrono::minutes STANDBY_TIMEOUT { 90min };
64 static constexpr std::chrono::milliseconds LONGPRESS_INTERVAL { 1s };
65 
66 #define LOC QString("MythMainWindow: ")
67 
68 static MythMainWindow *s_mainWin = nullptr;
69 static QMutex s_mainLock;
70 
79 {
80  if (s_mainWin)
81  return s_mainWin;
82 
83  QMutexLocker lock(&s_mainLock);
84 
85  if (!s_mainWin)
86  {
87  s_mainWin = new MythMainWindow(UseDB);
89  }
90 
91  return s_mainWin;
92 }
93 
95 {
96  if (gCoreContext)
97  gCoreContext->SetGUIObject(nullptr);
98  delete s_mainWin;
99  s_mainWin = nullptr;
100 }
101 
103 {
105 }
106 
108 {
109  return s_mainWin != nullptr;
110 }
111 
113 {
115 }
116 
118 {
120 }
121 
123 {
125  return nullptr;
127 }
128 
130 {
132 
133  // Switch to desired GUI resolution
134  if (m_display->UsingVideoModes())
135  m_display->SwitchToGUI(true);
136 
139 
141 
142  setObjectName("mainwindow");
143 
144  m_priv->m_allowInput = false;
145 
146  // This prevents database errors from RegisterKey() when there is no DB:
147  m_priv->m_useDB = UseDB;
148 
149  //Init();
150 
151  m_priv->m_exitingtomain = false;
152  m_priv->m_popwindows = true;
153  m_priv->m_exitMenuCallback = nullptr;
155  m_priv->m_mediaDeviceForCallback = nullptr;
156  m_priv->m_escapekey = Qt::Key_Escape;
157  m_priv->m_mainStack = nullptr;
158 
159  installEventFilter(this);
160 
162 
163  InitKeys();
164 
165  m_priv->m_gestureTimer = new QTimer(this);
167  m_priv->m_hideMouseTimer = new QTimer(this);
168  m_priv->m_hideMouseTimer->setSingleShot(true);
169  m_priv->m_hideMouseTimer->setInterval(3s);
171  m_priv->m_allowInput = true;
173  m_refreshTimer.setInterval(17ms);
174  m_refreshTimer.start();
175  setUpdatesEnabled(true);
176 
178  Qt::BlockingQueuedConnection);
180  Qt::BlockingQueuedConnection);
181 #ifdef Q_OS_ANDROID
182  connect(qApp, &QApplication::applicationStateChanged, this, &MythMainWindow::OnApplicationStateChange);
183 #endif
184 
185  // We need to listen for playback start/end events
186  gCoreContext->addListener(this);
187 
188  // Idle timer setup
189  m_idleTime =
190  gCoreContext->GetDurSetting<std::chrono::minutes>("FrontendIdleTimeout",
192  if (m_idleTime < 0min)
193  m_idleTime = 0min;
194  m_idleTimer.setInterval(m_idleTime);
196  if (m_idleTime > 0min)
197  m_idleTimer.start();
198 
200  if (m_screensaver)
201  {
205  }
206 }
207 
209 {
210  delete m_screensaver;
211 
212  if (gCoreContext != nullptr)
214 
216 
217  while (!m_priv->m_stackList.isEmpty())
218  {
219  MythScreenStack *stack = m_priv->m_stackList.back();
220  m_priv->m_stackList.pop_back();
221 
222  if (stack == m_priv->m_mainStack)
223  m_priv->m_mainStack = nullptr;
224 
225  delete stack;
226  }
227 
228  delete m_themeBase;
229 
230  while (!m_priv->m_keyContexts.isEmpty())
231  {
232  KeyContext *context = *m_priv->m_keyContexts.begin();
233  m_priv->m_keyContexts.erase(m_priv->m_keyContexts.begin());
234  delete context;
235  }
236 
237  delete m_deviceHandler;
238  delete m_priv->m_nc;
239 
241 
242  // N.B. we always call this to ensure the desktop mode is restored
243  // in case the setting was changed
245  delete m_display;
246 
247  delete m_priv;
248 }
249 
251 {
252  return m_display;
253 }
254 
256 {
257  return m_painter;
258 }
259 
261 {
262  return m_priv->m_nc;
263 }
264 
266 {
267  return m_painterWin;
268 }
269 
271 {
272  if (m_painterWin)
273  {
274  m_painterWin->show();
275  m_painterWin->raise();
276  }
277 }
278 
280 {
281  if (m_painterWin)
282  {
283  m_painterWin->clearMask();
285  m_painterWin->hide();
286  }
287 }
288 
290 {
291  return m_painterWin->GetRenderDevice();
292 }
293 
295 {
296  m_priv->m_stackList.push_back(Stack);
297  if (Main)
298  m_priv->m_mainStack = Stack;
299 }
300 
302 {
303  MythScreenStack *stack = m_priv->m_stackList.back();
304  m_priv->m_stackList.pop_back();
305  if (stack == m_priv->m_mainStack)
306  m_priv->m_mainStack = nullptr;
307  delete stack;
308 }
309 
311 {
312  return m_priv->m_stackList.size();
313 }
314 
316 {
317  return m_priv->m_mainStack;
318 }
319 
320 MythScreenStack *MythMainWindow::GetStack(const QString& Stackname)
321 {
322  for (auto * widget : qAsConst(m_priv->m_stackList))
323  if (widget->objectName() == Stackname)
324  return widget;
325  return nullptr;
326 }
327 
329 {
330  if (Position >= 0 && Position < m_priv->m_stackList.size())
331  return m_priv->m_stackList.at(Position);
332  return nullptr;
333 }
334 
336 {
337  if (!(m_painterWin && updatesEnabled()))
338  return;
339 
340  bool redraw = false;
341 
342  if (!m_repaintRegion.isEmpty())
343  redraw = true;
344 
345  // The call to GetDrawOrder can apparently alter m_stackList.
346  // NOLINTNEXTLINE(modernize-loop-convert,readability-qualified-auto) // both, qt6
347  for (auto it = m_priv->m_stackList.begin(); it != m_priv->m_stackList.end(); ++it)
348  {
349  QVector<MythScreenType *> drawList;
350  (*it)->GetDrawOrder(drawList);
351 
352  for (auto *screen : qAsConst(drawList))
353  {
354  screen->Pulse();
355 
356  if (screen->NeedsRedraw())
357  {
358  QRegion topDirty = screen->GetDirtyArea();
359  screen->ResetNeedsRedraw();
360  m_repaintRegion = m_repaintRegion.united(topDirty);
361  redraw = true;
362  }
363  }
364  }
365 
366  if (redraw && !m_painterWin->RenderIsShared())
367  m_painterWin->update(m_repaintRegion);
368 
369  for (auto *widget : qAsConst(m_priv->m_stackList))
370  widget->ScheduleInitIfNeeded();
371 }
372 
374 {
375  if (!(m_painterWin && updatesEnabled()))
376  return;
377 
378  if (Event)
379  m_repaintRegion = m_repaintRegion.united(Event->region());
380 
381  if (!m_painter->SupportsClipping())
382  {
384  }
385  else
386  {
387  // Ensure that the region is not larger than the screen which
388  // can happen with bad themes
390 
391  // Check for any widgets that have been updated since we built
392  // the dirty region list in ::animate()
393  // The call to GetDrawOrder can apparently alter m_stackList.
394  // NOLINTNEXTLINE(modernize-loop-convert,readability-qualified-auto) // both, qt6
395  for (auto it = m_priv->m_stackList.begin(); it != m_priv->m_stackList.end(); ++it)
396  {
397  QVector<MythScreenType *> redrawList;
398  (*it)->GetDrawOrder(redrawList);
399 
400  for (const auto *screen : qAsConst(redrawList))
401  {
402  if (screen->NeedsRedraw())
403  {
404  for (const QRect& wrect: screen->GetDirtyArea())
405  {
406  bool foundThisRect = false;
407  for (const QRect& drect: m_repaintRegion)
408  {
409  // Can't use QRegion::contains because it only
410  // checks for overlap. QRect::contains checks
411  // if fully contained.
412  if (drect.contains(wrect))
413  {
414  foundThisRect = true;
415  break;
416  }
417  }
418 
419  if (!foundThisRect)
420  return;
421  }
422  }
423  }
424  }
425  }
426 
428  Draw();
429 
430  m_repaintRegion = QRegion();
431 }
432 
434 {
435  if (!Painter)
436  Painter = m_painter;
437  if (!Painter)
438  return;
439 
440  Painter->Begin(m_painterWin);
441 
442  if (!Painter->SupportsClipping())
443  m_repaintRegion = QRegion(m_uiScreenRect);
444 
445  for (const QRect& rect : m_repaintRegion)
446  {
447  if (rect.width() == 0 || rect.height() == 0)
448  continue;
449 
450  if (rect != m_uiScreenRect)
451  Painter->SetClipRect(rect);
452 
453  // The call to GetDrawOrder can apparently alter m_stackList.
454  // NOLINTNEXTLINE(modernize-loop-convert,readability-qualified-auto) // both, qt6
455  for (auto it = m_priv->m_stackList.begin(); it != m_priv->m_stackList.end(); ++it)
456  {
457  QVector<MythScreenType *> redrawList;
458  (*it)->GetDrawOrder(redrawList);
459  for (auto *screen : qAsConst(redrawList))
460  screen->Draw(Painter, 0, 0, 255, rect);
461  }
462  }
463 
464  Painter->End();
465  m_repaintRegion = QRegion();
466 }
467 
468 // virtual
469 QPaintEngine *MythMainWindow::paintEngine() const
470 {
471  return testAttribute(Qt::WA_PaintOnScreen) ? nullptr : QWidget::paintEngine();
472 }
473 
475 {
476  if (Event->spontaneous())
477  {
478  auto * key = new QKeyEvent(QEvent::KeyPress, m_priv->m_escapekey, Qt::NoModifier);
479  QCoreApplication::postEvent(this, key);
480  Event->ignore();
481  return;
482  }
483 
484  QWidget::closeEvent(Event);
485 }
486 
487 void MythMainWindow::GrabWindow(QImage& Image)
488 {
489  WId winid = 0;
490  auto * active = QApplication::activeWindow();
491  if (active)
492  {
493  winid = active->winId();
494  }
495  else
496  {
497  // According to the following we page, you "just pass 0 as the
498  // window id, indicating that we want to grab the entire screen".
499  //
500  // https://doc.qt.io/qt-5/qtwidgets-desktop-screenshot-example.html#screenshot-class-implementation
501  winid = 0;
502  }
503 
504  auto * display = GetMythMainWindow()->GetDisplay();
505  if (auto * screen = display->GetCurrentScreen(); screen)
506  {
507  QPixmap image = screen->grabWindow(winid);
508  Image = image.toImage();
509  }
510 }
511 
512 /* This is required to allow a screenshot to be requested by another thread
513  * other than the UI thread, and to wait for the screenshot before returning.
514  * It is used by mythweb for the remote access screenshots
515  */
516 void MythMainWindow::DoRemoteScreenShot(const QString& Filename, int Width, int Height)
517 {
518  // This will be running in the UI thread, as is required by QPixmap
519  QStringList args;
520  args << QString::number(Width);
521  args << QString::number(Height);
522  args << Filename;
524  QCoreApplication::sendEvent(this, &me);
525 }
526 
527 void MythMainWindow::RemoteScreenShot(QString Filename, int Width, int Height)
528 {
529  // This will be running in a non-UI thread and is used to trigger a
530  // function in the UI thread, and waits for completion of that handler
531  emit SignalRemoteScreenShot(std::move(Filename), Width, Height);
532 }
533 
534 bool MythMainWindow::SaveScreenShot(const QImage& Image, QString Filename)
535 {
536  if (Filename.isEmpty())
537  {
538  QString fpath = GetMythDB()->GetSetting("ScreenShotPath", "/tmp");
539  Filename = QString("%1/myth-screenshot-%2.png")
541  }
542 
543  QString extension = Filename.section('.', -1, -1);
544  if (extension == "jpg")
545  extension = "JPEG";
546  else
547  extension = "PNG";
548 
549  LOG(VB_GENERAL, LOG_INFO, QString("Saving screenshot to %1 (%2x%3)")
550  .arg(Filename).arg(Image.width()).arg(Image.height()));
551 
552  if (Image.save(Filename, extension.toLatin1(), 100))
553  {
554  LOG(VB_GENERAL, LOG_INFO, "MythMainWindow::screenShot succeeded");
555  return true;
556  }
557 
558  LOG(VB_GENERAL, LOG_INFO, "MythMainWindow::screenShot Failed!");
559  return false;
560 }
561 
562 bool MythMainWindow::ScreenShot(int Width, int Height, QString Filename)
563 {
564  QImage img;
565  GrabWindow(img);
566  if (Width <= 0)
567  Width = img.width();
568  if (Height <= 0)
569  Height = img.height();
570  img = img.scaled(Width, Height, Qt::KeepAspectRatio, Qt::SmoothTransformation);
571  return SaveScreenShot(img, std::move(Filename));
572 }
573 
575 {
576  if (HasMythMainWindow())
578 }
579 
581 {
582  if (HasMythMainWindow())
584 }
585 
587 {
588  if (HasMythMainWindow())
590 }
591 
593 {
594  if (HasMythMainWindow())
595  {
596  MythMainWindow* window = GetMythMainWindow();
597  if (window->m_screensaver)
598  return window->m_screensaver->Asleep();
599  }
600  return false;
601 }
602 
604 {
605  if (HasMythMainWindow())
607  return false;
608 }
609 
611 {
612  if (!updatesEnabled() && (Event->type() == QEvent::UpdateRequest))
613  m_priv->m_pendingUpdate = true;
614 
615  if (Event->type() == QEvent::Show && !Event->spontaneous())
616  QCoreApplication::postEvent(this, new QEvent(MythEvent::kMythPostShowEventType));
617 
619  {
620  raise();
621  activateWindow();
622  return true;
623  }
624 
625  if ((Event->type() == QEvent::WindowActivate) || (Event->type() == QEvent::WindowDeactivate))
627 
628  return QWidget::event(Event);
629 }
630 
632 {
635  QApplication::setStyle("Windows");
636 }
637 
638 void MythMainWindow::Init(bool MayReInit)
639 {
640  LoadQtConfig();
641  m_display->SetWidget(nullptr);
642  m_priv->m_useDB = ! gCoreContext->GetDB()->SuppressDBMessages();
643 
644  if (!(MayReInit || m_priv->m_firstinit))
645  return;
646 
647  // Set window border based on fullscreen attribute
648  Qt::WindowFlags flags = Qt::Window;
649 
651  bool inwindow = m_wantWindow && !m_qtFullScreen;
652  bool fullscreen = m_wantFullScreen && !GeometryIsOverridden();
653 
654  // On Compiz/Unit, when the window is fullscreen and frameless changing
655  // screen position ends up stuck. Adding a border temporarily prevents this
656  setWindowFlags(windowFlags() & ~Qt::FramelessWindowHint);
657 
658  if (!inwindow)
659  {
660  LOG(VB_GENERAL, LOG_INFO, "Using Frameless Window");
661  flags |= Qt::FramelessWindowHint;
662  }
663 
664  // Workaround Qt/Windows playback bug?
665 #ifdef _WIN32
666  flags |= Qt::MSWindowsOwnDC;
667 #endif
668 
669  // NOTE if running fullscreen AND windowed (i.e. borders etc) then we do not
670  // have any idea at this time of the size of the borders/decorations.
671  // Typically, on linux, this means we create the UI slightly larger than
672  // required - as X adds the decorations at a later point.
673 
674  if (fullscreen && !inwindow)
675  {
676  LOG(VB_GENERAL, LOG_INFO, "Using Full Screen Window");
677  if (m_priv->m_firstinit)
678  {
679  // During initialization, we force being fullscreen using setWindowState
680  // otherwise, in ubuntu's unity, the side bar often stays visible
681  setWindowState(Qt::WindowFullScreen);
682  }
683  }
684  else
685  {
686  // reset type
687  setWindowState(Qt::WindowNoState);
688  }
689 
691  flags |= Qt::WindowStaysOnTopHint;
692 
693  setWindowFlags(flags);
694 
695  // SetWidget may move the widget into a new screen.
696  m_display->SetWidget(this);
697  QTimer::singleShot(1s, this, &MythMainWindow::DelayedAction);
698 
699  // Ensure we have latest screen bounds if we have moved
701  SetUIScreenRect({{0, 0}, m_screenRect.size()});
703  Show();
704 
705  // The window is sometimes not created until Show has been called - so try
706  // MythDisplay::setWidget again to ensure we listen for QScreen changes
707  m_display->SetWidget(this);
708 
709  if (!GetMythDB()->GetBoolSetting("HideMouseCursor", false))
710  setMouseTracking(true); // Required for mouse cursor auto-hide
711  // Set cursor call must come after Show() to work on some systems.
712  ShowMouseCursor(false);
713 
714  move(m_screenRect.topLeft());
715 
716  if (m_painterWin || m_painter)
717  {
718  LOG(VB_GENERAL, LOG_INFO, "Destroying painter and painter window");
720  }
721 
722  QString warningmsg = MythPainterWindow::CreatePainters(this, m_painterWin, m_painter);
723  if (!warningmsg.isEmpty())
724  {
725  LOG(VB_GENERAL, LOG_WARNING, warningmsg);
726  }
727 
728  if (!m_painterWin)
729  {
730  LOG(VB_GENERAL, LOG_ERR, "MythMainWindow failed to create a painter window.");
731  return;
732  }
733 
734  if (m_painter && m_painter->GetName() != "Qt")
735  {
736  setAttribute(Qt::WA_NoSystemBackground);
737  setAutoFillBackground(false);
738  }
739  setAttribute(Qt::WA_InputMethodEnabled);
740 
743 
744  // Redraw the window now to avoid race conditions in EGLFS (Qt5.4) if a
745  // 2nd window (e.g. TVPlayback) is created before this is redrawn.
746 #ifdef Q_OS_ANDROID
747  static const QLatin1String EARLY_SHOW_PLATFORM_NAME_CHECK { "android" };
748 #else
749  static const QLatin1String EARLY_SHOW_PLATFORM_NAME_CHECK { "egl" };
750 #endif
751  if (QGuiApplication::platformName().contains(EARLY_SHOW_PLATFORM_NAME_CHECK))
752  QCoreApplication::processEvents();
753 
754  if (!GetMythDB()->GetBoolSetting("HideMouseCursor", false))
755  m_painterWin->setMouseTracking(true); // Required for mouse cursor auto-hide
756 
758  if (m_themeBase)
759  m_themeBase->Reload();
760  else
761  m_themeBase = new MythThemeBase(this);
762 
763  if (!m_priv->m_nc)
765 
766  emit SignalWindowReady();
767 
768  if (!warningmsg.isEmpty())
769  {
770  MythNotification notification(warningmsg, "");
771  m_priv->m_nc->Queue(notification);
772  }
773 }
774 
776 {
778  Show();
779 
780 #ifdef Q_OS_ANDROID
781  QtAndroid::hideSplashScreen();
782 #endif
783 }
784 
786 {
787  RegisterKey("Global", ACTION_UP, QT_TRANSLATE_NOOP("MythControls",
788  "Up Arrow"), "Up");
789  RegisterKey("Global", ACTION_DOWN, QT_TRANSLATE_NOOP("MythControls",
790  "Down Arrow"), "Down");
791  RegisterKey("Global", ACTION_LEFT, QT_TRANSLATE_NOOP("MythControls",
792  "Left Arrow"), "Left");
793  RegisterKey("Global", ACTION_RIGHT, QT_TRANSLATE_NOOP("MythControls",
794  "Right Arrow"), "Right");
795  RegisterKey("Global", "NEXT", QT_TRANSLATE_NOOP("MythControls",
796  "Move to next widget"), "Tab");
797  RegisterKey("Global", "PREVIOUS", QT_TRANSLATE_NOOP("MythControls",
798  "Move to preview widget"), "Backtab");
799  RegisterKey("Global", ACTION_SELECT, QT_TRANSLATE_NOOP("MythControls",
800  "Select"), "Return,Enter,Space");
801  RegisterKey("Global", "BACKSPACE", QT_TRANSLATE_NOOP("MythControls",
802  "Backspace"), "Backspace");
803  RegisterKey("Global", "ESCAPE", QT_TRANSLATE_NOOP("MythControls",
804  "Escape"), "Esc");
805  RegisterKey("Global", "MENU", QT_TRANSLATE_NOOP("MythControls",
806  "Pop-up menu"), "M,Meta+Enter");
807  RegisterKey("Global", "INFO", QT_TRANSLATE_NOOP("MythControls",
808  "More information"), "I");
809  RegisterKey("Global", "DELETE", QT_TRANSLATE_NOOP("MythControls",
810  "Delete"), "D");
811  RegisterKey("Global", "EDIT", QT_TRANSLATE_NOOP("MythControls",
812  "Edit"), "E");
813  RegisterKey("Global", ACTION_SCREENSHOT, QT_TRANSLATE_NOOP("MythControls",
814  "Save screenshot"), "");
815  RegisterKey("Global", ACTION_HANDLEMEDIA, QT_TRANSLATE_NOOP("MythControls",
816  "Play a media resource"), "");
817 
818  RegisterKey("Global", "PAGEUP", QT_TRANSLATE_NOOP("MythControls",
819  "Page Up"), "PgUp");
820  RegisterKey("Global", "PAGEDOWN", QT_TRANSLATE_NOOP("MythControls",
821  "Page Down"), "PgDown");
822  RegisterKey("Global", "PAGETOP", QT_TRANSLATE_NOOP("MythControls",
823  "Page to top of list"), "");
824  RegisterKey("Global", "PAGEMIDDLE", QT_TRANSLATE_NOOP("MythControls",
825  "Page to middle of list"), "");
826  RegisterKey("Global", "PAGEBOTTOM", QT_TRANSLATE_NOOP("MythControls",
827  "Page to bottom of list"), "");
828 
829  RegisterKey("Global", "PREVVIEW", QT_TRANSLATE_NOOP("MythControls",
830  "Previous View"), "Home");
831  RegisterKey("Global", "NEXTVIEW", QT_TRANSLATE_NOOP("MythControls",
832  "Next View"), "End");
833 
834  RegisterKey("Global", "HELP", QT_TRANSLATE_NOOP("MythControls",
835  "Help"), "F1");
836  RegisterKey("Global", "EJECT", QT_TRANSLATE_NOOP("MythControls"
837  ,"Eject Removable Media"), "");
838 
839  RegisterKey("Global", "CUT", QT_TRANSLATE_NOOP("MythControls",
840  "Cut text from textedit"), "Ctrl+X");
841  RegisterKey("Global", "COPY", QT_TRANSLATE_NOOP("MythControls"
842  ,"Copy text from textedit"), "Ctrl+C");
843  RegisterKey("Global", "PASTE", QT_TRANSLATE_NOOP("MythControls",
844  "Paste text into textedit"), "Ctrl+V");
845  RegisterKey("Global", "NEWLINE", QT_TRANSLATE_NOOP("MythControls",
846  "Insert newline into textedit"), "Ctrl+Return");
847  RegisterKey("Global", "UNDO", QT_TRANSLATE_NOOP("MythControls",
848  "Undo"), "Ctrl+Z");
849  RegisterKey("Global", "REDO", QT_TRANSLATE_NOOP("MythControls",
850  "Redo"), "Ctrl+Y");
851  RegisterKey("Global", "SEARCH", QT_TRANSLATE_NOOP("MythControls",
852  "Show incremental search dialog"), "Ctrl+S");
853 
854  RegisterKey("Global", ACTION_0, QT_TRANSLATE_NOOP("MythControls","0"), "0");
855  RegisterKey("Global", ACTION_1, QT_TRANSLATE_NOOP("MythControls","1"), "1");
856  RegisterKey("Global", ACTION_2, QT_TRANSLATE_NOOP("MythControls","2"), "2");
857  RegisterKey("Global", ACTION_3, QT_TRANSLATE_NOOP("MythControls","3"), "3");
858  RegisterKey("Global", ACTION_4, QT_TRANSLATE_NOOP("MythControls","4"), "4");
859  RegisterKey("Global", ACTION_5, QT_TRANSLATE_NOOP("MythControls","5"), "5");
860  RegisterKey("Global", ACTION_6, QT_TRANSLATE_NOOP("MythControls","6"), "6");
861  RegisterKey("Global", ACTION_7, QT_TRANSLATE_NOOP("MythControls","7"), "7");
862  RegisterKey("Global", ACTION_8, QT_TRANSLATE_NOOP("MythControls","8"), "8");
863  RegisterKey("Global", ACTION_9, QT_TRANSLATE_NOOP("MythControls","9"), "9");
864 
865  RegisterKey("Global", ACTION_TVPOWERON, QT_TRANSLATE_NOOP("MythControls",
866  "Turn the display on"), "");
867  RegisterKey("Global", ACTION_TVPOWEROFF, QT_TRANSLATE_NOOP("MythControls",
868  "Turn the display off"), "");
869 
870  RegisterKey("Global", "SYSEVENT01", QT_TRANSLATE_NOOP("MythControls",
871  "Trigger System Key Event #1"), "");
872  RegisterKey("Global", "SYSEVENT02", QT_TRANSLATE_NOOP("MythControls",
873  "Trigger System Key Event #2"), "");
874  RegisterKey("Global", "SYSEVENT03", QT_TRANSLATE_NOOP("MythControls",
875  "Trigger System Key Event #3"), "");
876  RegisterKey("Global", "SYSEVENT04", QT_TRANSLATE_NOOP("MythControls",
877  "Trigger System Key Event #4"), "");
878  RegisterKey("Global", "SYSEVENT05", QT_TRANSLATE_NOOP("MythControls",
879  "Trigger System Key Event #5"), "");
880  RegisterKey("Global", "SYSEVENT06", QT_TRANSLATE_NOOP("MythControls",
881  "Trigger System Key Event #6"), "");
882  RegisterKey("Global", "SYSEVENT07", QT_TRANSLATE_NOOP("MythControls",
883  "Trigger System Key Event #7"), "");
884  RegisterKey("Global", "SYSEVENT08", QT_TRANSLATE_NOOP("MythControls",
885  "Trigger System Key Event #8"), "");
886  RegisterKey("Global", "SYSEVENT09", QT_TRANSLATE_NOOP("MythControls",
887  "Trigger System Key Event #9"), "");
888  RegisterKey("Global", "SYSEVENT10", QT_TRANSLATE_NOOP("MythControls",
889  "Trigger System Key Event #10"), "");
890 
891  // these are for the html viewer widget (MythUIWebBrowser)
892  RegisterKey("Browser", "ZOOMIN", QT_TRANSLATE_NOOP("MythControls",
893  "Zoom in on browser window"), ".,>");
894  RegisterKey("Browser", "ZOOMOUT", QT_TRANSLATE_NOOP("MythControls",
895  "Zoom out on browser window"), ",,<");
896  RegisterKey("Browser", "TOGGLEINPUT", QT_TRANSLATE_NOOP("MythControls",
897  "Toggle where keyboard input goes to"), "F1");
898 
899  RegisterKey("Browser", "MOUSEUP", QT_TRANSLATE_NOOP("MythControls",
900  "Move mouse pointer up"), "2");
901  RegisterKey("Browser", "MOUSEDOWN", QT_TRANSLATE_NOOP("MythControls",
902  "Move mouse pointer down"), "8");
903  RegisterKey("Browser", "MOUSELEFT", QT_TRANSLATE_NOOP("MythControls",
904  "Move mouse pointer left"), "4");
905  RegisterKey("Browser", "MOUSERIGHT", QT_TRANSLATE_NOOP("MythControls",
906  "Move mouse pointer right"), "6");
907  RegisterKey("Browser", "MOUSELEFTBUTTON", QT_TRANSLATE_NOOP("MythControls",
908  "Mouse Left button click"), "5");
909 
910  RegisterKey("Browser", "PAGEDOWN", QT_TRANSLATE_NOOP("MythControls",
911  "Scroll down half a page"), "9");
912  RegisterKey("Browser", "PAGEUP", QT_TRANSLATE_NOOP("MythControls",
913  "Scroll up half a page"), "3");
914  RegisterKey("Browser", "PAGELEFT", QT_TRANSLATE_NOOP("MythControls",
915  "Scroll left half a page"), "7");
916  RegisterKey("Browser", "PAGERIGHT", QT_TRANSLATE_NOOP("MythControls",
917  "Scroll right half a page"), "1");
918 
919  RegisterKey("Browser", "NEXTLINK", QT_TRANSLATE_NOOP("MythControls",
920  "Move selection to next link"), "Z");
921  RegisterKey("Browser", "PREVIOUSLINK", QT_TRANSLATE_NOOP("MythControls",
922  "Move selection to previous link"), "Q");
923  RegisterKey("Browser", "FOLLOWLINK", QT_TRANSLATE_NOOP("MythControls",
924  "Follow selected link"), "Return,Space,Enter");
925  RegisterKey("Browser", "HISTORYBACK", QT_TRANSLATE_NOOP("MythControls",
926  "Go back to previous page"), "R,Backspace");
927  RegisterKey("Browser", "HISTORYFORWARD", QT_TRANSLATE_NOOP("MythControls",
928  "Go forward to previous page"), "F");
929 
930  RegisterKey("Main Menu", "EXITPROMPT", QT_TRANSLATE_NOOP("MythControls",
931  "Display System Exit Prompt"), "Esc");
932  RegisterKey("Main Menu", "EXIT", QT_TRANSLATE_NOOP("MythControls",
933  "System Exit"), "");
934  RegisterKey("Main Menu", "STANDBYMODE",QT_TRANSLATE_NOOP("MythControls",
935  "Enter Standby Mode"), "");
936  RegisterKey("Long Press", "LONGPRESS1",QT_TRANSLATE_NOOP("MythControls",
937  "Up to 16 Keys that allow Long Press"), "");
938  RegisterKey("Long Press", "LONGPRESS2",QT_TRANSLATE_NOOP("MythControls",
939  "Up to 16 Keys that allow Long Press"), "");
940  RegisterKey("Long Press", "LONGPRESS3",QT_TRANSLATE_NOOP("MythControls",
941  "Up to 16 Keys that allow Long Press"), "");
942  RegisterKey("Long Press", "LONGPRESS4",QT_TRANSLATE_NOOP("MythControls",
943  "Up to 16 Keys that allow Long Press"), "");
944 }
945 
947 {
948  ClearKeyContext("Global");
949  ClearKeyContext("Browser");
950  ClearKeyContext("Main Menu");
951  InitKeys();
952 }
953 
955 {
956  bool inwindow = m_wantWindow && !m_qtFullScreen;
957  bool fullscreen = m_wantFullScreen && !GeometryIsOverridden();
958  if (fullscreen && !inwindow && !m_priv->m_firstinit)
959  showFullScreen();
960  else
961  show();
962  m_priv->m_firstinit = false;
963 }
964 
965 void MythMainWindow::MoveResize(QRect& Geometry)
966 {
967  setFixedSize(Geometry.size());
968  setGeometry(Geometry);
969  if (m_painterWin)
970  {
971  m_painterWin->setFixedSize(Geometry.size());
972  m_painterWin->setGeometry(0, 0, Geometry.width(), Geometry.height());
973  }
974 }
975 
977 {
978  QMutexLocker locker(&m_priv->m_drawDisableLock);
980  if (m_priv->m_drawDisabledDepth && updatesEnabled())
981  SetDrawEnabled(false);
982  return m_priv->m_drawDisabledDepth;
983 }
984 
986 {
987  QMutexLocker locker(&m_priv->m_drawDisableLock);
989  {
991  if (!m_priv->m_drawDisabledDepth && !updatesEnabled())
992  SetDrawEnabled(true);
993  }
994  return m_priv->m_drawDisabledDepth;
995 }
996 
998 {
999  if (!gCoreContext->IsUIThread())
1000  {
1001  emit SignalSetDrawEnabled(Enable);
1002  return;
1003  }
1004 
1005  setUpdatesEnabled(Enable);
1006  if (Enable)
1007  {
1008  if (m_priv->m_pendingUpdate)
1009  {
1010  QApplication::postEvent(this, new QEvent(QEvent::UpdateRequest), Qt::LowEventPriority);
1011  m_priv->m_pendingUpdate = false;
1012  }
1014  }
1015  else
1016  {
1018  }
1019 }
1020 
1022 {
1023  for (auto *widget : qAsConst(m_priv->m_stackList))
1024  {
1025  if (Enable)
1026  widget->EnableEffects();
1027  else
1028  widget->DisableEffects();
1029  }
1030 }
1031 
1033 {
1034  return m_priv->m_exitingtomain;
1035 }
1036 
1038 {
1039  bool jumpdone = !(m_priv->m_popwindows);
1040 
1041  m_priv->m_exitingtomain = true;
1042 
1043  MythScreenStack *toplevel = GetMainStack();
1044  if (toplevel && m_priv->m_popwindows)
1045  {
1046  MythScreenType *screen = toplevel->GetTopScreen();
1047  if (screen && screen->objectName() != QString("mainmenu"))
1048  {
1049  MythEvent xe("EXIT_TO_MENU");
1050  gCoreContext->dispatch(xe);
1051  if (screen->objectName() == QString("video playback window"))
1052  {
1053  auto *me = new MythEvent("EXIT_TO_MENU");
1054  QCoreApplication::postEvent(screen, me);
1055  }
1056  else
1057  {
1058  auto *key = new QKeyEvent(QEvent::KeyPress, m_priv->m_escapekey,
1059  Qt::NoModifier);
1060  QCoreApplication::postEvent(this, key);
1062  // Notifications have their own stack. We need to continue
1063  // the propagation of the escape here if there are notifications.
1064  int num = nc->DisplayedNotifications();
1065  if (num > 0)
1066  QCoreApplication::postEvent(
1067  this, new QEvent(MythEvent::kExitToMainMenuEventType));
1068  }
1069  return;
1070  }
1071  jumpdone = true;
1072  }
1073 
1074  if (jumpdone)
1075  {
1076  m_priv->m_exitingtomain = false;
1077  m_priv->m_popwindows = true;
1079  {
1080  void (*callback)(void) = m_priv->m_exitMenuCallback;
1081  m_priv->m_exitMenuCallback = nullptr;
1082  callback();
1083  }
1085  {
1088  m_priv->m_mediaDeviceForCallback = nullptr;
1089  callback(mediadevice);
1090  }
1091  }
1092 }
1093 
1104 bool MythMainWindow::TranslateKeyPress(const QString& Context, QKeyEvent* Event,
1105  QStringList& Actions, bool AllowJumps)
1106 {
1107  Actions.clear();
1108 
1109  // Special case for custom QKeyEvent where the action is embedded directly
1110  // in the QKeyEvent text property. Used by MythFEXML http extension
1111  if (Event && Event->key() == 0 &&
1112  !Event->text().isEmpty() &&
1113  Event->modifiers() == Qt::NoModifier)
1114  {
1115  QString action = Event->text();
1116  // check if it is a jumppoint
1117  if (!m_priv->m_destinationMap.contains(action))
1118  {
1119  Actions.append(action);
1120  return false;
1121  }
1122 
1123  if (AllowJumps)
1124  {
1125  // This does not filter the jump based on the current location but
1126  // is consistent with handling of other actions that do not need
1127  // a keybinding. The network control code tries to match
1128  // GetCurrentLocation with the jumppoint but matching is utterly
1129  // inconsistent e.g. mainmenu<->Main Menu, Playback<->Live TV
1130  JumpTo(action);
1131  return true;
1132  }
1133 
1134  return false;
1135  }
1136 
1138 
1139  QStringList localActions;
1140  auto * keycontext = m_priv->m_keyContexts.value(Context);
1141  if (AllowJumps && (m_priv->m_jumpMap.count(keynum) > 0) &&
1142  (!m_priv->m_jumpMap[keynum]->m_localAction.isEmpty()) &&
1143  keycontext && (keycontext->GetMapping(keynum, localActions)))
1144  {
1145  if (localActions.contains(m_priv->m_jumpMap[keynum]->m_localAction))
1146  AllowJumps = false;
1147  }
1148 
1149  if (AllowJumps && m_priv->m_jumpMap.count(keynum) > 0 &&
1150  !m_priv->m_jumpMap[keynum]->m_exittomain && m_priv->m_exitMenuCallback == nullptr)
1151  {
1152  void (*callback)(void) = m_priv->m_jumpMap[keynum]->m_callback;
1153  callback();
1154  return true;
1155  }
1156 
1157  if (AllowJumps &&
1158  m_priv->m_jumpMap.count(keynum) > 0 && m_priv->m_exitMenuCallback == nullptr)
1159  {
1160  m_priv->m_exitingtomain = true;
1161  m_priv->m_exitMenuCallback = m_priv->m_jumpMap[keynum]->m_callback;
1162  QCoreApplication::postEvent(
1163  this, new QEvent(MythEvent::kExitToMainMenuEventType));
1164  return true;
1165  }
1166 
1167  if (keycontext)
1168  keycontext->GetMapping(keynum, Actions);
1169 
1170  if (Context != "Global")
1171  {
1172  auto * keycontextG = m_priv->m_keyContexts.value("Global");
1173  if (keycontextG)
1174  keycontextG->GetMapping(keynum, Actions);
1175  }
1176 
1177  return false;
1178 }
1179 
1180 void MythMainWindow::ClearKey(const QString& Context, const QString& Action)
1181 {
1182  auto * keycontext = m_priv->m_keyContexts.value(Context);
1183  if (keycontext == nullptr)
1184  return;
1185 
1186  QMutableMapIterator<int, QStringList> it(keycontext->m_actionMap);
1187  while (it.hasNext())
1188  {
1189  it.next();
1190  QStringList list = it.value();
1191  list.removeAll(Action);
1192  if (list.isEmpty())
1193  it.remove();
1194  }
1195 }
1196 
1197 void MythMainWindow::ClearKeyContext(const QString& Context)
1198 {
1199  auto * keycontext = m_priv->m_keyContexts.value(Context);
1200  if (keycontext != nullptr)
1201  keycontext->m_actionMap.clear();
1202 }
1203 
1204 void MythMainWindow::BindKey(const QString& Context, const QString& Action, const QString& Key)
1205 {
1206  auto * keycontext = m_priv->m_keyContexts.value(Context);
1207  if (keycontext == nullptr)
1208  {
1209  keycontext = new KeyContext();
1210  if (keycontext == nullptr)
1211  return;
1212  m_priv->m_keyContexts.insert(Context, keycontext);
1213  }
1214 
1215  QKeySequence keyseq(Key);
1216  for (unsigned int i = 0; i < static_cast<uint>(keyseq.count()); i++)
1217  {
1218 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
1219  int keynum = keyseq[i];
1220 #else
1221  int keynum = keyseq[i].toCombined();
1222 #endif
1223 
1224  QStringList dummyaction("");
1225  if (keycontext->GetMapping(keynum, dummyaction))
1226  {
1227  LOG(VB_GENERAL, LOG_WARNING, QString("Key %1 is bound to multiple actions in context %2.")
1228  .arg(Key, Context));
1229  }
1230 
1231  keycontext->AddMapping(keynum, Action);
1232 #if 0
1233  LOG(VB_GENERAL, LOG_DEBUG, QString("Binding: %1 to action: %2 (%3)")
1234  .arg(Key).arg(Action).arg(Context));
1235 #endif
1236 
1237  if (Action == "ESCAPE" && Context == "Global" && i == 0)
1238  m_priv->m_escapekey = keynum;
1239  }
1240 }
1241 
1242 void MythMainWindow::RegisterKey(const QString& Context, const QString& Action,
1243  const QString& Description, const QString& Key)
1244 {
1245  QString keybind = Key;
1246 
1247  MSqlQuery query(MSqlQuery::InitCon());
1248 
1249  if (m_priv->m_useDB && query.isConnected())
1250  {
1251  query.prepare("SELECT keylist, description FROM keybindings WHERE "
1252  "context = :CONTEXT AND action = :ACTION AND "
1253  "hostname = :HOSTNAME ;");
1254  query.bindValue(":CONTEXT", Context);
1255  query.bindValue(":ACTION", Action);
1256  query.bindValue(":HOSTNAME", GetMythDB()->GetHostName());
1257 
1258  if (query.exec() && query.next())
1259  {
1260  keybind = query.value(0).toString();
1261  QString db_description = query.value(1).toString();
1262 
1263  // Update keybinding description if changed
1264  if (db_description != Description)
1265  {
1266  LOG(VB_GENERAL, LOG_NOTICE,
1267  "Updating keybinding description...");
1268  query.prepare(
1269  "UPDATE keybindings "
1270  "SET description = :DESCRIPTION "
1271  "WHERE context = :CONTEXT AND "
1272  " action = :ACTION AND "
1273  " hostname = :HOSTNAME");
1274 
1275  query.bindValue(":DESCRIPTION", Description);
1276  query.bindValue(":CONTEXT", Context);
1277  query.bindValue(":ACTION", Action);
1278  query.bindValue(":HOSTNAME", GetMythDB()->GetHostName());
1279 
1280  if (!query.exec() && !(GetMythDB()->SuppressDBMessages()))
1281  {
1282  MythDB::DBError("Update Keybinding", query);
1283  }
1284  }
1285  }
1286  else
1287  {
1288  const QString& inskey = keybind;
1289 
1290  query.prepare("INSERT INTO keybindings (context, action, "
1291  "description, keylist, hostname) VALUES "
1292  "( :CONTEXT, :ACTION, :DESCRIPTION, :KEYLIST, "
1293  ":HOSTNAME );");
1294  query.bindValue(":CONTEXT", Context);
1295  query.bindValue(":ACTION", Action);
1296  query.bindValue(":DESCRIPTION", Description);
1297  query.bindValue(":KEYLIST", inskey);
1298  query.bindValue(":HOSTNAME", GetMythDB()->GetHostName());
1299 
1300  if (!query.exec() && !(GetMythDB()->SuppressDBMessages()))
1301  {
1302  MythDB::DBError("Insert Keybinding", query);
1303  }
1304  }
1305  }
1306 
1307  BindKey(Context, Action, keybind);
1308  m_priv->m_actionText[Context][Action] = Description;
1309 }
1310 
1311 QString MythMainWindow::GetKey(const QString& Context, const QString& Action)
1312 {
1313  MSqlQuery query(MSqlQuery::InitCon());
1314  if (!query.isConnected())
1315  return "?";
1316 
1317  query.prepare("SELECT keylist "
1318  "FROM keybindings "
1319  "WHERE context = :CONTEXT AND "
1320  " action = :ACTION AND "
1321  " hostname = :HOSTNAME");
1322  query.bindValue(":CONTEXT", Context);
1323  query.bindValue(":ACTION", Action);
1324  query.bindValue(":HOSTNAME", GetMythDB()->GetHostName());
1325 
1326  if (!query.exec() || !query.isActive() || !query.next())
1327  return "?";
1328 
1329  return query.value(0).toString();
1330 }
1331 
1332 QString MythMainWindow::GetActionText(const QString& Context,
1333  const QString& Action) const
1334 {
1335  if (m_priv->m_actionText.contains(Context))
1336  {
1337  QHash<QString, QString> entry = m_priv->m_actionText.value(Context);
1338  if (entry.contains(Action))
1339  return entry.value(Action);
1340  }
1341  return "";
1342 }
1343 
1344 void MythMainWindow::ClearJump(const QString& Destination)
1345 {
1346  // make sure that the jump point exists (using [] would add it)
1347  if (!m_priv->m_destinationMap.contains(Destination))
1348  {
1349  LOG(VB_GENERAL, LOG_ERR, "Cannot clear ficticious jump point" + Destination);
1350  return;
1351  }
1352 
1353  QMutableMapIterator<int, JumpData*> it(m_priv->m_jumpMap);
1354  while (it.hasNext())
1355  {
1356  it.next();
1357  JumpData *jd = it.value();
1358  if (jd->m_destination == Destination)
1359  it.remove();
1360  }
1361 }
1362 
1363 
1364 void MythMainWindow::BindJump(const QString& Destination, const QString& Key)
1365 {
1366  // make sure the jump point exists
1367  if (!m_priv->m_destinationMap.contains(Destination))
1368  {
1369  LOG(VB_GENERAL, LOG_ERR, "Cannot bind to ficticious jump point" + Destination);
1370  return;
1371  }
1372 
1373  QKeySequence keyseq(Key);
1374 
1375  for (unsigned int i = 0; i < static_cast<uint>(keyseq.count()); i++)
1376  {
1377 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
1378  int keynum = keyseq[i];
1379 #else
1380  int keynum = keyseq[i].toCombined();
1381 #endif
1382 
1383  if (m_priv->m_jumpMap.count(keynum) == 0)
1384  {
1385 #if 0
1386  LOG(VB_GENERAL, LOG_DEBUG, QString("Binding: %1 to JumpPoint: %2")
1387  .arg(keybind).arg(destination));
1388 #endif
1389 
1390  m_priv->m_jumpMap[keynum] = &m_priv->m_destinationMap[Destination];
1391  }
1392  else
1393  {
1394  LOG(VB_GENERAL, LOG_WARNING, QString("Key %1 is already bound to a jump point.")
1395  .arg(Key));
1396  }
1397  }
1398 #if 0
1399  else
1400  LOG(VB_GENERAL, LOG_DEBUG,
1401  QString("JumpPoint: %2 exists, no keybinding") .arg(destination));
1402 #endif
1403 }
1404 
1405 void MythMainWindow::RegisterJump(const QString& Destination, const QString& Description,
1406  const QString& Key, void (*Callback)(void),
1407  bool Exittomain, QString LocalAction)
1408 {
1409  QString keybind = Key;
1410 
1411  MSqlQuery query(MSqlQuery::InitCon());
1412  if (query.isConnected())
1413  {
1414  query.prepare("SELECT keylist FROM jumppoints WHERE destination = :DEST and hostname = :HOST ;");
1415  query.bindValue(":DEST", Destination);
1416  query.bindValue(":HOST", GetMythDB()->GetHostName());
1417  if (query.exec() && query.next())
1418  {
1419  keybind = query.value(0).toString();
1420  }
1421  else
1422  {
1423  const QString& inskey = keybind;
1424 
1425  query.prepare("INSERT INTO jumppoints (destination, description, "
1426  "keylist, hostname) VALUES ( :DEST, :DESC, :KEYLIST, "
1427  ":HOST );");
1428  query.bindValue(":DEST", Destination);
1429  query.bindValue(":DESC", Description);
1430  query.bindValue(":KEYLIST", inskey);
1431  query.bindValue(":HOST", GetMythDB()->GetHostName());
1432  if (!query.exec() || !query.isActive())
1433  MythDB::DBError("Insert Jump Point", query);
1434  }
1435  }
1436 
1437  JumpData jd = { Callback, Destination, Description, Exittomain, std::move(LocalAction) };
1438  m_priv->m_destinationMap[Destination] = jd;
1439  BindJump(Destination, keybind);
1440 }
1441 
1443 {
1444  QList<QString> destinations = m_priv->m_destinationMap.keys();
1445  QList<QString>::Iterator it;
1446  for (it = destinations.begin(); it != destinations.end(); ++it)
1447  ClearJump(*it);
1448 }
1449 
1450 void MythMainWindow::JumpTo(const QString& Destination, bool Pop)
1451 {
1452  if (m_priv->m_destinationMap.count(Destination) > 0 && m_priv->m_exitMenuCallback == nullptr)
1453  {
1454  m_priv->m_exitingtomain = true;
1455  m_priv->m_popwindows = Pop;
1456  m_priv->m_exitMenuCallback = m_priv->m_destinationMap[Destination].m_callback;
1457  QCoreApplication::postEvent(
1458  this, new QEvent(MythEvent::kExitToMainMenuEventType));
1459  return;
1460  }
1461 }
1462 
1463 bool MythMainWindow::DestinationExists(const QString& Destination) const
1464 {
1465  return m_priv->m_destinationMap.count(Destination) > 0;
1466 }
1467 
1469 {
1470  return m_priv->m_destinationMap.keys();
1471 }
1472 
1473 void MythMainWindow::RegisterMediaPlugin(const QString& Name, const QString& Desc,
1474  MediaPlayCallback Func)
1475 {
1476  if (m_priv->m_mediaPluginMap.count(Name) == 0)
1477  {
1478  LOG(VB_GENERAL, LOG_NOTICE, QString("Registering %1 as a media playback plugin.")
1479  .arg(Name));
1480  m_priv->m_mediaPluginMap[Name] = { Desc, Func };
1481  }
1482  else
1483  {
1484  LOG(VB_GENERAL, LOG_NOTICE, QString("%1 is already registered as a media playback plugin.")
1485  .arg(Name));
1486  }
1487 }
1488 
1489 bool MythMainWindow::HandleMedia(const QString& Handler, const QString& Mrl,
1490  const QString& Plot, const QString& Title,
1491  const QString& Subtitle,
1492  const QString& Director, int Season,
1493  int Episode, const QString& Inetref,
1494  std::chrono::minutes LenMins, const QString& Year,
1495  const QString& Id, bool UseBookmarks)
1496 {
1497  QString lhandler(Handler);
1498  if (lhandler.isEmpty())
1499  lhandler = "Internal";
1500 
1501  // Let's see if we have a plugin that matches the handler name...
1502  if (m_priv->m_mediaPluginMap.contains(lhandler))
1503  {
1504  m_priv->m_mediaPluginMap[lhandler].second(Mrl, Plot, Title, Subtitle,
1505  Director, Season, Episode,
1506  Inetref, LenMins, Year, Id,
1507  UseBookmarks);
1508  return true;
1509  }
1510 
1511  return false;
1512 }
1513 
1515 {
1517 }
1518 
1520 {
1521  m_priv->m_allowInput = Allow;
1522 }
1523 
1525 {
1526  // complete the stroke if its our first timeout
1527  if (m_priv->m_gesture.Recording())
1528  m_priv->m_gesture.Stop(true);
1529 
1530  // get the last gesture
1531  auto * event = m_priv->m_gesture.GetGesture();
1532  if (event->GetGesture() < MythGestureEvent::Click)
1533  QCoreApplication::postEvent(this, event);
1534 }
1535 
1536 // Return code = true to skip further processing, false to continue
1537 // sNewEvent: Caller must pass in a QScopedPointer that will be used
1538 // to delete a new event if one is created.
1539 bool MythMainWindow::KeyLongPressFilter(QEvent** Event, QScopedPointer<QEvent>& NewEvent)
1540 {
1541  auto * keyevent = dynamic_cast<QKeyEvent*>(*Event);
1542  if (!keyevent)
1543  return false;
1544  int keycode = keyevent->key();
1545  // Ignore unknown key codes
1546  if (keycode == 0)
1547  return false;
1548 
1549  QEvent *newevent = nullptr;
1550  switch ((*Event)->type())
1551  {
1552  case QEvent::KeyPress:
1553  {
1554  // Check if we are in the middle of a long press
1555  if (keycode == m_priv->m_longPressKeyCode)
1556  {
1557  if (std::chrono::milliseconds(keyevent->timestamp()) - m_priv->m_longPressTime < LONGPRESS_INTERVAL
1558  || m_priv->m_longPressTime == 0ms)
1559  {
1560  // waiting for release of key.
1561  return true; // discard the key press
1562  }
1563 
1564  // expired log press - generate long key
1565  newevent = new QKeyEvent(QEvent::KeyPress, keycode,
1566  keyevent->modifiers() | Qt::MetaModifier, keyevent->nativeScanCode(),
1567  keyevent->nativeVirtualKey(), keyevent->nativeModifiers(),
1568  keyevent->text(), false,1);
1569  *Event = newevent;
1570  NewEvent.reset(newevent);
1571  m_priv->m_longPressTime = 0ms; // indicate we have generated the long press
1572  return false;
1573  }
1574  // If we got a keycode different from the long press keycode it
1575  // may have been injected by a jump point. Ignore it.
1576  if (m_priv->m_longPressKeyCode != 0)
1577  return false;
1578 
1579  // Process start of possible new long press.
1581  QStringList actions;
1582  bool handled = TranslateKeyPress("Long Press", keyevent, actions,false);
1583  if (handled)
1584  {
1585  // This shoudl never happen,, because we passed in false
1586  // to say do not process jump points and yet it returned true
1587  // to say it processed a jump point.
1588  LOG(VB_GUI, LOG_ERR, QString("TranslateKeyPress Long Press Invalid Response"));
1589  return true;
1590  }
1591  if (!actions.empty() && actions[0].startsWith("LONGPRESS"))
1592  {
1593  // Beginning of a press
1594  m_priv->m_longPressKeyCode = keycode;
1595  m_priv->m_longPressTime = std::chrono::milliseconds(keyevent->timestamp());
1596  return true; // discard the key press
1597  }
1598  break;
1599  }
1600  case QEvent::KeyRelease:
1601  {
1602  if (keycode == m_priv->m_longPressKeyCode)
1603  {
1604  if (keyevent->isAutoRepeat())
1605  return true;
1606  if (m_priv->m_longPressTime > 0ms)
1607  {
1608  // short press or non-repeating keyboard - generate key
1609  Qt::KeyboardModifiers modifier = Qt::NoModifier;
1610  if (std::chrono::milliseconds(keyevent->timestamp()) - m_priv->m_longPressTime >= LONGPRESS_INTERVAL)
1611  {
1612  // non-repeatng keyboard
1613  modifier = Qt::MetaModifier;
1614  }
1615  newevent = new QKeyEvent(QEvent::KeyPress, keycode,
1616  keyevent->modifiers() | modifier, keyevent->nativeScanCode(),
1617  keyevent->nativeVirtualKey(), keyevent->nativeModifiers(),
1618  keyevent->text(), false,1);
1619  *Event = newevent;
1620  NewEvent.reset(newevent);
1622  return false;
1623  }
1624 
1625  // end of long press
1627  return true;
1628  }
1629  break;
1630  }
1631  default:
1632  break;
1633  }
1634  return false;
1635 }
1636 
1637 bool MythMainWindow::eventFilter(QObject* Watched, QEvent* Event)
1638 {
1639  /* Don't let anything through if input is disallowed. */
1640  if (!m_priv->m_allowInput)
1641  return true;
1642 
1643  QScopedPointer<QEvent> newevent(nullptr);
1644  if (KeyLongPressFilter(&Event, newevent))
1645  return true;
1646 
1647  switch (Event->type())
1648  {
1649  case QEvent::KeyPress:
1650  {
1651  ResetIdleTimer();
1652  auto * event = dynamic_cast<QKeyEvent*>(Event);
1653 
1654  // Work around weird GCC run-time bug. Only manifest on Mac OS X
1655  if (!event)
1656  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast)
1657  event = static_cast<QKeyEvent*>(Event);
1658 
1659 #ifdef Q_OS_LINUX
1660  // Fixups for _some_ linux native codes that QT doesn't know
1661  if (event && event->key() <= 0)
1662  {
1663  int keycode = 0;
1664  switch (event->nativeScanCode())
1665  {
1666  case 209: // XF86AudioPause
1667  keycode = Qt::Key_MediaPause;
1668  break;
1669  default:
1670  break;
1671  }
1672 
1673  if (keycode > 0)
1674  {
1675  auto * key = new QKeyEvent(QEvent::KeyPress, keycode, event->modifiers());
1676  if (auto * target = GetTarget(*key); target)
1677  QCoreApplication::postEvent(target, key);
1678  else
1679  QCoreApplication::postEvent(this, key);
1680  return true;
1681  }
1682  }
1683 #endif
1684 
1685  QVector<MythScreenStack *>::const_reverse_iterator it;
1686  for (it = m_priv->m_stackList.rbegin(); it != m_priv->m_stackList.rend(); it++)
1687  {
1688  if (auto * top = (*it)->GetTopScreen(); top)
1689  {
1690  if (top->keyPressEvent(event))
1691  return true;
1692  // Note: The following break prevents keypresses being
1693  // sent to windows below popups
1694  if ((*it)->objectName() == "popup stack")
1695  break;
1696  }
1697  }
1698  break;
1699  }
1700  case QEvent::InputMethod:
1701  {
1702  ResetIdleTimer();
1703  auto *ie = dynamic_cast<QInputMethodEvent*>(Event);
1704  if (!ie)
1705  return MythUIScreenBounds::eventFilter(Watched, Event);
1706  QWidget *widget = QApplication::focusWidget();
1707  if (widget)
1708  {
1709  ie->accept();
1710  if (widget->isEnabled())
1711  QCoreApplication::instance()->notify(widget, ie);
1712  break;
1713  }
1714  QVector<MythScreenStack *>::const_reverse_iterator it;
1715  for (it = m_priv->m_stackList.rbegin(); it != m_priv->m_stackList.rend(); it++)
1716  {
1717  MythScreenType *top = (*it)->GetTopScreen();
1718  if (top == nullptr)
1719  continue;
1720  if (top->inputMethodEvent(ie))
1721  return true;
1722  // Note: The following break prevents keypresses being
1723  // sent to windows below popups
1724  if ((*it)->objectName() == "popup stack")
1725  break;
1726  }
1727  break;
1728  }
1729  case QEvent::MouseButtonPress:
1730  {
1731  ResetIdleTimer();
1732  ShowMouseCursor(true);
1733  if (!m_priv->m_gesture.Recording())
1734  {
1735  m_priv->m_gesture.Start();
1736  auto * mouseEvent = dynamic_cast<QMouseEvent*>(Event);
1737  if (!mouseEvent)
1738  return MythUIScreenBounds::eventFilter(Watched, Event);
1739  m_priv->m_gesture.Record(mouseEvent->pos(), mouseEvent->button());
1740  /* start a single shot timer */
1742  return true;
1743  }
1744  break;
1745  }
1746  case QEvent::MouseButtonRelease:
1747  {
1748  ResetIdleTimer();
1749  ShowMouseCursor(true);
1750  if (m_priv->m_gestureTimer->isActive())
1751  m_priv->m_gestureTimer->stop();
1752 
1753  if (m_priv->m_gesture.Recording())
1754  {
1755  m_priv->m_gesture.Stop();
1756  auto * gesture = m_priv->m_gesture.GetGesture();
1757  QPoint point { -1, -1 };
1758  auto * mouseevent = dynamic_cast<QMouseEvent*>(Event);
1759  if (mouseevent)
1760  {
1761  point = mouseevent->pos();
1762  gesture->SetPosition(point);
1763  }
1764 
1765  // Handle clicks separately
1766  if (gesture->GetGesture() == MythGestureEvent::Click)
1767  {
1768  if (!mouseevent)
1769  return MythUIScreenBounds::eventFilter(Watched, Event);
1770 
1771  QVector<MythScreenStack *>::const_reverse_iterator it;
1772  for (it = m_priv->m_stackList.rbegin(); it != m_priv->m_stackList.rend(); it++)
1773  {
1774  auto * screen = (*it)->GetTopScreen();
1775  if (!screen || !screen->ContainsPoint(point))
1776  continue;
1777 
1778  if (screen->gestureEvent(gesture))
1779  break;
1780  // Note: The following break prevents clicks being
1781  // sent to windows below popups
1782  //
1783  // we want to permit this in some cases, e.g.
1784  // when the music miniplayer is on screen or a
1785  // non-interactive alert/news scroller. So these
1786  // things need to be in a third or more stack
1787  if ((*it)->objectName() == "popup stack")
1788  break;
1789  }
1790  delete gesture;
1791  }
1792  else
1793  {
1794  bool handled = false;
1795 
1796  if (!mouseevent)
1797  {
1798  QCoreApplication::postEvent(this, gesture);
1799  return true;
1800  }
1801 
1802  QVector<MythScreenStack *>::const_reverse_iterator it;
1803  for (it = m_priv->m_stackList.rbegin(); it != m_priv->m_stackList.rend(); it++)
1804  {
1805  MythScreenType *screen = (*it)->GetTopScreen();
1806  if (!screen || !screen->ContainsPoint(point))
1807  continue;
1808 
1809  if (screen->gestureEvent(gesture))
1810  {
1811  handled = true;
1812  break;
1813  }
1814  // Note: The following break prevents clicks being
1815  // sent to windows below popups
1816  //
1817  // we want to permit this in some cases, e.g.
1818  // when the music miniplayer is on screen or a
1819  // non-interactive alert/news scroller. So these
1820  // things need to be in a third or more stack
1821  if ((*it)->objectName() == "popup stack")
1822  break;
1823  }
1824 
1825  if (handled)
1826  delete gesture;
1827  else
1828  QCoreApplication::postEvent(this, gesture);
1829  }
1830 
1831  return true;
1832  }
1833  break;
1834  }
1835  case QEvent::MouseMove:
1836  {
1837  ResetIdleTimer();
1838  ShowMouseCursor(true);
1839  if (m_priv->m_gesture.Recording())
1840  {
1841  // Reset the timer
1842  m_priv->m_gestureTimer->stop();
1844  auto * mouseevent = dynamic_cast<QMouseEvent*>(Event);
1845  if (!mouseevent)
1846  return MythUIScreenBounds::eventFilter(Watched, Event);
1847  m_priv->m_gesture.Record(mouseevent->pos(), mouseevent->button());
1848  return true;
1849  }
1850  break;
1851  }
1852  case QEvent::Wheel:
1853  {
1854  ResetIdleTimer();
1855  ShowMouseCursor(true);
1856  auto * wheel = dynamic_cast<QWheelEvent*>(Event);
1857  if (wheel == nullptr)
1858  return MythUIScreenBounds::eventFilter(Watched, Event);
1859  int delta = wheel->angleDelta().y();
1860  if (delta>0)
1861  {
1862  wheel->accept();
1863  auto *key = new QKeyEvent(QEvent::KeyPress, Qt::Key_Up, Qt::NoModifier);
1864  if (auto * target = GetTarget(*key); target)
1865  QCoreApplication::postEvent(target, key);
1866  else
1867  QCoreApplication::postEvent(this, key);
1868  }
1869  if (delta < 0)
1870  {
1871  wheel->accept();
1872  auto * key = new QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier);
1873  if (auto * target = GetTarget(*key); !target)
1874  QCoreApplication::postEvent(target, key);
1875  else
1876  QCoreApplication::postEvent(this, key);
1877  }
1878  break;
1879  }
1880  default:
1881  break;
1882  }
1883 
1884  return MythUIScreenBounds::eventFilter(Watched, Event);
1885 }
1886 
1888 {
1889  if (Event->type() == MythGestureEvent::kEventType)
1890  {
1891  auto * gesture = dynamic_cast<MythGestureEvent*>(Event);
1892  if (gesture == nullptr)
1893  return;
1894  if (auto * toplevel = GetMainStack(); toplevel)
1895  if (auto * screen = toplevel->GetTopScreen(); screen)
1896  screen->gestureEvent(gesture);
1897  LOG(VB_GUI, LOG_DEBUG, QString("Gesture: %1 (Button: %2)")
1898  .arg(gesture->GetName(), gesture->GetButtonName()));
1899  }
1901  {
1902  ExitToMainMenu();
1903  }
1904  else if (Event->type() == ExternalKeycodeEvent::kEventType)
1905  {
1906  auto * event = dynamic_cast<ExternalKeycodeEvent *>(Event);
1907  if (event == nullptr)
1908  return;
1909  auto * key = new QKeyEvent(QEvent::KeyPress, event->getKeycode(), Qt::NoModifier);
1910  if (auto * target = GetTarget(*key); target)
1911  QCoreApplication::sendEvent(target, key);
1912  else
1913  QCoreApplication::sendEvent(this, key);
1914  }
1915  else if (Event->type() == MythMediaEvent::kEventType)
1916  {
1917  auto *me = dynamic_cast<MythMediaEvent*>(Event);
1918  if (me == nullptr)
1919  return;
1920 
1921  // A listener based system might be more efficient, but we should never
1922  // have that many screens open at once so impact should be minimal.
1923  //
1924  // This approach is simpler for everyone to follow. Plugin writers
1925  // don't have to worry about adding their screens to the list because
1926  // all screens receive media events.
1927  //
1928  // Events are even sent to hidden or backgrounded screens, this avoids
1929  // the need for those to poll for changes when they become visible again
1930  // however this needs to be kept in mind if media changes trigger
1931  // actions which would not be appropriate when the screen doesn't have
1932  // focus. It is the programmers responsibility to ignore events when
1933  // necessary.
1934  for (auto * widget : qAsConst(m_priv->m_stackList))
1935  {
1936  QVector<MythScreenType*> screenList;
1937  widget->GetScreenList(screenList);
1938  for (auto * screen : qAsConst(screenList))
1939  if (screen)
1940  screen->mediaEvent(me);
1941  }
1942 
1943  // Debugging
1944  if (MythMediaDevice* device = me->getDevice(); device)
1945  {
1946  LOG(VB_GENERAL, LOG_DEBUG, QString("Media Event: %1 - %2")
1947  .arg(device->getDevicePath()).arg(device->getStatus()));
1948  }
1949  }
1950  else if (Event->type() == MythEvent::kPushDisableDrawingEventType)
1951  {
1952  PushDrawDisabled();
1953  }
1954  else if (Event->type() == MythEvent::kPopDisableDrawingEventType)
1955  {
1956  PopDrawDisabled();
1957  }
1958  else if (Event->type() == MythEvent::kLockInputDevicesEventType)
1959  {
1960  m_deviceHandler->IgnoreKeys(true);
1961  PauseIdleTimer(true);
1962  }
1963  else if (Event->type() == MythEvent::kUnlockInputDevicesEventType)
1964  {
1965  m_deviceHandler->IgnoreKeys(false);
1966  PauseIdleTimer(false);
1967  }
1968  else if (Event->type() == MythEvent::kDisableUDPListenerEventType)
1969  {
1971  }
1972  else if (Event->type() == MythEvent::kEnableUDPListenerEventType)
1973  {
1975  }
1976  else if (Event->type() == MythEvent::MythEventMessage)
1977  {
1978  auto * event = dynamic_cast<MythEvent *>(Event);
1979  if (event == nullptr)
1980  return;
1981 
1982  QString message = event->Message();
1983  if (message.startsWith(ACTION_HANDLEMEDIA))
1984  {
1985  if (event->ExtraDataCount() == 1)
1986  HandleMedia("Internal", event->ExtraData(0));
1987  else if (event->ExtraDataCount() >= 11)
1988  {
1989  bool usebookmark = true;
1990  if (event->ExtraDataCount() >= 12)
1991  usebookmark = (event->ExtraData(11).toInt() != 0);
1992  HandleMedia("Internal", event->ExtraData(0),
1993  event->ExtraData(1), event->ExtraData(2),
1994  event->ExtraData(3), event->ExtraData(4),
1995  event->ExtraData(5).toInt(), event->ExtraData(6).toInt(),
1996  event->ExtraData(7), std::chrono::minutes(event->ExtraData(8).toInt()),
1997  event->ExtraData(9), event->ExtraData(10),
1998  usebookmark);
1999  }
2000  else
2001  {
2002  LOG(VB_GENERAL, LOG_ERR, "Failed to handle media");
2003  }
2004  }
2005  else if (message.startsWith(ACTION_SCREENSHOT))
2006  {
2007  int width = 0;
2008  int height = 0;
2009  QString filename;
2010  if (event->ExtraDataCount() >= 2)
2011  {
2012  width = event->ExtraData(0).toInt();
2013  height = event->ExtraData(1).toInt();
2014  if (event->ExtraDataCount() == 3)
2015  filename = event->ExtraData(2);
2016  }
2017  ScreenShot(width, height, filename);
2018  }
2019  else if (message == ACTION_GETSTATUS)
2020  {
2021  QVariantMap state;
2022  state.insert("state", "idle");
2023  state.insert("menutheme", GetMythDB()->GetSetting("menutheme", "defaultmenu"));
2024  state.insert("currentlocation", GetMythUI()->GetCurrentLocation());
2026  }
2027  else if (message == "CLEAR_SETTINGS_CACHE")
2028  {
2029  // update the idle time
2030  m_idleTime =
2031  gCoreContext->GetDurSetting<std::chrono::minutes>("FrontendIdleTimeout",
2032  STANDBY_TIMEOUT);
2033 
2034  if (m_idleTime < 0min)
2035  m_idleTime = 0min;
2036  m_idleTimer.stop();
2037  if (m_idleTime > 0min)
2038  {
2039  m_idleTimer.setInterval(m_idleTime);
2040  m_idleTimer.start();
2041  LOG(VB_GENERAL, LOG_INFO, QString("Updating the frontend idle time to: %1 mins").arg(m_idleTime.count()));
2042  }
2043  else
2044  {
2045  LOG(VB_GENERAL, LOG_INFO, "Frontend idle timeout is disabled");
2046  }
2047  }
2048  else if (message == "NOTIFICATION")
2049  {
2050  MythNotification mn(*event);
2052  return;
2053  }
2054  else if (message == "RECONNECT_SUCCESS" && m_priv->m_standby)
2055  {
2056  // If the connection to the master backend has just been (re-)established
2057  // but we're in standby, make sure the backend is not blocked from
2058  // shutting down.
2060  }
2061  }
2062  else if (Event->type() == MythEvent::MythUserMessage)
2063  {
2064  if (auto * event = dynamic_cast<MythEvent *>(Event); event != nullptr)
2065  if (const QString& message = event->Message(); !message.isEmpty())
2066  ShowOkPopup(message);
2067  }
2068  else if (Event->type() == MythNotificationCenterEvent::kEventType)
2069  {
2071  }
2072 }
2073 
2074 QObject* MythMainWindow::GetTarget(QKeyEvent& Key)
2075 {
2076  auto * target = QWidget::keyboardGrabber();
2077  if (!target)
2078  {
2079  if (auto * widget = QApplication::focusWidget(); widget && widget->isEnabled())
2080  {
2081  target = widget;
2082  // Yes this is special code for handling the
2083  // the escape key.
2084  if (Key.key() == m_priv->m_escapekey && widget->topLevelWidget())
2085  target = widget->topLevelWidget();
2086  }
2087  }
2088 
2089  if (!target)
2090  target = this;
2091  return target;
2092 }
2093 
2095 {
2097 }
2098 
2100 {
2101  if (Show && GetMythDB()->GetBoolSetting("HideMouseCursor", false))
2102  return;
2103 
2104  // Set cursor call must come after Show() to work on some systems.
2105  setCursor(Show ? (Qt::ArrowCursor) : (Qt::BlankCursor));
2106  if (Show)
2107  m_priv->m_hideMouseTimer->start();
2108 }
2109 
2111 {
2112  ShowMouseCursor(false);
2113 }
2114 
2118 void MythMainWindow::DisableIdleTimer(bool DisableIdle)
2119 {
2120  if ((m_priv->m_disableIdle = DisableIdle))
2121  m_idleTimer.stop();
2122  else
2123  m_idleTimer.start();
2124 }
2125 
2130 {
2131  if (m_priv->m_disableIdle)
2132  return;
2133 
2134  if (m_idleTime == 0min || !m_idleTimer.isActive() || (m_priv->m_standby && m_priv->m_enteringStandby))
2135  return;
2136 
2137  if (m_priv->m_standby)
2138  ExitStandby(false);
2139 
2140  m_idleTimer.start();
2141 }
2142 
2147 {
2148  if (m_priv->m_disableIdle)
2149  return;
2150 
2151  // don't do anything if the idle timer is disabled
2152  if (m_idleTime == 0min)
2153  return;
2154 
2155  if (Pause)
2156  {
2157  LOG(VB_GENERAL, LOG_NOTICE, "Suspending idle timer");
2158  m_idleTimer.stop();
2159  }
2160  else
2161  {
2162  LOG(VB_GENERAL, LOG_NOTICE, "Resuming idle timer");
2163  m_idleTimer.start();
2164  }
2165 
2166  // ResetIdleTimer();
2167 }
2168 
2170 {
2171  if (m_priv->m_disableIdle)
2172  return;
2173 
2174  m_priv->m_enteringStandby = false;
2175 
2176  if (m_idleTime > 0min && !m_priv->m_standby)
2177  {
2178  LOG(VB_GENERAL, LOG_NOTICE,
2179  QString("Entering standby mode after %1 minutes of inactivity").arg(m_idleTime.count()));
2180  EnterStandby(false);
2181  if (gCoreContext->GetNumSetting("idleTimeoutSecs", 0) > 0)
2182  {
2183  m_priv->m_enteringStandby = true;
2184  JumpTo("Standby Mode");
2185  }
2186  }
2187 }
2188 
2190 {
2191  if (Manual && m_priv->m_enteringStandby)
2192  m_priv->m_enteringStandby = false;
2193 
2194  if (m_priv->m_standby)
2195  return;
2196 
2197  // We've manually entered standby mode and we want to pause the timer
2198  // to prevent it being Reset
2199  if (Manual)
2200  {
2201  PauseIdleTimer(true);
2202  LOG(VB_GENERAL, LOG_NOTICE, QString("Entering standby mode"));
2203  }
2204 
2205  m_priv->m_standby = true;
2207 
2208  QVariantMap state;
2209  state.insert("state", "standby");
2210  state.insert("menutheme", GetMythDB()->GetSetting("menutheme", "defaultmenu"));
2211  state.insert("currentlocation", GetMythUI()->GetCurrentLocation());
2213 
2214  // Cache WOL settings in case DB goes down
2215  QString masterserver = gCoreContext->GetSetting("MasterServerName");
2216  gCoreContext->GetSettingOnHost("BackendServerAddr", masterserver);
2218  gCoreContext->GetSetting("WOLbackendCommand", "");
2219 
2220  // While in standby do not attempt to wake the backend
2221  gCoreContext->SetWOLAllowed(false);
2222 }
2223 
2225 {
2227  return;
2228 
2229  if (Manual)
2230  PauseIdleTimer(false);
2231  else if (gCoreContext->GetNumSetting("idleTimeoutSecs", 0) > 0)
2232  JumpTo("Main Menu");
2233 
2234  if (!m_priv->m_standby)
2235  return;
2236 
2237  LOG(VB_GENERAL, LOG_NOTICE, "Leaving standby mode");
2238  m_priv->m_standby = false;
2239 
2240  // We may attempt to wake the backend
2241  gCoreContext->SetWOLAllowed(true);
2243 
2244  QVariantMap state;
2245  state.insert("state", "idle");
2246  state.insert("menutheme", GetMythDB()->GetSetting("menutheme", "defaultmenu"));
2247  state.insert("currentlocation", GetMythUI()->GetCurrentLocation());
2249 }
2250 
2252 {
2253  LOG(VB_GENERAL, LOG_NOTICE, QString("Application State Changed to %1").arg(State));
2254  switch (State)
2255  {
2256  case Qt::ApplicationState::ApplicationActive:
2257  PopDrawDisabled();
2258  break;
2259  case Qt::ApplicationState::ApplicationSuspended:
2260  PushDrawDisabled();
2261  break;
2262  default:
2263  break;
2264  }
2265 }
2266 /* vim: set expandtab tabstop=4 shiftwidth=4: */
MythUIScreenBounds::m_alwaysOnTop
bool m_alwaysOnTop
Definition: mythuiscreenbounds.h:50
MythMainWindow::BindJump
void BindJump(const QString &Destination, const QString &Key)
Definition: mythmainwindow.cpp:1364
MSqlQuery::isActive
bool isActive(void) const
Definition: mythdbcon.h:216
MythCoreContext::SetWOLAllowed
void SetWOLAllowed(bool allow)
Definition: mythcorecontext.cpp:627
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:811
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:128
build_compdb.args
args
Definition: build_compdb.py:11
MythPainterWindow::DestroyPainters
static void DestroyPainters(MythPainterWindow *&PaintWin, MythPainter *&Painter)
Definition: mythpainterwindow.cpp:132
MythUIStateTracker::SetState
static void SetState(const QVariantMap &NewState)
Definition: mythuistatetracker.cpp:26
MythMainWindow::GetMainStack
MythScreenStack * GetMainStack()
Definition: mythmainwindow.cpp:315
mythrect.h
mythevent.h
MythMainWindow::m_idleTimer
QTimer m_idleTimer
Definition: mythmainwindow.h:164
MythEvent::kLockInputDevicesEventType
static Type kLockInputDevicesEventType
Definition: mythevent.h:86
MythDate::toString
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
Definition: mythdate.cpp:84
MythEvent::MythEventMessage
static Type MythEventMessage
Definition: mythevent.h:79
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:103
ACTION_DOWN
static constexpr const char * ACTION_DOWN
Definition: mythuiactions.h:17
MythMainWindow::closeEvent
void closeEvent(QCloseEvent *Event) override
Definition: mythmainwindow.cpp:474
MythInputDeviceHandler::MainWindowReady
void MainWindowReady(void)
Definition: mythinputdevicehandler.cpp:201
MythMainWindow::Init
void Init(bool MayReInit=true)
Definition: mythmainwindow.cpp:638
MythNotificationCenter::ProcessQueue
void ProcessQueue(void)
ProcessQueue will be called by the GUI event handler and will process all queued MythNotifications an...
Definition: mythnotificationcenter.cpp:1354
MythMainWindow::OnApplicationStateChange
void OnApplicationStateChange(Qt::ApplicationState State)
Definition: mythmainwindow.cpp:2251
MythDisplay::SwitchToDesktop
void SwitchToDesktop()
Return the screen to the original desktop video mode.
Definition: mythdisplay.cpp:683
MythMainWindowPrivate::m_mediaDeviceForCallback
MythMediaDevice * m_mediaDeviceForCallback
Definition: mythmainwindowprivate.h:69
GESTURE_TIMEOUT
static constexpr std::chrono::milliseconds GESTURE_TIMEOUT
Definition: mythmainwindow.cpp:62
MythMainWindow::SignalDisableScreensaver
void SignalDisableScreensaver()
MythMainWindowPrivate::m_pendingUpdate
bool m_pendingUpdate
Definition: mythmainwindowprivate.h:84
mythdb.h
MythPainter::SupportsClipping
virtual bool SupportsClipping(void)=0
MythMainWindowPrivate::m_longPressKeyCode
int m_longPressKeyCode
Definition: mythmainwindowprivate.h:88
MythMainWindow::SaveScreenShot
static bool SaveScreenShot(const QImage &Image, QString Filename="")
Definition: mythmainwindow.cpp:534
MythCoreContext::AllowShutdown
void AllowShutdown(void)
Definition: mythcorecontext.cpp:608
ACTION_SCREENSHOT
static constexpr const char * ACTION_SCREENSHOT
Definition: mythuiactions.h:22
MythGesture::Recording
bool Recording()
Determine if the stroke is being recorded.
Definition: mythgesture.cpp:142
MythUIScreenBounds::UpdateScreenSettings
void UpdateScreenSettings(MythDisplay *mDisplay)
Definition: mythuiscreenbounds.cpp:144
MythMainWindow::SignalWindowReady
void SignalWindowReady()
LONGPRESS_INTERVAL
static constexpr std::chrono::milliseconds LONGPRESS_INTERVAL
Definition: mythmainwindow.cpp:64
MythEvent::kPushDisableDrawingEventType
static Type kPushDisableDrawingEventType
Definition: mythevent.h:84
MythGesture::Start
void Start()
Start recording.
Definition: mythgesture.cpp:151
MythMainWindowPrivate::m_gestureTimer
QTimer * m_gestureTimer
Definition: mythmainwindowprivate.h:75
MythUIScreenBounds::m_wantFullScreen
bool m_wantFullScreen
Definition: mythuiscreenbounds.h:48
MythMainWindow::MythMainWindow
MythMainWindow(bool UseDB=true)
Definition: mythmainwindow.cpp:129
MythMainWindowPrivate::m_useDB
bool m_useDB
To allow or prevent database access.
Definition: mythmainwindowprivate.h:59
MythInputDeviceHandler::Action
void Action(const QString &Action)
Definition: mythinputdevicehandler.cpp:180
MythMainWindow::GetStackCount
int GetStackCount()
Definition: mythmainwindow.cpp:310
MythMainWindow::JumpTo
void JumpTo(const QString &Destination, bool Pop=true)
Definition: mythmainwindow.cpp:1450
MythMainWindowPrivate::m_disableIdle
bool m_disableIdle
Definition: mythmainwindowprivate.h:82
MythMainWindow::getMainWindow
static MythMainWindow * getMainWindow(bool UseDB=true)
Return the existing main window, or create one.
Definition: mythmainwindow.cpp:78
MythUIScreenBounds::m_qtFullScreen
bool m_qtFullScreen
Definition: mythuiscreenbounds.h:49
MythEvent::kPopDisableDrawingEventType
static Type kPopDisableDrawingEventType
Definition: mythevent.h:85
MythMainWindow::ClearAllJumps
void ClearAllJumps()
Definition: mythmainwindow.cpp:1442
MythEvent
This class is used as a container for messages.
Definition: mythevent.h:16
MythMainWindowPrivate::m_stackList
QVector< MythScreenStack * > m_stackList
Definition: mythmainwindowprivate.h:72
ACTION_0
static constexpr const char * ACTION_0
Definition: mythuiactions.h:4
MythDate::kScreenShotFilename
@ kScreenShotFilename
"yyyy-MM-ddThh-mm-ss.zzz"
Definition: mythdate.h:29
mythdialogbox.h
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:205
MythScreenStack
Definition: mythscreenstack.h:16
MythMainWindow::RestoreScreensaver
static void RestoreScreensaver()
Definition: mythmainwindow.cpp:574
MythMainWindow::ShowMouseCursor
void ShowMouseCursor(bool Show)
Definition: mythmainwindow.cpp:2099
ACTION_LEFT
static constexpr const char * ACTION_LEFT
Definition: mythuiactions.h:18
MythMainWindow::ReloadKeys
void ReloadKeys()
Definition: mythmainwindow.cpp:946
MythMainWindowPrivate::m_popwindows
bool m_popwindows
Definition: mythmainwindowprivate.h:57
MythNotification
Definition: mythnotification.h:29
MythMainWindow::LoadQtConfig
static void LoadQtConfig()
Definition: mythmainwindow.cpp:631
MythMainWindowPrivate::m_exitingtomain
bool m_exitingtomain
Definition: mythmainwindowprivate.h:56
MSqlQuery::exec
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:617
MythMainWindowPrivate::m_longPressTime
std::chrono::milliseconds m_longPressTime
Definition: mythmainwindowprivate.h:89
MythMainWindowPrivate::m_exitMenuMediaDeviceCallback
void(* m_exitMenuMediaDeviceCallback)(MythMediaDevice *mediadevice)
Definition: mythmainwindowprivate.h:68
MythCoreContext::IsUIThread
bool IsUIThread(void)
Definition: mythcorecontext.cpp:1346
MythScreenSaverControl::Reset
void Reset()
MythMainWindow::HandleTVAction
void HandleTVAction(const QString &Action)
Definition: mythmainwindow.cpp:1514
MythMainWindow::Show
void Show()
Definition: mythmainwindow.cpp:954
MythMainWindowPrivate::m_mediaPluginMap
QMap< QString, MythMediaCallback > m_mediaPluginMap
Definition: mythmainwindowprivate.h:64
MythMainWindow::customEvent
void customEvent(QEvent *Event) override
Definition: mythmainwindow.cpp:1887
MythMainWindow::ResetIdleTimer
void ResetIdleTimer()
Reset the idle timeout timer.
Definition: mythmainwindow.cpp:2129
STANDBY_TIMEOUT
static constexpr std::chrono::minutes STANDBY_TIMEOUT
Definition: mythmainwindow.cpp:63
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
mythinputdevicehandler.h
MythMainWindow::ClearJump
void ClearJump(const QString &Destination)
Definition: mythmainwindow.cpp:1344
MythPainterWindow::CreatePainters
static QString CreatePainters(MythMainWindow *MainWin, MythPainterWindow *&PaintWin, MythPainter *&Paint)
Definition: mythpainterwindow.cpp:53
MythScreenType
Screen in which all other widgets are contained and rendered.
Definition: mythscreentype.h:45
show
static void show(uint8_t *buf, int length)
Definition: ringbuffer.cpp:339
MythMainWindowPrivate::m_actionText
QHash< QString, QHash< QString, QString > > m_actionText
Definition: mythmainwindowprivate.h:65
MythMainWindow::DoRemoteScreenShot
void DoRemoteScreenShot(const QString &Filename, int Width, int Height)
Definition: mythmainwindow.cpp:516
MythMainWindow::RegisterKey
void RegisterKey(const QString &Context, const QString &Action, const QString &Description, const QString &Key)
Definition: mythmainwindow.cpp:1242
GetMythDB
MythDB * GetMythDB(void)
Definition: mythdb.cpp:50
MythMainWindow::RegisterMediaPlugin
void RegisterMediaPlugin(const QString &Name, const QString &Desc, MediaPlayCallback Func)
Definition: mythmainwindow.cpp:1473
MythMainWindow::Draw
void Draw(MythPainter *Painter=nullptr)
Definition: mythmainwindow.cpp:433
mythdirs.h
MythScreenSaverControl::Restore
void Restore()
MythMainWindow::GetRenderDevice
MythRender * GetRenderDevice()
Definition: mythmainwindow.cpp:289
MythMainWindowPrivate::m_hideMouseTimer
QTimer * m_hideMouseTimer
Definition: mythmainwindowprivate.h:76
MythMainWindow::GetPainter
MythPainter * GetPainter()
Definition: mythmainwindow.cpp:255
ACTION_SELECT
static constexpr const char * ACTION_SELECT
Definition: mythuiactions.h:15
ACTION_9
static constexpr const char * ACTION_9
Definition: mythuiactions.h:13
MythMainWindow::PopScreenStack
void PopScreenStack()
Definition: mythmainwindow.cpp:301
mythmainwindowprivate.h
HasMythMainWindow
bool HasMythMainWindow(void)
Definition: mythmainwindow.cpp:107
MythMainWindow::SignalSetDrawEnabled
void SignalSetDrawEnabled(bool Enable)
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:14
MythEvent::Message
const QString & Message() const
Definition: mythevent.h:65
MythMainWindow::HandleMedia
bool HandleMedia(const QString &Handler, const QString &Mrl, const QString &Plot="", const QString &Title="", const QString &Subtitle="", const QString &Director="", int Season=0, int Episode=0, const QString &Inetref="", std::chrono::minutes LenMins=2h, const QString &Year="1895", const QString &Id="", bool UseBookmarks=false)
Definition: mythmainwindow.cpp:1489
MythMediaEvent::kEventType
static Type kEventType
Definition: mythmedia.h:193
MythMainWindowPrivate::TranslateKeyNum
static int TranslateKeyNum(QKeyEvent *Event)
Definition: mythmainwindowprivate.cpp:8
MythEvent::MythUserMessage
static Type MythUserMessage
Definition: mythevent.h:80
MythMainWindow::ClearKey
void ClearKey(const QString &Context, const QString &Action)
Definition: mythmainwindow.cpp:1180
Action
An action (for this plugin) consists of a description, and a set of key sequences.
Definition: action.h:40
MythMainWindow::AddScreenStack
void AddScreenStack(MythScreenStack *Stack, bool Main=false)
Definition: mythmainwindow.cpp:294
MythMainWindow::SetEffectsEnabled
void SetEffectsEnabled(bool Enable)
Definition: mythmainwindow.cpp:1021
MythEvent::kExitToMainMenuEventType
static Type kExitToMainMenuEventType
Definition: mythevent.h:82
mythpainterwindow.h
MythObservable::addListener
void addListener(QObject *listener)
Add a listener to the observable.
Definition: mythobservable.cpp:38
MythMainWindow::DisableIdleTimer
void DisableIdleTimer(bool DisableIdle=true)
Disable the idle timeout timer.
Definition: mythmainwindow.cpp:2118
MythMainWindow::GetDisplay
MythDisplay * GetDisplay()
Definition: mythmainwindow.cpp:250
MythMainWindow::DisableScreensaver
static void DisableScreensaver()
Definition: mythmainwindow.cpp:580
MythMainWindow::SignalRestoreScreensaver
void SignalRestoreScreensaver()
MythMainWindow::GetKey
static QString GetKey(const QString &Context, const QString &Action)
Definition: mythmainwindow.cpp:1311
MythThemeBase
Definition: myththemebase.h:11
ExternalKeycodeEvent
Definition: mythevent.h:105
MythMainWindow::KeyLongPressFilter
bool KeyLongPressFilter(QEvent **Event, QScopedPointer< QEvent > &NewEvent)
Definition: mythmainwindow.cpp:1539
MythGesture::Stop
void Stop(bool Timeout=false)
Stop recording.
Definition: mythgesture.cpp:163
mythdate.h
MythMainWindow::SetDrawEnabled
void SetDrawEnabled(bool Enable)
Definition: mythmainwindow.cpp:997
mythrender_base.h
MythScreenSaverControl::Asleep
bool Asleep()
Definition: mythscreensaver.cpp:80
MythMainWindow::m_screensaver
MythScreenSaverControl * m_screensaver
Definition: mythmainwindow.h:163
MythMainWindowPrivate::m_exitMenuCallback
void(* m_exitMenuCallback)(void)
Definition: mythmainwindowprivate.h:67
mythdisplay.h
mythlogging.h
MythMainWindow::HideMouseTimeout
void HideMouseTimeout()
Definition: mythmainwindow.cpp:2110
ACTION_1
static constexpr const char * ACTION_1
Definition: mythuiactions.h:5
MythMainWindowPrivate
Definition: mythmainwindowprivate.h:47
MythMainWindow::TranslateKeyPress
bool TranslateKeyPress(const QString &Context, QKeyEvent *Event, QStringList &Actions, bool AllowJumps=true)
Get a list of actions for a keypress in the given context.
Definition: mythmainwindow.cpp:1104
s_mainWin
static MythMainWindow * s_mainWin
Definition: mythmainwindow.cpp:68
MythMainWindow::event
bool event(QEvent *Event) override
Definition: mythmainwindow.cpp:610
ACTION_TVPOWERON
static constexpr const char * ACTION_TVPOWERON
Definition: mythuiactions.h:25
MythMainWindow::destroyMainWindow
static void destroyMainWindow()
Definition: mythmainwindow.cpp:94
MythInputDeviceHandler
A wrapper around sundry external input devices.
Definition: mythinputdevicehandler.h:18
MythMainWindowPrivate::m_destinationMap
QMap< QString, JumpData > m_destinationMap
Definition: mythmainwindowprivate.h:63
MythMainWindow::m_themeBase
MythThemeBase * m_themeBase
Definition: mythmainwindow.h:159
Event
Event details.
Definition: zmdefines.h:26
MythMainWindowPrivate::m_drawDisabledDepth
uint m_drawDisabledDepth
Definition: mythmainwindowprivate.h:78
MSqlQuery::InitCon
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:549
compat.h
MythDB::DBError
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:227
MythMainWindow::HidePainterWindow
void HidePainterWindow()
Definition: mythmainwindow.cpp:279
MythMainWindow::ExitToMainMenu
void ExitToMainMenu()
Definition: mythmainwindow.cpp:1037
MythCoreContext::GetDurSetting
std::enable_if_t< std::chrono::__is_duration< T >::value, T > GetDurSetting(const QString &key, T defaultval=T::zero())
Definition: mythcorecontext.h:169
mythscreensaver.h
MythMediaEvent
Definition: mythmedia.h:183
MythMainWindowPrivate::m_keyContexts
QHash< QString, KeyContext * > m_keyContexts
Definition: mythmainwindowprivate.h:61
MythMainWindow::ShowPainterWindow
void ShowPainterWindow()
Definition: mythmainwindow.cpp:270
State
State
Definition: zmserver.h:68
MythMainWindow::DestinationExists
bool DestinationExists(const QString &Destination) const
Definition: mythmainwindow.cpp:1463
DestroyMythMainWindow
void DestroyMythMainWindow(void)
Definition: mythmainwindow.cpp:112
MythNotificationCenter::DisplayedNotifications
int DisplayedNotifications(void) const
Returns number of notifications currently displayed.
Definition: mythnotificationcenter.cpp:1411
MythDisplay::SetWidget
void SetWidget(QWidget *MainWindow)
Set the QWidget and QWindow in use.
Definition: mythdisplay.cpp:248
MythCoreContext::GetDB
MythDB * GetDB(void)
Definition: mythcorecontext.cpp:1757
mythmedia.h
MythUIScreenBounds::m_screenRect
QRect m_screenRect
Definition: mythuiscreenbounds.h:44
MythUIScreenBounds::SetUIScreenRect
void SetUIScreenRect(QRect Rect)
Definition: mythuiscreenbounds.cpp:203
MythMainWindowPrivate::m_drawDisableLock
QMutex m_drawDisableLock
Definition: mythmainwindowprivate.h:77
MythMainWindow::RemoteScreenShot
void RemoteScreenShot(QString Filename, int Width, int Height)
Definition: mythmainwindow.cpp:527
MythScreenSaverControl
Controls all instances of the screensaver.
Definition: mythscreensaver.h:33
MythGesture::Record
bool Record(QPoint Point, Qt::MouseButton Button)
Record a point.
Definition: mythgesture.cpp:331
MythMainWindow::eventFilter
bool eventFilter(QObject *Watched, QEvent *Event) override
Definition: mythmainwindow.cpp:1637
MythMainWindow::Animate
void Animate()
Definition: mythmainwindow.cpp:335
JumpData::m_destination
QString m_destination
Definition: mythmainwindowprivate.h:39
MythGestureEvent::Click
@ Click
Definition: mythgesture.h:77
MythGestureEvent::SetPosition
void SetPosition(QPoint Position)
Definition: mythgesture.h:86
MythMainWindowPrivate::m_escapekey
int m_escapekey
Definition: mythmainwindowprivate.h:71
MythInputDeviceHandler::Reset
void Reset(void)
Definition: mythinputdevicehandler.cpp:157
ACTION_8
static constexpr const char * ACTION_8
Definition: mythuiactions.h:12
MythEvent::kDisableUDPListenerEventType
static Type kDisableUDPListenerEventType
Definition: mythevent.h:89
MythMainWindow::GetPaintWindow
QWidget * GetPaintWindow()
Definition: mythmainwindow.cpp:265
mythpainter.h
MythMainWindow::RegisterJump
void RegisterJump(const QString &Destination, const QString &Description, const QString &Key, void(*Callback)(void), bool Exittomain=true, QString LocalAction="")
Definition: mythmainwindow.cpp:1405
MythMainWindow::IsTopScreenInitialized
static bool IsTopScreenInitialized()
Definition: mythmainwindow.cpp:603
JumpData
Definition: mythmainwindowprivate.h:36
ACTION_TVPOWEROFF
static constexpr const char * ACTION_TVPOWEROFF
Definition: mythuiactions.h:24
MythMainWindow::SignalRemoteScreenShot
void SignalRemoteScreenShot(QString Filename, int Width, int Height)
MSqlQuery::isConnected
bool isConnected(void) const
Only updated once during object creation.
Definition: mythdbcon.h:138
uint
unsigned int uint
Definition: compat.h:81
ACTION_7
static constexpr const char * ACTION_7
Definition: mythuiactions.h:11
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:54
MythPainterWindow::GetRenderDevice
MythRender * GetRenderDevice()
Definition: mythpainterwindow.cpp:160
mythuistatetracker.h
MythMainWindow::GetStackAt
MythScreenStack * GetStackAt(int Position)
Definition: mythmainwindow.cpp:328
MythDisplay
Definition: mythdisplay.h:22
MythMainWindow::EnumerateDestinations
QStringList EnumerateDestinations() const
Definition: mythmainwindow.cpp:1468
MythMainWindow::m_refreshTimer
QTimer m_refreshTimer
Definition: mythmainwindow.h:158
MythCoreContext::GetNumSetting
int GetNumSetting(const QString &key, int defaultval=0)
Definition: mythcorecontext.cpp:910
mythgesture.h
A C++ ripoff of the stroke library for MythTV.
MythMainWindowPrivate::m_enteringStandby
bool m_enteringStandby
Definition: mythmainwindowprivate.h:81
ACTION_HANDLEMEDIA
static constexpr const char * ACTION_HANDLEMEDIA
Definition: mythuiactions.h:21
MythPainter::End
virtual void End()
Definition: mythpainter.h:55
MythMainWindow::PushDrawDisabled
uint PushDrawDisabled()
Definition: mythmainwindow.cpp:976
MythMainWindow::m_priv
MythMainWindowPrivate * m_priv
Definition: mythmainwindow.h:155
ACTION_UP
static constexpr const char * ACTION_UP
Definition: mythuiactions.h:16
MythMainWindow::GetCurrentNotificationCenter
MythNotificationCenter * GetCurrentNotificationCenter()
Definition: mythmainwindow.cpp:260
MythMainWindow::m_idleTime
std::chrono::minutes m_idleTime
Definition: mythmainwindow.h:165
MythPainter::GetName
virtual QString GetName(void)=0
MythUDP::EnableUDPListener
static void EnableUDPListener(bool Enable=true)
Definition: mythudplistener.cpp:173
mythuihelper.h
MythCoreContext::GetMasterServerPort
static int GetMasterServerPort(void)
Returns the Master Backend control port If no master server port has been defined in the database,...
Definition: mythcorecontext.cpp:978
MythUIScreenBounds::InitScreenBounds
void InitScreenBounds()
Definition: mythuiscreenbounds.cpp:130
MythMainWindow::~MythMainWindow
~MythMainWindow() override
Definition: mythmainwindow.cpp:208
ACTION_4
static constexpr const char * ACTION_4
Definition: mythuiactions.h:8
MythMainWindow::paintEngine
QPaintEngine * paintEngine() const override
Definition: mythmainwindow.cpp:469
MythUIScreenBounds::m_wantWindow
bool m_wantWindow
Definition: mythuiscreenbounds.h:47
mythmiscutil.h
MythEvent::kUnlockInputDevicesEventType
static Type kUnlockInputDevicesEventType
Definition: mythevent.h:87
ACTION_3
static constexpr const char * ACTION_3
Definition: mythuiactions.h:7
MythScreenSaverControl::Disable
void Disable()
MythUIScreenBounds::WindowIsAlwaysFullscreen
static bool WindowIsAlwaysFullscreen()
Return true if the current platform only supports fullscreen windows.
Definition: mythuiscreenbounds.cpp:115
ACTION_GETSTATUS
static constexpr const char * ACTION_GETSTATUS
Definition: mythuiactions.h:27
MythMainWindow::GetTarget
QObject * GetTarget(QKeyEvent &Key)
Definition: mythmainwindow.cpp:2074
ACTION_RIGHT
static constexpr const char * ACTION_RIGHT
Definition: mythuiactions.h:19
mythcorecontext.h
MythMainWindow::EnterStandby
void EnterStandby(bool Manual=true)
Definition: mythmainwindow.cpp:2189
MythRender
Definition: mythrender_base.h:23
MythScreenType::inputMethodEvent
bool inputMethodEvent(QInputMethodEvent *event) override
Input Method event handler.
Definition: mythscreentype.cpp:398
MediaPlayCallback
int(*)(const QString &, const QString &, const QString &, const QString &, const QString &, int, int, const QString &, std::chrono::minutes, const QString &, const QString &, bool) MediaPlayCallback
Definition: mythmainwindow.h:19
MythPainter
Definition: mythpainter.h:34
MythDisplay::SwitchToGUI
bool SwitchToGUI(bool Wait=false)
Switches to the GUI resolution.
Definition: mythdisplay.cpp:776
MythMainWindow::InitKeys
void InitKeys()
Definition: mythmainwindow.cpp:785
MythMainWindow::m_display
MythDisplay * m_display
Definition: mythmainwindow.h:156
MythCoreContext::ResetLanguage
void ResetLanguage(void)
Definition: mythcorecontext.cpp:1791
myththemebase.h
MythMainWindow::PopDrawDisabled
uint PopDrawDisabled()
Definition: mythmainwindow.cpp:985
mythudplistener.h
Name
Definition: channelsettings.cpp:71
MythCoreContext::GetSettingOnHost
QString GetSettingOnHost(const QString &key, const QString &host, const QString &defaultval="")
Definition: mythcorecontext.cpp:924
MythMainWindow::IsScreensaverAsleep
static bool IsScreensaverAsleep()
Definition: mythmainwindow.cpp:592
MSqlQuery::bindValue
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:887
MythMainWindow::m_repaintRegion
QRegion m_repaintRegion
Definition: mythmainwindow.h:157
MythMainWindowPrivate::m_allowInput
bool m_allowInput
Definition: mythmainwindowprivate.h:83
ACTION_5
static constexpr const char * ACTION_5
Definition: mythuiactions.h:9
MythMainWindow::m_deviceHandler
MythInputDeviceHandler * m_deviceHandler
Definition: mythmainwindow.h:162
GetNotificationCenter
MythNotificationCenter * GetNotificationCenter(void)
Definition: mythmainwindow.cpp:122
MythGestureEvent::kEventType
static Type kEventType
Definition: mythgesture.h:91
MythUIThemeCache::UpdateImageCache
void UpdateImageCache()
Definition: mythuithemecache.cpp:61
MythEvent::kMythPostShowEventType
static Type kMythPostShowEventType
Definition: mythevent.h:83
GetMythMainWindow
MythMainWindow * GetMythMainWindow(void)
Definition: mythmainwindow.cpp:102
MythUIType::ContainsPoint
bool ContainsPoint(QPoint point) const
Check if the given point falls within this widgets area.
Definition: mythuitype.cpp:1416
build_compdb.action
action
Definition: build_compdb.py:9
MythMainWindow::MouseTimeout
void MouseTimeout()
Definition: mythmainwindow.cpp:1524
MythMainWindowPrivate::m_jumpMap
QMap< int, JumpData * > m_jumpMap
Definition: mythmainwindowprivate.h:62
MythMainWindowPrivate::m_gesture
MythGesture m_gesture
Definition: mythmainwindowprivate.h:74
MythMainWindow::DelayedAction
void DelayedAction()
Definition: mythmainwindow.cpp:775
MythMainWindow::IsExitingToMain
bool IsExitingToMain() const
Definition: mythmainwindow.cpp:1032
MythMainWindowPrivate::m_firstinit
bool m_firstinit
Definition: mythmainwindowprivate.h:86
MythScreenType::gestureEvent
bool gestureEvent(MythGestureEvent *event) override
Mouse click/movement handler, receives mouse gesture events from the QCoreApplication event loop.
Definition: mythscreentype.cpp:446
MythPainter::SetClipRect
virtual void SetClipRect(QRect clipRect)
Definition: mythpainter.cpp:46
MythMainWindow::GetStack
MythScreenStack * GetStack(const QString &Stackname)
Definition: mythmainwindow.cpp:320
ExternalKeycodeEvent::kEventType
static Type kEventType
Definition: mythevent.h:113
MythThemeBase::Reload
void Reload()
Definition: myththemebase.cpp:37
MythGesture::GetGesture
MythGestureEvent * GetGesture() const
Complete the gesture event of the last completed stroke.
Definition: mythgesture.cpp:190
KeyContext
Definition: mythmainwindowprivate.h:12
MythMainWindow::ClearKeyContext
void ClearKeyContext(const QString &Context)
Definition: mythmainwindow.cpp:1197
MythMainWindow::SignalResetScreensaver
void SignalResetScreensaver()
mythuiactions.h
MythMediaDevice
Definition: mythmedia.h:48
MythNotificationCenter::GetInstance
static MythNotificationCenter * GetInstance(void)
returns the MythNotificationCenter singleton
Definition: mythnotificationcenter.cpp:1318
MythPainterWindow::RenderIsShared
bool RenderIsShared()
Definition: mythpainterwindow.cpp:165
MythGestureEvent
A custom event that represents a mouse gesture.
Definition: mythgesture.h:39
MythMainWindow::m_painterWin
MythPainterWindow * m_painterWin
Definition: mythmainwindow.h:161
MythMainWindow::MoveResize
void MoveResize(QRect &Geometry)
Definition: mythmainwindow.cpp:965
MythDisplay::UsingVideoModes
virtual bool UsingVideoModes()
Definition: mythdisplay.h:30
MythCoreContext::BlockShutdown
void BlockShutdown(void)
Definition: mythcorecontext.cpp:594
ACTION_2
static constexpr const char * ACTION_2
Definition: mythuiactions.h:6
MythNotificationCenter
Definition: mythnotificationcenter.h:40
GetMythPainter
MythPainter * GetMythPainter(void)
Definition: mythmainwindow.cpp:117
s_mainLock
static QMutex s_mainLock
Definition: mythmainwindow.cpp:69
MythMainWindow::GrabWindow
static void GrabWindow(QImage &Image)
Definition: mythmainwindow.cpp:487
MythMainWindow::ResetScreensaver
static void ResetScreensaver()
Definition: mythmainwindow.cpp:586
MythMainWindow::AllowInput
void AllowInput(bool Allow)
Definition: mythmainwindow.cpp:1519
MythUIThemeCache::ClearThemeCacheDir
void ClearThemeCacheDir()
Definition: mythuithemecache.cpp:56
mythburn.usebookmark
bool usebookmark
Definition: mythburn.py:179
MythMainWindow::IdleTimeout
void IdleTimeout()
Definition: mythmainwindow.cpp:2169
MythInputDeviceHandler::Event
void Event(QEvent *Event) const
Definition: mythinputdevicehandler.cpp:164
GetMythUI
MythUIHelper * GetMythUI()
Definition: mythuihelper.cpp:66
MythMainWindow::ScreenShot
static bool ScreenShot(int Width=0, int Height=0, QString Filename="")
Definition: mythmainwindow.cpp:562
build_compdb.filename
filename
Definition: build_compdb.py:21
MythMainWindow::RestartInputHandlers
void RestartInputHandlers()
Definition: mythmainwindow.cpp:2094
MythMainWindowPrivate::m_mainStack
MythScreenStack * m_mainStack
Definition: mythmainwindowprivate.h:73
mythmainwindow.h
MythMainWindowPrivate::m_standby
bool m_standby
Definition: mythmainwindowprivate.h:80
MythMainWindow::m_painter
MythPainter * m_painter
Definition: mythmainwindow.h:160
MythScreenType::IsInitialized
bool IsInitialized(void) const
Has Init() been called on this screen?
Definition: mythscreentype.cpp:360
MythCoreContext::dispatch
void dispatch(const MythEvent &event)
Definition: mythcorecontext.cpp:1723
MythMainWindow::GetActionText
QString GetActionText(const QString &Context, const QString &Action) const
Definition: mythmainwindow.cpp:1332
ShowOkPopup
MythConfirmationDialog * ShowOkPopup(const QString &message, bool showCancel)
Non-blocking version of MythPopupBox::showOkPopup()
Definition: mythdialogbox.cpp:562
MythPainter::Begin
virtual void Begin(QPaintDevice *)
Definition: mythpainter.h:54
MythMainWindow::BindKey
void BindKey(const QString &Context, const QString &Action, const QString &Key)
Definition: mythmainwindow.cpp:1204
MythMainWindow::ExitStandby
void ExitStandby(bool Manual=true)
Definition: mythmainwindow.cpp:2224
MythObservable::removeListener
void removeListener(QObject *listener)
Remove a listener to the observable.
Definition: mythobservable.cpp:55
MythDisplay::Create
static MythDisplay * Create(MythMainWindow *MainWindow)
Create a MythDisplay object appropriate for the current platform.
Definition: mythdisplay.cpp:83
ACTION_6
static constexpr const char * ACTION_6
Definition: mythuiactions.h:10
MythMainWindowPrivate::m_nc
MythNotificationCenter * m_nc
Definition: mythmainwindowprivate.h:79
MythMainWindow
Definition: mythmainwindow.h:28
MythMainWindow::drawScreen
void drawScreen(QPaintEvent *Event=nullptr)
Definition: mythmainwindow.cpp:373
MythCoreContext::SetGUIObject
void SetGUIObject(QObject *gui)
Definition: mythcorecontext.cpp:1737
mythscreentype.h
MythUIScreenBounds::GeometryIsOverridden
static bool GeometryIsOverridden()
Definition: mythuiscreenbounds.cpp:20
MythUIScreenBounds::m_uiScreenRect
QRect m_uiScreenRect
Definition: mythuiscreenbounds.h:43
MythNotificationCenterEvent::kEventType
static Type kEventType
Definition: mythnotificationcenter.h:30
MythMainWindow::PauseIdleTimer
void PauseIdleTimer(bool Pause)
Pause the idle timeout timer.
Definition: mythmainwindow.cpp:2146
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:896
MythUDP::StopUDPListener
static void StopUDPListener()
Definition: mythudplistener.cpp:213
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:836
MythInputDeviceHandler::IgnoreKeys
void IgnoreKeys(bool Ignore)
Definition: mythinputdevicehandler.cpp:189
MythScreenStack::GetTopScreen
virtual MythScreenType * GetTopScreen(void) const
Definition: mythscreenstack.cpp:182
MythEvent::kEnableUDPListenerEventType
static Type kEnableUDPListenerEventType
Definition: mythevent.h:90
MythNotificationCenter::Queue
bool Queue(const MythNotification &notification)
Queue a notification Queue() is thread-safe and can be called from anywhere.
Definition: mythnotificationcenter.cpp:1349