kexi
metamethod.cpp00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "metamethod.h"
00021 #include "metaobject.h"
00022 #include "metaparameter.h"
00023 #include "variable.h"
00024 #include "exception.h"
00025
00026 #include <qobject.h>
00027 #include <qmetaobject.h>
00028
00029
00030 #include <private/qucom_p.h>
00031 #include <private/qucomextra_p.h>
00032
00033 #include <kdebug.h>
00034
00035 using namespace KoMacro;
00036
00037 namespace KoMacro {
00038
00043 class MetaMethod::Private
00044 {
00045 public:
00046
00050 QString signature;
00051
00055 QString signaturetag;
00056
00060 QString signaturearguments;
00061
00066 MetaParameter::List arguments;
00067
00073 KSharedPtr<MetaObject> object;
00074
00079 MetaMethod::Type type;
00080 };
00081
00082 }
00083
00084 MetaMethod::MetaMethod(const QString& signature, Type type, KSharedPtr<MetaObject> object)
00085 : KShared()
00086 , d( new Private() )
00087 {
00088 d->signature = signature;
00089 d->object = object;
00090 d->type = type;
00091
00092 int startpos = d->signature.find("(");
00093 int endpos = d->signature.findRev(")");
00094 if(startpos < 0 || startpos > endpos) {
00095 throw Exception(QString("Invalid signature \"%1\"").arg(d->signature));
00096 }
00097
00098 d->signaturetag = d->signature.left(startpos).stripWhiteSpace();
00099 if(d->signaturetag.isEmpty()) {
00100 throw Exception(QString("Invalid tagname in signature \"%1\"").arg(d->signature));
00101 }
00102
00103 d->signaturearguments = d->signature.mid(startpos + 1, endpos - startpos - 1).stripWhiteSpace();
00104
00105 do {
00106 int commapos = d->signaturearguments.find(",");
00107 int starttemplatepos = d->signaturearguments.find("<");
00108 if(starttemplatepos >= 0 && (commapos < 0 || starttemplatepos < commapos)) {
00109 int endtemplatepos = d->signaturearguments.find(">", starttemplatepos);
00110 if(endtemplatepos <= 0) {
00111 throw Exception(QString("No closing template-definiton in signature \"%1\"").arg(d->signature));
00112 }
00113 commapos = d->signaturearguments.find(",", endtemplatepos);
00114 }
00115
00116 if(commapos > 0) {
00117 QString s = d->signaturearguments.left(commapos).stripWhiteSpace();
00118 if(! s.isEmpty()) {
00119 d->arguments.append( new MetaParameter(s) );
00120 }
00121 d->signaturearguments = d->signaturearguments.right(d->signaturearguments.length() - commapos - 1);
00122 }
00123 else {
00124 QString s = d->signaturearguments.stripWhiteSpace();
00125 if(! s.isEmpty()) {
00126 d->arguments.append( new MetaParameter(s) );
00127 }
00128 break;
00129 }
00130 } while(true);
00131 }
00132
00133 MetaMethod::~MetaMethod()
00134 {
00135 delete d;
00136 }
00137
00138 KSharedPtr<MetaObject> const MetaMethod::object() const
00139 {
00140 return d->object;
00141 }
00142
00143 const QString MetaMethod::signature() const
00144 {
00145 return d->signature;
00146 }
00147
00148 const QString MetaMethod::signatureTag() const
00149 {
00150 return d->signaturetag;
00151 }
00152
00153 const QString MetaMethod::signatureArguments() const
00154 {
00155 return d->signaturearguments;
00156 }
00157
00158 MetaMethod::Type MetaMethod::type() const
00159 {
00160 return d->type;
00161 }
00162
00163 MetaParameter::List MetaMethod::arguments() const
00164 {
00165 return d->arguments;
00166 }
00167
00168 QUObject* MetaMethod::toQUObject(Variable::List arguments)
00169 {
00170 uint argsize = d->arguments.size();
00171
00172 if(arguments.size() <= argsize) {
00173 throw Exception(QString("To less arguments for slot with siganture \"%1\"").arg(d->signature));
00174 }
00175
00176
00177
00178 QUObject* uo = new QUObject[ argsize + 1 ];
00179
00180 uo[0] = QUObject();
00181
00182 for(uint i = 0; i < argsize; i++) {
00183 KSharedPtr<MetaParameter> metaargument = d->arguments[i];
00184 KSharedPtr<Variable> variable = arguments[i + 1];
00185
00186 if ( !variable ) {
00187 throw Exception(QString("Variable is undefined !"));
00188 }
00189
00190 if(metaargument->type() != variable->type()) {
00191 throw Exception(QString("Wrong variable type in method \"%1\". Expected \"%2\" but got \"%3\"").arg(d->signature).arg(metaargument->type()).arg(variable->type()));
00192 }
00193
00194 switch(metaargument->type()) {
00195
00196 case Variable::TypeNone: {
00197 kdDebug() << "Variable::TypeNone" << endl;
00198 uo[i + 1] = QUObject();
00199 } break;
00200
00201 case Variable::TypeVariant: {
00202 kdDebug() << "Variable::TypeVariant" << endl;
00203
00204 const QVariant variant = variable->variant();
00205 switch(metaargument->variantType()) {
00206 case QVariant::String: {
00207 const QString s = variant.toString();
00208 static_QUType_QString.set( &(uo[i + 1]), s );
00209 } break;
00210 case QVariant::Int: {
00211 const int j = variant.toInt();
00212 static_QUType_int.set( &(uo[i + 1]), j );
00213 } break;
00214 case QVariant::Bool: {
00215 const bool b = variant.toBool();
00216 static_QUType_bool.set( &(uo[i + 1]), b );
00217 } break;
00218 case QVariant::Double: {
00219 const double d = variant.toDouble();
00220 static_QUType_double.set( &(uo[i + 1]), d );
00221 } break;
00222 case QVariant::Invalid: {
00223 static_QUType_QVariant.set( &(uo[i + 1]), variant );
00224 }
00225
00226
00227
00228
00229
00230
00231 default: {
00232 throw Exception(QString("Invalid parameter !!!!!!!!!!!!!!!!!!!!!!!"));
00233 } break;
00234 }
00235 } break;
00236
00237 case Variable::TypeObject: {
00238 kdDebug() << "Variable::TypeObject" << endl;
00239
00240 const QObject* obj = arguments[i + 1]->object();
00241 if(! obj) {
00242 throw Exception(QString("No QObject !"));
00243 }
00244 static_QUType_ptr.set( &(uo[i + 1]), obj );
00245 } break;
00246
00247 default: {
00248 throw Exception(QString("Invalid variable type"));
00249 } break;
00250 }
00251
00252 }
00253
00254 return uo;
00255 }
00256
00257 KSharedPtr<Variable> MetaMethod::toVariable(QUObject* uo)
00258 {
00259 const QString desc( uo->type->desc() );
00260
00261 if(desc == "null") {
00262 return new Variable();
00263 }
00264
00265 if(desc == "QString") {
00266 const QString s = static_QUType_QString.get(uo);
00267 return new Variable(s);
00268 }
00269
00270 if(desc == "int") {
00271 const int j = static_QUType_int.get(uo);
00272 return new Variable(j);
00273 }
00274
00275 if(desc == "bool") {
00276 const bool b = static_QUType_bool.get(uo);
00277 return new Variable(b);
00278 }
00279
00280 if(desc == "double") {
00281 const double d = static_QUType_double.get(uo);
00282 return new Variable(d);
00283 }
00284
00285 if(desc == "QVariant") {
00286 QVariant v = static_QUType_QVariant.get(uo);
00287 return new Variable(v);
00288 }
00289
00290 throw Exception(QString("Invalid parameter '%1'").arg(desc));
00291 }
00292
00293 Variable::List MetaMethod::toVariableList(QUObject* uo)
00294 {
00295 Variable::List list;
00296
00297 MetaParameter::List::ConstIterator it, end( d->arguments.constEnd() );
00298 for( it = d->arguments.constBegin(); it != end; ++it) {
00299 list.append( toVariable(uo) );
00300 uo++;
00301 }
00302
00303 return list;
00304 }
00305
00306 KSharedPtr<Variable> MetaMethod::invoke(Variable::List arguments)
00307 {
00308 kdDebug() << "KSharedPtr<Variable> MetaMethod::invoke(Variable::List arguments)" << endl;
00309
00310 if(! d->object) {
00311 throw Exception("MetaObject is undefined.");
00312 }
00313
00314 QObject* obj = d->object->object();
00315 KSharedPtr<Variable> returnvalue;
00316 QUObject* qu = 0;
00317
00318 try {
00319 qu = toQUObject(arguments);
00320
00321 switch( d->type ) {
00322 case Signal: {
00323 int index = d->object->indexOfSignal( d->signature.latin1() );
00324 obj->qt_emit(index, qu);
00325 } break;
00326 case Slot: {
00327 int index = d->object->indexOfSlot( d->signature.latin1() );
00328 obj->qt_invoke(index, qu);
00329 } break;
00330 default: {
00331 throw Exception("Unknown type.");
00332 } break;
00333 }
00334 returnvalue = toVariable( &qu[0] );
00335 }
00336 catch(Exception& e) {
00337 delete [] qu;
00338 kdDebug() << "EXCEPTION in KoMacro::MetaMethod::invoke(Variable::List)" << endl;
00339 throw Exception(e);
00340 }
00341
00342 delete [] qu;
00343 return returnvalue;
00344 }
|