bookmark_utils.cc revision dc0f95d653279beabeb9817299e2902918ba123e
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" 264a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/ui/browser.h" 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/notification_service.h" 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/pref_names.h" 29dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/page_navigator.h" 30dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.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" 43dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "views/widget/native_widget.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 // Allow nested message loop so we get DnD events as we drag this around. 335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool was_nested = MessageLoop::current()->IsNested(); 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->SetNestableTasksAllowed(true); 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 338dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen views::NativeWidget* native_widget = 339dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen views::NativeWidget::GetNativeWidgetForNativeView(view); 340dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (native_widget) { 341dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen native_widget->GetWidget()->RunShellDrag(NULL, data, 342dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_MOVE | 343dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ui::DragDropTypes::DRAG_LINK); 344dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->SetNestableTasksAllowed(was_nested); 347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_MACOSX) 348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Allow nested message loop so we get DnD events as we drag this around. 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool was_nested = MessageLoop::current()->IsNested(); 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->SetNestableTasksAllowed(true); 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bookmark_pasteboard_helper_mac::StartDrag(profile, nodes, view); 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->SetNestableTasksAllowed(was_nested); 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(TOOLKIT_GTK) 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BookmarkDrag::BeginDrag(profile, nodes); 355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid OpenAll(gfx::NativeWindow parent, 359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* profile, 360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PageNavigator* navigator, 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::vector<const BookmarkNode*>& nodes, 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WindowOpenDisposition initial_disposition) { 363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!ShouldOpenAll(parent, nodes)) 364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NewBrowserPageNavigator navigator_impl(profile); 367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!navigator) { 368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Browser* browser = 369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BrowserList::FindBrowserWithType(profile, Browser::TYPE_NORMAL, false); 370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!browser || !browser->GetSelectedTabContents()) { 371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch navigator = &navigator_impl; 372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (initial_disposition != NEW_WINDOW && 374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch initial_disposition != OFF_THE_RECORD) { 375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser->window()->Activate(); 376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch navigator = browser->GetSelectedTabContents(); 378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool opened_url = false; 382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < nodes.size(); ++i) 383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OpenAllImpl(nodes[i], initial_disposition, &navigator, &opened_url); 384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid OpenAll(gfx::NativeWindow parent, 387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* profile, 388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PageNavigator* navigator, 389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node, 390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WindowOpenDisposition initial_disposition) { 391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<const BookmarkNode*> nodes; 392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes.push_back(node); 393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OpenAll(parent, profile, navigator, nodes, initial_disposition); 394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CopyToClipboard(BookmarkModel* model, 397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::vector<const BookmarkNode*>& nodes, 398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool remove_nodes) { 399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (nodes.empty()) 400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 402201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch BookmarkNodeData(nodes).WriteToClipboard(NULL); 403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (remove_nodes) { 405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < nodes.size(); ++i) { 406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model->Remove(nodes[i]->GetParent(), 407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes[i]->GetParent()->IndexOfChild(nodes[i])); 408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid PasteFromClipboard(BookmarkModel* model, 413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* parent, 414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int index) { 415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!parent) 416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 418201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch BookmarkNodeData bookmark_data; 419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!bookmark_data.ReadFromClipboard()) 420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (index == -1) 423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch index = parent->GetChildCount(); 4244a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch bookmark_utils::CloneBookmarkNode( 4254a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch model, bookmark_data.elements, parent, index); 426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool CanPasteFromClipboard(const BookmarkNode* node) { 429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!node) 430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 431201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return BookmarkNodeData::ClipboardContainsBookmarks(); 432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 43472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstring16 GetNameForURL(const GURL& url) { 435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (url.is_valid()) { 43672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return net::GetSuggestedFilename(url, "", "", string16()); 437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 43872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return l10n_util::GetStringUTF16(IDS_APP_UNTITLED_SHORTCUT_FILE_NAME); 439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::vector<const BookmarkNode*> GetMostRecentlyModifiedGroups( 443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BookmarkModel* model, 444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t max_count) { 445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<const BookmarkNode*> nodes; 44672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ui::TreeNodeIterator<const BookmarkNode> iterator(model->root_node()); 447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (iterator.has_next()) { 448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* parent = iterator.Next(); 449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (parent->is_folder() && parent->date_group_modified() > base::Time()) { 450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (max_count == 0) { 451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes.push_back(parent); 452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<const BookmarkNode*>::iterator i = 454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::upper_bound(nodes.begin(), nodes.end(), parent, 455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &MoreRecentlyModified); 456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (nodes.size() < max_count || i != nodes.end()) { 457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes.insert(i, parent); 458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (nodes.size() > max_count) 459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes.pop_back(); 460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } // else case, the root node, which we don't care about or imported nodes 463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // (which have a time of 0). 464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (nodes.size() < max_count) { 467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Add the bookmark bar and other nodes if there is space. 468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (find(nodes.begin(), nodes.end(), model->GetBookmarkBarNode()) == 469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes.end()) { 470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes.push_back(model->GetBookmarkBarNode()); 471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (nodes.size() < max_count && 474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch find(nodes.begin(), nodes.end(), model->other_node()) == nodes.end()) { 475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes.push_back(model->other_node()); 476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return nodes; 479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GetMostRecentlyAddedEntries(BookmarkModel* model, 482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t count, 483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<const BookmarkNode*>* nodes) { 48472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ui::TreeNodeIterator<const BookmarkNode> iterator(model->root_node()); 485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (iterator.has_next()) { 486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node = iterator.Next(); 487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (node->is_url()) { 488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<const BookmarkNode*>::iterator insert_position = 489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::upper_bound(nodes->begin(), nodes->end(), node, 490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &MoreRecentlyAdded); 491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (nodes->size() < count || insert_position != nodes->end()) { 492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes->insert(insert_position, node); 493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (nodes->size() > count) 494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes->pop_back(); 495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 50072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTitleMatch::TitleMatch() 50172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen : node(NULL) { 50272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 50372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 50472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTitleMatch::~TitleMatch() {} 50572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool MoreRecentlyAdded(const BookmarkNode* n1, const BookmarkNode* n2) { 507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return n1->date_added() > n2->date_added(); 508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GetBookmarksContainingText(BookmarkModel* model, 5113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16& text, 512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t max_count, 5133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::string& languages, 514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<const BookmarkNode*>* nodes) { 515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<string16> words; 516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch QueryParser parser; 5173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick parser.ExtractQueryWords(l10n_util::ToLower(text), &words); 518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (words.empty()) 519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 52172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ui::TreeNodeIterator<const BookmarkNode> iterator(model->root_node()); 522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (iterator.has_next()) { 523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node = iterator.Next(); 524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (node->is_url() && DoesBookmarkContainWords(node, words, languages)) { 525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes->push_back(node); 526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (nodes->size() == max_count) 527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool DoesBookmarkContainText(const BookmarkNode* node, 5333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16& text, 5343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::string& languages) { 535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<string16> words; 536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch QueryParser parser; 5373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick parser.ExtractQueryWords(l10n_util::ToLower(text), &words); 538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (words.empty()) 539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return (node->is_url() && DoesBookmarkContainWords(node, words, languages)); 542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const BookmarkNode* CreateNewNode(BookmarkModel* model, 545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* parent, const BookmarkEditor::EditDetails& details, 5463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16& new_title, const GURL& new_url) { 547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node; 548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (details.type == BookmarkEditor::EditDetails::NEW_URL) { 549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch node = model->AddURL(parent, parent->GetChildCount(), new_title, new_url); 550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (details.type == BookmarkEditor::EditDetails::NEW_FOLDER) { 551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch node = model->AddGroup(parent, parent->GetChildCount(), new_title); 552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < details.urls.size(); ++i) { 553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model->AddURL(node, node->GetChildCount(), details.urls[i].second, 554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch details.urls[i].first); 555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model->SetDateGroupModified(parent, Time::Now()); 557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return node; 563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst BookmarkNode* ApplyEditsWithNoGroupChange(BookmarkModel* model, 566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* parent, const BookmarkEditor::EditDetails& details, 5673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16& new_title, const GURL& new_url) { 568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (details.type == BookmarkEditor::EditDetails::NEW_URL || 569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch details.type == BookmarkEditor::EditDetails::NEW_FOLDER) { 570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return CreateNewNode(model, parent, details, new_title, new_url); 571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node = details.existing_node; 574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(node); 575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (node->is_url()) 577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model->SetURL(node, new_url); 578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model->SetTitle(node, new_title); 579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return node; 581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst BookmarkNode* ApplyEditsWithPossibleGroupChange(BookmarkModel* model, 584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* new_parent, const BookmarkEditor::EditDetails& details, 5853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16& new_title, const GURL& new_url) { 586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (details.type == BookmarkEditor::EditDetails::NEW_URL || 587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch details.type == BookmarkEditor::EditDetails::NEW_FOLDER) { 588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return CreateNewNode(model, new_parent, details, new_title, new_url); 589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node = details.existing_node; 592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(node); 593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (new_parent != node->GetParent()) 595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model->Move(node, new_parent, new_parent->GetChildCount()); 596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (node->is_url()) 597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model->SetURL(node, new_url); 598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model->SetTitle(node, new_title); 599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return node; 601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Formerly in BookmarkBarView 604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ToggleWhenVisible(Profile* profile) { 605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PrefService* prefs = profile->GetPrefs(); 606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const bool always_show = !prefs->GetBoolean(prefs::kShowBookmarkBar); 607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The user changed when the bookmark bar is shown, update the preferences. 609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs->SetBoolean(prefs::kShowBookmarkBar, always_show); 610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs->ScheduleSavePersistentPrefs(); 611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // And notify the notification service. 613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Source<Profile> source(profile); 614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationService::current()->Notify( 615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationType::BOOKMARK_BAR_VISIBILITY_PREF_CHANGED, 616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch source, 617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationService::NoDetails()); 618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RegisterUserPrefs(PrefService* prefs) { 621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs->RegisterBooleanPref(prefs::kShowBookmarkBar, false); 622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GetURLAndTitleToBookmark(TabContents* tab_contents, 625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL* url, 6263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick string16* title) { 627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *url = tab_contents->GetURL(); 6283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick *title = tab_contents->GetTitle(); 629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GetURLsForOpenTabs(Browser* browser, 6323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::vector<std::pair<GURL, string16> >* urls) { 633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; i < browser->tab_count(); ++i) { 6343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::pair<GURL, string16> entry; 635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GetURLAndTitleToBookmark(browser->GetTabContentsAt(i), &(entry.first), 636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &(entry.second)); 637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch urls->push_back(entry); 638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst BookmarkNode* GetParentForNewNodes( 642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* parent, 643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::vector<const BookmarkNode*>& selection, 644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int* index) { 645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* real_parent = parent; 646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (selection.size() == 1 && selection[0]->is_folder()) 648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch real_parent = selection[0]; 649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (index) { 651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (selection.size() == 1 && selection[0]->is_url()) { 652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *index = real_parent->IndexOfChild(selection[0]) + 1; 653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (*index == 0) { 654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Node doesn't exist in parent, add to end. 655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *index = real_parent->GetChildCount(); 657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *index = real_parent->GetChildCount(); 660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return real_parent; 664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 666201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochbool NodeHasURLs(const BookmarkNode* node) { 667201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DCHECK(node); 668201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 669201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (node->is_url()) 670201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return true; 671201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 672201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch for (int i = 0; i < node->GetChildCount(); ++i) { 673201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (NodeHasURLs(node->GetChild(i))) 674201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return true; 675201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 676201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return false; 677201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 678201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace bookmark_utils 680