📄 abstractformbuilder.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2006 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://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** 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 "ui4_p.h"#include <QtCore/QVariant>#include <QtCore/QMetaProperty>#include <QtCore/QDateTime>#include <QtCore/QFileInfo>#include <QtCore/QDir>#include <QtCore/QQueue>#include <QtCore/QUrl>#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>#include <private/qfont_p.h>#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 QAbstractFormBuilderGadget: public QWidget{ Q_OBJECT Q_PROPERTY(Qt::Orientation orientation READ fakeOrientation) Q_PROPERTY(QSizePolicy::Policy sizeType READ fakeSizeType) Q_PROPERTY(QPalette::ColorRole colorRole READ fakeColorRole) Q_PROPERTY(QPalette::ColorGroup colorGroup READ fakeColorGroup) Q_PROPERTY(Qt::BrushStyle brushStyle READ fakeBrushStyle) Q_PROPERTY(QGradient::Type gradientType READ fakeGradientType) Q_PROPERTY(QGradient::Spread gradientSpread READ fakeGradientSpread) Q_PROPERTY(QGradient::CoordinateMode gradientCoordinate READ fakeGradientCoordinate)public: QAbstractFormBuilderGadget() { Q_ASSERT(0); } Qt::Orientation fakeOrientation() const { Q_ASSERT(0); return Qt::Horizontal; } QSizePolicy::Policy fakeSizeType() const { Q_ASSERT(0); return QSizePolicy::Expanding; } QPalette::ColorGroup fakeColorGroup() const { Q_ASSERT(0); return static_cast<QPalette::ColorGroup>(0); } QPalette::ColorRole fakeColorRole() const { Q_ASSERT(0); return static_cast<QPalette::ColorRole>(0); } Qt::BrushStyle fakeBrushStyle() const { Q_ASSERT(0); return Qt::NoBrush; } QGradient::Type fakeGradientType() const { Q_ASSERT(0); return QGradient::NoGradient; } QGradient::Spread fakeGradientSpread() const { Q_ASSERT(0); return QGradient::PadSpread; } QGradient::CoordinateMode fakeGradientCoordinate() const { Q_ASSERT(0); return QGradient::LogicalMode; }};/*! \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(){}/*! \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.firstChild().toElement(); DomUI ui; ui.read(root); /// ### check the result return create(&ui, parentWidget);}/*! \internal*/QWidget *QAbstractFormBuilder::create(DomUI *ui, QWidget *parentWidget){ if (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; createCustomWidgets(ui->elementCustomWidgets()); if (QWidget *widget = create(ui_widget, parentWidget)) { createConnections(ui->elementConnections(), widget); createResources(ui->elementResources()); applyTabStops(widget, ui->elementTabStops()); reset(); return widget; } 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 ); } foreach (DomWidget *ui_child, ui_widget->elementWidget()) { QWidget *child_w = create(ui_child, w); Q_UNUSED( child_w ); } 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()) { 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); 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;}/*! \internal*/bool QAbstractFormBuilder::addItem(DomWidget *ui_widget, QWidget *widget, QWidget *parentWidget){ QHash<QString, DomProperty*> attributes = propertyMap(ui_widget->elementAttribute()); QString title = QLatin1String("Page"); if (DomProperty *ptitle = attributes.value(QLatin1String("title"))) { title = toString(ptitle->elementString()); } QString label = QLatin1String(QLatin1String("Page")); if (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)) { if (DomProperty *attr = attributes.value(QLatin1String("toolBarArea"))) { Qt::ToolBarArea area = static_cast<Qt::ToolBarArea>(attr->elementNumber()); mw->addToolBar(area, toolBar); } else { mw->addToolBar(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 (DomProperty *attr = attributes.value(QLatin1String("dockWidgetArea"))) { Qt::DockWidgetArea area = static_cast<Qt::DockWidgetArea>(attr->elementNumber()); if (!dockWidget->isAreaAllowed(area)) { if (dockWidget->isAreaAllowed(Qt::LeftDockWidgetArea)) area = Qt::LeftDockWidgetArea; else if (dockWidget->isAreaAllowed(Qt::RightDockWidgetArea)) area = Qt::RightDockWidgetArea; else if (dockWidget->isAreaAllowed(Qt::TopDockWidgetArea)) area = Qt::TopDockWidgetArea; else if (dockWidget->isAreaAllowed(Qt::BottomDockWidgetArea)) area = Qt::BottomDockWidgetArea; } mw->addDockWidget(area, dockWidget); } else { mw->addDockWidget(Qt::LeftDockWidgetArea, dockWidget); } return true; } else if (! mw->centralWidget()) { mw->setCentralWidget(widget); return true; } } else if (QTabWidget *tabWidget = qobject_cast<QTabWidget*>(parentWidget)) { widget->setParent(0); int tabIndex = tabWidget->count(); tabWidget->addTab(widget, title); if (DomProperty *picon = attributes.value(QLatin1String("icon"))) { tabWidget->setTabIcon(tabIndex, qvariant_cast<QIcon>(toVariant(0, picon))); } if (DomProperty *ptoolTip = attributes.value(QLatin1String("toolTip"))) { tabWidget->setTabToolTip(tabIndex, toString(ptoolTip->elementString())); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -