📄 form.cpp
字号:
/************************************************************************ Copyright (C) 2000 Trolltech AS. All rights reserved.**** This file is part of Qt Designer.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/#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 QByteArray unzipXPM( QString 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 ); QByteArray baunzip = qUncompress( ba, baSize ); delete[] ba; return baunzip;}#if QT_VERSION >= 0x030900#error Add this functionality to QDir (relativePathTo() maybe?) and \remove it from here and from moc#endifQCString combinePath( const char *infile, const char *outfile ){ QFileInfo inFileInfo( QDir::current(), QFile::decodeName(infile) ); QFileInfo outFileInfo( QDir::current(), QFile::decodeName(outfile) ); int numCommonComponents = 0; QStringList inSplitted = QStringList::split( '/', inFileInfo.dir().canonicalPath(), TRUE ); QStringList outSplitted = QStringList::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 QFile::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 QFile::encodeName( inSplitted.join("/") ); }}/*! Creates a declaration (header file) for the form given in \a e \sa createFormImpl(), createObjectDecl()*/void Uic::createFormDecl( const QDomElement &e ){ QDomElement n; QDomNodeList nl; int i; QString objClass = getClassName( e ); if ( objClass.isEmpty() ) return; QString objName = getObjectName( e ); QStringList typeDefs; QMap<QString, CustomInclude> customWidgetIncludes; QString imageMembers; // at first the images QMap<QString, int> customWidgets; QStringList forwardDecl; QStringList forwardDecl2; QString 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++ ) { QString img = registerObject( nl.item(i).toElement().attribute("name") ); registerObject( img ); imageMembers += QString( " QPixmap %1;\n" ).arg( img ); } } else if ( n.tagName() == "customwidgets" ) { QDomElement n2 = n.firstChild().toElement(); while ( !n2.isNull() ) { if ( n2.tagName() == "customwidget" ) { QDomElement n3 = n2.firstChild().toElement(); QString 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 ); QString 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; QStringList globalIncludes, localIncludes; int wid = WidgetDatabase::idFromClassName( objClass ); { QMap<QString, 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++ ) { QDomElement n2 = nl.item(i).toElement(); QString 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++ ) { QDomElement n2 = nl.item(i).toElement(); QString 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; } } QStringList::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 QVBoxLayout;" << endl; out << "class QHBoxLayout;" << endl; out << "class QGridLayout;" << endl; if ( objClass == "QMainWindow" ) { out << "class QAction;" << endl; out << "class QActionGroup;" << endl; out << "class QToolBar;" << endl; out << "class QPopupMenu;" << endl; } bool dbForm = FALSE; registerDatabases( e ); dbConnections = unique( dbConnections ); if ( dbConnections.count() ) forwardDecl += "QSqlDatabase"; if ( dbCursors.count() ) forwardDecl += "QSqlCursor"; 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 += "QSqlForm"; 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 QString s = getClassName( nl.item(i).toElement() ); if ( s == "QLayoutWidget" ) continue; // hide qlayoutwidgets if ( s == "Line" ) s = "QFrame"; if ( !(nofwd && customWidgets.contains(s)) ) forwardDecl += s; if ( s.mid( 1 ) == "ListBox" || s.mid( 1 ) == "ListView" || s.mid( 1 ) == "IconView" ) forwardDecl += "Q" + s.mid( 1 ) + "Item"; if ( s == "QDataTable" ) { // other convenience classes which are used in QDataTable signals, and thus should be forward-declared by uic for us forwardDecl += "QSqlRecord"; } } } // 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++ ) { QDomElement n2 = nl.item(i).toElement(); QString 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++ ) { QDomElement n2 = nl.item(i).toElement(); QString 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 ) { QString forwardName = *it; QStringList forwardNamespaces = QStringList::split( "::", forwardName ); forwardName = forwardNamespaces.last(); forwardNamespaces.remove( forwardNamespaces.fromLast() ); QStringList::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 ) { QString fd = *it; fd = fd.stripWhiteSpace(); if ( !fd.endsWith( ";" ) ) fd += ";"; out << fd << endl; } out << endl; QStringList::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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -