| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/ui/views/options/cookies_view.h" | |
| 6 | |
| 7 #include <algorithm> | |
| 8 | |
| 9 #include "base/message_loop.h" | |
| 10 #include "base/string_util.h" | |
| 11 #include "chrome/browser/profiles/profile.h" | |
| 12 #include "chrome/browser/ui/views/appcache_info_view.h" | |
| 13 #include "chrome/browser/ui/views/cookie_info_view.h" | |
| 14 #include "chrome/browser/ui/views/database_info_view.h" | |
| 15 #include "chrome/browser/ui/views/indexed_db_info_view.h" | |
| 16 #include "chrome/browser/ui/views/local_storage_info_view.h" | |
| 17 #include "grit/generated_resources.h" | |
| 18 #include "grit/locale_settings.h" | |
| 19 #include "net/base/cookie_monster.h" | |
| 20 #include "ui/base/l10n/l10n_util.h" | |
| 21 #include "ui/gfx/canvas.h" | |
| 22 #include "ui/gfx/color_utils.h" | |
| 23 #include "views/border.h" | |
| 24 #include "views/controls/button/native_button.h" | |
| 25 #include "views/controls/label.h" | |
| 26 #include "views/controls/textfield/textfield.h" | |
| 27 #include "views/controls/tree/tree_view.h" | |
| 28 #include "views/layout/grid_layout.h" | |
| 29 #include "views/layout/layout_constants.h" | |
| 30 | |
| 31 // static | |
| 32 views::Window* CookiesView::instance_ = NULL; | |
| 33 static const int kSearchFilterDelayMs = 500; | |
| 34 | |
| 35 /////////////////////////////////////////////////////////////////////////////// | |
| 36 // CookiesTreeView | |
| 37 // Overridden to handle Delete key presses | |
| 38 | |
| 39 class CookiesTreeView : public views::TreeView { | |
| 40 public: | |
| 41 explicit CookiesTreeView(CookiesTreeModel* cookies_model); | |
| 42 virtual ~CookiesTreeView() {} | |
| 43 | |
| 44 // Removes the items associated with the selected node in the TreeView | |
| 45 void RemoveSelectedItems(); | |
| 46 | |
| 47 private: | |
| 48 DISALLOW_COPY_AND_ASSIGN(CookiesTreeView); | |
| 49 }; | |
| 50 | |
| 51 CookiesTreeView::CookiesTreeView(CookiesTreeModel* cookies_model) { | |
| 52 SetModel(cookies_model); | |
| 53 SetRootShown(false); | |
| 54 SetEditable(false); | |
| 55 } | |
| 56 | |
| 57 void CookiesTreeView::RemoveSelectedItems() { | |
| 58 ui::TreeModelNode* selected_node = GetSelectedNode(); | |
| 59 if (selected_node) { | |
| 60 static_cast<CookiesTreeModel*>(model())->DeleteCookieNode( | |
| 61 static_cast<CookieTreeNode*>(GetSelectedNode())); | |
| 62 } | |
| 63 } | |
| 64 | |
| 65 /////////////////////////////////////////////////////////////////////////////// | |
| 66 // CookiesView::InfoPanelView | |
| 67 // Overridden to handle layout of the various info views. | |
| 68 // | |
| 69 // This view is a child of the CookiesView and participates | |
| 70 // in its GridLayout. The various info views are all children | |
| 71 // of this view. Only one child is expected to be visible at a time. | |
| 72 | |
| 73 class CookiesView::InfoPanelView : public views::View { | |
| 74 public: | |
| 75 virtual void Layout() { | |
| 76 for (int i = 0; i < child_count(); ++i) | |
| 77 GetChildViewAt(i)->SetBounds(0, 0, width(), height()); | |
| 78 } | |
| 79 | |
| 80 virtual gfx::Size GetPreferredSize() { | |
| 81 DCHECK(has_children()); | |
| 82 return GetChildViewAt(0)->GetPreferredSize(); | |
| 83 } | |
| 84 }; | |
| 85 | |
| 86 /////////////////////////////////////////////////////////////////////////////// | |
| 87 // CookiesView, public: | |
| 88 | |
| 89 // static | |
| 90 void CookiesView::ShowCookiesWindow(Profile* profile) { | |
| 91 if (!instance_) { | |
| 92 CookiesView* cookies_view = new CookiesView(profile); | |
| 93 instance_ = views::Window::CreateChromeWindow( | |
| 94 NULL, gfx::Rect(), cookies_view); | |
| 95 } | |
| 96 if (!instance_->IsVisible()) { | |
| 97 instance_->Show(); | |
| 98 } else { | |
| 99 instance_->Activate(); | |
| 100 } | |
| 101 } | |
| 102 | |
| 103 CookiesView::~CookiesView() { | |
| 104 cookies_tree_->SetModel(NULL); | |
| 105 } | |
| 106 | |
| 107 /////////////////////////////////////////////////////////////////////////////// | |
| 108 // CookiesView, TreeModelObserver overrides: | |
| 109 | |
| 110 void CookiesView::TreeNodesAdded(ui::TreeModel* model, | |
| 111 ui::TreeModelNode* parent, | |
| 112 int start, | |
| 113 int count) { | |
| 114 UpdateRemoveButtonsState(); | |
| 115 } | |
| 116 | |
| 117 /////////////////////////////////////////////////////////////////////////////// | |
| 118 // CookiesView, views::Buttonlistener implementation: | |
| 119 | |
| 120 void CookiesView::ButtonPressed( | |
| 121 views::Button* sender, const views::Event& event) { | |
| 122 if (sender == remove_button_) { | |
| 123 cookies_tree_->RemoveSelectedItems(); | |
| 124 if (cookies_tree_model_->GetRoot()->child_count() == 0) | |
| 125 UpdateForEmptyState(); | |
| 126 } else if (sender == remove_all_button_) { | |
| 127 cookies_tree_model_->DeleteAllStoredObjects(); | |
| 128 UpdateForEmptyState(); | |
| 129 } else if (sender == clear_search_button_) { | |
| 130 ResetSearchQuery(); | |
| 131 } | |
| 132 } | |
| 133 | |
| 134 /////////////////////////////////////////////////////////////////////////////// | |
| 135 // CookiesView, views::TextfieldController implementation: | |
| 136 | |
| 137 void CookiesView::ContentsChanged(views::Textfield* sender, | |
| 138 const std::wstring& new_contents) { | |
| 139 clear_search_button_->SetEnabled(!search_field_->text().empty()); | |
| 140 search_update_factory_.RevokeAll(); | |
| 141 MessageLoop::current()->PostDelayedTask(FROM_HERE, | |
| 142 search_update_factory_.NewRunnableMethod( | |
| 143 &CookiesView::UpdateSearchResults), kSearchFilterDelayMs); | |
| 144 } | |
| 145 | |
| 146 bool CookiesView::HandleKeyEvent(views::Textfield* sender, | |
| 147 const views::KeyEvent& key_event) { | |
| 148 if (key_event.key_code() == ui::VKEY_ESCAPE) { | |
| 149 ResetSearchQuery(); | |
| 150 } else if (key_event.key_code() == ui::VKEY_RETURN) { | |
| 151 search_update_factory_.RevokeAll(); | |
| 152 UpdateSearchResults(); | |
| 153 } | |
| 154 return false; | |
| 155 } | |
| 156 | |
| 157 /////////////////////////////////////////////////////////////////////////////// | |
| 158 // CookiesView, views::DialogDelegate implementation: | |
| 159 | |
| 160 int CookiesView::GetDialogButtons() const { | |
| 161 return MessageBoxFlags::DIALOGBUTTON_CANCEL; | |
| 162 } | |
| 163 | |
| 164 views::View* CookiesView::GetInitiallyFocusedView() { | |
| 165 return search_field_; | |
| 166 } | |
| 167 | |
| 168 bool CookiesView::CanResize() const { | |
| 169 return true; | |
| 170 } | |
| 171 | |
| 172 std::wstring CookiesView::GetWindowTitle() const { | |
| 173 return UTF16ToWide( | |
| 174 l10n_util::GetStringUTF16(IDS_COOKIES_WEBSITE_PERMISSIONS_WINDOW_TITLE)); | |
| 175 } | |
| 176 | |
| 177 void CookiesView::WindowClosing() { | |
| 178 instance_ = NULL; | |
| 179 } | |
| 180 | |
| 181 views::View* CookiesView::GetContentsView() { | |
| 182 return this; | |
| 183 } | |
| 184 | |
| 185 /////////////////////////////////////////////////////////////////////////////// | |
| 186 // CookiesView, views::View overrides: | |
| 187 | |
| 188 void CookiesView::Layout() { | |
| 189 // Lay out the Remove/Remove All buttons in the parent view. | |
| 190 gfx::Size ps = remove_button_->GetPreferredSize(); | |
| 191 gfx::Rect parent_bounds = parent()->GetContentsBounds(); | |
| 192 int y_buttons = | |
| 193 parent_bounds.bottom() - ps.height() - views::kButtonVEdgeMargin; | |
| 194 | |
| 195 remove_button_->SetBounds(views::kPanelHorizMargin, y_buttons, ps.width(), | |
| 196 ps.height()); | |
| 197 | |
| 198 ps = remove_all_button_->GetPreferredSize(); | |
| 199 int remove_all_x = remove_button_->x() + remove_button_->width() + | |
| 200 views::kRelatedControlHorizontalSpacing; | |
| 201 remove_all_button_->SetBounds(remove_all_x, y_buttons, ps.width(), | |
| 202 ps.height()); | |
| 203 | |
| 204 // Lay out this View | |
| 205 View::Layout(); | |
| 206 } | |
| 207 | |
| 208 gfx::Size CookiesView::GetPreferredSize() { | |
| 209 return gfx::Size(views::Window::GetLocalizedContentsSize( | |
| 210 IDS_COOKIES_DIALOG_WIDTH_CHARS, | |
| 211 IDS_COOKIES_DIALOG_HEIGHT_LINES)); | |
| 212 } | |
| 213 | |
| 214 void CookiesView::ViewHierarchyChanged(bool is_add, | |
| 215 views::View* parent, | |
| 216 views::View* child) { | |
| 217 if (is_add && child == this) | |
| 218 Init(); | |
| 219 } | |
| 220 | |
| 221 /////////////////////////////////////////////////////////////////////////////// | |
| 222 // CookiesView, views::TreeViewController overrides: | |
| 223 | |
| 224 void CookiesView::OnTreeViewSelectionChanged(views::TreeView* tree_view) { | |
| 225 UpdateRemoveButtonsState(); | |
| 226 CookieTreeNode::DetailedInfo detailed_info = | |
| 227 static_cast<CookieTreeNode*>(tree_view->GetSelectedNode())-> | |
| 228 GetDetailedInfo(); | |
| 229 if (detailed_info.node_type == CookieTreeNode::DetailedInfo::TYPE_COOKIE) { | |
| 230 UpdateVisibleDetailedInfo(cookie_info_view_); | |
| 231 cookie_info_view_->SetCookie(detailed_info.cookie->Domain(), | |
| 232 *detailed_info.cookie); | |
| 233 } else if (detailed_info.node_type == | |
| 234 CookieTreeNode::DetailedInfo::TYPE_DATABASE) { | |
| 235 UpdateVisibleDetailedInfo(database_info_view_); | |
| 236 database_info_view_->SetDatabaseInfo(*detailed_info.database_info); | |
| 237 } else if (detailed_info.node_type == | |
| 238 CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE) { | |
| 239 UpdateVisibleDetailedInfo(local_storage_info_view_); | |
| 240 local_storage_info_view_->SetLocalStorageInfo( | |
| 241 *detailed_info.local_storage_info); | |
| 242 } else if (detailed_info.node_type == | |
| 243 CookieTreeNode::DetailedInfo::TYPE_APPCACHE) { | |
| 244 UpdateVisibleDetailedInfo(appcache_info_view_); | |
| 245 appcache_info_view_->SetAppCacheInfo(detailed_info.appcache_info); | |
| 246 } else if (detailed_info.node_type == | |
| 247 CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB) { | |
| 248 UpdateVisibleDetailedInfo(indexed_db_info_view_); | |
| 249 indexed_db_info_view_->SetIndexedDBInfo(*detailed_info.indexed_db_info); | |
| 250 } else { | |
| 251 UpdateVisibleDetailedInfo(cookie_info_view_); | |
| 252 cookie_info_view_->ClearCookieDisplay(); | |
| 253 } | |
| 254 } | |
| 255 | |
| 256 void CookiesView::OnTreeViewKeyDown(ui::KeyboardCode keycode) { | |
| 257 if (keycode == ui::VKEY_DELETE) | |
| 258 cookies_tree_->RemoveSelectedItems(); | |
| 259 } | |
| 260 | |
| 261 /////////////////////////////////////////////////////////////////////////////// | |
| 262 // CookiesView, public: | |
| 263 | |
| 264 void CookiesView::UpdateSearchResults() { | |
| 265 cookies_tree_model_->UpdateSearchResults(search_field_->text()); | |
| 266 UpdateRemoveButtonsState(); | |
| 267 } | |
| 268 | |
| 269 /////////////////////////////////////////////////////////////////////////////// | |
| 270 // CookiesView, private: | |
| 271 | |
| 272 CookiesView::CookiesView(Profile* profile) | |
| 273 : | |
| 274 search_label_(NULL), | |
| 275 search_field_(NULL), | |
| 276 clear_search_button_(NULL), | |
| 277 description_label_(NULL), | |
| 278 cookies_tree_(NULL), | |
| 279 info_panel_(NULL), | |
| 280 cookie_info_view_(NULL), | |
| 281 database_info_view_(NULL), | |
| 282 local_storage_info_view_(NULL), | |
| 283 appcache_info_view_(NULL), | |
| 284 indexed_db_info_view_(NULL), | |
| 285 remove_button_(NULL), | |
| 286 remove_all_button_(NULL), | |
| 287 profile_(profile), | |
| 288 ALLOW_THIS_IN_INITIALIZER_LIST(search_update_factory_(this)) { | |
| 289 } | |
| 290 | |
| 291 void CookiesView::Init() { | |
| 292 search_label_ = new views::Label( | |
| 293 UTF16ToWide(l10n_util::GetStringUTF16(IDS_COOKIES_SEARCH_LABEL))); | |
| 294 search_field_ = new views::Textfield; | |
| 295 search_field_->SetController(this); | |
| 296 clear_search_button_ = new views::NativeButton( | |
| 297 this, | |
| 298 UTF16ToWide(l10n_util::GetStringUTF16(IDS_COOKIES_CLEAR_SEARCH_LABEL))); | |
| 299 clear_search_button_->SetEnabled(false); | |
| 300 description_label_ = new views::Label( | |
| 301 UTF16ToWide(l10n_util::GetStringUTF16(IDS_COOKIES_INFO_LABEL))); | |
| 302 description_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); | |
| 303 cookies_tree_model_.reset(new CookiesTreeModel( | |
| 304 profile_->GetRequestContext()->GetCookieStore()->GetCookieMonster(), | |
| 305 new BrowsingDataDatabaseHelper(profile_), | |
| 306 new BrowsingDataLocalStorageHelper(profile_), | |
| 307 NULL, | |
| 308 new BrowsingDataAppCacheHelper(profile_), | |
| 309 BrowsingDataIndexedDBHelper::Create(profile_))); | |
| 310 cookies_tree_model_->AddCookiesTreeObserver(this); | |
| 311 | |
| 312 info_panel_ = new InfoPanelView; | |
| 313 cookie_info_view_ = new CookieInfoView(false); | |
| 314 database_info_view_ = new DatabaseInfoView; | |
| 315 local_storage_info_view_ = new LocalStorageInfoView; | |
| 316 appcache_info_view_ = new AppCacheInfoView; | |
| 317 indexed_db_info_view_ = new IndexedDBInfoView; | |
| 318 info_panel_->AddChildView(cookie_info_view_); | |
| 319 info_panel_->AddChildView(database_info_view_); | |
| 320 info_panel_->AddChildView(local_storage_info_view_); | |
| 321 info_panel_->AddChildView(appcache_info_view_); | |
| 322 info_panel_->AddChildView(indexed_db_info_view_); | |
| 323 | |
| 324 cookies_tree_ = new CookiesTreeView(cookies_tree_model_.get()); | |
| 325 remove_button_ = new views::NativeButton( | |
| 326 this, | |
| 327 UTF16ToWide(l10n_util::GetStringUTF16(IDS_COOKIES_REMOVE_LABEL))); | |
| 328 remove_all_button_ = new views::NativeButton( | |
| 329 this, | |
| 330 UTF16ToWide(l10n_util::GetStringUTF16(IDS_COOKIES_REMOVE_ALL_LABEL))); | |
| 331 | |
| 332 using views::GridLayout; | |
| 333 using views::ColumnSet; | |
| 334 | |
| 335 GridLayout* layout = GridLayout::CreatePanel(this); | |
| 336 SetLayoutManager(layout); | |
| 337 | |
| 338 const int five_column_layout_id = 0; | |
| 339 ColumnSet* column_set = layout->AddColumnSet(five_column_layout_id); | |
| 340 column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 0, | |
| 341 GridLayout::USE_PREF, 0, 0); | |
| 342 column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing); | |
| 343 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, | |
| 344 GridLayout::USE_PREF, 0, 0); | |
| 345 column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing); | |
| 346 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 0, | |
| 347 GridLayout::USE_PREF, 0, 0); | |
| 348 | |
| 349 const int single_column_layout_id = 1; | |
| 350 column_set = layout->AddColumnSet(single_column_layout_id); | |
| 351 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, | |
| 352 GridLayout::USE_PREF, 0, 0); | |
| 353 | |
| 354 layout->StartRow(0, five_column_layout_id); | |
| 355 layout->AddView(search_label_); | |
| 356 layout->AddView(search_field_); | |
| 357 layout->AddView(clear_search_button_); | |
| 358 layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing); | |
| 359 | |
| 360 layout->StartRow(0, single_column_layout_id); | |
| 361 layout->AddView(description_label_); | |
| 362 | |
| 363 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | |
| 364 layout->StartRow(1, single_column_layout_id); | |
| 365 cookies_tree_->set_lines_at_root(true); | |
| 366 cookies_tree_->set_auto_expand_children(true); | |
| 367 layout->AddView(cookies_tree_); | |
| 368 | |
| 369 cookies_tree_->SetController(this); | |
| 370 | |
| 371 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | |
| 372 layout->StartRow(0, single_column_layout_id); | |
| 373 layout->AddView(info_panel_); | |
| 374 | |
| 375 // Add the Remove/Remove All buttons to the ClientView | |
| 376 parent()->AddChildView(remove_button_); | |
| 377 parent()->AddChildView(remove_all_button_); | |
| 378 if (!cookies_tree_model_.get()->GetRoot()->child_count()) { | |
| 379 UpdateForEmptyState(); | |
| 380 } else { | |
| 381 UpdateVisibleDetailedInfo(cookie_info_view_); | |
| 382 UpdateRemoveButtonsState(); | |
| 383 } | |
| 384 } | |
| 385 | |
| 386 void CookiesView::ResetSearchQuery() { | |
| 387 search_field_->SetText(std::wstring()); | |
| 388 clear_search_button_->SetEnabled(false); | |
| 389 UpdateSearchResults(); | |
| 390 } | |
| 391 | |
| 392 void CookiesView::UpdateForEmptyState() { | |
| 393 cookie_info_view_->ClearCookieDisplay(); | |
| 394 remove_button_->SetEnabled(false); | |
| 395 remove_all_button_->SetEnabled(false); | |
| 396 UpdateVisibleDetailedInfo(cookie_info_view_); | |
| 397 } | |
| 398 | |
| 399 void CookiesView::UpdateRemoveButtonsState() { | |
| 400 remove_button_->SetEnabled(cookies_tree_model_->GetRoot()-> | |
| 401 GetTotalNodeCount() > 1 && cookies_tree_->GetSelectedNode()); | |
| 402 remove_all_button_->SetEnabled(cookies_tree_model_->GetRoot()-> | |
| 403 GetTotalNodeCount() > 1); | |
| 404 } | |
| 405 | |
| 406 void CookiesView::UpdateVisibleDetailedInfo(views::View* view) { | |
| 407 cookie_info_view_->SetVisible(view == cookie_info_view_); | |
| 408 database_info_view_->SetVisible(view == database_info_view_); | |
| 409 local_storage_info_view_->SetVisible(view == local_storage_info_view_); | |
| 410 appcache_info_view_->SetVisible(view == appcache_info_view_); | |
| 411 indexed_db_info_view_->SetVisible(view == indexed_db_info_view_); | |
| 412 } | |
| OLD | NEW |