7#include <QGlobalStatic>
8#include <QCoreApplication>
14#include "libmythbase/mythversion.h"
28#define LOC QString("FrontendServices: ")
49 QStringList contexts = bindings->GetContexts();
51 for (
const QString & context : std::as_const(contexts))
54 QStringList ctxactions = bindings->GetActions(context);
57 for (
const QString & actions : std::as_const(ctxactions))
59 QString desc = actions +
"," + bindings->GetActionDescription(context, actions);
70 if (
action.startsWith(
"select", Qt::CaseInsensitive) &&
action.contains(
"_"))
98 qRegisterMetaType<FrontendStatus*>(
"FrontendStatus");
99 qRegisterMetaType<FrontendActionList*>(
"FrontendActionList");
122 QString key = Key.toLower();
126 QMetaEnum meta = QMetaEnum::fromType<Qt::Key>();
127 for (
int i = 0; i < meta.keyCount(); i++)
129 if (QByteArray(meta.key(i)).mid(4).toLower() == key)
131 keycode = meta.value(i);
137 if (!valid && key.size() == 1)
139 keycode = key.toLatin1()[0] & 0x7f;
145 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"Unknown key: '%1'").arg(Key));
151 auto * event1 =
new QKeyEvent(QEvent::KeyPress, keycode, Qt::NoModifier,
"");
152 QCoreApplication::postEvent(mainwindow, event1);
153 auto * event2 =
new QKeyEvent(QEvent::KeyRelease, keycode, Qt::NoModifier,
"");
154 QCoreApplication::postEvent(mainwindow, event2);
155 LOG(VB_HTTP, LOG_INFO,
LOC + QString(
"Sent key: '%1'").arg(Key));
161 if (Message.isEmpty())
163 QStringList data(QString::number(
std::clamp(Timeout, 0U, 1000U)));
175 const QString& Message,
const QString& Origin,
176 const QString& Description,
const QString& Image,
177 const QString& Extra,
const QString& ProgressText,
178 float Progress, std::chrono::seconds Timeout,
179 bool Fullscreen,
uint Visibility,
186 Message, Origin.isNull() ? tr(
"FrontendServices") : Origin,
187 Description, Image, Extra, ProgressText, Progress, Timeout,
195 QHashIterator<QString,QStringList> contexts(s_actions->Descriptions());
196 while (contexts.hasNext())
199 if (!Context.isEmpty() && contexts.key() != Context)
203 QStringList actions = contexts.value();
204 for (
const QString &
action : std::as_const(actions))
206 QStringList split =
action.split(
",");
207 if (split.size() == 2)
208 result.insert(split[0], split[1]);
216 return s_actions->Descriptions().keys();
219bool MythFrontendService::SendAction(
const QString&
Action,
const QString& Value,
uint Width,
uint Height)
224 if (!Value.isEmpty() && s_actions->ValueActions().contains(
Action))
234 if (!Width || !Height)
236 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Invalid screenshot parameters.");
241 args << QString::number(Width) << QString::number(Height);
254 if (s_actions->Actions().contains(
Action) || s_actions->SelectActions().contains(
Action))
256 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Action '%1'' is invalid.").arg(
Action));
262 QDateTime starttime = StartTime;
264 if ((RecordedId <= 0) && (ChanId <= 0 || !StartTime.isValid()))
266 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Recorded ID or Channel ID and StartTime appears invalid.");
273 ChanId =
static_cast<int>(recInfo.
GetChanID());
281 QString message = QString(
"NETWORK_CONTROL STOP");
287 while (!timer.hasExpired(10000) && (
GetMythUI()->GetCurrentLocation().toLower() ==
"playback"))
288 std::this_thread::sleep_for(std::chrono::milliseconds(10));
291 if (
GetMythUI()->GetCurrentLocation().toLower() !=
"playbackbox")
296 while (!timer.hasExpired(10000) && (
GetMythUI()->GetCurrentLocation().toLower() !=
"playbackbox"))
297 std::this_thread::sleep_for(std::chrono::milliseconds(10));
301 std::this_thread::sleep_for(std::chrono::milliseconds(10));
304 if (
GetMythUI()->GetCurrentLocation().toLower() ==
"playbackbox")
306 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"PlayRecording, ChanID: %1 StartTime: %2")
307 .arg(ChanId).arg(starttime.toString(
Qt::ISODate)));
309 QString message = QString(
"NETWORK_CONTROL PLAY PROGRAM %1 %2 %3")
310 .arg(ChanId).arg(starttime.toString(
"yyyyMMddhhmmss"),
"12345");
324 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"Ignoring PlayVideo request - frontend is busy."));
329 uint id = Id.toUInt(&ok);
332 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"Invalid video Id."));
339 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"Didn't find any video metadata."));
343 if (metadata->GetHost().isEmpty())
345 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"No host for video."));
350 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"PlayVideo ID: %1 UseBookmark: %2 URL: '%3'")
351 .arg(
id).arg(UseBookmark).arg(mrl));
354 args << mrl << metadata->GetPlot() << metadata->GetTitle()
355 << metadata->GetSubtitle() << metadata->GetDirector()
356 << QString::number(metadata->GetSeason())
357 << QString::number(metadata->GetEpisode())
358 << metadata->GetInetRef() << QString::number(metadata->GetLength().count())
359 << QString::number(metadata->GetYear())
360 << QString::number(metadata->GetID())
361 << QString::number(
static_cast<int>(UseBookmark));
370 m_Version(
std::move(Version)),
373 if (m_State.contains(
"chaptertimes") &&
374#
if QT_VERSION < QT_VERSION_CHECK(6,0,0)
375 m_State[
"chaptertimes"].
type() == QVariant::List
377 m_State[
"chaptertimes"].typeId() == QMetaType::QVariantList
381 m_ChapterTimes = m_State[
"chaptertimes"].toList();
382 m_State.remove(
"chaptertimes");
385 if (m_State.contains(
"subtitletracks") &&
386#
if QT_VERSION < QT_VERSION_CHECK(6,0,0)
387 m_State[
"subtitletracks"].
type() == QVariant::Map
389 m_State[
"subtitletracks"].typeId() == QMetaType::QVariantMap
393 m_SubtitleTracks = m_State[
"subtitletracks"].toMap();
394 m_State.remove(
"subtitletracks");
397 if (m_State.contains(
"audiotracks") &&
398#
if QT_VERSION < QT_VERSION_CHECK(6,0,0)
399 m_State[
"audiotracks"].
type() == QVariant::Map
401 m_State[
"audiotracks"].typeId() == QMetaType::QVariantMap
405 m_AudioTracks = m_State[
"audiotracks"].toMap();
406 m_State.remove(
"audiotracks");
411 : m_ActionList(
std::move(List))
An action (for this plugin) consists of a description, and a set of key sequences.
Q_INVOKABLE FrontendActionList(QObject *parent=nullptr)
QStringList m_valueActions
QHash< QString, QStringList > m_actionDescriptions
QStringList m_selectActions
const QStringList & Actions()
const ActionDescs & Descriptions()
const QStringList & ValueActions()
const QStringList & SelectActions()
Q_INVOKABLE FrontendStatus(QObject *parent=nullptr)
Encapsulates information about the current keybindings.
QString GetHostName(void)
void dispatch(const MythEvent &event)
This class is used as a container for messages.
static const Type kMythUserMessage
static bool SendNotification(bool Error, const QString &Type, const QString &Message, const QString &Origin, const QString &Description, const QString &Image, const QString &Extra, const QString &ProgressText, float Progress, std::chrono::seconds Timeout, bool Fullscreen, uint Visibility, uint Priority)
Send a notification to the frontend.
static bool PlayVideo(const QString &Id, bool UseBookmark)
static FrontendActionList * GetActionList(const QString &Context)
static bool PlayRecording(int RecordedId, int ChanId, const QDateTime &StartTime)
static bool IsValidAction(const QString &Action)
static FrontendStatus * GetStatus()
static Q_CLASSINFO("GetContextList", "name=StringList") public slots bool SendKey(const QString &Key)
static QStringList GetContextList()
static bool SendMessage(const QString &Message, uint Timeout)
static void ResetScreensaver()
void JumpTo(const QString &Destination, bool Pop=true)
static bool IsTopScreenInitialized()
static Type TypeFromString(const QString &Type)
QString GetCurrentLocation(bool FullPath=false, bool MainStackOnly=true)
static void GetFreshState(QVariantMap &State)
uint GetChanID(void) const
This is the unique key used in the database to locate tuning information.
QDateTime GetRecordingStartTime(void) const
Approximate time the recording started.
Holds information on a TV Program one might wish to record.
static QString generate_file_url(const QString &storage_group, const QString &host, const QString &path)
static bool IsTVRunning()
Check whether media is currently playing.
Main header for keybinding classes.
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
QHash< QString, QStringList > ActionDescs
Q_GLOBAL_STATIC_WITH_ARGS(MythHTTPMetaService, s_service,(FRONTEND_HANDLE, MythFrontendService::staticMetaObject, &MythFrontendService::RegisterCustomTypes)) void MythFrontendService
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
MythNotificationCenter * GetNotificationCenter(void)
bool HasMythMainWindow(void)
MythMainWindow * GetMythMainWindow(void)
void ShowNotification(const QString &msg, const QString &from, const QString &detail, const VNMask visibility, const MythNotification::Priority priority)
static constexpr const char * ACTION_SCREENSHOT
static constexpr const char * ACTION_HANDLEMEDIA
MythUIHelper * GetMythUI()
const char * GetMythSourceVersion()
static eu8 clamp(eu8 value, eu8 low, eu8 high)
#define ACTION_SWITCHANGLE
#define ACTION_SETCONTRAST
#define ACTION_SETBRIGHTNESS
#define ACTION_SWITCHTITLE
#define ACTION_SEEKABSOLUTE
#define ACTION_JUMPCHAPTER
#define ACTION_SETAUDIOSYNC