Go to the documentation of this file.
5 #include <QCoreApplication>
8 #include <QDomDocument>
11 #include <QTextStream>
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";
242 QString sel =
"EXITING_MENU";
250 QCoreApplication::exit();
254 action ==
"STANDBYMODE" ||
256 (QCoreApplication::applicationName() ==
263 QCoreApplication::exit();
268 else if (
action ==
"HELP")
272 else if (
action ==
"EJECT")
304 int override_menu =
GetMythDB()->GetNumSetting(
"OverrideExitMenu");
305 QString label = tr(
"System Menu");
319 if (override_menu != 7)
322 switch (override_menu)
352 QFile
file(
"/etc/os_myth_release");
353 if (
file.open(QFile::ReadOnly))
355 QTextStream
t( &
file );
356 distro_line =
t.readLine();
360 QString label = tr(
"Revision: %1\n Branch: %2\n %3")
381 QString resultid = dce->GetId();
383 QString halt_cmd =
GetMythDB()->GetSetting(
"HaltCommand");
384 QString reboot_cmd =
GetMythDB()->GetSetting(
"RebootCommand");
386 if (resultid ==
"popmenu")
388 QString
action = dce->GetData().toString();
391 if (!halt_cmd.isEmpty())
394 else if (
action ==
"reboot")
396 if (!reboot_cmd.isEmpty())
399 else if (
action ==
"about")
403 else if (
action ==
"standby")
405 QString arg(
"standby_mode");
408 else if (
action ==
"exit")
410 QString arg(
"exiting_app");
414 else if (resultid ==
"password")
416 QString text = dce->GetResultText();
419 QString password =
GetMythDB()->GetSetting(button.password);
420 if (text == password)
422 QString timestamp_setting = QString(
"%1Time").arg(button.password);
424 QString last_time_stamp =
426 GetMythDB()->SaveSetting(timestamp_setting, last_time_stamp);
451 for (QDomNode child = element.firstChild(); !child.isNull();
452 child = child.nextSibling())
454 QDomElement
info = child.toElement();
457 if (
info.tagName() ==
"type")
461 else if (
info.tagName() ==
"text")
463 if (text.isEmpty() &&
464 info.attribute(
"lang",
"").isEmpty())
466 text = QCoreApplication::translate(
"ThemeUI",
469 else if ((
info.attribute(
"lang",
"").toLower() ==
471 (
info.attribute(
"lang",
"").toLower() ==
477 else if (
info.tagName() ==
"alttext")
479 if (alttext.isEmpty() &&
480 info.attribute(
"lang",
"").isEmpty())
482 alttext = QCoreApplication::translate(
"ThemeUI",
485 else if ((
info.attribute(
"lang",
"").toLower() ==
487 (
info.attribute(
"lang",
"").toLower() ==
493 else if (
info.tagName() ==
"action")
497 else if (
info.tagName() ==
"depends")
501 else if (
info.tagName() ==
"dependsexec")
505 else if (
info.tagName() ==
"dependssetting")
509 else if (
info.tagName() ==
"dependjumppoint")
514 else if (
info.tagName() ==
"dependswindow")
516 QString xmlFile =
info.attribute(
"xmlfile",
"");
518 if (xmlFile.isEmpty() || windowName.isEmpty())
523 else if (
info.tagName() ==
"description")
525 if (description.isEmpty() &&
526 info.attribute(
"lang",
"").isEmpty())
528 description = QCoreApplication::translate(
"ThemeUI",
531 else if ((
info.attribute(
"lang",
"").toLower() ==
533 (
info.attribute(
"lang",
"").toLower() ==
539 else if (
info.tagName() ==
"password")
545 LOG(VB_GENERAL, LOG_ERR,
546 QString(
"MythThemedMenu: Unknown tag %1 in button")
547 .arg(
info.tagName()));
554 LOG(VB_GENERAL, LOG_ERR,
"MythThemedMenu: Missing 'text' in button");
560 LOG(VB_GENERAL, LOG_ERR,
"MythThemedMenu: Missing 'action' in button");
588 if (!f.exists() || !f.open(QIODevice::ReadOnly))
590 LOG(VB_GENERAL, LOG_ERR, QString(
"MythThemedMenu: Couldn't read "
591 "menu file %1").arg(menuname));
593 if (menuname !=
"mainmenu.xml")
594 ShowOkPopup(tr(
"MythTV could not locate the menu file %1")
599 #if QT_VERSION < QT_VERSION_CHECK(6,5,0)
604 if (!doc.setContent(&f,
false, &errorMsg, &errorLine, &errorColumn))
606 LOG(VB_GENERAL, LOG_ERR,
607 QString(
"Error parsing: %1\nat line: %2 column: %3 msg: %4").
608 arg(
filename).arg(errorLine).arg(errorColumn).arg(errorMsg));
611 if (menuname !=
"mainmenu.xml")
617 auto parseResult = doc.setContent(&f);
620 LOG(VB_GENERAL, LOG_ERR,
621 QString(
"Error parsing: %1\nat line: %2 column: %3 msg: %4")
622 .arg(
filename).arg(parseResult.errorLine)
623 .arg(parseResult.errorColumn).arg(parseResult.errorMessage));
626 if (menuname !=
"mainmenu.xml")
635 LOG(VB_GUI, LOG_INFO, QString(
"Loading menu theme from %1").arg(
filename));
637 QDomElement docElem = doc.documentElement();
639 m_menumode = docElem.attribute(
"name",
"MAIN");
641 QDomNode n = docElem.firstChild();
644 QDomElement e = n.toElement();
647 if (e.tagName() ==
"button")
653 LOG(VB_GENERAL, LOG_ERR,
654 QString(
"MythThemedMenu: Unknown element %1")
664 LOG(VB_GENERAL, LOG_ERR,
665 QString(
"MythThemedMenu: No buttons for menu %1").arg(menuname));
698 const QString &alttext,
699 const QStringList &
action,
700 const QString &description,
701 const QString &password)
706 newbutton.
text = text;
715 QVariant::fromValue(newbutton));
717 listbuttonitem->DisplayState(
type,
"icon");
718 listbuttonitem->SetText(description,
"description");
729 for (
const auto & act : std::as_const(button.action))
748 QString testdir =
GetConfDir() +
'/' + menuname;
752 LOG(VB_FILE, LOG_DEBUG,
"No menu file " + testdir);
755 file.setFileName(testdir);
758 LOG(VB_FILE, LOG_DEBUG,
"No menu file " + testdir);
761 file.setFileName(testdir);
764 LOG(VB_FILE, LOG_DEBUG,
"No menu file " + testdir);
767 file.setFileName(testdir);
770 LOG(VB_FILE, LOG_DEBUG,
"No menu file " + testdir);
772 testdir =
"../mythfrontend/" + menuname;
773 file.setFileName(testdir);
776 LOG(VB_FILE, LOG_DEBUG,
"No menu file " + testdir);
778 testdir =
GetShareDir() +
"themes/defaultmenu/" + menuname;
779 file.setFileName(testdir);
782 LOG(VB_FILE, LOG_DEBUG,
"No menu file " + testdir);
800 if (
action.startsWith(
"EXEC "))
808 if (
action.startsWith(
"EXECTV "))
810 QString rest =
action.right(
action.length() - 7).trimmed();
814 else if (
action.startsWith(
"MENU "))
821 if (newmenu->foundTheme())
826 else if (
action.startsWith(
"UPMENU"))
830 else if (
action.startsWith(
"CONFIGPLUGIN"))
836 else if (
action.startsWith(
"PLUGIN"))
842 else if (
action.startsWith(
"SHUTDOWN"))
849 else if (
action.startsWith(
"EJECT"))
851 if (cbs && cbs->
eject)
854 else if (
action.startsWith(
"JUMP "))
859 else if (
action.startsWith(
"MEDIA "))
863 QStringList list =
action.simplified().split(
' ');
864 if (list.size() >= 3)
873 LOG(VB_GENERAL, LOG_ERR,
"Unknown menu action: " +
action);
881 QStringList files = fileList.split(
" ");
884 for (
const auto &
file : std::as_const(files))
903 return filename_info.exists() && filename_info.isFile() && filename_info.isExecutable();
914 QString timestamp_setting = QString(
"%1Time").arg(password_setting);
916 QString last_time_stamp =
GetMythDB()->GetSetting(timestamp_setting);
917 QString password =
GetMythDB()->GetSetting(password_setting);
920 if (password.isEmpty())
923 if (last_time_stamp.length() < 1)
925 LOG(VB_GENERAL, LOG_ERR,
926 "MythThemedMenu: Could not read password/pin time stamp.\n"
927 "This is only an issue if it happens repeatedly.");
932 if (!last_time.isValid() || last_time.secsTo(curr_time) < 120)
936 GetMythDB()->SaveSetting(timestamp_setting, last_time_stamp);
941 LOG(VB_GENERAL, LOG_INFO, QString(
"Using Password: %1")
942 .arg(password_setting));
944 QString text = tr(
"Enter password:");
948 if (dialog->Create())
950 dialog->SetReturnEvent(
this,
"password");
MythScreenStack * GetMainStack()
void SetReturnEvent(QObject *retobject, const QString &resultid)
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
void EnsureStateLoaded(const QString &name)
static constexpr const char * MYTH_APPNAME_MYTHFRONTEND
MythUIType * GetChild(const QString &name) const
Get a named child of this UIType.
void JumpTo(const QString &Destination, bool Pop=true)
const char * GetMythSourceVersion()
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
void Reset(void) override
Reset the widget to it's original state, should not reset changes made by the theme.
uint myth_system(const QString &command, uint flags, std::chrono::seconds timeout)
void CopyFrom(MythUIType *base) override
Copy this widgets state from another.
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
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 QString parseText(QDomElement &element)
MythUIType * GetFocusWidget(void) const
bool TranslateKeyPress(const QString &Context, QKeyEvent *Event, QStringList &Actions, bool AllowJumps=true)
Get a list of actions for a keypress in the given context.
void AddButton(const QString &title)
Basic menu dialog, message and a list of options.
static MythThemedMenu * menu
bool Create(void) override
QString GetShareDir(void)
bool DestinationExists(const QString &Destination) const
static QString getFirstText(QDomElement &element)
MythUIMenuCallbacks * GetMenuCBs()
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
static bool WindowExists(const QString &xmlfile, const QString &windowname)
QString GetLanguage(void)
Returns two character ISO-639 language descriptor for UI language.
MythScreenStack * GetScreenStack() const
A C++ ripoff of the stroke library for MythTV.
The base class on which all widgets and screens are based.
const char * GetMythSourcePath()
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
static constexpr const char * MYTH_APPNAME_MYTHTV_SETUP
void AddButtonV(const QString &title, QVariant data=0, bool newMenu=false, bool setCurrent=false)
All purpose text widget, displays a text string.
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
QString GetLanguageAndVariant(void)
Returns the user-set language and variant.
MythPlugin * GetPlugin(const QString &plugname)
Event dispatched from MythUI modal dialogs to a listening class containing a result of some form.
virtual void SetText(const QString &text)
virtual void PopScreen(MythScreenType *screen=nullptr, bool allowFade=true, bool deleteScreen=true)
static const Type kEventType
MythMainWindow * GetMythMainWindow(void)
@ kDatabase
Default UTC, database format.
MythScreenStack * GetStack(const QString &Stackname)
MythScreenStack * m_screenStack
QString GetMenuThemeDir()
Dialog prompting the user to enter a text string.
virtual void aboutToShow(void)
MythUIHelper * GetMythUI()
MythPluginManager * GetPluginManager(void)
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
MythConfirmationDialog * ShowOkPopup(const QString &message, bool showCancel)
Non-blocking version of MythPopupBox::showOkPopup()
This widget is used for grouping other widgets for display when a particular named state is called....
bool DisplayState(const QString &name)