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 + -
显示快捷键?