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