05c7b8b7f7bdec0d8862eed8c3a28a477cd6ad97
[WebKit-https.git] / Source / WebKit2 / UIProcess / API / qt / qwkpage.cpp
1 /*
2  * Copyright (C) 2010 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 "qwkpage.h"
23 #include "qwkpage_p.h"
24
25 #include "qwkpreferences_p.h"
26
27 #include "ChunkedUpdateDrawingAreaProxy.h"
28 #include "ClientImpl.h"
29 #include "qgraphicswkview.h"
30 #include "qwkcontext.h"
31 #include "qwkcontext_p.h"
32 #include "qwkhistory.h"
33 #include "qwkhistory_p.h"
34 #include "FindIndicator.h"
35 #include "LocalizedStrings.h"
36 #include "NativeWebKeyboardEvent.h"
37 #include "NotImplemented.h"
38 #include "TiledDrawingAreaProxy.h"
39 #include "WebContext.h"
40 #include "WebContextMenuProxyQt.h"
41 #include "WebEventFactoryQt.h"
42 #include "WebPopupMenuProxyQt.h"
43 #include "WKStringQt.h"
44 #include "WKURLQt.h"
45 #include "ViewportArguments.h"
46 #include <QAction>
47 #include <QApplication>
48 #include <QGraphicsSceneMouseEvent>
49 #include <QStyle>
50 #include <QTouchEvent>
51 #include <QtDebug>
52 #include <WebCore/Cursor.h>
53 #include <WebCore/FloatRect.h>
54 #include <WebCore/NotImplemented.h>
55 #include <WebKit2/WKFrame.h>
56 #include <WebKit2/WKPageGroup.h>
57 #include <WebKit2/WKRetainPtr.h>
58
59 using namespace WebKit;
60 using namespace WebCore;
61
62 static WebCore::ContextMenuAction contextMenuActionForWebAction(QWKPage::WebAction action)
63 {
64     switch (action) {
65     case QWKPage::OpenLink:
66         return WebCore::ContextMenuItemTagOpenLink;
67     case QWKPage::OpenLinkInNewWindow:
68         return WebCore::ContextMenuItemTagOpenLinkInNewWindow;
69     case QWKPage::CopyLinkToClipboard:
70         return WebCore::ContextMenuItemTagCopyLinkToClipboard;
71     case QWKPage::OpenImageInNewWindow:
72         return WebCore::ContextMenuItemTagOpenImageInNewWindow;
73     case QWKPage::Cut:
74         return WebCore::ContextMenuItemTagCut;
75     case QWKPage::Copy:
76         return WebCore::ContextMenuItemTagCopy;
77     case QWKPage::Paste:
78         return WebCore::ContextMenuItemTagPaste;
79     case QWKPage::SelectAll:
80         return WebCore::ContextMenuItemTagSelectAll;
81     default:
82         ASSERT(false);
83         break;
84     }
85     return WebCore::ContextMenuItemTagNoAction;
86 }
87
88 QWKPagePrivate::QWKPagePrivate(QWKPage* qq, QWKContext* c)
89     : q(qq)
90     , view(0)
91     , context(c)
92     , preferences(0)
93     , createNewPageFn(0)
94     , backingStoreType(QGraphicsWKView::Simple)
95     , isConnectedToEngine(true)
96 {
97     memset(actions, 0, sizeof(actions));
98     page = context->d->context->createWebPage(this, 0);
99     history = QWKHistoryPrivate::createHistory(page->backForwardList());
100 }
101
102 QWKPagePrivate::~QWKPagePrivate()
103 {
104     page->close();
105     delete history;
106 }
107
108 void QWKPagePrivate::init(QGraphicsItem* view, QGraphicsWKView::BackingStoreType backingStoreType)
109 {
110     this->view = view;
111     this->backingStoreType = backingStoreType;
112     page->initializeWebPage();
113 }
114
115 void QWKPagePrivate::setCursor(const WebCore::Cursor& cursor)
116 {
117 #ifndef QT_NO_CURSOR
118     emit q->cursorChanged(*cursor.platformCursor());
119 #endif
120 }
121
122 void QWKPagePrivate::setViewportArguments(const ViewportArguments& args)
123 {
124     viewportArguments = args;
125     emit q->viewportChangeRequested();
126 }
127
128 void QWKPagePrivate::takeFocus(bool direction)
129 {
130     emit q->focusNextPrevChild(direction);
131 }
132
133 PassOwnPtr<DrawingAreaProxy> QWKPagePrivate::createDrawingAreaProxy()
134 {
135     // FIXME: We should avoid this cast by decoupling the view from the page.
136     QGraphicsWKView* wkView = static_cast<QGraphicsWKView*>(view);
137
138 #if ENABLE(TILED_BACKING_STORE)
139     if (backingStoreType == QGraphicsWKView::Tiled)
140         return TiledDrawingAreaProxy::create(wkView, page.get());
141 #endif
142     return ChunkedUpdateDrawingAreaProxy::create(wkView, page.get());
143 }
144
145 void QWKPagePrivate::setViewNeedsDisplay(const WebCore::IntRect& rect)
146 {
147     view->update(QRect(rect));
148 }
149
150 void QWKPagePrivate::displayView()
151 {
152     // FIXME: Implement.
153 }
154
155 void QWKPagePrivate::scrollView(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset)
156 {
157     // FIXME: Implement.
158 }
159
160 WebCore::IntSize QWKPagePrivate::viewSize()
161 {
162     // FIXME: Implement.
163     return WebCore::IntSize();
164 }
165
166 bool QWKPagePrivate::isViewWindowActive()
167 {
168     return view && view->isActive();
169 }
170
171 bool QWKPagePrivate::isViewFocused()
172 {
173     return view && view->hasFocus();
174 }
175
176 bool QWKPagePrivate::isViewVisible()
177 {
178     return view && view->isVisible();
179 }
180
181 bool QWKPagePrivate::isViewInWindow()
182 {
183     // FIXME: Implement.
184     return true;
185 }
186
187 void QWKPagePrivate::enterAcceleratedCompositingMode(const LayerTreeContext&)
188 {
189     // FIXME: Implement.
190 }
191
192 void QWKPagePrivate::exitAcceleratedCompositingMode()
193 {
194     // FIXME: Implement.
195 }
196
197 void QWKPagePrivate::pageDidRequestScroll(const IntSize& delta)
198 {
199     emit q->scrollRequested(delta.width(), delta.height());
200 }
201
202 void QWKPagePrivate::didChangeContentsSize(const IntSize& newSize)
203 {
204     emit q->contentsSizeChanged(QSize(newSize));
205 }
206
207 void QWKPagePrivate::toolTipChanged(const String&, const String& newTooltip)
208 {
209     emit q->statusBarMessage(QString(newTooltip));
210 }
211
212 void QWKPagePrivate::registerEditCommand(PassRefPtr<WebEditCommandProxy>, WebPageProxy::UndoOrRedo)
213 {
214 }
215
216 void QWKPagePrivate::clearAllEditCommands()
217 {
218 }
219
220 FloatRect QWKPagePrivate::convertToDeviceSpace(const FloatRect& rect)
221 {
222     return rect;
223 }
224
225 FloatRect QWKPagePrivate::convertToUserSpace(const FloatRect& rect)
226 {
227     return rect;
228 }
229
230 void QWKPagePrivate::selectionChanged(bool, bool, bool, bool)
231 {
232 }
233
234 void QWKPagePrivate::doneWithKeyEvent(const NativeWebKeyboardEvent&, bool)
235 {
236 }
237
238 PassRefPtr<WebPopupMenuProxy> QWKPagePrivate::createPopupMenuProxy(WebPageProxy*)
239 {
240     return WebPopupMenuProxyQt::create();
241 }
242
243 PassRefPtr<WebContextMenuProxy> QWKPagePrivate::createContextMenuProxy(WebPageProxy*)
244 {
245     return WebContextMenuProxyQt::create(q);
246 }
247
248 void QWKPagePrivate::setFindIndicator(PassRefPtr<FindIndicator>, bool fadeOut)
249 {
250 }
251
252 void QWKPagePrivate::didCommitLoadForMainFrame(bool useCustomRepresentation)
253 {
254 }
255
256 void QWKPagePrivate::didFinishLoadingDataForCustomRepresentation(const String& suggestedFilename, const CoreIPC::DataReference&)
257 {
258 }
259
260 void QWKPagePrivate::flashBackingStoreUpdates(const Vector<IntRect>&)
261 {
262     notImplemented();
263 }
264
265 void QWKPagePrivate::paint(QPainter* painter, QRect area)
266 {
267     if (page->isValid() && page->drawingArea())
268         page->drawingArea()->paint(IntRect(area), painter);
269     else
270         painter->fillRect(area, Qt::white);
271 }
272
273 void QWKPagePrivate::keyPressEvent(QKeyEvent* ev)
274 {
275     page->handleKeyboardEvent(NativeWebKeyboardEvent(ev));
276 }
277
278 void QWKPagePrivate::keyReleaseEvent(QKeyEvent* ev)
279 {
280     page->handleKeyboardEvent(NativeWebKeyboardEvent(ev));
281 }
282
283 void QWKPagePrivate::mouseMoveEvent(QGraphicsSceneMouseEvent* ev)
284 {
285     // For some reason mouse press results in mouse hover (which is
286     // converted to mouse move for WebKit). We ignore these hover
287     // events by comparing lastPos with newPos.
288     // NOTE: lastPos from the event always comes empty, so we work
289     // around that here.
290     static QPointF lastPos = QPointF();
291     if (lastPos == ev->pos())
292         return;
293     lastPos = ev->pos();
294
295     WebMouseEvent mouseEvent = WebEventFactory::createWebMouseEvent(ev, 0);
296     page->handleMouseEvent(mouseEvent);
297 }
298
299 void QWKPagePrivate::mousePressEvent(QGraphicsSceneMouseEvent* ev)
300 {
301     if (tripleClickTimer.isActive() && (ev->pos() - tripleClick).manhattanLength() < QApplication::startDragDistance()) {
302         WebMouseEvent mouseEvent = WebEventFactory::createWebMouseEvent(ev, 3);
303         page->handleMouseEvent(mouseEvent);
304         return;
305     }
306
307     WebMouseEvent mouseEvent = WebEventFactory::createWebMouseEvent(ev, 1);
308     page->handleMouseEvent(mouseEvent);
309 }
310
311 void QWKPagePrivate::mouseReleaseEvent(QGraphicsSceneMouseEvent* ev)
312 {
313     WebMouseEvent mouseEvent = WebEventFactory::createWebMouseEvent(ev, 0);
314     page->handleMouseEvent(mouseEvent);
315 }
316
317 void QWKPagePrivate::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* ev)
318 {
319     WebMouseEvent mouseEvent = WebEventFactory::createWebMouseEvent(ev, 2);
320     page->handleMouseEvent(mouseEvent);
321
322     tripleClickTimer.start(QApplication::doubleClickInterval(), q);
323     tripleClick = ev->pos().toPoint();
324 }
325
326 void QWKPagePrivate::wheelEvent(QGraphicsSceneWheelEvent* ev)
327 {
328     WebWheelEvent wheelEvent = WebEventFactory::createWebWheelEvent(ev);
329     page->handleWheelEvent(wheelEvent);
330 }
331
332 void QWKPagePrivate::updateAction(QWKPage::WebAction action)
333 {
334 #ifdef QT_NO_ACTION
335     Q_UNUSED(action)
336 #else
337     QAction* a = actions[action];
338     if (!a)
339         return;
340
341     RefPtr<WebKit::WebFrameProxy> mainFrame = page->mainFrame();
342     if (!mainFrame)
343         return;
344
345     bool enabled = a->isEnabled();
346     bool checked = a->isChecked();
347
348     switch (action) {
349     case QWKPage::Back:
350         enabled = page->canGoBack();
351         break;
352     case QWKPage::Forward:
353         enabled = page->canGoForward();
354         break;
355     case QWKPage::Stop:
356         enabled = !(WebFrameProxy::LoadStateFinished == mainFrame->loadState());
357         break;
358     case QWKPage::Reload:
359         enabled = (WebFrameProxy::LoadStateFinished == mainFrame->loadState());
360         break;
361     default:
362         break;
363     }
364
365     a->setEnabled(enabled);
366
367     if (a->isCheckable())
368         a->setChecked(checked);
369 #endif // QT_NO_ACTION
370 }
371
372 void QWKPagePrivate::updateNavigationActions()
373 {
374     updateAction(QWKPage::Back);
375     updateAction(QWKPage::Forward);
376     updateAction(QWKPage::Stop);
377     updateAction(QWKPage::Reload);
378 }
379
380 #ifndef QT_NO_ACTION
381 void QWKPagePrivate::_q_webActionTriggered(bool checked)
382 {
383     QAction* a = qobject_cast<QAction*>(q->sender());
384     if (!a)
385         return;
386     QWKPage::WebAction action = static_cast<QWKPage::WebAction>(a->data().toInt());
387     q->triggerAction(action, checked);
388 }
389 #endif // QT_NO_ACTION
390
391 void QWKPagePrivate::touchEvent(QTouchEvent* event)
392 {
393 #if ENABLE(TOUCH_EVENTS)
394     WebTouchEvent touchEvent = WebEventFactory::createWebTouchEvent(event);
395     page->handleTouchEvent(touchEvent);
396 #else
397     event->ignore();
398 #endif
399 }
400
401 void QWKPagePrivate::didRelaunchProcess()
402 {
403     QGraphicsWKView* wkView = static_cast<QGraphicsWKView*>(view);
404     if (wkView)
405         q->setViewportSize(wkView->size().toSize());
406
407     isConnectedToEngine = true;
408     emit q->engineConnectionChanged(true);
409 }
410
411 void QWKPagePrivate::processDidCrash()
412 {
413     isConnectedToEngine = false;
414     emit q->engineConnectionChanged(false);
415 }
416
417 QWKPage::QWKPage(QWKContext* context)
418     : d(new QWKPagePrivate(this, context))
419 {
420     WKPageLoaderClient loadClient = {
421         0,      /* version */
422         this,   /* clientInfo */
423         qt_wk_didStartProvisionalLoadForFrame,
424         qt_wk_didReceiveServerRedirectForProvisionalLoadForFrame,
425         qt_wk_didFailProvisionalLoadWithErrorForFrame,
426         qt_wk_didCommitLoadForFrame,
427         qt_wk_didFinishDocumentLoadForFrame,
428         qt_wk_didFinishLoadForFrame,
429         qt_wk_didFailLoadWithErrorForFrame,
430         0, /* didSameDocumentNavigationForFrame */
431         qt_wk_didReceiveTitleForFrame,
432         qt_wk_didFirstLayoutForFrame,
433         qt_wk_didFirstVisuallyNonEmptyLayoutForFrame,
434         qt_wk_didRemoveFrameFromHierarchy,
435         0, /* didDisplayInsecureContentForFrame */
436         0, /* didRunInsecureContentForFrame */
437         0, /* canAuthenticateAgainstProtectionSpaceInFrame */
438         0, /* didReceiveAuthenticationChallengeInFrame */
439         qt_wk_didStartProgress,
440         qt_wk_didChangeProgress,
441         qt_wk_didFinishProgress,
442         qt_wk_didBecomeUnresponsive,
443         qt_wk_didBecomeResponsive,
444         0,  /* processDidCrash */
445         0,  /* didChangeBackForwardList */
446         0   /* shouldGoToBackForwardListItem */
447     };
448     WKPageSetPageLoaderClient(pageRef(), &loadClient);
449
450     WKPageUIClient uiClient = {
451         0,      /* version */
452         this,   /* clientInfo */
453         qt_wk_createNewPage,
454         qt_wk_showPage,
455         qt_wk_close,
456         qt_wk_runJavaScriptAlert,
457         0,  /* runJavaScriptConfirm */
458         0,  /* runJavaScriptPrompt */
459         0,  /* setStatusText */
460         0,  /* mouseDidMoveOverElement */
461         0,  /* missingPluginButtonClicked */
462         0,  /* didNotHandleKeyEvent */
463         0,  /* toolbarsAreVisible */
464         0,  /* setToolbarsAreVisible */
465         0,  /* menuBarIsVisible */
466         0,  /* setMenuBarIsVisible */
467         0,  /* statusBarIsVisible */
468         0,  /* setStatusBarIsVisible */
469         0,  /* isResizable */
470         0,  /* setIsResizable */
471         0,  /* getWindowFrame */
472         0,  /* setWindowFrame */
473         0,  /* runBeforeUnloadConfirmPanel */
474         0,  /* didDraw */
475         0,  /* pageDidScroll */
476         0,  /* exceededDatabaseQuota */
477         0,  /* runOpenPanel */
478         0,  /* decidePolicyForGeolocationPermissionRequest */
479         0,  /* headerHeight */
480         0,  /* footerHeight */
481         0,  /* drawHeader */
482         0,  /* drawFooter */
483         0,  /* printFrame */
484         0,  /* runModal */
485         0   /* didCompleteRubberBandForMainFrame */
486     };
487     WKPageSetPageUIClient(pageRef(), &uiClient);
488 }
489
490 QWKPage::~QWKPage()
491 {
492     delete d;
493 }
494
495 QWKPage::ViewportAttributes::ViewportAttributes()
496     : d(0)
497     , m_initialScaleFactor(-1.0)
498     , m_minimumScaleFactor(-1.0)
499     , m_maximumScaleFactor(-1.0)
500     , m_devicePixelRatio(-1.0)
501     , m_isUserScalable(true)
502     , m_isValid(false)
503 {
504
505 }
506
507 QWKPage::ViewportAttributes::ViewportAttributes(const QWKPage::ViewportAttributes& other)
508     : d(other.d)
509     , m_initialScaleFactor(other.m_initialScaleFactor)
510     , m_minimumScaleFactor(other.m_minimumScaleFactor)
511     , m_maximumScaleFactor(other.m_maximumScaleFactor)
512     , m_devicePixelRatio(other.m_devicePixelRatio)
513     , m_isUserScalable(other.m_isUserScalable)
514     , m_isValid(other.m_isValid)
515     , m_size(other.m_size)
516 {
517
518 }
519
520 QWKPage::ViewportAttributes::~ViewportAttributes()
521 {
522
523 }
524
525 QWKPage::ViewportAttributes& QWKPage::ViewportAttributes::operator=(const QWKPage::ViewportAttributes& other)
526 {
527     if (this != &other) {
528         d = other.d;
529         m_initialScaleFactor = other.m_initialScaleFactor;
530         m_minimumScaleFactor = other.m_minimumScaleFactor;
531         m_maximumScaleFactor = other.m_maximumScaleFactor;
532         m_devicePixelRatio = other.m_devicePixelRatio;
533         m_isUserScalable = other.m_isUserScalable;
534         m_isValid = other.m_isValid;
535         m_size = other.m_size;
536     }
537
538     return *this;
539 }
540
541 QWKPage::ViewportAttributes QWKPage::viewportAttributesForSize(const QSize& availableSize) const
542 {
543     static int desktopWidth = 980;
544     static int deviceDPI = 160;
545
546     ViewportAttributes result;
547
548      if (availableSize.isEmpty())
549          return result; // Returns an invalid instance.
550
551     // FIXME: Add a way to get these data via the platform plugin and fall back
552     // to the size of the view.
553     int deviceWidth = 480;
554     int deviceHeight = 864;
555
556     WebCore::ViewportAttributes conf = WebCore::computeViewportAttributes(d->viewportArguments, desktopWidth, deviceWidth, deviceHeight, deviceDPI, availableSize);
557
558     result.m_isValid = true;
559     result.m_size = conf.layoutSize;
560     result.m_initialScaleFactor = conf.initialScale;
561     result.m_minimumScaleFactor = conf.minimumScale;
562     result.m_maximumScaleFactor = conf.maximumScale;
563     result.m_devicePixelRatio = conf.devicePixelRatio;
564     result.m_isUserScalable = conf.userScalable;
565
566     return result;
567 }
568
569 void QWKPage::setActualVisibleContentsRect(const QRect& rect) const
570 {
571 #if ENABLE(TILED_BACKING_STORE)
572     d->page->setActualVisibleContentRect(rect);
573 #endif
574 }
575
576 void QWKPage::timerEvent(QTimerEvent* ev)
577 {
578     int timerId = ev->timerId();
579     if (timerId == d->tripleClickTimer.timerId())
580         d->tripleClickTimer.stop();
581     else
582         QObject::timerEvent(ev);
583 }
584
585 WKPageRef QWKPage::pageRef() const
586 {
587     return toAPI(d->page.get());
588 }
589
590 QWKContext* QWKPage::context() const
591 {
592     return d->context;
593 }
594
595 QWKPreferences* QWKPage::preferences() const
596 {
597     if (!d->preferences) {
598         WKPageGroupRef pageGroupRef = WKPageGetPageGroup(pageRef());
599         d->preferences = QWKPreferencesPrivate::createPreferences(pageGroupRef);
600     }
601
602     return d->preferences;
603 }
604
605 void QWKPage::setCreateNewPageFunction(CreateNewPageFn function)
606 {
607     d->createNewPageFn = function;
608 }
609
610 void QWKPage::setCustomUserAgent(const QString& userAgent)
611 {
612     WKRetainPtr<WKStringRef> wkUserAgent(WKStringCreateWithQString(userAgent));
613     WKPageSetCustomUserAgent(pageRef(), wkUserAgent.get());
614 }
615
616 QString QWKPage::customUserAgent() const
617 {
618     return WKStringCopyQString(WKPageCopyCustomUserAgent(pageRef()));
619 }
620
621 void QWKPage::load(const QUrl& url)
622 {
623     WKRetainPtr<WKURLRef> wkurl(WKURLCreateWithQUrl(url));
624     WKPageLoadURL(pageRef(), wkurl.get());
625 }
626
627 void QWKPage::setUrl(const QUrl& url)
628 {
629     load(url);
630 }
631
632 QUrl QWKPage::url() const
633 {
634     WKRetainPtr<WKFrameRef> frame = WKPageGetMainFrame(pageRef());
635     if (!frame)
636         return QUrl();
637     return WKURLCopyQUrl(WKFrameCopyURL(frame.get()));
638 }
639
640 QString QWKPage::title() const
641 {
642     return WKStringCopyQString(WKPageCopyTitle(pageRef()));
643 }
644
645 void QWKPage::setViewportSize(const QSize& size)
646 {
647     if (d->page->drawingArea())
648         d->page->drawingArea()->setSize(IntSize(size), IntSize());
649 }
650
651 qreal QWKPage::textZoomFactor() const
652 {
653     return WKPageGetTextZoomFactor(pageRef());
654 }
655
656 void QWKPage::setTextZoomFactor(qreal zoomFactor)
657 {
658     WKPageSetTextZoomFactor(pageRef(), zoomFactor);
659 }
660
661 qreal QWKPage::pageZoomFactor() const
662 {
663     return WKPageGetPageZoomFactor(pageRef());
664 }
665
666 void QWKPage::setPageZoomFactor(qreal zoomFactor)
667 {
668     WKPageSetPageZoomFactor(pageRef(), zoomFactor);
669 }
670
671 void QWKPage::setPageAndTextZoomFactors(qreal pageZoomFactor, qreal textZoomFactor)
672 {
673     WKPageSetPageAndTextZoomFactors(pageRef(), pageZoomFactor, textZoomFactor);
674 }
675
676 QWKHistory* QWKPage::history() const
677 {
678     return d->history;
679 }
680
681 void QWKPage::setResizesToContentsUsingLayoutSize(const QSize& targetLayoutSize)
682 {
683 #if ENABLE(TILED_BACKING_STORE)
684     d->page->setResizesToContentsUsingLayoutSize(targetLayoutSize);
685 #endif
686 }
687
688 #ifndef QT_NO_ACTION
689 void QWKPage::triggerAction(WebAction webAction, bool)
690 {
691     switch (webAction) {
692     case Back:
693         d->page->goBack();
694         return;
695     case Forward:
696         d->page->goForward();
697         return;
698     case Stop:
699         d->page->stopLoading();
700         return;
701     case Reload:
702         d->page->reload(/* reloadFromOrigin */ true);
703         return;
704     default:
705         break;
706     }
707
708     QAction* qtAction = action(webAction);
709     WebKit::WebContextMenuItemData menuItemData(ActionType, contextMenuActionForWebAction(webAction), qtAction->text(), qtAction->isEnabled(), qtAction->isChecked());
710     d->page->contextMenuItemSelected(menuItemData);
711 }
712 #endif // QT_NO_ACTION
713
714 #ifndef QT_NO_ACTION
715 QAction* QWKPage::action(WebAction action) const
716 {
717     if (action == QWKPage::NoWebAction || action >= WebActionCount)
718         return 0;
719
720     if (d->actions[action])
721         return d->actions[action];
722
723     QString text;
724     QIcon icon;
725     QStyle* style = qobject_cast<QApplication*>(QCoreApplication::instance())->style();
726     bool checkable = false;
727
728     switch (action) {
729     case OpenLink:
730         text = contextMenuItemTagOpenLink();
731         break;
732     case OpenLinkInNewWindow:
733         text = contextMenuItemTagOpenLinkInNewWindow();
734         break;
735     case CopyLinkToClipboard:
736         text = contextMenuItemTagCopyLinkToClipboard();
737         break;
738     case OpenImageInNewWindow:
739         text = contextMenuItemTagOpenImageInNewWindow();
740         break;
741     case Back:
742         text = contextMenuItemTagGoBack();
743         icon = style->standardIcon(QStyle::SP_ArrowBack);
744         break;
745     case Forward:
746         text = contextMenuItemTagGoForward();
747         icon = style->standardIcon(QStyle::SP_ArrowForward);
748         break;
749     case Stop:
750         text = contextMenuItemTagStop();
751         icon = style->standardIcon(QStyle::SP_BrowserStop);
752         break;
753     case Reload:
754         text = contextMenuItemTagReload();
755         icon = style->standardIcon(QStyle::SP_BrowserReload);
756         break;
757     case Cut:
758         text = contextMenuItemTagCut();
759         break;
760     case Copy:
761         text = contextMenuItemTagCopy();
762         break;
763     case Paste:
764         text = contextMenuItemTagPaste();
765         break;
766     case SelectAll:
767         text = contextMenuItemTagSelectAll();
768         break;
769     default:
770         return 0;
771         break;
772     }
773
774     if (text.isEmpty())
775         return 0;
776
777     QAction* a = new QAction(d->q);
778     a->setText(text);
779     a->setData(action);
780     a->setCheckable(checkable);
781     a->setIcon(icon);
782
783     connect(a, SIGNAL(triggered(bool)), this, SLOT(_q_webActionTriggered(bool)));
784
785     d->actions[action] = a;
786     d->updateAction(action);
787     return a;
788 }
789 #endif // QT_NO_ACTION
790
791 void QWKPage::findZoomableAreaForPoint(const QPoint& point)
792 {
793     d->page->findZoomableAreaForPoint(point);
794 }
795
796 void QWKPagePrivate::didFindZoomableArea(const IntRect& area)
797 {
798     emit q->zoomableAreaFound(QRect(area));
799 }
800
801 bool QWKPage::isConnectedToEngine() const
802 {
803     return d->isConnectedToEngine;
804 }
805
806 #include "moc_qwkpage.cpp"