1 // Copyright (c) 2012 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 "chrome/browser/ui/bookmarks/recently_used_folders_combo_model.h"
7 #include "chrome/browser/bookmarks/bookmark_model.h"
8 #include "chrome/browser/bookmarks/bookmark_utils.h"
9 #include "content/public/browser/user_metrics.h"
10 #include "grit/generated_resources.h"
11 #include "ui/base/l10n/l10n_util.h"
15 // Max number of most recently used folders.
16 const size_t kMaxMRUFolders
= 5;
20 struct RecentlyUsedFoldersComboModel::Item
{
24 TYPE_CHOOSE_ANOTHER_FOLDER
27 Item(const BookmarkNode
* node
, Type type
);
30 bool operator==(const Item
& item
) const;
32 const BookmarkNode
* node
;
36 RecentlyUsedFoldersComboModel::Item::Item(const BookmarkNode
* node
,
42 RecentlyUsedFoldersComboModel::Item::~Item() {}
44 bool RecentlyUsedFoldersComboModel::Item::operator==(const Item
& item
) const {
45 return item
.node
== node
&& item
.type
== type
;
48 RecentlyUsedFoldersComboModel::RecentlyUsedFoldersComboModel(
50 const BookmarkNode
* node
)
51 : bookmark_model_(model
),
52 node_parent_index_(0) {
53 // Use + 2 to account for bookmark bar and other node.
54 std::vector
<const BookmarkNode
*> nodes
=
55 bookmark_utils::GetMostRecentlyModifiedFolders(model
, kMaxMRUFolders
+ 2);
57 for (size_t i
= 0; i
< nodes
.size(); ++i
)
58 items_
.push_back(Item(nodes
[i
], Item::TYPE_NODE
));
60 // We special case the placement of these, so remove them from the list, then
62 RemoveNode(model
->bookmark_bar_node());
63 RemoveNode(model
->mobile_node());
64 RemoveNode(model
->other_node());
65 RemoveNode(node
->parent());
67 // Make the parent the first item, unless it's a permanent node, which is
69 if (!model
->is_permanent_node(node
->parent()))
70 items_
.insert(items_
.begin(), Item(node
->parent(), Item::TYPE_NODE
));
72 // Make sure we only have kMaxMRUFolders in the first chunk.
73 if (items_
.size() > kMaxMRUFolders
)
74 items_
.erase(items_
.begin() + kMaxMRUFolders
, items_
.end());
76 // And put the bookmark bar and other nodes at the end of the list.
77 items_
.push_back(Item(model
->bookmark_bar_node(), Item::TYPE_NODE
));
78 items_
.push_back(Item(model
->other_node(), Item::TYPE_NODE
));
79 if (model
->mobile_node()->IsVisible())
80 items_
.push_back(Item(model
->mobile_node(), Item::TYPE_NODE
));
81 #if defined(USE_AURA) || defined(TOOLKIT_GTK)
82 items_
.push_back(Item(NULL
, Item::TYPE_SEPARATOR
));
84 items_
.push_back(Item(NULL
, Item::TYPE_CHOOSE_ANOTHER_FOLDER
));
86 std::vector
<Item
>::iterator it
= std::find(items_
.begin(),
90 node_parent_index_
= static_cast<int>(it
- items_
.begin());
93 RecentlyUsedFoldersComboModel::~RecentlyUsedFoldersComboModel() {}
95 int RecentlyUsedFoldersComboModel::GetItemCount() const {
96 return static_cast<int>(items_
.size());
99 string16
RecentlyUsedFoldersComboModel::GetItemAt(int index
) {
100 switch (items_
[index
].type
) {
101 case Item::TYPE_NODE
:
102 return items_
[index
].node
->GetTitle();
103 case Item::TYPE_SEPARATOR
:
104 // This function should not be called for separators.
107 case Item::TYPE_CHOOSE_ANOTHER_FOLDER
:
108 return l10n_util::GetStringUTF16(
109 IDS_BOOKMARK_BUBBLE_CHOOSER_ANOTHER_FOLDER
);
115 bool RecentlyUsedFoldersComboModel::IsItemSeparatorAt(int index
) {
116 return items_
[index
].type
== Item::TYPE_SEPARATOR
;
119 int RecentlyUsedFoldersComboModel::GetDefaultIndex() const {
120 return node_parent_index_
;
123 void RecentlyUsedFoldersComboModel::MaybeChangeParent(
124 const BookmarkNode
* node
,
125 int selected_index
) {
126 if (items_
[selected_index
].type
!= Item::TYPE_NODE
)
129 const BookmarkNode
* new_parent
= GetNodeAt(selected_index
);
130 if (new_parent
!= node
->parent()) {
131 content::RecordAction(
132 content::UserMetricsAction("BookmarkBubble_ChangeParent"));
133 bookmark_model_
->Move(node
, new_parent
, new_parent
->child_count());
137 const BookmarkNode
* RecentlyUsedFoldersComboModel::GetNodeAt(int index
) {
138 if (index
< 0 || index
>= static_cast<int>(items_
.size()))
140 return items_
[index
].node
;
143 void RecentlyUsedFoldersComboModel::RemoveNode(const BookmarkNode
* node
) {
144 std::vector
<Item
>::iterator it
= std::find(items_
.begin(),
146 Item(node
, Item::TYPE_NODE
));
147 if (it
!= items_
.end())