abstractformbuilder.cpp

来自「奇趣公司比较新的qt/emd版本」· C++ 代码 · 共 2,006 行 · 第 1/5 页

CPP
2,006
字号
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the Qt Designer of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "abstractformbuilder.h"#include "formbuilderextra_p.h"#include "ui4_p.h"#include "properties_p.h"#include <QtCore/QVariant>#include <QtCore/QMetaProperty>#include <QtCore/QFileInfo>#include <QtCore/QDir>#include <QtCore/QQueue>#include <QtCore/QHash>#include <QtCore/qdebug.h>#include <QtGui/QAction>#include <QtGui/QActionGroup>#include <QtGui/QComboBox>#include <QtGui/QFontComboBox>#include <QtGui/QGridLayout>#include <QtGui/QIcon>#include <QtGui/QListWidget>#include <QtGui/QMainWindow>#include <QtGui/QPixmap>#include <QtGui/QStatusBar>#include <QtGui/QTreeWidget>#include <QtGui/QTableWidget>#include <QtGui/QWidget>#include <QtGui/QSplitter>#include <QtXml/QDomDocument>#include <QtGui/QDialog>// containers#include <QtGui/QToolBox>#include <QtGui/QStackedWidget>#include <QtGui/QTabWidget>#include <QtGui/QToolBar>#include <QtGui/QMenuBar>#include <QtGui/QDockWidget>#include <QtCore/qdebug.h>#include <limits.h>Q_DECLARE_METATYPE(QWidgetList)#ifdef QFORMINTERNAL_NAMESPACEusing namespace QFormInternal;#endifclass QFriendlyLayout: public QLayout{public:    inline QFriendlyLayout() { Q_ASSERT(0); }#ifdef QFORMINTERNAL_NAMESPACE    friend class QFormInternal::QAbstractFormBuilder;#else    friend class QAbstractFormBuilder;#endif};/*!    \class QAbstractFormBuilder    \brief The QAbstractFormBuilder class provides a default    implementation for classes that create user interfaces at    run-time.    \inmodule QtDesigner    QAbstractFormBuilder provides a standard interface and a default    implementation for constructing forms from user interface    files. It is not intended to be instantiated directly. Use the    QFormBuilder class to create user interfaces from \c{.ui} files at    run-time. For example:    \code        MyForm::MyForm(QWidget *parent)            : QWidget(parent)        {            QFormBuilder builder;            QFile file(":/forms/myWidget.ui");            file.open(QFile::ReadOnly);            QWidget *myWidget = builder.load(&file, this);            file.close();            QVBoxLayout *layout = new QVBoxLayout;            layout->addWidget(myWidget);            setLayout(layout);        }    \endcode    To override certain aspects of the form builder's behavior,    subclass QAbstractFormBuilder and reimplement the relevant virtual    functions:    \list    \o load() handles reading of \c{.ui} format files from arbitrary       QIODevices, and construction of widgets from the XML data       that they contain.    \o save() handles saving of widget details in \c{.ui} format to       arbitrary QIODevices.    \o workingDirectory() and setWorkingDirectory() control the       directory in which forms are held. The form builder looks for       other resources on paths relative to this directory.    \endlist    The QFormBuilder class is typically used by custom components and    applications that embed \QD. Standalone applications that need to    dynamically generate user interfaces at run-time use the    QUiLoader, found in the QtUiTools module.    \sa {QtUiTools Module}*//*!    Constructs a new form builder.*/QAbstractFormBuilder::QAbstractFormBuilder() :    m_defaultMargin(INT_MIN),    m_defaultSpacing(INT_MIN){}/*!    Destroys the form builder.*/QAbstractFormBuilder::~QAbstractFormBuilder(){    QFormBuilderExtra::removeInstance(this);}/*!    \fn QWidget *QAbstractFormBuilder::load(QIODevice *device, QWidget *parent)    Loads an XML representation of a widget from the given \a device,    and constructs a new widget with the specified \a parent.    \sa save()*/QWidget *QAbstractFormBuilder::load(QIODevice *dev, QWidget *parentWidget){    QDomDocument doc;    if (!doc.setContent(dev))        return 0;    QDomElement root = doc.firstChildElement();    DomUI ui;    ui.read(root); /// ### check the result    return create(&ui, parentWidget);}/*!    \internal*/QWidget *QAbstractFormBuilder::create(DomUI *ui, QWidget *parentWidget){    QFormBuilderExtra *formBuilderPrivate = QFormBuilderExtra::instance(this);    formBuilderPrivate->clear();    if (const DomLayoutDefault *def = ui->elementLayoutDefault()) {        m_defaultMargin = def->hasAttributeMargin() ? def->attributeMargin() : INT_MIN;        m_defaultSpacing = def->hasAttributeSpacing() ? def->attributeSpacing() : INT_MIN;    }    DomWidget *ui_widget = ui->elementWidget();    if (!ui_widget)        return 0;    DomCustomWidgets *domCustomWidgets  = ui->elementCustomWidgets();    createCustomWidgets(domCustomWidgets);#ifndef QT_FORMBUILDER_NO_SCRIPT        if (domCustomWidgets) {        foreach(const DomCustomWidget* cw, domCustomWidgets->elementCustomWidget()) {            if (const DomScript *domScript = cw->elementScript()) {                const QString script = domScript->text();                if (!script.isEmpty())                    formBuilderPrivate->storeCustomWidgetScript(cw->elementClass(), script);                        }        }    }#endif    if (QWidget *widget = create(ui_widget, parentWidget)) {        createConnections(ui->elementConnections(), widget);        createResources(ui->elementResources());        applyTabStops(widget, ui->elementTabStops());        formBuilderPrivate->applyInternalProperties();        reset();        formBuilderPrivate->clear();        return widget;    }    formBuilderPrivate->clear();    return 0;}/*!    \internal*/QWidget *QAbstractFormBuilder::create(DomWidget *ui_widget, QWidget *parentWidget){    QWidget *w = createWidget(ui_widget->attributeClass(), parentWidget, ui_widget->attributeName());    if (!w)        return 0;    applyProperties(w, ui_widget->elementProperty());    foreach (DomAction *ui_action, ui_widget->elementAction()) {        QAction *child_action = create(ui_action, w);        Q_UNUSED( child_action );    }    foreach (DomActionGroup *ui_action_group, ui_widget->elementActionGroup()) {        QActionGroup *child_action_group = create(ui_action_group, w);        Q_UNUSED( child_action_group );    }    QWidgetList children;    foreach (DomWidget *ui_child, ui_widget->elementWidget()) {        if (QWidget *child  = create(ui_child, w)) {            children += child;        } else {            const QString className = ui_child->elementClass().empty() ? QString() : ui_child->elementClass().front();            uiLibWarning(QObject::tr("The creation of a widget of the class '%1' failed.").arg(className));        }    }    foreach (DomLayout *ui_lay, ui_widget->elementLayout()) {        QLayout *child_lay = create(ui_lay, 0, w);        Q_UNUSED( child_lay );    }    foreach (DomActionRef *ui_action_ref, ui_widget->elementAddAction()) {        const QString name = ui_action_ref->attributeName();        if (name == QLatin1String("separator")) {            QAction *sep = new QAction(w);            sep->setSeparator(true);            w->addAction(sep);            addMenuAction(sep);        } else if (QAction *a = m_actions.value(name)) {            w->addAction(a);        } else if (QActionGroup *g = m_actionGroups.value(name)) {            w->addActions(g->actions());        } else if (QMenu *menu = qFindChild<QMenu*>(w, name)) {            w->addAction(menu->menuAction());            addMenuAction(menu->menuAction());        }    }    loadExtraInfo(ui_widget, w, parentWidget);#ifndef QT_FORMBUILDER_NO_SCRIPT    QString scriptErrorMessage;    QFormBuilderExtra *extra = QFormBuilderExtra::instance(this);    extra->formScriptRunner().run(ui_widget,                                  extra->customWidgetScript(ui_widget->attributeClass()),                                  w, children, &scriptErrorMessage);#endif    addItem(ui_widget, w, parentWidget);    if (qobject_cast<QDialog *>(w) && parentWidget)        w->setAttribute(Qt::WA_Moved, false); // So that QDialog::setVisible(true) will center it    return w;}/*!    \internal*/QAction *QAbstractFormBuilder::create(DomAction *ui_action, QObject *parent){    QAction *a = createAction(parent, ui_action->attributeName());    if (!a)        return 0;    applyProperties(a, ui_action->elementProperty());    return a;}/*!    \internal*/QActionGroup *QAbstractFormBuilder::create(DomActionGroup *ui_action_group, QObject *parent){    QActionGroup *a = createActionGroup(parent, ui_action_group->attributeName());    if (!a)        return 0;    applyProperties(a, ui_action_group->elementProperty());    foreach (DomAction *ui_action, ui_action_group->elementAction()) {        QAction *child_action = create(ui_action, a);        Q_UNUSED( child_action );    }    foreach (DomActionGroup *g, ui_action_group->elementActionGroup()) {        QActionGroup *child_action_group = create(g, parent);        Q_UNUSED( child_action_group );    }    return a;}// figure out the toolbar area of a DOM attrib list.// By legacy, it is stored as an integer. As of 4.3.0, it is the enumeration value.Qt::ToolBarArea QAbstractFormBuilder::toolbarAreaFromDOMAttributes(const DomPropertyHash &attributes) {    const DomProperty *attr = attributes.value(QLatin1String("toolBarArea"));    if (!attr)        return Qt::TopToolBarArea;    switch(attr->kind()) {    case DomProperty::Number:        return static_cast<Qt::ToolBarArea>(attr->elementNumber());    case DomProperty::Enum:        return enumKeyOfObjectToValue<QAbstractFormBuilderGadget, Qt::ToolBarArea>("toolBarArea",  attr->elementEnum().toLatin1());    default:        break;    }    return Qt::TopToolBarArea;}/*!    \internal*/bool QAbstractFormBuilder::addItem(DomWidget *ui_widget, QWidget *widget, QWidget *parentWidget){    const DomPropertyHash attributes = propertyMap(ui_widget->elementAttribute());    QString title = QLatin1String("Page");    if (const DomProperty *ptitle = attributes.value(QLatin1String("title"))) {        title = toString(ptitle->elementString());    }    QString label = QLatin1String("Page");    if (const DomProperty *plabel = attributes.value(QLatin1String("label"))) {        label = toString(plabel->elementString());    }    if (QMainWindow *mw = qobject_cast<QMainWindow*>(parentWidget)) {        // the menubar        if (QMenuBar *menuBar = qobject_cast<QMenuBar*>(widget)) {            mw->setMenuBar(menuBar);            return true;        }        // apply the toolbar's attributes        else if (QToolBar *toolBar = qobject_cast<QToolBar*>(widget)) {            mw->addToolBar(toolbarAreaFromDOMAttributes(attributes), toolBar);            // check break            if (const DomProperty *attr = attributes.value(QLatin1String("toolBarBreak")))                if (attr->elementBool() == QLatin1String("true"))                    mw->insertToolBarBreak (toolBar);            return true;        }        // statusBar        else if (QStatusBar *statusBar = qobject_cast<QStatusBar*>(widget)) {            mw->setStatusBar(statusBar);            return true;        }        // apply the dockwidget's attributes        else if (QDockWidget *dockWidget = qobject_cast<QDockWidget*>(widget)) {            if (const DomProperty *attr = attributes.value(QLatin1String("dockWidgetArea"))) {                Qt::DockWidgetArea area = static_cast<Qt::DockWidgetArea>(attr->elementNumber());                if (!dockWidget->isAreaAllowed(area)) {

⌨️ 快捷键说明

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