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