diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | 37333bf25ad9a4c538250f5af2f9f1d666362883 (patch) | |
tree | c45e8df5b9efbffe07eb3d9340df7811c7e16943 /ksysv | |
download | tdeadmin-37333bf25ad9a4c538250f5af2f9f1d666362883.tar.gz tdeadmin-37333bf25ad9a4c538250f5af2f9f1d666362883.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdeadmin@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'ksysv')
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><h3>What Operating System do you use?</h3></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>&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>&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>&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>&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>&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>&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>&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&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>&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>&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>&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>&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&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><h1>Congratulations!</h1> +<p> +You have finished the initial configuration of SysV-Init Editor. <b>Press</b> the button labeled <b>Finish</b> to start editing your init-configuration. +</p></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 Binary files differnew file mode 100644 index 0000000..999809e --- /dev/null +++ b/ksysv/hi16-app-ksysv.png diff --git a/ksysv/hi22-app-ksysv.png b/ksysv/hi22-app-ksysv.png Binary files differnew file mode 100644 index 0000000..e286b73 --- /dev/null +++ b/ksysv/hi22-app-ksysv.png diff --git a/ksysv/hi32-app-ksysv.png b/ksysv/hi32-app-ksysv.png Binary files differnew file mode 100644 index 0000000..89a85b4 --- /dev/null +++ b/ksysv/hi32-app-ksysv.png diff --git a/ksysv/hi48-app-ksysv.png b/ksysv/hi48-app-ksysv.png Binary files differnew file mode 100644 index 0000000..5845c03 --- /dev/null +++ b/ksysv/hi48-app-ksysv.png 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 ∁ +} + +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 ∁ +} + +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>&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>&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>&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>&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>&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 & 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 & 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&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>&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><p>Use the <strong>Select Color dialog box</strong> to pick a text color for <em>services that have been changed</em> (either order/sorting number or name).</p> +<p>Changed service entries will be distinguished by this color.</p></string> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>mChangedNormalLabel</cstring> + </property> + <property name="text"> + <string>&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><p>Use the <strong>Select Color dialog box</strong> to pick a text color for <em>services new to a runlevel</em>.</p> +<p>New service entries will be distinguished by this color.</p></string> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>mNewNormalLabel</cstring> + </property> + <property name="text"> + <string>&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><p>Use the <strong>Select Color dialog box</strong> to pick a selected text color for <em>services that have been changed</em> (either order/sorting number or name).</p> +<p>Changed service entries will be distinguished by this color while they are selected.</p></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><p>Use the <strong>Select Color dialog box</strong> to pick a selected text color for <em>services new to a runlevel</em>.</p> +<p>New service entries will be distinguished by this color while they are selected.</p></string> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>mNewSelectedLabel</cstring> + </property> + <property name="text"> + <string>New && &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 && s&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&)</signal> + <receiver>LookAndFeel</receiver> + <slot>slotChanged()</slot> + </connection> + <connection> + <sender>mNewSelected</sender> + <signal>changed(const QColor&)</signal> + <receiver>LookAndFeel</receiver> + <slot>slotChanged()</slot> + </connection> + <connection> + <sender>mChangedNormal</sender> + <signal>changed(const QColor&)</signal> + <receiver>LookAndFeel</receiver> + <slot>slotChanged()</slot> + </connection> + <connection> + <sender>mChangedSelected</sender> + <signal>changed(const QColor&)</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>&Show All</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>mWarnReadOnly</cstring> + </property> + <property name="text"> + <string>&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 &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>&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>&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>&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&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&)</signal> + <receiver>PathConfiguration</receiver> + <slot>slotChanged()</slot> + </connection> + <connection> + <sender>mRunlevelPath</sender> + <signal>textChanged(const QString&)</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 Binary files differnew file mode 100644 index 0000000..03480e3 --- /dev/null +++ b/ksysv/pics/ksysv_locked.png diff --git a/ksysv/pics/ksysv_restart.png b/ksysv/pics/ksysv_restart.png Binary files differnew file mode 100644 index 0000000..8f4ad31 --- /dev/null +++ b/ksysv/pics/ksysv_restart.png diff --git a/ksysv/pics/ksysv_start.png b/ksysv/pics/ksysv_start.png Binary files differnew file mode 100644 index 0000000..debff53 --- /dev/null +++ b/ksysv/pics/ksysv_start.png diff --git a/ksysv/pics/ksysv_stop.png b/ksysv/pics/ksysv_stop.png Binary files differnew file mode 100644 index 0000000..5decccd --- /dev/null +++ b/ksysv/pics/ksysv_stop.png diff --git a/ksysv/pics/ksysv_unlocked.png b/ksysv/pics/ksysv_unlocked.png Binary files differnew file mode 100644 index 0000000..a52d790 --- /dev/null +++ b/ksysv/pics/ksysv_unlocked.png diff --git a/ksysv/pics/stop.png b/ksysv/pics/stop.png Binary files differnew file mode 100644 index 0000000..1cabc6e --- /dev/null +++ b/ksysv/pics/stop.png 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 Binary files differnew file mode 100644 index 0000000..e2a44ec --- /dev/null +++ b/ksysv/toolbar/cr16-action-toggle_log.png 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; |