diff options
author | Hugo Lima <hugo.lima@openbossa.org> | 2009-12-16 21:10:15 -0200 |
---|---|---|
committer | Hugo Lima <hugo.lima@openbossa.org> | 2009-12-16 21:10:15 -0200 |
commit | 9e1a1ec8a75ba16cc9eb21ccc2aa8adf6f21de93 (patch) | |
tree | f1da461f8e1108d684c103b078670d7df145e0d4 /libpyside/dynamicqmetaobject.cpp | |
parent | e791f15afcd9d0a51c745b715f0f369e209500d9 (diff) |
We have a nice Dynamic MetaObject! Yay!
Python signals and slots are like C++ signals and slots to Qt :-)
Diffstat (limited to 'libpyside/dynamicqmetaobject.cpp')
-rw-r--r-- | libpyside/dynamicqmetaobject.cpp | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/libpyside/dynamicqmetaobject.cpp b/libpyside/dynamicqmetaobject.cpp new file mode 100644 index 000000000..47baf6c82 --- /dev/null +++ b/libpyside/dynamicqmetaobject.cpp @@ -0,0 +1,155 @@ +/* +* This file is part of the Shiboken Python Bindings Generator project. +* +* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public License +* version 2.1 as published by the Free Software Foundation. Please +* review the following information to ensure the GNU Lesser General +* Public License version 2.1 requirements will be met: +* http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +* +* As a special exception to the GNU Lesser General Public License +* version 2.1, the object code form of a "work that uses the Library" +* may incorporate material from a header file that is part of the +* Library. You may distribute such object code under terms of your +* choice, provided that the incorporated material (i) does not exceed +* more than 5% of the total size of the Library; and (ii) is limited to +* numerical parameters, data structure layouts, accessors, macros, +* inline functions and templates. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +*/ + +#include "dynamicqmetaobject.h" +#include <QByteArray> +#include <QString> +#include <QList> +#include <QObject> +#include <cstring> + +using namespace PySide; + +static int registerString(const QByteArray& s, QList<QByteArray>* strings) +{ + int idx = 0; + for (int i = 0; i < strings->count(); ++i) { + const QString &str = strings->at(i); + if (str == s) + return idx; + idx += str.length() + 1; + } + strings->append(s); + return idx; +} + +DynamicQMetaObject::DynamicQMetaObject(const QObject* object) : m_originalMetaObject(object->metaObject()) +{ + m_metaObject.d.superdata = m_originalMetaObject; + m_metaObject.d.stringdata = 0; + m_metaObject.d.data = 0; + m_metaObject.d.extradata = 0; + m_stringData = 0; + m_data = 0; + updateMetaObject(); +} + +DynamicQMetaObject::~DynamicQMetaObject() +{ + delete[] m_stringData; + delete[] m_data; +} + +void DynamicQMetaObject::addSignal(const char* signal) +{ + m_signals << QByteArray(signal); + updateMetaObject(); +} + +void DynamicQMetaObject::addSlot(const char* slot) +{ + m_signals << QByteArray(slot); + updateMetaObject(); +} + +void DynamicQMetaObject::updateMetaObject() +{ + // these values are from moc source code, generator.cpp:66 + enum MethodFlags { + AccessPrivate = 0x00, + AccessProtected = 0x01, + AccessPublic = 0x02, + MethodMethod = 0x00, + MethodSignal = 0x04, + MethodSlot = 0x08, + MethodConstructor = 0x0c, + MethodCompatibility = 0x10, + MethodCloned = 0x20, + MethodScriptable = 0x40 + }; + + uint n_signals = m_signals.count(); + uint n_methods = n_signals + m_slots.count(); + int header[] = {2, // revision + 0, // class name index in m_metadata + 0, 0, // classinfo and classinfo index, not used by us + n_methods, 0, // method count and method list index + 0, 0, // prop count and prop indexes + 0, 0 // enum count and enum index + }; + + const int HEADER_LENGHT = sizeof(header)/sizeof(int); + header[5] = HEADER_LENGHT; + // header size + 5 indexes per method + an ending zero + delete[] m_data; + m_data = new uint[HEADER_LENGHT + n_methods*5 + 1]; + std::memcpy(m_data, header, sizeof(header)); + + QList<QByteArray> strings; + registerString(m_originalMetaObject->className(), &strings); // register class string + const int NULL_INDEX = registerString("", &strings); // register a null string + int index = HEADER_LENGHT; + + //write signals + foreach(QByteArray signal, m_signals) { + m_data[index++] = registerString(signal, &strings); // func name + m_data[index++] = NULL_INDEX; // arguments + m_data[index++] = NULL_INDEX; // normalized type + m_data[index++] = NULL_INDEX; // tags + m_data[index++] = AccessPublic | MethodSignal; // flags + } + //write slots + foreach(QByteArray slot, m_slots) { + m_data[index++] = registerString(slot, &strings); // func name + m_data[index++] = NULL_INDEX; // arguments + m_data[index++] = NULL_INDEX; // normalized type + m_data[index++] = NULL_INDEX; // tags + m_data[index++] = AccessPublic | MethodSlot; // flags + } + m_data[index++] = 0; // the end + + // create the m_metadata string + QByteArray str; + foreach(QByteArray signature, strings) { + str.append(signature); + str.append(char(0)); + } + delete[] m_stringData; + m_stringData = new char[str.count()]; + std::copy(str.begin(), str.end(), m_stringData); + + // create metaobject + m_metaObject.d.stringdata = m_stringData; + m_metaObject.d.data = m_data; +} |