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#ifndef CHROME_BROWSER_TAB_CONTENTS_WEB_DRAG_DEST_GTK_H_
6#define CHROME_BROWSER_TAB_CONTENTS_WEB_DRAG_DEST_GTK_H_
7#pragma once
8
9#include <gtk/gtk.h>
10
11#include "base/memory/scoped_ptr.h"
12#include "base/task.h"
13#include "chrome/browser/bookmarks/bookmark_node_data.h"
14#include "third_party/WebKit/Source/WebKit/chromium/public/WebDragOperation.h"
15#include "ui/base/gtk/gtk_signal.h"
16#include "webkit/glue/webdropdata.h"
17
18class TabContents;
19
20// A helper class that handles DnD for drops in the renderer. In GTK parlance,
21// this handles destination-side DnD, but not source-side DnD.
22class WebDragDestGtk {
23 public:
24  WebDragDestGtk(TabContents* tab_contents, GtkWidget* widget);
25  virtual ~WebDragDestGtk();
26
27  // This is called when the renderer responds to a drag motion event. We must
28  // update the system drag cursor.
29  void UpdateDragStatus(WebKit::WebDragOperation operation);
30
31  // Informs the renderer when a system drag has left the render view.
32  // See OnDragLeave().
33  void DragLeave();
34
35 private:
36  // Called when a system drag crosses over the render view. As there is no drag
37  // enter event, we treat it as an enter event (and not a regular motion event)
38  // when |context_| is NULL.
39  CHROMEGTK_CALLBACK_4(WebDragDestGtk, gboolean, OnDragMotion, GdkDragContext*,
40                       gint, gint, guint);
41
42  // We make a series of requests for the drag data when the drag first enters
43  // the render view. This is the callback that is used to give us the data
44  // for each individual target. When |data_requests_| reaches 0, we know we
45  // have attained all the data, and we can finally tell the renderer about the
46  // drag.
47  CHROMEGTK_CALLBACK_6(WebDragDestGtk, void, OnDragDataReceived,
48                       GdkDragContext*, gint, gint, GtkSelectionData*,
49                       guint, guint);
50
51  // The drag has left our widget; forward this information to the renderer.
52  CHROMEGTK_CALLBACK_2(WebDragDestGtk, void, OnDragLeave, GdkDragContext*,
53                       guint);
54
55  // Called by GTK when the user releases the mouse, executing a drop.
56  CHROMEGTK_CALLBACK_4(WebDragDestGtk, gboolean, OnDragDrop, GdkDragContext*,
57                       gint, gint, guint);
58
59  TabContents* tab_contents_;
60  // The render view.
61  GtkWidget* widget_;
62  // The current drag context for system drags over our render view, or NULL if
63  // there is no system drag or the system drag is not over our render view.
64  GdkDragContext* context_;
65  // The data for the current drag, or NULL if |context_| is NULL.
66  scoped_ptr<WebDropData> drop_data_;
67
68  // The number of outstanding drag data requests we have sent to the drag
69  // source.
70  int data_requests_;
71
72  // The last time we sent a message to the renderer related to a drag motion.
73  gint drag_over_time_;
74
75  // Whether the cursor is over a drop target, according to the last message we
76  // got from the renderer.
77  bool is_drop_target_;
78
79  // Handler ID for the destroy signal handler. We connect to the destroy
80  // signal handler so that we won't call dest_unset on it after it is
81  // destroyed, but we have to cancel the handler if we are destroyed before
82  // |widget_| is.
83  int destroy_handler_;
84
85  // The bookmark data for the current tab. This will be empty if there is not
86  // a native bookmark drag (or we haven't gotten the data from the source yet).
87  BookmarkNodeData bookmark_drag_data_;
88
89  ScopedRunnableMethodFactory<WebDragDestGtk> method_factory_;
90
91  DISALLOW_COPY_AND_ASSIGN(WebDragDestGtk);
92};
93
94#endif  // CHROME_BROWSER_TAB_CONTENTS_WEB_DRAG_DEST_GTK_H_
95