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