You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdeutils/superkaramba/src/misc_python.cpp

853 lines
22 KiB

/****************************************************************************
* 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<73> <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 <tqglobal.h>
#include <tqobject.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;
TQString n;
TQString c;
TQString 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(PyString2TQString(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(PyString2TQString(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 */
TQString 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 TDEProcess;
/* 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 = PyString2TQString(strObj);
/* now do the parsing */
*(currTheme->currProcess) << line;
}
TQApplication::connect(currTheme->currProcess,
TQT_SIGNAL(processExited(TDEProcess *)),
currTheme,
TQT_SLOT(processExited(TDEProcess *)));
TQApplication::connect(currTheme->currProcess,
TQT_SIGNAL(receivedStdout(TDEProcess *, char *, int)),
currTheme,
TQT_SLOT(receivedStdout(TDEProcess *, char *, int)));
currTheme->currProcess->start(TDEProcess::NotifyOnExit, TDEProcess::Stdout);
return Py_BuildValue((char*)"l", (int)(currTheme->currProcess->pid()));
}
long attachClickArea(long widget, long meter, TQString LeftButton, TQString MiddleButton, TQString 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)
{
//tqWarning("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)
{
//tqWarning("attachClickArea : meter is text");
currTheme -> clickList -> append(text);
}
}
else
{
//The given meter does not support attached clickAreas.
tqWarning("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;
TQString 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", TDEGlobal::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 = TDEGlobal::locale()->languageList().count();
PyObject *list, *item;
list = PyList_New(noOfLangs);
for(unsigned int i = 0; i < noOfLangs; i++)
{
item = Py_BuildValue((char*)"s", TDEGlobal::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;
TQByteArray 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 );
TQString n;
TQString e;
TQString 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 );
TQString 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(TQString(path), TQString(str));
return (long)currTheme;
}
static long setIncomingData(long widget, char* path, char *obj)
{
karamba* currTheme = (karamba*) widget;
if (currTheme)
currTheme->setIncomingData(TQString(path), TQString(obj));
return (long)currTheme;
}
static TQString getIncomingData(long widget)
{
karamba* currTheme = (karamba*) widget;
if (currTheme)
return currTheme->getIncomingData();
return TQString("");
}
/*
* 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) {
TQString filename;
karamba* currTheme = 0;
filename.setAscii(path);
TQFileInfo file( filename );
if( file.exists() )
{
TQCString prettyName(name);
KarambaApplication* app = (KarambaApplication*)tqApp;
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)
{
TQString filename;
karamba* currTheme = 0;
filename.setAscii(path);
TQFileInfo file( filename );
if( file.exists() )
{
currTheme = new karamba( filename, TQString() );
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", TQString2PyString(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;
TQObjectListIt 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 */
TQString 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;
TQString 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)
{
tqWarning("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)
{
tqWarning("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);
//tqDebug("numdevs = %d", numdevs);
for (i = 0; i < numdevs; i++)
{
//tqDebug("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)
{
tqWarning("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)
{
tqWarning("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", TQString2PyString(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);
}