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