summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/uilib/abstractformbuilder.cpp112
-rw-r--r--tools/uilib/abstractformbuilder.h2
-rw-r--r--tools/uilib/formbuilderextra.cpp1
-rw-r--r--tools/uilib/formbuilderextra_p.h2
4 files changed, 94 insertions, 23 deletions
diff --git a/tools/uilib/abstractformbuilder.cpp b/tools/uilib/abstractformbuilder.cpp
index 4d142bd09f..1d44ad5ee6 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>
@@ -177,44 +178,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;
}
@@ -3119,4 +3173,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 4c22570932..3a1ddccc66 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/formbuilderextra.cpp b/tools/uilib/formbuilderextra.cpp
index 12e43f1e38..20e8e75327 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();