collected_cookies_win.cc revision dc0f95d653279beabeb9817299e2902918ba123e
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/collected_cookies_win.h" 6 7#include "chrome/browser/cookies_tree_model.h" 8#include "chrome/browser/profiles/profile.h" 9#include "chrome/common/notification_details.h" 10#include "chrome/common/notification_source.h" 11#include "content/browser/tab_contents/tab_contents.h" 12#include "grit/generated_resources.h" 13#include "grit/locale_settings.h" 14#include "grit/theme_resources.h" 15#include "ui/base/l10n/l10n_util.h" 16#include "ui/base/resource/resource_bundle.h" 17#include "ui/gfx/color_utils.h" 18#include "views/controls/button/native_button.h" 19#include "views/controls/image_view.h" 20#include "views/controls/label.h" 21#include "views/controls/separator.h" 22#include "views/layout/box_layout.h" 23#include "views/layout/grid_layout.h" 24#include "views/layout/layout_constants.h" 25#include "views/widget/root_view.h" 26#include "views/widget/widget_win.h" 27#include "views/window/window.h" 28 29namespace browser { 30 31// Declared in browser_dialogs.h so others don't have to depend on our header. 32void ShowCollectedCookiesDialog(gfx::NativeWindow parent_window, 33 TabContents* tab_contents) { 34 // Deletes itself on close. 35 new CollectedCookiesWin(parent_window, tab_contents); 36} 37 38} // namespace browser 39 40namespace { 41// Spacing between the infobar frame and its contents. 42const int kInfobarVerticalPadding = 3; 43const int kInfobarHorizontalPadding = 8; 44 45// Width of the infobar frame. 46const int kInfobarBorderSize = 1; 47 48// Dimensions of the tree views. 49const int kTreeViewWidth = 400; 50const int kTreeViewHeight = 125; 51 52} // namespace 53 54// A custom view that conditionally displays an infobar. 55class InfobarView : public views::View { 56 public: 57 InfobarView() { 58 content_ = new views::View; 59 SkColor border_color = color_utils::GetSysSkColor(COLOR_3DSHADOW); 60 views::Border* border = views::Border::CreateSolidBorder( 61 kInfobarBorderSize, border_color); 62 content_->set_border(border); 63 64 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 65 info_image_ = new views::ImageView(); 66 info_image_->SetImage(rb.GetBitmapNamed(IDR_INFO)); 67 label_ = new views::Label(); 68 } 69 virtual ~InfobarView() {} 70 71 // Update the visibility of the infobar. If |is_visible| is true, a rule for 72 // |setting| on |domain_name| was created. 73 void UpdateVisibility(bool is_visible, 74 ContentSetting setting, 75 const std::wstring& domain_name) { 76 if (!is_visible) { 77 SetVisible(false); 78 return; 79 } 80 81 std::wstring label; 82 switch (setting) { 83 case CONTENT_SETTING_BLOCK: 84 label = UTF16ToWide(l10n_util::GetStringFUTF16( 85 IDS_COLLECTED_COOKIES_BLOCK_RULE_CREATED, 86 WideToUTF16(domain_name))); 87 break; 88 89 case CONTENT_SETTING_ALLOW: 90 label = UTF16ToWide(l10n_util::GetStringFUTF16( 91 IDS_COLLECTED_COOKIES_ALLOW_RULE_CREATED, 92 WideToUTF16(domain_name))); 93 break; 94 95 case CONTENT_SETTING_SESSION_ONLY: 96 label = UTF16ToWide(l10n_util::GetStringFUTF16( 97 IDS_COLLECTED_COOKIES_SESSION_RULE_CREATED, 98 WideToUTF16(domain_name))); 99 break; 100 101 default: 102 NOTREACHED(); 103 } 104 label_->SetText(label); 105 content_->Layout(); 106 SetVisible(true); 107 } 108 109 private: 110 // Initialize contents and layout. 111 void Init() { 112 AddChildView(content_); 113 content_->SetLayoutManager( 114 new views::BoxLayout(views::BoxLayout::kHorizontal, 115 kInfobarHorizontalPadding, 116 kInfobarVerticalPadding, 117 views::kRelatedControlSmallHorizontalSpacing)); 118 content_->AddChildView(info_image_); 119 content_->AddChildView(label_); 120 UpdateVisibility(false, CONTENT_SETTING_BLOCK, std::wstring()); 121 } 122 123 // views::View overrides. 124 virtual gfx::Size GetPreferredSize() { 125 if (!IsVisible()) 126 return gfx::Size(); 127 128 // Add space around the banner. 129 gfx::Size size(content_->GetPreferredSize()); 130 size.Enlarge(0, 2 * views::kRelatedControlVerticalSpacing); 131 return size; 132 } 133 134 virtual void Layout() { 135 content_->SetBounds( 136 0, views::kRelatedControlVerticalSpacing, 137 width(), height() - views::kRelatedControlVerticalSpacing); 138 } 139 140 virtual void ViewHierarchyChanged(bool is_add, 141 views::View* parent, 142 views::View* child) { 143 if (is_add && child == this) 144 Init(); 145 } 146 147 // Holds the info icon image and text label and renders the border. 148 views::View* content_; 149 // Info icon image. 150 views::ImageView* info_image_; 151 // The label responsible for rendering the text. 152 views::Label* label_; 153 154 DISALLOW_COPY_AND_ASSIGN(InfobarView); 155}; 156 157/////////////////////////////////////////////////////////////////////////////// 158// CollectedCookiesWin, constructor and destructor: 159 160CollectedCookiesWin::CollectedCookiesWin(gfx::NativeWindow parent_window, 161 TabContents* tab_contents) 162 : tab_contents_(tab_contents), 163 allowed_label_(NULL), 164 blocked_label_(NULL), 165 allowed_cookies_tree_(NULL), 166 blocked_cookies_tree_(NULL), 167 block_allowed_button_(NULL), 168 allow_blocked_button_(NULL), 169 for_session_blocked_button_(NULL), 170 infobar_(NULL) { 171 TabSpecificContentSettings* content_settings = 172 tab_contents->GetTabSpecificContentSettings(); 173 registrar_.Add(this, NotificationType::COLLECTED_COOKIES_SHOWN, 174 Source<TabSpecificContentSettings>(content_settings)); 175 176 Init(); 177 178 window_ = tab_contents_->CreateConstrainedDialog(this); 179} 180 181CollectedCookiesWin::~CollectedCookiesWin() { 182 allowed_cookies_tree_->SetModel(NULL); 183 blocked_cookies_tree_->SetModel(NULL); 184} 185 186void CollectedCookiesWin::Init() { 187 TabSpecificContentSettings* content_settings = 188 tab_contents_->GetTabSpecificContentSettings(); 189 HostContentSettingsMap* host_content_settings_map = 190 tab_contents_->profile()->GetHostContentSettingsMap(); 191 192 // Allowed Cookie list. 193 allowed_label_ = new views::Label(UTF16ToWide(l10n_util::GetStringUTF16( 194 IDS_COLLECTED_COOKIES_ALLOWED_COOKIES_LABEL))); 195 allowed_cookies_tree_model_.reset( 196 content_settings->GetAllowedCookiesTreeModel()); 197 allowed_cookies_tree_ = new views::TreeView(); 198 allowed_cookies_tree_->SetModel(allowed_cookies_tree_model_.get()); 199 allowed_cookies_tree_->SetController(this); 200 allowed_cookies_tree_->SetRootShown(false); 201 allowed_cookies_tree_->SetEditable(false); 202 allowed_cookies_tree_->set_lines_at_root(true); 203 allowed_cookies_tree_->set_auto_expand_children(true); 204 205 // Blocked Cookie list. 206 blocked_label_ = new views::Label( 207 UTF16ToWide(l10n_util::GetStringUTF16( 208 host_content_settings_map->BlockThirdPartyCookies() ? 209 IDS_COLLECTED_COOKIES_BLOCKED_THIRD_PARTY_BLOCKING_ENABLED : 210 IDS_COLLECTED_COOKIES_BLOCKED_COOKIES_LABEL))); 211 blocked_label_->SetMultiLine(true); 212 blocked_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); 213 blocked_cookies_tree_model_.reset( 214 content_settings->GetBlockedCookiesTreeModel()); 215 blocked_cookies_tree_ = new views::TreeView(); 216 blocked_cookies_tree_->SetModel(blocked_cookies_tree_model_.get()); 217 blocked_cookies_tree_->SetController(this); 218 blocked_cookies_tree_->SetRootShown(false); 219 blocked_cookies_tree_->SetEditable(false); 220 blocked_cookies_tree_->set_lines_at_root(true); 221 blocked_cookies_tree_->set_auto_expand_children(true); 222 223 using views::GridLayout; 224 225 GridLayout* layout = GridLayout::CreatePanel(this); 226 SetLayoutManager(layout); 227 228 const int single_column_layout_id = 0; 229 views::ColumnSet* column_set = layout->AddColumnSet(single_column_layout_id); 230 column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 1, 231 GridLayout::USE_PREF, 0, 0); 232 233 const int three_columns_layout_id = 1; 234 column_set = layout->AddColumnSet(three_columns_layout_id); 235 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, 236 GridLayout::USE_PREF, 0, 0); 237 column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing); 238 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, 239 GridLayout::USE_PREF, 0, 0); 240 241 layout->StartRow(0, single_column_layout_id); 242 layout->AddView(allowed_label_); 243 244 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); 245 layout->StartRow(1, single_column_layout_id); 246 layout->AddView( 247 allowed_cookies_tree_, 1, 1, GridLayout::FILL, GridLayout::FILL, 248 kTreeViewWidth, kTreeViewHeight); 249 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); 250 251 layout->StartRow(0, single_column_layout_id); 252 block_allowed_button_ = new views::NativeButton(this, UTF16ToWide( 253 l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_BLOCK_BUTTON))); 254 layout->AddView( 255 block_allowed_button_, 1, 1, GridLayout::LEADING, GridLayout::CENTER); 256 layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing); 257 258 layout->StartRow(0, single_column_layout_id); 259 layout->AddView( 260 new views::Separator(), 1, 1, GridLayout::FILL, GridLayout::FILL); 261 layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing); 262 263 layout->StartRow(0, single_column_layout_id); 264 layout->AddView(blocked_label_, 1, 1, GridLayout::FILL, GridLayout::FILL); 265 266 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); 267 layout->StartRow(1, single_column_layout_id); 268 layout->AddView( 269 blocked_cookies_tree_, 1, 1, GridLayout::FILL, GridLayout::FILL, 270 kTreeViewWidth, kTreeViewHeight); 271 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); 272 273 layout->StartRow(0, three_columns_layout_id); 274 allow_blocked_button_ = new views::NativeButton(this, UTF16ToWide( 275 l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_ALLOW_BUTTON))); 276 layout->AddView(allow_blocked_button_); 277 for_session_blocked_button_ = new views::NativeButton(this, UTF16ToWide( 278 l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_SESSION_ONLY_BUTTON))); 279 layout->AddView(for_session_blocked_button_); 280 281 layout->StartRow(0, single_column_layout_id); 282 infobar_ = new InfobarView(); 283 layout->AddView(infobar_, 1, 1, GridLayout::FILL, GridLayout::FILL); 284 285 EnableControls(); 286} 287 288/////////////////////////////////////////////////////////////////////////////// 289// ConstrainedDialogDelegate implementation. 290 291std::wstring CollectedCookiesWin::GetWindowTitle() const { 292 return UTF16ToWide( 293 l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_DIALOG_TITLE)); 294} 295 296int CollectedCookiesWin::GetDialogButtons() const { 297 return MessageBoxFlags::DIALOGBUTTON_CANCEL; 298} 299 300std::wstring CollectedCookiesWin::GetDialogButtonLabel( 301 MessageBoxFlags::DialogButton button) const { 302 return UTF16ToWide(l10n_util::GetStringUTF16(IDS_CLOSE)); 303} 304 305void CollectedCookiesWin::DeleteDelegate() { 306 delete this; 307} 308 309bool CollectedCookiesWin::Cancel() { 310 return true; 311} 312 313views::View* CollectedCookiesWin::GetContentsView() { 314 return this; 315} 316 317/////////////////////////////////////////////////////////////////////////////// 318// views::ButtonListener implementation. 319 320void CollectedCookiesWin::ButtonPressed(views::Button* sender, 321 const views::Event& event) { 322 if (sender == block_allowed_button_) 323 AddContentException(allowed_cookies_tree_, CONTENT_SETTING_BLOCK); 324 else if (sender == allow_blocked_button_) 325 AddContentException(blocked_cookies_tree_, CONTENT_SETTING_ALLOW); 326 else if (sender == for_session_blocked_button_) 327 AddContentException(blocked_cookies_tree_, CONTENT_SETTING_SESSION_ONLY); 328} 329 330/////////////////////////////////////////////////////////////////////////////// 331// views::View implementation. 332 333void CollectedCookiesWin::OnTreeViewSelectionChanged( 334 views::TreeView* tree_view) { 335 EnableControls(); 336} 337 338/////////////////////////////////////////////////////////////////////////////// 339// CollectedCookiesWin, private methods. 340 341void CollectedCookiesWin::EnableControls() { 342 bool enable_allowed_buttons = false; 343 ui::TreeModelNode* node = allowed_cookies_tree_->GetSelectedNode(); 344 if (node) { 345 CookieTreeNode* cookie_node = static_cast<CookieTreeNode*>(node); 346 if (cookie_node->GetDetailedInfo().node_type == 347 CookieTreeNode::DetailedInfo::TYPE_ORIGIN) { 348 enable_allowed_buttons = static_cast<CookieTreeOriginNode*>( 349 cookie_node)->CanCreateContentException(); 350 } 351 } 352 block_allowed_button_->SetEnabled(enable_allowed_buttons); 353 354 bool enable_blocked_buttons = false; 355 node = blocked_cookies_tree_->GetSelectedNode(); 356 if (node) { 357 CookieTreeNode* cookie_node = static_cast<CookieTreeNode*>(node); 358 if (cookie_node->GetDetailedInfo().node_type == 359 CookieTreeNode::DetailedInfo::TYPE_ORIGIN) { 360 enable_blocked_buttons = static_cast<CookieTreeOriginNode*>( 361 cookie_node)->CanCreateContentException(); 362 } 363 } 364 allow_blocked_button_->SetEnabled(enable_blocked_buttons); 365 for_session_blocked_button_->SetEnabled(enable_blocked_buttons); 366} 367 368void CollectedCookiesWin::AddContentException(views::TreeView* tree_view, 369 ContentSetting setting) { 370 CookieTreeOriginNode* origin_node = 371 static_cast<CookieTreeOriginNode*>(tree_view->GetSelectedNode()); 372 origin_node->CreateContentException( 373 tab_contents_->profile()->GetHostContentSettingsMap(), setting); 374 infobar_->UpdateVisibility(true, setting, origin_node->GetTitle()); 375 gfx::Rect bounds = GetWidget()->GetClientAreaScreenBounds(); 376 // WidgetWin::GetBounds returns the bounds relative to the parent window, 377 // while WidgetWin::SetBounds wants screen coordinates. Do the translation 378 // here until http://crbug.com/52851 is fixed. 379 POINT topleft = {bounds.x(), bounds.y()}; 380 MapWindowPoints(HWND_DESKTOP, tab_contents_->GetNativeView(), &topleft, 1); 381 gfx::Size size = GetRootView()->GetPreferredSize(); 382 bounds.SetRect(topleft.x, topleft.y, size.width(), size.height()); 383 GetWidget()->SetBounds(bounds); 384} 385 386/////////////////////////////////////////////////////////////////////////////// 387// NotificationObserver implementation. 388 389void CollectedCookiesWin::Observe(NotificationType type, 390 const NotificationSource& source, 391 const NotificationDetails& details) { 392 DCHECK(type == NotificationType::COLLECTED_COOKIES_SHOWN); 393 DCHECK_EQ(Source<TabSpecificContentSettings>(source).ptr(), 394 tab_contents_->GetTabSpecificContentSettings()); 395 window_->CloseConstrainedWindow(); 396} 397