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