# HG changeset patch # User Max Samukha # Date 1274359748 -10800 # Node ID 31520b2c0b3c74c8d88c66a7b41e99c461fef736 # Parent 925386e0e78069e45e60586900065e11b501328a Removed dependency on parent trait and stringof diff -r 925386e0e780 -r 31520b2c0b3c build/core.txt --- a/build/core.txt Mon May 17 21:48:15 2010 +0300 +++ b/build/core.txt Thu May 20 15:49:08 2010 +0300 @@ -31,13 +31,14 @@ Atomic Marshal MOC - Meta Array ArrayOpsPrimitive util/Tuple ctfe/Integer ctfe/String ctfe/Format + meta/Compiletime + meta/Runtime ) set (d_generated_files core/Qt QDefines) ## Classes. diff -r 925386e0e780 -r 31520b2c0b3c d2/qt/QGlobal.d --- a/d2/qt/QGlobal.d Mon May 17 21:48:15 2010 +0300 +++ b/d2/qt/QGlobal.d Thu May 20 15:49:08 2010 +0300 @@ -58,10 +58,12 @@ } } -string tr(string arg) { +string _tr(string arg) { return arg; } +alias _tr tr; + /* can be used like #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) */ diff -r 925386e0e780 -r 31520b2c0b3c d2/qt/core/QMetaObject.d --- a/d2/qt/core/QMetaObject.d Mon May 17 21:48:15 2010 +0300 +++ b/d2/qt/core/QMetaObject.d Thu May 20 15:49:08 2010 +0300 @@ -8,32 +8,18 @@ import std.string; import std.stdio; -class Meta -{ - string name; -} +import qtd.meta.Runtime; +import qtd.Marshal; -class MetaType : Meta +class QMetaArgument : Meta { - this() - { - } } -class MetaVariable : Meta +class QMetaMethod : Meta { - MetaType type; -} - -class MetaCallable : Meta { } + alias typeof(this) This; -class MetaMethod : Meta { } - -class QMetaArgument : MetaVariable { } - -class QMetaMethod : MetaMethod -{ -// QMetaArgument[] arguments; +// QMetaArgument[] arguments; string signature; int indexOfMethod; @@ -57,22 +43,43 @@ int openBracket = indexOf(signature, '('); return signature[0..openBracket]; } + + // mixin(Derived) or typeof(Derived) would help a lot here + static create(alias method, M : This)(uint index) + { + alias ParameterTypeTuple!method Args; + return new M(.signature!(Args)(methodName!(method)), index); + } } class QMetaSignal : QMetaMethod { + alias typeof(this) This; + this(string signature_, int indexOfMethod_) { super(signature_, indexOfMethod_); } + + static This create(alias method)(uint index) + { + return typeof(super).create!(method, This)(index); + } } class QMetaSlot : QMetaMethod { + alias typeof(this) This; + this(string signature_, int indexOfMethod_) { super(signature_, indexOfMethod_); } + + static This create(alias method)(uint index) + { + return typeof(super).create!(method, This)(index); + } } class MetaObject : MetaType @@ -92,6 +99,10 @@ final class QMetaObject { + alias typeof(this) This; + + private this() {} + enum Call { InvokeMetaMethod, @@ -117,38 +128,80 @@ QObject function(void* nativeId) _createWrapper; } - + private void addDerived(QMetaObject mo) { mo._next = _firstDerived; _firstDerived = mo; } - - // NOTE: construction is split between this non-templated constructor and 'construct' function below. - this(QMetaObjectNative* nativeId, QMetaObject base) + + // ctor + void construct(T : QObject)(void* nativeId) { - _nativeId = nativeId; + alias BaseClassesTuple!(T)[0] Base; + This base; + static if (is(Base : QObject)) + base = Base.staticMetaObject; + + _nativeId = cast(QMetaObjectNative*)nativeId; + T.setStaticMetaObject(this); + if (base) { base.addDerived(this); _base = base; } - } - - // TODO: remove when D acquires templated constructors - void construct(T : QObject, Concrete = T)() - { - _classInfo = T.classinfo; + _classInfo = T.classinfo; + + + static if (isQtType!T) + { + static if (is(T.ConcreteType)) + alias T.ConcreteType Concrete; + else + alias T Concrete; + + _createWrapper = function QObject(void* nativeId) { + auto obj = new Concrete(nativeId, cast(QtdObjectFlags)(QtdObjectFlags.nativeOwnership | QtdObjectFlags.dynamicEntity)); + T.__createEntity(nativeId, cast(void*)obj); + return obj; + }; + + T._populateMetaInfo; + } + // create run time meta-objects for user-defined signals and slots + else static if (is(typeof(T.methods))) + { + int index = Base.staticMetaObject().methodCount(); - _createWrapper = function QObject(void* nativeId) { - // COMPILER BUG: cast is should not be needed - auto obj = new Concrete(nativeId, cast(QtdObjectFlags)(QtdObjectFlags.nativeOwnership | QtdObjectFlags.dynamicEntity)); - // TODO: Probably this should be a virtual call from T's constructor - T.__createEntity(nativeId, cast(void*)obj); - return obj; - }; + static if (T.signals.length) + { + foreach (signal; T.signals) + { + addMethod(QMetaSignal.create!signal(index)); + index++; + } + } + + static if (T.slots.length) + { + foreach (slot; T.slots) + { + addMethod(QMetaSlot.create!slot(index)); + index++; + } + } + } } - + + // new + static This create(T : QObject)(void* nativeId) + { + auto m = new This(); + m.construct!T(nativeId); + return m; + } + /++ +/ QMetaObject base() @@ -247,7 +300,7 @@ QObject getObject(void* nativeObjId) { QObject result; - + if (nativeObjId) { result = cast(QObject)qtd_get_d_qobject(nativeObjId); @@ -261,7 +314,7 @@ // get native metaobjects for the entire derivation lattice // up to, but not including, the current metaobject. size_t moCount = 1; - + for (void* tmp = moId;;) { tmp = qtd_QMetaObject_superClass(tmp); @@ -270,13 +323,13 @@ break; moCount++; } - + void*[] moIds = (cast(void**)alloca(moCount * (void*).sizeof))[0..moCount]; moIds[--moCount] = moId; while (moCount > 0) moIds[--moCount] = moId = qtd_QMetaObject_superClass(moId); - + result = lookupDerived(moIds)._createWrapper(nativeObjId); } } @@ -306,12 +359,12 @@ { return qtd_QMetaObject_indexOfMethod(_nativeId, toStringz(method)); } - + int methodCount() { return qtd_QMetaObject_methodCount(_nativeId); } - + static void connectImpl(QObject sender, string signalString, QObject receiver, string methodString, int type) { QMetaSignal[] signals; @@ -324,7 +377,7 @@ else signals = sender.metaObject.lookUpSignalOverloads(signalString); // parameters not specified. Looking for a match - if(indexOf(methodString, '(') > 0) + if(indexOf(methodString, '(') > 0) method = receiver.metaObject.lookUpMethod(methodString); else methods = receiver.metaObject.lookUpMethodOverloads(methodString); // parameters not specified. Looking for a match @@ -358,8 +411,8 @@ method = meth; break; } - } - + } + bool success = false; if(!signal && !method) @@ -372,7 +425,7 @@ int methodIndex = method.indexOfMethod; success = QMetaObject.connect(sender, signalIndex, receiver, methodIndex, type); } - + if(!success) throw new QMetaException("QMetaObject: Signal " ~ signalString ~ " and slot " ~ methodString ~ " cannot be found"); } @@ -383,7 +436,7 @@ extern(C) bool qtd_QMetaObject_connect(const void* sender, int signal_index, const void* receiver, int method_index, int type, int *types); - + extern(C) int qtd_QMetaObject_indexOfMethod(void *nativeId, const(char) *method); extern(C) int qtd_QMetaObject_methodCount(void *nativeId); diff -r 925386e0e780 -r 31520b2c0b3c d2/qtd/Array.d --- a/d2/qtd/Array.d Mon May 17 21:48:15 2010 +0300 +++ b/d2/qtd/Array.d Thu May 20 15:49:08 2010 +0300 @@ -35,3 +35,20 @@ } } } + +/** + Allocates a dynamic array at compile time. + */ +T[] newArray(T)(size_t len, T[] from = []) +{ + if (len == from.length) + return from; + + if (!from.length) + from = [T.init]; + + if (from.length < len) + return newArray!T(len, from ~ from); + + return from[0..len]; +} \ No newline at end of file diff -r 925386e0e780 -r 31520b2c0b3c d2/qtd/Attribute.d --- a/d2/qtd/Attribute.d Mon May 17 21:48:15 2010 +0300 +++ b/d2/qtd/Attribute.d Thu May 20 15:49:08 2010 +0300 @@ -58,7 +58,7 @@ When mixed in an aggregate, converts a compile-time tuple of name-value pairs to members of that aggregate. */ -struct NameValueTupleToFields(A...) +mixin template NameValueTupleToFields(A...) { } @@ -192,10 +192,9 @@ mixin Attribute!(typeof(this), attrClass, opts | AttributeOptions.inner, A); } -// ditto +/// ditto mixin template InnerAttribute(string attrClass, A...) { - // BUG: needs to be generalized to accept any parent mixin InnerAttribute!(attrClass, AttributeOptions.none, A); } @@ -335,7 +334,7 @@ auto attr = cast(MetaVariantAttribute) meta!(C).attributes[0]; assert(attr.name == "someAttribute"); - assert(qttr.length == 2); + assert(attr.length == 2); assert(attr.values[0] == "22"); assert(attr.values[1] == 33); } diff -r 925386e0e780 -r 31520b2c0b3c d2/qtd/MOC.d --- a/d2/qtd/MOC.d Mon May 17 21:48:15 2010 +0300 +++ b/d2/qtd/MOC.d Thu May 20 15:49:08 2010 +0300 @@ -1,38 +1,23 @@ module qtd.MOC; -import std.typetuple; +import + std.typetuple, + std.traits, + std.typetuple, + std.conv, + qt.QGlobal, + qtd.Signal, + qtd.Marshal, + qtd.Array, + qtd.Str, + qtd.meta.Compiletime, + qtd.ctfe.Format; -import qt.QGlobal; -import qtd.Signal; -import qtd.Marshal; -import qtd.Meta; -import qtd.ctfe.Format; +import qt.core.QString; -public import qt.core.QString; - -public import std.traits; /** Utils. - */ - -bool is_digit_char(const char s) -{ - return (s >= '0' && s <= '9'); -} - -bool is_octal_char(const char s) -{ - return (s >= '0' && s <= '7'); -} - -bool is_hex_char(const char s) -{ - return ((s >= 'a' && s <= 'f') - || (s >= 'A' && s <= 'F') - || (s >= '0' && s <= '9') - ); -} - + */ int lastIndexOf(T)(T[] haystack, T[] needle, int from = -1) { auto l = haystack.length; @@ -44,7 +29,7 @@ return -1; if (from > delta) from = delta; - + while(from >= 0) { if (haystack[from..from+ol] == needle) @@ -54,21 +39,6 @@ return -1; } - -T[] newArray(T)(size_t len, T[] from = []) -{ - if (len == from.length) - return from; - - if (!from.length) - from = [T.init]; - - if (from.length < len) - return newArray!T(len, from ~ from); - - return from[0..len]; -} - string replicate(int n, char value) { char[] ret = "".dup; @@ -113,7 +83,7 @@ // string name; string sig; string arguments; - Access access; + Access access; /* bool returnTypeIsVolatile; QList arguments; @@ -163,12 +133,12 @@ auto ch = s[i]; if (ch == 'x') { ++i; - while (i < s.length && is_hex_char(s[i])) + while (i < s.length && isHexChar(s[i])) ++i; - } else if (is_octal_char(ch)) { + } else if (isOctalChar(ch)) { while (i < startPos + 4 && i < s.length - && is_octal_char(s[i])) { + && isOctalChar(s[i])) { ++i; } } else { // single character escape sequence @@ -253,10 +223,10 @@ qualifiedClassNameIdentifier.replace(':', '_'); */ bool isConstructible = false; - + FunctionDef[] propertyList, enumList, constructorList; int index = 12; - gen.output ~= format_ctfe("static const uint[] qt_meta_data_${} = [\n", className); + gen.output ~= "private static const uint[] qt_meta_data = [\n"; gen.output ~= format_ctfe("\n // content:\n"); gen.output ~= format_ctfe(" ${}, // revision\n", 2); gen.output ~= format_ctfe(" ${}, // classname\n", strreg(gen, className)); @@ -323,7 +293,7 @@ // // Build stringdata array // - gen.output ~= format_ctfe("static const string qt_meta_stringdata_${} = \n", className); + gen.output ~= "private static const string qt_meta_stringdata = \n"; gen.output ~= format_ctfe(" \""); int col = 0; int len = 0; @@ -358,21 +328,10 @@ col += len + 2; } gen.output ~= "\";\n\n"; - + return gen.output; } -string metaCallArgs(Args...)() -{ - string res; - foreach(i, _; Args) { - if (i > 0) - res ~= ","; - res ~= metaCallArgument!(Args[i])("_a[" ~ __toString(i+1) ~ "]"); - } - return res; -} - string qtDeclArgs(Args...)() { string ret; @@ -385,36 +344,6 @@ return ret; } -string generate_qt_metacall(alias Signals, alias Slots)() -{ - string res = " -protected int qt_metacall(QMetaObject.Call _c, int _id, void **_a) - { - _id = super.qt_metacall(_c, _id, _a); - if (_id < 0) - return _id;\n"; - - alias TypeTuple!(Signals.at, Slots.at) Methods; - enum methodCount = Methods.length; - if(methodCount) - { - res ~= " - if (_c == QMetaObject.Call.InvokeMetaMethod) { - switch (_id) {"; - foreach(i, _; Repeat!(void, methodCount)) { - res ~= " - case " ~ __toString(i) ~ ": " ~ MetaEntryName!(Methods[i].at) ~ "(" ~ metaCallArgs!(MetaEntryArgs!(Methods[i].at))() ~ "); break;"; - } - res ~= "\n default: ;\n }\n"; - res ~= " _id -= " ~ __toString(methodCount) ~ ";"; - res ~= "\n }"; - } - - res ~= "\n return _id; - }"; - return res; -} - string dDeclArgs(Args...)() { string ret; @@ -422,65 +351,10 @@ { if (i > 0) ret ~= ", "; - ret ~= fullDName!(Args[i]); + ret ~= fullName!(Args[i]); } return ret; } -string genMetaMethodsConstr(alias Funcs)(string className) -{ - string res; - enum funcsCount = Funcs.at.length; - foreach(i, bogus; Repeat!(void, funcsCount)) - { - res ~= " index++;\n" ~ - " _staticMetaObject.addMethod(new " ~ className ~ "(signature!(" ~ dDeclArgs!(MetaEntryArgs!(Funcs.at[i].at))()~ ")(\"" ~ MetaEntryName!(Funcs.at[i].at) ~ "\"), index));\n\n"; - } - return res; -} -string generateMetaObjectConstruction(alias Signals, alias Slots)() -{ - string res; - res ~= "\n - private static void _populateMetaInfo() { - alias BaseClassesTuple!(typeof(this))[0] BaseClass; - int index = BaseClass.staticMetaObject().methodCount() - 1;\n\n"; - - res ~= genMetaMethodsConstr!(Signals)("QMetaSignal"); - res ~= genMetaMethodsConstr!(Slots)("QMetaSlot"); - - res ~= " - }\n"; - return res; -} - -string generateQMetaObject(string className) -{ - string res; - res ~= " - public QMetaObject metaObject() { return staticMetaObject(); } - private static __gshared QMetaObject _staticMetaObject; - private static __gshared QMetaObjectNative _nativeStaticMetaObject; - public static QMetaObject staticMetaObject() - { - if(!_staticMetaObject) - createStaticMetaObject(); - return _staticMetaObject; - } - protected static void createStaticMetaObject() { - assert(!_staticMetaObject); - alias BaseClassesTuple!(typeof(this))[0] BaseClass; - if (!BaseClass._staticMetaObject) - BaseClass.createStaticMetaObject; - auto base = BaseClass._staticMetaObject; - _nativeStaticMetaObject = QMetaObjectNative(base.nativeId, qt_meta_stringdata_" ~ className ~ ".ptr, - qt_meta_data_" ~ className ~ ".ptr, null ); - - _staticMetaObject = new QMetaObject(&_nativeStaticMetaObject, base); -// _staticMetaObject.construct!(typeof(this)); - _populateMetaInfo(); - }\n\n"; - return res; -} size_t commaCount(int argCount) { @@ -490,14 +364,15 @@ return ret; } -FunctionDef[] genFuncDefs(alias Funcs, alias newFunc)() +FunctionDef[] generateFuncDefs(alias newFunc, Funcs...)() { typeof(return) res; - enum funcsCount = Funcs.at.length; + enum funcsCount = Funcs.length; foreach(i, bogus; Repeat!(void, funcsCount)) { - string args = replicate(commaCount((MetaEntryArgs!(Funcs.at[i].at)).length), ','); - string funcSig = MetaEntryName!(Funcs.at[i].at) ~ "(" ~ qtDeclArgs!(MetaEntryArgs!(Funcs.at[i].at))() ~ ")"; + alias ParameterTypeTuple!(Funcs[i]) Args; + string args = replicate(commaCount(Args.length), ','); + string funcSig = methodName!(Funcs[i]) ~ "(" ~ qtDeclArgs!(Args)() ~ ")"; res ~= newFunc(funcSig, args); } return res; @@ -509,52 +384,136 @@ // ------------------------------------------------------------------------------------------ -string generateSignalEmitters(alias Funcs)() +string generateSignalEmitters(uint signalCount) { - string res; - enum funcsCount = Funcs.at.length; - foreach(i, bogus; Repeat!(void, funcsCount)) + string res = ""; + foreach (i; 0..signalCount) { - res ~= SignalEmitter!(MetaEntryArgs!(Funcs.at[i].at))(SignalType.NewSignal, MetaEntryName!(Funcs.at[i].at), cast(string[])[], i); + auto iStr = to!string(i); + res ~= "mixin SignalEmitter!(SignalKind.NewSignal, " ~ iStr ~ ");\n"; } return res; } -string generateSlotAliases(alias Funcs)() +private mixin template SlotAlias(alias slot) { - string res; - enum funcsCount = Funcs.at.length; - foreach(i, bogus; Repeat!(void, funcsCount)) + mixin ("alias slot " ~ methodName!slot ~ ";"); +} + +string generateSlotAliases(uint slotCount) +{ + string res = ""; + foreach(i; 0..slotCount) { - string name = MetaEntryName!(Funcs.at[i].at); - res ~= format_ctfe(" alias slot_${} ${};\n", name, name); + auto iStr = to!string(i); + res ~= "mixin SlotAlias!(slots[" ~ iStr ~ "]);\n"; } return res; } - -string generateMetaInfo(T, alias Signals, alias Slots)() +string generateMetaCall(string methodName, size_t argCount) { string res = ""; - auto signalList = genFuncDefs!(Signals, newSignal)(); - auto slotList = genFuncDefs!(Slots, newSlot)(); - res ~= generateSignalEmitters!(Signals)(); - res ~= generateSlotAliases!(Slots)(); - res ~= generateCode(T.stringof, signalList, slotList); - res ~= generate_qt_metacall!(Signals, Slots); - res ~= generateMetaObjectConstruction!(Signals, Slots); - res ~= generateQMetaObject(T.stringof); - return res; + foreach (i; 1..argCount) + res ~= generateConvToD(i); + + res ~= methodName ~ "("; + foreach (i; 1..argCount) + { + if (i > 1) + res ~= ", "; + res ~= "_out" ~ to!string(i); + } + return res ~ ");\n"; +} + +string generateDispatchSwitch(size_t methodCount) +{ + string res = "switch(_id) {\n"; + + foreach(i; 0..methodCount) + { + string iStr = to!string(i); + res ~= " case " ~ iStr ~ ":\n"; + res ~= " alias methods[" ~ iStr ~ "] method;\n"; + res ~= " alias TypeTuple!(void, ParameterTypeTuple!method) Args;\n"; + res ~= " mixin(generateMetaCall(methodName!method, Args.length));\n"; + res ~= " break;\n"; + } + + res ~= " default:\n"; + + return res ~ "}\n"; } -template Q_OBJECT() +mixin template Q_OBJECT() { - alias findSignals!(typeof(this)) SignalFuncs; - alias toMetaEntries!(SignalFuncs) SignalMetaEntries; - alias findSlots!(typeof(this)) SlotFuncs; - alias toMetaEntries!(SlotFuncs) SlotMetaEntries; + import std.typetuple; + import qtd.Marshal; + import qt.core.QString; // for QStringUtil.toNative + +public: // required to override the outside scope protection. + + alias typeof(this) This; + + alias findSignals!(This) signals; + alias findSlots!(This) slots; + alias TypeTuple!(signals, slots) methods; + + + mixin (generateSignalEmitters(signals.length)); + mixin (generateSlotAliases(slots.length)); + + auto signalList = generateFuncDefs!(newSignal, signals)(); + auto slotList = generateFuncDefs!(newSlot, slots)(); + mixin (generateCode(typeof(this).stringof, signalList, slotList)); + + protected int qt_metacall(QMetaObject.Call _c, int _id, void **_a) + { + _id = super.qt_metacall(_c, _id, _a); + + static if (methods.length) + { + if (_id < 0) + return _id; - mixin(generateMetaInfo!(typeof(this), SignalMetaEntries, SlotMetaEntries)()); - // debug output -// pragma(msg, generateMetaInfo!(typeof(this), SignalMetaEntries, SlotMetaEntries)()); + if (_c == QMetaObject.Call.InvokeMetaMethod) { + //pragma(msg, generateDispatchSwitch(methods.length)); + mixin (generateDispatchSwitch(methods.length)); + } + _id -= methods.length; + } + + return _id; + } + + @property + override QMetaObject metaObject() const { return staticMetaObject(); } + + private static __gshared QMetaObject _staticMetaObject; + private static __gshared QMetaObjectNative _nativeStaticMetaObject; + + @property + static QMetaObject staticMetaObject() + { + // TODO: synchronize or enable static constructors in circular modules + if(!_staticMetaObject) + { + alias BaseClassesTuple!(This)[0] Base; + + _nativeStaticMetaObject = QMetaObjectNative( + Base.staticMetaObject.nativeId, + qt_meta_stringdata.ptr, + qt_meta_data.ptr, null); + + QMetaObject.create!This(&_nativeStaticMetaObject); + } + return _staticMetaObject; + } + + /*internal*/ static void setStaticMetaObject(QMetaObject m) + { + _staticMetaObject = m; + } } + diff -r 925386e0e780 -r 31520b2c0b3c d2/qtd/Marshal.d --- a/d2/qtd/Marshal.d Mon May 17 21:48:15 2010 +0300 +++ b/d2/qtd/Marshal.d Thu May 20 15:49:08 2010 +0300 @@ -1,20 +1,24 @@ module qtd.Marshal; -import std.traits; +import + std.traits, + qtd.meta.Compiletime, + qtd.ctfe.Format; -import qtd.Meta; +import std.string : startsWith; -template isQObjectType(T) // is a QObject type that belongs to the library + +template isQObjectType(T) { enum isQObjectType = is(T.__isQObjectType); } -template isObjectType(T) // is a Qt Object type that belongs to the library +template isObjectType(T) { enum isObjectType = is(T.__isObjectType); } -template isValueType(T) // is a Qt Value type that belongs to the library +template isValueType(T) { enum isValueType = is(T.__isValueType); } @@ -41,7 +45,7 @@ template isQList(T) { - enum isQList = ctfeStartsWith(Unqual!(T).stringof, "QList!"); + enum isQList = startsWith(Unqual!(T).stringof, "QList!"); } // returns full name of enum: @@ -58,26 +62,8 @@ } else enum enumFullName = qualifiedDName!T; - } -// converts an argumnent from C++ to D in qt_metacall -string metaCallArgument(T)(string ptr) -{ - static if (isQObjectType!T || isObjectType!T) - return T.stringof ~ ".__getObject(*cast(void**)(" ~ ptr ~ "))"; - else static if (isValueType!T) - return "new " ~ T.stringof ~ "(" ~ T.stringof ~ ".__constructNativeCopy(" ~ ptr ~ "))"; - else static if (isNativeType!T) - return "*(cast(" ~ T.stringof ~ "*)" ~ ptr ~ ")"; - else static if (isStringType!T) - return "QStringUtil.toNativeString(" ~ ptr ~ ")"; - else static if (is(T == enum)) - return "*(cast(" ~ qualifiedDName!T ~ "*)" ~ ptr ~ ")"; - else - return "*(cast(" ~ T.stringof ~ "*)" ~ ptr ~ ")"; - //res = T.stringof; -} // converts a D argument type to C++ for registering in Qt meta system string qtDeclArg(T)() @@ -104,26 +90,31 @@ return T.stringof; } -// converts an argument from D to C++ in a signal emitter -string convertSignalArgument(T)(string arg) +/** + Generates C++-to-D conversion code for the + argument argIndex. + */ +string generateConvToD(uint argIndex) { - static if (isQObjectType!T || isObjectType!T) - return arg ~ " ? " "&" ~ arg ~ ".__nativeId : cast(void**) &" ~ arg; // since it is a pointer type check arg for null - else static if (isValueType!T) - return arg ~ ".__nativeId"; - else static if (isStringType!T) - return "&_qt" ~ arg; - else static if (isNativeType!T) - return "&" ~ arg; - else - return "&" ~ arg; + string res = format_ctfe(q{ + + static if (isQObjectType!(Args[${0}]) || isObjectType!(Args[${0}])) + auto _out${0} = Args[${0}].__getObject(*cast(void**)_a[${0}]); + else static if (isValueType!(Args[${0}])) + { + // COMPILER BUG: 'new' chokes on Args[argIndex], hence the alias + alias Args[${0}] Args${0}; + auto _out${0} = new Args${0}(Args[${0}].__constructNativeCopy(_a[${0}])); + } + else static if (isStringType!(Args[${0}])) + auto _out${0} = QStringUtil.toNativeString(_a[${0}]); + else + { + auto _out${0} = *cast(Args[${0}]*)_a[${0}]; + } + + }, argIndex); + + return res; } -string prepareSignalArguments(Args...)() -{ - string res; - foreach(i, _; Args) - static if (isStringType!(Args[i])) - res ~= "auto _qt_t" ~ __toString(i) ~ " = QString(_t" ~ __toString(i) ~ ");\n"; - return res; -} diff -r 925386e0e780 -r 31520b2c0b3c d2/qtd/Signal.d --- a/d2/qtd/Signal.d Mon May 17 21:48:15 2010 +0300 +++ b/d2/qtd/Signal.d Thu May 20 15:49:08 2010 +0300 @@ -11,29 +11,28 @@ */ module qtd.Signal; -public import qt.QGlobal; -import qtd.Marshal; -import qtd.Meta; - import core.stdc.stdlib : crealloc = realloc, cfree = free; import core.stdc.string : memmove; + import core.thread, core.exception, - std.algorithm; -public import + std.algorithm, std.typetuple, + std.conv, std.traits, - std.conv, - std.metastrings; + std.string, -public import std.string : strip, toStringz; - + qt.QGlobal, + qtd.Marshal, + qtd.meta.Compiletime, + qtd.ctfe.Format; + /** The beast that takes string representation of function arguments * and returns an array of default values it doesn't check if arguments * without default values follow the arguments with default values for - * simplicity. It is done by mixing in an delegate alias. + * simplicity. It is done by mixing in a delegate alias. */ string[] defaultValues(string signature) { @@ -42,7 +41,7 @@ bool inStringLiteral = false; string[] res; int startValue = 0; - + if(strip(signature).length == 0) return res; @@ -68,7 +67,7 @@ inStringLiteral = true; } } - + if (!inStringLiteral && braces == 0) { if(c == '=') // found default value @@ -86,100 +85,97 @@ } } } - + if (inDefaultValue) res ~= signature[startValue..$]; return res; } -int defaultValuesLength(string[] defVals) -{ - return defVals.length; -} - - -// templates for extracting data from static meta-information of signals, slots or properties -// public alias TypeTuple!("name", index, OwnerClass, ArgTypes) __signal -template MetaEntryName(source...) -{ - enum MetaEntryName = source[0]; // name of the metaentry is the first element -} - -template MetaEntryOwner(source...) +/** + Generates D-to-C++ conversion code for signals. + */ +string genConvToCpp(uint argIndex) { - alias TupleWrapper!(source[2]).at[0] MetaEntryOwner; // class that owns the property is the third - // Compiler #BUG 3092 - evaluates MetaEntryOwner as a Tuple with one element -} - -template MetaEntryArgs(source...) -{ - alias ParameterTypeTuple!(source[1]) MetaEntryArgs; // arguments-tuple starts from the fourth position -} - -template TupleWrapper(A...) { alias A at; } + string res = format_ctfe(q{ -string convertSignalArguments(Args...)() -{ -// void *_a[] = { 0, const_cast(reinterpret_cast(&_t1)) }; - // at least for string argument need to construct a QString value - string res = prepareSignalArguments!(Args); - - res ~= "void*[" ~ __toString(Args.length+1) ~ "] _a = [null"; - foreach(i, _; Args) - res ~= ", " ~ "cast(void*) (" ~ convertSignalArgument!(Args[i])("_t" ~ __toString(i)) ~ ")"; - res ~= "];\n"; + static if (isStringType!(Args[${0}])) + { + auto _tmp${0} = QString(_t${0}); + _a[${0}] = cast(void*)&_tmp${0}; + } + else static if (isQObjectType!(Args[${0}]) || isObjectType!(Args[${0}])) + _a[${0}] = _t${0} ? &(_t${0}.__nativeId) : cast(void*)&_t${0}; + else static if (isValueType!(Args[${0}])) + _a[${0}] = _t${0}.__nativeId; + else + _a[${0}] = cast(void*)&_t${0}; + + }, argIndex); + return res; } -public string SignalEmitter(A...)(SignalType signalType, string name, string[] defVals, int localIndex) +string genSignalEmitter(SignalKind signalKind, string name, uint localIndex, uint argCount) { - string fullArgs, args; - int defValsLength = defVals.length; - string argsConversion = ""; - string argsPtr = "null"; - static if (A.length) + string res; + + // signature + // + if (signalKind != SignalKind.BindQtSignal) + res ~= "protected "; + + res ~= "Args[0] " ~ name; + + if (signalKind == SignalKind.BindQtSignal) + res ~= "_emit"; + + res ~= "("; + + foreach (i; 1..argCount) { - while(A.length != defVals.length) - defVals = "" ~ defVals; - - fullArgs = A[0].stringof ~ " _t0"; - if (defVals[0].length) - fullArgs ~= " = " ~ defVals[0]; - args = "_t0"; - foreach(i, _; A[1..$]) - { - fullArgs ~= ", " ~ A[i+1].stringof ~ " _t" ~ __toString(i+1); - if (defVals[i+1].length) - fullArgs ~= " = " ~ defVals[i+1]; - args ~= ", _t" ~ __toString(i+1); - } - // build up conversion of signal args from D to C++ - argsPtr = "_a.ptr"; - argsConversion = convertSignalArguments!(A)(); + auto iStr = to!string(i); + if (i > 1) + res ~= ", "; + res ~= "Args[" ~ iStr ~ "] _t" ~ iStr; } - string attribute; - string sigName = name; - if (signalType == SignalType.BindQtSignal) - name ~= "_emit"; - else - attribute = "protected "; - - string indexArgs = __toString(localIndex); - if(defValsLength > 0) - indexArgs ~= ", " ~ __toString(localIndex+defValsLength); - string str = attribute ~ "final void " ~ name ~ "(" ~ fullArgs ~ ") {\n" ~ argsConversion ~ "\n" - ~ " QMetaObject.activate(this, typeof(this).staticMetaObject, " ~ indexArgs ~ ", " ~ argsPtr ~ ");\n" - ~ "}\n"; // ~ - return str; + + res ~= ") {\n"; + + // body + // + res ~= " void*[" ~ to!string(argCount) ~ "] _a;\n"; + foreach (i; 1..argCount) + res ~= genConvToCpp(i); + + res ~= " QMetaObject.activate(this, typeof(this).staticMetaObject, " + ~ to!string(localIndex) ~ ", _a.ptr);\n"; + + return res ~= "}\n"; +} + +// BUG: parameter storage classes are not supported yet +mixin template SignalEmitter(SignalKind signalKind, int localIndex) +{ + alias signals[localIndex] signal; + alias TypeTuple!(ReturnType!(signal), ParameterTypeTuple!(signal)) Args; + + /+ + pragma(msg, genSignalEmitter(signalKind, + methodName!signal, + localIndex, + Args.length)); + +/ + + mixin (genSignalEmitter(signalKind, + methodName!signal, + localIndex, + Args.length)); } /** ---------------- */ -const string signalPrefix = "__signal"; -const string slotPrefix = "__slot"; - -enum SignalType +enum SignalKind { BindQtSignal, NewSignal, @@ -209,32 +205,31 @@ string[] result; auto allSymbols = __traits(derivedMembers, C); foreach(s; allSymbols) - if(ctfeStartsWith(s, prefix)) + { + if(startsWith(s, prefix)) result ~= s; + } return result; } string removePrefix(string source) { foreach (i, c; source) + { if (c == '_') return source[i+1..$]; + } return source; } -template Alias(T...) -{ - alias T Alias; -} - // recursive search in the static meta-information template findSymbolsImpl2(C, alias signals, int id) { - alias Alias!(__traits(getOverloads, C, signals[id])) current; + alias qtd.meta.Compiletime.Alias!(__traits(getOverloads, C, signals[id])) current; static if (signals.length - id - 1 > 0) alias TypeTuple!(current, findSymbolsImpl2!(C, signals, id + 1).result) result; else - alias current result; + alias TypeTuple!(current) result; } template findSymbols2(C, string prefix) @@ -256,41 +251,7 @@ alias findSymbols2!(C, "slot_").result findSlots; } -/* commented out for future when we will implement default arguments -template metaMethods(alias func, int index, int defValsCount) -{ - static if(defValsCount >= 0) { - alias TupleWrapper!(func, index) current; -// pragma(msg, __traits(identifier, (current.at)[0]) ~ " " ~ typeof(&(current.at)[0]).stringof); - alias metaMethods!(func, index+1, defValsCount-1).result next; - alias TypeTuple!(current, next) result; - } - else - { - alias TypeTuple!() result; - } -} -*/ - -template toMetaEntriesImpl(int id, Methods...) +template methodName(alias method) { - static if (Methods.length > id) - { - alias typeof(&Methods[id]) Fn; -// commented out for future when we will implement default arguments -// enum defValsLength = 0; //ParameterTypeTuple!(Fn).length - requiredArgCount!(Methods[id])(); -// pragma(msg, __traits(identifier, Methods[id]) ~ " " ~ typeof(&Methods[id]).stringof); -// alias metaMethods!(Methods[id], 0, defValsLength).result subres; - alias TupleWrapper!(removePrefix(__traits(identifier, Methods[id])), typeof(&Methods[id])) subres; - alias TypeTuple!(subres, toMetaEntriesImpl!(id+1, Methods).result) result; - } - else - { - alias TypeTuple!() result; - } -} - -template toMetaEntries(Methods...) -{ - alias TupleWrapper!(toMetaEntriesImpl!(0, Methods).result) toMetaEntries; -} + enum methodName = removePrefix(__traits(identifier, method)); +} \ No newline at end of file diff -r 925386e0e780 -r 31520b2c0b3c d2/qtd/Str.d --- a/d2/qtd/Str.d Mon May 17 21:48:15 2010 +0300 +++ b/d2/qtd/Str.d Thu May 20 15:49:08 2010 +0300 @@ -11,19 +11,15 @@ module qtd.Str; +import core.stdc.string; import std.utf : toUTF8; -version(D_Version2) { -// private import core.sys.posix.stdio; - private import core.stdc.string; - - version = druntime; -} - alias immutable(char)* stringz; alias const(char)* cstringz; -public static char** toStringzArray(string[] args) +/** + */ +static char** toStringzArray(string[] args) { if ( args is null ) { @@ -40,12 +36,37 @@ return argv; } -public string fromStringz(const (char) *s) +/** + */ +bool isDigit(char s) +{ + return (s >= '0' && s <= '9'); +} + +/** + */ +bool isOctalChar(char s) +{ + return (s >= '0' && s <= '7'); +} + +/** + */ +bool isHexChar(char s) +{ + return ((s >= 'a' && s <= 'f') + || (s >= 'A' && s <= 'F') + || (s >= '0' && s <= '9') + ); +} + +/** + */ +string fromStringz(const (char) *s) { return s ? s[0 .. strlen(s)].idup : cast(string)null; } - extern(C) void qtd_toUtf8(wchar* arr, uint size, string* str) { *str = toUTF8(arr[0..size]); diff -r 925386e0e780 -r 31520b2c0b3c examples/desktop/systray/main.d --- a/examples/desktop/systray/main.d Mon May 17 21:48:15 2010 +0300 +++ b/examples/desktop/systray/main.d Thu May 20 15:49:08 2010 +0300 @@ -40,6 +40,7 @@ ****************************************************************************/ module main; +import std.stdio; // BUG: needed to workaround std.stdio initialization failure import qt.gui.QMessageBox; import qt.gui.QApplication; @@ -50,15 +51,15 @@ int main(string[] args) { - auto app = new QApplication(args); + auto app = new QApplication(args); - if (!QSystemTrayIcon.isSystemTrayAvailable()) { - QMessageBox.critical(null, tr("Systray"), tr("I couldn't detect any system tray on this system.")); - return 1; - } - QApplication.setQuitOnLastWindowClosed(false); + if (!QSystemTrayIcon.isSystemTrayAvailable()) { + QMessageBox.critical(null, tr("Systray"), tr("I couldn't detect any system tray on this system.")); + return 1; + } + QApplication.setQuitOnLastWindowClosed(false); - auto window = new Window; - window.show(); - return app.exec(); + auto window = new Window; + window.show(); + return app.exec(); } diff -r 925386e0e780 -r 31520b2c0b3c examples/desktop/systray/window.d --- a/examples/desktop/systray/window.d Mon May 17 21:48:15 2010 +0300 +++ b/examples/desktop/systray/window.d Thu May 20 15:49:08 2010 +0300 @@ -62,226 +62,226 @@ { public: - this() - { - createIconGroupBox(); - createMessageGroupBox(); + this() + { + createIconGroupBox(); + createMessageGroupBox(); - iconLabel.setMinimumWidth(durationLabel.sizeHint().width()); + iconLabel.setMinimumWidth(durationLabel.sizeHint().width()); - createActions(); - createTrayIcon(); + createActions(); + createTrayIcon(); - connect(showMessageButton, "clicked", this, "showMessage"); - connect(showIconCheckBox, "toggled", trayIcon, "setVisible"); - connect(iconComboBox, "currentIndexChanged", this, "setIcon"); - connect(trayIcon, "messageClicked", this, "messageClicked"); - connect(trayIcon, "activated", this, "iconActivated"); + connect(showMessageButton, "clicked", this, "showMessage"); + connect(showIconCheckBox, "toggled", trayIcon, "setVisible"); + connect(iconComboBox, "currentIndexChanged", this, "setIcon"); + connect(trayIcon, "messageClicked", this, "messageClicked"); + connect(trayIcon, "activated", this, "iconActivated"); - QVBoxLayout mainLayout = new QVBoxLayout; - mainLayout.addWidget(iconGroupBox); - mainLayout.addWidget(messageGroupBox); - setLayout(mainLayout); + QVBoxLayout mainLayout = new QVBoxLayout; + mainLayout.addWidget(iconGroupBox); + mainLayout.addWidget(messageGroupBox); + setLayout(mainLayout); - iconComboBox.setCurrentIndex(1); - trayIcon.show(); + iconComboBox.setCurrentIndex(1); + trayIcon.show(); - setWindowTitle(tr("Systray")); - resize(400, 300); - } + setWindowTitle(tr("Systray")); + resize(400, 300); + } - void setVisible(bool visible) - { - minimizeAction.setEnabled(visible); - maximizeAction.setEnabled(!isMaximized()); - restoreAction.setEnabled(isMaximized() || !visible); - QDialog.setVisible(visible); - } + void setVisible(bool visible) + { + minimizeAction.setEnabled(visible); + maximizeAction.setEnabled(!isMaximized()); + restoreAction.setEnabled(isMaximized() || !visible); + QDialog.setVisible(visible); + } - protected: + protected: - void closeEvent(QCloseEvent event) - { - if (trayIcon.isVisible()) { - QMessageBox.information(this, tr("Systray"), - tr("The program will keep running in the system tray. To terminate the program, " - "choose Quit in the context menu of the system tray entry.")); - hide(); - event.ignore(); - } - } + void closeEvent(QCloseEvent event) + { + if (trayIcon.isVisible()) { + QMessageBox.information(this, tr("Systray"), + tr("The program will keep running in the system tray. To terminate the program, " + "choose Quit in the context menu of the system tray entry.")); + hide(); + event.ignore(); + } + } private: // slots - void slot_setIcon(int index) - { - QIcon icon = iconComboBox.itemIcon(index); - trayIcon.setIcon(icon); - setWindowIcon(icon); + void slot_setIcon(int index) + { + QIcon icon = iconComboBox.itemIcon(index); + trayIcon.setIcon(icon); + setWindowIcon(icon); - trayIcon.setToolTip(iconComboBox.itemText(index)); - } - - void slot_iconActivated(QSystemTrayIcon.ActivationReason reason) - { - switch (reason) { - case QSystemTrayIcon.Trigger: - case QSystemTrayIcon.DoubleClick: - iconComboBox.setCurrentIndex((iconComboBox.currentIndex() + 1) % iconComboBox.count()); - break; - case QSystemTrayIcon.MiddleClick: - showMessage(); - break; - default: - } - } - - void slot_showMessage() - { - QSystemTrayIcon.MessageIcon icon = cast(QSystemTrayIcon.MessageIcon) - typeComboBox.itemData(typeComboBox.currentIndex()).toInt(); - trayIcon.showMessage(titleEdit.text(), bodyEdit.toPlainText(), icon, durationSpinBox.value() * 1000); - } - - void slot_messageClicked() - { - QMessageBox.information(null, tr("Systray"), - tr("Sorry, I already gave what help I could.\nMaybe you should try asking a human?")); - } + trayIcon.setToolTip(iconComboBox.itemText(index)); + } + + void slot_iconActivated(QSystemTrayIcon.ActivationReason reason) + { + switch (reason) { + case QSystemTrayIcon.Trigger: + case QSystemTrayIcon.DoubleClick: + iconComboBox.setCurrentIndex((iconComboBox.currentIndex() + 1) % iconComboBox.count()); + break; + case QSystemTrayIcon.MiddleClick: + showMessage(); + break; + default: + } + } + + void slot_showMessage() + { + QSystemTrayIcon.MessageIcon icon = cast(QSystemTrayIcon.MessageIcon) + typeComboBox.itemData(typeComboBox.currentIndex()).toInt(); + trayIcon.showMessage(titleEdit.text(), bodyEdit.toPlainText(), icon, durationSpinBox.value() * 1000); + } + + void slot_messageClicked() + { + QMessageBox.information(null, tr("Systray"), + tr("Sorry, I already gave what help I could.\nMaybe you should try asking a human?")); + } private: - void createIconGroupBox() - { - iconGroupBox = new QGroupBox(tr("Tray Icon")); + void createIconGroupBox() + { + iconGroupBox = new QGroupBox(tr("Tray Icon")); - iconLabel = new QLabel("Icon:"); + iconLabel = new QLabel("Icon:"); - iconComboBox = new QComboBox; - iconComboBox.addItem(new QIcon(":/images/bad.svg"), tr("Bad")); - iconComboBox.addItem(new QIcon(":/images/heart.svg"), tr("Heart")); - iconComboBox.addItem(new QIcon(":/images/trash.svg"), tr("Trash")); + iconComboBox = new QComboBox; + iconComboBox.addItem(new QIcon(":/images/bad.svg"), tr("Bad")); + iconComboBox.addItem(new QIcon(":/images/heart.svg"), tr("Heart")); + iconComboBox.addItem(new QIcon(":/images/trash.svg"), tr("Trash")); - showIconCheckBox = new QCheckBox(tr("Show icon")); - showIconCheckBox.setChecked(true); + showIconCheckBox = new QCheckBox(tr("Show icon")); + showIconCheckBox.setChecked(true); - QHBoxLayout iconLayout = new QHBoxLayout; - iconLayout.addWidget(iconLabel); - iconLayout.addWidget(iconComboBox); - iconLayout.addStretch(); - iconLayout.addWidget(showIconCheckBox); - iconGroupBox.setLayout(iconLayout); - } + QHBoxLayout iconLayout = new QHBoxLayout; + iconLayout.addWidget(iconLabel); + iconLayout.addWidget(iconComboBox); + iconLayout.addStretch(); + iconLayout.addWidget(showIconCheckBox); + iconGroupBox.setLayout(iconLayout); + } - void createMessageGroupBox() - { - messageGroupBox = new QGroupBox(tr("Balloon Message")); + void createMessageGroupBox() + { + messageGroupBox = new QGroupBox(tr("Balloon Message")); - typeLabel = new QLabel(tr("Type:")); + typeLabel = new QLabel(tr("Type:")); - typeComboBox = new QComboBox; - typeComboBox.addItem(tr("None"), new QVariant(cast(ulong) QSystemTrayIcon.NoIcon)); - typeComboBox.addItem(style().standardIcon( - QStyle.SP_MessageBoxInformation), tr("Information"), - new QVariant(cast(ulong) QSystemTrayIcon.Information)); - typeComboBox.addItem(style().standardIcon( - QStyle.SP_MessageBoxWarning), tr("Warning"), - new QVariant(cast(ulong) QSystemTrayIcon.Warning)); - typeComboBox.addItem(style().standardIcon( - QStyle.SP_MessageBoxCritical), tr("Critical"), - new QVariant(cast(ulong) QSystemTrayIcon.Critical)); - typeComboBox.setCurrentIndex(1); + typeComboBox = new QComboBox; + typeComboBox.addItem(tr("None"), new QVariant(cast(ulong) QSystemTrayIcon.NoIcon)); + typeComboBox.addItem(style().standardIcon( + QStyle.SP_MessageBoxInformation), tr("Information"), + new QVariant(cast(ulong) QSystemTrayIcon.Information)); + typeComboBox.addItem(style().standardIcon( + QStyle.SP_MessageBoxWarning), tr("Warning"), + new QVariant(cast(ulong) QSystemTrayIcon.Warning)); + typeComboBox.addItem(style().standardIcon( + QStyle.SP_MessageBoxCritical), tr("Critical"), + new QVariant(cast(ulong) QSystemTrayIcon.Critical)); + typeComboBox.setCurrentIndex(1); - durationLabel = new QLabel(tr("Duration:")); + durationLabel = new QLabel(tr("Duration:")); - durationSpinBox = new QSpinBox; - durationSpinBox.setRange(5, 60); - durationSpinBox.setSuffix(" s"); - durationSpinBox.setValue(15); + durationSpinBox = new QSpinBox; + durationSpinBox.setRange(5, 60); + durationSpinBox.setSuffix(" s"); + durationSpinBox.setValue(15); - durationWarningLabel = new QLabel(tr("(some systems might ignore this hint)")); - durationWarningLabel.setIndent(10); + durationWarningLabel = new QLabel(tr("(some systems might ignore this hint)")); + durationWarningLabel.setIndent(10); - titleLabel = new QLabel(tr("Title:")); + titleLabel = new QLabel(tr("Title:")); - titleEdit = new QLineEdit(tr("Cannot connect to network")); + titleEdit = new QLineEdit(tr("Cannot connect to network")); - bodyLabel = new QLabel(tr("Body:")); + bodyLabel = new QLabel(tr("Body:")); - bodyEdit = new QTextEdit; - bodyEdit.setPlainText(tr("Don't believe me. Honestly, I don't have a clue.\nClick this balloon for details.")); + bodyEdit = new QTextEdit; + bodyEdit.setPlainText(tr("Don't believe me. Honestly, I don't have a clue.\nClick this balloon for details.")); - showMessageButton = new QPushButton(tr("Show Message")); - showMessageButton.setDefault(true); + showMessageButton = new QPushButton(tr("Show Message")); + showMessageButton.setDefault(true); - QGridLayout messageLayout = new QGridLayout; - messageLayout.addWidget(typeLabel, 0, 0); - messageLayout.addWidget(typeComboBox, 0, 1, 1, 2); - messageLayout.addWidget(durationLabel, 1, 0); - messageLayout.addWidget(durationSpinBox, 1, 1); - messageLayout.addWidget(durationWarningLabel, 1, 2, 1, 3); - messageLayout.addWidget(titleLabel, 2, 0); - messageLayout.addWidget(titleEdit, 2, 1, 1, 4); - messageLayout.addWidget(bodyLabel, 3, 0); - messageLayout.addWidget(bodyEdit, 3, 1, 2, 4); - messageLayout.addWidget(showMessageButton, 5, 4); - messageLayout.setColumnStretch(3, 1); - messageLayout.setRowStretch(4, 1); - messageGroupBox.setLayout(messageLayout); - } + QGridLayout messageLayout = new QGridLayout; + messageLayout.addWidget(typeLabel, 0, 0); + messageLayout.addWidget(typeComboBox, 0, 1, 1, 2); + messageLayout.addWidget(durationLabel, 1, 0); + messageLayout.addWidget(durationSpinBox, 1, 1); + messageLayout.addWidget(durationWarningLabel, 1, 2, 1, 3); + messageLayout.addWidget(titleLabel, 2, 0); + messageLayout.addWidget(titleEdit, 2, 1, 1, 4); + messageLayout.addWidget(bodyLabel, 3, 0); + messageLayout.addWidget(bodyEdit, 3, 1, 2, 4); + messageLayout.addWidget(showMessageButton, 5, 4); + messageLayout.setColumnStretch(3, 1); + messageLayout.setRowStretch(4, 1); + messageGroupBox.setLayout(messageLayout); + } - void createActions() - { - minimizeAction = new QAction(tr("Mi&nimize"), this); - connect(minimizeAction, "triggered", this, "hide"); + void createActions() + { + minimizeAction = new QAction(tr("Mi&nimize"), this); + connect(minimizeAction, "triggered", this, "hide"); - maximizeAction = new QAction(tr("Ma&ximize"), this); - connect(maximizeAction, "triggered", this, "showMaximized"); + maximizeAction = new QAction(tr("Ma&ximize"), this); + connect(maximizeAction, "triggered", this, "showMaximized"); - restoreAction = new QAction(tr("&Restore"), this); - connect(restoreAction, "triggered", this, "showNormal"); + restoreAction = new QAction(tr("&Restore"), this); + connect(restoreAction, "triggered", this, "showNormal"); - quitAction = new QAction(tr("&Quit"), this); - connect(quitAction, "triggered", qApp(), "quit"); - } + quitAction = new QAction(tr("&Quit"), this); + connect(quitAction, "triggered", qApp(), "quit"); + } - void createTrayIcon() - { - trayIconMenu = new QMenu(this); - trayIconMenu.addAction(minimizeAction); - trayIconMenu.addAction(maximizeAction); - trayIconMenu.addAction(restoreAction); - trayIconMenu.addSeparator(); - trayIconMenu.addAction(quitAction); + void createTrayIcon() + { + trayIconMenu = new QMenu(this); + trayIconMenu.addAction(minimizeAction); + trayIconMenu.addAction(maximizeAction); + trayIconMenu.addAction(restoreAction); + trayIconMenu.addSeparator(); + trayIconMenu.addAction(quitAction); - trayIcon = new QSystemTrayIcon(this); - trayIcon.setContextMenu(trayIconMenu); - } + trayIcon = new QSystemTrayIcon(this); + trayIcon.setContextMenu(trayIconMenu); + } - QGroupBox iconGroupBox; - QLabel iconLabel; - QComboBox iconComboBox; - QCheckBox showIconCheckBox; + QGroupBox iconGroupBox; + QLabel iconLabel; + QComboBox iconComboBox; + QCheckBox showIconCheckBox; - QGroupBox messageGroupBox; - QLabel typeLabel; - QLabel durationLabel; - QLabel durationWarningLabel; - QLabel titleLabel; - QLabel bodyLabel; - QComboBox typeComboBox; - QSpinBox durationSpinBox; - QLineEdit titleEdit; - QTextEdit bodyEdit; - QPushButton showMessageButton; + QGroupBox messageGroupBox; + QLabel typeLabel; + QLabel durationLabel; + QLabel durationWarningLabel; + QLabel titleLabel; + QLabel bodyLabel; + QComboBox typeComboBox; + QSpinBox durationSpinBox; + QLineEdit titleEdit; + QTextEdit bodyEdit; + QPushButton showMessageButton; - QAction minimizeAction; - QAction maximizeAction; - QAction restoreAction; - QAction quitAction; + QAction minimizeAction; + QAction maximizeAction; + QAction restoreAction; + QAction quitAction; - QSystemTrayIcon trayIcon; - QMenu trayIconMenu; - + QSystemTrayIcon trayIcon; + QMenu trayIconMenu; + mixin Q_OBJECT; } diff -r 925386e0e780 -r 31520b2c0b3c examples/dialogs/standarddialogs/dialog.d --- a/examples/dialogs/standarddialogs/dialog.d Mon May 17 21:48:15 2010 +0300 +++ b/examples/dialogs/standarddialogs/dialog.d Thu May 20 15:49:08 2010 +0300 @@ -40,7 +40,6 @@ ****************************************************************************/ module dialog; - import qt.gui.QDialog; import qt.gui.QCheckBox; import qt.gui.QLabel; @@ -55,8 +54,7 @@ import qt.gui.QFileDialog; import qt.core.QFile; -import std.string; - +import std.string : format, join; string MESSAGE = tr("

Message boxes have a caption, a text, " "and any number of buttons, each with standard or custom texts." @@ -154,7 +152,7 @@ native = new QCheckBox(this); native.setText("Use native file dialog."); native.setChecked(true); - + version(windows) {} else { version(mac) {} else @@ -209,7 +207,7 @@ bool ok; int i = QInputDialog.getInt(this, tr("QInputgetInteger()"), tr("Percentage:"), 25, 0, 100, 1, ok); if (ok) - integerLabel.setText(format("%d", i)); + integerLabel.setText(format("%d", i)); } void slot_setDouble() @@ -218,7 +216,7 @@ double d = QInputDialog.getDouble(this, tr("QInputgetDouble()"), tr("Amount:"), 37.56, -10000, 10000, 2, ok); if (ok) - doubleLabel.setText(format("%g", d)); + doubleLabel.setText(format("%g", d)); } void slot_setItem() @@ -407,6 +405,6 @@ QErrorMessage errorMessageDialog; string openFilesPath; - + mixin Q_OBJECT; } diff -r 925386e0e780 -r 31520b2c0b3c examples/draganddrop/dropsite/dropsitewindow.d --- a/examples/draganddrop/dropsite/dropsitewindow.d Mon May 17 21:48:15 2010 +0300 +++ b/examples/draganddrop/dropsite/dropsitewindow.d Thu May 20 15:49:08 2010 +0300 @@ -41,7 +41,7 @@ module dropsitewindow; -import std.string; +import std.string : format, strip, toupper; import qt.gui.QWidget; import qt.gui.QLabel; @@ -56,13 +56,13 @@ class DropSiteWindow : public QWidget { public: - + this() { abstractLabel = new QLabel(tr("This example accepts drags from other " "applications and displays the MIME types " "provided by the drag object.")); - + abstractLabel.setWordWrap(true); abstractLabel.adjustSize(); @@ -125,7 +125,7 @@ } else { QByteArray data = mimeData.data(format); for (int i = 0; i < data.size() && i < 32; ++i) { - string hex = toupper(std.string.format("%x", data.at(i))); + string hex = toupper(std.string.format("%x", data.at(i))); text ~= hex ~ " "; } } @@ -148,6 +148,6 @@ QPushButton clearButton; QPushButton quitButton; QDialogButtonBox buttonBox; - + mixin Q_OBJECT; } diff -r 925386e0e780 -r 31520b2c0b3c examples/layouts/basiclayouts/dialog.d --- a/examples/layouts/basiclayouts/dialog.d Mon May 17 21:48:15 2010 +0300 +++ b/examples/layouts/basiclayouts/dialog.d Thu May 20 15:49:08 2010 +0300 @@ -56,10 +56,7 @@ import qt.gui.QComboBox; import qt.gui.QSpinBox; -version(Tango) - import tango.text.convert.Format: format = Format; -else - import std.string; +import std.string : format; import std.stdio; @@ -157,8 +154,6 @@ formGroupBox.setLayout(layout); } - mixin Q_OBJECT; - enum { NumGridRows = 3, NumButtons = 4 }; QMenuBar menuBar; @@ -174,4 +169,6 @@ QMenu fileMenu; QAction exitAction; + + mixin Q_OBJECT; } diff -r 925386e0e780 -r 31520b2c0b3c examples/mainwindows/dockwidgets/mainwindow.d --- a/examples/mainwindows/dockwidgets/mainwindow.d Mon May 17 21:48:15 2010 +0300 +++ b/examples/mainwindows/dockwidgets/mainwindow.d Thu May 20 15:49:08 2010 +0300 @@ -56,10 +56,7 @@ import qt.gui.QIcon; import qt.core.QDate; -version(Tango) - import tango.text.Util; -else - import std.string; +import std.string : split; class MainWindow : public QMainWindow { @@ -161,7 +158,7 @@ { if (customer == "") return; - + string[] customerList = customer.split(", "); auto document = textEdit.document(); QTextCursor cursor = document.find("NAME"); @@ -348,6 +345,6 @@ QAction aboutAct; QAction aboutQtAct; QAction quitAct; - + mixin Q_OBJECT; } diff -r 925386e0e780 -r 31520b2c0b3c examples/mainwindows/sdi/mainwindow.d --- a/examples/mainwindows/sdi/mainwindow.d Mon May 17 21:48:15 2010 +0300 +++ b/examples/mainwindows/sdi/mainwindow.d Thu May 20 15:49:08 2010 +0300 @@ -57,16 +57,9 @@ import qt.core.QSettings; import qt.core.QTextStream; -version(Tango) -{ - import tango.text.Util; - import Int = tango.text.convert.Integer; -} -else -{ - import std.string; - import std.conv; -} +//import std.string; +import std.conv; + class MainWindow : public QMainWindow { // Q_OBJECT @@ -371,9 +364,6 @@ isUntitled = fileName == null; if (isUntitled) { - version(Tango) - curFile = tr("document" ~ Int.toString(sequenceNumber++) ~ ".txt"); - else curFile = tr("document" ~ to!(string)(sequenceNumber++) ~ ".txt"); } else { scope qfi = new QFileInfo(fileName); @@ -426,6 +416,6 @@ QAction pasteAct; QAction aboutAct; QAction aboutQtAct; - + mixin Q_OBJECT; }; diff -r 925386e0e780 -r 31520b2c0b3c examples/widgets/calculator/calculator.d --- a/examples/widgets/calculator/calculator.d Mon May 17 21:48:15 2010 +0300 +++ b/examples/widgets/calculator/calculator.d Thu May 20 15:49:08 2010 +0300 @@ -49,13 +49,12 @@ import std.math; import std.conv; -import std.string; +import std.string : format, indexOf; class Calculator : public QDialog { - + public: - this(QWidget parent = null) { super(parent); @@ -70,7 +69,7 @@ display.setAlignment(Qt.AlignRight); display.setMaxLength(15); - auto font = new QFont(display.font()); + auto font = new QFont(display.font()); font.setPointSize(font.pointSize() + 8); display.setFont(font); @@ -150,7 +149,8 @@ display.clear(); waitingForOperand = false; } - display.setText(display.text() ~ format("%g", digitValue)); + + display.setText(display.text() ~ format("%s", digitValue)); } void slot_unaryOperatorClicked() @@ -267,7 +267,7 @@ if (indexOf(text, '.') >= text.length) display.setText(text ~ tr(".")); - + waitingForOperand = false; } diff -r 925386e0e780 -r 31520b2c0b3c generator/dgenerator.cpp --- a/generator/dgenerator.cpp Mon May 17 21:48:15 2010 +0300 +++ b/generator/dgenerator.cpp Thu May 20 15:49:08 2010 +0300 @@ -2558,8 +2558,8 @@ s << INDENT << d_class->name() << ".QTypeInfo.init();" << endl; if (d_class->isQObject()) { - s << INDENT << "if (!" << d_class->name() << "._staticMetaObject) " << endl - << INDENT << " " << d_class->name() << ".createStaticMetaObject;" << endl << endl; + // ensure meta-object is created at static construction + s << INDENT << d_class->name() << ".staticMetaObject();" << endl; } if (cpp_shared && d_class->generateShellClass()) { @@ -2732,9 +2732,8 @@ } writeMetaMethodSignatures(s, "__slotSignatures", slot_funcs); - QString concreteArg; - if (d_class->isAbstract()) - concreteArg += ", " + d_class->name() + "_ConcreteWrapper"; + if (d_class->isAbstract()) + s << "alias " << d_class->name() << "_ConcreteWrapper ConcreteType;" << endl; if (!d_class->isFinal()) s << " int qt_metacall(QMetaObject.Call _c, int _id, void **_a) {" << endl @@ -2742,28 +2741,17 @@ << " }" << endl << endl; s << " private static __gshared QMetaObject _staticMetaObject;" << endl - << " protected static void createStaticMetaObject() {" << endl - << " assert(!_staticMetaObject);" << endl - << " QMetaObject base;" << endl; - - if (d_class->name() != "QObject") - { - QString baseName = d_class->baseClassName(); - s << " if (!" << baseName << "._staticMetaObject)" << endl - << " " << baseName << ".createStaticMetaObject;" << endl - << " base = " << baseName << "._staticMetaObject;" << endl; - } - - s << " _staticMetaObject = new QMetaObject(qtd_" << d_class->name() << "_staticMetaObject, base);" << endl - << " _staticMetaObject.construct!(" << d_class->name() << concreteArg << ");" << endl - << " _populateMetaInfo();" << endl + << " protected static void setStaticMetaObject(QMetaObject m) {" << endl + << " _staticMetaObject = m;" << endl << " }" << endl << endl - << " QMetaObject metaObject() {" << endl + << " @property QMetaObject metaObject() {" << endl << " return _staticMetaObject;" << endl << " }" << endl << endl - << " static QMetaObject staticMetaObject() {" << endl + << " @property static QMetaObject staticMetaObject() {" << endl + << " if (!_staticMetaObject)" << endl + << " QMetaObject.create!(typeof(this))(qtd_" << d_class->name() << "_staticMetaObject());" << endl << " return _staticMetaObject;" << endl << " }" << endl << endl @@ -2771,11 +2759,11 @@ << " return static_cast!(" << d_class->name() << ")(_staticMetaObject.getObject(nativeId));" << endl << " }" << endl << endl - << " static void __createEntity(void* nativeId, void* dId) {" << endl + << " /* internal */ static void __createEntity(void* nativeId, void* dId) {" << endl << " return qtd_" << d_class->name() << "_createEntity(nativeId, dId);" << endl << " }" << endl << endl - << " private static void _populateMetaInfo() {" << endl + << " /* internal */ static void _populateMetaInfo() {" << endl << " int index;" << endl << endl; AbstractMetaFunctionList signal_funcs = signalFunctions(d_class, false);