| Index: chrome/browser/cookies_tree_model.cc
|
| ===================================================================
|
| --- chrome/browser/cookies_tree_model.cc (revision 0)
|
| +++ chrome/browser/cookies_tree_model.cc (revision 0)
|
| @@ -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);
|
| +}
|
|
|
| Property changes on: chrome\browser\cookies_tree_model.cc
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|