diff options
Diffstat (limited to 'tools/designer/uic/form.cpp')
-rw-r--r-- | tools/designer/uic/form.cpp | 1452 |
1 files changed, 1452 insertions, 0 deletions
diff --git a/tools/designer/uic/form.cpp b/tools/designer/uic/form.cpp new file mode 100644 index 000000000..3102b7b41 --- /dev/null +++ b/tools/designer/uic/form.cpp @@ -0,0 +1,1452 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of TQt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free TQt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing retquirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at [email protected]. +** +** Licensees holding valid TQt Commercial licenses may use this file in +** accordance with the TQt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "uic.h" +#include "parser.h" +#include "widgetdatabase.h" +#include "domtool.h" +#include <qstringlist.h> +#include <qvaluelist.h> +#include <qfile.h> +#include <qfileinfo.h> +#include <qdir.h> +#include <qregexp.h> +#define NO_STATIC_COLORS +#include <globaldefs.h> + +static TQByteArray unzipXPM( TQString data, ulong& length ) +{ + const int lengthOffset = 4; + int baSize = data.length() / 2 + lengthOffset; + uchar *ba = new uchar[ baSize ]; + for ( int i = lengthOffset; i < baSize; ++i ) { + char h = data[ 2 * (i-lengthOffset) ].latin1(); + char l = data[ 2 * (i-lengthOffset) + 1 ].latin1(); + uchar r = 0; + if ( h <= '9' ) + r += h - '0'; + else + r += h - 'a' + 10; + r = r << 4; + if ( l <= '9' ) + r += l - '0'; + else + r += l - 'a' + 10; + ba[ i ] = r; + } + // qUncompress() expects the first 4 bytes to be the expected length of the + // uncompressed data + ba[0] = ( length & 0xff000000 ) >> 24; + ba[1] = ( length & 0x00ff0000 ) >> 16; + ba[2] = ( length & 0x0000ff00 ) >> 8; + ba[3] = ( length & 0x000000ff ); + TQByteArray baunzip = qUncompress( ba, baSize ); + delete[] ba; + return baunzip; +} + +#if QT_VERSION >= 0x030900 +#error Add this functionality to TQDir (relativePathTo() maybe?) and \ +remove it from here and from moc +#endif + +TQCString combinePath( const char *infile, const char *outfile ) +{ + TQFileInfo inFileInfo( TQDir::current(), TQFile::decodeName(infile) ); + TQFileInfo outFileInfo( TQDir::current(), TQFile::decodeName(outfile) ); + int numCommonComponents = 0; + + TQStringList inSplitted = + TQStringList::split( '/', inFileInfo.dir().canonicalPath(), TRUE ); + TQStringList outSplitted = + TQStringList::split( '/', outFileInfo.dir().canonicalPath(), TRUE ); + + while ( !inSplitted.isEmpty() && !outSplitted.isEmpty() && + inSplitted.first() == outSplitted.first() ) { + inSplitted.remove( inSplitted.begin() ); + outSplitted.remove( outSplitted.begin() ); + numCommonComponents++; + } + + if ( numCommonComponents < 2 ) { + /* + The paths don't have the same drive, or they don't have the + same root directory. Use an absolute path. + */ + return TQFile::encodeName( inFileInfo.absFilePath() ); + } else { + /* + The paths have something in common. Use a path relative to + the output file. + */ + while ( !outSplitted.isEmpty() ) { + outSplitted.remove( outSplitted.begin() ); + inSplitted.prepend( ".." ); + } + inSplitted.append( inFileInfo.fileName() ); + return TQFile::encodeName( inSplitted.join("/") ); + } +} + +/*! + Creates a declaration (header file) for the form given in \a e + + \sa createFormImpl(), createObjectDecl() +*/ +void Uic::createFormDecl( const TQDomElement &e ) +{ + TQDomElement n; + TQDomNodeList nl; + int i; + TQString objClass = getClassName( e ); + if ( objClass.isEmpty() ) + return; + TQString objName = getObjectName( e ); + + TQStringList typeDefs; + + TQMap<TQString, CustomInclude> customWidgetIncludes; + + TQString imageMembers; + + /* + We are generating a few TQImage members that are not strictly + necessary in some cases. Ideally, we would use retquiredImage, + which is computed elsewhere, to keep the generated .h and .cpp + files synchronized. + */ + + // at first the images + TQMap<TQString, int> customWidgets; + TQStringList forwardDecl; + TQStringList forwardDecl2; + TQString exportMacro; + for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "images" ) { + nl = n.elementsByTagName( "image" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + TQString img = registerObject( nl.item(i).toElement().attribute("name") ); + registerObject( img ); + imageMembers += TQString( " TQPixmap %1;\n" ).arg( img ); + } + } else if ( n.tagName() == "customwidgets" ) { + TQDomElement n2 = n.firstChild().toElement(); + while ( !n2.isNull() ) { + if ( n2.tagName() == "customwidget" ) { + TQDomElement n3 = n2.firstChild().toElement(); + TQString cl; + WidgetDatabaseRecord *r = new WidgetDatabaseRecord; + while ( !n3.isNull() ) { + if ( n3.tagName() == "class" ) { + cl = n3.firstChild().toText().data(); + if ( !nofwd ) + forwardDecl << cl; + customWidgets.insert( cl, 0 ); + r->name = cl; + } else if ( n3.tagName() == "header" ) { + CustomInclude ci; + ci.header = n3.firstChild().toText().data(); + ci.location = n3.attribute( "location", "global" ); + r->includeFile = ci.header; + customWidgetIncludes.insert( cl, ci ); + } + WidgetDatabase::append( r ); + n3 = n3.nextSibling().toElement(); + } + } + n2 = n2.nextSibling().toElement(); + } + } + } + + // register the object and unify its name + objName = registerObject( objName ); + TQString protector = objName.upper() + "_H"; + protector.replace( "::", "_" ); + out << "#ifndef " << protector << endl; + out << "#define " << protector << endl; + out << endl; + out << "#include <qvariant.h>" << endl; // for broken HP-UX compilers + + if ( !imageMembers.isEmpty() ) + out << "#include <qpixmap.h>" << endl; + + TQStringList globalIncludes, localIncludes; + int wid = WidgetDatabase::idFromClassName( objClass ); + { + TQMap<TQString, CustomInclude>::Iterator it = customWidgetIncludes.find( objClass ); + if ( it != customWidgetIncludes.end() ) { + if ( ( *it ).location == "global" ) + globalIncludes += (*it).header; + else + localIncludes += (*it).header; + } else { + globalIncludes += WidgetDatabase::includeFile( wid ); + } + } + + nl = e.parentNode().toElement().elementsByTagName( "include" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + TQDomElement n2 = nl.item(i).toElement(); + TQString s = n2.firstChild().toText().data(); + if ( n2.attribute( "impldecl", "in implementation" ) == "in declaration" && + n2.attribute( "location" ) != "local" ) { + if ( s.right( 5 ) == ".ui.h" ) + continue; + globalIncludes += s; + } + } + for ( i = 0; i < (int) nl.length(); i++ ) { + TQDomElement n2 = nl.item(i).toElement(); + TQString s = n2.firstChild().toText().data(); + if ( n2.attribute( "impldecl", "in implementation" ) == "in declaration" && + n2.attribute( "location" ) == "local" &&!globalIncludes.contains( s ) ) { + if ( s.right( 5 ) == ".ui.h" ) + continue; + localIncludes += s; + } + } + + TQStringList::Iterator it; + + globalIncludes = unique( globalIncludes ); + for ( it = globalIncludes.begin(); it != globalIncludes.end(); ++it ) { + if ( !(*it).isEmpty() ) + out << "#include <" << *it << ">" << endl; + } + localIncludes = unique( localIncludes ); + for ( it = localIncludes.begin(); it != localIncludes.end(); ++it ) { + if ( !(*it).isEmpty() ) + out << "#include \"" << *it << "\"" << endl; + } + out << endl; + + // forward declarations for child widgets and layouts + out << "class TQVBoxLayout;" << endl; + out << "class TQHBoxLayout;" << endl; + out << "class TQGridLayout;" << endl; + out << "class TQSpacerItem;" << endl; + if ( objClass == "TQMainWindow" ) { + out << "class TQAction;" << endl; + out << "class TQActionGroup;" << endl; + out << "class TQToolBar;" << endl; + out << "class TQPopupMenu;" << endl; + } + + bool dbForm = FALSE; + registerDatabases( e ); + dbConnections = unique( dbConnections ); + if ( dbConnections.count() ) + forwardDecl += "TQSqlDatabase"; + if ( dbCursors.count() ) + forwardDecl += "TQSqlCursor"; + if ( dbForms[ "(default)" ].count() ) + dbForm = TRUE; + bool subDbForms = FALSE; + for ( it = dbConnections.begin(); it != dbConnections.end(); ++it ) { + if ( !(*it).isEmpty() && (*it) != "(default)" ) { + if ( dbForms[ (*it) ].count() ) { + subDbForms = TRUE; + break; + } + } + } + if ( dbForm || subDbForms ) + forwardDecl += "TQSqlForm"; + + for ( it = tags.begin(); it != tags.end(); ++it ) { + nl = e.parentNode().toElement().elementsByTagName( *it ); + for ( i = 1; i < (int) nl.length(); i++ ) { // begin at 1, 0 is the toplevel widget + TQString s = getClassName( nl.item(i).toElement() ); + if ( s == "TQLayoutWidget" ) + continue; // hide qlayoutwidgets + if ( s == "Line" ) + s = "TQFrame"; + if ( !(nofwd && customWidgets.contains(s)) ) + forwardDecl += s; + if ( s.mid( 2 ) == "ListBox" || s.mid( 2 ) == "ListView" || s.mid( 2 ) == "IconView" ) + forwardDecl += "TQ" + s.mid( 2 ) + "Item"; + if ( s == "TQDataTable" ) { // other convenience classes which are used in TQDataTable signals, and thus should be forward-declared by uic for us + forwardDecl += "TQSqlRecord"; + } + } + } + + // some typedefs, maybe + typeDefs = unique( typeDefs ); + for ( it = typeDefs.begin(); it != typeDefs.end(); ++it ) { + if ( !(*it).isEmpty() ) + out << "typedef " << *it << ";" << endl; + } + + nl = e.parentNode().toElement().elementsByTagName( "forward" ); + for ( i = 0; i < (int) nl.length(); i++ ) + forwardDecl2 << nl.item(i).toElement().firstChild().toText().data(); + + nl = e.parentNode().toElement().elementsByTagName( "include" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + TQDomElement n2 = nl.item(i).toElement(); + TQString s = n2.firstChild().toText().data(); + if ( n2.attribute( "impldecl", "in implementation" ) == "in declaration" && + n2.attribute( "location" ) != "local" ) + globalIncludes += s; + } + for ( i = 0; i < (int) nl.length(); i++ ) { + TQDomElement n2 = nl.item(i).toElement(); + TQString s = n2.firstChild().toText().data(); + if ( n2.attribute( "impldecl", "in implementation" ) == "in declaration" && + n2.attribute( "location" ) == "local" &&!globalIncludes.contains( s ) ) + localIncludes += s; + } + nl = e.parentNode().toElement().elementsByTagName( "exportmacro" ); + if ( nl.length() == 1 ) + exportMacro = nl.item( 0 ).firstChild().toText().data(); + + forwardDecl = unique( forwardDecl ); + for ( it = forwardDecl.begin(); it != forwardDecl.end(); ++it ) { + if ( !(*it).isEmpty() && (*it) != objClass ) { + TQString forwardName = *it; + TQStringList forwardNamespaces = TQStringList::split( "::", + forwardName ); + forwardName = forwardNamespaces.last(); + forwardNamespaces.remove( forwardNamespaces.fromLast() ); + + TQStringList::ConstIterator ns = forwardNamespaces.begin(); + while ( ns != forwardNamespaces.end() ) { + out << "namespace " << *ns << " {" << endl; + ++ns; + } + out << "class " << forwardName << ";" << endl; + for ( int i = 0; i < (int) forwardNamespaces.count(); i++ ) + out << "}" << endl; + } + } + + for ( it = forwardDecl2.begin(); it != forwardDecl2.end(); ++it ) { + TQString fd = *it; + fd = fd.stripWhiteSpace(); + if ( !fd.endsWith( ";" ) ) + fd += ";"; + out << fd << endl; + } + + out << endl; + + TQStringList::ConstIterator ns = namespaces.begin(); + while ( ns != namespaces.end() ) { + out << "namespace " << *ns << " {" << endl; + ++ns; + } + + out << "class "; + if ( !exportMacro.isEmpty() ) + out << exportMacro << " "; + out << bareNameOfClass << " : public " << objClass << endl << "{" << endl; + + /* qmake ignore Q_OBJECT */ + out << " Q_OBJECT" << endl; + out << endl; + out << "public:" << endl; + + // constructor + if ( objClass == "TQDialog" || objClass == "TQWizard" ) { + out << " " << bareNameOfClass << "( TQWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 );" << endl; + } else if ( objClass == "TQWidget" ) { + out << " " << bareNameOfClass << "( TQWidget* parent = 0, const char* name = 0, WFlags fl = 0 );" << endl; + } else if ( objClass == "TQMainWindow" ) { + out << " " << bareNameOfClass << "( TQWidget* parent = 0, const char* name = 0, WFlags fl = WType_TopLevel );" << endl; + isMainWindow = TRUE; + } else { + out << " " << bareNameOfClass << "( TQWidget* parent = 0, const char* name = 0 );" << endl; + } + + // destructor + out << " ~" << bareNameOfClass << "();" << endl; + out << endl; + + // children + bool needPolish = FALSE; + nl = e.parentNode().toElement().elementsByTagName( "widget" ); + for ( i = 1; i < (int) nl.length(); i++ ) { // start at 1, 0 is the toplevel widget + n = nl.item(i).toElement(); + createObjectDecl( n ); + TQString t = n.tagName(); + if ( t == "vbox" || t == "hbox" || t == "grid" ) + createSpacerDecl( n ); + TQString s = getClassName( n ); + if ( s == "TQDataTable" || s == "TQDataBrowser" ) { + if ( isFrameworkCodeGenerated( n ) ) + needPolish = TRUE; + } + } + + // actions, toolbars, menus + for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "actions" ) { + for ( TQDomElement a = n.firstChild().toElement(); !a.isNull(); a = a.nextSibling().toElement() ) + createActionDecl( a ); + } else if ( n.tagName() == "toolbars" ) { + for ( TQDomElement a = n.firstChild().toElement(); !a.isNull(); a = a.nextSibling().toElement() ) + createToolbarDecl( a ); + } else if ( n.tagName() == "menubar" ) { + out << " " << "TQMenuBar *" << getObjectName( n ) << ";" << endl; + for ( TQDomElement a = n.firstChild().toElement(); !a.isNull(); a = a.nextSibling().toElement() ) + createMenuBarDecl( a ); + } + } + out << endl; + + // database connections + dbConnections = unique( dbConnections ); + bool hadOutput = FALSE; + for ( it = dbConnections.begin(); it != dbConnections.end(); ++it ) { + if ( !(*it).isEmpty() ) { + // only need pointers to non-default connections + if ( (*it) != "(default)" && !(*it).isEmpty() ) { + out << indent << "TQSqlDatabase* " << *it << "Connection;" << endl; + hadOutput = TRUE; + } + } + } + if ( hadOutput ) + out << endl; + + TQStringList publicSlots, protectedSlots, privateSlots; + TQStringList publicSlotTypes, protectedSlotTypes, privateSlotTypes; + TQStringList publicSlotSpecifier, protectedSlotSpecifier, privateSlotSpecifier; + + nl = e.parentNode().toElement().elementsByTagName( "slot" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + n = nl.item(i).toElement(); + if ( n.parentNode().toElement().tagName() != "slots" + && n.parentNode().toElement().tagName() != "connections" ) + continue; + if ( n.attribute( "language", "C++" ) != "C++" ) + continue; + TQString returnType = n.attribute( "returnType", "void" ); + TQString functionName = n.firstChild().toText().data().stripWhiteSpace(); + if ( functionName.endsWith( ";" ) ) + functionName = functionName.left( functionName.length() - 1 ); + TQString specifier = n.attribute( "specifier" ); + TQString access = n.attribute( "access" ); + if ( access == "protected" ) { + protectedSlots += functionName; + protectedSlotTypes += returnType; + protectedSlotSpecifier += specifier; + } else if ( access == "private" ) { + privateSlots += functionName; + privateSlotTypes += returnType; + privateSlotSpecifier += specifier; + } else { + publicSlots += functionName; + publicSlotTypes += returnType; + publicSlotSpecifier += specifier; + } + } + + TQStringList publicFuncts, protectedFuncts, privateFuncts; + TQStringList publicFunctRetTyp, protectedFunctRetTyp, privateFunctRetTyp; + TQStringList publicFunctSpec, protectedFunctSpec, privateFunctSpec; + + nl = e.parentNode().toElement().elementsByTagName( "function" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + n = nl.item( i ).toElement(); + if ( n.parentNode().toElement().tagName() != "functions" ) + continue; + if ( n.attribute( "language", "C++" ) != "C++" ) + continue; + TQString returnType = n.attribute( "returnType", "void" ); + TQString functionName = n.firstChild().toText().data().stripWhiteSpace(); + if ( functionName.endsWith( ";" ) ) + functionName = functionName.left( functionName.length() - 1 ); + TQString specifier = n.attribute( "specifier" ); + TQString access = n.attribute( "access" ); + if ( access == "protected" ) { + protectedFuncts += functionName; + protectedFunctRetTyp += returnType; + protectedFunctSpec += specifier; + } else if ( access == "private" ) { + privateFuncts += functionName; + privateFunctRetTyp += returnType; + privateFunctSpec += specifier; + } else { + publicFuncts += functionName; + publicFunctRetTyp += returnType; + publicFunctSpec += specifier; + } + } + + TQStringList publicVars, protectedVars, privateVars; + nl = e.parentNode().toElement().elementsByTagName( "variable" ); + for ( i = 0; i < (int)nl.length(); i++ ) { + n = nl.item( i ).toElement(); + // Because of compatibility the next lines have to be commented out. + // Someday it should be uncommented. + //if ( n.parentNode().toElement().tagName() != "variables" ) + // continue; + TQString access = n.attribute( "access", "protected" ); + TQString var = n.firstChild().toText().data().stripWhiteSpace(); + if (var.isEmpty()) + continue; + if ( !var.endsWith( ";" ) ) + var += ";"; + if ( access == "public" ) + publicVars += var; + else if ( access == "private" ) + privateVars += var; + else + protectedVars += var; + } + + if ( !publicVars.isEmpty() ) { + for ( it = publicVars.begin(); it != publicVars.end(); ++it ) + out << indent << *it << endl; + out << endl; + } + if ( !publicFuncts.isEmpty() ) + writeFunctionsDecl( publicFuncts, publicFunctRetTyp, publicFunctSpec ); + + if ( needPolish || !publicSlots.isEmpty() ) { + out << "public slots:" << endl; + if ( needPolish ) { + out << indent << "virtual void polish();" << endl; + out << endl; + } + if ( !publicSlots.isEmpty() ) + writeFunctionsDecl( publicSlots, publicSlotTypes, publicSlotSpecifier ); + } + + // find signals + TQStringList extraSignals; + nl = e.parentNode().toElement().elementsByTagName( "signal" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + n = nl.item( i ).toElement(); + if ( n.parentNode().toElement().tagName() != "signals" + && n.parentNode().toElement().tagName() != "connections" ) + continue; + if ( n.attribute( "language", "C++" ) != "C++" ) + continue; + TQString sigName = n.firstChild().toText().data().stripWhiteSpace(); + if ( sigName.endsWith( ";" ) ) + sigName = sigName.left( sigName.length() - 1 ); + extraSignals += sigName; + } + + // create signals + if ( !extraSignals.isEmpty() ) { + out << "signals:" << endl; + for ( it = extraSignals.begin(); it != extraSignals.end(); ++it ) + out << " void " << (*it) << ";" << endl; + out << endl; + } + + out << "protected:" << endl; + if ( !protectedVars.isEmpty() ) { + for ( it = protectedVars.begin(); it != protectedVars.end(); ++it ) + out << indent << *it << endl; + out << endl; + } + if ( !protectedFuncts.isEmpty() ) + writeFunctionsDecl( protectedFuncts, protectedFunctRetTyp, protectedFunctSpec ); + + // child layouts + registerLayouts( e ); + out << endl; + +#if QT_VERSION >= 0x030900 +#error Make languageChange() a virtual protected non-slot member of TQWidget +#endif + + out << "protected slots:" << endl; + out << " virtual void languageChange();" << endl; + if ( !protectedSlots.isEmpty() ) { + out << endl; + writeFunctionsDecl( protectedSlots, protectedSlotTypes, protectedSlotSpecifier ); + } + out << endl; + + // create all private stuff + if ( !privateFuncts.isEmpty() || !privateVars.isEmpty() || !imageMembers.isEmpty() ) { + out << "private:" << endl; + if ( !privateVars.isEmpty() ) { + for ( it = privateVars.begin(); it != privateVars.end(); ++it ) + out << indent << *it << endl; + out << endl; + } + if ( !imageMembers.isEmpty() ) { + out << imageMembers; + out << endl; + } + if ( !privateFuncts.isEmpty() ) + writeFunctionsDecl( privateFuncts, privateFunctRetTyp, privateFunctSpec ); + } + + if ( !privateSlots.isEmpty() ) { + out << "private slots:" << endl; + writeFunctionsDecl( privateSlots, privateSlotTypes, privateSlotSpecifier ); + } + + out << "};" << endl; + for ( i = 0; i < (int) namespaces.count(); i++ ) + out << "}" << endl; + + out << endl; + out << "#endif // " << protector << endl; +} + +void Uic::writeFunctionsDecl( const TQStringList &fuLst, const TQStringList &typLst, const TQStringList &specLst ) +{ + TQValueListConstIterator<TQString> it, it2, it3; + for ( it = fuLst.begin(), it2 = typLst.begin(), it3 = specLst.begin(); + it != fuLst.end(); ++it, ++it2, ++it3 ) { + TQString signature = *it; + TQString specifier; + TQString pure; + TQString type = *it2; + if ( type.isEmpty() ) + type = "void"; + if ( *it3 == "static" ) { + specifier = "static "; + } else { + if ( *it3 != "non virtual" && *it3 != "nonVirtual" ) + specifier = "virtual "; + if ( *it3 == "pure virtual" || *it3 == "pureVirtual" ) + pure = " = 0"; + } + type.replace( ">>", "> >" ); + if ( !signature.contains("operator") ) + signature.replace( ">>", "> >" ); + out << " " << specifier << type << " " << signature << pure << ";" << endl; + } + out << endl; +} + +/*! + Creates an implementation (cpp-file) for the form given in \a e. + + \sa createFormDecl(), createObjectImpl() + */ +void Uic::createFormImpl( const TQDomElement &e ) +{ + TQDomElement n; + TQDomNodeList nl; + int i; + TQString objClass = getClassName( e ); + if ( objClass.isEmpty() ) + return; + TQString objName = getObjectName( e ); + + // generate local and local includes retquired + TQStringList globalIncludes, localIncludes; + TQStringList::Iterator it; + + TQMap<TQString, CustomInclude> customWidgetIncludes; + + // find additional slots and functions + TQStringList extraFuncts; + TQStringList extraFunctTyp; + TQStringList extraFunctSpecifier; + + nl = e.parentNode().toElement().elementsByTagName( "slot" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + n = nl.item(i).toElement(); + if ( n.parentNode().toElement().tagName() != "slots" + && n.parentNode().toElement().tagName() != "connections" ) + continue; + if ( n.attribute( "language", "C++" ) != "C++" ) + continue; + TQString functionName = n.firstChild().toText().data().stripWhiteSpace(); + if ( functionName.endsWith( ";" ) ) + functionName = functionName.left( functionName.length() - 1 ); + extraFuncts += functionName; + extraFunctTyp += n.attribute( "returnType", "void" ); + extraFunctSpecifier += n.attribute( "specifier", "virtual" ); + } + + nl = e.parentNode().toElement().elementsByTagName( "function" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + n = nl.item(i).toElement(); + if ( n.parentNode().toElement().tagName() != "functions" ) + continue; + if ( n.attribute( "language", "C++" ) != "C++" ) + continue; + TQString functionName = n.firstChild().toText().data().stripWhiteSpace(); + if ( functionName.endsWith( ";" ) ) + functionName = functionName.left( functionName.length() - 1 ); + extraFuncts += functionName; + extraFunctTyp += n.attribute( "returnType", "void" ); + extraFunctSpecifier += n.attribute( "specifier", "virtual" ); + } + + for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "customwidgets" ) { + TQDomElement n2 = n.firstChild().toElement(); + while ( !n2.isNull() ) { + if ( n2.tagName() == "customwidget" ) { + TQDomElement n3 = n2.firstChild().toElement(); + TQString cl; + WidgetDatabaseRecord *r = new WidgetDatabaseRecord; + while ( !n3.isNull() ) { + if ( n3.tagName() == "class" ) { + cl = n3.firstChild().toText().data(); + r->name = cl; + } else if ( n3.tagName() == "header" ) { + CustomInclude ci; + ci.header = n3.firstChild().toText().data(); + ci.location = n3.attribute( "location", "global" ); + r->includeFile = ci.header; + customWidgetIncludes.insert( cl, ci ); + } + WidgetDatabase::append( r ); + n3 = n3.nextSibling().toElement(); + } + } + n2 = n2.nextSibling().toElement(); + } + } + } + + // additional includes (local or global) and forward declaractions + nl = e.parentNode().toElement().elementsByTagName( "include" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + TQDomElement n2 = nl.item(i).toElement(); + TQString s = n2.firstChild().toText().data(); + if ( n2.attribute( "location" ) != "local" ) { + if ( s.right( 5 ) == ".ui.h" && !TQFile::exists( s ) ) + continue; + if ( n2.attribute( "impldecl", "in implementation" ) != "in implementation" ) + continue; + globalIncludes += s; + } + } + + registerDatabases( e ); + dbConnections = unique( dbConnections ); + if ( dbConnections.count() ) + globalIncludes += "qsqldatabase.h"; + if ( dbCursors.count() ) + globalIncludes += "qsqlcursor.h"; + bool dbForm = FALSE; + if ( dbForms[ "(default)" ].count() ) + dbForm = TRUE; + bool subDbForms = FALSE; + for ( it = dbConnections.begin(); it != dbConnections.end(); ++it ) { + if ( !(*it).isEmpty() && (*it) != "(default)" ) { + if ( dbForms[ (*it) ].count() ) { + subDbForms = TRUE; + break; + } + } + } + if ( dbForm || subDbForms ) { + globalIncludes += "qsqlform.h"; + globalIncludes += "qsqlrecord.h"; + } + + // do the local includes afterwards, since global includes have priority on clashes + for ( i = 0; i < (int) nl.length(); i++ ) { + TQDomElement n2 = nl.item(i).toElement(); + TQString s = n2.firstChild().toText().data(); + if ( n2.attribute( "location" ) == "local" &&!globalIncludes.contains( s ) ) { + if ( s.right( 5 ) == ".ui.h" && !TQFile::exists( s ) ) + continue; + if ( n2.attribute( "impldecl", "in implementation" ) != "in implementation" ) + continue; + localIncludes += s; + } + } + + // additional custom widget headers + nl = e.parentNode().toElement().elementsByTagName( "header" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + TQDomElement n2 = nl.item(i).toElement(); + TQString s = n2.firstChild().toText().data(); + if ( n2.attribute( "location" ) != "local" ) + globalIncludes += s; + else + localIncludes += s; + } + + // includes for child widgets + for ( it = tags.begin(); it != tags.end(); ++it ) { + nl = e.parentNode().toElement().elementsByTagName( *it ); + for ( i = 1; i < (int) nl.length(); i++ ) { // start at 1, 0 is the toplevel widget + TQString name = getClassName( nl.item(i).toElement() ); + if ( name == "Spacer" ) { + globalIncludes += "qlayout.h"; + globalIncludes += "qapplication.h"; + continue; + } + if ( name.mid( 2 ) == "ListView" ) + globalIncludes += "qheader.h"; + if ( name != objClass ) { + int wid = WidgetDatabase::idFromClassName( name ); + TQMap<TQString, CustomInclude>::Iterator it = customWidgetIncludes.find( name ); + if ( it == customWidgetIncludes.end() ) + globalIncludes += WidgetDatabase::includeFile( wid ); + } + } + } + + out << "#include <qvariant.h>" << endl; // first for gcc 2.7.2 + + globalIncludes = unique( globalIncludes ); + for ( it = globalIncludes.begin(); it != globalIncludes.end(); ++it ) { + if ( !(*it).isEmpty() ) + out << "#include <" << *it << ">" << endl; + } + + out << "#include <qlayout.h>" << endl; + out << "#include <qtooltip.h>" << endl; + out << "#include <qwhatsthis.h>" << endl; + if ( objClass == "TQMainWindow" ) { + out << "#include <qaction.h>" << endl; + out << "#include <qmenubar.h>" << endl; + out << "#include <qpopupmenu.h>" << endl; + out << "#include <qtoolbar.h>" << endl; + } + + // find out what images are retquired + TQStringList retquiredImages; + static const char *imgTags[] = { "pixmap", "iconset", 0 }; + for ( i = 0; imgTags[i] != 0; i++ ) { + nl = e.parentNode().toElement().elementsByTagName( imgTags[i] ); + for ( int j = 0; j < (int) nl.length(); j++ ) { + TQDomNode nn = nl.item(j); + while ( nn.parentNode() != e.parentNode() ) + nn = nn.parentNode(); + if ( nn.nodeName() != "customwidgets" ) + retquiredImages += nl.item(j).firstChild().toText().data(); + } + } + + if ( !retquiredImages.isEmpty() || externPixmaps ) { + out << "#include <qimage.h>" << endl; + out << "#include <qpixmap.h>" << endl << endl; + } + + /* + Put local includes after all global includes + */ + localIncludes = unique( localIncludes ); + for ( it = localIncludes.begin(); it != localIncludes.end(); ++it ) { + if ( !(*it).isEmpty() && *it != TQFileInfo( fileName + ".h" ).fileName() ) + out << "#include \"" << *it << "\"" << endl; + } + + TQString uiDotH = fileName + ".h"; + if ( TQFile::exists( uiDotH ) ) { + if ( !outputFileName.isEmpty() ) + uiDotH = combinePath( uiDotH, outputFileName ); + out << "#include \"" << uiDotH << "\"" << endl; + writeFunctImpl = FALSE; + } + + // register the object and unify its name + objName = registerObject( objName ); + + TQStringList images; + TQStringList xpmImages; + if ( pixmapLoaderFunction.isEmpty() && !externPixmaps ) { + // create images + for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "images" ) { + nl = n.elementsByTagName( "image" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + TQString img = registerObject( nl.item(i).toElement().attribute("name") ); + if ( !retquiredImages.contains( img ) ) + continue; + TQDomElement tmp = nl.item(i).firstChild().toElement(); + if ( tmp.tagName() != "data" ) + continue; + TQString format = tmp.attribute("format", "PNG" ); + TQString data = tmp.firstChild().toText().data(); + if ( format == "XPM.GZ" ) { + xpmImages += img; + ulong length = tmp.attribute("length").toULong(); + TQByteArray baunzip = unzipXPM( data, length ); + length = baunzip.size(); + // shouldn't we test the initial 'length' against the + // resulting 'length' to catch corrupt UIC files? + int a = 0; + int column = 0; + bool inQuote = FALSE; + out << "static const char* const " << img << "_data[] = { " << endl; + while ( baunzip[a] != '\"' ) + a++; + for ( ; a < (int) length; a++ ) { + out << baunzip[a]; + if ( baunzip[a] == '\n' ) { + column = 0; + } else if ( baunzip[a] == '"' ) { + inQuote = !inQuote; + } + + if ( column++ >= 511 && inQuote ) { + out << "\"\n\""; // be nice with MSVC & Co. + column = 1; + } + } + out << endl; + } else { + images += img; + out << "static const unsigned char " << img << "_data[] = { " << endl; + out << " "; + int a ; + for ( a = 0; a < (int) (data.length()/2)-1; a++ ) { + out << "0x" << TQString(data[2*a]) << TQString(data[2*a+1]) << ","; + if ( a % 12 == 11 ) + out << endl << " "; + else + out << " "; + } + out << "0x" << TQString(data[2*a]) << TQString(data[2*a+1]) << endl; + out << "};" << endl << endl; + } + } + } + } + out << endl; + } else if ( externPixmaps ) { + pixmapLoaderFunction = "TQPixmap::fromMimeSource"; + } + + // constructor + if ( objClass == "TQDialog" || objClass == "TQWizard" ) { + out << "/*" << endl; + out << " * Constructs a " << nameOfClass << " as a child of 'parent', with the" << endl; + out << " * name 'name' and widget flags set to 'f'." << endl; + out << " *" << endl; + out << " * The " << objClass.mid(1).lower() << " will by default be modeless, unless you set 'modal' to" << endl; + out << " * TRUE to construct a modal " << objClass.mid(1).lower() << "." << endl; + out << " */" << endl; + out << nameOfClass << "::" << bareNameOfClass << "( TQWidget* parent, const char* name, bool modal, WFlags fl )" << endl; + out << " : " << objClass << "( parent, name, modal, fl )"; + } else if ( objClass == "TQWidget" ) { + out << "/*" << endl; + out << " * Constructs a " << nameOfClass << " as a child of 'parent', with the" << endl; + out << " * name 'name' and widget flags set to 'f'." << endl; + out << " */" << endl; + out << nameOfClass << "::" << bareNameOfClass << "( TQWidget* parent, const char* name, WFlags fl )" << endl; + out << " : " << objClass << "( parent, name, fl )"; + } else if ( objClass == "TQMainWindow" ) { + out << "/*" << endl; + out << " * Constructs a " << nameOfClass << " as a child of 'parent', with the" << endl; + out << " * name 'name' and widget flags set to 'f'." << endl; + out << " *" << endl; + out << " */" << endl; + out << nameOfClass << "::" << bareNameOfClass << "( TQWidget* parent, const char* name, WFlags fl )" << endl; + out << " : " << objClass << "( parent, name, fl )"; + isMainWindow = TRUE; + } else { + out << "/*" << endl; + out << " * Constructs a " << nameOfClass << " which is a child of 'parent', with the" << endl; + out << " * name 'name'.' " << endl; + out << " */" << endl; + out << nameOfClass << "::" << bareNameOfClass << "( TQWidget* parent, const char* name )" << endl; + out << " : " << objClass << "( parent, name )"; + } + + // create pixmaps for all images + if ( !xpmImages.isEmpty() ) { + for ( it = xpmImages.begin(); it != xpmImages.end(); ++it ) { + out << "," << endl; + out << indent << " " << *it << "( (const char **) " << (*it) << "_data )"; + } + } + out << endl; + + out << "{" << endl; + if ( isMainWindow ) + out << indent << "(void)statusBar();" << endl; + + if ( !images.isEmpty() ) { + out << indent << "TQImage img;" << endl; + for ( it = images.begin(); it != images.end(); ++it ) { + out << indent << "img.loadFromData( " << (*it) << "_data, sizeof( " << (*it) << "_data ), \"PNG\" );" << endl; + out << indent << (*it) << " = img;" << endl; + } + } + + // set the properties + TQSize geometry( 0, 0 ); + + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "property" ) { + bool stdset = stdsetdef; + if ( n.hasAttribute( "stdset" ) ) + stdset = toBool( n.attribute( "stdset" ) ); + TQString prop = n.attribute("name"); + TQDomElement n2 = n.firstChild().toElement(); + TQString value = setObjectProperty( objClass, TQString::null, prop, n2, stdset ); + if ( value.isEmpty() ) + continue; + + if ( prop == "geometry" && n2.tagName() == "rect" ) { + TQDomElement n3 = n2.firstChild().toElement(); + while ( !n3.isNull() ) { + if ( n3.tagName() == "width" ) + geometry.setWidth( n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "height" ) + geometry.setHeight( n3.firstChild().toText().data().toInt() ); + n3 = n3.nextSibling().toElement(); + } + } else { + TQString call; + if ( stdset ) { + call = mkStdSet( prop ) + "( "; + } else { + call = "setProperty( \"" + prop + "\", "; + } + call += value + " );"; + + if ( n2.tagName() == "string" ) { + trout << indent << call << endl; + } else if ( prop == "name" ) { + out << indent << "if ( !name )" << endl; + out << "\t" << call << endl; + } else { + out << indent << call << endl; + } + } + } + } + + // create all children, some forms have special retquirements + + if ( objClass == "TQWizard" ) { + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( tags.contains( n.tagName() ) ) { + TQString page = createObjectImpl( n, objClass, "this" ); + TQString comment; + TQString label = DomTool::readAttribute( n, "title", "", comment ).toString(); + out << indent << "addPage( " << page << ", TQString(\"\") );" << endl; + trout << indent << "setTitle( " << page << ", " << trcall( label, comment ) << " );" << endl; + TQVariant def( FALSE, 0 ); + if ( DomTool::hasAttribute( n, "backEnabled" ) ) + out << indent << "setBackEnabled( " << page << ", " << mkBool( DomTool::readAttribute( n, "backEnabled", def).toBool() ) << endl; + if ( DomTool::hasAttribute( n, "nextEnabled" ) ) + out << indent << "setNextEnabled( " << page << ", " << mkBool( DomTool::readAttribute( n, "nextEnabled", def).toBool() ) << endl; + if ( DomTool::hasAttribute( n, "finishEnabled" ) ) + out << indent << "setFinishEnabled( " << page << ", " << mkBool( DomTool::readAttribute( n, "finishEnabled", def).toBool() ) << " );" << endl; + if ( DomTool::hasAttribute( n, "helpEnabled" ) ) + out << indent << "setHelpEnabled( " << page << ", " << mkBool( DomTool::readAttribute( n, "helpEnabled", def).toBool() ) << endl; + if ( DomTool::hasAttribute( n, "finish" ) ) + out << indent << "setFinish( " << page << ", " << mkBool( DomTool::readAttribute( n, "finish", def).toBool() ) << endl; + } + } + } else { // standard widgets + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( tags.contains( n.tagName() ) ) + createObjectImpl( n, objName, "this" ); + } + } + + // database support + dbConnections = unique( dbConnections ); + if ( dbConnections.count() ) + out << endl; + for ( it = dbConnections.begin(); it != dbConnections.end(); ++it ) { + if ( !(*it).isEmpty() && (*it) != "(default)") { + out << indent << (*it) << "Connection = TQSqlDatabase::database( \"" <<(*it) << "\" );" << endl; + } + } + + nl = e.parentNode().toElement().elementsByTagName( "widget" ); + for ( i = 1; i < (int) nl.length(); i++ ) { // start at 1, 0 is the toplevel widget + n = nl.item(i).toElement(); + TQString s = getClassName( n ); + if ( (dbForm || subDbForms) && (s == "TQDataBrowser" || s == "TQDataView") ) { + TQString objName = getObjectName( n ); + TQString tab = getDatabaseInfo( n, "table" ); + TQString con = getDatabaseInfo( n, "connection" ); + out << indent << "TQSqlForm* " << objName << "Form = new TQSqlForm( this, \"" << objName << "Form\" );" << endl; + TQDomElement n2; + for ( n2 = n.firstChild().toElement(); !n2.isNull(); n2 = n2.nextSibling().toElement() ) + createFormImpl( n2, objName, con, tab ); + out << indent << objName << "->setForm( " << objName << "Form );" << endl; + } + } + + // actions, toolbars, menubar + bool needEndl = FALSE; + for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "actions" ) { + if ( !needEndl ) + out << endl << indent << "// actions" << endl; + createActionImpl( n.firstChild().toElement(), "this" ); + needEndl = TRUE; + } + } + if ( needEndl ) + out << endl; + needEndl = FALSE; + for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "toolbars" ) { + if ( !needEndl ) + out << endl << indent << "// toolbars" << endl; + createToolbarImpl( n, objClass, objName ); + needEndl = TRUE; + } + } + if ( needEndl ) + out << endl; + needEndl = FALSE; + for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "menubar" ) { + if ( !needEndl ) + out << endl << indent << "// menubar" << endl; + createMenuBarImpl( n, objClass, objName ); + needEndl = TRUE; + } + } + if ( needEndl ) + out << endl; + + out << indent << "languageChange();" << endl; + + // take minimumSizeHint() into account, for height-for-width widgets + if ( !geometry.isNull() ) { + out << indent << "resize( TQSize(" << geometry.width() << ", " + << geometry.height() << ").expandedTo(minimumSizeHint()) );" << endl; + out << indent << "clearWState( WState_Polished );" << endl; + } + + for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "connections" ) { + // setup signals and slots connections + out << endl << indent << "// signals and slots connections" << endl; + nl = n.elementsByTagName( "connection" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + TQString sender, receiver, signal, slot; + for ( TQDomElement n2 = nl.item(i).firstChild().toElement(); !n2.isNull(); n2 = n2.nextSibling().toElement() ) { + if ( n2.tagName() == "sender" ) + sender = n2.firstChild().toText().data(); + else if ( n2.tagName() == "receiver" ) + receiver = n2.firstChild().toText().data(); + else if ( n2.tagName() == "signal" ) + signal = n2.firstChild().toText().data(); + else if ( n2.tagName() == "slot" ) + slot = n2.firstChild().toText().data(); + } + if ( sender.isEmpty() || + receiver.isEmpty() || + signal.isEmpty() || + slot.isEmpty() ) + continue; + if ( sender[0] == '<' || + receiver[0] == '<' || + signal[0] == '<' || + slot[0] == '<' ) + continue; + + sender = registeredName( sender ); + receiver = registeredName( receiver ); + + // translate formwindow name to "this" + if ( sender == objName ) + sender = "this"; + if ( receiver == objName ) + receiver = "this"; + + out << indent << "connect( " << sender << ", SIGNAL( " << signal << " ), " + << receiver << ", SLOT( " << slot << " ) );" << endl; + } + } else if ( n.tagName() == "tabstops" ) { + // setup tab order + out << endl << indent << "// tab order" << endl; + TQString lastName; + TQDomElement n2 = n.firstChild().toElement(); + while ( !n2.isNull() ) { + if ( n2.tagName() == "tabstop" ) { + TQString name = n2.firstChild().toText().data(); + name = registeredName( name ); + if ( !lastName.isEmpty() ) + out << indent << "setTabOrder( " << lastName << ", " << name << " );" << endl; + lastName = name; + } + n2 = n2.nextSibling().toElement(); + } + } + } + + // buddies + bool firstBuddy = TRUE; + for ( TQValueList<Buddy>::Iterator buddy = buddies.begin(); buddy != buddies.end(); ++buddy ) { + if ( isObjectRegistered( (*buddy).buddy ) ) { + if ( firstBuddy ) { + out << endl << indent << "// buddies" << endl; + } + out << indent << (*buddy).key << "->setBuddy( " << registeredName( (*buddy).buddy ) << " );" << endl; + firstBuddy = FALSE; + } + } + + if ( extraFuncts.find( "init()" ) != extraFuncts.end() ) + out << indent << "init();" << endl; + + // end of constructor + out << "}" << endl; + out << endl; + + // destructor + out << "/*" << endl; + out << " * Destroys the object and frees any allocated resources" << endl; + out << " */" << endl; + out << nameOfClass << "::~" << bareNameOfClass << "()" << endl; + out << "{" << endl; + if ( extraFuncts.find( "destroy()" ) != extraFuncts.end() ) + out << indent << "destroy();" << endl; + out << indent << "// no need to delete child widgets, TQt does it all for us" << endl; + out << "}" << endl; + out << endl; + + // handle application events if retquired + bool needFontEventHandler = FALSE; + bool needSqlTableEventHandler = FALSE; + bool needSqlDataBrowserEventHandler = FALSE; + nl = e.elementsByTagName( "widget" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + if ( !DomTool::propertiesOfType( nl.item(i).toElement() , "font" ).isEmpty() ) + needFontEventHandler = TRUE; + TQString s = getClassName( nl.item(i).toElement() ); + if ( s == "TQDataTable" || s == "TQDataBrowser" ) { + if ( !isFrameworkCodeGenerated( nl.item(i).toElement() ) ) + continue; + if ( s == "TQDataTable" ) + needSqlTableEventHandler = TRUE; + if ( s == "TQDataBrowser" ) + needSqlDataBrowserEventHandler = TRUE; + } + if ( needFontEventHandler && needSqlTableEventHandler && needSqlDataBrowserEventHandler ) + break; + } + if ( needFontEventHandler && FALSE ) { + // indent = "\t"; // increase indentation for if-clause below + out << "/*" << endl; + out << " * Main event handler. Reimplemented to handle" << endl; + out << " * application font changes"; + out << " */" << endl; + out << "bool " << nameOfClass << "::event( TQEvent* ev )" << endl; + out << "{" << endl; + out << " bool ret = " << objClass << "::event( ev ); " << endl; + if ( needFontEventHandler ) { + indent += "\t"; + out << " if ( ev->type() == TQEvent::ApplicationFontChange ) {" << endl; + for ( i = 0; i < (int) nl.length(); i++ ) { + n = nl.item(i).toElement(); + TQStringList list = DomTool::propertiesOfType( n, "font" ); + for ( it = list.begin(); it != list.end(); ++it ) + createExclusiveProperty( n, *it ); + } + out << " }" << endl; + indent = " "; + } + out << "}" << endl; + out << endl; + } + + if ( needSqlTableEventHandler || needSqlDataBrowserEventHandler ) { + out << "/*" << endl; + out << " * Widget polish. Reimplemented to handle" << endl; + if ( needSqlTableEventHandler ) + out << " * default data table initialization" << endl; + if ( needSqlDataBrowserEventHandler ) + out << " * default data browser initialization" << endl; + out << " */" << endl; + out << "void " << nameOfClass << "::polish()" << endl; + out << "{" << endl; + if ( needSqlTableEventHandler ) { + for ( i = 0; i < (int) nl.length(); i++ ) { + TQString s = getClassName( nl.item(i).toElement() ); + if ( s == "TQDataTable" ) { + n = nl.item(i).toElement(); + TQString c = getObjectName( n ); + TQString conn = getDatabaseInfo( n, "connection" ); + TQString tab = getDatabaseInfo( n, "table" ); + if ( !( conn.isEmpty() || tab.isEmpty() || !isFrameworkCodeGenerated( nl.item(i).toElement() ) ) ) { + out << indent << "if ( " << c << " ) {" << endl; + out << indent << indent << "TQSqlCursor* cursor = " << c << "->sqlCursor();" << endl; + out << indent << indent << "if ( !cursor ) {" << endl; + if ( conn == "(default)" ) + out << indent << indent << indent << "cursor = new TQSqlCursor( \"" << tab << "\" );" << endl; + else + out << indent << indent << indent << "cursor = new TQSqlCursor( \"" << tab << "\", TRUE, " << conn << "Connection );" << endl; + out << indent << indent << indent << "if ( " << c << "->isReadOnly() ) " << endl; + out << indent << indent << indent << indent << "cursor->setMode( TQSqlCursor::ReadOnly );" << endl; + out << indent << indent << indent << c << "->setSqlCursor( cursor, FALSE, TRUE );" << endl; + out << indent << indent << "}" << endl; + out << indent << indent << "if ( !cursor->isActive() )" << endl; + out << indent << indent << indent << c << "->refresh( TQDataTable::RefreshAll );" << endl; + out << indent << "}" << endl; + } + } + } + } + if ( needSqlDataBrowserEventHandler ) { + nl = e.elementsByTagName( "widget" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + TQString s = getClassName( nl.item(i).toElement() ); + if ( s == "TQDataBrowser" ) { + TQString obj = getObjectName( nl.item(i).toElement() ); + TQString tab = getDatabaseInfo( nl.item(i).toElement(), + "table" ); + TQString conn = getDatabaseInfo( nl.item(i).toElement(), + "connection" ); + if ( !(tab.isEmpty() || !isFrameworkCodeGenerated( nl.item(i).toElement() ) ) ) { + out << indent << "if ( " << obj << " ) {" << endl; + out << indent << indent << "if ( !" << obj << "->sqlCursor() ) {" << endl; + if ( conn == "(default)" ) + out << indent << indent << indent << "TQSqlCursor* cursor = new TQSqlCursor( \"" << tab << "\" );" << endl; + else + out << indent << indent << indent << "TQSqlCursor* cursor = new TQSqlCursor( \"" << tab << "\", TRUE, " << conn << "Connection );" << endl; + out << indent << indent << indent << obj << "->setSqlCursor( cursor, TRUE );" << endl; + out << indent << indent << indent << obj << "->refresh();" << endl; + out << indent << indent << indent << obj << "->first();" << endl; + out << indent << indent << "}" << endl; + out << indent << "}" << endl; + } + } + } + } + out << indent << objClass << "::polish();" << endl; + out << "}" << endl; + out << endl; + } + + out << "/*" << endl; + out << " * Sets the strings of the subwidgets using the current" << endl; + out << " * language." << endl; + out << " */" << endl; + out << "void " << nameOfClass << "::languageChange()" << endl; + out << "{" << endl; + out << languageChangeBody; + out << "}" << endl; + out << endl; + + // create stubs for additional slots if necessary + if ( !extraFuncts.isEmpty() && writeFunctImpl ) { + it = extraFuncts.begin(); + TQStringList::Iterator it2 = extraFunctTyp.begin(); + TQStringList::Iterator it3 = extraFunctSpecifier.begin(); + while ( it != extraFuncts.end() ) { + TQString type = *it2; + if ( type.isEmpty() ) + type = "void"; + type = type.simplifyWhiteSpace(); + TQString fname = Parser::cleanArgs( *it ); + if ( !(*it3).startsWith("pure") ) { // "pure virtual" or "pureVirtual" + out << type << " " << nameOfClass << "::" << fname << endl; + out << "{" << endl; + if ( *it != "init()" && *it != "destroy()" ) { + TQRegExp numeric( "^(?:signed|unsigned|u?char|u?short|u?int" + "|u?long|Q_U?INT(?:8|16|32)|Q_U?LONG|float" + "|double)$" ); + TQString retVal; + + /* + We return some kind of dummy value to shut the + compiler up. + + 1. If the type is 'void', we return nothing. + + 2. If the type is 'bool', we return 'FALSE'. + + 3. If the type is 'unsigned long' or + 'Q_UINT16' or 'double' or similar, we + return '0'. + + 4. If the type is 'Foo *', we return '0'. + + 5. If the type is 'Foo &', we create a static + variable of type 'Foo' and return it. + + 6. If the type is 'Foo', we assume there's a + default constructor and use it. + */ + if ( type != "void" ) { + TQStringList toks = TQStringList::split( " ", type ); + bool isBasicNumericType = + ( toks.grep(numeric).count() == toks.count() ); + + if ( type == "bool" ) { + retVal = "FALSE"; + } else if ( isBasicNumericType || type.endsWith("*") ) { + retVal = "0"; + } else if ( type.endsWith("&") ) { + do { + type.truncate( type.length() - 1 ); + } while ( type.endsWith(" ") ); + retVal = "uic_temp_var"; + out << indent << "static " << type << " " << retVal << ";" << endl; + } else { + retVal = type + "()"; + } + } + + out << indent << "qWarning( \"" << nameOfClass << "::" << fname << ": Not implemented yet\" );" << endl; + if ( !retVal.isEmpty() ) + out << indent << "return " << retVal << ";" << endl; + } + out << "}" << endl; + out << endl; + } + ++it; + ++it2; + ++it3; + } + } +} + + +/*! Creates form support implementation code for the widgets given + in \a e. + + Traverses recursively over all children. + */ + +void Uic::createFormImpl( const TQDomElement& e, const TQString& form, const TQString& connection, const TQString& table ) +{ + if ( e.tagName() == "widget" && + e.attribute( "class" ) != "TQDataTable" ) { + TQString field = getDatabaseInfo( e, "field" ); + if ( !field.isEmpty() ) { + if ( isWidgetInTable( e, connection, table ) ) + out << indent << form << "Form->insert( " << getObjectName( e ) << ", " << fixString( field ) << " );" << endl; + } + } + TQDomElement n; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + createFormImpl( n, form, connection, table ); + } +} |