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)
116 chromeClient = new ChromeClientQt(q);
117 contextMenuClient = new ContextMenuClientQt();
118 editorClient = new EditorClientQt(q);
119 page = new Page(chromeClient, contextMenuClient, editorClient,
120 new DragClientQt(q), new InspectorClientQt(q));
122 // ### should be configurable
123 page->settings()->setDefaultTextEncodingName("iso-8859-1");
125 settings = new QWebSettings(page->settings());
129 #if QT_VERSION < 0x040400
130 networkInterface = 0;
135 insideOpenCall = false;
137 history.d = new QWebHistoryPrivate(page->backForwardList());
138 memset(actions, 0, sizeof(actions));
141 QWebPagePrivate::~QWebPagePrivate()
146 #if QT_VERSION >= 0x040400
147 delete networkManager;
151 #if QT_VERSION < 0x040400
152 QWebPage::NavigationRequestResponse QWebPagePrivate::navigationRequested(QWebFrame *frame, const QWebNetworkRequest &request, QWebPage::NavigationType type)
155 && frame == mainFrame)
156 return QWebPage::AcceptNavigationRequest;
157 return q->navigationRequested(frame, request, type);
160 QWebPage::NavigationRequestResponse QWebPagePrivate::navigationRequested(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type)
163 && frame == mainFrame)
164 return QWebPage::AcceptNavigationRequest;
165 return q->navigationRequested(frame, request, type);
169 void QWebPagePrivate::createMainFrame()
172 QWebFrameData frameData;
173 frameData.ownerElement = 0;
174 frameData.allowsScrolling = true;
175 frameData.marginWidth = 0;
176 frameData.marginHeight = 0;
177 mainFrame = new QWebFrame(q, &frameData);
178 mainFrame->d->frame->view()->setFrameGeometry(IntRect(IntPoint(0,0), q->viewportSize()));
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 QWebFrame *frame = mainFrame();
1059 if (frame->d->frame && frame->d->frame->view())
1060 return frame->d->frame->view()->frameGeometry().size();
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 QWebFrame *frame = mainFrame();
1073 if (frame->d->frame && frame->d->frame->view()) {
1074 WebCore::FrameView* view = frame->d->frame->view();
1075 view->setFrameGeometry(QRect(QPoint(0, 0), size));
1076 frame->d->frame->forceLayout();
1077 view->adjustViewSize();
1082 #if QT_VERSION < 0x040400
1083 QWebPage::NavigationRequestResponse QWebPage::navigationRequested(QWebFrame *frame, const QWebNetworkRequest &request, QWebPage::NavigationType type)
1085 QWebPage::NavigationRequestResponse QWebPage::navigationRequested(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type)
1089 return AcceptNavigationRequest;
1093 \property QWebPage::selectedText
1095 Returns the text currently selected.
1097 QString QWebPage::selectedText() const
1099 return d->page->focusController()->focusedOrMainFrame()->selectedText();
1103 Returns a QAction for the specified WebAction \a action.
1105 The action is owned by the QWebPage but you can customize the look by
1106 changing its properties.
1108 QWebPage also takes care of implementing the action, so that upon
1109 triggering the corresponding action is performed on the page.
1111 QAction *QWebPage::action(WebAction action) const
1113 if (action == QWebPage::NoWebAction) return 0;
1114 if (d->actions[action])
1115 return d->actions[action];
1119 QStyle *style = view() ? view()->style() : qApp->style();
1120 bool checkable = false;
1124 text = contextMenuItemTagOpenLink();
1126 case OpenLinkInNewWindow:
1127 text = contextMenuItemTagOpenLinkInNewWindow();
1129 case OpenFrameInNewWindow:
1130 text = contextMenuItemTagOpenFrameInNewWindow();
1133 case DownloadLinkToDisk:
1134 text = contextMenuItemTagDownloadLinkToDisk();
1136 case CopyLinkToClipboard:
1137 text = contextMenuItemTagCopyLinkToClipboard();
1140 case OpenImageInNewWindow:
1141 text = contextMenuItemTagOpenImageInNewWindow();
1143 case DownloadImageToDisk:
1144 text = contextMenuItemTagDownloadImageToDisk();
1146 case CopyImageToClipboard:
1147 text = contextMenuItemTagCopyImageToClipboard();
1151 text = contextMenuItemTagGoBack();
1152 #if QT_VERSION >= 0x040400
1153 icon = style->standardIcon(QStyle::SP_ArrowBack);
1157 text = contextMenuItemTagGoForward();
1158 #if QT_VERSION >= 0x040400
1159 icon = style->standardIcon(QStyle::SP_ArrowForward);
1163 text = contextMenuItemTagStop();
1164 #if QT_VERSION >= 0x040400
1165 icon = style->standardIcon(QStyle::SP_BrowserStop);
1169 text = contextMenuItemTagReload();
1170 #if QT_VERSION >= 0x040400
1171 icon = style->standardIcon(QStyle::SP_BrowserReload);
1176 text = contextMenuItemTagCut();
1179 text = contextMenuItemTagCopy();
1182 text = contextMenuItemTagPaste();
1186 QAction *a = undoStack()->createUndoAction(d->q);
1187 d->actions[action] = a;
1191 QAction *a = undoStack()->createRedoAction(d->q);
1192 d->actions[action] = a;
1195 case MoveToNextChar:
1196 case MoveToPreviousChar:
1197 case MoveToNextWord:
1198 case MoveToPreviousWord:
1199 case MoveToNextLine:
1200 case MoveToPreviousLine:
1201 case MoveToStartOfLine:
1202 case MoveToEndOfLine:
1203 case MoveToStartOfBlock:
1204 case MoveToEndOfBlock:
1205 case MoveToStartOfDocument:
1206 case MoveToEndOfDocument:
1207 case SelectNextChar:
1208 case SelectPreviousChar:
1209 case SelectNextWord:
1210 case SelectPreviousWord:
1211 case SelectNextLine:
1212 case SelectPreviousLine:
1213 case SelectStartOfLine:
1214 case SelectEndOfLine:
1215 case SelectStartOfBlock:
1216 case SelectEndOfBlock:
1217 case SelectStartOfDocument:
1218 case SelectEndOfDocument:
1219 case DeleteStartOfWord:
1220 case DeleteEndOfWord:
1223 case SetTextDirectionDefault:
1224 text = contextMenuItemTagDefaultDirection();
1226 case SetTextDirectionLeftToRight:
1227 text = contextMenuItemTagLeftToRight();
1230 case SetTextDirectionRightToLeft:
1231 text = contextMenuItemTagRightToLeft();
1236 text = contextMenuItemTagBold();
1240 text = contextMenuItemTagItalic();
1243 case ToggleUnderline:
1244 text = contextMenuItemTagUnderline();
1248 case InspectElement:
1249 text = contextMenuItemTagInspectElement();
1259 QAction *a = new QAction(d->q);
1262 a->setCheckable(checkable);
1265 connect(a, SIGNAL(triggered(bool)),
1266 this, SLOT(_q_webActionTriggered(bool)));
1268 d->actions[action] = a;
1269 d->updateAction(action);
1274 \property QWebPage::modified
1276 Specifies if the page contains unsubmitted form data.
1278 bool QWebPage::isModified() const
1285 Returns a pointer to the undo stack used for editable content.
1287 QUndoStack *QWebPage::undoStack() const
1290 d->undoStack = new QUndoStack(const_cast<QWebPage *>(this));
1292 return d->undoStack;
1297 bool QWebPage::event(QEvent *ev)
1299 switch (ev->type()) {
1300 case QEvent::MouseMove:
1301 d->mouseMoveEvent(static_cast<QMouseEvent*>(ev));
1303 case QEvent::MouseButtonPress:
1304 d->mousePressEvent(static_cast<QMouseEvent*>(ev));
1306 case QEvent::MouseButtonDblClick:
1307 d->mouseDoubleClickEvent(static_cast<QMouseEvent*>(ev));
1309 case QEvent::MouseButtonRelease:
1310 d->mouseReleaseEvent(static_cast<QMouseEvent*>(ev));
1312 case QEvent::ContextMenu:
1313 d->contextMenuEvent(static_cast<QContextMenuEvent*>(ev));
1316 d->wheelEvent(static_cast<QWheelEvent*>(ev));
1318 case QEvent::KeyPress:
1319 d->keyPressEvent(static_cast<QKeyEvent*>(ev));
1321 case QEvent::KeyRelease:
1322 d->keyReleaseEvent(static_cast<QKeyEvent*>(ev));
1324 case QEvent::FocusIn:
1325 d->focusInEvent(static_cast<QFocusEvent*>(ev));
1327 case QEvent::FocusOut:
1328 d->focusOutEvent(static_cast<QFocusEvent*>(ev));
1330 #ifndef QT_NO_DRAGANDDROP
1331 case QEvent::DragEnter:
1332 d->dragEnterEvent(static_cast<QDragEnterEvent*>(ev));
1334 case QEvent::DragLeave:
1335 d->dragLeaveEvent(static_cast<QDragLeaveEvent*>(ev));
1337 case QEvent::DragMove:
1338 d->dragMoveEvent(static_cast<QDragMoveEvent*>(ev));
1341 d->dropEvent(static_cast<QDropEvent*>(ev));
1345 return QObject::event(ev);
1352 Similar to QWidget::focusNextPrevChild it focuses the next focusable web element
1353 if \a next is true. Otherwise the previous element is focused.
1355 bool QWebPage::focusNextPrevChild(bool next)
1357 QKeyEvent ev(QEvent::KeyPress, Qt::Key_Tab, Qt::KeyboardModifiers(next ? Qt::NoModifier : Qt::ShiftModifier));
1358 d->keyPressEvent(&ev);
1359 bool hasFocusedNode = false;
1360 Frame *frame = d->page->focusController()->focusedFrame();
1362 Document *document = frame->document();
1363 hasFocusedNode = document && document->focusedNode();
1365 //qDebug() << "focusNextPrevChild(" << next << ") =" << ev.isAccepted() << "focusedNode?" << hasFocusedNode;
1366 return hasFocusedNode;
1370 Returns a pointe to the page's settings object.
1372 QWebSettings *QWebPage::settings()
1378 This function is called when the web content requests a file name, for example
1379 as a result of the user clicking on a "file upload" button in a HTML form.
1381 QString QWebPage::chooseFile(QWebFrame *parentFrame, const QString& oldFile)
1383 #ifndef QT_NO_FILEDIALOG
1384 return QFileDialog::getOpenFileName(d->view, QString::null, oldFile);
1386 return QString::null;
1390 #if QT_VERSION < 0x040400
1392 void QWebPage::setNetworkInterface(QWebNetworkInterface *interface)
1394 d->networkInterface = interface;
1397 QWebNetworkInterface *QWebPage::networkInterface() const
1399 if (d->networkInterface)
1400 return d->networkInterface;
1402 return QWebNetworkInterface::defaultInterface();
1405 #ifndef QT_NO_NETWORKPROXY
1406 void QWebPage::setNetworkProxy(const QNetworkProxy& proxy)
1408 d->networkProxy = proxy;
1411 QNetworkProxy QWebPage::networkProxy() const
1413 return d->networkProxy;
1420 Sets the QNetworkAccessManager \a manager that is responsible for serving network
1421 requests for this QWebPage.
1423 \sa networkAccessManager
1425 void QWebPage::setNetworkAccessManager(QNetworkAccessManager *manager)
1427 if (manager == d->networkManager)
1429 delete d->networkManager;
1430 d->networkManager = manager;
1434 Returns the QNetworkAccessManager \a manager that is responsible for serving network
1435 requests for this QWebPage.
1437 \sa setNetworkAccessManager
1439 QNetworkAccessManager *QWebPage::networkAccessManager() const
1441 if (!d->networkManager) {
1442 QWebPage *that = const_cast<QWebPage *>(this);
1443 that->d->networkManager = new QNetworkAccessManager(that);
1445 return d->networkManager;
1450 void QWebPage::setPluginFactory(QWebPluginFactory *factory)
1452 d->pluginFactory = factory;
1455 QWebPluginFactory *QWebPage::pluginFactory() const
1457 return d->pluginFactory;
1461 This function is called when a user agent for HTTP requests is needed. You can re-implement this
1462 function to dynamically return different user agent's for different urls, based on the \a url parameter.
1464 QString QWebPage::userAgentFor(const QUrl& url) const
1467 return QLatin1String("Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en) AppleWebKit/523.15 (KHTML, like Gecko) Safari/419.3 Qt");
1471 void QWebPagePrivate::_q_onLoadProgressChanged(int) {
1472 m_totalBytes = page->progress()->totalPageAndResourceBytesToLoad();
1473 m_bytesReceived = page->progress()->totalBytesReceived();
1478 Returns the total number of bytes that were received from the network to render the current page,
1479 including extra content such as embedded images.
1481 quint64 QWebPage::totalBytes() const {
1482 return d->m_bytesReceived;
1487 Returns the number of bytes that were received from the network to render the current page.
1489 quint64 QWebPage::bytesReceived() const {
1490 return d->m_totalBytes;
1493 QWebPageContext::QWebPageContext(const WebCore::HitTestResult &hitTest)
1494 : d(new QWebPageContextPrivate)
1496 d->pos = hitTest.point();
1497 d->text = hitTest.textContent();
1498 d->linkUrl = hitTest.absoluteLinkURL().string();
1499 d->imageUrl = hitTest.absoluteImageURL().string();
1500 d->innerNonSharedNode = hitTest.innerNonSharedNode();
1501 WebCore::Image *img = hitTest.image();
1503 QPixmap *pix = img->getPixmap();
1507 WebCore::Frame *frame = hitTest.targetFrame();
1509 d->targetFrame = QWebFramePrivate::kit(frame);
1512 QWebPageContext::QWebPageContext()
1517 QWebPageContext::QWebPageContext(const QWebPageContext &other)
1521 d = new QWebPageContextPrivate(*other.d);
1524 QWebPageContext &QWebPageContext::operator=(const QWebPageContext &other)
1526 if (this != &other) {
1529 d = new QWebPageContextPrivate;
1539 QWebPageContext::~QWebPageContext()
1544 QPoint QWebPageContext::pos() const
1551 QString QWebPageContext::text() const
1558 QUrl QWebPageContext::linkUrl() const
1565 QUrl QWebPageContext::imageUrl() const
1572 QPixmap QWebPageContext::image() const
1579 QWebFrame *QWebPageContext::targetFrame() const
1583 return d->targetFrame;
1587 \fn void QWebPage::loadProgressChanged(int progress)
1589 This signal is emitted when the global progress status changes.
1590 The current value is provided by \a progress in percent.
1591 It accumulates changes from all the child frames.
1595 \fn void QWebPage::hoveringOverLink(const QString &link, const QString &title, const QString &textContent)
1597 This signal is emitted when the mouse is hovering over a link.
1598 The first parameter is the \a link url, the second is the link \a title
1599 if any, and third \a textContent is the text content. Method is emitter with both
1600 empty parameters when the mouse isn't hovering over any link element.
1604 \fn void QWebPage::statusBarTextChanged(const QString& text)
1606 This signal is emitted when the statusbar \a text is changed by the page.
1610 \fn void QWebPage::frameCreated(QWebFrame *frame)
1612 This signal is emitted whenever the page creates a new \a frame.
1616 \fn void QWebPage::selectionChanged()
1618 This signal is emitted whenever the selection changes.
1622 \fn void QWebPage::geometryChangeRequest(const QRect& geom)
1624 This signal is emitted whenever the document wants to change the position and size of the
1625 page to \a geom. This can happen for example through JavaScript.
1629 \fn void QWebPage::handleUnsupportedContent(QNetworkReply *reply)
1631 This signals is emitted when webkit cannot handle a link the user navigated to.
1633 At signal emissions time the meta data of the QNetworkReply is available.
1637 \fn void QWebPage::download(const QNetworkRequest &request)
1639 This signals is emitted when the user decides to download a link.
1642 #include "moc_qwebpage.cpp"