form.cpp

来自「qt-x11-free-3.0.3.tar.gz minigui图形界面工具」· C++ 代码 · 共 1,243 行 · 第 1/3 页

CPP
1,243
字号
/************************************************************************ 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 <qfile.h>#include <qfileinfo.h>#define NO_STATIC_COLORS#include <globaldefs.h>#include <zlib.h>static QByteArray unzipXPM( QString data, ulong& length ){    uchar *ba = new uchar[ data.length() / 2 ];    for ( int i = 0; i < (int)data.length() / 2; ++i ) {	char h = data[ 2 * i ].latin1();	char l = data[ 2 * i  + 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;    }    // I'm not sure this makes sense. Why couldn't the compressed data be    // less than 20% of the original data? Maybe it's enough to trust the    // `length' passed as an argument. Quoting the zlib header:    // 		Upon entry, destLen is the total size of the destination    // 		buffer, which must be large enough to hold the entire    // 		uncompressed data. (The size of the uncompressed data must    // 		have been saved previously by the compressor and transmitted    // 		to the decompressor by some mechanism outside the scope of    // 		this compression library.)    // Which is the role of `length'. On the other hand this could prevent    // crashes in some cases of slightly corrupt UIC files.    if ( length <  data.length() * 5 )	length = data.length() * 5;    QByteArray baunzip( length );    ::uncompress( (uchar*) baunzip.data(), &length, ba, data.length()/2 );    delete[] ba;    return baunzip;}/*!  Creates a declaration ( headerfile ) 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;    // at first the images, we need to ensure the names are unique    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++ ) {		registerObject( nl.item(i).firstChild().firstChild().toText().data() );	    }	} 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";    out << "#ifndef " << protector << endl;    out << "#define " << protector << endl;    out << endl;    out << "#include <qvariant.h>" << endl; // for broken HP-UX compilers    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, it2, it3;    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;    }    // 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 )	    out << "class " << *it << ";" << endl;    }    for ( it = forwardDecl2.begin(); it != forwardDecl2.end(); ++it ) {	QString fd = *it;	fd = fd.stripWhiteSpace();	if ( !fd.endsWith( ";" ) )	    fd += ";";	out << fd << endl;    }    out << endl;    out << "class " << ( !exportMacro.isEmpty() ? QString( exportMacro + " " ) : QString( "" ) ) <<	nameOfClass << " : public " << objClass << endl;    out << "{ " << endl;/* tmake ignore Q_OBJECT */    out << "    Q_OBJECT" << endl;    out << endl;    out << "public:" << endl;    // constructor(s)    if ( objClass == "QDialog" || objClass == "QWizard" ) {	out << "    " << nameOfClass << "( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 );" << endl;    } else if ( objClass == "QWidget" ) {	out << "    " << nameOfClass << "( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );" << endl;    } else if ( objClass == "QMainWindow" ) {	out << "    " << nameOfClass << "( QWidget* parent = 0, const char* name = 0, WFlags fl = WType_TopLevel );" << endl;	isMainWindow = TRUE;    } else {	out << "    " << nameOfClass << "( QWidget* parent = 0, const char* name = 0 );" << endl;    }    // destructor    out << "    ~" << nameOfClass << "();" << endl;    out << endl;    // children    bool needEventHandler = FALSE;    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 );	needEventHandler = needEventHandler ||			   !DomTool::propertiesOfType( n, "font" ).isEmpty() ;	QString s = getClassName( n );	if ( s == "QDataTable" || s == "QDataBrowser" ) {	    if ( isFrameworkCodeGenerated( n ) )		 needPolish = TRUE;	}    }    // actions, toolbars, menus    for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) {	if ( n.tagName()  == "actions" ) {	    for ( QDomElement a = n.firstChild().toElement(); !a.isNull(); a = a.nextSibling().toElement() )		createActionDecl( a );	} else if ( n.tagName() == "toolbars" ) {	    for ( QDomElement a = n.firstChild().toElement(); !a.isNull(); a = a.nextSibling().toElement() )		createToolbarDecl( a );	} else if ( n.tagName() == "menubar" ) {	    out << "    " << "QMenuBar *" << getObjectName( n ) << ";" << endl;	    for ( QDomElement a = n.firstChild().toElement(); !a.isNull(); a = a.nextSibling().toElement() )		createMenuBarDecl( a );	}    }    out << endl;    // database connections    dbConnections = unique( dbConnections );    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 << "QSqlDatabase* " << *it << "Connection;" << endl;	}    }    out << endl;    // find signals    QStringList 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;	QString 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;    }    // find additional slots    QStringList publicSlots, protectedSlots, privateSlots;    QStringList publicSlotTypes, protectedSlotTypes, privateSlotTypes;    QStringList publicSlotSpecifier, protectedSlotSpecifier, privateSlotSpecifier;    QMap<QString, QString> functionImpls;    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;	QString returnType = n.attribute( "returnType", "void" );	QString slotName = n.firstChild().toText().data().stripWhiteSpace();	if ( slotName.endsWith( ";" ) )	    slotName = slotName.left( slotName.length() - 1 );	QString specifier = n.attribute( "specifier" );	QString access = n.attribute( "access" );	if ( access == "protected" ) {	    protectedSlots += slotName;	    protectedSlotTypes += returnType;	    protectedSlotSpecifier += specifier;	} else if ( access == "private" ) {	    privateSlots += slotName;	    privateSlotTypes += returnType;	    privateSlotSpecifier += specifier;	} else {	    publicSlots += slotName;	    publicSlotTypes += returnType;	    publicSlotSpecifier += specifier;	}    }    // create public additional slots    if ( !publicSlots.isEmpty() || needPolish ) {	out << "public slots:" << endl;	for ( it = publicSlots.begin(), it2 = publicSlotTypes.begin(), it3 = publicSlotSpecifier.begin();

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?