1 // Copyright (c) 2012 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/tab_contents/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/spellchecker/spellcheck_service.h" 14 #include "chrome/browser/tab_contents/render_view_context_menu.h" 15 #include "chrome/common/chrome_switches.h" 16 #include "chrome/common/pref_names.h" 17 #include "chrome/common/spellcheck_messages.h" 18 #include "content/public/browser/render_view_host.h" 19 #include "content/public/browser/render_widget_host_view.h" 20 #include "extensions/browser/view_type_utils.h" 21 #include "grit/generated_resources.h" 22 #include "ui/base/l10n/l10n_util.h" 23 #include "ui/base/models/simple_menu_model.h" 24 25 using content::BrowserThread; 26 27 SpellCheckerSubMenuObserver::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 38 SpellCheckerSubMenuObserver::~SpellCheckerSubMenuObserver() { 39 } 40 41 void 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 Profile* profile = proxy_->GetProfile(); 47 DCHECK(profile); 48 language_selected_ = 49 SpellcheckService::GetSpellCheckLanguages(profile, &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 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 #if defined(TOOLKIT_GTK) 77 extensions::ViewType view_type = 78 extensions::GetViewType(proxy_->GetWebContents()); 79 if (view_type != extensions::VIEW_TYPE_PANEL) { 80 #endif 81 submenu_model_.AddCheckItem(IDC_CONTENT_CONTEXT_SPELLING_TOGGLE, 82 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_SPELLING_ASK_GOOGLE)); 83 #if defined(TOOLKIT_GTK) 84 } 85 #endif 86 87 // Add a check item "Automatically correct spelling". 88 const CommandLine* command_line = CommandLine::ForCurrentProcess(); 89 if (command_line->HasSwitch(switches::kEnableSpellingAutoCorrect)) { 90 submenu_model_.AddCheckItem(IDC_CONTENT_CONTEXT_AUTOCORRECT_SPELLING_TOGGLE, 91 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_SPELLING_AUTOCORRECT)); 92 } 93 94 proxy_->AddSubMenu( 95 IDC_SPELLCHECK_MENU, 96 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_SPELLCHECK_MENU), 97 &submenu_model_); 98 } 99 100 bool SpellCheckerSubMenuObserver::IsCommandIdSupported(int command_id) { 101 // Allow Spell Check language items on sub menu for text area context menu. 102 if (command_id >= IDC_SPELLCHECK_LANGUAGES_FIRST && 103 command_id < IDC_SPELLCHECK_LANGUAGES_LAST) { 104 return true; 105 } 106 107 switch (command_id) { 108 case IDC_CONTENT_CONTEXT_LANGUAGE_SETTINGS: 109 // Return false so RenderViewContextMenu can handle this item because it 110 // is hard for this class to handle it. 111 return false; 112 113 case IDC_CHECK_SPELLING_WHILE_TYPING: 114 case IDC_SPELLPANEL_TOGGLE: 115 case IDC_SPELLCHECK_MENU: 116 return true; 117 } 118 119 return false; 120 } 121 122 bool SpellCheckerSubMenuObserver::IsCommandIdChecked(int command_id) { 123 DCHECK(IsCommandIdSupported(command_id)); 124 125 if (command_id >= IDC_SPELLCHECK_LANGUAGES_FIRST && 126 command_id < IDC_SPELLCHECK_LANGUAGES_LAST) { 127 return language_selected_ == command_id - IDC_SPELLCHECK_LANGUAGES_FIRST; 128 } 129 130 // Check box for 'Check Spelling while typing'. 131 if (command_id == IDC_CHECK_SPELLING_WHILE_TYPING) { 132 Profile* profile = proxy_->GetProfile(); 133 DCHECK(profile); 134 return profile->GetPrefs()->GetBoolean(prefs::kEnableContinuousSpellcheck); 135 } 136 137 return false; 138 } 139 140 bool SpellCheckerSubMenuObserver::IsCommandIdEnabled(int command_id) { 141 DCHECK(IsCommandIdSupported(command_id)); 142 143 Profile* profile = proxy_->GetProfile(); 144 DCHECK(profile); 145 const PrefService* pref = profile->GetPrefs(); 146 if (command_id >= IDC_SPELLCHECK_LANGUAGES_FIRST && 147 command_id < IDC_SPELLCHECK_LANGUAGES_LAST) { 148 return pref->GetBoolean(prefs::kEnableContinuousSpellcheck); 149 } 150 151 switch (command_id) { 152 case IDC_CHECK_SPELLING_WHILE_TYPING: 153 case IDC_SPELLPANEL_TOGGLE: 154 case IDC_SPELLCHECK_MENU: 155 return true; 156 } 157 158 return false; 159 } 160 161 void SpellCheckerSubMenuObserver::ExecuteCommand(int command_id) { 162 DCHECK(IsCommandIdSupported(command_id)); 163 164 // Check to see if one of the spell check language ids have been clicked. 165 Profile* profile = proxy_->GetProfile(); 166 DCHECK(profile); 167 if (command_id >= IDC_SPELLCHECK_LANGUAGES_FIRST && 168 command_id < IDC_SPELLCHECK_LANGUAGES_LAST) { 169 const size_t language = command_id - IDC_SPELLCHECK_LANGUAGES_FIRST; 170 if (profile && language < languages_.size()) { 171 StringPrefMember dictionary_language; 172 dictionary_language.Init(prefs::kSpellCheckDictionary, 173 profile->GetPrefs()); 174 dictionary_language.SetValue(languages_[language]); 175 } 176 return; 177 } 178 179 switch (command_id) { 180 case IDC_CHECK_SPELLING_WHILE_TYPING: 181 profile->GetPrefs()->SetBoolean( 182 prefs::kEnableContinuousSpellcheck, 183 !profile->GetPrefs()->GetBoolean(prefs::kEnableContinuousSpellcheck)); 184 break; 185 } 186 } 187