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);
180 emit q->frameCreated(mainFrame);
184 static QWebPage::WebAction webActionForContextMenuAction(WebCore::ContextMenuAction action)
187 case WebCore::ContextMenuItemTagOpenLink: return QWebPage::OpenLink;
188 case WebCore::ContextMenuItemTagOpenLinkInNewWindow: return QWebPage::OpenLinkInNewWindow;
189 case WebCore::ContextMenuItemTagDownloadLinkToDisk: return QWebPage::DownloadLinkToDisk;
190 case WebCore::ContextMenuItemTagCopyLinkToClipboard: return QWebPage::CopyLinkToClipboard;
191 case WebCore::ContextMenuItemTagOpenImageInNewWindow: return QWebPage::OpenImageInNewWindow;
192 case WebCore::ContextMenuItemTagDownloadImageToDisk: return QWebPage::DownloadImageToDisk;
193 case WebCore::ContextMenuItemTagCopyImageToClipboard: return QWebPage::CopyImageToClipboard;
194 case WebCore::ContextMenuItemTagOpenFrameInNewWindow: return QWebPage::OpenFrameInNewWindow;
195 case WebCore::ContextMenuItemTagCopy: return QWebPage::Copy;
196 case WebCore::ContextMenuItemTagGoBack: return QWebPage::GoBack;
197 case WebCore::ContextMenuItemTagGoForward: return QWebPage::GoForward;
198 case WebCore::ContextMenuItemTagStop: return QWebPage::Stop;
199 case WebCore::ContextMenuItemTagReload: return QWebPage::Reload;
200 case WebCore::ContextMenuItemTagCut: return QWebPage::Cut;
201 case WebCore::ContextMenuItemTagPaste: return QWebPage::Paste;
202 case WebCore::ContextMenuItemTagDefaultDirection: return QWebPage::SetTextDirectionDefault;
203 case WebCore::ContextMenuItemTagLeftToRight: return QWebPage::SetTextDirectionLeftToRight;
204 case WebCore::ContextMenuItemTagRightToLeft: return QWebPage::SetTextDirectionRightToLeft;
205 case WebCore::ContextMenuItemTagBold: return QWebPage::ToggleBold;
206 case WebCore::ContextMenuItemTagItalic: return QWebPage::ToggleItalic;
207 case WebCore::ContextMenuItemTagUnderline: return QWebPage::ToggleUnderline;
208 case WebCore::ContextMenuItemTagInspectElement: return QWebPage::InspectElement;
211 return QWebPage::NoWebAction;
214 QMenu *QWebPagePrivate::createContextMenu(const WebCore::ContextMenu *webcoreMenu, const QList<WebCore::ContextMenuItem> *items)
216 QMenu *menu = new QMenu;
217 for (int i = 0; i < items->count(); ++i) {
218 const ContextMenuItem &item = items->at(i);
219 switch (item.type()) {
220 case WebCore::CheckableActionType: /* fall through */
221 case WebCore::ActionType: {
222 QWebPage::WebAction action = webActionForContextMenuAction(item.action());
223 QAction *a = q->action(action);
225 ContextMenuItem it(item);
226 webcoreMenu->checkOrEnableIfNeeded(it);
227 PlatformMenuItemDescription desc = it.releasePlatformDescription();
228 a->setEnabled(desc.enabled);
229 a->setChecked(desc.checked);
230 a->setCheckable(item.type() == WebCore::CheckableActionType);
236 case WebCore::SeparatorType:
237 menu->addSeparator();
239 case WebCore::SubmenuType: {
240 QMenu *subMenu = createContextMenu(webcoreMenu, item.platformSubMenu());
241 if (!subMenu->actions().isEmpty()) {
242 subMenu->setTitle(item.title());
243 menu->addAction(subMenu->menuAction());
254 QWebFrame *QWebPagePrivate::frameAt(const QPoint &pos) const
256 QWebFrame *frame = mainFrame;
259 QList<QWebFrame*> children = frame->childFrames();
260 for (int i = 0; i < children.size(); ++i) {
261 if (children.at(i)->geometry().contains(pos)) {
262 frame = children.at(i);
266 if (frame->geometry().contains(pos))
271 void QWebPagePrivate::_q_webActionTriggered(bool checked)
273 QAction *a = qobject_cast<QAction *>(q->sender());
276 QWebPage::WebAction action = static_cast<QWebPage::WebAction>(a->data().toInt());
277 q->triggerAction(action, checked);
280 void QWebPagePrivate::updateAction(QWebPage::WebAction action)
282 QAction *a = actions[action];
283 if (!a || !mainFrame)
286 WebCore::FrameLoader *loader = mainFrame->d->frame->loader();
287 WebCore::Editor *editor = page->focusController()->focusedOrMainFrame()->editor();
289 bool enabled = a->isEnabled();
292 case QWebPage::GoBack:
293 enabled = loader->canGoBackOrForward(-1);
295 case QWebPage::GoForward:
296 enabled = loader->canGoBackOrForward(1);
299 enabled = loader->isLoading();
301 case QWebPage::Reload:
302 enabled = !loader->isLoading();
305 enabled = editor->canCut();
308 enabled = editor->canCopy();
310 case QWebPage::Paste:
311 enabled = editor->canPaste();
315 // those two are handled by QUndoStack
320 a->setEnabled(enabled);
323 void QWebPagePrivate::updateNavigationActions()
325 updateAction(QWebPage::GoBack);
326 updateAction(QWebPage::GoForward);
327 updateAction(QWebPage::Stop);
328 updateAction(QWebPage::Reload);
331 void QWebPagePrivate::updateEditorActions()
333 updateAction(QWebPage::Cut);
334 updateAction(QWebPage::Copy);
335 updateAction(QWebPage::Paste);
338 void QWebPagePrivate::mouseMoveEvent(QMouseEvent *ev)
340 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame);
344 frame->eventHandler()->mouseMoved(PlatformMouseEvent(ev, 0));
347 void QWebPagePrivate::mousePressEvent(QMouseEvent *ev)
349 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame);
353 frame->eventHandler()->handleMousePressEvent(PlatformMouseEvent(ev, 1));
356 void QWebPagePrivate::mouseDoubleClickEvent(QMouseEvent *ev)
358 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame);
362 frame->eventHandler()->handleMousePressEvent(PlatformMouseEvent(ev, 2));
365 void QWebPagePrivate::mouseReleaseEvent(QMouseEvent *ev)
367 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame);
371 frame->eventHandler()->handleMouseReleaseEvent(PlatformMouseEvent(ev, 0));
374 void QWebPagePrivate::contextMenuEvent(QContextMenuEvent *ev)
376 page->contextMenuController()->clearContextMenu();
378 WebCore::Frame* focusedFrame = page->focusController()->focusedOrMainFrame();
379 focusedFrame->eventHandler()->sendContextMenuEvent(PlatformMouseEvent(ev, 1));
380 ContextMenu *menu = page->contextMenuController()->contextMenu();
381 // If the website defines its own handler then sendContextMenuEvent takes care of
382 // calling/showing it and the context menu pointer will be zero. This is the case
383 // on maps.google.com for example.
387 QWebPageContext oldContext = currentContext;
388 currentContext = QWebPageContext(menu->hitTestResult());
390 const QList<ContextMenuItem> *items = menu->platformDescription();
391 QMenu *qmenu = createContextMenu(menu, items);
393 qmenu->exec(ev->globalPos());
396 currentContext = oldContext;
399 void QWebPagePrivate::wheelEvent(QWheelEvent *ev)
401 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame);
405 WebCore::PlatformWheelEvent pev(ev);
406 bool accepted = frame->eventHandler()->handleWheelEvent(pev);
407 ev->setAccepted(accepted);
410 void QWebPagePrivate::keyPressEvent(QKeyEvent *ev)
412 bool handled = false;
413 WebCore::Frame *frame = page->focusController()->focusedOrMainFrame();
414 WebCore::Editor *editor = frame->editor();
415 if (editor->canEdit()) {
416 if (ev == QKeySequence::Cut) {
417 q->triggerAction(QWebPage::Cut);
419 } else if (ev == QKeySequence::Copy) {
420 q->triggerAction(QWebPage::Copy);
422 } else if (ev == QKeySequence::Paste) {
423 q->triggerAction(QWebPage::Paste);
425 } else if (ev == QKeySequence::Undo) {
426 q->triggerAction(QWebPage::Undo);
428 } else if (ev == QKeySequence::Redo) {
429 q->triggerAction(QWebPage::Redo);
431 } else if(ev == QKeySequence::MoveToNextChar) {
432 q->triggerAction(QWebPage::MoveToNextChar);
434 } else if(ev == QKeySequence::MoveToPreviousChar) {
435 q->triggerAction(QWebPage::MoveToPreviousChar);
437 } else if(ev == QKeySequence::MoveToNextWord) {
438 q->triggerAction(QWebPage::MoveToNextWord);
440 } else if(ev == QKeySequence::MoveToPreviousWord) {
441 q->triggerAction(QWebPage::MoveToPreviousWord);
443 } else if(ev == QKeySequence::MoveToNextLine) {
444 q->triggerAction(QWebPage::MoveToNextLine);
446 } else if(ev == QKeySequence::MoveToPreviousLine) {
447 q->triggerAction(QWebPage::MoveToPreviousLine);
449 // } else if(ev == QKeySequence::MoveToNextPage) {
450 // } else if(ev == QKeySequence::MoveToPreviousPage) {
451 } else if(ev == QKeySequence::MoveToStartOfLine) {
452 q->triggerAction(QWebPage::MoveToStartOfLine);
454 } else if(ev == QKeySequence::MoveToEndOfLine) {
455 q->triggerAction(QWebPage::MoveToEndOfLine);
457 } else if(ev == QKeySequence::MoveToStartOfBlock) {
458 q->triggerAction(QWebPage::MoveToStartOfBlock);
460 } else if(ev == QKeySequence::MoveToEndOfBlock) {
461 q->triggerAction(QWebPage::MoveToEndOfBlock);
463 } else if(ev == QKeySequence::MoveToStartOfDocument) {
464 q->triggerAction(QWebPage::MoveToStartOfDocument);
466 } else if(ev == QKeySequence::MoveToEndOfDocument) {
467 q->triggerAction(QWebPage::MoveToEndOfDocument);
469 } else if(ev == QKeySequence::SelectNextChar) {
470 q->triggerAction(QWebPage::SelectNextChar);
472 } else if(ev == QKeySequence::SelectPreviousChar) {
473 q->triggerAction(QWebPage::SelectPreviousChar);
475 } else if(ev == QKeySequence::SelectNextWord) {
476 q->triggerAction(QWebPage::SelectNextWord);
478 } else if(ev == QKeySequence::SelectPreviousWord) {
479 q->triggerAction(QWebPage::SelectPreviousWord);
481 } else if(ev == QKeySequence::SelectNextLine) {
482 q->triggerAction(QWebPage::SelectNextLine);
484 } else if(ev == QKeySequence::SelectPreviousLine) {
485 q->triggerAction(QWebPage::SelectPreviousLine);
487 // } else if(ev == QKeySequence::SelectNextPage) {
488 // } else if(ev == QKeySequence::SelectPreviousPage) {
489 } else if(ev == QKeySequence::SelectStartOfLine) {
490 q->triggerAction(QWebPage::SelectStartOfLine);
492 } else if(ev == QKeySequence::SelectEndOfLine) {
493 q->triggerAction(QWebPage::SelectEndOfLine);
495 } else if(ev == QKeySequence::SelectStartOfBlock) {
496 q->triggerAction(QWebPage::SelectStartOfBlock);
498 } else if(ev == QKeySequence::SelectEndOfBlock) {
499 q->triggerAction(QWebPage::SelectEndOfBlock);
501 } else if(ev == QKeySequence::SelectStartOfDocument) {
502 q->triggerAction(QWebPage::SelectStartOfDocument);
504 } else if(ev == QKeySequence::SelectEndOfDocument) {
505 q->triggerAction(QWebPage::SelectEndOfDocument);
507 } else if(ev == QKeySequence::DeleteStartOfWord) {
508 q->triggerAction(QWebPage::DeleteStartOfWord);
510 } else if(ev == QKeySequence::DeleteEndOfWord) {
511 q->triggerAction(QWebPage::DeleteEndOfWord);
513 // } else if(ev == QKeySequence::DeleteEndOfLine) {
517 handled = frame->eventHandler()->keyEvent(ev);
520 PlatformScrollbar *h, *v;
521 h = mainFrame->d->horizontalScrollBar();
522 v = mainFrame->d->verticalScrollBar();
525 defaultFont = view->font();
526 QFontMetrics fm(defaultFont);
527 int fontHeight = fm.height();
528 if (ev == QKeySequence::MoveToNextPage
529 || ev->key() == Qt::Key_Space) {
531 v->setValue(v->value() + q->viewportSize().height() - fontHeight);
532 } else if (ev == QKeySequence::MoveToPreviousPage) {
534 v->setValue(v->value() - q->viewportSize().height() + fontHeight);
535 } else if (ev->key() == Qt::Key_Up && ev->modifiers() == Qt::ControlModifier) {
538 } else if (ev->key() == Qt::Key_Down && ev->modifiers() == Qt::ControlModifier) {
540 v->setValue(INT_MAX);
545 v->setValue(v->value() - fontHeight);
549 v->setValue(v->value() + fontHeight);
553 h->setValue(h->value() - fontHeight);
557 h->setValue(h->value() + fontHeight);
559 case Qt::Key_Backspace:
560 if (ev->modifiers() == Qt::ShiftModifier)
561 q->triggerAction(QWebPage::GoForward);
563 q->triggerAction(QWebPage::GoBack);
571 ev->setAccepted(handled);
574 void QWebPagePrivate::keyReleaseEvent(QKeyEvent *ev)
576 if (ev->isAutoRepeat()) {
577 ev->setAccepted(true);
581 WebCore::Frame* frame = page->focusController()->focusedOrMainFrame();
582 bool handled = frame->eventHandler()->keyEvent(ev);
583 ev->setAccepted(handled);
586 void QWebPagePrivate::focusInEvent(QFocusEvent *ev)
588 if (ev->reason() != Qt::PopupFocusReason)
589 page->focusController()->setFocusedFrame(QWebFramePrivate::core(mainFrame));
592 void QWebPagePrivate::focusOutEvent(QFocusEvent *ev)
594 if (ev->reason() != Qt::PopupFocusReason)
595 page->focusController()->setFocusedFrame(0);
598 void QWebPagePrivate::dragEnterEvent(QDragEnterEvent *ev)
600 #ifndef QT_NO_DRAGANDDROP
601 DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(),
602 dropActionToDragOp(ev->possibleActions()));
603 Qt::DropAction action = dragOpToDropAction(page->dragController()->dragEntered(&dragData));
604 ev->setDropAction(action);
609 void QWebPagePrivate::dragLeaveEvent(QDragLeaveEvent *ev)
611 #ifndef QT_NO_DRAGANDDROP
612 DragData dragData(0, IntPoint(), QCursor::pos(), DragOperationNone);
613 page->dragController()->dragExited(&dragData);
618 void QWebPagePrivate::dragMoveEvent(QDragMoveEvent *ev)
620 #ifndef QT_NO_DRAGANDDROP
621 DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(),
622 dropActionToDragOp(ev->possibleActions()));
623 Qt::DropAction action = dragOpToDropAction(page->dragController()->dragUpdated(&dragData));
624 ev->setDropAction(action);
629 void QWebPagePrivate::dropEvent(QDropEvent *ev)
631 #ifndef QT_NO_DRAGANDDROP
632 DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(),
633 dropActionToDragOp(ev->possibleActions()));
634 Qt::DropAction action = dragOpToDropAction(page->dragController()->performDrag(&dragData));
640 \enum QWebPage::WebAction
642 \value NoWebAction No action is triggered.
643 \value OpenLink Open the current link.
644 \value OpenLinkInNewWindow Open the current link in a new window.
645 \value OpenFrameInNewWindow Replicate the current frame in a new window.
646 \value DownloadLinkToDisk Download the current link to the disk.
647 \value CopyLinkToClipboard Copy the current link to the clipboard.
648 \value OpenImageInNewWindow Open the highlighted image in a new window.
649 \value DownloadImageToDisk Download the highlighted image to the disk.
650 \value CopyImageToClipboard Copy the highlighted image to the clipboard.
651 \value GoBack Navigate back in the history of navigated links.
652 \value GoForward Navigate forward in the history of navigated links.
653 \value Stop Stop loading the current page.
654 \value Reload Reload the current page.
655 \value Cut Cut the content currently selected into the clipboard.
656 \value Copy Copy the content currently selected into the clipboard.
657 \value Paste Paste content from the clipboard.
658 \value Undo Undo the last editing action.
659 \value Redo Redo the last editing action.
660 \value MoveToNextChar Move the cursor to the next character.
661 \value MoveToPreviousChar Move the cursor to the previous character.
662 \value MoveToNextWord Move the cursor to the next word.
663 \value MoveToPreviousWord Move the cursor to the previous word.
664 \value MoveToNextLine Move the cursor to the next line.
665 \value MoveToPreviousLine Move the cursor to the previous line.
666 \value MoveToStartOfLine Move the cursor to the start of the line.
667 \value MoveToEndOfLine Move the cursor to the end of the line.
668 \value MoveToStartOfBlock Move the cursor to the start of the block.
669 \value MoveToEndOfBlock Move the cursor to the end of the block.
670 \value MoveToStartOfDocument Move the cursor to the start of the document.
671 \value MoveToEndOfDocument Move the cursor to the end of the document.
672 \value SelectNextChar Select to the next character.
673 \value SelectPreviousChar Select to the previous character.
674 \value SelectNextWord Select to the next word.
675 \value SelectPreviousWord Select to the previous word.
676 \value SelectNextLine Select to the next line.
677 \value SelectPreviousLine Select to the previous line.
678 \value SelectStartOfLine Select to the start of the line.
679 \value SelectEndOfLine Select to the end of the line.
680 \value SelectStartOfBlock Select to the start of the block.
681 \value SelectEndOfBlock Select to the end of the block.
682 \value SelectStartOfDocument Select to the start of the document.
683 \value SelectEndOfDocument Select to the end of the document.
684 \value DeleteStartOfWord Delete to the start of the word.
685 \value DeleteEndOfWord Delete to the end of the word.
686 \value SetTextDirectionDefault Set the text direction to the default direction.
687 \value SetTextDirectionLeftToRight Set the text direction to left-to-right.
688 \value SetTextDirectionRightToLeft Set the text direction to right-to-left.
689 \value ToggleBold Toggle the formatting between bold and normal weight.
690 \value ToggleItalic Toggle the formatting between italic and normal style.
691 \value ToggleUnderline Toggle underlining.
692 \value InspectElement Show the Web Inspector with the currently highlighted HTML element.
693 \omitvalue WebActionCount
700 \brief The QWebPage class provides a widget that is used to view and edit web documents.
702 QWebPage holds a main frame responsible for web content, settings, the history
703 of navigated links as well as actions. This class can be used, together with QWebFrame,
704 if you want to provide functionality like QWebView in a setup without widgets.
708 Constructs an empty QWebView with parent \a parent.
710 QWebPage::QWebPage(QObject *parent)
712 , d(new QWebPagePrivate(this))
714 setView(qobject_cast<QWidget *>(parent));
716 connect(this, SIGNAL(loadProgressChanged(int)), this, SLOT(_q_onLoadProgressChanged(int)));
722 QWebPage::~QWebPage()
724 FrameLoader *loader = d->mainFrame->d->frame->loader();
726 loader->detachFromParent();
731 Returns the main frame of the page.
733 The main frame provides access to the hierarchy of sub-frames and is also needed if you
734 want to explicitly render a web page into a given painter.
736 QWebFrame *QWebPage::mainFrame() const
738 d->createMainFrame();
743 Returns the frame currently active.
745 QWebFrame *QWebPage::currentFrame() const
747 return static_cast<WebCore::FrameLoaderClientQt *>(d->page->focusController()->focusedOrMainFrame()->loader()->client())->webFrame();
751 Returns a pointer to the view's history of navigated web pages.
754 QWebHistory *QWebPage::history() const
760 Sets the \a view that is associated with the web page.
764 void QWebPage::setView(QWidget *view)
767 setViewportSize(view ? view->size() : QSize(0, 0));
771 Returns the view widget that is associated with the web page.
775 QWidget *QWebPage::view() const
782 This function is called whenever a JavaScript program tries to print to what is the console in web browsers.
784 void QWebPage::javaScriptConsoleMessage(const QString& message, unsigned int lineNumber, const QString& sourceID)
789 This function is called whenever a JavaScript program calls the alert() function.
791 void QWebPage::javaScriptAlert(QWebFrame *frame, const QString& msg)
793 QMessageBox::information(d->view, mainFrame()->title(), msg, QMessageBox::Ok);
797 This function is called whenever a JavaScript program calls the confirm() function.
799 bool QWebPage::javaScriptConfirm(QWebFrame *frame, const QString& msg)
801 return 0 == QMessageBox::information(d->view, mainFrame()->title(), msg, QMessageBox::Yes, QMessageBox::No);
805 This function is called whenever a JavaScript program tries to prompt the user of input.
807 bool QWebPage::javaScriptPrompt(QWebFrame *frame, const QString& msg, const QString& defaultValue, QString* result)
810 #ifndef QT_NO_INPUTDIALOG
811 QString x = QInputDialog::getText(d->view, mainFrame()->title(), msg, QLineEdit::Normal, defaultValue, &ok);
820 This function is called whenever WebKit wants to create a new window, for example as a result of
821 a JavaScript request to open a document in a new window.
823 QWebPage *QWebPage::createWindow()
825 QWebView *webView = qobject_cast<QWebView *>(d->view);
827 QWebView *newView = webView->createWindow();
829 return newView->page();
835 This function is called whenever WebKit wants to create a new window that should act as a modal dialog.
837 QWebPage *QWebPage::createModalDialog()
843 This function is called whenever WebKit encounters a HTML object element with type "application/x-qt-plugin".
844 The \a classid, \a url, \a paramNames and \a paramValues correspond to the HTML object element attributes and
845 child elements to configure the embeddable object.
847 QObject *QWebPage::createPlugin(const QString &classid, const QUrl &url, const QStringList ¶mNames, const QStringList ¶mValues)
852 Q_UNUSED(paramValues)
856 static WebCore::FrameLoadRequest frameLoadRequest(const QUrl &url, WebCore::Frame *frame)
858 WebCore::ResourceRequest rr(url, frame->loader()->outgoingReferrer());
859 return WebCore::FrameLoadRequest(rr);
862 static void openNewWindow(const QUrl& url, WebCore::Frame* frame)
864 if (Page* oldPage = frame->page()) {
865 WindowFeatures features;
866 if (Page* newPage = oldPage->chrome()->createWindow(frame,
867 frameLoadRequest(url, frame), features))
868 newPage->chrome()->show();
873 This function can be called to trigger the specified \a action.
874 It is also called by QtWebKit if the user triggers the action, for example
875 through a context menu item.
877 If \a action is a checkable action then \a checked specified whether the action
880 void QWebPage::triggerAction(WebAction action, bool checked)
882 WebCore::Frame *frame = d->page->focusController()->focusedOrMainFrame();
883 WebCore::Editor *editor = frame->editor();
884 const char *command = 0;
888 if (QWebFrame *targetFrame = d->currentContext.targetFrame()) {
889 WTF::RefPtr<WebCore::Frame> wcFrame = targetFrame->d->frame;
890 targetFrame->d->frame->loader()->load(frameLoadRequest(d->currentContext.linkUrl(), wcFrame.get()),
891 /*lockHistory*/ false,
892 /*userGesture*/ true,
894 /*HTMLFormElement*/ 0,
896 WTF::HashMap<String, String>());
901 case OpenLinkInNewWindow:
902 openNewWindow(d->currentContext.linkUrl(), frame);
904 case OpenFrameInNewWindow:
906 case CopyLinkToClipboard:
907 editor->copyURL(d->currentContext.linkUrl(), d->currentContext.text());
909 case OpenImageInNewWindow:
910 openNewWindow(d->currentContext.imageUrl(), frame);
912 case DownloadImageToDisk:
913 case DownloadLinkToDisk:
914 frame->loader()->client()->startDownload(WebCore::ResourceRequest(d->currentContext.linkUrl(), frame->loader()->outgoingReferrer()));
916 case CopyImageToClipboard:
922 d->page->goForward();
925 mainFrame()->d->frame->loader()->stopForUserCancel();
928 mainFrame()->d->frame->loader()->reload();
948 command = "MoveForward";
950 case MoveToPreviousChar:
951 command = "MoveBackward";
954 command = "MoveWordForward";
956 case MoveToPreviousWord:
957 command = "MoveWordBackward";
960 command = "MoveDown";
962 case MoveToPreviousLine:
965 case MoveToStartOfLine:
966 command = "MoveToBeginningOfLine";
968 case MoveToEndOfLine:
969 command = "MoveToEndOfLine";
971 case MoveToStartOfBlock:
972 command = "MoveToBeginningOfParagraph";
974 case MoveToEndOfBlock:
975 command = "MoveToEndOfParagraph";
977 case MoveToStartOfDocument:
978 command = "MoveToBeginningOfDocument";
980 case MoveToEndOfDocument:
981 command = "MoveToEndOfDocument";
984 command = "MoveForwardAndModifySelection";
986 case SelectPreviousChar:
987 command = "MoveBackwardAndModifySelection";
990 command = "MoveWordForwardAndModifySelection";
992 case SelectPreviousWord:
993 command = "MoveWordBackwardAndModifySelection";
996 command = "MoveDownAndModifySelection";
998 case SelectPreviousLine:
999 command = "MoveUpAndModifySelection";
1001 case SelectStartOfLine:
1002 command = "MoveToBeginningOfLineAndModifySelection";
1004 case SelectEndOfLine:
1005 command = "MoveToEndOfLineAndModifySelection";
1007 case SelectStartOfBlock:
1008 command = "MoveToBeginningOfParagraphAndModifySelection";
1010 case SelectEndOfBlock:
1011 command = "MoveToEndOfParagraphAndModifySelection";
1013 case SelectStartOfDocument:
1014 command = "MoveToBeginningOfDocumentAndModifySelection";
1016 case SelectEndOfDocument:
1017 command = "MoveToEndOfDocumentAndModifySelection";
1019 case DeleteStartOfWord:
1020 command = "DeleteWordBackward";
1022 case DeleteEndOfWord:
1023 command = "DeleteWordForward";
1026 case SetTextDirectionDefault:
1027 editor->setBaseWritingDirection("inherit");
1029 case SetTextDirectionLeftToRight:
1030 editor->setBaseWritingDirection("ltr");
1032 case SetTextDirectionRightToLeft:
1033 editor->setBaseWritingDirection("rtl");
1037 command = "ToggleBold";
1040 command = "ToggleItalic";
1042 case ToggleUnderline:
1043 editor->toggleUnderline();
1045 case InspectElement:
1046 d->page->inspectorController()->inspect(d->currentContext.d->innerNonSharedNode.get());
1053 editor->command(command).execute();
1056 QSize QWebPage::viewportSize() const
1058 if (d->mainFrame && d->mainFrame->d->frame->view())
1059 return d->mainFrame->d->frame->view()->frameGeometry().size();
1061 return d->viewportSize;
1065 \property QWebPage::viewportSize
1067 Specifies the size of the viewport. The size affects for example the visibility of scrollbars
1068 if the document is larger than the viewport.
1070 void QWebPage::setViewportSize(const QSize &size) const
1072 d->viewportSize = size;
1074 QWebFrame *frame = mainFrame();
1075 if (frame->d->frame && frame->d->frame->view()) {
1076 WebCore::FrameView* view = frame->d->frame->view();
1077 view->setFrameGeometry(QRect(QPoint(0, 0), size));
1078 frame->d->frame->forceLayout();
1079 view->adjustViewSize();
1084 #if QT_VERSION < 0x040400
1085 QWebPage::NavigationRequestResponse QWebPage::navigationRequested(QWebFrame *frame, const QWebNetworkRequest &request, QWebPage::NavigationType type)
1087 QWebPage::NavigationRequestResponse QWebPage::navigationRequested(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type)
1091 return AcceptNavigationRequest;
1095 \property QWebPage::selectedText
1097 Returns the text currently selected.
1099 QString QWebPage::selectedText() const
1101 return d->page->focusController()->focusedOrMainFrame()->selectedText();
1105 Returns a QAction for the specified WebAction \a action.
1107 The action is owned by the QWebPage but you can customize the look by
1108 changing its properties.
1110 QWebPage also takes care of implementing the action, so that upon
1111 triggering the corresponding action is performed on the page.
1113 QAction *QWebPage::action(WebAction action) const
1115 if (action == QWebPage::NoWebAction) return 0;
1116 if (d->actions[action])
1117 return d->actions[action];
1121 QStyle *style = view() ? view()->style() : qApp->style();
1122 bool checkable = false;
1126 text = contextMenuItemTagOpenLink();
1128 case OpenLinkInNewWindow:
1129 text = contextMenuItemTagOpenLinkInNewWindow();
1131 case OpenFrameInNewWindow:
1132 text = contextMenuItemTagOpenFrameInNewWindow();
1135 case DownloadLinkToDisk:
1136 text = contextMenuItemTagDownloadLinkToDisk();
1138 case CopyLinkToClipboard:
1139 text = contextMenuItemTagCopyLinkToClipboard();
1142 case OpenImageInNewWindow:
1143 text = contextMenuItemTagOpenImageInNewWindow();
1145 case DownloadImageToDisk:
1146 text = contextMenuItemTagDownloadImageToDisk();
1148 case CopyImageToClipboard:
1149 text = contextMenuItemTagCopyImageToClipboard();
1153 text = contextMenuItemTagGoBack();
1154 #if QT_VERSION >= 0x040400
1155 icon = style->standardIcon(QStyle::SP_ArrowBack);
1159 text = contextMenuItemTagGoForward();
1160 #if QT_VERSION >= 0x040400
1161 icon = style->standardIcon(QStyle::SP_ArrowForward);
1165 text = contextMenuItemTagStop();
1166 #if QT_VERSION >= 0x040400
1167 icon = style->standardIcon(QStyle::SP_BrowserStop);
1171 text = contextMenuItemTagReload();
1172 #if QT_VERSION >= 0x040400
1173 icon = style->standardIcon(QStyle::SP_BrowserReload);
1178 text = contextMenuItemTagCut();
1181 text = contextMenuItemTagCopy();
1184 text = contextMenuItemTagPaste();
1188 QAction *a = undoStack()->createUndoAction(d->q);
1189 d->actions[action] = a;
1193 QAction *a = undoStack()->createRedoAction(d->q);
1194 d->actions[action] = a;
1197 case MoveToNextChar:
1198 case MoveToPreviousChar:
1199 case MoveToNextWord:
1200 case MoveToPreviousWord:
1201 case MoveToNextLine:
1202 case MoveToPreviousLine:
1203 case MoveToStartOfLine:
1204 case MoveToEndOfLine:
1205 case MoveToStartOfBlock:
1206 case MoveToEndOfBlock:
1207 case MoveToStartOfDocument:
1208 case MoveToEndOfDocument:
1209 case SelectNextChar:
1210 case SelectPreviousChar:
1211 case SelectNextWord:
1212 case SelectPreviousWord:
1213 case SelectNextLine:
1214 case SelectPreviousLine:
1215 case SelectStartOfLine:
1216 case SelectEndOfLine:
1217 case SelectStartOfBlock:
1218 case SelectEndOfBlock:
1219 case SelectStartOfDocument:
1220 case SelectEndOfDocument:
1221 case DeleteStartOfWord:
1222 case DeleteEndOfWord:
1225 case SetTextDirectionDefault:
1226 text = contextMenuItemTagDefaultDirection();
1228 case SetTextDirectionLeftToRight:
1229 text = contextMenuItemTagLeftToRight();
1232 case SetTextDirectionRightToLeft:
1233 text = contextMenuItemTagRightToLeft();
1238 text = contextMenuItemTagBold();
1242 text = contextMenuItemTagItalic();
1245 case ToggleUnderline:
1246 text = contextMenuItemTagUnderline();
1250 case InspectElement:
1251 text = contextMenuItemTagInspectElement();
1261 QAction *a = new QAction(d->q);
1264 a->setCheckable(checkable);
1267 connect(a, SIGNAL(triggered(bool)),
1268 this, SLOT(_q_webActionTriggered(bool)));
1270 d->actions[action] = a;
1271 d->updateAction(action);
1276 \property QWebPage::modified
1278 Specifies if the page contains unsubmitted form data.
1280 bool QWebPage::isModified() const
1287 Returns a pointer to the undo stack used for editable content.
1289 QUndoStack *QWebPage::undoStack() const
1292 d->undoStack = new QUndoStack(const_cast<QWebPage *>(this));
1294 return d->undoStack;
1299 bool QWebPage::event(QEvent *ev)
1301 switch (ev->type()) {
1302 case QEvent::MouseMove:
1303 d->mouseMoveEvent(static_cast<QMouseEvent*>(ev));
1305 case QEvent::MouseButtonPress:
1306 d->mousePressEvent(static_cast<QMouseEvent*>(ev));
1308 case QEvent::MouseButtonDblClick:
1309 d->mouseDoubleClickEvent(static_cast<QMouseEvent*>(ev));
1311 case QEvent::MouseButtonRelease:
1312 d->mouseReleaseEvent(static_cast<QMouseEvent*>(ev));
1314 case QEvent::ContextMenu:
1315 d->contextMenuEvent(static_cast<QContextMenuEvent*>(ev));
1318 d->wheelEvent(static_cast<QWheelEvent*>(ev));
1320 case QEvent::KeyPress:
1321 d->keyPressEvent(static_cast<QKeyEvent*>(ev));
1323 case QEvent::KeyRelease:
1324 d->keyReleaseEvent(static_cast<QKeyEvent*>(ev));
1326 case QEvent::FocusIn:
1327 d->focusInEvent(static_cast<QFocusEvent*>(ev));
1329 case QEvent::FocusOut:
1330 d->focusOutEvent(static_cast<QFocusEvent*>(ev));
1332 #ifndef QT_NO_DRAGANDDROP
1333 case QEvent::DragEnter:
1334 d->dragEnterEvent(static_cast<QDragEnterEvent*>(ev));
1336 case QEvent::DragLeave:
1337 d->dragLeaveEvent(static_cast<QDragLeaveEvent*>(ev));
1339 case QEvent::DragMove:
1340 d->dragMoveEvent(static_cast<QDragMoveEvent*>(ev));
1343 d->dropEvent(static_cast<QDropEvent*>(ev));
1347 return QObject::event(ev);
1354 Similar to QWidget::focusNextPrevChild it focuses the next focusable web element
1355 if \a next is true. Otherwise the previous element is focused.
1357 bool QWebPage::focusNextPrevChild(bool next)
1359 QKeyEvent ev(QEvent::KeyPress, Qt::Key_Tab, Qt::KeyboardModifiers(next ? Qt::NoModifier : Qt::ShiftModifier));
1360 d->keyPressEvent(&ev);
1361 bool hasFocusedNode = false;
1362 Frame *frame = d->page->focusController()->focusedFrame();
1364 Document *document = frame->document();
1365 hasFocusedNode = document && document->focusedNode();
1367 //qDebug() << "focusNextPrevChild(" << next << ") =" << ev.isAccepted() << "focusedNode?" << hasFocusedNode;
1368 return hasFocusedNode;
1372 Returns a pointe to the page's settings object.
1374 QWebSettings *QWebPage::settings()
1380 This function is called when the web content requests a file name, for example
1381 as a result of the user clicking on a "file upload" button in a HTML form.
1383 QString QWebPage::chooseFile(QWebFrame *parentFrame, const QString& oldFile)
1385 #ifndef QT_NO_FILEDIALOG
1386 return QFileDialog::getOpenFileName(d->view, QString::null, oldFile);
1388 return QString::null;
1392 #if QT_VERSION < 0x040400
1394 void QWebPage::setNetworkInterface(QWebNetworkInterface *interface)
1396 d->networkInterface = interface;
1399 QWebNetworkInterface *QWebPage::networkInterface() const
1401 if (d->networkInterface)
1402 return d->networkInterface;
1404 return QWebNetworkInterface::defaultInterface();
1407 #ifndef QT_NO_NETWORKPROXY
1408 void QWebPage::setNetworkProxy(const QNetworkProxy& proxy)
1410 d->networkProxy = proxy;
1413 QNetworkProxy QWebPage::networkProxy() const
1415 return d->networkProxy;
1422 Sets the QNetworkAccessManager \a manager that is responsible for serving network
1423 requests for this QWebPage.
1425 \sa networkAccessManager
1427 void QWebPage::setNetworkAccessManager(QNetworkAccessManager *manager)
1429 if (manager == d->networkManager)
1431 delete d->networkManager;
1432 d->networkManager = manager;
1436 Returns the QNetworkAccessManager \a manager that is responsible for serving network
1437 requests for this QWebPage.
1439 \sa setNetworkAccessManager
1441 QNetworkAccessManager *QWebPage::networkAccessManager() const
1443 if (!d->networkManager) {
1444 QWebPage *that = const_cast<QWebPage *>(this);
1445 that->d->networkManager = new QNetworkAccessManager(that);
1447 return d->networkManager;
1452 void QWebPage::setPluginFactory(QWebPluginFactory *factory)
1454 d->pluginFactory = factory;
1457 QWebPluginFactory *QWebPage::pluginFactory() const
1459 return d->pluginFactory;
1463 This function is called when a user agent for HTTP requests is needed. You can re-implement this
1464 function to dynamically return different user agent's for different urls, based on the \a url parameter.
1466 QString QWebPage::userAgentFor(const QUrl& url) const
1469 return QLatin1String("Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en) AppleWebKit/523.15 (KHTML, like Gecko) Safari/419.3 Qt");
1473 void QWebPagePrivate::_q_onLoadProgressChanged(int) {
1474 m_totalBytes = page->progress()->totalPageAndResourceBytesToLoad();
1475 m_bytesReceived = page->progress()->totalBytesReceived();
1480 Returns the total number of bytes that were received from the network to render the current page,
1481 including extra content such as embedded images.
1483 quint64 QWebPage::totalBytes() const {
1484 return d->m_bytesReceived;
1489 Returns the number of bytes that were received from the network to render the current page.
1491 quint64 QWebPage::bytesReceived() const {
1492 return d->m_totalBytes;
1495 QWebPageContext::QWebPageContext(const WebCore::HitTestResult &hitTest)
1496 : d(new QWebPageContextPrivate)
1498 d->pos = hitTest.point();
1499 d->text = hitTest.textContent();
1500 d->linkUrl = hitTest.absoluteLinkURL().string();
1501 d->imageUrl = hitTest.absoluteImageURL().string();
1502 d->innerNonSharedNode = hitTest.innerNonSharedNode();
1503 WebCore::Image *img = hitTest.image();
1505 QPixmap *pix = img->getPixmap();
1509 WebCore::Frame *frame = hitTest.targetFrame();
1511 d->targetFrame = QWebFramePrivate::kit(frame);
1514 QWebPageContext::QWebPageContext()
1519 QWebPageContext::QWebPageContext(const QWebPageContext &other)
1523 d = new QWebPageContextPrivate(*other.d);
1526 QWebPageContext &QWebPageContext::operator=(const QWebPageContext &other)
1528 if (this != &other) {
1531 d = new QWebPageContextPrivate;
1541 QWebPageContext::~QWebPageContext()
1546 QPoint QWebPageContext::pos() const
1553 QString QWebPageContext::text() const
1560 QUrl QWebPageContext::linkUrl() const
1567 QUrl QWebPageContext::imageUrl() const
1574 QPixmap QWebPageContext::image() const
1581 QWebFrame *QWebPageContext::targetFrame() const
1585 return d->targetFrame;
1589 \fn void QWebPage::loadProgressChanged(int progress)
1591 This signal is emitted when the global progress status changes.
1592 The current value is provided by \a progress in percent.
1593 It accumulates changes from all the child frames.
1597 \fn void QWebPage::hoveringOverLink(const QString &link, const QString &title, const QString &textContent)
1599 This signal is emitted when the mouse is hovering over a link.
1600 The first parameter is the \a link url, the second is the link \a title
1601 if any, and third \a textContent is the text content. Method is emitter with both
1602 empty parameters when the mouse isn't hovering over any link element.
1606 \fn void QWebPage::statusBarTextChanged(const QString& text)
1608 This signal is emitted when the statusbar \a text is changed by the page.
1612 \fn void QWebPage::frameCreated(QWebFrame *frame)
1614 This signal is emitted whenever the page creates a new \a frame.
1618 \fn void QWebPage::selectionChanged()
1620 This signal is emitted whenever the selection changes.
1624 \fn void QWebPage::geometryChangeRequest(const QRect& geom)
1626 This signal is emitted whenever the document wants to change the position and size of the
1627 page to \a geom. This can happen for example through JavaScript.
1631 \fn void QWebPage::handleUnsupportedContent(QNetworkReply *reply)
1633 This signals is emitted when webkit cannot handle a link the user navigated to.
1635 At signal emissions time the meta data of the QNetworkReply is available.
1639 \fn void QWebPage::download(const QNetworkRequest &request)
1641 This signals is emitted when the user decides to download a link.
1644 #include "moc_qwebpage.cpp"