[Metrics] Make MetricsStateManager take a callback param to check if UMA is enabled.
[chromium-blink-merge.git] / chrome / browser / ui / views / bookmarks / bookmark_drag_drop_views.cc
blob5c1c3ed311cc8244f3fe728ef93dd0c6b372ab0a
1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/views/bookmarks/bookmark_drag_drop_views.h"
7 #include "base/message_loop/message_loop.h"
8 #include "base/prefs/pref_service.h"
9 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/ui/bookmarks/bookmark_drag_drop.h"
12 #include "chrome/common/pref_names.h"
13 #include "components/bookmarks/browser/bookmark_model.h"
14 #include "components/bookmarks/browser/bookmark_node_data.h"
15 #include "components/user_prefs/user_prefs.h"
16 #include "ui/base/dragdrop/drag_drop_types.h"
17 #include "ui/base/dragdrop/os_exchange_data.h"
18 #include "ui/events/event.h"
19 #include "ui/views/drag_utils.h"
20 #include "ui/views/widget/widget.h"
22 namespace chrome {
24 void DragBookmarks(Profile* profile,
25 const std::vector<const BookmarkNode*>& nodes,
26 gfx::NativeView view,
27 ui::DragDropTypes::DragEventSource source) {
28 DCHECK(!nodes.empty());
30 // Set up our OLE machinery
31 ui::OSExchangeData data;
32 BookmarkNodeData drag_data(nodes);
33 drag_data.Write(profile->GetPath(), &data);
35 // Allow nested message loop so we get DnD events as we drag this around.
36 bool was_nested = base::MessageLoop::current()->IsNested();
37 base::MessageLoop::current()->SetNestableTasksAllowed(true);
39 int operation = ui::DragDropTypes::DRAG_COPY |
40 ui::DragDropTypes::DRAG_MOVE |
41 ui::DragDropTypes::DRAG_LINK;
42 views::Widget* widget = views::Widget::GetWidgetForNativeView(view);
44 if (widget) {
45 widget->RunShellDrag(NULL, data, gfx::Point(), operation, source);
46 } else {
47 // We hit this case when we're using WebContentsViewWin or
48 // WebContentsViewAura, instead of WebContentsViewViews.
49 views::RunShellDrag(view, data, gfx::Point(), operation, source);
52 base::MessageLoop::current()->SetNestableTasksAllowed(was_nested);
55 int GetBookmarkDragOperation(content::BrowserContext* browser_context,
56 const BookmarkNode* node) {
57 PrefService* prefs = user_prefs::UserPrefs::Get(browser_context);
59 int move = ui::DragDropTypes::DRAG_MOVE;
60 if (!prefs->GetBoolean(prefs::kEditBookmarksEnabled))
61 move = ui::DragDropTypes::DRAG_NONE;
62 if (node->is_url())
63 return ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_LINK | move;
64 return ui::DragDropTypes::DRAG_COPY | move;
67 int GetPreferredBookmarkDropOperation(int source_operations, int operations) {
68 int common_ops = (source_operations & operations);
69 if (!common_ops)
70 return ui::DragDropTypes::DRAG_NONE;
71 if (ui::DragDropTypes::DRAG_COPY & common_ops)
72 return ui::DragDropTypes::DRAG_COPY;
73 if (ui::DragDropTypes::DRAG_LINK & common_ops)
74 return ui::DragDropTypes::DRAG_LINK;
75 if (ui::DragDropTypes::DRAG_MOVE & common_ops)
76 return ui::DragDropTypes::DRAG_MOVE;
77 return ui::DragDropTypes::DRAG_NONE;
80 int GetBookmarkDropOperation(Profile* profile,
81 const ui::DropTargetEvent& event,
82 const BookmarkNodeData& data,
83 const BookmarkNode* parent,
84 int index) {
85 const base::FilePath& profile_path = profile->GetPath();
87 if (data.IsFromProfilePath(profile_path) && data.size() > 1)
88 // Currently only accept one dragged node at a time.
89 return ui::DragDropTypes::DRAG_NONE;
91 if (!IsValidBookmarkDropLocation(profile, data, parent, index))
92 return ui::DragDropTypes::DRAG_NONE;
94 if (data.GetFirstNode(BookmarkModelFactory::GetForProfile(profile),
95 profile_path))
96 // User is dragging from this profile: move.
97 return ui::DragDropTypes::DRAG_MOVE;
99 // User is dragging from another app, copy.
100 return GetPreferredBookmarkDropOperation(event.source_operations(),
101 ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_LINK);
104 bool IsValidBookmarkDropLocation(Profile* profile,
105 const BookmarkNodeData& data,
106 const BookmarkNode* drop_parent,
107 int index) {
108 if (!drop_parent->is_folder()) {
109 NOTREACHED();
110 return false;
113 if (!data.is_valid())
114 return false;
116 const base::FilePath& profile_path = profile->GetPath();
117 if (data.IsFromProfilePath(profile_path)) {
118 std::vector<const BookmarkNode*> nodes = data.GetNodes(
119 BookmarkModelFactory::GetForProfile(profile), profile_path);
120 for (size_t i = 0; i < nodes.size(); ++i) {
121 // Don't allow the drop if the user is attempting to drop on one of the
122 // nodes being dragged.
123 const BookmarkNode* node = nodes[i];
124 int node_index = (drop_parent == node->parent()) ?
125 drop_parent->GetIndexOf(nodes[i]) : -1;
126 if (node_index != -1 && (index == node_index || index == node_index + 1))
127 return false;
129 // drop_parent can't accept a child that is an ancestor.
130 if (drop_parent->HasAncestor(node))
131 return false;
133 return true;
135 // From the same profile, always accept.
136 return true;
139 } // namespace chrome