diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | 2bda8f7717adf28da4af0d34fb82f63d2868c31d (patch) | |
tree | 8d927b7b47a90c4adb646482a52613f58acd6f8c /superkaramba/src | |
download | tdeutils-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')
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, °)) + 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&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>&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&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>&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>&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&)</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&)</signal> + <receiver>ThemesLayout</receiver> + <slot>search(const QString&)</slot> + </connection> + <connection> + <sender>comboShow</sender> + <signal>activated(const QString&)</signal> + <receiver>ThemesLayout</receiver> + <slot>search(const QString&)</slot> + </connection> + <connection> + <sender>tableThemes</sender> + <signal>doubleClicked(int,int,int,const QPoint&)</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&)</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><p align="center">1 running</p></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 |