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