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.
1110 lines
31 KiB
1110 lines
31 KiB
/*
|
|
Requires the TQt widget libraries, available at no cost at
|
|
http://www.troll.no
|
|
|
|
Copyright (C) 1997-2000 Peter Putzer
|
|
putzer@kde.org
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of version 2 of the GNU General Public License
|
|
as published by the Free Software Foundation.
|
|
|
|
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
/****************************************************************
|
|
**
|
|
** KSysV
|
|
** Toplevel Widget
|
|
**
|
|
****************************************************************/
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <tqpopupmenu.h>
|
|
#include <tqkeycode.h>
|
|
#include <tqmessagebox.h>
|
|
#include <tqfontmetrics.h>
|
|
#include <tqpainter.h>
|
|
#include <tqmultilineedit.h>
|
|
#include <tqdatetime.h>
|
|
#include <kprinter.h>
|
|
#include <tqpaintdevicemetrics.h>
|
|
#include <tqbuttongroup.h>
|
|
#include <tqclipboard.h>
|
|
#include <tqtooltip.h>
|
|
#include <tqcheckbox.h>
|
|
#include <tqhbox.h>
|
|
#include <tqregexp.h>
|
|
#include <tqdatastream.h>
|
|
#include <tqpixmapcache.h>
|
|
#include <tqtextview.h>
|
|
#include <tqfileinfo.h>
|
|
#include <tqtextstream.h>
|
|
#include <tqwhatsthis.h>
|
|
#include <tqsimplerichtext.h>
|
|
|
|
#include <kresolver.h>
|
|
#include <ktoolbar.h>
|
|
#include <kkeydialog.h>
|
|
#include <kmenubar.h>
|
|
#include <kcompletion.h>
|
|
#include <kaction.h>
|
|
#include <kstdaction.h>
|
|
#include <kdebug.h>
|
|
#include <kapplication.h>
|
|
#include <kglobal.h>
|
|
#include <khelpmenu.h>
|
|
#include <klocale.h>
|
|
#include <kmessagebox.h>
|
|
#include <kstdaccel.h>
|
|
#include <kedittoolbar.h>
|
|
#include <kiconloader.h>
|
|
#include <kfiledialog.h>
|
|
#include <kaboutdata.h>
|
|
#include <kcursor.h>
|
|
|
|
#include "kbusymanager.h"
|
|
#include "ServiceDlg.h"
|
|
#include "PreferencesDialog.h"
|
|
#include "ActionList.h"
|
|
#include "ksv_core.h"
|
|
#include "ksv_conf.h"
|
|
#include "RunlevelAuthIcon.h"
|
|
#include "ksvdraglist.h"
|
|
#include "Data.h"
|
|
#include "ksvdrag.h"
|
|
#include "OldView.h"
|
|
#include "IOCore.h"
|
|
#include "TopWidget.h"
|
|
#include <tqlabel.h>
|
|
#include <kstatusbar.h>
|
|
|
|
namespace Status
|
|
{
|
|
enum {
|
|
Changed, Checklist, Writable
|
|
};
|
|
} // namespace Status
|
|
|
|
KSVTopLevel::KSVTopLevel()
|
|
: KMainWindow(0, 0L, WStyle_ContextHelp|WDestructiveClose),
|
|
mConfig(KSVConfig::self()),
|
|
mView (0L),
|
|
mPreferences (0L),
|
|
|
|
mEditUndo (0L), mEditCut (0L), mEditCopy (0L), mEditPaste (0L),
|
|
mEditProperties (0L),
|
|
|
|
mFileRevert (0L), mFileLoad (0L), mFilePrint (0L), mFilePrintLog (0L),
|
|
mFileSave (0L), mFileSaveAs (0L), mFileSaveLog(0L), mFileQuit (0L),
|
|
|
|
mToolsStartService (0L), mToolsStopService (0L),
|
|
mToolsRestartService (0L), mToolsEditService (0L),
|
|
|
|
mOptionsToggleLog (0L),
|
|
|
|
mOpenWith (0L), mOpenDefault (0L),
|
|
|
|
mUndoList (new ActionList (TQT_TQOBJECT(this), "UndoList")),
|
|
mRedoList (new ActionList (TQT_TQOBJECT(this), "RedoList")),
|
|
mStartDlg (new ServiceDlg (i18n("Start Service"),
|
|
i18n("&Choose which service to start:"),
|
|
this)),
|
|
mStopDlg (new ServiceDlg (i18n("Stop Service"),
|
|
i18n("&Choose which service to stop:"),
|
|
this)),
|
|
mRestartDlg (new ServiceDlg (i18n("Restart Service"),
|
|
i18n("&Choose which service to restart:"),
|
|
this)),
|
|
mEditDlg (new ServiceDlg (i18n("Edit Service"),
|
|
i18n("&Choose which service to edit:"),
|
|
this)),
|
|
mVisible (new TQCheckBox*[ksv::runlevelNumber])
|
|
{
|
|
setCaption(false);
|
|
|
|
initStatusBar(); // order dependency
|
|
initActions(); // order dependency
|
|
mView = new KSVContent (mOpenWith->popupMenu(), this, "Content"); // order dependency
|
|
initTools(); // order dependency
|
|
|
|
setCentralWidget(mView);
|
|
|
|
// ensure that the statusbar gets updated correctly
|
|
connect (mView, TQT_SIGNAL(sigRun(const TQString&)), this, TQT_SLOT(slotUpdateRunning(const TQString&)));
|
|
connect (mView, TQT_SIGNAL(sigStop()), statusBar(), TQT_SLOT(clear()));
|
|
connect (mView, TQT_SIGNAL(cannotGenerateNumber()), this, TQT_SLOT(catchCannotGenerateNumber()));
|
|
connect (mView, TQT_SIGNAL(undoAction(KSVAction*)), this, TQT_SLOT(pushUndoAction(KSVAction*)));
|
|
connect (mView, TQT_SIGNAL(logChanged()), this, TQT_SLOT(enableLogActions()));
|
|
|
|
// cut & copy
|
|
connect (mView, TQT_SIGNAL (newOrigin()),
|
|
this, TQT_SLOT (dispatchEdit()));
|
|
|
|
// undo
|
|
connect (mUndoList, TQT_SIGNAL(empty()), this, TQT_SLOT(disableUndo()));
|
|
connect (mUndoList, TQT_SIGNAL(filled()), this, TQT_SLOT(enableUndo()));
|
|
|
|
// and redo
|
|
connect (mRedoList, TQT_SIGNAL(empty()), this, TQT_SLOT(disableRedo()));
|
|
connect (mRedoList, TQT_SIGNAL(filled()), this, TQT_SLOT(enableRedo()));
|
|
|
|
// paste
|
|
connect (kapp->clipboard(), TQT_SIGNAL (dataChanged()),
|
|
this, TQT_SLOT (dispatchEdit()));
|
|
|
|
// init mView according to saved preferences
|
|
slotReadConfig();
|
|
initView();
|
|
setMinimumSize(600,400);
|
|
|
|
// restore size and position
|
|
move(mConfig->position()); // doesnt seem to work while unmapped
|
|
setAutoSaveSettings();
|
|
|
|
// start watching the directories
|
|
mAuth->setCheckEnabled(true);
|
|
|
|
dispatchEdit(); // disable cut & copy on startup
|
|
}
|
|
|
|
KSVTopLevel::~KSVTopLevel()
|
|
{
|
|
mUndoList->clear();
|
|
mRedoList->clear();
|
|
|
|
delete[] mVisible;
|
|
}
|
|
|
|
void KSVTopLevel::initTools()
|
|
{
|
|
connect (mStartDlg, TQT_SIGNAL(doAction(const TQString&)),
|
|
mView, TQT_SLOT(startService(const TQString&)));
|
|
connect (mStopDlg, TQT_SIGNAL(doAction(const TQString&)),
|
|
mView, TQT_SLOT(editService(const TQString&)));
|
|
connect (mRestartDlg, TQT_SIGNAL(doAction(const TQString&)),
|
|
mView, TQT_SLOT(restartService(const TQString&)));
|
|
connect (mEditDlg, TQT_SIGNAL(doAction(const TQString&)),
|
|
mView, TQT_SLOT(editService(const TQString&)));
|
|
|
|
connect (mStartDlg, TQT_SIGNAL (display (bool)),
|
|
this, TQT_SLOT (dispatchStartService (bool)));
|
|
connect (mStopDlg, TQT_SIGNAL (display (bool)),
|
|
this, TQT_SLOT (dispatchStopService (bool)));
|
|
connect (mRestartDlg, TQT_SIGNAL (display (bool)),
|
|
this, TQT_SLOT (dispatchRestartService (bool)));
|
|
connect (mEditDlg, TQT_SIGNAL (display (bool)),
|
|
this, TQT_SLOT (dispatchEditService (bool)));
|
|
|
|
}
|
|
|
|
void KSVTopLevel::initActions ()
|
|
{
|
|
KActionCollection* coll = actionCollection();
|
|
|
|
// setup File menu
|
|
mFileRevert = KStdAction::revert (TQT_TQOBJECT(this), TQT_SLOT (slotClearChanges()), coll);
|
|
mFileRevert->setText (i18n("Re&vert Configuration"));
|
|
|
|
mFileLoad = KStdAction::open (TQT_TQOBJECT(this), TQT_SLOT (load()), coll);
|
|
mFileLoad->setText (i18n ("&Open..."));
|
|
|
|
mFileSave = KStdAction::save(TQT_TQOBJECT(this), TQT_SLOT(slotAcceptChanges()), coll);
|
|
mFileSave->setText (i18n("&Save Configuration"));
|
|
|
|
mFileSaveAs = KStdAction::saveAs (TQT_TQOBJECT(this), TQT_SLOT (saveAs ()), coll);
|
|
|
|
mFileSaveLog = KStdAction::save (TQT_TQOBJECT(this), TQT_SLOT(slotSaveLog()), coll, "ksysv_save_log");
|
|
mFileSaveLog->setText (i18n("Save &Log..."));
|
|
mFileSaveLog->setShortcut (Key_L+CTRL);
|
|
mFileSaveLog->setEnabled (false);
|
|
|
|
// disabled due to complexity
|
|
// mFilePrint = KStdAction::print (this, TQT_SLOT (print()), coll);
|
|
|
|
mFilePrintLog = KStdAction::print(TQT_TQOBJECT(this), TQT_SLOT(printLog()), coll, "ksysv_print_log");
|
|
mFilePrintLog->setText( i18n("&Print Log..."));
|
|
mFilePrintLog->setEnabled (false);
|
|
|
|
mFileQuit = KStdAction::quit(TQT_TQOBJECT(this), TQT_SLOT(close()), coll);
|
|
|
|
// setup Edit menu
|
|
mEditUndo = KStdAction::undo(TQT_TQOBJECT(this), TQT_SLOT(editUndo()), coll);
|
|
mEditUndo->setEnabled (false);
|
|
mEditRedo = KStdAction::redo(TQT_TQOBJECT(this), TQT_SLOT(editRedo()), coll);
|
|
mEditUndo->setEnabled (false);
|
|
mEditCut = KStdAction::cut(TQT_TQOBJECT(this), TQT_SLOT(editCut()), coll);
|
|
mEditCopy = KStdAction::copy(TQT_TQOBJECT(this), TQT_SLOT(editCopy()), coll);
|
|
mEditPaste = KStdAction::paste(TQT_TQOBJECT(this), TQT_SLOT(editPaste()), coll);
|
|
mPasteAppend = KStdAction::paste (TQT_TQOBJECT(this), TQT_SLOT (pasteAppend()),
|
|
coll, "ksysv_paste_append");
|
|
|
|
mEditProperties = new KAction (i18n("P&roperties"), 0,
|
|
TQT_TQOBJECT(this), TQT_SLOT(properties()),
|
|
coll, "ksysv_properties");
|
|
|
|
mOpenDefault = new KAction (i18n ("&Open"), 0,
|
|
TQT_TQOBJECT(this), TQT_SLOT (editService()),
|
|
coll, "ksysv_open_service");
|
|
|
|
mOpenWith = new KActionMenu (i18n ("Open &With"), coll, "ksysv_open_with");
|
|
|
|
// setup Settings menu
|
|
createStandardStatusBarAction();
|
|
setStandardToolBarMenuEnabled(true);
|
|
KStdAction::keyBindings (TQT_TQOBJECT(this), TQT_SLOT(configureKeys()), coll);
|
|
KStdAction::configureToolbars (TQT_TQOBJECT(this), TQT_SLOT(configureToolbars()), coll);
|
|
KStdAction::saveOptions(TQT_TQOBJECT(this), TQT_SLOT(saveOptions()), coll);
|
|
KStdAction::preferences(TQT_TQOBJECT(this), TQT_SLOT(slotShowConfig()), coll);
|
|
mOptionsToggleLog = new KToggleAction (i18n("Show &Log"), "toggle_log", 0,
|
|
TQT_TQOBJECT(this), TQT_SLOT (toggleLog()),
|
|
coll, "ksysv_toggle_log");
|
|
mOptionsToggleLog->setCheckedState(i18n("Hide &Log"));
|
|
|
|
// setup Tools menu
|
|
mToolsStartService = new KToggleAction (i18n("&Start Service..."), "ksysv_start", 0,
|
|
TQT_TQOBJECT(mStartDlg), TQT_SLOT (toggle()),
|
|
coll, "ksysv_start_service");
|
|
|
|
mToolsStopService = new KToggleAction (i18n("&Stop Service..."), "ksysv_stop", 0,
|
|
TQT_TQOBJECT(mStopDlg), TQT_SLOT (toggle()),
|
|
coll, "ksysv_stop_service");
|
|
|
|
mToolsRestartService = new KToggleAction (i18n("&Restart Service..."), 0,
|
|
TQT_TQOBJECT(mRestartDlg), TQT_SLOT (toggle()),
|
|
coll, "ksysv_restart_service");
|
|
|
|
mToolsEditService = new KToggleAction (i18n("&Edit Service..."), 0,
|
|
TQT_TQOBJECT(mEditDlg), TQT_SLOT (toggle()),
|
|
coll, "ksysv_edit_service");
|
|
|
|
createGUI(xmlFile());
|
|
}
|
|
|
|
//
|
|
bool KSVTopLevel::queryExit()
|
|
{
|
|
uint res = KMessageBox::Continue;
|
|
|
|
if (mChanged) {
|
|
res = KMessageBox::warningContinueCancel(kapp->mainWidget(),
|
|
i18n("There are unsaved changes. Are you sure you want to quit?"),
|
|
i18n("Quit"),
|
|
KStdGuiItem::quit());
|
|
|
|
}
|
|
|
|
return res == KMessageBox::Continue;
|
|
}
|
|
|
|
void KSVTopLevel::slotClearChanges()
|
|
{
|
|
if (mChanged &&
|
|
KMessageBox::Yes ==
|
|
KMessageBox::questionYesNo(kapp->mainWidget(),
|
|
i18n("Do you really want to revert all unsaved changes?"),
|
|
i18n("Revert Configuration"),
|
|
i18n("&Revert"),
|
|
KStdGuiItem::cancel()))
|
|
{
|
|
mUndoList->undoAll();
|
|
mRedoList->clear();
|
|
}
|
|
}
|
|
|
|
void KSVTopLevel::slotAcceptChanges() {
|
|
if (KMessageBox::Continue ==
|
|
KMessageBox::warningContinueCancel(kapp->mainWidget(),
|
|
i18n("You're about to save the changes made to your init "
|
|
"configuration. Wrong settings can "
|
|
"make your system hang on startup.\n"
|
|
"Do you wish to continue?"),
|
|
i18n("Save Configuration"),
|
|
KStdGuiItem::save()))
|
|
{
|
|
mView->slotWriteSysV();
|
|
initView();
|
|
}
|
|
}
|
|
|
|
void KSVTopLevel::initView()
|
|
{
|
|
const bool authEnabled = mAuth->isCheckEnabled();
|
|
mAuth->setCheckEnabled(false);
|
|
|
|
mUndoList->clear();
|
|
mRedoList->clear();
|
|
|
|
mView->initScripts();
|
|
mView->initRunlevels();
|
|
|
|
setChanged(false);
|
|
|
|
// disable ToolsMenu_ entries when they can't do anything
|
|
ServiceDlg* tmp = new ServiceDlg ("","", this);
|
|
|
|
tmp->resetChooser (mView->scripts, false);
|
|
if (!tmp->count())
|
|
{
|
|
mToolsStartService->setEnabled (false);
|
|
mToolsStopService->setEnabled (false);
|
|
mToolsRestartService->setEnabled (false);
|
|
}
|
|
else
|
|
{
|
|
mToolsStartService->setEnabled (true);
|
|
mToolsStopService->setEnabled (true);
|
|
mToolsRestartService->setEnabled (true);
|
|
}
|
|
|
|
tmp->resetChooser (mView->scripts, true);
|
|
if (!tmp->count())
|
|
{
|
|
mToolsEditService->setEnabled (false);
|
|
}
|
|
else
|
|
{
|
|
|
|
mToolsEditService->setEnabled (true);
|
|
}
|
|
delete tmp;
|
|
|
|
// reset tools
|
|
mStartDlg->resetChooser (mView->scripts, false);
|
|
mStopDlg->resetChooser (mView->scripts, false);
|
|
mRestartDlg->resetChooser (mView->scripts, false);
|
|
mEditDlg->resetChooser (mView->scripts, true);
|
|
|
|
mAuth->setCheckEnabled(authEnabled);
|
|
}
|
|
|
|
void KSVTopLevel::initStatusBar()
|
|
{
|
|
KStatusBar* status = statusBar();
|
|
|
|
TQHBox* visBox = new TQHBox (status, "visBox");
|
|
TQButtonGroup* group = new TQButtonGroup (this, "visButtonGroup");
|
|
group->hide();
|
|
connect (group, TQT_SIGNAL (clicked (int)), this, TQT_SLOT (toggleRunlevel (int)));
|
|
|
|
TQWhatsThis::add (visBox, i18n ("<p>Click on the checkboxes to <strong>show</strong> or "\
|
|
"<strong>hide</strong> runlevels.</p> " \
|
|
"<p>The list of currently visible runlevels is saved "\
|
|
"when you use the <strong>Save Options command</strong>.</p>"));
|
|
TQToolTip::add (visBox, i18n ("Show only the selected runlevels"));
|
|
|
|
new TQLabel (i18n("Show runlevels:"), visBox, "visLabel");
|
|
for (int i = 0; i < ksv::runlevelNumber; ++i)
|
|
{
|
|
TQString label; label.setNum (i);
|
|
|
|
mVisible[i] = new TQCheckBox (label, visBox, label.latin1());
|
|
mVisible[i]->setChecked (mConfig->showRunlevel (i));
|
|
|
|
group->insert (mVisible[i]);
|
|
}
|
|
|
|
TQHBox* authIconBox = new TQHBox (status, "AuthIconBox");
|
|
TQWidget* strut = new TQWidget (authIconBox, "Strut");
|
|
strut->setFixedWidth (KDialog::spacingHint());
|
|
mAuth = new RunlevelAuthIcon (mConfig->scriptPath(), mConfig->runlevelPath(), authIconBox);
|
|
connect (mAuth, TQT_SIGNAL (authChanged(bool)), mView, TQT_SLOT(multiplexEnabled(bool)));
|
|
connect (mAuth, TQT_SIGNAL (authChanged(bool)), this, TQT_SLOT(writingEnabled(bool)));
|
|
|
|
TQWhatsThis::add (authIconBox, i18n ("<p>If the lock is closed <img src=\"user|ksysv_locked\"/>, "\
|
|
"you don't have the right " \
|
|
"<strong>permissions</strong> to edit the init configuration.</p>" \
|
|
"<p>Either restart %1 as root (or another more privileged user), " \
|
|
"or ask your sysadmin to install %1 <em>suid</em> or " \
|
|
"<em>sgid</em>.</p><p>The latter way is <strong>not</strong> "\
|
|
"recommended though, due to security issues.</p>")
|
|
.arg (kapp->aboutData()->programName()).arg(kapp->aboutData()->programName()));
|
|
|
|
authIconBox->setMinimumSize (authIconBox->minimumSizeHint());
|
|
visBox->setMinimumSize (visBox->minimumSizeHint());
|
|
|
|
status->addWidget (authIconBox, 0, false);
|
|
status->insertItem ("", Status::Changed, 100);
|
|
status->addWidget (visBox, 0, true);
|
|
|
|
status->setItemAlignment (Status::Changed, AlignLeft|AlignVCenter);
|
|
}
|
|
|
|
void KSVTopLevel::slotShowConfig()
|
|
{
|
|
if (!mPreferences)
|
|
{
|
|
mPreferences = KSVPreferences::self();
|
|
|
|
connect (mPreferences, TQT_SIGNAL (updateColors ()),
|
|
this, TQT_SLOT (updateColors ()));
|
|
|
|
connect (mPreferences, TQT_SIGNAL (updateServicesPath ()),
|
|
this, TQT_SLOT (updateServicesPath ()));
|
|
|
|
connect (mPreferences, TQT_SIGNAL (updateRunlevelsPath ()),
|
|
this, TQT_SLOT (updateRunlevelsPath ()));
|
|
|
|
connect (mPreferences, TQT_SIGNAL (updateFonts ()),
|
|
mView, TQT_SLOT (repaintRunlevels ()));
|
|
}
|
|
|
|
// mPreferences->setInitialSize (TQSize (400,300), true);
|
|
mPreferences->exec();
|
|
}
|
|
|
|
void KSVTopLevel::updateColors ()
|
|
{
|
|
ksv::serviceCompletion ()->clear ();
|
|
|
|
mView->setColors (mConfig->newNormalColor(),
|
|
mConfig->newSelectedColor(),
|
|
mConfig->changedNormalColor(),
|
|
mConfig->changedSelectedColor());
|
|
}
|
|
|
|
void KSVTopLevel::updateServicesPath ()
|
|
{
|
|
mView->updateServicesAfterChange (mConfig->scriptPath());
|
|
mAuth->setServicesPath (mConfig->scriptPath());
|
|
}
|
|
|
|
void KSVTopLevel::updateRunlevelsPath ()
|
|
{
|
|
mView->updateRunlevelsAfterChange ();
|
|
mAuth->setRunlevelPath (mConfig->runlevelPath());
|
|
}
|
|
|
|
void KSVTopLevel::slotReadConfig() {
|
|
setLog(mConfig->showLog());
|
|
}
|
|
|
|
void KSVTopLevel::toggleLog() {
|
|
const bool value = !mConfig->showLog();
|
|
setLog(value);
|
|
}
|
|
|
|
void KSVTopLevel::saveOptions()
|
|
{
|
|
mConfig->writeSettings();
|
|
}
|
|
|
|
void KSVTopLevel::slotUpdateRunning (const TQString& text)
|
|
{
|
|
statusBar()->changeItem(text, Status::Changed);
|
|
}
|
|
|
|
void KSVTopLevel::editCut() {
|
|
KSVDragList* list = mView->getOrigin();
|
|
|
|
if (list && list->currentItem())
|
|
{
|
|
KSVDrag* mime = new KSVDrag (*list->currentItem()->data(), 0L, 0L);
|
|
kapp->clipboard()->setData (mime);
|
|
|
|
KSVData data = *list->currentItem()->data();
|
|
delete list->currentItem();
|
|
|
|
mUndoList->push (new RemoveAction (list, &data));
|
|
setChanged (true);
|
|
}
|
|
}
|
|
|
|
void KSVTopLevel::editCopy()
|
|
{
|
|
KSVDragList* list = mView->getOrigin();
|
|
|
|
if (list)
|
|
{
|
|
KSVDrag* mime = new KSVDrag (*static_cast<KSVItem*> (list->currentItem()), 0L, 0L);
|
|
kapp->clipboard()->setData (mime);
|
|
}
|
|
}
|
|
|
|
void KSVTopLevel::editPaste()
|
|
{
|
|
KSVDragList* list = mView->getOrigin();
|
|
|
|
if (list)
|
|
{
|
|
KSVData data;
|
|
|
|
if (KSVDrag::decodeNative (kapp->clipboard()->data(), data))
|
|
{
|
|
KSVAction* action = 0L;
|
|
|
|
if (list->insert (data, list->currentItem(), action))
|
|
{
|
|
setChanged (true);
|
|
mUndoList->push (new AddAction (list, list->match (data)->data()));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
qFatal("Bug: could not get origin of \"Paste\" event.\n" \
|
|
"Please notify the maintainer of this program,\n" \
|
|
"Peter Putzer <putzer@kde.org>.");
|
|
}
|
|
|
|
void KSVTopLevel::setChanged (bool val)
|
|
{
|
|
mChanged = val;
|
|
setCaption(val);
|
|
|
|
mFileRevert->setEnabled (val);
|
|
mFileSave->setEnabled (val);
|
|
|
|
// update statusbar
|
|
statusBar()->changeItem(val ? i18n(" Changed") : TQString(), Status::Changed);
|
|
|
|
// clear messages
|
|
statusBar()->clear();
|
|
}
|
|
|
|
void KSVTopLevel::properties()
|
|
{
|
|
KSVDragList* list = mView->getOrigin();
|
|
|
|
if (list)
|
|
mView->infoOnData(list->currentItem());
|
|
}
|
|
|
|
void KSVTopLevel::scriptProperties()
|
|
{
|
|
KSVDragList* list = mView->getOrigin();
|
|
|
|
if (list)
|
|
mView->slotScriptProperties(list->currentItem());
|
|
}
|
|
|
|
void KSVTopLevel::editUndo ()
|
|
{
|
|
KSVAction* action = mUndoList->top();
|
|
|
|
mUndoList->undoLast();
|
|
|
|
mRedoList->push (action);
|
|
}
|
|
|
|
void KSVTopLevel::editRedo ()
|
|
{
|
|
KSVAction* action = mRedoList->top();
|
|
|
|
mRedoList->redoLast();
|
|
|
|
setChanged (true);
|
|
mUndoList->push (action);
|
|
}
|
|
|
|
void KSVTopLevel::setPaste (bool val)
|
|
{
|
|
mEditPaste->setEnabled (val);
|
|
mPasteAppend->setEnabled (val);
|
|
}
|
|
|
|
void KSVTopLevel::setLog (bool val)
|
|
{
|
|
mConfig->setShowLog(val);
|
|
|
|
mOptionsToggleLog->setChecked (val);
|
|
|
|
mView->setDisplayScriptOutput(val);
|
|
}
|
|
|
|
void KSVTopLevel::writingEnabled (bool on)
|
|
{
|
|
mFileLoad->setEnabled(on);
|
|
}
|
|
|
|
void KSVTopLevel::print()
|
|
{
|
|
// #define checkPage if (metrics.height() - y < fm.lineSpacing()) prt.newPage();
|
|
|
|
// static KPrinter prt;
|
|
// prt.setDocName(kapp->aboutData()->programName() + " Configuration");
|
|
// prt.setCreator(kapp->aboutData()->programName());
|
|
|
|
// static TQPrintDialog* dlg = new TQPrintDialog (&prt, this, "KSysV Print Dialog");
|
|
// dlg->setCaption(kapp->makeStdCaption (i18n("Print")));
|
|
|
|
// if (dlg->exec() == TQDialog::Accepted)
|
|
// {
|
|
// int y = 10;
|
|
// TQPainter p;
|
|
// p.begin( &prt );
|
|
|
|
// TQPaintDeviceMetrics metrics (&prt);
|
|
|
|
// p.setFont (TQFont("courier", 20, TQFont::Bold));
|
|
// TQFontMetrics fm = p.fontMetrics();
|
|
|
|
// p.drawText (10, y, i18n("%1 Configuration of %2")
|
|
// .arg (kapp->aboutData()->programName())
|
|
// .arg (ksv::hostname()));
|
|
// y += fm.lineSpacing();
|
|
|
|
// p.drawText (10, y, TQDateTime::currentDateTime().toString());
|
|
// y += fm.lineSpacing() * 2; // an extra empty line
|
|
|
|
// for (int i = 0; i < ksv::runlevelNumber; ++i)
|
|
// {
|
|
// p.setFont (TQFont("courier", 16, TQFont::Bold));
|
|
// TQFontMetrics fm = p.fontMetrics();
|
|
|
|
// p.drawText (10, y, i18n ("Runlevel %1").arg(i));
|
|
// y += fm.lineSpacing();
|
|
|
|
// checkPage
|
|
|
|
// p.drawText (10, y, i18n ("Started Services"));
|
|
// y += fm.lineSpacing() * 2; // an extra empty line
|
|
|
|
// checkPage
|
|
|
|
// p.setFont (TQFont("courier", 10));
|
|
// fm = p.fontMetrics();
|
|
|
|
// for (TQListViewItemIterator it (mView->startRL[i]);
|
|
// it.current();
|
|
// ++it)
|
|
// {
|
|
// KSVItem* item = static_cast<KSVItem*> (it.current());
|
|
|
|
// y += fm.ascent();
|
|
// p.drawText (10, y, item->toString());
|
|
// y += fm.descent();
|
|
|
|
// checkPage
|
|
|
|
// }
|
|
|
|
// p.setFont (TQFont("courier", 16, TQFont::Bold));
|
|
// fm = p.fontMetrics();
|
|
// y += fm.lineSpacing(); // an extra empty line
|
|
// p.drawText (10, y, i18n ("Stopped Services"));
|
|
// y += fm.lineSpacing() * 2; // an extra empty line
|
|
|
|
// checkPage
|
|
|
|
// p.setFont (TQFont("courier", 10));
|
|
// fm = p.fontMetrics();
|
|
|
|
// for (TQListViewItemIterator it (mView->stopRL[i]);
|
|
// it.current();
|
|
// ++it)
|
|
// {
|
|
// KSVItem* item = static_cast<KSVItem*> (it.current());
|
|
// checkPage
|
|
|
|
// y += fm.ascent();
|
|
// p.drawText (10, y, item->toString());
|
|
// y += fm.descent();
|
|
// }
|
|
// checkPage
|
|
|
|
// p.setFont (TQFont("courier", 16, TQFont::Bold));
|
|
// fm = p.fontMetrics();
|
|
// y += fm.lineSpacing() * 3; // two extra empty line
|
|
// }
|
|
// // TQStringList lines = TQStringList::split ('\n', mView->log(), true);
|
|
// // for(TQStringList::Iterator it = lines.begin();
|
|
// // it != lines.end();
|
|
// // ++it)
|
|
// // {
|
|
// // y += fm.ascent();
|
|
|
|
// // TQString line = *it;
|
|
// // if (line.isNull())
|
|
// // line = " ";
|
|
|
|
// // line.replace( TQRegExp("\t"), " " );
|
|
|
|
// // strncpy(buf,line.data(),160);
|
|
|
|
// // for (int j = 0 ; j <150; j++)
|
|
// // {
|
|
// // if (!isprint(buf[j]))
|
|
// // buf[j] = ' ';
|
|
// // }
|
|
|
|
// // buf[line.length()] = '\0';
|
|
// // p.drawText( 10, y, buf );
|
|
// // y += fm.descent();
|
|
// // }
|
|
|
|
// p.end();
|
|
// }
|
|
}
|
|
|
|
void KSVTopLevel::printLog()
|
|
{
|
|
KPrinter *prt = new KPrinter();
|
|
prt->setDocName(kapp->aboutData()->programName() + " Log File");
|
|
prt->setCreator(kapp->aboutData()->programName());
|
|
|
|
if (prt->setup(this, i18n("Print Log File")))
|
|
{
|
|
KBusyManager::self()->setBusy (true);
|
|
|
|
TQPainter p (prt);
|
|
TQPaintDeviceMetrics pm (prt);
|
|
const int height = pm.height();
|
|
const int width = pm.width();
|
|
|
|
TQStringList lines = TQStringList::split ('\n', mView->xmlLog(), true);
|
|
TQStringList::Iterator line = lines.begin();
|
|
|
|
int y = 0;
|
|
|
|
{
|
|
TQSimpleRichText rheading (i18n("<h1>KDE Sys-V Init Editor Log</h1>"),
|
|
TQFont("times"), TQString(), ksv::styleSheet(),
|
|
TQMimeSourceFactory::defaultFactory());
|
|
rheading.setWidth (&p, width);
|
|
int tmp_h = rheading.height();
|
|
TQRegion region (0, y, width, tmp_h);
|
|
rheading.draw (&p, 0, y, region, colorGroup(), 0L);
|
|
|
|
y += tmp_h;
|
|
|
|
TQSimpleRichText rdate (i18n("<h3>Printed on %1</h3><br/><br/>").arg(KGlobal::locale()->formatDateTime(TQDateTime::currentDateTime())),
|
|
TQFont("times"), TQString(), ksv::styleSheet(),
|
|
TQMimeSourceFactory::defaultFactory());
|
|
rdate.setWidth (&p, width);
|
|
tmp_h = rdate.height();
|
|
TQRegion r2 (0, y, width, tmp_h);
|
|
rdate.draw (&p, 0, y, r2, colorGroup(), 0L);
|
|
|
|
y += tmp_h;
|
|
}
|
|
|
|
while (line != lines.end())
|
|
{
|
|
while (y < height)
|
|
{
|
|
TQSimpleRichText rich (*line, TQFont("times"), TQString(), ksv::styleSheet(),
|
|
TQMimeSourceFactory::defaultFactory());
|
|
rich.setWidth (&p, width);
|
|
|
|
int tmp_h = rich.height();
|
|
if (y + tmp_h > height)
|
|
break;
|
|
|
|
TQRegion region (0, y, width, tmp_h);
|
|
rich.draw (&p, 0, y, region, colorGroup(), 0L);
|
|
|
|
y += tmp_h;
|
|
++line;
|
|
|
|
if (line == lines.end())
|
|
goto printing_finished;
|
|
|
|
kapp->processEvents();
|
|
}
|
|
|
|
prt->newPage();
|
|
y = 0;
|
|
}
|
|
|
|
printing_finished:
|
|
|
|
p.end();
|
|
|
|
KBusyManager::self()->restore();
|
|
delete prt;
|
|
}
|
|
}
|
|
|
|
void KSVTopLevel::catchCannotGenerateNumber()
|
|
{
|
|
if (mConfig->showMessage (ksv::CouldNotGenerateSortingNumber)) {
|
|
KMessageBox::information (kapp->mainWidget(),
|
|
i18n ("<p>Unable to generate a valid " \
|
|
"sorting number for this position. This means " \
|
|
"that there was no number available between "\
|
|
"the two adjacent services, and the service " \
|
|
"did not fit in lexically.</p>" \
|
|
"<p>Please adjust the sorting numbers manually "\
|
|
"via the <strong>Properties dialog box</strong>.</p>"),
|
|
i18n ("Unable to Generate Sorting Number"),
|
|
ksv::notifications[ksv::CouldNotGenerateSortingNumber]);
|
|
}
|
|
|
|
statusBar()->message (i18n ("Unable to generate sorting number. Please change manually."),
|
|
5000);
|
|
}
|
|
|
|
void KSVTopLevel::closeEvent (TQCloseEvent* e)
|
|
{
|
|
if (KBusyManager::self()->isBusy())
|
|
{
|
|
// do not allow a close during clearing => otherwise we get a segfault
|
|
e->ignore();
|
|
return;
|
|
}
|
|
|
|
KMainWindow::closeEvent (e);
|
|
}
|
|
|
|
void KSVTopLevel::dispatchEdit ()
|
|
{
|
|
KSVDragList* list = mView->getOrigin();
|
|
|
|
if (!list)
|
|
{
|
|
mEditCopy->setEnabled (false);
|
|
mEditCut->setEnabled (false);
|
|
mEditProperties->setEnabled (false);
|
|
setPaste (false);
|
|
|
|
return;
|
|
}
|
|
|
|
KSVItem* current = list->currentItem();
|
|
|
|
if (current) // there's a list, and it's got items...
|
|
{
|
|
mEditCopy->setEnabled (true);
|
|
mEditCut->setEnabled (true);
|
|
mEditProperties->setEnabled (true);
|
|
}
|
|
else // no current item
|
|
{
|
|
mEditCopy->setEnabled (false);
|
|
mEditCut->setEnabled (false);
|
|
mEditProperties->setEnabled (false);
|
|
}
|
|
|
|
if (mView->scripts == list)
|
|
{
|
|
mEditCut->setEnabled (false);
|
|
setPaste (false);
|
|
}
|
|
else
|
|
{
|
|
TQMimeSource* mime = kapp->clipboard()->data();
|
|
|
|
if (mime && mime->provides ("application/x-ksysv"))
|
|
setPaste (true);
|
|
else
|
|
setPaste (false);
|
|
}
|
|
}
|
|
|
|
void KSVTopLevel::enableUndo()
|
|
{
|
|
mEditUndo->setEnabled (true);
|
|
}
|
|
|
|
void KSVTopLevel::disableUndo()
|
|
{
|
|
mEditUndo->setEnabled (false);
|
|
setChanged(false);
|
|
}
|
|
|
|
void KSVTopLevel::enableRedo()
|
|
{
|
|
mEditRedo->setEnabled (true);
|
|
}
|
|
|
|
void KSVTopLevel::disableRedo ()
|
|
{
|
|
mEditRedo->setEnabled (false);
|
|
}
|
|
|
|
void KSVTopLevel::slotSaveLog()
|
|
{
|
|
static const TQString& filter = ksv::logFileFilter();
|
|
static const TQString& ext = ksv::logFileExtension();
|
|
TQString filename = KFileDialog::getSaveFileName(0L, filter, this);
|
|
|
|
if (filename.isEmpty())
|
|
return;
|
|
else if (filename.right(ext.length()) != ext)
|
|
filename += ext;
|
|
|
|
TQFile file(filename);
|
|
|
|
file.open( IO_WriteOnly | IO_Raw );
|
|
TQTextStream s(&file);
|
|
|
|
s << "KDE System V Init Editor"
|
|
<< endl
|
|
<< TQDateTime::currentDateTime().toString()
|
|
<< endl << endl
|
|
<< mView->log()
|
|
<< endl;
|
|
|
|
file.close();
|
|
}
|
|
|
|
void KSVTopLevel::enableLogActions ()
|
|
{
|
|
mFileSaveLog->setEnabled (true);
|
|
mFilePrintLog->setEnabled (true); // disabled due to complexity
|
|
}
|
|
|
|
void KSVTopLevel::setCaption (bool changed)
|
|
{
|
|
setPlainCaption (kapp->makeStdCaption(KNetwork::KResolver::localHostName(), true, changed));
|
|
}
|
|
|
|
KActionCollection* KSVTopLevel::filteredActions ()
|
|
{
|
|
// remove unwanted (internal) actions
|
|
static KActionCollection coll = *actionCollection();
|
|
static bool initialized = false;
|
|
|
|
if (!initialized)
|
|
{
|
|
coll.take(mPasteAppend);
|
|
coll.take(mOpenDefault);
|
|
initialized = true;
|
|
}
|
|
|
|
return &coll;
|
|
}
|
|
|
|
void KSVTopLevel::configureKeys ()
|
|
{
|
|
KKeyDialog::configure (filteredActions(), this, true);
|
|
}
|
|
|
|
void KSVTopLevel::configureToolbars ()
|
|
{
|
|
KEditToolbar dlg(filteredActions(), xmlFile(), true, this);
|
|
connect(&dlg, TQT_SIGNAL( newToolbarConfig() ), this, TQT_SLOT( slotNewToolbarConfig() ));
|
|
dlg.exec();
|
|
}
|
|
|
|
void KSVTopLevel::slotNewToolbarConfig()
|
|
{
|
|
createGUI (xmlFile());
|
|
}
|
|
|
|
void KSVTopLevel::dispatchEditService (bool val)
|
|
{
|
|
mToolsEditService->setChecked (val);
|
|
}
|
|
|
|
void KSVTopLevel::dispatchStartService (bool val)
|
|
{
|
|
mToolsStartService->setChecked (val);
|
|
}
|
|
|
|
void KSVTopLevel::dispatchStopService (bool val)
|
|
{
|
|
mToolsStopService->setChecked (val);
|
|
}
|
|
|
|
void KSVTopLevel::dispatchRestartService (bool val)
|
|
{
|
|
mToolsRestartService->setChecked (val);
|
|
}
|
|
|
|
void KSVTopLevel::pasteAppend ()
|
|
{
|
|
mView->pasteAppend ();
|
|
}
|
|
|
|
void KSVTopLevel::editService ()
|
|
{
|
|
mView->editService ();
|
|
}
|
|
|
|
void KSVTopLevel::toggleRunlevel (int index)
|
|
{
|
|
bool state = mVisible[index]->isChecked();
|
|
|
|
if (state)
|
|
mView->showRunlevel (index);
|
|
else
|
|
mView->hideRunlevel (index);
|
|
|
|
mConfig->setShowRunlevel (index, state);
|
|
}
|
|
|
|
void KSVTopLevel::saveAs ()
|
|
{
|
|
static const TQString& filter = ksv::nativeFileFilter();
|
|
static const TQString& ext = ksv::nativeFileExtension();
|
|
TQString filename = KFileDialog::getSaveFileName(0L, filter, this);
|
|
|
|
if (filename.isEmpty())
|
|
return;
|
|
else if (filename.right(ext.length()) != ext)
|
|
filename += ext;
|
|
|
|
TQFile file(filename);
|
|
// we're busy
|
|
KBusyManager::self()->setBusy (true);
|
|
|
|
file.open (IO_WriteOnly | IO_Raw);
|
|
TQDataStream s (&file);
|
|
|
|
if (ksv::IO::saveConfiguration (s, mView->startRL, mView->stopRL))
|
|
{
|
|
statusBar()->message(i18n("Configuration package saved successfully."), 5000);
|
|
}
|
|
else
|
|
{
|
|
kdDebug(3000) << "ERROR saving file" << endl;
|
|
}
|
|
|
|
file.close();
|
|
|
|
KBusyManager::self()->restore();
|
|
}
|
|
|
|
void KSVTopLevel::load ()
|
|
{
|
|
static const TQString& filter = ksv::nativeFileFilter();
|
|
TQString filename = KFileDialog::getOpenFileName(0L, filter, this);
|
|
|
|
if (filename.isEmpty())
|
|
return;
|
|
|
|
TQFile file(filename);
|
|
KBusyManager::self()->setBusy (true);
|
|
|
|
file.open (IO_ReadOnly | IO_Raw);
|
|
TQDataStream s (&file);
|
|
TQValueList<KSVData>* startLists = new TQValueList<KSVData>[ksv::runlevelNumber];
|
|
TQValueList<KSVData>* stopLists = new TQValueList<KSVData>[ksv::runlevelNumber];
|
|
|
|
if (ksv::IO::loadSavedConfiguration (s, startLists, stopLists))
|
|
{
|
|
statusBar()->message(i18n("Configuration package loaded successfully."), 5000);
|
|
mView->mergeLoadedPackage (startLists, stopLists);
|
|
}
|
|
else
|
|
{
|
|
kdDebug (3000) << "ERROR loading file" << endl;
|
|
}
|
|
|
|
file.close();
|
|
|
|
delete[] startLists;
|
|
delete[] stopLists;
|
|
|
|
KBusyManager::self()->restore();
|
|
}
|
|
|
|
void KSVTopLevel::pushUndoAction (KSVAction* action)
|
|
{
|
|
mRedoList->clear();
|
|
mUndoList->push (action);
|
|
|
|
setChanged(true);
|
|
}
|
|
|
|
#include "TopWidget.moc"
|