qwidgetfactory.cpp

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

CPP
1,717
字号
/************************************************************************ Copyright (C) 2000-2002 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 "qwidgetfactory.h"#include "../interfaces/eventinterface.h"#include "../interfaces/interpreterinterface.h"#include "../interfaces/languageinterface.h"#include "../interfaces/widgetinterface.h"#include <qfeatures.h>#include "../designer/config.h"#include "../designer/database2.h"#include <qdom.h>#include <qdir.h>#include <qlayout.h>#include <qmetaobject.h>#include <domtool.h>#include <qapplication.h>#include <qtooltip.h>#include <qwhatsthis.h>#include <qobjectlist.h>#include <private/qpluginmanager_p.h>#include <qmime.h>#include <qdragobject.h>#include <zlib.h>#ifndef QT_NO_SQL#include <qsqlrecord.h>#include <qsqldatabase.h>#include <qdatatable.h>#endif// include all Qt widgets we support#include <qpushbutton.h>#include <qtoolbutton.h>#include <qcheckbox.h>#include <qradiobutton.h>#include <qgroupbox.h>#include <qbuttongroup.h>#include <qiconview.h>#include <qheader.h>#ifndef QT_NO_TABLE#include <qtable.h>#endif#include <qlistbox.h>#include <qlistview.h>#include <qlineedit.h>#include <qspinbox.h>#include <qmultilineedit.h>#include <qlabel.h>#include <qwidget.h>#include <qtabwidget.h>#include <qcombobox.h>#include <qdialog.h>#include <qwizard.h>#include <qlcdnumber.h>#include <qprogressbar.h>#include <qtextview.h>#include <qtextbrowser.h>#include <qdial.h>#include <qslider.h>#include <qframe.h>#include <qwidgetstack.h>#include <qtextedit.h>#include <qscrollbar.h>#include <qmainwindow.h>#include <qsplitter.h>#include <qaction.h>#include <qpopupmenu.h>#include <qmenubar.h>#include <qpopupmenu.h>#include <qwidgetstack.h>#include <qdatetimeedit.h>#include <stdlib.h>static QPtrList<QWidgetFactory> widgetFactories;static QPluginManager<EventInterface> *eventInterfaceManager = 0;static QPluginManager<InterpreterInterface> *interpreterInterfaceManager = 0;static QPluginManager<LanguageInterface> *languageInterfaceManager = 0;static QPluginManager<WidgetInterface> *widgetInterfaceManager = 0;QMap<QWidget*, QString> *qwf_functions = 0;QMap<QWidget*, QString> *qwf_forms = 0;QString *qwf_language = 0;bool qwf_execute_code = TRUE;bool qwf_stays_on_top = FALSE;QString qwf_currFileName = "";/*!  \class QWidgetFactory  \brief The QWidgetFactory class provides for the dynamic creation of widgets  from Qt Designer .ui files.  This class basically offers two things:  \list  \i Dynamically creating widgets from \link designer-manual.book Qt  Designer\endlink\e{Qt Designer} user interface description files.  You can do this using the static function QWidgetFactory::create().  This function also performs signal and slot connections, tab  ordering, etc., as defined in the .ui file, and returns the  top-level widget in the .ui file. After creating the widget you can  use QObject::child() and QObject::queryList() to access child  widgets of this returned widget.  \i Adding additional widget factories to be able to create custom  widgets. See createWidget() for details.  \endlist  This class is not included in the Qt library itself. To use it you  must link against \c libqui.so (Unix) or \c qui.lib (Windows), which is  built into \c $(QTDIR)/lib if you built \e{Qt Designer}.  See the "Creating Dynamic Dialogs from .ui Files" section of the \link  designer-manual.book Qt Designer manual\endlink for an example. See  also the \l{QWidgetPlugin} class and the \link plugins-howto.html  Plugins documentation\endlink.*//*! Constructs a QWidgetFactory. */QWidgetFactory::QWidgetFactory()    : dbControls( 0 ), usePixmapCollection( FALSE ){    widgetFactories.setAutoDelete( TRUE );    defSpacing = 6;    defMargin = 11;}/*! \fn QWidgetFactory::~QWidgetFactory()    Destructor.*/QWidgetFactory::~QWidgetFactory(){#if 0 // #### Volker, please test your changes!!!    delete widgetInterfaceManager;    widgetInterfaceManager = 0;    delete languageInterfaceManager;    languageInterfaceManager = 0;    delete interpreterInterfaceManager;    interpreterInterfaceManager = 0;    delete eventInterfaceManager;    eventInterfaceManager = 0;#endif}/*!    Loads the \e{Qt Designer} user interface description file \a uiFile  and returns the top-level widget in that description. \a parent and  \a name are passed to the constructor of the top-level widget.  This function also performs signal and slot connections, tab  ordering, etc., as described in the .ui file. In \e{Qt Designer} it  is possible to add custom slots to a form and connect to them. If  you want these connections to be made, you must create a class  derived from QObject, which implements all these slots. Then pass an  instance of the object as \a connector to this function. If you do  this, the connections to the custom slots will be done using the \a  connector as slot.  If something fails, 0 is returned.  The ownership of the returned widget is passed to the caller.*/QWidget *QWidgetFactory::create( const QString &uiFile, QObject *connector, QWidget *parent, const char *name ){    QFile f( uiFile );    if ( !f.open( IO_ReadOnly ) )	return 0;    qwf_currFileName = uiFile;    QWidget *w = QWidgetFactory::create( &f, connector, parent, name );    if ( !qwf_forms )	qwf_forms = new QMap<QWidget*, QString>;    qwf_forms->insert( w, uiFile );    return w;}#undef slots/*!  \overload    Loads the user interface description from device \a dev. */QWidget *QWidgetFactory::create( QIODevice *dev, QObject *connector, QWidget *parent, const char *name ){    QDomDocument doc;    QString errMsg;    int errLine;    if ( !doc.setContent( dev, &errMsg, &errLine ) ) {	qDebug( QString("Parse error: ") + errMsg + QString(" in line %d"), errLine );	return 0;    }    DomTool::fixDocument( doc );    QWidgetFactory *widgetFactory = new QWidgetFactory;    widgetFactory->toplevel = 0;    QDomElement e = doc.firstChild().toElement().firstChild().toElement();    QDomElement variables = e;    while ( variables.tagName() != "variables" && !variables.isNull() )	variables = variables.nextSibling().toElement();    QDomElement slots = e;    while ( slots.tagName() != "slots" && !slots.isNull() )	slots = slots.nextSibling().toElement();    QDomElement connections = e;    while ( connections.tagName() != "connections" && !connections.isNull() )	connections = connections.nextSibling().toElement();    QDomElement imageCollection = e;    while ( imageCollection.tagName() != "images" && !imageCollection.isNull() )	imageCollection = imageCollection.nextSibling().toElement();    QDomElement tabOrder = e;    while ( tabOrder.tagName() != "tabstops" && !tabOrder.isNull() )	tabOrder = tabOrder.nextSibling().toElement();    QDomElement actions = e;    while ( actions.tagName() != "actions" && !actions.isNull() )	actions = actions.nextSibling().toElement();    QDomElement toolbars = e;    while ( toolbars.tagName() != "toolbars" && !toolbars.isNull() )	toolbars = toolbars.nextSibling().toElement();    QDomElement menubar = e;    while ( menubar.tagName() != "menubar" && !menubar.isNull() )	menubar = menubar.nextSibling().toElement();    QDomElement functions = e;    while ( functions.tagName() != "functions" && !functions.isNull() )	functions = functions.nextSibling().toElement();    QDomElement widget;    while ( !e.isNull() ) {	if ( e.tagName() == "widget" ) {	    widget = e;	} else if ( e.tagName() == "variable" ) { // compatibility with old betas	    widgetFactory->variables << e.firstChild().toText().data();	} else if ( e.tagName() == "pixmapinproject" ) {	    widgetFactory->usePixmapCollection = TRUE;	} else if ( e.tagName() == "layoutdefaults" ) {	    widgetFactory->defSpacing = e.attribute( "spacing", QString::number( widgetFactory->defSpacing ) ).toInt();	    widgetFactory->defMargin = e.attribute( "margin", QString::number( widgetFactory->defMargin ) ).toInt();	}	e = e.nextSibling().toElement();    }    if ( !imageCollection.isNull() )	widgetFactory->loadImageCollection( imageCollection );    widgetFactory->createWidgetInternal( widget, parent, 0, widget.attribute("class", "QWidget") );    QWidget *w = widgetFactory->toplevel;    if ( !w ) {	delete widgetFactory;	return 0;    }    if ( !variables.isNull() ) {	for ( QDomElement n = variables.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() )	    if ( n.tagName() == "variable" )		widgetFactory->variables << n.firstChild().toText().data();    }    if ( !slots.isNull() ) {	for ( QDomElement n = slots.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() )	    if ( n.tagName() == "slot" ) {		QString s = n.firstChild().toText().data();		widgetFactory->languageSlots.insert( s.left( s.find( "(" ) ) , n.attribute( "language", "C++" ) );	    }    }    if ( !actions.isNull() )	widgetFactory->loadActions( actions );    if ( !toolbars.isNull() )	widgetFactory->loadToolBars( toolbars );    if ( !menubar.isNull() )	widgetFactory->loadMenuBar( menubar );    if ( !connections.isNull() )	widgetFactory->loadConnections( connections, connector );    if ( w && name && qstrlen( name ) > 0 )	w->setName( name );    if ( !tabOrder.isNull() )	widgetFactory->loadTabOrder( tabOrder );    if ( !functions.isNull() ) // compatibiliy with early 3.0 betas	widgetFactory->loadFunctions( functions );    if ( !languageInterfaceManager )	languageInterfaceManager = new QPluginManager<LanguageInterface>( IID_Language, QApplication::libraryPaths(), "/designer" );    if ( !interpreterInterfaceManager )	interpreterInterfaceManager =	    new QPluginManager<InterpreterInterface>( IID_Interpreter, QApplication::libraryPaths(), "/designer" );    widgetFactory->loadExtraSource();    if ( widgetFactory->toplevel ) {#ifndef QT_NO_SQL	QMap<QWidget*, SqlWidgetConnection>::Iterator cit = widgetFactory->sqlWidgetConnections.begin();	for( ; cit != widgetFactory->sqlWidgetConnections.end(); ++cit ) {	    if ( widgetFactory->noDatabaseWidgets.find( cit.key()->name() ) != widgetFactory->noDatabaseWidgets.end() )		continue;	    if ( cit.key()->inherits( "QDesignerDataBrowser2" ) )		( (QDesignerDataBrowser2*)cit.key() )->initPreview( (*cit).conn, (*cit).table, cit.key(), *(*cit).dbControls );	    else if ( cit.key()->inherits( "QDesignerDataView2" ) )		( (QDesignerDataView2*)cit.key() )->initPreview( (*cit).conn, (*cit).table, cit.key(), *(*cit).dbControls );	}	for ( QMap<QString, QStringList>::Iterator it = widgetFactory->dbTables.begin(); it != widgetFactory->dbTables.end(); ++it ) {	    QDataTable *table = (QDataTable*)widgetFactory->toplevel->child( it.key(), "QDataTable" );	    if ( !table )		continue;	    if ( widgetFactory->noDatabaseWidgets.find( table->name() ) != widgetFactory->noDatabaseWidgets.end() )		continue;	    QValueList<Field> fieldMap = *widgetFactory->fieldMaps.find( table );	    QString conn = (*it)[ 0 ];	    QSqlCursor* c = 0;	    QSqlDatabase *db = 0;	    if ( conn.isEmpty() || conn == "(default)" ) {		db = QSqlDatabase::database();		c = new QSqlCursor( (*it)[ 1 ] );	    } else {		db = QSqlDatabase::database( conn );		c = new QSqlCursor( (*it)[ 1 ], TRUE, db );	    }	    if ( db ) {		table->setSqlCursor( c, fieldMap.isEmpty(), TRUE );		table->refresh( QDataTable::RefreshAll );	    }	}#endif	if ( !eventInterfaceManager )	    eventInterfaceManager = new QPluginManager<EventInterface>( IID_Event, QApplication::libraryPaths(), "/designer" );	if ( eventInterfaceManager && interpreterInterfaceManager && languageInterfaceManager ) {	    QStringList langs = languageInterfaceManager->featureList();	    for ( QStringList::Iterator lit = langs.begin(); lit != langs.end(); ++lit ) {		EventInterface *eventInterface = 0;		eventInterfaceManager->queryInterface( *lit, &eventInterface );		InterpreterInterface *interpreterInterface = 0;		interpreterInterfaceManager->queryInterface( *lit, &interpreterInterface );		if ( eventInterface && interpreterInterface ) {		    interpreterInterface->init();		    QMap<QString, Functions*>::Iterator fit = widgetFactory->languageFunctions.find( *lit );		    if ( fit != widgetFactory->languageFunctions.end() ) {			QString funcs = (*fit)->functions;			funcs += "\n";			for ( QStringList::Iterator vit = widgetFactory->variables.begin(); vit != widgetFactory->variables.end(); ++vit )			    funcs += interpreterInterface->createVariableDeclaration( *vit ) + "\n";			if ( qwf_execute_code )			    interpreterInterface->exec( widgetFactory->toplevel, funcs );		    }		    if ( widgetFactory->languageFunctions.isEmpty() && qwf_execute_code )			interpreterInterface->exec( widgetFactory->toplevel, "dummy=0;" );		    for ( QMap<QObject *, EventFunction>::Iterator it = widgetFactory->eventMap.begin();			  it != widgetFactory->eventMap.end(); ++it ) {			QStringList::Iterator eit;			QValueList<QStringList>::Iterator fit;			for ( eit = (*it).events.begin(), fit = (*it).functions.begin(); eit != (*it).events.end(); ++eit, ++fit ) {			    QStringList funcs = *fit;			    for ( QStringList::Iterator fit2 = funcs.begin(); fit2 != funcs.end(); ++fit2 ) {				if ( widgetFactory->languageSlots.find( *fit2 ) !=				     widgetFactory->languageSlots.end() && qwf_execute_code ) {				    eventInterface->addEventHandler( it.key(),								     widgetFactory->toplevel, *eit, *fit2 );				}			    }			}		    }		    eventInterface->release();		    interpreterInterface->release();		}	    }	}    }    for ( QMap<QString, QString>::Iterator it = widgetFactory->buddies.begin(); it != widgetFactory->buddies.end(); ++it ) {	QLabel *label = (QLabel*)widgetFactory->toplevel->child( it.key(), "QLabel" );	QWidget *buddy = (QWidget*)widgetFactory->toplevel->child( *it, "QWidget" );	if ( label && buddy )	    label->setBuddy( buddy );    }    delete widgetFactory;    QApplication::sendPostedEvents();    return w;}/*! Installs a widget factory \a factory, which normally contains  additional widgets that can then be created using a QWidgetFactory.  See createWidget() for further details.*/void QWidgetFactory::addWidgetFactory( QWidgetFactory *factory ){

⌨️ 快捷键说明

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