2 Copyright (C) 2007 Trolltech ASA
3 Copyright (C) 2007 Staikos Computing Services Inc.
4 Copyright (C) 2007 Apple Inc.
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.
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.
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.
21 This class provides all functionality needed for loading images, style sheets and html
22 pages from the web. It has a memory cache for these objects.
27 #include "qwebframe.h"
28 #include "qwebpage_p.h"
29 #include "qwebframe_p.h"
30 #include "qwebhistory.h"
31 #include "qwebhistory_p.h"
32 #include "qwebsettings.h"
35 #include "FrameLoaderClientQt.h"
36 #include "ChromeClientQt.h"
37 #include "ContextMenu.h"
38 #include "ContextMenuClientQt.h"
39 #include "DragClientQt.h"
40 #include "DragController.h"
42 #include "EditorClientQt.h"
45 #include "FrameLoader.h"
46 #include "FrameLoadRequest.h"
49 #include "InspectorClientQt.h"
50 #include "InspectorController.h"
51 #include "FocusController.h"
53 #include "PlatformScrollBar.h"
54 #include "PlatformKeyboardEvent.h"
55 #include "PlatformWheelEvent.h"
56 #include "ProgressTracker.h"
59 #include "HitTestResult.h"
60 #include "WindowFeatures.h"
61 #include "LocalizedStrings.h"
64 #include <QDragEnterEvent>
65 #include <QDragLeaveEvent>
66 #include <QDragMoveEvent>
68 #include <QFileDialog>
69 #include <QHttpRequestHeader>
70 #include <QInputDialog>
71 #include <QMessageBox>
72 #include <QNetworkProxy>
76 #if QT_VERSION >= 0x040400
77 #include <QNetworkAccessManager>
78 #include <QNetworkRequest>
80 #include "qwebnetworkinterface.h"
83 using namespace WebCore;
85 static inline DragOperation dropActionToDragOp(Qt::DropActions actions)
88 if (actions & Qt::CopyAction)
89 result |= DragOperationCopy;
90 if (actions & Qt::MoveAction)
91 result |= DragOperationMove;
92 if (actions & Qt::LinkAction)
93 result |= DragOperationLink;
94 return (DragOperation)result;
97 static inline Qt::DropAction dragOpToDropAction(unsigned actions)
99 Qt::DropAction result = Qt::IgnoreAction;
100 if (actions & DragOperationCopy)
101 result = Qt::CopyAction;
102 else if (actions & DragOperationMove)
103 result = Qt::MoveAction;
104 else if (actions & DragOperationLink)
105 result = Qt::LinkAction;
109 QWebPagePrivate::QWebPagePrivate(QWebPage *qq)
114 chromeClient = new ChromeClientQt(q);
115 contextMenuClient = new ContextMenuClientQt();
116 editorClient = new EditorClientQt(q);
117 page = new Page(chromeClient, contextMenuClient, editorClient,
118 new DragClientQt(q), new InspectorClientQt(q));
120 // ### should be configurable
121 page->settings()->setDefaultTextEncodingName("iso-8859-1");
123 settings = new QWebSettings(page->settings());
127 #if QT_VERSION < 0x040400
128 networkInterface = 0;
132 insideOpenCall = false;
134 history.d = new QWebHistoryPrivate(page->backForwardList());
135 memset(actions, 0, sizeof(actions));
138 QWebPagePrivate::~QWebPagePrivate()
143 #if QT_VERSION >= 0x040400
144 delete networkManager;
148 #if QT_VERSION < 0x040400
149 QWebPage::NavigationRequestResponse QWebPagePrivate::navigationRequested(QWebFrame *frame, const QWebNetworkRequest &request, QWebPage::NavigationType type)
152 && frame == mainFrame)
153 return QWebPage::AcceptNavigationRequest;
154 return q->navigationRequested(frame, request, type);
157 QWebPage::NavigationRequestResponse QWebPagePrivate::navigationRequested(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type)
160 && frame == mainFrame)
161 return QWebPage::AcceptNavigationRequest;
162 return q->navigationRequested(frame, request, type);
166 void QWebPagePrivate::createMainFrame()
169 QWebFrameData frameData;
170 frameData.ownerElement = 0;
171 frameData.allowsScrolling = true;
172 frameData.marginWidth = 0;
173 frameData.marginHeight = 0;
174 mainFrame = new QWebFrame(q, &frameData);
175 mainFrame->d->frameView->setFrameGeometry(IntRect(IntPoint(0,0), q->viewportSize()));
177 emit q->frameCreated(mainFrame);
181 static QWebPage::WebAction webActionForContextMenuAction(WebCore::ContextMenuAction action)
184 case WebCore::ContextMenuItemTagOpenLink: return QWebPage::OpenLink;
185 case WebCore::ContextMenuItemTagOpenLinkInNewWindow: return QWebPage::OpenLinkInNewWindow;
186 case WebCore::ContextMenuItemTagDownloadLinkToDisk: return QWebPage::DownloadLinkToDisk;
187 case WebCore::ContextMenuItemTagCopyLinkToClipboard: return QWebPage::CopyLinkToClipboard;
188 case WebCore::ContextMenuItemTagOpenImageInNewWindow: return QWebPage::OpenImageInNewWindow;
189 case WebCore::ContextMenuItemTagDownloadImageToDisk: return QWebPage::DownloadImageToDisk;
190 case WebCore::ContextMenuItemTagCopyImageToClipboard: return QWebPage::CopyImageToClipboard;
191 case WebCore::ContextMenuItemTagOpenFrameInNewWindow: return QWebPage::OpenFrameInNewWindow;
192 case WebCore::ContextMenuItemTagCopy: return QWebPage::Copy;
193 case WebCore::ContextMenuItemTagGoBack: return QWebPage::GoBack;
194 case WebCore::ContextMenuItemTagGoForward: return QWebPage::GoForward;
195 case WebCore::ContextMenuItemTagStop: return QWebPage::Stop;
196 case WebCore::ContextMenuItemTagReload: return QWebPage::Reload;
197 case WebCore::ContextMenuItemTagCut: return QWebPage::Cut;
198 case WebCore::ContextMenuItemTagPaste: return QWebPage::Paste;
199 case WebCore::ContextMenuItemTagDefaultDirection: return QWebPage::SetTextDirectionDefault;
200 case WebCore::ContextMenuItemTagLeftToRight: return QWebPage::SetTextDirectionLeftToRight;
201 case WebCore::ContextMenuItemTagRightToLeft: return QWebPage::SetTextDirectionRightToLeft;
202 case WebCore::ContextMenuItemTagBold: return QWebPage::ToggleBold;
203 case WebCore::ContextMenuItemTagItalic: return QWebPage::ToggleItalic;
204 case WebCore::ContextMenuItemTagUnderline: return QWebPage::ToggleUnderline;
205 case WebCore::ContextMenuItemTagInspectElement: return QWebPage::InspectElement;
208 return QWebPage::NoWebAction;
211 QMenu *QWebPagePrivate::createContextMenu(const WebCore::ContextMenu *webcoreMenu, const QList<WebCore::ContextMenuItem> *items)
213 QMenu *menu = new QMenu;
214 for (int i = 0; i < items->count(); ++i) {
215 const ContextMenuItem &item = items->at(i);
216 switch (item.type()) {
217 case WebCore::CheckableActionType: /* fall through */
218 case WebCore::ActionType: {
219 QWebPage::WebAction action = webActionForContextMenuAction(item.action());
220 QAction *a = q->action(action);
222 ContextMenuItem it(item);
223 webcoreMenu->checkOrEnableIfNeeded(it);
224 PlatformMenuItemDescription desc = it.releasePlatformDescription();
225 a->setEnabled(desc.enabled);
226 a->setChecked(desc.checked);
227 a->setCheckable(item.type() == WebCore::CheckableActionType);
233 case WebCore::SeparatorType:
234 menu->addSeparator();
236 case WebCore::SubmenuType: {
237 QMenu *subMenu = createContextMenu(webcoreMenu, item.platformSubMenu());
238 if (!subMenu->actions().isEmpty()) {
239 subMenu->setTitle(item.title());
240 menu->addAction(subMenu->menuAction());
251 QWebFrame *QWebPagePrivate::frameAt(const QPoint &pos) const
253 QWebFrame *frame = mainFrame;
256 QList<QWebFrame*> children = frame->childFrames();
257 for (int i = 0; i < children.size(); ++i) {
258 if (children.at(i)->geometry().contains(pos)) {
259 frame = children.at(i);
263 if (frame->geometry().contains(pos))
268 void QWebPagePrivate::_q_webActionTriggered(bool checked)
270 QAction *a = qobject_cast<QAction *>(q->sender());
273 QWebPage::WebAction action = static_cast<QWebPage::WebAction>(a->data().toInt());
274 q->triggerAction(action, checked);
277 void QWebPagePrivate::updateAction(QWebPage::WebAction action)
279 QAction *a = actions[action];
280 if (!a || !mainFrame)
283 WebCore::FrameLoader *loader = mainFrame->d->frame->loader();
284 WebCore::Editor *editor = page->focusController()->focusedOrMainFrame()->editor();
286 bool enabled = a->isEnabled();
289 case QWebPage::GoBack:
290 enabled = loader->canGoBackOrForward(-1);
292 case QWebPage::GoForward:
293 enabled = loader->canGoBackOrForward(1);
296 enabled = loader->isLoading();
298 case QWebPage::Reload:
299 enabled = !loader->isLoading();
302 enabled = editor->canCut();
305 enabled = editor->canCopy();
307 case QWebPage::Paste:
308 enabled = editor->canPaste();
312 // those two are handled by QUndoStack
317 a->setEnabled(enabled);
320 void QWebPagePrivate::updateNavigationActions()
322 updateAction(QWebPage::GoBack);
323 updateAction(QWebPage::GoForward);
324 updateAction(QWebPage::Stop);
325 updateAction(QWebPage::Reload);
328 void QWebPagePrivate::updateEditorActions()
330 updateAction(QWebPage::Cut);
331 updateAction(QWebPage::Copy);
332 updateAction(QWebPage::Paste);
335 void QWebPagePrivate::mouseMoveEvent(QMouseEvent *ev)
337 QWebFramePrivate::core(mainFrame)->eventHandler()->handleMouseMoveEvent(PlatformMouseEvent(ev, 0));
339 mainFrame->d->horizontalScrollBar() ? mainFrame->d->horizontalScrollBar()->value() : 0;
341 mainFrame->d->verticalScrollBar() ? mainFrame->d->verticalScrollBar()->value() : 0;
342 IntPoint pt(ev->x() + xOffset, ev->y() + yOffset);
343 WebCore::HitTestResult result = QWebFramePrivate::core(mainFrame)->eventHandler()->hitTestResultAtPoint(pt, false);
345 if (result.absoluteLinkURL() != lastHoverURL
346 || result.title() != lastHoverTitle
347 || result.textContent() != lastHoverContent) {
348 lastHoverURL = result.absoluteLinkURL();
349 lastHoverTitle = result.title();
350 lastHoverContent = result.textContent();
351 emit q->hoveringOverLink(lastHoverURL.prettyURL(), lastHoverTitle, lastHoverContent);
355 void QWebPagePrivate::mousePressEvent(QMouseEvent *ev)
357 QWebFramePrivate::core(mainFrame)->eventHandler()->handleMousePressEvent(PlatformMouseEvent(ev, 1));
360 void QWebPagePrivate::mouseDoubleClickEvent(QMouseEvent *ev)
362 QWebFramePrivate::core(mainFrame)->eventHandler()->handleMousePressEvent(PlatformMouseEvent(ev, 2));
365 void QWebPagePrivate::mouseReleaseEvent(QMouseEvent *ev)
367 QWebFramePrivate::core(mainFrame)->eventHandler()->handleMouseReleaseEvent(PlatformMouseEvent(ev, 0));
370 void QWebPagePrivate::contextMenuEvent(QContextMenuEvent *ev)
372 page->contextMenuController()->clearContextMenu();
374 WebCore::Frame* focusedFrame = page->focusController()->focusedOrMainFrame();
375 focusedFrame->eventHandler()->sendContextMenuEvent(PlatformMouseEvent(ev, 1));
376 ContextMenu *menu = page->contextMenuController()->contextMenu();
377 // If the website defines its own handler then sendContextMenuEvent takes care of
378 // calling/showing it and the context menu pointer will be zero. This is the case
379 // on maps.google.com for example.
383 QWebPageContext oldContext = currentContext;
384 currentContext = QWebPageContext(menu->hitTestResult());
386 const QList<ContextMenuItem> *items = menu->platformDescription();
387 QMenu *qmenu = createContextMenu(menu, items);
389 qmenu->exec(ev->globalPos());
392 currentContext = oldContext;
395 void QWebPagePrivate::wheelEvent(QWheelEvent *ev)
397 WebCore::PlatformWheelEvent pev(ev);
398 bool accepted = QWebFramePrivate::core(mainFrame)->eventHandler()->handleWheelEvent(pev);
399 ev->setAccepted(accepted);
402 void QWebPagePrivate::keyPressEvent(QKeyEvent *ev)
404 bool handled = false;
405 WebCore::Frame *frame = page->focusController()->focusedOrMainFrame();
406 WebCore::Editor *editor = frame->editor();
407 if (editor->canEdit()) {
408 if (ev == QKeySequence::Cut) {
409 q->triggerAction(QWebPage::Cut);
411 } else if (ev == QKeySequence::Copy) {
412 q->triggerAction(QWebPage::Copy);
414 } else if (ev == QKeySequence::Paste) {
415 q->triggerAction(QWebPage::Paste);
417 } else if (ev == QKeySequence::Undo) {
418 q->triggerAction(QWebPage::Undo);
420 } else if (ev == QKeySequence::Redo) {
421 q->triggerAction(QWebPage::Redo);
423 } else if(ev == QKeySequence::MoveToNextChar) {
424 q->triggerAction(QWebPage::MoveToNextChar);
426 } else if(ev == QKeySequence::MoveToPreviousChar) {
427 q->triggerAction(QWebPage::MoveToPreviousChar);
429 } else if(ev == QKeySequence::MoveToNextWord) {
430 q->triggerAction(QWebPage::MoveToNextWord);
432 } else if(ev == QKeySequence::MoveToPreviousWord) {
433 q->triggerAction(QWebPage::MoveToPreviousWord);
435 } else if(ev == QKeySequence::MoveToNextLine) {
436 q->triggerAction(QWebPage::MoveToNextLine);
438 } else if(ev == QKeySequence::MoveToPreviousLine) {
439 q->triggerAction(QWebPage::MoveToPreviousLine);
441 // } else if(ev == QKeySequence::MoveToNextPage) {
442 // } else if(ev == QKeySequence::MoveToPreviousPage) {
443 } else if(ev == QKeySequence::MoveToStartOfLine) {
444 q->triggerAction(QWebPage::MoveToStartOfLine);
446 } else if(ev == QKeySequence::MoveToEndOfLine) {
447 q->triggerAction(QWebPage::MoveToEndOfLine);
449 } else if(ev == QKeySequence::MoveToStartOfBlock) {
450 q->triggerAction(QWebPage::MoveToStartOfBlock);
452 } else if(ev == QKeySequence::MoveToEndOfBlock) {
453 q->triggerAction(QWebPage::MoveToEndOfBlock);
455 } else if(ev == QKeySequence::MoveToStartOfDocument) {
456 q->triggerAction(QWebPage::MoveToStartOfDocument);
458 } else if(ev == QKeySequence::MoveToEndOfDocument) {
459 q->triggerAction(QWebPage::MoveToEndOfDocument);
461 } else if(ev == QKeySequence::SelectNextChar) {
462 q->triggerAction(QWebPage::SelectNextChar);
464 } else if(ev == QKeySequence::SelectPreviousChar) {
465 q->triggerAction(QWebPage::SelectPreviousChar);
467 } else if(ev == QKeySequence::SelectNextWord) {
468 q->triggerAction(QWebPage::SelectNextWord);
470 } else if(ev == QKeySequence::SelectPreviousWord) {
471 q->triggerAction(QWebPage::SelectPreviousWord);
473 } else if(ev == QKeySequence::SelectNextLine) {
474 q->triggerAction(QWebPage::SelectNextLine);
476 } else if(ev == QKeySequence::SelectPreviousLine) {
477 q->triggerAction(QWebPage::SelectPreviousLine);
479 // } else if(ev == QKeySequence::SelectNextPage) {
480 // } else if(ev == QKeySequence::SelectPreviousPage) {
481 } else if(ev == QKeySequence::SelectStartOfLine) {
482 q->triggerAction(QWebPage::SelectStartOfLine);
484 } else if(ev == QKeySequence::SelectEndOfLine) {
485 q->triggerAction(QWebPage::SelectEndOfLine);
487 } else if(ev == QKeySequence::SelectStartOfBlock) {
488 q->triggerAction(QWebPage::SelectStartOfBlock);
490 } else if(ev == QKeySequence::SelectEndOfBlock) {
491 q->triggerAction(QWebPage::SelectEndOfBlock);
493 } else if(ev == QKeySequence::SelectStartOfDocument) {
494 q->triggerAction(QWebPage::SelectStartOfDocument);
496 } else if(ev == QKeySequence::SelectEndOfDocument) {
497 q->triggerAction(QWebPage::SelectEndOfDocument);
499 } else if(ev == QKeySequence::DeleteStartOfWord) {
500 q->triggerAction(QWebPage::DeleteStartOfWord);
502 } else if(ev == QKeySequence::DeleteEndOfWord) {
503 q->triggerAction(QWebPage::DeleteEndOfWord);
505 // } else if(ev == QKeySequence::DeleteEndOfLine) {
509 handled = frame->eventHandler()->keyEvent(ev);
512 PlatformScrollbar *h, *v;
513 h = mainFrame->d->horizontalScrollBar();
514 v = mainFrame->d->verticalScrollBar();
516 if (ev == QKeySequence::MoveToNextPage) {
518 v->setValue(v->value() + q->viewportSize().height());
519 } else if (ev == QKeySequence::MoveToPreviousPage) {
521 v->setValue(v->value() - q->viewportSize().height());
526 v->setValue(v->value() - 10);
530 v->setValue(v->value() + 10);
534 h->setValue(h->value() - 10);
538 h->setValue(h->value() + 10);
547 ev->setAccepted(handled);
550 void QWebPagePrivate::keyReleaseEvent(QKeyEvent *ev)
552 if (ev->isAutoRepeat()) {
553 ev->setAccepted(true);
557 WebCore::Frame* frame = page->focusController()->focusedOrMainFrame();
558 bool handled = frame->eventHandler()->keyEvent(ev);
559 ev->setAccepted(handled);
562 void QWebPagePrivate::focusInEvent(QFocusEvent *ev)
564 if (ev->reason() != Qt::PopupFocusReason)
565 page->focusController()->setFocusedFrame(QWebFramePrivate::core(mainFrame));
568 void QWebPagePrivate::focusOutEvent(QFocusEvent *ev)
570 if (ev->reason() != Qt::PopupFocusReason)
571 page->focusController()->setFocusedFrame(0);
574 void QWebPagePrivate::dragEnterEvent(QDragEnterEvent *ev)
576 #ifndef QT_NO_DRAGANDDROP
577 DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(),
578 dropActionToDragOp(ev->possibleActions()));
579 Qt::DropAction action = dragOpToDropAction(page->dragController()->dragEntered(&dragData));
580 ev->setDropAction(action);
585 void QWebPagePrivate::dragLeaveEvent(QDragLeaveEvent *ev)
587 #ifndef QT_NO_DRAGANDDROP
588 DragData dragData(0, IntPoint(), QCursor::pos(), DragOperationNone);
589 page->dragController()->dragExited(&dragData);
594 void QWebPagePrivate::dragMoveEvent(QDragMoveEvent *ev)
596 #ifndef QT_NO_DRAGANDDROP
597 DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(),
598 dropActionToDragOp(ev->possibleActions()));
599 Qt::DropAction action = dragOpToDropAction(page->dragController()->dragUpdated(&dragData));
600 ev->setDropAction(action);
605 void QWebPagePrivate::dropEvent(QDropEvent *ev)
607 #ifndef QT_NO_DRAGANDDROP
608 DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(),
609 dropActionToDragOp(ev->possibleActions()));
610 Qt::DropAction action = dragOpToDropAction(page->dragController()->performDrag(&dragData));
616 \enum QWebPage::WebAction
618 \value NoWebAction No action is triggered.
619 \value OpenLink Open the current link.
620 \value OpenLinkInNewWindow Open the current link in a new window.
621 \value OpenFrameInNewWindow Replicate the current frame in a new window.
622 \value DownloadLinkToDisk Download the current link to the disk.
623 \value CopyLinkToClipboard Copy the current link to the clipboard.
624 \value OpenImageInNewWindow Open the highlighted image in a new window.
625 \value DownloadImageToDisk Download the highlighted image to the disk.
626 \value CopyImageToClipboard Copy the highlighted image to the clipboard.
627 \value GoBack Navigate back in the history of navigated links.
628 \value GoForward Navigate forward in the history of navigated links.
629 \value Stop Stop loading the current page.
630 \value Reload Reload the current page.
631 \value Cut Cut the content currently selected into the clipboard.
632 \value Copy Copy the content currently selected into the clipboard.
633 \value Paste Paste content from the clipboard.
634 \value Undo Undo the last editing action.
635 \value Redo Redo the last editing action.
636 \value MoveToNextChar Move the cursor to the next character.
637 \value MoveToPreviousChar Move the cursor to the previous character.
638 \value MoveToNextWord Move the cursor to the next word.
639 \value MoveToPreviousWord Move the cursor to the previous word.
640 \value MoveToNextLine Move the cursor to the next line.
641 \value MoveToPreviousLine Move the cursor to the previous line.
642 \value MoveToStartOfLine Move the cursor to the start of the line.
643 \value MoveToEndOfLine Move the cursor to the end of the line.
644 \value MoveToStartOfBlock Move the cursor to the start of the block.
645 \value MoveToEndOfBlock Move the cursor to the end of the block.
646 \value MoveToStartOfDocument Move the cursor to the start of the document.
647 \value MoveToEndOfDocument Move the cursor to the end of the document.
648 \value SelectNextChar Select to the next character.
649 \value SelectPreviousChar Select to the previous character.
650 \value SelectNextWord Select to the next word.
651 \value SelectPreviousWord Select to the previous word.
652 \value SelectNextLine Select to the next line.
653 \value SelectPreviousLine Select to the previous line.
654 \value SelectStartOfLine Select to the start of the line.
655 \value SelectEndOfLine Select to the end of the line.
656 \value SelectStartOfBlock Select to the start of the block.
657 \value SelectEndOfBlock Select to the end of the block.
658 \value SelectStartOfDocument Select to the start of the document.
659 \value SelectEndOfDocument Select to the end of the document.
660 \value DeleteStartOfWord Delete to the start of the word.
661 \value DeleteEndOfWord Delete to the end of the word.
662 \value SetTextDirectionDefault Set the text direction to the default direction.
663 \value SetTextDirectionLeftToRight Set the text direction to left-to-right.
664 \value SetTextDirectionRightToLeft Set the text direction to right-to-left.
665 \value ToggleBold Toggle the formatting between bold and normal weight.
666 \value ToggleItalic Toggle the formatting between italic and normal style.
667 \value ToggleUnderline Toggle underlining.
668 \value InspectElement Show the Web Inspector with the currently highlighted HTML element.
669 \omitvalue WebActionCount
676 \brief The QWebPage class provides a widget that is used to view and edit web documents.
678 QWebPage holds a main frame responsible for web content, settings, the history
679 of navigated links as well as actions. This class can be used, together with QWebFrame,
680 if you want to provide functionality like QWebView in a setup without widgets.
684 Constructs an empty QWebView with parent \a parent.
686 QWebPage::QWebPage(QObject *parent)
688 , d(new QWebPagePrivate(this))
690 setView(qobject_cast<QWidget *>(parent));
692 connect(this, SIGNAL(loadProgressChanged(int)), this, SLOT(_q_onLoadProgressChanged(int)));
698 QWebPage::~QWebPage()
700 FrameLoader *loader = d->mainFrame->d->frame->loader();
702 loader->detachFromParent();
707 Returns the main frame of the page.
709 The main frame provides access to the hierarchy of sub-frames and is also needed if you
710 want to explicitly render a web page into a given painter.
712 QWebFrame *QWebPage::mainFrame() const
714 d->createMainFrame();
719 Returns the frame currently active.
721 QWebFrame *QWebPage::currentFrame() const
723 return static_cast<WebCore::FrameLoaderClientQt *>(d->page->focusController()->focusedOrMainFrame()->loader()->client())->webFrame();
727 Returns a pointer to the view's history of navigated web pages.
730 QWebHistory *QWebPage::history() const
736 Sets the \a view that is associated with the web page.
740 void QWebPage::setView(QWidget *view)
743 setViewportSize(view ? view->size() : QSize(0, 0));
747 Returns the view widget that is associated with the web page.
751 QWidget *QWebPage::view() const
758 This function is called whenever a JavaScript program tries to print to what is the console in web browsers.
760 void QWebPage::javaScriptConsoleMessage(const QString& message, unsigned int lineNumber, const QString& sourceID)
765 This function is called whenever a JavaScript program calls the alert() function.
767 void QWebPage::javaScriptAlert(QWebFrame *frame, const QString& msg)
769 QMessageBox::information(d->view, mainFrame()->title(), msg, QMessageBox::Ok);
773 This function is called whenever a JavaScript program calls the confirm() function.
775 bool QWebPage::javaScriptConfirm(QWebFrame *frame, const QString& msg)
777 return 0 == QMessageBox::information(d->view, mainFrame()->title(), msg, QMessageBox::Yes, QMessageBox::No);
781 This function is called whenever a JavaScript program tries to prompt the user of input.
783 bool QWebPage::javaScriptPrompt(QWebFrame *frame, const QString& msg, const QString& defaultValue, QString* result)
786 #ifndef QT_NO_INPUTDIALOG
787 QString x = QInputDialog::getText(d->view, mainFrame()->title(), msg, QLineEdit::Normal, defaultValue, &ok);
796 This function is called whenever WebKit wants to create a new window, for example as a result of
797 a JavaScript request to open a document in a new window.
799 QWebPage *QWebPage::createWindow()
801 QWebView *webView = qobject_cast<QWebView *>(d->view);
803 QWebView *newView = webView->createWindow();
805 return newView->page();
811 This function is called whenever WebKit wants to create a new window that should act as a modal dialog.
813 QWebPage *QWebPage::createModalDialog()
819 This function is called whenever WebKit encounters a HTML object element with type "application/x-qt-plugin".
820 The \a classid, \a url, \a paramNames and \a paramValues correspond to the HTML object element attributes and
821 child elements to configure the embeddable object.
823 QObject *QWebPage::createPlugin(const QString &classid, const QUrl &url, const QStringList ¶mNames, const QStringList ¶mValues)
828 Q_UNUSED(paramValues)
832 static WebCore::FrameLoadRequest frameLoadRequest(const QUrl &url, WebCore::Frame *frame)
834 WebCore::ResourceRequest rr(url, frame->loader()->outgoingReferrer());
835 return WebCore::FrameLoadRequest(rr);
838 static void openNewWindow(const QUrl& url, WebCore::Frame* frame)
840 if (Page* oldPage = frame->page()) {
841 WindowFeatures features;
842 if (Page* newPage = oldPage->chrome()->createWindow(frame,
843 frameLoadRequest(url, frame), features))
844 newPage->chrome()->show();
849 This function can be called to trigger the specified \a action.
850 It is also called by QtWebKit if the user triggers the action, for example
851 through a context menu item.
853 If \a action is a checkable action then \a checked specified whether the action
856 void QWebPage::triggerAction(WebAction action, bool checked)
858 WebCore::Frame *frame = d->page->focusController()->focusedOrMainFrame();
859 WebCore::Editor *editor = frame->editor();
860 const char *command = 0;
864 if (QWebFrame *targetFrame = d->currentContext.targetFrame()) {
865 WTF::RefPtr<WebCore::Frame> wcFrame = targetFrame->d->frame;
866 targetFrame->d->frame->loader()->load(frameLoadRequest(d->currentContext.linkUrl(), wcFrame.get()),
867 /*lockHistory*/ false,
868 /*userGesture*/ true,
870 /*HTMLFormElement*/ 0,
872 WTF::HashMap<String, String>());
877 case OpenLinkInNewWindow:
878 openNewWindow(d->currentContext.linkUrl(), frame);
880 case OpenFrameInNewWindow:
882 case DownloadLinkToDisk:
883 case CopyLinkToClipboard:
884 editor->copyURL(d->currentContext.linkUrl(), d->currentContext.text());
886 case OpenImageInNewWindow:
887 openNewWindow(d->currentContext.imageUrl(), frame);
889 case DownloadImageToDisk:
890 case CopyImageToClipboard:
896 d->page->goForward();
899 mainFrame()->d->frame->loader()->stopForUserCancel();
902 mainFrame()->d->frame->loader()->reload();
922 command = "MoveForward";
924 case MoveToPreviousChar:
925 command = "MoveBackward";
928 command = "MoveWordForward";
930 case MoveToPreviousWord:
931 command = "MoveWordBackward";
934 command = "MoveDown";
936 case MoveToPreviousLine:
939 case MoveToStartOfLine:
940 command = "MoveToBeginningOfLine";
942 case MoveToEndOfLine:
943 command = "MoveToEndOfLine";
945 case MoveToStartOfBlock:
946 command = "MoveToBeginningOfParagraph";
948 case MoveToEndOfBlock:
949 command = "MoveToEndOfParagraph";
951 case MoveToStartOfDocument:
952 command = "MoveToBeginningOfDocument";
954 case MoveToEndOfDocument:
955 command = "MoveToEndOfDocument";
958 command = "MoveForwardAndModifySelection";
960 case SelectPreviousChar:
961 command = "MoveBackwardAndModifySelection";
964 command = "MoveWordForwardAndModifySelection";
966 case SelectPreviousWord:
967 command = "MoveWordBackwardAndModifySelection";
970 command = "MoveDownAndModifySelection";
972 case SelectPreviousLine:
973 command = "MoveUpAndModifySelection";
975 case SelectStartOfLine:
976 command = "MoveToBeginningOfLineAndModifySelection";
978 case SelectEndOfLine:
979 command = "MoveToEndOfLineAndModifySelection";
981 case SelectStartOfBlock:
982 command = "MoveToBeginningOfParagraphAndModifySelection";
984 case SelectEndOfBlock:
985 command = "MoveToEndOfParagraphAndModifySelection";
987 case SelectStartOfDocument:
988 command = "MoveToBeginningOfDocumentAndModifySelection";
990 case SelectEndOfDocument:
991 command = "MoveToEndOfDocumentAndModifySelection";
993 case DeleteStartOfWord:
994 command = "DeleteWordBackward";
996 case DeleteEndOfWord:
997 command = "DeleteWordForward";
1000 case SetTextDirectionDefault:
1001 editor->setBaseWritingDirection("inherit");
1003 case SetTextDirectionLeftToRight:
1004 editor->setBaseWritingDirection("ltr");
1006 case SetTextDirectionRightToLeft:
1007 editor->setBaseWritingDirection("rtl");
1011 command = "ToggleBold";
1014 command = "ToggleItalic";
1016 case ToggleUnderline:
1017 editor->toggleUnderline();
1019 case InspectElement:
1020 d->page->inspectorController()->inspect(d->currentContext.d->innerNonSharedNode.get());
1027 editor->command(command).execute();
1030 QSize QWebPage::viewportSize() const
1032 QWebFrame *frame = mainFrame();
1033 if (frame->d->frame && frame->d->frameView)
1034 return frame->d->frameView->frameGeometry().size();
1039 \property QWebPage::viewportSize
1041 Specifies the size of the viewport. The size affects for example the visibility of scrollbars
1042 if the document is larger than the viewport.
1044 void QWebPage::setViewportSize(const QSize &size) const
1046 QWebFrame *frame = mainFrame();
1047 if (frame->d->frame && frame->d->frameView) {
1048 frame->d->frameView->setFrameGeometry(QRect(QPoint(0, 0), size));
1049 frame->d->frame->forceLayout();
1050 frame->d->frame->view()->adjustViewSize();
1055 #if QT_VERSION < 0x040400
1056 QWebPage::NavigationRequestResponse QWebPage::navigationRequested(QWebFrame *frame, const QWebNetworkRequest &request, QWebPage::NavigationType type)
1058 QWebPage::NavigationRequestResponse QWebPage::navigationRequested(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type)
1062 return AcceptNavigationRequest;
1066 \property QWebPage::selectedText
1068 Returns the text currently selected.
1070 QString QWebPage::selectedText() const
1072 return d->page->focusController()->focusedOrMainFrame()->selectedText();
1076 Returns a QAction for the specified WebAction \a action.
1078 The action is owned by the QWebPage but you can customize the look by
1079 changing its properties.
1081 QWebPage also takes care of implementing the action, so that upon
1082 triggering the corresponding action is performed on the page.
1084 QAction *QWebPage::action(WebAction action) const
1086 if (action == QWebPage::NoWebAction) return 0;
1087 if (d->actions[action])
1088 return d->actions[action];
1091 bool checkable = false;
1095 text = contextMenuItemTagOpenLink();
1097 case OpenLinkInNewWindow:
1098 text = contextMenuItemTagOpenLinkInNewWindow();
1100 case OpenFrameInNewWindow:
1101 text = contextMenuItemTagOpenFrameInNewWindow();
1104 case DownloadLinkToDisk:
1105 text = contextMenuItemTagDownloadLinkToDisk();
1107 case CopyLinkToClipboard:
1108 text = contextMenuItemTagCopyLinkToClipboard();
1111 case OpenImageInNewWindow:
1112 text = contextMenuItemTagOpenImageInNewWindow();
1114 case DownloadImageToDisk:
1115 text = contextMenuItemTagDownloadImageToDisk();
1117 case CopyImageToClipboard:
1118 text = contextMenuItemTagCopyImageToClipboard();
1122 text = contextMenuItemTagGoBack();
1125 text = contextMenuItemTagGoForward();
1128 text = contextMenuItemTagStop();
1131 text = contextMenuItemTagReload();
1135 text = contextMenuItemTagCut();
1138 text = contextMenuItemTagCopy();
1141 text = contextMenuItemTagPaste();
1145 QAction *a = undoStack()->createUndoAction(d->q);
1146 d->actions[action] = a;
1150 QAction *a = undoStack()->createRedoAction(d->q);
1151 d->actions[action] = a;
1154 case MoveToNextChar:
1155 case MoveToPreviousChar:
1156 case MoveToNextWord:
1157 case MoveToPreviousWord:
1158 case MoveToNextLine:
1159 case MoveToPreviousLine:
1160 case MoveToStartOfLine:
1161 case MoveToEndOfLine:
1162 case MoveToStartOfBlock:
1163 case MoveToEndOfBlock:
1164 case MoveToStartOfDocument:
1165 case MoveToEndOfDocument:
1166 case SelectNextChar:
1167 case SelectPreviousChar:
1168 case SelectNextWord:
1169 case SelectPreviousWord:
1170 case SelectNextLine:
1171 case SelectPreviousLine:
1172 case SelectStartOfLine:
1173 case SelectEndOfLine:
1174 case SelectStartOfBlock:
1175 case SelectEndOfBlock:
1176 case SelectStartOfDocument:
1177 case SelectEndOfDocument:
1178 case DeleteStartOfWord:
1179 case DeleteEndOfWord:
1182 case SetTextDirectionDefault:
1183 text = contextMenuItemTagDefaultDirection();
1185 case SetTextDirectionLeftToRight:
1186 text = contextMenuItemTagLeftToRight();
1189 case SetTextDirectionRightToLeft:
1190 text = contextMenuItemTagRightToLeft();
1195 text = contextMenuItemTagBold();
1199 text = contextMenuItemTagItalic();
1202 case ToggleUnderline:
1203 text = contextMenuItemTagUnderline();
1207 case InspectElement:
1208 text = contextMenuItemTagInspectElement();
1218 QAction *a = new QAction(d->q);
1221 a->setCheckable(checkable);
1223 connect(a, SIGNAL(triggered(bool)),
1224 this, SLOT(_q_webActionTriggered(bool)));
1226 d->actions[action] = a;
1227 d->updateAction(action);
1232 \property QWebPage::modified
1234 Specifies if the page contains unsubmitted form data.
1236 bool QWebPage::isModified() const
1243 Returns a pointer to the undo stack used for editable content.
1245 QUndoStack *QWebPage::undoStack() const
1248 d->undoStack = new QUndoStack(const_cast<QWebPage *>(this));
1250 return d->undoStack;
1255 bool QWebPage::event(QEvent *ev)
1257 switch (ev->type()) {
1258 case QEvent::MouseMove:
1259 d->mouseMoveEvent(static_cast<QMouseEvent*>(ev));
1261 case QEvent::MouseButtonPress:
1262 d->mousePressEvent(static_cast<QMouseEvent*>(ev));
1264 case QEvent::MouseButtonDblClick:
1265 d->mouseDoubleClickEvent(static_cast<QMouseEvent*>(ev));
1267 case QEvent::MouseButtonRelease:
1268 d->mouseReleaseEvent(static_cast<QMouseEvent*>(ev));
1270 case QEvent::ContextMenu:
1271 d->contextMenuEvent(static_cast<QContextMenuEvent*>(ev));
1274 d->wheelEvent(static_cast<QWheelEvent*>(ev));
1276 case QEvent::KeyPress:
1277 d->keyPressEvent(static_cast<QKeyEvent*>(ev));
1279 case QEvent::KeyRelease:
1280 d->keyReleaseEvent(static_cast<QKeyEvent*>(ev));
1282 case QEvent::FocusIn:
1283 d->focusInEvent(static_cast<QFocusEvent*>(ev));
1285 case QEvent::FocusOut:
1286 d->focusOutEvent(static_cast<QFocusEvent*>(ev));
1288 #ifndef QT_NO_DRAGANDDROP
1289 case QEvent::DragEnter:
1290 d->dragEnterEvent(static_cast<QDragEnterEvent*>(ev));
1292 case QEvent::DragLeave:
1293 d->dragLeaveEvent(static_cast<QDragLeaveEvent*>(ev));
1295 case QEvent::DragMove:
1296 d->dragMoveEvent(static_cast<QDragMoveEvent*>(ev));
1299 d->dropEvent(static_cast<QDropEvent*>(ev));
1303 return QObject::event(ev);
1310 Similar to QWidget::focusNextPrevChild it focuses the next focusable web element
1311 if \a next is true. Otherwise the previous element is focused.
1313 bool QWebPage::focusNextPrevChild(bool next)
1315 QKeyEvent ev(QEvent::KeyPress, Qt::Key_Tab, Qt::KeyboardModifiers(next ? Qt::NoModifier : Qt::ShiftModifier));
1316 d->keyPressEvent(&ev);
1317 bool hasFocusedNode = false;
1318 Frame *frame = d->page->focusController()->focusedFrame();
1320 Document *document = frame->document();
1321 hasFocusedNode = document && document->focusedNode();
1323 //qDebug() << "focusNextPrevChild(" << next << ") =" << ev.isAccepted() << "focusedNode?" << hasFocusedNode;
1324 return hasFocusedNode;
1328 Returns a pointe to the page's settings object.
1330 QWebSettings *QWebPage::settings()
1336 This function is called when the web content requests a file name, for example
1337 as a result of the user clicking on a "file upload" button in a HTML form.
1339 QString QWebPage::chooseFile(QWebFrame *parentFrame, const QString& oldFile)
1341 #ifndef QT_NO_FILEDIALOG
1342 return QFileDialog::getOpenFileName(d->view, QString::null, oldFile);
1344 return QString::null;
1348 #if QT_VERSION < 0x040400
1350 void QWebPage::setNetworkInterface(QWebNetworkInterface *interface)
1352 d->networkInterface = interface;
1355 QWebNetworkInterface *QWebPage::networkInterface() const
1357 if (d->networkInterface)
1358 return d->networkInterface;
1360 return QWebNetworkInterface::defaultInterface();
1363 #ifndef QT_NO_NETWORKPROXY
1364 void QWebPage::setNetworkProxy(const QNetworkProxy& proxy)
1366 d->networkProxy = proxy;
1369 QNetworkProxy QWebPage::networkProxy() const
1371 return d->networkProxy;
1378 Sets the QNetworkAccessManager \a manager that is responsible for serving network
1379 requests for this QWebPage.
1381 \sa networkAccessManager
1383 void QWebPage::setNetworkAccessManager(QNetworkAccessManager *manager)
1385 if (manager == d->networkManager)
1387 delete d->networkManager;
1388 d->networkManager = manager;
1392 Returns the QNetworkAccessManager \a manager that is responsible for serving network
1393 requests for this QWebPage.
1395 \sa setNetworkAccessManager
1397 QNetworkAccessManager *QWebPage::networkAccessManager() const
1399 if (!d->networkManager) {
1400 QWebPage *that = const_cast<QWebPage *>(this);
1401 that->d->networkManager = new QNetworkAccessManager(that);
1403 return d->networkManager;
1409 This function is called when a user agent for HTTP requests is needed. You can re-implement this
1410 function to dynamically return different user agent's for different urls, based on the \a url parameter.
1412 QString QWebPage::userAgentFor(const QUrl& url) const
1415 return QLatin1String("Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en) AppleWebKit/418.9.1 (KHTML, like Gecko) Safari/419.3 Qt");
1419 void QWebPagePrivate::_q_onLoadProgressChanged(int) {
1420 m_totalBytes = page->progress()->totalPageAndResourceBytesToLoad();
1421 m_bytesReceived = page->progress()->totalBytesReceived();
1426 Returns the total number of bytes that were received from the network to render the current page,
1427 including extra content such as embedded images.
1429 quint64 QWebPage::totalBytes() const {
1430 return d->m_bytesReceived;
1435 Returns the number of bytes that were received from the network to render the current page.
1437 quint64 QWebPage::bytesReceived() const {
1438 return d->m_totalBytes;
1441 QWebPageContext::QWebPageContext(const WebCore::HitTestResult &hitTest)
1442 : d(new QWebPageContextPrivate)
1444 d->pos = hitTest.point();
1445 d->text = hitTest.textContent();
1446 d->linkUrl = hitTest.absoluteLinkURL().string();
1447 d->imageUrl = hitTest.absoluteImageURL().string();
1448 d->innerNonSharedNode = hitTest.innerNonSharedNode();
1449 WebCore::Image *img = hitTest.image();
1451 QPixmap *pix = img->getPixmap();
1455 WebCore::Frame *frame = hitTest.targetFrame();
1457 d->targetFrame = frame->view()->qwebframe();
1460 QWebPageContext::QWebPageContext()
1465 QWebPageContext::QWebPageContext(const QWebPageContext &other)
1469 d = new QWebPageContextPrivate(*other.d);
1472 QWebPageContext &QWebPageContext::operator=(const QWebPageContext &other)
1474 if (this != &other) {
1477 d = new QWebPageContextPrivate;
1487 QWebPageContext::~QWebPageContext()
1492 QPoint QWebPageContext::pos() const
1499 QString QWebPageContext::text() const
1506 QUrl QWebPageContext::linkUrl() const
1513 QUrl QWebPageContext::imageUrl() const
1520 QPixmap QWebPageContext::image() const
1527 QWebFrame *QWebPageContext::targetFrame() const
1531 return d->targetFrame;
1535 \fn void QWebPage::loadProgressChanged(int progress)
1537 This signal is emitted when the global progress status changes.
1538 The current value is provided by \a progress in percent.
1539 It accumulates changes from all the child frames.
1543 \fn void QWebPage::hoveringOverLink(const QString &link, const QString &title, const QString &textContent)
1545 This signal is emitted when the mouse is hovering over a link.
1546 The first parameter is the \a link url, the second is the link \a title
1547 if any, and third \a textContent is the text content. Method is emitter with both
1548 empty parameters when the mouse isn't hovering over any link element.
1552 \fn void QWebPage::statusBarTextChanged(const QString& text)
1554 This signal is emitted when the statusbar \a text is changed by the page.
1558 \fn void QWebPage::frameCreated(QWebFrame *frame)
1560 This signal is emitted whenever the page creates a new \a frame.
1564 \fn void QWebPage::selectionChanged()
1566 This signal is emitted whenever the selection changes.
1570 \fn void QWebPage::geometryChangeRequest(const QRect& geom)
1572 This signal is emitted whenever the document wants to change the position and size of the
1573 page to \a geom. This can happen for example through JavaScript.
1576 #include "moc_qwebpage.cpp"