diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 01:29:50 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 01:29:50 +0000 |
commit | 8362bf63dea22bbf6736609b0f49c152f975eb63 (patch) | |
tree | 0eea3928e39e50fae91d4e68b21b1e6cbae25604 /kexi/plugins/macros/lib/metamethod.cpp | |
download | koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.tar.gz koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.zip |
Added old abandoned KDE3 version of koffice
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1077364 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kexi/plugins/macros/lib/metamethod.cpp')
-rw-r--r-- | kexi/plugins/macros/lib/metamethod.cpp | 344 |
1 files changed, 344 insertions, 0 deletions
diff --git a/kexi/plugins/macros/lib/metamethod.cpp b/kexi/plugins/macros/lib/metamethod.cpp new file mode 100644 index 00000000..8aa4dc54 --- /dev/null +++ b/kexi/plugins/macros/lib/metamethod.cpp @@ -0,0 +1,344 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2005 by Sebastian Sauer ([email protected]) + * copyright (C) 2005 by Tobi Krebs ([email protected]) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * 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 + * Library General Public License for more details. + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ***************************************************************************/ + +#include "metamethod.h" +#include "metaobject.h" +#include "metaparameter.h" +#include "variable.h" +#include "exception.h" + +#include <qobject.h> +#include <qmetaobject.h> + +// to access the Qt3 QUObject API. +#include <private/qucom_p.h> +#include <private/qucomextra_p.h> + +#include <kdebug.h> + +using namespace KoMacro; + +namespace KoMacro { + + /** + * @internal d-pointer class to be more flexible on future extension of the + * functionality without to much risk to break the binary compatibility. + */ + class MetaMethod::Private + { + public: + + /** + * The signature this @a MetaMethod has. + */ + QString signature; + + /** + * The signature tagname this @a MetaMethod has. + */ + QString signaturetag; + + /** + * The signature arguments this @a MetaMethod has. + */ + QString signaturearguments; + + /** + * Cached signature arguments parsed into a list + * of @a MetaParameter instances. + */ + MetaParameter::List arguments; + + /** + * The @a MetaObject this @a MetaMethod belongs to or is NULL + * if this @a MetaMethod doesn't belong to any @a MetaObject + * yet. + */ + KSharedPtr<MetaObject> object; + + /** + * The @a MetaMethod::Type this method provides access + * to. + */ + MetaMethod::Type type; + }; + +} + +MetaMethod::MetaMethod(const QString& signature, Type type, KSharedPtr<MetaObject> object) + : KShared() + , d( new Private() ) // create the private d-pointer instance. +{ + d->signature = signature; + d->object = object; + d->type = type; + + int startpos = d->signature.find("("); + int endpos = d->signature.findRev(")"); + if(startpos < 0 || startpos > endpos) { + throw Exception(QString("Invalid signature \"%1\"").arg(d->signature)); + } + + d->signaturetag = d->signature.left(startpos).stripWhiteSpace(); + if(d->signaturetag.isEmpty()) { + throw Exception(QString("Invalid tagname in signature \"%1\"").arg(d->signature)); + } + + d->signaturearguments = d->signature.mid(startpos + 1, endpos - startpos - 1).stripWhiteSpace(); + + do { + int commapos = d->signaturearguments.find(","); + int starttemplatepos = d->signaturearguments.find("<"); + if(starttemplatepos >= 0 && (commapos < 0 || starttemplatepos < commapos)) { + int endtemplatepos = d->signaturearguments.find(">", starttemplatepos); + if(endtemplatepos <= 0) { + throw Exception(QString("No closing template-definiton in signature \"%1\"").arg(d->signature)); + } + commapos = d->signaturearguments.find(",", endtemplatepos); + } + + if(commapos > 0) { + QString s = d->signaturearguments.left(commapos).stripWhiteSpace(); + if(! s.isEmpty()) { + d->arguments.append( new MetaParameter(s) ); + } + d->signaturearguments = d->signaturearguments.right(d->signaturearguments.length() - commapos - 1); + } + else { + QString s = d->signaturearguments.stripWhiteSpace(); + if(! s.isEmpty()) { + d->arguments.append( new MetaParameter(s) ); + } + break; + } + } while(true); +} + +MetaMethod::~MetaMethod() +{ + delete d; +} + +KSharedPtr<MetaObject> const MetaMethod::object() const +{ + return d->object; +} + +const QString MetaMethod::signature() const +{ + return d->signature; +} + +const QString MetaMethod::signatureTag() const +{ + return d->signaturetag; +} + +const QString MetaMethod::signatureArguments() const +{ + return d->signaturearguments; +} + +MetaMethod::Type MetaMethod::type() const +{ + return d->type; +} + +MetaParameter::List MetaMethod::arguments() const +{ + return d->arguments; +} + +QUObject* MetaMethod::toQUObject(Variable::List arguments) +{ + uint argsize = d->arguments.size(); + + if(arguments.size() <= argsize) { + throw Exception(QString("To less arguments for slot with siganture \"%1\"").arg(d->signature)); + } + + // The first item in the QUObject-array is for the returnvalue + // while everything >=1 are the passed parameters. + QUObject* uo = new QUObject[ argsize + 1 ]; + + uo[0] = QUObject(); // empty placeholder for the returnvalue. + + for(uint i = 0; i < argsize; i++) { + KSharedPtr<MetaParameter> metaargument = d->arguments[i]; + KSharedPtr<Variable> variable = arguments[i + 1]; + + if ( !variable ) { + throw Exception(QString("Variable is undefined !")); + } + + if(metaargument->type() != variable->type()) { + throw Exception(QString("Wrong variable type in method \"%1\". Expected \"%2\" but got \"%3\"").arg(d->signature).arg(metaargument->type()).arg(variable->type())); + } + + switch(metaargument->type()) { + + case Variable::TypeNone: { + kdDebug() << "Variable::TypeNone" << endl; + uo[i + 1] = QUObject(); + } break; + + case Variable::TypeVariant: { + kdDebug() << "Variable::TypeVariant" << endl; + + const QVariant variant = variable->variant(); + switch(metaargument->variantType()) { + case QVariant::String: { + const QString s = variant.toString(); + static_QUType_QString.set( &(uo[i + 1]), s ); + } break; + case QVariant::Int: { + const int j = variant.toInt(); + static_QUType_int.set( &(uo[i + 1]), j ); + } break; + case QVariant::Bool: { + const bool b = variant.toBool(); + static_QUType_bool.set( &(uo[i + 1]), b ); + } break; + case QVariant::Double: { + const double d = variant.toDouble(); + static_QUType_double.set( &(uo[i + 1]), d ); + } break; + case QVariant::Invalid: { + static_QUType_QVariant.set( &(uo[i + 1]), variant ); + } + + /*FIXME + static_QUType_charstar + static_QUType_ptr.get(uo); QObject *qobj = (QObject *)(ptr); + */ + + default: { + throw Exception(QString("Invalid parameter !!!!!!!!!!!!!!!!!!!!!!!")); + } break; + } + } break; + + case Variable::TypeObject: { + kdDebug() << "Variable::TypeObject" << endl; + + const QObject* obj = arguments[i + 1]->object(); + if(! obj) { //FIXME: move check to MetaParameter?! + throw Exception(QString("No QObject !")); + } + static_QUType_ptr.set( &(uo[i + 1]), obj ); + } break; + + default: { + throw Exception(QString("Invalid variable type")); + } break; + } + + } + + return uo; +} + +KSharedPtr<Variable> MetaMethod::toVariable(QUObject* uo) +{ + const QString desc( uo->type->desc() ); + + if(desc == "null") { + return new Variable(); + } + + if(desc == "QString") { + const QString s = static_QUType_QString.get(uo); + return new Variable(s); + } + + if(desc == "int") { + const int j = static_QUType_int.get(uo); + return new Variable(j); + } + + if(desc == "bool") { + const bool b = static_QUType_bool.get(uo); + return new Variable(b); + } + + if(desc == "double") { + const double d = static_QUType_double.get(uo); + return new Variable(d); + } + + if(desc == "QVariant") { + QVariant v = static_QUType_QVariant.get(uo); + return new Variable(v); + } + + throw Exception(QString("Invalid parameter '%1'").arg(desc)); +} + +Variable::List MetaMethod::toVariableList(QUObject* uo) +{ + Variable::List list; + + MetaParameter::List::ConstIterator it, end( d->arguments.constEnd() ); + for( it = d->arguments.constBegin(); it != end; ++it) { + list.append( toVariable(uo) ); + uo++; + } + + return list; +} + +KSharedPtr<Variable> MetaMethod::invoke(Variable::List arguments) +{ + kdDebug() << "KSharedPtr<Variable> MetaMethod::invoke(Variable::List arguments)" << endl; + + if(! d->object) { + throw Exception("MetaObject is undefined."); + } + + QObject* obj = d->object->object(); + KSharedPtr<Variable> returnvalue; + QUObject* qu = 0; + + try { + qu = toQUObject(arguments); + + switch( d->type ) { + case Signal: { + int index = d->object->indexOfSignal( d->signature.latin1() ); + obj->qt_emit(index, qu); + } break; + case Slot: { + int index = d->object->indexOfSlot( d->signature.latin1() ); + obj->qt_invoke(index, qu); + } break; + default: { + throw Exception("Unknown type."); + } break; + } + returnvalue = toVariable( &qu[0] ); + } + catch(Exception& e) { + delete [] qu; // free the QUObject array and + kdDebug() << "EXCEPTION in KoMacro::MetaMethod::invoke(Variable::List)" << endl; + throw Exception(e); // re-throw exception + } + + delete [] qu; + return returnvalue; +} |