/* actions.cpp - Actions Copyright (C) 2005 Konrad Twardowski 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 #include #include #include #include #include #include #include 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 TDEApplication::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( TDEApplication::ShutdownConfirmNo, type, TDEApplication::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(TDEApplication::ShutdownTypeHalt, action); break; // reboot case Reboot: _totalExit = true; MiscUtils::closeCDTray(); getMethod(action, method, command); MiscUtils::runCommandBeforeAction("Reboot"); if (method == Method_KDE) return endSession(TDEApplication::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(TDEApplication::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 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; } TDEConfig *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 { TDEConfig *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(); #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); }