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