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 | 37333bf25ad9a4c538250f5af2f9f1d666362883 (patch) | |
tree | c45e8df5b9efbffe07eb3d9340df7811c7e16943 /ksysv/OldView.cpp | |
download | tdeadmin-37333bf25ad9a4c538250f5af2f9f1d666362883.tar.gz tdeadmin-37333bf25ad9a4c538250f5af2f9f1d666362883.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/kdeadmin@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'ksysv/OldView.cpp')
-rw-r--r-- | ksysv/OldView.cpp | 1150 |
1 files changed, 1150 insertions, 0 deletions
diff --git a/ksysv/OldView.cpp b/ksysv/OldView.cpp new file mode 100644 index 0000000..6e9f7d3 --- /dev/null +++ b/ksysv/OldView.cpp @@ -0,0 +1,1150 @@ +/*************************************************************************** + begin : Sun Oct 3 1999 + copyright : (C) 1997-2000 by Peter Putzer + email : putzer@kde.org + ***************************************************************************/ + +/*************************************************************************** + * * + * 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; version 2. * + * * + ***************************************************************************/ + +/***************************************** + ** ** + ** Main Widget ** + ** ** + *****************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <qprogressdialog.h> +#include <qkeycode.h> +#include <qmessagebox.h> +#include <qgroupbox.h> +#include <qaccel.h> +#include <qscrollbar.h> +#include <qtextedit.h> +#include <qcstring.h> +#include <qclipboard.h> +#include <qheader.h> +#include <qlabel.h> +#include <qstylesheet.h> +#include <qwhatsthis.h> +#include <qlayout.h> +#include <qvbox.h> +#include <qvaluelist.h> +#include <qsplitter.h> +#include <qmap.h> + +#include <kapplication.h> +#include <kdebug.h> +#include <kiconloader.h> +#include <kprocess.h> +#include <kstandarddirs.h> +#include <kcursor.h> +#include <kpopupmenu.h> +#include <kmessagebox.h> +#include <klocale.h> +#include <kglobalsettings.h> +#include <kaboutdata.h> +#include <kdialog.h> +#include <kdirwatch.h> +#include <kcompletion.h> +#include <krun.h> +#include <kopenwith.h> +#include <kmimemagic.h> + +#include "kbusymanager.h" +#include "Properties.h" +#include "kscroller.h" +#include "IOCore.h" +#include "ksvdraglist.h" +#include "ksvdrag.h" +#include "trash.h" +#include "ksv_core.h" +#include "ksv_conf.h" +#include "OldView.h" +#include "ActionList.h" +#include "TopWidget.h" + +KSVContent::KSVContent (KPopupMenu* openWithMenu, KSVTopLevel* parent, const char* name) + : QSplitter (QSplitter::Vertical, parent, name), + startRL (new KSVDragList*[ksv::runlevelNumber]), + stopRL (new KSVDragList*[ksv::runlevelNumber]), + conf(KSVConfig::self()), + mScriptBox (0L), + mRunlevels (new QVBox*[ksv::runlevelNumber]), + mOrigin (0L), + mOpenWithMenu (openWithMenu), m_buffer( QCString() ) +{ + setOpaqueResize( KGlobalSettings::opaqueResize() ); + + KXMLGUIFactory* factory = parent->factory(); + mItemMenu = static_cast<KPopupMenu*> (factory->container ("item_menu", parent)); + mItemMenu->insertTitle (i18n ("Runlevel Menu"), -1, 0); + mContextMenu = static_cast<KPopupMenu*> (factory->container ("list_menu", parent)); + mContextMenu->insertTitle (i18n ("Runlevel Menu"), -1, 0); + mScriptMenu = static_cast<KPopupMenu*> (factory->container ("script_menu", parent)); + mScriptMenu->insertTitle (i18n ("Services Menu"), -1, 0); + + mScroller = new KScroller (this); + mContent = new QFrame(mScroller, "KSysV Real Content"); + + mScroller->setContent (mContent); + + initLList(); + + // watch services dir + KDirWatch* dirwatch = KDirWatch::self(); + dirwatch->addDir (conf->scriptPath ()); + connect (dirwatch, SIGNAL (dirty (const QString&)), + this, SLOT (updateServicesAfterChange (const QString&))); + connect (dirwatch, SIGNAL (created (const QString&)), + this, SLOT (updateServicesAfterChange (const QString&))); + connect (dirwatch, SIGNAL (deleted (const QString&)), + this, SLOT (updateServicesAfterChange (const QString&))); + + setSizes(KSVContent::panningFactorToSplitter (conf->panningFactor())); + + // someone must have focus + scripts->setFocus(); + + // show/hide everything + for (int i = 0; i < ksv::runlevelNumber; ++i) + { + if (conf->showRunlevel (i)) + mRunlevels[i]->show(); + else + mRunlevels[i]->hide(); + } + + textDisplay->setStyleSheet (ksv::styleSheet()); + + // Open With... menu + connect (mOpenWithMenu, SIGNAL (activated (int)), this, SLOT (openWith (int))); + + calcMinSize(); +} + +KSVContent::~KSVContent() +{ + delete[] mRunlevels; + + delete[] startRL; + delete[] stopRL; + delete scripts; + delete trash; + delete textDisplay ; + +} + +void KSVContent::updateServicesAfterChange (const QString& dir) +{ + if (!dir.startsWith(conf->scriptPath())) + return; + + // const bool enabled = scripts->isEnabled (); + initScripts(); +} + +void KSVContent::updateRunlevelsAfterChange () +{ + // MUTEX + KBusyManager::self()->setBusy (true); + + // int i = 0; + for (int i = 0; i < ksv::runlevelNumber; ++i) { + startRL[i]->setEnabled(false); + startRL[i]->clear(); + + stopRL[i]->setEnabled(false); + stopRL[i]->clear(); + } + + initRunlevels(); + + for (int i = 0; i < ksv::runlevelNumber; ++i) + { + startRL[i]->setEnabled(true); + stopRL[i]->setEnabled(true); + } + + // refresh GUI + qApp->processEvents(); + + scripts->setFocus(); + + KBusyManager::self()->restore(); +} + +void KSVContent::initLList() +{ + QHBoxLayout *lay = new QHBoxLayout( mContent, KDialog::marginHint(), KDialog::spacingHint() ); + mScriptBox = new QVBox (mContent); + lay->addWidget(mScriptBox); + mScriptBox->setSpacing (KDialog::spacingHint()); + + QVBox* scriptLabelBox = new QVBox (mScriptBox); + QLabel* servL = new QLabel (i18n("&Available\n" \ + "Services"), scriptLabelBox); + + // provide quickhelp + QWhatsThis::add (scriptLabelBox, + i18n("<p>These are the <img src=\"small|exec\"/> <strong>services</strong> available on your computer. " \ + "To start a service, drag it onto the <em>Start</em> " \ + "section of a runlevel.</p>" \ + "<p>To stop one, do the same for the <em>Stop</em> section.</p>")); + + + QFont bold_font = QFont(KGlobalSettings::generalFont()); + bold_font.setBold(TRUE); + servL->setFont(bold_font); + + scripts = new KServiceDragList (scriptLabelBox, "Scripts"); + scripts->setAcceptDrops (false); + scripts->setColumnWidthMode (KSVItem::SortNumber, QListView::Manual); + scripts->setColumnWidth(KSVItem::SortNumber,0); + scripts->setSorting (KSVItem::ServiceName); + scripts->header()->setResizeEnabled (false, 0); + + scripts->setDefaultIcon (SmallIcon("exec")); + mOrigin = scripts; + + // setBuddy + servL->setBuddy(scripts); + + // doubleclick && return + connect (scripts, SIGNAL(executed(QListViewItem*)), + this, SLOT(slotScriptProperties(QListViewItem*))); + connect (scripts, SIGNAL (returnPressed (QListViewItem*)), + this, SLOT (slotScriptProperties (QListViewItem*))); + + // context menus + connect (scripts, SIGNAL (contextMenu (KListView*, QListViewItem*, const QPoint&)), + this, SLOT (popupServicesMenu (KListView*, QListViewItem*, const QPoint&))); + + // for cut & copy + connect (scripts, SIGNAL (newOrigin ()), + this, SLOT (fwdOrigin ())); + + // for origin updates + connect (scripts, SIGNAL (newOrigin (KSVDragList*)), + this, SLOT (fwdOrigin (KSVDragList*))); + + trash = new KSVTrash(mScriptBox, "Trash"); + connect (trash, SIGNAL (undoAction (KSVAction*)), this, SLOT (fwdUndoAction (KSVAction*))); + QWhatsThis::add (trash, + i18n ("<p>You can drag services from a runlevel onto " \ + "the <img src=\"small|trash\"/> <strong>trashcan</strong> to " \ + "delete them from that runlevel.</p><p>The <strong>Undo command</strong> "\ + "can be used to restore deleted entries.</p>")); + + for(int i = 0; i < ksv::runlevelNumber; ++i) + { + mRunlevels[i] = new QVBox (mContent); + lay->addWidget(mRunlevels[i]); + mRunlevels[i]->setSpacing (KDialog::spacingHint()); + + // create QString for label + QString _label (i18n("Runlevel &%1").arg(i)); + // and for the name + QString _name (i18n("Runlevel %1").arg(i)); + + QVBox* startBox = new QVBox (mRunlevels[i]); + QWhatsThis::add (startBox, + i18n("<p>These are the services <strong>started</strong> in runlevel %1.</p>" \ + "<p>The number shown on the left of the <img src=\"user|ksysv_start\"/> icon " \ + "determines the order in which the services are started. " \ + "You can arrange them via drag and drop, as long as a suitable " \ + "<em>sorting number</em> can be generated.</p><p>If that's not possible, you have " \ + "to change the number manually via the <strong>Properties dialog box</strong>.</p>").arg(i)); + + QLabel* rlL = new QLabel(_label, startBox); + new QLabel(i18n("Start"), startBox); + rlL->setFont(bold_font); + + // create the "START" list: + startRL[i] = new KSVDragList(startBox, (_name + " START").latin1()); + startRL[i]->setDefaultIcon(SmallIcon("ksysv_start")); + + QVBox* stopBox = new QVBox (mRunlevels[i]); + new QLabel(i18n("Stop"), stopBox); + QWhatsThis::add (stopBox, + i18n("<p>These are the services <strong>stopped</strong> in runlevel %1.</p>" \ + "<p>The number shown on the left of the <img src=\"user|ksysv_stop\"/> icon " \ + "determines the order in which the services are stopped. " \ + "You can arrange them via drag and drop, as long as a suitable " \ + "<em>sorting number</em> can be generated.</p><p>If that's not possible, you have " \ + "to change the number manually via the <strong>Properties dialog box</strong>.</p>").arg(i)); + + // create the "STOP" list: + stopRL[i] = new KSVDragList(stopBox, (_name + " STOP").latin1()); + stopRL[i]->setDefaultIcon(SmallIcon("ksysv_stop")); + + // set the buddy widget for the "Runlevel %i" label... => the corresponding runlevel + rlL->setBuddy(startRL[i]); + + // for cut'n'paste + connect (startRL[i], SIGNAL (newOrigin ()), + this, SLOT (fwdOrigin ())); + connect (startRL[i], SIGNAL (newOrigin (KSVDragList*)), + this, SLOT (fwdOrigin (KSVDragList*))); + + connect (stopRL[i], SIGNAL (newOrigin ()), + this, SLOT (fwdOrigin ())); + connect (stopRL[i], SIGNAL (newOrigin (KSVDragList*)), + this, SLOT (fwdOrigin (KSVDragList*))); + } + + lay->addStretch(1); + + connect (scripts, SIGNAL(undoAction(KSVAction*)), + this, SLOT(fwdUndoAction(KSVAction*))); + + // add text-diplay widget + textDisplay = new QTextEdit( QString::null, QString::null, this, "TextDisplayWidget" ); + textDisplay->setTextFormat( Qt::RichText ); + textDisplay->setReadOnly( true ); + + for (int i = 0; i < ksv::runlevelNumber; ++i) + { + connect (startRL[i], SIGNAL(newOrigin()), stopRL[i], SLOT(slotNewOrigin())); + connect (stopRL[i], SIGNAL(newOrigin()), startRL[i], SLOT(slotNewOrigin())); + + connect (startRL[i], SIGNAL(undoAction(KSVAction*)), + this, SLOT(fwdUndoAction(KSVAction*))); + connect (stopRL[i], SIGNAL(undoAction(KSVAction*)), + this, SLOT(fwdUndoAction(KSVAction*))); + + // doubleclick && return + connect (startRL[i], SIGNAL(executed(QListViewItem*)), + this, SLOT(slotDoubleClick(QListViewItem*))); + connect (stopRL[i], SIGNAL(executed(QListViewItem*)), + this, SLOT(slotDoubleClick(QListViewItem*))); + connect (startRL[i], SIGNAL(returnPressed(QListViewItem*)), + this, SLOT(slotDoubleClick(QListViewItem*))); + connect (stopRL[i], SIGNAL(returnPressed(QListViewItem*)), + this, SLOT(slotDoubleClick(QListViewItem*))); + + // context menus + connect (startRL[i], SIGNAL (contextMenu (KListView*, QListViewItem*, const QPoint&)), + this, SLOT (popupRunlevelMenu (KListView*, QListViewItem*, const QPoint&))); + connect (stopRL[i], SIGNAL (contextMenu (KListView*, QListViewItem*, const QPoint&)), + this, SLOT (popupRunlevelMenu (KListView*, QListViewItem*, const QPoint&))); + + // cannot generate sorting number + connect (startRL[i], SIGNAL(cannotGenerateNumber()), + this, SLOT(fwdCannotGenerateNumber())); + connect (stopRL[i], SIGNAL(cannotGenerateNumber()), + this, SLOT(fwdCannotGenerateNumber())); + + // connecting origin things for "Scripts", too + connect (scripts, SIGNAL(newOrigin()), startRL[i], SLOT(slotNewOrigin())); + connect (scripts, SIGNAL(newOrigin()), stopRL[i], SLOT(slotNewOrigin())); + connect (startRL[i], SIGNAL(newOrigin()), scripts, SLOT(slotNewOrigin())); + connect (stopRL[i], SIGNAL(newOrigin()), scripts, SLOT(slotNewOrigin())); + + // use this loop for setting tooltips + startRL[i]->setToolTip (i18n("Drag here to start services\n" \ + "when entering runlevel %1").arg(i)); + stopRL[i]->setToolTip (i18n("Drag here to stop services\n" \ + "when entering runlevel %1").arg(i)); + + for (int j = 0; j < ksv::runlevelNumber; ++j) + { + if (i != j) + { + connect (startRL[i], SIGNAL (newOrigin()), startRL[j], SLOT (slotNewOrigin())); + connect (stopRL[i], SIGNAL (newOrigin()), stopRL[j], SLOT (slotNewOrigin())); + + connect (startRL[i], SIGNAL(newOrigin()), stopRL[j], SLOT(slotNewOrigin())); + connect (stopRL[i], SIGNAL(newOrigin()), startRL[j], SLOT(slotNewOrigin())); + } + } + } +} + +void KSVContent::fwdUndoAction (KSVAction* a) +{ + emit undoAction(a); +} + +void KSVContent::initScripts() { + QDir scriptDir = QDir(conf->scriptPath()); + if (!scriptDir.exists()) + return; + + scriptDir.setFilter (QDir::Files | QDir::Hidden | + QDir::NoSymLinks | QDir::Executable); + + scriptDir.setSorting (QDir::Name); + + // const QFileInfoList *scriptList = scriptDir.entryInfoList(); + QFileInfoListIterator it (*scriptDir.entryInfoList()); + + KCompletion* comp = ksv::serviceCompletion(); + comp->clear (); + + // clear the listview + scripts->setEnabled(false); + scripts->clear(); + + QFileInfo* fi; QString name; + while ((fi = it.current())) + { + name = fi->fileName(); + scripts->initItem(name, + ksv::IO::relToAbs(conf->scriptPath(), fi->dirPath(FALSE)), + name, 0); + + comp->addItem (name); + + ++it; + + // keep GUI alive + qApp->processEvents(); + } + + scripts->setEnabled(true); + scripts->setToolTip (i18n("The services available on your computer")); +} + +void KSVContent::initRunlevels() +{ + for (int i = 0; i < ksv::runlevelNumber; ++i) + { + // clear the listviews + startRL[i]->clear(); + stopRL[i]->clear(); + + const QString _path = conf->runlevelPath() + QString("/rc%1.d").arg(i); + + if (!QDir(_path).exists()) + continue; + + QDir d = QDir(_path); + d.setFilter( QDir::Files ); + d.setSorting( QDir::Name ); + + const QFileInfoList *rlList = d.entryInfoList(); + QFileInfoListIterator it( *rlList ); // create list iterator + QFileInfo* fi; // pointer for traversing + + while ( (fi=it.current()) ) + { // for each file... + info2Widget( fi, i); + ++it; // goto next list element + + // keep GUI alive + qApp->processEvents(); + } + } +} + +void KSVContent::info2Widget( QFileInfo* info, int index ) +{ + if (!info->exists()) + return; + + QString f_name = info->fileName(); + + QFileInfo link_info = QFileInfo(info->readLink()); + QString l_base = link_info.fileName(); + + QString l_path = ksv::IO::relToAbs(conf->scriptPath(), link_info.dirPath(FALSE)); + + QString name; + int number; + ksv::IO::dissectFilename( f_name, name, number ); + + // finally insert the items... + if ( f_name.left(1) == "S" ) + startRL[index]->initItem( l_base, l_path, name, number ); + else + stopRL[index]->initItem( l_base, l_path, name, number ); +} + +void KSVContent::slotWriteSysV() +{ + appendLog(i18n("<vip>WRITING CONFIGURATION</vip>"), + i18n("** WRITING CONFIGURATION **")); + + for (int i = 0; i < ksv::runlevelNumber; ++i) + { + appendLog(i18n("<rl>RUNLEVEL %1</rl>").arg(i), + i18n("** RUNLEVEL %1 **").arg(i)); + + clearRL(i); // rm changed/deleted entries + + // process "Start" + KSVItem* item = 0L; + for (QListViewItemIterator it (startRL[i]); + (item = static_cast<KSVItem*> (it.current())); + ++it) + { + if (item->isChanged() || item->isNew()) + writeToDisk (*item->data(), i, true); + } + + // process "Stop" + for (QListViewItemIterator it (stopRL[i]); + (item = static_cast<KSVItem*> (it.current())); + ++it) + { + if (item->isChanged() || item->isNew()) + writeToDisk (*item->data(), i, false); + } + + appendLog("<br/><br/>", "\n"); + } + + appendLog("<br/>", ""); +} + +void KSVContent::writeToDisk(const KSVData& _w, int _rl, bool _start) { + QString rich, plain; + ksv::IO::makeSymlink (_w, _rl, _start, rich, plain); + appendLog(rich, plain); +} + +void KSVContent::repaintRunlevels () +{ + for (int i = 0; i < ksv::runlevelNumber; ++i) + { + startRL[i]->triggerUpdate(); + stopRL[i]->triggerUpdate(); + } + + scripts->triggerUpdate(); +} + +void KSVContent::clearRL(int _rl) +{ + QString path = conf->runlevelPath() + QString("/rc%1.d").arg(_rl); + + QDir dir (path); + + KSVData* d = 0L; + + for (QPtrListIterator<KSVData> it (startRL[_rl]->getDeletedItems()); + (d = it.current()); + ++it) + { + // ugly hack -> dont try to delete if entry is new (i.e. not save to disk) + if (d->newEntry() && d->originalRunlevel() != startRL[_rl]->name()) + break; + + QFileInfo file (path + QString("/S%1%2").arg(d->numberString()).arg(d->label())); + + QString rich, plain; + ksv::IO::removeFile (file, dir, rich, plain); + appendLog(rich, plain); + } + + // keep GUI alive + qApp->processEvents(); + + for (QPtrListIterator<KSVData> it (stopRL[_rl]->getDeletedItems()); + (d = it.current()); + ++it) + { + // ugly, too + if (d->newEntry() && d->originalRunlevel() != stopRL[_rl]->name()) + break; + + QFileInfo file (path + QString("/K%1%2").arg(d->numberString()).arg(d->label())); + + QString rich, plain; + ksv::IO::removeFile (file, dir, rich, plain); + appendLog(rich, plain); + } + + // keep GUI alive + qApp->processEvents(); +} + +void KSVContent::infoOnData (KSVItem* item) +{ + KSVData oldState = *item->data(); + KSVData newState = oldState; + KSVEntryPropertiesDialog* props = new KSVEntryPropertiesDialog (newState, kapp->mainWidget()); + + connect (props, SIGNAL (editService (const QString&)), + this, SLOT (editService (const QString&))); + connect (props, SIGNAL (startService (const QString&)), + this, SLOT (startService (const QString&))); + connect (props, SIGNAL (stopService (const QString&)), + this, SLOT (stopService (const QString&))); + connect (props, SIGNAL (restartService (const QString&)), + this, SLOT (restartService (const QString&))); + + int res = props->exec(); + + if (res == QDialog::Accepted + && !(oldState == newState && oldState.number() == newState.number())) + { + item->copy (newState); + + reSortRL(); + + emit undoAction(new ChangeAction(getOrigin(), &oldState, &newState)); + } +} + +void KSVContent::stopService () +{ + KSVContent::stopService (getOrigin()->currentItem()->filenameAndPath()); +} + +void KSVContent::stopService (const QString& path) +{ + KProcess *_proc = new KProcess(); + _proc->clearArguments(); + + *_proc << path << "stop"; + + connect(_proc, SIGNAL(processExited(KProcess*)), this, SLOT(slotExitedProcess(KProcess*))); + connect(_proc, SIGNAL(receivedStdout(KProcess*, char*, int)), this, SLOT(slotOutputOrError(KProcess*, char*, int))); + connect(_proc, SIGNAL(receivedStderr(KProcess*, char*, int)), this, SLOT(slotOutputOrError(KProcess*, char*, int))); + + // refresh textDisplay + appendLog(i18n("** <stop>Stopping</stop> <cmd>%1</cmd> **<br/>").arg(path), + i18n("** Stopping %1 **").arg(path)); + + _proc->start(KProcess::NotifyOnExit, KProcess::AllOutput); + + // notify parent + emit sigRun(path + i18n(" stop")); +} + +void KSVContent::startService () +{ + KSVContent::startService (getOrigin()->currentItem()->filenameAndPath()); +} + +void KSVContent::startService (const QString& path) +{ + KProcess* _proc = new KProcess(); + _proc->clearArguments(); + + *_proc << path << "start"; + + connect(_proc, SIGNAL(processExited(KProcess*)), this, SLOT(slotExitedProcess(KProcess*))); + connect(_proc, SIGNAL(receivedStdout(KProcess*, char*, int)), this, SLOT(slotOutputOrError(KProcess*, char*, int))); + connect(_proc, SIGNAL(receivedStderr(KProcess*, char*, int)), this, SLOT(slotOutputOrError(KProcess*, char*, int))); + + // refresh textDisplay + appendLog(i18n("** <start>Starting</start> <cmd>%1</cmd> **<br/>").arg(path), + i18n("** Starting %1 **").arg(path)); + + _proc->start(KProcess::NotifyOnExit, KProcess::AllOutput); + + // notify parent + emit sigRun(path + i18n(" start")); +} + +void KSVContent::editService() +{ + editService (getOrigin()->currentItem()->filenameAndPath()); +} + +void KSVContent::editService (const QString& path) +{ + // unfortunately KRun::run() only takes an URL-list instead of a single + // URL as an argument. + KURL url; url.setPath (path); KURL::List urls; urls << url; + KRun::run (*ksv::IO::preferredServiceForFile (path), urls); +} + +void KSVContent::restartService () +{ + KSVContent::restartService (getOrigin()->currentItem()->filenameAndPath()); +} + +void KSVContent::restartService (const QString& path) +{ + // restarting + KProcess *_proc = new KProcess(); + _proc->clearArguments(); + + *_proc << path << "restart"; + + connect(_proc, SIGNAL(processExited(KProcess*)), this, SLOT(slotExitDuringRestart(KProcess*))); + connect(_proc, SIGNAL(receivedStdout(KProcess*, char*, int)), this, SLOT(slotOutputOrError(KProcess*, char*, int))); + connect(_proc, SIGNAL(receivedStderr(KProcess*, char*, int)), this, SLOT(slotOutputOrError(KProcess*, char*, int))); + + // refresh textDisplay + appendLog(i18n("** Re-starting <cmd>%1</cmd> **</br>").arg(path), + i18n("** Re-starting %1 **").arg(path)); + + _proc->start(KProcess::NotifyOnExit, KProcess::AllOutput); + + // notify parent + emit sigRun(path + i18n(" restart")); +} + +void KSVContent::slotOutputOrError( KProcess*, char* _buffer, int _buflen) { + if (_buflen > 0) { + m_buffer += QCString( _buffer, _buflen + 1 ); + appendLog( m_buffer ); + } +} + +void KSVContent::slotExitedProcess( KProcess* proc ) { + appendLog("<hr/>", "--------------"); + + emit sigStop(); + delete proc; +} + +void KSVContent::slotScriptsNotRemovable() +{ + emit sigNotRemovable(); +} + +void KSVContent::slotDoubleClick (QListViewItem* item) { + infoOnData(static_cast<KSVItem*>(item)); +} + +void KSVContent::slotScriptProperties(QListViewItem* item) +{ + KSVServicePropertiesDialog* prop = + new KSVServicePropertiesDialog (*static_cast<KSVItem*> (item)->data(), kapp->mainWidget()); + + connect (prop, SIGNAL (editService (const QString&)), + this, SLOT (editService (const QString&))); + connect (prop, SIGNAL (startService (const QString&)), + this, SLOT (startService (const QString&))); + connect (prop, SIGNAL (stopService (const QString&)), + this, SLOT (stopService (const QString&))); + connect (prop, SIGNAL (restartService (const QString&)), + this, SLOT (restartService (const QString&))); + + prop->exec(); + + // delete prop; +} + +void KSVContent::slotExitDuringRestart( KProcess* proc ) +{ + delete proc; + proc = new KProcess(); // necessary because otherwise we still have some + // signals connected that screw up our output + proc->clearArguments(); + + connect(proc, SIGNAL(processExited(KProcess*)), this, SLOT(slotExitedProcess(KProcess*))); + connect(proc, SIGNAL(receivedStdout(KProcess*, char*, int)), this, SLOT(slotOutputOrError(KProcess*, char*, int))); + connect(proc, SIGNAL(receivedStderr(KProcess*, char*, int)), this, SLOT(slotOutputOrError(KProcess*, char*, int))); + + proc->start(KProcess::NotifyOnExit, KProcess::AllOutput); +} + +KSVDragList* KSVContent::getOrigin() +{ + return mOrigin; +} + +void KSVContent::setDisplayScriptOutput(bool val) +{ + if (val) + { + setSizes(KSVContent::panningFactorToSplitter (conf->panningFactor())); + textDisplay->show(); + } + else + { + conf->setPanningFactor (KSVContent::splitterToPanningFactor (sizes())); + textDisplay->hide(); + } + + calcMinSize(); +} + +int KSVContent::splitterToPanningFactor (const QValueList<int>& list) +{ + const int cont_size = *list.at(0); + const int log_size = *list.at(1); + + return cont_size * 100 / (cont_size + log_size); +} + +const QValueList<int>& KSVContent::panningFactorToSplitter (int panningFactor) +{ + static QValueList<int> res; + res.clear(); + + res << panningFactor << 100 - panningFactor; + + return res; +} + +void KSVContent::appendLog (const QString& rich, const QString& plain) +{ + static bool changed = false; + + if (!changed) + { + changed = true; + emit logChanged(); + } + + mLogText += plain + "\n"; + mXMLLogText += rich + "\n"; + textDisplay->append (rich); +} + +void KSVContent::appendLog(const QCString& _buffer) +{ + QStringList _lines = QStringList::split( "\n", QString::fromLocal8Bit( _buffer ) ); + for ( QStringList::Iterator it = _lines.begin(); it != _lines.end(); ++it ) + appendLog( *it, *it ); + + m_buffer = QCString(); +} + +const QString& KSVContent::log () const +{ + return mLogText; +} + +const QString& KSVContent::xmlLog () const +{ + return mXMLLogText; +} + +void KSVContent::fwdCannotGenerateNumber() { + emit cannotGenerateNumber(); +} + +void KSVContent::updatePanningFactor() +{ + conf->setPanningFactor(KSVContent::splitterToPanningFactor(sizes())); +} + +void KSVContent::fwdOrigin () +{ + emit newOrigin(); +} + +void KSVContent::fwdOrigin (KSVDragList* list) +{ + mOrigin = list; +} + +void KSVContent::showEvent (QShowEvent* e) +{ + calcMinSize(); + + QSplitter::showEvent (e); +} + +void KSVContent::reSortRL() +{ + getOrigin()->sort(); +} + +void KSVContent::pasteAppend() +{ + KSVDragList* list = getOrigin(); + + if (list) + { + KSVData data; + + if (KSVDrag::decodeNative (kapp->clipboard()->data(), data)) + { + KSVAction* action = 0L; + + if (list->insert (data, list->lastItem(), action)) + { + emit undoAction (action); + } + } + } +} + +void KSVContent::resizeEvent (QResizeEvent* e) +{ + updatePanningFactor(); + + QSplitter::resizeEvent (e); +} + +void KSVContent::moveEvent (QMoveEvent* e) +{ + QSplitter::moveEvent (e); +} + +void KSVContent::setColors (const QColor& newNormal, + const QColor& newSelected, + const QColor& changedNormal, + const QColor& changedSelected) +{ + for (int i = 0; i < ksv::runlevelNumber; ++i) + { + startRL[i]->setNewNormalColor (newNormal); + startRL[i]->setNewSelectedColor (newSelected); + startRL[i]->setChangedNormalColor (changedNormal); + startRL[i]->setChangedSelectedColor (changedSelected); + startRL[i]->viewport()->update(); + + stopRL[i]->setNewNormalColor (newNormal); + stopRL[i]->setNewSelectedColor (newSelected); + stopRL[i]->setChangedNormalColor (changedNormal); + stopRL[i]->setChangedSelectedColor (changedSelected); + stopRL[i]->viewport()->update(); + } +} + +void KSVContent::multiplexEnabled (bool val) +{ + QListView* list = getOrigin(); + + + if (list) + { + list->clearSelection(); + list->setCurrentItem (0L); + } + + + for (int i = 0; i < ksv::runlevelNumber; ++i) + { + startRL[i]->setEnabled (val); + startRL[i]->setAcceptDrops (val); + + stopRL[i]->setEnabled (val); + stopRL[i]->setAcceptDrops (val); + } + + if (!val) + { + mOrigin = 0L; + emit newOrigin (); + + KSVConfig *config = KSVConfig::self(); + QFileInfo *file = new QFileInfo( config->scriptPath() ); + + if ( !file->exists() ) + { + int choice = KMessageBox::warningYesNo + (kapp->mainWidget(), + i18n ("<p>You have specified that your system's init " \ + "scripts are located in the folder " \ + "<tt><b>%1</b></tt>, but this folder does not "\ + "exist. You probably selected the wrong " \ + "distribution during configuration.</p> " \ + "<p>If you reconfigure %2, it may be possible to "\ + "fix the problem. If you choose to reconfigure, " \ + "you should shut down the application " \ + "and the configuration wizard will appear the " \ + "next time %3 is run. If you choose not to " \ + "reconfigure, you will not be able to view or " \ + "edit your system's init configuration.</p>" \ + "<p>Would you like to reconfigure %4?</p>") + .arg (config->scriptPath()) + .arg (kapp->aboutData()->programName()) + .arg (kapp->aboutData()->programName()) + .arg (kapp->aboutData()->programName()), + i18n("Folder Does Not Exist"),i18n("Reconfigure"),i18n("Do Not Reconfigure")); + + if ( choice == KMessageBox::Yes ) + { + config->setConfigured(false); + config->writeSettings(); + } + } + else + { + KMessageBox::information (kapp->mainWidget(), + i18n ("<p>You do not have the right permissions " \ + "to edit your system's init configuration. " \ + "However, you are free to browse the runlevels.</p>" \ + "<p>If you really want to edit the " \ + "configuration, either <strong>restart</strong> " \ + "%1 <strong>as root</strong> (or another privileged "\ + "user), or ask your sysadmin to install %2 " \ + "<em>suid</em> or <em>sgid</em>.</p>" \ + "<p>The latter way is not recommended though, " \ + "due to security issues.</p>") + .arg (kapp->aboutData()->programName()) + .arg (kapp->aboutData()->programName()), + i18n("Insufficient Permissions"), + ksv::notifications[ksv::RunlevelsReadOnly]); + } + + delete file; + } +} + +void KSVContent::hideRunlevel (int index) +{ + mRunlevels[index]->hide(); + calcMinSize(); +} + +void KSVContent::showRunlevel (int index) +{ + mRunlevels[index]->show(); + calcMinSize(); +} + +void KSVContent::popupRunlevelMenu (KListView* list, QListViewItem* i, const QPoint& p) +{ + if (i) + mItemMenu->exec (p, 1); + else + { + if (!list->header()->rect().contains (list->mapFromGlobal(p))) + mContextMenu->exec (p, 1); + } +} + +void KSVContent::popupServicesMenu (KListView*, QListViewItem* i, const QPoint& p) +{ + if (i) + { + mOpenWithMenu->clear(); + + mOpenWithOffers + = ksv::IO::servicesForFile (static_cast<KSVItem*>(i)->filenameAndPath()); + + int i = 0; + for (KTrader::OfferList::Iterator it = mOpenWithOffers.begin(); + it != mOpenWithOffers.end(); + ++it) + { + mOpenWithMenu->insertItem (SmallIconSet((*it)->icon()), (*it)->name(), i); + ++i; + } + + if (i >= 1) + mOpenWithMenu->insertSeparator(); + + mOpenWithMenu->insertItem (i18n ("&Other..."), this, SLOT (openWith())); + + mScriptMenu->exec (p, 1); + } +} + +void KSVContent::openWith () +{ + KURL url; url.setPath(static_cast<KSVItem*>(getOrigin()->currentItem())->filenameAndPath()); + KURL::List urls; urls.append (url); + + KRun::displayOpenWithDialog (urls); + + kdDebug(3000) << "Opening with..." << endl; +} + +void KSVContent::openWith (int index) +{ + if (index < 0) + return; + + KService::Ptr service = *mOpenWithOffers.at (index); + KURL url; url.setPath(static_cast<KSVItem*>(getOrigin()->currentItem())->filenameAndPath()); + KURL::List urls; urls.append (url); + + KRun::run (*service, urls); + + kdDebug(3000) << "Opening with " << service->exec() << endl; +} + +void KSVContent::calcMinSize () +{ + // Cryptic code alert: Changing w or h will change mMinSize + QCOORD& w = mMinSize.rwidth(); + QCOORD& h = mMinSize.rheight(); + + w = 2 * KDialog::marginHint() + mScriptBox->sizeHint().width(); + h = 2 * KDialog::marginHint() + mScriptBox->sizeHint().height(); + + for (int i = 0; i < ksv::runlevelNumber; ++i) + { + if (mRunlevels[i]->isHidden()) + continue; + + w += KDialog::spacingHint() + mRunlevels[i]->sizeHint().width(); + h = kMax (h, mRunlevels[i]->sizeHint().height()); + } + + mContent->layout()->setEnabled(false); + mContent->setMinimumSize(mMinSize); + mScroller->updateScrollBars(); + mContent->layout()->setEnabled(true); +} + +void KSVContent::mergeLoadedPackage (QValueList<KSVData>* start, + QValueList<KSVData>* stop) +{ + for (int i = 0; i < ksv::runlevelNumber; ++i) + { + merge (start[i], startRL[i]); + merge (stop[i], stopRL[i]); + } +} + +void KSVContent::merge (QValueList<KSVData>& list, KSVDragList* widget) +{ + typedef QMap<KSVData, bool> LoadMap; + LoadMap loaded; + + for (QValueListIterator<KSVData> it = list.begin(); + it != list.end(); + ++it) + { + KSVItem* exists = widget->match (*it); + if (exists) + { + KSVData oldState = *exists->data(); + exists->setNumber ((*it).number()); + exists->setLabel ((*it).label()); + exists->setFilename ((*it).filename()); + exists->setPath ((*it).path()); + loaded[*exists->data()] = true; + + if (exists->isChanged()) + { + emit undoAction (new ChangeAction (widget, &oldState, exists->data())); + } + } + else + { + KSVItem* item = new KSVItem (widget, *it); + item->setNew (true); + loaded[*item->data()] = true; + + emit undoAction (new AddAction (widget, item->data())); + } + + kapp->processEvents (); + } + + QPtrList<KSVItem> deleteList; + deleteList.setAutoDelete (true); + + for (QListViewItemIterator it (widget); it.current(); ++it) + { + KSVItem* item = static_cast<KSVItem*> (it.current()); + + if (!loaded[*item->data()]) + { + deleteList.append (item); + + emit undoAction (new RemoveAction (widget, item->data())); + } + + kapp->processEvents (); + } + + widget->sort(); + kapp->processEvents(); +} + +#include "OldView.moc" |