Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/views/bookmarks/bookmark_drag_drop_views.h" | 5 #include "chrome/browser/ui/views/bookmarks/bookmark_drag_drop_views.h" |
| 6 | 6 |
| 7 #include "base/message_loop/message_loop.h" | 7 #include "base/message_loop/message_loop.h" |
| 8 #include "base/prefs/pref_service.h" | 8 #include "base/prefs/pref_service.h" |
| 9 #include "chrome/browser/bookmarks/bookmark_model_factory.h" | 9 #include "chrome/browser/bookmarks/bookmark_model_factory.h" |
| 10 #include "chrome/browser/profiles/profile.h" | 10 #include "chrome/browser/profiles/profile.h" |
| 11 #include "chrome/browser/ui/bookmarks/bookmark_drag_drop.h" | 11 #include "chrome/browser/ui/bookmarks/bookmark_drag_drop.h" |
| 12 #include "chrome/common/pref_names.h" | 12 #include "chrome/common/pref_names.h" |
| 13 #include "components/bookmarks/browser/bookmark_model.h" | 13 #include "components/bookmarks/browser/bookmark_model.h" |
| 14 #include "components/bookmarks/browser/bookmark_node_data.h" | 14 #include "components/bookmarks/browser/bookmark_node_data.h" |
| 15 #include "components/bookmarks/browser/bookmark_utils.h" | |
| 15 #include "components/user_prefs/user_prefs.h" | 16 #include "components/user_prefs/user_prefs.h" |
| 16 #include "ui/base/dragdrop/drag_drop_types.h" | 17 #include "ui/base/dragdrop/drag_drop_types.h" |
| 17 #include "ui/base/dragdrop/os_exchange_data.h" | 18 #include "ui/base/dragdrop/os_exchange_data.h" |
| 18 #include "ui/events/event.h" | 19 #include "ui/events/event.h" |
| 19 #include "ui/views/drag_utils.h" | 20 #include "ui/views/drag_utils.h" |
| 20 #include "ui/views/widget/widget.h" | 21 #include "ui/views/widget/widget.h" |
| 21 | 22 |
| 22 namespace chrome { | 23 namespace chrome { |
| 23 | 24 |
| 24 void DragBookmarks(Profile* profile, | 25 void DragBookmarks(Profile* profile, |
| 25 const std::vector<const BookmarkNode*>& nodes, | 26 const std::vector<const BookmarkNode*>& nodes, |
| 26 gfx::NativeView view, | 27 gfx::NativeView view, |
| 27 ui::DragDropTypes::DragEventSource source) { | 28 ui::DragDropTypes::DragEventSource source) { |
| 28 DCHECK(!nodes.empty()); | 29 DCHECK(!nodes.empty()); |
| 29 | 30 |
| 30 // Set up our OLE machinery | 31 // Set up our OLE machinery. |
| 31 ui::OSExchangeData data; | 32 ui::OSExchangeData data; |
| 32 BookmarkNodeData drag_data(nodes); | 33 BookmarkNodeData drag_data(nodes); |
| 33 drag_data.Write(profile->GetPath(), &data); | 34 drag_data.Write(profile->GetPath(), &data); |
| 34 | 35 |
| 35 // Allow nested message loop so we get DnD events as we drag this around. | 36 // Allow nested message loop so we get DnD events as we drag this around. |
| 36 bool was_nested = base::MessageLoop::current()->IsNested(); | 37 bool was_nested = base::MessageLoop::current()->IsNested(); |
| 37 base::MessageLoop::current()->SetNestableTasksAllowed(true); | 38 base::MessageLoop::current()->SetNestableTasksAllowed(true); |
| 38 | 39 |
| 39 int operation = ui::DragDropTypes::DRAG_COPY | | 40 int operation = ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_LINK; |
| 40 ui::DragDropTypes::DRAG_MOVE | | 41 BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile); |
| 41 ui::DragDropTypes::DRAG_LINK; | 42 if (model->client()->AllCanBeEditedByUser(nodes)) |
| 43 operation |= ui::DragDropTypes::DRAG_MOVE; | |
| 44 | |
| 42 views::Widget* widget = views::Widget::GetWidgetForNativeView(view); | 45 views::Widget* widget = views::Widget::GetWidgetForNativeView(view); |
| 43 | 46 |
| 44 if (widget) { | 47 if (widget) { |
| 45 widget->RunShellDrag(NULL, data, gfx::Point(), operation, source); | 48 widget->RunShellDrag(NULL, data, gfx::Point(), operation, source); |
| 46 } else { | 49 } else { |
| 47 // We hit this case when we're using WebContentsViewWin or | 50 // We hit this case when we're using WebContentsViewWin or |
| 48 // WebContentsViewAura, instead of WebContentsViewViews. | 51 // WebContentsViewAura, instead of WebContentsViewViews. |
| 49 views::RunShellDrag(view, data, gfx::Point(), operation, source); | 52 views::RunShellDrag(view, data, gfx::Point(), operation, source); |
| 50 } | 53 } |
| 51 | 54 |
| 52 base::MessageLoop::current()->SetNestableTasksAllowed(was_nested); | 55 base::MessageLoop::current()->SetNestableTasksAllowed(was_nested); |
| 53 } | 56 } |
| 54 | 57 |
| 55 int GetBookmarkDragOperation(content::BrowserContext* browser_context, | 58 int GetBookmarkDragOperation(content::BrowserContext* browser_context, |
| 56 const BookmarkNode* node) { | 59 const BookmarkNode* node) { |
| 57 PrefService* prefs = user_prefs::UserPrefs::Get(browser_context); | 60 PrefService* prefs = user_prefs::UserPrefs::Get(browser_context); |
| 61 Profile* profile = Profile::FromBrowserContext(browser_context); | |
| 62 BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile); | |
| 58 | 63 |
| 59 int move = ui::DragDropTypes::DRAG_MOVE; | 64 int move = ui::DragDropTypes::DRAG_MOVE; |
| 60 if (!prefs->GetBoolean(prefs::kEditBookmarksEnabled)) | 65 if (!prefs->GetBoolean(prefs::kEditBookmarksEnabled) || |
| 66 !model->client()->CanBeEditedByUser(node)) { | |
|
sky
2014/06/05 23:58:48
Can we fold the pref into CanBeEditedByUser?
Joao da Silva
2014/06/06 15:41:03
At first glance I think so, yes. If you agree I'd
| |
| 61 move = ui::DragDropTypes::DRAG_NONE; | 67 move = ui::DragDropTypes::DRAG_NONE; |
| 68 } | |
| 62 if (node->is_url()) | 69 if (node->is_url()) |
| 63 return ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_LINK | move; | 70 return ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_LINK | move; |
| 64 return ui::DragDropTypes::DRAG_COPY | move; | 71 return ui::DragDropTypes::DRAG_COPY | move; |
| 65 } | 72 } |
| 66 | 73 |
| 67 int GetPreferredBookmarkDropOperation(int source_operations, int operations) { | 74 int GetPreferredBookmarkDropOperation(int source_operations, int operations) { |
| 68 int common_ops = (source_operations & operations); | 75 int common_ops = (source_operations & operations); |
| 69 if (!common_ops) | 76 if (!common_ops) |
| 70 return ui::DragDropTypes::DRAG_NONE; | 77 return ui::DragDropTypes::DRAG_NONE; |
| 71 if (ui::DragDropTypes::DRAG_COPY & common_ops) | 78 if (ui::DragDropTypes::DRAG_COPY & common_ops) |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 84 int index) { | 91 int index) { |
| 85 const base::FilePath& profile_path = profile->GetPath(); | 92 const base::FilePath& profile_path = profile->GetPath(); |
| 86 | 93 |
| 87 if (data.IsFromProfilePath(profile_path) && data.size() > 1) | 94 if (data.IsFromProfilePath(profile_path) && data.size() > 1) |
| 88 // Currently only accept one dragged node at a time. | 95 // Currently only accept one dragged node at a time. |
| 89 return ui::DragDropTypes::DRAG_NONE; | 96 return ui::DragDropTypes::DRAG_NONE; |
| 90 | 97 |
| 91 if (!IsValidBookmarkDropLocation(profile, data, parent, index)) | 98 if (!IsValidBookmarkDropLocation(profile, data, parent, index)) |
| 92 return ui::DragDropTypes::DRAG_NONE; | 99 return ui::DragDropTypes::DRAG_NONE; |
| 93 | 100 |
| 94 if (data.GetFirstNode(BookmarkModelFactory::GetForProfile(profile), | 101 BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile); |
| 95 profile_path)) | 102 if (!model->client()->CanBeEditedByUser(parent)) |
| 96 // User is dragging from this profile: move. | 103 return ui::DragDropTypes::DRAG_NONE; |
| 104 | |
| 105 const BookmarkNode* dragged_node = | |
| 106 data.GetFirstNode(model, profile->GetPath()); | |
| 107 if (dragged_node) { | |
| 108 // User is dragging from this profile. | |
| 109 if (!model->client()->CanBeEditedByUser(dragged_node)) { | |
| 110 // Do a copy instead of a move when dragging bookmarks that the user can't | |
| 111 // modify. | |
| 112 return ui::DragDropTypes::DRAG_COPY; | |
| 113 } | |
| 97 return ui::DragDropTypes::DRAG_MOVE; | 114 return ui::DragDropTypes::DRAG_MOVE; |
| 115 } | |
| 98 | 116 |
| 99 // User is dragging from another app, copy. | 117 // User is dragging from another app, copy. |
| 100 return GetPreferredBookmarkDropOperation(event.source_operations(), | 118 return GetPreferredBookmarkDropOperation(event.source_operations(), |
| 101 ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_LINK); | 119 ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_LINK); |
| 102 } | 120 } |
| 103 | 121 |
| 104 bool IsValidBookmarkDropLocation(Profile* profile, | 122 bool IsValidBookmarkDropLocation(Profile* profile, |
| 105 const BookmarkNodeData& data, | 123 const BookmarkNodeData& data, |
| 106 const BookmarkNode* drop_parent, | 124 const BookmarkNode* drop_parent, |
| 107 int index) { | 125 int index) { |
| 108 if (!drop_parent->is_folder()) { | 126 if (!drop_parent->is_folder()) { |
| 109 NOTREACHED(); | 127 NOTREACHED(); |
| 110 return false; | 128 return false; |
| 111 } | 129 } |
| 112 | 130 |
| 113 if (!data.is_valid()) | 131 if (!data.is_valid()) |
| 114 return false; | 132 return false; |
| 115 | 133 |
| 134 BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile); | |
| 135 if (!model->client()->CanBeEditedByUser(drop_parent)) | |
| 136 return false; | |
| 137 | |
| 116 const base::FilePath& profile_path = profile->GetPath(); | 138 const base::FilePath& profile_path = profile->GetPath(); |
| 117 if (data.IsFromProfilePath(profile_path)) { | 139 if (data.IsFromProfilePath(profile_path)) { |
| 118 std::vector<const BookmarkNode*> nodes = data.GetNodes( | 140 std::vector<const BookmarkNode*> nodes = data.GetNodes(model, profile_path); |
| 119 BookmarkModelFactory::GetForProfile(profile), profile_path); | |
| 120 for (size_t i = 0; i < nodes.size(); ++i) { | 141 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 | 142 // Don't allow the drop if the user is attempting to drop on one of the |
| 122 // nodes being dragged. | 143 // nodes being dragged. |
| 123 const BookmarkNode* node = nodes[i]; | 144 const BookmarkNode* node = nodes[i]; |
| 124 int node_index = (drop_parent == node->parent()) ? | 145 int node_index = (drop_parent == node->parent()) ? |
| 125 drop_parent->GetIndexOf(nodes[i]) : -1; | 146 drop_parent->GetIndexOf(nodes[i]) : -1; |
| 126 if (node_index != -1 && (index == node_index || index == node_index + 1)) | 147 if (node_index != -1 && (index == node_index || index == node_index + 1)) |
| 127 return false; | 148 return false; |
| 128 | 149 |
| 129 // drop_parent can't accept a child that is an ancestor. | 150 // drop_parent can't accept a child that is an ancestor. |
| 130 if (drop_parent->HasAncestor(node)) | 151 if (drop_parent->HasAncestor(node)) |
| 131 return false; | 152 return false; |
| 132 } | 153 } |
| 133 return true; | 154 return true; |
| 134 } | 155 } |
| 135 // From the same profile, always accept. | 156 // From another profile, always accept. |
| 136 return true; | 157 return true; |
| 137 } | 158 } |
| 138 | 159 |
| 139 } // namespace chrome | 160 } // namespace chrome |
| OLD | NEW |