5#include <QCoreApplication>
24#include "libmythbase/mythversion.h"
47 LOG(VB_GENERAL, LOG_ERR,
"Missing 'menu' buttonlist.");
61 LOG(VB_GENERAL, LOG_INFO,
"ERROR, bad parsing");
202 if (
type &&
type->keyPressEvent(event))
209 bool handled =
false;
214 for (
int i = 0; i < actions.size() && !handled; i++)
216 const QString&
action = actions[i];
227 QString menuaction =
"UPMENU";
228 QString selExit =
"EXITING_APP_PROMPT";
231 selExit =
"EXITING_APP";
232 else if (
action ==
"STANDBYMODE")
233 selExit =
"STANDBY_MODE";
244 QString sel =
"EXITING_MENU";
252 QCoreApplication::exit();
256 action ==
"STANDBYMODE" ||
258 (QCoreApplication::applicationName() ==
267 QCoreApplication::exit();
272 else if (
action ==
"HELP")
276 else if (
action ==
"EJECT")
308 int override_menu =
GetMythDB()->GetNumSetting(
"OverrideExitMenu");
309 QString label = tr(
"System Menu");
323 if (override_menu != 7)
326 switch (override_menu)
356 QFile
file(
"/etc/os_myth_release");
357 if (
file.open(QFile::ReadOnly))
359 QTextStream
t( &
file );
360 distro_line =
t.readLine();
364 QString label = tr(
"Revision: %1\n Branch: %2\n %3")
385 QString resultid = dce->GetId();
387 QString halt_cmd =
GetMythDB()->GetSetting(
"HaltCommand");
388 QString reboot_cmd =
GetMythDB()->GetSetting(
"RebootCommand");
390 if (resultid ==
"popmenu")
392 QString
action = dce->GetData().toString();
395 if (!halt_cmd.isEmpty())
398 else if (
action ==
"reboot")
400 if (!reboot_cmd.isEmpty())
403 else if (
action ==
"about")
407 else if (
action ==
"standby")
409 QString arg(
"standby_mode");
412 else if (
action ==
"exit")
414 QString arg(
"exiting_app");
418 else if (resultid ==
"password")
420 QString text = dce->GetResultText();
423 QString password =
GetMythDB()->GetSetting(button.password);
424 if (text == password)
426 QString timestamp_setting = QString(
"%1Time").arg(button.password);
428 QString last_time_stamp =
430 GetMythDB()->SaveSetting(timestamp_setting, last_time_stamp);
455 for (QDomNode child = element.firstChild(); !child.isNull();
456 child = child.nextSibling())
458 QDomElement
info = child.toElement();
461 if (
info.tagName() ==
"type")
465 else if (
info.tagName() ==
"text")
467 if (text.isEmpty() &&
468 info.attribute(
"lang",
"").isEmpty())
470 text = QCoreApplication::translate(
"ThemeUI",
473 else if ((
info.attribute(
"lang",
"").toLower() ==
475 (
info.attribute(
"lang",
"").toLower() ==
481 else if (
info.tagName() ==
"alttext")
483 if (alttext.isEmpty() &&
484 info.attribute(
"lang",
"").isEmpty())
486 alttext = QCoreApplication::translate(
"ThemeUI",
489 else if ((
info.attribute(
"lang",
"").toLower() ==
491 (
info.attribute(
"lang",
"").toLower() ==
497 else if (
info.tagName() ==
"action")
501 else if (
info.tagName() ==
"depends")
505 else if (
info.tagName() ==
"dependsexec")
509 else if (
info.tagName() ==
"dependssetting")
513 else if (
info.tagName() ==
"dependjumppoint")
518 else if (
info.tagName() ==
"dependswindow")
520 QString xmlFile =
info.attribute(
"xmlfile",
"");
522 if (xmlFile.isEmpty() || windowName.isEmpty())
527 else if (
info.tagName() ==
"description")
529 if (description.isEmpty() &&
530 info.attribute(
"lang",
"").isEmpty())
532 description = QCoreApplication::translate(
"ThemeUI",
535 else if ((
info.attribute(
"lang",
"").toLower() ==
537 (
info.attribute(
"lang",
"").toLower() ==
543 else if (
info.tagName() ==
"password")
549 LOG(VB_GENERAL, LOG_ERR,
550 QString(
"MythThemedMenu: Unknown tag %1 in button")
551 .arg(
info.tagName()));
558 LOG(VB_GENERAL, LOG_ERR,
"MythThemedMenu: Missing 'text' in button");
564 LOG(VB_GENERAL, LOG_ERR,
"MythThemedMenu: Missing 'action' in button");
592 if (!f.exists() || !f.open(QIODevice::ReadOnly))
594 LOG(VB_GENERAL, LOG_ERR, QString(
"MythThemedMenu: Couldn't read "
595 "menu file %1").arg(menuname));
597 if (menuname !=
"mainmenu.xml")
598 ShowOkPopup(tr(
"MythTV could not locate the menu file %1")
603#if QT_VERSION < QT_VERSION_CHECK(6,5,0)
608 if (!doc.setContent(&f,
false, &errorMsg, &errorLine, &errorColumn))
610 LOG(VB_GENERAL, LOG_ERR,
611 QString(
"Error parsing: %1\nat line: %2 column: %3 msg: %4").
612 arg(
filename).arg(errorLine).arg(errorColumn).arg(errorMsg));
615 if (menuname !=
"mainmenu.xml")
621 auto parseResult = doc.setContent(&f);
624 LOG(VB_GENERAL, LOG_ERR,
625 QString(
"Error parsing: %1\nat line: %2 column: %3 msg: %4")
626 .arg(
filename).arg(parseResult.errorLine)
627 .arg(parseResult.errorColumn).arg(parseResult.errorMessage));
630 if (menuname !=
"mainmenu.xml")
639 LOG(VB_GUI, LOG_INFO, QString(
"Loading menu theme from %1").arg(
filename));
641 QDomElement docElem = doc.documentElement();
643 m_menumode = docElem.attribute(
"name",
"MAIN");
645 QDomNode n = docElem.firstChild();
648 QDomElement e = n.toElement();
651 if (e.tagName() ==
"button")
657 LOG(VB_GENERAL, LOG_ERR,
658 QString(
"MythThemedMenu: Unknown element %1")
668 LOG(VB_GENERAL, LOG_ERR,
669 QString(
"MythThemedMenu: No buttons for menu %1").arg(menuname));
702 const QString &alttext,
703 const QStringList &
action,
704 const QString &description,
705 const QString &password)
710 newbutton.
text = text;
719 QVariant::fromValue(newbutton));
721 listbuttonitem->DisplayState(
type,
"icon");
722 listbuttonitem->SetText(description,
"description");
733 for (
const auto & act : std::as_const(button.action))
752 QString testdir =
GetConfDir() +
'/' + menuname;
756 LOG(VB_FILE, LOG_DEBUG,
"No menu file " + testdir);
759 file.setFileName(testdir);
762 LOG(VB_FILE, LOG_DEBUG,
"No menu file " + testdir);
765 file.setFileName(testdir);
768 LOG(VB_FILE, LOG_DEBUG,
"No menu file " + testdir);
771 file.setFileName(testdir);
774 LOG(VB_FILE, LOG_DEBUG,
"No menu file " + testdir);
776 testdir =
"../mythfrontend/" + menuname;
777 file.setFileName(testdir);
780 LOG(VB_FILE, LOG_DEBUG,
"No menu file " + testdir);
782 testdir =
GetShareDir() +
"themes/defaultmenu/" + menuname;
783 file.setFileName(testdir);
786 LOG(VB_FILE, LOG_DEBUG,
"No menu file " + testdir);
804 if (
action.startsWith(
"EXEC "))
812 if (
action.startsWith(
"EXECTV "))
814 QString rest =
action.right(
action.length() - 7).trimmed();
818 else if (
action.startsWith(
"MENU "))
825 if (newmenu->foundTheme())
830 else if (
action.startsWith(
"UPMENU"))
834 else if (
action.startsWith(
"CONFIGPLUGIN"))
840 else if (
action.startsWith(
"PLUGIN"))
846 else if (
action.startsWith(
"SHUTDOWN"))
853 else if (
action.startsWith(
"EJECT"))
855 if (cbs && cbs->
eject)
858 else if (
action.startsWith(
"JUMP "))
863 else if (
action.startsWith(
"MEDIA "))
867 QStringList list =
action.simplified().split(
' ');
868 if (list.size() >= 3)
877 LOG(VB_GENERAL, LOG_ERR,
"Unknown menu action: " +
action);
885 QStringList files = fileList.split(
" ");
888 for (
const auto &
file : std::as_const(files))
907 return filename_info.exists() && filename_info.isFile() && filename_info.isExecutable();
918 QString timestamp_setting = QString(
"%1Time").arg(password_setting);
920 QString last_time_stamp =
GetMythDB()->GetSetting(timestamp_setting);
921 QString password =
GetMythDB()->GetSetting(password_setting);
924 if (password.isEmpty())
927 if (last_time_stamp.length() < 1)
929 LOG(VB_GENERAL, LOG_ERR,
930 "MythThemedMenu: Could not read password/pin time stamp.\n"
931 "This is only an issue if it happens repeatedly.");
936 if (!last_time.isValid() || last_time.secsTo(curr_time) < 120)
940 GetMythDB()->SaveSetting(timestamp_setting, last_time_stamp);
945 LOG(VB_GENERAL, LOG_INFO, QString(
"Using Password: %1")
946 .arg(password_setting));
948 QString text = tr(
"Enter password:");
952 if (dialog->Create())
954 dialog->SetReturnEvent(
this,
"password");
Event dispatched from MythUI modal dialogs to a listening class containing a result of some form.
static const Type kEventType
MythPluginManager * GetPluginManager(void)
QString GetLanguage(void)
Returns two character ISO-639 language descriptor for UI language.
QString GetLanguageAndVariant(void)
Returns the user-set language and variant.
Basic menu dialog, message and a list of options.
void AddButton(const QString &title)
void SetReturnEvent(QObject *retobject, const QString &resultid)
void AddButtonV(const QString &title, QVariant data=0, bool newMenu=false, bool setCurrent=false)
bool Create(void) override
MythScreenStack * GetMainStack()
void JumpTo(const QString &Destination, bool Pop=true)
bool TranslateKeyPress(const QString &Context, QKeyEvent *Event, QStringList &Actions, bool AllowJumps=true)
Get a list of actions for a keypress in the given context.
MythScreenStack * GetStack(const QString &Stackname)
bool DestinationExists(const QString &Destination) 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)
MythPlugin * GetPlugin(const QString &plugname)
virtual void PopScreen(MythScreenType *screen=nullptr, bool allowFade=true, bool deleteScreen=true)
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
MythScreenStack * m_screenStack
virtual void aboutToShow(void)
MythUIType * GetFocusWidget(void) const
MythScreenStack * GetScreenStack() const
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
void CopyFrom(MythUIType *base) override
Copy this widgets state from another.
Dialog prompting the user to enter a text string.
MythUIMenuCallbacks * GetMenuCBs()
This widget is used for grouping other widgets for display when a particular named state is called.
void EnsureStateLoaded(const QString &name)
void Reset(void) override
Reset the widget to it's original state, should not reset changes made by the theme.
bool DisplayState(const QString &name)
All purpose text widget, displays a text string.
virtual void SetText(const QString &text)
QString GetMenuThemeDir()
The base class on which all widgets and screens are based.
MythUIType * GetChild(const QString &name) const
Get a named child of this UIType.
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
static QString getFirstText(QDomElement &element)
static bool WindowExists(const QString &xmlfile, const QString &windowname)
static QString parseText(QDomElement &element)
static constexpr const char * MYTH_APPNAME_MYTHTV_SETUP
static constexpr const char * MYTH_APPNAME_MYTHFRONTEND
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()
QString GetShareDir(void)
A C++ ripoff of the stroke library for MythTV.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
MythMainWindow * GetMythMainWindow(void)
uint myth_system(const QString &command, uint flags, std::chrono::seconds timeout)
static MythThemedMenu * menu
MythUIHelper * GetMythUI()
const char * GetMythSourceVersion()
const char * GetMythSourcePath()
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
@ kDatabase
Default UTC, database format.
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
QDateTime current(bool stripped)
Returns current Date and Time in UTC.