diff options
Diffstat (limited to 'ksim/library')
-rw-r--r-- | ksim/library/Makefile.am | 25 | ||||
-rw-r--r-- | ksim/library/chart.cpp | 627 | ||||
-rw-r--r-- | ksim/library/chart.h | 184 | ||||
-rw-r--r-- | ksim/library/common.cpp | 102 | ||||
-rw-r--r-- | ksim/library/common.h | 134 | ||||
-rw-r--r-- | ksim/library/ksimconfig.cpp | 427 | ||||
-rw-r--r-- | ksim/library/ksimconfig.h | 109 | ||||
-rw-r--r-- | ksim/library/label.cpp | 301 | ||||
-rw-r--r-- | ksim/library/label.h | 210 | ||||
-rw-r--r-- | ksim/library/led.cpp | 349 | ||||
-rw-r--r-- | ksim/library/led.h | 193 | ||||
-rw-r--r-- | ksim/library/pluginglobal.cpp | 207 | ||||
-rw-r--r-- | ksim/library/pluginglobal.h | 161 | ||||
-rw-r--r-- | ksim/library/pluginloader.cpp | 326 | ||||
-rw-r--r-- | ksim/library/pluginloader.h | 183 | ||||
-rw-r--r-- | ksim/library/pluginmodule.cpp | 174 | ||||
-rw-r--r-- | ksim/library/pluginmodule.h | 205 | ||||
-rw-r--r-- | ksim/library/progress.cpp | 231 | ||||
-rw-r--r-- | ksim/library/progress.h | 181 | ||||
-rw-r--r-- | ksim/library/themeloader.cpp | 1266 | ||||
-rw-r--r-- | ksim/library/themeloader.h | 511 | ||||
-rw-r--r-- | ksim/library/themetypes.h | 81 |
22 files changed, 6187 insertions, 0 deletions
diff --git a/ksim/library/Makefile.am b/ksim/library/Makefile.am new file mode 100644 index 0000000..f3b834f --- /dev/null +++ b/ksim/library/Makefile.am @@ -0,0 +1,25 @@ +lib_LTLIBRARIES = libksimcore.la + +libksimcore_la_SOURCES = common.cpp themeloader.cpp \ + chart.cpp label.cpp \ + led.cpp progress.cpp \ + pluginglobal.cpp pluginloader.cpp \ + pluginmodule.cpp ksimconfig.cpp + +libksimcore_la_LDFLAGS = $(all_libraries) -version-info 1:0 -no-undefined +libksimcore_la_LIBADD = $(LIB_KDEUI) + +ksiminclude_HEADERS = common.h themeloader.h \ + chart.h label.h \ + led.h progress.h \ + pluginglobal.h pluginloader.h \ + pluginmodule.h themetypes.h \ + ksimconfig.h + + +ksimincludedir = $(includedir)/ksim + +INCLUDES= $(all_includes) + +METASOURCES = AUTO + diff --git a/ksim/library/chart.cpp b/ksim/library/chart.cpp new file mode 100644 index 0000000..38f0f17 --- /dev/null +++ b/ksim/library/chart.cpp @@ -0,0 +1,627 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "chart.h" +#include "chart.moc" + +#include <qrect.h> +#include <qpainter.h> +#include <qimage.h> +#include <qcolor.h> +#include <qtimer.h> +#include <qvaluelist.h> +#include <qbitmap.h> + +#include <kdebug.h> +#include <klocale.h> +#include <kglobalsettings.h> +#include <kconfig.h> + +#include <themeloader.h> +#include <led.h> +#include <ksimconfig.h> +#include "themetypes.h" + +class KSim::Chart::Timer +{ + public: + static void syncChart(KSim::Chart *chart) + { + if (!m_timer) { + m_timer = new QTimer; + m_timer->start(1000); + qAddPostRoutine(cleanup); + } + + QObject::connect(m_timer, SIGNAL(timeout()), + chart, SLOT(updateDisplay())); + } + + static void disconnect(KSim::Chart *chart) + { + if (!m_timer) + return; + + QObject::disconnect(m_timer, SIGNAL(timeout()), + chart, SLOT(updateDisplay())); + } + + private: + static void cleanup() + { + if (!m_timer) + return; + + delete m_timer; + m_timer = 0; + } + + static QTimer *m_timer; +}; + +QTimer *KSim::Chart::Timer::m_timer = 0; + +class KSim::Chart::Private +{ + public: + typedef QPair<int, int> ValuePair; + + QSize size; + int type; + bool showShadow; + bool showKrell; + QString inText; + QString outText; + QString title; + QPixmap chartPixmap; + QPixmap gridPixmap; + QPixmap graphData; + QColor mColour; + QColor sColour; + QColor dataInColour; + QColor dataOutColour; + Chart::LabelType labelType; + KSim::Label *krell; + // first will be data In and second will be data out + QValueList<ValuePair> values; + QValueList<int> maxValues; + int minValue; + int maxValue; + bool variableGraphs; +}; + +KSim::Chart::Chart(bool showKrell, int maxValue, + const QString &title, QWidget *parent, const char *name, + WFlags fl) : QWidget(parent, name, fl) +{ + init(showKrell, maxValue, title); +} + +KSim::Chart::Chart(bool showKrell, int maxValue, + QWidget *parent, const char *name, WFlags fl) + : QWidget(parent, name, fl) +{ + init(showKrell, maxValue, i18n("None")); +} + +KSim::Chart::~Chart() +{ + delete d->krell; + delete d; +} + +const QString &KSim::Chart::text(DataType type) const +{ + if (type == DataIn) + return d->inText; + + return d->outText; +} + +const QString &KSim::Chart::title() const +{ + return d->title; +} + +bool KSim::Chart::displayMeter() const +{ + return d->showKrell; +} + +int KSim::Chart::minValue() const +{ + return d->minValue; +} + +int KSim::Chart::maxValue() const +{ + return d->maxValue; +} + +int KSim::Chart::value(DataType dataType) const +{ + switch (dataType) { + case DataIn: + return d->values.first().first; + break; + case DataOut: + return d->values.first().second; + break; + } + + return 0; +} + +void KSim::Chart::setLabelType(LabelType labelType) +{ + d->labelType = labelType; + + // return if d->krell is not NULL and if the label type is the + // same or if showKrell is set to false + if ((d->krell && d->labelType == labelType) || !d->showKrell) + return; + + delete d->krell; + + switch (labelType) { + case Label: + d->krell = new KSim::Label(this); + break; + case Progress: + d->krell = new KSim::Progress(maxValue(), KSim::Types::None, + KSim::Progress::Panel, this); + break; + case Led: + d->krell = new KSim::LedLabel(maxValue(), KSim::Types::None, this); + break; + } + + int height = d->krell->height() - 2; + d->krell->setText(title()); + d->krell->setFixedSize(width(), height); + d->krell->move(0, d->size.height() - height); + d->krell->show(); +} + +KSim::Chart::LabelType KSim::Chart::labelType() const +{ + return d->labelType; +} + +void KSim::Chart::buildPixmaps() +{ + QImage image(themeLoader().current().chartPixmap()); + KSim::ThemeLoader::self().reColourImage(image); + d->chartPixmap.convertFromImage(image.smoothScale(chartSize())); + + // We need to reset the image data just + // incase the krellDataIn image doesn't exist + image.reset(); + image.load(themeLoader().current().gridPixmap()); + KSim::ThemeLoader::self().reColourImage(image); + d->gridPixmap.convertFromImage(image.smoothScale(chartSize().width(), 1)); + + // load these values here so we dont need to keep accessing them while + // painting to keep the cpu usage down + d->dataInColour = themeLoader().current().chartInColour(); + d->dataOutColour = themeLoader().current().chartOutColour(); + + image.reset(); + image.load(themeLoader().current().dataInPixmap()); + KSim::ThemeLoader::self().reColourImage(image); + if (!image.isNull()) { + d->dataInColour = image.smoothScale(chartSize()).pixel(2, 2); + kdDebug(2003) << className() << ": Using krellDataIn() = " + << themeLoader().current().dataInPixmap() << endl; + } + else { + kdDebug(2003) << className() << ": Using chartInColor() = " + << d->dataInColour.name() << endl; + } + + image.reset(); + image.load(themeLoader().current().dataOutPixmap()); + KSim::ThemeLoader::self().reColourImage(image); + if (!image.isNull()) { + d->dataOutColour = image.smoothScale(chartSize()).pixel(2, 2); + kdDebug(2003) << className() << ": Using krellDataOut() = " + << themeLoader().current().dataOutPixmap() << endl; + } + else { + kdDebug(2003) << className() << ": Using chartOutColor() = " + << d->dataOutColour.name() << endl; + } +} + +void KSim::Chart::configureObject(bool repaintWidget) +{ + QSize oldSize = sizeHint(); + KSim::Config::config()->setGroup("Misc"); + d->size = KSim::Config::config()->readSizeEntry("GraphSize"); + + if (d->krell && d->showKrell) { + int krellHeight = d->krell->fontMetrics().height() - 2; + d->size.setHeight(d->size.height() + krellHeight); + d->krell->setFixedHeight(krellHeight); + d->krell->move(0, d->size.height() - krellHeight); + d->krell->show(); + } + + // Update our geometry if we need to let any + // layout know about our sizeHint() change + if (oldSize != sizeHint()) { + // Using resize() here seems to be needed + resize(sizeHint()); + updateGeometry(); + } + + buildPixmaps(); + + setConfigValues(); + + if (repaintWidget) + update(); +} + +QSize KSim::Chart::sizeHint() const +{ + return d->size; +} + +QSize KSim::Chart::minimumSizeHint() const +{ + return sizeHint(); +} + +void KSim::Chart::resizeEvent(QResizeEvent *re) +{ + if (d->chartPixmap.size() != chartSize()) + buildPixmaps(); + QWidget::resizeEvent(re); +} + +void KSim::Chart::disableAutomaticUpdates() +{ + KSim::Chart::Timer::disconnect(this); +} + +void KSim::Chart::clear() +{ + d->values.clear(); + d->maxValues.clear(); + updateDisplay(); +} + +void KSim::Chart::setTitle(const QString &name) +{ + if (d->krell) { + d->title = name; + d->krell->setText(name); + } +} + +void KSim::Chart::setDisplayMeter(bool value) +{ + if (d->showKrell == value) + return; + + d->showKrell = value; + setLabelType(d->labelType); + + // delete the meter if value is false + if (!value) { + delete d->krell; + d->krell = 0; + } +} + +void KSim::Chart::setText(const QString &in, const QString &out) +{ + bool repaint = false; + + if (d->inText != in) { + repaint = true; + d->inText = in; + } + + if (d->outText != out) { + repaint = true; + d->outText = out; + } + + if (repaint) + update(); +} + +void KSim::Chart::setMinValue(int minValue) +{ + if (d->minValue == minValue) + return; + + d->minValue = minValue; + + if (d->krell && labelType() != Label) + static_cast<KSim::Progress *>(d->krell)->setMinValue(minValue); +} + +void KSim::Chart::setMaxValue(int maxValue) +{ + if (d->maxValue == maxValue) + return; + + d->maxValue = maxValue; + + if (d->krell && labelType() != Label) + static_cast<KSim::Progress *>(d->krell)->setMaxValue(maxValue); +} + +void KSim::Chart::setValue(int valueIn, int valueOut) +{ + d->values.prepend(qMakePair(range(valueIn), range(valueOut))); + + if (d->variableGraphs) { + d->maxValues.prepend(valueIn > valueOut ? valueIn : valueOut); + } + else { + if (valueIn > maxValue()) + setMaxValue(valueIn); + + if (valueOut > maxValue()) + setMaxValue(valueOut); + } + + if (d->krell && labelType() != Label) + static_cast<KSim::Progress *>(d->krell)->setValue(valueIn ? valueIn + : valueOut); + + // Remove the first entry from our lists to + // make sure we only have a list the size of + // our widgets width + if (d->values.count() == (uint)(width() + 1)) { + d->values.remove(--(d->values.end())); + d->maxValues.remove(--(d->maxValues.end())); + } + + if (d->krell && labelType() == Led) { + static_cast<KSim::LedLabel *>(d->krell)->toggle(KSim::Led::First); + static_cast<KSim::LedLabel *>(d->krell)->toggle(KSim::Led::Second); + } +} + +void KSim::Chart::setConfigValues() +{ + QFont newFont = font(); + bool repaint = themeLoader().current().fontColours(this, + newFont, d->mColour, d->sColour, d->showShadow); + + if (font() != newFont) + setFont(newFont); + + if (repaint) + update(); +} + +void KSim::Chart::extraTypeCall() +{ + setConfigValues(); +} + +QColor KSim::Chart::chartColour(const DataType &dataType, int, int) const +{ + switch (dataType) { + case DataIn: + return d->dataInColour; + break; + case DataOut: + return d->dataOutColour; + break; + } + + return QColor(); // avoid a g++ warning +} + +void KSim::Chart::paintEvent(QPaintEvent *) +{ + if (d->krell && labelType() == Led) { + static_cast<KSim::LedLabel *>(d->krell)->setOff(KSim::Led::First); + static_cast<KSim::LedLabel *>(d->krell)->setOff(KSim::Led::Second); + } + + const QSize &size = chartSize(); + QPixmap pixmap(size); + QPainter painter; + painter.begin(&pixmap, this); + + int location = size.height() / 5; + painter.drawPixmap(0, 0, d->chartPixmap); + // draw the plotted data onto the graph + painter.drawPixmap(0, 0, d->graphData); + painter.drawPixmap(0, location, d->gridPixmap); + painter.drawPixmap(0, location * 2, d->gridPixmap); + painter.drawPixmap(0, location * 3, d->gridPixmap); + painter.drawPixmap(0, location * 4, d->gridPixmap); + painter.drawPixmap(0, location * 5, d->gridPixmap); + + if (d->showShadow) { + painter.setPen(d->sColour); + location = (fontMetrics().height() / 2) + 5; + painter.drawText(3, location, d->inText); + if (!d->outText.isNull()) + painter.drawText(3, location * 2, d->outText); + } + + painter.setPen(d->mColour); + location = (fontMetrics().height() / 2) + 3; + painter.drawText(1, location, d->inText); + if (!d->outText.isNull()) + painter.drawText(1, location * 2, d->outText); + + painter.end(); + bitBlt(this, 0, 0, &pixmap); +} + +void KSim::Chart::fontChange(const QFont &) +{ + if (d->krell) + d->krell->setFont(font()); +} + +void KSim::Chart::updateDisplay() +{ + drawChart(); + update(); +} + +int KSim::Chart::yLocation(int value) const +{ + int krellHeight = (d->krell ? d->krell->height() : 0); + + int rangePos = maxValue() - minValue(); + int valuePos = value - minValue(); + + int returnValue = 0; + if (rangePos) + returnValue = (height() - krellHeight) * valuePos / rangePos; + + // Make sure we dont return a negative value + return returnValue >= 0 ? returnValue : 0; +} + +void KSim::Chart::drawChart() +{ + if (chartSize() != d->graphData.size()) + d->graphData.resize(chartSize()); + + if (d->variableGraphs) { + int maxValue = 0; + QValueList<int>::ConstIterator max; + for (max = d->maxValues.begin(); max != d->maxValues.end(); ++max) { + if ((*max) > maxValue) + maxValue = (*max); + } + + setMaxValue(maxValue); + } + + QPainter painter; + d->graphData.setMask(drawMask(&painter)); + painter.begin(&d->graphData, this); + + int position = width() - 1; + QValueList<Private::ValuePair>::ConstIterator it; + for (it = d->values.begin(); it != d->values.end(); ++it) { + // Draw the data In lines first if its higher than the data out lines + if ((*it).first >= (*it).second) { + drawIn(&painter, (*it).first, position); + drawOut(&painter, (*it).second, position); + } + else { + drawOut(&painter, (*it).second, position); + drawIn(&painter, (*it).first, position); + } + --position; + } + + painter.end(); +} + +QSize KSim::Chart::chartSize() const +{ + QSize sz(size()); + if (d->krell && d->showKrell) + sz.setHeight(sz.height() - d->krell->height()); + + return sz; +} + +QBitmap KSim::Chart::drawMask(QPainter *painter) +{ + QBitmap bitmap(chartSize(), true); + painter->begin(&bitmap, this); + painter->setPen(color1); + + int position = width() - 1; + QValueList<Private::ValuePair>::ConstIterator it; + for (it = d->values.begin(); it != d->values.end(); ++it) { + drawIn(painter, (*it).first, position, true); + drawOut(painter, (*it).second, position, true); + --position; + } + + painter->end(); + + return bitmap; +} + +void KSim::Chart::drawIn(QPainter *painter, int value, int pos, bool dontSet) +{ + if (!dontSet) { + painter->setPen(chartColour(DataIn)); + } + + int location = yLocation(value); + painter->moveTo(0, 0); + painter->drawLine(pos, d->graphData.size().height(), + pos, d->graphData.size().height() - location); +} + +void KSim::Chart::drawOut(QPainter *painter, int value, int pos, bool dontSet) +{ + if (!dontSet) { + painter->setPen(chartColour(DataOut)); + } + + int location = yLocation(value); + painter->moveTo(0, 0); + painter->drawLine(pos, d->graphData.size().height(), + pos, d->graphData.size().height() - location); +} + +int KSim::Chart::range(int value) const +{ + if (value > maxValue()) + return maxValue(); + + if (value < minValue()) + return minValue(); + + return value; +} + +void KSim::Chart::init(bool krell, int maxValue, const QString &title) +{ + setConfigString("StyleChart"); + setThemeConfigOnly(false); + setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed)); + + d = new Private; + KSim::Config::config()->setGroup("Misc"); + d->variableGraphs = KSim::Config::config()->readBoolEntry("UseVariableGraphs", true); + d->showKrell = krell; + d->krell = 0L; + d->title = title; + d->minValue = 0; + d->maxValue = 0; + + KSim::Chart::Timer::syncChart(this); + setBackgroundMode(NoBackground); + setLabelType(Label); + setMaxValue(maxValue); + configureObject(false); +} diff --git a/ksim/library/chart.h b/ksim/library/chart.h new file mode 100644 index 0000000..55f4426 --- /dev/null +++ b/ksim/library/chart.h @@ -0,0 +1,184 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KSIM__CHART_H +#define KSIM__CHART_H + +#include <qwidget.h> +#include "common.h" + +#include <kdemacros.h> + +class QColor; + +namespace KSim +{ + /** + * provides a graph displaying data onscreen using gkrellm themes + * @author Robbie Ward <linuxphreak@gmx.co.uk> + */ + class KDE_EXPORT Chart : public QWidget, public KSim::Base + { + Q_OBJECT + public: + enum DataType { DataIn = 0, DataOut }; + enum LabelType { Label = 0, Progress, Led }; + /** + * Constructs a KSim::Chart. + * + * @param displayMeter is if the krellbar should be shown + * @param minValue is the minimum value to show + * @param maxValue is the maximum value to show + * @param title is the title off the krell bar (if enabled) + * @param parent is the parent widget + */ + Chart(bool displayMeter, int maxValue, + const QString &title, QWidget *parent, + const char *name = 0, WFlags fl = 0); + /** + * Constructs a KSim::Chart. + * + * @param showKrell is if the krellbar should be shown + * @param minValue is the minimum value to show + * @param maxValue is the maximum value to show + * @param parent is the parent widget + */ + Chart(bool displayMeter, int maxValue, + QWidget *parent, const char *name = 0, + WFlags fl = 0); + /** + * destructs KSim::Chart + */ + virtual ~Chart(); + + /** + * returns the current text of the chart + */ + const QString &text(DataType type) const; + /** + * @return the title of the chart + */ + const QString &title() const; + /** + * @return true if the meter is enabled + */ + bool displayMeter() const; + /** + * @return the minimum value + */ + int minValue() const; + /** + * @return the minimum value + */ + int maxValue() const; + /** + * @return the current value + */ + int value(DataType dataType) const; + /** + * sets the type of the label that will appear under the graph + */ + void setLabelType(LabelType labelType); + /** + * @return the current label type, one of: Label, Progress, Led + */ + LabelType labelType() const; + + /** + * reimplemented for internal reasons + */ + virtual void configureObject(bool repaintWidget = true); + + /** + * reimplemented for internal reasons + */ + QSize sizeHint() const; + /** + * reimplemented for internal reasons + */ + QSize minimumSizeHint() const; + + void disableAutomaticUpdates(); + + public slots: + /** + * Cleats the graphs contents + */ + void clear(); + /** + * sets the title of the chart, this function returns if + * the optional krell widget is disabled + */ + void setTitle(const QString &); + /** + * turns the meter on and off + */ + void setDisplayMeter(bool); + /** + * sets the current text that apears in the top left hand corner + */ + void setText(const QString &in, const QString &out = QString::null); + /** + * Sets the minimum value the graph will display + */ + void setMinValue(int); + /** + * Sets the maximum value the graph will display + */ + void setMaxValue(int); + /** + * sets the value of the graph + */ + void setValue(int valueIn, int valueOut = 0); + + protected: + /** + * Set the config values depending on the chart type + */ + void setConfigValues(); + /** + * reimplemented for internal reasons + */ + virtual void extraTypeCall(); + + QColor chartColour(const DataType &dataType, int x = 1, int y = 1) const; + virtual void paintEvent(QPaintEvent *); + virtual void fontChange(const QFont &); + virtual void resizeEvent(QResizeEvent *re); + + protected slots: + void updateDisplay(); + + private: + void buildPixmaps(); + int yLocation(int) const; + void drawChart(); + QSize chartSize() const; + QBitmap drawMask(QPainter *); + void drawIn(QPainter *, int, int, bool = false); + void drawOut(QPainter *, int, int, bool = false); + int range(int) const; + void init(bool, int, const QString &); + + class Timer; + class Private; + Private *d; + }; +} +#endif diff --git a/ksim/library/common.cpp b/ksim/library/common.cpp new file mode 100644 index 0000000..3e714c6 --- /dev/null +++ b/ksim/library/common.cpp @@ -0,0 +1,102 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "common.h" +#include <kdebug.h> + +#include <themeloader.h> +#include "themetypes.h" +#include "../baselist.h" + +class KSim::Base::Private +{ + public: + int type; + bool theme; + QString string; +}; + +KSim::Base::Base() +{ + KSim::BaseList::add(this); + + d = new Base::Private; + d->type = KSim::Types::None; + d->theme = true; +} + +KSim::Base::Base(int type) +{ + KSim::BaseList::add(this); + + d = new Base::Private; + d->type = type; + d->theme = true; +} + +KSim::Base::~Base() +{ + if (!KSim::BaseList::remove(this)) + kdError() << "While trying to remove " << this << " from the list" << endl; + delete d; +} + +bool KSim::Base::isThemeConfigOnly() const +{ + return d->theme; +} + +void KSim::Base::setType(int type) +{ + if (d->type == type) + return; + + d->type = type; + extraTypeCall(); +} + +int KSim::Base::type() const +{ + return d->type; +} + +void KSim::Base::setConfigString(const QString &string) +{ + d->string = string; +} + +const QString &KSim::Base::configString() const +{ + return d->string; +} + +void KSim::Base::extraTypeCall() +{ +} + +KSim::ThemeLoader &KSim::Base::themeLoader() const +{ + // Provided for convenience + return KSim::ThemeLoader::self(); +} + +void KSim::Base::setThemeConfigOnly(bool value) +{ + d->theme = value; +} diff --git a/ksim/library/common.h b/ksim/library/common.h new file mode 100644 index 0000000..3f53f7a --- /dev/null +++ b/ksim/library/common.h @@ -0,0 +1,134 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KSIM__COMMON_H +#define KSIM__COMMON_H + +#define KSIM_VERSION 110 +#define KSIM_VERSION_STRING "1.1.0" + +#include <qstring.h> +#include <kdemacros.h> + +/** + * namespace for common ksim entries + * + * @author Robbie Ward <linuxphreak@gmx.co.uk> + */ +namespace KSim +{ + // a few forward declares + class ThemeLoader; + class Theme; + class PluginLoader; + class PluginList; + class Plugin; + class PluginObject; + class PluginView; + class PluginPage; + + /** + * class that all widgets (library dir only) HAVE to inherit + * if they want to change items on ksim configuration reload + * + * any class that inherits this must re-implement + * the configureObject() function. + * + * example: + * <pre> + * #include <qwidget.h> + * #include <ksim/common.h> + * + * class Test : public QWidget, virtual public KSim::Base + * { + * public: + * Test(QWidget *parent, const char *name) : QWidget(parent, name) + * { + * } + * ~Test() {} + * + * void configureObject(bool repaintWidget) + * { + * // Re-Create view code here + * } + * }; + * </pre> + * @short base class for widgets + * @author Robbie Ward <linuxphreak@gmx.co.uk> + */ + class KDE_EXPORT Base + { + public: + Base(); + Base(int type); + virtual ~Base(); + + /** + * Reimplement this to change theme images/locations etc + */ + virtual void configureObject(bool = true) = 0; + /** + * returns true if configureObject has been setup + * to contain only theme configuration + * @see #setThemeConfigOnly + */ + bool isThemeConfigOnly() const; + /** + * sets the theme type + */ + void setType(int type); + /** + * @return the theme type, eg host, mem, swap etc + */ + int type() const; + /** + * Set the config entry key to look for when reading gkrellmrc + */ + void setConfigString(const QString &string); + /** + * @return the config entry to look for when reading theme files + */ + const QString &configString() const; + + protected: + /** + * reimplement this function if you want setType() + * to call extra information + */ + virtual void extraTypeCall(); + /** + * @return the current KSim::ThemeLoader instance + */ + KSim::ThemeLoader &themeLoader() const; + /** + * set this to false if you want KSim to call your KSim::Base + * configureObject() when KSim's configuration has changed + * even if the theme settings are the same. The default is true + */ + void setThemeConfigOnly(bool); + + private: + Base(const Base &rhs); + Base &operator=(const Base &rhs); + + class Private; + Private *d; + }; +} +#endif diff --git a/ksim/library/ksimconfig.cpp b/ksim/library/ksimconfig.cpp new file mode 100644 index 0000000..9f70890 --- /dev/null +++ b/ksim/library/ksimconfig.cpp @@ -0,0 +1,427 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <kstandarddirs.h> +#include <kconfig.h> +#include <kglobal.h> + +#include "ksimconfig.h" +#include "themeloader.h" + +KConfig *KSim::Config::mainConfig = 0; + +KSim::Config::Config(KConfig *config) +{ + mainConfig = config; +} + +KSim::Config::~Config() +{ +} + +KConfig *KSim::Config::config() +{ + return mainConfig; +} + +int KSim::Config::width(int defaultWidth) const +{ + mainConfig->setGroup("General Options"); + int savedWidth = mainConfig->readNumEntry("Width"); + if (savedWidth == -1) + return defaultWidth; + + return savedWidth; +} + +void KSim::Config::setWidth(int width) +{ + mainConfig->setGroup("General Options"); + mainConfig->writeEntry("Width", width); + mainConfig->sync(); +} + +bool KSim::Config::enabledMonitor(const QString &entry) const +{ + mainConfig->setGroup("Monitors"); + return mainConfig->readBoolEntry(entry, false); +} + +void KSim::Config::setEnabledMonitor(const QString &entry, bool enabled) +{ + mainConfig->setGroup("Monitors"); + mainConfig->writeEntry(entry, enabled); + mainConfig->sync(); +} + +QString KSim::Config::monitorCommand(const QString &entry) const +{ + mainConfig->setGroup("Monitors"); + return mainConfig->readPathEntry(entry + "_command"); +} + +void KSim::Config::setMonitorCommand(const QString &entry, + const QString &command) +{ + mainConfig->setGroup("Monitors"); + mainConfig->writePathEntry(entry + "_command", command); + mainConfig->sync(); +} + +int KSim::Config::monitorLocation(const QString &entry) +{ + mainConfig->setGroup("Monitors"); + return mainConfig->readNumEntry(entry + "_location", -1); +} + +void KSim::Config::setMonitorLocation(const QString &entry, int location) +{ + mainConfig->setGroup("Monitors"); + mainConfig->writeEntry(entry + "_location", location); + mainConfig->sync(); +} + +bool KSim::Config::displayFqdn() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readBoolEntry("DisplayFqdn", true); +} + +void KSim::Config::setDisplayFqdn(bool value) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("DisplayFqdn", value); + mainConfig->sync(); +} + +bool KSim::Config::showDock() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readBoolEntry("showDock", true); +} + +void KSim::Config::setShowDock(bool showDock) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("showDock", showDock); + mainConfig->sync(); +} + +bool KSim::Config::savePos() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readBoolEntry("savePos", false); +} + +void KSim::Config::setSavePos(bool savePos) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("savePos", savePos); + mainConfig->sync(); +} + +bool KSim::Config::stayOnTop() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readBoolEntry("stayOnTop", false); +} + +void KSim::Config::setStayOnTop(bool stayOnTop) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("stayOnTop", stayOnTop); + mainConfig->sync(); +} + +QPoint KSim::Config::position(const QPoint &defaultPos) const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readPointEntry("ksimPosition", &defaultPos); +} + +void KSim::Config::setPosition(const QPoint &pos) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("ksimPosition", pos); + mainConfig->sync(); +} + +QSize KSim::Config::graphSize() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readSizeEntry("GraphSize"); +} + +void KSim::Config::setGraphSize(const QSize &size) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("GraphSize", size); + mainConfig->sync(); +} + +QString KSim::Config::uptimeFormat() const +{ + return uptimeFormatList()[uptimeItem()]; +} + +int KSim::Config::uptimeItem() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readNumEntry("UptimeItem", 0); +} + +QStringList KSim::Config::uptimeFormatList() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readListEntry("UptimeFormat"); +} + +void KSim::Config::setUptimeFormat(const QStringList &uptimeFormat) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("UptimeFormat", uptimeFormat); + mainConfig->sync(); +} + +void KSim::Config::setUptimeItem(int item) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("UptimeItem", item); + mainConfig->sync(); +} + +QString KSim::Config::memoryFormat() const +{ + return memoryFormatList()[memoryItem()]; +} + +int KSim::Config::memoryItem() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readNumEntry("MemoryItem", 0); +} + +QStringList KSim::Config::memoryFormatList() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readListEntry("MemoryFormat"); +} + +void KSim::Config::setMemoryFormat(const QStringList &memoryFormat) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("MemoryFormat", memoryFormat); + mainConfig->sync(); +} + +void KSim::Config::setMemoryItem(int item) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("MemoryItem", item); + mainConfig->sync(); +} + +QString KSim::Config::swapFormat() const +{ + mainConfig->setGroup("Misc"); + return swapFormatList()[swapItem()]; +} + +int KSim::Config::swapItem() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readNumEntry("SwapItem", 0); +} + +QStringList KSim::Config::swapFormatList() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readListEntry("SwapFormat"); +} + +void KSim::Config::setSwapFormat(const QStringList &swapFormat) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("SwapFormat", swapFormat); + mainConfig->sync(); +} + +void KSim::Config::setSwapItem(int item) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("SwapItem", item); + mainConfig->sync(); +} + +bool KSim::Config::showTime() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readBoolEntry("ShowTime", false); +} + +void KSim::Config::setShowTime(bool time) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("ShowTime", time); + mainConfig->sync(); +} + +bool KSim::Config::show24hour() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readBoolEntry("Show24hour", true); +} + +void KSim::Config::setShow24hour(bool _24hour) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("Show24hour", _24hour); + mainConfig->sync(); +} + +bool KSim::Config::showDate() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readBoolEntry("ShowDate", false); +} + +void KSim::Config::setShowDate(bool date) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("ShowDate", date); + mainConfig->sync(); +} + +bool KSim::Config::showUptime() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readBoolEntry("ShowUptime", true); +} + +void KSim::Config::setShowUptime(bool uptime) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("ShowUptime", uptime); + mainConfig->sync(); +} + +bool KSim::Config::showMemory() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readBoolEntry("ShowMemory", true); +} + +void KSim::Config::setShowMemory(bool memory) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("ShowMemory", memory); + mainConfig->sync(); +} + +bool KSim::Config::showSwap() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readBoolEntry("ShowSwap", true); +} + +void KSim::Config::setShowSwap(bool swap) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("ShowSwap", swap); + mainConfig->sync(); +} + +bool KSim::Config::showProcs() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readBoolEntry("ShowProcs", false); +} + +void KSim::Config::setShowProcs(bool procs) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("ShowProcs", procs); + mainConfig->sync(); +} + +QString KSim::Config::themeUrl() const +{ + return KSim::ThemeLoader::currentUrl(); +} + +QString KSim::Config::themeName() const +{ + return KSim::ThemeLoader::currentName(); +} + +void KSim::Config::setThemeName(const QString &name) +{ + mainConfig->setGroup("Theme"); + mainConfig->writeEntry("Name", name); + mainConfig->sync(); +} + +int KSim::Config::themeAlt() const +{ + return KSim::ThemeLoader::currentAlternative(); +} + +void KSim::Config::setThemeAlt(int alt) +{ + mainConfig->setGroup("Theme"); + mainConfig->writeEntry("Alternative", alt); + mainConfig->sync(); +} + +QFont KSim::Config::themeFont() const +{ + return KSim::ThemeLoader::currentFont(); +} + +void KSim::Config::setThemeFont(const QFont &font) +{ + mainConfig->setGroup("Theme"); + mainConfig->writeEntry("Font", font); + mainConfig->sync(); +} + +int KSim::Config::themeFontItem() const +{ + return KSim::ThemeLoader::currentFontItem(); +} + +void KSim::Config::setThemeFontItem(int item) +{ + mainConfig->setGroup("Theme"); + mainConfig->writeEntry("FontItem", item); + mainConfig->sync(); +} + +bool KSim::Config::reColourThemes() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readBoolEntry("ReColourTheme", false); +} + +void KSim::Config::setReColourThemes(bool value) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("ReColourTheme", value); + mainConfig->sync(); +} diff --git a/ksim/library/ksimconfig.h b/ksim/library/ksimconfig.h new file mode 100644 index 0000000..0208b18 --- /dev/null +++ b/ksim/library/ksimconfig.h @@ -0,0 +1,109 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KSIMCONFIG_H +#define KSIMCONFIG_H + +#include <qstringlist.h> +#include <qpoint.h> +#include <qfont.h> + +#include <kdemacros.h> + +class KConfig; + +namespace KSim +{ + /** + * @internal + */ + class KDE_EXPORT Config + { + public: + Config(KConfig *config); + ~Config(); + + static KConfig *config(); + + int width(int defaultWidth) const; + void setWidth(int width); + bool enabledMonitor(const QString &) const; + void setEnabledMonitor(const QString &, bool); + QString monitorCommand(const QString &) const; + void setMonitorCommand(const QString &, const QString &); + int monitorLocation(const QString &); + void setMonitorLocation(const QString &, int); + bool displayFqdn() const; + void setDisplayFqdn(bool); + bool showDock() const; + void setShowDock(bool); + bool savePos() const; + void setSavePos(bool); + bool stayOnTop() const; + void setStayOnTop(bool); + QPoint position(const QPoint &) const; + void setPosition(const QPoint &); + QSize graphSize() const; + void setGraphSize(const QSize &); + QString uptimeFormat() const; + void setUptimeFormat(const QStringList &); + int uptimeItem() const; + void setUptimeItem(int); + QStringList uptimeFormatList() const; + QString memoryFormat() const; + void setMemoryFormat(const QStringList &); + int memoryItem() const; + void setMemoryItem(int); + QStringList memoryFormatList() const; + QString swapFormat() const; + void setSwapFormat(const QStringList &); + int swapItem() const; + void setSwapItem(int); + QStringList swapFormatList() const; + bool showTime() const; + void setShowTime(bool); + bool show24hour() const; + void setShow24hour(bool); + bool showDate() const; + void setShowDate(bool); + bool showUptime() const; + void setShowUptime(bool); + bool showMemory() const; + void setShowMemory(bool); + bool showSwap() const; + void setShowSwap(bool); + bool showProcs() const; + void setShowProcs(bool); + QString themeUrl() const; + QString themeName() const; + void setThemeName(const QString &); + int themeAlt() const; + void setThemeAlt(int); + QFont themeFont() const; + void setThemeFont(const QFont &); + int themeFontItem() const; + void setThemeFontItem(int); + bool reColourThemes() const; + void setReColourThemes(bool); + + private: + static KConfig *mainConfig; + }; +} +#endif diff --git a/ksim/library/label.cpp b/ksim/library/label.cpp new file mode 100644 index 0000000..91e7621 --- /dev/null +++ b/ksim/library/label.cpp @@ -0,0 +1,301 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "label.h" +#include "label.moc" +#include <ksimconfig.h> +#include "themetypes.h" + +#include <qpainter.h> +#include <qstyle.h> +#include <qstylesheet.h> +#include <qsimplerichtext.h> +#include <qcursor.h> +#include <qpixmap.h> +#include <qimage.h> + +#include <themeloader.h> +#include <kdebug.h> +#include <kglobal.h> +#include <kglobalsettings.h> +#include <kconfig.h> + +class KSim::Label::Private +{ + public: + QColor mColour; + QColor sColour; + QRect loc; + QRect shad; + QString text; + QImage meterImage; + QPixmap background; + QPixmap sidePixmap; + bool showShadow; +}; + +KSim::Label::Label(QWidget *parent, const char *name, WFlags fl) + : QWidget(parent, name, fl) +{ + initWidget(KSim::Types::None); +} + +KSim::Label::Label(int type, QWidget *parent, const char *name, + WFlags fl) : QWidget(parent, name, fl) +{ + initWidget(type); +} + +KSim::Label::Label(int type, const QString &text, QWidget *parent, + const char *name, WFlags fl) : QWidget(parent, name, fl) +{ + initWidget(type); + setText(text); +} + +KSim::Label::~Label() +{ + delete d; +} + +const QString &KSim::Label::text() const +{ + return d->text; +} + +void KSim::Label::configureObject(bool repaintWidget) +{ + QString image = themeLoader().current().meterPixmap(type(), false); + if (image.isEmpty()) + image = themeLoader().current().panelPixmap(type()); + + d->meterImage.load(image); + KSim::ThemeLoader::self().reColourImage(d->meterImage); + d->background = d->meterImage.smoothScale(size()); + QSize oldSize = sizeHint(); + + setConfigValues(); + relayoutLabel(oldSize, repaintWidget); +} + +void KSim::Label::setPixmap(const QPixmap &pixmap) +{ + if (pixmap.serialNumber() == d->sidePixmap.serialNumber()) + return; + + QSize oldSize = sizeHint(); + d->sidePixmap = pixmap; + + relayoutLabel(oldSize); +} + +const QPixmap &KSim::Label::pixmap() const +{ + return d->sidePixmap; +} + +QSize KSim::Label::sizeHint() const +{ + int width = fontMetrics().size(SingleLine, text()).width(); + if (!pixmap().isNull()) + width += pixmap().width() + 5; + + int height = fontMetrics().height() + 4; + if (!pixmap().isNull() && pixmap().height() > height) + height = pixmap().height(); + + return QSize(width, height); +} + +QSize KSim::Label::minimumSizeHint() const +{ + return sizeHint(); +} + +void KSim::Label::clear() +{ + setText(QString::null); +} + +void KSim::Label::setText(const QString &text) +{ + if (text == d->text) + return; // If the text is the same, no need to repaint etc + + QSize oldSize = sizeHint(); + // set the text of our widget and repaint + d->text = text; + relayoutLabel(oldSize); +} + +void KSim::Label::extraTypeCall() +{ + d->meterImage.load(themeLoader().current().meterPixmap(type())); + setConfigValues(); +} + +void KSim::Label::setShowShadow(bool show) +{ + d->showShadow = show; +} + +bool KSim::Label::showShadow() const +{ + return d->showShadow; +} + +void KSim::Label::setTextColour(const QColor &color) +{ + d->mColour = color; +} + +const QColor &KSim::Label::textColour() const +{ + return d->mColour; +} + +void KSim::Label::setShadowColour(const QColor &color) +{ + d->sColour = color; +} + +const QColor &KSim::Label::shadowColour() const +{ + return d->sColour; +} + +void KSim::Label::setConfigValues() +{ + QFont newFont = font(); + bool repaint = themeLoader().current().fontColours(this, + newFont, d->mColour, d->sColour, d->showShadow); + + if (font() != newFont) + setFont(newFont); + + if (repaint) + update(); +} + +void KSim::Label::paintEvent(QPaintEvent *) +{ + QPainter painter; + painter.begin(this); + + // paint our background pixmap onto the widget + painter.drawPixmap(0, 0, d->background); + + drawPixmap(&painter, d->loc, pixmap()); + if (d->showShadow) { // draw the shadow text on the image + drawText(&painter, d->shad, d->sColour, d->text); + } + + // draw the label text onto the widget + painter.setPen(d->mColour); + drawText(&painter, d->loc, d->mColour, d->text); + painter.end(); +} + +void KSim::Label::resizeEvent(QResizeEvent *ev) +{ + // set the location of where the shadow'ed text will be drawn + d->shad.setWidth(ev->size().width() + 3); + d->shad.setHeight(ev->size().height() + 3); + + // set the location of where the text will be drawn + d->loc.setWidth(ev->size().width()); + d->loc.setHeight(ev->size().height()); + + d->background = d->meterImage.smoothScale(ev->size()); +} + +void KSim::Label::drawText(QPainter *painter, const QRect &rect, + const QColor &color, const QString &text) +{ + QRect location(rect); + if (!pixmap().isNull()) + location.setX(pixmap().width() + 5); + + style().drawItem(painter, location, AlignCenter, colorGroup(), true, + 0, text, -1, &color); +} + +void KSim::Label::drawPixmap(QPainter *painter, const QRect &rect, + const QPixmap &pixmap) +{ + QRect location(rect); + location.setWidth(pixmap.width()); + + style().drawItem(painter, location, AlignCenter, colorGroup(), true, + pixmap.isNull() ? 0 : &pixmap, QString::null); +} + +void KSim::Label::setTextLocation(const QRect &rect) +{ + d->loc = rect; +} + +const QRect &KSim::Label::textLocation() const +{ + return d->loc; +} + +void KSim::Label::setShadowLocation(const QRect &rect) +{ + d->shad = rect; +} + +const QRect &KSim::Label::shadowLocation() const +{ + return d->shad; +} + +void KSim::Label::setThemePixmap(const QString &image) +{ + QSize oldSize = sizeHint(); + d->meterImage.reset(); + d->meterImage.load(image); + KSim::ThemeLoader::self().reColourImage(d->meterImage); + d->background = d->meterImage.smoothScale(size()); + relayoutLabel(oldSize); +} + +void KSim::Label::relayoutLabel(const QSize &old, bool repaint) +{ + if (sizeHint() != old) { + updateGeometry(); + } + + if (repaint) + update(); +} + +void KSim::Label::initWidget(int type) +{ + d = new Private; + setType(type); + setConfigString("StyleMeter"); + + // try to reduce flicker as much as possible + setBackgroundMode(NoBackground); + setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, + QSizePolicy::Fixed)); + + configureObject(); +} diff --git a/ksim/library/label.h b/ksim/library/label.h new file mode 100644 index 0000000..1c750f2 --- /dev/null +++ b/ksim/library/label.h @@ -0,0 +1,210 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KSIM__LABEL_H +#define KSIM__LABEL_H + +#include <qwidget.h> +#include "common.h" + +#include <kdemacros.h> + +namespace KSim +{ + /** + * A widget that provides a text or image display + * which supports themes from gkrellm + * + * @short Label widget + * @author Robbie Ward <linuxphreak@gmx.co.uk> + */ + class KDE_EXPORT Label : public QWidget, public KSim::Base + { + Q_OBJECT + public: + /** + * Constructs a KSim::Label. + * + * @param parent is the parent widget + * + * Example usage: + * <pre> + * KSim::Label *label = new KSim::Label(this); + * </pre> + * To create a KSim::Label with the normal theme look + * @see KSim::ThemeLoader + */ + Label(QWidget *parent, const char *name = 0, WFlags fl = 0); + /** + * Constructs a KSimLabel. + * + * @param type is the theme type + * @param parent is the parent widget + * + * Example usage: + * <pre> + * KSim::Label *label = new KSim::Label(KSim::Types::None, this); + * </pre> + * To create a KSim::Label with the normal theme look, + * NOTE: this is the same as the KSim::Label(QWidget *, const char *, WFlags) ctor + * @see KSim::ThemeLoader + */ + Label(int type, QWidget *parent, const char *name = 0, WFlags fl = 0); + /** + * Constructs a KSim::Label. + * + * @param type is the theme type + * @param text is the default text to display + * @param parent is the parent widget + * + * Example usage: + * <pre> + * KSim::Label *label = new KSim:Label(KSim::Types::Host, "test label", this); + * </pre> + * To create a KSim::Label with the theme look of host + * @see KSim::ThemeLoader + */ + Label(int type, const QString &text, + QWidget *parent, const char *name = 0, WFlags fl = 0); + /** + * destructs KSim::Label. + */ + virtual ~Label(); + + /** + * returns the current text of the label + * @see #setText + */ + const QString &text() const; + /** + * recreates the labels look & feel + */ + virtual void configureObject(bool repaintWidget = true); + /** + * sets a pixmap for the label + */ + void setPixmap(const QPixmap &pixmap); + /** + * @return the side pixmap + */ + const QPixmap &pixmap() const; + /** + * reimplemented for internal reasons + */ + virtual QSize sizeHint() const; + /** + * reimplemented for internal reasons + */ + virtual QSize minimumSizeHint() const; + + public slots: + /** + * clears the current text in the label + */ + void clear(); + /** + * sets the current label of the widget to @ref text + * @see text() + */ + void setText(const QString &text); + + protected: + /** + * reimplemented for internal reasons + */ + virtual void extraTypeCall(); + /** + * set wether the shadow should be shown or not + */ + void setShowShadow(bool show); + /** + * @return true if the shadow is to be shown, else false + */ + bool showShadow() const; + /** + * Set the text color + */ + void setTextColour(const QColor &color); + /** + * @return the text color + */ + const QColor &textColour() const; + /** + * Set the shadow color + */ + void setShadowColour(const QColor &color); + /** + * @return the shadow color + */ + const QColor &shadowColour() const; + /** + * Set the config values depending on the chart type + */ + void setConfigValues(); + /** + * reimplemented for internal reasons + */ + virtual void paintEvent(QPaintEvent *); + /** + * reimplemented for internal reasons + */ + virtual void resizeEvent(QResizeEvent *); + /** + * draw the text onto the label + */ + void drawText(QPainter *painter, const QRect &rect, + const QColor &color, const QString &text); + /** + * draw the pixmap onto the label + */ + void drawPixmap(QPainter *painter, + const QRect &rect, const QPixmap &pixmap); + /** + * sets the location of the text + */ + void setTextLocation(const QRect &rect); + /** + * @return the location of the text + */ + const QRect &textLocation() const; + /** + * sets the location of the shadow text + */ + void setShadowLocation(const QRect &rect); + /** + * @return the location of the shadow text + */ + const QRect &shadowLocation() const; + /** + * sets the background image to be painted + */ + void setThemePixmap(const QString &image); + void relayoutLabel(const QSize &old, bool repaint = true); + + private: + /** + * initiates the widget + */ + void initWidget(int type); + + class Private; + Private *d; + }; +} +#endif diff --git a/ksim/library/led.cpp b/ksim/library/led.cpp new file mode 100644 index 0000000..8d0c88d --- /dev/null +++ b/ksim/library/led.cpp @@ -0,0 +1,349 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "led.h" +#include "led.moc" + +#include <qimage.h> +#include <qpainter.h> +#include <qfile.h> +#include <qbitmap.h> + +#include <kdebug.h> +#include <kpixmapsplitter.h> + +#include <themeloader.h> +#include "themetypes.h" + +class KSim::Led::Private +{ + public: + KPixmapSplitter splitter; + QPixmap pixmap; + QString imageName; + KSim::Led::Type type; + bool toggled; +}; + +KSim::Led::Led() : QPixmap() +{ + d = new Private; + + d->type = First; + d->toggled = false; + + setPixmap(KSim::ThemeLoader::self().current().ledPixmap(KSim::Types::Net)); + setOff(); +} + +KSim::Led::Led(Type type, const QString &imageName) : QPixmap() +{ + d = new Private; + + d->type = type; + d->toggled = false; + + setPixmap(imageName); + setOff(); +} + +KSim::Led::~Led() +{ + delete d; +} + +void KSim::Led::setOn(bool force) +{ + if (isOn() && !force) + return; + + // Return if our pixmap is null + QRect rect = d->splitter.coordinates(d->type == First ? 1 : 3); + if (d->pixmap.isNull() || rect.isEmpty()) { + resize(12, 8); + fill(Qt::white); + return; + } + + if (d->pixmap.mask() && !d->pixmap.mask()->isNull()) { + QBitmap mask(rect.size()); + bitBlt(&mask, QPoint(0, 0), d->pixmap.mask(), rect, CopyROP); + setMask(mask); + } + + bitBlt(this, QPoint(0, 0), &d->pixmap, rect, CopyROP); + d->toggled = true; +} + +void KSim::Led::setOff(bool force) +{ + if (!isOn() && !force) + return; + + // Return if our pixmap is null + QRect rect = d->splitter.coordinates(d->type == First ? 0 : 2); + if (d->pixmap.isNull() || rect.isEmpty()) { + resize(12, 8); + fill(Qt::white); + return; + } + + if (d->pixmap.mask() && !d->pixmap.mask()->isNull()) { + QBitmap mask(rect.size()); + bitBlt(&mask, QPoint(0, 0), d->pixmap.mask(), rect, CopyROP); + setMask(mask); + } + + bitBlt(this, QPoint(0, 0), &d->pixmap, rect, CopyROP); + d->toggled = false; +} + +void KSim::Led::toggle() +{ + if (d->toggled) + setOff(); + else + setOn(); +} + +void KSim::Led::setPixmap(const QString &imageName) +{ + if (imageName == d->imageName) + return; + + QImage image(imageName); + + if (image.width() >= 19) + image = image.smoothScale(19, image.height()); + + KSim::ThemeLoader::self().reColourImage(image); + d->pixmap.convertFromImage(image); + QSize size(image.width(), image.height() / 4); + + d->splitter.setPixmap(d->pixmap); + d->splitter.setItemSize(size); + + resize(size); + setMask(QBitmap()); +} + +const QString &KSim::Led::fileName() const +{ + return d->imageName; +} + +bool KSim::Led::isOn() const +{ + return d->toggled; +} + +void KSim::Led::setType(Type type) +{ + if (type == d->type) + return; + + d->type = type; +} + +KSim::Led::Type KSim::Led::type() const +{ + return d->type; +} + +void KSim::Led::update() +{ + if (isOn()) + setOn(true); + else + setOff(true); +} + +class KSim::LedLabel::Private +{ + public: + KSim::Led receiveLed; + KSim::Led sendLed; + QPoint sendPoint; + QPoint receivePoint; +}; + +KSim::LedLabel::LedLabel(int max, int type, const QString &label, + QWidget *parent, const char *name, WFlags fl) + : KSim::Progress(max, type, Panel, parent, name, fl) +{ + init(); + setText(label); +} + +KSim::LedLabel::LedLabel(int max, int type, + QWidget *parent, const char *name, WFlags fl) + : KSim::Progress(max, type, Panel, parent, name, fl) +{ + init(); +} + +KSim::LedLabel::LedLabel(int max, + QWidget *parent, const char *name, WFlags fl) + : KSim::Progress(max, KSim::Types::None, + Panel, parent, name, fl) +{ + init(); +} + +KSim::LedLabel::~LedLabel() +{ + delete d; +} + +void KSim::LedLabel::configureObject(bool reapaintWidget) +{ + KSim::Progress::configureObject(false); + + QPixmap pixmap = themeLoader().current().splitPixmap(KSim::Theme::KrellPanel, 0, false); + if (pixmap.isNull()) + pixmap = themeLoader().current().splitPixmap(KSim::Theme::KrellSlider); + + setMeterPixmap(pixmap); + d->receiveLed.setPixmap(themeLoader().current().ledPixmap(KSim::Types::Net)); + d->sendLed.setPixmap(themeLoader().current().ledPixmap(KSim::Types::Net)); + + // Update the leds to make sure they get painted correctly + d->receiveLed.update(); + d->sendLed.update(); + + setConfigValues(); + layoutLeds(); + + if (reapaintWidget) + update(); +} + +QSize KSim::LedLabel::sizeHint() const +{ + QSize hint(Progress::sizeHint()); + + if (d->sendLed.height() > hint.height()) + hint.setHeight(d->sendLed.height()); + + return hint; +} + +void KSim::LedLabel::reset() +{ + KSim::Progress::reset(); + setOff(Led::First); + setOff(Led::Second); +} + +void KSim::LedLabel::setOn(Led::Type type) +{ + if (type == Led::First) { + if (d->receiveLed.isOn()) + return; + + d->receiveLed.setOn(); + } + else { + if (d->sendLed.isOn()) + return; + + d->sendLed.setOn(); + } + + update(); +} + +void KSim::LedLabel::setOff(Led::Type type) +{ + if (type == Led::First) { + if (!d->receiveLed.isOn()) + return; + + d->receiveLed.setOff(); + } + else { + if (!d->sendLed.isOn()) + return; + + d->sendLed.setOff(); + } + + update(); +} + +void KSim::LedLabel::toggle(Led::Type type) +{ + if (type == Led::First) + d->receiveLed.toggle(); + else + d->sendLed.toggle(); + + update(); +} + +void KSim::LedLabel::drawLeds() +{ + bitBlt(this, d->sendPoint, &d->sendLed); + bitBlt(this, d->receivePoint, &d->receiveLed); +} + +void KSim::LedLabel::paintEvent(QPaintEvent *ev) +{ + KSim::Label::paintEvent(ev); + drawLeds(); + KSim::Progress::drawMeter(); +} + +void KSim::LedLabel::resizeEvent(QResizeEvent *ev) +{ + KSim::Progress::resizeEvent(ev); + layoutLeds(); +} + +void KSim::LedLabel::layoutLeds() +{ + int ledHeight = height() / 2; + + // get the location of the sendLed + d->sendPoint.setX((width() - d->sendLed.width()) - 2); + d->sendPoint.setY(ledHeight - (d->sendLed.height() / 2)); + + // get the location of the receiveLed + d->receivePoint.setX((d->sendPoint.x() - d->receiveLed.width()) - 3); + d->receivePoint.setY(ledHeight - (d->receiveLed.height() / 2)); + + QRect location = textLocation(); + location.setWidth(d->receivePoint.x()); + setTextLocation(location); + + QRect shadow = shadowLocation(); + shadow.setWidth(d->receivePoint.x() + 3); + setShadowLocation(shadow); + + setOrigin(rect()); +} + +void KSim::LedLabel::init() +{ + d = new Private; + d->receiveLed.setType(KSim::Led::First); + d->sendLed.setType(KSim::Led::Second); + setConfigString("StylePanel"); + configureObject(); +} diff --git a/ksim/library/led.h b/ksim/library/led.h new file mode 100644 index 0000000..2e5d084 --- /dev/null +++ b/ksim/library/led.h @@ -0,0 +1,193 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KSIM__LED_H +#define KSIM__LED_H + +#include "progress.h" +#include <kdemacros.h> +#include <qpixmap.h> + +namespace KSim +{ + /** + * A custom led for use with KSim::LedLabel, + * usually you shouldn't need to use this class, use KSim::LedLabel instead + * @see KSim::LedLabel + * + * @short led using gkrellm themes + * @author Robbie Ward <linuxphreak@gmx.co.uk> + */ + class KDE_EXPORT Led : public QPixmap + { + public: + enum Type { First = 0, Second }; + Led(); + /** + * Constructs a KSim::Led. + * + * @param type is the led type + * @param ImageName is the image to display + * the image's height is divided by 4 and each item is used for send in, + * send out, receive in and receive out + * @param parent is the parent widget + * @param name is the object instance name + */ + Led(Type type, const QString &imageName); + /** + * destructor for KSim::Led. + */ + virtual ~Led(); + + /** + * sets the led on + */ + void setOn(bool force = false); + /** + * sets the led off + */ + void setOff(bool force = false); + /** + * toggles the current state of the led + */ + void toggle(); + /** + * sets the image of the led + */ + void setPixmap(const QString &); + /** + * @return the location of the filename + */ + const QString &fileName() const; + /** + * @return true if the led is on + */ + bool isOn() const; + /** + * sets the type of led, send or receive + */ + void setType(Type type); + /** + * @return the type of the led + */ + Type type() const; + /** + * Force the Led to repaint its state + */ + void update(); + + private: + class Private; + Private *d; + }; + + /** + * A custom widget that inheriits KSim::Progress. + * this wiget provides two KSim::Led's and a label + * + * @short Label widget with 2 leds + * @author Robbie Ward <linuxphreak@gmx.co.uk> + */ + class KDE_EXPORT LedLabel : public KSim::Progress + { + Q_OBJECT + public: + /** + * Constructs a KSim::LedLabel. + * + * @param type is the theme type + * @param label is the default text to display + * @param parent is the parent widget + * @see KSim::ThemeLoader + */ + LedLabel(int max, int type, const QString &label, + QWidget *parent, const char *name = 0, WFlags fl = 0); + /** + * Constructs a KSim::LedLabel. + * + * @param type is the theme type + * @param label is the default text to display + * @param parent is the parent widget + * @see KSim::ThemeLoader + */ + LedLabel(int max, int type, QWidget *parent, + const char *name = 0, WFlags fl = 0); + /** + * Constructs a KSim::LedLabel. + * + * @param label is the default text to display + * @param parent is the parent widget + * @see KSim::ThemeLoader + */ + LedLabel(int max, QWidget *parent, + const char *name = 0, WFlags fl = 0); + /** + * destructor for KSim::LedLabel. + */ + virtual ~LedLabel(); + + /** + * reimplemented for internal reasons + */ + virtual void configureObject(bool reapaintWidget = true); + /** + * reimplemented for internal reasons + */ + virtual QSize sizeHint() const; + + public slots: + /** + * reimplemented for internal reasons + */ + virtual void reset(); + /** + * sets @ref ledType on + */ + void setOn(Led::Type type); + /** + * sets @ref ledType off + */ + void setOff(Led::Type type); + /** + * toggles the state of @ref ledType + * if the led is on then it will be set off, + * if the led is off it will be set on. + */ + void toggle(Led::Type type); + + protected: + void drawLeds(); + /** + * reimplemented for internal reasons + */ + virtual void paintEvent(QPaintEvent *); + /** + * reimplemented for internal reasons + */ + virtual void resizeEvent(QResizeEvent *); + + private: + void layoutLeds(); + void init(); + + class Private; + Private *d; + }; +} +#endif // KSIMLED_H diff --git a/ksim/library/pluginglobal.cpp b/ksim/library/pluginglobal.cpp new file mode 100644 index 0000000..02b32ad --- /dev/null +++ b/ksim/library/pluginglobal.cpp @@ -0,0 +1,207 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "pluginglobal.h" +#include "pluginmodule.h" + +#include <kdebug.h> +#include <kdesktopfile.h> +#include <klocale.h> +#include <kiconloader.h> + +class KSim::Plugin::Private +{ + public: + Private() : plugin(0), + view(0), page(0) + { + oldState = true; + enabled = true; + // Set the ref-count to 1 + count = 1; + } + + ~Private() + { + kdDebug(2003) << "Deleting " << (plugin ? + plugin->name() : QString("Null")) + << " objects." << endl; + + // Remember to delete the objects we own + delete plugin; + delete view; + delete page; + + plugin = 0; + view = 0; + page = 0; + } + + void ref() { ++count; } + bool deref() { return !--count; } + + uint count; + QString name; + QPixmap icon; + QCString libName; + QString filename; + KSim::PluginObject *plugin; + KSim::PluginView *view; + KSim::PluginPage *page; + bool oldState; + bool enabled; +}; + +KSim::Plugin KSim::Plugin::null; + +// Null Plugin +KSim::Plugin::Plugin() : d(0) +{ +} + +KSim::Plugin::Plugin(KSim::PluginObject *plugin, const KDesktopFile &file) +{ + init(plugin, file); + + if (d) { + d->view = d->plugin ? d->plugin->createView(d->libName) : 0; + d->page = d->plugin ? d->plugin->createConfigPage(d->libName) : 0; + } +} + +KSim::Plugin::Plugin(const KSim::Plugin &rhs) +{ + d = rhs.d; + if (d) + d->ref(); +} + +KSim::Plugin::~Plugin() +{ + if (d && d->deref()) + delete d; +} + +KSim::Plugin &KSim::Plugin::operator=(const KSim::Plugin &rhs) +{ + if (*this == rhs) + return *this; + + if (rhs.d) { + rhs.d->ref(); + if (d && d->deref()) + delete d; + + d = rhs.d; + return *this; + } + + // rhs is a null plugin so we just go ahead + // and make this a null plugin too. + if (d && d->deref()) + delete d; + + d = 0; + return *this; +} + +bool KSim::Plugin::operator==(const KSim::Plugin &rhs) const +{ + return d == rhs.d; +} + +bool KSim::Plugin::operator!=(const KSim::Plugin &rhs) const +{ + return !(operator==(rhs)); +} + +void KSim::Plugin::setEnabled(bool enabled) +{ + if (!d) + return; + + d->oldState = d->enabled; + d->enabled = enabled; +} + +bool KSim::Plugin::isEnabled() const +{ + return (d ? d->enabled : false); +} + +bool KSim::Plugin::isDifferent() const +{ + return d ? d->enabled != d->oldState : false; +} + +bool KSim::Plugin::isNull() const +{ + return !d; +} + +const QString &KSim::Plugin::name() const +{ + return d ? d->name : QString::null; +} + +QPixmap KSim::Plugin::icon() const +{ + return d ? d->icon : QPixmap(); +} + +QCString KSim::Plugin::libName() const +{ + return d ? d->libName : QCString(); +} + +const QString &KSim::Plugin::fileName() const +{ + return d ? d->filename : QString::null; +} + +KSim::PluginObject *KSim::Plugin::plugin() const +{ + return d ? d->plugin : 0; +} + +KSim::PluginView *KSim::Plugin::view() const +{ + return d ? d->view : 0; +} + +KSim::PluginPage *KSim::Plugin::configPage() const +{ + return d ? d->page : 0; +} + +void KSim::Plugin::init(KSim::PluginObject *plugin, const KDesktopFile &file) +{ + if (!plugin || file.fileName().isEmpty()) { + d = 0; + return; + } + + d = new Private; + + d->libName = "ksim_" + file.readEntry("X-KSIM-LIBRARY").local8Bit(); + d->name = file.readName(); + d->icon = SmallIcon(file.readIcon()); + d->filename = file.fileName(); + d->plugin = plugin; +} diff --git a/ksim/library/pluginglobal.h b/ksim/library/pluginglobal.h new file mode 100644 index 0000000..85df9ce --- /dev/null +++ b/ksim/library/pluginglobal.h @@ -0,0 +1,161 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef PLUGINGLOBAL_H +#define PLUGINGLOBAL_H + +#include <qstring.h> +#include <qpixmap.h> +#include <qvaluelist.h> + +#include <kdemacros.h> + +class KDesktopFile; + +namespace KSim +{ + class PluginObject; + class PluginView; + class PluginPage; + + /** + * A class that holds various information about a plugin + * @author Robbie Ward <linuxphreak@gmx.co.uk> + */ + class KDE_EXPORT Plugin + { + public: + /** + * Constructs a null Plugin + */ + Plugin(); + /** + * Constructs a Plugin + */ + Plugin(KSim::PluginObject *plugin, const KDesktopFile &file); + /** + * Copy constructor + */ + Plugin(const Plugin &rhs); + /** + * Destructor for Plugin + */ + ~Plugin(); + + /** + * Assigns rhs to this Plugin and returns a reference to this Plugin. + */ + Plugin &operator=(const Plugin &rhs); + /** + * @return true if the plugin is equal to rhs; otherwise returns false + * @see #operator!= + */ + bool operator==(const Plugin &rhs) const; + /** + * @return true if the plugin is different to rhs; otherwise returns false + * @see #operator== + */ + bool operator!=(const Plugin &rhs) const; + /** + * sets if the plugin is enabled or not + */ + void setEnabled(bool enabled); + /** + * returns true if this plugin is enabled, else it returns false + */ + bool isEnabled() const; + /** + * returns true if the last enabled state is different to the current + * enabled state, else it returns false + */ + bool isDifferent() const; + /** + * @return true if the Plugin object is empty + */ + bool isNull() const; + /** + * @return the name of the plugin, NOT the library name + * @see #libName + */ + const QString &name() const; + /** + * @return the icon of the plugin + */ + QPixmap icon() const; + /** + * @return library name of the plugin + */ + QCString libName() const; + /** + * @return path to the .desktop file + */ + const QString &fileName() const; + /** + * @return the plugin object + */ + KSim::PluginObject *plugin() const; + /** + * @return the view object of the plugin + */ + KSim::PluginView *view() const; + /** + * @return the config object of the plugin + */ + KSim::PluginPage *configPage() const; + /** + * a null plugin, provided for convenience. + * currently only used in KSim::PluginLoader + */ + static KSim::Plugin null; + private: + void init(KSim::PluginObject *plugin, const KDesktopFile &file); + + class Private; + Private *d; + }; + + /** + * Please do not use this class directly, + * use pluginList() from KSim::PluginLoader instead + * @author Robbie Ward <linuxphreak@gmx.co.uk> + */ + class KDE_EXPORT PluginList : public QValueList<Plugin> + { + public: + /** + * constructs a null list + */ + PluginList() : QValueList<Plugin>() {} + /** + * constructs a copy of @p list + */ + PluginList(const PluginList &list) : QValueList<Plugin>(list) {} + /** + * constructs a copy of @p list + */ + PluginList(const QValueList<Plugin> &list) + : QValueList<Plugin>(list) {} + /** + * constructs a list with just one item + */ + PluginList(const Plugin &plugin) { append(plugin); } + ~PluginList() {} + }; +} +#endif diff --git a/ksim/library/pluginloader.cpp b/ksim/library/pluginloader.cpp new file mode 100644 index 0000000..be2d2bf --- /dev/null +++ b/ksim/library/pluginloader.cpp @@ -0,0 +1,326 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "pluginloader.h" +#include "pluginloader.moc" + +#include <kdebug.h> +#include <klibloader.h> +#include <kdesktopfile.h> +#include <klocale.h> +#include <kglobal.h> +#include <kstandarddirs.h> +#include <kmessagebox.h> + +#include <qstringlist.h> + +class KSim::PluginInfo::Private +{ + public: +}; + +KSim::PluginInfo::~PluginInfo() +{ +} + +const QString &KSim::PluginInfo::name() const +{ + return m_name; +} + +QCString KSim::PluginInfo::libName(bool includePrefix) const +{ + return (includePrefix ? "ksim_" + m_libName : m_libName); +} + +const QString &KSim::PluginInfo::location() const +{ + return m_location; +} + +KSim::PluginInfo::PluginInfo() +{ +} + +class KSim::PluginLoader::Private +{ + public: + typedef KSim::PluginObject *(PluginPtr)(const char *); + KSim::PluginList pluginList; + QString error; + QString lib; + bool lastLoaded; + static const char *const ksimString; +}; + +const char *const KSim::PluginLoader::Private::ksimString = "ksim_"; + +KSim::PluginLoader *KSim::PluginLoader::m_instance = 0; // initialize pointer +KSim::PluginLoader &KSim::PluginLoader::self() +{ + if (!m_instance) // is it the first call? + m_instance = new PluginLoader; // create sole instance + + return *m_instance; // address of sole instance +} + +KSim::PluginLoader::~PluginLoader() +{ + unloadAllPlugins(); + delete d; +} + +bool KSim::PluginLoader::loadPlugin(const KDesktopFile &file) +{ + switch (createPlugin(file)) { + case KSim::PluginLoader::EmptyLibName: + KMessageBox::error(0, i18n("KSim was unable to load the plugin %1" + " due to the X-KSIM-LIBRARY property being empty in the" + " plugins desktop file").arg(file.readName())); + return false; + break; + case KSim::PluginLoader::LibNotFound: + KMessageBox::error(0, i18n("KSim was unable to load the plugin %1" + " due to not being able to find the plugin, check that the plugin" + " is installed and is in your $KDEDIR/lib path").arg(file.readName())); + return false; + break; + case KSim::PluginLoader::UnSymbols: + KMessageBox::error(0, i18n("<qt>An error occurred while trying \n" + "to load the plugin '%1'. \nThis could be caused by the" + " following:<ul>\n<li>The plugin doesn't have the %2" + " macro</li>\n<li>The plugin has been damaged or has" + " some unresolved symbols</li>\n</ul> \nLast" + " error message that occurred: \n%3</qt>") + .arg(d->lib.prepend("ksim_")).arg("KSIM_INIT_PLUGIN") + .arg(d->error)); + return false; + break; + default: + break; + } + + return true; +} + +bool KSim::PluginLoader::unloadPlugin(const QCString &name) +{ + if (name.isEmpty()) + return false; + + // see if our plugin is loaded + KSim::Plugin plugin = find(name); + if (plugin.isNull()) + return false; + + // try to unload the library + kdDebug(2003) << "Unloading plugin " << plugin.libName() << endl; + KLibLoader::self()->unloadLibrary(plugin.libName()); + d->pluginList.remove(plugin); + return true; +} + +void KSim::PluginLoader::unloadAllPlugins() +{ + kdDebug(2003) << "Unloading all plugins" << endl; + + // Go through the plugin list and unload each plugin; + KSim::PluginList::ConstIterator it; + for (it = d->pluginList.begin(); it != d->pluginList.end(); ++it) { + KLibLoader::self()->unloadLibrary((*it).libName()); + } + + // Clear the plugin list; + d->pluginList.clear(); + KLibLoader::cleanUp(); +} + +bool KSim::PluginLoader::isLoaded(const KSim::Plugin &info) const +{ + return isLoaded(info.libName()); +} + +bool KSim::PluginLoader::isLoaded(const QCString &library) const +{ + if (library.isEmpty()) + return false; + + return !find(library).isNull(); +} + +KSim::PluginInfo KSim::PluginLoader::findPluginInfo(const QString &name, + SearchType type) const +{ + QString location; + + switch (type) { + case Name: { + QStringList files = KGlobal::dirs()->findAllResources("data", "ksim/monitors/*.desktop"); + QStringList::ConstIterator it; + for (it = files.begin(); it != files.end(); ++it) { + KDesktopFile file((*it)); + if (file.readName() == name) { + location = (*it); + break; + } + } + break; + } + case LibName: { + QStringList files = KGlobal::dirs()->findAllResources("data", "ksim/monitors/*.desktop"); + QStringList::ConstIterator it; + for (it = files.begin(); it != files.end(); ++it) { + KDesktopFile file((*it)); + if (file.readEntry("X-KSIM-LIBRARY") == name) { + location = (*it); + break; + } + } + break; + } + case DesktopFile: { + if (!KDesktopFile::isDesktopFile(name)) + return KSim::PluginInfo(); + + location = name; + break; + } + } + + KDesktopFile file(location); + KSim::PluginInfo info; + info.m_name = file.readName(); + info.m_libName = file.readEntry("X-KSIM-LIBRARY").local8Bit(); + info.m_location = location; + return info; +} + +KSim::Plugin &KSim::PluginLoader::find(const QCString &libName) +{ + if (libName.isEmpty()) + return KSim::Plugin::null; + + QCString library(libName); + if (libName.find(Private::ksimString) == -1) + library.prepend(Private::ksimString); + + KSim::PluginList::Iterator it; + for (it = d->pluginList.begin(); it != d->pluginList.end(); ++it) { + if ((*it).libName() == library) + return (*it); + } + + return KSim::Plugin::null; +} + +const KSim::Plugin &KSim::PluginLoader::find(const QCString &libName) const +{ + if (libName.isEmpty()) + return KSim::Plugin::null; + + QCString library(libName); + if (libName.find(Private::ksimString) == -1) + library.prepend(Private::ksimString); + + KSim::PluginList::ConstIterator it; + for (it = d->pluginList.begin(); it != d->pluginList.end(); ++it) { + if ((*it).libName() == library) + return (*it); + } + + return KSim::Plugin::null; +} + +KSim::Plugin &KSim::PluginLoader::find(const KSim::PluginInfo &info) +{ + return find(info.libName()); +} + +const KSim::Plugin &KSim::PluginLoader::find(const KSim::PluginInfo &info) const +{ + return find(info.libName()); +} + +const KSim::PluginList &KSim::PluginLoader::pluginList() const +{ + return d->pluginList; +} + +KSim::PluginList &KSim::PluginLoader::pluginList() +{ + return d->pluginList; +} + +const KSim::Plugin &KSim::PluginLoader::plugin() const +{ + return (d->lastLoaded ? d->pluginList.last() : KSim::Plugin::null); +} + +KSim::Plugin &KSim::PluginLoader::plugin() +{ + return (d->lastLoaded ? d->pluginList.last() : KSim::Plugin::null); +} + +KSim::PluginLoader::PluginLoader() : QObject(0, "PluginLoader") +{ + d = new KSim::PluginLoader::Private; + d->lastLoaded = false; +} + +void KSim::PluginLoader::cleanup() +{ + if (!m_instance) + return; + + delete m_instance; + m_instance = 0; +} + +KSim::PluginLoader::ErrorCode KSim::PluginLoader::createPlugin(const KDesktopFile &file) +{ + d->error = QString::null; + QCString pluginName(file.readEntry("X-KSIM-LIBRARY").local8Bit()); + if (pluginName.isEmpty()) + return EmptyLibName; + + QCString libName(Private::ksimString + pluginName); + KLibrary *library = KLibLoader::self()->library(libName); + if (!library) + return LibNotFound; + + QCString symbol("init_plugin"); + if (Private::PluginPtr *create = (Private::PluginPtr *)(library->symbol(symbol))) { + d->pluginList.append(KSim::Plugin(create(pluginName), file)); + d->lib = QString::null; + d->lastLoaded = true; + } + else { + d->error = KLibLoader::self()->lastErrorMessage().isEmpty() ? + i18n("Unable to get last error message") : + KLibLoader::self()->lastErrorMessage(); + + KLibLoader::self()->unloadLibrary(libName); + d->lib = pluginName; + d->lastLoaded = false; + return UnSymbols; + } + + emit pluginLoaded(d->pluginList.last()); + return LibLoaded; +} diff --git a/ksim/library/pluginloader.h b/ksim/library/pluginloader.h new file mode 100644 index 0000000..f101973 --- /dev/null +++ b/ksim/library/pluginloader.h @@ -0,0 +1,183 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef PLUGINLOADER_H +#define PLUGINLOADER_H + +#include "pluginglobal.h" +#include <qobject.h> + +#include <kdemacros.h> + +namespace KSim +{ + class KDE_EXPORT PluginInfo + { + friend class PluginLoader; + public: + ~PluginInfo(); + + /** + * @return the name of the plugin + */ + const QString &name() const; + /** + * @return the library name of the plugin + */ + QCString libName(bool includePrefix = false) const; + /** + * @return the location of the desktop file + */ + const QString &location() const; + + private: + PluginInfo(); + + QString m_name; + QString m_location; + QCString m_libName; + + class Private; + Private *d; + }; + + /** + * Provides a loader for the plugins + * @author Robbie Ward <linuxphreak@gmx.co.uk> + */ + class KDE_EXPORT PluginLoader : public QObject + { + Q_OBJECT + friend class MainView; + public: + enum SearchType { Name = 0, DesktopFile, LibName }; + enum ErrorCode { EmptyLibName = -3, LibNotFound = -2, + UnSymbols = -1, LibLoaded = 0 }; + + /** + * @return a reference to the instance + */ + static PluginLoader &self(); + /** + * loads a plugin, example: + * <pre> + * KDesktopFile deskfile("/home/user/foo.desktop"); + * KSim::PluginLoader::self().loadPlugin(deskFile); + * </pre> + * you can then use @ref pluginList() to access the plugin, view, + * config page and plugin information + * @param file is the desktop file of the lib + * @return true if the plugin is successfully loaded + */ + bool loadPlugin(const KDesktopFile &file); + /** + * unloads a loaded plugin and removes plugin entries from pluginList() + */ + bool unloadPlugin(const QCString &name); + /** + * unloads all loaded plugins + */ + void unloadAllPlugins(); + /** + * convenience function + * + * returns true if info is loaded + */ + bool isLoaded(const KSim::Plugin &info) const; + /** + * returns true if library is loaded + */ + bool isLoaded(const QCString &library) const; + /** + * finds the plugins desktopfile and returns information + * on the plugin + * @return a KSim::PluginInfo object + * @see KSim::PluginInfo + */ + KSim::PluginInfo findPluginInfo(const QString &name, + SearchType type = DesktopFile) const; + /** + * looks through the list of loaded plugins and returns + * the one that matches libName, or returns + * KSim::Plugin::null if a plugin could not be found. + * + * if libName does not start with "ksim_" then the function + * will prepend this automatically. + * @return a KSim::Plugin object + * @see KSim::Plugin + */ + KSim::Plugin &find(const QCString &libName); + /** + * convenience function, see the above function for details. + */ + const KSim::Plugin &find(const QCString &libName) const; + /** + * equivalent to find(info.libName()); + */ + KSim::Plugin &find(const KSim::PluginInfo &info); + /** + * convenience function, see the above function for details. + */ + const KSim::Plugin &find(const KSim::PluginInfo &info) const; + /** + * provides plugin(), view(), config page and plugin information + * @see KSim::Plugin KSim::PluginList + */ + const KSim::PluginList &pluginList() const; + /** + * Overloaded member function, This behaves essentially like + * the above function + */ + KSim::PluginList &pluginList(); + /** + * @return a reference to the last plugin loaded (or a null plugin + * if the plugin was unable to load) + */ + const KSim::Plugin &plugin() const; + /** + * Overloaded member function, This behaves essentially like + * the above function + */ + KSim::Plugin &plugin(); + + signals: + void pluginLoaded(const KSim::Plugin &); + + protected: + /** + * constructor for PluginLoader, use self() to get an instance + */ + PluginLoader(); + ~PluginLoader(); + + private: + PluginLoader(const PluginLoader &); + PluginLoader &operator=(const PluginLoader &); + /** + * Deletes the instance and cleans up after itself + */ + static void cleanup(); + ErrorCode createPlugin(const KDesktopFile &file); + + class Private; + Private *d; + static PluginLoader *m_instance; + }; +} +#endif diff --git a/ksim/library/pluginmodule.cpp b/ksim/library/pluginmodule.cpp new file mode 100644 index 0000000..f267197 --- /dev/null +++ b/ksim/library/pluginmodule.cpp @@ -0,0 +1,174 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "pluginmodule.h" +#include "pluginmodule.moc" + +#include <klocale.h> +#include <kapplication.h> +#include <kaboutdata.h> +#include <kdebug.h> +#include <qregexp.h> +#include <qpopupmenu.h> +#include <kconfig.h> + + +class KSim::PluginObject::Private +{ + public: + QCString name; + QString configName; +}; + +KSim::PluginObject::PluginObject(const QCString &name) +{ + d = new PluginObject::Private; + d->name = name; + d->configName = "ksim_" + name; +} + +KSim::PluginObject::~PluginObject() +{ + delete d; +} + +const char *KSim::PluginObject::instanceName() const +{ + return kapp->aboutData()->appName(); +} + +const QCString &KSim::PluginObject::name() const +{ + return d->name; +} + +void KSim::PluginObject::setConfigFileName(const QString &name) +{ + if (d->configName == name) + return; + + d->configName = name; + if (name.find("ksim") == -1) + d->configName.prepend("ksim_"); +} + +const QString &KSim::PluginObject::configFileName() const +{ + return d->configName; +} + +class KSim::PluginPage::Private +{ + public: + KConfig *config; + KSim::PluginObject *parent; +}; + +KSim::PluginPage::PluginPage(KSim::PluginObject *parent, const char *name) + : QWidget(0, name) +{ + d = new PluginPage::Private; + d->parent = parent; + if (parent && !parent->configFileName().isEmpty()) + d->config = new KConfig(parent->configFileName() + "rc"); + else { + kdWarning() << className() << ": Can not create the config() " + "pointer due to the parent being null" << endl; + d->config = 0; + } +} + +KSim::PluginPage::~PluginPage() +{ + delete d->config; + delete d; +} + +KConfig *KSim::PluginPage::config() const +{ + if (d) + return d->config; + else + return 0; +} + +class KSim::PluginView::Private +{ + public: + PluginObject *parent; + QPopupMenu *popupMenu; + KConfig *config; +}; + +KSim::PluginView::PluginView(KSim::PluginObject *parent, const char *name) + : QWidget(0, name) +{ + d = new PluginView::Private; + d->parent = parent; + d->popupMenu = new QPopupMenu(this); + d->popupMenu->insertItem(i18n("About"), this, + SLOT(showAbout()), 0, -1, 0); + + if (parent && !parent->configFileName().isEmpty()) + d->config = new KConfig(parent->configFileName() + "rc"); + else { + kdWarning() << className() << ": Can not create the config() " + "pointer due to the parent being null" << endl; + d->config = 0; + } +} + +KSim::PluginView::~PluginView() +{ + delete d->popupMenu; + delete d->config; + delete d; + d = 0; +} + +KConfig *KSim::PluginView::config() const +{ + return d->config; +} + +QPopupMenu *KSim::PluginView::menu() const +{ + return d->popupMenu; +} + +void KSim::PluginView::doCommand() +{ + emit runCommand(name()); +} + +void KSim::PluginView::mousePressEvent(QMouseEvent *ev) +{ + if (ev->button() == QMouseEvent::LeftButton) + doCommand(); +} + +KSim::PluginObject *KSim::PluginView::parentPlugin() const +{ + return d->parent; +} + +void KSim::PluginView::showAbout() +{ + parentPlugin()->showAbout(); +} diff --git a/ksim/library/pluginmodule.h b/ksim/library/pluginmodule.h new file mode 100644 index 0000000..1cc6a1c --- /dev/null +++ b/ksim/library/pluginmodule.h @@ -0,0 +1,205 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef PLUGINMODULE_H +#define PLUGINMODULE_H + +#include <qwidget.h> + +#include <kdemacros.h> + +class QPopupMenu; +class KConfig; + +#define KSIM_INIT_PLUGIN(className) \ +extern "C" { \ + KDE_EXPORT KSim::PluginObject *init_plugin(const char *name) { \ + return new className(name); \ + } \ +} + +namespace KSim +{ + class PluginView; + class PluginPage; + + /** + * The base class for ksim modules. + * + * To init a plugin so KSim can load your plugin just do: + * <pre> + * // MyPluginModule is the class that inherits KSim::PluginObject + * KSIM_INIT_PLUGIN(MyPluginModule); + * </pre> + * @see KSim::PluginView KSim::PluginPage + * @author Robbie Ward <linuxphreak@gmx.co.uk> + */ + class KDE_EXPORT PluginObject + { + public: + /** + * constructor for PluginObject + */ + PluginObject(const QCString &name); + /** + * destructor for PluginObject + */ + virtual ~PluginObject(); + + /** + * creates a new View page, re-implement this + * to return your main view class + */ + virtual KSim::PluginView *createView(const char *) = 0; + /** + * creates a new Config page, re-implement this + * to return you config class + */ + virtual KSim::PluginPage *createConfigPage(const char *) = 0; + /** + * re-implement this to show your about dialog + */ + virtual void showAbout() = 0; + /** + * @return the instance name of the app + */ + const char *instanceName() const; + /** + * @return the name of the plugin + */ + const QCString &name() const; + /** + * sets the configuration file name to @p name + */ + void setConfigFileName(const QString &name); + /** + * @return the config filename the plugin should use + * or name() if the filename hasn't been set + */ + const QString &configFileName() const; + + private: + PluginObject(); + PluginObject(const PluginObject &); + PluginObject &operator=(const PluginObject &); + + class Private; + Private *d; + }; + + /** + * Provides you with a config page + * + * re-implement readConfig() and saveConfig() for your + * classes reading and saving functions and use + * the config() to gain access to your config file + * @author Robbie Ward <linuxphreak@gmx.co.uk> + */ + class KDE_EXPORT PluginPage : public QWidget + { + Q_OBJECT + public: + /** + * constructor for PluginPage + */ + PluginPage(KSim::PluginObject *parent, const char *name); + /** + * destructor for PluginPage + */ + virtual ~PluginPage(); + + /** + * called when apply or ok button is clicked in KSimPref + * use this to save your plugin options + */ + virtual void saveConfig() = 0; + /** + * called when apply or ok button is clicked in KSimPref + * use this to read your plugin options + */ + virtual void readConfig() = 0; + /* + * use this to get a config object unique to the plugin name, + * eg: the plugin foo would have the config file foorc + */ + KConfig *config() const; + + signals: + void pageChanged(); + + protected: + PluginObject *parentPlugin() const; + + private: + class Private; + Private *d; + }; + + /** + * inherit from this class to get your base view + * + * use config() to get an instance of your config file, + * reimplement reparseConfig() to recreate your view + * when apply or ok gets clicked in the config dialog + * @author Robbie Ward <linuxphreak@gmx.co.uk> + */ + class KDE_EXPORT PluginView : public QWidget + { + Q_OBJECT + public: + /** + * constructor for PluginView + */ + PluginView(KSim::PluginObject *parent, const char *name); + /** + * destructor for PluginView + */ + virtual ~PluginView(); + + /* + * use this to get a config object unique to the plugin name, + * eg: the plugin foo would have the config file foorc + */ + KConfig *config() const; + /** + * the plugins popup menu + */ + QPopupMenu *menu() const; + /** + * reimplement to recreate your view when KSim requests this + */ + virtual void reparseConfig() = 0; + void doCommand(); + + signals: + void runCommand(const QCString &); + + protected: + virtual void mousePressEvent(QMouseEvent *); + PluginObject *parentPlugin() const; + + private slots: + void showAbout(); + + private: + class Private; + Private *d; + }; +} +#endif diff --git a/ksim/library/progress.cpp b/ksim/library/progress.cpp new file mode 100644 index 0000000..fd923d2 --- /dev/null +++ b/ksim/library/progress.cpp @@ -0,0 +1,231 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "progress.h" +#include "progress.moc" + +#include <kdebug.h> +#include <qpainter.h> +#include <qpixmap.h> +#include <qimage.h> + +#include <themeloader.h> + +class KSim::Progress::Private +{ + public: + QPixmap meterPixmap; + QRect rectOrigin; + ProgressType type; + int krellDepth; + int value; + int minValue; + int maxValue; +}; + +KSim::Progress::Progress(int maxValue, + QWidget *parent, const char *name, + WFlags fl) : KSim::Label(parent, name, fl) +{ + init(maxValue); + configureObject(); +} + +KSim::Progress::Progress(int maxValue, + int type, const QString &label, QWidget *parent, + const char *name, WFlags fl) + : KSim::Label(type, label, parent, name, fl) +{ + init(maxValue); + configureObject(); +} + +KSim::Progress::Progress(int maxValue, + int type, const QString &label, int value, + QWidget *parent, const char *name, WFlags fl) + : KSim::Label(type, label, parent, name, fl) +{ + init(maxValue, value); + configureObject(); +} + +KSim::Progress::Progress(int maxValue, + int type, QWidget *parent, + const char *name, WFlags fl) + : KSim::Label(type, parent, name, fl) +{ + init(maxValue); + configureObject(); +} + +KSim::Progress::Progress(int maxValue, int type, + ProgressType progressType, + QWidget *parent, const char *name, WFlags fl) + : KSim::Label(type, parent, name, fl) +{ + init(maxValue, 0, progressType); + configureObject(); +} + +KSim::Progress::~Progress() +{ + delete d; +} + +int KSim::Progress::value() const +{ + return d->value; +} + +int KSim::Progress::minValue() const +{ + return d->minValue; +} + +int KSim::Progress::maxValue() const +{ + return d->maxValue; +} + +const QRect &KSim::Progress::rectOrigin() const +{ + return d->rectOrigin; +} + +void KSim::Progress::configureObject(bool repaintWidget) +{ + KSim::Label::configureObject(false); + + if (d->type == Panel) { + setMeterPixmap(themeLoader().current().splitPixmap(KSim::Theme::KrellPanel)); + setThemePixmap(themeLoader().current().panelPixmap(type())); + } + else { + setMeterPixmap(themeLoader().current().splitPixmap(KSim::Theme::KrellMeter)); + } + + if (repaintWidget) + update(); +} + +QSize KSim::Progress::sizeHint() const +{ + QSize hint(Label::sizeHint()); + + if (d->meterPixmap.height() > hint.height()) + hint.setHeight(d->meterPixmap.height()); + + return hint; +} + +void KSim::Progress::reset() +{ + KSim::Label::clear(); + setMinValue(0); + setMaxValue(0); + setValue(0); +} + +void KSim::Progress::setValue(int value) +{ + if (value == d->value) + return; + + d->value = value; + if (value < minValue()) + d->value = minValue(); + + if (value > maxValue()) + d->value = maxValue(); + + update(); +} + +void KSim::Progress::setMinValue(int minValue) +{ + if (d->minValue == minValue) + return; + + if (!(minValue > maxValue())) { + d->minValue = minValue; + update(); + } +} + +void KSim::Progress::setMaxValue(int maxValue) +{ + if (d->maxValue == maxValue) + return; + + if (!(maxValue < minValue())) { + d->maxValue = maxValue; + update(); + } +} + +void KSim::Progress::setOrigin(const QRect &origin) +{ + d->rectOrigin = origin; +} + +void KSim::Progress::setMeterPixmap(const QPixmap &pixmap) +{ + QSize oldSize = sizeHint(); + d->meterPixmap = pixmap; + relayoutLabel(oldSize); +} + +int KSim::Progress::xLocation() const +{ + int position = d->rectOrigin.width() - d->meterPixmap.width(); + int rangePos = maxValue() - minValue(); + int valuePos = value() - minValue(); + + int returnValue = 0; + if (rangePos) + returnValue = position * valuePos / rangePos; + + return returnValue; +} + +void KSim::Progress::paintEvent(QPaintEvent *ev) +{ + KSim::Label::paintEvent(ev); + drawMeter(); +} + +void KSim::Progress::resizeEvent(QResizeEvent *ev) +{ + KSim::Label::resizeEvent(ev); + setOrigin(rect()); +} + +void KSim::Progress::drawMeter() +{ + bitBlt(this, xLocation(), 2, &d->meterPixmap); +} + +void KSim::Progress::init(int maxValue, int value, ProgressType type) +{ + d = new Private; + d->type = type; + d->value = d->minValue = 0; + d->maxValue = maxValue; + setValue(value); +} diff --git a/ksim/library/progress.h b/ksim/library/progress.h new file mode 100644 index 0000000..570894a --- /dev/null +++ b/ksim/library/progress.h @@ -0,0 +1,181 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KSIM__PROGRESS_H +#define KSIM__PROGRESS_H + +#include "label.h" + +#include <kdemacros.h> + +namespace KSim +{ + /** + * provides a label with a progress bar meter + * @author Robbie Ward <linuxphreak@gmx.co.uk> + */ + class KDE_EXPORT Progress : public KSim::Label + { + Q_OBJECT + public: + enum ProgressType { Panel, Meter }; + /** + * constructs a KSim::Progress + * + * @param maxValue is the maximum value + * that the progress bar will show + * @param label is the text that will be displayed + * @param parent is the parent widget + */ + Progress(int maxValue, QWidget *parent, + const char *name = 0, WFlags fl = 0); + /** + * constructs a KSim::Progress + * + * @param maxValue is the maximum value + * that the progress bar will show + * @param type is the theme type + * @param label is the text that will be displayed + * @param parent is the parent widget + */ + Progress(int maxValue, int type, const QString &label, + QWidget *parent, const char *name = 0, WFlags fl = 0); + /** + * constructs a KSim::Progress + * + * @param maxValue is the maximum value + * that the progress bar will show + * @param type is the theme type + * @param label is the text that will be displayed + * @param value is the initial value to be displayed + * @param parent is the parent widget + */ + Progress(int maxValue, int type, const QString &label, + int value, QWidget *parent, const char *name = 0, + WFlags fl = 0); + /** + * constructs a KSim::Progress + * + * @param maxValue is the maximum value + * that the progress bar will show + * @param type is the theme type + * @param parent is the parent widget + */ + Progress(int maxValue, int type, QWidget *parent, + const char *name = 0, WFlags fl = 0); + /** + * constructs a KSim::Progress + * + * @param maxValue is the maximum value + * that the progress bar will show + * @param type is the theme type + * @param progressType is onr of Progress::ProgressType + * @param parent is the parent widget + */ + Progress(int maxValue, int type, + ProgressType progressType, + QWidget *parent, const char *name = 0, + WFlags fl = 0); + /** + * destructs KSim::Chart + */ + virtual ~Progress(); + + /** + * @return the current value + */ + int value() const; + /** + * @return the minimum value + */ + int minValue() const; + /** + * @return the maximum value + */ + int maxValue() const; + + /** + * @return the area that the progress meter will be drawn + */ + const QRect &rectOrigin() const; + /** + * reimplemented for internal reasons + */ + virtual void configureObject(bool repaintWidget = true); + /** + * reimplemented for internal reasons + */ + virtual QSize sizeHint() const; + + public slots: + /** + * calls KSim::Label::clear() and resets the value(), + * maxValue() and minValue() to 0 + */ + virtual void reset(); + /** + * sets the current value the progress bar will display + */ + void setValue(int); + /** + * sets the minimum value the progress bar will display + */ + void setMinValue(int); + /** + * sets the maximum value the progress bar will display + */ + void setMaxValue(int); + + protected: + /** + * sets the area that the progess bar will be drawn + */ + void setOrigin(const QRect &); + /** + * sets the progress bar pixmap + */ + void setMeterPixmap(const QPixmap &); + /** + * @return the pixel position where the meter should be drawn + */ + int xLocation() const; + /** + * reimplemented for internal reasons + */ + virtual void paintEvent(QPaintEvent *); + /** + * reimplemented for internal reasons + */ + virtual void resizeEvent(QResizeEvent *); + /** + * paints the meter image onto the widget + */ + void drawMeter(); + + private: + /** + * inits the widget + */ + void init(int, int = 0, ProgressType = Meter); + + class Private; + Private *d; + }; +} +#endif diff --git a/ksim/library/themeloader.cpp b/ksim/library/themeloader.cpp new file mode 100644 index 0000000..7c42dcd --- /dev/null +++ b/ksim/library/themeloader.cpp @@ -0,0 +1,1266 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "themeloader.h" +#include <ksimconfig.h> +#include "themetypes.h" +#include "common.h" + +#include <qfile.h> +#include <qstringlist.h> +#include <qvaluevector.h> +#include <qregexp.h> +#include <qapplication.h> +#include <qfileinfo.h> +#include <qdir.h> +#include <qimage.h> +#include <qbitmap.h> + +#include <kdebug.h> +#include <ksimpleconfig.h> +#include <kglobalsettings.h> +#include <kstandarddirs.h> +#include <kglobal.h> + +class KSim::Theme::Private +{ + public: + Private(const QValueVector<QString> &names, + const QStringList &list) : fileNames(names), + imageTypes(list) {} + + QStringList file; + QStringList dFile; + KConfig *globalReader; + QString altTheme; + QString location; + const QValueVector<QString> &fileNames; + const QStringList &imageTypes; + int alternative; + int font; + bool recolour; + + QString readOption(const QString &entry, + bool useGlobal = true, + const QString &defValue = QString::null) + { + QString text; + QStringList::ConstIterator it; + for (it = file.begin(); it != file.end(); ++it) { + if ((*it).find(entry) != -1) { + text = QStringList::split("=", (*it))[1].stripWhiteSpace(); + } + } + + if (!text.isEmpty() || dFile.isEmpty()) + return text; + + QStringList::ConstIterator it2; + for (it2 = dFile.begin(); it2 != dFile.end(); ++it) { + if ((*it2).find(entry) != -1) { + text = QStringList::split("=", (*it2))[1].stripWhiteSpace(); + } + } + + if (!text.isEmpty()) + return text; + + if (!globalReader || !useGlobal) + return defValue; + + text = globalReader->readEntry(entry, defValue); + return text; + } +}; + +class KSim::ThemeLoader::Private +{ + public: + QValueVector<QString> fileNames; + QStringList imageTypes; + KConfig *globalReader; + bool recolour; + QColor pixelColour; +}; + +bool KSim::Theme::operator==(const KSim::Theme &rhs) const +{ + return d == rhs.d; +} + +bool KSim::Theme::operator!=(const KSim::Theme &rhs) const +{ + return !(operator==(rhs)); +} + +KSim::Theme &KSim::Theme::operator=(const KSim::Theme &rhs) +{ + if (*this == rhs) + return *this; + + delete d; + d = rhs.d; + return *this; +} + +KSim::Theme::~Theme() +{ + delete d; +} + +const QString &KSim::Theme::path() const +{ + return d->location; +} + +QString KSim::Theme::name() const +{ + QString name = d->location; + if (name.endsWith("/")) + name.remove(name.length() - 1, 1); + + return name.remove(0, name.findRev("/") + 1); +} + +QString KSim::Theme::author() const +{ + QString author(d->readOption("author", false)); + return author.replace(QRegExp("\""), QString::null); +} + +int KSim::Theme::fontItem() const +{ + return d->font; +} + +int KSim::Theme::alternative() const +{ + return d->alternative; +} + +int KSim::Theme::alternatives() const +{ + return d->readOption("theme_alternatives").toInt(); +} + +int KSim::Theme::chartWidthRef(int defValue) const +{ + return internalNumEntry("chart_width_ref", defValue); +} + +int KSim::Theme::chartWidthMin(int defValue) const +{ + return internalNumEntry("chart_width_min", defValue); +} + +bool KSim::Theme::scaling(bool defValue) const +{ + return internalNumEntry("allow_scaling", defValue); +} + +int KSim::Theme::frameTopHeight(int defValue) const +{ + return KMIN(2, internalNumEntry("frame_top_height", defValue)); +} + +int KSim::Theme::frameBottomHeight(int defValue) const +{ + return KMIN(2, internalNumEntry("frame_bottom_height", defValue)); +} + +int KSim::Theme::frameLeftWidth(int defValue) const +{ + return KMIN(2, internalNumEntry("frame_left_width", defValue)); +} + +int KSim::Theme::frameRightWidth(int defValue) const +{ + return KMIN(2, internalNumEntry("frame_right_width", defValue)); +} + +QRect KSim::Theme::frameTopBorder(const QRect &defValue) const +{ + return internalRectEntry("frame_top_border", defValue); +} + +QRect KSim::Theme::frameBottomBorder(const QRect &defValue) const +{ + return internalRectEntry("frame_bottom_border", defValue); +} + +QRect KSim::Theme::frameLeftBorder(const QRect &defValue) const +{ + return internalRectEntry("frame_left_border", defValue); +} + +QRect KSim::Theme::frameRightBorder(const QRect &defValue) const +{ + return internalRectEntry("frame_right_border", defValue); +} + +QColor KSim::Theme::chartInColour(const QColor &defValue) const +{ + if (d->recolour) + return QApplication::palette().active().background(); + + return internalColourEntry("chart_in_color", defValue); +} + +QColor KSim::Theme::chartInColourGrid(const QColor &defValue) const +{ + return internalColourEntry("chart_in_color_grid", defValue); +} + +QColor KSim::Theme::chartOutColour(const QColor &defValue) const +{ + if (d->recolour) + return QApplication::palette().active().background(); + + return internalColourEntry("chart_out_color", defValue); +} + +QColor KSim::Theme::chartOutColourGrid(const QColor &defValue) const +{ + return internalColourEntry("chart_out_color_grid", defValue); +} + +bool KSim::Theme::bgGridMode(bool defValue) const +{ + return internalNumEntry("bg_grid_mode", defValue); +} + +int KSim::Theme::rxLedX(int defValue) const +{ + return internalNumEntry("rx_led_x", defValue); +} + +int KSim::Theme::rxLedY(int defValue) const +{ + return internalNumEntry("rx_led_y", defValue); +} + +int KSim::Theme::txLedX(int defValue) const +{ + return internalNumEntry("tx_led_x", defValue); +} + +int KSim::Theme::txLedY(int defValue) const +{ + return internalNumEntry("tx_led_y", defValue); +} + +int KSim::Theme::mailFrames(int defValue) const +{ + return internalNumEntry("decal_mail_frames", defValue); +} + +int KSim::Theme::mailDelay(int defValue) const +{ + return internalNumEntry("decal_mail_delay", defValue); +} + +int KSim::Theme::krellSliderDepth(int defValue) const +{ + return internalNumEntry("krell_slider_depth", defValue); +} + +int KSim::Theme::krellSliderXHot(int defValue) const +{ + return internalNumEntry("krell_slider_x_hot", defValue); +} + +QRect KSim::Theme::sliderPanel(const QRect &defValue) const +{ + return internalRectEntry("bg_slider_panel_border", defValue); +} + +QRect KSim::Theme::sliderMeter(const QRect &defValue) const +{ + return internalRectEntry("bg_slider_meter_border", defValue); +} + +QRect KSim::Theme::timerBorder(const QRect &defValue) const +{ + return internalRectEntry("bg_timer_border", defValue); +} + +QRect KSim::Theme::buttonPanelBorder(const QRect &defValue) const +{ + return internalRectEntry("button_panel_border", defValue); +} + +QRect KSim::Theme::buttonMeterBorder(const QRect &defValue) const +{ + return internalRectEntry("button_meter_border", defValue); +} + +QFont KSim::Theme::largeFont() const +{ + QString font(internalStringEntry("large_font", QString::null)); + + if (font.isEmpty()) + return QApplication::font(); + + QFont themeFont; + themeFont.setRawName(font.replace(QRegExp("\""), QString::null)); + return themeFont; +} + +QFont KSim::Theme::normalFont() const +{ + QString font(internalStringEntry("normal_font", QString::null)); + + if (font.isEmpty()) + return QApplication::font(); + + QFont themeFont; + themeFont.setRawName(font.replace(QRegExp("\""), QString::null)); + return themeFont; +} + +QFont KSim::Theme::smallFont() const +{ + QString font(internalStringEntry("small_font", QString::null)); + + if (font.isEmpty()) + return QApplication::font(); + + QFont themeFont; + themeFont.setRawName(font.replace(QRegExp("\""), QString::null)); + return themeFont; +} + +QFont KSim::Theme::currentFont() const +{ + switch (fontItem()) { + case 0: + return smallFont(); + break; + case 1: + return normalFont(); + break; + case 2: + return largeFont(); + break; + case 3: + return KSim::ThemeLoader::currentFont(); + break; + case 4: + return KGlobalSettings::generalFont(); + break; + } + + return QFont(); +} + +QString KSim::Theme::meterPixmap(int type, bool useDefault) const +{ + QString imageFile = createType(type, d->location); + QString text; + QString file = d->fileNames[7]; + + QStringList::ConstIterator it; + for (it = d->imageTypes.begin(); it != d->imageTypes.end(); ++it) { + if (QFile::exists(imageFile + file + d->altTheme + "." + *it)) { + text = imageFile + file + d->altTheme + "." + *it; + break; + } + else + if (QFile::exists(d->location + file + d->altTheme + "." + *it)) { + text = d->location + file + d->altTheme + "." + *it; + break; + } + } + + if (text.isNull() && useDefault) + return KSim::ThemeLoader::defaultUrl() + d->fileNames[7] + ".png"; + + return text; +} + +QString KSim::Theme::panelPixmap(int type, bool useDefault) const +{ + QString imageFile = createType(type, d->location); + QString text; + QString file = d->fileNames[6]; + + QStringList::ConstIterator it; + for (it = d->imageTypes.begin(); it != d->imageTypes.end(); ++it) { + if (QFile::exists(imageFile + file + d->altTheme + "." + *it)) { + text = imageFile + file + d->altTheme + "." + *it; + break; + } + else + if (QFile::exists(d->location + file + d->altTheme + "." + *it)) { + text = d->location + file + d->altTheme + "." + *it; + break; + } + } + + if (text.isNull() && useDefault) + return KSim::ThemeLoader::defaultUrl() + d->fileNames[6] + ".png"; + + return text; +} + +QString KSim::Theme::ledPixmap(int type, bool useDefault) const +{ + QString imageFile = createType(type, d->location); + QString text; + QString file = d->fileNames[30]; + + QStringList::ConstIterator it; + for (it = d->imageTypes.begin(); it != d->imageTypes.end(); ++it) { + if (QFile::exists(imageFile + file + d->altTheme + "." + *it)) { + text = imageFile + file + d->altTheme + "." + *it; + break; + } + else + if (QFile::exists(d->location + file + d->altTheme + "." + *it)) { + text = d->location + file + d->altTheme + "." + *it; + break; + } + } + + if (text.isNull() && useDefault) + return KSim::ThemeLoader::defaultUrl() + d->fileNames[30] + ".png"; + + return text; +} + +QString KSim::Theme::framePixmap(int type, bool useDefault) const +{ + QString text; + QString file; + + switch (type) { + case Types::TopFrame: + file = d->fileNames[0]; + break; + case Types::BottomFrame: + file = d->fileNames[1]; + break; + case Types::LeftFrame: + file = d->fileNames[2]; + break; + case Types::RightFrame: + file = d->fileNames[3]; + break; + } + + QStringList::ConstIterator it; + for (it = d->imageTypes.begin(); it != d->imageTypes.end(); ++it) { + if (QFile::exists(d->location + file + d->altTheme + "." + *it)) { + text = d->location + file + d->altTheme + "." + *it; + break; + } + } + + if (text.isNull() && useDefault) { + switch (type) { + case Types::TopFrame: + return KSim::ThemeLoader::defaultUrl() + d->fileNames[0] + ".png"; + break; + case Types::BottomFrame: + return KSim::ThemeLoader::defaultUrl() + d->fileNames[1] + ".png"; + break; + case Types::LeftFrame: + return KSim::ThemeLoader::defaultUrl() + d->fileNames[2] + ".png"; + break; + case Types::RightFrame: + return KSim::ThemeLoader::defaultUrl() + d->fileNames[3] + ".png"; + break; + } + } + + return text; +} + +QString KSim::Theme::chartPixmap(bool useDefault) const +{ + return loader(4, useDefault); +} + +QString KSim::Theme::gridPixmap(bool useDefault) const +{ + return loader(5, useDefault); +} + +QString KSim::Theme::krellPanelPixmap(bool useDefault) const +{ + return loader(14, useDefault); +} + +QString KSim::Theme::krellMeterPixmap(bool useDefault) const +{ + return loader(15, useDefault); +} + +QString KSim::Theme::krellSliderPixmap(bool useDefault) const +{ + return loader(16, useDefault); +} + +QString KSim::Theme::dataInPixmap(bool useDefault) const +{ + return loader(18, useDefault); +} + +QString KSim::Theme::dataOutPixmap(bool useDefault) const +{ + return loader(20, useDefault); +} + +QString KSim::Theme::mailPixmap(bool useDefault) const +{ + QString imageFile = createType(KSim::Types::Mail, d->location); + QString text; + QString file = d->fileNames[25]; + + QStringList::ConstIterator it; + for (it = d->imageTypes.begin(); it != d->imageTypes.end(); ++it) { + if (QFile::exists(imageFile + file + d->altTheme + "." + *it)) { + text = imageFile + file + d->altTheme + "." + *it; + break; + } + else + if (QFile::exists(d->location + file + d->altTheme + "." + *it)) { + text = d->location + file + d->altTheme + "." + *it; + break; + } + } + + if (text.isNull() && useDefault) + return KSim::ThemeLoader::defaultUrl() + + createType(KSim::Types::Mail, QString::null) + file + ".png"; + + return text; +} + +QPixmap KSim::Theme::splitPixmap(PixmapType type, uint itemNo, + bool useDefault) const +{ + return pixmapToList(type, itemNo, useDefault)[itemNo]; +} + +QValueList<QPixmap> KSim::Theme::pixmapToList(PixmapType type, + int limitAmount, bool useDefault) const +{ + QImage image; + int xOffset = 0; + int yOffset = 0; + int depth = 0; + + switch (type) { + case KrellPanel: + depth = readIntEntry("StylePanel", "*.krell_depth"); + xOffset = readIntEntry("StylePanel", "*.krell_x_hot"); + yOffset = readIntEntry("StylePanel", "*.krell_yoff"); + image.load(krellPanelPixmap(useDefault)); + kdDebug(2003) << "KSim::Theme: type = KrellPanel" << endl; + break; + case KrellMeter: + depth = readIntEntry("StyleMeter", "*.krell_depth"); + xOffset = readIntEntry("StyleMeter", "*.krell_x_hot"); + yOffset = readIntEntry("StyleMeter", "*.krell_yoff"); + image.load(krellMeterPixmap(useDefault)); + kdDebug(2003) << "KSim::Theme: type = KrellMeter" << endl; + break; + case KrellSlider: + depth = krellSliderDepth(); + image.load(krellSliderPixmap(useDefault)); + kdDebug(2003) << "KSim::Theme: type = KrellSlider" << endl; + break; + default: + return QValueList<QPixmap>(); + break; + } + + if (image.isNull()) + return QValueList<QPixmap>(); + + QValueList<QPixmap> list; + int size = image.height(); + if (depth) + size = image.height() / depth; + + KSim::ThemeLoader::self().reColourImage(image); + QPixmap pixmap = image; + QPixmap newPixmap(image.width() - xOffset, size); + + for (int i = 0; i < (depth + 1); ++i) { + newPixmap.fill(); + + if (pixmap.mask()) { + QBitmap mask(newPixmap.size()); + bitBlt(&mask, 0, 0, pixmap.mask(), xOffset, yOffset, + image.width() - xOffset, size); + newPixmap.setMask(mask); + } + + bitBlt(&newPixmap, 0, 0, &pixmap, xOffset, yOffset, + image.width() - xOffset, size); + + list.append(newPixmap); + + if (limitAmount == i) + break; + } + + kdDebug(2003) << "KSim::Theme: size = " << size << endl; + kdDebug(2003) << "KSim::Theme: depth = " << depth << endl; + kdDebug(2003) << "KSim::Theme: xOffset = " << xOffset << endl; + kdDebug(2003) << "KSim::Theme: yOffset = " << xOffset << endl; + + return list; +} + +int KSim::Theme::transparency(const QString &itemType, + const QString &entry) const +{ + return readIntEntry(itemType, entry); +} + +bool KSim::Theme::textShadow(const QString &itemType, + const QString &entry) const +{ + if (d->recolour) + return false; + + QString shadow = readEntry(itemType, entry); + if (shadow.isEmpty() || shadow.findRev("none") != -1) + return false; + + return true; +} + +QColor KSim::Theme::shadowColour(const QString &itemType, + const QString &entry) const +{ + return readColourEntry(itemType, entry, 1); +} + +QColor KSim::Theme::textColour(const QString &itemType, + const QString &entry) const +{ + if (d->recolour) + return KGlobalSettings::textColor(); + + return readColourEntry(itemType, entry, 0); +} + +int KSim::Theme::readIntEntry(const QString &itemType, + const QString &entry) const +{ + QString entryName = itemType + " " + entry; + return internalNumEntry(entryName, 0); +} + +QRect KSim::Theme::readRectEntry(const QString &itemType, + const QString &entry) const +{ + QString entryName = itemType + " " + entry; + return internalRectEntry(entryName, QRect()); +} + +QString KSim::Theme::readEntry(const QString &itemType, + const QString &entry) const +{ + QString entryName = itemType + " " + entry; + return internalStringEntry(entryName, QString::null); +} + +QString KSim::Theme::readColourEntry(const QString &itemType, + const QString &entry, int row) const +{ + QString color = readEntry(itemType, entry); + if (color.isEmpty()) + color = QString::fromLatin1("#ffffff #ffffff"); + + return QStringList::split(' ', color)[row]; +} + +QFont KSim::Theme::readFontEntry(const QString &itemType, + const QString &entry) const +{ + const QString &font = readEntry(itemType, entry); + + // If only there was a better way of doing this + if (font == "small_font") + return smallFont(); + else + if (font == "normal_font") + return normalFont(); + else + if (font == "large_font") + return largeFont(); + + return QFont(); +} + +bool KSim::Theme::fontColours(int type, const QString &string, QFont &font, + QColor &text, QColor &shadow, bool &showShadow) const +{ + QString key = KSim::Types::typeToString(type, false); + bool repaint = false; + + // set colours from the string 'key' + if (!readEntry(string, key + ".textcolor").isEmpty()) { + text= textColour(string, key + ".textcolor"); + shadow = shadowColour(string, key + ".textcolor"); + showShadow = textShadow(string, key + ".textcolor"); + repaint = true; + } + else { + text= textColour(string, "*.textcolor"); + shadow = shadowColour(string, "*.textcolor"); + showShadow = textShadow(string, "*.textcolor"); + } + + // set fonts from the string 'key' + if (!readEntry(string, key + ".font").isEmpty()) { + if (KSim::ThemeLoader::currentFontItem() != 3) { + font = readFontEntry(string, key + ".font"); + repaint = true; + } + } + else { + font = currentFont(); + } + + return repaint; +} + +bool KSim::Theme::fontColours(const KSim::Base *const base, QFont &font, + QColor &text, QColor &shadow, bool &showShadow) const +{ + if (!base) + return false; + + return fontColours(base->type(), base->configString(), font, + text, shadow, showShadow); +} + +KSim::Theme::Theme() +{ + d = 0; +} + +KSim::Theme::Theme(const QString &url, const QString &fileName, int alt, + const QValueVector<QString> &vector, const QStringList &list, + KConfig *globalReader) +{ + create(vector, list, globalReader); + init(url, fileName, alt); + + KSim::Config::config()->setGroup("Misc"); + d->recolour = KSim::Config::config()->readBoolEntry("ReColourTheme", false); +} + +void KSim::Theme::create(const QValueVector<QString> &vector, + const QStringList &list, KConfig *globalReader) +{ + d = new Private(vector, list); + d->globalReader = globalReader; +} + +void KSim::Theme::init(const QString &url, const QString &fileName, int alt) +{ + d->altTheme = KSim::ThemeLoader::alternativeAsString(alt); + d->location = url; + d->alternative = alt; + d->font = KSim::ThemeLoader::currentFontItem(); + + d->file = QStringList::split("\n", parseConfig(url, fileName)); + + if (alt != 0) + d->dFile = QStringList::split("\n", parseConfig(url, "gkrellmrc")); +} + +void KSim::Theme::reparse(const QString &url, const QString &fileName, int alt) +{ + init(url, fileName, alt); +} + +QString KSim::Theme::parseConfig(const QString &url, + const QString &fileName) +{ + return KSim::ThemeLoader::self().parseConfig(url, fileName); +} + +QString KSim::Theme::loader(int value, bool useDefault) const +{ + QString text; + QString file = d->fileNames[value]; + + QStringList::ConstIterator it; + for (it = d->imageTypes.begin(); it != d->imageTypes.end(); ++it) { + if (QFile::exists(d->location + file + d->altTheme + "." + *it)) { + text = d->location + file + d->altTheme + "." + *it; + break; + } + } + + if (text.isNull() && useDefault) + return KSim::ThemeLoader::defaultUrl() + d->fileNames[value] + ".png"; + + return text; +} + +QString KSim::Theme::createType(int type, const QString &text) const +{ + if (type == Types::None) + return text; + + return text + KSim::Types::typeToString(type); +} + +void KSim::Theme::setRecolour(bool value) +{ + if (!d) + return; + + d->recolour = value; +} + +// Keep the ugliness here to make the rest +// of the class readable +int KSim::Theme::internalNumEntry(const QString &entry, int defValue) const +{ + return d->readOption(entry, true, QString::number(defValue)).toInt(); +} + +QRect KSim::Theme::internalRectEntry(const QString &entry, + const QRect &defValue) const +{ + QString rect; + rect += QString::number(defValue.left()); + rect += ","; + rect += QString::number(defValue.top()); + rect += ","; + rect += QString::number(defValue.width()); + rect += ","; + rect += QString::number(defValue.height()); + + QStringList list = QStringList::split(",", d->readOption(entry, true, rect)); + QRect rect2(list[0].toInt(), list[1].toInt(), list[2].toInt(), list[3].toInt()); + + return rect2; +} + +QColor KSim::Theme::internalColourEntry(const QString &entry, + const QColor &defValue) const +{ + return d->readOption(entry, true, defValue.name()); +} + +QString KSim::Theme::internalStringEntry(const QString &entry, + const QString &defValue) const +{ + return d->readOption(entry, true, defValue); +} + +// check if the dir is writable, if not generate the new file in the home dir +#define KSIM_THEME_URL(url) \ +{ \ +} + +KSim::ThemeLoader *KSim::ThemeLoader::m_self = 0; // initialize pointer +KSim::ThemeLoader &KSim::ThemeLoader::self() +{ + if (!m_self) { // is it the first call? + m_self = new KSim::ThemeLoader; // create sole instance + qAddPostRoutine(cleanup); + } + + return *m_self; // address of sole instance +} + +bool KSim::ThemeLoader::isDifferent() const +{ + // if the theme path, theme alternative or the + // specified font has changed then we should + // return true, else false + + KSim::Config::config()->setGroup("Misc"); + bool recolour = KSim::Config::config()->readBoolEntry("ReColourTheme", false); + + return (current().path() != currentUrl() + || current().alternative() != currentAlternative() + || current().fontItem() != currentFontItem() + || d->recolour != recolour); +} + +void KSim::ThemeLoader::reload() +{ + reColourItems(); + grabColour(); + + if (!isDifferent()) + return; + + if (currentUrl() != defaultUrl()) { + if (!d->globalReader) + d->globalReader = new KConfig(defaultUrl() + "gkrellmrc_ksim"); + } + else { + delete d->globalReader; + d->globalReader = 0; + } + + if (m_theme.d) + m_theme.d->globalReader = d->globalReader; + + QString fileName = QString::fromLatin1("gkrellmrc") + alternativeAsString(); + m_theme.reparse(currentUrl(), fileName, currentAlternative()); +} + +const KSim::Theme &KSim::ThemeLoader::current() const +{ + return m_theme; +} + +KSim::Theme KSim::ThemeLoader::theme(const QString &url, + const QString &rcFile, int alt) const +{ + return KSim::Theme(url, rcFile, alt, d->fileNames, + d->imageTypes, d->globalReader); +} + +void KSim::ThemeLoader::reColourImage(QImage &image) +{ + if (!d->recolour || image.isNull()) + return; + + QColor color = QApplication::palette().active().background(); + QImage output(image.width(), image.height(), 32); + output.setAlphaBuffer(image.hasAlphaBuffer()); + + Q_UINT32 r = color.red(); + Q_UINT32 g = color.green(); + Q_UINT32 b = color.blue(); + Q_UINT32 *write = reinterpret_cast<Q_UINT32 *>(output.bits()); + Q_UINT32 *read = reinterpret_cast<Q_UINT32 *>(image.bits()); + int size = image.width() * image.height(); + + for (int pos = 0; pos < size; pos++) + { + QRgb basePix = static_cast<QRgb>(*read); + + // Here, we assume that source is really gray, so R=G=B=I + // Use blue since it's very easy to extract. + Q_UINT32 i = qBlue(basePix); + + Q_UINT32 cr = (r * i + 128) >> 8; // Fixed point.. + Q_UINT32 cg = (g * i + 128) >> 8; + Q_UINT32 cb = (b * i + 128) >> 8; + + Q_UINT32 alpha = qAlpha(basePix); + *write = qRgba(cr, cg, cb, alpha); + write++; + read++; + } + + image = output; +} + +QString KSim::ThemeLoader::parseConfig(const QString &url, + const QString &fileName) +{ + QFile origFile(url + fileName); + + if (!origFile.open(IO_ReadOnly)) + return QString::null; + + QTextStream origStream(&origFile); + QString text; + QRegExp reg("\\*"); // regexp for '*' chars + QRegExp number("[0-9]+"); // regexp for all numbers + QRegExp numbers("[0-9]+,[0-9]+,[0-9]+,[0-9]+"); // regexp for int,int,int,int + QRegExp minus("[a-zA-Z]+ \\- [a-zA-Z]+"); // regexp for 'someText - someText' + while (!origStream.atEnd()) { + QString line(origStream.readLine().simplifyWhiteSpace()); + + if (line.find(reg) == 0) // find the location of the * comments + // replace all * comments with # comments so KConfig doesn't complain + line.replace(reg, "#"); + + if (line.find("#") == -1) { // find the location of the string 'gkrellmms' + if (line.findRev("=") == -1) { // if found we check for the string '=' + int numLoc = line.findRev(numbers); + if (numLoc != -1) + // if '=' doesn't exist we add one so KConfig doesn't complain + line.insert(numLoc, " = "); + + numLoc = line.findRev(number); + if (numLoc != -1) + // if '=' doesn't exist we add one so KConfig doesn't complain + line.insert(numLoc, " = "); + + numLoc = line.findRev(minus); + if (numLoc != -1) + // replace the '-' with an '=' so KConfig doesn't get confused + line.replace(QRegExp("-"), "="); + } + } + + text.append(line).append('\n'); + } + + return text; +} + +// GKrellM themes seem to be rather inconsistant +// so the following code changes the dir structure +// of a theme to be more consistant, but the dir structure +// is still compliant with GKrellM. +void KSim::ThemeLoader::parseDir(const QString &url, int alt) +{ + if ( !QFileInfo( url ).isWritable() && currentName() != "ksim" ) + { + QString homePath = QDir::current().path(); + homePath = locateLocal( "data", "ksim" ) + + QString::fromLatin1( "/themes" ) + + homePath.right( homePath.length() + - homePath.findRev( QRegExp( "\\/" ), + homePath.length() ) ); + + if ( !QFile::exists( homePath ) ) + KStandardDirs::makeDir( homePath ); + + kdWarning() << "Cant write to current dir, setting dir to " + << homePath << endl; + + QDir::setCurrent( homePath ); + } + + int alternatives = ++alt; + + QStringList formats; + QStringList panels; + QStringList meters; + + formats << "png" << "jpg" << "jpeg" << "gif" << "xpm"; + panels << "inet" << "net" << "proc" << "cpu" << "disk"; + meters << "mem" << "fs" << "mail" << "apm" << "uptime" + << "clock" << "cal" << "timer" << "host" << "swap"; + + QDir directory; + for (int i = 0; i < alternatives; ++i) { + QString altString = KSim::ThemeLoader::alternativeAsString(i); + if (alternatives == 1 || i == 0) + altString = QString::null; + + QStringList::ConstIterator format; + for (format = formats.begin(); format != formats.end(); ++format) { + // go through the meters array and move the files to the correct dir/filename + QStringList::Iterator meter; + for (meter = meters.begin(); meter != meters.end(); ++meter) { + QString bgMeter = QString::fromLatin1("bg_meter_"); + if (QFile::exists(bgMeter + (*meter) + altString + "." + (*format))) { + if (KStandardDirs::makeDir(url + (*meter))) + directory.rename(bgMeter + (*meter) + altString + "." + (*format), + (*meter) + "/bg_meter" + altString + "." + (*format)); + } + } + + // go through the panels array and move the files to the correct dir/filename + QStringList::ConstIterator panel; + for (panel = panels.begin(); panel != panels.end(); ++panel) { + QString bgPanel = QString::fromLatin1("bg_panel_"); + if (QFile::exists(bgPanel + (*panel) + altString + "." + (*format))) { + if (KStandardDirs::makeDir(url + (*panel))) + directory.rename(bgPanel + (*panel) + altString + "." + (*format), + (*panel) + "/bg_panel" + altString + "." + (*format)); + } + } + + // fix stupid themes that have a bg_panel image in the host dir + QString tempFile = QString::fromLatin1("host/bg_panel"); + if (QFile::exists(tempFile + altString + "." + (*format))) + directory.rename(tempFile + altString + "." + (*format), "host/bg_meter" + + altString + "." + (*format)); + + // move decal_net_leds* to the net folder to be more consistant + tempFile = QString::fromLatin1("decal_net_leds"); + if (QFile::exists(tempFile + altString + "." + (*format))) { + if (KStandardDirs::makeDir(url + "net")) + directory.rename(tempFile + altString + "." + (*format), + "net/decal_net_leds" + altString + "." + (*format)); + } + } + } +} + +void KSim::ThemeLoader::validate() +{ + if (!QFile::exists(currentUrl())) { + KSim::Config::config()->setGroup("Theme"); + KSim::Config::config()->writeEntry("Name", "ksim"); + KSim::Config::config()->writeEntry("Alternative", 0); + KSim::Config::config()->sync(); + } +} + +void KSim::ThemeLoader::themeColours(QWidget *widget) +{ + widget->setEraseColor(d->pixelColour); +} + +QString KSim::ThemeLoader::currentName() +{ + KSim::Config::config()->setGroup("Theme"); + return KSim::Config::config()->readEntry("Name", "ksim"); +} + +QString KSim::ThemeLoader::currentUrl() +{ + KSim::Config::config()->setGroup("Theme"); + QString folder(KSim::Config::config()->readEntry("Name")); + folder.prepend("ksim/themes/").append("/"); + QString dirName(KGlobal::dirs()->findResourceDir("data", folder)); + dirName += folder; + + return dirName; +} + +QString KSim::ThemeLoader::defaultUrl() +{ + return KGlobal::dirs()->findDirs("data", "ksim/themes/ksim").first(); +} + +int KSim::ThemeLoader::currentAlternative() +{ + KSim::Config::config()->setGroup("Theme"); + int alternative = KSim::Config::config()->readNumEntry("Alternative"); + + if ( alternative > self().current().alternatives() ) + alternative = self().current().alternatives(); + + return alternative; +} + +QString KSim::ThemeLoader::alternativeAsString(int alt) +{ + int alternative = (alt == -1 ? currentAlternative() : alt); + return (alternative == 0 ? QString::null : QString::fromLatin1("_") + + QString::number(alternative)); +} + +QFont KSim::ThemeLoader::currentFont() +{ + if (currentFontItem() != 3) + return self().current().currentFont(); + + KSim::Config::config()->setGroup("Theme"); + return KSim::Config::config()->readFontEntry("Font"); +} + +int KSim::ThemeLoader::currentFontItem() +{ + KSim::Config::config()->setGroup("Theme"); + return KSim::Config::config()->readNumEntry("FontItem", 0); +} + +KSim::ThemeLoader::ThemeLoader() +{ + m_self = this; + + d = new Private; + d->imageTypes << "png" << "jpg" << "jpeg" << "xpm" << "gif"; + + if (currentUrl() != defaultUrl()) + d->globalReader = new KConfig(defaultUrl() + "gkrellmrc_ksim"); + else + d->globalReader = 0; + + d->fileNames.resize(31); + d->fileNames[0] = "frame_top"; + d->fileNames[1] = "frame_bottom"; + d->fileNames[2] = "frame_left"; + d->fileNames[3] = "frame_right"; + d->fileNames[4] = "bg_chart"; + d->fileNames[5] = "bg_grid"; + d->fileNames[6] = "bg_panel"; + d->fileNames[7] = "bg_meter"; + d->fileNames[8] = "bg_slider_panel"; + d->fileNames[9] = "bg_slider_meter"; + d->fileNames[10] = "button_panel_in"; + d->fileNames[11] = "button_panel_out"; + d->fileNames[12] = "button_meter_in"; + d->fileNames[13] = "button_meter_out"; + d->fileNames[14] = "krell_panel"; + d->fileNames[15] = "krell_meter"; + d->fileNames[16] = "krell_slider"; + d->fileNames[17] = "decal_misc"; + d->fileNames[18] = "data_in"; + d->fileNames[19] = "data_in_grid"; + d->fileNames[20] = "data_out"; + d->fileNames[21] = "data_out_grid"; + d->fileNames[22] = "krell"; + d->fileNames[23] = "spacer_top"; + d->fileNames[24] = "spacer_bottom"; + d->fileNames[25] = "decal_mail"; + d->fileNames[26] = "krell_penguin"; + d->fileNames[27] = "bg_volt"; + d->fileNames[28] = "decal_timer_button"; + d->fileNames[29] = "bg_timer"; + d->fileNames[30] = "decal_net_leds"; + + m_theme.create(d->fileNames, d->imageTypes, d->globalReader); + + QString fileName = QString::fromLatin1("gkrellmrc") + alternativeAsString(); + m_theme.init(currentUrl(), fileName, currentAlternative()); + + reColourItems(); + grabColour(); +} + +KSim::ThemeLoader::~ThemeLoader() +{ + delete d->globalReader; + delete d; +} + +void KSim::ThemeLoader::cleanup() +{ + if (!m_self) + return; + + delete m_self; + m_self = 0; +} + +void KSim::ThemeLoader::reColourItems() +{ + KSim::Config::config()->setGroup("Misc"); + d->recolour = KSim::Config::config()->readBoolEntry("ReColourTheme", false); + m_theme.setRecolour(d->recolour); +} + +void KSim::ThemeLoader::grabColour() +{ + KSim::Config::config()->setGroup("Theme"); + QPoint pos(2, 2); + pos = KSim::Config::config()->readPointEntry("PixelLocation", &pos); + + QImage image(current().meterPixmap(Types::None)); + reColourImage(image); + d->pixelColour = image.pixel(pos.x(), pos.y()); +} diff --git a/ksim/library/themeloader.h b/ksim/library/themeloader.h new file mode 100644 index 0000000..c20afe0 --- /dev/null +++ b/ksim/library/themeloader.h @@ -0,0 +1,511 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef THEMELOADER_H +#define THEMELOADER_H + +#include <qstring.h> +#include <qrect.h> +#include <qcolor.h> +#include <qfont.h> +#include <qvaluelist.h> + +#include <kdemacros.h> + +class QStringList; +template<class> class QValueVector; +class KConfig; +class QWidget; + +namespace KSim +{ + class Base; + + /** + * a class containing various information + * about a theme, use KSim::ThemeLoader to + * get an instance + * @author Robbie Ward <linuxphreak@gmx.co.uk> + * @short Provides a loader for the themes + */ + class KDE_EXPORT Theme + { + friend class ThemeLoader; + public: + enum PixmapType { KrellPanel = 0, KrellMeter, KrellSlider }; + ~Theme(); + bool operator==(const KSim::Theme &rhs) const; + bool operator!=(const KSim::Theme &rhs) const; + KSim::Theme &operator=(const KSim::Theme &rhs); + /** + * @return the theme path + */ + const QString &path() const; + /** + * @return the name of the theme + */ + QString name() const; + /** + * @return the author of the theme + */ + QString author() const; + /** + * @return the set font item for the theme + */ + int fontItem() const; + /** + * @return the amount of alternatives the theme has + */ + int alternative() const; + /** + * @return the amount of alternatives the theme has + */ + int alternatives() const; + /** + * @return the width leds should be scaled to (if scaling() returns true) + */ + int chartWidthRef(int defValue = 0) const; + int chartWidthMin(int defValue = 0) const; + /** + * @return true if sacling should be enabled + */ + bool scaling(bool defValue = false) const; + /** + * @return the height of the top frame + */ + int frameTopHeight(int defValue = 0) const; + /** + * @return the height of the bottom frame + */ + int frameBottomHeight(int defValue = 0) const; + /** + * @return the width of the left frame + */ + int frameLeftWidth(int defValue = 0) const; + /** + * @return the width of the right frame + */ + int frameRightWidth(int defValue = 0) const; + /** + * @return a rect of the top frame border + */ + QRect frameTopBorder(const QRect &defValue = QRect()) const; + /** + * @return a rect of the bottom frame border + */ + QRect frameBottomBorder(const QRect &defValue = QRect()) const; + /** + * @return a rect of the left frame border + */ + QRect frameLeftBorder(const QRect &defValue = QRect()) const; + /** + * @return a rect of the right frame border + */ + QRect frameRightBorder(const QRect &defValue = QRect()) const; + /** + * @return the color of the chart in + */ + QColor chartInColour(const QColor &defValue = QColor()) const; + /** + * @return the color of the chart in grid + */ + QColor chartInColourGrid(const QColor &defValue = QColor()) const; + /** + * @return the color of the chart out + */ + QColor chartOutColour(const QColor &defValue = QColor()) const; + /** + * @return the color of the chart out grid + */ + QColor chartOutColourGrid(const QColor &defValue = QColor()) const; + /** + * if false then the grid lines should be drawn at the + * top and bottom of the graphs + */ + bool bgGridMode(bool defValue = false) const; + /** + * @return the X location of the receive led + */ + int rxLedX(int defValue = 0) const; + /** + * @return the Y location of the receive led + */ + int rxLedY(int defValue = 0) const; + /** + * @return the X location of the send led + */ + int txLedX(int defValue = 0) const; + /** + * @return the Y location of the send led + */ + int txLedY(int defValue = 0) const; + /** + * @return the amount of mail frames + */ + int mailFrames(int defValue = 0) const; + /** + * @return the mail check delay + */ + int mailDelay(int defValue = 0) const; + /** + * @return the slider depth + */ + int krellSliderDepth(int defValue = 7) const; + /** + * @return the vertical location of the start of the image + */ + int krellSliderXHot(int defValue = 0) const; + /** + * @return the area for the slider panel + */ + QRect sliderPanel(const QRect &defValue = QRect()) const; + /** + * @return the area for the slider meter + */ + QRect sliderMeter(const QRect &defValue = QRect()) const; + /** + * @return the border for the timer label/button + */ + QRect timerBorder(const QRect &defValue = QRect()) const; + /** + * @return the border for the panel button + */ + QRect buttonPanelBorder(const QRect &defValue = QRect()) const; + /** + * @return the border for the meter button + */ + QRect buttonMeterBorder(const QRect &defValue = QRect()) const; + /** + * @return the large font that the theme specifies + */ + QFont largeFont() const; + /** + * @return the normal font that the theme specifies + */ + QFont normalFont() const; + /** + * @return the small font that the theme specifies + */ + QFont smallFont() const; + /** + * @return the current font to be used + * according to fontItem() + */ + QFont currentFont() const; + /** + * @return the meter image (bg_meter.[png|jpg|gif]) + * of the current theme, if type is specified then it will + * look in the folder type. + * + * it will first look in the dir 'type' if no image is found + * it will drop back a dir + * @param type is one of: none, apm, cal, clock, fs, + * host, mail, mem, swap, timer, uptime + */ + QString meterPixmap(int type, bool useDefault = true) const; + /** + * @return the meter image (bg_panel.[png|jpg|gif]) + * of the current theme, it will first look in the dir 'type' + * if no image is found it will drop back a dir + * @param type is one of: net, inet + */ + QString panelPixmap(int type, bool useDefault = true) const; + /** + * @return the decal net leds image + * (usually decal_net_leds.[png|jpg|gif]) of the + * current theme, it will first look in the dir 'type' + * if no image is found it will drop back a dir + * @param type is one of: net, inet + */ + QString ledPixmap(int type, bool useDefault = true) const; + /** + * @return the frame image of the current theme, + * @param type is one of: top, bottom, left, right + */ + QString framePixmap(int type, bool useDefault = true) const; + /** + * @return the krell chart image (bg_chart.[png|jpg|gif]) + * of the current theme + */ + QString chartPixmap(bool useDefault = true) const; + /** + * @return the krell grid image (bg_grid.[png|jpg|gif]) + * of the current theme + */ + QString gridPixmap(bool useDefault = true) const; + /** + * @return the krell panel image (krell_panel.[png|jpg|gif]) + * of the current theme + */ + QString krellPanelPixmap(bool useDefault = true) const; + /** + * @return the krell meter image (krell_meter.[png|jpg|gif]) + * of the current theme + */ + QString krellMeterPixmap(bool useDefault = true) const; + /** + * @return the krell slider image (krell_slider.[png|jpg|gif]) + * of the current theme + */ + QString krellSliderPixmap(bool useDefault = true) const; + /** + * @return the data in image (data_in.[png|jpg|gif]) + * of the current theme + */ + QString dataInPixmap(bool useDefault = true) const; + /** + * @return the data out image (data_out.[png|jpg|gif]) + * of the current theme + */ + QString dataOutPixmap(bool useDefault = true) const; + /** + * @return the mail image (mail/decal_mail.[png|jpg|gif]) + * of the current theme + */ + QString mailPixmap(bool useDefault = true) const; + /** + * @return a segmant of an image, using @p itemNo to + * get the segmant and from the ImageType @p type + */ + QPixmap splitPixmap(PixmapType type, uint itemNo = 0, + bool useDefault = true) const; + /** + * Same as the above function but returns an array of pixmaps + * with the maximum size of limitAmount, or all the pixmaps if @p + * limitAmount is -1 (default) + * @return an array of pixmaps + */ + QValueList<QPixmap> pixmapToList(PixmapType type, + int limitAmount = -1, bool useDefault = true) const; + /** + * returns the transparency level from the specified keys + */ + int transparency(const QString &, const QString &) const; + /** + * @return true if shadow text is enabled + */ + bool textShadow(const QString &, const QString &) const; + /** + * @return the shadow color (if any) for the specified keys + */ + QColor shadowColour(const QString &, const QString &) const; + /** + * @return the text color for the specified keys + */ + QColor textColour(const QString &, const QString &) const; + /** + * reads an entry and returns it as an int + */ + int readIntEntry(const QString &, const QString &) const; + /** + * @return a rect from the specified keys + */ + QRect readRectEntry(const QString &, const QString &) const; + /** + * reads an entry from the specified keys + */ + QString readEntry(const QString &, const QString &) const; + /** + * reads a color entry from the specified keys + */ + QString readColourEntry(const QString &, const QString &, int) const; + /** + * reads a font entry from the specified keys + */ + QFont readFontEntry(const QString &, const QString &) const; + /** + * sets the font, textColour, shadowColour and showShadow to + * the fonts and colours KSim should use depending on type and + * string. + * + * returns true if one of the parameters were changed using + * type and string, else the parameters will be set to the current + * colours and font that KSim should use and returns false. + * + * example usage: + * <pre> + * QFont font; + * QColor textColour, shadowColour; + * bool showShadow; + * if (KSim::ThemeLoader::self().current().fontColours(type(), configString(), font, + * textColour, shadowColour, showShadow) + * { + * setFont(font); + * // Do something with textColour, shadowColour and showShadow + * } + * </pre> + * @param type is the theme type you want, generally if you're calling this + * from a KSim::Base (or derived from) object then use type() + * @param string is the config string entry you want the function to read + * from, generally if you're calling this from a KSim::Base (or derived from) + * object then use configString() + */ + bool fontColours(int type, const QString &string, QFont &font, + QColor &textColour, QColor &shadowColour, bool &showShadow) const; + /** + * convenience function. + * + * collects the theme type and config key from the base pointer + */ + bool fontColours(const KSim::Base *const base, QFont &font, + QColor &textColour, QColor &shadowColour, bool &showShadow) const; + + Theme(const KSim::Theme &); + + private: + Theme(); + Theme(const QString &url, const QString &fileName, int alt, + const QValueVector<QString> &vector, const QStringList &list, + KConfig *globalReader); + void create(const QValueVector<QString> &, const QStringList &, KConfig *); + void init(const QString &url, const QString &fileName, int alt); + void reparse(const QString &url, const QString &fileName, int alt); + QString parseConfig(const QString &, const QString &); + QString loader(int, bool useDefault = true) const; + QString createType(int, const QString &) const; + void setRecolour(bool); + + int internalNumEntry(const QString &, int) const; + QRect internalRectEntry(const QString &, const QRect &) const; + QColor internalColourEntry(const QString &, const QColor &) const; + QString internalStringEntry(const QString &, const QString &) const; + + class Private; + Private *d; + }; + + /** + * returns a class Theme containing + * information of the current theme or + * of the theme path specified + * @author Robbie Ward <linuxphreak@gmx.co.uk> + * @short Provides a loader for the themes + */ + class KDE_EXPORT ThemeLoader + { + public: + /** + * @return a reference to the instance + */ + static ThemeLoader &self(); + /** + * @return true if the theme has changed + */ + bool isDifferent() const; + /** + * Updates the info to the current theme + */ + void reload(); + /** + * @return the current theme that is set + */ + const KSim::Theme ¤t() const; + /** + * @return a theme from the path specified + * @param url is the path of the theme dir + * @param rcFile is the filename of the config file (optional) + * @param alt is the theme alternative number (optional) + */ + KSim::Theme theme(const QString &url, + const QString &rcFile = "gkrellmrc", int alt = 0) const; + /** + * re-colours an image to the current KDE + * color scheme + */ + void reColourImage(QImage &image); + /** + * changes some of the entries in the config file so kconfig + * can handle the file better. + * @return the location of the config file + */ + QString parseConfig(const QString &url, const QString &file); + /** + * change the dir structure of a theme directory + * so KSim can understand them better + */ + void parseDir(const QString &url, int alt); + /** + * checks if the themeUrl entry is valid, + * if not it then reverts the current theme + * to the default url + */ + void validate(); + /** + * sets the pallete of the current theme + */ + void themeColours(QWidget *); + /** + * @return current theme name + */ + static QString currentName(); + /** + * @return current theme url, if there is no current theme + * then it will return the default theme + */ + static QString currentUrl(); + /** + * @return the default theme url + */ + static QString defaultUrl(); + /** + * @return the current theme alternative + */ + static int currentAlternative(); + /** + * @return the current theme alternative as a string, eg if the + * current theme alt is 1 then this will return '_1'. + * if there is no theme alt this will return a null string. + * + * if this is set to -1 (the default) then the current alternative + * will be used + */ + static QString alternativeAsString(int alt = -1); + /** + * @return the font of the theme if the theme font is set to custom + */ + static QFont currentFont(); + /** + * @return the font item of the theme, eg: 0 would be the small font + */ + static int currentFontItem(); + + protected: + /** + * Default constructor, use self() to get an instance + */ + ThemeLoader(); + ~ThemeLoader(); + + private: + ThemeLoader(const ThemeLoader &); + ThemeLoader &operator=(const ThemeLoader &); + /** + * Deletes the instance and cleans up after itself + */ + static void cleanup(); + void reColourItems(); + void grabColour(); + + class Private; + Private *d; + KSim::Theme m_theme; + static ThemeLoader *m_self; + }; +} +#endif diff --git a/ksim/library/themetypes.h b/ksim/library/themetypes.h new file mode 100644 index 0000000..805302c --- /dev/null +++ b/ksim/library/themetypes.h @@ -0,0 +1,81 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef THEMETYPES_H +#define THEMETYPES_H + +namespace KSim +{ + namespace Types + { + /** + * available types for the frames + */ + enum FrameType + { + TopFrame = 0, + BottomFrame, + LeftFrame, + RightFrame + }; + + /** + * available theme types + */ + enum ThemeType + { + None = -1, + Apm, + Cal, + Clock, + Fs, + Host, + Mail, + Mem, + Swap, + Timer, + Uptime, + Net, + Inet + }; + + /** + * @return the ThemeType enum as a QString + */ + inline QString typeToString(int type, bool incSlash = true) + { + if (type == Types::None) + return QString::null; + + // This array MUST be in the same order + // as the ThemeType enum + const char *typeNames[] = { + "apm", "cal", "clock", + "fs", "host", "mail", + "mem", "swap", "timer", + "uptime", "net", "inet", 0 + }; + + QString returnString; + returnString.setLatin1(typeNames[type]); + return incSlash ? returnString + QString::fromLatin1("/") : returnString; + } + } +} +#endif |