Home | History | Annotate | Download | only in web_contents
      1 // Copyright (c) 2012 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 CONTENT_BROWSER_WEB_CONTENTS_WEB_DRAG_DEST_GTK_H_
      6 #define CONTENT_BROWSER_WEB_CONTENTS_WEB_DRAG_DEST_GTK_H_
      7 
      8 #include <gtk/gtk.h>
      9 
     10 #include "base/gtest_prod_util.h"
     11 #include "base/memory/scoped_ptr.h"
     12 #include "base/memory/weak_ptr.h"
     13 #include "content/common/content_export.h"
     14 #include "content/public/common/drop_data.h"
     15 #include "third_party/WebKit/public/web/WebDragOperation.h"
     16 #include "ui/base/gtk/gtk_signal.h"
     17 
     18 namespace content {
     19 
     20 class RenderViewHostImpl;
     21 class WebContents;
     22 class WebDragDestDelegate;
     23 
     24 // A helper class that handles DnD for drops in the renderer. In GTK parlance,
     25 // this handles destination-side DnD, but not source-side DnD.
     26 class CONTENT_EXPORT WebDragDestGtk {
     27  public:
     28   WebDragDestGtk(WebContents* web_contents, GtkWidget* widget);
     29   ~WebDragDestGtk();
     30 
     31   DropData* current_drop_data() const { return drop_data_.get(); }
     32 
     33   // This is called when the renderer responds to a drag motion event. We must
     34   // update the system drag cursor.
     35   void UpdateDragStatus(WebKit::WebDragOperation operation);
     36 
     37   // Informs the renderer when a system drag has left the render view.
     38   // See OnDragLeave().
     39   void DragLeave();
     40 
     41   WebDragDestDelegate* delegate() const { return delegate_; }
     42   void set_delegate(WebDragDestDelegate* delegate) { delegate_ = delegate; }
     43 
     44   GtkWidget* widget() const { return widget_; }
     45 
     46  private:
     47   RenderViewHostImpl* GetRenderViewHost() const;
     48 
     49   // Called when a system drag crosses over the render view. As there is no drag
     50   // enter event, we treat it as an enter event (and not a regular motion event)
     51   // when |context_| is NULL.
     52   CHROMEGTK_CALLBACK_4(WebDragDestGtk, gboolean, OnDragMotion, GdkDragContext*,
     53                        gint, gint, guint);
     54 
     55   // We make a series of requests for the drag data when the drag first enters
     56   // the render view. This is the callback that is used to give us the data
     57   // for each individual target. When |data_requests_| reaches 0, we know we
     58   // have attained all the data, and we can finally tell the renderer about the
     59   // drag.
     60   CHROMEGTK_CALLBACK_6(WebDragDestGtk, void, OnDragDataReceived,
     61                        GdkDragContext*, gint, gint, GtkSelectionData*,
     62                        guint, guint);
     63 
     64   // The drag has left our widget; forward this information to the renderer.
     65   CHROMEGTK_CALLBACK_2(WebDragDestGtk, void, OnDragLeave, GdkDragContext*,
     66                        guint);
     67 
     68   // Called by GTK when the user releases the mouse, executing a drop.
     69   CHROMEGTK_CALLBACK_4(WebDragDestGtk, gboolean, OnDragDrop, GdkDragContext*,
     70                        gint, gint, guint);
     71 
     72   WebContents* web_contents_;
     73 
     74   // The render view.
     75   GtkWidget* widget_;
     76 
     77   // The current drag context for system drags over our render view, or NULL if
     78   // there is no system drag or the system drag is not over our render view.
     79   GdkDragContext* context_;
     80 
     81   // The data for the current drag, or NULL if |context_| is NULL.
     82   scoped_ptr<DropData> drop_data_;
     83 
     84   // The number of outstanding drag data requests we have sent to the drag
     85   // source.
     86   int data_requests_;
     87 
     88   // The last time we sent a message to the renderer related to a drag motion.
     89   gint drag_over_time_;
     90 
     91   // Whether the cursor is over a drop target, according to the last message we
     92   // got from the renderer.
     93   bool is_drop_target_;
     94 
     95   // Stores Handler IDs for the gtk signal handlers. We have to cancel the
     96   // signal handlers when this WebDragDestGtk is deleted so that if, later on,
     97   // we re-create the drag dest with the same widget, we don't get callbacks to
     98   // deleted functions.
     99   scoped_ptr<int[]> handlers_;
    100 
    101   // A delegate that can receive drag information about drag events.
    102   WebDragDestDelegate* delegate_;
    103 
    104   // True if the drag has been canceled.
    105   bool canceled_;
    106 
    107   base::WeakPtrFactory<WebDragDestGtk> method_factory_;
    108 
    109   DISALLOW_COPY_AND_ASSIGN(WebDragDestGtk);
    110 };
    111 
    112 }  // namespace content
    113 
    114 #endif  // CONTENT_BROWSER_WEB_CONTENTS_WEB_DRAG_DEST_GTK_H_
    115