Home | History | Annotate | Download | only in options
      1 // Copyright (c) 2011 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/ui/webui/options/search_engine_manager_handler.h"
      6 
      7 #include "base/callback.h"
      8 #include "base/string_number_conversions.h"
      9 #include "base/utf_string_conversions.h"
     10 #include "base/values.h"
     11 #include "chrome/browser/profiles/profile.h"
     12 #include "chrome/browser/search_engines/template_url.h"
     13 #include "chrome/browser/search_engines/template_url_model.h"
     14 #include "chrome/browser/ui/search_engines/keyword_editor_controller.h"
     15 #include "chrome/browser/ui/search_engines/template_url_table_model.h"
     16 #include "chrome/common/url_constants.h"
     17 #include "grit/generated_resources.h"
     18 #include "grit/locale_settings.h"
     19 #include "ui/base/l10n/l10n_util.h"
     20 
     21 namespace {
     22 
     23 enum EngineInfoIndexes {
     24   ENGINE_NAME,
     25   ENGINE_KEYWORD,
     26   ENGINE_URL,
     27 };
     28 
     29 };  // namespace
     30 
     31 SearchEngineManagerHandler::SearchEngineManagerHandler() {
     32 }
     33 
     34 SearchEngineManagerHandler::~SearchEngineManagerHandler() {
     35   if (list_controller_.get() && list_controller_->table_model())
     36     list_controller_->table_model()->SetObserver(NULL);
     37 }
     38 
     39 void SearchEngineManagerHandler::Initialize() {
     40   list_controller_.reset(new KeywordEditorController(web_ui_->GetProfile()));
     41   if (list_controller_.get()) {
     42     list_controller_->table_model()->SetObserver(this);
     43     OnModelChanged();
     44   }
     45 }
     46 
     47 void SearchEngineManagerHandler::GetLocalizedValues(
     48     DictionaryValue* localized_strings) {
     49   DCHECK(localized_strings);
     50 
     51   RegisterTitle(localized_strings, "searchEngineManagerPage",
     52                 IDS_SEARCH_ENGINES_EDITOR_WINDOW_TITLE);
     53   localized_strings->SetString("defaultSearchEngineListTitle",
     54       l10n_util::GetStringUTF16(IDS_SEARCH_ENGINES_EDITOR_MAIN_SEPARATOR));
     55   localized_strings->SetString("otherSearchEngineListTitle",
     56       l10n_util::GetStringUTF16(IDS_SEARCH_ENGINES_EDITOR_OTHER_SEPARATOR));
     57   localized_strings->SetString("searchEngineTableNameHeader",
     58       l10n_util::GetStringUTF16(IDS_SEARCH_ENGINES_EDITOR_DESCRIPTION_COLUMN));
     59   localized_strings->SetString("searchEngineTableKeywordHeader",
     60       l10n_util::GetStringUTF16(IDS_SEARCH_ENGINES_EDITOR_KEYWORD_COLUMN));
     61   localized_strings->SetString("searchEngineTableURLHeader",
     62       l10n_util::GetStringUTF16(IDS_SEARCH_ENGINES_EDITOR_EDIT_BUTTON));
     63   localized_strings->SetString("makeDefaultSearchEngineButton",
     64       l10n_util::GetStringUTF16(IDS_SEARCH_ENGINES_EDITOR_MAKE_DEFAULT_BUTTON));
     65   localized_strings->SetString("searchEngineTableNamePlaceholder",
     66       l10n_util::GetStringUTF16(IDS_SEARCH_ENGINE_ADD_NEW_NAME_PLACEHOLDER));
     67   localized_strings->SetString("searchEngineTableKeywordPlaceholder",
     68       l10n_util::GetStringUTF16(IDS_SEARCH_ENGINE_ADD_NEW_KEYWORD_PLACEHOLDER));
     69   localized_strings->SetString("searchEngineTableURLPlaceholder",
     70       l10n_util::GetStringUTF16(IDS_SEARCH_ENGINE_ADD_NEW_URL_PLACEHOLDER));
     71   localized_strings->SetString("editSearchEngineInvalidTitleToolTip",
     72       l10n_util::GetStringUTF16(IDS_SEARCH_ENGINES_INVALID_TITLE_TT));
     73   localized_strings->SetString("editSearchEngineInvalidKeywordToolTip",
     74       l10n_util::GetStringUTF16(IDS_SEARCH_ENGINES_INVALID_KEYWORD_TT));
     75   localized_strings->SetString("editSearchEngineInvalidURLToolTip",
     76       l10n_util::GetStringUTF16(IDS_SEARCH_ENGINES_INVALID_URL_TT));
     77 }
     78 
     79 void SearchEngineManagerHandler::RegisterMessages() {
     80   web_ui_->RegisterMessageCallback(
     81       "managerSetDefaultSearchEngine",
     82       NewCallback(this, &SearchEngineManagerHandler::SetDefaultSearchEngine));
     83   web_ui_->RegisterMessageCallback(
     84       "removeSearchEngine",
     85       NewCallback(this, &SearchEngineManagerHandler::RemoveSearchEngine));
     86   web_ui_->RegisterMessageCallback(
     87       "editSearchEngine",
     88       NewCallback(this, &SearchEngineManagerHandler::EditSearchEngine));
     89   web_ui_->RegisterMessageCallback(
     90       "checkSearchEngineInfoValidity",
     91       NewCallback(this,
     92                   &SearchEngineManagerHandler::CheckSearchEngineInfoValidity));
     93   web_ui_->RegisterMessageCallback(
     94       "searchEngineEditCancelled",
     95       NewCallback(this, &SearchEngineManagerHandler::EditCancelled));
     96   web_ui_->RegisterMessageCallback(
     97       "searchEngineEditCompleted",
     98       NewCallback(this, &SearchEngineManagerHandler::EditCompleted));
     99 }
    100 
    101 void SearchEngineManagerHandler::OnModelChanged() {
    102   if (!list_controller_->loaded())
    103     return;
    104 
    105   // Find the default engine.
    106   const TemplateURL* default_engine =
    107       list_controller_->url_model()->GetDefaultSearchProvider();
    108   int default_index = list_controller_->table_model()->IndexOfTemplateURL(
    109       default_engine);
    110 
    111   // Build the first list (default search engine options).
    112   ListValue defaults_list;
    113   int last_default_engine_index =
    114       list_controller_->table_model()->last_search_engine_index();
    115   for (int i = 0; i < last_default_engine_index; ++i) {
    116     defaults_list.Append(CreateDictionaryForEngine(i, i == default_index));
    117   }
    118 
    119   // Build the second list (other search templates).
    120   ListValue others_list;
    121   if (last_default_engine_index < 0)
    122     last_default_engine_index = 0;
    123   int engine_count = list_controller_->table_model()->RowCount();
    124   for (int i = last_default_engine_index; i < engine_count; ++i) {
    125     others_list.Append(CreateDictionaryForEngine(i, i == default_index));
    126   }
    127 
    128   web_ui_->CallJavascriptFunction("SearchEngineManager.updateSearchEngineList",
    129                                   defaults_list, others_list);
    130 }
    131 
    132 void SearchEngineManagerHandler::OnItemsChanged(int start, int length) {
    133   OnModelChanged();
    134 }
    135 
    136 void SearchEngineManagerHandler::OnItemsAdded(int start, int length) {
    137   OnModelChanged();
    138 }
    139 
    140 void SearchEngineManagerHandler::OnItemsRemoved(int start, int length) {
    141   OnModelChanged();
    142 }
    143 
    144 DictionaryValue* SearchEngineManagerHandler::CreateDictionaryForEngine(
    145     int index, bool is_default) {
    146   TemplateURLTableModel* table_model = list_controller_->table_model();
    147   const TemplateURL* template_url = list_controller_->GetTemplateURL(index);
    148 
    149   DictionaryValue* dict = new DictionaryValue();
    150   dict->SetString("name",  template_url->short_name());
    151   dict->SetString("displayName", table_model->GetText(
    152     index, IDS_SEARCH_ENGINES_EDITOR_DESCRIPTION_COLUMN));
    153   dict->SetString("keyword", table_model->GetText(
    154     index, IDS_SEARCH_ENGINES_EDITOR_KEYWORD_COLUMN));
    155   dict->SetString("url", template_url->url()->DisplayURL());
    156   dict->SetBoolean("urlLocked", template_url->prepopulate_id() > 0);
    157   GURL icon_url = template_url->GetFaviconURL();
    158   if (icon_url.is_valid())
    159     dict->SetString("iconURL", icon_url.spec());
    160   dict->SetString("modelIndex", base::IntToString(index));
    161 
    162   if (list_controller_->CanRemove(template_url))
    163     dict->SetString("canBeRemoved", "1");
    164   if (list_controller_->CanMakeDefault(template_url))
    165     dict->SetString("canBeDefault", "1");
    166   if (is_default)
    167     dict->SetString("default", "1");
    168 
    169   return dict;
    170 }
    171 
    172 void SearchEngineManagerHandler::SetDefaultSearchEngine(const ListValue* args) {
    173   int index;
    174   if (!ExtractIntegerValue(args, &index)) {
    175     NOTREACHED();
    176     return;
    177   }
    178   if (index < 0 || index >= list_controller_->table_model()->RowCount())
    179     return;
    180 
    181   list_controller_->MakeDefaultTemplateURL(index);
    182 }
    183 
    184 void SearchEngineManagerHandler::RemoveSearchEngine(const ListValue* args) {
    185   int index;
    186   if (!ExtractIntegerValue(args, &index)) {
    187     NOTREACHED();
    188     return;
    189   }
    190   if (index < 0 || index >= list_controller_->table_model()->RowCount())
    191     return;
    192 
    193   if (list_controller_->CanRemove(list_controller_->GetTemplateURL(index)))
    194     list_controller_->RemoveTemplateURL(index);
    195 }
    196 
    197 void SearchEngineManagerHandler::EditSearchEngine(const ListValue* args) {
    198   int index;
    199   if (!ExtractIntegerValue(args, &index)) {
    200     NOTREACHED();
    201     return;
    202   }
    203   // Allow -1, which means we are adding a new engine.
    204   if (index < -1 || index >= list_controller_->table_model()->RowCount())
    205     return;
    206 
    207   const TemplateURL* edit_url = NULL;
    208   if (index != -1)
    209     edit_url = list_controller_->GetTemplateURL(index);
    210   edit_controller_.reset(
    211       new EditSearchEngineController(edit_url, this, web_ui_->GetProfile()));
    212 }
    213 
    214 void SearchEngineManagerHandler::OnEditedKeyword(
    215     const TemplateURL* template_url,
    216     const string16& title,
    217     const string16& keyword,
    218     const std::string& url) {
    219   if (template_url) {
    220     list_controller_->ModifyTemplateURL(template_url, title, keyword, url);
    221   } else {
    222     list_controller_->AddTemplateURL(title, keyword, url);
    223   }
    224   edit_controller_.reset();
    225 }
    226 
    227 void SearchEngineManagerHandler::CheckSearchEngineInfoValidity(
    228     const ListValue* args)
    229 {
    230   if (!edit_controller_.get())
    231     return;
    232   string16 name;
    233   string16 keyword;
    234   std::string url;
    235   std::string modelIndex;
    236   if (!args->GetString(ENGINE_NAME, &name) ||
    237       !args->GetString(ENGINE_KEYWORD, &keyword) ||
    238       !args->GetString(ENGINE_URL, &url) ||
    239       !args->GetString(3, &modelIndex)) {
    240     NOTREACHED();
    241     return;
    242   }
    243 
    244   DictionaryValue validity;
    245   validity.SetBoolean("name", edit_controller_->IsTitleValid(name));
    246   validity.SetBoolean("keyword", edit_controller_->IsKeywordValid(keyword));
    247   validity.SetBoolean("url", edit_controller_->IsURLValid(url));
    248   StringValue indexValue(modelIndex);
    249   web_ui_->CallJavascriptFunction("SearchEngineManager.validityCheckCallback",
    250                                   validity, indexValue);
    251 }
    252 
    253 void SearchEngineManagerHandler::EditCancelled(const ListValue* args) {
    254   if (!edit_controller_.get())
    255     return;
    256   edit_controller_->CleanUpCancelledAdd();
    257   edit_controller_.reset();
    258 }
    259 
    260 void SearchEngineManagerHandler::EditCompleted(const ListValue* args) {
    261   if (!edit_controller_.get())
    262     return;
    263   string16 name;
    264   string16 keyword;
    265   std::string url;
    266   if (!args->GetString(ENGINE_NAME, &name) ||
    267       !args->GetString(ENGINE_KEYWORD, &keyword) ||
    268       !args->GetString(ENGINE_URL, &url)) {
    269     NOTREACHED();
    270     return;
    271   }
    272   edit_controller_->AcceptAddOrEdit(name, keyword, url);
    273 }
    274