Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(106)

Side by Side Diff: chrome/browser/extensions/extension_bookmark_manager_api.cc

Issue 596105: Bookmark Manager Drag and Drop backend.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/extensions/extension_bookmark_manager_api.h" 5 #include "chrome/browser/extensions/extension_bookmark_manager_api.h"
6 6
7 #include <vector>
8
7 #include "app/l10n_util.h" 9 #include "app/l10n_util.h"
10 #include "base/json/json_writer.h"
11 #include "base/string_util.h"
8 #include "base/values.h" 12 #include "base/values.h"
13 #include "chrome/browser/bookmarks/bookmark_drag_data.h"
9 #include "chrome/browser/bookmarks/bookmark_model.h" 14 #include "chrome/browser/bookmarks/bookmark_model.h"
10 #include "chrome/browser/bookmarks/bookmark_html_writer.h" 15 #include "chrome/browser/bookmarks/bookmark_html_writer.h"
11 #include "chrome/browser/bookmarks/bookmark_utils.h" 16 #include "chrome/browser/bookmarks/bookmark_utils.h"
12 #include "chrome/browser/extensions/extension_bookmarks_module_constants.h" 17 #include "chrome/browser/extensions/extension_bookmarks_module_constants.h"
18 #include "chrome/browser/extensions/extension_dom_ui.h"
19 #include "chrome/browser/extensions/extension_message_service.h"
13 #include "chrome/browser/importer/importer.h" 20 #include "chrome/browser/importer/importer.h"
14 #include "chrome/browser/profile.h" 21 #include "chrome/browser/profile.h"
22 #include "chrome/browser/tab_contents/tab_contents.h"
15 #include "grit/generated_resources.h" 23 #include "grit/generated_resources.h"
16 24
17 #include <vector>
18
19 namespace keys = extension_bookmarks_module_constants; 25 namespace keys = extension_bookmarks_module_constants;
20 26
21 namespace { 27 namespace {
22 28
29 typedef RenderViewHostDelegate::BookmarkDrag::DragData DragData;
30
23 // Returns a single bookmark node from the argument ID. 31 // Returns a single bookmark node from the argument ID.
24 // This returns NULL in case of failure. 32 // This returns NULL in case of failure.
25 const BookmarkNode* GetNodeFromArguments(BookmarkModel* model, 33 const BookmarkNode* GetNodeFromArguments(BookmarkModel* model,
26 const Value* args) { 34 const Value* args) {
27 std::string id_string; 35 std::string id_string;
28 if (!args->GetAsString(&id_string)) 36 if (!args->GetAsString(&id_string))
29 return NULL; 37 return NULL;
30 int64 id; 38 int64 id;
31 if (!StringToInt64(id_string, &id)) 39 if (!StringToInt64(id_string, &id))
32 return NULL; 40 return NULL;
(...skipping 17 matching lines...) Expand all
50 return false; 58 return false;
51 const BookmarkNode* node = model->GetNodeByID(id); 59 const BookmarkNode* node = model->GetNodeByID(id);
52 if (!node) 60 if (!node)
53 return false; 61 return false;
54 nodes->push_back(node); 62 nodes->push_back(node);
55 } 63 }
56 64
57 return true; 65 return true;
58 } 66 }
59 67
68 // Recursively adds a node to a list. This is by used |BookmarkDragDataToJSON|
69 // when the data comes from the current profile. In this case we have a
70 // BookmarkNode since we got the data from the current profile.
71 void AddNodeToList(ListValue* list, const BookmarkNode& node) {
72 DictionaryValue* dict = new DictionaryValue();
73
74 // Add id and parentId so we can associate the data with existing nodes on the
75 // client side.
76 std::string id_string = Int64ToString(node.id());
77 dict->SetString(keys::kIdKey, id_string);
78
79 std::string parent_id_string = Int64ToString(node.GetParent()->id());
80 dict->SetString(keys::kParentIdKey, parent_id_string);
81
82 if (node.is_url())
83 dict->SetString(keys::kUrlKey, node.GetURL().spec());
84
85 dict->SetString(keys::kTitleKey, node.GetTitle());
86
87 ListValue* children = new ListValue();
88 for (int i = 0; i < node.GetChildCount(); ++i)
89 AddNodeToList(children, *node.GetChild(i));
90 dict->Set(keys::kChildrenKey, children);
91
92 list->Append(dict);
93 }
94
95 // Recursively adds an element to a list. This is by used
96 // |BookmarkDragDataToJSON| when the data comes from a different profile. When
97 // the data comes from a different profile we do not have any IDs or parent IDs.
98 void AddElementToList(ListValue* list,
99 const BookmarkDragData::Element& element) {
100 DictionaryValue* dict = new DictionaryValue();
101
102 if (element.is_url)
103 dict->SetString(keys::kUrlKey, element.url.spec());
104
105 dict->SetString(keys::kTitleKey, UTF16ToWide(element.title));
106
107 ListValue* children = new ListValue();
108 for (size_t i = 0; i < element.children.size(); ++i)
109 AddElementToList(children, element.children[i]);
110 dict->Set(keys::kChildrenKey, children);
111
112 list->Append(dict);
113 }
114
115 // Builds the JSON structure based on the BookmarksDragData.
116 void BookmarkDragDataToJSON(Profile* profile, const BookmarkDragData& data,
117 ListValue* args) {
118 bool same_profile = data.IsFromProfile(profile);
119 DictionaryValue* value = new DictionaryValue();
120 value->SetBoolean(keys::kSameProfileKey, same_profile);
121
122 ListValue* list = new ListValue();
123 if (same_profile) {
124 std::vector<const BookmarkNode*> nodes = data.GetNodes(profile);
125 for (size_t i = 0; i < nodes.size(); ++i)
126 AddNodeToList(list, *nodes[i]);
127 } else {
128 // We do not have an node IDs when the data comes from a different profile.
129 std::vector<BookmarkDragData::Element> elements = data.elements;
130 for (size_t i = 0; i < elements.size(); ++i)
131 AddElementToList(list, elements[i]);
132 }
133 value->Set(keys::kElementsKey, list);
134
135 args->Append(value);
136 }
137
138 // This is the platform specific function that takes the drag data and creates
139 // the BookmarkDragData as needed.
140 bool GetBookmarkDragData(const DragData* data,
141 BookmarkDragData* bookmark_drag_data) {
142 #if defined(TOOLKIT_VIEWS)
143 // On TOOLKIT_VIEWS DragData is OSExchangeData.
144 return bookmark_drag_data->Read(*data);
145 #else
146 NOTIMPLEMENTED();
147 return false;
148 #endif
149 }
150
151 } // namespace
152
153 ExtensionBookmarkManagerEventRouter::ExtensionBookmarkManagerEventRouter(
154 Profile* profile, TabContents* tab_contents)
155 : profile_(profile),
156 tab_contents_(tab_contents) {
157 tab_contents_->SetBookmarkDragDelegate(this);
158 }
159
160 ExtensionBookmarkManagerEventRouter::~ExtensionBookmarkManagerEventRouter() {
161 if (tab_contents_->GetBookmarkDragDelegate() == this)
162 tab_contents_->SetBookmarkDragDelegate(NULL);
163 }
164
165 void ExtensionBookmarkManagerEventRouter::DispatchEvent(const char* event_name,
166 const ListValue* args) {
167 if (!profile_->GetExtensionMessageService())
168 return;
169
170 std::string json_args;
171 base::JSONWriter::Write(args, false, &json_args);
172 profile_->GetExtensionMessageService()->
173 DispatchEventToRenderers(event_name, json_args);
174 }
175
176 void ExtensionBookmarkManagerEventRouter::DispatchDragEvent(
177 const DragData* data, const char* event_name) {
178 BookmarkDragData bookmark_drag_data;
179 if (::GetBookmarkDragData(data, &bookmark_drag_data)) {
180 ListValue args;
181 BookmarkDragDataToJSON(profile_, bookmark_drag_data, &args);
182 DispatchEvent(event_name, &args);
183 }
184 }
185
186 void ExtensionBookmarkManagerEventRouter::OnDragEnter(const DragData* data) {
187 DispatchDragEvent(data, keys::kOnBookmarkDragEnter);
188 }
189
190 void ExtensionBookmarkManagerEventRouter::OnDragOver(const DragData* data) {
191 // Intentionally empty since these events happens too often and floods the
192 // message queue. We do not need this event for the bookmark manager anyway.
193 }
194
195 void ExtensionBookmarkManagerEventRouter::OnDragLeave(const DragData* data) {
196 DispatchDragEvent(data, keys::kOnBookmarkDragLeave);
197 }
198
199 void ExtensionBookmarkManagerEventRouter::OnDrop(const DragData* data) {
200 DispatchDragEvent(data, keys::kOnBookmarkDrop);
201
202 // Make a copy that is owned by this instance.
203 ClearBookmarkDragData();
204 ::GetBookmarkDragData(data, &bookmark_drag_data_);
205 }
206
207 const BookmarkDragData*
208 ExtensionBookmarkManagerEventRouter::GetBookmarkDragData() {
209 if (bookmark_drag_data_.is_valid())
210 return &bookmark_drag_data_;
211 return NULL;
212 }
213
214 void ExtensionBookmarkManagerEventRouter::ClearBookmarkDragData() {
215 bookmark_drag_data_.Clear();
60 } 216 }
61 217
62 bool ClipboardBookmarkManagerFunction::CopyOrCut(bool cut) { 218 bool ClipboardBookmarkManagerFunction::CopyOrCut(bool cut) {
63 BookmarkModel* model = profile()->GetBookmarkModel(); 219 BookmarkModel* model = profile()->GetBookmarkModel();
64 std::vector<const BookmarkNode*> nodes; 220 std::vector<const BookmarkNode*> nodes;
65 EXTENSION_FUNCTION_VALIDATE(GetNodesFromArguments(model, args_as_list(), 221 EXTENSION_FUNCTION_VALIDATE(GetNodesFromArguments(model, args_as_list(),
66 &nodes)); 222 &nodes));
67 bookmark_utils::CopyToClipboard(model, nodes, cut); 223 bookmark_utils::CopyToClipboard(model, nodes, cut);
68 return true; 224 return true;
69 } 225 }
70 226
71 bool CopyBookmarkManagerFunction::RunImpl() { 227 bool CopyBookmarkManagerFunction::RunImpl() {
72 return CopyOrCut(false); 228 return CopyOrCut(false);
73 } 229 }
74 230
75 bool CutBookmarkManagerFunction::RunImpl() { 231 bool CutBookmarkManagerFunction::RunImpl() {
76 return CopyOrCut(true); 232 return CopyOrCut(true);
77 } 233 }
78 234
79 bool PasteBookmarkManagerFunction::RunImpl() { 235 bool PasteBookmarkManagerFunction::RunImpl() {
80 BookmarkModel* model = profile()->GetBookmarkModel(); 236 BookmarkModel* model = profile()->GetBookmarkModel();
81 const BookmarkNode* parent_node = GetNodeFromArguments(model, args_.get()); 237 const BookmarkNode* parent_node = GetNodeFromArguments(model, args_.get());
82 EXTENSION_FUNCTION_VALIDATE(parent_node); 238 if (!parent_node) {
239 error_ = keys::kNoParentError;
240 return false;
241 }
83 bool can_paste = bookmark_utils::CanPasteFromClipboard(parent_node); 242 bool can_paste = bookmark_utils::CanPasteFromClipboard(parent_node);
84 EXTENSION_FUNCTION_VALIDATE(can_paste); 243 if (!can_paste)
244 return false;
85 bookmark_utils::PasteFromClipboard(model, parent_node, -1); 245 bookmark_utils::PasteFromClipboard(model, parent_node, -1);
86 return true; 246 return true;
87 } 247 }
88 248
89 bool CanPasteBookmarkManagerFunction::RunImpl() { 249 bool CanPasteBookmarkManagerFunction::RunImpl() {
90 BookmarkModel* model = profile()->GetBookmarkModel(); 250 BookmarkModel* model = profile()->GetBookmarkModel();
91 const BookmarkNode* parent_node = GetNodeFromArguments(model, args_.get()); 251 const BookmarkNode* parent_node = GetNodeFromArguments(model, args_.get());
92 EXTENSION_FUNCTION_VALIDATE(parent_node); 252 if (!parent_node) {
253 error_ = keys::kNoParentError;
254 return false;
255 }
93 bool can_paste = bookmark_utils::CanPasteFromClipboard(parent_node); 256 bool can_paste = bookmark_utils::CanPasteFromClipboard(parent_node);
94 result_.reset(Value::CreateBooleanValue(can_paste)); 257 result_.reset(Value::CreateBooleanValue(can_paste));
95 SendResponse(true); 258 SendResponse(true);
96 return true; 259 return true;
97 } 260 }
98 261
99 void BookmarkManagerIOFunction::SelectFile(SelectFileDialog::Type type) { 262 void BookmarkManagerIOFunction::SelectFile(SelectFileDialog::Type type) {
100 // Balanced in one of the three callbacks of SelectFileDialog: 263 // Balanced in one of the three callbacks of SelectFileDialog:
101 // either FileSelectionCanceled, MultiFilesSelected, or FileSelected 264 // either FileSelectionCanceled, MultiFilesSelected, or FileSelected
102 AddRef(); 265 AddRef();
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 void ExportBookmarksFunction::FileSelected(const FilePath& path, 316 void ExportBookmarksFunction::FileSelected(const FilePath& path,
154 int index, 317 int index,
155 void* params) { 318 void* params) {
156 bookmark_html_writer::WriteBookmarks(profile(), path, NULL); 319 bookmark_html_writer::WriteBookmarks(profile(), path, NULL);
157 Release(); // Balanced in BookmarkManagerIOFunction::SelectFile() 320 Release(); // Balanced in BookmarkManagerIOFunction::SelectFile()
158 } 321 }
159 322
160 bool SortChildrenBookmarkManagerFunction::RunImpl() { 323 bool SortChildrenBookmarkManagerFunction::RunImpl() {
161 BookmarkModel* model = profile()->GetBookmarkModel(); 324 BookmarkModel* model = profile()->GetBookmarkModel();
162 const BookmarkNode* parent_node = GetNodeFromArguments(model, args_.get()); 325 const BookmarkNode* parent_node = GetNodeFromArguments(model, args_.get());
163 EXTENSION_FUNCTION_VALIDATE(parent_node); 326 if (!parent_node) {
327 error_ = keys::kNoParentError;
328 return false;
329 }
164 model->SortChildren(parent_node); 330 model->SortChildren(parent_node);
165 return true; 331 return true;
166 } 332 }
167 333
168 bool BookmarkManagerGetStringsFunction::RunImpl() { 334 bool BookmarkManagerGetStringsFunction::RunImpl() {
169 DictionaryValue* localized_strings = new DictionaryValue(); 335 DictionaryValue* localized_strings = new DictionaryValue();
170 336
171 localized_strings->SetString(L"title", 337 localized_strings->SetString(L"title",
172 l10n_util::GetString(IDS_BOOKMARK_MANAGER_TITLE)); 338 l10n_util::GetString(IDS_BOOKMARK_MANAGER_TITLE));
173 localized_strings->SetString(L"search_button", 339 localized_strings->SetString(L"search_button",
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 l10n_util::GetString(IDS_CONTENT_CONTEXT_CUT)); 382 l10n_util::GetString(IDS_CONTENT_CONTEXT_CUT));
217 localized_strings->SetString(L"paste", 383 localized_strings->SetString(L"paste",
218 l10n_util::GetString(IDS_CONTENT_CONTEXT_PASTE)); 384 l10n_util::GetString(IDS_CONTENT_CONTEXT_PASTE));
219 localized_strings->SetString(L"delete", 385 localized_strings->SetString(L"delete",
220 l10n_util::GetString(IDS_CONTENT_CONTEXT_DELETE)); 386 l10n_util::GetString(IDS_CONTENT_CONTEXT_DELETE));
221 387
222 result_.reset(localized_strings); 388 result_.reset(localized_strings);
223 SendResponse(true); 389 SendResponse(true);
224 return true; 390 return true;
225 } 391 }
392
393 bool StartDragBookmarkManagerFunction::RunImpl() {
394 BookmarkModel* model = profile()->GetBookmarkModel();
395 std::vector<const BookmarkNode*> nodes;
396 EXTENSION_FUNCTION_VALIDATE(
397 GetNodesFromArguments(model, args_as_list(), &nodes));
398
399 bookmark_utils::DragBookmarks(profile(), nodes,
400 dispatcher()->GetExtensionDOMUI()->tab_contents()->GetNativeView());
401
402 return true;
403 }
404
405 bool DropBookmarkManagerFunction::RunImpl() {
406 BookmarkModel* model = profile()->GetBookmarkModel();
407
408 // TODO(arv): The arguments change between a list and a value depending on the
409 // parameters. See http://crbug.com/36301
410 int64 id;
411 std::string id_string;
412 if (args_->IsType(Value::TYPE_STRING)) {
413 EXTENSION_FUNCTION_VALIDATE(args_->GetAsString(&id_string));
414 } else {
415 EXTENSION_FUNCTION_VALIDATE(args_->IsType(Value::TYPE_LIST));
416 EXTENSION_FUNCTION_VALIDATE(args_as_list()->GetString(0, &id_string));
417 }
418 if (!StringToInt64(id_string, &id)) {
419 error_ = keys::kInvalidIdError;
420 return false;
421 }
422
423 const BookmarkNode* drop_parent = model->GetNodeByID(id);
424 if (!drop_parent) {
425 error_ = keys::kNoParentError;
426 return false;
427 }
428
429 int drop_index;
430 if (args_as_list()->GetSize() == 2)
431 EXTENSION_FUNCTION_VALIDATE(args_as_list()->GetInteger(1, &drop_index));
432 else
433 drop_index = drop_parent->GetChildCount();
434
435 ExtensionBookmarkManagerEventRouter* router = dispatcher()->
436 GetExtensionDOMUI()->extension_bookmark_manager_event_router();
437
438 DCHECK(router);
439
440 bookmark_utils::PerformBookmarkDrop(profile(), *router->GetBookmarkDragData(),
441 drop_parent, drop_index);
442
443 router->ClearBookmarkDragData();
444 SendResponse(true);
445 return true;
446 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698