Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(422)

Side by Side Diff: chrome/browser/ui/views/options/advanced_contents_view.cc

Issue 6670011: Options: Remove the GTK and Views native options code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase. Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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/advanced_contents_view.h"
6
7 #include <windows.h>
8
9 #include <cryptuiapi.h>
10 #pragma comment(lib, "cryptui.lib")
11 #include <shellapi.h>
12 #include <vsstyle.h>
13 #include <vssym32.h>
14
15 #include <string>
16
17 #include "base/command_line.h"
18 #include "base/file_util.h"
19 #include "base/i18n/rtl.h"
20 #include "base/message_loop.h"
21 #include "base/path_service.h"
22 #include "base/scoped_callback_factory.h"
23 #include "base/threading/thread.h"
24 #include "base/utf_string_conversions.h"
25 #include "chrome/browser/browser_list.h"
26 #include "chrome/browser/browser_process.h"
27 #include "chrome/browser/download/download_manager.h"
28 #include "chrome/browser/download/download_prefs.h"
29 #include "chrome/browser/google/google_util.h"
30 #include "chrome/browser/gears_integration.h"
31 #include "chrome/browser/prefs/pref_member.h"
32 #include "chrome/browser/prefs/pref_service.h"
33 #include "chrome/browser/prefs/pref_set_observer.h"
34 #include "chrome/browser/printing/cloud_print/cloud_print_proxy_service.h"
35 #include "chrome/browser/printing/cloud_print/cloud_print_setup_flow.h"
36 #include "chrome/browser/printing/cloud_print/cloud_print_url.h"
37 #include "chrome/browser/profiles/profile.h"
38 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
39 #include "chrome/browser/ui/options/options_util.h"
40 #include "chrome/browser/ui/options/show_options_url.h"
41 #include "chrome/browser/ui/shell_dialogs.h"
42 #include "chrome/browser/ui/views/browser_dialogs.h"
43 #include "chrome/browser/ui/views/clear_browsing_data_view.h"
44 #include "chrome/browser/ui/views/list_background.h"
45 #include "chrome/browser/ui/views/options/content_settings_window_view.h"
46 #include "chrome/browser/ui/views/options/fonts_languages_window_view.h"
47 #include "chrome/common/chrome_switches.h"
48 #include "chrome/common/pref_names.h"
49 #include "chrome/common/url_constants.h"
50 #include "content/browser/renderer_host/resource_dispatcher_host.h"
51 #include "grit/app_resources.h"
52 #include "grit/chromium_strings.h"
53 #include "grit/generated_resources.h"
54 #include "grit/locale_settings.h"
55 #include "net/base/ssl_config_service_win.h"
56 #include "skia/ext/skia_utils_win.h"
57 #include "third_party/skia/include/core/SkBitmap.h"
58 #include "ui/base/l10n/l10n_util.h"
59 #include "ui/base/resource/resource_bundle.h"
60 #include "ui/gfx/canvas_skia.h"
61 #include "ui/gfx/native_theme_win.h"
62 #include "views/background.h"
63 #include "views/controls/button/checkbox.h"
64 #include "views/controls/combobox/combobox.h"
65 #include "views/controls/scroll_view.h"
66 #include "views/controls/textfield/textfield.h"
67 #include "views/layout/grid_layout.h"
68 #include "views/layout/layout_constants.h"
69 #include "views/widget/widget.h"
70 #include "views/window/window.h"
71
72 using views::GridLayout;
73 using views::ColumnSet;
74
75 namespace {
76
77 const int kFileIconSize = 16;
78 const int kFileIconVerticalSpacing = 3;
79 const int kFileIconHorizontalSpacing = 3;
80 const int kFileIconTextFieldSpacing = 3;
81
82 ////////////////////////////////////////////////////////////////////////////////
83 // FileDisplayArea
84
85 class FileDisplayArea : public views::View {
86 public:
87 FileDisplayArea();
88 virtual ~FileDisplayArea();
89
90 void SetFile(const FilePath& file_path);
91
92 // views::View overrides:
93 virtual void OnPaint(gfx::Canvas* canvas);
94 virtual void Layout();
95 virtual gfx::Size GetPreferredSize();
96
97 protected:
98 // views::View overrides:
99 virtual void ViewHierarchyChanged(bool is_add,
100 views::View* parent,
101 views::View* child);
102
103 private:
104 void Init();
105
106 views::Textfield* text_field_;
107 SkColor text_field_background_color_;
108
109 gfx::Rect icon_bounds_;
110
111 bool initialized_;
112
113 static void InitClass();
114 static SkBitmap default_folder_icon_;
115
116 DISALLOW_COPY_AND_ASSIGN(FileDisplayArea);
117 };
118
119 // static
120 SkBitmap FileDisplayArea::default_folder_icon_;
121
122 FileDisplayArea::FileDisplayArea()
123 : text_field_(new views::Textfield),
124 text_field_background_color_(0),
125 initialized_(false) {
126 InitClass();
127 }
128
129 FileDisplayArea::~FileDisplayArea() {
130 }
131
132 void FileDisplayArea::SetFile(const FilePath& file_path) {
133 // Force file path to have LTR directionality.
134 if (base::i18n::IsRTL()) {
135 string16 localized_file_path;
136 base::i18n::WrapPathWithLTRFormatting(file_path, &localized_file_path);
137 text_field_->SetText(UTF16ToWide(localized_file_path));
138 } else {
139 text_field_->SetText(file_path.LossyDisplayName());
140 }
141 }
142
143 void FileDisplayArea::OnPaint(gfx::Canvas* canvas) {
144 HDC dc = canvas->BeginPlatformPaint();
145 RECT rect = { 0, 0, width(), height() };
146 gfx::NativeTheme::instance()->PaintTextField(
147 dc, EP_EDITTEXT, ETS_READONLY, 0, &rect,
148 skia::SkColorToCOLORREF(text_field_background_color_), true, true);
149 canvas->EndPlatformPaint();
150 // Mirror left point for icon_bounds_ to draw icon in RTL locales correctly.
151 canvas->DrawBitmapInt(default_folder_icon_, GetMirroredXForRect(icon_bounds_),
152 icon_bounds_.y());
153 }
154
155 void FileDisplayArea::Layout() {
156 icon_bounds_.SetRect(kFileIconHorizontalSpacing, kFileIconVerticalSpacing,
157 kFileIconSize, kFileIconSize);
158 gfx::Size ps = text_field_->GetPreferredSize();
159 text_field_->SetBounds(icon_bounds_.right() + kFileIconTextFieldSpacing,
160 (height() - ps.height()) / 2,
161 width() - icon_bounds_.right() -
162 kFileIconHorizontalSpacing -
163 kFileIconTextFieldSpacing, ps.height());
164 }
165
166 gfx::Size FileDisplayArea::GetPreferredSize() {
167 return gfx::Size(kFileIconSize + 2 * kFileIconVerticalSpacing,
168 kFileIconSize + 2 * kFileIconHorizontalSpacing);
169 }
170
171 void FileDisplayArea::ViewHierarchyChanged(bool is_add,
172 views::View* parent,
173 views::View* child) {
174 if (!initialized_ && is_add && GetWidget())
175 Init();
176 }
177
178 void FileDisplayArea::Init() {
179 initialized_ = true;
180 AddChildView(text_field_);
181 text_field_background_color_ =
182 gfx::NativeTheme::instance()->GetThemeColorWithDefault(
183 gfx::NativeTheme::TEXTFIELD, EP_EDITTEXT, ETS_READONLY,
184 TMT_FILLCOLOR, COLOR_3DFACE);
185 text_field_->SetReadOnly(true);
186 text_field_->RemoveBorder();
187 text_field_->SetBackgroundColor(text_field_background_color_);
188 }
189
190 // static
191 void FileDisplayArea::InitClass() {
192 static bool initialized = false;
193 if (!initialized) {
194 // We'd prefer to use base::i18n::IsRTL() to perform the RTL
195 // environment check, but it's nonstatic, so, instead, we check whether the
196 // locale is RTL.
197 bool ui_is_rtl = base::i18n::IsRTL();
198 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
199 default_folder_icon_ = *rb.GetBitmapNamed(ui_is_rtl ?
200 IDR_FOLDER_CLOSED_RTL :
201 IDR_FOLDER_CLOSED);
202 initialized = true;
203 }
204 }
205
206 ////////////////////////////////////////////////////////////////////////////////
207 // AdvancedSection
208 // A convenience view for grouping advanced options together into related
209 // sections.
210 //
211 class AdvancedSection : public OptionsPageView {
212 public:
213 AdvancedSection(Profile* profile, const std::wstring& title);
214 virtual ~AdvancedSection() {}
215
216 protected:
217 // Convenience helpers to add different kinds of ColumnSets for specific
218 // types of layout.
219 void AddWrappingColumnSet(views::GridLayout* layout, int id);
220 void AddDependentTwoColumnSet(views::GridLayout* layout, int id);
221 void AddTwoColumnSet(views::GridLayout* layout, int id);
222 void AddIndentedColumnSet(views::GridLayout* layout, int id);
223
224 // Convenience helpers for adding controls to specific layouts in an
225 // aesthetically pleasing way.
226 void AddWrappingCheckboxRow(views::GridLayout* layout,
227 views::Checkbox* checkbox,
228 int id,
229 bool related_follows);
230 void AddWrappingLabelRow(views::GridLayout* layout,
231 views::Label* label,
232 int id,
233 bool related_follows);
234 void AddLabeledTwoColumnRow(views::GridLayout* layout,
235 views::Label* label,
236 views::View* control,
237 bool control_stretches,
238 int id,
239 bool related_follows);
240 void AddTwoColumnRow(views::GridLayout* layout,
241 views::View* first,
242 views::View* second,
243 bool control_stretches, // Whether or not the control
244 // expands to fill the width.
245 int id,
246 int trailing_space);
247 void AddLeadingControl(views::GridLayout* layout,
248 views::View* control,
249 int id,
250 bool related_follows);
251 void AddIndentedControl(views::GridLayout* layout,
252 views::View* control,
253 int id,
254 bool related_follows);
255 void AddSpacing(views::GridLayout* layout, bool related_follows);
256
257 // OptionsPageView overrides:
258 virtual void InitControlLayout();
259
260 // The View that contains the contents of the section.
261 views::View* contents_;
262
263 private:
264 // The section title.
265 views::Label* title_label_;
266
267 DISALLOW_COPY_AND_ASSIGN(AdvancedSection);
268 };
269
270 ////////////////////////////////////////////////////////////////////////////////
271 // AdvancedSection, public:
272
273 AdvancedSection::AdvancedSection(Profile* profile,
274 const std::wstring& title)
275 : contents_(NULL),
276 title_label_(new views::Label(title)),
277 OptionsPageView(profile) {
278 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
279 gfx::Font title_font =
280 rb.GetFont(ResourceBundle::BaseFont).DeriveFont(0, gfx::Font::BOLD);
281 title_label_->SetFont(title_font);
282
283 SkColor title_color = gfx::NativeTheme::instance()->GetThemeColorWithDefault(
284 gfx::NativeTheme::BUTTON, BP_GROUPBOX, GBS_NORMAL, TMT_TEXTCOLOR,
285 COLOR_WINDOWTEXT);
286 title_label_->SetColor(title_color);
287 }
288
289 ////////////////////////////////////////////////////////////////////////////////
290 // AdvancedSection, protected:
291
292 void AdvancedSection::AddWrappingColumnSet(views::GridLayout* layout, int id) {
293 ColumnSet* column_set = layout->AddColumnSet(id);
294 column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1,
295 GridLayout::USE_PREF, 0, 0);
296 }
297
298 void AdvancedSection::AddDependentTwoColumnSet(views::GridLayout* layout,
299 int id) {
300 ColumnSet* column_set = layout->AddColumnSet(id);
301 column_set->AddPaddingColumn(0, views::Checkbox::GetTextIndent());
302 column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 0,
303 GridLayout::USE_PREF, 0, 0);
304 column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
305 column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1,
306 GridLayout::USE_PREF, 0, 0);
307 column_set->AddPaddingColumn(0, views::kUnrelatedControlHorizontalSpacing);
308 }
309
310 void AdvancedSection::AddTwoColumnSet(views::GridLayout* layout, int id) {
311 ColumnSet* column_set = layout->AddColumnSet(id);
312 column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 0,
313 GridLayout::USE_PREF, 0, 0);
314 column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
315 column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1,
316 GridLayout::USE_PREF, 0, 0);
317 }
318
319 void AdvancedSection::AddIndentedColumnSet(views::GridLayout* layout, int id) {
320 ColumnSet* column_set = layout->AddColumnSet(id);
321 column_set->AddPaddingColumn(0, views::Checkbox::GetTextIndent());
322 column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1,
323 GridLayout::USE_PREF, 0, 0);
324 }
325
326 void AdvancedSection::AddWrappingCheckboxRow(views::GridLayout* layout,
327 views::Checkbox* checkbox,
328 int id,
329 bool related_follows) {
330 checkbox->SetMultiLine(true);
331 layout->StartRow(0, id);
332 layout->AddView(checkbox);
333 AddSpacing(layout, related_follows);
334 }
335
336 void AdvancedSection::AddWrappingLabelRow(views::GridLayout* layout,
337 views::Label* label,
338 int id,
339 bool related_follows) {
340 label->SetMultiLine(true);
341 label->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
342 layout->StartRow(0, id);
343 layout->AddView(label);
344 AddSpacing(layout, related_follows);
345 }
346
347 void AdvancedSection::AddLabeledTwoColumnRow(views::GridLayout* layout,
348 views::Label* label,
349 views::View* control,
350 bool control_stretches,
351 int id,
352 bool related_follows) {
353 label->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
354 AddTwoColumnRow(layout, label, control, control_stretches, id,
355 related_follows ? views::kRelatedControlVerticalSpacing
356 : views::kUnrelatedControlVerticalSpacing);
357 }
358
359 void AdvancedSection::AddTwoColumnRow(views::GridLayout* layout,
360 views::View* first,
361 views::View* second,
362 bool control_stretches,
363 int id,
364 int trailing_space) {
365 layout->StartRow(0, id);
366 layout->AddView(first);
367 if (control_stretches) {
368 layout->AddView(second);
369 } else {
370 layout->AddView(second, 1, 1, views::GridLayout::LEADING,
371 views::GridLayout::CENTER);
372 }
373 layout->AddPaddingRow(0, trailing_space);
374 }
375
376 void AdvancedSection::AddLeadingControl(views::GridLayout* layout,
377 views::View* control,
378 int id,
379 bool related_follows) {
380 layout->StartRow(0, id);
381 layout->AddView(control, 1, 1, GridLayout::LEADING, GridLayout::CENTER);
382 AddSpacing(layout, related_follows);
383 }
384
385 void AdvancedSection::AddSpacing(views::GridLayout* layout,
386 bool related_follows) {
387 layout->AddPaddingRow(
388 0, related_follows ? views::kRelatedControlVerticalSpacing
389 : views::kUnrelatedControlVerticalSpacing);
390 }
391
392 ////////////////////////////////////////////////////////////////////////////////
393 // AdvancedSection, OptionsPageView overrides:
394
395 void AdvancedSection::InitControlLayout() {
396 contents_ = new views::View;
397
398 GridLayout* layout = new GridLayout(this);
399 SetLayoutManager(layout);
400
401 const int single_column_layout_id = 0;
402 ColumnSet* column_set = layout->AddColumnSet(single_column_layout_id);
403 column_set->AddColumn(GridLayout::LEADING, GridLayout::LEADING, 0,
404 GridLayout::USE_PREF, 0, 0);
405 const int inset_column_layout_id = 1;
406 column_set = layout->AddColumnSet(inset_column_layout_id);
407 column_set->AddPaddingColumn(0, views::kUnrelatedControlHorizontalSpacing);
408 column_set->AddColumn(GridLayout::FILL, GridLayout::LEADING, 1,
409 GridLayout::USE_PREF, 0, 0);
410
411 layout->StartRow(0, single_column_layout_id);
412 layout->AddView(title_label_);
413 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
414 layout->StartRow(0, inset_column_layout_id);
415 layout->AddView(contents_);
416 }
417
418 ////////////////////////////////////////////////////////////////////////////////
419 // PrivacySection
420
421 class PrivacySection : public AdvancedSection,
422 public views::ButtonListener,
423 public views::LinkController {
424 public:
425 explicit PrivacySection(Profile* profile);
426 virtual ~PrivacySection() {}
427
428 // Overridden from views::ButtonListener:
429 virtual void ButtonPressed(views::Button* sender, const views::Event& event);
430
431 // Overridden from views::LinkController:
432 virtual void LinkActivated(views::Link* source, int event_flags);
433
434 protected:
435 // OptionsPageView overrides:
436 virtual void InitControlLayout();
437 virtual void NotifyPrefChanged(const std::string* pref_name);
438
439 private:
440 // Controls for this section:
441 views::NativeButton* content_settings_button_;
442 views::NativeButton* clear_data_button_;
443 views::Label* section_description_label_;
444 views::Checkbox* enable_link_doctor_checkbox_;
445 views::Checkbox* enable_suggest_checkbox_;
446 views::Checkbox* enable_dns_prefetching_checkbox_;
447 views::Checkbox* enable_safe_browsing_checkbox_;
448 views::Checkbox* reporting_enabled_checkbox_;
449 views::Link* learn_more_link_;
450
451 // Preferences for this section:
452 BooleanPrefMember alternate_error_pages_;
453 BooleanPrefMember use_suggest_;
454 BooleanPrefMember dns_prefetch_enabled_;
455 BooleanPrefMember safe_browsing_;
456 BooleanPrefMember enable_metrics_recording_;
457
458 void ResolveMetricsReportingEnabled();
459
460 DISALLOW_COPY_AND_ASSIGN(PrivacySection);
461 };
462
463 PrivacySection::PrivacySection(Profile* profile)
464 : content_settings_button_(NULL),
465 clear_data_button_(NULL),
466 section_description_label_(NULL),
467 enable_link_doctor_checkbox_(NULL),
468 enable_suggest_checkbox_(NULL),
469 enable_dns_prefetching_checkbox_(NULL),
470 enable_safe_browsing_checkbox_(NULL),
471 reporting_enabled_checkbox_(NULL),
472 learn_more_link_(NULL),
473 AdvancedSection(profile, UTF16ToWide(l10n_util::GetStringUTF16(
474 IDS_OPTIONS_ADVANCED_SECTION_TITLE_PRIVACY))) {
475 }
476
477 void PrivacySection::ButtonPressed(
478 views::Button* sender, const views::Event& event) {
479 if (sender == enable_link_doctor_checkbox_) {
480 bool enabled = enable_link_doctor_checkbox_->checked();
481 UserMetricsRecordAction(UserMetricsAction(enabled ?
482 "Options_LinkDoctorCheckbox_Enable" :
483 "Options_LinkDoctorCheckbox_Disable"),
484 profile()->GetPrefs());
485 alternate_error_pages_.SetValue(enabled);
486 } else if (sender == enable_suggest_checkbox_) {
487 bool enabled = enable_suggest_checkbox_->checked();
488 UserMetricsRecordAction(UserMetricsAction(enabled ?
489 "Options_UseSuggestCheckbox_Enable" :
490 "Options_UseSuggestCheckbox_Disable"),
491 profile()->GetPrefs());
492 use_suggest_.SetValue(enabled);
493 } else if (sender == enable_dns_prefetching_checkbox_) {
494 bool enabled = enable_dns_prefetching_checkbox_->checked();
495 UserMetricsRecordAction(UserMetricsAction(enabled ?
496 "Options_DnsPrefetchCheckbox_Enable" :
497 "Options_DnsPrefetchCheckbox_Disable"),
498 profile()->GetPrefs());
499 dns_prefetch_enabled_.SetValue(enabled);
500 } else if (sender == enable_safe_browsing_checkbox_) {
501 bool enabled = enable_safe_browsing_checkbox_->checked();
502 UserMetricsRecordAction(UserMetricsAction(enabled ?
503 "Options_SafeBrowsingCheckbox_Enable" :
504 "Options_SafeBrowsingCheckbox_Disable"),
505 profile()->GetPrefs());
506 safe_browsing_.SetValue(enabled);
507 SafeBrowsingService* safe_browsing_service =
508 g_browser_process->resource_dispatcher_host()->safe_browsing_service();
509 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
510 safe_browsing_service, &SafeBrowsingService::OnEnable, enabled));
511 } else if (reporting_enabled_checkbox_ &&
512 (sender == reporting_enabled_checkbox_)) {
513 bool enabled = reporting_enabled_checkbox_->checked();
514 UserMetricsRecordAction(UserMetricsAction(enabled ?
515 "Options_MetricsReportingCheckbox_Enable" :
516 "Options_MetricsReportingCheckbox_Disable"),
517 profile()->GetPrefs());
518 ResolveMetricsReportingEnabled();
519 enable_metrics_recording_.SetValue(enabled);
520 } else if (sender == content_settings_button_) {
521 UserMetricsRecordAction(UserMetricsAction("Options_ContentSettings"), NULL);
522 browser::ShowContentSettingsWindow(GetWindow()->GetNativeWindow(),
523 CONTENT_SETTINGS_TYPE_DEFAULT, profile());
524 } else if (sender == clear_data_button_) {
525 UserMetricsRecordAction(UserMetricsAction("Options_ClearData"), NULL);
526 views::Window::CreateChromeWindow(
527 GetWindow()->GetNativeWindow(),
528 gfx::Rect(),
529 new ClearBrowsingDataView(profile()))->Show();
530 }
531 }
532
533 void PrivacySection::LinkActivated(views::Link* source, int event_flags) {
534 DCHECK(source == learn_more_link_);
535 GURL url = google_util::AppendGoogleLocaleParam(
536 GURL(chrome::kPrivacyLearnMoreURL));
537 browser::ShowOptionsURL(profile(), url);
538 }
539
540 void PrivacySection::InitControlLayout() {
541 AdvancedSection::InitControlLayout();
542
543 content_settings_button_ = new views::NativeButton(
544 this,
545 UTF16ToWide(l10n_util::GetStringUTF16(
546 IDS_OPTIONS_PRIVACY_CONTENT_SETTINGS_BUTTON)));
547 clear_data_button_ = new views::NativeButton(
548 this,
549 UTF16ToWide(l10n_util::GetStringUTF16(
550 IDS_OPTIONS_PRIVACY_CLEAR_DATA_BUTTON)));
551 section_description_label_ = new views::Label(
552 UTF16ToWide(l10n_util::GetStringUTF16(IDS_OPTIONS_DISABLE_SERVICES)));
553 enable_link_doctor_checkbox_ = new views::Checkbox(
554 UTF16ToWide(l10n_util::GetStringUTF16(IDS_OPTIONS_LINKDOCTOR_PREF)));
555 enable_link_doctor_checkbox_->set_listener(this);
556 enable_suggest_checkbox_ = new views::Checkbox(
557 UTF16ToWide(l10n_util::GetStringUTF16(IDS_OPTIONS_SUGGEST_PREF)));
558 enable_suggest_checkbox_->set_listener(this);
559 enable_dns_prefetching_checkbox_ = new views::Checkbox(
560 UTF16ToWide(l10n_util::GetStringUTF16(
561 IDS_NETWORK_DNS_PREFETCH_ENABLED_DESCRIPTION)));
562 enable_dns_prefetching_checkbox_->set_listener(this);
563 enable_safe_browsing_checkbox_ = new views::Checkbox(
564 UTF16ToWide(l10n_util::GetStringUTF16(
565 IDS_OPTIONS_SAFEBROWSING_ENABLEPROTECTION)));
566 enable_safe_browsing_checkbox_->set_listener(this);
567 #if defined(GOOGLE_CHROME_BUILD)
568 reporting_enabled_checkbox_ = new views::Checkbox(
569 UTF16ToWide(l10n_util::GetStringUTF16(IDS_OPTIONS_ENABLE_LOGGING)));
570 reporting_enabled_checkbox_->SetMultiLine(true);
571 reporting_enabled_checkbox_->set_listener(this);
572 reporting_enabled_checkbox_->SetVisible(true);
573 #endif
574 learn_more_link_ = new views::Link(
575 UTF16ToWide(l10n_util::GetStringUTF16(IDS_LEARN_MORE)));
576 learn_more_link_->SetController(this);
577
578 GridLayout* layout = new GridLayout(contents_);
579 contents_->SetLayoutManager(layout);
580
581 const int leading_column_set_id = 0;
582 AddTwoColumnSet(layout, leading_column_set_id);
583 const int single_column_view_set_id = 1;
584 AddWrappingColumnSet(layout, single_column_view_set_id);
585 const int dependent_labeled_field_set_id = 2;
586 AddDependentTwoColumnSet(layout, dependent_labeled_field_set_id);
587 const int indented_view_set_id = 3;
588 AddIndentedColumnSet(layout, indented_view_set_id);
589 const int indented_column_set_id = 4;
590 AddIndentedColumnSet(layout, indented_column_set_id);
591
592 AddTwoColumnRow(layout, content_settings_button_, clear_data_button_, false,
593 leading_column_set_id,
594 views::kUnrelatedControlLargeVerticalSpacing);
595
596 // The description label at the top and label.
597 section_description_label_->SetMultiLine(true);
598 AddWrappingLabelRow(layout, section_description_label_,
599 single_column_view_set_id, true);
600 // Learn more link.
601 AddLeadingControl(layout, learn_more_link_,
602 single_column_view_set_id, true);
603
604 // Link doctor.
605 AddWrappingCheckboxRow(layout, enable_link_doctor_checkbox_,
606 indented_view_set_id, true);
607 // Use Suggest service.
608 AddWrappingCheckboxRow(layout, enable_suggest_checkbox_,
609 indented_view_set_id, true);
610 // DNS pre-fetching.
611 AddWrappingCheckboxRow(layout, enable_dns_prefetching_checkbox_,
612 indented_view_set_id, true);
613 // Safe browsing controls.
614 AddWrappingCheckboxRow(layout, enable_safe_browsing_checkbox_,
615 indented_view_set_id,
616 reporting_enabled_checkbox_ != NULL);
617 // The "Help make Google Chrome better" checkbox.
618 if (reporting_enabled_checkbox_) {
619 AddWrappingCheckboxRow(layout, reporting_enabled_checkbox_,
620 indented_view_set_id, false);
621 }
622
623 // Init member prefs so we can update the controls if prefs change.
624 alternate_error_pages_.Init(prefs::kAlternateErrorPagesEnabled,
625 profile()->GetPrefs(), this);
626 use_suggest_.Init(prefs::kSearchSuggestEnabled,
627 profile()->GetPrefs(), this);
628 dns_prefetch_enabled_.Init(prefs::kDnsPrefetchingEnabled,
629 profile()->GetPrefs(), this);
630 safe_browsing_.Init(prefs::kSafeBrowsingEnabled, profile()->GetPrefs(), this);
631 enable_metrics_recording_.Init(prefs::kMetricsReportingEnabled,
632 g_browser_process->local_state(), this);
633 }
634
635 void PrivacySection::NotifyPrefChanged(const std::string* pref_name) {
636 if (!pref_name || *pref_name == prefs::kAlternateErrorPagesEnabled) {
637 enable_link_doctor_checkbox_->SetEnabled(
638 !alternate_error_pages_.IsManaged());
639 enable_link_doctor_checkbox_->SetChecked(
640 alternate_error_pages_.GetValue());
641 }
642 if (!pref_name || *pref_name == prefs::kSearchSuggestEnabled) {
643 enable_suggest_checkbox_->SetEnabled(!use_suggest_.IsManaged());
644 enable_suggest_checkbox_->SetChecked(use_suggest_.GetValue());
645 }
646 if (!pref_name || *pref_name == prefs::kDnsPrefetchingEnabled) {
647 enable_dns_prefetching_checkbox_->SetEnabled(
648 !dns_prefetch_enabled_.IsManaged());
649 bool enabled = dns_prefetch_enabled_.GetValue();
650 enable_dns_prefetching_checkbox_->SetChecked(enabled);
651 }
652 if (!pref_name || *pref_name == prefs::kSafeBrowsingEnabled) {
653 enable_safe_browsing_checkbox_->SetEnabled(!safe_browsing_.IsManaged());
654 enable_safe_browsing_checkbox_->SetChecked(safe_browsing_.GetValue());
655 }
656 if (reporting_enabled_checkbox_ &&
657 (!pref_name || *pref_name == prefs::kMetricsReportingEnabled)) {
658 reporting_enabled_checkbox_->SetEnabled(
659 !enable_metrics_recording_.IsManaged());
660 reporting_enabled_checkbox_->SetChecked(
661 enable_metrics_recording_.GetValue());
662 ResolveMetricsReportingEnabled();
663 }
664 }
665
666 void PrivacySection::ResolveMetricsReportingEnabled() {
667 DCHECK(reporting_enabled_checkbox_);
668 bool enabled = reporting_enabled_checkbox_->checked();
669
670 enabled = OptionsUtil::ResolveMetricsReportingEnabled(enabled);
671
672 reporting_enabled_checkbox_->SetChecked(enabled);
673 }
674
675 ////////////////////////////////////////////////////////////////////////////////
676 // WebContentSection
677
678 class WebContentSection : public AdvancedSection,
679 public views::ButtonListener {
680 public:
681 explicit WebContentSection(Profile* profile);
682 virtual ~WebContentSection() {}
683
684 // Overridden from views::ButtonListener:
685 virtual void ButtonPressed(views::Button* sender, const views::Event& event);
686
687 protected:
688 // OptionsPageView overrides:
689 virtual void InitControlLayout();
690
691 private:
692 // Controls for this section:
693 views::Label* fonts_and_languages_label_;
694 views::NativeButton* change_content_fonts_button_;
695 views::Label* gears_label_;
696 views::NativeButton* gears_settings_button_;
697
698 DISALLOW_COPY_AND_ASSIGN(WebContentSection);
699 };
700
701 WebContentSection::WebContentSection(Profile* profile)
702 : fonts_and_languages_label_(NULL),
703 change_content_fonts_button_(NULL),
704 gears_label_(NULL),
705 gears_settings_button_(NULL),
706 AdvancedSection(profile, UTF16ToWide(l10n_util::GetStringUTF16(
707 IDS_OPTIONS_ADVANCED_SECTION_TITLE_CONTENT))) {
708 }
709
710 void WebContentSection::ButtonPressed(
711 views::Button* sender, const views::Event& event) {
712 if (sender == gears_settings_button_) {
713 UserMetricsRecordAction(UserMetricsAction("Options_GearsSettings"), NULL);
714 GearsSettingsPressed(GetAncestor(GetWidget()->GetNativeView(), GA_ROOT));
715 } else if (sender == change_content_fonts_button_) {
716 views::Window::CreateChromeWindow(
717 GetWindow()->GetNativeWindow(),
718 gfx::Rect(),
719 new FontsLanguagesWindowView(profile()))->Show();
720 }
721 }
722
723 void WebContentSection::InitControlLayout() {
724 AdvancedSection::InitControlLayout();
725
726 if (!base::i18n::IsRTL()) {
727 gears_label_ = new views::Label(UTF16ToWide(
728 l10n_util::GetStringUTF16(IDS_OPTIONS_GEARSSETTINGS_GROUP_NAME)));
729 } else {
730 // Add an RTL mark so that
731 // ":" in "Google Gears:" in Hebrew Chrome is displayed left-most.
732 std::wstring gearssetting_group_name = UTF16ToWide(
733 l10n_util::GetStringUTF16(IDS_OPTIONS_GEARSSETTINGS_GROUP_NAME));
734 gearssetting_group_name.push_back(
735 static_cast<wchar_t>(base::i18n::kRightToLeftMark));
736 gears_label_ = new views::Label(gearssetting_group_name);
737 }
738 gears_settings_button_ = new views::NativeButton(
739 this,
740 UTF16ToWide(l10n_util::GetStringUTF16(
741 IDS_OPTIONS_GEARSSETTINGS_CONFIGUREGEARS_BUTTON)));
742 fonts_and_languages_label_ = new views::Label(
743 UTF16ToWide(l10n_util::GetStringUTF16(IDS_OPTIONS_FONTSETTINGS_INFO)));
744
745 change_content_fonts_button_ = new views::NativeButton(
746 this,
747 UTF16ToWide(l10n_util::GetStringUTF16(
748 IDS_OPTIONS_FONTSETTINGS_CONFIGUREFONTS_BUTTON)));
749
750 GridLayout* layout = new GridLayout(contents_);
751 contents_->SetLayoutManager(layout);
752
753 const int single_column_view_set_id = 0;
754 AddWrappingColumnSet(layout, single_column_view_set_id);
755 const int indented_column_set_id = 1;
756 AddIndentedColumnSet(layout, indented_column_set_id);
757 const int single_double_column_set = 2;
758 AddTwoColumnSet(layout, single_double_column_set);
759
760 // Fonts and Languages.
761 AddWrappingLabelRow(layout, fonts_and_languages_label_,
762 single_column_view_set_id,
763 true);
764 AddLeadingControl(layout, change_content_fonts_button_,
765 indented_column_set_id,
766 false);
767
768 // Gears.
769 AddLabeledTwoColumnRow(layout, gears_label_, gears_settings_button_, false,
770 single_double_column_set, false);
771 }
772
773 ////////////////////////////////////////////////////////////////////////////////
774 // SecuritySection
775
776 class SecuritySection : public AdvancedSection,
777 public views::ButtonListener {
778 public:
779 explicit SecuritySection(Profile* profile);
780 virtual ~SecuritySection() {}
781
782 // Overridden from views::ButtonListener:
783 virtual void ButtonPressed(views::Button* sender, const views::Event& event);
784
785 protected:
786 // OptionsPageView overrides:
787 virtual void InitControlLayout();
788 virtual void NotifyPrefChanged(const std::string* pref_name);
789
790 private:
791 // Controls for this section:
792 views::Label* ssl_info_label_;
793 views::Checkbox* enable_ssl3_checkbox_;
794 views::Checkbox* enable_tls1_checkbox_;
795 views::Checkbox* check_for_cert_revocation_checkbox_;
796 views::Label* manage_certificates_label_;
797 views::NativeButton* manage_certificates_button_;
798
799 DISALLOW_COPY_AND_ASSIGN(SecuritySection);
800 };
801
802 SecuritySection::SecuritySection(Profile* profile)
803 : ssl_info_label_(NULL),
804 enable_ssl3_checkbox_(NULL),
805 enable_tls1_checkbox_(NULL),
806 check_for_cert_revocation_checkbox_(NULL),
807 manage_certificates_label_(NULL),
808 manage_certificates_button_(NULL),
809 AdvancedSection(profile, UTF16ToWide(l10n_util::GetStringUTF16(
810 IDS_OPTIONS_ADVANCED_SECTION_TITLE_SECURITY))) {
811 }
812
813 void SecuritySection::ButtonPressed(
814 views::Button* sender, const views::Event& event) {
815 if (sender == enable_ssl3_checkbox_) {
816 bool enabled = enable_ssl3_checkbox_->checked();
817 if (enabled) {
818 UserMetricsRecordAction(UserMetricsAction("Options_SSL3_Enable"), NULL);
819 } else {
820 UserMetricsRecordAction(UserMetricsAction("Options_SSL3_Disable"), NULL);
821 }
822 net::SSLConfigServiceWin::SetSSL3Enabled(enabled);
823 } else if (sender == enable_tls1_checkbox_) {
824 bool enabled = enable_tls1_checkbox_->checked();
825 if (enabled) {
826 UserMetricsRecordAction(UserMetricsAction("Options_TLS1_Enable"), NULL);
827 } else {
828 UserMetricsRecordAction(UserMetricsAction("Options_TLS1_Disable"), NULL);
829 }
830 net::SSLConfigServiceWin::SetTLS1Enabled(enabled);
831 } else if (sender == check_for_cert_revocation_checkbox_) {
832 bool enabled = check_for_cert_revocation_checkbox_->checked();
833 if (enabled) {
834 UserMetricsRecordAction(
835 UserMetricsAction("Options_CheckCertRevocation_Enable"), NULL);
836 } else {
837 UserMetricsRecordAction(
838 UserMetricsAction("Options_CheckCertRevocation_Disable"), NULL);
839 }
840 net::SSLConfigServiceWin::SetRevCheckingEnabled(enabled);
841 } else if (sender == manage_certificates_button_) {
842 UserMetricsRecordAction(UserMetricsAction("Options_ManagerCerts"), NULL);
843 CRYPTUI_CERT_MGR_STRUCT cert_mgr = { 0 };
844 cert_mgr.dwSize = sizeof(CRYPTUI_CERT_MGR_STRUCT);
845 cert_mgr.hwndParent = GetWindow()->GetNativeWindow();
846 ::CryptUIDlgCertMgr(&cert_mgr);
847 }
848 }
849
850 void SecuritySection::InitControlLayout() {
851 AdvancedSection::InitControlLayout();
852
853 ssl_info_label_ = new views::Label(UTF16ToWide(
854 l10n_util::GetStringUTF16(IDS_OPTIONS_SSL_GROUP_DESCRIPTION)));
855 enable_ssl3_checkbox_ = new views::Checkbox(
856 UTF16ToWide(l10n_util::GetStringUTF16(IDS_OPTIONS_SSL_USESSL3)));
857 enable_ssl3_checkbox_->set_listener(this);
858 enable_tls1_checkbox_ = new views::Checkbox(
859 UTF16ToWide(l10n_util::GetStringUTF16(IDS_OPTIONS_SSL_USETLS1)));
860 enable_tls1_checkbox_->set_listener(this);
861 check_for_cert_revocation_checkbox_ = new views::Checkbox(
862 UTF16ToWide(l10n_util::GetStringUTF16(IDS_OPTIONS_SSL_CHECKREVOCATION)));
863 check_for_cert_revocation_checkbox_->set_listener(this);
864 manage_certificates_label_ = new views::Label(
865 UTF16ToWide(l10n_util::GetStringUTF16(IDS_OPTIONS_CERTIFICATES_LABEL)));
866 manage_certificates_button_ = new views::NativeButton(
867 this,
868 UTF16ToWide(
869 l10n_util::GetStringUTF16(IDS_OPTIONS_CERTIFICATES_MANAGE_BUTTON)));
870
871 GridLayout* layout = new GridLayout(contents_);
872 contents_->SetLayoutManager(layout);
873
874 const int single_column_view_set_id = 0;
875 AddWrappingColumnSet(layout, single_column_view_set_id);
876 const int dependent_labeled_field_set_id = 1;
877 AddDependentTwoColumnSet(layout, dependent_labeled_field_set_id);
878 const int double_column_view_set_id = 2;
879 AddTwoColumnSet(layout, double_column_view_set_id);
880 const int indented_column_set_id = 3;
881 AddIndentedColumnSet(layout, indented_column_set_id);
882 const int indented_view_set_id = 4;
883 AddIndentedColumnSet(layout, indented_view_set_id);
884
885 // SSL connection controls and Certificates.
886 AddWrappingLabelRow(layout, manage_certificates_label_,
887 single_column_view_set_id, true);
888 AddLeadingControl(layout, manage_certificates_button_,
889 indented_column_set_id, false);
890 AddWrappingLabelRow(layout, ssl_info_label_, single_column_view_set_id,
891 true);
892 AddWrappingCheckboxRow(layout, enable_ssl3_checkbox_,
893 indented_column_set_id, true);
894 AddWrappingCheckboxRow(layout, enable_tls1_checkbox_,
895 indented_column_set_id, true);
896 AddWrappingCheckboxRow(layout, check_for_cert_revocation_checkbox_,
897 indented_column_set_id, false);
898 }
899
900 // This method is called with a null pref_name when the dialog is initialized.
901 void SecuritySection::NotifyPrefChanged(const std::string* pref_name) {
902 // These SSL options are system settings and stored in the OS.
903 if (!pref_name) {
904 net::SSLConfig config;
905 if (net::SSLConfigServiceWin::GetSSLConfigNow(&config)) {
906 enable_ssl3_checkbox_->SetChecked(config.ssl3_enabled);
907 enable_tls1_checkbox_->SetChecked(config.tls1_enabled);
908 check_for_cert_revocation_checkbox_->SetChecked(
909 config.rev_checking_enabled);
910 } else {
911 enable_ssl3_checkbox_->SetEnabled(false);
912 enable_tls1_checkbox_->SetEnabled(false);
913 check_for_cert_revocation_checkbox_->SetEnabled(false);
914 }
915 }
916 }
917
918 ////////////////////////////////////////////////////////////////////////////////
919 // NetworkSection
920
921 // A helper method that opens the Internet Options control panel dialog with
922 // the Connections tab selected.
923 class OpenConnectionDialogTask : public Task {
924 public:
925 OpenConnectionDialogTask() {}
926
927 virtual void Run() {
928 // Using rundll32 seems better than LaunchConnectionDialog which causes a
929 // new dialog to be made for each call. rundll32 uses the same global
930 // dialog and it seems to share with the shortcut in control panel.
931 FilePath rundll32;
932 PathService::Get(base::DIR_SYSTEM, &rundll32);
933 rundll32 = rundll32.AppendASCII("rundll32.exe");
934
935 FilePath shell32dll;
936 PathService::Get(base::DIR_SYSTEM, &shell32dll);
937 shell32dll = shell32dll.AppendASCII("shell32.dll");
938
939 FilePath inetcpl;
940 PathService::Get(base::DIR_SYSTEM, &inetcpl);
941 inetcpl = inetcpl.AppendASCII("inetcpl.cpl,,4");
942
943 std::wstring args(shell32dll.value());
944 args.append(L",Control_RunDLL ");
945 args.append(inetcpl.value());
946
947 ShellExecute(NULL, L"open", rundll32.value().c_str(), args.c_str(), NULL,
948 SW_SHOWNORMAL);
949 }
950
951 private:
952 DISALLOW_COPY_AND_ASSIGN(OpenConnectionDialogTask);
953 };
954
955 class NetworkSection : public AdvancedSection,
956 public views::ButtonListener {
957 public:
958 explicit NetworkSection(Profile* profile);
959 virtual ~NetworkSection() {}
960
961 // Overridden from views::ButtonListener:
962 virtual void ButtonPressed(views::Button* sender, const views::Event& event);
963
964 protected:
965 // OptionsPageView overrides:
966 virtual void InitControlLayout();
967 virtual void NotifyPrefChanged(const std::string* pref_name);
968
969 private:
970 // Controls for this section:
971 views::Label* change_proxies_label_;
972 views::NativeButton* change_proxies_button_;
973
974 // Tracks the proxy preferences.
975 scoped_ptr<PrefSetObserver> proxy_prefs_;
976
977 DISALLOW_COPY_AND_ASSIGN(NetworkSection);
978 };
979
980 NetworkSection::NetworkSection(Profile* profile)
981 : change_proxies_label_(NULL),
982 change_proxies_button_(NULL),
983 AdvancedSection(profile, UTF16ToWide(l10n_util::GetStringUTF16(
984 IDS_OPTIONS_ADVANCED_SECTION_TITLE_NETWORK))) {
985 }
986
987 void NetworkSection::ButtonPressed(
988 views::Button* sender, const views::Event& event) {
989 if (sender == change_proxies_button_) {
990 UserMetricsRecordAction(UserMetricsAction("Options_ChangeProxies"), NULL);
991 base::Thread* thread = g_browser_process->file_thread();
992 DCHECK(thread);
993 thread->message_loop()->PostTask(FROM_HERE, new OpenConnectionDialogTask);
994 }
995 }
996
997 void NetworkSection::InitControlLayout() {
998 AdvancedSection::InitControlLayout();
999
1000 change_proxies_label_ = new views::Label(
1001 UTF16ToWide(l10n_util::GetStringUTF16(IDS_OPTIONS_PROXIES_LABEL)));
1002 change_proxies_button_ = new views::NativeButton(
1003 this, UTF16ToWide(
1004 l10n_util::GetStringUTF16(IDS_OPTIONS_PROXIES_CONFIGURE_BUTTON)));
1005
1006 GridLayout* layout = new GridLayout(contents_);
1007 contents_->SetLayoutManager(layout);
1008
1009 const int single_column_view_set_id = 0;
1010 AddWrappingColumnSet(layout, single_column_view_set_id);
1011 const int indented_view_set_id = 1;
1012 AddIndentedColumnSet(layout, indented_view_set_id);
1013 const int dependent_labeled_field_set_id = 2;
1014 AddDependentTwoColumnSet(layout, dependent_labeled_field_set_id);
1015 const int dns_set_id = 3;
1016 AddDependentTwoColumnSet(layout, dns_set_id);
1017
1018 // Proxy settings.
1019 AddWrappingLabelRow(layout, change_proxies_label_, single_column_view_set_id,
1020 true);
1021 AddLeadingControl(layout, change_proxies_button_, indented_view_set_id,
1022 false);
1023
1024 proxy_prefs_.reset(PrefSetObserver::CreateProxyPrefSetObserver(
1025 profile()->GetPrefs(), this));
1026 NotifyPrefChanged(NULL);
1027 }
1028
1029 void NetworkSection::NotifyPrefChanged(const std::string* pref_name) {
1030 if (!pref_name || proxy_prefs_->IsObserved(*pref_name)) {
1031 change_proxies_button_->SetEnabled(!proxy_prefs_->IsManaged());
1032 }
1033 }
1034
1035 } // namespace
1036
1037 ////////////////////////////////////////////////////////////////////////////////
1038 // DownloadSection
1039
1040 class DownloadSection : public AdvancedSection,
1041 public views::ButtonListener,
1042 public SelectFileDialog::Listener {
1043 public:
1044 explicit DownloadSection(Profile* profile);
1045 virtual ~DownloadSection() {
1046 select_file_dialog_->ListenerDestroyed();
1047 }
1048
1049 // Overridden from views::ButtonListener.
1050 virtual void ButtonPressed(views::Button* sender, const views::Event& event);
1051
1052 // SelectFileDialog::Listener implementation.
1053 virtual void FileSelected(const FilePath& path, int index, void* params);
1054
1055 // OptionsPageView implementation.
1056 virtual bool CanClose() const;
1057
1058 protected:
1059 // OptionsPageView overrides.
1060 virtual void InitControlLayout();
1061 virtual void NotifyPrefChanged(const std::string* pref_name);
1062
1063 private:
1064 // Controls for this section.
1065 views::Label* download_file_location_label_;
1066 FileDisplayArea* download_default_download_location_display_;
1067 views::NativeButton* download_browse_button_;
1068 views::Checkbox* download_ask_for_save_location_checkbox_;
1069 scoped_refptr<SelectFileDialog> select_file_dialog_;
1070 views::Label* reset_file_handlers_label_;
1071 views::NativeButton* reset_file_handlers_button_;
1072
1073 // Pref members.
1074 FilePathPrefMember default_download_location_;
1075 BooleanPrefMember ask_for_save_location_;
1076
1077 // Updates the directory displayed in the default download location view with
1078 // the current value of the pref.
1079 void UpdateDownloadDirectoryDisplay();
1080
1081 // Helper function for reacting to managed prefs.
1082 void DownloadSection::UpdateWidgetsForManagedPrefs();
1083
1084 StringPrefMember auto_open_files_;
1085
1086 DISALLOW_COPY_AND_ASSIGN(DownloadSection);
1087 };
1088
1089 DownloadSection::DownloadSection(Profile* profile)
1090 : download_file_location_label_(NULL),
1091 download_default_download_location_display_(NULL),
1092 download_browse_button_(NULL),
1093 download_ask_for_save_location_checkbox_(NULL),
1094 ALLOW_THIS_IN_INITIALIZER_LIST(
1095 select_file_dialog_(SelectFileDialog::Create(this))),
1096 reset_file_handlers_label_(NULL),
1097 reset_file_handlers_button_(NULL),
1098 AdvancedSection(profile, UTF16ToWide(l10n_util::GetStringUTF16(
1099 IDS_OPTIONS_DOWNLOADLOCATION_GROUP_NAME))) {
1100 }
1101
1102 void DownloadSection::ButtonPressed(
1103 views::Button* sender, const views::Event& event) {
1104 if (sender == download_browse_button_) {
1105 const std::wstring dialog_title = UTF16ToWide(
1106 l10n_util::GetStringUTF16(IDS_OPTIONS_DOWNLOADLOCATION_BROWSE_TITLE));
1107 select_file_dialog_->SelectFile(SelectFileDialog::SELECT_FOLDER,
1108 dialog_title,
1109 profile()->GetPrefs()->GetFilePath(
1110 prefs::kDownloadDefaultDirectory),
1111 NULL, 0, std::wstring(),
1112 GetWindow()->GetNativeWindow(),
1113 NULL);
1114 } else if (sender == download_ask_for_save_location_checkbox_) {
1115 bool enabled = download_ask_for_save_location_checkbox_->checked();
1116 if (enabled) {
1117 UserMetricsRecordAction(
1118 UserMetricsAction("Options_AskForSaveLocation_Enable"),
1119 profile()->GetPrefs());
1120 } else {
1121 UserMetricsRecordAction(
1122 UserMetricsAction("Options_AskForSaveLocation_Disable"),
1123 profile()->GetPrefs());
1124 }
1125 ask_for_save_location_.SetValue(enabled);
1126 } else if (sender == reset_file_handlers_button_) {
1127 profile()->GetDownloadManager()->download_prefs()->ResetAutoOpen();
1128 UserMetricsRecordAction(UserMetricsAction("Options_ResetAutoOpenFiles"),
1129 profile()->GetPrefs());
1130 }
1131 }
1132
1133 void DownloadSection::FileSelected(const FilePath& path,
1134 int index, void* params) {
1135 UserMetricsRecordAction(UserMetricsAction("Options_SetDownloadDirectory"),
1136 profile()->GetPrefs());
1137 default_download_location_.SetValue(path);
1138 // We need to call this manually here since because we're setting the value
1139 // through the pref member which avoids notifying the listener that set the
1140 // value.
1141 UpdateDownloadDirectoryDisplay();
1142 }
1143
1144 bool DownloadSection::CanClose() const {
1145 return !select_file_dialog_->IsRunning(GetWindow()->GetNativeWindow());
1146 }
1147
1148 void DownloadSection::InitControlLayout() {
1149 AdvancedSection::InitControlLayout();
1150
1151 // Layout the download components.
1152 download_file_location_label_ = new views::Label(UTF16ToWide(
1153 l10n_util::GetStringUTF16(IDS_OPTIONS_DOWNLOADLOCATION_BROWSE_TITLE)));
1154 download_default_download_location_display_ = new FileDisplayArea;
1155 download_browse_button_ = new views::NativeButton(
1156 this,
1157 UTF16ToWide(l10n_util::GetStringUTF16(
1158 IDS_OPTIONS_DOWNLOADLOCATION_BROWSE_BUTTON)));
1159
1160 download_ask_for_save_location_checkbox_ = new views::Checkbox(
1161 UTF16ToWide(l10n_util::GetStringUTF16(
1162 IDS_OPTIONS_DOWNLOADLOCATION_ASKFORSAVELOCATION)));
1163 download_ask_for_save_location_checkbox_->set_listener(this);
1164 download_ask_for_save_location_checkbox_->SetMultiLine(true);
1165 reset_file_handlers_label_ = new views::Label(
1166 UTF16ToWide(l10n_util::GetStringUTF16(
1167 IDS_OPTIONS_AUTOOPENFILETYPES_INFO)));
1168 reset_file_handlers_button_ = new views::NativeButton(
1169 this, UTF16ToWide(l10n_util::GetStringUTF16(
1170 IDS_OPTIONS_AUTOOPENFILETYPES_RESETTODEFAULT)));
1171
1172 GridLayout* layout = new GridLayout(contents_);
1173 contents_->SetLayoutManager(layout);
1174
1175 // Download location label.
1176 const int single_column_view_set_id = 0;
1177 AddWrappingColumnSet(layout, single_column_view_set_id);
1178 AddWrappingLabelRow(layout, download_file_location_label_,
1179 single_column_view_set_id, true);
1180
1181 // Download location control.
1182 const int double_column_view_set_id = 1;
1183 ColumnSet* column_set = layout->AddColumnSet(double_column_view_set_id);
1184 column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1,
1185 GridLayout::USE_PREF, 0, 0);
1186 column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
1187 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
1188 GridLayout::USE_PREF, 0, 0);
1189 column_set->AddPaddingColumn(0, views::kUnrelatedControlHorizontalSpacing);
1190 layout->StartRow(0, double_column_view_set_id);
1191 layout->AddView(download_default_download_location_display_, 1, 1,
1192 GridLayout::FILL, GridLayout::CENTER);
1193 layout->AddView(download_browse_button_);
1194 AddSpacing(layout, true);
1195
1196 // Save location checkbox layout.
1197 const int indented_view_set_id = 2;
1198 AddIndentedColumnSet(layout, indented_view_set_id);
1199 AddWrappingCheckboxRow(layout, download_ask_for_save_location_checkbox_,
1200 indented_view_set_id, false);
1201
1202 // Reset file handlers layout.
1203 AddWrappingLabelRow(layout, reset_file_handlers_label_,
1204 single_column_view_set_id, true);
1205 AddLeadingControl(layout, reset_file_handlers_button_,
1206 indented_view_set_id,
1207 false);
1208
1209 // Init member prefs so we can update the controls if prefs change.
1210 default_download_location_.Init(prefs::kDownloadDefaultDirectory,
1211 profile()->GetPrefs(), this);
1212 ask_for_save_location_.Init(prefs::kPromptForDownload,
1213 profile()->GetPrefs(), this);
1214 auto_open_files_.Init(prefs::kDownloadExtensionsToOpen, profile()->GetPrefs(),
1215 this);
1216 }
1217
1218 void DownloadSection::NotifyPrefChanged(const std::string* pref_name) {
1219 if (!pref_name || *pref_name == prefs::kDownloadDefaultDirectory)
1220 UpdateDownloadDirectoryDisplay();
1221
1222 if (!pref_name || *pref_name == prefs::kPromptForDownload) {
1223 download_ask_for_save_location_checkbox_->SetChecked(
1224 ask_for_save_location_.GetValue());
1225 }
1226
1227 if (!pref_name || *pref_name == prefs::kDownloadExtensionsToOpen) {
1228 bool enabled =
1229 profile()->GetDownloadManager()->download_prefs()->IsAutoOpenUsed();
1230 reset_file_handlers_label_->SetEnabled(enabled);
1231 reset_file_handlers_button_->SetEnabled(enabled);
1232 }
1233 UpdateWidgetsForManagedPrefs();
1234 }
1235
1236 void DownloadSection::UpdateDownloadDirectoryDisplay() {
1237 download_default_download_location_display_->SetFile(
1238 default_download_location_.GetValue());
1239 }
1240
1241 void DownloadSection::UpdateWidgetsForManagedPrefs() {
1242 const bool enabled = !default_download_location_.IsManaged();
1243 download_default_download_location_display_->SetEnabled(enabled);
1244 download_browse_button_->SetEnabled(enabled);
1245 download_ask_for_save_location_checkbox_->SetEnabled(enabled);
1246 }
1247
1248 ////////////////////////////////////////////////////////////////////////////////
1249 // TranslateSection
1250
1251 class TranslateSection : public AdvancedSection,
1252 public views::ButtonListener {
1253 public:
1254 explicit TranslateSection(Profile* profile);
1255 virtual ~TranslateSection() {}
1256
1257 // Overridden from views::ButtonListener:
1258 virtual void ButtonPressed(views::Button* sender, const views::Event& event);
1259
1260 protected:
1261 // OptionsPageView overrides:
1262 virtual void InitControlLayout();
1263 virtual void NotifyPrefChanged(const std::string* pref_name);
1264
1265 private:
1266 // Control for this section:
1267 views::Checkbox* enable_translate_checkbox_;
1268
1269 // Preferences for this section:
1270 BooleanPrefMember enable_translate_;
1271
1272 DISALLOW_COPY_AND_ASSIGN(TranslateSection);
1273 };
1274
1275 TranslateSection::TranslateSection(Profile* profile)
1276 : enable_translate_checkbox_(NULL),
1277 AdvancedSection(profile, UTF16ToWide(l10n_util::GetStringUTF16(
1278 IDS_OPTIONS_ADVANCED_SECTION_TITLE_TRANSLATE))) {
1279 }
1280
1281 void TranslateSection::ButtonPressed(
1282 views::Button* sender, const views::Event& event) {
1283 DCHECK(sender == enable_translate_checkbox_);
1284 bool enabled = enable_translate_checkbox_->checked();
1285 UserMetricsRecordAction(enabled ?
1286 UserMetricsAction("Options_Translate_Enable") :
1287 UserMetricsAction("Options_Translate_Disable"),
1288 profile()->GetPrefs());
1289 enable_translate_.SetValue(enabled);
1290 }
1291
1292 void TranslateSection::InitControlLayout() {
1293 AdvancedSection::InitControlLayout();
1294
1295 GridLayout* layout = new GridLayout(contents_);
1296 contents_->SetLayoutManager(layout);
1297
1298 AddIndentedColumnSet(layout, 0);
1299
1300 enable_translate_checkbox_ = new views::Checkbox(UTF16ToWide(
1301 l10n_util::GetStringUTF16(IDS_OPTIONS_TRANSLATE_ENABLE_TRANSLATE)));
1302 enable_translate_checkbox_->set_listener(this);
1303 AddWrappingCheckboxRow(layout, enable_translate_checkbox_, 0, false);
1304
1305 // Init member pref so we can update the controls if prefs change.
1306 enable_translate_.Init(prefs::kEnableTranslate, profile()->GetPrefs(), this);
1307 }
1308
1309 void TranslateSection::NotifyPrefChanged(const std::string* pref_name) {
1310 if (!pref_name || *pref_name == prefs::kEnableTranslate)
1311 enable_translate_checkbox_->SetChecked(enable_translate_.GetValue());
1312 }
1313
1314 ////////////////////////////////////////////////////////////////////////////////
1315 // CloudPrintProxySection
1316
1317 class CloudPrintProxySection : public AdvancedSection,
1318 public views::ButtonListener,
1319 public CloudPrintSetupFlow::Delegate {
1320 public:
1321 explicit CloudPrintProxySection(Profile* profile);
1322 virtual ~CloudPrintProxySection() {}
1323
1324 // Overridden from views::ButtonListener:
1325 virtual void ButtonPressed(views::Button* sender, const views::Event& event);
1326
1327 // CloudPrintSetupFlow::Delegate implementation.
1328 virtual void OnDialogClosed();
1329
1330 protected:
1331 // OptionsPageView overrides:
1332 virtual void InitControlLayout();
1333 virtual void NotifyPrefChanged(const std::string* pref_name);
1334
1335 private:
1336 bool Enabled() const;
1337
1338 // Controls for this section:
1339 views::Label* section_description_label_;
1340 views::NativeButton* enable_disable_button_;
1341 views::NativeButton* manage_printer_button_;
1342
1343 // Preferences we tie things to.
1344 StringPrefMember cloud_print_proxy_email_;
1345 BooleanPrefMember cloud_print_proxy_enabled_;
1346
1347 base::ScopedCallbackFactory<CloudPrintProxySection> factory_;
1348
1349 DISALLOW_COPY_AND_ASSIGN(CloudPrintProxySection);
1350 };
1351
1352 CloudPrintProxySection::CloudPrintProxySection(Profile* profile)
1353 : section_description_label_(NULL),
1354 enable_disable_button_(NULL),
1355 manage_printer_button_(NULL),
1356 factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
1357 AdvancedSection(profile,
1358 UTF16ToWide(l10n_util::GetStringUTF16(
1359 IDS_OPTIONS_ADVANCED_SECTION_TITLE_CLOUD_PRINT))) {
1360 }
1361
1362 void CloudPrintProxySection::ButtonPressed(views::Button* sender,
1363 const views::Event& event) {
1364 if (sender == enable_disable_button_) {
1365 if (Enabled()) {
1366 // Enabled, we must be the disable button.
1367 UserMetricsRecordAction(
1368 UserMetricsAction("Options_DisableCloudPrintProxy"), NULL);
1369 profile()->GetCloudPrintProxyService()->DisableForUser();
1370 } else {
1371 UserMetricsRecordAction(
1372 UserMetricsAction("Options_EnableCloudPrintProxy"), NULL);
1373 // We open a new browser window so the Options dialog doesn't
1374 // get lost behind other windows.
1375 enable_disable_button_->SetEnabled(false);
1376 enable_disable_button_->SetLabel(UTF16ToWide(l10n_util::GetStringUTF16(
1377 IDS_OPTIONS_CLOUD_PRINT_PROXY_ENABLING_BUTTON)));
1378 enable_disable_button_->InvalidateLayout();
1379 Layout();
1380 CloudPrintSetupFlow::OpenDialog(profile(), this,
1381 GetWindow()->GetNativeWindow());
1382 }
1383 } else if (sender == manage_printer_button_) {
1384 UserMetricsRecordAction(
1385 UserMetricsAction("Options_ManageCloudPrinters"), NULL);
1386 browser::ShowOptionsURL(
1387 profile(),
1388 CloudPrintURL(profile()).GetCloudPrintServiceManageURL());
1389 }
1390 }
1391
1392 void CloudPrintProxySection::OnDialogClosed() {
1393 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1394 enable_disable_button_->SetEnabled(true);
1395 // If the dialog is canceled, the preference won't change, and so we
1396 // have to revert the button text back to the disabled state.
1397 if (!Enabled()) {
1398 enable_disable_button_->SetLabel(UTF16ToWide(l10n_util::GetStringUTF16(
1399 IDS_OPTIONS_CLOUD_PRINT_PROXY_DISABLED_BUTTON)));
1400 enable_disable_button_->InvalidateLayout();
1401 Layout();
1402 }
1403 }
1404
1405 void CloudPrintProxySection::InitControlLayout() {
1406 AdvancedSection::InitControlLayout();
1407
1408 section_description_label_ = new views::Label(
1409 UTF16ToWide(l10n_util::GetStringUTF16(
1410 IDS_OPTIONS_CLOUD_PRINT_PROXY_DISABLED_LABEL)));
1411 enable_disable_button_ = new views::NativeButton(this,
1412 UTF16ToWide(l10n_util::GetStringUTF16(
1413 IDS_OPTIONS_CLOUD_PRINT_PROXY_DISABLED_BUTTON)));
1414 manage_printer_button_ = new views::NativeButton(this,
1415 UTF16ToWide(l10n_util::GetStringUTF16(
1416 IDS_OPTIONS_CLOUD_PRINT_PROXY_ENABLED_MANAGE_BUTTON)));
1417
1418 GridLayout* layout = new GridLayout(contents_);
1419 contents_->SetLayoutManager(layout);
1420
1421 const int single_column_view_set_id = 0;
1422 AddWrappingColumnSet(layout, single_column_view_set_id);
1423 const int control_view_set_id = 1;
1424 AddDependentTwoColumnSet(layout, control_view_set_id);
1425
1426 // The description label at the top and label.
1427 section_description_label_->SetMultiLine(true);
1428 AddWrappingLabelRow(layout, section_description_label_,
1429 single_column_view_set_id, true);
1430
1431 // The enable / disable button and manage button.
1432 AddTwoColumnRow(layout, enable_disable_button_, manage_printer_button_, false,
1433 control_view_set_id, views::kRelatedControlVerticalSpacing);
1434
1435 // Attach the preferences so we can flip things appropriately.
1436 cloud_print_proxy_email_.Init(prefs::kCloudPrintEmail,
1437 profile()->GetPrefs(), this);
1438 cloud_print_proxy_enabled_.Init(prefs::kCloudPrintProxyEnabled,
1439 profile()->GetPrefs(), this);
1440
1441 // Start the UI off in the state we think it should be in.
1442 std::string pref_string(prefs::kCloudPrintEmail);
1443 NotifyPrefChanged(&pref_string);
1444
1445 // Kick off a task to ask the background service what the real
1446 // answer is.
1447 profile()->GetCloudPrintProxyService()->RefreshStatusFromService();
1448 }
1449
1450 void CloudPrintProxySection::NotifyPrefChanged(const std::string* pref_name) {
1451 if (pref_name == NULL)
1452 return;
1453
1454 if (*pref_name == prefs::kCloudPrintEmail ||
1455 *pref_name == prefs::kCloudPrintProxyEnabled) {
1456 bool cloud_print_proxy_allowed =
1457 !cloud_print_proxy_enabled_.IsManaged() ||
1458 cloud_print_proxy_enabled_.GetValue();
1459
1460 if (Enabled() && cloud_print_proxy_allowed) {
1461 std::string email;
1462 if (profile()->GetPrefs()->HasPrefPath(prefs::kCloudPrintEmail))
1463 email = profile()->GetPrefs()->GetString(prefs::kCloudPrintEmail);
1464
1465 section_description_label_->SetText(UTF16ToWide(
1466 l10n_util::GetStringFUTF16(
1467 IDS_OPTIONS_CLOUD_PRINT_PROXY_ENABLED_LABEL,
1468 UTF8ToUTF16(email))));
1469 enable_disable_button_->SetLabel(UTF16ToWide(l10n_util::GetStringUTF16(
1470 IDS_OPTIONS_CLOUD_PRINT_PROXY_ENABLED_BUTTON)));
1471 enable_disable_button_->InvalidateLayout();
1472 enable_disable_button_->SetEnabled(true);
1473 manage_printer_button_->SetVisible(true);
1474 manage_printer_button_->InvalidateLayout();
1475 } else {
1476 section_description_label_->SetText(UTF16ToWide(l10n_util::GetStringUTF16(
1477 IDS_OPTIONS_CLOUD_PRINT_PROXY_DISABLED_LABEL)));
1478 enable_disable_button_->SetLabel(UTF16ToWide(l10n_util::GetStringUTF16(
1479 IDS_OPTIONS_CLOUD_PRINT_PROXY_DISABLED_BUTTON)));
1480 enable_disable_button_->InvalidateLayout();
1481 enable_disable_button_->SetEnabled(cloud_print_proxy_allowed);
1482 manage_printer_button_->SetVisible(false);
1483 }
1484
1485 // Find the parent ScrollView, and ask it to re-layout since it's
1486 // possible that the section_description_label_ has changed
1487 // heights. And scroll us back to being visible in that case, to
1488 // be nice to the user.
1489 views::View* view = section_description_label_->parent();
1490 while (view && view->GetClassName() != views::ScrollView::kViewClassName)
1491 view = view->parent();
1492 if (view) {
1493 gfx::Rect visible_bounds = GetVisibleBounds();
1494 bool was_all_visible = (visible_bounds.size() == size());
1495 // Our bounds can change across this call, so we have to use the
1496 // new bounds if we want to stay completely visible.
1497 view->Layout();
1498 ScrollRectToVisible(was_all_visible ? bounds() : visible_bounds);
1499 } else {
1500 Layout();
1501 }
1502 }
1503 }
1504
1505 bool CloudPrintProxySection::Enabled() const {
1506 return profile()->GetPrefs()->HasPrefPath(prefs::kCloudPrintEmail) &&
1507 !profile()->GetPrefs()->GetString(prefs::kCloudPrintEmail).empty();
1508 }
1509
1510 ////////////////////////////////////////////////////////////////////////////////
1511 // AdvancedContentsView
1512
1513 class AdvancedContentsView : public OptionsPageView {
1514 public:
1515 explicit AdvancedContentsView(Profile* profile);
1516 virtual ~AdvancedContentsView();
1517
1518 // views::View overrides:
1519 virtual int GetLineScrollIncrement(views::ScrollView* scroll_view,
1520 bool is_horizontal, bool is_positive);
1521 virtual void Layout();
1522
1523 protected:
1524 // OptionsPageView implementation:
1525 virtual void InitControlLayout();
1526
1527 private:
1528 static void InitClass();
1529
1530 static int line_height_;
1531
1532 DISALLOW_COPY_AND_ASSIGN(AdvancedContentsView);
1533 };
1534
1535 // static
1536 int AdvancedContentsView::line_height_ = 0;
1537
1538 ////////////////////////////////////////////////////////////////////////////////
1539 // AdvancedContentsView, public:
1540
1541 AdvancedContentsView::AdvancedContentsView(Profile* profile)
1542 : OptionsPageView(profile) {
1543 InitClass();
1544 }
1545
1546 AdvancedContentsView::~AdvancedContentsView() {
1547 }
1548
1549 ////////////////////////////////////////////////////////////////////////////////
1550 // AdvancedContentsView, views::View overrides:
1551
1552 int AdvancedContentsView::GetLineScrollIncrement(
1553 views::ScrollView* scroll_view,
1554 bool is_horizontal,
1555 bool is_positive) {
1556
1557 if (!is_horizontal)
1558 return line_height_;
1559 return View::GetPageScrollIncrement(scroll_view, is_horizontal, is_positive);
1560 }
1561
1562 void AdvancedContentsView::Layout() {
1563 if (parent() && parent()->width()) {
1564 const int width = parent()->width();
1565 const int height = GetHeightForWidth(width);
1566 SetBounds(0, 0, width, height);
1567 } else {
1568 gfx::Size prefsize = GetPreferredSize();
1569 SetBounds(0, 0, prefsize.width(), prefsize.height());
1570 }
1571 View::Layout();
1572 }
1573
1574 ////////////////////////////////////////////////////////////////////////////////
1575 // AdvancedContentsView, OptionsPageView implementation:
1576
1577 void AdvancedContentsView::InitControlLayout() {
1578 GridLayout* layout = GridLayout::CreatePanel(this);
1579 SetLayoutManager(layout);
1580
1581 const int single_column_view_set_id = 0;
1582 ColumnSet* column_set = layout->AddColumnSet(single_column_view_set_id);
1583 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
1584 GridLayout::USE_PREF, 0, 0);
1585
1586 layout->StartRow(0, single_column_view_set_id);
1587 layout->AddView(new PrivacySection(profile()));
1588 layout->StartRow(0, single_column_view_set_id);
1589 layout->AddView(new NetworkSection(profile()));
1590 layout->StartRow(0, single_column_view_set_id);
1591 layout->AddView(new TranslateSection(profile()));
1592 layout->StartRow(0, single_column_view_set_id);
1593 layout->AddView(new DownloadSection(profile()));
1594 layout->StartRow(0, single_column_view_set_id);
1595 layout->AddView(new WebContentSection(profile()));
1596 layout->StartRow(0, single_column_view_set_id);
1597 layout->AddView(new SecuritySection(profile()));
1598 #if defined(GOOGLE_CHROME_BUILD) && defined(OS_WIN)
1599 // We want to enable the cloud print UI on Windows. Since the cloud
1600 // print proxy on Windows needs the PDF plugin, we only enable it by
1601 // default on Google Chrome Windows builds (which contain the PDF
1602 // plugin).
1603 bool cloud_print_available = true;
1604 #else
1605 bool cloud_print_available = CommandLine::ForCurrentProcess()->HasSwitch(
1606 switches::kEnableCloudPrintProxy);
1607 #endif
1608 if (cloud_print_available &&
1609 profile()->GetCloudPrintProxyService()) {
1610 layout->StartRow(0, single_column_view_set_id);
1611 layout->AddView(new CloudPrintProxySection(profile()));
1612 }
1613 }
1614
1615 ////////////////////////////////////////////////////////////////////////////////
1616 // AdvancedContentsView, private:
1617
1618 void AdvancedContentsView::InitClass() {
1619 static bool initialized = false;
1620 if (!initialized) {
1621 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
1622 line_height_ = rb.GetFont(ResourceBundle::BaseFont).GetHeight();
1623 initialized = true;
1624 }
1625 }
1626
1627 ////////////////////////////////////////////////////////////////////////////////
1628 // AdvancedScrollViewContainer, public:
1629
1630 AdvancedScrollViewContainer::AdvancedScrollViewContainer(Profile* profile)
1631 : contents_view_(new AdvancedContentsView(profile)),
1632 scroll_view_(new views::ScrollView) {
1633 AddChildView(scroll_view_);
1634 scroll_view_->SetContents(contents_view_);
1635 set_background(new ListBackground());
1636 }
1637
1638 AdvancedScrollViewContainer::~AdvancedScrollViewContainer() {
1639 }
1640
1641 ////////////////////////////////////////////////////////////////////////////////
1642 // AdvancedScrollViewContainer, views::View overrides:
1643
1644 void AdvancedScrollViewContainer::Layout() {
1645 gfx::Rect lb = GetLocalBounds();
1646
1647 gfx::Size border = gfx::NativeTheme::instance()->GetThemeBorderSize(
1648 gfx::NativeTheme::LIST);
1649 lb.Inset(border.width(), border.height());
1650 scroll_view_->SetBoundsRect(lb);
1651 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/options/advanced_contents_view.h ('k') | chrome/browser/ui/views/options/advanced_page_view.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698