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