Home | History | Annotate | Download | only in tab_contents
      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