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#include "chrome/browser/history/query_parser.h" 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/platform_util.h" 193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/prefs/pref_service.h" 2021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h" 214a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/ui/browser.h" 22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_list.h" 23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_window.h" 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/pref_names.h" 25dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/page_navigator.h" 26dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.h" 27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_service.h" 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/app_strings.h" 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/chromium_strings.h" 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h" 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_util.h" 3272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/dragdrop/drag_drop_types.h" 3372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h" 3472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/models/tree_node_iterator.h" 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(OS_MACOSX) 37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.h" 38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif 39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(TOOLKIT_VIEWS) 4172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/dragdrop/os_exchange_data.h" 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/drag_utils.h" 4372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "views/events/event.h" 44dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "views/widget/native_widget.h" 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/widget/widget.h" 46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif 47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(TOOLKIT_GTK) 4972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/custom_drag.h" 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::Time; 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace { 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A PageNavigator implementation that creates a new Browser. This is used when 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// opening a url and there is no Browser open. The Browser is created the first 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// time the PageNavigator method is invoked. 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass NewBrowserPageNavigator : public PageNavigator { 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch explicit NewBrowserPageNavigator(Profile* profile) 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : profile_(profile), 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser_(NULL) {} 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ~NewBrowserPageNavigator() { 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (browser_) 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser_->window()->Show(); 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Browser* browser() const { return browser_; } 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void OpenURL(const GURL& url, 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& referrer, 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WindowOpenDisposition disposition, 75ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen PageTransition::Type transition) OVERRIDE { 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!browser_) { 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* profile = (disposition == OFF_THE_RECORD) ? 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_->GetOffTheRecordProfile() : profile_; 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser_ = Browser::Create(profile); 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Always open the first tab in the foreground. 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch disposition = NEW_FOREGROUND_TAB; 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser_->OpenURL(url, referrer, NEW_FOREGROUND_TAB, transition); 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* profile_; 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Browser* browser_; 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(NewBrowserPageNavigator); 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 934a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochvoid CloneBookmarkNodeImpl(BookmarkModel* model, 94201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const BookmarkNodeData::Element& element, 954a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const BookmarkNode* parent, 964a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch int index_to_add_at) { 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (element.is_url) { 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model->AddURL(parent, index_to_add_at, element.title, element.url); 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const BookmarkNode* new_folder = model->AddFolder(parent, 101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen index_to_add_at, 102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen element.title); 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; i < static_cast<int>(element.children.size()); ++i) 1044a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch CloneBookmarkNodeImpl(model, element.children[i], new_folder, i); 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Returns the number of children of |node| that are of type url. 109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenint ChildURLCount(const BookmarkNode* node) { 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int result = 0; 111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (int i = 0; i < node->child_count(); ++i) { 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* child = node->GetChild(i); 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (child->is_url()) 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch result++; 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return result; 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Implementation of OpenAll. Opens all nodes of type URL and any children of 120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// |node| that are of type URL. |navigator| is the PageNavigator used to open 121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// URLs. After the first url is opened |opened_url| is set to true and 122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// |navigator| is set to the PageNavigator of the last active tab. This is done 123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// to handle a window disposition of new window, in which case we want 124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// subsequent tabs to open in that window. 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid OpenAllImpl(const BookmarkNode* node, 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WindowOpenDisposition initial_disposition, 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PageNavigator** navigator, 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool* opened_url) { 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (node->is_url()) { 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WindowOpenDisposition disposition; 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (*opened_url) 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch disposition = NEW_BACKGROUND_TAB; 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch disposition = initial_disposition; 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (*navigator)->OpenURL(node->GetURL(), GURL(), disposition, 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PageTransition::AUTO_BOOKMARK); 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!*opened_url) { 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *opened_url = true; 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We opened the first URL which may have opened a new window or clobbered 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the current page, reset the navigator just to be sure. 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Browser* new_browser = BrowserList::GetLastActive(); 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (new_browser) { 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TabContents* current_tab = new_browser->GetSelectedTabContents(); 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(new_browser && current_tab); 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (new_browser && current_tab) 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *navigator = current_tab; 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } // else, new_browser == NULL, which happens during testing. 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // For folders only open direct children. 151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (int i = 0; i < node->child_count(); ++i) { 152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const BookmarkNode* child_node = node->GetChild(i); 153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (child_node->is_url()) 154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen OpenAllImpl(child_node, initial_disposition, navigator, opened_url); 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ShouldOpenAll(gfx::NativeWindow parent, 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::vector<const BookmarkNode*>& nodes) { 161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int child_count = 0; 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < nodes.size(); ++i) 163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen child_count += ChildURLCount(nodes[i]); 164ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (child_count < bookmark_utils::num_urls_before_prompting) 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch string16 message = l10n_util::GetStringFUTF16( 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDS_BOOKMARK_BAR_SHOULD_OPEN_ALL, 169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::IntToString16(child_count)); 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch string16 title = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return platform_util::SimpleYesNoBox(parent, title, message); 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Comparison function that compares based on date modified of the two nodes. 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool MoreRecentlyModified(const BookmarkNode* n1, const BookmarkNode* n2) { 176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return n1->date_folder_modified() > n2->date_folder_modified(); 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Returns true if |text| contains each string in |words|. This is used when 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// searching for bookmarks. 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool DoesBookmarkTextContainWords(const string16& text, 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::vector<string16>& words) { 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < words.size(); ++i) { 1843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (text.find(words[i]) == string16::npos) 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Returns true if |node|s title or url contains the strings in |words|. 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |languages| argument is user's accept-language setting to decode IDN. 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool DoesBookmarkContainWords(const BookmarkNode* node, 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::vector<string16>& words, 1943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::string& languages) { 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DoesBookmarkTextContainWords( 1973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick l10n_util::ToLower(node->GetTitle()), words) || 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DoesBookmarkTextContainWords( 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch l10n_util::ToLower(UTF8ToUTF16(node->GetURL().spec())), words) || 2003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DoesBookmarkTextContainWords(l10n_util::ToLower( 2013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::FormatUrl(node->GetURL(), languages, net::kFormatUrlOmitNothing, 2023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick UnescapeRule::NORMAL, NULL, NULL, NULL)), words); 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace bookmark_utils { 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint num_urls_before_prompting = 15; 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint PreferredDropOperation(int source_operations, int operations) { 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int common_ops = (source_operations & operations); 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!common_ops) 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 0; 21572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (ui::DragDropTypes::DRAG_COPY & common_ops) 21672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ui::DragDropTypes::DRAG_COPY; 21772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (ui::DragDropTypes::DRAG_LINK & common_ops) 21872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ui::DragDropTypes::DRAG_LINK; 21972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (ui::DragDropTypes::DRAG_MOVE & common_ops) 22072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ui::DragDropTypes::DRAG_MOVE; 22172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ui::DragDropTypes::DRAG_NONE; 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenint BookmarkDragOperation(Profile* profile, const BookmarkNode* node) { 225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int move = ui::DragDropTypes::DRAG_MOVE; 226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!profile->GetPrefs()->GetBoolean(prefs::kEditBookmarksEnabled)) 227ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen move = 0; 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (node->is_url()) { 229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_LINK | move; 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return ui::DragDropTypes::DRAG_COPY | move; 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 23472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#if defined(TOOLKIT_VIEWS) 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint BookmarkDropOperation(Profile* profile, 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const views::DropTargetEvent& event, 237201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const BookmarkNodeData& data, 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* parent, 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int index) { 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (data.IsFromProfile(profile) && data.size() > 1) 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Currently only accept one dragged node at a time. 24272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ui::DragDropTypes::DRAG_NONE; 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!bookmark_utils::IsValidDropLocation(profile, data, parent, index)) 24572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ui::DragDropTypes::DRAG_NONE; 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (data.GetFirstNode(profile)) { 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // User is dragging from this profile: move. 24972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ui::DragDropTypes::DRAG_MOVE; 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // User is dragging from another app, copy. 25272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return PreferredDropOperation(event.source_operations(), 25372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_LINK); 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 25572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#endif // defined(TOOLKIT_VIEWS) 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint PerformBookmarkDrop(Profile* profile, 258201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const BookmarkNodeData& data, 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* parent_node, 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int index) { 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BookmarkModel* model = profile->GetBookmarkModel(); 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (data.IsFromProfile(profile)) { 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::vector<const BookmarkNode*> dragged_nodes = 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data.GetNodes(profile); 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!dragged_nodes.empty()) { 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Drag from same profile. Move nodes. 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < dragged_nodes.size(); ++i) { 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model->Move(dragged_nodes[i], parent_node, index); 269ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen index = parent_node->GetIndexOf(dragged_nodes[i]) + 1; 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 27172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ui::DragDropTypes::DRAG_MOVE; 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 27372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ui::DragDropTypes::DRAG_NONE; 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 275ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Dropping a folder from different profile. Always accept. 2764a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch bookmark_utils::CloneBookmarkNode(model, data.elements, parent_node, index); 27772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ui::DragDropTypes::DRAG_COPY; 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool IsValidDropLocation(Profile* profile, 281201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const BookmarkNodeData& data, 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* drop_parent, 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int index) { 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!drop_parent->is_folder()) { 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!data.is_valid()) 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (data.IsFromProfile(profile)) { 293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<const BookmarkNode*> nodes = data.GetNodes(profile); 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < nodes.size(); ++i) { 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Don't allow the drop if the user is attempting to drop on one of the 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // nodes being dragged. 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node = nodes[i]; 298ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int node_index = (drop_parent == node->parent()) ? 299ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen drop_parent->GetIndexOf(nodes[i]) : -1; 300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (node_index != -1 && (index == node_index || index == node_index + 1)) 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // drop_parent can't accept a child that is an ancestor. 304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (drop_parent->HasAncestor(node)) 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // From the same profile, always accept. 310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3134a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochvoid CloneBookmarkNode(BookmarkModel* model, 314201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const std::vector<BookmarkNodeData::Element>& elements, 3154a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const BookmarkNode* parent, 3164a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch int index_to_add_at) { 317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!parent->is_folder() || !model) { 318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < elements.size(); ++i) 3224a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch CloneBookmarkNodeImpl(model, elements[i], parent, index_to_add_at + i); 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Bookmark dragging 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid DragBookmarks(Profile* profile, 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::vector<const BookmarkNode*>& nodes, 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::NativeView view) { 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!nodes.empty()); 331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(TOOLKIT_VIEWS) 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Set up our OLE machinery 33472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ui::OSExchangeData data; 335201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch BookmarkNodeData drag_data(nodes); 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch drag_data.Write(profile, &data); 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Allow nested message loop so we get DnD events as we drag this around. 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool was_nested = MessageLoop::current()->IsNested(); 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->SetNestableTasksAllowed(true); 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 342dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen views::NativeWidget* native_widget = 343dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen views::NativeWidget::GetNativeWidgetForNativeView(view); 344dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (native_widget) { 345dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen native_widget->GetWidget()->RunShellDrag(NULL, data, 346dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_MOVE | 347dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ui::DragDropTypes::DRAG_LINK); 348dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->SetNestableTasksAllowed(was_nested); 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_MACOSX) 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Allow nested message loop so we get DnD events as we drag this around. 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool was_nested = MessageLoop::current()->IsNested(); 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->SetNestableTasksAllowed(true); 355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bookmark_pasteboard_helper_mac::StartDrag(profile, nodes, view); 356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->SetNestableTasksAllowed(was_nested); 357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(TOOLKIT_GTK) 358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BookmarkDrag::BeginDrag(profile, nodes); 359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid OpenAll(gfx::NativeWindow parent, 363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* profile, 364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PageNavigator* navigator, 365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::vector<const BookmarkNode*>& nodes, 366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WindowOpenDisposition initial_disposition) { 367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!ShouldOpenAll(parent, nodes)) 368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NewBrowserPageNavigator navigator_impl(profile); 371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!navigator) { 372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Browser* browser = 373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BrowserList::FindBrowserWithType(profile, Browser::TYPE_NORMAL, false); 374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!browser || !browser->GetSelectedTabContents()) { 375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch navigator = &navigator_impl; 376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (initial_disposition != NEW_WINDOW && 378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch initial_disposition != OFF_THE_RECORD) { 379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser->window()->Activate(); 380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch navigator = browser->GetSelectedTabContents(); 382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool opened_url = false; 386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < nodes.size(); ++i) 387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OpenAllImpl(nodes[i], initial_disposition, &navigator, &opened_url); 388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid OpenAll(gfx::NativeWindow parent, 391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* profile, 392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PageNavigator* navigator, 393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node, 394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WindowOpenDisposition initial_disposition) { 395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<const BookmarkNode*> nodes; 396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes.push_back(node); 397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OpenAll(parent, profile, navigator, nodes, initial_disposition); 398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CopyToClipboard(BookmarkModel* model, 401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::vector<const BookmarkNode*>& nodes, 402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool remove_nodes) { 403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (nodes.empty()) 404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 406201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch BookmarkNodeData(nodes).WriteToClipboard(NULL); 407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (remove_nodes) { 409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < nodes.size(); ++i) { 410ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int index = nodes[i]->parent()->GetIndexOf(nodes[i]); 411ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (index > -1) 412ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen model->Remove(nodes[i]->parent(), index); 413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid PasteFromClipboard(BookmarkModel* model, 418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* parent, 419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int index) { 420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!parent) 421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 423201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch BookmarkNodeData bookmark_data; 424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!bookmark_data.ReadFromClipboard()) 425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (index == -1) 428ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen index = parent->child_count(); 4294a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch bookmark_utils::CloneBookmarkNode( 4304a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch model, bookmark_data.elements, parent, index); 431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool CanPasteFromClipboard(const BookmarkNode* node) { 434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!node) 435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 436201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return BookmarkNodeData::ClipboardContainsBookmarks(); 437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 43972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstring16 GetNameForURL(const GURL& url) { 440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (url.is_valid()) { 44172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return net::GetSuggestedFilename(url, "", "", string16()); 442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 44372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return l10n_util::GetStringUTF16(IDS_APP_UNTITLED_SHORTCUT_FILE_NAME); 444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 447ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstd::vector<const BookmarkNode*> GetMostRecentlyModifiedFolders( 448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BookmarkModel* model, 449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t max_count) { 450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<const BookmarkNode*> nodes; 45172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ui::TreeNodeIterator<const BookmarkNode> iterator(model->root_node()); 452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (iterator.has_next()) { 453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* parent = iterator.Next(); 454ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (parent->is_folder() && parent->date_folder_modified() > base::Time()) { 455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (max_count == 0) { 456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes.push_back(parent); 457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<const BookmarkNode*>::iterator i = 459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::upper_bound(nodes.begin(), nodes.end(), parent, 460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &MoreRecentlyModified); 461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (nodes.size() < max_count || i != nodes.end()) { 462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes.insert(i, parent); 463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (nodes.size() > max_count) 464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes.pop_back(); 465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } // else case, the root node, which we don't care about or imported nodes 468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // (which have a time of 0). 469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (nodes.size() < max_count) { 472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Add the bookmark bar and other nodes if there is space. 473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (find(nodes.begin(), nodes.end(), model->GetBookmarkBarNode()) == 474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes.end()) { 475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes.push_back(model->GetBookmarkBarNode()); 476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (nodes.size() < max_count && 479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch find(nodes.begin(), nodes.end(), model->other_node()) == nodes.end()) { 480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes.push_back(model->other_node()); 481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return nodes; 484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GetMostRecentlyAddedEntries(BookmarkModel* model, 487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t count, 488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<const BookmarkNode*>* nodes) { 48972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ui::TreeNodeIterator<const BookmarkNode> iterator(model->root_node()); 490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (iterator.has_next()) { 491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node = iterator.Next(); 492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (node->is_url()) { 493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<const BookmarkNode*>::iterator insert_position = 494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::upper_bound(nodes->begin(), nodes->end(), node, 495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &MoreRecentlyAdded); 496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (nodes->size() < count || insert_position != nodes->end()) { 497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes->insert(insert_position, node); 498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (nodes->size() > count) 499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes->pop_back(); 500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 50572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTitleMatch::TitleMatch() 50672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen : node(NULL) { 50772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 50872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 50972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTitleMatch::~TitleMatch() {} 51072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool MoreRecentlyAdded(const BookmarkNode* n1, const BookmarkNode* n2) { 512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return n1->date_added() > n2->date_added(); 513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GetBookmarksContainingText(BookmarkModel* model, 5163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16& text, 517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t max_count, 5183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::string& languages, 519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<const BookmarkNode*>* nodes) { 520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<string16> words; 521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch QueryParser parser; 5223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick parser.ExtractQueryWords(l10n_util::ToLower(text), &words); 523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (words.empty()) 524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 52672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ui::TreeNodeIterator<const BookmarkNode> iterator(model->root_node()); 527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (iterator.has_next()) { 528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node = iterator.Next(); 529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (node->is_url() && DoesBookmarkContainWords(node, words, languages)) { 530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes->push_back(node); 531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (nodes->size() == max_count) 532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool DoesBookmarkContainText(const BookmarkNode* node, 5383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16& text, 5393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::string& languages) { 540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<string16> words; 541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch QueryParser parser; 5423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick parser.ExtractQueryWords(l10n_util::ToLower(text), &words); 543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (words.empty()) 544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return (node->is_url() && DoesBookmarkContainWords(node, words, languages)); 547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const BookmarkNode* CreateNewNode(BookmarkModel* model, 550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* parent, const BookmarkEditor::EditDetails& details, 5513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16& new_title, const GURL& new_url) { 552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node; 553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (details.type == BookmarkEditor::EditDetails::NEW_URL) { 554ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen node = model->AddURL(parent, parent->child_count(), new_title, new_url); 555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (details.type == BookmarkEditor::EditDetails::NEW_FOLDER) { 556ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen node = model->AddFolder(parent, parent->child_count(), new_title); 557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < details.urls.size(); ++i) { 558ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen model->AddURL(node, node->child_count(), details.urls[i].second, 559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch details.urls[i].first); 560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 561ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen model->SetDateFolderModified(parent, Time::Now()); 562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return node; 568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 570ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst BookmarkNode* ApplyEditsWithNoFolderChange(BookmarkModel* model, 571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* parent, const BookmarkEditor::EditDetails& details, 5723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16& new_title, const GURL& new_url) { 573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (details.type == BookmarkEditor::EditDetails::NEW_URL || 574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch details.type == BookmarkEditor::EditDetails::NEW_FOLDER) { 575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return CreateNewNode(model, parent, details, new_title, new_url); 576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node = details.existing_node; 579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(node); 580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (node->is_url()) 582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model->SetURL(node, new_url); 583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model->SetTitle(node, new_title); 584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return node; 586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 588ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst BookmarkNode* ApplyEditsWithPossibleFolderChange(BookmarkModel* model, 589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* new_parent, const BookmarkEditor::EditDetails& details, 5903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16& new_title, const GURL& new_url) { 591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (details.type == BookmarkEditor::EditDetails::NEW_URL || 592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch details.type == BookmarkEditor::EditDetails::NEW_FOLDER) { 593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return CreateNewNode(model, new_parent, details, new_title, new_url); 594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node = details.existing_node; 597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(node); 598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 599ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (new_parent != node->parent()) 600ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen model->Move(node, new_parent, new_parent->child_count()); 601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (node->is_url()) 602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model->SetURL(node, new_url); 603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model->SetTitle(node, new_title); 604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return node; 606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Formerly in BookmarkBarView 609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ToggleWhenVisible(Profile* profile) { 610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PrefService* prefs = profile->GetPrefs(); 611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const bool always_show = !prefs->GetBoolean(prefs::kShowBookmarkBar); 612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The user changed when the bookmark bar is shown, update the preferences. 614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs->SetBoolean(prefs::kShowBookmarkBar, always_show); 615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs->ScheduleSavePersistentPrefs(); 616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // And notify the notification service. 618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Source<Profile> source(profile); 619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationService::current()->Notify( 620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationType::BOOKMARK_BAR_VISIBILITY_PREF_CHANGED, 621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch source, 622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationService::NoDetails()); 623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RegisterUserPrefs(PrefService* prefs) { 626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs->RegisterBooleanPref(prefs::kShowBookmarkBar, false); 627ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefs->RegisterBooleanPref(prefs::kEditBookmarksEnabled, true); 628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GetURLAndTitleToBookmark(TabContents* tab_contents, 631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL* url, 6323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick string16* title) { 633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *url = tab_contents->GetURL(); 6343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick *title = tab_contents->GetTitle(); 635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GetURLsForOpenTabs(Browser* browser, 6383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::vector<std::pair<GURL, string16> >* urls) { 639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; i < browser->tab_count(); ++i) { 6403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::pair<GURL, string16> entry; 641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GetURLAndTitleToBookmark(browser->GetTabContentsAt(i), &(entry.first), 642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &(entry.second)); 643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch urls->push_back(entry); 644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst BookmarkNode* GetParentForNewNodes( 648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* parent, 649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::vector<const BookmarkNode*>& selection, 650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int* index) { 651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* real_parent = parent; 652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (selection.size() == 1 && selection[0]->is_folder()) 654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch real_parent = selection[0]; 655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (index) { 657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (selection.size() == 1 && selection[0]->is_url()) { 658ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *index = real_parent->GetIndexOf(selection[0]) + 1; 659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (*index == 0) { 660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Node doesn't exist in parent, add to end. 661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 662ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *index = real_parent->child_count(); 663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 665ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *index = real_parent->child_count(); 666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return real_parent; 670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 672201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochbool NodeHasURLs(const BookmarkNode* node) { 673201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DCHECK(node); 674201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 675201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (node->is_url()) 676201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return true; 677201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 678ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (int i = 0; i < node->child_count(); ++i) { 679201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (NodeHasURLs(node->GetChild(i))) 680201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return true; 681201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 682201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return false; 683201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 684201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace bookmark_utils 686