You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kshutdown/kshutdown/actions.cpp

456 lines
9.7 KiB

/*
actions.cpp - Actions
Copyright (C) 2005 Konrad Twardowski <kdtonline@poczta.onet.pl>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "actions.h"
#include "configuration.h"
#include "confirmation.h"
#include "extras.h"
#include "miscutils.h"
#include "mmainwindow.h"
#include "msystemtray.h"
#include "systemconfig.h"
#include <ntqimage.h>
#include <ntqtimer.h>
#include <dcopclient.h>
#include <kdebug.h>
#include <kiconloader.h>
#include <kimageeffect.h>
#include <klocale.h>
#include <kmessagebox.h>
Action *Action::_instance = 0;
Action::~Action()
{
}
TQString Action::actionToConfigGroup(const Type action) const
{
switch (action)
{
case ShutDown: return "Shut Down";
case Reboot: return "Reboot";
case LockScreen: return "Lock Screen";
case Logout: return "Logout";
default: return TQString::null;
}
}
// TODO: 2.0: GDM support
// TODO: 2.0: force application exit (without asking for data save)
bool Action::endSession(const KApplication::ShutdownType type, const Type action)
{
_totalExit = false;
MiscUtils::passiveMessage(i18n("Please wait..."));
// test mode
if (_testMode)
{
MiscUtils::showTestMessage(getName(action));
return true;
}
_totalExit = true;
if (
!kapp->requestShutDown(
KApplication::ShutdownConfirmNo,
type,
KApplication::ShutdownModeForceNow
)
)
{
KMessageBox::error(
0,
i18n(
"Could not logout properly.\n" \
"The session manager cannot be contacted."
)
);
_totalExit = false;
return false; // error
}
return true; // ok
}
bool Action::exec(const Type action, const bool stopTimer)
{
if (stopTimer)
ks_main->cancel();
_totalExit = false;
Method method = Method_KDE;
TQString command;
if (!isEnabled(action))
return false; // error
// kdDebug() << "Action::exec: " << action << endl;
switch (action)
{
// nothing
case Nothing:
return false; // error
// shut down
case ShutDown:
_totalExit = true;
MiscUtils::closeCDTray();
getMethod(action, method, command);
MiscUtils::runCommandBeforeAction("Shut Down");
if (method == Method_KDE)
return endSession(KApplication::ShutdownTypeHalt, action);
break;
// reboot
case Reboot:
_totalExit = true;
MiscUtils::closeCDTray();
getMethod(action, method, command);
MiscUtils::runCommandBeforeAction("Reboot");
if (method == Method_KDE)
return endSession(KApplication::ShutdownTypeReboot, action);
break;
case LockScreen:
return lockScreen();
// logout
case Logout:
_totalExit = true;
MiscUtils::closeCDTray();
getMethod(action, method, command);
MiscUtils::runCommandBeforeAction("Logout");
if (method == Method_KDE)
return endSession(KApplication::ShutdownTypeNone, action);
break;
// "extras" action
case Extras:
// test mode
if (_testMode)
{
MiscUtils::showTestMessage(
ks_extras->getActionDescription() + "\n" +
ks_extras->fileToExecute()
);
return true; // ok
}
return ks_extras->execAction();
}
// test mode
if (_testMode)
{
MiscUtils::showTestMessage(i18n("Command: %1").arg(command));
return true; // ok
}
// run default or user command
// TODO: 2.0: add function to change /sbin/* permissions (e.g. /sbin/poweroff)
// TODO: 2.0: save session before /sbin/* execution
if (MiscUtils::runCommand(command))
{
// hide window
if ((action == LockScreen) && (MSystemTray::mode() == MSystemTray::Always))
ks_main->hide();
return true; // ok
}
_totalExit = false;
return false; // error
}
bool Action::execConfirm(const Type action, const TQString &delay)
{
if (
(action != LockScreen) && // no confirmation for "Lock Session"
!Confirmation::confirm(action, delay.isNull() ? i18n("No Delay") : delay)
)
return false;
return exec(action, action != LockScreen);
}
bool Action::execCurrent()
{
return exec(_current);
}
TQString Action::getCurrentName() const
{
return getName(_current);
}
TQPixmap Action::getIcon(const Type action) const
{
TQMapIterator<Type, TQPixmap> i = iconCache->find(action);
return (i == iconCache->end()) ? SmallIcon("misc") : i.data();
}
TQString Action::getIconName(const Type action) const
{
switch (action)
{
case ShutDown: return "exit";
case Reboot: return "reload";
case LockScreen: return "lock";
case Logout: return "undo";
case Extras: return "bookmark";
case Nothing:
default:
return "misc";
}
}
TQString Action::getMethod(const Action::Type action, Method &method, TQString &command)
{
TQString group = actionToConfigGroup(action);
if (group.isNull())
{
// kdDebug() << "Action::getMethod: No group in config for action " << action << endl;
return TQString::null;
}
TQString defaultCommand;
switch (action)
{
case ShutDown:
defaultCommand = DEFAULT_SHUT_DOWN_COMMAND;
break;
case Reboot:
defaultCommand = DEFAULT_REBOOT_COMMAND;
break;
case LockScreen:
defaultCommand = DEFAULT_LOCK_SCREEN_COMMAND;
break;
case Logout:
defaultCommand = DEFAULT_LOGOUT_COMMAND;
break;
default:
defaultCommand = TQString::null;
}
KConfig *conf = kshutdownrc->config();
if (!conf->hasGroup(group))
{
method = Method_KDE;
command = defaultCommand;
// kdDebug() << "Action::getMethod: No group in config for action " << action << endl;
return defaultCommand;
}
conf->setGroup(group);
// read method
method = (Method)conf->readNumEntry("Method", Method_KDE);
if ((method < Method_KDE) || (method > Method_UserCommand))
method = Method_KDE;
switch (method)
{
case Method_KDE:
command = conf->readEntry("Command", defaultCommand);
break;
case Method_DefaultCommand:
command = defaultCommand;
break;
case Method_UserCommand:
command = conf->readEntry("Command", defaultCommand);
if (command.isEmpty())
method = Method_KDE;
break;
}
return defaultCommand;
}
void Action::setMethod(const TQString &group, const Method method, const TQString &command) const
{
KConfig *conf = kshutdownrc->config();
conf->setGroup(group);
if (method == Method_UserCommand)
conf->writeEntry("Command", command);
conf->writeEntry("Method", method);
}
TQString Action::getName(const Type action) const
{
switch (action)
{
case Nothing: return i18n("Nothing");
case ShutDown: return i18n("Turn Off Computer");
case Reboot: return i18n("Restart Computer");
case LockScreen: return i18n("Lock Session");
case Logout: return i18n("End Current Session");
case Extras: return ks_extras->getActionDescription();
}
return i18n("Unknown");
}
bool Action::isEnabled(const Type action)
{
Method m = Method_KDE;
TQString c = TQString::null;
switch (action)
{
case Nothing:
return false;
case ShutDown:
getMethod(action, m, c);
return
!MiscUtils::isRestricted("action_shutdown") &&
!((m == Method_KDE) && !SystemConfig::canShutDown());
case Reboot:
getMethod(action, m, c);
return
!MiscUtils::isRestricted("action_reboot") &&
!((m == Method_KDE) && !SystemConfig::canShutDown());
case LockScreen:
return !MiscUtils::isRestricted("action_lockscreen");
case Logout:
return !MiscUtils::isRestricted("action_logout");
case Extras:
return !MiscUtils::isRestricted("action_extras");
}
return false;
}
void Action::totalExec()
{
if (!execCurrent())
KMessageBox::sorry(0, i18n("Action failed! (%1)").arg(_current));
}
Action::Action()
: TQObject(ks_main),
_active(false),
_testMode(false),
_totalExit(false),
_current(Nothing)
{
// NOTE: compatible with the standard KDE logout dialog
// NOTE: sync. with panel applet
iconCache = new TQMap<Type, TQPixmap>();
#define KS_ADD_ICON(action) \
iconCache->insert(action, SmallIcon(getIconName(action)));
KS_ADD_ICON(Nothing);
KS_ADD_ICON(ShutDown);
KS_ADD_ICON(Reboot);
KS_ADD_ICON(LockScreen);
KS_ADD_ICON(Logout);
KS_ADD_ICON(Extras);
}
bool Action::lockScreen() {
Method method;
TQString command;
getMethod(LockScreen, method, command);
MiscUtils::runCommandBeforeAction("Lock Screen");
if (method == Method_KDE) {
// test mode
if (_testMode) {
MiscUtils::showTestMessage(getName(LockScreen));
return true; // ok
}
// this is a modified "void Lockout::lock()"
// from the "Lock/Logout Applet" (lockout.cpp [3.1.4])
TQCString kdesktop("kdesktop");
int kshutdown_screen_number = tqt_xscreen();
if (kshutdown_screen_number)
kdesktop.sprintf("kdesktop-screen-%d", kshutdown_screen_number);
if (!kapp->dcopClient()->send(kdesktop, "KScreensaverIface", "lock()", "")) {
KMessageBox::error(0, i18n("kdesktop: DCOP call failed!"));
return false; // error
}
// hide window
if (MSystemTray::mode() == MSystemTray::Always)
ks_main->hide();
return true; // ok
}
else {
if (_testMode) {
MiscUtils::showTestMessage(i18n("Command: %1").arg(command));
return true; // ok
}
else if (MiscUtils::runCommand(command)) {
// hide window
if (MSystemTray::mode() == MSystemTray::Always)
ks_main->hide();
return true; // ok
}
}
return false; // error
}
// public slots
void Action::slotLockScreen()
{
execConfirm(LockScreen);
}
void Action::slotLogout()
{
execConfirm(Logout);
}
void Action::slotReboot()
{
execConfirm(Reboot);
}
void Action::slotShutDown()
{
execConfirm(ShutDown);
}