@@ -198,6 +198,7 @@ void ShellHeaderGenerator::write(QTextStream &s, const AbstractMetaClass *meta_c
198198 }
199199
200200 foreach (AbstractMetaFunction* fun, promoteFunctions) {
201+ // normal promoter
201202 if (fun->isStatic ()) {
202203 s << " static " ;
203204 }
@@ -210,26 +211,37 @@ void ShellHeaderGenerator::write(QTextStream &s, const AbstractMetaClass *meta_c
210211 if (fun->type ()) {
211212 s << " return " ;
212213 }
213- if (!fun->isAbstract ()) {
214- s << meta_class->qualifiedCppName () << " ::" ;
215- }
216- else {
217- s << " this->" ;
218- }
214+ // always do a direct call, since we want to call the real virtual function here
215+ s << " this->" ;
219216 s << fun->originalName () << " (" ;
220- for (int i = 0 ; i < args.size (); ++i) {
221- if (i > 0 ) {
222- s << " , " ;
217+ writePromoterArgs (args, s);
218+ s << " ); }" << endl;
219+ }
220+
221+ foreach (AbstractMetaFunction* fun, promoteFunctions) {
222+ // qualified promoter for virtual functions
223+ if (fun->isVirtual ()) {
224+ s << " inline " ;
225+ writeFunctionSignature (s, fun, 0 , " py_qualified_" ,
226+ Option (IncludeDefaultExpression | OriginalName | UnderscoreSpaces | ProtectedEnumAsInts));
227+ s << " { " ;
228+ QString scriptFunctionName = fun->originalName ();
229+ AbstractMetaArgumentList args = fun->arguments ();
230+ if (fun->type ()) {
231+ s << " return " ;
223232 }
224- if (args.at (i)->type ()->isEnum ()) {
225- AbstractMetaEnum* enumType = m_classes.findEnum ((EnumTypeEntry *)args.at (i)->type ()->typeEntry ());
226- if (enumType && enumType->wasProtected ()) {
227- s << " (" << enumType->typeEntry ()->qualifiedCppName () << " )" ;
228- }
233+ if (!fun->isAbstract ()) {
234+ // call the qualified version, we don't want the virtual function
235+ s << meta_class->qualifiedCppName () << " ::" ;
229236 }
230- s << args.at (i)->argumentName ();
237+ else {
238+ // TODO: this would better be empty and do no call at all...
239+ s << " this->" ;
240+ }
241+ s << fun->originalName () << " (" ;
242+ writePromoterArgs (args, s);
243+ s << " ); }" << endl;
231244 }
232- s << " ); }" << endl;
233245 }
234246
235247 s << " };" << endl << endl;
@@ -338,16 +350,41 @@ void ShellHeaderGenerator::write(QTextStream &s, const AbstractMetaClass *meta_c
338350 AbstractMetaFunctionList functions = getFunctionsToWrap (meta_class);
339351
340352 foreach (const AbstractMetaFunction *function, functions) {
341- if (!function->isSlot () || function->isVirtual ()) {
342-
353+ if (!function->isSlot ()) {
343354 // for debugging:
344355 // functionHasNonConstReferences(function);
345-
346356 s << " " ;
347357 writeFunctionSignature (s, function, 0 , QString (),
348358 Option (AddOwnershipTemplates | ConvertReferenceToPtr | FirstArgIsWrappedObject | IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces | ProtectedEnumAsInts));
349359 s << " ;" << endl;
350360 }
361+ if (function->isVirtual ()) {
362+ // qualified version that calls the promoter/the qualified version
363+ s << " " ;
364+ writeFunctionSignature (s, function, 0 , " py_qualified_" ,
365+ Option (AddOwnershipTemplates | ConvertReferenceToPtr | FirstArgIsWrappedObject | IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces | ProtectedEnumAsInts));
366+ s << " { " ;
367+
368+ QString scriptFunctionName = function->originalName ();
369+ AbstractMetaArgumentList args = function->arguments ();
370+ // call the C++ implementation
371+ if (function->type ()) {
372+ s << " return " ;
373+ // call the C++ implementation
374+ if (function->type ()->isReference ()) {
375+ s << " &" ;
376+ }
377+ }
378+ s << " (((" << promoterClassName (meta_class) << " *)theWrappedObject)->py_qualified_" ;
379+ s << function->originalName () << " (" ;
380+ for (int i = 0 ; i < args.size (); ++i) {
381+ if (i > 0 )
382+ s << " , " ;
383+ s << args.at (i)->argumentName ();
384+ }
385+ s << " ));" ;
386+ s << " }" << endl;
387+ }
351388 }
352389 if (meta_class->hasDefaultToStringFunction () || meta_class->hasToStringCapability ()) {
353390 s << " QString py_toString(" << meta_class->qualifiedCppName () << " *);" << endl;
@@ -380,6 +417,22 @@ void ShellHeaderGenerator::write(QTextStream &s, const AbstractMetaClass *meta_c
380417
381418}
382419
420+ void ShellHeaderGenerator::writePromoterArgs (AbstractMetaArgumentList &args, QTextStream & s)
421+ {
422+ for (int i = 0 ; i < args.size (); ++i) {
423+ if (i > 0 ) {
424+ s << " , " ;
425+ }
426+ if (args.at (i)->type ()->isEnum ()) {
427+ AbstractMetaEnum* enumType = m_classes.findEnum ((EnumTypeEntry *)args.at (i)->type ()->typeEntry ());
428+ if (enumType && enumType->wasProtected ()) {
429+ s << " (" << enumType->typeEntry ()->qualifiedCppName () << " )" ;
430+ }
431+ }
432+ s << args.at (i)->argumentName ();
433+ }
434+ }
435+
383436void ShellHeaderGenerator::writeInjectedCode (QTextStream &s, const AbstractMetaClass *meta_class, int type, bool recursive)
384437{
385438 const AbstractMetaClass *cls = meta_class;
0 commit comments