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