diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-05-18 14:03:11 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-05-18 14:03:11 +0200 |
commit | 8d473cf9743f1d30a16a27114e93bd5af5648d23 (patch) | |
tree | cdca40d0353886b3ca52f33a2d7b8f1c0011aafc /Source/WebKit2/UIProcess/qt/QtDialogRunner.cpp | |
parent | 1b914638db989aaa98631a1c1e02c7b2d44805d8 (diff) | |
download | qtwebkit-8d473cf9743f1d30a16a27114e93bd5af5648d23.tar.gz |
Imported WebKit commit 1350e72f7345ced9da2bd9980deeeb5a8d62fab4 (http://svn.webkit.org/repository/webkit/trunk@117578)
Weekly snapshot
Diffstat (limited to 'Source/WebKit2/UIProcess/qt/QtDialogRunner.cpp')
-rw-r--r-- | Source/WebKit2/UIProcess/qt/QtDialogRunner.cpp | 237 |
1 files changed, 168 insertions, 69 deletions
diff --git a/Source/WebKit2/UIProcess/qt/QtDialogRunner.cpp b/Source/WebKit2/UIProcess/qt/QtDialogRunner.cpp index 6e41c8b39..3ff4f273a 100644 --- a/Source/WebKit2/UIProcess/qt/QtDialogRunner.cpp +++ b/Source/WebKit2/UIProcess/qt/QtDialogRunner.cpp @@ -23,6 +23,7 @@ #include "WKRetainPtr.h" #include "WKStringQt.h" +#include "qquickwebview_p_p.h" #include "qwebpermissionrequest_p.h" #include <QtQml/QQmlComponent> #include <QtQml/QQmlContext> @@ -32,8 +33,9 @@ namespace WebKit { -QtDialogRunner::QtDialogRunner() +QtDialogRunner::QtDialogRunner(QQuickWebView* webView) : QEventLoop() + , m_webView(webView) , m_wasAccepted(false) { } @@ -42,30 +44,62 @@ QtDialogRunner::~QtDialogRunner() { } -class DialogContextObject : public QObject { +// All dialogs need a way to support the state of the +// dialog being done/finished/dismissed. This is handled +// in the dialog base context. +class DialogContextBase : public QObject { + Q_OBJECT + +public: + DialogContextBase() + : QObject() + , m_dismissed(false) + { + } + +public slots: + // Allows clients to call dismiss() directly, while also + // being able to hook up signals to automatically also + // dismiss the dialog since it's a slot. + + void dismiss() + { + m_dismissed = true; + emit dismissed(); + } + +signals: + void dismissed(); + +private: + // We store the dismissed state so that run() can check to see if a + // dialog has already been dismissed before spinning an event loop. + bool m_dismissed; + friend void QtDialogRunner::run(); +}; + +class DialogContextObject : public DialogContextBase { Q_OBJECT Q_PROPERTY(QString message READ message CONSTANT) Q_PROPERTY(QString defaultValue READ defaultValue CONSTANT) public: DialogContextObject(const QString& message, const QString& defaultValue = QString()) - : QObject() + : DialogContextBase() , m_message(message) , m_defaultValue(defaultValue) { + connect(this, SIGNAL(accepted(QString)), SLOT(dismiss())); + connect(this, SIGNAL(rejected()), SLOT(dismiss())); } QString message() const { return m_message; } QString defaultValue() const { return m_defaultValue; } public slots: - void dismiss() { emit dismissed(); } - void accept() { emit accepted(); } - void accept(const QString& result) { emit accepted(result); } + void accept(const QString& result = QString()) { emit accepted(result); } void reject() { emit rejected(); } signals: - void dismissed(); - void accepted(); void accepted(const QString& result); void rejected(); @@ -74,17 +108,19 @@ private: QString m_defaultValue; }; -class BaseAuthenticationContextObject : public QObject { +class BaseAuthenticationContextObject : public DialogContextBase { Q_OBJECT Q_PROPERTY(QString hostname READ hostname CONSTANT) Q_PROPERTY(QString prefilledUsername READ prefilledUsername CONSTANT) public: BaseAuthenticationContextObject(const QString& hostname, const QString& prefilledUsername) - : QObject() + : DialogContextBase() , m_hostname(hostname) , m_prefilledUsername(prefilledUsername) { + connect(this, SIGNAL(accepted(QString, QString)), SLOT(dismiss())); + connect(this, SIGNAL(rejected()), SLOT(dismiss())); } QString hostname() const { return m_hostname; } @@ -137,15 +173,17 @@ private: quint16 m_port; }; -class CertificateVerificationDialogContextObject : public QObject { +class CertificateVerificationDialogContextObject : public DialogContextBase { Q_OBJECT Q_PROPERTY(QString hostname READ hostname CONSTANT) public: CertificateVerificationDialogContextObject(const QString& hostname) - : QObject() + : DialogContextBase() , m_hostname(hostname) { + connect(this, SIGNAL(accepted()), SLOT(dismiss())); + connect(this, SIGNAL(rejected()), SLOT(dismiss())); } QString hostname() const { return m_hostname; } @@ -162,17 +200,19 @@ private: QString m_hostname; }; -class FilePickerContextObject : public QObject { +class FilePickerContextObject : public DialogContextBase { Q_OBJECT Q_PROPERTY(QStringList fileList READ fileList CONSTANT) Q_PROPERTY(bool allowMultipleFiles READ allowMultipleFiles CONSTANT) public: FilePickerContextObject(const QStringList& selectedFiles, bool allowMultiple) - : QObject() + : DialogContextBase() , m_allowMultiple(allowMultiple) , m_fileList(selectedFiles) { + connect(this, SIGNAL(fileSelected(QStringList)), SLOT(dismiss())); + connect(this, SIGNAL(rejected()), SLOT(dismiss())); } QStringList fileList() const { return m_fileList; } @@ -198,7 +238,7 @@ private: QStringList m_fileList; }; -class DatabaseQuotaDialogContextObject : public QObject { +class DatabaseQuotaDialogContextObject : public DialogContextBase { Q_OBJECT Q_PROPERTY(QString databaseName READ databaseName CONSTANT) Q_PROPERTY(QString displayName READ displayName CONSTANT) @@ -210,7 +250,7 @@ class DatabaseQuotaDialogContextObject : public QObject { public: DatabaseQuotaDialogContextObject(const QString& databaseName, const QString& displayName, WKSecurityOriginRef securityOrigin, quint64 currentQuota, quint64 currentOriginUsage, quint64 currentDatabaseUsage, quint64 expectedUsage) - : QObject() + : DialogContextBase() , m_databaseName(databaseName) , m_displayName(displayName) , m_currentQuota(currentQuota) @@ -224,6 +264,9 @@ public: m_securityOrigin.setScheme(WKStringCopyQString(scheme.get())); m_securityOrigin.setHost(WKStringCopyQString(host.get())); m_securityOrigin.setPort(static_cast<int>(WKSecurityOriginGetPort(securityOrigin))); + + connect(this, SIGNAL(accepted(quint64)), SLOT(dismiss())); + connect(this, SIGNAL(rejected()), SLOT(dismiss())); } QString databaseName() const { return m_databaseName; } @@ -252,118 +295,136 @@ private: QtWebSecurityOrigin m_securityOrigin; }; -bool QtDialogRunner::initForAlert(QQmlComponent* component, QQuickItem* dialogParent, const QString& message) +void QtDialogRunner::run() { - DialogContextObject* contextObject = new DialogContextObject(message); - if (!createDialog(component, dialogParent, contextObject)) - return false; + DialogContextBase* context = static_cast<DialogContextBase*>(m_dialogContext->contextObject()); - connect(contextObject, SIGNAL(dismissed()), SLOT(quit())); - return true; + // We may have already been dismissed as part of Component.onCompleted() + if (context->m_dismissed) + return; + + connect(context, SIGNAL(dismissed()), SLOT(quit())); + + QQuickWebViewPrivate* webViewPrivate = QQuickWebViewPrivate::get(m_webView); + + // FIXME: Change the way we disable mouse and touch events to use the + // concept of suspending instead (in this case event processing). + webViewPrivate->disableMouseEvents(); + webViewPrivate->m_dialogActive = true; + exec(); // Spin the event loop + webViewPrivate->m_dialogActive = false; + webViewPrivate->enableMouseEvents(); } -bool QtDialogRunner::initForConfirm(QQmlComponent* component, QQuickItem* dialogParent, const QString& message) +bool QtDialogRunner::initForAlert(const QString& message) { + QQmlComponent* component = m_webView->experimental()->alertDialog(); + if (!component) + return false; + DialogContextObject* contextObject = new DialogContextObject(message); - if (!createDialog(component, dialogParent, contextObject)) + + return createDialog(component, contextObject); +} + +bool QtDialogRunner::initForConfirm(const QString& message) +{ + QQmlComponent* component = m_webView->experimental()->confirmDialog(); + if (!component) return false; - connect(contextObject, SIGNAL(accepted()), SLOT(onAccepted())); - connect(contextObject, SIGNAL(accepted()), SLOT(quit())); - connect(contextObject, SIGNAL(rejected()), SLOT(quit())); - return true; + DialogContextObject* contextObject = new DialogContextObject(message); + connect(contextObject, SIGNAL(accepted(QString)), SLOT(onAccepted())); + + return createDialog(component, contextObject); } -bool QtDialogRunner::initForPrompt(QQmlComponent* component, QQuickItem* dialogParent, const QString& message, const QString& defaultValue) +bool QtDialogRunner::initForPrompt(const QString& message, const QString& defaultValue) { - DialogContextObject* contextObject = new DialogContextObject(message, defaultValue); - if (!createDialog(component, dialogParent, contextObject)) + QQmlComponent* component = m_webView->experimental()->promptDialog(); + if (!component) return false; + DialogContextObject* contextObject = new DialogContextObject(message, defaultValue); connect(contextObject, SIGNAL(accepted(QString)), SLOT(onAccepted(QString))); - connect(contextObject, SIGNAL(accepted(QString)), SLOT(quit())); - connect(contextObject, SIGNAL(rejected()), SLOT(quit())); - return true; + + return createDialog(component, contextObject); } -bool QtDialogRunner::initForAuthentication(QQmlComponent* component, QQuickItem* dialogParent, const QString& hostname, const QString& realm, const QString& prefilledUsername) +bool QtDialogRunner::initForAuthentication(const QString& hostname, const QString& realm, const QString& prefilledUsername) { - HttpAuthenticationDialogContextObject* contextObject = new HttpAuthenticationDialogContextObject(hostname, realm, prefilledUsername); - if (!createDialog(component, dialogParent, contextObject)) + QQmlComponent* component = m_webView->experimental()->authenticationDialog(); + if (!component) return false; + HttpAuthenticationDialogContextObject* contextObject = new HttpAuthenticationDialogContextObject(hostname, realm, prefilledUsername); connect(contextObject, SIGNAL(accepted(QString, QString)), SLOT(onAuthenticationAccepted(QString, QString))); - connect(contextObject, SIGNAL(accepted(QString, QString)), SLOT(quit())); - connect(contextObject, SIGNAL(rejected()), SLOT(quit())); - return true; + return createDialog(component, contextObject); } -bool QtDialogRunner::initForProxyAuthentication(QQmlComponent* component, QQuickItem* dialogParent, const QString& hostname, uint16_t port, const QString& prefilledUsername) +bool QtDialogRunner::initForProxyAuthentication(const QString& hostname, uint16_t port, const QString& prefilledUsername) { - ProxyAuthenticationDialogContextObject* contextObject = new ProxyAuthenticationDialogContextObject(hostname, port, prefilledUsername); - if (!createDialog(component, dialogParent, contextObject)) + QQmlComponent* component = m_webView->experimental()->proxyAuthenticationDialog(); + if (!component) return false; + ProxyAuthenticationDialogContextObject* contextObject = new ProxyAuthenticationDialogContextObject(hostname, port, prefilledUsername); connect(contextObject, SIGNAL(accepted(QString, QString)), SLOT(onAuthenticationAccepted(QString, QString))); - connect(contextObject, SIGNAL(accepted(QString, QString)), SLOT(quit())); - connect(contextObject, SIGNAL(rejected()), SLOT(quit())); - return true; + return createDialog(component, contextObject); } -bool QtDialogRunner::initForCertificateVerification(QQmlComponent* component, QQuickItem* dialogParent, const QString& hostname) +bool QtDialogRunner::initForCertificateVerification(const QString& hostname) { - CertificateVerificationDialogContextObject* contextObject = new CertificateVerificationDialogContextObject(hostname); - if (!createDialog(component, dialogParent, contextObject)) + QQmlComponent* component = m_webView->experimental()->certificateVerificationDialog(); + if (!component) return false; + CertificateVerificationDialogContextObject* contextObject = new CertificateVerificationDialogContextObject(hostname); connect(contextObject, SIGNAL(accepted()), SLOT(onAccepted())); - connect(contextObject, SIGNAL(accepted()), SLOT(quit())); - connect(contextObject, SIGNAL(rejected()), SLOT(quit())); - return true; + return createDialog(component, contextObject); } -bool QtDialogRunner::initForFilePicker(QQmlComponent* component, QQuickItem* dialogParent, const QStringList& selectedFiles, bool allowMultiple) +bool QtDialogRunner::initForFilePicker(const QStringList& selectedFiles, bool allowMultiple) { - FilePickerContextObject* contextObject = new FilePickerContextObject(selectedFiles, allowMultiple); - if (!createDialog(component, dialogParent, contextObject)) + QQmlComponent* component = m_webView->experimental()->filePicker(); + if (!component) return false; + FilePickerContextObject* contextObject = new FilePickerContextObject(selectedFiles, allowMultiple); connect(contextObject, SIGNAL(fileSelected(QStringList)), SLOT(onFileSelected(QStringList))); - connect(contextObject, SIGNAL(fileSelected(QStringList)), SLOT(quit())); - connect(contextObject, SIGNAL(rejected()), SLOT(quit())); - return true; + return createDialog(component, contextObject); } -bool QtDialogRunner::initForDatabaseQuotaDialog(QQmlComponent* component, QQuickItem* dialogParent, const QString& databaseName, const QString& displayName, WKSecurityOriginRef securityOrigin, quint64 currentQuota, quint64 currentOriginUsage, quint64 currentDatabaseUsage, quint64 expectedUsage) +bool QtDialogRunner::initForDatabaseQuotaDialog(const QString& databaseName, const QString& displayName, WKSecurityOriginRef securityOrigin, quint64 currentQuota, quint64 currentOriginUsage, quint64 currentDatabaseUsage, quint64 expectedUsage) { - DatabaseQuotaDialogContextObject* contextObject = new DatabaseQuotaDialogContextObject(databaseName, displayName, securityOrigin, currentQuota, currentOriginUsage, currentDatabaseUsage, expectedUsage); - if (!createDialog(component, dialogParent, contextObject)) + QQmlComponent* component = m_webView->experimental()->databaseQuotaDialog(); + if (!component) return false; + DatabaseQuotaDialogContextObject* contextObject = new DatabaseQuotaDialogContextObject(databaseName, displayName, securityOrigin, currentQuota, currentOriginUsage, currentDatabaseUsage, expectedUsage); connect(contextObject, SIGNAL(accepted(quint64)), SLOT(onDatabaseQuotaAccepted(quint64))); - connect(contextObject, SIGNAL(accepted(quint64)), SLOT(quit())); - connect(contextObject, SIGNAL(rejected()), SLOT(quit())); - return true; + return createDialog(component, contextObject); } -bool QtDialogRunner::createDialog(QQmlComponent* component, QQuickItem* dialogParent, QObject* contextObject) +bool QtDialogRunner::createDialog(QQmlComponent* component, QObject* contextObject) { QQmlContext* baseContext = component->creationContext(); if (!baseContext) - baseContext = QQmlEngine::contextForObject(dialogParent); + baseContext = QQmlEngine::contextForObject(m_webView); m_dialogContext = adoptPtr(new QQmlContext(baseContext)); - // This makes both "message" and "model.message" work for the dialog, just like QtQuick's ListView delegates. + // This makes both "message" and "model.message" work for the dialog, + // just like QtQuick's ListView delegates. contextObject->setParent(m_dialogContext.get()); m_dialogContext->setContextProperty(QLatin1String("model"), contextObject); m_dialogContext->setContextObject(contextObject); - QObject* object = component->create(m_dialogContext.get()); + QObject* object = component->beginCreate(m_dialogContext.get()); if (!object) { m_dialogContext.clear(); return false; @@ -376,10 +437,48 @@ bool QtDialogRunner::createDialog(QQmlComponent* component, QQuickItem* dialogPa return false; } - m_dialog->setParentItem(dialogParent); + QQuickWebViewPrivate::get(m_webView)->addAttachedPropertyTo(m_dialog.get()); + m_dialog->setParentItem(m_webView); + + // Only fully create the component once we've set both a parent + // and the needed context and attached properties, so that dialogs + // can do useful stuff in their Component.onCompleted() method. + component->completeCreate(); + + // FIXME: As part of completeCreate, the bindings of the item will be + // evaluated, but for some reason doing mapToItem/mapFromItem in a + // binding will not work as expected, even if we at binding evaluation + // time have the parent and all the way up to the root QML item. + // As a workaround you can set whichever property you need in + // Component.onCompleted, even to a binding using Qt.bind(). + return true; } +void QtDialogRunner::onAccepted(const QString& result) +{ + m_wasAccepted = true; + m_result = result; +} + +void QtDialogRunner::onAuthenticationAccepted(const QString& username, const QString& password) +{ + m_username = username; + m_password = password; +} + +void QtDialogRunner::onFileSelected(const QStringList& filePaths) +{ + m_wasAccepted = true; + m_filepaths = filePaths; +} + +void QtDialogRunner::onDatabaseQuotaAccepted(quint64 quota) +{ + m_wasAccepted = true; + m_databaseQuota = quota; +} + } // namespace WebKit #include "QtDialogRunner.moc" |