Infobar material design refresh: layout
[chromium-blink-merge.git] / chrome / browser / ui / views / collected_cookies_views.cc
blob10820d911729157b7f80e5c9f8df7cfda220441d
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/views/collected_cookies_views.h"
7 #include "base/prefs/pref_service.h"
8 #include "chrome/browser/browsing_data/browsing_data_appcache_helper.h"
9 #include "chrome/browser/browsing_data/browsing_data_channel_id_helper.h"
10 #include "chrome/browser/browsing_data/browsing_data_cookie_helper.h"
11 #include "chrome/browser/browsing_data/browsing_data_database_helper.h"
12 #include "chrome/browser/browsing_data/browsing_data_file_system_helper.h"
13 #include "chrome/browser/browsing_data/browsing_data_indexed_db_helper.h"
14 #include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h"
15 #include "chrome/browser/browsing_data/cookies_tree_model.h"
16 #include "chrome/browser/chrome_notification_types.h"
17 #include "chrome/browser/content_settings/cookie_settings_factory.h"
18 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
19 #include "chrome/browser/infobars/infobar_service.h"
20 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/browser/ui/collected_cookies_infobar_delegate.h"
22 #include "chrome/browser/ui/views/cookie_info_view.h"
23 #include "chrome/common/pref_names.h"
24 #include "chrome/grit/generated_resources.h"
25 #include "chrome/grit/locale_settings.h"
26 #include "components/constrained_window/constrained_window_views.h"
27 #include "components/content_settings/core/browser/cookie_settings.h"
28 #include "components/content_settings/core/common/pref_names.h"
29 #include "content/public/browser/notification_details.h"
30 #include "content/public/browser/notification_source.h"
31 #include "content/public/browser/web_contents.h"
32 #include "grit/theme_resources.h"
33 #include "net/cookies/canonical_cookie.h"
34 #include "ui/base/l10n/l10n_util.h"
35 #include "ui/base/resource/resource_bundle.h"
36 #include "ui/gfx/color_utils.h"
37 #include "ui/views/border.h"
38 #include "ui/views/controls/button/label_button.h"
39 #include "ui/views/controls/image_view.h"
40 #include "ui/views/controls/label.h"
41 #include "ui/views/controls/scroll_view.h"
42 #include "ui/views/controls/tabbed_pane/tabbed_pane.h"
43 #include "ui/views/controls/tree/tree_view.h"
44 #include "ui/views/layout/box_layout.h"
45 #include "ui/views/layout/grid_layout.h"
46 #include "ui/views/layout/layout_constants.h"
47 #include "ui/views/widget/widget.h"
49 namespace {
51 // Spacing between the infobar frame and its contents.
52 const int kInfobarVerticalPadding = 3;
53 const int kInfobarHorizontalPadding = 8;
55 // Width of the infobar frame.
56 const int kInfobarBorderSize = 1;
58 // Dimensions of the tree views.
59 const int kTreeViewWidth = 400;
60 const int kTreeViewHeight = 125;
62 // The color of the border around the cookies tree view.
63 const SkColor kCookiesBorderColor = SkColorSetRGB(0xC8, 0xC8, 0xC8);
65 // Spacing constants used with the new dialog style.
66 const int kTabbedPaneTopPadding = 14;
67 const int kLabelBottomPadding = 17;
68 const int kCookieInfoBottomPadding = 4;
69 const int kVPanelPadding = 15;
71 } // namespace
73 // A custom view that conditionally displays an infobar.
74 class InfobarView : public views::View {
75 public:
76 InfobarView() {
77 content_ = new views::View;
78 SkColor border_color = SK_ColorGRAY;
79 content_->SetBorder(
80 views::Border::CreateSolidBorder(kInfobarBorderSize, border_color));
82 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
83 info_image_ = new views::ImageView();
84 info_image_->SetImage(rb.GetImageSkiaNamed(IDR_INFO));
85 label_ = new views::Label();
87 ~InfobarView() override {}
89 // Update the visibility of the infobar. If |is_visible| is true, a rule for
90 // |setting| on |domain_name| was created.
91 void UpdateVisibility(bool is_visible,
92 ContentSetting setting,
93 const base::string16& domain_name) {
94 if (!is_visible) {
95 SetVisible(false);
96 return;
99 base::string16 label;
100 switch (setting) {
101 case CONTENT_SETTING_BLOCK:
102 label = l10n_util::GetStringFUTF16(
103 IDS_COLLECTED_COOKIES_BLOCK_RULE_CREATED, domain_name);
104 break;
106 case CONTENT_SETTING_ALLOW:
107 label = l10n_util::GetStringFUTF16(
108 IDS_COLLECTED_COOKIES_ALLOW_RULE_CREATED, domain_name);
109 break;
111 case CONTENT_SETTING_SESSION_ONLY:
112 label = l10n_util::GetStringFUTF16(
113 IDS_COLLECTED_COOKIES_SESSION_RULE_CREATED, domain_name);
114 break;
116 default:
117 NOTREACHED();
119 label_->SetText(label);
120 content_->Layout();
121 SetVisible(true);
124 private:
125 // Initialize contents and layout.
126 void Init() {
127 AddChildView(content_);
128 content_->SetLayoutManager(
129 new views::BoxLayout(views::BoxLayout::kHorizontal,
130 kInfobarHorizontalPadding,
131 kInfobarVerticalPadding,
132 views::kRelatedControlSmallHorizontalSpacing));
133 content_->AddChildView(info_image_);
134 content_->AddChildView(label_);
135 UpdateVisibility(false, CONTENT_SETTING_BLOCK, base::string16());
138 // views::View overrides.
139 gfx::Size GetPreferredSize() const override {
140 if (!visible())
141 return gfx::Size();
143 // Add space around the banner.
144 gfx::Size size(content_->GetPreferredSize());
145 size.Enlarge(0, 2 * views::kRelatedControlVerticalSpacing);
146 return size;
149 void Layout() override {
150 content_->SetBounds(
151 0, views::kRelatedControlVerticalSpacing,
152 width(), height() - views::kRelatedControlVerticalSpacing);
155 void ViewHierarchyChanged(
156 const ViewHierarchyChangedDetails& details) override {
157 if (details.is_add && details.child == this)
158 Init();
161 // Holds the info icon image and text label and renders the border.
162 views::View* content_;
163 // Info icon image.
164 views::ImageView* info_image_;
165 // The label responsible for rendering the text.
166 views::Label* label_;
168 DISALLOW_COPY_AND_ASSIGN(InfobarView);
171 ///////////////////////////////////////////////////////////////////////////////
172 // CollectedCookiesViews, public:
174 CollectedCookiesViews::CollectedCookiesViews(content::WebContents* web_contents)
175 : web_contents_(web_contents),
176 allowed_label_(NULL),
177 blocked_label_(NULL),
178 allowed_cookies_tree_(NULL),
179 blocked_cookies_tree_(NULL),
180 block_allowed_button_(NULL),
181 delete_allowed_button_(NULL),
182 allow_blocked_button_(NULL),
183 for_session_blocked_button_(NULL),
184 cookie_info_view_(NULL),
185 infobar_(NULL),
186 status_changed_(false) {
187 TabSpecificContentSettings* content_settings =
188 TabSpecificContentSettings::FromWebContents(web_contents);
189 registrar_.Add(this, chrome::NOTIFICATION_COLLECTED_COOKIES_SHOWN,
190 content::Source<TabSpecificContentSettings>(content_settings));
191 constrained_window::ShowWebModalDialogViews(this, web_contents);
194 ///////////////////////////////////////////////////////////////////////////////
195 // CollectedCookiesViews, views::DialogDelegate implementation:
197 base::string16 CollectedCookiesViews::GetWindowTitle() const {
198 return l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_DIALOG_TITLE);
201 int CollectedCookiesViews::GetDialogButtons() const {
202 return ui::DIALOG_BUTTON_CANCEL;
205 base::string16 CollectedCookiesViews::GetDialogButtonLabel(
206 ui::DialogButton button) const {
207 return l10n_util::GetStringUTF16(IDS_CLOSE);
210 bool CollectedCookiesViews::Cancel() {
211 // If the user closes our parent tab while we're still open, this method will
212 // (eventually) be called in response to a WebContentsDestroyed() call from
213 // the WebContentsImpl to its observers. But since the InfoBarService is also
214 // torn down in response to WebContentsDestroyed(), it may already be null.
215 // Since the tab is going away anyway, we can just omit showing an infobar,
216 // which prevents any attempt to access a null InfoBarService.
217 if (status_changed_ && !web_contents_->IsBeingDestroyed()) {
218 CollectedCookiesInfoBarDelegate::Create(
219 InfoBarService::FromWebContents(web_contents_));
221 return true;
224 ui::ModalType CollectedCookiesViews::GetModalType() const {
225 return ui::MODAL_TYPE_CHILD;
228 ///////////////////////////////////////////////////////////////////////////////
229 // CollectedCookiesViews, views::ButtonListener implementation:
231 void CollectedCookiesViews::ButtonPressed(views::Button* sender,
232 const ui::Event& event) {
233 if (sender == block_allowed_button_) {
234 AddContentException(allowed_cookies_tree_, CONTENT_SETTING_BLOCK);
235 } else if (sender == delete_allowed_button_) {
236 allowed_cookies_tree_model_->DeleteCookieNode(
237 static_cast<CookieTreeNode*>(allowed_cookies_tree_->GetSelectedNode()));
238 } else if (sender == allow_blocked_button_) {
239 AddContentException(blocked_cookies_tree_, CONTENT_SETTING_ALLOW);
240 } else if (sender == for_session_blocked_button_) {
241 AddContentException(blocked_cookies_tree_, CONTENT_SETTING_SESSION_ONLY);
245 ///////////////////////////////////////////////////////////////////////////////
246 // CollectedCookiesViews, views::TabbedPaneListener implementation:
248 void CollectedCookiesViews::TabSelectedAt(int index) {
249 EnableControls();
250 ShowCookieInfo();
253 ///////////////////////////////////////////////////////////////////////////////
254 // CollectedCookiesViews, views::TreeViewController implementation:
256 void CollectedCookiesViews::OnTreeViewSelectionChanged(
257 views::TreeView* tree_view) {
258 EnableControls();
259 ShowCookieInfo();
262 ///////////////////////////////////////////////////////////////////////////////
263 // CollectedCookiesViews, views::View overrides:
265 gfx::Size CollectedCookiesViews::GetMinimumSize() const {
266 // Allow UpdateWebContentsModalDialogPosition to clamp the dialog width.
267 return gfx::Size(0, View::GetMinimumSize().height());
270 void CollectedCookiesViews::ViewHierarchyChanged(
271 const ViewHierarchyChangedDetails& details) {
272 views::DialogDelegateView::ViewHierarchyChanged(details);
273 if (details.is_add && details.child == this)
274 Init();
277 ////////////////////////////////////////////////////////////////////////////////
278 // CollectedCookiesViews, private:
280 CollectedCookiesViews::~CollectedCookiesViews() {
281 allowed_cookies_tree_->SetModel(NULL);
282 blocked_cookies_tree_->SetModel(NULL);
285 void CollectedCookiesViews::Init() {
286 using views::GridLayout;
288 GridLayout* layout = GridLayout::CreatePanel(this);
289 SetLayoutManager(layout);
291 const int single_column_layout_id = 0;
292 views::ColumnSet* column_set = layout->AddColumnSet(single_column_layout_id);
293 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
294 GridLayout::USE_PREF, 0, 0);
296 layout->StartRow(0, single_column_layout_id);
297 views::TabbedPane* tabbed_pane = new views::TabbedPane();
298 layout->SetInsets(gfx::Insets(kTabbedPaneTopPadding, 0, 0, 0));
300 layout->AddView(tabbed_pane);
301 // NOTE: Panes must be added after |tabbed_pane| has been added to its parent.
302 base::string16 label_allowed = l10n_util::GetStringUTF16(
303 IDS_COLLECTED_COOKIES_ALLOWED_COOKIES_TAB_LABEL);
304 base::string16 label_blocked = l10n_util::GetStringUTF16(
305 IDS_COLLECTED_COOKIES_BLOCKED_COOKIES_TAB_LABEL);
306 tabbed_pane->AddTab(label_allowed, CreateAllowedPane());
307 tabbed_pane->AddTab(label_blocked, CreateBlockedPane());
308 tabbed_pane->SelectTabAt(0);
309 tabbed_pane->set_listener(this);
310 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
312 layout->StartRow(0, single_column_layout_id);
313 cookie_info_view_ = new CookieInfoView();
314 layout->AddView(cookie_info_view_);
315 layout->AddPaddingRow(0, kCookieInfoBottomPadding);
317 layout->StartRow(0, single_column_layout_id);
318 infobar_ = new InfobarView();
319 layout->AddView(infobar_);
321 EnableControls();
322 ShowCookieInfo();
325 views::View* CollectedCookiesViews::CreateAllowedPane() {
326 TabSpecificContentSettings* content_settings =
327 TabSpecificContentSettings::FromWebContents(web_contents_);
329 // Create the controls that go into the pane.
330 allowed_label_ = new views::Label(l10n_util::GetStringUTF16(
331 IDS_COLLECTED_COOKIES_ALLOWED_COOKIES_LABEL));
333 allowed_cookies_tree_model_ =
334 content_settings->CreateAllowedCookiesTreeModel();
335 allowed_cookies_tree_ = new views::TreeView();
336 allowed_cookies_tree_->SetModel(allowed_cookies_tree_model_.get());
337 allowed_cookies_tree_->SetRootShown(false);
338 allowed_cookies_tree_->SetEditable(false);
339 allowed_cookies_tree_->set_auto_expand_children(true);
340 allowed_cookies_tree_->SetController(this);
342 block_allowed_button_ = new views::LabelButton(this,
343 l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_BLOCK_BUTTON));
344 block_allowed_button_->SetStyle(views::Button::STYLE_BUTTON);
346 delete_allowed_button_ = new views::LabelButton(this,
347 l10n_util::GetStringUTF16(IDS_COOKIES_REMOVE_LABEL));
348 delete_allowed_button_->SetStyle(views::Button::STYLE_BUTTON);
350 // Create the view that holds all the controls together. This will be the
351 // pane added to the tabbed pane.
352 using views::GridLayout;
354 views::View* pane = new views::View();
355 GridLayout* layout = GridLayout::CreatePanel(pane);
356 layout->SetInsets(kVPanelPadding, views::kButtonHEdgeMarginNew,
357 kVPanelPadding, views::kButtonHEdgeMarginNew);
358 pane->SetLayoutManager(layout);
360 const int single_column_layout_id = 0;
361 views::ColumnSet* column_set = layout->AddColumnSet(single_column_layout_id);
362 column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 1,
363 GridLayout::USE_PREF, 0, 0);
365 const int three_columns_layout_id = 1;
366 column_set = layout->AddColumnSet(three_columns_layout_id);
367 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
368 GridLayout::USE_PREF, 0, 0);
369 column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
370 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
371 GridLayout::USE_PREF, 0, 0);
373 layout->StartRow(0, single_column_layout_id);
374 layout->AddView(allowed_label_);
375 layout->AddPaddingRow(0, kLabelBottomPadding);
377 layout->StartRow(1, single_column_layout_id);
378 layout->AddView(CreateScrollView(allowed_cookies_tree_), 1, 1,
379 GridLayout::FILL, GridLayout::FILL, kTreeViewWidth,
380 kTreeViewHeight);
381 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
383 layout->StartRow(0, three_columns_layout_id);
384 layout->AddView(block_allowed_button_);
385 layout->AddView(delete_allowed_button_);
387 return pane;
390 views::View* CollectedCookiesViews::CreateBlockedPane() {
391 TabSpecificContentSettings* content_settings =
392 TabSpecificContentSettings::FromWebContents(web_contents_);
394 Profile* profile =
395 Profile::FromBrowserContext(web_contents_->GetBrowserContext());
396 PrefService* prefs = profile->GetPrefs();
398 // Create the controls that go into the pane.
399 blocked_label_ = new views::Label(
400 l10n_util::GetStringUTF16(
401 prefs->GetBoolean(prefs::kBlockThirdPartyCookies) ?
402 IDS_COLLECTED_COOKIES_BLOCKED_THIRD_PARTY_BLOCKING_ENABLED :
403 IDS_COLLECTED_COOKIES_BLOCKED_COOKIES_LABEL));
404 blocked_label_->SetMultiLine(true);
405 blocked_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
406 blocked_label_->SizeToFit(kTreeViewWidth);
407 blocked_cookies_tree_model_ =
408 content_settings->CreateBlockedCookiesTreeModel();
409 blocked_cookies_tree_ = new views::TreeView();
410 blocked_cookies_tree_->SetModel(blocked_cookies_tree_model_.get());
411 blocked_cookies_tree_->SetRootShown(false);
412 blocked_cookies_tree_->SetEditable(false);
413 blocked_cookies_tree_->set_auto_expand_children(true);
414 blocked_cookies_tree_->SetController(this);
416 allow_blocked_button_ = new views::LabelButton(this,
417 l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_ALLOW_BUTTON));
418 allow_blocked_button_->SetStyle(views::Button::STYLE_BUTTON);
419 for_session_blocked_button_ = new views::LabelButton(this,
420 l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_SESSION_ONLY_BUTTON));
421 for_session_blocked_button_->SetStyle(views::Button::STYLE_BUTTON);
423 // Create the view that holds all the controls together. This will be the
424 // pane added to the tabbed pane.
425 using views::GridLayout;
427 views::View* pane = new views::View();
428 GridLayout* layout = GridLayout::CreatePanel(pane);
429 layout->SetInsets(kVPanelPadding, views::kButtonHEdgeMarginNew,
430 kVPanelPadding, views::kButtonHEdgeMarginNew);
431 pane->SetLayoutManager(layout);
433 const int single_column_layout_id = 0;
434 views::ColumnSet* column_set = layout->AddColumnSet(single_column_layout_id);
435 column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 1,
436 GridLayout::USE_PREF, 0, 0);
438 const int three_columns_layout_id = 1;
439 column_set = layout->AddColumnSet(three_columns_layout_id);
440 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
441 GridLayout::USE_PREF, 0, 0);
442 column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
443 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
444 GridLayout::USE_PREF, 0, 0);
446 layout->StartRow(0, single_column_layout_id);
447 layout->AddView(blocked_label_, 1, 1, GridLayout::FILL, GridLayout::FILL);
448 layout->AddPaddingRow(0, kLabelBottomPadding);
450 layout->StartRow(1, single_column_layout_id);
451 layout->AddView(
452 CreateScrollView(blocked_cookies_tree_), 1, 1,
453 GridLayout::FILL, GridLayout::FILL, kTreeViewWidth, kTreeViewHeight);
454 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
456 layout->StartRow(0, three_columns_layout_id);
457 layout->AddView(allow_blocked_button_);
458 layout->AddView(for_session_blocked_button_);
460 return pane;
463 views::View* CollectedCookiesViews::CreateScrollView(views::TreeView* pane) {
464 views::ScrollView* scroll_view = new views::ScrollView();
465 scroll_view->SetContents(pane);
466 scroll_view->SetBorder(
467 views::Border::CreateSolidBorder(1, kCookiesBorderColor));
468 return scroll_view;
471 void CollectedCookiesViews::EnableControls() {
472 bool enable_allowed_buttons = false;
473 ui::TreeModelNode* node = allowed_cookies_tree_->GetSelectedNode();
474 if (node) {
475 CookieTreeNode* cookie_node = static_cast<CookieTreeNode*>(node);
476 if (cookie_node->GetDetailedInfo().node_type ==
477 CookieTreeNode::DetailedInfo::TYPE_HOST) {
478 enable_allowed_buttons = static_cast<CookieTreeHostNode*>(
479 cookie_node)->CanCreateContentException();
482 block_allowed_button_->SetEnabled(enable_allowed_buttons);
483 delete_allowed_button_->SetEnabled(node != NULL);
485 bool enable_blocked_buttons = false;
486 node = blocked_cookies_tree_->GetSelectedNode();
487 if (node) {
488 CookieTreeNode* cookie_node = static_cast<CookieTreeNode*>(node);
489 if (cookie_node->GetDetailedInfo().node_type ==
490 CookieTreeNode::DetailedInfo::TYPE_HOST) {
491 enable_blocked_buttons = static_cast<CookieTreeHostNode*>(
492 cookie_node)->CanCreateContentException();
495 allow_blocked_button_->SetEnabled(enable_blocked_buttons);
496 for_session_blocked_button_->SetEnabled(enable_blocked_buttons);
499 void CollectedCookiesViews::ShowCookieInfo() {
500 ui::TreeModelNode* node = allowed_cookies_tree_->GetSelectedNode();
501 if (!node)
502 node = blocked_cookies_tree_->GetSelectedNode();
504 if (node) {
505 CookieTreeNode* cookie_node = static_cast<CookieTreeNode*>(node);
506 const CookieTreeNode::DetailedInfo detailed_info =
507 cookie_node->GetDetailedInfo();
509 if (detailed_info.node_type == CookieTreeNode::DetailedInfo::TYPE_COOKIE) {
510 cookie_info_view_->SetCookie(detailed_info.cookie->Domain(),
511 *detailed_info.cookie);
512 } else {
513 cookie_info_view_->ClearCookieDisplay();
515 } else {
516 cookie_info_view_->ClearCookieDisplay();
520 void CollectedCookiesViews::AddContentException(views::TreeView* tree_view,
521 ContentSetting setting) {
522 CookieTreeHostNode* host_node =
523 static_cast<CookieTreeHostNode*>(tree_view->GetSelectedNode());
524 Profile* profile =
525 Profile::FromBrowserContext(web_contents_->GetBrowserContext());
526 host_node->CreateContentException(
527 CookieSettingsFactory::GetForProfile(profile).get(), setting);
528 infobar_->UpdateVisibility(true, setting, host_node->GetTitle());
529 status_changed_ = true;
532 ///////////////////////////////////////////////////////////////////////////////
533 // CollectedCookiesViews, content::NotificationObserver implementation:
535 void CollectedCookiesViews::Observe(
536 int type,
537 const content::NotificationSource& source,
538 const content::NotificationDetails& details) {
539 DCHECK_EQ(chrome::NOTIFICATION_COLLECTED_COOKIES_SHOWN, type);
540 GetWidget()->Close();