OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/bookmarks/browser/bookmark_utils.h" | 5 #include "components/bookmarks/browser/bookmark_utils.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
11 #include "base/i18n/case_conversion.h" | 11 #include "base/i18n/case_conversion.h" |
12 #include "base/i18n/string_search.h" | 12 #include "base/i18n/string_search.h" |
13 #include "base/metrics/user_metrics_action.h" | 13 #include "base/metrics/user_metrics_action.h" |
14 #include "base/prefs/pref_service.h" | 14 #include "base/prefs/pref_service.h" |
15 #include "base/strings/utf_string_conversions.h" | 15 #include "base/strings/utf_string_conversions.h" |
16 #include "base/time/time.h" | 16 #include "base/time/time.h" |
17 #include "components/bookmarks/browser/bookmark_client.h" | |
18 #include "components/bookmarks/browser/bookmark_model.h" | 17 #include "components/bookmarks/browser/bookmark_model.h" |
19 #include "components/bookmarks/browser/scoped_group_bookmark_actions.h" | 18 #include "components/bookmarks/browser/scoped_group_bookmark_actions.h" |
20 #include "components/bookmarks/common/bookmark_pref_names.h" | 19 #include "components/bookmarks/common/bookmark_pref_names.h" |
21 #include "components/pref_registry/pref_registry_syncable.h" | 20 #include "components/pref_registry/pref_registry_syncable.h" |
22 #include "components/query_parser/query_parser.h" | 21 #include "components/query_parser/query_parser.h" |
23 #include "net/base/net_util.h" | 22 #include "net/base/net_util.h" |
24 #include "ui/base/models/tree_node_iterator.h" | 23 #include "ui/base/models/tree_node_iterator.h" |
25 #include "url/gurl.h" | 24 #include "url/gurl.h" |
26 | 25 |
27 using base::Time; | 26 using base::Time; |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
197 BookmarkNodeData bookmark_data; | 196 BookmarkNodeData bookmark_data; |
198 if (!bookmark_data.ReadFromClipboard(ui::CLIPBOARD_TYPE_COPY_PASTE)) | 197 if (!bookmark_data.ReadFromClipboard(ui::CLIPBOARD_TYPE_COPY_PASTE)) |
199 return; | 198 return; |
200 | 199 |
201 if (index == -1) | 200 if (index == -1) |
202 index = parent->child_count(); | 201 index = parent->child_count(); |
203 bookmarks::ScopedGroupBookmarkActions group_paste(model); | 202 bookmarks::ScopedGroupBookmarkActions group_paste(model); |
204 CloneBookmarkNode(model, bookmark_data.elements, parent, index, true); | 203 CloneBookmarkNode(model, bookmark_data.elements, parent, index, true); |
205 } | 204 } |
206 | 205 |
207 bool CanPasteFromClipboard(BookmarkModel* model, const BookmarkNode* node) { | 206 bool CanPasteFromClipboard(const BookmarkNode* node) { |
208 if (!node || !model->client()->CanBeEditedByUser(node)) | 207 if (!node) |
209 return false; | 208 return false; |
210 return BookmarkNodeData::ClipboardContainsBookmarks(); | 209 return BookmarkNodeData::ClipboardContainsBookmarks(); |
211 } | 210 } |
212 | 211 |
213 std::vector<const BookmarkNode*> GetMostRecentlyModifiedUserFolders( | 212 std::vector<const BookmarkNode*> GetMostRecentlyModifiedFolders( |
214 BookmarkModel* model, | 213 BookmarkModel* model, |
215 size_t max_count) { | 214 size_t max_count) { |
216 std::vector<const BookmarkNode*> nodes; | 215 std::vector<const BookmarkNode*> nodes; |
217 ui::TreeNodeIterator<const BookmarkNode> iterator(model->root_node(), | 216 ui::TreeNodeIterator<const BookmarkNode> iterator(model->root_node(), |
218 PruneInvisibleFolders); | 217 PruneInvisibleFolders); |
219 | 218 |
220 while (iterator.has_next()) { | 219 while (iterator.has_next()) { |
221 const BookmarkNode* parent = iterator.Next(); | 220 const BookmarkNode* parent = iterator.Next(); |
222 if (!model->client()->CanBeEditedByUser(parent)) | |
223 continue; | |
224 if (parent->is_folder() && parent->date_folder_modified() > Time()) { | 221 if (parent->is_folder() && parent->date_folder_modified() > Time()) { |
225 if (max_count == 0) { | 222 if (max_count == 0) { |
226 nodes.push_back(parent); | 223 nodes.push_back(parent); |
227 } else { | 224 } else { |
228 std::vector<const BookmarkNode*>::iterator i = | 225 std::vector<const BookmarkNode*>::iterator i = |
229 std::upper_bound(nodes.begin(), nodes.end(), parent, | 226 std::upper_bound(nodes.begin(), nodes.end(), parent, |
230 &MoreRecentlyModified); | 227 &MoreRecentlyModified); |
231 if (nodes.size() < max_count || i != nodes.end()) { | 228 if (nodes.size() < max_count || i != nodes.end()) { |
232 nodes.insert(i, parent); | 229 nodes.insert(i, parent); |
233 while (nodes.size() > max_count) | 230 while (nodes.size() > max_count) |
234 nodes.pop_back(); | 231 nodes.pop_back(); |
235 } | 232 } |
236 } | 233 } |
237 } // else case, the root node, which we don't care about or imported nodes | 234 } // else case, the root node, which we don't care about or imported nodes |
238 // (which have a time of 0). | 235 // (which have a time of 0). |
239 } | 236 } |
240 | 237 |
241 if (nodes.size() < max_count) { | 238 if (nodes.size() < max_count) { |
242 // Add the permanent nodes if there is space. The permanent nodes are the | 239 // Add the permanent nodes if there is space. The permanent nodes are the |
243 // only children of the root_node. | 240 // only children of the root_node. |
244 const BookmarkNode* root_node = model->root_node(); | 241 const BookmarkNode* root_node = model->root_node(); |
245 | 242 |
246 for (int i = 0; i < root_node->child_count(); ++i) { | 243 for (int i = 0; i < root_node->child_count(); ++i) { |
247 const BookmarkNode* node = root_node->GetChild(i); | 244 const BookmarkNode* node = root_node->GetChild(i); |
248 if (node->IsVisible() && model->client()->CanBeEditedByUser(node) && | 245 if (node->IsVisible() && |
249 std::find(nodes.begin(), nodes.end(), node) == nodes.end()) { | 246 std::find(nodes.begin(), nodes.end(), node) == nodes.end()) { |
250 nodes.push_back(node); | 247 nodes.push_back(node); |
251 | 248 |
252 if (nodes.size() == max_count) | 249 if (nodes.size() == max_count) |
253 break; | 250 break; |
254 } | 251 } |
255 } | 252 } |
256 } | 253 } |
257 return nodes; | 254 return nodes; |
258 } | 255 } |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 if (!node) | 369 if (!node) |
373 continue; | 370 continue; |
374 const BookmarkNode* parent = node->parent(); | 371 const BookmarkNode* parent = node->parent(); |
375 model->Remove(parent, parent->GetIndexOf(node)); | 372 model->Remove(parent, parent->GetIndexOf(node)); |
376 } | 373 } |
377 } | 374 } |
378 | 375 |
379 void AddIfNotBookmarked(BookmarkModel* model, | 376 void AddIfNotBookmarked(BookmarkModel* model, |
380 const GURL& url, | 377 const GURL& url, |
381 const base::string16& title) { | 378 const base::string16& title) { |
382 if (IsBookmarkedByUser(model, url)) | 379 std::vector<const BookmarkNode*> bookmarks; |
383 return; // Nothing to do, a user bookmark with that url already exists. | 380 model->GetNodesByURL(url, &bookmarks); |
| 381 if (!bookmarks.empty()) |
| 382 return; // Nothing to do, a bookmark with that url already exists. |
| 383 |
384 model->client()->RecordAction(base::UserMetricsAction("BookmarkAdded")); | 384 model->client()->RecordAction(base::UserMetricsAction("BookmarkAdded")); |
385 const BookmarkNode* parent = model->GetParentForNewNodes(); | 385 const BookmarkNode* parent = model->GetParentForNewNodes(); |
386 model->AddURL(parent, parent->child_count(), title, url); | 386 model->AddURL(parent, parent->child_count(), title, url); |
387 } | 387 } |
388 | 388 |
389 void RemoveAllBookmarks(BookmarkModel* model, const GURL& url) { | 389 void RemoveAllBookmarks(BookmarkModel* model, const GURL& url) { |
390 std::vector<const BookmarkNode*> bookmarks; | 390 std::vector<const BookmarkNode*> bookmarks; |
391 model->GetNodesByURL(url, &bookmarks); | 391 model->GetNodesByURL(url, &bookmarks); |
392 | 392 |
393 // Remove all the user bookmarks. | 393 // Remove all the bookmarks. |
394 for (size_t i = 0; i < bookmarks.size(); ++i) { | 394 for (size_t i = 0; i < bookmarks.size(); ++i) { |
395 const BookmarkNode* node = bookmarks[i]; | 395 const BookmarkNode* node = bookmarks[i]; |
396 int index = node->parent()->GetIndexOf(node); | 396 int index = node->parent()->GetIndexOf(node); |
397 if (index > -1 && model->client()->CanBeEditedByUser(node)) | 397 if (index > -1) |
398 model->Remove(node->parent(), index); | 398 model->Remove(node->parent(), index); |
399 } | 399 } |
400 } | 400 } |
401 | 401 |
402 base::string16 CleanUpUrlForMatching( | 402 base::string16 CleanUpUrlForMatching( |
403 const GURL& gurl, | 403 const GURL& gurl, |
404 const std::string& languages, | 404 const std::string& languages, |
405 base::OffsetAdjuster::Adjustments* adjustments) { | 405 base::OffsetAdjuster::Adjustments* adjustments) { |
406 base::OffsetAdjuster::Adjustments tmp_adjustments; | 406 base::OffsetAdjuster::Adjustments tmp_adjustments; |
407 return base::i18n::ToLower(net::FormatUrlWithAdjustments( | 407 return base::i18n::ToLower(net::FormatUrlWithAdjustments( |
408 GURL(TruncateUrl(gurl.spec())), languages, | 408 GURL(TruncateUrl(gurl.spec())), languages, |
409 net::kFormatUrlOmitUsernamePassword, | 409 net::kFormatUrlOmitUsernamePassword, |
410 net::UnescapeRule::SPACES | net::UnescapeRule::URL_SPECIAL_CHARS, | 410 net::UnescapeRule::SPACES | net::UnescapeRule::URL_SPECIAL_CHARS, |
411 NULL, NULL, adjustments ? adjustments : &tmp_adjustments)); | 411 NULL, NULL, adjustments ? adjustments : &tmp_adjustments)); |
412 } | 412 } |
413 | 413 |
414 base::string16 CleanUpTitleForMatching(const base::string16& title) { | 414 base::string16 CleanUpTitleForMatching(const base::string16& title) { |
415 return base::i18n::ToLower(title.substr(0u, kCleanedUpTitleMaxLength)); | 415 return base::i18n::ToLower(title.substr(0u, kCleanedUpTitleMaxLength)); |
416 } | 416 } |
417 | 417 |
418 bool CanAllBeEditedByUser(BookmarkClient* client, | |
419 const std::vector<const BookmarkNode*>& nodes) { | |
420 for (size_t i = 0; i < nodes.size(); ++i) { | |
421 if (!client->CanBeEditedByUser(nodes[i])) | |
422 return false; | |
423 } | |
424 return true; | |
425 } | |
426 | |
427 bool IsBookmarkedByUser(BookmarkModel* model, const GURL& url) { | |
428 std::vector<const BookmarkNode*> nodes; | |
429 model->GetNodesByURL(url, &nodes); | |
430 for (size_t i = 0; i < nodes.size(); ++i) { | |
431 if (model->client()->CanBeEditedByUser(nodes[i])) | |
432 return true; | |
433 } | |
434 return false; | |
435 } | |
436 | |
437 } // namespace bookmark_utils | 418 } // namespace bookmark_utils |
438 | 419 |
439 const BookmarkNode* GetBookmarkNodeByID(const BookmarkModel* model, int64 id) { | 420 const BookmarkNode* GetBookmarkNodeByID(const BookmarkModel* model, int64 id) { |
440 // TODO(sky): TreeNode needs a method that visits all nodes using a predicate. | 421 // TODO(sky): TreeNode needs a method that visits all nodes using a predicate. |
441 return GetNodeByID(model->root_node(), id); | 422 return GetNodeByID(model->root_node(), id); |
442 } | 423 } |
OLD | NEW |