Skip to content

Commit

Permalink
Add a standby mode screen, this is a significantly cutdown version of…
Browse files Browse the repository at this point in the history
… mythwelcome, accessed directly from the frontend so by design doesn't duplicate any information or actions which can be accessed elsewhere in the frontend. Standby mode is currently accessed from the Main Menu context menu and the option to make it the default exit action will follow. When in 'standby mode' the backend will be allowed to shut down and when that happens, optionally the frontend may be shut down as well. You may continue to use mythwelcome as before if this new mode doesn't suit. The initial default theme is very basic, I hope to add some icons to the status statetype before the 0.25 release.
  • Loading branch information
stuartm committed Feb 12, 2012
1 parent 7ebdf77 commit 89a4faa
Show file tree
Hide file tree
Showing 10 changed files with 324 additions and 25 deletions.
2 changes: 1 addition & 1 deletion mythtv/libs/libmythbase/mythversion.h
Expand Up @@ -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.
*
Expand Down
55 changes: 43 additions & 12 deletions mythtv/libs/libmythui/mythmainwindow.cpp
Expand Up @@ -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: ")

Expand Down Expand Up @@ -2573,7 +2573,7 @@ void MythMainWindow::ResetIdleTimer(void)
return;

if (d->standby)
ExitStandby();
ExitStandby(false);

d->idleTimer->start();
}
Expand All @@ -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();
}
Expand Down
7 changes: 3 additions & 4 deletions mythtv/libs/libmythui/mythmainwindow.h
Expand Up @@ -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();
Expand Down Expand Up @@ -165,9 +167,6 @@ class MUI_PUBLIC MythMainWindow : public QWidget
void LockInputDevices(bool locked);

void ShowMouseCursor(bool show);

void EnterStandby();
void ExitStandby();

MythMainWindowPrivate *d;
};
Expand Down
7 changes: 5 additions & 2 deletions mythtv/libs/libmythui/myththemedmenu.cpp
Expand Up @@ -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:
Expand Down Expand Up @@ -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")
Expand Down
8 changes: 4 additions & 4 deletions mythtv/programs/mythfrontend/exitprompt.cpp
Expand Up @@ -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)
Expand Down Expand Up @@ -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.");
}
Expand All @@ -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);


Expand Down
172 changes: 172 additions & 0 deletions mythtv/programs/mythfrontend/idlescreen.cpp
@@ -0,0 +1,172 @@

#include "idlescreen.h"

#include <QTimer>

#include <mythcontext.h>
#include <mythsystem.h>

#include <mythuibuttonlist.h>
#include <mythuistatetype.h>
#include <mythmainwindow.h>

#include <programinfo.h>

#include <tvremoteutil.h>

#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<MythUIStateType*>
(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<MythUIText *>(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<MythEvent *>(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);
}

43 changes: 43 additions & 0 deletions mythtv/programs/mythfrontend/idlescreen.h
@@ -0,0 +1,43 @@
#ifndef _IDLESCREEN_H_
#define _IDLESCREEN_H_

#include <mythscreentype.h>

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

0 comments on commit 89a4faa

Please sign in to comment.