metamethod.cpp
1/***************************************************************************
2 * This file is part of the KDE project
3 * copyright (C) 2005 by Sebastian Sauer (mail@dipe.org)
4 * copyright (C) 2005 by Tobi Krebs (tobi.krebs@gmail.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public License
15 * along with this program; see the file COPYING. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 ***************************************************************************/
19
20#include "metamethod.h"
21#include "metaobject.h"
22#include "metaparameter.h"
23#include "variable.h"
24#include "exception.h"
25
26#include <tqobject.h>
27#include <tqmetaobject.h>
28
29// to access the TQt3 TQUObject API.
30#include <private/tqucom_p.h>
31#include <private/tqucomextra_p.h>
32
33#include <kdebug.h>
34
35using namespace KoMacro;
36
37namespace KoMacro {
38
43 class MetaMethod::Private
44 {
45 public:
46
50 TQString signature;
51
55 TQString signaturetag;
56
60 TQString signaturearguments;
61
66 MetaParameter::List arguments;
67
73 TDESharedPtr<MetaObject> object;
74
80 };
81
82}
83
84MetaMethod::MetaMethod(const TQString& signature, Type type, TDESharedPtr<MetaObject> object)
85 : TDEShared()
86 , d( new Private() ) // create the private d-pointer instance.
87{
88 d->signature = signature;
89 d->object = object;
90 d->type = type;
91
92 int startpos = d->signature.find("(");
93 int endpos = d->signature.findRev(")");
94 if(startpos < 0 || startpos > endpos) {
95 throw Exception(TQString("Invalid signature \"%1\"").arg(d->signature));
96 }
97
98 d->signaturetag = d->signature.left(startpos).stripWhiteSpace();
99 if(d->signaturetag.isEmpty()) {
100 throw Exception(TQString("Invalid tagname in signature \"%1\"").arg(d->signature));
101 }
102
103 d->signaturearguments = d->signature.mid(startpos + 1, endpos - startpos - 1).stripWhiteSpace();
104
105 do {
106 int commapos = d->signaturearguments.find(",");
107 int starttemplatepos = d->signaturearguments.find("<");
108 if(starttemplatepos >= 0 && (commapos < 0 || starttemplatepos < commapos)) {
109 int endtemplatepos = d->signaturearguments.find(">", starttemplatepos);
110 if(endtemplatepos <= 0) {
111 throw Exception(TQString("No closing template-definiton in signature \"%1\"").arg(d->signature));
112 }
113 commapos = d->signaturearguments.find(",", endtemplatepos);
114 }
115
116 if(commapos > 0) {
117 TQString s = d->signaturearguments.left(commapos).stripWhiteSpace();
118 if(! s.isEmpty()) {
119 d->arguments.append( new MetaParameter(s) );
120 }
121 d->signaturearguments = d->signaturearguments.right(d->signaturearguments.length() - commapos - 1);
122 }
123 else {
124 TQString s = d->signaturearguments.stripWhiteSpace();
125 if(! s.isEmpty()) {
126 d->arguments.append( new MetaParameter(s) );
127 }
128 break;
129 }
130 } while(true);
131}
132
134{
135 delete d;
136}
137
138TDESharedPtr<MetaObject> const MetaMethod::object() const
139{
140 return d->object;
141}
142
143const TQString MetaMethod::signature() const
144{
145 return d->signature;
146}
147
148const TQString MetaMethod::signatureTag() const
149{
150 return d->signaturetag;
151}
152
153const TQString MetaMethod::signatureArguments() const
154{
155 return d->signaturearguments;
156}
157
159{
160 return d->type;
161}
162
164{
165 return d->arguments;
166}
167
169{
170 uint argsize = d->arguments.size();
171
172 if(arguments.size() <= argsize) {
173 throw Exception(TQString("To less arguments for slot with siganture \"%1\"").arg(d->signature));
174 }
175
176 // The first item in the TQUObject-array is for the returnvalue
177 // while everything >=1 are the passed parameters.
178 TQUObject* uo = new TQUObject[ argsize + 1 ];
179
180 uo[0] = TQUObject(); // empty placeholder for the returnvalue.
181
182 for(uint i = 0; i < argsize; i++) {
183 TDESharedPtr<MetaParameter> metaargument = d->arguments[i];
184 TDESharedPtr<Variable> variable = arguments[i + 1];
185
186 if ( !variable ) {
187 throw Exception(TQString("Variable is undefined !"));
188 }
189
190 if(metaargument->type() != variable->type()) {
191 throw Exception(TQString("Wrong variable type in method \"%1\". Expected \"%2\" but got \"%3\"").arg(d->signature).arg(metaargument->type()).arg(variable->type()));
192 }
193
194 switch(metaargument->type()) {
195
196 case Variable::TypeNone: {
197 kdDebug() << "Variable::TypeNone" << endl;
198 uo[i + 1] = TQUObject();
199 } break;
200
202 kdDebug() << "Variable::TypeVariant" << endl;
203
204 const TQVariant variant = variable->variant();
205 switch(metaargument->variantType()) {
206 case TQVariant::String: {
207 const TQString s = variant.toString();
208 static_QUType_TQString.set( &(uo[i + 1]), s );
209 } break;
210 case TQVariant::Int: {
211 const int j = variant.toInt();
212 static_QUType_int.set( &(uo[i + 1]), j );
213 } break;
214 case TQVariant::Bool: {
215 const bool b = variant.toBool();
216 static_QUType_bool.set( &(uo[i + 1]), b );
217 } break;
218 case TQVariant::Double: {
219 const double d = variant.toDouble();
220 static_TQUType_double.set( &(uo[i + 1]), d );
221 } break;
222 case TQVariant::Invalid: {
223 static_TQUType_TQVariant.set( &(uo[i + 1]), variant );
224 }
225
226 /*FIXME
227 static_QUType_charstar
228 static_QUType_ptr.get(uo); TQObject *qobj = (TQObject *)(ptr);
229 */
230
231 default: {
232 throw Exception(TQString("Invalid parameter !!!!!!!!!!!!!!!!!!!!!!!"));
233 } break;
234 }
235 } break;
236
238 kdDebug() << "Variable::TypeObject" << endl;
239
240 const TQObject* obj = arguments[i + 1]->object();
241 if(! obj) { //FIXME: move check to MetaParameter?!
242 throw Exception(TQString("No TQObject !"));
243 }
244 static_QUType_ptr.set( &(uo[i + 1]), obj );
245 } break;
246
247 default: {
248 throw Exception(TQString("Invalid variable type"));
249 } break;
250 }
251
252 }
253
254 return uo;
255}
256
257TDESharedPtr<Variable> MetaMethod::toVariable(TQUObject* uo)
258{
259 const TQString desc( uo->type->desc() );
260
261 if(desc == "null") {
262 return new Variable();
263 }
264
265 if(desc == "TQString") {
266 const TQString s = static_QUType_TQString.get(uo);
267 return new Variable(s);
268 }
269
270 if(desc == "int") {
271 const int j = static_QUType_int.get(uo);
272 return new Variable(j);
273 }
274
275 if(desc == "bool") {
276 const bool b = static_QUType_bool.get(uo);
277 return new Variable(b);
278 }
279
280 if(desc == "double") {
281 const double d = static_TQUType_double.get(uo);
282 return new Variable(d);
283 }
284
285 if(desc == "TQVariant") {
286 TQVariant v = static_TQUType_TQVariant.get(uo);
287 return new Variable(v);
288 }
289
290 throw Exception(TQString("Invalid parameter '%1'").arg(desc));
291}
292
294{
295 Variable::List list;
296
297 MetaParameter::List::ConstIterator it, end( d->arguments.constEnd() );
298 for( it = d->arguments.constBegin(); it != end; ++it) {
299 list.append( toVariable(uo) );
300 uo++;
301 }
302
303 return list;
304}
305
306TDESharedPtr<Variable> MetaMethod::invoke(Variable::List arguments)
307{
308 kdDebug() << "TDESharedPtr<Variable> MetaMethod::invoke(Variable::List arguments)" << endl;
309
310 if(! d->object) {
311 throw Exception("MetaObject is undefined.");
312 }
313
314 TQObject* obj = d->object->object();
315 TDESharedPtr<Variable> returnvalue;
316 TQUObject* qu = 0;
317
318 try {
320
321 switch( d->type ) {
322 case Signal: {
323 int index = d->object->indexOfSignal( d->signature.latin1() );
324 obj->tqt_emit(index, qu);
325 } break;
326 case Slot: {
327 int index = d->object->indexOfSlot( d->signature.latin1() );
328 obj->tqt_invoke(index, qu);
329 } break;
330 default: {
331 throw Exception("Unknown type.");
332 } break;
333 }
334 returnvalue = toVariable( &qu[0] );
335 }
336 catch(Exception& e) {
337 delete [] qu; // free the TQUObject array and
338 kdDebug() << "EXCEPTION in KoMacro::MetaMethod::invoke(Variable::List)" << endl;
339 throw Exception(e); // re-throw exception
340 }
341
342 delete [] qu;
343 return returnvalue;
344}
Base Exception class.
Definition exception.h:35
const TQString signatureTag() const
TDESharedPtr< Variable > toVariable(TQUObject *uo)
Translate the passed uo TQUObject reference into an internal used Variable instances.
TQValueList< TDESharedPtr< MetaParameter > > arguments() const
~MetaMethod()
Destructor.
const TQString signatureArguments() const
TQUObject * toTQUObject(TQValueList< TDESharedPtr< Variable > > arguments)
Translate the passed arguments list of Variable instances into a TQt3 TQUObject* array.
TDESharedPtr< Variable > invoke(TQValueList< TDESharedPtr< Variable > > arguments)
Invoke the MetaMethod with the optional arguments arguments and return a variable.
TDESharedPtr< MetaObject > const object() const
Type
The type of method this MetaMethod provides access to.
Definition metamethod.h:54
@ Slot
The MetaMethod points to a TQt signal.
Definition metamethod.h:56
MetaMethod(const TQString &signature, Type type=Unknown, TDESharedPtr< MetaObject > object=0)
Constructor.
TQValueList< TDESharedPtr< Variable > > toVariableList(TQUObject *uo)
Translate the passed uo TQUObject array into an internal used list of Variable instances.
const TQString signature() const
Class to provide abstract methods for the undocumented TQt3 TQUObject-API functionality.
TQValueList< TDESharedPtr< MetaParameter > > List
Property to get the type of the variable.
@ TypeObject
The MetaParameter is a TQVariant.
@ TypeVariant
None type, the MetaParameter is empty.
A variable value used to provide abstract access to variables.
Definition variable.h:39
TQValueList< TDESharedPtr< Variable > > List
Property to get and set a TQVariant as variable.
Definition variable.h:61