bookmark_utils.cc revision 72a454cd3513ac24fbdd0e0cb9ad70b86a99b801
172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/bookmarks/bookmark_utils.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <utility> 821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/basictypes.h" 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_path.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string16.h" 1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/string_number_conversions.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/time.h" 143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/bookmarks/bookmark_model.h" 1672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/bookmarks/bookmark_node_data.h" 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_MACOSX) 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.h" 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browser_list.h" 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browser_window.h" 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/history/query_parser.h" 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/platform_util.h" 243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/prefs/pref_service.h" 2521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h" 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/tab_contents/page_navigator.h" 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/tab_contents/tab_contents.h" 284a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/ui/browser.h" 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/notification_service.h" 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/pref_names.h" 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/app_strings.h" 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/chromium_strings.h" 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h" 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_util.h" 3572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/dragdrop/drag_drop_types.h" 3672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h" 3772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/models/tree_node_iterator.h" 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(TOOLKIT_VIEWS) 4072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/dragdrop/os_exchange_data.h" 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/drag_utils.h" 4272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "views/events/event.h" 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/widget/root_view.h" 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/widget/widget.h" 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(TOOLKIT_GTK) 4672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/custom_drag.h" 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::Time; 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace { 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A PageNavigator implementation that creates a new Browser. This is used when 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// opening a url and there is no Browser open. The Browser is created the first 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// time the PageNavigator method is invoked. 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass NewBrowserPageNavigator : public PageNavigator { 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch explicit NewBrowserPageNavigator(Profile* profile) 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : profile_(profile), 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser_(NULL) {} 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ~NewBrowserPageNavigator() { 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (browser_) 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser_->window()->Show(); 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Browser* browser() const { return browser_; } 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void OpenURL(const GURL& url, 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& referrer, 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WindowOpenDisposition disposition, 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PageTransition::Type transition) { 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!browser_) { 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* profile = (disposition == OFF_THE_RECORD) ? 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_->GetOffTheRecordProfile() : profile_; 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser_ = Browser::Create(profile); 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Always open the first tab in the foreground. 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch disposition = NEW_FOREGROUND_TAB; 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser_->OpenURL(url, referrer, NEW_FOREGROUND_TAB, transition); 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* profile_; 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Browser* browser_; 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(NewBrowserPageNavigator); 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 904a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochvoid CloneBookmarkNodeImpl(BookmarkModel* model, 91201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const BookmarkNodeData::Element& element, 924a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const BookmarkNode* parent, 934a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch int index_to_add_at) { 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (element.is_url) { 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model->AddURL(parent, index_to_add_at, element.title, element.url); 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* new_folder = model->AddGroup(parent, 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch index_to_add_at, 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch element.title); 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; i < static_cast<int>(element.children.size()); ++i) 1014a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch CloneBookmarkNodeImpl(model, element.children[i], new_folder, i); 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Returns the number of descendants of node that are of type url. 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint DescendantURLCount(const BookmarkNode* node) { 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int result = 0; 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; i < node->GetChildCount(); ++i) { 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* child = node->GetChild(i); 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (child->is_url()) 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch result++; 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch result += DescendantURLCount(child); 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return result; 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Implementation of OpenAll. Opens all nodes of type URL and recurses for 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// groups. |navigator| is the PageNavigator used to open URLs. After the first 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// url is opened |opened_url| is set to true and |navigator| is set to the 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// PageNavigator of the last active tab. This is done to handle a window 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// disposition of new window, in which case we want subsequent tabs to open in 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// that window. 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid OpenAllImpl(const BookmarkNode* node, 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WindowOpenDisposition initial_disposition, 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PageNavigator** navigator, 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool* opened_url) { 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (node->is_url()) { 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WindowOpenDisposition disposition; 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (*opened_url) 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch disposition = NEW_BACKGROUND_TAB; 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch disposition = initial_disposition; 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (*navigator)->OpenURL(node->GetURL(), GURL(), disposition, 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PageTransition::AUTO_BOOKMARK); 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!*opened_url) { 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *opened_url = true; 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We opened the first URL which may have opened a new window or clobbered 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the current page, reset the navigator just to be sure. 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Browser* new_browser = BrowserList::GetLastActive(); 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (new_browser) { 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TabContents* current_tab = new_browser->GetSelectedTabContents(); 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(new_browser && current_tab); 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (new_browser && current_tab) 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *navigator = current_tab; 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } // else, new_browser == NULL, which happens during testing. 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Group, recurse through children. 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; i < node->GetChildCount(); ++i) { 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OpenAllImpl(node->GetChild(i), initial_disposition, navigator, 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch opened_url); 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ShouldOpenAll(gfx::NativeWindow parent, 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::vector<const BookmarkNode*>& nodes) { 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int descendant_count = 0; 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < nodes.size(); ++i) 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch descendant_count += DescendantURLCount(nodes[i]); 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (descendant_count < bookmark_utils::num_urls_before_prompting) 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch string16 message = l10n_util::GetStringFUTF16( 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDS_BOOKMARK_BAR_SHOULD_OPEN_ALL, 1673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::IntToString16(descendant_count)); 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch string16 title = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return platform_util::SimpleYesNoBox(parent, title, message); 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Comparison function that compares based on date modified of the two nodes. 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool MoreRecentlyModified(const BookmarkNode* n1, const BookmarkNode* n2) { 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return n1->date_group_modified() > n2->date_group_modified(); 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Returns true if |text| contains each string in |words|. This is used when 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// searching for bookmarks. 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool DoesBookmarkTextContainWords(const string16& text, 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::vector<string16>& words) { 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < words.size(); ++i) { 1823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (text.find(words[i]) == string16::npos) 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Returns true if |node|s title or url contains the strings in |words|. 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |languages| argument is user's accept-language setting to decode IDN. 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool DoesBookmarkContainWords(const BookmarkNode* node, 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::vector<string16>& words, 1923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::string& languages) { 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DoesBookmarkTextContainWords( 1953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick l10n_util::ToLower(node->GetTitle()), words) || 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DoesBookmarkTextContainWords( 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch l10n_util::ToLower(UTF8ToUTF16(node->GetURL().spec())), words) || 1983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DoesBookmarkTextContainWords(l10n_util::ToLower( 1993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::FormatUrl(node->GetURL(), languages, net::kFormatUrlOmitNothing, 2003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick UnescapeRule::NORMAL, NULL, NULL, NULL)), words); 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace bookmark_utils { 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint num_urls_before_prompting = 15; 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint PreferredDropOperation(int source_operations, int operations) { 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int common_ops = (source_operations & operations); 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!common_ops) 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 0; 21372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (ui::DragDropTypes::DRAG_COPY & common_ops) 21472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ui::DragDropTypes::DRAG_COPY; 21572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (ui::DragDropTypes::DRAG_LINK & common_ops) 21672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ui::DragDropTypes::DRAG_LINK; 21772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (ui::DragDropTypes::DRAG_MOVE & common_ops) 21872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ui::DragDropTypes::DRAG_MOVE; 21972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ui::DragDropTypes::DRAG_NONE; 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint BookmarkDragOperation(const BookmarkNode* node) { 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (node->is_url()) { 22472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_MOVE | 22572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ui::DragDropTypes::DRAG_LINK; 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 22772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_MOVE; 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 23072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#if defined(TOOLKIT_VIEWS) 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint BookmarkDropOperation(Profile* profile, 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const views::DropTargetEvent& event, 233201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const BookmarkNodeData& data, 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* parent, 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int index) { 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (data.IsFromProfile(profile) && data.size() > 1) 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Currently only accept one dragged node at a time. 23872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ui::DragDropTypes::DRAG_NONE; 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!bookmark_utils::IsValidDropLocation(profile, data, parent, index)) 24172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ui::DragDropTypes::DRAG_NONE; 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (data.GetFirstNode(profile)) { 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // User is dragging from this profile: move. 24572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ui::DragDropTypes::DRAG_MOVE; 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // User is dragging from another app, copy. 24872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return PreferredDropOperation(event.source_operations(), 24972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_LINK); 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 25172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#endif // defined(TOOLKIT_VIEWS) 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint PerformBookmarkDrop(Profile* profile, 254201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const BookmarkNodeData& data, 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* parent_node, 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int index) { 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BookmarkModel* model = profile->GetBookmarkModel(); 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (data.IsFromProfile(profile)) { 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::vector<const BookmarkNode*> dragged_nodes = 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data.GetNodes(profile); 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!dragged_nodes.empty()) { 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Drag from same profile. Move nodes. 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < dragged_nodes.size(); ++i) { 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model->Move(dragged_nodes[i], parent_node, index); 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch index = parent_node->IndexOfChild(dragged_nodes[i]) + 1; 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 26772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ui::DragDropTypes::DRAG_MOVE; 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 26972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ui::DragDropTypes::DRAG_NONE; 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Dropping a group from different profile. Always accept. 2724a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch bookmark_utils::CloneBookmarkNode(model, data.elements, parent_node, index); 27372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ui::DragDropTypes::DRAG_COPY; 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool IsValidDropLocation(Profile* profile, 277201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const BookmarkNodeData& data, 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* drop_parent, 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int index) { 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!drop_parent->is_folder()) { 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!data.is_valid()) 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (data.IsFromProfile(profile)) { 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<const BookmarkNode*> nodes = data.GetNodes(profile); 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < nodes.size(); ++i) { 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Don't allow the drop if the user is attempting to drop on one of the 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // nodes being dragged. 293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node = nodes[i]; 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int node_index = (drop_parent == node->GetParent()) ? 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch drop_parent->IndexOfChild(nodes[i]) : -1; 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (node_index != -1 && (index == node_index || index == node_index + 1)) 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // drop_parent can't accept a child that is an ancestor. 300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (drop_parent->HasAncestor(node)) 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // From the same profile, always accept. 306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3094a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochvoid CloneBookmarkNode(BookmarkModel* model, 310201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const std::vector<BookmarkNodeData::Element>& elements, 3114a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const BookmarkNode* parent, 3124a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch int index_to_add_at) { 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!parent->is_folder() || !model) { 314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < elements.size(); ++i) 3184a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch CloneBookmarkNodeImpl(model, elements[i], parent, index_to_add_at + i); 319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Bookmark dragging 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid DragBookmarks(Profile* profile, 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::vector<const BookmarkNode*>& nodes, 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::NativeView view) { 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!nodes.empty()); 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(TOOLKIT_VIEWS) 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Set up our OLE machinery 33072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ui::OSExchangeData data; 331201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch BookmarkNodeData drag_data(nodes); 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch drag_data.Write(profile, &data); 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch views::RootView* root_view = 335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch views::Widget::GetWidgetFromNativeView(view)->GetRootView(); 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Allow nested message loop so we get DnD events as we drag this around. 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool was_nested = MessageLoop::current()->IsNested(); 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->SetNestableTasksAllowed(true); 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch root_view->StartDragForViewFromMouseEvent(NULL, data, 34272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_MOVE | 34372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ui::DragDropTypes::DRAG_LINK); 344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->SetNestableTasksAllowed(was_nested); 346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_MACOSX) 347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Allow nested message loop so we get DnD events as we drag this around. 348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool was_nested = MessageLoop::current()->IsNested(); 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->SetNestableTasksAllowed(true); 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bookmark_pasteboard_helper_mac::StartDrag(profile, nodes, view); 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->SetNestableTasksAllowed(was_nested); 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(TOOLKIT_GTK) 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BookmarkDrag::BeginDrag(profile, nodes); 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid OpenAll(gfx::NativeWindow parent, 358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* profile, 359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PageNavigator* navigator, 360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::vector<const BookmarkNode*>& nodes, 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WindowOpenDisposition initial_disposition) { 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!ShouldOpenAll(parent, nodes)) 363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NewBrowserPageNavigator navigator_impl(profile); 366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!navigator) { 367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Browser* browser = 368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BrowserList::FindBrowserWithType(profile, Browser::TYPE_NORMAL, false); 369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!browser || !browser->GetSelectedTabContents()) { 370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch navigator = &navigator_impl; 371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (initial_disposition != NEW_WINDOW && 373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch initial_disposition != OFF_THE_RECORD) { 374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser->window()->Activate(); 375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch navigator = browser->GetSelectedTabContents(); 377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool opened_url = false; 381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < nodes.size(); ++i) 382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OpenAllImpl(nodes[i], initial_disposition, &navigator, &opened_url); 383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid OpenAll(gfx::NativeWindow parent, 386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* profile, 387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PageNavigator* navigator, 388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node, 389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WindowOpenDisposition initial_disposition) { 390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<const BookmarkNode*> nodes; 391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes.push_back(node); 392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OpenAll(parent, profile, navigator, nodes, initial_disposition); 393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CopyToClipboard(BookmarkModel* model, 396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::vector<const BookmarkNode*>& nodes, 397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool remove_nodes) { 398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (nodes.empty()) 399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 401201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch BookmarkNodeData(nodes).WriteToClipboard(NULL); 402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (remove_nodes) { 404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < nodes.size(); ++i) { 405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model->Remove(nodes[i]->GetParent(), 406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes[i]->GetParent()->IndexOfChild(nodes[i])); 407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid PasteFromClipboard(BookmarkModel* model, 412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* parent, 413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int index) { 414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!parent) 415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 417201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch BookmarkNodeData bookmark_data; 418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!bookmark_data.ReadFromClipboard()) 419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (index == -1) 422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch index = parent->GetChildCount(); 4234a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch bookmark_utils::CloneBookmarkNode( 4244a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch model, bookmark_data.elements, parent, index); 425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool CanPasteFromClipboard(const BookmarkNode* node) { 428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!node) 429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 430201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return BookmarkNodeData::ClipboardContainsBookmarks(); 431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 43372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstring16 GetNameForURL(const GURL& url) { 434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (url.is_valid()) { 43572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return net::GetSuggestedFilename(url, "", "", string16()); 436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 43772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return l10n_util::GetStringUTF16(IDS_APP_UNTITLED_SHORTCUT_FILE_NAME); 438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::vector<const BookmarkNode*> GetMostRecentlyModifiedGroups( 442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BookmarkModel* model, 443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t max_count) { 444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<const BookmarkNode*> nodes; 44572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ui::TreeNodeIterator<const BookmarkNode> iterator(model->root_node()); 446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (iterator.has_next()) { 447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* parent = iterator.Next(); 448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (parent->is_folder() && parent->date_group_modified() > base::Time()) { 449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (max_count == 0) { 450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes.push_back(parent); 451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<const BookmarkNode*>::iterator i = 453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::upper_bound(nodes.begin(), nodes.end(), parent, 454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &MoreRecentlyModified); 455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (nodes.size() < max_count || i != nodes.end()) { 456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes.insert(i, parent); 457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (nodes.size() > max_count) 458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes.pop_back(); 459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } // else case, the root node, which we don't care about or imported nodes 462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // (which have a time of 0). 463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (nodes.size() < max_count) { 466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Add the bookmark bar and other nodes if there is space. 467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (find(nodes.begin(), nodes.end(), model->GetBookmarkBarNode()) == 468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes.end()) { 469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes.push_back(model->GetBookmarkBarNode()); 470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (nodes.size() < max_count && 473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch find(nodes.begin(), nodes.end(), model->other_node()) == nodes.end()) { 474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes.push_back(model->other_node()); 475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return nodes; 478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GetMostRecentlyAddedEntries(BookmarkModel* model, 481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t count, 482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<const BookmarkNode*>* nodes) { 48372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ui::TreeNodeIterator<const BookmarkNode> iterator(model->root_node()); 484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (iterator.has_next()) { 485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node = iterator.Next(); 486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (node->is_url()) { 487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<const BookmarkNode*>::iterator insert_position = 488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::upper_bound(nodes->begin(), nodes->end(), node, 489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &MoreRecentlyAdded); 490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (nodes->size() < count || insert_position != nodes->end()) { 491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes->insert(insert_position, node); 492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (nodes->size() > count) 493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes->pop_back(); 494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 49972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTitleMatch::TitleMatch() 50072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen : node(NULL) { 50172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 50272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 50372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTitleMatch::~TitleMatch() {} 50472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool MoreRecentlyAdded(const BookmarkNode* n1, const BookmarkNode* n2) { 506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return n1->date_added() > n2->date_added(); 507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GetBookmarksContainingText(BookmarkModel* model, 5103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16& text, 511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t max_count, 5123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::string& languages, 513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<const BookmarkNode*>* nodes) { 514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<string16> words; 515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch QueryParser parser; 5163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick parser.ExtractQueryWords(l10n_util::ToLower(text), &words); 517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (words.empty()) 518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 52072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ui::TreeNodeIterator<const BookmarkNode> iterator(model->root_node()); 521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (iterator.has_next()) { 522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node = iterator.Next(); 523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (node->is_url() && DoesBookmarkContainWords(node, words, languages)) { 524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes->push_back(node); 525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (nodes->size() == max_count) 526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool DoesBookmarkContainText(const BookmarkNode* node, 5323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16& text, 5333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::string& languages) { 534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<string16> words; 535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch QueryParser parser; 5363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick parser.ExtractQueryWords(l10n_util::ToLower(text), &words); 537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (words.empty()) 538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return (node->is_url() && DoesBookmarkContainWords(node, words, languages)); 541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const BookmarkNode* CreateNewNode(BookmarkModel* model, 544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* parent, const BookmarkEditor::EditDetails& details, 5453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16& new_title, const GURL& new_url) { 546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node; 547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (details.type == BookmarkEditor::EditDetails::NEW_URL) { 548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch node = model->AddURL(parent, parent->GetChildCount(), new_title, new_url); 549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (details.type == BookmarkEditor::EditDetails::NEW_FOLDER) { 550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch node = model->AddGroup(parent, parent->GetChildCount(), new_title); 551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < details.urls.size(); ++i) { 552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model->AddURL(node, node->GetChildCount(), details.urls[i].second, 553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch details.urls[i].first); 554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model->SetDateGroupModified(parent, Time::Now()); 556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return node; 562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst BookmarkNode* ApplyEditsWithNoGroupChange(BookmarkModel* model, 565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* parent, const BookmarkEditor::EditDetails& details, 5663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16& new_title, const GURL& new_url) { 567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (details.type == BookmarkEditor::EditDetails::NEW_URL || 568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch details.type == BookmarkEditor::EditDetails::NEW_FOLDER) { 569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return CreateNewNode(model, parent, details, new_title, new_url); 570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node = details.existing_node; 573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(node); 574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (node->is_url()) 576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model->SetURL(node, new_url); 577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model->SetTitle(node, new_title); 578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return node; 580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst BookmarkNode* ApplyEditsWithPossibleGroupChange(BookmarkModel* model, 583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* new_parent, const BookmarkEditor::EditDetails& details, 5843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16& new_title, const GURL& new_url) { 585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (details.type == BookmarkEditor::EditDetails::NEW_URL || 586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch details.type == BookmarkEditor::EditDetails::NEW_FOLDER) { 587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return CreateNewNode(model, new_parent, details, new_title, new_url); 588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node = details.existing_node; 591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(node); 592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (new_parent != node->GetParent()) 594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model->Move(node, new_parent, new_parent->GetChildCount()); 595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (node->is_url()) 596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model->SetURL(node, new_url); 597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model->SetTitle(node, new_title); 598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return node; 600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Formerly in BookmarkBarView 603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ToggleWhenVisible(Profile* profile) { 604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PrefService* prefs = profile->GetPrefs(); 605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const bool always_show = !prefs->GetBoolean(prefs::kShowBookmarkBar); 606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The user changed when the bookmark bar is shown, update the preferences. 608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs->SetBoolean(prefs::kShowBookmarkBar, always_show); 609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs->ScheduleSavePersistentPrefs(); 610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // And notify the notification service. 612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Source<Profile> source(profile); 613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationService::current()->Notify( 614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationType::BOOKMARK_BAR_VISIBILITY_PREF_CHANGED, 615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch source, 616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationService::NoDetails()); 617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RegisterUserPrefs(PrefService* prefs) { 620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs->RegisterBooleanPref(prefs::kShowBookmarkBar, false); 621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GetURLAndTitleToBookmark(TabContents* tab_contents, 624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL* url, 6253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick string16* title) { 626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *url = tab_contents->GetURL(); 6273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick *title = tab_contents->GetTitle(); 628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GetURLsForOpenTabs(Browser* browser, 6313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::vector<std::pair<GURL, string16> >* urls) { 632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; i < browser->tab_count(); ++i) { 6333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::pair<GURL, string16> entry; 634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GetURLAndTitleToBookmark(browser->GetTabContentsAt(i), &(entry.first), 635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &(entry.second)); 636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch urls->push_back(entry); 637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst BookmarkNode* GetParentForNewNodes( 641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* parent, 642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::vector<const BookmarkNode*>& selection, 643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int* index) { 644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* real_parent = parent; 645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (selection.size() == 1 && selection[0]->is_folder()) 647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch real_parent = selection[0]; 648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (index) { 650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (selection.size() == 1 && selection[0]->is_url()) { 651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *index = real_parent->IndexOfChild(selection[0]) + 1; 652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (*index == 0) { 653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Node doesn't exist in parent, add to end. 654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *index = real_parent->GetChildCount(); 656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *index = real_parent->GetChildCount(); 659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return real_parent; 663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 665201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochbool NodeHasURLs(const BookmarkNode* node) { 666201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DCHECK(node); 667201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 668201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (node->is_url()) 669201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return true; 670201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 671201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch for (int i = 0; i < node->GetChildCount(); ++i) { 672201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (NodeHasURLs(node->GetChild(i))) 673201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return true; 674201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 675201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return false; 676201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 677201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace bookmark_utils 679