[Qt][WK2] Move non-api classes to WebKit namespace at WebKit2/UiProcess/qt
[WebKit-https.git] / Source / WebKit2 / UIProcess / qt / QtDialogRunner.cpp
1 /*
2  * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this program; see the file COPYING.LIB.  If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  *
19  */
20
21 #include "config.h"
22 #include "QtDialogRunner.h"
23
24 #include "WKRetainPtr.h"
25 #include "WKStringQt.h"
26 #include "qwebpermissionrequest_p.h"
27 #include <QtQml/QQmlComponent>
28 #include <QtQml/QQmlContext>
29 #include <QtQml/QQmlEngine>
30 #include <QtQuick/QQuickItem>
31 #include <wtf/PassOwnPtr.h>
32
33 namespace WebKit {
34
35 QtDialogRunner::QtDialogRunner()
36     : QEventLoop()
37     , m_wasAccepted(false)
38 {
39 }
40
41 QtDialogRunner::~QtDialogRunner()
42 {
43 }
44
45 class DialogContextObject : public QObject {
46     Q_OBJECT
47     Q_PROPERTY(QString message READ message CONSTANT)
48     Q_PROPERTY(QString defaultValue READ defaultValue CONSTANT)
49
50 public:
51     DialogContextObject(const QString& message, const QString& defaultValue = QString())
52         : QObject()
53         , m_message(message)
54         , m_defaultValue(defaultValue)
55     {
56     }
57     QString message() const { return m_message; }
58     QString defaultValue() const { return m_defaultValue; }
59
60 public slots:
61     void dismiss() { emit dismissed(); }
62     void accept() { emit accepted(); }
63     void accept(const QString& result) { emit accepted(result); }
64     void reject() { emit rejected(); }
65
66 signals:
67     void dismissed();
68     void accepted();
69     void accepted(const QString& result);
70     void rejected();
71
72 private:
73     QString m_message;
74     QString m_defaultValue;
75 };
76
77 class BaseAuthenticationContextObject : public QObject {
78     Q_OBJECT
79     Q_PROPERTY(QString hostname READ hostname CONSTANT)
80     Q_PROPERTY(QString prefilledUsername READ prefilledUsername CONSTANT)
81
82 public:
83     BaseAuthenticationContextObject(const QString& hostname, const QString& prefilledUsername)
84         : QObject()
85         , m_hostname(hostname)
86         , m_prefilledUsername(prefilledUsername)
87     {
88     }
89
90     QString hostname() const { return m_hostname; }
91     QString prefilledUsername() const { return m_prefilledUsername; }
92
93 public slots:
94     void accept(const QString& username, const QString& password) { emit accepted(username, password); }
95     void reject() { emit rejected(); }
96
97 signals:
98     void accepted(const QString& username, const QString& password);
99     void rejected();
100
101 private:
102     QString m_hostname;
103     QString m_prefilledUsername;
104 };
105
106 class HttpAuthenticationDialogContextObject : public BaseAuthenticationContextObject {
107     Q_OBJECT
108     Q_PROPERTY(QString realm READ realm CONSTANT)
109
110 public:
111     HttpAuthenticationDialogContextObject(const QString& hostname, const QString& realm, const QString& prefilledUsername)
112         : BaseAuthenticationContextObject(hostname, prefilledUsername)
113         , m_realm(realm)
114     {
115     }
116
117     QString realm() const { return m_realm; }
118
119 private:
120     QString m_realm;
121 };
122
123 class ProxyAuthenticationDialogContextObject : public BaseAuthenticationContextObject {
124     Q_OBJECT
125     Q_PROPERTY(quint16 port READ port CONSTANT)
126
127 public:
128     ProxyAuthenticationDialogContextObject(const QString& hostname, quint16 port, const QString& prefilledUsername)
129         : BaseAuthenticationContextObject(hostname, prefilledUsername)
130         , m_port(port)
131     {
132     }
133
134     quint16 port() const { return m_port; }
135
136 private:
137     quint16 m_port;
138 };
139
140 class CertificateVerificationDialogContextObject : public QObject {
141     Q_OBJECT
142     Q_PROPERTY(QString hostname READ hostname CONSTANT)
143
144 public:
145     CertificateVerificationDialogContextObject(const QString& hostname)
146         : QObject()
147         , m_hostname(hostname)
148     {
149     }
150
151     QString hostname() const { return m_hostname; }
152
153 public slots:
154     void accept() { emit accepted(); }
155     void reject() { emit rejected(); }
156
157 signals:
158     void accepted();
159     void rejected();
160
161 private:
162     QString m_hostname;
163 };
164
165 class FilePickerContextObject : public QObject {
166     Q_OBJECT
167     Q_PROPERTY(QStringList fileList READ fileList CONSTANT)
168     Q_PROPERTY(bool allowMultipleFiles READ allowMultipleFiles CONSTANT)
169
170 public:
171     FilePickerContextObject(const QStringList& selectedFiles, bool allowMultiple)
172         : QObject()
173         , m_allowMultiple(allowMultiple)
174         , m_fileList(selectedFiles)
175     {
176     }
177
178     QStringList fileList() const { return m_fileList; }
179     bool allowMultipleFiles() const { return m_allowMultiple;}
180
181 public slots:
182     void reject() { emit rejected();}
183     void accept(const QVariant& path)
184     {
185         QStringList filesPath = path.toStringList();
186         // For single file upload, send only the first element if there are more than one file paths
187         if (!m_allowMultiple && filesPath.count() > 1)
188             filesPath = QStringList(filesPath.at(0));
189         emit fileSelected(filesPath);
190     }
191
192 signals:
193     void rejected();
194     void fileSelected(const QStringList&);
195
196 private:
197     bool m_allowMultiple;
198     QStringList m_fileList;
199 };
200
201 class DatabaseQuotaDialogContextObject : public QObject {
202     Q_OBJECT
203     Q_PROPERTY(QString databaseName READ databaseName CONSTANT)
204     Q_PROPERTY(QString displayName READ displayName CONSTANT)
205     Q_PROPERTY(quint64 currentQuota READ currentQuota CONSTANT)
206     Q_PROPERTY(quint64 currentOriginUsage READ currentOriginUsage CONSTANT)
207     Q_PROPERTY(quint64 currentDatabaseUsage READ currentDatabaseUsage CONSTANT)
208     Q_PROPERTY(quint64 expectedUsage READ expectedUsage CONSTANT)
209     Q_PROPERTY(QtWebSecurityOrigin* origin READ securityOrigin CONSTANT)
210
211 public:
212     DatabaseQuotaDialogContextObject(const QString& databaseName, const QString& displayName, WKSecurityOriginRef securityOrigin, quint64 currentQuota, quint64 currentOriginUsage, quint64 currentDatabaseUsage, quint64 expectedUsage)
213         : QObject()
214         , m_databaseName(databaseName)
215         , m_displayName(displayName)
216         , m_currentQuota(currentQuota)
217         , m_currentOriginUsage(currentOriginUsage)
218         , m_currentDatabaseUsage(currentDatabaseUsage)
219         , m_expectedUsage(expectedUsage)
220     {
221         WKRetainPtr<WKStringRef> scheme = adoptWK(WKSecurityOriginCopyProtocol(securityOrigin));
222         WKRetainPtr<WKStringRef> host = adoptWK(WKSecurityOriginCopyHost(securityOrigin));
223
224         m_securityOrigin.setScheme(WKStringCopyQString(scheme.get()));
225         m_securityOrigin.setHost(WKStringCopyQString(host.get()));
226         m_securityOrigin.setPort(static_cast<int>(WKSecurityOriginGetPort(securityOrigin)));
227     }
228
229     QString databaseName() const { return m_databaseName; }
230     QString displayName() const { return m_displayName; }
231     quint64 currentQuota() const { return m_currentQuota; }
232     quint64 currentOriginUsage() const { return m_currentOriginUsage; }
233     quint64 currentDatabaseUsage() const { return m_currentDatabaseUsage; }
234     quint64 expectedUsage() const { return m_expectedUsage; }
235     QtWebSecurityOrigin* securityOrigin() { return &m_securityOrigin; }
236
237 public slots:
238     void accept(quint64 size) { emit accepted(size); }
239     void reject() { emit rejected(); }
240
241 signals:
242     void accepted(quint64 size);
243     void rejected();
244
245 private:
246     QString m_databaseName;
247     QString m_displayName;
248     quint64 m_currentQuota;
249     quint64 m_currentOriginUsage;
250     quint64 m_currentDatabaseUsage;
251     quint64 m_expectedUsage;
252     QtWebSecurityOrigin m_securityOrigin;
253 };
254
255 bool QtDialogRunner::initForAlert(QQmlComponent* component, QQuickItem* dialogParent, const QString& message)
256 {
257     DialogContextObject* contextObject = new DialogContextObject(message);
258     if (!createDialog(component, dialogParent, contextObject))
259         return false;
260
261     connect(contextObject, SIGNAL(dismissed()), SLOT(quit()));
262     return true;
263 }
264
265 bool QtDialogRunner::initForConfirm(QQmlComponent* component, QQuickItem* dialogParent, const QString& message)
266 {
267     DialogContextObject* contextObject = new DialogContextObject(message);
268     if (!createDialog(component, dialogParent, contextObject))
269         return false;
270
271     connect(contextObject, SIGNAL(accepted()), SLOT(onAccepted()));
272     connect(contextObject, SIGNAL(accepted()), SLOT(quit()));
273     connect(contextObject, SIGNAL(rejected()), SLOT(quit()));
274     return true;
275 }
276
277 bool QtDialogRunner::initForPrompt(QQmlComponent* component, QQuickItem* dialogParent, const QString& message, const QString& defaultValue)
278 {
279     DialogContextObject* contextObject = new DialogContextObject(message, defaultValue);
280     if (!createDialog(component, dialogParent, contextObject))
281         return false;
282
283     connect(contextObject, SIGNAL(accepted(QString)), SLOT(onAccepted(QString)));
284     connect(contextObject, SIGNAL(accepted(QString)), SLOT(quit()));
285     connect(contextObject, SIGNAL(rejected()), SLOT(quit()));
286     return true;
287 }
288
289 bool QtDialogRunner::initForAuthentication(QQmlComponent* component, QQuickItem* dialogParent, const QString& hostname, const QString& realm, const QString& prefilledUsername)
290 {
291     HttpAuthenticationDialogContextObject* contextObject = new HttpAuthenticationDialogContextObject(hostname, realm, prefilledUsername);
292     if (!createDialog(component, dialogParent, contextObject))
293         return false;
294
295     connect(contextObject, SIGNAL(accepted(QString, QString)), SLOT(onAuthenticationAccepted(QString, QString)));
296     connect(contextObject, SIGNAL(accepted(QString, QString)), SLOT(quit()));
297     connect(contextObject, SIGNAL(rejected()), SLOT(quit()));
298
299     return true;
300 }
301
302 bool QtDialogRunner::initForProxyAuthentication(QQmlComponent* component, QQuickItem* dialogParent, const QString& hostname, uint16_t port, const QString& prefilledUsername)
303 {
304     ProxyAuthenticationDialogContextObject* contextObject = new ProxyAuthenticationDialogContextObject(hostname, port, prefilledUsername);
305     if (!createDialog(component, dialogParent, contextObject))
306         return false;
307
308     connect(contextObject, SIGNAL(accepted(QString, QString)), SLOT(onAuthenticationAccepted(QString, QString)));
309     connect(contextObject, SIGNAL(accepted(QString, QString)), SLOT(quit()));
310     connect(contextObject, SIGNAL(rejected()), SLOT(quit()));
311
312     return true;
313 }
314
315 bool QtDialogRunner::initForCertificateVerification(QQmlComponent* component, QQuickItem* dialogParent, const QString& hostname)
316 {
317     CertificateVerificationDialogContextObject* contextObject = new CertificateVerificationDialogContextObject(hostname);
318     if (!createDialog(component, dialogParent, contextObject))
319         return false;
320
321     connect(contextObject, SIGNAL(accepted()), SLOT(onAccepted()));
322     connect(contextObject, SIGNAL(accepted()), SLOT(quit()));
323     connect(contextObject, SIGNAL(rejected()), SLOT(quit()));
324
325     return true;
326 }
327
328 bool QtDialogRunner::initForFilePicker(QQmlComponent* component, QQuickItem* dialogParent, const QStringList& selectedFiles, bool allowMultiple)
329 {
330     FilePickerContextObject* contextObject = new FilePickerContextObject(selectedFiles, allowMultiple);
331     if (!createDialog(component, dialogParent, contextObject))
332         return false;
333
334     connect(contextObject, SIGNAL(fileSelected(QStringList)), SLOT(onFileSelected(QStringList)));
335     connect(contextObject, SIGNAL(fileSelected(QStringList)), SLOT(quit()));
336     connect(contextObject, SIGNAL(rejected()), SLOT(quit()));
337
338     return true;
339 }
340
341 bool QtDialogRunner::initForDatabaseQuotaDialog(QQmlComponent* component, QQuickItem* dialogParent, const QString& databaseName, const QString& displayName, WKSecurityOriginRef securityOrigin, quint64 currentQuota, quint64 currentOriginUsage, quint64 currentDatabaseUsage, quint64 expectedUsage)
342 {
343     DatabaseQuotaDialogContextObject* contextObject = new DatabaseQuotaDialogContextObject(databaseName, displayName, securityOrigin, currentQuota, currentOriginUsage, currentDatabaseUsage, expectedUsage);
344     if (!createDialog(component, dialogParent, contextObject))
345         return false;
346
347     connect(contextObject, SIGNAL(accepted(quint64)), SLOT(onDatabaseQuotaAccepted(quint64)));
348     connect(contextObject, SIGNAL(accepted(quint64)), SLOT(quit()));
349     connect(contextObject, SIGNAL(rejected()), SLOT(quit()));
350
351     return true;
352 }
353
354 bool QtDialogRunner::createDialog(QQmlComponent* component, QQuickItem* dialogParent, QObject* contextObject)
355 {
356     QQmlContext* baseContext = component->creationContext();
357     if (!baseContext)
358         baseContext = QQmlEngine::contextForObject(dialogParent);
359     m_dialogContext = adoptPtr(new QQmlContext(baseContext));
360
361     // This makes both "message" and "model.message" work for the dialog, just like QtQuick's ListView delegates.
362     contextObject->setParent(m_dialogContext.get());
363     m_dialogContext->setContextProperty(QLatin1String("model"), contextObject);
364     m_dialogContext->setContextObject(contextObject);
365
366     QObject* object = component->create(m_dialogContext.get());
367     if (!object) {
368         m_dialogContext.clear();
369         return false;
370     }
371
372     m_dialog = adoptPtr(qobject_cast<QQuickItem*>(object));
373     if (!m_dialog) {
374         m_dialogContext.clear();
375         m_dialog.clear();
376         return false;
377     }
378
379     m_dialog->setParentItem(dialogParent);
380     return true;
381 }
382
383 } // namespace WebKit
384
385 #include "QtDialogRunner.moc"
386 #include "moc_QtDialogRunner.cpp"
387