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 60 using namespace WebKit; 61 using namespace WebCore; 62 63 static 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 89 QWKPagePrivate::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 103 QWKPagePrivate::~QWKPagePrivate() 104 { 105 page->close(); 106 delete history; 107 } 108 109 void QWKPagePrivate::init(QGraphicsItem* view, QGraphicsWKView::BackingStoreType backingStoreType) 110 { 111 this->view = view; 112 this->backingStoreType = backingStoreType; 113 page->initializeWebPage(); 114 } 115 116 void QWKPagePrivate::setCursor(const WebCore::Cursor& cursor) 117 { 118 #ifndef QT_NO_CURSOR 119 emit q->cursorChanged(*cursor.platformCursor()); 120 #endif 121 } 122 123 void QWKPagePrivate::setViewportArguments(const ViewportArguments& args) 124 { 125 viewportArguments = args; 126 emit q->viewportChangeRequested(); 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 return view && view->isActive(); 165 } 166 167 bool QWKPagePrivate::isViewFocused() 168 { 169 return view && view->hasFocus(); 170 } 171 172 bool QWKPagePrivate::isViewVisible() 173 { 174 return view && view->isVisible(); 175 } 176 177 bool QWKPagePrivate::isViewInWindow() 178 { 179 // FIXME: Implement. 180 return true; 181 } 182 183 void QWKPagePrivate::enterAcceleratedCompositingMode(const LayerTreeContext&) 184 { 185 // FIXME: Implement. 186 } 187 188 void QWKPagePrivate::exitAcceleratedCompositingMode() 189 { 190 // FIXME: Implement. 191 } 192 193 void QWKPagePrivate::pageDidRequestScroll(const IntPoint& point) 194 { 195 emit q->scrollRequested(point.x(), point.y()); 196 } 197 198 void QWKPagePrivate::didChangeContentsSize(const IntSize& newSize) 199 { 200 emit q->contentsSizeChanged(QSize(newSize)); 201 } 202 203 void QWKPagePrivate::toolTipChanged(const String&, const String& newTooltip) 204 { 205 emit q->toolTipChanged(QString(newTooltip)); 206 } 207 208 void QWKPagePrivate::registerEditCommand(PassRefPtr<WebEditCommandProxy>, WebPageProxy::UndoOrRedo) 209 { 210 } 211 212 void QWKPagePrivate::clearAllEditCommands() 213 { 214 } 215 216 bool QWKPagePrivate::canUndoRedo(WebPageProxy::UndoOrRedo) 217 { 218 return false; 219 } 220 221 void QWKPagePrivate::executeUndoRedo(WebPageProxy::UndoOrRedo) 222 { 223 } 224 225 FloatRect QWKPagePrivate::convertToDeviceSpace(const FloatRect& rect) 226 { 227 return rect; 228 } 229 230 IntRect QWKPagePrivate::windowToScreen(const IntRect& rect) 231 { 232 return rect; 233 } 234 235 FloatRect QWKPagePrivate::convertToUserSpace(const FloatRect& rect) 236 { 237 return rect; 238 } 239 240 void QWKPagePrivate::selectionChanged(bool, bool, bool, bool) 241 { 242 } 243 244 void QWKPagePrivate::doneWithKeyEvent(const NativeWebKeyboardEvent&, bool) 245 { 246 } 247 248 PassRefPtr<WebPopupMenuProxy> QWKPagePrivate::createPopupMenuProxy(WebPageProxy*) 249 { 250 return WebPopupMenuProxyQt::create(); 251 } 252 253 PassRefPtr<WebContextMenuProxy> QWKPagePrivate::createContextMenuProxy(WebPageProxy*) 254 { 255 return WebContextMenuProxyQt::create(q); 256 } 257 258 void QWKPagePrivate::setFindIndicator(PassRefPtr<FindIndicator>, bool fadeOut) 259 { 260 } 261 262 void QWKPagePrivate::didCommitLoadForMainFrame(bool useCustomRepresentation) 263 { 264 } 265 266 void QWKPagePrivate::didFinishLoadingDataForCustomRepresentation(const String& suggestedFilename, const CoreIPC::DataReference&) 267 { 268 } 269 270 void QWKPagePrivate::flashBackingStoreUpdates(const Vector<IntRect>&) 271 { 272 notImplemented(); 273 } 274 275 void 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 283 void QWKPagePrivate::keyPressEvent(QKeyEvent* ev) 284 { 285 page->handleKeyboardEvent(NativeWebKeyboardEvent(ev)); 286 } 287 288 void QWKPagePrivate::keyReleaseEvent(QKeyEvent* ev) 289 { 290 page->handleKeyboardEvent(NativeWebKeyboardEvent(ev)); 291 } 292 293 void 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 308 void 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 318 void QWKPagePrivate::mouseReleaseEvent(QGraphicsSceneMouseEvent* ev) 319 { 320 page->handleMouseEvent(NativeWebMouseEvent(ev, 0)); 321 } 322 323 void 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 331 void QWKPagePrivate::wheelEvent(QGraphicsSceneWheelEvent* ev) 332 { 333 WebWheelEvent wheelEvent = WebEventFactory::createWebWheelEvent(ev); 334 page->handleWheelEvent(wheelEvent); 335 } 336 337 void QWKPagePrivate::updateAction(QWKPage::WebAction action) 338 { 339 #ifdef QT_NO_ACTION 340 Q_UNUSED(action) 341 #else 342 QAction* a = actions[action]; 343 if (!a) 344 return; 345 346 RefPtr<WebKit::WebFrameProxy> mainFrame = page->mainFrame(); 347 if (!mainFrame) 348 return; 349 350 bool enabled = a->isEnabled(); 351 bool checked = a->isChecked(); 352 353 switch (action) { 354 case QWKPage::Back: 355 enabled = page->canGoBack(); 356 break; 357 case QWKPage::Forward: 358 enabled = page->canGoForward(); 359 break; 360 case QWKPage::Stop: 361 enabled = !(WebFrameProxy::LoadStateFinished == mainFrame->loadState()); 362 break; 363 case QWKPage::Reload: 364 enabled = (WebFrameProxy::LoadStateFinished == mainFrame->loadState()); 365 break; 366 default: 367 break; 368 } 369 370 a->setEnabled(enabled); 371 372 if (a->isCheckable()) 373 a->setChecked(checked); 374 #endif // QT_NO_ACTION 375 } 376 377 void QWKPagePrivate::updateNavigationActions() 378 { 379 updateAction(QWKPage::Back); 380 updateAction(QWKPage::Forward); 381 updateAction(QWKPage::Stop); 382 updateAction(QWKPage::Reload); 383 } 384 385 #ifndef QT_NO_ACTION 386 void QWKPagePrivate::_q_webActionTriggered(bool checked) 387 { 388 QAction* a = qobject_cast<QAction*>(q->sender()); 389 if (!a) 390 return; 391 QWKPage::WebAction action = static_cast<QWKPage::WebAction>(a->data().toInt()); 392 q->triggerAction(action, checked); 393 } 394 #endif // QT_NO_ACTION 395 396 void QWKPagePrivate::touchEvent(QTouchEvent* event) 397 { 398 #if ENABLE(TOUCH_EVENTS) 399 WebTouchEvent touchEvent = WebEventFactory::createWebTouchEvent(event); 400 page->handleTouchEvent(touchEvent); 401 #else 402 event->ignore(); 403 #endif 404 } 405 406 void QWKPagePrivate::didRelaunchProcess() 407 { 408 QGraphicsWKView* wkView = static_cast<QGraphicsWKView*>(view); 409 if (wkView) 410 q->setViewportSize(wkView->size().toSize()); 411 412 isConnectedToEngine = true; 413 emit q->engineConnectionChanged(true); 414 } 415 416 void QWKPagePrivate::processDidCrash() 417 { 418 isConnectedToEngine = false; 419 emit q->engineConnectionChanged(false); 420 } 421 422 QWKPage::QWKPage(QWKContext* context) 423 : d(new QWKPagePrivate(this, context)) 424 { 425 WKPageLoaderClient loadClient = { 426 0, /* version */ 427 this, /* clientInfo */ 428 qt_wk_didStartProvisionalLoadForFrame, 429 qt_wk_didReceiveServerRedirectForProvisionalLoadForFrame, 430 qt_wk_didFailProvisionalLoadWithErrorForFrame, 431 qt_wk_didCommitLoadForFrame, 432 qt_wk_didFinishDocumentLoadForFrame, 433 qt_wk_didFinishLoadForFrame, 434 qt_wk_didFailLoadWithErrorForFrame, 435 0, /* didSameDocumentNavigationForFrame */ 436 qt_wk_didReceiveTitleForFrame, 437 qt_wk_didFirstLayoutForFrame, 438 qt_wk_didFirstVisuallyNonEmptyLayoutForFrame, 439 qt_wk_didRemoveFrameFromHierarchy, 440 0, /* didDisplayInsecureContentForFrame */ 441 0, /* didRunInsecureContentForFrame */ 442 0, /* canAuthenticateAgainstProtectionSpaceInFrame */ 443 0, /* didReceiveAuthenticationChallengeInFrame */ 444 qt_wk_didStartProgress, 445 qt_wk_didChangeProgress, 446 qt_wk_didFinishProgress, 447 qt_wk_didBecomeUnresponsive, 448 qt_wk_didBecomeResponsive, 449 0, /* processDidCrash */ 450 0, /* didChangeBackForwardList */ 451 0 /* shouldGoToBackForwardListItem */ 452 }; 453 WKPageSetPageLoaderClient(pageRef(), &loadClient); 454 455 WKPageUIClient uiClient = { 456 0, /* version */ 457 this, /* clientInfo */ 458 qt_wk_createNewPage, 459 qt_wk_showPage, 460 qt_wk_close, 461 qt_wk_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 499 QWKPage::~QWKPage() 500 { 501 delete d; 502 } 503 504 QWKPage::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 516 QWKPage::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 529 QWKPage::ViewportAttributes::~ViewportAttributes() 530 { 531 532 } 533 534 QWKPage::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 550 QWKPage::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 578 void QWKPage::setActualVisibleContentsRect(const QRect& rect) const 579 { 580 #if ENABLE(TILED_BACKING_STORE) 581 d->page->setActualVisibleContentRect(rect); 582 #endif 583 } 584 585 void 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 594 WKPageRef QWKPage::pageRef() const 595 { 596 return toAPI(d->page.get()); 597 } 598 599 QWKContext* QWKPage::context() const 600 { 601 return d->context; 602 } 603 604 QWKPreferences* 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 614 void QWKPage::setCreateNewPageFunction(CreateNewPageFn function) 615 { 616 d->createNewPageFn = function; 617 } 618 619 void QWKPage::setCustomUserAgent(const QString& userAgent) 620 { 621 WKRetainPtr<WKStringRef> wkUserAgent(WKStringCreateWithQString(userAgent)); 622 WKPageSetCustomUserAgent(pageRef(), wkUserAgent.get()); 623 } 624 625 QString QWKPage::customUserAgent() const 626 { 627 return WKStringCopyQString(WKPageCopyCustomUserAgent(pageRef())); 628 } 629 630 void QWKPage::load(const QUrl& url) 631 { 632 WKRetainPtr<WKURLRef> wkurl(WKURLCreateWithQUrl(url)); 633 WKPageLoadURL(pageRef(), wkurl.get()); 634 } 635 636 void QWKPage::setUrl(const QUrl& url) 637 { 638 load(url); 639 } 640 641 QUrl QWKPage::url() const 642 { 643 WKRetainPtr<WKFrameRef> frame = WKPageGetMainFrame(pageRef()); 644 if (!frame) 645 return QUrl(); 646 return WKURLCopyQUrl(WKFrameCopyURL(frame.get())); 647 } 648 649 QString QWKPage::title() const 650 { 651 return WKStringCopyQString(WKPageCopyTitle(pageRef())); 652 } 653 654 void QWKPage::setViewportSize(const QSize& size) 655 { 656 if (d->page->drawingArea()) 657 d->page->drawingArea()->setSize(IntSize(size), IntSize()); 658 } 659 660 qreal QWKPage::textZoomFactor() const 661 { 662 return WKPageGetTextZoomFactor(pageRef()); 663 } 664 665 void QWKPage::setTextZoomFactor(qreal zoomFactor) 666 { 667 WKPageSetTextZoomFactor(pageRef(), zoomFactor); 668 } 669 670 qreal QWKPage::pageZoomFactor() const 671 { 672 return WKPageGetPageZoomFactor(pageRef()); 673 } 674 675 void QWKPage::setPageZoomFactor(qreal zoomFactor) 676 { 677 WKPageSetPageZoomFactor(pageRef(), zoomFactor); 678 } 679 680 void QWKPage::setPageAndTextZoomFactors(qreal pageZoomFactor, qreal textZoomFactor) 681 { 682 WKPageSetPageAndTextZoomFactors(pageRef(), pageZoomFactor, textZoomFactor); 683 } 684 685 QWKHistory* QWKPage::history() const 686 { 687 return d->history; 688 } 689 690 void 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 698 void 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 724 QAction* 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 800 void QWKPage::findZoomableAreaForPoint(const QPoint& point) 801 { 802 d->page->findZoomableAreaForPoint(point); 803 } 804 805 void QWKPagePrivate::didFindZoomableArea(const IntRect& area) 806 { 807 emit q->zoomableAreaFound(QRect(area)); 808 } 809 810 bool QWKPage::isConnectedToEngine() const 811 { 812 return d->isConnectedToEngine; 813 } 814 815 #include "moc_qwkpage.cpp" 816