1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/enhanced_bookmarks/enhanced_bookmark_utils.h"
7 #include "base/i18n/string_compare.h"
8 #include "base/i18n/string_search.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "components/bookmarks/browser/bookmark_model.h"
11 #include "ui/base/models/tree_node_iterator.h"
13 namespace enhanced_bookmarks
{
15 std::vector
<const BookmarkNode
*> FindBookmarksWithQuery(
16 BookmarkModel
* bookmark_model
,
17 const std::string
& query
) {
18 std::vector
<const BookmarkNode
*> results
;
19 base::string16 query16
= base::UTF8ToUTF16(query
);
20 base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents
pattern16(query16
);
22 ui::TreeNodeIterator
<const BookmarkNode
> iterator(
23 bookmark_model
->root_node());
24 while (iterator
.has_next()) {
25 const BookmarkNode
* node
= iterator
.Next();
29 // Search the title for the query.
33 pattern16
.Search(node
->GetTitle(), &match_index
, &match_length
);
35 results
.push_back(node
);
40 // Comparator used to sort bookmarks. No folders are allowed.
41 class BookmarkNameComparator
: public std::binary_function
<const BookmarkNode
*,
45 explicit BookmarkNameComparator(icu::Collator
* collator
)
46 : collator_(collator
) {}
48 // Returns true if |n1| preceeds |n2|.
49 bool operator()(const BookmarkNode
* n1
, const BookmarkNode
* n2
) {
50 DCHECK(!n1
->is_folder());
51 DCHECK(!n2
->is_folder());
53 return n1
->GetTitle() < n2
->GetTitle();
54 return base::i18n::CompareString16WithCollator(
55 collator_
, n1
->GetTitle(), n2
->GetTitle()) == UCOL_LESS
;
59 icu::Collator
* collator_
;
62 void SortBookmarksByName(std::vector
<const BookmarkNode
*>& nodes
) {
63 UErrorCode error
= U_ZERO_ERROR
;
64 scoped_ptr
<icu::Collator
> collator(icu::Collator::createInstance(error
));
67 std::sort(nodes
.begin(), nodes
.end(), BookmarkNameComparator(collator
.get()));
70 std::vector
<const BookmarkNode
*> PrimaryPermanentNodes(BookmarkModel
* model
) {
71 DCHECK(model
->loaded());
72 std::vector
<const BookmarkNode
*> nodes
;
73 nodes
.push_back(model
->other_node());
74 nodes
.push_back(model
->mobile_node());
78 std::vector
<const BookmarkNode
*> RootLevelFolders(BookmarkModel
* model
) {
79 std::vector
<const BookmarkNode
*> root_level_folders
;
81 // Find the direct folder children of the primary permanent nodes.
82 std::vector
<const BookmarkNode
*> primary_permanent_nodes
=
83 PrimaryPermanentNodes(model
);
84 for (const BookmarkNode
* parent
: primary_permanent_nodes
) {
85 int child_count
= parent
->child_count();
86 for (int i
= 0; i
< child_count
; ++i
) {
87 const BookmarkNode
* node
= parent
->GetChild(i
);
88 if (node
->is_folder() && node
->IsVisible())
89 root_level_folders
.push_back(node
);
93 // Add the bookmark bar if it has children.
94 const BookmarkNode
* bb_node
= model
->bookmark_bar_node();
95 if (bb_node
->child_count() > 0)
96 root_level_folders
.push_back(bb_node
);
98 return root_level_folders
;
101 bool IsPrimaryPermanentNode(const BookmarkNode
* node
, BookmarkModel
* model
) {
102 std::vector
<const BookmarkNode
*> primary_nodes(PrimaryPermanentNodes(model
));
103 if (std::find(primary_nodes
.begin(), primary_nodes
.end(), node
) !=
104 primary_nodes
.end()) {
110 const BookmarkNode
* RootLevelFolderForNode(const BookmarkNode
* node
,
111 BookmarkModel
* model
) {
112 // This helper function doesn't work for managed bookmarks. This checks that
113 // |node| is editable by the user, which currently covers all the other
114 // bookmarks except the managed bookmarks.
115 DCHECK(model
->client()->CanBeEditedByUser(node
));
117 const std::vector
<const BookmarkNode
*> root_folders(RootLevelFolders(model
));
118 const BookmarkNode
* top
= node
;
120 std::find(root_folders
.begin(), root_folders
.end(), top
) ==
121 root_folders
.end()) {
127 } // namespace enhanced_bookmarks