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