diff options
Diffstat (limited to 'tools/designer/uic')
-rw-r--r-- | tools/designer/uic/embed.cpp | 316 | ||||
-rw-r--r-- | tools/designer/uic/form.cpp | 1452 | ||||
-rw-r--r-- | tools/designer/uic/main.cpp | 358 | ||||
-rw-r--r-- | tools/designer/uic/object.cpp | 745 | ||||
-rw-r--r-- | tools/designer/uic/subclassing.cpp | 352 | ||||
-rw-r--r-- | tools/designer/uic/uic.cpp | 1129 | ||||
-rw-r--r-- | tools/designer/uic/uic.h | 176 | ||||
-rw-r--r-- | tools/designer/uic/uic.pro | 42 |
8 files changed, 4570 insertions, 0 deletions
diff --git a/tools/designer/uic/embed.cpp b/tools/designer/uic/embed.cpp new file mode 100644 index 000000000..4baabd91c --- /dev/null +++ b/tools/designer/uic/embed.cpp @@ -0,0 +1,316 @@ +/********************************************************************** +** Copyright (C) 2000-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 sales@trolltech.com. +** +** 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 <qfile.h> +#include <qimage.h> +#include <qstringlist.h> +#include <qdatetime.h> +#include <qfileinfo.h> +#include <stdio.h> +#include <ctype.h> + +// on embedded, we do not compress image data. Rationale: by mapping +// the ready-only data directly into memory we are both faster and +// more memory efficient +#if defined(Q_WS_QWS) && !defined(QT_NO_IMAGE_COLLECTION_COMPRESSION) +#define QT_NO_IMAGE_COLLECTION_COMPRESSION +#endif + +struct EmbedImage +{ + ~EmbedImage() { delete[] colorTable; } + int width, height, depth; + int numColors; + TQRgb* colorTable; + TQString name; + TQString cname; + bool alpha; +#ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION + ulong compressed; +#endif +}; + +static TQString convertToCIdentifier( const char *s ) +{ + TQString r = s; + int len = r.length(); + if ( len > 0 && !isalpha( (char)r[0].latin1() ) ) + r[0] = '_'; + for ( int i=1; i<len; i++ ) { + if ( !isalnum( (char)r[i].latin1() ) ) + r[i] = '_'; + } + return r; +} + + +static ulong embedData( TQTextStream& out, const uchar* input, int nbytes ) +{ +#ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION + TQByteArray bazip( qCompress( input, nbytes ) ); + ulong len = bazip.size(); +#else + ulong len = nbytes; +#endif + static const char hexdigits[] = "0123456789abcdef"; + TQString s; + for ( int i=0; i<(int)len; i++ ) { + if ( (i%14) == 0 ) { + s += "\n "; + out << (const char*)s; + s.truncate( 0 ); + } + uint v = (uchar) +#ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION + bazip +#else + input +#endif + [i]; + s += "0x"; + s += hexdigits[(v >> 4) & 15]; + s += hexdigits[v & 15]; + if ( i < (int)len-1 ) + s += ','; + } + if ( s.length() ) + out << (const char*)s; + return len; +} + +static void embedData( TQTextStream& out, const TQRgb* input, int n ) +{ + out << hex; + const TQRgb *v = input; + for ( int i=0; i<n; i++ ) { + if ( (i%14) == 0 ) + out << "\n "; + out << "0x"; + out << hex << *v++; + if ( i < n-1 ) + out << ','; + } + out << dec; // back to decimal mode +} + +void Uic::embed( TQTextStream& out, const char* project, const TQStringList& images ) +{ + + TQString cProject = convertToCIdentifier( project ); + + TQStringList::ConstIterator it; + out << "/****************************************************************************\n"; + out << "** Image collection for project '" << project << "'.\n"; + out << "**\n"; + out << "** Generated from reading image files: \n"; + for ( it = images.begin(); it != images.end(); ++it ) + out << "** " << *it << "\n"; + out << "**\n"; + out << "** Created: " << TQDateTime::currentDateTime().toString() << "\n"; + out << "**\n"; + out << "** WARNING! All changes made in this file will be lost!\n"; + out << "****************************************************************************/\n"; + out << "\n"; + + out << "#include <qimage.h>\n"; + out << "#include <qdict.h>\n"; + out << "#include <qmime.h>\n"; + out << "#include <qdragobject.h>\n"; + out << "\n"; + + TQPtrList<EmbedImage> list_image; + list_image.setAutoDelete( TRUE ); + int image_count = 0; + for ( it = images.begin(); it != images.end(); ++it ) { + TQImage img; + if ( !img.load( *it ) ) { + fprintf( stderr, "uic: cannot load image file %s\n", (*it).latin1() ); + continue; + } + EmbedImage *e = new EmbedImage; + e->width = img.width(); + e->height = img.height(); + e->depth = img.depth(); + e->numColors = img.numColors(); + e->colorTable = new TQRgb[e->numColors]; + e->alpha = img.hasAlphaBuffer(); + memcpy(e->colorTable, img.colorTable(), e->numColors*sizeof(TQRgb)); + TQFileInfo fi( *it ); + e->name = fi.fileName(); + e->cname = TQString("image_%1").arg( image_count++); + list_image.append( e ); + out << "// " << *it << "\n"; + TQString s; + if ( e->depth == 1 ) + img = img.convertBitOrder(TQImage::BigEndian); + out << s.sprintf( "static const unsigned char %s_data[] = {", + (const char *)e->cname ); +#ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION + e->compressed = +#endif + embedData( out, img.bits(), img.numBytes() ); + out << "\n};\n\n"; + if ( e->numColors ) { + out << s.sprintf( "static const TQRgb %s_ctable[] = {", + (const char *)e->cname ); + embedData( out, e->colorTable, e->numColors ); + out << "\n};\n\n"; + } + } + + if ( !list_image.isEmpty() ) { + out << "static struct EmbedImage {\n" + " int width, height, depth;\n" + " const unsigned char *data;\n" +#ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION + " ulong compressed;\n" +#endif + " int numColors;\n" + " const TQRgb *colorTable;\n" + " bool alpha;\n" + " const char *name;\n" + "} embed_image_vec[] = {\n"; + EmbedImage *e = list_image.first(); + while ( e ) { + out << " { " + << e->width << ", " + << e->height << ", " + << e->depth << ", " + << "(const unsigned char*)" << e->cname << "_data, " +#ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION + << e->compressed << ", " +#endif + << e->numColors << ", "; + if ( e->numColors ) + out << e->cname << "_ctable, "; + else + out << "0, "; + if ( e->alpha ) + out << "TRUE, "; + else + out << "FALSE, "; + out << "\"" << e->name << "\" },\n"; + e = list_image.next(); + } +#ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION + out << " { 0, 0, 0, 0, 0, 0, 0, 0, 0 }\n};\n"; +#else + out << " { 0, 0, 0, 0, 0, 0, 0, 0 }\n};\n"; +#endif + + out << "\n" + "static TQImage uic_findImage( const TQString& name )\n" + "{\n" + " for ( int i=0; embed_image_vec[i].data; i++ ) {\n" + " if ( TQString::fromUtf8(embed_image_vec[i].name) == name ) {\n" +#ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION + " TQByteArray baunzip;\n" + " baunzip = qUncompress( embed_image_vec[i].data, \n" + " embed_image_vec[i].compressed );\n" + " TQImage img((uchar*)baunzip.data(),\n" + " embed_image_vec[i].width,\n" + " embed_image_vec[i].height,\n" + " embed_image_vec[i].depth,\n" + " (TQRgb*)embed_image_vec[i].colorTable,\n" + " embed_image_vec[i].numColors,\n" + " TQImage::BigEndian\n" + " );\n" + " img = img.copy();\n" +#else + " TQImage img((uchar*)embed_image_vec[i].data,\n" + " embed_image_vec[i].width,\n" + " embed_image_vec[i].height,\n" + " embed_image_vec[i].depth,\n" + " (TQRgb*)embed_image_vec[i].colorTable,\n" + " embed_image_vec[i].numColors,\n" + " TQImage::BigEndian\n" + " );\n" +#endif + " if ( embed_image_vec[i].alpha )\n" + " img.setAlphaBuffer(TRUE);\n" + " return img;\n" + " }\n" + " }\n" + " return TQImage();\n" + "}\n\n"; + + out << "class MimeSourceFactory_" << cProject << " : public TQMimeSourceFactory\n"; + out << "{\n"; + out << "public:\n"; + out << " MimeSourceFactory_" << cProject << "() {}\n"; + out << " ~MimeSourceFactory_" << cProject << "() {}\n"; + out << " const TQMimeSource* data( const TQString& abs_name ) const {\n"; + out << "\tconst TQMimeSource* d = TQMimeSourceFactory::data( abs_name );\n"; + out << "\tif ( d || abs_name.isNull() ) return d;\n"; + out << "\tTQImage img = uic_findImage( abs_name );\n"; + out << "\tif ( !img.isNull() )\n"; + out << "\t ((TQMimeSourceFactory*)this)->setImage( abs_name, img );\n"; + out << "\treturn TQMimeSourceFactory::data( abs_name );\n"; + out << " };\n"; + out << "};\n\n"; + + out << "static TQMimeSourceFactory* factory = 0;\n"; + out << "\n"; + + out << "void qInitImages_" << cProject << "()\n"; + out << "{\n"; + out << " if ( !factory ) {\n"; + out << "\tfactory = new MimeSourceFactory_" << cProject << ";\n"; + out << "\tTQMimeSourceFactory::defaultFactory()->addFactory( factory );\n"; + out << " }\n"; + out << "}\n\n"; + + out << "void qCleanupImages_" << cProject << "()\n"; + out << "{\n"; + out << " if ( factory ) {\n"; + out << "\tTQMimeSourceFactory::defaultFactory()->removeFactory( factory );\n"; + out << "\tdelete factory;\n"; + out << "\tfactory = 0;\n"; + out << " }\n"; + out << "}\n\n"; + + out << "class StaticInitImages_" << cProject << "\n"; + out << "{\n"; + out << "public:\n"; + out << " StaticInitImages_" << cProject << "() { qInitImages_" << cProject << "(); }\n"; + out << "#if defined(Q_OS_SCO) || defined(Q_OS_UNIXWARE)\n"; + out << " ~StaticInitImages_" << cProject << "() { }\n"; + out << "#else\n"; + out << " ~StaticInitImages_" << cProject << "() { qCleanupImages_" << cProject << "(); }\n"; + out << "#endif\n"; + out << "};\n\n"; + + out << "static StaticInitImages_" << cProject << " staticImages;\n"; + } +} 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 sales@trolltech.com. +** +** 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 ); + } +} diff --git a/tools/designer/uic/main.cpp b/tools/designer/uic/main.cpp new file mode 100644 index 000000000..3a20b471c --- /dev/null +++ b/tools/designer/uic/main.cpp @@ -0,0 +1,358 @@ +/********************************************************************** +** 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 sales@trolltech.com. +** +** 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 "domtool.h" +#if defined(UIB) +#include "ui2uib.h" +#endif +#include <qapplication.h> +#include <qfile.h> +#include <qstringlist.h> +#include <qdatetime.h> +#include <qsettings.h> +#define NO_STATIC_COLORS +#include <globaldefs.h> +#include <stdio.h> +#include <stdlib.h> + +// see ### in widgetdatabase.cpp +extern bool dbnounload; +extern TQStringList *dbpaths; + +int main( int argc, char * argv[] ) +{ + bool impl = FALSE; + bool subcl = FALSE; + bool imagecollection = FALSE; + bool imagecollection_tmpfile = FALSE; +#if defined(UIB) + bool binary = FALSE; +#endif + TQStringList images; + const char *error = 0; + const char* fileName = 0; + const char* className = 0; + const char* headerFile = 0; + TQCString outputFile; + TQCString image_tmpfile; + const char* projectName = 0; + const char* trmacro = 0; + bool nofwd = FALSE; + bool fix = FALSE; + TQCString pchFile; + TQApplication app(argc, argv, FALSE); + + TQString keybase( "/TQt Designer/" + + TQString::number( (QT_VERSION >> 16) & 0xff ) +"." + TQString::number( (QT_VERSION >> 8) & 0xff ) + "/" ); + TQSettings config; + config.insertSearchPath( TQSettings::Windows, "/Trolltech" ); + TQStringList pluginPaths = config.readListEntry( keybase + "PluginPaths" ); + if (pluginPaths.count()) + TQApplication::setLibraryPaths(pluginPaths); + + for ( int n = 1; n < argc && error == 0; n++ ) { + TQCString arg = argv[n]; + if ( arg[0] == '-' ) { // option + TQCString opt = &arg[1]; + if ( opt[0] == 'o' ) { // output redirection + if ( opt[1] == '\0' ) { + if ( !(n < argc-1) ) { + error = "Missing output-file name"; + break; + } + outputFile = argv[++n]; + } else + outputFile = &opt[1]; + } else if ( opt[0] == 'i' || opt == "impl" ) { + impl = TRUE; + if ( opt == "impl" || opt[1] == '\0' ) { + if ( !(n < argc-1) ) { + error = "Missing name of header file"; + break; + } + headerFile = argv[++n]; + } else + headerFile = &opt[1]; + } else if ( opt[0] == 'e' || opt == "embed" ) { + imagecollection = TRUE; + if ( opt == "embed" || opt[1] == '\0' ) { + if ( !(n < argc-1) ) { + error = "Missing name of project"; + break; + } + projectName = argv[++n]; + } else { + projectName = &opt[1]; + } + if ( argc > n+1 && qstrcmp( argv[n+1], "-f" ) == 0 ) { + imagecollection_tmpfile = TRUE; + image_tmpfile = argv[n+2]; + n += 2; + } +#if defined(UIB) + + } else if ( opt == "binary" ) { + binary = TRUE; +#endif + } else if ( opt == "nofwd" ) { + nofwd = TRUE; + } else if ( opt == "nounload" ) { + dbnounload = TRUE; + } else if ( opt == "subdecl" ) { + subcl = TRUE; + if ( !(n < argc-2) ) { + error = "Missing arguments"; + break; + } + className = argv[++n]; + headerFile = argv[++n]; + } else if ( opt == "subimpl" ) { + subcl = TRUE; + impl = TRUE; + if ( !(n < argc-2) ) { + error = "Missing arguments"; + break; + } + className = argv[++n]; + headerFile = argv[++n]; + } else if ( opt == "tr" ) { + if ( opt == "tr" || opt[1] == '\0' ) { + if ( !(n < argc-1) ) { + error = "Missing tr macro."; + break; + } + trmacro = argv[++n]; + } else { + trmacro = &opt[1]; + } + } else if ( opt == "L" ) { + if ( !(n < argc-1) ) { + error = "Missing plugin path."; + break; + } + if ( !dbpaths ) + dbpaths = new TQStringList(); + TQString fn = TQFile::decodeName( argv[++n] ); + dbpaths->append( fn ); + TQApplication::addLibraryPath( fn ); + } else if ( opt == "version" ) { + fprintf( stderr, + "User Interface Compiler for TQt version %s\n", + QT_VERSION_STR ); + return 1; + } else if ( opt == "help" ) { + break; + } else if ( opt == "fix" ) { + fix = TRUE; + } else if ( opt == "pch") { + if ( !(n < argc-1) ) { + error = "Missing name of PCH file"; + break; + } + pchFile = argv[++n]; + } else { + error = "Unrecognized option"; + } + } else { + if ( imagecollection && !imagecollection_tmpfile ) + images << argv[n]; + else if ( fileName ) // can handle only one file + error = "Too many input files specified"; + else + fileName = argv[n]; + } + } + + if ( argc < 2 || error || (!fileName && !imagecollection ) ) { + fprintf( stderr, "TQt user interface compiler.\n" ); + if ( error ) + fprintf( stderr, "uic: %s\n", error ); + + fprintf( stderr, "Usage: %s [options] [mode] <uifile>\n\n" + "Generate declaration:\n" + " %s [options] <uifile>\n" + "Generate implementation:\n" + " %s [options] -impl <headerfile> <uifile>\n" + "\t<headerfile> name of the declaration file\n" + "Generate image collection:\n" + " %s [options] -embed <project> <image1> <image2> <image3> ...\n" + "or\n" + " %s [options] -embed <project> -f <temporary file containing image names>\n" + "\t<project> project name\n" + "\t<image[1-N]> image files\n" +#if defined(UIB) + "Generate binary UI file:\n" + " %s [options] -binary <uifile>\n" +#endif + "Generate subclass declaration:\n" + " %s [options] -subdecl <subclassname> <baseclassheaderfile> <uifile>\n" + "\t<subclassname> name of the subclass to generate\n" + "\t<baseclassheaderfile> declaration file of the baseclass\n" + "Generate subclass implementation:\n" + " %s [options] -subimpl <subclassname> <subclassheaderfile> <uifile>\n" + "\t<subclassname> name of the subclass to generate\n" + "\t<subclassheaderfile> declaration file of the subclass\n" + "Options:\n" + "\t-o file Write output to file rather than stdout\n" + "\t-pch file Add #include \"file\" as the first statement in implementation\n" + "\t-nofwd Omit forward declarations of custom classes\n" + "\t-nounload Don't unload plugins after processing\n" + "\t-tr func Use func() instead of tr() for i18n\n" + "\t-L path Additional plugin search path\n" + "\t-version Display version of uic\n" + "\t-help Display this information\n" + , argv[0], argv[0], argv[0], argv[0], argv[0], argv[0], argv[0] +#if defined(UIB) + , argv[0] +#endif + ); + return 1; + } + + if ( imagecollection_tmpfile ) { + TQFile ifile( image_tmpfile ); + if ( ifile.open( IO_ReadOnly ) ) { + TQTextStream ts( &ifile ); + TQString s = ts.read(); + s = s.simplifyWhiteSpace(); + images = TQStringList::split( ' ', s ); + for ( TQStringList::Iterator it = images.begin(); it != images.end(); ++it ) + *it = (*it).simplifyWhiteSpace(); + } + } + +#if defined(UIB) + if ( binary && outputFile.isEmpty() ) { + outputFile = fileName; + if ( outputFile.mid(outputFile.length() - 3).lower() == ".ui" ) + outputFile.truncate( outputFile.length() - 3 ); + outputFile += ".uib"; + } +#endif + + TQFile fileOut; + if ( !outputFile.isEmpty() ) { + fileOut.setName( outputFile ); + if (!fileOut.open( IO_WriteOnly ) ) { + qWarning( "uic: Could not open output file '%s'", outputFile.data() ); + return 1; + } + } else { + fileOut.open( IO_WriteOnly, stdout ); + } + TQTextStream out( &fileOut ); + + if ( imagecollection ) { + out.setEncoding( TQTextStream::Latin1 ); + Uic::embed( out, projectName, images ); + return 0; + } + + out.setEncoding( TQTextStream::UnicodeUTF8 ); + + TQFile file( fileName ); + if ( !file.open( IO_ReadOnly ) ) { + qWarning( "uic: Could not open file '%s'", fileName ); + return 1; + } + + TQDomDocument doc; + TQString errMsg; + int errLine; + if ( !doc.setContent( &file, &errMsg, &errLine ) ) { + qWarning( TQString("uic: Failed to parse %s: ") + errMsg + TQString (" in line %d"), fileName, errLine ); + return 1; + } + + TQDomElement e = doc.firstChild().toElement(); + if ( e.hasAttribute("version") && e.attribute("version").toDouble() > 3.3 ) { + qWarning( TQString("uic: File generated with too recent version of TQt Designer (%s vs. %s)"), + e.attribute("version").latin1(), QT_VERSION_STR ); + return 1; + } + + DomTool::fixDocument( doc ); + + if ( fix ) { + out << doc.toString(); + return 0; +#if defined(UIB) + } else if ( binary ) { + out.unsetDevice(); + TQDataStream binaryOut( &fileOut ); + convertUiToUib( doc, binaryOut ); + return 0; +#endif + } + + if ( !subcl ) { + out << "/****************************************************************************" << endl; + out << "** Form "<< (impl? "implementation" : "interface") << " generated from reading ui file '" << fileName << "'" << endl; + out << "**" << endl; + out << "** Created: " << TQDateTime::currentDateTime().toString() << endl; + out << "**" << endl; + out << "** WARNING! All changes made in this file will be lost!" << endl; + out << "****************************************************************************/" << endl << endl; + } + + TQString protector; + if ( subcl && className && !impl ) + protector = TQString::fromLocal8Bit( className ).upper() + "_H"; + + if ( !protector.isEmpty() ) { + out << "#ifndef " << protector << endl; + out << "#define " << protector << endl; + } + + if ( !pchFile.isEmpty() && impl ) { + out << "#include \"" << pchFile << "\" // PCH include" << endl; + } + + if ( headerFile ) { + out << "#include \"" << headerFile << "\"" << endl << endl; + } + + Uic( fileName, outputFile, out, doc, !impl, subcl, trmacro, className, nofwd ); + + if ( !protector.isEmpty() ) { + out << endl; + out << "#endif // " << protector << endl; + } + if ( fileOut.status() != IO_Ok ) { + qWarning( "uic: Error writing to file" ); + if ( !outputFile.isEmpty() ) + remove( outputFile ); + } + return 0; +} diff --git a/tools/designer/uic/object.cpp b/tools/designer/uic/object.cpp new file mode 100644 index 000000000..d27c14f0c --- /dev/null +++ b/tools/designer/uic/object.cpp @@ -0,0 +1,745 @@ +/********************************************************************** +** 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 sales@trolltech.com. +** +** 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 "domtool.h" +#include <qregexp.h> +#include <qsizepolicy.h> +#include <qstringlist.h> +#define NO_STATIC_COLORS +#include <globaldefs.h> +#include "../interfaces/widgetinterface.h" +#include "../shared/widgetdatabase.h" + +/*! + Creates a declaration for the object given in \a e. + + Children are not traversed recursively. + + \sa createObjectImpl() + */ +void Uic::createObjectDecl( const TQDomElement& e ) +{ + if ( e.tagName() == "vbox" ) { + out << " TQVBoxLayout* " << registerObject(getLayoutName(e) ) << ";" << endl; + } else if ( e.tagName() == "hbox" ) { + out << " TQHBoxLayout* " << registerObject(getLayoutName(e) ) << ";" << endl; + } else if ( e.tagName() == "grid" ) { + out << " TQGridLayout* " << registerObject(getLayoutName(e) ) << ";" << endl; + } else { + TQString objClass = getClassName( e ); + if ( objClass.isEmpty() ) + return; + TQString objName = getObjectName( e ); + if ( objName.isEmpty() ) + return; + // ignore TQLayoutWidgets + if ( objClass == "TQLayoutWidget" ) + return; + // register the object and unify its name + objName = registerObject( objName ); + if ( objClass == "Line" ) + objClass = "TQFrame"; + else if (objClass == "Spacer") + objClass = "TQSpacerItem"; + out << " " << objClass << "* " << objName << ";" << endl; + } +} + + +/*! + Creates an implementation for the object given in \a e. + + Traverses recursively over all children. + + Returns the name of the generated child object. + + \sa createObjectDecl() + */ + +static bool createdCentralWidget = FALSE; + +TQString Uic::createObjectImpl( const TQDomElement &e, const TQString& parentClass, const TQString& par, const TQString& layout ) +{ + TQString parent( par ); + if ( parent == "this" && isMainWindow ) { + if ( !createdCentralWidget ) + out << indent << "setCentralWidget( new TQWidget( this, \"qt_central_widget\" ) );" << endl; + createdCentralWidget = TRUE; + parent = "centralWidget()"; + } + TQDomElement n; + TQString objClass, objName; + int numItems = 0; + int numColumns = 0; + int numRows = 0; + + if ( layouts.contains( e.tagName() ) ) + return createLayoutImpl( e, parentClass, parent, layout ); + + objClass = getClassName( e ); + if ( objClass.isEmpty() ) + return objName; + objName = getObjectName( e ); + + TQString definedName = objName; + bool isTmpObject = objName.isEmpty() || objClass == "TQLayoutWidget"; + if ( isTmpObject ) { + if (( objClass[0] == 'T' ) && ( objClass[1] == 'Q' )) + objName = objClass.mid(2); + else + objName = objClass.lower(); + objName.prepend( "private" ); + } + + bool isLine = objClass == "Line"; + if ( isLine ) + objClass = "TQFrame"; + + out << endl; + if ( objClass == "TQLayoutWidget" ) { + if ( layout.isEmpty() ) { + // register the object and unify its name + objName = registerObject( objName ); + out << " TQWidget* " << objName << " = new TQWidget( " << parent << ", \"" << definedName << "\" );" << endl; + } else { + // the layout widget is not necessary, hide it by creating its child in the parent + TQString result; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if (tags.contains( n.tagName() ) ) + result = createObjectImpl( n, parentClass, parent, layout ); + } + return result; + } + } else if ( objClass != "TQToolBar" && objClass != "TQMenuBar" ) { + // register the object and unify its name + objName = registerObject( objName ); + out << " "; + if ( isTmpObject ) + out << objClass << "* "; + out << objName << " = new " << createObjectInstance( objClass, parent, objName ) << ";" << endl; + } + + if ( objClass == "TQAxWidget" ) { + TQString controlId; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "property" && n.attribute( "name" ) == "control" ) { + controlId = n.firstChild().toElement().text(); + } + } + out << " "; + out << objName << "->setControl(\"" << controlId << "\");" << endl; + } + + lastItem = "0"; + // set the properties and insert items + bool hadFrameShadow = FALSE; + 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" ); + if ( prop == "database" ) + continue; + TQString value = setObjectProperty( objClass, objName, prop, n.firstChild().toElement(), stdset ); + if ( value.isEmpty() ) + continue; + if ( prop == "name" ) + continue; + if ( isLine && prop == "frameShadow" ) + hadFrameShadow = TRUE; + if ( prop == "buddy" && value.startsWith("\"") && value.endsWith("\"") ) { + buddies << Buddy( objName, value.mid(1, value.length() - 2 ) ); + continue; + } + if ( isLine && prop == "orientation" ) { + prop = "frameShape"; + if ( value.right(10) == "Horizontal" ) + value = "TQFrame::HLine"; + else + value = "TQFrame::VLine"; + if ( !hadFrameShadow ) { + prop = "frameStyle"; + value += " | TQFrame::Sunken"; + } + } + if ( prop == "buttonGroupId" ) { + if ( parentClass == "TQButtonGroup" ) + out << indent << parent << "->insert( " << objName << ", " << value << " );" << endl; + continue; + } + if ( prop == "frameworkCode" ) + continue; + if ( objClass == "TQMultiLineEdit" && + TQRegExp("echoMode|hMargin|maxLength|maxLines|undoEnabled").exactMatch(prop) ) + continue; + + TQString call = objName + "->"; + if ( stdset ) { + call += mkStdSet( prop ) + "( "; + } else { + call += "setProperty( \"" + prop + "\", "; + } + if ( prop == "accel" ) + call += "TQKeySequence( " + value + " ) );"; + else + call += value + " );"; + + if ( n.firstChild().toElement().tagName() == "string" || + prop == "currentItem" ) { + trout << indent << call << endl; + } else { + out << indent << call << endl; + } + } else if ( n.tagName() == "item" ) { + TQString call; + TQString value; + + if ( objClass.contains( "ListBox" ) ) { + call = createListBoxItemImpl( n, objName ); + if ( !call.isEmpty() ) { + if ( numItems == 0 ) + trout << indent << objName << "->clear();" << endl; + trout << indent << call << endl; + } + } else if ( objClass.contains( "ComboBox" ) ) { + call = createListBoxItemImpl( n, objName, &value ); + if ( !call.isEmpty() ) { + if ( numItems == 0 ) + trout << indent << objName << "->clear();" << endl; + trout << indent << call << endl; + } + } else if ( objClass.contains( "IconView" ) ) { + call = createIconViewItemImpl( n, objName ); + if ( !call.isEmpty() ) { + if ( numItems == 0 ) + trout << indent << objName << "->clear();" << endl; + trout << indent << call << endl; + } + } else if ( objClass.contains( "ListView" ) ) { + call = createListViewItemImpl( n, objName, TQString::null ); + if ( !call.isEmpty() ) { + if ( numItems == 0 ) + trout << indent << objName << "->clear();" << endl; + trout << call << endl; + } + } + if ( !call.isEmpty() ) + numItems++; + } else if ( n.tagName() == "column" || n.tagName() == "row" ) { + TQString call; + TQString value; + + if ( objClass.contains( "ListView" ) ) { + call = createListViewColumnImpl( n, objName, &value ); + if ( !call.isEmpty() ) { + out << call; + trout << indent << objName << "->header()->setLabel( " + << numColumns++ << ", " << value << " );\n"; + } + } else if ( objClass == "TQTable" || objClass == "TQDataTable" ) { + bool isCols = ( n.tagName() == "column" ); + call = createTableRowColumnImpl( n, objName, &value ); + if ( !call.isEmpty() ) { + out << call; + trout << indent << objName << "->" + << ( isCols ? "horizontalHeader" : "verticalHeader" ) + << "()->setLabel( " + << ( isCols ? numColumns++ : numRows++ ) + << ", " << value << " );\n"; + } + } + } + } + + // create all children, some widgets have special retquirements + + if ( objClass == "TQTabWidget" ) { + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( tags.contains( n.tagName() ) ) { + TQString page = createObjectImpl( n, objClass, objName ); + TQString comment; + TQString label = DomTool::readAttribute( n, "title", "", comment ).toString(); + out << indent << objName << "->insertTab( " << page << ", TQString::fromLatin1(\"\") );" << endl; + trout << indent << objName << "->changeTab( " << page << ", " + << trcall( label, comment ) << " );" << endl; + } + } + } else if ( objClass == "TQWidgetStack" ) { + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( tags.contains( n.tagName() ) ) { + TQString page = createObjectImpl( n, objClass, objName ); + int id = DomTool::readAttribute( n, "id", "" ).toInt(); + out << indent << objName << "->addWidget( " << page << ", " << id << " );" << endl; + } + } + } else if ( objClass == "TQToolBox" ) { + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( tags.contains( n.tagName() ) ) { + TQString page = createObjectImpl( n, objClass, objName ); + TQString comment; + TQString label = DomTool::readAttribute( n, "label", "", comment ).toString(); + out << indent << objName << "->addItem( " << page << ", TQString::fromLatin1(\"\") );" << endl; + trout << indent << objName << "->setItemLabel( " << objName + << "->indexOf(" << page << "), " << trcall( label, comment ) + << " );" << endl; + } + } + } else if ( objClass != "TQToolBar" && objClass != "TQMenuBar" ) { // standard widgets + WidgetInterface *iface = 0; + widgetManager()->queryInterface( objClass, &iface ); +#ifdef QT_CONTAINER_CUSTOM_WIDGETS + int id = WidgetDatabase::idFromClassName( objClass ); + if ( WidgetDatabase::isContainer( id ) && WidgetDatabase::isCustomPluginWidget( id ) && iface ) { + TQWidgetContainerInterfacePrivate *iface2 = 0; + iface->queryInterface( IID_QWidgetContainer, (TQUnknownInterface**)&iface2 ); + if ( iface2 ) { + bool supportsPages = iface2->supportsPages( objClass ); + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( tags.contains( n.tagName() ) ) { + if ( supportsPages ) { + TQString page = createObjectImpl( n, objClass, objName ); + TQString comment; + TQString label = DomTool::readAttribute( n, "label", "", comment ).toString(); + out << indent << iface2->createCode( objClass, objName, page, label ) << endl; + } else { + createObjectImpl( n, objClass, objName ); + } + } + } + iface2->release(); + } + iface->release(); + } else { +#endif + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( tags.contains( n.tagName() ) ) + createObjectImpl( n, objClass, objName ); + } +#ifdef QT_CONTAINER_CUSTOM_WIDGETS + } +#endif + } + + return objName; +} + +/*! + Creates declarations for spacer items that are children of \a e. + + \sa createObjectDecl() +*/ + +void Uic::createSpacerDecl( const TQDomElement &e ) +{ + for ( TQDomElement n = e.firstChild().toElement(); + !n.isNull(); n = n.nextSibling().toElement() ) + if ( n.tagName() == "spacer" ) + out << " TQSpacerItem* " << registerObject(getObjectName(n)) << ";" << endl; +} + +/*! + Creates a set-call for property \a exclusiveProp of the object + given in \a e. + + If the object does not have this property, the function does nothing. + + Exclusive properties are used to generate the implementation of + application font or palette change handlers in createFormImpl(). + + */ +void Uic::createExclusiveProperty( const TQDomElement & e, const TQString& exclusiveProp ) +{ + TQDomElement n; + TQString objClass = getClassName( e ); + if ( objClass.isEmpty() ) + return; + TQString objName = getObjectName( e ); +#if 0 // it's not clear whether this check should be here or not + if ( objName.isEmpty() ) + return; +#endif + 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" ); + if ( prop != exclusiveProp ) + continue; + TQString value = setObjectProperty( objClass, objName, prop, n.firstChild().toElement(), stdset ); + if ( value.isEmpty() ) + continue; + // we assume the property isn't of type 'string' + out << '\t' << objName << "->setProperty( \"" << prop << "\", " << value << " );" << endl; + } + } +} + + +/*! Attention: this function has to be in sync with + Resource::saveProperty() and DomTool::elementToVariant. If you + change one, change all. + */ +TQString Uic::setObjectProperty( const TQString& objClass, const TQString& obj, const TQString &prop, const TQDomElement &e, bool stdset ) +{ + TQString v; + if ( e.tagName() == "rect" ) { + TQDomElement n3 = e.firstChild().toElement(); + int x = 0, y = 0, w = 0, h = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "x" ) + x = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "y" ) + y = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "width" ) + w = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "height" ) + h = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = "TQRect( %1, %2, %3, %4 )"; + v = v.arg(x).arg(y).arg(w).arg(h); + + } else if ( e.tagName() == "point" ) { + TQDomElement n3 = e.firstChild().toElement(); + int x = 0, y = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "x" ) + x = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "y" ) + y = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = "TQPoint( %1, %2 )"; + v = v.arg(x).arg(y); + } else if ( e.tagName() == "size" ) { + TQDomElement n3 = e.firstChild().toElement(); + int w = 0, h = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "width" ) + w = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "height" ) + h = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = "TQSize( %1, %2 )"; + v = v.arg(w).arg(h); + } else if ( e.tagName() == "color" ) { + TQDomElement n3 = e.firstChild().toElement(); + int r = 0, g = 0, b = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "red" ) + r = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "green" ) + g = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "blue" ) + b = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = "TQColor( %1, %2, %3 )"; + v = v.arg(r).arg(g).arg(b); + } else if ( e.tagName() == "font" ) { + TQDomElement n3 = e.firstChild().toElement(); + TQString attrname = e.parentNode().toElement().attribute( "name", "font" ); + TQString fontname; + if ( !obj.isEmpty() ) { + fontname = registerObject( obj + "_" + attrname ); + out << indent << "TQFont " << fontname << "( " << obj << "->font() );" << endl; + } else { + fontname = registerObject( "f" ); + out << indent << "TQFont " << fontname << "( font() );" << endl; + } + while ( !n3.isNull() ) { + if ( n3.tagName() == "family" ) + out << indent << fontname << ".setFamily( \"" << n3.firstChild().toText().data() << "\" );" << endl; + else if ( n3.tagName() == "pointsize" ) + out << indent << fontname << ".setPointSize( " << n3.firstChild().toText().data() << " );" << endl; + else if ( n3.tagName() == "bold" ) + out << indent << fontname << ".setBold( " << mkBool( n3.firstChild().toText().data() ) << " );" << endl; + else if ( n3.tagName() == "italic" ) + out << indent << fontname << ".setItalic( " << mkBool( n3.firstChild().toText().data() ) << " );" << endl; + else if ( n3.tagName() == "underline" ) + out << indent << fontname << ".setUnderline( " << mkBool( n3.firstChild().toText().data() ) << " );" << endl; + else if ( n3.tagName() == "strikeout" ) + out << indent << fontname << ".setStrikeOut( " << mkBool( n3.firstChild().toText().data() ) << " );" << endl; + n3 = n3.nextSibling().toElement(); + } + + if ( prop == "font" ) { + if ( !obj.isEmpty() ) + out << indent << obj << "->setFont( " << fontname << " ); " << endl; + else + out << indent << "setFont( " << fontname << " ); " << endl; + } else { + v = fontname; + } + } else if ( e.tagName() == "string" ) { + TQString txt = e.firstChild().toText().data(); + TQString com = getComment( e.parentNode() ); + + if ( prop == "toolTip" && objClass != "TQAction" && objClass != "TQActionGroup" ) { + if ( !obj.isEmpty() ) + trout << indent << "TQToolTip::add( " << obj << ", " + << trcall( txt, com ) << " );" << endl; + else + trout << indent << "TQToolTip::add( this, " + << trcall( txt, com ) << " );" << endl; + } else if ( prop == "whatsThis" && objClass != "TQAction" && objClass != "TQActionGroup" ) { + if ( !obj.isEmpty() ) + trout << indent << "TQWhatsThis::add( " << obj << ", " + << trcall( txt, com ) << " );" << endl; + else + trout << indent << "TQWhatsThis::add( this, " + << trcall( txt, com ) << " );" << endl; + } else { + v = trcall( txt, com ); + } + } else if ( e.tagName() == "cstring" ) { + v = "\"%1\""; + v = v.arg( e.firstChild().toText().data() ); + } else if ( e.tagName() == "number" ) { + v = "%1"; + v = v.arg( e.firstChild().toText().data() ); + } else if ( e.tagName() == "bool" ) { + if ( stdset ) + v = "%1"; + else + v = "TQVariant( %1, 0 )"; + v = v.arg( mkBool( e.firstChild().toText().data() ) ); + } else if ( e.tagName() == "pixmap" ) { + v = e.firstChild().toText().data(); + if ( !pixmapLoaderFunction.isEmpty() ) { + v.prepend( pixmapLoaderFunction + "( " + TQString( externPixmaps ? "\"" : "" ) ); + v.append( TQString( externPixmaps ? "\"" : "" ) + " )" ); + } + } else if ( e.tagName() == "iconset" ) { + v = "TQIconSet( %1 )"; + TQString s = e.firstChild().toText().data(); + if ( !pixmapLoaderFunction.isEmpty() ) { + s.prepend( pixmapLoaderFunction + "( " + TQString( externPixmaps ? "\"" : "" ) ); + s.append( TQString( externPixmaps ? "\"" : "" ) + " )" ); + } + v = v.arg( s ); + } else if ( e.tagName() == "image" ) { + v = e.firstChild().toText().data() + ".convertToImage()"; + } else if ( e.tagName() == "enum" ) { + if ( stdset ) + v = "%1::%2"; + else + v = "\"%1\""; + TQString oc = objClass; + TQString ev = e.firstChild().toText().data(); + if ( oc == "TQListView" && ev == "Manual" ) // #### workaround, rename TQListView::Manual in 4.0 + oc = "TQScrollView"; + if ( stdset ) + v = v.arg( oc ).arg( ev ); + else + v = v.arg( ev ); + } else if ( e.tagName() == "set" ) { + TQString keys( e.firstChild().toText().data() ); + TQStringList lst = TQStringList::split( '|', keys ); + v = "int( "; + TQStringList::Iterator it = lst.begin(); + while ( it != lst.end() ) { + v += objClass + "::" + *it; + if ( it != lst.fromLast() ) + v += " | "; + ++it; + } + v += " )"; + } else if ( e.tagName() == "sizepolicy" ) { + TQDomElement n3 = e.firstChild().toElement(); + TQSizePolicy sp; + while ( !n3.isNull() ) { + if ( n3.tagName() == "hsizetype" ) + sp.setHorData( (TQSizePolicy::SizeType)n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "vsizetype" ) + sp.setVerData( (TQSizePolicy::SizeType)n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "horstretch" ) + sp.setHorStretch( n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "verstretch" ) + sp.setVerStretch( n3.firstChild().toText().data().toInt() ); + n3 = n3.nextSibling().toElement(); + } + TQString tmp; + if ( !obj.isEmpty() ) + tmp = obj + "->"; + v = "TQSizePolicy( (TQSizePolicy::SizeType)%1, (TQSizePolicy::SizeType)%2, %3, %4, " + tmp + "sizePolicy().hasHeightForWidth() )"; + v = v.arg( (int)sp.horData() ).arg( (int)sp.verData() ).arg( sp.horStretch() ).arg( sp.verStretch() ); + } else if ( e.tagName() == "palette" ) { + TQPalette pal; + bool no_pixmaps = e.elementsByTagName( "pixmap" ).count() == 0; + TQDomElement n; + if ( no_pixmaps ) { + n = e.firstChild().toElement(); + while ( !n.isNull() ) { + TQColorGroup cg; + if ( n.tagName() == "active" ) { + cg = loadColorGroup( n ); + pal.setActive( cg ); + } else if ( n.tagName() == "inactive" ) { + cg = loadColorGroup( n ); + pal.setInactive( cg ); + } else if ( n.tagName() == "disabled" ) { + cg = loadColorGroup( n ); + pal.setDisabled( cg ); + } + n = n.nextSibling().toElement(); + } + } + if ( no_pixmaps && pal == TQPalette( pal.active().button(), pal.active().background() ) ) { + v = "TQPalette( TQColor( %1, %2, %3 ), TQColor( %1, %2, %3 ) )"; + v = v.arg( pal.active().button().red() ).arg( pal.active().button().green() ).arg( pal.active().button().blue() ); + v = v.arg( pal.active().background().red() ).arg( pal.active().background().green() ).arg( pal.active().background().blue() ); + } else { + TQString palette = "pal"; + if ( !pal_used ) { + out << indent << "TQPalette " << palette << ";" << endl; + pal_used = TRUE; + } + TQString cg = "cg"; + if ( !cg_used ) { + out << indent << "TQColorGroup " << cg << ";" << endl; + cg_used = TRUE; + } + n = e.firstChild().toElement(); + while ( !n.isNull() && n.tagName() != "active" ) + n = n.nextSibling().toElement(); + createColorGroupImpl( cg, n ); + out << indent << palette << ".setActive( " << cg << " );" << endl; + + n = e.firstChild().toElement(); + while ( !n.isNull() && n.tagName() != "inactive" ) + n = n.nextSibling().toElement(); + createColorGroupImpl( cg, n ); + out << indent << palette << ".setInactive( " << cg << " );" << endl; + + n = e.firstChild().toElement(); + while ( !n.isNull() && n.tagName() != "disabled" ) + n = n.nextSibling().toElement(); + createColorGroupImpl( cg, n ); + out << indent << palette << ".setDisabled( " << cg << " );" << endl; + v = palette; + } + } else if ( e.tagName() == "cursor" ) { + v = "TQCursor( %1 )"; + v = v.arg( e.firstChild().toText().data() ); + } else if ( e.tagName() == "date" ) { + TQDomElement n3 = e.firstChild().toElement(); + int y, m, d; + y = m = d = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "year" ) + y = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "month" ) + m = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "day" ) + d = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = "TQDate( %1, %2, %3 )"; + v = v.arg(y).arg(m).arg(d); + } else if ( e.tagName() == "time" ) { + TQDomElement n3 = e.firstChild().toElement(); + int h, m, s; + h = m = s = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "hour" ) + h = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "minute" ) + m = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "second" ) + s = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = "TQTime( %1, %2, %3 )"; + v = v.arg(h).arg(m).arg(s); + } else if ( e.tagName() == "datetime" ) { + TQDomElement n3 = e.firstChild().toElement(); + int h, mi, s, y, mo, d; + h = mi = s = y = mo = d = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "hour" ) + h = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "minute" ) + mi = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "second" ) + s = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "year" ) + y = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "month" ) + mo = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "day" ) + d = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = "TQDateTime( TQDate( %1, %2, %3 ), TQTime( %4, %5, %6 ) )"; + v = v.arg(y).arg(mo).arg(d).arg(h).arg(mi).arg(s); + } else if ( e.tagName() == "stringlist" ) { + TQStringList l; + TQDomElement n3 = e.firstChild().toElement(); + TQString listname = "l"; + if ( !obj.isEmpty() ) { + listname = obj + "_stringlist"; + listname = registerObject( listname ); + out << indent << "TQStringList " << listname << ";" << endl; + } else { + listname = registerObject( listname ); + out << indent << "TQStringList " << listname << ";" << endl; + } + while ( !n3.isNull() ) { + if ( n3.tagName() == "string" ) + out << indent << listname << " << \"" << n3.firstChild().toText().data().simplifyWhiteSpace() << "\";" << endl; + n3 = n3.nextSibling().toElement(); + } + v = listname; + } + return v; +} + +/*! Extracts a named object property from \a e. + */ +TQDomElement Uic::getObjectProperty( const TQDomElement& e, const TQString& name ) +{ + TQDomElement n; + for ( n = e.firstChild().toElement(); + !n.isNull(); + n = n.nextSibling().toElement() ) { + if ( n.tagName() == "property" && n.toElement().attribute("name") == name ) + return n; + } + return n; +} diff --git a/tools/designer/uic/subclassing.cpp b/tools/designer/uic/subclassing.cpp new file mode 100644 index 000000000..bdfa23b02 --- /dev/null +++ b/tools/designer/uic/subclassing.cpp @@ -0,0 +1,352 @@ +/********************************************************************** +** 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 sales@trolltech.com. +** +** 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 <qfile.h> +#include <qstringlist.h> +#include <qdatetime.h> +#define NO_STATIC_COLORS +#include <globaldefs.h> +#include <qregexp.h> +#include <stdio.h> +#include <stdlib.h> + +/*! + Creates a declaration ( headerfile ) for a subclass \a subClass + of the form given in \a e + + \sa createSubImpl() + */ +void Uic::createSubDecl( const TQDomElement &e, const TQString& subClass ) +{ + TQDomElement n; + TQDomNodeList nl; + int i; + + TQString objClass = getClassName( e ); + if ( objClass.isEmpty() ) + return; + + out << "class " << subClass << " : public " << nameOfClass << endl; + out << "{" << endl; + +/* tmake ignore Q_OBJECT */ + out << " Q_OBJECT" << endl; + out << endl; + out << "public:" << endl; + + // constructor + if ( objClass == "TQDialog" || objClass == "TQWizard" ) { + out << " " << subClass << "( TQWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 );" << endl; + } else { // standard TQWidget + out << " " << subClass << "( TQWidget* parent = 0, const char* name = 0, WFlags fl = 0 );" << endl; + } + + // destructor + out << " ~" << subClass << "();" << endl; + out << endl; + + // find additional functions + TQStringList publicSlots, protectedSlots, privateSlots; + TQStringList publicSlotTypes, protectedSlotTypes, privateSlotTypes; + TQStringList publicSlotSpecifier, protectedSlotSpecifier, privateSlotSpecifier; + TQStringList publicFuncts, protectedFuncts, privateFuncts; + TQStringList publicFunctRetTyp, protectedFunctRetTyp, privateFunctRetTyp; + TQStringList publicFunctSpec, protectedFunctSpec, privateFunctSpec; + + 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; + } + } + + 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; + } + } + + if ( !publicFuncts.isEmpty() ) + writeFunctionsSubDecl( publicFuncts, publicFunctRetTyp, publicFunctSpec ); + + // create public additional slots + if ( !publicSlots.isEmpty() ) { + out << "public slots:" << endl; + writeFunctionsSubDecl( publicSlots, publicSlotTypes, publicSlotSpecifier ); + } + + if ( !protectedFuncts.isEmpty() ) { + out << "protected:" << endl; + writeFunctionsSubDecl( protectedFuncts, protectedFunctRetTyp, protectedFunctSpec ); + } + + // create protected additional slots + if ( !protectedSlots.isEmpty() ) { + out << "protected slots:" << endl; + writeFunctionsSubDecl( protectedSlots, protectedSlotTypes, protectedSlotSpecifier ); + } + + if ( !privateFuncts.isEmpty() ) { + out << "private:" << endl; + writeFunctionsSubDecl( privateFuncts, privateFunctRetTyp, privateFunctSpec ); + } + + // create private additional slots + if ( !privateSlots.isEmpty() ) { + out << "private slots:" << endl; + writeFunctionsSubDecl( privateSlots, privateSlotTypes, privateSlotSpecifier ); + } + out << "};" << endl; +} + +void Uic::writeFunctionsSubDecl( 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 type = *it2; + if ( type.isEmpty() ) + type = "void"; + if ( *it3 == "non virtual" ) + continue; + out << " " << type << " " << (*it) << ";" << endl; + } + out << endl; +} + +/*! + Creates an implementation for a subclass \a subClass of the form + given in \a e + + \sa createSubDecl() + */ +void Uic::createSubImpl( const TQDomElement &e, const TQString& subClass ) +{ + TQDomElement n; + TQDomNodeList nl; + int i; + + TQString objClass = getClassName( e ); + if ( objClass.isEmpty() ) + return; + + // constructor + if ( objClass == "TQDialog" || objClass == "TQWizard" ) { + out << "/* " << endl; + out << " * Constructs a " << subClass << " which is 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 << subClass << "::" << subClass << "( TQWidget* parent, const char* name, bool modal, WFlags fl )" << endl; + out << " : " << nameOfClass << "( parent, name, modal, fl )" << endl; + } else { // standard TQWidget + out << "/* " << endl; + out << " * Constructs a " << subClass << " which is a child of 'parent', with the " << endl; + out << " * name 'name' and widget flags set to 'f' " << endl; + out << " */" << endl; + out << subClass << "::" << subClass << "( TQWidget* parent, const char* name, WFlags fl )" << endl; + out << " : " << nameOfClass << "( parent, name, fl )" << endl; + } + out << "{" << endl; + out << "}" << endl; + out << endl; + + // destructor + out << "/* " << endl; + out << " * Destroys the object and frees any allocated resources" << endl; + out << " */" << endl; + out << subClass << "::~" << subClass << "()" << endl; + out << "{" << endl; + out << " // no need to delete child widgets, TQt does it all for us" << endl; + out << "}" << endl; + out << endl; + + + // find additional functions + TQStringList publicSlots, protectedSlots, privateSlots; + TQStringList publicSlotTypes, protectedSlotTypes, privateSlotTypes; + TQStringList publicSlotSpecifier, protectedSlotSpecifier, privateSlotSpecifier; + TQStringList publicFuncts, protectedFuncts, privateFuncts; + TQStringList publicFunctRetTyp, protectedFunctRetTyp, privateFunctRetTyp; + TQStringList publicFunctSpec, protectedFunctSpec, privateFunctSpec; + + 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; + } + } + + 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; + } + } + + if ( !publicFuncts.isEmpty() ) + writeFunctionsSubImpl( publicFuncts, publicFunctRetTyp, publicFunctSpec, subClass, "public function" ); + + // create stubs for public additional slots + if ( !publicSlots.isEmpty() ) + writeFunctionsSubImpl( publicSlots, publicSlotTypes, publicSlotSpecifier, subClass, "public slot" ); + + if ( !protectedFuncts.isEmpty() ) + writeFunctionsSubImpl( protectedFuncts, protectedFunctRetTyp, protectedFunctSpec, subClass, "protected function" ); + + // create stubs for protected additional slots + if ( !protectedSlots.isEmpty() ) + writeFunctionsSubImpl( protectedSlots, protectedSlotTypes, protectedSlotSpecifier, subClass, "protected slot" ); + + if ( !privateFuncts.isEmpty() ) + writeFunctionsSubImpl( privateFuncts, privateFunctRetTyp, privateFunctSpec, subClass, "private function" ); + + // create stubs for private additional slots + if ( !privateSlots.isEmpty() ) + writeFunctionsSubImpl( privateSlots, privateSlotTypes, privateSlotSpecifier, subClass, "private slot" ); +} + +void Uic::writeFunctionsSubImpl( const TQStringList &fuLst, const TQStringList &typLst, const TQStringList &specLst, + const TQString &subClass, const TQString &descr ) +{ + TQValueListConstIterator<TQString> it, it2, it3; + for ( it = fuLst.begin(), it2 = typLst.begin(), it3 = specLst.begin(); + it != fuLst.end(); ++it, ++it2, ++it3 ) { + TQString type = *it2; + if ( type.isEmpty() ) + type = "void"; + if ( *it3 == "non virtual" ) + continue; + out << "/*" << endl; + out << " * " << descr << endl; + out << " */" << endl; + out << type << " " << subClass << "::" << (*it) << endl; + out << "{" << endl; + out << " qWarning( \"" << subClass << "::" << (*it) << " not yet implemented!\" );" << endl; + out << "}" << endl << endl; + } + out << endl; +} diff --git a/tools/designer/uic/uic.cpp b/tools/designer/uic/uic.cpp new file mode 100644 index 000000000..6baadec7f --- /dev/null +++ b/tools/designer/uic/uic.cpp @@ -0,0 +1,1129 @@ +/********************************************************************** +** 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 sales@trolltech.com. +** +** 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 <qfile.h> +#include <qstringlist.h> +#include <qdatetime.h> +#define NO_STATIC_COLORS +#include <globaldefs.h> +#include <qregexp.h> +#include <stdio.h> +#include <stdlib.h> + +bool Uic::isMainWindow = FALSE; + +TQString Uic::getComment( const TQDomNode& n ) +{ + TQDomNode child = n.firstChild(); + while ( !child.isNull() ) { + if ( child.toElement().tagName() == "comment" ) + return child.toElement().firstChild().toText().data(); + child = child.nextSibling(); + } + return TQString::null; +} + +TQString Uic::mkBool( bool b ) +{ + return b? "TRUE" : "FALSE"; +} + +TQString Uic::mkBool( const TQString& s ) +{ + return mkBool( s == "true" || s == "1" ); +} + +bool Uic::toBool( const TQString& s ) +{ + return s == "true" || s.toInt() != 0; +} + +TQString Uic::fixString( const TQString &str, bool encode ) +{ + TQString s; + if ( !encode ) { + s = str; + s.replace( "\\", "\\\\" ); + s.replace( "\"", "\\\"" ); + s.replace( "\r", "" ); + s.replace( "\n", "\\n\"\n\"" ); + } else { + TQCString utf8 = str.utf8(); + const int l = utf8.length(); + + for ( int i = 0; i < l; ++i ) { + uchar c = (uchar)utf8[i]; + if (c != 0x0d) // skip \r + s += "\\x" + TQString::number(c, 16); + + if (i && (i % 20) == 0) + s += "\"\n \""; + } + } + + return "\"" + s + "\""; +} + +TQString Uic::trcall( const TQString& sourceText, const TQString& comment ) +{ + if ( sourceText.isEmpty() && comment.isEmpty() ) + return "TQString::null"; + + TQString t = trmacro; + bool encode = FALSE; + if ( t.isNull() ) { + t = "tr"; + for ( int i = 0; i < (int) sourceText.length(); i++ ) { + if ( sourceText[i].unicode() >= 0x80 ) { + t = "trUtf8"; + encode = TRUE; + break; + } + } + } + + if ( comment.isEmpty() ) { + return t + "( " + fixString( sourceText, encode ) + " )"; + } else { + return t + "( " + fixString( sourceText, encode ) + ", " + + fixString( comment, encode ) + " )"; + } +} + +TQString Uic::mkStdSet( const TQString& prop ) +{ + return TQString( "set" ) + prop[0].upper() + prop.mid(1); +} + + + +/*! + \class Uic uic.h + \brief User Interface Compiler + + The class Uic encapsulates the user interface compiler (uic). + */ +Uic::Uic( const TQString &fn, const char *outputFn, TQTextStream &outStream, + TQDomDocument doc, bool decl, bool subcl, const TQString &trm, + const TQString& subClass, bool omitForwardDecls ) + : out( outStream ), trout( &languageChangeBody ), + outputFileName( outputFn ), trmacro( trm ), nofwd( omitForwardDecls ) +{ + fileName = fn; + writeFunctImpl = TRUE; + defMargin = BOXLAYOUT_DEFAULT_MARGIN; + defSpacing = BOXLAYOUT_DEFAULT_SPACING; + externPixmaps = FALSE; + indent = " "; // default indent + + item_used = cg_used = pal_used = 0; + + layouts << "hbox" << "vbox" << "grid"; + tags = layouts; + tags << "widget"; + + pixmapLoaderFunction = getPixmapLoaderFunction( doc.firstChild().toElement() ); + nameOfClass = getFormClassName( doc.firstChild().toElement() ); + + uiFileVersion = doc.firstChild().toElement().attribute("version"); + stdsetdef = toBool( doc.firstChild().toElement().attribute("stdsetdef") ); + + if ( doc.firstChild().isNull() || doc.firstChild().firstChild().isNull() ) + return; + TQDomElement e = doc.firstChild().firstChild().toElement(); + TQDomElement widget; + while ( !e.isNull() ) { + if ( e.tagName() == "widget" ) { + widget = e; + } else if ( e.tagName() == "pixmapinproject" ) { + externPixmaps = TRUE; + } else if ( e.tagName() == "layoutdefaults" ) { + defSpacing = e.attribute( "spacing", defSpacing.toString() ); + defMargin = e.attribute( "margin", defMargin.toString() ); + } else if ( e.tagName() == "layoutfunctions" ) { + defSpacing = e.attribute( "spacing", defSpacing.toString() ); + bool ok; + defSpacing.toInt( &ok ); + if ( !ok ) { + TQString buf = defSpacing.toString(); + defSpacing = buf.append( "()" ); + } + defMargin = e.attribute( "margin", defMargin.toString() ); + defMargin.toInt( &ok ); + if ( !ok ) { + TQString buf = defMargin.toString(); + defMargin = buf.append( "()" ); + } + } + e = e.nextSibling().toElement(); + } + e = widget; + + if ( nameOfClass.isEmpty() ) + nameOfClass = getObjectName( e ); + namespaces = TQStringList::split( "::", nameOfClass ); + bareNameOfClass = namespaces.last(); + namespaces.remove( namespaces.fromLast() ); + + if ( subcl ) { + if ( decl ) + createSubDecl( e, subClass ); + else + createSubImpl( e, subClass ); + } else { + if ( decl ) + createFormDecl( e ); + else + createFormImpl( e ); + } + +} + +/*! Extracts a pixmap loader function from \a e + */ +TQString Uic::getPixmapLoaderFunction( const TQDomElement& e ) +{ + TQDomElement n; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "pixmapfunction" ) + return n.firstChild().toText().data(); + } + return TQString::null; +} + + +/*! Extracts the forms class name from \a e + */ +TQString Uic::getFormClassName( const TQDomElement& e ) +{ + TQDomElement n; + TQString cn; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "class" ) { + TQString s = n.firstChild().toText().data(); + int i; + while ( ( i = s.find(' ' )) != -1 ) + s[i] = '_'; + cn = s; + } + } + return cn; +} + +/*! Extracts a class name from \a e. + */ +TQString Uic::getClassName( const TQDomElement& e ) +{ + TQString s = e.attribute( "class" ); + if ( s.isEmpty() && e.tagName() == "toolbar" ) + s = "TQToolBar"; + else if ( s.isEmpty() && e.tagName() == "menubar" ) + s = "TQMenuBar"; + return s; +} + +/*! Returns TRUE if database framework code is generated, else FALSE. +*/ + +bool Uic::isFrameworkCodeGenerated( const TQDomElement& e ) +{ + TQDomElement n = getObjectProperty( e, "frameworkCode" ); + if ( n.attribute("name") == "frameworkCode" && + !DomTool::elementToVariant( n.firstChild().toElement(), TQVariant( TRUE, 0 ) ).toBool() ) + return FALSE; + return TRUE; +} + +/*! Extracts an object name from \a e. It's stored in the 'name' + property. + */ +TQString Uic::getObjectName( const TQDomElement& e ) +{ + TQDomElement n = getObjectProperty( e, "name" ); + if ( n.firstChild().toElement().tagName() == "cstring" ) + return n.firstChild().toElement().firstChild().toText().data(); + return TQString::null; +} + +/*! Extracts an layout name from \a e. It's stored in the 'name' + property of the preceeding sibling (the first child of a TQLayoutWidget). + */ +TQString Uic::getLayoutName( const TQDomElement& e ) +{ + TQDomElement p = e.parentNode().toElement(); + TQString name; + + if ( getClassName(p) != "TQLayoutWidget" ) + name = "Layout"; + + TQDomElement n = getObjectProperty( p, "name" ); + if ( n.firstChild().toElement().tagName() == "cstring" ) { + name.prepend( n.firstChild().toElement().firstChild().toText().data() ); + return TQStringList::split( "::", name ).last(); + } + return e.tagName(); +} + + +TQString Uic::getDatabaseInfo( const TQDomElement& e, const TQString& tag ) +{ + TQDomElement n; + TQDomElement n1; + int child = 0; + // database info is a stringlist stored in this order + if ( tag == "connection" ) + child = 0; + else if ( tag == "table" ) + child = 1; + else if ( tag == "field" ) + child = 2; + else + return TQString::null; + n = getObjectProperty( e, "database" ); + if ( n.firstChild().toElement().tagName() == "stringlist" ) { + // find correct stringlist entry + TQDomElement n1 = n.firstChild().firstChild().toElement(); + for ( int i = 0; i < child && !n1.isNull(); ++i ) + n1 = n1.nextSibling().toElement(); + if ( n1.isNull() ) + return TQString::null; + return n1.firstChild().toText().data(); + } + return TQString::null; +} + + +void Uic::registerLayouts( const TQDomElement &e ) +{ + if ( layouts.contains(e.tagName())) { + createObjectDecl(e); + TQString t = e.tagName(); + if ( t == "vbox" || t == "hbox" || t == "grid" ) + createSpacerDecl( e ); + } + + TQDomNodeList nl = e.childNodes(); + for ( int i = 0; i < (int) nl.length(); ++i ) + registerLayouts( nl.item(i).toElement() ); +} + + +/*! + Returns include file for class \a className or a null string. + */ +TQString Uic::getInclude( const TQString& className ) +{ + int wid = WidgetDatabase::idFromClassName( className ); + if ( wid != -1 ) + return WidgetDatabase::includeFile( wid ); + return TQString::null; +} + + +void Uic::createActionDecl( const TQDomElement& e ) +{ + TQString objClass = e.tagName() == "action" ? "TQAction" : "TQActionGroup"; + TQString objName = getObjectName( e ); + if ( objName.isEmpty() ) + return; + out << " " << objClass << "* " << objName << ";" << endl; + if ( e.tagName() == "actiongroup" ) { + for ( TQDomElement n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "action" || n.tagName() == "actiongroup" ) + createActionDecl( n ); + } + } +} + +void Uic::createToolbarDecl( const TQDomElement &e ) +{ + if ( e.tagName() == "toolbar" ) + out << " " << "TQToolBar *" << getObjectName( e ) << ";" << endl; +} + +void Uic::createMenuBarDecl( const TQDomElement &e ) +{ + if ( e.tagName() == "item" ) { + out << " " << "TQPopupMenu *" << e.attribute( "name" ) << ";" << endl; + createPopupMenuDecl( e ); + } +} + +void Uic::createPopupMenuDecl( const TQDomElement &e ) +{ + for ( TQDomElement n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "action" || n.tagName() == "actiongroup" ) { + TQDomElement n2 = n.nextSibling().toElement(); + if ( n2.tagName() == "item" ) { // the action has a sub menu + out << " " << "TQPopupMenu *" << n2.attribute( "name" ) << ";" << endl; + createPopupMenuDecl( n2 ); + n = n2; + } + } + } +} + +void Uic::createActionImpl( const TQDomElement &n, const TQString &parent ) +{ + for ( TQDomElement ae = n; !ae.isNull(); ae = ae.nextSibling().toElement() ) { + TQString objName = registerObject( getObjectName( ae ) ); + if ( ae.tagName() == "action" ) + out << indent << objName << " = new TQAction( " << parent << ", \"" << objName << "\" );" << endl; + else if ( ae.tagName() == "actiongroup" ) + out << indent << objName << " = new TQActionGroup( " << parent << ", \"" << objName << "\" );" << endl; + else + continue; + bool subActionsDone = FALSE; + bool hasMenuText = FALSE; + TQString actionText; + for ( TQDomElement n2 = ae.firstChild().toElement(); !n2.isNull(); n2 = n2.nextSibling().toElement() ) { + if ( n2.tagName() == "property" ) { + bool stdset = stdsetdef; + if ( n2.hasAttribute( "stdset" ) ) + stdset = toBool( n2.attribute( "stdset" ) ); + TQString prop = n2.attribute("name"); + if ( prop == "name" ) + continue; + TQString value = setObjectProperty( "TQAction", objName, prop, n2.firstChild().toElement(), stdset ); + if ( value.isEmpty() ) + continue; + + TQString call = objName + "->"; + if ( stdset ) { + call += mkStdSet( prop ) + "( "; + } else { + call += "setProperty( \"" + prop + "\", "; + } + call += value + " );"; + + if (prop == "menuText") + hasMenuText = TRUE; + else if (prop == "text") + actionText = value; + + if ( n2.firstChild().toElement().tagName() == "string" ) { + trout << indent << call << endl; + } else { + out << indent << call << endl; + } + } else if ( !subActionsDone && ( n2.tagName() == "actiongroup" || n2.tagName() == "action" ) ) { + createActionImpl( n2, objName ); + subActionsDone = TRUE; + } + } + // workaround for loading pre-3.3 files expecting bogus TQAction behavior + if (!hasMenuText && !actionText.isEmpty() && uiFileVersion < "3.3") + trout << indent << objName << "->setMenuText(" << actionText << ");" << endl; + } +} + +TQString get_dock( const TQString &d ) +{ + if ( d == "0" ) + return "DockUnmanaged"; + if ( d == "1" ) + return "DockTornOff"; + if ( d == "2" ) + return "DockTop"; + if ( d == "3" ) + return "DockBottom"; + if ( d == "4" ) + return "DockRight"; + if ( d == "5" ) + return "DockLeft"; + if ( d == "6" ) + return "DockMinimized"; + return ""; +} + +void Uic::createToolbarImpl( const TQDomElement &n, const TQString &parentClass, const TQString &parent ) +{ + TQDomNodeList nl = n.elementsByTagName( "toolbar" ); + for ( int i = 0; i < (int) nl.length(); i++ ) { + TQDomElement ae = nl.item( i ).toElement(); + TQString dock = get_dock( ae.attribute( "dock" ) ); + TQString objName = getObjectName( ae ); + out << indent << objName << " = new TQToolBar( TQString(\"\"), this, " << dock << " ); " << endl; + createObjectImpl( ae, parentClass, parent ); + for ( TQDomElement n2 = ae.firstChild().toElement(); !n2.isNull(); n2 = n2.nextSibling().toElement() ) { + if ( n2.tagName() == "action" ) { + out << indent << n2.attribute( "name" ) << "->addTo( " << objName << " );" << endl; + } else if ( n2.tagName() == "separator" ) { + out << indent << objName << "->addSeparator();" << endl; + } else if ( n2.tagName() == "widget" ) { + if ( n2.attribute( "class" ) != "Spacer" ) { + createObjectImpl( n2, "TQToolBar", objName ); + } else { + TQString child = createSpacerImpl( n2, parentClass, parent, objName ); + out << indent << "TQApplication::sendPostedEvents( " << objName + << ", TQEvent::ChildInserted );" << endl; + out << indent << objName << "->boxLayout()->addItem( " << child << " );" << endl; + } + } + } + } +} + +void Uic::createMenuBarImpl( const TQDomElement &n, const TQString &parentClass, const TQString &parent ) +{ + TQString objName = getObjectName( n ); + out << indent << objName << " = new TQMenuBar( this, \"" << objName << "\" );" << endl; + createObjectImpl( n, parentClass, parent ); + int i = 0; + TQDomElement c = n.firstChild().toElement(); + while ( !c.isNull() ) { + if ( c.tagName() == "item" ) { + TQString itemName = c.attribute( "name" ); + out << endl; + out << indent << itemName << " = new TQPopupMenu( this );" << endl; + createPopupMenuImpl( c, parentClass, itemName ); + out << indent << objName << "->insertItem( TQString(\"\"), " << itemName << ", " << i << " );" << endl; + TQString findItem(objName + "->findItem(%1)"); + findItem = findItem.arg(i); + trout << indent << "if (" << findItem << ")" << endl; + trout << indent << indent << findItem << "->setText( " << trcall( c.attribute( "text" ) ) << " );" << endl; + } else if ( c.tagName() == "separator" ) { + out << endl; + out << indent << objName << "->insertSeparator( " << i << " );" << endl; + } + c = c.nextSibling().toElement(); + i++; + } +} + +void Uic::createPopupMenuImpl( const TQDomElement &e, const TQString &parentClass, const TQString &parent ) +{ + int i = 0; + for ( TQDomElement n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "action" || n.tagName() == "actiongroup" ) { + TQDomElement n2 = n.nextSibling().toElement(); + if ( n2.tagName() == "item" ) { // the action has a sub menu + TQString itemName = n2.attribute( "name" ); + TQString itemText = n2.attribute( "text" ); + out << indent << itemName << " = new TQPopupMenu( this );" << endl; + out << indent << parent << "->insertItem( " << n.attribute( "name" ) << "->iconSet(), "; + out << trcall( itemText ) << ", " << itemName << " );" << endl; + trout << indent << parent << "->changeItem( " << parent << "->idAt( " << i << " ), "; + trout << trcall( itemText ) << " );" << endl; + createPopupMenuImpl( n2, parentClass, itemName ); + n = n2; + } else { + out << indent << n.attribute( "name" ) << "->addTo( " << parent << " );" << endl; + } + } else if ( n.tagName() == "separator" ) { + out << indent << parent << "->insertSeparator();" << endl; + } + ++i; + } +} + +/*! + Creates implementation of an listbox item tag. +*/ + +TQString Uic::createListBoxItemImpl( const TQDomElement &e, const TQString &parent, + TQString *value ) +{ + TQDomElement n = e.firstChild().toElement(); + TQString txt; + TQString com; + TQString pix; + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + TQString attrib = n.attribute( "name" ); + TQVariant v = DomTool::elementToVariant( n.firstChild().toElement(), TQVariant() ); + if ( attrib == "text" ) { + txt = v.toString(); + com = getComment( n ); + } else if ( attrib == "pixmap" ) { + pix = v.toString(); + if ( !pix.isEmpty() && !pixmapLoaderFunction.isEmpty() ) { + pix.prepend( pixmapLoaderFunction + "( " + TQString( externPixmaps ? "\"" : "" ) ); + pix.append( TQString( externPixmaps ? "\"" : "" ) + " )" ); + } + } + } + n = n.nextSibling().toElement(); + } + + if ( value ) + *value = trcall( txt, com ); + + if ( pix.isEmpty() ) { + return parent + "->insertItem( " + trcall( txt, com ) + " );"; + } else { + return parent + "->insertItem( " + pix + ", " + trcall( txt, com ) + " );"; + } +} + +/*! + Creates implementation of an iconview item tag. +*/ + +TQString Uic::createIconViewItemImpl( const TQDomElement &e, const TQString &parent ) +{ + TQDomElement n = e.firstChild().toElement(); + TQString txt; + TQString com; + TQString pix; + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + TQString attrib = n.attribute( "name" ); + TQVariant v = DomTool::elementToVariant( n.firstChild().toElement(), TQVariant() ); + if ( attrib == "text" ) { + txt = v.toString(); + com = getComment( n ); + } else if ( attrib == "pixmap" ) { + pix = v.toString(); + if ( !pix.isEmpty() && !pixmapLoaderFunction.isEmpty() ) { + pix.prepend( pixmapLoaderFunction + "( " + TQString( externPixmaps ? "\"" : "" ) ); + pix.append( TQString( externPixmaps ? "\"" : "" ) + " )" ); + } + } + } + n = n.nextSibling().toElement(); + } + + if ( pix.isEmpty() ) + return "(void) new TQIconViewItem( " + parent + ", " + trcall( txt, com ) + " );"; + else + return "(void) new TQIconViewItem( " + parent + ", " + trcall( txt, com ) + ", " + pix + " );"; +} + +/*! + Creates implementation of an listview item tag. +*/ + +TQString Uic::createListViewItemImpl( const TQDomElement &e, const TQString &parent, + const TQString &parentItem ) +{ + TQString s; + + TQDomElement n = e.firstChild().toElement(); + + bool hasChildren = e.elementsByTagName( "item" ).count() > 0; + TQString item; + + if ( hasChildren ) { + item = registerObject( "item" ); + s = indent + "TQListViewItem * " + item + " = "; + } else { + item = "item"; + if ( item_used ) + s = indent + item + " = "; + else + s = indent + "TQListViewItem * " + item + " = "; + item_used = TRUE; + } + + if ( !parentItem.isEmpty() ) + s += "new TQListViewItem( " + parentItem + ", " + lastItem + " );\n"; + else + s += "new TQListViewItem( " + parent + ", " + lastItem + " );\n"; + + TQStringList texts; + TQStringList pixmaps; + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + TQString attrib = n.attribute("name"); + TQVariant v = DomTool::elementToVariant( n.firstChild().toElement(), TQVariant() ); + if ( attrib == "text" ) + texts << v.toString(); + else if ( attrib == "pixmap" ) { + TQString pix = v.toString(); + if ( !pix.isEmpty() && !pixmapLoaderFunction.isEmpty() ) { + pix.prepend( pixmapLoaderFunction + "( " + TQString( externPixmaps ? "\"" : "" ) ); + pix.append( TQString( externPixmaps ? "\"" : "" ) + " )" ); + } + pixmaps << pix; + } + } else if ( n.tagName() == "item" ) { + s += indent + item + "->setOpen( TRUE );\n"; + s += createListViewItemImpl( n, parent, item ); + } + n = n.nextSibling().toElement(); + } + + for ( int i = 0; i < (int)texts.count(); ++i ) { + if ( !texts[ i ].isEmpty() ) + s += indent + item + "->setText( " + TQString::number( i ) + ", " + trcall( texts[ i ] ) + " );\n"; + if ( !pixmaps[ i ].isEmpty() ) + s += indent + item + "->setPixmap( " + TQString::number( i ) + ", " + pixmaps[ i ] + " );\n"; + } + + lastItem = item; + return s; +} + +/*! + Creates implementation of an listview column tag. +*/ + +TQString Uic::createListViewColumnImpl( const TQDomElement &e, const TQString &parent, + TQString *value ) +{ + TQDomElement n = e.firstChild().toElement(); + TQString txt; + TQString com; + TQString pix; + bool clickable = FALSE, resizable = FALSE; + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + TQString attrib = n.attribute("name"); + TQVariant v = DomTool::elementToVariant( n.firstChild().toElement(), TQVariant() ); + if ( attrib == "text" ) { + txt = v.toString(); + com = getComment( n ); + } else if ( attrib == "pixmap" ) { + pix = v.toString(); + if ( !pix.isEmpty() && !pixmapLoaderFunction.isEmpty() ) { + pix.prepend( pixmapLoaderFunction + "( " + TQString( externPixmaps ? "\"" : "" ) ); + pix.append( TQString( externPixmaps ? "\"" : "" ) + " )" ); + } + } else if ( attrib == "clickable" ) + clickable = v.toBool(); + else if ( attrib == "resizable" || attrib == "resizeable" ) + resizable = v.toBool(); + } + n = n.nextSibling().toElement(); + } + + if ( value ) + *value = trcall( txt, com ); + + TQString s; + s = indent + parent + "->addColumn( " + trcall( txt, com ) + " );\n"; + if ( !pix.isEmpty() ) + s += indent + parent + "->header()->setLabel( " + parent + "->header()->count() - 1, " + pix + ", " + trcall( txt, com ) + " );\n"; + if ( !clickable ) + s += indent + parent + "->header()->setClickEnabled( FALSE, " + parent + "->header()->count() - 1 );\n"; + if ( !resizable ) + s += indent + parent + "->header()->setResizeEnabled( FALSE, " + parent + "->header()->count() - 1 );\n"; + return s; +} + +TQString Uic::createTableRowColumnImpl( const TQDomElement &e, const TQString &parent, + TQString *value ) +{ + TQString objClass = getClassName( e.parentNode().toElement() ); + TQDomElement n = e.firstChild().toElement(); + TQString txt; + TQString com; + TQString pix; + TQString field; + bool isRow = e.tagName() == "row"; + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + TQString attrib = n.attribute("name"); + TQVariant v = DomTool::elementToVariant( n.firstChild().toElement(), TQVariant() ); + if ( attrib == "text" ) { + txt = v.toString(); + com = getComment( n ); + } else if ( attrib == "pixmap" ) { + pix = v.toString(); + if ( !pix.isEmpty() && !pixmapLoaderFunction.isEmpty() ) { + pix.prepend( pixmapLoaderFunction + "( " + TQString( externPixmaps ? "\"" : "" ) ); + pix.append( TQString( externPixmaps ? "\"" : "" ) + " )" ); + } + } else if ( attrib == "field" ) + field = v.toString(); + } + n = n.nextSibling().toElement(); + } + + if ( value ) + *value = trcall( txt, com ); + + // ### This generated code sucks! We have to set the number of + // rows/cols before and then only do setLabel/() + // ### careful, though, since TQDataTable has an API which makes this code pretty good + + TQString s; + if ( isRow ) { + s = indent + parent + "->setNumRows( " + parent + "->numRows() + 1 );\n"; + if ( pix.isEmpty() ) + s += indent + parent + "->verticalHeader()->setLabel( " + parent + "->numRows() - 1, " + + trcall( txt, com ) + " );\n"; + else + s += indent + parent + "->verticalHeader()->setLabel( " + parent + "->numRows() - 1, " + + pix + ", " + trcall( txt, com ) + " );\n"; + } else { + if ( objClass == "TQTable" ) { + s = indent + parent + "->setNumCols( " + parent + "->numCols() + 1 );\n"; + if ( pix.isEmpty() ) + s += indent + parent + "->horizontalHeader()->setLabel( " + parent + "->numCols() - 1, " + + trcall( txt, com ) + " );\n"; + else + s += indent + parent + "->horizontalHeader()->setLabel( " + parent + "->numCols() - 1, " + + pix + ", " + trcall( txt, com ) + " );\n"; + } else if ( objClass == "TQDataTable" ) { + if ( !txt.isEmpty() && !field.isEmpty() ) { + if ( pix.isEmpty() ) + out << indent << parent << "->addColumn( " << fixString( field ) << ", " << trcall( txt, com ) << " );" << endl; + else + out << indent << parent << "->addColumn( " << fixString( field ) << ", " << trcall( txt, com ) << ", " << pix << " );" << endl; + } + } + } + return s; +} + +/*! + Creates the implementation of a layout tag. Called from createObjectImpl(). + */ +TQString Uic::createLayoutImpl( const TQDomElement &e, const TQString& parentClass, const TQString& parent, const TQString& layout ) +{ + TQDomElement n; + TQString objClass, objName; + objClass = e.tagName(); + + TQString qlayout = "TQVBoxLayout"; + if ( objClass == "hbox" ) + qlayout = "TQHBoxLayout"; + else if ( objClass == "grid" ) + qlayout = "TQGridLayout"; + + bool isGrid = e.tagName() == "grid" ; + objName = registerObject( getLayoutName( e ) ); + layoutObjects += objName; + + TQString margin = DomTool::readProperty( e, "margin", defMargin ).toString(); + TQString spacing = DomTool::readProperty( e, "spacing", defSpacing ).toString(); + TQString resizeMode = DomTool::readProperty( e, "resizeMode", TQString::null ).toString(); + + TQString optcells; + if ( isGrid ) + optcells = "1, 1, "; + if ( (parentClass == "TQGroupBox" || parentClass == "TQButtonGroup") && layout.isEmpty() ) { + // special case for group box + out << indent << parent << "->setColumnLayout(0, TQt::Vertical );" << endl; + out << indent << parent << "->layout()->setSpacing( " << spacing << " );" << endl; + out << indent << parent << "->layout()->setMargin( " << margin << " );" << endl; + out << indent << objName << " = new " << qlayout << "( " << parent << "->layout() );" << endl; + out << indent << objName << "->setAlignment( TQt::AlignTop );" << endl; + } else { + out << indent << objName << " = new " << qlayout << "( "; + if ( layout.isEmpty() ) + out << parent; + else { + out << "0"; + if ( !DomTool::hasProperty( e, "margin" ) ) + margin = "0"; + } + out << ", " << optcells << margin << ", " << spacing << ", \"" << objName << "\"); " << endl; + } + if ( !resizeMode.isEmpty() ) + out << indent << objName << "->setResizeMode( TQLayout::" << resizeMode << " );" << endl; + + if ( !isGrid ) { + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "spacer" ) { + TQString child = createSpacerImpl( n, parentClass, parent, objName ); + out << indent << objName << "->addItem( " << child << " );" << endl; + } else if ( tags.contains( n.tagName() ) ) { + TQString child = createObjectImpl( n, parentClass, parent, objName ); + if ( isLayout( child ) ) + out << indent << objName << "->addLayout( " << child << " );" << endl; + else + out << indent << objName << "->addWidget( " << child << " );" << endl; + } + } + } else { + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + TQDomElement ae = n; + int row = ae.attribute( "row" ).toInt(); + int col = ae.attribute( "column" ).toInt(); + int rowspan = ae.attribute( "rowspan" ).toInt(); + int colspan = ae.attribute( "colspan" ).toInt(); + if ( rowspan < 1 ) + rowspan = 1; + if ( colspan < 1 ) + colspan = 1; + if ( n.tagName() == "spacer" ) { + TQString child = createSpacerImpl( n, parentClass, parent, objName ); + if ( rowspan * colspan != 1 ) + out << indent << objName << "->addMultiCell( " << child << ", " + << row << ", " << ( row + rowspan - 1 ) << ", " << col << ", " << ( col + colspan - 1 ) << " );" << endl; + else + out << indent << objName << "->addItem( " << child << ", " + << row << ", " << col << " );" << endl; + } else if ( tags.contains( n.tagName() ) ) { + TQString child = createObjectImpl( n, parentClass, parent, objName ); + out << endl; + TQString o = "Widget"; + if ( isLayout( child ) ) + o = "Layout"; + if ( rowspan * colspan != 1 ) + out << indent << objName << "->addMultiCell" << o << "( " << child << ", " + << row << ", " << ( row + rowspan - 1 ) << ", " << col << ", " << ( col + colspan - 1 ) << " );" << endl; + else + out << indent << objName << "->add" << o << "( " << child << ", " + << row << ", " << col << " );" << endl; + } + } + } + + return objName; +} + + + +TQString Uic::createSpacerImpl( const TQDomElement &e, const TQString& /*parentClass*/, const TQString& /*parent*/, const TQString& /*layout*/) +{ + TQDomElement n; + TQString objClass, objName; + objClass = e.tagName(); + objName = registerObject( getObjectName( e ) ); + + TQSize size = DomTool::readProperty( e, "sizeHint", TQSize( 0, 0 ) ).toSize(); + TQString sizeType = DomTool::readProperty( e, "sizeType", "Expanding" ).toString(); + bool isVspacer = DomTool::readProperty( e, "orientation", "Horizontal" ) == "Vertical"; + + if ( sizeType != "Expanding" && sizeType != "MinimumExpanding" && + DomTool::hasProperty( e, "geometry" ) ) { // compatibility TQt 2.2 + TQRect geom = DomTool::readProperty( e, "geometry", TQRect(0,0,0,0) ).toRect(); + size = geom.size(); + } + + if ( isVspacer ) + out << " " << objName << " = new TQSpacerItem( " + << size.width() << ", " << size.height() + << ", TQSizePolicy::Minimum, TQSizePolicy::" << sizeType << " );" << endl; + else + out << " " << objName << " = new TQSpacerItem( " + << size.width() << ", " << size.height() + << ", TQSizePolicy::" << sizeType << ", TQSizePolicy::Minimum );" << endl; + + return objName; +} + +static const char* const ColorRole[] = { + "Foreground", "Button", "Light", "Midlight", "Dark", "Mid", + "Text", "BrightText", "ButtonText", "Base", "Background", "Shadow", + "Highlight", "HighlightedText", "Link", "LinkVisited", 0 +}; + + +/*! + Creates a colorgroup with name \a name from the color group \a cg + */ +void Uic::createColorGroupImpl( const TQString& name, const TQDomElement& e ) +{ + TQColorGroup cg; + int r = -1; + TQDomElement n = e.firstChild().toElement(); + TQString color; + while ( !n.isNull() ) { + if ( n.tagName() == "color" ) { + r++; + TQColor col = DomTool::readColor( n ); + color = "TQColor( %1, %2, %3)"; + color = color.arg( col.red() ).arg( col.green() ).arg( col.blue() ); + if ( col == white ) + color = "white"; + else if ( col == black ) + color = "black"; + if ( n.nextSibling().toElement().tagName() != "pixmap" ) { + out << indent << name << ".setColor( TQColorGroup::" << ColorRole[r] << ", " << color << " );" << endl; + } + } else if ( n.tagName() == "pixmap" ) { + TQString pixmap = n.firstChild().toText().data(); + if ( !pixmapLoaderFunction.isEmpty() ) { + pixmap.prepend( pixmapLoaderFunction + "( " + TQString( externPixmaps ? "\"" : "" ) ); + pixmap.append( TQString( externPixmaps ? "\"" : "" ) + " )" ); + } + out << indent << name << ".setBrush( TQColorGroup::" + << ColorRole[r] << ", TQBrush( " << color << ", " << pixmap << " ) );" << endl; + } + n = n.nextSibling().toElement(); + } +} + +/*! + Auxiliary function to load a color group. The colorgroup must not + contain pixmaps. + */ +TQColorGroup Uic::loadColorGroup( const TQDomElement &e ) +{ + TQColorGroup cg; + int r = -1; + TQDomElement n = e.firstChild().toElement(); + TQColor col; + while ( !n.isNull() ) { + if ( n.tagName() == "color" ) { + r++; + cg.setColor( (TQColorGroup::ColorRole)r, (col = DomTool::readColor( n ) ) ); + } + n = n.nextSibling().toElement(); + } + return cg; +} + +/*! Returns TRUE if the widget properties specify that it belongs to + the database \a connection and \a table. +*/ + +bool Uic::isWidgetInTable( const TQDomElement& e, const TQString& connection, const TQString& table ) +{ + TQString conn = getDatabaseInfo( e, "connection" ); + TQString tab = getDatabaseInfo( e, "table" ); + if ( conn == connection && tab == table ) + return TRUE; + return FALSE; +} + +/*! + Registers all database connections, cursors and forms. +*/ + +void Uic::registerDatabases( const TQDomElement& e ) +{ + TQDomElement n; + TQDomNodeList nl; + int i; + nl = e.parentNode().toElement().elementsByTagName( "widget" ); + for ( i = 0; i < (int) nl.length(); ++i ) { + n = nl.item(i).toElement(); + TQString conn = getDatabaseInfo( n, "connection" ); + TQString tab = getDatabaseInfo( n, "table" ); + TQString fld = getDatabaseInfo( n, "field" ); + if ( !conn.isNull() ) { + dbConnections += conn; + if ( !tab.isNull() ) { + dbCursors[conn] += tab; + if ( !fld.isNull() ) + dbForms[conn] += tab; + } + } + } +} + +/*! + Registers an object with name \a name. + + The returned name is a valid variable identifier, as similar to \a + name as possible and guaranteed to be unique within the form. + + \sa registeredName(), isObjectRegistered() + */ +TQString Uic::registerObject( const TQString& name ) +{ + if ( objectNames.isEmpty() ) { + // some temporary variables we need + objectNames += "img"; + objectNames += "item"; + objectNames += "cg"; + objectNames += "pal"; + } + + TQString result = name; + int i; + while ( ( i = result.find(' ' )) != -1 ) { + result[i] = '_'; + } + + if ( objectNames.contains( result ) ) { + int i = 2; + while ( objectNames.contains( result + "_" + TQString::number(i) ) ) + i++; + result += "_"; + result += TQString::number(i); + } + objectNames += result; + objectMapper.insert( name, result ); + return result; +} + +/*! + Returns the registered name for the original name \a name + or \a name if \a name wasn't registered. + + \sa registerObject(), isObjectRegistered() + */ +TQString Uic::registeredName( const TQString& name ) +{ + if ( !objectMapper.contains( name ) ) + return name; + return objectMapper[name]; +} + +/*! + Returns whether the object \a name was registered yet or not. + */ +bool Uic::isObjectRegistered( const TQString& name ) +{ + return objectMapper.contains( name ); +} + + +/*! + Unifies the entries in stringlist \a list. Should really be a TQStringList feature. + */ +TQStringList Uic::unique( const TQStringList& list ) +{ + if ( list.isEmpty() ) + return list; + + TQStringList result; + for ( TQStringList::ConstIterator it = list.begin(); it != list.end(); ++it ) { + if ( !result.contains(*it) ) + result += *it; + } + return result; +} + + + +/*! + Creates an instance of class \a objClass, with parent \a parent and name \a objName + */ +TQString Uic::createObjectInstance( const TQString& objClass, const TQString& parent, const TQString& objName ) +{ + + if ( objClass.mid( 1 ) == "ComboBox" ) { + return objClass + "( FALSE, " + parent + ", \"" + objName + "\" )"; + } + return objClass + "( " + parent + ", \"" + objName + "\" )"; +} + +bool Uic::isLayout( const TQString& name ) const +{ + return layoutObjects.contains( name ); +} + + + diff --git a/tools/designer/uic/uic.h b/tools/designer/uic/uic.h new file mode 100644 index 000000000..90f8cdf5b --- /dev/null +++ b/tools/designer/uic/uic.h @@ -0,0 +1,176 @@ +/********************************************************************** +** 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 sales@trolltech.com. +** +** 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. +** +**********************************************************************/ + +#ifndef UIC_H +#define UIC_H +#include <qdom.h> +#include <qstring.h> +#include <qstringlist.h> +#include <qmap.h> +#include <qtextstream.h> +#include <qpalette.h> +#include <qvariant.h> + +class Uic : public TQt +{ +public: + Uic( const TQString &fn, const char *outputFn, TQTextStream& out, + TQDomDocument doc, bool decl, bool subcl, const TQString &trm, + const TQString& subclname, bool omitForwardDecls ); + + void createFormDecl( const TQDomElement &e ); + void createFormImpl( const TQDomElement &e ); + + void createSubDecl( const TQDomElement &e, const TQString& subclname ); + void createSubImpl( const TQDomElement &e, const TQString& subclname ); + + void createObjectDecl( const TQDomElement &e ); + void createSpacerDecl( const TQDomElement &e ); + void createActionDecl( const TQDomElement &e ); + void createToolbarDecl( const TQDomElement &e ); + void createMenuBarDecl( const TQDomElement &e ); + void createPopupMenuDecl( const TQDomElement &e ); + void createActionImpl( const TQDomElement &e, const TQString &parent ); + void createToolbarImpl( const TQDomElement &e, const TQString &parentClass, const TQString &parent ); + void createMenuBarImpl( const TQDomElement &e, const TQString &parentClass, const TQString &parent ); + void createPopupMenuImpl( const TQDomElement &e, const TQString &parentClass, const TQString &parent ); + TQString createObjectImpl( const TQDomElement &e, const TQString& parentClass, const TQString& parent, const TQString& layout = TQString::null ); + TQString createLayoutImpl( const TQDomElement &e, const TQString& parentClass, const TQString& parent, const TQString& layout = TQString::null ); + TQString createObjectInstance( const TQString& objClass, const TQString& parent, const TQString& objName ); + TQString createSpacerImpl( const TQDomElement &e, const TQString& parentClass, const TQString& parent, const TQString& layout = TQString::null ); + void createExclusiveProperty( const TQDomElement & e, const TQString& exclusiveProp ); + TQString createListBoxItemImpl( const TQDomElement &e, const TQString &parent, TQString *value = 0 ); + TQString createIconViewItemImpl( const TQDomElement &e, const TQString &parent ); + TQString createListViewColumnImpl( const TQDomElement &e, const TQString &parent, TQString *value = 0 ); + TQString createTableRowColumnImpl( const TQDomElement &e, const TQString &parent, TQString *value = 0 ); + TQString createListViewItemImpl( const TQDomElement &e, const TQString &parent, + const TQString &parentItem ); + void createColorGroupImpl( const TQString& cg, const TQDomElement& e ); + TQColorGroup loadColorGroup( const TQDomElement &e ); + + TQDomElement getObjectProperty( const TQDomElement& e, const TQString& name ); + TQString getPixmapLoaderFunction( const TQDomElement& e ); + TQString getFormClassName( const TQDomElement& e ); + TQString getClassName( const TQDomElement& e ); + TQString getObjectName( const TQDomElement& e ); + TQString getLayoutName( const TQDomElement& e ); + TQString getInclude( const TQString& className ); + + TQString setObjectProperty( const TQString& objClass, const TQString& obj, const TQString &prop, const TQDomElement &e, bool stdset ); + + TQString registerObject( const TQString& name ); + TQString registeredName( const TQString& name ); + bool isObjectRegistered( const TQString& name ); + TQStringList unique( const TQStringList& ); + + TQString trcall( const TQString& sourceText, const TQString& comment = "" ); + + static void embed( TQTextStream& out, const char* project, const TQStringList& images ); + +private: + void registerLayouts ( const TQDomElement& e ); + + TQTextStream& out; + TQTextOStream trout; + TQString languageChangeBody; + TQCString outputFileName; + TQStringList objectNames; + TQMap<TQString,TQString> objectMapper; + TQString indent; + TQStringList tags; + TQStringList layouts; + TQString formName; + TQString lastItem; + TQString trmacro; + bool nofwd; + + struct Buddy + { + Buddy( const TQString& k, const TQString& b ) + : key( k ), buddy( b ) {} + Buddy(){} // for valuelist + TQString key; + TQString buddy; + bool operator==( const Buddy& other ) const + { return (key == other.key); } + }; + struct CustomInclude + { + TQString header; + TQString location; + Q_DUMMY_COMPARISON_OPERATOR(CustomInclude) + }; + TQValueList<Buddy> buddies; + + TQStringList layoutObjects; + bool isLayout( const TQString& name ) const; + + uint item_used : 1; + uint cg_used : 1; + uint pal_used : 1; + uint stdsetdef : 1; + uint externPixmaps : 1; + + TQString uiFileVersion; + TQString nameOfClass; + TQStringList namespaces; + TQString bareNameOfClass; + TQString pixmapLoaderFunction; + + void registerDatabases( const TQDomElement& e ); + bool isWidgetInTable( const TQDomElement& e, const TQString& connection, const TQString& table ); + bool isFrameworkCodeGenerated( const TQDomElement& e ); + TQString getDatabaseInfo( const TQDomElement& e, const TQString& tag ); + void createFormImpl( const TQDomElement& e, const TQString& form, const TQString& connection, const TQString& table ); + void writeFunctionsDecl( const TQStringList &fuLst, const TQStringList &typLst, const TQStringList &specLst ); + void writeFunctionsSubDecl( const TQStringList &fuLst, const TQStringList &typLst, const TQStringList &specLst ); + void writeFunctionsSubImpl( const TQStringList &fuLst, const TQStringList &typLst, const TQStringList &specLst, + const TQString &subClass, const TQString &descr ); + TQStringList dbConnections; + TQMap< TQString, TQStringList > dbCursors; + TQMap< TQString, TQStringList > dbForms; + + static bool isMainWindow; + static TQString mkBool( bool b ); + static TQString mkBool( const TQString& s ); + bool toBool( const TQString& s ); + static TQString fixString( const TQString &str, bool encode = FALSE ); + static bool onlyAscii; + static TQString mkStdSet( const TQString& prop ); + static TQString getComment( const TQDomNode& n ); + TQVariant defSpacing, defMargin; + TQString fileName; + bool writeFunctImpl; +}; + +#endif diff --git a/tools/designer/uic/uic.pro b/tools/designer/uic/uic.pro new file mode 100644 index 000000000..ef5bde012 --- /dev/null +++ b/tools/designer/uic/uic.pro @@ -0,0 +1,42 @@ +TEMPLATE = app +CONFIG += qt console warn_on release professional +HEADERS = uic.h \ + ../shared/widgetdatabase.h \ + ../shared/domtool.h \ + ../shared/parser.h \ + ../interfaces/widgetinterface.h + +#HEADERS += ../shared/ui2uib.h \ +# ../shared/uib.h + +SOURCES = main.cpp uic.cpp form.cpp object.cpp \ + subclassing.cpp embed.cpp\ + ../shared/widgetdatabase.cpp \ + ../shared/domtool.cpp \ + ../shared/parser.cpp + +#SOURCES += ../shared/ui2uib.cpp \ +# ../shared/uib.cpp + +DEFINES += QT_INTERNAL_XML +include( ../../../src/qt_professional.pri ) + +TARGET = uic +INCLUDEPATH += ../shared +DEFINES += UIC +DESTDIR = ../../../bin + +target.path=$$bins.path +INSTALLS += target + +*-mwerks { + TEMPLATE = lib + TARGET = McUic + CONFIG -= static + CONFIG += shared plugin + DEFINES += UIC_MWERKS_PLUGIN + MWERKSDIR = $(QT_SOURCE_TREE)/util/mwerks_plugin + INCLUDEPATH += $$MWERKSDIR/Headers + LIBS += $$MWERKSDIR/Libraries/PluginLib4.shlb + SOURCES += mwerks_mac.cpp +} |