| Index: chrome/browser/bookmark_bar_model.cc
|
| ===================================================================
|
| --- chrome/browser/bookmark_bar_model.cc (revision 1903)
|
| +++ chrome/browser/bookmark_bar_model.cc (working copy)
|
| @@ -1,694 +0,0 @@
|
| -// 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/bookmark_bar_model.h"
|
| -
|
| -#include "base/gfx/png_decoder.h"
|
| -#include "chrome/browser/history/query_parser.h"
|
| -#include "chrome/browser/profile.h"
|
| -#include "chrome/browser/bookmark_storage.h"
|
| -#include "chrome/common/scoped_vector.h"
|
| -
|
| -#include "generated_resources.h"
|
| -
|
| -namespace {
|
| -
|
| -// Functions used for sorting.
|
| -bool MoreRecentlyModified(BookmarkBarNode* n1, BookmarkBarNode* n2) {
|
| - return n1->date_group_modified() > n2->date_group_modified();
|
| -}
|
| -
|
| -bool MoreRecentlyAdded(BookmarkBarNode* n1, BookmarkBarNode* n2) {
|
| - return n1->date_added() > n2->date_added();
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -// BookmarkBarNode ------------------------------------------------------------
|
| -
|
| -namespace {
|
| -
|
| -// ID for BookmarkBarNodes.
|
| -// Various places assume an invalid id if == 0, for that reason we start with 1.
|
| -int next_id_ = 1;
|
| -
|
| -}
|
| -
|
| -const SkBitmap& BookmarkBarNode::GetFavIcon() {
|
| - if (!loaded_favicon_) {
|
| - loaded_favicon_ = true;
|
| - model_->LoadFavIcon(this);
|
| - }
|
| - return favicon_;
|
| -}
|
| -
|
| -BookmarkBarNode::BookmarkBarNode(BookmarkBarModel* model, const GURL& url)
|
| - : model_(model),
|
| - id_(next_id_++),
|
| - loaded_favicon_(false),
|
| - favicon_load_handle_(0),
|
| - url_(url),
|
| - type_(!url.is_empty() ? history::StarredEntry::URL :
|
| - history::StarredEntry::BOOKMARK_BAR),
|
| - date_added_(Time::Now()) {
|
| -}
|
| -
|
| -void BookmarkBarNode::Reset(const history::StarredEntry& entry) {
|
| - DCHECK(entry.type != history::StarredEntry::URL ||
|
| - entry.url == url_);
|
| -
|
| - favicon_ = SkBitmap();
|
| - type_ = entry.type;
|
| - date_added_ = entry.date_added;
|
| - date_group_modified_ = entry.date_group_modified;
|
| - SetTitle(entry.title);
|
| -}
|
| -
|
| -// BookmarkBarModel -----------------------------------------------------------
|
| -
|
| -BookmarkBarModel::BookmarkBarModel(Profile* profile)
|
| - : profile_(profile),
|
| - loaded_(false),
|
| -#pragma warning(suppress: 4355) // Okay to pass "this" here.
|
| - root_(this, GURL()),
|
| - bookmark_bar_node_(NULL),
|
| - other_node_(NULL),
|
| - waiting_for_history_load_(false),
|
| - loaded_signal_(CreateEvent(NULL, TRUE, FALSE, NULL)) {
|
| - // Create the bookmark bar and other bookmarks folders. These always exist.
|
| - CreateBookmarkBarNode();
|
| - CreateOtherBookmarksNode();
|
| -
|
| - // And add them to the root.
|
| - //
|
| - // WARNING: order is important here, various places assume bookmark bar then
|
| - // other node.
|
| - root_.Add(0, bookmark_bar_node_);
|
| - root_.Add(1, other_node_);
|
| -
|
| - if (!profile_) {
|
| - // Profile is null during testing.
|
| - DoneLoading();
|
| - }
|
| -}
|
| -
|
| -BookmarkBarModel::~BookmarkBarModel() {
|
| - if (profile_ && store_.get()) {
|
| - NotificationService::current()->RemoveObserver(
|
| - this, NOTIFY_FAVICON_CHANGED, Source<Profile>(profile_));
|
| - }
|
| -
|
| - if (waiting_for_history_load_) {
|
| - NotificationService::current()->RemoveObserver(
|
| - this, NOTIFY_HISTORY_LOADED, Source<Profile>(profile_));
|
| - }
|
| -
|
| - FOR_EACH_OBSERVER(BookmarkBarModelObserver, observers_,
|
| - BookmarkModelBeingDeleted(this));
|
| -
|
| - if (store_) {
|
| - // The store maintains a reference back to us. We need to tell it we're gone
|
| - // so that it doesn't try and invoke a method back on us again.
|
| - store_->BookmarkModelDeleted();
|
| - }
|
| -}
|
| -
|
| -void BookmarkBarModel::Load() {
|
| - if (store_.get()) {
|
| - // If the store is non-null, it means Load was already invoked. Load should
|
| - // only be invoked once.
|
| - NOTREACHED();
|
| - return;
|
| - }
|
| -
|
| - // Listen for changes to favicons so that we can update the favicon of the
|
| - // node appropriately.
|
| - NotificationService::current()->AddObserver(
|
| - this, NOTIFY_FAVICON_CHANGED, Source<Profile>(profile_));
|
| -
|
| - // Load the bookmarks. BookmarkStorage notifies us when done.
|
| - store_ = new BookmarkStorage(profile_, this);
|
| - store_->LoadBookmarks(false);
|
| -}
|
| -
|
| -BookmarkBarNode* BookmarkBarModel::GetParentForNewNodes() {
|
| - std::vector<BookmarkBarNode*> nodes;
|
| -
|
| - GetMostRecentlyModifiedGroupNodes(&root_, 1, &nodes);
|
| - return nodes.empty() ? bookmark_bar_node_ : nodes[0];
|
| -}
|
| -
|
| -std::vector<BookmarkBarNode*> BookmarkBarModel::GetMostRecentlyModifiedGroups(
|
| - size_t max_count) {
|
| - std::vector<BookmarkBarNode*> nodes;
|
| - GetMostRecentlyModifiedGroupNodes(&root_, max_count, &nodes);
|
| -
|
| - if (nodes.size() < max_count) {
|
| - // Add the bookmark bar and other nodes if there is space.
|
| - if (find(nodes.begin(), nodes.end(), bookmark_bar_node_) == nodes.end())
|
| - nodes.push_back(bookmark_bar_node_);
|
| -
|
| - if (nodes.size() < max_count &&
|
| - find(nodes.begin(), nodes.end(), other_node_) == nodes.end()) {
|
| - nodes.push_back(other_node_);
|
| - }
|
| - }
|
| - return nodes;
|
| -}
|
| -
|
| -void BookmarkBarModel::GetMostRecentlyAddedEntries(
|
| - size_t count,
|
| - std::vector<BookmarkBarNode*>* nodes) {
|
| - AutoLock url_lock(url_lock_);
|
| - for (NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.begin();
|
| - i != nodes_ordered_by_url_set_.end(); ++i) {
|
| - std::vector<BookmarkBarNode*>::iterator insert_position =
|
| - std::upper_bound(nodes->begin(), nodes->end(), *i, &MoreRecentlyAdded);
|
| - if (nodes->size() < count || insert_position != nodes->end()) {
|
| - nodes->insert(insert_position, *i);
|
| - while (nodes->size() > count)
|
| - nodes->pop_back();
|
| - }
|
| - }
|
| -}
|
| -
|
| -void BookmarkBarModel::GetBookmarksMatchingText(
|
| - const std::wstring& text,
|
| - size_t max_count,
|
| - std::vector<TitleMatch>* matches) {
|
| - QueryParser parser;
|
| - ScopedVector<QueryNode> query_nodes;
|
| - parser.ParseQuery(text, &query_nodes.get());
|
| - if (query_nodes.empty())
|
| - return;
|
| -
|
| - AutoLock url_lock(url_lock_);
|
| - Snippet::MatchPositions match_position;
|
| - for (NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.begin();
|
| - i != nodes_ordered_by_url_set_.end(); ++i) {
|
| - if (parser.DoesQueryMatch((*i)->GetTitle(), query_nodes.get(),
|
| - &match_position)) {
|
| - matches->push_back(TitleMatch());
|
| - matches->back().node = *i;
|
| - matches->back().match_positions.swap(match_position);
|
| - if (matches->size() == max_count)
|
| - break;
|
| - }
|
| - }
|
| -}
|
| -
|
| -void BookmarkBarModel::Remove(BookmarkBarNode* parent, int index) {
|
| - if (!loaded_ || !IsValidIndex(parent, index, false) || parent == &root_) {
|
| - NOTREACHED();
|
| - return;
|
| - }
|
| - RemoveAndDeleteNode(parent->GetChild(index));
|
| -}
|
| -
|
| -void BookmarkBarModel::Move(BookmarkBarNode* node,
|
| - BookmarkBarNode* new_parent,
|
| - int index) {
|
| - if (!loaded_ || !node || !IsValidIndex(new_parent, index, true) ||
|
| - new_parent == &root_ || node == &root_ || node == bookmark_bar_node_ ||
|
| - node == other_node_) {
|
| - NOTREACHED();
|
| - return;
|
| - }
|
| -
|
| - if (new_parent->HasAncestor(node)) {
|
| - // Can't make an ancestor of the node be a child of the node.
|
| - NOTREACHED();
|
| - return;
|
| - }
|
| -
|
| - SetDateGroupModified(new_parent, Time::Now());
|
| -
|
| - BookmarkBarNode* old_parent = node->GetParent();
|
| - int old_index = old_parent->IndexOfChild(node);
|
| -
|
| - if (old_parent == new_parent &&
|
| - (index == old_index || index == old_index + 1)) {
|
| - // Node is already in this position, nothing to do.
|
| - return;
|
| - }
|
| -
|
| - if (old_parent == new_parent && index > old_index)
|
| - index--;
|
| - new_parent->Add(index, node);
|
| -
|
| - if (store_.get())
|
| - store_->ScheduleSave();
|
| -
|
| - FOR_EACH_OBSERVER(BookmarkBarModelObserver, observers_,
|
| - BookmarkNodeMoved(this, old_parent, old_index,
|
| - new_parent, index));
|
| -}
|
| -
|
| -void BookmarkBarModel::SetTitle(BookmarkBarNode* node,
|
| - const std::wstring& title) {
|
| - if (!node) {
|
| - NOTREACHED();
|
| - return;
|
| - }
|
| - if (node->GetTitle() == title)
|
| - return;
|
| -
|
| - node->SetTitle(title);
|
| -
|
| - if (store_.get())
|
| - store_->ScheduleSave();
|
| -
|
| - FOR_EACH_OBSERVER(BookmarkBarModelObserver, observers_,
|
| - BookmarkNodeChanged(this, node));
|
| -}
|
| -
|
| -BookmarkBarNode* BookmarkBarModel::GetNodeByURL(const GURL& url) {
|
| - AutoLock url_lock(url_lock_);
|
| - BookmarkBarNode tmp_node(this, url);
|
| - NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.find(&tmp_node);
|
| - return (i != nodes_ordered_by_url_set_.end()) ? *i : NULL;
|
| -}
|
| -
|
| -void BookmarkBarModel::GetBookmarks(std::vector<GURL>* urls) {
|
| - AutoLock url_lock(url_lock_);
|
| - for (NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.begin();
|
| - i != nodes_ordered_by_url_set_.end(); ++i) {
|
| - urls->push_back((*i)->GetURL());
|
| - }
|
| -}
|
| -
|
| -BookmarkBarNode* BookmarkBarModel::GetNodeByID(int id) {
|
| - // TODO(sky): TreeNode needs a method that visits all nodes using a predicate.
|
| - return GetNodeByID(&root_, id);
|
| -}
|
| -
|
| -BookmarkBarNode* BookmarkBarModel::AddGroup(
|
| - BookmarkBarNode* parent,
|
| - int index,
|
| - const std::wstring& title) {
|
| - if (!loaded_ || parent == &root_ || !IsValidIndex(parent, index, true)) {
|
| - // Can't add to the root.
|
| - NOTREACHED();
|
| - return NULL;
|
| - }
|
| -
|
| - BookmarkBarNode* new_node = new BookmarkBarNode(this, GURL());
|
| - new_node->SetTitle(title);
|
| - new_node->type_ = history::StarredEntry::USER_GROUP;
|
| -
|
| - return AddNode(parent, index, new_node);
|
| -}
|
| -
|
| -BookmarkBarNode* BookmarkBarModel::AddURL(BookmarkBarNode* parent,
|
| - int index,
|
| - const std::wstring& title,
|
| - const GURL& url) {
|
| - return AddURLWithCreationTime(parent, index, title, url, Time::Now());
|
| -}
|
| -
|
| -BookmarkBarNode* BookmarkBarModel::AddURLWithCreationTime(
|
| - BookmarkBarNode* parent,
|
| - int index,
|
| - const std::wstring& title,
|
| - const GURL& url,
|
| - const Time& creation_time) {
|
| - if (!loaded_ || !url.is_valid() || parent == &root_ ||
|
| - !IsValidIndex(parent, index, true)) {
|
| - NOTREACHED();
|
| - return NULL;
|
| - }
|
| -
|
| - BookmarkBarNode* existing_node = GetNodeByURL(url);
|
| - if (existing_node) {
|
| - Move(existing_node, parent, index);
|
| - SetTitle(existing_node, title);
|
| - return existing_node;
|
| - }
|
| -
|
| - SetDateGroupModified(parent, creation_time);
|
| -
|
| - BookmarkBarNode* new_node = new BookmarkBarNode(this, url);
|
| - new_node->SetTitle(title);
|
| - new_node->date_added_ = creation_time;
|
| - new_node->type_ = history::StarredEntry::URL;
|
| -
|
| - AutoLock url_lock(url_lock_);
|
| - nodes_ordered_by_url_set_.insert(new_node);
|
| -
|
| - return AddNode(parent, index, new_node);
|
| -}
|
| -
|
| -void BookmarkBarModel::SetURLStarred(const GURL& url,
|
| - const std::wstring& title,
|
| - bool is_starred) {
|
| - BookmarkBarNode* node = GetNodeByURL(url);
|
| - if (is_starred && !node) {
|
| - // Add the url.
|
| - BookmarkBarNode* parent = GetParentForNewNodes();
|
| - AddURL(parent, parent->GetChildCount(), title, url);
|
| - } else if (!is_starred && node) {
|
| - Remove(node->GetParent(), node->GetParent()->IndexOfChild(node));
|
| - }
|
| -}
|
| -
|
| -void BookmarkBarModel::ResetDateGroupModified(BookmarkBarNode* node) {
|
| - SetDateGroupModified(node, Time());
|
| -}
|
| -
|
| -void BookmarkBarModel::FavIconLoaded(BookmarkBarNode* node) {
|
| - // Send out notification to the observer.
|
| - FOR_EACH_OBSERVER(BookmarkBarModelObserver, observers_,
|
| - BookmarkNodeFavIconLoaded(this, node));
|
| -}
|
| -
|
| -void BookmarkBarModel::RemoveNode(BookmarkBarNode* node,
|
| - std::set<GURL>* removed_urls) {
|
| - if (!loaded_ || !node || node == &root_ || node == bookmark_bar_node_ ||
|
| - node == other_node_) {
|
| - NOTREACHED();
|
| - return;
|
| - }
|
| -
|
| - if (node->GetType() == history::StarredEntry::URL) {
|
| - // NOTE: this is called in such a way that url_lock_ is already held. As
|
| - // such, this doesn't explicitly grab the lock.
|
| - NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.find(node);
|
| - DCHECK(i != nodes_ordered_by_url_set_.end());
|
| - nodes_ordered_by_url_set_.erase(i);
|
| - removed_urls->insert(node->GetURL());
|
| - }
|
| -
|
| - CancelPendingFavIconLoadRequests(node);
|
| -
|
| - // Recurse through children.
|
| - for (int i = node->GetChildCount() - 1; i >= 0; --i)
|
| - RemoveNode(node->GetChild(i), removed_urls);
|
| -}
|
| -
|
| -void BookmarkBarModel::OnBookmarkStorageLoadedBookmarks(
|
| - bool file_exists,
|
| - bool loaded_from_history) {
|
| - if (loaded_) {
|
| - NOTREACHED();
|
| - return;
|
| - }
|
| -
|
| - if (file_exists || loaded_from_history || !profile_ ||
|
| - !profile_->GetHistoryService(Profile::EXPLICIT_ACCESS)) {
|
| - // The file exists, we're loaded.
|
| - DoneLoading();
|
| -
|
| - if (loaded_from_history) {
|
| - // We were just populated from the historical file. Schedule a save so
|
| - // that the main file is up to date.
|
| - store_->ScheduleSave();
|
| - }
|
| - return;
|
| - }
|
| -
|
| - // The file doesn't exist. This means one of two things:
|
| - // 1. A clean profile.
|
| - // 2. The user is migrating from an older version where bookmarks were saved
|
| - // in history.
|
| - // We assume step 2. If history had the bookmarks, history will write the
|
| - // bookmarks to a file for us. We need to wait until history has finished
|
| - // loading before reading from that file.
|
| - HistoryService* history =
|
| - profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
|
| - if (!history->backend_loaded()) {
|
| - // The backend isn't finished loading. Wait for it.
|
| - waiting_for_history_load_ = true;
|
| - NotificationService::current()->AddObserver(
|
| - this, NOTIFY_HISTORY_LOADED, Source<Profile>(profile_));
|
| - } else {
|
| - OnHistoryDone();
|
| - }
|
| -}
|
| -
|
| -void BookmarkBarModel::OnHistoryDone() {
|
| - if (loaded_) {
|
| - NOTREACHED();
|
| - return;
|
| - }
|
| -
|
| - // If the bookmarks were stored in the db the db will have migrated them to
|
| - // a file now. Try loading from the file.
|
| - store_->LoadBookmarks(true);
|
| -}
|
| -
|
| -void BookmarkBarModel::DoneLoading() {
|
| - {
|
| - AutoLock url_lock(url_lock_);
|
| - // Update nodes_ordered_by_url_set_ from the nodes.
|
| - PopulateNodesByURL(&root_);
|
| - }
|
| -
|
| - loaded_ = true;
|
| -
|
| - if (loaded_signal_.Get())
|
| - SetEvent(loaded_signal_.Get());
|
| -
|
| -
|
| - // Notify our direct observers.
|
| - FOR_EACH_OBSERVER(BookmarkBarModelObserver, observers_, Loaded(this));
|
| -
|
| - // And generic notification.
|
| - NotificationService::current()->Notify(
|
| - NOTIFY_BOOKMARK_MODEL_LOADED,
|
| - Source<Profile>(profile_),
|
| - NotificationService::NoDetails());
|
| -}
|
| -
|
| -void BookmarkBarModel::RemoveAndDeleteNode(BookmarkBarNode* delete_me) {
|
| - scoped_ptr<BookmarkBarNode> node(delete_me);
|
| -
|
| - BookmarkBarNode* parent = node->GetParent();
|
| - DCHECK(parent);
|
| - int index = parent->IndexOfChild(node.get());
|
| - parent->Remove(index);
|
| - history::URLsStarredDetails details(false);
|
| - {
|
| - AutoLock url_lock(url_lock_);
|
| - RemoveNode(node.get(), &details.changed_urls);
|
| - }
|
| -
|
| - if (store_.get())
|
| - store_->ScheduleSave();
|
| -
|
| - FOR_EACH_OBSERVER(BookmarkBarModelObserver, observers_,
|
| - BookmarkNodeRemoved(this, parent, index));
|
| -
|
| - if (profile_) {
|
| - HistoryService* history =
|
| - profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
|
| - if (history)
|
| - history->URLsNoLongerBookmarked(details.changed_urls);
|
| - }
|
| -
|
| - NotificationService::current()->Notify(NOTIFY_URLS_STARRED,
|
| - Source<Profile>(profile_),
|
| - Details<history::URLsStarredDetails>(&details));
|
| -}
|
| -
|
| -BookmarkBarNode* BookmarkBarModel::AddNode(BookmarkBarNode* parent,
|
| - int index,
|
| - BookmarkBarNode* node) {
|
| - parent->Add(index, node);
|
| -
|
| - if (store_.get())
|
| - store_->ScheduleSave();
|
| -
|
| - FOR_EACH_OBSERVER(BookmarkBarModelObserver, observers_,
|
| - BookmarkNodeAdded(this, parent, index));
|
| -
|
| - if (node->GetType() == history::StarredEntry::URL) {
|
| - history::URLsStarredDetails details(true);
|
| - details.changed_urls.insert(node->GetURL());
|
| - NotificationService::current()->Notify(NOTIFY_URLS_STARRED,
|
| - Source<Profile>(profile_),
|
| - Details<history::URLsStarredDetails>(&details));
|
| - }
|
| - return node;
|
| -}
|
| -
|
| -void BookmarkBarModel::BlockTillLoaded() {
|
| - if (loaded_signal_.Get())
|
| - WaitForSingleObject(loaded_signal_.Get(), INFINITE);
|
| -}
|
| -
|
| -BookmarkBarNode* BookmarkBarModel::GetNodeByID(BookmarkBarNode* node,
|
| - int id) {
|
| - if (node->id() == id)
|
| - return node;
|
| -
|
| - for (int i = 0; i < node->GetChildCount(); ++i) {
|
| - BookmarkBarNode* result = GetNodeByID(node->GetChild(i), id);
|
| - if (result)
|
| - return result;
|
| - }
|
| - return NULL;
|
| -}
|
| -
|
| -bool BookmarkBarModel::IsValidIndex(BookmarkBarNode* parent,
|
| - int index,
|
| - bool allow_end) {
|
| - return (parent &&
|
| - (index >= 0 && (index < parent->GetChildCount() ||
|
| - (allow_end && index == parent->GetChildCount()))));
|
| - }
|
| -
|
| -void BookmarkBarModel::SetDateGroupModified(BookmarkBarNode* parent,
|
| - const Time time) {
|
| - DCHECK(parent);
|
| - parent->date_group_modified_ = time;
|
| -
|
| - if (store_.get())
|
| - store_->ScheduleSave();
|
| -}
|
| -
|
| -void BookmarkBarModel::CreateBookmarkBarNode() {
|
| - history::StarredEntry entry;
|
| - entry.type = history::StarredEntry::BOOKMARK_BAR;
|
| - bookmark_bar_node_ = CreateRootNodeFromStarredEntry(entry);
|
| -}
|
| -
|
| -void BookmarkBarModel::CreateOtherBookmarksNode() {
|
| - history::StarredEntry entry;
|
| - entry.type = history::StarredEntry::OTHER;
|
| - other_node_ = CreateRootNodeFromStarredEntry(entry);
|
| -}
|
| -
|
| -BookmarkBarNode* BookmarkBarModel::CreateRootNodeFromStarredEntry(
|
| - const history::StarredEntry& entry) {
|
| - DCHECK(entry.type == history::StarredEntry::BOOKMARK_BAR ||
|
| - entry.type == history::StarredEntry::OTHER);
|
| - BookmarkBarNode* node = new BookmarkBarNode(this, GURL());
|
| - node->Reset(entry);
|
| - if (entry.type == history::StarredEntry::BOOKMARK_BAR)
|
| - node->SetTitle(l10n_util::GetString(IDS_BOOMARK_BAR_FOLDER_NAME));
|
| - else
|
| - node->SetTitle(l10n_util::GetString(IDS_BOOMARK_BAR_OTHER_FOLDER_NAME));
|
| - return node;
|
| -}
|
| -
|
| -void BookmarkBarModel::OnFavIconDataAvailable(
|
| - HistoryService::Handle handle,
|
| - bool know_favicon,
|
| - scoped_refptr<RefCountedBytes> data,
|
| - bool expired,
|
| - GURL icon_url) {
|
| - SkBitmap fav_icon;
|
| - BookmarkBarNode* node =
|
| - load_consumer_.GetClientData(
|
| - profile_->GetHistoryService(Profile::EXPLICIT_ACCESS), handle);
|
| - DCHECK(node);
|
| - node->favicon_load_handle_ = 0;
|
| - if (know_favicon && data.get() &&
|
| - PNGDecoder::Decode(&data->data, &fav_icon)) {
|
| - node->favicon_ = fav_icon;
|
| - FavIconLoaded(node);
|
| - }
|
| -}
|
| -
|
| -void BookmarkBarModel::LoadFavIcon(BookmarkBarNode* node) {
|
| - if (node->GetType() != history::StarredEntry::URL)
|
| - return;
|
| -
|
| - DCHECK(node->GetURL().is_valid());
|
| - HistoryService* history_service =
|
| - profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
|
| - if (!history_service)
|
| - return;
|
| -
|
| - HistoryService::Handle handle = history_service->GetFavIconForURL(
|
| - node->GetURL(), &load_consumer_,
|
| - NewCallback(this, &BookmarkBarModel::OnFavIconDataAvailable));
|
| - load_consumer_.SetClientData(history_service, handle, node);
|
| - node->favicon_load_handle_ = handle;
|
| -}
|
| -
|
| -void BookmarkBarModel::CancelPendingFavIconLoadRequests(BookmarkBarNode* node) {
|
| - if (node->favicon_load_handle_) {
|
| - HistoryService* history =
|
| - profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
|
| - if (history)
|
| - history->CancelRequest(node->favicon_load_handle_);
|
| - node->favicon_load_handle_ = 0;
|
| - }
|
| -}
|
| -
|
| -void BookmarkBarModel::GetMostRecentlyModifiedGroupNodes(
|
| - BookmarkBarNode* parent,
|
| - size_t count,
|
| - std::vector<BookmarkBarNode*>* nodes) {
|
| - if (parent != &root_ && parent->is_folder() &&
|
| - parent->date_group_modified() > Time()) {
|
| - if (count == 0) {
|
| - nodes->push_back(parent);
|
| - } else {
|
| - std::vector<BookmarkBarNode*>::iterator i =
|
| - std::upper_bound(nodes->begin(), nodes->end(), parent,
|
| - &MoreRecentlyModified);
|
| - if (nodes->size() < count || i != nodes->end()) {
|
| - nodes->insert(i, parent);
|
| - while (nodes->size() > count)
|
| - nodes->pop_back();
|
| - }
|
| - }
|
| - } // else case, the root node, which we don't care about or imported nodes
|
| - // (which have a time of 0).
|
| - for (int i = 0; i < parent->GetChildCount(); ++i) {
|
| - BookmarkBarNode* child = parent->GetChild(i);
|
| - if (child->is_folder())
|
| - GetMostRecentlyModifiedGroupNodes(child, count, nodes);
|
| - }
|
| -}
|
| -
|
| -void BookmarkBarModel::Observe(NotificationType type,
|
| - const NotificationSource& source,
|
| - const NotificationDetails& details) {
|
| - switch (type) {
|
| - case NOTIFY_FAVICON_CHANGED: {
|
| - // Prevent the observers from getting confused for multiple favicon loads.
|
| - Details<history::FavIconChangeDetails> favicon_details(details);
|
| - for (std::set<GURL>::const_iterator i = favicon_details->urls.begin();
|
| - i != favicon_details->urls.end(); ++i) {
|
| - BookmarkBarNode* node = GetNodeByURL(*i);
|
| - if (node) {
|
| - // Got an updated favicon, for a URL, do a new request.
|
| - node->InvalidateFavicon();
|
| - CancelPendingFavIconLoadRequests(node);
|
| - FOR_EACH_OBSERVER(BookmarkBarModelObserver, observers_,
|
| - BookmarkNodeChanged(this, node));
|
| - }
|
| - }
|
| - break;
|
| - }
|
| -
|
| - case NOTIFY_HISTORY_LOADED: {
|
| - if (waiting_for_history_load_) {
|
| - waiting_for_history_load_ = false;
|
| - NotificationService::current()->RemoveObserver(
|
| - this, NOTIFY_HISTORY_LOADED, Source<Profile>(profile_));
|
| - OnHistoryDone();
|
| - } else {
|
| - NOTREACHED();
|
| - }
|
| - break;
|
| - }
|
| -
|
| - default:
|
| - NOTREACHED();
|
| - break;
|
| - }
|
| -}
|
| -
|
| -void BookmarkBarModel::PopulateNodesByURL(BookmarkBarNode* node) {
|
| - // NOTE: this is called with url_lock_ already held. As such, this doesn't
|
| - // explicitly grab the lock.
|
| - if (node->is_url())
|
| - nodes_ordered_by_url_set_.insert(node);
|
| - for (int i = 0; i < node->GetChildCount(); ++i)
|
| - PopulateNodesByURL(node->GetChild(i));
|
| -}
|
|
|