1 /**************************************************************************** 2 ** 3 ** DQt - D bindings for the Qt Toolkit 4 ** 5 ** GNU Lesser General Public License Usage 6 ** This file may be used under the terms of the GNU Lesser 7 ** General Public License version 3 as published by the Free Software 8 ** Foundation and appearing in the file LICENSE.LGPL3 included in the 9 ** packaging of this file. Please review the following information to 10 ** ensure the GNU Lesser General Public License version 3 requirements 11 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. 12 ** 13 ****************************************************************************/ 14 module qt.core.objectdefs; 15 extern(C++): 16 17 import qt.config; 18 import qt.core.bytearray; 19 import qt.core.metaobject; 20 import qt.core.namespace; 21 import qt.core.object; 22 import qt.core.objectdefs_impl; 23 import qt.core.point; 24 import qt.helpers; 25 import std.traits; 26 import std.meta; 27 version(QT_NO_TRANSLATION){}else 28 import qt.core.string; 29 30 /+ #if defined(__OBJC__) && !defined(__cplusplus) 31 # warning "File built in Objective-C mode (.m), but using Qt requires Objective-C++ (.mm)" 32 #endif 33 34 35 36 class QByteArray; 37 struct QArrayData; 38 39 class QString; 40 #ifndef Q_MOC_OUTPUT_REVISION 41 #define Q_MOC_OUTPUT_REVISION 67 42 #endif 43 44 // The following macros can be defined by tools that understand Qt 45 // to have the information from the macro. 46 #ifndef QT_ANNOTATE_CLASS 47 # define QT_ANNOTATE_CLASS(type, ...) 48 #endif 49 #ifndef QT_ANNOTATE_CLASS2 50 # define QT_ANNOTATE_CLASS2(type, a1, a2) 51 #endif 52 #ifndef QT_ANNOTATE_FUNCTION 53 # define QT_ANNOTATE_FUNCTION(x) 54 #endif 55 #ifndef QT_ANNOTATE_ACCESS_SPECIFIER 56 # define QT_ANNOTATE_ACCESS_SPECIFIER(x) 57 #endif 58 59 // The following macros are our "extensions" to C++ 60 // They are used, strictly speaking, only by the moc. 61 62 #ifndef Q_MOC_RUN +/ 63 /+ #ifndef QT_NO_META_MACROS 64 # if defined(QT_NO_KEYWORDS) 65 # define QT_NO_EMIT 66 # else 67 # ifndef QT_NO_SIGNALS_SLOTS_KEYWORDS 68 # define slots Q_SLOTS 69 # define signals Q_SIGNALS 70 # endif 71 # endif 72 # define Q_SLOTS QT_ANNOTATE_ACCESS_SPECIFIER(qt_slot) 73 # define Q_SIGNALS public QT_ANNOTATE_ACCESS_SPECIFIER(qt_signal) 74 # define Q_PRIVATE_SLOT(d, signature) QT_ANNOTATE_CLASS2(qt_private_slot, d, signature) 75 # define Q_EMIT 76 #ifndef QT_NO_EMIT 77 # define emit 78 #endif 79 #ifndef Q_CLASSINFO 80 # define Q_CLASSINFO(name, value) 81 #endif 82 #define Q_PLUGIN_METADATA(x) QT_ANNOTATE_CLASS(qt_plugin_metadata, x) 83 #define Q_INTERFACES(x) QT_ANNOTATE_CLASS(qt_interfaces, x) 84 #define Q_PROPERTY(...) QT_ANNOTATE_CLASS(qt_property, __VA_ARGS__) 85 #define Q_PRIVATE_PROPERTY(d, text) QT_ANNOTATE_CLASS2(qt_private_property, d, text) 86 #ifndef Q_REVISION 87 # define Q_REVISION(v) 88 #endif 89 #define Q_OVERRIDE(text) QT_ANNOTATE_CLASS(qt_override, text) 90 #define QDOC_PROPERTY(text) QT_ANNOTATE_CLASS(qt_qdoc_property, text) 91 #define Q_ENUMS(x) QT_ANNOTATE_CLASS(qt_enums, x) 92 #define Q_FLAGS(x) QT_ANNOTATE_CLASS(qt_enums, x) 93 #define Q_ENUM_IMPL(ENUM) \ 94 friend Q_DECL_CONSTEXPR const QMetaObject *qt_getEnumMetaObject(ENUM) noexcept { return &staticMetaObject; } \ 95 friend Q_DECL_CONSTEXPR const char *qt_getEnumName(ENUM) noexcept { return #ENUM; } 96 #define Q_ENUM(x) Q_ENUMS(x) Q_ENUM_IMPL(x) 97 #define Q_FLAG(x) Q_FLAGS(x) Q_ENUM_IMPL(x) 98 #define Q_ENUM_NS_IMPL(ENUM) \ 99 inline Q_DECL_CONSTEXPR const QMetaObject *qt_getEnumMetaObject(ENUM) noexcept { return &staticMetaObject; } \ 100 inline Q_DECL_CONSTEXPR const char *qt_getEnumName(ENUM) noexcept { return #ENUM; } 101 #define Q_ENUM_NS(x) Q_ENUMS(x) Q_ENUM_NS_IMPL(x) 102 #define Q_FLAG_NS(x) Q_FLAGS(x) Q_ENUM_NS_IMPL(x) 103 #define Q_SCRIPTABLE QT_ANNOTATE_FUNCTION(qt_scriptable) 104 #define Q_INVOKABLE QT_ANNOTATE_FUNCTION(qt_invokable) 105 #define Q_SIGNAL QT_ANNOTATE_FUNCTION(qt_signal) 106 #define Q_SLOT QT_ANNOTATE_FUNCTION(qt_slot) 107 #endif +/ // QT_NO_META_MACROS 108 109 version(QT_NO_TRANSLATION){}else 110 { 111 // full set of tr functions 112 /+ # define QT_TR_FUNCTIONS \ 113 static inline QString tr(const char *s, const char *c = nullptr, int n = -1) \ 114 { return staticMetaObject.tr(s, c, n); } \ 115 QT_DEPRECATED static inline QString trUtf8(const char *s, const char *c = nullptr, int n = -1) \ 116 { return staticMetaObject.tr(s, c, n); } +/ 117 enum QT_TR_FUNCTIONS = 118 q{pragma(inline, true) static imported!"qt.core.string".QString tr(const(char)* s, const(char)* c = null, int n = -1) 119 { return staticMetaObject.tr(s, c, n); } 120 /+ QT_DEPRECATED +/ pragma(inline, true) static imported!"qt.core.string".QString trUtf8(const(char)* s, const(char)* c = null, int n = -1) 121 { return staticMetaObject.tr(s, c, n); }}; 122 } 123 version(QT_NO_TRANSLATION) 124 { 125 // inherit the ones from QObject 126 /+ # define QT_TR_FUNCTIONS +/ 127 } 128 129 /+ #ifdef Q_CLANG_QDOC 130 #define QT_TR_FUNCTIONS 131 #endif 132 133 // ### Qt6: remove 134 #define Q_OBJECT_CHECK /* empty, unused since Qt 5.2 */ 135 136 #if defined(Q_CC_INTEL) 137 // Cannot redefine the visibility of a method in an exported class 138 # define Q_DECL_HIDDEN_STATIC_METACALL 139 #else 140 # define Q_DECL_HIDDEN_STATIC_METACALL Q_DECL_HIDDEN 141 #endif 142 143 #if defined(Q_CC_CLANG) && Q_CC_CLANG >= 306 144 # define Q_OBJECT_NO_OVERRIDE_WARNING QT_WARNING_DISABLE_CLANG("-Winconsistent-missing-override") 145 #elif defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 501 146 # define Q_OBJECT_NO_OVERRIDE_WARNING QT_WARNING_DISABLE_GCC("-Wsuggest-override") 147 #else 148 # define Q_OBJECT_NO_OVERRIDE_WARNING 149 #endif 150 151 #if defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 600 152 # define Q_OBJECT_NO_ATTRIBUTES_WARNING QT_WARNING_DISABLE_GCC("-Wattributes") 153 #else 154 # define Q_OBJECT_NO_ATTRIBUTES_WARNING 155 #endif +/ 156 157 /* qmake ignore Q_OBJECT */ 158 /+ #define Q_OBJECT \ 159 public: \ 160 QT_WARNING_PUSH \ 161 Q_OBJECT_NO_OVERRIDE_WARNING \ 162 static const QMetaObject staticMetaObject; \ 163 virtual const QMetaObject *metaObject() const; \ 164 virtual void *qt_metacast(const char *); \ 165 virtual int qt_metacall(QMetaObject::Call, int, void **); \ 166 QT_TR_FUNCTIONS \ 167 private: \ 168 Q_OBJECT_NO_ATTRIBUTES_WARNING \ 169 Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \ 170 QT_WARNING_POP \ 171 struct QPrivateSignal {}; \ 172 QT_ANNOTATE_CLASS(qt_qobject, "") +/ 173 enum Q_OBJECT = 174 q{ public: 175 /+ QT_WARNING_PUSH 176 Q_OBJECT_NO_OVERRIDE_WARNING +/ 177 extern(C++) extern } ~ exportOnWindows ~ q{static __gshared const(imported!q{qt.core.objectdefs}.QMetaObject) staticMetaObject; 178 extern(C++) override /+ virtual +/ const(imported!q{qt.core.objectdefs}.QMetaObject)* metaObject() const; 179 extern(C++) override /+ virtual +/ void* qt_metacast(const(char)* ); 180 extern(C++) override /+ virtual +/ int qt_metacall(imported!q{qt.core.objectdefs}.QMetaObject.Call, int, void** ); 181 } ~ QT_TR_FUNCTIONS ~ q{ 182 private: 183 /+ Q_OBJECT_NO_ATTRIBUTES_WARNING +/ 184 /+ Q_DECL_HIDDEN_STATIC_METACALL +/ static void qt_static_metacall(imported!"qt.core.object".QObject , imported!q{qt.core.objectdefs}.QMetaObject.Call, int, void** ); 185 /+ QT_WARNING_POP +/ 186 extern(C++) struct QPrivateSignal {}}; 187 /+ QT_ANNOTATE_CLASS(qt_qobject, "") +/ 188 189 /* qmake ignore Q_OBJECT */ 190 /+ #define Q_OBJECT_FAKE Q_OBJECT QT_ANNOTATE_CLASS(qt_fake, "") 191 192 #ifndef QT_NO_META_MACROS +/ 193 /* qmake ignore Q_GADGET */ 194 195 struct CPPMemberFunctionPointer(T) 196 { 197 void *ptr; 198 uint adj; 199 } 200 201 template memberFunctionExternDeclaration(alias F) 202 { 203 mixin((){ 204 string code; 205 version(Windows) 206 static if(packageName!(F).length > 3 && packageName!(F)[0..3] == "qt.") 207 code ~= "export "; 208 code ~= "extern(" ~ functionLinkage!F ~ ")"; 209 code ~= q{pragma(mangle, F.mangleof) ReturnType!F memberFunctionExternDeclaration(__traits(parent, F), Parameters!F);}; 210 return code; 211 }()); 212 } 213 214 enum NotIsConstructor(alias F) = __traits(identifier, F) != "__ctor"; 215 216 template MetaObjectImpl(T) 217 { 218 import qt.core.refcount; 219 import qt.core.metatype; 220 extern(D): 221 222 alias Overloads(string name) = __traits(getOverloads, T, name); 223 //pragma(msg, staticMap!(Overloads, __traits(derivedMembers, T))); 224 alias allFunctions = Filter!(NotIsConstructor, staticMap!(Overloads, __traits(derivedMembers, T))); 225 alias allSignals = Filter!(IsQSignal, allFunctions); 226 alias allSlots = Filter!(IsQSlot, allFunctions); 227 alias allInvokables = Filter!(IsQInvokable, allFunctions); 228 alias allMethods = std.meta.AliasSeq!(allSignals, allSlots, allInvokables); 229 230 /*pragma(msg, allSignals); 231 pragma(msg, allSlots); 232 pragma(msg, allInvokables);*/ 233 234 template signalIndex(alias F) 235 { 236 enum signalIndex = staticIndexOf!(F, allSignals); 237 } 238 239 enum CODE = (){ 240 import std.conv; 241 242 string concatenatedStrings; 243 string stringLiteralsCode; 244 size_t numStrings; 245 size_t[string] stringCache; 246 247 size_t addString(string s) 248 { 249 if(s in stringCache) 250 return stringCache[s]; 251 stringLiteralsCode ~= text("QT_MOC_LITERAL(", numStrings, ", ", concatenatedStrings.length, ", " , s.length, "),\n"); 252 concatenatedStrings ~= s; 253 concatenatedStrings ~= "\0"; 254 stringCache[s] = numStrings; 255 return numStrings++; 256 } 257 258 addString(__traits(identifier, T)); 259 260 size_t currentOutputIndex = 0; 261 262 currentOutputIndex += 14; 263 264 size_t methodsStartIndex = currentOutputIndex; 265 266 string metaDataCode = mixin(interpolateMixin(q{ 267 // content: 268 8, // revision 269 0, // classname 270 0, 0, // classinfo 271 $(text(allMethods.length)), $(text(methodsStartIndex)), // methods 272 0, 0, // properties 273 0, 0, // enums/sets 274 0, 0, // constructors 275 0, // flags 276 $(text(allSignals.length)), // signalCount 277 278 })); 279 280 assert(methodsStartIndex == currentOutputIndex); 281 currentOutputIndex += 5 * allMethods.length; 282 283 string typeToMeta(T2)() 284 { 285 import qt.core.list: QList; 286 import qt.core.vector: QVector; 287 static if(is(T2 == int)) 288 return "QMetaType.Type.Int"; 289 else static if(is(T2 == uint)) 290 return "QMetaType.Type.UInt"; 291 else static if(is(T2 == bool)) 292 return "QMetaType.Type.Bool"; 293 else static if(is(T2 == double)) 294 return "QMetaType.Type.Double"; 295 else static if(is(const(T2) == const(QString))) 296 return "QMetaType.Type.QString"; 297 else static if(is(const(T2) == const(QList!int))) 298 return text("0x80000000 | ", addString("QList<int>")); 299 else static if(is(const(T2) == const(QVector!int))) 300 return text("0x80000000 | ", addString("QVector<int>")); 301 else static if(is(const(T2) == const(QPoint))) 302 return "QMetaType.Type.QPoint"; 303 else static if(is(T2 == int*)) 304 return text("0x80000000 | ", addString("int*")); 305 else 306 static assert("TODO: Type not yet supported ", T2.stringof); 307 } 308 309 void addMethods(M...)(string typename, uint type) 310 { 311 if(M.length) 312 metaDataCode ~= " // " ~ typename ~ ": name, argc, parameters, tag, flags\n"; 313 static foreach(i; 0..M.length) 314 {{ 315 size_t nameId = addString(__traits(identifier, M[i])); 316 size_t parameterCount = Parameters!(M[i]).length; 317 uint flags; 318 flags |= 2; // Public // TODO 319 metaDataCode ~= mixin(interpolateMixin(q{ 320 $(text(nameId)), $(text(parameterCount)), $(text(currentOutputIndex)), 2, $(text(flags)), $("// " ~ __traits(identifier, M[i])) 321 })); 322 currentOutputIndex += 1 + 2 * parameterCount; 323 }} 324 } 325 addMethods!(allSignals)("signals", 4); 326 addMethods!(allSlots)("slots", 8); 327 addMethods!(allInvokables)("methods", 0); 328 void addMethodParameters(M...)(string typename) 329 { 330 if(M.length) 331 metaDataCode ~= " // " ~ typename ~ ": parameters\n"; 332 static foreach(i; 0..M.length) 333 { 334 metaDataCode ~= " QMetaType.Type.Void, "; // TODO: correct return type 335 foreach(P; Parameters!(M[i])) 336 metaDataCode ~= typeToMeta!(P) ~ ", "; 337 foreach(j, P; Parameters!(M[i])) 338 metaDataCode ~= text(addString(ParameterIdentifierTuple!(M[i])[j]), ", "); 339 metaDataCode ~= "// " ~ __traits(identifier, M[i]) ~ "\n"; 340 } 341 } 342 addMethodParameters!(allSignals)("signals"); 343 addMethodParameters!(allSlots)("slots"); 344 addMethodParameters!(allInvokables)("methods"); 345 346 addString(""); 347 348 string concatenatedStringsCode = "\""; 349 foreach(char c; concatenatedStrings) 350 { 351 if(c == '\0') 352 concatenatedStringsCode ~= "\\0"; 353 else if(c == '\\') 354 concatenatedStringsCode ~= "\\\\"; 355 else if(c == '\n') 356 concatenatedStringsCode ~= "\\n"; 357 else if(c == '\r') 358 concatenatedStringsCode ~= "\\r"; 359 else if(c == '\"') 360 concatenatedStringsCode ~= "\\\""; 361 else if(c == '\'') 362 concatenatedStringsCode ~= "\\\'"; 363 else 364 concatenatedStringsCode ~= c; 365 } 366 concatenatedStringsCode ~= "\""; 367 368 return mixin(interpolateMixin(q{ 369 extern(C++) struct stringdata_t { 370 QByteArrayData[$(text(numStrings))] data; 371 char[$(text(concatenatedStrings.length))] stringdata0; 372 }; 373 374 extern(C++) const(QByteArrayData) Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(int size, size_t offset) 375 { 376 return const(QByteArrayData)(Q_REFCOUNT_INITIALIZE_STATIC, size, 0,/* 0,*/ offset); 377 } 378 379 extern(C++) const(QByteArrayData) QT_MOC_LITERAL(size_t idx, size_t ofs, int len) 380 { 381 return Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, 382 ptrdiff_t(stringdata_t.stringdata0.offsetof + ofs 383 - idx * QByteArrayData.sizeof) 384 ); 385 } 386 387 extern(C++) static __gshared const stringdata_t stringdata = { 388 [ 389 $(stringLiteralsCode) 390 ], 391 $(concatenatedStringsCode) 392 }; 393 394 extern(C++) static __gshared const uint[$(text(currentOutputIndex + 1))] meta_data = [ 395 $(metaDataCode) 396 0 // eod 397 ]; 398 399 version(Windows) 400 { 401 pragma(mangle, T.staticMetaObject.mangleof) 402 extern(C++) static __gshared const(QMetaObject) staticMetaObject = { { 403 null, 404 &stringdata, 405 meta_data.ptr, 406 &T.qt_static_metacall, 407 null, 408 null 409 } }; 410 shared static this() 411 { 412 // Necessary for Windows, because staticMetaObject from a DLL can't be used directly. 413 (cast(QMetaObject*)&staticMetaObject).d.superdata.direct = &BaseClassesTuple!(T)[0].staticMetaObject; 414 } 415 } 416 else 417 { 418 pragma(mangle, T.staticMetaObject.mangleof) 419 extern(C++) static __gshared const(QMetaObject) staticMetaObject = { { 420 QMetaObject.SuperData.link!(BaseClassesTuple!(T)[0].staticMetaObject)(), 421 &stringdata, 422 meta_data.ptr, 423 &T.qt_static_metacall, 424 null, 425 null 426 } }; 427 } 428 })); 429 }(); 430 //pragma(msg, CODE); 431 mixin(CODE); 432 } 433 434 enum Q_OBJECT_D = q{ 435 public: 436 extern(C++) extern static __gshared const(imported!q{qt.core.objectdefs}.QMetaObject) staticMetaObject; 437 extern(C++) override const(imported!q{qt.core.objectdefs}.QMetaObject)* metaObject() const 438 { 439 import qt.core.object; 440 return qt.core.object.QObject.d_ptr.metaObject ? qt.core.object.QObject.d_ptr.dynamicMetaObject() : &staticMetaObject; 441 } 442 extern(C++) override void * qt_metacast(const(char)* _clname) 443 { 444 import qt.core.objectdefs; 445 if (!_clname) return null; 446 import core.stdc.string; 447 if (!core.stdc..string.strcmp(_clname, qt.core.objectdefs.MetaObjectImpl!(typeof(this)).stringdata.stringdata0.ptr)) 448 return static_cast!(void*)(this); 449 return super.qt_metacast(_clname); 450 } 451 extern(C++) override int qt_metacall(imported!q{qt.core.objectdefs}.QMetaObject.Call _c, int _id, void **_a) 452 { 453 import qt.core.objectdefs; 454 _id = super.qt_metacall(_c, _id, _a); 455 if (_id < 0) 456 return _id; 457 alias allMethods = qt.core.objectdefs.MetaObjectImpl!(typeof(this)).allMethods; 458 if (_c == qt.core.objectdefs.QMetaObject.Call.InvokeMetaMethod) { 459 if (_id < allMethods.length) 460 qt_static_metacall(this, _c, _id, _a); 461 _id -= allMethods.length; 462 } else if (_c == qt.core.objectdefs.QMetaObject.Call.RegisterMethodArgumentMetaType) { 463 if (_id < allMethods.length) 464 *reinterpret_cast!(int*)(_a[0]) = -1; 465 _id -= allMethods.length; 466 } 467 return _id; 468 } 469 extern(C++) static void qt_static_metacall(imported!"qt.core.object".QObject _o, imported!q{qt.core.objectdefs}.QMetaObject.Call _c, int _id, void **_a) 470 { 471 import qt.core.objectdefs; 472 if (_c == qt.core.objectdefs.QMetaObject.Call.InvokeMetaMethod) { 473 alias allMethods = qt.core.objectdefs.MetaObjectImpl!(typeof(this)).allMethods; 474 import std.conv, std.traits; 475 auto _t = static_cast!(typeof(this))(_o); 476 //Q_UNUSED(_t) 477 switch (_id) { 478 mixin((){ 479 string methodCallCases; 480 static foreach(i; 0..allMethods.length) 481 {{ 482 methodCallCases ~= text("\n case ", i, ": _t.", __traits(identifier, allMethods[i]), "("); 483 static foreach(j, P; Parameters!(allMethods[i])) 484 { 485 methodCallCases ~= text("*cast(Parameters!(allMethods[", i, "])[", j, "]*)(_a[", j + 1, "]), "); 486 } 487 methodCallCases ~= "); break;"; 488 }} 489 return methodCallCases; 490 }()); 491 default: {} 492 } 493 } else if (_c == qt.core.objectdefs.QMetaObject.Call.RegisterMethodArgumentMetaType) { 494 // TODO 495 } else if (_c == qt.core.objectdefs.QMetaObject.Call.IndexOfMethod) { 496 alias allSignals = qt.core.objectdefs.MetaObjectImpl!(typeof(this)).allSignals; 497 int *result = reinterpret_cast!(int *)(_a[0]); 498 static foreach(i; 0..allSignals.length) 499 {{ 500 alias _t = qt.core.objectdefs.CPPMemberFunctionPointer!(typeof(this)); 501 502 auto fp = &memberFunctionExternDeclaration!(allSignals[i]); 503 qt.core.objectdefs.CPPMemberFunctionPointer!(typeof(this)) memberFunction = qt.core.objectdefs.CPPMemberFunctionPointer!(typeof(this))(fp); 504 505 if (*reinterpret_cast!(_t *)(_a[1]) == memberFunction) { 506 *result = i; 507 return; 508 } 509 }} 510 } 511 //Q_UNUSED(_a); 512 } 513 } ~ QT_TR_FUNCTIONS ~ q{ 514 private: 515 struct QPrivateSignal {} 516 }; 517 518 enum Q_SIGNAL_IMPL_D = q{ 519 struct Dummy{} 520 import std.traits; 521 void*[std.traits.Parameters!(__traits(parent, Dummy)).length + 1] _a = mixin((){ 522 string r = "[null"; 523 static foreach(i; 0..std.traits.Parameters!(__traits(parent, Dummy)).length) 524 r ~= " , cast(void*)&" ~ std.traits.ParameterIdentifierTuple!(__traits(parent, Dummy))[i]; 525 r ~= "]"; 526 return r; 527 }()); 528 imported!q{qt.core.objectdefs}.QMetaObject.activate(this, &staticMetaObject, imported!q{qt.core.objectdefs}.MetaObjectImpl!(typeof(this)).signalIndex!(__traits(parent, Dummy)), _a.ptr); 529 }; 530 531 /+ #define Q_GADGET \ 532 public: \ 533 static const QMetaObject staticMetaObject; \ 534 void qt_check_for_QGADGET_macro(); \ 535 typedef void QtGadgetHelper; \ 536 private: \ 537 QT_WARNING_PUSH \ 538 Q_OBJECT_NO_ATTRIBUTES_WARNING \ 539 Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \ 540 QT_WARNING_POP \ 541 QT_ANNOTATE_CLASS(qt_qgadget, "") \ 542 /*end*/ +/ 543 enum Q_GADGET = 544 q{ public: 545 extern static __gshared const(imported!q{qt.core.objectdefs}.QMetaObject) staticMetaObject; 546 /+ void qt_check_for_QGADGET_macro(); +/ 547 alias QtGadgetHelper = void; 548 private: 549 /+ QT_WARNING_PUSH 550 Q_OBJECT_NO_ATTRIBUTES_WARNING +/ 551 /+ Q_DECL_HIDDEN_STATIC_METACALL +/ static void qt_static_metacall(imported!q{qt.core.object}.QObject , imported!q{qt.core.objectdefs}.QMetaObject.Call, int, void** );}; 552 /+ QT_WARNING_POP 553 QT_ANNOTATE_CLASS(qt_qgadget, "") +/ 554 /*end*/ 555 556 /* qmake ignore Q_NAMESPACE_EXPORT */ 557 /+ #define Q_NAMESPACE_EXPORT(...) \ 558 extern __VA_ARGS__ const QMetaObject staticMetaObject; \ 559 QT_ANNOTATE_CLASS(qt_qnamespace, "") \ 560 /*end*/ 561 562 /* qmake ignore Q_NAMESPACE */ 563 #define Q_NAMESPACE Q_NAMESPACE_EXPORT() \ 564 /*end*/ +/ 565 566 /+ #endif +/ // QT_NO_META_MACROS 567 568 /+ #else // Q_MOC_RUN 569 #define slots slots 570 #define signals signals 571 #define Q_SLOTS Q_SLOTS 572 #define Q_SIGNALS Q_SIGNALS 573 #define Q_CLASSINFO(name, value) Q_CLASSINFO(name, value) 574 #define Q_INTERFACES(x) Q_INTERFACES(x) 575 #define Q_PROPERTY(text) Q_PROPERTY(text) 576 #define Q_PRIVATE_PROPERTY(d, text) Q_PRIVATE_PROPERTY(d, text) 577 #define Q_REVISION(v) Q_REVISION(v) 578 #define Q_OVERRIDE(text) Q_OVERRIDE(text) 579 #define Q_ENUMS(x) Q_ENUMS(x) 580 #define Q_FLAGS(x) Q_FLAGS(x) 581 #define Q_ENUM(x) Q_ENUM(x) 582 #define Q_FLAGS(x) Q_FLAGS(x) 583 /* qmake ignore Q_OBJECT */ 584 #define Q_OBJECT Q_OBJECT 585 /* qmake ignore Q_OBJECT */ 586 #define Q_OBJECT_FAKE Q_OBJECT_FAKE 587 /* qmake ignore Q_GADGET */ 588 #define Q_GADGET Q_GADGET 589 #define Q_SCRIPTABLE Q_SCRIPTABLE 590 #define Q_INVOKABLE Q_INVOKABLE 591 #define Q_SIGNAL Q_SIGNAL 592 #define Q_SLOT Q_SLOT 593 #endif //Q_MOC_RUN 594 595 #ifndef QT_NO_META_MACROS 596 // macro for onaming members 597 #ifdef METHOD 598 #undef METHOD 599 #endif 600 #ifdef SLOT 601 #undef SLOT 602 #endif 603 #ifdef SIGNAL 604 #undef SIGNAL 605 #endif 606 #endif +/ // QT_NO_META_MACROS 607 608 /+ Q_CORE_EXPORT +/ const(char)* qFlagLocation(const(char)* method); 609 610 /+ #ifndef QT_NO_META_MACROS +/ 611 /+ #ifndef QT_NO_DEBUG 612 # define QLOCATION "\0" __FILE__ ":" QT_STRINGIFY(__LINE__) 613 # ifndef QT_NO_KEYWORDS 614 # define METHOD(a) qFlagLocation("0"#a QLOCATION) 615 # endif 616 # define SLOT(a) qFlagLocation("1"#a QLOCATION) 617 # define SIGNAL(a) qFlagLocation("2"#a QLOCATION) 618 #else +/ 619 /+ # ifndef QT_NO_KEYWORDS 620 # define METHOD(a) "0"#a 621 # endif +/ 622 /+ # define SLOT(a) "1"#a +/ 623 extern(D) alias SLOT = function string(string a) 624 { 625 return mixin(interpolateMixin(q{"1" ~$(stringifyMacroParameter(a))})); 626 }; 627 /+ # define SIGNAL(a) "2"#a +/ 628 extern(D) alias SIGNAL = function string(string a) 629 { 630 return mixin(interpolateMixin(q{"2" ~$(stringifyMacroParameter(a))})); 631 }; 632 /+ #endif 633 634 #define QMETHOD_CODE 0 // member type codes 635 #define QSLOT_CODE 1 636 #define QSIGNAL_CODE 2 +/ 637 /+ #endif // QT_NO_META_MACROS 638 639 #define Q_ARG(type, data) QArgument<type >(#type, data) 640 #define Q_RETURN_ARG(type, data) QReturnArgument<type >(#type, data) 641 642 class QObject; 643 class QMetaMethod; 644 class QMetaEnum; 645 class QMetaProperty; 646 class QMetaClassInfo; +/ 647 648 649 extern(C++, class) struct /+ Q_CORE_EXPORT +/ QGenericArgument 650 { 651 public: 652 pragma(inline, true) this(const(char)* aName/+ = null+/, const(void)* aData = null) 653 { 654 this._data = aData; 655 this._name = aName; 656 } 657 pragma(inline, true) void* data() const { return const_cast!(void*)(_data); } 658 pragma(inline, true) const(char)* name() const { return _name; } 659 660 private: 661 const(void)* _data = null; 662 const(char)* _name = null; 663 } 664 665 extern(C++, class) struct /+ Q_CORE_EXPORT +/ QGenericReturnArgument 666 { 667 public QGenericArgument base0; 668 alias base0 this; 669 public: 670 pragma(inline, true) this(const(char)* aName/+ = null+/, void* aData = null) 671 { 672 this.base0 = QGenericArgument(aName, aData); 673 } 674 } 675 676 class QArgument(T): QGenericArgument 677 { 678 public: 679 pragma(inline, true) this(const(char)* aName, ref const(T) aData) 680 { 681 super(aName, static_cast!(const(void)*)(&aData)); 682 } 683 } 684 /+ template <class T> 685 class QArgument<T &>: public QGenericArgument 686 { 687 public: 688 inline QArgument(const char *aName, T &aData) 689 : QGenericArgument(aName, static_cast<const void *>(&aData)) 690 {} 691 }; +/ 692 693 694 class QReturnArgument(T): QGenericReturnArgument 695 { 696 public: 697 pragma(inline, true) this(const(char)* aName, ref T aData) 698 { 699 super(aName, static_cast!(void*)(&aData)); 700 } 701 } 702 703 struct /+ Q_CORE_EXPORT +/ QMetaObject 704 { 705 /+ 706 extern(C++, class) struct Connection; 707 +/extern(C++, class) struct /+ Q_CORE_EXPORT +/ Connection { 708 private: 709 void* d_ptr; //QObjectPrivate::Connection* 710 /+ explicit +/this(void* data) 711 { 712 this.d_ptr = data; 713 } 714 /+ friend class QObject; +/ 715 /+ friend class QObjectPrivate; +/ 716 /+ friend struct QMetaObject; +/ 717 bool isConnected_helper() const; 718 public: 719 ~this(); 720 721 this(ref const(Connection) other); 722 /+ref Connection operator =(ref const(Connection) other);+/ 723 /+ #ifdef Q_QDOC 724 operator bool() const; 725 #else +/ 726 alias RestrictedBool = void*/+ Connection::* +/*; 727 /+auto opCast(T : RestrictedBool)() const { return d_ptr && isConnected_helper() ? &Connection.d_ptr : null; }+/ 728 /+ #endif +/ 729 730 /+ Connection(Connection &&o) noexcept : d_ptr(o.d_ptr) { o.d_ptr = nullptr; } +/ 731 /+ Connection &operator=(Connection &&other) noexcept 732 { qSwap(d_ptr, other.d_ptr); return *this; } +/ 733 } 734 735 const(char)* className() const; 736 /+ pragma(inline, true) const(QMetaObject)* superClass() const 737 { return cast(const(QMetaObject)*)(d.superdata); }+/ 738 739 bool inherits(const(QMetaObject)* metaObject) const/+ noexcept+/; 740 /*QObject cast_(QObject obj) const; 741 const(QObject) cast_(const(QObject) obj) const;*/ 742 743 version(QT_NO_TRANSLATION){}else 744 { 745 QString tr(const(char)* s, const(char)* c, int n = -1) const; 746 } 747 748 int methodOffset() const; 749 int enumeratorOffset() const; 750 int propertyOffset() const; 751 int classInfoOffset() const; 752 753 int constructorCount() const; 754 int methodCount() const; 755 int enumeratorCount() const; 756 int propertyCount() const; 757 int classInfoCount() const; 758 759 int indexOfConstructor(const(char)* constructor) const; 760 int indexOfMethod(const(char)* method) const; 761 int indexOfSignal(const(char)* signal) const; 762 int indexOfSlot(const(char)* slot) const; 763 int indexOfEnumerator(const(char)* name) const; 764 int indexOfProperty(const(char)* name) const; 765 int indexOfClassInfo(const(char)* name) const; 766 767 QMetaMethod constructor(int index) const; 768 QMetaMethod method(int index) const; 769 QMetaEnum enumerator(int index) const; 770 QMetaProperty property(int index) const; 771 QMetaClassInfo classInfo(int index) const; 772 QMetaProperty userProperty() const; 773 774 static bool checkConnectArgs(const(char)* signal, const(char)* method); 775 static bool checkConnectArgs(ref const(QMetaMethod) signal, 776 ref const(QMetaMethod) method); 777 static QByteArray normalizedSignature(const(char)* method); 778 static QByteArray normalizedType(const(char)* type); 779 780 // internal index-based connect 781 /+ static Connection connect(const QObject *sender, int signal_index, 782 const QObject *receiver, int method_index, 783 int type = 0, int *types = nullptr); +/ 784 // internal index-based disconnect 785 /+ static bool disconnect(const QObject *sender, int signal_index, 786 const QObject *receiver, int method_index); +/ 787 static bool disconnectOne(const(QObject) sender, int signal_index, 788 const(QObject) receiver, int method_index); 789 // internal slot-name based connect 790 static void connectSlotsByName(QObject o); 791 792 // internal index-based signal activation 793 static void activate(QObject sender, int signal_index, void** argv); 794 static void activate(QObject sender, const(QMetaObject)* , int local_signal_index, void** argv); 795 static void activate(QObject sender, int signal_offset, int local_signal_index, void** argv); 796 797 static bool invokeMethod(QObject obj, const(char)* member, 798 /+ Qt:: +/qt.core.namespace.ConnectionType, 799 QGenericReturnArgument ret, 800 QGenericArgument val0 = QGenericArgument(null), 801 QGenericArgument val1 = QGenericArgument(), 802 QGenericArgument val2 = QGenericArgument(), 803 QGenericArgument val3 = QGenericArgument(), 804 QGenericArgument val4 = QGenericArgument(), 805 QGenericArgument val5 = QGenericArgument(), 806 QGenericArgument val6 = QGenericArgument(), 807 QGenericArgument val7 = QGenericArgument(), 808 QGenericArgument val8 = QGenericArgument(), 809 QGenericArgument val9 = QGenericArgument()); 810 811 /+ pragma(inline, true) static bool invokeMethod(QObject obj, const(char)* member, 812 QGenericReturnArgument ret, 813 QGenericArgument val0 = QGenericArgument(null), 814 QGenericArgument val1 = QGenericArgument(), 815 QGenericArgument val2 = QGenericArgument(), 816 QGenericArgument val3 = QGenericArgument(), 817 QGenericArgument val4 = QGenericArgument(), 818 QGenericArgument val5 = QGenericArgument(), 819 QGenericArgument val6 = QGenericArgument(), 820 QGenericArgument val7 = QGenericArgument(), 821 QGenericArgument val8 = QGenericArgument(), 822 QGenericArgument val9 = QGenericArgument()) 823 { 824 return invokeMethod(obj, member, /+ Qt:: +/qt.core.namespace.ConnectionType.AutoConnection, ret, val0, val1, val2, val3, 825 val4, val5, val6, val7, val8, val9); 826 }+/ 827 828 /+ pragma(inline, true) static bool invokeMethod(QObject obj, const(char)* member, 829 /+ Qt:: +/qt.core.namespace.ConnectionType type, 830 QGenericArgument val0 = QGenericArgument(null), 831 QGenericArgument val1 = QGenericArgument(), 832 QGenericArgument val2 = QGenericArgument(), 833 QGenericArgument val3 = QGenericArgument(), 834 QGenericArgument val4 = QGenericArgument(), 835 QGenericArgument val5 = QGenericArgument(), 836 QGenericArgument val6 = QGenericArgument(), 837 QGenericArgument val7 = QGenericArgument(), 838 QGenericArgument val8 = QGenericArgument(), 839 QGenericArgument val9 = QGenericArgument()) 840 { 841 return invokeMethod(obj, member, type, QGenericReturnArgument(), val0, val1, val2, 842 val3, val4, val5, val6, val7, val8, val9); 843 }+/ 844 845 /+ pragma(inline, true) static bool invokeMethod(QObject obj, const(char)* member, 846 QGenericArgument val0 = QGenericArgument(null), 847 QGenericArgument val1 = QGenericArgument(), 848 QGenericArgument val2 = QGenericArgument(), 849 QGenericArgument val3 = QGenericArgument(), 850 QGenericArgument val4 = QGenericArgument(), 851 QGenericArgument val5 = QGenericArgument(), 852 QGenericArgument val6 = QGenericArgument(), 853 QGenericArgument val7 = QGenericArgument(), 854 QGenericArgument val8 = QGenericArgument(), 855 QGenericArgument val9 = QGenericArgument()) 856 { 857 return invokeMethod(obj, member, /+ Qt:: +/qt.core.namespace.ConnectionType.AutoConnection, QGenericReturnArgument(), val0, 858 val1, val2, val3, val4, val5, val6, val7, val8, val9); 859 }+/ 860 861 /+ #ifdef Q_CLANG_QDOC 862 template<typename Functor, typename FunctorReturnType> 863 static bool invokeMethod(QObject *context, Functor function, Qt::ConnectionType type = Qt::AutoConnection, FunctorReturnType *ret = nullptr); 864 template<typename Functor, typename FunctorReturnType> 865 static bool invokeMethod(QObject *context, Functor function, FunctorReturnType *ret); 866 #else +/ 867 868 // invokeMethod() for member function pointer 869 /+ template <typename Func> +/ 870 /+ static typename std::enable_if<QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction 871 && !std::is_convertible<Func, const char*>::value 872 && QtPrivate::FunctionPointer<Func>::ArgumentCount == 0, bool>::type 873 invokeMethod(typename QtPrivate::FunctionPointer<Func>::Object *object, 874 Func function, 875 Qt::ConnectionType type = Qt::AutoConnection, 876 typename QtPrivate::FunctionPointer<Func>::ReturnType *ret = nullptr) 877 { 878 return invokeMethodImpl(object, new QtPrivate::QSlotObjectWithNoArgs<Func>(function), type, ret); 879 } +/ 880 881 /+ template <typename Func> +/ 882 /+ static typename std::enable_if<QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction 883 && !std::is_convertible<Func, const char*>::value 884 && QtPrivate::FunctionPointer<Func>::ArgumentCount == 0, bool>::type 885 invokeMethod(typename QtPrivate::FunctionPointer<Func>::Object *object, 886 Func function, 887 typename QtPrivate::FunctionPointer<Func>::ReturnType *ret) 888 { 889 return invokeMethodImpl(object, new QtPrivate::QSlotObjectWithNoArgs<Func>(function), Qt::AutoConnection, ret); 890 } +/ 891 892 // invokeMethod() for function pointer (not member) 893 /+ template <typename Func> +/ 894 /+ static typename std::enable_if<!QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction 895 && !std::is_convertible<Func, const char*>::value 896 && QtPrivate::FunctionPointer<Func>::ArgumentCount == 0, bool>::type 897 invokeMethod(QObject *context, Func function, 898 Qt::ConnectionType type = Qt::AutoConnection, 899 typename QtPrivate::FunctionPointer<Func>::ReturnType *ret = nullptr) 900 { 901 return invokeMethodImpl(context, new QtPrivate::QFunctorSlotObjectWithNoArgsImplicitReturn<Func>(function), type, ret); 902 } +/ 903 904 /+ template <typename Func> +/ 905 /+ static typename std::enable_if<!QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction 906 && !std::is_convertible<Func, const char*>::value 907 && QtPrivate::FunctionPointer<Func>::ArgumentCount == 0, bool>::type 908 invokeMethod(QObject *context, Func function, 909 typename QtPrivate::FunctionPointer<Func>::ReturnType *ret) 910 { 911 return invokeMethodImpl(context, new QtPrivate::QFunctorSlotObjectWithNoArgsImplicitReturn<Func>(function), Qt::AutoConnection, ret); 912 } +/ 913 914 // invokeMethod() for Functor 915 /+ template <typename Func> +/ 916 /+ static typename std::enable_if<!QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction 917 && QtPrivate::FunctionPointer<Func>::ArgumentCount == -1 918 && !std::is_convertible<Func, const char*>::value, bool>::type 919 invokeMethod(QObject *context, Func function, 920 Qt::ConnectionType type = Qt::AutoConnection, decltype(function()) *ret = nullptr) 921 { 922 return invokeMethodImpl(context, 923 new QtPrivate::QFunctorSlotObjectWithNoArgs<Func, decltype(function())>(std::move(function)), 924 type, 925 ret); 926 } +/ 927 928 /+ template <typename Func> +/ 929 /+ static typename std::enable_if<!QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction 930 && QtPrivate::FunctionPointer<Func>::ArgumentCount == -1 931 && !std::is_convertible<Func, const char*>::value, bool>::type 932 invokeMethod(QObject *context, Func function, decltype(function()) *ret) 933 { 934 return invokeMethodImpl(context, 935 new QtPrivate::QFunctorSlotObjectWithNoArgs<Func, decltype(function())>(std::move(function)), 936 Qt::AutoConnection, 937 ret); 938 } +/ 939 940 /+ #endif +/ 941 942 QObject newInstance(QGenericArgument val0 = QGenericArgument(null), 943 QGenericArgument val1 = QGenericArgument(), 944 QGenericArgument val2 = QGenericArgument(), 945 QGenericArgument val3 = QGenericArgument(), 946 QGenericArgument val4 = QGenericArgument(), 947 QGenericArgument val5 = QGenericArgument(), 948 QGenericArgument val6 = QGenericArgument(), 949 QGenericArgument val7 = QGenericArgument(), 950 QGenericArgument val8 = QGenericArgument(), 951 QGenericArgument val9 = QGenericArgument()) const; 952 953 enum Call { 954 InvokeMetaMethod, 955 ReadProperty, 956 WriteProperty, 957 ResetProperty, 958 QueryPropertyDesignable, 959 QueryPropertyScriptable, 960 QueryPropertyStored, 961 QueryPropertyEditable, 962 QueryPropertyUser, 963 CreateInstance, 964 IndexOfMethod, 965 RegisterPropertyMetaType, 966 RegisterMethodArgumentMetaType 967 } 968 969 int static_metacall(Call, int, void** ) const; 970 static int metacall(QObject , Call, int, void** ); 971 972 static const(QMetaObject*) staticMetaObject(alias MO)() 973 { 974 return &MO; 975 } 976 977 struct SuperData { 978 const(QMetaObject)* direct; 979 /+ SuperData() = default; +/ 980 /+ constexpr +/this(typeof(null)) 981 { 982 this.direct = null; 983 } 984 /+ constexpr +/this(const(QMetaObject)* mo) 985 { 986 this.direct = mo; 987 } 988 989 /+/+ constexpr +/ const(QMetaObject)* operator ->() const { return operator const QMetaObject *(); }+/ 990 991 version(QT_NO_DATA_RELOCATION) 992 { 993 alias Getter = ExternCPPFunc!(const(QMetaObject)* function()); 994 Getter indirect = null; 995 /+ constexpr +/this(Getter g) 996 { 997 this.direct = null; 998 this.indirect = g; 999 } 1000 /+/+ constexpr +/ auto opCast(T : const(QMetaObject))() const 1001 { return indirect ? cast(const(QMetaObject))(indirect()) : cast(const(QMetaObject))(direct); }+/ 1002 /+ template <const QMetaObject &MO> +/ /+ static constexpr SuperData link() 1003 { return SuperData(QMetaObject::staticMetaObject<MO>); } +/ 1004 } 1005 else 1006 { 1007 /+/+ constexpr +/ auto opCast(T : const(QMetaObject))() const 1008 { return cast(const(QMetaObject))(direct); }+/ 1009 static SuperData link(alias MO)() 1010 { return SuperData(QMetaObject.staticMetaObject!(MO)()); } 1011 } 1012 } 1013 1014 struct generated_qobjectdefs_0 { // private data 1015 SuperData superdata; 1016 const(void)* stringdata; 1017 const(uint)* data; 1018 alias StaticMetacallFunction = ExternCPPFunc!(void function(QObject , QMetaObject.Call, int, void** )); 1019 StaticMetacallFunction static_metacall; 1020 const(SuperData)* relatedMetaObjects; 1021 void* extradata; //reserved for future use 1022 }generated_qobjectdefs_0 d; 1023 1024 private: 1025 static bool invokeMethodImpl(QObject object, /+ QtPrivate:: +/qt.core.objectdefs_impl.QSlotObjectBase* slot, /+ Qt:: +/qt.core.namespace.ConnectionType type, void* ret); 1026 /+ friend class QTimer; +/ 1027 } 1028 1029 extern(C++, "QtPrivate") { 1030 /* Trait that tells is a the Object has a Q_OBJECT macro */ 1031 struct HasQ_OBJECT_Macro(Object) { 1032 /+ template <typename T> +/ 1033 /+ static char test(int (T::*)(QMetaObject::Call, int, void **)); +/ 1034 static int test(ExternCPPFunc!(int function(QMetaObject.Call, int, void** ))/+ Object::* +/ ); 1035 enum { Value = (test(&Object.qt_metacall)). sizeof == int.sizeof } 1036 } 1037 } 1038