summaryrefslogtreecommitdiffstats
path: root/src/webenginewidgets/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/webenginewidgets/api')
-rw-r--r--src/webenginewidgets/api/qwebenginecertificateerror.cpp2
-rw-r--r--src/webenginewidgets/api/qwebenginecertificateerror.h1
-rw-r--r--src/webenginewidgets/api/qwebenginecontextmenudata.cpp41
-rw-r--r--src/webenginewidgets/api/qwebenginecontextmenudata.h2
-rw-r--r--src/webenginewidgets/api/qwebenginedownloaditem.cpp32
-rw-r--r--src/webenginewidgets/api/qwebenginedownloaditem.h9
-rw-r--r--src/webenginewidgets/api/qwebenginedownloaditem_p.h1
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp230
-rw-r--r--src/webenginewidgets/api/qwebenginepage.h18
-rw-r--r--src/webenginewidgets/api/qwebenginepage_p.h7
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.cpp90
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.h5
-rw-r--r--src/webenginewidgets/api/qwebenginescript.cpp3
-rw-r--r--src/webenginewidgets/api/qwebenginescriptcollection.cpp2
-rw-r--r--src/webenginewidgets/api/qwebenginesettings.cpp7
-rw-r--r--src/webenginewidgets/api/qwebenginesettings.h5
16 files changed, 383 insertions, 72 deletions
diff --git a/src/webenginewidgets/api/qwebenginecertificateerror.cpp b/src/webenginewidgets/api/qwebenginecertificateerror.cpp
index 289bb7ec0..a0641c9dd 100644
--- a/src/webenginewidgets/api/qwebenginecertificateerror.cpp
+++ b/src/webenginewidgets/api/qwebenginecertificateerror.cpp
@@ -104,6 +104,8 @@ QWebEngineCertificateError::~QWebEngineCertificateError()
\value CertificateWeakKey The certificate contains a weak key.
\value CertificateNameConstraintViolation The certificate claimed DNS names that are in violation of name constraints.
\value CertificateValidityTooLong The certificate has a validity period that is too long. (Added in Qt 5.7)
+ \value CertificateTransparencyRequired Certificate Transparency was required for this connection, but the server
+ did not provide CT information that complied with the policy. (Added in Qt 5.8)
*/
/*!
diff --git a/src/webenginewidgets/api/qwebenginecertificateerror.h b/src/webenginewidgets/api/qwebenginecertificateerror.h
index 7cb6341bc..82ac281be 100644
--- a/src/webenginewidgets/api/qwebenginecertificateerror.h
+++ b/src/webenginewidgets/api/qwebenginecertificateerror.h
@@ -70,6 +70,7 @@ public:
CertificateWeakKey = -211,
CertificateNameConstraintViolation = -212,
CertificateValidityTooLong = -213,
+ CertificateTransparencyRequired = -214,
};
Error error() const;
diff --git a/src/webenginewidgets/api/qwebenginecontextmenudata.cpp b/src/webenginewidgets/api/qwebenginecontextmenudata.cpp
index 4d72071e5..5d68ed0ec 100644
--- a/src/webenginewidgets/api/qwebenginecontextmenudata.cpp
+++ b/src/webenginewidgets/api/qwebenginecontextmenudata.cpp
@@ -135,7 +135,7 @@ void QWebEngineContextMenuData::reset()
*/
QPoint QWebEngineContextMenuData::position() const
{
- return d ? d->pos : QPoint();
+ return d ? d->position() : QPoint();
}
/*!
@@ -143,7 +143,7 @@ QPoint QWebEngineContextMenuData::position() const
*/
QString QWebEngineContextMenuData::linkText() const
{
- return d ? d->linkText : QString();
+ return d ? d->linkText() : QString();
}
/*!
@@ -151,7 +151,7 @@ QString QWebEngineContextMenuData::linkText() const
*/
QUrl QWebEngineContextMenuData::linkUrl() const
{
- return d ? d->linkUrl : QUrl();
+ return d ? d->linkUrl() : QUrl();
}
/*!
@@ -159,7 +159,7 @@ QUrl QWebEngineContextMenuData::linkUrl() const
*/
QString QWebEngineContextMenuData::selectedText() const
{
- return d ? d->selectedText : QString();
+ return d ? d->selectedText() : QString();
}
/*!
@@ -167,7 +167,7 @@ QString QWebEngineContextMenuData::selectedText() const
*/
QUrl QWebEngineContextMenuData::mediaUrl() const
{
- return d ? d->mediaUrl : QUrl();
+ return d ? d->mediaUrl() : QUrl();
}
/*!
@@ -175,7 +175,7 @@ QUrl QWebEngineContextMenuData::mediaUrl() const
*/
QWebEngineContextMenuData::MediaType QWebEngineContextMenuData::mediaType() const
{
- return d ? static_cast<QWebEngineContextMenuData::MediaType>(d->mediaType) : MediaTypeNone;
+ return d ? static_cast<QWebEngineContextMenuData::MediaType>(d->mediaType()) : MediaTypeNone;
}
/*!
@@ -183,7 +183,34 @@ QWebEngineContextMenuData::MediaType QWebEngineContextMenuData::mediaType() cons
*/
bool QWebEngineContextMenuData::isContentEditable() const
{
- return d ? d->isEditable : false;
+ return d ? d->isEditable() : false;
+}
+
+/*!
+ If the context is a word considered misspelled by the spell-checker, returns the misspelled word.
+
+ For possible replacements of the word, see spellCheckerSuggestions().
+
+ \since 5.8
+*/
+QString QWebEngineContextMenuData::misspelledWord() const
+{
+ if (d)
+ return d->misspelledWord();
+ return QString();
+}
+
+/*!
+ If the context is a word considered misspelled by the spell-checker, returns a list of suggested replacements
+ for misspelledWord().
+
+ \since 5.8
+*/
+QStringList QWebEngineContextMenuData::spellCheckerSuggestions() const
+{
+ if (d)
+ return d->spellCheckerSuggestions();
+ return QStringList();
}
/*!
diff --git a/src/webenginewidgets/api/qwebenginecontextmenudata.h b/src/webenginewidgets/api/qwebenginecontextmenudata.h
index 8e85fee16..97cfe9f65 100644
--- a/src/webenginewidgets/api/qwebenginecontextmenudata.h
+++ b/src/webenginewidgets/api/qwebenginecontextmenudata.h
@@ -76,6 +76,8 @@ public:
QUrl mediaUrl() const;
MediaType mediaType() const;
bool isContentEditable() const;
+ QString misspelledWord() const;
+ QStringList spellCheckerSuggestions() const;
private:
void reset();
diff --git a/src/webenginewidgets/api/qwebenginedownloaditem.cpp b/src/webenginewidgets/api/qwebenginedownloaditem.cpp
index bfb0dd0e8..b777a0898 100644
--- a/src/webenginewidgets/api/qwebenginedownloaditem.cpp
+++ b/src/webenginewidgets/api/qwebenginedownloaditem.cpp
@@ -80,6 +80,7 @@ QWebEngineDownloadItemPrivate::QWebEngineDownloadItemPrivate(QWebEngineProfilePr
, downloadId(-1)
, downloadState(QWebEngineDownloadItem::DownloadCancelled)
, savePageFormat(QWebEngineDownloadItem::MimeHtmlSaveFormat)
+ , type(QWebEngineDownloadItem::Attachment)
, downloadUrl(url)
, totalBytes(-1)
, receivedBytes(0)
@@ -218,6 +219,25 @@ quint32 QWebEngineDownloadItem::id() const
*/
/*!
+ \enum QWebEngineDownloadItem::DownloadType
+ \since 5.8
+
+ Describes the requested download's type.
+
+ \value Attachment The web server's response includes a
+ \c Content-Disposition header with the \c attachment directive. If \c Content-Disposition
+ is present in the reply, the web server is indicating that the client should prompt the
+ user to save the content regardless of the content type.
+ See \l {RFC 2616 section 19.5.1} for details.
+ \value DownloadAttribute The user clicked a link with the \c download
+ attribute. See \l {HTML download attribute} for details.
+ \value UserRequested The user initiated the download, for example by
+ selecting a web action.
+ \value SavePage Saving of the current page was requested (for example by
+ the \l{QWebEnginePage::WebAction}{QWebEnginePage::SavePage} web action).
+*/
+
+/*!
Returns the download item's current state.
\sa QWebEngineDownloadItem::DownloadState
@@ -342,6 +362,18 @@ void QWebEngineDownloadItem::setSavePageFormat(QWebEngineDownloadItem::SavePageF
d->savePageFormat = format;
}
+/*!
+ Returns the requested download's type.
+ \since 5.8
+
+ */
+
+QWebEngineDownloadItem::DownloadType QWebEngineDownloadItem::type() const
+{
+ Q_D(const QWebEngineDownloadItem);
+ return d->type;
+}
+
QWebEngineDownloadItem::QWebEngineDownloadItem(QWebEngineDownloadItemPrivate *p, QObject *parent)
: QObject(parent)
, d_ptr(p)
diff --git a/src/webenginewidgets/api/qwebenginedownloaditem.h b/src/webenginewidgets/api/qwebenginedownloaditem.h
index 80b5c06c5..4b58748ad 100644
--- a/src/webenginewidgets/api/qwebenginedownloaditem.h
+++ b/src/webenginewidgets/api/qwebenginedownloaditem.h
@@ -72,6 +72,14 @@ public:
};
Q_ENUM(SavePageFormat)
+ enum DownloadType {
+ Attachment = 0,
+ DownloadAttribute,
+ UserRequested,
+ SavePage
+ };
+ Q_ENUM(DownloadType)
+
quint32 id() const;
DownloadState state() const;
qint64 totalBytes() const;
@@ -83,6 +91,7 @@ public:
bool isFinished() const;
SavePageFormat savePageFormat() const;
void setSavePageFormat(SavePageFormat format);
+ DownloadType type() const;
public Q_SLOTS:
void accept();
diff --git a/src/webenginewidgets/api/qwebenginedownloaditem_p.h b/src/webenginewidgets/api/qwebenginedownloaditem_p.h
index ddb3b443a..9ddb45444 100644
--- a/src/webenginewidgets/api/qwebenginedownloaditem_p.h
+++ b/src/webenginewidgets/api/qwebenginedownloaditem_p.h
@@ -72,6 +72,7 @@ public:
quint32 downloadId;
QWebEngineDownloadItem::DownloadState downloadState;
QWebEngineDownloadItem::SavePageFormat savePageFormat;
+ QWebEngineDownloadItem::DownloadType type;
QString downloadPath;
const QUrl downloadUrl;
QString mimeType;
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index e84c91bd7..0188cfef8 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -90,6 +90,8 @@ QT_BEGIN_NAMESPACE
using namespace QtWebEngineCore;
+static const int MaxTooltipLength = 1024;
+
static QWebEnginePage::WebWindowType toWindowType(WebContentsAdapterClient::WindowOpenDisposition disposition)
{
switch (disposition) {
@@ -390,6 +392,13 @@ void QWebEnginePagePrivate::didPrintPage(quint64 requestId, const QByteArray &re
m_callbacks.invoke(requestId, result);
}
+#ifndef QT_NO_PRINTER
+void QWebEnginePagePrivate::didPrintPageOnPrinter(quint64 requestId, bool result)
+{
+ m_callbacks.invoke(requestId, result);
+}
+#endif
+
void QWebEnginePagePrivate::passOnFocus(bool reverse)
{
if (view)
@@ -489,6 +498,9 @@ void QWebEnginePagePrivate::updateAction(QWebEnginePage::WebAction action) const
case QWebEnginePage::ReloadAndBypassCache:
enabled = !isLoading;
break;
+ case QWebEnginePage::ViewSource:
+ enabled = adapter->canViewSource();
+ break;
default:
break;
}
@@ -504,6 +516,7 @@ void QWebEnginePagePrivate::updateNavigationActions()
updateAction(QWebEnginePage::Stop);
updateAction(QWebEnginePage::Reload);
updateAction(QWebEnginePage::ReloadAndBypassCache);
+ updateAction(QWebEnginePage::ViewSource);
}
#ifndef QT_NO_ACTION
@@ -788,6 +801,29 @@ void QWebEnginePage::setBackgroundColor(const QColor &color)
}
/*!
+ * Save the currently loaded web page to disk.
+ *
+ * The web page is saved to \a filePath in the specified \a{format}.
+ *
+ * This is a short cut for the following actions:
+ * \list
+ * \li Trigger the Save web action.
+ * \li Accept the next download item and set the specified file path and save format.
+ * \endlist
+ *
+ * This function issues an asynchronous download request for the web page and returns immediately.
+ *
+ * \sa QWebEngineDownloadItem::SavePageFormat
+ * \since 5.8
+ */
+void QWebEnginePage::save(const QString &filePath,
+ QWebEngineDownloadItem::SavePageFormat format) const
+{
+ Q_D(const QWebEnginePage);
+ d->adapter->save(filePath, format);
+}
+
+/*!
\property QWebEnginePage::audioMuted
\brief whether the current page audio is muted.
\since 5.7
@@ -972,6 +1008,9 @@ QAction *QWebEnginePage::action(WebAction action) const
case SavePage:
text = tr("Save &Page");
break;
+ case ViewSource:
+ text = tr("&View Page Source");
+ break;
case NoWebAction:
case WebActionCount:
Q_UNREACHABLE();
@@ -1036,122 +1075,122 @@ void QWebEnginePage::triggerAction(WebAction action, bool)
d->adapter->unselect();
break;
case OpenLinkInThisWindow:
- if (menuData.linkUrl.isValid())
- setUrl(menuData.linkUrl);
+ if (menuData.linkUrl().isValid())
+ setUrl(menuData.linkUrl());
break;
case OpenLinkInNewWindow:
- if (menuData.linkUrl.isValid()) {
+ if (menuData.linkUrl().isValid()) {
QWebEnginePage *newPage = createWindow(WebBrowserWindow);
if (newPage)
- newPage->setUrl(menuData.linkUrl);
+ newPage->setUrl(menuData.linkUrl());
}
break;
case OpenLinkInNewTab:
- if (menuData.linkUrl.isValid()) {
+ if (menuData.linkUrl().isValid()) {
QWebEnginePage *newPage = createWindow(WebBrowserTab);
if (newPage)
- newPage->setUrl(menuData.linkUrl);
+ newPage->setUrl(menuData.linkUrl());
}
break;
case OpenLinkInNewBackgroundTab:
- if (menuData.linkUrl.isValid()) {
+ if (menuData.linkUrl().isValid()) {
QWebEnginePage *newPage = createWindow(WebBrowserBackgroundTab);
if (newPage)
- newPage->setUrl(menuData.linkUrl);
+ newPage->setUrl(menuData.linkUrl());
}
break;
case CopyLinkToClipboard:
- if (menuData.linkUrl.isValid()) {
- QString urlString = menuData.linkUrl.toString(QUrl::FullyEncoded);
- QString title = menuData.linkText.toHtmlEscaped();
+ if (menuData.linkUrl().isValid()) {
+ QString urlString = menuData.linkUrl().toString(QUrl::FullyEncoded);
+ QString title = menuData.linkText().toHtmlEscaped();
QMimeData *data = new QMimeData();
data->setText(urlString);
QString html = QStringLiteral("<a href=\"") + urlString + QStringLiteral("\">") + title + QStringLiteral("</a>");
data->setHtml(html);
- data->setUrls(QList<QUrl>() << menuData.linkUrl);
+ data->setUrls(QList<QUrl>() << menuData.linkUrl());
qApp->clipboard()->setMimeData(data);
}
break;
case DownloadLinkToDisk:
- if (menuData.linkUrl.isValid())
- d->adapter->download(menuData.linkUrl, menuData.suggestedFileName);
+ if (menuData.linkUrl().isValid())
+ d->adapter->download(menuData.linkUrl(), menuData.suggestedFileName());
break;
case CopyImageToClipboard:
- if (menuData.hasImageContent &&
- (menuData.mediaType == WebEngineContextMenuData::MediaTypeImage ||
- menuData.mediaType == WebEngineContextMenuData::MediaTypeCanvas))
+ if (menuData.hasImageContent() &&
+ (menuData.mediaType() == WebEngineContextMenuData::MediaTypeImage ||
+ menuData.mediaType() == WebEngineContextMenuData::MediaTypeCanvas))
{
- d->adapter->copyImageAt(menuData.pos);
+ d->adapter->copyImageAt(menuData.position());
}
break;
case CopyImageUrlToClipboard:
- if (menuData.mediaUrl.isValid() && menuData.mediaType == WebEngineContextMenuData::MediaTypeImage) {
- QString urlString = menuData.mediaUrl.toString(QUrl::FullyEncoded);
- QString title = menuData.linkText;
+ if (menuData.mediaUrl().isValid() && menuData.mediaType() == WebEngineContextMenuData::MediaTypeImage) {
+ QString urlString = menuData.mediaUrl().toString(QUrl::FullyEncoded);
+ QString title = menuData.linkText();
if (!title.isEmpty())
title = QStringLiteral(" alt=\"%1\"").arg(title.toHtmlEscaped());
QMimeData *data = new QMimeData();
data->setText(urlString);
QString html = QStringLiteral("<img src=\"") + urlString + QStringLiteral("\"") + title + QStringLiteral("></img>");
data->setHtml(html);
- data->setUrls(QList<QUrl>() << menuData.mediaUrl);
+ data->setUrls(QList<QUrl>() << menuData.mediaUrl());
qApp->clipboard()->setMimeData(data);
}
break;
case DownloadImageToDisk:
case DownloadMediaToDisk:
- if (menuData.mediaUrl.isValid())
- d->adapter->download(menuData.mediaUrl, menuData.suggestedFileName);
+ if (menuData.mediaUrl().isValid())
+ d->adapter->download(menuData.mediaUrl(), menuData.suggestedFileName());
break;
case CopyMediaUrlToClipboard:
- if (menuData.mediaUrl.isValid() &&
- (menuData.mediaType == WebEngineContextMenuData::MediaTypeAudio ||
- menuData.mediaType == WebEngineContextMenuData::MediaTypeVideo))
+ if (menuData.mediaUrl().isValid() &&
+ (menuData.mediaType() == WebEngineContextMenuData::MediaTypeAudio ||
+ menuData.mediaType() == WebEngineContextMenuData::MediaTypeVideo))
{
- QString urlString = menuData.mediaUrl.toString(QUrl::FullyEncoded);
+ QString urlString = menuData.mediaUrl().toString(QUrl::FullyEncoded);
QMimeData *data = new QMimeData();
data->setText(urlString);
- if (menuData.mediaType == WebEngineContextMenuData::MediaTypeAudio)
+ if (menuData.mediaType() == WebEngineContextMenuData::MediaTypeAudio)
data->setHtml(QStringLiteral("<audio src=\"") + urlString + QStringLiteral("\"></audio>"));
else
data->setHtml(QStringLiteral("<video src=\"") + urlString + QStringLiteral("\"></video>"));
- data->setUrls(QList<QUrl>() << menuData.mediaUrl);
+ data->setUrls(QList<QUrl>() << menuData.mediaUrl());
qApp->clipboard()->setMimeData(data);
}
break;
case ToggleMediaControls:
- if (menuData.mediaUrl.isValid() && menuData.mediaFlags & WebEngineContextMenuData::MediaCanToggleControls) {
- bool enable = !(menuData.mediaFlags & WebEngineContextMenuData::MediaControls);
- d->adapter->executeMediaPlayerActionAt(menuData.pos, WebContentsAdapter::MediaPlayerControls, enable);
+ if (menuData.mediaUrl().isValid() && menuData.mediaFlags() & WebEngineContextMenuData::MediaCanToggleControls) {
+ bool enable = !(menuData.mediaFlags() & WebEngineContextMenuData::MediaControls);
+ d->adapter->executeMediaPlayerActionAt(menuData.position(), WebContentsAdapter::MediaPlayerControls, enable);
}
break;
case ToggleMediaLoop:
- if (menuData.mediaUrl.isValid() &&
- (menuData.mediaType == WebEngineContextMenuData::MediaTypeAudio ||
- menuData.mediaType == WebEngineContextMenuData::MediaTypeVideo))
+ if (menuData.mediaUrl().isValid() &&
+ (menuData.mediaType() == WebEngineContextMenuData::MediaTypeAudio ||
+ menuData.mediaType() == WebEngineContextMenuData::MediaTypeVideo))
{
- bool enable = !(menuData.mediaFlags & WebEngineContextMenuData::MediaLoop);
- d->adapter->executeMediaPlayerActionAt(menuData.pos, WebContentsAdapter::MediaPlayerLoop, enable);
+ bool enable = !(menuData.mediaFlags() & WebEngineContextMenuData::MediaLoop);
+ d->adapter->executeMediaPlayerActionAt(menuData.position(), WebContentsAdapter::MediaPlayerLoop, enable);
}
break;
case ToggleMediaPlayPause:
- if (menuData.mediaUrl.isValid() &&
- (menuData.mediaType == WebEngineContextMenuData::MediaTypeAudio ||
- menuData.mediaType == WebEngineContextMenuData::MediaTypeVideo))
+ if (menuData.mediaUrl().isValid() &&
+ (menuData.mediaType() == WebEngineContextMenuData::MediaTypeAudio ||
+ menuData.mediaType() == WebEngineContextMenuData::MediaTypeVideo))
{
- bool enable = (menuData.mediaFlags & WebEngineContextMenuData::MediaPaused);
- d->adapter->executeMediaPlayerActionAt(menuData.pos, WebContentsAdapter::MediaPlayerPlay, enable);
+ bool enable = (menuData.mediaFlags() & WebEngineContextMenuData::MediaPaused);
+ d->adapter->executeMediaPlayerActionAt(menuData.position(), WebContentsAdapter::MediaPlayerPlay, enable);
}
break;
case ToggleMediaMute:
- if (menuData.mediaUrl.isValid() && menuData.mediaFlags & WebEngineContextMenuData::MediaHasAudio) {
+ if (menuData.mediaUrl().isValid() && menuData.mediaFlags() & WebEngineContextMenuData::MediaHasAudio) {
// Make sure to negate the value, so that toggling actually works.
- bool enable = !(menuData.mediaFlags & WebEngineContextMenuData::MediaMuted);
- d->adapter->executeMediaPlayerActionAt(menuData.pos, WebContentsAdapter::MediaPlayerMute, enable);
+ bool enable = !(menuData.mediaFlags() & WebEngineContextMenuData::MediaMuted);
+ d->adapter->executeMediaPlayerActionAt(menuData.position(), WebContentsAdapter::MediaPlayerMute, enable);
}
break;
case InspectElement:
- d->adapter->inspectElementAt(menuData.pos);
+ d->adapter->inspectElementAt(menuData.position());
break;
case ExitFullScreen:
d->adapter->exitFullScreen();
@@ -1162,6 +1201,17 @@ void QWebEnginePage::triggerAction(WebAction action, bool)
case SavePage:
d->adapter->save();
break;
+ case ViewSource:
+ // This is a workaround to make the ViewSource action working in a context menu.
+ // The WebContentsAdapter::viewSource() method deletes a
+ // RenderWidgetHostViewQtDelegateWidget instance which passes the control to the event
+ // loop. If the QMenu::aboutToHide() signal is connected to the QObject::deleteLater()
+ // slot the QMenu is deleted by the event handler while the ViewSource action is still not
+ // completed. This may lead to a crash. To avoid this the WebContentsAdapter::viewSource()
+ // method is called indirectly via the QTimer::singleShot() function which schedules the
+ // the viewSource() call after the QMenu's destruction.
+ QTimer::singleShot(0, this, [d](){ d->adapter->viewSource(); });
+ break;
case NoWebAction:
break;
case WebActionCount:
@@ -1170,6 +1220,22 @@ void QWebEnginePage::triggerAction(WebAction action, bool)
}
}
+/*!
+ * \since 5.8
+ * Replace the current misspelled word with \a replacement.
+ *
+ * The current misspelled word can be found in QWebEngineContextMenuData::misspelledWord(),
+ * and suggested replacements in QWebEngineContextMenuData::spellCheckerSuggestions().
+ *
+ * \sa contextMenuData(),
+ */
+
+void QWebEnginePage::replaceMisspelledWord(const QString &replacement)
+{
+ Q_D(QWebEnginePage);
+ d->adapter->replaceMisspelling(replacement);
+}
+
void QWebEnginePage::findText(const QString &subString, FindFlags options, const QWebEngineCallback<bool> &resultCallback)
{
Q_D(QWebEnginePage);
@@ -1206,7 +1272,7 @@ bool QWebEnginePagePrivate::contextMenuRequested(const WebEngineContextMenuData
return false;
contextData.reset();
- QContextMenuEvent event(QContextMenuEvent::Mouse, data.pos, view->mapToGlobal(data.pos));
+ QContextMenuEvent event(QContextMenuEvent::Mouse, data.position(), view->mapToGlobal(data.position()));
switch (view->contextMenuPolicy()) {
case Qt::PreventContextMenu:
return false;
@@ -1216,7 +1282,7 @@ bool QWebEnginePagePrivate::contextMenuRequested(const WebEngineContextMenuData
break;
case Qt::CustomContextMenu:
contextData = data;
- Q_EMIT view->customContextMenuRequested(data.pos);
+ Q_EMIT view->customContextMenuRequested(data.position());
break;
case Qt::ActionsContextMenu:
if (view->actions().count()) {
@@ -1351,6 +1417,16 @@ bool QWebEnginePagePrivate::isEnabled() const
return true;
}
+void QWebEnginePagePrivate::setToolTip(const QString &toolTipText)
+{
+ if (view) {
+ QString wrappedTip;
+ if (!toolTipText.isEmpty())
+ wrappedTip = QLatin1String("<p>") % toolTipText.toHtmlEscaped().left(MaxTooltipLength) % QLatin1String("</p>");
+ view->setToolTip(wrappedTip);
+ }
+}
+
QMenu *QWebEnginePage::createStandardContextMenu()
{
Q_D(QWebEnginePage);
@@ -1361,13 +1437,25 @@ QMenu *QWebEnginePage::createStandardContextMenu()
QAction *action = 0;
const WebEngineContextMenuData &contextMenuData = *d->contextData.d;
- if (!contextMenuData.linkText.isEmpty() && contextMenuData.linkUrl.isValid()) {
+ if (contextMenuData.isEditable() && !contextMenuData.spellCheckerSuggestions().isEmpty()) {
+ QPointer<QWebEnginePage> thisRef(this);
+ for (int i=0; i < contextMenuData.spellCheckerSuggestions().count() && i < 4; i++) {
+ QAction *action = new QAction(menu);
+ QString replacement = contextMenuData.spellCheckerSuggestions().at(i);
+ QObject::connect(action, &QAction::triggered, [thisRef, replacement] { if (thisRef) thisRef->replaceMisspelledWord(replacement); });
+ action->setText(replacement);
+ menu->addAction(action);
+ }
+ menu->addSeparator();
+ }
+
+ if (!contextMenuData.linkText().isEmpty() && contextMenuData.linkUrl().isValid()) {
action = QWebEnginePage::action(OpenLinkInThisWindow);
action->setText(tr("Follow Link"));
menu->addAction(action);
menu->addAction(QWebEnginePage::action(DownloadLinkToDisk));
}
- if (contextMenuData.selectedText.isEmpty()) {
+ if (contextMenuData.selectedText().isEmpty()) {
action = new QAction(QIcon::fromTheme(QStringLiteral("go-previous")), tr("&Back"), menu);
connect(action, &QAction::triggered, d->view, &QWebEngineView::back);
action->setEnabled(d->adapter->canGoBack());
@@ -1381,16 +1469,18 @@ QMenu *QWebEnginePage::createStandardContextMenu()
action = new QAction(QIcon::fromTheme(QStringLiteral("view-refresh")), tr("&Reload"), menu);
connect(action, &QAction::triggered, d->view, &QWebEngineView::reload);
menu->addAction(action);
+
+ menu->addAction(QWebEnginePage::action(ViewSource));
} else {
menu->addAction(QWebEnginePage::action(Copy));
menu->addAction(QWebEnginePage::action(Unselect));
}
- if (!contextMenuData.linkText.isEmpty() && contextMenuData.linkUrl.isValid()) {
+ if (!contextMenuData.linkText().isEmpty() && contextMenuData.linkUrl().isValid()) {
menu->addAction(QWebEnginePage::action(CopyLinkToClipboard));
}
- if (contextMenuData.mediaUrl.isValid()) {
- switch (contextMenuData.mediaType) {
+ if (contextMenuData.mediaUrl().isValid()) {
+ switch (contextMenuData.mediaType()) {
case WebEngineContextMenuData::MediaTypeImage:
menu->addAction(QWebEnginePage::action(DownloadImageToDisk));
menu->addAction(QWebEnginePage::action(CopyImageUrlToClipboard));
@@ -1405,15 +1495,15 @@ QMenu *QWebEnginePage::createStandardContextMenu()
menu->addAction(QWebEnginePage::action(CopyMediaUrlToClipboard));
menu->addAction(QWebEnginePage::action(ToggleMediaPlayPause));
menu->addAction(QWebEnginePage::action(ToggleMediaLoop));
- if (contextMenuData.mediaFlags & WebEngineContextMenuData::MediaHasAudio)
+ if (contextMenuData.mediaFlags() & WebEngineContextMenuData::MediaHasAudio)
menu->addAction(QWebEnginePage::action(ToggleMediaMute));
- if (contextMenuData.mediaFlags & WebEngineContextMenuData::MediaCanToggleControls)
+ if (contextMenuData.mediaFlags() & WebEngineContextMenuData::MediaCanToggleControls)
menu->addAction(QWebEnginePage::action(ToggleMediaControls));
break;
default:
break;
}
- } else if (contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeCanvas) {
+ } else if (contextMenuData.mediaType() == WebEngineContextMenuData::MediaTypeCanvas) {
menu->addAction(QWebEnginePage::action(CopyImageToClipboard));
}
@@ -1471,7 +1561,7 @@ static inline QWebEnginePage::FileSelectionMode toPublic(FilePickerController::F
return static_cast<QWebEnginePage::FileSelectionMode>(mode);
}
-void QWebEnginePagePrivate::runFileChooser(FilePickerController *controller)
+void QWebEnginePagePrivate::runFileChooser(QSharedPointer<FilePickerController> controller)
{
Q_Q(QWebEnginePage);
@@ -1481,8 +1571,6 @@ void QWebEnginePagePrivate::runFileChooser(FilePickerController *controller)
controller->accepted(selectedFileNames);
else
controller->rejected();
-
- delete controller;
}
WebEngineSettings *QWebEnginePagePrivate::webEngineSettings() const
@@ -1779,6 +1867,28 @@ void QWebEnginePage::printToPdf(const QWebEngineCallback<const QByteArray&> &res
d->m_callbacks.registerCallback(requestId, resultCallback);
}
+#ifndef QT_NO_PRINTER
+/*!
+ \fn void QWebEnginePage::print(QPrinter *printer, FunctorOrLambda resultCallback)
+ Renders the current content of the page into a temporary PDF document, then prints it using \a printer.
+
+ The settings for creating and printing the PDF document will be retrieved from the \a printer
+ object.
+ It is the users responsibility to ensure the \a printer remains valid until \a resultCallback
+ has been called.
+
+ The \a resultCallback must take a boolean as parameter. If printing was successful, this
+ boolean will have the value \c true, otherwise, its value will be \c false.
+ \since 5.8
+*/
+void QWebEnginePage::print(QPrinter *printer, const QWebEngineCallback<bool> &resultCallback)
+{
+ Q_D(QWebEnginePage);
+ quint64 requestId = d->adapter->printOnPrinterCallbackResult(printer);
+ d->m_callbacks.registerCallback(requestId, resultCallback);
+}
+#endif // QT_NO_PRINTER
+
/*!
\since 5.7
diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h
index 2ac8e0f3e..e85f9b30e 100644
--- a/src/webenginewidgets/api/qwebenginepage.h
+++ b/src/webenginewidgets/api/qwebenginepage.h
@@ -42,6 +42,7 @@
#include <QtWebEngineWidgets/qtwebenginewidgetsglobal.h>
#include <QtWebEngineWidgets/qwebenginecertificateerror.h>
+#include <QtWebEngineWidgets/qwebenginedownloaditem.h>
#include <QtWebEngineCore/qwebenginecallback.h>
#include <QtCore/qobject.h>
@@ -53,6 +54,9 @@
QT_BEGIN_NAMESPACE
class QMenu;
+#ifndef QT_NO_PRINTER
+class QPrinter;
+#endif
class QWebChannel;
class QWebEngineContextMenuData;
class QWebEngineFullScreenRequest;
@@ -123,6 +127,7 @@ public:
Unselect,
SavePage,
OpenLinkInNewBackgroundTab,
+ ViewSource,
WebActionCount
};
@@ -206,6 +211,8 @@ public:
#endif
virtual void triggerAction(WebAction action, bool checked = false);
+ void replaceMisspelledWord(const QString &replacement);
+
virtual bool event(QEvent*);
#ifdef Q_QDOC
void findText(const QString &subString, FindFlags options = FindFlags());
@@ -261,6 +268,9 @@ public:
QColor backgroundColor() const;
void setBackgroundColor(const QColor &color);
+ void save(const QString &filePath, QWebEngineDownloadItem::SavePageFormat format
+ = QWebEngineDownloadItem::MimeHtmlSaveFormat) const;
+
bool isAudioMuted() const;
void setAudioMuted(bool muted);
bool recentlyAudible() const;
@@ -272,6 +282,14 @@ public:
void printToPdf(const QWebEngineCallback<const QByteArray&> &resultCallback, const QPageLayout &layout = QPageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF()));
#endif
+#ifndef QT_NO_PRINTER
+#ifdef Q_QDOC
+ void print(QPrinter *printer, FunctorOrLambda resultCallback);
+#else
+ void print(QPrinter *printer, const QWebEngineCallback<bool> &resultCallback);
+#endif // QDOC
+#endif // QT_NO_PRINTER
+
const QWebEngineContextMenuData &contextMenuData() const;
Q_SIGNALS:
diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h
index 96640a63a..8d78429d8 100644
--- a/src/webenginewidgets/api/qwebenginepage_p.h
+++ b/src/webenginewidgets/api/qwebenginepage_p.h
@@ -112,13 +112,16 @@ public:
virtual void requestFullScreenMode(const QUrl &origin, bool fullscreen) Q_DECL_OVERRIDE;
virtual bool isFullScreenMode() const Q_DECL_OVERRIDE;
virtual void javascriptDialog(QSharedPointer<QtWebEngineCore::JavaScriptDialogController>) Q_DECL_OVERRIDE;
- virtual void runFileChooser(QtWebEngineCore::FilePickerController *controller) Q_DECL_OVERRIDE;
+ virtual void runFileChooser(QSharedPointer<QtWebEngineCore::FilePickerController>) Q_DECL_OVERRIDE;
virtual void showColorDialog(QSharedPointer<QtWebEngineCore::ColorChooserController>) Q_DECL_OVERRIDE;
virtual void didRunJavaScript(quint64 requestId, const QVariant& result) Q_DECL_OVERRIDE;
virtual void didFetchDocumentMarkup(quint64 requestId, const QString& result) Q_DECL_OVERRIDE;
virtual void didFetchDocumentInnerText(quint64 requestId, const QString& result) Q_DECL_OVERRIDE;
virtual void didFindText(quint64 requestId, int matchCount) Q_DECL_OVERRIDE;
virtual void didPrintPage(quint64 requestId, const QByteArray &result) Q_DECL_OVERRIDE;
+#ifndef QT_NO_PRINTER
+ virtual void didPrintPageOnPrinter(quint64 requestId, bool result) Q_DECL_OVERRIDE;
+#endif
virtual void passOnFocus(bool reverse) Q_DECL_OVERRIDE;
virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) Q_DECL_OVERRIDE;
virtual void authenticationRequired(QSharedPointer<QtWebEngineCore::AuthenticationDialogController>) Q_DECL_OVERRIDE;
@@ -141,6 +144,7 @@ public:
void startDragging(const content::DropData &dropData, Qt::DropActions allowedActions,
const QPixmap &pixmap, const QPoint &offset) Q_DECL_OVERRIDE;
virtual bool isEnabled() const Q_DECL_OVERRIDE;
+ virtual void setToolTip(const QString &toolTipText) Q_DECL_OVERRIDE;
const QObject *holdingQObject() const Q_DECL_OVERRIDE;
virtual QSharedPointer<QtWebEngineCore::BrowserContextAdapter> browserContextAdapter() Q_DECL_OVERRIDE;
@@ -173,6 +177,7 @@ public:
QWebChannel *webChannel;
unsigned int webChannelWorldId;
QUrl iconUrl;
+ bool m_navigationActionTriggered;
mutable QtWebEngineCore::CallbackDirectory m_callbacks;
mutable QAction *actions[QWebEnginePage::WebActionCount];
diff --git a/src/webenginewidgets/api/qwebengineprofile.cpp b/src/webenginewidgets/api/qwebengineprofile.cpp
index 664323034..886a7207e 100644
--- a/src/webenginewidgets/api/qwebengineprofile.cpp
+++ b/src/webenginewidgets/api/qwebengineprofile.cpp
@@ -96,6 +96,11 @@ using QtWebEngineCore::BrowserContextAdapter;
A QWebEngineUrlSchemeHandler can be registered for a profile by installUrlSchemeHandler()
to add support for custom URL schemes. Requests for the scheme are then issued to
QWebEngineUrlSchemeHandler::requestStarted() as QWebEngineUrlRequestJob objects.
+
+ Spellchecking HTML form fields can be enabled per profile by using the setSpellCheckEnabled()
+ method and the current languages used for spellchecking can be set by using the
+ setSpellCheckLanguages() method.
+
*/
/*!
@@ -180,10 +185,12 @@ void QWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info)
Q_ASSERT(!m_ongoingDownloads.contains(info.id));
QWebEngineDownloadItemPrivate *itemPrivate = new QWebEngineDownloadItemPrivate(this, info.url);
itemPrivate->downloadId = info.id;
- itemPrivate->downloadState = QWebEngineDownloadItem::DownloadRequested;
+ itemPrivate->downloadState = info.accepted ? QWebEngineDownloadItem::DownloadInProgress
+ : QWebEngineDownloadItem::DownloadRequested;
itemPrivate->downloadPath = info.path;
itemPrivate->mimeType = info.mimeType;
itemPrivate->savePageFormat = static_cast<QWebEngineDownloadItem::SavePageFormat>(info.savePageFormat);
+ itemPrivate->type = static_cast<QWebEngineDownloadItem::DownloadType>(info.downloadType);
QWebEngineDownloadItem *download = new QWebEngineDownloadItem(itemPrivate, q);
@@ -556,6 +563,87 @@ QWebEngineProfile *QWebEngineProfile::defaultProfile()
}
/*!
+ \since 5.8
+
+ Sets the current list of \a languages for the spell checker.
+ Each language should match the name of the \c .bdic dictionary.
+ For example, the language \c en-US will load the \c en-US.bdic
+ dictionary file.
+
+ Qt WebEngine checks for the \c qtwebengine_dictionaries subdirectory
+ first in the local directory and if it is not found, in the Qt
+ installation directory.
+
+ On macOS, depending on how Qt WebEngine is configured at build time, there are two possibilities
+ how spellchecking data is found:
+
+ \list
+ \li Hunspell dictionaries (default) - .bdic dictionaries are used, just like on other
+ platforms
+ \li Native dictionaries - the macOS spellchecking APIs are used (which means the results
+ will depend on the installed OS dictionaries)
+ \endlist
+
+ Thus, in the macOS Hunspell case, Qt WebEngine will look in the \e qtwebengine_dictionaries
+ subdirectory located inside the application bundle \c Resources directory, and also in the
+ \c Resources directory located inside the Qt framework bundle.
+
+ To summarize, in case of Hunspell usage, the following paths are considered:
+
+ \list
+ \li QCoreApplication::applicationDirPath()/qtwebengine_dictionaries
+ or QCoreApplication::applicationDirPath()/../Contents/Resources/qtwebengine_dictionaries
+ (on macOS)
+ \li [QLibraryInfo::DataPath]/qtwebengine_dictionaries
+ or path/to/QtWebEngineCore.framework/Resources/qtwebengine_dictionaries (Qt framework
+ bundle on macOS)
+ \endlist
+
+ For more information about how to compile \c .bdic dictionaries, see the
+ \l{WebEngine Widgets Spellchecker Example}{Spellchecker Example}.
+
+*/
+void QWebEngineProfile::setSpellCheckLanguages(const QStringList &languages)
+{
+ Q_D(QWebEngineProfile);
+ d->browserContext()->setSpellCheckLanguages(languages);
+}
+
+/*!
+ \since 5.8
+
+ Returns the list of languages used by the spell checker.
+*/
+QStringList QWebEngineProfile::spellCheckLanguages() const
+{
+ const Q_D(QWebEngineProfile);
+ return d->browserContext()->spellCheckLanguages();
+}
+
+/*!
+ \since 5.8
+
+ Enables spell checker if \a enable is \c true, otherwise disables it.
+ \sa isSpellCheckEnabled()
+ */
+void QWebEngineProfile::setSpellCheckEnabled(bool enable)
+{
+ Q_D(QWebEngineProfile);
+ d->browserContext()->setSpellCheckEnabled(enable);
+}
+/*!
+ \since 5.8
+
+ Returns \c true if the spell checker is enabled; otherwise returns \c false.
+ \sa setSpellCheckEnabled()
+ */
+bool QWebEngineProfile::isSpellCheckEnabled() const
+{
+ const Q_D(QWebEngineProfile);
+ return d->browserContext()->isSpellCheckEnabled();
+}
+
+/*!
Returns the default settings for all pages in this profile.
*/
QWebEngineSettings *QWebEngineProfile::settings() const
diff --git a/src/webenginewidgets/api/qwebengineprofile.h b/src/webenginewidgets/api/qwebengineprofile.h
index d981fa5bb..1ce4bfe17 100644
--- a/src/webenginewidgets/api/qwebengineprofile.h
+++ b/src/webenginewidgets/api/qwebengineprofile.h
@@ -121,6 +121,11 @@ public:
void clearHttpCache();
+ void setSpellCheckLanguages(const QStringList &languages);
+ QStringList spellCheckLanguages() const;
+ void setSpellCheckEnabled(bool enabled);
+ bool isSpellCheckEnabled() const;
+
static QWebEngineProfile *defaultProfile();
Q_SIGNALS:
diff --git a/src/webenginewidgets/api/qwebenginescript.cpp b/src/webenginewidgets/api/qwebenginescript.cpp
index 73dd5075e..04a9d979a 100644
--- a/src/webenginewidgets/api/qwebenginescript.cpp
+++ b/src/webenginewidgets/api/qwebenginescript.cpp
@@ -61,7 +61,8 @@ using QtWebEngineCore::UserScript;
not accessible from a different one. ScriptWorldId provides some predefined IDs for this
purpose.
- \note Chromium extensions, such as \c @include, \c @match, and \c @exclude, are not supported.
+ The following \l Greasemonkey attributes are supported since Qt 5.8:
+ \c @exclude, \c @include, \c @name, \c @match, and \c @run-at.
Use QWebEnginePage::scripts() and QWebEngineProfile::scripts() to access
the collection of scripts associated with a single page or a
diff --git a/src/webenginewidgets/api/qwebenginescriptcollection.cpp b/src/webenginewidgets/api/qwebenginescriptcollection.cpp
index 4b77b4699..8d393924f 100644
--- a/src/webenginewidgets/api/qwebenginescriptcollection.cpp
+++ b/src/webenginewidgets/api/qwebenginescriptcollection.cpp
@@ -40,7 +40,7 @@
#include "qwebenginescriptcollection.h"
#include "qwebenginescriptcollection_p.h"
-#include "user_resource_controller_host.h"
+#include "renderer_host/user_resource_controller_host.h"
using QtWebEngineCore::UserScript;
diff --git a/src/webenginewidgets/api/qwebenginesettings.cpp b/src/webenginewidgets/api/qwebenginesettings.cpp
index dfca16287..50002e3e6 100644
--- a/src/webenginewidgets/api/qwebenginesettings.cpp
+++ b/src/webenginewidgets/api/qwebenginesettings.cpp
@@ -89,6 +89,13 @@ static WebEngineSettings::Attribute toWebEngineAttribute(QWebEngineSettings::Web
return WebEngineSettings::AutoLoadIconsForPage;
case QWebEngineSettings::TouchIconsEnabled:
return WebEngineSettings::TouchIconsEnabled;
+ case QWebEngineSettings::FocusOnNavigationEnabled:
+ return WebEngineSettings::FocusOnNavigationEnabled;
+ case QWebEngineSettings::PrintElementBackgrounds:
+ return WebEngineSettings::PrintElementBackgrounds;
+ case QWebEngineSettings::AllowRunningInsecureContent:
+ return WebEngineSettings::AllowRunningInsecureContent;
+
default:
return WebEngineSettings::UnsupportedInCoreSettings;
}
diff --git a/src/webenginewidgets/api/qwebenginesettings.h b/src/webenginewidgets/api/qwebenginesettings.h
index 8eda50ee2..e3fb83ff5 100644
--- a/src/webenginewidgets/api/qwebenginesettings.h
+++ b/src/webenginewidgets/api/qwebenginesettings.h
@@ -85,7 +85,10 @@ public:
WebGLEnabled,
Accelerated2dCanvasEnabled,
AutoLoadIconsForPage,
- TouchIconsEnabled
+ TouchIconsEnabled,
+ FocusOnNavigationEnabled,
+ PrintElementBackgrounds,
+ AllowRunningInsecureContent
};
enum FontSize {