1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/renderer_context_menu/spellchecker_submenu_observer.h" 6 7#include "base/command_line.h" 8#include "base/logging.h" 9#include "base/prefs/pref_member.h" 10#include "base/prefs/pref_service.h" 11#include "chrome/app/chrome_command_ids.h" 12#include "chrome/browser/browser_process.h" 13#include "chrome/browser/renderer_context_menu/render_view_context_menu.h" 14#include "chrome/browser/spellchecker/spellcheck_service.h" 15#include "chrome/common/chrome_switches.h" 16#include "chrome/common/pref_names.h" 17#include "chrome/common/spellcheck_messages.h" 18#include "chrome/grit/generated_resources.h" 19#include "content/public/browser/render_view_host.h" 20#include "content/public/browser/render_widget_host_view.h" 21#include "extensions/browser/view_type_utils.h" 22#include "ui/base/l10n/l10n_util.h" 23#include "ui/base/models/simple_menu_model.h" 24 25using content::BrowserThread; 26 27SpellCheckerSubMenuObserver::SpellCheckerSubMenuObserver( 28 RenderViewContextMenuProxy* proxy, 29 ui::SimpleMenuModel::Delegate* delegate, 30 int group) 31 : proxy_(proxy), 32 submenu_model_(delegate), 33 language_group_(group), 34 language_selected_(0) { 35 DCHECK(proxy_); 36} 37 38SpellCheckerSubMenuObserver::~SpellCheckerSubMenuObserver() { 39} 40 41void SpellCheckerSubMenuObserver::InitMenu( 42 const content::ContextMenuParams& params) { 43 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 44 45 // Add available spell-checker languages to the sub menu. 46 content::BrowserContext* browser_context = proxy_->GetBrowserContext(); 47 DCHECK(browser_context); 48 language_selected_ = 49 SpellcheckService::GetSpellCheckLanguages(browser_context, &languages_); 50 DCHECK(languages_.size() < 51 IDC_SPELLCHECK_LANGUAGES_LAST - IDC_SPELLCHECK_LANGUAGES_FIRST); 52 const std::string app_locale = g_browser_process->GetApplicationLocale(); 53 for (size_t i = 0; i < languages_.size(); ++i) { 54 base::string16 display_name( 55 l10n_util::GetDisplayNameForLocale(languages_[i], app_locale, true)); 56 submenu_model_.AddRadioItem(IDC_SPELLCHECK_LANGUAGES_FIRST + i, 57 display_name, 58 language_group_); 59 } 60 61 // Add an item that opens the 'fonts and languages options' page. 62 submenu_model_.AddSeparator(ui::NORMAL_SEPARATOR); 63 submenu_model_.AddItemWithStringId( 64 IDC_CONTENT_CONTEXT_LANGUAGE_SETTINGS, 65 IDS_CONTENT_CONTEXT_LANGUAGE_SETTINGS); 66 67 // Add a 'Check spelling while typing' item in the sub menu. 68 submenu_model_.AddCheckItem( 69 IDC_CHECK_SPELLING_WHILE_TYPING, 70 l10n_util::GetStringUTF16( 71 IDS_CONTENT_CONTEXT_CHECK_SPELLING_WHILE_TYPING)); 72 73 // Add a check item "Ask Google for spelling suggestions" item. (This class 74 // does not handle this item because the SpellingMenuObserver class handles it 75 // on behalf of this class.) 76 submenu_model_.AddCheckItem(IDC_CONTENT_CONTEXT_SPELLING_TOGGLE, 77 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_SPELLING_ASK_GOOGLE)); 78 79 // Add a check item "Automatically correct spelling". 80 const CommandLine* command_line = CommandLine::ForCurrentProcess(); 81 if (command_line->HasSwitch(switches::kEnableSpellingAutoCorrect)) { 82 submenu_model_.AddCheckItem(IDC_CONTENT_CONTEXT_AUTOCORRECT_SPELLING_TOGGLE, 83 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_SPELLING_AUTOCORRECT)); 84 } 85 86 proxy_->AddSubMenu( 87 IDC_SPELLCHECK_MENU, 88 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_SPELLCHECK_MENU), 89 &submenu_model_); 90} 91 92bool SpellCheckerSubMenuObserver::IsCommandIdSupported(int command_id) { 93 // Allow Spell Check language items on sub menu for text area context menu. 94 if (command_id >= IDC_SPELLCHECK_LANGUAGES_FIRST && 95 command_id < IDC_SPELLCHECK_LANGUAGES_LAST) { 96 return true; 97 } 98 99 switch (command_id) { 100 case IDC_CONTENT_CONTEXT_LANGUAGE_SETTINGS: 101 // Return false so RenderViewContextMenu can handle this item because it 102 // is hard for this class to handle it. 103 return false; 104 105 case IDC_CHECK_SPELLING_WHILE_TYPING: 106 case IDC_SPELLPANEL_TOGGLE: 107 case IDC_SPELLCHECK_MENU: 108 return true; 109 } 110 111 return false; 112} 113 114bool SpellCheckerSubMenuObserver::IsCommandIdChecked(int command_id) { 115 DCHECK(IsCommandIdSupported(command_id)); 116 117 if (command_id >= IDC_SPELLCHECK_LANGUAGES_FIRST && 118 command_id < IDC_SPELLCHECK_LANGUAGES_LAST) { 119 return language_selected_ == command_id - IDC_SPELLCHECK_LANGUAGES_FIRST; 120 } 121 122 // Check box for 'Check Spelling while typing'. 123 if (command_id == IDC_CHECK_SPELLING_WHILE_TYPING) { 124 Profile* profile = Profile::FromBrowserContext(proxy_->GetBrowserContext()); 125 DCHECK(profile); 126 return profile->GetPrefs()->GetBoolean(prefs::kEnableContinuousSpellcheck); 127 } 128 129 return false; 130} 131 132bool SpellCheckerSubMenuObserver::IsCommandIdEnabled(int command_id) { 133 DCHECK(IsCommandIdSupported(command_id)); 134 135 Profile* profile = Profile::FromBrowserContext(proxy_->GetBrowserContext()); 136 DCHECK(profile); 137 const PrefService* pref = profile->GetPrefs(); 138 if (command_id >= IDC_SPELLCHECK_LANGUAGES_FIRST && 139 command_id < IDC_SPELLCHECK_LANGUAGES_LAST) { 140 return pref->GetBoolean(prefs::kEnableContinuousSpellcheck); 141 } 142 143 switch (command_id) { 144 case IDC_CHECK_SPELLING_WHILE_TYPING: 145 case IDC_SPELLPANEL_TOGGLE: 146 case IDC_SPELLCHECK_MENU: 147 return true; 148 } 149 150 return false; 151} 152 153void SpellCheckerSubMenuObserver::ExecuteCommand(int command_id) { 154 DCHECK(IsCommandIdSupported(command_id)); 155 156 // Check to see if one of the spell check language ids have been clicked. 157 Profile* profile = Profile::FromBrowserContext(proxy_->GetBrowserContext()); 158 DCHECK(profile); 159 if (command_id >= IDC_SPELLCHECK_LANGUAGES_FIRST && 160 command_id < IDC_SPELLCHECK_LANGUAGES_LAST) { 161 const size_t language = command_id - IDC_SPELLCHECK_LANGUAGES_FIRST; 162 if (profile && language < languages_.size()) { 163 StringPrefMember dictionary_language; 164 dictionary_language.Init(prefs::kSpellCheckDictionary, 165 profile->GetPrefs()); 166 dictionary_language.SetValue(languages_[language]); 167 } 168 return; 169 } 170 171 switch (command_id) { 172 case IDC_CHECK_SPELLING_WHILE_TYPING: 173 profile->GetPrefs()->SetBoolean( 174 prefs::kEnableContinuousSpellcheck, 175 !profile->GetPrefs()->GetBoolean(prefs::kEnableContinuousSpellcheck)); 176 break; 177 } 178} 179