AX: Webkit2 not sending UAZoomFocusChanged notifications
[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 IntRect QWKPagePrivate::windowToScreen(const IntRect& rect)
226 {
227     return rect;
228 }
229
230 FloatRect QWKPagePrivate::convertToUserSpace(const FloatRect& rect)
231 {
232     return rect;
233 }
234
235 void QWKPagePrivate::selectionChanged(bool, bool, bool, bool)
236 {
237 }
238
239 void QWKPagePrivate::doneWithKeyEvent(const NativeWebKeyboardEvent&, bool)
240 {
241 }
242
243 PassRefPtr<WebPopupMenuProxy> QWKPagePrivate::createPopupMenuProxy(WebPageProxy*)
244 {
245     return WebPopupMenuProxyQt::create();
246 }
247
248 PassRefPtr<WebContextMenuProxy> QWKPagePrivate::createContextMenuProxy(WebPageProxy*)
249 {
250     return WebContextMenuProxyQt::create(q);
251 }
252
253 void QWKPagePrivate::setFindIndicator(PassRefPtr<FindIndicator>, bool fadeOut)
254 {
255 }
256
257 void QWKPagePrivate::didCommitLoadForMainFrame(bool useCustomRepresentation)
258 {
259 }
260
261 void QWKPagePrivate::didFinishLoadingDataForCustomRepresentation(const String& suggestedFilename, const CoreIPC::DataReference&)
262 {
263 }
264
265 void QWKPagePrivate::flashBackingStoreUpdates(const Vector<IntRect>&)
266 {
267     notImplemented();
268 }
269
270 void QWKPagePrivate::paint(QPainter* painter, QRect area)
271 {
272     if (page->isValid() && page->drawingArea())
273         page->drawingArea()->paint(IntRect(area), painter);
274     else
275         painter->fillRect(area, Qt::white);
276 }
277
278 void QWKPagePrivate::keyPressEvent(QKeyEvent* ev)
279 {
280     page->handleKeyboardEvent(NativeWebKeyboardEvent(ev));
281 }
282
283 void QWKPagePrivate::keyReleaseEvent(QKeyEvent* ev)
284 {
285     page->handleKeyboardEvent(NativeWebKeyboardEvent(ev));
286 }
287
288 void QWKPagePrivate::mouseMoveEvent(QGraphicsSceneMouseEvent* ev)
289 {
290     // For some reason mouse press results in mouse hover (which is
291     // converted to mouse move for WebKit). We ignore these hover
292     // events by comparing lastPos with newPos.
293     // NOTE: lastPos from the event always comes empty, so we work
294     // around that here.
295     static QPointF lastPos = QPointF();
296     if (lastPos == ev->pos())
297         return;
298     lastPos = ev->pos();
299
300     WebMouseEvent mouseEvent = WebEventFactory::createWebMouseEvent(ev, 0);
301     page->handleMouseEvent(mouseEvent);
302 }
303
304 void QWKPagePrivate::mousePressEvent(QGraphicsSceneMouseEvent* ev)
305 {
306     if (tripleClickTimer.isActive() && (ev->pos() - tripleClick).manhattanLength() < QApplication::startDragDistance()) {
307         WebMouseEvent mouseEvent = WebEventFactory::createWebMouseEvent(ev, 3);
308         page->handleMouseEvent(mouseEvent);
309         return;
310     }
311
312     WebMouseEvent mouseEvent = WebEventFactory::createWebMouseEvent(ev, 1);
313     page->handleMouseEvent(mouseEvent);
314 }
315
316 void QWKPagePrivate::mouseReleaseEvent(QGraphicsSceneMouseEvent* ev)
317 {
318     WebMouseEvent mouseEvent = WebEventFactory::createWebMouseEvent(ev, 0);
319     page->handleMouseEvent(mouseEvent);
320 }
321
322 void QWKPagePrivate::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* ev)
323 {
324     WebMouseEvent mouseEvent = WebEventFactory::createWebMouseEvent(ev, 2);
325     page->handleMouseEvent(mouseEvent);
326
327     tripleClickTimer.start(QApplication::doubleClickInterval(), q);
328     tripleClick = ev->pos().toPoint();
329 }
330
331 void QWKPagePrivate::wheelEvent(QGraphicsSceneWheelEvent* ev)
332 {
333     WebWheelEvent wheelEvent = WebEventFactory::createWebWheelEvent(ev);
334     page->handleWheelEvent(wheelEvent);
335 }
336
337 void QWKPagePrivate::updateAction(QWKPage::WebAction action)
338 {
339 #ifdef QT_NO_ACTION
340     Q_UNUSED(action)
341 #else
342     QAction* a = actions[action];
343     if (!a)
344         return;
345
346     RefPtr<WebKit::WebFrameProxy> mainFrame = page->mainFrame();
347     if (!mainFrame)
348         return;
349
350     bool enabled = a->isEnabled();
351     bool checked = a->isChecked();
352
353     switch (action) {
354     case QWKPage::Back:
355         enabled = page->canGoBack();
356         break;
357     case QWKPage::Forward:
358         enabled = page->canGoForward();
359         break;
360     case QWKPage::Stop:
361         enabled = !(WebFrameProxy::LoadStateFinished == mainFrame->loadState());
362         break;
363     case QWKPage::Reload:
364         enabled = (WebFrameProxy::LoadStateFinished == mainFrame->loadState());
365         break;
366     default:
367         break;
368     }
369
370     a->setEnabled(enabled);
371
372     if (a->isCheckable())
373         a->setChecked(checked);
374 #endif // QT_NO_ACTION
375 }
376
377 void QWKPagePrivate::updateNavigationActions()
378 {
379     updateAction(QWKPage::Back);
380     updateAction(QWKPage::Forward);
381     updateAction(QWKPage::Stop);
382     updateAction(QWKPage::Reload);
383 }
384
385 #ifndef QT_NO_ACTION
386 void QWKPagePrivate::_q_webActionTriggered(bool checked)
387 {
388     QAction* a = qobject_cast<QAction*>(q->sender());
389     if (!a)
390         return;
391     QWKPage::WebAction action = static_cast<QWKPage::WebAction>(a->data().toInt());
392     q->triggerAction(action, checked);
393 }
394 #endif // QT_NO_ACTION
395
396 void QWKPagePrivate::touchEvent(QTouchEvent* event)
397 {
398 #if ENABLE(TOUCH_EVENTS)
399     WebTouchEvent touchEvent = WebEventFactory::createWebTouchEvent(event);
400     page->handleTouchEvent(touchEvent);
401 #else
402     event->ignore();
403 #endif
404 }
405
406 void QWKPagePrivate::didRelaunchProcess()
407 {
408     QGraphicsWKView* wkView = static_cast<QGraphicsWKView*>(view);
409     if (wkView)
410         q->setViewportSize(wkView->size().toSize());
411
412     isConnectedToEngine = true;
413     emit q->engineConnectionChanged(true);
414 }
415
416 void QWKPagePrivate::processDidCrash()
417 {
418     isConnectedToEngine = false;
419     emit q->engineConnectionChanged(false);
420 }
421
422 QWKPage::QWKPage(QWKContext* context)
423     : d(new QWKPagePrivate(this, context))
424 {
425     WKPageLoaderClient loadClient = {
426         0,      /* version */
427         this,   /* clientInfo */
428         qt_wk_didStartProvisionalLoadForFrame,
429         qt_wk_didReceiveServerRedirectForProvisionalLoadForFrame,
430         qt_wk_didFailProvisionalLoadWithErrorForFrame,
431         qt_wk_didCommitLoadForFrame,
432         qt_wk_didFinishDocumentLoadForFrame,
433         qt_wk_didFinishLoadForFrame,
434         qt_wk_didFailLoadWithErrorForFrame,
435         0, /* didSameDocumentNavigationForFrame */
436         qt_wk_didReceiveTitleForFrame,
437         qt_wk_didFirstLayoutForFrame,
438         qt_wk_didFirstVisuallyNonEmptyLayoutForFrame,
439         qt_wk_didRemoveFrameFromHierarchy,
440         0, /* didDisplayInsecureContentForFrame */
441         0, /* didRunInsecureContentForFrame */
442         0, /* canAuthenticateAgainstProtectionSpaceInFrame */
443         0, /* didReceiveAuthenticationChallengeInFrame */
444         qt_wk_didStartProgress,
445         qt_wk_didChangeProgress,
446         qt_wk_didFinishProgress,
447         qt_wk_didBecomeUnresponsive,
448         qt_wk_didBecomeResponsive,
449         0,  /* processDidCrash */
450         0,  /* didChangeBackForwardList */
451         0   /* shouldGoToBackForwardListItem */
452     };
453     WKPageSetPageLoaderClient(pageRef(), &loadClient);
454
455     WKPageUIClient uiClient = {
456         0,      /* version */
457         this,   /* clientInfo */
458         qt_wk_createNewPage,
459         qt_wk_showPage,
460         qt_wk_close,
461         qt_wk_runJavaScriptAlert,
462         0,  /* runJavaScriptConfirm */
463         0,  /* runJavaScriptPrompt */
464         0,  /* setStatusText */
465         0,  /* mouseDidMoveOverElement */
466         0,  /* missingPluginButtonClicked */
467         0,  /* didNotHandleKeyEvent */
468         0,  /* toolbarsAreVisible */
469         0,  /* setToolbarsAreVisible */
470         0,  /* menuBarIsVisible */
471         0,  /* setMenuBarIsVisible */
472         0,  /* statusBarIsVisible */
473         0,  /* setStatusBarIsVisible */
474         0,  /* isResizable */
475         0,  /* setIsResizable */
476         0,  /* getWindowFrame */
477         0,  /* setWindowFrame */
478         0,  /* runBeforeUnloadConfirmPanel */
479         0,  /* didDraw */
480         0,  /* pageDidScroll */
481         0,  /* exceededDatabaseQuota */
482         0,  /* runOpenPanel */
483         0,  /* decidePolicyForGeolocationPermissionRequest */
484         0,  /* headerHeight */
485         0,  /* footerHeight */
486         0,  /* drawHeader */
487         0,  /* drawFooter */
488         0,  /* printFrame */
489         0,  /* runModal */
490         0   /* didCompleteRubberBandForMainFrame */
491     };
492     WKPageSetPageUIClient(pageRef(), &uiClient);
493 }
494
495 QWKPage::~QWKPage()
496 {
497     delete d;
498 }
499
500 QWKPage::ViewportAttributes::ViewportAttributes()
501     : d(0)
502     , m_initialScaleFactor(-1.0)
503     , m_minimumScaleFactor(-1.0)
504     , m_maximumScaleFactor(-1.0)
505     , m_devicePixelRatio(-1.0)
506     , m_isUserScalable(true)
507     , m_isValid(false)
508 {
509
510 }
511
512 QWKPage::ViewportAttributes::ViewportAttributes(const QWKPage::ViewportAttributes& other)
513     : d(other.d)
514     , m_initialScaleFactor(other.m_initialScaleFactor)
515     , m_minimumScaleFactor(other.m_minimumScaleFactor)
516     , m_maximumScaleFactor(other.m_maximumScaleFactor)
517     , m_devicePixelRatio(other.m_devicePixelRatio)
518     , m_isUserScalable(other.m_isUserScalable)
519     , m_isValid(other.m_isValid)
520     , m_size(other.m_size)
521 {
522
523 }
524
525 QWKPage::ViewportAttributes::~ViewportAttributes()
526 {
527
528 }
529
530 QWKPage::ViewportAttributes& QWKPage::ViewportAttributes::operator=(const QWKPage::ViewportAttributes& other)
531 {
532     if (this != &other) {
533         d = other.d;
534         m_initialScaleFactor = other.m_initialScaleFactor;
535         m_minimumScaleFactor = other.m_minimumScaleFactor;
536         m_maximumScaleFactor = other.m_maximumScaleFactor;
537         m_devicePixelRatio = other.m_devicePixelRatio;
538         m_isUserScalable = other.m_isUserScalable;
539         m_isValid = other.m_isValid;
540         m_size = other.m_size;
541     }
542
543     return *this;
544 }
545
546 QWKPage::ViewportAttributes QWKPage::viewportAttributesForSize(const QSize& availableSize) const
547 {
548     static int desktopWidth = 980;
549     static int deviceDPI = 160;
550
551     ViewportAttributes result;
552
553      if (availableSize.isEmpty())
554          return result; // Returns an invalid instance.
555
556     // FIXME: Add a way to get these data via the platform plugin and fall back
557     // to the size of the view.
558     int deviceWidth = 480;
559     int deviceHeight = 864;
560
561     WebCore::ViewportAttributes conf = WebCore::computeViewportAttributes(d->viewportArguments, desktopWidth, deviceWidth, deviceHeight, deviceDPI, availableSize);
562
563     result.m_isValid = true;
564     result.m_size = conf.layoutSize;
565     result.m_initialScaleFactor = conf.initialScale;
566     result.m_minimumScaleFactor = conf.minimumScale;
567     result.m_maximumScaleFactor = conf.maximumScale;
568     result.m_devicePixelRatio = conf.devicePixelRatio;
569     result.m_isUserScalable = conf.userScalable;
570
571     return result;
572 }
573
574 void QWKPage::setActualVisibleContentsRect(const QRect& rect) const
575 {
576 #if ENABLE(TILED_BACKING_STORE)
577     d->page->setActualVisibleContentRect(rect);
578 #endif
579 }
580
581 void QWKPage::timerEvent(QTimerEvent* ev)
582 {
583     int timerId = ev->timerId();
584     if (timerId == d->tripleClickTimer.timerId())
585         d->tripleClickTimer.stop();
586     else
587         QObject::timerEvent(ev);
588 }
589
590 WKPageRef QWKPage::pageRef() const
591 {
592     return toAPI(d->page.get());
593 }
594
595 QWKContext* QWKPage::context() const
596 {
597     return d->context;
598 }
599
600 QWKPreferences* QWKPage::preferences() const
601 {
602     if (!d->preferences) {
603         WKPageGroupRef pageGroupRef = WKPageGetPageGroup(pageRef());
604         d->preferences = QWKPreferencesPrivate::createPreferences(pageGroupRef);
605     }
606
607     return d->preferences;
608 }
609
610 void QWKPage::setCreateNewPageFunction(CreateNewPageFn function)
611 {
612     d->createNewPageFn = function;
613 }
614
615 void QWKPage::setCustomUserAgent(const QString& userAgent)
616 {
617     WKRetainPtr<WKStringRef> wkUserAgent(WKStringCreateWithQString(userAgent));
618     WKPageSetCustomUserAgent(pageRef(), wkUserAgent.get());
619 }
620
621 QString QWKPage::customUserAgent() const
622 {
623     return WKStringCopyQString(WKPageCopyCustomUserAgent(pageRef()));
624 }
625
626 void QWKPage::load(const QUrl& url)
627 {
628     WKRetainPtr<WKURLRef> wkurl(WKURLCreateWithQUrl(url));
629     WKPageLoadURL(pageRef(), wkurl.get());
630 }
631
632 void QWKPage::setUrl(const QUrl& url)
633 {
634     load(url);
635 }
636
637 QUrl QWKPage::url() const
638 {
639     WKRetainPtr<WKFrameRef> frame = WKPageGetMainFrame(pageRef());
640     if (!frame)
641         return QUrl();
642     return WKURLCopyQUrl(WKFrameCopyURL(frame.get()));
643 }
644
645 QString QWKPage::title() const
646 {
647     return WKStringCopyQString(WKPageCopyTitle(pageRef()));
648 }
649
650 void QWKPage::setViewportSize(const QSize& size)
651 {
652     if (d->page->drawingArea())
653         d->page->drawingArea()->setSize(IntSize(size), IntSize());
654 }
655
656 qreal QWKPage::textZoomFactor() const
657 {
658     return WKPageGetTextZoomFactor(pageRef());
659 }
660
661 void QWKPage::setTextZoomFactor(qreal zoomFactor)
662 {
663     WKPageSetTextZoomFactor(pageRef(), zoomFactor);
664 }
665
666 qreal QWKPage::pageZoomFactor() const
667 {
668     return WKPageGetPageZoomFactor(pageRef());
669 }
670
671 void QWKPage::setPageZoomFactor(qreal zoomFactor)
672 {
673     WKPageSetPageZoomFactor(pageRef(), zoomFactor);
674 }
675
676 void QWKPage::setPageAndTextZoomFactors(qreal pageZoomFactor, qreal textZoomFactor)
677 {
678     WKPageSetPageAndTextZoomFactors(pageRef(), pageZoomFactor, textZoomFactor);
679 }
680
681 QWKHistory* QWKPage::history() const
682 {
683     return d->history;
684 }
685
686 void QWKPage::setResizesToContentsUsingLayoutSize(const QSize& targetLayoutSize)
687 {
688 #if ENABLE(TILED_BACKING_STORE)
689     d->page->setResizesToContentsUsingLayoutSize(targetLayoutSize);
690 #endif
691 }
692
693 #ifndef QT_NO_ACTION
694 void QWKPage::triggerAction(WebAction webAction, bool)
695 {
696     switch (webAction) {
697     case Back:
698         d->page->goBack();
699         return;
700     case Forward:
701         d->page->goForward();
702         return;
703     case Stop:
704         d->page->stopLoading();
705         return;
706     case Reload:
707         d->page->reload(/* reloadFromOrigin */ true);
708         return;
709     default:
710         break;
711     }
712
713     QAction* qtAction = action(webAction);
714     WebKit::WebContextMenuItemData menuItemData(ActionType, contextMenuActionForWebAction(webAction), qtAction->text(), qtAction->isEnabled(), qtAction->isChecked());
715     d->page->contextMenuItemSelected(menuItemData);
716 }
717 #endif // QT_NO_ACTION
718
719 #ifndef QT_NO_ACTION
720 QAction* QWKPage::action(WebAction action) const
721 {
722     if (action == QWKPage::NoWebAction || action >= WebActionCount)
723         return 0;
724
725     if (d->actions[action])
726         return d->actions[action];
727
728     QString text;
729     QIcon icon;
730     QStyle* style = qobject_cast<QApplication*>(QCoreApplication::instance())->style();
731     bool checkable = false;
732
733     switch (action) {
734     case OpenLink:
735         text = contextMenuItemTagOpenLink();
736         break;
737     case OpenLinkInNewWindow:
738         text = contextMenuItemTagOpenLinkInNewWindow();
739         break;
740     case CopyLinkToClipboard:
741         text = contextMenuItemTagCopyLinkToClipboard();
742         break;
743     case OpenImageInNewWindow:
744         text = contextMenuItemTagOpenImageInNewWindow();
745         break;
746     case Back:
747         text = contextMenuItemTagGoBack();
748         icon = style->standardIcon(QStyle::SP_ArrowBack);
749         break;
750     case Forward:
751         text = contextMenuItemTagGoForward();
752         icon = style->standardIcon(QStyle::SP_ArrowForward);
753         break;
754     case Stop:
755         text = contextMenuItemTagStop();
756         icon = style->standardIcon(QStyle::SP_BrowserStop);
757         break;
758     case Reload:
759         text = contextMenuItemTagReload();
760         icon = style->standardIcon(QStyle::SP_BrowserReload);
761         break;
762     case Cut:
763         text = contextMenuItemTagCut();
764         break;
765     case Copy:
766         text = contextMenuItemTagCopy();
767         break;
768     case Paste:
769         text = contextMenuItemTagPaste();
770         break;
771     case SelectAll:
772         text = contextMenuItemTagSelectAll();
773         break;
774     default:
775         return 0;
776         break;
777     }
778
779     if (text.isEmpty())
780         return 0;
781
782     QAction* a = new QAction(d->q);
783     a->setText(text);
784     a->setData(action);
785     a->setCheckable(checkable);
786     a->setIcon(icon);
787
788     connect(a, SIGNAL(triggered(bool)), this, SLOT(_q_webActionTriggered(bool)));
789
790     d->actions[action] = a;
791     d->updateAction(action);
792     return a;
793 }
794 #endif // QT_NO_ACTION
795
796 void QWKPage::findZoomableAreaForPoint(const QPoint& point)
797 {
798     d->page->findZoomableAreaForPoint(point);
799 }
800
801 void QWKPagePrivate::didFindZoomableArea(const IntRect& area)
802 {
803     emit q->zoomableAreaFound(QRect(area));
804 }
805
806 bool QWKPage::isConnectedToEngine() const
807 {
808     return d->isConnectedToEngine;
809 }
810
811 #include "moc_qwkpage.cpp"