diff options
author | sky@google.com <sky@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-24 01:54:26 +0000 |
---|---|---|
committer | sky@google.com <sky@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-24 01:54:26 +0000 |
commit | 9eb381798e60beac696ba13855b85691e9d22fb7 (patch) | |
tree | 9b1c83fcd7f442f06c5279b6730492d5d3fdef0d | |
parent | 4e8d907dd01011dd67fdf7661d98c7cbc663b0ff (diff) | |
download | chromium_src-9eb381798e60beac696ba13855b85691e9d22fb7.zip chromium_src-9eb381798e60beac696ba13855b85691e9d22fb7.tar.gz chromium_src-9eb381798e60beac696ba13855b85691e9d22fb7.tar.bz2 |
Refactors some of the bookmark drag and drop code into a separate
class that I can use in the bookmark manager.
BUG=674
TEST=make sure drag and drop on the bookmark bar still works,
especially when moving folders around.
Review URL: http://codereview.chromium.org/8115
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@3896 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/bookmarks/bookmark_drag_data.cc | 6 | ||||
-rw-r--r-- | chrome/browser/bookmarks/bookmark_drag_data.h | 5 | ||||
-rw-r--r-- | chrome/browser/bookmarks/bookmark_drag_utils.cc | 91 | ||||
-rw-r--r-- | chrome/browser/bookmarks/bookmark_drag_utils.h | 45 | ||||
-rw-r--r-- | chrome/browser/views/bookmark_bar_view.cc | 65 | ||||
-rw-r--r-- | chrome/browser/views/bookmark_bar_view.h | 13 |
6 files changed, 155 insertions, 70 deletions
diff --git a/chrome/browser/bookmarks/bookmark_drag_data.cc b/chrome/browser/bookmarks/bookmark_drag_data.cc index 65d3445..85911a7 100644 --- a/chrome/browser/bookmarks/bookmark_drag_data.cc +++ b/chrome/browser/bookmarks/bookmark_drag_data.cc @@ -135,7 +135,7 @@ bool BookmarkDragData::Read(const OSExchangeData& data) { std::vector<BookmarkNode*> BookmarkDragData::GetNodes(Profile* profile) const { std::vector<BookmarkNode*> nodes; - if (profile->GetPath() != profile_path_) + if (!IsFromProfile(profile)) return nodes; for (size_t i = 0; i < elements.size(); ++i) { @@ -154,3 +154,7 @@ BookmarkNode* BookmarkDragData::GetFirstNode(Profile* profile) const { std::vector<BookmarkNode*> nodes = GetNodes(profile); return nodes.size() == 1 ? nodes[0] : NULL; } + +bool BookmarkDragData::IsFromProfile(Profile* profile) const { + return (profile->GetPath() == profile_path_); +} diff --git a/chrome/browser/bookmarks/bookmark_drag_data.h b/chrome/browser/bookmarks/bookmark_drag_data.h index 10d269b..263bf8d 100644 --- a/chrome/browser/bookmarks/bookmark_drag_data.h +++ b/chrome/browser/bookmarks/bookmark_drag_data.h @@ -96,7 +96,10 @@ struct BookmarkDragData { bool has_single_url() const { return is_valid() && elements[0].is_url; } // Number of elements. - size_t size() { return elements.size(); } + size_t size() const { return elements.size(); } + + // Returns true if this data is from the specified profile. + bool IsFromProfile(Profile* profile) const; // The actual elements written to the clipboard. std::vector<Element> elements; diff --git a/chrome/browser/bookmarks/bookmark_drag_utils.cc b/chrome/browser/bookmarks/bookmark_drag_utils.cc new file mode 100644 index 0000000..863369c --- /dev/null +++ b/chrome/browser/bookmarks/bookmark_drag_utils.cc @@ -0,0 +1,91 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/bookmarks/bookmark_drag_utils.h" + +#include "chrome/browser/bookmarks/bookmark_drag_data.h" +#include "chrome/browser/bookmarks/bookmark_model.h" +#include "chrome/common/drag_drop_types.h" +#include "chrome/views/event.h" + +namespace { + +void CloneDragDataImpl(BookmarkModel* model, + const BookmarkDragData::Element& element, + BookmarkNode* parent, + int index_to_add_at) { + if (element.is_url) { + model->AddURL(parent, index_to_add_at, element.title, element.url); + } else { + BookmarkNode* new_folder = model->AddGroup(parent, index_to_add_at, + element.title); + for (int i = 0; i < static_cast<int>(element.children.size()); ++i) + CloneDragDataImpl(model, element.children[i], new_folder, i); + } +} + +} // namespace + +namespace bookmark_drag_utils { + +int PreferredDropOperation(const views::DropTargetEvent& event, + int operation) { + int common_ops = (event.GetSourceOperations() & operation); + if (!common_ops) + return 0; + if (DragDropTypes::DRAG_COPY & common_ops) + return DragDropTypes::DRAG_COPY; + if (DragDropTypes::DRAG_LINK & common_ops) + return DragDropTypes::DRAG_LINK; + if (DragDropTypes::DRAG_MOVE & common_ops) + return DragDropTypes::DRAG_MOVE; + return DragDropTypes::DRAG_NONE; +} + +bool IsValidDropLocation(Profile* profile, + const BookmarkDragData& data, + BookmarkNode* drop_parent, + int index) { + if (!drop_parent->is_folder()) { + NOTREACHED(); + return false; + } + + if (!data.is_valid()) + return false; + + if (data.IsFromProfile(profile)) { + std::vector<BookmarkNode*> nodes = data.GetNodes(profile); + for (size_t i = 0; i < nodes.size(); ++i) { + // Don't allow the drop if the user is attempting to drop on one of the + // nodes being dragged. + BookmarkNode* node = nodes[i]; + int node_index = (drop_parent == node->GetParent()) ? + drop_parent->IndexOfChild(nodes[i]) : -1; + if (node_index != -1 && (index == node_index || index == node_index + 1)) + return false; + + // drop_parent can't accept a child that is an ancestor. + if (drop_parent->HasAncestor(node)) + return false; + } + return true; + } + // From the same profile, always accept. + return true; +} + +void CloneDragData(BookmarkModel* model, + const std::vector<BookmarkDragData::Element>& elements, + BookmarkNode* parent, + int index_to_add_at) { + if (!parent->is_folder() || !model) { + NOTREACHED(); + return; + } + for (size_t i = 0; i < elements.size(); ++i) + CloneDragDataImpl(model, elements[i], parent, index_to_add_at + i); +} + +} // namespace bookmark_drag_utils diff --git a/chrome/browser/bookmarks/bookmark_drag_utils.h b/chrome/browser/bookmarks/bookmark_drag_utils.h new file mode 100644 index 0000000..2805311 --- /dev/null +++ b/chrome/browser/bookmarks/bookmark_drag_utils.h @@ -0,0 +1,45 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_BOOKMARKS_BOOKMARK_DRAG_UTILS_H_ +#define CHROME_BROWSER_BOOKMARKS_BOOKMARK_DRAG_UTILS_H_ + +#include "chrome/browser/bookmarks/bookmark_drag_data.h" + +class BookmarkNode; +class Profile; + +namespace views { +class DropTargetEvent; +} + +// Functions used in managing bookmark drag and drop. These functions are +// used by both the bookmark bar and bookmark manager. +namespace bookmark_drag_utils { + +// Calculates the drop operation given the event and supported set of +// operations. This prefers the following ordering: COPY, LINK then MOVE. +int PreferredDropOperation(const views::DropTargetEvent& event, + int operation); + +// Returns true if the bookmark data can be dropped on |drop_parent| at +// |index|. A drop from a separate profile is always allowed, where as +// a drop from the same profile is only allowed if none of the nodes in +// |data| are an ancestor of |drop_parent| and one of the nodes isn't already +// a child of |drop_parent| at |index|. +bool IsValidDropLocation(Profile* profile, + const BookmarkDragData& data, + BookmarkNode* drop_parent, + int index); + +// Clones drag data, adding newly created nodes to |parent| starting at +// |index_to_add_at|. +void CloneDragData(BookmarkModel* model, + const std::vector<BookmarkDragData::Element>& elements, + BookmarkNode* parent, + int index_to_add_at); + +} + +#endif // CHROME_BROWSER_BOOKMARKS_BOOKMARK_DRAG_UTILS_H_ diff --git a/chrome/browser/views/bookmark_bar_view.cc b/chrome/browser/views/bookmark_bar_view.cc index 457339c..28d6b98 100644 --- a/chrome/browser/views/bookmark_bar_view.cc +++ b/chrome/browser/views/bookmark_bar_view.cc @@ -10,6 +10,7 @@ #include "base/gfx/skia_utils.h" #include "chrome/app/theme/theme_resources.h" #include "chrome/browser/bookmark_bar_context_menu_controller.h" +#include "chrome/browser/bookmarks/bookmark_drag_utils.h" #include "chrome/browser/browser.h" #include "chrome/browser/browser_list.h" #include "chrome/browser/browser_process.h" @@ -148,21 +149,6 @@ static const int kOtherFolderButtonTag = 1; namespace { -// Calculates the drop operation given the event and supported set of -// operations. -int PreferredDropOperation(const DropTargetEvent& event, int operation) { - int common_ops = (event.GetSourceOperations() & operation); - if (!common_ops) - return 0; - if (DragDropTypes::DRAG_COPY & common_ops) - return DragDropTypes::DRAG_COPY; - if (DragDropTypes::DRAG_LINK & common_ops) - return DragDropTypes::DRAG_LINK; - if (DragDropTypes::DRAG_MOVE & common_ops) - return DragDropTypes::DRAG_MOVE; - return DragDropTypes::DRAG_NONE; -} - // Returns the tooltip text for the specified url and title. The returned // text is clipped to fit within the bounds of the monitor. // @@ -1666,7 +1652,7 @@ int BookmarkBarView::CalculateDropOperation(const DropTargetEvent& event, int ops = data.GetFirstNode(profile_) ? DragDropTypes::DRAG_MOVE : DragDropTypes::DRAG_COPY | DragDropTypes::DRAG_LINK; - return PreferredDropOperation(event, ops); + return bookmark_drag_utils::PreferredDropOperation(event, ops); } for (int i = 0; i < GetBookmarkButtonCount() && @@ -1743,7 +1729,11 @@ int BookmarkBarView::CalculateDropOperation(const DropTargetEvent& event, const BookmarkDragData& data, BookmarkNode* parent, int index) { - if (!CanDropAt(data, parent, index)) + if (data.IsFromProfile(profile_) && data.size() > 1) + // Currently only accept one dragged node at a time. + return DragDropTypes::DRAG_NONE; + + if (!bookmark_drag_utils::IsValidDropLocation(profile_, data, parent, index)) return DragDropTypes::DRAG_NONE; if (data.GetFirstNode(profile_)) { @@ -1751,33 +1741,11 @@ int BookmarkBarView::CalculateDropOperation(const DropTargetEvent& event, return DragDropTypes::DRAG_MOVE; } else { // User is dragging from another app, copy. - return PreferredDropOperation( + return bookmark_drag_utils::PreferredDropOperation( event, DragDropTypes::DRAG_COPY | DragDropTypes::DRAG_LINK); } } -bool BookmarkBarView::CanDropAt(const BookmarkDragData& data, - BookmarkNode* parent, - int index) { - DCHECK(data.is_valid()); - BookmarkNode* dragged_node = data.GetFirstNode(profile_); - if (dragged_node) { - if (dragged_node->GetParent() == parent) { - const int existing_index = parent->IndexOfChild(dragged_node); - if (index == existing_index || existing_index + 1 == index) - return false; - } - // Allow the drop only if the node we're going to drop on isn't a - // descendant of the dragged node. - BookmarkNode* test_node = parent; - while (test_node && test_node != dragged_node) - test_node = test_node->GetParent(); - return (test_node == NULL); - } // else case clones, always allow. - return true; -} - - int BookmarkBarView::PerformDropImpl(const BookmarkDragData& data, BookmarkNode* parent_node, int index) { @@ -1799,25 +1767,12 @@ int BookmarkBarView::PerformDropImpl(const BookmarkDragData& data, return DragDropTypes::DRAG_COPY | DragDropTypes::DRAG_LINK; } else { // Dropping a group from different profile. Always accept. - CloneDragData(data.elements[0], parent_node, index); + bookmark_drag_utils::CloneDragData(model_, data.elements, parent_node, + index); return DragDropTypes::DRAG_COPY; } } -void BookmarkBarView::CloneDragData(const BookmarkDragData::Element& element, - BookmarkNode* parent, - int index_to_add_at) { - DCHECK(model_); - if (element.is_url) { - model_->AddURL(parent, index_to_add_at, element.title, element.url); - } else { - BookmarkNode* new_folder = model_->AddGroup(parent, index_to_add_at, - element.title); - for (int i = 0; i < static_cast<int>(element.children.size()); ++i) - CloneDragData(element.children[i], new_folder, i); - } -} - int BookmarkBarView::GetFirstHiddenNodeIndex() { const int bb_count = GetBookmarkButtonCount(); for (int i = 0; i < bb_count; ++i) { diff --git a/chrome/browser/views/bookmark_bar_view.h b/chrome/browser/views/bookmark_bar_view.h index c5480ff..242a7f2 100644 --- a/chrome/browser/views/bookmark_bar_view.h +++ b/chrome/browser/views/bookmark_bar_view.h @@ -352,25 +352,12 @@ class BookmarkBarView : public views::View, BookmarkNode* parent, int index); - // Returns true if the specified location is a valid drop location for - // the supplied drag data. - bool CanDropAt(const BookmarkDragData& data, - BookmarkNode* parent, - int index); - // Performs a drop of the specified data at the specified location. Returns // the result. int PerformDropImpl(const BookmarkDragData& data, BookmarkNode* parent_node, int index); - // Creates a new group/entry for data, and recursively invokes itself for - // all children of data. This is used during drag and drop to clone a - // group from another profile. - void CloneDragData(const BookmarkDragData::Element& data, - BookmarkNode* parent, - int index_to_add_at); - // Returns the index of the first hidden bookmark button. If all buttons are // visible, this returns GetBookmarkButtonCount(). int GetFirstHiddenNodeIndex(); |