aboutsummaryrefslogtreecommitdiffstats
path: root/libpyside
diff options
context:
space:
mode:
authorrenatofilho <renato.filho@openbossa.org>2010-11-05 16:34:11 -0300
committerrenatofilho <renato.filho@openbossa.org>2010-11-05 19:01:07 -0300
commit257e0cdf188172a9548e652ca5763bb124bb58ea (patch)
treec80ef9004c247d81c60b32535e3bf847aa0fafea /libpyside
parent5371e403ffe741119ba0803077b772ca84f3fce3 (diff)
Implemented PySideMetaFunction class used to call dynamic slots.
Reviewer: Hugo Parente Lima <hugo.pl@gmail.com> Luciano Wolf <luciano.wolf@openbossa.org>
Diffstat (limited to 'libpyside')
-rw-r--r--libpyside/CMakeLists.txt16
-rw-r--r--libpyside/pyside.cpp2
-rw-r--r--libpyside/pysidemetafunction.cpp162
-rw-r--r--libpyside/pysidemetafunction.h59
-rw-r--r--libpyside/pysidemetafunction_p.h35
5 files changed, 267 insertions, 7 deletions
diff --git a/libpyside/CMakeLists.txt b/libpyside/CMakeLists.txt
index 939bcc45e..04bf0a771 100644
--- a/libpyside/CMakeLists.txt
+++ b/libpyside/CMakeLists.txt
@@ -1,13 +1,14 @@
project(libpyside)
set(libpyside_SRC
-dynamicqmetaobject.cpp
-signalmanager.cpp
-globalreceiver.cpp
-pysidesignal.cpp
-pysideslot.cpp
-pysideproperty.cpp
-pyside.cpp
+ dynamicqmetaobject.cpp
+ signalmanager.cpp
+ globalreceiver.cpp
+ pysidemetafunction.cpp
+ pysidesignal.cpp
+ pysideslot.cpp
+ pysideproperty.cpp
+ pyside.cpp
)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}
@@ -37,6 +38,7 @@ set(libpyside_HEADERS
pysidemacros.h
signalmanager.h
pyside.h
+ pysidemetafunction.h
pysidesignal.h
pysideproperty.h
)
diff --git a/libpyside/pyside.cpp b/libpyside/pyside.cpp
index 833ae9cef..7f2e96add 100644
--- a/libpyside/pyside.cpp
+++ b/libpyside/pyside.cpp
@@ -27,6 +27,7 @@
#include "pysidesignal.h"
#include "pysidesignal_p.h"
#include "pysideslot_p.h"
+#include "pysidemetafunction_p.h"
#include <basewrapper.h>
#include <conversions.h>
@@ -46,6 +47,7 @@ void init(PyObject *module)
Signal::init(module);
Slot::init(module);
Property::init(module);
+ MetaFunction::init(module);
// Init signal manager, so it will register some meta types used by QVariant.
SignalManager::instance();
}
diff --git a/libpyside/pysidemetafunction.cpp b/libpyside/pysidemetafunction.cpp
new file mode 100644
index 000000000..bcccbb82a
--- /dev/null
+++ b/libpyside/pysidemetafunction.cpp
@@ -0,0 +1,162 @@
+/*
+ * This file is part of the PySide project.
+ *
+ * Copyright (C) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: PySide team <contact@pyside.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <Python.h>
+#include "pysidemetafunction.h"
+
+#include <shiboken.h>
+#include <QObject>
+#include <QMetaMethod>
+#include <QDebug>
+
+extern "C"
+{
+
+struct PySideMetaFunctionPrivate
+{
+ QObject* qobject;
+ QMetaMethod method;
+};
+
+//methods
+static void functionFree(void*);
+static PyObject* functionCall(PyObject*, PyObject*, PyObject*);
+
+PyTypeObject PySideMetaFunctionType = {
+ PyObject_HEAD_INIT(0)
+ /*ob_size*/ 0,
+ /*tp_name*/ "PySide.MetaFunction",
+ /*tp_basicsize*/ sizeof(PySideMetaFunction),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ 0,
+ /*tp_print*/ 0,
+ /*tp_getattr*/ 0,
+ /*tp_setattr*/ 0,
+ /*tp_compare*/ 0,
+ /*tp_repr*/ 0,
+ /*tp_as_number*/ 0,
+ /*tp_as_sequence*/ 0,
+ /*tp_as_mapping*/ 0,
+ /*tp_hash*/ 0,
+ /*tp_call*/ functionCall,
+ /*tp_str*/ 0,
+ /*tp_getattro*/ 0,
+ /*tp_setattro*/ 0,
+ /*tp_as_buffer*/ 0,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT,
+ /*tp_doc*/ "MetaFunction",
+ /*tp_traverse*/ 0,
+ /*tp_clear*/ 0,
+ /*tp_richcompare*/ 0,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ 0,
+ /*tp_iternext*/ 0,
+ /*tp_methods*/ 0,
+ /*tp_members*/ 0,
+ /*tp_getset*/ 0,
+ /*tp_base*/ 0,
+ /*tp_dict*/ 0,
+ /*tp_descr_get*/ 0,
+ /*tp_descr_set*/ 0,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ 0,
+ /*tp_alloc*/ 0,
+ /*tp_new*/ PyType_GenericNew,
+ /*tp_free*/ functionFree,
+ /*tp_is_gc*/ 0,
+ /*tp_bases*/ 0,
+ /*tp_mro*/ 0,
+ /*tp_cache*/ 0,
+ /*tp_subclasses*/ 0,
+ /*tp_weaklist*/ 0,
+ /*tp_del*/ 0,
+};
+
+void functionFree(void *self)
+{
+ PySideMetaFunction* function = reinterpret_cast<PySideMetaFunction*>(self);
+ delete function->d;
+}
+
+PyObject* functionCall(PyObject* self, PyObject* args, PyObject* kw)
+{
+ QGenericArgument gArgs[10];
+ PySideMetaFunction* function = reinterpret_cast<PySideMetaFunction*>(self);
+ QList<QVariant*> vArgs;
+ QMetaMethod method = function->d->method;
+ QList<QByteArray> pTypes = method.parameterTypes();
+ int numArgs = pTypes.size();
+
+ Shiboken::TypeResolver* typeResolver = Shiboken::TypeResolver::get("QVariant");
+ Q_ASSERT(typeResolver);
+ for(int i=0; i < numArgs; i++) {
+ QVariant *vArg;
+ Shiboken::AutoDecRef pyArg(PySequence_GetItem(args, i));
+ typeResolver->toCpp(pyArg, (void**)&vArg, true);
+ vArgs.append(vArg);
+ gArgs[i] = Q_ARG(QVariant, *vArg);
+ }
+
+ QVariant retVariant;
+ QGenericReturnArgument returnValue = Q_RETURN_ARG(QVariant, retVariant);
+ method.invoke(function->d->qobject, returnValue, gArgs[0], gArgs[1], gArgs[2], gArgs[3], gArgs[4], gArgs[5], gArgs[6], gArgs[7], gArgs[8], gArgs[9]);
+
+ while(!vArgs.isEmpty())
+ delete vArgs.takeFirst();
+
+ if (retVariant.isValid())
+ return typeResolver->toPython(&retVariant);
+
+ Py_RETURN_NONE;
+}
+
+} // extern "C"
+
+namespace PySide { namespace MetaFunction {
+
+void init(PyObject* module)
+{
+ if (PyType_Ready(&PySideMetaFunctionType) < 0)
+ return;
+
+ PyModule_AddObject(module, "MetaFunction", ((PyObject*)&PySideMetaFunctionType));
+}
+
+PySideMetaFunction* newObject(QObject* source, int methodIndex)
+{
+ if (methodIndex >= source->metaObject()->methodCount())
+ return 0;
+
+ QMetaMethod method = source->metaObject()->method(methodIndex);
+ if ((method.methodType() == QMetaMethod::Slot) ||
+ (method.methodType() == QMetaMethod::Method)) {
+ PySideMetaFunction* function = PyObject_New(PySideMetaFunction, &PySideMetaFunctionType);
+ function->d = new PySideMetaFunctionPrivate();
+ function->d->qobject = source;
+ function->d->method = method;
+ return function;
+ }
+ return 0;
+}
+
+} //namespace MetaFunction
+} //namespace PySide
+
diff --git a/libpyside/pysidemetafunction.h b/libpyside/pysidemetafunction.h
new file mode 100644
index 000000000..0d4e16f88
--- /dev/null
+++ b/libpyside/pysidemetafunction.h
@@ -0,0 +1,59 @@
+/*
+ * This file is part of the PySide project.
+ *
+ * Copyright (C) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: PySide team <contact@pyside.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef PYSIDE_FUNCTION_H
+#define PYSIDE_METAFUNCTION_H
+
+#include <QObject>
+#include <QString>
+#include <QStringList>
+
+#include <pysidemacros.h>
+#include <Python.h>
+
+extern "C"
+{
+ extern PYSIDE_API PyTypeObject PySideMetaFunctionType;
+
+ struct PySideMetaFunctionPrivate;
+ struct PYSIDE_API PySideMetaFunction
+ {
+ PyObject_HEAD
+ PySideMetaFunctionPrivate* d;
+ };
+}; //extern "C"
+
+namespace PySide { namespace MetaFunction {
+
+/**
+ * This function creates a MetaFunction object
+ *
+ * @param obj the QObject witch this fuction is part of
+ * @param methodIndex The index of this function on MetaObject
+ * @return Return a new reference of PySideMetaFunction
+ **/
+PYSIDE_API PySideMetaFunction* newObject(QObject* obj, int methodIndex);
+
+} //namespace MetaFunction
+} //namespace PySide
+
+#endif
diff --git a/libpyside/pysidemetafunction_p.h b/libpyside/pysidemetafunction_p.h
new file mode 100644
index 000000000..808714ef1
--- /dev/null
+++ b/libpyside/pysidemetafunction_p.h
@@ -0,0 +1,35 @@
+/*
+ * This file is part of the PySide project.
+ *
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: PySide team <contact@pyside.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef PYSIDE_METAFUNCTION_P_H
+#define PYSIDE_METAFUNCTION_P_H
+
+#include <Python.h>
+
+namespace PySide { namespace MetaFunction {
+
+ void init(PyObject* module);
+
+} //namespace MetaFunction
+} //namespace PySide
+
+#endif