97a6ed0d866c20df3dbf780d1885e3e0aa6c73b5
[WebKit-https.git] / Source / WebKit2 / UIProcess / qt / QtWebPageProxy.cpp
1 /*
2  * Copyright (C) 2010, 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 "QtWebPageProxy.h"
23
24 #include "QtWebError.h"
25 #include "qwebdownloaditem.h"
26 #include "qwebdownloaditem_p.h"
27 #include "qwebpreferences.h"
28 #include "qwebpreferences_p.h"
29
30 #include "ClientImpl.h"
31 #include "DownloadProxy.h"
32 #include "DrawingAreaProxyImpl.h"
33 #include "qwkhistory.h"
34 #include "qwkhistory_p.h"
35 #include "FindIndicator.h"
36 #include "LocalizedStrings.h"
37 #include "MutableArray.h"
38 #include "NativeWebKeyboardEvent.h"
39 #include "NativeWebMouseEvent.h"
40 #include "NativeWebWheelEvent.h"
41 #include "NotImplemented.h"
42 #include "QtPolicyInterface.h"
43 #include "QtViewInterface.h"
44 #include "QtViewportInteractionEngine.h"
45 #include "QtWebUndoCommand.h"
46 #include "WebBackForwardList.h"
47 #include "WebContext.h"
48 #include "WebContextMenuProxyQt.h"
49 #include "WebEditCommandProxy.h"
50 #include "WebEventFactoryQt.h"
51 #include "WebPopupMenuProxyQt.h"
52 #include "WKStringQt.h"
53 #include "WKURLQt.h"
54 #include <QApplication>
55 #include <QGraphicsSceneMouseEvent>
56 #include <QJSEngine>
57 #include <QMimeData>
58 #include <QTouchEvent>
59 #include <QUndoStack>
60 #include <QtDebug>
61 #include <WebCore/Cursor.h>
62 #include <WebCore/DragData.h>
63 #include <WebCore/FloatRect.h>
64 #include <WebCore/NotImplemented.h>
65 #include <WebCore/Region.h>
66 #include <WebKit2/WKFrame.h>
67 #include <WebKit2/WKPageGroup.h>
68 #include <WebKit2/WKRetainPtr.h>
69
70 using namespace WebKit;
71 using namespace WebCore;
72
73 RefPtr<WebContext> QtWebPageProxy::s_defaultContext;
74 RefPtr<QtDownloadManager> QtWebPageProxy::s_downloadManager;
75
76 unsigned QtWebPageProxy::s_defaultPageProxyCount = 0;
77
78 PassRefPtr<WebContext> QtWebPageProxy::defaultWKContext()
79 {
80     if (!s_defaultContext) {
81         s_defaultContext = WebContext::create(String());
82         setupContextInjectedBundleClient(toAPI(s_defaultContext.get()));
83         s_downloadManager = QtDownloadManager::create(s_defaultContext.get());
84     }
85     return s_defaultContext;
86 }
87
88 static inline Qt::DropAction dragOperationToDropAction(unsigned dragOperation)
89 {
90     Qt::DropAction result = Qt::IgnoreAction;
91     if (dragOperation & DragOperationCopy)
92         result = Qt::CopyAction;
93     else if (dragOperation & DragOperationMove)
94         result = Qt::MoveAction;
95     else if (dragOperation & DragOperationGeneric)
96         result = Qt::MoveAction;
97     else if (dragOperation & DragOperationLink)
98         result = Qt::LinkAction;
99     return result;
100 }
101
102 static inline Qt::DropActions dragOperationToDropActions(unsigned dragOperations)
103 {
104     Qt::DropActions result = Qt::IgnoreAction;
105     if (dragOperations & DragOperationCopy)
106         result |= Qt::CopyAction;
107     if (dragOperations & DragOperationMove)
108         result |= Qt::MoveAction;
109     if (dragOperations & DragOperationGeneric)
110         result |= Qt::MoveAction;
111     if (dragOperations & DragOperationLink)
112         result |= Qt::LinkAction;
113     return result;
114 }
115
116 WebCore::DragOperation dropActionToDragOperation(Qt::DropActions actions)
117 {
118     unsigned result = 0;
119     if (actions & Qt::CopyAction)
120         result |= DragOperationCopy;
121     if (actions & Qt::MoveAction)
122         result |= (DragOperationMove | DragOperationGeneric);
123     if (actions & Qt::LinkAction)
124         result |= DragOperationLink;
125     if (result == (DragOperationCopy | DragOperationMove | DragOperationGeneric | DragOperationLink))
126         result = DragOperationEvery;
127     return (DragOperation)result;
128 }
129
130 QtWebPageProxy::QtWebPageProxy(QtViewInterface* viewInterface, QtViewportInteractionEngine* viewportInteractionEngine, QtPolicyInterface* policyInterface, WKContextRef contextRef, WKPageGroupRef pageGroupRef)
131     : m_viewInterface(viewInterface)
132     , m_interactionEngine(viewportInteractionEngine)
133     , m_panGestureRecognizer(viewportInteractionEngine)
134     , m_pinchGestureRecognizer(viewportInteractionEngine)
135     , m_policyInterface(policyInterface)
136     , m_context(contextRef ? toImpl(contextRef) : defaultWKContext())
137     , m_undoStack(adoptPtr(new QUndoStack(this)))
138     , m_loadProgress(0)
139     , m_navigatorQtObjectEnabled(false)
140 {
141     ASSERT(viewInterface);
142     m_webPageProxy = m_context->createWebPage(this, toImpl(pageGroupRef));
143     m_history = QWKHistoryPrivate::createHistory(this, m_webPageProxy->backForwardList());
144     if (!contextRef)
145         s_defaultPageProxyCount++;
146 }
147
148 void QtWebPageProxy::init()
149 {
150     m_webPageProxy->initializeWebPage();
151
152     setupPageLoaderClient(this, m_webPageProxy.get());
153     setupPageUiClient(this, m_webPageProxy.get());
154
155     if (m_policyInterface)
156         setupPagePolicyClient(m_policyInterface, m_webPageProxy.get());
157 }
158
159 QtWebPageProxy::~QtWebPageProxy()
160 {
161     m_webPageProxy->close();
162     // The context is the default one and we're deleting the last QtWebPageProxy.
163     if (m_context == s_defaultContext) {
164         ASSERT(s_defaultPageProxyCount > 0);
165         s_defaultPageProxyCount--;
166         if (!s_defaultPageProxyCount) {
167             s_defaultContext.clear();
168             s_downloadManager.clear();
169         }
170     }
171     delete m_history;
172 }
173
174 bool QtWebPageProxy::handleEvent(QEvent* ev)
175 {
176     switch (ev->type()) {
177     case QEvent::MouseMove:
178         return handleMouseMoveEvent(reinterpret_cast<QMouseEvent*>(ev));
179     case QEvent::MouseButtonPress:
180         return handleMousePressEvent(reinterpret_cast<QMouseEvent*>(ev));
181     case QEvent::MouseButtonRelease:
182         return handleMouseReleaseEvent(reinterpret_cast<QMouseEvent*>(ev));
183     case QEvent::MouseButtonDblClick:
184         return handleMouseDoubleClickEvent(reinterpret_cast<QMouseEvent*>(ev));
185     case QEvent::Wheel:
186         return handleWheelEvent(reinterpret_cast<QWheelEvent*>(ev));
187     case QEvent::HoverLeave:
188         return handleHoverLeaveEvent(reinterpret_cast<QHoverEvent*>(ev));
189     case QEvent::HoverEnter: // Fall-through, for WebKit the distinction doesn't matter.
190     case QEvent::HoverMove:
191         return handleHoverMoveEvent(reinterpret_cast<QHoverEvent*>(ev));
192     case QEvent::DragEnter:
193         return handleDragEnterEvent(reinterpret_cast<QDragEnterEvent*>(ev));
194     case QEvent::DragLeave:
195         return handleDragLeaveEvent(reinterpret_cast<QDragLeaveEvent*>(ev));
196     case QEvent::DragMove:
197         return handleDragMoveEvent(reinterpret_cast<QDragMoveEvent*>(ev));
198     case QEvent::Drop:
199         return handleDropEvent(reinterpret_cast<QDropEvent*>(ev));
200     case QEvent::KeyPress:
201         return handleKeyPressEvent(reinterpret_cast<QKeyEvent*>(ev));
202     case QEvent::KeyRelease:
203         return handleKeyReleaseEvent(reinterpret_cast<QKeyEvent*>(ev));
204     case QEvent::FocusIn:
205         return handleFocusInEvent(reinterpret_cast<QFocusEvent*>(ev));
206     case QEvent::FocusOut:
207         return handleFocusOutEvent(reinterpret_cast<QFocusEvent*>(ev));
208     case QEvent::TouchBegin:
209     case QEvent::TouchEnd:
210     case QEvent::TouchUpdate:
211         touchEvent(static_cast<QTouchEvent*>(ev));
212         return true;
213     }
214
215     // FIXME: Move all common event handling here.
216     return false;
217 }
218
219 bool QtWebPageProxy::handleMouseMoveEvent(QMouseEvent* ev)
220 {
221     // For some reason mouse press results in mouse hover (which is
222     // converted to mouse move for WebKit). We ignore these hover
223     // events by comparing lastPos with newPos.
224     // NOTE: lastPos from the event always comes empty, so we work
225     // around that here.
226     static QPointF lastPos = QPointF();
227     if (lastPos == ev->pos())
228         return ev->isAccepted();
229     lastPos = ev->pos();
230
231     m_webPageProxy->handleMouseEvent(NativeWebMouseEvent(ev, /*eventClickCount=*/0));
232
233     return ev->isAccepted();
234 }
235
236 bool QtWebPageProxy::handleMousePressEvent(QMouseEvent* ev)
237 {
238     if (m_tripleClickTimer.isActive() && (ev->pos() - m_tripleClick).manhattanLength() < QApplication::startDragDistance()) {
239         m_webPageProxy->handleMouseEvent(NativeWebMouseEvent(ev, /*eventClickCount=*/3));
240         return ev->isAccepted();
241     }
242
243     m_webPageProxy->handleMouseEvent(NativeWebMouseEvent(ev, /*eventClickCount=*/1));
244     return ev->isAccepted();
245 }
246
247 bool QtWebPageProxy::handleMouseReleaseEvent(QMouseEvent* ev)
248 {
249     m_webPageProxy->handleMouseEvent(NativeWebMouseEvent(ev, /*eventClickCount=*/0));
250     return ev->isAccepted();
251 }
252
253 bool QtWebPageProxy::handleMouseDoubleClickEvent(QMouseEvent* ev)
254 {
255     m_webPageProxy->handleMouseEvent(NativeWebMouseEvent(ev, /*eventClickCount=*/2));
256
257     m_tripleClickTimer.start(QApplication::doubleClickInterval(), this);
258     m_tripleClick = ev->localPos().toPoint();
259     return ev->isAccepted();
260 }
261
262 bool QtWebPageProxy::handleWheelEvent(QWheelEvent* ev)
263 {
264     m_webPageProxy->handleWheelEvent(NativeWebWheelEvent(ev));
265     return ev->isAccepted();
266 }
267
268 bool QtWebPageProxy::handleHoverLeaveEvent(QHoverEvent* ev)
269 {
270     // To get the correct behavior of mouseout, we need to turn the Leave event of our webview into a mouse move
271     // to a very far region.
272     QHoverEvent fakeEvent(QEvent::HoverMove, QPoint(INT_MIN, INT_MIN), ev->oldPos());
273     return handleHoverMoveEvent(&fakeEvent);
274 }
275
276 bool QtWebPageProxy::handleHoverMoveEvent(QHoverEvent* ev)
277 {
278     QMouseEvent me(QEvent::MouseMove, ev->pos(), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
279     me.setAccepted(ev->isAccepted());
280
281     return handleMouseMoveEvent(&me);
282 }
283
284 bool QtWebPageProxy::handleDragEnterEvent(QDragEnterEvent* ev)
285 {
286     m_webPageProxy->resetDragOperation();
287     // FIXME: Should not use QCursor::pos()
288     DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), dropActionToDragOperation(ev->possibleActions()));
289     m_webPageProxy->dragEntered(&dragData);
290     ev->acceptProposedAction();
291     return true;
292 }
293
294 bool QtWebPageProxy::handleDragLeaveEvent(QDragLeaveEvent* ev)
295 {
296     bool accepted = ev->isAccepted();
297
298     // FIXME: Should not use QCursor::pos()
299     DragData dragData(0, IntPoint(), QCursor::pos(), DragOperationNone);
300     m_webPageProxy->dragExited(&dragData);
301     m_webPageProxy->resetDragOperation();
302
303     ev->setAccepted(accepted);
304     return accepted;
305 }
306
307 bool QtWebPageProxy::handleDragMoveEvent(QDragMoveEvent* ev)
308 {
309     bool accepted = ev->isAccepted();
310
311     // FIXME: Should not use QCursor::pos()
312     DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), dropActionToDragOperation(ev->possibleActions()));
313     m_webPageProxy->dragUpdated(&dragData);
314     ev->setDropAction(dragOperationToDropAction(m_webPageProxy->dragSession().operation));
315     if (m_webPageProxy->dragSession().operation != DragOperationNone)
316         ev->accept();
317
318     ev->setAccepted(accepted);
319     return accepted;
320 }
321
322 bool QtWebPageProxy::handleDropEvent(QDropEvent* ev)
323 {
324     bool accepted = ev->isAccepted();
325
326     // FIXME: Should not use QCursor::pos()
327     DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), dropActionToDragOperation(ev->possibleActions()));
328     SandboxExtension::Handle handle;
329     m_webPageProxy->performDrag(&dragData, String(), handle);
330     ev->setDropAction(dragOperationToDropAction(m_webPageProxy->dragSession().operation));
331     ev->accept();
332
333     ev->setAccepted(accepted);
334     return accepted;
335 }
336
337 void QtWebPageProxy::timerEvent(QTimerEvent* ev)
338 {
339     int timerId = ev->timerId();
340     if (timerId == m_tripleClickTimer.timerId())
341         m_tripleClickTimer.stop();
342     else
343         QObject::timerEvent(ev);
344 }
345
346 bool QtWebPageProxy::handleKeyPressEvent(QKeyEvent* ev)
347 {
348     m_webPageProxy->handleKeyboardEvent(NativeWebKeyboardEvent(ev));
349     return true;
350 }
351
352 bool QtWebPageProxy::handleKeyReleaseEvent(QKeyEvent* ev)
353 {
354     m_webPageProxy->handleKeyboardEvent(NativeWebKeyboardEvent(ev));
355     return true;
356 }
357
358 bool QtWebPageProxy::handleFocusInEvent(QFocusEvent*)
359 {
360     m_webPageProxy->viewStateDidChange(WebPageProxy::ViewIsFocused | WebPageProxy::ViewWindowIsActive);
361     return true;
362 }
363
364 bool QtWebPageProxy::handleFocusOutEvent(QFocusEvent*)
365 {
366     m_webPageProxy->viewStateDidChange(WebPageProxy::ViewIsFocused | WebPageProxy::ViewWindowIsActive);
367     return true;
368 }
369
370 void QtWebPageProxy::setCursor(const WebCore::Cursor& cursor)
371 {
372     m_viewInterface->didChangeCursor(*cursor.platformCursor());
373 }
374
375 void QtWebPageProxy::setCursorHiddenUntilMouseMoves(bool hiddenUntilMouseMoves)
376 {
377     notImplemented();
378 }
379
380 void QtWebPageProxy::setViewNeedsDisplay(const WebCore::IntRect& rect)
381 {
382     m_viewInterface->setViewNeedsDisplay(QRect(rect));
383 }
384
385 void QtWebPageProxy::displayView()
386 {
387     // FIXME: Implement.
388 }
389
390 void QtWebPageProxy::scrollView(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset)
391 {
392     // FIXME: Implement.
393 }
394
395 WebCore::IntSize QtWebPageProxy::viewSize()
396 {
397     return WebCore::IntSize(m_viewInterface->drawingAreaSize());
398 }
399
400 bool QtWebPageProxy::isViewWindowActive()
401 {
402     return m_viewInterface->isActive();
403 }
404
405 bool QtWebPageProxy::isViewFocused()
406 {
407     return m_viewInterface->hasFocus();
408 }
409
410 bool QtWebPageProxy::isViewVisible()
411 {
412     return m_viewInterface->isVisible();
413 }
414
415 bool QtWebPageProxy::isViewInWindow()
416 {
417     // FIXME: Implement.
418     return true;
419 }
420
421 void QtWebPageProxy::enterAcceleratedCompositingMode(const LayerTreeContext&)
422 {
423     // FIXME: Implement.
424 }
425
426 void QtWebPageProxy::exitAcceleratedCompositingMode()
427 {
428     // FIXME: Implement.
429 }
430
431 void QtWebPageProxy::pageDidRequestScroll(const IntPoint& pos)
432 {
433     m_viewInterface->scrollPositionRequested(pos);
434 }
435
436 void QtWebPageProxy::didChangeContentsSize(const IntSize& newSize)
437 {
438     m_viewInterface->contentSizeChanged(QSize(newSize));
439 }
440
441 void QtWebPageProxy::toolTipChanged(const String&, const String& newTooltip)
442 {
443     m_viewInterface->didChangeToolTip(QString(newTooltip));
444 }
445
446 void QtWebPageProxy::registerEditCommand(PassRefPtr<WebEditCommandProxy> command, WebPageProxy::UndoOrRedo undoOrRedo)
447 {
448     if (undoOrRedo == WebPageProxy::Undo) {
449         const QtWebUndoCommand* webUndoCommand = static_cast<const QtWebUndoCommand*>(m_undoStack->command(m_undoStack->index()));
450         if (webUndoCommand && webUndoCommand->inUndoRedo())
451             return;
452         m_undoStack->push(new QtWebUndoCommand(command));
453     }
454 }
455
456 void QtWebPageProxy::clearAllEditCommands()
457 {
458     m_undoStack->clear();
459 }
460
461 bool QtWebPageProxy::canUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo)
462 {
463     if (undoOrRedo == WebPageProxy::Undo)
464         return m_undoStack->canUndo();
465     return m_undoStack->canRedo();
466 }
467
468 void QtWebPageProxy::executeUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo)
469 {
470     if (undoOrRedo == WebPageProxy::Undo)
471         m_undoStack->undo();
472     else
473         m_undoStack->redo();
474 }
475
476 FloatRect QtWebPageProxy::convertToDeviceSpace(const FloatRect& rect)
477 {
478     return rect;
479 }
480
481 IntPoint QtWebPageProxy::screenToWindow(const IntPoint& point)
482 {
483     return point;
484 }
485
486 IntRect QtWebPageProxy::windowToScreen(const IntRect& rect)
487 {
488     return rect;
489 }
490
491 FloatRect QtWebPageProxy::convertToUserSpace(const FloatRect& rect)
492 {
493     return rect;
494 }
495
496 void QtWebPageProxy::selectionChanged(bool, bool, bool, bool)
497 {
498 }
499
500 void QtWebPageProxy::doneWithKeyEvent(const NativeWebKeyboardEvent&, bool)
501 {
502 }
503
504 PassRefPtr<WebPopupMenuProxy> QtWebPageProxy::createPopupMenuProxy(WebPageProxy*)
505 {
506     return WebPopupMenuProxyQt::create();
507 }
508
509 PassRefPtr<WebContextMenuProxy> QtWebPageProxy::createContextMenuProxy(WebPageProxy*)
510 {
511     return WebContextMenuProxyQt::create(m_webPageProxy.get(), m_viewInterface);
512 }
513
514 void QtWebPageProxy::setFindIndicator(PassRefPtr<FindIndicator>, bool fadeOut)
515 {
516 }
517
518 void QtWebPageProxy::didCommitLoadForMainFrame(bool useCustomRepresentation)
519 {
520 }
521
522 void QtWebPageProxy::didFinishLoadingDataForCustomRepresentation(const String& suggestedFilename, const CoreIPC::DataReference&)
523 {
524 }
525
526 void QtWebPageProxy::flashBackingStoreUpdates(const Vector<IntRect>&)
527 {
528     notImplemented();
529 }
530
531 WKPageRef QtWebPageProxy::pageRef() const
532 {
533     return toAPI(m_webPageProxy.get());;
534 }
535
536 void QtWebPageProxy::didFindZoomableArea(const IntPoint& target, const IntRect& area)
537 {
538     m_viewInterface->didFindZoomableArea(QPoint(target), QRect(area));
539 }
540
541 void QtWebPageProxy::didReceiveMessageFromNavigatorQtObject(const String& message)
542 {
543     QVariantMap variantMap;
544     variantMap.insert(QLatin1String("data"), QString(message));
545     variantMap.insert(QLatin1String("origin"), url());
546     emit receivedMessageFromNavigatorQtObject(variantMap);
547 }
548
549 void QtWebPageProxy::didChangeUrl(const QUrl& url)
550 {
551     m_viewInterface->didChangeUrl(url);
552 }
553
554 void QtWebPageProxy::didChangeTitle(const QString& newTitle)
555 {
556     m_viewInterface->didChangeTitle(newTitle);
557 }
558
559 void QtWebPageProxy::loadDidBegin()
560 {
561     m_viewInterface->loadDidBegin();
562 }
563
564 void QtWebPageProxy::loadDidCommit()
565 {
566     m_viewInterface->loadDidCommit();
567 }
568
569 void QtWebPageProxy::loadDidSucceed()
570 {
571     m_viewInterface->loadDidSucceed();
572 }
573
574 void QtWebPageProxy::loadDidFail(const QtWebError& error)
575 {
576     m_viewInterface->loadDidFail(error);
577 }
578
579 void QtWebPageProxy::didChangeLoadProgress(int newLoadProgress)
580 {
581     m_loadProgress = newLoadProgress;
582     m_viewInterface->didChangeLoadProgress(newLoadProgress);
583 }
584
585 void QtWebPageProxy::paint(QPainter* painter, const QRect& area)
586 {
587     if (m_webPageProxy->isValid())
588         paintContent(painter, area);
589     else
590         painter->fillRect(area, Qt::white);
591 }
592
593 bool QtWebPageProxy::canGoBack() const
594 {
595     return m_webPageProxy->canGoBack();
596 }
597
598 void QtWebPageProxy::goBack()
599 {
600     m_webPageProxy->goBack();
601 }
602
603 bool QtWebPageProxy::canGoForward() const
604 {
605     return m_webPageProxy->canGoForward();
606 }
607
608 void QtWebPageProxy::goForward()
609 {
610     m_webPageProxy->goForward();
611 }
612
613 bool QtWebPageProxy::canStop() const
614 {
615     RefPtr<WebKit::WebFrameProxy> mainFrame = m_webPageProxy->mainFrame();
616     return mainFrame && !(WebFrameProxy::LoadStateFinished == mainFrame->loadState());
617 }
618
619 void QtWebPageProxy::stop()
620 {
621     m_webPageProxy->stopLoading();
622 }
623
624 bool QtWebPageProxy::canReload() const
625 {
626     RefPtr<WebKit::WebFrameProxy> mainFrame = m_webPageProxy->mainFrame();
627     if (mainFrame)
628         return (WebFrameProxy::LoadStateFinished == mainFrame->loadState());
629     return m_webPageProxy->backForwardList()->currentItem();
630 }
631
632 void QtWebPageProxy::reload()
633 {
634     m_webPageProxy->reload(/* reloadFromOrigin */ true);
635 }
636
637 void QtWebPageProxy::navigationStateChanged()
638 {
639     emit updateNavigationState();
640 }
641
642 void QtWebPageProxy::didRelaunchProcess()
643 {
644     updateNavigationState();
645     m_viewInterface->didRelaunchProcess();
646     setDrawingAreaSize(m_viewInterface->drawingAreaSize());
647 }
648
649 void QtWebPageProxy::processDidCrash()
650 {
651     updateNavigationState();
652     m_panGestureRecognizer.reset();
653     m_pinchGestureRecognizer.reset();
654     m_viewInterface->processDidCrash();
655 }
656
657 QWebPreferences* QtWebPageProxy::preferences() const
658 {
659     if (!m_preferences)
660         m_preferences = adoptPtr(QWebPreferencesPrivate::createPreferences(const_cast<QtWebPageProxy*>(this)));
661     return m_preferences.get();
662 }
663
664 void QtWebPageProxy::setCustomUserAgent(const QString& userAgent)
665 {
666     WKRetainPtr<WKStringRef> wkUserAgent(WKStringCreateWithQString(userAgent));
667     WKPageSetCustomUserAgent(pageRef(), wkUserAgent.get());
668 }
669
670 QString QtWebPageProxy::customUserAgent() const
671 {
672     return WKStringCopyQString(WKPageCopyCustomUserAgent(pageRef()));
673 }
674
675 void QtWebPageProxy::setNavigatorQtObjectEnabled(bool enabled)
676 {
677     static String messageName("SetNavigatorQtObjectEnabled");
678
679     ASSERT(enabled != m_navigatorQtObjectEnabled);
680     // FIXME: Currently we have to keep this information in both processes and the setting is asynchronous.
681     m_navigatorQtObjectEnabled = enabled;
682     RefPtr<MutableArray> body = MutableArray::create();
683     body->append(m_webPageProxy.get());
684     RefPtr<WebBoolean> webEnabled = WebBoolean::create(enabled);
685     body->append(webEnabled.get());
686     m_context->postMessageToInjectedBundle(messageName, body.get());
687 }
688
689 void QtWebPageProxy::postMessageToNavigatorQtObject(const QString& message)
690 {
691     static String messageName("MessageToNavigatorQtObject");
692
693     RefPtr<MutableArray> body = MutableArray::create();
694     body->append(m_webPageProxy.get());
695     RefPtr<WebString> contents = WebString::create(String(message));
696     body->append(contents.get());
697     m_context->postMessageToInjectedBundle(messageName, body.get());
698 }
699
700 void QtWebPageProxy::load(const QUrl& url)
701 {
702     WKRetainPtr<WKURLRef> wkurl(WKURLCreateWithQUrl(url));
703     WKPageLoadURL(pageRef(), wkurl.get());
704 }
705
706 QUrl QtWebPageProxy::url() const
707 {
708     WKRetainPtr<WKFrameRef> frame = WKPageGetMainFrame(pageRef());
709     if (!frame)
710         return QUrl();
711     return WKURLCopyQUrl(WKFrameCopyURL(frame.get()));
712 }
713
714 QString QtWebPageProxy::title() const
715 {
716     return WKStringCopyQString(WKPageCopyTitle(toAPI(m_webPageProxy.get())));
717 }
718
719 void QtWebPageProxy::setDrawingAreaSize(const QSize& size)
720 {
721     if (!m_webPageProxy->drawingArea())
722         return;
723     m_webPageProxy->drawingArea()->setSize(IntSize(size), IntSize());
724 }
725
726 qreal QtWebPageProxy::textZoomFactor() const
727 {
728     return WKPageGetTextZoomFactor(pageRef());
729 }
730
731 void QtWebPageProxy::setTextZoomFactor(qreal zoomFactor)
732 {
733     WKPageSetTextZoomFactor(pageRef(), zoomFactor);
734 }
735
736 qreal QtWebPageProxy::pageZoomFactor() const
737 {
738     return WKPageGetPageZoomFactor(pageRef());
739 }
740
741 void QtWebPageProxy::setPageZoomFactor(qreal zoomFactor)
742 {
743     WKPageSetPageZoomFactor(pageRef(), zoomFactor);
744 }
745
746 void QtWebPageProxy::setPageAndTextZoomFactors(qreal pageZoomFactor, qreal textZoomFactor)
747 {
748     WKPageSetPageAndTextZoomFactors(pageRef(), pageZoomFactor, textZoomFactor);
749 }
750
751 QWKHistory* QtWebPageProxy::history() const
752 {
753     return m_history;
754 }
755
756 void QtWebPageProxy::startDrag(const WebCore::DragData& dragData, PassRefPtr<ShareableBitmap> dragImage)
757 {
758     QImage dragQImage;
759     if (dragImage)
760         dragQImage = dragImage->createQImage();
761     else if (dragData.platformData() && dragData.platformData()->hasImage())
762         dragQImage = qvariant_cast<QImage>(dragData.platformData()->imageData());
763
764
765     DragOperation dragOperationMask = dragData.draggingSourceOperationMask();
766     QMimeData* mimeData = const_cast<QMimeData*>(dragData.platformData());
767     Qt::DropActions supportedDropActions = dragOperationToDropActions(dragOperationMask);
768
769     QPoint clientPosition;
770     QPoint globalPosition;
771     Qt::DropAction actualDropAction;
772
773     m_viewInterface->startDrag(supportedDropActions, dragQImage, mimeData,
774                                &clientPosition, &globalPosition, &actualDropAction);
775
776     m_webPageProxy->dragEnded(clientPosition, globalPosition, dropActionToDragOperation(actualDropAction));
777 }
778
779 void QtWebPageProxy::didChangeViewportProperties(const WebCore::ViewportArguments& args)
780 {
781     m_viewInterface->didChangeViewportProperties(args);
782 }
783
784 void QtWebPageProxy::handleDownloadRequest(DownloadProxy* download)
785 {
786     // This function is responsible for hooking up a DownloadProxy to our API layer
787     // by creating a QWebDownloadItem. It will then wait for the QWebDownloadItem to be
788     // ready (filled with the ResourceResponse information) so we can pass it through to
789     // our WebViews.
790     QWebDownloadItem* downloadItem = new QWebDownloadItem();
791     downloadItem->d->downloadProxy = download;
792
793     connect(downloadItem->d, SIGNAL(receivedResponse(QWebDownloadItem*)), this, SLOT(didReceiveDownloadResponse(QWebDownloadItem*)));
794     s_downloadManager->addDownload(download, downloadItem);
795 }
796
797 void QtWebPageProxy::didReceiveDownloadResponse(QWebDownloadItem* download)
798 {
799     // Now that our downloadItem has everything we need we can emit downloadRequested.
800     m_viewInterface->downloadRequested(download);
801 }
802
803 void QtWebPageProxy::paintContent(QPainter* painter, const QRect& area)
804 {
805     // FIXME: Do something with the unpainted region?
806     WebCore::Region unpaintedRegion;
807     static_cast<DrawingAreaProxyImpl*>(m_webPageProxy->drawingArea())->paint(painter, area, unpaintedRegion);
808 }
809
810 PassOwnPtr<DrawingAreaProxy> QtWebPageProxy::createDrawingAreaProxy()
811 {
812     return DrawingAreaProxyImpl::create(m_webPageProxy.get());
813 }
814
815 void QtWebPageProxy::renderToCurrentGLContext(const TransformationMatrix& transform, float opacity)
816 {
817     DrawingAreaProxy* drawingArea = m_webPageProxy->drawingArea();
818     if (drawingArea)
819         drawingArea->paintToCurrentGLContext(transform, opacity);
820 }
821
822 #if ENABLE(TOUCH_EVENTS)
823 void QtWebPageProxy::doneWithTouchEvent(const NativeWebTouchEvent& event, bool wasEventHandled)
824 {
825     if (!m_interactionEngine)
826         return;
827     if (wasEventHandled || event.type() == WebEvent::TouchCancel) {
828         m_panGestureRecognizer.reset();
829         m_pinchGestureRecognizer.reset();
830         return;
831     }
832
833     const QTouchEvent* ev = event.nativeEvent();
834
835     switch (ev->type()) {
836     case QEvent::TouchBegin:
837         ASSERT(!m_interactionEngine->panGestureActive());
838         ASSERT(!m_interactionEngine->pinchGestureActive());
839
840         // The interaction engine might still be animating kinetic scrolling or a scale animation
841         // such as double-tap to zoom or the bounce back effect. A touch stops the kinetic scrolling
842         // where as it does not stop the scale animation.
843         if (m_interactionEngine->scrollAnimationActive())
844             m_interactionEngine->interruptScrollAnimation();
845         break;
846     case QEvent::TouchUpdate:
847         // The scale animation can only be interrupted by a pinch gesture, which will then take over.
848         if (m_interactionEngine->scaleAnimationActive() && m_pinchGestureRecognizer.isRecognized())
849             m_interactionEngine->interruptScaleAnimation();
850         break;
851     default:
852         break;
853     }
854
855     // If the scale animation is active we don't pass the event to the recognizers. In the future
856     // we would want to queue the event here and repost then when the animation ends.
857     if (m_interactionEngine->scaleAnimationActive())
858         return;
859
860     // Convert the event timestamp from second to millisecond.
861     qint64 eventTimestampMillis = static_cast<qint64>(event.timestamp() * 1000);
862     m_panGestureRecognizer.recognize(ev, eventTimestampMillis);
863     m_pinchGestureRecognizer.recognize(ev);
864 }
865 #endif
866
867 void QtWebPageProxy::setVisibleContentRectAndScale(const QRectF& visibleContentRect, float scale)
868 {
869     QRect alignedVisibleContentRect = visibleContentRect.toAlignedRect();
870     m_webPageProxy->drawingArea()->setVisibleContentsRectAndScale(alignedVisibleContentRect, scale);
871
872     // FIXME: Once we support suspend and resume, this should be delayed until the page is active if the page is suspended.
873     m_webPageProxy->setFixedVisibleContentRect(alignedVisibleContentRect);
874 }
875
876 void QtWebPageProxy::setVisibleContentRectTrajectoryVector(const QPointF& trajectoryVector)
877 {
878     m_webPageProxy->drawingArea()->setVisibleContentRectTrajectoryVector(trajectoryVector);
879 }
880
881 void QtWebPageProxy::touchEvent(QTouchEvent* event)
882 {
883 #if ENABLE(TOUCH_EVENTS)
884     m_webPageProxy->handleTouchEvent(NativeWebTouchEvent(event));
885     event->accept();
886 #else
887     ASSERT_NOT_REACHED();
888     ev->ignore();
889 #endif
890 }
891
892 void QtWebPageProxy::findZoomableAreaForPoint(const QPoint& point)
893 {
894     m_webPageProxy->findZoomableAreaForPoint(point);
895 }
896
897 #include "moc_QtWebPageProxy.cpp"