diff --git a/mythtv/libs/libmythbase/mythversion.h b/mythtv/libs/libmythbase/mythversion.h index 2a5c09ba95f..ec0461569f1 100644 --- a/mythtv/libs/libmythbase/mythversion.h +++ b/mythtv/libs/libmythbase/mythversion.h @@ -12,7 +12,7 @@ /// Update this whenever the plug-in API changes. /// Including changes in the libmythbase, libmyth, libmythtv, libmythav* and /// libmythui class methods used by plug-ins. -#define MYTH_BINARY_VERSION "0.25.20120212-3" +#define MYTH_BINARY_VERSION "0.25.20120212-4" /** \brief Increment this whenever the MythTV network protocol changes. * diff --git a/mythtv/libs/libmythui/mythmainwindow.cpp b/mythtv/libs/libmythui/mythmainwindow.cpp index 313e873c6c4..5653390c0b9 100644 --- a/mythtv/libs/libmythui/mythmainwindow.cpp +++ b/mythtv/libs/libmythui/mythmainwindow.cpp @@ -82,7 +82,7 @@ using namespace std; #endif #define GESTURE_TIMEOUT 1000 -#define STANDBY_TIMEOUT 30 // Minutes +#define STANDBY_TIMEOUT 90 // Minutes #define LOC QString("MythMainWindow: ") @@ -2573,7 +2573,7 @@ void MythMainWindow::ResetIdleTimer(void) return; if (d->standby) - ExitStandby(); + ExitStandby(false); d->idleTimer->start(); } @@ -2585,29 +2585,60 @@ void MythMainWindow::PauseIdleTimer(bool pause) else d->idleTimer->start(); - ResetIdleTimer(); + // ResetIdleTimer(); } void MythMainWindow::IdleTimeout(void) { - EnterStandby(); + if (!d->standby) + { + int idletimeout = gCoreContext->GetNumSetting("FrontendIdleTimeout", + STANDBY_TIMEOUT); + LOG(VB_GENERAL, LOG_NOTICE, QString("Entering standby mode after " + "%1 minutes of inactivity") + .arg(idletimeout)); + + // HACK Prevent faked keypresses interrupting the transition to standby + PauseIdleTimer(true); + // HACK end + + JumpTo("Main Menu"); + + // HACK + PauseIdleTimer(false); + // HACK end + + EnterStandby(false); + } } -void MythMainWindow::EnterStandby() +void MythMainWindow::EnterStandby(bool manual) { - int idletimeout = gCoreContext->GetNumSetting("FrontendIdleTimeout", - STANDBY_TIMEOUT); - LOG(VB_GENERAL, LOG_NOTICE, QString("Entering standby mode after " - "%1 minutes of inactivity") - .arg(idletimeout)); - //JumpTo("Main Menu"); + if (d->standby) + return; + + // We've manually entered standby mode and we want to pause the timer + // to prevent it being Reset + if (manual) + { + PauseIdleTimer(true); + LOG(VB_GENERAL, LOG_NOTICE, QString("Entering standby mode")); + } + d->standby = true; gCoreContext->AllowShutdown(); } -void MythMainWindow::ExitStandby() +void MythMainWindow::ExitStandby(bool manual) { + if (manual) + PauseIdleTimer(false); + + if (!d->standby) + return; + LOG(VB_GENERAL, LOG_NOTICE, "Leaving standby mode"); + d->standby = false; gCoreContext->BlockShutdown(); } diff --git a/mythtv/libs/libmythui/mythmainwindow.h b/mythtv/libs/libmythui/mythmainwindow.h index 94781268da3..1f629b5b759 100644 --- a/mythtv/libs/libmythui/mythmainwindow.h +++ b/mythtv/libs/libmythui/mythmainwindow.h @@ -126,9 +126,11 @@ class MUI_PUBLIC MythMainWindow : public QWidget uint PopDrawDisabled(void); void SetEffectsEnabled(bool enable); void draw(void); - + void ResetIdleTimer(void); void PauseIdleTimer(bool pause); + void EnterStandby(bool manual = true); + void ExitStandby(bool manual = true); public slots: void mouseTimeout(); @@ -165,9 +167,6 @@ class MUI_PUBLIC MythMainWindow : public QWidget void LockInputDevices(bool locked); void ShowMouseCursor(bool show); - - void EnterStandby(); - void ExitStandby(); MythMainWindowPrivate *d; }; diff --git a/mythtv/libs/libmythui/myththemedmenu.cpp b/mythtv/libs/libmythui/myththemedmenu.cpp index f9943f475cf..9cc9bf00024 100644 --- a/mythtv/libs/libmythui/myththemedmenu.cpp +++ b/mythtv/libs/libmythui/myththemedmenu.cpp @@ -298,7 +298,9 @@ void MythThemedMenu::ShowMenu() m_menuPopup->SetReturnEvent(this, "popmenu"); - //m_menuPopup->AddButton(tr("Enter standby mode"), QVariant("standby")); + // HACK Implement a better check for this + if (QCoreApplication::applicationName() == MYTH_APPNAME_MYTHFRONTEND) + m_menuPopup->AddButton(tr("Enter standby mode"), QVariant("standby")); switch (override_menu) { case 2: @@ -381,7 +383,8 @@ void MythThemedMenu::customEvent(QEvent *event) } else if (action == "standby") { - + QString arg("standby_mode"); + m_state->m_callback(m_state->m_callbackdata, arg); } } else if (resultid == "password") diff --git a/mythtv/programs/mythfrontend/exitprompt.cpp b/mythtv/programs/mythfrontend/exitprompt.cpp index c1d2acf7b29..266a8d94e2b 100644 --- a/mythtv/programs/mythfrontend/exitprompt.cpp +++ b/mythtv/programs/mythfrontend/exitprompt.cpp @@ -78,7 +78,7 @@ void ExitPrompter::halt() /* If supported, use DBus to shutdown */ if (ret != GENERIC_EXIT_OK && !DBusHalt()) - myth_system("sudo /sbin/halt -p"); + myth_system("sudo /sbin/halt -p"); } static bool DBusReboot(void) @@ -132,7 +132,7 @@ void ExitPrompter::reboot() { ret = myth_system(reboot_cmd); if (ret != GENERIC_EXIT_OK) - LOG(VB_GENERAL, LOG_ERR, + LOG(VB_GENERAL, LOG_ERR, "User defined RebootCommand failed, falling back to " "alternative methods."); } @@ -144,14 +144,14 @@ void ExitPrompter::reboot() void ExitPrompter::handleExit() { - // IsFrontendOnly() triggers a popup if there is no BE connection. + // HACK IsFrontendOnly() triggers a popup if there is no BE connection. // We really don't need that right now. This hack prevents it. gContext->SetDisableEventPopup(true); // first of all find out, if this is a frontend only host... bool frontendOnly = gCoreContext->IsFrontendOnly(); - // Undo the hack, just in case we _don't_ quit: + // HACK Undo the hack, just in case we _don't_ quit: gContext->SetDisableEventPopup(false); diff --git a/mythtv/programs/mythfrontend/idlescreen.cpp b/mythtv/programs/mythfrontend/idlescreen.cpp new file mode 100644 index 00000000000..c7600ddb63a --- /dev/null +++ b/mythtv/programs/mythfrontend/idlescreen.cpp @@ -0,0 +1,172 @@ + +#include "idlescreen.h" + +#include + +#include +#include + +#include +#include +#include + +#include + +#include + +#define UPDATE_STATUS_INTERVAL 30000 + +IdleScreen::IdleScreen(MythScreenStack *parent) + :MythScreenType(parent, "standbymode"), + m_updateStatusTimer(new QTimer(this)), m_statusState(NULL), + m_secondsToShutdown(0), m_backendRecording(false) +{ + gCoreContext->addListener(this); + GetMythMainWindow()->EnterStandby(); + + connect(m_updateStatusTimer, SIGNAL(timeout()), + this, SLOT(UpdateStatus())); + m_updateStatusTimer->start(UPDATE_STATUS_INTERVAL); +} + +IdleScreen::~IdleScreen() +{ + GetMythMainWindow()->ExitStandby(); + gCoreContext->removeListener(this); + + if (m_updateStatusTimer) + m_updateStatusTimer->disconnect(); +} + +bool IdleScreen::Create(void) +{ + bool foundtheme = false; + + // Load the theme for this screen + foundtheme = LoadWindowFromXML("status-ui.xml", "standbymode", this); + + if (!foundtheme) + return false; + + m_statusState = dynamic_cast + (GetChild("backendstatus")); + + if (!m_statusState) + return false; + + return true; +} + +void IdleScreen::Load(void) +{ + MythScreenType::Load(); +} + +void IdleScreen::Init(void) +{ + UpdateScreen(); +} + +bool IdleScreen::CheckConnectionToServer(void) +{ + m_updateStatusTimer->stop(); + + bool bRes = false; + + if (gCoreContext->IsConnectedToMaster()) + bRes = true; + else + { + if (gCoreContext->ConnectToMasterServer(false)) + bRes = true; + } + + if (bRes) + m_updateStatusTimer->start(UPDATE_STATUS_INTERVAL); + else + m_updateStatusTimer->start(5000); + + return bRes; +} + +void IdleScreen::UpdateStatus(void) +{ + QString state = "idle"; + + if (CheckConnectionToServer()) + { + if (m_secondsToShutdown) + state = "shuttingdown"; + else if (RemoteGetRecordingStatus()) + state = "recording"; + } + else + { + state = "offline"; + } + + m_statusState->DisplayState(state); +} + +void IdleScreen::UpdateScreen(void) +{ + + MythUIText *statusText = dynamic_cast(GetChild("status")); + + if (statusText) + { + QString status; + + if (m_secondsToShutdown) + status = tr("MythTV is idle and will shutdown in %n " + "second(s).", "", m_secondsToShutdown); + + if (!status.isEmpty()) + statusText->SetText(status); + else + statusText->Reset(); + } + + UpdateStatus(); +} + +bool IdleScreen::keyPressEvent(QKeyEvent* event) +{ + return MythScreenType::keyPressEvent(event); +} + +void IdleScreen::customEvent(QEvent* event) +{ + + if ((MythEvent::Type)(event->type()) == MythEvent::MythEventMessage) + { + MythEvent *me = static_cast(event); + + if (me->Message().left(18) == "SHUTDOWN_COUNTDOWN") + { + QString secs = me->Message().mid(19); + m_secondsToShutdown = secs.toInt(); + UpdateStatus(); + } + else if (me->Message().left(12) == "SHUTDOWN_NOW") + { + if (gCoreContext->IsFrontendOnly()) + { + // does the user want to shutdown this frontend only machine + // when the BE shuts down? + if (gCoreContext->GetNumSetting("ShutdownWithMasterBE", 0) == 1) + { + LOG(VB_GENERAL, LOG_NOTICE, + "Backend has gone offline, Shutting down frontend"); + QString poweroff_cmd = + gCoreContext->GetSetting("MythShutdownPowerOff", ""); + if (!poweroff_cmd.isEmpty()) + myth_system(poweroff_cmd); + } + } + } + } + + MythUIType::customEvent(event); +} + diff --git a/mythtv/programs/mythfrontend/idlescreen.h b/mythtv/programs/mythfrontend/idlescreen.h new file mode 100644 index 00000000000..d0950e1cb58 --- /dev/null +++ b/mythtv/programs/mythfrontend/idlescreen.h @@ -0,0 +1,43 @@ +#ifndef _IDLESCREEN_H_ +#define _IDLESCREEN_H_ + +#include + +class MythUIStateType; +class MythUIButtonList; +class QTimer; + +class IdleScreen : public MythScreenType +{ + Q_OBJECT + + public: + IdleScreen(MythScreenStack *parent); + virtual ~IdleScreen(); + + bool Create(void); + bool keyPressEvent(QKeyEvent *event); + void customEvent(QEvent *e); + + + public slots: + void UpdateStatus(void); + void UpdateScreen(void); + + protected: + void Load(void); + void Init(void); + + private: + bool CheckConnectionToServer(void); + + QTimer *m_updateStatusTimer; + + MythUIButtonList *m_upcomingList; + MythUIStateType *m_statusState; + + int m_secondsToShutdown; + bool m_backendRecording; +}; + +#endif diff --git a/mythtv/programs/mythfrontend/main.cpp b/mythtv/programs/mythfrontend/main.cpp index 60a1ef27f31..2b7d6e4cbd6 100644 --- a/mythtv/programs/mythfrontend/main.cpp +++ b/mythtv/programs/mythfrontend/main.cpp @@ -56,6 +56,7 @@ using namespace std; #include "dbcheck.h" #include "mythmediamonitor.h" #include "statusbox.h" +#include "idlescreen.h" #include "lcddevice.h" #include "langsettings.h" #include "mythtranslation.h" @@ -93,6 +94,7 @@ using namespace std; #include #include "bonjourregister.h" #include "mythairplayserver.h" +#include #endif static ExitPrompter *exitPopup = NULL; @@ -588,6 +590,19 @@ static void showStatus(void) delete statusbox; } + +static void standbyScreen(void) +{ + MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack(); + + IdleScreen *idlescreen = new IdleScreen(mainStack); + + if (idlescreen->Create()) + mainStack->AddScreen(idlescreen); + else + delete idlescreen; +} + static void RunVideoScreen(VideoDialog::DialogType type, bool fromJump = false) { QString message = QObject::tr("Loading videos ..."); @@ -1018,6 +1033,8 @@ static void TVMenuCallback(void *data, QString &selection) handleExit(true); else if (sel == "exiting_app") handleExit(false); + else if (sel == "standby_mode") + standbyScreen(); else LOG(VB_GENERAL, LOG_ERR, "Unknown menu action: " + selection); diff --git a/mythtv/programs/mythfrontend/mythfrontend.pro b/mythtv/programs/mythfrontend/mythfrontend.pro index 75a2095e2cc..d7f2ec9db7c 100644 --- a/mythtv/programs/mythfrontend/mythfrontend.pro +++ b/mythtv/programs/mythfrontend/mythfrontend.pro @@ -39,7 +39,7 @@ HEADERS += videoplayercommand.h videopopups.h HEADERS += videofilter.h videolist.h HEADERS += videoplayersettings.h videodlg.h HEADERS += videoglobalsettings.h upnpscanner.h -HEADERS += commandlineparser.h +HEADERS += commandlineparser.h idlescreen.h SOURCES += main.cpp playbackbox.cpp viewscheduled.cpp audiogeneralsettings.cpp SOURCES += globalsettings.cpp manualschedule.cpp programrecpriority.cpp @@ -60,7 +60,7 @@ SOURCES += videoplayercommand.cpp videopopups.cpp SOURCES += videofilter.cpp videolist.cpp SOURCES += videoplayersettings.cpp videodlg.cpp SOURCES += videoglobalsettings.cpp upnpscanner.cpp -SOURCES += commandlineparser.cpp +SOURCES += commandlineparser.cpp idlescreen.cpp HEADERS += serviceHosts/frontendServiceHost.h HEADERS += services/frontend.h diff --git a/mythtv/themes/default/status-ui.xml b/mythtv/themes/default/status-ui.xml index f2072af60d4..f52935b9c5c 100644 --- a/mythtv/themes/default/status-ui.xml +++ b/mythtv/themes/default/status-ui.xml @@ -93,5 +93,39 @@ + + + + + 100,270,600,40 + + + + + + + + + + + + + + +