/* 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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 #include namespace tqStatus { enum { Changed, Checklist, Writable }; } // namespace tqStatus 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 ("

Click on the checkboxes to show or "\ "hide runlevels.

" \ "

The list of currently visible runlevels is saved "\ "when you use the Save Options command.

")); 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 ("

If the lock is closed , "\ "you don't have the right " \ "permissions to edit the init configuration.

" \ "

Either restart %1 as root (or another more privileged user), " \ "or ask your sysadmin to install %1 suid or " \ "sgid.

The latter way is not "\ "recommended though, due to security issues.

") .tqarg (kapp->aboutData()->programName()).tqarg(kapp->aboutData()->programName())); authIconBox->setMinimumSize (authIconBox->tqminimumSizeHint()); visBox->setMinimumSize (visBox->tqminimumSizeHint()); status->addWidget (authIconBox, 0, false); status->insertItem ("", tqStatus::Changed, 100); status->addWidget (visBox, 0, true); status->setItemAlignment (tqStatus::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, tqStatus::Changed); } void KSVTopLevel::editCut() { KSVDragList* list = mView->getOrigin(); if (list && list->currentItem()) { KSVDrag* mime = new KSVDrag (*list->currentItem()->data(), 0L, 0L); kapp->tqclipboard()->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 (list->currentItem()), 0L, 0L); kapp->tqclipboard()->setData (mime); } } void KSVTopLevel::editPaste() { KSVDragList* list = mView->getOrigin(); if (list) { KSVData data; if (KSVDrag::decodeNative (kapp->tqclipboard()->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 ."); } void KSVTopLevel::setChanged (bool val) { mChanged = val; setCaption(val); mFileRevert->setEnabled (val); mFileSave->setEnabled (val); // update statusbar statusBar()->changeItem(val ? i18n(" Changed") : TQString(), tqStatus::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::tqcurrentDateTime().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").tqarg(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 (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 (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("

KDE Sys-V Init Editor Log

"), 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, tqcolorGroup(), 0L); y += tmp_h; TQSimpleRichText rdate (i18n("

Printed on %1



").tqarg(KGlobal::locale()->formatDateTime(TQDateTime::tqcurrentDateTime())), 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, tqcolorGroup(), 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, tqcolorGroup(), 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 ("

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.

" \ "

Please adjust the sorting numbers manually "\ "via the Properties dialog box.

"), 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->tqclipboard()->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::tqcurrentDateTime().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* startLists = new TQValueList[ksv::runlevelNumber]; TQValueList* stopLists = new TQValueList[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"