summaryrefslogtreecommitdiffstats
path: root/superkaramba/src
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit2bda8f7717adf28da4af0d34fb82f63d2868c31d (patch)
tree8d927b7b47a90c4adb646482a52613f58acd6f8c /superkaramba/src
downloadtdeutils-2bda8f7717adf28da4af0d34fb82f63d2868c31d.tar.gz
tdeutils-2bda8f7717adf28da4af0d34fb82f63d2868c31d.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdeutils@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'superkaramba/src')
-rw-r--r--superkaramba/src/Makefile.am54
-rw-r--r--superkaramba/src/bar.cpp134
-rw-r--r--superkaramba/src/bar.h55
-rw-r--r--superkaramba/src/bar_python.cpp168
-rw-r--r--superkaramba/src/bar_python.h316
-rw-r--r--superkaramba/src/clickable.cpp37
-rw-r--r--superkaramba/src/clickable.h46
-rw-r--r--superkaramba/src/clickarea.cpp107
-rw-r--r--superkaramba/src/clickarea.h69
-rw-r--r--superkaramba/src/clickmap.cpp96
-rw-r--r--superkaramba/src/clickmap.h43
-rw-r--r--superkaramba/src/config_python.cpp182
-rw-r--r--superkaramba/src/config_python.h138
-rw-r--r--superkaramba/src/cpusensor.cpp167
-rw-r--r--superkaramba/src/cpusensor.h44
-rw-r--r--superkaramba/src/datesensor.cpp129
-rw-r--r--superkaramba/src/datesensor.h47
-rw-r--r--superkaramba/src/dcopinterface.h37
-rw-r--r--superkaramba/src/disksensor.cpp175
-rw-r--r--superkaramba/src/disksensor.h51
-rw-r--r--superkaramba/src/graph.cpp74
-rw-r--r--superkaramba/src/graph.h39
-rw-r--r--superkaramba/src/graph_python.cpp137
-rw-r--r--superkaramba/src/graph_python.h289
-rw-r--r--superkaramba/src/imagelabel.cpp632
-rw-r--r--superkaramba/src/imagelabel.h191
-rw-r--r--superkaramba/src/imagelabel_python.cpp331
-rw-r--r--superkaramba/src/imagelabel_python.h449
-rw-r--r--superkaramba/src/input.cpp196
-rw-r--r--superkaramba/src/input.h84
-rw-r--r--superkaramba/src/input_python.cpp355
-rw-r--r--superkaramba/src/input_python.h475
-rw-r--r--superkaramba/src/karamba.cpp2098
-rw-r--r--superkaramba/src/karamba.h363
-rw-r--r--superkaramba/src/karamba_python.cpp635
-rw-r--r--superkaramba/src/karamba_python.h85
-rw-r--r--superkaramba/src/karambaapp.cpp427
-rw-r--r--superkaramba/src/karambaapp.h95
-rw-r--r--superkaramba/src/karambainterface.cpp153
-rw-r--r--superkaramba/src/karambainterface.h42
-rw-r--r--superkaramba/src/karambalistboxitem.cpp25
-rw-r--r--superkaramba/src/karambalistboxitem.h31
-rw-r--r--superkaramba/src/karambarootpixmap.cpp36
-rw-r--r--superkaramba/src/karambarootpixmap.h39
-rw-r--r--superkaramba/src/karambasessionmanaged.cpp63
-rw-r--r--superkaramba/src/karambasessionmanaged.h30
-rw-r--r--superkaramba/src/kwidgetlistbox.cpp200
-rw-r--r--superkaramba/src/kwidgetlistbox.h68
-rw-r--r--superkaramba/src/lineparser.cpp96
-rw-r--r--superkaramba/src/lineparser.h53
-rw-r--r--superkaramba/src/main.cpp156
-rw-r--r--superkaramba/src/memsensor.cpp359
-rw-r--r--superkaramba/src/memsensor.h67
-rw-r--r--superkaramba/src/menu_python.cpp200
-rw-r--r--superkaramba/src/menu_python.h124
-rw-r--r--superkaramba/src/meter.cpp111
-rw-r--r--superkaramba/src/meter.h99
-rw-r--r--superkaramba/src/meter_python.cpp373
-rw-r--r--superkaramba/src/meter_python.h44
-rw-r--r--superkaramba/src/misc_python.cpp852
-rw-r--r--superkaramba/src/misc_python.h606
-rw-r--r--superkaramba/src/networksensor.cpp164
-rw-r--r--superkaramba/src/networksensor.h47
-rw-r--r--superkaramba/src/noatunsensor.cpp234
-rw-r--r--superkaramba/src/noatunsensor.h48
-rw-r--r--superkaramba/src/programsensor.cpp93
-rw-r--r--superkaramba/src/programsensor.h38
-rw-r--r--superkaramba/src/richtextlabel.cpp212
-rw-r--r--superkaramba/src/richtextlabel.h64
-rw-r--r--superkaramba/src/richtextlabel_python.cpp182
-rw-r--r--superkaramba/src/richtextlabel_python.h338
-rw-r--r--superkaramba/src/rsssensor.cpp136
-rw-r--r--superkaramba/src/rsssensor.h39
-rw-r--r--superkaramba/src/sensor.cpp64
-rw-r--r--superkaramba/src/sensor.h47
-rw-r--r--superkaramba/src/sensorparams.cpp34
-rw-r--r--superkaramba/src/sensorparams.h48
-rw-r--r--superkaramba/src/sensorsensor.cpp115
-rw-r--r--superkaramba/src/sensorsensor.h49
-rw-r--r--superkaramba/src/showdesktop.cpp123
-rw-r--r--superkaramba/src/showdesktop.h58
-rw-r--r--superkaramba/src/sklineedit.cpp82
-rw-r--r--superkaramba/src/sklineedit.h57
-rw-r--r--superkaramba/src/sknewstuff.cpp140
-rw-r--r--superkaramba/src/sknewstuff.h53
-rw-r--r--superkaramba/src/superkaramba.desktop99
-rw-r--r--superkaramba/src/superkaramba.kcfg16
-rw-r--r--superkaramba/src/superkaramba.lsm16
-rw-r--r--superkaramba/src/superkarambasettings.kcfgc4
-rw-r--r--superkaramba/src/superkarambaui.rc8
-rw-r--r--superkaramba/src/svcgrp_python.cpp156
-rw-r--r--superkaramba/src/svcgrp_python.h44
-rw-r--r--superkaramba/src/systemtray.cpp231
-rw-r--r--superkaramba/src/systemtray.h69
-rw-r--r--superkaramba/src/systray_python.cpp199
-rw-r--r--superkaramba/src/systray_python.h117
-rw-r--r--superkaramba/src/task_python.cpp375
-rw-r--r--superkaramba/src/task_python.h153
-rw-r--r--superkaramba/src/taskbartest.cpp183
-rw-r--r--superkaramba/src/taskbartest.h23
-rw-r--r--superkaramba/src/taskmanager.cpp829
-rw-r--r--superkaramba/src/taskmanager.h550
-rw-r--r--superkaramba/src/textfield.cpp159
-rw-r--r--superkaramba/src/textfield.h59
-rw-r--r--superkaramba/src/textfilesensor.cpp109
-rw-r--r--superkaramba/src/textfilesensor.h53
-rw-r--r--superkaramba/src/textlabel.cpp379
-rw-r--r--superkaramba/src/textlabel.h87
-rw-r--r--superkaramba/src/textlabel_python.cpp235
-rw-r--r--superkaramba/src/textlabel_python.h397
-rw-r--r--superkaramba/src/themefile.cpp414
-rw-r--r--superkaramba/src/themefile.h107
-rw-r--r--superkaramba/src/themelocale.cpp438
-rw-r--r--superkaramba/src/themelocale.h61
-rw-r--r--superkaramba/src/themes_layout.ui241
-rw-r--r--superkaramba/src/themesdlg.cpp543
-rw-r--r--superkaramba/src/themesdlg.h80
-rw-r--r--superkaramba/src/themewidget.cpp113
-rw-r--r--superkaramba/src/themewidget.h57
-rw-r--r--superkaramba/src/themewidget_layout.ui182
-rw-r--r--superkaramba/src/uptimesensor.cpp119
-rw-r--r--superkaramba/src/uptimesensor.h30
-rw-r--r--superkaramba/src/widget_python.cpp214
-rw-r--r--superkaramba/src/widget_python.h131
-rw-r--r--superkaramba/src/xmmssensor.cpp149
-rw-r--r--superkaramba/src/xmmssensor.h38
126 files changed, 22809 insertions, 0 deletions
diff --git a/superkaramba/src/Makefile.am b/superkaramba/src/Makefile.am
new file mode 100644
index 0000000..90c9aa3
--- /dev/null
+++ b/superkaramba/src/Makefile.am
@@ -0,0 +1,54 @@
+# set the include path for X, qt and KDE
+INCLUDES = $(all_includes) $(XMMS_INCLUDES) $(PYTHONINC)
+
+# these are the headers for your project
+noinst_HEADERS = karamba.h karambaapp.h karamba_python.h lineparser.h \
+ themefile.h themesdlg.h themewidget.h kwidgetlistbox.h themelocale.h input.h \
+ sklineedit.h input_python.h
+
+KDE_OPTIONS = nofinal
+
+# let automoc handle all of the meta source files (moc)
+METASOURCES = AUTO
+
+messages: rc.cpp
+ $(EXTRACTRC) *.ui >> rc.cpp
+ $(XGETTEXT) *.cpp -o $(podir)/superkaramba.pot
+
+#########################################################################
+# APPLICATION SECTION
+#########################################################################
+# this is the program that gets installed. its name is used for all
+# of the other Makefile.am variables
+bin_PROGRAMS = superkaramba
+
+# the application source, library search path, and link libraries
+superkaramba_SOURCES = main.cpp karamba.cpp meter.cpp bar.cpp sensor.cpp \
+ datesensor.cpp textlabel.cpp memsensor.cpp uptimesensor.cpp cpusensor.cpp \
+ networksensor.cpp imagelabel.cpp graph.cpp xmmssensor.cpp programsensor.cpp \
+ disksensor.cpp sensorparams.cpp sensorsensor.cpp textfilesensor.cpp clickarea.cpp \
+ noatunsensor.cpp karambarootpixmap.cpp clickmap.cpp rsssensor.cpp textfield.cpp \
+ taskmanager.cpp showdesktop.cpp richtextlabel.cpp karambasessionmanaged.cpp \
+ systemtray.cpp bar_python.cpp meter_python.cpp textlabel_python.cpp \
+ richtextlabel_python.cpp imagelabel_python.cpp config_python.cpp misc_python.cpp \
+ systray_python.cpp task_python.cpp widget_python.cpp menu_python.cpp \
+ karambalistboxitem.cpp graph_python.cpp dcopinterface.skel dcopinterface.stub \
+ karambainterface.cpp karambaapp.cpp karamba_python.cpp lineparser.cpp themefile.cpp \
+ themesdlg.cpp themes_layout.ui themewidget_layout.ui themewidget.cpp \
+ kwidgetlistbox.cpp sknewstuff.h sknewstuff.cpp superkarambasettings.kcfgc themelocale.cpp \
+ input.cpp sklineedit.cpp input_python.cpp svcgrp_python.cpp
+
+# kde_cfg_DATA = superkaramba.kcfg
+
+superkaramba_LDFLAGS = -Wl,-export-dynamic $(KDE_RPATH) $(all_libraries) $(PYTHONLIB) $(XMMS_LDFLAGS)
+#superkaramba_LDADD = -lkio $(LIB_KDEUI) $(XMMS_LDADD) $(LIBPYTHON) $(LIBKVM) $(MY_LIBKNEWSTUFF)
+superkaramba_LDADD = -lkio $(LIB_KDEUI) $(XMMS_LIBS) $(LIBPYTHON) $(LIBKVM) $(MY_LIBKNEWSTUFF)
+
+# this is where the desktop file will go
+shelldesktopdir = $(kde_appsdir)/Utilities
+shelldesktop_DATA = superkaramba.desktop
+
+# this is where the shell's XML-GUI resource file goes
+shellrcdir = $(kde_datadir)/superkaramba
+shellrc_DATA = superkarambaui.rc
+
diff --git a/superkaramba/src/bar.cpp b/superkaramba/src/bar.cpp
new file mode 100644
index 0000000..354433d
--- /dev/null
+++ b/superkaramba/src/bar.cpp
@@ -0,0 +1,134 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Hans Karlsson *
+ * karlsson.h@home.se *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+
+#include "bar.h"
+#include "karamba.h"
+
+Bar::Bar(karamba* k, int x, int y, int w, int h) : Meter(k, x, y, w, h)
+{
+ value = 0;
+ minValue = 0;
+ maxValue = 100;
+ barValue = 0;
+ vertical = false;
+}
+
+Bar::~Bar()
+{
+}
+
+bool Bar::setImage(QString fileName)
+{
+ QFileInfo fileInfo(fileName);
+ bool res = false;
+
+ if(m_karamba->theme().isThemeFile(fileName))
+ {
+ QByteArray ba = m_karamba->theme().readThemeFile(fileName);
+ res = pixmap.loadFromData(ba);
+ }
+ else
+ {
+ res = pixmap.load(fileName);
+ }
+ pixmapWidth = pixmap.width();
+ pixmapHeight = pixmap.height();
+
+ if(getWidth()==0 || getHeight()==0)
+ {
+ setWidth(pixmapWidth);
+ setHeight(pixmapHeight);
+ }
+ if(res)
+ imagePath = fileName;
+ return res;
+}
+
+void Bar::setValue( long v )
+{
+ if(v > maxValue)
+ {
+ // maxValue = v;
+ v = maxValue;
+ }
+
+ if(v < minValue)
+ {
+ //minValue = v;
+ v = minValue;
+ }
+
+ barValue = v;
+
+ long diff = maxValue - minValue;
+ if(diff != 0)
+ {
+ if(vertical)
+ {
+ value = long((v-minValue)*getHeight() / diff + 0.5);
+ }
+ else // horizontal
+ {
+ value = long((v-minValue)*getWidth() / diff + 0.5);
+ }
+ }
+ else
+ {
+ value = 0;
+ }
+}
+
+void Bar::setValue(QString v)
+{
+ setValue((long)(v.toDouble() + 0.5));
+}
+
+void Bar::setMax(long m)
+{
+ Meter::setMax(m);
+ recalculateValue();
+}
+
+void Bar::setMin(long m)
+{
+ Meter::setMin(m);
+ recalculateValue();
+}
+
+void Bar::setVertical(bool b)
+{
+ vertical = b;
+}
+
+void Bar::mUpdate(QPainter *p)
+{
+ int x, y, width, height;
+ x = getX();
+ y = getY();
+ width = getWidth();
+ height = getHeight();
+ //only draw image if not hidden
+ if(hidden == 0)
+ {
+ if(vertical)
+ {
+ // int v = int( (value-minValue)*height / (maxValue-minValue) + 0.5 );
+ p->drawTiledPixmap(x, y+height-value, width, value, pixmap, 0,
+ pixmapHeight-value);
+ }
+ else // horizontal
+ {
+ //int v = int( (value-minValue)*width / (maxValue-minValue) + 0.5 );
+ p->drawTiledPixmap(x, y, value, height, pixmap);
+ }
+ }
+}
+
+#include "bar.moc"
diff --git a/superkaramba/src/bar.h b/superkaramba/src/bar.h
new file mode 100644
index 0000000..d23ac3e
--- /dev/null
+++ b/superkaramba/src/bar.h
@@ -0,0 +1,55 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Hans Karlsson *
+ * karlsson.h@home.se *
+ * *
+ * 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. *
+ ***************************************************************************/
+#ifndef BAR_H
+#define BAR_H
+
+#include "meter.h"
+#include <qpixmap.h>
+#include <qstring.h>
+#include <qpainter.h>
+
+class Bar : public Meter
+{
+Q_OBJECT
+public:
+ Bar(karamba* k,int ix,int iy,int iw,int ih );
+ ~Bar();
+
+ void mUpdate( QPainter * );
+
+ virtual void setMax( long m );
+ virtual void setMin( long m );
+
+public slots:
+ bool setImage( QString imagePath );
+ QString getImage() { return imagePath; };
+
+ void setValue( long );
+ long getValue() { return barValue; };
+ void setValue( QString );
+ void recalculateValue() {setValue(barValue); };
+
+ void setVertical( bool );
+ int getVertical() { return vertical; };
+
+private:
+ long barValue;
+ long value;
+
+ int pixmapWidth;
+ int pixmapHeight;
+
+ bool vertical; // vertical bar?
+
+ QString imagePath;
+ QPixmap pixmap;
+}
+;
+#endif // BAR_H
diff --git a/superkaramba/src/bar_python.cpp b/superkaramba/src/bar_python.cpp
new file mode 100644
index 0000000..fa94f85
--- /dev/null
+++ b/superkaramba/src/bar_python.cpp
@@ -0,0 +1,168 @@
+/****************************************************************************
+* bar_python.cpp - Functions for bar python api
+*
+* Copyright (c) 2004 Petri Damstn <damu@iki.fi>
+*
+* This file is part of SuperKaramba.
+*
+* SuperKaramba 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.
+*
+* SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+#ifdef _XOPEN_SOURCE
+#undef _XOPEN_SOURCE
+#endif
+
+#include <Python.h>
+#include <qobject.h>
+#include "karamba.h"
+#include "meter.h"
+#include "meter_python.h"
+#include "bar_python.h"
+
+PyObject* py_createBar(PyObject *, PyObject *args)
+{
+ long widget, x, y, w, h;
+ char *text;
+ if (!PyArg_ParseTuple(args, (char*)"lllll|s", &widget, &x, &y, &w, &h, &text))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+
+ Bar *tmp = new Bar((karamba*)widget, x,y,w,h);
+ if (text && text[0] != '\0')
+ tmp->setImage(text);
+ ((karamba*)widget)->meterList->append(tmp);
+ return (Py_BuildValue((char*)"l", (long)tmp));
+}
+
+PyObject* py_deleteBar(PyObject *, PyObject *args)
+{
+ long widget, meter;
+ if (!PyArg_ParseTuple(args, (char*)"ll", &widget, &meter))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, "Bar"))
+ return NULL;
+
+ ((karamba*)widget)->deleteMeterFromSensors((Meter*)meter);
+ return Py_BuildValue((char*)"l",
+ ((karamba*)widget)->meterList->removeRef((Meter*)meter));
+}
+
+PyObject* py_getThemeBar(PyObject *self, PyObject *args)
+{
+ return py_getThemeMeter(self, args, "Bar");
+}
+
+PyObject* py_getBarSize(PyObject *self, PyObject *args)
+{
+ return py_getSize(self, args, "Bar");
+}
+
+PyObject* py_resizeBar(PyObject *self, PyObject *args)
+{
+ return py_resize(self, args, "Bar");
+}
+
+PyObject* py_getBarPos(PyObject *self, PyObject *args)
+{
+ return py_getPos(self, args, "Bar");
+}
+
+PyObject* py_moveBar(PyObject *self, PyObject *args)
+{
+ return py_move(self, args, "Bar");
+}
+
+PyObject* py_hideBar(PyObject *self, PyObject *args)
+{
+ return py_hide(self, args, "Bar");
+}
+
+PyObject* py_showBar(PyObject *self, PyObject *args)
+{
+ return py_show(self, args, "Bar");
+}
+
+PyObject* py_getBarMinMax(PyObject *self, PyObject *args)
+{
+ return py_getMinMax(self, args, "Bar");
+}
+
+PyObject* py_setBarMinMax(PyObject *self, PyObject *args)
+{
+ return py_setMinMax(self, args, "Bar");
+}
+
+PyObject* py_getBarValue(PyObject *self, PyObject *args)
+{
+ return py_getValue(self, args, "Bar");
+}
+
+PyObject* py_setBarValue(PyObject *self, PyObject *args)
+{
+ return py_setValue(self, args, "Bar");
+}
+
+PyObject* py_getBarSensor(PyObject *self, PyObject *args)
+{
+ return py_getSensor(self, args, "Bar");
+}
+
+PyObject* py_setBarSensor(PyObject *self, PyObject *args)
+{
+ return py_setSensor(self, args, "Bar");
+}
+
+PyObject* py_getBarImage(PyObject *, PyObject *args)
+{
+ long widget, meter;
+ if (!PyArg_ParseTuple(args, (char*)"ll", &widget, &meter))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, "Bar"))
+ return NULL;
+ return Py_BuildValue((char*)"s", ((Bar*)meter)->getImage().ascii());
+}
+
+PyObject* py_setBarImage(PyObject *, PyObject *args)
+{
+ long widget, meter;
+ char* s;
+ if (!PyArg_ParseTuple(args, (char*)"lls", &widget, &meter, &s))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, "Bar"))
+ return NULL;
+ return Py_BuildValue((char*)"l", ((Bar*)meter)->setImage(s));
+}
+
+PyObject* py_getBarVertical(PyObject *, PyObject *args)
+{
+ long widget, meter;
+ if (!PyArg_ParseTuple(args, (char*)"ll", &widget, &meter))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, "Bar"))
+ return NULL;
+ return Py_BuildValue((char*)"l", ((Bar*)meter)->getVertical());
+}
+
+PyObject* py_setBarVertical(PyObject *, PyObject *args)
+{
+ long widget, meter, l;
+ if (!PyArg_ParseTuple(args, (char*)"lll", &widget, &meter, &l))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, "Bar"))
+ return NULL;
+ ((Bar*)meter)->setVertical(l);
+ return Py_BuildValue((char*)"l", 1);
+}
diff --git a/superkaramba/src/bar_python.h b/superkaramba/src/bar_python.h
new file mode 100644
index 0000000..0d5d428
--- /dev/null
+++ b/superkaramba/src/bar_python.h
@@ -0,0 +1,316 @@
+/****************************************************************************
+* bar_python.cpp - Functions for bar python api
+*
+* Copyright (c) 2004 Petri Damstn <damu@iki.fi>
+*
+* This file is part of SuperKaramba.
+*
+* SuperKaramba 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.
+*
+* SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+#ifndef BAR_PYTHON_H
+#define BAR_PYTHON_H
+
+/** Bar/createBar
+*
+* SYNOPSIS
+* long createBar(widget, x, y, w, h, image)
+* DESCRIPTION
+* This creates a bar at x,y with width and height w,h.
+* ARGUMENTS
+* * long widget -- karamba
+* * long x -- x coordinate
+* * long y -- y coordinate
+* * long w -- width
+* * long h -- height
+* * string image -- Path to image
+* RETURN VALUE
+* Pointer to new bar meter
+*/
+PyObject* py_createBar(PyObject *self, PyObject *args);
+
+/** Bar/deleteBar
+*
+* SYNOPSIS
+* long deleteBar(widget, bar)
+* DESCRIPTION
+* This deletes bar.
+* ARGUMENTS
+* * long widget -- karamba
+* * long widget -- bar
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_deleteBar(PyObject *self, PyObject *args);
+
+/** Bar/getThemeBar
+*
+* SYNOPSIS
+* long getThemeBar(widget, name)
+* DESCRIPTION
+* You can reference bar in your python code that was created in the
+* theme file. Basically, you just add a NAME= value to the BAR line in
+* the .theme file. Then if you want to use that object, instead of calling
+* createBar, you can call this function.
+*
+* The name you pass to the function is the same one that you gave it for
+* the NAME= parameter in the .theme file.
+* ARGUMENTS
+* * long widget -- karamba
+* * string name -- name of the bar to get
+* RETURN VALUE
+* Pointer to bar
+*/
+PyObject* py_getThemeBar(PyObject *self, PyObject *args);
+
+/** Bar/getBarSize
+*
+* SYNOPSIS
+* tuple getBarSize(widget, bar)
+* DESCRIPTION
+* Given a reference to a bar object, this will return a tuple
+* containing the height and width of a bar object.
+* ARGUMENTS
+* * long widget -- karamba
+* * long bar -- pointer to bar
+* RETURN VALUE
+* size
+*/
+PyObject* py_getBarSize(PyObject *self, PyObject *args);
+
+/** Bar/resizeBar
+*
+* SYNOPSIS
+* long resizeBar(widget, bar, w, h)
+* DESCRIPTION
+* This will resize bar to new height and width.
+* ARGUMENTS
+* * long widget -- karamba
+* * long bar -- pointer to bar
+* * long w -- new width
+* * long h -- new height
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_resizeBar(PyObject *self, PyObject *args);
+
+/** Bar/getBarPos
+*
+* SYNOPSIS
+* tuple getBarPos(widget, bar)
+* DESCRIPTION
+* Given a reference to a bar object, this will return a tuple
+* containing the x and y coordinate of a bar object.
+* ARGUMENTS
+* * long widget -- karamba
+* * long bar -- pointer to bar
+* RETURN VALUE
+* pos
+*/
+PyObject* py_getBarPos(PyObject *self, PyObject *args);
+
+/** Bar/moveBar
+*
+* SYNOPSIS
+* long moveBar(widget, bar, x, y)
+* DESCRIPTION
+* This will move bar to new x and y coordinates.
+* ARGUMENTS
+* * long widget -- karamba
+* * long bar -- pointer to bar
+* * long x -- x coordinate
+* * long y -- y coordinate
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_moveBar(PyObject *self, PyObject *args);
+
+/** Bar/hideBar
+*
+* SYNOPSIS
+* long hideBar(widget, bar)
+* DESCRIPTION
+* This hides an bar. In other words, during subsequent calls to
+* widgetUpdate(), this bar will not be drawn.
+* ARGUMENTS
+* * long widget -- karamba
+* * long bar -- pointer to bar
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_hideBar(PyObject *self, PyObject *args);
+
+/** Bar/showBar
+*
+* SYNOPSIS
+* long showBar(widget, bar)
+* DESCRIPTION
+* This shows an bar. In other words, during subsequent calls to
+* widgetUpdate(), this bar will be drawn.
+* ARGUMENTS
+* * long widget -- karamba
+* * long bar -- pointer to bar
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_showBar(PyObject *self, PyObject *args);
+
+/** Bar/getBarValue
+*
+* SYNOPSIS
+* long getBarValue(widget, bar)
+* DESCRIPTION
+* Returns current bar value.
+* ARGUMENTS
+* * long widget -- karamba
+* * long bar -- pointer to bar
+* RETURN VALUE
+* value
+*/
+PyObject* py_getBarValue(PyObject *self, PyObject *args);
+
+/** Bar/setBarValue
+*
+* SYNOPSIS
+* long setBarValue(widget, bar, value)
+* DESCRIPTION
+* Sets current bar value.
+* ARGUMENTS
+* * long widget -- karamba
+* * long bar -- pointer to bar
+* * long value -- new value
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_setBarValue(PyObject *self, PyObject *args);
+
+/** Bar/getBarMinMax
+*
+* SYNOPSIS
+* tuple getBarMinMax(widget, bar)
+* DESCRIPTION
+* Returns current bar value.
+* ARGUMENTS
+* * long widget -- karamba
+* * long bar -- pointer to bar
+* RETURN VALUE
+* min & max
+*/
+PyObject* py_getBarMinMax(PyObject *self, PyObject *args);
+
+/** Bar/setBarMinMax
+*
+* SYNOPSIS
+* long setBarMinMax(widget, bar, min, max)
+* DESCRIPTION
+* Returns current bar value.
+* ARGUMENTS
+* * long widget -- karamba
+* * long bar -- pointer to bar
+* * long min -- min value
+* * long max -- max value
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_setBarMinMax(PyObject *self, PyObject *args);
+
+/** Bar/getBarSensor
+*
+* SYNOPSIS
+* string getBarSensor(widget, bar)
+* DESCRIPTION
+* Get current sensor string
+* ARGUMENTS
+* * long widget -- karamba
+* * long bar -- pointer to bar
+* RETURN VALUE
+* sensor string
+*/
+PyObject* py_getBarSensor(PyObject *self, PyObject *args);
+
+/** Bar/setBarSensor
+*
+* SYNOPSIS
+* long setBarSensor(widget, bar, sensor)
+* DESCRIPTION
+* Get current sensor string
+* ARGUMENTS
+* * long widget -- karamba
+* * long bar -- pointer to bar
+* * string sensor -- new sensor as in theme files
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_setBarSensor(PyObject *self, PyObject *args);
+
+/** Bar/getBarImage
+*
+* SYNOPSIS
+* string getBarImage(widget, bar)
+* DESCRIPTION
+* Get bar image
+* ARGUMENTS
+* * long widget -- karamba
+* * long bar -- pointer to bar
+* RETURN VALUE
+* path to bar image
+*/
+PyObject* py_getBarImage(PyObject *self, PyObject *args);
+
+/** Bar/setBarImage
+*
+* SYNOPSIS
+* long setBarImage(widget, bar, image)
+* DESCRIPTION
+* Get bar image
+* ARGUMENTS
+* * long widget -- karamba
+* * long bar -- pointer to bar
+* * string image -- new image
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_setBarImage(PyObject *self, PyObject *args);
+
+/** Bar/getBarVertical
+*
+* SYNOPSIS
+* string getBarVertical(widget, bar)
+* DESCRIPTION
+* Check if bar is vertical bar
+* ARGUMENTS
+* * long widget -- karamba
+* * long bar -- pointer to bar
+* RETURN VALUE
+* 1 if vertical
+*/
+PyObject* py_getBarVertical(PyObject *self, PyObject *args);
+
+/** Bar/setBarVertical
+*
+* SYNOPSIS
+* long setBarVertical(widget, bar)
+* DESCRIPTION
+* Set bar vertical
+* ARGUMENTS
+* * long widget -- karamba
+* * long bar -- pointer to bar
+* * long vertical -- 1 if vertical
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_setBarVertical(PyObject *self, PyObject *args);
+
+#endif // BAR_PYTHON_H
diff --git a/superkaramba/src/clickable.cpp b/superkaramba/src/clickable.cpp
new file mode 100644
index 0000000..ac3ae1b
--- /dev/null
+++ b/superkaramba/src/clickable.cpp
@@ -0,0 +1,37 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Ralph M. Churchill *
+ * mrchucho@yahoo.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+
+#include "clickable.h"
+
+
+Clickable::Clickable( int x, int y, int w, int h )
+{
+ boundingBox = QRect( x, y, w, h );
+}
+
+Clickable::~Clickable()
+{}
+
+/*
+void Clickable::setOnClick( QString oc )
+{
+ onClick = oc;
+}
+
+void Clickable::setOnMiddleClick( QString oc )
+{
+ onMiddleClick = oc;
+}
+*/
+
+QRect Clickable::getBoundingBox()
+{
+ return boundingBox;
+}
diff --git a/superkaramba/src/clickable.h b/superkaramba/src/clickable.h
new file mode 100644
index 0000000..f549893
--- /dev/null
+++ b/superkaramba/src/clickable.h
@@ -0,0 +1,46 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Ralph M. Churchill *
+ * mrchucho@yahoo.com *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef CLICKABLE_H
+#define CLICKABLE_H
+
+#include <qstring.h>
+#include <qrect.h>
+#include <qevent.h>
+
+
+/**
+ *
+ * Ralph M. Churchill
+ **/
+class Clickable
+{
+public:
+ Clickable(int x, int y, int w, int h );
+
+ virtual ~Clickable();
+
+ virtual void click( QMouseEvent* ) = 0;
+ /*
+ void setOnClick( QString );
+ void setOnMiddleClick( QString );
+ */
+
+ virtual QRect getBoundingBox();
+
+protected:
+ QRect boundingBox;
+ /*
+ QString onClick;
+ QString onMiddleClick;
+ */
+};
+
+#endif
diff --git a/superkaramba/src/clickarea.cpp b/superkaramba/src/clickarea.cpp
new file mode 100644
index 0000000..d060b4d
--- /dev/null
+++ b/superkaramba/src/clickarea.cpp
@@ -0,0 +1,107 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Hans Karlsson *
+ * karlsson.h@home.se *
+ * *
+ * Copyright (C) 2004,2005 Luke Kenneth Casson Leighton <lkcl@lkcl.net> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "clickarea.h"
+
+#include <kservicegroup.h>
+
+
+ClickArea::ClickArea(karamba* k, int x, int y, int w, int h )
+ : Meter(k, x, y, w, h )
+{
+ value = "";
+ rect = QRect( x, y, w, h );
+}
+
+ClickArea::~ClickArea()
+{}
+
+
+bool ClickArea::click( QMouseEvent *e )
+{
+ if( rect.contains( e->x(), e->y() ) )
+ {
+ //qDebug(QString::number(e->type()));
+ //KShellProcess ksp;
+ if( e->button() != Qt::LeftButton )
+ return false;
+ if (!svc_name.isEmpty())
+ {
+ KService sv(svc_name, svc_onClick, svc_icon);
+ KURL::List l;
+ KRun::run(sv, l);
+ return false;
+ }
+ else
+ {
+ QString program;
+ program = onClick;
+ program.replace( QRegExp("%v", false), value );
+
+ if( !program.isEmpty() )
+ {
+ //qDebug(program);
+ KRun::runCommand(program);
+ }
+ }
+ }
+ return false;
+}
+
+void ClickArea::setOnClick( QString oc )
+{
+ onClick = oc;
+}
+
+void ClickArea::setServiceOnClick( QString name , QString exec, QString icon )
+{
+ svc_name = name;
+ svc_onClick = exec;
+ svc_icon = icon;
+}
+
+void ClickArea::setOnMiddleClick( QString oc )
+{
+ onMiddleClick = oc;
+}
+
+
+QRect ClickArea::getRectangle()
+{
+ return rect;
+}
+
+void ClickArea::mUpdate( QPainter *p )
+{
+
+ p->drawRect(boundingBox);
+
+}
+
+
+void ClickArea::setValue( long v)
+{
+
+ setValue( QString::number( v ) );
+
+}
+
+
+void ClickArea::setValue( QString v )
+{
+ value = v;
+}
+
+
+
+
+
+#include "clickarea.moc"
diff --git a/superkaramba/src/clickarea.h b/superkaramba/src/clickarea.h
new file mode 100644
index 0000000..80625ee
--- /dev/null
+++ b/superkaramba/src/clickarea.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+ * Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+ * Copyright (c) 2005 Ryan Nickell <p0z3r@earthlink.net>
+ *
+ * This file is part of SuperKaramba.
+ *
+ * SuperKaramba 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.
+ *
+ * SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+#ifndef CLICKAREA_H
+#define CLICKAREA_H
+
+#include <qstring.h>
+#include <qrect.h>
+#include <qevent.h>
+#include <qregexp.h>
+
+#include <kprocess.h>
+#include <kprocio.h>
+#include <krun.h>
+
+#include <meter.h>
+#include "clickable.h"
+/**
+ *
+ * Hans Karlsson
+ **/
+class ClickArea : public Meter
+{
+ Q_OBJECT
+public:
+ ClickArea(karamba* k, int x, int y, int w, int h );
+
+ ~ClickArea();
+
+ virtual bool click( QMouseEvent* );
+ void setOnClick( QString );
+ void setServiceOnClick( QString , QString, QString);
+ void setOnMiddleClick( QString );
+
+
+ QRect getRectangle();
+
+ void mUpdate( QPainter* );
+ void setValue( long );
+ void setValue( QString );
+
+ QRect rect;
+ QString onClick;
+ QString svc_onClick;
+ QString svc_name;
+ QString svc_icon;
+ QString onMiddleClick;
+ QString value;
+};
+
+#endif
diff --git a/superkaramba/src/clickmap.cpp b/superkaramba/src/clickmap.cpp
new file mode 100644
index 0000000..62b4376
--- /dev/null
+++ b/superkaramba/src/clickmap.cpp
@@ -0,0 +1,96 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Ralph M. Churchill *
+ * mrchucho@yahoo.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+
+#include "clickmap.h"
+#include <qregexp.h>
+#include <krun.h>
+
+ClickMap::ClickMap(karamba* k, int x, int y, int w, int h )
+ :Meter(k, x, y, w, h )
+{
+/*
+ if( h != 0 || w != 0)
+ clip = 0;
+ else
+ clip = Qt::DontClip;
+*/
+
+ if( h == 0 || w == 0)
+ {
+ setWidth(-1);
+ setHeight(-1);
+ }
+}
+
+ClickMap::~ClickMap()
+{
+}
+
+void ClickMap::setTextProps( TextField *t )
+{
+ text = *t;
+}
+
+bool ClickMap::click( QMouseEvent *e ) {
+
+ //Don't load the web page if the click isn't for us
+ if (boundingBox.contains(e->x(), e->y())) {
+
+ int index = ((e -> y() - getY()) / text.getLineHeight()) + 1;
+ if (index >= 1 && index <= (int)displays.count()) {
+ // qDebug( "You clicked item " + QString::number( index ) + ", " +
+ // displays[index - 1] + " " + links[index - 1] );
+ KRun::runCommand("konqueror " + links[index - 1]);
+ }
+ }
+ return false;
+}
+
+void ClickMap::mUpdate( QPainter *p )
+{
+ int i = 0; //text.getLineHeight();
+ int row = 1;
+
+ p->setFont(text.getFont());
+ QStringList::Iterator it = displays.begin();
+ while( it != displays.end() && (row <= getHeight() || getHeight() == -1 ) )
+ {
+ p->setPen( text.getColor() );
+ // p->drawText(x,y+i,width,height, Qt::AlignCenter | Qt::ExpandTabs, *it);
+ p->drawText(getX(), getY() + i + text.getLineHeight(), *it);
+ i += text.getLineHeight();
+ it++;
+ row++;
+ }
+}
+
+void ClickMap::setValue( QString v )
+{
+ QRegExp rx("^http://", false );
+ if ( rx.search( v ) == -1 )
+ {
+ displays.append( v );
+ }
+ else
+ {
+ links.append( v );
+ }
+}
+
+void ClickMap::setValue( long v )
+{
+ if ( v == 0 )
+ {
+ links.clear();
+ displays.clear();
+ }
+}
+
+#include "clickmap.moc"
diff --git a/superkaramba/src/clickmap.h b/superkaramba/src/clickmap.h
new file mode 100644
index 0000000..f6df0db
--- /dev/null
+++ b/superkaramba/src/clickmap.h
@@ -0,0 +1,43 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Ralph M. Churchill *
+ * mrchucho@yahoo.com *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef CLICKMAP_H
+#define CLICKMAP_H
+
+#include <meter.h>
+#include "clickable.h"
+#include "textfield.h"
+
+
+/**
+ *
+ * Ralph M. Churchill
+ **/
+class ClickMap : public Meter
+{
+Q_OBJECT
+public:
+ ClickMap(karamba* k, int x, int y, int w, int h);
+ ~ClickMap();
+
+ virtual bool click( QMouseEvent* );
+ void mUpdate( QPainter* );
+ void setValue( QString );
+ void setValue( long );
+ void setTextProps( TextField * );
+
+private:
+ TextField text;
+
+ QStringList links;
+ QStringList displays;
+};
+
+#endif
diff --git a/superkaramba/src/config_python.cpp b/superkaramba/src/config_python.cpp
new file mode 100644
index 0000000..28d5364
--- /dev/null
+++ b/superkaramba/src/config_python.cpp
@@ -0,0 +1,182 @@
+/****************************************************************************
+* config_python.cpp - Functions for config python api
+*
+* Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+* Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+* Copyright (c) 2004 Petri Damstn <damu@iki.fi>
+*
+* This file is part of SuperKaramba.
+*
+* SuperKaramba 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.
+*
+* SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+#ifdef _XOPEN_SOURCE
+#undef _XOPEN_SOURCE
+#endif
+
+#include <Python.h>
+#include <qobject.h>
+#include "karamba.h"
+#include "meter.h"
+#include "meter_python.h"
+#include "config_python.h"
+
+// API-Function addMenuConfigOption
+long addMenuConfigOption(long widget, QString key, QString name)
+{
+ karamba* currTheme = (karamba*)widget;
+
+ currTheme -> addMenuConfigOption(key, name);
+
+ return 1;
+}
+
+PyObject* py_add_menu_config_option(PyObject *, PyObject *args)
+{
+ long widget;
+ char* key;
+ PyObject* name;
+
+ if (!PyArg_ParseTuple(args, (char*)"lsO:addMenuConfigOption", &widget, &key, &name))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+
+ QString k, n;
+ k.setAscii(key);
+ n = PyString2QString(name);
+
+ return Py_BuildValue((char*)"l", addMenuConfigOption(widget, k, n));
+}
+
+long setMenuConfigOption(long widget, QString key, bool value)
+{
+ karamba* currTheme = (karamba*)widget;
+
+ return currTheme -> setMenuConfigOption(key, value);
+}
+
+PyObject* py_set_menu_config_option(PyObject *, PyObject *args)
+{
+ long widget;
+ char* key;
+ int value;
+
+ if (!PyArg_ParseTuple(args, (char*)"lsi:setMenuConfigOption", &widget, &key, &value))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+
+ QString k;
+ k.setAscii(key);
+
+ return Py_BuildValue((char*)"l", setMenuConfigOption(widget, k, (bool)value));
+}
+
+long readMenuConfigOption(long widget, QString key)
+{
+ karamba* currTheme = (karamba*)widget;
+
+ return currTheme -> readMenuConfigOption(key);
+}
+
+PyObject* py_read_menu_config_option(PyObject *, PyObject *args)
+{
+ long widget;
+ char* key;
+
+ if (!PyArg_ParseTuple(args, (char*)"ls:readMenuConfigOption", &widget, &key))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+
+ QString k;
+ k.setAscii(key);
+
+ return Py_BuildValue((char*)"l", readMenuConfigOption(widget, k));
+}
+
+// API-Function writeConfigEntry
+long writeConfigEntry(long widget, QString key, QString value)
+{
+ karamba* currTheme = (karamba*)widget;
+
+ currTheme -> config -> setGroup("theme");
+ currTheme -> config -> writeEntry(key, value);
+
+ return 1;
+}
+
+PyObject* py_write_config_entry(PyObject *, PyObject *args)
+{
+ long widget;
+ char* key;
+ char* value;
+
+ if (!PyArg_ParseTuple(args, (char*)"lss:writeConfigEntry", &widget, &key, &value))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ QString k, v;
+ k.setAscii(key);
+ v.setAscii(value);
+
+ return Py_BuildValue((char*)"l", writeConfigEntry(widget, k, value));
+}
+
+// API-Function readConfigEntry
+QVariant readConfigEntry(long widget, QString key)
+{
+ karamba* currTheme = (karamba*)widget;
+
+ currTheme -> config -> setGroup("theme");
+ return currTheme -> config -> readEntry(key);
+}
+
+PyObject* py_read_config_entry(PyObject *, PyObject *args)
+{
+ long widget;
+ char* key;
+ if (!PyArg_ParseTuple(args, (char*)"ls:readConfigEntry", &widget, &key))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ QString k;
+ k.setAscii(key);
+
+ QVariant entry = readConfigEntry(widget, k);
+ QString type;
+ type.setAscii(entry.typeName());
+
+ if (type == "Bool")
+ {
+ return Py_BuildValue((char*)"l", (int)entry.toBool());
+ }
+
+ bool isint = false;
+ int i = entry.toInt(&isint);
+ if (isint)
+ {
+ return Py_BuildValue((char*)"l", i);
+ }
+
+ if (type == "QString")
+ {
+ return Py_BuildValue((char*)"s", entry.toString().ascii());
+ }
+ // Add more types if needed
+ return NULL;
+}
+
diff --git a/superkaramba/src/config_python.h b/superkaramba/src/config_python.h
new file mode 100644
index 0000000..c22a032
--- /dev/null
+++ b/superkaramba/src/config_python.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+* config_python.h - Functions for config python api
+*
+* Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+* Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+* Copyright (c) 2004 Petri Damstn <damu@iki.fi>
+*
+* This file is part of SuperKaramba.
+*
+* SuperKaramba 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.
+*
+* SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+#ifndef CONFIG_PYTHON_H
+#define CONFIG_PYTHON_H
+
+/** Config/addMenuConfigOption
+*
+* SYNOPSIS
+* long addMenuConfigOption(widget, key, name)
+* DESCRIPTION
+* SuperKaramba supports a simplistic configuration pop-up menu. This menu
+* appears when you right-click on a widget and choose Configure Theme.
+* Basically, it allows you to have check-able entrys in the menu to allow
+* the user to enable or disable features in your theme.
+*
+* Before you use any configuration menu stuff, you NEED to add a new
+* callback to your script:
+*
+* def menuOptionChanged(widget, key, value):
+*
+* This will get called whenever a config menu option is changed. Now you
+* can add items to the config menu:
+*
+* addMenuConfigOption(widget, String key, String name)
+*
+* Key is the name of a key value where the value will be saved
+* automatically into the widget's config file. Name is the actual text that
+* will show up in the config menu.
+*
+* For example, I could allow the user to enable or disable a clock showing
+* up in my theme:
+*
+* karamba.addMenuConfigOption(widget, "showclock", "Display a clock")
+* ARGUMENTS
+* * long widget -- karamba
+* * string key -- key for menu item
+* * string name -- name of the graph to get
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_add_menu_config_option(PyObject *self, PyObject *args);
+
+/** Config/setMenuConfigOption
+*
+* SYNOPSIS
+* long setMenuConfigOption(widget, key, value)
+* DESCRIPTION
+* This sets whether or not the given option is checked in the theme's
+* Configure Theme menu. Value should be 0 if key should not be checked and
+* 1 if key should be checked.
+*
+* See addMenuConfigOption for a more detailed explanation.
+* ARGUMENTS
+* * long widget -- karamba
+* * string key -- key for menu item
+* * int value -- 1 if checked
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_set_menu_config_option(PyObject *self, PyObject *args);
+
+/** Config/readMenuConfigOption
+*
+* SYNOPSIS
+* long readMenuConfigOption(widget, key)
+* DESCRIPTION
+* This returns whether or not the given option is checked in the theme's
+* Configure Theme menu.
+*
+* See addMenuConfigOption for a more detailed explanation.
+* ARGUMENTS
+* * long widget -- karamba
+* * string key -- key for menu item
+* RETURN VALUE
+* 0 is returned if it is not checked and 1 is returned if it is.
+*/
+PyObject* py_read_menu_config_option(PyObject *self, PyObject *args);
+
+/** Config/writeConfigEntry
+*
+* SYNOPSIS
+* long writeConfigEntry(widget, key, value)
+* DESCRIPTION
+* SuperKaramba automatically supports configuration files for each theme.
+* These files will be saved in /your/home/dir/.superkaramba/ and will be
+* named themenamerc where themename is the name of the theme.
+*
+* This function writes an entry into the config file with the given key and
+* value.
+*
+* For example, to save my favorite color, I would do
+* karamba.writeConfigEntry(widget, "FavColor", "Red")
+* ARGUMENTS
+* * long widget -- karamba
+* * string key -- key for config item
+* * string value -- config value
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_write_config_entry(PyObject *self, PyObject *args);
+
+/** Config/readConfigEntry
+*
+* SYNOPSIS
+* string|long readConfigEntry(widget, key, value)
+* DESCRIPTION
+* This function reads an entry from the config file with the given key.
+* ARGUMENTS
+* * long widget -- karamba
+* * string key -- key for config item
+* RETURN VALUE
+* config value for key
+*/
+PyObject* py_read_config_entry(PyObject *self, PyObject *args);
+
+#endif // CONFIG_PYTHON_H
diff --git a/superkaramba/src/cpusensor.cpp b/superkaramba/src/cpusensor.cpp
new file mode 100644
index 0000000..bc4b095
--- /dev/null
+++ b/superkaramba/src/cpusensor.cpp
@@ -0,0 +1,167 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Hans Karlsson *
+ * karlsson.h@home.se *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+
+#include <qglobal.h>
+
+#ifdef __FreeBSD__
+#include <sys/time.h>
+#include <sys/dkstat.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/resource.h>
+#endif
+
+#if defined(Q_OS_NETBSD)
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/sched.h>
+#endif
+
+#include "cpusensor.h"
+
+CPUSensor::CPUSensor( QString cpu, int interval ) :
+ Sensor(interval), userTicks(0), sysTicks(0), niceTicks(0), idleTicks(0)
+{
+ cpuNbr = cpu;
+ QRegExp rx("^\\d+$");
+ if( rx.search( cpu.lower() ) == -1)
+ cpuNbr = "";
+ cpuNbr = "cpu"+cpuNbr;
+ getCPULoad();
+}
+
+CPUSensor::~CPUSensor()
+{
+}
+
+void CPUSensor::getTicks (long &u,long &s,long &n,long &i)
+{
+#ifdef __FreeBSD__
+ static long cp_time[CPUSTATES];
+
+ size_t size = sizeof(cp_time);
+
+ /* get the cp_time array */
+ if (sysctlbyname("kern.cp_time", &cp_time, &size, NULL, 0) != -1) {
+ u = cp_time[CP_USER];
+ s = cp_time[CP_SYS] + cp_time[CP_INTR];
+ n = cp_time[CP_NICE];
+ i = cp_time[CP_IDLE];
+ }
+#else
+#if defined(Q_OS_NETBSD)
+ static uint64_t cp_time[CPUSTATES];
+
+ size_t size = sizeof(cp_time);
+
+ /* get the cp_time array */
+ if (sysctlbyname("kern.cp_time", &cp_time, &size, NULL, 0) != -1) {
+ u = cp_time[CP_USER];
+ s = cp_time[CP_SYS] + cp_time[CP_INTR];
+ n = cp_time[CP_NICE];
+ i = cp_time[CP_IDLE];
+ }
+#else
+ QFile file("/proc/stat");
+ QString line;
+ if ( file.open(IO_ReadOnly | IO_Translate) )
+ {
+ QTextStream t( &file ); // use a text stream
+ QRegExp rx( cpuNbr+"\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)");
+ line = t.readLine();
+ rx.search( line );
+ while( (line = t.readLine()) !=0 && rx.cap(0) == "" )
+ {
+ rx.search( line );
+ }
+ //user
+ u = rx.cap(1).toLong();
+ //nice
+ n = rx.cap(2).toLong();
+ //system
+ s = rx.cap(3).toLong();
+ //idle
+ i = rx.cap(4).toLong();
+ file.close();
+ }
+#endif
+#endif
+ else
+ {
+ u = 0;
+ s = 0;
+ n = 0;
+ i = 0;
+ }
+}
+
+int CPUSensor::getCPULoad()
+{
+ long uTicks, sTicks, nTicks, iTicks;
+
+ getTicks(uTicks, sTicks, nTicks, iTicks);
+
+ const long totalTicks = ((uTicks - userTicks) +
+ (sTicks - sysTicks) +
+ (nTicks - niceTicks) +
+ (iTicks - idleTicks));
+
+ int load = (totalTicks == 0) ? 0 : (int) ( 100.0 * ( (uTicks+sTicks+nTicks) - (userTicks+sysTicks+niceTicks))/( totalTicks+0.001) + 0.5 );
+ user = (totalTicks == 0) ? 0 : (int) ( 100.0 * ( uTicks - userTicks)/( totalTicks+0.001) + 0.5 );
+ idle = (totalTicks == 0) ? 0 : (int) ( 100.0 * ( iTicks - idleTicks)/( totalTicks+0.001) + 0.5 );
+ system = (totalTicks == 0) ? 0 : (int) ( 100.0 * ( sTicks - sysTicks)/( totalTicks+0.001) + 0.5 );
+ nice = (totalTicks == 0) ? 0 : (int) ( 100.0 * ( nTicks - niceTicks)/( totalTicks+0.001) + 0.5 );
+
+ userTicks = uTicks;
+ sysTicks = sTicks;
+ niceTicks = nTicks;
+ idleTicks = iTicks;
+
+ return load;
+}
+
+void CPUSensor::update()
+{
+ SensorParams *sp;
+ Meter *meter;
+ QString format;
+ int load = getCPULoad();
+
+ QObjectListIt it( *objList );
+ while (it != 0)
+ {
+ sp = (SensorParams*)(*it);
+ meter = sp->getMeter();
+ format = sp->getParam( "FORMAT" );
+
+ if( format.length() == 0)
+ {
+ format = "%v";
+ }
+ format.replace( QRegExp("%load", false), QString::number( load ) );
+ format.replace( QRegExp("%user", false), QString::number( user ) );
+ format.replace( QRegExp("%nice", false), QString::number( nice ) );
+ format.replace( QRegExp("%idle", false), QString::number( idle ) );
+ format.replace( QRegExp("%system", false), QString::number( system ) );
+ format.replace( QRegExp("%v", false), QString::number( load ) );
+
+ meter->setValue( format );
+ ++it;
+ }
+}
+
+void CPUSensor::setMaxValue( SensorParams *sp )
+{
+ Meter *meter;
+ meter = sp->getMeter();
+ meter->setMax( 100 );
+}
+
+#include "cpusensor.moc"
diff --git a/superkaramba/src/cpusensor.h b/superkaramba/src/cpusensor.h
new file mode 100644
index 0000000..5b857f6
--- /dev/null
+++ b/superkaramba/src/cpusensor.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Hans Karlsson *
+ * karlsson.h@home.se *
+ * *
+ * 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. *
+ ***************************************************************************/
+#ifndef CPUSENSOR_H
+#define CPUSENSOR_H
+#include "sensor.h"
+
+#include <qfile.h>
+#include <qregexp.h>
+
+class CPUSensor : public Sensor
+{
+ Q_OBJECT
+public:
+ CPUSensor( QString cpuNbr, int interval );
+ ~CPUSensor();
+ void update();
+ void setMaxValue( SensorParams *sp );
+
+ int getCPULoad();
+
+private:
+ long userTicks;
+ long sysTicks;
+ long niceTicks;
+ long idleTicks;
+
+ int user;
+ int system;
+ int nice;
+ int idle;
+
+ void getTicks (long &u,long &s,long &n,long &i);
+ QString cpuNbr;
+
+};
+
+#endif // CPUSENSOR_H
diff --git a/superkaramba/src/datesensor.cpp b/superkaramba/src/datesensor.cpp
new file mode 100644
index 0000000..186f552
--- /dev/null
+++ b/superkaramba/src/datesensor.cpp
@@ -0,0 +1,129 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Hans Karlsson *
+ * karlsson.h@home.se *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "datesensor.h"
+
+#include <qapplication.h>
+DateSensor::DateSensor( int interval ) : Sensor( interval )
+{
+ hidden = true;
+}
+DateSensor::~DateSensor()
+{
+}
+
+void DateSensor::update()
+{
+ QDateTime qdt = QDateTime::currentDateTime();
+ QString format;
+ SensorParams *sp;
+ Meter *meter;
+
+ QObjectListIt it( *objList );
+ while (it != 0)
+ {
+ sp = (SensorParams*)(*it);
+ meter = sp->getMeter();
+ format = sp->getParam("FORMAT");
+
+ if (format.length() == 0 )
+ {
+ format = "hh:mm";
+ }
+ meter->setValue(qdt.toString(format));
+ ++it;
+ }
+}
+
+void DateSensor::slotCalendarDeleted()
+{
+ hidden = true;
+ cal = 0L;
+}
+
+
+DatePicker::DatePicker(QWidget *parent)
+ : QVBox( parent, 0, WType_TopLevel | WDestructiveClose |
+ WStyle_Customize | WStyle_StaysOnTop | WStyle_NoBorder )
+{
+ setFrameStyle( QFrame::PopupPanel | QFrame::Raised );
+ //KWin::setOnAllDesktops( handle(), true );
+ picker = new KDatePicker(this);
+ picker->setCloseButton(true);
+
+ /* name and icon for kicker's taskbar */
+ //setCaption(i18n("Calendar"));
+ //setIcon(SmallIcon("date"));
+}
+
+void DatePicker::keyReleaseEvent(QKeyEvent *e)
+{
+ QVBox::keyReleaseEvent(e);
+ if (e->key() == Qt::Key_Escape)
+ close();
+}
+
+void DateSensor::toggleCalendar(QMouseEvent *ev)
+{
+ QObjectListIt it(*objList);
+ while (it != 0)
+ {
+ SensorParams *sp = (SensorParams*)(*it);
+ Meter *meter = sp->getMeter();
+ QString width = sp->getParam("CALWIDTH");
+ QString height = sp->getParam("CALHEIGHT");
+
+ QRect rect(meter->getX(),meter->getY(),width.toInt(), height.toInt());
+ if (rect.contains( ev->x(), ev->y() ))
+ {
+ if (hidden)
+ {
+ hidden = false;
+ cal = new DatePicker(0);
+
+ connect(cal, SIGNAL(destroyed()), SLOT(slotCalendarDeleted()));
+ QPoint c = (QPoint(ev->x(), ev->y()));
+
+ int w = cal->sizeHint().width();
+ int h = cal->sizeHint().height();
+
+ // make calendar fully visible
+ QRect deskR = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(c));
+
+
+ if (c.y()+h > deskR.bottom()) c.setY(deskR.bottom()-h-1);
+ if (c.x()+w > deskR.right()) c.setX(deskR.right()-w-1);
+ cal->move(c);
+ cal->show();
+
+ }
+ else
+ {
+ cal->close();
+ }
+ }
+
+ ++it;
+ }
+}
+
+void DateSensor::mousePressEvent(QMouseEvent *ev)
+{
+ switch (ev->button())
+ {
+ case QMouseEvent::LeftButton:
+ toggleCalendar(ev);
+ break;
+ default:
+ break;
+ }
+}
+
+
+#include "datesensor.moc"
diff --git a/superkaramba/src/datesensor.h b/superkaramba/src/datesensor.h
new file mode 100644
index 0000000..75db6e0
--- /dev/null
+++ b/superkaramba/src/datesensor.h
@@ -0,0 +1,47 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Hans Karlsson *
+ * karlsson.h@home.se *
+ * *
+ * 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. *
+ ***************************************************************************/
+#ifndef DATESENSOR_H
+#define DATESENSOR_H
+#include "sensor.h"
+#include "sensorparams.h"
+#include <qdatetime.h>
+#include <kdatepicker.h>
+#include <qvbox.h>
+
+class DatePicker : public QVBox
+{
+public:
+ DatePicker(QWidget*);
+private:
+ KDatePicker *picker;
+ void keyReleaseEvent(QKeyEvent *e);
+};
+
+class DateSensor : public Sensor
+{
+Q_OBJECT
+public:
+ DateSensor( int interval );
+ ~DateSensor();
+
+ void toggleCalendar(QMouseEvent *ev);
+ void mousePressEvent(QMouseEvent *ev);
+ void update();
+
+protected slots:
+ void slotCalendarDeleted();
+
+private:
+ bool hidden;
+ DatePicker* cal;
+
+};
+
+#endif // SENSOR_H
diff --git a/superkaramba/src/dcopinterface.h b/superkaramba/src/dcopinterface.h
new file mode 100644
index 0000000..665187d
--- /dev/null
+++ b/superkaramba/src/dcopinterface.h
@@ -0,0 +1,37 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Petri Damsten *
+ * petri.damsten@iki.fi *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef DCOPINTERFACE_H
+#define DCOPINTERFACE_H
+
+#include <dcopobject.h>
+
+class dcopIface : virtual public DCOPObject
+{
+ K_DCOP
+public:
+
+k_dcop:
+ virtual ASYNC openTheme(QString file) = 0;
+ virtual ASYNC openNamedTheme(QString file, QString name, bool is_sub_theme) = 0;
+ virtual ASYNC closeTheme(QString name) = 0;
+ virtual ASYNC quit() = 0;
+ virtual ASYNC hideSystemTray(bool hide) = 0;
+ virtual ASYNC showThemeDialog() = 0;
+
+ virtual int themeAdded(QString appId, QString file) = 0;
+ virtual ASYNC themeClosed(QString appId, QString file, int instance) = 0;
+ virtual ASYNC themeNotify(QString name, QString text) = 0;
+ virtual ASYNC setIncomingData(QString name, QString obj) = 0;
+ virtual bool isMainKaramba() = 0;
+
+};
+
+#endif // DCOPINTERFACE_H
diff --git a/superkaramba/src/disksensor.cpp b/superkaramba/src/disksensor.cpp
new file mode 100644
index 0000000..b8b9b96
--- /dev/null
+++ b/superkaramba/src/disksensor.cpp
@@ -0,0 +1,175 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Hans Karlsson *
+ * karlsson.h@home.se *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "disksensor.h"
+
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qstring.h>
+#include <qregexp.h>
+#include <kprocess.h>
+#include <kprocio.h>
+
+DiskSensor::DiskSensor( int msec ) : Sensor( msec )
+{
+ connect(&ksp, SIGNAL(receivedStdout(KProcess *, char *, int )),
+ this,SLOT(receivedStdout(KProcess *, char *, int )));
+ connect(&ksp, SIGNAL(processExited(KProcess *)),
+ this,SLOT(processExited( KProcess * )));
+
+ // update values on startup
+ ksp.clearArguments();
+ ksp << "df";
+ ksp.start( KProcIO::Block,KProcIO::Stdout);
+ init = 1;
+}
+DiskSensor::~DiskSensor()
+{}
+
+long DiskSensor::getFreeSpace(QString mntPt) const
+{
+ QRegExp rx( "^\\S*\\s*\\d+\\s+\\d+\\s+(\\d+)");
+ rx.search(mntMap[mntPt]);
+ return rx.cap(1).toLong();
+}
+
+long DiskSensor::getUsedSpace(QString mntPt) const
+{
+ QRegExp rx( "^\\S*\\s*\\d+\\s+(\\d+)\\s+\\d+");
+ rx.search(mntMap[mntPt]);
+ return rx.cap(1).toLong();
+}
+
+long DiskSensor::getTotalSpace(QString mntPt) const
+{
+
+ QRegExp rx( "^\\S*\\s*(\\d+)\\s+\\d+\\s+\\d+");
+ rx.search(mntMap[mntPt]);
+
+ return rx.cap(1).toLong();
+
+}
+
+int DiskSensor::getPercentUsed(QString mntPt) const
+{
+ QRegExp rx( "\\s+(\\d+)%\\s+");
+ rx.search(mntMap[mntPt]);
+ return rx.cap(1).toInt();
+}
+
+int DiskSensor::getPercentFree(QString mntPt) const
+{
+ return ( 100 - getPercentUsed( mntPt ) );
+}
+
+void DiskSensor::receivedStdout(KProcess *, char *buffer, int len )
+{
+
+ buffer[len] = 0;
+ sensorResult += QString( QCString(buffer) );
+
+}
+
+void DiskSensor::processExited(KProcess *)
+{
+ QStringList stringList = QStringList::split('\n',sensorResult);
+ sensorResult = "";
+ QStringList::Iterator it = stringList.begin();
+ //QRegExp rx( "^(/dev/).*(/\\S*)$");
+ QRegExp rx( ".*\\s+(/\\S*)$");
+
+ while( it != stringList.end())
+ {
+ rx.search( *it );
+ if ( !rx.cap(0).isEmpty())
+ {
+ mntMap[rx.cap(1)] = *it;
+ }
+ it++;
+ }
+ stringList.clear();
+
+ QString format;
+ QString mntPt;
+ SensorParams *sp;
+ Meter *meter;
+
+ QObjectListIt lit( *objList );
+ while (lit != 0)
+ {
+ sp = (SensorParams*)(*lit);
+ meter = sp->getMeter();
+ format = sp->getParam("FORMAT");
+ mntPt = sp->getParam("MOUNTPOINT");
+ if (mntPt.length() == 0)
+ mntPt="/";
+
+ if (format.length() == 0 )
+ {
+ format = "%u";
+ }
+ format.replace( QRegExp("%fp", false),QString::number(getPercentFree(mntPt)));
+ format.replace( QRegExp("%fg",false),
+ QString::number(getFreeSpace(mntPt)/(1024*1024)));
+ format.replace( QRegExp("%fkb",false),
+ QString::number(getFreeSpace(mntPt)*8) );
+ format.replace( QRegExp("%fk",false),
+ QString::number(getFreeSpace(mntPt)) );
+ format.replace( QRegExp("%f", false),QString::number(getFreeSpace(mntPt)/1024));
+
+ format.replace( QRegExp("%up", false),QString::number(getPercentUsed(mntPt)));
+ format.replace( QRegExp("%ug",false),
+ QString::number(getUsedSpace(mntPt)/(1024*1024)));
+ format.replace( QRegExp("%ukb",false),
+ QString::number(getUsedSpace(mntPt)*8) );
+ format.replace( QRegExp("%uk",false),
+ QString::number(getUsedSpace(mntPt)) );
+ format.replace( QRegExp("%u", false),QString::number(getUsedSpace(mntPt)/1024));
+
+ format.replace( QRegExp("%tg",false),
+ QString::number(getTotalSpace(mntPt)/(1024*1024)));
+ format.replace( QRegExp("%tkb",false),
+ QString::number(getTotalSpace(mntPt)*8));
+ format.replace( QRegExp("%tk",false),
+ QString::number(getTotalSpace(mntPt)));
+ format.replace( QRegExp("%t", false),QString::number(getTotalSpace(mntPt)/1024));
+ meter->setValue(format);
+ ++lit;
+ }
+ if ( init == 1 )
+ {
+ emit initComplete();
+ init = 0;
+ }
+}
+
+void DiskSensor::update()
+{
+ ksp.clearArguments();
+ ksp << "df";
+ ksp.start( KProcIO::NotifyOnExit,KProcIO::Stdout);
+}
+
+void DiskSensor::setMaxValue( SensorParams *sp )
+{
+ Meter *meter;
+ meter = sp->getMeter();
+ const QString mntPt = sp->getParam( "MOUNTPOINT" );
+
+ QString f;
+ f = sp->getParam("FORMAT");
+ if( f == "%fp" || f == "%up" )
+ meter->setMax( 100 );
+ else
+ meter->setMax( getTotalSpace( mntPt ) / 1024 );
+}
+
+
+
+#include "disksensor.moc"
diff --git a/superkaramba/src/disksensor.h b/superkaramba/src/disksensor.h
new file mode 100644
index 0000000..e35b9d8
--- /dev/null
+++ b/superkaramba/src/disksensor.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Hans Karlsson *
+ * karlsson.h@home.se *
+ * *
+ * 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. *
+ ***************************************************************************/
+#ifndef DISKSENSOR_H
+#define DISKSENSOR_H
+#include "sensor.h"
+#include <qmap.h>
+#include <qstring.h>
+#include <qtextcodec.h>
+#include <qregexp.h>
+#include <qstringlist.h>
+#include <kprocess.h>
+class DiskSensor : public Sensor
+{
+Q_OBJECT
+public:
+ DiskSensor(int msec );
+ ~DiskSensor();
+ void update();
+ void setMaxValue( SensorParams *sp );
+
+private:
+ long getFreeSpace(QString mntPt) const;
+ long getUsedSpace(QString mntPt) const;
+ long getTotalSpace(QString mntPt) const;
+ int getPercentUsed(QString mntPt) const;
+ int getPercentFree(QString mntPt) const;
+
+ KShellProcess ksp;
+ QString sensorResult;
+
+ QMap<QString,QString> mntMap;
+ QStringList stringList;
+
+ int init;
+
+private slots:
+ void receivedStdout(KProcess *, char *buffer, int);
+ void processExited(KProcess *);
+
+signals:
+ void initComplete();
+
+};
+#endif // DISKSENSOR_H
diff --git a/superkaramba/src/graph.cpp b/superkaramba/src/graph.cpp
new file mode 100644
index 0000000..c028aea
--- /dev/null
+++ b/superkaramba/src/graph.cpp
@@ -0,0 +1,74 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Hans Karlsson *
+ * karlsson.h@home.se *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+
+#include "graph.h"
+#include <qstring.h>
+
+Graph::Graph(karamba* k, int x, int y, int w, int h, int nbrPts):
+ Meter(k, x, y, w, h), lastValue(0)
+{
+
+ nbrPoints = (nbrPts==0)? 50:nbrPts ;
+ ptPtr = 0;
+ values = new int[nbrPoints];
+ for(int i = 0; i < nbrPoints; i++)
+ values[i] = 0;
+ minValue = 0;
+ maxValue = 100;
+}
+
+Graph::~Graph()
+{
+ delete[] values;
+}
+
+void Graph::setValue( long v)
+{
+ if( v > maxValue)
+ {
+ // maxValue = v;
+ v = maxValue;
+ }
+ if( v < minValue)
+ {
+ //minValue = v;
+ v = minValue;
+ }
+ lastValue = v;
+ values[ptPtr] = (int) (v / (maxValue + 0.0001) * getHeight());
+ ptPtr = (ptPtr + 1) % nbrPoints;
+}
+
+void Graph::setValue( QString v )
+{
+ setValue((long)(v.toDouble() + 0.5));
+}
+
+void Graph::mUpdate(QPainter *p)
+{
+ if (hidden == 0)
+ {
+ double step = (getWidth() / (nbrPoints-1.001));
+ double xPos = 0;
+ double nextXPos = 0;
+ p->setPen(color);
+ for (int i = 0; i < nbrPoints - 1 ; i ++)
+ {
+ nextXPos = xPos + step;
+ p->drawLine(getX() + (int)xPos, getY()+getHeight() -
+ (int) values[(ptPtr+i) % nbrPoints] ,
+ getX() + (int)nextXPos, getY()+getHeight() -
+ (int) values[(ptPtr + i +1) % nbrPoints] );
+ xPos = nextXPos;
+ }
+ }
+}
+
+#include "graph.moc"
diff --git a/superkaramba/src/graph.h b/superkaramba/src/graph.h
new file mode 100644
index 0000000..626b569
--- /dev/null
+++ b/superkaramba/src/graph.h
@@ -0,0 +1,39 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Hans Karlsson *
+ * karlsson.h@home.se *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef GRAPH_H
+#define GRAPH_H
+
+#include "meter.h"
+#include <qpainter.h>
+#include <qcolor.h>
+
+class Graph : public Meter
+{
+Q_OBJECT
+
+public:
+ Graph(karamba* k, int ix, int iy, int iw, int ih, int nbrPoints);
+ Graph();
+ ~Graph();
+
+ void setValue( long );
+ long getValue() { return lastValue; };
+ void setValue( QString );
+ void mUpdate( QPainter * );
+
+private:
+ int lastValue;
+ int* values;
+ int nbrPoints;
+ int ptPtr; // points to the array position
+};
+
+#endif // GRAPH_H
diff --git a/superkaramba/src/graph_python.cpp b/superkaramba/src/graph_python.cpp
new file mode 100644
index 0000000..1ef6e73
--- /dev/null
+++ b/superkaramba/src/graph_python.cpp
@@ -0,0 +1,137 @@
+/****************************************************************************
+* graph_python.h - Functions for graph python api
+*
+* Copyright (c) 2004 Petri Damstn <damu@iki.fi>
+*
+* This file is part of SuperKaramba.
+*
+* SuperKaramba 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.
+*
+* SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+#ifdef _XOPEN_SOURCE
+#undef _XOPEN_SOURCE
+#endif
+
+#include <Python.h>
+#include <qobject.h>
+#include "karamba.h"
+#include "meter.h"
+#include "meter_python.h"
+#include "graph_python.h"
+
+PyObject* py_createGraph(PyObject *, PyObject *args)
+{
+ long widget, x, y, w, h, points;
+
+ if (!PyArg_ParseTuple(args, (char*)"llllll", &widget, &x, &y, &w, &h, &points))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+
+ Graph *tmp =
+ new Graph((karamba*)widget, (int)x, (int)y, (int)w, (int)h, (int)points);
+ ((karamba*)widget)->meterList->append(tmp);
+ return (Py_BuildValue((char*)"l", (long)tmp));
+}
+
+PyObject* py_deleteGraph(PyObject *, PyObject *args)
+{
+ long widget, meter;
+ if (!PyArg_ParseTuple(args, (char*)"ll", &widget, &meter))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, "Graph"))
+ return NULL;
+
+ ((karamba*)widget)->deleteMeterFromSensors((Meter*)meter);
+ return Py_BuildValue((char*)"l",
+ ((karamba*)widget)->meterList->removeRef((Meter*)meter));
+}
+
+PyObject* py_getThemeGraph(PyObject *self, PyObject *args)
+{
+ return py_getThemeMeter(self, args, "Graph");
+}
+
+PyObject* py_getGraphSize(PyObject *self, PyObject *args)
+{
+ return py_getSize(self, args, "Graph");
+}
+
+PyObject* py_resizeGraph(PyObject *self, PyObject *args)
+{
+ return py_resize(self, args, "Graph");
+}
+
+PyObject* py_getGraphPos(PyObject *self, PyObject *args)
+{
+ return py_getPos(self, args, "Graph");
+}
+
+PyObject* py_moveGraph(PyObject *self, PyObject *args)
+{
+ return py_move(self, args, "Graph");
+}
+
+PyObject* py_hideGraph(PyObject *self, PyObject *args)
+{
+ return py_hide(self, args, "Graph");
+}
+
+PyObject* py_showGraph(PyObject *self, PyObject *args)
+{
+ return py_show(self, args, "Graph");
+}
+
+PyObject* py_getGraphMinMax(PyObject *self, PyObject *args)
+{
+ return py_getMinMax(self, args, "Graph");
+}
+
+PyObject* py_setGraphMinMax(PyObject *self, PyObject *args)
+{
+ return py_setMinMax(self, args, "Graph");
+}
+
+PyObject* py_getGraphValue(PyObject *self, PyObject *args)
+{
+ return py_getValue(self, args, "Graph");
+}
+
+PyObject* py_setGraphValue(PyObject *self, PyObject *args)
+{
+ return py_setValue(self, args, "Graph");
+}
+
+PyObject* py_getGraphSensor(PyObject *self, PyObject *args)
+{
+ return py_getSensor(self, args, "Graph");
+}
+
+PyObject* py_setGraphSensor(PyObject *self, PyObject *args)
+{
+ return py_setSensor(self, args, "Graph");
+}
+
+PyObject* py_getGraphColor(PyObject *self, PyObject *args)
+{
+ return py_getColor(self, args, "Graph");
+}
+
+PyObject* py_setGraphColor(PyObject *self, PyObject *args)
+{
+ return py_setColor(self, args, "Graph");
+}
+
+
diff --git a/superkaramba/src/graph_python.h b/superkaramba/src/graph_python.h
new file mode 100644
index 0000000..e635c07
--- /dev/null
+++ b/superkaramba/src/graph_python.h
@@ -0,0 +1,289 @@
+/****************************************************************************
+* graph_python.cpp - Functions for graph python api
+*
+* Copyright (c) 2004 Petri Damstn <damu@iki.fi>
+*
+* This file is part of SuperKaramba.
+*
+* SuperKaramba 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.
+*
+* SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+#ifndef GRAPH_PYTHON_H
+#define GRAPH_PYTHON_H
+
+/** Graph/createGraph
+*
+* SYNOPSIS
+* long createGraph(widget, x, y, w, h, points)
+* DESCRIPTION
+* This creates a graph at x,y with width and height w,h.
+* ARGUMENTS
+* * long widget -- karamba
+* * long x -- x coordinate
+* * long y -- y coordinate
+* * long w -- width
+* * long h -- height
+* * long points -- Number of points in graph
+* RETURN VALUE
+* Pointer to new graph meter
+*/
+PyObject* py_createGraph(PyObject *self, PyObject *args);
+
+/** Graph/deleteGraph
+*
+* SYNOPSIS
+* long deleteGraph(widget, graph)
+* DESCRIPTION
+* This deletes graph.
+* ARGUMENTS
+* * long widget -- karamba
+* * long widget -- graph
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_deleteGraph(PyObject *self, PyObject *args);
+
+/** Graph/getThemeGraph
+*
+* SYNOPSIS
+* long getThemeGraph(widget, name)
+* DESCRIPTION
+* You can reference graph in your python code that was created in the
+* theme file. Basically, you just add a NAME= value to the GRAPH line in
+* the .theme file. Then if you want to use that object, instead of calling
+* createGraph, you can call this function.
+*
+* The name you pass to the function is the same one that you gave it for
+* the NAME= parameter in the .theme file.
+* ARGUMENTS
+* * long widget -- karamba
+* * string name -- name of the graph to get
+* RETURN VALUE
+* Pointer to graph
+*/
+PyObject* py_getThemeGraph(PyObject *self, PyObject *args);
+
+/** Graph/getGraphSize
+*
+* SYNOPSIS
+* tuple getGraphSize(widget, graph)
+* DESCRIPTION
+* Given a reference to a graph object, this will return a tuple
+* containing the height and width of a graph object.
+* ARGUMENTS
+* * long widget -- karamba
+* * long graph -- pointer to graph
+* RETURN VALUE
+* size
+*/
+PyObject* py_getGraphSize(PyObject *self, PyObject *args);
+
+/** Graph/resizeGraph
+*
+* SYNOPSIS
+* long resizeGraph(widget, graph, w, h)
+* DESCRIPTION
+* This will resize graph to new height and width.
+* ARGUMENTS
+* * long widget -- karamba
+* * long graph -- pointer to graph
+* * long w -- new width
+* * long h -- new height
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_resizeGraph(PyObject *self, PyObject *args);
+
+/** Graph/getGraphPos
+*
+* SYNOPSIS
+* tuple getGraphPos(widget, graph)
+* DESCRIPTION
+* Given a reference to a graph object, this will return a tuple
+* containing the x and y coordinate of a graph object.
+* ARGUMENTS
+* * long widget -- karamba
+* * long graph -- pointer to graph
+* RETURN VALUE
+* pos
+*/
+PyObject* py_getGraphPos(PyObject *self, PyObject *args);
+
+/** Graph/moveGraph
+*
+* SYNOPSIS
+* long moveGraph(widget, graph, x, y)
+* DESCRIPTION
+* This will move graph to new x and y coordinates.
+* ARGUMENTS
+* * long widget -- karamba
+* * long graph -- pointer to graph
+* * long x -- x coordinate
+* * long y -- y coordinate
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_moveGraph(PyObject *self, PyObject *args);
+
+/** Graph/hideGraph
+*
+* SYNOPSIS
+* long hideGraph(widget, graph)
+* DESCRIPTION
+* This hides an graph. In other words, during subsequent calls to
+* widgetUpdate(), this graph will not be drawn.
+* ARGUMENTS
+* * long widget -- karamba
+* * long graph -- pointer to graph
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_hideGraph(PyObject *self, PyObject *args);
+
+/** Graph/showGraph
+*
+* SYNOPSIS
+* long showGraph(widget, graph)
+* DESCRIPTION
+* This shows an graph. In other words, during subsequent calls to
+* widgetUpdate(), this graph will be drawn.
+* ARGUMENTS
+* * long widget -- karamba
+* * long graph -- pointer to graph
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_showGraph(PyObject *self, PyObject *args);
+
+/** Graph/getGraphValue
+*
+* SYNOPSIS
+* long getGraphValue(widget, graph)
+* DESCRIPTION
+* Returns current graph value.
+* ARGUMENTS
+* * long widget -- karamba
+* * long graph -- pointer to graph
+* RETURN VALUE
+* value
+*/
+PyObject* py_getGraphValue(PyObject *self, PyObject *args);
+
+/** Graph/setGraphValue
+*
+* SYNOPSIS
+* long setGraphValue(widget, graph, value)
+* DESCRIPTION
+* Sets current graph value.
+* ARGUMENTS
+* * long widget -- karamba
+* * long graph -- pointer to graph
+* * long value -- new value
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_setGraphValue(PyObject *self, PyObject *args);
+
+/** Graph/getGraphMinMax
+*
+* SYNOPSIS
+* tuple getGraphMinMax(widget, graph)
+* DESCRIPTION
+* Returns current graph value.
+* ARGUMENTS
+* * long widget -- karamba
+* * long graph -- pointer to graph
+* RETURN VALUE
+* min & max
+*/
+PyObject* py_getGraphMinMax(PyObject *self, PyObject *args);
+
+/** Graph/setGraphMinMax
+*
+* SYNOPSIS
+* long setGraphMinMax(widget, graph, min, max)
+* DESCRIPTION
+* Returns current graph value.
+* ARGUMENTS
+* * long widget -- karamba
+* * long graph -- pointer to graph
+* * long min -- min value
+* * long max -- max value
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_setGraphMinMax(PyObject *self, PyObject *args);
+
+/** Graph/getGraphSensor
+*
+* SYNOPSIS
+* string getGraphSensor(widget, graph)
+* DESCRIPTION
+* Get current sensor string
+* ARGUMENTS
+* * long widget -- karamba
+* * long graph -- pointer to graph
+* RETURN VALUE
+* sensor string
+*/
+PyObject* py_getGraphSensor(PyObject *self, PyObject *args);
+
+/** Graph/setGraphSensor
+*
+* SYNOPSIS
+* long setGraphSensor(widget, graph, sensor)
+* DESCRIPTION
+* Get current sensor string
+* ARGUMENTS
+* * long widget -- karamba
+* * long graph -- pointer to graph
+* * string sensor -- new sensor as in theme files
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_setGraphSensor(PyObject *self, PyObject *args);
+
+/** Graph/getGraphColor
+*
+* SYNOPSIS
+* tuple getGraphColor(widget, graph)
+* DESCRIPTION
+* Get current graph color
+* ARGUMENTS
+* * long widget -- karamba
+* * long graph -- pointer to graph
+* RETURN VALUE
+* (red, green, blue)
+*/
+PyObject* py_getGraphColor(PyObject *self, PyObject *args);
+
+/** Graph/setGraphColor
+*
+* SYNOPSIS
+* tuple setGraphColor(widget, graph, red, green, blue)
+* DESCRIPTION
+* Set current graph color
+* ARGUMENTS
+* * long widget -- karamba
+* * long graph -- pointer to graph
+* * long red -- red component of color
+* * long green -- green component of color
+* * long blue -- blue component of color
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_setGraphColor(PyObject *self, PyObject *args);
+
+#endif // GRAPH_PYTHON_H
diff --git a/superkaramba/src/imagelabel.cpp b/superkaramba/src/imagelabel.cpp
new file mode 100644
index 0000000..9959e8b
--- /dev/null
+++ b/superkaramba/src/imagelabel.cpp
@@ -0,0 +1,632 @@
+/****************************************************************************
+* imagelabel.cpp - ImageLabel meter
+*
+* Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+* Copyright (c) 2004 Petri Damstn <damu@iki.fi>
+*
+* This file is part of SuperKaramba.
+*
+* SuperKaramba 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.
+*
+* SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+#include <qpixmap.h>
+#include <qtimer.h>
+#include <qtooltip.h>
+#include <kpixmapeffect.h>
+#include <kdebug.h>
+#include <kimageeffect.h>
+#include <ktempfile.h>
+#include <kio/job.h>
+#include "karambaapp.h"
+#include "imagelabel.h"
+
+// Effect
+Effect::Effect(ImageLabel* img, int msec) :
+ myImage(img)
+{
+ if (msec > 0)
+ {
+ // remove the effect after the given time
+ //QTimer::singleShot (millisec, myImage, SLOT(slotEffectExpired()));
+ //timer -> changeInterval(millisec);
+ millisec = msec;
+ }
+ else
+ {
+ millisec = msec;
+ }
+}
+
+Effect::~Effect()
+{
+}
+
+void Effect::startTimer()
+{
+ if (millisec > 0)
+ {
+ QTimer::singleShot (millisec, myImage, SLOT(slotEffectExpired()));
+ millisec = 0;
+ }
+}
+
+// Intensity
+Intensity::Intensity(ImageLabel* img, float r, int millisec) :
+ Effect(img, millisec)
+{
+ ratio = r;
+ ratio = (ratio > 1) ? 1 : ratio;
+ ratio = (ratio < -1) ? -1 : ratio;
+}
+
+KPixmap Intensity::apply(KPixmap pixmap)
+{
+ return KPixmapEffect::intensity(pixmap, ratio);
+}
+
+// ChannelIntensity
+ChannelIntensity::ChannelIntensity(ImageLabel* img, float r, QString c,
+ int millisec) :
+ Effect(img, millisec)
+{
+ ratio = r;
+ ratio = (ratio > 1) ? 1 : ratio;
+ ratio = (ratio < -1) ? -1 : ratio;
+
+ channel = 0;
+ if (c.find("red", 0 , false))
+ {
+ channel = 0;
+ }
+ else if (c.find("green", 0, false))
+ {
+ channel = 1;
+ }
+ else if (c.find("blue", 0, false))
+ {
+ channel = 2;
+ }
+}
+
+KPixmap ChannelIntensity::apply(KPixmap pixmap)
+{
+ return KPixmapEffect::channelIntensity(pixmap, ratio,
+ (KPixmapEffect::RGBComponent)channel);
+}
+
+// ToGray
+ToGray::ToGray(ImageLabel* img, int millisec) : Effect(img, millisec)
+{
+}
+
+KPixmap ToGray::apply(KPixmap pixmap)
+{
+ return KPixmapEffect::toGray(pixmap);
+}
+
+/***********************************************************************/
+
+ImageLabel::ImageLabel(karamba* k, int ix,int iy,int iw,int ih) :
+ Meter(k, ix,iy,iw,ih), zoomed(false), rollover(false)
+{
+ background = 0;
+ cblend = 0;
+ //scaleMat.reset();
+ //rotMat.reset();
+ scale_w = 1;
+ scale_h = 1;
+ rot_angle = 0;
+
+ doScale = false;
+ doRotate = false;
+
+ imageEffect = 0;
+}
+
+ImageLabel::ImageLabel(karamba* k) :
+ Meter(k), zoomed(false), rollover(false)
+{
+ cblend = 0;
+ background = 0;
+}
+
+ImageLabel::~ImageLabel()
+{
+ if (imageEffect != 0)
+ {
+ delete imageEffect;
+ imageEffect = 0;
+ }
+ if(!old_tip_rect.isNull())
+ {
+ QToolTip::remove(m_karamba, old_tip_rect);
+ }
+}
+
+void ImageLabel::setValue(long v)
+{
+ setValue( QString::number( v ) );
+}
+
+void ImageLabel::show()
+{
+ Meter::show();
+ setEnabled(true);
+}
+
+void ImageLabel::hide()
+{
+ Meter::hide();
+ setEnabled(false);
+}
+
+void ImageLabel::rotate(int deg)
+{
+ doRotate = !(deg == 0);
+
+ rot_angle = deg;
+
+ applyTransformations();
+}
+
+void ImageLabel::scale(int w, int h)
+{
+ doScale = !(w == realpixmap.width() && h == realpixmap.height());
+
+ scale_w = w;
+ scale_h = h;
+
+ applyTransformations();
+}
+
+void ImageLabel::smoothScale(int w, int h)
+{
+ doScale = !(w == realpixmap.width() && h == realpixmap.height());
+
+ scale_w = w;
+ scale_h = h;
+
+ applyTransformations(true);
+
+// double widthFactor = ((double)w) / ((double)realpixmap.width());
+// double heightFactor = ((double)h) / ((double)realpixmap.height());
+
+// pixmap.convertFromImage(realpixmap.convertToImage().smoothScale(w, h));
+
+// setWidth(pixmap.width());
+// setHeight(pixmap.height());
+
+}
+
+void ImageLabel::removeImageTransformations()
+{
+ doScale = false;
+ doRotate = false;
+
+ scale_w = 1;
+ scale_h = 1;
+ rot_angle = 0;
+ pixmap = realpixmap;
+}
+
+void ImageLabel::applyTransformations(bool useSmoothScale)
+{
+ pixmap = realpixmap;
+ if (doRotate)
+ {
+ // KDE and QT seem to miss a high quality image rotation
+ QWMatrix rotMat;
+ rotMat.rotate(rot_angle);
+ pixmap = pixmap.xForm(rotMat);
+ }
+ if (doScale)
+ {
+ if (m_karamba -> useSmoothTransforms() || useSmoothScale)
+ {
+ pixmap.convertFromImage(
+ pixmap.convertToImage().smoothScale(scale_w, scale_h));
+ }
+ else
+ {
+ double widthFactor = ((double)scale_w) / ((double)pixmap.width());
+ double heightFactor = ((double)scale_h) / ((double)pixmap.height());
+ QWMatrix scaleMat;
+ scaleMat.scale(widthFactor, heightFactor);
+ pixmap = pixmap.xForm(scaleMat);
+ }
+ }
+ if (imageEffect != 0)
+ {
+ pixmap = imageEffect -> apply(pixmap);
+ }
+ setWidth(pixmap.width());
+ setHeight(pixmap.height());
+}
+
+void ImageLabel::slotCopyResult(KIO::Job* job)
+{
+ QString tempFile = ((KIO::FileCopyJob*)job)->destURL().path();
+ if(job->error() == 0)
+ {
+ setValue(tempFile);
+ imagePath = ((KIO::FileCopyJob*)job)->srcURL().path();
+ emit pixmapLoaded();
+ }
+ else
+ {
+ qWarning("Error downloading (%s): %s", job->errorText().ascii(),
+ tempFile.ascii());
+ }
+ KIO::NetAccess::removeTempFile(tempFile);
+}
+
+void ImageLabel::setValue(QString fn)
+{
+ // use the first line
+ QStringList sList = QStringList::split( "\n", fn );
+ QString fileName = *sList.begin();
+ KURL url(fileName);
+ QRegExp rx("^[a-zA-Z]{1,5}:/",false);
+ bool protocol = (rx.search(fileName)!=-1)?true:false;
+ QPixmap pm;
+
+ if(protocol && url.isLocalFile() == false)
+ {
+ KTempFile tmpFile;
+ KIO::FileCopyJob* copy = KIO::file_copy(fileName, tmpFile.name(), 0600,
+ true, false, false);
+ connect(copy, SIGNAL(result(KIO::Job*)),
+ this, SLOT(slotCopyResult(KIO::Job*)));
+ return;
+ }
+ else
+ {
+ if(m_karamba->theme().isThemeFile(fileName))
+ {
+ QByteArray ba = m_karamba->theme().readThemeFile(fileName);
+ pm.loadFromData(ba);
+ }
+ else
+ {
+ pm.load(fileName);
+ }
+ imagePath = fileName;
+ }
+ setValue(pm);
+}
+
+//Matthew Kay: a new version of setValue to be used by createTaskIcon()
+/**
+ * set the internal pixmap of this image to the given QPixmap pix
+ */
+void ImageLabel::setValue(QPixmap& pix)
+{
+ realpixmap = KPixmap(pix);
+ pixmap = realpixmap;
+ setWidth(pixmap.width());
+ setHeight(pixmap.height());
+
+ pixmapWidth = pixmap.width();
+ pixmapHeight = pixmap.height();
+ rect_off = QRect(getX(),getY(),pixmapWidth,pixmapHeight);
+}
+
+void ImageLabel::mUpdate(QPainter* p, int backgroundUpdate)
+{
+ if (backgroundUpdate == 1)
+ {
+ //only draw image if not hidden
+ if (hidden == 0)
+ {
+ if (cblend == 0)
+ //draw the pixmap
+ p->drawPixmap(getX(),getY(),pixmap);
+ else
+ {
+ //Blend this image with a color
+
+ QImage image = pixmap.convertToImage();
+
+ QImage result = KImageEffect::blend(QColor(255,0,0), image, 0.5f);
+ p->drawImage(getX(),getY(),result);
+
+ //p->drawRect(boundingBox);
+ }
+ }
+ // start Timer
+ if (imageEffect != 0)
+ {
+ imageEffect -> startTimer();
+ }
+ }
+}
+
+void ImageLabel::mUpdate(QPainter* p)
+{
+ //only draw image if not hidden
+ if (hidden == 0 && background == 0)
+ {
+ if (cblend == 0)
+ {
+ //draw the pixmap
+ p->drawPixmap(getX(),getY(),pixmap);
+ }
+ else
+ {
+ //Blend this image with a color
+
+ QImage image = pixmap.convertToImage();
+
+ QImage result = KImageEffect::blend(QColor(255,0,0), image, 0.5f);
+ p->drawImage(getX(),getY(),result);
+
+ //p->drawRect(boundingBox);
+ }
+ }
+ // start Timer
+ if (imageEffect != 0)
+ {
+ imageEffect -> startTimer();
+ }
+}
+
+bool ImageLabel::click(QMouseEvent* e)
+{
+ if (getBoundingBox().contains(e -> x(), e -> y()) && isEnabled())
+ {
+ QString program;
+ if (e -> button() == Qt::LeftButton)
+ {
+ program = leftButtonAction;
+ }
+ else if (e -> button() == Qt::MidButton)
+ {
+ program = middleButtonAction;
+ }
+ else if (e -> button() == Qt::RightButton)
+ {
+ program = rightButtonAction;
+ }
+
+ if( !program.isEmpty() )
+ {
+ KRun::runCommand(program);
+ }
+ else
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+void ImageLabel::parseImages(QString fn, QString fn_roll, int _xoff,
+ int _yoff, int _xon, int _yon)
+{
+ //fn = filename;
+ //fn_roll = filename_roll;
+
+ xoff = _xoff;
+ yoff = _yoff;
+ xon = _xon;
+ yon = _yon;
+
+ // use the first line
+ QStringList sList = QStringList::split( "\n", fn );
+ QString fileName = *sList.begin();
+ QFileInfo fileInfo( fileName );
+ QString path;
+
+ QRegExp rx("^http://",false);
+ bool fileOnNet = (rx.search(fileName)!=-1)?true:false;
+
+
+ if( fileInfo.isRelative() && !fileOnNet )
+ {
+ path = m_karamba->theme().path() + "/" + fileName;
+ }
+ else
+ {
+ path = fileName;
+ }
+
+ if ( fileOnNet )
+ {
+ QString tmpFile;
+#if defined(KDE_3_2)
+ if(KIO::NetAccess::download(KURL(path), tmpFile, karambaApp->parentWindow()))
+#else
+ if(KIO::NetAccess::download(KURL(path), tmpFile))
+#endif
+ {
+ pixmap_off = KPixmap(tmpFile);
+ KIO::NetAccess::removeTempFile(tmpFile);
+ qDebug( "Downloaded: %s to %s", path.ascii(), tmpFile.ascii() );
+ }
+ else
+ {
+ qDebug( "Error Downloading: %s", path.ascii());
+ }
+ }
+ else
+ {
+ pixmap_off = KPixmap( path );
+ }
+
+ pixmapOffWidth = pixmap.width();
+ pixmapOffHeight = pixmap.height();
+
+ rect_off = QRect(xoff,yoff,pixmapWidth,pixmapHeight);
+/////////////////////////////
+ if (fn_roll.isEmpty())
+ return;
+
+ rollover=true;
+ sList = QStringList::split( "\n", fn_roll );
+ fileName = *sList.begin();
+ fileInfo = QFileInfo( fileName );
+
+ fileOnNet = (rx.search(fileName)!=-1)?true:false;
+
+
+ if( fileInfo.isRelative() && !fileOnNet )
+ {
+ path = m_karamba->theme().path() + "/" + fileName;
+ }
+ else
+ {
+ path = fileName;
+ }
+
+ if ( fileOnNet )
+ {
+ QString tmpFile;
+#if defined(KDE_3_2)
+ if(KIO::NetAccess::download(KURL(path), tmpFile, karambaApp->parentWindow()))
+#else
+ if(KIO::NetAccess::download(KURL(path), tmpFile))
+#endif
+ {
+ pixmap_on = KPixmap(tmpFile);
+ KIO::NetAccess::removeTempFile(tmpFile);
+ qDebug( "Downloaded: %s to %s", path.ascii(), tmpFile.ascii());
+ }
+ else
+ {
+ qDebug( "Error Downloading: %s", path.ascii());
+ }
+ }
+ else
+ {
+ pixmap_on = KPixmap( path );
+ }
+ pixmapOnWidth = pixmap_on.width();
+ pixmapOnHeight = pixmap_on.height();
+
+ rect_on = QRect(xon,yon,pixmapOnWidth,pixmapOnHeight);
+}
+
+void ImageLabel::setBackground(int b)
+{
+ background = b;
+}
+
+void ImageLabel::rolloverImage(QMouseEvent *e)
+{
+ if (!rollover)
+ return;
+
+ if (zoomed)
+ {
+ if (!rect_off.contains(e->pos()))
+ {
+ // rollover the image to the zoomed image
+ //setValue(fn_roll);
+ setX(xoff);
+ setY(yoff);
+ pixmap = pixmap_off;
+ pixmapWidth = pixmapOffWidth;
+ pixmapHeight = pixmapOffHeight;
+ zoomed = false;
+ m_karamba->step();
+ }
+ }
+ else
+ {
+ if (rect_off.contains(e->pos()))
+ {
+ // rollover the image to the zoomed image
+ //setValue(fn_roll);
+ setX(xon);
+ setY(yon);
+ pixmap = pixmap_on;
+ pixmapWidth = pixmapOnWidth;
+ pixmapHeight = pixmapOnHeight;
+ zoomed = true;
+ m_karamba->step();
+ }
+ }
+}
+
+void ImageLabel::setTooltip(QString txt)
+{
+ QRect rect(getX(),getY(),pixmapWidth,pixmapHeight);
+ QToolTip::add(m_karamba, rect, txt);
+ old_tip_rect = QRect(rect.topLeft(), rect.bottomRight());
+}
+
+
+void ImageLabel::removeEffects()
+{
+ if (imageEffect != 0)
+ {
+ delete imageEffect;
+ imageEffect = 0;
+ }
+ applyTransformations();
+}
+
+void ImageLabel::intensity(float ratio, int millisec)
+{
+ if (imageEffect != 0)
+ {
+ delete imageEffect;
+ imageEffect = 0;
+ }
+ //KPixmapEffect::intensity(pixmap, ratio);
+ imageEffect = new Intensity(this, ratio, millisec);
+ applyTransformations();
+}
+
+void ImageLabel::channelIntensity(float ratio, QString channel, int millisec)
+{
+ if (imageEffect != 0)
+ {
+ delete imageEffect;
+ imageEffect = 0;
+ }
+ //KPixmapEffect::channelIntensity(pixmap, ratio, rgbChannel);
+ imageEffect = new ChannelIntensity(this, ratio, channel, millisec);
+ applyTransformations();
+}
+
+void ImageLabel::toGray(int millisec)
+{
+ if (imageEffect != 0)
+ {
+ delete imageEffect;
+ imageEffect = 0;
+ }
+ //KPixmapEffect::toGray(pixmap);
+ imageEffect = new ToGray(this, millisec);
+ applyTransformations();
+}
+
+void ImageLabel::slotEffectExpired()
+{
+ removeEffects();
+ m_karamba -> externalStep();
+}
+
+void ImageLabel::attachClickArea(QString leftMouseButton,
+ QString middleMouseButton,
+ QString rightMouseButton)
+{
+ leftButtonAction = leftMouseButton;
+ middleButtonAction = middleMouseButton;
+ rightButtonAction = rightMouseButton;
+}
+
+#include "imagelabel.moc"
diff --git a/superkaramba/src/imagelabel.h b/superkaramba/src/imagelabel.h
new file mode 100644
index 0000000..ff2a7ec
--- /dev/null
+++ b/superkaramba/src/imagelabel.h
@@ -0,0 +1,191 @@
+/****************************************************************************
+* imagelabel.h - ImageLabel meter
+*
+* Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+* Copyright (c) 2004 Petri Damstn <damu@iki.fi>
+*
+* This file is part of SuperKaramba.
+*
+* SuperKaramba 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.
+*
+* SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+#ifndef IMAGELABEL_H
+#define IMAGELABEL_H
+
+#include "meter.h"
+#include <kpixmap.h>
+#include <qimage.h>
+#include <qpixmap.h>
+#include <qpainter.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <kurl.h>
+#include <kio/netaccess.h>
+#include <qregexp.h>
+#include <qtimer.h>
+#include "karamba.h"
+
+class ImageLabel;
+class KIO::CopyJob;
+
+// Abstract Effects Baseclass
+class Effect : public QObject
+{
+
+Q_OBJECT
+
+public:
+ Effect(ImageLabel*, int millisec);
+
+ virtual ~Effect();
+
+ virtual KPixmap apply(KPixmap pixmap) = 0;
+
+ void startTimer();
+
+protected:
+ ImageLabel* myImage;
+
+ int millisec;
+};
+
+// Intensity
+class Intensity : public Effect
+{
+public:
+ Intensity(ImageLabel*, float r, int millisec);
+
+ KPixmap apply(KPixmap pixmap);
+
+private:
+ float ratio;
+};
+
+
+// ChannelIntensity
+class ChannelIntensity : public Effect
+{
+public:
+ ChannelIntensity(ImageLabel*, float r, QString c, int millisec);
+
+ KPixmap apply(KPixmap pixmap);
+
+private:
+ float ratio;
+ int channel;
+};
+
+// ToGray
+class ToGray : public Effect
+{
+public:
+ ToGray(ImageLabel*, int millisec);
+
+ KPixmap apply(KPixmap pixmap);
+};
+
+class ImageLabel : public Meter
+{
+
+Q_OBJECT
+
+public:
+ ImageLabel(karamba* k, int ix,int iy,int iw,int ih );
+ ImageLabel(karamba* k);
+ ~ImageLabel();
+ void setValue( QString imagePath );
+
+ void setValue( long );
+ void setValue( QPixmap& );
+ QString getStringValue() { return imagePath; };
+ void scale( int, int );
+ void smoothScale( int, int );
+
+ void rotate(int);
+ void removeImageTransformations();
+ void mUpdate( QPainter * );
+ void mUpdate( QPainter *, int );
+
+ void rolloverImage(QMouseEvent *e);
+ void parseImages( QString fn, QString fn_roll, int, int, int, int );
+ virtual void show();
+ virtual void hide();
+
+ void setTooltip(QString txt);
+ int cblend;
+ int background;
+ // Pixmap Effects
+ void removeEffects();
+ void intensity(float ratio, int millisec);
+ void channelIntensity(float ratio, QString channel, int millisec);
+ void toGray(int millisec);
+ void setBackground(int b);
+
+ void attachClickArea(QString leftMouseButton, QString middleMouseButton,
+ QString rightMouseButton);
+
+ virtual bool click(QMouseEvent*);
+
+private slots:
+
+ // gets called if a timed effects needs to bee removed
+ void slotEffectExpired();
+ void slotCopyResult(KIO::Job* job);
+
+signals:
+ void pixmapLoaded();
+
+private:
+ void applyTransformations(bool useSmoothScale = false);
+ int pixmapWidth;
+ int pixmapHeight;
+ int pixmapOffWidth;
+ int pixmapOffHeight;
+ int pixmapOnWidth;
+ int pixmapOnHeight;
+
+ // true if Image has been scaled
+ bool doScale;
+ // true if Image has been rotated
+ bool doRotate;
+
+ // Contains the current Effect or is 0 if no Effect is applied
+ Effect* imageEffect;
+
+ // Scale Matrix
+ //QWMatrix scaleMat;
+ int scale_w;
+ int scale_h;
+ // Rotation Matrix
+ //QWMatrix rotMat;
+ int rot_angle;
+
+ KPixmap pixmap;
+ KPixmap realpixmap;
+
+ QRect rect_off, rect_on;
+ QRect old_tip_rect;
+
+ bool zoomed;
+ //QString fn, fn_roll;
+ bool rollover;
+ KPixmap pixmap_off;
+ KPixmap pixmap_on;
+ int xoff,xon;
+ int yoff,yon;
+ QString imagePath;
+};
+
+#endif // IMAGELABEL_H
diff --git a/superkaramba/src/imagelabel_python.cpp b/superkaramba/src/imagelabel_python.cpp
new file mode 100644
index 0000000..6564ce5
--- /dev/null
+++ b/superkaramba/src/imagelabel_python.cpp
@@ -0,0 +1,331 @@
+/****************************************************************************
+* imagelabel_python.cpp - Imagelabel functions for python api
+*
+* Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+* Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+* Copyright (c) 2004 Petri Damstn <damu@iki.fi>
+*
+* This file is part of SuperKaramba.
+*
+* SuperKaramba 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.
+*
+* SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+#ifdef _XOPEN_SOURCE
+#undef _XOPEN_SOURCE
+#endif
+
+#include <Python.h>
+#include <qobject.h>
+#include "karamba.h"
+#include "imagelabel.h"
+#include "meter_python.h"
+#include "imagelabel_python.h"
+#include "lineparser.h"
+
+ImageLabel* createImageLabel(karamba *theme, long x, long y,
+ char* path, bool bg)
+{
+ QString file;
+ //QString fakefile;
+
+ /*tmp->setThemePath(theme->themePath);*/
+ //FIXME: This is an ugly hack to ensure a unique reference
+ //to add to the meterList. It is a workaround for when a clickarea
+ //is attached to an image, the image is deleted, and a new image is
+ //created. A correct solution would be have dictionaries with a key/value
+ //pair of ints->refs.
+ ImageLabel *tmp2 = new ImageLabel(theme, x, y, 0, 0);
+ ImageLabel *tmp = new ImageLabel(theme, x, y, 0, 0);
+ delete tmp2;
+
+ if(path)
+ {
+ file.setAscii(path);
+ tmp->setValue(file);
+ //tmp->parseImages(file, fakefile, x,y, 0, 0);
+ }
+ tmp->setBackground(bg);
+ theme->setSensor(LineParser(file), tmp);
+ theme->meterList->append (tmp);
+ theme->imageList->append (tmp);
+ if(bg)
+ theme->kroot->repaint(true);
+ return tmp;
+}
+
+PyObject* py_createImage(PyObject *, PyObject *args)
+{
+ long widget, x, y;
+ char *text;
+ if (!PyArg_ParseTuple(args, (char*)"llls:createImage", &widget, &x, &y, &text))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+
+ ImageLabel *tmp = createImageLabel((karamba*)widget, x, y, text, 0);
+ return (Py_BuildValue((char*)"l", (long)tmp));
+}
+
+PyObject* py_createBackgroundImage(PyObject *, PyObject *args)
+{
+ long widget, x, y;
+ char *text;
+ if (!PyArg_ParseTuple(args, (char*)"llls:createBackgroundImage", &widget, &x, &y,
+ &text))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ ImageLabel *tmp = createImageLabel((karamba*)widget, x, y, text, 1);
+ return (Py_BuildValue((char*)"l", (long)tmp));
+}
+
+//Matthew Kay: new function for creating icons for tasks
+/**
+ * creates the icon for the specified task as a karamba image
+ * @param ctask the window id of the task to create the icon for
+ */
+PyObject* py_createTaskIcon(PyObject *, PyObject *args)
+{
+ long widget, x, y;
+ long ctask;
+ if (!PyArg_ParseTuple(args, (char*)"llll:createTaskIcon", &widget, &x, &y, &ctask))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+
+ //get the specified task and insure it exists
+ TaskList taskList = ((karamba*)widget)->taskManager.tasks();
+ Task* task = 0;
+ Task* currTask = 0;
+ for (task = taskList.first(); task; task = taskList.next())
+ {
+ if ((long)task == (long)ctask)
+ {
+ //task found
+ currTask = task;
+ break;
+ }
+ }
+ if (currTask == 0)
+ {
+ //no task was found
+ qWarning("Task not found.");
+ return (long)NULL ;
+ }
+ //retrieve the QPixmap that represents this image
+ QPixmap iconPixmap = KWin::icon(currTask->window());
+
+ ImageLabel *tmp = createImageLabel((karamba*)widget, x, y, 0, 0);
+ tmp->setValue(iconPixmap);
+ return (Py_BuildValue((char*)"l", (long)tmp));
+}
+
+PyObject* py_deleteImage(PyObject *, PyObject *args)
+{
+ long widget, meter;
+ if (!PyArg_ParseTuple(args, (char*)"ll:deleteImage", &widget, &meter))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, "ImageLabel"))
+ return NULL;
+
+ ((karamba*)widget)->deleteMeterFromSensors((Meter*)meter);
+ ((karamba*)widget)->clickList->removeRef((Meter*)meter);
+ ((karamba*)widget)->imageList->removeRef((Meter*)meter);
+ return Py_BuildValue((char*)"l",
+ ((karamba*)widget)->meterList->removeRef((Meter*)meter));
+}
+
+PyObject* py_getThemeImage(PyObject *self, PyObject *args)
+{
+ return py_getThemeMeter(self, args, "ImageLabel");
+}
+
+PyObject* py_getImagePos(PyObject *self, PyObject *args)
+{
+ return py_getPos(self, args, "ImageLabel");
+}
+
+PyObject* py_getImageSize(PyObject *self, PyObject *args)
+{
+ return py_getSize(self, args, "ImageLabel");
+}
+
+PyObject* py_moveImage(PyObject *self, PyObject *args)
+{
+ return py_move(self, args, "ImageLabel");
+}
+
+PyObject* py_hideImage(PyObject *self, PyObject *args)
+{
+ return py_hide(self, args, "ImageLabel");
+}
+
+PyObject* py_showImage(PyObject *self, PyObject *args)
+{
+ return py_show(self, args, "ImageLabel");
+}
+
+PyObject* py_getImageValue(PyObject *self, PyObject *args)
+{
+ return py_getStringValue(self, args, "ImageLabel");
+}
+
+PyObject* py_setImageValue(PyObject *self, PyObject *args)
+{
+ return py_setStringValue(self, args, "ImageLabel");
+}
+
+PyObject* py_getImageSensor(PyObject *self, PyObject *args)
+{
+ return py_getSensor(self, args, "ImageLabel");
+}
+
+PyObject* py_setImageSensor(PyObject *self, PyObject *args)
+{
+ return py_setSensor(self, args, "ImageLabel");
+}
+
+PyObject* py_removeImageEffects(PyObject *, PyObject *args)
+{
+ long widget, meter;
+ if (!PyArg_ParseTuple(args, (char*)"ll:removeImageEffects", &widget, &meter))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, "ImageLabel"))
+ return NULL;
+ ((ImageLabel*)meter)->removeEffects();
+ return Py_BuildValue((char*)"l", 1);
+}
+
+PyObject* py_changeImageIntensity(PyObject *, PyObject *args)
+{
+ long widget, meter;
+ long millisec = 0;
+ float ratio;
+ if (!PyArg_ParseTuple(args, (char*)"llf|l:changeImageIntensity", &widget, &meter,
+ &ratio, &millisec))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, "ImageLabel"))
+ return NULL;
+ ((ImageLabel*)meter)->intensity(ratio, millisec);
+ return Py_BuildValue((char*)"l", 1);
+}
+
+PyObject* py_changeImageChannelIntensity(PyObject *, PyObject *args)
+{
+ long widget, meter;
+ float ratio;
+ char* channel;
+ long millisec = 0;
+ if (!PyArg_ParseTuple(args, (char*)"llfs|l:changeImageChannelIntensity", &widget,
+ &meter, &ratio, &channel, &millisec))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, "ImageLabel"))
+ return NULL;
+ ((ImageLabel*)meter)->channelIntensity(ratio, channel, millisec);
+ return Py_BuildValue((char*)"l", 1);
+}
+
+PyObject* py_changeImageToGray(PyObject *, PyObject *args)
+{
+ long widget, meter;
+ long millisec = 0;
+ if (!PyArg_ParseTuple(args, (char*)"ll|l:changeImageToGray", &widget, &meter,
+ &millisec))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, "ImageLabel"))
+ return NULL;
+ ((ImageLabel*)meter)->toGray(millisec);
+ return Py_BuildValue((char*)"l", 1);
+}
+
+PyObject* py_removeImageTransformations(PyObject *, PyObject *args)
+{
+ long widget, meter;
+ if (!PyArg_ParseTuple(args, (char*)"ll:removeImageTransformations", &widget, &meter))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, "ImageLabel"))
+ return NULL;
+ ((ImageLabel*)meter)->removeImageTransformations();
+ return Py_BuildValue((char*)"l", 1);
+}
+
+PyObject* py_rotateImage(PyObject *, PyObject *args)
+{
+ long widget, meter;
+ long deg;
+ if (!PyArg_ParseTuple(args, (char*)"lll:rotateImage", &widget, &meter, &deg))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, "ImageLabel"))
+ return NULL;
+ ((ImageLabel*)meter)->rotate((int)deg);
+ return Py_BuildValue((char*)"l", 1);
+}
+
+PyObject* py_getImageHeight(PyObject *, PyObject *args)
+{
+ long widget, meter;
+ if (!PyArg_ParseTuple(args, (char*)"ll:getImageHeight", &widget, &meter))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, "ImageLabel"))
+ return NULL;
+ return Py_BuildValue((char*)"l", ((ImageLabel*)meter)->getHeight());
+}
+
+PyObject* py_getImageWidth(PyObject *, PyObject *args)
+{
+ long widget, meter;
+ if (!PyArg_ParseTuple(args, (char*)"ll:getImageWidth", &widget, &meter))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, "ImageLabel"))
+ return NULL;
+ return Py_BuildValue((char*)"l", ((ImageLabel*)meter)->getWidth());
+}
+
+PyObject* py_resizeImageSmooth(PyObject *, PyObject *args)
+{
+ long widget, meter;
+ long w, h;
+ if (!PyArg_ParseTuple(args, (char*)"llll:resizeImageSmooth", &widget, &meter,
+ &w, &h))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, "ImageLabel"))
+ return NULL;
+ ((ImageLabel*)meter)->smoothScale((int)w, (int)h);
+ return Py_BuildValue((char*)"l", 1);
+}
+
+PyObject* py_resizeImage(PyObject *, PyObject *args)
+{
+ long widget, meter, w, h;
+ if (!PyArg_ParseTuple(args, (char*)"llll:resizeImage", &widget, &meter,
+ &w, &h))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, "ImageLabel"))
+ return NULL;
+ ((ImageLabel*)meter)->scale((int)w, (int)h);
+ return Py_BuildValue((char*)"l", 1);
+}
+
+PyObject* py_addImageTooltip(PyObject *, PyObject *args)
+{
+ long widget, meter;
+ PyObject* t;
+ if (!PyArg_ParseTuple(args, (char*)"llO:addImageTooltip", &widget, &meter, &t))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, "ImageLabel"))
+ return NULL;
+ ((ImageLabel*)meter)->setTooltip(PyString2QString(t));
+ return Py_BuildValue((char*)"l", 1);
+}
diff --git a/superkaramba/src/imagelabel_python.h b/superkaramba/src/imagelabel_python.h
new file mode 100644
index 0000000..5a7f4b6
--- /dev/null
+++ b/superkaramba/src/imagelabel_python.h
@@ -0,0 +1,449 @@
+/****************************************************************************
+* imagelabel_python.h - Imagelabel functions for python api
+*
+* Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+* Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+* Copyright (c) 2004 Petri Damstn <damu@iki.fi>
+*
+* This file is part of SuperKaramba.
+*
+* SuperKaramba 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.
+*
+* SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+#ifndef IMAGELABEL_PYTHON_H
+#define IMAGELABEL_PYTHON_H
+
+/** Image/createImage
+*
+* SYNOPSIS
+* long createImage(widget, x, y, image)
+* DESCRIPTION
+* This creates an image on your widget at x, y. The filename should be
+* given as the path parameter. In theory the image could be local or could
+* be a url. It works just like adding an image in your theme file. You
+* will need to save the return value to be able to call other functions on
+* your image, such as moveImage()
+* ARGUMENTS
+* * long widget -- karamba
+* * long x -- x coordinate
+* * long y -- y coordinate
+* * string image -- image for the imagelabel
+* RETURN VALUE
+* Pointer to new image meter
+*/
+PyObject* py_createImage(PyObject *self, PyObject *args);
+
+/** Image/createBackgroundImage
+*
+* SYNOPSIS
+* long createBackgroundImage(widget, x, y, w, h, image)
+* DESCRIPTION
+* This creates an background image on your widget at x, y. The filename
+* should be given as the path parameter. In theory the image could be
+* local or could be a url. It works just like adding an image in your
+* theme file. You will need to save the return value to be able to call
+* other functions on your image, such as moveImage()
+* ARGUMENTS
+* * long widget -- karamba
+* * long x -- x coordinate
+* * long y -- y coordinate
+* * string image -- image for the imagelabel
+* RETURN VALUE
+* Pointer to new image meter
+*/
+PyObject* py_createBackgroundImage(PyObject *self, PyObject *args);
+
+/** Image/createTaskIcon
+*
+* SYNOPSIS
+* long createTaskIcon(widget, x, y, ctask)
+* DESCRIPTION
+* This creates a task image at x,y.
+* ARGUMENTS
+* * long widget -- karamba
+* * long x -- x coordinate
+* * long y -- y coordinate
+* * long task -- task
+* RETURN VALUE
+* Pointer to new image meter
+*/
+PyObject* py_createTaskIcon(PyObject *self, PyObject *args);
+
+/** Image/deleteImage
+*
+* SYNOPSIS
+* long deleteImage(widget, image)
+* DESCRIPTION
+* This removes image from memory. Please do not call functions on "image"
+* after calling deleteImage, as it does not exist anymore and that could
+* cause crashes in some cases.
+* ARGUMENTS
+* * long widget -- karamba
+* * long widget -- image
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_deleteImage(PyObject *self, PyObject *args);
+
+/** Image/getThemeImage
+*
+* SYNOPSIS
+* long getThemeImage(widget, name)
+* DESCRIPTION
+* You can reference an image in your python code that was created in the
+* .theme file. Basically, you just add a NAME= value to the IMAGE line in
+* the .theme file. Then if you want to use that object, instead of calling
+* createImage, you can call this function.
+*
+* The name you pass to the function is the same one that you gave it for
+* the NAME= parameter in the .theme file.
+* ARGUMENTS
+* * long widget -- karamba
+* * string name -- name of the image to get
+* RETURN VALUE
+* Pointer to image
+*/
+PyObject* py_getThemeImage(PyObject *self, PyObject *args);
+
+/** Image/getImagePos
+*
+* SYNOPSIS
+* tuple getImagePos(widget, image)
+* DESCRIPTION
+* Given a reference to a image object, this will return a tuple
+* containing the x and y coordinate of a image object.
+* ARGUMENTS
+* * long widget -- karamba
+* * long image -- pointer to image
+* RETURN VALUE
+* pos
+*/
+PyObject* py_getImagePos(PyObject *self, PyObject *args);
+
+/** Image/getImageSize
+*
+* SYNOPSIS
+* tuple getImageSize(widget, image)
+* DESCRIPTION
+* Given a reference to a image object, this will return a tuple
+* containing the height and width of a image object.
+* ARGUMENTS
+* * long widget -- karamba
+* * long image -- pointer to image
+* RETURN VALUE
+* size
+*/
+PyObject* py_getImageSize(PyObject *self, PyObject *args);
+
+/** Image/getImageHeight
+*
+* SYNOPSIS
+* long getImageSize(widget, image)
+* DESCRIPTION
+* This returns the height of an image. This is useful if you have rotated
+* an image and its size changed, so you do not know how big it is anymore.
+* ARGUMENTS
+* * long widget -- karamba
+* * long image -- pointer to image
+* RETURN VALUE
+* height
+*/
+PyObject* py_getImageHeight(PyObject *self, PyObject *args);
+
+/** Image/getImageWidth
+*
+* SYNOPSIS
+* long getImageSize(widget, image)
+* DESCRIPTION
+* This returns the width of an image. This is useful if you have rotated
+* an image and its size changed, so you do not know how big it is anymore. // ARGUMENTS
+* * long widget -- karamba
+* * long image -- pointer to image
+* RETURN VALUE
+* width
+*/
+PyObject* py_getImageWidth(PyObject *self, PyObject *args);
+
+/** Image/showImage
+*
+* SYNOPSIS
+* long showImage(widget, image)
+* DESCRIPTION
+* This shows a previously hidden image. It does not actually refresh the
+* image on screen. That is what redrawWidget() does.
+* ARGUMENTS
+* * long widget -- karamba
+* * long image -- pointer to image
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_showImage(PyObject *self, PyObject *args);
+
+/** Image/hideImage
+*
+* SYNOPSIS
+* long hideImage(widget, image)
+* DESCRIPTION
+* This hides an image. In other words, during subsequent calls to
+* widgetUpdate(), this image will not be drawn.
+* ARGUMENTS
+* * long widget -- karamba
+* * long image -- pointer to image
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_hideImage(PyObject *self, PyObject *args);
+
+/** Image/moveImage
+*
+* SYNOPSIS
+* long moveImage(widget, image, x, y)
+* DESCRIPTION
+* This moves an image to a new x, y relative to your widget. In other
+* words, (0,0) is the top corner of your widget, not the screen. The
+* imageToMove parameter is a reference to the image to move that you saved
+* as the return value from createImage()
+* ARGUMENTS
+* * long widget -- karamba
+* * long image -- pointer to image
+* * long x -- x coordinate
+* * long y -- y coordinate
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_moveImage(PyObject *self, PyObject *args);
+
+/** Image/getImagePath
+*
+* SYNOPSIS
+* string getImagePath(widget, image)
+* DESCRIPTION
+* Returns current image path.
+* ARGUMENTS
+* * long widget -- karamba
+* * long image -- pointer to image
+* RETURN VALUE
+* path
+*/
+PyObject* py_getImageValue(PyObject *self, PyObject *args);
+
+/** Image/setImagePath
+*
+* SYNOPSIS
+* long setImagePath(widget, image, path)
+* DESCRIPTION
+* This will change image of a image widget.
+* ARGUMENTS
+* * long widget -- karamba
+* * long image -- pointer to image
+* * long path -- new path
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_setImageValue(PyObject *self, PyObject *args);
+
+/** Image/getImageSensor
+*
+* SYNOPSIS
+* string getImageSensor(widget, image)
+* DESCRIPTION
+* Get current sensor string
+* ARGUMENTS
+* * long widget -- karamba
+* * long image -- pointer to image
+* RETURN VALUE
+* sensor string
+*/
+PyObject* py_getImageSensor(PyObject *self, PyObject *args);
+
+/** Image/setImageSensor
+*
+* SYNOPSIS
+* long setImageSensor(widget, image, sensor)
+* DESCRIPTION
+* Get current sensor string
+* ARGUMENTS
+* * long widget -- karamba
+* * long image -- pointer to image
+* * string sensor -- new sensor as in theme files
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_setImageSensor(PyObject *self, PyObject *args);
+
+/** Image/removeImageEffects
+*
+* SYNOPSIS
+* long removeImageEffects(widget, image)
+* DESCRIPTION
+* If you have called image effect commands on your image (ex:
+* changeImageIntensity), you can call this to restore your image to it's
+* original form.
+* ARGUMENTS
+* * long widget -- karamba
+* * long image -- pointer to image
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_removeImageEffects(PyObject *self, PyObject *args);
+
+/** Image/changeImageIntensity
+*
+* SYNOPSIS
+* long changeImageIntensity(widget, image, ratio, millisec)
+* DESCRIPTION
+* Changes the "intensity" of the image, which is similar to it's
+* brightness. ratio is a floating point number from -1.0 to 1.0 that
+* determines how much to brighten or darken the image. Millisec specifies
+* how long in milliseconds before the image is restored to it's original
+* form. This is useful for "mouse over" type animations. Using 0 for
+* millisec disables this feature and leaves the image permanently
+* affected.
+* ARGUMENTS
+* * long widget -- karamba
+* * long image -- pointer to image
+* * float ratio -- -1.0 to 1.0 (dark to bright)
+* * long millisec -- milliseconds before the image is restored
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_changeImageIntensity(PyObject *self, PyObject *args);
+
+/** Image/changeImageChannelIntensity
+*
+* SYNOPSIS
+* long changeImageChannelIntensity(widget, image, ratio, channel, millisec)
+* DESCRIPTION
+* Changes the "intensity" of the image color channel, which is similar to
+* it's brightness.
+* ARGUMENTS
+* * long widget -- karamba
+* * long image -- pointer to image
+* * float ratio -- -1.0 to 1.0 (dark to bright)
+* * string channel -- color channel (red|green|blue)
+* * long millisec -- milliseconds before the image is restored
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_changeImageChannelIntensity(PyObject *self, PyObject *args);
+
+/** Image/changeImageToGray
+*
+* SYNOPSIS
+* long changeImageToGray(widget, image, millisec)
+* DESCRIPTION
+* Turns the given image into a grayscale image. Millisec specifies how
+* long in milliseconds before the image is restored to it's original form.
+* This is useful for "mouse over" type animations. Using 0 for millisec
+* disables this feature and leaves the image permanently affected.
+* ARGUMENTS
+* * long widget -- karamba
+* * long image -- pointer to image
+* * long millisec -- milliseconds before the image is restored
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_changeImageToGray(PyObject *self, PyObject *args);
+
+/** Image/removeImageTransformations
+*
+* SYNOPSIS
+* long removeImageTransformations(widget, image)
+* DESCRIPTION
+* If you have rotated or resized your image, you can call this to restore
+* your image to it's original form.
+* ARGUMENTS
+* * long widget -- karamba
+* * long image -- pointer to image
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_removeImageTransformations(PyObject *self, PyObject *args);
+
+/** Image/rotateImage
+*
+* SYNOPSIS
+* long rotateImage(widget, image, deg)
+* DESCRIPTION
+* This rotates your image to by the specified amount of degrees. The
+* imageToRotate parameter is a reference to an image that you saved as the
+* return value from createImage()
+* ARGUMENTS
+* * long widget -- karamba
+* * long image -- pointer to image
+* * long deg -- degrees to rotate
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_rotateImage(PyObject *self, PyObject *args);
+
+/** Image/resizeImageSmooth
+*
+* SYNOPSIS
+* long resizeImageSmooth(widget, image, w, h)
+* DESCRIPTION
+* DEPRECATED: resizeImage now allows the user to pick whether to use fast
+* or smooth resizing from the SuperKaramba menu - This resizes your image
+* to width, height. The imageToResize parameter is a reference to an
+* image that you saved as the return value from createImage()
+* ARGUMENTS
+* * long widget -- karamba
+* * long image -- pointer to image
+* * long w -- width
+* * long h -- height
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_resizeImageSmooth(PyObject *self, PyObject *args);
+
+/** Image/resizeImage
+*
+* SYNOPSIS
+* long resizeImage(widget, image, w, h)
+* DESCRIPTION
+* This resizes your image to width, height. The imageToResize parameter is
+* a reference to an image that you saved as the return value from
+* createImage()
+* ARGUMENTS
+* * long widget -- karamba
+* * long image -- pointer to image
+* * long w -- width
+* * long h -- height
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_resizeImage(PyObject *self, PyObject *args);
+
+/** Image/addImageTooltip
+*
+* SYNOPSIS
+* long addImageTooltip(widget, image, text)
+* DESCRIPTION
+* This creats a tooltip for image with tooltip_text.
+*
+* Note:
+* * If you move the image, the tooltip does not move! It stays! Do not
+* create a tooltip if the image is off-screen because you will not be
+* able to ever see it.
+* ARGUMENTS
+* * long widget -- karamba
+* * long image -- pointer to image
+* * string text -- tooltip text
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_addImageTooltip(PyObject *self, PyObject *args);
+
+#endif // IMAGELABEL_PYTHON_H
diff --git a/superkaramba/src/input.cpp b/superkaramba/src/input.cpp
new file mode 100644
index 0000000..a917488
--- /dev/null
+++ b/superkaramba/src/input.cpp
@@ -0,0 +1,196 @@
+/****************************************************************************
+ * Copyright (c) 2005 Alexander Wiedenbruch <mail@wiedenbruch.de>
+ *
+ * This file is part of SuperKaramba.
+ *
+ * SuperKaramba 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.
+ *
+ * SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#include "input.h"
+#include "kdebug.h"
+
+Input::Input(karamba* k, int x, int y, int w, int h):
+ Meter(k, x, y, w, h)
+{
+ edit = new SKLineEdit((QWidget*)k, this);
+ edit->setGeometry(x,y,w,h);
+}
+
+Input::~Input()
+{
+ delete edit;
+}
+
+void Input::mUpdate(QPainter*)
+{
+ edit->repaint();
+}
+
+void Input::setValue(QString text)
+{
+ edit->setText(text);
+}
+
+QString Input::getStringValue() const
+{
+ return edit->text();
+}
+
+void Input::setBGColor(QColor c)
+{
+ edit->setBackgroundColor(c);
+}
+
+void Input::setColor(QColor c)
+{
+ Meter::setColor(c);
+ edit->setFrameColor(c);
+}
+
+QColor Input::getBGColor() const
+{
+ return edit->backgroundColor();
+}
+
+QColor Input::getColor() const
+{
+ return edit->getFrameColor();
+}
+
+void Input::hide()
+{
+ Meter::hide();
+ edit->setHidden(true);
+}
+
+void Input::show()
+{
+ Meter::show();
+ edit->setHidden(false);
+}
+
+void Input::setSize(int ix, int iy, int iw, int ih)
+{
+ Meter::setSize(ix, iy, iw, ih);
+ edit->setGeometry(ix, iy, iw, ih);
+}
+
+void Input::setX(int ix)
+{
+ Meter::setX(ix);
+ edit->setGeometry(ix, getY(), getWidth(), getHeight());
+}
+
+void Input::setY(int iy)
+{
+ Meter::setY(iy);
+ edit->setGeometry(getX(), iy, getWidth(), getHeight());
+}
+
+void Input::setWidth(int iw)
+{
+ Meter::setWidth(iw);
+ edit->setGeometry(getX(), getY(), iw, getHeight());
+}
+
+void Input::setHeight(int ih)
+{
+ Meter::setHeight(ih);
+ edit->setGeometry(getX(), getY(), getWidth(), ih);
+}
+
+void Input::setFont(QString f)
+{
+ font.setFamily(f);
+ edit->setFont(font);
+}
+
+QString Input::getFont() const
+{
+ return font.family();
+}
+
+void Input::setFontColor(QColor fontColor)
+{
+ QPalette palette = edit->palette();
+ palette.setColor(QColorGroup::Text, fontColor);
+ edit->setPalette(palette);
+}
+
+QColor Input::getFontColor() const
+{
+ const QColorGroup &color = edit->colorGroup();
+ return color.text();
+}
+
+void Input::setSelectionColor(QColor selectionColor)
+{
+ QPalette palette = edit->palette();
+ palette.setColor(QColorGroup::Highlight, selectionColor);
+ edit->setPalette(palette);
+}
+
+QColor Input::getSelectionColor() const
+{
+ const QColorGroup &color = edit->colorGroup();
+ return color.highlight();
+}
+
+void Input::setSelectedTextColor(QColor selectedTextColor)
+{
+ QPalette palette = edit->palette();
+ palette.setColor(QColorGroup::HighlightedText, selectedTextColor);
+ edit->setPalette(palette);
+}
+
+QColor Input::getSelectedTextColor() const
+{
+ const QColorGroup &color = edit->colorGroup();
+ return color.highlightedText();
+}
+
+void Input::setFontSize(int size)
+{
+ font.setPixelSize(size);
+ edit->setFont(font);
+}
+
+int Input::getFontSize() const
+{
+ return font.pixelSize();
+}
+
+void Input::setTextProps(TextField* t)
+{
+ if(t)
+ {
+ setFontSize(t->getFontSize());
+ setFont(t->getFont());
+ setColor(t->getColor());
+ setBGColor(t->getBGColor());
+ }
+}
+
+void Input::setInputFocus()
+{
+ edit->setFocus();
+}
+
+void Input::clearInputFocus()
+{
+ edit->clearFocus();
+}
+
+#include "input.moc"
diff --git a/superkaramba/src/input.h b/superkaramba/src/input.h
new file mode 100644
index 0000000..15c16e0
--- /dev/null
+++ b/superkaramba/src/input.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+ * Copyright (c) 2005 Alexander Wiedenbruch <mail@wiedenbruch.de>
+ *
+ * This file is part of SuperKaramba.
+ *
+ * SuperKaramba 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.
+ *
+ * SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#ifndef INPUT_H
+#define INPUT_H
+
+#include <meter.h>
+#include <sklineedit.h>
+
+#include <qpainter.h>
+#include <qcolor.h>
+#include <qlineedit.h>
+#include <qwidget.h>
+#include <qstring.h>
+#include <qfont.h>
+
+#include "textfield.h"
+
+class Input : public Meter
+{
+Q_OBJECT
+public:
+ Input(karamba* k, int ix, int iy, int iw, int ih);
+ Input();
+
+ ~Input();
+
+ void mUpdate(QPainter *p);
+
+ void setValue(QString text);
+ QString getStringValue() const;
+
+ void setBGColor(QColor c);
+ QColor getBGColor() const;
+ void setColor(QColor c);
+ QColor getColor() const;
+ void setFontColor(QColor fontColor);
+ QColor getFontColor() const;
+ void setSelectionColor(QColor selectionColor);
+ QColor getSelectionColor() const;
+ void setSelectedTextColor(QColor selectedTextColor);
+ QColor getSelectedTextColor() const;
+ void setTextProps(TextField*);
+
+ void hide();
+ void show();
+
+ void setSize(int ix, int iy, int iw, int ih);
+ void setX(int ix);
+ void setY(int iy);
+ void setWidth(int iw);
+ void setHeight(int ih);
+
+ void setFont(QString f);
+ QString getFont() const;
+ void setFontSize(int size);
+ int getFontSize() const;
+
+ void setInputFocus();
+ void clearInputFocus();
+
+private:
+ SKLineEdit *edit;
+ QFont font;
+};
+
+#endif
diff --git a/superkaramba/src/input_python.cpp b/superkaramba/src/input_python.cpp
new file mode 100644
index 0000000..0bf45e1
--- /dev/null
+++ b/superkaramba/src/input_python.cpp
@@ -0,0 +1,355 @@
+/****************************************************************************
+* input_python.cpp - Functions for input box python api
+*
+* Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+* Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+* Copyright (c) 2004 Petri Damstn <damu@iki.fi>
+* Copyright (c) 2005 Alexander Wiedenbruch <mail@wiedenbruch.de>
+*
+* This file is part of SuperKaramba.
+*
+* SuperKaramba 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.
+*
+* SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+#ifdef _XOPEN_SOURCE
+#undef _XOPEN_SOURCE
+#endif
+
+#include <Python.h>
+#include <qobject.h>
+#include "karamba.h"
+#include "meter.h"
+#include "meter_python.h"
+#include "input_python.h"
+
+PyObject* py_createInputBox(PyObject *, PyObject *args)
+{
+ long widget, x, y, w, h;
+ PyObject *text;
+ if (!PyArg_ParseTuple(args, (char*)"lllllO:createInputBox", &widget, &x, &y, &w, &h, &text))
+ return NULL;
+
+ if (!checkKaramba(widget))
+ return NULL;
+
+ Input *tmp = new Input((karamba*)widget, (int)x, (int)y, (int)w, (int)h);
+ tmp->setValue(PyString2QString(text));
+ tmp->setTextProps(((karamba*)widget)->getDefaultTextProps());
+ ((karamba*)widget)->meterList->append(tmp);
+ tmp->show();
+
+ ((karamba*)widget)->makeActive();
+
+ return (Py_BuildValue((char*)"l", (long)tmp));
+}
+
+PyObject* py_deleteInputBox(PyObject *, PyObject *args)
+{
+ long widget, meter;
+ if (!PyArg_ParseTuple(args, (char*)"ll:deleteInputBox", &widget, &meter))
+ return NULL;
+
+ if (!checkKarambaAndMeter(widget, meter, "Input"))
+ return NULL;
+
+ bool result = ((karamba*)widget)->meterList->removeRef((Meter*)meter);
+
+ ((karamba*)widget)->makePassive();
+
+ return Py_BuildValue((char*)"l", result);
+}
+
+PyObject* py_getThemeInputBox(PyObject *self, PyObject *args)
+{
+ return py_getThemeMeter(self, args, "Input");
+}
+
+PyObject* py_getInputBoxValue(PyObject *self, PyObject *args)
+{
+ return py_getStringValue(self, args, "Input");
+}
+
+PyObject* py_setInputBoxValue(PyObject *self, PyObject *args)
+{
+ return py_setStringValue(self, args, "Input");
+}
+
+PyObject* py_hideInputBox(PyObject *self, PyObject *args)
+{
+ return py_hide(self, args, "Input");
+}
+
+PyObject* py_showInputBox(PyObject *self, PyObject *args)
+{
+ return py_show(self, args, "Input");
+}
+
+PyObject* py_getInputBoxPos(PyObject *self, PyObject *args)
+{
+ return py_getPos(self, args, "Input");
+}
+
+PyObject* py_moveInputBox(PyObject *self, PyObject *args)
+{
+ return py_move(self, args, "Input");
+}
+
+PyObject* py_getInputBoxSize(PyObject *self, PyObject *args)
+{
+ return py_getSize(self, args, "Input");
+}
+
+PyObject* py_resizeInputBox(PyObject *self, PyObject *args)
+{
+ return py_resize(self, args, "Input");
+}
+
+PyObject* py_setInputBoxFont(PyObject *, PyObject *args)
+{
+ long widget, inputBox;
+ char* text;
+ if (!PyArg_ParseTuple(args, (char*)"lls:changeInputBoxFont",
+ &widget, &inputBox, &text))
+ return NULL;
+
+ if (!checkKarambaAndMeter(widget, inputBox, "Input"))
+ return NULL;
+
+ ((Input*)inputBox)->setFont(text);
+ return Py_BuildValue((char*)"l", 1);
+}
+
+PyObject* py_getInputBoxFont(PyObject *, PyObject *args)
+{
+ long widget, inputBox;
+ if (!PyArg_ParseTuple(args, (char*)"ll:getInputBoxFont", &widget, &inputBox))
+ return NULL;
+
+ if (!checkKarambaAndMeter(widget, inputBox, "Input"))
+ return NULL;
+
+ return Py_BuildValue((char*)"s", ((Input*)inputBox)->getFont().ascii());
+}
+
+PyObject* py_setInputBoxFontColor(PyObject *, PyObject *args)
+{
+ long widget, inputBox;
+ long r, g, b;
+ if (!PyArg_ParseTuple(args, (char*)"lllll:changeInputBoxFontColor", &widget, &inputBox, &r, &g, &b))
+ return NULL;
+
+ if (!checkKarambaAndMeter(widget, inputBox, "Input"))
+ return NULL;
+
+ ((Input*)inputBox)->setFontColor(QColor(r, g, b));
+ return Py_BuildValue((char*)"l", 1);
+}
+
+PyObject* py_getInputBoxFontColor(PyObject *, PyObject *args)
+{
+ long widget, inputBox;
+ if (!PyArg_ParseTuple(args, (char*)"ll:changeInputBoxFontColor", &widget, &inputBox))
+ return NULL;
+
+ if (!checkKarambaAndMeter(widget, inputBox, "Input"))
+ return NULL;
+
+ QColor color = ((Input*)inputBox)->getFontColor();
+ return Py_BuildValue((char*)"(i,i,i)", color.red(), color.green(), color.blue());
+}
+
+PyObject* py_setInputBoxSelectionColor(PyObject *, PyObject *args)
+{
+ long widget, inputBox;
+ long r, g, b;
+ if (!PyArg_ParseTuple(args, (char*)"lllll:changeInputBoxSelectionColor", &widget, &inputBox, &r, &g, &b))
+ return NULL;
+
+ if (!checkKarambaAndMeter(widget, inputBox, "Input"))
+ return NULL;
+
+ ((Input*)inputBox)->setSelectionColor(QColor(r, g, b));
+ return Py_BuildValue((char*)"l", 1);
+}
+
+PyObject* py_getInputBoxSelectionColor(PyObject *, PyObject *args)
+{
+ long widget, inputBox;
+ if (!PyArg_ParseTuple(args, (char*)"ll:changeInputBoxSelectionColor", &widget, &inputBox))
+ return NULL;
+
+ if (!checkKarambaAndMeter(widget, inputBox, "Input"))
+ return NULL;
+
+ QColor color = ((Input*)inputBox)->getSelectionColor();
+ return Py_BuildValue((char*)"(i,i,i)", color.red(), color.green(), color.blue());
+}
+
+PyObject* py_setInputBoxBGColor(PyObject *, PyObject *args)
+{
+ long widget, inputBox;
+ long r, g, b;
+ if (!PyArg_ParseTuple(args, (char*)"lllll:changeInputBoxBackgroundColor", &widget, &inputBox, &r, &g, &b))
+ return NULL;
+
+ if (!checkKarambaAndMeter(widget, inputBox, "Input"))
+ return NULL;
+
+ ((Input*)inputBox)->setBGColor(QColor(r, g, b));
+ return Py_BuildValue((char*)"l", 1);
+}
+
+PyObject* py_getInputBoxBGColor(PyObject *, PyObject *args)
+{
+ long widget, inputBox;
+if (!PyArg_ParseTuple(args, (char*)"ll:getInputBoxBackgroundColor", &widget, &inputBox))
+ return NULL;
+
+ if (!checkKarambaAndMeter(widget, inputBox, "Input"))
+ return NULL;
+
+ QColor color = ((Input*)inputBox)->getBGColor();
+ return Py_BuildValue((char*)"(i,i,i)", color.red(), color.green(), color.blue());
+}
+
+PyObject* py_setInputBoxFrameColor(PyObject *, PyObject *args)
+{
+ long widget, inputBox;
+ long r, g, b;
+if (!PyArg_ParseTuple(args, (char*)"lllll:changeInputBoxFrameColor", &widget, &inputBox, &r, &g, &b))
+ return NULL;
+
+ if (!checkKarambaAndMeter(widget, inputBox, "Input"))
+ return NULL;
+
+ ((Input*)inputBox)->setColor(QColor(r, g, b));
+ return Py_BuildValue((char*)"l", 1);
+}
+
+PyObject* py_getInputBoxFrameColor(PyObject *, PyObject *args)
+{
+ long widget, inputBox;
+if (!PyArg_ParseTuple(args, (char*)"ll:getInputBoxFrameColor", &widget, &inputBox))
+ return NULL;
+
+ if (!checkKarambaAndMeter(widget, inputBox, "Input"))
+ return NULL;
+
+ QColor color = ((Input*)inputBox)->getColor();
+ return Py_BuildValue((char*)"(i,i,i)", color.red(), color.green(), color.blue());
+}
+
+PyObject* py_setInputBoxSelectedTextColor(PyObject *, PyObject *args)
+{
+ long widget, inputBox;
+ long r, g, b;
+if (!PyArg_ParseTuple(args, (char*)"lllll:changeInputBoxSelectedTextColor", &widget, &inputBox, &r, &g, &b))
+ return NULL;
+
+ if (!checkKarambaAndMeter(widget, inputBox, "Input"))
+ return NULL;
+
+ ((Input*)inputBox)->setSelectedTextColor(QColor(r, g, b));
+ return Py_BuildValue((char*)"l", 1);
+}
+
+PyObject* py_getInputBoxSelectedTextColor(PyObject *, PyObject *args)
+{
+ long widget, inputBox;
+if (!PyArg_ParseTuple(args, (char*)"ll:getInputBoxSelectedTextColor", &widget, &inputBox))
+ return NULL;
+
+ if (!checkKarambaAndMeter(widget, inputBox, "Input"))
+ return NULL;
+
+ QColor color = ((Input*)inputBox)->getSelectedTextColor();
+ return Py_BuildValue((char*)"(i,i,i)", color.red(), color.green(), color.blue());
+}
+
+PyObject* py_setInputBoxFontSize(PyObject *, PyObject *args)
+{
+ long widget, inputBox;
+ long size;
+ if (!PyArg_ParseTuple(args, (char*)"lll:changeInputBoxFontSize",
+ &widget, &inputBox, &size))
+ return NULL;
+
+ if (!checkKarambaAndMeter(widget, inputBox, "Input"))
+ return NULL;
+
+ ((Input*)inputBox)->setFontSize( size );
+ return Py_BuildValue((char*)"l", 1);
+}
+
+PyObject* py_getInputBoxFontSize(PyObject *, PyObject *args)
+{
+ long widget, inputBox;
+ if (!PyArg_ParseTuple(args, (char*)"ll:getInputBoxFontSize", &widget, &inputBox))
+ return NULL;
+
+ if (!checkKarambaAndMeter(widget, inputBox, "Input"))
+ return NULL;
+
+ return Py_BuildValue((char*)"l", ((Input*)inputBox)->getFontSize());
+}
+
+PyObject* py_setInputFocus(PyObject *, PyObject *args)
+{
+ long widget, inputBox;
+ if (!PyArg_ParseTuple(args, (char*)"ll:setInputFocus", &widget, &inputBox))
+ return NULL;
+
+ if (!checkKarambaAndMeter(widget, inputBox, "Input"))
+ return NULL;
+
+ //((karamba*)widget)->setActiveWindow();
+
+ ((Input*)inputBox)->setInputFocus();
+ return Py_BuildValue((char*)"l", 1);
+}
+
+PyObject* py_clearInputFocus(PyObject *, PyObject *args)
+{
+ long widget, inputBox;
+ if (!PyArg_ParseTuple(args, (char*)"ll:clearInputFocus", &widget, &inputBox))
+ return NULL;
+
+ if (!checkKarambaAndMeter(widget, inputBox, "Input"))
+ return NULL;
+
+ ((Input*)inputBox)->clearInputFocus();
+ return Py_BuildValue((char*)"l", 1);
+}
+
+PyObject* py_getInputFocus(PyObject *, PyObject *args)
+{
+ long widget;
+ if (!PyArg_ParseTuple(args, (char*)"l:getInputFocus", &widget))
+ return NULL;
+
+ if (!checkKaramba(widget))
+ return NULL;
+
+ //
+ // FocusWidget() returns the currently focused line edit,
+ // but unfortunately we need an 'Input' object here.
+ //
+ QWidget *obj = ((karamba*)widget)->focusWidget();
+
+ if(obj->isA("QLineEdit")) // SKLineEdit is no Q_Object, but QLineEdit can only be here as a SKLineEdit
+ return Py_BuildValue((char*)"l", ((SKLineEdit*)obj)->getInput());
+
+ return Py_BuildValue((char*)"l", 0);
+}
diff --git a/superkaramba/src/input_python.h b/superkaramba/src/input_python.h
new file mode 100644
index 0000000..4080b0c
--- /dev/null
+++ b/superkaramba/src/input_python.h
@@ -0,0 +1,475 @@
+/****************************************************************************
+* input_python.h - Functions for input box python api
+*
+* Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+* Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+* Copyright (c) 2004 Petri Damstn <damu@iki.fi>
+* Copyright (c) 2005 Alexander Wiedenbruch <mail@wiedenbruch.de>
+*
+* This file is part of SuperKaramba.
+*
+* SuperKaramba 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.
+*
+* SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+#ifndef INPUT_PYTHON_H
+#define INPUT_PYTHON_H
+
+/** InputBox/createInputBox
+*
+* SYNOPSIS
+* long createInputBox(widget, x, y, w, h, text)
+* DESCRIPTION
+* This creates a Input Box at x, y with width and height w, h. You need to save
+* the return value of this function to call other functions on your Input Box
+* field, such as changeInputBox().
+* The karamba widget is automatically set active, to allow user interactions.
+* ARGUMENTS
+* * long widget -- karamba
+* * long x -- x coordinate
+* * long y -- y coordinate
+* * long w -- width
+* * long h -- height
+* * string text -- text for the Input Box
+* RETURN VALUE
+* Pointer to new Input Box
+*/
+PyObject* py_createInputBox(PyObject *, PyObject *args);
+
+/** InputBox/deleteInputBox
+*
+* SYNOPSIS
+* long deleteInputBox(widget, inputBox)
+* DESCRIPTION
+* This removes a Input Box object from memory. Please do not call functions of
+* the Input Box after calling deleteInputBox, as it does not exist anymore and that
+* could cause crashes in some cases.
+* The karamba widget ist automatically set passive, when no more Input Boxes are on
+* the karamba widget.
+* ARGUMENTS
+* * long widget -- karamba
+* * long widget -- inputBox
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_deleteInputBox(PyObject *, PyObject *args);
+
+/** InputBox/getThemeInputBox
+*
+* SYNOPSIS
+* long getThemeInputBox(widget, name)
+* DESCRIPTION
+* You can reference text in your python code that was created in the
+* theme file. Basically, you just add a NAME= value to the INPUT line in
+* the .theme file. Then if you want to use that object, instead of calling
+* createInputBox, you can call this function.
+*
+* The name you pass to the function is the same one that you gave it for
+* the NAME= parameter in the .theme file.
+* ARGUMENTS
+* * long widget -- karamba
+* * string name -- name of the Input Box to get
+* RETURN VALUE
+* Pointer to Input Box
+*/
+PyObject* py_getThemeInputBox(PyObject *self, PyObject *args);
+
+/** InputBox/getInputBoxValue
+*
+* SYNOPSIS
+* string getInputBoxValue(widget, inputBox)
+* DESCRIPTION
+* Returns current Input Box text.
+* ARGUMENTS
+* * long widget -- karamba
+* * long inputBox -- pointer to text
+* RETURN VALUE
+* value
+*/
+PyObject* py_getInputBoxValue(PyObject *self, PyObject *args);
+
+/** InputBox/changeInputBox
+*
+* SYNOPSIS
+* long changeInputBox(widget, inputBox, value)
+* DESCRIPTION
+* This will change the contents of a input box widget.
+* ARGUMENTS
+* * long widget -- karamba
+* * long text -- pointer to Input Box
+* * long value -- new value
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_setInputBoxValue(PyObject *self, PyObject *args);
+
+/** InputBox/hideInputBox
+*
+* SYNOPSIS
+* long hideInputBox(widget, inputBox)
+* DESCRIPTION
+* Hides a Input Box that is visible.
+* ARGUMENTS
+* * long widget -- karamba
+* * long inputBox -- pointer to Input Box
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_hideInputBox(PyObject *self, PyObject *args);
+
+/** InputBox/showInputBox
+*
+* SYNOPSIS
+* long showInputBox(widget, inputBox)
+* DESCRIPTION
+* Shows Input Box that has been hidden with hideInputBox()
+* ARGUMENTS
+* * long widget -- karamba
+* * long inputBox -- pointer to Input Box
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_showInputBox(PyObject *self, PyObject *args);
+
+/** InputBox/getInputBoxPos
+*
+* SYNOPSIS
+* tuple getInputBoxPos(widget, inputBox)
+* DESCRIPTION
+* Given a reference to a Input Box object, this will return a tuple
+* containing the x and y coordinate of a Input Box object.
+* ARGUMENTS
+* * long widget -- karamba
+* * long inputBox -- pointer to Input Box
+* RETURN VALUE
+* pos
+*/
+PyObject* py_getInputBoxPos(PyObject *self, PyObject *args);
+
+/** InputBox/moveInputBox
+*
+* SYNOPSIS
+* long moveInputBox(widget, inputBox, x, y)
+* DESCRIPTION
+* This moves a Input Box object to a new x, y relative to your widget. In other
+* words, (0,0) is the top corner of your widget, not the screen.
+* ARGUMENTS
+* * long widget -- karamba
+* * long inputBox -- pointer to Input Box
+* * long x -- x coordinate
+* * long y -- y coordinate
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_moveInputBox(PyObject *self, PyObject *args);
+
+/** InputBox/getInputBoxSize
+*
+* SYNOPSIS
+* tuple getInputBoxSize(widget, inputBox)
+* DESCRIPTION
+* Given a reference to a Input Box object, this will return a tuple
+* containing the height and width of a Input Box object.
+* ARGUMENTS
+* * long widget -- karamba
+* * long inputBox -- pointer to Input Box
+* RETURN VALUE
+* size
+*/
+PyObject* py_getInputBoxSize(PyObject *self, PyObject *args);
+
+/** InputBox/resizeInputBox
+*
+* SYNOPSIS
+* long resizeInputBox(widget, inputBox, w, h)
+* DESCRIPTION
+* This will resize Input Box to new height and width.
+* ARGUMENTS
+* * long widget -- karamba
+* * long inputBox -- pointer to Input Box
+* * long w -- new width
+* * long h -- new height
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_resizeInputBox(PyObject *self, PyObject *args);
+
+/** InputBox/changeInputBoxFont
+*
+* SYNOPSIS
+* long changeInputBoxFont(widget, inputBox, font)
+* DESCRIPTION
+* This will change the font of a Input Box widget. InputBox is the reference to the
+* Input Box object to change. Font is a string the the name of the font to use.
+* ARGUMENTS
+* * long widget -- karamba
+* * long inputBox -- pointer to inputBox
+* * string font -- font name
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_setInputBoxFont(PyObject *, PyObject *args);
+
+/** InputBox/getInputBoxFont
+*
+* SYNOPSIS
+* string getInputBoxFont(widget, inputBox)
+* DESCRIPTION
+* Get current Input Box font name
+* ARGUMENTS
+* * long widget -- karamba
+* * long inputBox -- pointer to Input Box
+* RETURN VALUE
+* font name
+*/
+PyObject* py_getInputBoxFont(PyObject *, PyObject *args);
+
+/** InputBox/changeInputBoxFontColor
+*
+* SYNOPSIS
+* long changeInputBoxFontColor(widget, inputBox, r, g, b)
+* DESCRIPTION
+* This will change the color of a text of a Input Box widget.
+* InputBox is the reference to the text object to change
+* r, g, b are ints from 0 to 255 that represent red, green, and blue.
+* ARGUMENTS
+* * long widget -- karamba
+* * long inputBox -- pointer to Input Box
+* * long red -- red component of color
+* * long green -- green component of color
+* * long blue -- blue component of color
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_setInputBoxFontColor(PyObject *, PyObject *args);
+
+/** InputBox/getInputBoxFontColor
+*
+* SYNOPSIS
+* tuple getInputBoxFontColor(widget, inputBox)
+* DESCRIPTION
+* Get current text color of a Input Box
+* ARGUMENTS
+* * long widget -- karamba
+* * long inputBox -- pointer to Input Box
+* RETURN VALUE
+* (red, green, blue)
+*/
+PyObject* py_getInputBoxFontColor(PyObject *, PyObject *args);
+
+/** InputBox/changeInputBoxSelectionColor
+*
+* SYNOPSIS
+* long changeInputBoxSelectionColor(widget, inputBox, r, g, b)
+* DESCRIPTION
+* This will change the color of the selection of a Input Box widget.
+* InputBox is the reference to the text object to change
+* r, g, b are ints from 0 to 255 that represent red, green, and blue.
+* ARGUMENTS
+* * long widget -- karamba
+* * long inputBox -- pointer to Input Box
+* * long red -- red component of color
+* * long green -- green component of color
+* * long blue -- blue component of color
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_setInputBoxSelectionColor(PyObject *, PyObject *args);
+
+/** InputBox/getInputBoxSelectionColor
+*
+* SYNOPSIS
+* tuple getInputBoxSelectionColor(widget, inputBox)
+* DESCRIPTION
+* Get current selection color of a Input Box
+* ARGUMENTS
+* * long widget -- karamba
+* * long inputBox -- pointer to Input Box
+* RETURN VALUE
+* (red, green, blue)
+*/
+PyObject* py_getInputBoxSelectionColor(PyObject *, PyObject *args);
+
+/** InputBox/changeInputBoxBackgroundColor
+*
+* SYNOPSIS
+* long changeInputBoxBackgroundColor(widget, inputBox, r, g, b)
+* DESCRIPTION
+* This will change the background color of a Input Box widget.
+* InputBox is the reference to the text object to change
+* r, g, b are ints from 0 to 255 that represent red, green, and blue.
+* ARGUMENTS
+* * long widget -- karamba
+* * long inputBox -- pointer to Input Box
+* * long red -- red component of color
+* * long green -- green component of color
+* * long blue -- blue component of color
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_setInputBoxBGColor(PyObject *, PyObject *args);
+
+/** InputBox/getInputBoxBackgroundColor
+*
+* SYNOPSIS
+* tuple getInputBoxBackgroundColor(widget, inputBox)
+* DESCRIPTION
+* Get current background color of a Input Box
+* ARGUMENTS
+* * long widget -- karamba
+* * long inputBox -- pointer to Input Box
+* RETURN VALUE
+* (red, green, blue)
+*/
+PyObject* py_getInputBoxBGColor(PyObject *, PyObject *args);
+
+/** InputBox/changeInputBoxFrameColor
+*
+* SYNOPSIS
+* long changeInputBoxFrameColor(widget, inputBox, r, g, b)
+* DESCRIPTION
+* This will change the frame color of a Input Box widget.
+* InputBox is the reference to the text object to change
+* r, g, b are ints from 0 to 255 that represent red, green, and blue.
+* ARGUMENTS
+* * long widget -- karamba
+* * long inputBox -- pointer to Input Box
+* * long red -- red component of color
+* * long green -- green component of color
+* * long blue -- blue component of color
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_setInputBoxFrameColor(PyObject *, PyObject *args);
+
+/** InputBox/getInputBoxFrameColor
+*
+* SYNOPSIS
+* tuple getInputBoxFrameColor(widget, inputBox)
+* DESCRIPTION
+* Get current frame color of a Input Box
+* ARGUMENTS
+* * long widget -- karamba
+* * long inputBox -- pointer to Input Box
+* RETURN VALUE
+* (red, green, blue)
+*/
+PyObject* py_getInputBoxFrameColor(PyObject *, PyObject *args);
+
+/** InputBox/changeInputBoxSelectedTextColor
+*
+* SYNOPSIS
+* long changeInputBoxSelectedTextColor(widget, inputBox, r, g, b)
+* DESCRIPTION
+* This will change the selected text color of a Input Box widget.
+* InputBox is the reference to the text object to change
+* r, g, b are ints from 0 to 255 that represent red, green, and blue.
+* ARGUMENTS
+* * long widget -- karamba
+* * long inputBox -- pointer to Input Box
+* * long red -- red component of color
+* * long green -- green component of color
+* * long blue -- blue component of color
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_setInputBoxSelectedTextColor(PyObject *, PyObject *args);
+
+/** InputBox/getInputBoxSelectedTextColor
+*
+* SYNOPSIS
+* tuple getInputBoxSelectedTextColor(widget, inputBox)
+* DESCRIPTION
+* Get current selected text color of a Input Box
+* ARGUMENTS
+* * long widget -- karamba
+* * long inputBox -- pointer to Input Box
+* RETURN VALUE
+* (red, green, blue)
+*/
+PyObject* py_getInputBoxSelectedTextColor(PyObject *, PyObject *args);
+
+/** InputBox/changeInputBoxFontSize
+*
+* SYNOPSIS
+* long changeInputBoxFontSize(widget, text, size)
+* DESCRIPTION
+* This will change the font size of a Input Box widget.
+* InputBox is the reference to the text object to change.
+* Size is the new font point size.
+* ARGUMENTS
+* * long widget -- karamba
+* * long inputBox -- pointer to Input Box
+* * long size -- new size for text
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_setInputBoxFontSize(PyObject *, PyObject *args);
+
+/** InputBox/getInputBoxFontSize
+*
+* SYNOPSIS
+* long getInputBoxFontSize(widget, inputBox)
+* DESCRIPTION
+* Get current text font size
+* ARGUMENTS
+* * long widget -- karamba
+* * long inputBox -- pointer to Input Box
+* RETURN VALUE
+* text font size
+*/
+PyObject* py_getInputBoxFontSize(PyObject *, PyObject *args);
+
+/** InputBox/setInputFocus
+*
+* SYNOPSIS
+* long setInputFocus(widget, inputBox)
+* DESCRIPTION
+* Sets the Input Focus to the Input Box
+* ARGUMENTS
+* * long widget -- karamba
+* * long inputBox -- pointer to Input Box
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_setInputFocus(PyObject *, PyObject *args);
+
+/** InputBox/clearInputFocus
+*
+* SYNOPSIS
+* long clearInputFocus(widget, inputBox)
+* DESCRIPTION
+* releases the Input Focus from the Input Box
+* ARGUMENTS
+* * long widget -- karamba
+* * long inputBox -- pointer to Input Box
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_clearInputFocus(PyObject *, PyObject *args);
+
+/** InputBox/getInputFocus
+*
+* SYNOPSIS
+* long getInputFocus(widget)
+* DESCRIPTION
+* Get the Input Box currently focused
+* ARGUMENTS
+* * long widget -- karamba
+* RETURN VALUE
+* the input box or 0
+*/
+PyObject* py_getInputFocus(PyObject *, PyObject *args);
+
+#endif
diff --git a/superkaramba/src/karamba.cpp b/superkaramba/src/karamba.cpp
new file mode 100644
index 0000000..b112af0
--- /dev/null
+++ b/superkaramba/src/karamba.cpp
@@ -0,0 +1,2098 @@
+/*
+ * Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+ * Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+ * Copyright (C) 2004,2005 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
+ * Copyright (c) 2005 Ryan Nickell <p0z3r@earthlink.net>
+ *
+ * This file is part of SuperKaramba.
+ *
+ * SuperKaramba 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.
+ *
+ * SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#include "karamba_python.h"
+#include "dcopinterface_stub.h"
+#include "richtextlabel.h"
+#include "karamba.h"
+#include "karambaapp.h"
+#include "themesdlg.h"
+#include "lineparser.h"
+#include "themelocale.h"
+#include "superkarambasettings.h"
+
+#include <kdebug.h>
+#include <kmessagebox.h>
+#include <krun.h>
+#include <klocale.h>
+#include <kwin.h>
+#include <kdeversion.h>
+#include <kdirwatch.h>
+
+#include <kparts/componentfactory.h>
+#include <kparts/part.h>
+
+#include <qdir.h>
+#include <qwidgetlist.h>
+
+// Menu IDs
+#define EDITSCRIPT 1
+#define THEMECONF 2
+
+karamba::karamba(QString fn, QString name, bool reloading, int instance,
+ bool sub_theme):
+ QWidget(0,"karamba", Qt::WGroupLeader | WStyle_Customize |
+ WRepaintNoErase| WStyle_NoBorder | WDestructiveClose ),
+ meterList(0), imageList(0), clickList(0), kpop(0), widgetMask(0),
+ config(0), kWinModule(0), tempUnit('C'), m_instance(instance),
+ sensorList(0), timeList(0),
+ themeConfMenu(0), toDesktopMenu(0), kglobal(0), clickPos(0, 0), accColl(0),
+ menuAccColl(0), toggleLocked(0), pythonIface(0), defaultTextField(0),
+ trayMenuSeperatorId(-1), trayMenuQuitId(-1), trayMenuToggleId(-1),
+ trayMenuThemeId(-1),
+ m_sysTimer(NULL)
+{
+ themeStarted = false;
+ want_right_button = false;
+ want_meter_wheel_event = false;
+ prettyName = name;
+ m_sub_theme = sub_theme;
+
+ KURL url;
+
+ if(fn.find('/') == -1)
+ url.setFileName(fn);
+ else
+ url = fn;
+ if(!m_theme.set(url))
+ {
+ setFixedSize(0, 0);
+ QTimer::singleShot(100, this, SLOT(killWidget()));
+ return;
+ }
+ // Add self to list of open themes
+ // This also updates instance number
+ karambaApp->addKaramba(this, reloading);
+
+ if(prettyName.isEmpty())
+ prettyName = QString("%1 - %2").arg(m_theme.name()).arg(m_instance);
+
+ kdDebug() << "Starting theme: " << m_theme.name()
+ << " pretty name: " << prettyName << endl;
+ QString qName = "karamba - " + prettyName;
+ setName(qName.ascii());
+
+ KDirWatch *dirWatch = KDirWatch::self();
+ connect(dirWatch, SIGNAL( dirty( const QString & ) ),
+ SLOT( slotFileChanged( const QString & ) ) );
+
+ if(!dirWatch->contains(m_theme.file()))
+ dirWatch->addFile(m_theme.file());
+
+ if(!m_theme.isZipTheme() && m_theme.pythonModuleExists())
+ {
+ QString pythonFile = m_theme.path() + "/" + m_theme.pythonModule() + ".py";
+ if(!dirWatch->contains(pythonFile))
+ dirWatch->addFile(pythonFile);
+ }
+
+ widgetUpdate = true;
+
+ // Creates KConfig Object
+ QString instanceString;
+ if(m_instance > 1)
+ instanceString = QString("-%1").arg(m_instance);
+ QString cfg = QDir::home().absPath() + "/.superkaramba/"
+ + m_theme.id() + instanceString + ".rc";
+ kdDebug() << cfg << endl;
+ QFile themeConfigFile(cfg);
+ // Tests if config file Exists
+ if (!QFileInfo(themeConfigFile).exists())
+ {
+ // Create config file
+ themeConfigFile.open(IO_ReadWrite);
+ themeConfigFile.close();
+ }
+
+ config = new KConfig(cfg, false, false);
+ config -> sync();
+ config -> setGroup("internal");
+
+ m_reloading = reloading;
+ if(m_theme.pythonModuleExists())
+ {
+ kdDebug() << "Loading python module: " << m_theme.pythonModule() << endl;
+ QTimer::singleShot(0, this, SLOT(initPythonInterface()));
+ }
+
+ widgetMask = 0;
+ info = new NETWinInfo( qt_xdisplay(), winId(), qt_xrootwin(), NET::WMState );
+
+ // could be replaced with TaskManager
+ kWinModule = new KWinModule();
+ desktop = 0;
+
+ connect( kWinModule,SIGNAL(currentDesktopChanged(int)), this,
+ SLOT(currentDesktopChanged(int)) );
+ connect( kapp, SIGNAL(backgroundChanged(int)), this,
+ SLOT(currentWallpaperChanged(int)));
+
+ // Setup of the Task Manager Callbacks
+ connect(&taskManager, SIGNAL(activeTaskChanged(Task*)), this,
+ SLOT(activeTaskChanged(Task*)) );
+ connect(&taskManager, SIGNAL(taskAdded(Task*)), this,
+ SLOT(taskAdded(Task*)) );
+ connect(&taskManager, SIGNAL(taskRemoved(Task*)), this,
+ SLOT(taskRemoved(Task*)) );
+ connect(&taskManager, SIGNAL(startupAdded(Startup*)), this,
+ SLOT(startupAdded(Startup*)) );
+ connect(&taskManager, SIGNAL(startupRemoved(Startup*)), this,
+ SLOT(startupRemoved(Startup*)) );
+
+ themeConfMenu = new KPopupMenu( this);
+ themeConfMenu -> setCheckable(true);
+
+ /* XXX - need to be able to delete all these DesktopChangeSlot objects */
+ DesktopChangeSlot *dslot;
+
+ int mid;
+
+ toDesktopMenu = new KPopupMenu (this);
+ toDesktopMenu -> setCheckable(true);
+ mid = toDesktopMenu -> insertItem (i18n("&All Desktops"),
+ dslot = new DesktopChangeSlot(this,0),
+ SLOT(receive()));
+ dslot->setMenuId(mid);
+
+ toDesktopMenu -> insertSeparator();
+ for (int ndesktop=1; ndesktop <= kWinModule->numberOfDesktops(); ndesktop++)
+ {
+ QString name = i18n("Desktop &");
+ name += ('0' + ndesktop);
+
+ mid = toDesktopMenu -> insertItem (name,
+ dslot = new DesktopChangeSlot(this, ndesktop), SLOT(receive()));
+ dslot->setMenuId(mid);
+ }
+
+
+ kpop = new KPopupMenu( this );
+ kpop -> setCheckable(true);
+
+ accColl = new KActionCollection( this );
+ menuAccColl = new KActionCollection( this );
+
+ kpop->insertItem( SmallIconSet("reload"),i18n("Update"), this,
+ SLOT(updateSensors()), Key_F5 );
+ toggleLocked = new KToggleAction ( i18n("Toggle &Locked Position"),
+ SmallIconSet("locked"),
+ CTRL+Key_L, this,
+ SLOT( slotToggleLocked() ),
+ accColl, "Locked position" );
+ accColl->insert(toggleLocked);
+ toggleLocked -> setChecked(true);
+
+ toggleLocked->plug(kpop);
+
+ toggleFastTransforms = new KToggleAction(i18n("Use &Fast Image Scaling"),
+ CTRL+Key_F, this,
+ SLOT( slotToggleFastTransforms() ),
+ accColl, "Fast transformations");
+
+ accColl->insert(toggleFastTransforms);
+ toggleFastTransforms -> setChecked(true);
+
+ toggleFastTransforms -> plug(kpop);
+
+ kpop->insertSeparator();
+
+ kpop->insertItem(i18n("Configure &Theme"), themeConfMenu, THEMECONF);
+ kpop->setItemEnabled(THEMECONF, false);
+ kpop->insertItem(i18n("To Des&ktop"), toDesktopMenu);
+
+ kpop->insertItem( SmallIconSet("reload3"),i18n("&Reload Theme"),this,
+ SLOT(reloadConfig()), CTRL+Key_R );
+ kpop->insertItem( SmallIconSet("fileclose"),i18n("&Close This Theme"), this,
+ SLOT(killWidget()), CTRL+Key_C );
+
+ if(!SuperKarambaSettings::showSysTray())
+ showMenuExtension();
+
+ kpop->polish();
+
+ numberOfConfMenuItems = 0;
+
+ systray = 0;
+ foundKaramba = false;
+ onTop = false;
+ managed = false;
+ fixedPosition = false;
+ defaultTextField = new TextField();
+
+ meterList = new QObjectList();
+ meterList->setAutoDelete( true );
+ sensorList = new QObjectList();
+ sensorList->setAutoDelete( true );
+ clickList = new QObjectList();
+ timeList = new QObjectList();
+ imageList = new QObjectList();
+ menuList = new QObjectList();
+ menuList->setAutoDelete( true );
+
+ client = kapp->dcopClient();
+ if (!client->isAttached())
+ client->attach();
+ appId = client->registerAs(qApp->name());
+
+
+ setBackgroundMode( NoBackground);
+ if( !(onTop || managed))
+ KWin::lowerWindow( winId() );
+
+ if( !parseConfig() )
+ {
+ setFixedSize(0,0);
+ QTimer::singleShot( 100, this, SLOT(killWidget()) );
+ qWarning("Could not read config file.");
+ }
+ else
+ {
+ kroot = new KarambaRootPixmap((QWidget*)this);
+ kroot->start();
+ }
+
+ // Karamba specific Config Entries
+ bool locked = toggleLocked->isChecked();
+ locked = config->readBoolEntry("lockedPosition", locked);
+ toggleLocked->setChecked(locked);
+ slotToggleLocked();
+
+ if (!config -> readBoolEntry("fastTransforms", true))
+ {
+ toggleFastTransforms -> setChecked(false);
+ slotToggleFastTransforms();
+ }
+
+ desktop = config -> readNumEntry("desktop", desktop);
+ if (desktop > kWinModule->numberOfDesktops())
+ {
+ desktop = 0;
+ }
+
+ if (desktop)
+ {
+ info->setDesktop( desktop );
+ }
+ else
+ info->setDesktop( NETWinInfo::OnAllDesktops);
+
+ // Read Themespecific Config Entries
+ config -> setGroup("theme");
+ if (config -> hasKey("widgetPosX") && config -> hasKey("widgetPosY"))
+ {
+ int xpos = config -> readNumEntry("widgetPosX");
+ int ypos = config -> readNumEntry("widgetPosY");
+
+ if (xpos < 0)
+ xpos = 0;
+ if (ypos < 0)
+ ypos = 0;
+ move(xpos, ypos);
+ }
+
+ haveUpdated = 0;
+ this->setMouseTracking(true);
+
+
+ setFocusPolicy(QWidget::StrongFocus);
+}
+
+karamba::~karamba()
+{
+ //qDebug("karamba::~karamba");
+ //Remove self from list of open themes
+ karambaApp->deleteKaramba(this, m_reloading);
+
+ widgetClosed();
+ if(m_theme.isValid())
+ writeConfigData();
+
+ delete config;
+
+ if(meterList != 0)
+ {
+ meterList->clear();
+ delete meterList;
+ }
+
+ if( sensorList != 0 )
+ {
+ sensorList->clear();
+ delete sensorList;
+ }
+
+ if( imageList != 0 )
+ {
+ imageList->clear();
+ delete imageList;
+ }
+
+ if( clickList != 0 )
+ {
+ clickList->clear();
+ delete clickList;
+ }
+
+ if( timeList != 0 )
+ {
+ timeList->clear();
+ delete timeList;
+ }
+
+ delete toggleLocked;
+ delete accColl;
+ delete menuAccColl;
+ delete themeConfMenu;
+ delete kpop;
+ delete widgetMask;
+ delete kWinModule;
+ delete defaultTextField;
+ if (pythonIface != NULL)
+ delete pythonIface;
+}
+
+bool karamba::parseConfig()
+{
+ //qDebug("karamba::parseConfig");
+ bool passive = true;
+
+ if(m_theme.open())
+ {
+ QValueStack<QPoint> offsetStack;
+ LineParser lineParser;
+ int x=0;
+ int y=0;
+ int w=0;
+ int h=0;
+
+ offsetStack.push(QPoint(0,0));
+
+ while(m_theme.nextLine(lineParser))
+ {
+ x = lineParser.getInt("X") + offsetStack.top().x();
+ y = lineParser.getInt("Y") + offsetStack.top().y();
+ w = lineParser.getInt("W");
+ h = lineParser.getInt("H");
+
+ if(lineParser.meter() == "KARAMBA" && !foundKaramba )
+ {
+ //qDebug("karamba found");
+ toggleLocked->setChecked(lineParser.getBoolean("LOCKED"));
+ slotToggleLocked();
+
+ x = ( x < 0 ) ? 0:x;
+ y = ( y < 0 ) ? 0:y;
+
+ if( w == 0 || h == 0)
+ {
+ w = 300;
+ h = 300;
+ }
+ setFixedSize(w,h);
+
+ if(lineParser.getBoolean("RIGHT"))
+ {
+ QDesktopWidget *d = QApplication::desktop();
+ x = d->width() - w;
+ }
+ else if(lineParser.getBoolean("LEFT"))
+ {
+ x = 0;
+ }
+
+ if(lineParser.getBoolean("BOTTOM"))
+ {
+ QDesktopWidget *d = QApplication::desktop();
+ y = d->height() - h;
+ }
+ else if(lineParser.getBoolean("TOP"))
+ {
+ y = 0;
+ }
+
+ move(x,y);
+ //pm = QPixmap(size());
+
+ if(lineParser.getBoolean("ONTOP"))
+ {
+ onTop = true;
+ KWin::setState( winId(), NET::StaysOnTop );
+ }
+
+ if(lineParser.getBoolean("MANAGED"))
+ {
+ managed = true;
+ reparent(0, Qt::WType_Dialog | WStyle_Customize | WStyle_NormalBorder
+ | WRepaintNoErase | WDestructiveClose, pos());
+ }
+ else
+ {
+ info->setState( NETWinInfo::SkipTaskbar
+ | NETWinInfo::SkipPager,NETWinInfo::SkipTaskbar
+ | NETWinInfo::SkipPager );
+ if (onTop)
+ {
+ KWin::setState( winId(), NET::StaysOnTop );
+
+ }
+ }
+
+ if (lineParser.getBoolean("ONALLDESKTOPS"))
+ {
+ desktop = 200; // ugly
+ }
+
+
+ bool dfound=false;
+ //int desktop = lineParser.getInt("DESKTOP", line, dfound);
+ if (dfound)
+ {
+ info->setDesktop( dfound );
+ }
+ if(lineParser.getBoolean("TOPBAR"))
+ {
+ move(x,0);
+ KWin::setStrut( winId(), 0, 0, h, 0 );
+ toggleLocked->setChecked( true );
+ slotToggleLocked();
+ toggleLocked->setEnabled(false);
+ }
+
+ if(lineParser.getBoolean("BOTTOMBAR"))
+ {
+ int dh = QApplication::desktop()->height();
+ move( x, dh - h );
+ KWin::setStrut( winId(), 0, 0, 0, h );
+ toggleLocked->setChecked( true );
+ slotToggleLocked();
+ toggleLocked->setEnabled(false);
+ }
+
+ if(lineParser.getBoolean("RIGHTBAR"))
+ {
+ int dw = QApplication::desktop()->width();
+ move( dw - w, y );
+ KWin::setStrut( winId(), 0, w, 0, 0 );
+ toggleLocked->setChecked( true );
+ slotToggleLocked();
+ toggleLocked->setEnabled(false);
+ }
+
+ if(lineParser.getBoolean("LEFTBAR"))
+ {
+ move( 0, y );
+ KWin::setStrut( winId(), w, 0, 0, 0 );
+ toggleLocked->setChecked( true );
+ slotToggleLocked();
+ toggleLocked->setEnabled(false);
+ }
+
+ QString path = lineParser.getString("MASK");
+
+ QFileInfo info(path);
+ QString absPath;
+ QBitmap bmMask;
+ QByteArray ba;
+ if( info.isRelative() )
+ {
+ absPath.setAscii(m_theme.path().ascii());
+ absPath.append(path.ascii());
+ ba = m_theme.readThemeFile(path);
+ }
+ else
+ {
+ absPath.setAscii(path.ascii());
+ ba = m_theme.readThemeFile(info.fileName());
+ }
+ if(m_theme.isZipTheme())
+ {
+ bmMask.loadFromData(ba);
+ }
+ else
+ {
+ bmMask.load(absPath);
+ }
+ setMask(bmMask);
+
+ m_interval = lineParser.getInt("INTERVAL");
+ m_interval = (m_interval == 0) ? 1000 : m_interval;
+
+ QString temp = lineParser.getString("TEMPUNIT", "C").upper();
+ tempUnit = temp.ascii()[0];
+ foundKaramba = true;
+ }
+
+ if(lineParser.meter() == "THEME")
+ {
+ QString path = lineParser.getString("PATH");
+ QFileInfo info(path);
+ if( info.isRelative())
+ path = m_theme.path() +"/" + path;
+ (new karamba( path, QString() ))->show();
+ }
+
+ if(lineParser.meter() == "<GROUP>")
+ {
+ int offsetX = offsetStack.top().x();
+ int offsetY = offsetStack.top().y();
+ offsetStack.push( QPoint( offsetX + lineParser.getInt("X"),
+ offsetY + lineParser.getInt("Y")));
+ }
+
+ if(lineParser.meter() == "</GROUP>")
+ {
+ offsetStack.pop();
+ }
+
+ if(lineParser.meter() == "CLICKAREA")
+ {
+ if( !hasMouseTracking() )
+ setMouseTracking(true);
+ ClickArea *tmp = new ClickArea(this, x, y, w, h );
+ tmp->setOnClick(lineParser.getString("ONCLICK"));
+
+ setSensor(lineParser, (Meter*)tmp);
+ clickList->append( tmp );
+ if( lineParser.getBoolean("PREVIEW"))
+ meterList->append( tmp );
+ }
+
+ // program sensor without a meter
+ if(lineParser.meter() == "SENSOR=PROGRAM")
+ {
+ setSensor(lineParser, 0 );
+ }
+
+ if(lineParser.meter() == "IMAGE")
+ {
+ QString file = lineParser.getString("PATH");
+ QString file_roll = lineParser.getString("PATHROLL");
+ int xon = lineParser.getInt("XROLL");
+ int yon = lineParser.getInt("YROLL");
+ QString tiptext = lineParser.getString("TOOLTIP");
+ QString name = lineParser.getString("NAME");
+ bool bg = lineParser.getBoolean("BACKGROUND");
+ xon = ( xon <= 0 ) ? x:xon;
+ yon = ( yon <= 0 ) ? y:yon;
+
+ ImageLabel *tmp = new ImageLabel(this, x, y, 0, 0);
+ tmp->setValue(file);
+ if(!file_roll.isEmpty())
+ tmp->parseImages(file, file_roll, x,y, xon, yon);
+ tmp->setBackground(bg);
+ if (!name.isEmpty())
+ tmp->setName(name.ascii());
+ if (!tiptext.isEmpty())
+ tmp->setTooltip(tiptext);
+
+ connect(tmp, SIGNAL(pixmapLoaded()), this, SLOT(externalStep()));
+ setSensor(lineParser, (Meter*) tmp );
+ meterList->append (tmp );
+ imageList->append (tmp );
+ }
+
+ if(lineParser.meter() == "DEFAULTFONT" )
+ {
+ delete defaultTextField;
+ defaultTextField = new TextField( );
+
+ defaultTextField->setColor(lineParser.getColor("COLOR",
+ QColor("black")));
+ defaultTextField->setBGColor(lineParser.getColor("BGCOLOR",
+ QColor("white")));
+ defaultTextField->setFont(lineParser.getString("FONT", "Helvetica"));
+ defaultTextField->setFontSize(lineParser.getInt("FONTSIZE", 12));
+ defaultTextField->setAlignment(lineParser.getString("ALIGN",
+ "LEFT"));
+ defaultTextField->setFixedPitch(lineParser.getBoolean("FIXEDPITCH",
+ false));
+ defaultTextField->setShadow(lineParser.getInt("SHADOW", 0));
+ }
+
+ if(lineParser.meter() == "TEXT" ||
+ lineParser.meter() == "CLICKMAP" ||
+ lineParser.meter() == "RICHTEXT" ||
+ lineParser.meter() == "INPUT")
+ {
+ TextField defTxt;
+
+ if(defaultTextField)
+ defTxt = *defaultTextField;
+
+ TextField* tmpText = new TextField();
+
+ tmpText->setColor(lineParser.getColor("COLOR", defTxt.getColor()));
+ tmpText->setBGColor(lineParser.getColor("BGCOLOR",
+ defTxt.getBGColor()));
+ tmpText->setFont(lineParser.getString("FONT", defTxt.getFont()));
+ tmpText->setFontSize(lineParser.getInt("FONTSIZE",
+ defTxt.getFontSize()));
+ tmpText->setAlignment(lineParser.getString("ALIGN",
+ defTxt.getAlignmentAsString()));
+ tmpText->setFixedPitch(lineParser.getInt("FIXEDPITCH",
+ defTxt.getFixedPitch()));
+
+ tmpText->setShadow(lineParser.getInt("SHADOW", defTxt.getShadow()));
+
+ // ////////////////////////////////////////////////////
+ // Now handle the specifics
+ if(lineParser.meter() == "TEXT")
+ {
+
+ TextLabel *tmp = new TextLabel(this, x, y, w, h );
+ tmp->setTextProps(tmpText);
+ tmp->setValue(
+ m_theme.locale()->translate(lineParser.getString("VALUE")));
+
+ QString name = lineParser.getString("NAME");
+ if (!name.isEmpty())
+ tmp->setName(name.ascii());
+
+ setSensor(lineParser, (Meter*)tmp);
+ meterList->append ( tmp );
+ }
+
+ if(lineParser.meter() == "CLICKMAP")
+ {
+ if( !hasMouseTracking() )
+ setMouseTracking(true);
+ ClickMap *tmp = new ClickMap(this, x, y, w, h);
+ tmp->setTextProps( tmpText );
+
+ setSensor(lineParser, (Meter*)tmp);
+ // set all params
+ clickList -> append(tmp);
+ meterList->append( tmp );
+
+ }
+
+ if(lineParser.meter() == "RICHTEXT")
+ {
+ RichTextLabel *tmp = new RichTextLabel(this, x, y, w, h);
+
+ bool dUl = lineParser.getBoolean("UNDERLINE");
+
+ tmp->setText(
+ m_theme.locale()->translate(lineParser.getString("VALUE").ascii()), dUl);
+ tmp->setTextProps( tmpText );
+ tmp->setWidth(w);
+ tmp->setHeight(h);
+
+ QString name = lineParser.getString("NAME");
+ if (!name.isEmpty())
+ tmp->setName(name.ascii());
+
+ setSensor(lineParser, (Meter*)tmp);
+ clickList -> append(tmp);
+ meterList->append ( tmp );
+ }
+
+ if(lineParser.meter() == "INPUT")
+ {
+ Input *tmp = new Input(this, x, y, w, h);
+
+ QString name = lineParser.getString("NAME");
+ if (!name.isEmpty())
+ tmp->setName(name.ascii());
+
+ tmp->setTextProps(tmpText);
+ tmp->setValue(
+ m_theme.locale()->translate(lineParser.getString("VALUE").ascii()));
+
+ meterList->append(tmp);
+ passive = false;
+ }
+ }
+
+ if(lineParser.meter() == "BAR")
+ {
+ Bar *tmp = new Bar(this, x, y, w, h );
+ tmp->setImage(lineParser.getString("PATH").ascii());
+ tmp->setVertical(lineParser.getBoolean("VERTICAL"));
+ tmp->setMax(lineParser.getInt("MAX", 100));
+ tmp->setMin(lineParser.getInt("MIN", 0));
+ tmp->setValue(lineParser.getInt("VALUE"));
+ QString name = lineParser.getString("NAME");
+ if (!name.isEmpty())
+ tmp->setName(name.ascii());
+ setSensor(lineParser, (Meter*)tmp );
+ meterList->append ( tmp );
+ }
+
+ if(lineParser.meter() == "GRAPH")
+ {
+ int points = lineParser.getInt("POINTS");
+
+ Graph *tmp = new Graph(this, x, y, w, h, points);
+ tmp->setMax(lineParser.getInt("MAX", 100));
+ tmp->setMin(lineParser.getInt("MIN", 0));
+ QString name = lineParser.getString("NAME");
+ if (!name.isEmpty())
+ tmp->setName(name.ascii());
+
+ tmp->setColor(lineParser.getColor("COLOR"));
+
+ setSensor(lineParser, (Graph*)tmp);
+ meterList->append ( tmp );
+ }
+ }
+
+ if(passive && !managed)
+ {
+ // Matthew Kay: set window type to "dock"
+ // (plays better with taskbar themes this way)
+ KWin::setType(winId(), NET::Dock);
+ #if defined(KDE_MAKE_VERSION)
+ #if KDE_VERSION >= KDE_MAKE_VERSION(3,1,9)
+ //KDE 3.2 addition for the always on top issues
+ KWin::setState(winId(), NET::KeepBelow);
+ #endif
+ #endif
+ }
+
+ m_theme.close();
+ }
+ //qDebug("parseConfig ok: %d", foundKaramba);
+ if( !foundKaramba )
+ {
+ // interval = initKaramba( "", 0, 0, 0, 0 );
+ // this->close(true);
+ //delete this;
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+}
+
+void karamba::start()
+{
+ m_sysTimer = new QTimer(this);
+
+ connect(m_sysTimer, SIGNAL(timeout()), SLOT(step()));
+
+ m_sysTimer->start(m_interval);
+
+ //Start the widget running
+ QTimer::singleShot( 0, this, SLOT(step()) );
+
+ if( !(onTop || managed) )
+ lowerTimer.start();
+}
+
+void karamba::makeActive()
+{
+ KWin::setType(winId(), NET::Normal);
+
+ #if defined(KDE_MAKE_VERSION)
+ #if KDE_VERSION >= KDE_MAKE_VERSION(3,1,9)
+ //KDE 3.2 addition for the always on top issues
+ KWin::setState(winId(), NET::Modal);
+ #endif
+ #endif
+}
+
+void karamba::makePassive()
+{
+ if(managed)
+ return;
+
+ QObject *meter;
+ for (meter = meterList->first(); meter; meter = meterList->next())
+ {
+ if((meter)->isA("Input"))
+ return;
+ }
+
+ // Matthew Kay: set window type to "dock" (plays better with taskbar themes
+ // this way)
+ KWin::setType(winId(), NET::Dock);
+ #if defined(KDE_MAKE_VERSION)
+ #if KDE_VERSION >= KDE_MAKE_VERSION(3,1,9)
+ //KDE 3.2 addition for the always on top issues
+ KWin::setState(winId(), NET::KeepBelow);
+ #endif
+ #endif
+}
+
+void karamba::popupNotify(int)
+{
+ //qDebug("karamba::popupNotify");
+}
+
+void karamba::reloadConfig()
+{
+ //qDebug("karamba::reloadConfig: %s", m_theme.file().ascii());
+ writeConfigData();
+ if(m_theme.exists())
+ {
+ QFileInfo fileInfo( m_theme.file() );
+ (new karamba(m_theme.file(), fileInfo.baseName(), true, m_instance))->show();
+ }
+ closeTheme(true);
+}
+
+void karamba::closeTheme(bool reloading)
+{
+ m_reloading = reloading;
+ close();
+}
+
+void karamba::killWidget()
+{
+ closeTheme();
+}
+
+void karamba::initPythonInterface()
+{
+ pythonIface = new KarambaPython(m_theme, m_reloading);
+}
+
+void karamba::editConfig()
+{
+ //qDebug("karamba::editConfig");
+ QFileInfo fileInfo( m_theme.file() );
+ QString path;
+
+ if( fileInfo.isRelative() )
+ {
+ path = m_theme.path() + "/" + m_theme.file();
+ }
+ else
+ {
+ path = m_theme.file();
+ }
+
+ KRun::runURL( KURL( path ), "text/plain" );
+}
+
+void karamba::editScript()
+{
+ //qDebug("karamba::editScript");
+ QFileInfo fileInfo( m_theme.file() );
+ QString path;
+
+ if( fileInfo.isRelative() )
+ {
+ path = m_theme.path() + "/" + m_theme.name() + ".py";
+ }
+ else
+ {
+ path = QFileInfo(m_theme.file()).dirPath() + "/" + m_theme.name() + ".py";
+ }
+ KRun::runURL( KURL( path ), "text/plain" );
+}
+
+QString karamba::findSensorFromMap(Sensor* sensor)
+{
+ //qDebug("karamba::findSensorFromMap");
+ QMap<QString,Sensor*>::ConstIterator it;
+ QMap<QString,Sensor*>::ConstIterator end( sensorMap.end() );
+ for ( it = sensorMap.begin(); it != end; ++it )
+ {
+ if (it.data() == sensor)
+ return it.key();
+ }
+ return "";
+}
+
+Sensor* karamba::findSensorFromList(Meter* meter)
+{
+ //qDebug("karamba::findSensorFromList");
+ QObjectListIt it( *sensorList ); // iterate over meters
+
+ while ( it != 0 )
+ {
+ if (((Sensor*) *it)->hasMeter(meter))
+ return ((Sensor*)*it);
+ ++it;
+ }
+ return NULL;
+}
+
+QString karamba::getSensor(Meter* meter)
+{
+ //qDebug("karamba::getSensor");
+ QString s;
+ Sensor* sensor = findSensorFromList(meter);
+ if (sensor)
+ s = findSensorFromMap(sensor);
+ return s;
+}
+
+void karamba::deleteMeterFromSensors(Meter* meter)
+{
+ //qDebug("karamba::deleteMeterFromSensors");
+ Sensor* sensor = findSensorFromList(meter);
+
+ if (sensor)
+ {
+ sensor->deleteMeter(meter);
+ if (sensor->isEmpty())
+ {
+ QString s = findSensorFromMap(sensor);
+ sensorMap.erase(s);
+ sensorList->removeRef(sensor);
+ }
+ }
+}
+
+void karamba::setSensor(const LineParser& lineParser, Meter* meter)
+{
+ //qDebug("karamba::setSensor");
+ Sensor* sensor = 0;
+
+ deleteMeterFromSensors(meter);
+
+ QString sens = lineParser.getString("SENSOR").upper();
+
+ if( sens == "CPU" )
+ {
+ QString cpuNbr = lineParser.getString("CPU");
+ sensor = sensorMap["CPU"+cpuNbr];
+ if (sensor == 0)
+ {
+ int interval = lineParser.getInt("INTERVAL");
+ interval = (interval == 0)?1000:interval;
+ sensor = ( sensorMap["CPU"+cpuNbr] = new CPUSensor( cpuNbr, interval ) );
+ sensorList->append( sensor );
+ }
+ SensorParams *sp = new SensorParams(meter);
+ sp->addParam("FORMAT",
+ m_theme.locale()->translate(lineParser.getString("FORMAT").ascii()));
+ sp->addParam("DECIMALS",lineParser.getString("DECIMALS"));
+
+ sensor->addMeter(sp);
+ sensor->setMaxValue(sp);
+
+ }
+
+ if( sens == "MEMORY" )
+ {
+ sensor = sensorMap["MEMORY"];
+ if (sensor == 0)
+ {
+ int interval = lineParser.getInt("INTERVAL");
+ interval = (interval == 0)?3000:interval;
+ sensor = ( sensorMap["MEMORY"] = new MemSensor( interval ) );
+ sensorList->append( sensor );
+ }
+ SensorParams *sp = new SensorParams(meter);
+ sp->addParam("FORMAT",
+ m_theme.locale()->translate(lineParser.getString("FORMAT").ascii()));
+
+ sensor->addMeter(sp);
+ sensor->setMaxValue(sp);
+ }
+
+
+ if( sens == "DISK" )
+ {
+ sensor = sensorMap["DISK"];
+ if (sensor == 0)
+ {
+ int interval = lineParser.getInt("INTERVAL");
+ interval = (interval == 0)?5000:interval;
+ sensor = ( sensorMap["DISK"] = new DiskSensor( interval ) );
+ connect( sensor, SIGNAL(initComplete()), this, SLOT(externalStep()) );
+ sensorList->append( sensor );
+ }
+ // meter->setMax( ((DiskSensor*)sensor)->getTotalSpace(mntPt)/1024 );
+ SensorParams *sp = new SensorParams(meter);
+ QString mntPt = lineParser.getString("MOUNTPOINT");
+ if( mntPt.isEmpty() )
+ {
+ mntPt = "/";
+ }
+ // remove any trailing '/' from mount points in the .theme config, our
+ // mntMap doesn't like trailing '/'s for matching in DiskSensor
+ if( mntPt.length() > 1 && mntPt.endsWith("/") )
+ {
+ mntPt.remove( mntPt.length()-1, 1 );
+ }
+ sp->addParam("MOUNTPOINT",mntPt);
+ sp->addParam("FORMAT",
+ m_theme.locale()->translate(lineParser.getString("FORMAT").ascii()));
+ sensor->addMeter(sp);
+ sensor->setMaxValue(sp);
+ }
+
+ if( sens == "NETWORK")
+ {
+ int interval = lineParser.getInt("INTERVAL");
+ interval = (interval == 0)?2000:interval;
+ QString device = lineParser.getString("DEVICE");
+ sensor = sensorMap["NETWORK"+device];
+ if (sensor == 0)
+ {
+ sensor = ( sensorMap["NETWORK"+device] =
+ new NetworkSensor(device, interval));
+ sensorList->append( sensor );
+ }
+ SensorParams *sp = new SensorParams(meter);
+ sp->addParam("FORMAT",
+ m_theme.locale()->translate(lineParser.getString("FORMAT").ascii()));
+ sp->addParam("DECIMALS", lineParser.getString("DECIMALS"));
+ sensor->addMeter(sp);
+ }
+
+ if( sens == "UPTIME" )
+ {
+ sensor = sensorMap["UPTIME"];
+ if (sensor == 0)
+ {
+ int interval = lineParser.getInt("INTERVAL");
+ interval = (interval == 0)?60000:interval;
+ sensor = ( sensorMap["UPTIME"] = new UptimeSensor( interval ));
+ sensorList->append( sensor );
+
+ }
+ SensorParams *sp = new SensorParams(meter);
+ sp->addParam("FORMAT",
+ m_theme.locale()->translate(lineParser.getString("FORMAT").ascii()));
+ sensor->addMeter(sp);
+ }
+
+ if( sens == "SENSOR" )
+ {
+ sensor = sensorMap["SENSOR"];
+ if (sensor == 0)
+ {
+ int interval = lineParser.getInt("INTERVAL");
+ interval = (interval == 0)?30000:interval;
+ sensor = (sensorMap["SENSOR"] = new SensorSensor(interval, tempUnit));
+ sensorList->append( sensor );
+ }
+ SensorParams *sp = new SensorParams(meter);
+ sp->addParam("FORMAT",
+ m_theme.locale()->translate(lineParser.getString("FORMAT").ascii()));
+ sp->addParam("TYPE", lineParser.getString("TYPE"));
+ sensor->addMeter(sp);
+ }
+
+
+ if( sens == "TEXTFILE" )
+ {
+ QString path = lineParser.getString("PATH");
+ bool rdf = lineParser.getBoolean("RDF");
+ sensor = sensorMap["TEXTFILE"+path];
+ if (sensor == 0)
+ {
+ int interval = lineParser.getInt("INTERVAL");
+ interval = ( interval == 0 )?60000:interval;
+ QString encoding = lineParser.getString("ENCODING");
+
+ sensor = ( sensorMap["TEXTFILE"+path] =
+ new TextFileSensor( path, rdf, interval, encoding ) );
+ sensorList->append( sensor );
+ }
+ SensorParams *sp = new SensorParams(meter);
+ sp->addParam("LINE",QString::number(lineParser.getInt("LINE")));
+ sensor->addMeter(sp);
+ }
+
+
+ if( sens == "TIME")
+ {
+ sensor = sensorMap["DATE"];
+ if (sensor == 0)
+ {
+ int interval = lineParser.getInt("INTERVAL");
+ interval = (interval == 0)?60000:interval;
+ sensor = ( sensorMap["DATE"] = new DateSensor( interval ) );
+ sensorList->append( sensor );
+ timeList->append( sensor );
+ }
+ SensorParams *sp = new SensorParams(meter);
+ sp->addParam("FORMAT",
+ m_theme.locale()->translate(lineParser.getString("FORMAT").ascii()));
+ sp->addParam("CALWIDTH",lineParser.getString("CALWIDTH"));
+ sp->addParam("CALHEIGHT",lineParser.getString("CALHEIGHT"));
+ sensor->addMeter(sp);
+ }
+
+#ifdef HAVE_XMMS
+
+ if( sens == "XMMS" )
+ {
+ sensor = sensorMap["XMMS"];
+ if (sensor == 0)
+ {
+ int interval = lineParser.getInt("INTERVAL");
+ interval = (interval == 0)?1000:interval;
+ QString encoding = lineParser.getString("ENCODING");
+
+ sensor = ( sensorMap["XMMS"] = new XMMSSensor( interval, encoding ) );
+ sensorList->append( sensor );
+ }
+ SensorParams *sp = new SensorParams(meter);
+ sp->addParam("FORMAT",
+ m_theme.locale()->translate(lineParser.getString("FORMAT").ascii()));
+ sensor->addMeter(sp);
+ sensor->setMaxValue(sp);
+ }
+#endif // HAVE_XMMS
+
+
+ if( sens == "NOATUN" )
+ {
+ sensor = sensorMap["NOATUN"];
+ if (sensor == 0)
+ {
+ int interval = lineParser.getInt("INTERVAL");
+ interval = (interval == 0)?1000:interval;
+ sensor = ( sensorMap["NOATUN"] = new NoatunSensor( interval, client ) );
+ sensorList->append( sensor );
+ }
+ SensorParams *sp = new SensorParams(meter);
+ sp->addParam("FORMAT",
+ m_theme.locale()->translate(lineParser.getString("FORMAT").ascii()));
+ sensor->addMeter(sp);
+ sensor->setMaxValue(sp);
+ }
+
+ if( sens == "PROGRAM")
+ {
+ QString progName = lineParser.getString("PROGRAM");
+ sensor = sensorMap["PROGRAM"+progName];
+ if (sensor == 0)
+ {
+ int interval = lineParser.getInt("INTERVAL");
+ interval = (interval == 0)?3600000:interval;
+ QString encoding = lineParser.getString("ENCODING");
+
+ sensor = (sensorMap["PROGRAM"+progName] =
+ new ProgramSensor( progName, interval, encoding ) );
+ sensorList->append( sensor );
+ }
+ SensorParams *sp = new SensorParams(meter);
+ sp->addParam( "LINE", QString::number(lineParser.getInt("LINE")));
+ sp->addParam( "THEMAPATH", m_theme.path() );
+ sensor->addMeter(sp);
+ }
+
+ if( sens == "RSS" )
+ {
+ QString source = lineParser.getString("SOURCE");
+ QString format =
+ m_theme.locale()->translate(lineParser.getString("FORMAT").ascii());
+
+ sensor = sensorMap["RSS"+source];
+ if (sensor == 0)
+ {
+ int interval = lineParser.getInt( "INTERVAL");
+ interval = ( interval == 0 )?60000:interval;
+ QString encoding = lineParser.getString("ENCODING");
+
+ sensor = ( sensorMap["RSS"+source] =
+ new RssSensor( source, interval, format, encoding ) );
+ sensorList->append( sensor );
+ }
+ SensorParams *sp = new SensorParams(meter);
+ sp->addParam("SOURCE",lineParser.getString("SOURCE"));
+ sensor->addMeter(sp);
+ }
+
+ if (sensor != 0)
+ {
+ QTimer::singleShot( 0, sensor, SLOT(update()) );
+ sensor->start();
+ }
+}
+
+void karamba::slotFileChanged( const QString & file)
+{
+ //kdDebug() << "fileChanged: " << file << endl;
+
+ QString pythonFile = m_theme.path() + "/" + m_theme.pythonModule() + ".py";
+
+ if(file == m_theme.file() || file == pythonFile)
+ reloadConfig();
+}
+
+void karamba::passMenuOptionChanged(QString key, bool value)
+{
+ //Everything below is to call the python callback function
+ if (pythonIface && pythonIface->isExtensionLoaded())
+ pythonIface->menuOptionChanged(this, key, value);
+}
+
+void karamba::setIncomingData(QString theme, QString obj)
+{
+ KarambaApplication* app = (KarambaApplication*)qApp;
+
+ kdDebug() << "karamba::setIncomingData " << theme << obj << endl;
+ //QByteArray data;
+ //QDataStream dataStream( data, IO_WriteOnly );
+ //dataStream << theme;
+ //dataStream << txt;
+
+ //kapp->dcopClient()->send( app->dcopClient()->appId(), "KarambaIface", "themeNotify(QString,QString)", data );
+
+ DCOPClient *c = kapp->dcopClient();
+ if (!c->isAttached())
+ c->attach();
+
+ if(app->dcopStub())
+ app->dcopStub()->setIncomingData(theme, obj);
+}
+
+void karamba::callTheme(QString theme, QString txt)
+{
+ KarambaApplication* app = (KarambaApplication*)qApp;
+ kdDebug() << "karamba::callTheme " << theme << txt << endl;
+ //qWarning("karamba::callTheme");
+ //QByteArray data;
+ //QDataStream dataStream( data, IO_WriteOnly );
+ //dataStream << theme;
+ //dataStream << txt;
+
+ //kapp->dcopClient()->send( app->dcopClient()->appId(), "KarambaIface", "themeNotify(QString,QString)", data );
+
+ DCOPClient *c = kapp->dcopClient();
+ if (!c->isAttached())
+ c->attach();
+
+ if(app->dcopStub())
+ app->dcopStub()->themeNotify(theme, txt);
+}
+
+void karamba::themeNotify(QString theme, QString txt)
+{
+ kdDebug() << "karamba::themeNotify" << theme << txt << endl;
+ if (pythonIface->isExtensionLoaded())
+ {
+ pythonIface->themeNotify(this, theme.ascii(), txt.ascii());
+ }
+}
+
+void karamba::meterClicked(QMouseEvent* e, Meter* meter)
+{
+ //qWarning("karamba::meterClicked");
+ if (pythonIface && pythonIface->isExtensionLoaded() && haveUpdated)
+ {
+ int button = 0;
+
+ if( e->button() == Qt::LeftButton )
+ button = 1;
+ else if( e->button() == Qt::MidButton )
+ button = 2;
+ else if( e->button() == Qt::RightButton )
+ button = 3;
+
+ if (RichTextLabel* richText = dynamic_cast<RichTextLabel*>(meter))
+ {
+ pythonIface->meterClicked(this, richText->anchorAt(e->x(), e->y()),
+ button);
+ }
+ else
+ {
+ pythonIface->meterClicked(this, meter, button);
+ }
+ }
+}
+
+void karamba::changeInterval(int interval)
+{
+ if (m_sysTimer != NULL)
+ m_sysTimer->changeInterval(interval);
+}
+
+void karamba::passClick(QMouseEvent *e)
+{
+ //qDebug("karamba::passClick");
+ QObjectListIt it2( *timeList ); // iterate over meters
+ while ( it2 != 0 )
+ {
+ (( DateSensor* ) *it2)->toggleCalendar( e );
+ ++it2;
+ }
+
+
+ // We create a temporary click list here because original
+ // can change during the loop (infinite loop Bug 994359)
+ QObjectList clickListTmp(*clickList);
+ QObjectListIt it(clickListTmp);
+ while (it != 0)
+ {
+ Meter* meter = (Meter*)(*it);
+ // Check if meter is still in list
+ if (clickList->containsRef(meter) && meter->click(e))
+ {
+ // callback
+ meterClicked(e, meter);
+ }
+ ++it;
+ }
+
+ //Everything below is to call the python callback function
+ if (pythonIface && pythonIface->isExtensionLoaded() && haveUpdated)
+ {
+ int button = 0;
+
+ if( e->button() == Qt::LeftButton )
+ button = 1;
+ else if( e->button() == Qt::MidButton )
+ button = 2;
+ else if( e->button() == Qt::RightButton )
+ button = 3;
+
+ pythonIface->widgetClicked(this, e->x(), e->y(), button);
+ }
+}
+
+void karamba::passWheelClick( QWheelEvent *e )
+{
+ //qDebug("karamba::passWheelClick");
+ //Everything below is to call the python callback function
+ if (pythonIface && pythonIface->isExtensionLoaded() && haveUpdated)
+ {
+ int button = 0;
+
+ if( e->delta() > 0 )
+ button = 4;
+ else
+ button = 5;
+
+ // We create a temporary click list here because original
+ // can change during the loop (infinite loop Bug 994359)
+ if (want_meter_wheel_event)
+ {
+ QObjectList clickListTmp(*clickList);
+ QObjectListIt it(clickListTmp);
+
+ QMouseEvent fakeEvent(QEvent::MouseButtonPress, e->pos(), e->globalPos(), button, e->state());
+
+ while (it != 0)
+ {
+ Meter* meter = (Meter*)(*it);
+ // Check if meter is still in list
+ if (clickList->containsRef(meter) && meter->click(&fakeEvent))
+ {
+ if (RichTextLabel* richText = dynamic_cast<RichTextLabel*>(meter))
+ {
+ pythonIface->meterClicked(this, richText->anchorAt(fakeEvent.x(), fakeEvent.y()),
+ button);
+ }
+ else
+ {
+ pythonIface->meterClicked(this, meter, button);
+ }
+ }
+ ++it;
+ }
+ }
+
+ pythonIface->widgetClicked(this, e->x(), e->y(), button);
+ }
+}
+
+void karamba::management_popup( void )
+{
+ kpop->popup(QCursor::pos());
+}
+
+void karamba::mousePressEvent( QMouseEvent *e )
+{
+ //qDebug("karamba::mousePressEvent");
+ if( e->button() == RightButton && !want_right_button )
+ {
+ management_popup();
+ }
+ else
+ {
+ clickPos = e->pos();
+ if( toggleLocked -> isChecked() )
+ passClick( e );
+ if( !(onTop || managed))
+ KWin::lowerWindow( winId() );
+ }
+}
+
+void karamba::wheelEvent( QWheelEvent *e )
+{
+ //qDebug("karamba::wheelEvent");
+ passWheelClick( e );
+}
+
+void karamba::mouseReleaseEvent( QMouseEvent *e )
+{
+ //qDebug("karamba::mouseReleaseEvent");
+ clickPos = e->pos();
+}
+
+void karamba::mouseDoubleClickEvent( QMouseEvent *e )
+{
+ //qDebug("karamba::mouseDoubleClickEvent");
+ if( !toggleLocked -> isChecked() )
+ {
+ passClick( e );
+ }
+}
+
+void karamba::keyPressEvent(QKeyEvent *e)
+{
+ //qDebug("karamba::keyPressEvent");
+ keyPressed(e->text(), 0);
+}
+
+void karamba::keyPressed(const QString& s, const Meter* meter)
+{
+ if (pythonIface && pythonIface->isExtensionLoaded())
+ pythonIface->keyPressed(this, meter, s);
+}
+
+void karamba::mouseMoveEvent( QMouseEvent *e )
+{
+ //qDebug("karamba::mouseMoveEvent");
+ if( e->state() != 0 && e->state() < 16 && !toggleLocked -> isChecked() )
+ {
+ move( e->globalPos() - clickPos );
+ }
+ else
+ {
+ // Change cursor over ClickArea
+ QObjectListIt it(*clickList);
+ bool insideArea = false;
+
+ while (it != 0)
+ {
+ insideArea = ((Meter*)(*it)) -> insideActiveArea(e -> x(), e ->y());
+ if (insideArea)
+ {
+ break;
+ }
+ ++it;
+ }
+
+ if(insideArea)
+ {
+ if( cursor().shape() != PointingHandCursor )
+ setCursor( PointingHandCursor );
+ }
+ else
+ {
+ if( cursor().shape() != ArrowCursor )
+ setCursor( ArrowCursor );
+ }
+
+ QObjectListIt image_it( *imageList); // iterate over image sensors
+ while ( image_it != 0 )
+ {
+ ((ImageLabel*) *image_it)->rolloverImage(e);
+ ++image_it;
+ }
+ }
+
+ if (pythonIface && pythonIface->isExtensionLoaded())
+ {
+ int button = 0;
+
+ //Modified by Ryan Nickell (p0z3r@mail.com) 03/16/2004
+ // This will work now, but only when you move at least
+ // one pixel in any direction with your mouse.
+ //if( e->button() == Qt::LeftButton )
+ if( e->state() == LeftButton)
+ button = 1;
+ //else if( e->button() == Qt::MidButton )
+ else if( e->state() == MidButton )
+ button = 2;
+ //else if( e->button() == Qt::RightButton )
+ else if( e->state() == RightButton )
+ button = 3;
+
+ pythonIface->widgetMouseMoved(this, e->x(), e->y(), button);
+ }
+}
+
+void karamba::closeEvent ( QCloseEvent * qc)
+{
+ //qDebug("karamba::closeEvent");
+ qc->accept();
+ // close(true);
+ // delete this;
+}
+
+void karamba::paintEvent ( QPaintEvent *e)
+{
+ //kdDebug() << k_funcinfo << pm.size() << endl;
+ if(pm.width() == 0)
+ return;
+ if( !(onTop || managed))
+ {
+ if( lowerTimer.elapsed() > 100 )
+ {
+ KWin::lowerWindow( winId() );
+ lowerTimer.restart();
+ }
+ }
+ QRect rect = e->rect();
+ bitBlt(this,rect.topLeft(),&pm,rect,Qt::CopyROP);
+}
+
+void karamba::updateSensors()
+{
+ //qDebug("karamba::updateSensors");
+ QObjectListIt it( *sensorList ); // iterate over meters
+ while ( it != 0 )
+ {
+ ((Sensor*) *it)->update();
+ ++it;
+ }
+ QTimer::singleShot( 500, this, SLOT(step()) );
+}
+
+void karamba::updateBackground(KSharedPixmap* kpm)
+{
+ //kdDebug() << k_funcinfo << pm.size() << endl;
+ // if pm width == 0 this is the first time we come here and we should start
+ // the theme. This is because we need the background before starting.
+ //if(pm.width() == 0)
+ if( !themeStarted )
+ {
+ themeStarted = true;
+ start();
+ }
+ background = QPixmap(*kpm);
+
+ QPixmap buffer = QPixmap(size());
+
+ pm = QPixmap(size());
+ buffer.fill(Qt::black);
+
+ QObjectListIt it( *imageList ); // iterate over meters
+ p.begin(&buffer);
+ bitBlt(&buffer,0,0,&background,0,Qt::CopyROP);
+
+ while ( it != 0 )
+ {
+ if (((ImageLabel*) *it)->background == 1)
+ {
+ ((ImageLabel*) *it)->mUpdate(&p, 1);
+ }
+ ++it;
+ }
+ p.end();
+
+ bitBlt(&pm,0,0,&buffer,0,Qt::CopyROP);
+ background = pm;
+
+ QPixmap buffer2 = QPixmap(size());
+
+ pm = QPixmap(size());
+ buffer2.fill(Qt::black);
+
+ QObjectListIt it2( *meterList ); // iterate over meters
+ p.begin(&buffer2);
+ bitBlt(&buffer2,0,0,&background,0,Qt::CopyROP);
+
+ while ( it2 != 0 )
+ {
+ ((Meter*) *it2)->mUpdate(&p);
+ ++it2;
+ }
+ p.end();
+
+ bitBlt(&pm,0,0,&buffer2,0,Qt::CopyROP);
+ if (systray != 0)
+ {
+ systray->updateBackgroundPixmap(buffer2);
+ }
+ repaint();
+}
+
+void karamba::currentDesktopChanged( int i )
+{
+ //qDebug("karamba::currentDesktopChanged");
+ kroot->repaint( true );
+ if (pythonIface && pythonIface->isExtensionLoaded())
+ pythonIface->desktopChanged(this, i);
+}
+
+void karamba::currentWallpaperChanged(int i )
+{
+ //qDebug("karamba::currentWallpaperChanged");
+ kroot->repaint( true );
+ if (pythonIface && pythonIface->isExtensionLoaded())
+ pythonIface->wallpaperChanged(this, i);
+}
+
+void karamba::externalStep()
+{
+ //kdDebug() << k_funcinfo << pm.size() << endl;
+ if (widgetUpdate)
+ {
+ QPixmap buffer = QPixmap(size());
+
+ pm = QPixmap(size());
+ buffer.fill(Qt::black);
+
+ QObjectListIt it( *meterList ); // iterate over meters
+ p.begin(&buffer);
+ bitBlt(&buffer,0,0,&background,0,Qt::CopyROP);
+
+ while ( it != 0 )
+ {
+ ((Meter*) *it)->mUpdate(&p);
+ ++it;
+ }
+ p.end();
+
+ bitBlt(&pm,0,0,&buffer,0,Qt::CopyROP);
+ repaint();
+ }
+}
+
+void karamba::step()
+{
+ //kdDebug() << k_funcinfo << pm.size() << endl;
+ if (widgetUpdate && haveUpdated)
+ {
+ pm = QPixmap(size());
+ QPixmap buffer = QPixmap(size());
+ buffer.fill(Qt::black);
+
+ QObjectListIt it( *meterList ); // iterate over meters
+ p.begin(&buffer);
+
+ bitBlt(&buffer,0,0,&background,0,Qt::CopyROP);
+
+ while (it != 0)
+ {
+ ((Meter*) *it)->mUpdate(&p);
+ ++it;
+ }
+ p.end();
+
+ bitBlt(&pm,0,0,&buffer,0,Qt::CopyROP);
+ update();
+ }
+
+ if (pythonIface && pythonIface->isExtensionLoaded())
+ {
+ if (haveUpdated == 0)
+ pythonIface->initWidget(this);
+ else
+ pythonIface->widgetUpdated(this);
+ }
+
+ if (haveUpdated == 0)
+ haveUpdated = 1;
+}
+
+void karamba::widgetClosed()
+{
+ //qDebug("karamba::widgetClosed");
+ if (pythonIface && pythonIface->isExtensionLoaded())
+ pythonIface->widgetClosed(this);
+}
+
+void karamba::slotToggleLocked()
+{
+ //qDebug("karamba::slotToggleLocked");
+ if(toggleLocked->isChecked())
+ {
+ toggleLocked->setIconSet(SmallIconSet("lock"));
+ }
+ else
+ {
+ toggleLocked->setIconSet(SmallIconSet("move"));
+ }
+}
+
+void karamba::slotToggleFastTransforms()
+{
+ //qDebug("karamba::slotToggleFastTransforms");
+ // bool fastTransforms = toggleFastTransforms -> isChecked();
+ // if (toggleFastTransforms -> isChecked())
+ // {
+ // toggleFastTransforms -> setIconSet(SmallIconSet("ok"));
+ // }
+ // else
+ // {
+ // QPixmap ok_disabled;
+ // toggleFastTransforms -> setIconSet(ok_disabled);
+ // }
+ //config.setGroup("internal");
+ //config.writeEntry("fastTransforms", toggleFastTransforms -> isChecked());
+}
+
+
+bool karamba::useSmoothTransforms()
+{
+ //qDebug("karamba::useSmoothTransforms");
+ return !toggleFastTransforms -> isChecked();
+}
+
+void karamba::writeConfigData()
+{
+ //qDebug("karamba::writeConfigData");
+ config -> setGroup("internal");
+ config -> writeEntry("lockedPosition", toggleLocked -> isChecked() );
+ config -> writeEntry("fastTransforms", toggleFastTransforms -> isChecked() );
+ config -> writeEntry("desktop", desktop );
+ config -> setGroup("theme");
+ // Widget Position
+ config -> writeEntry("widgetPosX", x());
+ config -> writeEntry("widgetPosY", y());
+ // Widget Size
+ config -> writeEntry("widgetWidth", width());
+ config -> writeEntry("widgetHeight", height());
+
+ // write changes to DiskSensor
+ config -> sync();
+ //qWarning("Config File ~/.superkaramba/%s.rc written.",
+ // m_theme.name().ascii());
+}
+
+void karamba::slotToggleConfigOption(QString key, bool value)
+{
+ //qDebug("karamba::slotToggleConfigOption");
+ config -> setGroup("config menu");
+ config -> writeEntry(key, value);
+ passMenuOptionChanged(key, value);
+}
+
+void karamba::addMenuConfigOption(QString key, QString name)
+{
+ //qDebug("karamba::addMenuConfigOption");
+ kpop -> setItemEnabled(THEMECONF, true);
+
+ SignalBridge* action = new SignalBridge(this, key, menuAccColl);
+ KToggleAction* confItem = new KToggleAction (name, KShortcut::null(),
+ action, SLOT(receive()),
+ menuAccColl, key.ascii());
+ confItem -> setName(key.ascii());
+
+ menuAccColl -> insert(confItem);
+
+ connect(action, SIGNAL( enabled(QString, bool) ),
+ this, SLOT( slotToggleConfigOption(QString, bool) ));
+
+ config -> setGroup("config menu");
+ confItem -> setChecked(config -> readBoolEntry(key));
+
+ confItem -> plug(themeConfMenu);
+
+ numberOfConfMenuItems++;
+}
+
+bool karamba::setMenuConfigOption(QString key, bool value)
+{
+ //qDebug("karamba::setMenuConfigOption");
+ KToggleAction* menuAction = ((KToggleAction*)menuAccColl -> action(key.ascii()));
+ if (menuAction == NULL)
+ {
+ qWarning("Menu action %s not found.", key.ascii());
+ return false;
+ }
+ else
+ {
+ menuAction -> setChecked(value);
+ return true;
+ }
+}
+
+bool karamba::readMenuConfigOption(QString key)
+{
+ //qDebug("karamba::readMenuConfigOption");
+ KToggleAction* menuAction = ((KToggleAction*)menuAccColl -> action(key.ascii()));
+ if (menuAction == NULL)
+ {
+ qWarning("Menu action %s not found.", key.ascii());
+ return false;
+ }
+ else
+ {
+ return menuAction -> isChecked();
+ }
+}
+
+void karamba::passMenuItemClicked(int id)
+{
+ //qDebug("karamba::passMenuItemClicked");
+ //Everything below is to call the python callback function
+ if (pythonIface && pythonIface->isExtensionLoaded())
+ {
+ KPopupMenu* menu = 0;
+ for(int i = 0; i < (int)menuList->count(); i++)
+ {
+ KPopupMenu* tmp;
+ if(i==0)
+ {
+ tmp = (KPopupMenu*) menuList->first();
+ }
+ else
+ {
+ tmp = (KPopupMenu*) menuList->next();
+ }
+ if(tmp != 0)
+ {
+ if(tmp->isItemVisible(id))
+ {
+ menu = tmp;
+ break;
+ }
+ }
+ }
+ pythonIface->menuItemClicked(this, menu, id);
+ }
+}
+
+void karamba::activeTaskChanged(Task* t)
+{
+ //qDebug("karamba::activeTaskChanged");
+ //Everything below is to call the python callback function
+ if (pythonIface && pythonIface->isExtensionLoaded())
+ pythonIface->activeTaskChanged(this, t);
+}
+
+void karamba::taskAdded(Task* t)
+{
+ //qDebug("karamba::taskAdded");
+ //Everything below is to call the python callback function
+ if (pythonIface && pythonIface->isExtensionLoaded())
+ pythonIface->taskAdded(this, t);
+}
+
+void karamba::taskRemoved(Task* t)
+{
+ //qDebug("karamba::taskRemoved");
+ //Everything below is to call the python callback function
+ if (pythonIface && pythonIface->isExtensionLoaded())
+ pythonIface->taskRemoved(this, t);
+}
+
+void karamba::startupAdded(Startup* t)
+{
+ //qDebug("karamba::startupAdded");
+ //Everything below is to call the python callback function
+ if (pythonIface && pythonIface->isExtensionLoaded())
+ pythonIface->startupAdded(this, t);
+}
+
+void karamba::startupRemoved(Startup* t)
+{
+ //qDebug("karamba::startupRemoved");
+ //Everything below is to call the python callback function
+ if (pythonIface && pythonIface->isExtensionLoaded())
+ pythonIface->startupRemoved(this, t);
+}
+
+void karamba::processExited (KProcess* proc)
+{
+ //qDebug("karamba::processExited");
+ if (pythonIface && pythonIface->isExtensionLoaded())
+ pythonIface->commandFinished(this, (int)proc->pid());
+}
+
+void karamba::receivedStdout (KProcess *proc, char *buffer, int)
+{
+ //qDebug("karamba::receivedStdout");
+ //Everything below is to call the python callback function
+ if (pythonIface && pythonIface->isExtensionLoaded())
+ pythonIface->commandOutput(this, (int)proc->pid(), buffer);
+}
+
+//For KDE session management
+void karamba::saveProperties(KConfig* config)
+{
+ //qDebug("karamba::saveProperties");
+ config->setGroup("session");
+ config->writeEntry("theme", m_theme.file());
+ writeConfigData();
+}
+
+//For KDE session management
+void karamba::readProperties(KConfig* config)
+{
+ //qDebug("karamba::readProperties");
+ config->setGroup("session");
+ QString atheme = config->readEntry("theme");
+}
+
+//Register types of events that can be dragged on our widget
+void karamba::dragEnterEvent(QDragEnterEvent* event)
+{
+ //qDebug("karamba::dragEnterEvent");
+ event->accept(QTextDrag::canDecode(event));
+}
+
+//Handle the drop part of a drag and drop event.
+void karamba::dropEvent(QDropEvent* event)
+{
+ //qDebug("karamba::dropEvent");
+ QString text;
+
+ if ( QTextDrag::decode(event, text) )
+ {
+ //Everything below is to call the python callback function
+ if (pythonIface && pythonIface->isExtensionLoaded())
+ {
+ const QPoint &p = event->pos();
+ pythonIface->itemDropped(this, text, p.x(), p.y());
+ }
+ }
+}
+
+void karamba::toDesktop(int id, int menuid)
+{
+ //qDebug("karamba::toDesktop");
+ int i;
+
+ desktop = id;
+ for (i=0; ; i++)
+ {
+ int mid = toDesktopMenu->idAt(i);
+ if (mid == -1)
+ break;
+
+ toDesktopMenu->setItemChecked(mid, false);
+ }
+ toDesktopMenu->setItemChecked(menuid, true);
+
+ if (desktop)
+ info->setDesktop( desktop);
+ else
+ info->setDesktop( NETWinInfo::OnAllDesktops );
+}
+
+void karamba::systrayUpdated()
+{
+ //qDebug("karamba::systrayUpdated");
+ if (pythonIface && pythonIface->isExtensionLoaded())
+ pythonIface->systrayUpdated(this);
+}
+
+void karamba::toggleWidgetUpdate( bool b)
+{
+ //qDebug("karamba::toggleWidgetUpdate");
+ if (pythonIface && pythonIface->isExtensionLoaded())
+ widgetUpdate = b;
+}
+
+SignalBridge::SignalBridge(QObject* parent, QString name, KActionCollection* ac)
+ : QObject(parent, name.ascii()), collection(ac)
+{
+ setName(name.ascii());
+}
+
+void SignalBridge::receive()
+{
+ emit enabled(name(), ((KToggleAction*)collection -> action(name())) ->
+isChecked());
+}
+
+DesktopChangeSlot::DesktopChangeSlot(QObject *parent, int id)
+ : QObject(parent, "")
+{
+ desktopid = id;
+}
+
+void DesktopChangeSlot::receive()
+{
+ karamba *k = (karamba *)parent();
+
+ // XXX - check type cast
+
+ k->toDesktop(desktopid, menuid);
+}
+
+void DesktopChangeSlot::setMenuId(int id)
+{
+ menuid = id;
+}
+
+int DesktopChangeSlot::menuId()
+{
+ return menuid;
+}
+
+void karamba::showMenuExtension()
+{
+ kglobal = new KPopupMenu(this);
+
+ trayMenuToggleId = kglobal->insertItem(SmallIconSet("superkaramba"),
+ i18n("Show System Tray Icon"), this,
+ SLOT(slotToggleSystemTray()),
+ CTRL+Key_S);
+
+ trayMenuThemeId = kglobal->insertItem(SmallIconSet("knewstuff"),
+ i18n("&Manage Themes..."), this,
+ SLOT(slotShowTheme()), CTRL+Key_M);
+
+ trayMenuQuitId = kglobal->insertItem(SmallIconSet("exit"),
+ i18n("&Quit SuperKaramba"), this,
+ SLOT(slotQuit()), CTRL+Key_Q);
+
+ kglobal->polish();
+
+ trayMenuSeperatorId = kpop->insertSeparator();
+ kpop->insertItem("SuperKaramba", kglobal);
+}
+
+void karamba::hideMenuExtension()
+{
+ if(kglobal)
+ {
+ kpop->removeItem(trayMenuSeperatorId);
+ kglobal->removeItem(trayMenuToggleId);
+ kglobal->removeItem(trayMenuThemeId);
+ kglobal->removeItem(trayMenuQuitId);
+
+ delete kglobal;
+ kglobal = 0;
+ }
+}
+
+void karamba::slotToggleSystemTray()
+{
+ karambaApp->globalHideSysTray(false);
+}
+
+void karamba::slotQuit()
+{
+ karambaApp->globalQuitSuperKaramba();
+}
+
+void karamba::slotShowTheme()
+{
+ karambaApp->globalShowThemeDialog();
+}
+
+void karamba::setAlwaysOnTop(bool stay)
+{
+ if(stay)
+ {
+ onTop = true;
+ KWin::setState( winId(), NET::KeepAbove );
+ }
+ else
+ {
+ onTop = false;
+ KWin::setState( winId(), NET::KeepBelow );
+ }
+}
+
+#include "karamba.moc"
diff --git a/superkaramba/src/karamba.h b/superkaramba/src/karamba.h
new file mode 100644
index 0000000..a81b11b
--- /dev/null
+++ b/superkaramba/src/karamba.h
@@ -0,0 +1,363 @@
+/*
+ * Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+ * Copyright (C) 2004,2005 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
+ * Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+ * Copyright (c) 2005 Ryan Nickell <p0z3r@earthlink.net>
+ *
+ * This file is part of SuperKaramba.
+ *
+ * SuperKaramba 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.
+ *
+ * SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#ifndef _KARAMBA_H_
+#define _KARAMBA_H_
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <qwidget.h>
+#include <kapplication.h>
+
+#include <kwinmodule.h>
+#include <kwin.h>
+
+#include <qfile.h>
+#include <kfile.h>
+#include <qfileinfo.h>
+#include <kaction.h>
+#include <qtimer.h>
+#include <qpixmap.h>
+#include <qpainter.h>
+
+//#include <krootpixmap.h>
+
+#include <qregexp.h>
+#include <qlabel.h>
+#include <qobjectlist.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <ksharedpixmap.h>
+#include <qvaluestack.h>
+#include <dcopclient.h>
+#include <kpopupmenu.h>
+#include <qcursor.h>
+#include <netwm.h>
+#include <kiconloader.h>
+#include <kfiledialog.h>
+#include <qmap.h>
+#include <kurl.h>
+#include <krun.h>
+#include <qdatetime.h>
+#include <qbitmap.h>
+#include <kconfig.h>
+#include <kprocess.h>
+#include <qdragobject.h>
+
+#include "karambarootpixmap.h"
+
+#include "bar.h"
+#include "textlabel.h"
+#include "imagelabel.h"
+#include "graph.h"
+#include "input.h"
+
+#include "clickarea.h"
+
+#include "sensorparams.h"
+#include "memsensor.h"
+#include "datesensor.h"
+#include "uptimesensor.h"
+#include "memsensor.h"
+#include "cpusensor.h"
+#include "networksensor.h"
+#include "xmmssensor.h"
+#include "noatunsensor.h"
+#include "programsensor.h"
+#include "disksensor.h"
+#include "sensorsensor.h"
+#include "textfilesensor.h"
+
+#include "clickmap.h"
+#include "rsssensor.h"
+//#include "clickable.h"
+#include "taskmanager.h"
+#include "showdesktop.h"
+#include "systemtray.h"
+#include "themefile.h"
+
+/**
+ * @short Application Main Window
+ * @author Adam Geitgey <adam@rootnode.org>
+ * @author Hans Karlsson <karlsson.h@home.se>
+ * @author Luke Kenneth Casson Leighton <lkcl@lkcl.net>
+ * @version 0.26
+ */
+
+class KarambaPython;
+class LineParser;
+
+class karamba : public QWidget
+{
+ Q_OBJECT
+
+public:
+ karamba(QString fn, QString name, bool reloading = false,
+ int instance = -1, bool sub_theme = false);
+ QObjectList *menuList;
+
+ virtual ~karamba();
+ const ThemeFile& theme() const { return m_theme; };
+
+ QObjectList *meterList;
+ QObjectList *imageList;
+ QObjectList *clickList;
+ void setSensor(const LineParser& lineParser, Meter* meter);
+ QString getSensor(Meter* meter);
+ QString findSensorFromMap(Sensor* sensor);
+ void deleteMeterFromSensors(Meter* meter);
+ Sensor* findSensorFromList(Meter* meter);
+ KPopupMenu* keditpop;
+ KPopupMenu *kpop;
+ QBitmap* widgetMask;
+ KarambaRootPixmap *kroot;
+ TaskManager taskManager;
+ Systemtray* systray;
+ KProcess* currProcess;
+ bool useSmoothTransforms();
+
+ void changeInterval(int interval);
+ void setWidgetUpdate(bool wu) { widgetUpdate = wu; };
+ bool getWidgetUpdate() { return widgetUpdate; };
+ bool hasMeter(Meter* meter) { return meterList->containsRef(meter) > 0; };
+ char getTempUnit() { return tempUnit; };
+ void addMenuConfigOption(QString key, QString name);
+ bool setMenuConfigOption(QString key, bool value);
+ bool readMenuConfigOption(QString key);
+ void writeConfigData();
+ TextField* getDefaultTextProps() { return defaultTextField; };
+ int instance() const { return m_instance; };
+ void setInstance(int instance) { m_instance = instance; };
+ void closeTheme(bool reloading = false);
+ void keyPressed(const QString& s, const Meter* meter);
+
+ int numberOfConfMenuItems;
+ KConfig* config;
+ QString prettyName;
+ bool m_sub_theme;
+ bool isSubTheme() { return m_sub_theme; }
+
+ void toggleWidgetUpdate( bool );
+
+ KWinModule* kWinModule;
+
+ QString incomingData;
+ QString getIncomingData() { return incomingData; }
+ void _setIncomingData(QString data) { incomingData = data; }
+ void setIncomingData(QString theme, QString data);
+
+ void themeNotify(QString theme, QString txt);
+ void callTheme(QString theme, QString txt);
+
+ double getUpdateTime() { return update_time; }
+ void setUpdateTime(double time) { update_time = time; }
+
+ void makeActive();
+ void makePassive();
+
+ void showMenuExtension();
+ void hideMenuExtension();
+
+protected:
+ void mousePressEvent( QMouseEvent *);
+ void wheelEvent( QWheelEvent *);
+ void mouseReleaseEvent( QMouseEvent *);
+ void mouseDoubleClickEvent( QMouseEvent *);
+ void mouseMoveEvent( QMouseEvent *);
+ void keyPressEvent ( QKeyEvent * e );
+ void closeEvent ( QCloseEvent *);
+ void paintEvent ( QPaintEvent *);
+ void saveProperties(KConfig *);
+ void readProperties(KConfig *);
+ void dragEnterEvent(QDragEnterEvent* event);
+ void dropEvent(QDropEvent* event);
+
+private:
+ bool widgetUpdate;
+ bool repaintInProgress;
+ //bool reloading;
+ bool want_right_button;
+ bool want_meter_wheel_event;
+
+ NETWinInfo* info;
+ bool onTop;
+ bool managed;
+ bool fixedPosition;
+ bool haveUpdated;
+ char tempUnit;
+ double update_time;
+ int m_instance;
+
+ bool parseConfig();
+
+ void passClick( QMouseEvent* );
+ void passWheelClick( QWheelEvent* );
+ void meterClicked(QMouseEvent*, Meter*);
+
+ QMap<QString, Sensor*> sensorMap;
+ QObjectList *sensorList;
+ QObjectList *timeList;
+
+ QTime lowerTimer;
+ // use only the first occurance of KARAMBA in a config file
+ bool foundKaramba;
+
+ KPopupMenu* themeConfMenu;
+ KPopupMenu* toDesktopMenu;
+ KPopupMenu* kglobal;
+
+ DCOPClient *client;
+ QCString appId;
+
+ QPixmap pm;
+ QPixmap background;
+ QPainter p;
+
+ QPoint clickPos;
+ KActionCollection* accColl;
+ KActionCollection* menuAccColl;
+ KToggleAction *toggleLocked;
+ // use highquality scale and rotate algorithms
+ KToggleAction *toggleFastTransforms;
+
+ // Python module references
+ KarambaPython* pythonIface;
+ TextField *defaultTextField;
+
+ int desktop;
+ ThemeFile m_theme;
+
+ int trayMenuSeperatorId;
+ int trayMenuQuitId;
+ int trayMenuToggleId;
+ int trayMenuThemeId;
+ void start();
+
+public slots:
+ void step();
+ void externalStep();
+ void widgetClosed();
+ void updateSensors();
+ void currentDesktopChanged(int);
+ void currentWallpaperChanged(int);
+ void slotToggleConfigOption(QString key, bool);
+ void updateBackground(KSharedPixmap*);
+ void passMenuOptionChanged(QString key, bool);
+ void passMenuItemClicked(int);
+ void processExited (KProcess *proc);
+ void receivedStdout (KProcess *proc, char *buffer, int buflen);
+ void toDesktop(int desktopid, int menuid);
+ const char *getPrettyName() { return prettyName.ascii(); }
+
+ // Systray
+ void systrayUpdated();
+
+ // Task Manager
+ void startupAdded(Startup*);
+ void startupRemoved(Startup*);
+
+ void taskAdded(Task*);
+ void taskRemoved(Task*);
+ void activeTaskChanged(Task*);
+ void reloadConfig();
+
+ void setAlwaysOnTop(bool stay);
+
+ /**
+ * If true, then when a right button is pressed on the theme,
+ * the theme's python widgetMouseMoved function is called.
+ */
+ void setWantRightButton(bool yesno) { want_right_button = yesno; }
+
+ void setWantMeterWheelEvent(bool yesno) { want_meter_wheel_event = yesno; }
+
+ /**
+ * can be used to fire up the karamba management popup menu
+ */
+ void management_popup( void );
+
+private:
+ bool m_reloading;
+ bool themeStarted;
+ QTimer *m_sysTimer;
+ int m_interval;
+
+private slots:
+ void initPythonInterface();
+ void killWidget();
+ void editConfig();
+ void editScript();
+ void slotToggleLocked();
+ void slotToggleFastTransforms();
+ void popupNotify(int);
+ void slotFileChanged( const QString & );
+
+ void slotToggleSystemTray();
+ void slotQuit();
+ void slotShowTheme();
+};
+
+/*
+ * Slot to receive the event of moving the karamba object
+ * to a new desktop. Generated by karamba::toDesktopMenu items
+ */
+class DesktopChangeSlot : public QObject
+{
+ Q_OBJECT
+
+ public:
+ DesktopChangeSlot(QObject *parent, int desktop_id);
+ /* Parent should be the karamba object
+ * desktop id of 0 indicates all desktops */
+ void setMenuId(int id);
+ int menuId();
+
+ public slots:
+ void receive();
+
+ protected:
+ int desktopid;
+ int menuid;
+};
+
+/** SignalBridge is an ungulate that lives in the forests of wild Wisconsin. */
+class SignalBridge : public QObject
+{
+ Q_OBJECT
+
+ public:
+ SignalBridge(QObject* parent, QString, KActionCollection*);
+
+ signals:
+ void enabled(QString, bool);
+
+ public slots:
+ void receive();
+
+ private:
+ KActionCollection* collection;
+};
+
+#endif // _KARAMBA_H_
diff --git a/superkaramba/src/karamba_python.cpp b/superkaramba/src/karamba_python.cpp
new file mode 100644
index 0000000..ab0034a
--- /dev/null
+++ b/superkaramba/src/karamba_python.cpp
@@ -0,0 +1,635 @@
+/****************************************************************************
+* karamba_python.cpp - Functions for calling python scripts
+*
+* Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+* Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+* Copyright (c) 2004 Petri Damst� <damu@iki.fi>
+* Copyright (c) 2004 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
+*
+* This file is part of SuperKaramba.
+*
+* SuperKaramba 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.
+*
+* SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+#ifdef _XOPEN_SOURCE
+#undef _XOPEN_SOURCE
+#endif
+
+#include <Python.h>
+#include "karambaapp.h"
+#include "themefile.h"
+
+#include "karamba_python.h"
+#include "meter_python.h"
+#include "bar_python.h"
+#include "graph_python.h"
+#include "textlabel_python.h"
+#include "richtextlabel_python.h"
+#include "imagelabel_python.h"
+#include "widget_python.h"
+#include "menu_python.h"
+#include "config_python.h"
+#include "task_python.h"
+#include "systray_python.h"
+#include "svcgrp_python.h"
+#include "misc_python.h"
+#include "input_python.h"
+
+/*******************************************
+ * Python methods are defined here.
+ * Each method accessible from python should have:
+ * - A wrapper function that returns a PyObject or appropriate python type
+ * - A C++ implementation of the python method, named the same as the python call
+ * - An entry in the python methods array so the call is accessible from python
+ *
+ * Example:
+ * py_move_systay - wrapper function
+ * moveSystray - actual implementation of method
+ * {"moveSystray", py_move_systray, METH_VARARGS, "Move the Systray"} - array entry
+ */
+
+static PyMethodDef karamba_methods[] = {
+ // Bar - bar_python.cpp
+ {(char*)"createBar", py_createBar, METH_VARARGS, (char*)"Create new Bar."},
+ {(char*)"deleteBar", py_deleteBar, METH_VARARGS, (char*)"Delete Bar."},
+ {(char*)"getThemeBar", py_getThemeBar, METH_VARARGS, (char*)"Get Bar from .theme using it's name."},
+ {(char*)"getBarSize", py_getBarSize, METH_VARARGS, (char*)"Get Bar size."},
+ {(char*)"resizeBar", py_resizeBar, METH_VARARGS, (char*)"Resize Bar."},
+ {(char*)"getBarPos", py_getBarPos, METH_VARARGS, (char*)"Get Bar position."},
+ {(char*)"moveBar", py_moveBar, METH_VARARGS, (char*)"Move Bar."},
+ {(char*)"hideBar", py_hideBar, METH_VARARGS, (char*)"Hide Bar."},
+ {(char*)"showBar", py_showBar, METH_VARARGS, (char*)"Show Bar."},
+ {(char*)"getBarSensor", py_getBarSensor, METH_VARARGS, (char*)"Get Bar sensor."},
+ {(char*)"setBarSensor", py_setBarSensor, METH_VARARGS, (char*)"Set Bar sensor."},
+ {(char*)"setBarImage", py_setBarImage, METH_VARARGS, (char*)"Set bar image"},
+ {(char*)"getBarImage", py_getBarImage, METH_VARARGS, (char*)"Get bar image"},
+ {(char*)"setBarVertical", py_setBarVertical, METH_VARARGS, (char*)"Set bar orientation"},
+ {(char*)"getBarVertical", py_getBarVertical, METH_VARARGS, (char*)"Get bar orientation"},
+ {(char*)"setBarValue", py_setBarValue, METH_VARARGS, (char*)"Set bar value"},
+ {(char*)"getBarValue", py_getBarValue, METH_VARARGS, (char*)"Get bar value"},
+ {(char*)"setBarMinMax", py_setBarMinMax, METH_VARARGS, (char*)"Set bar min & max"},
+ {(char*)"getBarMinMax", py_getBarMinMax, METH_VARARGS, (char*)"Get bar min & max"},
+ {(char*)"getIncomingData", py_get_incoming_data, METH_VARARGS, (char*)"Get incoming data passed from another theme"},
+ {(char*)"setIncomingData", py_set_incoming_data, METH_VARARGS, (char*)"Set incoming data passed in another theme"},
+
+ // Graph - graph_python.cpp
+ {(char*)"createGraph", py_createGraph, METH_VARARGS, (char*)"Create new Graph."},
+ {(char*)"deleteGraph", py_deleteGraph, METH_VARARGS, (char*)"Delete Graph."},
+ {(char*)"getThemeGraph", py_getThemeGraph, METH_VARARGS, (char*)"Get Graph from .theme using it's name."},
+ {(char*)"getGraphSize", py_getGraphSize, METH_VARARGS, (char*)"Get Graph size."},
+ {(char*)"resizeGraph", py_resizeGraph, METH_VARARGS, (char*)"Resize Graph."},
+ {(char*)"getGraphPos", py_getGraphPos, METH_VARARGS, (char*)"Get Graph position."},
+ {(char*)"moveGraph", py_moveGraph, METH_VARARGS, (char*)"Move Graph."},
+ {(char*)"hideGraph", py_hideGraph, METH_VARARGS, (char*)"Hide Graph."},
+ {(char*)"showGraph", py_showGraph, METH_VARARGS, (char*)"Show Graph."},
+ {(char*)"getGraphSensor", py_getGraphSensor, METH_VARARGS, (char*)"Get Graph sensor."},
+ {(char*)"setGraphSensor", py_setGraphSensor, METH_VARARGS, (char*)"Set Graph sensor."},
+ {(char*)"setGraphValue", py_setGraphValue, METH_VARARGS, (char*)"Set graph value"},
+ {(char*)"getGraphValue", py_getGraphValue, METH_VARARGS, (char*)"Get graph value"},
+ {(char*)"setGraphMinMax", py_setGraphMinMax, METH_VARARGS, (char*)"Set graph min & max"},
+ {(char*)"getGraphMinMax", py_getGraphMinMax, METH_VARARGS, (char*)"Get graph min & max"},
+ {(char*)"setGraphColor", py_setGraphColor, METH_VARARGS, (char*)"Change a Graph Sensor's Color"},
+ {(char*)"getGraphColor", py_getGraphColor, METH_VARARGS, (char*)"Get a Graph Sensor's Color"},
+
+ // TextLabel - textlabel_python.cpp
+ {(char*)"createText", py_createText, METH_VARARGS, (char*)"Create new Text."},
+ {(char*)"deleteText", py_deleteText, METH_VARARGS, (char*)"Delete Text."},
+ {(char*)"getThemeText", py_getThemeText, METH_VARARGS, (char*)"Get Text from .theme using it's name."},
+ {(char*)"getTextSize", py_getTextSize, METH_VARARGS, (char*)"Get Text size."},
+ {(char*)"resizeText", py_resizeText, METH_VARARGS, (char*)"Resize Text."},
+ {(char*)"getTextPos", py_getTextPos, METH_VARARGS, (char*)"Get Text position."},
+ {(char*)"moveText", py_moveText, METH_VARARGS, (char*)"Move Text."},
+ {(char*)"hideText", py_hideText, METH_VARARGS, (char*)"Hide Text."},
+ {(char*)"showText", py_showText, METH_VARARGS, (char*)"Show Text."},
+ {(char*)"getTextSensor", py_getTextSensor, METH_VARARGS, (char*)"Get Text sensor."},
+ {(char*)"setTextSensor", py_setTextSensor, METH_VARARGS, (char*)"Set Text sensor."},
+ {(char*)"changeText", py_setTextValue, METH_VARARGS, (char*)"Change a Text Sensor's Text"},
+ {(char*)"getTextValue", py_getTextValue, METH_VARARGS, (char*)"Get Text value"},
+ {(char*)"changeTextShadow", py_setTextShadow, METH_VARARGS, (char*)"Change a Text Shadow size"},
+ {(char*)"getTextShadow", py_getTextShadow, METH_VARARGS, (char*)"Get a Text Shadow size"},
+ {(char*)"changeTextFont", py_setTextFont, METH_VARARGS, (char*)"Change a Text Sensor's Font"},
+ {(char*)"getTextFont", py_getTextFont, METH_VARARGS, (char*)"Get a Text Sensor's Font"},
+ {(char*)"changeTextColor", py_setTextColor, METH_VARARGS, (char*)"Change a Text Sensor's Color"},
+ {(char*)"getTextColor", py_getTextColor, METH_VARARGS, (char*)"Get a Text Sensor's Color"},
+ {(char*)"changeTextSize", py_setTextFontSize, METH_VARARGS, (char*)"Change a Text Sensor's Font Size"},
+ {(char*)"getTextFontSize", py_getTextFontSize, METH_VARARGS, (char*)"Get a Text Sensor's Font Size"},
+ {(char*)"getTextAlign", py_getTextAlign, METH_VARARGS, (char*)"Get Text alignment."},
+ {(char*)"setTextAlign", py_setTextAlign, METH_VARARGS, (char*)"Set Text alignment."},
+ {(char*)"setTextScroll", py_setTextScroll, METH_VARARGS, (char*)"Set Text scroll."},
+
+ // RichTextLabel - richtextlabel_python.cpp
+ {(char*)"createRichText", py_createRichText, METH_VARARGS, (char*)"Create a Rich Text Sensor"},
+ {(char*)"deleteRichText", py_deleteRichText, METH_VARARGS, (char*)"Deletes a Rich Text Sensor"},
+ {(char*)"getThemeRichText", py_getThemeRichText, METH_VARARGS, (char*)"Get Rich Text from .theme using it's name."},
+ {(char*)"getRichTextSize", py_getRichTextSize, METH_VARARGS, (char*)"Get the (width, height) of a Rich Text Sensor"},
+ {(char*)"resizeRichText", py_resizeRichText, METH_VARARGS, (char*)"Resize Rich Text."},
+ {(char*)"setRichTextWidth", py_set_rich_text_width, METH_VARARGS, (char*)"Sets the width of a Rich Text Sensor"},
+ {(char*)"getRichTextPos", py_getRichTextPos, METH_VARARGS, (char*)"Get Rich Text position."},
+ {(char*)"moveRichText", py_moveRichText, METH_VARARGS, (char*)"Moves a Rich Text Sensor"},
+ {(char*)"hideRichText", py_hideRichText, METH_VARARGS, (char*)"hides a Rich Text Sensor"},
+ {(char*)"showRichText", py_showRichText, METH_VARARGS, (char*)"shows a Rich Text Sensor"},
+ {(char*)"getRichTextSensor", py_getRichTextSensor, METH_VARARGS, (char*)"Get Rich Text sensor."},
+ {(char*)"setRichTextSensor", py_setRichTextSensor, METH_VARARGS, (char*)"Set Rich Text sensor."},
+ {(char*)"changeRichText", py_setRichTextValue, METH_VARARGS, (char*)"Change the content of a Rich Text Sensor"},
+ {(char*)"getRichTextValue", py_getRichTextValue, METH_VARARGS, (char*)"Get Rich Text value"},
+ {(char*)"changeRichTextFont", py_setRichTextFont, METH_VARARGS, (char*)"Change a Rich Text Sensor's Font"},
+ {(char*)"getRichTextFont", py_getRichTextFont, METH_VARARGS, (char*)"Get a Rich Text Sensor's Font"},
+ {(char*)"changeRichTextSize", py_setRichTextFontSize, METH_VARARGS, (char*)"Change a Rich Text Sensor's Font Size"},
+ {(char*)"getRichTextFontSize", py_getRichTextFontSize, METH_VARARGS, (char*)"Get a Rich Text Sensor's Font Size"},
+
+ // ImageLabel - imagelabel_python.cpp
+ {(char*)"createImage", py_createImage, METH_VARARGS, (char*)"Create an Image"},
+ {(char*)"createTaskIcon", py_createTaskIcon, METH_VARARGS, (char*)"Create an Image of the Icon for a Task"},
+ {(char*)"createBackgroundImage", py_createBackgroundImage, METH_VARARGS, (char*)"Create an Image (only redraw it when background changes)"},
+ {(char*)"deleteImage", py_deleteImage, METH_VARARGS, (char*)"Delete an Image"},
+ {(char*)"getThemeImage", py_getThemeImage, METH_VARARGS, (char*)"Get image meter from .theme using it's name"},
+ {(char*)"getImageSize", py_getImageSize, METH_VARARGS, (char*)"Get Image size."},
+ {(char*)"getImageWidth", py_getImageWidth, METH_VARARGS, (char*)"Get the width of an Image"},
+ {(char*)"getImageHeight", py_getImageHeight, METH_VARARGS, (char*)"Get the height of an Image"},
+ {(char*)"getImagePos", py_getImagePos, METH_VARARGS, (char*)"Get Image position."},
+ {(char*)"moveImage", py_moveImage, METH_VARARGS, (char*)"Move an Image"},
+ {(char*)"hideImage", py_hideImage, METH_VARARGS, (char*)"Hide an Image"},
+ {(char*)"showImage", py_showImage, METH_VARARGS, (char*)"Show an Image"},
+ {(char*)"getImagePath", py_getImageValue, METH_VARARGS, (char*)"Get Image path."},
+ {(char*)"setImagePath", py_setImageValue, METH_VARARGS, (char*)"Set Image path."},
+ {(char*)"getImageSensor", py_getImageSensor, METH_VARARGS, (char*)"Get Image sensor."},
+ {(char*)"setImageSensor", py_setImageSensor, METH_VARARGS, (char*)"Set Image sensor."},
+ {(char*)"addImageTooltip", py_addImageTooltip, METH_VARARGS, (char*)"Create a Tooltip for an Image"},
+ {(char*)"resizeImage", py_resizeImage, METH_VARARGS, (char*)"Scale an Image"},
+ {(char*)"resizeImageSmooth", py_resizeImageSmooth, METH_VARARGS, (char*)"Scale an Image (slower, better looking)"},
+ {(char*)"rotateImage", py_rotateImage, METH_VARARGS, (char*)"Rotate an Image"},
+ {(char*)"removeImageTransformations", py_removeImageTransformations, METH_VARARGS, (char*)"Restore original size and orientation of an Image"},
+ {(char*)"removeImageEffects", py_removeImageEffects, METH_VARARGS, (char*)"Remove Effects of an Image"},
+ {(char*)"changeImageIntensity", py_changeImageIntensity, METH_VARARGS, (char*)"Change Intensity of an Image"},
+ {(char*)"changeImageChannelIntensity", py_changeImageChannelIntensity, METH_VARARGS, (char*)"Change Intensity of an Image Channel"},
+ {(char*)"changeImageToGray", py_changeImageToGray, METH_VARARGS, (char*)"Converts an Image to Grayscale"},
+
+ // Menu - menu_python.cpp
+ {(char*)"createMenu", py_create_menu, METH_VARARGS, (char*)"Create a popup menu"},
+ {(char*)"deleteMenu", py_delete_menu, METH_VARARGS, (char*)"Delete a popup menu"},
+ {(char*)"addMenuItem", py_add_menu_item, METH_VARARGS, (char*)"Add a popup menu entry"},
+ {(char*)"addMenuSeparator", py_add_menu_separator, METH_VARARGS, (char*)"Add a popup menu seperator item"},
+ {(char*)"removeMenuItem", py_remove_menu_item, METH_VARARGS, (char*)"Remove a popup menu entry"},
+ {(char*)"popupMenu", py_popup_menu, METH_VARARGS, (char*)"Popup a menu at a specified location"},
+
+ // Config - config_python.cpp
+ {(char*)"addMenuConfigOption", py_add_menu_config_option, METH_VARARGS, (char*)"Add a configuration entry to the menu"},
+ {(char*)"setMenuConfigOption", py_set_menu_config_option, METH_VARARGS, (char*)"Set a configuration entry in the menu"},
+ {(char*)"readMenuConfigOption", py_read_menu_config_option, METH_VARARGS, (char*)"Read a configuration entry in the menu"},
+ {(char*)"readConfigEntry", py_read_config_entry, METH_VARARGS, (char*)"Read a configuration entry"},
+ {(char*)"writeConfigEntry", py_write_config_entry, METH_VARARGS, (char*)"Writes a configuration entry"},
+
+ // Widget - widget_python.cpp
+ {(char*)"moveWidget", py_move_widget, METH_VARARGS, (char*)"Move Widget to x,y"},
+ {(char*)"resizeWidget", py_resize_widget, METH_VARARGS, (char*)"Resize Widget to width,height"},
+ {(char*)"createWidgetMask", py_create_widget_mask, METH_VARARGS, (char*)"Create a clipping mask for this widget"},
+ {(char*)"redrawWidget", py_redraw_widget, METH_VARARGS, (char*)"Update Widget to reflect your changes"},
+ {(char*)"redrawWidgetBackground", py_redraw_widget_background, METH_VARARGS, (char*)"Update Widget to reflect background image changes"},
+ {(char*)"getWidgetPosition", py_get_widget_position, METH_VARARGS, (char*)"Get Widget Position"},
+ {(char*)"toggleWidgetRedraw", py_toggle_widget_redraw, METH_VARARGS, (char*)"Toggle Widget redrawing"},
+
+ // Task - task_python.cpp
+ {(char*)"getStartupList", py_get_startup_list, METH_VARARGS, (char*)"Get the system startup list"},
+ {(char*)"getStartupInfo", py_get_startup_info, METH_VARARGS, (char*)"Get all the info for a startup"},
+ {(char*)"getTaskList", py_get_task_list, METH_VARARGS, (char*)"Get the system task list"},
+ {(char*)"getTaskNames", py_get_task_names, METH_VARARGS, (char*)"Get the system task list in name form"},
+ {(char*)"getTaskInfo", py_get_task_info, METH_VARARGS, (char*)"Get all the info for a task"},
+ {(char*)"performTaskAction", py_perform_task_action, METH_VARARGS, (char*)"Do something with a task, such as minimize it"},
+
+ // System Tray - systray_python.cpp
+ {(char*)"createSystray", py_create_systray, METH_VARARGS, (char*)"Create a Systray"},
+ {(char*)"hideSystray", py_hide_systray, METH_VARARGS, (char*)"Hide the Systray"},
+ {(char*)"showSystray", py_show_systray, METH_VARARGS, (char*)"Show the Systray"},
+ {(char*)"moveSystray", py_move_systray, METH_VARARGS, (char*)"Move the Systray"},
+ {(char*)"getCurrentWindowCount", py_get_current_window_count, METH_VARARGS, (char*)"Get current Window count"},
+ {(char*)"updateSystrayLayout", py_update_systray_layout, METH_VARARGS, (char*)"Update Systray layout"},
+
+ // Misc - misc_python.cpp
+ {(char*)"getThemePath", py_get_theme_path, METH_VARARGS, (char*)"Get the file path of the theme"},
+ {(char*)"readThemeFile", py_read_theme_file, METH_VARARGS,
+ (char*)"Read file from theme."},
+ {(char*)"language", py_language, METH_VARARGS,
+ (char*)"Return default language of a translation file."},
+ {(char*)"userLanguage", py_userLanguage, METH_VARARGS,
+ (char*)"Return user language."},
+ {(char*)"userLanguages", py_userLanguages, METH_VARARGS,
+ (char*)"Return preferred user languages."},
+ {(char*)"openTheme", py_open_theme, METH_VARARGS,
+ (char*)"Open a new theme"},
+ {(char*)"reloadTheme", py_reload_theme, METH_VARARGS,
+ (char*)"Reload current theme"},
+ {(char*)"acceptDrops", py_accept_drops, METH_VARARGS,
+ (char*)"Allows widget to receive Drop (I.E. Drag and Drop) events"},
+ {(char*)"toggleShowDesktop", py_toggle_show_desktop, METH_VARARGS,
+ (char*)"Show/Hide the desktop"},
+ {(char*)"execute", py_execute_command, METH_VARARGS, (char*)"Execute a command"},
+ {(char*)"executeInteractive", py_execute_command_interactive, METH_VARARGS, (char*)"Execute a command and get it's output (stdout)"},
+ {(char*)"attachClickArea", (PyCFunction)py_attach_clickArea, METH_VARARGS|METH_KEYWORDS, (char*)"Add a clickArea to the given text or image"},
+ {(char*)"createClickArea", py_create_click_area, METH_VARARGS, (char*)"Create a Click Area Sensor"},
+ {(char*)"getNumberOfDesktops", py_get_number_of_desktops, METH_VARARGS, (char*)"Get current number of virtual desktops"},
+ {(char*)"getIp", py_get_ip, METH_VARARGS, (char*)"Get current host's IP address"},
+ {(char*)"translateAll", py_translate_all, METH_VARARGS, (char*)"Translate all widgets in a theme"},
+ {(char*)"show", py_show, METH_VARARGS, (char*)"Show theme"},
+ {(char*)"hide", py_hide, METH_VARARGS, (char*)"Hide theme"},
+
+ // Input Box - input_python.cpp
+ {(char*)"createInputBox", py_createInputBox, METH_VARARGS,
+ (char*)"Create new Input Box."},
+ {(char*)"deleteInputBox", py_deleteInputBox, METH_VARARGS,
+ (char*)"Delete Input Box."},
+ {(char*)"getThemeInputBox", py_getThemeInputBox, METH_VARARGS,
+ (char*)"Get Input Box from .theme using it's name."},
+ {(char*)"getInputBoxValue", py_getInputBoxValue, METH_VARARGS,
+ (char*)"Get Input Box value"},
+ {(char*)"changeInputBox", py_setInputBoxValue, METH_VARARGS,
+ (char*)"Change a Input Box Text"},
+ {(char*)"hideInputBox", py_hideInputBox, METH_VARARGS,
+ (char*)"Hide Input Box."},
+ {(char*)"showInputBox", py_showInputBox, METH_VARARGS,
+ (char*)"Show Input Box."},
+ {(char*)"getInputBoxPos", py_getInputBoxPos, METH_VARARGS,
+ (char*)"Get InputBox position."},
+ {(char*)"moveInputBox", py_moveInputBox, METH_VARARGS,
+ (char*)"Moves a Input Box"},
+ {(char*)"getInputBoxSize", py_getInputBoxSize, METH_VARARGS,
+ (char*)"Get the (width, height) of a Input Box"},
+ {(char*)"resizeInputBox", py_resizeInputBox, METH_VARARGS,
+ (char*)"Resize Input Box."},
+ {(char*)"changeInputBoxFont", py_setInputBoxFont, METH_VARARGS,
+ (char*)"Change a Input Box Font"},
+ {(char*)"getInputBoxFont", py_getInputBoxFont, METH_VARARGS,
+ (char*)"Get a Input Box Font"},
+ {(char*)"changeInputBoxFontColor", py_setInputBoxFontColor, METH_VARARGS,
+ (char*)"Change a Input Box Font Color"},
+ {(char*)"getInputBoxFontColor", py_getInputBoxFontColor, METH_VARARGS,
+ (char*)"Get a Input Box Font Color"},
+ {(char*)"changeInputBoxSelectionColor", py_setInputBoxSelectionColor,
+ METH_VARARGS, (char*)"Change a Input Box Selection Color"},
+ {(char*)"getInputBoxSelectionColor", py_getInputBoxSelectionColor,
+ METH_VARARGS, (char*)"Get a Input Box Selection Color"},
+ {(char*)"changeInputBoxBackgroundColor", py_setInputBoxBGColor,
+ METH_VARARGS, (char*)"Change a Input Box Background Color"},
+ {(char*)"getInputBoxBackgroundColor", py_getInputBoxBGColor, METH_VARARGS,
+ (char*)"Get a Input Box Background Color"},
+ {(char*)"changeInputBoxFrameColor", py_setInputBoxFrameColor, METH_VARARGS,
+ (char*)"Change a Input Box Frame Color"},
+ {(char*)"getInputBoxFrameColor", py_getInputBoxFrameColor, METH_VARARGS,
+ (char*)"Get a Input Box Frame Color"},
+ {(char*)"changeInputBoxSelectedTextColor", py_setInputBoxSelectedTextColor,
+ METH_VARARGS, (char*)"Change a Input Box Selected Text Color"},
+ {(char*)"getInputBoxSelectedTextColor", py_getInputBoxSelectedTextColor,
+ METH_VARARGS, (char*)"Get a Input Box Selected Text Color"},
+ {(char*)"changeInputBoxFontSize", py_setInputBoxFontSize, METH_VARARGS,
+ (char*)"Change a Input Box Font Size"},
+ {(char*)"getInputBoxFontSize", py_getInputBoxFontSize, METH_VARARGS,
+ (char*)"Get a Input Box Font Size"},
+ {(char*)"setInputFocus", py_setInputFocus, METH_VARARGS,
+ (char*)"Set the Input Focus to the Input Box"},
+ {(char*)"clearInputFocus", py_clearInputFocus, METH_VARARGS,
+ (char*)"Clear the Input Focus of the Input Box"},
+ {(char*)"getInputFocus", py_getInputFocus, METH_VARARGS,
+ (char*)"Get the Input Box currently focused"},
+
+ {(char*)"setWidgetOnTop", py_set_widget_on_top, METH_VARARGS,
+ (char*)"changes 'on top' status"},
+ {(char*)"getSystraySize", py_get_systray_size, METH_VARARGS,
+ (char*)"Get the size of the Systray"},
+ {(char*)"getPrettyThemeName", py_get_pretty_name, METH_VARARGS,
+ (char*)"Get the pretty name of the theme"},
+ {(char*)"openNamedTheme", py_open_named_theme, METH_VARARGS,
+ (char*)"Open a new theme giving it a new name"},
+ {(char*)"callTheme", py_call_theme, METH_VARARGS,
+ (char*)"Pass a string to another theme"},
+ {(char*)"changeInterval", py_change_interval, METH_VARARGS,
+ (char*)"Change the refresh interval"},
+ {(char*)"run", py_run_command, METH_VARARGS,
+ (char*)"Execute a command with KRun"},
+ {(char*)"createServiceClickArea", py_create_service_click_area, METH_VARARGS,
+ (char*)"Create a Service-named Click Area Sensor"},
+ {(char*)"removeClickArea", py_remove_click_area, METH_VARARGS,
+ (char*)"Remove a Click Area Sensor"},
+ {(char*)"setUpdateTime", py_set_update_time, METH_VARARGS,
+ (char*)"Set last updated time"},
+ {(char*)"getUpdateTime", py_get_update_time, METH_VARARGS,
+ (char*)"Get last updated time"},
+ {(char*)"setWantRightButton", py_want_right_button, METH_VARARGS,
+ (char*)"Set to 1 to deactivate management popups"},
+ {(char*)"setWantMeterWheelEvent", py_want_wheel_event, METH_VARARGS,
+ (char*)"Enables wheel events over meters."},
+ {(char*)"managementPopup", py_management_popup, METH_VARARGS,
+ (char*)"Activates the Management Popup menu"},
+
+ // service groups
+ {(char*)"getServiceGroups", py_get_service_groups, METH_VARARGS,
+ (char*)"Get KDE Service Groups"},
+
+ {NULL, NULL, 0 ,NULL}
+};
+
+PyThreadState* KarambaPython::mainThreadState = 0;
+
+KarambaPython::KarambaPython(const ThemeFile& theme, bool reloading):
+ pythonThemeExtensionLoaded(false), pName(0), pModule(0), pDict(0)
+{
+ PyThreadState* myThreadState;
+ char pypath[1024];
+
+ getLock(&myThreadState);
+
+ // load the .py file for this .theme
+ PyRun_SimpleString((char*)"import sys");
+ //Add theme path to python path so that we can find the python file
+ snprintf(pypath, 1023, "sys.path.insert(0, '%s')", theme.path().ascii());
+ PyRun_SimpleString(pypath);
+ PyRun_SimpleString((char*)"sys.path.insert(0, '')");
+
+ PyImport_AddModule((char*)"karamba");
+ Py_InitModule((char*)"karamba", karamba_methods);
+
+ pName = PyString_FromString(theme.pythonModule().ascii());
+ pModule = PyImport_Import(pName);
+
+ fprintf(stderr, "%s\n", pypath);
+
+ //Make sure the module is up to date.
+ if (reloading)
+ PyImport_ReloadModule(pModule);
+
+ if (pModule != NULL)
+ {
+ pDict = PyModule_GetDict(pModule);
+ if (pDict != NULL)
+ {
+ pythonThemeExtensionLoaded = true;
+ }
+ }
+ else
+ {
+ PyErr_Print();
+ fprintf(stderr,
+ "------------------------------------------------------\n");
+ fprintf(stderr, "What does ImportError mean?\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr,
+ "It means that I couldn't load a python add-on %s.py\n",
+ theme.pythonModule().ascii());
+ fprintf(stderr, "If this is a regular theme and doesn't use python\n");
+ fprintf(stderr, "extensions, then nothing is wrong.\n");
+ fprintf(stderr,
+ "------------------------------------------------------\n");
+ }
+ releaseLock(myThreadState);
+}
+
+KarambaPython::~KarambaPython()
+{
+ //Clean up Python references
+ if (pythonThemeExtensionLoaded) {
+ PyThreadState* myThreadState;
+ getLock(&myThreadState);
+
+ //Displose of current python module so we can reload in constructor.
+ Py_DECREF(pModule);
+ Py_DECREF(pName);
+
+ releaseLock(myThreadState);
+ }
+}
+
+void KarambaPython::initPython()
+{
+ // initialize Python
+ Py_Initialize();
+
+ // initialize thread support
+ PyEval_InitThreads();
+
+ // save a pointer to the main PyThreadState object
+ mainThreadState = PyThreadState_Get();
+
+ // release the lock
+ PyEval_ReleaseLock();
+}
+
+void KarambaPython::shutdownPython()
+{
+ // shut down the interpreter
+ PyInterpreterState * mainInterpreterState = mainThreadState->interp;
+ // create a thread state object for this thread
+ PyThreadState * myThreadState = PyThreadState_New(mainInterpreterState);
+ PyThreadState_Swap(myThreadState);
+ PyEval_AcquireLock();
+ Py_Finalize();
+}
+
+void KarambaPython::getLock(PyThreadState** myThreadState)
+{
+ // get the global lock
+ PyEval_AcquireLock();
+
+ // create a thread state object for this thread
+ *myThreadState = PyThreadState_New(mainThreadState->interp);
+ PyThreadState_Swap(*myThreadState);
+}
+
+void KarambaPython::releaseLock(PyThreadState* myThreadState)
+{
+ // swap my thread state out of the interpreter
+ PyThreadState_Swap(NULL);
+ // clear out any cruft from thread state object
+ PyThreadState_Clear(myThreadState);
+ // delete my thread state object
+ PyThreadState_Delete(myThreadState);
+ // release the lock
+ PyEval_ReleaseLock();
+}
+
+PyObject* KarambaPython::getFunc(const char* function)
+{
+ PyObject* pFunc = PyDict_GetItemString(pDict, (char*)function);
+ if (pFunc && PyCallable_Check(pFunc))
+ return pFunc;
+ return NULL;
+}
+
+bool KarambaPython::callObject(const char* func, PyObject* pArgs, bool lock)
+{
+ bool result = false;
+ PyThreadState* myThreadState;
+
+ //qDebug("Calling %s", func);
+
+ if (lock)
+ getLock(&myThreadState);
+ PyObject* pFunc = getFunc(func);
+
+ if (pFunc != NULL)
+ {
+ PyObject* pValue = PyObject_CallObject(pFunc, pArgs);
+
+ if (pValue != NULL)
+ {
+ Py_DECREF(pValue);
+ result = true;
+ }
+ else
+ {
+ qWarning("Call to %s failed", func);
+ PyErr_Print();
+ }
+ }
+ Py_DECREF(pArgs);
+ if (lock)
+ releaseLock(myThreadState);
+ return result;
+}
+
+bool KarambaPython::initWidget(karamba* k)
+{
+ PyObject* pArgs = Py_BuildValue((char*)"(l)", k);
+ return callObject("initWidget", pArgs);
+}
+
+bool KarambaPython::widgetUpdated(karamba* k)
+{
+ PyObject* pArgs = Py_BuildValue((char*)"(l)", k);
+ return callObject("widgetUpdated", pArgs);
+}
+
+bool KarambaPython::widgetClosed(karamba* k)
+{
+ PyObject* pArgs = Py_BuildValue((char*)"(l)", k);
+ return callObject("widgetClosed", pArgs);
+}
+
+bool KarambaPython::menuOptionChanged(karamba* k, QString key, bool value)
+{
+ PyObject* pArgs = Py_BuildValue((char*)"(lsi)", k, key.ascii(), (int)value);
+ return callObject("menuOptionChanged", pArgs);
+}
+
+bool KarambaPython::menuItemClicked(karamba* k, KPopupMenu* menu, long id)
+{
+ PyObject* pArgs = Py_BuildValue((char*)"(lll)", k, menu, id);
+ return callObject("menuItemClicked", pArgs);
+}
+
+bool KarambaPython::meterClicked(karamba* k, Meter* meter, int button)
+{
+ PyObject* pArgs = Py_BuildValue((char*)"(lli)", k, meter, button);
+ return callObject("meterClicked", pArgs);
+}
+
+bool KarambaPython::meterClicked(karamba* k, QString anchor, int button)
+{
+ PyObject* pArgs = Py_BuildValue((char*)"(lsi)", k, anchor.ascii(), button);
+ return callObject("meterClicked", pArgs);
+}
+
+bool KarambaPython::widgetClicked(karamba* k, int x, int y, int button)
+{
+ PyObject* pArgs = Py_BuildValue((char*)"(liii)", k, x, y, button);
+ return callObject("widgetClicked", pArgs);
+}
+
+bool KarambaPython::keyPressed(karamba* k, const Meter* meter,
+ const QString& text)
+{
+ PyObject* pArgs = Py_BuildValue((char*)"(lls)", k, meter, text.ucs2());
+ return callObject("keyPressed", pArgs);
+}
+
+bool KarambaPython::widgetMouseMoved(karamba* k, int x, int y, int button)
+{
+ PyObject* pArgs = Py_BuildValue((char*)"(liii)", k, x, y, button);
+ return callObject("widgetMouseMoved", pArgs);
+}
+
+bool KarambaPython::activeTaskChanged(karamba* k, Task* t)
+{
+ PyObject* pArgs = Py_BuildValue((char*)"(ll)", k, t);
+ return callObject("activeTaskChanged", pArgs);
+}
+
+bool KarambaPython::taskAdded(karamba* k, Task* t)
+{
+ PyObject* pArgs = Py_BuildValue((char*)"(ll)", k, t);
+ return callObject("taskAdded", pArgs);
+}
+
+bool KarambaPython::taskRemoved(karamba* k, Task* t)
+{
+ PyObject* pArgs = Py_BuildValue((char*)"(ll)", k, t);
+ return callObject("taskRemoved", pArgs);
+}
+
+bool KarambaPython::startupAdded(karamba* k, Startup* t)
+{
+ PyObject* pArgs = Py_BuildValue((char*)"(ll)", k, t);
+ return callObject("startupAdded", pArgs);
+}
+
+bool KarambaPython::startupRemoved(karamba* k, Startup* t)
+{
+ PyObject* pArgs = Py_BuildValue((char*)"(ll)", k, t);
+ return callObject("startupRemoved", pArgs);
+}
+
+bool KarambaPython::commandOutput(karamba* k, int pid, char *buffer)
+{
+ PyObject* pArgs = Py_BuildValue((char*)"(lis)", k, pid, buffer);
+ return callObject("commandOutput", pArgs);
+}
+
+bool KarambaPython::commandFinished(karamba* k, int pid)
+{
+ PyObject* pArgs = Py_BuildValue((char*)"(li)", k, pid);
+ return callObject("commandFinished", pArgs);
+}
+
+bool KarambaPython::itemDropped(karamba* k, QString text, int x, int y)
+{
+ PyObject* pArgs = Py_BuildValue((char*)"(lOii)", k, QString2PyString(text), x, y);
+ return callObject("itemDropped", pArgs);
+}
+
+bool KarambaPython::themeNotify(karamba* k, const char *from, const char *str)
+{
+ // WARNING WARNING WARNING i had to switch off thread locking to get
+ // this to work. callNotify is called from INSIDE another locked thread,
+ // so can never complete because themeNotify will expect locking to be
+ // released...
+ //
+ PyObject* pArgs = Py_BuildValue((char*)"(lss)", k, from, str);
+ return callObject("themeNotify", pArgs, false);
+}
+
+bool KarambaPython::systrayUpdated(karamba* k)
+{
+ PyObject* pArgs = Py_BuildValue((char*)"(l)", k);
+ return callObject("systrayUpdated", pArgs);
+}
+
+bool KarambaPython::desktopChanged(karamba* k, int desktop)
+{
+ PyObject* pArgs = Py_BuildValue((char*)"(li)", k, desktop);
+ return callObject("desktopChanged", pArgs);
+}
+
+bool KarambaPython::wallpaperChanged(karamba* k, int desktop)
+{
+ PyObject* pArgs = Py_BuildValue((char*)"(li)", k, desktop);
+ return callObject("wallpaperChanged", pArgs);
+}
diff --git a/superkaramba/src/karamba_python.h b/superkaramba/src/karamba_python.h
new file mode 100644
index 0000000..5f2032e
--- /dev/null
+++ b/superkaramba/src/karamba_python.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+* karamba_python.h - Functions for calling python scripts
+*
+* Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+* Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+* Copyright (c) 2004 Petri Damstn <damu@iki.fi>
+*
+* This file is part of SuperKaramba.
+*
+* SuperKaramba 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.
+*
+* SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+#ifndef KARAMBA_PYTHON_H
+#define KARAMBA_PYTHON_H
+
+class QString;
+class KPopupMenu;
+class Task;
+class Startup;
+class karamba;
+class Meter;
+struct _object;
+typedef struct _object PyObject;
+struct _ts;
+typedef struct _ts PyThreadState;
+class ThemeFile;
+
+class KarambaPython
+{
+protected:
+ bool pythonThemeExtensionLoaded;
+ PyObject *pName, *pModule;
+ PyObject *pDict;
+ static PyThreadState* mainThreadState;
+
+ void getLock(PyThreadState** myThreadState);
+ PyObject* getFunc(const char* function);
+ void releaseLock(PyThreadState* myThreadState);
+ bool callObject(const char* func, PyObject* pArgs, bool lock=true);
+
+public:
+ KarambaPython(const ThemeFile& theme, bool reloading);
+ ~KarambaPython();
+
+ static void initPython();
+ static void shutdownPython();
+
+ bool isExtensionLoaded() { return pythonThemeExtensionLoaded; };
+ bool initWidget(karamba* k);
+ bool widgetUpdated(karamba* k);
+ bool widgetClosed(karamba* k);
+ bool menuOptionChanged(karamba* k, QString key, bool value);
+ bool meterClicked(karamba* k, Meter* meter, int button);
+ bool meterClicked(karamba* k, QString anchor, int button);
+ bool widgetClicked(karamba* k, int x, int y, int button);
+ bool keyPressed(karamba* k, const Meter* meter, const QString& text);
+ bool widgetMouseMoved(karamba* k, int x, int y, int button);
+ bool menuItemClicked(karamba* k, KPopupMenu* menu, long id);
+ bool activeTaskChanged(karamba* k, Task* t);
+ bool taskAdded(karamba* k, Task* t);
+ bool taskRemoved(karamba* k, Task* t);
+ bool startupAdded(karamba* k, Startup* t);
+ bool startupRemoved(karamba* k, Startup* t);
+ bool commandOutput(karamba* k, int pid, char *buffer);
+ bool commandFinished(karamba* k, int pid);
+ bool itemDropped(karamba* k, QString text, int x, int y);
+ bool themeNotify(karamba* k, const char *from, const char *txt);
+ bool systrayUpdated(karamba* k);
+ bool desktopChanged(karamba* k, int desktop);
+ bool wallpaperChanged(karamba* k, int desktop);
+};
+
+#endif // KARAMBA_PYTHON_H
diff --git a/superkaramba/src/karambaapp.cpp b/superkaramba/src/karambaapp.cpp
new file mode 100644
index 0000000..5357b01
--- /dev/null
+++ b/superkaramba/src/karambaapp.cpp
@@ -0,0 +1,427 @@
+/***************************************************************************
+ * Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org> *
+ * Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qdir.h>
+#include <kfiledialog.h>
+#include <kcmdlineargs.h>
+#include <fcntl.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kdebug.h>
+#include <khelpmenu.h>
+
+#include <qtooltip.h>
+
+#include "themesdlg.h"
+#include "karambainterface.h"
+#include "karambaapp.h"
+#include "dcopinterface_stub.h"
+#include "karamba.h"
+#include "superkarambasettings.h"
+#include "qwidgetlist.h"
+
+int KarambaApplication::fd = -1;
+
+KarambaApplication::KarambaApplication() :
+ m_helpMenu(0), iface(0), themeListWindow(0), dcopIfaceStub(0),
+ karambaList(0), sysTrayIcon(0)
+{
+ iface = new KarambaIface();
+ karambaList = new QObjectList();
+ // register ourselves as a dcop client
+ dcopClient()->registerAs(name());
+ dcopClient()->setDefaultObject(dcopIface()->objId());
+}
+
+KarambaApplication::~KarambaApplication()
+{
+ delete iface;
+ delete karambaList;
+ delete themeListWindow;
+ delete dcopIfaceStub;
+ //delete m_helpMenu;
+}
+
+void KarambaApplication::initDcopStub(QCString app)
+{
+ if(app.isEmpty())
+ app = dcopClient()->appId();
+ dcopIfaceStub = new dcopIface_stub(app, iface->objId());
+}
+
+QString KarambaApplication::getMainKaramba()
+{
+ QStringList karambas = getKarambas();
+ QStringList::Iterator it;
+
+ for (it = karambas.begin(); it != karambas.end(); ++it)
+ {
+ if((*it).ascii() == dcopClient()->appId())
+ continue;
+ dcopIface_stub dcop((*it).ascii(), iface->objId());
+ if (dcop.isMainKaramba())
+ return *it;
+ }
+ return QString::null;
+}
+
+bool KarambaApplication::themeExists(QString pretty_name)
+{
+ QWidgetList *list = QApplication::allWidgets();
+ QWidgetListIt it( *list ); // iterate over the widgets
+ QWidget * w;
+ while ( (w=it.current()) != 0 ) // for each widget...
+ {
+ ++it;
+ if (QString(w->name()).startsWith("karamba"))
+ {
+ karamba* k = (karamba*) w;
+ if (k->getPrettyName() == pretty_name)
+ return true;
+ }
+ }
+ delete list; // delete the list, not the widgets
+ return false;
+}
+
+QStringList KarambaApplication::getKarambas()
+{
+ QCStringList applst = dcopClient()->registeredApplications();
+ QCStringList::Iterator it;
+ QCString s;
+ QStringList result;
+
+ for (it = applst.begin(); (s = *it) != 0; ++it)
+ {
+ if (s.left(strlen(name())) == name())
+ result.append(s);
+ }
+ return result;
+}
+
+void KarambaApplication::checkSuperKarambaDir()
+{
+ // Create ~/.superkaramba if necessary
+ QDir configDir(QDir::home().absPath() + "/.superkaramba");
+ if (!configDir.exists())
+ {
+ qWarning("~/.superkaramba doesn't exist");
+ if(!configDir.mkdir(QDir::home().absPath() + "/.superkaramba"))
+ {
+ qWarning("Couldn't create Directory ~/.superkaramba");
+ }
+ else
+ {
+ qWarning("created ~/.superkaramba");
+ }
+ }
+}
+
+void KarambaApplication::setUpSysTray(KAboutData* about)
+{
+ //kdDebug() << k_funcinfo << endl;
+ KAction* action;
+
+ //Create theme list window.
+ //This will function as the main window for the tray icon
+ themeListWindow = new ThemesDlg();
+
+ //Set up systray icon
+ sysTrayIcon = new KSystemTray(themeListWindow);
+
+ KPopupMenu *menu = sysTrayIcon->contextMenu();
+ menu->insertItem(SmallIconSet("superkaramba"),
+ i18n("Hide System Tray Icon"), this,
+ SLOT(globalHideSysTray()));
+ menu->insertSeparator();
+
+ m_helpMenu = new KHelpMenu(themeListWindow, about);
+ action = KStdAction::help(m_helpMenu, SLOT(appHelpActivated()),
+ sysTrayIcon->actionCollection());
+ action->plug(menu);
+ action = KStdAction::aboutApp(m_helpMenu, SLOT(aboutApplication()),
+ sysTrayIcon->actionCollection());
+ action->plug(menu);
+ action = KStdAction::aboutKDE(m_helpMenu, SLOT(aboutKDE()),
+ sysTrayIcon->actionCollection());
+ action->plug(menu);
+
+ sysTrayIcon->setPixmap(sysTrayIcon->loadIcon("superkaramba"));
+ setToolTip();
+
+ if(SuperKarambaSettings::showSysTray())
+ sysTrayIcon->show();
+ else
+ sysTrayIcon->hide();
+
+ //Connect Systray icon's quit event
+ QObject::connect(sysTrayIcon, SIGNAL(quitSelected()),
+ this, SLOT(globalQuitSuperKaramba()));
+}
+
+void KarambaApplication::showKarambaMenuExtension(bool show)
+{
+ QObject *k;
+
+ if(show)
+ {
+ for (k = karambaList->first(); k; k = karambaList->next())
+ {
+ ((karamba*)k)->showMenuExtension();
+ }
+ }
+ else
+ {
+ for (k = karambaList->first(); k; k = karambaList->next())
+ {
+ ((karamba*)k)->hideMenuExtension();
+ }
+ }
+}
+
+void KarambaApplication::setToolTip(const QString &tip)
+{
+ QToolTip::remove(sysTrayIcon);
+ if(tip.isNull())
+ QToolTip::add(sysTrayIcon, i18n("SuperKaramba"));
+ else
+ QToolTip::add(sysTrayIcon, tip);
+}
+
+void KarambaApplication::buildToolTip()
+{
+ if(!sysTrayIcon || !themeListWindow)
+ return;
+
+ QStringList list = themeListWindow->runningThemes();
+
+ if(list.isEmpty())
+ {
+ setToolTip();
+ return;
+ }
+
+ QString toolTip("<b><center>" + i18n("SuperKaramba") + "</center></b>");
+ toolTip += "<table width=300>";
+
+ bool firstRun = true;
+ for(QStringList::Iterator it = list.begin(); it != list.end(); ++it )
+ {
+ if(firstRun)
+ {
+ toolTip +=
+ "<tr><td align=right>" +
+ i18n("1 Running Theme:", "%n Running Themes:", list.count()) +
+ "</td><td align=left>" + (*it) + "</td></tr>";
+ firstRun = false;
+ }
+ else
+ {
+ toolTip += "<tr><td></td><td align=left>" + (*it) + "</td></tr>";
+ }
+ }
+
+ toolTip += "</table>";
+
+ setToolTip(toolTip);
+}
+
+void KarambaApplication::checkPreviousSession(KApplication &app,
+ QStringList &lst)
+{
+ /******
+ Try to restore a previous session if applicable.
+ */
+ if (app.isSessionRestored())
+ {
+ KConfig* config = app.sessionConfig();
+ config->setGroup("General Options");
+ QString restartThemes = config->readEntry("OpenThemes");
+
+ //Get themes that were running
+ lst = QStringList::split(QString(";"), restartThemes);
+ }
+}
+
+void KarambaApplication::checkCommandLine(KCmdLineArgs *args, QStringList &lst)
+{
+ /******
+ Not a saved session - check for themes given on command line
+ */
+ if(args->count() > 0)
+ {
+ for(int i = 0; i < (args->count()); i++)
+ {
+ if( args->arg(i) && *args->arg(i) )
+ {
+ KURL url = args->url(i);
+
+ lst.push_back(url.path());
+ }
+ }
+ }
+}
+
+bool KarambaApplication::startThemes(QStringList &lst)
+{
+ bool result = false;
+
+ for(QStringList::Iterator it = lst.begin(); it != lst.end(); ++it )
+ {
+ karamba *mainWin = 0;
+
+ mainWin = new karamba(*it , QString());
+ mainWin->show();
+ result = true;
+ }
+
+ buildToolTip();
+ return result;
+}
+
+void KarambaApplication::addKaramba(karamba* k, bool reloading)
+{
+ if(!reloading && karambaApp->dcopStub())
+ {
+ int instance = karambaApp->dcopStub()->themeAdded(
+ karambaApp->dcopClient()->appId(), k->theme().file());
+ k->setInstance(instance);
+ }
+ karambaList->append(k);
+}
+
+void KarambaApplication::deleteKaramba(karamba* k, bool reloading)
+{
+ if(!reloading && karambaApp->dcopStub())
+ karambaApp->dcopStub()->themeClosed(
+ karambaApp->dcopClient()->appId(), k->theme().file(), k->instance());
+ karambaList->removeRef(k);
+}
+
+bool KarambaApplication::hasKaramba(karamba* k)
+{
+ return karambaList->containsRef(k) > 0;
+}
+
+// XXX: I guess this should be made with mutex/semaphores
+// but this is good for now...
+
+bool KarambaApplication::lockKaramba()
+{
+ QString file = QDir::home().absPath() + "/.superkaramba/.lock";
+ mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
+
+ fd = open(file.ascii(), O_CREAT | O_RDWR | O_TRUNC, mode);
+ if (fd < 0)
+ {
+ qWarning("Open failed in lock.");
+ return false;
+ }
+ //qDebug("lock %d", getpid());
+ if(lockf(fd, F_LOCK, 0))
+ {
+ qWarning("Lock failed.");
+ return false;
+ }
+ return true;
+}
+
+void KarambaApplication::unlockKaramba()
+{
+ if(fd > 0)
+ {
+ lockf(fd, F_ULOCK, 0);
+ //qDebug("Unlock %d", getpid());
+ close(fd);
+ fd = -1;
+ }
+}
+
+void KarambaApplication::hideSysTray(bool hide)
+{
+ //kdDebug() << k_funcinfo << endl;
+ if(hide)
+ {
+ if(sysTrayIcon)
+ {
+ KMessageBox::information(0,
+ i18n("<qt>Hiding the system tray icon will keep SuperKaramba running "
+ "in background. To show it again use the theme menu.</qt>"),
+ i18n("Hiding System Tray Icon"), "hideIcon");
+ sysTrayIcon->hide();
+ }
+ showKarambaMenuExtension();
+ }
+ else
+ {
+ showKarambaMenuExtension(false);
+ if(sysTrayIcon)
+ sysTrayIcon->show();
+ }
+}
+
+void KarambaApplication::showThemeDialog()
+{
+ //kdDebug() << k_funcinfo << endl;
+ if(themeListWindow)
+ themeListWindow->show();
+}
+
+void KarambaApplication::quitSuperKaramba()
+{
+ if(themeListWindow)
+ themeListWindow->saveUserAddedThemes();
+ qApp->closeAllWindows();
+ qApp->quit();
+}
+
+void KarambaApplication::globalQuitSuperKaramba()
+{
+ QStringList apps = getKarambas();
+ QStringList::Iterator it;
+
+ for (it = apps.begin(); it != apps.end(); ++it)
+ {
+ dcopIface_stub dcop((*it).ascii(), dcopIface()->objId());
+ dcop.quit();
+ }
+}
+
+void KarambaApplication::globalShowThemeDialog()
+{
+ QStringList apps = getKarambas();
+ QStringList::Iterator it;
+
+ for (it = apps.begin(); it != apps.end(); ++it)
+ {
+ dcopIface_stub dcop((*it).ascii(), dcopIface()->objId());
+ dcop.showThemeDialog();
+ }
+}
+
+void KarambaApplication::globalHideSysTray(bool hide)
+{
+ //kdDebug() << k_funcinfo << endl;
+ QStringList apps = getKarambas();
+ QStringList::Iterator it;
+
+ SuperKarambaSettings::setShowSysTray(!hide);
+ SuperKarambaSettings::writeConfig();
+
+ for (it = apps.begin(); it != apps.end(); ++it)
+ {
+ dcopIface_stub dcop((*it).ascii(), dcopIface()->objId());
+ dcop.hideSystemTray(hide);
+ }
+}
+
+#include "karambaapp.moc"
diff --git a/superkaramba/src/karambaapp.h b/superkaramba/src/karambaapp.h
new file mode 100644
index 0000000..ef92244
--- /dev/null
+++ b/superkaramba/src/karambaapp.h
@@ -0,0 +1,95 @@
+/***************************************************************************
+ * Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org> *
+ * Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se> *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef KARAMBAAPP_H
+#define KARAMBAAPP_H
+
+#include "kapplication.h"
+#include <kdeversion.h>
+#include <ksystemtray.h>
+
+#undef KDE_3_2
+#undef KDE_3_3
+#if defined(KDE_MAKE_VERSION)
+#if KDE_VERSION >= KDE_MAKE_VERSION(3,2,0)
+#define KDE_3_2
+#endif
+#if KDE_VERSION >= KDE_MAKE_VERSION(3,3,0)
+#define KDE_3_3
+#endif
+#endif
+
+#define karambaApp ((KarambaApplication*)qApp)
+
+class karamba;
+class KarambaIface;
+class KCmdLineArgs;
+class ThemesDlg;
+class dcopIface_stub;
+class KHelpMenu;
+class KAboutData;
+
+class KarambaApplication : public KApplication
+{
+ Q_OBJECT
+
+ friend class KarambaIface;
+
+ private:
+ static int fd;
+ KHelpMenu* m_helpMenu;
+
+ void showKarambaMenuExtension(bool show = true);
+ void setToolTip(const QString &tip = QString::null);
+
+ protected:
+ KarambaIface* iface;
+ ThemesDlg* themeListWindow;
+ dcopIface_stub* dcopIfaceStub;
+ QObjectList *karambaList;
+ KSystemTray* sysTrayIcon;
+
+ public:
+ KarambaApplication();
+ ~KarambaApplication();
+
+ QString getMainKaramba();
+ QStringList getKarambas();
+ bool themeExists(QString pretty_name);
+ void initDcopStub(QCString app = "");
+ void setUpSysTray(KAboutData* about);
+ void checkPreviousSession(KApplication &app, QStringList &lst);
+ void checkCommandLine(KCmdLineArgs *args, QStringList &lst);
+ bool startThemes(QStringList &lst);
+ KarambaIface* dcopIface() { return iface; };
+ dcopIface_stub* dcopStub() { return dcopIfaceStub; };
+ QWidget* parentWindow() { return (QWidget*)themeListWindow; };
+
+ void addKaramba(karamba* k, bool reloading = false);
+ void deleteKaramba(karamba* k, bool reloading = false);
+ bool hasKaramba(karamba* k);
+
+ static bool lockKaramba();
+ static void unlockKaramba();
+ static void checkSuperKarambaDir();
+
+ public slots:
+ void buildToolTip();
+ void globalQuitSuperKaramba();
+ void globalShowThemeDialog();
+ void globalHideSysTray(bool hide = true);
+
+ protected slots:
+ void quitSuperKaramba();
+ void showThemeDialog();
+ void hideSysTray(bool hide = true);
+};
+
+#endif // KARAMBAAPP_H
diff --git a/superkaramba/src/karambainterface.cpp b/superkaramba/src/karambainterface.cpp
new file mode 100644
index 0000000..7a201d8
--- /dev/null
+++ b/superkaramba/src/karambainterface.cpp
@@ -0,0 +1,153 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Petri Damsten *
+ * petri.damsten@iki.fi *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+
+#include "karamba.h"
+#include "karambainterface.h"
+#include <kdebug.h>
+#include "qwidgetlist.h"
+#include "themesdlg.h"
+
+KarambaIface::KarambaIface(): DCOPObject("KarambaIface")
+{
+}
+
+KarambaIface::~KarambaIface()
+{
+}
+
+karamba* KarambaIface::getKaramba(QString name)
+{
+ QWidgetList *list = QApplication::allWidgets();
+ QWidgetListIt it(*list); // iterate over the widgets
+ QWidget* w;
+ karamba* result = 0;
+
+ while ( (w=it.current()) != 0 ) // for each widget...
+ {
+ ++it;
+ if (QString(w->name()).startsWith("karamba"))
+ {
+ karamba* k = (karamba*) w;
+ //if(k->prettyName == name)
+ if(k->theme().name() == name)
+ {
+ result = k;
+ break;
+ }
+ }
+ }
+ delete list;
+ return result;
+}
+
+ThemesDlg* KarambaIface::getThemeWnd()
+{
+ QWidgetList *list = QApplication::allWidgets();
+ QWidgetListIt it( *list ); // iterate over the widgets
+ QWidget* w;
+ ThemesDlg* result = 0;
+
+ while ( (w=it.current()) != 0 ) // for each widget...
+ {
+ ++it;
+ if (QString(w->name()) == "ThemesLayout")
+ {
+ result = (ThemesDlg*) w;
+ break;
+ }
+ }
+ delete list; // delete the list, not the widgets
+ return result;
+}
+
+void KarambaIface::openTheme(QString filename)
+{
+ QFileInfo file(filename);
+ if(file.exists())
+ {
+ (new karamba(filename, QString()))->show();
+ }
+}
+
+void KarambaIface::openNamedTheme(QString filename, QString name, bool is_sub_theme)
+{
+ QFileInfo file(filename);
+ if(file.exists())
+ {
+ (new karamba(filename, name, false, -1, is_sub_theme))->show();
+ }
+}
+
+void KarambaIface::closeTheme(QString name)
+{
+ kdDebug() << "KarambaIface::closeTheme: " << name << endl;
+ karamba* k;
+
+ while((k = getKaramba(name)))
+ {
+ k->writeConfigData();
+ k->close(true);
+ }
+}
+
+int KarambaIface::themeAdded(QString appId, QString file)
+{
+ ThemesDlg* tw = getThemeWnd();
+ if(tw)
+ return tw->addTheme(appId, file);
+ return -1;
+}
+
+void KarambaIface::themeNotify(QString name, QString text)
+{
+ karamba* k = getKaramba(name);
+ if(k)
+ {
+ k->themeNotify(name, text);
+ }
+}
+
+void KarambaIface::setIncomingData(QString name, QString text)
+{
+ karamba* k = getKaramba(name);
+ if(k)
+ {
+ k->_setIncomingData(text);
+ }
+}
+
+void KarambaIface::themeClosed(QString appId, QString file, int instance)
+{
+ ThemesDlg* tw = getThemeWnd();
+ if(tw)
+ tw->removeTheme(appId, file, instance);
+}
+
+bool KarambaIface::isMainKaramba()
+{
+ if(getThemeWnd())
+ return true;
+ return false;
+}
+
+void KarambaIface::quit()
+{
+ karambaApp->quitSuperKaramba();
+}
+
+void KarambaIface::hideSystemTray(bool hide)
+{
+ karambaApp->hideSysTray(hide);
+}
+
+void KarambaIface::showThemeDialog()
+{
+ karambaApp->showThemeDialog();
+}
diff --git a/superkaramba/src/karambainterface.h b/superkaramba/src/karambainterface.h
new file mode 100644
index 0000000..1202cc5
--- /dev/null
+++ b/superkaramba/src/karambainterface.h
@@ -0,0 +1,42 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Petri Damsten *
+ * petri.damsten@iki.fi *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef KARAMBAINTERFACE_H
+#define KARAMBAINTERFACE_H
+
+#include "dcopinterface.h"
+
+class karamba;
+class ThemeListWindow;
+
+class KarambaIface: virtual public dcopIface
+{
+public:
+ KarambaIface();
+ ~KarambaIface();
+ karamba* getKaramba(QString name);
+ ThemesDlg* getThemeWnd();
+
+public slots:
+ virtual void openTheme(QString filename);
+ virtual void openNamedTheme(QString filename, QString name, bool is_sub_theme);
+ virtual void closeTheme(QString name);
+ virtual void quit();
+ virtual void hideSystemTray(bool show);
+ virtual void showThemeDialog();
+
+ virtual int themeAdded(QString appId, QString file);
+ virtual void themeClosed(QString appId, QString file, int instance);
+ virtual void themeNotify(QString name, QString text);
+ virtual void setIncomingData(QString name, QString text);
+ virtual bool isMainKaramba();
+};
+
+#endif // KARAMBAINTERFACE_H
diff --git a/superkaramba/src/karambalistboxitem.cpp b/superkaramba/src/karambalistboxitem.cpp
new file mode 100644
index 0000000..703e3ef
--- /dev/null
+++ b/superkaramba/src/karambalistboxitem.cpp
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+ * Copyright (c) 2005 Ryan Nickell <p0z3r@earthlink.net>
+ *
+ * This file is part of SuperKaramba.
+ *
+ * SuperKaramba 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.
+ *
+ * SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+#include "karambalistboxitem.h"
+
+KarambaListBoxItem::KarambaListBoxItem( QListBox* listbox, const QString & text ) : QListBoxText(listbox, text) {
+
+}
diff --git a/superkaramba/src/karambalistboxitem.h b/superkaramba/src/karambalistboxitem.h
new file mode 100644
index 0000000..76427c2
--- /dev/null
+++ b/superkaramba/src/karambalistboxitem.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+ * Copyright (c) 2005 Ryan Nickell <p0z3r@earthlink.net>
+ *
+ * This file is part of SuperKaramba.
+ *
+ * SuperKaramba 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.
+ *
+ * SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+#include "karamba.h"
+#include <qlistbox.h>
+
+class KarambaListBoxItem : public QListBoxText
+{
+
+public:
+ QString appId;
+ KarambaListBoxItem( QListBox* listbox, const QString & text=QString::null );
+
+};
diff --git a/superkaramba/src/karambarootpixmap.cpp b/superkaramba/src/karambarootpixmap.cpp
new file mode 100644
index 0000000..b733624
--- /dev/null
+++ b/superkaramba/src/karambarootpixmap.cpp
@@ -0,0 +1,36 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Hans Karlsson *
+ * karlsson.h@home.se *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+
+#include "karambarootpixmap.h"
+#include "karamba.h"
+
+KarambaRootPixmap::KarambaRootPixmap(QWidget *w) :
+ KRootPixmap( w)
+{
+ widget = w;
+}
+
+/*KarambaRootPixmap::KarambaRootPixmap()
+ : KRootPixmap(0)
+ {
+
+//widget = w;
+}
+*/
+
+KarambaRootPixmap::~KarambaRootPixmap()
+{
+}
+
+void KarambaRootPixmap::updateBackground (KSharedPixmap *kpm)
+{
+ ((karamba*)widget)->updateBackground(kpm);
+}
+
diff --git a/superkaramba/src/karambarootpixmap.h b/superkaramba/src/karambarootpixmap.h
new file mode 100644
index 0000000..9445528
--- /dev/null
+++ b/superkaramba/src/karambarootpixmap.h
@@ -0,0 +1,39 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Hans Karlsson *
+ * karlsson.h@home.se *
+ * *
+ * 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. *
+ ***************************************************************************/
+#ifndef KARAMBAROOTPIXMAP_H
+#define KARAMBAROOTPIXMAP_H
+
+#include <qwidget.h>
+#include <krootpixmap.h>
+#include <ksharedpixmap.h>
+
+//#include "karamba.h"
+
+/**
+@author Hans Karlsson
+*/
+class KarambaRootPixmap : public KRootPixmap
+{
+public:
+ //KarambaRootPixmap();
+ KarambaRootPixmap( QWidget *);
+
+ ~KarambaRootPixmap();
+
+
+void updateBackground ( KSharedPixmap * );
+
+private:
+QWidget *widget;
+
+
+};
+
+#endif
diff --git a/superkaramba/src/karambasessionmanaged.cpp b/superkaramba/src/karambasessionmanaged.cpp
new file mode 100644
index 0000000..eccff7e
--- /dev/null
+++ b/superkaramba/src/karambasessionmanaged.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+* karambasessionmanaged.cpp - Karamba session management
+*
+* Copyright (C) 2004 -
+*
+* This file is part of SuperKaramba.
+*
+* SuperKaramba 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.
+*
+* SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+#include <kapplication.h>
+#include <kconfig.h>
+#include "karambasessionmanaged.h"
+#include "karamba.h"
+#include "qwidgetlist.h"
+
+bool KarambaSessionManaged::saveState(QSessionManager&)
+{
+ KConfig* config = kapp->sessionConfig();
+
+ config->setGroup("General Options");
+
+ QString openThemes="";
+
+ QWidgetList *list = QApplication::allWidgets();
+ QWidgetListIt it( *list ); // iterate over the widgets
+ QWidget * w;
+ while ( (w=it.current()) != 0 ) // for each widget...
+ {
+ ++it;
+ if (QString(w->name()).startsWith("karamba"))
+ {
+ karamba* k = (karamba*) w;
+ if (k->isSubTheme())
+ continue;
+ openThemes += QFileInfo(k->theme().file()).absFilePath();
+ k->writeConfigData();
+ openThemes += ";";
+ }
+ }
+ delete list; // delete the list, not the widgets
+
+ qDebug("Open themes %s", openThemes.ascii());
+ config->writeEntry("OpenThemes", openThemes);
+ return true;
+}
+
+bool KarambaSessionManaged::commitData(QSessionManager&)
+{
+ return true;
+}
diff --git a/superkaramba/src/karambasessionmanaged.h b/superkaramba/src/karambasessionmanaged.h
new file mode 100644
index 0000000..9024549
--- /dev/null
+++ b/superkaramba/src/karambasessionmanaged.h
@@ -0,0 +1,30 @@
+/****************************************************************************
+* karambasessionmanaged.h - Karamba session management
+*
+* Copyright (C) 2004 -
+*
+* This file is part of SuperKaramba.
+*
+* SuperKaramba 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.
+*
+* SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+class KarambaSessionManaged : public KSessionManaged
+{
+public:
+ KarambaSessionManaged() {};
+
+ virtual bool commitData( QSessionManager& );
+ virtual bool saveState( QSessionManager& );
+};
diff --git a/superkaramba/src/kwidgetlistbox.cpp b/superkaramba/src/kwidgetlistbox.cpp
new file mode 100644
index 0000000..4749f64
--- /dev/null
+++ b/superkaramba/src/kwidgetlistbox.cpp
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2005 Petri Damstn <petri.damsten@iki.fi>
+ *
+ * This file is part of SuperKaramba.
+ *
+ * SuperKaramba 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.
+ *
+ * SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+#include "kwidgetlistbox.h"
+#include <kdebug.h>
+#include <kglobalsettings.h>
+
+KWidgetListbox::KWidgetListbox(QWidget *parent, const char *name)
+ : QTable(parent, name)
+{
+ setNumRows(0);
+ setNumCols(1);
+ setColumnStretchable(0, true);
+ setLeftMargin(0);
+ setTopMargin(0);
+ horizontalHeader()->hide();
+ verticalHeader()->hide();
+ setSelectionMode(QTable::NoSelection);
+ setFocusStyle(QTable::FollowStyle);
+ connect(this, SIGNAL(currentChanged(int, int)),
+ this, SLOT(selectionChanged(int, int)));
+ setHScrollBarMode(QScrollView::AlwaysOff);
+ setVScrollBarMode(QScrollView::Auto);
+}
+
+KWidgetListbox::~KWidgetListbox()
+{
+ clear();
+}
+
+void KWidgetListbox::clear()
+{
+ for(int i = 0; i < numRows(); ++i)
+ clearCellWidget(i, 0);
+ setNumRows(0);
+}
+
+int KWidgetListbox::insertItem(QWidget* item, int index)
+{
+ int row;
+
+ if(index == -1)
+ {
+ row = numRows();
+ setNumRows(row + 1);
+ }
+ else
+ return -1;
+
+ setRowHeight(row, item->height());
+ setCellWidget(row, 0, item);
+ setItemColors(row, even(row));
+ return row;
+}
+
+void KWidgetListbox::setSelected(QWidget* item)
+{
+ setSelected(index(item));
+}
+
+void KWidgetListbox::selectionChanged(int row, int col)
+{
+ ensureCellVisible(row, col);
+ updateColors();
+ emit selected(row);
+}
+
+void KWidgetListbox::removeItem(QWidget* item)
+{
+ removeItem(index(item));
+}
+
+void KWidgetListbox::removeItem(int index)
+{
+ removeRow(index);
+ updateColors();
+}
+
+void KWidgetListbox::setSelected(int index)
+{
+ setCurrentCell(index, 0);
+}
+
+int KWidgetListbox::selected() const
+{
+ return currentRow();
+}
+
+QWidget* KWidgetListbox::selectedItem() const
+{
+ return item(selected());
+}
+
+QWidget* KWidgetListbox::item(int index) const
+{
+ return cellWidget(index, 0);
+}
+
+int KWidgetListbox::index(QWidget* itm) const
+{
+ for(int i = 0; i < numRows(); ++i)
+ if(item(i) == itm)
+ return i;
+ return -1;
+}
+
+bool KWidgetListbox::even(int index)
+{
+ int v = 0;
+ for(int i = 0; i < numRows(); ++i)
+ {
+ if(index == i)
+ break;
+ if(!isRowHidden(i))
+ ++v;
+ }
+ return (v%2 == 0);
+}
+
+void KWidgetListbox::updateColors()
+{
+ int v = 0;
+ for(int i = 0; i < numRows(); ++i)
+ {
+ if(!isRowHidden(i))
+ {
+ setItemColors(i, (v%2 == 0));
+ ++v;
+ }
+ }
+}
+
+void KWidgetListbox::setItemColors(int index, bool even)
+{
+ QWidget* itm = item(index);
+
+ if(index == selected())
+ {
+ itm->setPaletteBackgroundColor(KGlobalSettings::highlightColor());
+ itm->setPaletteForegroundColor(KGlobalSettings::highlightedTextColor());
+ }
+ else if(even)
+ {
+ itm->setPaletteBackgroundColor(KGlobalSettings::baseColor());
+ itm->setPaletteForegroundColor(KGlobalSettings::textColor());
+ }
+ else
+ {
+ itm->setPaletteBackgroundColor(
+ KGlobalSettings::alternateBackgroundColor());
+ itm->setPaletteForegroundColor(KGlobalSettings::textColor());
+ }
+}
+
+void KWidgetListbox::showItems(show_callback func, void* data)
+{
+ for(int i = 0; i < numRows(); ++i)
+ {
+ if(func == 0)
+ showRow(i);
+ else
+ {
+ if(func(i, item(i), data))
+ showRow(i);
+ else
+ hideRow(i);
+ }
+ }
+ updateColors();
+}
+
+void KWidgetListbox::showEvent(QShowEvent*)
+{
+ //kdDebug() << k_funcinfo << endl;
+ repaintContents(false);
+}
+
+void KWidgetListbox::paintCell(QPainter*, int, int, const QRect&,
+ bool, const QColorGroup&)
+{
+ //kdDebug() << k_funcinfo << endl;
+}
+
+#include "kwidgetlistbox.moc"
diff --git a/superkaramba/src/kwidgetlistbox.h b/superkaramba/src/kwidgetlistbox.h
new file mode 100644
index 0000000..62a52a8
--- /dev/null
+++ b/superkaramba/src/kwidgetlistbox.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2005 Petri Damstn <petri.damsten@iki.fi>
+ *
+ * This file is part of SuperKaramba.
+ *
+ * SuperKaramba 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.
+ *
+ * SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+#ifndef KWIDGETLISTBOX_H
+#define KWIDGETLISTBOX_H
+
+#include <qtable.h>
+
+/**
+@author See README for the list of authors
+*/
+
+typedef bool (*show_callback) (int index, QWidget* widget, void* data);
+
+class KWidgetListbox : public QTable
+{
+ Q_OBJECT
+
+ public:
+ KWidgetListbox(QWidget *parent = 0, const char *name = 0);
+ ~KWidgetListbox();
+
+ int insertItem(QWidget* item, int index = -1);
+ void setSelected(QWidget* item);
+ void setSelected(int index);
+ void removeItem(QWidget* item);
+ void removeItem(int index);
+ void clear();
+ int selected() const;
+ QWidget* selectedItem() const;
+ QWidget* item(int index) const;
+ int index(QWidget* itm) const;
+ uint count() const { return numRows(); };
+
+ void showItems(show_callback func = 0, void* data = 0);
+
+ void paintCell(QPainter* p, int row, int col, const QRect& cr,
+ bool selected, const QColorGroup& cg);
+ protected:
+ void setItemColors(int index, bool even);
+ void updateColors();
+ bool even(int index);
+ virtual void showEvent(QShowEvent* e);
+
+ protected slots:
+ void selectionChanged(int row, int col);
+
+ signals:
+ void selected(int index);
+};
+
+#endif
diff --git a/superkaramba/src/lineparser.cpp b/superkaramba/src/lineparser.cpp
new file mode 100644
index 0000000..d923b6c
--- /dev/null
+++ b/superkaramba/src/lineparser.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+ * Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+ * Copyright (c) 2005 Ryan Nickell <p0z3r@earthlink.net>
+ * Copyright (c) 2005 Petri Damsten <damu@iki.fi>
+ *
+ * This file is part of SuperKaramba.
+ *
+ * SuperKaramba 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.
+ *
+ * SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+#include "lineparser.h"
+#include <qregexp.h>
+
+LineParser::LineParser(const QString& line)
+{
+ set(line);
+}
+
+LineParser::~LineParser()
+{
+}
+
+void LineParser::set(const QString& line)
+{
+ QRegExp rx("^\\s*(\\S+)");
+ m_line = line;
+
+ rx.search(m_line);
+ m_meter = rx.cap(1).upper();
+}
+
+int LineParser::getInt(QString w, int def) const
+{
+ QRegExp rx( "\\W+" + w +"=([-]?\\d+)", false );
+ if (rx.search(m_line) != -1)
+ return rx.cap(1).toInt();
+ else
+ return def;
+}
+
+QColor LineParser::getColor(QString w, QColor def) const
+{
+ QRegExp rx( "\\W+" + w + "=([-]?\\d+),([-]?\\d+),([-]?\\d+)", false );
+ if (rx.search(m_line) != -1)
+ return QColor(rx.cap(1).toInt(), rx.cap(2).toInt(), rx.cap(3).toInt());
+ else
+ return def;
+}
+
+QString LineParser::getString(QString w, QString def) const
+{
+ QString result;
+ QRegExp rx( "\\W+" + w + "=\"([^\"]*)\"", false );
+
+ bool found = (rx.search(m_line)==-1)?false:true;
+ if (rx.cap(1).isEmpty())
+ {
+ rx = QRegExp(w + "=(\\S+)", false);
+ found = (rx.search(m_line)==-1)?false:true;
+ result = rx.cap(1);
+ }
+ else
+ {
+ result = rx.cap(1);
+ }
+ if(found)
+ return result;
+ else
+ return def;
+}
+
+bool LineParser::getBoolean(QString w, bool def) const
+{
+ QString boolean = getString(w, "-").lower();
+ if(boolean == "-")
+ return def;
+ else if (boolean == "true") // true / false
+ return true;
+ else if (boolean == "1") // 1 / 0
+ return true;
+ else if (boolean == "on") // on / off
+ return true;
+ return false;
+}
diff --git a/superkaramba/src/lineparser.h b/superkaramba/src/lineparser.h
new file mode 100644
index 0000000..b877e6c
--- /dev/null
+++ b/superkaramba/src/lineparser.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+ * Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+ * Copyright (c) 2005 Ryan Nickell <p0z3r@earthlink.net>
+ * Copyright (c) 2005 Petri Damsten <damu@iki.fi>
+ *
+ * This file is part of SuperKaramba.
+ *
+ * SuperKaramba 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.
+ *
+ * SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+#ifndef LINEPARSER_H
+#define LINEPARSER_H
+
+/**
+@author See README for the list of authors
+*/
+
+#include <qstring.h>
+#include <qcolor.h>
+
+class LineParser
+{
+ public:
+ LineParser(const QString& line = QString::null);
+ ~LineParser();
+
+ void set(const QString& line);
+
+ int getInt(QString w, int def = 0) const;
+ QColor getColor(QString w, QColor def = QColor()) const;
+ QString getString(QString w, QString def = QString()) const;
+ bool getBoolean(QString w, bool def = false) const;
+
+ const QString& meter() const { return m_meter; };
+
+ private:
+ QString m_line;
+ QString m_meter;
+};
+
+#endif
diff --git a/superkaramba/src/main.cpp b/superkaramba/src/main.cpp
new file mode 100644
index 0000000..14c651c
--- /dev/null
+++ b/superkaramba/src/main.cpp
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+ * Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+ * Copyright (c) 2005 Ryan Nickell <p0z3r@earthlink.net>
+ *
+ * This file is part of SuperKaramba.
+ *
+ * SuperKaramba 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.
+ *
+ * SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#include <karambaapp.h>
+#include <qobject.h>
+
+#include <kaboutdata.h>
+#include <kcmdlineargs.h>
+#include <klocale.h>
+#include <kconfig.h>
+#include <kmainwindow.h>
+#include <qfileinfo.h>
+#include <qstringlist.h>
+#include <kconfig.h>
+#include <kstandarddirs.h>
+#include <kdeversion.h>
+
+#include "karamba.h"
+#include "karambasessionmanaged.h"
+#include "karambainterface.h"
+#include "karamba_python.h"
+
+static const char *description =
+ I18N_NOOP("A KDE Eye-candy Application");
+
+static const char *version = "0.42";
+
+static KCmdLineOptions options[] =
+{
+ // { "+[URL]", I18N_NOOP( "Document to open" ), 0 },
+ // { "!nosystray", I18N_NOOP("Disable systray icon"), 0 },
+ { "+file", I18N_NOOP("A required argument 'file'"), 0 },
+ { 0, 0, 0 }
+};
+
+// This is for redirecting all qWarning, qDebug,... messages to file.
+// Usefull when testing session management issues etc.
+// #define KARAMBA_LOG 1
+
+#ifdef KARAMBA_LOG
+
+void karambaMessageOutput(QtMsgType type, const char *msg)
+{
+ FILE* fp = fopen("/tmp/karamba.log", "a");
+ if(fp)
+ {
+ pid_t pid = getpid();
+
+ switch ( type )
+ {
+ case QtDebugMsg:
+ fprintf( fp, "Debug (%d): %s\n", pid, msg );
+ break;
+ case QtWarningMsg:
+ if (strncmp(msg, "X Error", 7) != 0)
+ fprintf( fp, "Warning (%d): %s\n", pid, msg );
+ break;
+ case QtFatalMsg:
+ fprintf( fp, "Fatal (%d): %s\n", pid, msg );
+ abort(); // deliberately core dump
+ }
+ fclose(fp);
+ }
+}
+
+#endif
+
+int main(int argc, char **argv)
+{
+#ifdef KARAMBA_LOG
+ qInstallMsgHandler(karambaMessageOutput);
+#endif
+ KAboutData about("superkaramba", I18N_NOOP("SuperKaramba"),
+ version, description,
+ KAboutData::License_GPL,
+ "(c) 2003-2006 The SuperKaramba developers");
+ about.addAuthor("Adam Geitgey", 0, "adam@rootnode.org");
+ about.addAuthor("Hans Karlsson", 0, "karlsson.h@home.se");
+ about.addAuthor("Ryan Nickell", 0, "p0z3r@earthlink.net");
+ about.addAuthor("Petri Damstén", 0, "petri.damsten@iki.fi");
+ about.addAuthor("Alexander Wiedenbruch", 0, "mail@wiedenbruch.de");
+ about.addAuthor("Luke Kenneth Casson Leighton", 0, "lkcl@lkcl.net");
+ KCmdLineArgs::init(argc, argv, &about);
+ KCmdLineArgs::addCmdLineOptions(options);
+ KarambaSessionManaged ksm;
+ //karamba *mainWin = 0;
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+ QStringList lst;
+ int ret = 0;
+
+ // Create ~/.superkaramba if necessary
+ KarambaApplication::checkSuperKarambaDir();
+
+ KarambaApplication::lockKaramba();
+
+ KarambaApplication app;
+
+ QString mainAppId = app.getMainKaramba();
+ if(!mainAppId.isEmpty())
+ {
+ app.initDcopStub(mainAppId.ascii());
+ }
+ else
+ {
+ //Set up systray icon
+ app.setUpSysTray(&about);
+ app.initDcopStub();
+ }
+
+ KarambaApplication::unlockKaramba();
+
+ app.connect(qApp,SIGNAL(lastWindowClosed()),qApp,SLOT(quit()));
+
+ // Try to restore a previous session if applicable.
+ app.checkPreviousSession(app, lst);
+ if( (lst.size() == 0) && !app.isRestored() )
+ {
+ //Not a saved session - check for themes given on command line
+ app.checkCommandLine(args, lst);
+
+ if(lst.size() == 0)
+ {
+ //No themes given on command line and no saved session.
+ //Show welcome dialog.
+ app.globalShowThemeDialog();
+ }
+ }
+
+ args->clear();
+
+ KarambaPython::initPython();
+ //qDebug("startThemes");
+ if(app.startThemes(lst) || mainAppId.isEmpty())
+ ret = app.exec();
+ KarambaPython::shutdownPython();
+ return ret;
+}
diff --git a/superkaramba/src/memsensor.cpp b/superkaramba/src/memsensor.cpp
new file mode 100644
index 0000000..21d9f35
--- /dev/null
+++ b/superkaramba/src/memsensor.cpp
@@ -0,0 +1,359 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Hans Karlsson *
+ * karlsson.h@home.se *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "memsensor.h"
+#include <qfile.h>
+#include <qglobal.h>
+#include <qtextstream.h>
+#include <qstring.h>
+#include <qregexp.h>
+
+#ifdef Q_OS_FREEBSD
+#include <sys/time.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/resource.h>
+#include <unistd.h>
+#include <kvm.h>
+#include <sys/file.h>
+#include <osreldate.h>
+#endif
+
+#if defined(Q_OS_NETBSD)
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/sched.h>
+#include <sys/swap.h>
+#endif
+
+#include <kprocio.h>
+
+#if defined Q_OS_FREEBSD || defined(Q_OS_NETBSD)
+/* define pagetok in terms of pageshift */
+#define pagetok(size) ((size) << pageshift)
+#endif
+
+MemSensor::MemSensor(int msec) : Sensor(msec)
+{
+#if defined Q_OS_FREEBSD || defined(Q_OS_NETBSD)
+ /* get the page size with "getpagesize" and calculate pageshift from it */
+ int pagesize = getpagesize();
+ pageshift = 0;
+ while (pagesize > 1)
+ {
+ pageshift++;
+ pagesize >>= 1;
+ }
+
+ /* we only need the amount of log(2)1024 for our conversion */
+ pageshift -= 10;
+# if defined(Q_OS_FREEBSD) && defined(__FreeBSD_version) && __FreeBSD_version >= 500018
+ kd = kvm_open("/dev/null", "/dev/null", "/dev/null", O_RDONLY, "kvm_open");
+# elif defined Q_OS_FREEBSD
+ connect(&ksp, SIGNAL(receivedStdout(KProcess *, char *, int )),
+ this,SLOT(receivedStdout(KProcess *, char *, int )));
+ connect(&ksp, SIGNAL(processExited(KProcess *)),
+ this,SLOT(processExited( KProcess * )));
+
+ swapTotal = swapUsed = 0;
+
+ MaxSet = false;
+
+ readValues();
+# endif
+#else
+ readValues();
+#endif
+}
+
+MemSensor::~MemSensor()
+{}
+
+#ifdef Q_OS_FREEBSD
+void MemSensor::receivedStdout(KProcess *, char *buffer, int len )
+{
+ buffer[len] = 0;
+ sensorResult += QString( QCString(buffer) );
+}
+#else
+void MemSensor::receivedStdout(KProcess *, char *, int)
+{
+}
+#endif
+
+void MemSensor::processExited(KProcess *)
+{
+#ifdef Q_OS_FREEBSD
+ QStringList stringList = QStringList::split('\n',sensorResult);
+ sensorResult = "";
+ QStringList itemsList = QStringList::split(' ', stringList[1]);
+
+ swapUsed = itemsList[2].toInt();
+ swapTotal = itemsList[1].toInt();
+#endif
+}
+
+int MemSensor::getMemTotal()
+{
+#if defined Q_OS_FREEBSD || defined(Q_OS_NETBSD)
+ static int mem = 0;
+ size_t size = sizeof(mem);
+
+ sysctlbyname("hw.physmem", &mem, &size, NULL, 0);
+ return (mem / 1024);
+#else
+ QRegExp rx( "MemTotal:\\s*(\\d+)" );
+ rx.search( meminfo );
+ return ( rx.cap(1).toInt() );
+#endif
+}
+
+int MemSensor::getMemFree()
+{
+#ifdef Q_OS_FREEBSD
+ static int mem = 0;
+ size_t size = sizeof(mem);
+
+ sysctlbyname("vm.stats.vm.v_free_count", &mem, &size, NULL, 0);
+ return (pagetok(mem));
+#elif defined(Q_OS_NETBSD)
+ struct uvmexp_sysctl uvmexp;
+ int mib[2];
+ size_t ssize;
+ mib[0] = CTL_VM;
+ mib[1] = VM_UVMEXP2;
+ ssize = sizeof(uvmexp);
+ sysctl(mib,2,&uvmexp,&ssize,NULL,0);
+ return pagetok(uvmexp.free);
+#else
+ QRegExp rx( "MemFree:\\s*(\\d+)" );
+ rx.search( meminfo );
+ return ( rx.cap(1).toInt() );
+#endif
+}
+
+int MemSensor::getBuffers()
+{
+#ifdef Q_OS_FREEBSD
+ static int mem = 0;
+ size_t size = sizeof(mem);
+
+ sysctlbyname("vfs.bufspace", &mem, &size, NULL, 0);
+ return (mem / 1024);
+#elif defined(Q_OS_NETBSD)
+ static int buf_mem = 0;
+ size_t size = sizeof(buf_mem);
+
+ sysctlbyname("vm.bufmem", &buf_mem, &size, NULL, 0);
+ return (buf_mem / 1024);
+#else
+ QRegExp rx( "Buffers:\\s*(\\d+)" );
+ rx.search( meminfo );
+ return ( rx.cap(1).toInt() );
+#endif
+}
+
+int MemSensor::getCached()
+{
+#ifdef Q_OS_FREEBSD
+ static int mem = 0;
+ size_t size = sizeof(mem);
+
+ sysctlbyname("vm.stats.vm.v_cache_count", &mem, &size, NULL, 0);
+ return (pagetok(mem));
+#elif defined(Q_OS_NETBSD)
+ return 0;
+#else
+ QRegExp rx1( "Cached:\\s*(\\d+)" );
+ QRegExp rx2( "SwapCached:\\s*(\\d+)" );
+ rx1.search( meminfo );
+ rx2.search( meminfo );
+ return ( rx1.cap(1).toInt() + rx2.cap(1).toInt() );
+#endif
+}
+
+
+int MemSensor::getSwapTotal()
+{
+#ifdef Q_OS_FREEBSD
+# if defined(__FreeBSD_version) && __FreeBSD_version >= 500018
+ int n = -1;
+ int pagesize = getpagesize();
+ int retavail = 0;
+
+ if (kd != NULL)
+ n = kvm_getswapinfo(kd, &swapinfo, 1, 0);
+
+ if (n < 0 || swapinfo.ksw_total == 0)
+ return(0);
+
+ retavail = swapinfo.ksw_total * pagesize / 1024;
+
+ return(retavail);
+#else
+ return(swapTotal);
+# endif
+#elif defined(Q_OS_NETBSD)
+ struct uvmexp_sysctl uvmexp;
+ int STotal = 0;
+ int pagesize = 1;
+ int mib[2];
+ size_t ssize;
+ mib[0] = CTL_VM;
+ mib[1] = VM_UVMEXP;
+ ssize = sizeof(uvmexp);
+
+ if (sysctl(mib,2,&uvmexp,&ssize,NULL,0) != -1) {
+ pagesize = uvmexp.pagesize;
+ STotal = (pagesize*uvmexp.swpages) >> 10;
+ }
+ return STotal;
+#else
+ QRegExp rx( "SwapTotal:\\s*(\\d+)" );
+ rx.search( meminfo );
+ return ( rx.cap(1).toInt() );
+#endif
+}
+
+int MemSensor::getSwapFree()
+{
+#ifdef Q_OS_FREEBSD
+# if defined(__FreeBSD_version) && __FreeBSD_version >= 500018
+ int n = -1;
+ int pagesize = getpagesize();
+ int retfree = 0;
+
+ if (kd != NULL)
+ n = kvm_getswapinfo(kd, &swapinfo, 1, 0);
+ if (n < 0 || swapinfo.ksw_total == 0)
+ return(0);
+
+ retfree = (swapinfo.ksw_total - swapinfo.ksw_used) * pagesize / 1024;
+
+ return(retfree);
+# else
+ return(swapTotal - swapUsed);
+# endif
+#elif defined(Q_OS_NETBSD)
+ struct uvmexp_sysctl uvmexp;
+ int STotal = 0;
+ int SFree = 0;
+ int SUsed = 0;
+ int pagesize = 1;
+ int mib[2];
+ size_t ssize;
+ mib[0] = CTL_VM;
+ mib[1] = VM_UVMEXP;
+ ssize = sizeof(uvmexp);
+
+ if (sysctl(mib,2,&uvmexp,&ssize,NULL,0) != -1) {
+ pagesize = uvmexp.pagesize;
+ STotal = (pagesize*uvmexp.swpages) >> 10;
+ SUsed = (pagesize*uvmexp.swpginuse) >> 10;
+ SFree = STotal - SUsed;
+ }
+ return SFree;
+#else
+ QRegExp rx( "SwapFree:\\s*(\\d+)" );
+ rx.search( meminfo );
+ return ( rx.cap(1).toInt() );
+#endif
+}
+
+void MemSensor::readValues()
+{
+#if defined Q_OS_FREEBSD || defined(Q_OS_NETBSD)
+# if defined(Q_OS_FREEBSD) && !(defined(__FreeBSD_version) && __FreeBSD_version >= 500018)
+ ksp.clearArguments();
+ ksp << "swapinfo";
+ ksp.start( KProcess::NotifyOnExit,KProcIO::Stdout);
+# endif
+#else
+ QFile file("/proc/meminfo");
+ QString line;
+ if ( file.open(IO_ReadOnly | IO_Translate) )
+ {
+ QTextStream t( &file ); // use a text stream
+ meminfo = t.read();
+ file.close();
+ }
+#endif
+}
+
+void MemSensor::update()
+{
+ readValues();
+ QString format;
+ SensorParams *sp;
+ Meter *meter;
+ QObjectListIt it( *objList );
+#if defined(Q_OS_FREEBSD) && !(defined(__FreeBSD_version) && __FreeBSD_version >= 500018)
+ bool set = false;
+#endif
+ int totalMem = getMemTotal();
+ int usedMem = totalMem - getMemFree();
+ int usedMemNoBuffers = usedMem - getBuffers() - getCached();
+ int totalSwap = getSwapTotal();
+ int usedSwap = totalSwap - getSwapFree();
+
+ while (it != 0)
+ {
+ sp = (SensorParams*)(*it);
+#if defined(Q_OS_FREEBSD) && !(defined(__FreeBSD_version) && __FreeBSD_version >= 500018)
+ if ( (!MaxSet) && (totalSwap > 0) ) {
+ setMaxValue(sp);
+ bool set = true;
+ }
+#endif
+ meter = sp->getMeter();
+ format = sp->getParam("FORMAT");
+ if (format.length() == 0 )
+ {
+ format = "%um";
+ }
+
+ format.replace( QRegExp("%fmb", false), QString::number( (int)(( totalMem - usedMemNoBuffers)/1024.0+0.5)));
+ format.replace( QRegExp("%fm", false), QString::number( (int)( ( totalMem - usedMem )/1024.0+0.5) ));
+
+ format.replace( QRegExp("%umb", false), QString::number( (int)((usedMemNoBuffers)/1024.0+0.5)));
+ format.replace( QRegExp("%um", false), QString::number( (int)((usedMem)/1024.0+0.5 )));
+
+ format.replace( QRegExp("%tm", false), QString::number( (int)( (totalMem)/1024.0+0.5)));
+
+ format.replace( QRegExp("%fs", false), QString::number( (int)((totalSwap - usedSwap)/1024.0+0.5)));
+ format.replace( QRegExp("%us", false), QString::number( (int)(usedSwap/1024.0+0.5)));
+ format.replace( QRegExp("%ts", false), QString::number( (int)(totalSwap/1024.0+0.5)));
+
+ meter->setValue(format);
+ ++it;
+ }
+#if defined(Q_OS_FREEBSD) && !(defined(__FreeBSD_version) && __FreeBSD_version >= 500018)
+ if (set)
+ MaxSet = true;
+#endif
+}
+
+void MemSensor::setMaxValue( SensorParams *sp )
+{
+ Meter *meter;
+ meter = sp->getMeter();
+ QString f;
+ f = sp->getParam("FORMAT");
+
+ if (f.length() == 0 )
+ {
+ f = "%um";
+ }
+ if( f=="%fm" || f== "%um" || f=="%fmb" || f=="%umb" )
+ meter->setMax( getMemTotal() / 1024 );
+ if( f=="%fs" || f== "%us" )
+ meter->setMax( getSwapTotal() / 1024 );
+}
+
+#include "memsensor.moc"
diff --git a/superkaramba/src/memsensor.h b/superkaramba/src/memsensor.h
new file mode 100644
index 0000000..a9e425e
--- /dev/null
+++ b/superkaramba/src/memsensor.h
@@ -0,0 +1,67 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Hans Karlsson *
+ * karlsson.h@home.se *
+ * *
+ * 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. *
+ ***************************************************************************/
+#ifndef MEMSENSOR_H
+#define MEMSENSOR_H
+#include "sensor.h"
+#include <qglobal.h>
+#include <qstring.h>
+#include <qregexp.h>
+#include <kprocess.h>
+
+#ifdef __FreeBSD__
+#include <kprocio.h>
+#include <kvm.h>
+#include <osreldate.h>
+#endif
+
+class MemSensor : public Sensor
+{
+Q_OBJECT
+public:
+
+ MemSensor( int interval );
+ ~MemSensor();
+
+ int getMemTotal();
+ int getMemFree();
+ int getBuffers();
+ int getCached();
+
+ int getSwapTotal();
+ int getSwapFree();
+
+ void update();
+ void setMaxValue( SensorParams *sp );
+ QString getMemLine();
+
+private:
+ QString meminfo;
+ void readValues();
+#if defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD)
+ int pageshift; /* log base 2 of the pagesize */
+ QString sensorResult;
+ int swapTotal;
+ int swapUsed;
+# if defined(Q_OS_FREEBSD) && defined(__FreeBSD_version) && __FreeBSD_version >= 500018
+ kvm_t *kd;
+ kvm_swap swapinfo;
+# elif defined(Q_OS_FREEBSD)
+ KShellProcess ksp;
+ bool MaxSet;
+# endif
+#endif
+
+private slots:
+ void receivedStdout(KProcess *, char *buffer, int);
+ void processExited(KProcess *);
+
+};
+
+#endif // MEMSENSOR_H
diff --git a/superkaramba/src/menu_python.cpp b/superkaramba/src/menu_python.cpp
new file mode 100644
index 0000000..0a85836
--- /dev/null
+++ b/superkaramba/src/menu_python.cpp
@@ -0,0 +1,200 @@
+/****************************************************************************
+* menu_python.h - Functions for menu python api
+*
+* Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+* Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+* Copyright (c) 2004 Petri Damstn <damu@iki.fi>
+*
+* This file is part of SuperKaramba.
+*
+* SuperKaramba 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.
+*
+* SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+#ifdef _XOPEN_SOURCE
+#undef _XOPEN_SOURCE
+#endif
+
+#include <Python.h>
+#include <qobject.h>
+#include "karamba.h"
+#include "meter.h"
+#include "meter_python.h"
+#include "menu_python.h"
+
+long createMenu(long widget)
+{
+ karamba* currTheme = (karamba*)widget;
+
+ KPopupMenu* tmp = new KPopupMenu(currTheme);
+ currTheme->menuList->append (tmp );
+
+ currTheme->connect(tmp, SIGNAL(activated(int)), currTheme,
+ SLOT(passMenuItemClicked(int)));
+
+ return (long)tmp;
+}
+
+PyObject* py_create_menu(PyObject *, PyObject *args)
+{
+ long widget;
+ if (!PyArg_ParseTuple(args, (char*)"l:createMenu", &widget))
+ return NULL;
+ return Py_BuildValue((char*)"l", createMenu(widget));
+}
+
+bool menuExists(karamba* currTheme, KPopupMenu* menu)
+{
+ bool foundMenu = false;
+ KPopupMenu* tmp;
+
+ for(int i = 0; i < (int)currTheme->menuList->count(); i++)
+ {
+ if(i==0)
+ {
+ tmp = (KPopupMenu*) currTheme->menuList->first();
+ }
+ else
+ {
+ tmp = (KPopupMenu*) currTheme->menuList->next();
+ }
+ if(tmp != 0)
+ {
+ if(tmp == menu)
+ {
+ foundMenu = true;
+ break;
+ }
+ }
+ }
+ return foundMenu;
+}
+
+long deleteMenu(long widget, long menu)
+{
+ karamba* currTheme = (karamba*)widget;
+ KPopupMenu* tmp = (KPopupMenu*)menu;
+
+ currTheme->menuList->removeRef(tmp);
+
+ return 1;
+}
+
+PyObject* py_delete_menu(PyObject *, PyObject *args)
+{
+ long widget, menu;
+ if (!PyArg_ParseTuple(args, (char*)"ll:deleteMenu", &widget, &menu))
+ return NULL;
+ return Py_BuildValue((char*)"l", deleteMenu(widget, menu));
+}
+
+long addMenuItem(long widget, long menu, QString text, QString icon)
+{
+ karamba* currTheme = (karamba*)widget;
+ KPopupMenu* tmp = (KPopupMenu*)menu;
+
+ long id = 0;
+ if(menuExists(currTheme, tmp))
+ {
+ id = tmp->insertItem(SmallIconSet(icon), text);
+ }
+ return id;
+}
+
+PyObject* py_add_menu_item(PyObject *, PyObject *args)
+{
+ long widget, menu;
+ char* i;
+ PyObject* t;
+ if (!PyArg_ParseTuple(args, (char*)"llOs:addMenuItem", &widget, &menu, &t, &i))
+ return NULL;
+ QString icon;
+ QString text;
+ icon.setAscii(i);
+ text = PyString2QString(t);
+ return Py_BuildValue((char*)"l", addMenuItem(widget, menu, text, icon));
+}
+
+long addMenuSeparator(long widget, long menu)
+{
+ karamba* currTheme = (karamba*)widget;
+ KPopupMenu* tmp = (KPopupMenu*)menu;
+
+ long id = 0;
+ if(menuExists(currTheme, tmp))
+ {
+ id = tmp->insertSeparator();
+ }
+
+ return id;
+}
+
+PyObject* py_add_menu_separator(PyObject *, PyObject *args)
+{
+ long widget, menu;
+
+ if (!PyArg_ParseTuple(args, (char*)"ll:addMenuSeparator", &widget, &menu))
+ return NULL;
+
+ return Py_BuildValue((char*)"l", addMenuSeparator(widget, menu));
+}
+
+long removeMenuItem(long widget, long menu, long id)
+{
+ karamba* currTheme = (karamba*)widget;
+ KPopupMenu* tmp = (KPopupMenu*)menu;
+
+ if(menuExists(currTheme,tmp))
+ {
+ tmp->removeItem(id);
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+PyObject* py_remove_menu_item(PyObject *, PyObject *args)
+{
+ long widget, menu, id;
+ if (!PyArg_ParseTuple(args, (char*)"lll:removeMenuItem", &widget, &menu, &id))
+ return NULL;
+ return Py_BuildValue((char*)"l", removeMenuItem(widget, menu, id));
+}
+
+long popupMenu(long widget, long menu, long x, long y)
+{
+ karamba* currTheme = (karamba*)widget;
+ KPopupMenu* tmp = (KPopupMenu*)menu;
+
+ if(menuExists(currTheme,tmp))
+ {
+ tmp->popup(currTheme->mapToGlobal( QPoint(x,y) ));
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+PyObject* py_popup_menu(PyObject *, PyObject *args)
+{
+ long widget, menu, x, y;
+ if (!PyArg_ParseTuple(args, (char*)"llll:popupMenu", &widget, &menu, &x, &y))
+ return NULL;
+ return Py_BuildValue((char*)"l", popupMenu(widget, menu, x, y));
+}
+
diff --git a/superkaramba/src/menu_python.h b/superkaramba/src/menu_python.h
new file mode 100644
index 0000000..88f8ea0
--- /dev/null
+++ b/superkaramba/src/menu_python.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+* menu_python.h - Functions for menu python api
+*
+* Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+* Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+* Copyright (c) 2004 Petri Damstn <damu@iki.fi>
+*
+* This file is part of SuperKaramba.
+*
+* SuperKaramba 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.
+*
+* SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+#ifndef MENU_PYTHON_H
+#define MENU_PYTHON_H
+
+/** Menu/createMenu
+*
+* SYNOPSIS
+* long createMenu(widget)
+* DESCRIPTION
+* This creates an empty popup menu and returns a pointer to the menu.
+* ARGUMENTS
+* * long widget -- karamba
+* RETURN VALUE
+* pointer to menu
+*/
+PyObject* py_create_menu(PyObject *self, PyObject *args);
+
+/** Menu/deleteMenu
+*
+* SYNOPSIS
+* long deleteMenu(widget, menu)
+* DESCRIPTION
+* This deletes the referenced menu if that menu exists.
+* ARGUMENTS
+* * long widget -- karamba
+* * long menu -- pointer to menu
+* RETURN VALUE
+* 1 if menu existed and was deleted, returns 0 otherwise.
+*/
+PyObject* py_delete_menu(PyObject *self, PyObject *args);
+
+/** Menu/addMenuItem
+*
+* SYNOPSIS
+* long addMenuItem(widget, menu, text, icon)
+* DESCRIPTION
+* This adds an entry to the given menu with label text and with given icon.
+* icon can be just an application name in which case the user's current
+* icon set is used, or can be a path to a 16x16 png file.
+*
+* The function returns the id of the menu item, which identifies that popup
+* menu item uniquely among popupmenu items application-wide or returns 0
+* if the given menu doesn't exist.
+* ARGUMENTS
+* * long widget -- karamba
+* * long menu -- pointer to menu
+* * string text -- text for menu item
+* * string icon -- icon
+* RETURN VALUE
+* menu item id
+*/
+PyObject* py_add_menu_item(PyObject *self, PyObject *args);
+
+/** Menu/addMenuSeparator
+*
+* SYNOPSIS
+* long addMenuSeparator(widget, menu)
+* DESCRIPTION
+* This adds an menu separator to the given menu.
+* ARGUMENTS
+* * long widget -- karamba
+* * long menu -- pointer to menu
+* RETURN VALUE
+* menu item id
+*/
+PyObject* py_add_menu_separator(PyObject *self, PyObject *args);
+
+/** Menu/removeMenuItem
+*
+* SYNOPSIS
+* long removeMenuItem(widget, menu, id)
+* DESCRIPTION
+* This removes the item with given id from given menu if that menu exists.
+* ARGUMENTS
+* * long widget -- karamba
+* * long menu -- pointer to menu
+* * long id -- menu item id
+* RETURN VALUE
+* 1 if the menu item existed and was removed or returns zero otherwise.
+*/
+PyObject* py_remove_menu_item(PyObject *self, PyObject *args);
+
+/** Menu/popupMenu
+*
+* SYNOPSIS
+* long popupMenu(widget, menu, x, y)
+* DESCRIPTION
+* This pops up the given menu at the given co-ordinates. The co-ordinates
+* are relative to the widget, not the screen. You can use negative
+* co-ordinates to make a menu appear to the right of or above your theme.
+* ARGUMENTS
+* * long widget -- karamba
+* * long menu -- pointer to menu
+* * long x -- x coordinate
+* * long y -- y coordinate
+* RETURN VALUE
+* 1 if the menu existed and was popped up, returns 0 otherwise.
+*/
+PyObject* py_popup_menu(PyObject *self, PyObject *args);
+
+#endif // MENU_PYTHON_H
diff --git a/superkaramba/src/meter.cpp b/superkaramba/src/meter.cpp
new file mode 100644
index 0000000..efc8a13
--- /dev/null
+++ b/superkaramba/src/meter.cpp
@@ -0,0 +1,111 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Hans Karlsson *
+ * karlsson.h@home.se *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "meter.h"
+
+Meter::Meter(karamba* k, int ix, int iy, int iw, int ih):
+ boundingBox(ix, iy, iw, ih), leftButtonAction(""), middleButtonAction(""),
+ rightButtonAction(""), clickable(true), hidden(0), minValue(0), maxValue(0),
+ color(0,0,0), m_karamba(k)
+{
+}
+
+Meter::Meter(karamba* k):
+ boundingBox(0, 0, 0, 0), leftButtonAction(""), middleButtonAction(""),
+ rightButtonAction(""), clickable(true), hidden(0), minValue(0), maxValue(0),
+ color(0,0,0), m_karamba(k)
+{
+}
+
+Meter::~Meter()
+{
+}
+
+bool Meter::click(QMouseEvent*)
+{
+ return false;
+}
+
+void Meter::setSize(int ix, int iy, int iw, int ih)
+{
+ boundingBox.setRect(ix, iy, iw, ih);
+ recalculateValue();
+}
+
+void Meter::setThemePath( QString path )
+{
+ themePath = path;
+}
+
+int Meter::getX()
+{
+ return boundingBox.x();
+}
+
+int Meter::getY()
+{
+ return boundingBox.y();
+}
+
+void Meter::setX(int newx)
+{
+ int temp = boundingBox.width();
+ boundingBox.setX(newx);
+ boundingBox.setWidth(temp);
+}
+
+void Meter::setY(int newy)
+{
+ int temp = boundingBox.height();
+ boundingBox.setY(newy);
+ boundingBox.setHeight(temp);
+}
+
+int Meter::getWidth()
+{
+ return boundingBox.width();
+}
+int Meter::getHeight()
+{
+ return boundingBox.height();
+}
+
+void Meter::setWidth(int width)
+{
+ boundingBox.setWidth(width);
+ recalculateValue();
+}
+
+void Meter::setHeight(int height)
+{
+ boundingBox.setHeight(height);
+ recalculateValue();
+}
+
+QRect Meter::getBoundingBox()
+{
+ return boundingBox;
+}
+
+void Meter::setEnabled(bool e)
+{
+ clickable = e;
+}
+
+bool Meter::isEnabled()
+{
+ return clickable;
+}
+
+bool Meter::insideActiveArea(int x, int y)
+{
+ return boundingBox.contains(x, y) && clickable;
+}
+
+#include "meter.moc"
diff --git a/superkaramba/src/meter.h b/superkaramba/src/meter.h
new file mode 100644
index 0000000..8d1aeaf
--- /dev/null
+++ b/superkaramba/src/meter.h
@@ -0,0 +1,99 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Hans Karlsson *
+ * karlsson.h@home.se *
+ * *
+ * 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. *
+ ***************************************************************************/
+#ifndef METER_H
+#define METER_H
+
+#include <qpixmap.h>
+#include <qpainter.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qobject.h>
+
+#include <qfileinfo.h>
+
+class karamba;
+
+class Meter : public QObject
+{
+Q_OBJECT
+public:
+
+ Meter(karamba* k, int ix,int iy,int iw,int ih);
+ Meter(karamba* k);
+ virtual ~Meter();
+ virtual int getX();
+ virtual int getY();
+ virtual int getWidth();
+ virtual int getHeight();
+ virtual void setX(int);
+ virtual void setY(int);
+ virtual void setWidth(int);
+ virtual void setHeight(int);
+
+ virtual void setSize(int ix, int iy, int iw, int ih);
+
+ virtual void setMax(long max) { maxValue = max; };
+ virtual void setMin(long min) { minValue = min; };
+ virtual long getMax() { return minValue; };
+ virtual long getMin() { return maxValue; };
+
+ void setThemePath( QString );
+
+ virtual void mUpdate(QPainter *)=0 ;
+
+ virtual void setValue(long) {};
+ virtual long getValue() { return -1; };
+ virtual void setValue(QString) {};
+ virtual QString getStringValue() const { return QString::null; };
+ virtual void recalculateValue() {};
+
+ virtual void setColor(QColor clr) { color = clr; };
+ virtual QColor getColor() { return color; };
+
+ virtual void show() { hidden = 0; };
+ virtual void hide() { hidden = 1; };
+
+ QRect getBoundingBox();
+
+ // true when given coordinate point is inside the meters
+ // active reagion and meter is enabled
+ virtual bool insideActiveArea(int, int);
+
+ // returns true when callback meterClicked should be called.
+ virtual bool click( QMouseEvent* );
+
+ void setEnabled(bool);
+ bool isEnabled();
+
+ /*
+ void setOnClick( QString );
+ void setOnMiddleClick( QString );
+ */
+
+protected: // Protected attributes
+ QString themePath;
+
+ QRect boundingBox;
+
+ // Actions to execute when clicked on meter
+ QString leftButtonAction;
+ QString middleButtonAction;
+ QString rightButtonAction;
+
+ bool clickable;
+ int hidden;
+ long minValue;
+ long maxValue;
+
+ QColor color;
+ karamba* m_karamba;
+};
+
+#endif // METER_H
diff --git a/superkaramba/src/meter_python.cpp b/superkaramba/src/meter_python.cpp
new file mode 100644
index 0000000..029820d
--- /dev/null
+++ b/superkaramba/src/meter_python.cpp
@@ -0,0 +1,373 @@
+/***************************************************************************
+ * Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org> *
+ * Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se> *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifdef _XOPEN_SOURCE
+#undef _XOPEN_SOURCE
+#endif
+
+#include <Python.h>
+#include <qobject.h>
+#include "karamba.h"
+#include "karambaapp.h"
+#include "meter.h"
+#include "meter_python.h"
+#include "lineparser.h"
+
+bool checkKaramba(long widget)
+{
+/*
+ if (!karambaApp)
+ {
+ PyErr_SetString(PyExc_ValueError, "app pointer was 0.");
+ return false;
+ }
+*/
+ if (!widget)
+ {
+ PyErr_SetString(PyExc_ValueError, "widget pointer was 0.");
+ return false;
+ }
+ if (!karambaApp->hasKaramba((karamba*)widget))
+ {
+ QString tmp;
+
+ tmp.sprintf("no %x widget found.", (unsigned int)widget);
+ PyErr_SetString(PyExc_ValueError, tmp.ascii());
+ return false;
+ }
+ return true;
+}
+
+bool checkMeter(long widget, long meter, const char* type)
+{
+ if (!meter)
+ {
+ PyErr_SetString(PyExc_ValueError, "meter pointer was 0.");
+ return false;
+ }
+ if (!((karamba*)widget)->hasMeter((Meter*)meter))
+ {
+ QString tmp;
+
+ tmp.sprintf("widget does not have meter %x.", (unsigned int)meter);
+ PyErr_SetString(PyExc_ValueError, tmp.ascii());
+ return false;
+ }
+ if (!((QObject*)meter)->isA(type))
+ {
+ QString tmp;
+
+ tmp.sprintf("meter is not type of %s.", type);
+ PyErr_SetString(PyExc_TypeError, tmp.ascii());
+ return false;
+ }
+ return true;
+}
+
+bool checkKarambaAndMeter(long widget, long meter, const char* type)
+{
+ return checkKaramba(widget) && checkMeter(widget, meter, type);
+}
+
+// This just throws awya extra bytes.
+// I guess there is a better way to do this...
+QString fromUcs4(Q_UINT32* ucs4)
+{
+ QString result = "";
+ while(*ucs4 != 0)
+ {
+ result += QChar((Q_UINT16)*ucs4);
+ ++ucs4;
+ }
+ return result;
+}
+
+// Converts a Python String to a QString with Unicode support
+QString PyString2QString(PyObject* text)
+{
+ QString qtext;
+ if (PyString_CheckExact(text))
+ {
+ char* t = PyString_AsString(text);
+ qtext.setAscii(t);
+ }
+ else if (PyUnicode_CheckExact(text))
+ {
+ Py_UNICODE* t = PyUnicode_AsUnicode(text);
+ if(sizeof(Py_UNICODE) == 4)
+ qtext = fromUcs4((Q_UINT32*)t);
+ else
+ qtext = QString::fromUcs2((Q_UINT16*)t);
+ }
+ else
+ {
+ // Error raise execption ...
+ }
+ return qtext;
+}
+
+// Converts a QString to a Python String with Unicode support
+PyObject* QString2PyString(QString string)
+{
+ PyObject *pyString;
+
+ const unsigned short* tmp = string.ucs2();
+ bool dofree = false;
+
+ if(tmp)
+ {
+ #if Py_UNICODE_SIZE == 4
+
+ Py_UNICODE* buf = new Py_UNICODE[string.length()];
+
+ for(unsigned int i = 0; i < string.length(); i++)
+ {
+ buf[i] = tmp[i];
+ }
+ dofree = true;
+
+ #else
+
+ Py_UNICODE* buf = (Py_UNICODE*) tmp;
+
+ #endif
+
+ pyString = PyUnicode_FromUnicode(buf, string.length());
+
+ if(dofree)
+ {
+ delete [] buf;
+ }
+ }
+
+ else
+ pyString = PyString_FromString("");
+
+ return pyString;
+}
+
+
+long getMeter(long widget, char* name)
+{
+ karamba* theme = (karamba*)widget;
+ QObjectListIt it( *theme->meterList ); // iterate over meters
+
+ while ( it != 0 )
+ {
+ if (strcmp(((Meter*) *it)->name(), name) == 0)
+ return (long)*it;
+ ++it;
+ }
+ return 0;
+}
+
+PyObject* py_getThemeMeter(PyObject *, PyObject *args, QString type)
+{
+ long widget, meter;
+ char* name;
+ if (!PyArg_ParseTuple(args, (char*)"ls", &widget, &name))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ if(!name)
+ return NULL;
+ meter = getMeter(widget, name);
+ if (!checkMeter(widget, meter, type.ascii()))
+ return NULL;
+ return (Py_BuildValue((char*)"l", meter));
+}
+
+PyObject* py_getSize(PyObject *, PyObject *args, QString type)
+{
+ long widget;
+ long meter;
+ if (!PyArg_ParseTuple(args, (char*)"ll", &widget, &meter))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, type.ascii()))
+ return NULL;
+ return Py_BuildValue((char*)"(i,i)", ((Meter*)meter)->getWidth(),
+ ((Meter*)meter)->getHeight());
+}
+
+PyObject* py_resize(PyObject *, PyObject *args, QString type)
+{
+ long widget, meter, x, y;
+ if (!PyArg_ParseTuple(args, (char*)"llll", &widget, &meter, &x, &y))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, type.ascii()))
+ return NULL;
+ ((Meter*)meter)->setSize(((Meter*)meter)->getX(), ((Meter*)meter)->getY(),
+ x, y);
+ return Py_BuildValue((char*)"l", 1);
+}
+
+PyObject* py_getPos(PyObject *, PyObject *args, QString type)
+{
+ long widget, meter;
+ if (!PyArg_ParseTuple(args, (char*)"ll", &widget, &meter))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, type.ascii()))
+ return NULL;
+ return Py_BuildValue((char*)"(i,i)", ((Meter*)meter)->getX(),
+ ((Meter*)meter)->getY());
+}
+
+PyObject* py_move(PyObject *, PyObject *args, QString type)
+{
+ long widget, meter, x, y;
+ if (!PyArg_ParseTuple(args, (char*)"llll", &widget, &meter, &x, &y))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, type.ascii()))
+ return NULL;
+ ((Meter*)meter)->setSize(x, y,
+ ((Meter*)meter)->getWidth(),
+ ((Meter*)meter)->getHeight());
+ return Py_BuildValue((char*)"l", 1);
+}
+
+PyObject* py_hide(PyObject *, PyObject *args, QString type)
+{
+ long widget, meter;
+ if (!PyArg_ParseTuple(args, (char*)"ll", &widget, &meter))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, type.ascii()))
+ return NULL;
+ ((Meter*)meter)->hide();
+ return Py_BuildValue((char*)"l", 1);
+}
+
+PyObject* py_show(PyObject *, PyObject *args, QString type)
+{
+ long widget, meter;
+ if (!PyArg_ParseTuple(args, (char*)"ll", &widget, &meter))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, type.ascii()))
+ return NULL;
+ ((Meter*)meter)->show();
+ return Py_BuildValue((char*)"l", 1);
+}
+
+PyObject* py_getValue(PyObject *, PyObject *args, QString type)
+{
+ long widget, meter;
+ if (!PyArg_ParseTuple(args, (char*)"ll", &widget, &meter))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, type.ascii()))
+ return NULL;
+ return Py_BuildValue((char*)"l", ((Meter*)meter)->getValue());
+}
+
+PyObject* py_setValue(PyObject *, PyObject *args, QString type)
+{
+ long widget, meter, l;
+ if (!PyArg_ParseTuple(args, (char*)"lll", &widget, &meter, &l))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, type.ascii()))
+ return NULL;
+ ((Meter*)meter)->setValue(l);
+ return Py_BuildValue((char*)"l", ((long)meter));
+}
+
+PyObject* py_getStringValue(PyObject *, PyObject *args, QString type)
+{
+ long widget, meter;
+ if (!PyArg_ParseTuple(args, (char*)"ll", &widget, &meter))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, type.ascii()))
+ return NULL;
+ return Py_BuildValue((char*)"O",
+ QString2PyString(((Meter*)meter)->getStringValue()));
+}
+
+PyObject* py_setStringValue(PyObject *, PyObject *args, QString type)
+{
+ long widget, meter;
+ PyObject* s;
+ if (!PyArg_ParseTuple(args, (char*)"llO", &widget, &meter, &s))
+ return NULL;
+ if (!s)
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, type.ascii()))
+ return NULL;
+ ((Meter*)meter)->setValue(PyString2QString(s));
+ return Py_BuildValue((char*)"l", ((long)meter));
+}
+
+PyObject* py_getMinMax(PyObject *, PyObject *args, QString type)
+{
+ long widget, meter;
+ if (!PyArg_ParseTuple(args, (char*)"ll", &widget, &meter))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, type.ascii()))
+ return NULL;
+ return Py_BuildValue((char*)"(i,i)", ((Meter*)meter)->getMin(),
+ ((Meter*)meter)->getMax());
+}
+
+PyObject* py_setMinMax(PyObject *, PyObject *args, QString type)
+{
+ long widget, meter, x, y;
+ if (!PyArg_ParseTuple(args, (char*)"llll", &widget, &meter, &x, &y))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, type.ascii()))
+ return NULL;
+ ((Meter*)meter)->setMin(x);
+ ((Meter*)meter)->setMax(y);
+ return Py_BuildValue((char*)"l", 1);
+}
+
+PyObject* py_getSensor(PyObject *, PyObject *args, QString type)
+{
+ long widget, meter;
+ QString s;
+ if (!PyArg_ParseTuple(args, (char*)"ll", &widget, &meter))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, type.ascii()))
+ return NULL;
+ return Py_BuildValue((char*)"s",
+ ((karamba*)widget)->getSensor((Meter*)meter).ascii());
+}
+
+PyObject* py_setSensor(PyObject *, PyObject *args, QString type)
+{
+ long widget, meter;
+ char* s;
+
+ if (!PyArg_ParseTuple(args, (char*)"lls", &widget, &meter, &s))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, type.ascii()))
+ return NULL;
+ ((karamba*)widget)->setSensor(LineParser(s), (Meter*)meter);
+ return Py_BuildValue((char*)"l", 1);
+}
+
+PyObject* py_setColor(PyObject *, PyObject *args, QString type)
+{
+ long widget, meter;
+ long r, g, b;
+ if (!PyArg_ParseTuple(args, (char*)"lllll", &widget, &meter, &r, &g, &b))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, type.ascii()))
+ return NULL;
+ ((Meter*)meter)->setColor(QColor(r, g, b));
+ return Py_BuildValue((char*)"l", 1);
+}
+
+PyObject* py_getColor(PyObject *, PyObject *args, QString type)
+{
+ long widget, meter;
+ if (!PyArg_ParseTuple(args, (char*)"ll", &widget, &meter))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, type.ascii()))
+ return NULL;
+ QColor color = ((Meter*)meter)->getColor();
+ return Py_BuildValue((char*)"(i,i,i)", color.red(), color.green(), color.blue());
+}
+
diff --git a/superkaramba/src/meter_python.h b/superkaramba/src/meter_python.h
new file mode 100644
index 0000000..f064977
--- /dev/null
+++ b/superkaramba/src/meter_python.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ * Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org> *
+ * Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se> *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef METER_PYTHON_H
+#define METER_PYTHON_H
+
+// Python uses char* where it should use const char*
+#define PY_PARSE(a, b, c, d) (PyArg_ParseTuple(a, (char*)b, c, d))
+#define PY_BUILD(a, b) (Py_BuildValue((char*)a, b))
+
+bool checkKaramba(long widget);
+bool checkMeter(long widget, long meter, const char* type);
+bool checkKarambaAndMeter(long widget, long meter, const char* type);
+
+QString PyString2QString(PyObject* text);
+PyObject* QString2PyString(QString string);
+
+PyObject* py_getThemeMeter(PyObject *self, PyObject *args, QString type);
+PyObject* py_getSize(PyObject *self, PyObject *args, QString type);
+PyObject* py_resize(PyObject *self, PyObject *args, QString type);
+PyObject* py_getPos(PyObject *self, PyObject *args, QString type);
+PyObject* py_move(PyObject *self, PyObject *args, QString type);
+PyObject* py_hide(PyObject *self, PyObject *args, QString type);
+PyObject* py_show(PyObject *self, PyObject *args, QString type);
+PyObject* py_getValue(PyObject *self, PyObject *args, QString type);
+PyObject* py_setValue(PyObject *self, PyObject *args, QString type);
+PyObject* py_getStringValue(PyObject *self, PyObject *args, QString type);
+PyObject* py_setStringValue(PyObject *self, PyObject *args, QString type);
+PyObject* py_getMinMax(PyObject *self, PyObject *args, QString type);
+PyObject* py_setMinMax(PyObject *self, PyObject *args, QString type);
+PyObject* py_getSensor(PyObject *self, PyObject *args, QString type);
+PyObject* py_setSensor(PyObject *self, PyObject *args, QString type);
+PyObject* py_getColor(PyObject *self, PyObject *args, QString type);
+PyObject* py_setColor(PyObject *self, PyObject *args, QString type);
+
+#endif // METER_PYTHON_H
+
diff --git a/superkaramba/src/misc_python.cpp b/superkaramba/src/misc_python.cpp
new file mode 100644
index 0000000..ba67573
--- /dev/null
+++ b/superkaramba/src/misc_python.cpp
@@ -0,0 +1,852 @@
+/****************************************************************************
+* misc_python.cpp - Misc Functions for python api
+*
+* Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+* Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+* Copyright (C) 2004 Petri Damst� <damu@iki.fi>
+* Copyright (C) 2004, 2005 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
+*
+* This file is part of SuperKaramba.
+*
+* SuperKaramba 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.
+*
+* SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+#ifdef _XOPEN_SOURCE
+#undef _XOPEN_SOURCE
+#endif
+
+#include <Python.h>
+#include <qglobal.h>
+#include <qobject.h>
+
+#include <kglobal.h>
+#include <klocale.h>
+
+#include "kdebug.h"
+#include "karamba.h"
+#include "karambaapp.h"
+#include "themefile.h"
+#include "themelocale.h"
+#include "meter.h"
+#include "meter_python.h"
+#include "misc_python.h"
+
+/* now a method we need to expose to Python */
+long acceptDrops(long widget)
+{
+ karamba* currTheme = (karamba*)widget;
+
+ currTheme->setAcceptDrops(true);
+
+ return 1;
+}
+
+PyObject* py_accept_drops(PyObject *, PyObject *args)
+{
+ long widget;
+
+ if (!PyArg_ParseTuple(args, (char*)"l", &widget))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ return Py_BuildValue((char*)"l", acceptDrops(widget));
+}
+
+// Runs a command, returns 0 if it could not start command
+PyObject* py_run_command(PyObject*, PyObject* args)
+{
+ char* name;
+ char* command;
+ char* icon;
+ PyObject *lst;
+ if (!PyArg_ParseTuple(args, (char*)"sssO:run", &name, &command, &icon, &lst) ||
+ lst == NULL || !PyList_Check(lst))
+ return NULL;
+
+ QString n;
+ QString c;
+ QString i;
+
+ n.setAscii(name);
+ c.setAscii(command);
+ i.setAscii(icon);
+
+ KService svc(n, c, i);
+ KURL::List l;
+
+ for (int i = 0; i < PyList_Size(lst); i++)
+ {
+ l.append(PyString2QString(PyList_GetItem(lst, i)));
+ }
+ KRun::run(svc, l);
+ return Py_BuildValue("l", 1);
+}
+
+// Runs a command, returns 0 if it could not start command
+PyObject* py_execute_command(PyObject *, PyObject* args)
+{
+ PyObject* s;
+
+ if (!PyArg_ParseTuple(args, (char*)"O:execute", &s))
+ return NULL;
+ return Py_BuildValue((char*)"l", KRun::runCommand(PyString2QString(s)));
+}
+
+// Runs a command, returns 0 if it could not start command
+PyObject* py_execute_command_interactive(PyObject *, PyObject* args)
+{
+ long widget;
+ //if (!PyArg_ParseTuple(args, (char*)"ls", &widget, &command))
+ // return NULL;
+
+ int numLines; /* how many lines we passed for parsing */
+ QString line; /* pointer to the line as a string */
+
+ PyObject * listObj; /* the list of strings */
+ PyObject * strObj; /* one string in the list */
+
+ /* the O! parses for a Python object (listObj) checked
+ to be of type PyList_Type */
+ if (! PyArg_ParseTuple(args, (char*)"lO!", &widget, &PyList_Type, &listObj))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+
+ karamba* currTheme = (karamba*)widget;
+
+ currTheme->currProcess = new KProcess;
+
+ /* get the number of lines passed to us */
+ numLines = PyList_Size(listObj);
+
+ /* should raise an error here. */
+ if (numLines < 0) return NULL; /* Not a list */
+
+ /* iterate over items of the list, grabbing strings, and parsing
+ for numbers */
+ for (int i=0; i<numLines; i++){
+
+ /* grab the string object from the next element of the list */
+ strObj = PyList_GetItem(listObj, i); /* Can't fail */
+
+ /* make it a string */
+ line = PyString2QString(strObj);
+
+ /* now do the parsing */
+ *(currTheme->currProcess) << line;
+
+ }
+ QApplication::connect(currTheme->currProcess,
+ SIGNAL(processExited(KProcess *)),
+ currTheme,
+ SLOT(processExited(KProcess *)));
+ QApplication::connect(currTheme->currProcess,
+ SIGNAL(receivedStdout(KProcess *, char *, int)),
+ currTheme,
+ SLOT(receivedStdout(KProcess *, char *, int)));
+ currTheme->currProcess->start(KProcess::NotifyOnExit, KProcess::Stdout);
+
+ return Py_BuildValue((char*)"l", (int)(currTheme->currProcess->pid()));
+}
+
+long attachClickArea(long widget, long meter, QString LeftButton, QString MiddleButton, QString RightButton)
+{
+ karamba* currTheme = (karamba*) widget;
+ Meter* currMeter = (Meter*) meter;
+
+ // Look if currMeter has an ClickArea attached.
+ bool meterAlreadyClickable = currTheme->clickList->containsRef(currMeter);
+
+ // if currMeter is of type ImageLabel*
+ if (ImageLabel* image = dynamic_cast<ImageLabel*>(currMeter))
+ {
+ image -> attachClickArea(LeftButton, MiddleButton, RightButton);
+ if (!meterAlreadyClickable)
+ {
+ //qWarning("attachClickArea : meter is image");
+ currTheme -> clickList -> append(image);
+ }
+ }
+ // else if currMeter is of type TextLabel*
+ else if (TextLabel* text = dynamic_cast<TextLabel*>(currMeter))
+ {
+ text -> attachClickArea(LeftButton, MiddleButton, RightButton);
+ if (!meterAlreadyClickable)
+ {
+ //qWarning("attachClickArea : meter is text");
+ currTheme -> clickList -> append(text);
+ }
+ }
+ else
+ {
+ //The given meter does not support attached clickAreas.
+ qWarning("The given meter is not of type image or text");
+ return 0;
+ }
+ return 1;
+}
+
+PyObject* py_attach_clickArea(PyObject*, PyObject* args, PyObject* dict)
+{
+ long widget;
+ long meter;
+ char* LeftButton = NULL;
+ char* MiddleButton = NULL;
+ char* RightButton = NULL;
+ const char* mouseButtons[] = {"Widget", "Meter", "LeftButton", "MiddleButton",
+ "RightButton", NULL};
+ if (!PyArg_ParseTupleAndKeywords(args, dict, (char*)"ll|sss:attachClickArea",
+ (char**)mouseButtons, &widget, &meter, &LeftButton, &MiddleButton, &RightButton))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ QString lB, mB, rB;
+ if (LeftButton != NULL)
+ {
+ lB.setAscii(LeftButton);
+ }
+ else
+ {
+ lB.setAscii("");
+ }
+ if (MiddleButton != NULL)
+ {
+ mB.setAscii(MiddleButton);
+ }
+ else
+ {
+ mB.setAscii("");
+ }
+ if (RightButton != NULL)
+ {
+ rB.setAscii(RightButton);
+ }
+ else
+ {
+ rB.setAscii("");
+ }
+ return Py_BuildValue((char*)"l", attachClickArea(widget, meter, lB, mB, rB));
+}
+
+/* now a method we need to expose to Python */
+long toggleShowDesktop(long)
+{
+ ShowDesktop *s = ShowDesktop::the();
+ s->toggle();
+ return 1;
+}
+
+PyObject* py_toggle_show_desktop(PyObject *, PyObject *args)
+{
+ long widget;
+ if (!PyArg_ParseTuple(args, (char*)"l:toggleShowDesktop", &widget))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ return Py_BuildValue((char*)"l", toggleShowDesktop(widget));
+}
+
+/* now a method we need to expose to Python */
+const char* getPrettyName(long widget) {
+ karamba* currTheme = (karamba*)widget;
+
+ return currTheme->prettyName.ascii();
+}
+
+PyObject* py_get_pretty_name(PyObject *, PyObject *args)
+{
+ long widget;
+ if (!PyArg_ParseTuple(args, (char*)"l:getPrettyThemeName", &widget))
+ return NULL;
+ return Py_BuildValue((char*)"s", getPrettyName(widget));
+}
+
+/* now a method we need to expose to Python */
+const char* getThemePath(long widget) {
+ karamba* currTheme = (karamba*)widget;
+
+ return currTheme->theme().path().ascii();
+}
+
+PyObject* py_get_theme_path(PyObject *, PyObject *args)
+{
+ long widget;
+ if (!PyArg_ParseTuple(args, (char*)"l:getThemePath", &widget))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ return Py_BuildValue((char*)"s", getThemePath(widget));
+}
+
+PyObject* py_language(PyObject *, PyObject *args)
+{
+ long widget;
+ if (!PyArg_ParseTuple(args, (char*)"l:language", &widget))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ return Py_BuildValue((char*)"s",
+ ((karamba*)widget)->theme().locale()->language().ascii());
+}
+
+PyObject* py_userLanguage(PyObject *, PyObject *args)
+{
+ long widget;
+ if (!PyArg_ParseTuple(args, (char*)"l:language", &widget))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ return Py_BuildValue((char*)"s", KGlobal::locale()->language().ascii());
+}
+
+PyObject* py_userLanguages(PyObject *, PyObject *args)
+{
+ long widget;
+ if (!PyArg_ParseTuple(args, (char*)"l:language", &widget))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+
+ unsigned int noOfLangs = KGlobal::locale()->languageList().count();
+
+ PyObject *list, *item;
+ list = PyList_New(noOfLangs);
+
+ for(unsigned int i = 0; i < noOfLangs; i++)
+ {
+ item = Py_BuildValue((char*)"s", KGlobal::locale()->languageList()[i].ascii());
+ PyList_SetItem(list, i, item);
+ }
+
+ return list;
+}
+
+PyObject* py_read_theme_file(PyObject *, PyObject *args)
+{
+ long widget;
+ char *file;
+ if (!PyArg_ParseTuple(args, (char*)"ls:readThemeFile", &widget, &file))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ karamba* k = (karamba*)widget;
+ QByteArray ba = k->theme().readThemeFile(file);
+ return PyString_FromStringAndSize(ba.data(), ba.size());
+}
+
+/* now a method we need to expose to Python */
+long removeClickArea(long widget, long click) {
+
+ karamba* currTheme = (karamba*)widget;
+ ClickArea *tmp = (ClickArea*)click;
+
+ currTheme -> clickList -> remove(tmp);
+
+ delete tmp;
+ return (long)tmp;
+}
+
+/* now a method we need to expose to Python */
+long createServiceClickArea(long widget, long x, long y, long w, long h, char *name, char* exec, char *icon) {
+
+ karamba* currTheme = (karamba*)widget;
+ ClickArea *tmp = new ClickArea( currTheme, x, y, w, h );
+ QString n;
+ QString e;
+ QString i;
+
+ n.setAscii(name);
+ e.setAscii(exec);
+ i.setAscii(icon);
+
+ tmp->setServiceOnClick(n, e, i);
+
+ currTheme -> clickList -> append(tmp);
+ return (long)tmp;
+}
+
+long createClickArea(long widget, long x, long y, long w, long h, char* text) {
+
+ karamba* currTheme = (karamba*)widget;
+ ClickArea *tmp = new ClickArea(currTheme, x, y, w, h );
+ QString onclick;
+
+ onclick.setAscii(text);
+
+ tmp->setOnClick(onclick );
+
+ currTheme -> clickList -> append(tmp);
+ return (long)tmp;
+}
+
+PyObject* py_remove_click_area(PyObject *, PyObject *args)
+{
+ long widget, click;
+ if (!PyArg_ParseTuple(args, (char*)"ll:removeClickArea", &widget, &click))
+ return NULL;
+ return Py_BuildValue((char*)"l", removeClickArea(widget, click));
+}
+
+PyObject* py_create_service_click_area(PyObject *, PyObject *args)
+{
+ long widget, x, y, w, h;
+ char *name;
+ char *exec;
+ char *icon;
+ if (!PyArg_ParseTuple(args, (char*)"lllllsss:createServiceClickArea", &widget, &x, &y,
+ &w, &h, &name, &exec, &icon))
+ return NULL;
+ return Py_BuildValue((char*)"l", createServiceClickArea(widget, x, y, w, h, name, exec, icon));
+}
+
+PyObject* py_create_click_area(PyObject *, PyObject *args)
+{
+ long widget, x, y, w, h;
+ char *text;
+ if (!PyArg_ParseTuple(args, (char*)"llllls:createClickArea", &widget, &x, &y,
+ &w, &h, &text))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ return Py_BuildValue((char*)"l", createClickArea(widget, x, y, w, h, text));
+}
+
+static long callTheme(long widget, char* path, char *str)
+{
+ karamba* currTheme = (karamba*) widget;
+
+ if (currTheme)
+ currTheme->callTheme(QString(path), QString(str));
+
+ return (long)currTheme;
+}
+
+static long setIncomingData(long widget, char* path, char *obj)
+{
+ karamba* currTheme = (karamba*) widget;
+
+ if (currTheme)
+ currTheme->setIncomingData(QString(path), QString(obj));
+
+ return (long)currTheme;
+}
+
+static QString getIncomingData(long widget)
+{
+ karamba* currTheme = (karamba*) widget;
+
+ if (currTheme)
+ return currTheme->getIncomingData();
+
+ return QString("");
+}
+
+/*
+ * openNamedTheme. this function checks to see whether the theme
+ * being opened is unique or not (against all running karamba widgets).
+ * this is important, as loading themes with the same name causes
+ * grief.
+ */
+long openNamedTheme(char* path, char *name, bool is_sub_theme) {
+
+ QString filename;
+ karamba* currTheme = 0;
+
+ filename.setAscii(path);
+
+ QFileInfo file( filename );
+
+ if( file.exists() )
+ {
+ QCString prettyName(name);
+ KarambaApplication* app = (KarambaApplication*)qApp;
+ if (!app->themeExists(prettyName))
+ {
+ currTheme = new karamba( filename, prettyName, false ,
+ -1, is_sub_theme);
+ currTheme->show();
+ }
+ }
+ return (long)currTheme;
+}
+
+/* now a method we need to expose to Python */
+long openTheme(char* path)
+{
+
+ QString filename;
+ karamba* currTheme = 0;
+
+ filename.setAscii(path);
+
+ QFileInfo file( filename );
+
+ if( file.exists() )
+ {
+ currTheme = new karamba( filename, QString() );
+ currTheme->show();
+ }
+
+ return (long)currTheme;
+}
+
+PyObject* py_get_incoming_data(PyObject *, PyObject *args)
+{
+ long widget;
+ if (!PyArg_ParseTuple(args, (char*)"l:getIncomingData", &widget))
+ return NULL;
+ return Py_BuildValue((char*)"O", QString2PyString(getIncomingData(widget)));
+}
+
+PyObject* py_set_incoming_data(PyObject *, PyObject *args)
+{
+ char *themePath;
+ long widget;
+ char *obj;
+ if (!PyArg_ParseTuple(args, (char*)"lss:setIncomingData", &widget, &themePath, &obj))
+ return NULL;
+ return Py_BuildValue((char*)"l", setIncomingData(widget, themePath, obj));
+}
+
+PyObject* py_call_theme(PyObject *, PyObject *args)
+{
+ char *themePath;
+ char *str;
+ long widget;
+ if (!PyArg_ParseTuple(args, (char*)"lss:callTheme", &widget, &themePath, &str))
+ return NULL;
+ return Py_BuildValue((char*)"l", callTheme(widget, themePath, str));
+}
+
+PyObject* py_open_named_theme(PyObject *, PyObject *args)
+{
+ char *themePath;
+ char *themeName;
+ long is_sub_theme;
+ if (!PyArg_ParseTuple(args, (char*)"ssl:openNamedTheme", &themePath, &themeName, &is_sub_theme))
+ return NULL;
+ return Py_BuildValue((char*)"l", openNamedTheme(themePath, themeName, is_sub_theme ? true : false));
+}
+
+PyObject* py_open_theme(PyObject *, PyObject *args)
+{
+ char *themePath;
+ if (!PyArg_ParseTuple(args, (char*)"s:openTheme", &themePath))
+ return NULL;
+ return Py_BuildValue((char*)"l", openTheme(themePath));
+}
+
+PyObject* py_reload_theme(PyObject *, PyObject *args)
+{
+ long widget;
+ if (!PyArg_ParseTuple(args, (char*)"l:reloadTheme", &widget))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ ((karamba*)widget)->reloadConfig();
+ return Py_BuildValue((char*)"l", 1);
+}
+
+/* now a method we need to expose to Python */
+int getNumberOfDesktops(long widget)
+{
+ karamba* currTheme = (karamba*)widget;
+
+ return currTheme->kWinModule->numberOfDesktops();
+}
+
+PyObject* py_get_number_of_desktops(PyObject *, PyObject *args)
+{
+ long widget;
+ if (!PyArg_ParseTuple(args, (char*)"l:getNumberOfDesktops", &widget))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ return Py_BuildValue((char*)"l", getNumberOfDesktops(widget));
+}
+
+/* now a method we need to expose to Python */
+int translateAll(long widget, int x, int y)
+{
+ karamba* currTheme = (karamba*)widget;
+
+ QObjectListIt it2( *currTheme->meterList ); // iterate over meters
+
+ while ( it2 != 0 )
+ {
+ ((Meter*) *it2)->setSize(((Meter*) *it2)->getX()+x,
+ ((Meter*) *it2)->getY()+y,
+ ((Meter*) *it2)->getWidth(),
+ ((Meter*) *it2)->getHeight());
+ ++it2;
+ }
+
+ if (currTheme->systray != 0)
+ {
+ currTheme->systray->move(currTheme->systray->x()+x,
+ currTheme->systray->y()+y);
+ }
+ return 0;
+}
+
+PyObject* py_translate_all(PyObject *, PyObject *args)
+{
+ long widget;
+ int x, y;
+ if (!PyArg_ParseTuple(args, (char*)"lii:translateAll", &widget, &x, &y))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ return Py_BuildValue((char*)"lii", translateAll(widget, x, y));
+}
+
+/* now a method we need to expose to Python */
+int show(long widget)
+{
+ karamba* currTheme = (karamba*)widget;
+ currTheme->show();
+ return 0;
+}
+
+PyObject* py_show(PyObject *, PyObject *args)
+{
+ long widget;
+ if (!PyArg_ParseTuple(args, (char*)"l:show", &widget))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ return Py_BuildValue((char*)"l", show(widget));
+}
+
+/* now a method we need to expose to Python */
+int hide(long widget)
+{
+ karamba* currTheme = (karamba*)widget;
+ currTheme->hide();
+ return 0;
+}
+
+PyObject* py_hide(PyObject *, PyObject *args)
+{
+ long widget;
+ if (!PyArg_ParseTuple(args, (char*)"l:hide", &widget))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ return Py_BuildValue((char*)"l", hide(widget));
+}
+
+/*Putting includes here to show the dependency for the call(s) below (if we ever decide to move the networking callbacks into a separate file*/
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <arpa/inet.h>
+#if defined(__FreeBSD__) || defined(__DragonFly__)
+#include <netinet/in.h>
+#endif
+#if defined(Q_OS_SOLARIS)
+#include <sys/sockio.h>
+#endif
+/* now a method we need to expose to Python */
+QString getIp(char *device_name)
+{
+ int i, sd, numdevs;
+ struct ifconf ifc_conf;
+ char ifc_conf_buf[sizeof ( struct ifreq ) * 32];
+ struct ifreq *devptr;
+ int ifc_conf_buf_size;
+ static struct in_addr host;
+ QString retval;
+
+ retval = "Disconnected";
+
+ /*
+ * Open a socket, any type will do so we choose UDP, and ask it with
+ * an ioctl call what devices are behind it.
+ */
+ if ((sd = socket(AF_INET,SOCK_DGRAM,0)) < 0)
+ {
+ qWarning("Error: Unable to create socket (socket)");
+ return "Error";
+ }
+
+ /*
+ * Fill the buffer with our static buffer, probably big enough, and get
+ * the interface configuration.
+ */
+ ifc_conf_buf_size = sizeof ifc_conf_buf;
+ ifc_conf.ifc_len = ifc_conf_buf_size;
+ ifc_conf.ifc_buf = ifc_conf_buf;
+ if (ioctl(sd,SIOCGIFCONF,&ifc_conf) < 0)
+ {
+ qWarning("Error: Unable to get network interface conf (ioctl)");
+ close(sd);
+ return "Error";
+ }
+
+ /*
+ * An array of devices were returned. Which ones are up right now and
+ * have broadcast capability?
+ */
+ numdevs = ifc_conf.ifc_len / sizeof (struct ifreq);
+ //qDebug("numdevs = %d", numdevs);
+ for (i = 0; i < numdevs; i++)
+ {
+ //qDebug("iterations: %d", i);
+ /* devptr points into an array of ifreq structs. */
+ devptr = &ifc_conf.ifc_req[i];
+
+ if (ioctl(sd, SIOCGIFADDR, devptr) < 0 || devptr->ifr_addr.sa_family != AF_INET)
+ continue;
+
+ if (ioctl(sd,SIOCGIFFLAGS,devptr) < 0)
+ {
+ qWarning("Error: Unable to get device interface flags (ioctl).");
+ close(sd);
+ return "Error";
+ }
+
+ //We generally don't want probing of the loopback devices
+ if ((devptr->ifr_flags & IFF_LOOPBACK) != 0)
+ continue;
+
+ if ((devptr->ifr_flags & IFF_UP) == 0)
+ continue;
+
+ if ((devptr->ifr_flags & IFF_BROADCAST) == 0)
+ continue;
+
+ /* Get the broadcast address. */
+ if (ioctl(sd,SIOCGIFFLAGS,devptr) < 0)
+ {
+ qWarning("Error: Unable to get device interface flags (ioctl).");
+ close(sd);
+ return "Error";
+ }
+ else
+ {
+ if (!strcmp((char*)devptr->ifr_name, device_name))
+ {
+ host.s_addr = ((struct sockaddr_in*)&devptr->ifr_addr)->sin_addr.s_addr;
+ retval = inet_ntoa(host);
+ break;
+ }
+ }
+ }
+ close(sd);
+ return retval;
+}
+
+PyObject* py_set_update_time(PyObject *, PyObject *args)
+{
+ long widget;
+ double time;
+ if (!PyArg_ParseTuple(args, (char*)"ld:setUpdateTime", &widget, &time))
+ return NULL;
+ karamba* currTheme = (karamba*)widget;
+ currTheme->setUpdateTime(time);
+ return Py_BuildValue((char*)"l", 1);
+}
+
+PyObject* py_get_update_time(PyObject *, PyObject *args)
+{
+ long widget;
+ double time;
+ if (!PyArg_ParseTuple(args, (char*)"l:getUpdateTime", &widget, &time))
+ return NULL;
+ karamba* currTheme = (karamba*)widget;
+ return Py_BuildValue((char*)"d", currTheme->getUpdateTime());
+}
+
+PyObject* py_get_ip(PyObject *, PyObject *args)
+{
+ long widget;
+ char *interface;
+ if (!PyArg_ParseTuple(args, (char*)"ls:getIp", &widget, &interface))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ return Py_BuildValue((char*)"O", QString2PyString(getIp(interface)));
+}
+
+static void management_popup(long widget)
+{
+ karamba* currTheme = (karamba*)widget;
+ currTheme->management_popup();
+}
+
+PyObject* py_management_popup(PyObject *, PyObject *args)
+{
+ long widget;
+ if (!PyArg_ParseTuple(args, (char*)"l:managementPopup", &widget))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ management_popup(widget);
+ return Py_BuildValue((char*)"l", 1);
+}
+
+static void set_want_right_button(long widget, long yesno)
+{
+ karamba* currTheme = (karamba*)widget;
+ currTheme->setWantRightButton(yesno);
+}
+
+PyObject* py_want_right_button(PyObject *, PyObject *args)
+{
+ long widget, i;
+ if (!PyArg_ParseTuple(args, (char*)"ll:setWantRightButton", &widget, &i))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ set_want_right_button(widget, i);
+ return Py_BuildValue((char*)"l", 1);
+}
+
+static void set_want_wheel_event(long widget, long yesno)
+{
+ karamba* currTheme = (karamba*)widget;
+ currTheme->setWantMeterWheelEvent(yesno);
+}
+
+PyObject* py_want_wheel_event(PyObject *, PyObject *args)
+{
+ long widget, i;
+ if (!PyArg_ParseTuple(args, (char*)"ll:setWantMeterWheelEvent", &widget, &i))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ set_want_wheel_event(widget, i);
+ return Py_BuildValue((char*)"l", 1);
+}
+
+static void changeInterval(long widget, long interval)
+{
+ karamba* currTheme = (karamba*)widget;
+ currTheme->changeInterval(interval);
+}
+
+PyObject* py_change_interval(PyObject *, PyObject *args)
+{
+ long widget, i;
+ if (!PyArg_ParseTuple(args, (char*)"ll:changeInterval", &widget, &i))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ changeInterval(widget, i);
+ return Py_BuildValue((char*)"l", 1);
+}
+
+
diff --git a/superkaramba/src/misc_python.h b/superkaramba/src/misc_python.h
new file mode 100644
index 0000000..46c0988
--- /dev/null
+++ b/superkaramba/src/misc_python.h
@@ -0,0 +1,606 @@
+/*
+* misc_python.h - Misc Functions for python api
+*
+* Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+* Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+* Copyright (C) 2004 Petri Damst� <damu@iki.fi>
+* Copyright (C) 2004,2005 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
+*
+* This file is part of SuperKaramba.
+*
+* SuperKaramba 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.
+*
+* SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+#ifndef MISC_PYTHON_H
+#define MISC_PYTHON_H
+
+/** @file
+*
+* These are global functions that are used to interpret
+* certain Python calls.
+*/
+
+/** Misc/acceptDrops
+*
+* SYNOPSIS
+* long acceptDrops(widget)
+* DESCRIPTION
+* Calling this enables your widget to receive Drop events. In other words,
+* the user will be able to drag icons from her desktop and drop them on
+* your widget. The "itemDropped" callback is called as a result with the
+* data about the icon that was dropped on your widget. This allows, for
+* example, icon bars where items are added to the icon bar by Drag and
+* Drop.
+* ARGUMENTS
+* * long widget -- karamba
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_accept_drops(PyObject *self, PyObject *args);
+
+/** Misc/execute
+*
+* SYNOPSIS
+* long execute(command)
+* DESCRIPTION
+* This command simply executes a program or command on the system. This is
+* just for convience (IE you could accomplish this directly through python,
+* but sometimes threading problems crop up that way). The only option is a
+* string containing the command to execute.
+* ARGUMENTS
+* * string command -- command to execute
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_execute_command(PyObject* self, PyObject* args);
+
+/** Misc/executeInteractive
+*
+* SYNOPSIS
+* long executeInteractive(widget, command)
+* DESCRIPTION
+* This command executes a program or command on the system. But it allows
+* you to get any text that the program outputs. Futhermore, it won't freeze
+* up your widget while the command executes.
+*
+* To use it, call executeInteractive with the reference to your widget and
+* an array of command options. The array is simply a list that contains the
+* command as the first entry, and each option as a seperate list entry.
+* Make sure to catch the returning value from executeInteractive(); it will
+* be the identifier (process number) for the command.
+*
+* Output from the command triggers commandOutput callback. Among other items
+* commandOutput gives the process number of the command that gave the output.
+* This allows you to identify the output when running more than one command
+* at a time.
+*
+* Example:
+* To run the command "ls -la *.zip"
+*
+* myCommand = ["ls", "-la", "*.zip"]
+* procID = karamba.executeInteractive(widget, myCommand)
+*
+* To catch the output, screen commandOutput output for procID.
+*
+* ARGUMENTS
+* * long widget -- karamba
+* * list command -- command to execute
+* RETURN VALUE
+* identification number of the executed command process
+*/
+PyObject* py_execute_command_interactive(PyObject* self, PyObject* args);
+
+/** Misc/run
+*
+* SYNOPSIS
+* long run(name, command, icon, list_of_args)
+* DESCRIPTION
+* This command simply executes a program or command on the system.
+* The difference between run and execute is that run takes arguments,
+* and the name of the icon to be displayed.
+* ARGUMENTS
+* * string name -- name to be displayed
+* * string command -- command to execute
+* * string icon -- name of icon to be displayed
+* * string list_of_args -- arguments to be passed to the command
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_run_command(PyObject* self, PyObject* args);
+
+/** Misc/attachClickArea
+*
+* SYNOPSIS
+* long attachClickArea(widget, meter, lB, mB, rB)
+* DESCRIPTION
+* It is possible to attach a clickarea to a meter (image or text field),
+* which is moved and resized correctly if the meter is moved or resized.
+*
+* There is also a callback meterClicked(widget, meter, button) which is
+* called whenever a meter is clicked (if something is attached to it).
+* Given an Image or a TextLabel, this call makes it clickable. When a mouse
+* click is detected, the callback meterClicked is called.
+*
+* lB, mB, and rB are strings that specify what command is executed when
+* this meter is clicked with the left mouse button, middle mouse button,
+* and right mouse button respectively. If given, the appropriate command is
+* executed when the mouse click is received.
+*
+* The keyword arguments are all optional. If command is an empty string
+* nothing is executed.
+*
+* For now the command given to RightButton has obviosly no effect (because
+* that brings up the SuperKaramba menu).
+*
+* ARGUMENTS
+* * long widget -- karamba
+* * long meter -- pointer to meter
+* * string lB -- command to left mouse button
+* * string mB -- command to middle mouse button
+* * string rB -- command to right mouse button
+*
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_attach_clickArea(PyObject* self, PyObject* args, PyObject* dict);
+
+/** Misc/toggleShowDesktop
+*
+* SYNOPSIS
+* long toggleShowDesktop(widget)
+* DESCRIPTION
+* This shows/hides the current desktop just like the Show Desktop button on
+* kicker. Basically, it minimizes all the windows on the current desktop.
+* Call it once to show the desktop and again to hide it.
+* ARGUMENTS
+* * long widget -- karamba
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_toggle_show_desktop(PyObject *self, PyObject *args);
+
+/** Misc/getThemePath
+*
+* SYNOPSIS
+* string getThemePath(widget)
+* DESCRIPTION
+* Returns a string containing the directory where your theme was loaded
+* from. If you are running the theme from (compressed) skz (zip) file, the
+* return value will be the path of that file, including the file name.
+* ARGUMENTS
+* * long widget -- karamba
+* RETURN VALUE
+* path to theme
+*/
+PyObject* py_get_theme_path(PyObject *self, PyObject *args);
+
+/** Misc/language
+*
+* SYNOPSIS
+* string language(widget)
+* DESCRIPTION
+* Returns a string containing default language of a translation file.
+* Please, see userLanguage to obtain the preferred KDE interface language.
+* ARGUMENTS
+* * long widget -- karamba
+* RETURN VALUE
+* default language or empty string if no translation files found.
+*/
+PyObject* py_language(PyObject *self, PyObject *args);
+
+/** Misc/userLanguage
+*
+* SYNOPSIS
+* string userLanguage(widget)
+* DESCRIPTION
+* Returns a string containing the language name abbreviation for the
+* language user chose for the KDE session in Region & Language settings.
+* Implemented in version 0.40. Parse ~/.kde/share/config/kdeglobals
+* for 'Language' directly for earlier clients.
+* ARGUMENTS
+* * long widget -- karamba
+* RETURN VALUE
+* user language or empty string.
+*/
+PyObject* py_userLanguage(PyObject *self, PyObject *args);
+
+
+/** Misc/userLanguages
+*
+* SYNOPSIS
+* string userLanguages(widget)
+* DESCRIPTION
+* Returns a list (array) containing the language name abbreviations for the
+* preferred interface languages user chose for KDE session in Region &
+* Language settings.
+* Having the whole array of preferred languages available is important for
+* cases when you cannot provide interface translation for the 1st preferred
+* language, but can for consecutive languages.
+* (Implemented in version 0.42.)
+* ARGUMENTS
+* * long widget -- karamba
+* RETURN VALUE
+* list (array) with user languages in the order of preference.
+*/
+PyObject* py_userLanguages(PyObject *self, PyObject *args);
+
+
+/** Misc/readThemeFile
+*
+* SYNOPSIS
+* string readThemeFile(widget, file)
+* DESCRIPTION
+* Returns a string containing the contents of the file.
+* ARGUMENTS
+* * long widget -- karamba
+* * string file -- name of the file to read
+* RETURN VALUE
+* file contents
+*/
+PyObject* py_read_theme_file(PyObject *self, PyObject *args);
+
+/** Misc/createClickArea
+*
+* SYNOPSIS
+* long createClickArea(widget, x, y, w, h, cmd_to_run)
+* DESCRIPTION
+* This creates a clickable area at x,y with width and height w,h. When
+* this area is clicked, cmd_to_run will be executed. The mouse will change
+* to the clickable icon while hovering over this area.
+* ARGUMENTS
+* * long widget -- karamba
+* * long x -- x coordinate
+* * long y -- y coordinate
+* * long w -- width
+* * long h -- height
+* * string cmd_to_run -- command to be run
+* RETURN VALUE
+* a handle to the click area
+*/
+PyObject* py_create_click_area(PyObject *self, PyObject *args);
+
+/** Misc/openTheme
+*
+* SYNOPSIS
+* long openTheme(theme)
+* DESCRIPTION
+* Opens new theme.
+* ARGUMENTS
+* * string theme -- path to new theme
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_open_theme(PyObject *self, PyObject *args);
+
+/** Misc/reloadTheme
+*
+* SYNOPSIS
+* long reloadTheme(theme)
+* DESCRIPTION
+* Reloads current theme.
+* ARGUMENTS
+* * string theme -- path to new theme
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_reload_theme(PyObject *self, PyObject *args);
+
+/** Misc/getNumberOfDesktop
+*
+* SYNOPSIS
+* long getNumberOfDesktop(widget)
+* DESCRIPTION
+* Returns number fo desktops
+* ARGUMENTS
+* * long widget -- karamba
+* RETURN VALUE
+* number of desktops
+*/
+PyObject* py_get_number_of_desktops(PyObject *self, PyObject *args);
+
+/** Misc/translateAll
+*
+* SYNOPSIS
+* long translateAll(widget, relative_x, relative_y)
+* DESCRIPTION
+* Moves all widgets within a theme in a particular direction relative to
+* the previous spot without moving the parent theme widget.
+* ARGUMENTS
+* * long widget -- karamba
+* * long translate_x -- move horizontally
+* * long translate_y -- move vertically
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_translate_all(PyObject *self, PyObject *args);
+
+/** Misc/show
+*
+* SYNOPSIS
+* string show(widget)
+* DESCRIPTION
+* show theme
+* ARGUMENTS
+* * long widget -- karamba
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_show(PyObject *self, PyObject *args);
+
+/** Misc/hide
+*
+* SYNOPSIS
+* string hide(widget)
+* DESCRIPTION
+* hide theme
+* ARGUMENTS
+* * long widget -- karamba
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_hide(PyObject *self, PyObject *args);
+
+/** Misc/getIp
+*
+* SYNOPSIS
+* string getIp(widget, interface_name)
+* DESCRIPTION
+* get current IP address of the interface_name interface.
+* ARGUMENTS
+* * long widget -- karamba
+* * string interface_name -- name of the interface to get ip
+* RETURN VALUE
+* ip address
+*/
+PyObject* py_get_ip(PyObject *self, PyObject *args);
+
+/** Misc/changeInterval
+*
+* SYNOPSIS
+* long changeInterval(widget, interval)
+* DESCRIPTION
+* Calling this changes your widget's refresh rate (ms)
+* ARGUMENTS
+* * long widget -- karamba
+* * int interval -- interval, in ms
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_change_interval(PyObject *self, PyObject *args);
+
+/** Misc/createServiceClickArea
+*
+* SYNOPSIS
+* long createServiceClickArea(widget, x, y, w, h, name_of_command, cmd_to_run, icon_to_display)
+* DESCRIPTION
+* This creates a clickable area at x,y with width and height w,h. When
+* this area is clicked, cmd_to_run will be executed. The mouse will change
+* to the clickable icon when over this area. For more information on
+* the difference between createClickArea and createServiceClickArea,
+* see the KDE documentation about KService, and the difference
+* between KRun::run and KRun::runCommand.
+* ARGUMENTS
+* * long widget -- karamba
+* * long x -- x coordinate
+* * long y -- y coordinate
+* * long w -- width
+* * long h -- height
+* * string name_of_command -- name to be displayed
+* * string cmd_to_run -- command to be run
+* * string icon_to_display -- name of icon to be displayed
+* RETURN VALUE
+* a handle to the click area
+*/
+PyObject* py_create_service_click_area(PyObject *self, PyObject *args);
+
+/** Misc/removeClickArea
+*
+* SYNOPSIS
+* long removeClickArea(widget, clickarea)
+* DESCRIPTION
+* This function deletes a clickable area.
+* ARGUMENTS
+* * long widget -- karamba
+* * long clickarea -- handle to the click area
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_remove_click_area(PyObject *self, PyObject *args);
+
+
+/** Misc/getPrettyThemeName
+*
+* SYNOPSIS
+* string getPrettyThemeName(theme)
+* DESCRIPTION
+* When a theme is created with openNamedTheme, there is an
+* option to give the theme an alternative name.
+* This is useful if you open several widgets from the same theme:
+* you need to give them unique names in order to contact them
+* (for example, with callTheme or with setIncomingData)
+* ARGUMENTS
+* * string theme -- path to the theme
+* RETURN VALUE
+* the pretty name of the theme
+*/
+PyObject* py_get_pretty_name(PyObject *self, PyObject *args);
+
+/** Misc/openNamedTheme
+*
+* SYNOPSIS
+* long openNamedTheme(theme, pretty_name, is_sub_theme)
+* DESCRIPTION
+* Opens a new theme, giving it a pretty (alternative and by your
+* own choice _unique_) name.
+* If you do not want the theme to be loaded when superkaramba is
+* first started up (but instead want it to only be opened by
+* this function call) then set is_sub_theme to 1.
+* Themes opened with openNamedTheme will be unique. If a theme
+* with the same pretty name already exists, openNamedTheme will
+* have no effect. If you want duplicate themes (and a bit of a
+* mess), use openTheme, instead.
+* ARGUMENTS
+* * string theme -- path to new theme
+* * string pretty_name -- the name to be associated with the new widget
+* * long is_sub_theme -- sets persistence (save state) of the theme
+* RETURN VALUE
+* a handle to the widget created
+*/
+PyObject* py_open_named_theme(PyObject *self, PyObject *args);
+
+/** Misc/callTheme
+*
+* SYNOPSIS
+* long callTheme(widget, theme, info)
+* DESCRIPTION
+* Sends a string to the theme identified by the pretty name.
+* If you need to pass complex arguments (dictionaries, lists), use python
+* "repr" and "eval" functions to marshall and unmarshall the data structure.
+* (themeNotify Will be called in the target theme when message is received)
+*
+* Note: As a bug/feature of SuperKaramba version 0.40, multiple instances of
+* the same theme share global variables. If you want to communicate to other
+* instances of the same theme, just communicate through global variables.
+* ARGUMENTS
+* * long widget -- karamba
+* * string theme -- pretty name of the theme to be called
+* * string info -- a string containing the info to be passed to the theme
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_call_theme(PyObject *self, PyObject *args);
+
+/** Misc/setIncomingData
+*
+* SYNOPSIS
+* long setIncomingData(widget, theme, info)
+* DESCRIPTION
+* Contacts a theme - identified by the pretty name - and stores a string
+* to be associated with the remote theme. The difference between
+* setIncomingData and callTheme is that the theme is not notified
+* by setIncomingData that the data has arrived. Previous information,
+* if any, is overwritten. Use getIncomingData to retrieve the last
+* stored information.
+* setIncomingData is not very sophisticated, and could benefit from
+* having info passed to it put into a queue, instead of being overwritten.
+* ARGUMENTS
+* * long widget -- karamba
+* * string theme -- pretty name of theme the information is passed to.
+* * string info -- a string containing the info to be passed to the theme
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_set_incoming_data(PyObject *self, PyObject *args);
+
+/** Misc/getIncomingData
+*
+* SYNOPSIS
+* long getIncomingData(widget)
+* DESCRIPTION
+* Obtains the last data received by any other theme that set the
+* "incoming data" of this theme. This isn't particularly sophisticated
+* and could benefit from the data being placed in an FIFO queue instead.
+* ARGUMENTS
+* * long widget -- karamba
+* RETURN VALUE
+* string containing last information received from setIncomingData
+*/
+PyObject* py_get_incoming_data(PyObject *self, PyObject *args);
+
+/** Misc/getUpdateTime
+*
+* SYNOPSIS
+* long getUpdateTime(widget)
+* DESCRIPTION
+* returns the last stored update time. Intended for use
+* so that the next refresh interval can work out how long ago
+* the mouse was last moved over the widget.
+* ARGUMENTS
+* * long widget -- karamba
+* RETURN VALUE
+* last stored update time (from setUpdateTime)
+*/
+PyObject* py_get_update_time(PyObject *self, PyObject *args);
+
+/** Misc/setWantRightButton
+*
+* SYNOPSIS
+* long setWantRightButton(widget, want_receive_right_button)
+* DESCRIPTION
+* There's a management menu for SuperKaramba themes which
+* allows themes to be loaded, closed, moved to other
+* screens. Not all themes will want this management
+* interface. call karamba.wantRightButton(widget, 1)
+* if you want to receive MouseUpdate button notifications.
+* ARGUMENTS
+* * long widget -- karamba
+* * long want_receive_right_button -- whether the widget will receive right clicks
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_want_right_button(PyObject *self, PyObject *args);
+
+/** Misc/setWantMeterWheelEvent
+*
+* SYNOPSIS
+* long setWantMeterWheelEvent(widget, want_receive_wheel_event)
+* DESCRIPTION
+* Enabling this allows themes to receive a wheel event when
+* the wheel is turned over a meter.
+* This function is available after version 0.42.
+* This behaviour is default in SuperKaramba 0.50 and later,
+* so this function will be not available after the 0.50 version.
+* ARGUMENTS
+* * long widget -- karamba
+* * long want_receive_wheel_event -- whether the theme will receive mouse wheel events
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_want_wheel_event(PyObject *, PyObject *args);
+
+/** Misc/managementPopup
+*
+* SYNOPSIS
+* long managementPopup(widget)
+* DESCRIPTION
+* There's a management menu for SuperKaramba themes which
+* allows themes to be loaded, closed, moved to other
+* screens. If you want this popup menu to appear, call
+* this function.
+* ARGUMENTS
+* * long widget -- karamba
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_management_popup(PyObject *self, PyObject *args);
+
+/** Misc/setUpdateTime
+*
+* SYNOPSIS
+* long getUpdateTime(widget, updated_time)
+* DESCRIPTION
+* returns the last stored update time. intended for use
+* so that the next refresh interval can work out how long ago
+* the mouse was last moved over the widget.
+* ARGUMENTS
+* * long widget -- karamba
+* * long updated_time -- the update time to be associated with the widget
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_set_update_time(PyObject *self, PyObject *args);
+
+#endif /* MISC_PYTHON_H */
+
diff --git a/superkaramba/src/networksensor.cpp b/superkaramba/src/networksensor.cpp
new file mode 100644
index 0000000..30f9612
--- /dev/null
+++ b/superkaramba/src/networksensor.cpp
@@ -0,0 +1,164 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Hans Karlsson *
+ * karlsson.h@home.se *
+ * *
+ * 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. *
+ ***************************************************************************/
+#ifdef __FreeBSD__
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/socket.h>
+#include <net/route.h>
+#endif
+
+#include "networksensor.h"
+
+NetworkSensor::NetworkSensor( QString dev, int interval ):Sensor( interval )
+{
+ device = dev.lower();
+
+#ifdef __FreeBSD__
+ /* Determine number of interfaces */
+ u_int n = 0;
+ size_t nlen = 0;
+ nlen = sizeof(n);
+ sysctlbyname("net.link.generic.system.ifcount", &n, &nlen, NULL, 0);
+
+ size_t if_miblen = 0;
+ if_miblen = sizeof(if_mib);
+ static int name[] = { CTL_NET,
+ PF_LINK,
+ NETLINK_GENERIC,
+ IFMIB_IFDATA,
+ 0,
+ IFDATA_GENERAL };
+
+ /*
+ If the device was defined by the theme, find the right devicenumber.
+ If not, use the device that holds the default route.
+ */
+
+ if_number = -1;
+ int if_gw = -1;
+
+ for (int i = 1; i <= n; ++i) {
+ name[4] = i;
+ /* Get data for iface-number i */
+ sysctl(name, 6, (void*)&if_mib, (size_t*)&if_miblen, (void*)NULL, (size_t)0);
+
+ /* We found the right interface? */
+ if (QString(if_mib.ifmd_name) == device) {
+ if_number = i;
+ break;
+ }
+
+ /* Does the interface hold the default route? */
+ if ( if_mib.ifmd_flags & RTF_GATEWAY )
+ if_gw = i;
+ }
+
+ if ((if_number == -1) && (if_gw != -1))
+ if_number = if_gw;
+#else
+ if( device.isEmpty() )
+ device = "eth0";
+#endif
+ getInOutBytes(receivedBytes,transmittedBytes);
+ netTimer.start();
+
+}
+NetworkSensor::~NetworkSensor()
+{
+}
+void NetworkSensor::getInOutBytes ( unsigned long &in,unsigned long &out) const
+{
+#ifdef __FreeBSD__
+ if (if_number != -1) {
+ size_t if_miblen = 0;
+ if_miblen = sizeof(if_mib);
+ int name[] = { CTL_NET,
+ PF_LINK,
+ NETLINK_GENERIC,
+ IFMIB_IFDATA,
+ if_number,
+ IFDATA_GENERAL };
+
+ sysctl(name, 6, (void*)&if_mib, (size_t*)&if_miblen, (void*)NULL, (size_t)0);
+
+ in = if_mib.ifmd_data.ifi_ibytes;
+ out = if_mib.ifmd_data.ifi_obytes;
+ }
+ else {
+ in = 0;
+ out = 0;
+ }
+#else
+ QFile file("/proc/net/dev");
+ QString line;
+ if ( file.open(IO_ReadOnly | IO_Translate) )
+ {
+ QTextStream t( &file ); // use a text stream
+ line = t.readLine();
+ while(line !=0 && !line.contains(device))
+ {
+ line = t.readLine();
+ }
+ if ( line.contains( device ) )
+ {
+ QRegExp rx( "\\W+"+device+":\\D*(\\d+)(?:\\D+\\d+){7}\\D+(\\d+)", false);
+ rx.search(line);
+ in = rx.cap(1).toULong();
+ out = rx.cap(2).toULong();
+ }
+ else
+ {
+ qDebug("Network sensor: can not find %s", device.ascii());
+ in = 0;
+ out = 0;
+ }
+ file.close();
+ }
+#endif
+}
+
+void NetworkSensor::update()
+{
+ SensorParams *sp;
+ Meter *meter;
+ QObjectListIt it( *objList );
+ QString format;
+ int decimals;
+
+ unsigned long inB, outB;
+ const double delay = (double) netTimer.elapsed(); // msec elapsed since last update
+ getInOutBytes( inB, outB );
+ netTimer.restart();
+
+ while( it != 0 )
+ {
+ sp = (SensorParams*)(*it);
+ meter = sp->getMeter();
+ format = sp->getParam( "FORMAT" );
+ decimals = ( sp->getParam( "DECIMALS" ) ).toInt();
+ if (format.length() == 0 )
+ {
+ format = "%in";
+ }
+
+ format.replace( QRegExp("%inkb", false), QString::number( ((inB - receivedBytes)*8)/delay, 'f', decimals ) );
+ format.replace( QRegExp("%in", false), QString::number( (inB - receivedBytes)/delay, 'f', decimals ) );
+
+ format.replace( QRegExp("%outkb", false), QString::number( ((outB - transmittedBytes)*8)/delay, 'f', decimals ) );
+ format.replace( QRegExp("%out", false), QString::number( (outB - transmittedBytes)/delay, 'f', decimals ) );
+
+ meter->setValue( format );
+ ++it;
+ }
+ receivedBytes = inB;
+ transmittedBytes = outB;
+}
+
+#include "networksensor.moc"
diff --git a/superkaramba/src/networksensor.h b/superkaramba/src/networksensor.h
new file mode 100644
index 0000000..bbdbd13
--- /dev/null
+++ b/superkaramba/src/networksensor.h
@@ -0,0 +1,47 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Hans Karlsson *
+ * karlsson.h@home.se *
+ * *
+ * 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. *
+ ***************************************************************************/
+#ifndef NETWORKSENSOR_H
+#define NETWORKSENSOR_H
+
+#include "sensor.h"
+
+#include <qdatetime.h>
+#include <qfile.h>
+#include <qregexp.h>
+#ifdef __FreeBSD__
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <net/if_mib.h>
+#endif
+
+class NetworkSensor : public Sensor
+{
+ Q_OBJECT
+public:
+ NetworkSensor( QString device, int interval );
+ ~NetworkSensor();
+ void update();
+
+
+private:
+ unsigned long receivedBytes;
+ unsigned long transmittedBytes;
+ QTime netTimer;
+ QString device;
+#ifdef __FreeBSD__
+ int if_number;
+ ifmibdata if_mib;
+#endif
+ void getInOutBytes (unsigned long &in,unsigned long &out) const;
+
+};
+#endif // NETWORKSENSOR_H
+
diff --git a/superkaramba/src/noatunsensor.cpp b/superkaramba/src/noatunsensor.cpp
new file mode 100644
index 0000000..607da9e
--- /dev/null
+++ b/superkaramba/src/noatunsensor.cpp
@@ -0,0 +1,234 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Hans Karlsson *
+ * karlsson.h@home.se *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "noatunsensor.h"
+
+NoatunSensor::NoatunSensor( int interval, DCOPClient *c)
+ : Sensor( interval )
+{
+ client = c;
+ noatunID = "noatun";
+}
+
+
+NoatunSensor::~NoatunSensor()
+{}
+
+
+void NoatunSensor::update()
+{
+ QString format;
+ SensorParams *sp;
+ Meter *meter;
+ QObjectListIt it( *objList );
+
+ QString title;
+ int songLength = 0;
+ int currentTime = 0;
+
+ bool running = isRunning();
+
+ if( running )
+ {
+ title = getTitle();
+
+ if( title.isEmpty() )
+ title = "Noatun";
+ currentTime = getTime();
+ if( currentTime == -1 )
+ currentTime = 0;
+
+ songLength = getLength();
+ if( songLength == -1 )
+ songLength = 0;
+ }
+
+
+ while (it != 0)
+ {
+ sp = (SensorParams*)(*it);
+ meter = sp->getMeter();
+
+ if( running )
+ {
+
+ format = sp->getParam("FORMAT");
+ if (format.length() == 0 )
+ {
+ format = "%title %time / %length";
+ }
+
+ if( format.lower() == "%ms" )
+ {
+ meter->setMax( songLength );
+ meter->setValue( currentTime );
+ }
+ else
+ if ( format.lower() == "%full" )
+ {
+ meter->setValue( 1 );
+ }
+ else
+
+ {
+ format.replace( QRegExp("%title", false), title );
+ format.replace( QRegExp("%id", false), noatunID );
+
+ format.replace( QRegExp("%length", false), QTime( 0,0,0 ).
+ addMSecs( songLength )
+ .toString( "h:mm:ss" ) );
+
+ format.replace( QRegExp("%time", false), QTime( 0,0,0 ).
+ addMSecs( currentTime )
+ .toString( "h:mm:ss" ) );
+ format.replace( QRegExp("%remain", false), QTime( 0,0,0 ).
+ addMSecs( songLength )
+ .addMSecs(-currentTime )
+ .toString( "h:mm:ss" ) );
+
+ meter->setValue(format);
+ }
+ }
+ else
+
+ {
+ meter->setValue("");
+ }
+ ++it;
+
+
+ }
+
+}
+
+bool NoatunSensor::isRunning()
+{
+ QRegExp rx("(noatun)|(noatun-\\d+)");
+ QCStringList list = client->registeredApplications();
+ QValueList<QCString>::iterator it;
+ it = list.begin();
+ bool foundNoatun = false;
+ noatunID = "noatun";
+ while( foundNoatun == false && it != list.end() )
+ {
+ if( rx.search( *it ) != -1 )
+ {
+ foundNoatun = true;
+ noatunID = *it;
+ }
+ ++it;
+ }
+ return ( client->isApplicationRegistered ( noatunID ) );
+}
+
+
+QString NoatunSensor::getTitle()
+{
+ QByteArray data, replyData;
+ QCString replyType;
+ QString result;
+ QDataStream arg(data, IO_WriteOnly);
+ arg << 5;
+ if (!client->call( noatunID, "Noatun", "title()",
+ data, replyType, replyData))
+ {
+ result = "";
+ qDebug("there was some error using DCOP.");
+ }
+ else
+ {
+ QDataStream reply(replyData, IO_ReadOnly);
+ if (replyType == "QString")
+ {
+ reply >> result;
+ result.replace( QRegExp("_")," " );
+ result.replace( QRegExp(".mp3$"),"" );
+
+ }
+ else
+ {
+ result = "";
+ qDebug("title returned an unexpected type of reply!");
+ }
+ }
+ return result;
+}
+
+
+int NoatunSensor::getTime()
+{
+ QByteArray data, replyData;
+ QCString replyType;
+ int result;
+ QDataStream arg(data, IO_WriteOnly);
+ arg << 5;
+ if (!client->call( noatunID, "Noatun", "position()",
+ data, replyType, replyData))
+ {
+ result = 0;
+ qDebug("there was some error using DCOP.");
+ }
+ else
+ {
+ QDataStream reply(replyData, IO_ReadOnly);
+ if (replyType == "int")
+ {
+ reply >> result;
+ }
+ else
+ {
+ result = 0;
+ qDebug("title returned an unexpected type of reply!");
+ }
+ }
+ return result;
+}
+
+
+int NoatunSensor::getLength()
+{
+ QByteArray data, replyData;
+ QCString replyType;
+ int result;
+ QDataStream arg(data, IO_WriteOnly);
+ arg << 5;
+ if (!client->call( noatunID, "Noatun", "length()",
+ data, replyType, replyData))
+ {
+ result = 0;
+ qDebug("there was some error using DCOP.");
+ }
+ else
+ {
+ QDataStream reply(replyData, IO_ReadOnly);
+ if (replyType == "int")
+ {
+ reply >> result;
+ }
+ else
+ {
+ result = 0;
+ qDebug("title returned an unexpected type of reply!");
+ }
+ }
+ return result;
+}
+
+
+void NoatunSensor::setMaxValue( SensorParams *sp)
+{
+ Meter *meter;
+ meter = sp->getMeter();
+ QString f;
+ f = sp->getParam("FORMAT");
+
+ if ( f == "%full" )
+ meter->setMax( 1 );
+
+}
diff --git a/superkaramba/src/noatunsensor.h b/superkaramba/src/noatunsensor.h
new file mode 100644
index 0000000..7d43b96
--- /dev/null
+++ b/superkaramba/src/noatunsensor.h
@@ -0,0 +1,48 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Hans Karlsson *
+ * karlsson.h@home.se *
+ * *
+ * 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. *
+ ***************************************************************************/
+#ifndef NOATUNSENSOR_H
+#define NOATUNSENSOR_H
+
+#include "sensor.h"
+#include <dcopclient.h>
+#include <qregexp.h>
+#include <qcstring.h>
+#include <qdatastream.h>
+#include <qstringlist.h>
+
+/**
+@author Hans Karlsson
+*/
+class NoatunSensor : public Sensor
+{
+public:
+ NoatunSensor( int interval, DCOPClient *client);
+
+ ~NoatunSensor();
+
+ void update();
+ void setMaxValue( SensorParams *);
+
+
+
+private:
+ QCString noatunID;
+
+ bool isRunning();
+ QString getTitle();
+ int getTime();
+ int getLength();
+
+
+ DCOPClient *client;
+ QCString appId;
+};
+
+#endif
diff --git a/superkaramba/src/programsensor.cpp b/superkaramba/src/programsensor.cpp
new file mode 100644
index 0000000..a3bddc5
--- /dev/null
+++ b/superkaramba/src/programsensor.cpp
@@ -0,0 +1,93 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Hans Karlsson *
+ * karlsson.h@home.se *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "programsensor.h"
+
+#include <qstringlist.h>
+ProgramSensor::ProgramSensor(const QString &progName, int interval, QString encoding )
+ : Sensor( interval )
+{
+ if( !encoding.isEmpty())
+ {
+ codec = QTextCodec::codecForName( encoding.ascii() );
+ if ( codec == 0)
+ codec = QTextCodec::codecForLocale();
+ }
+ else
+ codec = QTextCodec::codecForLocale();
+
+
+ programName = progName;
+ //update();
+ connect(&ksp, SIGNAL(receivedStdout(KProcess *, char *, int )),
+ this,SLOT(receivedStdout(KProcess *, char *, int )));
+ connect(&ksp, SIGNAL(processExited(KProcess *)),
+ this,SLOT(processExited( KProcess * )));
+}
+
+ProgramSensor::~ProgramSensor()
+{}
+
+void ProgramSensor::receivedStdout(KProcess *, char *buffer, int len)
+{
+ buffer[len] = 0;
+ sensorResult += codec->toUnicode( QCString(buffer) );
+}
+
+void ProgramSensor::processExited(KProcess *)
+{
+ int lineNbr;
+ SensorParams *sp;
+ Meter *meter;
+ QValueVector<QString> lines;
+ QStringList stringList = QStringList::split('\n',sensorResult,true);
+ QStringList::ConstIterator end( stringList.end() );
+ for ( QStringList::ConstIterator it = stringList.begin(); it != end; ++it )
+ {
+ lines.push_back(*it);
+ }
+
+ int count = (int) lines.size();
+ QObjectListIt it( *objList );
+ while (it != 0)
+ {
+ sp = (SensorParams*)(*it);
+ meter = sp->getMeter();
+ if( meter != 0)
+ {
+ lineNbr = (sp->getParam("LINE")).toInt();
+ if ( lineNbr >= 1 && lineNbr <= (int) count )
+ {
+ meter->setValue(lines[lineNbr-1]);
+ }
+ if ( -lineNbr >= 1 && -lineNbr <= (int) count )
+ {
+ meter->setValue(lines[count+lineNbr]);
+ }
+ if (lineNbr == 0)
+ {
+ meter->setValue(sensorResult);
+ }
+ }
+ ++it;
+ }
+
+ sensorResult = "";
+}
+
+void ProgramSensor::update()
+{
+ ksp.clearArguments();
+ ksp << programName;
+
+
+ ksp.start( KProcIO::NotifyOnExit,KProcIO::Stdout);
+}
+
+#include "programsensor.moc"
diff --git a/superkaramba/src/programsensor.h b/superkaramba/src/programsensor.h
new file mode 100644
index 0000000..1ee7407
--- /dev/null
+++ b/superkaramba/src/programsensor.h
@@ -0,0 +1,38 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Hans Karlsson *
+ * karlsson.h@home.se *
+ * *
+ * 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. *
+ ***************************************************************************/
+#ifndef PROGRAMSENSOR_H
+#define PROGRAMSENSOR_H
+#include "sensor.h"
+#include <kprocess.h>
+#include <kprocio.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qvaluevector.h>
+#include <qtextcodec.h>
+class ProgramSensor : public Sensor
+{
+ Q_OBJECT
+public:
+ ProgramSensor(const QString &programName, int msec=1000, QString encoding="" );
+ ~ProgramSensor();
+ void update();
+
+private:
+ QTextCodec *codec;
+ KShellProcess ksp;
+ QString programName;
+ QString sensorResult;
+
+public slots:
+ void receivedStdout(KProcess *proc, char *buffer, int buflen);
+ void processExited(KProcess *proc);
+};
+
+#endif // PROGRAMSENSOR_H
diff --git a/superkaramba/src/richtextlabel.cpp b/superkaramba/src/richtextlabel.cpp
new file mode 100644
index 0000000..9a8fee0
--- /dev/null
+++ b/superkaramba/src/richtextlabel.cpp
@@ -0,0 +1,212 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Wilfried Huss *
+ * Wilfried.Huss@gmx.at *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+
+#include <krun.h>
+#include <kdebug.h>
+#include "karamba.h"
+#include "richtextlabel.h"
+
+RichTextLabel::RichTextLabel(karamba* k) :
+ Meter(k, 0, 0, 100, 100),
+ text(0),
+ source(""),
+ colorGrp(k->colorGroup()),
+ underlineLinks(false)
+{
+ originalSize = QSize(0, 0);
+}
+
+RichTextLabel::RichTextLabel(karamba* k, int x, int y, int w, int h) :
+ Meter(k, x, y, w, h),
+ text(0),
+ source(""),
+ colorGrp(k->colorGroup()),
+ underlineLinks(false)
+{
+ kdDebug() << k_funcinfo << x << ", " << y << ", " << w << ", " << h << endl;
+ originalSize = QSize(w, h);
+}
+
+RichTextLabel::~RichTextLabel()
+{
+ if (text != 0)
+ {
+ delete text;
+ text = 0;
+ }
+}
+
+void RichTextLabel::setText(QString t, bool linkUnderline)
+{
+ source = t;
+ if (text != 0)
+ {
+ delete text;
+ text = 0;
+ }
+ else
+ {
+ // set underlineLinks only when RichTextLabel is created, not
+ // when text is changed.
+ underlineLinks = linkUnderline;
+ }
+
+ text = new QSimpleRichText(t, font, m_karamba->theme().path(),
+ 0, // default QStyleSheet*
+ 0, // default QMimeSourceFactory
+ -1, // no pageBreak
+ Qt::blue, // (has no effect) link Color
+ underlineLinks);
+
+ // set the text to a reasonable size
+ text->adjustSize();
+ if(originalSize.width() < 1)
+ setWidth(text->width());
+ else
+ text->setWidth(getWidth());
+ if(originalSize.height() < 1)
+ setHeight(text->height());
+}
+
+void RichTextLabel::setValue(QString text)
+{
+ setText(text);
+}
+
+void RichTextLabel::setValue(long v)
+{
+ setText(QString::number(v));
+}
+
+void RichTextLabel::setFont(QString f)
+{
+ font.setFamily(f);
+ if(text != 0)
+ text->setDefaultFont(font);
+}
+
+QString RichTextLabel::getFont() const
+{
+ return font.family();
+}
+
+void RichTextLabel::setFontSize(int size)
+{
+ font.setPixelSize(size);
+ if(text != 0)
+ text->setDefaultFont(font);
+}
+
+int RichTextLabel::getFontSize() const
+{
+ return font.pixelSize();
+}
+
+void RichTextLabel::setFixedPitch(bool fp)
+{
+ font.setFixedPitch(fp);
+ if(text != 0)
+ text->setDefaultFont(font);
+}
+
+bool RichTextLabel::getFixedPitch() const
+{
+ return font.fixedPitch();
+}
+
+void RichTextLabel::setTextProps(TextField* t)
+{
+ if(t)
+ {
+ setFontSize(t->getFontSize());
+ setFont(t->getFont());
+ colorGrp.setColor(QColorGroup::Text, t->getColor());
+ }
+}
+
+void RichTextLabel::setWidth(int width)
+{
+ Meter::setWidth(width);
+ // rearrange text
+ text->setWidth(getWidth());
+ if(originalSize.height() < 1)
+ setHeight(text->height());
+}
+
+void RichTextLabel::mUpdate(QPainter* p)
+{
+ if (hidden || text == 0)
+ {
+ return;
+ }
+
+ int x = getX();
+ int y = getY();
+ int w = getWidth();
+ int h = getHeight();
+ QRect clipRect(x, y, w, h);
+ text->draw(p, x, y, clipRect, colorGrp, 0 /* no background */);
+}
+
+bool RichTextLabel::click(QMouseEvent* e)
+{
+ if (hidden)
+ {
+ return false;
+ }
+ QPoint point(e->x() - getX(), e->y() - getY());
+ QString anchor = text->anchorAt(point);
+ if (anchor[0] != '#')
+ {
+ if (e->button() == Qt::LeftButton)
+ {
+ KRun :: runCommand(anchor);
+ }
+ return false;
+ }
+ else
+ {
+ //call callback meterClicked
+ return true;
+ }
+}
+
+QString RichTextLabel::anchorAt(int x, int y)
+{
+ QPoint point(x - getX(), y - getY());
+ QString anchor = text->anchorAt(point);
+ if (anchor[0] == '#')
+ {
+ return anchor.remove(0, 1);
+ }
+ else
+ {
+ // ASSERT: should never happen
+ return "";
+ }
+}
+
+bool RichTextLabel::insideActiveArea(int x, int y)
+{
+ QPoint point(x - getX(), y - getY());
+ return text->anchorAt(point) != ""; // && text -> inText(point);
+}
+
+void RichTextLabel::setColorGroup(const QColorGroup &colorg)
+{
+ colorGrp = colorg;
+}
+
+const QColorGroup & RichTextLabel::getColorGroup() const
+{
+ return colorGrp;
+}
+
+#include "richtextlabel.moc"
diff --git a/superkaramba/src/richtextlabel.h b/superkaramba/src/richtextlabel.h
new file mode 100644
index 0000000..810b129
--- /dev/null
+++ b/superkaramba/src/richtextlabel.h
@@ -0,0 +1,64 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Wilfried Huss *
+ * Wilfried.Huss@gmx.at *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef RICHTEXTLABEL_H
+#define RICHTEXTLABEL_H
+
+#include "meter.h"
+#include <qstring.h>
+#include <qsimplerichtext.h>
+#include <qpainter.h>
+#include <qfont.h>
+#include <qfontmetrics.h>
+#include <qrect.h>
+#include <qsize.h>
+#include "karamba.h"
+
+class RichTextLabel : public Meter
+{
+ Q_OBJECT
+ public:
+ RichTextLabel(karamba*);
+ RichTextLabel(karamba* k, int x, int y, int w, int h);
+ ~RichTextLabel();
+
+ void setText(QString text, bool linkUnderline = false);
+ void setValue(QString text);
+ void setValue(long v);
+ QString getStringValue() { return source; };
+
+ void setFont(QString font);
+ QString getFont() const;
+ void setFontSize(int);
+ int getFontSize() const;
+ void setFixedPitch(bool);
+ bool getFixedPitch() const;
+ void setTextProps( TextField* t );
+ void setColorGroup(const QColorGroup &colorg);
+ const QColorGroup &getColorGroup() const;
+ void setWidth(int width);
+
+ virtual bool insideActiveArea(int, int);
+
+ virtual bool click(QMouseEvent*);
+ virtual void mUpdate(QPainter*);
+
+ QString anchorAt(int, int);
+
+ private:
+ QSimpleRichText* text;
+ QString source;
+ QFont font;
+ QColorGroup colorGrp;
+ bool underlineLinks;
+ QSize originalSize;
+};
+
+#endif
diff --git a/superkaramba/src/richtextlabel_python.cpp b/superkaramba/src/richtextlabel_python.cpp
new file mode 100644
index 0000000..7ac14cd
--- /dev/null
+++ b/superkaramba/src/richtextlabel_python.cpp
@@ -0,0 +1,182 @@
+/****************************************************************************
+* richtextlabel_python.cpp - Functions for richtext python api
+*
+* Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+* Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+* Copyright (c) 2004 Petri Damstn <damu@iki.fi>
+*
+* This file is part of SuperKaramba.
+*
+* SuperKaramba 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.
+*
+* SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+#ifdef _XOPEN_SOURCE
+#undef _XOPEN_SOURCE
+#endif
+
+#include <Python.h>
+#include <qobject.h>
+#include "karamba.h"
+#include "richtextlabel.h"
+#include "meter_python.h"
+#include "richtextlabel_python.h"
+
+PyObject* py_createRichText(PyObject *, PyObject *args)
+{
+ long widget, underline = 0;
+ PyObject *text;
+ if (!PyArg_ParseTuple(args, (char*)"lO|l:createRichText",
+ &widget, &text, &underline))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ RichTextLabel *tmp = new RichTextLabel((karamba*)widget);
+ tmp->setText(PyString2QString(text), underline);
+ tmp->setTextProps(((karamba*)widget)->getDefaultTextProps());
+ ((karamba*)widget)->meterList->append(tmp);
+ ((karamba*)widget)->clickList->append(tmp);
+ return (Py_BuildValue((char*)"l", (long)tmp));
+}
+
+PyObject* py_deleteRichText(PyObject *, PyObject *args)
+{
+ long widget, meter;
+ if (!PyArg_ParseTuple(args, (char*)"ll:deleteRichText", &widget, &meter))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, "RichTextLabel"))
+ return NULL;
+
+ ((karamba*)widget)->deleteMeterFromSensors((Meter*)meter);
+ ((karamba*)widget)->clickList->removeRef((Meter*)meter);
+ return Py_BuildValue((char*)"l",
+ ((karamba*)widget)->meterList->removeRef((Meter*)meter));
+}
+
+PyObject* py_getThemeRichText(PyObject *self, PyObject *args)
+{
+ return py_getThemeMeter(self, args, "RichTextLabel");
+}
+
+PyObject* py_getRichTextSize(PyObject *self, PyObject *args)
+{
+ return py_getSize(self, args, "RichTextLabel");
+}
+
+PyObject* py_resizeRichText(PyObject *self, PyObject *args)
+{
+ return py_resize(self, args, "RichTextLabel");
+}
+
+PyObject* py_getRichTextPos(PyObject *self, PyObject *args)
+{
+ return py_getPos(self, args, "RichTextLabel");
+}
+
+PyObject* py_moveRichText(PyObject *self, PyObject *args)
+{
+ return py_move(self, args, "RichTextLabel");
+}
+
+PyObject* py_hideRichText(PyObject *self, PyObject *args)
+{
+ return py_hide(self, args, "RichTextLabel");
+}
+
+PyObject* py_showRichText(PyObject *self, PyObject *args)
+{
+ return py_show(self, args, "RichTextLabel");
+}
+
+PyObject* py_getRichTextValue(PyObject *self, PyObject *args)
+{
+ return py_getStringValue(self, args, "RichTextLabel");
+}
+
+PyObject* py_setRichTextValue(PyObject *self, PyObject *args)
+{
+ return py_setStringValue(self, args, "RichTextLabel");
+}
+
+PyObject* py_getRichTextSensor(PyObject *self, PyObject *args)
+{
+ return py_getSensor(self, args, "RichTextLabel");
+}
+
+PyObject* py_setRichTextSensor(PyObject *self, PyObject *args)
+{
+ return py_setSensor(self, args, "RichTextLabel");
+}
+
+PyObject* py_setRichTextFontSize(PyObject *, PyObject *args)
+{
+ long widget, textSensor;
+ long size;
+ if (!PyArg_ParseTuple(args, (char*)"lll:changeRichTextSize",
+ &widget, &textSensor, &size))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, textSensor, "RichTextLabel"))
+ return NULL;
+ ((RichTextLabel*)textSensor)->setFontSize( size );
+ return Py_BuildValue((char*)"l", 1);
+}
+
+PyObject* py_getRichTextFontSize(PyObject *, PyObject *args)
+{
+ long widget, textSensor;
+ if (!PyArg_ParseTuple(args, (char*)"ll:getRichTextSize", &widget, &textSensor))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, textSensor, "RichTextLabel"))
+ return NULL;
+ return Py_BuildValue((char*)"l", ((RichTextLabel*)textSensor)->getFontSize());
+}
+
+PyObject* py_setRichTextFont(PyObject *, PyObject *args)
+{
+ long widget, textSensor;
+ char* text;
+ if (!PyArg_ParseTuple(args, (char*)"lls:changeRichTextFont",
+ &widget, &textSensor, &text))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, textSensor, "RichTextLabel"))
+ return NULL;
+ ((RichTextLabel*)textSensor)->setFont( text );
+ return Py_BuildValue((char*)"l", 1);
+}
+
+PyObject* py_getRichTextFont(PyObject *, PyObject *args)
+{
+ long widget, textSensor;
+ if (!PyArg_ParseTuple(args, (char*)"ll:getRichTextFont", &widget, &textSensor))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, textSensor, "RichTextLabel"))
+ return NULL;
+ return Py_BuildValue((char*)"s", ((RichTextLabel*)textSensor)->getFont().ascii());
+}
+
+// Set the width of a Rich Text Label
+PyObject* py_set_rich_text_width(PyObject*, PyObject* args)
+{
+ long widget, text, size;
+ if (!PyArg_ParseTuple(args, (char*)"lll:setRichTextWidth", &widget, &text, &size))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, text, "RichTextLabel"))
+ return NULL;
+
+ RichTextLabel* richText = (RichTextLabel*) text;
+
+ richText -> setWidth(size);
+ return Py_BuildValue((char*)"l", 1);
+}
+
diff --git a/superkaramba/src/richtextlabel_python.h b/superkaramba/src/richtextlabel_python.h
new file mode 100644
index 0000000..2d988de
--- /dev/null
+++ b/superkaramba/src/richtextlabel_python.h
@@ -0,0 +1,338 @@
+/****************************************************************************
+* richtextlabel_python.h - Functions for richtext python api
+*
+* Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+* Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+* Copyright (c) 2004 Petri Damstn <damu@iki.fi>
+*
+* This file is part of SuperKaramba.
+*
+* SuperKaramba 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.
+*
+* SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+#ifndef RICHTEXTLABEL_PYTHON_H
+#define RICHTEXTLABEL_PYTHON_H
+
+/** RichText/createRichText
+*
+* SYNOPSIS
+* long createRichText(widget, text, underlineLinks)
+* DESCRIPTION
+* This creates creates a rich text string. underlineLinks is a boolean that
+* determines if html links will be automatically underlined so that the
+* user knows that the links can be clicked on. You need to save the return
+* value of this function to call other functions on your rich text field,
+* such as changeRichText().
+*
+* The differance between Rich Text and a regular text field is that rich
+* text fields can display HTML code embedded in your text.
+*
+* In a <a href="command"> ... </a> tag command is executed if the link is
+* click with the left mouse button.
+*
+* Except if command starts with an '#' (ie: href="#value" ) the callback
+* meterClicked is called with value (without the #) as the meter argument.
+*
+* Also inline images work. Unfortunatly currently only when using absolute
+* paths.
+* ARGUMENTS
+* * long widget -- karamba
+* * string text -- text for richtext
+* * long underlineLinks -- should the links be underlined
+* RETURN VALUE
+* Pointer to new richtext meter
+*/
+PyObject* py_createRichText(PyObject *self, PyObject *args);
+
+/** RichText/deleteRichText
+*
+* SYNOPSIS
+* long deleteRichText(widget, richtext)
+* DESCRIPTION
+* This removes a richt text object from memory. Please do not call
+* functions on "text" after calling deleteRichText, as it does not exist
+* anymore and that could cause crashes in some cases.
+* ARGUMENTS
+* * long widget -- karamba
+* * long widget -- richtext
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_deleteRichText(PyObject *self, PyObject *args);
+
+/** RichText/getThemeRichText
+*
+* SYNOPSIS
+* long getThemeRichText(widget, name)
+* DESCRIPTION
+* You can reference richtext in your python code that was created in the
+* theme file. Basically, you just add a NAME= value to the GRAPH line in
+* the .theme file. Then if you want to use that object, instead of calling
+* createRichText, you can call this function.
+*
+* The name you pass to the function is the same one that you gave it for
+* the NAME= parameter in the .theme file.
+* ARGUMENTS
+* * long widget -- karamba
+* * string name -- name of the richtext to get
+* RETURN VALUE
+* Pointer to richtext
+*/
+PyObject* py_getThemeRichText(PyObject *self, PyObject *args);
+
+/** RichText/getRichTextSize
+*
+* SYNOPSIS
+* tuple getRichTextSize(widget, richtext)
+* DESCRIPTION
+* Given a reference to a richtext object, this will return a tuple
+* containing the height and width of a richtext object.
+* ARGUMENTS
+* * long widget -- karamba
+* * long richtext -- pointer to richtext
+* RETURN VALUE
+* size
+*/
+PyObject* py_getRichTextSize(PyObject *self, PyObject *args);
+
+/** RichText/resizeRichText
+*
+* SYNOPSIS
+* long resizeRichText(widget, richtext, w, h)
+* DESCRIPTION
+* This will resize richtext to new height and width.
+* ARGUMENTS
+* * long widget -- karamba
+* * long richtext -- pointer to richtext
+* * long w -- new width
+* * long h -- new height
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_resizeRichText(PyObject *self, PyObject *args);
+
+/** RichText/getRichTextPos
+*
+* SYNOPSIS
+* tuple getRichTextPos(widget, richtext)
+* DESCRIPTION
+* Given a reference to a richtext object, this will return a tuple
+* containing the x and y coordinate of a richtext object.
+* ARGUMENTS
+* * long widget -- karamba
+* * long richtext -- pointer to richtext
+* RETURN VALUE
+* pos
+*/
+PyObject* py_getRichTextPos(PyObject *self, PyObject *args);
+
+/** RichText/moveRichText
+*
+* SYNOPSIS
+* long moveRichText(widget, richtext, x, y)
+* DESCRIPTION
+* This moves a text object to a new x, y relative to your widget. In other
+* words, (0,0) is the top corner of your widget, not the screen.
+* ARGUMENTS
+* * long widget -- karamba
+* * long richtext -- pointer to richtext
+* * long x -- x coordinate
+* * long y -- y coordinate
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_moveRichText(PyObject *self, PyObject *args);
+
+/** RichText/hideRichText
+*
+* SYNOPSIS
+* long hideRichText(widget, richtext)
+* DESCRIPTION
+* This hides an richtext. In other words, during subsequent calls to
+* widgetUpdate(), this richtext will not be drawn.
+* ARGUMENTS
+* * long widget -- karamba
+* * long richtext -- pointer to richtext
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_hideRichText(PyObject *self, PyObject *args);
+
+/** RichText/showRichText
+*
+* SYNOPSIS
+* long showRichText(widget, richtext)
+* DESCRIPTION
+* This shows an richtext. In other words, during subsequent calls to
+* widgetUpdate(), this richtext will be drawn.
+* ARGUMENTS
+* * long widget -- karamba
+* * long richtext -- pointer to richtext
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_showRichText(PyObject *self, PyObject *args);
+
+/** RichText/getRichTextValue
+*
+* SYNOPSIS
+* string getRichTextValue(widget, richtext)
+* DESCRIPTION
+* Returns current richtext value.
+* ARGUMENTS
+* * long widget -- karamba
+* * long richtext -- pointer to richtext
+* RETURN VALUE
+* value
+*/
+PyObject* py_getRichTextValue(PyObject *self, PyObject *args);
+
+/** RichText/changeRichText
+*
+* SYNOPSIS
+* long changeRichText(widget, richtext, value)
+* DESCRIPTION
+* This will change the contents of a rich text widget. richText is the
+* reference to the text object to change that you saved from the
+* createRichText() call. text is a string containing the new value for the
+* rich text object.
+*
+* The differance between Rich Text and a regular text field is that rich
+* text fields can display HTML code embedded in your text.
+*
+* In a <a href="command"> ... </a> tag command is executed if the link is
+* click with the left mouse button.
+*
+* Except if command starts with an '#' (ie: href="#value" ) the callback
+* meterClicked is called with value (without the #) as the meter argument.
+*
+* Also inline images work. Unfortunatly currently only when using absolute
+* paths.
+* ARGUMENTS
+* * long widget -- karamba
+* * long richtext -- pointer to richtext
+* * string value -- new text
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_setRichTextValue(PyObject *self, PyObject *args);
+
+/** RichText/getRichTextSensor
+*
+* SYNOPSIS
+* string getRichTextSensor(widget, richtext)
+* DESCRIPTION
+* Get current sensor string
+* ARGUMENTS
+* * long widget -- karamba
+* * long richtext -- pointer to richtext
+* RETURN VALUE
+* sensor string
+*/
+PyObject* py_getRichTextSensor(PyObject *self, PyObject *args);
+
+/** RichText/setRichTextSensor
+*
+* SYNOPSIS
+* long setRichTextSensor(widget, richtext, sensor)
+* DESCRIPTION
+* Get current sensor string
+* ARGUMENTS
+* * long widget -- karamba
+* * long richtext -- pointer to richtext
+* * string sensor -- new sensor as in theme files
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_setRichTextSensor(PyObject *self, PyObject *args);
+
+/** RichText/changeRichTextSize
+*
+* SYNOPSIS
+* long changeRichTextSize(widget, richtext, size)
+* DESCRIPTION
+* This will change the font size of a richtext widget.
+* ARGUMENTS
+* * long widget -- karamba
+* * long richtext -- pointer to richtext
+* * long size -- new font point size
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_setRichTextFontSize(PyObject *self, PyObject *args);
+
+/** RichText/getRichTextFontSize
+*
+* SYNOPSIS
+* long getRichTextFontSize(widget, richtext)
+* DESCRIPTION
+* This will get the font size of a richtext widget.
+* ARGUMENTS
+* * long widget -- karamba
+* * long richtext -- pointer to richtext
+* RETURN VALUE
+* font point size
+*/
+PyObject* py_getRichTextFontSize(PyObject *self, PyObject *args);
+
+/** RichText/changeRichTextFont
+*
+* SYNOPSIS
+* long changeRichTextFont(widget, richtext, font)
+* DESCRIPTION
+* This will change the font of a richtext widget.
+* ARGUMENTS
+* * long widget -- karamba
+* * long richtext -- pointer to richtext
+* * string font -- name of the new font
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_setRichTextFont(PyObject *self, PyObject *args);
+
+/** RichText/getRichTextFont
+*
+* SYNOPSIS
+* string getRichTextFont(widget, richtext)
+* DESCRIPTION
+* This will get the font of a richtext widget.
+* ARGUMENTS
+* * long widget -- karamba
+* * long richtext -- pointer to richtext
+* RETURN VALUE
+* font name
+*/
+PyObject* py_getRichTextFont(PyObject *self, PyObject *args);
+
+/** RichText/setRichTextWidth
+*
+* SYNOPSIS
+* long setRichTextWidth(widget, richtext, width)
+* DESCRIPTION
+* Given a reference to a rich text object, this function changes it's width
+* to the specified value in pixels.
+*
+* The height adjusts automatically as the contents are changed with
+* changeRichText.
+* ARGUMENTS
+* * long widget -- karamba
+* * long richtext -- pointer to richtext
+* * long width -- new width in pixels
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_set_rich_text_width(PyObject* self, PyObject* args);
+
+#endif // RICHTEXTLABEL_PYTHON_H
diff --git a/superkaramba/src/rsssensor.cpp b/superkaramba/src/rsssensor.cpp
new file mode 100644
index 0000000..1477062
--- /dev/null
+++ b/superkaramba/src/rsssensor.cpp
@@ -0,0 +1,136 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Ralph M. Churchill *
+ * mrchucho@yahoo.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+
+#include "karambaapp.h"
+#include "rsssensor.h"
+#include <qdom.h>
+#include <qregexp.h>
+#include <kurl.h>
+#include <kio/netaccess.h>
+
+RssSensor::RssSensor( const QString &src, int interval, const QString &form, const QString &enc)
+ : Sensor(interval),
+ source(src),
+ format(form),
+ encoding(enc)
+
+{
+ // Format:
+ // %t = title (DEFAULT)
+ // %d = desc
+
+ if( !encoding.isEmpty() )
+ {
+ codec = QTextCodec::codecForName( encoding.ascii() );
+ if ( codec == 0)
+ codec = QTextCodec::codecForLocale();
+ }
+ else
+ codec = QTextCodec::codecForLocale();
+}
+
+RssSensor::~RssSensor()
+{
+}
+
+void RssSensor::update()
+{
+ QDomDocument doc;
+ QFile file;
+ QString tmpFile;
+ bool OK = false;
+
+#if defined(KDE_3_3)
+ if(KIO::NetAccess::download(KURL(source), tmpFile, karambaApp->parentWindow()))
+#else
+ if(KIO::NetAccess::download(KURL(source), tmpFile))
+#endif
+ {
+ file.setName(tmpFile);
+ if ( file.open(IO_ReadOnly | IO_Translate) )
+ {
+ if ( doc.setContent( &file ) )
+ {
+ OK = true;
+ }
+ else
+ {
+ qDebug("Error on building DOM");
+ }
+ }
+ else
+ {
+ qDebug("Error opening file");
+ }
+ }
+ else {
+ qDebug( "Error Downloading: %s", source.ascii());
+ }
+
+ if ( OK )
+ {
+ SensorParams *sp;
+ Meter *meter;
+
+ QObjectListIt it( *objList );
+ while (it != 0)
+ {
+ sp = (SensorParams*)(*it);
+ meter = sp->getMeter();
+
+ // this is a hack to force the
+ // clickmap to reset its data lists
+ meter->setValue(0);
+
+ QDomElement docElem = doc.documentElement();
+ QDomNode n = docElem.firstChild();
+ if (!n.isNull())
+ {
+ QDomNodeList links = docElem.elementsByTagName( "link" );
+ QDomNodeList displays;
+ if ( format.contains( "%d", false ) > 0 )
+ {
+ displays = docElem.elementsByTagName( "description" );
+ }
+ else
+ {
+ displays = docElem.elementsByTagName( "title" );
+ }
+
+ QRegExp rx("^http://", false );
+ for (uint i=1; i < displays.count(); ++i )
+ {
+ QString dispTxt = displays.item( i ).toElement().text();
+ QString linkTxt = links.item( i ).toElement().text();
+ if( (rx.search(dispTxt) == -1) && (rx.search(linkTxt) != -1) )
+ {
+ meter->setValue( dispTxt );
+ meter->setValue( linkTxt );
+ }
+ else
+ {
+ qDebug("Skipping");
+ }
+ }
+ }
+ else
+ {
+ qDebug ("Document Node was null!!");
+ }
+
+ ++it;
+ }
+ }
+ // Cleanup
+ file.close();
+ KIO::NetAccess::removeTempFile( tmpFile );
+}
+
+#include "rsssensor.moc"
diff --git a/superkaramba/src/rsssensor.h b/superkaramba/src/rsssensor.h
new file mode 100644
index 0000000..d896d04
--- /dev/null
+++ b/superkaramba/src/rsssensor.h
@@ -0,0 +1,39 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Ralph M. Churchill *
+ * mrchucho@yahoo.com *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef RSSSENSOR_H
+#define RSSSENSOR_H
+
+#include <sensor.h>
+#include <qstring.h>
+#include <qtextcodec.h>
+
+/**
+ *
+ * Ralph M. Churchill
+ **/
+class RssSensor : public Sensor
+{
+ Q_OBJECT
+public:
+ RssSensor( const QString &source, int interval, const QString &format, const QString &encoding=QString::null );
+
+ ~RssSensor();
+
+ void update();
+private:
+ QTextCodec *codec;
+ QString source;
+ QString format;
+ QString encoding;
+
+};
+
+#endif // RSSSENSOR_H
diff --git a/superkaramba/src/sensor.cpp b/superkaramba/src/sensor.cpp
new file mode 100644
index 0000000..6aba5d2
--- /dev/null
+++ b/superkaramba/src/sensor.cpp
@@ -0,0 +1,64 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Hans Karlsson *
+ * karlsson.h@home.se *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "sensor.h"
+Sensor::Sensor(int iMsec)
+{
+ objList = new QObjectList();
+ objList->setAutoDelete( true );
+ msec = iMsec;
+}
+
+void Sensor::start()
+{
+ if (!timer.isActive())
+ {
+ connect (&timer,SIGNAL(timeout()),this,SLOT(update()));
+ timer.start( (msec == 0)?1000:msec);
+ }
+}
+
+Sensor::~Sensor()
+{
+objList->clear();
+delete objList;
+}
+
+void Sensor::addMeter( SensorParams *sp )
+{
+ objList->append(sp);
+}
+
+SensorParams* Sensor::hasMeter( Meter *meter )
+{
+ QObjectListIt it( *objList );
+ while ( it != 0 )
+ {
+ if (((SensorParams*) *it)->getMeter() == meter)
+ {
+ return (SensorParams*) *it;
+ }
+ ++it;
+ }
+ return NULL;
+}
+
+void Sensor::deleteMeter( Meter *meter )
+{
+ SensorParams* sp = hasMeter(meter);
+
+ if (sp)
+ objList->removeRef(sp);
+}
+
+void Sensor::setMaxValue( SensorParams* )
+{
+}
+
+#include "sensor.moc"
diff --git a/superkaramba/src/sensor.h b/superkaramba/src/sensor.h
new file mode 100644
index 0000000..d7368b0
--- /dev/null
+++ b/superkaramba/src/sensor.h
@@ -0,0 +1,47 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Hans Karlsson *
+ * karlsson.h@home.se *
+ * *
+ * 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. *
+ ***************************************************************************/
+#ifndef SENSOR_H
+#define SENSOR_H
+#include <qstring.h>
+#include <qobject.h>
+#include <qobjectlist.h>
+#include <qstringlist.h>
+#include <qmap.h>
+#include <qtimer.h>
+
+#include "sensorparams.h"
+
+class Sensor : public QObject
+{
+ Q_OBJECT
+
+public:
+ Sensor( int msec = 1000 );
+ void start();
+ virtual ~Sensor();
+ void addMeter( SensorParams *s );
+ SensorParams* hasMeter( Meter *meter );
+ void deleteMeter( Meter *meter );
+ int isEmpty() { return objList->isEmpty(); };
+ virtual void setMaxValue( SensorParams *s );
+
+private:
+ int msec;
+ QTimer timer;
+
+protected:
+ QObjectList *objList;
+
+public slots:
+ virtual void update()=0;
+
+};
+
+#endif // SENSOR_H
diff --git a/superkaramba/src/sensorparams.cpp b/superkaramba/src/sensorparams.cpp
new file mode 100644
index 0000000..954b2d5
--- /dev/null
+++ b/superkaramba/src/sensorparams.cpp
@@ -0,0 +1,34 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Hans Karlsson *
+ * karlsson.h@home.se *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "sensorparams.h"
+
+
+SensorParams::SensorParams(Meter* m)
+{
+ meter = m;
+}
+
+SensorParams::~SensorParams()
+{
+}
+
+void SensorParams::addParam( const QString &name, const QString &value){
+ params[name] = value;
+}
+
+QString SensorParams::getParam( const QString &name ) const
+{
+ return params[name];
+}
+
+Meter* SensorParams::getMeter() const
+{
+ return meter;
+}
diff --git a/superkaramba/src/sensorparams.h b/superkaramba/src/sensorparams.h
new file mode 100644
index 0000000..24f0fae
--- /dev/null
+++ b/superkaramba/src/sensorparams.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+ * Copyright (c) 2005 Ryan Nickell <p0z3r@earthlink.net>
+ *
+ * This file is part of SuperKaramba.
+ *
+ * SuperKaramba 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.
+ *
+ * SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+#ifndef SENSORPARAMS_H
+#define SENSORPARAMS_H
+
+#include "meter.h"
+#include <qstring.h>
+#include <qmap.h>
+/**
+ *
+ * Hans Karlsson
+ **/
+class SensorParams : public QObject
+{
+public:
+ SensorParams( Meter* );
+
+ ~SensorParams();
+
+ void addParam( const QString &name, const QString &value);
+ QString getParam( const QString& ) const;
+
+ Meter* getMeter() const;
+private:
+Meter *meter;
+QMap<QString,QString> params;
+
+};
+
+#endif
diff --git a/superkaramba/src/sensorsensor.cpp b/superkaramba/src/sensorsensor.cpp
new file mode 100644
index 0000000..9ff0d47
--- /dev/null
+++ b/superkaramba/src/sensorsensor.cpp
@@ -0,0 +1,115 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Hans Karlsson *
+ * karlsson.h@home.se *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "sensorsensor.h"
+#include <qglobal.h>
+
+SensorSensor::SensorSensor(int interval, char tempUnit) : Sensor( interval )
+{
+#if defined __FreeBSD__ || defined(Q_OS_NETBSD)
+ sensorMapBSD["VCore 1"] = "VC0";
+ sensorMapBSD["VCore 2"] = "VC1";
+ sensorMapBSD["+3.3V"] = "V33";
+ sensorMapBSD["+5V"] = "V50P";
+ sensorMapBSD["+12V"] = "V12P";
+ sensorMapBSD["-12V"] = "V12N";
+ sensorMapBSD["-5V"] = "V50N";
+ sensorMapBSD["fan1"] = "FAN0";
+ sensorMapBSD["fan2"] = "FAN1";
+ sensorMapBSD["fan3"] = "FAN2";
+ sensorMapBSD["temp1"] = "TEMP0";
+ sensorMapBSD["temp2"] = "TEMP1";
+ sensorMapBSD["temp3"] = "TEMP2";
+#endif
+ if(tempUnit == 'F')
+ extraParams = " -f";
+ connect(&ksp, SIGNAL(receivedStdout(KProcess *, char *, int )),
+ this,SLOT(receivedStdout(KProcess *, char *, int )));
+ connect(&ksp, SIGNAL(processExited(KProcess *)),
+ this,SLOT(processExited( KProcess * )));
+
+ // readValues();
+}
+
+
+SensorSensor::~SensorSensor()
+{
+}
+
+void SensorSensor::receivedStdout(KProcess *, char *buffer, int len )
+{
+ buffer[len] = 0;
+ sensorResult += QString( QCString(buffer) );
+}
+
+void SensorSensor::processExited(KProcess *)
+{
+ QStringList stringList = QStringList::split('\n',sensorResult);
+ sensorResult = "";
+ QStringList::Iterator it = stringList.begin();
+#if defined __FreeBSD__ || defined(Q_OS_NETBSD)
+ QRegExp rx( "^(\\S+)\\s+:\\s+[\\+\\-]?(\\d+\\.?\\d*)");
+#else
+ QRegExp rx( "^(.+):\\s+[\\+\\-]?(\\d+\\.?\\d*)");
+#endif
+ while( it != stringList.end())
+ {
+ rx.search( *it );
+
+ if ( !rx.cap(0).isEmpty())
+ {
+ sensorMap[rx.cap(1)] = rx.cap(2);
+ }
+ it++;
+ }
+
+ QString format;
+ QString type;
+ SensorParams *sp;
+ Meter *meter;
+
+ QObjectListIt lit( *objList );
+ while (lit != 0)
+ {
+ sp = (SensorParams*)(*lit);
+ meter = sp->getMeter();
+ format = sp->getParam("FORMAT");
+ type = sp->getParam("TYPE");
+
+ if (type.length() == 0)
+ type = "temp2";
+
+ if (format.length() == 0 )
+ {
+ format = "%v";
+ }
+
+#if defined __FreeBSD__ || defined(Q_OS_NETBSD)
+ format.replace( QRegExp("%v", false), sensorMap[sensorMapBSD[type]]);
+#else
+ format.replace( QRegExp("%v", false), sensorMap[type]);
+#endif
+ meter->setValue(format);
+ ++lit;
+ }
+}
+
+void SensorSensor::update()
+{
+ ksp.clearArguments();
+#if defined __FreeBSD__ || defined(Q_OS_NETBSD)
+ ksp << "mbmon -r -c 1" << extraParams;
+#else
+ ksp << "sensors" << extraParams;
+#endif
+ ksp.start( KProcess::NotifyOnExit,KProcIO::Stdout);
+}
+
+
+#include "sensorsensor.moc"
diff --git a/superkaramba/src/sensorsensor.h b/superkaramba/src/sensorsensor.h
new file mode 100644
index 0000000..82adf10
--- /dev/null
+++ b/superkaramba/src/sensorsensor.h
@@ -0,0 +1,49 @@
+
+#ifndef SENSORSENSOR_H
+#define SENSORSENSOR_H
+
+#include <qstring.h>
+#include <qtextcodec.h>
+#include <qmap.h>
+#include <qstringlist.h>
+#include <qregexp.h>
+#include <kprocess.h>
+#include <kprocio.h>
+
+
+#include "sensor.h"
+
+/**
+ *
+ * Hans Karlsson
+ **/
+class SensorSensor : public Sensor
+{
+ Q_OBJECT
+public:
+ SensorSensor(int interval, char tempUnit);
+
+ ~SensorSensor();
+
+ void update();
+
+
+private:
+ KShellProcess ksp;
+ QString extraParams;
+
+ QMap<QString,QString> sensorMap;
+#ifdef __FreeBSD__
+ QMap<QString,QString> sensorMapBSD;
+#endif
+ QString sensorResult;
+
+private slots:
+ void receivedStdout(KProcess *, char *buffer, int);
+ void processExited(KProcess *);
+
+
+
+};
+
+#endif
diff --git a/superkaramba/src/showdesktop.cpp b/superkaramba/src/showdesktop.cpp
new file mode 100644
index 0000000..304dcb6
--- /dev/null
+++ b/superkaramba/src/showdesktop.cpp
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+ * Copyright (c) 2005 Ryan Nickell <p0z3r@earthlink.net>
+ *
+ * This file is part of SuperKaramba.
+ *
+ * SuperKaramba 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.
+ *
+ * SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+#include <kwinmodule.h>
+#include <netwm.h>
+#include <kwin.h>
+
+#include "karambaapp.h"
+#include "showdesktop.h"
+#include "showdesktop.moc"
+
+ShowDesktop* ShowDesktop::the()
+{
+ static ShowDesktop showDesktop;
+ return &showDesktop;
+}
+
+ShowDesktop::ShowDesktop()
+ : QObject()
+ , showingDesktop( false )
+ , kWinModule( 0 )
+{
+ kWinModule = new KWinModule( this );
+
+ // on desktop changes or when a window is deiconified, we abort the show desktop mode
+ connect( kWinModule, SIGNAL(currentDesktopChanged(int)),
+ SLOT(slotCurrentDesktopChanged(int)));
+ connect( kWinModule, SIGNAL(windowChanged(WId,unsigned int)),
+ SLOT(slotWindowChanged(WId,unsigned int)));
+}
+
+void ShowDesktop::slotCurrentDesktopChanged(int)
+{
+ showDesktop( false );
+}
+
+#ifdef KDE_3_3
+#define NET_ALL_TYPES_MASK (NET::AllTypesMask)
+#else
+#define NET_ALL_TYPES_MASK (-1LU)
+#endif
+
+void ShowDesktop::slotWindowChanged(WId w, unsigned int dirty)
+{
+ if (!showingDesktop)
+ return;
+
+ // SELI this needs checking for kwin_iii (_NET_SHOWING_DESKTOP)
+ if ( dirty & NET::XAWMState )
+ {
+ NETWinInfo inf(qt_xdisplay(), w, qt_xrootwin(),
+ NET::XAWMState | NET::WMWindowType);
+#ifdef KDE_3_2
+ NET::WindowType windowType = inf.windowType(NET_ALL_TYPES_MASK);
+#else
+ NET::WindowType windowType = inf.windowType();
+#endif
+ if ((windowType == NET::Normal || windowType == NET::Unknown)
+ && inf.mappingState() == NET::Visible )
+ {
+ // a window was deiconified, abort the show desktop mode.
+ iconifiedList.clear();
+ showingDesktop = false;
+ emit desktopShown( false );
+ }
+ }
+}
+
+void ShowDesktop::showDesktop( bool b )
+{
+ if( b == showingDesktop ) return;
+ showingDesktop = b;
+
+ if ( b ) {
+ // this code should move to KWin after supporting NETWM1.2
+ iconifiedList.clear();
+ const QValueList<WId> windows = kWinModule->windows();
+ QValueList<WId>::ConstIterator it;
+ QValueList<WId>::ConstIterator end( windows.end() );
+ for ( it=windows.begin(); it!=end; ++it ) {
+ WId w = *it;
+ NETWinInfo info( qt_xdisplay(), w, qt_xrootwin(),
+ NET::XAWMState | NET::WMDesktop );
+ if ( info.mappingState() == NET::Visible &&
+ ( info.desktop() == NETWinInfo::OnAllDesktops
+ || info.desktop() == (int) kWinModule->currentDesktop() )
+ ) {
+ iconifiedList.append( w );
+ }
+ }
+ // find first, hide later, otherwise transients may get minimized
+ // with the window they're transient for
+ QValueList<WId>::ConstIterator endInconifiedList( iconifiedList.end() );
+ for ( it=iconifiedList.begin(); it!=endInconifiedList; ++it ) {
+ KWin::iconifyWindow( *it, false );
+ }
+ } else {
+ QValueList<WId>::ConstIterator it;
+ QValueList<WId>::ConstIterator end( iconifiedList.end() );
+ for ( it=iconifiedList.begin(); it!=end; ++it ) {
+ KWin::deIconifyWindow( *it, false );
+ }
+ }
+
+ emit desktopShown( showingDesktop );
+}
diff --git a/superkaramba/src/showdesktop.h b/superkaramba/src/showdesktop.h
new file mode 100644
index 0000000..6a980dc
--- /dev/null
+++ b/superkaramba/src/showdesktop.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+ * Copyright (c) 2005 Ryan Nickell <p0z3r@earthlink.net>
+ *
+ * This file is part of SuperKaramba.
+ *
+ * SuperKaramba 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.
+ *
+ * SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#ifndef __showdesktop_h__
+#define __showdesktop_h__
+
+class KWinModule;
+
+/**
+ * Singleton class that handles desktop access (minimizing all windows)
+ */
+class ShowDesktop : public QObject
+{
+ Q_OBJECT
+
+public:
+ static ShowDesktop* the();
+ bool desktopShowing() { return showingDesktop; }
+
+public slots:
+ void showDesktop( bool show );
+ void toggle() { showDesktop( !desktopShowing() ); }
+
+signals:
+ void desktopShown( bool shown );
+
+private slots:
+ void slotCurrentDesktopChanged(int);
+ void slotWindowChanged(WId w, unsigned int dirty);
+
+private:
+ ShowDesktop();
+
+ bool showingDesktop;
+ KWinModule* kWinModule;
+ QValueList<WId> iconifiedList;
+
+};
+
+#endif
diff --git a/superkaramba/src/sklineedit.cpp b/superkaramba/src/sklineedit.cpp
new file mode 100644
index 0000000..a384e44
--- /dev/null
+++ b/superkaramba/src/sklineedit.cpp
@@ -0,0 +1,82 @@
+/****************************************************************************
+ * Copyright (c) 2005 Alexander Wiedenbruch <mail@wiedenbruch.de>
+ *
+ * This file is part of SuperKaramba.
+ *
+ * SuperKaramba 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.
+ *
+ * SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#include "sklineedit.h"
+#include "karamba.h"
+#include "kdebug.h"
+
+SKLineEdit::SKLineEdit(QWidget *w, Input *i) : QLineEdit(w), m_input(i)
+{
+ frameColor = Qt::gray;
+ setBackgroundColor(Qt::white);
+}
+
+SKLineEdit::~SKLineEdit()
+{
+}
+
+void SKLineEdit::drawFrame(QPainter *p)
+{
+ p->setPen(frameColor);
+ p->drawRect(frameRect());
+}
+
+void SKLineEdit::drawContents(QPainter *p)
+{
+ QLineEdit::drawContents(p);
+}
+
+void SKLineEdit::setFrameColor(QColor c)
+{
+ frameColor = c;
+ repaint();
+}
+
+void SKLineEdit::setBackgroundColor(QColor c)
+{
+ QLineEdit::setBackgroundColor(c);
+ repaint();
+}
+
+QColor SKLineEdit::getFrameColor() const
+{
+ return frameColor;
+}
+
+void SKLineEdit::keyPressEvent(QKeyEvent* e)
+{
+ QLineEdit::keyPressEvent(e);
+
+ if(!e->text().isEmpty())
+ {
+ karamba* k = static_cast<karamba*>(parent());
+ k->keyPressed(e->text(), m_input);
+ }
+}
+
+void SKLineEdit::keyReleaseEvent(QKeyEvent* e)
+{
+ QLineEdit::keyReleaseEvent(e);
+}
+
+Input* SKLineEdit::getInput()
+{
+ return m_input;
+}
diff --git a/superkaramba/src/sklineedit.h b/superkaramba/src/sklineedit.h
new file mode 100644
index 0000000..2afd6c5
--- /dev/null
+++ b/superkaramba/src/sklineedit.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+ * Copyright (c) 2005 Alexander Wiedenbruch <mail@wiedenbruch.de>
+ *
+ * This file is part of SuperKaramba.
+ *
+ * SuperKaramba 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.
+ *
+ * SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#ifndef SKLINEEDIT_H
+#define SKLINEEDIT_H
+
+#include <qlineedit.h>
+#include <qwidget.h>
+#include <qevent.h>
+#include <qpainter.h>
+#include <qcolor.h>
+
+class Input;
+
+class SKLineEdit : public QLineEdit
+{
+ public:
+ SKLineEdit(QWidget *w, Input *i);
+ ~SKLineEdit();
+
+ void drawFrame(QPainter *p);
+ void drawContents(QPainter *p);
+
+ void setFrameColor(QColor c);
+ QColor getFrameColor() const;
+
+ void setBackgroundColor(QColor c);
+
+ Input* getInput();
+
+ protected:
+ virtual void keyReleaseEvent(QKeyEvent* e);
+ virtual void keyPressEvent(QKeyEvent* e);
+
+ private:
+ QColor frameColor;
+ Input* m_input;
+};
+
+#endif
diff --git a/superkaramba/src/sknewstuff.cpp b/superkaramba/src/sknewstuff.cpp
new file mode 100644
index 0000000..bf16fe6
--- /dev/null
+++ b/superkaramba/src/sknewstuff.cpp
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2005 Ryan Nickell <p0z3r @ earthlink . net>
+ *
+ * This file is part of SuperKaramba.
+ *
+ * SuperKaramba 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.
+ *
+ * SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#include <kapplication.h>
+#include <kdebug.h>
+#include <kfilemetainfo.h>
+#include <kio/netaccess.h>
+#include <kmimetype.h>
+#include <krun.h>
+#include <kstandarddirs.h>
+#include <ktar.h>
+#include <kurl.h>
+#include <qdir.h>
+#include <qfileinfo.h>
+
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
+#include "karambaapp.h"
+#include "themesdlg.h"
+#ifdef HAVE_KNEWSTUFF
+#include "sknewstuff.h"
+
+SKNewStuff::SKNewStuff( ThemesDlg *dlg ) :
+ KNewStuff( "superkaramba/themes", dlg ),
+ mDlg( dlg )
+{
+}
+
+bool SKNewStuff::install( const QString &fileName )
+{
+ kdDebug() << "SKNewStuff::install(): " << fileName << endl;
+
+ KMimeType::Ptr result = KMimeType::findByURL(fileName);
+ KStandardDirs myStdDir;
+ QFileInfo fi(fileName);
+ QString base = fi.baseName();
+ QString baseDestDir =myStdDir.saveLocation("data", kapp->instanceName() + "/themes/", true);
+ const QString destDir = baseDestDir + base + "/";
+ KStandardDirs::makeDir( destDir );
+
+ kdDebug() << "SKNewStuff::install() mimetype: " << result->name() << endl;
+
+ if( result->name() == "application/x-gzip" ||
+ result->name() == "application/x-tgz" ||
+ result->name() == "application/x-bzip" ||
+ result->name() == "application/x-bzip2" ||
+ result->name() == "application/x-tbz" ||
+ result->name() == "application/x-tbz2" ||
+ result->name() == "application/x-tar" ||
+ result->name() == "application/x-tarz")
+ {
+ kdDebug() << "SKNewStuff::install() gzip/bzip2 mimetype encountered" <<
+ endl;
+ KTar archive( fileName );
+ if ( !archive.open( IO_ReadOnly ) )
+ return false;
+ const KArchiveDirectory *archiveDir = archive.directory();
+ archiveDir->copyTo(destDir);
+ //Add the theme to the Theme Dialog
+ mDlg->addThemeToDialog(archiveDir, destDir);
+ archive.close();
+ }
+ else if(result->name() == "application/x-zip" ||
+ result->name() == "application/x-superkaramba")
+ {
+ kdDebug() << "SKNewStuff::install() zip mimetype encountered" << endl;
+ //TODO: write a routine to check if this is a valid .skz file
+ //otherwise we need to unpack it like it is an old theme that was packaged
+ //as a .zip instead of .bz2 or .tar.gz
+ KURL sourceFile(fileName);
+ KURL destFile( destDir + sourceFile.fileName() );
+ if(!KIO::NetAccess::file_copy( sourceFile, destFile ))
+ {
+ return false;
+ }
+ KIO::NetAccess::removeTempFile( sourceFile.url() );
+ //Add the skz theme to the Theme Dialog
+ mDlg->addSkzThemeToDialog(destFile.path());
+ }
+ else if(result->name() == "plain/text")
+ {
+ kdDebug() << "SKNewStuff::install() plain text" << endl;
+ }
+ else if(result->name() == "text/html")
+ {
+ kdDebug() << "SKNewStuff::install() text/html" << endl;
+ KRun::runURL( m_sourceLink, "text/html");
+ }
+ else
+ {
+ kdDebug() << "SKNewStuff::install() Error no compatible mimetype encountered to install"
+ << endl;
+ return false;
+ }
+ return true;
+}
+
+bool SKNewStuff::createUploadFile( const QString &fileName )
+{
+ kdDebug() << "SKNewStuff::createUploadFile(): " << fileName << endl;
+ return true;
+}
+
+QString SKNewStuff::downloadDestination( KNS::Entry *entry )
+{
+ KURL source = entry->payload();
+ m_sourceLink = source;
+
+ kdDebug() << "SKNewStuff::downloadDestination() url: "
+ << source.url() << " fileName: " << source.fileName() << endl;
+ QString file(source.fileName());
+ if ( file.isEmpty() )
+ {
+ kdDebug() << "The file was empty. " << source.url() <<
+ " must be a URL link." << endl;
+ KRun::runURL( source, "text/html");
+ return file;
+ }
+ return KGlobal::dirs()->saveLocation( "tmp" ) + source.fileName();
+}
+#endif //HAVE_KNEWSTUFF
diff --git a/superkaramba/src/sknewstuff.h b/superkaramba/src/sknewstuff.h
new file mode 100644
index 0000000..c646f36
--- /dev/null
+++ b/superkaramba/src/sknewstuff.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2005 Ryan Nickell <p0z3r @ earthlink . net>
+ *
+ * This file is part of SuperKaramba.
+ *
+ * SuperKaramba 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.
+ *
+ * SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#ifndef SKNEWSTUFF_H
+#define SKNEWSTUFF_H
+
+#include <kurl.h>
+#include "karambaapp.h"
+
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
+#ifdef HAVE_KNEWSTUFF
+#include "knewstuff/knewstuff.h"
+#include "knewstuff/entry.h"
+
+class ThemesDlg;
+class KArchiveDirectory;
+
+class SKNewStuff : public KNewStuff
+{
+ public:
+ SKNewStuff( ThemesDlg * );
+
+ bool install( const QString &fileName );
+ bool createUploadFile( const QString &fileName );
+ QString downloadDestination( KNS::Entry *entry );
+
+ private:
+ ThemesDlg *mDlg;
+ KURL m_sourceLink;
+};
+
+#endif //HAVE_KNEWSTUFF
+#endif //SKNEWSTUFF_H
diff --git a/superkaramba/src/superkaramba.desktop b/superkaramba/src/superkaramba.desktop
new file mode 100644
index 0000000..77d54f5
--- /dev/null
+++ b/superkaramba/src/superkaramba.desktop
@@ -0,0 +1,99 @@
+[Desktop Entry]
+Name=SuperKaramba
+Name[ar]=سوبركارامبا
+Name[is]=SúperKaramba
+Name[ne]=सुपरकराम्बा
+Name[sr]=СуперКарамба
+Exec=superkaramba %U
+Icon=superkaramba
+Type=Application
+MimeType=application/x-superkaramba;
+Comment=An engine for cool desktop eyecandy.
+Comment[ar]=محرك لجماليات سطح مكتب لطيفة.
+Comment[bg]=Модул за разкрасяване на работния плот
+Comment[bs]=Pogon za cool ukrase desktopa.
+Comment[ca]=Un motor per fer més vistós l'escriptori.
+Comment[cs]=Nástroj pro úžasnou pracovní plochu, která je pastvou pro oči.
+Comment[da]=En grænseflade for lækre øjegodter på desktoppen.
+Comment[de]=Infrastruktur für faszinierende optische Effekte
+Comment[el]=Μία μηχανή για εντυπωσιακές διακοσμήσεις επιφάνειας εργασίας.
+Comment[es]=Un motor para añadir vistosidad al escritorio.
+Comment[et]=Töölaua lahedate vidinate mootor.
+Comment[eu]=Mahaigaineko efektu politentzako euskarri bat.
+Comment[fa]=eyecandy موتوری برای سرد کردن رومیزی.
+Comment[fi]=Työpöydän hieno koristelu.
+Comment[fr]=Un moteur de bureau esthétique et sympathique
+Comment[he]=מנוע שהופך את שולחן העבודה למגניב.
+Comment[hu]=Keretrendszer grafikus asztali elemek használatához.
+Comment[is]=Flottar skjáborðsviðbætur.
+Comment[it]=Un motore per rendere il desktop più gradevole.
+Comment[ja]=格好いいデスクトップ eyecandy エンジン。
+Comment[kk]=Үстелдің әсем бөлшектері.
+Comment[km]=ម៉ាស៊ីន​សម្រាប់​កម្មវិធី​ត្រជាក់​ភ្នែក​របស់​ផ្ទៃតុ
+Comment[lt]=Šaunių darbastalio papuošimų priedas.
+Comment[nb]=Et program for kule skrivebordseffekter.
+Comment[nds]=En Ümgeven för wunnerbore Schriefdischeffekten.
+Comment[ne]=ठन्डा डेस्कटप आइक्यान्डीका लागि इन्जिन ।
+Comment[nl]=Een programma voor bureaubladverfraaiing.
+Comment[nn]=Eit rammeverk for lekre skrivebord.
+Comment[pl]=Narzędzie do tworzenia efektownego pulpitu.
+Comment[pt]=Um motor para embelezar o ecrã.
+Comment[pt_BR]=Mecanismo para recursos gráficos interessantes.
+Comment[ru]=Набор виджетов рабочего стола.
+Comment[sk]=Podpora pre cool desktop eyecandy.
+Comment[sl]=Pogon za lišpanje namizja.
+Comment[sr]=Машина за лицкање радне површине.
+Comment[sr@Latn]=Mašina za lickanje radne površine.
+Comment[sv]=Ett gränssnitt för häftigt ögongodis på skrivbordet.
+Comment[tr]=Masaüstünde güzel görünüm sağlayan bir motor.
+Comment[uk]=Рушій для елементів стільниці.
+Comment[zh_CN]=桌面养眼引擎。
+Comment[zh_TW]=桌面佈景選擇程式
+GenericName=Desktop Widgets
+GenericName[ar]=أدوات سطح المكتب
+GenericName[bg]=Графични контроли
+GenericName[bs]=Desktop ukrasi
+GenericName[ca]=Estris de l'escriptori
+GenericName[cs]=Udělátka pro pracovní plochu
+GenericName[da]=Desktopkontroller
+GenericName[de]=Arbeitsflächen-Erweiterungen
+GenericName[el]=Γραφικά συστατικά επιφάνειας εργασίας
+GenericName[eo]=Tabulaj fenestraĵoj
+GenericName[es]=Elementos visuales para el escritorio
+GenericName[et]=Töölauavidinad
+GenericName[eu]=Mahaigaineko trepetak
+GenericName[fa]=عنصرهای رومیزی
+GenericName[fi]=Työpöytäelementit
+GenericName[fr]=Éléments graphiques pour le bureau
+GenericName[ga]=Giuirléidí Deisce
+GenericName[he]=יישומונים על שולחן העבודה
+GenericName[hu]=Asztali programelemek
+GenericName[is]=Skjáborðshlutir
+GenericName[it]=Elementi desktop
+GenericName[ja]=デスクトップウィジェット
+GenericName[ka]=სამუშაო მაგიდის ელემენტები
+GenericName[kk]=Үстелдің бөлшектері
+GenericName[km]=វត្ថុ​មើលឃើញ​របស់​ផ្ទៃតុ
+GenericName[lt]=Darbastalio valdikliai
+GenericName[nb]=Skjermelement for skrivebordet
+GenericName[nds]=Schriefdisch-Verwiedern
+GenericName[ne]=डेस्कटप विजेट
+GenericName[nl]=Bureaubladprogramma's
+GenericName[nn]=Skrivebordsprogram
+GenericName[pa]=ਵੇਹੜਾ ਸਹਾਇਕ
+GenericName[pl]=Aplety pulpitu
+GenericName[pt]=Elementos do Ecrã
+GenericName[pt_BR]=Componentes para o Desktop
+GenericName[ru]=Виджеты рабочего стола
+GenericName[sk]=Prvky pracovnej plochy
+GenericName[sl]=Namizni gradniki
+GenericName[sr]=Додаци десктопа
+GenericName[sr@Latn]=Dodaci desktopa
+GenericName[sv]=Grafiska skrivbordskomponenter
+GenericName[tr]=Masaüstü Ögeleri
+GenericName[uk]=Віджети стільниці
+GenericName[zh_CN]=桌面部件
+GenericName[zh_TW]=桌面元件
+DocPath=superkaramba/index.html
+Categories=Qt;KDE;Utility;X-KDE-Utilities-Desktop;
+OnlyShowIn=KDE;
diff --git a/superkaramba/src/superkaramba.kcfg b/superkaramba/src/superkaramba.kcfg
new file mode 100644
index 0000000..c586b3c
--- /dev/null
+++ b/superkaramba/src/superkaramba.kcfg
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE kcfg SYSTEM "http://www.kde.org/standards/kcfg/1.0/kcfg.dtd">
+<kcfg>
+ <kcfgfile name="superkarambarc"/>
+ <group name="general">
+ <entry name="ShowSysTray" type="Bool">
+ <label>Show system tray icon.</label>
+ <default>true</default>
+ </entry>
+ </group>
+ <group name="themes">
+ <entry name="UserAddedThemes" type="PathList">
+ <label>Themes that user added to theme list.</label>
+ </entry>
+ </group>
+</kcfg>
diff --git a/superkaramba/src/superkaramba.lsm b/superkaramba/src/superkaramba.lsm
new file mode 100644
index 0000000..614fc65
--- /dev/null
+++ b/superkaramba/src/superkaramba.lsm
@@ -0,0 +1,16 @@
+Begin3
+Title: SuperKaramba - Eye-candy for KDE
+Version: 0.40
+Entered-date:
+Description:
+Keywords: KDE3 Qt
+Author: Hans Karlsson <karlsson.h@home.se>
+Maintained-by: Adam Geitgey <adam@rootnode.org>
+Home-page: http://netdragon.sourceforge.net/ssuperkaramba.html
+Alternate-site:
+Primary-site: http://netdragon.sourceforge.net/ssuperkaramba.html
+ xxxxxx superkaramba-0.40.tar.gz
+ xxx superkaramba-0.40.lsm
+Platform: Linux. Needs KDE 3.? QT 3.?
+Copying-policy: GPL
+End
diff --git a/superkaramba/src/superkarambasettings.kcfgc b/superkaramba/src/superkarambasettings.kcfgc
new file mode 100644
index 0000000..deb102f
--- /dev/null
+++ b/superkaramba/src/superkarambasettings.kcfgc
@@ -0,0 +1,4 @@
+File=superkaramba.kcfg
+ClassName=SuperKarambaSettings
+Singleton=true
+Mutators=true \ No newline at end of file
diff --git a/superkaramba/src/superkarambaui.rc b/superkaramba/src/superkarambaui.rc
new file mode 100644
index 0000000..fcecdab
--- /dev/null
+++ b/superkaramba/src/superkarambaui.rc
@@ -0,0 +1,8 @@
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+<kpartgui name="superkaramba" version="1">
+<MenuBar>
+ <Menu name="custom"><text>C&amp;ustom</text>
+ <Action name="custom_action" />
+ </Menu>
+</MenuBar>
+</kpartgui>
diff --git a/superkaramba/src/svcgrp_python.cpp b/superkaramba/src/svcgrp_python.cpp
new file mode 100644
index 0000000..5a59c82
--- /dev/null
+++ b/superkaramba/src/svcgrp_python.cpp
@@ -0,0 +1,156 @@
+/***************************************************************************
+ * *
+ * Copyright (C) 2004 Luke Kenneth Casson Leighton <lkcl@lkcl.net> *
+ * *
+ * contains code from kickermenu: *
+ * *
+ * Copyright (C) 2004 by Tommy Brander *
+ * tbr00001@student.mdh.se *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifdef _XOPEN_SOURCE
+#undef _XOPEN_SOURCE
+#endif
+
+#include <Python.h>
+#include "task_python.h"
+#include <qobject.h>
+#include <kservicegroup.h>
+#include "karamba.h"
+#include "svcgrp_python.h"
+
+static PyObject *get_svc_grp(KServiceGroup::Ptr const& g)
+{
+ //Avoid adding empty groups.
+ KServiceGroup::Ptr subMenuRoot = KServiceGroup::group(g->relPath());
+ if (subMenuRoot->childCount() == 0)
+ return NULL;
+ // Ignore dotfiles.
+ if ((g->name().at(0) == '.'))
+ return NULL;
+
+ PyObject *tuple = PyTuple_New(2);
+ PyObject *dict = PyDict_New();
+
+ PyDict_SetItem(dict, PyString_FromString("caption"),
+ PyString_FromString(g->caption().ascii()));
+ if (g->comment() != NULL)
+ PyDict_SetItem(dict, PyString_FromString("comment"),
+ PyString_FromString(g->comment().ascii()));
+ if (g->icon() != NULL)
+ PyDict_SetItem(dict, PyString_FromString("icon"),
+ PyString_FromString(g->icon().ascii()));
+ PyDict_SetItem(dict, PyString_FromString("relpath"),
+ PyString_FromString(g->relPath().ascii()));
+
+ PyTuple_SET_ITEM(tuple, 0, Py_BuildValue((char*)"l", 0));
+ PyTuple_SET_ITEM(tuple, 1, dict);
+
+ return tuple;
+}
+
+
+static PyObject *get_svc(KService::Ptr const& g)
+{
+ PyObject *tuple = PyTuple_New(2);
+ PyObject *dict = PyDict_New();
+
+ if (g->exec() != NULL)
+ PyDict_SetItem(dict, PyString_FromString("exec"),
+ PyString_FromString(g->exec().ascii()));
+ if (g->menuId() != NULL)
+ PyDict_SetItem(dict, PyString_FromString("menuid"),
+ PyString_FromString(g->menuId().ascii()));
+ if (g->name() != NULL)
+ PyDict_SetItem(dict, PyString_FromString("name"),
+ PyString_FromString(g->name().ascii()));
+ if (g->path() != NULL)
+ PyDict_SetItem(dict, PyString_FromString("path"),
+ PyString_FromString(g->path().ascii()));
+ if (g->icon() != NULL)
+ PyDict_SetItem(dict, PyString_FromString("icon"),
+ PyString_FromString(g->icon().ascii()));
+ if (g->library() != NULL)
+ PyDict_SetItem(dict, PyString_FromString("library"),
+ PyString_FromString(g->library().ascii()));
+ if (g->comment() != NULL)
+ PyDict_SetItem(dict, PyString_FromString("comment"),
+ PyString_FromString(g->comment().ascii()));
+ if (g->type() != NULL)
+ PyDict_SetItem(dict, PyString_FromString("type"),
+ PyString_FromString(g->type().ascii()));
+ if (g->genericName() != NULL)
+ PyDict_SetItem(dict, PyString_FromString("genericname"),
+ PyString_FromString(g->genericName().ascii()));
+ /*
+ PyDict_SetItem(dict, PyString_FromString("terminal"),
+ Py_BuildValue("l", g->terminal()));
+ PyDict_SetItem(dict, PyString_FromString("type"),
+ PyString_FromString(g->type().ascii()));
+ PyDict_SetItem(dict, PyString_FromString("username"),
+ PyString_FromString(g->username().ascii()));
+ PyDict_SetItem(dict, PyString_FromString("substuid"),
+ Py_BuildValue("l", g->substituteUid()));
+ PyDict_SetItem(dict, PyString_FromString("path"),
+ PyString_FromString(g->path().ascii()));
+ */
+
+ PyTuple_SET_ITEM(tuple, 0, Py_BuildValue((char*)"l", 1));
+ PyTuple_SET_ITEM(tuple, 1, dict);
+
+ return tuple;
+}
+
+static PyObject *getServiceGroups(const char *rel_path)
+{
+ PyObject *list = PyList_New(0);
+
+ // We ask KSycoca to give us all services (sorted).
+ KServiceGroup::Ptr root = KServiceGroup::group(rel_path);
+
+ if (!root || !root->isValid())
+ return list;
+
+ bool excludeNoDisplay_ = true;
+ bool detailed_ = false;
+ bool detailedNamesFirst_ = false;
+
+ KServiceGroup::List sl = root->entries(true, excludeNoDisplay_, true, detailed_ && !detailedNamesFirst_);
+
+ QStringList suppressGenericNames = root->suppressGenericNames();
+
+ KServiceGroup::List::ConstIterator it = sl.begin();
+ for (; it != sl.end(); ++it)
+ {
+ KSycocaEntry * e = *it;
+
+ PyObject *tuple = NULL;
+ if (e->isType(KST_KServiceGroup)) {
+ KServiceGroup::Ptr g(static_cast<KServiceGroup *>(e));
+ tuple = get_svc_grp(g);
+ }
+ else if (e->isType(KST_KService)) {
+ KService::Ptr g(static_cast<KService *>(e));
+ tuple = get_svc(g);
+ }
+
+ if (tuple != NULL)
+ PyList_Append(list, tuple);
+ }
+
+ return list;
+}
+
+PyObject* py_get_service_groups(PyObject *, PyObject *args)
+{
+ char *rel_path;
+ if (!PyArg_ParseTuple(args, (char*)"s:getServiceGroup", &rel_path))
+ return NULL;
+ return getServiceGroups(rel_path);
+}
+
diff --git a/superkaramba/src/svcgrp_python.h b/superkaramba/src/svcgrp_python.h
new file mode 100644
index 0000000..e8d4e4b
--- /dev/null
+++ b/superkaramba/src/svcgrp_python.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ * Copyright (C) 2004 Luke Kenneth Casson Leighton <lkcl@lkcl.net> *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef SVC_GRPS_PYTHON_H
+#define SVC_GRPS_PYTHON_H
+
+#include <Python.h>
+
+//****p* Misc/getServiceGroups
+//
+// SYNOPSIS
+// list getServiceGroups(widget, path)
+// DESCRIPTION
+// This function returns a list of services and service groups
+// that are in the user's KDE Menu. It is not a recursive
+// function, so if there are submenus (service groups) in the
+// returned results, you must call getServiceGroups with the
+// path of the submenu in order to obtain the information in
+// that submenu.
+// The return result is complex: it's a list of tuples.
+// The tuple contains two elements - a 1 if the second element
+// is a service, and a 0 if it's a service group.
+// The second element is a dictionary, with keys (if they exist)
+// of caption, comment, icon, and relpath if it's a service group,
+// and keys (if they exist) of exec, menuid, name, path, icon,
+// library, comment, type and genericname.
+// To fully understand the return results of this function,
+// it is thoroughly recommended // that you look up the
+// KDE documentation on KServiceGroup and KService.
+// ARGUMENTS
+// * long widget -- karamba
+// * string path -- path to the Service Group you wish to retrieve
+// RETURN VALUE
+// List of Dictionaries of services and service groups
+//***
+PyObject* py_get_service_groups(PyObject *self, PyObject *args);
+
+#endif // SVC_GRPS_PYTHON_H
diff --git a/superkaramba/src/systemtray.cpp b/superkaramba/src/systemtray.cpp
new file mode 100644
index 0000000..312fe59
--- /dev/null
+++ b/superkaramba/src/systemtray.cpp
@@ -0,0 +1,231 @@
+/***************************************************************************
+ copyright (C) 2003 Adam Geitgey <adam@rootnode.org>
+ 2003 Sven Leiber <s.leiber@web.de>
+ 2000-2001 Matthias Ettrich <ettrich@kde.org>
+ 2000-2001 Matthias Elter <elter@kde.org>
+ 2001 Carsten Pfeiffer <pfeiffer@kde.org>
+ 2001 Martijn Klingens <mklingens@yahoo.com>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "systemtray.h"
+
+
+#include <qobject.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kwinmodule.h>
+#include <kmessagebox.h>
+#include <kdebug.h>
+#include <kwin.h>
+
+#include <qpopupmenu.h>
+#include <qdragobject.h>
+#include <qlayout.h>
+#include <qstringlist.h>
+#include <qpixmap.h>
+
+#include <X11/Xlib.h>
+
+Systemtray::Systemtray(QWidget* parent)
+ : QWidget(parent,0,0)
+{
+ setBackgroundOrigin(ParentOrigin);
+ setBackgroundMode(FixedPixmap);
+ m_Wins.setAutoDelete(true);
+}
+
+
+Systemtray::~Systemtray()
+{
+ m_Wins.clear();
+}
+
+int Systemtray::getTraySize() {
+
+ return (int) kwin_module->systemTrayWindows().size();
+}
+
+void Systemtray::updateBackgroundPixmap ( const QPixmap & pixmap) {
+ QXEmbed *emb;
+ setPaletteBackgroundPixmap (pixmap);
+ for (emb = m_Wins.first(); emb != 0L; emb = m_Wins.next()) {
+
+ //Stupid stupid stupid work around for annoying bug
+ //QXEmbed ignores setBackgroundOrigin(AncestorOrigin)....
+ QPixmap bug = QPixmap(emb->size());
+ bitBlt(&bug, 0, 0, &pixmap, emb->parentWidget()->x()+emb->x(), emb->parentWidget()->y()+emb->y(), emb->width(), emb->height(),Qt::CopyROP, false);
+ emb->setPaletteBackgroundPixmap (bug);
+
+ }
+
+ QPoint topPoint = mapToGlobal(QPoint(0,0));
+ Window hack = XCreateSimpleWindow(qt_xdisplay(), winId(), 0,0, width(), height(), 0, 0, 0);
+ XRaiseWindow(qt_xdisplay(), hack);
+ XMapWindow(qt_xdisplay(), hack);
+ XUnmapWindow(qt_xdisplay(), hack);
+ XDestroyWindow(qt_xdisplay(), hack);
+}
+
+void Systemtray::initSystray( void )
+{
+ bool existing = false;
+ //bool content = false;
+ Display *display = qt_xdisplay();
+ no_of_systray_windows = 0;
+
+ kwin_module = new KWinModule();
+ systemTrayWindows = kwin_module->systemTrayWindows();
+ QValueList<WId>::ConstIterator end(systemTrayWindows.end());
+ for (QValueList<WId>::ConstIterator it = systemTrayWindows.begin(); it!=end; ++it)
+ {
+ no_of_systray_windows++;
+ QXEmbed *emb;
+
+ emb = new QXEmbed(this);
+ emb->setBackgroundMode(FixedPixmap);
+
+ emb->setAutoDelete(false);
+
+ connect(emb, SIGNAL(embeddedWindowDestroyed()), SLOT(updateTrayWindows()));
+
+ m_Wins.append(emb);
+
+ emb->embed(*it);
+ emb->resize(24, 24);
+ emb->show();
+ existing = true;
+ }
+
+ updateTrayWindows();
+
+ connect(kwin_module, SIGNAL(systemTrayWindowAdded(WId)), SLOT(systemTrayWindowAdded(WId)));
+ connect(kwin_module, SIGNAL(systemTrayWindowRemoved(WId)), SLOT(systemTrayWindowRemoved(WId)));
+
+ QCString screenstr;
+ screenstr.setNum(qt_xscreen());
+ QCString trayatom = "_NET_SYSTEM_TRAY_S" + screenstr;
+
+ net_system_tray_selection = XInternAtom( display, trayatom, false );
+ net_system_tray_opcode = XInternAtom( display, "_NET_SYSTEM_TRAY_OPCODE", false );
+
+ // Acquire system tray
+ XSetSelectionOwner( display,
+ net_system_tray_selection,
+ winId(),
+ CurrentTime );
+
+ WId root = qt_xrootwin();
+
+ if (XGetSelectionOwner(display, net_system_tray_selection) == winId())
+ {
+ XClientMessageEvent xev;
+
+ xev.type = ClientMessage;
+ xev.window = root;
+
+ xev.message_type = XInternAtom(display, "MANAGER", false);
+ xev.format = 32;
+
+ xev.data.l[0] = CurrentTime;
+ xev.data.l[1] = net_system_tray_selection;
+ xev.data.l[2] = winId();
+ xev.data.l[3] = 0; /* Manager specific data */
+ xev.data.l[4] = 0; /* Manager specific data */
+
+ XSendEvent( display, root, false, StructureNotifyMask, (XEvent *)&xev );
+ }
+}
+
+void Systemtray::updateTrayWindows( void )
+{
+ QXEmbed *emb;
+
+ emb = m_Wins.first();
+ while ((emb = m_Wins.current()) != 0L)
+ {
+ WId wid = emb->embeddedWinId();
+ if ((wid == 0) || !kwin_module->systemTrayWindows().contains(wid) )
+ m_Wins.remove(emb);
+ else
+ m_Wins.next();
+ }
+ layoutSystray();
+}
+void Systemtray::layoutSystray()
+{
+ int i = 0, a = 0;
+
+ QXEmbed* emb;
+ int x = 0;
+ int count = 0;
+
+ //How many systray icons can fit on a line?
+ int aa = width() / 24;
+
+ if(aa < 1)
+ {
+ /* The place is to small to display a icon we make than one line with
+ icons that we display at the top */
+ aa = 1;
+ }
+
+ for (emb = m_Wins.first(); emb != 0L; emb = m_Wins.next()) {
+ x = 2+i*24;
+
+ emb->move(a*24, x);
+ a++;
+
+ if(a+1 > aa) {
+ a = 0;
+ i++;
+ }
+
+ count++;
+ emb->repaint();
+ }
+}
+
+void Systemtray::systemTrayWindowAdded( WId w )
+{
+ //bool content = false;
+ QXEmbed *emb;
+ no_of_systray_windows++;
+ emit updated();
+
+ emb = new QXEmbed(this);
+
+ emb->setAutoDelete(false);
+ //emb->setBackgroundMode(X11ParentRelative);
+ emb->setBackgroundMode(FixedPixmap);
+ connect(emb, SIGNAL(embeddedWindowDestroyed()), SLOT(updateTrayWindows()));
+ m_Wins.append(emb);
+
+ emb->embed(w);
+ emb->resize(24, 24);
+ emb->show();
+
+ layoutSystray();
+}
+
+void Systemtray::systemTrayWindowRemoved(WId)
+{
+ no_of_systray_windows--;
+ emit updated();
+ updateTrayWindows();
+}
+
+int Systemtray::getCurrentWindowCount()
+{
+ return no_of_systray_windows;
+}
+
+#include "systemtray.moc"
diff --git a/superkaramba/src/systemtray.h b/superkaramba/src/systemtray.h
new file mode 100644
index 0000000..768e00c
--- /dev/null
+++ b/superkaramba/src/systemtray.h
@@ -0,0 +1,69 @@
+/*
+ ***************************************************************************
+ copyright (C) 2003 Adam Geitgey <adam@rootnode.org>
+ 2003 Sven Leiber <s.leiber@web.de>
+ 2000-2001 Matthias Ettrich <ettrich@kde.org>
+ 2000-2001 Matthias Elter <elter@kde.org>
+ 2001 Carsten Pfeiffer <pfeiffer@kde.org>
+ 2001 Martijn Klingens <mklingens@yahoo.com>
+ ***************************************************************************
+
+ ***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************
+ */
+
+#ifndef TESTCARDAPPLET_H
+#define TESTCARDAPPLET_H
+
+#include <qobject.h>
+#include <qpixmap.h>
+#include <qptrlist.h>
+#include <qxembed.h>
+
+class KWinModule;
+
+typedef long unsigned int Atom;
+
+
+class Systemtray : public QWidget
+{
+ Q_OBJECT
+public:
+ Systemtray(QWidget* parent);
+ ~Systemtray();
+
+ void updateBackgroundPixmap ( const QPixmap & );
+
+ int getCurrentWindowCount();
+
+ virtual void initSystray( void );
+
+public slots:
+ void updateTrayWindows();
+ int getTraySize();
+ void systemTrayWindowAdded( WId w );
+ void systemTrayWindowRemoved( WId w );
+ void layoutSystray();
+
+signals:
+ void updated();
+
+private:
+ KWinModule *kwin_module;
+ QValueList<WId> systemTrayWindows;
+
+ QPtrList<QXEmbed> m_Wins;
+
+ Atom net_system_tray_selection;
+ Atom net_system_tray_opcode;
+
+ int no_of_systray_windows;
+};
+
+#endif
diff --git a/superkaramba/src/systray_python.cpp b/superkaramba/src/systray_python.cpp
new file mode 100644
index 0000000..cb8909a
--- /dev/null
+++ b/superkaramba/src/systray_python.cpp
@@ -0,0 +1,199 @@
+/****************************************************************************
+* systray_python.h - Functions for systray python api
+*
+* Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+* Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+* Copyright (c) 2004 Petri Damstn <damu@iki.fi>
+*
+* This file is part of SuperKaramba.
+*
+* SuperKaramba 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.
+*
+* SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+#ifdef _XOPEN_SOURCE
+#undef _XOPEN_SOURCE
+#endif
+
+#include <Python.h>
+#include <qobject.h>
+#include "karamba.h"
+#include "meter.h"
+#include "meter_python.h"
+#include "systray_python.h"
+
+long moveSystray(long widget, long x, long y, long w, long h)
+{
+ karamba* currTheme = (karamba*)widget;
+
+ if (currTheme->systray != 0) {
+ currTheme->systray->move((int)x,(int)y);
+ currTheme->systray->setMinimumSize((int)w,(int)h);
+ currTheme->systray->layoutSystray();
+ currTheme->systray->show();
+ }
+ return 1;
+}
+
+PyObject* py_move_systray(PyObject *, PyObject *args)
+{
+ long widget, x, y, w, h;
+ if (!PyArg_ParseTuple(args, (char*)"lllll:moveSystray", &widget, &x, &y, &w, &h))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ return Py_BuildValue((char*)"l", moveSystray(widget, x, y, w, h));
+}
+
+/* now a method we need to expose to Python */
+long showSystray(long widget)
+{
+ karamba* currTheme = (karamba*)widget;
+
+ if (currTheme->systray != 0)
+ {
+ currTheme->systray->show();
+ }
+ return 1;
+}
+
+PyObject* py_show_systray(PyObject *, PyObject *args)
+{
+ long widget;
+ if (!PyArg_ParseTuple(args, (char*)"l:showSystray", &widget))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ return Py_BuildValue((char*)"l", showSystray(widget));
+}
+
+/* now a method we need to expose to Python */
+long hideSystray(long widget)
+{
+ karamba* currTheme = (karamba*)widget;
+
+ if (currTheme->systray != 0)
+ {
+ currTheme->systray->hide();
+ }
+ return 1;
+}
+
+PyObject* py_hide_systray(PyObject *, PyObject *args)
+{
+ long widget;
+ if (!PyArg_ParseTuple(args, (char*)"l:hideSystray", &widget))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ return Py_BuildValue((char*)"l", hideSystray(widget));
+}
+
+/* now a method we need to expose to Python */
+long createSystray(long widget, long x, long y, long w, long h)
+{
+ karamba* currTheme = (karamba*)widget;
+
+ //Don't create more than one systray
+ if (currTheme->systray == 0) {
+ currTheme->systray = new Systemtray(currTheme);
+ currTheme->systray->move((int)x,(int)y);
+ currTheme->systray->setMinimumSize((int)w,(int)h);
+ currTheme->systray->initSystray();
+ QObject::connect(currTheme->systray,SIGNAL(updated()),
+ currTheme,SLOT(systrayUpdated()));
+ currTheme->systray->show();
+ }
+
+ return 1;
+}
+
+PyObject* py_create_systray(PyObject *, PyObject *args)
+{
+ long widget, x, y, w, h;
+ if (!PyArg_ParseTuple(args, (char*)"lllll:createSystray", &widget, &x, &y, &w, &h))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ return Py_BuildValue((char*)"l", createSystray(widget, x, y, w, h));
+}
+
+/* now a method we need to expose to Python */
+long getCurrentWindowCount(long widget)
+{
+ karamba* currTheme = (karamba*)widget;
+ int num;
+
+ num = 0;
+
+ if (currTheme->systray != 0)
+ {
+ num = currTheme->systray->getCurrentWindowCount();
+ }
+ return num;
+}
+
+PyObject* py_get_current_window_count(PyObject *, PyObject *args)
+{
+ long widget;
+ if (!PyArg_ParseTuple(args, (char*)"l:getCurrentWindowCount", &widget ))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ return Py_BuildValue((char*)"l", getCurrentWindowCount(widget));
+}
+
+/* now a method we need to expose to Python */
+long updateSystrayLayout(long widget)
+{
+ karamba* currTheme = (karamba*)widget;
+
+ if (currTheme->systray != 0)
+ {
+ currTheme->systray->layoutSystray();
+ }
+ return 1;
+}
+
+PyObject* py_update_systray_layout(PyObject *, PyObject *args)
+{
+ long widget;
+ if (!PyArg_ParseTuple(args, (char*)"l:updateSystrayLayout", &widget ))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ return Py_BuildValue((char*)"l", updateSystrayLayout(widget));
+}
+
+/* get the systray size from python */
+int getSystraySize(long widget) {
+ karamba* currTheme = (karamba*)widget;
+ if(currTheme->systray == 0) {
+ return 0;
+ } else {
+ return currTheme->systray->getTraySize();
+ }
+}
+
+// Returns the size of the systray
+PyObject* py_get_systray_size(PyObject*, PyObject* args)
+{
+ long widget;
+
+ if (!PyArg_ParseTuple(args, "l:getSystraySize", &widget))
+ return NULL;
+
+ return Py_BuildValue("l", getSystraySize(widget));
+}
+
diff --git a/superkaramba/src/systray_python.h b/superkaramba/src/systray_python.h
new file mode 100644
index 0000000..045382a
--- /dev/null
+++ b/superkaramba/src/systray_python.h
@@ -0,0 +1,117 @@
+/****************************************************************************
+* systray_python.h - Functions for systray python api
+*
+* Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+* Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+*
+* This file is part of SuperKaramba.
+*
+* SuperKaramba 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.
+*
+* SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+#ifndef SYSTRAY_PYTHON_H
+#define SYSTRAY_PYTHON_H
+
+struct _object;
+typedef _object PyObject;
+
+/** Systray/moveSystray
+*
+* SYNOPSIS
+* long moveSystray(widget, x, y, w, h)
+* DESCRIPTION
+* ??
+* ARGUMENTS
+* * long widget -- karamba
+* * long x -- x coordinate
+* * long y -- y coordinate
+* * long w -- width
+* * long h -- height
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_move_systray(PyObject *self, PyObject *args);
+
+/** Systray/showSystray
+*
+* SYNOPSIS
+* long showSystray(widget)
+* DESCRIPTION
+* ??
+* ARGUMENTS
+* * long widget -- karamba
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_show_systray(PyObject *self, PyObject *args);
+
+/** Systray/hideSystray
+*
+* SYNOPSIS
+* long hideSystray(widget)
+* DESCRIPTION
+* ??
+* ARGUMENTS
+* * long widget -- karamba
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_hide_systray(PyObject *self, PyObject *args);
+
+/** Systray/createSystray
+*
+* SYNOPSIS
+* long createSystray(widget, x, y, w, h)
+* DESCRIPTION
+* ??
+* ARGUMENTS
+* * long widget -- karamba
+* * long x -- x coordinate
+* * long y -- y coordinate
+* * long w -- width
+* * long h -- height
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_create_systray(PyObject *self, PyObject *args);
+
+/** Systray/getCurrentWindowCount
+*
+* SYNOPSIS
+* long getCurrentWindowCount(widget)
+* DESCRIPTION
+* ??
+* ARGUMENTS
+* * long widget -- karamba
+* RETURN VALUE
+* window count
+*/
+PyObject* py_get_current_window_count(PyObject *self, PyObject *args);
+
+/** Systray/updateSystrayLayout
+*
+* SYNOPSIS
+* long getCurrentWindowCount(widget)
+* DESCRIPTION
+* ??
+* ARGUMENTS
+* * long widget -- karamba
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_update_systray_layout(PyObject *self, PyObject *args);
+PyObject* py_get_systray_size(PyObject *self, PyObject *args);
+
+#endif // SYSTRAY_PYTHON_H
diff --git a/superkaramba/src/task_python.cpp b/superkaramba/src/task_python.cpp
new file mode 100644
index 0000000..7a74559
--- /dev/null
+++ b/superkaramba/src/task_python.cpp
@@ -0,0 +1,375 @@
+/****************************************************************************
+* task_python.cpp - Functions for task python api
+*
+* Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+* Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+* Copyright (c) 2004 Petri Damstn <damu@iki.fi>
+*
+* This file is part of SuperKaramba.
+*
+* SuperKaramba 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.
+*
+* SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+#ifdef _XOPEN_SOURCE
+#undef _XOPEN_SOURCE
+#endif
+
+#include <Python.h>
+#include <qobject.h>
+#include "karamba.h"
+#include "meter.h"
+#include "meter_python.h"
+#include "task_python.h"
+
+// This does something with a task, such as minimize or close it
+int performTaskAction(long widget, long ctask, long action)
+{
+ karamba* currTheme = (karamba*)widget;
+ Task* currTask = 0;
+ Task* task;
+
+ TaskList taskList = currTheme -> taskManager.tasks();
+
+ for (task = taskList.first(); task; task = taskList.next())
+ {
+ if ((long)task == (long)ctask)
+ {
+ currTask = task;
+ }
+ }
+
+ if (currTask != 0)
+ {
+ switch (action)
+ {
+ case 1:
+ currTask->maximize();
+ break;
+
+ case 2:
+ currTask->restore();
+ break;
+
+ case 3:
+ currTask->iconify();
+ break;
+
+ case 4:
+ currTask->close();
+ break;
+
+ case 5:
+ currTask->activate();
+ break;
+
+ case 6:
+ currTask->raise();
+ break;
+
+ case 7:
+ currTask->lower();
+ break;
+
+ case 8:
+ currTask->activateRaiseOrIconify();
+ break;
+
+ case 9:
+ currTask->toggleAlwaysOnTop();
+ break;
+
+ case 10:
+ currTask->toggleShaded();
+ break;
+
+ default:
+ printf("You are trying to perform an invalid action in \
+ performTaskAction\n");
+ }
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+PyObject* py_perform_task_action(PyObject *, PyObject *args)
+{
+ long widget, task, action;
+ if (!PyArg_ParseTuple(args, (char*)"lll:performTaskAction",
+ &widget, &task, &action))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ return Py_BuildValue((char*)"l", performTaskAction(widget, task, action));
+}
+
+// This returns all the info about a certain task
+// Return type is a Python List
+PyObject* getTaskInfo(long widget, long ctask)
+{
+ karamba* currTheme = (karamba*)widget;
+ Task* currTask = 0;
+ Task* task;
+
+ TaskList taskList = currTheme -> taskManager.tasks();
+
+ for (task = taskList.first(); task; task = taskList.next())
+ {
+ if ((long)task == (long)ctask)
+ {
+ currTask = task;
+ }
+
+ }
+
+ if (currTask != 0)
+ {
+ PyObject* pList = PyList_New(0);
+
+ //Task Name
+ if (currTask->name() != NULL)
+ {
+ PyList_Append(pList, PyString_FromString(currTask->name().latin1()));
+ }
+ else
+ {
+ PyList_Append(pList, PyString_FromString(""));
+ }
+
+ //Icon Name
+ if (currTask->iconName() != NULL)
+ {
+ PyList_Append(pList, PyString_FromString(currTask->iconName().latin1()));
+ }
+ else
+ {
+ PyList_Append(pList, PyString_FromString(""));
+ }
+
+ //Class Name
+ if (currTask->className() != NULL)
+ {
+ PyList_Append(pList, PyString_FromString(currTask->className().latin1()));
+ }
+ else
+ {
+ PyList_Append(pList, PyString_FromString(""));
+ }
+
+ // Desktop this task is on
+ PyList_Append(pList, PyInt_FromLong(currTask->desktop()));
+
+ // is it maximized?
+ PyList_Append(pList, PyInt_FromLong(currTask->isMaximized()));
+
+ // is it iconified?
+ PyList_Append(pList, PyInt_FromLong(currTask->isIconified()));
+
+ // is it shaded?
+ PyList_Append(pList, PyInt_FromLong(currTask->isShaded()));
+
+ // is it focused?
+ PyList_Append(pList, PyInt_FromLong(currTask->isActive()));
+
+ // a reference back to itself
+ PyList_Append(pList, PyInt_FromLong((long)currTask));
+
+ return pList;
+
+ }
+ else
+ {
+ qWarning("Task not found.");
+ return NULL;
+ }
+}
+
+PyObject* py_get_task_info(PyObject *, PyObject *args)
+{
+ long widget, task;
+ if (!PyArg_ParseTuple(args, (char*)"ll:getTaskInfo", &widget, &task))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ return getTaskInfo(widget, task);
+}
+
+// This returns all the info about a certain startup
+// Return type is a Python List
+PyObject* getStartupInfo(long widget, long cstartup)
+{
+ karamba* currTheme = (karamba*)widget;
+ Startup* currentStartup = (Startup*) cstartup;
+ Startup* startup;
+
+ StartupList startupList = currTheme -> taskManager.startups();
+
+ for (startup = startupList.first(); startup; startup = startupList.next())
+ {
+ if ((long)startup == (long)cstartup)
+ {
+ break;
+ }
+ }
+
+ startup = currentStartup;
+
+ if (startup != 0)
+ {
+ PyObject* pList = PyList_New(0);
+
+ //Startup Name
+ if (startup -> text() != NULL)
+ {
+ PyList_Append(pList, PyString_FromString(startup -> text().latin1()));
+ }
+ else
+ {
+ PyList_Append(pList, PyString_FromString(""));
+ }
+
+ //Icon Name
+ if (startup -> icon() != NULL)
+ {
+ PyList_Append(pList, PyString_FromString(startup -> icon().latin1()));
+ }
+ else
+ {
+ PyList_Append(pList, PyString_FromString(""));
+ }
+
+ //Executable Name
+ if (startup -> bin() != NULL)
+ {
+ PyList_Append(pList, PyString_FromString(startup -> bin().latin1()));
+ }
+ else
+ {
+ PyList_Append(pList, PyString_FromString(""));
+ }
+
+ // a reference back to itself
+ PyList_Append(pList, PyInt_FromLong((long) startup));
+
+ return pList;
+
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+PyObject* py_get_startup_info(PyObject*, PyObject* args)
+{
+ long widget, startup;
+ if (!PyArg_ParseTuple(args, (char*)"ll:getStartupInfo", &widget, &startup))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ return getStartupInfo(widget, startup);
+}
+
+// This gets a system task list
+// It returns a String List of task names
+PyObject* getTaskNames(long widget)
+{
+ karamba* currTheme = (karamba*)widget;
+ PyObject* pList = PyList_New(0);
+ PyObject* pString;
+
+ TaskList taskList = currTheme -> taskManager.tasks();
+
+ Task* task;
+ for (task = taskList.first(); task; task = taskList.next())
+ {
+ const char* tmp = task->name().latin1();
+ if(tmp == 0)
+ continue;
+ pString = PyString_FromString(tmp);
+ if(pString)
+ PyList_Append(pList, pString);
+ }
+ return pList;
+}
+
+PyObject* py_get_task_names(PyObject *, PyObject *args)
+{
+ long widget;
+ if(!PyArg_ParseTuple(args, (char*)"l:getTaskNames", &widget))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ return getTaskNames(widget);
+}
+
+// This gets a system task list
+PyObject* getTaskList(long widget)
+{
+ karamba* currTheme = (karamba*)widget;
+ PyObject* pList = PyList_New(0);
+ PyObject* pString;
+
+ TaskList taskList = currTheme -> taskManager.tasks();
+
+ Task* task;
+ for (task = taskList.first(); task; task = taskList.next())
+ {
+ pString = PyInt_FromLong((long)task);
+ PyList_Append(pList, pString);
+ }
+ return pList;
+}
+
+PyObject* py_get_task_list(PyObject *, PyObject *args)
+{
+ long widget;
+ if(!PyArg_ParseTuple(args, (char*)"l:getTaskList", &widget))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ return getTaskList(widget);
+}
+
+// This gets a system startup list
+PyObject* getStartupList(long widget)
+{
+ karamba* currTheme = (karamba*)widget;
+ PyObject* pList = PyList_New(0);
+ PyObject* pString;
+
+ StartupList startupList = currTheme -> taskManager.startups();
+
+ Startup* startup;
+
+ for (startup = startupList.first(); startup; startup = startupList.next())
+ {
+ pString = PyInt_FromLong((long) startup);
+ PyList_Append(pList, pString);
+ }
+ return pList;
+}
+
+PyObject* py_get_startup_list(PyObject *, PyObject *args)
+{
+ long widget;
+ if(!PyArg_ParseTuple(args, (char*)"l:getStartupList", &widget))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ return getStartupList(widget);
+}
diff --git a/superkaramba/src/task_python.h b/superkaramba/src/task_python.h
new file mode 100644
index 0000000..ab4365e
--- /dev/null
+++ b/superkaramba/src/task_python.h
@@ -0,0 +1,153 @@
+/****************************************************************************
+* task_python.h - Functions for task python api
+*
+* Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+* Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+* Copyright (c) 2004 Petri Damstn <damu@iki.fi>
+*
+* This file is part of SuperKaramba.
+*
+* SuperKaramba 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.
+*
+* SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+#ifndef TASK_PYTHON_H
+#define TASK_PYTHON_H
+
+/** Task/performTaskAction
+*
+* SYNOPSIS
+* long performTaskAction(widget, task, action)
+* DESCRIPTION
+* This peforms the given action on a task object. widget is a reference to
+* the current widget. task is a reference to a task object you got from
+* getTaskList(). Action is a number from 1 to 10. See the list below.
+*
+* Possible actions:
+* * 1 = Maximize the window
+* * 2 = Restore the window (use on iconified windows)
+* * 3 = Iconify the window (minimize it)
+* * 4 = Close the window
+* * 5 = Activate (give focus to) the window
+* * 6 = Raise the window
+* * 7 = Lower the window
+* * 8 = Smart Focus/Minimize - This will what the KDE taskbar does when you
+* click on a window. If it is iconified, raise it. If it has focus,
+* iconify it.
+* * 9 = Toggle whether this window is always on top
+* * 10 = Toggle wheter this window is shaded (rolled up)
+* ARGUMENTS
+* * long widget -- karamba
+* * long task -- pointer to task
+* * long action -- action number
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_perform_task_action(PyObject *self, PyObject *args);
+
+/** Task/getTaskInfo
+*
+* SYNOPSIS
+* list getTaskInfo(widget, task)
+* DESCRIPTION
+* This returns all of the info about a certain task in the form of a Python
+* List. widget is a reference to the current widget. task is a reference to
+* the window you want info about which you obtain by calling getTaskList().
+* ARGUMENTS
+* * long widget -- karamba
+* * long task -- pointer to task
+* RETURN VALUE
+* Here is the format of the returned list by index value:
+* * 0 = Task name (The full name of the window)
+* * 1 = Icon name
+* * 2 = Class name - This is for grouping tasks. All tasks with the same
+* name can be grouped together because they are instances of the same
+* program.
+* * 3 = Desktop number - The desktop number this window is on
+* * 4 = Is this window maximized? 0=no, 1=yes
+* * 5 = Is this window iconified (minimized)? 0=no, 1=yes
+* * 6 = Is this window shaded (rolled up)? 0=no, 1=yes
+* * 7 = Is this window focused? 0=no, 1=yes
+* * 8 = A reference back to the task you got info on
+*/
+PyObject* py_get_task_info(PyObject *self, PyObject *args);
+
+/** Task/getStartupInfo
+*
+* SYNOPSIS
+* list getStartupInfo(widget, task)
+* DESCRIPTION
+* This returns all of the info about a certain starting task in the form of
+* a Python List. widget is a reference to the current widget. task is a
+* reference to the window you want info about which you obtain by calling
+* getStartupList().
+* ARGUMENTS
+* * long widget -- karamba
+* * long task -- pointer to task
+* RETURN VALUE
+* Here is the format of the returned list by index value:
+* * 0 = Task name (The full name of the window)
+* * 1 = Icon name
+* * 2 = Executable name
+* * 3 = A reference back to the task you got info on
+*/
+PyObject* py_get_startup_info(PyObject* self, PyObject* args);
+
+/** Task/getTaskNames
+*
+* SYNOPSIS
+* list getTaskNames(widget)
+* DESCRIPTION
+* This returns a Python List containing the String names of all open
+* windows on the system. This is for convience if you want to list open
+* windows or see if a window by a certain name exists. Anything else
+* requires the reference to the window you would obtain from getTaskList()
+* ARGUMENTS
+* * long widget -- karamba
+* RETURN VALUE
+* Task list
+*/
+PyObject* py_get_task_names(PyObject *self, PyObject *args);
+
+/** Task/getTaskList
+*
+* SYNOPSIS
+* list getTaskList(widget)
+* DESCRIPTION
+* This returns a Python List object with references to all the current
+* windows open on this system. You can then call performTaskAction() or
+* getTaskInfo() on any of the entries in the list.
+* ARGUMENTS
+* * long widget -- karamba
+* RETURN VALUE
+* Task list
+*/
+PyObject* py_get_task_list(PyObject *self, PyObject *args);
+
+/** Task/getStartupList
+*
+* SYNOPSIS
+* list getTaskList(widget)
+* DESCRIPTION
+* This returns a Python List object with references to all the current
+* windows that are in the process of loading on this system. You can then
+* call getStartupInfo() on any of the entries in the list.
+* ARGUMENTS
+* * long widget -- karamba
+* RETURN VALUE
+* startup list
+*/
+PyObject* py_get_startup_list(PyObject *self, PyObject *args);
+
+#endif // TASK_PYTHON_H
diff --git a/superkaramba/src/taskbartest.cpp b/superkaramba/src/taskbartest.cpp
new file mode 100644
index 0000000..3ad6922
--- /dev/null
+++ b/superkaramba/src/taskbartest.cpp
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+ * Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+ * Copyright (c) 2005 Ryan Nickell <p0z3r@earthlink.net>
+ *
+ * This file is part of SuperKaramba.
+ *
+ * SuperKaramba 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.
+ *
+ * SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#include <kapplication.h>
+#include <kfiledialog.h>
+#include <kaboutdata.h>
+#include <kcmdlineargs.h>
+#include <klocale.h>
+#include <kconfig.h>
+
+#include <qfileinfo.h>
+#include <qstringlist.h>
+
+#include <iostream.h>
+
+#include "taskbartest.h"
+
+static const char *description =
+ I18N_NOOP("A KDE Eye-candy Application");
+
+static const char *version = "0.17";
+
+static KCmdLineOptions options[] =
+ {
+ // { "+[URL]", I18N_NOOP( "Document to open" ), 0 },
+ { "+file", I18N_NOOP("A required argument 'file'"), 0 },
+ { 0, 0, 0 }
+
+ };
+
+
+int main(int argc, char **argv)
+{
+ KAboutData about("karamba", I18N_NOOP("karamba"), version, description,
+ KAboutData::License_GPL, "(C) 2003 Hans Karlsson", 0, 0, "karlsson.h@home.se");
+ about.addAuthor( "Hans Karlsson", 0, "karlsson.h@home.se" );
+ KCmdLineArgs::init(argc, argv, &about);
+ KCmdLineArgs::addCmdLineOptions( options );
+
+ KApplication app;
+// karamba *mainWin = 0;
+
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+
+// //KSGRD::SensorManager *f32 = new KSGRD::SensorManager();
+// //f32->engage("localhost");
+// // KSGRD::SensorMgr foo ;// p->engage( "" );
+
+
+// //KConfig *kconfig = KGlobal::config();
+// //kconfig->setGroup("karamba");
+// //kconfig->writeEntry("test", "/home/hk/foofoo");
+// //kconfig->sync();
+
+
+// bool OK = false;
+
+// // initialize Python
+// Py_Initialize();
+
+// // initialize thread support
+// PyEval_InitThreads();
+
+// mainThreadState = NULL;
+
+// // save a pointer to the main PyThreadState object
+// mainThreadState = PyThreadState_Get();
+
+// // release the lock
+// PyEval_ReleaseLock();
+
+
+// if(args->count() > 0)
+// {
+// for (int i = 0; i < (args->count()); i++)
+// {
+// if( args->arg(i) != "" )
+// {
+// QFileInfo file( args->arg(i) );
+// //qDebug( file.dirPath(true) );
+// if( file.exists() && !file.isDir() )
+// {
+// //qDebug( "File exists" );
+// mainWin = new karamba( ( args->arg(i) ));
+// mainWin->show();
+// OK = true;
+// }
+// }
+// }
+
+// //app.setMainWidget( mainWin );
+// int ret = 0;
+// if( OK )
+// ret = app.exec();
+
+// // shut down the interpreter
+// PyInterpreterState * mainInterpreterState = mainThreadState->interp;
+// // create a thread state object for this thread
+// PyThreadState * myThreadState = PyThreadState_New(mainInterpreterState);
+// PyThreadState_Swap(myThreadState);
+
+// PyEval_AcquireLock();
+// Py_Finalize();
+
+// return ret;
+// }
+// else
+// {
+// QStringList fileNames;
+// fileNames = KFileDialog::getOpenFileNames(QString::null, "*.theme", 0, "Open configurations");
+// for ( QStringList::Iterator it = fileNames.begin(); it != fileNames.end(); ++it )
+// {
+// QFileInfo file( *it );
+// if( file.exists() && !file.isDir() )
+// {
+// mainWin = new karamba( *it );
+// mainWin->show();
+// OK = true;
+// }
+// }
+// int ret = 0;
+// if( OK )
+// ret = app.exec();
+
+// // shut down the interpreter
+// PyInterpreterState * mainInterpreterState = mainThreadState->interp;
+// // create a thread state object for this thread
+// PyThreadState * myThreadState = PyThreadState_New(mainInterpreterState);
+// PyThreadState_Swap(myThreadState);
+// PyEval_AcquireLock();
+// Py_Finalize();
+// return ret;
+// }
+
+// args->clear();
+
+// // shut down the interpreter
+
+// PyInterpreterState * mainInterpreterState = mainThreadState->interp;
+// // create a thread state object for this thread
+// PyThreadState * myThreadState = PyThreadState_New(mainInterpreterState);
+// PyThreadState_Swap(myThreadState);
+// PyEval_AcquireLock();
+// Py_Finalize();
+
+
+ TaskManager t;
+
+ printf("%d %d", t.numberOfDesktops(), t.currentDesktop());
+
+ TaskList list = t.tasks();
+
+ Task *task;
+ for ( task = list.first(); task; task = list.next() ) {
+ cout << task->name().latin1() << endl;
+ task->restore();
+ }
+ cout << endl;
+
+ return 0;
+
+
+
+}
diff --git a/superkaramba/src/taskbartest.h b/superkaramba/src/taskbartest.h
new file mode 100644
index 0000000..6050569
--- /dev/null
+++ b/superkaramba/src/taskbartest.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+ * Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+ * Copyright (c) 2005 Ryan Nickell <p0z3r@earthlink.net>
+ *
+ * This file is part of SuperKaramba.
+ *
+ * SuperKaramba 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.
+ *
+ * SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#include "taskmanager.h"
diff --git a/superkaramba/src/taskmanager.cpp b/superkaramba/src/taskmanager.cpp
new file mode 100644
index 0000000..c1f2568
--- /dev/null
+++ b/superkaramba/src/taskmanager.cpp
@@ -0,0 +1,829 @@
+/*****************************************************************
+
+Copyright (c) 2000 Matthias Elter <elter@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#include <kglobal.h>
+#include <klocale.h>
+#include <kdebug.h>
+#include <kconfig.h>
+#include <kiconloader.h>
+#include <kwinmodule.h>
+#include <netwm.h>
+#include <qtimer.h>
+#include <qimage.h>
+
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#include "taskmanager.h"
+#include "taskmanager.moc"
+
+template class QPtrList<Task>;
+
+// Hack: create a global KWinModule without a parent. We
+// can't make it a child of TaskManager because more than one
+// TaskManager might be created. We can't make it a class
+// variable without changing Task, which also uses it.
+// So, we'll leak a little memory, but it's better than crashing.
+// The real problem is that KWinModule should be a singleton.
+KWinModule* kwin_module = 0;
+
+TaskManager::TaskManager(QObject *parent, const char *name)
+ : QObject(parent, name), _active(0), _startup_info( NULL )
+{
+
+ kwin_module = new KWinModule();
+
+// KGlobal::locale()->insertCatalogue("libtaskmanager");
+ connect(kwin_module, SIGNAL(windowAdded(WId)), SLOT(windowAdded(WId)));
+ connect(kwin_module, SIGNAL(windowRemoved(WId)), SLOT(windowRemoved(WId)));
+ connect(kwin_module, SIGNAL(activeWindowChanged(WId)), SLOT(activeWindowChanged(WId)));
+ connect(kwin_module, SIGNAL(currentDesktopChanged(int)), SLOT(currentDesktopChanged(int)));
+ connect(kwin_module, SIGNAL(windowChanged(WId,unsigned int)), SLOT(windowChanged(WId,unsigned int)));
+
+ // register existing windows
+ const QValueList<WId> windows = kwin_module->windows();
+ QValueList<WId>::ConstIterator end( windows.end() );
+ for (QValueList<WId>::ConstIterator it = windows.begin(); it != end; ++it )
+ windowAdded(*it);
+
+ // set active window
+ WId win = kwin_module->activeWindow();
+ activeWindowChanged(win);
+
+ configure_startup();
+}
+
+TaskManager::~TaskManager()
+{
+}
+
+void TaskManager::configure_startup()
+{
+ KConfig c("klaunchrc", true);
+ c.setGroup("FeedbackStyle");
+ if (!c.readBoolEntry("TaskbarButton", true))
+ return;
+ _startup_info = new KStartupInfo( true, this );
+ connect( _startup_info,
+ SIGNAL( gotNewStartup( const KStartupInfoId&, const KStartupInfoData& )),
+ SLOT( gotNewStartup( const KStartupInfoId&, const KStartupInfoData& )));
+ connect( _startup_info,
+ SIGNAL( gotStartupChange( const KStartupInfoId&, const KStartupInfoData& )),
+ SLOT( gotStartupChange( const KStartupInfoId&, const KStartupInfoData& )));
+ connect( _startup_info,
+ SIGNAL( gotRemoveStartup( const KStartupInfoId&, const KStartupInfoData& )),
+ SLOT( gotRemoveStartup( const KStartupInfoId& )));
+ c.setGroup( "TaskbarButtonSettings" );
+ _startup_info->setTimeout( c.readUnsignedNumEntry( "Timeout", 30 ));
+}
+
+Task* TaskManager::findTask(WId w)
+{
+ for (Task* t = _tasks.first(); t != 0; t = _tasks.next())
+ if (t->window() == w || t->hasTransient(w))
+ return t;
+ return 0;
+}
+
+#ifdef KDE_3_3
+#define NET_ALL_TYPES_MASK (NET::AllTypesMask)
+#else
+#define NET_ALL_TYPES_MASK (-1LU)
+#endif
+
+void TaskManager::windowAdded(WId w )
+{
+ NETWinInfo info(qt_xdisplay(), w, qt_xrootwin(),
+ NET::WMWindowType | NET::WMPid | NET::WMState );
+ #ifdef KDE_3_2
+ NET::WindowType windowType = info.windowType(NET_ALL_TYPES_MASK);
+ #else
+ NET::WindowType windowType = info.windowType();
+ #endif
+ // ignore NET::Tool and other special window types
+ if (windowType != NET::Normal && windowType != NET::Override
+ && windowType != NET::Unknown && windowType != NET::Dialog)
+ return;
+ // ignore windows that want to be ignored by the taskbar
+ if ((info.state() & NET::SkipTaskbar) != 0)
+ {
+ _skiptaskbar_windows.push_front( w ); // remember them though
+ return;
+ }
+
+ Window transient_for_tmp;
+ if (XGetTransientForHint(qt_xdisplay(), (Window) w, &transient_for_tmp))
+ {
+ WId transient_for = (WId) transient_for_tmp;
+
+ // check if it's transient for a skiptaskbar window
+ if (_skiptaskbar_windows.contains(transient_for))
+ return;
+
+ // lets see if this is a transient for an existing task
+ if (transient_for != qt_xrootwin() && transient_for != 0 )
+ {
+ Task* t = findTask(transient_for);
+ if (t)
+ {
+ if (t->window() != w)
+ {
+ t->addTransient(w);
+ // kdDebug() << "TM: Transient " << w << " added for Task: " << t->window() << endl;
+ }
+ return;
+ }
+ }
+ }
+ Task* t = new Task(w, this);
+ _tasks.append(t);
+
+ // kdDebug() << "TM: Task added for WId: " << w << endl;
+ emit taskAdded(t);
+}
+
+void TaskManager::windowRemoved(WId w )
+{
+ _skiptaskbar_windows.remove( w );
+ // find task
+ Task* t = findTask(w);
+ if (!t) return;
+
+ if (t->window() == w) {
+ _tasks.removeRef(t);
+
+ emit taskRemoved(t);
+
+ if(t == _active) _active = 0;
+ delete t;
+ //kdDebug() << "TM: Task for WId " << w << " removed." << endl;
+ }
+ else {
+ t->removeTransient( w );
+ //kdDebug() << "TM: Transient " << w << " for Task " << t->window() << " removed." << endl;
+ }
+}
+
+void TaskManager::windowChanged(WId w, unsigned int dirty)
+{
+ if( dirty & NET::WMState ) {
+ NETWinInfo info ( qt_xdisplay(), w, qt_xrootwin(), NET::WMState );
+ if ( (info.state() & NET::SkipTaskbar) != 0 ) {
+ windowRemoved( w );
+ _skiptaskbar_windows.push_front( w );
+ return;
+ }
+ else {
+ _skiptaskbar_windows.remove( w );
+ if( !findTask( w ))
+ windowAdded( w ); // skipTaskBar state was removed, so add this window
+ }
+ }
+
+ // check if any state we are interested in is marked dirty
+ if(!(dirty & (NET::WMVisibleName|NET::WMName|NET::WMState|NET::WMIcon|NET::XAWMState|NET::WMDesktop)) )
+ return;
+
+ // find task
+ Task* t = findTask( w );
+ if (!t) return;
+
+ //kdDebug() << "TaskManager::windowChanged " << w << " " << dirty << endl;
+
+
+ // refresh icon pixmap if necessary
+ if (dirty & NET::WMIcon)
+ t->refresh(true);
+ else
+ t->refresh();
+
+ if(dirty & (NET::WMDesktop|NET::WMState|NET::XAWMState))
+ emit windowChanged(w); // moved to different desktop or is on all or change in iconification/withdrawnnes
+}
+
+void TaskManager::activeWindowChanged(WId w )
+{
+ //kdDebug() << "TaskManager::activeWindowChanged" << endl;
+
+ Task* t = findTask( w );
+ if (!t) {
+ if (_active) {
+ _active->setActive(false);
+ _active = 0;
+
+ // there is no active window at the moment
+ emit activeTaskChanged(0);
+ }
+ }
+ else {
+ if (_active)
+ _active->setActive(false);
+
+ _active = t;
+ _active->setActive(true);
+
+ emit activeTaskChanged(_active);
+ }
+}
+
+void TaskManager::currentDesktopChanged(int desktop)
+{
+ emit desktopChanged(desktop);
+}
+
+void TaskManager::gotNewStartup( const KStartupInfoId& id, const KStartupInfoData& data )
+{
+ Startup* s = new Startup( id, data, this );
+ _startups.append(s);
+
+ emit startupAdded(s);
+}
+
+void TaskManager::gotStartupChange( const KStartupInfoId& id, const KStartupInfoData& data )
+{
+ for( Startup* s = _startups.first(); s != 0; s = _startups.next()) {
+ if ( s->id() == id ) {
+ s->update( data );
+ return;
+ }
+ }
+}
+
+void TaskManager::gotRemoveStartup( const KStartupInfoId& id )
+{
+ killStartup( id );
+}
+
+void TaskManager::killStartup( const KStartupInfoId& id )
+{
+ Startup* s = 0;
+ for(s = _startups.first(); s != 0; s = _startups.next()) {
+ if (s->id() == id)
+ break;
+ }
+ if (s == 0) return;
+
+ _startups.removeRef(s);
+ emit startupRemoved(s);
+ delete s;
+}
+
+void TaskManager::killStartup(Startup* s)
+{
+ if (s == 0) return;
+
+ _startups.removeRef(s);
+ emit startupRemoved(s);
+ delete s;
+}
+
+QString TaskManager::desktopName(int desk) const
+{
+ return kwin_module->desktopName(desk);
+}
+
+int TaskManager::numberOfDesktops() const
+{
+ return kwin_module->numberOfDesktops();
+}
+
+bool TaskManager::isOnTop(const Task* task)
+{
+ if(!task) return false;
+
+ for (QValueList<WId>::ConstIterator it = kwin_module->stackingOrder().fromLast();
+ it != kwin_module->stackingOrder().end(); --it ) {
+ for (Task* t = _tasks.first(); t != 0; t = _tasks.next() ) {
+ if ( (*it) == t->window() ) {
+ if ( t == task )
+ return true;
+ if ( !t->isIconified() && (t->isAlwaysOnTop() == task->isAlwaysOnTop()) )
+ return false;
+ break;
+ }
+ }
+ }
+ return false;
+}
+
+
+Task::Task(WId win, TaskManager * parent, const char *name) :
+ QObject(parent, name),
+ _active(false), _win(win),
+ _lastWidth(0), _lastHeight(0), _lastResize(false), _lastIcon(),
+ _thumbSize(0.2), _thumb(), _grab()
+{
+#ifdef KDE_3_2
+ _info = KWin::windowInfo(_win, 0, 0);
+#else
+ _info = KWin::info(_win);
+#endif
+ // try to load icon via net_wm
+ _pixmap = KWin::icon(_win, 16, 16, true);
+
+ // try to guess the icon from the classhint
+ if(_pixmap.isNull())
+ KGlobal::instance()->iconLoader()->loadIcon(className().lower(),
+ KIcon::Small,KIcon::Small,
+ KIcon::DefaultState, 0, true);
+
+ // load xapp icon
+ if (_pixmap.isNull())
+ _pixmap = SmallIcon("kcmx");
+}
+
+Task::~Task()
+{
+}
+
+void Task::refresh(bool icon)
+{
+#ifdef KDE_3_2
+ _info = KWin::windowInfo(_win, 0, 0);
+#else
+ _info = KWin::info(_win);
+#endif
+ if (icon)
+ {
+ // try to load icon via net_wm
+ _pixmap = KWin::icon(_win, 16, 16, true);
+
+ // try to guess the icon from the classhint
+ if(_pixmap.isNull())
+ {
+ KGlobal::instance()->iconLoader()->loadIcon(className().lower(),
+ KIcon::Small, KIcon::Small, KIcon::DefaultState, 0, true);
+ }
+
+ // load xapp icon
+ if (_pixmap.isNull())
+ _pixmap = SmallIcon("kcmx");
+
+ _lastIcon.resize(0,0);
+ emit iconChanged();
+ }
+ emit changed();
+}
+
+void Task::setActive(bool a)
+{
+ _active = a;
+ emit changed();
+ if ( a )
+ emit activated();
+ else
+ emit deactivated();
+}
+
+bool Task::isMaximized() const
+{
+#ifdef KDE_3_2
+ return(_info.state() & NET::Max);
+#else
+ return(_info.state & NET::Max);
+#endif
+}
+
+bool Task::isIconified() const
+{
+#ifdef KDE_3_2
+ return (_info.mappingState() == NET::Iconic);
+#else
+ return (_info.mappingState == NET::Iconic);
+#endif
+}
+
+bool Task::isAlwaysOnTop() const
+{
+#ifdef KDE_3_2
+ return (_info.state() & NET::StaysOnTop);
+#else
+ return (_info.state & NET::StaysOnTop);
+#endif
+}
+
+bool Task::isShaded() const
+{
+#ifdef KDE_3_2
+ return (_info.state() & NET::Shaded);
+#else
+ return (_info.state & NET::Shaded);
+#endif
+}
+
+bool Task::isOnCurrentDesktop() const
+{
+#ifdef KDE_3_2
+ return (_info.onAllDesktops() || _info.desktop() == kwin_module->currentDesktop());
+#else
+ return (_info.onAllDesktops || _info.desktop == kwin_module->currentDesktop());
+#endif
+}
+
+bool Task::isOnAllDesktops() const
+{
+#ifdef KDE_3_2
+ return _info.onAllDesktops();
+#else
+ return _info.onAllDesktops;
+#endif
+}
+
+bool Task::isActive() const
+{
+ return _active;
+}
+
+bool Task::isOnTop() const
+{
+ return taskManager()->isOnTop( this );
+}
+
+bool Task::isModified() const
+{
+ static QString modStr = QString::fromUtf8("[") + i18n("modified") + QString::fromUtf8("]");
+#ifdef KDE_3_2
+ int modStrPos = _info.visibleName().find(modStr);
+#else
+ int modStrPos = _info.visibleName.find(modStr);
+#endif
+
+ return ( modStrPos != -1 );
+}
+
+QString Task::iconName() const
+{
+ NETWinInfo ni( qt_xdisplay(), _win, qt_xrootwin(), NET::WMIconName);
+ return QString::fromUtf8(ni.iconName());
+}
+QString Task::visibleIconName() const
+{
+ NETWinInfo ni( qt_xdisplay(), _win, qt_xrootwin(), NET::WMVisibleIconName);
+ return QString::fromUtf8(ni.visibleIconName());
+}
+
+QString Task::className()
+{
+ XClassHint hint;
+ if(XGetClassHint(qt_xdisplay(), _win, &hint)) {
+ QString nh( hint.res_name );
+ XFree( hint.res_name );
+ XFree( hint.res_class );
+ return nh;
+ }
+ return QString::null;
+}
+
+QString Task::classClass()
+{
+ XClassHint hint;
+ if(XGetClassHint(qt_xdisplay(), _win, &hint)) {
+ QString ch( hint.res_class );
+ XFree( hint.res_name );
+ XFree( hint.res_class );
+ return ch;
+ }
+ return QString::null;
+}
+
+QPixmap Task::icon( int width, int height, bool allowResize )
+{
+ if ( (width == _lastWidth)
+ && (height == _lastHeight)
+ && (allowResize == _lastResize )
+ && (!_lastIcon.isNull()) )
+ return _lastIcon;
+
+ QPixmap newIcon = KWin::icon( _win, width, height, allowResize );
+ if ( !newIcon.isNull() ) {
+ _lastIcon = newIcon;
+ _lastWidth = width;
+ _lastHeight = height;
+ _lastResize = allowResize;
+ }
+
+ return newIcon;
+}
+
+QPixmap Task::bestIcon( int size, bool &isStaticIcon )
+{
+ QPixmap pixmap;
+ isStaticIcon = false;
+
+ switch( size ) {
+ case KIcon::SizeSmall:
+ {
+ pixmap = icon( 16, 16, true );
+
+ // Icon of last resort
+ if( pixmap.isNull() ) {
+ pixmap = KGlobal::iconLoader()->loadIcon( "go",
+ KIcon::NoGroup,
+ KIcon::SizeSmall );
+ isStaticIcon = true;
+ }
+ }
+ break;
+ case KIcon::SizeMedium:
+ {
+ //
+ // Try 34x34 first for KDE 2.1 icons with shadows, if we don't
+ // get one then try 32x32.
+ //
+ pixmap = icon( 34, 34, false );
+
+ if ( ( pixmap.width() != 34 ) || ( pixmap.height() != 34 ) ) {
+ if ( ( pixmap.width() != 32 ) || ( pixmap.height() != 32 ) ) {
+ pixmap = icon( 32, 32, true );
+ }
+ }
+
+ // Icon of last resort
+ if( pixmap.isNull() ) {
+ pixmap = KGlobal::iconLoader()->loadIcon( "go",
+ KIcon::NoGroup,
+ KIcon::SizeMedium );
+ isStaticIcon = true;
+ }
+ }
+ break;
+ case KIcon::SizeLarge:
+ {
+ // If there's a 48x48 icon in the hints then use it
+ pixmap = icon( size, size, false );
+
+ // If not, try to get one from the classname
+ if ( pixmap.isNull() || pixmap.width() != size || pixmap.height() != size ) {
+ pixmap = KGlobal::iconLoader()->loadIcon( className(),
+ KIcon::NoGroup,
+ size,
+ KIcon::DefaultState,
+ 0L,
+ true );
+ isStaticIcon = true;
+ }
+
+ // If we still don't have an icon then scale the one in the hints
+ if ( pixmap.isNull() || ( pixmap.width() != size ) || ( pixmap.height() != size ) ) {
+ pixmap = icon( size, size, true );
+ isStaticIcon = false;
+ }
+
+ // Icon of last resort
+ if( pixmap.isNull() ) {
+ pixmap = KGlobal::iconLoader()->loadIcon( "go",
+ KIcon::NoGroup,
+ size );
+ isStaticIcon = true;
+ }
+ }
+ }
+
+ return pixmap;
+}
+
+bool Task::idMatch( const QString& id1, const QString& id2 )
+{
+ if ( id1.isEmpty() || id2.isEmpty() )
+ return false;
+
+ if ( id1.contains( id2 ) > 0 )
+ return true;
+
+ if ( id2.contains( id1 ) > 0 )
+ return true;
+
+ return false;
+}
+
+
+void Task::maximize()
+{
+ NETWinInfo ni( qt_xdisplay(), _win, qt_xrootwin(), NET::WMState);
+ ni.setState( NET::Max, NET::Max );
+
+#ifdef KDE_3_2
+ if (_info.mappingState() == NET::Iconic)
+#else
+ if (_info.mappingState == NET::Iconic)
+#endif
+ activate();
+}
+
+void Task::restore()
+{
+ NETWinInfo ni( qt_xdisplay(), _win, qt_xrootwin(), NET::WMState);
+ ni.setState( 0, NET::Max );
+#ifdef KDE_3_2
+ if (_info.mappingState() == NET::Iconic)
+#else
+ if (_info.mappingState == NET::Iconic)
+#endif
+ activate();
+}
+
+void Task::iconify()
+{
+ XIconifyWindow( qt_xdisplay(), _win, qt_xscreen() );
+}
+
+void Task::close()
+{
+ NETRootInfo ri( qt_xdisplay(), NET::CloseWindow );
+ ri.closeWindowRequest( _win );
+}
+
+void Task::raise()
+{
+// kdDebug(1210) << "Task::raise(): " << name() << endl;
+ XRaiseWindow( qt_xdisplay(), _win );
+}
+
+void Task::lower()
+{
+// kdDebug(1210) << "Task::lower(): " << name() << endl;
+ XLowerWindow( qt_xdisplay(), _win );
+}
+
+void Task::activate()
+{
+// kdDebug(1210) << "Task::activate():" << name() << endl;
+ NETRootInfo ri( qt_xdisplay(), 0 );
+ ri.setActiveWindow( _win );
+}
+
+void Task::activateRaiseOrIconify()
+{
+ if ( !isActive() || isIconified() ) {
+ activate();
+ } else if ( !isOnTop() ) {
+ raise();
+ } else {
+ iconify();
+ }
+}
+
+void Task::toDesktop(int desk)
+{
+ NETWinInfo ni(qt_xdisplay(), _win, qt_xrootwin(), NET::WMDesktop);
+ if (desk == 0)
+ {
+#ifdef KDE_3_2
+ if (_info.onAllDesktops())
+ {
+ ni.setDesktop(kwin_module->currentDesktop());
+ KWin::forceActiveWindow(_win);
+ }
+#else
+ if (_info.onAllDesktops)
+ {
+ ni.setDesktop(kwin_module->currentDesktop());
+ KWin::setActiveWindow(_win);
+ }
+#endif
+ else
+ ni.setDesktop(NETWinInfo::OnAllDesktops);
+ return;
+ }
+ ni.setDesktop(desk);
+ if (desk == kwin_module->currentDesktop())
+#ifdef KDE_3_2
+ KWin::forceActiveWindow(_win);
+#else
+ KWin::setActiveWindow(_win);
+#endif
+}
+
+void Task::toCurrentDesktop()
+{
+ toDesktop(kwin_module->currentDesktop());
+}
+
+void Task::setAlwaysOnTop(bool stay)
+{
+ NETWinInfo ni( qt_xdisplay(), _win, qt_xrootwin(), NET::WMState);
+ if(stay)
+ ni.setState( NET::StaysOnTop, NET::StaysOnTop );
+ else
+ ni.setState( 0, NET::StaysOnTop );
+}
+
+void Task::toggleAlwaysOnTop()
+{
+ setAlwaysOnTop( !isAlwaysOnTop() );
+}
+
+void Task::setShaded(bool shade)
+{
+ NETWinInfo ni( qt_xdisplay(), _win, qt_xrootwin(), NET::WMState);
+ if(shade)
+ ni.setState( NET::Shaded, NET::Shaded );
+ else
+ ni.setState( 0, NET::Shaded );
+}
+
+void Task::toggleShaded()
+{
+ setShaded( !isShaded() );
+}
+
+void Task::publishIconGeometry(QRect rect)
+{
+ NETWinInfo ni( qt_xdisplay(), _win, qt_xrootwin(), NET::WMIconGeometry);
+ NETRect r;
+ r.pos.x = rect.x();
+ r.pos.y = rect.y();
+ r.size.width = rect.width();
+ r.size.height = rect.height();
+ ni.setIconGeometry(r);
+}
+
+void Task::updateThumbnail()
+{
+ if ( !isOnCurrentDesktop() )
+ return;
+ if ( !isActive() )
+ return;
+ if ( !_grab.isNull() ) // We're already processing one...
+ return;
+
+ //
+ // We do this as a two stage process to remove the delay caused
+ // by the thumbnail generation. This makes things much smoother
+ // on slower machines.
+ //
+ QWidget *rootWin = qApp->desktop();
+#ifdef KDE_3_2
+ QRect geom = _info.geometry();
+#else
+ QRect geom = _info.geometry;
+#endif
+ _grab = QPixmap::grabWindow( rootWin->winId(),
+ geom.x(), geom.y(),
+ geom.width(), geom.height() );
+
+ if ( !_grab.isNull() )
+ QTimer::singleShot( 200, this, SLOT( generateThumbnail() ) );
+}
+
+void Task::generateThumbnail()
+{
+ if ( _grab.isNull() )
+ return;
+
+ QImage img = _grab.convertToImage();
+
+ double width = img.width();
+ double height = img.height();
+ width = width * _thumbSize;
+ height = height * _thumbSize;
+
+ img = img.smoothScale( (int) width, (int) height );
+ _thumb = img;
+ _grab.resize( 0, 0 ); // Makes grab a null image.
+
+ emit thumbnailChanged();
+}
+
+Startup::Startup( const KStartupInfoId& id, const KStartupInfoData& data,
+ QObject * parent, const char *name)
+ : QObject(parent, name), _id( id ), _data( data )
+{
+}
+
+Startup::~Startup()
+{
+
+}
+
+void Startup::update( const KStartupInfoData& data )
+{
+ _data.update( data );
+ emit changed();
+}
+
+int TaskManager::currentDesktop() const
+{
+ return kwin_module->currentDesktop();
+}
diff --git a/superkaramba/src/taskmanager.h b/superkaramba/src/taskmanager.h
new file mode 100644
index 0000000..86e4a74
--- /dev/null
+++ b/superkaramba/src/taskmanager.h
@@ -0,0 +1,550 @@
+/*****************************************************************
+
+Copyright (c) 2000-2001 Matthias Elter <elter@kde.org>
+Copyright (c) 2001 Richard Moore <rich@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#ifndef __taskmanager_h__
+#define __taskmanager_h__
+
+#include <sys/types.h>
+
+#include <qpoint.h>
+#include <qobject.h>
+#include <qvaluelist.h>
+#include <qptrlist.h>
+#include <qpixmap.h>
+
+#include <dcopobject.h>
+#include <kwin.h>
+#include <kstartupinfo.h>
+#include "karambaapp.h"
+
+class TaskManager;
+
+/**
+ * A dynamic interface to a task (main window).
+ *
+ * @see TaskManager
+ * @see KWinModule
+ */
+class Task: public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY( QString name READ name )
+ Q_PROPERTY( QString visibleName READ visibleName )
+ Q_PROPERTY( QString visibleNameWithState READ visibleNameWithState )
+ Q_PROPERTY( QString iconName READ iconName )
+ Q_PROPERTY( QString visibleIconName READ visibleIconName )
+ Q_PROPERTY( QPixmap pixmap READ pixmap )
+ Q_PROPERTY( bool maximized READ isMaximized )
+ Q_PROPERTY( bool iconified READ isIconified )
+ Q_PROPERTY( bool shaded READ isShaded WRITE setShaded )
+ Q_PROPERTY( bool active READ isActive )
+ Q_PROPERTY( bool onCurrentDesktop READ isOnCurrentDesktop )
+ Q_PROPERTY( bool onAllDesktops READ isOnAllDesktops )
+ Q_PROPERTY( bool alwaysOnTop READ isAlwaysOnTop WRITE setAlwaysOnTop )
+ Q_PROPERTY( bool modified READ isModified )
+ Q_PROPERTY( int desktop READ desktop )
+ Q_PROPERTY( double thumbnailSize READ thumbnailSize WRITE setThumbnailSize )
+ Q_PROPERTY( bool hasThumbnail READ hasThumbnail )
+ Q_PROPERTY( QPixmap thumbnail READ thumbnail )
+
+public:
+ Task( WId win, TaskManager * parent, const char *name = 0 );
+ virtual ~Task();
+
+ TaskManager* taskManager() const { return (TaskManager*) parent(); }
+
+ WId window() const { return _win; }
+#ifdef KDE_3_2
+ QString name() const { return _info.name(); }
+ QString visibleName() const { return _info.visibleName(); }
+ /**
+ * Returns the desktop on which this task's window resides.
+ */
+ int desktop() const { return _info.desktop(); }
+#else
+ QString name() const { return _info.name; }
+ QString visibleName() const { return _info.visibleName; }
+ /**
+ * Returns the desktop on which this task's window resides.
+ */
+ int desktop() const { return _info.desktop; }
+#endif
+ QString visibleNameWithState() const { return _info.visibleNameWithState(); }
+ QString iconName() const;
+ QString visibleIconName() const;
+ QString className();
+ QString classClass();
+
+ /**
+ * A list of the window ids of all transient windows (dialogs) associated
+ * with this task.
+ */
+ QValueList<WId> transients() const { return _transients; }
+
+ /**
+ * Returns a 16x16 (KIcon::Small) icon for the task. This method will
+ * only fall back to a static icon if there is no icon of any size in
+ * the WM hints.
+ */
+ QPixmap pixmap() const { return _pixmap; }
+
+ /**
+ * Returns the best icon for any of the KIcon::StdSizes. If there is no
+ * icon of the specified size specified in the WM hints, it will try to
+ * get one using KIconLoader.
+ *
+ * <pre>
+ * bool gotStaticIcon;
+ * QPixmap icon = myTask->icon( KIcon::SizeMedium, gotStaticIcon );
+ * </pre>
+ *
+ * @param size Any of the constants in KIcon::StdSizes.
+ * @param isStaticIcon Set to true if KIconLoader was used, false otherwise.
+ * @see KIcon
+ */
+ QPixmap bestIcon( int size, bool &isStaticIcon );
+
+ /**
+ * Tries to find an icon for the task with the specified size. If there
+ * is no icon that matches then it will either resize the closest available
+ * icon or return a null pixmap depending on the value of allowResize.
+ *
+ * Note that the last icon is cached, so a sequence of calls with the same
+ * parameters will only query the NET properties if the icon has changed or
+ * none was found.
+ */
+ QPixmap icon( int width, int height, bool allowResize = false );
+
+ /**
+ * Returns true iff the windows with the specified ids should be grouped
+ * together in the task list.
+ */
+ static bool idMatch(const QString &, const QString &);
+
+ // state
+
+ /**
+ * Returns true if the task's window is maximized.
+ */
+ bool isMaximized() const;
+
+ /**
+ * Returns true if the task's window is iconified.
+ */
+ bool isIconified() const;
+
+ /**
+ * Returns true if the task's window is shaded.
+ */
+ bool isShaded() const;
+
+ /**
+ * Returns true if the task's window is the active window.
+ */
+ bool isActive() const;
+
+ /**
+ * Returns true if the task's window is the topmost non-iconified,
+ * non-always-on-top window.
+ */
+ bool isOnTop() const;
+
+ /**
+ * Returns true if the task's window is on the current virtual desktop.
+ */
+ bool isOnCurrentDesktop() const;
+
+ /**
+ * Returns true if the task's window is on all virtual desktops.
+ */
+ bool isOnAllDesktops() const;
+
+ /**
+ * Returns true if the task's window will remain at the top of the
+ * stacking order.
+ */
+ bool isAlwaysOnTop() const;
+
+ /**
+ * Returns true if the document the task is editing has been modified.
+ * This is currently handled heuristically by looking for the string
+ * '[i18n_modified]' in the window title where i18n_modified is the
+ * word 'modified' in the current language.
+ */
+ bool isModified() const ;
+
+ // internal
+
+ //* @internal
+ void refresh(bool icon = false);
+ //* @internal
+ void addTransient( WId w ) { _transients.append( w ); }
+ //* @internal
+ void removeTransient( WId w ) { _transients.remove( w ); }
+ //* @internal
+ bool hasTransient( WId w ) const { return _transients.contains( w ); }
+ //* @internal
+ void setActive(bool a);
+
+ // For thumbnails
+
+ /**
+ * Returns the current thumbnail size.
+ */
+ double thumbnailSize() const { return _thumbSize; }
+
+ /**
+ * Sets the size for the window thumbnail. For example a size of
+ * 0.2 indicates the thumbnail will be 20% of the original window
+ * size.
+ */
+ void setThumbnailSize( double size ) { _thumbSize = size; }
+
+ /**
+ * Returns true if this task has a thumbnail. Note that this method
+ * can only ever return true after a call to updateThumbnail().
+ */
+ bool hasThumbnail() const { return !_thumb.isNull(); }
+
+ /**
+ * Returns the thumbnail for this task (or a null image if there is
+ * none).
+ */
+ const QPixmap &thumbnail() const { return _thumb; }
+
+public slots:
+ // actions
+
+ /**
+ * Maximise the main window of this task.
+ */
+ void maximize();
+
+ /**
+ * Restore the main window of the task (if it was iconified).
+ */
+ void restore();
+
+ /**
+ * Iconify the task.
+ */
+ void iconify();
+
+ /**
+ * Activate the task's window.
+ */
+ void close();
+
+ /**
+ * Raise the task's window.
+ */
+ void raise();
+
+ /**
+ * Lower the task's window.
+ */
+ void lower();
+
+ /**
+ * Activate the task's window.
+ */
+ void activate();
+
+ /**
+ * Perform the action that is most appropriate for this task. If it
+ * is not active, activate it. Else if it is not the top window, raise
+ * it. Otherwise, iconify it.
+ */
+ void activateRaiseOrIconify();
+
+ /**
+ * If true, the task's window will remain at the top of the stacking order.
+ */
+ void setAlwaysOnTop(bool);
+ void toggleAlwaysOnTop();
+
+ /**
+ * If true then the task's window will be shaded. Most window managers
+ * represent this state by displaying on the window's title bar.
+ */
+ void setShaded(bool);
+ void toggleShaded();
+
+ /**
+ * Moves the task's window to the specified virtual desktop.
+ */
+ void toDesktop(int);
+
+ /**
+ * Moves the task's window to the current virtual desktop.
+ */
+ void toCurrentDesktop();
+
+ /**
+ * This method informs the window manager of the location at which this
+ * task will be displayed when iconised. It is used, for example by the
+ * KWin inconify animation.
+ */
+ void publishIconGeometry(QRect);
+
+ /**
+ * Tells the task to generate a new thumbnail. When the thumbnail is
+ * ready the thumbnailChanged() signal will be emitted.
+ */
+ void updateThumbnail();
+
+signals:
+ /**
+ * Indicates that this task has changed in some way.
+ */
+ void changed();
+
+ /**
+ * Indicates that the icon for this task has changed.
+ */
+ void iconChanged();
+
+ /**
+ * Indicates that this task is now the active task.
+ */
+ void activated();
+
+ /**
+ * Indicates that this task is no longer the active task.
+ */
+ void deactivated();
+
+ /**
+ * Indicates that the thumbnail for this task has changed.
+ */
+ void thumbnailChanged();
+
+protected slots:
+ //* @internal
+ void generateThumbnail();
+
+private:
+ bool _active;
+ WId _win;
+ QPixmap _pixmap;
+#ifdef KDE_3_2
+ KWin::WindowInfo _info;
+#else
+ KWin::Info _info;
+#endif
+ QValueList<WId> _transients;
+
+ int _lastWidth;
+ int _lastHeight;
+ bool _lastResize;
+ QPixmap _lastIcon;
+
+ double _thumbSize;
+ QPixmap _thumb;
+ QPixmap _grab;
+
+ class TaskPrivate *d;
+};
+
+/**
+ * Represents a task which is in the process of starting.
+ *
+ * @see TaskManager
+ */
+class Startup: public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY( QString text READ text )
+ Q_PROPERTY( QString bin READ bin )
+ Q_PROPERTY( QString icon READ icon )
+
+public:
+ Startup( const KStartupInfoId& id, const KStartupInfoData& data, QObject * parent,
+ const char *name = 0);
+ virtual ~Startup();
+
+ /**
+ * The name of the starting task (if known).
+ */
+ QString text() const { return _data.findName(); }
+
+ /**
+ * The name of the executable of the starting task.
+ */
+ QString bin() const { return _data.bin(); }
+
+ /**
+ * The name of the icon to be used for the starting task.
+ */
+ QString icon() const { return _data.findIcon(); }
+ void update( const KStartupInfoData& data );
+ const KStartupInfoId& id() const { return _id; }
+
+signals:
+ /**
+ * Indicates that this startup has changed in some way.
+ */
+ void changed();
+
+private:
+ KStartupInfoId _id;
+ KStartupInfoData _data;
+ class StartupPrivate *d;
+};
+
+typedef QPtrList<Task> TaskList;
+typedef QPtrList<Startup> StartupList;
+
+
+/**
+ * A generic API for task managers. This class provides an easy way to
+ * build NET compliant task managers. It provides support for startup
+ * notification, virtual desktops and the full range of WM properties.
+ *
+ * @see Task
+ * @see Startup
+ * @see KWinModule
+ * @version $Id: taskmanager.h,v 1.2 2004/11/17 10:16:47 kodaaja Exp $
+ */
+class TaskManager : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY( int currentDesktop READ currentDesktop )
+ Q_PROPERTY( int numberOfDesktops READ numberOfDesktops )
+
+public:
+ TaskManager( QObject *parent = 0, const char *name = 0 );
+ virtual ~TaskManager();
+
+ /**
+ * Returns a list of all current tasks. Return type changed to
+ * QPtrList in KDE 3.
+ */
+ TaskList tasks() const { return _tasks; }
+
+ /**
+ * Returns a list of all current startups. Return type changed to
+ * QPtrList in KDE 3.
+ */
+ StartupList startups() const { return _startups; }
+
+ /**
+ * Returns the name of the nth desktop.
+ */
+ QString desktopName(int n) const;
+
+ /**
+ * Returns the number of virtual desktops.
+ */
+ int numberOfDesktops() const;
+
+ /**
+ * Returns the number of the current desktop.
+ */
+ int currentDesktop() const;
+
+ /**
+ * Returns true if the specified task is on top.
+ */
+ bool isOnTop( const Task*);
+signals:
+ /**
+ * Emitted when the active window changed.
+ */
+ void activeTaskChanged(Task*);
+
+ /**
+ * Emitted when a new task has started.
+ */
+ void taskAdded(Task*);
+
+ /**
+ * Emitted when a task has terminated.
+ */
+ void taskRemoved(Task*);
+
+ /**
+ * Emitted when a new task is expected.
+ */
+ void startupAdded(Startup*);
+
+ /**
+ * Emitted when a startup item should be removed. This could be because
+ * the task has started, because it is known to have died, or simply
+ * as a result of a timeout.
+ */
+ void startupRemoved(Startup*);
+
+ /**
+ * Emitted when the current desktop changes.
+ */
+ void desktopChanged(int desktop);
+
+ /**
+ * Emitted when a window changes desktop.
+ */
+ void windowChanged(WId);
+
+protected slots:
+ //* @internal
+ void windowAdded(WId);
+ //* @internal
+ void windowRemoved(WId);
+ //* @internal
+ void windowChanged(WId, unsigned int);
+
+ //* @internal
+ void activeWindowChanged(WId);
+ //* @internal
+ void currentDesktopChanged(int);
+ //* @internal
+ void killStartup( const KStartupInfoId& );
+ //* @internal
+ void killStartup(Startup*);
+
+ //* @internal
+ void gotNewStartup( const KStartupInfoId&, const KStartupInfoData& );
+ //* @internal
+ void gotStartupChange( const KStartupInfoId&, const KStartupInfoData& );
+ //* @internal
+ void gotRemoveStartup( const KStartupInfoId& );
+
+protected:
+ /**
+ * Returns the task for a given WId, or 0 if there is no such task.
+ */
+ Task* findTask(WId w);
+ void configure_startup();
+
+private:
+ Task* _active;
+ TaskList _tasks;
+ QValueList< WId > _skiptaskbar_windows;
+ StartupList _startups;
+ KStartupInfo* _startup_info;
+
+ class TaskManagerPrivate *d;
+};
+
+#endif
diff --git a/superkaramba/src/textfield.cpp b/superkaramba/src/textfield.cpp
new file mode 100644
index 0000000..6578466
--- /dev/null
+++ b/superkaramba/src/textfield.cpp
@@ -0,0 +1,159 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Ralph M. Churchill *
+ * mrchucho@yahoo.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+
+#include "textfield.h"
+#include <qfontmetrics.h>
+#include <kdebug.h>
+
+TextField::TextField( )
+{
+ setFontSize(12);
+ setColor(QColor(192, 192, 192));
+ setBGColor(QColor(0, 0, 0));
+ setFont("Helvetica");
+ setAlignment(Qt::AlignLeft);
+ setFixedPitch(false);
+ setShadow(0);
+}
+
+TextField::~TextField()
+{
+}
+
+TextField::TextField( const TextField& def )
+{
+ setFontSize( def.getFontSize() );
+
+ setColor(def.getColor());
+ setBGColor(def.getBGColor());
+
+ setFont( def.getFont() );
+ setAlignment( def.getAlignment() );
+ setFixedPitch( def.getFixedPitch() );
+ setShadow( def.getShadow() );
+}
+
+TextField& TextField::operator=(const TextField& rhs)
+{
+ if( this == &rhs)
+ return *this;
+
+ setFontSize( rhs.getFontSize() );
+
+ setColor(rhs.getColor());
+ setBGColor(rhs.getBGColor());
+
+ setFont( rhs.getFont() );
+ setAlignment( rhs.getAlignment() );
+ setFixedPitch( rhs.getFixedPitch() );
+ setShadow( rhs.getShadow() );
+
+ return *this;
+}
+
+void TextField::setColor(QColor clr)
+{
+ color = clr;
+}
+
+QColor TextField::getColor() const
+{
+ return color;
+}
+
+void TextField::setBGColor(QColor clr)
+{
+ bgColor = clr;
+}
+
+QColor TextField::getBGColor() const
+{
+ return bgColor;
+}
+
+
+void TextField::setFont(const QString &f)
+{
+ font.setFamily(f);
+ lineHeight = QFontMetrics(font).height();
+}
+
+
+QString TextField::getFont() const
+{
+ return font.family();
+}
+
+void TextField::setFontSize(int size)
+{
+ font.setPointSize(size);
+ lineHeight = QFontMetrics(font).height();
+}
+
+int TextField::getFontSize() const
+{
+ return font.pointSize();
+}
+
+void TextField::setAlignment( const QString &align )
+{
+ QString a = align.upper();
+ if( a == "LEFT" || a.isEmpty() )
+ alignment = Qt::AlignLeft;
+ if( a == "RIGHT" )
+ alignment = Qt::AlignRight;
+ if( a == "CENTER" )
+ alignment = Qt::AlignHCenter;
+}
+
+void TextField::setAlignment( int af )
+{
+ alignment = af;
+}
+
+int TextField::getAlignment() const
+{
+ return alignment;
+}
+
+QString TextField::getAlignmentAsString() const
+{
+ if( alignment == Qt::AlignHCenter )
+ return "CENTER";
+ else if( alignment == Qt::AlignRight )
+ return "RIGHT";
+ else
+ return "LEFT";
+}
+
+void TextField::setFixedPitch( bool fp)
+{
+ font.setFixedPitch( fp );
+}
+
+bool TextField::getFixedPitch() const
+{
+ return font.fixedPitch();
+}
+
+void TextField::setShadow ( int s )
+{
+ shadow = s;
+}
+
+int TextField::getShadow() const
+{
+ return shadow;
+}
+
+int TextField::getLineHeight() const
+{
+ return lineHeight;
+}
diff --git a/superkaramba/src/textfield.h b/superkaramba/src/textfield.h
new file mode 100644
index 0000000..b24fff3
--- /dev/null
+++ b/superkaramba/src/textfield.h
@@ -0,0 +1,59 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Ralph M. Churchill *
+ * mrchucho@yahoo.com *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef TEXTFIELD_H
+#define TEXTFIELD_H
+#include <qstring.h>
+#include <qcolor.h>
+#include <qfont.h>
+
+/**
+ *
+ * Ralph M. Churchill
+ **/
+class TextField
+{
+public:
+ TextField();
+ TextField( const TextField& );
+ ~TextField();
+
+ TextField& operator=(const TextField& );
+
+ void setFontSize( int );
+ void setColor(QColor clr);
+ void setBGColor(QColor clr);
+ void setFont( const QString& );
+ void setAlignment( int );
+ void setAlignment( const QString& );
+ void setFixedPitch( bool );
+ void setShadow( int );
+
+ int getFontSize() const;
+ QColor getColor() const;
+ QColor getBGColor() const;
+ QString getFont() const;
+ int getAlignment() const;
+ QString getAlignmentAsString() const;
+ bool getFixedPitch() const;
+ int getShadow() const;
+ int getLineHeight() const;
+
+protected:
+ int alignment;
+ QFont font;
+ QColor color;
+ QColor bgColor;
+ int shadow;
+ int lineHeight;
+
+}
+;
+#endif // TEXTFIELD_H
diff --git a/superkaramba/src/textfilesensor.cpp b/superkaramba/src/textfilesensor.cpp
new file mode 100644
index 0000000..cad696f
--- /dev/null
+++ b/superkaramba/src/textfilesensor.cpp
@@ -0,0 +1,109 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Hans Karlsson *
+ * karlsson.h@home.se *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "textfilesensor.h"
+#include "qdom.h"
+
+TextFileSensor::TextFileSensor( const QString &fn, bool iRdf, int interval, const QString &encoding )
+ : Sensor( interval )
+{
+ fileName = fn;
+ rdf = iRdf;
+
+ if( !encoding.isEmpty() )
+ {
+ codec = QTextCodec::codecForName( encoding.ascii() );
+ if ( codec == 0)
+ codec = QTextCodec::codecForLocale();
+ }
+ else
+ codec = QTextCodec::codecForLocale();
+}
+
+TextFileSensor::~TextFileSensor()
+{}
+
+void TextFileSensor::update()
+{
+ QValueVector<QString> lines;
+ QFile file(fileName);
+ QString line;
+ if ( file.open(IO_ReadOnly | IO_Translate) )
+ {
+ if (rdf)
+ {
+ QDomDocument doc;
+ if ( !doc.setContent( &file ) )
+ {
+ file.close();
+ return;
+ }
+ QDomElement docElem = doc.documentElement();
+ QDomNode n = docElem.firstChild();
+ if (!n.isNull())
+ {
+ QDomNodeList titles = docElem.elementsByTagName( "title" );
+ QDomNodeList links = docElem.elementsByTagName( "link" );
+
+ uint i;
+ for ( i = 0; i < titles.count(); ++i )
+ {
+ QDomElement element = titles.item( i ).toElement();
+ lines.push_back(element.text());
+
+ element = links.item( i ).toElement();
+ lines.push_back(element.text());
+ }
+ }
+ }
+ else
+ {
+ QTextStream t( &file ); // use a text stream
+ while( (line = t.readLine()) !=0 )
+ {
+ lines.push_back(line);
+ }
+ }
+ file.close();
+ }
+
+ int lineNbr;
+ SensorParams *sp;
+ Meter *meter;
+
+ int count = (int) lines.size();
+ QObjectListIt it( *objList );
+ while (it != 0)
+ {
+ sp = (SensorParams*)(*it);
+ meter = sp->getMeter();
+ lineNbr = (sp->getParam("LINE")).toInt();
+ if ( lineNbr >= 1 && lineNbr <= (int) count )
+ {
+ meter->setValue(lines[lineNbr-1]);
+ }
+ if ( -lineNbr >= 1 && -lineNbr <= (int) count )
+ {
+ meter->setValue(lines[count+lineNbr]);
+ }
+
+ if ( lineNbr == 0 )
+ {
+ QString text;
+ for( int i=0; i < count; i++ )
+ {
+ text += lines[i] + "\n";
+ }
+ meter->setValue( text );
+ }
+ ++it;
+ }
+}
+
+#include "textfilesensor.moc"
diff --git a/superkaramba/src/textfilesensor.h b/superkaramba/src/textfilesensor.h
new file mode 100644
index 0000000..1d5951b
--- /dev/null
+++ b/superkaramba/src/textfilesensor.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+ * Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+ * Copyright (c) 2005 Ryan Nickell <p0z3r@earthlink.net>
+ *
+ * This file is part of SuperKaramba.
+ *
+ * SuperKaramba 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.
+ *
+ * SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+#ifndef TEXTFILESENSOR_H
+#define TEXTFILESENSOR_H
+
+
+#include <sensor.h>
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qstring.h>
+#include <qtextcodec.h>
+#include <qvaluevector.h>
+/**
+ *
+ * Hans Karlsson
+ **/
+class TextFileSensor : public Sensor
+{
+
+Q_OBJECT
+public:
+ TextFileSensor( const QString &fileName, bool rdf, int interval, const QString &encoding=QString::null );
+
+ ~TextFileSensor();
+
+ void update();
+
+private:
+QTextCodec *codec;
+QString fileName;
+bool rdf;
+};
+
+#endif // TEXTFILESENSOR_H
diff --git a/superkaramba/src/textlabel.cpp b/superkaramba/src/textlabel.cpp
new file mode 100644
index 0000000..69fb841
--- /dev/null
+++ b/superkaramba/src/textlabel.cpp
@@ -0,0 +1,379 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Hans Karlsson *
+ * karlsson.h@home.se *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+
+#include <krun.h>
+#include <stdlib.h>
+#include "textlabel.h"
+
+TextLabel::TextLabel(karamba *k, int x,int y,int w,int h):
+ Meter(k, x,y,w,h), alignment(Qt::AlignLeft), clip(0), bgColor(0, 0, 0),
+ lineHeight(0), shadow(0), scrollSpeed(0, 0), scrollPos(0, 0), scrollGap(0),
+ scrollPause(0), pauseCounter(0), scrollType(ScrollNone)
+{
+ calculateTextSize();
+ if( h != 0 || w != 0)
+ clip = 0;
+ else
+ clip = Qt::DontClip;
+
+ if( h == 0 || w == 0)
+ {
+ setWidth(-1);
+ setHeight(-1);
+ }
+}
+
+TextLabel::TextLabel(karamba *k):
+ Meter(k, 0, 0, 0, 0), alignment(Qt::AlignLeft), clip(0), bgColor(0, 0, 0),
+ lineHeight(0), shadow(0), scrollSpeed(0, 0), scrollPos(0, 0), scrollGap(0),
+ scrollPause(0), pauseCounter(0), scrollType(ScrollNone)
+{
+}
+
+TextLabel::~TextLabel()
+{
+}
+
+void TextLabel::show()
+{
+ Meter::show();
+ setEnabled(true);
+}
+
+void TextLabel::hide()
+{
+ Meter::hide();
+ setEnabled(false);
+}
+
+void TextLabel::setTextProps( TextField* t )
+{
+ if(t)
+ {
+ text = *t;
+ //lineHeight = t->getLineHeight();
+ shadow = t->getShadow();
+ alignment = t->getAlignment();
+ setFontSize(t->getFontSize());
+ setFont(t->getFont());
+
+ setColor(t->getColor());
+ setBGColor(t->getBGColor());
+ }
+ calculateTextSize();
+}
+
+void TextLabel::calculateTextSize()
+{
+ int tmp;
+ QFontMetrics fm(font);
+ lineHeight = fm.height();
+ textSize.setWidth(0);
+ textSize.setHeight(lineHeight * value.count());
+ QStringList::Iterator it = value.begin();
+ while(it != value.end())
+ {
+ tmp = fm.width(*it);
+ if(tmp > textSize.width())
+ textSize.setWidth(tmp);
+ ++it;
+ }
+}
+
+void TextLabel::setValue( QString text)
+{
+ value = QStringList::split('\n',text);
+ calculateTextSize();
+}
+
+void TextLabel::setValue( long v)
+{
+ value = QStringList( QString::number( v ) );
+ calculateTextSize();
+}
+
+void TextLabel::setBGColor(QColor clr)
+{
+ bgColor = clr;
+}
+
+QColor TextLabel::getBGColor() const
+{
+ return bgColor;
+}
+
+void TextLabel::setFont(QString f)
+{
+ font.setFamily(f);
+ calculateTextSize();
+}
+
+QString TextLabel::getFont() const
+{
+ return font.family();
+}
+
+void TextLabel::setFontSize(int size)
+{
+ font.setPixelSize(size);
+ calculateTextSize();
+}
+
+int TextLabel::getFontSize() const
+{
+ return font.pixelSize();
+}
+
+void TextLabel::setAlignment( QString align )
+{
+ QString a = align.upper();
+ if( a == "LEFT" || a.isEmpty() )
+ alignment = Qt::AlignLeft;
+ if( a == "RIGHT" )
+ alignment = Qt::AlignRight;
+ if( a == "CENTER" )
+ alignment = Qt::AlignHCenter;
+}
+
+QString TextLabel::getAlignment() const
+{
+ if( alignment == Qt::AlignHCenter )
+ return "CENTER";
+ else if( alignment == Qt::AlignRight )
+ return "RIGHT";
+ else
+ return "LEFT";
+}
+
+void TextLabel::setFixedPitch( bool fp)
+{
+ font.setFixedPitch( fp );
+}
+
+bool TextLabel::getFixedPitch() const
+{
+ return font.fixedPitch();
+}
+
+void TextLabel::setShadow ( int s )
+{
+ shadow = s;
+}
+
+int TextLabel::getShadow() const
+{
+ return shadow;
+}
+
+void TextLabel::setScroll(char* type, QPoint speed, int gap, int pause)
+{
+ ScrollType t = TextLabel::ScrollNone;
+ QString a = type;
+ a = a.upper();
+ if(a == "NONE")
+ t = TextLabel::ScrollNone;
+ else if( a == "NORMAL" )
+ t = TextLabel::ScrollNormal;
+ else if( a == "BACKANDFORTH" )
+ t = TextLabel::ScrollBackAndForth;
+ else if( a == "ONEPASS" )
+ t = TextLabel::ScrollOnePass;
+ setScroll(t, speed, gap, pause);
+}
+
+void TextLabel::setScroll(ScrollType type, QPoint speed, int gap, int pause)
+{
+ scrollType = type;
+ scrollSpeed = speed;
+ switch(scrollType)
+ {
+ case ScrollNormal:
+ case ScrollOnePass:
+ {
+ int x = 0, y = 0;
+
+ if(speed.x() > 0)
+ x = -1 * textSize.width();
+ else if(speed.x() < 0)
+ x = getWidth()-1;
+ if(speed.y() > 0)
+ x = -1 * textSize.height();
+ else if(speed.y() < 0)
+ x = getHeight()-1;
+ scrollPos = QPoint(x,y);
+ break;
+ }
+ case ScrollNone:
+ case ScrollBackAndForth:
+ default:
+ scrollPos = QPoint(0,0);
+ break;
+ }
+ scrollGap = gap;
+ scrollPause = pause;
+ pauseCounter = 1;
+}
+
+int TextLabel::drawText(QPainter *p, int x, int y, int width, int height,
+ QString text)
+{
+ if( shadow != 0)
+ {
+ p->setPen(getBGColor());
+ p->drawText(x + shadow, y + shadow, width, height,
+ alignment | clip | Qt::ExpandTabs, text);
+ }
+ p->setPen(getColor());
+ p->drawText(x, y, width, height, alignment | clip | Qt::ExpandTabs, text);
+ return 0;
+}
+
+bool TextLabel::calculateScrollCoords(QRect meterRect, QRect &textRect,
+ QPoint &next, int &x, int &y)
+{
+ if(scrollType == ScrollBackAndForth &&
+ (scrollSpeed.x() != 0 && textSize.width() < getWidth() ||
+ scrollSpeed.y() != 0 && textSize.height() < getHeight()))
+ return true;
+
+ x += scrollPos.x();
+ y += scrollPos.y();
+
+ if(pauseCounter < 1)
+ {
+ scrollPos += scrollSpeed;
+
+ // -1 | 0 | 1
+ QPoint direction(scrollSpeed.x()/abs((scrollSpeed.x() == 0)?
+ 1:scrollSpeed.x()),
+ scrollSpeed.y()/abs((scrollSpeed.y() == 0)?
+ 1:scrollSpeed.y()));
+ next = QPoint(-1 * direction.x() * (scrollGap + textSize.width()),
+ -1 * direction.y() * (scrollGap + textSize.height()));
+ textRect.setCoords(x, y, x + textSize.width(), y + textSize.height());
+
+ if(scrollType == ScrollBackAndForth)
+ {
+ if(direction.x() < 0 && textRect.right() <= meterRect.right() ||
+ direction.x() > 0 && textRect.left() >= meterRect.left())
+ {
+ scrollSpeed.setX(scrollSpeed.x() * -1);
+ pauseCounter = scrollPause;
+ }
+ if(direction.y() < 0 && textRect.bottom() <= meterRect.bottom() ||
+ direction.y() > 0 && textRect.top() >= meterRect.top())
+ {
+ scrollSpeed.setY(scrollSpeed.y() * -1);
+ pauseCounter = scrollPause;
+ }
+ }
+ else if(!textRect.intersects(meterRect))
+ {
+ if(scrollType == ScrollNormal)
+ scrollPos += next;
+ else if(scrollType == ScrollOnePass)
+ return false;
+ }
+ }
+ else
+ --pauseCounter;
+ return true;
+}
+
+void TextLabel::mUpdate(QPainter *p)
+{
+ if (hidden != 1)
+ {
+ int i = 0; //lineHeight;
+ int row = 1;
+ int x = getX();
+ int y = getY();
+ int width = getWidth();
+ int height = getHeight();
+ QRect meterRect(x, y, width, height);
+ QRect textRect;
+ QPoint next;
+
+ p->setFont(font);
+ if(scrollType != ScrollNone)
+ {
+ p->setClipRect(x, y, width, height);
+ if(!calculateScrollCoords(meterRect, textRect, next, x, y))
+ {
+ p->setClipping(false);
+ return;
+ }
+ width = textSize.width();
+ height = textSize.height();
+ }
+ QStringList::Iterator it = value.begin();
+ while(it != value.end() && (row <= height || height == -1 ))
+ {
+ drawText(p, x, y + i, width, height, *it);
+
+ // Draw more instances of text if scroll type is normal scroll
+ if(scrollType == ScrollNormal)
+ {
+ textRect.addCoords(next.x(), next.y(), next.x(), next.y());
+ while(textRect.intersects(meterRect))
+ {
+ drawText(p, textRect.x(), textRect.y() + i, width, height, *it);
+ textRect.addCoords(next.x(), next.y(), next.x(), next.y());
+ }
+ }
+ i += lineHeight;
+ it++;
+ row++;
+ }
+ if(scrollType != ScrollNone)
+ p->setClipping(false);
+ }
+}
+
+bool TextLabel::click(QMouseEvent* e)
+{
+ if (getBoundingBox().contains(e -> x(), e -> y()) && isEnabled())
+ {
+ QString program;
+ if (e -> button() == Qt::LeftButton)
+ {
+ program = leftButtonAction;
+ }
+ else if (e -> button() == Qt::MidButton)
+ {
+ program = middleButtonAction;
+ }
+ else if (e -> button() == Qt::RightButton)
+ {
+ program = rightButtonAction;
+ }
+
+ if( !program.isEmpty() )
+ {
+ KRun::runCommand(program);
+ }
+ else
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+void TextLabel::attachClickArea(QString leftMouseButton,
+ QString middleMouseButton,
+ QString rightMouseButton)
+{
+ leftButtonAction = leftMouseButton;
+ middleButtonAction = middleMouseButton;
+ rightButtonAction = rightMouseButton;
+}
+
+#include "textlabel.moc"
diff --git a/superkaramba/src/textlabel.h b/superkaramba/src/textlabel.h
new file mode 100644
index 0000000..e8fc9e4
--- /dev/null
+++ b/superkaramba/src/textlabel.h
@@ -0,0 +1,87 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Hans Karlsson *
+ * karlsson.h@home.se *
+ * *
+ * 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. *
+ ***************************************************************************/
+#ifndef TEXTLABEL_H
+#define TEXTLABEL_H
+#include "meter.h"
+#include <qstring.h>
+#include <qpainter.h>
+#include <qcolor.h>
+#include <qfont.h>
+#include <qfontmetrics.h>
+#include <qstringlist.h>
+#include <qrect.h>
+
+#include "textfield.h"
+
+class TextLabel : public Meter
+{
+Q_OBJECT
+public:
+ enum ScrollType { ScrollNone, ScrollNormal,
+ ScrollBackAndForth, ScrollOnePass };
+
+ TextLabel(karamba *k, int x,int y,int w,int h);
+ TextLabel(karamba *k);
+ ~TextLabel();
+
+ void setTextProps( TextField* );
+ void setValue( QString );
+ void setValue( long );
+ //virtual QString getStringValue() const { return value.join("\n"); };
+ QString getStringValue() const { return value.join("\n"); };
+ void setFontSize( int );
+ void setBGColor(QColor clr);
+ void setFont( QString );
+ void setAlignment( QString );
+ void setFixedPitch( bool );
+ void setShadow( int );
+ void mUpdate( QPainter * );
+
+ virtual void show();
+ virtual void hide();
+ int getFontSize() const;
+ QColor getBGColor() const;
+ QString getFont() const;
+ QString getAlignment() const;
+ bool getFixedPitch() const;
+ int getShadow() const;
+ void setScroll(ScrollType type, QPoint speed, int gap, int pause);
+ void setScroll(char* type, QPoint speed, int gap, int pause);
+
+ void attachClickArea(QString leftMouseButton, QString middleMouseButton,
+ QString rightMouseButton);
+
+ virtual bool click(QMouseEvent*);
+
+private:
+ int alignment;
+ int clip;
+ QStringList value;
+ QFont font;
+ QColor bgColor;
+ int lineHeight;
+ QSize textSize;
+ int shadow;
+ TextField text;
+ QPoint scrollSpeed;
+ QPoint scrollPos;
+ int scrollGap;
+ int scrollPause;
+ int pauseCounter;
+ ScrollType scrollType;
+
+ int drawText(QPainter *p, int x, int y, int width, int height,
+ QString text);
+ bool calculateScrollCoords(QRect meterRect, QRect &textRect,
+ QPoint &next, int &x, int &y);
+ void calculateTextSize();
+};
+
+#endif // TEXTLABEL_H
diff --git a/superkaramba/src/textlabel_python.cpp b/superkaramba/src/textlabel_python.cpp
new file mode 100644
index 0000000..0802be9
--- /dev/null
+++ b/superkaramba/src/textlabel_python.cpp
@@ -0,0 +1,235 @@
+/****************************************************************************
+* textlabel_python.cpp - Functions for textlabel python api
+*
+* Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+* Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+* Copyright (c) 2004 Petri Damstn <damu@iki.fi>
+*
+* This file is part of SuperKaramba.
+*
+* SuperKaramba 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.
+*
+* SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+#ifdef _XOPEN_SOURCE
+#undef _XOPEN_SOURCE
+#endif
+
+#include <Python.h>
+#include <qobject.h>
+#include "karamba.h"
+#include "textlabel.h"
+#include "meter_python.h"
+#include "textlabel_python.h"
+
+PyObject* py_createText(PyObject *, PyObject *args)
+{
+ long widget, x, y, w, h;
+ PyObject *text;
+ if (!PyArg_ParseTuple(args, (char*)"lllllO:createText", &widget, &x, &y, &w, &h, &text))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ TextLabel *tmp =
+ new TextLabel((karamba*)widget, (int)x, (int)y, (int)w, (int)h);
+ tmp->setValue(PyString2QString(text));
+ tmp->setTextProps(((karamba*)widget)->getDefaultTextProps());
+ ((karamba*)widget)->meterList->append(tmp);
+ return (Py_BuildValue((char*)"l", (long)tmp));
+}
+
+PyObject* py_deleteText(PyObject *, PyObject *args)
+{
+ long widget, meter;
+ if (!PyArg_ParseTuple(args, (char*)"ll:deleteText", &widget, &meter))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, meter, "TextLabel"))
+ return NULL;
+
+ ((karamba*)widget)->deleteMeterFromSensors((Meter*)meter);
+ ((karamba*)widget)->clickList->removeRef((Meter*)meter);
+ return Py_BuildValue((char*)"l",
+ ((karamba*)widget)->meterList->removeRef((Meter*)meter));
+}
+
+PyObject* py_getThemeText(PyObject *self, PyObject *args)
+{
+ return py_getThemeMeter(self, args, "TextLabel");
+}
+
+PyObject* py_getTextSize(PyObject *self, PyObject *args)
+{
+ return py_getSize(self, args, "TextLabel");
+}
+
+PyObject* py_resizeText(PyObject *self, PyObject *args)
+{
+ return py_resize(self, args, "TextLabel");
+}
+
+PyObject* py_getTextPos(PyObject *self, PyObject *args)
+{
+ return py_getPos(self, args, "TextLabel");
+}
+
+PyObject* py_moveText(PyObject *self, PyObject *args)
+{
+ return py_move(self, args, "TextLabel");
+}
+
+PyObject* py_hideText(PyObject *self, PyObject *args)
+{
+ return py_hide(self, args, "TextLabel");
+}
+
+PyObject* py_showText(PyObject *self, PyObject *args)
+{
+ return py_show(self, args, "TextLabel");
+}
+
+PyObject* py_getTextValue(PyObject *self, PyObject *args)
+{
+ return py_getStringValue(self, args, "TextLabel");
+}
+
+PyObject* py_setTextValue(PyObject *self, PyObject *args)
+{
+ return py_setStringValue(self, args, "TextLabel");
+}
+
+PyObject* py_getTextSensor(PyObject *self, PyObject *args)
+{
+ return py_getSensor(self, args, "TextLabel");
+}
+
+PyObject* py_setTextSensor(PyObject *self, PyObject *args)
+{
+ return py_setSensor(self, args, "TextLabel");
+}
+
+PyObject* py_getTextColor(PyObject *self, PyObject *args)
+{
+ return py_getColor(self, args, "TextLabel");
+}
+
+PyObject* py_setTextColor(PyObject *self, PyObject *args)
+{
+ return py_setColor(self, args, "TextLabel");
+}
+
+PyObject* py_setTextShadow(PyObject *, PyObject *args)
+{
+ long widget, textSensor;
+ long shadow;
+ if (!PyArg_ParseTuple(args, (char*)"lll:changeTextShadow",
+ &widget, &textSensor, &shadow))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, textSensor, "TextLabel"))
+ return NULL;
+ ((TextLabel*)textSensor)->setShadow( shadow );
+ return Py_BuildValue((char*)"l", 1);
+}
+
+PyObject* py_getTextShadow(PyObject *, PyObject *args)
+{
+ long widget, textSensor;
+ if (!PyArg_ParseTuple(args, (char*)"ll:getTextShadow", &widget, &textSensor))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, textSensor, "TextLabel"))
+ return NULL;
+ return Py_BuildValue((char*)"l", ((TextLabel*)textSensor)->getShadow());
+}
+
+PyObject* py_setTextFontSize(PyObject *, PyObject *args)
+{
+ long widget, textSensor;
+ long size;
+ if (!PyArg_ParseTuple(args, (char*)"lll:changeTextSize",
+ &widget, &textSensor, &size))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, textSensor, "TextLabel"))
+ return NULL;
+ ((TextLabel*)textSensor)->setFontSize( size );
+ return Py_BuildValue((char*)"l", 1);
+}
+
+PyObject* py_getTextFontSize(PyObject *, PyObject *args)
+{
+ long widget, textSensor;
+ if (!PyArg_ParseTuple(args, (char*)"ll:getTextSize", &widget, &textSensor))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, textSensor, "TextLabel"))
+ return NULL;
+ return Py_BuildValue((char*)"l", ((TextLabel*)textSensor)->getFontSize());
+}
+
+PyObject* py_setTextFont(PyObject *, PyObject *args)
+{
+ long widget, textSensor;
+ char* text;
+ if (!PyArg_ParseTuple(args, (char*)"lls:changeTextFont",
+ &widget, &textSensor, &text))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, textSensor, "TextLabel"))
+ return NULL;
+ ((TextLabel*)textSensor)->setFont( text );
+ return Py_BuildValue((char*)"l", 1);
+}
+
+PyObject* py_getTextFont(PyObject *, PyObject *args)
+{
+ long widget, textSensor;
+ if (!PyArg_ParseTuple(args, (char*)"ll:getTextFont", &widget, &textSensor))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, textSensor, "TextLabel"))
+ return NULL;
+ return Py_BuildValue((char*)"s", ((TextLabel*)textSensor)->getFont().ascii());
+}
+
+PyObject* py_setTextAlign(PyObject *, PyObject *args)
+{
+ long widget, textSensor;
+ char* text;
+ if (!PyArg_ParseTuple(args, (char*)"lls:changeTextFont",
+ &widget, &textSensor, &text))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, textSensor, "TextLabel"))
+ return NULL;
+ ((TextLabel*)textSensor)->setAlignment( text );
+ return Py_BuildValue((char*)"l", 1);
+}
+
+PyObject* py_getTextAlign(PyObject *, PyObject *args)
+{
+ long widget, textSensor;
+ if (!PyArg_ParseTuple(args, (char*)"ll:getTextFont", &widget, &textSensor))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, textSensor, "TextLabel"))
+ return NULL;
+ return Py_BuildValue((char*)"s", ((TextLabel*)textSensor)->getAlignment().ascii());
+}
+
+PyObject* py_setTextScroll(PyObject *, PyObject *args)
+{
+ long widget, textSensor;
+ char* type;
+ int x=0, y=0, pause=0, gap=0;
+ if (!PyArg_ParseTuple(args, (char*)"lls|llll:setScroll",
+ &widget, &textSensor, &type, &x, &y, &gap, &pause))
+ return NULL;
+ if (!checkKarambaAndMeter(widget, textSensor, "TextLabel"))
+ return NULL;
+ ((TextLabel*)textSensor)->setScroll(type, QPoint(x,y), gap, pause);
+ return Py_BuildValue((char*)"l", 1);
+}
diff --git a/superkaramba/src/textlabel_python.h b/superkaramba/src/textlabel_python.h
new file mode 100644
index 0000000..78e047a
--- /dev/null
+++ b/superkaramba/src/textlabel_python.h
@@ -0,0 +1,397 @@
+/****************************************************************************
+* textlabel_python.h - Functions for textlabel python api
+*
+* Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+* Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+* Copyright (c) 2004 Petri Damstn <damu@iki.fi>
+*
+* This file is part of SuperKaramba.
+*
+* SuperKaramba 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.
+*
+* SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+#ifndef TEXTLABEL_PYTHON_H
+#define TEXTLABEL_PYTHON_H
+
+/** Text/createText
+*
+* SYNOPSIS
+* long createText(widget, x, y, w, h, text)
+* DESCRIPTION
+* This creates a text at x,y with width and height w,h. You need to save
+* the return value of this function to call other functions on your text
+* field, such as changeText()
+* ARGUMENTS
+* * long widget -- karamba
+* * long x -- x coordinate
+* * long y -- y coordinate
+* * long w -- width
+* * long h -- height
+* * string text -- text for the textlabel
+* RETURN VALUE
+* Pointer to new text meter
+*/
+PyObject* py_createText(PyObject *self, PyObject *args);
+
+/** Text/deleteText
+*
+* SYNOPSIS
+* long deleteText(widget, text)
+* DESCRIPTION
+* This removes a text object from memory. Please do not call functions on
+* "text" after calling deleteText, as it does not exist anymore and that
+* could cause crashes in some cases.
+* ARGUMENTS
+* * long widget -- karamba
+* * long widget -- text
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_deleteText(PyObject *self, PyObject *args);
+
+/** Text/getThemeText
+*
+* SYNOPSIS
+* long getThemeText(widget, name)
+* DESCRIPTION
+* You can reference text in your python code that was created in the
+* theme file. Basically, you just add a NAME= value to the TEXT line in
+* the .theme file. Then if you want to use that object, instead of calling
+* createText, you can call this function.
+*
+* The name you pass to the function is the same one that you gave it for
+* the NAME= parameter in the .theme file.
+* ARGUMENTS
+* * long widget -- karamba
+* * string name -- name of the text to get
+* RETURN VALUE
+* Pointer to text
+*/
+PyObject* py_getThemeText(PyObject *self, PyObject *args);
+
+/** Text/getTextSize
+*
+* SYNOPSIS
+* tuple getTextSize(widget, text)
+* DESCRIPTION
+* Given a reference to a text object, this will return a tuple
+* containing the height and width of a text object.
+* ARGUMENTS
+* * long widget -- karamba
+* * long text -- pointer to text
+* RETURN VALUE
+* size
+*/
+PyObject* py_getTextSize(PyObject *self, PyObject *args);
+
+/** Text/resizeText
+*
+* SYNOPSIS
+* long resizeText(widget, text, w, h)
+* DESCRIPTION
+* This will resize text to new height and width.
+* ARGUMENTS
+* * long widget -- karamba
+* * long text -- pointer to text
+* * long w -- new width
+* * long h -- new height
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_resizeText(PyObject *self, PyObject *args);
+
+/** Text/getTextPos
+*
+* SYNOPSIS
+* tuple getTextPos(widget, text)
+* DESCRIPTION
+* Given a reference to a text object, this will return a tuple
+* containing the x and y coordinate of a text object.
+* ARGUMENTS
+* * long widget -- karamba
+* * long text -- pointer to text
+* RETURN VALUE
+* pos
+*/
+PyObject* py_getTextPos(PyObject *self, PyObject *args);
+
+/** Text/moveText
+*
+* SYNOPSIS
+* long moveText(widget, text, x, y)
+* DESCRIPTION
+* This moves a text object to a new x, y relative to your widget. In other
+* words, (0,0) is the top corner of your widget, not the screen.
+* ARGUMENTS
+* * long widget -- karamba
+* * long text -- pointer to text
+* * long x -- x coordinate
+* * long y -- y coordinate
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_moveText(PyObject *self, PyObject *args);
+
+/** Text/hideText
+*
+* SYNOPSIS
+* long hideText(widget, text)
+* DESCRIPTION
+* Hides text that is visible. You need to call redrawWidget() afterwords
+* to actually hide the text on screen.
+* ARGUMENTS
+* * long widget -- karamba
+* * long text -- pointer to text
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_hideText(PyObject *self, PyObject *args);
+
+/** Text/showText
+*
+* SYNOPSIS
+* long showText(widget, text)
+* DESCRIPTION
+* Shows text that has been hidden with hideText()
+* ARGUMENTS
+* * long widget -- karamba
+* * long text -- pointer to text
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_showText(PyObject *self, PyObject *args);
+
+/** Text/getTextValue
+*
+* SYNOPSIS
+* string getTextValue(widget, text)
+* DESCRIPTION
+* Returns current text value.
+* ARGUMENTS
+* * long widget -- karamba
+* * long text -- pointer to text
+* RETURN VALUE
+* value
+*/
+PyObject* py_getTextValue(PyObject *self, PyObject *args);
+
+/** Text/changeText
+*
+* SYNOPSIS
+* long changeText(widget, text, value)
+* DESCRIPTION
+* This will change the contents of a text widget.
+* ARGUMENTS
+* * long widget -- karamba
+* * long text -- pointer to text
+* * long value -- new value
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_setTextValue(PyObject *self, PyObject *args);
+
+/** Text/getTextSensor
+*
+* SYNOPSIS
+* string getTextSensor(widget, text)
+* DESCRIPTION
+* Get current sensor string
+* ARGUMENTS
+* * long widget -- karamba
+* * long text -- pointer to text
+* RETURN VALUE
+* sensor string
+*/
+PyObject* py_getTextSensor(PyObject *self, PyObject *args);
+
+/** Text/setTextSensor
+*
+* SYNOPSIS
+* long setTextSensor(widget, text, sensor)
+* DESCRIPTION
+* Get current sensor string
+* ARGUMENTS
+* * long widget -- karamba
+* * long text -- pointer to text
+* * string sensor -- new sensor as in theme files
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_setTextSensor(PyObject *self, PyObject *args);
+
+/** Text/changeTextShadow
+*
+* SYNOPSIS
+* long changeTextShadow(widget, text, shadow)
+* DESCRIPTION
+* This will change the shadow size of a text widget (only ones you
+* created through python currently). textToChange is the reference to the
+* text object to change that you saved from the createText() call. size
+* is the offset of the shadow in pixels. 1 or 2 is a good value in most
+* cases. Get current sensor string
+* ARGUMENTS
+* * long widget -- karamba
+* * long text -- pointer to text
+* * long shadow -- shadow offset
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_setTextShadow(PyObject *self, PyObject *args);
+
+/** Text/getTextShadow
+*
+* SYNOPSIS
+* long getTextShadow(widget, text)
+* DESCRIPTION
+* Get current shadow offset
+* ARGUMENTS
+* * long widget -- karamba
+* * long text -- pointer to text
+* RETURN VALUE
+* shadow offset
+*/
+PyObject* py_getTextShadow(PyObject *self, PyObject *args);
+
+/** Text/changeTextSize
+*
+* SYNOPSIS
+* long changeTextSize(widget, text, size)
+* DESCRIPTION
+* This will change the font size of a text widget (only ones you created
+* through python currently). textToChange is the reference to the text
+* object to change that you saved from the createText() call. size is the
+* new font point size.
+* ARGUMENTS
+* * long widget -- karamba
+* * long text -- pointer to text
+* * long size -- new size for text
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_setTextFontSize(PyObject *self, PyObject *args);
+
+/** Text/getTextFontSize
+*
+* SYNOPSIS
+* long getTextFontSize(widget, text)
+* DESCRIPTION
+* Get current text font size
+* ARGUMENTS
+* * long widget -- karamba
+* * long text -- pointer to text
+* RETURN VALUE
+* text font size
+*/
+PyObject* py_getTextFontSize(PyObject *self, PyObject *args);
+
+/** Text/changeTextColor
+*
+* SYNOPSIS
+* long changeTextColor(widget, text, r, g, b)
+* DESCRIPTION
+* This will change the color of a text widget (only ones you created
+* through python currently). textToChange is the reference to the text
+* object to change that you saved from the createText() call. r, g, b are
+* ints from 0 to 255 that represent red, green, and blue.
+* ARGUMENTS
+* * long widget -- karamba
+* * long text -- pointer to text
+* * long red -- red component of color
+* * long green -- green component of color
+* * long blue -- blue component of color
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_setTextColor(PyObject *self, PyObject *args);
+
+/** Text/getTextColor
+*
+* SYNOPSIS
+* tuple getTextColor(widget, text)
+* DESCRIPTION
+* Get current text color
+* ARGUMENTS
+* * long widget -- karamba
+* * long text -- pointer to text
+* RETURN VALUE
+* (red, green, blue)
+*/
+PyObject* py_getTextColor(PyObject *self, PyObject *args);
+
+/** Text/changeTextFont
+*
+* SYNOPSIS
+* long changeTextFont(widget, text, font)
+* DESCRIPTION
+* This will change the font of a text widget (only ones you created
+* through python currently). Text is the reference to the text
+* object to change that you saved from the createText() call. Font is a
+* string the the name of the font to use.
+* ARGUMENTS
+* * long widget -- karamba
+* * long text -- pointer to text
+* * string font -- font name
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_setTextFont(PyObject *self, PyObject *args);
+
+/** Text/getTextFont
+*
+* SYNOPSIS
+* string getTextFont(widget, text)
+* DESCRIPTION
+* Get current text font name
+* ARGUMENTS
+* * long widget -- karamba
+* * long text -- pointer to text
+* RETURN VALUE
+* font name
+*/
+PyObject* py_getTextFont(PyObject *self, PyObject *args);
+
+/** Text/setTextAlign
+*
+* SYNOPSIS
+* long setTextAlign(widget, text, align)
+* DESCRIPTION
+* Sets text label align.
+* ARGUMENTS
+* * long widget -- karamba
+* * long text -- pointer to text
+* * string align -- LEFT, CENTER or RIGHT
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_setTextAlign(PyObject *self, PyObject *args);
+
+/** Text/getTextAlign
+*
+* SYNOPSIS
+* string getTextAlign(widget, text)
+* DESCRIPTION
+* Get current text align.
+* ARGUMENTS
+* * long widget -- karamba
+* * long text -- pointer to text
+* RETURN VALUE
+* LEFT, CENTER or RIGHT
+*/
+PyObject* py_getTextAlign(PyObject *self, PyObject *args);
+
+// XXX: Is this valid for new release
+PyObject* py_setTextScroll(PyObject *self, PyObject *args);
+
+#endif // TEXTLABEL_PYTHON_H
diff --git a/superkaramba/src/themefile.cpp b/superkaramba/src/themefile.cpp
new file mode 100644
index 0000000..ac02e2f
--- /dev/null
+++ b/superkaramba/src/themefile.cpp
@@ -0,0 +1,414 @@
+/****************************************************************************
+* themefile.cpp - Theme file handling
+*
+* Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+* Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+* Copyright (c) 2004 Petri Damst� <damu@iki.fi>
+*
+* This file is part of SuperKaramba.
+*
+* SuperKaramba 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.
+*
+* SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+#include "themefile.h"
+#include "lineparser.h"
+#include "themelocale.h"
+#include <kdebug.h>
+#include <kurl.h>
+#include <kzip.h>
+#include <kapplication.h>
+#include <kmessagebox.h>
+#include <kstandarddirs.h>
+#include <klocale.h>
+#include <kio/netaccess.h>
+#include <qtextstream.h>
+#include <qfileinfo.h>
+#include <qdom.h>
+#include <qdir.h>
+
+class ZipFile
+{
+ public:
+ ZipFile() :
+ m_zip(0), m_file(0)
+ {
+ }
+ void setFile(const QString& filename)
+ {
+ m_filename = filename;
+ if(filename.isEmpty())
+ return;
+
+ const KArchiveEntry* entry;
+
+ entry = m_dir->entry(filename);
+ if(entry == 0 || !entry->isFile())
+ {
+ m_file = 0;
+ return;
+ }
+ m_file = static_cast<const KArchiveFile*>(entry);
+ }
+ void setZip(const QString& zipfile)
+ {
+ closeZip();
+
+ m_zip = new KZip(zipfile);
+
+ if(!m_zip->open(IO_ReadOnly))
+ {
+ qDebug("Unable to open '%s' for reading.", zipfile.ascii());
+ return;
+ }
+ m_dir = m_zip->directory();
+ if(m_dir == 0)
+ {
+ qDebug("Error reading directory contents of file %s", zipfile.ascii());
+ return;
+ }
+ }
+
+ virtual ~ZipFile()
+ {
+ closeZip();
+ }
+
+ void closeZip()
+ {
+ if(m_zip)
+ {
+ m_zip->close();
+ delete m_zip;
+ }
+ }
+
+ QByteArray data()
+ {
+ if(m_file)
+ return m_file->data();
+ else
+ {
+ if(!m_filename.isEmpty())
+ qDebug("Error reading file %s from zip", m_filename.ascii());
+ return QByteArray();
+ }
+ }
+
+ bool exists()
+ {
+ return (m_file != 0);
+ }
+
+ private:
+ KZip* m_zip;
+ const KArchiveFile* m_file;
+ QString m_filename;
+ const KArchiveDirectory* m_dir;
+};
+
+ThemeFile::ThemeFile(const KURL& url)
+ : m_stream(0), m_locale(0), m_zip(0)
+{
+ if(url.isValid())
+ set(url);
+}
+
+ThemeFile::~ThemeFile()
+{
+ delete m_stream;
+ delete m_locale;
+ delete m_zip;
+}
+
+bool ThemeFile::open()
+{
+ bool result = false;
+
+ close();
+
+ if(m_zipTheme)
+ {
+ m_zip->setFile(m_theme);
+ m_ba = m_zip->data();
+ if(m_ba.size() > 0)
+ {
+ m_stream = new QTextStream(m_ba, IO_ReadOnly);
+ result = true;
+ }
+ }
+ else
+ {
+ m_fl.setName(m_file);
+
+ if(m_fl.open(IO_ReadOnly|IO_Translate))
+ {
+ m_stream = new QTextStream(&m_fl); // use a text stream
+ result = true;
+ }
+ }
+ return result;
+}
+
+bool ThemeFile::nextLine(LineParser& parser)
+{
+ parser.set("");
+
+ if(m_stream)
+ {
+ QString result = m_stream->readLine();
+
+ if(result.isNull())
+ return false;
+ parser.set(result);
+ return true;
+ }
+ return false;
+}
+
+bool ThemeFile::close()
+{
+ if(m_stream)
+ {
+ delete m_stream;
+ m_stream = 0;
+ m_fl.close();
+ m_ba.resize(0);
+ return true;
+ }
+ return false;
+}
+
+bool ThemeFile::isValid() const
+{
+ return (exists() && !m_name.isEmpty() && !m_theme.isEmpty());
+}
+
+bool ThemeFile::exists() const
+{
+ QFileInfo file(m_file);
+ return file.exists();
+}
+
+QPixmap ThemeFile::icon() const
+{
+ return QPixmap(readThemeFile(m_icon));
+}
+
+bool ThemeFile::set(const KURL &url)
+{
+ if(!url.isLocalFile() && !url.protocol().isEmpty())
+ {
+ if(KMessageBox::warningContinueCancel(kapp->activeWindow(),
+ i18n("You are about to install and run %1 SuperKaramba theme. Since "
+ "themes can contain executable code you should only install themes "
+ "from sources that you trust. Continue?"), i18n("Executable Code Warning"), i18n("Install")
+ .arg(url.prettyURL()))
+ == KMessageBox::Cancel)
+ {
+ return false;
+ }
+
+ QDir themeDir(locateLocal("appdata", "themes/", true));
+ QFileInfo localFile = themeDir.filePath(url.fileName());
+
+ if(localFile.exists())
+ {
+ if(KMessageBox::warningContinueCancel(kapp->activeWindow(),
+ i18n("%1 already exists. Do you want to overwrite it?")
+ .arg(localFile.filePath()),i18n("File Exists"),i18n("Overwrite"))
+ == KMessageBox::Cancel)
+ {
+ return false;
+ }
+ }
+ if(!KIO::NetAccess::file_copy(url, localFile.filePath(), -1, true,
+ false, kapp->mainWidget()))
+ {
+ return false;
+ }
+ m_file = localFile.filePath();
+ }
+ else
+ {
+ if(url.directory().isEmpty() || url.directory() == "/")
+ m_file = canonicalFile(QDir::current().filePath(url.fileName()));
+ else
+ m_file = canonicalFile(url.path());
+ if(!exists())
+ return false;
+ }
+
+ QFileInfo fi(m_file);
+
+ m_name = fi.baseName( TRUE );
+ m_theme = m_name + ".theme";
+ m_python = m_name;
+ m_id = m_name;
+
+ if(isZipFile(m_file))
+ {
+ m_path = m_file;
+ m_zipTheme = true;
+ m_zip = new ZipFile();
+ m_zip->setZip(m_file);
+ }
+ else
+ {
+ m_path = fi.dirPath(true) + "/";
+ m_zipTheme = false;
+ }
+ parseXml();
+
+ QFileInfo fimo(m_python);
+ if(m_python.isEmpty())
+ fimo.setFile(m_theme);
+ else
+ fimo.setFile(m_python);
+ m_mo = fimo.baseName( TRUE );
+
+ m_locale = new ThemeLocale(this);
+ return isValid();
+}
+
+void ThemeFile::parseXml()
+{
+ if(!fileExists("maindata.xml"))
+ return;
+ QByteArray ba = readThemeFile("maindata.xml");
+ QDomDocument doc("superkaramba_theme");
+ doc.setContent(ba);
+ QDomElement element = doc.documentElement();
+
+ QDomNode n = element.firstChild();
+ while(!n.isNull())
+ {
+ QDomElement e = n.toElement();
+ if(!e.isNull())
+ {
+ if(e.tagName() == "name")
+ m_name = e.text();
+ else if(e.tagName() == "themefile")
+ m_theme = e.text();
+ else if(e.tagName() == "python_module")
+ {
+ m_python = e.text();
+ if(m_python.right(3).lower() == ".py")
+ m_python.remove(m_python.length() - 3, 3);
+ }
+ else if(e.tagName() == "description")
+ m_description = e.text();
+ else if(e.tagName() == "author")
+ m_author = e.text();
+ else if(e.tagName() == "author_email")
+ m_authorEmail = e.text();
+ else if(e.tagName() == "homepage")
+ m_homepage = e.text();
+ else if(e.tagName() == "icon")
+ m_icon = e.text();
+ else if(e.tagName() == "version")
+ m_version = e.text();
+ else if(e.tagName() == "license")
+ m_license = e.text();
+ }
+ n = n.nextSibling();
+ }
+}
+
+bool ThemeFile::canUninstall() const
+{
+ QFileInfo fi(file());
+ if(fi.permission(QFileInfo::WriteUser) ||
+ fi.permission(QFileInfo::WriteGroup) ||
+ fi.permission(QFileInfo::WriteOther))
+ return true;
+ return false;
+}
+
+bool ThemeFile::isThemeFile(const QString& filename) const
+{
+ QFileInfo fileInfo(filename);
+
+ return fileInfo.isRelative();
+}
+
+bool ThemeFile::fileExists(const QString& filename) const
+{
+ if(isThemeFile(filename))
+ {
+ if(isZipTheme())
+ {
+ m_zip->setFile(filename);
+ return m_zip->exists();
+ }
+ else
+ return QFileInfo(path() + "/" + filename).exists();
+ }
+ else
+ return QFileInfo(filename).exists();
+}
+
+QByteArray ThemeFile::readThemeFile(const QString& filename) const
+{
+ //QTime time;
+ //time.start();
+ QByteArray ba;
+
+ if(isZipTheme())
+ {
+ m_zip->setFile(filename);
+ ba = m_zip->data();
+ }
+ else
+ {
+ QFile file(path() + "/" + filename);
+
+ if(file.open(IO_ReadOnly))
+ {
+ ba = file.readAll();
+ file.close();
+ }
+ }
+ //kdDebug() << "Read theme file: " << filename << ", " << time.elapsed()
+ // << "ms" << endl;
+ return ba;
+}
+
+bool ThemeFile::isZipFile(const QString& filename)
+{
+ QFile file(filename);
+
+ if(file.open(IO_ReadOnly))
+ {
+ unsigned char buf[5];
+
+ if(file.readBlock((char*)buf, 4) == 4)
+ {
+ if(buf[0] == 'P' && buf[1] == 'K' && buf[2] == 3 && buf[3] == 4)
+ return true;
+ }
+ }
+ return false;
+}
+
+bool ThemeFile::pythonModuleExists() const
+{
+ return (!m_python.isEmpty() && fileExists(m_python + ".py"));
+}
+
+QString ThemeFile::canonicalFile(const QString& file)
+{
+ // Get absolute path with NO symlinks
+ QFileInfo fi(file);
+ return QDir(fi.dir().canonicalPath()).filePath(fi.fileName());
+}
diff --git a/superkaramba/src/themefile.h b/superkaramba/src/themefile.h
new file mode 100644
index 0000000..c8259d6
--- /dev/null
+++ b/superkaramba/src/themefile.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+* themefile.h - Theme file handling
+*
+* Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+* Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+* Copyright (c) 2004 Petri Damstn <damu@iki.fi>
+*
+* This file is part of SuperKaramba.
+*
+* SuperKaramba 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.
+*
+* SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+#ifndef THEMEFILE_H
+#define THEMEFILE_H
+
+#include <kurl.h>
+#include <qstring.h>
+#include <qcstring.h>
+#include <qpixmap.h>
+#include <qfile.h>
+#include <qvaluevector.h>
+
+class LineParser;
+class QTextStream;
+class ThemeLocale;
+class ZipFile;
+
+/**
+@author See README for the list of authors
+*/
+class ThemeFile
+{
+ public:
+ typedef QValueVector<ThemeFile> List;
+
+ ThemeFile(const KURL& url = KURL());
+ ~ThemeFile();
+
+ bool isZipTheme() const { return m_zipTheme; };
+ const QString& name() const { return m_name; };
+ const QString& version() const { return m_version; };
+ const QString& license() const { return m_license; };
+ const QString& id() const { return m_id; };
+ const QString& mo() const { return m_mo; };
+ const QString& file() const { return m_file; };
+ const QString& pythonModule() const { return m_python; };
+ bool pythonModuleExists() const;
+ const QString& path() const { return m_path; };
+ const QString& description() const { return m_description; };
+ const QString& author() const { return m_author; };
+ const QString& authorEmail() const { return m_authorEmail; };
+ const QString& homepage() const { return m_homepage; };
+ QPixmap icon() const;
+ bool exists() const;
+ bool isThemeFile(const QString& filename) const;
+ bool isValid() const;
+ QByteArray readThemeFile(const QString& filename) const;
+ bool fileExists(const QString& filename) const;
+ const ThemeLocale* locale() const { return m_locale; };
+ bool canUninstall() const;
+
+ bool set(const KURL& url);
+ bool open();
+ bool nextLine(LineParser& parser);
+ bool close();
+
+ static bool isZipFile(const QString& filename);
+ static QString canonicalFile(const QString& file);
+
+ private:
+ void parseXml();
+ void mkdir(QDir dir);
+
+ QString m_path;
+ bool m_zipTheme;
+ QString m_file;
+ QString m_id;
+ QString m_mo;
+ QString m_name;
+ QString m_theme;
+ QString m_python;
+ QString m_icon;
+ QString m_version;
+ QString m_license;
+ QTextStream* m_stream;
+ QByteArray m_ba;
+ QFile m_fl;
+ QString m_description;
+ QString m_author;
+ QString m_authorEmail;
+ QString m_homepage;
+ ThemeLocale* m_locale;
+ ZipFile* m_zip;
+};
+
+#endif
diff --git a/superkaramba/src/themelocale.cpp b/superkaramba/src/themelocale.cpp
new file mode 100644
index 0000000..76fa62b
--- /dev/null
+++ b/superkaramba/src/themelocale.cpp
@@ -0,0 +1,438 @@
+/*
+ * languageList from klocale.cpp
+ * Copyright (c) 1997,2001 Stephan Kulow <coolo@kde.org>
+ * Copyright (c) 1999 Preston Brown <pbrown@kde.org>
+ * Copyright (c) 1999-2002 Hans Petter Bieker <bieker@kde.org>
+ * Copyright (c) 2002 Lukas Tinkl <lukas@kde.org>
+ *
+ * libintl.cpp -- gettext related functions from glibc-2.0.5
+ * Copyright (C) 1995 Software Foundation, Inc.
+ *
+ * This file is part of SuperKaramba.
+ * Copyright (c) 2005 Petri Damsten <damu@iki.fi>
+ *
+ * SuperKaramba 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.
+ *
+ * SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+#include <config.h>
+
+#include "themelocale.h"
+#include "themefile.h"
+#include <kdebug.h>
+#include <kconfig.h>
+#include <kglobal.h>
+#include <klocale.h>
+#include <qbuffer.h>
+#include <qglobal.h>
+#include <qiodevice.h>
+#include <stdlib.h>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifndef W
+# define W(flag, data) ((flag) ? SWAP (data) : (data))
+#endif
+
+typedef Q_UINT32 nls_uint32;
+
+struct loaded_domain
+{
+ const char *data;
+ int must_swap;
+ nls_uint32 nstrings;
+ struct string_desc *orig_tab;
+ struct string_desc *trans_tab;
+ nls_uint32 hash_size;
+ nls_uint32 *hash_tab;
+};
+
+static inline nls_uint32 SWAP (nls_uint32 i)
+{
+ return (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24);
+}
+
+/* @@ end of prolog @@ */
+
+/* The magic number of the GNU message catalog format. */
+#define _MAGIC 0x950412de
+#define _MAGIC_SWAPPED 0xde120495
+
+/* Revision number of the currently used .mo (binary) file format. */
+#define MO_REVISION_NUMBER 0
+
+
+/* Defines the so called `hashpjw' function by P.J. Weinberger
+ [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools,
+ 1986, 1987 Bell Telephone Laboratories, Inc.] */
+static inline unsigned long hash_string (const char *__str_param);
+
+/* @@ end of prolog @@ */
+
+/* Header for binary .mo file format. */
+struct mo_file_header
+{
+ /* The magic number. */
+ nls_uint32 magic;
+ /* The revision number of the file format. */
+ nls_uint32 revision;
+ /* The number of strings pairs. */
+ nls_uint32 nstrings;
+ /* Offset of table with start offsets of original strings. */
+ nls_uint32 orig_tab_offset;
+ /* Offset of table with start offsets of translation strings. */
+ nls_uint32 trans_tab_offset;
+ /* Size of hashing table. */
+ nls_uint32 hash_tab_size;
+ /* Offset of first hashing entry. */
+ nls_uint32 hash_tab_offset;
+};
+
+struct string_desc
+{
+ /* Length of addressed string. */
+ nls_uint32 length;
+ /* Offset of string in file. */
+ nls_uint32 offset;
+};
+
+void tl_nl_load_domain(QIODevice* device, int size,
+ struct sk_kde_loaded_l10nfile *domain_file);
+char* tl_nl_find_msg(const struct sk_kde_loaded_l10nfile *domain_file,
+ const char *msgid);
+void tl_nl_unload_domain(struct loaded_domain *domain);
+
+ThemeLocale::ThemeLocale(ThemeFile* theme)
+ : m_theme(theme)
+{
+ setLanguage(languageList());
+}
+
+ThemeLocale::~ThemeLocale()
+{
+ unload();
+}
+
+void ThemeLocale::unload()
+{
+ if(m_domain.data)
+ {
+ tl_nl_unload_domain((struct loaded_domain *)m_domain.data);
+ m_domain.data = 0;
+ }
+}
+
+QString ThemeLocale::translate(QString text) const
+{
+ if(text == 0)
+ return QString::null;
+ if(m_domain.data)
+ {
+ QString result = QString::fromUtf8(tl_nl_find_msg(&m_domain, text.ascii()));
+ if(result.isEmpty())
+ return text;
+ else
+ return result;
+ }
+ return text;
+}
+
+void ThemeLocale::setLanguage(const QStringList &languages)
+{
+ unload();
+ for(QStringList::ConstIterator it = languages.begin();
+ it != languages.end();
+ ++it)
+ {
+ QString file =
+ QString("locale/%1/LC_MESSAGES/%2.mo").arg(*it).arg(m_theme->mo());
+
+ if(m_theme->fileExists(file))
+ {
+ QBuffer buffer(m_theme->readThemeFile(file));
+ tl_nl_load_domain(&buffer, buffer.size(), &m_domain);
+ m_language = *it;
+ return;
+ }
+ }
+}
+
+QStringList ThemeLocale::languageList()
+{
+ KConfig* config = KGlobal::instance()->config();
+ // Reset the list and add the new languages
+ QStringList languageList;
+ languageList +=
+ QStringList::split(':', QFile::decodeName(::getenv("KDE_LANG")));
+
+ languageList += config->readListEntry("Language", ':');
+
+ // same order as setlocale use
+ // HPB: Only run splitLocale on the environment variables..
+ QStringList langs;
+
+ langs << QFile::decodeName(::getenv("LC_ALL"));
+ langs << QFile::decodeName(::getenv("LC_MESSAGES"));
+ langs << QFile::decodeName(::getenv("LANG"));
+
+ for(QStringList::Iterator it = langs.begin();
+ it != langs.end();
+ ++it )
+ {
+ QString ln, ct, chrset;
+ KLocale::splitLocale(*it, ln, ct, chrset);
+ /*
+ We don't use these in zip themes...
+ if (!ct.isEmpty())
+ {
+ langs.insert(it, ln + '_' + ct);
+ if (!chrset.isEmpty())
+ langs.insert(it, ln + '_' + ct + '.' + chrset);
+ }
+ */
+ langs.insert(it, ln);
+ }
+ languageList += langs;
+ // Remove empty strings
+ QStringList::Iterator end( languageList.end() );
+ for(QStringList::Iterator it=languageList.begin(); it!=end;)
+ {
+ if((*it).isEmpty())
+ it = languageList.remove(it);
+ else
+ ++it;
+ }
+ return languageList;
+}
+
+char* tl_nl_find_msg (const struct sk_kde_loaded_l10nfile *domain_file,
+ const char *msgid)
+{
+ size_t top, act, bottom;
+ struct loaded_domain *domain;
+
+ if (domain_file->decided == 0)
+ return NULL;
+
+ if (domain_file->data == NULL)
+ return NULL;
+
+ domain = (struct loaded_domain *) domain_file->data;
+
+ /* Locate the MSGID and its translation. */
+ if (domain->hash_size > 2 && domain->hash_tab != NULL)
+ {
+ /* Use the hashing table. */
+ nls_uint32 len = strlen (msgid);
+ nls_uint32 hash_val = hash_string (msgid);
+ nls_uint32 idx = hash_val % domain->hash_size;
+ nls_uint32 incr = 1 + (hash_val % (domain->hash_size - 2));
+ nls_uint32 nstr = W (domain->must_swap, domain->hash_tab[idx]);
+
+ if (nstr == 0)
+ /* Hash table entry is empty. */
+ return NULL;
+
+ if (W (domain->must_swap, domain->orig_tab[nstr - 1].length) == len
+ && strcmp (msgid,
+ domain->data + W (domain->must_swap,
+ domain->orig_tab[nstr - 1].offset)) == 0)
+ return (char *) domain->data + W (domain->must_swap,
+ domain->trans_tab[nstr - 1].offset);
+
+ while (1)
+ {
+ if (idx >= domain->hash_size - incr)
+ idx -= domain->hash_size - incr;
+ else
+ idx += incr;
+
+ nstr = W (domain->must_swap, domain->hash_tab[idx]);
+ if (nstr == 0)
+ /* Hash table entry is empty. */
+ return NULL;
+
+ if (W (domain->must_swap, domain->orig_tab[nstr - 1].length) == len
+ && strcmp (msgid,
+ domain->data + W (domain->must_swap,
+ domain->orig_tab[nstr - 1].offset))
+ == 0)
+ return (char *) domain->data
+ + W (domain->must_swap, domain->trans_tab[nstr - 1].offset);
+ }
+ /* NOTREACHED */
+ }
+
+ /* Now we try the default method: binary search in the sorted
+ array of messages. */
+ bottom = 0;
+ top = domain->nstrings;
+ act = top;
+ while (bottom < top)
+ {
+ int cmp_val;
+
+ act = (bottom + top) / 2;
+ cmp_val = strcmp (msgid, domain->data
+ + W (domain->must_swap,
+ domain->orig_tab[act].offset));
+ if (cmp_val < 0)
+ top = act;
+ else if (cmp_val > 0)
+ bottom = act + 1;
+ else
+ break;
+ }
+
+ /* If an translation is found return this. */
+ return bottom >= top ? NULL : (char *) domain->data
+ + W (domain->must_swap,
+ domain->trans_tab[act].offset);
+}
+
+/* @@ begin of epilog @@ */
+/* We assume to have `unsigned long int' value with at least 32 bits. */
+#define HASHWORDBITS 32
+
+static inline unsigned long
+hash_string (const char *str_param)
+{
+ unsigned long int hval, g;
+ const char *str = str_param;
+
+ /* Compute the hash value for the given string. */
+ hval = 0;
+ while (*str != '\0')
+ {
+ hval <<= 4;
+ hval += (unsigned long) *str++;
+ g = hval & ((unsigned long) 0xf << (HASHWORDBITS - 4));
+ if (g != 0)
+ {
+ hval ^= g >> (HASHWORDBITS - 8);
+ hval ^= g;
+ }
+ }
+ return hval;
+}
+
+/* Load the message catalogs specified by device. If it is no valid
+ message catalog do nothing. */
+void tl_nl_load_domain (QIODevice* device, int size,
+ struct sk_kde_loaded_l10nfile *domain_file)
+{
+ struct mo_file_header *data = (struct mo_file_header *) -1;
+ struct loaded_domain *domain;
+
+ domain_file->decided = 1;
+ domain_file->data = NULL;
+
+ /* If the record does not represent a valid locale the FILENAME
+ might be NULL. This can happen when according to the given
+ specification the locale file name is different for XPG and CEN
+ syntax. */
+ if (device == NULL)
+ return;
+
+ /* Try to open the addressed file. */
+ if (device->open(IO_ReadOnly) == false)
+ return;
+
+ /* We must know about the size of the file. */
+ if (size < (off_t) sizeof (struct mo_file_header))
+ {
+ /* Something went wrong. */
+ device->close();
+ return;
+ }
+
+ /* If the data is not yet available (i.e. mmap'ed) we try to load
+ it manually. */
+ if (data == (struct mo_file_header *) -1)
+ {
+ off_t to_read;
+ char *read_ptr;
+
+ data = (struct mo_file_header *) malloc (size);
+ if (data == NULL)
+ return;
+
+ to_read = size;
+ read_ptr = (char *) data;
+ do
+ {
+ long int nb = (long int) device->readBlock (read_ptr, to_read);
+ if (nb == -1)
+ {
+ device->close();
+ return;
+ }
+
+ read_ptr += nb;
+ to_read -= nb;
+ }
+ while (to_read > 0);
+
+ device->close();
+ }
+
+ /* Using the magic number we can test whether it really is a message
+ catalog file. */
+ if (data->magic != _MAGIC && data->magic != _MAGIC_SWAPPED)
+ {
+ /* The magic number is wrong: not a message catalog file. */
+ free (data);
+ return;
+ }
+
+ domain_file->data
+ = (struct loaded_domain *) malloc (sizeof (struct loaded_domain));
+ if (domain_file->data == NULL)
+ return;
+
+ domain = (struct loaded_domain *) domain_file->data;
+ domain->data = (char *) data;
+ domain->must_swap = data->magic != _MAGIC;
+
+ /* Fill in the information about the available tables. */
+ switch (W (domain->must_swap, data->revision))
+ {
+ case 0:
+ domain->nstrings = W (domain->must_swap, data->nstrings);
+ domain->orig_tab = (struct string_desc *)
+ ((char *) data + W (domain->must_swap,
+ data->orig_tab_offset));
+ domain->trans_tab = (struct string_desc *)
+ ((char *) data + W (domain->must_swap,
+ data->trans_tab_offset));
+ domain->hash_size = W (domain->must_swap, data->hash_tab_size);
+ domain->hash_tab = (nls_uint32 *)
+ ((char *) data + W (domain->must_swap,
+ data->hash_tab_offset));
+ break;
+ default:
+ /* This is an illegal revision. */
+ free (data);
+ free (domain);
+ domain_file->data = NULL;
+ return;
+ }
+}
+
+void tl_nl_unload_domain (struct loaded_domain *domain)
+{
+ free ((void *) domain->data);
+ free (domain);
+}
diff --git a/superkaramba/src/themelocale.h b/superkaramba/src/themelocale.h
new file mode 100644
index 0000000..33b6c4e
--- /dev/null
+++ b/superkaramba/src/themelocale.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2005 Petri Damsten <damu@iki.fi>
+ *
+ * This file is part of SuperKaramba.
+ *
+ * SuperKaramba 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.
+ *
+ * SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+#ifndef THEMELOCALE_H
+#define THEMELOCALE_H
+
+#include <qstring.h>
+#include <qstringlist.h>
+
+class ThemeFile;
+
+/**
+@author See README for the list of authors
+*/
+
+struct sk_kde_loaded_l10nfile
+{
+ int decided;
+ const void *data;
+ sk_kde_loaded_l10nfile() : decided(0), data(0) {}
+};
+
+class ThemeLocale
+{
+ public:
+ ThemeLocale(ThemeFile* theme);
+ ~ThemeLocale();
+
+ QString translate(QString text) const;
+ void setLanguage(const QStringList &languages);
+ QString language() const { return m_language; };
+
+ static QStringList languageList();
+
+ private:
+ sk_kde_loaded_l10nfile m_domain;
+ ThemeFile* m_theme;
+ QString m_language;
+
+ void unload();
+};
+
+
+
+#endif
diff --git a/superkaramba/src/themes_layout.ui b/superkaramba/src/themes_layout.ui
new file mode 100644
index 0000000..d7d3ba5
--- /dev/null
+++ b/superkaramba/src/themes_layout.ui
@@ -0,0 +1,241 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>ThemesLayout</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>ThemesLayout</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>399</width>
+ <height>517</height>
+ </rect>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="caption">
+ <string>SuperKaramba Themes</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>labelSearch</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Search:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>editSearch</cstring>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>editSearch</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>labelShow</cstring>
+ </property>
+ <property name="text">
+ <string>S&amp;how:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>comboShow</cstring>
+ </property>
+ </widget>
+ <widget class="QComboBox">
+ <item>
+ <property name="text">
+ <string>All</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Running</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>comboShow</cstring>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="KWidgetListbox">
+ <property name="name">
+ <cstring>tableThemes</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="focusPolicy">
+ <enum>StrongFocus</enum>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layoutButtons</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>buttonAddToDesktop</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="stdItem" stdset="0">
+ <number>27</number>
+ </property>
+ <property name="text">
+ <string>&amp;Add to Desktop</string>
+ </property>
+ </widget>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>buttonClose</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>&amp;Close</string>
+ </property>
+ <property name="stdItem" stdset="0">
+ <number>13</number>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+<customwidgets>
+ <customwidget>
+ <class>KWidgetListbox</class>
+ <header location="local">kwidgetlistbox.h</header>
+ <sizehint>
+ <width>-1</width>
+ <height>-1</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>5</hordata>
+ <verdata>5</verdata>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ <pixmap>image0</pixmap>
+ <signal>selected(int)</signal>
+ <signal>doubleClicked(int, int, int, const QPoint&amp;)</signal>
+ </customwidget>
+</customwidgets>
+<images>
+ <image name="image0">
+ <data format="XBM.GZ" length="79">789c534e494dcbcc4b554829cdcdad8c2fcf4c29c95030e0524611cd48cd4ccf28010a1797249664262b2467241641a592324b8aa363156c15aab914146aadb90067111b1f</data>
+ </image>
+</images>
+<connections>
+ <connection>
+ <sender>buttonClose</sender>
+ <signal>clicked()</signal>
+ <receiver>ThemesLayout</receiver>
+ <slot>close()</slot>
+ </connection>
+ <connection>
+ <sender>buttonAddToDesktop</sender>
+ <signal>clicked()</signal>
+ <receiver>ThemesLayout</receiver>
+ <slot>addToDesktop()</slot>
+ </connection>
+ <connection>
+ <sender>tableThemes</sender>
+ <signal>selected(int)</signal>
+ <receiver>ThemesLayout</receiver>
+ <slot>selectionChanged(int)</slot>
+ </connection>
+ <connection>
+ <sender>editSearch</sender>
+ <signal>textChanged(const QString&amp;)</signal>
+ <receiver>ThemesLayout</receiver>
+ <slot>search(const QString&amp;)</slot>
+ </connection>
+ <connection>
+ <sender>comboShow</sender>
+ <signal>activated(const QString&amp;)</signal>
+ <receiver>ThemesLayout</receiver>
+ <slot>search(const QString&amp;)</slot>
+ </connection>
+ <connection>
+ <sender>tableThemes</sender>
+ <signal>doubleClicked(int,int,int,const QPoint&amp;)</signal>
+ <receiver>ThemesLayout</receiver>
+ <slot>addToDesktop()</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>editSearch</tabstop>
+ <tabstop>comboShow</tabstop>
+ <tabstop>tableThemes</tabstop>
+ <tabstop>buttonAddToDesktop</tabstop>
+ <tabstop>buttonClose</tabstop>
+</tabstops>
+<slots>
+ <slot access="protected">addToDesktop()</slot>
+ <slot access="protected">selectionChanged(int)</slot>
+ <slot access="protected">search(const QString&amp;)</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/>
+<includehints>
+ <includehint>kwidgetlistbox.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+</includehints>
+</UI>
diff --git a/superkaramba/src/themesdlg.cpp b/superkaramba/src/themesdlg.cpp
new file mode 100644
index 0000000..655c982
--- /dev/null
+++ b/superkaramba/src/themesdlg.cpp
@@ -0,0 +1,543 @@
+/*
+ * Copyright (C) 2005 Petri Damstn <petri.damsten@iki.fi>
+ *
+ * This file is part of SuperKaramba.
+ *
+ * SuperKaramba 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.
+ *
+ * SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+#include "karambaapp.h"
+#include "dcopinterface_stub.h"
+#include "karambainterface.h"
+#include "themesdlg.h"
+#include "themewidget.h"
+#include "kwidgetlistbox.h"
+#include "karamba.h"
+
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
+#ifdef HAVE_KNEWSTUFF
+ #include "sknewstuff.h"
+#endif
+
+#include "superkarambasettings.h"
+#include <karchive.h>
+#include <kdebug.h>
+#include <kfiledialog.h>
+#include <kpushbutton.h>
+#include <kstandarddirs.h>
+#include <kapplication.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <qlineedit.h>
+#include <qtable.h>
+#include <qdir.h>
+#include <qlabel.h>
+#include <qcombobox.h>
+#include <qptrlist.h>
+#include <kio/job.h>
+#include <kprotocolinfo.h>
+
+ThemesDlg::ThemesDlg(QWidget *parent, const char *name)
+ : ThemesLayout(parent, name)
+{
+ populateListbox();
+#ifdef HAVE_KNEWSTUFF
+ mNewStuff = 0;
+#endif
+}
+
+ThemesDlg::~ThemesDlg()
+{
+ //kdDebug() << k_funcinfo << endl;
+ saveUserAddedThemes();
+#ifdef HAVE_KNEWSTUFF
+ if(mNewStuff)
+ {
+ delete mNewStuff;
+ }
+#endif
+}
+
+void ThemesDlg::saveUserAddedThemes()
+{
+ KStandardDirs ksd;
+ QStringList t = themes();
+ QStringList dirs = ksd.findDirs("data", QString(kapp->name()) + "/themes");
+ QStringList::Iterator it = t.begin();
+ bool remove;
+
+ while(it != t.end())
+ {
+ remove = false;
+ QStringList::Iterator jtend( dirs.end() );
+ for(QStringList::Iterator jt = dirs.begin(); jt != jtend; ++jt)
+ {
+ if(QFileInfo(*it).dir().path() + "/" == *jt)
+ {
+ remove = true;
+ break;
+ }
+ }
+ if(remove)
+ it = t.remove(it);
+ else
+ ++it;
+ }
+ SuperKarambaSettings::setUserAddedThemes(t);
+ SuperKarambaSettings::writeConfig();
+}
+
+QStringList ThemesDlg::themes()
+{
+ QStringList result;
+ ThemeWidget* w;
+
+ for(uint i = 2; i < tableThemes->count(); ++i)
+ {
+ w = static_cast<ThemeWidget*>(tableThemes->item(i));
+
+ result.append(w->themeFile()->file());
+ }
+ return result;
+}
+
+void ThemesDlg::populateListbox()
+{
+ ThemeWidget* item;
+ QDir dir;
+ QStringList dirs;
+ QStringList t;
+ KStandardDirs ksd;
+
+ tableThemes->clear();
+
+ item = new ThemeWidget;
+ item->icon->setPixmap(KGlobal::iconLoader()->loadIcon("knewstuff",
+ KIcon::NoGroup, KIcon::SizeHuge));
+ item->setHeaderText(i18n("Get New Stuff"));
+ item->setDescriptionText(i18n("Download new themes."));
+
+ item->buttonGo->setText(i18n("New Stuff..."));
+#ifdef HAVE_KNEWSTUFF
+ item->buttonGo->setEnabled(true);
+ connect(item->buttonGo, SIGNAL(clicked()),
+ this, SLOT(getNewStuff()));
+#else
+ item->buttonGo->setEnabled(false);
+#endif
+ tableThemes->insertItem(item);
+
+ item = new ThemeWidget;
+ item->icon->setPixmap(KGlobal::iconLoader()->loadIcon("ksysguard",
+ KIcon::NoGroup, KIcon::SizeHuge));
+ item->setHeaderText(i18n("Open Local Theme"));
+ item->setDescriptionText(i18n("Add local theme to the list."));
+ item->buttonGo->setProperty("stdItem", 18);
+ item->buttonGo->setText(i18n("Open..."));
+ connect(item->buttonGo, SIGNAL(clicked()),
+ this, SLOT(openLocalTheme()));
+ tableThemes->insertItem(item);
+
+ dirs = ksd.findDirs("data", QString(kapp->name()) + "/themes");
+ // Get custom dirs from config here?
+ QStringList::Iterator itend( dirs.end() );
+ for(QStringList::Iterator it = dirs.begin(); it != itend; ++it )
+ {
+ dir.setPath(*it);
+ t = dir.entryList("*.skz; *.theme");
+ for(QStringList::Iterator it = t.begin(); it != t.end(); ++it )
+ {
+ item = new ThemeWidget(new ThemeFile(dir.filePath(*it)));
+ tableThemes->insertItem(item);
+ item->buttonGo->setText(i18n("Uninstall"));
+ connect(item->buttonGo, SIGNAL(clicked()),
+ this, SLOT(uninstall()));
+ }
+ }
+ t = SuperKarambaSettings::userAddedThemes();
+ for(QStringList::Iterator it = t.begin(); it != t.end(); ++it )
+ {
+ ThemeFile* file = new ThemeFile(*it);
+
+ if(file->isValid())
+ {
+ item = new ThemeWidget(file);
+ tableThemes->insertItem(item);
+ item->buttonGo->setText(i18n("Uninstall"));
+ connect(item->buttonGo, SIGNAL(clicked()),
+ this, SLOT(uninstall()));
+ }
+ else
+ delete file;
+ }
+ tableThemes->setSelected(0);
+}
+
+void ThemesDlg::addToDesktop()
+{
+ ThemeWidget* w = static_cast<ThemeWidget*>(tableThemes->selectedItem());
+ if(w)
+ {
+ ThemeFile* tf = w->themeFile();
+ if(tf)
+ {
+ (new karamba(tf->file(), QString()))->show();
+ }
+ }
+}
+
+void ThemesDlg::openLocalTheme()
+{
+ QStringList fileNames;
+ fileNames = KFileDialog::getOpenFileNames(":<themes>",
+ i18n("*.theme *.skz|Themes"),
+ this, i18n("Open Themes"));
+ for(QStringList::Iterator it = fileNames.begin(); it != fileNames.end(); ++it)
+ {
+ ThemeFile file(*it);
+ if(file.isValid())
+ (new karamba(*it, QString()))->show();
+ }
+}
+
+void ThemesDlg::getNewStuff()
+{
+#ifdef HAVE_KNEWSTUFF
+ KConfig* config = KGlobal::config();
+ config->setGroup("KNewStuff");
+ config->writePathEntry("ProvidersUrl",
+ QString::fromLatin1("http://download.kde.org/khotnewstuff/karamba-providers.xml"));
+ config->sync();
+ m_newStuffStatus = config->entryMap("KNewStuffStatus").keys();
+ //This check is b/c KNewStuff will download, throw an error,
+ //and still have the entry in the config that it was successful
+ configSanityCheck();
+
+ if ( !mNewStuff )
+ {
+ mNewStuff = new SKNewStuff(this);
+ }
+ mNewStuff->download();
+#endif
+}
+
+void ThemesDlg::selectionChanged(int index)
+{
+ buttonAddToDesktop->setEnabled(index > 1);
+
+ for(uint i=2; i < tableThemes->count(); ++i)
+ {
+ ThemeWidget* w = static_cast<ThemeWidget*>(tableThemes->item(i));
+ w->showButton(false);
+ }
+ ThemeWidget* w = static_cast<ThemeWidget*>(tableThemes->item(index));
+ ThemeFile* themeFile = w->themeFile();
+ if(themeFile && themeFile->canUninstall())
+ w->showButton(true);
+}
+
+int ThemesDlg::themeIndex(QString file)
+{
+ ThemeWidget* w;
+ file = ThemeFile::canonicalFile(file);
+
+ for(uint i = 2; i < tableThemes->count(); ++i)
+ {
+ w = static_cast<ThemeWidget*>(tableThemes->item(i));
+
+ if(w->themeFile()->file() == file)
+ return i;
+ }
+ return -1;
+}
+
+void ThemesDlg::addSkzThemeToDialog(const QString &file)
+{
+ kdDebug() << "addSkzThemeToDialog(): file = " << file << endl;
+ addThemeToList(file);
+ writeNewStuffConfig(file);
+}
+
+void ThemesDlg::addThemeToDialog(const KArchiveDirectory *archiveDir,
+ const QString& destDir)
+{
+ kdDebug() << "addThemeToDialog(): destDir = " << destDir << endl;
+ QStringList entries = archiveDir->entries();
+
+ QStringList::Iterator end( entries.end() );
+ for(QStringList::Iterator it = entries.begin(); it != end; ++it)
+ {
+ if(archiveDir->entry(*it)->isDirectory())
+ {
+ addThemeToDialog(static_cast<const KArchiveDirectory*>(archiveDir->entry(*it)),
+ destDir + *it + "/");
+ }
+ else
+ {
+ QFileInfo fi(*it);
+ if(fi.extension( FALSE ) == "theme")
+ {
+ addThemeToList(destDir + *it);
+ writeNewStuffConfig(destDir);
+ }
+ }
+ }
+}
+
+void ThemesDlg::writeNewStuffConfig(const QString &file)
+{
+#ifdef HAVE_KNEWSTUFF
+ KConfig* config = KGlobal::config();
+ QStringList keys = config->entryMap("KNewStuffStatus").keys();
+
+ for(QStringList::Iterator it = m_newStuffStatus.begin();
+ it != m_newStuffStatus.end(); ++it)
+ {
+ keys.remove(*it);
+ }
+ if(!keys.isEmpty())
+ {
+ config->setGroup("KNewStuffNames");
+ config->writeEntry(file, keys[0]);
+ config->sync();
+ }
+#endif
+}
+
+void ThemesDlg::configSanityCheck()
+{
+#ifdef HAVE_KNEWSTUFF
+ KConfig* config = KGlobal::config();
+ QStringList statusKeys = config->entryMap("KNewStuffStatus").keys();
+ QStringList nameKeys = config->entryMap("KNewStuffNames").keys();
+ QStringList removeList;
+
+ for(QStringList::Iterator it = statusKeys.begin();
+ it != statusKeys.end(); ++it)
+ {
+ QString keyName(*it);
+ bool removeKey = true;
+ config->setGroup("KNewStuffNames");
+ for(QStringList::Iterator it2 = nameKeys.begin();
+ it2 != nameKeys.end(); ++it2)
+ {
+ QString tempName(config->readEntry(*it2));
+ if( tempName.compare(keyName) == 0)
+ {
+ removeKey = false;
+ }
+
+ }
+ if( removeKey )
+ {
+ kdDebug() << "sanityCheck() deleting entry " << keyName << endl;
+ config->setGroup("KNewStuffStatus");
+ config->deleteEntry( keyName );
+ }
+ }
+ config->sync();
+#endif
+}
+
+int ThemesDlg::addThemeToList(const QString &file)
+{
+ kdDebug() << "addThemeToList() file: " << file << endl;
+ int i = themeIndex(file);
+ if(i < 0)
+ {
+ ThemeWidget* item = new ThemeWidget(new ThemeFile(file));
+
+ i = tableThemes->insertItem(item);
+ item->buttonGo->setText(i18n("Uninstall"));
+ connect(item->buttonGo, SIGNAL(clicked()),
+ this, SLOT(uninstall()));
+ }
+ tableThemes->setSelected(i);
+ return i;
+}
+
+int ThemesDlg::addTheme(const QString& , const QString &file)
+{
+ int i = addThemeToList(file);
+ int result = -1;
+
+ ThemeWidget* w = static_cast<ThemeWidget*>(tableThemes->item(i));
+ if(w)
+ result = w->addInstance();
+ karambaApp->buildToolTip();
+ return result;
+}
+
+void ThemesDlg::removeTheme(const QString&, const QString& file, int instance)
+{
+ int i = themeIndex(file);
+
+ ThemeWidget* w = static_cast<ThemeWidget*>(tableThemes->item(i));
+ if(w)
+ w->removeInstance(instance);
+ karambaApp->buildToolTip();
+}
+
+void ThemesDlg::search(const QString&)
+{
+ tableThemes->showItems(&filter, this);
+}
+
+bool ThemesDlg::filter(int index, QWidget* widget, void* data)
+{
+ if(index < 2)
+ return true;
+
+ ThemesDlg* dlg = static_cast<ThemesDlg*>(data);
+ ThemeWidget* w = static_cast<ThemeWidget*>(widget);
+
+ if(dlg->comboShow->currentItem() == 1) // Running themes
+ if(w->instances() == 0)
+ return false;
+
+ QString searchText = dlg->editSearch->text().lower();
+ if(searchText.isEmpty())
+ {
+ return true;
+ }
+ else
+ {
+ if(w->themeName->text().lower().contains(searchText))
+ return true;
+ if(w->description->text().lower().contains(searchText))
+ return true;
+ }
+ return false;
+}
+
+bool ThemesDlg::isDownloaded( const QString& path )
+{
+ kdDebug() << "isDownloaded path: " << path << endl;
+ KConfig* config = KGlobal::config();
+ config->setGroup("KNewStuffNames");
+ return !config->readEntry(path).isEmpty();
+}
+
+void ThemesDlg::uninstall()
+{
+ ThemeWidget* w = static_cast<ThemeWidget*>(tableThemes->selectedItem());
+ ThemeFile* tf = w->themeFile();
+ KURL trash("trash:/");
+ KURL theme(tf->file());
+ QString tempPath(tf->path());
+
+ karambaApp->dcopIface()->closeTheme(tf->name());
+ if(!KProtocolInfo::isKnownProtocol(trash))
+ trash = KGlobalSettings::trashPath();
+
+ if(!tf->isZipTheme())
+ {
+ kdDebug() << "encountered unpacked theme" << endl;
+ //Don't move it to the trash if it is a local theme
+ if(isDownloaded(tempPath))
+ {
+ QFileInfo remPath(tf->path());
+ QDir remDir(remPath.dir());
+ remDir.cdUp();
+ kdDebug() << "moving " << remDir.path() << " to the trash" << endl;
+ KIO::move(remDir.path(), trash);
+ }
+ tableThemes->removeItem(w);
+
+ //some themes have multiple .theme files
+ //find all .themes that could be listed in the dialog for the directory removed
+ QPtrList<ThemeWidget> list;
+ for(uint i = 2; i < tableThemes->count(); ++i)
+ {
+ ThemeWidget* tempW = static_cast<ThemeWidget*>(tableThemes->item(i));
+ ThemeFile* tempTf = tempW->themeFile();
+ if( tempTf->path().compare( tempPath ) == 0 )
+ {
+ list.append( tempW );
+ }
+ }
+ ThemeWidget *twPtr;
+ for ( twPtr = list.first(); twPtr; twPtr = list.next() )
+ {
+ karambaApp->dcopIface()->closeTheme(twPtr->themeFile()->name());
+ tableThemes->removeItem( twPtr );
+ }
+#ifdef HAVE_KNEWSTUFF
+ // Remove theme from KNewStuffStatus
+ KConfig* config = KGlobal::config();
+ config->setGroup("KNewStuffNames");
+ QString name = config->readEntry(tempPath);
+ if(!name.isEmpty())
+ {
+ kdDebug() << "removing " << tempPath << " under KNewStuffNames from superkarambarc"
+ << endl;
+ kapp->config()->deleteEntry(tempPath);
+ config->setGroup("KNewStuffStatus");
+ kdDebug() << "removing " << name << " under KNewStuffStatus from superkarambarc"
+ << endl;
+ kapp->config()->deleteEntry(name);
+ kapp->config()->sync();
+ }
+#endif
+
+ }
+ else
+ {
+ kdDebug() << "encountered skz theme" << endl;
+ if(isDownloaded(theme.path()))
+ {
+ QFileInfo remPath(theme.path());
+ QDir remDir(remPath.dir());
+ kdDebug() << "moving " << remDir.path() << " to the trash" << endl;
+ KIO::move(remDir.path(), trash);
+ }
+ tableThemes->removeItem(w);
+#ifdef HAVE_KNEWSTUFF
+ // Remove theme from KNewStuffStatus
+ KConfig* config = KGlobal::config();
+ config->setGroup("KNewStuffNames");
+ QString name = config->readEntry(theme.path());
+ if(!name.isEmpty())
+ {
+ kdDebug() << "removing " << theme.path() << " from superkarambarc" << endl;
+ kapp->config()->deleteEntry(theme.path());
+ config->setGroup("KNewStuffStatus");
+ kdDebug() << "removing " << name << " from superkarambarc" << endl;
+ kapp->config()->deleteEntry(name);
+ kapp->config()->sync();
+ }
+#endif
+ }
+ selectionChanged(tableThemes->selected());
+}
+
+QStringList ThemesDlg::runningThemes()
+{
+ QStringList list;
+ ThemeWidget* w;
+
+ for(uint i = 2; i < tableThemes->count(); ++i)
+ {
+ w = static_cast<ThemeWidget*>(tableThemes->item(i));
+
+ if(w->instances() > 0)
+ list.append(w->themeFile()->name());
+ }
+ return list;
+}
+
+#include "themesdlg.moc"
diff --git a/superkaramba/src/themesdlg.h b/superkaramba/src/themesdlg.h
new file mode 100644
index 0000000..268a392
--- /dev/null
+++ b/superkaramba/src/themesdlg.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2005 Petri Damstn <petri.damsten@iki.fi>
+ *
+ * This file is part of SuperKaramba.
+ *
+ * SuperKaramba 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.
+ *
+ * SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#ifndef THEMESDLG_H
+#define THEMESDLG_H
+
+#include <themes_layout.h>
+#include "karambaapp.h"
+
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
+/**
+@author See README for the list of authors
+*/
+#ifdef HAVE_KNEWSTUFF
+class SKNewStuff;
+#endif
+class ThemeFile;
+class KArchiveDirectory;
+
+class ThemesDlg : public ThemesLayout
+{
+ Q_OBJECT
+
+ public:
+ ThemesDlg(QWidget *parent = 0, const char *name = 0);
+ ~ThemesDlg();
+
+ int addTheme(const QString &appId, const QString &file);
+ void removeTheme(const QString &appId, const QString &file, int instance);
+ int addThemeToList(const QString &file);
+ void addSkzThemeToDialog(const QString &file);
+ void addThemeToDialog(const KArchiveDirectory *archiveDir, const QString& destDir);
+ void writeNewStuffConfig(const QString &file);
+ void configSanityCheck();
+ bool isDownloaded(const QString &path);
+ void saveUserAddedThemes();
+ QStringList runningThemes();
+
+ protected slots:
+ virtual void addToDesktop();
+ virtual void selectionChanged(int);
+ virtual void openLocalTheme();
+ virtual void getNewStuff();
+ virtual void search(const QString& text);
+ virtual void uninstall();
+
+ protected:
+ static bool filter(int index, QWidget* widget, void* data);
+ void populateListbox();
+ int themeIndex(QString file);
+ QStringList themes();
+
+#ifdef HAVE_KNEWSTUFF
+ private:
+ SKNewStuff *mNewStuff;
+ QStringList m_newStuffStatus;
+#endif
+};
+
+#endif
diff --git a/superkaramba/src/themewidget.cpp b/superkaramba/src/themewidget.cpp
new file mode 100644
index 0000000..c28e3cf
--- /dev/null
+++ b/superkaramba/src/themewidget.cpp
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2005 Petri Damstn <petri.damsten@iki.fi>
+ *
+ * This file is part of SuperKaramba.
+ *
+ * SuperKaramba 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.
+ *
+ * SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+#include "themewidget.h"
+#include "themelocale.h"
+#include <kpushbutton.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <qlabel.h>
+#include <qlayout.h>
+
+ThemeWidget::ThemeWidget(QWidget *parent, const char *name)
+ : ThemeWidgetLayout(parent, name), m_themeFile(0)
+{
+ running->setText("");
+ setDescriptionMaxHeight();
+}
+
+ThemeWidget::ThemeWidget(ThemeFile* tf)
+ : m_themeFile(tf)
+{
+ QPixmap pixmap = m_themeFile->icon();
+ if(!pixmap.isNull())
+ icon->setPixmap(pixmap);
+ QString version;
+ if(!m_themeFile->version().isEmpty())
+ version = " - " + m_themeFile->version();
+ themeName->setText(
+ m_themeFile->locale()->translate(m_themeFile->name().ascii()) + version);
+ description->setText(
+ m_themeFile->locale()->translate(m_themeFile->description().ascii()));
+ running->setText("");
+ buttonGo->hide();
+ setDescriptionMaxHeight();
+}
+
+ThemeWidget::~ThemeWidget()
+{
+ delete m_themeFile;
+}
+
+int ThemeWidget::addInstance()
+{
+ int i = 1;
+ while(m_instancePool.find(i) != m_instancePool.end())
+ ++i;
+ m_instancePool.append(i);
+ updateRunning();
+ return i;
+}
+
+void ThemeWidget::removeInstance(int instance)
+{
+ m_instancePool.remove(instance);
+ updateRunning();
+}
+
+void ThemeWidget::updateRunning()
+{
+ int i = instances();
+ if(i > 0)
+ running->setText(i18n("<p align=\"center\">%1 running</p>").arg(i));
+ else
+ running->setText("");
+}
+
+void ThemeWidget::setDescriptionText(QString text)
+{
+ description->setText(text);
+}
+
+void ThemeWidget::setHeaderText(QString text)
+{
+ themeName->setText(text);
+}
+
+void ThemeWidget::showButton(bool show)
+{
+ if(show)
+ buttonGo->show();
+ else
+ buttonGo->hide();
+ setDescriptionMaxHeight();
+}
+
+void ThemeWidget::setDescriptionMaxHeight()
+{
+ if(layoutText->geometry().height() <= 0)
+ return;
+ int height = layoutText->geometry().height() - themeName->height() -
+ layoutText->spacing();
+ if(buttonGo->isVisible())
+ height -= layoutButton->geometry().height() + layoutText->spacing();
+ description->setMaximumHeight(height);
+}
+
+#include "themewidget.moc"
diff --git a/superkaramba/src/themewidget.h b/superkaramba/src/themewidget.h
new file mode 100644
index 0000000..4107716
--- /dev/null
+++ b/superkaramba/src/themewidget.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2005 Petri Damstn <petri.damsten@iki.fi>
+ *
+ * This file is part of SuperKaramba.
+ *
+ * SuperKaramba 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.
+ *
+ * SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+#ifndef THEMEWIDGET_H
+#define THEMEWIDGET_H
+
+#include "themefile.h"
+#include <themewidget_layout.h>
+
+/**
+@author See README for the list of authors
+*/
+
+class ThemeWidget : public ThemeWidgetLayout
+{
+ Q_OBJECT
+ public:
+ ThemeWidget(QWidget *parent = 0, const char *name = 0);
+ ThemeWidget(ThemeFile* tf);
+ ~ThemeWidget();
+
+ ThemeFile* themeFile() const { return m_themeFile; };
+
+ int addInstance();
+ int instances() const { return m_instancePool.count(); };
+ void removeInstance(int instance);
+
+ void setDescriptionText(QString text);
+ void setHeaderText(QString text);
+ void showButton(bool show);
+
+ protected:
+ void updateRunning();
+ void setDescriptionMaxHeight();
+
+ private:
+ ThemeFile* m_themeFile;
+ QValueList<int> m_instancePool;
+};
+
+#endif
diff --git a/superkaramba/src/themewidget_layout.ui b/superkaramba/src/themewidget_layout.ui
new file mode 100644
index 0000000..eb91f0a
--- /dev/null
+++ b/superkaramba/src/themewidget_layout.ui
@@ -0,0 +1,182 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>ThemeWidgetLayout</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>ThemeWidgetLayout</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>377</width>
+ <height>112</height>
+ </rect>
+ </property>
+ <property name="paletteBackgroundColor">
+ <color>
+ <red>250</red>
+ <green>248</green>
+ <blue>241</blue>
+ </color>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layoutIcon</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>icon</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>76</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="pixmap">
+ <pixmap>image0</pixmap>
+ </property>
+ <property name="alignment">
+ <set>AlignCenter</set>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>running</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>8</pointsize>
+ </font>
+ </property>
+ <property name="text">
+ <string>&lt;p align="center"&gt;1 running&lt;/p&gt;</string>
+ </property>
+ <property name="textFormat">
+ <enum>RichText</enum>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layoutText</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>themeName</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font">
+ <font>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Header</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>description</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Description</string>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignTop</set>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layoutButton</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>buttonGo</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="accel">
+ <string></string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ </hbox>
+</widget>
+<customwidgets>
+</customwidgets>
+<images>
+ <image name="image0">
+ <data format="PNG" length="5020">89504e470d0a1a0a0000000d4948445200000040000000400806000000aa6971de0000136349444154789ccd9b79701cd59dc73fdd3d3da76634b22559b66ccbb66c832f81011f9804dbc460ee04024b4ced5661b2542559425249259b4a422d816443b612925425454208098b03213e30068c39623026061bdf3696e54bb264dd1a5d73f774f7db3fbae7d0686449beb2bfaae77e6f34d3fdbedff7bbfaf79ee112486a2ddf32d7d32b36205efa16f30137205d8a679f4d8410c817f301fa3a569beb697028fc42f2058a0116cfe4274039e038eb6f5f26a8bdc4fed80b1cfcd1bd5401ce8b31c78b42406a2dcbf5756c53649e939cae2a662d81950f40692553cab9e5f1552c038a18420bf497099a26ef23b8429198f7d51b79e77feee76ac035d46fce552ee8cde22f335555f89522732700d58b60d61250652005d16e787b0d6dbd1c1eff2077038d4032f71e03c02f5a8d103ada872f90d289fced63bef4d0b3bc07c40171bef3bd60262036104cade5d76e95538acc9d8c9f032bbf0d353781eac49aab006f114c9a494590b9bf79885b003f395a3810fc9791a72d44a9be0af5ba7b90a1e88bd7f0d797becadd80970ba4bde7a501620341dde05b8acc23924431a53360d64d503a09d0725aca6aa60e89286c7d996858eb28ba9f65403d9048fd95a01069f00f214f5b88b5d009208e196a24ba690d4622c99e53fc60c5cff90d1001cc739efff96880be8ed542b0dfa1f0a8e42b2d66f1d7e0b3df80d26964563cbf09010e2754cdc6e7a6fcb5eff300103cfc14634566e5bf823c6d49963452808e3c760cde3bee06878bf993f8c9e647780408709e9a306a0d48ad65b92cf32b59a206d507b3ee86eacf6199b296732da001866eb5440cb66d408b6bd1ef3ecfbd4fdecfcf149979caa2af214f5b4ceeca5b57bb090d118bd0f7caeba43aba69ed65d3154ff020d007e8a3c52284183901b683fbb322733d00b35641f5cda03a86016f13207208307444d371cc831fa3a5883a247ccaa287ed958fe7b41cf024c14881ae21a2517a5e7d1badb397961e5ebffa49be0c748f9684119980d840505fc7f3b683bb9ec92b61e5f370f99740f590557133af9f3bce31012120a521a21184090e099f34e506e469d73350edb3ea0f3a08c3f221a681e45028b9e57adcd593a8f0737bed0ff9f0df1650cd39e40a432623690727048f2832c5945e05355f87e22aac954e16005e88883478fbbe674e601eda85d03484d38b88c7314e6c452a9b8e327dc160e0e9be69806137534772c80497cc43a40c8c632d33bef7395e8f697c61fd018e63a9dd88a47022b28ed5b2c42f258962bc9570f5e3503a2f0778aecae78e0b99810da8a311b1fb7dcc6818213b90a7cd46ae9c027bde23d11dc3481a38a62fc675fdbd0c527d53035d03dd320152a901fdf0e10642bb4e11d7687bb78e071fd9c87b392b34a414f401a9b52c77286c450d40cda330f9f63ca0f94d2b70cd697d2d70701b664733480ea8988c5c3915dc1e70a8b0771b0289785b1f465cc731e36a3ccbefc882279907dc26229543889e2272ac958e1d0da474221b0f71fff7b6f0778649988672828abe8e7ac51598c4ca6da0ba86216008f0b14ea8dd068d9f629a2005c7214d9c0a5ebf053cddf66f0749420848b48749764791c78cc37fd7bd482ec95afd0cd8c1c073c7d1d321da3e6a261937a3b5edfcf89e17f92d1065885c612827288eb7f228a97ea8fd15598796df8688f5a9181c7d1fb63e078d9f223c7ee4e957204dbd0c3c3e5094bce600878ae474e2995c865ae227d5d14edfba971189986df376336c5f60eab63f1838f655f898f8d909a8aaec9b5dca4f5fbc67f85c61a830e8e95bc3b6809705acdc02ded26156deee9fdc0ab5ef402a014e0f944f027fc9c015cf6f077780248124832c8324116fed2372a21da9c84ff0d6e53882fec2663084592442315a76f510ebd1a9efe67777fe95ef03fd8031120d00481e6fe5bf0138f8b3b3acbc3d6e3d006f3d01075fb3c25569254cba0c7cc5202b676fb606e050adbea2e2995c867fd624f4de305d6bb7906aefb2f3876c28cc8e8d6c84b0fbee2289aa6b8b70fb65aa027ce5ed553c0f945020ea0d458079cd77d8d21be55d5adf83aedd79a06de05db5b0fde7f0f13390e805ff18a8980a81b105547d889601ee0087dd1415f7a43282d74c47e8069debb7123d529f170a8d3c22069a85a2184cbe4ac534a1d4c31dd7543017f00d2220b596e5bd6b5801a87984685bf6f15d006aff3070e5631db0e769d8fe2474d581db076593a1b8cccaf5875bf5821a600147b1fb0e15776529a54be7220c41d7dff71139d298e7038c214831301206f53b358409af1ee38fbbdbc0c638c0ec1d0e85adc55e101b20aef1514ae74022c5c1a62edebbe63bd42d9bcb9f2ad8b79ad60fa07436d43e0f273759bf565de00b82cb6d0338cb4a0f458043cdf101f655b27c01b28c5aeaa4eca62be9da7e94cead874975575152337ef0eae78c8da4ce89ed0962bd828d753cf7f83f781de8c28aad03c2a2d4fa1c5fab08f2db827620e88f2638eaf7b010b5c8fa3015b156cde5039727c7a139cfeeec0a35c5094777679c5f067c86882c31a666d2f2ea6e12edfdf8ab4b19b77862c15068c4344e6c8b10eb31d3e05f034e61155ffac90989e93cc0f7d1937c73f14c7e8c1a84c52f40aa1dfaf643e747d0b567202baa7b2070e53c08903d70fc93b36a402e31a6a6d3b2690fd1862e8a2606a858548e221919f0f1ae048d3ba3c47a0c5ea9e3b927ce023e970019086cfe210facb8821fabee808fc54f43e95c200644a1ef309c78051ab7596aeb0b5a959e0180464980e202fc50bf63e06a6780cb0588b1aeadafeda5775f03ce6217539697a14806f1ae3827b6f6a127c588c0a709506c9bd0fef201472a4a38706555f276a56983135f19144f04e2e076c384b9106b83de26cbd63c45034257c6938fa8a920798022089fb1fd41da8738ac7eda412a4aded8817ff6248c844effd176c267e2385c50bfbd7f54e0011e7bec31943419406af31e1a2797b16f5e1577286d1f38f18d81e2f164decf275c06520ad17e12924970fb905cae8cd71e3101b2cb028f1fa20d03812ab9440c4d4cd1e513514bfc847635d0d390c4d4a13b4653733f47af9b406cf51c9caf9ea4966cf2529080fc4c50023c8fddc7c26fdec1b3c55eaaa95e093577dbe66011214eefc6dcf926020565f254a4a2c0e81c9f540414034168df52c0de076686854c43eb89d2be791fa18f8e234c102698f65598565048f77583a694419330e94dea1cbafd2d1e07924208a3502a2c019efbae63c6335f655dc0cb74262f84abef22b74a639e3a84fef17b0849419d713972a078e48e8f0056621684d0a651f90023a1d3f5fe61dadfd88b69826f6280aa9ba6e0f442b23b86d61d43e829fa1b6308dd20d2a913e93488f70984092983c88d5b58009c1142440a154404107ff91f1c753ab8eba9d5bc50dab8eb4ad0a066a9954a981af2c4a9a8cbbc24b7bd4db2b60e75da341c13270e13ff1d58bb62de6c53d4821ebf905684de3f4cfbe63de8510d57b99fca15d329aaf45a6130a5e10aa8b8bc1e482904ca65123d09e23d7a06fc893eb63f778c172ddbb3d2e2e16a824ea0fcd4d33c5355ca2d225086b2f44e2b6ed80f35439d243edc8ea9a570cd99833aa56a08d55741f6e5acbedd222f0eab01bdbb8ed1be79375a5718b5d84bf9b2cb1853332e3307eba528dbf46892964f7a68de1b251517b445a97bfe386b3637710868079a810e21447224455175fb13dc79ed4cd6992610188b7add8d1675f6c3cd5088d8ee7d18b104eeb97370cdbaac00016e9bf8205082de7286f8ee0d988933046ebe19c9ed1e940cc54eb4d2b1f91322c75a905d4ec67ee632c6dd707961e076bf635f17a7dee9241537896884d61ce7d9174fb00be804dab032c208a00b21c488aac2cdcf7053999fb72459c6d04cf097a0d65c85ecf5661e2ee231229f1c22d517c3396d0a454b97e4393e1f508c193688ef7e9764ddf6ccfd95b163295aba0ca5b40c2499544f84b60d1fd27fe014c284b14be751bef20a14074302ef3edc49fde626e23d1a118dd0fbcd6cfcd97ede024240ab4d4018eb1d5ec028cae29dcfb222e0e11d87cf8d3004c9fe24c82aee050b903deecc24443c4effbee3a4fa1338675613b87169c6f109cd49e2e03ee2bbdf29f80cc9e5c277e36d843ea8a577672da609c185f328bb7501ce31ae82a04969f41feba4e9ed7afa4ef691d489edede4dddf1ce2d586304d58eade01f4dac00b6682c34ac73316016ab008d9e9408fa64884a208d98177fe3c148f3333219188133ed141bc3d825a399ee0ddb7933cfc2989437b11c944c1fb0b13623d10ebb6de6b3cd5d594ddb214df8c0a200e2269e7fd59e0c98e3ecebc514bc7ae168409ad11eabebd83a74e873983a5ea1d408f7583a14b6267dda34f8b69c7586407389c388a9d783c2ea28dbd8477ecc333b30a576911e829244c0255018496227aba95f65fff0167c032ef4292ec8768c8c2e6089632e1ae2fe2af9949767324ed0c2540c288eb9cd97488d6bf5bf1df1b940977999ceee7e8e9300d581960bbfde361374a464400c22af408c501aaf54aada84e7c5355fa8f771239729ad4f8121c2e07aa5746910d8a27bac0300877e824bac15d62f9b6b4a4e210e9b0804b4e1fe3573d40f1c2456413aef46b8a051c49a2f9b503b4bd7d845444c33fcec1a4f92e840907374591ad72572f595b1f918c8880744665bdf9a5375f2414bf13ffe52ae1139dc49a7ab2df93241c2e19a75be00940a41b226d566931adeea918484e3f636fbc87314b6f43f6c85805dc34e82cf8aeed47695ebf93644718d5a750bdd44fd94c17007d67aca207028145c2a8768b4767028ac3deefcfb941c049c9554508c344eb89a1f52749866224fb12c47acd01696ab8ddb2716182525cc9d89b1ea268de221b7c6c10f8f0d1469ad6bc49b4a11d599599bc2448458d37edc3adc551cc4c0a7c2e32320d48e7d5e9f255aeef94ac7f24155ce3ddb82658d11e24b4de045a6f9c78479464778c4457dc224380d1d54ccb9ac7329397dd3e5c13aa10c2c03d713cb1d34df41f39893061c282122aaef0a338e50cf00c09b261cded1ccf8b8cd2041c59139032ffd8e3c15ece59eac45916a06886fd41d9e7c15489edfd1d08413c94c0489a180983586702113e4db8294adfa77556fcbfbc98098bc6e20ad8d314e9ba245902143db340e722a38c02ea201328ecdea51c6e72fe9e3c09c904deca6200bc95e965cb6e9e66fb69a0394b2b067f5fc8294b8b4602a4808c4a03b226401e7069c065d020ddcd94bfed7b14043a4a32949105b2a164f42630400386039ea71d99dabf7d702a175c2ef0416414d202bb7f290830856d02bac7ceebed3fe4fb81b4e4034f8f151514ddd6803c5b8673d3824ba901b1fa668acbc643516af0aa0fe2a1c0670e07188eb31090db1f21199782804f5b3830bf9223c6e986d9424804af5d044506280c033ccf0fa4eb7d691f7036702335894b41c0e77f4be8cb4bf8c2c34bf963d9a9facfea099d319f59825ce6c8dee1ac0ed01ecb794e1018bcaab9fd1168817c7e048cf48c9df9c71d9c9eff53563585d81c3bdd44fbe67730bb015db5de0f327b03f6fe80eab4f70ef2f60bd28e7444fb09cea1bf23bb40f342d27b490800eb7dbae3da5ff260730f6f243abb69d9f8267a4b0c34dbb3abb9c07340a43fcb0d8343821d8614c90909177abbcca98d751cf8fd3f00e84ad0c9594ae043c9b91c957500635e58c5c3d74ee65149755279d7adb8aaca61ac2befb6f9b9c278d0c260368d2cd9c95c84158afa4c880b5a3f6ee0d4e64f8987a2c474421f74b0f11747d808d4014d58a5eb6165540725f3c40114bfb88affb87a023f92542793eebe1df794f150e6cf039d7b2d07a317c4993cb085faf6d810d09f8288414f5d07475ed8453c14453789ede862d313077905eb90648bdd86dc09ca97f32100ec3dc517efe3eb73cbf94f057c13562c23387f2e549659657060a01694029d205ab20087d20243405f02fa347a8eb6736af3117a8e77a09bc4f6f7f0eeef8ef1eae9282d58d59f76ace3b20946f13a7cbe04804dc2f7af67c5bfcce1cf32f826aef81c2557d540e5f89cac31fd98127bbe6d30e0a80dd9be61424f0c7a62243a23d4addf4fe7c166004e84d9f1a713acdd15e218d97a5fbaec35e0fccf48e44210001609bec79672c31d33f98b22f095cebf92ca1b96c39469d679c0cc63025805daf6f4141840426f183afbd0fbe31c7b652f2d3beb01e84850b7e6146bde6cc9d4f5dbb0d43ec6391c924ecb852200ecedb4af5ccdc2fb67f1accf41f598d9739872eb6d30712a148fb1bfe2c5da930831007c4f2fb487d0fba2346e3f4ae30775e8718d3e8da6f58dfce5a5063ea1405d9f737f09042e2c01609370d35466fc6031eb3c0ad383d53398b6f25694993530763cd67ff969c6d25a01a12e686b034da375f749ea5efb043daee57af62d5880d3c007d4f5cf572e34016091e0bc751a33be319f178a55aef4948e63f67dff8a63ea1ca89c053441b8099a9b2012a6f34803c75edf49bc2792efe09ac896b7fb2850d73f5fb91804a4c50994afbf8d672a3cdce22dade0f2bbeec33d6536e82d106ea5a7a185faad7be83ed50ac0a7bdbcf3542d7f6b8cd2cc6007774181a7e5621200d63ef2d8f537f36cb99bdb64d54dcdaa0771b8921c7f7b2b1db5f50813cec4d8f7741dffbb2bc449b20e2e0dfc9c1ddc48e462130076d6f8fc727e52e5e3df15d58d164f204c688f51f77a331b5eaacf6c5cb66279c7281719785a2e0501609110fce5221eae29e1bfa21a5d6f34f1d2ef8fb30d0b783b590797e20239b891c8a52200acca41e0de292c5cdb808195b474d82dedd92f8a9d9f4d2e250160254c5eacd35106562c4ff24f009e1671ae9b09e721b97b5eff74114220fd3358f8ff24ff07d25c4baf04fdecaa0000000049454e44ae426082</data>
+ </image>
+</images>
+<layoutdefaults spacing="6" margin="6"/>
+<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/>
+<includehints>
+ <includehint>kpushbutton.h</includehint>
+</includehints>
+</UI>
diff --git a/superkaramba/src/uptimesensor.cpp b/superkaramba/src/uptimesensor.cpp
new file mode 100644
index 0000000..5d794a2
--- /dev/null
+++ b/superkaramba/src/uptimesensor.cpp
@@ -0,0 +1,119 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Hans Karlsson *
+ * karlsson.h@home.se *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include <qglobal.h>
+
+#if defined __FreeBSD__
+#include <sys/time.h>
+#include <sys/sysctl.h>
+#endif
+
+#if defined(Q_OS_NETBSD)
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/sysctl.h>
+#endif
+
+#include "uptimesensor.h"
+
+UptimeSensor::UptimeSensor( int interval ) : Sensor( interval )
+{}
+UptimeSensor::~UptimeSensor()
+{}
+
+void UptimeSensor::update()
+{
+#if defined __FreeBSD__ || defined(Q_OS_NETBSD)
+ struct timeval boottime;
+ time_t now; /* the current time of day */
+
+ double avenrun[3];
+ time_t uptime;
+ int days, hours, i, mins, secs;
+ int mib[2];
+ size_t size;
+ char buf[256];
+
+ /*
+ * Get time of day.
+ */
+ (void)time(&now);
+
+ /*
+ * Determine how long system has been up.
+ * (Found by looking getting "boottime" from the kernel)
+ */
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_BOOTTIME;
+ size = sizeof(boottime);
+ if (sysctl(mib, 2, &boottime, &size, NULL, 0) != -1 &&
+ boottime.tv_sec != 0) {
+ uptime = now - boottime.tv_sec;
+ if (uptime > 60)
+ uptime += 30;
+ days = uptime / 86400;
+ uptime %= 86400;
+ hours = uptime / 3600;
+ uptime %= 3600;
+ mins = uptime / 60;
+ secs = uptime % 60;
+ }
+#else
+ QFile file("/proc/uptime");
+ QString line;
+ if ( file.open(IO_ReadOnly | IO_Translate) )
+ {
+ // file opened successfully
+ QTextStream t( &file ); // use a text stream
+ line = t.readLine(); // line of text excluding '\n'
+ file.close();
+
+ QRegExp rx( "^\\d+" );
+ rx.search(line);
+ int uptime = rx.cap(0).toInt();
+ int days = uptime / 86400;
+ uptime -= days * 86400;
+ int hours = uptime / 3600;
+ uptime -= hours * 3600;
+ int mins = uptime / 60;
+ uptime -= mins * 60;
+ int secs = uptime;
+#endif
+
+ QString format;
+ SensorParams *sp;
+ Meter *meter;
+
+ QObjectListIt it( *objList );
+ while (it != 0)
+ {
+ sp = (SensorParams*)(*it);
+ meter = sp->getMeter();
+ format = sp->getParam("FORMAT");
+
+ if (format.length() == 0 )
+ {
+ format = "%dd %h:%M";
+ }
+ format.replace( QRegExp("%d"), QString::number(days));
+ format.replace( QRegExp("%H"), QString::number(hours).rightJustify(2,'0'));
+ format.replace( QRegExp("%M"), QString::number(mins).rightJustify(2,'0'));
+ format.replace( QRegExp("%S"), QString::number(secs).rightJustify(2,'0'));
+ format.replace( QRegExp("%h"), QString::number(hours));
+ format.replace( QRegExp("%m"), QString::number(mins));
+ format.replace( QRegExp("%s"), QString::number(secs));
+
+ meter->setValue(format);
+ ++it;
+ }
+
+#if !defined __FreeBSD__ && !defined(Q_OS_NETBSD)
+ }
+#endif
+}
diff --git a/superkaramba/src/uptimesensor.h b/superkaramba/src/uptimesensor.h
new file mode 100644
index 0000000..061a876
--- /dev/null
+++ b/superkaramba/src/uptimesensor.h
@@ -0,0 +1,30 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Hans Karlsson *
+ * karlsson.h@home.se *
+ * *
+ * 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. *
+ ***************************************************************************/
+#ifndef UPTIMESENSOR_H
+#define UPTIMESENSOR_H
+#include "sensor.h"
+
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qstring.h>
+#include <qregexp.h>
+#include <qdatetime.h>
+
+class UptimeSensor : public Sensor
+{
+
+public:
+ UptimeSensor(int interval);
+ ~UptimeSensor();
+ void update();
+
+};
+
+#endif // UPTIMESENSOR_H
diff --git a/superkaramba/src/widget_python.cpp b/superkaramba/src/widget_python.cpp
new file mode 100644
index 0000000..8d5d8e7
--- /dev/null
+++ b/superkaramba/src/widget_python.cpp
@@ -0,0 +1,214 @@
+/****************************************************************************
+* widget_python.h - Functions for widget python api
+*
+* Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+* Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+* Copyright (c) 2004 Petri Damstn <damu@iki.fi>
+*
+* This file is part of SuperKaramba.
+*
+* SuperKaramba 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.
+*
+* SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+#ifdef _XOPEN_SOURCE
+#undef _XOPEN_SOURCE
+#endif
+
+#include <Python.h>
+#include <qobject.h>
+#include "karamba.h"
+#include "meter.h"
+#include "meter_python.h"
+#include "widget_python.h"
+
+/* now a method we need to expose to Python */
+int getWidgetXCoordinate(long widget)
+{
+ karamba* currTheme = (karamba*)widget;
+ return currTheme->x();
+}
+
+/* now a method we need to expose to Python */
+int getWidgetYCoordinate(long widget)
+{
+ karamba* currTheme = (karamba*)widget;
+ return currTheme->y();
+}
+
+PyObject* py_get_widget_position(PyObject *, PyObject *args)
+{
+ long widget;
+ if(!PyArg_ParseTuple(args, (char*)"l:getWidgetPosition", &widget))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ return Py_BuildValue((char*)"(i,i)", getWidgetXCoordinate(widget),
+ getWidgetYCoordinate(widget));
+}
+
+/* now a method we need to expose to Python */
+long createWidgetMask(long widget, char* path)
+{
+ karamba* currTheme = (karamba*)widget;
+ QBitmap bm;
+ QString maskpath;
+ QString rootPath;
+ rootPath.setAscii(currTheme->theme().path().ascii());
+
+ currTheme->clearMask();
+
+ maskpath.setAscii(path);
+ rootPath.append(maskpath.ascii());
+
+ if(currTheme->theme().isZipTheme())
+ {
+ QByteArray ba = currTheme->theme().readThemeFile(path);
+ bm.loadFromData(ba);
+ }
+ else
+ {
+ bm.load(rootPath);
+ }
+ currTheme->setMask(bm);
+
+ return (long)currTheme->widgetMask;
+}
+
+PyObject* py_create_widget_mask(PyObject *, PyObject *args)
+{
+ long widget;
+ char *text;
+ if (!PyArg_ParseTuple(args, (char*)"ls:createWidgetMask", &widget, &text))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ return Py_BuildValue((char*)"l", createWidgetMask(widget, text));
+}
+
+/* now a method we need to expose to Python */
+long redrawWidgetBackground(long widget)
+{
+ karamba* currTheme = (karamba*)widget;
+ currTheme->kroot->repaint(true);
+ return 1;
+}
+
+PyObject* py_redraw_widget_background(PyObject *, PyObject *args)
+{
+ long widget;
+ if (!PyArg_ParseTuple(args, (char*)"l:redrawWidgetBackground", &widget))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ return Py_BuildValue((char*)"l", redrawWidgetBackground(widget));
+}
+
+/* now a method we need to expose to Python */
+long redrawWidget(long widget)
+{
+ karamba* currTheme = (karamba*)widget;
+ currTheme->externalStep();
+ return 1;
+}
+
+PyObject* py_redraw_widget(PyObject *, PyObject *args)
+{
+ long widget;
+ if (!PyArg_ParseTuple(args, (char*)"l:redrawWidget", &widget))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ return Py_BuildValue((char*)"l", redrawWidget(widget));
+}
+
+/* now a method we need to expose to Python */
+long resizeWidget(long widget, long x, long y)
+{
+ karamba* currTheme = (karamba*)widget;
+ //currTheme->test = true;
+ currTheme->setFixedSize((int)x,(int)y);
+ //currTheme->test = false;
+ return 1;
+}
+
+PyObject* py_resize_widget(PyObject *, PyObject *args)
+{
+ long widget, x, y;
+ if (!PyArg_ParseTuple(args, (char*)"lll:resizeWidget", &widget, &x, &y))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ return Py_BuildValue((char*)"l", resizeWidget(widget, x, y));
+}
+
+/* now a method we need to expose to Python */
+long moveWidget(long widget, long x, long y)
+{
+ karamba* currTheme = (karamba*)widget;
+ currTheme->move((int)x, (int)y);
+ return 1;
+}
+
+PyObject* py_move_widget(PyObject *, PyObject *args)
+{
+ long widget, x, y;
+ if (!PyArg_ParseTuple(args, (char*)"lll:moveWidget", &widget, &x, &y))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ return Py_BuildValue((char*)"l", moveWidget(widget, x, y));
+}
+
+/* now a method we need to expose to Python */
+long widgetSetOnTop(long widget, bool b) {
+ karamba* currTheme = (karamba*)widget;
+
+ if (currTheme != 0)
+ {
+ currTheme->setAlwaysOnTop(b);
+ }
+ return 1;
+}
+
+PyObject* py_set_widget_on_top(PyObject *, PyObject *args)
+{
+ long widget;
+ long b;
+ if (!PyArg_ParseTuple(args, (char*)"ll:setWidgetOnTop", &widget, &b ))
+ return NULL;
+ return Py_BuildValue((char*)"l", widgetSetOnTop(widget, b));
+}
+
+/* now a method we need to expose to Python */
+long toggleWidgetRedraw(long widget, bool b)
+{
+ karamba* currTheme = (karamba*)widget;
+ if (currTheme != 0)
+ {
+ currTheme->toggleWidgetUpdate( b );
+ }
+ return 0;
+}
+
+PyObject* py_toggle_widget_redraw(PyObject *, PyObject *args)
+{
+ long widget, b;
+
+ if (!PyArg_ParseTuple(args, (char*)"ll:toggleWidgetRedraw", &widget, &b ))
+ return NULL;
+ if (!checkKaramba(widget))
+ return NULL;
+ return Py_BuildValue((char*)"l", toggleWidgetRedraw(widget, b));
+}
diff --git a/superkaramba/src/widget_python.h b/superkaramba/src/widget_python.h
new file mode 100644
index 0000000..97cc263
--- /dev/null
+++ b/superkaramba/src/widget_python.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+* widget_python.h - Functions for widget python api
+*
+* Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
+* Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
+* Copyright (c) 2004 Petri Damstn <damu@iki.fi>
+*
+* This file is part of SuperKaramba.
+*
+* SuperKaramba 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.
+*
+* SuperKaramba 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 SuperKaramba; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+#ifndef WIDGET_PYTHON_H
+#define WIDGET_PYTHON_H
+
+/** Widget/getWidgetPosition
+*
+* SYNOPSIS
+* tuple getWidgetPosition(widget)
+* DESCRIPTION
+* Returns a Python Tuple containing the x and y position of you widget.
+* widget is a reference to the current widget.
+* ARGUMENTS
+* * long widget -- karamba
+* RETURN VALUE
+* position of the widget
+*/
+PyObject* py_get_widget_position(PyObject *self, PyObject *args);
+
+/** Widget/createWidgetMask
+*
+* SYNOPSIS
+* long createWidgetMask(widget, mask)
+* DESCRIPTION
+* This function doesn't work currently due to a bug in KDE. Please use
+* MASK= in your .theme file for the time being.
+* ARGUMENTS
+* * long widget -- karamba
+* * string mask -- The name of the widget mask file.
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_create_widget_mask(PyObject *self, PyObject *args);
+
+/** Widget/redrawWidgetBackground
+*
+* SYNOPSIS
+* long redrawWidgetBackground(widget)
+* DESCRIPTION
+* Redraws widget background.
+* ARGUMENTS
+* * long widget -- karamba
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_redraw_widget_background(PyObject *self, PyObject *args);
+
+/** Widget/redrawWidget
+*
+* SYNOPSIS
+* long redrawWidget(widget)
+* DESCRIPTION
+* This is THE most important function. After you do a bunch of other calls
+* (moving images, adding images or text, etc), you call this to update the
+* widget display area. You will not see your changes until you call this.
+* Redraws widget background.
+* ARGUMENTS
+* * long widget -- karamba
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_redraw_widget(PyObject *self, PyObject *args);
+
+/** Widget/resizeWidget
+*
+* SYNOPSIS
+* long resizeWidget(widget, w, h)
+* DESCRIPTION
+* Resizes your karamba widget to width=w, height=h
+* ARGUMENTS
+* * long widget -- karamba
+* * long w -- width
+* * long h -- height
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_resize_widget(PyObject *self, PyObject *args);
+
+/** Widget/moveWidget
+*
+* SYNOPSIS
+* long moveWidget(widget, x, y)
+* DESCRIPTION
+* Moves your karamba widget to a new screen location
+* ARGUMENTS
+* * long widget -- karamba
+* * long x -- x coordinate
+* * long y -- y coordinate
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_move_widget(PyObject *self, PyObject *args);
+
+/** Widget/toggleWidgetRedraw
+*
+* SYNOPSIS
+* long toggleWidgetRedraw(widget, b)
+* DESCRIPTION
+* Toggles widget redraw.
+* ARGUMENTS
+* * long widget -- karamba
+* * long b -- 1 = widget is drawn
+* RETURN VALUE
+* 1 if successful
+*/
+PyObject* py_toggle_widget_redraw(PyObject *self, PyObject *args);
+PyObject* py_set_widget_on_top(PyObject *self, PyObject *args);
+
+#endif // WIDGET_PYTHON_H
diff --git a/superkaramba/src/xmmssensor.cpp b/superkaramba/src/xmmssensor.cpp
new file mode 100644
index 0000000..a55209e
--- /dev/null
+++ b/superkaramba/src/xmmssensor.cpp
@@ -0,0 +1,149 @@
+/***************************************************************************
+* Copyright (C) 2003 by Hans Karlsson *
+* karlsson.h@home.se *
+* *
+* This program is free software; you can redistribute it and/or modify *
+* it under the terms of the GNU General Public License as published by *
+* the Free Software Foundation; either version 2 of the License, or *
+* (at your option) any later version. *
+***************************************************************************/
+#include "xmmssensor.h"
+
+#ifdef HAVE_XMMS
+#include <xmmsctrl.h>
+#endif // HAVE_XMMS
+
+XMMSSensor::XMMSSensor( int interval, const QString &encoding )
+ : Sensor( interval )
+{
+ if( !encoding.isEmpty() )
+ {
+ codec = QTextCodec::codecForName( encoding.ascii() );
+ if ( codec == 0)
+ codec = QTextCodec::codecForLocale();
+ }
+ else
+ codec = QTextCodec::codecForLocale();
+
+}
+XMMSSensor::~XMMSSensor()
+{}
+
+void XMMSSensor::update()
+{
+ QString format;
+ SensorParams *sp;
+ Meter *meter;
+ QObjectListIt it( *objList );
+
+#ifdef HAVE_XMMS
+
+ int pos;
+ QString title;
+ int songLength = 0;
+ int currentTime = 0;
+ bool isPlaying = false;
+ bool isRunning = xmms_remote_is_running(0);
+
+ if( isRunning )
+ {
+ isPlaying = xmms_remote_is_playing(0);
+ pos = xmms_remote_get_playlist_pos(0);
+ qDebug("unicode start");
+ title = codec->toUnicode( QCString( xmms_remote_get_playlist_title( 0, pos ) ) );
+ qDebug("unicode end");
+ if( title.isEmpty() )
+ title = "XMMS";
+
+ qDebug("Title: %s", title.ascii());
+ songLength = xmms_remote_get_playlist_time( 0, pos );
+ currentTime = xmms_remote_get_output_time( 0 );
+ }
+#endif // HAVE_XMMS
+
+ while (it != 0)
+ {
+ sp = (SensorParams*)(*it);
+ meter = sp->getMeter();
+
+#ifdef HAVE_XMMS
+
+ if( isRunning )
+ {
+
+ format = sp->getParam("FORMAT");
+
+
+ if (format.length() == 0 )
+ {
+ format = "%title %time / %length";
+ }
+
+ if( format == "%ms" )
+ {
+ meter->setMax( songLength );
+ meter->setValue( currentTime );
+ }
+ else
+
+ if ( format == "%full" )
+ {
+ meter->setValue( 1 );
+ }
+ else
+
+ {
+
+
+ format.replace( QRegExp("%title", false), title );
+
+ format.replace( QRegExp("%length", false), QTime( 0,0,0 ).
+ addMSecs( songLength )
+ .toString( "h:mm:ss" ) );
+
+ format.replace( QRegExp("%time", false), QTime( 0,0,0 ).
+ addMSecs( currentTime )
+ .toString( "h:mm:ss" ) );
+
+ if( isPlaying )
+ {
+ format.replace( QRegExp("%remain", false), QTime( 0,0,0 ).
+ addMSecs( songLength )
+ .addMSecs(-currentTime )
+ .toString( "h:mm:ss" ) );
+ }
+
+ else
+ {
+ format.replace( QRegExp("%remain", false), QTime( 0,0,0 ).toString("h:mm:ss" ) );
+ }
+ meter->setValue(format);
+ }
+ }
+ else
+#endif // HAVE_XMMS
+
+ {
+ meter->setValue("");
+ }
+ ++it;
+
+ }
+
+}
+
+void XMMSSensor::setMaxValue( SensorParams *sp)
+{
+ Meter *meter;
+ meter = sp->getMeter();
+ QString f;
+ f = sp->getParam("FORMAT");
+
+ if ( f == "%full" )
+ meter->setMax( 1 );
+
+}
+
+
+
+#include "xmmssensor.moc"
diff --git a/superkaramba/src/xmmssensor.h b/superkaramba/src/xmmssensor.h
new file mode 100644
index 0000000..f5fd6ef
--- /dev/null
+++ b/superkaramba/src/xmmssensor.h
@@ -0,0 +1,38 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Hans Karlsson *
+ * karlsson.h@home.se *
+ * *
+ * 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. *
+ ***************************************************************************/
+#ifndef XMMSSENSOR_H
+#define XMMSSENSOR_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <qdatetime.h>
+#include <qregexp.h>
+#include <qtextcodec.h>
+
+#include "sensor.h"
+
+class XMMSSensor : public Sensor
+{
+ Q_OBJECT
+public:
+ XMMSSensor( int interval, const QString &encoding=QString::null );
+ ~XMMSSensor();
+ void update();
+ void setMaxValue( SensorParams *);
+
+private:
+ QTextCodec *codec;
+
+};
+
+
+#endif // XMMSSENSOR_H