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 "FrameView.h"
37 #include "ChromeClientQt.h"
38 #include "ContextMenu.h"
39 #include "ContextMenuClientQt.h"
40 #include "DragClientQt.h"
41 #include "DragController.h"
43 #include "EditorClientQt.h"
46 #include "FrameLoader.h"
47 #include "FrameLoadRequest.h"
50 #include "InspectorClientQt.h"
51 #include "InspectorController.h"
52 #include "FocusController.h"
54 #include "PlatformScrollBar.h"
55 #include "PlatformKeyboardEvent.h"
56 #include "PlatformWheelEvent.h"
57 #include "ProgressTracker.h"
60 #include "HitTestResult.h"
61 #include "WindowFeatures.h"
62 #include "LocalizedStrings.h"
64 #include <QApplication>
66 #include <QDragEnterEvent>
67 #include <QDragLeaveEvent>
68 #include <QDragMoveEvent>
70 #include <QFileDialog>
71 #include <QHttpRequestHeader>
72 #include <QInputDialog>
73 #include <QMessageBox>
74 #include <QNetworkProxy>
78 #if QT_VERSION >= 0x040400
79 #include <QNetworkAccessManager>
80 #include <QNetworkRequest>
82 #include "qwebnetworkinterface.h"
85 using namespace WebCore;
87 static inline DragOperation dropActionToDragOp(Qt::DropActions actions)
90 if (actions & Qt::CopyAction)
91 result |= DragOperationCopy;
92 if (actions & Qt::MoveAction)
93 result |= DragOperationMove;
94 if (actions & Qt::LinkAction)
95 result |= DragOperationLink;
96 return (DragOperation)result;
99 static inline Qt::DropAction dragOpToDropAction(unsigned actions)
101 Qt::DropAction result = Qt::IgnoreAction;
102 if (actions & DragOperationCopy)
103 result = Qt::CopyAction;
104 else if (actions & DragOperationMove)
105 result = Qt::MoveAction;
106 else if (actions & DragOperationLink)
107 result = Qt::LinkAction;
111 QWebPagePrivate::QWebPagePrivate(QWebPage *qq)
115 , viewportSize(QSize(0,0))
117 chromeClient = new ChromeClientQt(q);
118 contextMenuClient = new ContextMenuClientQt();
119 editorClient = new EditorClientQt(q);
120 page = new Page(chromeClient, contextMenuClient, editorClient,
121 new DragClientQt(q), new InspectorClientQt(q));
123 // ### should be configurable
124 page->settings()->setDefaultTextEncodingName("iso-8859-1");
126 settings = new QWebSettings(page->settings());
130 #if QT_VERSION < 0x040400
131 networkInterface = 0;
136 insideOpenCall = false;
138 history.d = new QWebHistoryPrivate(page->backForwardList());
139 memset(actions, 0, sizeof(actions));
142 QWebPagePrivate::~QWebPagePrivate()
147 #if QT_VERSION >= 0x040400
148 delete networkManager;
152 #if QT_VERSION < 0x040400
153 QWebPage::NavigationRequestResponse QWebPagePrivate::navigationRequested(QWebFrame *frame, const QWebNetworkRequest &request, QWebPage::NavigationType type)
156 && frame == mainFrame)
157 return QWebPage::AcceptNavigationRequest;
158 return q->navigationRequested(frame, request, type);
161 QWebPage::NavigationRequestResponse QWebPagePrivate::navigationRequested(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type)
164 && frame == mainFrame)
165 return QWebPage::AcceptNavigationRequest;
166 return q->navigationRequested(frame, request, type);
170 void QWebPagePrivate::createMainFrame()
173 QWebFrameData frameData;
174 frameData.ownerElement = 0;
175 frameData.allowsScrolling = true;
176 frameData.marginWidth = 0;
177 frameData.marginHeight = 0;
178 mainFrame = new QWebFrame(q, &frameData);
179 mainFrame->d->frame->view()->setFrameGeometry(IntRect(IntPoint(0,0), q->viewportSize()));
181 emit q->frameCreated(mainFrame);
185 static QWebPage::WebAction webActionForContextMenuAction(WebCore::ContextMenuAction action)
188 case WebCore::ContextMenuItemTagOpenLink: return QWebPage::OpenLink;
189 case WebCore::ContextMenuItemTagOpenLinkInNewWindow: return QWebPage::OpenLinkInNewWindow;
190 case WebCore::ContextMenuItemTagDownloadLinkToDisk: return QWebPage::DownloadLinkToDisk;
191 case WebCore::ContextMenuItemTagCopyLinkToClipboard: return QWebPage::CopyLinkToClipboard;
192 case WebCore::ContextMenuItemTagOpenImageInNewWindow: return QWebPage::OpenImageInNewWindow;
193 case WebCore::ContextMenuItemTagDownloadImageToDisk: return QWebPage::DownloadImageToDisk;
194 case WebCore::ContextMenuItemTagCopyImageToClipboard: return QWebPage::CopyImageToClipboard;
195 case WebCore::ContextMenuItemTagOpenFrameInNewWindow: return QWebPage::OpenFrameInNewWindow;
196 case WebCore::ContextMenuItemTagCopy: return QWebPage::Copy;
197 case WebCore::ContextMenuItemTagGoBack: return QWebPage::GoBack;
198 case WebCore::ContextMenuItemTagGoForward: return QWebPage::GoForward;
199 case WebCore::ContextMenuItemTagStop: return QWebPage::Stop;
200 case WebCore::ContextMenuItemTagReload: return QWebPage::Reload;
201 case WebCore::ContextMenuItemTagCut: return QWebPage::Cut;
202 case WebCore::ContextMenuItemTagPaste: return QWebPage::Paste;
203 case WebCore::ContextMenuItemTagDefaultDirection: return QWebPage::SetTextDirectionDefault;
204 case WebCore::ContextMenuItemTagLeftToRight: return QWebPage::SetTextDirectionLeftToRight;
205 case WebCore::ContextMenuItemTagRightToLeft: return QWebPage::SetTextDirectionRightToLeft;
206 case WebCore::ContextMenuItemTagBold: return QWebPage::ToggleBold;
207 case WebCore::ContextMenuItemTagItalic: return QWebPage::ToggleItalic;
208 case WebCore::ContextMenuItemTagUnderline: return QWebPage::ToggleUnderline;
209 case WebCore::ContextMenuItemTagInspectElement: return QWebPage::InspectElement;
212 return QWebPage::NoWebAction;
215 QMenu *QWebPagePrivate::createContextMenu(const WebCore::ContextMenu *webcoreMenu, const QList<WebCore::ContextMenuItem> *items)
217 QMenu *menu = new QMenu;
218 for (int i = 0; i < items->count(); ++i) {
219 const ContextMenuItem &item = items->at(i);
220 switch (item.type()) {
221 case WebCore::CheckableActionType: /* fall through */
222 case WebCore::ActionType: {
223 QWebPage::WebAction action = webActionForContextMenuAction(item.action());
224 QAction *a = q->action(action);
226 ContextMenuItem it(item);
227 webcoreMenu->checkOrEnableIfNeeded(it);
228 PlatformMenuItemDescription desc = it.releasePlatformDescription();
229 a->setEnabled(desc.enabled);
230 a->setChecked(desc.checked);
231 a->setCheckable(item.type() == WebCore::CheckableActionType);
237 case WebCore::SeparatorType:
238 menu->addSeparator();
240 case WebCore::SubmenuType: {
241 QMenu *subMenu = createContextMenu(webcoreMenu, item.platformSubMenu());
242 if (!subMenu->actions().isEmpty()) {
243 subMenu->setTitle(item.title());
244 menu->addAction(subMenu->menuAction());
255 QWebFrame *QWebPagePrivate::frameAt(const QPoint &pos) const
257 QWebFrame *frame = mainFrame;
260 QList<QWebFrame*> children = frame->childFrames();
261 for (int i = 0; i < children.size(); ++i) {
262 if (children.at(i)->geometry().contains(pos)) {
263 frame = children.at(i);
267 if (frame->geometry().contains(pos))
272 void QWebPagePrivate::_q_webActionTriggered(bool checked)
274 QAction *a = qobject_cast<QAction *>(q->sender());
277 QWebPage::WebAction action = static_cast<QWebPage::WebAction>(a->data().toInt());
278 q->triggerAction(action, checked);
281 void QWebPagePrivate::updateAction(QWebPage::WebAction action)
283 QAction *a = actions[action];
284 if (!a || !mainFrame)
287 WebCore::FrameLoader *loader = mainFrame->d->frame->loader();
288 WebCore::Editor *editor = page->focusController()->focusedOrMainFrame()->editor();
290 bool enabled = a->isEnabled();
293 case QWebPage::GoBack:
294 enabled = loader->canGoBackOrForward(-1);
296 case QWebPage::GoForward:
297 enabled = loader->canGoBackOrForward(1);
300 enabled = loader->isLoading();
302 case QWebPage::Reload:
303 enabled = !loader->isLoading();
306 enabled = editor->canCut();
309 enabled = editor->canCopy();
311 case QWebPage::Paste:
312 enabled = editor->canPaste();
316 // those two are handled by QUndoStack
321 a->setEnabled(enabled);
324 void QWebPagePrivate::updateNavigationActions()
326 updateAction(QWebPage::GoBack);
327 updateAction(QWebPage::GoForward);
328 updateAction(QWebPage::Stop);
329 updateAction(QWebPage::Reload);
332 void QWebPagePrivate::updateEditorActions()
334 updateAction(QWebPage::Cut);
335 updateAction(QWebPage::Copy);
336 updateAction(QWebPage::Paste);
339 void QWebPagePrivate::mouseMoveEvent(QMouseEvent *ev)
341 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame);
345 frame->eventHandler()->mouseMoved(PlatformMouseEvent(ev, 0));
348 void QWebPagePrivate::mousePressEvent(QMouseEvent *ev)
350 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame);
354 frame->eventHandler()->handleMousePressEvent(PlatformMouseEvent(ev, 1));
357 void QWebPagePrivate::mouseDoubleClickEvent(QMouseEvent *ev)
359 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame);
363 frame->eventHandler()->handleMousePressEvent(PlatformMouseEvent(ev, 2));
366 void QWebPagePrivate::mouseReleaseEvent(QMouseEvent *ev)
368 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame);
372 frame->eventHandler()->handleMouseReleaseEvent(PlatformMouseEvent(ev, 0));
375 void QWebPagePrivate::contextMenuEvent(QContextMenuEvent *ev)
377 page->contextMenuController()->clearContextMenu();
379 WebCore::Frame* focusedFrame = page->focusController()->focusedOrMainFrame();
380 focusedFrame->eventHandler()->sendContextMenuEvent(PlatformMouseEvent(ev, 1));
381 ContextMenu *menu = page->contextMenuController()->contextMenu();
382 // If the website defines its own handler then sendContextMenuEvent takes care of
383 // calling/showing it and the context menu pointer will be zero. This is the case
384 // on maps.google.com for example.
388 QWebPageContext oldContext = currentContext;
389 currentContext = QWebPageContext(menu->hitTestResult());
391 const QList<ContextMenuItem> *items = menu->platformDescription();
392 QMenu *qmenu = createContextMenu(menu, items);
394 qmenu->exec(ev->globalPos());
397 currentContext = oldContext;
400 void QWebPagePrivate::wheelEvent(QWheelEvent *ev)
402 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame);
406 WebCore::PlatformWheelEvent pev(ev);
407 bool accepted = frame->eventHandler()->handleWheelEvent(pev);
408 ev->setAccepted(accepted);
411 void QWebPagePrivate::keyPressEvent(QKeyEvent *ev)
413 bool handled = false;
414 WebCore::Frame *frame = page->focusController()->focusedOrMainFrame();
415 WebCore::Editor *editor = frame->editor();
416 if (editor->canEdit()) {
417 if (ev == QKeySequence::Cut) {
418 q->triggerAction(QWebPage::Cut);
420 } else if (ev == QKeySequence::Copy) {
421 q->triggerAction(QWebPage::Copy);
423 } else if (ev == QKeySequence::Paste) {
424 q->triggerAction(QWebPage::Paste);
426 } else if (ev == QKeySequence::Undo) {
427 q->triggerAction(QWebPage::Undo);
429 } else if (ev == QKeySequence::Redo) {
430 q->triggerAction(QWebPage::Redo);
432 } else if(ev == QKeySequence::MoveToNextChar) {
433 q->triggerAction(QWebPage::MoveToNextChar);
435 } else if(ev == QKeySequence::MoveToPreviousChar) {
436 q->triggerAction(QWebPage::MoveToPreviousChar);
438 } else if(ev == QKeySequence::MoveToNextWord) {
439 q->triggerAction(QWebPage::MoveToNextWord);
441 } else if(ev == QKeySequence::MoveToPreviousWord) {
442 q->triggerAction(QWebPage::MoveToPreviousWord);
444 } else if(ev == QKeySequence::MoveToNextLine) {
445 q->triggerAction(QWebPage::MoveToNextLine);
447 } else if(ev == QKeySequence::MoveToPreviousLine) {
448 q->triggerAction(QWebPage::MoveToPreviousLine);
450 // } else if(ev == QKeySequence::MoveToNextPage) {
451 // } else if(ev == QKeySequence::MoveToPreviousPage) {
452 } else if(ev == QKeySequence::MoveToStartOfLine) {
453 q->triggerAction(QWebPage::MoveToStartOfLine);
455 } else if(ev == QKeySequence::MoveToEndOfLine) {
456 q->triggerAction(QWebPage::MoveToEndOfLine);
458 } else if(ev == QKeySequence::MoveToStartOfBlock) {
459 q->triggerAction(QWebPage::MoveToStartOfBlock);
461 } else if(ev == QKeySequence::MoveToEndOfBlock) {
462 q->triggerAction(QWebPage::MoveToEndOfBlock);
464 } else if(ev == QKeySequence::MoveToStartOfDocument) {
465 q->triggerAction(QWebPage::MoveToStartOfDocument);
467 } else if(ev == QKeySequence::MoveToEndOfDocument) {
468 q->triggerAction(QWebPage::MoveToEndOfDocument);
470 } else if(ev == QKeySequence::SelectNextChar) {
471 q->triggerAction(QWebPage::SelectNextChar);
473 } else if(ev == QKeySequence::SelectPreviousChar) {
474 q->triggerAction(QWebPage::SelectPreviousChar);
476 } else if(ev == QKeySequence::SelectNextWord) {
477 q->triggerAction(QWebPage::SelectNextWord);
479 } else if(ev == QKeySequence::SelectPreviousWord) {
480 q->triggerAction(QWebPage::SelectPreviousWord);
482 } else if(ev == QKeySequence::SelectNextLine) {
483 q->triggerAction(QWebPage::SelectNextLine);
485 } else if(ev == QKeySequence::SelectPreviousLine) {
486 q->triggerAction(QWebPage::SelectPreviousLine);
488 // } else if(ev == QKeySequence::SelectNextPage) {
489 // } else if(ev == QKeySequence::SelectPreviousPage) {
490 } else if(ev == QKeySequence::SelectStartOfLine) {
491 q->triggerAction(QWebPage::SelectStartOfLine);
493 } else if(ev == QKeySequence::SelectEndOfLine) {
494 q->triggerAction(QWebPage::SelectEndOfLine);
496 } else if(ev == QKeySequence::SelectStartOfBlock) {
497 q->triggerAction(QWebPage::SelectStartOfBlock);
499 } else if(ev == QKeySequence::SelectEndOfBlock) {
500 q->triggerAction(QWebPage::SelectEndOfBlock);
502 } else if(ev == QKeySequence::SelectStartOfDocument) {
503 q->triggerAction(QWebPage::SelectStartOfDocument);
505 } else if(ev == QKeySequence::SelectEndOfDocument) {
506 q->triggerAction(QWebPage::SelectEndOfDocument);
508 } else if(ev == QKeySequence::DeleteStartOfWord) {
509 q->triggerAction(QWebPage::DeleteStartOfWord);
511 } else if(ev == QKeySequence::DeleteEndOfWord) {
512 q->triggerAction(QWebPage::DeleteEndOfWord);
514 // } else if(ev == QKeySequence::DeleteEndOfLine) {
518 handled = frame->eventHandler()->keyEvent(ev);
521 PlatformScrollbar *h, *v;
522 h = mainFrame->d->horizontalScrollBar();
523 v = mainFrame->d->verticalScrollBar();
526 defaultFont = view->font();
527 QFontMetrics fm(defaultFont);
528 int fontHeight = fm.height();
529 if (ev == QKeySequence::MoveToNextPage
530 || ev->key() == Qt::Key_Space) {
532 v->setValue(v->value() + q->viewportSize().height() - fontHeight);
533 } else if (ev == QKeySequence::MoveToPreviousPage) {
535 v->setValue(v->value() - q->viewportSize().height() + fontHeight);
536 } else if (ev->key() == Qt::Key_Up && ev->modifiers() == Qt::ControlModifier) {
539 } else if (ev->key() == Qt::Key_Down && ev->modifiers() == Qt::ControlModifier) {
541 v->setValue(INT_MAX);
546 v->setValue(v->value() - fontHeight);
550 v->setValue(v->value() + fontHeight);
554 h->setValue(h->value() - fontHeight);
558 h->setValue(h->value() + fontHeight);
560 case Qt::Key_Backspace:
561 if (ev->modifiers() == Qt::ShiftModifier)
562 q->triggerAction(QWebPage::GoForward);
564 q->triggerAction(QWebPage::GoBack);
572 ev->setAccepted(handled);
575 void QWebPagePrivate::keyReleaseEvent(QKeyEvent *ev)
577 if (ev->isAutoRepeat()) {
578 ev->setAccepted(true);
582 WebCore::Frame* frame = page->focusController()->focusedOrMainFrame();
583 bool handled = frame->eventHandler()->keyEvent(ev);
584 ev->setAccepted(handled);
587 void QWebPagePrivate::focusInEvent(QFocusEvent *ev)
589 if (ev->reason() != Qt::PopupFocusReason)
590 page->focusController()->setFocusedFrame(QWebFramePrivate::core(mainFrame));
593 void QWebPagePrivate::focusOutEvent(QFocusEvent *ev)
595 if (ev->reason() != Qt::PopupFocusReason)
596 page->focusController()->setFocusedFrame(0);
599 void QWebPagePrivate::dragEnterEvent(QDragEnterEvent *ev)
601 #ifndef QT_NO_DRAGANDDROP
602 DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(),
603 dropActionToDragOp(ev->possibleActions()));
604 Qt::DropAction action = dragOpToDropAction(page->dragController()->dragEntered(&dragData));
605 ev->setDropAction(action);
610 void QWebPagePrivate::dragLeaveEvent(QDragLeaveEvent *ev)
612 #ifndef QT_NO_DRAGANDDROP
613 DragData dragData(0, IntPoint(), QCursor::pos(), DragOperationNone);
614 page->dragController()->dragExited(&dragData);
619 void QWebPagePrivate::dragMoveEvent(QDragMoveEvent *ev)
621 #ifndef QT_NO_DRAGANDDROP
622 DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(),
623 dropActionToDragOp(ev->possibleActions()));
624 Qt::DropAction action = dragOpToDropAction(page->dragController()->dragUpdated(&dragData));
625 ev->setDropAction(action);
630 void QWebPagePrivate::dropEvent(QDropEvent *ev)
632 #ifndef QT_NO_DRAGANDDROP
633 DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(),
634 dropActionToDragOp(ev->possibleActions()));
635 Qt::DropAction action = dragOpToDropAction(page->dragController()->performDrag(&dragData));
641 \enum QWebPage::WebAction
643 \value NoWebAction No action is triggered.
644 \value OpenLink Open the current link.
645 \value OpenLinkInNewWindow Open the current link in a new window.
646 \value OpenFrameInNewWindow Replicate the current frame in a new window.
647 \value DownloadLinkToDisk Download the current link to the disk.
648 \value CopyLinkToClipboard Copy the current link to the clipboard.
649 \value OpenImageInNewWindow Open the highlighted image in a new window.
650 \value DownloadImageToDisk Download the highlighted image to the disk.
651 \value CopyImageToClipboard Copy the highlighted image to the clipboard.
652 \value GoBack Navigate back in the history of navigated links.
653 \value GoForward Navigate forward in the history of navigated links.
654 \value Stop Stop loading the current page.
655 \value Reload Reload the current page.
656 \value Cut Cut the content currently selected into the clipboard.
657 \value Copy Copy the content currently selected into the clipboard.
658 \value Paste Paste content from the clipboard.
659 \value Undo Undo the last editing action.
660 \value Redo Redo the last editing action.
661 \value MoveToNextChar Move the cursor to the next character.
662 \value MoveToPreviousChar Move the cursor to the previous character.
663 \value MoveToNextWord Move the cursor to the next word.
664 \value MoveToPreviousWord Move the cursor to the previous word.
665 \value MoveToNextLine Move the cursor to the next line.
666 \value MoveToPreviousLine Move the cursor to the previous line.
667 \value MoveToStartOfLine Move the cursor to the start of the line.
668 \value MoveToEndOfLine Move the cursor to the end of the line.
669 \value MoveToStartOfBlock Move the cursor to the start of the block.
670 \value MoveToEndOfBlock Move the cursor to the end of the block.
671 \value MoveToStartOfDocument Move the cursor to the start of the document.
672 \value MoveToEndOfDocument Move the cursor to the end of the document.
673 \value SelectNextChar Select to the next character.
674 \value SelectPreviousChar Select to the previous character.
675 \value SelectNextWord Select to the next word.
676 \value SelectPreviousWord Select to the previous word.
677 \value SelectNextLine Select to the next line.
678 \value SelectPreviousLine Select to the previous line.
679 \value SelectStartOfLine Select to the start of the line.
680 \value SelectEndOfLine Select to the end of the line.
681 \value SelectStartOfBlock Select to the start of the block.
682 \value SelectEndOfBlock Select to the end of the block.
683 \value SelectStartOfDocument Select to the start of the document.
684 \value SelectEndOfDocument Select to the end of the document.
685 \value DeleteStartOfWord Delete to the start of the word.
686 \value DeleteEndOfWord Delete to the end of the word.
687 \value SetTextDirectionDefault Set the text direction to the default direction.
688 \value SetTextDirectionLeftToRight Set the text direction to left-to-right.
689 \value SetTextDirectionRightToLeft Set the text direction to right-to-left.
690 \value ToggleBold Toggle the formatting between bold and normal weight.
691 \value ToggleItalic Toggle the formatting between italic and normal style.
692 \value ToggleUnderline Toggle underlining.
693 \value InspectElement Show the Web Inspector with the currently highlighted HTML element.
694 \omitvalue WebActionCount
701 \brief The QWebPage class provides a widget that is used to view and edit web documents.
703 QWebPage holds a main frame responsible for web content, settings, the history
704 of navigated links as well as actions. This class can be used, together with QWebFrame,
705 if you want to provide functionality like QWebView in a setup without widgets.
709 Constructs an empty QWebView with parent \a parent.
711 QWebPage::QWebPage(QObject *parent)
713 , d(new QWebPagePrivate(this))
715 setView(qobject_cast<QWidget *>(parent));
717 connect(this, SIGNAL(loadProgressChanged(int)), this, SLOT(_q_onLoadProgressChanged(int)));
723 QWebPage::~QWebPage()
725 FrameLoader *loader = d->mainFrame->d->frame->loader();
727 loader->detachFromParent();
732 Returns the main frame of the page.
734 The main frame provides access to the hierarchy of sub-frames and is also needed if you
735 want to explicitly render a web page into a given painter.
737 QWebFrame *QWebPage::mainFrame() const
739 d->createMainFrame();
744 Returns the frame currently active.
746 QWebFrame *QWebPage::currentFrame() const
748 return static_cast<WebCore::FrameLoaderClientQt *>(d->page->focusController()->focusedOrMainFrame()->loader()->client())->webFrame();
752 Returns a pointer to the view's history of navigated web pages.
755 QWebHistory *QWebPage::history() const
761 Sets the \a view that is associated with the web page.
765 void QWebPage::setView(QWidget *view)
768 setViewportSize(view ? view->size() : QSize(0, 0));
772 Returns the view widget that is associated with the web page.
776 QWidget *QWebPage::view() const
783 This function is called whenever a JavaScript program tries to print to what is the console in web browsers.
785 void QWebPage::javaScriptConsoleMessage(const QString& message, unsigned int lineNumber, const QString& sourceID)
790 This function is called whenever a JavaScript program calls the alert() function.
792 void QWebPage::javaScriptAlert(QWebFrame *frame, const QString& msg)
794 QMessageBox::information(d->view, mainFrame()->title(), msg, QMessageBox::Ok);
798 This function is called whenever a JavaScript program calls the confirm() function.
800 bool QWebPage::javaScriptConfirm(QWebFrame *frame, const QString& msg)
802 return 0 == QMessageBox::information(d->view, mainFrame()->title(), msg, QMessageBox::Yes, QMessageBox::No);
806 This function is called whenever a JavaScript program tries to prompt the user of input.
808 bool QWebPage::javaScriptPrompt(QWebFrame *frame, const QString& msg, const QString& defaultValue, QString* result)
811 #ifndef QT_NO_INPUTDIALOG
812 QString x = QInputDialog::getText(d->view, mainFrame()->title(), msg, QLineEdit::Normal, defaultValue, &ok);
821 This function is called whenever WebKit wants to create a new window, for example as a result of
822 a JavaScript request to open a document in a new window.
824 QWebPage *QWebPage::createWindow()
826 QWebView *webView = qobject_cast<QWebView *>(d->view);
828 QWebView *newView = webView->createWindow();
830 return newView->page();
836 This function is called whenever WebKit wants to create a new window that should act as a modal dialog.
838 QWebPage *QWebPage::createModalDialog()
844 This function is called whenever WebKit encounters a HTML object element with type "application/x-qt-plugin".
845 The \a classid, \a url, \a paramNames and \a paramValues correspond to the HTML object element attributes and
846 child elements to configure the embeddable object.
848 QObject *QWebPage::createPlugin(const QString &classid, const QUrl &url, const QStringList ¶mNames, const QStringList ¶mValues)
853 Q_UNUSED(paramValues)
857 static WebCore::FrameLoadRequest frameLoadRequest(const QUrl &url, WebCore::Frame *frame)
859 WebCore::ResourceRequest rr(url, frame->loader()->outgoingReferrer());
860 return WebCore::FrameLoadRequest(rr);
863 static void openNewWindow(const QUrl& url, WebCore::Frame* frame)
865 if (Page* oldPage = frame->page()) {
866 WindowFeatures features;
867 if (Page* newPage = oldPage->chrome()->createWindow(frame,
868 frameLoadRequest(url, frame), features))
869 newPage->chrome()->show();
874 This function can be called to trigger the specified \a action.
875 It is also called by QtWebKit if the user triggers the action, for example
876 through a context menu item.
878 If \a action is a checkable action then \a checked specified whether the action
881 void QWebPage::triggerAction(WebAction action, bool checked)
883 WebCore::Frame *frame = d->page->focusController()->focusedOrMainFrame();
884 WebCore::Editor *editor = frame->editor();
885 const char *command = 0;
889 if (QWebFrame *targetFrame = d->currentContext.targetFrame()) {
890 WTF::RefPtr<WebCore::Frame> wcFrame = targetFrame->d->frame;
891 targetFrame->d->frame->loader()->load(frameLoadRequest(d->currentContext.linkUrl(), wcFrame.get()),
892 /*lockHistory*/ false,
893 /*userGesture*/ true,
895 /*HTMLFormElement*/ 0,
897 WTF::HashMap<String, String>());
902 case OpenLinkInNewWindow:
903 openNewWindow(d->currentContext.linkUrl(), frame);
905 case OpenFrameInNewWindow:
907 case CopyLinkToClipboard:
908 editor->copyURL(d->currentContext.linkUrl(), d->currentContext.text());
910 case OpenImageInNewWindow:
911 openNewWindow(d->currentContext.imageUrl(), frame);
913 case DownloadImageToDisk:
914 case DownloadLinkToDisk:
915 frame->loader()->client()->startDownload(WebCore::ResourceRequest(d->currentContext.linkUrl(), frame->loader()->outgoingReferrer()));
917 case CopyImageToClipboard:
923 d->page->goForward();
926 mainFrame()->d->frame->loader()->stopForUserCancel();
929 mainFrame()->d->frame->loader()->reload();
949 command = "MoveForward";
951 case MoveToPreviousChar:
952 command = "MoveBackward";
955 command = "MoveWordForward";
957 case MoveToPreviousWord:
958 command = "MoveWordBackward";
961 command = "MoveDown";
963 case MoveToPreviousLine:
966 case MoveToStartOfLine:
967 command = "MoveToBeginningOfLine";
969 case MoveToEndOfLine:
970 command = "MoveToEndOfLine";
972 case MoveToStartOfBlock:
973 command = "MoveToBeginningOfParagraph";
975 case MoveToEndOfBlock:
976 command = "MoveToEndOfParagraph";
978 case MoveToStartOfDocument:
979 command = "MoveToBeginningOfDocument";
981 case MoveToEndOfDocument:
982 command = "MoveToEndOfDocument";
985 command = "MoveForwardAndModifySelection";
987 case SelectPreviousChar:
988 command = "MoveBackwardAndModifySelection";
991 command = "MoveWordForwardAndModifySelection";
993 case SelectPreviousWord:
994 command = "MoveWordBackwardAndModifySelection";
997 command = "MoveDownAndModifySelection";
999 case SelectPreviousLine:
1000 command = "MoveUpAndModifySelection";
1002 case SelectStartOfLine:
1003 command = "MoveToBeginningOfLineAndModifySelection";
1005 case SelectEndOfLine:
1006 command = "MoveToEndOfLineAndModifySelection";
1008 case SelectStartOfBlock:
1009 command = "MoveToBeginningOfParagraphAndModifySelection";
1011 case SelectEndOfBlock:
1012 command = "MoveToEndOfParagraphAndModifySelection";
1014 case SelectStartOfDocument:
1015 command = "MoveToBeginningOfDocumentAndModifySelection";
1017 case SelectEndOfDocument:
1018 command = "MoveToEndOfDocumentAndModifySelection";
1020 case DeleteStartOfWord:
1021 command = "DeleteWordBackward";
1023 case DeleteEndOfWord:
1024 command = "DeleteWordForward";
1027 case SetTextDirectionDefault:
1028 editor->setBaseWritingDirection("inherit");
1030 case SetTextDirectionLeftToRight:
1031 editor->setBaseWritingDirection("ltr");
1033 case SetTextDirectionRightToLeft:
1034 editor->setBaseWritingDirection("rtl");
1038 command = "ToggleBold";
1041 command = "ToggleItalic";
1043 case ToggleUnderline:
1044 editor->toggleUnderline();
1046 case InspectElement:
1047 d->page->inspectorController()->inspect(d->currentContext.d->innerNonSharedNode.get());
1054 editor->command(command).execute();
1057 QSize QWebPage::viewportSize() const
1059 if (d->mainFrame && d->mainFrame->d->frame->view())
1060 return d->mainFrame->d->frame->view()->frameGeometry().size();
1062 return d->viewportSize;
1066 \property QWebPage::viewportSize
1068 Specifies the size of the viewport. The size affects for example the visibility of scrollbars
1069 if the document is larger than the viewport.
1071 void QWebPage::setViewportSize(const QSize &size) const
1073 d->viewportSize = size;
1075 QWebFrame *frame = mainFrame();
1076 if (frame->d->frame && frame->d->frame->view()) {
1077 WebCore::FrameView* view = frame->d->frame->view();
1078 view->setFrameGeometry(QRect(QPoint(0, 0), size));
1079 frame->d->frame->forceLayout();
1080 view->adjustViewSize();
1085 #if QT_VERSION < 0x040400
1086 QWebPage::NavigationRequestResponse QWebPage::navigationRequested(QWebFrame *frame, const QWebNetworkRequest &request, QWebPage::NavigationType type)
1088 QWebPage::NavigationRequestResponse QWebPage::navigationRequested(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type)
1092 return AcceptNavigationRequest;
1096 \property QWebPage::selectedText
1098 Returns the text currently selected.
1100 QString QWebPage::selectedText() const
1102 return d->page->focusController()->focusedOrMainFrame()->selectedText();
1106 Returns a QAction for the specified WebAction \a action.
1108 The action is owned by the QWebPage but you can customize the look by
1109 changing its properties.
1111 QWebPage also takes care of implementing the action, so that upon
1112 triggering the corresponding action is performed on the page.
1114 QAction *QWebPage::action(WebAction action) const
1116 if (action == QWebPage::NoWebAction) return 0;
1117 if (d->actions[action])
1118 return d->actions[action];
1122 QStyle *style = view() ? view()->style() : qApp->style();
1123 bool checkable = false;
1127 text = contextMenuItemTagOpenLink();
1129 case OpenLinkInNewWindow:
1130 text = contextMenuItemTagOpenLinkInNewWindow();
1132 case OpenFrameInNewWindow:
1133 text = contextMenuItemTagOpenFrameInNewWindow();
1136 case DownloadLinkToDisk:
1137 text = contextMenuItemTagDownloadLinkToDisk();
1139 case CopyLinkToClipboard:
1140 text = contextMenuItemTagCopyLinkToClipboard();
1143 case OpenImageInNewWindow:
1144 text = contextMenuItemTagOpenImageInNewWindow();
1146 case DownloadImageToDisk:
1147 text = contextMenuItemTagDownloadImageToDisk();
1149 case CopyImageToClipboard:
1150 text = contextMenuItemTagCopyImageToClipboard();
1154 text = contextMenuItemTagGoBack();
1155 #if QT_VERSION >= 0x040400
1156 icon = style->standardIcon(QStyle::SP_ArrowBack);
1160 text = contextMenuItemTagGoForward();
1161 #if QT_VERSION >= 0x040400
1162 icon = style->standardIcon(QStyle::SP_ArrowForward);
1166 text = contextMenuItemTagStop();
1167 #if QT_VERSION >= 0x040400
1168 icon = style->standardIcon(QStyle::SP_BrowserStop);
1172 text = contextMenuItemTagReload();
1173 #if QT_VERSION >= 0x040400
1174 icon = style->standardIcon(QStyle::SP_BrowserReload);
1179 text = contextMenuItemTagCut();
1182 text = contextMenuItemTagCopy();
1185 text = contextMenuItemTagPaste();
1189 QAction *a = undoStack()->createUndoAction(d->q);
1190 d->actions[action] = a;
1194 QAction *a = undoStack()->createRedoAction(d->q);
1195 d->actions[action] = a;
1198 case MoveToNextChar:
1199 case MoveToPreviousChar:
1200 case MoveToNextWord:
1201 case MoveToPreviousWord:
1202 case MoveToNextLine:
1203 case MoveToPreviousLine:
1204 case MoveToStartOfLine:
1205 case MoveToEndOfLine:
1206 case MoveToStartOfBlock:
1207 case MoveToEndOfBlock:
1208 case MoveToStartOfDocument:
1209 case MoveToEndOfDocument:
1210 case SelectNextChar:
1211 case SelectPreviousChar:
1212 case SelectNextWord:
1213 case SelectPreviousWord:
1214 case SelectNextLine:
1215 case SelectPreviousLine:
1216 case SelectStartOfLine:
1217 case SelectEndOfLine:
1218 case SelectStartOfBlock:
1219 case SelectEndOfBlock:
1220 case SelectStartOfDocument:
1221 case SelectEndOfDocument:
1222 case DeleteStartOfWord:
1223 case DeleteEndOfWord:
1226 case SetTextDirectionDefault:
1227 text = contextMenuItemTagDefaultDirection();
1229 case SetTextDirectionLeftToRight:
1230 text = contextMenuItemTagLeftToRight();
1233 case SetTextDirectionRightToLeft:
1234 text = contextMenuItemTagRightToLeft();
1239 text = contextMenuItemTagBold();
1243 text = contextMenuItemTagItalic();
1246 case ToggleUnderline:
1247 text = contextMenuItemTagUnderline();
1251 case InspectElement:
1252 text = contextMenuItemTagInspectElement();
1262 QAction *a = new QAction(d->q);
1265 a->setCheckable(checkable);
1268 connect(a, SIGNAL(triggered(bool)),
1269 this, SLOT(_q_webActionTriggered(bool)));
1271 d->actions[action] = a;
1272 d->updateAction(action);
1277 \property QWebPage::modified
1279 Specifies if the page contains unsubmitted form data.
1281 bool QWebPage::isModified() const
1288 Returns a pointer to the undo stack used for editable content.
1290 QUndoStack *QWebPage::undoStack() const
1293 d->undoStack = new QUndoStack(const_cast<QWebPage *>(this));
1295 return d->undoStack;
1300 bool QWebPage::event(QEvent *ev)
1302 switch (ev->type()) {
1303 case QEvent::MouseMove:
1304 d->mouseMoveEvent(static_cast<QMouseEvent*>(ev));
1306 case QEvent::MouseButtonPress:
1307 d->mousePressEvent(static_cast<QMouseEvent*>(ev));
1309 case QEvent::MouseButtonDblClick:
1310 d->mouseDoubleClickEvent(static_cast<QMouseEvent*>(ev));
1312 case QEvent::MouseButtonRelease:
1313 d->mouseReleaseEvent(static_cast<QMouseEvent*>(ev));
1315 case QEvent::ContextMenu:
1316 d->contextMenuEvent(static_cast<QContextMenuEvent*>(ev));
1319 d->wheelEvent(static_cast<QWheelEvent*>(ev));
1321 case QEvent::KeyPress:
1322 d->keyPressEvent(static_cast<QKeyEvent*>(ev));
1324 case QEvent::KeyRelease:
1325 d->keyReleaseEvent(static_cast<QKeyEvent*>(ev));
1327 case QEvent::FocusIn:
1328 d->focusInEvent(static_cast<QFocusEvent*>(ev));
1330 case QEvent::FocusOut:
1331 d->focusOutEvent(static_cast<QFocusEvent*>(ev));
1333 #ifndef QT_NO_DRAGANDDROP
1334 case QEvent::DragEnter:
1335 d->dragEnterEvent(static_cast<QDragEnterEvent*>(ev));
1337 case QEvent::DragLeave:
1338 d->dragLeaveEvent(static_cast<QDragLeaveEvent*>(ev));
1340 case QEvent::DragMove:
1341 d->dragMoveEvent(static_cast<QDragMoveEvent*>(ev));
1344 d->dropEvent(static_cast<QDropEvent*>(ev));
1348 return QObject::event(ev);
1355 Similar to QWidget::focusNextPrevChild it focuses the next focusable web element
1356 if \a next is true. Otherwise the previous element is focused.
1358 bool QWebPage::focusNextPrevChild(bool next)
1360 QKeyEvent ev(QEvent::KeyPress, Qt::Key_Tab, Qt::KeyboardModifiers(next ? Qt::NoModifier : Qt::ShiftModifier));
1361 d->keyPressEvent(&ev);
1362 bool hasFocusedNode = false;
1363 Frame *frame = d->page->focusController()->focusedFrame();
1365 Document *document = frame->document();
1366 hasFocusedNode = document && document->focusedNode();
1368 //qDebug() << "focusNextPrevChild(" << next << ") =" << ev.isAccepted() << "focusedNode?" << hasFocusedNode;
1369 return hasFocusedNode;
1373 Returns a pointe to the page's settings object.
1375 QWebSettings *QWebPage::settings()
1381 This function is called when the web content requests a file name, for example
1382 as a result of the user clicking on a "file upload" button in a HTML form.
1384 QString QWebPage::chooseFile(QWebFrame *parentFrame, const QString& oldFile)
1386 #ifndef QT_NO_FILEDIALOG
1387 return QFileDialog::getOpenFileName(d->view, QString::null, oldFile);
1389 return QString::null;
1393 #if QT_VERSION < 0x040400
1395 void QWebPage::setNetworkInterface(QWebNetworkInterface *interface)
1397 d->networkInterface = interface;
1400 QWebNetworkInterface *QWebPage::networkInterface() const
1402 if (d->networkInterface)
1403 return d->networkInterface;
1405 return QWebNetworkInterface::defaultInterface();
1408 #ifndef QT_NO_NETWORKPROXY
1409 void QWebPage::setNetworkProxy(const QNetworkProxy& proxy)
1411 d->networkProxy = proxy;
1414 QNetworkProxy QWebPage::networkProxy() const
1416 return d->networkProxy;
1423 Sets the QNetworkAccessManager \a manager that is responsible for serving network
1424 requests for this QWebPage.
1426 \sa networkAccessManager
1428 void QWebPage::setNetworkAccessManager(QNetworkAccessManager *manager)
1430 if (manager == d->networkManager)
1432 delete d->networkManager;
1433 d->networkManager = manager;
1437 Returns the QNetworkAccessManager \a manager that is responsible for serving network
1438 requests for this QWebPage.
1440 \sa setNetworkAccessManager
1442 QNetworkAccessManager *QWebPage::networkAccessManager() const
1444 if (!d->networkManager) {
1445 QWebPage *that = const_cast<QWebPage *>(this);
1446 that->d->networkManager = new QNetworkAccessManager(that);
1448 return d->networkManager;
1453 void QWebPage::setPluginFactory(QWebPluginFactory *factory)
1455 d->pluginFactory = factory;
1458 QWebPluginFactory *QWebPage::pluginFactory() const
1460 return d->pluginFactory;
1464 This function is called when a user agent for HTTP requests is needed. You can re-implement this
1465 function to dynamically return different user agent's for different urls, based on the \a url parameter.
1467 QString QWebPage::userAgentFor(const QUrl& url) const
1470 return QLatin1String("Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en) AppleWebKit/523.15 (KHTML, like Gecko) Safari/419.3 Qt");
1474 void QWebPagePrivate::_q_onLoadProgressChanged(int) {
1475 m_totalBytes = page->progress()->totalPageAndResourceBytesToLoad();
1476 m_bytesReceived = page->progress()->totalBytesReceived();
1481 Returns the total number of bytes that were received from the network to render the current page,
1482 including extra content such as embedded images.
1484 quint64 QWebPage::totalBytes() const {
1485 return d->m_bytesReceived;
1490 Returns the number of bytes that were received from the network to render the current page.
1492 quint64 QWebPage::bytesReceived() const {
1493 return d->m_totalBytes;
1496 QWebPageContext::QWebPageContext(const WebCore::HitTestResult &hitTest)
1497 : d(new QWebPageContextPrivate)
1499 d->pos = hitTest.point();
1500 d->text = hitTest.textContent();
1501 d->linkUrl = hitTest.absoluteLinkURL().string();
1502 d->imageUrl = hitTest.absoluteImageURL().string();
1503 d->innerNonSharedNode = hitTest.innerNonSharedNode();
1504 WebCore::Image *img = hitTest.image();
1506 QPixmap *pix = img->getPixmap();
1510 WebCore::Frame *frame = hitTest.targetFrame();
1512 d->targetFrame = QWebFramePrivate::kit(frame);
1515 QWebPageContext::QWebPageContext()
1520 QWebPageContext::QWebPageContext(const QWebPageContext &other)
1524 d = new QWebPageContextPrivate(*other.d);
1527 QWebPageContext &QWebPageContext::operator=(const QWebPageContext &other)
1529 if (this != &other) {
1532 d = new QWebPageContextPrivate;
1542 QWebPageContext::~QWebPageContext()
1547 QPoint QWebPageContext::pos() const
1554 QString QWebPageContext::text() const
1561 QUrl QWebPageContext::linkUrl() const
1568 QUrl QWebPageContext::imageUrl() const
1575 QPixmap QWebPageContext::image() const
1582 QWebFrame *QWebPageContext::targetFrame() const
1586 return d->targetFrame;
1590 \fn void QWebPage::loadProgressChanged(int progress)
1592 This signal is emitted when the global progress status changes.
1593 The current value is provided by \a progress in percent.
1594 It accumulates changes from all the child frames.
1598 \fn void QWebPage::hoveringOverLink(const QString &link, const QString &title, const QString &textContent)
1600 This signal is emitted when the mouse is hovering over a link.
1601 The first parameter is the \a link url, the second is the link \a title
1602 if any, and third \a textContent is the text content. Method is emitter with both
1603 empty parameters when the mouse isn't hovering over any link element.
1607 \fn void QWebPage::statusBarTextChanged(const QString& text)
1609 This signal is emitted when the statusbar \a text is changed by the page.
1613 \fn void QWebPage::frameCreated(QWebFrame *frame)
1615 This signal is emitted whenever the page creates a new \a frame.
1619 \fn void QWebPage::selectionChanged()
1621 This signal is emitted whenever the selection changes.
1625 \fn void QWebPage::geometryChangeRequest(const QRect& geom)
1627 This signal is emitted whenever the document wants to change the position and size of the
1628 page to \a geom. This can happen for example through JavaScript.
1632 \fn void QWebPage::handleUnsupportedContent(QNetworkReply *reply)
1634 This signals is emitted when webkit cannot handle a link the user navigated to.
1636 At signal emissions time the meta data of the QNetworkReply is available.
1640 \fn void QWebPage::download(const QNetworkRequest &request)
1642 This signals is emitted when the user decides to download a link.
1645 #include "moc_qwebpage.cpp"