[Qt][WK2] Move the C API callback setup out of QtWebPageProxy
[WebKit.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 "qwebpreferences_p.h"
26
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"
44 #include "WKURLQt.h"
45 #include <QApplication>
46 #include <QGraphicsSceneMouseEvent>
47 #include <QJSEngine>
48 #include <QMimeData>
49 #include <QTouchEvent>
50 #include <QUndoStack>
51 #include <QtDebug>
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>
59
60 using namespace WebKit;
61 using namespace WebCore;
62
63
64 RefPtr<WebContext> QtWebPageProxy::s_defaultContext;
65
66 unsigned QtWebPageProxy::s_defaultPageProxyCount = 0;
67
68 PassRefPtr<WebContext> QtWebPageProxy::defaultWKContext()
69 {
70     if (!s_defaultContext)
71         s_defaultContext = WebContext::create(String());
72     return s_defaultContext;
73 }
74
75 static inline Qt::DropActions dragOperationToDropActions(unsigned dragOperations)
76 {
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;
86     return result;
87 }
88
89 WebCore::DragOperation dropActionToDragOperation(Qt::DropActions actions)
90 {
91     unsigned result = 0;
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;
101 }
102
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())
107     , m_preferences(0)
108     , m_undoStack(adoptPtr(new QUndoStack(this)))
109     , m_loadProgress(0)
110 {
111     ASSERT(viewInterface);
112     m_webPageProxy = m_context->createWebPage(this, toImpl(pageGroupRef));
113     m_history = QWKHistoryPrivate::createHistory(this, m_webPageProxy->backForwardList());
114     if (!contextRef)
115         s_defaultPageProxyCount++;
116 }
117
118 void QtWebPageProxy::init()
119 {
120     m_webPageProxy->initializeWebPage();
121
122     setupPageLoaderClient(this, m_webPageProxy.get());
123     setupPageUiClient(this, m_webPageProxy.get());
124
125     if (m_policyInterface)
126         setupPagePolicyClient(m_policyInterface, m_webPageProxy.get());
127 }
128
129 QtWebPageProxy::~QtWebPageProxy()
130 {
131     m_webPageProxy->close();
132     // The context is the default one and we're deleting the last QtWebPageProxy.
133     if (m_context == s_defaultContext) {
134         ASSERT(s_defaultPageProxyCount > 0);
135         s_defaultPageProxyCount--;
136         if (!s_defaultPageProxyCount)
137             s_defaultContext.clear();
138     }
139     delete m_history;
140 }
141
142 bool QtWebPageProxy::handleEvent(QEvent* ev)
143 {
144     switch (ev->type()) {
145     case QEvent::KeyPress:
146         return handleKeyPressEvent(reinterpret_cast<QKeyEvent*>(ev));
147     case QEvent::KeyRelease:
148         return handleKeyReleaseEvent(reinterpret_cast<QKeyEvent*>(ev));
149     case QEvent::FocusIn:
150         return handleFocusInEvent(reinterpret_cast<QFocusEvent*>(ev));
151     case QEvent::FocusOut:
152         return handleFocusOutEvent(reinterpret_cast<QFocusEvent*>(ev));
153     }
154
155     // FIXME: Move all common event handling here.
156     return false;
157 }
158
159 bool QtWebPageProxy::handleKeyPressEvent(QKeyEvent* ev)
160 {
161     m_webPageProxy->handleKeyboardEvent(NativeWebKeyboardEvent(ev));
162     return true;
163 }
164
165 bool QtWebPageProxy::handleKeyReleaseEvent(QKeyEvent* ev)
166 {
167     m_webPageProxy->handleKeyboardEvent(NativeWebKeyboardEvent(ev));
168     return true;
169 }
170
171 bool QtWebPageProxy::handleFocusInEvent(QFocusEvent*)
172 {
173     m_webPageProxy->viewStateDidChange(WebPageProxy::ViewIsFocused | WebPageProxy::ViewWindowIsActive);
174     return true;
175 }
176
177 bool QtWebPageProxy::handleFocusOutEvent(QFocusEvent*)
178 {
179     m_webPageProxy->viewStateDidChange(WebPageProxy::ViewIsFocused | WebPageProxy::ViewWindowIsActive);
180     return true;
181 }
182
183 void QtWebPageProxy::setCursor(const WebCore::Cursor& cursor)
184 {
185     m_viewInterface->didChangeCursor(*cursor.platformCursor());
186 }
187
188 void QtWebPageProxy::setCursorHiddenUntilMouseMoves(bool hiddenUntilMouseMoves)
189 {
190     notImplemented();
191 }
192
193 void QtWebPageProxy::setViewNeedsDisplay(const WebCore::IntRect& rect)
194 {
195     m_viewInterface->setViewNeedsDisplay(QRect(rect));
196 }
197
198 void QtWebPageProxy::displayView()
199 {
200     // FIXME: Implement.
201 }
202
203 void QtWebPageProxy::scrollView(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset)
204 {
205     // FIXME: Implement.
206 }
207
208 WebCore::IntSize QtWebPageProxy::viewSize()
209 {
210     return WebCore::IntSize(m_viewInterface->drawingAreaSize());
211 }
212
213 bool QtWebPageProxy::isViewWindowActive()
214 {
215     return m_viewInterface->isActive();
216 }
217
218 bool QtWebPageProxy::isViewFocused()
219 {
220     return m_viewInterface->hasFocus();
221 }
222
223 bool QtWebPageProxy::isViewVisible()
224 {
225     return m_viewInterface->isVisible();
226 }
227
228 bool QtWebPageProxy::isViewInWindow()
229 {
230     // FIXME: Implement.
231     return true;
232 }
233
234 void QtWebPageProxy::enterAcceleratedCompositingMode(const LayerTreeContext&)
235 {
236     // FIXME: Implement.
237 }
238
239 void QtWebPageProxy::exitAcceleratedCompositingMode()
240 {
241     // FIXME: Implement.
242 }
243
244 void QtWebPageProxy::pageDidRequestScroll(const IntPoint& point)
245 {
246     emit scrollRequested(point.x(), point.y());
247 }
248
249 void QtWebPageProxy::didChangeContentsSize(const IntSize& newSize)
250 {
251     m_viewInterface->contentSizeChanged(QSize(newSize));
252 }
253
254 void QtWebPageProxy::toolTipChanged(const String&, const String& newTooltip)
255 {
256     m_viewInterface->didChangeToolTip(QString(newTooltip));
257 }
258
259 void QtWebPageProxy::registerEditCommand(PassRefPtr<WebEditCommandProxy> command, WebPageProxy::UndoOrRedo undoOrRedo)
260 {
261     if (undoOrRedo == WebPageProxy::Undo) {
262         const QtWebUndoCommand* webUndoCommand = static_cast<const QtWebUndoCommand*>(m_undoStack->command(m_undoStack->index()));
263         if (webUndoCommand && webUndoCommand->inUndoRedo())
264             return;
265         m_undoStack->push(new QtWebUndoCommand(command));
266     }
267 }
268
269 void QtWebPageProxy::clearAllEditCommands()
270 {
271     m_undoStack->clear();
272 }
273
274 bool QtWebPageProxy::canUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo)
275 {
276     if (undoOrRedo == WebPageProxy::Undo)
277         return m_undoStack->canUndo();
278     return m_undoStack->canRedo();
279 }
280
281 void QtWebPageProxy::executeUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo)
282 {
283     if (undoOrRedo == WebPageProxy::Undo)
284         m_undoStack->undo();
285     else
286         m_undoStack->redo();
287 }
288
289 FloatRect QtWebPageProxy::convertToDeviceSpace(const FloatRect& rect)
290 {
291     return rect;
292 }
293
294 IntPoint QtWebPageProxy::screenToWindow(const IntPoint& point)
295 {
296     return point;
297 }
298
299 IntRect QtWebPageProxy::windowToScreen(const IntRect& rect)
300 {
301     return rect;
302 }
303
304 FloatRect QtWebPageProxy::convertToUserSpace(const FloatRect& rect)
305 {
306     return rect;
307 }
308
309 void QtWebPageProxy::selectionChanged(bool, bool, bool, bool)
310 {
311 }
312
313 void QtWebPageProxy::doneWithKeyEvent(const NativeWebKeyboardEvent&, bool)
314 {
315 }
316
317 PassRefPtr<WebPopupMenuProxy> QtWebPageProxy::createPopupMenuProxy(WebPageProxy*)
318 {
319     return WebPopupMenuProxyQt::create();
320 }
321
322 PassRefPtr<WebContextMenuProxy> QtWebPageProxy::createContextMenuProxy(WebPageProxy*)
323 {
324     return WebContextMenuProxyQt::create(m_webPageProxy.get(), m_viewInterface);
325 }
326
327 void QtWebPageProxy::setFindIndicator(PassRefPtr<FindIndicator>, bool fadeOut)
328 {
329 }
330
331 void QtWebPageProxy::didCommitLoadForMainFrame(bool useCustomRepresentation)
332 {
333 }
334
335 void QtWebPageProxy::didFinishLoadingDataForCustomRepresentation(const String& suggestedFilename, const CoreIPC::DataReference&)
336 {
337 }
338
339 void QtWebPageProxy::flashBackingStoreUpdates(const Vector<IntRect>&)
340 {
341     notImplemented();
342 }
343
344 WKPageRef QtWebPageProxy::pageRef() const
345 {
346     return toAPI(m_webPageProxy.get());;
347 }
348
349 void QtWebPageProxy::didFindZoomableArea(const IntPoint& target, const IntRect& area)
350 {
351     m_viewInterface->didFindZoomableArea(QPoint(target), QRect(area));
352 }
353
354 void QtWebPageProxy::didChangeUrl(const QUrl& url)
355 {
356     m_viewInterface->didChangeUrl(url);
357 }
358
359 void QtWebPageProxy::didChangeTitle(const QString& newTitle)
360 {
361     m_viewInterface->didChangeTitle(newTitle);
362 }
363
364 void QtWebPageProxy::loadDidBegin()
365 {
366     m_viewInterface->loadDidBegin();
367 }
368
369 void QtWebPageProxy::loadDidCommit()
370 {
371     m_viewInterface->loadDidCommit();
372 }
373
374 void QtWebPageProxy::loadDidSucceed()
375 {
376     m_viewInterface->loadDidSucceed();
377 }
378
379 void QtWebPageProxy::loadDidFail(const QtWebError& error)
380 {
381     m_viewInterface->loadDidFail(error);
382 }
383
384 void QtWebPageProxy::didChangeLoadProgress(int newLoadProgress)
385 {
386     m_loadProgress = newLoadProgress;
387     m_viewInterface->didChangeLoadProgress(newLoadProgress);
388 }
389
390 void QtWebPageProxy::paint(QPainter* painter, const QRect& area)
391 {
392     if (m_webPageProxy->isValid())
393         paintContent(painter, area);
394     else
395         painter->fillRect(area, Qt::white);
396 }
397
398 bool QtWebPageProxy::canGoBack() const
399 {
400     return m_webPageProxy->canGoBack();
401 }
402
403 void QtWebPageProxy::goBack()
404 {
405     m_webPageProxy->goBack();
406 }
407
408 bool QtWebPageProxy::canGoForward() const
409 {
410     return m_webPageProxy->canGoForward();
411 }
412
413 void QtWebPageProxy::goForward()
414 {
415     m_webPageProxy->goForward();
416 }
417
418 bool QtWebPageProxy::canStop() const
419 {
420     RefPtr<WebKit::WebFrameProxy> mainFrame = m_webPageProxy->mainFrame();
421     return mainFrame && !(WebFrameProxy::LoadStateFinished == mainFrame->loadState());
422 }
423
424 void QtWebPageProxy::stop()
425 {
426     m_webPageProxy->stopLoading();
427 }
428
429 bool QtWebPageProxy::canReload() const
430 {
431     RefPtr<WebKit::WebFrameProxy> mainFrame = m_webPageProxy->mainFrame();
432     if (mainFrame)
433         return (WebFrameProxy::LoadStateFinished == mainFrame->loadState());
434     return m_webPageProxy->backForwardList()->currentItem();
435 }
436
437 void QtWebPageProxy::reload()
438 {
439     m_webPageProxy->reload(/* reloadFromOrigin */ true);
440 }
441
442 void QtWebPageProxy::navigationStateChanged()
443 {
444     emit updateNavigationState();
445 }
446
447 void QtWebPageProxy::didRelaunchProcess()
448 {
449     updateNavigationState();
450     m_viewInterface->didRelaunchProcess();
451     setDrawingAreaSize(m_viewInterface->drawingAreaSize());
452 }
453
454 void QtWebPageProxy::processDidCrash()
455 {
456     updateNavigationState();
457     m_viewInterface->processDidCrash();
458 }
459
460 QWebPreferences* QtWebPageProxy::preferences() const
461 {
462     if (!m_preferences) {
463         WKPageGroupRef pageGroupRef = WKPageGetPageGroup(pageRef());
464         m_preferences = QWebPreferencesPrivate::createPreferences(pageGroupRef);
465     }
466
467     return m_preferences;
468 }
469
470 void QtWebPageProxy::setCustomUserAgent(const QString& userAgent)
471 {
472     WKRetainPtr<WKStringRef> wkUserAgent(WKStringCreateWithQString(userAgent));
473     WKPageSetCustomUserAgent(pageRef(), wkUserAgent.get());
474 }
475
476 QString QtWebPageProxy::customUserAgent() const
477 {
478     return WKStringCopyQString(WKPageCopyCustomUserAgent(pageRef()));
479 }
480
481 void QtWebPageProxy::load(const QUrl& url)
482 {
483     WKRetainPtr<WKURLRef> wkurl(WKURLCreateWithQUrl(url));
484     WKPageLoadURL(pageRef(), wkurl.get());
485 }
486
487 QUrl QtWebPageProxy::url() const
488 {
489     WKRetainPtr<WKFrameRef> frame = WKPageGetMainFrame(pageRef());
490     if (!frame)
491         return QUrl();
492     return WKURLCopyQUrl(WKFrameCopyURL(frame.get()));
493 }
494
495 QString QtWebPageProxy::title() const
496 {
497     return WKStringCopyQString(WKPageCopyTitle(toAPI(m_webPageProxy.get())));
498 }
499
500 void QtWebPageProxy::setDrawingAreaSize(const QSize& size)
501 {
502     if (!m_webPageProxy->drawingArea())
503         return;
504     m_webPageProxy->drawingArea()->setSize(IntSize(size), IntSize());
505 }
506
507 qreal QtWebPageProxy::textZoomFactor() const
508 {
509     return WKPageGetTextZoomFactor(pageRef());
510 }
511
512 void QtWebPageProxy::setTextZoomFactor(qreal zoomFactor)
513 {
514     WKPageSetTextZoomFactor(pageRef(), zoomFactor);
515 }
516
517 qreal QtWebPageProxy::pageZoomFactor() const
518 {
519     return WKPageGetPageZoomFactor(pageRef());
520 }
521
522 void QtWebPageProxy::setPageZoomFactor(qreal zoomFactor)
523 {
524     WKPageSetPageZoomFactor(pageRef(), zoomFactor);
525 }
526
527 void QtWebPageProxy::setPageAndTextZoomFactors(qreal pageZoomFactor, qreal textZoomFactor)
528 {
529     WKPageSetPageAndTextZoomFactors(pageRef(), pageZoomFactor, textZoomFactor);
530 }
531
532 QWKHistory* QtWebPageProxy::history() const
533 {
534     return m_history;
535 }
536
537 void QtWebPageProxy::startDrag(const WebCore::DragData& dragData, PassRefPtr<ShareableBitmap> dragImage)
538 {
539     QImage dragQImage;
540     if (dragImage)
541         dragQImage = dragImage->createQImage();
542     else if (dragData.platformData() && dragData.platformData()->hasImage())
543         dragQImage = qvariant_cast<QImage>(dragData.platformData()->imageData());
544
545
546     DragOperation dragOperationMask = dragData.draggingSourceOperationMask();
547     QMimeData* mimeData = const_cast<QMimeData*>(dragData.platformData());
548     Qt::DropActions supportedDropActions = dragOperationToDropActions(dragOperationMask);
549
550     QPoint clientPosition;
551     QPoint globalPosition;
552     Qt::DropAction actualDropAction;
553
554     m_viewInterface->startDrag(supportedDropActions, dragQImage, mimeData,
555                                &clientPosition, &globalPosition, &actualDropAction);
556
557     m_webPageProxy->dragEnded(clientPosition, globalPosition, dropActionToDragOperation(actualDropAction));
558 }
559
560 void QtWebPageProxy::didChangeViewportProperties(const WebCore::ViewportArguments& args)
561 {
562     m_viewInterface->didChangeViewportProperties(args);
563 }
564
565 #include "moc_QtWebPageProxy.cpp"