OLD | NEW |
| (Empty) |
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/views/options/general_page_view.h" | |
6 | |
7 #include <string> | |
8 #include <vector> | |
9 | |
10 #include "base/callback.h" | |
11 #include "base/message_loop.h" | |
12 #include "base/string16.h" | |
13 #include "base/string_util.h" | |
14 #include "base/utf_string_conversions.h" | |
15 #include "chrome/browser/browser_process.h" | |
16 #include "chrome/browser/browser_window.h" | |
17 #include "chrome/browser/custom_home_pages_table_model.h" | |
18 #include "chrome/browser/instant/instant_confirm_dialog.h" | |
19 #include "chrome/browser/instant/instant_controller.h" | |
20 #include "chrome/browser/net/url_fixer_upper.h" | |
21 #include "chrome/browser/prefs/pref_service.h" | |
22 #include "chrome/browser/prefs/session_startup_pref.h" | |
23 #include "chrome/browser/profiles/profile.h" | |
24 #include "chrome/browser/search_engines/template_url.h" | |
25 #include "chrome/browser/search_engines/template_url_model.h" | |
26 #include "chrome/browser/search_engines/template_url_model_observer.h" | |
27 #include "chrome/browser/ui/options/show_options_url.h" | |
28 #include "chrome/browser/ui/views/keyword_editor_view.h" | |
29 #include "chrome/browser/ui/views/options/managed_prefs_banner_view.h" | |
30 #include "chrome/browser/ui/views/options/options_group_view.h" | |
31 #include "chrome/browser/ui/webui/new_tab_ui.h" | |
32 #include "chrome/common/chrome_constants.h" | |
33 #include "chrome/common/pref_names.h" | |
34 #include "chrome/common/url_constants.h" | |
35 #include "chrome/installer/util/browser_distribution.h" | |
36 #include "grit/chromium_strings.h" | |
37 #include "grit/generated_resources.h" | |
38 #include "ui/base/l10n/l10n_util.h" | |
39 #include "ui/base/models/combobox_model.h" | |
40 #include "views/controls/button/radio_button.h" | |
41 #include "views/controls/label.h" | |
42 #include "views/controls/table/table_view.h" | |
43 #include "views/controls/textfield/textfield.h" | |
44 #include "views/layout/grid_layout.h" | |
45 #include "views/layout/layout_constants.h" | |
46 | |
47 namespace { | |
48 | |
49 // All the options pages are in the same view hierarchy. This means we need to | |
50 // make sure group identifiers don't collide across different pages. | |
51 const int kStartupRadioGroup = 101; | |
52 const int kHomePageRadioGroup = 102; | |
53 const SkColor kDefaultBrowserLabelColor = SkColorSetRGB(0, 135, 0); | |
54 const SkColor kNotDefaultBrowserLabelColor = SkColorSetRGB(135, 0, 0); | |
55 const int kHomePageTextfieldWidthChars = 40; | |
56 | |
57 bool IsNewTabUIURLString(const GURL& url) { | |
58 return url == GURL(chrome::kChromeUINewTabURL); | |
59 } | |
60 } // namespace | |
61 | |
62 /////////////////////////////////////////////////////////////////////////////// | |
63 // OptionsGroupContents | |
64 class OptionsGroupContents : public views::View { | |
65 public: | |
66 OptionsGroupContents() { } | |
67 | |
68 // views::View overrides: | |
69 virtual AccessibilityTypes::Role GetAccessibleRole() { | |
70 return AccessibilityTypes::ROLE_GROUPING; | |
71 } | |
72 | |
73 private: | |
74 DISALLOW_COPY_AND_ASSIGN(OptionsGroupContents); | |
75 }; | |
76 | |
77 /////////////////////////////////////////////////////////////////////////////// | |
78 // SearchEngineListModel | |
79 | |
80 class SearchEngineListModel : public ui::ComboboxModel, | |
81 public TemplateURLModelObserver { | |
82 public: | |
83 explicit SearchEngineListModel(Profile* profile); | |
84 virtual ~SearchEngineListModel(); | |
85 | |
86 // Sets the Combobox. SearchEngineListModel needs a handle to the Combobox | |
87 // so that when the TemplateURLModel changes the combobox can be updated. | |
88 void SetCombobox(views::Combobox* combobox); | |
89 | |
90 // ui::ComboboxModel overrides: | |
91 virtual int GetItemCount(); | |
92 virtual string16 GetItemAt(int index); | |
93 | |
94 // Returns the TemplateURL at the specified index. | |
95 const TemplateURL* GetTemplateURLAt(int index); | |
96 | |
97 TemplateURLModel* model() { return template_url_model_; } | |
98 | |
99 private: | |
100 // TemplateURLModelObserver methods. | |
101 virtual void OnTemplateURLModelChanged(); | |
102 | |
103 // Recalculates the TemplateURLs to display and notifies the combobox. | |
104 void ResetContents(); | |
105 | |
106 // Resets the selection of the combobox based on the users selected search | |
107 // engine. | |
108 void ChangeComboboxSelection(); | |
109 | |
110 TemplateURLModel* template_url_model_; | |
111 | |
112 // The combobox hosting us. | |
113 views::Combobox* combobox_; | |
114 | |
115 // The TemplateURLs we're showing. | |
116 typedef std::vector<const TemplateURL*> TemplateURLs; | |
117 TemplateURLs template_urls_; | |
118 | |
119 DISALLOW_COPY_AND_ASSIGN(SearchEngineListModel); | |
120 }; | |
121 | |
122 SearchEngineListModel::SearchEngineListModel(Profile* profile) | |
123 : template_url_model_(profile->GetTemplateURLModel()), | |
124 combobox_(NULL) { | |
125 if (template_url_model_) { | |
126 template_url_model_->Load(); | |
127 template_url_model_->AddObserver(this); | |
128 } | |
129 ResetContents(); | |
130 } | |
131 | |
132 SearchEngineListModel::~SearchEngineListModel() { | |
133 if (template_url_model_) | |
134 template_url_model_->RemoveObserver(this); | |
135 } | |
136 | |
137 void SearchEngineListModel::SetCombobox(views::Combobox* combobox) { | |
138 combobox_ = combobox; | |
139 if (template_url_model_ && template_url_model_->loaded()) | |
140 ChangeComboboxSelection(); | |
141 else | |
142 combobox_->SetEnabled(false); | |
143 } | |
144 | |
145 int SearchEngineListModel::GetItemCount() { | |
146 return static_cast<int>(template_urls_.size()); | |
147 } | |
148 | |
149 string16 SearchEngineListModel::GetItemAt(int index) { | |
150 DCHECK(index < GetItemCount()); | |
151 return WideToUTF16Hack(template_urls_[index]->short_name()); | |
152 } | |
153 | |
154 const TemplateURL* SearchEngineListModel::GetTemplateURLAt(int index) { | |
155 DCHECK(index >= 0 && index < static_cast<int>(template_urls_.size())); | |
156 return template_urls_[static_cast<int>(index)]; | |
157 } | |
158 | |
159 void SearchEngineListModel::OnTemplateURLModelChanged() { | |
160 ResetContents(); | |
161 } | |
162 | |
163 void SearchEngineListModel::ResetContents() { | |
164 if (!template_url_model_ || !template_url_model_->loaded()) | |
165 return; | |
166 template_urls_.clear(); | |
167 TemplateURLs model_urls = template_url_model_->GetTemplateURLs(); | |
168 for (size_t i = 0; i < model_urls.size(); ++i) { | |
169 if (model_urls[i]->ShowInDefaultList()) | |
170 template_urls_.push_back(model_urls[i]); | |
171 } | |
172 | |
173 if (combobox_) { | |
174 combobox_->ModelChanged(); | |
175 ChangeComboboxSelection(); | |
176 } | |
177 } | |
178 | |
179 void SearchEngineListModel::ChangeComboboxSelection() { | |
180 if (template_urls_.size()) { | |
181 const TemplateURL* default_search_provider = | |
182 template_url_model_->GetDefaultSearchProvider(); | |
183 if (default_search_provider) { | |
184 TemplateURLs::iterator i = | |
185 find(template_urls_.begin(), template_urls_.end(), | |
186 default_search_provider); | |
187 if (i != template_urls_.end()) { | |
188 combobox_->SetSelectedItem( | |
189 static_cast<int>(i - template_urls_.begin())); | |
190 } | |
191 } else { | |
192 combobox_->SetSelectedItem(-1); | |
193 } | |
194 } | |
195 // If the default search is managed or there are no URLs, disable the control. | |
196 combobox_->SetEnabled(!template_urls_.empty() && | |
197 !template_url_model_->is_default_search_managed()); | |
198 } | |
199 | |
200 /////////////////////////////////////////////////////////////////////////////// | |
201 // GeneralPageView, public: | |
202 | |
203 GeneralPageView::GeneralPageView(Profile* profile) | |
204 : startup_group_(NULL), | |
205 startup_homepage_radio_(NULL), | |
206 startup_last_session_radio_(NULL), | |
207 startup_custom_radio_(NULL), | |
208 startup_add_custom_page_button_(NULL), | |
209 startup_remove_custom_page_button_(NULL), | |
210 startup_use_current_page_button_(NULL), | |
211 startup_custom_pages_table_(NULL), | |
212 homepage_group_(NULL), | |
213 homepage_use_newtab_radio_(NULL), | |
214 homepage_use_url_radio_(NULL), | |
215 homepage_use_url_textfield_(NULL), | |
216 homepage_show_home_button_checkbox_(NULL), | |
217 default_search_group_(NULL), | |
218 default_search_manage_engines_button_(NULL), | |
219 instant_checkbox_(NULL), | |
220 instant_link_(NULL), | |
221 default_browser_group_(NULL), | |
222 default_browser_status_label_(NULL), | |
223 default_browser_use_as_default_button_(NULL), | |
224 ALLOW_THIS_IN_INITIALIZER_LIST( | |
225 default_browser_worker_( | |
226 new ShellIntegration::DefaultBrowserWorker(this))), | |
227 OptionsPageView(profile) { | |
228 } | |
229 | |
230 GeneralPageView::~GeneralPageView() { | |
231 if (startup_custom_pages_table_) | |
232 startup_custom_pages_table_->SetModel(NULL); | |
233 default_browser_worker_->ObserverDestroyed(); | |
234 } | |
235 | |
236 /////////////////////////////////////////////////////////////////////////////// | |
237 // GeneralPageView, views::ButtonListener implementation: | |
238 | |
239 void GeneralPageView::ButtonPressed( | |
240 views::Button* sender, const views::Event& event) { | |
241 if (sender == startup_homepage_radio_ || | |
242 sender == startup_last_session_radio_ || | |
243 sender == startup_custom_radio_) { | |
244 SaveStartupPref(); | |
245 if (sender == startup_homepage_radio_) { | |
246 UserMetricsRecordAction(UserMetricsAction("Options_Startup_Homepage"), | |
247 profile()->GetPrefs()); | |
248 } else if (sender == startup_last_session_radio_) { | |
249 UserMetricsRecordAction(UserMetricsAction("Options_Startup_LastSession"), | |
250 profile()->GetPrefs()); | |
251 } else if (sender == startup_custom_radio_) { | |
252 UserMetricsRecordAction(UserMetricsAction("Options_Startup_Custom"), | |
253 profile()->GetPrefs()); | |
254 } | |
255 } else if (sender == startup_add_custom_page_button_) { | |
256 AddURLToStartupURLs(); | |
257 } else if (sender == startup_remove_custom_page_button_) { | |
258 RemoveURLsFromStartupURLs(); | |
259 } else if (sender == startup_use_current_page_button_) { | |
260 SetStartupURLToCurrentPage(); | |
261 } else if (sender == homepage_use_newtab_radio_) { | |
262 UserMetricsRecordAction(UserMetricsAction("Options_Homepage_UseNewTab"), | |
263 profile()->GetPrefs()); | |
264 UpdateHomepagePrefs(); | |
265 EnableHomepageURLField(false); | |
266 } else if (sender == homepage_use_url_radio_) { | |
267 UserMetricsRecordAction(UserMetricsAction("Options_Homepage_UseURL"), | |
268 profile()->GetPrefs()); | |
269 UpdateHomepagePrefs(); | |
270 EnableHomepageURLField(true); | |
271 } else if (sender == homepage_show_home_button_checkbox_) { | |
272 bool show_button = homepage_show_home_button_checkbox_->checked(); | |
273 if (show_button) { | |
274 UserMetricsRecordAction( | |
275 UserMetricsAction("Options_Homepage_ShowHomeButton"), | |
276 profile()->GetPrefs()); | |
277 } else { | |
278 UserMetricsRecordAction( | |
279 UserMetricsAction("Options_Homepage_HideHomeButton"), | |
280 profile()->GetPrefs()); | |
281 } | |
282 show_home_button_.SetValue(show_button); | |
283 } else if (sender == default_browser_use_as_default_button_) { | |
284 default_browser_worker_->StartSetAsDefaultBrowser(); | |
285 UserMetricsRecordAction(UserMetricsAction("Options_SetAsDefaultBrowser"), | |
286 NULL); | |
287 // If the user made Chrome the default browser, then he/she arguably wants | |
288 // to be notified when that changes. | |
289 profile()->GetPrefs()->SetBoolean(prefs::kCheckDefaultBrowser, true); | |
290 } else if (sender == default_search_manage_engines_button_) { | |
291 UserMetricsRecordAction(UserMetricsAction("Options_ManageSearchEngines"), | |
292 NULL); | |
293 KeywordEditorView::Show(profile()); | |
294 } else if (sender == instant_checkbox_) { | |
295 if (instant_checkbox_->checked()) { | |
296 // Don't toggle immediately, instead let | |
297 // ShowInstantConfirmDialogIfNecessary do it. | |
298 instant_checkbox_->SetChecked(false); | |
299 browser::ShowInstantConfirmDialogIfNecessary( | |
300 GetWindow()->GetNativeWindow(), profile()); | |
301 } else { | |
302 InstantController::Disable(profile()); | |
303 } | |
304 } | |
305 } | |
306 | |
307 /////////////////////////////////////////////////////////////////////////////// | |
308 // GeneralPageView, views::Combobox::Listener implementation: | |
309 | |
310 void GeneralPageView::ItemChanged(views::Combobox* combobox, | |
311 int prev_index, int new_index) { | |
312 if (combobox == default_search_engine_combobox_) { | |
313 SetDefaultSearchProvider(); | |
314 UserMetricsRecordAction(UserMetricsAction("Options_SearchEngineChanged"), | |
315 NULL); | |
316 } | |
317 } | |
318 | |
319 /////////////////////////////////////////////////////////////////////////////// | |
320 // GeneralPageView, views::Textfield:Controller implementation: | |
321 | |
322 void GeneralPageView::ContentsChanged(views::Textfield* sender, | |
323 const std::wstring& new_contents) { | |
324 if (sender == homepage_use_url_textfield_) { | |
325 UpdateHomepagePrefs(); | |
326 } | |
327 } | |
328 | |
329 bool GeneralPageView::HandleKeyEvent(views::Textfield* sender, | |
330 const views::KeyEvent& key_event) { | |
331 return false; | |
332 } | |
333 | |
334 /////////////////////////////////////////////////////////////////////////////// | |
335 // GeneralPageView, OptionsPageView implementation: | |
336 | |
337 void GeneralPageView::InitControlLayout() { | |
338 using views::GridLayout; | |
339 using views::ColumnSet; | |
340 | |
341 GridLayout* layout = new GridLayout(this); | |
342 layout->SetInsets(5, 5, 5, 5); | |
343 SetLayoutManager(layout); | |
344 | |
345 const int single_column_view_set_id = 0; | |
346 ColumnSet* column_set = layout->AddColumnSet(single_column_view_set_id); | |
347 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, | |
348 GridLayout::USE_PREF, 0, 0); | |
349 | |
350 layout->StartRow(0, single_column_view_set_id); | |
351 layout->AddView( | |
352 new ManagedPrefsBannerView(profile()->GetPrefs(), OPTIONS_PAGE_GENERAL)); | |
353 | |
354 layout->StartRow(0, single_column_view_set_id); | |
355 InitStartupGroup(); | |
356 layout->AddView(startup_group_); | |
357 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | |
358 | |
359 layout->StartRow(0, single_column_view_set_id); | |
360 InitHomepageGroup(); | |
361 layout->AddView(homepage_group_); | |
362 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | |
363 | |
364 layout->StartRow(0, single_column_view_set_id); | |
365 InitDefaultSearchGroup(); | |
366 layout->AddView(default_search_group_); | |
367 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | |
368 | |
369 #if !defined(OS_CHROMEOS) | |
370 layout->StartRow(0, single_column_view_set_id); | |
371 InitDefaultBrowserGroup(); | |
372 layout->AddView(default_browser_group_); | |
373 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | |
374 #endif | |
375 | |
376 // Register pref observers that update the controls when a pref changes. | |
377 registrar_.Init(profile()->GetPrefs()); | |
378 registrar_.Add(prefs::kRestoreOnStartup, this); | |
379 registrar_.Add(prefs::kURLsToRestoreOnStartup, this); | |
380 registrar_.Add(prefs::kInstantEnabled, this); | |
381 | |
382 new_tab_page_is_home_page_.Init(prefs::kHomePageIsNewTabPage, | |
383 profile()->GetPrefs(), this); | |
384 homepage_.Init(prefs::kHomePage, profile()->GetPrefs(), this); | |
385 show_home_button_.Init(prefs::kShowHomeButton, profile()->GetPrefs(), this); | |
386 default_browser_policy_.Init(prefs::kDefaultBrowserSettingEnabled, | |
387 g_browser_process->local_state(), | |
388 this); | |
389 } | |
390 | |
391 void GeneralPageView::NotifyPrefChanged(const std::string* pref_name) { | |
392 PrefService* prefs = profile()->GetPrefs(); | |
393 if (!pref_name || | |
394 *pref_name == prefs::kRestoreOnStartup || | |
395 *pref_name == prefs::kURLsToRestoreOnStartup) { | |
396 const SessionStartupPref startup_pref = | |
397 SessionStartupPref::GetStartupPref(prefs); | |
398 bool radio_buttons_enabled = !SessionStartupPref::TypeIsManaged(prefs); | |
399 bool restore_urls_enabled = !SessionStartupPref::URLsAreManaged(prefs); | |
400 switch (startup_pref.type) { | |
401 case SessionStartupPref::DEFAULT: | |
402 startup_homepage_radio_->SetChecked(true); | |
403 restore_urls_enabled = false; | |
404 break; | |
405 | |
406 case SessionStartupPref::LAST: | |
407 startup_last_session_radio_->SetChecked(true); | |
408 restore_urls_enabled = false; | |
409 break; | |
410 | |
411 case SessionStartupPref::URLS: | |
412 startup_custom_radio_->SetChecked(true); | |
413 break; | |
414 } | |
415 startup_homepage_radio_->SetEnabled(radio_buttons_enabled); | |
416 startup_last_session_radio_->SetEnabled(radio_buttons_enabled); | |
417 startup_custom_radio_->SetEnabled(radio_buttons_enabled); | |
418 EnableCustomHomepagesControls(restore_urls_enabled); | |
419 startup_custom_pages_table_model_->SetURLs(startup_pref.urls); | |
420 } | |
421 | |
422 if (!pref_name || | |
423 *pref_name == prefs::kHomePageIsNewTabPage || | |
424 *pref_name == prefs::kHomePage) { | |
425 bool new_tab_page_is_home_page_managed = | |
426 new_tab_page_is_home_page_.IsManaged(); | |
427 bool homepage_managed = homepage_.IsManaged(); | |
428 bool homepage_url_is_new_tab = | |
429 IsNewTabUIURLString(GURL(homepage_.GetValue())); | |
430 bool homepage_is_new_tab = homepage_url_is_new_tab || | |
431 new_tab_page_is_home_page_.GetValue(); | |
432 // If HomepageIsNewTab is managed or | |
433 // Homepage is 'chrome://newtab' and managed, disable the radios. | |
434 bool disable_homepage_choice_buttons = | |
435 new_tab_page_is_home_page_managed || | |
436 homepage_managed && homepage_url_is_new_tab; | |
437 if (!homepage_url_is_new_tab) | |
438 homepage_use_url_textfield_->SetText(UTF8ToWide(homepage_.GetValue())); | |
439 UpdateHomepageIsNewTabRadio( | |
440 homepage_is_new_tab, !disable_homepage_choice_buttons); | |
441 EnableHomepageURLField(!homepage_is_new_tab); | |
442 } | |
443 | |
444 if (!pref_name || *pref_name == prefs::kShowHomeButton) { | |
445 homepage_show_home_button_checkbox_->SetChecked( | |
446 show_home_button_.GetValue()); | |
447 homepage_show_home_button_checkbox_->SetEnabled( | |
448 !show_home_button_.IsManaged()); | |
449 } | |
450 | |
451 if (!pref_name || *pref_name == prefs::kInstantEnabled) | |
452 instant_checkbox_->SetChecked(prefs->GetBoolean(prefs::kInstantEnabled)); | |
453 | |
454 if (!pref_name || *pref_name == prefs::kDefaultBrowserSettingEnabled) { | |
455 // If the option is managed the UI is uncondionally disabled otherwise we | |
456 // restart the standard button enabling logic. | |
457 if (default_browser_policy_.IsManaged()) | |
458 default_browser_use_as_default_button_->SetEnabled(false); | |
459 else | |
460 default_browser_worker_->StartCheckDefaultBrowser(); | |
461 } | |
462 } | |
463 | |
464 void GeneralPageView::HighlightGroup(OptionsGroup highlight_group) { | |
465 if (highlight_group == OPTIONS_GROUP_DEFAULT_SEARCH) | |
466 default_search_group_->SetHighlighted(true); | |
467 } | |
468 | |
469 void GeneralPageView::LinkActivated(views::Link* source, int event_flags) { | |
470 DCHECK(source == instant_link_); | |
471 browser::ShowOptionsURL(profile(), browser::InstantLearnMoreURL()); | |
472 } | |
473 | |
474 /////////////////////////////////////////////////////////////////////////////// | |
475 // GeneralPageView, private: | |
476 | |
477 void GeneralPageView::SetDefaultBrowserUIState( | |
478 ShellIntegration::DefaultBrowserUIState state) { | |
479 bool button_enabled = | |
480 (state == ShellIntegration::STATE_NOT_DEFAULT) && | |
481 !default_browser_policy_.IsManaged(); | |
482 default_browser_use_as_default_button_->SetEnabled(button_enabled); | |
483 default_browser_use_as_default_button_->SetNeedElevation(true); | |
484 if (state == ShellIntegration::STATE_IS_DEFAULT) { | |
485 default_browser_status_label_->SetText(UTF16ToWide( | |
486 l10n_util::GetStringFUTF16(IDS_OPTIONS_DEFAULTBROWSER_DEFAULT, | |
487 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)))); | |
488 default_browser_status_label_->SetColor(kDefaultBrowserLabelColor); | |
489 Layout(); | |
490 } else if (state == ShellIntegration::STATE_NOT_DEFAULT) { | |
491 default_browser_status_label_->SetText(UTF16ToWide( | |
492 l10n_util::GetStringFUTF16(IDS_OPTIONS_DEFAULTBROWSER_NOTDEFAULT, | |
493 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)))); | |
494 default_browser_status_label_->SetColor(kNotDefaultBrowserLabelColor); | |
495 Layout(); | |
496 } else if (state == ShellIntegration::STATE_UNKNOWN) { | |
497 default_browser_status_label_->SetText(UTF16ToWide( | |
498 l10n_util::GetStringFUTF16(IDS_OPTIONS_DEFAULTBROWSER_UNKNOWN, | |
499 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)))); | |
500 default_browser_status_label_->SetColor(kNotDefaultBrowserLabelColor); | |
501 Layout(); | |
502 } | |
503 } | |
504 | |
505 void GeneralPageView::SetDefaultBrowserUIStateForSxS() { | |
506 default_browser_use_as_default_button_->SetEnabled(false); | |
507 default_browser_status_label_->SetText(UTF16ToWide( | |
508 l10n_util::GetStringFUTF16(IDS_OPTIONS_DEFAULTBROWSER_SXS, | |
509 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)))); | |
510 default_browser_status_label_->SetColor(kNotDefaultBrowserLabelColor); | |
511 Layout(); | |
512 } | |
513 | |
514 void GeneralPageView::InitStartupGroup() { | |
515 startup_homepage_radio_ = new views::RadioButton(UTF16ToWide( | |
516 l10n_util::GetStringUTF16(IDS_OPTIONS_STARTUP_SHOW_DEFAULT_AND_NEWTAB)), | |
517 kStartupRadioGroup); | |
518 startup_homepage_radio_->set_listener(this); | |
519 startup_last_session_radio_ = new views::RadioButton(UTF16ToWide( | |
520 l10n_util::GetStringUTF16(IDS_OPTIONS_STARTUP_SHOW_LAST_SESSION)), | |
521 kStartupRadioGroup); | |
522 startup_last_session_radio_->set_listener(this); | |
523 startup_last_session_radio_->SetMultiLine(true); | |
524 startup_custom_radio_ = new views::RadioButton( | |
525 UTF16ToWide(l10n_util::GetStringUTF16(IDS_OPTIONS_STARTUP_SHOW_PAGES)), | |
526 kStartupRadioGroup); | |
527 startup_custom_radio_->set_listener(this); | |
528 startup_add_custom_page_button_ = new views::NativeButton( | |
529 this, | |
530 UTF16ToWide(l10n_util::GetStringUTF16(IDS_OPTIONS_STARTUP_ADD_BUTTON))); | |
531 startup_remove_custom_page_button_ = new views::NativeButton( | |
532 this, | |
533 UTF16ToWide( | |
534 l10n_util::GetStringUTF16(IDS_OPTIONS_STARTUP_REMOVE_BUTTON))); | |
535 startup_remove_custom_page_button_->SetEnabled(false); | |
536 startup_use_current_page_button_ = new views::NativeButton( | |
537 this, | |
538 UTF16ToWide(l10n_util::GetStringUTF16(IDS_OPTIONS_STARTUP_USE_CURRENT))); | |
539 | |
540 startup_custom_pages_table_model_.reset( | |
541 new CustomHomePagesTableModel(profile())); | |
542 std::vector<TableColumn> columns; | |
543 columns.push_back(TableColumn()); | |
544 startup_custom_pages_table_ = new views::TableView( | |
545 startup_custom_pages_table_model_.get(), columns, | |
546 views::ICON_AND_TEXT, false, false, true); | |
547 startup_custom_pages_table_->SetObserver(this); | |
548 | |
549 using views::GridLayout; | |
550 using views::ColumnSet; | |
551 | |
552 views::View* contents = new OptionsGroupContents; | |
553 GridLayout* layout = new GridLayout(contents); | |
554 contents->SetLayoutManager(layout); | |
555 | |
556 const int single_column_view_set_id = 0; | |
557 ColumnSet* column_set = layout->AddColumnSet(single_column_view_set_id); | |
558 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1, | |
559 GridLayout::USE_PREF, 0, 0); | |
560 | |
561 const int double_column_view_set_id = 1; | |
562 column_set = layout->AddColumnSet(double_column_view_set_id); | |
563 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, | |
564 GridLayout::USE_PREF, 0, 0); | |
565 column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing); | |
566 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 0, | |
567 GridLayout::USE_PREF, 0, 0); | |
568 | |
569 layout->StartRow(0, single_column_view_set_id); | |
570 layout->AddView(startup_homepage_radio_); | |
571 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | |
572 layout->StartRow(0, single_column_view_set_id); | |
573 layout->AddView(startup_last_session_radio_, 1, 1, | |
574 GridLayout::FILL, GridLayout::LEADING); | |
575 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | |
576 layout->StartRow(0, single_column_view_set_id); | |
577 layout->AddView(startup_custom_radio_); | |
578 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | |
579 | |
580 layout->StartRow(0, double_column_view_set_id); | |
581 layout->AddView(startup_custom_pages_table_, 1, 1, | |
582 GridLayout::FILL, GridLayout::FILL); | |
583 | |
584 views::View* button_stack = new views::View; | |
585 GridLayout* button_stack_layout = new GridLayout(button_stack); | |
586 button_stack->SetLayoutManager(button_stack_layout); | |
587 | |
588 column_set = button_stack_layout->AddColumnSet(single_column_view_set_id); | |
589 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1, | |
590 GridLayout::USE_PREF, 0, 0); | |
591 button_stack_layout->StartRow(0, single_column_view_set_id); | |
592 button_stack_layout->AddView(startup_add_custom_page_button_, | |
593 1, 1, GridLayout::FILL, GridLayout::CENTER); | |
594 button_stack_layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | |
595 button_stack_layout->StartRow(0, single_column_view_set_id); | |
596 button_stack_layout->AddView(startup_remove_custom_page_button_, | |
597 1, 1, GridLayout::FILL, GridLayout::CENTER); | |
598 button_stack_layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | |
599 button_stack_layout->StartRow(0, single_column_view_set_id); | |
600 button_stack_layout->AddView(startup_use_current_page_button_, | |
601 1, 1, GridLayout::FILL, GridLayout::CENTER); | |
602 layout->AddView(button_stack); | |
603 | |
604 startup_group_ = new OptionsGroupView( | |
605 contents, | |
606 UTF16ToWide(l10n_util::GetStringUTF16(IDS_OPTIONS_STARTUP_GROUP_NAME)), | |
607 std::wstring(), true); | |
608 } | |
609 | |
610 void GeneralPageView::InitHomepageGroup() { | |
611 homepage_use_newtab_radio_ = new views::RadioButton( | |
612 UTF16ToWide(l10n_util::GetStringUTF16(IDS_OPTIONS_HOMEPAGE_USE_NEWTAB)), | |
613 kHomePageRadioGroup); | |
614 homepage_use_newtab_radio_->set_listener(this); | |
615 homepage_use_newtab_radio_->SetMultiLine(true); | |
616 homepage_use_url_radio_ = new views::RadioButton( | |
617 UTF16ToWide(l10n_util::GetStringUTF16(IDS_OPTIONS_HOMEPAGE_USE_URL)), | |
618 kHomePageRadioGroup); | |
619 homepage_use_url_radio_->set_listener(this); | |
620 homepage_use_url_textfield_ = new views::Textfield; | |
621 homepage_use_url_textfield_->SetController(this); | |
622 homepage_use_url_textfield_->set_default_width_in_chars( | |
623 kHomePageTextfieldWidthChars); | |
624 homepage_show_home_button_checkbox_ = new views::Checkbox( | |
625 UTF16ToWide(l10n_util::GetStringUTF16(IDS_OPTIONS_HOMEPAGE_SHOW_BUTTON))); | |
626 homepage_show_home_button_checkbox_->set_listener(this); | |
627 homepage_show_home_button_checkbox_->SetMultiLine(true); | |
628 | |
629 using views::GridLayout; | |
630 using views::ColumnSet; | |
631 | |
632 views::View* contents = new views::View; | |
633 GridLayout* layout = new GridLayout(contents); | |
634 contents->SetLayoutManager(layout); | |
635 | |
636 const int single_column_view_set_id = 0; | |
637 ColumnSet* column_set = layout->AddColumnSet(single_column_view_set_id); | |
638 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1, | |
639 GridLayout::USE_PREF, 0, 0); | |
640 | |
641 const int double_column_view_set_id = 1; | |
642 column_set = layout->AddColumnSet(double_column_view_set_id); | |
643 column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 0, | |
644 GridLayout::USE_PREF, 0, 0); | |
645 column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing); | |
646 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, | |
647 GridLayout::USE_PREF, 0, 0); | |
648 | |
649 layout->StartRow(0, single_column_view_set_id); | |
650 layout->AddView(homepage_use_newtab_radio_, 1, 1, | |
651 GridLayout::FILL, GridLayout::LEADING); | |
652 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | |
653 layout->StartRow(0, double_column_view_set_id); | |
654 layout->AddView(homepage_use_url_radio_); | |
655 layout->AddView(homepage_use_url_textfield_); | |
656 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | |
657 layout->StartRow(0, single_column_view_set_id); | |
658 layout->AddView(homepage_show_home_button_checkbox_, 1, 1, | |
659 GridLayout::FILL, GridLayout::LEADING); | |
660 | |
661 homepage_group_ = new OptionsGroupView( | |
662 contents, | |
663 UTF16ToWide(l10n_util::GetStringUTF16(IDS_OPTIONS_HOMEPAGE_GROUP_NAME)), | |
664 std::wstring(), true); | |
665 } | |
666 | |
667 | |
668 void GeneralPageView::InitDefaultSearchGroup() { | |
669 default_search_engines_model_.reset(new SearchEngineListModel(profile())); | |
670 default_search_engine_combobox_ = | |
671 new views::Combobox(default_search_engines_model_.get()); | |
672 default_search_engines_model_->SetCombobox(default_search_engine_combobox_); | |
673 default_search_engine_combobox_->set_listener(this); | |
674 | |
675 default_search_manage_engines_button_ = new views::NativeButton( | |
676 this, | |
677 UTF16ToWide(l10n_util::GetStringUTF16( | |
678 IDS_OPTIONS_DEFAULTSEARCH_MANAGE_ENGINES_LINK))); | |
679 | |
680 instant_checkbox_ = new views::Checkbox( | |
681 UTF16ToWide(l10n_util::GetStringUTF16(IDS_INSTANT_PREF))); | |
682 instant_checkbox_->SetMultiLine(false); | |
683 instant_checkbox_->set_listener(this); | |
684 | |
685 instant_link_ = new views::Link(UTF16ToWide( | |
686 l10n_util::GetStringUTF16(IDS_LEARN_MORE))); | |
687 instant_link_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); | |
688 instant_link_->SetController(this); | |
689 | |
690 using views::GridLayout; | |
691 using views::ColumnSet; | |
692 | |
693 views::View* contents = new views::View; | |
694 GridLayout* layout = new GridLayout(contents); | |
695 contents->SetLayoutManager(layout); | |
696 | |
697 const int double_column_view_set_id = 0; | |
698 ColumnSet* column_set = layout->AddColumnSet(double_column_view_set_id); | |
699 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, | |
700 GridLayout::USE_PREF, 0, 0); | |
701 column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing); | |
702 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, | |
703 GridLayout::USE_PREF, 0, 0); | |
704 | |
705 const int checkbox_column_view_set_id = 1; | |
706 column_set = layout->AddColumnSet(checkbox_column_view_set_id); | |
707 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, | |
708 GridLayout::USE_PREF, 0, 0); | |
709 | |
710 const int link_column_set_id = 2; | |
711 column_set = layout->AddColumnSet(link_column_set_id); | |
712 // TODO(sky): this isn't right, we need a method to determine real indent. | |
713 column_set->AddPaddingColumn(0, views::Checkbox::GetTextIndent() + 3); | |
714 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, | |
715 GridLayout::USE_PREF, 0, 0); | |
716 column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing); | |
717 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, | |
718 GridLayout::USE_PREF, 0, 0); | |
719 | |
720 layout->StartRow(0, double_column_view_set_id); | |
721 layout->AddView(default_search_engine_combobox_); | |
722 layout->AddView(default_search_manage_engines_button_); | |
723 layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing); | |
724 | |
725 layout->StartRow(0, checkbox_column_view_set_id); | |
726 layout->AddView(instant_checkbox_); | |
727 layout->AddPaddingRow(0, 0); | |
728 | |
729 layout->StartRow(0, link_column_set_id); | |
730 layout->AddView(new views::Label(UTF16ToWide( | |
731 l10n_util::GetStringUTF16(IDS_INSTANT_PREF_WARNING)))); | |
732 layout->AddView(instant_link_); | |
733 | |
734 default_search_group_ = new OptionsGroupView( | |
735 contents, | |
736 UTF16ToWide( | |
737 l10n_util::GetStringUTF16(IDS_OPTIONS_DEFAULTSEARCH_GROUP_NAME)), | |
738 std::wstring(), true); | |
739 } | |
740 | |
741 void GeneralPageView::InitDefaultBrowserGroup() { | |
742 default_browser_status_label_ = new views::Label; | |
743 default_browser_status_label_->SetMultiLine(true); | |
744 default_browser_status_label_->SetHorizontalAlignment( | |
745 views::Label::ALIGN_LEFT); | |
746 default_browser_use_as_default_button_ = new views::NativeButton( | |
747 this, | |
748 UTF16ToWide( | |
749 l10n_util::GetStringFUTF16(IDS_OPTIONS_DEFAULTBROWSER_USEASDEFAULT, | |
750 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)))); | |
751 | |
752 using views::GridLayout; | |
753 using views::ColumnSet; | |
754 | |
755 views::View* contents = new views::View; | |
756 GridLayout* layout = new GridLayout(contents); | |
757 contents->SetLayoutManager(layout); | |
758 | |
759 const int single_column_view_set_id = 0; | |
760 ColumnSet* column_set = layout->AddColumnSet(single_column_view_set_id); | |
761 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1, | |
762 GridLayout::USE_PREF, 0, 0); | |
763 | |
764 layout->StartRow(0, single_column_view_set_id); | |
765 layout->AddView(default_browser_status_label_, 1, 1, | |
766 GridLayout::FILL, GridLayout::LEADING); | |
767 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | |
768 layout->StartRow(0, single_column_view_set_id); | |
769 layout->AddView(default_browser_use_as_default_button_); | |
770 | |
771 default_browser_group_ = new OptionsGroupView( | |
772 contents, | |
773 UTF16ToWide( | |
774 l10n_util::GetStringUTF16(IDS_OPTIONS_DEFAULTBROWSER_GROUP_NAME)), | |
775 std::wstring(), false); | |
776 | |
777 if (BrowserDistribution::GetDistribution()->CanSetAsDefault()) | |
778 default_browser_worker_->StartCheckDefaultBrowser(); | |
779 else | |
780 SetDefaultBrowserUIStateForSxS(); | |
781 } | |
782 | |
783 void GeneralPageView::SaveStartupPref() { | |
784 SessionStartupPref pref; | |
785 | |
786 if (startup_last_session_radio_->checked()) { | |
787 pref.type = SessionStartupPref::LAST; | |
788 } else if (startup_custom_radio_->checked()) { | |
789 pref.type = SessionStartupPref::URLS; | |
790 } | |
791 | |
792 pref.urls = startup_custom_pages_table_model_->GetURLs(); | |
793 | |
794 SessionStartupPref::SetStartupPref(profile()->GetPrefs(), pref); | |
795 } | |
796 | |
797 void GeneralPageView::AddURLToStartupURLs() { | |
798 UrlPicker* dialog = new UrlPicker(this, profile()); | |
799 dialog->Show(GetWindow()->GetNativeWindow()); | |
800 } | |
801 | |
802 void GeneralPageView::RemoveURLsFromStartupURLs() { | |
803 int selected_row = 0; | |
804 for (views::TableView::iterator i = | |
805 startup_custom_pages_table_->SelectionBegin(); | |
806 i != startup_custom_pages_table_->SelectionEnd(); ++i) { | |
807 startup_custom_pages_table_model_->Remove(*i); | |
808 selected_row = *i; | |
809 } | |
810 int row_count = startup_custom_pages_table_->RowCount(); | |
811 if (selected_row >= row_count) | |
812 selected_row = row_count - 1; | |
813 if (selected_row >= 0) { | |
814 // Select the next row after the last row deleted, or the above item if the | |
815 // latest item was deleted or nothing when the table doesn't have any items. | |
816 startup_custom_pages_table_->Select(selected_row); | |
817 } | |
818 SaveStartupPref(); | |
819 } | |
820 | |
821 void GeneralPageView::SetStartupURLToCurrentPage() { | |
822 startup_custom_pages_table_model_->SetToCurrentlyOpenPages(); | |
823 | |
824 SaveStartupPref(); | |
825 } | |
826 | |
827 void GeneralPageView::EnableCustomHomepagesControls(bool enable) { | |
828 startup_add_custom_page_button_->SetEnabled(enable); | |
829 bool has_selected_rows = startup_custom_pages_table_->SelectedRowCount() > 0; | |
830 startup_remove_custom_page_button_->SetEnabled(enable && has_selected_rows); | |
831 startup_use_current_page_button_->SetEnabled(enable); | |
832 startup_custom_pages_table_->SetEnabled(enable); | |
833 } | |
834 | |
835 void GeneralPageView::AddBookmark(UrlPicker* dialog, | |
836 const std::wstring& title, | |
837 const GURL& url) { | |
838 // The restore URLs policy might have become managed while the dialog is | |
839 // displayed. While the model makes sure that no changes are made in this | |
840 // condition, we should still avoid changing the graphic elements. | |
841 if (SessionStartupPref::URLsAreManaged(profile()->GetPrefs())) | |
842 return; | |
843 int index = startup_custom_pages_table_->FirstSelectedRow(); | |
844 if (index == -1) | |
845 index = startup_custom_pages_table_model_->RowCount(); | |
846 else | |
847 index++; | |
848 startup_custom_pages_table_model_->Add(index, url); | |
849 startup_custom_pages_table_->Select(index); | |
850 | |
851 SaveStartupPref(); | |
852 } | |
853 | |
854 void GeneralPageView::UpdateHomepagePrefs() { | |
855 // If the text field contains a valid URL, sync it to prefs. We run it | |
856 // through the fixer upper to allow input like "google.com" to be converted | |
857 // to something valid ("http://google.com"). If the field contains an | |
858 // empty or null-host URL, a blank homepage is synced to prefs. | |
859 const GURL& homepage = | |
860 URLFixerUpper::FixupURL( | |
861 UTF16ToUTF8(homepage_use_url_textfield_->text()), std::string()); | |
862 bool new_tab_page_is_home_page = homepage_use_newtab_radio_->checked(); | |
863 if (IsNewTabUIURLString(homepage)) { // 'chrome://newtab/' | |
864 // This should be handled differently than invalid URLs. | |
865 // When the control arrives here, then |homepage| contains | |
866 // 'chrome://newtab/', and the homepage preference contains the previous | |
867 // valid content of the textfield (fixed up), most likely | |
868 // 'chrome://newta/'. This has to be cleared, because keeping it makes no | |
869 // sense to the user. | |
870 new_tab_page_is_home_page = true; | |
871 homepage_.SetValueIfNotManaged(std::string()); | |
872 } else if (!homepage.is_valid()) { | |
873 new_tab_page_is_home_page = true; | |
874 // The URL is invalid either with a host (e.g. http://chr%mium.org) | |
875 // or without a host (e.g. http://). In case there is a host, then | |
876 // the URL is not cleared, saving a fragment of the URL to the | |
877 // preferences (e.g. http://chr in case the characters of the above example | |
878 // were typed by the user one by one). | |
879 // See bug 40996. | |
880 if (!homepage.has_host()) | |
881 homepage_.SetValueIfNotManaged(std::string()); | |
882 } else { | |
883 homepage_.SetValueIfNotManaged(homepage.spec()); | |
884 } | |
885 new_tab_page_is_home_page_.SetValueIfNotManaged(new_tab_page_is_home_page); | |
886 } | |
887 | |
888 void GeneralPageView::UpdateHomepageIsNewTabRadio(bool homepage_is_new_tab, | |
889 bool enabled) { | |
890 homepage_use_newtab_radio_->SetChecked(homepage_is_new_tab); | |
891 homepage_use_url_radio_->SetChecked(!homepage_is_new_tab); | |
892 homepage_use_newtab_radio_->SetEnabled(enabled); | |
893 homepage_use_url_radio_->SetEnabled(enabled); | |
894 } | |
895 | |
896 void GeneralPageView::OnSelectionChanged() { | |
897 startup_remove_custom_page_button_->SetEnabled( | |
898 startup_custom_pages_table_->SelectedRowCount() > 0); | |
899 } | |
900 | |
901 void GeneralPageView::EnableHomepageURLField(bool enabled) { | |
902 if (homepage_.IsManaged()) { | |
903 enabled = false; | |
904 } | |
905 homepage_use_url_textfield_->SetEnabled(enabled); | |
906 homepage_use_url_textfield_->SetReadOnly(!enabled); | |
907 } | |
908 | |
909 void GeneralPageView::SetDefaultSearchProvider() { | |
910 const int index = default_search_engine_combobox_->selected_item(); | |
911 default_search_engines_model_->model()->SetDefaultSearchProvider( | |
912 default_search_engines_model_->GetTemplateURLAt(index)); | |
913 } | |
OLD | NEW |