c4608a9c93e0b1dd9eca9b73479891afead0a5bd
[WebKit-https.git] / Source / WebKit2 / UIProcess / API / qt / qdesktopwebview.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 "qdesktopwebview.h"
23 #include "qdesktopwebview_p.h"
24 #include "qwkcontext.h"
25
26 #include <QGraphicsSceneResizeEvent>
27 #include <QStyleOptionGraphicsItem>
28 #include <QtDeclarative/qsgcanvas.h>
29 #include <QtDeclarative/qsgevent.h>
30 #include <QtDeclarative/qsgitem.h>
31 #include <QtGui/QCursor>
32 #include <QtGui/QFocusEvent>
33 #include <QtGui/QGraphicsSceneEvent>
34 #include <QtGui/QHoverEvent>
35 #include <QtGui/QInputMethodEvent>
36 #include <QtGui/QKeyEvent>
37 #include <QtGui/QTouchEvent>
38 #include <QtGui/QWheelEvent>
39
40 QDesktopWebViewPrivate::QDesktopWebViewPrivate(QDesktopWebView* q, WKContextRef contextRef, WKPageGroupRef pageGroupRef)
41     : q(q)
42     , page(this, contextRef ? new QWKContext(contextRef) : defaultWKContext(), pageGroupRef)
43     , isCrashed(false)
44 {
45 }
46
47 void QDesktopWebViewPrivate::setViewNeedsDisplay(const QRect& invalidatedArea)
48 {
49     q->update(invalidatedArea);
50 }
51
52 QSize QDesktopWebViewPrivate::drawingAreaSize()
53 {
54     return QSize(q->width(), q->height());
55 }
56
57 void QDesktopWebViewPrivate::contentSizeChanged(const QSize&)
58 {
59 }
60
61 bool QDesktopWebViewPrivate::isActive()
62 {
63     // FIXME: The scene graph did not have the concept of being active or not when this was written.
64     return true;
65 }
66
67 bool QDesktopWebViewPrivate::hasFocus()
68 {
69     return q->hasFocus();
70 }
71
72 bool QDesktopWebViewPrivate::isVisible()
73 {
74     return q->isVisible();
75 }
76
77 void QDesktopWebViewPrivate::startDrag(Qt::DropActions supportedDropActions, const QImage& dragImage, QMimeData* data, QPoint* clientPosition, QPoint* globalPosition, Qt::DropAction* dropAction)
78 {
79     QWidget* widget = q->canvas();
80     if (!widget)
81         return;
82
83     QDrag* drag = new QDrag(widget);
84     drag->setPixmap(QPixmap::fromImage(dragImage));
85     drag->setMimeData(data);
86     *dropAction = drag->exec(supportedDropActions);
87     *globalPosition = QCursor::pos();
88     *clientPosition = widget->mapFromGlobal(*globalPosition);
89 }
90
91 void QDesktopWebViewPrivate::didChangeUrl(const QUrl& url)
92 {
93     emit q->urlChanged(url);
94 }
95
96 void QDesktopWebViewPrivate::didChangeTitle(const QString& newTitle)
97 {
98     emit q->titleChanged(newTitle);
99 }
100
101 void QDesktopWebViewPrivate::didChangeToolTip(const QString& newToolTip)
102 {
103     // FIXME: Add a proper implementation when Qt 5 supports tooltip.
104     q->canvas()->setToolTip(newToolTip);
105 }
106
107 void QDesktopWebViewPrivate::didChangeStatusText(const QString& newMessage)
108 {
109     emit q->statusBarMessageChanged(newMessage);
110 }
111
112 void QDesktopWebViewPrivate::didChangeCursor(const QCursor& newCursor)
113 {
114     // FIXME: add proper cursor handling when Qt 5 supports it.
115     q->canvas()->setCursor(newCursor);
116 }
117
118 void QDesktopWebViewPrivate::loadDidBegin()
119 {
120     emit q->loadStarted();
121 }
122
123 void QDesktopWebViewPrivate::loadDidSucceed()
124 {
125     emit q->loadSucceeded();
126 }
127
128 void QDesktopWebViewPrivate::loadDidFail(const QWebError& error)
129 {
130     emit q->loadFailed(error);
131 }
132
133 void QDesktopWebViewPrivate::didChangeLoadProgress(int percentageLoaded)
134 {
135     emit q->loadProgressChanged(percentageLoaded);
136 }
137
138 void QDesktopWebViewPrivate::showContextMenu(QSharedPointer<QMenu> menu)
139 {
140     // Remove the active menu in case this function is called twice.
141     if (activeMenu)
142         activeMenu->hide();
143
144     if (menu->isEmpty())
145         return;
146
147     QWidget* widget = q->canvas();
148     if (!widget)
149         return;
150
151     activeMenu = menu;
152
153     menu->setParent(widget, menu->windowFlags());
154     menu->exec(widget->mapToGlobal(menu->pos()));
155     // The last function to get out of exec() clear the local copy.
156     if (activeMenu == menu)
157         activeMenu.clear();
158 }
159
160 void QDesktopWebViewPrivate::hideContextMenu()
161 {
162     if (activeMenu)
163         activeMenu->hide();
164 }
165
166 QDesktopWebView::QDesktopWebView(QSGItem* parent)
167     : QSGPaintedItem(parent)
168     , d(new QDesktopWebViewPrivate(this))
169 {
170     init();
171 }
172
173 QDesktopWebView::QDesktopWebView(WKContextRef contextRef, WKPageGroupRef pageGroupRef, QSGItem* parent)
174     : QSGPaintedItem(parent)
175     , d(new QDesktopWebViewPrivate(this, contextRef, pageGroupRef))
176 {
177     init();
178 }
179
180 void QDesktopWebView::init()
181 {
182     setAcceptedMouseButtons(Qt::MouseButtonMask);
183     setAcceptHoverEvents(true);
184 }
185
186 QDesktopWebView::~QDesktopWebView()
187 {
188     delete d;
189 }
190
191 void QDesktopWebView::load(const QUrl& url)
192 {
193     d->page.load(url);
194 }
195
196 QUrl QDesktopWebView::url() const
197 {
198     return d->page.url();
199 }
200
201 int QDesktopWebView::loadProgress() const
202 {
203     return d->page.loadProgress();
204 }
205
206 QString QDesktopWebView::title() const
207 {
208     return d->page.title();
209 }
210
211 QAction* QDesktopWebView::navigationAction(QtWebKit::NavigationAction which) const
212 {
213     return d->page.navigationAction(which);
214 }
215
216 static void paintCrashedPage(QPainter* painter, const QRectF& rect)
217 {
218     painter->fillRect(rect, Qt::gray);
219     painter->drawText(rect, Qt::AlignCenter, QLatin1String(":("));
220 }
221
222 void QDesktopWebView::keyPressEvent(QKeyEvent* event)
223 {
224     this->event(event);
225 }
226
227 void QDesktopWebView::keyReleaseEvent(QKeyEvent* event)
228 {
229     this->event(event);
230 }
231
232 void QDesktopWebView::inputMethodEvent(QInputMethodEvent* event)
233 {
234     this->event(event);
235 }
236
237 void QDesktopWebView::focusInEvent(QFocusEvent* event)
238 {
239     this->event(event);
240 }
241
242 void QDesktopWebView::focusOutEvent(QFocusEvent* event)
243 {
244     this->event(event);
245 }
246
247 void QDesktopWebView::mousePressEvent(QGraphicsSceneMouseEvent* event)
248 {
249     this->event(event);
250 }
251
252 void QDesktopWebView::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
253 {
254     this->event(event);
255 }
256
257 void QDesktopWebView::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
258 {
259     this->event(event);
260 }
261
262 void QDesktopWebView::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
263 {
264     this->event(event);
265 }
266
267 void QDesktopWebView::wheelEvent(QWheelEvent* event)
268 {
269     // FIXME: for some reason, the scene graph delivers QWheelEvent instead of QGraphicsSceneWheelEvent.
270     // We transform them in QGraphicsSceneWheelEvent for consistency. Otherwise the position would be complete magic.
271     // We shoud modify the scenegraph to get the correct type of events.
272     QGraphicsSceneWheelEvent graphicsEvent(QEvent::GraphicsSceneWheel);
273     graphicsEvent.setPos(event->pos());
274     graphicsEvent.setButtons(event->buttons());
275     graphicsEvent.setDelta(event->delta());
276     graphicsEvent.setModifiers(event->modifiers());
277     graphicsEvent.setOrientation(event->orientation());
278     graphicsEvent.setScenePos(mapToScene(event->pos()));
279     graphicsEvent.setScreenPos(event->globalPos());
280     this->event(&graphicsEvent);
281 }
282
283 void QDesktopWebView::touchEvent(QTouchEvent* event)
284 {
285     this->event(event);
286 }
287
288 void QDesktopWebView::hoverEnterEvent(QHoverEvent* event)
289 {
290     this->event(event);
291 }
292
293 void QDesktopWebView::hoverMoveEvent(QHoverEvent* event)
294 {
295     this->event(event);
296 }
297
298 void QDesktopWebView::hoverLeaveEvent(QHoverEvent* event)
299 {
300     this->event(event);
301 }
302
303 void QDesktopWebView::dragMoveEvent(QSGDragEvent* event)
304 {
305     this->event(event);
306 }
307
308 void QDesktopWebView::dragEnterEvent(QSGDragEvent* event)
309 {
310     this->event(event);
311 }
312
313 void QDesktopWebView::dragExitEvent(QSGDragEvent* event)
314 {
315     this->event(event);
316 }
317
318 void QDesktopWebView::dragDropEvent(QSGDragEvent* event)
319 {
320     this->event(event);
321 }
322
323 void QDesktopWebView::geometryChanged(const QRectF& newGeometry, const QRectF& oldGeometry)
324 {
325     QSGPaintedItem::geometryChanged(newGeometry, oldGeometry);
326     if (newGeometry.size() != oldGeometry.size())
327         d->page.setDrawingAreaSize(newGeometry.size().toSize());
328 }
329
330 void QDesktopWebView::paint(QPainter* painter)
331 {
332     const QRectF rect = boundingRect();
333     if (d->isCrashed) {
334         paintCrashedPage(painter, rect);
335         return;
336     }
337
338     d->page.paint(painter, rect.toAlignedRect());
339 }
340
341 bool QDesktopWebView::event(QEvent* ev)
342 {
343     if (d->page.handleEvent(ev))
344         return true;
345     return QSGItem::event(ev);
346 }
347
348 WKPageRef QDesktopWebView::pageRef() const
349 {
350     return d->page.pageRef();
351 }
352
353 void QDesktopWebViewPrivate::processDidCrash()
354 {
355     isCrashed = true;
356     q->update();
357 }
358
359 void QDesktopWebViewPrivate::didRelaunchProcess()
360 {
361     isCrashed = false;
362     q->update();
363 }
364
365 #include "moc_qdesktopwebview.cpp"