2011-01-25 Andreas Kling <kling@webkit.org>
[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 void QWKPagePrivate::processDidCrash()
397 {
398     emit q->processCrashed();
399 }
400
401 QWKPage::QWKPage(QWKContext* context)
402     : d(new QWKPagePrivate(this, context))
403 {
404     WKPageLoaderClient loadClient = {
405         0,      /* version */
406         this,   /* clientInfo */
407         qt_wk_didStartProvisionalLoadForFrame,
408         qt_wk_didReceiveServerRedirectForProvisionalLoadForFrame,
409         qt_wk_didFailProvisionalLoadWithErrorForFrame,
410         qt_wk_didCommitLoadForFrame,
411         qt_wk_didFinishDocumentLoadForFrame,
412         qt_wk_didFinishLoadForFrame,
413         qt_wk_didFailLoadWithErrorForFrame,
414         0, /* didSameDocumentNavigationForFrame */
415         qt_wk_didReceiveTitleForFrame,
416         qt_wk_didFirstLayoutForFrame,
417         qt_wk_didFirstVisuallyNonEmptyLayoutForFrame,
418         qt_wk_didRemoveFrameFromHierarchy,
419         0, /* didDisplayInsecureContentForFrame */
420         0, /* didRunInsecureContentForFrame */
421         0, /* canAuthenticateAgainstProtectionSpaceInFrame */
422         0, /* didReceiveAuthenticationChallengeInFrame */
423         qt_wk_didStartProgress,
424         qt_wk_didChangeProgress,
425         qt_wk_didFinishProgress,
426         qt_wk_didBecomeUnresponsive,
427         qt_wk_didBecomeResponsive,
428         0,  /* processDidCrash */
429         0   /* didChangeBackForwardList */
430     };
431     WKPageSetPageLoaderClient(pageRef(), &loadClient);
432
433     WKPageUIClient uiClient = {
434         0,      /* version */
435         this,   /* clientInfo */
436         qt_wk_createNewPage,
437         qt_wk_showPage,
438         qt_wk_close,
439         qt_wk_runJavaScriptAlert,
440         0,  /* runJavaScriptConfirm */
441         0,  /* runJavaScriptPrompt */
442         0,  /* setStatusText */
443         0,  /* mouseDidMoveOverElement */
444         0,  /* missingPluginButtonClicked */
445         0,  /* didNotHandleKeyEvent */
446         0,  /* toolbarsAreVisible */
447         0,  /* setToolbarsAreVisible */
448         0,  /* menuBarIsVisible */
449         0,  /* setMenuBarIsVisible */
450         0,  /* statusBarIsVisible */
451         0,  /* setStatusBarIsVisible */
452         0,  /* isResizable */
453         0,  /* setIsResizable */
454         0,  /* getWindowFrame */
455         0,  /* setWindowFrame */
456         0,  /* runBeforeUnloadConfirmPanel */
457         0,  /* didDraw */
458         0,  /* pageDidScroll */
459         0,  /* exceededDatabaseQuota */
460         0,  /* runOpenPanel */
461         0,  /* decidePolicyForGeolocationPermissionRequest */
462         0,  /* headerHeight */
463         0,  /* footerHeight */
464         0,  /* drawHeader */
465         0,  /* drawFooter */
466         0,  /* printFrame */
467         0   /* runModal */
468     };
469     WKPageSetPageUIClient(pageRef(), &uiClient);
470 }
471
472 QWKPage::~QWKPage()
473 {
474     delete d;
475 }
476
477 QWKPage::ViewportAttributes::ViewportAttributes()
478     : d(0)
479     , m_initialScaleFactor(-1.0)
480     , m_minimumScaleFactor(-1.0)
481     , m_maximumScaleFactor(-1.0)
482     , m_devicePixelRatio(-1.0)
483     , m_isUserScalable(true)
484     , m_isValid(false)
485 {
486
487 }
488
489 QWKPage::ViewportAttributes::ViewportAttributes(const QWKPage::ViewportAttributes& other)
490     : d(other.d)
491     , m_initialScaleFactor(other.m_initialScaleFactor)
492     , m_minimumScaleFactor(other.m_minimumScaleFactor)
493     , m_maximumScaleFactor(other.m_maximumScaleFactor)
494     , m_devicePixelRatio(other.m_devicePixelRatio)
495     , m_isUserScalable(other.m_isUserScalable)
496     , m_isValid(other.m_isValid)
497     , m_size(other.m_size)
498 {
499
500 }
501
502 QWKPage::ViewportAttributes::~ViewportAttributes()
503 {
504
505 }
506
507 QWKPage::ViewportAttributes& QWKPage::ViewportAttributes::operator=(const QWKPage::ViewportAttributes& other)
508 {
509     if (this != &other) {
510         d = other.d;
511         m_initialScaleFactor = other.m_initialScaleFactor;
512         m_minimumScaleFactor = other.m_minimumScaleFactor;
513         m_maximumScaleFactor = other.m_maximumScaleFactor;
514         m_devicePixelRatio = other.m_devicePixelRatio;
515         m_isUserScalable = other.m_isUserScalable;
516         m_isValid = other.m_isValid;
517         m_size = other.m_size;
518     }
519
520     return *this;
521 }
522
523 QWKPage::ViewportAttributes QWKPage::viewportAttributesForSize(const QSize& availableSize) const
524 {
525     static int desktopWidth = 980;
526     static int deviceDPI = 160;
527
528     ViewportAttributes result;
529
530      if (availableSize.isEmpty())
531          return result; // Returns an invalid instance.
532
533     // FIXME: Add a way to get these data via the platform plugin and fall back
534     // to the size of the view.
535     int deviceWidth = 480;
536     int deviceHeight = 864;
537
538     WebCore::ViewportAttributes conf = WebCore::computeViewportAttributes(d->viewportArguments, desktopWidth, deviceWidth, deviceHeight, deviceDPI, availableSize);
539
540     result.m_isValid = true;
541     result.m_size = conf.layoutSize;
542     result.m_initialScaleFactor = conf.initialScale;
543     result.m_minimumScaleFactor = conf.minimumScale;
544     result.m_maximumScaleFactor = conf.maximumScale;
545     result.m_devicePixelRatio = conf.devicePixelRatio;
546     result.m_isUserScalable = conf.userScalable;
547
548     return result;
549 }
550
551 void QWKPage::setActualVisibleContentsRect(const QRect& rect) const
552 {
553 #if ENABLE(TILED_BACKING_STORE)
554     d->page->setActualVisibleContentRect(rect);
555 #endif
556 }
557
558 void QWKPage::timerEvent(QTimerEvent* ev)
559 {
560     int timerId = ev->timerId();
561     if (timerId == d->tripleClickTimer.timerId())
562         d->tripleClickTimer.stop();
563     else
564         QObject::timerEvent(ev);
565 }
566
567 WKPageRef QWKPage::pageRef() const
568 {
569     return toAPI(d->page.get());
570 }
571
572 QWKContext* QWKPage::context() const
573 {
574     return d->context;
575 }
576
577 QWKPreferences* QWKPage::preferences() const
578 {
579     if (!d->preferences) {
580         WKPageGroupRef pageGroupRef = WKPageGetPageGroup(pageRef());
581         d->preferences = QWKPreferencesPrivate::createPreferences(pageGroupRef);
582     }
583
584     return d->preferences;
585 }
586
587 void QWKPage::setCreateNewPageFunction(CreateNewPageFn function)
588 {
589     d->createNewPageFn = function;
590 }
591
592 void QWKPage::setCustomUserAgent(const QString& userAgent)
593 {
594     WKRetainPtr<WKStringRef> wkUserAgent(WKStringCreateWithQString(userAgent));
595     WKPageSetCustomUserAgent(pageRef(), wkUserAgent.get());
596 }
597
598 QString QWKPage::customUserAgent() const
599 {
600     return WKStringCopyQString(WKPageCopyCustomUserAgent(pageRef()));
601 }
602
603 void QWKPage::load(const QUrl& url)
604 {
605     WKRetainPtr<WKURLRef> wkurl(WKURLCreateWithQUrl(url));
606     WKPageLoadURL(pageRef(), wkurl.get());
607 }
608
609 void QWKPage::setUrl(const QUrl& url)
610 {
611     load(url);
612 }
613
614 QUrl QWKPage::url() const
615 {
616     WKRetainPtr<WKFrameRef> frame = WKPageGetMainFrame(pageRef());
617     if (!frame)
618         return QUrl();
619     return WKURLCopyQUrl(WKFrameCopyURL(frame.get()));
620 }
621
622 QString QWKPage::title() const
623 {
624     return WKStringCopyQString(WKPageCopyTitle(pageRef()));
625 }
626
627 void QWKPage::setViewportSize(const QSize& size)
628 {
629     if (d->page->drawingArea())
630         d->page->drawingArea()->setSize(IntSize(size));
631 }
632
633 qreal QWKPage::textZoomFactor() const
634 {
635     return WKPageGetTextZoomFactor(pageRef());
636 }
637
638 void QWKPage::setTextZoomFactor(qreal zoomFactor)
639 {
640     WKPageSetTextZoomFactor(pageRef(), zoomFactor);
641 }
642
643 qreal QWKPage::pageZoomFactor() const
644 {
645     return WKPageGetPageZoomFactor(pageRef());
646 }
647
648 void QWKPage::setPageZoomFactor(qreal zoomFactor)
649 {
650     WKPageSetPageZoomFactor(pageRef(), zoomFactor);
651 }
652
653 void QWKPage::setPageAndTextZoomFactors(qreal pageZoomFactor, qreal textZoomFactor)
654 {
655     WKPageSetPageAndTextZoomFactors(pageRef(), pageZoomFactor, textZoomFactor);
656 }
657
658 QWKHistory* QWKPage::history() const
659 {
660     return d->history;
661 }
662
663 void QWKPage::setResizesToContentsUsingLayoutSize(const QSize& targetLayoutSize)
664 {
665 #if ENABLE(TILED_BACKING_STORE)
666     d->page->setResizesToContentsUsingLayoutSize(targetLayoutSize);
667 #endif
668 }
669
670 #ifndef QT_NO_ACTION
671 void QWKPage::triggerAction(WebAction webAction, bool)
672 {
673     switch (webAction) {
674     case Back:
675         d->page->goBack();
676         return;
677     case Forward:
678         d->page->goForward();
679         return;
680     case Stop:
681         d->page->stopLoading();
682         return;
683     case Reload:
684         d->page->reload(/* reloadFromOrigin */ true);
685         return;
686     default:
687         break;
688     }
689
690     QAction* qtAction = action(webAction);
691     WebKit::WebContextMenuItemData menuItemData(ActionType, contextMenuActionForWebAction(webAction), qtAction->text(), qtAction->isEnabled(), qtAction->isChecked());
692     d->page->contextMenuItemSelected(menuItemData);
693 }
694 #endif // QT_NO_ACTION
695
696 #ifndef QT_NO_ACTION
697 QAction* QWKPage::action(WebAction action) const
698 {
699     if (action == QWKPage::NoWebAction || action >= WebActionCount)
700         return 0;
701
702     if (d->actions[action])
703         return d->actions[action];
704
705     QString text;
706     QIcon icon;
707     QStyle* style = qobject_cast<QApplication*>(QCoreApplication::instance())->style();
708     bool checkable = false;
709
710     switch (action) {
711     case OpenLink:
712         text = contextMenuItemTagOpenLink();
713         break;
714     case OpenLinkInNewWindow:
715         text = contextMenuItemTagOpenLinkInNewWindow();
716         break;
717     case CopyLinkToClipboard:
718         text = contextMenuItemTagCopyLinkToClipboard();
719         break;
720     case OpenImageInNewWindow:
721         text = contextMenuItemTagOpenImageInNewWindow();
722         break;
723     case Back:
724         text = contextMenuItemTagGoBack();
725         icon = style->standardIcon(QStyle::SP_ArrowBack);
726         break;
727     case Forward:
728         text = contextMenuItemTagGoForward();
729         icon = style->standardIcon(QStyle::SP_ArrowForward);
730         break;
731     case Stop:
732         text = contextMenuItemTagStop();
733         icon = style->standardIcon(QStyle::SP_BrowserStop);
734         break;
735     case Reload:
736         text = contextMenuItemTagReload();
737         icon = style->standardIcon(QStyle::SP_BrowserReload);
738         break;
739     case Cut:
740         text = contextMenuItemTagCut();
741         break;
742     case Copy:
743         text = contextMenuItemTagCopy();
744         break;
745     case Paste:
746         text = contextMenuItemTagPaste();
747         break;
748     case SelectAll:
749         text = contextMenuItemTagSelectAll();
750         break;
751     default:
752         return 0;
753         break;
754     }
755
756     if (text.isEmpty())
757         return 0;
758
759     QAction* a = new QAction(d->q);
760     a->setText(text);
761     a->setData(action);
762     a->setCheckable(checkable);
763     a->setIcon(icon);
764
765     connect(a, SIGNAL(triggered(bool)), this, SLOT(_q_webActionTriggered(bool)));
766
767     d->actions[action] = a;
768     d->updateAction(action);
769     return a;
770 }
771 #endif // QT_NO_ACTION
772
773 void QWKPage::findZoomableAreaForPoint(const QPoint& point)
774 {
775     d->page->findZoomableAreaForPoint(point);
776 }
777
778 void QWKPagePrivate::didFindZoomableArea(const IntRect& area)
779 {
780     emit q->zoomableAreaFound(QRect(area));
781 }
782
783 #include "moc_qwkpage.cpp"