From 4e2153a1d5056249fc31e23890d8c525a3986e1b Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Thu, 18 Apr 2013 12:30:20 +0200 Subject: Declarative dialog improvements for the non-Window use case Platforms like Android and EGL don't support multiple top-level windows, so we have to avoid trying to use widget-based dialogs (because a widget dialog on top of a scene graph will result in a second window), allow the QML dialog to be an Item, and decorate it to look like a window. Task-number: QTBUG-31898 Change-Id: I9af049f3265188e8be677a05a8bc6d1699b4cd00 Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: Richard Moe Gustavsen --- src/imports/dialogs/plugin.cpp | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) (limited to 'src/imports/dialogs/plugin.cpp') diff --git a/src/imports/dialogs/plugin.cpp b/src/imports/dialogs/plugin.cpp index 5502a65310..8d1501cd03 100644 --- a/src/imports/dialogs/plugin.cpp +++ b/src/imports/dialogs/plugin.cpp @@ -48,6 +48,7 @@ #include "qquickabstractcolordialog_p.h" #include "qquickplatformcolordialog_p.h" #include +#include //#define PURE_QML_ONLY @@ -78,9 +79,18 @@ class QtQuick2DialogsPlugin : public QQmlExtensionPlugin public: QtQuick2DialogsPlugin() : QQmlExtensionPlugin() { } + virtual void initializeEngine(QQmlEngine *engine, const char *uri) { + //qDebug() << Q_FUNC_INFO << uri << m_decorationComponentUrl; + QQuickAbstractDialog::m_decorationComponent = + new QQmlComponent(engine, m_decorationComponentUrl, QQmlComponent::Asynchronous); + } + virtual void registerTypes(const char *uri) { Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick.Dialogs")); + bool hasTopLevelWindows = QGuiApplicationPrivate::platformIntegration()-> + hasCapability(QPlatformIntegration::MultipleWindows); QDir qmlDir(baseUrl().toLocalFile()); + m_decorationComponentUrl = QUrl::fromLocalFile(qmlDir.filePath(QString("qml/DefaultWindowDecoration.qml"))); QDir widgetsDir(baseUrl().toLocalFile()); // TODO: find the directory by searching rather than assuming a relative path widgetsDir.cd("../PrivateWidgets"); @@ -96,8 +106,7 @@ public: qmlRegisterType(uri, DIALOGS_MAJOR_MINOR, "FileDialog"); else #endif - registerWidgetOrQmlImplementation(widgetsDir, "WidgetFileDialog.qml", - qmlDir, "DefaultFileDialog.qml", "FileDialog", uri); + registerWidgetOrQmlImplementation(widgetsDir, qmlDir, "FileDialog", uri, hasTopLevelWindows); // ColorDialog #ifndef PURE_QML_ONLY @@ -105,35 +114,37 @@ public: qmlRegisterType(uri, DIALOGS_MAJOR_MINOR, "ColorDialog"); else #endif - registerWidgetOrQmlImplementation(widgetsDir, "WidgetColorDialog.qml", - qmlDir, "DefaultColorDialog.qml", "ColorDialog", uri); + registerWidgetOrQmlImplementation(widgetsDir, qmlDir, "ColorDialog", uri, hasTopLevelWindows); } protected: template - void registerWidgetOrQmlImplementation(QDir widgetsDir, QString widgetQmlFile, - QDir qmlDir, QString qmlFile, const char *qmlName, const char *uri) { + void registerWidgetOrQmlImplementation(QDir widgetsDir, QDir qmlDir, + const char *qmlName, const char *uri, bool hasTopLevelWindows) { + //qDebug() << Q_FUNC_INFO << qmlDir << qmlName << uri; bool needQml = true; + #ifndef PURE_QML_ONLY // If there is a qmldir and we have a QApplication instance (as opposed to a // widget-free QGuiApplication), assume that the widget-based dialog will work. - if (widgetsDir.exists("qmldir") && !widgetQmlFile.isEmpty() && + if (hasTopLevelWindows && widgetsDir.exists("qmldir") && !qstrcmp(QCoreApplication::instance()->metaObject()->className(), "QApplication")) { - QString dialogQmlPath = qmlDir.filePath(widgetQmlFile); + QString dialogQmlPath = qmlDir.filePath(QString("Widget%1.qml").arg(qmlName)); if (qmlRegisterType(QUrl::fromLocalFile(dialogQmlPath), uri, DIALOGS_MAJOR_MINOR, qmlName) >= 0) needQml = false; - // qDebug() << "registering" << qmlName << " as " << dialogQmlPath << "success?" << needQml; + // qDebug() << "registering" << qmlName << " as " << dialogQmlPath << "success?" << !needQml; } #endif if (needQml) { - QString dialogQmlPath = qmlDir.filePath(qmlFile); QByteArray abstractTypeName = QByteArray("Abstract") + qmlName; qmlRegisterType(uri, DIALOGS_MAJOR_MINOR, abstractTypeName); // implementation wrapper + QString dialogQmlPath = qmlDir.filePath(QString("Default%1.qml").arg(qmlName)); // qDebug() << "registering" << qmlName << " as " << dialogQmlPath << "success?" << qmlRegisterType(QUrl::fromLocalFile(dialogQmlPath), uri, DIALOGS_MAJOR_MINOR, qmlName); } } + QUrl m_decorationComponentUrl; }; QT_END_NAMESPACE -- cgit v1.2.3