1 /* 2 Copyright (C) 2008, 2009 Nokia Corporation and/or its subsidiary(-ies) 3 Copyright (C) 2007 Staikos Computing Services Inc. 4 Copyright (C) 2007 Apple Inc. 5 6 This library is free software; you can redistribute it and/or 7 modify it under the terms of the GNU Library General Public 8 License as published by the Free Software Foundation; either 9 version 2 of the License, or (at your option) any later version. 10 11 This library is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 Library General Public License for more details. 15 16 You should have received a copy of the GNU Library General Public License 17 along with this library; see the file COPYING.LIB. If not, write to 18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 Boston, MA 02110-1301, USA. 20 */ 21 22 #include "config.h" 23 #include "qwebpage.h" 24 #include "qwebview.h" 25 #include "qwebframe.h" 26 #include "qwebpage_p.h" 27 #include "qwebframe_p.h" 28 #include "qwebhistory.h" 29 #include "qwebhistory_p.h" 30 #include "qwebinspector.h" 31 #include "qwebinspector_p.h" 32 #include "qwebsettings.h" 33 #include "qwebkitversion.h" 34 35 #include "Chrome.h" 36 #include "ContextMenuController.h" 37 #include "Frame.h" 38 #include "FrameTree.h" 39 #include "FrameLoader.h" 40 #include "FrameLoaderClientQt.h" 41 #include "FrameView.h" 42 #include "FormState.h" 43 #include "ApplicationCacheStorage.h" 44 #include "ChromeClientQt.h" 45 #include "ContextMenu.h" 46 #include "ContextMenuClientQt.h" 47 #include "DocumentLoader.h" 48 #include "DragClientQt.h" 49 #include "DragController.h" 50 #include "DragData.h" 51 #include "EditorClientQt.h" 52 #include "SecurityOrigin.h" 53 #include "Settings.h" 54 #include "Page.h" 55 #include "Pasteboard.h" 56 #include "FrameLoader.h" 57 #include "FrameLoadRequest.h" 58 #include "KURL.h" 59 #include "Logging.h" 60 #include "Image.h" 61 #include "InspectorClientQt.h" 62 #include "InspectorController.h" 63 #include "FocusController.h" 64 #include "Editor.h" 65 #include "Scrollbar.h" 66 #include "PlatformKeyboardEvent.h" 67 #include "PlatformWheelEvent.h" 68 #include "PluginDatabase.h" 69 #include "ProgressTracker.h" 70 #include "RefPtr.h" 71 #include "RenderTextControl.h" 72 #include "TextIterator.h" 73 #include "HashMap.h" 74 #include "HTMLFormElement.h" 75 #include "HTMLInputElement.h" 76 #include "HTMLNames.h" 77 #include "HitTestResult.h" 78 #include "WindowFeatures.h" 79 #include "LocalizedStrings.h" 80 #include "Cache.h" 81 #include "runtime/InitializeThreading.h" 82 #include "PageGroup.h" 83 #include "QWebPageClient.h" 84 #include "WorkerThread.h" 85 86 #include <QApplication> 87 #include <QBasicTimer> 88 #include <QBitArray> 89 #include <QDebug> 90 #include <QDragEnterEvent> 91 #include <QDragLeaveEvent> 92 #include <QDragMoveEvent> 93 #include <QDropEvent> 94 #include <QFileDialog> 95 #include <QHttpRequestHeader> 96 #include <QInputDialog> 97 #include <QLocale> 98 #include <QMessageBox> 99 #include <QNetworkProxy> 100 #include <QUndoStack> 101 #include <QUrl> 102 #include <QPainter> 103 #include <QClipboard> 104 #include <QSslSocket> 105 #include <QStyle> 106 #include <QSysInfo> 107 #include <QTextCharFormat> 108 #include <QTextDocument> 109 #include <QNetworkAccessManager> 110 #include <QNetworkRequest> 111 #if defined(Q_WS_X11) 112 #include <QX11Info> 113 #endif 114 115 #if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) 116 #include <QTouchEvent> 117 #include "PlatformTouchEvent.h" 118 #endif 119 120 using namespace WebCore; 121 122 void QWEBKIT_EXPORT qt_drt_overwritePluginDirectories() 123 { 124 PluginDatabase* db = PluginDatabase::installedPlugins(/* populate */ false); 125 126 Vector<String> paths; 127 String qtPath(qgetenv("QTWEBKIT_PLUGIN_PATH").data()); 128 qtPath.split(UChar(':'), /* allowEmptyEntries */ false, paths); 129 130 db->setPluginDirectories(paths); 131 db->refresh(); 132 } 133 134 int QWEBKIT_EXPORT qt_drt_workerThreadCount() 135 { 136 #if ENABLE(WORKERS) 137 return WebCore::WorkerThread::workerThreadCount(); 138 #else 139 return 0; 140 #endif 141 } 142 143 bool QWebPagePrivate::drtRun = false; 144 void QWEBKIT_EXPORT qt_drt_run(bool b) 145 { 146 QWebPagePrivate::drtRun = b; 147 } 148 149 void QWEBKIT_EXPORT qt_drt_setFrameSetFlatteningEnabled(QWebPage* page, bool enabled) 150 { 151 QWebPagePrivate::core(page)->settings()->setFrameSetFlatteningEnabled(enabled); 152 } 153 154 void QWEBKIT_EXPORT qt_webpage_setGroupName(QWebPage* page, const QString& groupName) 155 { 156 page->handle()->page->setGroupName(groupName); 157 } 158 159 QString QWEBKIT_EXPORT qt_webpage_groupName(QWebPage* page) 160 { 161 return page->handle()->page->groupName(); 162 } 163 164 class QWebPageWidgetClient : public QWebPageClient { 165 public: 166 QWebPageWidgetClient(QWidget* view) 167 : view(view) 168 { 169 Q_ASSERT(view); 170 } 171 172 virtual void scroll(int dx, int dy, const QRect&); 173 virtual void update(const QRect& dirtyRect); 174 virtual void setInputMethodEnabled(bool enable); 175 virtual bool inputMethodEnabled() const; 176 #if QT_VERSION >= 0x040600 177 virtual void setInputMethodHint(Qt::InputMethodHint hint, bool enable); 178 #endif 179 180 #ifndef QT_NO_CURSOR 181 virtual QCursor cursor() const; 182 virtual void updateCursor(const QCursor& cursor); 183 #endif 184 185 virtual QPalette palette() const; 186 virtual int screenNumber() const; 187 virtual QWidget* ownerWidget() const; 188 189 virtual QObject* pluginParent() const; 190 191 virtual QStyle* style() const; 192 193 QWidget* view; 194 }; 195 196 void QWebPageWidgetClient::scroll(int dx, int dy, const QRect& rectToScroll) 197 { 198 view->scroll(qreal(dx), qreal(dy), rectToScroll); 199 } 200 201 void QWebPageWidgetClient::update(const QRect & dirtyRect) 202 { 203 view->update(dirtyRect); 204 } 205 206 void QWebPageWidgetClient::setInputMethodEnabled(bool enable) 207 { 208 view->setAttribute(Qt::WA_InputMethodEnabled, enable); 209 } 210 211 bool QWebPageWidgetClient::inputMethodEnabled() const 212 { 213 return view->testAttribute(Qt::WA_InputMethodEnabled); 214 } 215 216 #if QT_VERSION >= 0x040600 217 void QWebPageWidgetClient::setInputMethodHint(Qt::InputMethodHint hint, bool enable) 218 { 219 if (enable) 220 view->setInputMethodHints(view->inputMethodHints() | hint); 221 else 222 view->setInputMethodHints(view->inputMethodHints() & ~hint); 223 } 224 #endif 225 #ifndef QT_NO_CURSOR 226 QCursor QWebPageWidgetClient::cursor() const 227 { 228 return view->cursor(); 229 } 230 231 void QWebPageWidgetClient::updateCursor(const QCursor& cursor) 232 { 233 view->setCursor(cursor); 234 } 235 #endif 236 237 QPalette QWebPageWidgetClient::palette() const 238 { 239 return view->palette(); 240 } 241 242 int QWebPageWidgetClient::screenNumber() const 243 { 244 #if defined(Q_WS_X11) 245 if (view) 246 return view->x11Info().screen(); 247 #endif 248 249 return 0; 250 } 251 252 QWidget* QWebPageWidgetClient::ownerWidget() const 253 { 254 return view; 255 } 256 257 QObject* QWebPageWidgetClient::pluginParent() const 258 { 259 return view; 260 } 261 262 QStyle* QWebPageWidgetClient::style() const 263 { 264 return view->style(); 265 } 266 267 // Lookup table mapping QWebPage::WebActions to the associated Editor commands 268 static const char* editorCommandWebActions[] = 269 { 270 0, // OpenLink, 271 272 0, // OpenLinkInNewWindow, 273 0, // OpenFrameInNewWindow, 274 275 0, // DownloadLinkToDisk, 276 0, // CopyLinkToClipboard, 277 278 0, // OpenImageInNewWindow, 279 0, // DownloadImageToDisk, 280 0, // CopyImageToClipboard, 281 282 0, // Back, 283 0, // Forward, 284 0, // Stop, 285 0, // Reload, 286 287 "Cut", // Cut, 288 "Copy", // Copy, 289 "Paste", // Paste, 290 291 "Undo", // Undo, 292 "Redo", // Redo, 293 "MoveForward", // MoveToNextChar, 294 "MoveBackward", // MoveToPreviousChar, 295 "MoveWordForward", // MoveToNextWord, 296 "MoveWordBackward", // MoveToPreviousWord, 297 "MoveDown", // MoveToNextLine, 298 "MoveUp", // MoveToPreviousLine, 299 "MoveToBeginningOfLine", // MoveToStartOfLine, 300 "MoveToEndOfLine", // MoveToEndOfLine, 301 "MoveToBeginningOfParagraph", // MoveToStartOfBlock, 302 "MoveToEndOfParagraph", // MoveToEndOfBlock, 303 "MoveToBeginningOfDocument", // MoveToStartOfDocument, 304 "MoveToEndOfDocument", // MoveToEndOfDocument, 305 "MoveForwardAndModifySelection", // SelectNextChar, 306 "MoveBackwardAndModifySelection", // SelectPreviousChar, 307 "MoveWordForwardAndModifySelection", // SelectNextWord, 308 "MoveWordBackwardAndModifySelection", // SelectPreviousWord, 309 "MoveDownAndModifySelection", // SelectNextLine, 310 "MoveUpAndModifySelection", // SelectPreviousLine, 311 "MoveToBeginningOfLineAndModifySelection", // SelectStartOfLine, 312 "MoveToEndOfLineAndModifySelection", // SelectEndOfLine, 313 "MoveToBeginningOfParagraphAndModifySelection", // SelectStartOfBlock, 314 "MoveToEndOfParagraphAndModifySelection", // SelectEndOfBlock, 315 "MoveToBeginningOfDocumentAndModifySelection", //SelectStartOfDocument, 316 "MoveToEndOfDocumentAndModifySelection", // SelectEndOfDocument, 317 "DeleteWordBackward", // DeleteStartOfWord, 318 "DeleteWordForward", // DeleteEndOfWord, 319 320 0, // SetTextDirectionDefault, 321 0, // SetTextDirectionLeftToRight, 322 0, // SetTextDirectionRightToLeft, 323 324 "ToggleBold", // ToggleBold, 325 "ToggleItalic", // ToggleItalic, 326 "ToggleUnderline", // ToggleUnderline, 327 328 0, // InspectElement, 329 330 "InsertNewline", // InsertParagraphSeparator 331 "InsertLineBreak", // InsertLineSeparator 332 333 "SelectAll", // SelectAll 334 0, // ReloadAndBypassCache, 335 336 "PasteAndMatchStyle", // PasteAndMatchStyle 337 "RemoveFormat", // RemoveFormat 338 "Strikethrough", // ToggleStrikethrough, 339 "Subscript", // ToggleSubscript 340 "Superscript", // ToggleSuperscript 341 "InsertUnorderedList", // InsertUnorderedList 342 "InsertOrderedList", // InsertOrderedList 343 "Indent", // Indent 344 "Outdent", // Outdent, 345 346 "AlignCenter", // AlignCenter, 347 "AlignJustified", // AlignJustified, 348 "AlignLeft", // AlignLeft, 349 "AlignRight", // AlignRight, 350 351 0 // WebActionCount 352 }; 353 354 // Lookup the appropriate editor command to use for WebAction \a action 355 const char* QWebPagePrivate::editorCommandForWebActions(QWebPage::WebAction action) 356 { 357 if ((action > QWebPage::NoWebAction) && (action < int(sizeof(editorCommandWebActions) / sizeof(const char*)))) 358 return editorCommandWebActions[action]; 359 return 0; 360 } 361 362 // If you change this make sure to also adjust the docs for QWebPage::userAgentForUrl 363 #define WEBKIT_VERSION "527+" 364 365 static inline DragOperation dropActionToDragOp(Qt::DropActions actions) 366 { 367 unsigned result = 0; 368 if (actions & Qt::CopyAction) 369 result |= DragOperationCopy; 370 // DragOperationgeneric represents InternetExplorer's equivalent of Move operation, 371 // hence it should be considered as "move" 372 if (actions & Qt::MoveAction) 373 result |= (DragOperationMove | DragOperationGeneric); 374 if (actions & Qt::LinkAction) 375 result |= DragOperationLink; 376 return (DragOperation)result; 377 } 378 379 static inline Qt::DropAction dragOpToDropAction(unsigned actions) 380 { 381 Qt::DropAction result = Qt::IgnoreAction; 382 if (actions & DragOperationCopy) 383 result = Qt::CopyAction; 384 else if (actions & DragOperationMove) 385 result = Qt::MoveAction; 386 // DragOperationgeneric represents InternetExplorer's equivalent of Move operation, 387 // hence it should be considered as "move" 388 else if (actions & DragOperationGeneric) 389 result = Qt::MoveAction; 390 else if (actions & DragOperationLink) 391 result = Qt::LinkAction; 392 return result; 393 } 394 395 QWebPagePrivate::QWebPagePrivate(QWebPage *qq) 396 : q(qq) 397 , client(0) 398 #if QT_VERSION < 0x040600 399 , view(0) 400 #endif 401 , clickCausedFocus(false) 402 , viewportSize(QSize(0, 0)) 403 , inspectorFrontend(0) 404 , inspector(0) 405 , inspectorIsInternalOnly(false) 406 { 407 WebCore::InitializeLoggingChannelsIfNecessary(); 408 JSC::initializeThreading(); 409 WebCore::SecurityOrigin::setLocalLoadPolicy(WebCore::SecurityOrigin::AllowLocalLoadsForLocalAndSubstituteData); 410 411 chromeClient = new ChromeClientQt(q); 412 contextMenuClient = new ContextMenuClientQt(); 413 editorClient = new EditorClientQt(q); 414 page = new Page(chromeClient, contextMenuClient, editorClient, 415 new DragClientQt(q), new InspectorClientQt(q), 0, 0); 416 417 settings = new QWebSettings(page->settings()); 418 419 #ifndef QT_NO_UNDOSTACK 420 undoStack = 0; 421 #endif 422 mainFrame = 0; 423 networkManager = 0; 424 pluginFactory = 0; 425 insideOpenCall = false; 426 forwardUnsupportedContent = false; 427 editable = false; 428 useFixedLayout = false; 429 linkPolicy = QWebPage::DontDelegateLinks; 430 #ifndef QT_NO_CONTEXTMENU 431 currentContextMenu = 0; 432 #endif 433 434 history.d = new QWebHistoryPrivate(page->backForwardList()); 435 memset(actions, 0, sizeof(actions)); 436 437 PageGroup::setShouldTrackVisitedLinks(true); 438 } 439 440 QWebPagePrivate::~QWebPagePrivate() 441 { 442 #ifndef QT_NO_CONTEXTMENU 443 delete currentContextMenu; 444 #endif 445 #ifndef QT_NO_UNDOSTACK 446 delete undoStack; 447 #endif 448 delete settings; 449 delete page; 450 } 451 452 WebCore::Page* QWebPagePrivate::core(QWebPage* page) 453 { 454 return page->d->page; 455 } 456 457 bool QWebPagePrivate::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type) 458 { 459 if (insideOpenCall 460 && frame == mainFrame) 461 return true; 462 return q->acceptNavigationRequest(frame, request, type); 463 } 464 465 void QWebPagePrivate::createMainFrame() 466 { 467 if (!mainFrame) { 468 QWebFrameData frameData(page); 469 mainFrame = new QWebFrame(q, &frameData); 470 471 emit q->frameCreated(mainFrame); 472 } 473 } 474 475 static QWebPage::WebAction webActionForContextMenuAction(WebCore::ContextMenuAction action) 476 { 477 switch (action) { 478 case WebCore::ContextMenuItemTagOpenLink: return QWebPage::OpenLink; 479 case WebCore::ContextMenuItemTagOpenLinkInNewWindow: return QWebPage::OpenLinkInNewWindow; 480 case WebCore::ContextMenuItemTagDownloadLinkToDisk: return QWebPage::DownloadLinkToDisk; 481 case WebCore::ContextMenuItemTagCopyLinkToClipboard: return QWebPage::CopyLinkToClipboard; 482 case WebCore::ContextMenuItemTagOpenImageInNewWindow: return QWebPage::OpenImageInNewWindow; 483 case WebCore::ContextMenuItemTagDownloadImageToDisk: return QWebPage::DownloadImageToDisk; 484 case WebCore::ContextMenuItemTagCopyImageToClipboard: return QWebPage::CopyImageToClipboard; 485 case WebCore::ContextMenuItemTagOpenFrameInNewWindow: return QWebPage::OpenFrameInNewWindow; 486 case WebCore::ContextMenuItemTagCopy: return QWebPage::Copy; 487 case WebCore::ContextMenuItemTagGoBack: return QWebPage::Back; 488 case WebCore::ContextMenuItemTagGoForward: return QWebPage::Forward; 489 case WebCore::ContextMenuItemTagStop: return QWebPage::Stop; 490 case WebCore::ContextMenuItemTagReload: return QWebPage::Reload; 491 case WebCore::ContextMenuItemTagCut: return QWebPage::Cut; 492 case WebCore::ContextMenuItemTagPaste: return QWebPage::Paste; 493 case WebCore::ContextMenuItemTagDefaultDirection: return QWebPage::SetTextDirectionDefault; 494 case WebCore::ContextMenuItemTagLeftToRight: return QWebPage::SetTextDirectionLeftToRight; 495 case WebCore::ContextMenuItemTagRightToLeft: return QWebPage::SetTextDirectionRightToLeft; 496 case WebCore::ContextMenuItemTagBold: return QWebPage::ToggleBold; 497 case WebCore::ContextMenuItemTagItalic: return QWebPage::ToggleItalic; 498 case WebCore::ContextMenuItemTagUnderline: return QWebPage::ToggleUnderline; 499 #if ENABLE(INSPECTOR) 500 case WebCore::ContextMenuItemTagInspectElement: return QWebPage::InspectElement; 501 #endif 502 default: break; 503 } 504 return QWebPage::NoWebAction; 505 } 506 507 #ifndef QT_NO_CONTEXTMENU 508 QMenu *QWebPagePrivate::createContextMenu(const WebCore::ContextMenu *webcoreMenu, 509 const QList<WebCore::ContextMenuItem> *items, QBitArray *visitedWebActions) 510 { 511 QMenu* menu = new QMenu(q->view()); 512 for (int i = 0; i < items->count(); ++i) { 513 const ContextMenuItem &item = items->at(i); 514 switch (item.type()) { 515 case WebCore::CheckableActionType: /* fall through */ 516 case WebCore::ActionType: { 517 QWebPage::WebAction action = webActionForContextMenuAction(item.action()); 518 QAction *a = q->action(action); 519 if (a) { 520 ContextMenuItem it(item); 521 webcoreMenu->checkOrEnableIfNeeded(it); 522 PlatformMenuItemDescription desc = it.releasePlatformDescription(); 523 a->setEnabled(desc.enabled); 524 a->setChecked(desc.checked); 525 a->setCheckable(item.type() == WebCore::CheckableActionType); 526 527 menu->addAction(a); 528 visitedWebActions->setBit(action); 529 } 530 break; 531 } 532 case WebCore::SeparatorType: 533 menu->addSeparator(); 534 break; 535 case WebCore::SubmenuType: { 536 QMenu *subMenu = createContextMenu(webcoreMenu, item.platformSubMenu(), visitedWebActions); 537 538 bool anyEnabledAction = false; 539 540 QList<QAction *> actions = subMenu->actions(); 541 for (int i = 0; i < actions.count(); ++i) { 542 if (actions.at(i)->isVisible()) 543 anyEnabledAction |= actions.at(i)->isEnabled(); 544 } 545 546 // don't show sub-menus with just disabled actions 547 if (anyEnabledAction) { 548 subMenu->setTitle(item.title()); 549 menu->addAction(subMenu->menuAction()); 550 } else 551 delete subMenu; 552 break; 553 } 554 } 555 } 556 return menu; 557 } 558 #endif // QT_NO_CONTEXTMENU 559 560 void QWebPagePrivate::_q_webActionTriggered(bool checked) 561 { 562 QAction *a = qobject_cast<QAction *>(q->sender()); 563 if (!a) 564 return; 565 QWebPage::WebAction action = static_cast<QWebPage::WebAction>(a->data().toInt()); 566 q->triggerAction(action, checked); 567 } 568 569 void QWebPagePrivate::_q_cleanupLeakMessages() 570 { 571 #ifndef NDEBUG 572 // Need this to make leak messages accurate. 573 cache()->setCapacities(0, 0, 0); 574 #endif 575 } 576 577 void QWebPagePrivate::updateAction(QWebPage::WebAction action) 578 { 579 QAction *a = actions[action]; 580 if (!a || !mainFrame) 581 return; 582 583 WebCore::FrameLoader *loader = mainFrame->d->frame->loader(); 584 WebCore::Editor *editor = page->focusController()->focusedOrMainFrame()->editor(); 585 586 bool enabled = a->isEnabled(); 587 bool checked = a->isChecked(); 588 589 switch (action) { 590 case QWebPage::Back: 591 enabled = page->canGoBackOrForward(-1); 592 break; 593 case QWebPage::Forward: 594 enabled = page->canGoBackOrForward(1); 595 break; 596 case QWebPage::Stop: 597 enabled = loader->isLoading(); 598 break; 599 case QWebPage::Reload: 600 case QWebPage::ReloadAndBypassCache: 601 enabled = !loader->isLoading(); 602 break; 603 #ifndef QT_NO_UNDOSTACK 604 case QWebPage::Undo: 605 case QWebPage::Redo: 606 // those two are handled by QUndoStack 607 break; 608 #endif // QT_NO_UNDOSTACK 609 case QWebPage::SelectAll: // editor command is always enabled 610 break; 611 case QWebPage::SetTextDirectionDefault: 612 case QWebPage::SetTextDirectionLeftToRight: 613 case QWebPage::SetTextDirectionRightToLeft: 614 enabled = editor->canEdit(); 615 checked = false; 616 break; 617 default: { 618 // see if it's an editor command 619 const char* commandName = editorCommandForWebActions(action); 620 621 // if it's an editor command, let it's logic determine state 622 if (commandName) { 623 Editor::Command command = editor->command(commandName); 624 enabled = command.isEnabled(); 625 if (enabled) 626 checked = command.state() != FalseTriState; 627 else 628 checked = false; 629 } 630 break; 631 } 632 } 633 634 a->setEnabled(enabled); 635 636 if (a->isCheckable()) 637 a->setChecked(checked); 638 } 639 640 void QWebPagePrivate::updateNavigationActions() 641 { 642 updateAction(QWebPage::Back); 643 updateAction(QWebPage::Forward); 644 updateAction(QWebPage::Stop); 645 updateAction(QWebPage::Reload); 646 updateAction(QWebPage::ReloadAndBypassCache); 647 } 648 649 void QWebPagePrivate::updateEditorActions() 650 { 651 updateAction(QWebPage::Cut); 652 updateAction(QWebPage::Copy); 653 updateAction(QWebPage::Paste); 654 updateAction(QWebPage::MoveToNextChar); 655 updateAction(QWebPage::MoveToPreviousChar); 656 updateAction(QWebPage::MoveToNextWord); 657 updateAction(QWebPage::MoveToPreviousWord); 658 updateAction(QWebPage::MoveToNextLine); 659 updateAction(QWebPage::MoveToPreviousLine); 660 updateAction(QWebPage::MoveToStartOfLine); 661 updateAction(QWebPage::MoveToEndOfLine); 662 updateAction(QWebPage::MoveToStartOfBlock); 663 updateAction(QWebPage::MoveToEndOfBlock); 664 updateAction(QWebPage::MoveToStartOfDocument); 665 updateAction(QWebPage::MoveToEndOfDocument); 666 updateAction(QWebPage::SelectNextChar); 667 updateAction(QWebPage::SelectPreviousChar); 668 updateAction(QWebPage::SelectNextWord); 669 updateAction(QWebPage::SelectPreviousWord); 670 updateAction(QWebPage::SelectNextLine); 671 updateAction(QWebPage::SelectPreviousLine); 672 updateAction(QWebPage::SelectStartOfLine); 673 updateAction(QWebPage::SelectEndOfLine); 674 updateAction(QWebPage::SelectStartOfBlock); 675 updateAction(QWebPage::SelectEndOfBlock); 676 updateAction(QWebPage::SelectStartOfDocument); 677 updateAction(QWebPage::SelectEndOfDocument); 678 updateAction(QWebPage::DeleteStartOfWord); 679 updateAction(QWebPage::DeleteEndOfWord); 680 updateAction(QWebPage::SetTextDirectionDefault); 681 updateAction(QWebPage::SetTextDirectionLeftToRight); 682 updateAction(QWebPage::SetTextDirectionRightToLeft); 683 updateAction(QWebPage::ToggleBold); 684 updateAction(QWebPage::ToggleItalic); 685 updateAction(QWebPage::ToggleUnderline); 686 updateAction(QWebPage::InsertParagraphSeparator); 687 updateAction(QWebPage::InsertLineSeparator); 688 updateAction(QWebPage::PasteAndMatchStyle); 689 updateAction(QWebPage::RemoveFormat); 690 updateAction(QWebPage::ToggleStrikethrough); 691 updateAction(QWebPage::ToggleSubscript); 692 updateAction(QWebPage::ToggleSuperscript); 693 updateAction(QWebPage::InsertUnorderedList); 694 updateAction(QWebPage::InsertOrderedList); 695 updateAction(QWebPage::Indent); 696 updateAction(QWebPage::Outdent); 697 updateAction(QWebPage::AlignCenter); 698 updateAction(QWebPage::AlignJustified); 699 updateAction(QWebPage::AlignLeft); 700 updateAction(QWebPage::AlignRight); 701 } 702 703 void QWebPagePrivate::timerEvent(QTimerEvent *ev) 704 { 705 int timerId = ev->timerId(); 706 if (timerId == tripleClickTimer.timerId()) 707 tripleClickTimer.stop(); 708 else 709 q->QObject::timerEvent(ev); 710 } 711 712 void QWebPagePrivate::mouseMoveEvent(QGraphicsSceneMouseEvent* ev) 713 { 714 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); 715 if (!frame->view()) 716 return; 717 718 bool accepted = frame->eventHandler()->mouseMoved(PlatformMouseEvent(ev, 0)); 719 ev->setAccepted(accepted); 720 } 721 722 void QWebPagePrivate::mouseMoveEvent(QMouseEvent *ev) 723 { 724 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); 725 if (!frame->view()) 726 return; 727 728 bool accepted = frame->eventHandler()->mouseMoved(PlatformMouseEvent(ev, 0)); 729 ev->setAccepted(accepted); 730 } 731 732 void QWebPagePrivate::mousePressEvent(QGraphicsSceneMouseEvent* ev) 733 { 734 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); 735 if (!frame->view()) 736 return; 737 738 if (tripleClickTimer.isActive() 739 && (ev->pos().toPoint() - tripleClick).manhattanLength() 740 < QApplication::startDragDistance()) { 741 mouseTripleClickEvent(ev); 742 return; 743 } 744 745 bool accepted = false; 746 PlatformMouseEvent mev(ev, 1); 747 // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton 748 if (mev.button() != NoButton) 749 accepted = frame->eventHandler()->handleMousePressEvent(mev); 750 ev->setAccepted(accepted); 751 } 752 753 void QWebPagePrivate::mousePressEvent(QMouseEvent *ev) 754 { 755 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); 756 if (!frame->view()) 757 return; 758 759 RefPtr<WebCore::Node> oldNode; 760 if (page->focusController()->focusedFrame() 761 && page->focusController()->focusedFrame()->document()) 762 oldNode = page->focusController()->focusedFrame()->document()->focusedNode(); 763 764 if (tripleClickTimer.isActive() 765 && (ev->pos() - tripleClick).manhattanLength() 766 < QApplication::startDragDistance()) { 767 mouseTripleClickEvent(ev); 768 return; 769 } 770 771 bool accepted = false; 772 PlatformMouseEvent mev(ev, 1); 773 // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton 774 if (mev.button() != NoButton) 775 accepted = frame->eventHandler()->handleMousePressEvent(mev); 776 ev->setAccepted(accepted); 777 778 RefPtr<WebCore::Node> newNode; 779 if (page->focusController()->focusedFrame() 780 && page->focusController()->focusedFrame()->document()) 781 newNode = page->focusController()->focusedFrame()->document()->focusedNode(); 782 783 if (newNode && oldNode != newNode) 784 clickCausedFocus = true; 785 } 786 787 void QWebPagePrivate::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *ev) 788 { 789 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); 790 if (!frame->view()) 791 return; 792 793 bool accepted = false; 794 PlatformMouseEvent mev(ev, 2); 795 // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton 796 if (mev.button() != NoButton) 797 accepted = frame->eventHandler()->handleMousePressEvent(mev); 798 ev->setAccepted(accepted); 799 800 tripleClickTimer.start(QApplication::doubleClickInterval(), q); 801 tripleClick = ev->pos().toPoint(); 802 } 803 804 void QWebPagePrivate::mouseDoubleClickEvent(QMouseEvent *ev) 805 { 806 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); 807 if (!frame->view()) 808 return; 809 810 bool accepted = false; 811 PlatformMouseEvent mev(ev, 2); 812 // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton 813 if (mev.button() != NoButton) 814 accepted = frame->eventHandler()->handleMousePressEvent(mev); 815 ev->setAccepted(accepted); 816 817 tripleClickTimer.start(QApplication::doubleClickInterval(), q); 818 tripleClick = ev->pos(); 819 } 820 821 void QWebPagePrivate::mouseTripleClickEvent(QGraphicsSceneMouseEvent *ev) 822 { 823 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); 824 if (!frame->view()) 825 return; 826 827 bool accepted = false; 828 PlatformMouseEvent mev(ev, 3); 829 // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton 830 if (mev.button() != NoButton) 831 accepted = frame->eventHandler()->handleMousePressEvent(mev); 832 ev->setAccepted(accepted); 833 } 834 835 void QWebPagePrivate::mouseTripleClickEvent(QMouseEvent *ev) 836 { 837 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); 838 if (!frame->view()) 839 return; 840 841 bool accepted = false; 842 PlatformMouseEvent mev(ev, 3); 843 // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton 844 if (mev.button() != NoButton) 845 accepted = frame->eventHandler()->handleMousePressEvent(mev); 846 ev->setAccepted(accepted); 847 } 848 849 void QWebPagePrivate::handleClipboard(QEvent* ev, Qt::MouseButton button) 850 { 851 #ifndef QT_NO_CLIPBOARD 852 if (QApplication::clipboard()->supportsSelection()) { 853 bool oldSelectionMode = Pasteboard::generalPasteboard()->isSelectionMode(); 854 Pasteboard::generalPasteboard()->setSelectionMode(true); 855 WebCore::Frame* focusFrame = page->focusController()->focusedOrMainFrame(); 856 if (button == Qt::LeftButton) { 857 if (focusFrame && (focusFrame->editor()->canCopy() || focusFrame->editor()->canDHTMLCopy())) { 858 focusFrame->editor()->copy(); 859 ev->setAccepted(true); 860 } 861 } else if (button == Qt::MidButton) { 862 if (focusFrame && (focusFrame->editor()->canPaste() || focusFrame->editor()->canDHTMLPaste())) { 863 focusFrame->editor()->paste(); 864 ev->setAccepted(true); 865 } 866 } 867 Pasteboard::generalPasteboard()->setSelectionMode(oldSelectionMode); 868 } 869 #endif 870 } 871 872 void QWebPagePrivate::mouseReleaseEvent(QGraphicsSceneMouseEvent* ev) 873 { 874 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); 875 if (!frame->view()) 876 return; 877 878 bool accepted = false; 879 PlatformMouseEvent mev(ev, 0); 880 // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton 881 if (mev.button() != NoButton) 882 accepted = frame->eventHandler()->handleMouseReleaseEvent(mev); 883 ev->setAccepted(accepted); 884 885 handleClipboard(ev, ev->button()); 886 handleSoftwareInputPanel(ev->button()); 887 } 888 889 void QWebPagePrivate::handleSoftwareInputPanel(Qt::MouseButton button) 890 { 891 #if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) 892 Frame* frame = page->focusController()->focusedFrame(); 893 if (!frame) 894 return; 895 896 if (client && client->inputMethodEnabled() 897 && frame->document()->focusedNode() 898 && button == Qt::LeftButton && qApp->autoSipEnabled()) { 899 QStyle::RequestSoftwareInputPanel behavior = QStyle::RequestSoftwareInputPanel( 900 client->ownerWidget()->style()->styleHint(QStyle::SH_RequestSoftwareInputPanel)); 901 if (!clickCausedFocus || behavior == QStyle::RSIP_OnMouseClick) { 902 QEvent event(QEvent::RequestSoftwareInputPanel); 903 QApplication::sendEvent(client->ownerWidget(), &event); 904 } 905 } 906 907 clickCausedFocus = false; 908 #endif 909 } 910 911 void QWebPagePrivate::mouseReleaseEvent(QMouseEvent *ev) 912 { 913 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); 914 if (!frame->view()) 915 return; 916 917 bool accepted = false; 918 PlatformMouseEvent mev(ev, 0); 919 // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton 920 if (mev.button() != NoButton) 921 accepted = frame->eventHandler()->handleMouseReleaseEvent(mev); 922 ev->setAccepted(accepted); 923 924 handleClipboard(ev, ev->button()); 925 handleSoftwareInputPanel(ev->button()); 926 } 927 928 #ifndef QT_NO_CONTEXTMENU 929 void QWebPagePrivate::contextMenuEvent(const QPoint& globalPos) 930 { 931 QMenu *menu = q->createStandardContextMenu(); 932 if (menu) { 933 menu->exec(globalPos); 934 delete menu; 935 } 936 } 937 #endif // QT_NO_CONTEXTMENU 938 939 /*! 940 \since 4.5 941 This function creates the standard context menu which is shown when 942 the user clicks on the web page with the right mouse button. It is 943 called from the default contextMenuEvent() handler. The popup menu's 944 ownership is transferred to the caller. 945 */ 946 QMenu *QWebPage::createStandardContextMenu() 947 { 948 #ifndef QT_NO_CONTEXTMENU 949 QMenu *menu = d->currentContextMenu; 950 d->currentContextMenu = 0; 951 return menu; 952 #else 953 return 0; 954 #endif 955 } 956 957 #ifndef QT_NO_WHEELEVENT 958 void QWebPagePrivate::wheelEvent(QGraphicsSceneWheelEvent* ev) 959 { 960 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); 961 if (!frame->view()) 962 return; 963 964 WebCore::PlatformWheelEvent pev(ev); 965 bool accepted = frame->eventHandler()->handleWheelEvent(pev); 966 ev->setAccepted(accepted); 967 } 968 969 void QWebPagePrivate::wheelEvent(QWheelEvent *ev) 970 { 971 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); 972 if (!frame->view()) 973 return; 974 975 WebCore::PlatformWheelEvent pev(ev); 976 bool accepted = frame->eventHandler()->handleWheelEvent(pev); 977 ev->setAccepted(accepted); 978 } 979 #endif // QT_NO_WHEELEVENT 980 981 #ifndef QT_NO_SHORTCUT 982 QWebPage::WebAction QWebPagePrivate::editorActionForKeyEvent(QKeyEvent* event) 983 { 984 static struct { 985 QKeySequence::StandardKey standardKey; 986 QWebPage::WebAction action; 987 } editorActions[] = { 988 { QKeySequence::Cut, QWebPage::Cut }, 989 { QKeySequence::Copy, QWebPage::Copy }, 990 { QKeySequence::Paste, QWebPage::Paste }, 991 { QKeySequence::Undo, QWebPage::Undo }, 992 { QKeySequence::Redo, QWebPage::Redo }, 993 { QKeySequence::MoveToNextChar, QWebPage::MoveToNextChar }, 994 { QKeySequence::MoveToPreviousChar, QWebPage::MoveToPreviousChar }, 995 { QKeySequence::MoveToNextWord, QWebPage::MoveToNextWord }, 996 { QKeySequence::MoveToPreviousWord, QWebPage::MoveToPreviousWord }, 997 { QKeySequence::MoveToNextLine, QWebPage::MoveToNextLine }, 998 { QKeySequence::MoveToPreviousLine, QWebPage::MoveToPreviousLine }, 999 { QKeySequence::MoveToStartOfLine, QWebPage::MoveToStartOfLine }, 1000 { QKeySequence::MoveToEndOfLine, QWebPage::MoveToEndOfLine }, 1001 { QKeySequence::MoveToStartOfBlock, QWebPage::MoveToStartOfBlock }, 1002 { QKeySequence::MoveToEndOfBlock, QWebPage::MoveToEndOfBlock }, 1003 { QKeySequence::MoveToStartOfDocument, QWebPage::MoveToStartOfDocument }, 1004 { QKeySequence::MoveToEndOfDocument, QWebPage::MoveToEndOfDocument }, 1005 { QKeySequence::SelectNextChar, QWebPage::SelectNextChar }, 1006 { QKeySequence::SelectPreviousChar, QWebPage::SelectPreviousChar }, 1007 { QKeySequence::SelectNextWord, QWebPage::SelectNextWord }, 1008 { QKeySequence::SelectPreviousWord, QWebPage::SelectPreviousWord }, 1009 { QKeySequence::SelectNextLine, QWebPage::SelectNextLine }, 1010 { QKeySequence::SelectPreviousLine, QWebPage::SelectPreviousLine }, 1011 { QKeySequence::SelectStartOfLine, QWebPage::SelectStartOfLine }, 1012 { QKeySequence::SelectEndOfLine, QWebPage::SelectEndOfLine }, 1013 { QKeySequence::SelectStartOfBlock, QWebPage::SelectStartOfBlock }, 1014 { QKeySequence::SelectEndOfBlock, QWebPage::SelectEndOfBlock }, 1015 { QKeySequence::SelectStartOfDocument, QWebPage::SelectStartOfDocument }, 1016 { QKeySequence::SelectEndOfDocument, QWebPage::SelectEndOfDocument }, 1017 { QKeySequence::DeleteStartOfWord, QWebPage::DeleteStartOfWord }, 1018 { QKeySequence::DeleteEndOfWord, QWebPage::DeleteEndOfWord }, 1019 #if QT_VERSION >= 0x040500 1020 { QKeySequence::InsertParagraphSeparator, QWebPage::InsertParagraphSeparator }, 1021 { QKeySequence::InsertLineSeparator, QWebPage::InsertLineSeparator }, 1022 #endif 1023 { QKeySequence::SelectAll, QWebPage::SelectAll }, 1024 { QKeySequence::UnknownKey, QWebPage::NoWebAction } 1025 }; 1026 1027 for (int i = 0; editorActions[i].standardKey != QKeySequence::UnknownKey; ++i) 1028 if (event == editorActions[i].standardKey) 1029 return editorActions[i].action; 1030 1031 return QWebPage::NoWebAction; 1032 } 1033 #endif // QT_NO_SHORTCUT 1034 1035 void QWebPagePrivate::keyPressEvent(QKeyEvent *ev) 1036 { 1037 bool handled = false; 1038 WebCore::Frame* frame = page->focusController()->focusedOrMainFrame(); 1039 // we forward the key event to WebCore first to handle potential DOM 1040 // defined event handlers and later on end up in EditorClientQt::handleKeyboardEvent 1041 // to trigger editor commands via triggerAction(). 1042 if (!handled) 1043 handled = frame->eventHandler()->keyEvent(ev); 1044 if (!handled) { 1045 handled = true; 1046 QFont defaultFont; 1047 if (q->view()) 1048 defaultFont = q->view()->font(); 1049 QFontMetrics fm(defaultFont); 1050 if (!handleScrolling(ev, frame)) { 1051 switch (ev->key()) { 1052 case Qt::Key_Back: 1053 q->triggerAction(QWebPage::Back); 1054 break; 1055 case Qt::Key_Forward: 1056 q->triggerAction(QWebPage::Forward); 1057 break; 1058 case Qt::Key_Stop: 1059 q->triggerAction(QWebPage::Stop); 1060 break; 1061 case Qt::Key_Refresh: 1062 q->triggerAction(QWebPage::Reload); 1063 break; 1064 case Qt::Key_Backspace: 1065 if (ev->modifiers() == Qt::ShiftModifier) 1066 q->triggerAction(QWebPage::Forward); 1067 else 1068 q->triggerAction(QWebPage::Back); 1069 break; 1070 default: 1071 handled = false; 1072 break; 1073 } 1074 } 1075 } 1076 1077 ev->setAccepted(handled); 1078 } 1079 1080 void QWebPagePrivate::keyReleaseEvent(QKeyEvent *ev) 1081 { 1082 if (ev->isAutoRepeat()) { 1083 ev->setAccepted(true); 1084 return; 1085 } 1086 1087 WebCore::Frame* frame = page->focusController()->focusedOrMainFrame(); 1088 bool handled = frame->eventHandler()->keyEvent(ev); 1089 ev->setAccepted(handled); 1090 } 1091 1092 void QWebPagePrivate::focusInEvent(QFocusEvent*) 1093 { 1094 FocusController *focusController = page->focusController(); 1095 focusController->setActive(true); 1096 focusController->setFocused(true); 1097 if (!focusController->focusedFrame()) 1098 focusController->setFocusedFrame(QWebFramePrivate::core(mainFrame)); 1099 } 1100 1101 void QWebPagePrivate::focusOutEvent(QFocusEvent*) 1102 { 1103 // only set the focused frame inactive so that we stop painting the caret 1104 // and the focus frame. But don't tell the focus controller so that upon 1105 // focusInEvent() we can re-activate the frame. 1106 FocusController *focusController = page->focusController(); 1107 // Call setFocused first so that window.onblur doesn't get called twice 1108 focusController->setFocused(false); 1109 focusController->setActive(false); 1110 } 1111 1112 void QWebPagePrivate::dragEnterEvent(QGraphicsSceneDragDropEvent* ev) 1113 { 1114 #ifndef QT_NO_DRAGANDDROP 1115 DragData dragData(ev->mimeData(), ev->pos().toPoint(), 1116 QCursor::pos(), dropActionToDragOp(ev->possibleActions())); 1117 Qt::DropAction action = dragOpToDropAction(page->dragController()->dragEntered(&dragData)); 1118 ev->setDropAction(action); 1119 if (action != Qt::IgnoreAction) 1120 ev->accept(); 1121 #endif 1122 } 1123 1124 void QWebPagePrivate::dragEnterEvent(QDragEnterEvent* ev) 1125 { 1126 #ifndef QT_NO_DRAGANDDROP 1127 DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), 1128 dropActionToDragOp(ev->possibleActions())); 1129 Qt::DropAction action = dragOpToDropAction(page->dragController()->dragEntered(&dragData)); 1130 ev->setDropAction(action); 1131 // We must accept this event in order to receive the drag move events that are sent 1132 // while the drag and drop action is in progress. 1133 ev->accept(); 1134 #endif 1135 } 1136 1137 void QWebPagePrivate::dragLeaveEvent(QGraphicsSceneDragDropEvent* ev) 1138 { 1139 #ifndef QT_NO_DRAGANDDROP 1140 DragData dragData(0, IntPoint(), QCursor::pos(), DragOperationNone); 1141 page->dragController()->dragExited(&dragData); 1142 ev->accept(); 1143 #endif 1144 } 1145 1146 void QWebPagePrivate::dragLeaveEvent(QDragLeaveEvent* ev) 1147 { 1148 #ifndef QT_NO_DRAGANDDROP 1149 DragData dragData(0, IntPoint(), QCursor::pos(), DragOperationNone); 1150 page->dragController()->dragExited(&dragData); 1151 ev->accept(); 1152 #endif 1153 } 1154 1155 void QWebPagePrivate::dragMoveEvent(QGraphicsSceneDragDropEvent* ev) 1156 { 1157 #ifndef QT_NO_DRAGANDDROP 1158 DragData dragData(ev->mimeData(), ev->pos().toPoint(), 1159 QCursor::pos(), dropActionToDragOp(ev->possibleActions())); 1160 Qt::DropAction action = dragOpToDropAction(page->dragController()->dragUpdated(&dragData)); 1161 ev->setDropAction(action); 1162 if (action != Qt::IgnoreAction) 1163 ev->accept(); 1164 #endif 1165 } 1166 1167 void QWebPagePrivate::dragMoveEvent(QDragMoveEvent* ev) 1168 { 1169 #ifndef QT_NO_DRAGANDDROP 1170 DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), 1171 dropActionToDragOp(ev->possibleActions())); 1172 Qt::DropAction action = dragOpToDropAction(page->dragController()->dragUpdated(&dragData)); 1173 m_lastDropAction = action; 1174 ev->setDropAction(action); 1175 // We must accept this event in order to receive the drag move events that are sent 1176 // while the drag and drop action is in progress. 1177 ev->accept(); 1178 #endif 1179 } 1180 1181 void QWebPagePrivate::dropEvent(QGraphicsSceneDragDropEvent* ev) 1182 { 1183 #ifndef QT_NO_DRAGANDDROP 1184 DragData dragData(ev->mimeData(), ev->pos().toPoint(), 1185 QCursor::pos(), dropActionToDragOp(ev->possibleActions())); 1186 if (page->dragController()->performDrag(&dragData)) 1187 ev->accept(); 1188 #endif 1189 } 1190 1191 void QWebPagePrivate::dropEvent(QDropEvent* ev) 1192 { 1193 #ifndef QT_NO_DRAGANDDROP 1194 // Overwrite the defaults set by QDragManager::defaultAction() 1195 ev->setDropAction(m_lastDropAction); 1196 DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), 1197 dropActionToDragOp(Qt::DropAction(ev->dropAction()))); 1198 if (page->dragController()->performDrag(&dragData)) 1199 ev->accept(); 1200 #endif 1201 } 1202 1203 void QWebPagePrivate::leaveEvent(QEvent*) 1204 { 1205 // Fake a mouse move event just outside of the widget, since all 1206 // the interesting mouse-out behavior like invalidating scrollbars 1207 // is handled by the WebKit event handler's mouseMoved function. 1208 QMouseEvent fakeEvent(QEvent::MouseMove, QCursor::pos(), Qt::NoButton, Qt::NoButton, Qt::NoModifier); 1209 mouseMoveEvent(&fakeEvent); 1210 } 1211 1212 /*! 1213 \property QWebPage::palette 1214 \brief the page's palette 1215 1216 The base brush of the palette is used to draw the background of the main frame. 1217 1218 By default, this property contains the application's default palette. 1219 */ 1220 void QWebPage::setPalette(const QPalette &pal) 1221 { 1222 d->palette = pal; 1223 if (!d->mainFrame || !d->mainFrame->d->frame->view()) 1224 return; 1225 1226 QBrush brush = pal.brush(QPalette::Base); 1227 QColor backgroundColor = brush.style() == Qt::SolidPattern ? brush.color() : QColor(); 1228 QWebFramePrivate::core(d->mainFrame)->view()->updateBackgroundRecursively(backgroundColor, !backgroundColor.alpha()); 1229 } 1230 1231 QPalette QWebPage::palette() const 1232 { 1233 return d->palette; 1234 } 1235 1236 void QWebPagePrivate::inputMethodEvent(QInputMethodEvent *ev) 1237 { 1238 WebCore::Frame *frame = page->focusController()->focusedOrMainFrame(); 1239 WebCore::Editor *editor = frame->editor(); 1240 1241 if (!editor->canEdit()) { 1242 ev->ignore(); 1243 return; 1244 } 1245 1246 RenderObject* renderer = 0; 1247 RenderTextControl* renderTextControl = 0; 1248 1249 if (frame->selection()->rootEditableElement()) 1250 renderer = frame->selection()->rootEditableElement()->shadowAncestorNode()->renderer(); 1251 1252 if (renderer && renderer->isTextControl()) 1253 renderTextControl = toRenderTextControl(renderer); 1254 1255 Vector<CompositionUnderline> underlines; 1256 1257 for (int i = 0; i < ev->attributes().size(); ++i) { 1258 const QInputMethodEvent::Attribute& a = ev->attributes().at(i); 1259 switch (a.type) { 1260 case QInputMethodEvent::TextFormat: { 1261 QTextCharFormat textCharFormat = a.value.value<QTextFormat>().toCharFormat(); 1262 QColor qcolor = textCharFormat.underlineColor(); 1263 underlines.append(CompositionUnderline(a.start, a.length, Color(makeRGBA(qcolor.red(), qcolor.green(), qcolor.blue(), qcolor.alpha())), false)); 1264 break; 1265 } 1266 case QInputMethodEvent::Cursor: { 1267 frame->selection()->setCaretVisible(a.length); //if length is 0 cursor is invisible 1268 if (a.length > 0) { 1269 RenderObject* caretRenderer = frame->selection()->caretRenderer(); 1270 if (caretRenderer) { 1271 QColor qcolor = a.value.value<QColor>(); 1272 caretRenderer->style()->setColor(Color(makeRGBA(qcolor.red(), qcolor.green(), qcolor.blue(), qcolor.alpha()))); 1273 } 1274 } 1275 break; 1276 } 1277 #if QT_VERSION >= 0x040600 1278 case QInputMethodEvent::Selection: { 1279 if (renderTextControl) { 1280 renderTextControl->setSelectionStart(a.start); 1281 renderTextControl->setSelectionEnd(a.start + a.length); 1282 } 1283 break; 1284 } 1285 #endif 1286 } 1287 } 1288 1289 if (!ev->commitString().isEmpty()) 1290 editor->confirmComposition(ev->commitString()); 1291 else if (!ev->preeditString().isEmpty()) { 1292 QString preedit = ev->preeditString(); 1293 editor->setComposition(preedit, underlines, preedit.length(), 0); 1294 } 1295 ev->accept(); 1296 } 1297 1298 void QWebPagePrivate::shortcutOverrideEvent(QKeyEvent* event) 1299 { 1300 WebCore::Frame* frame = page->focusController()->focusedOrMainFrame(); 1301 WebCore::Editor* editor = frame->editor(); 1302 if (editor->canEdit()) { 1303 if (event->modifiers() == Qt::NoModifier 1304 || event->modifiers() == Qt::ShiftModifier 1305 || event->modifiers() == Qt::KeypadModifier) { 1306 if (event->key() < Qt::Key_Escape) { 1307 event->accept(); 1308 } else { 1309 switch (event->key()) { 1310 case Qt::Key_Return: 1311 case Qt::Key_Enter: 1312 case Qt::Key_Delete: 1313 case Qt::Key_Home: 1314 case Qt::Key_End: 1315 case Qt::Key_Backspace: 1316 case Qt::Key_Left: 1317 case Qt::Key_Right: 1318 case Qt::Key_Up: 1319 case Qt::Key_Down: 1320 case Qt::Key_Tab: 1321 event->accept(); 1322 default: 1323 break; 1324 } 1325 } 1326 } 1327 #ifndef QT_NO_SHORTCUT 1328 else if (editorActionForKeyEvent(event) != QWebPage::NoWebAction) 1329 event->accept(); 1330 #endif 1331 } 1332 } 1333 1334 bool QWebPagePrivate::handleScrolling(QKeyEvent *ev, Frame *frame) 1335 { 1336 ScrollDirection direction; 1337 ScrollGranularity granularity; 1338 1339 #ifndef QT_NO_SHORTCUT 1340 if (ev == QKeySequence::MoveToNextPage 1341 || (ev->key() == Qt::Key_Space && !(ev->modifiers() & Qt::ShiftModifier))) { 1342 granularity = ScrollByPage; 1343 direction = ScrollDown; 1344 } else if (ev == QKeySequence::MoveToPreviousPage 1345 || ((ev->key() == Qt::Key_Space) && (ev->modifiers() & Qt::ShiftModifier))) { 1346 granularity = ScrollByPage; 1347 direction = ScrollUp; 1348 } else 1349 #endif // QT_NO_SHORTCUT 1350 if ((ev->key() == Qt::Key_Up && ev->modifiers() & Qt::ControlModifier) 1351 || ev->key() == Qt::Key_Home) { 1352 granularity = ScrollByDocument; 1353 direction = ScrollUp; 1354 } else if ((ev->key() == Qt::Key_Down && ev->modifiers() & Qt::ControlModifier) 1355 || ev->key() == Qt::Key_End) { 1356 granularity = ScrollByDocument; 1357 direction = ScrollDown; 1358 } else { 1359 switch (ev->key()) { 1360 case Qt::Key_Up: 1361 granularity = ScrollByLine; 1362 direction = ScrollUp; 1363 break; 1364 case Qt::Key_Down: 1365 granularity = ScrollByLine; 1366 direction = ScrollDown; 1367 break; 1368 case Qt::Key_Left: 1369 granularity = ScrollByLine; 1370 direction = ScrollLeft; 1371 break; 1372 case Qt::Key_Right: 1373 granularity = ScrollByLine; 1374 direction = ScrollRight; 1375 break; 1376 default: 1377 return false; 1378 } 1379 } 1380 1381 return frame->eventHandler()->scrollRecursively(direction, granularity); 1382 } 1383 1384 #if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) 1385 void QWebPagePrivate::touchEvent(QTouchEvent* event) 1386 { 1387 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); 1388 if (!frame->view()) 1389 return; 1390 1391 bool accepted = frame->eventHandler()->handleTouchEvent(PlatformTouchEvent(event)); 1392 event->setAccepted(accepted); 1393 } 1394 #endif 1395 1396 /*! 1397 This method is used by the input method to query a set of properties of the page 1398 to be able to support complex input method operations as support for surrounding 1399 text and reconversions. 1400 1401 \a property specifies which property is queried. 1402 1403 \sa QWidget::inputMethodEvent(), QInputMethodEvent, QInputContext 1404 */ 1405 QVariant QWebPage::inputMethodQuery(Qt::InputMethodQuery property) const 1406 { 1407 Frame* frame = d->page->focusController()->focusedFrame(); 1408 if (!frame) 1409 return QVariant(); 1410 1411 WebCore::Editor* editor = frame->editor(); 1412 1413 RenderObject* renderer = 0; 1414 RenderTextControl* renderTextControl = 0; 1415 1416 if (frame->selection()->rootEditableElement()) 1417 renderer = frame->selection()->rootEditableElement()->shadowAncestorNode()->renderer(); 1418 1419 if (renderer && renderer->isTextControl()) 1420 renderTextControl = toRenderTextControl(renderer); 1421 1422 switch (property) { 1423 case Qt::ImMicroFocus: { 1424 WebCore::FrameView* view = frame->view(); 1425 if (view && view->needsLayout()) { 1426 // We can't access absoluteCaretBounds() while the view needs to layout. 1427 return QVariant(); 1428 } 1429 return QVariant(frame->selection()->absoluteCaretBounds()); 1430 } 1431 case Qt::ImFont: { 1432 if (renderTextControl) { 1433 RenderStyle* renderStyle = renderTextControl->style(); 1434 return QVariant(QFont(renderStyle->font().font())); 1435 } 1436 return QVariant(QFont()); 1437 } 1438 case Qt::ImCursorPosition: { 1439 if (renderTextControl) { 1440 if (editor->hasComposition()) { 1441 RefPtr<Range> range = editor->compositionRange(); 1442 return QVariant(renderTextControl->selectionEnd() - TextIterator::rangeLength(range.get())); 1443 } 1444 return QVariant(renderTextControl->selectionEnd()); 1445 } 1446 return QVariant(); 1447 } 1448 case Qt::ImSurroundingText: { 1449 if (renderTextControl) { 1450 QString text = renderTextControl->text(); 1451 RefPtr<Range> range = editor->compositionRange(); 1452 if (range) { 1453 text.remove(range->startPosition().offsetInContainerNode(), TextIterator::rangeLength(range.get())); 1454 } 1455 return QVariant(text); 1456 } 1457 return QVariant(); 1458 } 1459 case Qt::ImCurrentSelection: { 1460 if (renderTextControl) { 1461 int start = renderTextControl->selectionStart(); 1462 int end = renderTextControl->selectionEnd(); 1463 if (end > start) 1464 return QVariant(QString(renderTextControl->text()).mid(start,end-start)); 1465 } 1466 return QVariant(); 1467 1468 } 1469 #if QT_VERSION >= 0x040600 1470 case Qt::ImAnchorPosition: { 1471 if (renderTextControl) { 1472 if (editor->hasComposition()) { 1473 RefPtr<Range> range = editor->compositionRange(); 1474 return QVariant(renderTextControl->selectionStart() - TextIterator::rangeLength(range.get())); 1475 } 1476 return QVariant(renderTextControl->selectionStart()); 1477 } 1478 return QVariant(); 1479 } 1480 case Qt::ImMaximumTextLength: { 1481 if (frame->selection()->isContentEditable()) { 1482 if (frame->document() && frame->document()->focusedNode()) { 1483 if (frame->document()->focusedNode()->hasTagName(HTMLNames::inputTag)) { 1484 HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(frame->document()->focusedNode()); 1485 return QVariant(inputElement->maxLength()); 1486 } 1487 } 1488 return QVariant(InputElement::s_maximumLength); 1489 } 1490 return QVariant(0); 1491 } 1492 #endif 1493 default: 1494 return QVariant(); 1495 } 1496 } 1497 1498 /*! 1499 \internal 1500 */ 1501 void QWebPagePrivate::setInspector(QWebInspector* insp) 1502 { 1503 if (inspector) 1504 inspector->d->setFrontend(0); 1505 1506 if (inspectorIsInternalOnly) { 1507 QWebInspector* inspToDelete = inspector; 1508 inspector = 0; 1509 inspectorIsInternalOnly = false; 1510 delete inspToDelete; // Delete after to prevent infinite recursion 1511 } 1512 1513 inspector = insp; 1514 1515 // Give inspector frontend web view if previously created 1516 if (inspector && inspectorFrontend) 1517 inspector->d->setFrontend(inspectorFrontend); 1518 } 1519 1520 /*! 1521 \internal 1522 Returns the inspector and creates it if it wasn't created yet. 1523 The instance created here will not be available through QWebPage's API. 1524 */ 1525 QWebInspector* QWebPagePrivate::getOrCreateInspector() 1526 { 1527 #if ENABLE(INSPECTOR) 1528 if (!inspector) { 1529 QWebInspector* insp = new QWebInspector; 1530 insp->setPage(q); 1531 inspectorIsInternalOnly = true; 1532 1533 Q_ASSERT(inspector); // Associated through QWebInspector::setPage(q) 1534 } 1535 #endif 1536 return inspector; 1537 } 1538 1539 /*! \internal */ 1540 InspectorController* QWebPagePrivate::inspectorController() 1541 { 1542 #if ENABLE(INSPECTOR) 1543 return page->inspectorController(); 1544 #else 1545 return 0; 1546 #endif 1547 } 1548 1549 1550 /*! 1551 \enum QWebPage::FindFlag 1552 1553 This enum describes the options available to QWebPage's findText() function. The options 1554 can be OR-ed together from the following list: 1555 1556 \value FindBackward Searches backwards instead of forwards. 1557 \value FindCaseSensitively By default findText() works case insensitive. Specifying this option 1558 changes the behaviour to a case sensitive find operation. 1559 \value FindWrapsAroundDocument Makes findText() restart from the beginning of the document if the end 1560 was reached and the text was not found. 1561 \value HighlightAllOccurrences Highlights all existing occurrences of a specific string. 1562 */ 1563 1564 /*! 1565 \enum QWebPage::LinkDelegationPolicy 1566 1567 This enum defines the delegation policies a webpage can have when activating links and emitting 1568 the linkClicked() signal. 1569 1570 \value DontDelegateLinks No links are delegated. Instead, QWebPage tries to handle them all. 1571 \value DelegateExternalLinks When activating links that point to documents not stored on the 1572 local filesystem or an equivalent - such as the Qt resource system - then linkClicked() is emitted. 1573 \value DelegateAllLinks Whenever a link is activated the linkClicked() signal is emitted. 1574 */ 1575 1576 /*! 1577 \enum QWebPage::NavigationType 1578 1579 This enum describes the types of navigation available when browsing through hyperlinked 1580 documents. 1581 1582 \value NavigationTypeLinkClicked The user clicked on a link or pressed return on a focused link. 1583 \value NavigationTypeFormSubmitted The user activated a submit button for an HTML form. 1584 \value NavigationTypeBackOrForward Navigation to a previously shown document in the back or forward history is requested. 1585 \value NavigationTypeReload The user activated the reload action. 1586 \value NavigationTypeFormResubmitted An HTML form was submitted a second time. 1587 \value NavigationTypeOther A navigation to another document using a method not listed above. 1588 */ 1589 1590 /*! 1591 \enum QWebPage::WebAction 1592 1593 This enum describes the types of action which can be performed on the web page. 1594 1595 Actions only have an effect when they are applicable. The availability of 1596 actions can be be determined by checking \l{QAction::}{isEnabled()} on the 1597 action returned by \l{QWebPage::}{action()}. 1598 1599 One method of enabling the text editing, cursor movement, and text selection actions 1600 is by setting \l contentEditable to true. 1601 1602 \value NoWebAction No action is triggered. 1603 \value OpenLink Open the current link. 1604 \value OpenLinkInNewWindow Open the current link in a new window. 1605 \value OpenFrameInNewWindow Replicate the current frame in a new window. 1606 \value DownloadLinkToDisk Download the current link to the disk. 1607 \value CopyLinkToClipboard Copy the current link to the clipboard. 1608 \value OpenImageInNewWindow Open the highlighted image in a new window. 1609 \value DownloadImageToDisk Download the highlighted image to the disk. 1610 \value CopyImageToClipboard Copy the highlighted image to the clipboard. 1611 \value Back Navigate back in the history of navigated links. 1612 \value Forward Navigate forward in the history of navigated links. 1613 \value Stop Stop loading the current page. 1614 \value Reload Reload the current page. 1615 \value ReloadAndBypassCache Reload the current page, but do not use any local cache. (Added in Qt 4.6) 1616 \value Cut Cut the content currently selected into the clipboard. 1617 \value Copy Copy the content currently selected into the clipboard. 1618 \value Paste Paste content from the clipboard. 1619 \value Undo Undo the last editing action. 1620 \value Redo Redo the last editing action. 1621 \value MoveToNextChar Move the cursor to the next character. 1622 \value MoveToPreviousChar Move the cursor to the previous character. 1623 \value MoveToNextWord Move the cursor to the next word. 1624 \value MoveToPreviousWord Move the cursor to the previous word. 1625 \value MoveToNextLine Move the cursor to the next line. 1626 \value MoveToPreviousLine Move the cursor to the previous line. 1627 \value MoveToStartOfLine Move the cursor to the start of the line. 1628 \value MoveToEndOfLine Move the cursor to the end of the line. 1629 \value MoveToStartOfBlock Move the cursor to the start of the block. 1630 \value MoveToEndOfBlock Move the cursor to the end of the block. 1631 \value MoveToStartOfDocument Move the cursor to the start of the document. 1632 \value MoveToEndOfDocument Move the cursor to the end of the document. 1633 \value SelectNextChar Select to the next character. 1634 \value SelectPreviousChar Select to the previous character. 1635 \value SelectNextWord Select to the next word. 1636 \value SelectPreviousWord Select to the previous word. 1637 \value SelectNextLine Select to the next line. 1638 \value SelectPreviousLine Select to the previous line. 1639 \value SelectStartOfLine Select to the start of the line. 1640 \value SelectEndOfLine Select to the end of the line. 1641 \value SelectStartOfBlock Select to the start of the block. 1642 \value SelectEndOfBlock Select to the end of the block. 1643 \value SelectStartOfDocument Select to the start of the document. 1644 \value SelectEndOfDocument Select to the end of the document. 1645 \value DeleteStartOfWord Delete to the start of the word. 1646 \value DeleteEndOfWord Delete to the end of the word. 1647 \value SetTextDirectionDefault Set the text direction to the default direction. 1648 \value SetTextDirectionLeftToRight Set the text direction to left-to-right. 1649 \value SetTextDirectionRightToLeft Set the text direction to right-to-left. 1650 \value ToggleBold Toggle the formatting between bold and normal weight. 1651 \value ToggleItalic Toggle the formatting between italic and normal style. 1652 \value ToggleUnderline Toggle underlining. 1653 \value InspectElement Show the Web Inspector with the currently highlighted HTML element. 1654 \value InsertParagraphSeparator Insert a new paragraph. 1655 \value InsertLineSeparator Insert a new line. 1656 \value SelectAll Selects all content. 1657 \value PasteAndMatchStyle Paste content from the clipboard with current style. 1658 \value RemoveFormat Removes formatting and style. 1659 \value ToggleStrikethrough Toggle the formatting between strikethrough and normal style. 1660 \value ToggleSubscript Toggle the formatting between subscript and baseline. 1661 \value ToggleSuperscript Toggle the formatting between supercript and baseline. 1662 \value InsertUnorderedList Toggles the selection between an ordered list and a normal block. 1663 \value InsertOrderedList Toggles the selection between an ordered list and a normal block. 1664 \value Indent Increases the indentation of the currently selected format block by one increment. 1665 \value Outdent Decreases the indentation of the currently selected format block by one increment. 1666 \value AlignCenter Applies center alignment to content. 1667 \value AlignJustified Applies full justification to content. 1668 \value AlignLeft Applies left justification to content. 1669 \value AlignRight Applies right justification to content. 1670 1671 1672 \omitvalue WebActionCount 1673 1674 */ 1675 1676 /*! 1677 \enum QWebPage::WebWindowType 1678 1679 \value WebBrowserWindow The window is a regular web browser window. 1680 \value WebModalDialog The window acts as modal dialog. 1681 */ 1682 1683 /*! 1684 \class QWebPage 1685 \since 4.4 1686 \brief The QWebPage class provides an object to view and edit web documents. 1687 1688 \inmodule QtWebKit 1689 1690 QWebPage holds a main frame responsible for web content, settings, the history 1691 of navigated links and actions. This class can be used, together with QWebFrame, 1692 to provide functionality like QWebView in a widget-less environment. 1693 1694 QWebPage's API is very similar to QWebView, as you are still provided with 1695 common functions like action() (known as \l{QWebView::}{pageAction()} in 1696 QWebView), triggerAction(), findText() and settings(). More QWebView-like 1697 functions can be found in the main frame of QWebPage, obtained via 1698 QWebPage::mainFrame(). For example, the load(), setUrl() and setHtml() 1699 unctions for QWebPage can be accessed using QWebFrame. 1700 1701 The loadStarted() signal is emitted when the page begins to load.The 1702 loadProgress() signal, on the other hand, is emitted whenever an element 1703 of the web page completes loading, such as an embedded image, a script, 1704 etc. Finally, the loadFinished() signal is emitted when the page has 1705 loaded completely. Its argument, either true or false, indicates whether 1706 or not the load operation succeeded. 1707 1708 \section1 Using QWebPage in a Widget-less Environment 1709 1710 Before you begin painting a QWebPage object, you need to set the size of 1711 the viewport by calling setViewportSize(). Then, you invoke the main 1712 frame's render function (QWebFrame::render()). An example of this 1713 is shown in the code snippet below. 1714 1715 Suppose we have a \c Thumbnail class as follows: 1716 1717 \snippet webkitsnippets/webpage/main.cpp 0 1718 1719 The \c Thumbnail's constructor takes in a \a url. We connect our QWebPage 1720 object's \l{QWebPage::}{loadFinished()} signal to our private slot, 1721 \c render(). 1722 1723 \snippet webkitsnippets/webpage/main.cpp 1 1724 1725 The \c render() function shows how we can paint a thumbnail using a 1726 QWebPage object. 1727 1728 \snippet webkitsnippets/webpage/main.cpp 2 1729 1730 We begin by setting the \l{QWebPage::viewportSize()}{viewportSize} and 1731 then we instantiate a QImage object, \c image, with the same size as our 1732 \l{QWebPage::viewportSize()}{viewportSize}. This image is then sent 1733 as a parameter to \c painter. Next, we render the contents of the main 1734 frame and its subframes into \c painter. Finally, we save the scaled image. 1735 1736 \sa QWebFrame 1737 */ 1738 1739 /*! 1740 Constructs an empty QWebPage with parent \a parent. 1741 */ 1742 QWebPage::QWebPage(QObject *parent) 1743 : QObject(parent) 1744 , d(new QWebPagePrivate(this)) 1745 { 1746 setView(qobject_cast<QWidget *>(parent)); 1747 1748 connect(this, SIGNAL(loadProgress(int)), this, SLOT(_q_onLoadProgressChanged(int))); 1749 #ifndef NDEBUG 1750 connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(_q_cleanupLeakMessages())); 1751 #endif 1752 } 1753 1754 /*! 1755 Destroys the web page. 1756 */ 1757 QWebPage::~QWebPage() 1758 { 1759 d->createMainFrame(); 1760 FrameLoader *loader = d->mainFrame->d->frame->loader(); 1761 if (loader) 1762 loader->detachFromParent(); 1763 if (d->inspector) { 1764 // Since we have to delete an internal inspector, 1765 // call setInspector(0) directly to prevent potential crashes 1766 if (d->inspectorIsInternalOnly) 1767 d->setInspector(0); 1768 else 1769 d->inspector->setPage(0); 1770 } 1771 delete d; 1772 } 1773 1774 /*! 1775 Returns the main frame of the page. 1776 1777 The main frame provides access to the hierarchy of sub-frames and is also needed if you 1778 want to explicitly render a web page into a given painter. 1779 1780 \sa currentFrame() 1781 */ 1782 QWebFrame *QWebPage::mainFrame() const 1783 { 1784 d->createMainFrame(); 1785 return d->mainFrame; 1786 } 1787 1788 /*! 1789 Returns the frame currently active. 1790 1791 \sa mainFrame(), frameCreated() 1792 */ 1793 QWebFrame *QWebPage::currentFrame() const 1794 { 1795 d->createMainFrame(); 1796 return static_cast<WebCore::FrameLoaderClientQt *>(d->page->focusController()->focusedOrMainFrame()->loader()->client())->webFrame(); 1797 } 1798 1799 1800 /*! 1801 \since 4.6 1802 1803 Returns the frame at the given point \a pos. 1804 1805 \sa mainFrame(), currentFrame() 1806 */ 1807 QWebFrame* QWebPage::frameAt(const QPoint& pos) const 1808 { 1809 QWebFrame* webFrame = mainFrame(); 1810 if (!webFrame->geometry().contains(pos)) 1811 return 0; 1812 QWebHitTestResult hitTestResult = webFrame->hitTestContent(pos); 1813 return hitTestResult.frame(); 1814 } 1815 1816 /*! 1817 Returns a pointer to the view's history of navigated web pages. 1818 */ 1819 QWebHistory *QWebPage::history() const 1820 { 1821 d->createMainFrame(); 1822 return &d->history; 1823 } 1824 1825 /*! 1826 Sets the \a view that is associated with the web page. 1827 1828 \sa view() 1829 */ 1830 void QWebPage::setView(QWidget *view) 1831 { 1832 if (this->view() != view) { 1833 d->view = view; 1834 if (!view) { 1835 delete d->client; 1836 d->client = 0; 1837 } else { 1838 if (!d->client) 1839 d->client = new QWebPageWidgetClient(view); 1840 else 1841 static_cast<QWebPageWidgetClient*>(d->client)->view = view; 1842 } 1843 setViewportSize(view ? view->size() : QSize(0, 0)); 1844 } 1845 } 1846 1847 /*! 1848 Returns the view widget that is associated with the web page. 1849 1850 \sa setView() 1851 */ 1852 QWidget *QWebPage::view() const 1853 { 1854 #if QT_VERSION < 0x040600 1855 return d->view; 1856 #else 1857 return d->view.data(); 1858 #endif 1859 } 1860 1861 /*! 1862 This function is called whenever a JavaScript program tries to print a \a message to the web browser's console. 1863 1864 For example in case of evaluation errors the source URL may be provided in \a sourceID as well as the \a lineNumber. 1865 1866 The default implementation prints nothing. 1867 */ 1868 void QWebPage::javaScriptConsoleMessage(const QString& message, int lineNumber, const QString& sourceID) 1869 { 1870 Q_UNUSED(message) 1871 Q_UNUSED(lineNumber) 1872 Q_UNUSED(sourceID) 1873 } 1874 1875 /*! 1876 This function is called whenever a JavaScript program running inside \a frame calls the alert() function with 1877 the message \a msg. 1878 1879 The default implementation shows the message, \a msg, with QMessageBox::information. 1880 */ 1881 void QWebPage::javaScriptAlert(QWebFrame *frame, const QString& msg) 1882 { 1883 Q_UNUSED(frame) 1884 #ifndef QT_NO_MESSAGEBOX 1885 QMessageBox::information(view(), tr("JavaScript Alert - %1").arg(mainFrame()->url().host()), Qt::escape(msg), QMessageBox::Ok); 1886 #endif 1887 } 1888 1889 /*! 1890 This function is called whenever a JavaScript program running inside \a frame calls the confirm() function 1891 with the message, \a msg. Returns true if the user confirms the message; otherwise returns false. 1892 1893 The default implementation executes the query using QMessageBox::information with QMessageBox::Yes and QMessageBox::No buttons. 1894 */ 1895 bool QWebPage::javaScriptConfirm(QWebFrame *frame, const QString& msg) 1896 { 1897 Q_UNUSED(frame) 1898 #ifdef QT_NO_MESSAGEBOX 1899 return true; 1900 #else 1901 return QMessageBox::Yes == QMessageBox::information(view(), tr("JavaScript Confirm - %1").arg(mainFrame()->url().host()), Qt::escape(msg), QMessageBox::Yes, QMessageBox::No); 1902 #endif 1903 } 1904 1905 /*! 1906 This function is called whenever a JavaScript program running inside \a frame tries to prompt the user for input. 1907 The program may provide an optional message, \a msg, as well as a default value for the input in \a defaultValue. 1908 1909 If the prompt was cancelled by the user the implementation should return false; otherwise the 1910 result should be written to \a result and true should be returned. If the prompt was not cancelled by the 1911 user, the implementation should return true and the result string must not be null. 1912 1913 The default implementation uses QInputDialog::getText. 1914 */ 1915 bool QWebPage::javaScriptPrompt(QWebFrame *frame, const QString& msg, const QString& defaultValue, QString* result) 1916 { 1917 Q_UNUSED(frame) 1918 bool ok = false; 1919 #ifndef QT_NO_INPUTDIALOG 1920 QString x = QInputDialog::getText(view(), tr("JavaScript Prompt - %1").arg(mainFrame()->url().host()), Qt::escape(msg), QLineEdit::Normal, defaultValue, &ok); 1921 if (ok && result) 1922 *result = x; 1923 #endif 1924 return ok; 1925 } 1926 1927 /*! 1928 \fn bool QWebPage::shouldInterruptJavaScript() 1929 \since 4.6 1930 This function is called when a JavaScript program is running for a long period of time. 1931 1932 If the user wanted to stop the JavaScript the implementation should return true; otherwise false. 1933 1934 The default implementation executes the query using QMessageBox::information with QMessageBox::Yes and QMessageBox::No buttons. 1935 1936 \warning Because of binary compatibility constraints, this function is not virtual. If you want to 1937 provide your own implementation in a QWebPage subclass, reimplement the shouldInterruptJavaScript() 1938 slot in your subclass instead. QtWebKit will dynamically detect the slot and call it. 1939 */ 1940 bool QWebPage::shouldInterruptJavaScript() 1941 { 1942 #ifdef QT_NO_MESSAGEBOX 1943 return false; 1944 #else 1945 return QMessageBox::Yes == QMessageBox::information(view(), tr("JavaScript Problem - %1").arg(mainFrame()->url().host()), tr("The script on this page appears to have a problem. Do you want to stop the script?"), QMessageBox::Yes, QMessageBox::No); 1946 #endif 1947 } 1948 1949 /*! 1950 This function is called whenever WebKit wants to create a new window of the given \a type, for 1951 example when a JavaScript program requests to open a document in a new window. 1952 1953 If the new window can be created, the new window's QWebPage is returned; otherwise a null pointer is returned. 1954 1955 If the view associated with the web page is a QWebView object, then the default implementation forwards 1956 the request to QWebView's createWindow() function; otherwise it returns a null pointer. 1957 1958 If \a type is WebModalDialog, the application must call setWindowModality(Qt::ApplicationModal) on the new window. 1959 1960 \sa acceptNavigationRequest() 1961 */ 1962 QWebPage *QWebPage::createWindow(WebWindowType type) 1963 { 1964 QWebView *webView = qobject_cast<QWebView *>(view()); 1965 if (webView) { 1966 QWebView *newView = webView->createWindow(type); 1967 if (newView) 1968 return newView->page(); 1969 } 1970 return 0; 1971 } 1972 1973 /*! 1974 This function is called whenever WebKit encounters a HTML object element with type "application/x-qt-plugin". 1975 The \a classid, \a url, \a paramNames and \a paramValues correspond to the HTML object element attributes and 1976 child elements to configure the embeddable object. 1977 */ 1978 QObject *QWebPage::createPlugin(const QString &classid, const QUrl &url, const QStringList ¶mNames, const QStringList ¶mValues) 1979 { 1980 Q_UNUSED(classid) 1981 Q_UNUSED(url) 1982 Q_UNUSED(paramNames) 1983 Q_UNUSED(paramValues) 1984 return 0; 1985 } 1986 1987 static WebCore::FrameLoadRequest frameLoadRequest(const QUrl &url, WebCore::Frame *frame) 1988 { 1989 WebCore::ResourceRequest rr(url, frame->loader()->outgoingReferrer()); 1990 return WebCore::FrameLoadRequest(rr); 1991 } 1992 1993 static void openNewWindow(const QUrl& url, WebCore::Frame* frame) 1994 { 1995 if (Page* oldPage = frame->page()) { 1996 WindowFeatures features; 1997 if (Page* newPage = oldPage->chrome()->createWindow(frame, 1998 frameLoadRequest(url, frame), features)) 1999 newPage->chrome()->show(); 2000 } 2001 } 2002 2003 /*! 2004 This function can be called to trigger the specified \a action. 2005 It is also called by QtWebKit if the user triggers the action, for example 2006 through a context menu item. 2007 2008 If \a action is a checkable action then \a checked specified whether the action 2009 is toggled or not. 2010 2011 \sa action() 2012 */ 2013 void QWebPage::triggerAction(WebAction action, bool) 2014 { 2015 WebCore::Frame *frame = d->page->focusController()->focusedOrMainFrame(); 2016 if (!frame) 2017 return; 2018 WebCore::Editor *editor = frame->editor(); 2019 const char *command = 0; 2020 2021 switch (action) { 2022 case OpenLink: 2023 if (QWebFrame *targetFrame = d->hitTestResult.linkTargetFrame()) { 2024 WTF::RefPtr<WebCore::Frame> wcFrame = targetFrame->d->frame; 2025 targetFrame->d->frame->loader()->loadFrameRequest(frameLoadRequest(d->hitTestResult.linkUrl(), wcFrame.get()), 2026 /*lockHistory*/ false, /*lockBackForwardList*/ false, /*event*/ 0, 2027 /*FormState*/ 0, SendReferrer); 2028 break; 2029 } 2030 // fall through 2031 case OpenLinkInNewWindow: 2032 openNewWindow(d->hitTestResult.linkUrl(), frame); 2033 break; 2034 case OpenFrameInNewWindow: { 2035 KURL url = frame->loader()->documentLoader()->unreachableURL(); 2036 if (url.isEmpty()) 2037 url = frame->loader()->documentLoader()->url(); 2038 openNewWindow(url, frame); 2039 break; 2040 } 2041 case CopyLinkToClipboard: { 2042 #if defined(Q_WS_X11) 2043 bool oldSelectionMode = Pasteboard::generalPasteboard()->isSelectionMode(); 2044 Pasteboard::generalPasteboard()->setSelectionMode(true); 2045 editor->copyURL(d->hitTestResult.linkUrl(), d->hitTestResult.linkText()); 2046 Pasteboard::generalPasteboard()->setSelectionMode(oldSelectionMode); 2047 #endif 2048 editor->copyURL(d->hitTestResult.linkUrl(), d->hitTestResult.linkText()); 2049 break; 2050 } 2051 case OpenImageInNewWindow: 2052 openNewWindow(d->hitTestResult.imageUrl(), frame); 2053 break; 2054 case DownloadImageToDisk: 2055 frame->loader()->client()->startDownload(WebCore::ResourceRequest(d->hitTestResult.imageUrl(), frame->loader()->outgoingReferrer())); 2056 break; 2057 case DownloadLinkToDisk: 2058 frame->loader()->client()->startDownload(WebCore::ResourceRequest(d->hitTestResult.linkUrl(), frame->loader()->outgoingReferrer())); 2059 break; 2060 #ifndef QT_NO_CLIPBOARD 2061 case CopyImageToClipboard: 2062 QApplication::clipboard()->setPixmap(d->hitTestResult.pixmap()); 2063 break; 2064 #endif 2065 case Back: 2066 d->page->goBack(); 2067 break; 2068 case Forward: 2069 d->page->goForward(); 2070 break; 2071 case Stop: 2072 mainFrame()->d->frame->loader()->stopForUserCancel(); 2073 break; 2074 case Reload: 2075 mainFrame()->d->frame->loader()->reload(/*endtoendreload*/false); 2076 break; 2077 case ReloadAndBypassCache: 2078 mainFrame()->d->frame->loader()->reload(/*endtoendreload*/true); 2079 break; 2080 case SetTextDirectionDefault: 2081 editor->setBaseWritingDirection(NaturalWritingDirection); 2082 break; 2083 case SetTextDirectionLeftToRight: 2084 editor->setBaseWritingDirection(LeftToRightWritingDirection); 2085 break; 2086 case SetTextDirectionRightToLeft: 2087 editor->setBaseWritingDirection(RightToLeftWritingDirection); 2088 break; 2089 case InspectElement: { 2090 #if ENABLE(INSPECTOR) 2091 if (!d->hitTestResult.isNull()) { 2092 d->getOrCreateInspector(); // Make sure the inspector is created 2093 d->inspector->show(); // The inspector is expected to be shown on inspection 2094 d->page->inspectorController()->inspect(d->hitTestResult.d->innerNonSharedNode.get()); 2095 } 2096 #endif 2097 break; 2098 } 2099 default: 2100 command = QWebPagePrivate::editorCommandForWebActions(action); 2101 break; 2102 } 2103 2104 if (command) 2105 editor->command(command).execute(); 2106 } 2107 2108 QSize QWebPage::viewportSize() const 2109 { 2110 if (d->mainFrame && d->mainFrame->d->frame->view()) 2111 return d->mainFrame->d->frame->view()->frameRect().size(); 2112 2113 return d->viewportSize; 2114 } 2115 2116 /*! 2117 \property QWebPage::viewportSize 2118 \brief the size of the viewport 2119 2120 The size affects for example the visibility of scrollbars 2121 if the document is larger than the viewport. 2122 2123 By default, for a newly-created Web page, this property contains a size with 2124 zero width and height. 2125 */ 2126 void QWebPage::setViewportSize(const QSize &size) const 2127 { 2128 d->viewportSize = size; 2129 2130 QWebFrame *frame = mainFrame(); 2131 if (frame->d->frame && frame->d->frame->view()) { 2132 WebCore::FrameView* view = frame->d->frame->view(); 2133 view->setFrameRect(QRect(QPoint(0, 0), size)); 2134 view->forceLayout(); 2135 view->adjustViewSize(); 2136 } 2137 } 2138 2139 QSize QWebPage::preferredContentsSize() const 2140 { 2141 QWebFrame* frame = d->mainFrame; 2142 if (frame) { 2143 WebCore::FrameView* view = frame->d->frame->view(); 2144 if (view && view->useFixedLayout()) 2145 return d->mainFrame->d->frame->view()->fixedLayoutSize(); 2146 } 2147 2148 return d->fixedLayoutSize; 2149 } 2150 2151 /*! 2152 \property QWebPage::preferredContentsSize 2153 \since 4.6 2154 \brief the size of the fixed layout 2155 2156 The size affects the layout of the page in the viewport. If set to a fixed size of 2157 1024x768 for example then webkit will layout the page as if the viewport were that size 2158 rather than something different. 2159 */ 2160 void QWebPage::setPreferredContentsSize(const QSize &size) const 2161 { 2162 d->fixedLayoutSize = size; 2163 2164 QWebFrame *frame = mainFrame(); 2165 if (frame->d->frame && frame->d->frame->view()) { 2166 WebCore::FrameView* view = frame->d->frame->view(); 2167 2168 if (size.isValid()) { 2169 view->setUseFixedLayout(true); 2170 view->setFixedLayoutSize(size); 2171 view->forceLayout(); 2172 } else if (view->useFixedLayout()) { 2173 view->setUseFixedLayout(false); 2174 view->forceLayout(); 2175 } 2176 } 2177 } 2178 2179 /*! 2180 \fn bool QWebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type) 2181 2182 This function is called whenever WebKit requests to navigate \a frame to the resource specified by \a request by means of 2183 the specified navigation type \a type. 2184 2185 If \a frame is a null pointer then navigation to a new window is requested. If the request is 2186 accepted createWindow() will be called. 2187 2188 The default implementation interprets the page's linkDelegationPolicy and emits linkClicked accordingly or returns true 2189 to let QWebPage handle the navigation itself. 2190 2191 \sa createWindow() 2192 */ 2193 bool QWebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type) 2194 { 2195 Q_UNUSED(frame) 2196 if (type == NavigationTypeLinkClicked) { 2197 switch (d->linkPolicy) { 2198 case DontDelegateLinks: 2199 return true; 2200 2201 case DelegateExternalLinks: 2202 if (WebCore::SecurityOrigin::shouldTreatURLSchemeAsLocal(request.url().scheme())) 2203 return true; 2204 emit linkClicked(request.url()); 2205 return false; 2206 2207 case DelegateAllLinks: 2208 emit linkClicked(request.url()); 2209 return false; 2210 } 2211 } 2212 return true; 2213 } 2214 2215 /*! 2216 \property QWebPage::selectedText 2217 \brief the text currently selected 2218 2219 By default, this property contains an empty string. 2220 2221 \sa selectionChanged() 2222 */ 2223 QString QWebPage::selectedText() const 2224 { 2225 d->createMainFrame(); 2226 return d->page->focusController()->focusedOrMainFrame()->selectedText(); 2227 } 2228 2229 /*! 2230 Returns a QAction for the specified WebAction \a action. 2231 2232 The action is owned by the QWebPage but you can customize the look by 2233 changing its properties. 2234 2235 QWebPage also takes care of implementing the action, so that upon 2236 triggering the corresponding action is performed on the page. 2237 2238 \sa triggerAction() 2239 */ 2240 QAction *QWebPage::action(WebAction action) const 2241 { 2242 if (action == QWebPage::NoWebAction) return 0; 2243 if (d->actions[action]) 2244 return d->actions[action]; 2245 2246 QString text; 2247 QIcon icon; 2248 QStyle *style = view() ? view()->style() : qApp->style(); 2249 bool checkable = false; 2250 2251 switch (action) { 2252 case OpenLink: 2253 text = contextMenuItemTagOpenLink(); 2254 break; 2255 case OpenLinkInNewWindow: 2256 text = contextMenuItemTagOpenLinkInNewWindow(); 2257 break; 2258 case OpenFrameInNewWindow: 2259 text = contextMenuItemTagOpenFrameInNewWindow(); 2260 break; 2261 2262 case DownloadLinkToDisk: 2263 text = contextMenuItemTagDownloadLinkToDisk(); 2264 break; 2265 case CopyLinkToClipboard: 2266 text = contextMenuItemTagCopyLinkToClipboard(); 2267 break; 2268 2269 case OpenImageInNewWindow: 2270 text = contextMenuItemTagOpenImageInNewWindow(); 2271 break; 2272 case DownloadImageToDisk: 2273 text = contextMenuItemTagDownloadImageToDisk(); 2274 break; 2275 case CopyImageToClipboard: 2276 text = contextMenuItemTagCopyImageToClipboard(); 2277 break; 2278 2279 case Back: 2280 text = contextMenuItemTagGoBack(); 2281 icon = style->standardIcon(QStyle::SP_ArrowBack); 2282 break; 2283 case Forward: 2284 text = contextMenuItemTagGoForward(); 2285 icon = style->standardIcon(QStyle::SP_ArrowForward); 2286 break; 2287 case Stop: 2288 text = contextMenuItemTagStop(); 2289 icon = style->standardIcon(QStyle::SP_BrowserStop); 2290 break; 2291 case Reload: 2292 text = contextMenuItemTagReload(); 2293 icon = style->standardIcon(QStyle::SP_BrowserReload); 2294 break; 2295 2296 case Cut: 2297 text = contextMenuItemTagCut(); 2298 break; 2299 case Copy: 2300 text = contextMenuItemTagCopy(); 2301 break; 2302 case Paste: 2303 text = contextMenuItemTagPaste(); 2304 break; 2305 #ifndef QT_NO_UNDOSTACK 2306 case Undo: { 2307 QAction *a = undoStack()->createUndoAction(d->q); 2308 d->actions[action] = a; 2309 return a; 2310 } 2311 case Redo: { 2312 QAction *a = undoStack()->createRedoAction(d->q); 2313 d->actions[action] = a; 2314 return a; 2315 } 2316 #endif // QT_NO_UNDOSTACK 2317 case MoveToNextChar: 2318 text = tr("Move the cursor to the next character"); 2319 break; 2320 case MoveToPreviousChar: 2321 text = tr("Move the cursor to the previous character"); 2322 break; 2323 case MoveToNextWord: 2324 text = tr("Move the cursor to the next word"); 2325 break; 2326 case MoveToPreviousWord: 2327 text = tr("Move the cursor to the previous word"); 2328 break; 2329 case MoveToNextLine: 2330 text = tr("Move the cursor to the next line"); 2331 break; 2332 case MoveToPreviousLine: 2333 text = tr("Move the cursor to the previous line"); 2334 break; 2335 case MoveToStartOfLine: 2336 text = tr("Move the cursor to the start of the line"); 2337 break; 2338 case MoveToEndOfLine: 2339 text = tr("Move the cursor to the end of the line"); 2340 break; 2341 case MoveToStartOfBlock: 2342 text = tr("Move the cursor to the start of the block"); 2343 break; 2344 case MoveToEndOfBlock: 2345 text = tr("Move the cursor to the end of the block"); 2346 break; 2347 case MoveToStartOfDocument: 2348 text = tr("Move the cursor to the start of the document"); 2349 break; 2350 case MoveToEndOfDocument: 2351 text = tr("Move the cursor to the end of the document"); 2352 break; 2353 case SelectAll: 2354 text = tr("Select all"); 2355 break; 2356 case SelectNextChar: 2357 text = tr("Select to the next character"); 2358 break; 2359 case SelectPreviousChar: 2360 text = tr("Select to the previous character"); 2361 break; 2362 case SelectNextWord: 2363 text = tr("Select to the next word"); 2364 break; 2365 case SelectPreviousWord: 2366 text = tr("Select to the previous word"); 2367 break; 2368 case SelectNextLine: 2369 text = tr("Select to the next line"); 2370 break; 2371 case SelectPreviousLine: 2372 text = tr("Select to the previous line"); 2373 break; 2374 case SelectStartOfLine: 2375 text = tr("Select to the start of the line"); 2376 break; 2377 case SelectEndOfLine: 2378 text = tr("Select to the end of the line"); 2379 break; 2380 case SelectStartOfBlock: 2381 text = tr("Select to the start of the block"); 2382 break; 2383 case SelectEndOfBlock: 2384 text = tr("Select to the end of the block"); 2385 break; 2386 case SelectStartOfDocument: 2387 text = tr("Select to the start of the document"); 2388 break; 2389 case SelectEndOfDocument: 2390 text = tr("Select to the end of the document"); 2391 break; 2392 case DeleteStartOfWord: 2393 text = tr("Delete to the start of the word"); 2394 break; 2395 case DeleteEndOfWord: 2396 text = tr("Delete to the end of the word"); 2397 break; 2398 2399 case SetTextDirectionDefault: 2400 text = contextMenuItemTagDefaultDirection(); 2401 break; 2402 case SetTextDirectionLeftToRight: 2403 text = contextMenuItemTagLeftToRight(); 2404 checkable = true; 2405 break; 2406 case SetTextDirectionRightToLeft: 2407 text = contextMenuItemTagRightToLeft(); 2408 checkable = true; 2409 break; 2410 2411 case ToggleBold: 2412 text = contextMenuItemTagBold(); 2413 checkable = true; 2414 break; 2415 case ToggleItalic: 2416 text = contextMenuItemTagItalic(); 2417 checkable = true; 2418 break; 2419 case ToggleUnderline: 2420 text = contextMenuItemTagUnderline(); 2421 checkable = true; 2422 break; 2423 2424 case InspectElement: 2425 text = contextMenuItemTagInspectElement(); 2426 break; 2427 2428 case InsertParagraphSeparator: 2429 text = tr("Insert a new paragraph"); 2430 break; 2431 case InsertLineSeparator: 2432 text = tr("Insert a new line"); 2433 break; 2434 2435 case PasteAndMatchStyle: 2436 text = tr("Paste and Match Style"); 2437 break; 2438 case RemoveFormat: 2439 text = tr("Remove formatting"); 2440 break; 2441 2442 case ToggleStrikethrough: 2443 text = tr("Strikethrough"); 2444 checkable = true; 2445 break; 2446 case ToggleSubscript: 2447 text = tr("Subscript"); 2448 checkable = true; 2449 break; 2450 case ToggleSuperscript: 2451 text = tr("Superscript"); 2452 checkable = true; 2453 break; 2454 case InsertUnorderedList: 2455 text = tr("Insert Bulleted List"); 2456 checkable = true; 2457 break; 2458 case InsertOrderedList: 2459 text = tr("Insert Numbered List"); 2460 checkable = true; 2461 break; 2462 case Indent: 2463 text = tr("Indent"); 2464 break; 2465 case Outdent: 2466 text = tr("Outdent"); 2467 break; 2468 case AlignCenter: 2469 text = tr("Center"); 2470 break; 2471 case AlignJustified: 2472 text = tr("Justify"); 2473 break; 2474 case AlignLeft: 2475 text = tr("Align Left"); 2476 break; 2477 case AlignRight: 2478 text = tr("Align Right"); 2479 break; 2480 2481 case NoWebAction: 2482 return 0; 2483 } 2484 2485 if (text.isEmpty()) 2486 return 0; 2487 2488 QAction *a = new QAction(d->q); 2489 a->setText(text); 2490 a->setData(action); 2491 a->setCheckable(checkable); 2492 a->setIcon(icon); 2493 2494 connect(a, SIGNAL(triggered(bool)), 2495 this, SLOT(_q_webActionTriggered(bool))); 2496 2497 d->actions[action] = a; 2498 d->updateAction(action); 2499 return a; 2500 } 2501 2502 /*! 2503 \property QWebPage::modified 2504 \brief whether the page contains unsubmitted form data 2505 2506 By default, this property is false. 2507 */ 2508 bool QWebPage::isModified() const 2509 { 2510 #ifdef QT_NO_UNDOSTACK 2511 return false; 2512 #else 2513 if (!d->undoStack) 2514 return false; 2515 return d->undoStack->canUndo(); 2516 #endif // QT_NO_UNDOSTACK 2517 } 2518 2519 #ifndef QT_NO_UNDOSTACK 2520 /*! 2521 Returns a pointer to the undo stack used for editable content. 2522 */ 2523 QUndoStack *QWebPage::undoStack() const 2524 { 2525 if (!d->undoStack) 2526 d->undoStack = new QUndoStack(const_cast<QWebPage *>(this)); 2527 2528 return d->undoStack; 2529 } 2530 #endif // QT_NO_UNDOSTACK 2531 2532 /*! \reimp 2533 */ 2534 bool QWebPage::event(QEvent *ev) 2535 { 2536 switch (ev->type()) { 2537 case QEvent::Timer: 2538 d->timerEvent(static_cast<QTimerEvent*>(ev)); 2539 break; 2540 case QEvent::MouseMove: 2541 d->mouseMoveEvent(static_cast<QMouseEvent*>(ev)); 2542 break; 2543 case QEvent::GraphicsSceneMouseMove: 2544 d->mouseMoveEvent(static_cast<QGraphicsSceneMouseEvent*>(ev)); 2545 break; 2546 case QEvent::MouseButtonPress: 2547 d->mousePressEvent(static_cast<QMouseEvent*>(ev)); 2548 break; 2549 case QEvent::GraphicsSceneMousePress: 2550 d->mousePressEvent(static_cast<QGraphicsSceneMouseEvent*>(ev)); 2551 break; 2552 case QEvent::MouseButtonDblClick: 2553 d->mouseDoubleClickEvent(static_cast<QMouseEvent*>(ev)); 2554 break; 2555 case QEvent::GraphicsSceneMouseDoubleClick: 2556 d->mouseDoubleClickEvent(static_cast<QGraphicsSceneMouseEvent*>(ev)); 2557 break; 2558 case QEvent::MouseButtonRelease: 2559 d->mouseReleaseEvent(static_cast<QMouseEvent*>(ev)); 2560 break; 2561 case QEvent::GraphicsSceneMouseRelease: 2562 d->mouseReleaseEvent(static_cast<QGraphicsSceneMouseEvent*>(ev)); 2563 break; 2564 #ifndef QT_NO_CONTEXTMENU 2565 case QEvent::ContextMenu: 2566 d->contextMenuEvent(static_cast<QContextMenuEvent*>(ev)->globalPos()); 2567 break; 2568 case QEvent::GraphicsSceneContextMenu: 2569 d->contextMenuEvent(static_cast<QGraphicsSceneContextMenuEvent*>(ev)->screenPos()); 2570 break; 2571 #endif 2572 #ifndef QT_NO_WHEELEVENT 2573 case QEvent::Wheel: 2574 d->wheelEvent(static_cast<QWheelEvent*>(ev)); 2575 break; 2576 case QEvent::GraphicsSceneWheel: 2577 d->wheelEvent(static_cast<QGraphicsSceneWheelEvent*>(ev)); 2578 break; 2579 #endif 2580 case QEvent::KeyPress: 2581 d->keyPressEvent(static_cast<QKeyEvent*>(ev)); 2582 break; 2583 case QEvent::KeyRelease: 2584 d->keyReleaseEvent(static_cast<QKeyEvent*>(ev)); 2585 break; 2586 case QEvent::FocusIn: 2587 d->focusInEvent(static_cast<QFocusEvent*>(ev)); 2588 break; 2589 case QEvent::FocusOut: 2590 d->focusOutEvent(static_cast<QFocusEvent*>(ev)); 2591 break; 2592 #ifndef QT_NO_DRAGANDDROP 2593 case QEvent::DragEnter: 2594 d->dragEnterEvent(static_cast<QDragEnterEvent*>(ev)); 2595 break; 2596 case QEvent::GraphicsSceneDragEnter: 2597 d->dragEnterEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev)); 2598 break; 2599 case QEvent::DragLeave: 2600 d->dragLeaveEvent(static_cast<QDragLeaveEvent*>(ev)); 2601 break; 2602 case QEvent::GraphicsSceneDragLeave: 2603 d->dragLeaveEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev)); 2604 break; 2605 case QEvent::DragMove: 2606 d->dragMoveEvent(static_cast<QDragMoveEvent*>(ev)); 2607 break; 2608 case QEvent::GraphicsSceneDragMove: 2609 d->dragMoveEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev)); 2610 break; 2611 case QEvent::Drop: 2612 d->dropEvent(static_cast<QDropEvent*>(ev)); 2613 break; 2614 case QEvent::GraphicsSceneDrop: 2615 d->dropEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev)); 2616 break; 2617 #endif 2618 case QEvent::InputMethod: 2619 d->inputMethodEvent(static_cast<QInputMethodEvent*>(ev)); 2620 case QEvent::ShortcutOverride: 2621 d->shortcutOverrideEvent(static_cast<QKeyEvent*>(ev)); 2622 break; 2623 case QEvent::Leave: 2624 d->leaveEvent(ev); 2625 break; 2626 #if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) 2627 case QEvent::TouchBegin: 2628 case QEvent::TouchUpdate: 2629 case QEvent::TouchEnd: 2630 d->touchEvent(static_cast<QTouchEvent*>(ev)); 2631 break; 2632 #endif 2633 default: 2634 return QObject::event(ev); 2635 } 2636 2637 return true; 2638 } 2639 2640 /*! 2641 Similar to QWidget::focusNextPrevChild it focuses the next focusable web element 2642 if \a next is true; otherwise the previous element is focused. 2643 2644 Returns true if it can find a new focusable element, or false if it can't. 2645 */ 2646 bool QWebPage::focusNextPrevChild(bool next) 2647 { 2648 QKeyEvent ev(QEvent::KeyPress, Qt::Key_Tab, Qt::KeyboardModifiers(next ? Qt::NoModifier : Qt::ShiftModifier)); 2649 d->keyPressEvent(&ev); 2650 bool hasFocusedNode = false; 2651 Frame *frame = d->page->focusController()->focusedFrame(); 2652 if (frame) { 2653 Document *document = frame->document(); 2654 hasFocusedNode = document && document->focusedNode(); 2655 } 2656 //qDebug() << "focusNextPrevChild(" << next << ") =" << ev.isAccepted() << "focusedNode?" << hasFocusedNode; 2657 return hasFocusedNode; 2658 } 2659 2660 /*! 2661 \property QWebPage::contentEditable 2662 \brief whether the content in this QWebPage is editable or not 2663 \since 4.5 2664 2665 If this property is enabled the contents of the page can be edited by the user through a visible 2666 cursor. If disabled (the default) only HTML elements in the web page with their 2667 \c{contenteditable} attribute set are editable. 2668 */ 2669 void QWebPage::setContentEditable(bool editable) 2670 { 2671 if (d->editable != editable) { 2672 d->editable = editable; 2673 d->page->setTabKeyCyclesThroughElements(!editable); 2674 if (d->mainFrame) { 2675 WebCore::Frame* frame = d->mainFrame->d->frame; 2676 if (editable) { 2677 frame->applyEditingStyleToBodyElement(); 2678 // FIXME: mac port calls this if there is no selectedDOMRange 2679 //frame->setSelectionFromNone(); 2680 } else 2681 frame->removeEditingStyleFromBodyElement(); 2682 } 2683 2684 d->updateEditorActions(); 2685 } 2686 } 2687 2688 bool QWebPage::isContentEditable() const 2689 { 2690 return d->editable; 2691 } 2692 2693 /*! 2694 \property QWebPage::forwardUnsupportedContent 2695 \brief whether QWebPage should forward unsupported content 2696 2697 If enabled, the unsupportedContent() signal is emitted with a network reply that 2698 can be used to read the content. 2699 2700 If disabled, the download of such content is aborted immediately. 2701 2702 By default unsupported content is not forwarded. 2703 */ 2704 2705 void QWebPage::setForwardUnsupportedContent(bool forward) 2706 { 2707 d->forwardUnsupportedContent = forward; 2708 } 2709 2710 bool QWebPage::forwardUnsupportedContent() const 2711 { 2712 return d->forwardUnsupportedContent; 2713 } 2714 2715 /*! 2716 \property QWebPage::linkDelegationPolicy 2717 \brief how QWebPage should delegate the handling of links through the 2718 linkClicked() signal 2719 2720 The default is to delegate no links. 2721 */ 2722 2723 void QWebPage::setLinkDelegationPolicy(LinkDelegationPolicy policy) 2724 { 2725 d->linkPolicy = policy; 2726 } 2727 2728 QWebPage::LinkDelegationPolicy QWebPage::linkDelegationPolicy() const 2729 { 2730 return d->linkPolicy; 2731 } 2732 2733 #ifndef QT_NO_CONTEXTMENU 2734 /*! 2735 Filters the context menu event, \a event, through handlers for scrollbars and 2736 custom event handlers in the web page. Returns true if the event was handled; 2737 otherwise false. 2738 2739 A web page may swallow a context menu event through a custom event handler, allowing for context 2740 menus to be implemented in HTML/JavaScript. This is used by \l{http://maps.google.com/}{Google 2741 Maps}, for example. 2742 */ 2743 bool QWebPage::swallowContextMenuEvent(QContextMenuEvent *event) 2744 { 2745 d->page->contextMenuController()->clearContextMenu(); 2746 2747 if (QWebFrame* webFrame = frameAt(event->pos())) { 2748 Frame* frame = QWebFramePrivate::core(webFrame); 2749 if (Scrollbar* scrollbar = frame->view()->scrollbarAtPoint(PlatformMouseEvent(event, 1).pos())) 2750 return scrollbar->contextMenu(PlatformMouseEvent(event, 1)); 2751 } 2752 2753 WebCore::Frame* focusedFrame = d->page->focusController()->focusedOrMainFrame(); 2754 focusedFrame->eventHandler()->sendContextMenuEvent(PlatformMouseEvent(event, 1)); 2755 ContextMenu *menu = d->page->contextMenuController()->contextMenu(); 2756 // If the website defines its own handler then sendContextMenuEvent takes care of 2757 // calling/showing it and the context menu pointer will be zero. This is the case 2758 // on maps.google.com for example. 2759 2760 return !menu; 2761 } 2762 #endif // QT_NO_CONTEXTMENU 2763 2764 /*! 2765 Updates the page's actions depending on the position \a pos. For example if \a pos is over an image 2766 element the CopyImageToClipboard action is enabled. 2767 */ 2768 void QWebPage::updatePositionDependentActions(const QPoint &pos) 2769 { 2770 // First we disable all actions, but keep track of which ones were originally enabled. 2771 QBitArray originallyEnabledWebActions(QWebPage::WebActionCount); 2772 for (int i = ContextMenuItemTagNoAction; i < ContextMenuItemBaseApplicationTag; ++i) { 2773 QWebPage::WebAction action = webActionForContextMenuAction(WebCore::ContextMenuAction(i)); 2774 if (QAction *a = this->action(action)) { 2775 originallyEnabledWebActions.setBit(action, a->isEnabled()); 2776 a->setEnabled(false); 2777 } 2778 } 2779 2780 d->createMainFrame(); 2781 WebCore::Frame* focusedFrame = d->page->focusController()->focusedOrMainFrame(); 2782 HitTestResult result = focusedFrame->eventHandler()->hitTestResultAtPoint(focusedFrame->view()->windowToContents(pos), /*allowShadowContent*/ false); 2783 2784 if (result.scrollbar()) 2785 d->hitTestResult = QWebHitTestResult(); 2786 else 2787 d->hitTestResult = QWebHitTestResult(new QWebHitTestResultPrivate(result)); 2788 WebCore::ContextMenu menu(result); 2789 menu.populate(); 2790 2791 #if ENABLE(INSPECTOR) 2792 if (d->page->inspectorController()->enabled()) 2793 menu.addInspectElementItem(); 2794 #endif 2795 2796 QBitArray visitedWebActions(QWebPage::WebActionCount); 2797 2798 #ifndef QT_NO_CONTEXTMENU 2799 delete d->currentContextMenu; 2800 2801 // Then we let createContextMenu() enable the actions that are put into the menu 2802 d->currentContextMenu = d->createContextMenu(&menu, menu.platformDescription(), &visitedWebActions); 2803 #endif // QT_NO_CONTEXTMENU 2804 2805 // Finally, we restore the original enablement for the actions that were not put into the menu. 2806 originallyEnabledWebActions &= ~visitedWebActions; // Mask out visited actions (they're part of the menu) 2807 for (int i = 0; i < QWebPage::WebActionCount; ++i) { 2808 if (originallyEnabledWebActions.at(i)) { 2809 if (QAction *a = this->action(QWebPage::WebAction(i))) 2810 a->setEnabled(true); 2811 } 2812 } 2813 2814 // This whole process ensures that any actions put into to the context menu has the right 2815 // enablement, while also keeping the correct enablement for actions that were left out of 2816 // the menu. 2817 2818 } 2819 2820 2821 2822 /*! 2823 \enum QWebPage::Extension 2824 2825 This enum describes the types of extensions that the page can support. Before using these extensions, you 2826 should verify that the extension is supported by calling supportsExtension(). 2827 2828 \value ChooseMultipleFilesExtension Whether the web page supports multiple file selection. 2829 This extension is invoked when the web content requests one or more file names, for example 2830 as a result of the user clicking on a "file upload" button in a HTML form where multiple 2831 file selection is allowed. 2832 2833 \omitvalue ErrorPageExtension (introduced in Qt 4.6) 2834 */ 2835 2836 /*! 2837 \enum QWebPage::ErrorDomain 2838 \since 4.6 2839 \internal 2840 2841 \value QtNetwork 2842 \value Http 2843 \value WebKit 2844 */ 2845 2846 /*! 2847 \class QWebPage::ExtensionOption 2848 \since 4.4 2849 \brief The ExtensionOption class provides an extended input argument to QWebPage's extension support. 2850 2851 \inmodule QtWebKit 2852 2853 \sa QWebPage::extension() 2854 */ 2855 2856 /*! 2857 \class QWebPage::ErrorPageExtensionOption 2858 \since 4.6 2859 \brief The ErrorPageExtensionOption class describes the option 2860 for the error page extension. 2861 2862 \inmodule QtWebKit 2863 2864 The ErrorPageExtensionOption class holds the \a url for which an error occoured as well as 2865 the associated \a frame. 2866 2867 The error itself is reported by an error \a domain, the \a error code as well as \a errorString. 2868 2869 \sa QWebPage::ErrorPageExtensionReturn 2870 */ 2871 2872 /*! 2873 \class QWebPage::ErrorPageExtensionReturn 2874 \since 4.6 2875 \brief The ErrorPageExtensionReturn describes the error page, which will be shown for the 2876 frame for which the error occured. 2877 2878 \inmodule QtWebKit 2879 2880 The ErrorPageExtensionReturn class holds the data needed for creating an error page. Some are 2881 optional such as \a contentType, which defaults to "text/html", as well as the \a encoding, which 2882 is assumed to be UTF-8 if not indicated otherwise. 2883 2884 The error page is stored in the \a content byte array, as HTML content. In order to convert a 2885 QString to a byte array, the QString::toUtf8() method can be used. 2886 2887 External objects such as stylesheets or images referenced in the HTML are located relative to 2888 \a baseUrl. 2889 2890 \sa QWebPage::ErrorPageExtensionOption, QString::toUtf8() 2891 */ 2892 2893 /*! 2894 \fn QWebPage::ErrorPageExtensionReturn::ErrorPageExtensionReturn() 2895 2896 Constructs a new error page object. 2897 */ 2898 2899 /*! 2900 \class QWebPage::ChooseMultipleFilesExtensionOption 2901 \since 4.5 2902 \brief The ChooseMultipleFilesExtensionOption class describes the option 2903 for the multiple files selection extension. 2904 2905 \inmodule QtWebKit 2906 2907 The ChooseMultipleFilesExtensionOption class holds the frame originating the request 2908 and the suggested filenames which might be provided. 2909 2910 \sa QWebPage::chooseFile(), QWebPage::ChooseMultipleFilesExtensionReturn 2911 */ 2912 2913 /*! 2914 \class QWebPage::ChooseMultipleFilesExtensionReturn 2915 \since 4.5 2916 \brief The ChooseMultipleFilesExtensionReturn describes the return value 2917 for the multiple files selection extension. 2918 2919 \inmodule QtWebKit 2920 2921 The ChooseMultipleFilesExtensionReturn class holds the filenames selected by the user 2922 when the extension is invoked. 2923 2924 \sa QWebPage::ChooseMultipleFilesExtensionOption 2925 */ 2926 2927 /*! 2928 This virtual function can be reimplemented in a QWebPage subclass to provide support for extensions. The \a option 2929 argument is provided as input to the extension; the output results can be stored in \a output. 2930 2931 The behavior of this function is determined by \a extension. 2932 2933 You can call supportsExtension() to check if an extension is supported by the page. 2934 2935 Returns true if the extension was called successfully; otherwise returns false. 2936 2937 \sa supportsExtension(), Extension 2938 */ 2939 bool QWebPage::extension(Extension extension, const ExtensionOption *option, ExtensionReturn *output) 2940 { 2941 #ifndef QT_NO_FILEDIALOG 2942 if (extension == ChooseMultipleFilesExtension) { 2943 // FIXME: do not ignore suggestedFiles 2944 QStringList suggestedFiles = static_cast<const ChooseMultipleFilesExtensionOption*>(option)->suggestedFileNames; 2945 QStringList names = QFileDialog::getOpenFileNames(view(), QString::null); 2946 static_cast<ChooseMultipleFilesExtensionReturn*>(output)->fileNames = names; 2947 return true; 2948 } 2949 #endif 2950 2951 return false; 2952 } 2953 2954 /*! 2955 This virtual function returns true if the web page supports \a extension; otherwise false is returned. 2956 2957 \sa extension() 2958 */ 2959 bool QWebPage::supportsExtension(Extension extension) const 2960 { 2961 #ifndef QT_NO_FILEDIALOG 2962 return extension == ChooseMultipleFilesExtension; 2963 #else 2964 Q_UNUSED(extension); 2965 return false; 2966 #endif 2967 } 2968 2969 /*! 2970 Finds the specified string, \a subString, in the page, using the given \a options. 2971 2972 If the HighlightAllOccurrences flag is passed, the function will highlight all occurrences 2973 that exist in the page. All subsequent calls will extend the highlight, rather than 2974 replace it, with occurrences of the new string. 2975 2976 If the HighlightAllOccurrences flag is not passed, the function will select an occurrence 2977 and all subsequent calls will replace the current occurrence with the next one. 2978 2979 To clear the selection, just pass an empty string. 2980 2981 Returns true if \a subString was found; otherwise returns false. 2982 */ 2983 bool QWebPage::findText(const QString &subString, FindFlags options) 2984 { 2985 ::TextCaseSensitivity caseSensitivity = ::TextCaseInsensitive; 2986 if (options & FindCaseSensitively) 2987 caseSensitivity = ::TextCaseSensitive; 2988 2989 if (options & HighlightAllOccurrences) { 2990 if (subString.isEmpty()) { 2991 d->page->unmarkAllTextMatches(); 2992 return true; 2993 } else 2994 return d->page->markAllMatchesForText(subString, caseSensitivity, true, 0); 2995 } else { 2996 ::FindDirection direction = ::FindDirectionForward; 2997 if (options & FindBackward) 2998 direction = ::FindDirectionBackward; 2999 3000 const bool shouldWrap = options & FindWrapsAroundDocument; 3001 3002 return d->page->findString(subString, caseSensitivity, direction, shouldWrap); 3003 } 3004 } 3005 3006 /*! 3007 Returns a pointer to the page's settings object. 3008 3009 \sa QWebSettings::globalSettings() 3010 */ 3011 QWebSettings *QWebPage::settings() const 3012 { 3013 return d->settings; 3014 } 3015 3016 /*! 3017 This function is called when the web content requests a file name, for example 3018 as a result of the user clicking on a "file upload" button in a HTML form. 3019 3020 A suggested filename may be provided in \a suggestedFile. The frame originating the 3021 request is provided as \a parentFrame. 3022 */ 3023 QString QWebPage::chooseFile(QWebFrame *parentFrame, const QString& suggestedFile) 3024 { 3025 Q_UNUSED(parentFrame) 3026 #ifndef QT_NO_FILEDIALOG 3027 return QFileDialog::getOpenFileName(view(), QString::null, suggestedFile); 3028 #else 3029 return QString::null; 3030 #endif 3031 } 3032 3033 /*! 3034 Sets the QNetworkAccessManager \a manager responsible for serving network requests for this 3035 QWebPage. 3036 3037 \note It is currently not supported to change the network access manager after the 3038 QWebPage has used it. The results of doing this are undefined. 3039 3040 \sa networkAccessManager() 3041 */ 3042 void QWebPage::setNetworkAccessManager(QNetworkAccessManager *manager) 3043 { 3044 if (manager == d->networkManager) 3045 return; 3046 if (d->networkManager && d->networkManager->parent() == this) 3047 delete d->networkManager; 3048 d->networkManager = manager; 3049 } 3050 3051 /*! 3052 Returns the QNetworkAccessManager that is responsible for serving network 3053 requests for this QWebPage. 3054 3055 \sa setNetworkAccessManager() 3056 */ 3057 QNetworkAccessManager *QWebPage::networkAccessManager() const 3058 { 3059 if (!d->networkManager) { 3060 QWebPage *that = const_cast<QWebPage *>(this); 3061 that->d->networkManager = new QNetworkAccessManager(that); 3062 } 3063 return d->networkManager; 3064 } 3065 3066 /*! 3067 Sets the QWebPluginFactory \a factory responsible for creating plugins embedded into this 3068 QWebPage. 3069 3070 Note: The plugin factory is only used if the QWebSettings::PluginsEnabled attribute is enabled. 3071 3072 \sa pluginFactory() 3073 */ 3074 void QWebPage::setPluginFactory(QWebPluginFactory *factory) 3075 { 3076 d->pluginFactory = factory; 3077 } 3078 3079 /*! 3080 Returns the QWebPluginFactory that is responsible for creating plugins embedded into 3081 this QWebPage. If no plugin factory is installed a null pointer is returned. 3082 3083 \sa setPluginFactory() 3084 */ 3085 QWebPluginFactory *QWebPage::pluginFactory() const 3086 { 3087 return d->pluginFactory; 3088 } 3089 3090 /*! 3091 This function is called when a user agent for HTTP requests is needed. You can reimplement this 3092 function to dynamically return different user agents for different URLs, based on the \a url parameter. 3093 3094 The default implementation returns the following value: 3095 3096 "Mozilla/5.0 (%Platform%; %Security%; %Subplatform%; %Locale%) AppleWebKit/%WebKitVersion% (KHTML, like Gecko) %AppVersion Safari/%WebKitVersion%" 3097 3098 In this string the following values are replaced at run-time: 3099 \list 3100 \o %Platform% and %Subplatform% are expanded to the windowing system and the operation system. 3101 \o %Security% expands to U if SSL is enabled, otherwise N. SSL is enabled if QSslSocket::supportsSsl() returns true. 3102 \o %Locale% is replaced with QLocale::name(). The locale is determined from the view of the QWebPage. If no view is set on the QWebPage, 3103 then a default constructed QLocale is used instead. 3104 \o %WebKitVersion% is the version of WebKit the application was compiled against. 3105 \o %AppVersion% expands to QCoreApplication::applicationName()/QCoreApplication::applicationVersion() if they're set; otherwise defaulting to Qt and the current Qt version. 3106 \endlist 3107 */ 3108 QString QWebPage::userAgentForUrl(const QUrl& url) const 3109 { 3110 Q_UNUSED(url) 3111 QString ua = QLatin1String("Mozilla/5.0 (" 3112 3113 // Platform 3114 #ifdef Q_WS_MAC 3115 "Macintosh" 3116 #elif defined Q_WS_QWS 3117 "QtEmbedded" 3118 #elif defined Q_WS_WIN 3119 "Windows" 3120 #elif defined Q_WS_X11 3121 "X11" 3122 #elif defined Q_OS_SYMBIAN 3123 "SymbianOS" 3124 #else 3125 "Unknown" 3126 #endif 3127 // Placeholder for Platform Version 3128 "%1; " 3129 3130 // Placeholder for security strength (N or U) 3131 "%2; " 3132 3133 // Subplatform" 3134 #ifdef Q_OS_AIX 3135 "AIX" 3136 #elif defined Q_OS_WIN32 3137 "%3" 3138 #elif defined Q_OS_DARWIN 3139 #ifdef __i386__ || __x86_64__ 3140 "Intel Mac OS X" 3141 #else 3142 "PPC Mac OS X" 3143 #endif 3144 3145 #elif defined Q_OS_BSDI 3146 "BSD" 3147 #elif defined Q_OS_BSD4 3148 "BSD Four" 3149 #elif defined Q_OS_CYGWIN 3150 "Cygwin" 3151 #elif defined Q_OS_DGUX 3152 "DG/UX" 3153 #elif defined Q_OS_DYNIX 3154 "DYNIX/ptx" 3155 #elif defined Q_OS_FREEBSD 3156 "FreeBSD" 3157 #elif defined Q_OS_HPUX 3158 "HP-UX" 3159 #elif defined Q_OS_HURD 3160 "GNU Hurd" 3161 #elif defined Q_OS_IRIX 3162 "SGI Irix" 3163 #elif defined Q_OS_LINUX 3164 "Linux" 3165 #elif defined Q_OS_LYNX 3166 "LynxOS" 3167 #elif defined Q_OS_NETBSD 3168 "NetBSD" 3169 #elif defined Q_OS_OS2 3170 "OS/2" 3171 #elif defined Q_OS_OPENBSD 3172 "OpenBSD" 3173 #elif defined Q_OS_OS2EMX 3174 "OS/2" 3175 #elif defined Q_OS_OSF 3176 "HP Tru64 UNIX" 3177 #elif defined Q_OS_QNX6 3178 "QNX RTP Six" 3179 #elif defined Q_OS_QNX 3180 "QNX" 3181 #elif defined Q_OS_RELIANT 3182 "Reliant UNIX" 3183 #elif defined Q_OS_SCO 3184 "SCO OpenServer" 3185 #elif defined Q_OS_SOLARIS 3186 "Sun Solaris" 3187 #elif defined Q_OS_ULTRIX 3188 "DEC Ultrix" 3189 #elif defined Q_WS_S60 3190 "Series60" 3191 #elif defined Q_OS_UNIX 3192 "UNIX BSD/SYSV system" 3193 #elif defined Q_OS_UNIXWARE 3194 "UnixWare Seven, Open UNIX Eight" 3195 #else 3196 "Unknown" 3197 #endif 3198 // Placeholder for SubPlatform Version 3199 "%4; "); 3200 3201 // Platform Version 3202 QString osVer; 3203 #ifdef Q_OS_SYMBIAN 3204 QSysInfo::SymbianVersion symbianVersion = QSysInfo::symbianVersion(); 3205 switch (symbianVersion) { 3206 case QSysInfo::SV_9_2: 3207 osVer = "/9.2"; 3208 break; 3209 case QSysInfo::SV_9_3: 3210 osVer = "/9.3"; 3211 break; 3212 case QSysInfo::SV_9_4: 3213 osVer = "/9.4"; 3214 break; 3215 default: 3216 osVer = "Unknown"; 3217 } 3218 #endif 3219 ua = ua.arg(osVer); 3220 3221 QChar securityStrength(QLatin1Char('N')); 3222 #if !defined(QT_NO_OPENSSL) 3223 // we could check QSslSocket::supportsSsl() here, but this makes 3224 // OpenSSL, certificates etc being loaded in all cases were QWebPage 3225 // is used. This loading is not needed for non-https. 3226 securityStrength = QLatin1Char('U'); 3227 // this may lead to a false positive: We indicate SSL since it is 3228 // compiled in even though supportsSsl() might return false 3229 #endif 3230 ua = ua.arg(securityStrength); 3231 3232 #if defined Q_OS_WIN32 3233 QString ver; 3234 switch (QSysInfo::WindowsVersion) { 3235 case QSysInfo::WV_32s: 3236 ver = "Windows 3.1"; 3237 break; 3238 case QSysInfo::WV_95: 3239 ver = "Windows 95"; 3240 break; 3241 case QSysInfo::WV_98: 3242 ver = "Windows 98"; 3243 break; 3244 case QSysInfo::WV_Me: 3245 ver = "Windows 98; Win 9x 4.90"; 3246 break; 3247 case QSysInfo::WV_NT: 3248 ver = "WinNT4.0"; 3249 break; 3250 case QSysInfo::WV_2000: 3251 ver = "Windows NT 5.0"; 3252 break; 3253 case QSysInfo::WV_XP: 3254 ver = "Windows NT 5.1"; 3255 break; 3256 case QSysInfo::WV_2003: 3257 ver = "Windows NT 5.2"; 3258 break; 3259 case QSysInfo::WV_VISTA: 3260 ver = "Windows NT 6.0"; 3261 break; 3262 #if QT_VERSION > 0x040500 3263 case QSysInfo::WV_WINDOWS7: 3264 ver = "Windows NT 6.1"; 3265 break; 3266 #endif 3267 case QSysInfo::WV_CE: 3268 ver = "Windows CE"; 3269 break; 3270 case QSysInfo::WV_CENET: 3271 ver = "Windows CE .NET"; 3272 break; 3273 case QSysInfo::WV_CE_5: 3274 ver = "Windows CE 5.x"; 3275 break; 3276 case QSysInfo::WV_CE_6: 3277 ver = "Windows CE 6.x"; 3278 break; 3279 } 3280 ua = QString(ua).arg(ver); 3281 #endif 3282 3283 // SubPlatform Version 3284 QString subPlatformVer; 3285 #ifdef Q_OS_SYMBIAN 3286 QSysInfo::S60Version s60Version = QSysInfo::s60Version(); 3287 switch (s60Version) { 3288 case QSysInfo::SV_S60_3_1: 3289 subPlatformVer = "/3.1"; 3290 break; 3291 case QSysInfo::SV_S60_3_2: 3292 subPlatformVer = "/3.2"; 3293 break; 3294 case QSysInfo::SV_S60_5_0: 3295 subPlatformVer = "/5.0"; 3296 break; 3297 default: 3298 subPlatformVer = " Unknown"; 3299 } 3300 #endif 3301 ua = ua.arg(subPlatformVer); 3302 3303 // Language 3304 QLocale locale; 3305 if (view()) 3306 locale = view()->locale(); 3307 QString name = locale.name(); 3308 name[2] = QLatin1Char('-'); 3309 ua.append(name); 3310 ua.append(QLatin1String(") ")); 3311 3312 // webkit/qt version 3313 ua.append(QString(QLatin1String("AppleWebKit/%1 (KHTML, like Gecko) ")) 3314 .arg(QString(qWebKitVersion()))); 3315 3316 // Application name/version 3317 QString appName = QCoreApplication::applicationName(); 3318 if (!appName.isEmpty()) { 3319 ua.append(appName); 3320 QString appVer = QCoreApplication::applicationVersion(); 3321 if (!appVer.isEmpty()) 3322 ua.append(QLatin1Char('/') + appVer); 3323 } else { 3324 // Qt version 3325 ua.append(QLatin1String("Qt/")); 3326 ua.append(QLatin1String(qVersion())); 3327 } 3328 3329 ua.append(QString(QLatin1String(" Safari/%1")) 3330 .arg(qWebKitVersion())); 3331 3332 return ua; 3333 } 3334 3335 3336 void QWebPagePrivate::_q_onLoadProgressChanged(int) 3337 { 3338 m_totalBytes = page->progress()->totalPageAndResourceBytesToLoad(); 3339 m_bytesReceived = page->progress()->totalBytesReceived(); 3340 } 3341 3342 3343 /*! 3344 Returns the total number of bytes that were received from the network to render the current page, 3345 including extra content such as embedded images. 3346 3347 \sa bytesReceived() 3348 */ 3349 quint64 QWebPage::totalBytes() const 3350 { 3351 return d->m_totalBytes; 3352 } 3353 3354 3355 /*! 3356 Returns the number of bytes that were received from the network to render the current page. 3357 3358 \sa totalBytes() 3359 */ 3360 quint64 QWebPage::bytesReceived() const 3361 { 3362 return d->m_bytesReceived; 3363 } 3364 3365 /*! 3366 \fn void QWebPage::loadStarted() 3367 3368 This signal is emitted when a new load of the page is started. 3369 3370 \sa loadFinished() 3371 */ 3372 3373 /*! 3374 \fn void QWebPage::loadProgress(int progress) 3375 3376 This signal is emitted when the global progress status changes. 3377 The current value is provided by \a progress and scales from 0 to 100, 3378 which is the default range of QProgressBar. 3379 It accumulates changes from all the child frames. 3380 3381 \sa bytesReceived() 3382 */ 3383 3384 /*! 3385 \fn void QWebPage::loadFinished(bool ok) 3386 3387 This signal is emitted when a load of the page is finished. 3388 \a ok will indicate whether the load was successful or any error occurred. 3389 3390 \sa loadStarted() 3391 */ 3392 3393 /*! 3394 \fn void QWebPage::linkHovered(const QString &link, const QString &title, const QString &textContent) 3395 3396 This signal is emitted when the mouse hovers over a link. 3397 3398 \a link contains the link url. 3399 \a title is the link element's title, if it is specified in the markup. 3400 \a textContent provides text within the link element, e.g., text inside an HTML anchor tag. 3401 3402 When the mouse leaves the link element the signal is emitted with empty parameters. 3403 3404 \sa linkClicked() 3405 */ 3406 3407 /*! 3408 \fn void QWebPage::statusBarMessage(const QString& text) 3409 3410 This signal is emitted when the statusbar \a text is changed by the page. 3411 */ 3412 3413 /*! 3414 \fn void QWebPage::frameCreated(QWebFrame *frame) 3415 3416 This signal is emitted whenever the page creates a new \a frame. 3417 */ 3418 3419 /*! 3420 \fn void QWebPage::selectionChanged() 3421 3422 This signal is emitted whenever the selection changes. 3423 3424 \sa selectedText() 3425 */ 3426 3427 /*! 3428 \fn void QWebPage::contentsChanged() 3429 \since 4.5 3430 3431 This signal is emitted whenever the text in form elements changes 3432 as well as other editable content. 3433 3434 \sa contentEditable, QWebFrame::toHtml(), QWebFrame::toPlainText() 3435 */ 3436 3437 /*! 3438 \fn void QWebPage::geometryChangeRequested(const QRect& geom) 3439 3440 This signal is emitted whenever the document wants to change the position and size of the 3441 page to \a geom. This can happen for example through JavaScript. 3442 */ 3443 3444 /*! 3445 \fn void QWebPage::repaintRequested(const QRect& dirtyRect) 3446 3447 This signal is emitted whenever this QWebPage should be updated and no view was set. 3448 \a dirtyRect contains the area that needs to be updated. To paint the QWebPage get 3449 the mainFrame() and call the render(QPainter*, const QRegion&) method with the 3450 \a dirtyRect as the second parameter. 3451 3452 \sa mainFrame() 3453 \sa view() 3454 */ 3455 3456 /*! 3457 \fn void QWebPage::scrollRequested(int dx, int dy, const QRect& rectToScroll) 3458 3459 This signal is emitted whenever the content given by \a rectToScroll needs 3460 to be scrolled \a dx and \a dy downwards and no view was set. 3461 3462 \sa view() 3463 */ 3464 3465 /*! 3466 \fn void QWebPage::windowCloseRequested() 3467 3468 This signal is emitted whenever the page requests the web browser window to be closed, 3469 for example through the JavaScript \c{window.close()} call. 3470 */ 3471 3472 /*! 3473 \fn void QWebPage::printRequested(QWebFrame *frame) 3474 3475 This signal is emitted whenever the page requests the web browser to print \a frame, 3476 for example through the JavaScript \c{window.print()} call. 3477 3478 \sa QWebFrame::print(), QPrintPreviewDialog 3479 */ 3480 3481 /*! 3482 \fn void QWebPage::unsupportedContent(QNetworkReply *reply) 3483 3484 This signal is emitted when WebKit cannot handle a link the user navigated to. 3485 3486 At signal emission time the meta-data of the QNetworkReply \a reply is available. 3487 3488 \note This signal is only emitted if the forwardUnsupportedContent property is set to true. 3489 3490 \sa downloadRequested() 3491 */ 3492 3493 /*! 3494 \fn void QWebPage::downloadRequested(const QNetworkRequest &request) 3495 3496 This signal is emitted when the user decides to download a link. The url of 3497 the link as well as additional meta-information is contained in \a request. 3498 3499 \sa unsupportedContent() 3500 */ 3501 3502 /*! 3503 \fn void QWebPage::microFocusChanged() 3504 3505 This signal is emitted when for example the position of the cursor in an editable form 3506 element changes. It is used inform input methods about the new on-screen position where 3507 the user is able to enter text. This signal is usually connected to QWidget's updateMicroFocus() 3508 slot. 3509 */ 3510 3511 /*! 3512 \fn void QWebPage::linkClicked(const QUrl &url) 3513 3514 This signal is emitted whenever the user clicks on a link and the page's linkDelegationPolicy 3515 property is set to delegate the link handling for the specified \a url. 3516 3517 By default no links are delegated and are handled by QWebPage instead. 3518 3519 \sa linkHovered() 3520 */ 3521 3522 /*! 3523 \fn void QWebPage::toolBarVisibilityChangeRequested(bool visible) 3524 3525 This signal is emitted whenever the visibility of the toolbar in a web browser 3526 window that hosts QWebPage should be changed to \a visible. 3527 */ 3528 3529 /*! 3530 \fn void QWebPage::statusBarVisibilityChangeRequested(bool visible) 3531 3532 This signal is emitted whenever the visibility of the statusbar in a web browser 3533 window that hosts QWebPage should be changed to \a visible. 3534 */ 3535 3536 /*! 3537 \fn void QWebPage::menuBarVisibilityChangeRequested(bool visible) 3538 3539 This signal is emitted whenever the visibility of the menubar in a web browser 3540 window that hosts QWebPage should be changed to \a visible. 3541 */ 3542 3543 /*! 3544 \fn void QWebPage::databaseQuotaExceeded(QWebFrame* frame, QString databaseName); 3545 \since 4.5 3546 3547 This signal is emitted whenever the web site shown in \a frame is asking to store data 3548 to the database \a databaseName and the quota allocated to that web site is exceeded. 3549 */ 3550 3551 /*! 3552 \since 4.5 3553 \fn void QWebPage::saveFrameStateRequested(QWebFrame* frame, QWebHistoryItem* item); 3554 3555 This signal is emitted shortly before the history of navigated pages 3556 in \a frame is changed, for example when navigating back in the history. 3557 3558 The provided QWebHistoryItem, \a item, holds the history entry of the frame before 3559 the change. 3560 3561 A potential use-case for this signal is to store custom data in 3562 the QWebHistoryItem associated to the frame, using QWebHistoryItem::setUserData(). 3563 */ 3564 3565 /*! 3566 \since 4.5 3567 \fn void QWebPage::restoreFrameStateRequested(QWebFrame* frame); 3568 3569 This signal is emitted when the load of \a frame is finished and the application may now update its state accordingly. 3570 */ 3571 3572 /*! 3573 \fn QWebPagePrivate* QWebPage::handle() const 3574 \internal 3575 */ 3576 3577 #include "moc_qwebpage.cpp" 3578