diff options
author | ian@chromium.org <ian@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-06 04:58:48 +0000 |
---|---|---|
committer | ian@chromium.org <ian@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-06 04:58:48 +0000 |
commit | dce516200cbac6100f0268c5f036e8dbddf4f8ac (patch) | |
tree | 9e758547e48369576b568c8dd46d69fb8a75f958 /chrome/browser/cookies_tree_model.cc | |
parent | 91c836e0591bd3c3d874eb18d2403ce927e6be6a (diff) | |
download | chromium_src-dce516200cbac6100f0268c5f036e8dbddf4f8ac.zip chromium_src-dce516200cbac6100f0268c5f036e8dbddf4f8ac.tar.gz chromium_src-dce516200cbac6100f0268c5f036e8dbddf4f8ac.tar.bz2 |
Converting the Cookies options page from a TableView to a TreeView
so that we can add in Database, LocalStorage, and Appcache next
to the cookies for an origin.
BUG=26713
TEST=cookies_tree_model_unittest.cc
Review URL: http://codereview.chromium.org/365005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@31207 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/cookies_tree_model.cc')
-rw-r--r-- | chrome/browser/cookies_tree_model.cc | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/chrome/browser/cookies_tree_model.cc b/chrome/browser/cookies_tree_model.cc new file mode 100644 index 0000000..1ec6e3f --- /dev/null +++ b/chrome/browser/cookies_tree_model.cc @@ -0,0 +1,231 @@ +// Copyright (c) 2009 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/cookies_tree_model.h" + +#include <algorithm> +#include <functional> +#include <vector> + +#include "app/l10n_util.h" +#include "app/resource_bundle.h" +#include "app/table_model_observer.h" +#include "app/tree_node_model.h" +#include "base/linked_ptr.h" +#include "base/string_util.h" +#include "chrome/browser/net/chrome_url_request_context.h" +#include "chrome/browser/profile.h" +#include "grit/app_resources.h" +#include "grit/generated_resources.h" +#include "grit/theme_resources.h" +#include "net/base/cookie_monster.h" +#include "net/url_request/url_request_context.h" +#include "third_party/skia/include/core/SkBitmap.h" + + +/////////////////////////////////////////////////////////////////////////////// +// CookieTreeNode, public: + +void CookieTreeNode::DeleteStoredObjects() { + std::for_each(children().begin(), + children().end(), + std::mem_fun(&CookieTreeNode::DeleteStoredObjects)); +} + +CookiesTreeModel* CookieTreeNode::GetModel() const { + if (GetParent()) + return GetParent()->GetModel(); + else + return NULL; +} + +/////////////////////////////////////////////////////////////////////////////// +// CookieTreeCookieNode, public: + +CookieTreeCookieNode::CookieTreeCookieNode( + net::CookieMonster::CookieListPair* cookie) + : CookieTreeNode(UTF8ToWide(cookie->second.Name())), + cookie_(cookie) { +} + +void CookieTreeCookieNode::DeleteStoredObjects() { + GetModel()->DeleteCookie(*cookie_); +} + +namespace { +// comparison functor, for use in CookieTreeRootNode +class OriginNodeComparator { + public: + bool operator() (const CookieTreeNode* lhs, + const CookieTreeNode* rhs) { + return (lhs->GetTitle() < rhs->GetTitle()); + } +}; + +} // namespace + +/////////////////////////////////////////////////////////////////////////////// +// CookieTreeRootNode, public: +CookieTreeOriginNode* CookieTreeRootNode::GetOrCreateOriginNode( + const std::wstring& origin) { + // Strip the trailing dot if it exists. + std::wstring rewritten_origin = origin; + if (origin.length() >= 1 && origin[0] == '.') + rewritten_origin = origin.substr(1); + + CookieTreeOriginNode rewritten_origin_node(rewritten_origin); + + // First see if there is an existing match. + std::vector<CookieTreeNode*>::iterator origin_node_iterator = + lower_bound(children().begin(), + children().end(), + &rewritten_origin_node, + OriginNodeComparator()); + + if (origin_node_iterator != children().end() && rewritten_origin == + (*origin_node_iterator)->GetTitle()) + return static_cast<CookieTreeOriginNode*>(*origin_node_iterator); + // Node doesn't exist, create a new one and insert it into the (ordered) + // children. + CookieTreeOriginNode* retval = new CookieTreeOriginNode(rewritten_origin); + DCHECK(model_); + model_->Add(this, (origin_node_iterator - children().begin()), retval); + return retval; +} + +/////////////////////////////////////////////////////////////////////////////// +// CookieTreeOriginNode, public: + +CookieTreeCookiesNode* CookieTreeOriginNode::GetOrCreateCookiesNode() { + if (cookies_child_) + return cookies_child_; + // need to make a Cookies node, add it to the tree, and return it + CookieTreeCookiesNode* retval = new CookieTreeCookiesNode; + GetModel()->Add(this, 0, retval); + cookies_child_ = retval; + return retval; +} + +/////////////////////////////////////////////////////////////////////////////// +// CookieTreeCookiesNode, public: + +CookieTreeCookiesNode::CookieTreeCookiesNode() + : CookieTreeNode(l10n_util::GetString(IDS_COOKIES_COOKIES)) {} + + +void CookieTreeCookiesNode::AddCookieNode( + CookieTreeCookieNode* new_child) { + std::vector<CookieTreeNode*>::iterator cookie_iterator = + lower_bound(children().begin(), + children().end(), + new_child, + CookieTreeCookieNode::CookieNodeComparator()); + GetModel()->Add(this, (cookie_iterator - children().begin()), new_child); +} + +/////////////////////////////////////////////////////////////////////////////// +// CookieTreeCookieNode, private + +bool CookieTreeCookieNode::CookieNodeComparator::operator() ( + const CookieTreeNode* lhs, const CookieTreeNode* rhs) { + return (static_cast<const CookieTreeCookieNode*>(lhs)-> + cookie_->second.Name() < + static_cast<const CookieTreeCookieNode*>(rhs)-> + cookie_->second.Name()); +} + +/////////////////////////////////////////////////////////////////////////////// +// CookiesTreeModel, public: + +CookiesTreeModel::CookiesTreeModel(Profile* profile) + : ALLOW_THIS_IN_INITIALIZER_LIST(TreeNodeModel<CookieTreeNode>( + new CookieTreeRootNode(this))), + profile_(profile) { + LoadCookies(); +} + +/////////////////////////////////////////////////////////////////////////////// +// CookiesTreeModel, TreeModel methods (public): + +// TreeModel methods: +// Returns the set of icons for the nodes in the tree. You only need override +// this if you don't want to use the default folder icons. +void CookiesTreeModel::GetIcons(std::vector<SkBitmap>* icons) { + icons->push_back(*ResourceBundle::GetSharedInstance().GetBitmapNamed( + IDR_DEFAULT_FAVICON)); + icons->push_back(*ResourceBundle::GetSharedInstance().GetBitmapNamed( + IDR_COOKIE_ICON)); +} + +// Returns the index of the icon to use for |node|. Return -1 to use the +// default icon. The index is relative to the list of icons returned from +// GetIcons. +int CookiesTreeModel::GetIconIndex(TreeModelNode* node) { + CookieTreeNode* ct_node = static_cast<CookieTreeNode*>(node); + switch (ct_node->GetDetailedInfo().node_type) { + case CookieTreeNode::DetailedInfo::TYPE_ORIGIN: + return ORIGIN; + break; + case CookieTreeNode::DetailedInfo::TYPE_COOKIE: + return COOKIE; + break; + default: + return -1; + } +} + +void CookiesTreeModel::LoadCookies() { + // mmargh mmargh mmargh! + + // Since we are running on the UI thread don't call GetURLRequestContext(). + net::CookieMonster* cookie_monster = + profile_->GetRequestContext()->GetCookieStore()->GetCookieMonster(); + + all_cookies_ = cookie_monster->GetAllCookies(); + CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot()); + for (CookieList::iterator it = all_cookies_.begin(); + it != all_cookies_.end(); + ++it) { + // Get the origin cookie + CookieTreeOriginNode* origin = + root->GetOrCreateOriginNode(UTF8ToWide(it->first)); + CookieTreeCookiesNode* cookies_node = origin->GetOrCreateCookiesNode(); + CookieTreeCookieNode* new_cookie = new CookieTreeCookieNode(&*it); + cookies_node->AddCookieNode(new_cookie); + } +} + +void CookiesTreeModel::DeleteCookie( + const net::CookieMonster::CookieListPair& cookie) { + // notify CookieMonster that we should delete this cookie + // Since we are running on the UI thread don't call GetURLRequestContext(). + net::CookieMonster* monster = + profile_->GetRequestContext()->GetCookieStore()->GetCookieMonster(); + // We have stored a copy of all the cookies in the model, and our model is + // never re-calculated. Thus, we just need to delete the nodes from our + // model, and tell CookieMonster to delete the cookies. We can keep the + // vector storing the cookies in-tact and not delete from there (that would + // invalidate our pointers), and the fact that it contains semi out-of-date + // data is not problematic as we don't re-build the model based on that. + monster->DeleteCookie(cookie.first, cookie.second, true); +} + +void CookiesTreeModel::DeleteAllCookies() { + CookieTreeNode* root = GetRoot(); + root->DeleteStoredObjects(); + int num_children = root->GetChildCount(); + for (int i = num_children - 1; i >= 0; --i) { + delete Remove(root, i); + } + LoadCookies(); + NotifyObserverTreeNodeChanged(root); +} + +void CookiesTreeModel::DeleteCookieNode(CookieTreeCookieNode* cookie_node) { + cookie_node->DeleteStoredObjects(); + // find the parent and index + CookieTreeNode* parent_node = cookie_node->GetParent(); + int cookie_node_index = parent_node->IndexOfChild(cookie_node); + delete Remove(parent_node, cookie_node_index); +} |