diff options
Diffstat (limited to 'chrome/browser/bookmarks/bookmark_table_model.cc')
-rw-r--r-- | chrome/browser/bookmarks/bookmark_table_model.cc | 325 |
1 files changed, 325 insertions, 0 deletions
diff --git a/chrome/browser/bookmarks/bookmark_table_model.cc b/chrome/browser/bookmarks/bookmark_table_model.cc new file mode 100644 index 0000000..c55f6ff --- /dev/null +++ b/chrome/browser/bookmarks/bookmark_table_model.cc @@ -0,0 +1,325 @@ +// 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_table_model.h" + +#include <limits> + +#include "base/string_util.h" +#include "base/time.h" +#include "base/time_format.h" +#include "chrome/app/theme/theme_resources.h" +#include "chrome/common/resource_bundle.h" +#include "googleurl/src/gurl.h" + +#include "generated_resources.h" + +namespace { + +// Number of bookmarks shown in recently bookmarked. +const int kRecentlyBookmarkedCount = 50; + +// FolderBookmarkTableModel ---------------------------------------------------- + +class FolderBookmarkTableModel : public BookmarkTableModel { + public: + FolderBookmarkTableModel(BookmarkModel* model, BookmarkNode* root_node) + : BookmarkTableModel(model), + root_node_(root_node) { + } + + virtual int RowCount() { + return root_node_ ? root_node_->GetChildCount() : 0; + } + + virtual BookmarkNode* GetNodeForRow(int row) { + DCHECK(root_node_); + return root_node_->GetChild(row); + } + + virtual void BookmarkNodeMoved(BookmarkModel* model, + BookmarkNode* old_parent, + int old_index, + BookmarkNode* new_parent, + int new_index) { + if (observer() && (old_parent == root_node_ || new_parent == root_node_)) + observer()->OnModelChanged(); + } + + virtual void BookmarkNodeAdded(BookmarkModel* model, + BookmarkNode* parent, + int index) { + if (root_node_ == parent && observer()) + observer()->OnItemsAdded(index, 1); + } + + virtual void BookmarkNodeRemoved(BookmarkModel* model, + BookmarkNode* parent, + int index, + BookmarkNode* node) { + if (root_node_->HasAncestor(node)) { + // We, our one of our ancestors was removed. + root_node_ = NULL; + if (observer()) + observer()->OnModelChanged(); + return; + } + if (root_node_ == parent && observer()) + observer()->OnItemsRemoved(index, 1); + } + + virtual void BookmarkNodeChanged(BookmarkModel* model, + BookmarkNode* node) { + NotifyChanged(node); + } + + virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model, + BookmarkNode* node) { + NotifyChanged(node); + } + + private: + void NotifyChanged(BookmarkNode* node) { + if (node->GetParent() == root_node_ && observer()) + observer()->OnItemsChanged(node->GetParent()->IndexOfChild(node), 1); + } + + // The node we're showing the children of. This is set to NULL if the node + // (or one of its ancestors) is removed from the model. + BookmarkNode* root_node_; + + DISALLOW_COPY_AND_ASSIGN(FolderBookmarkTableModel); +}; + +// VectorBackedBookmarkTableModel ---------------------------------------------- + +class VectorBackedBookmarkTableModel : public BookmarkTableModel { + public: + explicit VectorBackedBookmarkTableModel(BookmarkModel* model) + : BookmarkTableModel(model) { + } + + virtual BookmarkNode* GetNodeForRow(int row) { + return nodes_[row]; + } + + virtual int RowCount() { + return static_cast<int>(nodes_.size()); + } + + virtual void BookmarkNodeMoved(BookmarkModel* model, + BookmarkNode* old_parent, + int old_index, + BookmarkNode* new_parent, + int new_index) { + NotifyObserverOfChange(new_parent->GetChild(new_index)); + } + + virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model, + BookmarkNode* node) { + NotifyObserverOfChange(node); + } + + virtual void BookmarkNodeChanged(BookmarkModel* model, + BookmarkNode* node) { + NotifyObserverOfChange(node); + } + + protected: + void NotifyObserverOfChange(BookmarkNode* node) { + if (!observer()) + return; + + int index = IndexOfNode(node); + if (index != -1) + observer()->OnItemsChanged(index, 1); + } + + typedef std::vector<BookmarkNode*> Nodes; + Nodes nodes_; + + private: + DISALLOW_COPY_AND_ASSIGN(VectorBackedBookmarkTableModel); +}; + +// RecentlyBookmarkedTableModel ------------------------------------------------ + +class RecentlyBookmarkedTableModel : public VectorBackedBookmarkTableModel { + public: + explicit RecentlyBookmarkedTableModel(BookmarkModel* model) + : VectorBackedBookmarkTableModel(model) { + UpdateRecentlyBookmarked(); + } + + virtual void BookmarkNodeAdded(BookmarkModel* model, + BookmarkNode* parent, + int index) { + if (parent->GetChild(index)->is_url()) + UpdateRecentlyBookmarked(); + } + + virtual void BookmarkNodeRemoved(BookmarkModel* model, + BookmarkNode* parent, + int old_index, + BookmarkNode* old_node) { + if (old_node->is_url()) + UpdateRecentlyBookmarked(); + } + + private: + void UpdateRecentlyBookmarked() { + nodes_.clear(); + model()->GetMostRecentlyAddedEntries(kRecentlyBookmarkedCount, &nodes_); + if (observer()) + observer()->OnModelChanged(); + } + + DISALLOW_COPY_AND_ASSIGN(RecentlyBookmarkedTableModel); +}; + +// BookmarkSearchTableModel ---------------------------------------------------- + +class BookmarkSearchTableModel : public VectorBackedBookmarkTableModel { + public: + BookmarkSearchTableModel(BookmarkModel* model, + const std::wstring& search_text) + : VectorBackedBookmarkTableModel(model), + search_text_(search_text) { + std::vector<BookmarkModel::TitleMatch> matches; + model->GetBookmarksMatchingText(search_text, + std::numeric_limits<int>::max(), &matches); + for (size_t i = 0; i < matches.size(); ++i) + nodes_.push_back(matches[i].node); + } + + virtual void BookmarkNodeAdded(BookmarkModel* model, + BookmarkNode* parent, + int index) { + BookmarkNode* node = parent->GetChild(index); + if (model->DoesBookmarkMatchText(search_text_, node)) { + nodes_.push_back(node); + if (observer()) + observer()->OnItemsAdded(static_cast<int>(nodes_.size() - 1), 1); + } + } + + virtual void BookmarkNodeRemoved(BookmarkModel* model, + BookmarkNode* parent, + int index, + BookmarkNode* node) { + int internal_index = IndexOfNode(node); + if (internal_index == -1) + return; + + nodes_.erase(nodes_.begin() + static_cast<int>(internal_index)); + if (observer()) + observer()->OnItemsRemoved(internal_index, 1); + } + + private: + const std::wstring search_text_; + + DISALLOW_COPY_AND_ASSIGN(BookmarkSearchTableModel); +}; + +} // namespace + +// BookmarkTableModel ---------------------------------------------------------- + +// static +BookmarkTableModel* BookmarkTableModel::CreateRecentlyBookmarkedModel( + BookmarkModel* model) { + return new RecentlyBookmarkedTableModel(model); +} + +// static +BookmarkTableModel* BookmarkTableModel::CreateBookmarkTableModelForFolder( + BookmarkModel* model, BookmarkNode* node) { + return new FolderBookmarkTableModel(model, node); +} + +// static +BookmarkTableModel* BookmarkTableModel::CreateSearchTableModel( + BookmarkModel* model, + const std::wstring& text) { + return new BookmarkSearchTableModel(model, text); +} + +BookmarkTableModel::BookmarkTableModel(BookmarkModel* model) + : model_(model), + observer_(NULL) { + model_->AddObserver(this); +} + +BookmarkTableModel::~BookmarkTableModel() { + if (model_) + model_->RemoveObserver(this); +} + +std::wstring BookmarkTableModel::GetText(int row, int column_id) { + BookmarkNode* node = GetNodeForRow(row); + switch (column_id) { + case IDS_BOOKMARK_TABLE_TITLE: + return node->GetTitle(); + + case IDS_BOOKMARK_TABLE_URL: + return node->is_url() ? UTF8ToWide(node->GetURL().spec()) : + std::wstring(); + + case IDS_BOOKMARK_TABLE_PATH: { + std::wstring path; + BuildPath(node->GetParent(), &path); + return path; + } + } + NOTREACHED(); + return std::wstring(); +} + +SkBitmap BookmarkTableModel::GetIcon(int row) { + static SkBitmap* folder_icon = ResourceBundle::GetSharedInstance(). + GetBitmapNamed(IDR_BOOKMARK_BAR_FOLDER); + static SkBitmap* default_icon = ResourceBundle::GetSharedInstance(). + GetBitmapNamed(IDR_DEFAULT_FAVICON); + + BookmarkNode* node = GetNodeForRow(row); + if (node->is_folder()) + return *folder_icon; + + if (node->GetFavIcon().empty()) + return *default_icon; + + return node->GetFavIcon(); +} + +void BookmarkTableModel::BookmarkModelBeingDeleted(BookmarkModel* model) { + model_->RemoveObserver(this); + model_ = NULL; +} + +int BookmarkTableModel::IndexOfNode(BookmarkNode* node) { + for (int i = RowCount() - 1; i >= 0; --i) { + if (GetNodeForRow(i) == node) + return i; + } + return -1; +} + +void BookmarkTableModel::BuildPath(BookmarkNode* node, std::wstring* path) { + if (!node) { + NOTREACHED(); + return; + } + if (node == model()->GetBookmarkBarNode()) { + *path = l10n_util::GetString(IDS_BOOKMARK_TABLE_BOOKMARK_BAR_PATH); + return; + } + if (node == model()->other_node()) { + *path = l10n_util::GetString(IDS_BOOKMARK_TABLE_OTHER_BOOKMARKS_PATH); + return; + } + BuildPath(node->GetParent(), path); + path->append(l10n_util::GetString(IDS_BOOKMARK_TABLE_PATH_SEPARATOR)); + path->append(node->GetTitle()); +} |