diff options
Diffstat (limited to 'chrome/browser/ui/views/options/cookies_view.cc')
-rw-r--r-- | chrome/browser/ui/views/options/cookies_view.cc | 397 |
1 files changed, 397 insertions, 0 deletions
diff --git a/chrome/browser/ui/views/options/cookies_view.cc b/chrome/browser/ui/views/options/cookies_view.cc new file mode 100644 index 0000000..5e2b6d0 --- /dev/null +++ b/chrome/browser/ui/views/options/cookies_view.cc @@ -0,0 +1,397 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/views/options/cookies_view.h" + +#include <algorithm> + +#include "app/l10n_util.h" +#include "base/message_loop.h" +#include "base/string_util.h" +#include "chrome/browser/profile.h" +#include "chrome/browser/views/appcache_info_view.h" +#include "chrome/browser/views/cookie_info_view.h" +#include "chrome/browser/views/database_info_view.h" +#include "chrome/browser/views/indexed_db_info_view.h" +#include "chrome/browser/views/local_storage_info_view.h" +#include "gfx/canvas.h" +#include "gfx/color_utils.h" +#include "grit/generated_resources.h" +#include "grit/locale_settings.h" +#include "net/base/cookie_monster.h" +#include "views/border.h" +#include "views/grid_layout.h" +#include "views/controls/label.h" +#include "views/controls/button/native_button.h" +#include "views/controls/tree/tree_view.h" +#include "views/controls/textfield/textfield.h" +#include "views/standard_layout.h" + +// static +views::Window* CookiesView::instance_ = NULL; +static const int kSearchFilterDelayMs = 500; + +/////////////////////////////////////////////////////////////////////////////// +// CookiesTreeView +// Overridden to handle Delete key presses + +class CookiesTreeView : public views::TreeView { + public: + explicit CookiesTreeView(CookiesTreeModel* cookies_model); + virtual ~CookiesTreeView() {} + + // Removes the items associated with the selected node in the TreeView + void RemoveSelectedItems(); + + private: + DISALLOW_COPY_AND_ASSIGN(CookiesTreeView); +}; + +CookiesTreeView::CookiesTreeView(CookiesTreeModel* cookies_model) { + SetModel(cookies_model); + SetRootShown(false); + SetEditable(false); +} + +void CookiesTreeView::RemoveSelectedItems() { + TreeModelNode* selected_node = GetSelectedNode(); + if (selected_node) { + static_cast<CookiesTreeModel*>(model())->DeleteCookieNode( + static_cast<CookieTreeNode*>(GetSelectedNode())); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// CookiesView::InfoPanelView +// Overridden to handle layout of the various info views. +// +// This view is a child of the CookiesView and participates +// in its GridLayout. The various info views are all children +// of this view. Only one child is expected to be visible at a time. + +class CookiesView::InfoPanelView : public views::View { + public: + virtual void Layout() { + int child_count = GetChildViewCount(); + for (int i = 0; i < child_count; ++i) + GetChildViewAt(i)->SetBounds(0, 0, width(), height()); + } + + virtual gfx::Size GetPreferredSize() { + DCHECK(GetChildViewCount() > 0); + return GetChildViewAt(0)->GetPreferredSize(); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// CookiesView, public: + +// static +void CookiesView::ShowCookiesWindow(Profile* profile) { + if (!instance_) { + CookiesView* cookies_view = new CookiesView(profile); + instance_ = views::Window::CreateChromeWindow( + NULL, gfx::Rect(), cookies_view); + } + if (!instance_->IsVisible()) { + instance_->Show(); + } else { + instance_->Activate(); + } +} + +CookiesView::~CookiesView() { + cookies_tree_->SetModel(NULL); +} + +/////////////////////////////////////////////////////////////////////////////// +// CookiesView, TreeModelObserver overrides: + +void CookiesView::TreeNodesAdded(TreeModel* model, + TreeModelNode* parent, + int start, + int count) { + UpdateRemoveButtonsState(); +} + +/////////////////////////////////////////////////////////////////////////////// +// CookiesView, views::Buttonlistener implementation: + +void CookiesView::ButtonPressed( + views::Button* sender, const views::Event& event) { + if (sender == remove_button_) { + cookies_tree_->RemoveSelectedItems(); + if (cookies_tree_model_->GetRoot()->GetChildCount() == 0) + UpdateForEmptyState(); + } else if (sender == remove_all_button_) { + cookies_tree_model_->DeleteAllStoredObjects(); + UpdateForEmptyState(); + } else if (sender == clear_search_button_) { + ResetSearchQuery(); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// CookiesView, views::Textfield::Controller implementation: + +void CookiesView::ContentsChanged(views::Textfield* sender, + const std::wstring& new_contents) { + clear_search_button_->SetEnabled(!search_field_->text().empty()); + search_update_factory_.RevokeAll(); + MessageLoop::current()->PostDelayedTask(FROM_HERE, + search_update_factory_.NewRunnableMethod( + &CookiesView::UpdateSearchResults), kSearchFilterDelayMs); +} + +bool CookiesView::HandleKeystroke(views::Textfield* sender, + const views::Textfield::Keystroke& key) { + if (key.GetKeyboardCode() == app::VKEY_ESCAPE) { + ResetSearchQuery(); + } else if (key.GetKeyboardCode() == app::VKEY_RETURN) { + search_update_factory_.RevokeAll(); + UpdateSearchResults(); + } + return false; +} + +/////////////////////////////////////////////////////////////////////////////// +// CookiesView, views::DialogDelegate implementation: + +std::wstring CookiesView::GetWindowTitle() const { + return l10n_util::GetString(IDS_COOKIES_WEBSITE_PERMISSIONS_WINDOW_TITLE); +} + +void CookiesView::WindowClosing() { + instance_ = NULL; +} + +views::View* CookiesView::GetContentsView() { + return this; +} + +/////////////////////////////////////////////////////////////////////////////// +// CookiesView, views::View overrides: + +void CookiesView::Layout() { + // Lay out the Remove/Remove All buttons in the parent view. + gfx::Size ps = remove_button_->GetPreferredSize(); + gfx::Rect parent_bounds = GetParent()->GetLocalBounds(false); + int y_buttons = parent_bounds.bottom() - ps.height() - kButtonVEdgeMargin; + + remove_button_->SetBounds(kPanelHorizMargin, y_buttons, ps.width(), + ps.height()); + + ps = remove_all_button_->GetPreferredSize(); + int remove_all_x = remove_button_->x() + remove_button_->width() + + kRelatedControlHorizontalSpacing; + remove_all_button_->SetBounds(remove_all_x, y_buttons, ps.width(), + ps.height()); + + // Lay out this View + View::Layout(); +} + +gfx::Size CookiesView::GetPreferredSize() { + return gfx::Size(views::Window::GetLocalizedContentsSize( + IDS_COOKIES_DIALOG_WIDTH_CHARS, + IDS_COOKIES_DIALOG_HEIGHT_LINES)); +} + +void CookiesView::ViewHierarchyChanged(bool is_add, + views::View* parent, + views::View* child) { + if (is_add && child == this) + Init(); +} + +/////////////////////////////////////////////////////////////////////////////// +// CookiesView, views::TreeViewController overrides: + +void CookiesView::OnTreeViewSelectionChanged(views::TreeView* tree_view) { + UpdateRemoveButtonsState(); + CookieTreeNode::DetailedInfo detailed_info = + static_cast<CookieTreeNode*>(tree_view->GetSelectedNode())-> + GetDetailedInfo(); + if (detailed_info.node_type == CookieTreeNode::DetailedInfo::TYPE_COOKIE) { + UpdateVisibleDetailedInfo(cookie_info_view_); + cookie_info_view_->SetCookie(detailed_info.cookie->Domain(), + *detailed_info.cookie); + } else if (detailed_info.node_type == + CookieTreeNode::DetailedInfo::TYPE_DATABASE) { + UpdateVisibleDetailedInfo(database_info_view_); + database_info_view_->SetDatabaseInfo(*detailed_info.database_info); + } else if (detailed_info.node_type == + CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE) { + UpdateVisibleDetailedInfo(local_storage_info_view_); + local_storage_info_view_->SetLocalStorageInfo( + *detailed_info.local_storage_info); + } else if (detailed_info.node_type == + CookieTreeNode::DetailedInfo::TYPE_APPCACHE) { + UpdateVisibleDetailedInfo(appcache_info_view_); + appcache_info_view_->SetAppCacheInfo(detailed_info.appcache_info); + } else if (detailed_info.node_type == + CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB) { + UpdateVisibleDetailedInfo(indexed_db_info_view_); + indexed_db_info_view_->SetIndexedDBInfo(*detailed_info.indexed_db_info); + } else { + UpdateVisibleDetailedInfo(cookie_info_view_); + cookie_info_view_->ClearCookieDisplay(); + } +} + +void CookiesView::OnTreeViewKeyDown(app::KeyboardCode keycode) { + if (keycode == app::VKEY_DELETE) + cookies_tree_->RemoveSelectedItems(); +} + +/////////////////////////////////////////////////////////////////////////////// +// CookiesView, public: + +void CookiesView::UpdateSearchResults() { + cookies_tree_model_->UpdateSearchResults(search_field_->text()); + UpdateRemoveButtonsState(); +} + +/////////////////////////////////////////////////////////////////////////////// +// CookiesView, private: + +CookiesView::CookiesView(Profile* profile) + : + search_label_(NULL), + search_field_(NULL), + clear_search_button_(NULL), + description_label_(NULL), + cookies_tree_(NULL), + info_panel_(NULL), + cookie_info_view_(NULL), + database_info_view_(NULL), + local_storage_info_view_(NULL), + appcache_info_view_(NULL), + indexed_db_info_view_(NULL), + remove_button_(NULL), + remove_all_button_(NULL), + profile_(profile), + ALLOW_THIS_IN_INITIALIZER_LIST(search_update_factory_(this)) { +} + +void CookiesView::Init() { + search_label_ = new views::Label( + l10n_util::GetString(IDS_COOKIES_SEARCH_LABEL)); + search_field_ = new views::Textfield; + search_field_->SetController(this); + clear_search_button_ = new views::NativeButton( + this, l10n_util::GetString(IDS_COOKIES_CLEAR_SEARCH_LABEL)); + clear_search_button_->SetEnabled(false); + description_label_ = new views::Label( + l10n_util::GetString(IDS_COOKIES_INFO_LABEL)); + description_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); + cookies_tree_model_.reset(new CookiesTreeModel( + profile_->GetRequestContext()->GetCookieStore()->GetCookieMonster(), + new BrowsingDataDatabaseHelper(profile_), + new BrowsingDataLocalStorageHelper(profile_), + NULL, + new BrowsingDataAppCacheHelper(profile_), + BrowsingDataIndexedDBHelper::Create(profile_))); + cookies_tree_model_->AddObserver(this); + + info_panel_ = new InfoPanelView; + cookie_info_view_ = new CookieInfoView(false); + database_info_view_ = new DatabaseInfoView; + local_storage_info_view_ = new LocalStorageInfoView; + appcache_info_view_ = new AppCacheInfoView; + indexed_db_info_view_ = new IndexedDBInfoView; + info_panel_->AddChildView(cookie_info_view_); + info_panel_->AddChildView(database_info_view_); + info_panel_->AddChildView(local_storage_info_view_); + info_panel_->AddChildView(appcache_info_view_); + info_panel_->AddChildView(indexed_db_info_view_); + + cookies_tree_ = new CookiesTreeView(cookies_tree_model_.get()); + remove_button_ = new views::NativeButton( + this, l10n_util::GetString(IDS_COOKIES_REMOVE_LABEL)); + remove_all_button_ = new views::NativeButton( + this, l10n_util::GetString(IDS_COOKIES_REMOVE_ALL_LABEL)); + + using views::GridLayout; + using views::ColumnSet; + + GridLayout* layout = CreatePanelGridLayout(this); + SetLayoutManager(layout); + + const int five_column_layout_id = 0; + ColumnSet* column_set = layout->AddColumnSet(five_column_layout_id); + column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 0, + GridLayout::USE_PREF, 0, 0); + column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); + column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, + GridLayout::USE_PREF, 0, 0); + column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); + column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 0, + GridLayout::USE_PREF, 0, 0); + + const int single_column_layout_id = 1; + column_set = layout->AddColumnSet(single_column_layout_id); + column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, + GridLayout::USE_PREF, 0, 0); + + layout->StartRow(0, five_column_layout_id); + layout->AddView(search_label_); + layout->AddView(search_field_); + layout->AddView(clear_search_button_); + layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing); + + layout->StartRow(0, single_column_layout_id); + layout->AddView(description_label_); + + layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); + layout->StartRow(1, single_column_layout_id); + cookies_tree_->set_lines_at_root(true); + cookies_tree_->set_auto_expand_children(true); + layout->AddView(cookies_tree_); + + cookies_tree_->SetController(this); + + layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); + layout->StartRow(0, single_column_layout_id); + layout->AddView(info_panel_); + + // Add the Remove/Remove All buttons to the ClientView + View* parent = GetParent(); + parent->AddChildView(remove_button_); + parent->AddChildView(remove_all_button_); + if (!cookies_tree_model_.get()->GetRoot()->GetChildCount()) { + UpdateForEmptyState(); + } else { + UpdateVisibleDetailedInfo(cookie_info_view_); + UpdateRemoveButtonsState(); + } +} + +void CookiesView::ResetSearchQuery() { + search_field_->SetText(std::wstring()); + clear_search_button_->SetEnabled(false); + UpdateSearchResults(); +} + +void CookiesView::UpdateForEmptyState() { + cookie_info_view_->ClearCookieDisplay(); + remove_button_->SetEnabled(false); + remove_all_button_->SetEnabled(false); + UpdateVisibleDetailedInfo(cookie_info_view_); +} + +void CookiesView::UpdateRemoveButtonsState() { + remove_button_->SetEnabled(cookies_tree_model_->GetRoot()-> + GetTotalNodeCount() > 1 && cookies_tree_->GetSelectedNode()); + remove_all_button_->SetEnabled(cookies_tree_model_->GetRoot()-> + GetTotalNodeCount() > 1); +} + +void CookiesView::UpdateVisibleDetailedInfo(views::View* view) { + cookie_info_view_->SetVisible(view == cookie_info_view_); + database_info_view_->SetVisible(view == database_info_view_); + local_storage_info_view_->SetVisible(view == local_storage_info_view_); + appcache_info_view_->SetVisible(view == appcache_info_view_); + indexed_db_info_view_->SetVisible(view == indexed_db_info_view_); +} |