diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/uilib/abstractformbuilder.cpp | 112 | ||||
-rw-r--r-- | tools/uilib/abstractformbuilder.h | 2 | ||||
-rw-r--r-- | tools/uilib/container.h | 7 | ||||
-rw-r--r-- | tools/uilib/container.qdoc | 27 | ||||
-rw-r--r-- | tools/uilib/formbuilderextra.cpp | 1 | ||||
-rw-r--r-- | tools/uilib/formbuilderextra_p.h | 2 |
6 files changed, 128 insertions, 23 deletions
diff --git a/tools/uilib/abstractformbuilder.cpp b/tools/uilib/abstractformbuilder.cpp index a221b6c748..612126c88f 100644 --- a/tools/uilib/abstractformbuilder.cpp +++ b/tools/uilib/abstractformbuilder.cpp @@ -52,6 +52,7 @@ #include <QtCore/QDir> #include <QtCore/QQueue> #include <QtCore/QHash> +#include <QtCore/QPair> #include <QtCore/qdebug.h> #include <QtCore/QCoreApplication> @@ -143,44 +144,97 @@ QAbstractFormBuilder::~QAbstractFormBuilder() { } +// Return UI file version from attribute 'version="4.0"' +static QPair<int, int> uiVersion(const QString &attr) +{ + const QStringList versions = attr.split(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 = QLatin1String("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 = QLatin1String("version"); + const QString languageAttribute = QLatin1String("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) Loads an XML representation of a widget from the given \a device, and constructs a new widget with the specified \a parent. - \sa save() + \sa save(), errorString() */ QWidget *QAbstractFormBuilder::load(QIODevice *dev, QWidget *parentWidget) { - QXmlStreamReader reader; - reader.setDevice(dev); - DomUI ui; - bool initialized = false; - - const QString uiElement = QLatin1String("ui"); - while (!reader.atEnd()) { - if (reader.readNext() == QXmlStreamReader::StartElement) { - if (reader.name().compare(uiElement, Qt::CaseInsensitive) == 0) { - ui.read(reader); - initialized = true; - } else { - reader.raiseError(QCoreApplication::translate("QAbstractFormBuilder", "Unexpected element <%1>").arg(reader.name().toString())); - } - } + QXmlStreamReader reader(dev); + d->m_errorString.clear(); + if (!readUiAttributes(reader, d->m_language, &d->m_errorString)) { + uiLibWarning(d->m_errorString); + return false; } + DomUI ui; + ui.read(reader); if (reader.hasError()) { - uiLibWarning(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())); - return 0; - } - if (!initialized) { - uiLibWarning(QCoreApplication::translate("QAbstractFormBuilder", "Invalid UI file: The root element <ui> is missing.")); + d->m_errorString = msgXmlError(reader); + uiLibWarning(d->m_errorString); return 0; } QWidget *widget = create(&ui, parentWidget); + if (!widget && d->m_errorString.isEmpty()) + d->m_errorString = QCoreApplication::translate("QAbstractFormBuilder", "Invalid UI file"); return widget; } @@ -3085,4 +3139,16 @@ bool QAbstractFormBuilder::isScriptingEnabled() const #endif } +/*! + Returns a human-readable description of the last error occurred in load(). + + \since 5.0 + \sa load() +*/ + +QString QAbstractFormBuilder::errorString() const +{ + return d->m_errorString; +} + QT_END_NAMESPACE diff --git a/tools/uilib/abstractformbuilder.h b/tools/uilib/abstractformbuilder.h index 9d53e2d4b7..13208721ff 100644 --- a/tools/uilib/abstractformbuilder.h +++ b/tools/uilib/abstractformbuilder.h @@ -127,6 +127,8 @@ public: void setScriptingEnabled(bool enabled); bool isScriptingEnabled() const; + QString errorString() const; + protected: // // load diff --git a/tools/uilib/container.h b/tools/uilib/container.h index 89df461e02..f0d89faa08 100644 --- a/tools/uilib/container.h +++ b/tools/uilib/container.h @@ -65,6 +65,13 @@ public: virtual void addWidget(QWidget *widget) = 0; virtual void insertWidget(int index, QWidget *widget) = 0; virtual void remove(int index) = 0; + + virtual bool canAddWidget() const + // ### Qt6 remove body, provided in Qt5 for source compatibility to Qt4. + { return true; } + virtual bool canRemove(int index) const + // ### Qt6 remove body, provided in Qt5 for source compatibility to Qt4. + { Q_UNUSED(index); return true; } }; Q_DECLARE_EXTENSION_INTERFACE(QDesignerContainerExtension, "com.trolltech.Qt.Designer.Container") diff --git a/tools/uilib/container.qdoc b/tools/uilib/container.qdoc index d9310515d3..f8e0670811 100644 --- a/tools/uilib/container.qdoc +++ b/tools/uilib/container.qdoc @@ -170,3 +170,30 @@ \sa addWidget(), insertWidget() */ + +/*! + \fn bool QDesignerContainerExtension::canAddWidget() const + + Returns whether a widget can be added. This determines whether + the context menu options to add or insert pages are enabled. + + This should return false for containers that have a single, fixed + page, for example QScrollArea or QDockWidget. + + \since 5.0 + \sa addWidget(), canRemove() +*/ + +/*! + \fn bool QDesignerContainerExtension::canRemove(int index) const + + Returns whether the widget at the given \a index can be removed. + This determines whether the context menu option to remove the current + page is enabled. + + This should return false for containers that have a single, fixed + page, for example QScrollArea or QDockWidget. + + \since 5.0 + \sa remove(), canAddWidget() +*/ diff --git a/tools/uilib/formbuilderextra.cpp b/tools/uilib/formbuilderextra.cpp index bca0c595e5..264be6e461 100644 --- a/tools/uilib/formbuilderextra.cpp +++ b/tools/uilib/formbuilderextra.cpp @@ -87,6 +87,7 @@ QFormBuilderExtra::CustomWidgetData::CustomWidgetData(const DomCustomWidget *dcw QFormBuilderExtra::QFormBuilderExtra() : m_defaultMargin(INT_MIN), m_defaultSpacing(INT_MIN), + m_language(QLatin1String("c++")), m_layoutWidget(false), m_resourceBuilder(0), m_textBuilder(0) diff --git a/tools/uilib/formbuilderextra_p.h b/tools/uilib/formbuilderextra_p.h index a5e2029391..777776039d 100644 --- a/tools/uilib/formbuilderextra_p.h +++ b/tools/uilib/formbuilderextra_p.h @@ -180,6 +180,8 @@ public: int m_defaultMargin; int m_defaultSpacing; QDir m_workingDirectory; + QString m_errorString; + QString m_language; private: void clearResourceBuilder(); |