📄 uic.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 <qsizepolicy.h>#include <qpalette.h>#include <qfile.h>#include <stdio.h>#include <stdlib.h>#include <qstringlist.h>#include <qstrlist.h>#include <qdatetime.h>#include <widgetdatabase.h>#include <domtool.h>#include <globaldefs.h>#include <qregexp.h>#include <zlib.h>static QString getComment( const QDomNode& n ){ QDomNode child = n.firstChild(); while ( !child.isNull() ) { if ( child.toElement().tagName() == "comment" ) return child.toElement().firstChild().toText().data(); child = child.nextSibling(); } return QString::null;}static QString mkBool( bool b ){ return b? "TRUE" : "FALSE";}static QString mkBool( const QString& s ){ return mkBool( s == "true" || s == "1" );}static bool toBool( const QString& s ){ return s == "true" || s.toInt() != 0;}// fixString is only used in conjunction with tr(). We need to write out the // string in utf8 and make sure it's converted from utf8 when created.static QString fixString( const QString &str ){ QString s( str ); s.replace( QRegExp( "\\\\" ), "\\\\" ); s.replace( QRegExp( "\"" ), "\\\"" ); s.replace( QRegExp( "\n" ), "\\n\"\n\"" ); s.replace( QRegExp( "\r" ), "\\r" ); bool onlyAscii = TRUE; unsigned int i; for ( i = 0; i < s.length(); i++ ) { if ( s.at(i).unicode() >= 0x80 ) { onlyAscii = FALSE; break; } } if ( onlyAscii ) s = "\"" + s + "\""; else s = "QString::fromUtf8( \"" + s + "\" )"; return s;}QString Uic::trcall( const QString& txt, const QDomNode& node ){ return trcall(txt,getComment(node));}QString Uic::trcall( const QString& txt, const QString& com ){ QString r = trmacro + "( " + fixString(txt); if ( !com.isEmpty() ) r += ", " + fixString(com); return r + " )";}static QString mkStdSet( const QString& prop ){ return QString( "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( QTextStream &outStream, QDomDocument doc, bool decl, bool subcl, const QString &trm, const QString& subClass ) : out( outStream ), trmacro( trm ){ item_used = cg_used = pal_used = 0; layouts << "hbox" << "vbox" << "grid"; tags = layouts; tags << "widget"; nameOfClass = getClassName( doc.firstChild().toElement() ); QDomElement firstWidget = doc.firstChild().firstChild().toElement(); while ( firstWidget.tagName() != "widget" ) firstWidget = firstWidget.nextSibling().toElement(); if ( nameOfClass.isEmpty() ) nameOfClass = getObjectName( firstWidget ); if ( subcl ) { if ( decl ) createSubDecl( firstWidget, subClass ); else createSubImpl( firstWidget, subClass ); } else { if ( decl ) createFormDecl( firstWidget ); else createFormImpl( firstWidget ); }}/*! Extracts a class name from \a e */QString Uic::getClassName( const QDomElement& e ){ QDomElement n; QString cn; for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { if ( n.tagName() == "class" ) { QString s = n.firstChild().toText().data(); int i; while ( ( i = s.find(' ' )) != -1 ) s[i] = '_'; cn = s; } else if ( n.tagName() == "pixmapfunction" ) { pixmapLoaderFunction = n.firstChild().toText().data(); } } return cn;}/*! Extracts an object name from \a e. It's stored in the 'name' property. */QString Uic::getObjectName( const QDomElement& e ){ QDomElement n; for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { if ( n.tagName() == "property" ) { QDomElement n2 = n.firstChild().toElement(); if ( n2.tagName() == "name" && n2.firstChild().toText().data() == "name" ) { return n2.nextSibling().toElement().firstChild().toText().data(); } } } return QString::null;}/*! Extracts an layout name from \a e. It's stored in the 'name' property of the preceeding sibling (the first child of a QLayoutWidget). */QString Uic::getLayoutName( const QDomElement& e ){ QDomElement p = e.parentNode().toElement(); QString tail = QString::null; if (getClassName(p) != "QLayoutWidget") tail = "Layout"; QDomElement n; for ( n = p.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { if ( n.tagName() == "property" ) { QDomElement n2 = n.firstChild().toElement(); if ( n2.tagName() == "name" && n2.firstChild().toText().data() == "name" ) { return n2.nextSibling().toElement().firstChild().toText().data() + tail; } } } return e.tagName();}QByteArray unzipXPM( QString data, ulong& length ){ char *ba = new char[ 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; } if ( length < data.length() * 5 ) length = data.length() * 5; QByteArray baunzip( length ); ::uncompress( (uchar*) baunzip.data(), &length, (uchar*) ba, data.length()/2 ); 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 ); indent = " "; // default indent for child properties QStringList typeDefs; QMap<QString, CustomInclude> customWidgetIncludes; // at first the images, we need to ensure the names are unique QStringList forwardDecl; QStringList forwardDecl2; 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; while ( !n3.isNull() ) { if ( n3.tagName() == "class" ) { forwardDecl << n3.firstChild().toText().data(); cl = n3.firstChild().toText().data(); } else if ( n3.tagName() == "header" ) { CustomInclude ci; ci.header = n3.firstChild().toText().data(); ci.location = n3.attribute( "location", "global" ); customWidgetIncludes.insert( cl, ci ); } 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 HPUX compilers QStringList globalIncludes, localIncludes; int wid = WidgetDatabase::idFromClassName( objClass ); if ( wid != -1 ) { globalIncludes += WidgetDatabase::includeFile( wid ); } else { QMap<QString, CustomInclude>::Iterator it = customWidgetIncludes.find( objClass ); if ( it != customWidgetIncludes.end() ) { if ( ( *it ).location == "global" ) globalIncludes += (*it).header; else localIncludes += (*it).header; } } 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; } // forward declarations for child widgets and layouts out << "class QVBoxLayout; " << endl; out << "class QHBoxLayout; " << endl; out << "class QGridLayout; " << endl; for ( it = tags.begin(); it != tags.end(); ++it ) { nl = e.elementsByTagName( *it ); for ( i = 0; i < (int) nl.length(); i++ ) { QString s = getClassName( nl.item(i).toElement() ); if ( s == "QLayoutWidget" ) continue; // hide qlayoutwidgets if ( s == "Line" ) s = "QFrame"; forwardDecl += s; if ( s.mid( 1 ) == "ListBox" || s.mid( 1 ) == "ListView" || s.mid( 1 ) == "IconView" ) forwardDecl += "Q" + s.mid( 1 ) + "Item"; } } // 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(); 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[ (int)fd.length() - 1 ] != ';' ) fd += ";"; out << fd << endl; } out << endl; out << "class " << nameOfClass << " : public " << objClass << endl; out << "{ " << endl;/* tmake ignore Q_OBJECT */ out << " Q_OBJECT" << endl; out << endl; out << "public:" << endl; // constructor 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" ) { // standard QWidget out << " " << nameOfClass << "( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );" << endl; } else { out << " " << nameOfClass << "( QWidget* parent = 0, const char* name = 0 );" << endl; } // destructor out << " ~" << nameOfClass << "();" << endl; out << endl; // children nl = e.elementsByTagName( "widget" ); bool needEventHandler = FALSE; for ( i = 0; i < (int) nl.length(); i++ ) { n = nl.item(i).toElement(); createObjectDecl( n ); needEventHandler = needEventHandler || DomTool::hasProperty( n, "font" ); } out << endl; // find additional slots QStringList publicSlots, protectedSlots; for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -