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/ui/webui/options/startup_pages_handler.h" 6 7#include "base/bind.h" 8#include "base/bind_helpers.h" 9#include "base/prefs/pref_service.h" 10#include "chrome/browser/autocomplete/autocomplete_classifier.h" 11#include "chrome/browser/autocomplete/autocomplete_controller.h" 12#include "chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.h" 13#include "chrome/browser/chrome_notification_types.h" 14#include "chrome/browser/custom_home_pages_table_model.h" 15#include "chrome/browser/prefs/session_startup_pref.h" 16#include "chrome/browser/profiles/profile.h" 17#include "chrome/browser/search_engines/template_url_service_factory.h" 18#include "chrome/common/pref_names.h" 19#include "chrome/grit/generated_resources.h" 20#include "components/metrics/proto/omnibox_event.pb.h" 21#include "components/omnibox/autocomplete_input.h" 22#include "components/omnibox/autocomplete_result.h" 23#include "components/url_fixer/url_fixer.h" 24#include "content/public/browser/notification_details.h" 25#include "content/public/browser/web_ui.h" 26 27namespace options { 28 29StartupPagesHandler::StartupPagesHandler() { 30} 31 32StartupPagesHandler::~StartupPagesHandler() { 33} 34 35void StartupPagesHandler::GetLocalizedValues( 36 base::DictionaryValue* localized_strings) { 37 DCHECK(localized_strings); 38 39 static OptionsStringResource resources[] = { 40 { "startupAddLabel", IDS_OPTIONS_STARTUP_ADD_LABEL }, 41 { "startupUseCurrent", IDS_OPTIONS_STARTUP_USE_CURRENT }, 42 { "startupPagesPlaceholder", IDS_OPTIONS_STARTUP_PAGES_PLACEHOLDER }, 43 }; 44 45 RegisterStrings(localized_strings, resources, arraysize(resources)); 46 RegisterTitle(localized_strings, "startupPagesOverlay", 47 IDS_OPTIONS_STARTUP_PAGES_DIALOG_TITLE); 48} 49 50void StartupPagesHandler::RegisterMessages() { 51 // Guest profiles should never have been displayed the option to set these 52 // values. 53 if (Profile::FromWebUI(web_ui())->IsOffTheRecord()) 54 return; 55 56 web_ui()->RegisterMessageCallback("removeStartupPages", 57 base::Bind(&StartupPagesHandler::RemoveStartupPages, 58 base::Unretained(this))); 59 web_ui()->RegisterMessageCallback("addStartupPage", 60 base::Bind(&StartupPagesHandler::AddStartupPage, 61 base::Unretained(this))); 62 web_ui()->RegisterMessageCallback("editStartupPage", 63 base::Bind(&StartupPagesHandler::EditStartupPage, 64 base::Unretained(this))); 65 web_ui()->RegisterMessageCallback("setStartupPagesToCurrentPages", 66 base::Bind(&StartupPagesHandler::SetStartupPagesToCurrentPages, 67 base::Unretained(this))); 68 web_ui()->RegisterMessageCallback("dragDropStartupPage", 69 base::Bind(&StartupPagesHandler::DragDropStartupPage, 70 base::Unretained(this))); 71 web_ui()->RegisterMessageCallback( 72 "requestAutocompleteSuggestionsForStartupPages", 73 base::Bind(&StartupPagesHandler::RequestAutocompleteSuggestions, 74 base::Unretained(this))); 75 web_ui()->RegisterMessageCallback("commitStartupPrefChanges", 76 base::Bind(&StartupPagesHandler::CommitChanges, 77 base::Unretained(this))); 78 web_ui()->RegisterMessageCallback("cancelStartupPrefChanges", 79 base::Bind(&StartupPagesHandler::CancelChanges, 80 base::Unretained(this))); 81} 82 83void StartupPagesHandler::UpdateStartupPages() { 84 Profile* profile = Profile::FromWebUI(web_ui()); 85 const SessionStartupPref startup_pref = 86 SessionStartupPref::GetStartupPref(profile->GetPrefs()); 87 startup_custom_pages_table_model_->SetURLs(startup_pref.urls); 88} 89 90void StartupPagesHandler::InitializeHandler() { 91 Profile* profile = Profile::FromWebUI(web_ui()); 92 93 startup_custom_pages_table_model_.reset( 94 new CustomHomePagesTableModel(profile)); 95 startup_custom_pages_table_model_->SetObserver(this); 96 97 pref_change_registrar_.Init(profile->GetPrefs()); 98 pref_change_registrar_.Add( 99 prefs::kURLsToRestoreOnStartup, 100 base::Bind(&StartupPagesHandler::UpdateStartupPages, 101 base::Unretained(this))); 102 103 autocomplete_controller_.reset(new AutocompleteController(profile, 104 TemplateURLServiceFactory::GetForProfile(profile), this, 105 AutocompleteClassifier::kDefaultOmniboxProviders)); 106} 107 108void StartupPagesHandler::InitializePage() { 109 UpdateStartupPages(); 110} 111 112void StartupPagesHandler::OnModelChanged() { 113 base::ListValue startup_pages; 114 int page_count = startup_custom_pages_table_model_->RowCount(); 115 std::vector<GURL> urls = startup_custom_pages_table_model_->GetURLs(); 116 for (int i = 0; i < page_count; ++i) { 117 base::DictionaryValue* entry = new base::DictionaryValue(); 118 entry->SetString("title", startup_custom_pages_table_model_->GetText(i, 0)); 119 entry->SetString("url", urls[i].spec()); 120 entry->SetString("tooltip", 121 startup_custom_pages_table_model_->GetTooltip(i)); 122 entry->SetInteger("modelIndex", i); 123 startup_pages.Append(entry); 124 } 125 126 web_ui()->CallJavascriptFunction("StartupOverlay.updateStartupPages", 127 startup_pages); 128} 129 130void StartupPagesHandler::OnItemsChanged(int start, int length) { 131 OnModelChanged(); 132} 133 134void StartupPagesHandler::OnItemsAdded(int start, int length) { 135 OnModelChanged(); 136} 137 138void StartupPagesHandler::OnItemsRemoved(int start, int length) { 139 OnModelChanged(); 140} 141 142void StartupPagesHandler::SetStartupPagesToCurrentPages( 143 const base::ListValue* args) { 144 startup_custom_pages_table_model_->SetToCurrentlyOpenPages(); 145} 146 147void StartupPagesHandler::RemoveStartupPages(const base::ListValue* args) { 148 for (int i = args->GetSize() - 1; i >= 0; --i) { 149 int selected_index; 150 CHECK(args->GetInteger(i, &selected_index)); 151 152 if (selected_index < 0 || 153 selected_index >= startup_custom_pages_table_model_->RowCount()) { 154 NOTREACHED(); 155 return; 156 } 157 startup_custom_pages_table_model_->Remove(selected_index); 158 } 159} 160 161void StartupPagesHandler::AddStartupPage(const base::ListValue* args) { 162 std::string url_string; 163 CHECK(args->GetString(0, &url_string)); 164 165 GURL url = url_fixer::FixupURL(url_string, std::string()); 166 if (!url.is_valid()) 167 return; 168 169 int row_count = startup_custom_pages_table_model_->RowCount(); 170 int index; 171 if (!args->GetInteger(1, &index) || index > row_count) 172 index = row_count; 173 174 startup_custom_pages_table_model_->Add(index, url); 175} 176 177void StartupPagesHandler::EditStartupPage(const base::ListValue* args) { 178 std::string url_string; 179 GURL fixed_url; 180 int index; 181 CHECK_EQ(args->GetSize(), 2U); 182 CHECK(args->GetInteger(0, &index)); 183 CHECK(args->GetString(1, &url_string)); 184 185 if (index < 0 || index > startup_custom_pages_table_model_->RowCount()) { 186 NOTREACHED(); 187 return; 188 } 189 190 fixed_url = url_fixer::FixupURL(url_string, std::string()); 191 if (!fixed_url.is_empty()) { 192 std::vector<GURL> urls = startup_custom_pages_table_model_->GetURLs(); 193 urls[index] = fixed_url; 194 startup_custom_pages_table_model_->SetURLs(urls); 195 } else { 196 startup_custom_pages_table_model_->Remove(index); 197 } 198} 199 200void StartupPagesHandler::DragDropStartupPage(const base::ListValue* args) { 201 CHECK_EQ(args->GetSize(), 2U); 202 203 int to_index; 204 205 CHECK(args->GetInteger(0, &to_index)); 206 207 const base::ListValue* selected; 208 CHECK(args->GetList(1, &selected)); 209 210 std::vector<int> index_list; 211 for (size_t i = 0; i < selected->GetSize(); ++i) { 212 int index; 213 CHECK(selected->GetInteger(i, &index)); 214 index_list.push_back(index); 215 } 216 217 startup_custom_pages_table_model_->MoveURLs(to_index, index_list); 218} 219 220void StartupPagesHandler::SaveStartupPagesPref() { 221 PrefService* prefs = Profile::FromWebUI(web_ui())->GetPrefs(); 222 223 SessionStartupPref pref = SessionStartupPref::GetStartupPref(prefs); 224 pref.urls = startup_custom_pages_table_model_->GetURLs(); 225 226 if (pref.urls.empty()) 227 pref.type = SessionStartupPref::DEFAULT; 228 229 SessionStartupPref::SetStartupPref(prefs, pref); 230} 231 232void StartupPagesHandler::CommitChanges(const base::ListValue* args) { 233 SaveStartupPagesPref(); 234} 235 236void StartupPagesHandler::CancelChanges(const base::ListValue* args) { 237 UpdateStartupPages(); 238} 239 240void StartupPagesHandler::RequestAutocompleteSuggestions( 241 const base::ListValue* args) { 242 base::string16 input; 243 CHECK_EQ(args->GetSize(), 1U); 244 CHECK(args->GetString(0, &input)); 245 246 autocomplete_controller_->Start(AutocompleteInput( 247 input, base::string16::npos, base::string16(), GURL(), 248 metrics::OmniboxEventProto::INVALID_SPEC, true, false, false, true, 249 ChromeAutocompleteSchemeClassifier(Profile::FromWebUI(web_ui())))); 250} 251 252void StartupPagesHandler::OnResultChanged(bool default_match_changed) { 253 const AutocompleteResult& result = autocomplete_controller_->result(); 254 base::ListValue suggestions; 255 OptionsUI::ProcessAutocompleteSuggestions(result, &suggestions); 256 web_ui()->CallJavascriptFunction( 257 "StartupOverlay.updateAutocompleteSuggestions", suggestions); 258} 259 260} // namespace options 261