summaryrefslogtreecommitdiffstats
path: root/ksysv
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit37333bf25ad9a4c538250f5af2f9f1d666362883 (patch)
treec45e8df5b9efbffe07eb3d9340df7811c7e16943 /ksysv
downloadtdeadmin-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')
-rw-r--r--ksysv/AUTHORS17
-rw-r--r--ksysv/ActionList.cpp217
-rw-r--r--ksysv/ActionList.h131
-rw-r--r--ksysv/Data.cpp190
-rw-r--r--ksysv/Data.h79
-rw-r--r--ksysv/IOCore.cpp291
-rw-r--r--ksysv/IOCore.h64
-rw-r--r--ksysv/Makefile.am84
-rw-r--r--ksysv/OldView.cpp1150
-rw-r--r--ksysv/OldView.h179
-rw-r--r--ksysv/PreferencesDialog.cpp291
-rw-r--r--ksysv/PreferencesDialog.h68
-rw-r--r--ksysv/Properties.cpp209
-rw-r--r--ksysv/Properties.h110
-rw-r--r--ksysv/README33
-rw-r--r--ksysv/RunlevelAuthIcon.cpp149
-rw-r--r--ksysv/RunlevelAuthIcon.h49
-rw-r--r--ksysv/ServiceDlg.cpp123
-rw-r--r--ksysv/ServiceDlg.h56
-rw-r--r--ksysv/SpinBox.cpp87
-rw-r--r--ksysv/SpinBox.h32
-rw-r--r--ksysv/TODO7
-rw-r--r--ksysv/TopWidget.cpp1109
-rw-r--r--ksysv/TopWidget.h153
-rw-r--r--ksysv/configure.in.in11
-rw-r--r--ksysv/configwizard.ui626
-rwxr-xr-xksysv/genui.sh25
-rw-r--r--ksysv/hi16-app-ksysv.pngbin0 -> 663 bytes
-rw-r--r--ksysv/hi22-app-ksysv.pngbin0 -> 1033 bytes
-rw-r--r--ksysv/hi32-app-ksysv.pngbin0 -> 1542 bytes
-rw-r--r--ksysv/hi48-app-ksysv.pngbin0 -> 2614 bytes
-rw-r--r--ksysv/kbusymanager.cpp94
-rw-r--r--ksysv/kbusymanager.h49
-rw-r--r--ksysv/kdltooltip.cpp95
-rw-r--r--ksysv/kdltooltip.h43
-rw-r--r--ksysv/kscroller.cpp191
-rw-r--r--ksysv/kscroller.h150
-rw-r--r--ksysv/ksv_conf.cpp224
-rw-r--r--ksysv/ksv_conf.h143
-rw-r--r--ksysv/ksv_core.cpp186
-rw-r--r--ksysv/ksv_core.h58
-rw-r--r--ksysv/ksv_service.cpp76
-rw-r--r--ksysv/ksv_service.h99
-rw-r--r--ksysv/ksvapplication.cpp20
-rw-r--r--ksysv/ksvapplication.h19
-rw-r--r--ksysv/ksvconfigwizard.cpp150
-rw-r--r--ksysv/ksvconfigwizard.h66
-rw-r--r--ksysv/ksvdrag.cpp102
-rw-r--r--ksysv/ksvdrag.h36
-rw-r--r--ksysv/ksvdraglist.cpp802
-rw-r--r--ksysv/ksvdraglist.h277
-rw-r--r--ksysv/ksvlookandfeel.cpp93
-rw-r--r--ksysv/ksvlookandfeel.h39
-rw-r--r--ksysv/ksvmiscconfig.cpp64
-rw-r--r--ksysv/ksvmiscconfig.h47
-rw-r--r--ksysv/ksvpathconfig.cpp75
-rw-r--r--ksysv/ksvpathconfig.h49
-rw-r--r--ksysv/ksysv.desktop72
-rw-r--r--ksysv/ksysvui.rc96
-rw-r--r--ksysv/leveldb.c353
-rw-r--r--ksysv/leveldb.h50
-rw-r--r--ksysv/lookandfeelconfig.ui500
-rw-r--r--ksysv/main.cpp103
-rw-r--r--ksysv/miscconfig.ui186
-rw-r--r--ksysv/pathconfig.ui294
-rw-r--r--ksysv/pics/Makefile.am7
-rw-r--r--ksysv/pics/ksysv_locked.pngbin0 -> 928 bytes
-rw-r--r--ksysv/pics/ksysv_restart.pngbin0 -> 157 bytes
-rw-r--r--ksysv/pics/ksysv_start.pngbin0 -> 213 bytes
-rw-r--r--ksysv/pics/ksysv_stop.pngbin0 -> 216 bytes
-rw-r--r--ksysv/pics/ksysv_unlocked.pngbin0 -> 1009 bytes
-rw-r--r--ksysv/pics/stop.pngbin0 -> 821 bytes
-rw-r--r--ksysv/toolbar/Makefile.am1
-rw-r--r--ksysv/toolbar/cr16-action-toggle_log.pngbin0 -> 1111 bytes
-rw-r--r--ksysv/trash.cpp141
-rw-r--r--ksysv/trash.h66
-rw-r--r--ksysv/version.h32
-rw-r--r--ksysv/x-ksysv-log.desktop68
-rw-r--r--ksysv/x-ksysv.desktop78
79 files changed, 10834 insertions, 0 deletions
diff --git a/ksysv/AUTHORS b/ksysv/AUTHORS
new file mode 100644
index 0000000..a2a59a9
--- /dev/null
+++ b/ksysv/AUTHORS
@@ -0,0 +1,17 @@
+Current Code
+============
+
+Main developer:
+Peter Putzer <putzer@kde.org>
+
+leveldb.{h,c} (from chkconfig):
+Red Hat Software http://www.redhat.com
+
+Previous Versions
+=================
+
+IPC (stuff taken from kdehelp):
+Martin Jones
+
+Printing (stuff taken from kedit):
+Bernd Johannes Wuebben
diff --git a/ksysv/ActionList.cpp b/ksysv/ActionList.cpp
new file mode 100644
index 0000000..a2e2de8
--- /dev/null
+++ b/ksysv/ActionList.cpp
@@ -0,0 +1,217 @@
+/***************************************************************************
+ begin : Sun Oct 3 1999
+ copyright : (C) 1999 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. *
+ * *
+ ***************************************************************************/
+
+#include <qapplication.h>
+#include "ksvdraglist.h"
+#include "ActionList.h"
+
+//////////////////////////////////
+// Action //
+//////////////////////////////////
+
+KSVAction::KSVAction()
+{
+}
+
+KSVAction::~KSVAction()
+{
+ // default - shouldnt be used normally (pure virtual declaration)
+}
+
+SimpleAction::SimpleAction (KSVDragList* s, const KSVData* i)
+ : KSVAction(),
+ mSource (s),
+ mItem (new KSVData (*i))
+{
+}
+
+SimpleAction::~SimpleAction()
+{
+ delete mItem;
+}
+
+ChangeAction::ChangeAction (KSVDragList* s, const KSVData* oldS, const KSVData* newS)
+ : SimpleAction (s, oldS),
+ mNew (new KSVData (*newS))
+{
+ source()->addToRMList (*oldState());
+}
+
+ChangeAction::~ChangeAction()
+{
+ delete mNew;
+}
+
+void ChangeAction::redo ()
+{
+ source()->addToRMList(*oldState());
+ source()->match (*oldState())->copy (*newState());
+ source()->sort();
+}
+
+void ChangeAction::undo()
+{
+ source()->removeFromRMList(*oldState());
+ source()->match(*newState())->copy (*oldState());
+ source()->sort();
+}
+
+AddAction::AddAction (KSVDragList* s, const KSVData* i)
+ : SimpleAction(s, i)
+{
+}
+
+AddAction::~AddAction()
+{
+}
+
+void AddAction::redo ()
+{
+ new KSVItem (source(), *item());
+}
+
+void AddAction::undo()
+{
+ delete source()->match(*item());
+}
+
+RemoveAction::RemoveAction (KSVDragList* s, const KSVData* i)
+ : SimpleAction(s, i)
+{
+ source()->addToRMList (*item());
+}
+
+RemoveAction::~RemoveAction()
+{
+}
+
+void RemoveAction::redo()
+{
+ source()->addToRMList(*item());
+
+ delete source()->match (*item());
+}
+
+void RemoveAction::undo()
+{
+ source()->removeFromRMList(*item());
+
+ new KSVItem (source(), *item());
+}
+
+CompoundAction::CompoundAction (KSVAction** a, int nr)
+ : mActions (new KSVAction* [nr]),
+ mCount (nr)
+{
+ memcpy (mActions, a, sizeof(KSVAction*) * nr);
+}
+
+CompoundAction::~CompoundAction()
+{
+ for (int i=0; i < mCount; ++i)
+ {
+ delete mActions[i];
+ }
+
+ delete[] mActions;
+}
+
+void CompoundAction::redo ()
+{
+ for (int i=0; i < mCount; ++i)
+ {
+ mActions[i]->redo();
+ }
+}
+
+void CompoundAction::undo()
+{
+ for (int i=0; i < mCount; ++i)
+ {
+ mActions[i]->undo();
+ }
+}
+
+//////////////////////////////////
+// ActionList //
+//////////////////////////////////
+
+ActionList::ActionList (QObject* parent, const char* name)
+ : QObject(parent, name)
+{
+ setAutoDelete(false);
+}
+
+ActionList::~ActionList()
+{
+}
+
+void ActionList::undoLast()
+{
+ if (!count())
+ return;
+
+ KSVAction* a = QPtrStack<KSVAction>::pop();
+ a->undo();
+
+ emit undone();
+
+ if (!count())
+ emit empty();
+}
+
+void ActionList::undoAll()
+{
+ while (count())
+ undoLast();
+}
+
+void ActionList::redoLast()
+{
+ if (!count())
+ return;
+
+ KSVAction* a = QPtrStack<KSVAction>::pop();
+ a->redo();
+
+ emit undone();
+
+ if (!count())
+ emit empty();
+}
+
+void ActionList::redoAll()
+{
+ while (count())
+ redoLast();
+}
+
+void ActionList::push (KSVAction* a)
+{
+ QPtrStack<KSVAction>::push(a);
+
+ if (count() == 1)
+ emit filled();
+}
+
+void ActionList::clear()
+{
+ setAutoDelete (true);
+ QPtrStack<KSVAction>::clear();
+ setAutoDelete (false);
+
+ emit empty();
+}
+
+#include "ActionList.moc"
diff --git a/ksysv/ActionList.h b/ksysv/ActionList.h
new file mode 100644
index 0000000..f420b48
--- /dev/null
+++ b/ksysv/ActionList.h
@@ -0,0 +1,131 @@
+/***************************************************************************
+ begin : Sun Oct 3 1999
+ copyright : (C) 1997-99 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef KSV_ACTIONLIST_H
+#define KSV_ACTIONLIST_H
+
+#include <qptrstack.h>
+#include <qobject.h>
+
+class KSVData;
+class KSVDragList;
+
+class KSVAction
+{
+public:
+ KSVAction ();
+ virtual ~KSVAction () = 0;
+
+ virtual void undo () = 0;
+ virtual void redo() = 0;
+
+private:
+ const KSVAction& operator= (const KSVAction&); // undefined
+ KSVAction (const KSVAction&); // undefined
+};
+
+class SimpleAction : public KSVAction
+{
+public:
+ SimpleAction (KSVDragList* source, const KSVData* item);
+ virtual ~SimpleAction();
+
+ inline KSVDragList* source() { return mSource; }
+ inline KSVData* item() { return mItem; }
+
+ virtual void undo() = 0;
+ virtual void redo() = 0;
+
+private:
+ KSVDragList* mSource;
+ KSVData* mItem;
+};
+
+class RemoveAction : public SimpleAction
+{
+public:
+ RemoveAction (KSVDragList* s, const KSVData* i);
+ virtual ~RemoveAction();
+
+ virtual void undo();
+ virtual void redo();
+};
+
+class AddAction : public SimpleAction
+{
+public:
+ AddAction (KSVDragList* s, const KSVData* i);
+ virtual ~AddAction();
+
+ virtual void undo();
+ virtual void redo();
+};
+
+class ChangeAction : public SimpleAction
+{
+public:
+ ChangeAction (KSVDragList* s, const KSVData* oldState, const KSVData* newState);
+ virtual ~ChangeAction();
+
+ virtual void undo();
+ virtual void redo();
+
+ inline KSVData* newState() { return mNew; }
+ inline KSVData* oldState() { return item(); }
+private:
+ KSVData* mNew;
+};
+
+class CompoundAction : public KSVAction
+{
+public:
+ CompoundAction (KSVAction*[], int nr);
+ virtual ~CompoundAction();
+
+ virtual void undo();
+ virtual void redo();
+
+private:
+ KSVAction** mActions;
+ int mCount;
+};
+
+
+
+class ActionList : public QObject, private QPtrStack<KSVAction>
+{
+ Q_OBJECT
+
+public:
+ ActionList (QObject* parent, const char* name);
+ virtual ~ActionList ();
+
+ KSVAction* top () const { return QPtrStack<KSVAction>::top(); }
+
+public slots:
+ void undoLast ();
+ void undoAll ();
+ void redoLast ();
+ void redoAll ();
+ void push (KSVAction*);
+ void clear ();
+
+signals:
+ void undone ();
+ void empty ();
+ void filled ();
+};
+
+#endif
+
diff --git a/ksysv/Data.cpp b/ksysv/Data.cpp
new file mode 100644
index 0000000..caa4a1b
--- /dev/null
+++ b/ksysv/Data.cpp
@@ -0,0 +1,190 @@
+// (c) 2000 Peter Putzer
+
+#include <qdatastream.h>
+#include <kdatastream.h>
+
+#include "Data.h"
+
+KSVData::KSVData ()
+{
+ mNrChanged = mLabelChanged = mFilenameChanged = mOtherChanged = mNewEntry = false;
+ mNr = mOldNr = 0;
+}
+
+KSVData::KSVData (const QString& file, const QString& path,
+ const QString& label, Q_INT8 nr)
+ : mPath (path),
+ mLabel (label), mFilename (file)
+{
+ mNrChanged = mLabelChanged = mFilenameChanged = mOtherChanged = mNewEntry = false;
+ mNr = mOldNr = 0;
+ setNumber (nr);
+ mNrChanged = false;
+}
+
+KSVData::KSVData (const KSVData& rhs)
+ : mPath (rhs.mPath),
+ mLabel (rhs.mLabel),
+ mFilename (rhs.mFilename),
+ mRunlevel (rhs.mRunlevel),
+ mNr (rhs.mNr),
+ mOldLabel (rhs.mOldLabel),
+ mOldFilename (rhs.mOldFilename),
+ mOriginalRunlevel (rhs.mOriginalRunlevel),
+ mOldNr (rhs.mOldNr),
+ mNrChanged (rhs.mNrChanged),
+ mLabelChanged (rhs.mLabelChanged),
+ mOtherChanged (rhs.mOtherChanged),
+ mFilenameChanged (rhs.mFilenameChanged),
+ mNewEntry (rhs.mNewEntry), mNumberString (rhs.mNumberString)
+{
+}
+
+const KSVData& KSVData::operator= (const KSVData& rhs)
+{
+ if (this ==&rhs)
+ return *this;
+
+ mPath = rhs.mPath;
+ mLabel = rhs.mLabel;
+ mFilename = rhs.mFilename;
+ mRunlevel = rhs.mRunlevel;
+ mNr = rhs.mNr;
+
+ mOldLabel = rhs.mOldLabel;
+ mOldFilename = rhs.mOldFilename;
+ mOriginalRunlevel = rhs.mOriginalRunlevel;
+ mOldNr = rhs.mOldNr;
+
+ mNrChanged = rhs.mNrChanged;
+ mLabelChanged = rhs.mLabelChanged;
+ mOtherChanged = rhs.mOtherChanged;
+ mFilenameChanged = rhs.mFilenameChanged;
+ mNewEntry = rhs.mNewEntry;
+
+ mNumberString = rhs.mNumberString;
+
+ return *this;
+}
+
+bool KSVData::operator== (const KSVData& rhs) const
+{
+ return mLabel == rhs.mLabel &&
+ mPath == rhs.mPath && mFilename == rhs.mFilename;
+ // return mPath == rhs.mPath &&
+ // mLabel == rhs.mLabel &&
+ // mFilename == rhs.mFilename &&
+ // mRunlevel == rhs.mRunlevel &&
+ // mNr == rhs.mNr &&
+
+ // mOldLabel == rhs.mOldLabel &&
+ // mOldFilename == rhs.mOldFilename &&
+ // mOriginalRunlevel == rhs.mOriginalRunlevel &&
+ // mOldNr == rhs.mOldNr &&
+
+ // mNrChanged == rhs.mNrChanged &&
+ // mLabelChanged == rhs.mLabelChanged &&
+ // mOtherChanged == rhs.mOtherChanged &&
+ // mFilenameChanged == rhs.mFilenameChanged &&
+ // mNewEntry == rhs.mNewEntry;
+}
+
+bool KSVData::operator< (const KSVData& rhs) const
+{
+ return mNr< rhs.mNr;
+}
+
+void KSVData::setPath (const QString& s)
+{
+ if (mPath != s)
+ mOtherChanged = true;
+
+ mPath = s;
+}
+
+void KSVData::setLabel (const QString& s)
+{
+ if (!mLabelChanged && mLabel != s)
+ {
+ mOldLabel = mLabel;
+ mLabelChanged = true;
+ }
+
+ mLabel = s;
+}
+
+void KSVData::setFilename (const QString& s)
+{
+ if (!mFilenameChanged && mFilename != s)
+ {
+ mOldFilename = mFilename;
+ mFilenameChanged = true;
+ }
+
+ mFilename = s;
+}
+
+void KSVData::setRunlevel (const QString& s)
+{
+ mRunlevel = s;
+}
+
+void KSVData::setNumber (Q_INT8 nr)
+{
+ if (!mNrChanged && mNr != nr)
+ {
+ mOldNr = mNr;
+ mNrChanged = true;
+ }
+
+ mNr = nr;
+ mNumberString.sprintf ("%.2i", nr);
+}
+
+void KSVData::setChanged (bool val)
+{
+ mNrChanged = mLabelChanged = mOtherChanged = mFilenameChanged = val;
+}
+
+void KSVData::setOriginalRunlevel (const QString& rl)
+{
+ mOriginalRunlevel = rl;
+}
+
+QDataStream& operator<< (QDataStream& stream, const KSVData& data)
+{
+ return stream << data.mPath
+ << data.mFilename
+ << data.mNr
+ << data.mRunlevel
+ << data.mLabel
+ << data.mOldFilename
+ << data.mOldNr
+ << data.mOldLabel
+ << data.mNrChanged
+ << data.mLabelChanged
+ << data.mFilenameChanged
+ << data.mOtherChanged << data.mOriginalRunlevel << data.mNewEntry;
+
+}
+
+QDataStream& operator>> (QDataStream& stream, KSVData& data)
+{
+ stream >> data.mPath
+ >> data.mFilename
+ >> data.mNr
+ >> data.mRunlevel
+ >> data.mLabel
+ >> data.mOldFilename
+ >> data.mOldNr
+ >> data.mOldLabel
+ >> data.mNrChanged
+ >> data.mLabelChanged
+ >> data.mFilenameChanged
+ >> data.mOtherChanged >> data.mOriginalRunlevel >> data.mNewEntry;
+
+
+ data.mNumberString.sprintf ("%.2i", data.mNr);
+
+ return stream;
+}
diff --git a/ksysv/Data.h b/ksysv/Data.h
new file mode 100644
index 0000000..e282346
--- /dev/null
+++ b/ksysv/Data.h
@@ -0,0 +1,79 @@
+// (c) 2000 Peter Putzer
+
+#ifndef KSV_DATA_H
+#define KSV_DATA_H
+
+class QDataStream;
+
+class KSVData
+{
+public:
+ KSVData ();
+ KSVData (const QString& file, const QString& path, const QString& label, Q_INT8 nr);
+ KSVData (const KSVData& rhs);
+ inline ~KSVData () {}
+
+ const KSVData& operator= (const KSVData& rhs);
+ bool operator== (const KSVData& rhs) const;
+ bool operator< (const KSVData& rhs) const;
+
+ inline QString filenameAndPath () const { return mPath + "/" + mFilename; }
+
+ inline const QString& path () const { return mPath; }
+ inline const QString& label () const { return mLabel; }
+ inline const QString& filename () const { return mFilename; }
+ inline const QString& runlevel () const { return mRunlevel; }
+ inline Q_INT8 number () const { return mNr; }
+
+ inline const QString& numberString () const { return mNumberString; }
+
+ inline const QString& oldLabel () const { return mOldLabel; }
+ inline const QString& oldFilename () const { return mOldFilename; }
+ inline const QString& originalRunlevel () const { return mOldFilename; }
+ inline Q_INT8 oldNumber () const { return mOldNr; }
+
+ inline bool numberChanged () const { return mNrChanged; }
+ inline bool labelChanged () const { return mLabelChanged; }
+ inline bool otherChanged () const { return mOtherChanged; }
+ inline bool filenameChanged () const { return mFilenameChanged; }
+ inline bool newEntry () const { return mNewEntry; }
+
+ inline bool changed () const { return mNrChanged || mLabelChanged || mFilenameChanged; }
+
+ inline void setNumberChanged (bool val) { mNrChanged = val; }
+ inline void setNewEntry (bool val) { mNewEntry = val; }
+ void setPath (const QString&);
+ void setLabel (const QString&);
+ void setFilename (const QString&);
+ void setRunlevel (const QString&);
+ void setOriginalRunlevel (const QString&);
+ void setNumber (Q_INT8 nr);
+ void setChanged (bool);
+
+private:
+ friend QDataStream& operator<< (QDataStream&, const KSVData&);
+ friend QDataStream& operator>> (QDataStream&, KSVData&);
+
+ QString mPath;
+ QString mLabel;
+ QString mFilename;
+ QString mRunlevel;
+ Q_INT8 mNr;
+ QString mOldLabel;
+ QString mOldFilename;
+ QString mOriginalRunlevel;
+ Q_INT8 mOldNr;
+
+ bool mNrChanged;
+ bool mLabelChanged;
+ bool mOtherChanged;
+ bool mFilenameChanged;
+ bool mNewEntry;
+
+ QString mNumberString;
+};
+
+QDataStream& operator<< (QDataStream& stream, const KSVData& data);
+QDataStream& operator>> (QDataStream& stream, KSVData& data);
+
+#endif // KSV_DATA_H
diff --git a/ksysv/IOCore.cpp b/ksysv/IOCore.cpp
new file mode 100644
index 0000000..c61dec6
--- /dev/null
+++ b/ksysv/IOCore.cpp
@@ -0,0 +1,291 @@
+/***************************************************************************
+ ksv::IO.cpp - description
+ -------------------
+ 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. *
+ * *
+ ***************************************************************************/
+
+
+#include <errno.h>
+#include <unistd.h>
+
+#include <qfileinfo.h>
+#include <qptrlist.h>
+#include <qvaluelist.h>
+#include <qstringlist.h>
+
+#include <kdebug.h>
+#include <kapplication.h>
+#include <klocale.h>
+#include <kmimemagic.h>
+#include <kservice.h>
+#include <kuserprofile.h>
+
+#include "Data.h"
+#include "IOCore.h"
+#include "ksvdraglist.h"
+#include "ksv_core.h"
+#include "ksv_conf.h"
+
+QString ksv::IO::relToAbs (const QString& dir, const QString& rel)
+{
+ if (rel.left(1) != "/")
+ return QDir::cleanDirPath (dir + "/" + rel);
+ else
+ return QDir::cleanDirPath (rel);
+}
+
+void ksv::IO::removeFile (const QFileInfo& info, QDir& dir, QString& rich, QString& plain)
+{
+ if (!dir.remove(info.fileName(), FALSE))
+ {
+ rich = (i18n ("<error>FAILED</error> to remove <cmd>%1</cmd> from <cmd>%2</cmd>: \"%3\"<br/>")
+ .arg(info.fileName())
+ .arg(dir.path())
+ .arg(strerror(errno)));
+ plain = (i18n ("FAILED to remove %1 from %2: \"%3\"\n")
+ .arg(info.fileName())
+ .arg(dir.path())
+ .arg(strerror(errno)));
+ }
+ else
+ {
+ rich = i18n("removed <cmd>%1</cmd> from <cmd>%2</cmd><br/>")
+ .arg(info.fileName())
+ .arg(dir.path());
+
+ plain = i18n("removed %1 from %2\n")
+ .arg(info.fileName())
+ .arg(dir.path());
+ }
+}
+
+void ksv::IO::dissectFilename (const QString& file, QString& base, int& nr)
+{
+ QString tmp = file.mid(1, file.length());
+
+ nr = tmp.left(2).toInt();
+ base = tmp.mid(2, tmp.length());
+}
+
+void ksv::IO::makeSymlink (const KSVData& data, int runlevel, bool start,
+ QString& rich, QString& plain)
+{
+ const QString symName = QString("%1%2%3").arg(start ? "S" : "K").arg(data.numberString()).arg(data.label());
+ const QString symPath = QString("%1/rc%2.d/").arg(KSVConfig::self()->runlevelPath()).arg(runlevel);
+
+ const QString symbol = symPath + symName;
+ QString target = data.filename();
+
+ if (QDir::isRelativePath(target))
+ target = ksv::IO::makeRelativePath(QDir::cleanDirPath(symPath),
+ QDir::cleanDirPath(data.path())) + data.filename();
+
+ if (symlink(target.local8Bit(), symbol.local8Bit()) == 0)
+ {
+ rich = i18n("created <cmd>%1</cmd> in <cmd>%2</cmd><br/>").arg(symName).arg(symPath);
+ plain = i18n("created %1 in %2\n").arg(symName).arg(symPath);
+ }
+ else
+ {
+ rich = i18n("<error>FAILED</error> to create <cmd>%1</cmd> in <cmd>%2</cmd>: \"%3\"<br/>")
+ .arg(symName)
+ .arg(symPath)
+ .arg(strerror(errno));
+
+ plain = i18n("FAILED to create %1 in %2: \"%3\"\n")
+ .arg(symName)
+ .arg(symPath)
+ .arg(strerror(errno));
+ }
+}
+
+QString ksv::IO::makeRelativePath (const QString& from, const QString& to)
+{
+ if (QDir::isRelativePath(from) || QDir::isRelativePath(to))
+ return QString::null;
+
+ int pos = 0;
+ const int f_length = from.length();
+
+ QStringList from_list;
+ while (pos > -1)
+ {
+ const int old = pos + 1;
+ const int res = from.find('/', old);
+
+ int length = 0;
+
+ if (res > -1)
+ length = res - old + 1;
+ else
+ length = f_length - old;
+
+ from_list.append (from.mid(old, length));
+
+ pos = res;
+ }
+
+ const int t_length = to.length();
+
+ QStringList to_list;
+ pos = 0;
+
+ while (pos > -1)
+ {
+ const int old = pos + 1;
+ const int res = to.find('/', old);
+
+ int length = 0;
+
+ if (res > -1)
+ length = res - old + 1;
+ else
+ length = t_length - old;
+
+ to_list.append (to.mid(old, length));
+
+ pos = res;
+ }
+
+ int lcp = 0; // longest common prefix
+ const int f_c = from_list.count();
+ const int t_c = to_list.count();
+
+ while (lcp < f_c && lcp < t_c
+ && *from_list.at(lcp) == *to_list.at(lcp))
+ lcp++;
+
+ QString result;
+ for (int i = f_c - lcp; i > 0; --i)
+ result += "../";
+
+ for (int i = lcp; i < t_c; ++i)
+ result += *to_list.at(i) + "/";
+
+ return result;
+}
+
+bool ksv::IO::loadSavedConfiguration (QDataStream& s,
+ QValueList<KSVData>* start,
+ QValueList<KSVData>* stop)
+{
+ QCString magic;
+ s >> magic;
+ if (magic != "KSysV")
+ return false;
+
+ Q_INT32 version = 0;
+ s >> version;
+
+ if (version != 3)
+ return false; // too old
+
+ QDateTime saveTime;
+ s >> saveTime;
+
+ for (int i = 0; i < ksv::runlevelNumber; ++i)
+ {
+ QString rlMagic;
+ QString section;
+
+ s >> rlMagic;
+ s >> section;
+
+ if (rlMagic != QString::fromLatin1("RUNLEVEL %1").arg(i))
+ return false;
+
+ if (section != "START")
+ return false;
+
+ Q_INT32 numberOfItems;
+ s >> numberOfItems;
+
+ KSVData data;
+ for (int j = 0; j < numberOfItems; ++j)
+ {
+ s >> data;
+ start[i].append (data);
+ }
+
+ s >> section;
+ if (section != "STOP")
+ return false;
+
+ s >> numberOfItems;
+ for (int j = 0; j < numberOfItems; ++j)
+ {
+ s >> data;
+ stop[i].append(data);
+ }
+ }
+
+ return true;
+}
+
+bool ksv::IO::saveConfiguration (QDataStream& s,
+ KSVDragList** start,
+ KSVDragList** stop)
+{
+ Q_INT32 version = 3;
+
+ s << QCString("KSysV")
+ << version
+ << QDateTime::currentDateTime(); // save date
+
+ for (int i = 0; i < ksv::runlevelNumber; ++i)
+ {
+ Q_INT32 numberOfItems = start[i]->childCount();
+
+ s << QString::fromLatin1 ("RUNLEVEL %1").arg (i)
+ << QString::fromLatin1 ("START")
+ << numberOfItems;
+
+ for (QListViewItemIterator it (start[i]);
+ it.current();
+ ++it)
+ {
+ s << *static_cast<KSVItem*> (it.current())->data();
+ }
+
+ numberOfItems = stop[i]->childCount();
+
+ s << QString::fromLatin1 ("STOP")
+ << numberOfItems;
+
+ for (QListViewItemIterator it (stop[i]);
+ it.current();
+ ++it)
+ {
+ s << *static_cast<KSVItem*> (it.current())->data();
+ }
+ }
+
+ return true;
+}
+
+KTrader::OfferList ksv::IO::servicesForFile (const QString& filename)
+{
+ static KTrader* trader = KTrader::self();
+ static KMimeMagic* magic = KMimeMagic::self();
+ const QString mimetype = magic->findFileType(filename)->mimeType();
+
+ return trader->query (mimetype, "Type == 'Application'");
+}
+
+KService::Ptr ksv::IO::preferredServiceForFile (const QString& filename)
+{
+ static KMimeMagic* magic = KMimeMagic::self();
+ const QString mimetype = magic->findFileType(filename)->mimeType();
+
+ return KServiceTypeProfile::preferredService (mimetype, "Application");
+}
diff --git a/ksysv/IOCore.h b/ksysv/IOCore.h
new file mode 100644
index 0000000..37ac4e5
--- /dev/null
+++ b/ksysv/IOCore.h
@@ -0,0 +1,64 @@
+/***************************************************************************
+ ksv::IO.h - description
+ -------------------
+ begin : Sun Oct 3 1999
+ copyright : (C) 1997-99 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef KSV_IOCORE_H
+#define KSV_IOCORE_H
+
+#include <qdir.h>
+#include <qstring.h>
+
+#include <ktrader.h>
+#include <kservice.h>
+
+template<class T> class QValueList;
+class QFileInfo;
+class QDataStream;
+
+class KSVDragList;
+class KSVData;
+
+namespace ksv
+{
+ namespace IO
+ {
+ void removeFile (const QFileInfo& info, QDir& dir,
+ QString& rich, QString& plain);
+
+ QString relToAbs (const QString& dir, const QString& rel);
+
+ void makeSymlink (const KSVData& data, int runlevel, bool start,
+ QString& rich, QString& plain);
+
+ void dissectFilename (const QString& file, QString& name, int& nr);
+
+ QString makeRelativePath (const QString& from, const QString& to);
+
+ bool saveConfiguration (QDataStream&,
+ KSVDragList** start,
+ KSVDragList** stop);
+
+ bool loadSavedConfiguration (QDataStream&,
+ QValueList<KSVData>* start,
+ QValueList<KSVData>* stop);
+
+ KTrader::OfferList servicesForFile (const QString& filename);
+ KService::Ptr preferredServiceForFile (const QString& filename);
+
+ } // namespace IO
+} // namespace ksv
+
+#endif
+
diff --git a/ksysv/Makefile.am b/ksysv/Makefile.am
new file mode 100644
index 0000000..5e8ff78
--- /dev/null
+++ b/ksysv/Makefile.am
@@ -0,0 +1,84 @@
+INCLUDES= $(all_includes)
+SUBDIRS = pics toolbar
+KDE_ICON=AUTO
+xdg_apps_DATA = ksysv.desktop
+
+bin_PROGRAMS = ksysv
+# Which sources should be compiled for ksysv.
+ksysv_SOURCES = main.cpp \
+ ActionList.cpp \
+ IOCore.cpp \
+ ksvdraglist.cpp \
+ RunlevelAuthIcon.cpp \
+ OldView.cpp \
+ Properties.cpp \
+ SpinBox.cpp \
+ ServiceDlg.cpp \
+ TopWidget.cpp \
+ Data.cpp \
+ ksv_conf.cpp \
+ ksvapplication.cpp \
+ kdltooltip.cpp \
+ ksv_core.cpp \
+ ksvdrag.cpp \
+ kscroller.cpp \
+ ksv_service.cpp \
+ leveldb.c \
+ PreferencesDialog.cpp \
+ trash.cpp \
+ pathconfig.ui \
+ ksvpathconfig.cpp \
+ miscconfig.ui \
+ ksvmiscconfig.cpp \
+ lookandfeelconfig.ui \
+ ksvlookandfeel.cpp \
+ configwizard.ui \
+ ksvconfigwizard.cpp \
+ kbusymanager.cpp
+
+# the library search path
+ksysv_METASOURCES = AUTO
+ksysv_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+ksysv_LDADD = $(LIB_KFILE) -lkdeprint
+
+# this option you can leave out. Just, if you use "make dist", you need it
+noinst_HEADERS = ActionList.h \
+ IOCore.h \
+ OldView.h \
+ Properties.h \
+ SpinBox.h \
+ Data.h \
+ ksvapplication.h \
+ ServiceDlg.h \
+ TopWidget.h \
+ kdltooltip.h \
+ ksvdrag.h \
+ ksv_service.h \
+ ksv_conf.h \
+ RunlevelAuthIcon.h \
+ ksv_core.h \
+ kscroller.h \
+ ksvdraglist.h \
+ leveldb.h \
+ PreferencesDialog.h \
+ trash.h \
+ ksvpathconfig.h \
+ ksvmiscconfig.h \
+ ksvlookandfeel.h \
+ ksvconfigwizard.h \
+ kbusymanager.h \
+ version.h
+
+# just to make sure, automake makes them
+
+messages: rc.cpp
+ $(XGETTEXT) -C *.cpp -o $(podir)/ksysv.pot
+
+rcdir = $(kde_datadir)/ksysv
+rc_DATA = ksysvui.rc
+
+kdemime_DATA = x-ksysv.desktop
+kdemimedir = $(kde_mimedir)/application
+
+textmime_DATA = x-ksysv-log.desktop
+textmimedir= $(kde_mimedir)/text
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"
diff --git a/ksysv/OldView.h b/ksysv/OldView.h
new file mode 100644
index 0000000..8a6899e
--- /dev/null
+++ b/ksysv/OldView.h
@@ -0,0 +1,179 @@
+/***************************************************************************
+ begin : Sun Oct 3 1999
+ copyright : (C) 1999 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef KSV_VIEW_H
+#define KSV_VIEW_H
+
+#include <qsplitter.h>
+#include <qvaluelist.h>
+#include <qsize.h>
+
+#include <ktrader.h>
+
+class QPopupMenu;
+class QFileInfo;
+class QLabel;
+class QListViewItem;
+class QTextEdit;
+class QFrame;
+class QVBox;
+class QPixmap;
+class QLayout;
+
+class KScroller;
+class KProcess;
+class KListView;
+class QSplitter;
+class KPopupMenu;
+class KSVTrash;
+class KSVDragList;
+class KSVConfig;
+class KSVData;
+class KSVItem;
+class KSVAction;
+class KSVTopLevel;
+
+class KSVContent : public QSplitter
+{
+ Q_OBJECT
+
+public:
+ KSVContent (KPopupMenu* openWithMenu, KSVTopLevel* parent = 0, const char* name = 0);
+ ~KSVContent();
+
+ KSVDragList* getOrigin();
+
+ const QString& log() const;
+ const QString& xmlLog() const;
+
+ void setColors (const QColor& newNormal,
+ const QColor& newSelected,
+ const QColor& changedNormal,
+ const QColor& changedSelected);
+
+ void mergeLoadedPackage (QValueList<KSVData>* start,
+ QValueList<KSVData>* stop);
+
+public slots:
+ void slotWriteSysV();
+
+ void infoOnData(KSVItem* data);
+ void setDisplayScriptOutput(bool val);
+ void slotScriptProperties (QListViewItem*);
+ void multiplexEnabled (bool);
+
+ void hideRunlevel (int index);
+ void showRunlevel (int index);
+
+protected:
+ virtual void resizeEvent (QResizeEvent* e);
+ virtual void moveEvent (QMoveEvent* e);
+ virtual void showEvent (QShowEvent*);
+
+private slots:
+ void calcMinSize ();
+ void fwdOrigin (KSVDragList*);
+ void startService();
+ void startService (const QString& path);
+ void stopService();
+ void stopService (const QString& path);
+ void restartService();
+ void restartService (const QString& path);
+ void editService();
+ void editService (const QString& path);
+ void slotOutputOrError( KProcess* _p, char* _buffer, int _buflen );
+ void slotExitedProcess(KProcess* proc);
+ void slotScriptsNotRemovable();
+ void slotDoubleClick (QListViewItem*);
+ void slotExitDuringRestart(KProcess* proc);
+ void appendLog(const QString& rich, const QString& plain);
+ void appendLog(const QCString& _buffer);
+ void fwdCannotGenerateNumber();
+ void fwdOrigin();
+ void reSortRL();
+ void pasteAppend();
+ void fwdUndoAction(KSVAction*);
+ void updatePanningFactor();
+
+ void popupRunlevelMenu (KListView*, QListViewItem*, const QPoint&);
+ void popupServicesMenu (KListView*, QListViewItem*, const QPoint&);
+
+ void updateServicesAfterChange (const QString&);
+ void updateRunlevelsAfterChange ();
+
+ void repaintRunlevels ();
+
+ void openWith ();
+ void openWith (int index);
+
+signals:
+ void sigUpdateParent();
+ void sigRun (const QString&);
+ void sigStop();
+ void sigNotRemovable();
+ void cannotGenerateNumber();
+ void selected (KSVItem*);
+ void selectedScripts (KSVItem*);
+ void sizeChanged();
+
+ void undoAction (KSVAction*);
+ void logChanged();
+
+ void newOrigin();
+
+private:
+ static int splitterToPanningFactor (const QValueList<int>&);
+ static const QValueList<int>& panningFactorToSplitter (int);
+
+ void merge (QValueList<KSVData>& list, KSVDragList* widget);
+ void initLList();
+ void initScripts();
+ void initRunlevels();
+ void info2Widget (QFileInfo* info, int index);
+ void writeToDisk (const KSVData& _w, int _rl, bool _start);
+ void clearRL( int _rl );
+
+ friend class KSVTopLevel;
+
+ QFrame* mContent;
+ KScroller* mScroller;
+
+ KSVDragList** startRL;
+ KSVDragList** stopRL;
+ KSVDragList* scripts;
+
+ KPopupMenu* mItemMenu;
+ KPopupMenu* mContextMenu;
+ KPopupMenu* mScriptMenu;
+ KSVTrash* trash;
+ QTextEdit* textDisplay;
+ KSVConfig* conf;
+
+ QVBox* mScriptBox;
+ QVBox** mRunlevels;
+ QWidget* mBuffer;
+
+ KSVDragList* mOrigin;
+
+ QString mLogText, mXMLLogText;
+
+ QSize mMinSize;
+
+ KPopupMenu* mOpenWithMenu;
+ KTrader::OfferList mOpenWithOffers;
+
+ QCString m_buffer;
+};
+
+#endif
diff --git a/ksysv/PreferencesDialog.cpp b/ksysv/PreferencesDialog.cpp
new file mode 100644
index 0000000..b0a2c42
--- /dev/null
+++ b/ksysv/PreferencesDialog.cpp
@@ -0,0 +1,291 @@
+// (c) 2000 Peter Putzer
+
+#include <qframe.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <qvbox.h>
+#include <qhbox.h>
+#include <qgrid.h>
+#include <qdir.h>
+#include <qcheckbox.h>
+
+#include <kdebug.h>
+#include <klocale.h>
+#include <klineedit.h>
+#include <kiconloader.h>
+#include <kcolorbutton.h>
+#include <kapplication.h>
+#include <kmessagebox.h>
+
+#include "ksv_conf.h"
+// #include "ksvcolorconfig.h"
+#include "ksvmiscconfig.h"
+#include "ksvpathconfig.h"
+#include "ksvlookandfeel.h"
+// #include "ksvfontconfig.h"
+#include "ksv_core.h"
+
+#include "PreferencesDialog.h"
+
+KSVPreferences::KSVPreferences (QWidget* parent)
+ : KDialogBase (IconList, i18n("Configure"), Help|Ok|Apply|Cancel, Ok,
+ parent, "KSysV Preferences", true, true),
+ mConfig (KSVConfig::self())
+{
+ setMinimumSize (sizeHint ());
+
+ /**
+ * Look & Feel Page
+ */
+ QFrame* lafPage = addPage (i18n ("Look & Feel"), QString::null, DesktopIcon ("colorize", 32));
+ mLookAndFeel = new KSVLookAndFeel (lafPage);
+ connect( mLookAndFeel, SIGNAL( configChanged() ), this, SLOT( slotChanged() ) );
+
+ QVBoxLayout* lafLayout = new QVBoxLayout (lafPage);
+ lafLayout->addWidget (mLookAndFeel);
+
+// /**
+// * Colors Page
+// */
+// QFrame* colorPage = addPage (i18n("Colors"), QString::null, DesktopIcon ("colorize", 32));
+// mColorConfig = new KSVColorConfig(colorPage);
+
+// QVBoxLayout* colorLayout = new QVBoxLayout(colorPage);
+// colorLayout->addWidget(mColorConfig);
+
+// /**
+// * Fonts Page
+// */
+// QFrame* fontPage = addPage (i18n("Fonts"), QString::null, DesktopIcon ("fonts", 32));
+// mFontConfig = new KSVFontConfig(fontPage);
+
+// QVBoxLayout* fontLayout = new QVBoxLayout (fontPage);
+// fontLayout->addWidget(mFontConfig);
+
+ /**
+ * Paths Page
+ */
+ QFrame* pathPage = addPage (i18n ("Paths"), QString::null, DesktopIcon ("kfm", 32));
+ mPathConfig = new KSVPathConfig(pathPage);
+ connect( mPathConfig, SIGNAL( configChanged() ), this, SLOT( slotChanged() ) );
+
+ QVBoxLayout *pathLayout = new QVBoxLayout (pathPage);
+ pathLayout->addWidget (mPathConfig);
+
+ /**
+ * Miscellaneous Page
+ */
+ QFrame* miscPage = addPage (i18n ("Miscellaneous"), i18n("Settings Not Fitting Anywhere Else"),
+ DesktopIcon ("misc", 32));
+ mMiscConfig = new KSVMiscConfig(miscPage);
+ connect( mMiscConfig, SIGNAL( configChanged() ), this, SLOT( slotChanged() ) );
+
+ QVBoxLayout *miscLayout = new QVBoxLayout (miscPage);
+ miscLayout->addWidget (mMiscConfig);
+
+ connect (mMiscConfig->mShowAll, SIGNAL (clicked()), this, SLOT (showAllMessages()));
+
+ reReadConfig();
+ enableButton( Apply, false );
+ configChanged = false;
+}
+
+KSVPreferences::~KSVPreferences ()
+{
+}
+
+void KSVPreferences::slotChanged()
+{
+ enableButton( Apply, true );
+ configChanged = true;
+}
+
+void KSVPreferences::reReadConfig()
+{
+ mPathConfig->mRunlevelPath->setText(mConfig->runlevelPath());
+ mPathConfig->mServicesPath->setText(mConfig->scriptPath());
+
+ mLookAndFeel->mNewNormal->setColor (mConfig->newNormalColor());
+ mLookAndFeel->mNewSelected->setColor (mConfig->newSelectedColor());
+
+ mLookAndFeel->mChangedNormal->setColor (mConfig->changedNormalColor ());
+ mLookAndFeel->mChangedSelected->setColor (mConfig->changedSelectedColor ());
+
+ mLookAndFeel->setServiceFont (mConfig->serviceFont());
+ mLookAndFeel->setNumberFont (mConfig->numberFont());
+
+ reReadMessages();
+}
+
+void KSVPreferences::slotCancel ()
+{
+ reject();
+ reReadConfig();
+}
+
+void KSVPreferences::slotApply ()
+{
+ if (checkPaths())
+ {
+ setConfig();
+ enableButton( Apply, false );
+ configChanged = false;
+ }
+}
+
+bool KSVPreferences::checkPaths ()
+{
+ bool result = true;
+
+ if (!QDir(mPathConfig->mServicesPath->text()).exists())
+ result = (KMessageBox::warningContinueCancel(this,
+ i18n ("The service folder you specified does "
+ "not exist.\n"
+ "You can continue if you want to, "
+ "or you can click Cancel "
+ "to select a new folder."),
+ i18n ("Warning"))
+ != KMessageBox::Cancel);
+
+ if (!QDir(mPathConfig->mRunlevelPath->text()).exists())
+ result = result
+ && (KMessageBox::warningContinueCancel(this,
+ i18n ("The runlevel folder you specified does "
+ "not exist.\n"
+ "You can continue if you want to, "
+ "or you can click Cancel "
+ "to select a new folder."),
+ i18n ("Warning"))
+ != KMessageBox::Cancel);
+
+ return result;
+}
+
+void KSVPreferences::slotOk ()
+{
+ if (checkPaths())
+ {
+ accept();
+ setConfig ();
+ }
+}
+
+QColor KSVPreferences::newNormal() const
+{
+ return mLookAndFeel->mNewNormal->color();
+}
+
+QColor KSVPreferences::newSelected() const
+{
+ return mLookAndFeel->mNewSelected->color();
+}
+
+QColor KSVPreferences::changedNormal() const
+{
+ return mLookAndFeel->mChangedNormal->color();
+}
+
+QColor KSVPreferences::changedSelected() const
+{
+ return mLookAndFeel->mChangedSelected->color();
+}
+
+
+KSVPreferences* KSVPreferences::self ()
+{
+ static KSVPreferences* prefs = new KSVPreferences (kapp->mainWidget());
+
+ return prefs;
+}
+
+void KSVPreferences::setConfig ()
+{
+ // if necessary, update service path
+ {
+ QString sp = mPathConfig->mServicesPath->text();
+ if (sp != mConfig->scriptPath())
+ {
+ mConfig->setScriptPath (sp);
+
+ emit updateServicesPath ();
+ }
+ }
+
+ // if necesssary, update root path for runlevels
+ {
+ QString rp = mPathConfig->mRunlevelPath->text();
+ if (rp != mConfig->runlevelPath ())
+ {
+ mConfig->setRunlevelPath (rp);
+
+ emit updateRunlevelsPath ();
+ }
+ }
+
+ // if necessary, update miscellaneous settings
+ {
+ mConfig->setShowMessage (ksv::RunlevelsReadOnly,
+ mMiscConfig->mWarnReadOnly->isChecked());
+ mConfig->setShowMessage (ksv::CouldNotGenerateSortingNumber,
+ mMiscConfig->mWarnSortingNumber->isChecked());
+ }
+
+ // if necessary, update colors
+ {
+ QColor nn = newNormal();
+ QColor ns = newSelected();
+ QColor cn = changedNormal();
+ QColor cs = changedSelected();
+
+ if (nn != mConfig->newNormalColor() ||
+ ns != mConfig->newSelectedColor() ||
+ cn != mConfig->changedNormalColor() ||
+ cs != mConfig->changedSelectedColor())
+ {
+ mConfig->setNewNormalColor (nn);
+ mConfig->setNewSelectedColor (ns);
+ mConfig->setChangedNormalColor (cn);
+ mConfig->setChangedSelectedColor (cs);
+
+ emit updateColors ();
+ }
+ }
+
+ // if necessary, update fonts
+ {
+ const QFont& sf = mLookAndFeel->serviceFont();
+ const QFont& ns = mLookAndFeel->numberFont();
+
+ if (sf != mConfig->serviceFont() || ns != mConfig->numberFont())
+ {
+ mConfig->setServiceFont (sf);
+ mConfig->setNumberFont (ns);
+
+ emit updateFonts();
+ }
+ }
+}
+
+void KSVPreferences::showAllMessages ()
+{
+ KMessageBox::enableAllMessages ();
+
+ // update checkboxes
+ reReadMessages();
+}
+
+void KSVPreferences::reReadMessages()
+{
+ mMiscConfig->mWarnReadOnly->setChecked (mConfig->showMessage (ksv::RunlevelsReadOnly));
+ mMiscConfig->mWarnSortingNumber->setChecked (mConfig->showMessage (ksv::CouldNotGenerateSortingNumber));
+}
+
+void KSVPreferences::showEvent (QShowEvent* e)
+{
+ reReadMessages();
+
+ KDialogBase::showEvent (e);
+}
+
+#include "PreferencesDialog.moc"
diff --git a/ksysv/PreferencesDialog.h b/ksysv/PreferencesDialog.h
new file mode 100644
index 0000000..ba7d938
--- /dev/null
+++ b/ksysv/PreferencesDialog.h
@@ -0,0 +1,68 @@
+// (c) 2000 Peter Putzer
+
+#ifndef PREFERENCES_DIALOG_H
+#define PREFERENCES_DIALOG_H
+
+#include <qstring.h>
+#include <kdialogbase.h>
+
+class QPushButton;
+
+class KSVLookAndFeel;
+class KSVMiscConfig;
+class KSVPathConfig;
+class KSVConfig;
+
+
+class KSVPreferences : public KDialogBase
+{
+ Q_OBJECT
+
+public:
+ static KSVPreferences* self ();
+ virtual ~KSVPreferences ();
+
+ QColor newNormal () const;
+ QColor newSelected () const;
+ QColor changedNormal () const;
+ QColor changedSelected () const;
+
+ QString runlevelPath () const;
+ QString scriptPath () const;
+
+protected:
+ virtual void showEvent (QShowEvent* e);
+
+signals:
+ void updateColors ();
+ void updateServicesPath ();
+ void updateRunlevelsPath ();
+ void updateFonts ();
+
+protected slots:
+ virtual void slotApply ();
+ virtual void slotCancel ();
+ virtual void slotOk ();
+ void slotChanged();
+
+private slots:
+ void reReadConfig();
+ void showAllMessages ();
+
+private:
+ friend class KSVTopLevel;
+
+ KSVPreferences (QWidget* parent);
+ void setConfig ();
+ bool checkPaths();
+ void reReadMessages();
+ KSVConfig* mConfig;
+
+ KSVLookAndFeel* mLookAndFeel;
+ KSVPathConfig* mPathConfig;
+ KSVMiscConfig* mMiscConfig;
+ bool configChanged;
+};
+
+
+#endif // PREFERENCES_DIALOG_H
diff --git a/ksysv/Properties.cpp b/ksysv/Properties.cpp
new file mode 100644
index 0000000..7379b74
--- /dev/null
+++ b/ksysv/Properties.cpp
@@ -0,0 +1,209 @@
+// (c) 2000 Peter Putzer
+
+#include <qframe.h>
+#include <qlabel.h>
+#include <qtextview.h>
+#include <qlayout.h>
+#include <qhbox.h>
+#include <qvbox.h>
+#include <qbuttongroup.h>
+#include <qpushbutton.h>
+
+#include <kdebug.h>
+#include <klocale.h>
+#include <klineedit.h>
+#include <kiconloader.h>
+
+#include "SpinBox.h"
+#include "OldView.h"
+#include "ksv_conf.h"
+#include "ksv_core.h"
+#include "Data.h"
+#include "Properties.h"
+
+KSVServicePropertiesDialog::KSVServicePropertiesDialog (KSVData& data, QWidget* parent)
+ : KPropertiesDialog (KURL(data.filenameAndPath()),
+ parent, "KSVServicePropertiesDialog", true, false),
+ mData (data)
+{
+ KSVServicesPage* page = new KSVServicesPage (data, this);
+ insertPlugin (page);
+
+ showPage (page->pageIndex ());
+}
+
+KSVServicePropertiesDialog::~KSVServicePropertiesDialog ()
+{
+}
+
+KSVServicesPage::KSVServicesPage (KSVData& data, KPropertiesDialog* props)
+ : KPropsDlgPlugin (props),
+ mData (data),
+ mPage (props->addVBoxPage (i18n("&Service"))),
+ mIndex (props->pageIndex (mPage))
+{
+ mPage->setSpacing (KDialog::spacingHint());
+
+ QVBox* desc = new QVBox (mPage);
+ desc->setSpacing (1);
+
+ QLabel* label = new QLabel(i18n("Description:"), desc);
+ label->setFixedHeight (label->sizeHint().height());
+
+ QString text;
+ ksv::getServiceDescription (data.filename(), text);
+ mDesc = new QTextView (QString("<p>%1</p>").arg (text), QString::null, desc);
+
+ QButtonGroup* buttons = new QButtonGroup (1, Vertical, i18n ("Actions"), mPage);
+ QPushButton* b = new QPushButton (i18n ("&Edit"), buttons);
+ connect (b, SIGNAL (clicked()), props, SLOT (doEdit()));
+
+ QFrame* spacer = new QFrame (buttons);
+ spacer->setMinimumWidth (KDialog::spacingHint());
+
+ b = new QPushButton (i18n ("&Start"), buttons);
+ connect (b, SIGNAL (clicked()), props, SLOT (doStart()));
+
+ b = new QPushButton (i18n ("S&top"), buttons);
+ connect (b, SIGNAL (clicked()), props, SLOT (doStop()));
+
+ b = new QPushButton (i18n ("&Restart"), buttons);
+ connect (b, SIGNAL (clicked()), props, SLOT (doRestart()));
+}
+
+KSVServicesPage::~KSVServicesPage ()
+{
+}
+
+void KSVServicesPage::applyChanges ()
+{
+}
+
+void KSVServicePropertiesDialog::doEdit ()
+{
+ emit editService (mData.filenameAndPath ());
+}
+
+void KSVServicePropertiesDialog::doStart ()
+{
+ emit startService (mData.filenameAndPath ());
+}
+
+void KSVServicePropertiesDialog::doStop ()
+{
+ emit stopService (mData.filenameAndPath ());
+}
+
+void KSVServicePropertiesDialog::doRestart ()
+{
+ emit restartService (mData.filenameAndPath ());
+}
+
+
+KSVEntryPropertiesDialog::KSVEntryPropertiesDialog (KSVData& data, QWidget* parent)
+ : KPropertiesDialog (data.label(), parent, "KSVEntryPropertiesDialog", true),
+ mData (data)
+{
+ KSVEntryPage* page1 = new KSVEntryPage (data, this);
+ insertPlugin (page1);
+
+ KSVServicesPage* page2 = new KSVServicesPage (data, this);
+ insertPlugin (page2);
+}
+
+KSVEntryPropertiesDialog::~KSVEntryPropertiesDialog ()
+{
+}
+
+KSVEntryPage::KSVEntryPage (KSVData& data, KPropertiesDialog* props)
+ : KPropsDlgPlugin (props),
+ mData (data),
+ mPage (props->addPage (i18n("&Entry"))),
+ mIndex (props->pageIndex (mPage))
+{
+ QGridLayout* top = new QGridLayout (mPage, 4, 2, 0, KDialog::spacingHint());
+
+ QLabel* labelLabel = new QLabel (i18n ("&Name:"), mPage);
+ mLabelEdit = new KLineEdit (mPage);
+ mLabelEdit->setText (mData.label());
+ labelLabel->setBuddy (mLabelEdit);
+
+ QLabel* serviceLabel = new QLabel (i18n ("&Points to service:"), mPage);
+ mServiceEdit = new KLineEdit (mPage);
+ mServiceEdit->setCompletionObject (ksv::serviceCompletion(), true);
+ mServiceEdit->setText (mData.filename());
+ serviceLabel->setBuddy (mServiceEdit);
+
+ QLabel* numberLabel = new QLabel (i18n ("&Sorting number:"), mPage);
+ mNumberEdit = new KSVSpinBox (mPage);
+ mNumberEdit->setValue (mData.number());
+ numberLabel->setBuddy (mNumberEdit);
+
+ QLabel* iconLabel = new QLabel (mPage);
+ iconLabel->setPixmap (DesktopIcon ("ksysv", 48));
+
+ top->addWidget (labelLabel, 0, 0);
+ top->addWidget (mLabelEdit, 0, 1);
+ top->addWidget (serviceLabel, 1, 0);
+ top->addWidget (mServiceEdit, 1, 1);
+ top->addWidget (numberLabel, 2, 0);
+ top->addWidget (mNumberEdit, 2, 1);
+ top->addWidget (iconLabel, 3, 0);
+
+ connect (mServiceEdit, SIGNAL (textChanged (const QString&)),
+ this, SLOT (emitChanged()));
+ connect (mLabelEdit, SIGNAL (textChanged (const QString&)),
+ this, SLOT (emitChanged()));
+ connect (mNumberEdit, SIGNAL (valueChanged (int)),
+ this, SLOT (emitChanged()));
+}
+
+KSVEntryPage::~KSVEntryPage ()
+{
+}
+
+void KSVEntryPage::applyChanges ()
+{
+ if (mNumberEdit->value() != mData.number())
+ {
+ mData.setNumber (mNumberEdit->value());
+ }
+
+ if (mLabelEdit->text() != mData.label())
+ {
+ mData.setLabel (mLabelEdit->text());
+ }
+
+ if (mServiceEdit->text() != mData.filename())
+ {
+ mData.setFilename (mServiceEdit->text());
+ ksv::serviceCompletion ()->addItem (mData.filename());
+ }
+}
+
+void KSVEntryPage::emitChanged ()
+{
+ emit changed();
+}
+
+void KSVEntryPropertiesDialog::doEdit ()
+{
+ emit editService (mData.filenameAndPath ());
+}
+
+void KSVEntryPropertiesDialog::doStart ()
+{
+ emit startService (mData.filenameAndPath ());
+}
+
+void KSVEntryPropertiesDialog::doStop ()
+{
+ emit stopService (mData.filenameAndPath ());
+}
+
+void KSVEntryPropertiesDialog::doRestart ()
+{
+ emit restartService (mData.filenameAndPath ());
+}
+
+#include "Properties.moc"
diff --git a/ksysv/Properties.h b/ksysv/Properties.h
new file mode 100644
index 0000000..0e3225d
--- /dev/null
+++ b/ksysv/Properties.h
@@ -0,0 +1,110 @@
+// (c) 2000 Peter Putzer
+
+#ifndef PROPERTIES_H
+#define PROPERTIES_H
+
+#include <kpropertiesdialog.h>
+
+class QHBox;
+class QVBox;
+class QTextView;
+class QSpinBox;
+
+class KLineEdit;
+
+class KSVData;
+
+class KSVServicePropertiesDialog : public KPropertiesDialog
+{
+ Q_OBJECT
+
+public:
+ KSVServicePropertiesDialog (KSVData& data, QWidget* parent);
+ virtual ~KSVServicePropertiesDialog ();
+
+signals:
+ void startService (const QString&);
+ void stopService (const QString&);
+ void restartService (const QString&);
+ void editService (const QString&);
+
+private slots:
+ void doEdit ();
+ void doStart ();
+ void doStop ();
+ void doRestart ();
+
+private:
+ KSVData& mData;
+};
+
+
+class KSVEntryPropertiesDialog : public KPropertiesDialog
+{
+ Q_OBJECT
+
+public:
+ KSVEntryPropertiesDialog (KSVData& data, QWidget* parent);
+ virtual ~KSVEntryPropertiesDialog ();
+
+signals:
+ void startService (const QString&);
+ void stopService (const QString&);
+ void restartService (const QString&);
+ void editService (const QString&);
+
+private slots:
+ void doEdit ();
+ void doStart ();
+ void doStop ();
+ void doRestart ();
+
+private:
+ KSVData& mData;
+};
+
+class KSVEntryPage : public KPropsDlgPlugin
+{
+ Q_OBJECT
+
+public:
+ KSVEntryPage (KSVData& data, KPropertiesDialog* props);
+ virtual ~KSVEntryPage ();
+
+ virtual void applyChanges ();
+
+ inline int pageIndex () const { return mIndex; }
+
+private slots:
+ void emitChanged ();
+
+private:
+ KSVData& mData;
+ QFrame* mPage;
+ int mIndex;
+
+ KLineEdit* mServiceEdit;
+ KLineEdit* mLabelEdit;
+ QSpinBox* mNumberEdit;
+};
+
+class KSVServicesPage : public KPropsDlgPlugin
+{
+ Q_OBJECT
+
+public:
+ KSVServicesPage (KSVData& data, KPropertiesDialog* props);
+ virtual ~KSVServicesPage ();
+
+ virtual void applyChanges ();
+
+ inline int pageIndex () const { return mIndex; }
+
+private:
+ KSVData& mData;
+ QVBox* mPage;
+ QTextView* mDesc;
+ int mIndex;
+};
+
+#endif // PROPERTIES_H
diff --git a/ksysv/README b/ksysv/README
new file mode 100644
index 0000000..b0ac5a3
--- /dev/null
+++ b/ksysv/README
@@ -0,0 +1,33 @@
+/****************************************************************************
+* *
+* SYSTEM V INIT EDITOR *
+* for the KDE Project *
+* *
+****************************************************************************/
+
+DESCRIPTION:
+ SysV-Init Editor lets you edit your SysV-style init configuration
+ using drag'n'drop.
+
+INSTALLATION:
+ Just do a "./configure && make && make install".
+
+CONFIGURATION:
+ Through the GUI (Options/Configure...)
+
+CONTACT INFORMATION:
+ If something doesn't work (or does work :-) ) correctly, contact me:
+ Peter Putzer <putzer@kde.org>
+
+REMEMBER:
+ No warranties!
+
+BUGS:
+ See bugs.kde.org.
+
+LICENSE:
+ This program is licensed under the GNU General Public License, GPL for short.
+ See the file COPYING for details. No warranties!
+
+SPECIAL THANKS:
+ To Emanuel Pirker for his template for this README
diff --git a/ksysv/RunlevelAuthIcon.cpp b/ksysv/RunlevelAuthIcon.cpp
new file mode 100644
index 0000000..e086df1
--- /dev/null
+++ b/ksysv/RunlevelAuthIcon.cpp
@@ -0,0 +1,149 @@
+// (c) 2000 Peter Putzer <putzer@kde.org>
+
+#include <qtimer.h>
+#include <qfileinfo.h>
+#include <qlayout.h>
+#include <qtooltip.h>
+
+#include <kdebug.h>
+#include <kiconloader.h>
+#include <kdialog.h>
+#include <klocale.h>
+
+#include "ksv_core.h"
+#include "RunlevelAuthIcon.h"
+#include <qlabel.h>
+
+RunlevelAuthIcon::RunlevelAuthIcon (const QString& servicesPath, const QString& runlevelPath,
+ QWidget* parent, const char* name)
+ : KAuthIcon (parent, name),
+ mTimer (new QTimer (this)),
+ mServicesInfo (new QFileInfo (servicesPath)),
+ mRLInfo (new QFileInfo* [ksv::runlevelNumber]),
+ mOld (false),
+ mInterval (1000),
+ mCheckEnabled(false)
+{
+ lockText = i18n("Editing disabled - please check your permissions");
+ openLockText = i18n("Editing enabled");
+
+ lockLabel->setText (lockText);
+ lockLabel->hide();
+
+ lockPM = UserIcon ("ksysv_locked");
+ openLockPM = UserIcon ("ksysv_unlocked");
+
+ lockBox->setPixmap (lockPM);
+
+ lockBox->setMargin (1);
+ lockBox->setFrameStyle (QFrame::NoFrame);
+ lockBox->setFixedSize (lockBox->sizeHint());
+
+ connect (mTimer, SIGNAL (timeout()), this, SLOT (timerEvent()));
+ mTimer->start (mInterval);
+
+ for (int i = 0; i < ksv::runlevelNumber; ++i)
+ {
+ mRLInfo[i] = new QFileInfo ((runlevelPath + "/rc%1.d").arg(i));
+ }
+
+ updateStatus();
+ layout->activate();
+}
+
+RunlevelAuthIcon::~RunlevelAuthIcon ()
+{
+ delete mServicesInfo;
+
+ for (int i = 0; i < ksv::runlevelNumber; ++i)
+ {
+ delete mRLInfo[i];
+ }
+
+ delete[] mRLInfo;
+}
+
+void RunlevelAuthIcon::updateStatus ()
+{
+ if (!mCheckEnabled)
+ return;
+
+ const bool res = status();
+
+ if (mOld != res)
+ {
+ lockBox->setPixmap (res ? openLockPM : lockPM);
+ lockLabel->setText (res ? openLockText : lockText);
+
+ QToolTip::remove (this);
+ QToolTip::add (this, lockLabel->text());
+
+ mOld = res;
+ emit authChanged (res);
+ }
+ else
+ mOld = res;
+}
+
+bool RunlevelAuthIcon::status () const
+{
+ bool result = mServicesInfo->isWritable();
+
+ for (int i = 0; i < ksv::runlevelNumber; ++i)
+ result = result && mRLInfo[i]->isWritable();
+
+ return result;
+}
+
+void RunlevelAuthIcon::timerEvent ()
+{
+ for (int i = 0; i < ksv::runlevelNumber; ++i)
+ {
+ mRLInfo[i]->refresh();
+ }
+
+ mServicesInfo->refresh();
+
+ updateStatus();
+}
+
+void RunlevelAuthIcon::setServicesPath (const QString& path)
+{
+ mTimer->stop();
+
+ mServicesInfo->setFile (path);
+
+ mTimer->start(mInterval);
+}
+
+void RunlevelAuthIcon::setRunlevelPath (const QString& path)
+{
+ mTimer->stop();
+
+ for (int i = 0; i < ksv::runlevelNumber; ++i)
+ {
+ mRLInfo[i]->setFile ((path + "/rc%1.d").arg(i));
+ }
+
+ mTimer->start(mInterval);
+}
+
+void RunlevelAuthIcon::setRefreshInterval (int interval)
+{
+ mInterval = interval;
+
+ mTimer->stop();
+ mTimer->start (mInterval);
+}
+
+void RunlevelAuthIcon::setCheckEnabled (bool on)
+{
+ kdDebug(3000) << "enabling authicon " << on << endl;
+ mCheckEnabled = on;
+
+ // refresh everything
+ mOld = !status();
+ timerEvent();
+}
+
+#include "RunlevelAuthIcon.moc"
diff --git a/ksysv/RunlevelAuthIcon.h b/ksysv/RunlevelAuthIcon.h
new file mode 100644
index 0000000..d33f24d
--- /dev/null
+++ b/ksysv/RunlevelAuthIcon.h
@@ -0,0 +1,49 @@
+#ifndef RUNLEVEL_AUTH_ICON_H
+#define RUNLEVEL_AUTH_ICON_H
+
+// (c) 2000 Peter Putzer <putzer@kde.org>
+#include <kauthicon.h>
+
+class QTimer;
+class QFileInfo;
+
+class RunlevelAuthIcon : public KAuthIcon
+{
+ Q_OBJECT
+ Q_PROPERTY (int refreshInterval READ refreshInterval WRITE setRefreshInterval)
+
+public:
+ RunlevelAuthIcon (const QString& scriptPath, const QString& runlevelPath,
+ QWidget* parent = 0L, const char* name = 0L);
+
+ virtual ~RunlevelAuthIcon ();
+
+ virtual bool status () const;
+
+ inline int refreshInterval () const { return mInterval; }
+ inline bool isCheckEnabled () const { return mCheckEnabled; }
+
+public slots:
+ virtual void updateStatus ();
+
+ void setServicesPath (const QString& servicesPath);
+ void setRunlevelPath (const QString& runlevelPath);
+
+ void setRefreshInterval (int);
+
+ void setCheckEnabled(bool);
+
+private slots:
+ void timerEvent ();
+
+private:
+ QTimer* mTimer;
+ QFileInfo* mServicesInfo;
+ QFileInfo** mRLInfo;
+ bool mOld;
+ int mInterval;
+
+ bool mCheckEnabled;
+};
+
+#endif // RUNLEVEL_AUTH_ICON_H
diff --git a/ksysv/ServiceDlg.cpp b/ksysv/ServiceDlg.cpp
new file mode 100644
index 0000000..0564028
--- /dev/null
+++ b/ksysv/ServiceDlg.cpp
@@ -0,0 +1,123 @@
+/***************************************************************************
+ begin : Sun Oct 3 1999
+ copyright : (C) 1999 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. *
+ * *
+ ***************************************************************************/
+
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qfileinfo.h>
+#include <qcombobox.h>
+#include <qstring.h>
+
+#include <kapplication.h>
+#include <klocale.h>
+#include <kbuttonbox.h>
+
+#include "ksvdraglist.h"
+#include "ServiceDlg.h"
+
+#define MIN_SIZE(A) A->setMinimumSize(A->sizeHint())
+
+ServiceDlg::ServiceDlg (const QString& action, const QString& label,
+ QWidget* parent, const char* name)
+ : KDialogBase (parent, name, false, action, Apply|Close, Apply, true)
+{
+ QWidget* page = new QWidget (this);
+
+ QBoxLayout* top = new QVBoxLayout (page, 0, spacingHint());
+
+ mServices = new QComboBox (false, page);
+ QLabel* desc = new QLabel(label, page);
+ MIN_SIZE(desc);
+ desc->setBuddy(mServices);
+ MIN_SIZE(mServices);
+ mServices->setMinimumWidth(mServices->minimumSize().width() * 2);
+
+ QBoxLayout* serv_layout = new QHBoxLayout();
+ top->addLayout (serv_layout);
+ serv_layout->addWidget(desc);
+ serv_layout->addWidget(mServices);
+
+ setFixedSize (sizeHint());
+}
+
+ServiceDlg::~ServiceDlg()
+{
+}
+
+void ServiceDlg::slotApply()
+{
+ emit doAction (mMapServices[mServices->currentText()]->filenameAndPath());
+}
+
+int ServiceDlg::count() const
+{
+ return mServices->count();
+}
+
+void ServiceDlg::resetChooser(KSVDragList* list, bool edit)
+{
+ mServices->clear();
+ mMapServices.clear();
+
+ if (!list)
+ return;
+
+ // initialize the combobox
+ for (QListViewItemIterator it (list);
+ it.current();
+ ++it)
+ {
+ const KSVItem* item = static_cast<KSVItem*> (it.current());
+
+ QFileInfo info (item->filenameAndPath());
+
+ if (edit)
+ {
+ if (info.isReadable())
+ mServices->insertItem(item->label());
+
+ mMapServices[item->label()] = item;
+ }
+ else
+ {
+ if (info.isExecutable())
+ mServices->insertItem(item->label());
+
+ mMapServices[item->label()] = item;
+ }
+ }
+}
+
+void ServiceDlg::show ()
+{
+ QDialog::show ();
+
+ emit display (true);
+}
+
+void ServiceDlg::hide ()
+{
+ QDialog::hide ();
+
+ emit display (false);
+}
+
+void ServiceDlg::toggle ()
+{
+ if (isHidden())
+ show();
+ else
+ hide();
+}
+
+#include "ServiceDlg.moc"
diff --git a/ksysv/ServiceDlg.h b/ksysv/ServiceDlg.h
new file mode 100644
index 0000000..34fb69c
--- /dev/null
+++ b/ksysv/ServiceDlg.h
@@ -0,0 +1,56 @@
+/***************************************************************************
+ begin : Sun Oct 3 1999
+ copyright : (C) 1999 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef KSV_SERVICE_DIALOG_H
+#define KSV_SERVICE_DIALOG_H
+
+#include <kdialogbase.h>
+#include <qmap.h>
+
+class KSVDragList;
+class KSVItem;
+class QString;
+class QComboBox;
+
+class ServiceDlg : public KDialogBase
+{
+ Q_OBJECT
+
+public:
+ ServiceDlg (const QString& action, const QString& label,
+ QWidget* parent = 0, const char* name = 0);
+ virtual ~ServiceDlg();
+
+ int count() const;
+
+ void resetChooser (KSVDragList* data, bool edit);
+
+public slots:
+ virtual void show ();
+ virtual void hide ();
+ void toggle ();
+
+private:
+ QComboBox* mServices;
+ QMap<QString,const KSVItem*> mMapServices;
+
+protected slots:
+ virtual void slotApply();
+
+signals:
+ void doAction (const QString& on);
+ void display (bool);
+};
+
+#endif
diff --git a/ksysv/SpinBox.cpp b/ksysv/SpinBox.cpp
new file mode 100644
index 0000000..63a217a
--- /dev/null
+++ b/ksysv/SpinBox.cpp
@@ -0,0 +1,87 @@
+// (c) 2000 Peter Putzer
+
+#include <qlineedit.h>
+
+#include <kdebug.h>
+
+#include "ksv_core.h"
+#include "SpinBox.h"
+
+KSVSpinBox::KSVSpinBox (QWidget* parent, const char* name)
+ : QSpinBox (0, 99, 1, parent, name),
+ KCompletionBase (),
+ mClearedSelection (false)
+{
+ KCompletion* comp = ksv::numberCompletion();
+ setCompletionObject (comp, true);
+
+ editor()->installEventFilter (this);
+
+ connect (editor(), SIGNAL (textChanged (const QString&)),
+ comp, SLOT (slotMakeCompletion (const QString&)));
+ connect (comp, SIGNAL (match (const QString&)),
+ this, SLOT (handleMatch (const QString&)));
+}
+
+KSVSpinBox::~KSVSpinBox ()
+{
+}
+
+QString KSVSpinBox::mapValueToText (int value)
+{
+ QString result;
+
+ if (value < 10)
+ result.sprintf("%.2i", value);
+ else
+ result.setNum (value);
+
+ return result;
+}
+
+void KSVSpinBox::setCompletedText (const QString& text)
+{
+ QLineEdit* e = editor ();
+ const int pos = e->cursorPosition();
+
+ e->setText (text);
+
+ e->setSelection (pos, text.length());
+ e->setCursorPosition (pos);
+}
+
+void KSVSpinBox::setCompletedItems (const QStringList& /*items*/)
+{
+ // dont know what is supposed to be in here but it has to be defined
+ // because else the lack of this damn thing is making it abstract
+}
+
+void KSVSpinBox::handleMatch (const QString& match)
+{
+ if (!match.isNull() && editor()->text().length() < 2 && !mClearedSelection)
+ setCompletedText (match);
+}
+
+bool KSVSpinBox::eventFilter (QObject* o, QEvent* e)
+{
+ Q_UNUSED(o);
+ if (e->type() == QEvent::KeyPress)
+ {
+ QKeyEvent* ke = static_cast<QKeyEvent*> (e);
+
+ switch (ke->key())
+ {
+ case Key_BackSpace:
+ case Key_Delete:
+ mClearedSelection = true;
+ break;
+
+ default:
+ mClearedSelection = false;
+ }
+ }
+
+ return false;
+}
+
+#include "SpinBox.moc"
diff --git a/ksysv/SpinBox.h b/ksysv/SpinBox.h
new file mode 100644
index 0000000..147fc88
--- /dev/null
+++ b/ksysv/SpinBox.h
@@ -0,0 +1,32 @@
+// (c) 2000 Peter Putzer
+
+#ifndef KSV_SPINBOX_H
+#define KSV_SPINBOX_H
+
+#include <qspinbox.h>
+
+#include <kcompletion.h>
+
+class KSVSpinBox : public QSpinBox, public KCompletionBase
+{
+ Q_OBJECT
+
+public:
+ KSVSpinBox (QWidget* parent, const char* name = 0L);
+ virtual ~KSVSpinBox ();
+
+ virtual bool eventFilter (QObject*, QEvent*);
+ virtual void setCompletedText (const QString&);
+ virtual void setCompletedItems (const QStringList&);
+
+protected:
+ virtual QString mapValueToText (int value);
+
+private slots:
+ void handleMatch (const QString&);
+
+private:
+ bool mClearedSelection;
+};
+
+#endif // KSV_SPINBOX_H
diff --git a/ksysv/TODO b/ksysv/TODO
new file mode 100644
index 0000000..ced6dc4
--- /dev/null
+++ b/ksysv/TODO
@@ -0,0 +1,7 @@
+TODO
+
+ - printing stuff (PARTIALLY DONE but removed... too complex)
+ - support for REALLY starting daemons on SuSE and DLD
+ - use lexical compare of items to determine whether a drop is
+ allowed
+
diff --git a/ksysv/TopWidget.cpp b/ksysv/TopWidget.cpp
new file mode 100644
index 0000000..854c9cf
--- /dev/null
+++ b/ksysv/TopWidget.cpp
@@ -0,0 +1,1109 @@
+/*
+ Requires the Qt 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 <qpopupmenu.h>
+#include <qkeycode.h>
+#include <qmessagebox.h>
+#include <qfontmetrics.h>
+#include <qpainter.h>
+#include <qmultilineedit.h>
+#include <qdatetime.h>
+#include <kprinter.h>
+#include <qpaintdevicemetrics.h>
+#include <qbuttongroup.h>
+#include <qclipboard.h>
+#include <qtooltip.h>
+#include <qcheckbox.h>
+#include <qhbox.h>
+#include <qregexp.h>
+#include <qdatastream.h>
+#include <qpixmapcache.h>
+#include <qtextview.h>
+#include <qfileinfo.h>
+#include <qtextstream.h>
+#include <qwhatsthis.h>
+#include <qsimplerichtext.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 <qlabel.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 (this, "UndoList")),
+ mRedoList (new ActionList (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 QCheckBox*[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, SIGNAL(sigRun(const QString&)), this, SLOT(slotUpdateRunning(const QString&)));
+ connect (mView, SIGNAL(sigStop()), statusBar(), SLOT(clear()));
+ connect (mView, SIGNAL(cannotGenerateNumber()), this, SLOT(catchCannotGenerateNumber()));
+ connect (mView, SIGNAL(undoAction(KSVAction*)), this, SLOT(pushUndoAction(KSVAction*)));
+ connect (mView, SIGNAL(logChanged()), this, SLOT(enableLogActions()));
+
+ // cut & copy
+ connect (mView, SIGNAL (newOrigin()),
+ this, SLOT (dispatchEdit()));
+
+ // undo
+ connect (mUndoList, SIGNAL(empty()), this, SLOT(disableUndo()));
+ connect (mUndoList, SIGNAL(filled()), this, SLOT(enableUndo()));
+
+ // and redo
+ connect (mRedoList, SIGNAL(empty()), this, SLOT(disableRedo()));
+ connect (mRedoList, SIGNAL(filled()), this, SLOT(enableRedo()));
+
+ // paste
+ connect (kapp->clipboard(), SIGNAL (dataChanged()),
+ this, 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, SIGNAL(doAction(const QString&)),
+ mView, SLOT(startService(const QString&)));
+ connect (mStopDlg, SIGNAL(doAction(const QString&)),
+ mView, SLOT(editService(const QString&)));
+ connect (mRestartDlg, SIGNAL(doAction(const QString&)),
+ mView, SLOT(restartService(const QString&)));
+ connect (mEditDlg, SIGNAL(doAction(const QString&)),
+ mView, SLOT(editService(const QString&)));
+
+ connect (mStartDlg, SIGNAL (display (bool)),
+ this, SLOT (dispatchStartService (bool)));
+ connect (mStopDlg, SIGNAL (display (bool)),
+ this, SLOT (dispatchStopService (bool)));
+ connect (mRestartDlg, SIGNAL (display (bool)),
+ this, SLOT (dispatchRestartService (bool)));
+ connect (mEditDlg, SIGNAL (display (bool)),
+ this, SLOT (dispatchEditService (bool)));
+
+}
+
+void KSVTopLevel::initActions ()
+{
+ KActionCollection* coll = actionCollection();
+
+ // setup File menu
+ mFileRevert = KStdAction::revert (this, SLOT (slotClearChanges()), coll);
+ mFileRevert->setText (i18n("Re&vert Configuration"));
+
+ mFileLoad = KStdAction::open (this, SLOT (load()), coll);
+ mFileLoad->setText (i18n ("&Open..."));
+
+ mFileSave = KStdAction::save(this, SLOT(slotAcceptChanges()), coll);
+ mFileSave->setText (i18n("&Save Configuration"));
+
+ mFileSaveAs = KStdAction::saveAs (this, SLOT (saveAs ()), coll);
+
+ mFileSaveLog = KStdAction::save (this, 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, SLOT (print()), coll);
+
+ mFilePrintLog = KStdAction::print(this, SLOT(printLog()), coll, "ksysv_print_log");
+ mFilePrintLog->setText( i18n("&Print Log..."));
+ mFilePrintLog->setEnabled (false);
+
+ mFileQuit = KStdAction::quit(this, SLOT(close()), coll);
+
+ // setup Edit menu
+ mEditUndo = KStdAction::undo(this, SLOT(editUndo()), coll);
+ mEditUndo->setEnabled (false);
+ mEditRedo = KStdAction::redo(this, SLOT(editRedo()), coll);
+ mEditUndo->setEnabled (false);
+ mEditCut = KStdAction::cut(this, SLOT(editCut()), coll);
+ mEditCopy = KStdAction::copy(this, SLOT(editCopy()), coll);
+ mEditPaste = KStdAction::paste(this, SLOT(editPaste()), coll);
+ mPasteAppend = KStdAction::paste (this, SLOT (pasteAppend()),
+ coll, "ksysv_paste_append");
+
+ mEditProperties = new KAction (i18n("P&roperties"), 0,
+ this, SLOT(properties()),
+ coll, "ksysv_properties");
+
+ mOpenDefault = new KAction (i18n ("&Open"), 0,
+ this, SLOT (editService()),
+ coll, "ksysv_open_service");
+
+ mOpenWith = new KActionMenu (i18n ("Open &With"), coll, "ksysv_open_with");
+
+ // setup Settings menu
+ createStandardStatusBarAction();
+ setStandardToolBarMenuEnabled(true);
+ KStdAction::keyBindings (this, SLOT(configureKeys()), coll);
+ KStdAction::configureToolbars (this, SLOT(configureToolbars()), coll);
+ KStdAction::saveOptions(this, SLOT(saveOptions()), coll);
+ KStdAction::preferences(this, SLOT(slotShowConfig()), coll);
+ mOptionsToggleLog = new KToggleAction (i18n("Show &Log"), "toggle_log", 0,
+ this, SLOT (toggleLog()),
+ coll, "ksysv_toggle_log");
+ mOptionsToggleLog->setCheckedState(i18n("Hide &Log"));
+
+ // setup Tools menu
+ mToolsStartService = new KToggleAction (i18n("&Start Service..."), "ksysv_start", 0,
+ mStartDlg, SLOT (toggle()),
+ coll, "ksysv_start_service");
+
+ mToolsStopService = new KToggleAction (i18n("&Stop Service..."), "ksysv_stop", 0,
+ mStopDlg, SLOT (toggle()),
+ coll, "ksysv_stop_service");
+
+ mToolsRestartService = new KToggleAction (i18n("&Restart Service..."), 0,
+ mRestartDlg, SLOT (toggle()),
+ coll, "ksysv_restart_service");
+
+ mToolsEditService = new KToggleAction (i18n("&Edit Service..."), 0,
+ mEditDlg, 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();
+
+ QHBox* visBox = new QHBox (status, "visBox");
+ QButtonGroup* group = new QButtonGroup (this, "visButtonGroup");
+ group->hide();
+ connect (group, SIGNAL (clicked (int)), this, SLOT (toggleRunlevel (int)));
+
+ QWhatsThis::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>"));
+ QToolTip::add (visBox, i18n ("Show only the selected runlevels"));
+
+ new QLabel (i18n("Show runlevels:"), visBox, "visLabel");
+ for (int i = 0; i < ksv::runlevelNumber; ++i)
+ {
+ QString label; label.setNum (i);
+
+ mVisible[i] = new QCheckBox (label, visBox, label.latin1());
+ mVisible[i]->setChecked (mConfig->showRunlevel (i));
+
+ group->insert (mVisible[i]);
+ }
+
+ QHBox* authIconBox = new QHBox (status, "AuthIconBox");
+ QWidget* strut = new QWidget (authIconBox, "Strut");
+ strut->setFixedWidth (KDialog::spacingHint());
+ mAuth = new RunlevelAuthIcon (mConfig->scriptPath(), mConfig->runlevelPath(), authIconBox);
+ connect (mAuth, SIGNAL (authChanged(bool)), mView, SLOT(multiplexEnabled(bool)));
+ connect (mAuth, SIGNAL (authChanged(bool)), this, SLOT(writingEnabled(bool)));
+
+ QWhatsThis::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, SIGNAL (updateColors ()),
+ this, SLOT (updateColors ()));
+
+ connect (mPreferences, SIGNAL (updateServicesPath ()),
+ this, SLOT (updateServicesPath ()));
+
+ connect (mPreferences, SIGNAL (updateRunlevelsPath ()),
+ this, SLOT (updateRunlevelsPath ()));
+
+ connect (mPreferences, SIGNAL (updateFonts ()),
+ mView, SLOT (repaintRunlevels ()));
+ }
+
+// mPreferences->setInitialSize (QSize (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 QString& 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") : QString::null, 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 QPrintDialog* dlg = new QPrintDialog (&prt, this, "KSysV Print Dialog");
+// dlg->setCaption(kapp->makeStdCaption (i18n("Print")));
+
+// if (dlg->exec() == QDialog::Accepted)
+// {
+// int y = 10;
+// QPainter p;
+// p.begin( &prt );
+
+// QPaintDeviceMetrics metrics (&prt);
+
+// p.setFont (QFont("courier", 20, QFont::Bold));
+// QFontMetrics 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, QDateTime::currentDateTime().toString());
+// y += fm.lineSpacing() * 2; // an extra empty line
+
+// for (int i = 0; i < ksv::runlevelNumber; ++i)
+// {
+// p.setFont (QFont("courier", 16, QFont::Bold));
+// QFontMetrics 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 (QFont("courier", 10));
+// fm = p.fontMetrics();
+
+// for (QListViewItemIterator 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 (QFont("courier", 16, QFont::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 (QFont("courier", 10));
+// fm = p.fontMetrics();
+
+// for (QListViewItemIterator 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 (QFont("courier", 16, QFont::Bold));
+// fm = p.fontMetrics();
+// y += fm.lineSpacing() * 3; // two extra empty line
+// }
+// // QStringList lines = QStringList::split ('\n', mView->log(), true);
+// // for(QStringList::Iterator it = lines.begin();
+// // it != lines.end();
+// // ++it)
+// // {
+// // y += fm.ascent();
+
+// // QString line = *it;
+// // if (line.isNull())
+// // line = " ";
+
+// // line.replace( QRegExp("\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);
+
+ QPainter p (prt);
+ QPaintDeviceMetrics pm (prt);
+ const int height = pm.height();
+ const int width = pm.width();
+
+ QStringList lines = QStringList::split ('\n', mView->xmlLog(), true);
+ QStringList::Iterator line = lines.begin();
+
+ int y = 0;
+
+ {
+ QSimpleRichText rheading (i18n("<h1>KDE Sys-V Init Editor Log</h1>"),
+ QFont("times"), QString::null, ksv::styleSheet(),
+ QMimeSourceFactory::defaultFactory());
+ rheading.setWidth (&p, width);
+ int tmp_h = rheading.height();
+ QRegion region (0, y, width, tmp_h);
+ rheading.draw (&p, 0, y, region, colorGroup(), 0L);
+
+ y += tmp_h;
+
+ QSimpleRichText rdate (i18n("<h3>Printed on %1</h3><br/><br/>").arg(KGlobal::locale()->formatDateTime(QDateTime::currentDateTime())),
+ QFont("times"), QString::null, ksv::styleSheet(),
+ QMimeSourceFactory::defaultFactory());
+ rdate.setWidth (&p, width);
+ tmp_h = rdate.height();
+ QRegion r2 (0, y, width, tmp_h);
+ rdate.draw (&p, 0, y, r2, colorGroup(), 0L);
+
+ y += tmp_h;
+ }
+
+ while (line != lines.end())
+ {
+ while (y < height)
+ {
+ QSimpleRichText rich (*line, QFont("times"), QString::null, ksv::styleSheet(),
+ QMimeSourceFactory::defaultFactory());
+ rich.setWidth (&p, width);
+
+ int tmp_h = rich.height();
+ if (y + tmp_h > height)
+ break;
+
+ QRegion 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 (QCloseEvent* 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
+ {
+ QMimeSource* 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 QString& filter = ksv::logFileFilter();
+ static const QString& ext = ksv::logFileExtension();
+ QString filename = KFileDialog::getSaveFileName(0L, filter, this);
+
+ if (filename.isEmpty())
+ return;
+ else if (filename.right(ext.length()) != ext)
+ filename += ext;
+
+ QFile file(filename);
+
+ file.open( IO_WriteOnly | IO_Raw );
+ QTextStream s(&file);
+
+ s << "KDE System V Init Editor"
+ << endl
+ << QDateTime::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, SIGNAL( newToolbarConfig() ), this, 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 QString& filter = ksv::nativeFileFilter();
+ static const QString& ext = ksv::nativeFileExtension();
+ QString filename = KFileDialog::getSaveFileName(0L, filter, this);
+
+ if (filename.isEmpty())
+ return;
+ else if (filename.right(ext.length()) != ext)
+ filename += ext;
+
+ QFile file(filename);
+ // we're busy
+ KBusyManager::self()->setBusy (true);
+
+ file.open (IO_WriteOnly | IO_Raw);
+ QDataStream 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 QString& filter = ksv::nativeFileFilter();
+ QString filename = KFileDialog::getOpenFileName(0L, filter, this);
+
+ if (filename.isEmpty())
+ return;
+
+ QFile file(filename);
+ KBusyManager::self()->setBusy (true);
+
+ file.open (IO_ReadOnly | IO_Raw);
+ QDataStream s (&file);
+ QValueList<KSVData>* startLists = new QValueList<KSVData>[ksv::runlevelNumber];
+ QValueList<KSVData>* stopLists = new QValueList<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"
diff --git a/ksysv/TopWidget.h b/ksysv/TopWidget.h
new file mode 100644
index 0000000..6415538
--- /dev/null
+++ b/ksysv/TopWidget.h
@@ -0,0 +1,153 @@
+/***************************************************************************
+ begin : Sun Oct 3 1999
+ copyright : (C) 1997-99 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef KSV_TOPWIDGET_H
+#define KSV_TOPWIDGET_H
+
+#include <kmainwindow.h>
+
+class QCheckBox;
+
+class KAction;
+class KToggleAction;
+class KActionMenu;
+class KMenuBar;
+class KStatusBar;
+class KToolBar;
+class KActionCollection;
+
+class ActionList;
+class KSVAction;
+class ServiceDlg;
+class KSVConfig;
+class KSVItem;
+class KSVContent;
+class KSVPreferences;
+class RunlevelAuthIcon;
+
+class KSVTopLevel : public KMainWindow
+{
+ Q_OBJECT
+
+public:
+ KSVTopLevel();
+ virtual ~KSVTopLevel();
+
+public slots:
+ void setCaption (bool changed);
+
+protected:
+ virtual bool queryExit();
+ virtual void closeEvent( QCloseEvent* e );
+ void initTools();
+ void initActions ();
+ void initStatusBar();
+
+ KActionCollection* filteredActions ();
+
+private slots:
+ void slotClearChanges();
+ void slotAcceptChanges();
+ void pushUndoAction (KSVAction*);
+ void slotShowConfig();
+ void slotReadConfig();
+ void pasteAppend ();
+ void toggleLog();
+ void saveOptions();
+ void slotUpdateRunning (const QString&);
+ void editCut();
+ void editCopy();
+ void editPaste();
+ void editUndo();
+ void editRedo();
+ void editService ();
+ void saveAs ();
+ void load ();
+ void print();
+ void printLog();
+ void setChanged( bool val = true );
+ void setPaste( bool val = false );
+ void properties();
+ void scriptProperties();
+ void setLog( bool val );
+ void catchCannotGenerateNumber();
+
+ void configureKeys ();
+ void configureToolbars ();
+
+ void enableUndo();
+ void disableUndo();
+ void enableRedo();
+ void disableRedo();
+
+ void dispatchEditService (bool);
+ void dispatchStartService (bool);
+ void dispatchStopService (bool);
+ void dispatchRestartService (bool);
+
+ void dispatchEdit ();
+
+ /**
+ * initialize the view (plus some other things)
+ */
+ void initView();
+
+ void slotSaveLog();
+ void enableLogActions();
+
+ void toggleRunlevel (int index);
+
+ void updateColors ();
+ void updateServicesPath ();
+ void updateRunlevelsPath ();
+
+ void writingEnabled (bool);
+ void slotNewToolbarConfig();
+
+private:
+ KSVConfig* mConfig;
+ KSVContent* mView;
+
+ KSVPreferences* mPreferences;
+
+ KAction *mEditUndo, *mEditRedo, *mEditCut, *mEditCopy, *mEditPaste,
+ *mPasteAppend, *mEditProperties;
+
+ KAction *mFileRevert, *mFileLoad, *mFilePrint, *mFilePrintLog,
+ *mFileSave, *mFileSaveAs, *mFileSaveLog, *mFileQuit;
+
+ KToggleAction *mToolsStartService, *mToolsStopService,
+ *mToolsRestartService, *mToolsEditService;
+
+ KToggleAction *mOptionsToggleLog;
+
+ KActionMenu* mOpenWith;
+ KAction* mOpenDefault;
+
+ bool mChanged;
+
+ ActionList* mUndoList;
+ ActionList* mRedoList;
+
+ ServiceDlg* mStartDlg;
+ ServiceDlg* mStopDlg;
+ ServiceDlg* mRestartDlg;
+ ServiceDlg* mEditDlg;
+
+ RunlevelAuthIcon* mAuth;
+ QCheckBox** mVisible;
+};
+
+#endif // KSV_TOPWIDGET_H
+
diff --git a/ksysv/configure.in.in b/ksysv/configure.in.in
new file mode 100644
index 0000000..e97862c
--- /dev/null
+++ b/ksysv/configure.in.in
@@ -0,0 +1,11 @@
+dnl Disabled on BSD, where it doesn't apply
+AC_MSG_CHECKING(if ksysv can be compiled)
+case "$host" in
+ *-*-*bsd-gnu) ksysv_compile=yes;;
+ *-*-*bsd*) ksysv_compile=no;;
+ *) ksysv_compile=yes;;
+esac
+AC_MSG_RESULT($ksysv_compile)
+if test "$ksysv_compile" = "no"; then
+ DO_NOT_COMPILE="$DO_NOT_COMPILE ksysv"
+fi
diff --git a/ksysv/configwizard.ui b/ksysv/configwizard.ui
new file mode 100644
index 0000000..8edc980
--- /dev/null
+++ b/ksysv/configwizard.ui
@@ -0,0 +1,626 @@
+<!DOCTYPE UI><UI>
+<class>ConfigWizard</class>
+<author>Peter Putzer</author>
+<include location="global">klocale.h</include>
+<pixmapfunction>DesktopIcon</pixmapfunction>
+<widget>
+ <class>QWizard</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>ConfigWizard</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>394</width>
+ <height>291</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Configuration Wizard</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>mOSPage</cstring>
+ </property>
+ <attribute>
+ <name>title</name>
+ <string>Operating System</string>
+ </attribute>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>0</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1_2</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&lt;h3&gt;What Operating System do you use?&lt;/h3&gt;</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QFrame</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>mOSSpacer</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Plain</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>NoFrame</enum>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget>
+ <class>QButtonGroup</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>mOSBox</cstring>
+ </property>
+ <property stdset="1">
+ <name>title</name>
+ <string>Choose Your Operating System</string>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QRadioButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>RadioButton7</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Linux</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QRadioButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>RadioButton8</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Other</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <spacer>
+ <property>
+ <name>name</name>
+ <cstring>Spacer1</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ <widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>mDistributionPage</cstring>
+ </property>
+ <attribute>
+ <name>title</name>
+ <string>Distribution</string>
+ </attribute>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>0</number>
+ </property>
+ <widget>
+ <class>QButtonGroup</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>mDistributionBox</cstring>
+ </property>
+ <property stdset="1">
+ <name>title</name>
+ <string>Choose Your Distribution</string>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QRadioButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>mDistrib1</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Debian GNU/Linux</string>
+ </property>
+ <property stdset="1">
+ <name>checked</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QRadioButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>mDistrib2</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Red Hat Linux</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QRadioButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>mDistrib3</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;SuSE Linux</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QRadioButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>mDistrib4</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Mandrake Linux</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QRadioButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>mDistrib5</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Corel Linux OS</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QRadioButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>mDistrib6</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Conec&amp;tiva Linux</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QRadioButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>mDistrib7</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Other</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <spacer>
+ <property>
+ <name>name</name>
+ <cstring>mDistribSpacer</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ <widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>mPathsPage</cstring>
+ </property>
+ <attribute>
+ <name>title</name>
+ <string>Paths</string>
+ </attribute>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>0</number>
+ </property>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>mServicesLayout</cstring>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>0</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>mServicesLabel</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Service path:</string>
+ </property>
+ <property>
+ <name>buddy</name>
+ <cstring>mServicesPath</cstring>
+ </property>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>mServicesButtonLayout</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>0</number>
+ </property>
+ <widget>
+ <class>KLineEdit</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>mServicesPath</cstring>
+ </property>
+ <property stdset="1">
+ <name>minimumSize</name>
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>StrongFocus</enum>
+ </property>
+ <property>
+ <name>toolTip</name>
+ <string>Enter the path to the folder containing the services</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>mBrowseServices</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Browse...</string>
+ </property>
+ <property>
+ <name>toolTip</name>
+ <string>Select the folder containing the services</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ <widget>
+ <class>QFrame</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>mSpacer</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Plain</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>NoFrame</enum>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>minimumSize</name>
+ <size>
+ <width>0</width>
+ <height>10</height>
+ </size>
+ </property>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>mRunlevelLayout</cstring>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>0</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>mRunlevelLabel</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Runlevel path:</string>
+ </property>
+ <property>
+ <name>buddy</name>
+ <cstring>mRunlevelPath</cstring>
+ </property>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>mRunlevelButtonLayout</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>0</number>
+ </property>
+ <widget>
+ <class>KLineEdit</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>mRunlevelPath</cstring>
+ </property>
+ <property stdset="1">
+ <name>minimumSize</name>
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>StrongFocus</enum>
+ </property>
+ <property>
+ <name>toolTip</name>
+ <string>Enter the path to the folder containing the runlevel folders</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>mBrowseRunlevel</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Br&amp;owse...</string>
+ </property>
+ <property>
+ <name>toolTip</name>
+ <string>Select the folder containing the runlevel folders </string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ <spacer>
+ <property>
+ <name>name</name>
+ <cstring>mEmptySpace</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ <widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>mFinishedPage</cstring>
+ </property>
+ <attribute>
+ <name>title</name>
+ <string>Configuration Complete</string>
+ </attribute>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>0</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&lt;h1&gt;Congratulations!&lt;/h1&gt;
+&lt;p&gt;
+You have finished the initial configuration of SysV-Init Editor. &lt;b&gt;Press&lt;/b&gt; the button labeled &lt;b&gt;Finish&lt;/b&gt; to start editing your init-configuration.
+&lt;/p&gt;</string>
+ </property>
+ <property stdset="1">
+ <name>textFormat</name>
+ <enum>RichText</enum>
+ </property>
+ <property stdset="1">
+ <name>alignment</name>
+ <set>AlignTop|AlignLeft</set>
+ </property>
+ <property>
+ <name>vAlign</name>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+</widget>
+<connections>
+ <connection>
+ <sender>mDistributionBox</sender>
+ <signal>clicked(int)</signal>
+ <receiver>ConfigWizard</receiver>
+ <slot>chooseDistribution(int)</slot>
+ </connection>
+ <connection>
+ <sender>mBrowseServices</sender>
+ <signal>clicked()</signal>
+ <receiver>ConfigWizard</receiver>
+ <slot>browseServices()</slot>
+ </connection>
+ <connection>
+ <sender>mBrowseRunlevel</sender>
+ <signal>clicked()</signal>
+ <receiver>ConfigWizard</receiver>
+ <slot>browseRunlevels()</slot>
+ </connection>
+ <slot access="protected">browseRunlevels()</slot>
+ <slot access="protected">chooseDistribution(int)</slot>
+ <slot access="protected">browseServices()</slot>
+</connections>
+</UI>
diff --git a/ksysv/genui.sh b/ksysv/genui.sh
new file mode 100755
index 0000000..579872f
--- /dev/null
+++ b/ksysv/genui.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+UIC="uic -tr i18n"
+PAGES="path misc lookandfeel"
+WIZARDS="config"
+OTHERS=""
+
+for i in ${PAGES}; do
+ ${UIC} -o ${i}config.h ${i}config.ui
+ ${UIC} -o ${i}config.cpp -impl ${i}config.h ${i}config.ui
+done
+
+for i in ${WIZARDS}; do
+ n="${i}wizard"
+ ${UIC} -o ${n}.h ${n}.ui
+ ${UIC} -o ${n}.cpp -impl ${n}.h ${n}.ui
+
+ perl -pi -e "s/qwizard\.h/kwizard\.h/" ${n}.h
+ perl -pi -e "s/QWizard/KWizard/" ${n}.{cpp,h}
+done
+
+for i in ${OTHERS}; do
+ ${UIC} -o ${i}.h ${i}.ui
+ ${UIC} -o ${i}.cpp -impl ${i}.h ${i}.ui
+done
diff --git a/ksysv/hi16-app-ksysv.png b/ksysv/hi16-app-ksysv.png
new file mode 100644
index 0000000..999809e
--- /dev/null
+++ b/ksysv/hi16-app-ksysv.png
Binary files differ
diff --git a/ksysv/hi22-app-ksysv.png b/ksysv/hi22-app-ksysv.png
new file mode 100644
index 0000000..e286b73
--- /dev/null
+++ b/ksysv/hi22-app-ksysv.png
Binary files differ
diff --git a/ksysv/hi32-app-ksysv.png b/ksysv/hi32-app-ksysv.png
new file mode 100644
index 0000000..89a85b4
--- /dev/null
+++ b/ksysv/hi32-app-ksysv.png
Binary files differ
diff --git a/ksysv/hi48-app-ksysv.png b/ksysv/hi48-app-ksysv.png
new file mode 100644
index 0000000..5845c03
--- /dev/null
+++ b/ksysv/hi48-app-ksysv.png
Binary files differ
diff --git a/ksysv/kbusymanager.cpp b/ksysv/kbusymanager.cpp
new file mode 100644
index 0000000..d6c6e9c
--- /dev/null
+++ b/ksysv/kbusymanager.cpp
@@ -0,0 +1,94 @@
+/*
+** Copyright (C) 2000 Peter Putzer <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; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program in a file called COPYING; if not, write to
+** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+** MA 02110-1301, USA.
+*/
+
+/*
+** Bug reports and questions can be sent to kde-devel@kde.org
+*/
+#include "kbusymanager.h"
+
+#include <qvaluestack.h>
+#include <qapplication.h>
+
+#include <kcursor.h>
+#include <kapplication.h>
+
+class KBusyManager::Private
+{
+public:
+ Private()
+ : Size (-1)
+ {
+ }
+
+ ~Private()
+ {
+ }
+
+ QValueStack<bool> Stack;
+ int Size;
+};
+
+KBusyManager* KBusyManager::self ()
+{
+ static KBusyManager kb;
+
+ return &kb;
+}
+
+bool KBusyManager::isBusy () const
+{
+ return d->Stack.top();
+}
+
+void KBusyManager::setBusy (bool val)
+{
+ d->Stack.push (val);
+ d->Size++;
+
+ if (val)
+ QApplication::setOverrideCursor (KCursor::waitCursor());
+
+ kapp->mainWidget()->setEnabled (!val);
+}
+
+void KBusyManager::restore ()
+{
+ if (d->Size < 1)
+ return;
+
+ bool oldBusy = d->Stack.pop();
+
+ if (oldBusy)
+ QApplication::restoreOverrideCursor();
+
+ kapp->mainWidget()->setEnabled (!d->Stack.top());
+}
+
+KBusyManager::KBusyManager ()
+ : d (new Private())
+{
+ setBusy (false);
+}
+
+KBusyManager::~KBusyManager ()
+{
+ delete d;
+}
diff --git a/ksysv/kbusymanager.h b/ksysv/kbusymanager.h
new file mode 100644
index 0000000..2cebeaf
--- /dev/null
+++ b/ksysv/kbusymanager.h
@@ -0,0 +1,49 @@
+/*
+** Copyright (C) 2000 Peter Putzer <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; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program in a file called COPYING; if not, write to
+** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+** MA 02110-1301, USA.
+*/
+
+/*
+** Bug reports and questions can be sent to kde-devel@kde.org
+*/
+#ifndef KBUSYMANAGER_H
+#define KBUSYMANAGER_H
+
+class KBusyManager
+{
+public:
+ static KBusyManager* self ();
+
+ bool isBusy () const;
+ void setBusy (bool val);
+ void restore ();
+
+ ~KBusyManager(); // to make gcc happy, should be private.
+
+private:
+ KBusyManager ();
+
+ KBusyManager& operator= (const KBusyManager&); // undefined
+
+ class Private;
+ Private* d;
+};
+
+#endif // KBUSYMANAGER_H
diff --git a/ksysv/kdltooltip.cpp b/ksysv/kdltooltip.cpp
new file mode 100644
index 0000000..a0947ce
--- /dev/null
+++ b/ksysv/kdltooltip.cpp
@@ -0,0 +1,95 @@
+/***************************************************************************
+ begin : Tue Oct 5 1999
+ copyright : (C) 1999 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. *
+ * *
+ ***************************************************************************/
+
+#include <qrect.h>
+#include <qscrollbar.h>
+#include <qheader.h>
+
+#include <kdebug.h>
+
+#include "ksvdraglist.h"
+#include "kdltooltip.h"
+
+KDLToolTip::KDLToolTip (KSVDragList *parent, QToolTipGroup* group)
+ : QToolTip(parent, group),
+ mParent (parent)
+{
+}
+
+KDLToolTip::~KDLToolTip()
+{
+}
+
+void KDLToolTip::maybeTip (const QPoint& p)
+{
+ if (!mParent->displayToolTips())
+ return;
+
+ QString text;
+ QRect rect;
+
+ const QRect vert = mParent->verticalScrollBar()->geometry();
+ const QRect horiz = mParent->horizontalScrollBar()->geometry();
+
+ if (vert.contains(p))
+ {
+ rect = vert;
+
+ if (!mParent->commonToolTips())
+ text = mParent->verticalScrollBarTip();
+ else
+ text = mParent->tooltip();
+ }
+ else if (horiz.contains(p))
+ {
+ rect = horiz;
+ if (!mParent->commonToolTips())
+ text = mParent->horizontalScrollBarTip();
+ else
+ text = mParent->tooltip();
+
+ }
+ else
+ {
+ QPoint rp = mParent->viewport()->mapFromParent (p);
+ QListViewItem* i = mParent->itemAt (rp);
+ KSVItem* item = static_cast<KSVItem*> (i);
+
+ rect = mParent->header()->geometry();
+ if (rect.contains (p))
+ {
+ text = mParent->tooltip();
+ }
+ else if (item)
+ {
+ rect = mParent->itemRect (i);
+ rect.moveTopLeft (mParent->viewport()->mapToParent (rect.topLeft()));
+
+ text = item->tooltip();
+ }
+ else
+ {
+ rect = mParent->rect();
+
+ QListViewItem* last = mParent->lastItem();
+ if (last)
+ rect.setTop (mParent->viewport()->mapToParent (mParent->itemRect(last).bottomRight()).y());
+
+ text = mParent->tooltip();
+ }
+ }
+
+ if (!text.isEmpty())
+ tip (rect, text);
+}
diff --git a/ksysv/kdltooltip.h b/ksysv/kdltooltip.h
new file mode 100644
index 0000000..a107383
--- /dev/null
+++ b/ksysv/kdltooltip.h
@@ -0,0 +1,43 @@
+/***************************************************************************
+ begin : Tue Oct 5 1999
+ copyright : (C) 1999 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef KDLTOOLTIP_H
+#define KDLTOOLTIP_H
+
+#include <qtooltip.h>
+
+class KSVDragList;
+
+/**
+ * @short custom tooltip for use in @ref KDragList
+ * @author Peter Putzer
+ */
+class KDLToolTip : public QToolTip
+{
+public:
+ KDLToolTip (KSVDragList *parent, QToolTipGroup* group = 0L);
+ virtual ~KDLToolTip();
+
+protected:
+ /**
+ * Reimplemented from QToolTip for internal reasons.
+ */
+ virtual void maybeTip (const QPoint&);
+
+private:
+ KSVDragList* mParent;
+};
+
+#endif
+
diff --git a/ksysv/kscroller.cpp b/ksysv/kscroller.cpp
new file mode 100644
index 0000000..1f69b74
--- /dev/null
+++ b/ksysv/kscroller.cpp
@@ -0,0 +1,191 @@
+// (c) 2000 Peter Putzer
+
+#include <qscrollbar.h>
+#include <qlayout.h>
+#include <qstyle.h>
+
+#include <kdebug.h>
+#include <kdialog.h>
+#include <kapplication.h>
+
+#include "kscroller.h"
+
+class KScroller::KScrollerPrivate
+{
+public:
+ KScrollerPrivate ()
+ : setCornerWidget (0L)
+ {
+ }
+
+ ~KScrollerPrivate () {}
+
+ QWidget* setCornerWidget;
+};
+
+KScroller::KScroller (QWidget* parent, const char* name)
+ : QFrame (parent, name),
+ d (new KScrollerPrivate()),
+ mVertical (new QScrollBar (QScrollBar::Vertical, this)),
+ mHorizontal (new QScrollBar (QScrollBar::Horizontal, this)),
+ mCornerWidget (new QWidget (this)),
+ mContent (0L),
+ mVerticalOld (0),
+ mHorizontalOld (0)
+{
+ mCornerWidget->hide();
+ mVertical->hide();
+ mHorizontal->hide();
+
+ connect (mVertical, SIGNAL (valueChanged (int)),
+ this, SLOT (scrollVertical (int)));
+ connect (mHorizontal, SIGNAL (valueChanged (int)),
+ this, SLOT (scrollHorizontal (int)));
+}
+
+KScroller::~KScroller ()
+{
+ delete d;
+}
+
+void KScroller::setContent (QWidget* content)
+{
+ delete mContent;
+
+ mContent = content;
+ updateScrollBars();
+}
+
+void KScroller::setCornerWidget (QWidget* corner)
+{
+ delete mCornerWidget;
+
+ mCornerWidget = d->setCornerWidget = corner;
+
+ updateScrollBars();
+}
+
+QWidget* KScroller::cornerWidget ()
+{
+ return d->setCornerWidget;
+}
+
+void KScroller::resizeEvent (QResizeEvent* e)
+{
+ QFrame::resizeEvent (e);
+
+ updateScrollBars();
+}
+
+QSize KScroller::minimumSizeHint() const
+{
+ QSize size = sizeHint();
+ if (size.width() > 300)
+ size.setWidth(300);
+ return size;
+}
+
+QSize KScroller::sizeHint() const
+{
+ QSize size = mContent->minimumSize();
+ int extra = kapp->style().pixelMetric( QStyle::PM_ScrollBarExtent, 0 );
+ size += QSize( extra, extra );
+ return size;
+}
+
+void KScroller::updateScrollBars ()
+{
+ int w = width();
+ int h = height();
+ QSize cs = mContent->minimumSize();
+
+ setupVertical ( cs.width(), cs.height(), w, h);
+ setupHorizontal ( cs.width(), cs.height(), w, h);
+ mContent->resize (cs);
+
+ setupCornerWidget (w, h);
+}
+
+void KScroller::setupHorizontal (int cw, int, int w, int h)
+{
+ mHorizontal->setValue (0);
+ mHorizontalOld = 0;
+
+ if (cw > w)
+ {
+ int extra = kapp->style().pixelMetric( QStyle::PM_ScrollBarExtent, 0 );
+
+ if (!mVertical->isHidden())
+ w -= extra;
+
+ mHorizontal->setRange (0, cw - w);
+ mHorizontal->setPageStep (w);
+ mHorizontal->setLineStep (25);
+ mHorizontal->setGeometry (0, h - extra, w, extra);
+
+ mHorizontal->raise();
+ mHorizontal->show();
+ }
+ else
+ {
+ mHorizontal->hide();
+ }
+}
+
+void KScroller::setupVertical (int, int ch, int w, int h)
+{
+ mVertical->setValue (0);
+ mVerticalOld = 0;
+
+ if (ch > h)
+ {
+ int extra = kapp->style().pixelMetric( QStyle::PM_ScrollBarExtent, 0 );
+ mVertical->setRange (0, ch - h);
+ mVertical->setPageStep (h);
+ mVertical->setLineStep (25);
+
+ mVertical->setGeometry (w - extra, 0, extra, h);
+
+ mVertical->raise();
+ mVertical->show();
+ }
+ else
+ {
+ mVertical->hide();
+ }
+}
+
+void KScroller::scrollVertical (int value)
+{
+ int amount = value - mVerticalOld;
+ mVerticalOld = value;
+
+ mContent->move (mContent->x(), mContent->y() - amount);
+}
+
+void KScroller::scrollHorizontal (int value)
+{
+ int amount = value - mHorizontalOld;
+ mHorizontalOld = value;
+
+ mContent->move (mContent->x() - amount, mContent->y());
+}
+
+void KScroller::setupCornerWidget (int w, int h)
+{
+ if (!mVertical->isHidden() && !mHorizontal->isHidden())
+ {
+ int extra = kapp->style().pixelMetric( QStyle::PM_ScrollBarExtent, 0 );
+
+ mCornerWidget->raise();
+ mCornerWidget->setGeometry (w - extra, h - extra, extra, extra);
+
+ mCornerWidget->show();
+ }
+ else
+ {
+ mCornerWidget->hide();
+ }
+}
+
+#include "kscroller.moc"
diff --git a/ksysv/kscroller.h b/ksysv/kscroller.h
new file mode 100644
index 0000000..09329f1
--- /dev/null
+++ b/ksysv/kscroller.h
@@ -0,0 +1,150 @@
+// (c) 2000 Peter Putzer
+#ifndef KSCROLLER_H
+#define KSCROLLER_H
+
+#include <qframe.h>
+
+class QScrollBar;
+
+/**
+ * A window that automatically enables scrollbars
+ * if it's smaller than the content.
+ *
+ * @author Peter Putzer <putzer@kde.org>
+ * @version $Id$
+ */
+class KScroller : public QFrame
+{
+ Q_OBJECT
+
+public:
+ /**
+ * Constructor.
+ *
+ * @param parent the parent of this widget (passed on as ususal).
+ * @param name the name of this widget (as above).
+ */
+ KScroller (QWidget* parent = 0L, const char* name = 0L);
+
+ /**
+ * Destructor.
+ */
+ virtual ~KScroller ();
+
+ /**
+ * @return the vertical scrollbar.
+ */
+ inline QScrollBar* verticalScrollBar () { return mVertical; }
+
+ /**
+ * @return the horizontal scrollbar.
+ */
+ inline QScrollBar* horizontalScrollBar () { return mHorizontal; }
+
+ /**
+ * @return the current content, or 0L if none set.
+ */
+ inline QWidget* content () { return mContent; }
+
+ /**
+ * @return the current corner widget, or 0L if none set.
+ */
+ QWidget* cornerWidget ();
+
+public slots:
+ /**
+ * Sets the content. Ownership is transfered to the scroller, any
+ * previously set content will be deleted!
+ *
+ * @param content has to be a child of the KScroller.
+ */
+ void setContent (QWidget* content);
+
+ /**
+ * Sets the corner widget (the small widget that's located where the vertical and horizontal scrollbars
+ * allmost meet).
+ *
+ * @param corner has to be a child of the KScroller.
+ */
+ void setCornerWidget (QWidget* corner);
+
+ /**
+ * Update the scrollbars. Call whenever you change the contents minimumSize.
+ */
+ void updateScrollBars ();
+
+protected:
+ /**
+ * Reimplemented for internal reasons, the API is not affected.
+ */
+ virtual void resizeEvent (QResizeEvent*);
+
+ /**
+ * Reimplemented for internal reasons, the API is not affected.
+ */
+ virtual QSize sizeHint() const;
+
+ /**
+ * Reimplemented for internal reasons, the API is not affected.
+ */
+ virtual QSize minimumSizeHint() const;
+
+
+private slots:
+ /**
+ * Scroll vertically.
+ *
+ * @param value is the new slider value.
+ */
+ void scrollVertical (int value);
+
+ /**
+ * Scroll horizontally.
+ *
+ * @param value is the new slider value.
+ */
+ void scrollHorizontal (int value);
+
+private:
+ /**
+ * Set up the horizontal scrollbar.
+ *
+ * @param cw is the width of the content.
+ * @param ch is the height of the content.
+ * @param w is the width of the scroller.
+ * @param h is the height of the scroller.
+ */
+ void setupHorizontal (int cw, int ch, int w, int h);
+
+ /**
+ * Set up the vertical scrollbar
+ *
+ * @param cw is the width of the content.
+ * @param ch is the height of the content.
+ * @param w is the width of the scroller.
+ * @param h is the height of the scroller.
+ */
+ void setupVertical (int cw, int ch, int w, int h);
+
+ /**
+ * Set up the corner widget.
+ *
+ * @param w is the width of the scroller.
+ * @param h is the height of the scroller.
+ */
+ void setupCornerWidget (int w, int h);
+
+ class KScrollerPrivate;
+ KScrollerPrivate* d;
+
+ QScrollBar* mVertical;
+ QScrollBar* mHorizontal;
+ QWidget* mCornerWidget;
+
+ QWidget* mContent;
+
+ int mVerticalOld;
+ int mHorizontalOld;
+};
+
+#endif // KSCROLLER_H
diff --git a/ksysv/ksv_conf.cpp b/ksysv/ksv_conf.cpp
new file mode 100644
index 0000000..aa7ce8b
--- /dev/null
+++ b/ksysv/ksv_conf.cpp
@@ -0,0 +1,224 @@
+/***************************************************************************
+ begin : Sun Oct 3 1999
+ copyright : (C) 1997-99 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. *
+ * *
+ ***************************************************************************/
+// KSysV Config Object
+
+#include <kapplication.h>
+#include <kglobal.h>
+#include <kglobalsettings.h>
+#include <kmainwindow.h>
+#include <kconfig.h>
+
+#include "ksv_core.h"
+#include "ksv_conf.h"
+
+KSVConfig::KSVConfig ()
+ : mConfig (KGlobal::config())
+{
+ readSettings();
+}
+
+void KSVConfig::setPanningFactor (int val)
+{
+ mPanningFactor = val > 100 ? 100 : val;
+ mPanningFactor = mPanningFactor < 0 ? 0 : mPanningFactor;
+}
+
+void KSVConfig::readSettings()
+{
+ mConfig->setGroup("Path Settings");
+ mScriptPath = mConfig->readEntry("ScriptPath", "/etc/rc.d/init.d");
+ mRunlevelPath = mConfig->readEntry("RunlevelPath", "/etc/rc.d");
+
+ mConfig->setGroup("Other Settings");
+ mShowLog = mConfig->readBoolEntry("ShowLog", true);
+ mConfigured = mConfig->readBoolEntry("Configured", false);
+ mPanningFactor = mConfig->readNumEntry("PanningFactor", 80);
+ mShowDescription = mConfig->readBoolEntry("ShowDescription", true);
+
+ mConfig->setGroup("Colors");
+ mNewNormalColor = mConfig->readColorEntry ("New Text", &Qt::blue);
+ mNewSelectedColor = mConfig->readColorEntry ("New Selected Text", &Qt::blue);
+ mChangedNormalColor = mConfig->readColorEntry ("Changed Text", &Qt::red);
+ mChangedSelectedColor = mConfig->readColorEntry ("Changed Selected Text", &Qt::red);
+
+ mConfig->setGroup("Fonts");
+ QFont tmp = KGlobalSettings::generalFont();
+ mServiceFont = mConfig->readFontEntry ("Service Font", &tmp);
+ tmp = KGlobalSettings::fixedFont();
+ mNumberFont = mConfig->readFontEntry ("Number Font", &tmp);
+
+ readRunlevels();
+}
+
+void KSVConfig::readLegacySettings ()
+{
+ mConfig->setGroup("Path Settings");
+
+ mScriptPath = mConfig->readEntry("ScriptPath", "/etc/rc.d/init.d");
+ mRunlevelPath = mConfig->readEntry("RunlevelPath", "/etc/rc.d");
+
+ mConfig->setGroup("Other Settings");
+
+ mShowLog = mConfig->readBoolEntry("ShowLog", true);
+ mConfigured = mConfig->readBoolEntry("Configured", false);
+ mPanningFactor = mConfig->readNumEntry("PanningFactor", 80);
+ mShowDescription = mConfig->readBoolEntry("ShowDescription", true);
+ mConfig->setGroup("Colors");
+ mNewNormalColor = mConfig->readColorEntry("New", &Qt::blue);
+ mChangedNormalColor = mConfig->readColorEntry("Changed", &Qt::red);
+}
+
+void KSVConfig::writeSettings() {
+ mConfig->setGroup("Path Settings");
+ mConfig->writeEntry("ScriptPath", mScriptPath);
+ mConfig->writeEntry("RunlevelPath", mRunlevelPath);
+
+ mConfig->setGroup("Other Settings");
+ mConfig->writeEntry("ShowLog", mShowLog);
+ mConfig->writeEntry("Configured", mConfigured);
+ mConfig->writeEntry("PanningFactor", mPanningFactor);
+ mConfig->writeEntry("ShowDescription", mShowDescription);
+
+ mConfig->setGroup("Colors");
+ mConfig->writeEntry("New Text", mNewNormalColor);
+ mConfig->writeEntry("New Selected Text", mNewSelectedColor);
+ mConfig->writeEntry("Changed Text", mChangedNormalColor);
+ mConfig->writeEntry("Changed Selected Text", mChangedSelectedColor);
+
+ mConfig->setGroup("Fonts");
+ mConfig->writeEntry("Service Font", mServiceFont);
+ mConfig->writeEntry("Number Font", mNumberFont);
+
+ // save screen geometry
+ KMainWindow* mw = static_cast<KMainWindow*>(kapp->mainWidget());
+
+ if (mw)
+ {
+ mConfig->setGroup("Geometry");
+ mConfig->writeEntry("X-Position", mw->x());
+ mConfig->writeEntry("Y-Position", mw->y());
+ }
+
+ writeRunlevels();
+
+ // flush everything
+ mConfig->sync();
+}
+
+bool KSVConfig::showRunlevel (int index) const
+{
+ if (mShowRunlevel.contains (index))
+ return mShowRunlevel[index];
+ else
+ return false;
+}
+
+void KSVConfig::readRunlevels ()
+{
+ mConfig->setGroup ("Runlevels");
+
+ QValueList<int> list = mConfig->readIntListEntry ("Show Runlevels");
+
+ for (QValueList<int>::Iterator it = list.begin(); it != list.end(); ++it)
+ mShowRunlevel[*it] = true;
+
+ if (mShowRunlevel.isEmpty())
+ for (int i = 0; i < ksv::runlevelNumber; ++i)
+ mShowRunlevel[i] = true;
+}
+
+void KSVConfig::writeRunlevels ()
+{
+ QValueList<int> list;
+
+ for (QMap<int,bool>::Iterator it = mShowRunlevel.begin(); it != mShowRunlevel.end(); ++it)
+ if (it.data())
+ list.append (it.key());
+
+ mConfig->setGroup ("Runlevels");
+ mConfig->writeEntry ("Show Runlevels", list);
+}
+
+void KSVConfig::setShowRunlevel (int index, bool state)
+{
+ mShowRunlevel[index] = state;
+}
+
+QPoint KSVConfig::position() const
+{
+ mConfig->setGroup("Geometry");
+
+ return QPoint(mConfig->readNumEntry("X-Position", 0),
+ mConfig->readNumEntry("Y-Position", 0));
+}
+
+void KSVConfig::setScriptPath (const QString& path)
+{
+ mScriptPath = path;
+}
+
+void KSVConfig::setRunlevelPath (const QString& path)
+{
+ mRunlevelPath = path;
+}
+
+KSVConfig* KSVConfig::self()
+{
+ static KSVConfig conf;
+
+ return &conf;
+}
+
+void KSVConfig::setNewNormalColor (const QColor& col)
+{
+ mNewNormalColor = col;
+}
+
+void KSVConfig::setNewSelectedColor (const QColor& col)
+{
+ mNewSelectedColor = col;
+}
+
+void KSVConfig::setChangedNormalColor (const QColor& col)
+{
+ mChangedNormalColor = col;
+}
+
+void KSVConfig::setChangedSelectedColor (const QColor& col)
+{
+ mChangedSelectedColor = col;
+}
+
+void KSVConfig::setNumberFont (const QFont& font)
+{
+ mNumberFont = font;
+}
+
+void KSVConfig::setServiceFont (const QFont& font)
+{
+ mServiceFont = font;
+}
+
+void KSVConfig::setShowMessage (ksv::Messages msg, bool on)
+{
+ mConfig->setGroup("Notification Messages");
+ mConfig->writeEntry (ksv::notifications[msg], on);
+}
+
+bool KSVConfig::showMessage (ksv::Messages msg) const
+{
+ mConfig->setGroup("Notification Messages");
+ return mConfig->readBoolEntry (ksv::notifications[msg], true);
+}
+
diff --git a/ksysv/ksv_conf.h b/ksysv/ksv_conf.h
new file mode 100644
index 0000000..f17176a
--- /dev/null
+++ b/ksysv/ksv_conf.h
@@ -0,0 +1,143 @@
+/***************************************************************************
+ begin : Sun Oct 3 1999
+ copyright : (C) 1997-99 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef KSV_CONF_H
+#define KSV_CONF_H
+
+#include <qstring.h>
+#include <qpoint.h>
+#include <qfont.h>
+#include <qcolor.h>
+#include <qmap.h>
+
+#include "ksv_core.h"
+
+class KConfig;
+
+class KSVConfig
+{
+public:
+
+ inline ~KSVConfig() {}
+
+ void readSettings();
+ void readLegacySettings ();
+ void writeSettings();
+
+ void setPanningFactor (int val);
+
+ inline void setShowLog( bool val = false )
+ {
+ mShowLog = val;
+ }
+
+ void setNewNormalColor (const QColor& color);
+ void setNewSelectedColor (const QColor& color);
+ void setChangedNormalColor (const QColor& color);
+ void setChangedSelectedColor (const QColor& color);
+
+ void setServiceFont (const QFont& font);
+ void setNumberFont (const QFont& font);
+
+ void setScriptPath (const QString& path);
+ void setRunlevelPath (const QString& path);
+
+ inline void setConfigured( bool val = true )
+ {
+ mConfigured = val;
+ }
+
+ inline void setShowDescription (bool val)
+ {
+ mShowDescription = val;
+ }
+
+ inline bool showLog() const
+ {
+ return mShowLog;
+ }
+
+ inline int panningFactor() const
+ {
+ return mPanningFactor;
+ }
+
+ inline const QFont& serviceFont () const { return mServiceFont; }
+ inline const QFont& numberFont () const { return mNumberFont; }
+
+ QPoint position() const;
+
+ inline const QColor& newNormalColor () const { return mNewNormalColor; }
+ inline const QColor& newSelectedColor () const { return mNewSelectedColor; }
+
+ inline const QColor& changedNormalColor () const { return mChangedNormalColor; }
+ inline const QColor& changedSelectedColor () const { return mChangedSelectedColor; }
+
+ bool showRunlevel (int index) const;
+ void setShowRunlevel (int index, bool state);
+ void readRunlevels ();
+ void writeRunlevels ();
+
+ /**
+ * Have the necessary config entries
+ * been written?
+ */
+ inline bool isConfigured() const
+ {
+ return mConfigured;
+ }
+
+ inline const QString& scriptPath() const
+ {
+ return mScriptPath;
+ }
+
+ inline const QString& runlevelPath() const
+ {
+ return mRunlevelPath;
+ }
+
+ inline bool showDescription() const
+ {
+ return mShowDescription;
+ }
+
+ bool showMessage (ksv::Messages msg) const;
+ void setShowMessage (ksv::Messages msg, bool on);
+
+ static KSVConfig* self ();
+
+private:
+ KSVConfig ();
+
+ QString mScriptPath;
+ QString mRunlevelPath;
+ bool mShowLog;
+ bool mConfigured;
+ KConfig* mConfig;
+ int mPanningFactor;
+
+ QColor mNewNormalColor, mNewSelectedColor;
+ QColor mChangedNormalColor, mChangedSelectedColor;
+
+ bool mShowDescription;
+
+ QMap<int, bool> mShowRunlevel;
+
+ QFont mServiceFont;
+ QFont mNumberFont;
+};
+
+#endif // KSV_CONF_H
+
diff --git a/ksysv/ksv_core.cpp b/ksysv/ksv_core.cpp
new file mode 100644
index 0000000..a4e2b2c
--- /dev/null
+++ b/ksysv/ksv_core.cpp
@@ -0,0 +1,186 @@
+/***************************************************************************
+ begin : Sun Oct 3 1999
+ copyright : (C) 1997-99 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. *
+ * *
+ ***************************************************************************/
+
+#include <qpushbutton.h>
+#include <qstylesheet.h>
+
+#include <kapplication.h>
+#include <kglobalsettings.h>
+#include <kcompletion.h>
+#include <klocale.h>
+#include <kglobal.h>
+
+#include "ksv_conf.h"
+#include "ksvdraglist.h"
+#include "ksv_service.h"
+#include "ksv_core.h"
+
+const int ksv::runlevelNumber = 7;
+KAboutData* ksv::about = 0L;
+
+bool ksv::getServiceDescription (const QString& path, QString& res)
+{
+ KSVService* tmp = KSVService::newService (path, KSVConfig::self()->runlevelPath());
+ res = i18n ("No description available.");
+ bool result = false;
+
+ if (tmp)
+ {
+ res = tmp->description();
+ result = true;
+ }
+
+ delete tmp;
+
+ return result;
+}
+
+QString ksv::breakWords (const QString& s, int amount)
+{
+ QString res;
+
+ int left = s.length();
+ int maximum = amount;
+ QString str = s;
+
+ while (left > maximum)
+ {
+ int pos = -1;
+ for (int i = 1; i < amount; ++i)
+ {
+ if ((pos = str.find(' ', amount - i, false)) < 0 || (pos > maximum + i))
+ continue;
+ else
+ break;
+ }
+
+ if (pos == -1) break; //handles case when no spaces
+
+ maximum = kMax (maximum, pos);
+ res += str.left(pos) + "\n";
+ left += -pos - 1;
+ str = str.right(left);
+ }
+
+ res += str;
+
+ return res;
+}
+
+const QString& ksv::copyrightSymbol ()
+{
+ static QString c = QString::fromUtf8 ("©");
+
+ return c;
+}
+
+QStyleSheet* ksv::styleSheet ()
+{
+ static QStyleSheet style;
+ static bool initialized = false;
+
+ if (!initialized)
+ {
+ QStyleSheetItem* item = new QStyleSheetItem (&style, "vip"); // very important
+ item->setLogicalFontSize (5);
+ item->setFontWeight (QFont::Bold);
+ item->setDisplayMode (QStyleSheetItem::DisplayBlock);
+
+ item = new QStyleSheetItem (&style, "rl"); // runlevel
+ item->setLogicalFontSize (4);
+ item->setFontWeight (QFont::Bold);
+// item->setDisplayMode (QStyleSheetItem::DisplayBlock);
+
+ item = new QStyleSheetItem (&style, "start"); // start section
+ item->setColor (Qt::green);
+// item->setContexts ("rl");
+
+ item = new QStyleSheetItem (&style, "stop"); // stop section
+ item->setColor (Qt::red);
+// item->setContexts ("rl");
+
+ item = new QStyleSheetItem (&style, "error"); // signal an error
+ item->setColor (Qt::red);
+ item->setLogicalFontSizeStep (1);
+
+ item = new QStyleSheetItem (&style, "cmd"); // command line
+ item->setFontFamily (KGlobalSettings::fixedFont().family());
+ }
+
+ return &style;
+}
+
+KCompletion* ksv::serviceCompletion ()
+{
+ static KCompletion comp;
+
+ return &comp;
+}
+
+KCompletion* ksv::numberCompletion ()
+{
+ static KCompletion comp;
+ static bool initialized = false;
+
+ if (!initialized)
+ {
+ for (int value = 0; value < 100; value += 10)
+ {
+ QString result = QString::number (value);
+
+ if (value < 10)
+ result.sprintf("%.2i", value);
+
+ comp.addItem (result);
+ }
+ }
+
+ return &comp;
+}
+
+const QString& ksv::logFileFilter ()
+{
+ static QString filter = "*" + ksv::logFileExtension() + "|" +
+ QString(kapp->caption() + i18n(" log files") + " (*" + ksv::logFileExtension() + ")");
+
+ return filter;
+}
+
+const QString& ksv::nativeFileFilter ()
+{
+ static QString filter = "*" + ksv::nativeFileExtension() + "|"
+ + i18n("Saved Init Configurations") + " (*" + ksv::nativeFileExtension() + ")";
+
+ return filter;
+}
+
+const QString& ksv::logFileExtension ()
+{
+ static QString ext = ".ksysv_log";
+
+ return ext;
+}
+
+const QString& ksv::nativeFileExtension ()
+{
+ static QString ext = ".ksysv";
+
+ return ext;
+}
+
+const char* ksv::notifications[] =
+{
+ "Show Runlevels ReadOnly",
+ "Show Could Not Generate Sorting Number"
+};
diff --git a/ksysv/ksv_core.h b/ksysv/ksv_core.h
new file mode 100644
index 0000000..58d1fa2
--- /dev/null
+++ b/ksysv/ksv_core.h
@@ -0,0 +1,58 @@
+/***************************************************************************
+ begin : Sun Oct 3 1999
+ copyright : (C) 1997-99 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef KSV_CORE_H
+#define KSV_CORE_H
+
+class QPushButton;
+class QStyleSheet;
+class KAboutData;
+class KCompletion;
+class KSVItem;
+
+namespace ksv
+{
+ bool getServiceDescription (const QString& path, QString& res);
+
+ QString breakWords (const QString& s, int amount);
+
+ /**
+ * \return the Unicode string for the (c) symbol.
+ */
+ const QString& copyrightSymbol ();
+
+ QStyleSheet* styleSheet ();
+
+ const QString& logFileFilter ();
+ const QString& nativeFileFilter ();
+
+ const QString& logFileExtension ();
+ const QString& nativeFileExtension ();
+
+ KCompletion* serviceCompletion ();
+ KCompletion* numberCompletion ();
+
+ extern const int runlevelNumber;
+ extern KAboutData* about;
+
+ enum Messages {
+ RunlevelsReadOnly = 0,
+ CouldNotGenerateSortingNumber
+ };
+
+ extern const char* notifications[];
+}
+
+#endif // KSV_CORE_H
+
diff --git a/ksysv/ksv_service.cpp b/ksysv/ksv_service.cpp
new file mode 100644
index 0000000..e13ab6f
--- /dev/null
+++ b/ksysv/ksv_service.cpp
@@ -0,0 +1,76 @@
+/***************************************************************************
+ begin : Sun Oct 3 1999
+ copyright : (C) 1999 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. *
+ * *
+ ***************************************************************************/
+
+#include <ksv_service.h>
+#include "leveldb.h"
+
+KSVService::KSVService (const QString &name, const QString &basedir)
+ : name_ (name),
+ base_ (basedir)
+{
+
+}
+
+KSVService* KSVService::newService (const QString &name, const QString &basedir)
+{
+ struct service service;
+
+ int result = ::readServiceInfo (basedir.local8Bit(), name.local8Bit(), &service );
+
+ if (!result)
+ {
+ KSVService* tmp = new KSVService(name, basedir);
+ tmp->desc_ = service.desc;
+ tmp->levels = service.levels;
+ tmp->kPriority = service.kPriority;
+ tmp->sPriority = service.sPriority;
+
+ return tmp;
+ }
+ else
+ {
+ return 0L;
+ }
+}
+
+KSVService::~KSVService()
+{
+}
+
+bool KSVService::isOn (int level) const
+{
+ return !::isOn (base_.local8Bit(), name_.local8Bit(), level );
+}
+
+bool KSVService::isConfigured (int level) const
+{
+ return !::isConfigured (base_.local8Bit(), name_.local8Bit(), level);
+}
+
+int KSVService::set (int level, bool on)
+{
+ struct service service;
+ service.name = strdup (name_.local8Bit());
+ service.desc = strdup (desc_.local8Bit());
+ service.levels = levels;
+ service.kPriority = kPriority;
+ service.sPriority = sPriority;
+
+ return ::doSetService ("/etc/rc.d", service, level, on);
+}
+
+QString KSVService::description () const
+{
+ return desc_.stripWhiteSpace();
+}
diff --git a/ksysv/ksv_service.h b/ksysv/ksv_service.h
new file mode 100644
index 0000000..cdf42e1
--- /dev/null
+++ b/ksysv/ksv_service.h
@@ -0,0 +1,99 @@
+/***************************************************************************
+ begin : Sun Oct 3 1999
+ copyright : (C) 1999 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef KSV_SERVICE_H
+#define KSV_SERVICE_H
+
+#include <qstring.h>
+
+/**
+ * The long description for this class goes here
+ *
+ * @short This is the short description
+ * @author Peter Putzer <putzer@kde.org>
+ * @version 0.1
+ */
+class KSVService
+{
+public:
+
+ /**
+ * Named constructor
+ */
+ static KSVService* newService (const QString &name, const QString &basedir);
+
+ /**
+ * Destructor
+ */
+ ~KSVService();
+
+ /**
+ * Is the service active in runlevel "level"?
+ */
+ bool isOn (int level) const;
+
+ /**
+ * Is the service configured for runlevel "level"?
+ */
+ bool isConfigured (int level) const;
+
+ /**
+ * Set the service on or off in runlevel "level"
+ */
+ int set( int level, bool on = true );
+
+ /**
+ * Returns the description of the service
+ */
+ QString description () const;
+
+private:
+ /**
+ * Copy Constructor
+ */
+ KSVService(const KSVService&);
+
+ /**
+ * Default Constructor
+ */
+ KSVService();
+
+protected:
+ friend class KServiceGUI;
+ friend class KServiceManagerWidget;
+
+ /**
+ * Constructor
+ */
+ KSVService (const QString &name, const QString &basedir);
+
+ /**
+ * Name of the service
+ */
+ QString name_;
+
+ /**
+ * Description of the service (i.e. what it does)
+ */
+ QString desc_;
+
+ /**
+ * Base dir for storing runlevel dirs
+ */
+ QString base_;
+
+ int levels, kPriority, sPriority;
+};
+
+#endif // KSV_SERVICE_H
diff --git a/ksysv/ksvapplication.cpp b/ksysv/ksvapplication.cpp
new file mode 100644
index 0000000..d305712
--- /dev/null
+++ b/ksysv/ksvapplication.cpp
@@ -0,0 +1,20 @@
+// (c) 2000 Peter Putzer
+
+#include <unistd.h>
+
+#include <kwin.h>
+
+#include "ksvapplication.h"
+
+int KSVApplication::newInstance ()
+{
+ QWidget* main = mainWidget();
+
+ if (main)
+ KWin::activateWindow (main->winId());
+
+ return getpid();
+}
+
+#include "ksvapplication.moc"
+
diff --git a/ksysv/ksvapplication.h b/ksysv/ksvapplication.h
new file mode 100644
index 0000000..95c4b45
--- /dev/null
+++ b/ksysv/ksvapplication.h
@@ -0,0 +1,19 @@
+// (c) 2000 Peter Putzer
+
+#ifndef KSVAPPLICATION_H
+#define KSVAPPLICATION_H
+
+#include <kuniqueapplication.h>
+
+class KSVApplication : public KUniqueApplication
+{
+ Q_OBJECT
+
+public:
+ inline KSVApplication() {}
+ virtual inline ~KSVApplication () {}
+
+ virtual int newInstance ();
+};
+
+#endif // KSVAPPLICATION_H
diff --git a/ksysv/ksvconfigwizard.cpp b/ksysv/ksvconfigwizard.cpp
new file mode 100644
index 0000000..6a197cb
--- /dev/null
+++ b/ksysv/ksvconfigwizard.cpp
@@ -0,0 +1,150 @@
+/*
+** Copyright (C) 2000 Peter Putzer <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; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program in a file called COPYING; if not, write to
+** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+** MA 02110-1301, USA.
+*/
+
+/*
+** Bug reports and questions can be sent to kde-devel@kde.org
+*/
+#include "ksvconfigwizard.h"
+
+#include <qlayout.h>
+
+#include <kdialog.h>
+#include <kfiledialog.h>
+#include <klineedit.h>
+#include <qpushbutton.h>
+
+/*
+ * Constructs a KSVConfigWizard which is a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'
+ *
+ * The wizard will by default be modeless, unless you set 'modal' to
+ * TRUE to construct a modal wizard.
+ */
+KSVConfigWizard::KSVConfigWizard (QWidget* parent, const char* name, bool modal, WFlags fl)
+ : ConfigWizard (parent, name, modal, fl),
+ mChosenDistribution (Debian)
+{
+ mDistributionBoxLayout->setSpacing (KDialog::spacingHint());
+ mDistributionBoxLayout->setMargin (KDialog::marginHint());
+
+ mSpacer->setFixedHeight (KDialog::spacingHint());
+
+ // set the default paths
+ chooseDistribution (mChosenDistribution);
+
+ // enable finish-button
+ setFinishEnabled (mFinishedPage, true);
+
+ // some connections
+ connect (this, SIGNAL (selected (const QString&)),
+ this, SLOT (selectedPage (const QString&)));
+
+ // hide cancel-button
+ cancelButton()->hide();
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+KSVConfigWizard::~KSVConfigWizard()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+void KSVConfigWizard::browseServices()
+{
+ QString path = KFileDialog::getExistingDirectory(mServicesPath->text(), this);
+
+ if (!path.isEmpty())
+ mServicesPath->setText(path);
+
+ mServicesPath->setFocus();
+}
+
+void KSVConfigWizard::browseRunlevels()
+{
+ QString path = KFileDialog::getExistingDirectory(mRunlevelPath->text(), this);
+
+ if (!path.isEmpty())
+ mRunlevelPath->setText(path);
+
+ mRunlevelPath->setFocus();
+}
+
+void KSVConfigWizard::selectedPage (const QString& title)
+{
+ if (title == "Configuration Complete")
+ finishButton()->setDefault (true);
+ else
+ nextButton()->setDefault (true);
+}
+
+QString KSVConfigWizard::runlevelPath ()
+{
+ return mRunlevelPath->text();
+}
+
+QString KSVConfigWizard::servicesPath ()
+{
+ return mServicesPath->text();
+}
+
+void KSVConfigWizard::chooseDistribution(int which)
+{
+ mChosenDistribution = static_cast<Distribution> (which);
+
+ QString rlpath; QString spath;
+ switch (mChosenDistribution)
+ {
+ case Debian:
+ case Corel:
+ rlpath = "/etc";
+ spath = "/etc/init.d";
+ break;
+
+ case RedHat:
+ case Mandrake:
+ case Conectiva:
+ rlpath = "/etc/rc.d";
+ spath = "/etc/rc.d/init.d";
+ break;
+
+ case SuSE:
+ rlpath = "/etc/rc.d";
+ spath = "/etc/init.d";
+ break;
+
+ default:
+ rlpath = "/etc/rc.d";
+ spath = "/etc/rc.d/init.d";
+ }
+
+ mRunlevelPath->setText (rlpath);
+ mServicesPath->setText (spath);
+
+ if (which != Other)
+ setAppropriate (mPathsPage, false);
+ else
+ setAppropriate (mPathsPage, true);
+}
+
+#include "ksvconfigwizard.moc"
diff --git a/ksysv/ksvconfigwizard.h b/ksysv/ksvconfigwizard.h
new file mode 100644
index 0000000..35e8c7f
--- /dev/null
+++ b/ksysv/ksvconfigwizard.h
@@ -0,0 +1,66 @@
+/*
+** Copyright (C) 2000 Peter Putzer <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; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program in a file called COPYING; if not, write to
+** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+** MA 02110-1301, USA.
+*/
+
+/*
+** Bug reports and questions can be sent to kde-devel@kde.org
+*/
+#ifndef KSVCONFIGWIZARD_H
+#define KSVCONFIGWIZARD_H
+#include "configwizard.h"
+
+#include <qstring.h>
+
+class KSVConfigWizard : public ConfigWizard
+{
+ Q_OBJECT
+
+public:
+ KSVConfigWizard( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 );
+ ~KSVConfigWizard();
+
+public:
+ QString runlevelPath();
+ QString servicesPath();
+
+protected slots:
+ void browseRunlevels();
+ void chooseDistribution(int);
+ void browseServices();
+
+private slots:
+ void selectedPage (const QString&);
+
+private:
+ typedef enum {
+ Debian=0,
+ RedHat=1,
+ SuSE=2,
+ Mandrake=3,
+ Corel=4,
+ Conectiva=5,
+ Other=6
+ } Distribution;
+
+ Distribution mChosenDistribution;
+};
+
+#endif // KSVCONFIGWIZARD_H
diff --git a/ksysv/ksvdrag.cpp b/ksysv/ksvdrag.cpp
new file mode 100644
index 0000000..1f24417
--- /dev/null
+++ b/ksysv/ksvdrag.cpp
@@ -0,0 +1,102 @@
+// (c) 2000 Peter Putzer
+
+#include <qstring.h>
+#include <qcstring.h>
+
+#include <kurl.h>
+
+#include "Data.h"
+#include "ksvdraglist.h"
+#include "ksvdrag.h"
+
+class KSVDrag::Private
+{
+public:
+ QByteArray mNative;
+ QString mText;
+ KURL mURL;
+};
+
+KSVDrag::KSVDrag (const KSVData& item, QWidget* source, const char* name)
+ : QDragObject (source, name),
+ d (new Private())
+{
+ QDataStream ds (d->mNative, IO_ReadWrite);
+ ds << item;
+
+ d->mText = item.filenameAndPath ();
+ d->mURL.setPath (item.path() + "/" + item.filename());
+}
+
+KSVDrag::KSVDrag (const KSVItem& item, QWidget* source, const char* name)
+ : QDragObject (source, name),
+ d (new Private())
+{
+ QDataStream ds (d->mNative, IO_ReadWrite);
+ ds << *item.data();
+
+ d->mText = item.toString();
+ d->mURL.setPath (item.path() + "/" + item.filename());
+}
+
+KSVDrag::~KSVDrag ()
+{
+ delete d;
+}
+
+const char* KSVDrag::format (int i) const
+{
+ switch (i)
+ {
+ case Native:
+ return "application/x-ksysv";
+ break;
+
+ case Text:
+ return "text/plain";
+ break;
+
+ case URL:
+ return "text/uri-list";
+ break;
+
+ default:
+ return 0L;
+ }
+}
+
+QByteArray KSVDrag::encodedData (const char* format) const
+{
+ QByteArray res;
+
+ if (!strcmp (format, "application/x-ksysv"))
+ {
+ res = d->mNative;
+ }
+ else if (!strcmp (format, "text/plain"))
+ {
+ QDataStream ds (res, IO_ReadWrite);
+ ds << d->mText;
+ }
+ else if (!strcmp (format, "text/uri-list"))
+ {
+ res = QCString(d->mURL.url().latin1()).copy();
+ }
+
+ return res;
+}
+
+bool KSVDrag::decodeNative (const QMimeSource* mime, KSVData& data)
+{
+ if (mime && mime->provides ("application/x-ksysv"))
+ {
+ QDataStream ds (mime->encodedData ("application/x-ksysv"), IO_ReadOnly);
+ ds >> data;
+
+ return true;
+ }
+
+ return false;
+}
+
+#include "ksvdrag.moc"
diff --git a/ksysv/ksvdrag.h b/ksysv/ksvdrag.h
new file mode 100644
index 0000000..272f16d
--- /dev/null
+++ b/ksysv/ksvdrag.h
@@ -0,0 +1,36 @@
+// (c) 2000 Peter Putzer
+
+#ifndef KSVDRAG_H
+#define KSVDRAG_H
+
+#include <qdragobject.h>
+
+class KSVData;
+class KSVItem;
+class QWidget;
+
+class KSVDrag : public QDragObject
+{
+ Q_OBJECT
+
+public:
+ KSVDrag (const KSVData& item, QWidget* dragSource = 0L, const char* name = 0L);
+ KSVDrag (const KSVItem& item, QWidget* dragSource = 0L, const char* name = 0L);
+ virtual ~KSVDrag();
+
+ virtual const char* format (int i) const;
+ QByteArray encodedData (const char*) const;
+
+ static bool decodeNative (const QMimeSource*, KSVData&);
+
+private:
+ enum
+ {
+ Native, Text, URL
+ };
+
+ class Private;
+ Private* d;
+};
+
+#endif // KSVDRAG_H
diff --git a/ksysv/ksvdraglist.cpp b/ksysv/ksvdraglist.cpp
new file mode 100644
index 0000000..b0bd9bd
--- /dev/null
+++ b/ksysv/ksvdraglist.cpp
@@ -0,0 +1,802 @@
+/*
+** Copyright (C) 2000 Peter Putzer <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; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program in a file called COPYING; if not, write to
+** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+** MA 02110-1301, USA.
+*/
+
+/*
+** Bug reports and questions can be sent to kde-devel@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. *
+ * *
+ ***************************************************************************/
+
+#include <stdlib.h>
+
+#include <qpainter.h>
+#include <qdragobject.h>
+#include <qdatastream.h>
+#include <qheader.h>
+#include <qpixmapcache.h>
+#include <qbitmap.h>
+#include <qcursor.h>
+#include <qcolor.h>
+#include <qcstring.h>
+#include <qlabel.h>
+
+#include <kapplication.h>
+#include <kpopupmenu.h>
+#include <kglobal.h>
+#include <klocale.h>
+#include <kdebug.h>
+
+#include "kdltooltip.h"
+#include "ksv_core.h"
+#include "ksv_conf.h"
+#include "ksvdraglist.h"
+#include "ksvdrag.h"
+#include "ActionList.h"
+
+KSVItem::KSVItem (KListView* view)
+ : QListViewItem (view),
+ mData (new KSVData()),
+ mConfig (KSVConfig::self()),
+ mNewNormalColor (mConfig->newNormalColor()),
+ mNewSelectedColor (mConfig->newSelectedColor()),
+ mChangedNormalColor (mConfig->changedNormalColor()),
+ mChangedSelectedColor (mConfig->changedSelectedColor())
+{
+}
+
+KSVItem::KSVItem (const KSVItem& item)
+ : QListViewItem (item.listView()),
+ mData (new KSVData(*item.mData)),
+ mConfig (KSVConfig::self()),
+ mNewNormalColor (mConfig->newNormalColor()),
+ mNewSelectedColor (mConfig->newSelectedColor()),
+ mChangedNormalColor (mConfig->changedNormalColor()),
+ mChangedSelectedColor (mConfig->changedSelectedColor())
+
+{
+ setText (SortNumber, mData->numberString());
+ setText (ServiceName, label());
+ setIcon (*item.pixmap(Icon));
+}
+
+KSVItem::KSVItem (KSVDragList* view, const KSVData& data)
+ : QListViewItem (view),
+ mData (new KSVData (data)),
+ mConfig (KSVConfig::self()),
+ mNewNormalColor (mConfig->newNormalColor()),
+ mNewSelectedColor (mConfig->newSelectedColor()),
+ mChangedNormalColor (mConfig->changedNormalColor()),
+ mChangedSelectedColor (mConfig->changedSelectedColor())
+{
+ setText (SortNumber, mData->numberString());
+ setText (ServiceName, label());
+ setIcon (view->defaultIcon());
+}
+
+void KSVItem::copy (const KSVData& item)
+{
+ *mData = item;
+
+ setText (SortNumber, mData->numberString());
+ setText (ServiceName, mData->label());
+}
+
+QString KSVItem::key (int, bool) const
+{
+ return mData->numberString() + mData->label();
+}
+
+KSVItem::KSVItem (KListView* view, QString file, QString path, QString label, Q_INT8 nr )
+ : QListViewItem (view),
+ mData (new KSVData (file, path, label, nr)),
+ mConfig (KSVConfig::self()),
+ mNewNormalColor (mConfig->newNormalColor()),
+ mNewSelectedColor (mConfig->newSelectedColor()),
+ mChangedNormalColor (mConfig->changedNormalColor()),
+ mChangedSelectedColor (mConfig->changedSelectedColor())
+{
+ setText (ServiceName, mData->label());
+ setText (SortNumber, mData->numberString());
+}
+
+KSVItem::~KSVItem()
+{
+ delete mData;
+}
+
+void KSVItem::paintCell (QPainter* p, const QColorGroup& cg, int column, int width, int align)
+{
+ switch (column)
+ {
+ case SortNumber:
+ p->setFont (mConfig->numberFont());
+ break;
+
+ case ServiceName:
+ p->setFont (mConfig->serviceFont());
+ break;
+ }
+
+ QColorGroup colors = cg;
+
+ if (mData->newEntry())
+ {
+ colors.setColor (QColorGroup::Text, mNewNormalColor);
+ colors.setColor (QColorGroup::HighlightedText, mNewSelectedColor);
+ }
+ else if (mData->changed())
+ {
+ colors.setColor (QColorGroup::Text, mChangedNormalColor);
+ colors.setColor (QColorGroup::HighlightedText, mChangedSelectedColor);
+ }
+
+ QListViewItem::paintCell (p, colors, column, width, align);
+}
+
+QString KSVItem::toString() const
+{
+ return filenameAndPath();
+}
+
+QString KSVItem::tooltip () const
+{
+ QString result;
+
+ if (mConfig->showDescription())
+ {
+ if (!ksv::getServiceDescription(filename(), result))
+ result = toString();
+ else
+ {
+ // split into nice chunks
+ result = ksv::breakWords(result.simplifyWhiteSpace(), 50);
+ }
+ }
+ else
+ {
+ result = toString();
+ }
+
+ return result;
+}
+
+
+void KSVItem::setNew ( bool val )
+{
+ mData->setNewEntry (val);
+}
+
+
+QPixmap KSVItem::paintDragIcon (const QFont& font, const QColorGroup&) const
+{
+ QFontMetrics metric (font);
+ QRect textRect = metric.boundingRect (label());
+ const QPixmap& icon = *pixmap (Icon);
+ const int margin = listView()->itemMargin();
+
+ const int width = icon.width() + margin * 2 + textRect.width();
+ const int height = kMax (icon.height(), textRect.height());
+
+ QPixmap result (width, height);
+ result.fill (white);
+
+ QPainter p (&result);
+ p.drawPixmap (0, 0, icon);
+ p.setFont (font);
+
+ p.drawText (icon.width() + margin, 0,
+ width, height,
+ AlignLeft | AlignVCenter,
+ label());
+ p.end();
+
+ QBitmap mask (width, height);
+ p.begin (&mask);
+ p.setFont (font);
+
+ p.fillRect (0, 0, width, height, color0);
+
+ p.setPen (color1);
+ p.drawPixmap (0, 0, icon.createHeuristicMask());
+
+ p.drawText (icon.width() + margin, 0,
+ width, height,
+ AlignLeft | AlignVCenter,
+ label());
+
+ QBrush brush (color0);
+ brush.setStyle(Dense5Pattern);
+ p.fillRect (0, 0, width, height, brush);
+
+ p.end();
+
+ result.setMask(mask);
+ result.setOptimization(QPixmap::BestOptim);
+ return result;
+}
+
+void KSVItem::setIcon (const QPixmap& icon)
+{
+ setPixmap (Icon, icon);
+}
+
+void KSVItem::setLabel (const QString& label)
+{
+ mData->setLabel (label);
+
+ setText (ServiceName, label);
+}
+
+void KSVItem::setRunlevel (const QString& runlevel)
+{
+ mData->setRunlevel (runlevel);
+}
+
+void KSVItem::setFilename (const QString& file)
+{
+ mData->setFilename (file);
+}
+
+void KSVItem::setNumber (Q_INT8 nr)
+{
+ mData->setNumber (nr);
+
+ setText(SortNumber, mData->numberString());
+}
+
+void KSVItem::setPath (const QString& path)
+{
+ mData->setPath (path);
+}
+
+void KSVItem::setNewNormalColor (const QColor& col)
+{
+ mNewNormalColor = col;
+}
+
+void KSVItem::setNewSelectedColor (const QColor& col)
+{
+ mNewSelectedColor = col;
+}
+
+void KSVItem::setChangedNormalColor (const QColor& col)
+{
+ mChangedNormalColor = col;
+}
+
+void KSVItem::setChangedSelectedColor (const QColor& col)
+{
+ mChangedSelectedColor = col;
+}
+
+void KSVItem::setChanged (bool val)
+{
+ mData->setChanged (val);
+}
+
+void KSVItem::setOriginalRunlevel (const QString& rl)
+{
+ mData->setOriginalRunlevel (rl);
+}
+
+
+
+//-----------------------
+// KSVDragList
+//-----------------------
+
+KSVDragList::KSVDragList ( QWidget* parent, const char* name )
+ : KListView (parent, name),
+ mItemToDrag (0L),
+ mDragMenu (new KPopupMenu (this)),
+ mDragCopyMenu (new KPopupMenu (this)),
+ mDragMoveMenu (new KPopupMenu (this)),
+ mDisplayToolTips (true),
+ mCommonToolTips (true)
+{
+ // add tooltips
+ toolTip=new KDLToolTip (this);
+
+ setDragEnabled (true);
+ setDragAutoScroll(true);
+ setAcceptDrops(true);
+ setDropVisualizer (true);
+
+ QHeader* h = header();
+ h->setClickEnabled (false);
+
+ addColumn (i18n("No.")); // SortNumber
+ // setColumnWidthMode (KSVItem::SortNumber, Manual);
+ addColumn (""); // Icon
+// setColumnWidthMode (KSVItem::Icon, Manual);
+ addColumn (i18n("Name")); // ServiceName
+// setColumnWidthMode (KSVItem::ServiceName, Manual);
+
+ h->setResizeEnabled (false, KSVItem::Icon);
+
+ setShowSortIndicator (false);
+ setAllColumnsShowFocus (true);
+
+ // multiselection is to complicated due to the sorting numbers
+ setSelectionModeExt (Single);
+
+ // init DND menu
+ mDragMenu->insertTitle (i18n("Drag Menu"));
+ mDragMenu->insertItem ("&Copy", Copy);
+ mDragMenu->insertItem ("&Move", Move);
+
+ mDragCopyMenu->insertTitle (i18n("Drag Menu"));
+ mDragCopyMenu->insertItem ("&Copy", Copy);
+
+ mDragMoveMenu->insertTitle (i18n("Drag Menu"));
+ mDragMoveMenu->insertItem ("&Move", Move);
+
+ mRMList.setAutoDelete(true);
+
+ // catch drops
+ connect (this, SIGNAL (dropped (QDropEvent*, QListViewItem*)),
+ this, SLOT (drop (QDropEvent*, QListViewItem*)));
+}
+
+KSVDragList::~KSVDragList()
+{
+ delete mDragMenu;
+ delete mDragCopyMenu;
+ delete mDragMoveMenu;
+ delete toolTip;
+}
+
+void KSVDragList::initItem (QString file, QString path, QString name, Q_INT8 nr)
+{
+ KSVItem* tmp = new KSVItem(this, file, path, name, nr);
+ tmp->setRunlevel(QObject::name());
+ tmp->setOriginalRunlevel(QObject::name());
+
+ tmp->setIcon (mIcon);
+
+ setUpdatesEnabled(false);
+
+ // marked as new in insert, we dont want that
+ tmp->setNew(false);
+ tmp->setChanged (false);
+
+ setUpdatesEnabled(true);
+ repaint(false);
+}
+
+void KSVDragList::setDefaultIcon (const QPixmap& icon)
+{
+ mIcon = icon;
+
+ for (QListViewItemIterator it (firstChild()); it.current(); ++it)
+ {
+ static_cast <KSVItem*> (it.current())->setIcon (mIcon);
+ }
+}
+
+void KSVDragList::clear ()
+{
+ KListView::clear();
+
+ clearRMList();
+}
+
+void KSVDragList::setNewNormalColor ( const QColor& col )
+{
+ mNewNormalColor = col;
+
+ KSVItem* item;
+ for (QListViewItemIterator it (firstChild());
+ (item = static_cast<KSVItem*>(it.current()));
+ ++it)
+ {
+ item->setNewNormalColor (mNewNormalColor);
+ }
+}
+
+void KSVDragList::setNewSelectedColor (const QColor& col)
+{
+ mNewSelectedColor = col;
+
+ KSVItem* item;
+ for (QListViewItemIterator it (firstChild());
+ (item = static_cast<KSVItem*>(it.current()));
+ ++it)
+ {
+ item->setNewSelectedColor (mNewSelectedColor);
+ }
+}
+
+Q_INT8 KSVDragList::generateNumber (const QString& label,
+ const KSVData* itemBelow, const KSVData* itemAbove) const
+{
+ Q_INT8 high = itemBelow ? itemBelow->number() : -1;
+ Q_INT8 low = itemAbove ? itemAbove->number() : -1;
+ Q_INT8 result = generateNumber (high, low);
+
+ if (high == result && result != -1 && label >= itemBelow->label())
+ result = -1;
+
+ if (low == result && result != -1 && label <= itemAbove->label())
+ result = -1;
+
+ return result;
+}
+
+Q_INT8 KSVDragList::generateNumber (Q_INT8 high, Q_INT8 low) const
+{
+ Q_ASSERT (high >= low || high == -1);
+
+ Q_INT8 result = -1;
+
+ if (low < 0)
+ {
+ if (high < 0)
+ result = 50;
+ else
+ result = high / 2;
+ }
+ else if (high < 0)
+ result = (100 - low) / 2 + low;
+ else
+ result = (high - low) / 2 + low;
+
+ return result;
+}
+
+void KSVDragList::setChangedNormalColor (const QColor& col)
+{
+ mChangedNormalColor = col;
+
+ KSVItem* item;
+ for (QListViewItemIterator it (firstChild());
+ (item = static_cast<KSVItem*> (it.current()));
+ ++it)
+ {
+ item->setChangedNormalColor (mChangedNormalColor);
+ }
+}
+
+void KSVDragList::setChangedSelectedColor (const QColor& col)
+{
+ mChangedSelectedColor = col;
+
+ KSVItem* item;
+ for (QListViewItemIterator it (firstChild());
+ (item = static_cast<KSVItem*> (it.current()));
+ ++it)
+ {
+ item->setChangedSelectedColor (mChangedSelectedColor);
+ }
+}
+
+KSVItem* KSVDragList::match (const KSVData& data)
+{
+ KSVItem* res = 0L;
+
+ for (QListViewItemIterator it (this);
+ (res = static_cast<KSVItem*> (it.current()));
+ ++it)
+ {
+ if (*res->data() == data)
+ break;
+ else
+ res = 0L;
+ }
+
+ return res;
+}
+
+void KSVDragList::setOrigin (bool val)
+{
+ mOrigin = val;
+
+ if (mOrigin)
+ {
+ emit newOrigin (this);
+ emit newOrigin();
+ }
+ else
+ clearSelection();
+}
+
+void KSVDragList::startDrag ()
+{
+ mItemToDrag = static_cast<KSVItem*> (currentItem());
+
+ KSVDrag* d = dynamic_cast<KSVDrag*> (dragObject());
+
+ if (d)
+ {
+ d->setPixmap (mItemToDrag->paintDragIcon (font(), colorGroup()));
+
+ d->drag();
+ }
+}
+
+//KSVDrag* KSVDragList::dragObject ()
+QDragObject* KSVDragList::dragObject ()
+{
+ if (mItemToDrag)
+ {
+ return new KSVDrag (*mItemToDrag, this);
+ }
+ else
+ return 0L;
+}
+
+bool KSVDragList::acceptDrag (QDropEvent* e) const
+{
+ e->acceptAction ();
+
+ return acceptDrops() && e->provides ("application/x-ksysv");
+}
+
+void KSVDragList::focusInEvent (QFocusEvent* e)
+{
+ KListView::focusInEvent(e);
+
+ if (!currentItem())
+ setCurrentItem (firstChild());
+
+ setOrigin(true);
+}
+
+void KSVDragList::clearRMList()
+{
+ mRMList.clear();
+}
+
+bool KSVDragList::removeFromRMList (const KSVData& item)
+{
+ KSVData* res = 0L;
+
+ for (QPtrListIterator<KSVData> it (mRMList);
+ it.current();
+ ++it)
+ {
+ res = it.current();
+
+ if (*res == item)
+ break;
+ else
+ res = 0L;
+ }
+
+ if (res)
+ return mRMList.remove (res);
+ else
+ return false;
+}
+
+bool KSVDragList::insert (const KSVData& data, const KSVData* above, const KSVData* below)
+{
+ Q_INT8 nr = generateNumber (data.label(), below, above);
+
+ if (nr > -1)
+ {
+ KSVData real (data);
+ real.setNumber (nr);
+
+ KSVItem* item = new KSVItem (this, real);
+ item->setNew (true);
+
+ return true;
+ }
+ else
+ emit cannotGenerateNumber ();
+
+ return false;
+}
+
+bool KSVDragList::insert (const KSVData& data, const KSVItem* where, KSVAction*& action)
+{
+ const KSVData* above = 0L;
+ const KSVData* below = 0L;
+
+ if (where)
+ {
+ above = where->data();
+ KSVItem* tmp = static_cast<KSVItem*> (where->nextSibling());
+ below = tmp ? tmp->data() : 0L;
+ }
+ else
+ {
+ KSVItem* tmp = static_cast<KSVItem*> (firstChild());
+ below = tmp ? tmp->data() : 0L;
+ }
+
+ bool success = false;
+ KSVItem* exists = match (data);
+ action = 0L;
+
+ if (exists)
+ {
+ if (exists->data() == above || exists->data() == below)
+ return false;
+
+ Q_INT8 nr = generateNumber (exists->label(), below, above);
+
+ if (nr == -1)
+ {
+ emit cannotGenerateNumber();
+ }
+ else
+ {
+ KSVData oldState = *exists->data();
+ exists->setNumber (nr);
+ sort();
+
+ action = new ChangeAction (this, &oldState, exists->data());
+ success = true;
+ }
+ }
+ else
+ {
+ success = insert (data, above, below);
+
+ if (success)
+ action = new AddAction (this, match (data)->data());
+ }
+
+ return success;
+}
+
+void KSVDragList::drop (QDropEvent* e, QListViewItem* after)
+{
+ KSVData data;
+ KSVDragList* source = static_cast<KSVDragList*> (e->source());
+ QPopupMenu* menu = 0L;
+
+ // hack to empty the cursor stack after DND
+ QApplication::restoreOverrideCursor();
+ QApplication::restoreOverrideCursor();
+
+ if ((!source) || (!strcmp(source->name(), "Scripts")))
+ menu = mDragCopyMenu;
+ else if (source == this)
+ menu = mDragMoveMenu;
+ else
+ menu = mDragMenu;
+
+ if (KSVDrag::decodeNative (e, data))
+ {
+ int res = -1;
+
+ if (e->action() == QDropEvent::Copy && source != this)
+ res = Copy;
+ else
+ res = menu->exec (QCursor::pos(), 1);
+
+ if (res == -1) // operation cancelled
+ return;
+
+ const bool move = res == Move;
+
+ KSVItem* tmp = static_cast<KSVItem*> (after);
+ KSVAction* action = 0L;
+ if (insert (data, tmp, action))
+ {
+ if (move && source != this)
+ {
+ KSVAction* actions[2];
+ actions [0] = new RemoveAction (source, &data);
+ actions [1] = action;
+
+ action = new CompoundAction (actions, 2);
+ delete source->match (data);
+ }
+
+ emit undoAction (action);
+ }
+ }
+}
+
+bool KSVDragList::addToRMList (const KSVData& item)
+{
+ KSVData* res = 0L;
+
+ for (QPtrListIterator<KSVData> it (mRMList);
+ it.current();
+ ++it)
+ {
+ res = it.current();
+
+ if (*res == item)
+ break;
+ else
+ res = 0L;
+ }
+
+ if (!res)
+ {
+ mRMList.append (new KSVData(item));
+ return true;
+ }
+ else
+ return false;
+}
+
+void KSVDragList::setEnabled (bool enable)
+{
+ if (enable)
+ clearWState (WState_ForceDisabled);
+ else
+ setWState (WState_ForceDisabled);
+
+ if (enable)
+ {
+ if (testWState (WState_Disabled))
+ {
+ clearWState (WState_Disabled);
+ // setBackgroundFromMode(); // this is private in QWidget...
+ // well it doesn't really matter in this case
+ enabledChange( TRUE );
+ }
+ }
+ else
+ {
+ if (!testWState(WState_Disabled))
+ {
+ if (focusWidget() == this)
+ focusNextPrevChild (TRUE);
+ setWState (WState_Disabled);
+ // setBackgroundFromMode(); // this is private in QWidget...
+ // well it doesn't really matter in this case
+ enabledChange (FALSE);
+ }
+ }
+
+ viewport()->setEnabled (enable);
+}
+
+// KServiceDragList
+
+KServiceDragList::KServiceDragList (QWidget* parent, const char* name)
+ : KSVDragList (parent, name)
+{
+}
+
+KServiceDragList::~KServiceDragList ()
+{
+}
+
+void KServiceDragList::startDrag ()
+{
+ mItemToDrag = static_cast<KSVItem*> (currentItem());
+
+ KSVDrag* d = dynamic_cast<KSVDrag*> (dragObject());
+
+ if (d)
+ {
+ d->setPixmap (mItemToDrag->paintDragIcon (font(), colorGroup()));
+
+ d->dragCopy();
+ }
+}
+
+#include "ksvdraglist.moc"
diff --git a/ksysv/ksvdraglist.h b/ksysv/ksvdraglist.h
new file mode 100644
index 0000000..f5474b8
--- /dev/null
+++ b/ksysv/ksvdraglist.h
@@ -0,0 +1,277 @@
+/*
+** Copyright (C) 2000 Peter Putzer <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; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program in a file called COPYING; if not, write to
+** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+** MA 02110-1301, USA.
+*/
+
+/*
+** Bug reports and questions can be sent to kde-devel@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. *
+ * *
+ ***************************************************************************/
+
+#ifndef KSVDRAGLIST_H
+#define KSVDRAGLIST_H
+
+#include <qstring.h>
+#include <qcolor.h>
+#include <qpixmap.h>
+
+#include <klistview.h>
+
+#include "Data.h"
+
+class QPen;
+class KSVAction;
+class SimpleAction;
+class KSVDragList;
+class KPopupMenu;
+class KSVConfig;
+class KDLToolTip;
+
+class KSVItem : public QListViewItem
+{
+public:
+ typedef enum {
+ SortNumber = 0,
+ Icon,
+ ServiceName,
+ FileName,
+
+ // insert additional columns here
+
+ Last
+ } Columns;
+
+ KSVItem (KListView*);
+ KSVItem (const KSVItem&);
+ explicit KSVItem (KSVDragList*, const KSVData&);
+ KSVItem (KListView* view, QString file, QString path, QString label, Q_INT8 nr );
+ virtual ~KSVItem ();
+
+ virtual QString key (int col, bool ascending) const;
+
+ inline bool isChanged() const { return mData->changed(); }
+
+ inline bool isNumChanged() const { return mData->numberChanged(); }
+ inline bool isLabelChanged() const { return mData->labelChanged(); }
+ inline bool isNew() const { return mData->newEntry(); }
+
+ inline const QString& oldFilename() const { return mData->oldFilename(); }
+ inline const QString& filename() const { return mData->filename(); }
+ inline const QString& oldLabel() const { return mData->oldLabel(); }
+ inline const QString& label() const { return mData->label(); }
+ inline const QString& runlevel() const { return mData->runlevel(); }
+
+ inline QString filenameAndPath() const { return mData->filenameAndPath (); }
+
+ inline const QString& path() const { return mData->path(); }
+
+ inline Q_INT8 number() const { return mData->number(); }
+ inline Q_INT8 oldNumber() const { return mData->oldNumber(); }
+
+ void copy (const KSVData&);
+
+ KSVData* data () { return mData; }
+ const KSVData* data () const { return mData; }
+
+ QString toString () const;
+
+ inline bool operator== (const KSVItem & rhs) const { return mData == rhs.mData; }
+
+ inline const QColor& newNormalColor () const
+ {
+ return mNewNormalColor;
+ }
+
+ inline const QColor& changedNormalColor () const
+ {
+ return mChangedNormalColor;
+ }
+
+ inline QString originalRunlevel() const { return mData->originalRunlevel(); }
+
+ void setIcon (const QPixmap& icon);
+ void setLabel (const QString& label);
+ void setFilename (const QString& file);
+ void setRunlevel (const QString& runlevel);
+ void setNumber (Q_INT8 nr);
+ void setPath (const QString& path);
+ void setChanged (bool);
+ void setNewNormalColor (const QColor&);
+ void setChangedNormalColor (const QColor&);
+ void setNewSelectedColor (const QColor&);
+ void setChangedSelectedColor (const QColor&);
+ void setNew (bool);
+ void setOriginalRunlevel (const QString&);
+
+ inline void setNumberChanged (bool val) { mData->setNumberChanged (val); }
+
+ QString tooltip () const;
+ virtual void paintCell (QPainter* p, const QColorGroup& cg, int column, int width, int align);
+
+protected:
+ friend class KSVDragList;
+ friend class KServiceDragList;
+
+ QPixmap paintDragIcon (const QFont& f, const QColorGroup& g) const;
+
+private:
+ friend class KSVDrag;
+
+ KSVData* mData;
+ KSVConfig* mConfig;
+
+ QColor mNewNormalColor;
+ QColor mNewSelectedColor;
+ QColor mChangedNormalColor;
+ QColor mChangedSelectedColor;
+};
+
+class KSVDragList : public KListView
+{
+ Q_OBJECT
+
+public:
+ KSVDragList ( QWidget* parent = 0, const char* name = 0 );
+ virtual ~KSVDragList();
+
+ virtual void clear();
+
+ inline bool displayToolTips () const { return mDisplayToolTips; }
+ inline bool commonToolTips () const { return mCommonToolTips; }
+
+ inline const QString& tooltip () const { return mToolTip; }
+ inline const QString& horizontalScrollBarTip () const { return mHorizontalTip; }
+ inline const QString& verticalScrollBarTip () const { return mVerticalTip; }
+
+ virtual void initItem (QString file, QString path, QString name, Q_INT8 nr);
+ QPtrList<KSVData>& getDeletedItems() { return mRMList; }
+
+ /**
+ * @return whether this is the currently "selected" KSVDragList.
+ */
+ inline bool isOrigin() const { return mOrigin; }
+
+ inline KSVItem* currentItem() { return static_cast<KSVItem*> (KListView::currentItem()); }
+
+ inline KSVItem* lastItem () { return static_cast<KSVItem*> (KListView::lastItem()); }
+
+ /**
+ * @return true if the insertion was successful.
+ */
+ bool insert (const KSVData& data, const KSVData* above = 0L, const KSVData* below = 0L);
+
+ bool insert (const KSVData& data, const KSVItem* where, KSVAction*& action);
+
+ inline const QPixmap& defaultIcon() const { return mIcon; }
+
+ bool removeFromRMList (const KSVData&);
+ bool addToRMList (const KSVData&);
+ void clearRMList();
+
+ KSVItem* match (const KSVData&);
+
+ inline void setDisplayToolTips (bool val) { mDisplayToolTips = val; }
+ inline void setCommonToolTips (bool val) { mCommonToolTips = val; }
+ inline void setHorizontalScrollBarTip (const QString& t) { mHorizontalTip = t; }
+ inline void setVerticalScrollBarTip (const QString& t) { mVerticalTip = t; }
+ inline void setToolTip (const QString& t) { mToolTip = t; }
+
+public slots:
+ void setNewNormalColor (const QColor &);
+ void setChangedNormalColor (const QColor &);
+ void setNewSelectedColor (const QColor &);
+ void setChangedSelectedColor (const QColor &);
+
+ void setOrigin (bool);
+ inline void slotNewOrigin() { setOrigin (false); }
+
+ void setDefaultIcon (const QPixmap& icon);
+
+ void drop (QDropEvent*, QListViewItem*);
+
+ virtual void setEnabled (bool);
+
+protected:
+ virtual void focusInEvent (QFocusEvent*);
+ virtual bool acceptDrag (QDropEvent*) const;
+ virtual QDragObject* dragObject ();
+// virtual KSVDrag* dragObject ();
+
+ virtual void startDrag ();
+
+ /**
+ * Generates a sorting number for an item at
+ * the given index by taking the average of the item
+ * above and the item below.
+ */
+ Q_INT8 generateNumber (Q_INT8 high, Q_INT8 low) const;
+
+ /**
+ * A convenience function that also takes the label into account
+ */
+ Q_INT8 generateNumber (const QString& label, const KSVData* itemAbove, const KSVData* itemBelow) const;
+
+ KSVItem* mItemToDrag;
+
+private:
+ QPixmap mIcon;
+
+ bool mOrigin;
+ QPtrList<KSVData> mRMList;
+
+ QColor mNewNormalColor;
+ QColor mNewSelectedColor;
+ QColor mChangedNormalColor;
+ QColor mChangedSelectedColor;
+
+ KPopupMenu* mDragMenu;
+ KPopupMenu* mDragCopyMenu;
+ KPopupMenu* mDragMoveMenu;
+ KDLToolTip* toolTip;
+ typedef enum { Copy, Move } DragAction;
+
+ QString mToolTip, mHorizontalTip, mVerticalTip;
+ bool mDisplayToolTips, mCommonToolTips;
+
+signals:
+ void newOrigin();
+ void newOrigin (KSVDragList*);
+
+ void cannotGenerateNumber();
+ void undoAction(KSVAction*);
+};
+
+class KServiceDragList : public KSVDragList
+{
+public:
+ KServiceDragList (QWidget* parent = 0L, const char* name = 0L);
+ virtual ~KServiceDragList ();
+
+protected:
+ virtual void startDrag ();
+};
+
+#endif
diff --git a/ksysv/ksvlookandfeel.cpp b/ksysv/ksvlookandfeel.cpp
new file mode 100644
index 0000000..29e4de5
--- /dev/null
+++ b/ksysv/ksvlookandfeel.cpp
@@ -0,0 +1,93 @@
+/*
+** Copyright (C) 2000 Peter Putzer <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; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program in a file called COPYING; if not, write to
+** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+** MA 02110-1301, USA.
+*/
+
+/*
+** Bug reports and questions can be sent to kde-devel@kde.org
+*/
+#include "ksvlookandfeel.h"
+
+#include <qlabel.h>
+#include <qlayout.h>
+
+#include <kdialog.h>
+#include <kfontdialog.h>
+
+/*
+ * Constructs a KSVLookAndFeel which is a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'
+ */
+KSVLookAndFeel::KSVLookAndFeel( QWidget* parent, const char* name, WFlags fl )
+ : LookAndFeel( parent, name, fl )
+{
+ mTopLayout->setSpacing (KDialog::spacingHint());
+ mColorGrid->setSpacing (KDialog::spacingHint());
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+KSVLookAndFeel::~KSVLookAndFeel()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+/*
+ * protected slot
+ */
+void KSVLookAndFeel::chooseNumberFont()
+{
+ KFontDialog::getFont (mNumberFont, false, this);
+ setNumberFont (mNumberFont);
+ emit configChanged();
+}
+
+/*
+ * protected slot
+ */
+void KSVLookAndFeel::chooseServiceFont()
+{
+ KFontDialog::getFont (mServiceFont, false, this);
+ setServiceFont (mServiceFont);
+ emit configChanged();
+}
+
+void KSVLookAndFeel::setServiceFont (const QFont& font)
+{
+ mServiceFontPreview->setFont(font);
+ mServiceFontPreview->setText(font.family() + " " + QString::number(font.pointSize()));
+
+ mServiceFont = font;
+}
+
+void KSVLookAndFeel::setNumberFont (const QFont& font)
+{
+ mNumberFontPreview->setFont(font);
+ mNumberFontPreview->setText(font.family() + " " + QString::number(font.pointSize()));
+
+ mNumberFont = font;
+}
+
+void KSVLookAndFeel::slotChanged()
+{
+ emit configChanged();
+}
+#include "ksvlookandfeel.moc"
diff --git a/ksysv/ksvlookandfeel.h b/ksysv/ksvlookandfeel.h
new file mode 100644
index 0000000..5e59a91
--- /dev/null
+++ b/ksysv/ksvlookandfeel.h
@@ -0,0 +1,39 @@
+/**
+ * Released under the GNU General Public License, version 2.
+ *
+ * Copyright (c) 2000 Peter Putzer <putzer@kde.org>
+ */
+
+#ifndef KSVLOOKANDFEEL_H
+#define KSVLOOKANDFEEL_H
+#include "lookandfeelconfig.h"
+
+#include <qfont.h>
+class KSVLookAndFeel : public LookAndFeel
+{
+ Q_OBJECT
+
+public:
+ KSVLookAndFeel( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
+ ~KSVLookAndFeel();
+
+ inline const QFont& serviceFont() const { return mServiceFont; }
+ inline const QFont& numberFont() const { return mNumberFont; }
+
+ void setServiceFont (const QFont& font);
+ void setNumberFont (const QFont& font);
+
+signals:
+ void configChanged();
+
+protected slots:
+ void chooseServiceFont();
+ void chooseNumberFont();
+ void slotChanged();
+
+private:
+ QFont mServiceFont;
+ QFont mNumberFont;
+};
+
+#endif // KSVLOOKANDFEEL_H
diff --git a/ksysv/ksvmiscconfig.cpp b/ksysv/ksvmiscconfig.cpp
new file mode 100644
index 0000000..05e9126
--- /dev/null
+++ b/ksysv/ksvmiscconfig.cpp
@@ -0,0 +1,64 @@
+/*
+** Copyright (C) 2000 Peter Putzer <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; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program in a file called COPYING; if not, write to
+** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+** MA 02110-1301, USA.
+*/
+
+/*
+** Bug reports and questions can be sent to kde-devel@kde.org
+*/
+#include "ksvmiscconfig.h"
+
+#include <qgroupbox.h>
+#include <qlayout.h>
+
+#include <kdialog.h>
+
+/*
+ * Constructs a KSVMiscConfig which is a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'
+ */
+KSVMiscConfig::KSVMiscConfig( QWidget* parent, const char* name, WFlags fl )
+ : MiscConfiguration( parent, name, fl )
+{
+ mSpacer->setFixedHeight (KDialog::spacingHint());
+
+ // Messages
+ mMessagesBoxLayout->setMargin (KDialog::marginHint());
+ mMessagesBoxLayout->setSpacing(KDialog::spacingHint());
+
+// // Editor
+// mEditorBoxLayout->setMargin (KDialog::marginHint());
+// mEditorBoxLayout->setSpacing (KDialog::spacingHint());
+}
+
+void KSVMiscConfig::slotChanged()
+{
+ emit configChanged();
+}
+/*
+ * Destroys the object and frees any allocated resources
+ */
+KSVMiscConfig::~KSVMiscConfig()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+#include "ksvmiscconfig.moc"
+
diff --git a/ksysv/ksvmiscconfig.h b/ksysv/ksvmiscconfig.h
new file mode 100644
index 0000000..8195d00
--- /dev/null
+++ b/ksysv/ksvmiscconfig.h
@@ -0,0 +1,47 @@
+/*
+** Copyright (C) 2000 Peter Putzer <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; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program in a file called COPYING; if not, write to
+** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+** MA 02110-1301, USA.
+*/
+
+/*
+** Bug reports and questions can be sent to kde-devel@kde.org
+*/
+#ifndef KSVMISCCONFIG_H
+#define KSVMISCCONFIG_H
+#include "miscconfig.h"
+
+class KSVMiscConfig : public MiscConfiguration
+{
+ Q_OBJECT
+
+public:
+ KSVMiscConfig( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
+ ~KSVMiscConfig();
+
+signals:
+ void configChanged();
+
+protected slots:
+ void slotChanged();
+
+};
+
+#endif // KSVMISCCONFIG_H
+
diff --git a/ksysv/ksvpathconfig.cpp b/ksysv/ksvpathconfig.cpp
new file mode 100644
index 0000000..bf7be35
--- /dev/null
+++ b/ksysv/ksvpathconfig.cpp
@@ -0,0 +1,75 @@
+/*
+** Copyright (C) 2000 Peter Putzer <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; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program in a file called COPYING; if not, write to
+** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+** MA 02110-1301, USA.
+*/
+
+/*
+** Bug reports and questions can be sent to kde-devel@kde.org
+*/
+#include "ksvpathconfig.h"
+
+#include <klineedit.h>
+#include <kfiledialog.h>
+
+/*
+ * Constructs a KSVPathConfig which is a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'
+ */
+KSVPathConfig::KSVPathConfig( QWidget* parent, const char* name, WFlags fl )
+ : PathConfiguration( parent, name, fl )
+{
+ mSpacer->setFixedHeight (KDialog::spacingHint());
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+KSVPathConfig::~KSVPathConfig()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+void KSVPathConfig::browseServices()
+{
+ QString path = KFileDialog::getExistingDirectory(mServicesPath->text(), this);
+
+ if (!path.isEmpty())
+ mServicesPath->setText(path);
+
+ mServicesPath->setFocus();
+}
+
+void KSVPathConfig::browseRunlevels()
+{
+ QString path = KFileDialog::getExistingDirectory(mRunlevelPath->text(), this);
+
+ if (!path.isEmpty())
+ mRunlevelPath->setText(path);
+
+ mRunlevelPath->setFocus();
+}
+
+void KSVPathConfig::slotChanged()
+{
+ emit configChanged();
+}
+
+#include "ksvpathconfig.moc"
+
diff --git a/ksysv/ksvpathconfig.h b/ksysv/ksvpathconfig.h
new file mode 100644
index 0000000..8cced64
--- /dev/null
+++ b/ksysv/ksvpathconfig.h
@@ -0,0 +1,49 @@
+/*
+** Copyright (C) 2000 Peter Putzer <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; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program in a file called COPYING; if not, write to
+** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+** MA 02110-1301, USA.
+*/
+
+/*
+** Bug reports and questions can be sent to kde-devel@kde.org
+*/
+#ifndef KSVPATHCONFIG_H
+#define KSVPATHCONFIG_H
+#include "pathconfig.h"
+
+class KSVPathConfig : public PathConfiguration
+{
+ Q_OBJECT
+
+public:
+ KSVPathConfig( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
+ ~KSVPathConfig();
+
+signals:
+ void configChanged();
+
+protected slots:
+ void browseRunlevels();
+ void browseServices();
+ void slotChanged();
+
+};
+
+#endif // KSVPATHCONFIG_H
+
diff --git a/ksysv/ksysv.desktop b/ksysv/ksysv.desktop
new file mode 100644
index 0000000..6cbb8e5
--- /dev/null
+++ b/ksysv/ksysv.desktop
@@ -0,0 +1,72 @@
+[Desktop Entry]
+Name=KSysV
+Name[ar]=برنامج KSysV
+Name[bn]=কে-সিস-ভি
+Name[pt_BR]=KSysV
+Name[th]=แก้ไขการเริ่มระบบแบบ SysV - K
+GenericName=SysV-Init Editor
+GenericName[ar]=محرر SysV-Init
+GenericName[bg]=Редактор на SysV-Init
+GenericName[bn]=সিস-ভি-আইনিট সম্পাদক
+GenericName[br]=Aozer deraouiñ SysV
+GenericName[bs]=SysV Init Editor
+GenericName[ca]=Editor de l'init SysV
+GenericName[cs]=SysV-Init editor
+GenericName[cy]=Golygydd SysV-Init
+GenericName[el]=Επεξεργαστής SysV-Init
+GenericName[es]= Editor de inicio SysV
+GenericName[et]=SysV-Init redaktor
+GenericName[eu]=SysV Init editorea
+GenericName[fa]=ویرایشگر آغازین SysV
+GenericName[fi]=SysV-Init -asetusmuokkain
+GenericName[fr]=Éditeur de l'initialisation SysV
+GenericName[ga]=Eagarthóir SysV-Init
+GenericName[gl]=Editor de Inicio SysV
+GenericName[he]=מנהל השירותים
+GenericName[hr]=Uređivač SysV-Init
+GenericName[hu]=Szolgáltatáskezelő
+GenericName[is]=SysV Init-stjóri
+GenericName[it]=Editor per SysV-Init
+GenericName[ja]=SystemV 起動スクリプトエディタ
+GenericName[ka]=SysV-Init რედაქტორი
+GenericName[kk]=SysV-Init редакторы
+GenericName[km]=កម្មវិធី​និពន្ធ SysV-Init
+GenericName[ko]=SysV Init 편집기
+GenericName[lt]=SysV-Init redaktorius
+GenericName[mk]=Уредувач на SysV-Init
+GenericName[mt]=Editur SysV-Init
+GenericName[nb]=SysV-init-redigering
+GenericName[nds]=Editor för SysV-Init
+GenericName[ne]=SysV-Init सम्पादक
+GenericName[nn]=SysV-init-redigering
+GenericName[pa]=SysV-Init ਸੰਪਾਦਕ
+GenericName[pl]=Edytor Startu SysV
+GenericName[pt]=Editor de SysV-Init
+GenericName[pt_BR]=Editor do SysV-Init
+GenericName[ro]=Manager de servicii SysV
+GenericName[ru]=Редактор сценариев SysV
+GenericName[se]=Sysv-init-doaimmaheapmi
+GenericName[sk]=SysV-Init editor
+GenericName[sl]=Urejevalnik začetnih nastavitev SysV
+GenericName[sr]=Уређивач SysV-init-а
+GenericName[sr@Latn]=Uređivač SysV-init-a
+GenericName[sv]=Sys V-starteditor
+GenericName[th]=แก้ไขการเริ่มระบบแบบ SysV
+GenericName[tr]=SysV-Init Düzenleyici
+GenericName[uk]=Редактор KSysV-Init
+GenericName[vi]=SysV-Bộ sửa Init
+GenericName[wa]=Aspougneu po SysV-Init
+GenericName[zh_CN]=SysV Init 编辑器
+GenericName[zh_HK]=SysV-Init 編輯器
+GenericName[zh_TW]=SysV-Init 編輯器
+MimeType=
+Exec=ksysv -caption "%c" %i %m
+Icon=ksysv
+Path=
+DocPath=ksysv/index.html
+Type=Application
+Terminal=false
+X-KDE-StartupNotify=true
+X-DCOP-ServiceType=Unique
+X-KDE-SubstituteUID=true
+Categories=Qt;KDE;System;
diff --git a/ksysv/ksysvui.rc b/ksysv/ksysvui.rc
new file mode 100644
index 0000000..11a79b5
--- /dev/null
+++ b/ksysv/ksysvui.rc
@@ -0,0 +1,96 @@
+<!DOCTYPE kpartgui>
+<kpartgui name="ksysv" version="3">
+ <MenuBar noMerge="1">
+ <Menu name="file"><text>&amp;File</text>
+ <Action name="file_revert"/>
+ <Action name="file_open"/>
+ <Separator line_separator="true"/>
+ <Action name="file_save"/>
+ <Action name="file_save_as"/>
+ <Action name="ksysv_save_log"/>
+ <Separator line_separator="true"/>
+ <Action name="ksysv_print_log"/>
+ <Separator line_separator="true"/>
+ <Action name="file_quit"/>
+ </Menu>
+
+ <Menu name="edit"><text>&amp;Edit</text>
+ <Action name="edit_undo"/>
+ <Action name="edit_redo"/>
+ <Separator line_separator="true"/>
+ <Action name="edit_cut"/>
+ <Action name="edit_copy"/>
+ <Action name="edit_paste"/>
+ <Separator line_separator="true"/>
+ <Action name="ksysv_properties"/>
+ </Menu>
+
+ <Menu name="tools"><text>&amp;Tools</text>
+ <Action name="ksysv_start_service"/>
+ <Action name="ksysv_stop_service"/>
+ <Action name="ksysv_restart_service"/>
+ <Separator line_separator="true"/>
+ <Action name="ksysv_edit_service"/>
+ </Menu>
+
+ <Menu name="settings"><text>&amp;Settings</text>
+ <Merge name="StandardToolBarMenuHandler" />
+ <Action name="ksysv_toggle_log"/>
+ <Separator line_separator="true"/>
+ <Action name="options_save_options"/>
+ <Separator line_separator="true"/>
+ <Action name="options_configure_keybinding"/>
+ <Action name="options_configure_toolbars"/>
+ <Action name="options_configure"/>
+ </Menu>
+
+ <Menu name="help"><text>&amp;Help</text>
+ <Action name="help_contents"/>
+ <Action name="help_whats_this"/>
+ <Separator line_separator="true"/>
+ <Action name="help_report_bug"/>
+ <Separator line_separator="true"/>
+ <Action name="help_about_app"/>
+ <Action name="help_about_kde"/>
+ </Menu>
+ </MenuBar>
+
+ <ToolBar fullWidth="true" name="mainToolBar" noMerge="1">
+ <text>Main Toolbar</text>
+ <Action name="file_revert"/>
+ <Action name="file_save"/>
+ <Separator line_separator="true"/>
+ <Action name="edit_undo"/>
+ <Action name="edit_redo"/>
+ <Separator line_separator="true"/>
+ <Action name="edit_cut"/>
+ <Action name="edit_copy"/>
+ <Action name="edit_paste"/>
+ <Action name="ksysv_toggle_log"/>
+ </ToolBar>
+
+ <Menu name="item_menu">
+ <text>Runlevel Menu</text>
+ <Action name="edit_cut"/>
+ <Action name="edit_copy"/>
+ <Action name="edit_paste"/>
+ <Separator/>
+ <Action name="ksysv_properties"/>
+ </Menu>
+
+ <Menu name="script_menu">
+ <text>Services Menu</text>
+ <Action name="edit_copy"/>
+ <Separator/>
+ <Action name="ksysv_open_service"/>
+ <Action name="ksysv_open_with"/>
+ <Separator/>
+ <Action name="ksysv_properties"/>
+ </Menu>
+
+ <Menu name="list_menu">
+ <text>Runlevel Menu</text>
+ <Action name="ksysv_paste_append"/>
+ </Menu>
+
+</kpartgui>
diff --git a/ksysv/leveldb.c b/ksysv/leveldb.c
new file mode 100644
index 0000000..149cb3b
--- /dev/null
+++ b/ksysv/leveldb.c
@@ -0,0 +1,353 @@
+/***************************************************************************
+ begin : Sun Oct 3 1999
+ copyright : Modifications (C) 1999 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; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <glob.h>
+#include <locale.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+/* Changes
+ 2000-08-04 - Peter Putzer <putzer@kde.org>
+ fixed compilation on *BSD (use GLOB_NOCHECK & strcmp instead of
+ checking for GLOB_NOMATCH)
+
+ 1999-04-11 - Peter Putzer <putzer@kde.org>
+ modified leveldb.h for use with C++
+
+ 1998-09-22 - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ i18n for init.d scripts (eg.: description(pt_BR) is a brazilian
+ portuguese description for the package)
+*/
+
+#define _(String) String
+
+#include "leveldb.h"
+
+int parseLevels(const char* str, int emptyOk) {
+ const char* chptr = str;
+ int rc = 0;
+
+ if (!str || !strlen(str))
+ return emptyOk ? 0 : -1;
+
+ while (*chptr) {
+ if (!isdigit(*chptr) || *chptr > '6') return -1;
+ rc |= 1 << (*chptr - '0');
+ chptr++;
+ }
+
+ return rc;
+}
+
+int readServiceInfo(const char* RUNLEVELS, const char * name, struct service * service) {
+ char * filename = (char *) malloc(strlen(name) + strlen(RUNLEVELS) + 50);
+ int fd, i;
+ struct stat sb;
+ char * bufstart, * bufstop, * start, * end, * next;
+ struct service serv = { NULL, -1, -1, -1, NULL };
+ char overflow;
+ char english;
+ char is_my_lang = 0;
+ char levelbuf[20];
+ char * lang = getenv ("LANG"),
+ * final_parenthesis,
+ * english_desc = NULL;
+ char my_lang_loaded = 0;
+
+ sprintf(filename, "%s/init.d/%s", RUNLEVELS, name);
+
+ if ((fd = open(filename, O_RDONLY)) < 0)
+ {
+ free(filename);
+ return -1;
+ }
+ free(filename);
+ fstat(fd, &sb);
+
+ bufstart = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
+ if (bufstart == ((caddr_t) -1)) {
+ close(fd);
+ return -1;
+ }
+
+ bufstop = bufstart + sb.st_size;
+ close(fd);
+
+ next = bufstart;
+ while (next < bufstop && (serv.levels == -1 || !serv.desc)) {
+ start = next;
+
+ while (isspace(*start) && start < bufstop) start++;
+ if (start == bufstop) break;
+
+ end = strchr(start, '\n');
+ if (!end)
+ next = end = bufstop;
+ else
+ next = end + 1;
+
+ if (*start != '#') continue;
+
+ start++;
+ while (isspace(*start) && start < end) start++;
+ if (start == end) continue;
+
+ if (!strncmp(start, "chkconfig:", 10)) {
+ start += 10;
+ while (isspace(*start) && start < end) start++;
+ if (start == end) {
+ if (serv.desc) free(serv.desc);
+ munmap(bufstart, sb.st_size);
+ return 1;
+ }
+
+ if ((sscanf(start, "%19s %d %d%c", levelbuf,
+ &serv.sPriority, &serv.kPriority, &overflow) != 4) ||
+ overflow != '\n') {
+ if (serv.desc) free(serv.desc);
+ munmap(bufstart, sb.st_size);
+ return 1;
+ }
+
+ if (!strcmp(levelbuf, "-"))
+ serv.levels = 0;
+ else
+ serv.levels = parseLevels(levelbuf, 0);
+ if (serv.levels == -1) {
+ if (serv.desc) free(serv.desc);
+ munmap(bufstart, sb.st_size);
+ return 1;
+ }
+ } else if (!strncmp(start, "description", 11)) {
+ start += 11;
+
+ english = *start == ':';
+
+ if (!english) {
+ if (*start != '(') {
+ if (serv.desc) free(serv.desc);
+ munmap(bufstart, sb.st_size);
+ return 1;
+ }
+
+ ++start;
+ final_parenthesis = strchr (start, ')');
+
+ if (final_parenthesis == NULL || final_parenthesis - start > 5) {
+ if (serv.desc) free(serv.desc);
+ munmap(bufstart, sb.st_size);
+ return 1;
+ }
+
+ is_my_lang = lang ? strncmp (lang, start, strlen (lang)) == 0 : 0;
+ start = final_parenthesis + 2;
+ } else ++start;
+
+ while (isspace(*start) && start < end) start++;
+ if (start == end) {
+ munmap(bufstart, sb.st_size);
+ return 1;
+ }
+ {
+ char* desc = malloc(end - start + 1);
+ strncpy(desc, start, end - start);
+ desc[end - start] = '\0';
+
+ start = next;
+
+ while (desc[strlen(desc) - 1] == '\\') {
+ desc[strlen(desc) - 1] = '\0';
+ start = next;
+
+ while (isspace(*start) && start < bufstop) start++;
+ if (start == bufstop || *start != '#') {
+ munmap(bufstart, sb.st_size);
+ return 1;
+ }
+
+ start++;
+
+ while (isspace(*start) && start < bufstop) start++;
+ if (start == bufstop) {
+ munmap(bufstart, sb.st_size);
+ return 1;
+ }
+
+ end = strchr(start, '\n');
+ if (!end)
+ next = end = bufstop;
+ else
+ next = end + 1;
+
+ i = strlen(desc);
+ desc = realloc(desc, i + end - start + 1);
+ strncat(desc, start, end - start);
+ desc[i + end - start] = '\0';
+
+ start = next;
+ }
+
+ if (desc) {
+ if (my_lang_loaded) {
+ free(desc);
+ } else if (is_my_lang) {
+ if (serv.desc)
+ free(serv.desc);
+
+ serv.desc = desc;
+ break;
+ } else if (english) {
+ if (serv.desc)
+ free(serv.desc);
+
+ if (english_desc)
+ free (english_desc);
+
+ english_desc = desc;
+ } else free (desc);
+ }
+ }
+ }
+ }
+
+ munmap(bufstart, sb.st_size);
+
+ if (!serv.desc) {
+ if (english_desc)
+ serv.desc = english_desc;
+ } else if (english_desc)
+ free (english_desc);
+
+ if ((serv.levels == -1 ) || !serv.desc) {
+ return 1;
+ }
+
+ serv.name = strdup(name);
+
+ *service = serv;
+ return 0;
+}
+
+/* returns -1 on error */
+int currentRunlevel(void) {
+ FILE * p;
+ char response[50];
+
+ p = popen("/sbin/runlevel", "r");
+ if (!p) return -1;
+
+ if (!fgets(response, sizeof(response), p)) {
+ pclose(p);
+ return -1;
+ }
+
+ pclose(p);
+
+ if (response[1] != ' ' || !isdigit(response[2]) || response[3] != '\n')
+ return -1;
+
+ return response[2] - '0';
+}
+
+int findServiceEntries(const char* RUNLEVELS, const char* name, int level, glob_t * globresptr) {
+ char match[200];
+ glob_t globres;
+ int rc;
+
+ sprintf(match, "%s/rc%d.d/[SK][0-9][0-9]%s", RUNLEVELS, level, name);
+
+ rc = glob(match, GLOB_ERR | GLOB_NOSORT | GLOB_NOCHECK, NULL, &globres);
+
+ if (rc) {
+ fprintf(stderr, _("failed to glob pattern %s: %s\n"), match,
+ strerror(errno));
+ return 1;
+ } else if (!strcmp(match, globres.gl_pathv[0])) {
+ globresptr->gl_pathc = 0;
+ return 0;
+ }
+
+ *globresptr = globres;
+ return 0;
+}
+
+int isConfigured(const char* RUNLEVELS, const char* name, int level) {
+ glob_t globres;
+
+ if (findServiceEntries(RUNLEVELS, name, level, &globres))
+ exit(1);
+
+ if (!globres.gl_pathc)
+ return 0;
+
+ globfree(&globres);
+ return 1;
+}
+
+int isOn(const char* RUNLEVELS, const char* name, int level) {
+ glob_t globres;
+
+ if (level == -1) {
+ level = currentRunlevel();
+ if (level == -1) {
+ fprintf(stderr, _("cannot determine current run level\n"));
+ return 0;
+ }
+ }
+
+ if (findServiceEntries(RUNLEVELS, name, level, &globres))
+ exit(1);
+
+ if (!globres.gl_pathc || !strstr(globres.gl_pathv[0], "/S"))
+ return 0;
+
+ globfree(&globres);
+ return 1;
+}
+
+int doSetService(const char* RUNLEVELS, struct service s, int level, int on) {
+ int priority = on ? s.sPriority : s.kPriority;
+ char linkname[200];
+ char linkto[200];
+ glob_t globres;
+ int i;
+
+ if (!findServiceEntries(RUNLEVELS, s.name, level, &globres)) {
+ for (i = 0; (unsigned int) i < globres.gl_pathc; i++)
+ unlink(globres.gl_pathv[i]);
+ if (globres.gl_pathc) globfree(&globres);
+ }
+
+ sprintf(linkname, "%s/rc%d.d/%c%02d%s", RUNLEVELS, level,
+ on ? 'S' : 'K', priority, s.name);
+ sprintf(linkto, "../init.d/%s", s.name);
+
+ unlink(linkname); /* just in case */
+ if (symlink(linkto, linkname)) {
+ fprintf(stderr, _("failed to make symlink %s: %s\n"), linkname,
+ strerror(errno));
+ return 1;
+ }
+
+ return 0;
+}
+
diff --git a/ksysv/leveldb.h b/ksysv/leveldb.h
new file mode 100644
index 0000000..e18d202
--- /dev/null
+++ b/ksysv/leveldb.h
@@ -0,0 +1,50 @@
+/***************************************************************************
+ begin : Sun Oct 3 1999
+ copyright : (C) 1999 by Red Hat Software
+ 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; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+/* modifications (c) 1999 Peter Putzer */
+
+#ifndef H_LEVELDB
+#define H_LEVELDB
+
+
+#ifdef __cplusplus
+
+extern "C" {
+#endif
+
+#include <glob.h>
+
+struct service {
+ char * name;
+ int levels, kPriority, sPriority;
+ char * desc;
+};
+
+int parseLevels(const char * str, int emptyOk);
+
+/* returns 0 on success, 1 if the service is not chkconfig-able, -1 if an
+ I/O error occurs (in which case errno can be checked) */
+int readServiceInfo(const char* RUNLEVELS, const char* name, struct service * service);
+int currentRunlevel(void);
+int isOn(const char* RUNLEVELS, const char* name, int where);
+int isConfigured(const char* RUNLEVELS, const char* name, int level);
+int doSetService(const char* RUNLEVELS, struct service s, int level, int on);
+int findServiceEntries(const char* RUNLEVELS, const char* name, int level, glob_t * globresptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/ksysv/lookandfeelconfig.ui b/ksysv/lookandfeelconfig.ui
new file mode 100644
index 0000000..bedd940
--- /dev/null
+++ b/ksysv/lookandfeelconfig.ui
@@ -0,0 +1,500 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>LookAndFeel</class>
+<comment>Look &amp; Feel configuration for SysV-Init Editor</comment>
+<author>Peter Putzer</author>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>LookAndFeel</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>532</width>
+ <height>303</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Look &amp; Feel</string>
+ </property>
+ <property name="layoutMargin" stdset="0">
+ </property>
+ <property name="layoutSpacing" stdset="0">
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>mFontBox</cstring>
+ </property>
+ <property name="title">
+ <string>Fonts</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>mTopLayout</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QPushButton" row="1" column="2">
+ <property name="name">
+ <cstring>mChooseNumberFont</cstring>
+ </property>
+ <property name="text">
+ <string>C&amp;hoose...</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="1">
+ <property name="name">
+ <cstring>mServiceFontPreview</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>200</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="text">
+ <string>dummy-font</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="1">
+ <property name="name">
+ <cstring>mNumberFontPreview</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>200</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="text">
+ <string>dummy-font</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>mServiceFontLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Services:</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>mChooseServiceFont</cstring>
+ </property>
+ <property name="hAlign" stdset="0">
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>mNumberFontLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Sorting numbers:</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>mChooseNumberFont</cstring>
+ </property>
+ <property name="hAlign" stdset="0">
+ </property>
+ </widget>
+ <widget class="QPushButton" row="0" column="2">
+ <property name="name">
+ <cstring>mChooseServiceFont</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Choose...</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QFrame">
+ <property name="name">
+ <cstring>mSpacer</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>10</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Plain</enum>
+ </property>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>mColorBox</cstring>
+ </property>
+ <property name="title">
+ <string>Colors</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>mColorGrid</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="KColorButton" row="2" column="1">
+ <property name="name">
+ <cstring>mChangedNormal</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="focusPolicy">
+ <enum>StrongFocus</enum>
+ </property>
+ <property name="text">
+ <string>Dummy</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Choose a color for changed services</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;p&gt;Use the &lt;strong&gt;Select Color dialog box&lt;/strong&gt; to pick a text color for &lt;em&gt;services that have been changed&lt;/em&gt; (either order/sorting number or name).&lt;/p&gt;
+&lt;p&gt;Changed service entries will be distinguished by this color.&lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>mChangedNormalLabel</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Changed:</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>mChangedNormal</cstring>
+ </property>
+ <property name="hAlign" stdset="0">
+ </property>
+ </widget>
+ <widget class="KColorButton" row="0" column="1">
+ <property name="name">
+ <cstring>mNewNormal</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="focusPolicy">
+ <enum>StrongFocus</enum>
+ </property>
+ <property name="text">
+ <string>Dummy</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Choose a color for service new to a runlevel</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;p&gt;Use the &lt;strong&gt;Select Color dialog box&lt;/strong&gt; to pick a text color for &lt;em&gt;services new to a runlevel&lt;/em&gt;.&lt;/p&gt;
+&lt;p&gt;New service entries will be distinguished by this color.&lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>mNewNormalLabel</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;New:</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>mNewNormal</cstring>
+ </property>
+ <property name="hAlign" stdset="0">
+ </property>
+ </widget>
+ <widget class="KColorButton" row="3" column="1">
+ <property name="name">
+ <cstring>mChangedSelected</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="focusPolicy">
+ <enum>StrongFocus</enum>
+ </property>
+ <property name="text">
+ <string>Dummy</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Choose a color for changed services that are selected</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;p&gt;Use the &lt;strong&gt;Select Color dialog box&lt;/strong&gt; to pick a selected text color for &lt;em&gt;services that have been changed&lt;/em&gt; (either order/sorting number or name).&lt;/p&gt;
+&lt;p&gt;Changed service entries will be distinguished by this color while they are selected.&lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="KColorButton" row="1" column="1">
+ <property name="name">
+ <cstring>mNewSelected</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="focusPolicy">
+ <enum>StrongFocus</enum>
+ </property>
+ <property name="text">
+ <string>Dummy</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Choose a color for services new to a runlevel that are selected</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;p&gt;Use the &lt;strong&gt;Select Color dialog box&lt;/strong&gt; to pick a selected text color for &lt;em&gt;services new to a runlevel&lt;/em&gt;.&lt;/p&gt;
+&lt;p&gt;New service entries will be distinguished by this color while they are selected.&lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>mNewSelectedLabel</cstring>
+ </property>
+ <property name="text">
+ <string>New &amp;&amp; &amp;selected:</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>mNewSelected</cstring>
+ </property>
+ <property name="hAlign" stdset="0">
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>mChangedSelectedLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Changed &amp;&amp; s&amp;elected:</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>mChangedSelected</cstring>
+ </property>
+ <property name="hAlign" stdset="0">
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </vbox>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>mChooseServiceFont</sender>
+ <signal>clicked()</signal>
+ <receiver>LookAndFeel</receiver>
+ <slot>chooseServiceFont()</slot>
+ </connection>
+ <connection>
+ <sender>mChooseNumberFont</sender>
+ <signal>clicked()</signal>
+ <receiver>LookAndFeel</receiver>
+ <slot>chooseNumberFont()</slot>
+ </connection>
+ <connection>
+ <sender>mNewNormal</sender>
+ <signal>changed(const QColor&amp;)</signal>
+ <receiver>LookAndFeel</receiver>
+ <slot>slotChanged()</slot>
+ </connection>
+ <connection>
+ <sender>mNewSelected</sender>
+ <signal>changed(const QColor&amp;)</signal>
+ <receiver>LookAndFeel</receiver>
+ <slot>slotChanged()</slot>
+ </connection>
+ <connection>
+ <sender>mChangedNormal</sender>
+ <signal>changed(const QColor&amp;)</signal>
+ <receiver>LookAndFeel</receiver>
+ <slot>slotChanged()</slot>
+ </connection>
+ <connection>
+ <sender>mChangedSelected</sender>
+ <signal>changed(const QColor&amp;)</signal>
+ <receiver>LookAndFeel</receiver>
+ <slot>slotChanged()</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>mChooseServiceFont</tabstop>
+ <tabstop>mChooseNumberFont</tabstop>
+ <tabstop>mNewNormal</tabstop>
+ <tabstop>mNewSelected</tabstop>
+ <tabstop>mChangedNormal</tabstop>
+ <tabstop>mChangedSelected</tabstop>
+</tabstops>
+<includes>
+ <include location="global" impldecl="in declaration">klocale.h</include>
+</includes>
+<slots>
+ <slot access="protected">chooseNumberFont()</slot>
+ <slot access="protected">chooseServiceFont()</slot>
+ <slot access="protected">slotChanged()</slot>
+</slots>
+<pixmapfunction>DesktopIcon</pixmapfunction>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/ksysv/main.cpp b/ksysv/main.cpp
new file mode 100644
index 0000000..4dd0e09
--- /dev/null
+++ b/ksysv/main.cpp
@@ -0,0 +1,103 @@
+ /***************************************************************************
+ 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. *
+ * *
+ ***************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <iostream>
+
+#include <kcmdlineargs.h>
+#include <kaboutdata.h>
+#include <kglobal.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+
+#include "ksvapplication.h"
+#include "ksv_conf.h"
+#include "ksvconfigwizard.h"
+#include "TopWidget.h"
+#include "version.h"
+
+using namespace std;
+
+#if (defined(DEBUG) && !(defined(NDEBUG) || defined(NO_DEBUG)))
+#define KSYSV_DEBUG(x) x
+#else
+#define KSYSV_DEBUG(x) do { } while (0)
+#endif
+
+static void myMessageOutput( QtMsgType type, const char *msg )
+{
+ switch ( type ) {
+ case QtDebugMsg:
+ KSYSV_DEBUG(cerr << "Debug: " << msg << endl);
+ break;
+ case QtWarningMsg:
+ KSYSV_DEBUG(cerr << "Warning: " << msg << endl);
+ break;
+ case QtFatalMsg:
+ cerr << "Fatal: " << msg << endl;
+ abort(); // dump core on purpose
+ }
+}
+
+int main( int argc, char **argv ) {
+ // install own message handler that ignores debug-msg when DEBUG is not defined
+ qInstallMsgHandler(myMessageOutput);
+
+ KAboutData about("ksysv", I18N_NOOP("SysV-Init Editor"), KSYSV_VERSION_STRING,
+ I18N_NOOP ("Editor for Sys-V like init configurations"),
+ KAboutData::License_GPL,
+ "Copyright (c) 1997-2000, Peter Putzer.",
+ I18N_NOOP ("Similar to Red Hat's" \
+ "\"tksysv\", but SysV-Init Editor allows\n" \
+ "drag-and-drop, as well as keyboard use."));
+ about.addAuthor ("Peter Putzer", I18N_NOOP("Main developer"), "putzer@kde.org");
+ ksv::about = &about;
+
+ KCmdLineArgs::init(argc, argv, &about);
+ KUniqueApplication::addCmdLineOptions ();
+
+ if (!KUniqueApplication::start()) {
+ cerr << "SysV-Init Editor is already running!" << endl;
+ return -1;
+ }
+
+ KSVApplication app;
+
+ // session-management
+ if (kapp->isRestored())
+ RESTORE(KSVTopLevel)
+ else
+ {
+ KSVConfig* conf = KSVConfig::self();
+ if (!conf->isConfigured())
+ {
+ KSVConfigWizard* w = new KSVConfigWizard(0, "ConfigWizard", true);
+ w->exec();
+
+ conf->setConfigured(true);
+ conf->setRunlevelPath (w->runlevelPath());
+ conf->setScriptPath (w->servicesPath());
+ conf->writeSettings();
+ }
+
+ KSVTopLevel* top = new KSVTopLevel();
+ app.setMainWidget(top);
+ top->show();
+ }
+ // end session-management
+
+ return app.exec();
+}
+
diff --git a/ksysv/miscconfig.ui b/ksysv/miscconfig.ui
new file mode 100644
index 0000000..0cfebe2
--- /dev/null
+++ b/ksysv/miscconfig.ui
@@ -0,0 +1,186 @@
+<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
+<class>MiscConfiguration</class>
+<author>Peter Putzer</author>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>MiscConfiguration</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>332</width>
+ <height>137</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Miscellaneous</string>
+ </property>
+ <property name="layoutMargin" stdset="0">
+ </property>
+ <property name="layoutSpacing" stdset="0">
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>mMessagesBox</cstring>
+ </property>
+ <property name="title">
+ <string>Informational Messages</string>
+ </property>
+ <property name="layoutMargin" stdset="0">
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout12</cstring>
+ </property>
+ <property name="layoutSpacing" stdset="0">
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>mShowAllLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Show all messages again:</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>mShowAll</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Show All</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>mWarnReadOnly</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Warn if not allowed to write configuration</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>mWarnSortingNumber</cstring>
+ </property>
+ <property name="text">
+ <string>Warn &amp;if unable to generate a sorting number</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QFrame">
+ <property name="name">
+ <cstring>mSpacer</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>10</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Plain</enum>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer7</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>mWarnReadOnly</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>MiscConfiguration</receiver>
+ <slot>slotChanged()</slot>
+ </connection>
+ <connection>
+ <sender>mWarnSortingNumber</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>MiscConfiguration</receiver>
+ <slot>slotChanged()</slot>
+ </connection>
+</connections>
+<includes>
+ <include location="global" impldecl="in declaration">klocale.h</include>
+</includes>
+<slots>
+ <slot access="protected">slotChanged()</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/ksysv/pathconfig.ui b/ksysv/pathconfig.ui
new file mode 100644
index 0000000..c59a96f
--- /dev/null
+++ b/ksysv/pathconfig.ui
@@ -0,0 +1,294 @@
+<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
+<class>PathConfiguration</class>
+<comment>Path configuration for KSysV</comment>
+<author>Peter Putzer</author>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>PathConfiguration</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>305</width>
+ <height>168</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="caption">
+ <string>Path Configuration</string>
+ </property>
+ <property name="layoutMargin" stdset="0">
+ </property>
+ <property name="layoutSpacing" stdset="0">
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>mServicesLayout</cstring>
+ </property>
+ <property name="layoutMargin" stdset="0">
+ </property>
+ <property name="layoutSpacing" stdset="0">
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>mServicesLabel</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Service path:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>mServicesPath</cstring>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>mServicesButtonLayout</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>mServicesPath</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="focusPolicy">
+ <enum>StrongFocus</enum>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Enter the path to the folder containing the services</string>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>mBrowseServices</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Browse...</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Select the folder containing the services</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QFrame">
+ <property name="name">
+ <cstring>mSpacer</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>10</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Plain</enum>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>mRunlevelLayout</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>mRunlevelLabel</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Runlevel path:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>mRunlevelPath</cstring>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>mRunlevelButtonLayout</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>mRunlevelPath</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="focusPolicy">
+ <enum>StrongFocus</enum>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Enter the path to the folder containing the runlevel folders</string>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>mBrowseRunlevel</cstring>
+ </property>
+ <property name="text">
+ <string>Br&amp;owse...</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Select the folder containing the runlevel folders </string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>mEmptySpace</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>mBrowseServices</sender>
+ <signal>clicked()</signal>
+ <receiver>PathConfiguration</receiver>
+ <slot>browseServices()</slot>
+ </connection>
+ <connection>
+ <sender>mBrowseRunlevel</sender>
+ <signal>clicked()</signal>
+ <receiver>PathConfiguration</receiver>
+ <slot>browseRunlevels()</slot>
+ </connection>
+ <connection>
+ <sender>mServicesPath</sender>
+ <signal>textChanged(const QString&amp;)</signal>
+ <receiver>PathConfiguration</receiver>
+ <slot>slotChanged()</slot>
+ </connection>
+ <connection>
+ <sender>mRunlevelPath</sender>
+ <signal>textChanged(const QString&amp;)</signal>
+ <receiver>PathConfiguration</receiver>
+ <slot>slotChanged()</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>mServicesPath</tabstop>
+ <tabstop>mBrowseServices</tabstop>
+ <tabstop>mRunlevelPath</tabstop>
+ <tabstop>mBrowseRunlevel</tabstop>
+</tabstops>
+<includes>
+ <include location="global" impldecl="in declaration">klocale.h</include>
+ <include location="global" impldecl="in declaration">kdialog.h</include>
+</includes>
+<slots>
+ <slot access="protected">browseServices()</slot>
+ <slot access="protected">browseRunlevels()</slot>
+ <slot access="protected">slotChanged()</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>klineedit.h</includehint>
+ <includehint>klineedit.h</includehint>
+</includehints>
+</UI>
diff --git a/ksysv/pics/Makefile.am b/ksysv/pics/Makefile.am
new file mode 100644
index 0000000..e60bc77
--- /dev/null
+++ b/ksysv/pics/Makefile.am
@@ -0,0 +1,7 @@
+#KDE_ICON = ksysv
+# add here all files
+pics_DATA = ksysv_start.png ksysv_locked.png ksysv_unlocked.png \
+ ksysv_restart.png ksysv_stop.png
+
+# this is the directory, where all datas are installed
+picsdir = $(kde_datadir)/ksysv/pics
diff --git a/ksysv/pics/ksysv_locked.png b/ksysv/pics/ksysv_locked.png
new file mode 100644
index 0000000..03480e3
--- /dev/null
+++ b/ksysv/pics/ksysv_locked.png
Binary files differ
diff --git a/ksysv/pics/ksysv_restart.png b/ksysv/pics/ksysv_restart.png
new file mode 100644
index 0000000..8f4ad31
--- /dev/null
+++ b/ksysv/pics/ksysv_restart.png
Binary files differ
diff --git a/ksysv/pics/ksysv_start.png b/ksysv/pics/ksysv_start.png
new file mode 100644
index 0000000..debff53
--- /dev/null
+++ b/ksysv/pics/ksysv_start.png
Binary files differ
diff --git a/ksysv/pics/ksysv_stop.png b/ksysv/pics/ksysv_stop.png
new file mode 100644
index 0000000..5decccd
--- /dev/null
+++ b/ksysv/pics/ksysv_stop.png
Binary files differ
diff --git a/ksysv/pics/ksysv_unlocked.png b/ksysv/pics/ksysv_unlocked.png
new file mode 100644
index 0000000..a52d790
--- /dev/null
+++ b/ksysv/pics/ksysv_unlocked.png
Binary files differ
diff --git a/ksysv/pics/stop.png b/ksysv/pics/stop.png
new file mode 100644
index 0000000..1cabc6e
--- /dev/null
+++ b/ksysv/pics/stop.png
Binary files differ
diff --git a/ksysv/toolbar/Makefile.am b/ksysv/toolbar/Makefile.am
new file mode 100644
index 0000000..e5515a8
--- /dev/null
+++ b/ksysv/toolbar/Makefile.am
@@ -0,0 +1 @@
+KDE_ICON = AUTO
diff --git a/ksysv/toolbar/cr16-action-toggle_log.png b/ksysv/toolbar/cr16-action-toggle_log.png
new file mode 100644
index 0000000..e2a44ec
--- /dev/null
+++ b/ksysv/toolbar/cr16-action-toggle_log.png
Binary files differ
diff --git a/ksysv/trash.cpp b/ksysv/trash.cpp
new file mode 100644
index 0000000..8420687
--- /dev/null
+++ b/ksysv/trash.cpp
@@ -0,0 +1,141 @@
+/***************************************************************************
+ 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. *
+ * *
+ ***************************************************************************/
+
+// Trash Can
+
+#include <qtooltip.h>
+#include <qlabel.h>
+#include <qpainter.h>
+
+#include <kapplication.h>
+#include <kiconloader.h>
+#include <kglobal.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+
+#include "ksvdraglist.h"
+#include "ksvdrag.h"
+#include "ActionList.h"
+#include "trash.h"
+
+KSVTrash::KSVTrash (QWidget* parent, const char* name)
+ : QFrame (parent, name),
+ mKIL (KGlobal::iconLoader()),
+ mLabel (new QLabel(this)),
+ mOpen (false)
+{
+ setLineWidth(1);
+ setMidLineWidth(0);
+
+ setFrameStyle (QFrame::StyledPanel | QFrame::Sunken);
+
+ mLabel->setPixmap(mKIL->loadIcon("trashcan_empty", KIcon::Desktop));
+ mPixmapWidth = mLabel->pixmap()->width();
+ mLabel->setGeometry(5, 7, mPixmapWidth, mPixmapWidth);
+
+ QToolTip::add(mLabel, i18n("Drag here to remove services"));
+ QToolTip::add(this, i18n("Drag here to remove services"));
+
+ setMinimumSize(sizeHint());
+ setAcceptDrops(true);
+
+ mLabel->installEventFilter(this);
+ mLabel->setAcceptDrops(true);
+}
+
+KSVTrash::~KSVTrash()
+{
+}
+
+void KSVTrash::dropEvent (QDropEvent* e)
+{
+ KSVData data;
+ KSVDragList* list = static_cast<KSVDragList*> (e->source());
+
+ if (list && strcmp (list->name(), "Scripts") && KSVDrag::decodeNative (e, data))
+ {
+ e->accept();
+
+ emit undoAction (new RemoveAction (list, &data));
+ delete list->match (data);
+ }
+ else
+ e->ignore();
+
+ if (mOpen)
+ {
+ mLabel->repaint();
+ mOpen = false;
+ }
+}
+
+void KSVTrash::dragMoveEvent ( QDragMoveEvent* e )
+{
+ if (e->provides ("application/x-ksysv") &&
+ e->source() && strcmp (e->source()->name(), "Scripts"))
+ {
+ QPainter p;
+
+ p.begin(mLabel);
+ p.drawPixmap( 0, 0, mKIL->loadIcon("trashcan_full", KIcon::Desktop) );
+ p.end();
+
+ mOpen = true;
+ e->accept();
+ }
+ else
+ e->ignore();
+}
+
+void KSVTrash::dragLeaveEvent ( QDragLeaveEvent* )
+{
+ if (mOpen)
+ {
+ mLabel->repaint();
+ mOpen = false;
+ }
+}
+
+bool KSVTrash::eventFilter( QObject *, QEvent *e )
+{
+ switch (e->type())
+ {
+ case QEvent::DragMove:
+ dragMoveEvent ( static_cast<QDragMoveEvent*> (e) );
+ return true;
+ break;
+
+ case QEvent::DragLeave:
+ dragLeaveEvent ( static_cast<QDragLeaveEvent*> (e) );
+ return true;
+ break;
+
+ case QEvent::Drop:
+ dropEvent ( static_cast<QDropEvent*> (e) );
+ return true;
+ break;
+
+ default:
+ return false;
+ }
+}
+
+QSize KSVTrash::sizeHint() const
+{
+ static QSize size = QSize (mPixmapWidth + 2 * 5, mPixmapWidth + 2 * 7);
+
+ return size;
+}
+
+#include "trash.moc"
diff --git a/ksysv/trash.h b/ksysv/trash.h
new file mode 100644
index 0000000..7772d19
--- /dev/null
+++ b/ksysv/trash.h
@@ -0,0 +1,66 @@
+/***************************************************************************
+ begin : Sun Oct 3 1999
+ copyright : (C) 1997-99 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef KSV_TRASH_H
+#define KSV_TRASH_H
+
+#include <qframe.h>
+#include <qpixmap.h>
+#include <qstring.h>
+
+// forward declarations
+class QLabel;
+class KIconLoader;
+class KSVItem;
+class KSVAction;
+
+class KSVTrash : public QFrame
+{
+ Q_OBJECT
+
+public:
+ KSVTrash (QWidget* parent = 0, const char* name = 0);
+ virtual ~KSVTrash();
+
+ virtual QSize sizeHint() const;
+
+protected:
+ /**
+ * Overridden from @ref QDropSite
+ */
+ virtual void dragMoveEvent ( QDragMoveEvent* );
+
+ /**
+ * Overridden from @ref QDropSite
+ */
+ virtual void dragLeaveEvent ( QDragLeaveEvent* );
+
+ /**
+ * Overridden from @ref QDropSite
+ */
+ virtual void dropEvent ( QDropEvent* );
+
+ virtual bool eventFilter ( QObject*, QEvent* );
+
+private:
+ KIconLoader* mKIL;
+ QLabel* mLabel;
+ bool mOpen;
+ int mPixmapWidth;
+
+signals:
+ void undoAction (KSVAction*);
+};
+
+#endif
diff --git a/ksysv/version.h b/ksysv/version.h
new file mode 100644
index 0000000..6b5ea67
--- /dev/null
+++ b/ksysv/version.h
@@ -0,0 +1,32 @@
+/*
+** Copyright (C) 2000 Peter Putzer <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; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program in a file called COPYING; if not, write to
+** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+** MA 02110-1301, USA.
+*/
+
+/*
+** Bug reports and questions can be sent to kde-devel@kde.org
+*/
+#ifndef KSV_VERSION_H
+#define KSV_VERSION_H
+
+#define KSYSV_VERSION_STRING "1.3.9"
+
+#endif // KSV_VERSION_H
+
diff --git a/ksysv/x-ksysv-log.desktop b/ksysv/x-ksysv-log.desktop
new file mode 100644
index 0000000..30e4d66
--- /dev/null
+++ b/ksysv/x-ksysv-log.desktop
@@ -0,0 +1,68 @@
+[Desktop Entry]
+Comment=SysV-Init Editor Log File
+Comment[ar]=ملف محرّر سجل الوقائع SysV-Init
+Comment[az]=SysV-Init Editor Qeyd Faylı
+Comment[be]=Часопіс рэдактара SysV-Init
+Comment[bg]=Редактор на инициализиращите нива
+Comment[bn]= সিস-ভি-আইনিট সম্পাদক কার্যবিবরণী ফাইল
+Comment[bs]=SysV-Init Editor log datoteka
+Comment[ca]=Fitxer de registre de l'editor init SysV
+Comment[cs]=Záznamový soubor programu SysV-Init editoru
+Comment[cy]=Ffeil Cofnodi Golygydd SysV-Init
+Comment[da]=SysV-Init editor logfil
+Comment[de]=Protokolldatei des SysV-Init-Editors
+Comment[el]=Αρχείο καταχωρήσεων επεξεργαστή SysV-Init
+Comment[eo]=protokoldosiero de SysV-Prepar-Redaktilo
+Comment[es]=Archivo de registro del Editor de inicio SysV
+Comment[et]=SysV-Init redaktori logifail
+Comment[eu]=SysV-abioko editorearen logfitxategia
+Comment[fa]=پروندۀ ثبت ویرایشگر آغازین SysV
+Comment[fi]=SysV-init-editorin lokitiedosto
+Comment[fr]=Journal de l'éditeur de configuration de démarrage SysV
+Comment[ga]=Logchomhad don eagarthóir SysV-Init
+Comment[gl]=Ficheiro de Rexisto do Editor de Início SysV
+Comment[he]=קובץ רישום של מנהל השירותים
+Comment[hi]=सिस-वी-इनिट संपादक लॉग फ़ाइल
+Comment[hr]=Datoteka zapisnika uređivača SysV-Init
+Comment[hu]=SysV-Init (szolgáltatáskezelő) naplófájl
+Comment[is]=SysV-Init stjóra annáll
+Comment[it]=File di log dell'editor di SysV-Init
+Comment[ja]=SystemV 起動スクリプトエディタのログファイル
+Comment[ka]=SysV-Init რედაქტორის ჟურნალი
+Comment[kk]=SysV-Init редактордың журналы
+Comment[km]=ឯកសារ​កំណត់​ហេតុ​កម្មវិធី​និពន្ធ SysV-Init
+Comment[ko]=SysV-Init 편집기 로그 파일
+Comment[lt]=SysV-Init redaktoriaus žurnalas
+Comment[mk]=Дневник на уредувачот на SysV-Init
+Comment[mt]=Logfile ta' l-editur SysV-Init
+Comment[nb]=Loggfil for SysV-init-redigering
+Comment[nds]=Logbook för den SysV-Init-Editor
+Comment[ne]=SysV-Init सम्पादक लग फाइल
+Comment[nl]=Logbestand van SysV-Init Editor
+Comment[nn]=Loggfil for SysV-init-redigering
+Comment[pa]=SysV-Init ਸੰਪਾਦਕ ਲਾੱਗ ਫਾਇਲ਼
+Comment[pl]=Plik dziennika edytora SysV-Init
+Comment[pt]=Registo do Editor System V Init
+Comment[pt_BR]=Arquivo de Registro do Editor do SysV-Init
+Comment[ro]=Fişier jurnal al managerului de servicii SysV
+Comment[ru]=Журнал редактора SysV-Init
+Comment[se]=Sysv-init-doaimmaheami gozihanfiila
+Comment[sk]=Súbor záznamu SysV-Init editora
+Comment[sl]=Datoteka z dnevnikom SysV-Init
+Comment[sr]=Дневник уређивача SysV-init-а
+Comment[sr@Latn]=Dnevnik uređivača SysV-init-a
+Comment[sv]=Editor för Sysv-Init-loggfiler
+Comment[ta]=SysV-Init திருத்துபவர் பதிவுக்கோப்பு
+Comment[tg]=Муҳаррири Файли Вориди SysV-Init
+Comment[th]=แฟ้มบันทึกการทำงานของเครื่องมือแก้ไขการเริ่มระบบแบบ SysV
+Comment[tr]=SysV-Inıt Düzenleyici Günlük Dosyası
+Comment[uk]=Файл журналу редактора SysV-Init
+Comment[vi]=Tập tin ghi lưu bộ sửa SysV-Init
+Comment[wa]=Fitchî djournå di l' aspougneu po SysV-Init
+Comment[zh_CN]=SysV-Init 编辑器记录文件
+Comment[zh_HK]=SysV-Init 編輯器記錄檔案
+Comment[zh_TW]=SysV Init 編輯器記錄檔案
+Icon=ksysv
+Type=MimeType
+MimeType=text/x-ksysv-log
+Patterns=*.ksysv_log;
diff --git a/ksysv/x-ksysv.desktop b/ksysv/x-ksysv.desktop
new file mode 100644
index 0000000..8e6f73a
--- /dev/null
+++ b/ksysv/x-ksysv.desktop
@@ -0,0 +1,78 @@
+[Desktop Entry]
+Comment=Saved Init Configuration
+Comment[af]=Gestoor Init Opstelling
+Comment[ar]=إعدادات Init المحفوظة
+Comment[az]=Qeyd Edilmiş Init Quraşdırması
+Comment[be]=Запісаныя настаўленні ініцыялізацыі
+Comment[bg]=Настройване на инициализиращите нива
+Comment[bn]=সংরক্ষিত আইনিট কনফিগারেশন
+Comment[br]=Kefluniañ deraouiñ enrollet
+Comment[bs]=Spremljena Init postavka
+Comment[ca]=S'ha desat la configuració init
+Comment[cs]=Uložené nastavení inicializačních schémat
+Comment[cy]=Wedi cadw furfweddiad Init
+Comment[da]=Gemt Init-indstilling
+Comment[de]=Gespeicherte Init-Einstellungen
+Comment[el]=Αποθηκευμένες ρυθμίσεις Init
+Comment[eo]=Konservita Preparagordo
+Comment[es]=Configuración de inicio guardada
+Comment[et]=Salvestatud Initi konfiguratsioon
+Comment[eu]=Init konfigurazio gordea
+Comment[fa]=پیکربندی آغازین ذخیره‌شده
+Comment[fi]=Tallennetut Init-asetukset
+Comment[fo]=Hevur goymt upprunaliga uppsetinging
+Comment[fr]=Sauvegarde de la configuration de démarrage
+Comment[ga]=Cumraíocht Tosaithe Sábháilte
+Comment[gl]=Configuración de Init Guardada
+Comment[he]=תצורת אתחול שמורה
+Comment[hi]=इनिट कॉन्फ़िगरेशन सहेजा
+Comment[hr]=Spremljena Init konfiguracija
+Comment[hu]=Elmentett Init beállítás
+Comment[id]=Konfigurasi Saved Init
+Comment[is]=Vistaðar Init stillingar
+Comment[it]=Configurazione di Init salvata
+Comment[ja]=保存されている起動スクリプトの設定
+Comment[ka]=Init-ის შენახული კონფიგურაცია
+Comment[kk]=Сақталған инициализацияның баптаулары
+Comment[km]=ការ​កំណត់​រចនា​សម្ព័ន្ធ Init ដែល​បាន​រក្សា​ទុក
+Comment[ko]=Init 설정을 저장했습니다
+Comment[lt]=Įrašytos Init parinktys
+Comment[lv]=Saglabātā Init Konfigurācija
+Comment[mk]=Зачувана конфигурација на Init
+Comment[mn]=Хадгалагдсан Инит Тохиргоо
+Comment[ms]=Konfigurasi Init yang Disimpan
+Comment[mt]=Konfigurazzjoni mistura tal-Init
+Comment[nb]=Lagret oppstartsoppsett
+Comment[nds]=Sekert Init-Instellen
+Comment[ne]=बचत गरिएको Init कन्फिगरेसन
+Comment[nl]=Opgeslagen Init-configuratie
+Comment[nn]=Lagra init-oppsett
+Comment[pa]=ਸੰਭਾਲੀ Init ਸੰਰਚਨਾ
+Comment[pl]=Zapisana konfiguracja startowa systemu
+Comment[pt]=Configuração do Init
+Comment[pt_BR]=Configuração do Init Salva
+Comment[ro]=Configuraţie de iniţializare salvată
+Comment[ru]=Сохранённые настройки инициализации
+Comment[se]=Vurkii init-heivehusat
+Comment[sk]=Uložená konfigurácia init
+Comment[sl]=Shranjena uvodna sestava
+Comment[sr]=Сачувана почетна подешавања
+Comment[sr@Latn]=Sačuvana početna podešavanja
+Comment[sv]=Sparad startinställning
+Comment[ta]=Init வடிவமைப்பு சேமிக்கப்பட்டது
+Comment[tg]=Танзимотҳои оғози нигоҳ дошта
+Comment[th]=บันทึกค่าปรับแต่งของการเริ่มระบบ
+Comment[tr]=Kaydedilmiş Init Yapılandırması
+Comment[uk]=Збережена конфігурація процесу Init
+Comment[ven]=Khonofiguresheni yo vhulungelwaho khayo
+Comment[vi]=Cấu hình Init đã lưu
+Comment[wa]=Apontiaedje d' enondaedje schapé
+Comment[xh]=Uqwalaselo olugciniweyo lwe Init
+Comment[zh_CN]=已保存的 Init 配置
+Comment[zh_HK]=已儲存 Init 設定
+Comment[zh_TW]=已儲存起始設定
+Comment[zu]=Uhlanganiselo olugciniwe lwe Init
+Icon=ksysv
+Type=MimeType
+MimeType=application/x-ksysv-package
+Patterns=*.ksysv;