summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorfeldstein@chromium.org <feldstein@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-07 03:43:51 +0000
committerfeldstein@chromium.org <feldstein@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-07 03:43:51 +0000
commiteda74d6837b1d8915a15f1a0598d1ce3c99b5cb0 (patch)
tree22f0a72166f5f9b34e37974489b991319ec16baf /chrome/browser
parentc3c91a64cba4f083f0aed48a7c4719303dd89e7d (diff)
downloadchromium_src-eda74d6837b1d8915a15f1a0598d1ce3c99b5cb0.zip
chromium_src-eda74d6837b1d8915a15f1a0598d1ce3c99b5cb0.tar.gz
chromium_src-eda74d6837b1d8915a15f1a0598d1ce3c99b5cb0.tar.bz2
Initial implementation of Drag and Drop for the extension BMM.
Review URL: http://codereview.chromium.org/660139 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@40858 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/bookmarks/bookmark_drag_data.cc10
-rw-r--r--chrome/browser/bookmarks/bookmark_drag_data.h12
-rw-r--r--chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.h37
-rw-r--r--chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.mm165
-rw-r--r--chrome/browser/bookmarks/bookmark_utils.cc47
-rw-r--r--chrome/browser/cocoa/bookmark_drag_source.h30
-rw-r--r--chrome/browser/cocoa/bookmark_drag_source.mm43
-rw-r--r--chrome/browser/cocoa/web_contents_drag_source.h65
-rw-r--r--chrome/browser/cocoa/web_contents_drag_source.mm131
-rw-r--r--chrome/browser/cocoa/web_drop_target.mm18
-rw-r--r--chrome/browser/extensions/extension_bookmark_manager_api.cc2
11 files changed, 494 insertions, 66 deletions
diff --git a/chrome/browser/bookmarks/bookmark_drag_data.cc b/chrome/browser/bookmarks/bookmark_drag_data.cc
index 5a5340b..3491d06 100644
--- a/chrome/browser/bookmarks/bookmark_drag_data.cc
+++ b/chrome/browser/bookmarks/bookmark_drag_data.cc
@@ -150,11 +150,17 @@ bool BookmarkDragData::ClipboardContainsBookmarks() {
}
#else
void BookmarkDragData::WriteToClipboard(Profile* profile) const {
- bookmark_pasteboard_helper_mac::WriteToClipboard(elements);
+ bookmark_pasteboard_helper_mac::WriteToClipboard(elements, profile_path_);
}
bool BookmarkDragData::ReadFromClipboard() {
- return bookmark_pasteboard_helper_mac::ReadFromClipboard(elements);
+ return bookmark_pasteboard_helper_mac::ReadFromClipboard(elements,
+ &profile_path_);
+}
+
+bool BookmarkDragData::ReadFromDragClipboard() {
+ return bookmark_pasteboard_helper_mac::ReadFromDragClipboard(elements,
+ &profile_path_);
}
bool BookmarkDragData::ClipboardContainsBookmarks() {
diff --git a/chrome/browser/bookmarks/bookmark_drag_data.h b/chrome/browser/bookmarks/bookmark_drag_data.h
index 9d033ae..9d72456 100644
--- a/chrome/browser/bookmarks/bookmark_drag_data.h
+++ b/chrome/browser/bookmarks/bookmark_drag_data.h
@@ -59,6 +59,9 @@ struct BookmarkDragData {
// Children, only used for non-URL nodes.
std::vector<Element> children;
+ int64 get_id() {
+ return id_;
+ }
private:
friend struct BookmarkDragData;
@@ -83,9 +86,14 @@ struct BookmarkDragData {
// Writes elements to the clipboard.
void WriteToClipboard(Profile* profile) const;
- // Reads bookmarks from the clipboard. Prefers data written via
- // WriteToClipboard but will also attempt to read a plain bookmark.
+ // Reads bookmarks from the general copy/paste clipboard. Prefers data
+ // written via WriteToClipboard but will also attempt to read a plain bookmark.
bool ReadFromClipboard();
+#if defined(OS_MACOSX)
+ // Reads bookmarks that are being dragged from the drag and drop
+ // pasteboard.
+ bool ReadFromDragClipboard();
+#endif
#if defined(TOOLKIT_VIEWS)
// Writes elements to data. If there is only one element and it is a URL
diff --git a/chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.h b/chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.h
index 357671e..4366b44 100644
--- a/chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.h
+++ b/chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.h
@@ -5,16 +5,47 @@
#ifndef CHROME_BROWSER_BOOKMARKS_BOOKMARK_PASTEBOARD_HELPER_MAC_H_
#define CHROME_BROWSER_BOOKMARKS_BOOKMARK_PASTEBOARD_HELPER_MAC_H_
-#import "chrome/browser/bookmarks/bookmark_drag_data.h"
+#include "app/gfx/native_widget_types.h"
+#include "base/file_path.h"
+#include "chrome/browser/bookmarks/bookmark_drag_data.h"
+// This set of functions lets C++ code interact with the cocoa pasteboard
+// and dragging methods.
namespace bookmark_pasteboard_helper_mac {
-void WriteToClipboard(const std::vector<BookmarkDragData::Element>& elements);
+// Writes a set of bookmark elements from a profile to the general pasteboard.
+// This should be used for copy/paste functions.
+void WriteToClipboard(const std::vector<BookmarkDragData::Element>& elements,
+ FilePath::StringType profile_path);
-bool ReadFromClipboard(std::vector<BookmarkDragData::Element>& elements);
+// Writes a set of bookmark elements from a profile to the dragging pasteboard
+// for drag and drop functions.
+void WriteToDragClipboard(
+ const std::vector<BookmarkDragData::Element>& elements,
+ FilePath::StringType profile_path);
+// Reads a set of bookmark elements from the general copy/paste clipboard.
+bool ReadFromClipboard(std::vector<BookmarkDragData::Element>& elements,
+ FilePath::StringType* profile_path);
+
+// Reads a set of bookmark elements from the drag and drop clipboard.
+bool ReadFromDragClipboard(std::vector<BookmarkDragData::Element>& elements,
+ FilePath::StringType* profile_path);
+
+// Returns true if the general copy/paste pasteboard contains any sort of
+// bookmark elements. It currently does not consider a plaintext url a
+// valid bookmark.
bool ClipboardContainsBookmarks();
+// Returns true if the dragging pasteboard contains any sort of bookmark
+// elements.
+bool DragClipboardContainsBookmarks();
+
+// Copies the bookmark nodes to the dragging pasteboard and initiates a
+// drag from the specified view. |view| must be a |TabContentsViewCocoa*|.
+void StartDrag(Profile* profile, const std::vector<const BookmarkNode*>& nodes,
+ gfx::NativeView view);
+
}
#endif // CHROME_BROWSER_BOOKMARKS_BOOKMARK_PASTEBOARD_HELPER_MAC_H_
diff --git a/chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.mm b/chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.mm
index 28dbac1..166fda7 100644
--- a/chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.mm
+++ b/chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.mm
@@ -2,57 +2,78 @@
// 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_pasteboard_helper_mac.h"
+
#import <Cocoa/Cocoa.h>
#include "base/sys_string_conversions.h"
-#include "chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.h"
+#include "chrome/browser/bookmarks/bookmark_model.h"
+#include "chrome/browser/cocoa/bookmark_drag_source.h"
+#include "chrome/browser/tab_contents/tab_contents_view_mac.h"
-namespace bookmark_pasteboard_helper_mac {
+namespace {
+
+// Pasteboard type used to store profile path to determine which profile
+// a set of bookmarks came from.
+NSString* const ChromiumProfilePathPboardType =
+ @"ChromiumProfilePathPboardType";
+
+// Internal bookmark ID for a bookmark node. Used only when moving inside
+// of one profile.
+NSString* const kChromiumBookmarkId =
+ @"ChromiumBookmarkId";
// Mac WebKit uses this type, declared in
// WebKit/mac/History/WebURLsWithTitles.h
-static NSString* const WebURLsWithTitlesPboardType =
+NSString* const WebURLsWithTitlesPboardType =
@"WebURLsWithTitlesPboardType";
-static NSString* const BookmarkDictionaryListPboardType =
+NSString* const BookmarkDictionaryListPboardType =
@"BookmarkDictionaryListPboardType";
// Keys for the type of node in BookmarkDictionaryListPboardType
-static NSString* const WebBookmarkType =
+NSString* const WebBookmarkType =
@"WebBookmarkType";
-static NSString* const WebBookmarkTypeList =
+NSString* const WebBookmarkTypeList =
@"WebBookmarkTypeList";
-static NSString* const WebBookmarkTypeLeaf =
+NSString* const WebBookmarkTypeLeaf =
@"WebBookmarkTypeLeaf";
-static void ConvertPlistToElements(NSArray* input,
+void ConvertPlistToElements(NSArray* input,
std::vector<BookmarkDragData::Element>& elements) {
NSUInteger len = [input count];
for (NSUInteger i = 0; i < len; ++i) {
- NSDictionary* object = [input objectAtIndex:i];
- BookmarkDragData::Element element;
- BOOL is_folder = [[object objectForKey:WebBookmarkType]
+ NSDictionary* pboardBookmark = [input objectAtIndex:i];
+ scoped_ptr<BookmarkNode> new_node(new BookmarkNode(0, GURL()));
+ int64 node_id =
+ [[pboardBookmark objectForKey:kChromiumBookmarkId] longLongValue];
+ new_node->set_id(node_id);
+ BOOL is_folder = [[pboardBookmark objectForKey:WebBookmarkType]
isEqualToString:WebBookmarkTypeList];
- if(is_folder) {
- NSString* title = [object objectForKey:@"Title"];
- element.title = base::SysNSStringToUTF16(title);
- ConvertPlistToElements([object objectForKey:@"Children"],
- element.children);
+ if (is_folder) {
+ new_node->set_type(BookmarkNode::FOLDER);
+ NSString* title = [pboardBookmark objectForKey:@"Title"];
+ new_node->SetTitle(base::SysNSStringToUTF16(title));
} else {
- NSDictionary* uriDictionary = [object objectForKey:@"URIDictionary"];
+ new_node->set_type(BookmarkNode::URL);
+ NSDictionary* uriDictionary =
+ [pboardBookmark objectForKey:@"URIDictionary"];
NSString* title = [uriDictionary objectForKey:@"title"];
- NSString* urlString = [object objectForKey:@"URLString"];
- element.title = base::SysNSStringToUTF16(title);
- element.url = GURL(base::SysNSStringToUTF8(urlString));
- element.is_url = true;
+ NSString* urlString = [pboardBookmark objectForKey:@"URLString"];
+ new_node->SetTitle(base::SysNSStringToUTF16(title));
+ new_node->SetURL(GURL(base::SysNSStringToUTF8(urlString)));
}
- elements.push_back(element);
+ BookmarkDragData::Element e = BookmarkDragData::Element(new_node.get());
+ if(is_folder)
+ ConvertPlistToElements([pboardBookmark objectForKey:@"Children"],
+ e.children);
+ elements.push_back(e);
}
}
-static bool ReadBookmarkDictionaryListPboardType(NSPasteboard* pb,
+bool ReadBookmarkDictionaryListPboardType(NSPasteboard* pb,
std::vector<BookmarkDragData::Element>& elements) {
NSArray* bookmarks = [pb propertyListForType:
BookmarkDictionaryListPboardType];
@@ -61,7 +82,7 @@ static bool ReadBookmarkDictionaryListPboardType(NSPasteboard* pb,
return true;
}
-static bool ReadWebURLsWithTitlesPboardType(NSPasteboard* pb,
+bool ReadWebURLsWithTitlesPboardType(NSPasteboard* pb,
std::vector<BookmarkDragData::Element>& elements) {
NSArray* bookmarkPairs =
[pb propertyListForType:WebURLsWithTitlesPboardType];
@@ -92,7 +113,7 @@ static bool ReadWebURLsWithTitlesPboardType(NSPasteboard* pb,
return true;
}
-static bool ReadNSURLPboardType(NSPasteboard* pb,
+bool ReadNSURLPboardType(NSPasteboard* pb,
std::vector<BookmarkDragData::Element>& elements) {
NSURL* url = [NSURL URLFromPasteboard:pb];
if (url == nil) {
@@ -111,7 +132,7 @@ static bool ReadNSURLPboardType(NSPasteboard* pb,
return true;
}
-static NSArray* GetPlistForBookmarkList(
+NSArray* GetPlistForBookmarkList(
const std::vector<BookmarkDragData::Element>& elements) {
NSMutableArray* plist = [NSMutableArray array];
for (size_t i = 0; i < elements.size(); ++i) {
@@ -119,21 +140,27 @@ static NSArray* GetPlistForBookmarkList(
if (element.is_url) {
NSString* title = base::SysUTF16ToNSString(element.title);
NSString* url = base::SysUTF8ToNSString(element.url.spec());
+ int64 elementId = element.get_id();
+ NSNumber* idNum = [NSNumber numberWithLongLong:elementId];
NSDictionary* uriDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
title, @"title", nil];
NSDictionary* object = [NSDictionary dictionaryWithObjectsAndKeys:
uriDictionary, @"URIDictionary",
url, @"URLString",
WebBookmarkTypeLeaf, WebBookmarkType,
+ idNum, kChromiumBookmarkId,
nil];
[plist addObject:object];
} else {
NSString* title = base::SysUTF16ToNSString(element.title);
NSArray* children = GetPlistForBookmarkList(element.children);
+ int64 elementId = element.get_id();
+ NSNumber* idNum = [NSNumber numberWithLongLong:elementId];
NSDictionary* object = [NSDictionary dictionaryWithObjectsAndKeys:
title, @"Title",
children, @"Children",
WebBookmarkTypeList, WebBookmarkType,
+ idNum, kChromiumBookmarkId,
nil];
[plist addObject:object];
}
@@ -141,13 +168,13 @@ static NSArray* GetPlistForBookmarkList(
return plist;
}
-static void WriteBookmarkDictionaryListPboardType(NSPasteboard* pb,
+void WriteBookmarkDictionaryListPboardType(NSPasteboard* pb,
const std::vector<BookmarkDragData::Element>& elements) {
NSArray* plist = GetPlistForBookmarkList(elements);
[pb setPropertyList:plist forType:BookmarkDictionaryListPboardType];
}
-static void FillFlattenedArraysForBookmarks(
+void FillFlattenedArraysForBookmarks(
const std::vector<BookmarkDragData::Element>& elements,
NSMutableArray* titles, NSMutableArray* urls) {
for (size_t i = 0; i < elements.size(); ++i) {
@@ -163,7 +190,7 @@ static void FillFlattenedArraysForBookmarks(
}
}
-static void WriteSimplifiedBookmarkTypes(NSPasteboard* pb,
+void WriteSimplifiedBookmarkTypes(NSPasteboard* pb,
const std::vector<BookmarkDragData::Element>& elements) {
NSMutableArray* titles = [NSMutableArray array];
NSMutableArray* urls = [NSMutableArray array];
@@ -184,33 +211,40 @@ static void WriteSimplifiedBookmarkTypes(NSPasteboard* pb,
[pb setString:titleString forType:@"public.url-name"];
}
-void WriteToClipboard(const std::vector<BookmarkDragData::Element>& elements) {
+void WriteToClipboardPrivate(
+ const std::vector<BookmarkDragData::Element>& elements,
+ NSPasteboard* pb,
+ FilePath::StringType profile_path) {
if (elements.size() == 0) {
return;
}
- NSPasteboard* pb = [NSPasteboard generalPasteboard];
NSArray* types = [NSArray arrayWithObjects:BookmarkDictionaryListPboardType,
WebURLsWithTitlesPboardType,
NSStringPboardType,
NSURLPboardType,
@"public.url-name",
+ ChromiumProfilePathPboardType,
nil];
[pb declareTypes:types owner:nil];
+ [pb setString:base::SysUTF8ToNSString(profile_path)
+ forType:ChromiumProfilePathPboardType];
WriteBookmarkDictionaryListPboardType(pb, elements);
WriteSimplifiedBookmarkTypes(pb, elements);
}
-bool ReadFromClipboard(std::vector<BookmarkDragData::Element>& elements) {
+bool ReadFromClipboardPrivate(
+ std::vector<BookmarkDragData::Element>& elements,
+ NSPasteboard* pb,
+ FilePath::StringType* profile_path) {
elements.clear();
-
- NSPasteboard* pb = [NSPasteboard generalPasteboard];
+ NSString* profile = [pb stringForType:ChromiumProfilePathPboardType];
+ profile_path->assign(base::SysNSStringToUTF8(profile));
return (ReadBookmarkDictionaryListPboardType(pb, elements) ||
ReadWebURLsWithTitlesPboardType(pb, elements) ||
ReadNSURLPboardType(pb, elements));
}
-bool ClipboardContainsBookmarks() {
- NSPasteboard* pb = [NSPasteboard generalPasteboard];
+bool ClipboardContainsBookmarksPrivate(NSPasteboard* pb) {
NSArray* availableTypes = [NSArray arrayWithObjects:
BookmarkDictionaryListPboardType,
WebURLsWithTitlesPboardType,
@@ -219,4 +253,63 @@ bool ClipboardContainsBookmarks() {
return [pb availableTypeFromArray:availableTypes] != nil;
}
+} // anonymous namespace
+
+namespace bookmark_pasteboard_helper_mac {
+
+void WriteToClipboard(const std::vector<BookmarkDragData::Element>& elements,
+ FilePath::StringType profile_path) {
+ NSPasteboard* pb = [NSPasteboard generalPasteboard];
+ WriteToClipboardPrivate(elements, pb, profile_path);
+}
+
+void WriteToDragClipboard(
+ const std::vector<BookmarkDragData::Element>& elements,
+ FilePath::StringType profile_path) {
+ NSPasteboard* pb = [NSPasteboard pasteboardWithName:NSDragPboard];
+ WriteToClipboardPrivate(elements, pb, profile_path);
+}
+
+bool ReadFromClipboard(std::vector<BookmarkDragData::Element>& elements,
+ FilePath::StringType* profile_path) {
+ NSPasteboard* pb = [NSPasteboard generalPasteboard];
+ return ReadFromClipboardPrivate(elements, pb, profile_path);
+}
+
+bool ReadFromDragClipboard(std::vector<BookmarkDragData::Element>& elements,
+ FilePath::StringType* profile_path) {
+ NSPasteboard* pb = [NSPasteboard pasteboardWithName:NSDragPboard];
+ return ReadFromClipboardPrivate(elements, pb, profile_path);
+}
+
+
+bool ClipboardContainsBookmarks() {
+ NSPasteboard* pb = [NSPasteboard generalPasteboard];
+ return ClipboardContainsBookmarksPrivate(pb);
+}
+
+bool DragClipboardContainsBookmarks() {
+ NSPasteboard* pb = [NSPasteboard pasteboardWithName:NSDragPboard];
+ return ClipboardContainsBookmarksPrivate(pb);
}
+
+void StartDrag(Profile* profile, const std::vector<const BookmarkNode*>& nodes,
+ gfx::NativeView view) {
+ DCHECK([view isKindOfClass:[TabContentsViewCocoa class]]);
+ TabContentsViewCocoa* tabView = static_cast<TabContentsViewCocoa*>(view);
+ std::vector<BookmarkDragData::Element> elements;
+ for (std::vector<const BookmarkNode*>::const_iterator it = nodes.begin();
+ it != nodes.end(); ++it) {
+ elements.push_back(BookmarkDragData::Element(*it));
+ }
+ NSPasteboard* pb = [NSPasteboard pasteboardWithName:NSDragPboard];
+ scoped_nsobject<BookmarkDragSource> source([[BookmarkDragSource alloc]
+ initWithContentsView:tabView
+ dropData:elements
+ profile:profile
+ pasteboard:pb
+ dragOperationMask:NSDragOperationEvery]);
+ [source startDrag];
+}
+
+} // namespace bookmark_pasteboard_helper_mac
diff --git a/chrome/browser/bookmarks/bookmark_utils.cc b/chrome/browser/bookmarks/bookmark_utils.cc
index 4aa14eb..e43c89d 100644
--- a/chrome/browser/bookmarks/bookmark_utils.cc
+++ b/chrome/browser/bookmarks/bookmark_utils.cc
@@ -15,6 +15,9 @@
#include "base/time.h"
#include "chrome/browser/bookmarks/bookmark_drag_data.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
+#if defined(OS_MACOSX)
+#include "chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.h"
+#endif
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_process.h"
@@ -252,31 +255,23 @@ int PerformBookmarkDrop(Profile* profile,
const BookmarkDragData& data,
const BookmarkNode* parent_node,
int index) {
- const std::vector<const BookmarkNode*> dragged_nodes = data.GetNodes(profile);
BookmarkModel* model = profile->GetBookmarkModel();
- if (!dragged_nodes.empty()) {
- // Drag from same profile. Move nodes.
- for (size_t i = 0; i < dragged_nodes.size(); ++i) {
- model->Move(dragged_nodes[i], parent_node, index);
- index = parent_node->IndexOfChild(dragged_nodes[i]) + 1;
- }
- return DragDropTypes::DRAG_MOVE;
- } else if (data.has_single_url()) {
- // New URL, add it at the specified location.
- string16 title = data.elements[0].title;
- if (title.empty()) {
- // No title, use the host.
- title = UTF8ToUTF16(data.elements[0].url.host());
- if (title.empty())
- title = TabContents::GetDefaultTitle();
+ if (data.IsFromProfile(profile)) {
+ const std::vector<const BookmarkNode*> dragged_nodes =
+ data.GetNodes(profile);
+ if (!dragged_nodes.empty()) {
+ // Drag from same profile. Move nodes.
+ for (size_t i = 0; i < dragged_nodes.size(); ++i) {
+ model->Move(dragged_nodes[i], parent_node, index);
+ index = parent_node->IndexOfChild(dragged_nodes[i]) + 1;
+ }
+ return DragDropTypes::DRAG_MOVE;
}
- model->AddURL(parent_node, index, title, data.elements[0].url);
- return DragDropTypes::DRAG_COPY | DragDropTypes::DRAG_LINK;
- } else {
- // Dropping a group from different profile. Always accept.
- bookmark_utils::CloneDragData(model, data.elements, parent_node, index);
- return DragDropTypes::DRAG_COPY;
+ return DragDropTypes::DRAG_NONE;
}
+ // Dropping a group from different profile. Always accept.
+ bookmark_utils::CloneDragData(model, data.elements, parent_node, index);
+ return DragDropTypes::DRAG_COPY;
}
bool IsValidDropLocation(Profile* profile,
@@ -348,8 +343,14 @@ void DragBookmarks(Profile* profile,
DragDropTypes::DRAG_LINK);
MessageLoop::current()->SetNestableTasksAllowed(was_nested);
+#elif defined(OS_MACOSX)
+ // Allow nested message loop so we get DnD events as we drag this around.
+ bool was_nested = MessageLoop::current()->IsNested();
+ MessageLoop::current()->SetNestableTasksAllowed(true);
+ bookmark_pasteboard_helper_mac::StartDrag(profile, nodes, view);
+ MessageLoop::current()->SetNestableTasksAllowed(was_nested);
#else
- // TODO(arv): Implement for GTK and Cocoa.
+ // TODO(arv): Implement for GTK.
NOTIMPLEMENTED();
#endif
}
diff --git a/chrome/browser/cocoa/bookmark_drag_source.h b/chrome/browser/cocoa/bookmark_drag_source.h
new file mode 100644
index 0000000..fde2086
--- /dev/null
+++ b/chrome/browser/cocoa/bookmark_drag_source.h
@@ -0,0 +1,30 @@
+// Copyright (c) 2010 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.
+
+#import <Cocoa/Cocoa.h>
+
+#include "chrome/browser/bookmarks/bookmark_drag_data.h"
+#include "chrome/browser/cocoa/web_contents_drag_source.h"
+
+// A class that handles tracking and event processing for a drag and drop
+// originating from the content area.
+@interface BookmarkDragSource : WebContentsDragSource {
+ @private
+ // Our drop data. Should only be initialized once.
+ std::vector<BookmarkDragData::Element> dropData_;
+
+ Profile* profile_;
+}
+
+// Initialize a DragDataSource object for a drag (originating on the given
+// contentsView and with the given dropData and pboard). Fill the pasteboard
+// with data types appropriate for dropData.
+- (id)initWithContentsView:(TabContentsViewCocoa*)contentsView
+ dropData:
+ (const std::vector<BookmarkDragData::Element>&)dropData
+ profile:(Profile*)profile
+ pasteboard:(NSPasteboard*)pboard
+ dragOperationMask:(NSDragOperation)dragOperationMask;
+
+@end
diff --git a/chrome/browser/cocoa/bookmark_drag_source.mm b/chrome/browser/cocoa/bookmark_drag_source.mm
new file mode 100644
index 0000000..81e55e6
--- /dev/null
+++ b/chrome/browser/cocoa/bookmark_drag_source.mm
@@ -0,0 +1,43 @@
+// Copyright (c) 2010 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.
+
+#import "chrome/browser/cocoa/bookmark_drag_source.h"
+
+#include "chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.h"
+#include "chrome/browser/profile.h"
+#include "chrome/browser/tab_contents/tab_contents_view_mac.h"
+
+@implementation BookmarkDragSource
+
+- (id)initWithContentsView:(TabContentsViewCocoa*)contentsView
+ dropData:
+ (const std::vector<BookmarkDragData::Element>&)dropData
+ profile:(Profile*)profile
+ pasteboard:(NSPasteboard*)pboard
+ dragOperationMask:(NSDragOperation)dragOperationMask {
+ self = [super initWithContentsView:contentsView
+ pasteboard:pboard
+ dragOperationMask:dragOperationMask];
+ if (self) {
+ dropData_ = dropData;
+ profile_ = profile;
+ }
+
+ return self;
+}
+
+- (void)fillPasteboard {
+ bookmark_pasteboard_helper_mac::WriteToDragClipboard(dropData_,
+ profile_->GetPath().value());
+}
+
+- (NSImage*)dragImage {
+ // TODO(feldstein): Do something better than this. Should have badging
+ // and a single drag image.
+ // http://crbug.com/37264
+ return [NSImage imageNamed:NSImageNameMultipleDocuments];
+}
+
+@end // @implementation BookmarkDragSource
+
diff --git a/chrome/browser/cocoa/web_contents_drag_source.h b/chrome/browser/cocoa/web_contents_drag_source.h
new file mode 100644
index 0000000..8d451ea
--- /dev/null
+++ b/chrome/browser/cocoa/web_contents_drag_source.h
@@ -0,0 +1,65 @@
+// Copyright (c) 2010 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_COCOA_WEB_CONTENTS_DRAG_SOURCE_H_
+#define CHROME_BROWSER_COCOA_WEB_CONTENTS_DRAG_SOURCE_H_
+
+#import <Cocoa/Cocoa.h>
+
+#include "app/download_file_interface.h"
+#include "base/file_path.h"
+#include "base/scoped_nsobject.h"
+#include "base/scoped_ptr.h"
+#include "chrome/browser/bookmarks/bookmark_drag_data.h"
+
+@class TabContentsViewCocoa;
+
+// A class that handles tracking and event processing for a drag and drop
+// originating from the content area. Subclasses should implement
+// fillClipboard and dragImage.
+@interface WebContentsDragSource : NSObject {
+ @private
+ // Our tab. Weak reference (owns or co-owns us).
+ TabContentsViewCocoa* contentsView_;
+
+ // Our pasteboard.
+ scoped_nsobject<NSPasteboard> pasteboard_;
+
+ // A mask of the allowed drag operations.
+ NSDragOperation dragOperationMask_;
+}
+
+// Initialize a DragDataSource object for a drag (originating on the given
+// contentsView and with the given dropData and pboard). Fill the pasteboard
+// with data types appropriate for dropData.
+- (id)initWithContentsView:(TabContentsViewCocoa*)contentsView
+ pasteboard:(NSPasteboard*)pboard
+ dragOperationMask:(NSDragOperation)dragOperationMask;
+
+// Creates the drag image. Implemented by the subclass.
+- (NSImage*)dragImage;
+
+// Put the data being dragged onto the pasteboard. Implemented by the
+// subclass.
+- (void)fillPasteboard;
+
+// Returns a mask of the allowed drag operations.
+- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal;
+
+// Start the drag (on the originally provided contentsView); can do this right
+// after -initWithContentsView:....
+- (void)startDrag;
+
+// End the drag and clear the pasteboard; hook up to
+// -draggedImage:endedAt:operation:.
+- (void)endDragAt:(NSPoint)screenPoint
+ operation:(NSDragOperation)operation;
+
+// Drag moved; hook up to -draggedImage:movedTo:.
+- (void)moveDragTo:(NSPoint)screenPoint;
+
+@end
+
+#endif // define CHROME_BROWSER_COCOA_WEB_CONTENTS_DRAG_SOURCE_H_
+
diff --git a/chrome/browser/cocoa/web_contents_drag_source.mm b/chrome/browser/cocoa/web_contents_drag_source.mm
new file mode 100644
index 0000000..8bc883c
--- /dev/null
+++ b/chrome/browser/cocoa/web_contents_drag_source.mm
@@ -0,0 +1,131 @@
+// Copyright (c) 2010 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.
+
+#import "chrome/browser/cocoa/web_contents_drag_source.h"
+
+#include "base/file_path.h"
+#include "base/nsimage_cache_mac.h"
+#include "base/string_util.h"
+#include "base/sys_string_conversions.h"
+#include "chrome/browser/renderer_host/render_view_host.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/tab_contents/tab_contents_view_mac.h"
+
+namespace {
+
+// Make a drag image from the drop data.
+// TODO(feldstein): Make this work
+NSImage* MakeDragImage() {
+ // TODO(feldstein): Just a stub for now. Make it do something (see, e.g.,
+ // WebKit/WebKit/mac/Misc/WebNSViewExtras.m: |-_web_DragImageForElement:...|).
+
+ // Default to returning a generic image.
+ return nsimage_cache::ImageNamed(@"nav.pdf");
+}
+
+// Flips screen and point coordinates over the y axis to work with webkit
+// coordinate systems.
+void FlipPointCoordinates(NSPoint& screenPoint,
+ NSPoint& localPoint,
+ NSView* view) {
+ NSRect viewFrame = [view frame];
+ localPoint.y = NSHeight(viewFrame) - localPoint.y;
+ // Flip |screenPoint|.
+ NSRect screenFrame = [[[view window] screen] frame];
+ screenPoint.y = NSHeight(screenFrame) - screenPoint.y;
+}
+
+} // namespace
+
+
+@implementation WebContentsDragSource
+
+- (id)initWithContentsView:(TabContentsViewCocoa*)contentsView
+ pasteboard:(NSPasteboard*)pboard
+ dragOperationMask:(NSDragOperation)dragOperationMask {
+ if ((self = [super init])) {
+ contentsView_ = contentsView;
+ DCHECK(contentsView_);
+
+ pasteboard_.reset([pboard retain]);
+ DCHECK(pasteboard_.get());
+
+ dragOperationMask_ = dragOperationMask;
+ }
+
+ return self;
+}
+
+- (NSImage*)dragImage {
+ return MakeDragImage();
+}
+
+- (void)fillPasteboard {
+ NOTIMPLEMENTED() << "Subclasses should implement fillPasteboard";
+}
+
+- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal {
+ return dragOperationMask_;
+}
+
+- (void)startDrag {
+ [self fillPasteboard];
+ NSEvent* currentEvent = [NSApp currentEvent];
+
+ // Synthesize an event for dragging, since we can't be sure that
+ // [NSApp currentEvent] will return a valid dragging event.
+ NSWindow* window = [contentsView_ window];
+ NSPoint position = [window mouseLocationOutsideOfEventStream];
+ NSTimeInterval eventTime = [currentEvent timestamp];
+ NSEvent* dragEvent = [NSEvent mouseEventWithType:NSLeftMouseDragged
+ location:position
+ modifierFlags:NSLeftMouseDraggedMask
+ timestamp:eventTime
+ windowNumber:[window windowNumber]
+ context:nil
+ eventNumber:0
+ clickCount:1
+ pressure:1.0];
+ [window dragImage:[self dragImage]
+ at:position
+ offset:NSZeroSize
+ event:dragEvent
+ pasteboard:pasteboard_
+ source:self
+ slideBack:YES];
+}
+
+- (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint
+ operation:(NSDragOperation)operation {
+}
+
+- (void)endDragAt:(NSPoint)screenPoint
+ operation:(NSDragOperation)operation {
+ RenderViewHost* rvh = [contentsView_ tabContents]->render_view_host();
+ if (rvh) {
+ rvh->DragSourceSystemDragEnded();
+
+ NSPoint localPoint = [contentsView_ convertPoint:screenPoint fromView: nil];
+ FlipPointCoordinates(screenPoint, localPoint, contentsView_);
+ rvh->DragSourceEndedAt(localPoint.x, localPoint.y,
+ screenPoint.x, screenPoint.y,
+ static_cast<WebKit::WebDragOperation>(operation));
+ }
+
+ // Make sure the pasteboard owner isn't us.
+ [pasteboard_ declareTypes:[NSArray array] owner:nil];
+}
+
+- (void)moveDragTo:(NSPoint)screenPoint {
+ RenderViewHost* rvh = [contentsView_ tabContents]->render_view_host();
+ if (rvh) {
+ NSPoint localPoint = [contentsView_ convertPoint:screenPoint fromView:nil];
+ FlipPointCoordinates(screenPoint, localPoint, contentsView_);
+ rvh->DragSourceMovedTo(localPoint.x, localPoint.y,
+ screenPoint.x, screenPoint.y);
+ }
+}
+
+@end // @implementation WebContentsDragSource
+
diff --git a/chrome/browser/cocoa/web_drop_target.mm b/chrome/browser/cocoa/web_drop_target.mm
index fa08c69..06e0a98 100644
--- a/chrome/browser/cocoa/web_drop_target.mm
+++ b/chrome/browser/cocoa/web_drop_target.mm
@@ -5,6 +5,7 @@
#import "chrome/browser/cocoa/web_drop_target.h"
#include "base/sys_string_conversions.h"
+#include "chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#import "third_party/mozilla/include/NSPasteboard+Utils.h"
@@ -78,6 +79,12 @@ using WebKit::WebDragOperationsMask;
return NSDragOperationNone;
}
+ // If the tab is showing the boomark manager, send BookmarkDrag events
+ RenderViewHostDelegate::BookmarkDrag* dragDelegate =
+ tabContents_->GetBookmarkDragDelegate();
+ if(dragDelegate)
+ dragDelegate->OnDragEnter(NULL);
+
// Fill out a WebDropData from pasteboard.
WebDropData data;
[self populateWebDropData:&data fromPasteboard:[info draggingPasteboard]];
@@ -132,6 +139,11 @@ using WebKit::WebDragOperationsMask;
gfx::Point(screenPoint.x, screenPoint.y),
static_cast<WebDragOperationsMask>(mask));
+ // If the tab is showing the boomark manager, send BookmarkDrag events
+ RenderViewHostDelegate::BookmarkDrag* dragDelegate =
+ tabContents_->GetBookmarkDragDelegate();
+ if(dragDelegate)
+ dragDelegate->OnDragOver(NULL);
return current_operation_;
}
@@ -153,6 +165,12 @@ using WebKit::WebDragOperationsMask;
return NO;
}
+ // If the tab is showing the boomark manager, send BookmarkDrag events
+ RenderViewHostDelegate::BookmarkDrag* dragDelegate =
+ tabContents_->GetBookmarkDragDelegate();
+ if(dragDelegate)
+ dragDelegate->OnDrop(NULL);
+
currentRVH_ = NULL;
// Create the appropriate mouse locations for WebCore. The draggingLocation
diff --git a/chrome/browser/extensions/extension_bookmark_manager_api.cc b/chrome/browser/extensions/extension_bookmark_manager_api.cc
index e397111..f12e62f 100644
--- a/chrome/browser/extensions/extension_bookmark_manager_api.cc
+++ b/chrome/browser/extensions/extension_bookmark_manager_api.cc
@@ -143,6 +143,8 @@ bool GetBookmarkDragData(const DragData* data,
#if defined(TOOLKIT_VIEWS)
// On TOOLKIT_VIEWS DragData is OSExchangeData.
return bookmark_drag_data->Read(*data);
+#elif defined(OS_MACOSX)
+ return bookmark_drag_data->ReadFromDragClipboard();
#else
NOTIMPLEMENTED();
return false;