changeset 350:31520b2c0b3c

Removed dependency on parent trait and stringof
author Max Samukha <maxter@spambox.com>
date Thu, 20 May 2010 15:49:08 +0300
parents 925386e0e780
children 59d847a814e3
files build/core.txt d2/qt/QGlobal.d d2/qt/core/QMetaObject.d d2/qtd/Array.d d2/qtd/Attribute.d d2/qtd/MOC.d d2/qtd/Marshal.d d2/qtd/Signal.d d2/qtd/Str.d examples/desktop/systray/main.d examples/desktop/systray/window.d examples/dialogs/standarddialogs/dialog.d examples/draganddrop/dropsite/dropsitewindow.d examples/layouts/basiclayouts/dialog.d examples/mainwindows/dockwidgets/mainwindow.d examples/mainwindows/sdi/mainwindow.d examples/widgets/calculator/calculator.d generator/dgenerator.cpp
diffstat 18 files changed, 657 insertions(+), 682 deletions(-) [+]
line wrap: on
line diff
--- 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.
--- 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))
 */
--- 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
+import qtd.meta.Runtime;
+import qtd.Marshal;
+
+class QMetaArgument : Meta
 {
-    string name;
 }
 
-class MetaType : Meta
+class QMetaMethod : Meta
 {
-    this()
-    {
-    }
-}
+    alias typeof(this) This;
 
-class MetaVariable : Meta
-{
-    MetaType type;
-}
-
-class MetaCallable : Meta { }
-
-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;
         }
+        _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();
+
+            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++;
+                }
+            }
+        }
     }
-    
-    // TODO: remove when D acquires templated constructors       
-    void construct(T : QObject, Concrete = T)()
+
+    // new
+    static This create(T : QObject)(void* nativeId)
     {
-        _classInfo = T.classinfo;        
+        auto m = new This();
+        m.construct!T(nativeId);
+        return m;
+    }
 
-        _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;
-            };
-    }
-    
     /++
     +/
     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);
 
--- 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
--- 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);
     }
--- 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<ArgumentDef> 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";
 }
 
-template Q_OBJECT()
+string generateDispatchSwitch(size_t methodCount)
 {
-    alias findSignals!(typeof(this)) SignalFuncs;
-    alias toMetaEntries!(SignalFuncs) SignalMetaEntries;
-    alias findSlots!(typeof(this)) SlotFuncs;
-    alias toMetaEntries!(SlotFuncs) SlotMetaEntries;
+    string res = "switch(_id) {\n";
 
-    mixin(generateMetaInfo!(typeof(this), SignalMetaEntries, SlotMetaEntries)());
-    // debug output
-//    pragma(msg, generateMetaInfo!(typeof(this), SignalMetaEntries, SlotMetaEntries)());
+    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";
 }
+
+mixin template Q_OBJECT()
+{
+    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;
+
+            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;
+    }
+}
+
--- 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;
-}
--- 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)
+/**
+    Generates D-to-C++ conversion code for signals.
+ */
+string genConvToCpp(uint argIndex)
 {
-    return defVals.length;
-}
+    string res = format_ctfe(q{
 
+        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};
 
-// 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
-}
+    }, argIndex);
 
-template MetaEntryOwner(source...)
-{
-    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 convertSignalArguments(Args...)()
-{
-//        void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_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";
     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)
+template methodName(alias method)
 {
-    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...)
-{
-    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
--- 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]);
--- 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();
 }
--- 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 <b>Quit</b> 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 <b>Quit</b> 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;
 }
--- 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("<p>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;
 }
--- 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;
 }
--- 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;
 }
--- 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;
 }
--- 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;
 };
--- 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;
         }
 
--- 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);