blob: d5d8038fcbf59e3205fe8fe236906015f951f8c9 [file] [log] [blame]
// Copyright (c) 2006-2008 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/bookmarks/bookmark_folder_tree_model.h"
#include "chrome/app/theme/theme_resources.h"
#include "chrome/common/l10n_util.h"
#include "chrome/common/resource_bundle.h"
#include "generated_resources.h"
BookmarkFolderTreeModel::BookmarkFolderTreeModel(BookmarkModel* model)
: views::TreeNodeModel<FolderNode>(new FolderNode(NULL)),
model_(model),
recently_bookmarked_node_(new FolderNode(NULL)),
search_node_(new FolderNode(NULL)){
recently_bookmarked_node_->SetTitle(
l10n_util::GetString(IDS_BOOKMARK_TREE_RECENTLY_BOOKMARKED_NODE_TITLE));
search_node_->SetTitle(
l10n_util::GetString(IDS_BOOKMARK_TREE_SEARCH_NODE_TITLE));
if (model_->IsLoaded())
AddRootChildren();
model_->AddObserver(this);
}
BookmarkFolderTreeModel::~BookmarkFolderTreeModel() {
if (model_)
model_->RemoveObserver(this);
}
BookmarkFolderTreeModel::NodeType BookmarkFolderTreeModel::GetNodeType(
views::TreeModelNode* node) {
if (node == recently_bookmarked_node_)
return RECENTLY_BOOKMARKED;
if (node == search_node_)
return SEARCH;
if (node == GetRoot())
return NONE;
return BOOKMARK;
}
FolderNode* BookmarkFolderTreeModel::GetFolderNodeForBookmarkNode(
BookmarkNode* node) {
if (!node->is_folder())
return NULL;
return GetFolderNodeForBookmarkNode(AsNode(GetRoot()), node);
}
BookmarkNode* BookmarkFolderTreeModel::TreeNodeAsBookmarkNode(
views::TreeModelNode* node) {
if (GetNodeType(node) != BOOKMARK)
return NULL;
return AsNode(node)->value;
}
void BookmarkFolderTreeModel::Loaded(BookmarkModel* model) {
AddRootChildren();
}
void BookmarkFolderTreeModel::BookmarkModelBeingDeleted(BookmarkModel* model) {
DCHECK(model_);
model_->RemoveObserver(this);
model_ = NULL;
}
void BookmarkFolderTreeModel::BookmarkNodeMoved(BookmarkModel* model,
BookmarkNode* old_parent,
int old_index,
BookmarkNode* new_parent,
int new_index) {
BookmarkNode* moved_node = new_parent->GetChild(new_index);
if (!moved_node->is_folder())
return; // We're only showing folders, so we can ignore this.
FolderNode* moved_folder_node = GetFolderNodeForBookmarkNode(moved_node);
DCHECK(moved_folder_node);
int old_folder_index =
moved_folder_node->GetParent()->IndexOfChild(moved_folder_node);
Remove(moved_folder_node->GetParent(), old_folder_index);
int new_folder_index = CalculateIndexForChild(moved_node);
Add(GetFolderNodeForBookmarkNode(new_parent), new_folder_index,
moved_folder_node);
}
void BookmarkFolderTreeModel::BookmarkNodeAdded(BookmarkModel* model,
BookmarkNode* parent,
int index) {
BookmarkNode* new_node = parent->GetChild(index);
if (!new_node->is_folder())
return; // We're only showing folders, so we can ignore this.
int folder_index = CalculateIndexForChild(new_node);
Add(GetFolderNodeForBookmarkNode(parent), folder_index,
CreateFolderNode(new_node));
}
void BookmarkFolderTreeModel::BookmarkNodeRemoved(BookmarkModel* model,
BookmarkNode* parent,
int index,
BookmarkNode* node) {
if (!node->is_folder())
return; // We're only showing folders.
FolderNode* folder_node = GetFolderNodeForBookmarkNode(parent);
DCHECK(folder_node);
for (int i = 0; i < folder_node->GetChildCount(); ++i) {
if (folder_node->GetChild(i)->value == node) {
scoped_ptr<FolderNode> removed_node(Remove(folder_node, i));
return;
}
}
// If we get here it means a folder was removed that we didn't know about,
// which shouldn't happen.
NOTREACHED();
}
void BookmarkFolderTreeModel::BookmarkNodeChanged(BookmarkModel* model,
BookmarkNode* node) {
if (!node->is_folder())
return;
FolderNode* folder_node = GetFolderNodeForBookmarkNode(node);
if (!folder_node)
return;
folder_node->SetTitle(node->GetTitle());
if (GetObserver())
GetObserver()->TreeNodeChanged(this, folder_node);
}
void BookmarkFolderTreeModel::GetIcons(std::vector<SkBitmap>* icons) {
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
icons->push_back(*rb.GetBitmapNamed(IDR_BOOKMARK_MANAGER_RECENT_ICON));
icons->push_back(*rb.GetBitmapNamed(IDR_BOOKMARK_MANAGER_SEARCH_ICON));
}
int BookmarkFolderTreeModel::GetIconIndex(views::TreeModelNode* node) {
if (node == recently_bookmarked_node_)
return 0;
if (node == search_node_)
return 1;
// Return -1 to use the default.
return -1;
}
void BookmarkFolderTreeModel::AddRootChildren() {
Add(AsNode(GetRoot()), 0, CreateFolderNode(model_->GetBookmarkBarNode()));
Add(AsNode(GetRoot()), 1, CreateFolderNode(model_->other_node()));
Add(AsNode(GetRoot()), 2, recently_bookmarked_node_);
Add(AsNode(GetRoot()), 3, search_node_);
}
FolderNode* BookmarkFolderTreeModel::GetFolderNodeForBookmarkNode(
FolderNode* folder_node,
BookmarkNode* node) {
DCHECK(node->is_folder());
if (folder_node->value == node)
return folder_node;
for (int i = 0; i < folder_node->GetChildCount(); ++i) {
FolderNode* result =
GetFolderNodeForBookmarkNode(folder_node->GetChild(i), node);
if (result)
return result;
}
return NULL;
}
FolderNode* BookmarkFolderTreeModel::CreateFolderNode(BookmarkNode* node) {
DCHECK(node->is_folder());
FolderNode* folder_node = new FolderNode(node);
folder_node->SetTitle(node->GetTitle());
// And clone the children folders.
for (int i = 0; i < node->GetChildCount(); ++i) {
BookmarkNode* child = node->GetChild(i);
if (child->is_folder())
folder_node->Add(folder_node->GetChildCount(), CreateFolderNode(child));
}
return folder_node;
}
int BookmarkFolderTreeModel::CalculateIndexForChild(BookmarkNode* node) {
BookmarkNode* parent = node->GetParent();
DCHECK(parent);
for (int i = 0, folder_count = 0; i < parent->GetChildCount(); ++i) {
BookmarkNode* child = parent->GetChild(i);
if (child == node)
return folder_count;
if (child->is_folder())
folder_count++;
}
NOTREACHED();
return 0;
}