2 * Copyright (C) 2010, 2011 Nokia Corporation and/or its subsidiary(-ies)
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.
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.
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.
22 #include "QtWebPageProxy.h"
24 #include "QtWebError.h"
25 #include "qwebpreferences_p.h"
27 #include "ClientImpl.h"
28 #include "qwkhistory.h"
29 #include "qwkhistory_p.h"
30 #include "FindIndicator.h"
31 #include "LocalizedStrings.h"
32 #include "NativeWebKeyboardEvent.h"
33 #include "NotImplemented.h"
34 #include "QtPolicyInterface.h"
35 #include "QtViewInterface.h"
36 #include "QtWebUndoCommand.h"
37 #include "WebBackForwardList.h"
38 #include "WebContext.h"
39 #include "WebContextMenuProxyQt.h"
40 #include "WebEditCommandProxy.h"
41 #include "WebEventFactoryQt.h"
42 #include "WebPopupMenuProxyQt.h"
43 #include "WKStringQt.h"
45 #include <QApplication>
46 #include <QGraphicsSceneMouseEvent>
49 #include <QTouchEvent>
52 #include <WebCore/Cursor.h>
53 #include <WebCore/DragData.h>
54 #include <WebCore/FloatRect.h>
55 #include <WebCore/NotImplemented.h>
56 #include <WebKit2/WKFrame.h>
57 #include <WebKit2/WKPageGroup.h>
58 #include <WebKit2/WKRetainPtr.h>
60 using namespace WebKit;
61 using namespace WebCore;
64 RefPtr<WebContext> QtWebPageProxy::s_defaultContext;
66 unsigned QtWebPageProxy::s_defaultPageProxyCount = 0;
68 PassRefPtr<WebContext> QtWebPageProxy::defaultWKContext()
70 if (!s_defaultContext)
71 s_defaultContext = WebContext::create(String());
72 return s_defaultContext;
75 static inline Qt::DropActions dragOperationToDropActions(unsigned dragOperations)
77 Qt::DropActions result = Qt::IgnoreAction;
78 if (dragOperations & DragOperationCopy)
79 result |= Qt::CopyAction;
80 if (dragOperations & DragOperationMove)
81 result |= Qt::MoveAction;
82 if (dragOperations & DragOperationGeneric)
83 result |= Qt::MoveAction;
84 if (dragOperations & DragOperationLink)
85 result |= Qt::LinkAction;
89 WebCore::DragOperation dropActionToDragOperation(Qt::DropActions actions)
92 if (actions & Qt::CopyAction)
93 result |= DragOperationCopy;
94 if (actions & Qt::MoveAction)
95 result |= (DragOperationMove | DragOperationGeneric);
96 if (actions & Qt::LinkAction)
97 result |= DragOperationLink;
98 if (result == (DragOperationCopy | DragOperationMove | DragOperationGeneric | DragOperationLink))
99 result = DragOperationEvery;
100 return (DragOperation)result;
103 QtWebPageProxy::QtWebPageProxy(QtViewInterface* viewInterface, QtPolicyInterface* policyInterface, WKContextRef contextRef, WKPageGroupRef pageGroupRef)
104 : m_viewInterface(viewInterface)
105 , m_policyInterface(policyInterface)
106 , m_context(contextRef ? toImpl(contextRef) : defaultWKContext())
108 , m_undoStack(adoptPtr(new QUndoStack(this)))
111 ASSERT(viewInterface);
112 m_webPageProxy = m_context->createWebPage(this, toImpl(pageGroupRef));
113 m_history = QWKHistoryPrivate::createHistory(this, m_webPageProxy->backForwardList());
115 s_defaultPageProxyCount++;
118 void QtWebPageProxy::init()
120 m_webPageProxy->initializeWebPage();
122 WKPageLoaderClient loadClient;
123 memset(&loadClient, 0, sizeof(WKPageLoaderClient));
124 loadClient.version = kWKPageLoaderClientCurrentVersion;
125 loadClient.clientInfo = this;
126 loadClient.didStartProvisionalLoadForFrame = qt_wk_didStartProvisionalLoadForFrame;
127 loadClient.didFailProvisionalLoadWithErrorForFrame = qt_wk_didFailProvisionalLoadWithErrorForFrame;
128 loadClient.didCommitLoadForFrame = qt_wk_didCommitLoadForFrame;
129 loadClient.didFinishLoadForFrame = qt_wk_didFinishLoadForFrame;
130 loadClient.didFailLoadWithErrorForFrame = qt_wk_didFailLoadWithErrorForFrame;
131 loadClient.didSameDocumentNavigationForFrame = qt_wk_didSameDocumentNavigationForFrame;
132 loadClient.didReceiveTitleForFrame = qt_wk_didReceiveTitleForFrame;
133 loadClient.didStartProgress = qt_wk_didStartProgress;
134 loadClient.didChangeProgress = qt_wk_didChangeProgress;
135 loadClient.didFinishProgress = qt_wk_didFinishProgress;
136 WKPageSetPageLoaderClient(pageRef(), &loadClient);
138 WKPageUIClient uiClient;
139 memset(&uiClient, 0, sizeof(WKPageUIClient));
140 uiClient.version = kWKPageUIClientCurrentVersion;
141 uiClient.clientInfo = m_viewInterface;
142 uiClient.runJavaScriptAlert = qt_wk_runJavaScriptAlert;
143 uiClient.runJavaScriptConfirm = qt_wk_runJavaScriptConfirm;
144 uiClient.runJavaScriptPrompt = qt_wk_runJavaScriptPrompt;
145 uiClient.setStatusText = qt_wk_setStatusText;
146 uiClient.runOpenPanel = qt_wk_runOpenPanel;
147 uiClient.mouseDidMoveOverElement = qt_wk_mouseDidMoveOverElement;
148 WKPageSetPageUIClient(toAPI(m_webPageProxy.get()), &uiClient);
150 if (m_policyInterface) {
151 WKPagePolicyClient policyClient;
152 memset(&policyClient, 0, sizeof(WKPagePolicyClient));
153 policyClient.version = kWKPagePolicyClientCurrentVersion;
154 policyClient.clientInfo = m_policyInterface;
155 policyClient.decidePolicyForNavigationAction = qt_wk_decidePolicyForNavigationAction;
156 policyClient.decidePolicyForResponse = qt_wk_decidePolicyForResponse;
157 WKPageSetPagePolicyClient(toAPI(m_webPageProxy.get()), &policyClient);
161 QtWebPageProxy::~QtWebPageProxy()
163 m_webPageProxy->close();
164 // The context is the default one and we're deleting the last QtWebPageProxy.
165 if (m_context == s_defaultContext) {
166 ASSERT(s_defaultPageProxyCount > 0);
167 s_defaultPageProxyCount--;
168 if (!s_defaultPageProxyCount)
169 s_defaultContext.clear();
174 bool QtWebPageProxy::handleEvent(QEvent* ev)
176 switch (ev->type()) {
177 case QEvent::KeyPress:
178 return handleKeyPressEvent(reinterpret_cast<QKeyEvent*>(ev));
179 case QEvent::KeyRelease:
180 return handleKeyReleaseEvent(reinterpret_cast<QKeyEvent*>(ev));
181 case QEvent::FocusIn:
182 return handleFocusInEvent(reinterpret_cast<QFocusEvent*>(ev));
183 case QEvent::FocusOut:
184 return handleFocusOutEvent(reinterpret_cast<QFocusEvent*>(ev));
187 // FIXME: Move all common event handling here.
191 bool QtWebPageProxy::handleKeyPressEvent(QKeyEvent* ev)
193 m_webPageProxy->handleKeyboardEvent(NativeWebKeyboardEvent(ev));
197 bool QtWebPageProxy::handleKeyReleaseEvent(QKeyEvent* ev)
199 m_webPageProxy->handleKeyboardEvent(NativeWebKeyboardEvent(ev));
203 bool QtWebPageProxy::handleFocusInEvent(QFocusEvent*)
205 m_webPageProxy->viewStateDidChange(WebPageProxy::ViewIsFocused | WebPageProxy::ViewWindowIsActive);
209 bool QtWebPageProxy::handleFocusOutEvent(QFocusEvent*)
211 m_webPageProxy->viewStateDidChange(WebPageProxy::ViewIsFocused | WebPageProxy::ViewWindowIsActive);
215 void QtWebPageProxy::setCursor(const WebCore::Cursor& cursor)
217 m_viewInterface->didChangeCursor(*cursor.platformCursor());
220 void QtWebPageProxy::setCursorHiddenUntilMouseMoves(bool hiddenUntilMouseMoves)
225 void QtWebPageProxy::setViewNeedsDisplay(const WebCore::IntRect& rect)
227 m_viewInterface->setViewNeedsDisplay(QRect(rect));
230 void QtWebPageProxy::displayView()
235 void QtWebPageProxy::scrollView(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset)
240 WebCore::IntSize QtWebPageProxy::viewSize()
242 return WebCore::IntSize(m_viewInterface->drawingAreaSize());
245 bool QtWebPageProxy::isViewWindowActive()
247 return m_viewInterface->isActive();
250 bool QtWebPageProxy::isViewFocused()
252 return m_viewInterface->hasFocus();
255 bool QtWebPageProxy::isViewVisible()
257 return m_viewInterface->isVisible();
260 bool QtWebPageProxy::isViewInWindow()
266 void QtWebPageProxy::enterAcceleratedCompositingMode(const LayerTreeContext&)
271 void QtWebPageProxy::exitAcceleratedCompositingMode()
276 void QtWebPageProxy::pageDidRequestScroll(const IntPoint& point)
278 emit scrollRequested(point.x(), point.y());
281 void QtWebPageProxy::didChangeContentsSize(const IntSize& newSize)
283 m_viewInterface->contentSizeChanged(QSize(newSize));
286 void QtWebPageProxy::toolTipChanged(const String&, const String& newTooltip)
288 m_viewInterface->didChangeToolTip(QString(newTooltip));
291 void QtWebPageProxy::registerEditCommand(PassRefPtr<WebEditCommandProxy> command, WebPageProxy::UndoOrRedo undoOrRedo)
293 if (undoOrRedo == WebPageProxy::Undo) {
294 const QtWebUndoCommand* webUndoCommand = static_cast<const QtWebUndoCommand*>(m_undoStack->command(m_undoStack->index()));
295 if (webUndoCommand && webUndoCommand->inUndoRedo())
297 m_undoStack->push(new QtWebUndoCommand(command));
301 void QtWebPageProxy::clearAllEditCommands()
303 m_undoStack->clear();
306 bool QtWebPageProxy::canUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo)
308 if (undoOrRedo == WebPageProxy::Undo)
309 return m_undoStack->canUndo();
310 return m_undoStack->canRedo();
313 void QtWebPageProxy::executeUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo)
315 if (undoOrRedo == WebPageProxy::Undo)
321 FloatRect QtWebPageProxy::convertToDeviceSpace(const FloatRect& rect)
326 IntPoint QtWebPageProxy::screenToWindow(const IntPoint& point)
331 IntRect QtWebPageProxy::windowToScreen(const IntRect& rect)
336 FloatRect QtWebPageProxy::convertToUserSpace(const FloatRect& rect)
341 void QtWebPageProxy::selectionChanged(bool, bool, bool, bool)
345 void QtWebPageProxy::doneWithKeyEvent(const NativeWebKeyboardEvent&, bool)
349 PassRefPtr<WebPopupMenuProxy> QtWebPageProxy::createPopupMenuProxy(WebPageProxy*)
351 return WebPopupMenuProxyQt::create();
354 PassRefPtr<WebContextMenuProxy> QtWebPageProxy::createContextMenuProxy(WebPageProxy*)
356 return WebContextMenuProxyQt::create(m_webPageProxy.get(), m_viewInterface);
359 void QtWebPageProxy::setFindIndicator(PassRefPtr<FindIndicator>, bool fadeOut)
363 void QtWebPageProxy::didCommitLoadForMainFrame(bool useCustomRepresentation)
367 void QtWebPageProxy::didFinishLoadingDataForCustomRepresentation(const String& suggestedFilename, const CoreIPC::DataReference&)
371 void QtWebPageProxy::flashBackingStoreUpdates(const Vector<IntRect>&)
376 WKPageRef QtWebPageProxy::pageRef() const
378 return toAPI(m_webPageProxy.get());;
381 void QtWebPageProxy::didFindZoomableArea(const IntPoint& target, const IntRect& area)
383 m_viewInterface->didFindZoomableArea(QPoint(target), QRect(area));
386 void QtWebPageProxy::didChangeUrl(const QUrl& url)
388 m_viewInterface->didChangeUrl(url);
391 void QtWebPageProxy::didChangeTitle(const QString& newTitle)
393 m_viewInterface->didChangeTitle(newTitle);
396 void QtWebPageProxy::loadDidBegin()
398 m_viewInterface->loadDidBegin();
401 void QtWebPageProxy::loadDidCommit()
403 m_viewInterface->loadDidCommit();
406 void QtWebPageProxy::loadDidSucceed()
408 m_viewInterface->loadDidSucceed();
411 void QtWebPageProxy::loadDidFail(const QtWebError& error)
413 m_viewInterface->loadDidFail(error);
416 void QtWebPageProxy::didChangeLoadProgress(int newLoadProgress)
418 m_loadProgress = newLoadProgress;
419 m_viewInterface->didChangeLoadProgress(newLoadProgress);
422 void QtWebPageProxy::paint(QPainter* painter, const QRect& area)
424 if (m_webPageProxy->isValid())
425 paintContent(painter, area);
427 painter->fillRect(area, Qt::white);
430 bool QtWebPageProxy::canGoBack() const
432 return m_webPageProxy->canGoBack();
435 void QtWebPageProxy::goBack()
437 m_webPageProxy->goBack();
440 bool QtWebPageProxy::canGoForward() const
442 return m_webPageProxy->canGoForward();
445 void QtWebPageProxy::goForward()
447 m_webPageProxy->goForward();
450 bool QtWebPageProxy::canStop() const
452 RefPtr<WebKit::WebFrameProxy> mainFrame = m_webPageProxy->mainFrame();
453 return mainFrame && !(WebFrameProxy::LoadStateFinished == mainFrame->loadState());
456 void QtWebPageProxy::stop()
458 m_webPageProxy->stopLoading();
461 bool QtWebPageProxy::canReload() const
463 RefPtr<WebKit::WebFrameProxy> mainFrame = m_webPageProxy->mainFrame();
465 return (WebFrameProxy::LoadStateFinished == mainFrame->loadState());
466 return m_webPageProxy->backForwardList()->currentItem();
469 void QtWebPageProxy::reload()
471 m_webPageProxy->reload(/* reloadFromOrigin */ true);
474 void QtWebPageProxy::navigationStateChanged()
476 emit updateNavigationState();
479 void QtWebPageProxy::didRelaunchProcess()
481 updateNavigationState();
482 m_viewInterface->didRelaunchProcess();
483 setDrawingAreaSize(m_viewInterface->drawingAreaSize());
486 void QtWebPageProxy::processDidCrash()
488 updateNavigationState();
489 m_viewInterface->processDidCrash();
492 QWebPreferences* QtWebPageProxy::preferences() const
494 if (!m_preferences) {
495 WKPageGroupRef pageGroupRef = WKPageGetPageGroup(pageRef());
496 m_preferences = QWebPreferencesPrivate::createPreferences(pageGroupRef);
499 return m_preferences;
502 void QtWebPageProxy::setCustomUserAgent(const QString& userAgent)
504 WKRetainPtr<WKStringRef> wkUserAgent(WKStringCreateWithQString(userAgent));
505 WKPageSetCustomUserAgent(pageRef(), wkUserAgent.get());
508 QString QtWebPageProxy::customUserAgent() const
510 return WKStringCopyQString(WKPageCopyCustomUserAgent(pageRef()));
513 void QtWebPageProxy::load(const QUrl& url)
515 WKRetainPtr<WKURLRef> wkurl(WKURLCreateWithQUrl(url));
516 WKPageLoadURL(pageRef(), wkurl.get());
519 QUrl QtWebPageProxy::url() const
521 WKRetainPtr<WKFrameRef> frame = WKPageGetMainFrame(pageRef());
524 return WKURLCopyQUrl(WKFrameCopyURL(frame.get()));
527 QString QtWebPageProxy::title() const
529 return WKStringCopyQString(WKPageCopyTitle(toAPI(m_webPageProxy.get())));
532 void QtWebPageProxy::setDrawingAreaSize(const QSize& size)
534 if (!m_webPageProxy->drawingArea())
536 m_webPageProxy->drawingArea()->setSize(IntSize(size), IntSize());
539 qreal QtWebPageProxy::textZoomFactor() const
541 return WKPageGetTextZoomFactor(pageRef());
544 void QtWebPageProxy::setTextZoomFactor(qreal zoomFactor)
546 WKPageSetTextZoomFactor(pageRef(), zoomFactor);
549 qreal QtWebPageProxy::pageZoomFactor() const
551 return WKPageGetPageZoomFactor(pageRef());
554 void QtWebPageProxy::setPageZoomFactor(qreal zoomFactor)
556 WKPageSetPageZoomFactor(pageRef(), zoomFactor);
559 void QtWebPageProxy::setPageAndTextZoomFactors(qreal pageZoomFactor, qreal textZoomFactor)
561 WKPageSetPageAndTextZoomFactors(pageRef(), pageZoomFactor, textZoomFactor);
564 QWKHistory* QtWebPageProxy::history() const
569 void QtWebPageProxy::startDrag(const WebCore::DragData& dragData, PassRefPtr<ShareableBitmap> dragImage)
573 dragQImage = dragImage->createQImage();
574 else if (dragData.platformData() && dragData.platformData()->hasImage())
575 dragQImage = qvariant_cast<QImage>(dragData.platformData()->imageData());
578 DragOperation dragOperationMask = dragData.draggingSourceOperationMask();
579 QMimeData* mimeData = const_cast<QMimeData*>(dragData.platformData());
580 Qt::DropActions supportedDropActions = dragOperationToDropActions(dragOperationMask);
582 QPoint clientPosition;
583 QPoint globalPosition;
584 Qt::DropAction actualDropAction;
586 m_viewInterface->startDrag(supportedDropActions, dragQImage, mimeData,
587 &clientPosition, &globalPosition, &actualDropAction);
589 m_webPageProxy->dragEnded(clientPosition, globalPosition, dropActionToDragOperation(actualDropAction));
592 void QtWebPageProxy::didChangeViewportProperties(const WebCore::ViewportArguments& args)
594 m_viewInterface->didChangeViewportProperties(args);
597 #include "moc_QtWebPageProxy.cpp"