summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorSamuel Rødal <samuel.rodal@nokia.com>2011-05-20 19:45:38 +0200
committerSamuel Rødal <samuel.rodal@nokia.com>2011-05-20 19:46:19 +0200
commitd671acd5b296b83440db9836a92189c501c87ff3 (patch)
treebd9c1a000e17c70124c207666cfb3276b5518ffd /tools
parent42f5786104f9eef9542df2c7469a03324978281d (diff)
parent4f2138ecfbdc58e5cb5b0c7d762197ef69752957 (diff)
Merge remote branch 'staging/master' into refactor
Conflicts: src/opengl/qgl_qpa.cpp src/plugins/platforms/glxconvenience/qglxconvenience.cpp src/plugins/platforms/platforms.pro src/plugins/platforms/wayland/qwaylandwindow.cpp src/plugins/platforms/xcb/qxcbwindow.cpp src/plugins/platforms/xcb/qxcbwindow.h src/plugins/platforms/xcb/qxcbwindowsurface.cpp src/widgets/kernel/qwidget_qpa.cpp tests/auto/qvariant/tst_qvariant.cpp
Diffstat (limited to 'tools')
-rw-r--r--tools/uilib/abstractformbuilder.cpp112
-rw-r--r--tools/uilib/abstractformbuilder.h2
-rw-r--r--tools/uilib/container.h7
-rw-r--r--tools/uilib/container.qdoc27
-rw-r--r--tools/uilib/formbuilderextra.cpp1
-rw-r--r--tools/uilib/formbuilderextra_p.h2
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();