#include "config.h"
#include "qwebpage.h"
#include "DefaultFullScreenVideoHandler.h"
#include "InitWebKitQt.h"
#include "InspectorClientQt.h"
#include "InspectorClientWebPage.h"
#include "InspectorServerQt.h"
#include "PageClientQt.h"
#include "QGraphicsWidgetPluginImpl.h"
#include "QWebUndoCommand.h"
#include "QWidgetPluginImpl.h"
#include "QtFallbackWebPopup.h"
#include "QtPlatformPlugin.h"
#include "UndoStepQt.h"
#include "WebEventConversion.h"
#include "qwebframe.h"
#include "qwebframe_p.h"
#include "qwebhistory.h"
#include "qwebinspector.h"
#include "qwebinspector_p.h"
#include "qwebkitplatformplugin.h"
#include "qwebpage_p.h"
#include "qwebsettings.h"
#include "qwebview.h"
#include <QAction>
#include <QApplication>
#include <QBasicTimer>
#include <QBitArray>
#include <QClipboard>
#include <QColorDialog>
#include <QDebug>
#include <QDesktopWidget>
#include <QDragEnterEvent>
#include <QDragLeaveEvent>
#include <QDragMoveEvent>
#include <QDropEvent>
#include <QFileDialog>
#include <QGestureEvent>
#include <QInputDialog>
#include <QLabel>
#include <QMenu>
#include <QMessageBox>
#include <QNetworkAccessManager>
#include <QNetworkProxy>
#include <QNetworkRequest>
#include <QPainter>
#include <QSslSocket>
#include <QStyle>
#include <QSysInfo>
#if USE(QT_MOBILITY_SYSTEMINFO)
#include <qsysteminfo.h>
#endif
#include <QSystemTrayIcon>
#include <QTextCharFormat>
#include <QToolTip>
#include <QTouchEvent>
#include <QUndoStack>
#include <QUrl>
#if defined(Q_WS_X11)
#include <QX11Info>
#endif
using namespace WebCore;
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,
0 };
const char* QWebPagePrivate::editorCommandForWebActions(QWebPage::WebAction action)
{
if ((action > QWebPage::NoWebAction) && (action < int(sizeof(editorCommandWebActions) / sizeof(const char*))))
return editorCommandWebActions[action];
return 0;
}
QWebPagePrivate::QWebPagePrivate(QWebPage *qq)
: q(qq)
#ifndef QT_NO_UNDOSTACK
, undoStack(0)
#endif
, linkPolicy(QWebPage::DontDelegateLinks)
, m_viewportSize(QSize(0, 0))
, useFixedLayout(false)
, inspectorFrontend(0)
, inspector(0)
, inspectorIsInternalOnly(false)
, m_lastDropAction(Qt::IgnoreAction)
{
WebKit::initializeWebKitWidgets();
initializeWebCorePage();
memset(actions, 0, sizeof(actions));
#if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
addNotificationPresenterClient();
#ifndef QT_NO_SYSTEMTRAYICON
if (!hasSystemTrayIcon())
setSystemTrayIcon(new QSystemTrayIcon);
#endif // QT_NO_SYSTEMTRAYICON
#endif // ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
}
QWebPagePrivate::~QWebPagePrivate()
{
#ifndef QT_NO_CONTEXTMENU
delete currentContextMenu.data();
#endif
#ifndef QT_NO_UNDOSTACK
delete undoStack;
undoStack = 0;
#endif
if (inspector) {
if (inspectorIsInternalOnly)
delete inspector;
else
inspector->setPage(0);
}
deletePage();
}
void QWebPagePrivate::show()
{
if (!view)
return;
view->window()->show();
}
void QWebPagePrivate::setFocus()
{
if (!view)
return;
view->setFocus();
}
void QWebPagePrivate::unfocus()
{
if (!view)
return;
view->clearFocus();
}
void QWebPagePrivate::setWindowRect(const QRect &rect)
{
emit q->geometryChangeRequested(rect);
}
QSize QWebPagePrivate::viewportSize() const
{
return q->viewportSize();
}
QWebPageAdapter *QWebPagePrivate::createWindow(bool dialog)
{
QWebPage *newPage = q->createWindow(dialog ? QWebPage::WebModalDialog : QWebPage::WebBrowserWindow);
if (!newPage)
return 0;
newPage->d->createMainFrame();
return newPage->d;
}
void QWebPagePrivate::javaScriptConsoleMessage(const QString &message, int lineNumber, const QString &sourceID)
{
q->javaScriptConsoleMessage(message, lineNumber, sourceID);
}
void QWebPagePrivate::javaScriptAlert(QWebFrameAdapter* frame, const QString& msg)
{
q->javaScriptAlert(QWebFramePrivate::kit(frame), msg);
}
bool QWebPagePrivate::javaScriptConfirm(QWebFrameAdapter* frame, const QString& msg)
{
return q->javaScriptConfirm(QWebFramePrivate::kit(frame), msg);
}
bool QWebPagePrivate::javaScriptPrompt(QWebFrameAdapter *frame, const QString &msg, const QString &defaultValue, QString *result)
{
return q->javaScriptPrompt(QWebFramePrivate::kit(frame), msg, defaultValue, result);
}
bool QWebPagePrivate::shouldInterruptJavaScript()
{
return q->shouldInterruptJavaScript();
}
void QWebPagePrivate::printRequested(QWebFrameAdapter *frame)
{
emit q->printRequested(QWebFramePrivate::kit(frame));
}
void QWebPagePrivate::databaseQuotaExceeded(QWebFrameAdapter* frame, const QString& databaseName)
{
emit q->databaseQuotaExceeded(QWebFramePrivate::kit(frame), databaseName);
}
void QWebPagePrivate::applicationCacheQuotaExceeded(QWebSecurityOrigin *origin, quint64 defaultOriginQuota, quint64 c)
{
emit q->applicationCacheQuotaExceeded(origin, defaultOriginQuota, c);
}
void QWebPagePrivate::setToolTip(const QString &tip)
{
#ifndef QT_NO_TOOLTIP
if (!view)
return;
if (tip.isEmpty()) {
view->setToolTip(QString());
QToolTip::hideText();
} else {
QString dtip = QLatin1String("<p>") + QString(tip).toHtmlEscaped() + QLatin1String("</p>");
view->setToolTip(dtip);
}
#else
Q_UNUSED(tip);
#endif
}
#if USE(QT_MULTIMEDIA)
QWebFullScreenVideoHandler *QWebPagePrivate::createFullScreenVideoHandler()
{
return new WebKit::DefaultFullScreenVideoHandler;
}
#endif
QWebFrameAdapter *QWebPagePrivate::mainFrameAdapter()
{
return q->mainFrame()->d;
}
QStringList QWebPagePrivate::chooseFiles(QWebFrameAdapter *frame, bool allowMultiple, const QStringList &suggestedFileNames)
{
if (allowMultiple && q->supportsExtension(QWebPage::ChooseMultipleFilesExtension)) {
QWebPage::ChooseMultipleFilesExtensionOption option;
option.parentFrame = QWebFramePrivate::kit(frame);
option.suggestedFileNames = suggestedFileNames;
QWebPage::ChooseMultipleFilesExtensionReturn output;
q->extension(QWebPage::ChooseMultipleFilesExtension, &option, &output);
return output.fileNames;
}
QStringList result;
QString suggestedFile;
if (!suggestedFileNames.isEmpty())
suggestedFile = suggestedFileNames.first();
QString file = q->chooseFile(QWebFramePrivate::kit(frame), suggestedFile);
if (!file.isEmpty())
result << file;
return result;
}
bool QWebPagePrivate::acceptNavigationRequest(QWebFrameAdapter *frameAdapter, const QNetworkRequest &request, int type)
{
QWebFrame *frame = frameAdapter ? QWebFramePrivate::kit(frameAdapter): 0;
if (insideOpenCall
&& frame == mainFrame.data())
return true;
return q->acceptNavigationRequest(frame, request, QWebPage::NavigationType(type));
}
void QWebPagePrivate::emitRestoreFrameStateRequested(QWebFrameAdapter *frame)
{
emit q->restoreFrameStateRequested(QWebFramePrivate::kit(frame));
}
void QWebPagePrivate::emitSaveFrameStateRequested(QWebFrameAdapter *frame, QWebHistoryItem *item)
{
emit q->saveFrameStateRequested(QWebFramePrivate::kit(frame), item);
}
void QWebPagePrivate::emitDownloadRequested(const QNetworkRequest &request)
{
emit q->downloadRequested(request);
}
void QWebPagePrivate::emitFrameCreated(QWebFrameAdapter *frame)
{
emit q->frameCreated(QWebFramePrivate::kit(frame));
}
bool QWebPagePrivate::errorPageExtension(QWebPageAdapter::ErrorPageOption *opt, QWebPageAdapter::ErrorPageReturn *out)
{
QWebPage::ErrorPageExtensionOption option;
if (opt->domain == QLatin1String("QtNetwork"))
option.domain = QWebPage::QtNetwork;
else if (opt->domain == QLatin1String("HTTP"))
option.domain = QWebPage::Http;
else if (opt->domain == QLatin1String("WebKit"))
option.domain = QWebPage::WebKit;
else
return false;
option.url = opt->url;
option.frame = QWebFramePrivate::kit(opt->frame);
option.error = opt->error;
option.errorString = opt->errorString;
QWebPage::ErrorPageExtensionReturn output;
if (!q->extension(QWebPage::ErrorPageExtension, &option, &output))
return false;
out->baseUrl = output.baseUrl;
out->content = output.content;
out->contentType = output.contentType;
out->encoding = output.encoding;
return true;
}
QtPluginWidgetAdapter *QWebPagePrivate::createPlugin(const QString &classid, const QUrl &url, const QStringList ¶mNames, const QStringList ¶mValues)
{
QObject *widget = q->createPlugin(classid, url, paramNames, paramValues);
return adapterForWidget(widget);
}
QtPluginWidgetAdapter *QWebPagePrivate::adapterForWidget(QObject *object) const
{
if (QWidget *widget = qobject_cast<QWidget*>(object))
return new QWidgetPluginImpl(widget);
if (QGraphicsWidget *widget = qobject_cast<QGraphicsWidget*>(object))
return new QGraphicsWidgetPluginImpl(widget);
return 0;
}
void QWebPagePrivate::createMainFrame()
{
if (!mainFrame) {
mainFrame = new QWebFrame(q);
emit q->frameCreated(mainFrame.data());
}
}
#define MAP_WEB_ACTION_FROM_ADAPTER_EQUIVALENT(Name, Value) \
case QWebPageAdapter::Name: return QWebPage::Name
static QWebPage::WebAction webActionForAdapterMenuAction(QWebPageAdapter::MenuAction action)
{
switch (action) {
FOR_EACH_MAPPED_MENU_ACTION(MAP_WEB_ACTION_FROM_ADAPTER_EQUIVALENT, SEMICOLON_SEPARATOR);
#if ENABLE(INSPECTOR)
case QWebPageAdapter::InspectElement: return QWebPage::InspectElement;
#endif
default:
ASSERT_NOT_REACHED();
break;
}
return QWebPage::NoWebAction;
}
#define MAP_ADAPTER_ACTION_FROM_WEBACTION_EQUIVALENT(Name, Value) \
case QWebPage::Name: return QWebPageAdapter::Name
static QWebPageAdapter::MenuAction adapterMenuActionForWebAction(QWebPage::WebAction action)
{
switch (action) {
FOR_EACH_MAPPED_MENU_ACTION(MAP_ADAPTER_ACTION_FROM_WEBACTION_EQUIVALENT, SEMICOLON_SEPARATOR);
#if ENABLE(INSPECTOR)
case QWebPage::InspectElement: return QWebPageAdapter::InspectElement;
#endif
default:
ASSERT_NOT_REACHED();
break;
}
return QWebPageAdapter::NoAction;
}
#ifndef QT_NO_CONTEXTMENU
typedef QWebPageAdapter::MenuItemDescription MenuItem;
QMenu *createContextMenu(QWebPage* page, const QList<MenuItem>& items, QBitArray *visitedWebActions)
{
if (items.isEmpty())
return 0;
QMenu* menu = new QMenu(page->view());
for (int i = 0; i < items.count(); ++i) {
const MenuItem &item = items.at(i);
switch (item.type) {
case MenuItem::Action: {
QWebPage::WebAction action = webActionForAdapterMenuAction(item.action);
QAction *a = page->action(action);
if (a) {
a->setEnabled(item.traits & MenuItem::Enabled);
a->setCheckable(item.traits & MenuItem::Checkable);
a->setChecked(item.traits & MenuItem::Checked);
menu->addAction(a);
visitedWebActions->setBit(action);
}
break;
}
case MenuItem::Separator:
menu->addSeparator();
break;
case MenuItem::SubMenu: {
QMenu *subMenu = createContextMenu(page, item.subMenu, visitedWebActions);
Q_ASSERT(subMenu);
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.subMenuTitle);
menu->addAction(subMenu->menuAction());
} else
delete subMenu;
break;
}
}
}
return menu;
}
#endif // QT_NO_CONTEXTMENU
void QWebPagePrivate::createAndSetCurrentContextMenu(const QList<MenuItemDescription>& items, QBitArray* visitedWebActions)
{
#ifndef QT_NO_CONTEXTMENU
delete currentContextMenu.data();
currentContextMenu = createContextMenu(q, items, visitedWebActions);
#else
Q_UNUSED(menuDescription);
Q_UNUSED(visitedWebActions);
#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::updateAction(QWebPage::WebAction action)
{
#ifdef QT_NO_ACTION
Q_UNUSED(action)
#else
QAction *a = actions[action];
if (!a || !mainFrame)
return;
bool enabled = a->isEnabled();
bool checked = a->isChecked();
QWebPageAdapter::MenuAction mappedAction = QWebPageAdapter::NoAction;
const char* commandName = 0;
switch (action) {
case QWebPage::Back:
case QWebPage::Forward:
case QWebPage::Stop:
case QWebPage::Reload:
case QWebPage::SetTextDirectionDefault:
case QWebPage::SetTextDirectionLeftToRight:
case QWebPage::SetTextDirectionRightToLeft:
mappedAction = adapterMenuActionForWebAction(action);
break;
case QWebPage::ReloadAndBypassCache: mappedAction = QWebPageAdapter::Reload;
break;
#ifndef QT_NO_UNDOSTACK
case QWebPage::Undo:
case QWebPage::Redo:
break;
#endif // QT_NO_UNDOSTACK
case QWebPage::SelectAll: break;
default: {
commandName = editorCommandForWebActions(action);
break;
}
}
if (mappedAction != QWebPageAdapter::NoAction || commandName)
updateActionInternal(mappedAction, commandName, &enabled, &checked);
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);
}
QObject *QWebPagePrivate::inspectorHandle()
{
return getOrCreateInspector();
}
void QWebPagePrivate::setInspectorFrontend(QObject* frontend)
{
inspectorFrontend = qobject_cast<QWidget*>(frontend);
if (inspector)
inspector->d->setFrontend(frontend);
}
void QWebPagePrivate::setInspectorWindowTitle(const QString& title)
{
if (inspector)
inspector->setWindowTitle(title);
}
void QWebPagePrivate::createWebInspector(QObject** inspectorView, QWebPageAdapter** inspectorPage)
{
QWebPage* page = new WebKit::InspectorClientWebPage;
*inspectorView = page->view();
*inspectorPage = page->d;
}
#ifndef QT_NO_MENU
static QStringList iterateContextMenu(QMenu* menu)
{
if (!menu)
return QStringList();
QStringList items;
QList<QAction *> actions = menu->actions();
for (int i = 0; i < actions.count(); ++i) {
if (actions.at(i)->isSeparator())
items << QLatin1String("<separator>");
else
items << actions.at(i)->text();
if (actions.at(i)->menu())
items << iterateContextMenu(actions.at(i)->menu());
}
return items;
}
#endif
QStringList QWebPagePrivate::menuActionsAsText()
{
#ifndef QT_NO_MENU
return iterateContextMenu(currentContextMenu.data());
#else
return QStringList();
#endif
}
void QWebPagePrivate::emitViewportChangeRequested()
{
emit q->viewportChangeRequested();
}
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);
}
bool QWebPagePrivate::requestSoftwareInputPanel() const
{
return QStyle::RequestSoftwareInputPanel(client->style()->styleHint(QStyle::SH_RequestSoftwareInputPanel)) == QStyle::RSIP_OnMouseClick;
}
#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 = 0;
return menu;
#else
return 0;
#endif
}
#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 = handleKeyEvent(ev);
if (!handled)
handled = handleScrolling(ev);
if (!handled) {
handled = true;
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;
default:
handled = false;
break;
}
}
ev->setAccepted(handled);
}
void QWebPagePrivate::keyReleaseEvent(QKeyEvent *ev)
{
if (ev->isAutoRepeat()) {
ev->setAccepted(true);
return;
}
bool handled = handleKeyEvent(ev);
ev->setAccepted(handled);
}
template<class T>
void QWebPagePrivate::dragEnterEvent(T* ev)
{
#ifndef QT_NO_DRAGANDDROP
Qt::DropAction action = dragEntered(ev->mimeData(), QPointF(ev->pos()).toPoint(), ev->possibleActions());
ev->setDropAction(action);
ev->acceptProposedAction();
#endif
}
template<class T>
void QWebPagePrivate::dragMoveEvent(T *ev)
{
#ifndef QT_NO_DRAGANDDROP
m_lastDropAction = dragUpdated(ev->mimeData(), QPointF(ev->pos()).toPoint(), ev->possibleActions());
ev->setDropAction(m_lastDropAction);
if (m_lastDropAction != Qt::IgnoreAction)
ev->accept();
#endif
}
template<class T>
void QWebPagePrivate::dropEvent(T *ev)
{
#ifndef QT_NO_DRAGANDDROP
if (performDrag(ev->mimeData(), QPointF(ev->pos()).toPoint(), ev->possibleActions())) {
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->hasView())
return;
QBrush brush = pal.brush(QPalette::Base);
QColor backgroundColor = brush.style() == Qt::SolidPattern ? brush.color() : QColor();
d->mainFrame.data()->d->updateBackgroundRecursively(backgroundColor);
}
QPalette QWebPage::palette() const
{
return d->palette;
}
void QWebPagePrivate::shortcutOverrideEvent(QKeyEvent* event)
{
if (handleShortcutOverrideEvent(event))
return;
#ifndef QT_NO_SHORTCUT
if (editorActionForKeyEvent(event) != QWebPage::NoWebAction)
event->accept();
#endif
}
bool QWebPagePrivate::gestureEvent(QGestureEvent* event)
{
QWebFrameAdapter* frame = mainFrame.data()->d;
if (!frame->hasView())
return false;
bool handled = false;
#if ENABLE(GESTURE_EVENTS)
QGestureEventFacade gestureFacade;
QGesture* gesture = event->gesture(Qt::TapGesture);
if (gesture && (gesture->state() == Qt::GestureStarted || gesture->state() == Qt::NoGesture)) {
gestureFacade.type = Qt::TapGesture;
QPointF globalPos = static_cast<const QTapGesture*>(gesture)->position();
gestureFacade.globalPos = globalPos.toPoint();
gestureFacade.pos = event->widget()->mapFromGlobal(globalPos.toPoint());
frame->handleGestureEvent(&gestureFacade);
handled = true;
}
gesture = event->gesture(Qt::TapAndHoldGesture);
if (gesture && (gesture->state() == Qt::GestureStarted || gesture->state() == Qt::NoGesture)) {
gestureFacade.type = Qt::TapAndHoldGesture;
QPointF globalPos = static_cast<const QTapAndHoldGesture*>(gesture)->position();
gestureFacade.globalPos = globalPos.toPoint();
gestureFacade.pos = event->widget()->mapFromGlobal(globalPos.toPoint());
frame->handleGestureEvent(&gestureFacade);
handled = true;
}
#endif // ENABLE(GESTURE_EVENTS)
event->setAccepted(handled);
return handled;
}
QVariant QWebPage::inputMethodQuery(Qt::InputMethodQuery property) const
{
return d->inputMethodQuery(property);
}
void QWebPagePrivate::setInspector(QWebInspector* insp)
{
if (inspector)
inspector->d->setFrontend(0);
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;
}
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()
{
delete d;
}
QWebFrame *QWebPage::mainFrame() const
{
d->createMainFrame();
return d->mainFrame.data();
}
QWebFrame *QWebPage::currentFrame() const
{
d->createMainFrame();
return qobject_cast<QWebFrame*>(d->currentFrame());
}
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.data())->view = view;
return;
}
if (view)
d->client.reset(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 (QWebPageAdapter::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
QMessageBox box(view());
box.setWindowTitle(tr("JavaScript Alert - %1").arg(mainFrame()->url().host()));
box.setTextFormat(Qt::PlainText);
box.setText(msg);
box.setStandardButtons(QMessageBox::Ok);
box.exec();
#endif
}
bool QWebPage::javaScriptConfirm(QWebFrame *frame, const QString& msg)
{
Q_UNUSED(frame);
#ifdef QT_NO_MESSAGEBOX
return true;
#else
QMessageBox box(view());
box.setWindowTitle(tr("JavaScript Confirm - %1").arg(mainFrame()->url().host()));
box.setTextFormat(Qt::PlainText);
box.setText(msg);
box.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
return QMessageBox::Ok == box.exec();
#endif
}
bool QWebPage::javaScriptPrompt(QWebFrame *frame, const QString& msg, const QString& defaultValue, QString* result)
{
Q_UNUSED(frame);
bool ok = false;
#ifndef QT_NO_INPUTDIALOG
QInputDialog dlg(view());
dlg.setWindowTitle(tr("JavaScript Prompt - %1").arg(mainFrame()->url().host()));
QLabel* label = dlg.findChild<QLabel*>();
if (label)
label->setTextFormat(Qt::PlainText);
QString escMsg(msg);
escMsg.replace(QChar::fromLatin1('&'), QLatin1String("&&"));
dlg.setLabelText(escMsg);
dlg.setTextEchoMode(QLineEdit::Normal);
dlg.setTextValue(defaultValue);
ok = !!dlg.exec();
if (ok && result)
*result = dlg.textValue();
#endif
return ok;
}
bool QWebPage::shouldInterruptJavaScript()
{
#ifdef QT_NO_MESSAGEBOX
return false;
#else
return QMessageBox::Yes == QMessageBox::information(view(), 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)
{
#if !ENABLE(NOTIFICATIONS) && !ENABLE(LEGACY_NOTIFICATIONS) && !ENABLE(GEOLOCATION)
Q_UNUSED(frame);
Q_UNUSED(policy);
#endif
switch (feature) {
case Notifications:
#if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
if (policy != PermissionUnknown)
d->setNotificationsAllowedForFrame(frame->d, (policy == PermissionGrantedByUser));
#endif
break;
case Geolocation:
#if ENABLE(GEOLOCATION) && HAVE(QTLOCATION)
if (policy != PermissionUnknown)
d->setGeolocationEnabledForFrame(frame->d, (policy == PermissionGrantedByUser));
#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;
}
QStringList QWebPage::supportedContentTypes() const
{
return d->supportedContentTypes();
}
bool QWebPage::supportsContentType(const QString& mimeType) const
{
return d->supportsContentType(mimeType);
}
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)
{
const char *command = 0;
QWebPageAdapter::MenuAction mappedAction = QWebPageAdapter::NoAction;
QWebHitTestResultPrivate* hitTestResult = d->hitTestResult.d;
switch (action) {
case OpenLink:
case OpenLinkInNewWindow:
case OpenLinkInThisWindow:
case OpenFrameInNewWindow:
case CopyLinkToClipboard:
case OpenImageInNewWindow:
case DownloadImageToDisk:
case DownloadLinkToDisk:
case Back:
case Forward:
case Stop:
case Reload:
case SetTextDirectionDefault:
case SetTextDirectionLeftToRight:
case SetTextDirectionRightToLeft:
mappedAction = adapterMenuActionForWebAction(action);
break;
case ReloadAndBypassCache: mappedAction = QWebPageAdapter::Reload;
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 InspectElement: {
#if ENABLE(INSPECTOR)
if (!d->hitTestResult.isNull()) {
d->getOrCreateInspector(); d->inspector->show(); mappedAction = QWebPageAdapter::InspectElement;
}
#endif
break;
}
case StopScheduledPageRefresh: {
QWebFrame* topFrame = mainFrame();
topFrame->d->cancelLoad();
QList<QWebFrame*> childFrames;
collectChildFrames(topFrame, childFrames);
QListIterator<QWebFrame*> it(childFrames);
while (it.hasNext())
it.next()->d->cancelLoad();
break;
}
default:
command = QWebPagePrivate::editorCommandForWebActions(action);
break;
}
if (command || mappedAction != QWebPageAdapter::NoAction)
d->triggerAction(mappedAction, hitTestResult, command, action == ReloadAndBypassCache);
}
QColor QWebPagePrivate::colorSelectionRequested(const QColor &selectedColor)
{
QColor ret = selectedColor;
#ifndef QT_NO_COLORDIALOG
ret = QColorDialog::getColor(selectedColor, q->view());
if (!ret.isValid())
ret = selectedColor;
#endif
return ret;
}
QWebSelectMethod *QWebPagePrivate::createSelectPopup()
{
return new QtFallbackWebPopup(this);
}
QRect QWebPagePrivate::viewRectRelativeToWindow()
{
QWidget* ownerWidget= client.isNull() ? 0 : qobject_cast<QWidget*>(client->ownerWidget());
if (!ownerWidget)
return QRect();
QWidget* topLevelWidget = ownerWidget->window();
QPoint topLeftCorner = ownerWidget->mapFrom(topLevelWidget, QPoint(0, 0));
return QRect(topLeftCorner, ownerWidget->size());
}
void QWebPagePrivate::geolocationPermissionRequested(QWebFrameAdapter* frame)
{
emit q->featurePermissionRequested(QWebFramePrivate::kit(frame), QWebPage::Geolocation);
}
void QWebPagePrivate::geolocationPermissionRequestCancelled(QWebFrameAdapter* frame)
{
emit q->featurePermissionRequestCanceled(QWebFramePrivate::kit(frame), QWebPage::Geolocation);
}
void QWebPagePrivate::notificationsPermissionRequested(QWebFrameAdapter* frame)
{
emit q->featurePermissionRequested(QWebFramePrivate::kit(frame), QWebPage::Notifications);
}
void QWebPagePrivate::notificationsPermissionRequestCancelled(QWebFrameAdapter* frame)
{
emit q->featurePermissionRequestCanceled(QWebFramePrivate::kit(frame), QWebPage::Notifications);
}
void QWebPagePrivate::respondToChangedContents()
{
updateEditorActions();
emit q->contentsChanged();
}
void QWebPagePrivate::respondToChangedSelection()
{
updateEditorActions();
emit q->selectionChanged();
}
void QWebPagePrivate::microFocusChanged()
{
emit q->microFocusChanged();
}
void QWebPagePrivate::triggerCopyAction()
{
q->triggerAction(QWebPage::Copy);
}
void QWebPagePrivate::triggerActionForKeyEvent(QKeyEvent* event)
{
QWebPage::WebAction action = editorActionForKeyEvent(event);
q->triggerAction(action);
}
void QWebPagePrivate::clearUndoStack()
{
#ifndef QT_NO_UNDOSTACK
if (undoStack)
undoStack->clear();
#endif
}
bool QWebPagePrivate::canUndo() const
{
#ifndef QT_NO_UNDOSTACK
if (!undoStack)
return false;
return undoStack->canUndo();
#else
return false;
#endif
}
bool QWebPagePrivate::canRedo() const
{
#ifndef QT_NO_UNDOSTACK
if (!undoStack)
return false;
return undoStack->canRedo();
#else
return false;
#endif
}
void QWebPagePrivate::undo()
{
#ifndef QT_NO_UNDOSTACK
if (undoStack)
undoStack->undo();
#endif
}
void QWebPagePrivate::redo()
{
#ifndef QT_NO_UNDOSTACK
if (undoStack)
undoStack->redo();
#endif
}
void QWebPagePrivate::createUndoStep(QSharedPointer<UndoStepQt> step)
{
#ifndef QT_NO_UNDOSTACK
q->undoStack()->push(new QWebUndoCommand(step));
#endif
}
const char *QWebPagePrivate::editorCommandForKeyEvent(QKeyEvent* event)
{
QWebPage::WebAction action = editorActionForKeyEvent(event);
return editorCommandForWebActions(action);
}
QSize QWebPage::viewportSize() const
{
if (d->mainFrame && d->mainFrame.data()->d->hasView())
return d->mainFrame.data()->d->frameRect().size();
return d->m_viewportSize;
}
void QWebPage::setViewportSize(const QSize &size) const
{
d->m_viewportSize = size;
QWebFrameAdapter* mainFrame = d->mainFrameAdapter();
if (!mainFrame->hasView())
return;
mainFrame->setViewportSize(size);
}
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
{
ViewportAttributes result;
if (availableSize.isEmpty())
return result;
QSize deviceSize(getintenv("QTWEBKIT_DEVICE_WIDTH"), getintenv("QTWEBKIT_DEVICE_HEIGHT"));
if (deviceSize.isNull())
deviceSize = queryDeviceSizeForScreenContainingWidget(view());
QWebPageAdapter::ViewportAttributes attr = d->viewportAttributesForSize(availableSize, deviceSize);
result.m_isValid = true;
result.m_size = attr.size;
result.m_initialScaleFactor = attr.initialScaleFactor;
result.m_minimumScaleFactor = attr.minimumScaleFactor;
result.m_maximumScaleFactor = attr.maximumScaleFactor;
result.m_devicePixelRatio = attr.devicePixelRatio;
result.m_isUserScalable = attr.isUserScalable;
return result;
}
QSize QWebPage::preferredContentsSize() const
{
QWebFrameAdapter* mainFrame = d->mainFrame ? d->mainFrame->d : 0;
QSize customSize;
if (mainFrame && mainFrame->hasView())
customSize = mainFrame->customLayoutSize();
return customSize.isNull() ? d->fixedLayoutSize : customSize;
}
void QWebPage::setPreferredContentsSize(const QSize& size) const
{
d->fixedLayoutSize = size;
QWebFrameAdapter* mainFrame = d->mainFrameAdapter();
if (!mainFrame->hasView())
return;
mainFrame->setCustomLayoutSize(size);
}
void QWebPage::setActualVisibleContentRect(const QRect& rect) const
{
QWebFrameAdapter* mainFrame = d->mainFrameAdapter();
if (!mainFrame->hasView())
return;
mainFrame->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 (QWebPageAdapter::treatSchemeAsLocal(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();
return d->hasSelection();
}
QString QWebPage::selectedText() const
{
d->createMainFrame();
return d->selectedText();
}
QString QWebPage::selectedHtml() const
{
d->createMainFrame();
return d->selectedHtml();
}
#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;
QWebPageAdapter::MenuAction mappedAction = QWebPageAdapter::NoAction;
switch (action) {
case OpenLink:
case OpenLinkInNewWindow:
case OpenFrameInNewWindow:
case OpenLinkInThisWindow:
case DownloadLinkToDisk:
case CopyLinkToClipboard:
case OpenImageInNewWindow:
case DownloadImageToDisk:
case CopyImageToClipboard:
case CopyImageUrlToClipboard:
case Cut:
case Copy:
case Paste:
case SelectAll:
case SetTextDirectionDefault:
case SetTextDirectionLeftToRight:
case SetTextDirectionRightToLeft:
case ToggleBold:
case ToggleItalic:
case ToggleUnderline:
mappedAction = adapterMenuActionForWebAction(action);
break;
case InspectElement:
#if ENABLE(INSPECTOR)
mappedAction = QWebPageAdapter::InspectElement;
#endif
break;
case Back:
mappedAction = QWebPageAdapter::Back;
icon = style->standardIcon(QStyle::SP_ArrowBack);
break;
case Forward:
mappedAction = QWebPageAdapter::Forward;
icon = style->standardIcon(QStyle::SP_ArrowForward);
break;
case Stop:
mappedAction = QWebPageAdapter::Stop;
icon = style->standardIcon(QStyle::SP_BrowserStop);
break;
case Reload:
mappedAction = QWebPageAdapter::Reload;
icon = style->standardIcon(QStyle::SP_BrowserReload);
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 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 (mappedAction != QWebPageAdapter::NoAction)
text = d->contextMenuItemTagForAction(mappedAction, &checkable);
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: {
QGraphicsSceneMouseEvent *gsEv = static_cast<QGraphicsSceneMouseEvent*>(ev);
QMouseEvent dummyEvent(QEvent::MouseMove, gsEv->pos(), gsEv->screenPos(), gsEv->button(), gsEv->buttons(), gsEv->modifiers());
d->mouseMoveEvent(&dummyEvent);
ev->setAccepted(dummyEvent.isAccepted());
break;
}
case QEvent::GraphicsSceneMouseRelease: {
QGraphicsSceneMouseEvent *gsEv = static_cast<QGraphicsSceneMouseEvent*>(ev);
QMouseEvent dummyEvent(QEvent::MouseButtonRelease, gsEv->pos(), gsEv->screenPos(), gsEv->button(), gsEv->buttons(), gsEv->modifiers());
d->adjustPointForClicking(&dummyEvent);
d->mouseReleaseEvent(&dummyEvent);
ev->setAccepted(dummyEvent.isAccepted());
break;
}
case QEvent::GraphicsSceneMousePress: {
QGraphicsSceneMouseEvent *gsEv = static_cast<QGraphicsSceneMouseEvent*>(ev);
QMouseEvent dummyEvent(QEvent::MouseButtonPress, gsEv->pos(), gsEv->screenPos(), gsEv->button(), gsEv->buttons(), gsEv->modifiers());
d->adjustPointForClicking(&dummyEvent);
d->mousePressEvent(&dummyEvent);
ev->setAccepted(dummyEvent.isAccepted());
break;
}
case QEvent::GraphicsSceneMouseDoubleClick: {
QGraphicsSceneMouseEvent *gsEv = static_cast<QGraphicsSceneMouseEvent*>(ev);
QMouseEvent dummyEvent(QEvent::MouseButtonDblClick, gsEv->pos(), gsEv->screenPos(), gsEv->button(), gsEv->buttons(), gsEv->modifiers());
d->adjustPointForClicking(&dummyEvent);
d->mouseDoubleClickEvent(&dummyEvent);
ev->setAccepted(dummyEvent.isAccepted());
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), QApplication::wheelScrollLines());
break;
#if !defined(QT_NO_GRAPHICSVIEW)
case QEvent::GraphicsSceneWheel: {
QGraphicsSceneWheelEvent *gsEv = static_cast<QGraphicsSceneWheelEvent*>(ev);
QWheelEvent dummyEvent(gsEv->pos(), gsEv->screenPos(), gsEv->delta(), gsEv->buttons(), gsEv->modifiers(), gsEv->orientation());
d->wheelEvent(&dummyEvent, QApplication::wheelScrollLines());
ev->setAccepted(dummyEvent.isAccepted());
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();
ev->accept();
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();
ev->accept();
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:
case QEvent::TouchCancel:
return d->touchEvent(static_cast<QTouchEvent*>(ev));
#ifndef QT_NO_GESTURES
case QEvent::Gesture:
d->gestureEvent(static_cast<QGestureEvent*>(ev));
break;
#endif
#ifndef QT_NO_PROPERTIES
case QEvent::DynamicPropertyChange:
d->dynamicPropertyChangeEvent(this, 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);
return d->hasFocusedNode();
}
void QWebPage::setContentEditable(bool editable)
{
if (isContentEditable() != editable) {
d->setContentEditable(editable);
d->updateEditorActions();
}
}
bool QWebPage::isContentEditable() const
{
return d->isContentEditable();
}
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
bool QWebPagePrivate::handleScrollbarContextMenuEvent(QContextMenuEvent* event, bool horizontal, QWebPageAdapter::ScrollDirection* direction, QWebPageAdapter::ScrollGranularity* granularity)
{
if (!QApplication::style()->styleHint(QStyle::SH_ScrollBar_ContextMenu))
return false;
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)
return true;
if (actionSelected == actScrollTop) {
*direction = horizontal ? ScrollLeft : ScrollUp;
*granularity = ScrollByDocument;
} else if (actionSelected == actScrollBottom) {
*direction =horizontal ? ScrollRight : ScrollDown;
*granularity = ScrollByDocument;
} else if (actionSelected == actPageUp) {
*direction = horizontal ? ScrollLeft : ScrollUp;
*granularity = ScrollByPage;
} else if (actionSelected == actPageDown) {
*direction =horizontal ? ScrollRight : ScrollDown;
*granularity = ScrollByPage;
} else if (actionSelected == actScrollUp) {
*direction = horizontal ? ScrollLeft : ScrollUp;
*granularity = ScrollByLine;
} else if (actionSelected == actScrollDown) {
*direction =horizontal ? ScrollRight : ScrollDown;
*granularity = ScrollByLine;
}
return true;
}
bool QWebPage::swallowContextMenuEvent(QContextMenuEvent *event)
{
QWebFrame* webFrame = frameAt(event->pos());
return d->swallowContextMenuEvent(event, webFrame ? webFrame->d : 0);
}
#endif // QT_NO_CONTEXTMENU
void QWebPage::updatePositionDependentActions(const QPoint &pos)
{
#ifndef QT_NO_ACTION
QBitArray originallyEnabledWebActions(QWebPage::WebActionCount);
for (int i = QWebPageAdapter::NoAction + 1; i < QWebPageAdapter::ActionCount; ++i) {
QWebPage::WebAction action = webActionForAdapterMenuAction(QWebPageAdapter::MenuAction(i));
if (QAction *a = this->action(action)) {
originallyEnabledWebActions.setBit(action, a->isEnabled());
a->setEnabled(false);
}
}
#endif // QT_NO_ACTION
QBitArray visitedWebActions(QWebPage::WebActionCount);
d->createMainFrame();
QWebHitTestResultPrivate* result = d->updatePositionDependentMenuActions(pos, &visitedWebActions);
if (!result)
d->hitTestResult = QWebHitTestResult();
else
d->hitTestResult = QWebHitTestResult(result);
#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;
QStringList names = QFileDialog::getOpenFileNames(view(), 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
}
QWebPageAdapter *QWebPage::handle() const
{
return d;
}
bool QWebPage::findText(const QString &subString, FindFlags options)
{
return d->findText(subString, static_cast<QWebPageAdapter::FindFlag>(options.operator int()));
}
QWebSettings *QWebPage::settings() const
{
return d->settings;
}
QString QWebPage::chooseFile(QWebFrame *parentFrame, const QString& suggestedFile)
{
Q_UNUSED(parentFrame);
#ifndef QT_NO_FILEDIALOG
return QFileDialog::getOpenFileName(view(), QString::null, suggestedFile);
#else
return QString::null;
#endif
}
void QWebPage::setNetworkAccessManager(QNetworkAccessManager *manager)
{
d->setNetworkAccessManager(manager);
}
QNetworkAccessManager *QWebPage::networkAccessManager() const
{
return d->networkAccessManager();
}
void QWebPage::setPluginFactory(QWebPluginFactory *factory)
{
d->pluginFactory = factory;
}
QWebPluginFactory *QWebPage::pluginFactory() const
{
return d->pluginFactory;
}
QString QWebPage::userAgentForUrl(const QUrl&) const
{
return QWebPageAdapter::defaultUserAgentString();
}
quint64 QWebPage::totalBytes() const
{
return d->m_totalBytes;
}
quint64 QWebPage::bytesReceived() const
{
return d->m_bytesReceived;
}
#include "moc_qwebpage.cpp"