summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-18 17:10:18 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-18 17:10:18 +0000
commit2ca8a064a206fba910dc0f50f8a2f2509828d8f1 (patch)
tree9e128f90d2392b901aca101baabe12dd36621943 /chrome/browser
parent911f815112d8d11778c771467fbef2c2b1f8e160 (diff)
downloadchromium_src-2ca8a064a206fba910dc0f50f8a2f2509828d8f1.zip
chromium_src-2ca8a064a206fba910dc0f50f8a2f2509828d8f1.tar.gz
chromium_src-2ca8a064a206fba910dc0f50f8a2f2509828d8f1.tar.bz2
GTK: implement extension bookmark manager drag api.
Also, cross-platform: eschew RenderViewHostDelegate:BookmarkDrag::DragData type in favor of BookmarkDragData. BUG=37702 TEST=manual Review URL: http://codereview.chromium.org/1029004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@41959 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/bookmarks/bookmark_drag_data.cc26
-rw-r--r--chrome/browser/bookmarks/bookmark_drag_data.h8
-rw-r--r--chrome/browser/bookmarks/bookmark_utils.cc7
-rw-r--r--chrome/browser/cocoa/web_drop_target.mm16
-rw-r--r--chrome/browser/download/download_util.cc2
-rw-r--r--chrome/browser/extensions/extension_bookmark_manager_api.cc45
-rw-r--r--chrome/browser/extensions/extension_bookmark_manager_api.h11
-rw-r--r--chrome/browser/gtk/bookmark_bar_gtk.cc7
-rw-r--r--chrome/browser/gtk/bookmark_manager_gtk.cc10
-rw-r--r--chrome/browser/gtk/bookmark_utils_gtk.cc22
-rw-r--r--chrome/browser/gtk/bookmark_utils_gtk.h4
-rw-r--r--chrome/browser/gtk/custom_drag.cc134
-rw-r--r--chrome/browser/gtk/custom_drag.h95
-rw-r--r--chrome/browser/gtk/download_item_drag.cc83
-rw-r--r--chrome/browser/gtk/download_item_drag.h43
-rw-r--r--chrome/browser/gtk/download_item_gtk.cc2
-rw-r--r--chrome/browser/renderer_host/render_view_host_delegate.h20
-rw-r--r--chrome/browser/tab_contents/web_drag_dest_gtk.cc34
-rw-r--r--chrome/browser/tab_contents/web_drag_dest_gtk.h7
-rw-r--r--chrome/browser/tab_contents/web_drop_target_win.cc17
20 files changed, 376 insertions, 217 deletions
diff --git a/chrome/browser/bookmarks/bookmark_drag_data.cc b/chrome/browser/bookmarks/bookmark_drag_data.cc
index 3491d06..d722659 100644
--- a/chrome/browser/bookmarks/bookmark_drag_data.cc
+++ b/chrome/browser/bookmarks/bookmark_drag_data.cc
@@ -89,8 +89,20 @@ BookmarkDragData::BookmarkDragData(const BookmarkNode* node) {
BookmarkDragData::BookmarkDragData(
const std::vector<const BookmarkNode*>& nodes) {
+ ReadFromVector(nodes);
+}
+
+bool BookmarkDragData::ReadFromVector(
+ const std::vector<const BookmarkNode*>& nodes) {
+ Clear();
+
+ if (nodes.empty())
+ return false;
+
for (size_t i = 0; i < nodes.size(); ++i)
elements.push_back(Element(nodes[i]));
+
+ return true;
}
#if !defined(OS_MACOSX)
@@ -272,12 +284,14 @@ void BookmarkDragData::Clear() {
elements.clear();
}
+void BookmarkDragData::SetOriginatingProfile(Profile* profile) {
+ DCHECK(profile_path_.empty());
+
+ if (profile)
+ profile_path_ = profile->GetPath().value();
+}
+
bool BookmarkDragData::IsFromProfile(Profile* profile) const {
// An empty path means the data is not associated with any profile.
- return (!profile_path_.empty() &&
-#if defined(WCHAR_T_IS_UTF16)
- profile->GetPath().ToWStringHack() == profile_path_);
-#elif defined(WCHAR_T_IS_UTF32)
- profile->GetPath().value() == profile_path_);
-#endif
+ return !profile_path_.empty() && profile_path_ == profile->GetPath().value();
}
diff --git a/chrome/browser/bookmarks/bookmark_drag_data.h b/chrome/browser/bookmarks/bookmark_drag_data.h
index e26c362..7f007a2 100644
--- a/chrome/browser/bookmarks/bookmark_drag_data.h
+++ b/chrome/browser/bookmarks/bookmark_drag_data.h
@@ -86,6 +86,9 @@ struct BookmarkDragData {
explicit BookmarkDragData(const BookmarkNode* node);
explicit BookmarkDragData(const std::vector<const BookmarkNode*>& nodes);
+ // Reads bookmarks from the given vector.
+ bool ReadFromVector(const std::vector<const BookmarkNode*>& nodes);
+
// Writes elements to the clipboard.
void WriteToClipboard(Profile* profile) const;
@@ -138,6 +141,11 @@ struct BookmarkDragData {
// Clears the data.
void Clear();
+ // Sets |profile_path_| to that of |profile|. This is useful for the
+ // constructors/readers that don't set it. This should only be called if the
+ // profile path is not already set.
+ void SetOriginatingProfile(Profile* profile);
+
// Returns true if this data is from the specified profile.
bool IsFromProfile(Profile* profile) const;
diff --git a/chrome/browser/bookmarks/bookmark_utils.cc b/chrome/browser/bookmarks/bookmark_utils.cc
index c31b821..cda4ef0 100644
--- a/chrome/browser/bookmarks/bookmark_utils.cc
+++ b/chrome/browser/bookmarks/bookmark_utils.cc
@@ -40,6 +40,8 @@
#include "views/drag_utils.h"
#include "views/widget/root_view.h"
#include "views/widget/widget.h"
+#elif defined(TOOLKIT_GTK)
+#include "chrome/browser/gtk/custom_drag.h"
#endif
using base::Time;
@@ -352,9 +354,8 @@ void DragBookmarks(Profile* profile,
MessageLoop::current()->SetNestableTasksAllowed(true);
bookmark_pasteboard_helper_mac::StartDrag(profile, nodes, view);
MessageLoop::current()->SetNestableTasksAllowed(was_nested);
-#else
- // TODO(arv): Implement for GTK.
- NOTIMPLEMENTED();
+#elif defined(TOOLKIT_GTK)
+ BookmarkDrag::BeginDrag(profile, nodes);
#endif
}
diff --git a/chrome/browser/cocoa/web_drop_target.mm b/chrome/browser/cocoa/web_drop_target.mm
index 06e0a98..b051772 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_drag_data.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"
@@ -82,8 +83,9 @@ using WebKit::WebDragOperationsMask;
// If the tab is showing the boomark manager, send BookmarkDrag events
RenderViewHostDelegate::BookmarkDrag* dragDelegate =
tabContents_->GetBookmarkDragDelegate();
- if(dragDelegate)
- dragDelegate->OnDragEnter(NULL);
+ BookmarkDragData dragData;
+ if(dragDelegate && dragData.ReadFromDragClipboard())
+ dragDelegate->OnDragEnter(dragData);
// Fill out a WebDropData from pasteboard.
WebDropData data;
@@ -142,8 +144,9 @@ using WebKit::WebDragOperationsMask;
// If the tab is showing the boomark manager, send BookmarkDrag events
RenderViewHostDelegate::BookmarkDrag* dragDelegate =
tabContents_->GetBookmarkDragDelegate();
- if(dragDelegate)
- dragDelegate->OnDragOver(NULL);
+ BookmarkDragData dragData;
+ if(dragDelegate && dragData.ReadFromDragClipboard())
+ dragDelegate->OnDragOver(dragData);
return current_operation_;
}
@@ -168,8 +171,9 @@ using WebKit::WebDragOperationsMask;
// If the tab is showing the boomark manager, send BookmarkDrag events
RenderViewHostDelegate::BookmarkDrag* dragDelegate =
tabContents_->GetBookmarkDragDelegate();
- if(dragDelegate)
- dragDelegate->OnDrop(NULL);
+ BookmarkDragData dragData;
+ if(dragDelegate && dragData.ReadFromDragClipboard())
+ dragDelegate->OnDrop(dragData);
currentRVH_ = NULL;
diff --git a/chrome/browser/download/download_util.cc b/chrome/browser/download/download_util.cc
index 6aa33e1..6d83c8f 100644
--- a/chrome/browser/download/download_util.cc
+++ b/chrome/browser/download/download_util.cc
@@ -43,7 +43,7 @@
#include "app/drag_drop_types.h"
#include "views/widget/widget_gtk.h"
#elif defined(TOOLKIT_GTK)
-#include "chrome/browser/gtk/download_item_drag.h"
+#include "chrome/browser/gtk/custom_drag.h"
#endif // defined(TOOLKIT_GTK)
#endif // defined(OS_LINUX)
diff --git a/chrome/browser/extensions/extension_bookmark_manager_api.cc b/chrome/browser/extensions/extension_bookmark_manager_api.cc
index f12e62f..5c589ba 100644
--- a/chrome/browser/extensions/extension_bookmark_manager_api.cc
+++ b/chrome/browser/extensions/extension_bookmark_manager_api.cc
@@ -27,8 +27,6 @@ namespace keys = extension_bookmarks_module_constants;
namespace {
-typedef RenderViewHostDelegate::BookmarkDrag::DragData DragData;
-
// Returns a single bookmark node from the argument ID.
// This returns NULL in case of failure.
const BookmarkNode* GetNodeFromArguments(BookmarkModel* model,
@@ -136,21 +134,6 @@ void BookmarkDragDataToJSON(Profile* profile, const BookmarkDragData& data,
args->Append(value);
}
-// This is the platform specific function that takes the drag data and creates
-// the BookmarkDragData as needed.
-bool GetBookmarkDragData(const DragData* data,
- BookmarkDragData* bookmark_drag_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;
-#endif
-}
-
} // namespace
ExtensionBookmarkManagerEventRouter::ExtensionBookmarkManagerEventRouter(
@@ -177,34 +160,38 @@ void ExtensionBookmarkManagerEventRouter::DispatchEvent(const char* event_name,
}
void ExtensionBookmarkManagerEventRouter::DispatchDragEvent(
- const DragData* data, const char* event_name) {
- BookmarkDragData bookmark_drag_data;
- if (::GetBookmarkDragData(data, &bookmark_drag_data)) {
- ListValue args;
- BookmarkDragDataToJSON(profile_, bookmark_drag_data, &args);
- DispatchEvent(event_name, &args);
- }
+ const BookmarkDragData& data, const char* event_name) {
+ if (data.size() == 0)
+ return;
+
+ ListValue args;
+ BookmarkDragDataToJSON(profile_, data, &args);
+ DispatchEvent(event_name, &args);
}
-void ExtensionBookmarkManagerEventRouter::OnDragEnter(const DragData* data) {
+void ExtensionBookmarkManagerEventRouter::OnDragEnter(
+ const BookmarkDragData& data) {
DispatchDragEvent(data, keys::kOnBookmarkDragEnter);
}
-void ExtensionBookmarkManagerEventRouter::OnDragOver(const DragData* data) {
+void ExtensionBookmarkManagerEventRouter::OnDragOver(
+ const BookmarkDragData& data) {
// Intentionally empty since these events happens too often and floods the
// message queue. We do not need this event for the bookmark manager anyway.
}
-void ExtensionBookmarkManagerEventRouter::OnDragLeave(const DragData* data) {
+void ExtensionBookmarkManagerEventRouter::OnDragLeave(
+ const BookmarkDragData& data) {
DispatchDragEvent(data, keys::kOnBookmarkDragLeave);
}
-void ExtensionBookmarkManagerEventRouter::OnDrop(const DragData* data) {
+void ExtensionBookmarkManagerEventRouter::OnDrop(
+ const BookmarkDragData& data) {
DispatchDragEvent(data, keys::kOnBookmarkDrop);
// Make a copy that is owned by this instance.
ClearBookmarkDragData();
- ::GetBookmarkDragData(data, &bookmark_drag_data_);
+ bookmark_drag_data_ = data;
}
const BookmarkDragData*
diff --git a/chrome/browser/extensions/extension_bookmark_manager_api.h b/chrome/browser/extensions/extension_bookmark_manager_api.h
index 3ab9964..b15e07c 100644
--- a/chrome/browser/extensions/extension_bookmark_manager_api.h
+++ b/chrome/browser/extensions/extension_bookmark_manager_api.h
@@ -11,6 +11,7 @@
#include "chrome/browser/renderer_host/render_view_host_delegate.h"
#include "chrome/browser/shell_dialogs.h"
+struct BookmarkDragData;
class BookmarkNode;
class ListValue;
class Profile;
@@ -25,10 +26,10 @@ class ExtensionBookmarkManagerEventRouter
virtual ~ExtensionBookmarkManagerEventRouter();
// RenderViewHostDelegate::BookmarkDrag interface
- virtual void OnDragEnter(const DragData* data);
- virtual void OnDragOver(const DragData* data);
- virtual void OnDragLeave(const DragData* data);
- virtual void OnDrop(const DragData* data);
+ virtual void OnDragEnter(const BookmarkDragData& data);
+ virtual void OnDragOver(const BookmarkDragData& data);
+ virtual void OnDragLeave(const BookmarkDragData& data);
+ virtual void OnDrop(const BookmarkDragData& data);
// The bookmark drag and drop data. This gets set after a drop was done on
// the page. This returns NULL if no data is available.
@@ -41,7 +42,7 @@ class ExtensionBookmarkManagerEventRouter
// Helper to actually dispatch an event to extension listeners.
void DispatchEvent(const char* event_name, const ListValue* args);
- void DispatchDragEvent(const DragData* data, const char* event_name);
+ void DispatchDragEvent(const BookmarkDragData& data, const char* event_name);
Profile* profile_;
TabContents* tab_contents_;
diff --git a/chrome/browser/gtk/bookmark_bar_gtk.cc b/chrome/browser/gtk/bookmark_bar_gtk.cc
index 2ae1421..c1054ab 100644
--- a/chrome/browser/gtk/bookmark_bar_gtk.cc
+++ b/chrome/browser/gtk/bookmark_bar_gtk.cc
@@ -837,12 +837,7 @@ GtkWidget* BookmarkBarGtk::CreateBookmarkButton(const BookmarkNode* node) {
// The tool item is also a source for dragging
gtk_drag_source_set(button, GDK_BUTTON1_MASK, NULL, 0,
static_cast<GdkDragAction>(GDK_ACTION_MOVE | GDK_ACTION_COPY));
- int target_mask = gtk_dnd_util::CHROME_BOOKMARK_ITEM;
- if (node->is_url()) {
- target_mask |= gtk_dnd_util::TEXT_URI_LIST |
- gtk_dnd_util::TEXT_PLAIN |
- gtk_dnd_util::NETSCAPE_URL;
- }
+ int target_mask = bookmark_utils::GetCodeMask(node->is_folder());
gtk_dnd_util::SetSourceTargetListFromCodeMask(button, target_mask);
g_signal_connect(button, "drag-begin",
G_CALLBACK(&OnButtonDragBeginThunk), this);
diff --git a/chrome/browser/gtk/bookmark_manager_gtk.cc b/chrome/browser/gtk/bookmark_manager_gtk.cc
index b023a44c..848b306 100644
--- a/chrome/browser/gtk/bookmark_manager_gtk.cc
+++ b/chrome/browser/gtk/bookmark_manager_gtk.cc
@@ -60,12 +60,6 @@ const int kDefaultColumnWidth = 200;
// The destination targets that the right tree view accepts for dragging.
const int kDestTargetList[] = { gtk_dnd_util::CHROME_BOOKMARK_ITEM, -1 };
-// The source targets that the right tree view supports for dragging.
-const int kSourceTargetMask = gtk_dnd_util::CHROME_BOOKMARK_ITEM |
- gtk_dnd_util::TEXT_URI_LIST |
- gtk_dnd_util::TEXT_PLAIN |
- gtk_dnd_util::NETSCAPE_URL;
-
// We only have one manager open at a time.
BookmarkManagerGtk* manager = NULL;
@@ -559,7 +553,7 @@ GtkWidget* BookmarkManagerGtk::MakeRightPane() {
static_cast<GdkDragAction>(GDK_ACTION_MOVE | GDK_ACTION_COPY |
GDK_ACTION_LINK));
gtk_dnd_util::SetSourceTargetListFromCodeMask(
- right_tree_view_, kSourceTargetMask);
+ right_tree_view_, bookmark_utils::GetCodeMask(false));
// We connect to drag dest signals, but we don't actually enable the widget
// as a drag destination unless it corresponds to the contents of a folder.
@@ -1301,7 +1295,7 @@ gboolean BookmarkManagerGtk::OnRightTreeViewMotion(
static_cast<gint>(event->y))) {
bm->delaying_mousedown_ = false;
GtkTargetList* targets = gtk_dnd_util::GetTargetListFromCodeMask(
- kSourceTargetMask);
+ bookmark_utils::GetCodeMask(false));
gtk_drag_begin(tree_view, targets, GDK_ACTION_MOVE,
1, reinterpret_cast<GdkEvent*>(event));
// The drag adds a ref; let it own the list.
diff --git a/chrome/browser/gtk/bookmark_utils_gtk.cc b/chrome/browser/gtk/bookmark_utils_gtk.cc
index 73b3feda..c15c9fb 100644
--- a/chrome/browser/gtk/bookmark_utils_gtk.cc
+++ b/chrome/browser/gtk/bookmark_utils_gtk.cc
@@ -198,6 +198,16 @@ void SetButtonTextColors(GtkWidget* label, GtkThemeProvider* provider) {
// DnD-related -----------------------------------------------------------------
+int GetCodeMask(bool folder) {
+ int rv = gtk_dnd_util::CHROME_BOOKMARK_ITEM;
+ if (!folder) {
+ rv |= gtk_dnd_util::TEXT_URI_LIST |
+ gtk_dnd_util::TEXT_PLAIN |
+ gtk_dnd_util::NETSCAPE_URL;
+ }
+ return rv;
+}
+
void WriteBookmarkToSelection(const BookmarkNode* node,
GtkSelectionData* selection_data,
guint target_type,
@@ -272,17 +282,19 @@ std::vector<const BookmarkNode*> GetNodesFromSelection(
Profile* profile,
gboolean* delete_selection_data,
gboolean* dnd_success) {
- *delete_selection_data = FALSE;
- *dnd_success = FALSE;
+ if (delete_selection_data)
+ *delete_selection_data = FALSE;
+ if (dnd_success)
+ *dnd_success = FALSE;
if ((selection_data != NULL) && (selection_data->length >= 0)) {
- if (context->action == GDK_ACTION_MOVE) {
+ if (context && delete_selection_data && context->action == GDK_ACTION_MOVE)
*delete_selection_data = TRUE;
- }
switch (target_type) {
case gtk_dnd_util::CHROME_BOOKMARK_ITEM: {
- *dnd_success = TRUE;
+ if (dnd_success)
+ *dnd_success = TRUE;
Pickle pickle(reinterpret_cast<char*>(selection_data->data),
selection_data->length);
BookmarkDragData drag_data;
diff --git a/chrome/browser/gtk/bookmark_utils_gtk.h b/chrome/browser/gtk/bookmark_utils_gtk.h
index de56039..012ce96 100644
--- a/chrome/browser/gtk/bookmark_utils_gtk.h
+++ b/chrome/browser/gtk/bookmark_utils_gtk.h
@@ -48,6 +48,10 @@ void SetButtonTextColors(GtkWidget* label, GtkThemeProvider* provider);
// Drag and drop. --------------------------------------------------------------
+// Get the DnD target mask for a bookmark drag. This will vary based on whether
+// the node in question is a folder.
+int GetCodeMask(bool folder);
+
// Pickle a node into a GtkSelection.
void WriteBookmarkToSelection(const BookmarkNode* node,
GtkSelectionData* selection_data,
diff --git a/chrome/browser/gtk/custom_drag.cc b/chrome/browser/gtk/custom_drag.cc
new file mode 100644
index 0000000..7cff653
--- /dev/null
+++ b/chrome/browser/gtk/custom_drag.cc
@@ -0,0 +1,134 @@
+// 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.
+
+#include "chrome/browser/gtk/custom_drag.h"
+
+#include "app/gtk_dnd_util.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/browser/download/download_manager.h"
+#include "chrome/browser/gtk/bookmark_utils_gtk.h"
+#include "gfx/gtk_util.h"
+#include "googleurl/src/gurl.h"
+#include "net/base/net_util.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+
+namespace {
+
+const int kDownloadItemCodeMask = gtk_dnd_util::TEXT_URI_LIST |
+ gtk_dnd_util::CHROME_NAMED_URL;
+const GdkDragAction kDownloadItemDragAction = GDK_ACTION_COPY;
+const GdkDragAction kBookmarkDragAction = GDK_ACTION_COPY;
+
+void OnDragDataGetForDownloadItem(GtkSelectionData* selection_data,
+ guint target_type,
+ const DownloadItem* download_item) {
+ GURL url = net::FilePathToFileURL(download_item->full_path());
+ gtk_dnd_util::WriteURLWithName(selection_data, url,
+ UTF8ToUTF16(download_item->GetFileName().value()), target_type);
+}
+
+void OnDragDataGetStandalone(GtkWidget* widget, GdkDragContext* context,
+ GtkSelectionData* selection_data,
+ guint target_type, guint time,
+ const DownloadItem* item) {
+ OnDragDataGetForDownloadItem(selection_data, target_type, item);
+}
+
+} // namespace
+
+// CustomDrag ------------------------------------------------------------------
+
+CustomDrag::CustomDrag(SkBitmap* icon, int code_mask, GdkDragAction action)
+ : drag_widget_(gtk_invisible_new()),
+ pixbuf_(icon ? gfx::GdkPixbufFromSkBitmap(icon) : NULL) {
+ g_object_ref_sink(drag_widget_);
+ g_signal_connect(drag_widget_, "drag-data-get",
+ G_CALLBACK(OnDragDataGetThunk), this);
+ g_signal_connect(drag_widget_, "drag-begin",
+ G_CALLBACK(OnDragBeginThunk), this);
+ g_signal_connect(drag_widget_, "drag-end",
+ G_CALLBACK(OnDragEndThunk), this);
+
+ GtkTargetList* list = gtk_dnd_util::GetTargetListFromCodeMask(code_mask);
+ GdkEvent* event = gtk_get_current_event();
+ gtk_drag_begin(drag_widget_, list, action, 1, event);
+ if (event)
+ gdk_event_free(event);
+ gtk_target_list_unref(list);
+}
+
+CustomDrag::~CustomDrag() {
+ if (pixbuf_)
+ g_object_unref(pixbuf_);
+ g_object_unref(drag_widget_);
+}
+
+void CustomDrag::OnDragBegin(GtkWidget* widget, GdkDragContext* drag_context) {
+ if (pixbuf_)
+ gtk_drag_set_icon_pixbuf(drag_context, pixbuf_, 0, 0);
+}
+
+void CustomDrag::OnDragEnd(GtkWidget* widget, GdkDragContext* drag_context) {
+ delete this;
+}
+
+// DownloadItemDrag ------------------------------------------------------------
+
+DownloadItemDrag::DownloadItemDrag(const DownloadItem* item,
+ SkBitmap* icon)
+ : CustomDrag(icon, kDownloadItemCodeMask, kDownloadItemDragAction),
+ download_item_(item) {
+}
+
+DownloadItemDrag::~DownloadItemDrag() {
+}
+
+void DownloadItemDrag::OnDragDataGet(
+ GtkWidget* widget, GdkDragContext* context,
+ GtkSelectionData* selection_data,
+ guint target_type, guint time) {
+ OnDragDataGetForDownloadItem(selection_data, target_type, download_item_);
+}
+
+// static
+void DownloadItemDrag::SetSource(GtkWidget* widget, DownloadItem* item) {
+ gtk_drag_source_set(widget, GDK_BUTTON1_MASK, NULL, 0,
+ kDownloadItemDragAction);
+ gtk_dnd_util::SetSourceTargetListFromCodeMask(widget, kDownloadItemCodeMask);
+ g_signal_connect(widget, "drag-data-get",
+ G_CALLBACK(OnDragDataGetStandalone), item);
+}
+
+// static
+void DownloadItemDrag::BeginDrag(const DownloadItem* item, SkBitmap* icon) {
+ new DownloadItemDrag(item, icon);
+}
+
+// BookmarkDrag ----------------------------------------------------------------
+
+BookmarkDrag::BookmarkDrag(Profile* profile,
+ const std::vector<const BookmarkNode*>& nodes)
+ : CustomDrag(NULL,
+ bookmark_utils::GetCodeMask(false),
+ kBookmarkDragAction),
+ profile_(profile),
+ nodes_(nodes) {
+}
+
+BookmarkDrag::~BookmarkDrag() {
+}
+
+void BookmarkDrag::OnDragDataGet(GtkWidget* widget, GdkDragContext* context,
+ GtkSelectionData* selection_data,
+ guint target_type, guint time) {
+ bookmark_utils::WriteBookmarksToSelection(nodes_, selection_data,
+ target_type, profile_);
+}
+
+// static
+void BookmarkDrag::BeginDrag(Profile* profile,
+ const std::vector<const BookmarkNode*>& nodes) {
+ new BookmarkDrag(profile, nodes);
+}
+
diff --git a/chrome/browser/gtk/custom_drag.h b/chrome/browser/gtk/custom_drag.h
new file mode 100644
index 0000000..a43b0da
--- /dev/null
+++ b/chrome/browser/gtk/custom_drag.h
@@ -0,0 +1,95 @@
+// 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_GTK_CUSTOM_DRAG_H_
+#define CHROME_BROWSER_GTK_CUSTOM_DRAG_H_
+
+#include <gtk/gtk.h>
+#include <vector>
+
+#include "app/gtk_signal.h"
+#include "base/basictypes.h"
+
+class BookmarkNode;
+class DownloadItem;
+class Profile;
+class SkBitmap;
+
+// Base class for programatically generated drags.
+class CustomDrag {
+ protected:
+ explicit CustomDrag(SkBitmap* icon, int code_mask, GdkDragAction action);
+ virtual ~CustomDrag();
+
+ virtual void OnDragDataGet(GtkWidget* widget, GdkDragContext* context,
+ GtkSelectionData* selection_data,
+ guint target_type, guint time) = 0;
+
+ private:
+ CHROMEGTK_CALLBACK_1(CustomDrag, void, OnDragBegin, GdkDragContext*);
+ CHROMEGTK_CALLBACK_1(CustomDrag, void, OnDragEnd, GdkDragContext*);
+
+ // Since this uses a virtual function, we can't use a macro.
+ static void OnDragDataGetThunk(GtkWidget* widget, GdkDragContext* context,
+ GtkSelectionData* selection_data,
+ guint target_type, guint time,
+ CustomDrag* custom_drag) {
+ return custom_drag->OnDragDataGet(widget, context, selection_data,
+ target_type, time);
+ }
+
+ GtkWidget* drag_widget_;
+ GdkPixbuf* pixbuf_;
+
+ DISALLOW_COPY_AND_ASSIGN(CustomDrag);
+};
+
+// Encapsulates functionality for drags of download items.
+class DownloadItemDrag : public CustomDrag {
+ public:
+ // Sets |widget| as a source for drags pertaining to |item|. No
+ // DownloadItemDrag object is created.
+ static void SetSource(GtkWidget* widget, DownloadItem* item);
+
+ // Creates a new DownloadItemDrag, the lifetime of which is tied to the
+ // system drag.
+ static void BeginDrag(const DownloadItem* item, SkBitmap* icon);
+
+ private:
+ DownloadItemDrag(const DownloadItem* item, SkBitmap* icon);
+ virtual ~DownloadItemDrag();
+
+ virtual void OnDragDataGet(GtkWidget* widget, GdkDragContext* context,
+ GtkSelectionData* selection_data,
+ guint target_type, guint time);
+
+ const DownloadItem* download_item_;
+
+ DISALLOW_COPY_AND_ASSIGN(DownloadItemDrag);
+};
+
+// Encapsulates functionality for drags of one or more bookmarks.
+class BookmarkDrag : public CustomDrag {
+ public:
+ // Creates a new BookmarkDrag, the lifetime of which is tied to the
+ // system drag.
+ static void BeginDrag(Profile* profile,
+ const std::vector<const BookmarkNode*>& nodes);
+
+ private:
+ BookmarkDrag(Profile* profile,
+ const std::vector<const BookmarkNode*>& nodes);
+ virtual ~BookmarkDrag();
+
+ virtual void OnDragDataGet(GtkWidget* widget, GdkDragContext* context,
+ GtkSelectionData* selection_data,
+ guint target_type, guint time);
+
+ Profile* profile_;
+ std::vector<const BookmarkNode*> nodes_;
+
+ DISALLOW_COPY_AND_ASSIGN(BookmarkDrag);
+};
+
+#endif // CHROME_BROWSER_GTK_CUSTOM_DRAG_H_
diff --git a/chrome/browser/gtk/download_item_drag.cc b/chrome/browser/gtk/download_item_drag.cc
deleted file mode 100644
index 24c312e..0000000
--- a/chrome/browser/gtk/download_item_drag.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-// 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.
-
-#include "chrome/browser/gtk/download_item_drag.h"
-
-#include "app/gtk_dnd_util.h"
-#include "base/utf_string_conversions.h"
-#include "chrome/browser/download/download_manager.h"
-#include "gfx/gtk_util.h"
-#include "googleurl/src/gurl.h"
-#include "net/base/net_util.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-
-namespace {
-
-const int kCodeMask = gtk_dnd_util::TEXT_URI_LIST |
- gtk_dnd_util::CHROME_NAMED_URL;
-const GdkDragAction kDragAction = GDK_ACTION_COPY;
-
-void OnDragDataGet(GtkWidget* widget, GdkDragContext* context,
- GtkSelectionData* selection_data,
- guint target_type, guint time,
- DownloadItem* download_item) {
- GURL url = net::FilePathToFileURL(download_item->full_path());
- gtk_dnd_util::WriteURLWithName(selection_data, url,
- UTF8ToUTF16(download_item->GetFileName().value()), target_type);
-}
-
-} // namespace
-
-// static
-void DownloadItemDrag::SetSource(GtkWidget* widget, DownloadItem* item) {
- gtk_drag_source_set(widget, GDK_BUTTON1_MASK, NULL, 0,
- kDragAction);
- gtk_dnd_util::SetSourceTargetListFromCodeMask(widget, kCodeMask);
- g_signal_connect(widget, "drag-data-get",
- G_CALLBACK(OnDragDataGet), item);
-}
-
-// static
-void DownloadItemDrag::BeginDrag(const DownloadItem* item, SkBitmap* icon) {
- new DownloadItemDrag(item, icon);
-}
-
-DownloadItemDrag::DownloadItemDrag(const DownloadItem* item,
- SkBitmap* icon)
- : drag_widget_(gtk_invisible_new()),
- pixbuf_(gfx::GdkPixbufFromSkBitmap(icon)) {
- g_object_ref_sink(drag_widget_);
- g_signal_connect(drag_widget_, "drag-data-get",
- G_CALLBACK(OnDragDataGet), const_cast<DownloadItem*>(item));
- g_signal_connect(drag_widget_, "drag-begin",
- G_CALLBACK(OnDragBegin), this);
- g_signal_connect(drag_widget_, "drag-end",
- G_CALLBACK(OnDragEnd), this);
-
- GtkTargetList* list = gtk_dnd_util::GetTargetListFromCodeMask(kCodeMask);
- GdkEvent* event = gtk_get_current_event();
- gtk_drag_begin(drag_widget_, list, kDragAction, 1, event);
- if (event)
- gdk_event_free(event);
- gtk_target_list_unref(list);
-}
-
-DownloadItemDrag::~DownloadItemDrag() {
- g_object_unref(pixbuf_);
- g_object_unref(drag_widget_);
-}
-
-// static
-void DownloadItemDrag::OnDragBegin(GtkWidget* widget,
- GdkDragContext* drag_context,
- DownloadItemDrag* drag) {
- gtk_drag_set_icon_pixbuf(drag_context, drag->pixbuf_, 0, 0);
-}
-
-// static
-void DownloadItemDrag::OnDragEnd(GtkWidget* widget,
- GdkDragContext* drag_context,
- DownloadItemDrag* drag) {
- delete drag;
-}
diff --git a/chrome/browser/gtk/download_item_drag.h b/chrome/browser/gtk/download_item_drag.h
deleted file mode 100644
index 1f8df44..0000000
--- a/chrome/browser/gtk/download_item_drag.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// 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_GTK_DOWNLOAD_ITEM_DRAG_H_
-#define CHROME_BROWSER_GTK_DOWNLOAD_ITEM_DRAG_H_
-
-#include <gtk/gtk.h>
-
-#include "base/basictypes.h"
-
-class DownloadItem;
-class SkBitmap;
-
-class DownloadItemDrag {
- public:
- // Sets |widget| as a source for drags pertaining to |item|. No
- // DownloadItemDrag object is created.
- static void SetSource(GtkWidget* widget, DownloadItem* item);
-
- // Creates a new DownloadItemDrag, the lifetime of which is tied to the
- // system drag.
- static void BeginDrag(const DownloadItem* item, SkBitmap* icon);
-
- private:
- explicit DownloadItemDrag(const DownloadItem* item, SkBitmap* icon);
- ~DownloadItemDrag();
-
- static void OnDragBegin(GtkWidget* widget,
- GdkDragContext* drag_context,
- DownloadItemDrag* drag);
-
- static void OnDragEnd(GtkWidget* widget,
- GdkDragContext* drag_context,
- DownloadItemDrag* drag);
-
- GtkWidget* drag_widget_;
- GdkPixbuf* pixbuf_;
-
- DISALLOW_COPY_AND_ASSIGN(DownloadItemDrag);
-};
-
-#endif // CHROME_BROWSER_GTK_DOWNLOAD_ITEM_DRAG_H_
diff --git a/chrome/browser/gtk/download_item_gtk.cc b/chrome/browser/gtk/download_item_gtk.cc
index 264b003..d996bc5 100644
--- a/chrome/browser/gtk/download_item_gtk.cc
+++ b/chrome/browser/gtk/download_item_gtk.cc
@@ -24,7 +24,7 @@
#include "chrome/browser/download/download_manager.h"
#include "chrome/browser/download/download_shelf.h"
#include "chrome/browser/download/download_util.h"
-#include "chrome/browser/gtk/download_item_drag.h"
+#include "chrome/browser/gtk/custom_drag.h"
#include "chrome/browser/gtk/download_shelf_gtk.h"
#include "chrome/browser/gtk/gtk_theme_provider.h"
#include "chrome/browser/gtk/gtk_util.h"
diff --git a/chrome/browser/renderer_host/render_view_host_delegate.h b/chrome/browser/renderer_host/render_view_host_delegate.h
index ff10230..b1a1148 100644
--- a/chrome/browser/renderer_host/render_view_host_delegate.h
+++ b/chrome/browser/renderer_host/render_view_host_delegate.h
@@ -17,6 +17,7 @@
#include "webkit/glue/window_open_disposition.h"
struct BookmarkDragData;
+class BookmarkNode;
struct ContextMenuParams;
class FilePath;
class GURL;
@@ -424,21 +425,10 @@ class RenderViewHostDelegate {
class BookmarkDrag {
public:
-
-#if defined(TOOLKIT_VIEWS)
- typedef OSExchangeData DragData;
-#elif defined(OS_LINUX)
- // TODO(arv): GtkSelectionData?
- class DragData {};
-#else
- // TODO(arv): NSDraggingInfo?
- class DragData {};
-#endif
-
- virtual void OnDragEnter(const DragData* data) = 0;
- virtual void OnDragOver(const DragData* data) = 0;
- virtual void OnDragLeave(const DragData* data) = 0;
- virtual void OnDrop(const DragData* data) = 0;
+ virtual void OnDragEnter(const BookmarkDragData& data) = 0;
+ virtual void OnDragOver(const BookmarkDragData& data) = 0;
+ virtual void OnDragLeave(const BookmarkDragData& data) = 0;
+ virtual void OnDrop(const BookmarkDragData& data) = 0;
};
// ---------------------------------------------------------------------------
diff --git a/chrome/browser/tab_contents/web_drag_dest_gtk.cc b/chrome/browser/tab_contents/web_drag_dest_gtk.cc
index 2bb5fa3..d96f6cf 100644
--- a/chrome/browser/tab_contents/web_drag_dest_gtk.cc
+++ b/chrome/browser/tab_contents/web_drag_dest_gtk.cc
@@ -9,6 +9,7 @@
#include "app/gtk_dnd_util.h"
#include "base/file_path.h"
#include "base/utf_string_conversions.h"
+#include "chrome/browser/gtk/bookmark_utils_gtk.h"
#include "chrome/browser/gtk/gtk_util.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/tab_contents/tab_contents.h"
@@ -60,6 +61,10 @@ void WebDragDestGtk::UpdateDragStatus(WebDragOperation operation) {
void WebDragDestGtk::DragLeave() {
tab_contents_->render_view_host()->DragTargetDragLeave();
+
+ if (tab_contents_->GetBookmarkDragDelegate()) {
+ tab_contents_->GetBookmarkDragDelegate()->OnDragLeave(bookmark_drag_data_);
+ }
}
gboolean WebDragDestGtk::OnDragMotion(GtkWidget* sender,
@@ -77,6 +82,7 @@ gboolean WebDragDestGtk::OnDragMotion(GtkWidget* sender,
gtk_dnd_util::TEXT_HTML,
gtk_dnd_util::NETSCAPE_URL,
gtk_dnd_util::CHROME_NAMED_URL,
+ gtk_dnd_util::CHROME_BOOKMARK_ITEM,
// TODO(estade): support image drags?
};
@@ -87,12 +93,14 @@ gboolean WebDragDestGtk::OnDragMotion(GtkWidget* sender,
time);
}
} else if (data_requests_ == 0) {
+ // TODO(snej): Pass appropriate DragOperation instead of hardcoding
tab_contents_->render_view_host()->
DragTargetDragOver(gtk_util::ClientPoint(widget_),
gtk_util::ScreenPoint(widget_),
static_cast<WebDragOperation>(
WebDragOperationCopy | WebDragOperationMove));
- // TODO(snej): Pass appropriate DragOperation instead of hardcoding
+ if (tab_contents_->GetBookmarkDragDelegate())
+ tab_contents_->GetBookmarkDragDelegate()->OnDragOver(bookmark_drag_data_);
drag_over_time_ = time;
}
@@ -160,19 +168,36 @@ void WebDragDestGtk::OnDragDataReceived(
gtk_dnd_util::GetAtomForTarget(gtk_dnd_util::CHROME_NAMED_URL)) {
gtk_dnd_util::ExtractNamedURL(data,
&drop_data_->url, &drop_data_->url_title);
+ } else if (data->target ==
+ gtk_dnd_util::GetAtomForTarget(
+ gtk_dnd_util::CHROME_BOOKMARK_ITEM)) {
+ bookmark_drag_data_.ReadFromVector(
+ bookmark_utils::GetNodesFromSelection(
+ NULL, data,
+ gtk_dnd_util::CHROME_BOOKMARK_ITEM,
+ tab_contents_->profile(), NULL, NULL));
+ bookmark_drag_data_.SetOriginatingProfile(tab_contents_->profile());
}
}
if (data_requests_ == 0) {
// Tell the renderer about the drag.
// |x| and |y| are seemingly arbitrary at this point.
+ // TODO(snej): Pass appropriate DragOperation instead of hardcoding.
tab_contents_->render_view_host()->
DragTargetDragEnter(*drop_data_.get(),
gtk_util::ClientPoint(widget_),
gtk_util::ScreenPoint(widget_),
static_cast<WebDragOperation>(
WebDragOperationCopy | WebDragOperationMove));
- // TODO(snej): Pass appropriate DragOperation instead of hardcoding
+
+ // This is non-null if tab_contents_ is showing an ExtensionDOMUI with
+ // support for (at the moment experimental) drag and drop extensions.
+ if (tab_contents_->GetBookmarkDragDelegate()) {
+ tab_contents_->GetBookmarkDragDelegate()->OnDragEnter(
+ bookmark_drag_data_);
+ }
+
drag_over_time_ = time;
}
}
@@ -202,6 +227,11 @@ gboolean WebDragDestGtk::OnDragDrop(GtkWidget* sender, GdkDragContext* context,
DragTargetDrop(gtk_util::ClientPoint(widget_),
gtk_util::ScreenPoint(widget_));
+ // This is non-null if tab_contents_ is showing an ExtensionDOMUI with
+ // support for (at the moment experimental) drag and drop extensions.
+ if (tab_contents_->GetBookmarkDragDelegate())
+ tab_contents_->GetBookmarkDragDelegate()->OnDrop(bookmark_drag_data_);
+
// The second parameter is just an educated guess, but at least we will
// get the drag-end animation right sometimes.
gtk_drag_finish(context, is_drop_target_, FALSE, time);
diff --git a/chrome/browser/tab_contents/web_drag_dest_gtk.h b/chrome/browser/tab_contents/web_drag_dest_gtk.h
index e8b0c3a..49607b2 100644
--- a/chrome/browser/tab_contents/web_drag_dest_gtk.h
+++ b/chrome/browser/tab_contents/web_drag_dest_gtk.h
@@ -6,13 +6,16 @@
#define CHROME_BROWSER_TAB_CONTENTS_WEB_DRAG_DEST_GTK_H_
#include <gtk/gtk.h>
+#include <vector>
#include "app/gtk_signal.h"
#include "base/scoped_ptr.h"
#include "base/task.h"
+#include "chrome/browser/bookmarks/bookmark_drag_data.h"
#include "third_party/WebKit/WebKit/chromium/public/WebDragOperation.h"
#include "webkit/glue/webdropdata.h"
+class BookmarkNode;
class TabContents;
// A helper class that handles DnD for drops in the renderer. In GTK parlance,
@@ -80,6 +83,10 @@ class WebDragDestGtk {
// |widget_| is.
int destroy_handler_;
+ // The bookmark data for the current tab. This will be empty if there is not
+ // a native bookmark drag (or we haven't gotten the data from the source yet).
+ BookmarkDragData bookmark_drag_data_;
+
ScopedRunnableMethodFactory<WebDragDestGtk> method_factory_;
DISALLOW_COPY_AND_ASSIGN(WebDragDestGtk);
diff --git a/chrome/browser/tab_contents/web_drop_target_win.cc b/chrome/browser/tab_contents/web_drop_target_win.cc
index f84a4b0..72d4e23 100644
--- a/chrome/browser/tab_contents/web_drop_target_win.cc
+++ b/chrome/browser/tab_contents/web_drop_target_win.cc
@@ -10,6 +10,7 @@
#include "app/clipboard/clipboard_util_win.h"
#include "app/os_exchange_data.h"
#include "app/os_exchange_data_provider_win.h"
+#include "chrome/browser/bookmarks/bookmark_drag_data.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "gfx/point.h"
@@ -122,7 +123,9 @@ DWORD WebDropTarget::OnDragEnter(IDataObject* data_object,
// support for (at the moment experimental) drag and drop extensions.
if (tab_contents_->GetBookmarkDragDelegate()) {
OSExchangeData os_exchange_data(new OSExchangeDataProviderWin(data_object));
- tab_contents_->GetBookmarkDragDelegate()->OnDragEnter(&os_exchange_data);
+ BookmarkDragData bookmark_drag_data;
+ if (bookmark_drag_data.Read(os_exchange_data))
+ tab_contents_->GetBookmarkDragDelegate()->OnDragEnter(bookmark_drag_data);
}
// We lie here and always return a DROPEFFECT because we don't want to
@@ -150,7 +153,9 @@ DWORD WebDropTarget::OnDragOver(IDataObject* data_object,
if (tab_contents_->GetBookmarkDragDelegate()) {
OSExchangeData os_exchange_data(new OSExchangeDataProviderWin(data_object));
- tab_contents_->GetBookmarkDragDelegate()->OnDragOver(&os_exchange_data);
+ BookmarkDragData bookmark_drag_data;
+ if (bookmark_drag_data.Read(os_exchange_data))
+ tab_contents_->GetBookmarkDragDelegate()->OnDragOver(bookmark_drag_data);
}
if (!is_drop_target_)
@@ -172,7 +177,9 @@ void WebDropTarget::OnDragLeave(IDataObject* data_object) {
if (tab_contents_->GetBookmarkDragDelegate()) {
OSExchangeData os_exchange_data(new OSExchangeDataProviderWin(data_object));
- tab_contents_->GetBookmarkDragDelegate()->OnDragLeave(&os_exchange_data);
+ BookmarkDragData bookmark_drag_data;
+ if (bookmark_drag_data.Read(os_exchange_data))
+ tab_contents_->GetBookmarkDragDelegate()->OnDragLeave(bookmark_drag_data);
}
}
@@ -198,7 +205,9 @@ DWORD WebDropTarget::OnDrop(IDataObject* data_object,
if (tab_contents_->GetBookmarkDragDelegate()) {
OSExchangeData os_exchange_data(new OSExchangeDataProviderWin(data_object));
- tab_contents_->GetBookmarkDragDelegate()->OnDrop(&os_exchange_data);
+ BookmarkDragData bookmark_drag_data;
+ if (bookmark_drag_data.Read(os_exchange_data))
+ tab_contents_->GetBookmarkDragDelegate()->OnDrop(bookmark_drag_data);
}
current_rvh_ = NULL;