#include "config.h"
#include "qwebpage.h"
#include "qwebview.h"
#include "qwebframe.h"
#include "qwebpage_p.h"
#include "qwebframe_p.h"
#include "qwebhistory.h"
#include "qwebhistory_p.h"
#include "qwebinspector.h"
#include "qwebinspector_p.h"
#include "qwebsettings.h"
#include "qwebkitplatformplugin.h"
#include "qwebkitversion.h"
#include "CSSComputedStyleDeclaration.h"
#include "CSSParser.h"
#include "ApplicationCacheStorage.h"
#include "BackForwardListImpl.h"
#include "MemoryCache.h"
#include "Chrome.h"
#include "ChromeClientQt.h"
#include "ClientRect.h"
#include "ContextMenu.h"
#include "ContextMenuClientQt.h"
#include "ContextMenuController.h"
#if ENABLE(DEVICE_ORIENTATION)
#include "DeviceMotionClientQt.h"
#include "DeviceOrientationClientMock.h"
#include "DeviceOrientationClientQt.h"
#endif
#include "DocumentLoader.h"
#include "DragClientQt.h"
#include "DragController.h"
#include "DragData.h"
#include "DragSession.h"
#include "Editor.h"
#include "EditorClientQt.h"
#include "FocusController.h"
#include "FormState.h"
#include "Frame.h"
#include "FrameLoadRequest.h"
#include "FrameLoader.h"
#include "FrameLoader.h"
#include "FrameLoaderClientQt.h"
#include "FrameTree.h"
#include "FrameView.h"
#if ENABLE(GEOLOCATION)
#include "GeolocationClientMock.h"
#include "GeolocationClientQt.h"
#include "GeolocationController.h"
#endif
#include "GeolocationPermissionClientQt.h"
#include "HTMLFormElement.h"
#include "HTMLFrameOwnerElement.h"
#include "HTMLInputElement.h"
#include "HTMLNames.h"
#include "HitTestResult.h"
#include "Image.h"
#include "InitWebCoreQt.h"
#include "InspectorClientQt.h"
#include "InspectorController.h"
#include "InspectorServerQt.h"
#include "KURL.h"
#include "LocalizedStrings.h"
#include "MIMETypeRegistry.h"
#include "NavigationAction.h"
#include "NetworkingContext.h"
#include "NodeList.h"
#include "NotificationPresenterClientQt.h"
#include "NotImplemented.h"
#include "Page.h"
#include "PageClientQt.h"
#include "PageGroup.h"
#include "Pasteboard.h"
#include "PlatformKeyboardEvent.h"
#include "PlatformTouchEvent.h"
#include "PlatformWheelEvent.h"
#include "PluginDatabase.h"
#include "PluginDatabase.h"
#include "PluginPackage.h"
#include "ProgressTracker.h"
#include "QtPlatformPlugin.h"
#include "RenderTextControl.h"
#include "RenderThemeQt.h"
#include "SchemeRegistry.h"
#include "Scrollbar.h"
#include "ScrollbarTheme.h"
#include "SecurityOrigin.h"
#include "Settings.h"
#if defined Q_OS_WIN32
#include "SystemInfo.h"
#endif // Q_OS_WIN32
#include "TextIterator.h"
#include "UtilsQt.h"
#include "WebEventConversion.h"
#include "WindowFeatures.h"
#include "WorkerThread.h"
#include <QAction>
#include <QApplication>
#include <QBasicTimer>
#include <QBitArray>
#include <QDebug>
#include <QDesktopWidget>
#include <QDragEnterEvent>
#include <QDragLeaveEvent>
#include <QDragMoveEvent>
#include <QDropEvent>
#include <QFileDialog>
#include <QInputDialog>
#include <QMenu>
#include <QMessageBox>
#include <QNetworkProxy>
#include <QUndoStack>
#include <QUrl>
#include <QPainter>
#include <QClipboard>
#include <QSslSocket>
#include <QStyle>
#include <QSysInfo>
#include <QTextCharFormat>
#include <QTouchEvent>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#if defined(Q_WS_X11)
#include <QX11Info>
#endif
#if USE(QT_MOBILITY_SYSTEMINFO)
#include <qsysteminfo.h>
#endif
using namespace WebCore;
QT_BEGIN_NAMESPACE
extern Q_GUI_EXPORT int qt_defaultDpi();
QT_END_NAMESPACE
bool QWebPagePrivate::drtRun = false;
static const char* editorCommandWebActions[] =
{
0,
0, 0,
0, 0,
0, 0, 0,
0, 0, 0, 0,
"Cut", "Copy", "Paste",
"Undo", "Redo", "MoveForward", "MoveBackward", "MoveWordForward", "MoveWordBackward", "MoveDown", "MoveUp", "MoveToBeginningOfLine", "MoveToEndOfLine", "MoveToBeginningOfParagraph", "MoveToEndOfParagraph", "MoveToBeginningOfDocument", "MoveToEndOfDocument", "MoveForwardAndModifySelection", "MoveBackwardAndModifySelection", "MoveWordForwardAndModifySelection", "MoveWordBackwardAndModifySelection", "MoveDownAndModifySelection", "MoveUpAndModifySelection", "MoveToBeginningOfLineAndModifySelection", "MoveToEndOfLineAndModifySelection", "MoveToBeginningOfParagraphAndModifySelection", "MoveToEndOfParagraphAndModifySelection", "MoveToBeginningOfDocumentAndModifySelection", "MoveToEndOfDocumentAndModifySelection", "DeleteWordBackward", "DeleteWordForward",
0, 0, 0,
"ToggleBold", "ToggleItalic", "ToggleUnderline",
0,
"InsertNewline", "InsertLineBreak",
"SelectAll", 0,
"PasteAndMatchStyle", "RemoveFormat", "Strikethrough", "Subscript", "Superscript", "InsertUnorderedList", "InsertOrderedList", "Indent", "Outdent",
"AlignCenter", "AlignJustified", "AlignLeft", "AlignRight",
0,
0,
0 };
const char* QWebPagePrivate::editorCommandForWebActions(QWebPage::WebAction action)
{
if ((action > QWebPage::NoWebAction) && (action < int(sizeof(editorCommandWebActions) / sizeof(const char*))))
return editorCommandWebActions[action];
return 0;
}
static inline DragOperation dropActionToDragOp(Qt::DropActions actions)
{
unsigned result = 0;
if (actions & Qt::CopyAction)
result |= DragOperationCopy;
if (actions & Qt::MoveAction)
result |= (DragOperationMove | DragOperationGeneric);
if (actions & Qt::LinkAction)
result |= DragOperationLink;
if (result == (DragOperationCopy | DragOperationMove | DragOperationGeneric | DragOperationLink))
result = DragOperationEvery;
return (DragOperation)result;
}
static inline Qt::DropAction dragOpToDropAction(unsigned actions)
{
Qt::DropAction result = Qt::IgnoreAction;
if (actions & DragOperationCopy)
result = Qt::CopyAction;
else if (actions & DragOperationMove)
result = Qt::MoveAction;
else if (actions & DragOperationGeneric)
result = Qt::MoveAction;
else if (actions & DragOperationLink)
result = Qt::LinkAction;
return result;
}
QWebPagePrivate::QWebPagePrivate(QWebPage *qq)
: q(qq)
, page(0)
#ifndef QT_NO_UNDOSTACK
, undoStack(0)
#endif
, insideOpenCall(false)
, m_totalBytes(0)
, m_bytesReceived()
, clickCausedFocus(false)
, networkManager(0)
, forwardUnsupportedContent(false)
, smartInsertDeleteEnabled(true)
, selectTrailingWhitespaceEnabled(false)
, linkPolicy(QWebPage::DontDelegateLinks)
, viewportSize(QSize(0, 0))
, settings(0)
, useFixedLayout(false)
, pluginFactory(0)
, inspectorFrontend(0)
, inspector(0)
, inspectorIsInternalOnly(false)
, m_lastDropAction(Qt::IgnoreAction)
{
#if ENABLE(GEOLOCATION) || ENABLE(DEVICE_ORIENTATION)
bool useMock = QWebPagePrivate::drtRun;
#endif
WebCore::initializeWebCoreQt();
Page::PageClients pageClients;
pageClients.chromeClient = new ChromeClientQt(q);
pageClients.contextMenuClient = new ContextMenuClientQt();
pageClients.editorClient = new EditorClientQt(q);
pageClients.dragClient = new DragClientQt(q);
pageClients.inspectorClient = new InspectorClientQt(q);
page = new Page(pageClients);
#if ENABLE(GEOLOCATION)
if (useMock) {
GeolocationClientMock* mock = new GeolocationClientMock;
WebCore::provideGeolocationTo(page, mock);
mock->setController(WebCore::GeolocationController::from(page));
} else
WebCore::provideGeolocationTo(page, new GeolocationClientQt(q));
#endif
#if ENABLE(DEVICE_ORIENTATION)
if (useMock)
WebCore::provideDeviceOrientationTo(page, new DeviceOrientationClientMock);
else
WebCore::provideDeviceOrientationTo(page, new DeviceOrientationClientQt);
WebCore::provideDeviceMotionTo(page, new DeviceMotionClientQt);
#endif
#if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
WebCore::provideNotification(page, NotificationPresenterClientQt::notificationPresenter());
#endif
page->setGroupName("Default Group");
settings = new QWebSettings(page->settings());
#if ENABLE(WEB_SOCKETS)
page->settings()->setUseHixie76WebSocketProtocol(false);
#endif
history.d = new QWebHistoryPrivate(static_cast<WebCore::BackForwardListImpl*>(page->backForwardList()));
memset(actions, 0, sizeof(actions));
PageGroup::setShouldTrackVisitedLinks(true);
#if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
NotificationPresenterClientQt::notificationPresenter()->addClient();
#endif
}
QWebPagePrivate::~QWebPagePrivate()
{
if (inspector && inspectorIsInternalOnly) {
setInspector(0);
}
#ifndef QT_NO_CONTEXTMENU
delete currentContextMenu.data();
#endif
#ifndef QT_NO_UNDOSTACK
delete undoStack;
#endif
delete settings;
delete page;
if (inspector)
inspector->setPage(0);
#if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
NotificationPresenterClientQt::notificationPresenter()->removeClient();
#endif
}
WebCore::ViewportArguments QWebPagePrivate::viewportArguments()
{
return page ? page->viewportArguments() : WebCore::ViewportArguments();
}
WebCore::Page* QWebPagePrivate::core(const QWebPage* page)
{
return page->d->page;
}
QWebPagePrivate* QWebPagePrivate::priv(QWebPage* page)
{
return page->d;
}
bool QWebPagePrivate::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type)
{
if (insideOpenCall
&& frame == mainFrame.data())
return true;
return q->acceptNavigationRequest(frame, request, type);
}
void QWebPagePrivate::createMainFrame()
{
if (!mainFrame) {
QWebFrameData frameData(page);
mainFrame = new QWebFrame(q, &frameData);
emit q->frameCreated(mainFrame.data());
}
}
static QWebPage::WebAction webActionForContextMenuAction(WebCore::ContextMenuAction action)
{
switch (action) {
case WebCore::ContextMenuItemTagOpenLink: return QWebPage::OpenLink;
case WebCore::ContextMenuItemTagOpenLinkInNewWindow: return QWebPage::OpenLinkInNewWindow;
case WebCore::ContextMenuItemTagDownloadLinkToDisk: return QWebPage::DownloadLinkToDisk;
case WebCore::ContextMenuItemTagCopyLinkToClipboard: return QWebPage::CopyLinkToClipboard;
case WebCore::ContextMenuItemTagOpenImageInNewWindow: return QWebPage::OpenImageInNewWindow;
case WebCore::ContextMenuItemTagDownloadImageToDisk: return QWebPage::DownloadImageToDisk;
case WebCore::ContextMenuItemTagCopyImageToClipboard: return QWebPage::CopyImageToClipboard;
case WebCore::ContextMenuItemTagCopyImageUrlToClipboard: return QWebPage::CopyImageUrlToClipboard;
case WebCore::ContextMenuItemTagOpenFrameInNewWindow: return QWebPage::OpenFrameInNewWindow;
case WebCore::ContextMenuItemTagCopy: return QWebPage::Copy;
case WebCore::ContextMenuItemTagGoBack: return QWebPage::Back;
case WebCore::ContextMenuItemTagGoForward: return QWebPage::Forward;
case WebCore::ContextMenuItemTagStop: return QWebPage::Stop;
case WebCore::ContextMenuItemTagReload: return QWebPage::Reload;
case WebCore::ContextMenuItemTagCut: return QWebPage::Cut;
case WebCore::ContextMenuItemTagPaste: return QWebPage::Paste;
case WebCore::ContextMenuItemTagDefaultDirection: return QWebPage::SetTextDirectionDefault;
case WebCore::ContextMenuItemTagLeftToRight: return QWebPage::SetTextDirectionLeftToRight;
case WebCore::ContextMenuItemTagRightToLeft: return QWebPage::SetTextDirectionRightToLeft;
case WebCore::ContextMenuItemTagBold: return QWebPage::ToggleBold;
case WebCore::ContextMenuItemTagItalic: return QWebPage::ToggleItalic;
case WebCore::ContextMenuItemTagUnderline: return QWebPage::ToggleUnderline;
case WebCore::ContextMenuItemTagSelectAll: return QWebPage::SelectAll;
#if ENABLE(INSPECTOR)
case WebCore::ContextMenuItemTagInspectElement: return QWebPage::InspectElement;
#endif
default: break;
}
return QWebPage::NoWebAction;
}
#ifndef QT_NO_CONTEXTMENU
QMenu *QWebPagePrivate::createContextMenu(const WebCore::ContextMenu *webcoreMenu,
const QList<WebCore::ContextMenuItem> *items, QBitArray *visitedWebActions)
{
if (!client || !webcoreMenu)
return 0;
QMenu* menu = new QMenu(client->ownerWidget());
for (int i = 0; i < items->count(); ++i) {
const ContextMenuItem &item = items->at(i);
switch (item.type()) {
case WebCore::CheckableActionType:
case WebCore::ActionType: {
QWebPage::WebAction action = webActionForContextMenuAction(item.action());
QAction *a = q->action(action);
if (a) {
ContextMenuItem it(item);
page->contextMenuController()->checkOrEnableIfNeeded(it);
PlatformMenuItemDescription desc = it.releasePlatformDescription();
a->setEnabled(desc.enabled);
a->setChecked(desc.checked);
a->setCheckable(item.type() == WebCore::CheckableActionType);
menu->addAction(a);
visitedWebActions->setBit(action);
}
break;
}
case WebCore::SeparatorType:
menu->addSeparator();
break;
case WebCore::SubmenuType: {
QMenu *subMenu = createContextMenu(webcoreMenu, item.platformSubMenu(), visitedWebActions);
bool anyEnabledAction = false;
QList<QAction *> actions = subMenu->actions();
for (int i = 0; i < actions.count(); ++i) {
if (actions.at(i)->isVisible())
anyEnabledAction |= actions.at(i)->isEnabled();
}
if (anyEnabledAction) {
subMenu->setTitle(item.title());
menu->addAction(subMenu->menuAction());
} else
delete subMenu;
break;
}
}
}
return menu;
}
#endif // QT_NO_CONTEXTMENU
#ifndef QT_NO_ACTION
void QWebPagePrivate::_q_webActionTriggered(bool checked)
{
QAction *a = qobject_cast<QAction *>(q->sender());
if (!a)
return;
QWebPage::WebAction action = static_cast<QWebPage::WebAction>(a->data().toInt());
q->triggerAction(action, checked);
}
#endif // QT_NO_ACTION
void QWebPagePrivate::_q_cleanupLeakMessages()
{
#ifndef NDEBUG
memoryCache()->setCapacities(0, 0, 0);
#endif
}
void QWebPagePrivate::updateAction(QWebPage::WebAction action)
{
#ifdef QT_NO_ACTION
Q_UNUSED(action)
#else
QAction *a = actions[action];
if (!a || !mainFrame)
return;
WebCore::FrameLoader *loader = mainFrame.data()->d->frame->loader();
WebCore::Editor *editor = page->focusController()->focusedOrMainFrame()->editor();
bool enabled = a->isEnabled();
bool checked = a->isChecked();
switch (action) {
case QWebPage::Back:
enabled = page->canGoBackOrForward(-1);
break;
case QWebPage::Forward:
enabled = page->canGoBackOrForward(1);
break;
case QWebPage::Stop:
enabled = loader->isLoading();
break;
case QWebPage::Reload:
case QWebPage::ReloadAndBypassCache:
enabled = !loader->isLoading();
break;
#ifndef QT_NO_UNDOSTACK
case QWebPage::Undo:
case QWebPage::Redo:
break;
#endif // QT_NO_UNDOSTACK
case QWebPage::SelectAll: break;
case QWebPage::SetTextDirectionDefault:
case QWebPage::SetTextDirectionLeftToRight:
case QWebPage::SetTextDirectionRightToLeft:
enabled = editor->canEdit();
checked = false;
break;
default: {
const char* commandName = editorCommandForWebActions(action);
if (commandName) {
Editor::Command command = editor->command(commandName);
enabled = command.isEnabled();
if (enabled)
checked = command.state() != FalseTriState;
else
checked = false;
}
break;
}
}
a->setEnabled(enabled);
if (a->isCheckable())
a->setChecked(checked);
#endif // QT_NO_ACTION
}
void QWebPagePrivate::updateNavigationActions()
{
updateAction(QWebPage::Back);
updateAction(QWebPage::Forward);
updateAction(QWebPage::Stop);
updateAction(QWebPage::Reload);
updateAction(QWebPage::ReloadAndBypassCache);
}
void QWebPagePrivate::updateEditorActions()
{
updateAction(QWebPage::Cut);
updateAction(QWebPage::Copy);
updateAction(QWebPage::Paste);
updateAction(QWebPage::MoveToNextChar);
updateAction(QWebPage::MoveToPreviousChar);
updateAction(QWebPage::MoveToNextWord);
updateAction(QWebPage::MoveToPreviousWord);
updateAction(QWebPage::MoveToNextLine);
updateAction(QWebPage::MoveToPreviousLine);
updateAction(QWebPage::MoveToStartOfLine);
updateAction(QWebPage::MoveToEndOfLine);
updateAction(QWebPage::MoveToStartOfBlock);
updateAction(QWebPage::MoveToEndOfBlock);
updateAction(QWebPage::MoveToStartOfDocument);
updateAction(QWebPage::MoveToEndOfDocument);
updateAction(QWebPage::SelectNextChar);
updateAction(QWebPage::SelectPreviousChar);
updateAction(QWebPage::SelectNextWord);
updateAction(QWebPage::SelectPreviousWord);
updateAction(QWebPage::SelectNextLine);
updateAction(QWebPage::SelectPreviousLine);
updateAction(QWebPage::SelectStartOfLine);
updateAction(QWebPage::SelectEndOfLine);
updateAction(QWebPage::SelectStartOfBlock);
updateAction(QWebPage::SelectEndOfBlock);
updateAction(QWebPage::SelectStartOfDocument);
updateAction(QWebPage::SelectEndOfDocument);
updateAction(QWebPage::DeleteStartOfWord);
updateAction(QWebPage::DeleteEndOfWord);
updateAction(QWebPage::SetTextDirectionDefault);
updateAction(QWebPage::SetTextDirectionLeftToRight);
updateAction(QWebPage::SetTextDirectionRightToLeft);
updateAction(QWebPage::ToggleBold);
updateAction(QWebPage::ToggleItalic);
updateAction(QWebPage::ToggleUnderline);
updateAction(QWebPage::InsertParagraphSeparator);
updateAction(QWebPage::InsertLineSeparator);
updateAction(QWebPage::PasteAndMatchStyle);
updateAction(QWebPage::RemoveFormat);
updateAction(QWebPage::ToggleStrikethrough);
updateAction(QWebPage::ToggleSubscript);
updateAction(QWebPage::ToggleSuperscript);
updateAction(QWebPage::InsertUnorderedList);
updateAction(QWebPage::InsertOrderedList);
updateAction(QWebPage::Indent);
updateAction(QWebPage::Outdent);
updateAction(QWebPage::AlignCenter);
updateAction(QWebPage::AlignJustified);
updateAction(QWebPage::AlignLeft);
updateAction(QWebPage::AlignRight);
}
void QWebPagePrivate::timerEvent(QTimerEvent *ev)
{
int timerId = ev->timerId();
if (timerId == tripleClickTimer.timerId())
tripleClickTimer.stop();
else
q->timerEvent(ev);
}
template<class T>
void QWebPagePrivate::mouseMoveEvent(T* ev)
{
WebCore::Frame* frame = QWebFramePrivate::core(mainFrame.data());
if (!frame->view())
return;
bool accepted = frame->eventHandler()->mouseMoved(convertMouseEvent(ev, 0));
ev->setAccepted(accepted);
}
template<class T>
void QWebPagePrivate::mousePressEvent(T* ev)
{
WebCore::Frame* frame = QWebFramePrivate::core(mainFrame.data());
if (!frame->view())
return;
RefPtr<WebCore::Node> oldNode;
Frame* focusedFrame = page->focusController()->focusedFrame();
if (Document* focusedDocument = focusedFrame ? focusedFrame->document() : 0)
oldNode = focusedDocument->focusedNode();
if (tripleClickTimer.isActive()
&& (ev->pos() - tripleClick).manhattanLength()
< QApplication::startDragDistance()) {
mouseTripleClickEvent(ev);
return;
}
bool accepted = false;
adjustPointForClicking(ev);
PlatformMouseEvent mev = convertMouseEvent(ev, 1);
if (mev.button() != NoButton)
accepted = frame->eventHandler()->handleMousePressEvent(mev);
ev->setAccepted(accepted);
RefPtr<WebCore::Node> newNode;
focusedFrame = page->focusController()->focusedFrame();
if (Document* focusedDocument = focusedFrame ? focusedFrame->document() : 0)
newNode = focusedDocument->focusedNode();
if (newNode && oldNode != newNode)
clickCausedFocus = true;
}
template<class T>
void QWebPagePrivate::mouseDoubleClickEvent(T *ev)
{
WebCore::Frame* frame = QWebFramePrivate::core(mainFrame.data());
if (!frame->view())
return;
bool accepted = false;
PlatformMouseEvent mev = convertMouseEvent(ev, 2);
if (mev.button() != NoButton)
accepted = frame->eventHandler()->handleMousePressEvent(mev);
ev->setAccepted(accepted);
tripleClickTimer.start(QApplication::doubleClickInterval(), q);
tripleClick = QPointF(ev->pos()).toPoint();
}
template<class T>
void QWebPagePrivate::mouseTripleClickEvent(T *ev)
{
WebCore::Frame* frame = QWebFramePrivate::core(mainFrame.data());
if (!frame->view())
return;
bool accepted = false;
PlatformMouseEvent mev = convertMouseEvent(ev, 3);
if (mev.button() != NoButton)
accepted = frame->eventHandler()->handleMousePressEvent(mev);
ev->setAccepted(accepted);
}
void QWebPagePrivate::handleClipboard(QEvent* ev, Qt::MouseButton button)
{
#ifndef QT_NO_CLIPBOARD
if (QApplication::clipboard()->supportsSelection()) {
bool oldSelectionMode = Pasteboard::generalPasteboard()->isSelectionMode();
Pasteboard::generalPasteboard()->setSelectionMode(true);
WebCore::Frame* focusFrame = page->focusController()->focusedOrMainFrame();
if (button == Qt::LeftButton) {
if (focusFrame && (focusFrame->editor()->canCopy() || focusFrame->editor()->canDHTMLCopy())) {
Pasteboard::generalPasteboard()->writeSelection(focusFrame->editor()->selectedRange().get(), focusFrame->editor()->canSmartCopyOrDelete(), focusFrame);
ev->setAccepted(true);
}
} else if (button == Qt::MidButton) {
if (focusFrame && (focusFrame->editor()->canPaste() || focusFrame->editor()->canDHTMLPaste())) {
focusFrame->editor()->paste();
ev->setAccepted(true);
}
}
Pasteboard::generalPasteboard()->setSelectionMode(oldSelectionMode);
}
#endif
}
template<class T>
void QWebPagePrivate::mouseReleaseEvent(T *ev)
{
WebCore::Frame* frame = QWebFramePrivate::core(mainFrame.data());
if (!frame->view())
return;
bool accepted = false;
adjustPointForClicking(ev);
PlatformMouseEvent mev = convertMouseEvent(ev, 0);
if (mev.button() != NoButton)
accepted = frame->eventHandler()->handleMouseReleaseEvent(mev);
ev->setAccepted(accepted);
handleClipboard(ev, ev->button());
handleSoftwareInputPanel(ev->button(), QPointF(ev->pos()).toPoint());
}
void QWebPagePrivate::handleSoftwareInputPanel(Qt::MouseButton button, const QPoint& pos)
{
Frame* frame = page->focusController()->focusedFrame();
if (!frame)
return;
if (client && client->inputMethodEnabled()
&& frame->document()->focusedNode()
&& button == Qt::LeftButton && qApp->autoSipEnabled()) {
QStyle::RequestSoftwareInputPanel behavior = QStyle::RequestSoftwareInputPanel(
client->ownerWidget()->style()->styleHint(QStyle::SH_RequestSoftwareInputPanel));
if (!clickCausedFocus || behavior == QStyle::RSIP_OnMouseClick) {
HitTestResult result = frame->eventHandler()->hitTestResultAtPoint(frame->view()->windowToContents(pos), false);
if (result.isContentEditable()) {
QEvent event(QEvent::RequestSoftwareInputPanel);
QApplication::sendEvent(client->ownerWidget(), &event);
}
}
}
clickCausedFocus = false;
}
#ifndef QT_NO_CONTEXTMENU
void QWebPagePrivate::contextMenuEvent(const QPoint& globalPos)
{
QMenu *menu = q->createStandardContextMenu();
if (menu) {
menu->exec(globalPos);
delete menu;
}
}
#endif // QT_NO_CONTEXTMENU
QMenu *QWebPage::createStandardContextMenu()
{
#ifndef QT_NO_CONTEXTMENU
QMenu* menu = d->currentContextMenu.data();
d->currentContextMenu.clear();
return menu;
#else
return 0;
#endif
}
#ifndef QT_NO_WHEELEVENT
template<class T>
void QWebPagePrivate::wheelEvent(T *ev)
{
WebCore::Frame* frame = QWebFramePrivate::core(mainFrame.data());
if (!frame->view())
return;
PlatformWheelEvent pev = convertWheelEvent(ev);
bool accepted = frame->eventHandler()->handleWheelEvent(pev);
ev->setAccepted(accepted);
}
#endif // QT_NO_WHEELEVENT
#ifndef QT_NO_SHORTCUT
QWebPage::WebAction QWebPagePrivate::editorActionForKeyEvent(QKeyEvent* event)
{
static struct {
QKeySequence::StandardKey standardKey;
QWebPage::WebAction action;
} editorActions[] = {
{ QKeySequence::Cut, QWebPage::Cut },
{ QKeySequence::Copy, QWebPage::Copy },
{ QKeySequence::Paste, QWebPage::Paste },
{ QKeySequence::Undo, QWebPage::Undo },
{ QKeySequence::Redo, QWebPage::Redo },
{ QKeySequence::MoveToNextChar, QWebPage::MoveToNextChar },
{ QKeySequence::MoveToPreviousChar, QWebPage::MoveToPreviousChar },
{ QKeySequence::MoveToNextWord, QWebPage::MoveToNextWord },
{ QKeySequence::MoveToPreviousWord, QWebPage::MoveToPreviousWord },
{ QKeySequence::MoveToNextLine, QWebPage::MoveToNextLine },
{ QKeySequence::MoveToPreviousLine, QWebPage::MoveToPreviousLine },
{ QKeySequence::MoveToStartOfLine, QWebPage::MoveToStartOfLine },
{ QKeySequence::MoveToEndOfLine, QWebPage::MoveToEndOfLine },
{ QKeySequence::MoveToStartOfBlock, QWebPage::MoveToStartOfBlock },
{ QKeySequence::MoveToEndOfBlock, QWebPage::MoveToEndOfBlock },
{ QKeySequence::MoveToStartOfDocument, QWebPage::MoveToStartOfDocument },
{ QKeySequence::MoveToEndOfDocument, QWebPage::MoveToEndOfDocument },
{ QKeySequence::SelectNextChar, QWebPage::SelectNextChar },
{ QKeySequence::SelectPreviousChar, QWebPage::SelectPreviousChar },
{ QKeySequence::SelectNextWord, QWebPage::SelectNextWord },
{ QKeySequence::SelectPreviousWord, QWebPage::SelectPreviousWord },
{ QKeySequence::SelectNextLine, QWebPage::SelectNextLine },
{ QKeySequence::SelectPreviousLine, QWebPage::SelectPreviousLine },
{ QKeySequence::SelectStartOfLine, QWebPage::SelectStartOfLine },
{ QKeySequence::SelectEndOfLine, QWebPage::SelectEndOfLine },
{ QKeySequence::SelectStartOfBlock, QWebPage::SelectStartOfBlock },
{ QKeySequence::SelectEndOfBlock, QWebPage::SelectEndOfBlock },
{ QKeySequence::SelectStartOfDocument, QWebPage::SelectStartOfDocument },
{ QKeySequence::SelectEndOfDocument, QWebPage::SelectEndOfDocument },
{ QKeySequence::DeleteStartOfWord, QWebPage::DeleteStartOfWord },
{ QKeySequence::DeleteEndOfWord, QWebPage::DeleteEndOfWord },
{ QKeySequence::InsertParagraphSeparator, QWebPage::InsertParagraphSeparator },
{ QKeySequence::InsertLineSeparator, QWebPage::InsertLineSeparator },
{ QKeySequence::SelectAll, QWebPage::SelectAll },
{ QKeySequence::UnknownKey, QWebPage::NoWebAction }
};
for (int i = 0; editorActions[i].standardKey != QKeySequence::UnknownKey; ++i)
if (event == editorActions[i].standardKey)
return editorActions[i].action;
return QWebPage::NoWebAction;
}
#endif // QT_NO_SHORTCUT
void QWebPagePrivate::keyPressEvent(QKeyEvent *ev)
{
bool handled = false;
WebCore::Frame* frame = page->focusController()->focusedOrMainFrame();
if (!handled)
handled = frame->eventHandler()->keyEvent(ev);
if (!handled) {
handled = true;
if (!handleScrolling(ev, frame)) {
switch (ev->key()) {
case Qt::Key_Back:
q->triggerAction(QWebPage::Back);
break;
case Qt::Key_Forward:
q->triggerAction(QWebPage::Forward);
break;
case Qt::Key_Stop:
q->triggerAction(QWebPage::Stop);
break;
case Qt::Key_Refresh:
q->triggerAction(QWebPage::Reload);
break;
case Qt::Key_Backspace:
if (ev->modifiers() == Qt::ShiftModifier)
q->triggerAction(QWebPage::Forward);
else
q->triggerAction(QWebPage::Back);
break;
default:
handled = false;
break;
}
}
}
ev->setAccepted(handled);
}
void QWebPagePrivate::keyReleaseEvent(QKeyEvent *ev)
{
if (ev->isAutoRepeat()) {
ev->setAccepted(true);
return;
}
WebCore::Frame* frame = page->focusController()->focusedOrMainFrame();
bool handled = frame->eventHandler()->keyEvent(ev);
ev->setAccepted(handled);
}
void QWebPagePrivate::focusInEvent(QFocusEvent*)
{
FocusController *focusController = page->focusController();
focusController->setActive(true);
focusController->setFocused(true);
if (!focusController->focusedFrame())
focusController->setFocusedFrame(QWebFramePrivate::core(mainFrame.data()));
}
void QWebPagePrivate::focusOutEvent(QFocusEvent*)
{
FocusController *focusController = page->focusController();
focusController->setFocused(false);
focusController->setActive(false);
}
template<class T>
void QWebPagePrivate::dragEnterEvent(T* ev)
{
#ifndef QT_NO_DRAGANDDROP
DragData dragData(ev->mimeData(), QPointF(ev->pos()).toPoint(),
QCursor::pos(), dropActionToDragOp(ev->possibleActions()));
Qt::DropAction action = dragOpToDropAction(page->dragController()->dragEntered(&dragData).operation);
ev->setDropAction(action);
ev->acceptProposedAction();
#endif
}
template<class T>
void QWebPagePrivate::dragLeaveEvent(T *ev)
{
#ifndef QT_NO_DRAGANDDROP
DragData dragData(0, IntPoint(), QCursor::pos(), DragOperationNone);
page->dragController()->dragExited(&dragData);
ev->accept();
#endif
}
template<class T>
void QWebPagePrivate::dragMoveEvent(T *ev)
{
#ifndef QT_NO_DRAGANDDROP
DragData dragData(ev->mimeData(), QPointF(ev->pos()).toPoint(),
QCursor::pos(), dropActionToDragOp(ev->possibleActions()));
m_lastDropAction = dragOpToDropAction(page->dragController()->dragUpdated(&dragData).operation);
ev->setDropAction(m_lastDropAction);
if (m_lastDropAction != Qt::IgnoreAction)
ev->accept();
#endif
}
template<class T>
void QWebPagePrivate::dropEvent(T *ev)
{
#ifndef QT_NO_DRAGANDDROP
DragData dragData(ev->mimeData(), QPointF(ev->pos()).toPoint(),
QCursor::pos(), dropActionToDragOp(ev->possibleActions()));
if (page->dragController()->performDrag(&dragData)) {
ev->setDropAction(m_lastDropAction);
ev->accept();
}
#endif
}
void QWebPagePrivate::leaveEvent(QEvent*)
{
QMouseEvent fakeEvent(QEvent::MouseMove, QCursor::pos(), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
mouseMoveEvent(&fakeEvent);
}
void QWebPage::setPalette(const QPalette &pal)
{
d->palette = pal;
if (!d->mainFrame || !d->mainFrame.data()->d->frame->view())
return;
QBrush brush = pal.brush(QPalette::Base);
QColor backgroundColor = brush.style() == Qt::SolidPattern ? brush.color() : QColor();
QWebFramePrivate::core(d->mainFrame.data())->view()->updateBackgroundRecursively(backgroundColor, !backgroundColor.alpha());
}
QPalette QWebPage::palette() const
{
return d->palette;
}
void QWebPagePrivate::inputMethodEvent(QInputMethodEvent *ev)
{
WebCore::Frame *frame = page->focusController()->focusedOrMainFrame();
WebCore::Editor *editor = frame->editor();
if (!editor->canEdit()) {
ev->ignore();
return;
}
Node* node = 0;
if (frame->selection()->rootEditableElement())
node = frame->selection()->rootEditableElement()->shadowAncestorNode();
Vector<CompositionUnderline> underlines;
bool hasSelection = false;
for (int i = 0; i < ev->attributes().size(); ++i) {
const QInputMethodEvent::Attribute& a = ev->attributes().at(i);
switch (a.type) {
case QInputMethodEvent::TextFormat: {
QTextCharFormat textCharFormat = a.value.value<QTextFormat>().toCharFormat();
QColor qcolor = textCharFormat.underlineColor();
underlines.append(CompositionUnderline(qMin(a.start, (a.start + a.length)), qMax(a.start, (a.start + a.length)), Color(makeRGBA(qcolor.red(), qcolor.green(), qcolor.blue(), qcolor.alpha())), false));
break;
}
case QInputMethodEvent::Cursor: {
frame->selection()->setCaretVisible(a.length); if (a.length > 0) {
RenderObject* caretRenderer = frame->selection()->caretRenderer();
if (caretRenderer) {
QColor qcolor = a.value.value<QColor>();
caretRenderer->style()->setColor(Color(makeRGBA(qcolor.red(), qcolor.green(), qcolor.blue(), qcolor.alpha())));
}
}
break;
}
case QInputMethodEvent::Selection: {
hasSelection = true;
if (node) {
if (HTMLTextFormControlElement* textControl = toTextFormControl(node))
textControl->setSelectionRange(qMin(a.start, (a.start + a.length)), qMax(a.start, (a.start + a.length)));
}
if (!ev->preeditString().isEmpty())
editor->setComposition(ev->preeditString(), underlines, qMin(a.start, (a.start + a.length)), qMax(a.start, (a.start + a.length)));
else {
if (editor->hasComposition() && (a.start + a.length == 0))
editor->setComposition(QString(), underlines, 0, 0);
}
break;
}
default:
break;
}
}
if (node && ev->replacementLength() > 0) {
int cursorPos = frame->selection()->extent().offsetInContainerNode();
int start = cursorPos + ev->replacementStart();
if (HTMLTextFormControlElement* textControl = toTextFormControl(node))
textControl->setSelectionRange(start, start + ev->replacementLength());
editor->confirmComposition(ev->commitString());
} else if (!ev->commitString().isEmpty()) {
if (editor->hasComposition())
editor->confirmComposition(ev->commitString());
else
editor->insertText(ev->commitString(), 0);
} else if (!hasSelection && !ev->preeditString().isEmpty())
editor->setComposition(ev->preeditString(), underlines, 0, 0);
else if (ev->preeditString().isEmpty() && editor->hasComposition())
editor->confirmComposition(String());
ev->accept();
}
#ifndef QT_NO_PROPERTIES
typedef struct {
const char* name;
double deferredRepaintDelay;
double initialDeferredRepaintDelayDuringLoading;
double maxDeferredRepaintDelayDuringLoading;
double deferredRepaintDelayIncrementDuringLoading;
} QRepaintThrottlingPreset;
void QWebPagePrivate::dynamicPropertyChangeEvent(QDynamicPropertyChangeEvent* event)
{
if (event->propertyName() == "_q_viewMode") {
page->setViewMode(Page::stringToViewMode(q->property("_q_viewMode").toString()));
} else if (event->propertyName() == "_q_HTMLTokenizerChunkSize") {
int chunkSize = q->property("_q_HTMLTokenizerChunkSize").toInt();
q->handle()->page->setCustomHTMLTokenizerChunkSize(chunkSize);
} else if (event->propertyName() == "_q_HTMLTokenizerTimeDelay") {
double timeDelay = q->property("_q_HTMLTokenizerTimeDelay").toDouble();
q->handle()->page->setCustomHTMLTokenizerTimeDelay(timeDelay);
} else if (event->propertyName() == "_q_RepaintThrottlingDeferredRepaintDelay") {
double p = q->property("_q_RepaintThrottlingDeferredRepaintDelay").toDouble();
FrameView::setRepaintThrottlingDeferredRepaintDelay(p);
} else if (event->propertyName() == "_q_RepaintThrottlingnInitialDeferredRepaintDelayDuringLoading") {
double p = q->property("_q_RepaintThrottlingnInitialDeferredRepaintDelayDuringLoading").toDouble();
FrameView::setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading(p);
} else if (event->propertyName() == "_q_RepaintThrottlingMaxDeferredRepaintDelayDuringLoading") {
double p = q->property("_q_RepaintThrottlingMaxDeferredRepaintDelayDuringLoading").toDouble();
FrameView::setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading(p);
} else if (event->propertyName() == "_q_RepaintThrottlingDeferredRepaintDelayIncrementDuringLoading") {
double p = q->property("_q_RepaintThrottlingDeferredRepaintDelayIncrementDuringLoading").toDouble();
FrameView::setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading(p);
} else if (event->propertyName() == "_q_RepaintThrottlingPreset") {
static const QRepaintThrottlingPreset presets[] = {
{ "NoThrottling", 0, 0, 0, 0 },
{ "Legacy", 0.025, 0, 2.5, 0.5 },
{ "Minimal", 0.01, 0, 1, 0.2 },
{ "Medium", 0.025, 1, 5, 0.5 },
{ "Heavy", 0.1, 2, 10, 1 }
};
QString p = q->property("_q_RepaintThrottlingPreset").toString();
for (size_t i = 0; i < sizeof(presets) / sizeof(presets[0]); i++) {
if (p == QLatin1String(presets[i].name)) {
FrameView::setRepaintThrottlingDeferredRepaintDelay(
presets[i].deferredRepaintDelay);
FrameView::setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading(
presets[i].initialDeferredRepaintDelayDuringLoading);
FrameView::setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading(
presets[i].maxDeferredRepaintDelayDuringLoading);
FrameView::setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading(
presets[i].deferredRepaintDelayIncrementDuringLoading);
break;
}
}
}
else if (event->propertyName() == "_q_webInspectorServerPort") {
InspectorServerQt* inspectorServer = InspectorServerQt::server();
inspectorServer->listen(inspectorServerPort());
} else if (event->propertyName() == "_q_deadDecodedDataDeletionInterval") {
double interval = q->property("_q_deadDecodedDataDeletionInterval").toDouble();
memoryCache()->setDeadDecodedDataDeletionInterval(interval);
}
}
#endif
void QWebPagePrivate::shortcutOverrideEvent(QKeyEvent* event)
{
WebCore::Frame* frame = page->focusController()->focusedOrMainFrame();
WebCore::Editor* editor = frame->editor();
if (editor->canEdit()) {
if (event->modifiers() == Qt::NoModifier
|| event->modifiers() == Qt::ShiftModifier
|| event->modifiers() == Qt::KeypadModifier) {
if (event->key() < Qt::Key_Escape) {
event->accept();
} else {
switch (event->key()) {
case Qt::Key_Return:
case Qt::Key_Enter:
case Qt::Key_Delete:
case Qt::Key_Home:
case Qt::Key_End:
case Qt::Key_Backspace:
case Qt::Key_Left:
case Qt::Key_Right:
case Qt::Key_Up:
case Qt::Key_Down:
case Qt::Key_Tab:
event->accept();
default:
break;
}
}
}
#ifndef QT_NO_SHORTCUT
else if (editorActionForKeyEvent(event) != QWebPage::NoWebAction)
event->accept();
#endif
}
}
bool QWebPagePrivate::handleScrolling(QKeyEvent *ev, Frame *frame)
{
ScrollDirection direction;
ScrollGranularity granularity;
#ifndef QT_NO_SHORTCUT
if (ev == QKeySequence::MoveToNextPage
|| (ev->key() == Qt::Key_Space && !(ev->modifiers() & Qt::ShiftModifier))) {
granularity = ScrollByPage;
direction = ScrollDown;
} else if (ev == QKeySequence::MoveToPreviousPage
|| ((ev->key() == Qt::Key_Space) && (ev->modifiers() & Qt::ShiftModifier))) {
granularity = ScrollByPage;
direction = ScrollUp;
} else
#endif // QT_NO_SHORTCUT
if ((ev->key() == Qt::Key_Up && ev->modifiers() & Qt::ControlModifier)
|| ev->key() == Qt::Key_Home) {
granularity = ScrollByDocument;
direction = ScrollUp;
} else if ((ev->key() == Qt::Key_Down && ev->modifiers() & Qt::ControlModifier)
|| ev->key() == Qt::Key_End) {
granularity = ScrollByDocument;
direction = ScrollDown;
} else {
switch (ev->key()) {
case Qt::Key_Up:
granularity = ScrollByLine;
direction = ScrollUp;
break;
case Qt::Key_Down:
granularity = ScrollByLine;
direction = ScrollDown;
break;
case Qt::Key_Left:
granularity = ScrollByLine;
direction = ScrollLeft;
break;
case Qt::Key_Right:
granularity = ScrollByLine;
direction = ScrollRight;
break;
default:
return false;
}
}
return frame->eventHandler()->scrollRecursively(direction, granularity);
}
void QWebPagePrivate::adjustPointForClicking(QMouseEvent*)
{
notImplemented();
}
#if !defined(QT_NO_GRAPHICSVIEW)
void QWebPagePrivate::adjustPointForClicking(QGraphicsSceneMouseEvent* ev)
{
QtPlatformPlugin platformPlugin;
OwnPtr<QWebTouchModifier> touchModifier = platformPlugin.createTouchModifier();
if (!touchModifier)
return;
unsigned topPadding = touchModifier->hitTestPaddingForTouch(QWebTouchModifier::Up);
unsigned rightPadding = touchModifier->hitTestPaddingForTouch(QWebTouchModifier::Right);
unsigned bottomPadding = touchModifier->hitTestPaddingForTouch(QWebTouchModifier::Down);
unsigned leftPadding = touchModifier->hitTestPaddingForTouch(QWebTouchModifier::Left);
touchModifier = nullptr;
if (!topPadding && !rightPadding && !bottomPadding && !leftPadding)
return;
Document* startingDocument = page->mainFrame()->document();
if (!startingDocument)
return;
IntPoint originalPoint(QPointF(ev->pos()).toPoint());
TouchAdjuster touchAdjuster(topPadding, rightPadding, bottomPadding, leftPadding);
IntPoint adjustedPoint = touchAdjuster.findCandidatePointForTouch(originalPoint, startingDocument);
if (adjustedPoint == IntPoint::zero())
return;
ev->setPos(QPointF(adjustedPoint));
}
#endif
bool QWebPagePrivate::touchEvent(QTouchEvent* event)
{
#if ENABLE(TOUCH_EVENTS)
WebCore::Frame* frame = QWebFramePrivate::core(mainFrame.data());
if (!frame->view())
return false;
event->setAccepted(true);
return frame->eventHandler()->handleTouchEvent(convertTouchEvent(event));
#else
event->ignore();
return false;
#endif
}
QVariant QWebPage::inputMethodQuery(Qt::InputMethodQuery property) const
{
Frame* frame = d->page->focusController()->focusedFrame();
if (!frame)
return QVariant();
WebCore::Editor* editor = frame->editor();
RenderObject* renderer = 0;
RenderTextControl* renderTextControl = 0;
if (frame->selection()->rootEditableElement())
renderer = frame->selection()->rootEditableElement()->shadowAncestorNode()->renderer();
if (renderer && renderer->isTextControl())
renderTextControl = toRenderTextControl(renderer);
switch (property) {
case Qt::ImMicroFocus: {
WebCore::FrameView* view = frame->view();
if (view && view->needsLayout()) {
return QVariant();
}
return QVariant(view->contentsToWindow(frame->selection()->absoluteCaretBounds()));
}
case Qt::ImFont: {
if (renderTextControl) {
RenderStyle* renderStyle = renderTextControl->style();
return QVariant(QFont(renderStyle->font().syntheticFont()));
}
return QVariant(QFont());
}
case Qt::ImCursorPosition: {
if (editor->hasComposition())
return QVariant(frame->selection()->end().offsetInContainerNode());
return QVariant(frame->selection()->extent().offsetInContainerNode());
}
case Qt::ImSurroundingText: {
if (renderTextControl && renderTextControl->textFormControlElement()) {
QString text = renderTextControl->textFormControlElement()->value();
RefPtr<Range> range = editor->compositionRange();
if (range)
text.remove(range->startPosition().offsetInContainerNode(), TextIterator::rangeLength(range.get()));
return QVariant(text);
}
return QVariant();
}
case Qt::ImCurrentSelection: {
if (!editor->hasComposition() && renderTextControl && renderTextControl->textFormControlElement()) {
int start = frame->selection()->start().offsetInContainerNode();
int end = frame->selection()->end().offsetInContainerNode();
if (end > start)
return QVariant(QString(renderTextControl->textFormControlElement()->value()).mid(start, end - start));
}
return QVariant();
}
case Qt::ImAnchorPosition: {
if (editor->hasComposition())
return QVariant(frame->selection()->start().offsetInContainerNode());
return QVariant(frame->selection()->base().offsetInContainerNode());
}
case Qt::ImMaximumTextLength: {
if (frame->selection()->isContentEditable()) {
if (frame->document() && frame->document()->focusedNode()) {
if (frame->document()->focusedNode()->hasTagName(HTMLNames::inputTag)) {
HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(frame->document()->focusedNode());
return QVariant(inputElement->maxLength());
}
}
return QVariant(HTMLInputElement::maximumLength);
}
return QVariant(0);
}
default:
return QVariant();
}
}
void QWebPagePrivate::setInspector(QWebInspector* insp)
{
if (inspector)
inspector->d->setFrontend(0);
if (inspectorIsInternalOnly) {
QWebInspector* inspToDelete = inspector;
inspector = 0;
inspectorIsInternalOnly = false;
delete inspToDelete; }
inspector = insp;
if (inspector && inspectorFrontend)
inspector->d->setFrontend(inspectorFrontend);
}
QWebInspector* QWebPagePrivate::getOrCreateInspector()
{
#if ENABLE(INSPECTOR)
if (!inspector) {
QWebInspector* insp = new QWebInspector;
insp->setPage(q);
inspectorIsInternalOnly = true;
Q_ASSERT(inspector); }
#endif
return inspector;
}
InspectorController* QWebPagePrivate::inspectorController()
{
#if ENABLE(INSPECTOR)
return page->inspectorController();
#else
return 0;
#endif
}
quint16 QWebPagePrivate::inspectorServerPort()
{
#if ENABLE(INSPECTOR) && !defined(QT_NO_PROPERTIES)
if (q && q->property("_q_webInspectorServerPort").isValid())
return q->property("_q_webInspectorServerPort").toInt();
#endif
return 0;
}
static bool hasMouseListener(Element* element)
{
ASSERT(element);
return element->hasEventListeners(eventNames().clickEvent)
|| element->hasEventListeners(eventNames().mousedownEvent)
|| element->hasEventListeners(eventNames().mouseupEvent);
}
static bool isClickableElement(Element* element, RefPtr<NodeList> list)
{
ASSERT(element);
bool isClickable = hasMouseListener(element);
if (!isClickable && list) {
Element* parent = element->parentElement();
unsigned count = list->length();
for (unsigned i = 0; i < count && parent; i++) {
if (list->item(i) != parent)
continue;
isClickable = hasMouseListener(parent);
if (isClickable)
break;
parent = parent->parentElement();
}
}
ExceptionCode ec = 0;
return isClickable
|| element->webkitMatchesSelector("a,*:link,*:visited,*[role=button],button,input,select,label", ec)
|| CSSComputedStyleDeclaration::create(element)->getPropertyValue(cssPropertyID("cursor")) == "pointer";
}
static bool isValidFrameOwner(Element* element)
{
ASSERT(element);
return element->isFrameOwnerElement() && static_cast<HTMLFrameOwnerElement*>(element)->contentFrame();
}
static Element* nodeToElement(Node* node)
{
if (node && node->isElementNode())
return static_cast<Element*>(node);
return 0;
}
QWebPagePrivate::TouchAdjuster::TouchAdjuster(unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding)
: m_topPadding(topPadding)
, m_rightPadding(rightPadding)
, m_bottomPadding(bottomPadding)
, m_leftPadding(leftPadding)
{
}
IntPoint QWebPagePrivate::TouchAdjuster::findCandidatePointForTouch(const IntPoint& touchPoint, Document* document) const
{
if (!document)
return IntPoint();
int x = touchPoint.x();
int y = touchPoint.y();
RefPtr<NodeList> intersectedNodes = document->nodesFromRect(x, y, m_topPadding, m_rightPadding, m_bottomPadding, m_leftPadding, false , false );
if (!intersectedNodes)
return IntPoint();
Element* closestClickableElement = 0;
IntRect largestIntersectionRect;
FrameView* view = document->frame()->view();
IntRect touchRect(HitTestResult::rectForPoint(view->windowToContents(IntPoint(x, y)), m_topPadding, m_rightPadding, m_bottomPadding, m_leftPadding));
for (unsigned i = 0; i < intersectedNodes->length(); i++) {
Node* currentNode = intersectedNodes->item(i);
Element* currentElement = nodeToElement(currentNode);
if (!currentElement || (!isClickableElement(currentElement, 0) && !isValidFrameOwner(currentElement)))
continue;
IntRect currentElementBoundingRect = currentElement->getPixelSnappedRect();
currentElementBoundingRect.intersect(touchRect);
if (currentElementBoundingRect.isEmpty())
continue;
int currentIntersectionRectArea = currentElementBoundingRect.width() * currentElementBoundingRect.height();
int largestIntersectionRectArea = largestIntersectionRect.width() * largestIntersectionRect.height();
if (currentIntersectionRectArea > largestIntersectionRectArea) {
closestClickableElement = currentElement;
largestIntersectionRect = currentElementBoundingRect;
}
}
if (largestIntersectionRect.isEmpty())
return IntPoint();
if (closestClickableElement->isFrameOwnerElement()) {
PassRefPtr<ClientRect> rect = closestClickableElement->getBoundingClientRect();
IntPoint newTouchPoint = touchPoint;
IntSize offset = IntSize(rect->left(), rect->top());
newTouchPoint -= offset;
HTMLFrameOwnerElement* owner = static_cast<HTMLFrameOwnerElement*>(closestClickableElement);
Document* childDocument = owner->contentFrame()->document();
return findCandidatePointForTouch(newTouchPoint, childDocument);
}
return view->contentsToWindow(largestIntersectionRect).center();
}
QWebPage::ViewportAttributes::ViewportAttributes()
: d(0)
, m_initialScaleFactor(-1.0)
, m_minimumScaleFactor(-1.0)
, m_maximumScaleFactor(-1.0)
, m_devicePixelRatio(-1.0)
, m_isUserScalable(true)
, m_isValid(false)
{
}
QWebPage::ViewportAttributes::ViewportAttributes(const QWebPage::ViewportAttributes& other)
: d(other.d)
, m_initialScaleFactor(other.m_initialScaleFactor)
, m_minimumScaleFactor(other.m_minimumScaleFactor)
, m_maximumScaleFactor(other.m_maximumScaleFactor)
, m_devicePixelRatio(other.m_devicePixelRatio)
, m_isUserScalable(other.m_isUserScalable)
, m_isValid(other.m_isValid)
, m_size(other.m_size)
{
}
QWebPage::ViewportAttributes::~ViewportAttributes()
{
}
QWebPage::ViewportAttributes& QWebPage::ViewportAttributes::operator=(const QWebPage::ViewportAttributes& other)
{
if (this != &other) {
d = other.d;
m_initialScaleFactor = other.m_initialScaleFactor;
m_minimumScaleFactor = other.m_minimumScaleFactor;
m_maximumScaleFactor = other.m_maximumScaleFactor;
m_isUserScalable = other.m_isUserScalable;
m_isValid = other.m_isValid;
m_size = other.m_size;
}
return *this;
}
QWebPage::QWebPage(QObject *parent)
: QObject(parent)
, d(new QWebPagePrivate(this))
{
setView(qobject_cast<QWidget*>(parent));
connect(this, SIGNAL(loadProgress(int)), this, SLOT(_q_onLoadProgressChanged(int)));
#ifndef NDEBUG
connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(_q_cleanupLeakMessages()));
#endif
}
QWebPage::~QWebPage()
{
d->createMainFrame();
FrameLoader* loader = d->mainFrame.data()->d->frame->loader();
if (loader)
loader->detachFromParent();
delete d;
}
QWebFrame *QWebPage::mainFrame() const
{
d->createMainFrame();
return d->mainFrame.data();
}
QWebFrame *QWebPage::currentFrame() const
{
d->createMainFrame();
WebCore::Frame *frame = d->page->focusController()->focusedOrMainFrame();
return qobject_cast<QWebFrame*>(frame->loader()->networkingContext()->originatingObject());
}
QWebFrame* QWebPage::frameAt(const QPoint& pos) const
{
QWebFrame* webFrame = mainFrame();
if (!webFrame->geometry().contains(pos))
return 0;
QWebHitTestResult hitTestResult = webFrame->hitTestContent(pos);
return hitTestResult.frame();
}
QWebHistory *QWebPage::history() const
{
d->createMainFrame();
return &d->history;
}
void QWebPage::setView(QWidget* view)
{
if (this->view() == view)
return;
d->view = view;
setViewportSize(view ? view->size() : QSize(0, 0));
if (d->client) {
if (d->client->isQWidgetClient())
static_cast<PageClientQWidget*>(d->client.get())->view = view;
return;
}
if (view)
d->client = adoptPtr(new PageClientQWidget(view, this));
}
QWidget *QWebPage::view() const
{
return d->view.data();
}
void QWebPage::javaScriptConsoleMessage(const QString& message, int lineNumber, const QString& sourceID)
{
Q_UNUSED(sourceID)
if (QWebPagePrivate::drtRun) {
if (message == QLatin1String("PLUGIN: NPP_Destroy")) {
fprintf(stdout, "CONSOLE MESSAGE: ");
if (lineNumber)
fprintf(stdout, "line %d: ", lineNumber);
fprintf(stdout, "%s\n", message.toUtf8().constData());
}
}
}
void QWebPage::javaScriptAlert(QWebFrame *frame, const QString& msg)
{
Q_UNUSED(frame)
#ifndef QT_NO_MESSAGEBOX
QWidget* parent = (d->client) ? d->client->ownerWidget() : 0;
QMessageBox::information(parent, tr("JavaScript Alert - %1").arg(mainFrame()->url().host()), escapeHtml(msg), QMessageBox::Ok);
#endif
}
bool QWebPage::javaScriptConfirm(QWebFrame *frame, const QString& msg)
{
Q_UNUSED(frame)
#ifdef QT_NO_MESSAGEBOX
return true;
#else
QWidget* parent = (d->client) ? d->client->ownerWidget() : 0;
return QMessageBox::Yes == QMessageBox::information(parent, tr("JavaScript Confirm - %1").arg(mainFrame()->url().host()), escapeHtml(msg), QMessageBox::Yes, QMessageBox::No);
#endif
}
bool QWebPage::javaScriptPrompt(QWebFrame *frame, const QString& msg, const QString& defaultValue, QString* result)
{
Q_UNUSED(frame)
bool ok = false;
#ifndef QT_NO_INPUTDIALOG
QWidget* parent = (d->client) ? d->client->ownerWidget() : 0;
QString x = QInputDialog::getText(parent, tr("JavaScript Prompt - %1").arg(mainFrame()->url().host()), escapeHtml(msg), QLineEdit::Normal, defaultValue, &ok);
if (ok && result)
*result = x;
#endif
return ok;
}
bool QWebPage::shouldInterruptJavaScript()
{
#ifdef QT_NO_MESSAGEBOX
return false;
#else
QWidget* parent = (d->client) ? d->client->ownerWidget() : 0;
return QMessageBox::Yes == QMessageBox::information(parent, tr("JavaScript Problem - %1").arg(mainFrame()->url().host()), tr("The script on this page appears to have a problem. Do you want to stop the script?"), QMessageBox::Yes, QMessageBox::No);
#endif
}
void QWebPage::setFeaturePermission(QWebFrame* frame, Feature feature, PermissionPolicy policy)
{
switch (feature) {
case Notifications:
#if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
if (policy == PermissionGrantedByUser)
NotificationPresenterClientQt::notificationPresenter()->allowNotificationForFrame(frame->d->frame);
#endif
break;
case Geolocation:
#if ENABLE(GEOLOCATION)
GeolocationPermissionClientQt::geolocationPermissionClient()->setPermission(frame, policy);
#endif
break;
default:
break;
}
}
QWebPage *QWebPage::createWindow(WebWindowType type)
{
QWebView *webView = qobject_cast<QWebView*>(view());
if (webView) {
QWebView *newView = webView->createWindow(type);
if (newView)
return newView->page();
}
return 0;
}
QObject *QWebPage::createPlugin(const QString &classid, const QUrl &url, const QStringList ¶mNames, const QStringList ¶mValues)
{
Q_UNUSED(classid)
Q_UNUSED(url)
Q_UNUSED(paramNames)
Q_UNUSED(paramValues)
return 0;
}
static void extractContentTypeFromHash(const HashSet<String>& types, QStringList* list)
{
if (!list)
return;
HashSet<String>::const_iterator endIt = types.end();
for (HashSet<String>::const_iterator it = types.begin(); it != endIt; ++it)
*list << *it;
}
static void extractContentTypeFromPluginVector(const Vector<PluginPackage*>& plugins, QStringList* list)
{
if (!list)
return;
for (unsigned int i = 0; i < plugins.size(); ++i) {
MIMEToDescriptionsMap::const_iterator map_it = plugins[i]->mimeToDescriptions().begin();
MIMEToDescriptionsMap::const_iterator map_end = plugins[i]->mimeToDescriptions().end();
for (; map_it != map_end; ++map_it)
*list << map_it->first;
}
}
QStringList QWebPage::supportedContentTypes() const
{
QStringList mimeTypes;
extractContentTypeFromHash(MIMETypeRegistry::getSupportedImageMIMETypes(), &mimeTypes);
extractContentTypeFromHash(MIMETypeRegistry::getSupportedNonImageMIMETypes(), &mimeTypes);
if (d->page->settings() && d->page->settings()->arePluginsEnabled())
extractContentTypeFromPluginVector(PluginDatabase::installedPlugins()->plugins(), &mimeTypes);
return mimeTypes;
}
bool QWebPage::supportsContentType(const QString& mimeType) const
{
const String type = mimeType.toLower();
if (MIMETypeRegistry::isSupportedImageMIMEType(type))
return true;
if (MIMETypeRegistry::isSupportedNonImageMIMEType(type))
return true;
if (d->page->settings() && d->page->settings()->arePluginsEnabled()
&& PluginDatabase::installedPlugins()->isMIMETypeRegistered(type))
return true;
return false;
}
static WebCore::FrameLoadRequest frameLoadRequest(const QUrl &url, WebCore::Frame *frame)
{
return WebCore::FrameLoadRequest(frame->document()->securityOrigin(),
WebCore::ResourceRequest(url, frame->loader()->outgoingReferrer()));
}
static void openNewWindow(const QUrl& url, WebCore::Frame* frame)
{
if (Page* oldPage = frame->page()) {
WindowFeatures features;
NavigationAction action;
FrameLoadRequest request = frameLoadRequest(url, frame);
if (Page* newPage = oldPage->chrome()->createWindow(frame, request, features, action)) {
newPage->mainFrame()->loader()->loadFrameRequest(request, false, false, 0, 0, MaybeSendReferrer);
newPage->chrome()->show();
}
}
}
static void collectChildFrames(QWebFrame* frame, QList<QWebFrame*>& list)
{
list << frame->childFrames();
QListIterator<QWebFrame*> it(frame->childFrames());
while (it.hasNext()) {
collectChildFrames(it.next(), list);
}
}
void QWebPage::triggerAction(WebAction action, bool)
{
WebCore::Frame *frame = d->page->focusController()->focusedOrMainFrame();
if (!frame)
return;
WebCore::Editor *editor = frame->editor();
const char *command = 0;
switch (action) {
case OpenLink:
if (QWebFrame *targetFrame = d->hitTestResult.linkTargetFrame()) {
WTF::RefPtr<WebCore::Frame> wcFrame = targetFrame->d->frame;
targetFrame->d->frame->loader()->loadFrameRequest(frameLoadRequest(d->hitTestResult.linkUrl(), wcFrame.get()),
false, false, 0,
0, MaybeSendReferrer);
break;
}
case OpenLinkInNewWindow:
openNewWindow(d->hitTestResult.linkUrl(), frame);
break;
case OpenFrameInNewWindow: {
KURL url = frame->loader()->documentLoader()->unreachableURL();
if (url.isEmpty())
url = frame->loader()->documentLoader()->url();
openNewWindow(url, frame);
break;
}
case CopyLinkToClipboard: {
#if defined(Q_WS_X11)
bool oldSelectionMode = Pasteboard::generalPasteboard()->isSelectionMode();
Pasteboard::generalPasteboard()->setSelectionMode(true);
editor->copyURL(d->hitTestResult.linkUrl(), d->hitTestResult.linkText());
Pasteboard::generalPasteboard()->setSelectionMode(oldSelectionMode);
#endif
editor->copyURL(d->hitTestResult.linkUrl(), d->hitTestResult.linkText());
break;
}
case OpenImageInNewWindow:
openNewWindow(d->hitTestResult.imageUrl(), frame);
break;
case DownloadImageToDisk:
frame->loader()->client()->startDownload(WebCore::ResourceRequest(d->hitTestResult.imageUrl(), frame->loader()->outgoingReferrer()));
break;
case DownloadLinkToDisk:
frame->loader()->client()->startDownload(WebCore::ResourceRequest(d->hitTestResult.linkUrl(), frame->loader()->outgoingReferrer()));
break;
#ifndef QT_NO_CLIPBOARD
case CopyImageToClipboard:
QApplication::clipboard()->setPixmap(d->hitTestResult.pixmap());
break;
case CopyImageUrlToClipboard:
QApplication::clipboard()->setText(d->hitTestResult.imageUrl().toString());
break;
#endif
case Back:
d->page->goBack();
break;
case Forward:
d->page->goForward();
break;
case Stop:
mainFrame()->d->frame->loader()->stopForUserCancel();
d->updateNavigationActions();
break;
case Reload:
mainFrame()->d->frame->loader()->reload(false);
break;
case ReloadAndBypassCache:
mainFrame()->d->frame->loader()->reload(true);
break;
case SetTextDirectionDefault:
editor->setBaseWritingDirection(NaturalWritingDirection);
break;
case SetTextDirectionLeftToRight:
editor->setBaseWritingDirection(LeftToRightWritingDirection);
break;
case SetTextDirectionRightToLeft:
editor->setBaseWritingDirection(RightToLeftWritingDirection);
break;
case InspectElement: {
#if ENABLE(INSPECTOR)
if (!d->hitTestResult.isNull()) {
d->getOrCreateInspector(); d->inspector->show(); d->page->inspectorController()->inspect(d->hitTestResult.d->innerNonSharedNode.get());
}
#endif
break;
}
case StopScheduledPageRefresh: {
QWebFrame* topFrame = mainFrame();
topFrame->d->frame->navigationScheduler()->cancel();
QList<QWebFrame*> childFrames;
collectChildFrames(topFrame, childFrames);
QListIterator<QWebFrame*> it(childFrames);
while (it.hasNext())
it.next()->d->frame->navigationScheduler()->cancel();
break;
}
default:
command = QWebPagePrivate::editorCommandForWebActions(action);
break;
}
if (command)
editor->command(command).execute();
}
QSize QWebPage::viewportSize() const
{
if (d->mainFrame && d->mainFrame.data()->d->frame->view())
return d->mainFrame.data()->d->frame->view()->frameRect().size();
return d->viewportSize;
}
void QWebPage::setViewportSize(const QSize &size) const
{
d->viewportSize = size;
QWebFrame *frame = mainFrame();
if (frame->d->frame && frame->d->frame->view()) {
WebCore::FrameView* view = frame->d->frame->view();
view->resize(size);
view->adjustViewSize();
}
}
static int getintenv(const char* variable)
{
bool ok;
int value = qgetenv(variable).toInt(&ok);
return (ok) ? value : -1;
}
static QSize queryDeviceSizeForScreenContainingWidget(const QWidget* widget)
{
QDesktopWidget* desktop = QApplication::desktop();
if (!desktop)
return QSize();
QSize size;
if (widget) {
size = desktop->availableGeometry(widget).size();
} else
size = desktop->availableGeometry().size();
if (size.width() > size.height()) {
int width = size.width();
size.setWidth(size.height());
size.setHeight(width);
}
return size;
}
QWebPage::ViewportAttributes QWebPage::viewportAttributesForSize(const QSize& availableSize) const
{
static int desktopWidth = 980;
ViewportAttributes result;
if (availableSize.isEmpty())
return result;
int deviceWidth = getintenv("QTWEBKIT_DEVICE_WIDTH");
int deviceHeight = getintenv("QTWEBKIT_DEVICE_HEIGHT");
if (deviceWidth < 0 && deviceHeight < 0) {
QSize size = queryDeviceSizeForScreenContainingWidget((d->client) ? d->client->ownerWidget() : 0);
deviceWidth = size.width();
deviceHeight = size.height();
}
WebCore::ViewportAttributes conf = WebCore::computeViewportAttributes(d->viewportArguments(), desktopWidth, deviceWidth, deviceHeight, qt_defaultDpi(), availableSize);
WebCore::restrictMinimumScaleFactorToViewportSize(conf, availableSize);
WebCore::restrictScaleFactorToInitialScaleIfNotUserScalable(conf);
result.m_isValid = true;
result.m_size = QSizeF(conf.layoutSize.width(), conf.layoutSize.height());
result.m_initialScaleFactor = conf.initialScale;
result.m_minimumScaleFactor = conf.minimumScale;
result.m_maximumScaleFactor = conf.maximumScale;
result.m_devicePixelRatio = conf.devicePixelRatio;
result.m_isUserScalable = static_cast<bool>(conf.userScalable);
d->page->setDeviceScaleFactor(conf.devicePixelRatio);
return result;
}
QSize QWebPage::preferredContentsSize() const
{
QWebFrame* frame = d->mainFrame.data();
if (frame) {
WebCore::FrameView* view = frame->d->frame->view();
if (view && view->useFixedLayout())
return d->mainFrame.data()->d->frame->view()->fixedLayoutSize();
}
return d->fixedLayoutSize;
}
void QWebPage::setPreferredContentsSize(const QSize& size) const
{
d->fixedLayoutSize = size;
QWebFrame* frame = mainFrame();
if (!frame->d->frame || !frame->d->frame->view())
return;
WebCore::FrameView* view = frame->d->frame->view();
if (size.isValid()) {
view->setUseFixedLayout(true);
view->setFixedLayoutSize(size);
} else if (view->useFixedLayout())
view->setUseFixedLayout(false);
view->layout();
}
void QWebPage::setActualVisibleContentRect(const QRect& rect) const
{
QWebFrame* frame = mainFrame();
if (!frame->d->frame || !frame->d->frame->view())
return;
WebCore::FrameView* view = frame->d->frame->view();
view->setFixedVisibleContentRect(rect);
}
bool QWebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type)
{
Q_UNUSED(frame)
if (type == NavigationTypeLinkClicked) {
switch (d->linkPolicy) {
case DontDelegateLinks:
return true;
case DelegateExternalLinks:
if (WebCore::SchemeRegistry::shouldTreatURLSchemeAsLocal(request.url().scheme()))
return true;
emit linkClicked(request.url());
return false;
case DelegateAllLinks:
emit linkClicked(request.url());
return false;
}
}
return true;
}
bool QWebPage::hasSelection() const
{
d->createMainFrame();
WebCore::Frame* frame = d->page->focusController()->focusedOrMainFrame();
if (frame)
return (frame->selection()->selection().selectionType() != VisibleSelection::NoSelection);
return false;
}
QString QWebPage::selectedText() const
{
d->createMainFrame();
WebCore::Frame* frame = d->page->focusController()->focusedOrMainFrame();
if (frame->selection()->selection().selectionType() == VisibleSelection::NoSelection)
return QString();
return frame->editor()->selectedText();
}
QString QWebPage::selectedHtml() const
{
d->createMainFrame();
return d->page->focusController()->focusedOrMainFrame()->editor()->selectedRange()->toHTML();
}
#ifndef QT_NO_ACTION
QAction *QWebPage::action(WebAction action) const
{
if (action == QWebPage::NoWebAction) return 0;
if (d->actions[action])
return d->actions[action];
QString text;
QIcon icon;
QStyle *style = d->client ? d->client->style() : qApp->style();
bool checkable = false;
switch (action) {
case OpenLink:
text = contextMenuItemTagOpenLink();
break;
case OpenLinkInNewWindow:
text = contextMenuItemTagOpenLinkInNewWindow();
break;
case OpenFrameInNewWindow:
text = contextMenuItemTagOpenFrameInNewWindow();
break;
case DownloadLinkToDisk:
text = contextMenuItemTagDownloadLinkToDisk();
break;
case CopyLinkToClipboard:
text = contextMenuItemTagCopyLinkToClipboard();
break;
case OpenImageInNewWindow:
text = contextMenuItemTagOpenImageInNewWindow();
break;
case DownloadImageToDisk:
text = contextMenuItemTagDownloadImageToDisk();
break;
case CopyImageToClipboard:
text = contextMenuItemTagCopyImageToClipboard();
break;
case CopyImageUrlToClipboard:
text = contextMenuItemTagCopyImageUrlToClipboard();
break;
case Back:
text = contextMenuItemTagGoBack();
icon = style->standardIcon(QStyle::SP_ArrowBack);
break;
case Forward:
text = contextMenuItemTagGoForward();
icon = style->standardIcon(QStyle::SP_ArrowForward);
break;
case Stop:
text = contextMenuItemTagStop();
icon = style->standardIcon(QStyle::SP_BrowserStop);
break;
case Reload:
text = contextMenuItemTagReload();
icon = style->standardIcon(QStyle::SP_BrowserReload);
break;
case Cut:
text = contextMenuItemTagCut();
break;
case Copy:
text = contextMenuItemTagCopy();
break;
case Paste:
text = contextMenuItemTagPaste();
break;
case SelectAll:
text = contextMenuItemTagSelectAll();
break;
#ifndef QT_NO_UNDOSTACK
case Undo: {
QAction *a = undoStack()->createUndoAction(d->q);
d->actions[action] = a;
return a;
}
case Redo: {
QAction *a = undoStack()->createRedoAction(d->q);
d->actions[action] = a;
return a;
}
#endif // QT_NO_UNDOSTACK
case MoveToNextChar:
text = tr("Move the cursor to the next character");
break;
case MoveToPreviousChar:
text = tr("Move the cursor to the previous character");
break;
case MoveToNextWord:
text = tr("Move the cursor to the next word");
break;
case MoveToPreviousWord:
text = tr("Move the cursor to the previous word");
break;
case MoveToNextLine:
text = tr("Move the cursor to the next line");
break;
case MoveToPreviousLine:
text = tr("Move the cursor to the previous line");
break;
case MoveToStartOfLine:
text = tr("Move the cursor to the start of the line");
break;
case MoveToEndOfLine:
text = tr("Move the cursor to the end of the line");
break;
case MoveToStartOfBlock:
text = tr("Move the cursor to the start of the block");
break;
case MoveToEndOfBlock:
text = tr("Move the cursor to the end of the block");
break;
case MoveToStartOfDocument:
text = tr("Move the cursor to the start of the document");
break;
case MoveToEndOfDocument:
text = tr("Move the cursor to the end of the document");
break;
case SelectNextChar:
text = tr("Select to the next character");
break;
case SelectPreviousChar:
text = tr("Select to the previous character");
break;
case SelectNextWord:
text = tr("Select to the next word");
break;
case SelectPreviousWord:
text = tr("Select to the previous word");
break;
case SelectNextLine:
text = tr("Select to the next line");
break;
case SelectPreviousLine:
text = tr("Select to the previous line");
break;
case SelectStartOfLine:
text = tr("Select to the start of the line");
break;
case SelectEndOfLine:
text = tr("Select to the end of the line");
break;
case SelectStartOfBlock:
text = tr("Select to the start of the block");
break;
case SelectEndOfBlock:
text = tr("Select to the end of the block");
break;
case SelectStartOfDocument:
text = tr("Select to the start of the document");
break;
case SelectEndOfDocument:
text = tr("Select to the end of the document");
break;
case DeleteStartOfWord:
text = tr("Delete to the start of the word");
break;
case DeleteEndOfWord:
text = tr("Delete to the end of the word");
break;
case SetTextDirectionDefault:
text = contextMenuItemTagDefaultDirection();
break;
case SetTextDirectionLeftToRight:
text = contextMenuItemTagLeftToRight();
checkable = true;
break;
case SetTextDirectionRightToLeft:
text = contextMenuItemTagRightToLeft();
checkable = true;
break;
case ToggleBold:
text = contextMenuItemTagBold();
checkable = true;
break;
case ToggleItalic:
text = contextMenuItemTagItalic();
checkable = true;
break;
case ToggleUnderline:
text = contextMenuItemTagUnderline();
checkable = true;
break;
case InspectElement:
text = contextMenuItemTagInspectElement();
break;
case InsertParagraphSeparator:
text = tr("Insert a new paragraph");
break;
case InsertLineSeparator:
text = tr("Insert a new line");
break;
case PasteAndMatchStyle:
text = tr("Paste and Match Style");
break;
case RemoveFormat:
text = tr("Remove formatting");
break;
case ToggleStrikethrough:
text = tr("Strikethrough");
checkable = true;
break;
case ToggleSubscript:
text = tr("Subscript");
checkable = true;
break;
case ToggleSuperscript:
text = tr("Superscript");
checkable = true;
break;
case InsertUnorderedList:
text = tr("Insert Bulleted List");
checkable = true;
break;
case InsertOrderedList:
text = tr("Insert Numbered List");
checkable = true;
break;
case Indent:
text = tr("Indent");
break;
case Outdent:
text = tr("Outdent");
break;
case AlignCenter:
text = tr("Center");
break;
case AlignJustified:
text = tr("Justify");
break;
case AlignLeft:
text = tr("Align Left");
break;
case AlignRight:
text = tr("Align Right");
break;
case NoWebAction:
return 0;
default:
break;
}
if (text.isEmpty())
return 0;
QAction *a = new QAction(d->q);
a->setText(text);
a->setData(action);
a->setCheckable(checkable);
a->setIcon(icon);
connect(a, SIGNAL(triggered(bool)),
this, SLOT(_q_webActionTriggered(bool)));
d->actions[action] = a;
d->updateAction(action);
return a;
}
#endif // QT_NO_ACTION
bool QWebPage::isModified() const
{
#ifdef QT_NO_UNDOSTACK
return false;
#else
if (!d->undoStack)
return false;
return d->undoStack->canUndo();
#endif // QT_NO_UNDOSTACK
}
#ifndef QT_NO_UNDOSTACK
QUndoStack *QWebPage::undoStack() const
{
if (!d->undoStack)
d->undoStack = new QUndoStack(const_cast<QWebPage *>(this));
return d->undoStack;
}
#endif // QT_NO_UNDOSTACK
bool QWebPage::event(QEvent *ev)
{
switch (ev->type()) {
case QEvent::Timer:
d->timerEvent(static_cast<QTimerEvent*>(ev));
break;
case QEvent::MouseMove:
d->mouseMoveEvent(static_cast<QMouseEvent*>(ev));
break;
case QEvent::MouseButtonPress:
d->mousePressEvent(static_cast<QMouseEvent*>(ev));
break;
case QEvent::MouseButtonDblClick:
d->mouseDoubleClickEvent(static_cast<QMouseEvent*>(ev));
break;
case QEvent::MouseButtonRelease:
d->mouseReleaseEvent(static_cast<QMouseEvent*>(ev));
break;
#if !defined(QT_NO_GRAPHICSVIEW)
case QEvent::GraphicsSceneMouseMove:
d->mouseMoveEvent(static_cast<QGraphicsSceneMouseEvent*>(ev));
break;
case QEvent::GraphicsSceneMousePress:
d->mousePressEvent(static_cast<QGraphicsSceneMouseEvent*>(ev));
break;
case QEvent::GraphicsSceneMouseDoubleClick:
d->mouseDoubleClickEvent(static_cast<QGraphicsSceneMouseEvent*>(ev));
break;
case QEvent::GraphicsSceneMouseRelease:
d->mouseReleaseEvent(static_cast<QGraphicsSceneMouseEvent*>(ev));
break;
#endif
#ifndef QT_NO_CONTEXTMENU
case QEvent::ContextMenu:
d->contextMenuEvent(static_cast<QContextMenuEvent*>(ev)->globalPos());
break;
#if !defined(QT_NO_GRAPHICSVIEW)
case QEvent::GraphicsSceneContextMenu:
d->contextMenuEvent(static_cast<QGraphicsSceneContextMenuEvent*>(ev)->screenPos());
break;
#endif
#endif
#ifndef QT_NO_WHEELEVENT
case QEvent::Wheel:
d->wheelEvent(static_cast<QWheelEvent*>(ev));
break;
#if !defined(QT_NO_GRAPHICSVIEW)
case QEvent::GraphicsSceneWheel:
d->wheelEvent(static_cast<QGraphicsSceneWheelEvent*>(ev));
break;
#endif
#endif
case QEvent::KeyPress:
d->keyPressEvent(static_cast<QKeyEvent*>(ev));
break;
case QEvent::KeyRelease:
d->keyReleaseEvent(static_cast<QKeyEvent*>(ev));
break;
case QEvent::FocusIn:
d->focusInEvent(static_cast<QFocusEvent*>(ev));
break;
case QEvent::FocusOut:
d->focusOutEvent(static_cast<QFocusEvent*>(ev));
break;
#ifndef QT_NO_DRAGANDDROP
case QEvent::DragEnter:
d->dragEnterEvent(static_cast<QDragEnterEvent*>(ev));
break;
case QEvent::DragLeave:
d->dragLeaveEvent(static_cast<QDragLeaveEvent*>(ev));
break;
case QEvent::DragMove:
d->dragMoveEvent(static_cast<QDragMoveEvent*>(ev));
break;
case QEvent::Drop:
d->dropEvent(static_cast<QDropEvent*>(ev));
break;
#if !defined(QT_NO_GRAPHICSVIEW)
case QEvent::GraphicsSceneDragEnter:
d->dragEnterEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev));
break;
case QEvent::GraphicsSceneDragMove:
d->dragMoveEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev));
break;
case QEvent::GraphicsSceneDragLeave:
d->dragLeaveEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev));
break;
case QEvent::GraphicsSceneDrop:
d->dropEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev));
break;
#endif
#endif
case QEvent::InputMethod:
d->inputMethodEvent(static_cast<QInputMethodEvent*>(ev));
break;
case QEvent::ShortcutOverride:
d->shortcutOverrideEvent(static_cast<QKeyEvent*>(ev));
break;
case QEvent::Leave:
d->leaveEvent(ev);
break;
case QEvent::TouchBegin:
case QEvent::TouchUpdate:
case QEvent::TouchEnd:
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
case QEvent::TouchCancel:
#endif
return d->touchEvent(static_cast<QTouchEvent*>(ev));
#ifndef QT_NO_PROPERTIES
case QEvent::DynamicPropertyChange:
d->dynamicPropertyChangeEvent(static_cast<QDynamicPropertyChangeEvent*>(ev));
break;
#endif
default:
return QObject::event(ev);
}
return true;
}
bool QWebPage::focusNextPrevChild(bool next)
{
QKeyEvent ev(QEvent::KeyPress, Qt::Key_Tab, Qt::KeyboardModifiers(next ? Qt::NoModifier : Qt::ShiftModifier));
d->keyPressEvent(&ev);
bool hasFocusedNode = false;
Frame *frame = d->page->focusController()->focusedFrame();
if (frame) {
Document *document = frame->document();
hasFocusedNode = document && document->focusedNode();
}
return hasFocusedNode;
}
void QWebPage::setContentEditable(bool editable)
{
if (isContentEditable() != editable) {
d->page->setEditable(editable);
d->page->setTabKeyCyclesThroughElements(!editable);
if (d->mainFrame) {
WebCore::Frame* frame = d->mainFrame.data()->d->frame;
if (editable) {
frame->editor()->applyEditingStyleToBodyElement();
}
}
d->updateEditorActions();
}
}
bool QWebPage::isContentEditable() const
{
return d->page->isEditable();
}
void QWebPage::setForwardUnsupportedContent(bool forward)
{
d->forwardUnsupportedContent = forward;
}
bool QWebPage::forwardUnsupportedContent() const
{
return d->forwardUnsupportedContent;
}
void QWebPage::setLinkDelegationPolicy(LinkDelegationPolicy policy)
{
d->linkPolicy = policy;
}
QWebPage::LinkDelegationPolicy QWebPage::linkDelegationPolicy() const
{
return d->linkPolicy;
}
#ifndef QT_NO_CONTEXTMENU
static bool handleScrollbarContextMenuEvent(Scrollbar* scrollBar, QContextMenuEvent* event)
{
if (!QApplication::style()->styleHint(QStyle::SH_ScrollBar_ContextMenu))
return true;
bool horizontal = (scrollBar->orientation() == HorizontalScrollbar);
QMenu menu;
QAction* actScrollHere = menu.addAction(QCoreApplication::translate("QWebPage", "Scroll here"));
menu.addSeparator();
QAction* actScrollTop = menu.addAction(horizontal ? QCoreApplication::translate("QWebPage", "Left edge") : QCoreApplication::translate("QWebPage", "Top"));
QAction* actScrollBottom = menu.addAction(horizontal ? QCoreApplication::translate("QWebPage", "Right edge") : QCoreApplication::translate("QWebPage", "Bottom"));
menu.addSeparator();
QAction* actPageUp = menu.addAction(horizontal ? QCoreApplication::translate("QWebPage", "Page left") : QCoreApplication::translate("QWebPage", "Page up"));
QAction* actPageDown = menu.addAction(horizontal ? QCoreApplication::translate("QWebPage", "Page right") : QCoreApplication::translate("QWebPage", "Page down"));
menu.addSeparator();
QAction* actScrollUp = menu.addAction(horizontal ? QCoreApplication::translate("QWebPage", "Scroll left") : QCoreApplication::translate("QWebPage", "Scroll up"));
QAction* actScrollDown = menu.addAction(horizontal ? QCoreApplication::translate("QWebPage", "Scroll right") : QCoreApplication::translate("QWebPage", "Scroll down"));
QAction* actionSelected = menu.exec(event->globalPos());
if (actionSelected == actScrollHere) {
ScrollbarTheme* theme = scrollBar->theme();
int position = theme->trackPosition(scrollBar) + theme->thumbPosition(scrollBar) + theme->thumbLength(scrollBar) / 2;
scrollBar->setPressedPos(position);
const QPoint pos = scrollBar->convertFromContainingWindow(event->pos());
scrollBar->moveThumb(horizontal ? pos.x() : pos.y());
} else if (actionSelected == actScrollTop)
scrollBar->scrollableArea()->scroll(horizontal ? ScrollLeft : ScrollUp, ScrollByDocument);
else if (actionSelected == actScrollBottom)
scrollBar->scrollableArea()->scroll(horizontal ? ScrollRight : ScrollDown, ScrollByDocument);
else if (actionSelected == actPageUp)
scrollBar->scrollableArea()->scroll(horizontal ? ScrollLeft : ScrollUp, ScrollByPage);
else if (actionSelected == actPageDown)
scrollBar->scrollableArea()->scroll(horizontal ? ScrollRight : ScrollDown, ScrollByPage);
else if (actionSelected == actScrollUp)
scrollBar->scrollableArea()->scroll(horizontal ? ScrollLeft : ScrollUp, ScrollByLine);
else if (actionSelected == actScrollDown)
scrollBar->scrollableArea()->scroll(horizontal ? ScrollRight : ScrollDown, ScrollByLine);
return true;
}
bool QWebPage::swallowContextMenuEvent(QContextMenuEvent *event)
{
d->page->contextMenuController()->clearContextMenu();
if (QWebFrame* webFrame = frameAt(event->pos())) {
Frame* frame = QWebFramePrivate::core(webFrame);
if (Scrollbar* scrollbar = frame->view()->scrollbarAtPoint(convertMouseEvent(event, 1).position()))
return handleScrollbarContextMenuEvent(scrollbar, event);
}
WebCore::Frame* focusedFrame = d->page->focusController()->focusedOrMainFrame();
focusedFrame->eventHandler()->sendContextMenuEvent(convertMouseEvent(event, 1));
ContextMenu *menu = d->page->contextMenuController()->contextMenu();
return !menu;
}
#endif // QT_NO_CONTEXTMENU
void QWebPage::updatePositionDependentActions(const QPoint &pos)
{
#ifndef QT_NO_ACTION
QBitArray originallyEnabledWebActions(QWebPage::WebActionCount);
for (int i = ContextMenuItemTagNoAction; i < ContextMenuItemBaseApplicationTag; ++i) {
QWebPage::WebAction action = webActionForContextMenuAction(WebCore::ContextMenuAction(i));
if (QAction *a = this->action(action)) {
originallyEnabledWebActions.setBit(action, a->isEnabled());
a->setEnabled(false);
}
}
#endif // QT_NO_ACTION
d->createMainFrame();
WebCore::Frame* focusedFrame = d->page->focusController()->focusedOrMainFrame();
HitTestResult result = focusedFrame->eventHandler()->hitTestResultAtPoint(focusedFrame->view()->windowToContents(pos), false);
if (result.scrollbar())
d->hitTestResult = QWebHitTestResult();
else
d->hitTestResult = QWebHitTestResult(new QWebHitTestResultPrivate(result));
d->page->contextMenuController()->setHitTestResult(result);
#if ENABLE(INSPECTOR)
if (d->page->inspectorController()->enabled())
d->page->contextMenuController()->addInspectElementItem();
#endif
QBitArray visitedWebActions(QWebPage::WebActionCount);
#ifndef QT_NO_CONTEXTMENU
delete d->currentContextMenu.data();
d->currentContextMenu = d->createContextMenu(d->page->contextMenuController()->contextMenu(), d->page->contextMenuController()->contextMenu()->platformDescription(), &visitedWebActions);
#endif // QT_NO_CONTEXTMENU
#ifndef QT_NO_ACTION
originallyEnabledWebActions &= ~visitedWebActions; for (int i = 0; i < QWebPage::WebActionCount; ++i) {
if (originallyEnabledWebActions.at(i)) {
if (QAction *a = this->action(QWebPage::WebAction(i)))
a->setEnabled(true);
}
}
#endif // QT_NO_ACTION
}
bool QWebPage::extension(Extension extension, const ExtensionOption *option, ExtensionReturn *output)
{
#ifndef QT_NO_FILEDIALOG
if (extension == ChooseMultipleFilesExtension) {
QStringList suggestedFiles = static_cast<const ChooseMultipleFilesExtensionOption*>(option)->suggestedFileNames;
QWidget* parent = (d->client) ? d->client->ownerWidget() : 0;
QStringList names = QFileDialog::getOpenFileNames(parent, QString::null);
static_cast<ChooseMultipleFilesExtensionReturn*>(output)->fileNames = names;
return true;
}
#endif
return false;
}
bool QWebPage::supportsExtension(Extension extension) const
{
#ifndef QT_NO_FILEDIALOG
return extension == ChooseMultipleFilesExtension;
#else
Q_UNUSED(extension);
return false;
#endif
}
bool QWebPage::findText(const QString &subString, FindFlags options)
{
::TextCaseSensitivity caseSensitivity = ::TextCaseInsensitive;
if (options & FindCaseSensitively)
caseSensitivity = ::TextCaseSensitive;
if (options & HighlightAllOccurrences) {
if (subString.isEmpty()) {
d->page->unmarkAllTextMatches();
return true;
} else
return d->page->markAllMatchesForText(subString, caseSensitivity, true, 0);
} else {
if (subString.isEmpty()) {
d->page->mainFrame()->selection()->clear();
Frame* frame = d->page->mainFrame()->tree()->firstChild();
while (frame) {
frame->selection()->clear();
frame = frame->tree()->traverseNextWithWrap(false);
}
}
::FindDirection direction = ::FindDirectionForward;
if (options & FindBackward)
direction = ::FindDirectionBackward;
const bool shouldWrap = options & FindWrapsAroundDocument;
return d->page->findString(subString, caseSensitivity, direction, shouldWrap);
}
}
QWebSettings *QWebPage::settings() const
{
return d->settings;
}
QString QWebPage::chooseFile(QWebFrame *parentFrame, const QString& suggestedFile)
{
Q_UNUSED(parentFrame)
#ifndef QT_NO_FILEDIALOG
QWidget* parent = (d->client) ? d->client->ownerWidget() : 0;
return QFileDialog::getOpenFileName(parent, QString::null, suggestedFile);
#else
return QString::null;
#endif
}
void QWebPage::setNetworkAccessManager(QNetworkAccessManager *manager)
{
if (manager == d->networkManager)
return;
if (d->networkManager && d->networkManager->parent() == this)
delete d->networkManager;
d->networkManager = manager;
}
QNetworkAccessManager *QWebPage::networkAccessManager() const
{
if (!d->networkManager) {
QWebPage *that = const_cast<QWebPage *>(this);
that->d->networkManager = new QNetworkAccessManager(that);
}
return d->networkManager;
}
void QWebPage::setPluginFactory(QWebPluginFactory *factory)
{
d->pluginFactory = factory;
}
QWebPluginFactory *QWebPage::pluginFactory() const
{
return d->pluginFactory;
}
QString QWebPage::userAgentForUrl(const QUrl&) const
{
static QString firstPart;
static QString secondPart;
static QString thirdPart;
if (firstPart.isNull() || secondPart.isNull() || thirdPart.isNull()) {
QString firstPartTemp;
firstPartTemp.reserve(150);
firstPartTemp += QString::fromLatin1("Mozilla/5.0 ("
#ifdef Q_WS_MAC
"Macintosh; "
#elif defined Q_WS_QWS
"QtEmbedded; "
#elif defined Q_WS_WIN
#elif defined Q_WS_X11
"X11; "
#else
"Unknown; "
#endif
);
#if defined(QT_NO_OPENSSL)
firstPartTemp += QString::fromLatin1("N; ");
#endif
#ifdef Q_OS_AIX
firstPartTemp += QString::fromLatin1("AIX");
#elif defined Q_OS_WIN32
firstPartTemp += windowsVersionForUAString();
#elif defined Q_OS_DARWIN
#ifdef __i386__ || __x86_64__
firstPartTemp += QString::fromLatin1("Intel Mac OS X");
#else
firstPartTemp += QString::fromLatin1("PPC Mac OS X");
#endif
#elif defined Q_OS_BSDI
firstPartTemp += QString::fromLatin1("BSD");
#elif defined Q_OS_BSD4
firstPartTemp += QString::fromLatin1("BSD Four");
#elif defined Q_OS_CYGWIN
firstPartTemp += QString::fromLatin1("Cygwin");
#elif defined Q_OS_DGUX
firstPartTemp += QString::fromLatin1("DG/UX");
#elif defined Q_OS_DYNIX
firstPartTemp += QString::fromLatin1("DYNIX/ptx");
#elif defined Q_OS_FREEBSD
firstPartTemp += QString::fromLatin1("FreeBSD");
#elif defined Q_OS_HPUX
firstPartTemp += QString::fromLatin1("HP-UX");
#elif defined Q_OS_HURD
firstPartTemp += QString::fromLatin1("GNU Hurd");
#elif defined Q_OS_IRIX
firstPartTemp += QString::fromLatin1("SGI Irix");
#elif defined Q_OS_LINUX
#if defined(__x86_64__)
firstPartTemp += QString::fromLatin1("Linux x86_64");
#elif defined(__i386__)
firstPartTemp += QString::fromLatin1("Linux i686");
#else
firstPartTemp += QString::fromLatin1("Linux");
#endif
#elif defined Q_OS_LYNX
firstPartTemp += QString::fromLatin1("LynxOS");
#elif defined Q_OS_NETBSD
firstPartTemp += QString::fromLatin1("NetBSD");
#elif defined Q_OS_OS2
firstPartTemp += QString::fromLatin1("OS/2");
#elif defined Q_OS_OPENBSD
firstPartTemp += QString::fromLatin1("OpenBSD");
#elif defined Q_OS_OS2EMX
firstPartTemp += QString::fromLatin1("OS/2");
#elif defined Q_OS_OSF
firstPartTemp += QString::fromLatin1("HP Tru64 UNIX");
#elif defined Q_OS_QNX6
firstPartTemp += QString::fromLatin1("QNX RTP Six");
#elif defined Q_OS_QNX
firstPartTemp += QString::fromLatin1("QNX");
#elif defined Q_OS_RELIANT
firstPartTemp += QString::fromLatin1("Reliant UNIX");
#elif defined Q_OS_SCO
firstPartTemp += QString::fromLatin1("SCO OpenServer");
#elif defined Q_OS_SOLARIS
firstPartTemp += QString::fromLatin1("Sun Solaris");
#elif defined Q_OS_ULTRIX
firstPartTemp += QString::fromLatin1("DEC Ultrix");
#elif defined Q_OS_UNIX
firstPartTemp += QString::fromLatin1("UNIX BSD/SYSV system");
#elif defined Q_OS_UNIXWARE
firstPartTemp += QString::fromLatin1("UnixWare Seven, Open UNIX Eight");
#else
firstPartTemp += QString::fromLatin1("Unknown");
#endif
#if USE(QT_MOBILITY_SYSTEMINFO)
QtMobility::QSystemDeviceInfo systemDeviceInfo;
QString model = systemDeviceInfo.model();
if (!model.isEmpty()) {
if (!firstPartTemp.endsWith("; "))
firstPartTemp += QString::fromLatin1("; ");
firstPartTemp += systemDeviceInfo.model();
}
#endif
firstPartTemp.squeeze();
firstPart = firstPartTemp;
QString secondPartTemp;
secondPartTemp.reserve(150);
secondPartTemp += QString::fromLatin1(") ");
secondPartTemp += QString::fromLatin1("AppleWebKit/");
secondPartTemp += qWebKitVersion();
secondPartTemp += QString::fromLatin1(" (KHTML, like Gecko) ");
secondPartTemp.squeeze();
secondPart = secondPartTemp;
QString thirdPartTemp;
thirdPartTemp.reserve(150);
thirdPartTemp += QLatin1String(" Safari/");
thirdPartTemp += qWebKitVersion();
thirdPartTemp.squeeze();
thirdPart = thirdPartTemp;
Q_ASSERT(!firstPart.isNull());
Q_ASSERT(!secondPart.isNull());
Q_ASSERT(!thirdPart.isNull());
}
QString appName = QCoreApplication::applicationName();
if (!appName.isEmpty()) {
QString appVer = QCoreApplication::applicationVersion();
if (!appVer.isEmpty())
appName.append(QLatin1Char('/') + appVer);
} else {
appName = QString::fromLatin1("Qt/") + QString::fromLatin1(qVersion());
}
return firstPart + secondPart + appName + thirdPart;
}
void QWebPagePrivate::_q_onLoadProgressChanged(int)
{
m_totalBytes = page->progress()->totalPageAndResourceBytesToLoad();
m_bytesReceived = page->progress()->totalBytesReceived();
}
quint64 QWebPage::totalBytes() const
{
return d->m_totalBytes;
}
quint64 QWebPage::bytesReceived() const
{
return d->m_bytesReceived;
}
#include "moc_qwebpage.cpp"