172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/custom_drag.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h" 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/download/download_item.h" 9dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/ui/gtk/bookmarks/bookmark_utils_gtk.h" 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "googleurl/src/gurl.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_util.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "third_party/skia/include/core/SkBitmap.h" 1372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/dragdrop/gtk_dnd_util.h" 1472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/gtk_util.h" 15dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "ui/gfx/image.h" 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace { 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenconst int kDownloadItemCodeMask = ui::TEXT_URI_LIST | ui::CHROME_NAMED_URL; 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst GdkDragAction kDownloadItemDragAction = GDK_ACTION_COPY; 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst GdkDragAction kBookmarkDragAction = 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<GdkDragAction>(GDK_ACTION_COPY | GDK_ACTION_MOVE); 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid OnDragDataGetForDownloadItem(GtkSelectionData* selection_data, 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch guint target_type, 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const DownloadItem* download_item) { 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL url = net::FilePathToFileURL(download_item->full_path()); 2872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ui::WriteURLWithName(selection_data, url, 29513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch UTF8ToUTF16(download_item->GetFileNameToReportUser().value()), 30513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch target_type); 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid OnDragDataGetStandalone(GtkWidget* widget, GdkDragContext* context, 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkSelectionData* selection_data, 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch guint target_type, guint time, 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const DownloadItem* item) { 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OnDragDataGetForDownloadItem(selection_data, target_type, item); 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// CustomDrag ------------------------------------------------------------------ 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 44dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenCustomDrag::CustomDrag(gfx::Image* icon, int code_mask, GdkDragAction action) 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : drag_widget_(gtk_invisible_new()), 46dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen image_(icon) { 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(drag_widget_, "drag-data-get", 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch G_CALLBACK(OnDragDataGetThunk), this); 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(drag_widget_, "drag-begin", 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch G_CALLBACK(OnDragBeginThunk), this); 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(drag_widget_, "drag-end", 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch G_CALLBACK(OnDragEndThunk), this); 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen GtkTargetList* list = ui::GetTargetListFromCodeMask(code_mask); 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkEvent* event = gtk_get_current_event(); 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_drag_begin(drag_widget_, list, action, 1, event); 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (event) 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_event_free(event); 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_target_list_unref(list); 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochCustomDrag::~CustomDrag() { 63513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch gtk_widget_destroy(drag_widget_); 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CustomDrag::OnDragBegin(GtkWidget* widget, GdkDragContext* drag_context) { 67dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (image_) 68dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen gtk_drag_set_icon_pixbuf(drag_context, *image_, 0, 0); 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CustomDrag::OnDragEnd(GtkWidget* widget, GdkDragContext* drag_context) { 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete this; 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// DownloadItemDrag ------------------------------------------------------------ 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochDownloadItemDrag::DownloadItemDrag(const DownloadItem* item, 78dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen gfx::Image* icon) 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : CustomDrag(icon, kDownloadItemCodeMask, kDownloadItemDragAction), 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch download_item_(item) { 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochDownloadItemDrag::~DownloadItemDrag() { 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid DownloadItemDrag::OnDragDataGet( 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* widget, GdkDragContext* context, 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkSelectionData* selection_data, 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch guint target_type, guint time) { 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OnDragDataGetForDownloadItem(selection_data, target_type, download_item_); 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid DownloadItemDrag::SetSource(GtkWidget* widget, 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DownloadItem* item, 96dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen gfx::Image* icon) { 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_drag_source_set(widget, GDK_BUTTON1_MASK, NULL, 0, 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kDownloadItemDragAction); 9972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ui::SetSourceTargetListFromCodeMask(widget, kDownloadItemCodeMask); 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Disconnect previous signal handlers, if any. 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_handlers_disconnect_by_func( 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch widget, 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch reinterpret_cast<gpointer>(OnDragDataGetStandalone), 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch item); 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Connect new signal handlers. 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(widget, "drag-data-get", 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch G_CALLBACK(OnDragDataGetStandalone), item); 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 110dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (icon) 111dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen gtk_drag_source_set_icon_pixbuf(widget, *icon); 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 115dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid DownloadItemDrag::BeginDrag(const DownloadItem* item, gfx::Image* icon) { 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DownloadItemDrag(item, icon); 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// BookmarkDrag ---------------------------------------------------------------- 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBookmarkDrag::BookmarkDrag(Profile* profile, 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::vector<const BookmarkNode*>& nodes) 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : CustomDrag(NULL, 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bookmark_utils::GetCodeMask(false), 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kBookmarkDragAction), 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_(profile), 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes_(nodes) { 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBookmarkDrag::~BookmarkDrag() { 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BookmarkDrag::OnDragDataGet(GtkWidget* widget, GdkDragContext* context, 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkSelectionData* selection_data, 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch guint target_type, guint time) { 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bookmark_utils::WriteBookmarksToSelection(nodes_, selection_data, 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch target_type, profile_); 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BookmarkDrag::BeginDrag(Profile* profile, 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::vector<const BookmarkNode*>& nodes) { 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new BookmarkDrag(profile, nodes); 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 145