diff options
author | feldstein@chromium.org <feldstein@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-07 03:43:51 +0000 |
---|---|---|
committer | feldstein@chromium.org <feldstein@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-07 03:43:51 +0000 |
commit | eda74d6837b1d8915a15f1a0598d1ce3c99b5cb0 (patch) | |
tree | 22f0a72166f5f9b34e37974489b991319ec16baf /chrome/browser | |
parent | c3c91a64cba4f083f0aed48a7c4719303dd89e7d (diff) | |
download | chromium_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.cc | 10 | ||||
-rw-r--r-- | chrome/browser/bookmarks/bookmark_drag_data.h | 12 | ||||
-rw-r--r-- | chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.h | 37 | ||||
-rw-r--r-- | chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.mm | 165 | ||||
-rw-r--r-- | chrome/browser/bookmarks/bookmark_utils.cc | 47 | ||||
-rw-r--r-- | chrome/browser/cocoa/bookmark_drag_source.h | 30 | ||||
-rw-r--r-- | chrome/browser/cocoa/bookmark_drag_source.mm | 43 | ||||
-rw-r--r-- | chrome/browser/cocoa/web_contents_drag_source.h | 65 | ||||
-rw-r--r-- | chrome/browser/cocoa/web_contents_drag_source.mm | 131 | ||||
-rw-r--r-- | chrome/browser/cocoa/web_drop_target.mm | 18 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_bookmark_manager_api.cc | 2 |
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; |