diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | 4aed2c8219774f5d797760606b8489a92ddc5163 (patch) | |
tree | 3f8c130f7d269626bf6a9447407ef6c35954426a /kdesktop/minicli.cpp | |
download | tdebase-4aed2c8219774f5d797760606b8489a92ddc5163.tar.gz tdebase-4aed2c8219774f5d797760606b8489a92ddc5163.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdebase@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kdesktop/minicli.cpp')
-rw-r--r-- | kdesktop/minicli.cpp | 886 |
1 files changed, 886 insertions, 0 deletions
diff --git a/kdesktop/minicli.cpp b/kdesktop/minicli.cpp new file mode 100644 index 000000000..096b293d0 --- /dev/null +++ b/kdesktop/minicli.cpp @@ -0,0 +1,886 @@ +/* This file is part of the KDE project + + Copyright (C) 1999-2002,2003 Dawit Alemayehu <adawit@kde.org> + Copyright (C) 2000 Malte Starostik <starosti@zedat.fu-berlin.de> + Copyright (C) 2003 Sven Leiber <s.leiber@web.de> + + Kdesu integration: + Copyright (C) 2000 Geert Jansen <jansen@kde.org> + + Original authors: + Copyright (C) 1997 Matthias Ettrich <ettrich@kde.org> + Copyright (C) 1997 Torben Weis [ Added command completion ] + Copyright (C) 1999 Preston Brown <pbrown@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <pwd.h> +#include <string.h> +#include <errno.h> + +#include <qvbox.h> +#include <qlabel.h> +#include <qbitmap.h> +#include <qfile.h> +#include <qslider.h> +#include <qlayout.h> +#include <qgroupbox.h> +#include <qcheckbox.h> +#include <qregexp.h> +#include <qwhatsthis.h> +#include <qstylesheet.h> + +#include <dcopclient.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kprocess.h> +#include <kcombobox.h> +#include <klineedit.h> +#include <kapplication.h> +#include <kdebug.h> +#include <kpassdlg.h> +#include <krun.h> +#include <kwin.h> +#include <kdesu/su.h> +#include <kstandarddirs.h> +#include <kconfig.h> +#include <kiconloader.h> +#include <kpushbutton.h> +#include <kguiitem.h> +#include <kstdguiitem.h> +#include <kmimetype.h> +#include <kurifilter.h> +#include <kcompletionbox.h> + +#include "minicli.moc" +#include "minicli_ui.h" +#include "kdesktopsettings.h" + +#define KDESU_ERR strerror(errno) + +Minicli::Minicli( QWidget *parent, const char *name) + :KDialog( parent, name, false, WType_TopLevel ), + m_autoCheckedRunInTerm(false) +{ + setPlainCaption( i18n("Run Command") ); + KWin::setIcons( winId(), DesktopIcon("run"), SmallIcon("run") ); + + QVBoxLayout* mainLayout = new QVBoxLayout( this, 0, KDialog::spacingHint() ); + m_dlg = new MinicliDlgUI (this); + mainLayout->addWidget(m_dlg); + + m_dlg->lbRunIcon->setPixmap(DesktopIcon("kmenu")); + m_dlg->lbComment->setAlignment( Qt::WordBreak ); + + m_dlg->cbCommand->setDuplicatesEnabled( false ); + m_dlg->cbCommand->setTrapReturnKey( true ); + + // Options button... + m_dlg->pbOptions->setGuiItem (KGuiItem( i18n("&Options >>"), "configure" )); + + // Run button... + m_dlg->pbRun->setGuiItem (KGuiItem( i18n("&Run"), "run" )); + + // Cancel button... + m_dlg->pbCancel->setGuiItem ( KStdGuiItem::cancel() ); + + if (!kapp->authorize("shell_access")) + m_dlg->pbOptions->hide(); + + m_dlg->pbRun->setEnabled(!m_dlg->cbCommand->currentText().isEmpty()); + m_dlg->pbRun->setDefault( true ); + + // Do not show the advanced group box on startup... + m_dlg->gbAdvanced->hide(); + + // URI Filter meta object... + m_filterData = new KURIFilterData(); + + // Create a timer object... + m_parseTimer = new QTimer(this); + + m_FocusWidget = 0; + + m_prevCached = false; + m_iPriority = 50; + m_iScheduler = StubProcess::SchedNormal; + + m_dlg->leUsername->setText("root"); + + // Main widget buttons... + connect( m_dlg->pbRun, SIGNAL(clicked()), this, SLOT(accept()) ); + connect( m_dlg->pbCancel, SIGNAL(clicked()), this, SLOT(reject()) ); + connect( m_dlg->pbOptions, SIGNAL(clicked()), SLOT(slotAdvanced()) ); + connect( m_parseTimer, SIGNAL(timeout()), SLOT(slotParseTimer()) ); + + connect( m_dlg->cbCommand, SIGNAL( textChanged( const QString& ) ), + SLOT( slotCmdChanged(const QString&) ) ); + + connect( m_dlg->cbCommand, SIGNAL( returnPressed() ), + m_dlg->pbRun, SLOT( animateClick() ) ); + + // Advanced group box... + connect(m_dlg->cbPriority, SIGNAL(toggled(bool)), SLOT(slotChangeScheduler(bool))); + connect(m_dlg->slPriority, SIGNAL(valueChanged(int)), SLOT(slotPriority(int))); + connect(m_dlg->cbRealtime, SIGNAL(toggled(bool)), SLOT(slotRealtime(bool))); + connect(m_dlg->cbRunAsOther, SIGNAL(toggled(bool)), SLOT(slotChangeUid(bool))); + connect(m_dlg->leUsername, SIGNAL(lostFocus()), SLOT(updateAuthLabel())); + connect(m_dlg->cbRunInTerminal, SIGNAL(toggled(bool)), SLOT(slotTerminal(bool))); + + m_dlg->slPriority->setValue(50); + + loadConfig(); +} + +Minicli::~Minicli() +{ + delete m_filterData; +} + +void Minicli::setCommand(const QString& command) +{ + m_dlg->cbCommand->lineEdit()->setText(command); + m_dlg->cbCommand->lineEdit()->deselect(); + int firstSpace = command.find(' '); + if (firstSpace > 0) { + m_dlg->cbCommand->lineEdit()->setSelection(firstSpace+1, command.length()); + } +} + +QSize Minicli::sizeHint() const +{ + int maxWidth = qApp->desktop()->screenGeometry((QWidget*)this).width(); + if (maxWidth < 603) + { + // a sensible max for smaller screens + maxWidth = (maxWidth > 240) ? 240 : maxWidth; + } + else + { + maxWidth = maxWidth * 2 / 5; + } + + return QSize(maxWidth, -1); +} + +void Minicli::show() +{ + KWin::setState( winId(), NET::StaysOnTop ); + KDialog::show(); +} + +void Minicli::loadConfig() +{ + QStringList histList = KDesktopSettings::history(); + int maxHistory = KDesktopSettings::historyLength(); + m_terminalAppList = KDesktopSettings::terminalApps(); + + if (m_terminalAppList.isEmpty()) + m_terminalAppList << "ls"; // Default + + bool block = m_dlg->cbCommand->signalsBlocked(); + m_dlg->cbCommand->blockSignals( true ); + m_dlg->cbCommand->setMaxCount( maxHistory ); + m_dlg->cbCommand->setHistoryItems( histList ); + m_dlg->cbCommand->blockSignals( block ); + + QStringList compList = KDesktopSettings::completionItems(); + if( compList.isEmpty() ) + m_dlg->cbCommand->completionObject()->setItems( histList ); + else + m_dlg->cbCommand->completionObject()->setItems( compList ); + + int mode = KDesktopSettings::completionMode(); + m_dlg->cbCommand->setCompletionMode( (KGlobalSettings::Completion) mode ); + + KCompletionBox* box = m_dlg->cbCommand->completionBox(); + if (box) + box->setActivateOnSelect( false ); + + m_finalFilters = KURIFilter::self()->pluginNames(); + m_finalFilters.remove("kuriikwsfilter"); + + m_middleFilters = m_finalFilters; + m_middleFilters.remove("localdomainurifilter"); + + // Provide username completions. Use saner and configurable maximum values. + int maxEntries = KDesktopSettings::maxUsernameCompletions(); + QStringList users; + + struct passwd *pw; + setpwent(); + for (int count=0; ((pw = getpwent()) != 0L) && (count < maxEntries); count++) + users << QString::fromLocal8Bit(pw->pw_name); + endpwent(); + + KCompletion *completion = new KCompletion; + completion->setOrder(KCompletion::Sorted); + completion->insertItems (users); + + m_dlg->leUsername->setCompletionObject(completion, true); + m_dlg->leUsername->setCompletionMode(KGlobalSettings::completionMode()); + m_dlg->leUsername->setAutoDeleteCompletionObject( true ); + +} + +void Minicli::saveConfig() +{ + KDesktopSettings::setHistory( m_dlg->cbCommand->historyItems() ); + KDesktopSettings::setTerminalApps( m_terminalAppList ); + KDesktopSettings::setCompletionItems( m_dlg->cbCommand->completionObject()->items() ); + KDesktopSettings::setCompletionMode( m_dlg->cbCommand->completionMode() ); + KDesktopSettings::writeConfig(); +} + +void Minicli::clearHistory() +{ + m_dlg->cbCommand->clearHistory(); + saveConfig(); +} + +void Minicli::accept() +{ + QString cmd = m_dlg->cbCommand->currentText().stripWhiteSpace(); + if (!cmd.isEmpty() && (cmd[0].isNumber() || (cmd[0] == '(')) && + (QRegExp("[a-zA-Z\\]\\[]").search(cmd) == -1)) + { + QString result = calculate(cmd); + if (!result.isEmpty()) + m_dlg->cbCommand->setCurrentText(result); + return; + } + + bool logout = (cmd == "logout"); + if( !logout && runCommand() == 1 ) + return; + + m_dlg->cbCommand->addToHistory( m_dlg->cbCommand->currentText().stripWhiteSpace() ); + reset(); + saveConfig(); + QDialog::accept(); + + if ( logout ) + { + kapp->propagateSessionManager(); + kapp->requestShutDown(); + } +} + +void Minicli::reject() +{ + reset(); + QDialog::reject(); +} + +void Minicli::reset() +{ + if( m_dlg->gbAdvanced->isShown() ) + slotAdvanced(); + + bool block = m_dlg->cbCommand->signalsBlocked(); + m_dlg->cbCommand->blockSignals( true ); + m_dlg->cbCommand->clearEdit(); + m_dlg->cbCommand->setFocus(); + m_dlg->cbCommand->reset(); + m_dlg->cbCommand->blockSignals( block ); + m_dlg->pbRun->setEnabled( false ); + + m_iPriority = 50; + m_iScheduler = StubProcess::SchedNormal; + + m_dlg->cbRunInTerminal->setChecked(false); + m_dlg->cbRunAsOther->setChecked(false); + + m_dlg->leUsername->setText("root"); + + m_dlg->cbPriority->setChecked(false); + + m_dlg->slPriority->setValue(m_iPriority); + + m_dlg->cbRealtime->setChecked( m_iScheduler == StubProcess::SchedRealtime ); + m_dlg->lePassword->erase(); + + m_FocusWidget = 0; + m_iconName = QString::null; + m_prevIconName = QString::null; + + m_prevCached = false; + updateAuthLabel(); + setIcon(); +} + +void Minicli::keyPressEvent( QKeyEvent* e ) +{ + if ( e->key() == Qt::Key_Escape ) + { + e->accept(); + m_dlg->pbCancel->animateClick(); + return; + } + + QDialog::keyPressEvent( e ); +} + +QString Minicli::terminalCommand (const QString& cmd, const QString& args) +{ + QString terminal = KDesktopSettings::terminalApplication().stripWhiteSpace(); + if (terminal.endsWith("konsole")) + terminal += " --noclose"; + + if( args.isEmpty() ) + terminal += QString(" -e /bin/sh -c \"%1\"").arg(cmd); + else + terminal += QString(" -e /bin/sh -c \"%1 %2\"").arg(cmd).arg(args); + + if (!m_terminalAppList.contains(cmd)) + m_terminalAppList << cmd; + + return terminal; +} + +int Minicli::runCommand() +{ + m_parseTimer->stop(); + + // Make sure we have an updated data + parseLine( true ); + + // Ignore empty commands... + if ( m_dlg->cbCommand->currentText().isEmpty() ) + return 1; + + QString cmd; + KURL uri = m_filterData->uri(); + if ( uri.isLocalFile() && !uri.hasRef() && uri.query().isEmpty() ) + cmd = uri.path(); + else + cmd = uri.url(); + + // Determine whether the application should be run through + // the command line (terminal) interface... + bool useTerminal = m_dlg->cbRunInTerminal->isChecked(); + + kdDebug (1207) << "Use terminal ? " << useTerminal << endl; + + if (!kapp->authorize("shell_access")) + useTerminal = false; + + if( needsKDEsu() ) + { + QCString user; + struct passwd *pw; + + if (m_dlg->cbRunAsOther) + { + pw = getpwnam(m_dlg->leUsername->text().local8Bit()); + if (pw == 0L) + { + KMessageBox::sorry( this, i18n("<qt>The user <b>%1</b> " + "does not exist on this system.</qt>").arg(m_dlg->leUsername->text())); + return 1; + } + } + else + { + pw = getpwuid(getuid()); + if (pw == 0L) + { + KMessageBox::error( this, i18n("You do not exist.\n")); + return 1; + } + } + + user = pw->pw_name; + + { + // Scoped. we want this object to go away before the fork + // (maybe not necessary, but can't hurt) according to the cvs log, + // creating the SuProcess object in the parent and using it in the + // child creates crashes, but we need to check password before the + // fork in order to not get in trouble with X for the messagebox + + SuProcess proc_checkpwd; + proc_checkpwd.setUser( user ); + + if (m_dlg->cbPriority->isChecked()) + { + proc_checkpwd.setPriority(m_iPriority); + proc_checkpwd.setScheduler(m_iScheduler); + } + + if (proc_checkpwd.checkInstall(m_dlg->lePassword->password()) != 0) + { + KMessageBox::sorry(this, i18n("Incorrect password; please try again.")); + return 1; + } + } + + QApplication::flushX(); + + int pid = fork(); + + if (pid < 0) + { + kdError(1207) << "fork(): " << KDESU_ERR << "\n"; + return -1; + } + + if (pid > 0) + return 0; + + // From here on, this is child... + + SuProcess proc; + proc.setUser(user); + + if (m_dlg->cbPriority->isChecked()) + { + proc.setPriority(m_iPriority); + proc.setScheduler(m_iScheduler); + } + + QCString command; + + if (useTerminal) + command = terminalCommand( cmd, m_filterData->argsAndOptions() ).local8Bit(); + else + { + command = cmd.local8Bit(); + if( m_filterData->hasArgsAndOptions() ) + command += m_filterData->argsAndOptions().local8Bit(); + } + + proc.setCommand(command); + + // Block SIGCHLD because SuProcess::exec() uses waitpid() + sigset_t sset; + sigemptyset(&sset); + sigaddset(&sset, SIGCHLD); + sigprocmask(SIG_BLOCK, &sset, 0L); + proc.setTerminal(true); + proc.setErase(true); + _exit(proc.exec(m_dlg->lePassword->password())); + return 0; + } + else + { + QString exec; + + // yes, this is a hack, but there is no way of doing it + // through SuProcess without providing the user password + if (m_iPriority < 50) + { + // from kdesu_stub.c + int val = 20 - (int) (((double) m_iPriority) * 40 / 100 + 0.5); + cmd = "nice -n " + QString::number( val ) + " " + cmd; + } + + if (useTerminal) + { + cmd = terminalCommand( cmd, m_filterData->argsAndOptions() ); + kdDebug(1207) << "Terminal command: " << cmd << endl; + } + else + { + switch( m_filterData->uriType() ) + { + case KURIFilterData::LOCAL_FILE: + case KURIFilterData::LOCAL_DIR: + case KURIFilterData::NET_PROTOCOL: + case KURIFilterData::HELP: + { + // No need for kfmclient, KRun does it all (David) + (void) new KRun( m_filterData->uri(), parentWidget()); + return 0; + } + case KURIFilterData::EXECUTABLE: + { + if( !m_filterData->hasArgsAndOptions() ) + { + // Look for desktop file + KService::Ptr service = KService::serviceByDesktopName(cmd); + if (service && service->isValid() && service->type() == "Application") + { + notifyServiceStarted(service); + KRun::run(*service, KURL::List()); + return 0; + } + } + } + // fall-through to shell case + case KURIFilterData::SHELL: + { + if (kapp->authorize("shell_access")) + { + exec = cmd; + + if( m_filterData->hasArgsAndOptions() ) + cmd += m_filterData->argsAndOptions(); + + break; + } + else + { + KMessageBox::sorry( this, i18n("<center><b>%1</b></center>\n" + "You do not have permission to execute " + "this command.") + .arg( QStyleSheet::convertFromPlainText(cmd) )); + return 1; + } + } + case KURIFilterData::UNKNOWN: + case KURIFilterData::ERROR: + default: + { + // Look for desktop file + KService::Ptr service = KService::serviceByDesktopName(cmd); + if (service && service->isValid() && service->type() == "Application") + { + notifyServiceStarted(service); + KRun::run(*service, KURL::List(), this); + return 0; + } + + service = KService::serviceByName(cmd); + if (service && service->isValid() && service->type() == "Application") + { + notifyServiceStarted(service); + KRun::run(*service, KURL::List(), this); + return 0; + } + + KMessageBox::sorry( this, i18n("<center><b>%1</b></center>\n" + "Could not run the specified command.") + .arg( QStyleSheet::convertFromPlainText(cmd) )); + return 1; + } + } + } + + if ( KRun::runCommand( cmd, exec, m_iconName ) ) + return 0; + else + { + KMessageBox::sorry( this, i18n("<center><b>%1</b></center>\n" + "The specified command does not exist.").arg(cmd) ); + return 1; // Let the user try again... + } + } +} + +void Minicli::notifyServiceStarted(KService::Ptr service) +{ + // Inform other applications (like the quickstarter applet) + // that an application was started + QByteArray params; + QDataStream stream(params, IO_WriteOnly); + stream << "minicli" << service->storageId(); + kdDebug() << "minicli appLauncher dcop signal: " << service->storageId() << endl; + KApplication::kApplication()->dcopClient()->emitDCOPSignal("appLauncher", + "serviceStartedByStorageId(QString,QString)", params); +} + +void Minicli::slotCmdChanged(const QString& text) +{ + bool isEmpty = text.isEmpty(); + m_dlg->pbRun->setEnabled( !isEmpty ); + + if( isEmpty ) + { + // Reset values to default + m_filterData->setData(KURL()); + + // Empty String is certainly no terminal application + slotTerminal(false); + + // Reset the icon if needed... + const QPixmap pixmap = DesktopIcon("kmenu"); + + if ( pixmap.serialNumber() != m_dlg->lbRunIcon->pixmap()->serialNumber()) + m_dlg->lbRunIcon->setPixmap(pixmap); + + return; + } + + m_parseTimer->start(250, true); +} + +void Minicli::slotAdvanced() +{ + if (m_dlg->gbAdvanced->isHidden()) + { + m_dlg->gbAdvanced->show(); + m_dlg->pbOptions->setText(i18n("&Options <<")); + + // Set the focus back to the widget that had it to begin with, i.e. + // do not put the focus on the "Options" button. + m_FocusWidget = focusWidget(); + + if( m_FocusWidget ) + m_FocusWidget->setFocus(); + } + else + { + m_dlg->gbAdvanced->hide(); + m_dlg->pbOptions->setText(i18n("&Options >>")); + + if( m_FocusWidget && m_FocusWidget->parent() != m_dlg->gbAdvanced ) + m_FocusWidget->setFocus(); + } + adjustSize(); +} + +void Minicli::slotParseTimer() +{ + //kdDebug (1207) << "Minicli::slotParseTimer: Timed out..." << endl; + parseLine( false ); +} + +void Minicli::parseLine( bool final ) +{ + QString cmd = m_dlg->cbCommand->currentText().stripWhiteSpace(); + m_filterData->setData( cmd ); + + if( final ) + KURIFilter::self()->filterURI( *(m_filterData), m_finalFilters ); + else + KURIFilter::self()->filterURI( *(m_filterData), m_middleFilters ); + + bool isTerminalApp = ((m_filterData->uriType() == KURIFilterData::EXECUTABLE) && + m_terminalAppList.contains(m_filterData->uri().url())); + + if( !isTerminalApp ) + { + m_iconName = m_filterData->iconName(); + setIcon(); + } + + if ( isTerminalApp && final && !m_dlg->cbRunInTerminal->isChecked() ) + { + m_terminalAppList.remove( m_filterData->uri().url() ); + isTerminalApp = false; + } + else + { + bool wasAutoChecked = m_autoCheckedRunInTerm; + bool willBeAutoChecked = isTerminalApp && !m_dlg->cbRunInTerminal->isChecked(); + slotTerminal(isTerminalApp || (m_dlg->cbRunInTerminal->isChecked() && !m_autoCheckedRunInTerm)); + if (!wasAutoChecked && willBeAutoChecked) + m_autoCheckedRunInTerm = true; + } + + kdDebug (1207) << "Command: " << m_filterData->uri().url() << endl; + kdDebug (1207) << "Arguments: " << m_filterData->argsAndOptions() << endl; +} + +void Minicli::setIcon () +{ + if( m_iconName.isEmpty() || m_iconName == "unknown" || m_iconName == "kde" ) + m_iconName = QString::fromLatin1("kmenu"); + + QPixmap icon = DesktopIcon( m_iconName ); + + if ( m_iconName == "www" ) + { + // Not using KIconEffect::overlay as that requires the same size + // for the icon and the overlay, also the overlay definately doesn't + // have a more that one-bit alpha channel here + QPixmap overlay( locate ( "icon", KMimeType::favIconForURL( m_filterData->uri() ) + ".png" ) ); + if ( !overlay.isNull() ) + { + int x = icon.width() - overlay.width(); + int y = icon.height() - overlay.height(); + if ( icon.mask() ) + { + QBitmap mask = *icon.mask(); + bitBlt( &mask, x, y, + overlay.mask() ? const_cast<QBitmap *>(overlay.mask()) : &overlay, + 0, 0, overlay.width(), overlay.height(), + overlay.mask() ? OrROP : SetROP ); + icon.setMask(mask); + } + bitBlt( &icon, x, y, &overlay ); + } + } + + m_dlg->lbRunIcon->setPixmap( icon ); +} + +void Minicli::updateAuthLabel() +{ + if (m_dlg->cbPriority->isChecked() && (m_iPriority > 50) || + (m_iScheduler != StubProcess::SchedNormal)) + { + if (!m_prevCached && !m_dlg->leUsername->text().isEmpty()) + { + //kdDebug(1207) << k_funcinfo << "Caching: user=" << m_dlg->leUsername->text() << + // ", checked=" << m_dlg->cbRunAsOther->isChecked() << endl; + + m_prevUser = m_dlg->leUsername->text(); + m_prevPass = m_dlg->lePassword->text(); + m_prevChecked = m_dlg->cbRunAsOther->isChecked(); + m_prevCached = true; + } + if (m_dlg->leUsername->text() != QString::fromLatin1("root")) + m_dlg->lePassword->setText(QString::null); + m_dlg->leUsername->setText(QString::fromLatin1("root")); + m_dlg->cbRunAsOther->setChecked(true); + m_dlg->cbRunAsOther->setEnabled(false); + m_dlg->leUsername->setEnabled(false); + m_dlg->lbUsername->setEnabled(true); + m_dlg->lePassword->setEnabled(true); + m_dlg->lbPassword->setEnabled(true); + } + else if (m_dlg->cbRunAsOther->isEnabled() && + m_dlg->cbRunAsOther->isChecked() && !m_dlg->leUsername->text().isEmpty()) + { + m_dlg->lePassword->setEnabled(true); + m_dlg->lbPassword->setEnabled(true); + } + else + { + if (m_prevCached) + { + m_dlg->leUsername->setText(m_prevUser); + m_dlg->lePassword->setText(m_prevPass); + m_dlg->cbRunAsOther->setChecked(m_prevChecked); + m_dlg->leUsername->setEnabled(m_prevChecked); + m_dlg->lbUsername->setEnabled(m_prevChecked); + } + else + { + m_dlg->cbRunAsOther->setChecked(false); + m_dlg->leUsername->setEnabled(false); + m_dlg->lbUsername->setEnabled(false); + } + m_dlg->cbRunAsOther->setEnabled(true); + m_dlg->lePassword->setEnabled(false); + m_dlg->lbPassword->setEnabled(false); + m_prevCached = false; + } +} + +void Minicli::slotTerminal(bool enable) +{ + m_dlg->cbRunInTerminal->setChecked(enable); + m_autoCheckedRunInTerm = false; + + if (enable) + { + m_prevIconName = m_iconName; + m_iconName = QString::fromLatin1( "konsole" ); + setIcon(); + } + else if (!m_prevIconName.isEmpty()) + { + m_iconName = m_prevIconName; + setIcon(); + } +} + +void Minicli::slotChangeUid(bool enable) +{ + m_dlg->leUsername->setEnabled(enable); + m_dlg->lbUsername->setEnabled(enable); + + if(enable) + { + m_dlg->leUsername->selectAll(); + m_dlg->leUsername->setFocus(); + } + + updateAuthLabel(); +} + +void Minicli::slotChangeScheduler(bool enable) +{ + m_dlg->slPriority->setEnabled(enable); + m_dlg->lbLowPriority->setEnabled(enable); + m_dlg->lbHighPriority->setEnabled(enable); + + updateAuthLabel(); +} + +bool Minicli::needsKDEsu() +{ + return ((m_dlg->cbPriority->isChecked() && ((m_iPriority > 50) || + (m_iScheduler != StubProcess::SchedNormal))) || + (m_dlg->cbRunAsOther->isChecked() && !m_dlg->leUsername->text().isEmpty())); +} + +void Minicli::slotRealtime(bool enabled) +{ + m_iScheduler = enabled ? StubProcess::SchedRealtime : StubProcess::SchedNormal; + + if (enabled) + { + if (KMessageBox::warningContinueCancel(this, + i18n("Running a realtime application can be very dangerous. " + "If the application misbehaves, the system might hang " + "unrecoverably.\nAre you sure you want to continue?"), + i18n("Warning - Run Command"), KGuiItem(i18n("&Run Realtime")),QString::null,KMessageBox::Notify|KMessageBox::PlainCaption) + != KMessageBox::Continue ) + { + m_iScheduler = StubProcess::SchedNormal; + m_dlg->cbRealtime->setChecked(false); + } + } + + updateAuthLabel(); +} + +void Minicli::slotPriority(int priority) +{ + // Provide a way to easily return to the default priority + if ((priority > 40) && (priority < 60)) + { + priority = 50; + m_dlg->slPriority->setValue(50); + } + + m_iPriority = priority; + + updateAuthLabel(); +} + +QString Minicli::calculate(const QString &exp) +{ + QString result, cmd; + const QString bc = KStandardDirs::findExe("bc"); + if ( !bc.isEmpty() ) + cmd = QString("echo %1 | %2").arg(KProcess::quote(QString("scale=8; ")+exp), KProcess::quote(bc)); + else + cmd = QString("echo $((%1))").arg(exp); + FILE *fs = popen(QFile::encodeName(cmd).data(), "r"); + if (fs) + { + { // scope for QTextStream + QTextStream ts(fs, IO_ReadOnly); + result = ts.read().stripWhiteSpace(); + } + pclose(fs); + } + return result; +} + +void Minicli::fontChange( const QFont & ) +{ + adjustSize(); +} + +// vim: set et ts=2 sts=2 sw=2: + |