summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/core/browser_context_adapter.cpp27
-rw-r--r--src/core/browser_context_adapter.h7
-rw-r--r--src/core/browser_context_qt.cpp79
-rw-r--r--src/core/browser_context_qt.h20
-rw-r--r--src/core/chrome_qt.gyp95
-rw-r--r--src/core/config/embedded_linux.pri1
-rw-r--r--src/core/config/linux.pri3
-rw-r--r--src/core/config/mac_osx.pri3
-rw-r--r--src/core/config/windows.pri3
-rw-r--r--src/core/content_browser_client_qt.cpp11
-rw-r--r--src/core/content_main_delegate_qt.cpp4
-rw-r--r--src/core/renderer/content_renderer_client_qt.cpp11
-rw-r--r--src/core/renderer/content_renderer_client_qt.h5
-rw-r--r--src/core/type_conversion.h11
-rw-r--r--src/core/web_contents_adapter.cpp13
-rw-r--r--src/core/web_contents_adapter.h4
-rw-r--r--src/core/web_contents_adapter_client.h13
-rw-r--r--src/core/web_contents_view_qt.cpp17
-rw-r--r--src/core/web_engine_library_info.cpp30
-rw-r--r--src/webengine/api/qquickwebengineprofile.cpp90
-rw-r--r--src/webengine/api/qquickwebengineprofile.h17
-rw-r--r--src/webengine/api/qquickwebengineview.cpp37
-rw-r--r--src/webengine/api/qquickwebengineview_p.h8
-rw-r--r--src/webengine/plugin/plugin.cpp1
-rw-r--r--src/webengine/ui_delegates_manager.cpp5
-rw-r--r--src/webengine/ui_delegates_manager.h3
-rw-r--r--src/webengine/webengine.pro7
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp38
-rw-r--r--src/webenginewidgets/api/qwebenginepage.h8
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.cpp64
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.h8
-rw-r--r--src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc5
-rw-r--r--src/webenginewidgets/webenginewidgets.pro7
33 files changed, 640 insertions, 15 deletions
diff --git a/src/core/browser_context_adapter.cpp b/src/core/browser_context_adapter.cpp
index 0b9c4f3f2..94770f0bb 100644
--- a/src/core/browser_context_adapter.cpp
+++ b/src/core/browser_context_adapter.cpp
@@ -431,4 +431,31 @@ void BrowserContextAdapter::clearHttpCache()
m_browserContext->url_request_getter_->clearHttpCache();
}
+#if defined(ENABLE_SPELLCHECK)
+QStringList BrowserContextAdapter::spellCheckLanguages(const QStringList &acceptLanguages)
+{
+ return m_browserContext->spellCheckLanguages(acceptLanguages);
+}
+
+void BrowserContextAdapter::setSpellCheckLanguage(const QString &language)
+{
+ m_browserContext->setSpellCheckLanguage(language);
+}
+
+QString BrowserContextAdapter::spellCheckLanguage() const
+{
+ return m_browserContext->spellCheckLanguage();
+}
+
+void BrowserContextAdapter::setSpellCheckEnabled(bool enabled)
+{
+ m_browserContext->setSpellCheckEnabled(enabled);
+}
+
+bool BrowserContextAdapter::isSpellCheckEnabled() const
+{
+ return m_browserContext->isSpellCheckEnabled();
+}
+#endif
+
} // namespace QtWebEngineCore
diff --git a/src/core/browser_context_adapter.h b/src/core/browser_context_adapter.h
index 393107940..8eb7631f7 100644
--- a/src/core/browser_context_adapter.h
+++ b/src/core/browser_context_adapter.h
@@ -107,6 +107,13 @@ public:
QString httpUserAgent() const;
void setHttpUserAgent(const QString &userAgent);
+#if defined(ENABLE_SPELLCHECK)
+ QStringList spellCheckLanguages(const QStringList &acceptLanguages);
+ void setSpellCheckLanguage(const QString &language);
+ QString spellCheckLanguage() const;
+ void setSpellCheckEnabled(bool enabled);
+ bool isSpellCheckEnabled() const;
+#endif
// KEEP IN SYNC with API or add mapping layer
enum HttpCacheType {
MemoryHttpCache = 0,
diff --git a/src/core/browser_context_qt.cpp b/src/core/browser_context_qt.cpp
index 15c73180b..ca772c169 100644
--- a/src/core/browser_context_qt.cpp
+++ b/src/core/browser_context_qt.cpp
@@ -52,12 +52,49 @@
#include "content/public/browser/storage_partition.h"
#include "net/proxy/proxy_config_service.h"
+#if defined(ENABLE_SPELLCHECK)
+#include "base/prefs/pref_member.h"
+#include "base/prefs/pref_service.h"
+#include "base/prefs/testing_pref_store.h"
+#include "base/prefs/pref_service.h"
+#include "base/prefs/pref_service_factory.h"
+#include "base/prefs/pref_registry_simple.h"
+#include "components/user_prefs/user_prefs.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/browser/spellchecker/spellcheck_service.h"
+#endif
+
namespace QtWebEngineCore {
+#if defined(ENABLE_SPELLCHECK)
+BrowserContextQt::BrowserContextQt(BrowserContextAdapter *adapter)
+ : m_adapter(adapter),
+ m_prefStore(new TestingPrefStore())
+{
+ m_prefStore->SetInitializationCompleted();
+ base::PrefServiceFactory factory;
+ factory.set_user_prefs(m_prefStore);
+ scoped_refptr<PrefRegistrySimple> registry(new PrefRegistrySimple());
+
+ // Initial spellcheck settings
+ std::string spellcheckLang("en-US");
+ base::ListValue *dictionaries = new base::ListValue;
+ dictionaries->AppendString(spellcheckLang);
+ registry->RegisterListPref(prefs::kSpellCheckDictionaries, dictionaries);
+ registry->RegisterStringPref(prefs::kAcceptLanguages, spellcheckLang);
+ registry->RegisterStringPref(prefs::kSpellCheckDictionary, spellcheckLang);
+ registry->RegisterBooleanPref(prefs::kSpellCheckUseSpellingService, false);
+ registry->RegisterBooleanPref(prefs::kEnableContinuousSpellcheck, false);
+ registry->RegisterBooleanPref(prefs::kEnableAutoSpellCorrect, false);
+ m_prefService = factory.Create(registry.get()).Pass();
+ user_prefs::UserPrefs::Set(this, m_prefService.get());
+}
+#else
BrowserContextQt::BrowserContextQt(BrowserContextAdapter *adapter)
: m_adapter(adapter)
{
}
+#endif //ENABLE_SPELLCHECK
BrowserContextQt::~BrowserContextQt()
{
@@ -156,4 +193,46 @@ net::URLRequestContextGetter *BrowserContextQt::CreateRequestContext(content::Pr
return url_request_getter_.get();
}
+
+#if defined(ENABLE_SPELLCHECK)
+QStringList BrowserContextQt::spellCheckLanguages(const QStringList& acceptedLanguages)
+{
+ QStringList result;
+#if !defined(OS_MACOSX) // no SpellcheckService::GetSpellCheckLanguages
+ m_prefService->SetString(prefs::kAcceptLanguages,acceptedLanguages.join(",").toStdString());
+
+ std::vector<std::string> vec;
+ SpellcheckService::GetSpellCheckLanguages(this, &vec);
+
+ for (std::vector<std::string>::iterator it = vec.begin(); it != vec.end(); ++it) {
+ result << QString::fromStdString(*it);
+ }
+#endif
+ return result;
+}
+
+void BrowserContextQt::setSpellCheckLanguage(const QString &language)
+{
+ base::ListValue dictionaries;
+ dictionaries.AppendString(language.toStdString());
+ m_prefService->Set(prefs::kSpellCheckDictionaries, dictionaries);
+}
+
+QString BrowserContextQt::spellCheckLanguage() const
+{
+ std::string dictionary;
+ m_prefService->GetList(prefs::kSpellCheckDictionaries)->GetString(0, &dictionary);
+ return QString::fromStdString(dictionary);
+}
+
+void BrowserContextQt::setSpellCheckEnabled(bool enabled)
+{
+ m_prefService->SetBoolean(prefs::kEnableContinuousSpellcheck, enabled);
+}
+
+bool BrowserContextQt::isSpellCheckEnabled() const
+{
+ return m_prefService->GetBoolean(prefs::kEnableContinuousSpellcheck);
+}
+#endif //ENABLE_SPELLCHECK
} // namespace QtWebEngineCore
diff --git a/src/core/browser_context_qt.h b/src/core/browser_context_qt.h
index 1513bf4bc..6a4b65b6b 100644
--- a/src/core/browser_context_qt.h
+++ b/src/core/browser_context_qt.h
@@ -47,6 +47,14 @@
#include <QtCore/qcompilerdetection.h> // Needed for Q_DECL_OVERRIDE
+#if defined(ENABLE_SPELLCHECK)
+QT_BEGIN_NAMESPACE
+class QStringList;
+QT_END_NAMESPACE
+class TestingPrefStore;
+class PrefService;
+#endif
+
namespace QtWebEngineCore {
class BrowserContextAdapter;
@@ -81,6 +89,14 @@ public:
BrowserContextAdapter *adapter() { return m_adapter; }
+#if defined(ENABLE_SPELLCHECK)
+ QStringList spellCheckLanguages(const QStringList &acceptLanguages);
+ void setSpellCheckLanguage(const QString &language);
+ QString spellCheckLanguage() const;
+ void setSpellCheckEnabled(bool enabled);
+ bool isSpellCheckEnabled() const;
+#endif
+
private:
friend class ContentBrowserClientQt;
friend class WebContentsAdapter;
@@ -88,6 +104,10 @@ private:
scoped_refptr<URLRequestContextGetterQt> url_request_getter_;
scoped_ptr<PermissionManagerQt> permissionManager;
BrowserContextAdapter *m_adapter;
+#if defined(ENABLE_SPELLCHECK)
+ scoped_refptr<TestingPrefStore> m_prefStore;
+ scoped_ptr<PrefService> m_prefService;
+#endif
friend class BrowserContextAdapter;
DISALLOW_COPY_AND_ASSIGN(BrowserContextQt);
diff --git a/src/core/chrome_qt.gyp b/src/core/chrome_qt.gyp
index 6c8e0d4d6..626691db4 100644
--- a/src/core/chrome_qt.gyp
+++ b/src/core/chrome_qt.gyp
@@ -1,6 +1,61 @@
{
'variables': {
'grit_out_dir': '<(SHARED_INTERMEDIATE_DIR)/chrome',
+ 'chrome_spellchecker_sources': [
+ '<(DEPTH)/base/prefs/testing_pref_store.cc',
+ '<(DEPTH)/base/prefs/testing_pref_store.h',
+ '<(DEPTH)/chrome/browser/spellchecker/feedback.cc',
+ '<(DEPTH)/chrome/browser/spellchecker/feedback.h',
+ '<(DEPTH)/chrome/browser/spellchecker/feedback_sender.cc',
+ '<(DEPTH)/chrome/browser/spellchecker/feedback_sender.h',
+ '<(DEPTH)/chrome/browser/spellchecker/misspelling.cc',
+ '<(DEPTH)/chrome/browser/spellchecker/misspelling.h',
+ '<(DEPTH)/chrome/browser/spellchecker/spellcheck_action.cc',
+ '<(DEPTH)/chrome/browser/spellchecker/spellcheck_action.h',
+ '<(DEPTH)/chrome/browser/spellchecker/spellcheck_custom_dictionary.cc',
+ '<(DEPTH)/chrome/browser/spellchecker/spellcheck_custom_dictionary.h',
+ '<(DEPTH)/chrome/browser/spellchecker/spellcheck_factory.cc',
+ '<(DEPTH)/chrome/browser/spellchecker/spellcheck_factory.h',
+ '<(DEPTH)/chrome/browser/spellchecker/spellcheck_host_metrics.cc',
+ '<(DEPTH)/chrome/browser/spellchecker/spellcheck_host_metrics.h',
+ '<(DEPTH)/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc',
+ '<(DEPTH)/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h',
+ '<(DEPTH)/chrome/browser/spellchecker/spellcheck_message_filter.cc',
+ '<(DEPTH)/chrome/browser/spellchecker/spellcheck_message_filter.h',
+ '<(DEPTH)/chrome/browser/spellchecker/spellcheck_message_filter_platform.h',
+ '<(DEPTH)/chrome/browser/spellchecker/spellcheck_message_filter_platform_mac.cc',
+ '<(DEPTH)/chrome/browser/spellchecker/spellcheck_platform_mac.mm',
+ '<(DEPTH)/chrome/browser/spellchecker/spellcheck_service.cc',
+ '<(DEPTH)/chrome/browser/spellchecker/spellcheck_service.h',
+ '<(DEPTH)/chrome/browser/spellchecker/spelling_service_client.cc',
+ '<(DEPTH)/chrome/browser/spellchecker/spelling_service_client.h',
+ '<(DEPTH)/chrome/browser/spellchecker/word_trimmer.cc',
+ '<(DEPTH)/chrome/browser/spellchecker/word_trimmer.h',
+ '<(DEPTH)/chrome/common/common_message_generator.cc',
+ '<(DEPTH)/chrome/common/pref_names.cc',
+ '<(DEPTH)/chrome/common/pref_names.h',
+ '<(DEPTH)/chrome/common/spellcheck_bdict_language.h',
+ '<(DEPTH)/chrome/common/spellcheck_common.cc',
+ '<(DEPTH)/chrome/common/spellcheck_common.h',
+ '<(DEPTH)/chrome/common/spellcheck_marker.h',
+ '<(DEPTH)/chrome/common/spellcheck_messages.h',
+ '<(DEPTH)/chrome/common/spellcheck_result.h',
+ '<(DEPTH)/chrome/renderer/spellchecker/custom_dictionary_engine.cc',
+ '<(DEPTH)/chrome/renderer/spellchecker/custom_dictionary_engine.h',
+ '<(DEPTH)/chrome/renderer/spellchecker/hunspell_engine.cc',
+ '<(DEPTH)/chrome/renderer/spellchecker/hunspell_engine.h',
+ '<(DEPTH)/chrome/renderer/spellchecker/platform_spelling_engine.cc',
+ '<(DEPTH)/chrome/renderer/spellchecker/platform_spelling_engine.h',
+ '<(DEPTH)/chrome/renderer/spellchecker/spellcheck.cc',
+ '<(DEPTH)/chrome/renderer/spellchecker/spellcheck.h',
+ '<(DEPTH)/chrome/renderer/spellchecker/spellcheck_language.cc',
+ '<(DEPTH)/chrome/renderer/spellchecker/spellcheck_language.h',
+ '<(DEPTH)/chrome/renderer/spellchecker/spellcheck_provider.cc',
+ '<(DEPTH)/chrome/renderer/spellchecker/spellcheck_provider.h',
+ '<(DEPTH)/chrome/renderer/spellchecker/spellcheck_worditerator.cc',
+ '<(DEPTH)/chrome/renderer/spellchecker/spellcheck_worditerator.h',
+ '<(DEPTH)/chrome/renderer/spellchecker/spelling_engine.h',
+ ]
},
'targets': [
{
@@ -20,14 +75,52 @@
'<(SHARED_INTERMEDIATE_DIR)/components/strings',
],
'sources': [
+ '<(DEPTH)/chrome/browser/media/desktop_media_list.h',
'<(DEPTH)/chrome/browser/media/desktop_streams_registry.cc',
'<(DEPTH)/chrome/browser/media/desktop_streams_registry.h',
- '<(DEPTH)/chrome/browser/media/desktop_media_list.h',
'<(DEPTH)/chrome/common/chrome_switches.cc',
'<(DEPTH)/chrome/common/chrome_switches.h',
'<(DEPTH)/chrome/common/localized_error.cc',
'<(DEPTH)/chrome/common/localized_error.h',
],
+ 'conditions': [
+ ['enable_spellcheck==1', {
+ 'sources': [ '<@(chrome_spellchecker_sources)' ],
+ 'include_dirs': [
+ '<(chromium_src_dir)/third_party/WebKit',
+ ],
+ 'dependencies': [
+ '<(chromium_src_dir)/components/components.gyp:keyed_service_content',
+ '<(chromium_src_dir)/components/components.gyp:keyed_service_core',
+ '<(chromium_src_dir)/components/components.gyp:pref_registry',
+ '<(chromium_src_dir)/components/components.gyp:user_prefs',
+ '<(chromium_src_dir)/third_party/hunspell/hunspell.gyp:hunspell',
+ '<(chromium_src_dir)/third_party/icu/icu.gyp:icui18n',
+ '<(chromium_src_dir)/third_party/icu/icu.gyp:icuuc',
+ ],
+ 'defines': [
+ '__STDC_CONSTANT_MACROS',
+ '__STDC_FORMAT_MACROS',
+ ],
+ 'conditions': [
+ ['OS == "win"', {
+ # crbug.com/167187 fix size_t to int truncations
+ 'msvs_disabled_warnings': [4267, ],
+ }],
+ [ 'OS != "mac"', {
+ 'sources/': [
+ ['exclude', '_mac\\.(cc|cpp|mm?)$'],
+ ],
+ }],
+ ['use_browser_spellchecker==0', {
+ 'sources!': [
+ '<(DEPTH)/chrome/renderer/spellchecker/platform_spelling_engine.cc',
+ '<(DEPTH)/chrome/renderer/spellchecker/platform_spelling_engine.h',
+ ],
+ }],
+ ]
+ }],
+ ],
},
{
'target_name': 'chrome_resources',
diff --git a/src/core/config/embedded_linux.pri b/src/core/config/embedded_linux.pri
index 50f94147e..84db049cb 100644
--- a/src/core/config/embedded_linux.pri
+++ b/src/core/config/embedded_linux.pri
@@ -18,7 +18,6 @@ GYP_CONFIG += \
enable_plugins=0 \
enable_printing=0 \
enable_session_service=0 \
- enable_spellcheck=0 \
enable_task_manager=0 \
enable_themes=0 \
enable_webrtc=0 \
diff --git a/src/core/config/linux.pri b/src/core/config/linux.pri
index c3398757e..f2883bc32 100644
--- a/src/core/config/linux.pri
+++ b/src/core/config/linux.pri
@@ -24,6 +24,9 @@ GYP_CONFIG += \
use_openssl_certs=1
}
+no_spellcheck: GYP_CONFIG += enable_spellcheck=0
+else: GYP_CONFIG += enable_spellcheck=1
+
contains(QT_CONFIG, system-zlib): use?(system_minizip): GYP_CONFIG += use_system_zlib=1
contains(QT_CONFIG, system-png): GYP_CONFIG += use_system_libpng=1
contains(QT_CONFIG, system-jpeg): GYP_CONFIG += use_system_libjpeg=1
diff --git a/src/core/config/mac_osx.pri b/src/core/config/mac_osx.pri
index 6532077de..f11dba1b7 100644
--- a/src/core/config/mac_osx.pri
+++ b/src/core/config/mac_osx.pri
@@ -17,5 +17,8 @@ GYP_CONFIG += \
clang_use_chrome_plugins=0 \
enable_widevine=1
+no_spellcheck: GYP_CONFIG += enable_spellcheck=0 use_browser_spellchecker=0
+else: GYP_CONFIG += enable_spellcheck=1 use_browser_spellchecker=1
+
QMAKE_MAC_SDK_PATH = "$$eval(QMAKE_MAC_SDK.$${QMAKE_MAC_SDK}.path)"
exists($$QMAKE_MAC_SDK_PATH): GYP_CONFIG += mac_sdk_path=\"$${QMAKE_MAC_SDK_PATH}\"
diff --git a/src/core/config/windows.pri b/src/core/config/windows.pri
index 92e193422..153a4fe72 100644
--- a/src/core/config/windows.pri
+++ b/src/core/config/windows.pri
@@ -6,6 +6,9 @@ GYP_CONFIG += \
use_ash=0 \
enable_widevine=1
+no_spellcheck: GYP_CONFIG += enable_spellcheck=0
+else: GYP_CONFIG += enable_spellcheck=1
+
# Chromium builds with debug info in release by default but Qt doesn't
CONFIG(release, debug|release):!force_debug_info: GYP_CONFIG += fastbuild=1
diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp
index 25cac53aa..54430b81c 100644
--- a/src/core/content_browser_client_qt.cpp
+++ b/src/core/content_browser_client_qt.cpp
@@ -41,6 +41,9 @@
#include "base/message_loop/message_loop.h"
#include "base/threading/thread_restrictions.h"
+#if defined(ENABLE_SPELLCHECK)
+#include "chrome/browser/spellchecker/spellcheck_message_filter.h"
+#endif
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/public/browser/browser_main_parts.h"
#include "content/public/browser/child_process_security_policy.h"
@@ -352,10 +355,14 @@ content::BrowserMainParts *ContentBrowserClientQt::CreateBrowserMainParts(const
void ContentBrowserClientQt::RenderProcessWillLaunch(content::RenderProcessHost* host)
{
// FIXME: Add a settings variable to enable/disable the file scheme.
- content::ChildProcessSecurityPolicy::GetInstance()->GrantScheme(host->GetID(), url::kFileScheme);
+ const int id = host->GetID();
+ content::ChildProcessSecurityPolicy::GetInstance()->GrantScheme(id, url::kFileScheme);
static_cast<BrowserContextQt*>(host->GetBrowserContext())->m_adapter->userScriptController()->renderProcessStartedWithHost(host);
#if defined(ENABLE_PEPPER_CDMS)
- host->AddFilter(new BrowserMessageFilterQt(host->GetID()));
+ host->AddFilter(new BrowserMessageFilterQt(id));
+#endif
+#if defined(ENABLE_SPELLCHECK)
+ host->AddFilter(new SpellCheckMessageFilter(id));
#endif
}
diff --git a/src/core/content_main_delegate_qt.cpp b/src/core/content_main_delegate_qt.cpp
index 3c633600a..2f61e1e5e 100644
--- a/src/core/content_main_delegate_qt.cpp
+++ b/src/core/content_main_delegate_qt.cpp
@@ -103,7 +103,9 @@ bool ContentMainDelegateQt::BasicStartupComplete(int *exit_code)
PathService::Override(base::DIR_QT_LIBRARY_DATA, WebEngineLibraryInfo::getPath(base::DIR_QT_LIBRARY_DATA));
PathService::Override(content::DIR_MEDIA_LIBS, WebEngineLibraryInfo::getPath(content::DIR_MEDIA_LIBS));
PathService::Override(ui::DIR_LOCALES, WebEngineLibraryInfo::getPath(ui::DIR_LOCALES));
-
+#if defined(ENABLE_SPELLCHECK)
+ PathService::Override(base::DIR_APP_DICTIONARIES, WebEngineLibraryInfo::getPath(base::DIR_APP_DICTIONARIES));
+#endif
SetContentClient(new ContentClientQt);
return false;
}
diff --git a/src/core/renderer/content_renderer_client_qt.cpp b/src/core/renderer/content_renderer_client_qt.cpp
index 5d2882020..36e4f83f1 100644
--- a/src/core/renderer/content_renderer_client_qt.cpp
+++ b/src/core/renderer/content_renderer_client_qt.cpp
@@ -44,6 +44,10 @@
#include "base/strings/string_split.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/common/localized_error.h"
+#if defined(ENABLE_SPELLCHECK)
+#include "chrome/renderer/spellchecker/spellcheck.h"
+#include "chrome/renderer/spellchecker/spellcheck_provider.h"
+#endif
#include "components/cdm/renderer/widevine_key_systems.h"
#include "components/error_page/common/error_page_params.h"
#include "components/visitedlink/renderer/visitedlink_slave.h"
@@ -93,6 +97,10 @@ void ContentRendererClientQt::RenderThreadStarted()
// mark qrc as a secure scheme (avoids deprecation warnings)
blink::WebSecurityPolicy::registerURLSchemeAsSecure(blink::WebString::fromLatin1(kQrcSchemeQt));
+#if defined(ENABLE_SPELLCHECK)
+ m_spellCheck.reset(new SpellCheck());
+ renderThread->AddObserver(m_spellCheck.data());
+#endif
}
void ContentRendererClientQt::RenderViewCreated(content::RenderView* render_view)
@@ -101,6 +109,9 @@ void ContentRendererClientQt::RenderViewCreated(content::RenderView* render_view
new RenderViewObserverQt(render_view, m_webCacheObserver.data());
new WebChannelIPCTransport(render_view);
UserScriptController::instance()->renderViewCreated(render_view);
+#if defined(ENABLE_SPELLCHECK)
+ new SpellCheckProvider(render_view, m_spellCheck.data());
+#endif
}
void ContentRendererClientQt::RenderFrameCreated(content::RenderFrame* render_frame)
diff --git a/src/core/renderer/content_renderer_client_qt.h b/src/core/renderer/content_renderer_client_qt.h
index ca4bebe94..c80395140 100644
--- a/src/core/renderer/content_renderer_client_qt.h
+++ b/src/core/renderer/content_renderer_client_qt.h
@@ -52,6 +52,8 @@ namespace web_cache {
class WebCacheRenderProcessObserver;
}
+class SpellCheck;
+
namespace QtWebEngineCore {
class ContentRendererClientQt : public content::ContentRendererClient {
@@ -73,6 +75,9 @@ public:
private:
QScopedPointer<visitedlink::VisitedLinkSlave> m_visitedLinkSlave;
QScopedPointer<web_cache::WebCacheRenderProcessObserver> m_webCacheObserver;
+#if defined(ENABLE_SPELLCHECK)
+ QScopedPointer<SpellCheck> m_spellCheck;
+#endif
};
} // namespace
diff --git a/src/core/type_conversion.h b/src/core/type_conversion.h
index e203697c0..0f3357948 100644
--- a/src/core/type_conversion.h
+++ b/src/core/type_conversion.h
@@ -250,6 +250,17 @@ inline std::vector<T> toVector(const QStringList &fileList)
int flagsFromModifiers(Qt::KeyboardModifiers modifiers);
+#if defined(ENABLE_SPELLCHECK)
+inline QStringList fromVector(const std::vector<base::string16> &vector)
+{
+ QStringList result;
+ for (auto s: vector) {
+ result.append(toQt(s));
+ }
+ return result;
+}
+#endif
+
} // namespace QtWebEngineCore
#endif // TYPE_CONVERSION_H
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 497221861..bf36a771c 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -1162,6 +1162,19 @@ void WebContentsAdapter::initUpdateDragCursorMessagePollingTimer()
});
}
+#if defined(ENABLE_SPELLCHECK)
+void WebContentsAdapter::replaceMisspelling(const QString &word)
+{
+ Q_D(WebContentsAdapter);
+ d->webContents->ReplaceMisspelling(toString16(word));
+}
+
+void WebContentsAdapter::toogleSpellCheckEnabled()
+{
+ browserContext()->setSpellCheckEnabled(!browserContext()->isSpellCheckEnabled());
+}
+#endif
+
WebContentsAdapterClient::RenderProcessTerminationStatus
WebContentsAdapterClient::renderProcessExitStatus(int terminationStatus) {
auto status = WebContentsAdapterClient::RenderProcessTerminationStatus(-1);
diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h
index cbc7c34fb..e6aef23ec 100644
--- a/src/core/web_contents_adapter.h
+++ b/src/core/web_contents_adapter.h
@@ -170,6 +170,10 @@ public:
// meant to be used within WebEngineCore only
content::WebContents *webContents() const;
+#if defined(ENABLE_SPELLCHECK)
+ void replaceMisspelling(const QString &word);
+ void toogleSpellCheckEnabled();
+#endif
private:
Q_DISABLE_COPY(WebContentsAdapter)
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index c29abe53f..5e6335584 100644
--- a/src/core/web_contents_adapter_client.h
+++ b/src/core/web_contents_adapter_client.h
@@ -79,6 +79,10 @@ public:
: mediaType(MediaTypeNone)
, hasImageContent(false)
, mediaFlags(0)
+#if defined(ENABLE_SPELLCHECK)
+ , isEditable(false)
+ , isSpellCheckerEnabled(false)
+#endif
{
}
@@ -124,11 +128,14 @@ public:
bool hasImageContent;
uint mediaFlags;
QString suggestedFileName;
+#if defined(ENABLE_SPELLCHECK)
+ bool isEditable;
+ bool isSpellCheckerEnabled;
+ QString misspelledWord;
+ QStringList spellCheckerSuggestions;
+#endif
// Some likely candidates for future additions as we add support for the related actions:
// bool isImageBlocked;
-// bool isEditable;
-// bool isSpellCheckingEnabled;
-// QStringList spellCheckingSuggestions;
// <enum tbd> mediaType;
// ...
};
diff --git a/src/core/web_contents_view_qt.cpp b/src/core/web_contents_view_qt.cpp
index 926e159df..9614aa0f8 100644
--- a/src/core/web_contents_view_qt.cpp
+++ b/src/core/web_contents_view_qt.cpp
@@ -39,7 +39,7 @@
#include "web_contents_view_qt.h"
-#include "browser_context_qt.h"
+#include "browser_context_adapter.h"
#include "content_browser_client_qt.h"
#include "render_widget_host_view_qt_delegate.h"
#include "type_conversion.h"
@@ -162,12 +162,27 @@ static WebEngineContextMenuData fromParams(const content::ContextMenuParams &par
ret.hasImageContent = params.has_image_contents;
ret.mediaFlags = params.media_flags;
ret.suggestedFileName = toQt(params.suggested_filename.data());
+#if defined(ENABLE_SPELLCHECK)
+ ret.isEditable = params.is_editable;
+ ret.misspelledWord = toQt(params.misspelled_word);
+ ret.spellCheckerSuggestions = fromVector(params.dictionary_suggestions);
+#endif
return ret;
}
void WebContentsViewQt::ShowContextMenu(content::RenderFrameHost *, const content::ContextMenuParams &params)
{
WebEngineContextMenuData contextMenuData(fromParams(params));
+#if defined(ENABLE_SPELLCHECK)
+ // Do not use params.spellcheck_enabled, since it is never
+ // correctly initialized for chrome asynchronous spellchecking.
+ // Even fixing the initialization in ContextMenuClientImpl::showContextMenu
+ // will not work. By default SpellCheck::spellcheck_enabled_
+ // must be initialized to true due to the way how the initialization sequence
+ // in SpellCheck works ie. typing the first word triggers the creation
+ // of the SpellcheckService. Use user preference store instead.
+ contextMenuData.isSpellCheckerEnabled = m_client->browserContextAdapter()->isSpellCheckEnabled();
+#endif
m_client->contextMenuRequested(contextMenuData);
}
diff --git a/src/core/web_engine_library_info.cpp b/src/core/web_engine_library_info.cpp
index aae86dce8..ee8174af7 100644
--- a/src/core/web_engine_library_info.cpp
+++ b/src/core/web_engine_library_info.cpp
@@ -205,6 +205,32 @@ QString localesPath()
#endif
}
+#if defined(ENABLE_SPELLCHECK)
+QString dictionariesPath()
+{
+#if defined(OS_MACOSX) && defined(QT_MAC_FRAMEWORK_BUILD)
+ return getResourcesPath(frameworkBundle()) % QLatin1String("/qtwebengine_dictionaries");
+#else
+ static bool initialized = false;
+ static QString potentialDictionariesPath = QLibraryInfo::location(QLibraryInfo::DataPath) % QDir::separator() % QLatin1String("qtwebengine_dictionaries");
+
+ if (!initialized) {
+ initialized = true;
+ if (!QFileInfo::exists(potentialDictionariesPath)) {
+ qWarning("Installed Qt WebEngine dictionaries directory not found at location %s. Trying application directory...", qPrintable(potentialDictionariesPath));
+ potentialDictionariesPath = QCoreApplication::applicationDirPath() % QDir::separator() % QLatin1String("qtwebengine_dictionaries");
+ }
+ if (!QFileInfo::exists(potentialDictionariesPath)) {
+ qWarning("Qt WebEngine dictionaries directory not found at location %s. Trying fallback directory... Spellcheck MAY NOT work.", qPrintable(potentialDictionariesPath));
+ potentialDictionariesPath = fallbackDir();
+ }
+ }
+
+ return potentialDictionariesPath;
+#endif
+}
+#endif // ENABLE_SPELLCHECK
+
QString icuDataPath()
{
#if defined(OS_MACOSX) && defined(QT_MAC_FRAMEWORK_BUILD)
@@ -292,6 +318,10 @@ base::FilePath WebEngineLibraryInfo::getPath(int key)
return toFilePath(pluginsPath());
case ui::DIR_LOCALES:
return toFilePath(localesPath());
+#if defined(ENABLE_SPELLCHECK)
+ case base::DIR_APP_DICTIONARIES:
+ return toFilePath(dictionariesPath());
+#endif
default:
// Note: the path system expects this function to override the default
// behavior. So no need to log an error if we don't support a given
diff --git a/src/webengine/api/qquickwebengineprofile.cpp b/src/webengine/api/qquickwebengineprofile.cpp
index 1cf3d8922..14405251e 100644
--- a/src/webengine/api/qquickwebengineprofile.cpp
+++ b/src/webengine/api/qquickwebengineprofile.cpp
@@ -592,7 +592,97 @@ QQuickWebEngineProfile *QQuickWebEngineProfile::defaultProfile()
return profile;
}
+#if !defined(QT_NO_SPELLCHECK)
/*!
+ \qmlmethod void QQuickWebEngineProfile::spellCheckLanguages()
+
+ Returns the subset of \a acceptLanguages supported by the spell checker.
+ Checks whether the spell checker dictionary is installed for the specified
+ language from the \a acceptLanguages list. If the dictionary file is missing
+ or corrupted, the language is removed from the returned list.
+
+ \since QtWebEngine 1.3
+*/
+
+/*!
+ Returns the subset of \a acceptLanguages supported by the spell checker.
+ Checks whether the spell checker dictionary is installed for the specified
+ language from the \a acceptLanguages list. If the dictionary file is missing
+ or corrupted, the language is removed from the returned list.
+
+ \since QtWebEngine 1.3
+*/
+QStringList QQuickWebEngineProfile::spellCheckLanguages(const QStringList &acceptLanguages)
+{
+ const Q_D(QQuickWebEngineProfile);
+ return d->browserContext()->spellCheckLanguages(acceptLanguages);
+}
+
+/*!
+ \property QQuickWebEngineProfile::spellCheckLanguage
+ \brief the language used by the spell checker.
+
+ \since QtWebEngine 1.3
+*/
+
+/*!
+ \qmlproperty QString WebEngineProfile::spellCheckLanguage
+
+ This property holds the language used by the spell checker.
+
+ \since QtWebEngine 1.3
+*/
+void QQuickWebEngineProfile::setSpellCheckLanguage(const QString &language)
+{
+ Q_D(QQuickWebEngineProfile);
+ if (language != d->browserContext()->spellCheckLanguage()) {
+ d->browserContext()->setSpellCheckLanguage(language);
+ emit spellCheckLanguageChanged();
+ }
+}
+
+/*!
+ \since 5.7
+
+ Returns the language used by the spell checker.
+*/
+QString QQuickWebEngineProfile::spellCheckLanguage() const
+{
+ const Q_D(QQuickWebEngineProfile);
+ return d->browserContext()->spellCheckLanguage();
+}
+
+/*!
+ \property QQuickWebEngineProfile::spellCheckEnabled
+ \brief whether the web engine spell checker is enabled.
+
+ \since QtWebEngine 1.3
+*/
+
+/*!
+ \qmlproperty QString WebEngineProfile::spellCheckEnabled
+
+ This property holds whether the web engine spell checker is enabled.
+
+ \since QtWebEngine 1.3
+*/
+void QQuickWebEngineProfile::setSpellCheckEnabled(bool enable)
+{
+ Q_D(QQuickWebEngineProfile);
+ if (enable != isSpellCheckEnabled()) {
+ d->browserContext()->setSpellCheckEnabled(enable);
+ emit spellCheckEnabledChanged();
+ }
+}
+
+bool QQuickWebEngineProfile::isSpellCheckEnabled() const
+{
+ const Q_D(QQuickWebEngineProfile);
+ return d->browserContext()->isSpellCheckEnabled();
+}
+#endif
+/*!
+
Returns the cookie store singleton, if one has been set.
*/
QWebEngineCookieStore *QQuickWebEngineProfile::cookieStore() const
diff --git a/src/webengine/api/qquickwebengineprofile.h b/src/webengine/api/qquickwebengineprofile.h
index ba0126eaa..cf4334126 100644
--- a/src/webengine/api/qquickwebengineprofile.h
+++ b/src/webengine/api/qquickwebengineprofile.h
@@ -71,6 +71,11 @@ class Q_WEBENGINE_EXPORT QQuickWebEngineProfile : public QObject {
Q_PROPERTY(QString httpAcceptLanguage READ httpAcceptLanguage WRITE setHttpAcceptLanguage NOTIFY httpAcceptLanguageChanged FINAL REVISION 1)
Q_PROPERTY(PersistentCookiesPolicy persistentCookiesPolicy READ persistentCookiesPolicy WRITE setPersistentCookiesPolicy NOTIFY persistentCookiesPolicyChanged FINAL)
Q_PROPERTY(int httpCacheMaximumSize READ httpCacheMaximumSize WRITE setHttpCacheMaximumSize NOTIFY httpCacheMaximumSizeChanged FINAL)
+#if !defined(QT_NO_SPELLCHECK)
+ Q_PROPERTY(QString spellCheckLanguage READ spellCheckLanguage WRITE setSpellCheckLanguage NOTIFY spellCheckLanguageChanged REVISION 2)
+ Q_PROPERTY(bool spellCheckEnabled READ isSpellCheckEnabled WRITE setSpellCheckEnabled NOTIFY spellCheckEnabledChanged REVISION 2)
+# endif
+
public:
QQuickWebEngineProfile(QObject *parent = Q_NULLPTR);
~QQuickWebEngineProfile();
@@ -128,6 +133,14 @@ public:
void clearHttpCache();
+#if !defined(QT_NO_SPELLCHECK)
+ Q_REVISION(2) Q_INVOKABLE QStringList spellCheckLanguages(const QStringList &acceptLanguages);
+ Q_REVISION(2) void setSpellCheckLanguage(const QString &language);
+ Q_REVISION(2) QString spellCheckLanguage() const;
+ Q_REVISION(2) void setSpellCheckEnabled(bool enabled);
+ Q_REVISION(2) bool isSpellCheckEnabled() const;
+# endif
+
static QQuickWebEngineProfile *defaultProfile();
Q_SIGNALS:
@@ -140,6 +153,10 @@ Q_SIGNALS:
void persistentCookiesPolicyChanged();
void httpCacheMaximumSizeChanged();
Q_REVISION(1) void httpAcceptLanguageChanged();
+#if !defined(QT_NO_SPELLCHECK)
+ Q_REVISION(2) void spellCheckLanguageChanged();
+ Q_REVISION(2) void spellCheckEnabledChanged();
+#endif
void downloadRequested(QQuickWebEngineDownloadItem *download);
void downloadFinished(QQuickWebEngineDownloadItem *download);
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index 20264c7f7..17710b5cc 100644
--- a/src/webengine/api/qquickwebengineview.cpp
+++ b/src/webengine/api/qquickwebengineview.cpp
@@ -193,7 +193,17 @@ bool QQuickWebEngineViewPrivate::contextMenuRequested(const WebEngineContextMenu
// Populate our menu
MenuItemHandler *item = 0;
-
+#if !defined(QT_NO_SPELLCHECK)
+ if (contextMenuData.isEditable && !contextMenuData.spellCheckerSuggestions.isEmpty()) {
+ for (int i=0; i < contextMenuData.spellCheckerSuggestions.count() && i < 4; i++) {
+ item = new MenuItemHandler(menu);
+ int index = QQuickWebEngineView::ReplaceMisspelledWord_1 + i;
+ QObject::connect(item, &MenuItemHandler::triggered, [q,index] { q->triggerWebAction(static_cast<QQuickWebEngineView::WebAction>(index)); });
+ ui()->addMenuItem(item, contextMenuData.spellCheckerSuggestions.at(i));
+ }
+ ui()->addMenuSeparator(menu);
+ }
+#endif
if (!data.linkText.isEmpty() && data.linkUrl.isValid()) {
item = new MenuItemHandler(menu);
QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::OpenLinkInThisWindow); });
@@ -296,7 +306,13 @@ bool QQuickWebEngineViewPrivate::contextMenuRequested(const WebEngineContextMenu
QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::ExitFullScreen); });
ui()->addMenuItem(item, QQuickWebEngineView::tr("Exit Full Screen Mode"));
}
-
+#if !defined(QT_NO_SPELLCHECK)
+ if (contextMenuData.isEditable) {
+ item = new MenuItemHandler(menu);
+ QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::ToggleSpellcheck); });
+ ui()->addMenuItem(item, QQuickWebEngineView::tr("Check Spelling"), QString(), true, true, contextMenuData.isSpellCheckerEnabled);
+ }
+#endif
// FIXME: expose the context menu data as an attached property to make this more useful
if (contextMenuExtraItems) {
ui()->addMenuSeparator(menu);
@@ -1525,6 +1541,23 @@ void QQuickWebEngineView::triggerWebAction(WebAction action)
case SavePage:
d->adapter->save();
break;
+#if !defined(QT_NO_SPELLCHECK)
+ case ToggleSpellcheck:
+ d->adapter->toogleSpellCheckEnabled();
+ break;
+ case ReplaceMisspelledWord_1:
+ d->adapter->replaceMisspelling(d->contextMenuData.spellCheckerSuggestions.at(0));
+ break;
+ case ReplaceMisspelledWord_2:
+ d->adapter->replaceMisspelling(d->contextMenuData.spellCheckerSuggestions.at(1));
+ break;
+ case ReplaceMisspelledWord_3:
+ d->adapter->replaceMisspelling(d->contextMenuData.spellCheckerSuggestions.at(2));
+ break;
+ case ReplaceMisspelledWord_4:
+ d->adapter->replaceMisspelling(d->contextMenuData.spellCheckerSuggestions.at(3));
+ break;
+#endif
default:
Q_UNREACHABLE();
}
diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h
index 3aace7563..4c6cbbaff 100644
--- a/src/webengine/api/qquickwebengineview_p.h
+++ b/src/webengine/api/qquickwebengineview_p.h
@@ -239,7 +239,13 @@ public:
RequestClose,
Unselect,
SavePage,
-
+#if !defined(QT_NO_SPELLCHECK)
+ ToggleSpellcheck,
+ ReplaceMisspelledWord_1,
+ ReplaceMisspelledWord_2,
+ ReplaceMisspelledWord_3,
+ ReplaceMisspelledWord_4,
+#endif
WebActionCount
};
Q_ENUM(WebAction)
diff --git a/src/webengine/plugin/plugin.cpp b/src/webengine/plugin/plugin.cpp
index c41bacf08..2feb3d195 100644
--- a/src/webengine/plugin/plugin.cpp
+++ b/src/webengine/plugin/plugin.cpp
@@ -76,6 +76,7 @@ public:
qmlRegisterType<QQuickWebEngineView, 3>(uri, 1, 3, "WebEngineView");
qmlRegisterType<QQuickWebEngineProfile>(uri, 1, 1, "WebEngineProfile");
qmlRegisterType<QQuickWebEngineProfile, 1>(uri, 1, 2, "WebEngineProfile");
+ qmlRegisterType<QQuickWebEngineProfile, 2>(uri, 1, 3, "WebEngineProfile");
qmlRegisterType<QQuickWebEngineScript>(uri, 1, 1, "WebEngineScript");
qmlRegisterUncreatableType<QQuickWebEngineCertificateError>(uri, 1, 1, "WebEngineCertificateError", tr("Cannot create separate instance of WebEngineCertificateError"));
qmlRegisterUncreatableType<QQuickWebEngineDownloadItem>(uri, 1, 1, "WebEngineDownloadItem",
diff --git a/src/webengine/ui_delegates_manager.cpp b/src/webengine/ui_delegates_manager.cpp
index d819c3321..a82ed0f2e 100644
--- a/src/webengine/ui_delegates_manager.cpp
+++ b/src/webengine/ui_delegates_manager.cpp
@@ -166,7 +166,8 @@ bool UIDelegatesManager::ensureComponentLoaded(ComponentType type)
if (!prop.isSignalProperty()) \
qWarning("%s is missing %s signal property.\n", qPrintable(location.toString()), qPrintable(prop.name()));
-void UIDelegatesManager::addMenuItem(MenuItemHandler *menuItemHandler, const QString &text, const QString &iconName, bool enabled)
+void UIDelegatesManager::addMenuItem(MenuItemHandler *menuItemHandler, const QString &text, const QString &iconName, bool enabled,
+ bool checkable, bool checked)
{
Q_ASSERT(menuItemHandler);
if (!ensureComponentLoaded(MenuItem))
@@ -176,6 +177,8 @@ void UIDelegatesManager::addMenuItem(MenuItemHandler *menuItemHandler, const QSt
QQmlProperty(it, QStringLiteral("text")).write(text);
QQmlProperty(it, QStringLiteral("iconName")).write(iconName);
QQmlProperty(it, QStringLiteral("enabled")).write(enabled);
+ QQmlProperty(it, QStringLiteral("checkable")).write(checkable);
+ QQmlProperty(it, QStringLiteral("checked")).write(checked);
QQmlProperty signal(it, QStringLiteral("onTriggered"));
CHECK_QML_SIGNAL_PROPERTY(signal, menuItemComponent->url());
diff --git a/src/webengine/ui_delegates_manager.h b/src/webengine/ui_delegates_manager.h
index ba3e0ff60..b63aa91f1 100644
--- a/src/webengine/ui_delegates_manager.h
+++ b/src/webengine/ui_delegates_manager.h
@@ -103,7 +103,8 @@ public:
UIDelegatesManager(QQuickWebEngineView *);
- void addMenuItem(MenuItemHandler *menuItemHandler, const QString &text, const QString &iconName = QString(), bool enabled = true);
+ void addMenuItem(MenuItemHandler *menuItemHandler, const QString &text, const QString &iconName = QString(),
+ bool enabled = true, bool checkable = false, bool checked = true);
void addMenuSeparator(QObject *menu);
QObject *addMenu(QObject *parentMenu, const QString &title, const QPoint &pos = QPoint());
QQmlContext *creationContextForComponent(QQmlComponent *);
diff --git a/src/webengine/webengine.pro b/src/webengine/webengine.pro
index 8f802d5c4..10353107a 100644
--- a/src/webengine/webengine.pro
+++ b/src/webengine/webengine.pro
@@ -55,4 +55,11 @@ isQMLTestSupportApiEnabled() {
DEFINES += ENABLE_QML_TESTSUPPORT_API
}
+no_spellcheck {
+ DEFINES += QT_NO_SPELLCHECK
+ MODULE_DEFINES += QT_NO_SPELLCHECK
+} else {
+ DEFINES += ENABLE_SPELLCHECK
+}
+
load(qt_module)
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index d68f364e4..62c1adee6 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -835,6 +835,11 @@ QAction *QWebEnginePage::action(WebAction action) const
case SavePage:
text = tr("Save &Page");
break;
+#if !defined(QT_NO_SPELLCHECK)
+ case ToggleSpellcheck:
+ text = tr("Check Spelling");
+ break;
+#endif
default:
break;
}
@@ -1015,6 +1020,17 @@ void QWebEnginePage::triggerAction(WebAction action, bool)
case SavePage:
d->adapter->save();
break;
+#if !defined(QT_NO_SPELLCHECK)
+ case ToggleSpellcheck:
+ d->adapter->toogleSpellCheckEnabled();
+ break;
+ case ReplaceMisspelledWord_1:
+ case ReplaceMisspelledWord_2:
+ case ReplaceMisspelledWord_3:
+ case ReplaceMisspelledWord_4:
+ d->adapter->replaceMisspelling(d->actions[action]->text());
+ break;
+#endif
default:
Q_UNREACHABLE();
}
@@ -1194,6 +1210,19 @@ QMenu *QWebEnginePage::createStandardContextMenu()
QMenu *menu = new QMenu(d->view);
QAction *action = 0;
WebEngineContextMenuData contextMenuData(d->m_menuData);
+
+#if !defined(QT_NO_SPELLCHECK)
+ if (contextMenuData.isEditable && !contextMenuData.spellCheckerSuggestions.isEmpty()) {
+ for (int i=0; i < contextMenuData.spellCheckerSuggestions.count() && i < 4; i++) {
+ int index = ReplaceMisspelledWord_1 + i;
+ QAction *action(QWebEnginePage::action(static_cast<QWebEnginePage::WebAction>(index)));
+ action->setText(contextMenuData.spellCheckerSuggestions.at(i));
+ menu->addAction(action);
+ }
+ menu->addSeparator();
+ }
+#endif
+
if (!contextMenuData.linkText.isEmpty() && contextMenuData.linkUrl.isValid()) {
action = QWebEnginePage::action(OpenLinkInThisWindow);
action->setText(tr("Follow Link"));
@@ -1259,6 +1288,15 @@ QMenu *QWebEnginePage::createStandardContextMenu()
if (d->isFullScreenMode())
menu->addAction(QWebEnginePage::action(ExitFullScreen));
+#if !defined(QT_NO_SPELLCHECK)
+ if (contextMenuData.isEditable) {
+ QAction* spellcheckAction(QWebEnginePage::action(ToggleSpellcheck));
+ menu->addAction(spellcheckAction);
+ spellcheckAction->setCheckable(true);
+ spellcheckAction->setChecked(contextMenuData.isSpellCheckerEnabled);
+ }
+#endif
+
return menu;
}
diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h
index d8bdec303..be9f08ad1 100644
--- a/src/webenginewidgets/api/qwebenginepage.h
+++ b/src/webenginewidgets/api/qwebenginepage.h
@@ -118,7 +118,13 @@ public:
RequestClose,
Unselect,
SavePage,
-
+#if !defined(QT_NO_SPELLCHECK)
+ ToggleSpellcheck,
+ ReplaceMisspelledWord_1,
+ ReplaceMisspelledWord_2,
+ ReplaceMisspelledWord_3,
+ ReplaceMisspelledWord_4,
+#endif
WebActionCount
};
diff --git a/src/webenginewidgets/api/qwebengineprofile.cpp b/src/webenginewidgets/api/qwebengineprofile.cpp
index 69d96f925..8a6523a1b 100644
--- a/src/webenginewidgets/api/qwebengineprofile.cpp
+++ b/src/webenginewidgets/api/qwebengineprofile.cpp
@@ -530,6 +530,70 @@ QWebEngineProfile *QWebEngineProfile::defaultProfile()
return profile;
}
+#if !defined(QT_NO_SPELLCHECK)
+/*!
+ \since 5.7
+
+ Returns the subset of \a acceptLanguages supported by the spell checker.
+
+ Checks whether the spell checker dictionary is installed for the specified
+ language from the \a acceptLanguages list. If the dictionary file is missing
+ or corrupted, the language is removed from the returned list.
+
+ \sa setSpellCheckLanguage()
+*/
+QStringList QWebEngineProfile::spellCheckLanguages(const QStringList &acceptLanguages)
+{
+ const Q_D(QWebEngineProfile);
+ return d->browserContext()->spellCheckLanguages(acceptLanguages);
+}
+
+/*!
+ \since 5.7
+
+ Sets the current \a language for the spell checker.
+*/
+void QWebEngineProfile::setSpellCheckLanguage(const QString &language)
+{
+ Q_D(QWebEngineProfile);
+ d->browserContext()->setSpellCheckLanguage(language);
+}
+
+/*!
+ \since 5.7
+
+ Returns the language used by the spell checker.
+*/
+QString QWebEngineProfile::spellCheckLanguage() const
+{
+ const Q_D(QWebEngineProfile);
+ return d->browserContext()->spellCheckLanguage();
+}
+
+/*!
+ \since 5.7
+
+ 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.7
+
+ 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();
+}
+#endif
+
/*!
Returns the default settings for all pages in this profile.
*/
diff --git a/src/webenginewidgets/api/qwebengineprofile.h b/src/webenginewidgets/api/qwebengineprofile.h
index 22a913fb2..1a9bfe43a 100644
--- a/src/webenginewidgets/api/qwebengineprofile.h
+++ b/src/webenginewidgets/api/qwebengineprofile.h
@@ -121,6 +121,14 @@ public:
void clearHttpCache();
+#if !defined(QT_NO_SPELLCHECK)
+ QStringList spellCheckLanguages(const QStringList &acceptLanguages);
+ void setSpellCheckLanguage(const QString &language);
+ QString spellCheckLanguage() const;
+ void setSpellCheckEnabled(bool enabled);
+ bool isSpellCheckEnabled() const;
+#endif
+
static QWebEngineProfile *defaultProfile();
Q_SIGNALS:
diff --git a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
index d3c540016..3b25bac76 100644
--- a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
@@ -125,6 +125,11 @@
\value Unselect Clear the current selection. (Added in Qt 5.7)
\value SavePage Save the current page to disk. MHTML is the default format that is used to store
the web page on disk. (Added in Qt 5.7)
+ \value ToggleSpellcheck Enable or disable the spell checker. (Added in Qt 5.7)
+ \value ReplaceMisspelledWord_1 Replace a misspelled word. (Added in Qt 5.7)
+ \value ReplaceMisspelledWord_2 Replace a misspelled word. (Added in Qt 5.7)
+ \value ReplaceMisspelledWord_3 Replace a misspelled word. (Added in Qt 5.7)
+ \value ReplaceMisspelledWord_4 Replace a misspelled word. (Added in Qt 5.7)
\omitvalue WebActionCount
diff --git a/src/webenginewidgets/webenginewidgets.pro b/src/webenginewidgets/webenginewidgets.pro
index 5687bffaf..3b6b843b6 100644
--- a/src/webenginewidgets/webenginewidgets.pro
+++ b/src/webenginewidgets/webenginewidgets.pro
@@ -46,4 +46,11 @@ HEADERS = \
DEFINES += QT_UI_DELEGATES
}
+no_spellcheck {
+ DEFINES += QT_NO_SPELLCHECK
+ MODULE_DEFINES += QT_NO_SPELLCHECK
+} else {
+ DEFINES += ENABLE_SPELLCHECK
+}
+
load(qt_module)