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