blob: 5f743ef08f54d1fc53fcb49e57c38be44a3dd64b [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/renderer_context_menu/spelling_options_submenu_observer.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_context_menu/render_view_context_menu.h"
#include "chrome/browser/spellchecker/spellcheck_service.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/grit/generated_resources.h"
#include "components/prefs/pref_member.h"
#include "components/prefs/pref_service.h"
#include "components/renderer_context_menu/render_view_context_menu_proxy.h"
#include "components/spellcheck/browser/pref_names.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/models/menu_separator_types.h"
using content::BrowserThread;
SpellingOptionsSubMenuObserver::SpellingOptionsSubMenuObserver(
RenderViewContextMenuProxy* proxy,
ui::SimpleMenuModel::Delegate* delegate,
int group_id)
: proxy_(proxy),
submenu_model_(delegate),
language_group_id_(group_id),
num_selected_dictionaries_(0) {
if (proxy_ && proxy_->GetBrowserContext()) {
Profile* profile = Profile::FromBrowserContext(proxy_->GetBrowserContext());
use_spelling_service_.Init(spellcheck::prefs::kSpellCheckUseSpellingService,
profile->GetPrefs());
}
DCHECK(proxy_);
}
SpellingOptionsSubMenuObserver::~SpellingOptionsSubMenuObserver() {}
void SpellingOptionsSubMenuObserver::InitMenu(
const content::ContextMenuParams& params) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// Add available spell-checker languages to the sub menu.
content::BrowserContext* browser_context = proxy_->GetBrowserContext();
DCHECK(browser_context);
SpellcheckService::GetDictionaries(browser_context, &dictionaries_);
DCHECK(dictionaries_.size() <
IDC_SPELLCHECK_LANGUAGES_LAST - IDC_SPELLCHECK_LANGUAGES_FIRST);
const std::string app_locale = g_browser_process->GetApplicationLocale();
if (dictionaries_.size() > 1) {
submenu_model_.AddRadioItemWithStringId(
IDC_SPELLCHECK_MULTI_LINGUAL,
IDS_CONTENT_CONTEXT_SPELLCHECK_MULTI_LINGUAL, language_group_id_);
}
const size_t kMaxLanguages = static_cast<size_t>(
IDC_SPELLCHECK_LANGUAGES_FIRST - IDC_SPELLCHECK_LANGUAGES_LAST);
for (size_t i = 0; i < dictionaries_.size() && i < kMaxLanguages; ++i) {
submenu_model_.AddRadioItem(
IDC_SPELLCHECK_LANGUAGES_FIRST + i,
l10n_util::GetDisplayNameForLocale(dictionaries_[i].language,
app_locale, true),
language_group_id_);
if (dictionaries_[i].used_for_spellcheck)
++num_selected_dictionaries_;
}
// Add an item that opens the 'Settings - Languages' page. This item is
// handled in RenderViewContextMenu.
submenu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_LANGUAGE_SETTINGS,
IDS_CONTENT_CONTEXT_LANGUAGE_SETTINGS);
submenu_model_.AddSeparator(ui::NORMAL_SEPARATOR);
if (num_selected_dictionaries_ > 0) {
// Add a 'Check spelling while typing' item in the sub menu.
submenu_model_.AddCheckItem(
IDC_CHECK_SPELLING_WHILE_TYPING,
l10n_util::GetStringUTF16(
IDS_CONTENT_CONTEXT_CHECK_SPELLING_WHILE_TYPING));
}
// Add a check item 'Ask Google for spelling suggestions'. This item is
// handled in SpellingMenuObserver.
RenderViewContextMenu::AddSpellCheckServiceItem(
&submenu_model_, use_spelling_service_.GetValue());
proxy_->AddSubMenu(
IDC_SPELLCHECK_MENU,
l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_SPELLCHECK_MENU),
&submenu_model_);
}
bool SpellingOptionsSubMenuObserver::IsCommandIdSupported(int command_id) {
// Allow Spell Check language items on sub menu for text area context menu.
if (command_id >= IDC_SPELLCHECK_LANGUAGES_FIRST &&
command_id < IDC_SPELLCHECK_LANGUAGES_LAST) {
DCHECK_GT(IDC_SPELLCHECK_LANGUAGES_FIRST + dictionaries_.size(),
static_cast<size_t>(command_id));
return true;
}
switch (command_id) {
case IDC_CHECK_SPELLING_WHILE_TYPING:
case IDC_SPELLCHECK_MENU:
case IDC_SPELLCHECK_MULTI_LINGUAL:
return true;
}
return false;
}
bool SpellingOptionsSubMenuObserver::IsCommandIdChecked(int command_id) {
DCHECK(IsCommandIdSupported(command_id));
if (command_id == IDC_SPELLCHECK_MULTI_LINGUAL)
return num_selected_dictionaries_ == dictionaries_.size();
if (command_id >= IDC_SPELLCHECK_LANGUAGES_FIRST &&
command_id < IDC_SPELLCHECK_LANGUAGES_LAST) {
if (num_selected_dictionaries_ == dictionaries_.size())
return dictionaries_.size() == 1;
size_t dictionary_index =
static_cast<size_t>(command_id - IDC_SPELLCHECK_LANGUAGES_FIRST);
return dictionaries_[dictionary_index].used_for_spellcheck;
}
// Check box for 'Check Spelling while typing'.
if (command_id == IDC_CHECK_SPELLING_WHILE_TYPING) {
Profile* profile = Profile::FromBrowserContext(proxy_->GetBrowserContext());
return profile->GetPrefs()->GetBoolean(
spellcheck::prefs::kSpellCheckEnable);
}
return false;
}
bool SpellingOptionsSubMenuObserver::IsCommandIdEnabled(int command_id) {
DCHECK(IsCommandIdSupported(command_id));
Profile* profile = Profile::FromBrowserContext(proxy_->GetBrowserContext());
DCHECK(profile);
const PrefService* pref = profile->GetPrefs();
if ((command_id >= IDC_SPELLCHECK_LANGUAGES_FIRST &&
command_id < IDC_SPELLCHECK_LANGUAGES_LAST) ||
command_id == IDC_SPELLCHECK_MULTI_LINGUAL) {
return pref->GetBoolean(spellcheck::prefs::kSpellCheckEnable);
}
switch (command_id) {
case IDC_CHECK_SPELLING_WHILE_TYPING:
return !pref->FindPreference(spellcheck::prefs::kSpellCheckEnable)
->IsManaged();
case IDC_SPELLCHECK_MENU:
return true;
}
return false;
}
void SpellingOptionsSubMenuObserver::ExecuteCommand(int command_id) {
DCHECK(IsCommandIdSupported(command_id));
// Check to see if one of the spell check language ids have been clicked.
Profile* profile = Profile::FromBrowserContext(proxy_->GetBrowserContext());
DCHECK(profile);
if (command_id >= IDC_SPELLCHECK_LANGUAGES_FIRST &&
static_cast<size_t>(command_id) <
IDC_SPELLCHECK_LANGUAGES_FIRST + dictionaries_.size()) {
size_t dictionary_index =
static_cast<size_t>(command_id - IDC_SPELLCHECK_LANGUAGES_FIRST);
StringListPrefMember dictionaries_pref;
dictionaries_pref.Init(spellcheck::prefs::kSpellCheckDictionaries,
profile->GetPrefs());
dictionaries_pref.SetValue({dictionaries_[dictionary_index].language});
return;
}
switch (command_id) {
case IDC_CHECK_SPELLING_WHILE_TYPING:
profile->GetPrefs()->SetBoolean(
spellcheck::prefs::kSpellCheckEnable,
!profile->GetPrefs()->GetBoolean(
spellcheck::prefs::kSpellCheckEnable));
break;
case IDC_SPELLCHECK_MULTI_LINGUAL:
StringListPrefMember dictionaries_pref;
dictionaries_pref.Init(spellcheck::prefs::kSpellCheckDictionaries,
profile->GetPrefs());
std::vector<std::string> all_languages;
for (const auto& dictionary : dictionaries_)
all_languages.push_back(dictionary.language);
dictionaries_pref.SetValue(all_languages);
break;
}
}