QtDialogRunner.cpp [plain text]
#include "config.h"
#include "QtDialogRunner.h"
#include "WKRetainPtr.h"
#include "WKStringQt.h"
#include "qquickwebview_p_p.h"
#include "qwebpermissionrequest_p.h"
#include <QtQml/QQmlComponent>
#include <QtQml/QQmlContext>
#include <QtQml/QQmlEngine>
#include <QtQuick/QQuickItem>
#include <wtf/PassOwnPtr.h>
namespace WebKit {
QtDialogRunner::QtDialogRunner(QQuickWebView* webView)
: QEventLoop()
, m_webView(webView)
, m_wasAccepted(false)
{
}
QtDialogRunner::~QtDialogRunner()
{
}
class DialogContextBase : public QObject {
Q_OBJECT
public:
DialogContextBase()
: QObject()
, m_dismissed(false)
{
}
public Q_SLOTS:
void dismiss()
{
m_dismissed = true;
emit dismissed();
}
Q_SIGNALS:
void dismissed();
private:
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())
: 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 Q_SLOTS:
void accept(const QString& result = QString()) { emit accepted(result); }
void reject() { emit rejected(); }
Q_SIGNALS:
void accepted(const QString& result);
void rejected();
private:
QString m_message;
QString m_defaultValue;
};
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)
: 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; }
QString prefilledUsername() const { return m_prefilledUsername; }
public Q_SLOTS:
void accept(const QString& username, const QString& password) { emit accepted(username, password); }
void reject() { emit rejected(); }
Q_SIGNALS:
void accepted(const QString& username, const QString& password);
void rejected();
private:
QString m_hostname;
QString m_prefilledUsername;
};
class HttpAuthenticationDialogContextObject : public BaseAuthenticationContextObject {
Q_OBJECT
Q_PROPERTY(QString realm READ realm CONSTANT)
public:
HttpAuthenticationDialogContextObject(const QString& hostname, const QString& realm, const QString& prefilledUsername)
: BaseAuthenticationContextObject(hostname, prefilledUsername)
, m_realm(realm)
{
}
QString realm() const { return m_realm; }
private:
QString m_realm;
};
class ProxyAuthenticationDialogContextObject : public BaseAuthenticationContextObject {
Q_OBJECT
Q_PROPERTY(quint16 port READ port CONSTANT)
public:
ProxyAuthenticationDialogContextObject(const QString& hostname, quint16 port, const QString& prefilledUsername)
: BaseAuthenticationContextObject(hostname, prefilledUsername)
, m_port(port)
{
}
quint16 port() const { return m_port; }
private:
quint16 m_port;
};
class CertificateVerificationDialogContextObject : public DialogContextBase {
Q_OBJECT
Q_PROPERTY(QString hostname READ hostname CONSTANT)
public:
CertificateVerificationDialogContextObject(const QString& hostname)
: DialogContextBase()
, m_hostname(hostname)
{
connect(this, SIGNAL(accepted()), SLOT(dismiss()));
connect(this, SIGNAL(rejected()), SLOT(dismiss()));
}
QString hostname() const { return m_hostname; }
public Q_SLOTS:
void accept() { emit accepted(); }
void reject() { emit rejected(); }
Q_SIGNALS:
void accepted();
void rejected();
private:
QString m_hostname;
};
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)
: 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; }
bool allowMultipleFiles() const { return m_allowMultiple;}
public Q_SLOTS:
void reject() { emit rejected();}
void accept(const QVariant& path)
{
QStringList filesPath = path.toStringList();
if (filesPath.isEmpty()) {
emit rejected();
return;
}
if (!m_allowMultiple && filesPath.count() > 1)
filesPath = QStringList(filesPath.at(0));
emit fileSelected(filesPath);
}
Q_SIGNALS:
void rejected();
void fileSelected(const QStringList&);
private:
bool m_allowMultiple;
QStringList m_fileList;
};
class DatabaseQuotaDialogContextObject : public DialogContextBase {
Q_OBJECT
Q_PROPERTY(QString databaseName READ databaseName CONSTANT)
Q_PROPERTY(QString displayName READ displayName CONSTANT)
Q_PROPERTY(quint64 currentQuota READ currentQuota CONSTANT)
Q_PROPERTY(quint64 currentOriginUsage READ currentOriginUsage CONSTANT)
Q_PROPERTY(quint64 currentDatabaseUsage READ currentDatabaseUsage CONSTANT)
Q_PROPERTY(quint64 expectedUsage READ expectedUsage CONSTANT)
Q_PROPERTY(QtWebSecurityOrigin* origin READ securityOrigin CONSTANT)
public:
DatabaseQuotaDialogContextObject(const QString& databaseName, const QString& displayName, WKSecurityOriginRef securityOrigin, quint64 currentQuota, quint64 currentOriginUsage, quint64 currentDatabaseUsage, quint64 expectedUsage)
: DialogContextBase()
, m_databaseName(databaseName)
, m_displayName(displayName)
, m_currentQuota(currentQuota)
, m_currentOriginUsage(currentOriginUsage)
, m_currentDatabaseUsage(currentDatabaseUsage)
, m_expectedUsage(expectedUsage)
{
WKRetainPtr<WKStringRef> scheme = adoptWK(WKSecurityOriginCopyProtocol(securityOrigin));
WKRetainPtr<WKStringRef> host = adoptWK(WKSecurityOriginCopyHost(securityOrigin));
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; }
QString displayName() const { return m_displayName; }
quint64 currentQuota() const { return m_currentQuota; }
quint64 currentOriginUsage() const { return m_currentOriginUsage; }
quint64 currentDatabaseUsage() const { return m_currentDatabaseUsage; }
quint64 expectedUsage() const { return m_expectedUsage; }
QtWebSecurityOrigin* securityOrigin() { return &m_securityOrigin; }
public Q_SLOTS:
void accept(quint64 size) { emit accepted(size); }
void reject() { emit rejected(); }
Q_SIGNALS:
void accepted(quint64 size);
void rejected();
private:
QString m_databaseName;
QString m_displayName;
quint64 m_currentQuota;
quint64 m_currentOriginUsage;
quint64 m_currentDatabaseUsage;
quint64 m_expectedUsage;
QtWebSecurityOrigin m_securityOrigin;
};
void QtDialogRunner::run()
{
DialogContextBase* context = static_cast<DialogContextBase*>(m_dialogContext->contextObject());
if (context->m_dismissed)
return;
connect(context, SIGNAL(dismissed()), SLOT(quit()));
exec(); }
bool QtDialogRunner::initForAlert(const QString& message)
{
QQmlComponent* component = m_webView->experimental()->alertDialog();
if (!component)
return false;
DialogContextObject* contextObject = new DialogContextObject(message);
return createDialog(component, contextObject);
}
bool QtDialogRunner::initForConfirm(const QString& message)
{
QQmlComponent* component = m_webView->experimental()->confirmDialog();
if (!component)
return false;
DialogContextObject* contextObject = new DialogContextObject(message);
connect(contextObject, SIGNAL(accepted(QString)), SLOT(onAccepted()));
return createDialog(component, contextObject);
}
bool QtDialogRunner::initForPrompt(const QString& message, const QString& defaultValue)
{
QQmlComponent* component = m_webView->experimental()->promptDialog();
if (!component)
return false;
DialogContextObject* contextObject = new DialogContextObject(message, defaultValue);
connect(contextObject, SIGNAL(accepted(QString)), SLOT(onAccepted(QString)));
return createDialog(component, contextObject);
}
bool QtDialogRunner::initForAuthentication(const QString& hostname, const QString& realm, const QString& prefilledUsername)
{
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)));
return createDialog(component, contextObject);
}
bool QtDialogRunner::initForProxyAuthentication(const QString& hostname, uint16_t port, const QString& prefilledUsername)
{
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)));
return createDialog(component, contextObject);
}
bool QtDialogRunner::initForCertificateVerification(const QString& hostname)
{
QQmlComponent* component = m_webView->experimental()->certificateVerificationDialog();
if (!component)
return false;
CertificateVerificationDialogContextObject* contextObject = new CertificateVerificationDialogContextObject(hostname);
connect(contextObject, SIGNAL(accepted()), SLOT(onAccepted()));
return createDialog(component, contextObject);
}
bool QtDialogRunner::initForFilePicker(const QStringList& selectedFiles, bool allowMultiple)
{
QQmlComponent* component = m_webView->experimental()->filePicker();
if (!component)
return false;
FilePickerContextObject* contextObject = new FilePickerContextObject(selectedFiles, allowMultiple);
connect(contextObject, SIGNAL(fileSelected(QStringList)), SLOT(onFileSelected(QStringList)));
return createDialog(component, contextObject);
}
bool QtDialogRunner::initForDatabaseQuotaDialog(const QString& databaseName, const QString& displayName, WKSecurityOriginRef securityOrigin, quint64 currentQuota, quint64 currentOriginUsage, quint64 currentDatabaseUsage, quint64 expectedUsage)
{
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)));
return createDialog(component, contextObject);
}
bool QtDialogRunner::createDialog(QQmlComponent* component, QObject* contextObject)
{
QQmlContext* baseContext = component->creationContext();
if (!baseContext)
baseContext = QQmlEngine::contextForObject(m_webView);
m_dialogContext = adoptPtr(new QQmlContext(baseContext));
contextObject->setParent(m_dialogContext.get());
m_dialogContext->setContextProperty(QLatin1String("model"), contextObject);
m_dialogContext->setContextObject(contextObject);
QObject* object = component->beginCreate(m_dialogContext.get());
if (!object) {
m_dialogContext.clear();
return false;
}
m_dialog = adoptPtr(qobject_cast<QQuickItem*>(object));
if (!m_dialog) {
m_dialogContext.clear();
m_dialog.clear();
return false;
}
QQuickWebViewPrivate::get(m_webView)->addAttachedPropertyTo(m_dialog.get());
m_dialog->setParentItem(m_webView);
component->completeCreate();
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;
}
}
#include "QtDialogRunner.moc"
#include "moc_QtDialogRunner.cpp"