From 4b8d1c2343899d18a6ac8958ef7116f3133f7630 Mon Sep 17 00:00:00 2001 From: konrad Date: Wed, 20 Oct 2010 20:18:45 +0000 Subject: [PATCH] basic scriptability and meta-classing for pack git-svn-id: https://silmor.de/svn/softmagic/pack/trunk@603 6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33 --- qtbase/include/interface.h | 11 ++ qtbase/include/nullable.h | 13 +- qtbase/include/object.h | 15 ++ qtbase/include/transaction.h | 19 ++- qtbase/src/object.cpp | 12 ++ woc/qt/qtclass.cpp | 62 +++++++- woc/qt/qtclass.h | 3 + woc/qt/qtctrans.cpp | 378 ++++++++++++++++++++++++++---------------- woc/qt/qtctrans.h | 15 ++ woc/qt/qtout.cpp | 53 +++++-- woc/qt/qtout.h | 12 +- 11 files changed, 419 insertions(+), 174 deletions(-) diff --git a/qtbase/include/interface.h b/qtbase/include/interface.h index b89e9ee..04dc8b4 100644 --- a/qtbase/include/interface.h +++ b/qtbase/include/interface.h @@ -25,6 +25,17 @@ class QNetworkReply; class WInterface:public QObject { Q_OBJECT + Q_PROPERTY(QUrl url READ url) + Q_PROPERTY(bool useProxy READ useProxy) + Q_PROPERTY(bool useProxyAuth READ useProxyAuth) + Q_PROPERTY(QString proxyHost READ proxyHost) + Q_PROPERTY(unsigned short proxyPort READ proxyPort) + Q_PROPERTY(QString proxyUser READ proxyUser) + Q_PROPERTY(QString proxyPassword READ proxyPassword) + Q_PROPERTY(int webTimeout READ webTimeout) + Q_PROPERTY(QString name READ name) + Q_ENUMS(LogLevel) + Q_PROPERTY(LogLevel logLevel READ logLevel) protected: ///used by child classes for instantiation WInterface(QString name); diff --git a/qtbase/include/nullable.h b/qtbase/include/nullable.h index ed82877..304168a 100644 --- a/qtbase/include/nullable.h +++ b/qtbase/include/nullable.h @@ -62,13 +62,16 @@ templateclass Nullable }; #include +#include //convenience wrappers +typedef Nullable Bool;Q_DECLARE_METATYPE(Bool) typedef Nullable Int; -typedef Nullable Int32; -typedef Nullable Int64; -typedef Nullable UInt32; -typedef Nullable UInt64; -typedef Nullable NString; +typedef Nullable Int32;Q_DECLARE_METATYPE(Int32) +typedef Nullable Int64;Q_DECLARE_METATYPE(Int64) +typedef Nullable UInt32;Q_DECLARE_METATYPE(UInt32) +typedef Nullable UInt64;Q_DECLARE_METATYPE(UInt64) +typedef Nullable NString;Q_DECLARE_METATYPE(NString) +typedef Nullable NByteArray;Q_DECLARE_METATYPE(NByteArray) inline bool operator==(Int64 i1,int i2){return i1.operator==(i2);} inline bool operator==(UInt32 i1,int i2){return i1.operator==(i2);} diff --git a/qtbase/include/object.h b/qtbase/include/object.h index 57f24e8..5949283 100644 --- a/qtbase/include/object.h +++ b/qtbase/include/object.h @@ -22,6 +22,8 @@ class QDomElement; class QDomDocument; +class QScriptValue; +class QScriptEngine; /**base class of all web based objects*/ class WObject:public WHelper @@ -47,4 +49,17 @@ class WDeserializerException:public WException wob& operator=(const wob ## Abstract&w){wob ## Abstract::operator=(w);return *this;} \ private: + +#define WOSCRIPT(wob) public: \ + static QScriptValue toScriptValue(QScriptEngine*,const wob &); \ + static void fromScriptValue(const QScriptValue&,wob &); \ + private: + +#define WOSCRIPT_IMP(wob) +/* QScriptValue wob::toScriptValue(QScriptEngine*engine,const wob &obj){\ + return engine->newQObject(new wob (obj),QScriptEngine::ScriptOwnership);}\ + void wob::fromScriptValue(const QScriptValue&val,wob &obj){\ + wob *xobj=qobject_cast< wob *>(val.toQObject());\ + if(xobj!=0 && &obj!=xobj)obj = *xobj;}*/ + #endif diff --git a/qtbase/include/transaction.h b/qtbase/include/transaction.h index 25cc027..2457d6e 100644 --- a/qtbase/include/transaction.h +++ b/qtbase/include/transaction.h @@ -27,6 +27,15 @@ class WTransaction_Private; class WTransaction:public WHelper { Q_OBJECT + Q_ENUMS(Stage) + Q_PROPERTY(Stage stage READ stage) + Q_PROPERTY(bool isInProgress READ isInProgress) + Q_PROPERTY(bool isFinished READ isFinished) + Q_PROPERTY(bool isUnstarted READ isUnstarted) + Q_PROPERTY(bool hasError READ hasError) + Q_PROPERTY(QString errorType READ errorType) + Q_PROPERTY(QString errorString READ errorString) + Q_PROPERTY(QString interfaceName READ interface) public: /**stage the transaction is in*/ enum Stage { @@ -55,10 +64,6 @@ class WTransaction:public WHelper /**returns the interface that is used for the transaction*/ virtual QString interface()const; - /**waits for this transaction to finish, returns true if the transaction was successful, returns immediately if the transaction is not running - \param tmout the maximum amount of milli seconds to wait, if 0 it will not time out*/ - virtual bool waitForFinished(int tmout=30000); - /**deconstructor*/ virtual ~WTransaction(); @@ -95,6 +100,12 @@ class WTransaction:public WHelper protected: void loop(); }; + + public slots: + /**waits for this transaction to finish, returns true if the transaction was successful, returns immediately if the transaction is not running + \param tmout the maximum amount of milli seconds to wait, if 0 it will not time out*/ + virtual bool waitForFinished(int tmout=30000); + protected: /**internal: construct the transaction*/ WTransaction(QString iface=QString()); diff --git a/qtbase/src/object.cpp b/qtbase/src/object.cpp index fc8a896..ae172b8 100644 --- a/qtbase/src/object.cpp +++ b/qtbase/src/object.cpp @@ -11,3 +11,15 @@ // #include "WObject" + +//do at least something useful +#include "Nullable" + +static int itype0= + qRegisterMetaType()+ + qRegisterMetaType()+ + qRegisterMetaType()+ + qRegisterMetaType()+ + qRegisterMetaType()+ + qRegisterMetaType()+ + qRegisterMetaType(); diff --git a/woc/qt/qtclass.cpp b/woc/qt/qtclass.cpp index 2b71781..42a07a8 100644 --- a/woc/qt/qtclass.cpp +++ b/woc/qt/qtclass.cpp @@ -61,7 +61,7 @@ void WocQtClass::newClass(const WocClass&cls) hcd+="#include \""+m_prefix+"O"+cls.propertyPlainType(k[i])+"\"\n"; //class declaration - hcd+="class "+cna+":public "+cls.clientBaseClass()+"\n{\n"; + hcd+="class "+cna+":public "+cls.clientBaseClass()+"\n{\n Q_OBJECT\n"; hdr.write(hcd.toAscii()); //enums @@ -76,12 +76,58 @@ void WocQtClass::newClass(const WocClass&cls) //deserializer (constructor) classDeserializer(cls,hdr,src,cna); - //lead out + //scripting + classScripting(cls,hdr,src,cna,cn); + + //meta types + m_aux+="Q_DECLARE_METATYPE("+cna+")\n"; + m_aux+="Q_DECLARE_METATYPE(QList<"+cna+">)\n"; + m_aux+="Q_DECLARE_METATYPE(Nullable<"+cna+">)\n"; + scd="static int class_metatypeid="; + scd+="qRegisterMetaType<"+cna+">()+"; + scd+="qRegisterMetaType >()+"; + scd+="qRegisterMetaType >();\n"; + + //end of class, aux stuff, meta types hdr.write(QByteArray("\n};\n")); + hdr.write(m_aux.toAscii());m_aux.clear(); + src.write(scd.toAscii()); + + //lead out hdr.write(QByteArray(HDREND).replace("%",cna.toAscii())); src.write(QByteArray(SRCEND).replace("%",cna.toAscii())); } +void WocQtClass::classScripting(const WocClass& cls, MFile& hdr, MFile& src, QString cna,QString cn) +{ + Q_UNUSED(cna);Q_UNUSED(hdr);Q_UNUSED(cls); + //converters + QString hcd,scd; + if(cna==cn){ + hcd+=" public:\n"; + hcd+="\tstatic QScriptValue toScriptValue(QScriptEngine*,const "+cna+"&);\n"; + hcd+="\tstatic void fromScriptValue(const QScriptValue&,"+cna+"&);\n"; + }else{ + scd+="#include \""+cn+"\"\n"; + } + scd+="#include \n"; + scd+="#include \n"; + scd+="QScriptValue "+cn+"::toScriptValue(QScriptEngine*engine,const "+cn+"&obj)\n{\n"; + scd+="\treturn engine->newQObject(new "+cn+"(obj),QScriptEngine::ScriptOwnership);\n}\n"; + scd+="void "+cn+"::fromScriptValue(const QScriptValue&val,"+cn+"&obj)\n{\n"; + scd+="\t"+cn+"*xobj=qobject_cast<"+cn+"*>(val.toQObject());\n"; + scd+="\tif(xobj!=0 && &obj!=xobj)obj = *xobj;\n}\n"; + hdr.write(hcd.toAscii()); + src.write(scd.toAscii()); + //scripting registry + m_parent->addScriptInit( + "\tgval.setProperty(\""+cn+"\",engine->newQMetaObject(&"+cn+"::staticMetaObject));\n" + "\tqScriptRegisterMetaType(engine,"+cn+"::toScriptValue,"+cn+"::fromScriptValue);\n" + "\tqScriptRegisterSequenceMetaType >(engine);\n" + ); +} + + void WocQtClass::classEnums(const WocClass&cls,MFile&hdr,MFile&src,QString cn) { QStringList k=cls.enumTypes(); @@ -89,6 +135,12 @@ void WocQtClass::classEnums(const WocClass&cls,MFile&hdr,MFile&src,QString cn) QString hcd=" public:\n"; QString scd; for(int i=0;i)\n"; + scd+="static int enum_"+k[i]+"_metatypeid=qRegisterMetaType<"+cn+"::"+k[i]+">();\n"; + scd+="static int enum_"+k[i]+"_metatypeid2=qRegisterMetaType >();\n"; //type hcd+="\tenum "+k[i]+"{"; QListev=cls.enumValues(k[i]); @@ -140,8 +192,12 @@ void WocQtClass::classProperties(const WocClass&cls,MFile&hdr,MFile&) QStringList k=cls.propertyNames(); if(k.size()==0)return; QString hcd,scd; + //declare property + for(int i=0;i\n"; - } - for(int i=0;i\n"; - } - hcd+="\nclass "+cnp+";\n"; - hcd+="\nclass "+cn+":public "+m_transbase+"\n{\n"; - pcd+="\nclass "+cnp+":public WTransaction_PrivateBase\n{\n"; + + //include section + genInclude(ct); + //start of class + ct.hcd+="\nclass "+cnp+";\n"; + ct.hcd+="\nclass "+cn+":public "+m_transbase+"\n{\n Q_OBJECT\n"; + ct.pcd+="\nclass "+cnp+":public WTransaction_PrivateBase\n{\n"; //create properties - QString inlist,clist; - hcd+=" private:\n\t"+cnp+"*p;\n\tfriend class "+cnp+";\n"; - pcd+=" protected:\n\tfriend class "+cn+";\n"; - pcd+="\t"+cnp+"("+cn+"*parent){parent->p=this;}\n"; - pcd+="\tvoid attach("+cn+"*parent){parent->p=this;WTransaction_PrivateBase::attach();}\n"; - pcd+="\tvoid detach("+cn+"*parent){parent->p=0;WTransaction_PrivateBase::detach();}\n"; - for(int i=0;iprojectName()+"\""; + genTors(ct); - //global interface code - QString sif=" "+cn+" query"+trn.name()+"("+inlist+")\n\t"; - sif+="{return "+cn+"::query("+clist+(clist!=""?",":"")+"name());}\n"; - m_iface.write(sif.toAscii());sif.clear(); + //query method implemented + genQuery(ct); + + //create getters + genGetters(ct); - //create constructors - if(inlist!="")inlist+=","; - inlist+="QString iface"; - if(clist!="")clist+=","; - clist+="iface"; - QString defparm="=\""+WocProcessor::instance()->projectName()+"\""; + //create scripting + genScripting(ct); + + //button class up + ct.hcd+="};\n\n"; + ct.pcd+="};\n\n"; + + //make meta object... + ct.hcd+="Q_DECLARE_METATYPE("+cn+")\n"; + ct.scd+="static int mymetatypeid=qRegisterMetaType<"+cn+">();\n"; + + //write code + hdr.write(ct.hdi.toAscii()); + hdr.write(ct.hcd.toAscii()); + src.write(ct.sri.toAscii()); + src.write(ct.pcd.toAscii()); + src.write(ct.scd.toAscii()); + + //lead out + hdr.write(QByteArray(HDREND).replace("%",cn.toAscii())); + src.write(QByteArray(SRCEND).replace("%",cn.toAscii())); +} + +void WocQtClientTransaction::initList(QtCTrans& ct) +{ + for(int i=0;i\n"; + } + for(int i=0;i\n"; + } +} + +void WocQtClientTransaction::genProperties(QtCTrans&ct) +{ + ct.hcd+=" private:\n\t"+ct.cnp+"*p;\n\tfriend class "+ct.cnp+";\n"; + ct.pcd+=" protected:\n\tfriend class "+ct.cn+";\n"; + ct.pcd+="\t"+ct.cnp+"("+ct.cn+"*parent){parent->p=this;}\n"; + ct.pcd+="\tvoid attach("+ct.cn+"*parent){parent->p=this;WTransaction_PrivateBase::attach();}\n"; + ct.pcd+="\tvoid detach("+ct.cn+"*parent){parent->p=0;WTransaction_PrivateBase::detach();}\n"; + for(int i=0;idetach(this);\n}\n\n"; - - //query method implemented - scd+="void "+cn+"::netquery()\n{\n"; - scd+="\tWTransaction::Log log(this,\""+trn.name()+"\");\n"; - scd+="\tQByteArray enc=encodeData();\n"; - scd+="\tif(enc.isEmpty()){\n\t\temit finished();\n\t\treturn;\n\t}\n"; - scd+="\texecuteQuery(\""+trn.name()+"\",enc);\n"; - scd+="}\n"; + ct.hcd+="\t~"+ct.cn+"();\n"; + ct.scd+=ct.cn+"::~"+ct.cn+"()\n{\n\tp->detach(this);\n}\n\n"; +} + +void WocQtClientTransaction::genQuery(QtCTrans& ct) +{ + //global interface code + QString sif=" Q_SLOT "+ct.cn+" query"+ct.trn.name()+"("+ct.inlist+")\n\t"; + sif+="{return "+ct.cn+"::query("+ct.clist+(ct.clist!=""?",":"")+"name());}\n"; + m_iface.write(sif.toAscii());sif.clear(); + //query method decl + ct.hcd+=" private:\n"; + ct.hcd+="\tvoid netquery();\n\tvoid asyncnetquery();\n"; + ct.hcd+="\tQByteArray encodeData();\n\tvoid decodeData(QByteArray);\n"; + ct.hcd+=" protected:\n\tvirtual void endQuery();\n"; + //sync query + ct.scd+="void "+ct.cn+"::netquery()\n{\n"; + ct.scd+="\tWTransaction::Log log(this,\""+ct.trn.name()+"\");\n"; + ct.scd+="\tQByteArray enc=encodeData();\n"; + ct.scd+="\tif(enc.isEmpty()){\n\t\temit finished();\n\t\treturn;\n\t}\n"; + ct.scd+="\texecuteQuery(\""+ct.trn.name()+"\",enc);\n"; + ct.scd+="}\n"; //async query method implemented - scd+="void "+cn+"::asyncnetquery()\n{\n"; - scd+="\tnew WTransaction::Log(this,\""+trn.name()+"\");\n"; - scd+="\tQByteArray enc=encodeData();\n"; - scd+="\tif(enc.isEmpty()){\n\t\temit finished();\n\t\treturn;\n\t}\n"; - scd+="\tstartQuery(\""+trn.name()+"\",enc);\n"; - scd+="}\n"; + ct.scd+="void "+ct.cn+"::asyncnetquery()\n{\n"; + ct.scd+="\tnew WTransaction::Log(this,\""+ct.trn.name()+"\");\n"; + ct.scd+="\tQByteArray enc=encodeData();\n"; + ct.scd+="\tif(enc.isEmpty()){\n\t\temit finished();\n\t\treturn;\n\t}\n"; + ct.scd+="\tstartQuery(\""+ct.trn.name()+"\",enc);\n"; + ct.scd+="}\n"; //encode input - scd+="QByteArray "+cn+"::encodeData()\n{\n"; - scd+=trnInput(trn); - scd+="}\n"; + ct.scd+="QByteArray "+ct.cn+"::encodeData()\n{\n"; + ct.scd+=trnInput(ct.trn); + ct.scd+="}\n"; //decode output - scd+="void "+cn+"::decodeData(QByteArray rba)\n{\n"; - scd+=trnOutput(trn); - scd+="}\n"; - scd+="void "+cn+"::endQuery()\n{\n"; - scd+="\tdecodeData(d->m_rspdata.trimmed());\n"; - scd+="\temit finished();\n}\n"; - - - //create getters - for(int i=0;iout_"+out[i]+";}\n"; - } - + ct.scd+="void "+ct.cn+"::decodeData(QByteArray rba)\n{\n"; + ct.scd+=trnOutput(ct.trn); + ct.scd+="}\n"; + ct.scd+="void "+ct.cn+"::endQuery()\n{\n"; + ct.scd+="\tdecodeData(d->m_rspdata.trimmed());\n"; + ct.scd+="\temit finished();\n}\n"; //create queries - hcd+="\tstatic "+cn+" query("+inlist+defparm+");\n"; - scd+=cn+" "+cn+"::query("+inlist+")\n{\n"; - scd+="\t"+cn; - if(clist!="")scd+=" r("+clist+");\n";else scd+=" r;\n"; - scd+="\tr.netquery();\n\treturn r;\n}\n"; - hcd+="\tstatic "+cn+" asyncQuery("+inlist+defparm+");\n"; - scd+=cn+" "+cn+"::asyncQuery("+inlist+")\n{\n"; - scd+="\t"+cn; - if(clist!="")scd+=" r("+clist+");\n";else scd+=" r;\n"; - scd+="\tr.asyncnetquery();\n\treturn r;\n}\n"; - - //button up - hcd+="};\n\n"; - pcd+="};\n\n"; - - //write code - hdr.write(hdi.toAscii()); - hdr.write(hcd.toAscii()); -// hdp.write(pcd.toAscii()); - src.write(sri.toAscii()); - src.write(pcd.toAscii()); - src.write(scd.toAscii()); - - //lead out - hdr.write(QByteArray(HDREND).replace("%",cn.toAscii())); -// hdp.write(QByteArray(HDREND).replace("%",cnp.toAscii())); - src.write(QByteArray(SRCEND).replace("%",cn.toAscii())); + ct.hcd+=" public:\n"; + ct.hcd+="\tstatic "+ct.cn+" query("+ct.xinlist+ct.defparm+");\n"; + ct.scd+=ct.cn+" "+ct.cn+"::query("+ct.xinlist+")\n{\n"; + ct.scd+="\t"+ct.cn; + ct.scd+=" r("+ct.xclist+");\n"; + ct.scd+="\tr.netquery();\n\treturn r;\n}\n"; + ct.hcd+="\tstatic "+ct.cn+" asyncQuery("+ct.xinlist+ct.defparm+");\n"; + ct.scd+=ct.cn+" "+ct.cn+"::asyncQuery("+ct.xinlist+")\n{\n"; + ct.scd+="\t"+ct.cn; + ct.scd+=" r("+ct.xclist+");\n"; + ct.scd+="\tr.asyncnetquery();\n\treturn r;\n}\n"; +} + +void WocQtClientTransaction::genGetters(QtCTrans& ct) +{ + for(int i=0;iout_"+ct.out[i]+";}\n"; + } +} + +void WocQtClientTransaction::genScripting(QtCTrans& ct) +{ + if(!m_parent->doGenerateScripting())return; + //converters between transaction and script values + ct.hdi+="class QScriptValue;\n"; + ct.hdi+="class QScriptEngine;\n"; + ct.sri+="#include \n"; + ct.sri+="#include \n"; + ct.hcd+="\tstatic QScriptValue toScriptValue(QScriptEngine*,const "+ct.cn+"&);\n"; + ct.hcd+="\tstatic void fromScriptValue(const QScriptValue&,"+ct.cn+"&);\n"; + ct.scd+="QScriptValue "+ct.cn+"::toScriptValue(QScriptEngine*engine,const "+ct.cn+"&obj)\n{\n"; + ct.scd+="\treturn engine->newQObject(new "+ct.cn+"(obj),QScriptEngine::ScriptOwnership);\n}\n"; + ct.scd+="void "+ct.cn+"::fromScriptValue(const QScriptValue&val,"+ct.cn+"&obj)\n{\n"; + ct.scd+="\t"+ct.cn+"*xobj=qobject_cast<"+ct.cn+"*>(val.toQObject());\n"; + ct.scd+="\tif(xobj!=0 && &obj!=xobj)obj = *xobj;\n}\n"; + //add to engine + m_parent->addScriptInit( + "\t{QScriptValue mo=engine->newQMetaObject(&"+ct.cn+"::staticMetaObject);\n" + "\tgval.setProperty(\""+ct.cn+"\",mo);\n" + "\tqScriptRegisterMetaType(engine,"+ct.cn+"::toScriptValue,"+ct.cn+"::fromScriptValue);}\n" + ); } QString WocQtClientTransaction::trnInput(const WocTransaction&trn) @@ -342,6 +420,7 @@ void WocQtClientTransaction::trnList() { QString code; //header + code+=" Q_ENUMS(Right)\n"; code+=" enum Right {\n NoRight"; QStringList r=WocProcessor::instance()->transactionNames(); QStringList p=WocProcessor::instance()->privilegeNames(); @@ -351,39 +430,46 @@ void WocQtClientTransaction::trnList() for(int i=0;iifaceClassName()+"::RightList allKnownRights();\n"; + m_iface.write(code.toAscii());code.clear(); - code="QString "+m_prefix+"Interface::rightToString(Right r)\n{\n\tswitch(r){\n"; + code+="static int righttypeid="; + code+="qRegisterMetaType<"+m_parent->ifaceClassName()+"::RightList>()+"; + code+="qRegisterMetaTypeifaceClassName()+"::RightList> >();\n"; + m_parent->addPostIface("Q_DECLARE_METATYPE("+m_parent->ifaceClassName()+"::RightList)\n"); + m_parent->addPostIface("Q_DECLARE_METATYPE(QList<"+ m_parent->ifaceClassName()+ "::RightList>)\n"); + m_parent->addScriptInit("\tqScriptRegisterSequenceMetaType >(engine);\n"); + code+="QString "+m_parent->ifaceClassName()+"::rightToString(Right r)\n{\n\tswitch(r){\n"; for(int i=0;iifaceClassName()+"::rightToLocalString(Right r)\n{\n\tswitch(r){\n"; for(int i=0;iifaceClassName()+"::Right "+m_prefix+"Interface::stringToRight(QString s)\n{\n"; for(int i=0;i "+m_prefix+"Interface::allKnownRights()\n{\n"; + code+="QList<"+m_parent->ifaceClassName()+"::Right> "+m_parent->ifaceClassName()+"::allKnownRights()\n{\n"; code+="\tQList ret;ret"; for(int i=0;iifaceClassName()+"::allKnownRightsString()\n{\n"; code+="\tQStringList ret;ret"; for(int i=0;iprojectName(); - m_ifacecpp.setFileName(m_basedir+"/"+m_subdir+"/src"+m_prefix+"Interface.cpp"); + m_ifacecpp.setFileName(m_basedir+"/"+m_subdir+"/src"+ifaceClassName()+".cpp"); if(!m_ifacecpp.open(QIODevice::WriteOnly|QIODevice::Truncate)){ qDebug("Error: cannot create Qt interface file %s.",m_ifacecpp.fileName().toAscii().data()); emit errorFound(); return; } - m_ifacecpp.write(QByteArray(SRCSTART).replace('%',m_prefix+"Interface")); - m_iface.setFileName(m_basedir+"/"+m_subdir+"/src"+m_prefix+"Interface.h"); + m_ifacecpp.write(QByteArray(SRCSTART).replace('%',ifaceClassName())); + m_iface.setFileName(m_basedir+"/"+m_subdir+"/src"+ifaceClassName()+".h"); if(!m_iface.open(QIODevice::WriteOnly|QIODevice::Truncate)){ qDebug("Error: cannot create Qt interface file %s.",m_iface.fileName().toAscii().data()); emit errorFound(); @@ -65,15 +66,24 @@ WocQtOut::WocQtOut(QDomElement&el) m_iface.write(QByteArray(HDRSTART).replace("%",m_prefix.toAscii()+"INTERFACE_H")); m_iface.write(QByteArray("#include \""+m_prefix.toAscii()+"IncludeAll\"\n#include \"WInterface\"\n")); m_iface.write(QByteArray("#include \n")); - m_iface.write(QString("class "+m_prefix+"Interface:public WInterface\n{\n Q_OBJECT\n").toAscii()); - m_iface.write(QString(" public:\n "+m_prefix+"Interface(QString name=\""+pn+"\"):WInterface(name){}\n").toAscii()); - m_iface.write(QString(" static "+m_prefix+"Interface*instance(QString name=\""+pn+"\")\n\t{return qobject_cast<"+m_prefix+"Interface*>(WInterface::instance(name));}\n\n").toAscii()); - m_iface.write(QString(" static QString commVersion(){return \""+woc->verComm()+"\";}\n").toAscii()); - m_iface.write(QString(" static QString needCommVersion(){return \""+woc->verNeedComm()+"\";}\n").toAscii()); - m_iface.write(QString(" static QString version(){return \""+woc->verHR()+"\";}\n").toAscii()); - m_iface.write(QString(" static QString svnVersion(){return \""+woc->svnRevision()+"\";}\n\n").toAscii()); - m_iface.write(QString(" static QString svnRepositoryRoot(){return \""+woc->svnRepositoryRoot()+"\";}\n\n").toAscii()); - m_iface.write(QString(" static QString svnRepositoryUrl(){return \""+woc->svnRepositoryUrl()+"\";}\n\n").toAscii()); + if(m_genscript) + m_iface.write(QByteArray("class QScriptEngine;\n")); + m_iface.write(QString("class "+ifaceClassName()+":public WInterface\n{\n Q_OBJECT\n").toAscii()); + m_iface.write(QString(" public:\n "+ifaceClassName()+"(QString name=\""+pn+"\"):WInterface(name){}\n").toAscii()); + m_iface.write(QString(" static "+ifaceClassName()+"*instance(QString name=\""+pn+"\")\n\t{return qobject_cast<"+ifaceClassName()+"*>(WInterface::instance(name));}\n\n").toAscii()); + m_iface.write(QString(" Q_INVOKABLE static QString commVersion(){return \""+woc->verComm()+"\";}\n").toAscii()); + m_iface.write(QString(" Q_INVOKABLE static QString needCommVersion(){return \""+woc->verNeedComm()+"\";}\n").toAscii()); + m_iface.write(QString(" Q_INVOKABLE static QString version(){return \""+woc->verHR()+"\";}\n").toAscii()); + m_iface.write(QString(" Q_INVOKABLE static QString svnVersion(){return \""+woc->svnRevision()+"\";}\n\n").toAscii()); + m_iface.write(QString(" Q_INVOKABLE static QString svnRepositoryRoot(){return \""+woc->svnRepositoryRoot()+"\";}\n\n").toAscii()); + m_iface.write(QString(" Q_INVOKABLE static QString svnRepositoryUrl(){return \""+woc->svnRepositoryUrl()+"\";}\n\n").toAscii()); + + //init scripting + m_scriptcode="#include \n"; + m_scriptcode+="void "+ifaceClassName()+"::initScriptEngine(QScriptEngine*engine)\n{\n"; + m_scriptcode+="\tQScriptValue gval=engine->globalObject();\n"; + m_scriptcode+="\tgval.setProperty(\"Interface\",engine->newQMetaObject(this->metaObject()));\n"; + m_scriptcode+="\tgval.setProperty(\"interface\",engine->newQObject(this,QScriptEngine::QtOwnership, QScriptEngine::ExcludeDeleteLater));\n"; //create all includer m_hdr.setFileName(m_basedir+"/"+m_subdir+"/"+m_prefix+"IncludeAll"); @@ -83,20 +93,29 @@ WocQtOut::WocQtOut(QDomElement&el) return; } m_hdr.write(QByteArray(HDRSTART).replace("%",m_prefix.toAscii()+"INCLUDE_H")); - addFile(m_prefix.toAscii()+"Interface"); + addFile(ifaceClassName().toAscii()); } WocQtOut::~WocQtOut(){} void WocQtOut::finalize() { + //finish sub-classes if(qclass)qclass->finalize(); if(qtable)qtable->finalize(); if(qtrans)qtrans->finalize(); + //finish scripting stuff + if(m_genscript){ + m_iface.write(QByteArray(" void initScriptEngine(QScriptEngine*);\n")); + m_scriptcode+="}\n\n"; + m_ifacecpp.write(m_scriptcode.toAscii()); + } //finish sources m_ifacecpp.write(SRCEND); m_ifacecpp.close(); - m_iface.write(QByteArray("};\n")+HDREND); + m_iface.write(QByteArray("};\n")); + m_iface.write(m_postiface.toAscii()); + m_iface.write(HDREND); m_iface.close(); m_pri.write(QByteArray("\n#END OF AUTOGENERATED PRI FILE\n")); m_pri.close(); @@ -114,6 +133,12 @@ void WocQtOut::finalize() } } +void WocQtOut::addPostIface(QString s) +{ + m_postiface+=s; +} + + void WocQtOut::newTable(const WocTable&tbl) { if(qtable)qtable->newTable(tbl); diff --git a/woc/qt/qtout.h b/woc/qt/qtout.h index 45deeae..a4c83f6 100644 --- a/woc/qt/qtout.h +++ b/woc/qt/qtout.h @@ -54,9 +54,9 @@ class WocQtOut:public WocOutput friend class WocQtTransaction; friend class WocQtTable; - QString m_basedir,m_subdir,m_prefix,m_transbase,m_lang; + QString m_basedir,m_subdir,m_prefix,m_transbase,m_lang,m_postiface,m_scriptcode; MFile m_pri,m_iface,m_ifacecpp,m_hdr; - bool m_clean; + bool m_clean,m_genscript; ///types of files generated enum FileType{ @@ -80,6 +80,14 @@ class WocQtOut:public WocOutput void addFile(FileType kind,QString fname); /**helper: add a line to the project file*/ void addProjectLine(QString); + /**helper: adds a line after the class definition of the interface class*/ + void addPostIface(QString); + /**helper: returns the class name of the interface class*/ + QString ifaceClassName()const{return m_prefix+"Interface";} + /**helper: adds a line to the script initializer; this is ignored if scripting is inactive*/ + void addScriptInit(QString s){m_scriptcode+=s;} + ///helper: returns true if sub-classes are supposed to create scripting code + bool doGenerateScripting()const{return m_genscript;} WocQtClass*qclass; WocQtTable*qtable; -- 1.7.2.5