14#include <QWaitCondition>
15#include <QApplication>
21#include <QKeySequence>
22#include <QInputMethodEvent>
58#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
68#define LOC QString("MythMainWindow: ")
143 setObjectName(
"mainwindow");
160 installEventFilter(
this);
176 setUpdatesEnabled(
true);
179 Qt::BlockingQueuedConnection);
181 Qt::BlockingQueuedConnection);
325 if (widget->objectName() == Stackname)
332 if (Position >= 0 && Position < m_priv->m_stackList.size())
351 QVector<MythScreenType *> drawList;
352 (*it)->GetDrawOrder(drawList);
354 for (
auto *screen : std::as_const(drawList))
358 if (screen->NeedsRedraw())
360 QRegion topDirty = screen->GetDirtyArea();
361 screen->ResetNeedsRedraw();
372 widget->ScheduleInitIfNeeded();
399 QVector<MythScreenType *> redrawList;
400 (*it)->GetDrawOrder(redrawList);
402 for (
const auto *screen : std::as_const(redrawList))
404 if (screen->NeedsRedraw())
406 for (
const QRect& wrect: screen->GetDirtyArea())
408 bool foundThisRect =
false;
414 if (drect.contains(wrect))
416 foundThisRect =
true;
449 if (rect.width() == 0 || rect.height() == 0)
459 QVector<MythScreenType *> redrawList;
460 (*it)->GetDrawOrder(redrawList);
461 for (
auto *screen : std::as_const(redrawList))
462 screen->Draw(Painter, 0, 0, 255, rect);
473 return testAttribute(Qt::WA_PaintOnScreen) ? nullptr : QWidget::paintEngine();
478 if (
Event->spontaneous())
480 auto * key =
new QKeyEvent(QEvent::KeyPress,
m_priv->
m_escapekey, Qt::NoModifier);
481 QCoreApplication::postEvent(
this, key);
486 QWidget::closeEvent(
Event);
492 auto * active = QApplication::activeWindow();
495 winid = active->winId();
507 if (
auto * screen = display->GetCurrentScreen(); screen)
509 QPixmap image = screen->grabWindow(winid);
510 Image = image.toImage();
522 args << QString::number(Width);
523 args << QString::number(Height);
526 QCoreApplication::sendEvent(
this, &me);
538 if (Filename.isEmpty())
540 QString fpath =
GetMythDB()->GetSetting(
"ScreenShotPath",
"/tmp");
541 Filename = QString(
"%1/myth-screenshot-%2.png")
545 QString extension = Filename.section(
'.', -1, -1);
546 if (extension ==
"jpg")
551 LOG(VB_GENERAL, LOG_INFO, QString(
"Saving screenshot to %1 (%2x%3)")
552 .arg(Filename).arg(Image.width()).arg(Image.height()));
554 if (Image.save(Filename, extension.toLatin1(), 100))
556 LOG(VB_GENERAL, LOG_INFO,
"MythMainWindow::screenShot succeeded");
560 LOG(VB_GENERAL, LOG_INFO,
"MythMainWindow::screenShot Failed!");
571 Height = img.height();
572 img = img.scaled(Width, Height, Qt::KeepAspectRatio, Qt::SmoothTransformation);
614 if (!updatesEnabled() && (
Event->type() == QEvent::UpdateRequest))
617 if (
Event->type() == QEvent::Show && !
Event->spontaneous())
627 if ((
Event->type() == QEvent::WindowActivate) || (
Event->type() == QEvent::WindowDeactivate))
630 return QWidget::event(
Event);
638 QApplication::setStyle(
"Windows");
651 Qt::WindowFlags flags = Qt::Window;
659 setWindowFlags(windowFlags() & ~Qt::FramelessWindowHint);
663 LOG(VB_GENERAL, LOG_INFO,
"Using Frameless Window");
664 flags |= Qt::FramelessWindowHint;
669 flags |= Qt::MSWindowsOwnDC;
677 if (fullscreen && !inwindow)
679 LOG(VB_GENERAL, LOG_INFO,
"Using Full Screen Window");
684 setWindowState(Qt::WindowFullScreen);
690 setWindowState(Qt::WindowNoState);
694 flags |= Qt::WindowStaysOnTopHint;
696 setWindowFlags(flags);
712 if (!
GetMythDB()->GetBoolSetting(
"HideMouseCursor",
false))
713 setMouseTracking(
true);
721 LOG(VB_GENERAL, LOG_INFO,
"Destroying painter and painter window");
726 if (!warningmsg.isEmpty())
728 LOG(VB_GENERAL, LOG_WARNING, warningmsg);
733 LOG(VB_GENERAL, LOG_ERR,
"MythMainWindow failed to create a painter window.");
739 setAttribute(Qt::WA_NoSystemBackground);
740 setAutoFillBackground(
false);
742 setAttribute(Qt::WA_InputMethodEnabled);
750 static const QLatin1String EARLY_SHOW_PLATFORM_NAME_CHECK {
"android" };
752 static const QLatin1String EARLY_SHOW_PLATFORM_NAME_CHECK {
"egl" };
754 if (QGuiApplication::platformName().contains(EARLY_SHOW_PLATFORM_NAME_CHECK))
755 QCoreApplication::processEvents();
757 if (!
GetMythDB()->GetBoolSetting(
"HideMouseCursor",
false))
771 if (!warningmsg.isEmpty())
784#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
785 QtAndroid::hideSplashScreen();
787 QNativeInterface::QAndroidApplication::hideSplashScreen();
797 "Down Arrow"),
"Down");
799 "Left Arrow"),
"Left");
801 "Right Arrow"),
"Right");
802 RegisterKey(
"Global",
"NEXT", QT_TRANSLATE_NOOP(
"MythControls",
803 "Move to next widget"),
"Tab");
804 RegisterKey(
"Global",
"PREVIOUS", QT_TRANSLATE_NOOP(
"MythControls",
805 "Move to preview widget"),
"Backtab");
807 "Select"),
"Return,Enter,Space");
808 RegisterKey(
"Global",
"BACKSPACE", QT_TRANSLATE_NOOP(
"MythControls",
809 "Backspace"),
"Backspace");
810 RegisterKey(
"Global",
"ESCAPE", QT_TRANSLATE_NOOP(
"MythControls",
811 "Escape"),
"Esc,Back");
812 RegisterKey(
"Global",
"MENU", QT_TRANSLATE_NOOP(
"MythControls",
813 "Pop-up menu"),
"M,Meta+Enter,Ctrl+M,Menu");
814 RegisterKey(
"Global",
"INFO", QT_TRANSLATE_NOOP(
"MythControls",
815 "More information"),
"I,Ctrl+I,Home Page");
816 RegisterKey(
"Global",
"DELETE", QT_TRANSLATE_NOOP(
"MythControls",
817 "Delete"),
"D,Ctrl+E");
818 RegisterKey(
"Global",
"EDIT", QT_TRANSLATE_NOOP(
"MythControls",
821 "Save screenshot"),
"");
823 "Play a media resource"),
"");
825 RegisterKey(
"Global",
"PAGEUP", QT_TRANSLATE_NOOP(
"MythControls",
827 RegisterKey(
"Global",
"PAGEDOWN", QT_TRANSLATE_NOOP(
"MythControls",
828 "Page Down"),
"PgDown");
829 RegisterKey(
"Global",
"PAGETOP", QT_TRANSLATE_NOOP(
"MythControls",
830 "Page to top of list"),
"");
831 RegisterKey(
"Global",
"PAGEMIDDLE", QT_TRANSLATE_NOOP(
"MythControls",
832 "Page to middle of list"),
"");
833 RegisterKey(
"Global",
"PAGEBOTTOM", QT_TRANSLATE_NOOP(
"MythControls",
834 "Page to bottom of list"),
"");
836 RegisterKey(
"Global",
"PREVVIEW", QT_TRANSLATE_NOOP(
"MythControls",
837 "Previous View"),
"Home,Media Previous");
838 RegisterKey(
"Global",
"NEXTVIEW", QT_TRANSLATE_NOOP(
"MythControls",
839 "Next View"),
"End,Media Next");
841 RegisterKey(
"Global",
"HELP", QT_TRANSLATE_NOOP(
"MythControls",
843 RegisterKey(
"Global",
"EJECT", QT_TRANSLATE_NOOP(
"MythControls"
844 ,
"Eject Removable Media"),
"");
846 RegisterKey(
"Global",
"CUT", QT_TRANSLATE_NOOP(
"MythControls",
847 "Cut text from textedit"),
"Ctrl+X");
848 RegisterKey(
"Global",
"COPY", QT_TRANSLATE_NOOP(
"MythControls"
849 ,
"Copy text from textedit"),
"Ctrl+C");
850 RegisterKey(
"Global",
"PASTE", QT_TRANSLATE_NOOP(
"MythControls",
851 "Paste text into textedit"),
"Ctrl+V");
852 RegisterKey(
"Global",
"NEWLINE", QT_TRANSLATE_NOOP(
"MythControls",
853 "Insert newline into textedit"),
"Ctrl+Return");
854 RegisterKey(
"Global",
"UNDO", QT_TRANSLATE_NOOP(
"MythControls",
856 RegisterKey(
"Global",
"REDO", QT_TRANSLATE_NOOP(
"MythControls",
858 RegisterKey(
"Global",
"SEARCH", QT_TRANSLATE_NOOP(
"MythControls",
859 "Show incremental search dialog"),
"Ctrl+S,Search");
873 "Turn the display on"),
"");
875 "Turn the display off"),
"");
877 RegisterKey(
"Global",
"SYSEVENT01", QT_TRANSLATE_NOOP(
"MythControls",
878 "Trigger System Key Event #1"),
"");
879 RegisterKey(
"Global",
"SYSEVENT02", QT_TRANSLATE_NOOP(
"MythControls",
880 "Trigger System Key Event #2"),
"");
881 RegisterKey(
"Global",
"SYSEVENT03", QT_TRANSLATE_NOOP(
"MythControls",
882 "Trigger System Key Event #3"),
"");
883 RegisterKey(
"Global",
"SYSEVENT04", QT_TRANSLATE_NOOP(
"MythControls",
884 "Trigger System Key Event #4"),
"");
885 RegisterKey(
"Global",
"SYSEVENT05", QT_TRANSLATE_NOOP(
"MythControls",
886 "Trigger System Key Event #5"),
"");
887 RegisterKey(
"Global",
"SYSEVENT06", QT_TRANSLATE_NOOP(
"MythControls",
888 "Trigger System Key Event #6"),
"");
889 RegisterKey(
"Global",
"SYSEVENT07", QT_TRANSLATE_NOOP(
"MythControls",
890 "Trigger System Key Event #7"),
"");
891 RegisterKey(
"Global",
"SYSEVENT08", QT_TRANSLATE_NOOP(
"MythControls",
892 "Trigger System Key Event #8"),
"");
893 RegisterKey(
"Global",
"SYSEVENT09", QT_TRANSLATE_NOOP(
"MythControls",
894 "Trigger System Key Event #9"),
"");
895 RegisterKey(
"Global",
"SYSEVENT10", QT_TRANSLATE_NOOP(
"MythControls",
896 "Trigger System Key Event #10"),
"");
899 RegisterKey(
"Browser",
"ZOOMIN", QT_TRANSLATE_NOOP(
"MythControls",
900 "Zoom in on browser window"),
".,>,Ctrl+F,Media Fast Forward");
901 RegisterKey(
"Browser",
"ZOOMOUT", QT_TRANSLATE_NOOP(
"MythControls",
902 "Zoom out on browser window"),
",,<,Ctrl+B,Media Rewind");
903 RegisterKey(
"Browser",
"TOGGLEINPUT", QT_TRANSLATE_NOOP(
"MythControls",
904 "Toggle where keyboard input goes to"),
"F1");
905 RegisterKey(
"Browser",
"RELOAD" , QT_TRANSLATE_NOOP(
"MythControls",
906 "Reload the current webpage"),
"F2");
907 RegisterKey(
"Browser",
"FULLRELOAD", QT_TRANSLATE_NOOP(
"MythControls",
908 "Reload the current webpage bypassing the cache"),
"F3");
910 RegisterKey(
"Browser",
"MOUSEUP", QT_TRANSLATE_NOOP(
"MythControls",
911 "Move mouse pointer up"),
"2");
912 RegisterKey(
"Browser",
"MOUSEDOWN", QT_TRANSLATE_NOOP(
"MythControls",
913 "Move mouse pointer down"),
"8");
914 RegisterKey(
"Browser",
"MOUSELEFT", QT_TRANSLATE_NOOP(
"MythControls",
915 "Move mouse pointer left"),
"4");
916 RegisterKey(
"Browser",
"MOUSERIGHT", QT_TRANSLATE_NOOP(
"MythControls",
917 "Move mouse pointer right"),
"6");
918 RegisterKey(
"Browser",
"MOUSELEFTBUTTON", QT_TRANSLATE_NOOP(
"MythControls",
919 "Mouse Left button click"),
"5");
921 RegisterKey(
"Browser",
"PAGEDOWN", QT_TRANSLATE_NOOP(
"MythControls",
922 "Scroll down half a page"),
"9");
923 RegisterKey(
"Browser",
"PAGEUP", QT_TRANSLATE_NOOP(
"MythControls",
924 "Scroll up half a page"),
"3");
925 RegisterKey(
"Browser",
"PAGELEFT", QT_TRANSLATE_NOOP(
"MythControls",
926 "Scroll left half a page"),
"7");
927 RegisterKey(
"Browser",
"PAGERIGHT", QT_TRANSLATE_NOOP(
"MythControls",
928 "Scroll right half a page"),
"1");
930 RegisterKey(
"Browser",
"NEXTLINK", QT_TRANSLATE_NOOP(
"MythControls",
931 "Move selection to next link"),
"Z");
932 RegisterKey(
"Browser",
"PREVIOUSLINK", QT_TRANSLATE_NOOP(
"MythControls",
933 "Move selection to previous link"),
"Q");
934 RegisterKey(
"Browser",
"FOLLOWLINK", QT_TRANSLATE_NOOP(
"MythControls",
935 "Follow selected link"),
"Return,Space,Enter");
936 RegisterKey(
"Browser",
"HISTORYBACK", QT_TRANSLATE_NOOP(
"MythControls",
937 "Go back to previous page"),
"R,Backspace");
938 RegisterKey(
"Browser",
"HISTORYFORWARD", QT_TRANSLATE_NOOP(
"MythControls",
939 "Go forward to previous page"),
"F");
941 RegisterKey(
"Main Menu",
"EXITPROMPT", QT_TRANSLATE_NOOP(
"MythControls",
942 "Display System Exit Prompt"),
"Esc,Back");
943 RegisterKey(
"Main Menu",
"EXIT", QT_TRANSLATE_NOOP(
"MythControls",
945 RegisterKey(
"Main Menu",
"STANDBYMODE",QT_TRANSLATE_NOOP(
"MythControls",
946 "Enter Standby Mode"),
"");
947 RegisterKey(
"Long Press",
"LONGPRESS1",QT_TRANSLATE_NOOP(
"MythControls",
948 "Up to 16 Keys that allow Long Press"),
"");
949 RegisterKey(
"Long Press",
"LONGPRESS2",QT_TRANSLATE_NOOP(
"MythControls",
950 "Up to 16 Keys that allow Long Press"),
"");
951 RegisterKey(
"Long Press",
"LONGPRESS3",QT_TRANSLATE_NOOP(
"MythControls",
952 "Up to 16 Keys that allow Long Press"),
"");
953 RegisterKey(
"Long Press",
"LONGPRESS4",QT_TRANSLATE_NOOP(
"MythControls",
954 "Up to 16 Keys that allow Long Press"),
"");
978 setFixedSize(Geometry.size());
979 setGeometry(Geometry);
983 m_painterWin->setGeometry(0, 0, Geometry.width(), Geometry.height());
1016 setUpdatesEnabled(Enable);
1021 QApplication::postEvent(
this,
new QEvent(QEvent::UpdateRequest), Qt::LowEventPriority);
1037 widget->EnableEffects();
1039 widget->DisableEffects();
1058 if (screen && screen->objectName() != QString(
"mainmenu"))
1062 if (screen->objectName() == QString(
"video playback window"))
1064 auto *me =
new MythEvent(
"EXIT_TO_MENU");
1065 QCoreApplication::postEvent(screen, me);
1071 QCoreApplication::postEvent(
this, key);
1077 QCoreApplication::postEvent(
1100 callback(mediadevice);
1116 QStringList& Actions,
bool AllowJumps)
1123 !
Event->text().isEmpty() &&
1124 Event->modifiers() == Qt::NoModifier)
1150 QStringList localActions;
1154 keycontext && (keycontext->GetMapping(keynum, localActions)))
1173 QCoreApplication::postEvent(
1179 keycontext->GetMapping(keynum, Actions);
1181 if (Context !=
"Global")
1185 keycontextG->GetMapping(keynum, Actions);
1194 if (keycontext ==
nullptr)
1197 QMutableMapIterator<int, QStringList> it(keycontext->m_actionMap);
1198 while (it.hasNext())
1201 QStringList list = it.value();
1211 if (keycontext !=
nullptr)
1212 keycontext->m_actionMap.clear();
1218 if (keycontext ==
nullptr)
1221 if (keycontext ==
nullptr)
1226 QKeySequence keyseq(Key);
1227 for (
unsigned int i = 0; i < static_cast<uint>(keyseq.count()); i++)
1229#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
1230 int keynum = keyseq[i];
1232 int keynum = keyseq[i].toCombined();
1235 QStringList dummyaction(
"");
1236 if (keycontext->GetMapping(keynum, dummyaction))
1238 LOG(VB_GENERAL, LOG_WARNING, QString(
"Key %1 is bound to multiple actions in context %2.")
1239 .arg(Key, Context));
1242 keycontext->AddMapping(keynum,
Action);
1244 LOG(VB_GENERAL, LOG_DEBUG, QString(
"Binding: %1 to action: %2 (%3)")
1245 .arg(Key).arg(
Action).arg(Context));
1248 if (
Action ==
"ESCAPE" && Context ==
"Global" && i == 0)
1254 const QString& Description,
const QString& Key)
1256 QString keybind = Key;
1262 query.
prepare(
"SELECT keylist, description FROM keybindings WHERE "
1263 "context = :CONTEXT AND action = :ACTION AND "
1264 "hostname = :HOSTNAME ;");
1271 keybind = query.
value(0).toString();
1272 QString db_description = query.
value(1).toString();
1275 if (db_description != Description)
1277 LOG(VB_GENERAL, LOG_NOTICE,
1278 "Updating keybinding description...");
1280 "UPDATE keybindings "
1281 "SET description = :DESCRIPTION "
1282 "WHERE context = :CONTEXT AND "
1283 " action = :ACTION AND "
1284 " hostname = :HOSTNAME");
1286 query.
bindValue(
":DESCRIPTION", Description);
1299 const QString& inskey = keybind;
1301 query.
prepare(
"INSERT INTO keybindings (context, action, "
1302 "description, keylist, hostname) VALUES "
1303 "( :CONTEXT, :ACTION, :DESCRIPTION, :KEYLIST, "
1307 query.
bindValue(
":DESCRIPTION", Description);
1328 query.
prepare(
"SELECT keylist "
1330 "WHERE context = :CONTEXT AND "
1331 " action = :ACTION AND "
1332 " hostname = :HOSTNAME");
1340 return query.
value(0).toString();
1344 const QString&
Action)
const
1349 if (entry.contains(
Action))
1350 return entry.value(
Action);
1360 LOG(VB_GENERAL, LOG_ERR,
"Cannot clear ficticious jump point" + Destination);
1365 while (it.hasNext())
1380 LOG(VB_GENERAL, LOG_ERR,
"Cannot bind to ficticious jump point" + Destination);
1384 QKeySequence keyseq(Key);
1386 for (
unsigned int i = 0; i < static_cast<uint>(keyseq.count()); i++)
1388#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
1389 int keynum = keyseq[i];
1391 int keynum = keyseq[i].toCombined();
1397 LOG(VB_GENERAL, LOG_DEBUG, QString(
"Binding: %1 to JumpPoint: %2")
1398 .arg(keybind).arg(destination));
1405 LOG(VB_GENERAL, LOG_WARNING, QString(
"Key %1 is already bound to a jump point.")
1411 LOG(VB_GENERAL, LOG_DEBUG,
1412 QString(
"JumpPoint: %2 exists, no keybinding") .arg(destination));
1417 const QString& Key,
void (*Callback)(
void),
1418 bool Exittomain, QString LocalAction)
1420 QString keybind = Key;
1425 query.
prepare(
"SELECT keylist FROM jumppoints WHERE destination = :DEST and hostname = :HOST ;");
1430 keybind = query.
value(0).toString();
1434 const QString& inskey = keybind;
1436 query.
prepare(
"INSERT INTO jumppoints (destination, description, "
1437 "keylist, hostname) VALUES ( :DEST, :DESC, :KEYLIST, "
1448 JumpData jd = { Callback, Destination, Description, Exittomain, std::move(LocalAction) };
1456 QList<QString>::Iterator it;
1457 for (it = destinations.begin(); it != destinations.end(); ++it)
1468 QCoreApplication::postEvent(
1489 LOG(VB_GENERAL, LOG_NOTICE, QString(
"Registering %1 as a media playback plugin.")
1495 LOG(VB_GENERAL, LOG_NOTICE, QString(
"%1 is already registered as a media playback plugin.")
1501 const QString& Plot,
const QString& Title,
1502 const QString& Subtitle,
1503 const QString& Director,
int Season,
1504 int Episode,
const QString& Inetref,
1505 std::chrono::minutes LenMins,
const QString& Year,
1506 const QString& Id,
bool UseBookmarks)
1508 QString lhandler(Handler);
1509 if (lhandler.isEmpty())
1510 lhandler =
"Internal";
1516 Director, Season, Episode,
1517 Inetref, LenMins, Year, Id,
1544 QCoreApplication::postEvent(
this,
event);
1552 auto * keyevent =
dynamic_cast<QKeyEvent*
>(*Event);
1555 int keycode = keyevent->key();
1560 QEvent *newevent =
nullptr;
1561 switch ((*Event)->type())
1563 case QEvent::KeyPress:
1576 newevent =
new QKeyEvent(QEvent::KeyPress, keycode,
1577 keyevent->modifiers() | Qt::MetaModifier, keyevent->nativeScanCode(),
1578 keyevent->nativeVirtualKey(), keyevent->nativeModifiers(),
1579 keyevent->text(),
false,1);
1581 NewEvent.reset(newevent);
1592 QStringList actions;
1599 LOG(VB_GUI, LOG_ERR, QString(
"TranslateKeyPress Long Press Invalid Response"));
1602 if (!actions.empty() && actions[0].startsWith(
"LONGPRESS"))
1611 case QEvent::KeyRelease:
1615 if (keyevent->isAutoRepeat())
1620 Qt::KeyboardModifiers modifier = Qt::NoModifier;
1624 modifier = Qt::MetaModifier;
1626 newevent =
new QKeyEvent(QEvent::KeyPress, keycode,
1627 keyevent->modifiers() | modifier, keyevent->nativeScanCode(),
1628 keyevent->nativeVirtualKey(), keyevent->nativeModifiers(),
1629 keyevent->text(),
false,1);
1631 NewEvent.reset(newevent);
1654 QScopedPointer<QEvent> newevent(
nullptr);
1658 switch (
Event->type())
1660 case QEvent::KeyPress:
1663 auto *
event =
dynamic_cast<QKeyEvent*
>(
Event);
1668 event =
static_cast<QKeyEvent*
>(
Event);
1675 switch (
event->nativeScanCode())
1678 keycode = Qt::Key_MediaPause;
1686 auto * key =
new QKeyEvent(QEvent::KeyPress, keycode,
event->modifiers());
1687 if (
auto * target =
GetTarget(*key); target)
1688 QCoreApplication::postEvent(target, key);
1690 QCoreApplication::postEvent(
this, key);
1696 QVector<MythScreenStack *>::const_reverse_iterator it;
1699 if (
auto * top = (*it)->GetTopScreen(); top)
1701 if (top->keyPressEvent(
event))
1705 if ((*it)->objectName() ==
"popup stack")
1711 case QEvent::InputMethod:
1714 auto *ie =
dynamic_cast<QInputMethodEvent*
>(
Event);
1716 return MythUIScreenBounds::eventFilter(Watched,
Event);
1717 QWidget *widget = QApplication::focusWidget();
1721 if (widget->isEnabled())
1722 QCoreApplication::instance()->notify(widget, ie);
1725 QVector<MythScreenStack *>::const_reverse_iterator it;
1735 if ((*it)->objectName() ==
"popup stack")
1740 case QEvent::MouseButtonPress:
1747 auto * mouseEvent =
dynamic_cast<QMouseEvent*
>(
Event);
1749 return MythUIScreenBounds::eventFilter(Watched,
Event);
1757 case QEvent::MouseButtonRelease:
1768 QPoint point { -1, -1 };
1769 auto * mouseevent =
dynamic_cast<QMouseEvent*
>(
Event);
1772 point = mouseevent->pos();
1780 return MythUIScreenBounds::eventFilter(Watched,
Event);
1782 QVector<MythScreenStack *>::const_reverse_iterator it;
1785 auto * screen = (*it)->GetTopScreen();
1786 if (!screen || !screen->ContainsPoint(point))
1789 if (screen->gestureEvent(gesture))
1798 if ((*it)->objectName() ==
"popup stack")
1805 bool handled =
false;
1809 QCoreApplication::postEvent(
this, gesture);
1813 QVector<MythScreenStack *>::const_reverse_iterator it;
1832 if ((*it)->objectName() ==
"popup stack")
1839 QCoreApplication::postEvent(
this, gesture);
1846 case QEvent::MouseMove:
1855 auto * mouseevent =
dynamic_cast<QMouseEvent*
>(
Event);
1857 return MythUIScreenBounds::eventFilter(Watched,
Event);
1867 auto * wheel =
dynamic_cast<QWheelEvent*
>(
Event);
1868 if (wheel ==
nullptr)
1869 return MythUIScreenBounds::eventFilter(Watched,
Event);
1870 int delta = wheel->angleDelta().y();
1874 auto *key =
new QKeyEvent(QEvent::KeyPress, Qt::Key_Up, Qt::NoModifier);
1875 if (
auto * target =
GetTarget(*key); target)
1876 QCoreApplication::postEvent(target, key);
1878 QCoreApplication::postEvent(
this, key);
1883 auto * key =
new QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier);
1884 if (
auto * target =
GetTarget(*key); !target)
1885 QCoreApplication::postEvent(target, key);
1887 QCoreApplication::postEvent(
this, key);
1895 return MythUIScreenBounds::eventFilter(Watched,
Event);
1903 if (gesture ==
nullptr)
1906 if (
auto * screen = toplevel->GetTopScreen(); screen)
1907 screen->gestureEvent(gesture);
1908 LOG(VB_GUI, LOG_DEBUG, QString(
"Gesture: %1 (Button: %2)")
1909 .arg(gesture->GetName(), gesture->GetButtonName()));
1918 if (
event ==
nullptr)
1920 auto * key =
new QKeyEvent(QEvent::KeyPress,
event->getKeycode(), Qt::NoModifier);
1921 if (
auto * target =
GetTarget(*key); target)
1922 QCoreApplication::sendEvent(target, key);
1924 QCoreApplication::sendEvent(
this, key);
1947 QVector<MythScreenType*> screenList;
1948 widget->GetScreenList(screenList);
1949 for (
auto * screen : std::as_const(screenList))
1951 screen->mediaEvent(me);
1957 LOG(VB_GENERAL, LOG_DEBUG, QString(
"Media Event: %1 - %2")
1958 .arg(device->getDevicePath()).arg(device->getStatus()));
1990 if (
event ==
nullptr)
1993 QString message =
event->
Message();
1996 if (
event->ExtraDataCount() == 1)
1998 else if (
event->ExtraDataCount() >= 11)
2001 if (
event->ExtraDataCount() >= 12)
2006 event->ExtraData(5).toInt(),
event->ExtraData(6).toInt(),
2007 event->ExtraData(7), std::chrono::minutes(
event->ExtraData(8).toInt()),
2013 LOG(VB_GENERAL, LOG_ERR,
"Failed to handle media");
2021 if (
event->ExtraDataCount() >= 2)
2023 width =
event->ExtraData(0).toInt();
2024 height =
event->ExtraData(1).toInt();
2025 if (
event->ExtraDataCount() == 3)
2033 state.insert(
"state",
"idle");
2034 state.insert(
"menutheme",
GetMythDB()->GetSetting(
"menutheme",
"defaultmenu"));
2035 state.insert(
"currentlocation",
GetMythUI()->GetCurrentLocation());
2038 else if (message ==
"CLEAR_SETTINGS_CACHE")
2052 LOG(VB_GENERAL, LOG_INFO, QString(
"Updating the frontend idle time to: %1 mins").arg(
m_idleTime.count()));
2056 LOG(VB_GENERAL, LOG_INFO,
"Frontend idle timeout is disabled");
2059 else if (message ==
"NOTIFICATION")
2076 if (
const QString& message =
event->Message(); !message.isEmpty())
2087 auto * target = QWidget::keyboardGrabber();
2090 if (
auto * widget = QApplication::focusWidget(); widget && widget->isEnabled())
2096 target = widget->topLevelWidget();
2112 if (
Show &&
GetMythDB()->GetBoolSetting(
"HideMouseCursor",
false))
2116 setCursor(
Show ? (Qt::ArrowCursor) : (Qt::BlankCursor));
2169 LOG(VB_GENERAL, LOG_NOTICE,
"Suspending idle timer");
2174 LOG(VB_GENERAL, LOG_NOTICE,
"Resuming idle timer");
2190 LOG(VB_GENERAL, LOG_NOTICE,
2191 QString(
"Entering standby mode after %1 minutes of inactivity").arg(
m_idleTime.count()));
2214 LOG(VB_GENERAL, LOG_NOTICE, QString(
"Entering standby mode"));
2221 state.insert(
"state",
"standby");
2222 state.insert(
"menutheme",
GetMythDB()->GetSetting(
"menutheme",
"defaultmenu"));
2223 state.insert(
"currentlocation",
GetMythUI()->GetCurrentLocation());
2249 LOG(VB_GENERAL, LOG_NOTICE,
"Leaving standby mode");
2257 state.insert(
"state",
"idle");
2258 state.insert(
"menutheme",
GetMythDB()->GetSetting(
"menutheme",
"defaultmenu"));
2259 state.insert(
"currentlocation",
GetMythUI()->GetCurrentLocation());
2265 LOG(VB_GENERAL, LOG_NOTICE, QString(
"Application State Changed to %1").arg(
State));
2268 case Qt::ApplicationState::ApplicationActive:
2271 case Qt::ApplicationState::ApplicationSuspended:
An action (for this plugin) consists of a description, and a set of key sequences.
static const Type kEventType
QSqlQuery wrapper that fetches a DB connection from the connection pool.
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
QVariant value(int i) const
bool isActive(void) const
bool isConnected(void) const
Only updated once during object creation.
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
void ResetAudioLanguage(void)
void SetWOLAllowed(bool allow)
QString GetSetting(const QString &key, const QString &defaultval="")
static int GetMasterServerPort(void)
Returns the Master Backend control port If no master server port has been defined in the database,...
QString GetSettingOnHost(const QString &key, const QString &host, const QString &defaultval="")
void dispatch(const MythEvent &event)
void SetGUIObject(QObject *gui)
int GetNumSetting(const QString &key, int defaultval=0)
std::enable_if_t< std::chrono::__is_duration< T >::value, T > GetDurSetting(const QString &key, T defaultval=T::zero())
static void DBError(const QString &where, const MSqlQuery &query)
void SwitchToDesktop()
Return the screen to the original desktop video mode.
bool SwitchToGUI(bool Wait=false)
Switches to the GUI resolution.
virtual bool UsingVideoModes()
void SetWidget(QWidget *MainWindow)
Set the QWidget and QWindow in use.
This class is used as a container for messages.
static const Type kExitToMainMenuEventType
static const Type kPushDisableDrawingEventType
static const Type kDisableUDPListenerEventType
const QString & Message() const
static const Type kUnlockInputDevicesEventType
static const Type kPopDisableDrawingEventType
static const Type kEnableUDPListenerEventType
static const Type kMythPostShowEventType
static const Type kMythEventMessage
static const Type kMythUserMessage
static const Type kLockInputDevicesEventType
A custom event that represents a mouse gesture.
void SetPosition(QPoint Position)
static const Type kEventType
bool Record(QPoint Point, Qt::MouseButton Button)
Record a point.
MythGestureEvent * GetGesture() const
Complete the gesture event of the last completed stroke.
bool Recording()
Determine if the stroke is being recorded.
void Start()
Start recording.
void Stop(bool Timeout=false)
Stop recording.
QTimer * m_hideMouseTimer
void(* m_exitMenuCallback)(void)
QVector< MythScreenStack * > m_stackList
QMap< int, JumpData * > m_jumpMap
std::chrono::milliseconds m_longPressTime
QHash< QString, QHash< QString, QString > > m_actionText
QMap< QString, JumpData > m_destinationMap
MythNotificationCenter * m_nc
QHash< QString, KeyContext * > m_keyContexts
bool m_useDB
To allow or prevent database access.
static int TranslateKeyNum(QKeyEvent *Event)
QMap< QString, MythMediaCallback > m_mediaPluginMap
void(* m_exitMenuMediaDeviceCallback)(MythMediaDevice *mediadevice)
MythMediaDevice * m_mediaDeviceForCallback
MythScreenStack * m_mainStack
void customEvent(QEvent *Event) override
QWidget * GetPaintWindow()
void ClearKeyContext(const QString &Context)
static void DisableScreensaver()
void ShowMouseCursor(bool Show)
MythScreenStack * GetStackAt(int Position)
static void LoadQtConfig()
void ExitStandby(bool Manual=true)
void RemoteScreenShot(QString Filename, int Width, int Height)
MythNotificationCenter * GetCurrentNotificationCenter()
void SetDrawEnabled(bool Enable)
static void ResetScreensaver()
void OnApplicationStateChange(Qt::ApplicationState State)
void SignalRemoteScreenShot(QString Filename, int Width, int Height)
std::chrono::minutes m_idleTime
QString GetActionText(const QString &Context, const QString &Action) const
void PauseIdleTimer(bool Pause)
Pause the idle timeout timer.
MythDisplay * GetDisplay()
void HandleTVAction(const QString &Action)
MythScreenStack * GetMainStack()
static bool ScreenShot(int Width=0, int Height=0, QString Filename="")
void RestartInputHandlers()
void SignalDisableScreensaver()
void drawScreen(QPaintEvent *Event=nullptr)
MythRender * GetRenderDevice()
~MythMainWindow() override
MythScreenSaverControl * m_screensaver
void JumpTo(const QString &Destination, bool Pop=true)
void BindJump(const QString &Destination, const QString &Key)
bool event(QEvent *Event) override
void SignalResetScreensaver()
bool eventFilter(QObject *Watched, QEvent *Event) override
MythPainter * GetPainter()
static MythMainWindow * getMainWindow(bool UseDB=true)
Return the existing main window, or create one.
void SignalRestoreScreensaver()
static bool IsScreensaverAsleep()
void RegisterMediaPlugin(const QString &Name, const QString &Desc, MediaPlayCallback Func)
void ClearKey(const QString &Context, const QString &Action)
bool TranslateKeyPress(const QString &Context, QKeyEvent *Event, QStringList &Actions, bool AllowJumps=true)
Get a list of actions for a keypress in the given context.
MythMainWindow(bool UseDB=true)
void RegisterJump(const QString &Destination, const QString &Description, const QString &Key, void(*Callback)(void), bool Exittomain=true, QString LocalAction="")
static bool IsTopScreenInitialized()
bool IsExitingToMain() const
void SignalSetDrawEnabled(bool Enable)
static bool SaveScreenShot(const QImage &Image, QString Filename="")
void MoveResize(QRect &Geometry)
MythThemeBase * m_themeBase
void DoRemoteScreenShot(const QString &Filename, int Width, int Height)
void AddScreenStack(MythScreenStack *Stack, bool Main=false)
MythMainWindowPrivate * m_priv
static void GrabWindow(QImage &Image)
static void destroyMainWindow()
MythScreenStack * GetStack(const QString &Stackname)
void ResetIdleTimer()
Reset the idle timeout timer.
void EnterStandby(bool Manual=true)
static QString GetKey(const QString &Context, const QString &Action)
bool KeyLongPressFilter(QEvent **Event, QScopedPointer< QEvent > &NewEvent)
MythPainterWindow * m_painterWin
bool DestinationExists(const QString &Destination) const
void ClearJump(const QString &Destination)
void RegisterKey(const QString &Context, const QString &Action, const QString &Description, const QString &Key)
QStringList EnumerateDestinations() const
bool HandleMedia(const QString &Handler, const QString &Mrl, const QString &Plot="", const QString &Title="", const QString &Subtitle="", const QString &Director="", int Season=0, int Episode=0, const QString &Inetref="", std::chrono::minutes LenMins=2h, const QString &Year="1895", const QString &Id="", bool UseBookmarks=false)
static void RestoreScreensaver()
QPaintEngine * paintEngine() const override
void Draw(MythPainter *Painter=nullptr)
void closeEvent(QCloseEvent *Event) override
void SetEffectsEnabled(bool Enable)
void BindKey(const QString &Context, const QString &Action, const QString &Key)
void DisableIdleTimer(bool DisableIdle=true)
Disable the idle timeout timer.
void Init(bool MayReInit=true)
MythInputDeviceHandler * m_deviceHandler
QObject * GetTarget(QKeyEvent &Key)
void AllowInput(bool Allow)
static const Type kEventType
void ProcessQueue(void)
ProcessQueue will be called by the GUI event handler and will process all queued MythNotifications an...
static MythNotificationCenter * GetInstance(void)
returns the MythNotificationCenter singleton
int DisplayedNotifications(void) const
Returns number of notifications currently displayed.
bool Queue(const MythNotification ¬ification)
Queue a notification Queue() is thread-safe and can be called from anywhere.
void addListener(QObject *listener)
Add a listener to the observable.
void removeListener(QObject *listener)
Remove a listener to the observable.
static void DestroyPainters(MythPainterWindow *&PaintWin, MythPainter *&Painter)
static QString CreatePainters(MythMainWindow *MainWin, MythPainterWindow *&PaintWin, MythPainter *&Paint)
MythRender * GetRenderDevice()
virtual bool SupportsClipping(void)=0
virtual void SetClipRect(QRect clipRect)
virtual QString GetName(void)=0
virtual void Begin(QPaintDevice *)
Controls all instances of the screensaver.
virtual MythScreenType * GetTopScreen(void) const
Screen in which all other widgets are contained and rendered.
bool gestureEvent(MythGestureEvent *event) override
Mouse click/movement handler, receives mouse gesture events from the QCoreApplication event loop.
bool inputMethodEvent(QInputMethodEvent *event) override
Input Method event handler.
bool IsInitialized(void) const
Has Init() been called on this screen?
static void EnableUDPListener(bool Enable=true)
static void StopUDPListener()
static bool WindowIsAlwaysFullscreen()
Return true if the current platform only supports fullscreen windows.
void UpdateScreenSettings(MythDisplay *mDisplay)
static bool GeometryIsOverridden()
void SetUIScreenRect(QRect Rect)
static void SetState(const QVariantMap &NewState)
void ClearThemeCacheDir()
bool ContainsPoint(QPoint point) const
Check if the given point falls within this widgets area.
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
MythConfirmationDialog * ShowOkPopup(const QString &message, bool showCancel)
Non-blocking version of MythPopupBox::showOkPopup()
A C++ ripoff of the stroke library for MythTV.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
static constexpr std::chrono::minutes STANDBY_TIMEOUT
MythNotificationCenter * GetNotificationCenter(void)
bool HasMythMainWindow(void)
static constexpr std::chrono::milliseconds LONGPRESS_INTERVAL
MythPainter * GetMythPainter(void)
MythMainWindow * GetMythMainWindow(void)
static MythMainWindow * s_mainWin
void DestroyMythMainWindow(void)
static constexpr std::chrono::milliseconds GESTURE_TIMEOUT
int(*)(const QString &, const QString &, const QString &, const QString &, const QString &, int, int, const QString &, std::chrono::minutes, const QString &, const QString &, bool) MediaPlayCallback
static constexpr const char * ACTION_7
static constexpr const char * ACTION_5
static constexpr const char * ACTION_0
static constexpr const char * ACTION_SCREENSHOT
static constexpr const char * ACTION_LEFT
static constexpr const char * ACTION_DOWN
static constexpr const char * ACTION_3
static constexpr const char * ACTION_1
static constexpr const char * ACTION_TVPOWERON
static constexpr const char * ACTION_HANDLEMEDIA
static constexpr const char * ACTION_TVPOWEROFF
static constexpr const char * ACTION_4
static constexpr const char * ACTION_RIGHT
static constexpr const char * ACTION_SELECT
static constexpr const char * ACTION_UP
static constexpr const char * ACTION_GETSTATUS
static constexpr const char * ACTION_6
static constexpr const char * ACTION_8
static constexpr const char * ACTION_2
static constexpr const char * ACTION_9
MythUIHelper * GetMythUI()
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
@ kScreenShotFilename
"yyyy-MM-ddThh-mm-ss.zzz"
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
static void show(uint8_t *buf, int length)