summaryrefslogtreecommitdiffstats
path: root/chrome/browser/bookmarks/bookmark_table_model.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/bookmarks/bookmark_table_model.cc')
-rw-r--r--chrome/browser/bookmarks/bookmark_table_model.cc325
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());
+}