diff options
-rw-r--r-- | src/designer/src/components/formeditor/formwindow.cpp | 11 | ||||
-rw-r--r-- | src/designer/src/components/formeditor/qdesigner_resource.cpp | 22 | ||||
-rw-r--r-- | src/designer/src/components/formeditor/qdesigner_resource.h | 3 | ||||
-rw-r--r-- | src/designer/src/lib/uilib/abstractformbuilder.cpp | 88 | ||||
-rw-r--r-- | src/designer/src/lib/uilib/formbuilderextra.cpp | 96 | ||||
-rw-r--r-- | src/designer/src/lib/uilib/formbuilderextra_p.h | 4 | ||||
-rw-r--r-- | src/designer/src/uitools/doc/src/qtuitools-module.qdoc | 2 | ||||
-rw-r--r-- | src/designer/src/uitools/quiloader.cpp | 2 | ||||
-rw-r--r-- | src/qdoc/node.cpp | 14 | ||||
-rw-r--r-- | src/qtattributionsscanner/scanner.cpp | 3 | ||||
-rw-r--r-- | tests/auto/qtattributionsscanner/testdata/warnings/incomplete/expected.error | 1 |
11 files changed, 143 insertions, 103 deletions
diff --git a/src/designer/src/components/formeditor/formwindow.cpp b/src/designer/src/components/formeditor/formwindow.cpp index 62365943b..d791666c6 100644 --- a/src/designer/src/components/formeditor/formwindow.cpp +++ b/src/designer/src/components/formeditor/formwindow.cpp @@ -2140,6 +2140,14 @@ bool FormWindow::handleContextMenu(QWidget *, QWidget *managedWidget, QContextMe bool FormWindow::setContents(QIODevice *dev, QString *errorMessageIn /* = 0 */) { + QDesignerResource r(this); + QScopedPointer<DomUI> ui(r.readUi(dev)); + if (ui.isNull()) { + if (errorMessageIn) + *errorMessageIn = r.errorString(); + return false; + } + UpdateBlocker ub(this); clearSelection(); m_selection->clearSelectionPool(); @@ -2151,8 +2159,7 @@ bool FormWindow::setContents(QIODevice *dev, QString *errorMessageIn /* = 0 */) m_undoStack.clear(); emit changed(); - QDesignerResource r(this); - QWidget *w = r.load(dev, formContainer()); + QWidget *w = r.loadUi(ui.data(), formContainer()); if (w) { setMainContainer(w); emit changed(); diff --git a/src/designer/src/components/formeditor/qdesigner_resource.cpp b/src/designer/src/components/formeditor/qdesigner_resource.cpp index 9309918a0..4dd6439e4 100644 --- a/src/designer/src/components/formeditor/qdesigner_resource.cpp +++ b/src/designer/src/components/formeditor/qdesigner_resource.cpp @@ -461,6 +461,11 @@ QDesignerResource::~QDesignerResource() { } +DomUI *QDesignerResource::readUi(QIODevice *dev) +{ + return d->readUi(dev); +} + static inline QString messageBoxTitle() { return QApplication::translate("Designer", "Qt Designer"); @@ -596,10 +601,19 @@ void QDesignerResource::saveDom(DomUI *ui, QWidget *widget) QWidget *QDesignerResource::load(QIODevice *dev, QWidget *parentWidget) { - QWidget *w = QEditorFormBuilder::load(dev, parentWidget); - if (w) // Store the class name as 'reset' value for the main container's object name. - w->setProperty("_q_classname", w->objectName()); - return w; + QScopedPointer<DomUI> ui(readUi(dev)); + return ui.isNull() ? nullptr : loadUi(ui.data(), parentWidget); +} + +QWidget *QDesignerResource::loadUi(DomUI *ui, QWidget *parentWidget) +{ + QWidget *widget = create(ui, parentWidget); + // Store the class name as 'reset' value for the main container's object name. + if (widget) + widget->setProperty("_q_classname", widget->objectName()); + else if (d->m_errorString.isEmpty()) + d->m_errorString = QFormBuilderExtra::msgInvalidUiFile(); + return widget; } bool QDesignerResource::saveRelative() const diff --git a/src/designer/src/components/formeditor/qdesigner_resource.h b/src/designer/src/components/formeditor/qdesigner_resource.h index fb4b0200b..6368f9424 100644 --- a/src/designer/src/components/formeditor/qdesigner_resource.h +++ b/src/designer/src/components/formeditor/qdesigner_resource.h @@ -78,6 +78,9 @@ public: QWidget *load(QIODevice *dev, QWidget *parentWidget) override; + DomUI *readUi(QIODevice *dev); + QWidget *loadUi(DomUI *ui, QWidget *parentWidget); + protected: using QEditorFormBuilder::create; using QEditorFormBuilder::createDom; diff --git a/src/designer/src/lib/uilib/abstractformbuilder.cpp b/src/designer/src/lib/uilib/abstractformbuilder.cpp index 241fedeb7..a64c1d951 100644 --- a/src/designer/src/lib/uilib/abstractformbuilder.cpp +++ b/src/designer/src/lib/uilib/abstractformbuilder.cpp @@ -93,9 +93,8 @@ # include <private/qlayout_p.h> // Compiling within Designer #endif -#include <QtCore/qxmlstream.h> - #include <QtCore/qdebug.h> +#include <QtCore/qxmlstream.h> #include <limits.h> @@ -178,70 +177,6 @@ QAbstractFormBuilder::~QAbstractFormBuilder() { } -// Return UI file version from attribute 'version="4.0"' -static QPair<int, int> uiVersion(const QString &attr) -{ - const QVector<QStringRef> versions = attr.splitRef(QLatin1Char('.'), QString::SkipEmptyParts); - if (versions.size() >= 2) { - bool okMajor, okMinor; - const int majorVersion = versions.at(0).toInt(&okMajor); - const int minorVersion = versions.at(1).toInt(&okMinor); - if (okMajor && okMinor) - return QPair<int, int>(majorVersion, minorVersion); - } - return QPair<int, int>(-1, -1); -} - -static inline QString msgXmlError(const QXmlStreamReader &reader) -{ - return QCoreApplication::translate("QAbstractFormBuilder", "An error has occurred while reading the UI file at line %1, column %2: %3") - .arg(reader.lineNumber()).arg(reader.columnNumber()).arg(reader.errorString()); -} - -// Read and check the version and the (optional) language attribute -// of an <ui> element and leave reader positioned at <ui>. -static bool inline readUiAttributes(QXmlStreamReader &reader, const QString &language, QString *errorMessage) -{ - const QString uiElement = QStringLiteral("ui"); - // Read up to first element - while (!reader.atEnd()) { - switch (reader.readNext()) { - case QXmlStreamReader::Invalid: - *errorMessage = msgXmlError(reader); - return false; - case QXmlStreamReader::StartElement: - if (reader.name().compare(uiElement, Qt::CaseInsensitive) == 0) { - const QString versionAttribute = QStringLiteral("version"); - const QString languageAttribute = QStringLiteral("language"); - const QXmlStreamAttributes attributes = reader.attributes(); - if (attributes.hasAttribute(versionAttribute)) { - const QString versionString = attributes.value(versionAttribute).toString(); - if (uiVersion(versionString).first < 4) { - *errorMessage = QCoreApplication::translate("QAbstractFormBuilder", "This file was created using Designer from Qt-%1 and cannot be read.") - .arg(versionString); - return false; - } // version error - } // has version - if (attributes.hasAttribute(languageAttribute)) { - // Check on optional language (Jambi) - const QString formLanguage = attributes.value(languageAttribute).toString(); - if (!formLanguage.isEmpty() && formLanguage.compare(language, Qt::CaseInsensitive)) { - *errorMessage = QCoreApplication::translate("QAbstractFormBuilder", "This file cannot be read because it was created using %1.").arg(formLanguage); - return false; - } // language error - } // has language - return true; - } // <ui> matched - break; - default: - break; - } - } - // No <ui> found. - *errorMessage = QCoreApplication::translate("QAbstractFormBuilder", "Invalid UI file: The root element <ui> is missing."); - return false; -} - /*! \fn QWidget *QAbstractFormBuilder::load(QIODevice *device, QWidget *parent) @@ -252,23 +187,12 @@ static bool inline readUiAttributes(QXmlStreamReader &reader, const QString &lan */ QWidget *QAbstractFormBuilder::load(QIODevice *dev, QWidget *parentWidget) { - QXmlStreamReader reader(dev); - d->m_errorString.clear(); - if (!readUiAttributes(reader, d->m_language, &d->m_errorString)) { - uiLibWarning(d->m_errorString); - return 0; - } - DomUI ui; - ui.read(reader); - if (reader.hasError()) { - d->m_errorString = msgXmlError(reader); - uiLibWarning(d->m_errorString); - return 0; - } - - QWidget *widget = create(&ui, parentWidget); + QScopedPointer<DomUI> ui(d->readUi(dev)); + if (ui.isNull()) + return nullptr; + QWidget *widget = create(ui.data(), parentWidget); if (!widget && d->m_errorString.isEmpty()) - d->m_errorString = QCoreApplication::translate("QAbstractFormBuilder", "Invalid UI file"); + d->m_errorString = QFormBuilderExtra::msgInvalidUiFile(); return widget; } diff --git a/src/designer/src/lib/uilib/formbuilderextra.cpp b/src/designer/src/lib/uilib/formbuilderextra.cpp index b3527efb6..66609737b 100644 --- a/src/designer/src/lib/uilib/formbuilderextra.cpp +++ b/src/designer/src/lib/uilib/formbuilderextra.cpp @@ -114,6 +114,102 @@ void QFormBuilderExtra::clear() m_buttonGroups.clear(); } +// Return UI file version from attribute 'version="4.0"' +static QPair<int, int> uiVersion(const QString &attr) +{ + const QVector<QStringRef> versions = attr.splitRef(QLatin1Char('.'), QString::SkipEmptyParts); + if (versions.size() >= 2) { + bool okMajor, okMinor; + const int majorVersion = versions.at(0).toInt(&okMajor); + const int minorVersion = versions.at(1).toInt(&okMinor); + if (okMajor && okMinor) + return QPair<int, int>(majorVersion, minorVersion); + } + return QPair<int, int>(-1, -1); +} + +static inline QString msgXmlError(const QXmlStreamReader &reader) +{ + return QCoreApplication::translate("QAbstractFormBuilder", + "An error has occurred while reading the UI file at line %1, column %2: %3") + .arg(reader.lineNumber()).arg(reader.columnNumber()) + .arg(reader.errorString()); +} + +// Read and check the version and the (optional) language attribute +// of an <ui> element and leave reader positioned at <ui>. +static bool inline readUiAttributes(QXmlStreamReader &reader, const QString &language, + QString *errorMessage) +{ + const QString uiElement = QStringLiteral("ui"); + // Read up to first element + while (!reader.atEnd()) { + switch (reader.readNext()) { + case QXmlStreamReader::Invalid: + *errorMessage = msgXmlError(reader); + return false; + case QXmlStreamReader::StartElement: + if (reader.name().compare(uiElement, Qt::CaseInsensitive) == 0) { + const QString versionAttribute = QStringLiteral("version"); + const QString languageAttribute = QStringLiteral("language"); + const QXmlStreamAttributes attributes = reader.attributes(); + if (attributes.hasAttribute(versionAttribute)) { + const QString versionString = attributes.value(versionAttribute).toString(); + if (uiVersion(versionString).first < 4) { + *errorMessage = + QCoreApplication::translate("QAbstractFormBuilder", + "This file was created using Designer from Qt-%1 and cannot be read.") + .arg(versionString); + return false; + } // version error + } // has version + if (attributes.hasAttribute(languageAttribute)) { + // Check on optional language (Jambi) + const QString formLanguage = attributes.value(languageAttribute).toString(); + if (!formLanguage.isEmpty() && formLanguage.compare(language, Qt::CaseInsensitive)) { + *errorMessage = + QCoreApplication::translate("QAbstractFormBuilder", + "This file cannot be read because it was created using %1.") + .arg(formLanguage); + return false; + } // language error + } // has language + return true; + } // <ui> matched + break; + default: + break; + } + } + // No <ui> found. + *errorMessage = QCoreApplication::translate("QAbstractFormBuilder", + "Invalid UI file: The root element <ui> is missing."); + return false; +} + +DomUI *QFormBuilderExtra::readUi(QIODevice *dev) +{ + QXmlStreamReader reader(dev); + m_errorString.clear(); + if (!readUiAttributes(reader, m_language, &m_errorString)) { + uiLibWarning(m_errorString); + return nullptr; + } + DomUI *ui = new DomUI; + ui->read(reader); + if (reader.hasError()) { + m_errorString = msgXmlError(reader); + uiLibWarning(m_errorString); + delete ui; + return nullptr; + } + return ui; +} + +QString QFormBuilderExtra::msgInvalidUiFile() +{ + return QCoreApplication::translate("QAbstractFormBuilder", "Invalid UI file"); +} bool QFormBuilderExtra::applyPropertyInternally(QObject *o, const QString &propertyName, const QVariant &value) { diff --git a/src/designer/src/lib/uilib/formbuilderextra_p.h b/src/designer/src/lib/uilib/formbuilderextra_p.h index 20c9d39de..5c06dc3dc 100644 --- a/src/designer/src/lib/uilib/formbuilderextra_p.h +++ b/src/designer/src/lib/uilib/formbuilderextra_p.h @@ -92,6 +92,7 @@ namespace QFormInternal class DomButtonGroups; class DomButtonGroup; class DomCustomWidget; +class DomUI; class QAbstractFormBuilder; class QResourceBuilder; @@ -115,6 +116,9 @@ public: void clear(); + DomUI *readUi(QIODevice *dev); + static QString msgInvalidUiFile(); + bool applyPropertyInternally(QObject *o, const QString &propertyName, const QVariant &value); enum BuddyMode { BuddyApplyAll, BuddyApplyVisibleOnly }; diff --git a/src/designer/src/uitools/doc/src/qtuitools-module.qdoc b/src/designer/src/uitools/doc/src/qtuitools-module.qdoc index df44f5271..2820ac475 100644 --- a/src/designer/src/uitools/doc/src/qtuitools-module.qdoc +++ b/src/designer/src/uitools/doc/src/qtuitools-module.qdoc @@ -42,7 +42,9 @@ in a \c qmake project file to ensure that the application is compiled and linked appropriately. + \if !defined(qtforpython) \snippet quiloader/doc_src_qtuiloader.pro 0 + \endif A form loader object, provided by the QUiLoader class, is used to construct the user interface. This user interface can diff --git a/src/designer/src/uitools/quiloader.cpp b/src/designer/src/uitools/quiloader.cpp index 3b3c82bf7..68b2eb144 100644 --- a/src/designer/src/uitools/quiloader.cpp +++ b/src/designer/src/uitools/quiloader.cpp @@ -620,10 +620,12 @@ void QUiLoaderPrivate::setupWidgetMap() const \snippet quiloader/mywidget.cpp 0 + \if !defined(qtforpython) By including the user interface in the form's resources (\c myform.qrc), we ensure that it will be present at run-time: \quotefile quiloader/mywidget.qrc + \endif The availableWidgets() function returns a QStringList with the class names of the widgets available in the specified plugin paths. To create these diff --git a/src/qdoc/node.cpp b/src/qdoc/node.cpp index 926c8ebdb..5207be7e3 100644 --- a/src/qdoc/node.cpp +++ b/src/qdoc/node.cpp @@ -77,18 +77,10 @@ void Node::initialize() bool Node::nodeNameLessThan(const Node *n1, const Node *n2) { - if (n1->isDocumentNode() && n2->isDocumentNode()) { - const DocumentNode* f1 = static_cast<const DocumentNode*>(n1); - const DocumentNode* f2 = static_cast<const DocumentNode*>(n2); - if (f1->fullTitle() < f2->fullTitle()) - return true; - else if (f1->fullTitle() > f2->fullTitle()) - return false; - } + if (n1->isAggregate() && n2->isAggregate()) { + const Aggregate* f1 = static_cast<const Aggregate*>(n1); + const Aggregate* f2 = static_cast<const Aggregate*>(n2); - if (n1->isCollectionNode() && n2->isCollectionNode()) { - const CollectionNode* f1 = static_cast<const CollectionNode*>(n1); - const CollectionNode* f2 = static_cast<const CollectionNode*>(n2); if (f1->fullTitle() < f2->fullTitle()) return true; else if (f1->fullTitle() > f2->fullTitle()) diff --git a/src/qtattributionsscanner/scanner.cpp b/src/qtattributionsscanner/scanner.cpp index b07ca8f2f..fe59d9942 100644 --- a/src/qtattributionsscanner/scanner.cpp +++ b/src/qtattributionsscanner/scanner.cpp @@ -112,11 +112,8 @@ static Package readPackage(const QJsonObject &object, const QString &filePath, L missingPropertyWarning(filePath, QStringLiteral("Name")); if (p.id.isEmpty()) missingPropertyWarning(filePath, QStringLiteral("Id")); - if (p.license.isEmpty()) missingPropertyWarning(filePath, QStringLiteral("License")); - if (p.copyright.isEmpty()) - missingPropertyWarning(filePath, QStringLiteral("Copyright")); if (p.qtParts.isEmpty()) p.qtParts << QStringLiteral("libs"); diff --git a/tests/auto/qtattributionsscanner/testdata/warnings/incomplete/expected.error b/tests/auto/qtattributionsscanner/testdata/warnings/incomplete/expected.error index 265e653b4..0acbdc7a9 100644 --- a/tests/auto/qtattributionsscanner/testdata/warnings/incomplete/expected.error +++ b/tests/auto/qtattributionsscanner/testdata/warnings/incomplete/expected.error @@ -1,4 +1,3 @@ File %{PWD}/qt_attribution_test.json: Missing mandatory property 'Name'. File %{PWD}/qt_attribution_test.json: Missing mandatory property 'Id'. File %{PWD}/qt_attribution_test.json: Missing mandatory property 'License'. -File %{PWD}/qt_attribution_test.json: Missing mandatory property 'Copyright'. |