Home | History | Annotate | Download | only in dragdrop
      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 UI_BASE_DRAGDROP_OS_EXCHANGE_DATA_PROVIDER_WIN_H_
      6 #define UI_BASE_DRAGDROP_OS_EXCHANGE_DATA_PROVIDER_WIN_H_
      7 
      8 #include <objidl.h>
      9 #include <shlobj.h>
     10 #include <string>
     11 #include <vector>
     12 
     13 // Win8 SDK compatibility, see http://goo.gl/fufvl for more information.
     14 // "Note: This interface has been renamed IDataObjectAsyncCapability."
     15 // If we're building on pre-8 we define it to its old name. It's documented as
     16 // being binary compatible.
     17 #ifndef __IDataObjectAsyncCapability_FWD_DEFINED__
     18 #define IDataObjectAsyncCapability IAsyncOperation
     19 #endif
     20 
     21 #include "base/memory/scoped_vector.h"
     22 #include "base/win/scoped_comptr.h"
     23 #include "ui/base/dragdrop/os_exchange_data.h"
     24 #include "ui/base/ui_export.h"
     25 #include "ui/gfx/image/image_skia.h"
     26 #include "ui/gfx/vector2d.h"
     27 
     28 namespace ui {
     29 
     30 class DataObjectImpl : public DownloadFileObserver,
     31                        public IDataObject,
     32                        public IDataObjectAsyncCapability {
     33  public:
     34   class Observer {
     35    public:
     36     virtual void OnWaitForData() = 0;
     37     virtual void OnDataObjectDisposed() = 0;
     38    protected:
     39     virtual ~Observer() { }
     40   };
     41 
     42   DataObjectImpl();
     43 
     44   // Accessors.
     45   void set_observer(Observer* observer) { observer_ = observer; }
     46   void set_in_drag_loop(bool in_drag_loop) { in_drag_loop_ = in_drag_loop; }
     47 
     48   // Number of known formats.
     49   size_t size() const { return contents_.size(); }
     50 
     51   // DownloadFileObserver implementation:
     52   virtual void OnDownloadCompleted(const base::FilePath& file_path);
     53   virtual void OnDownloadAborted();
     54 
     55   // IDataObject implementation:
     56   HRESULT __stdcall GetData(FORMATETC* format_etc, STGMEDIUM* medium);
     57   HRESULT __stdcall GetDataHere(FORMATETC* format_etc, STGMEDIUM* medium);
     58   HRESULT __stdcall QueryGetData(FORMATETC* format_etc);
     59   HRESULT __stdcall GetCanonicalFormatEtc(
     60       FORMATETC* format_etc, FORMATETC* result);
     61   HRESULT __stdcall SetData(
     62       FORMATETC* format_etc, STGMEDIUM* medium, BOOL should_release);
     63   HRESULT __stdcall EnumFormatEtc(
     64       DWORD direction, IEnumFORMATETC** enumerator);
     65   HRESULT __stdcall DAdvise(FORMATETC* format_etc, DWORD advf,
     66                             IAdviseSink* sink, DWORD* connection);
     67   HRESULT __stdcall DUnadvise(DWORD connection);
     68   HRESULT __stdcall EnumDAdvise(IEnumSTATDATA** enumerator);
     69 
     70   // IDataObjectAsyncCapability implementation:
     71   HRESULT __stdcall EndOperation(
     72       HRESULT result, IBindCtx* reserved, DWORD effects);
     73   HRESULT __stdcall GetAsyncMode(BOOL* is_op_async);
     74   HRESULT __stdcall InOperation(BOOL* in_async_op);
     75   HRESULT __stdcall SetAsyncMode(BOOL do_op_async);
     76   HRESULT __stdcall StartOperation(IBindCtx* reserved);
     77 
     78   // IUnknown implementation:
     79   HRESULT __stdcall QueryInterface(const IID& iid, void** object);
     80   ULONG __stdcall AddRef();
     81   ULONG __stdcall Release();
     82 
     83  private:
     84   // FormatEtcEnumerator only likes us for our StoredDataMap typedef.
     85   friend class FormatEtcEnumerator;
     86   friend class OSExchangeDataProviderWin;
     87 
     88   virtual ~DataObjectImpl();
     89 
     90   void StopDownloads();
     91 
     92   // Removes from contents_ the first data that matches |format|.
     93   void RemoveData(const FORMATETC& format);
     94 
     95   // Our internal representation of stored data & type info.
     96   struct StoredDataInfo {
     97     FORMATETC format_etc;
     98     STGMEDIUM* medium;
     99     bool owns_medium;
    100     scoped_refptr<DownloadFileProvider> downloader;
    101 
    102     StoredDataInfo(const FORMATETC& format_etc, STGMEDIUM* medium)
    103         : format_etc(format_etc), medium(medium), owns_medium(true) {}
    104 
    105     ~StoredDataInfo() {
    106       if (owns_medium) {
    107         ReleaseStgMedium(medium);
    108         delete medium;
    109       }
    110       if (downloader.get())
    111         downloader->Stop();
    112     }
    113   };
    114 
    115   typedef ScopedVector<StoredDataInfo> StoredData;
    116   StoredData contents_;
    117 
    118   base::win::ScopedComPtr<IDataObject> source_object_;
    119 
    120   bool is_aborting_;
    121   bool in_drag_loop_;
    122   bool in_async_mode_;
    123   bool async_operation_started_;
    124   Observer* observer_;
    125 };
    126 
    127 class UI_EXPORT OSExchangeDataProviderWin : public OSExchangeData::Provider {
    128  public:
    129   // Returns true if source has plain text that is a valid url.
    130   static bool HasPlainTextURL(IDataObject* source);
    131 
    132   // Returns true if source has plain text that is a valid URL and sets url to
    133   // that url.
    134   static bool GetPlainTextURL(IDataObject* source, GURL* url);
    135 
    136   static DataObjectImpl* GetDataObjectImpl(const OSExchangeData& data);
    137   static IDataObject* GetIDataObject(const OSExchangeData& data);
    138   static IDataObjectAsyncCapability* GetIAsyncOperation(
    139       const OSExchangeData& data);
    140 
    141   explicit OSExchangeDataProviderWin(IDataObject* source);
    142   OSExchangeDataProviderWin();
    143 
    144   virtual ~OSExchangeDataProviderWin();
    145 
    146   IDataObject* data_object() const { return data_.get(); }
    147   IDataObjectAsyncCapability* async_operation() const { return data_.get(); }
    148 
    149   // OSExchangeData::Provider methods.
    150   virtual Provider* Clone() const;
    151   virtual void SetString(const base::string16& data);
    152   virtual void SetURL(const GURL& url, const base::string16& title);
    153   virtual void SetFilename(const base::FilePath& path);
    154   virtual void SetFilenames(
    155       const std::vector<OSExchangeData::FileInfo>& filenames);
    156   virtual void SetPickledData(const OSExchangeData::CustomFormat& format,
    157                               const Pickle& data);
    158   virtual void SetFileContents(const base::FilePath& filename,
    159                                const std::string& file_contents);
    160   virtual void SetHtml(const base::string16& html, const GURL& base_url);
    161 
    162   virtual bool GetString(base::string16* data) const;
    163   virtual bool GetURLAndTitle(GURL* url, base::string16* title) const;
    164   virtual bool GetFilename(base::FilePath* path) const;
    165   virtual bool GetFilenames(
    166       std::vector<OSExchangeData::FileInfo>* filenames) const;
    167   virtual bool GetPickledData(const OSExchangeData::CustomFormat& format,
    168                               Pickle* data) const;
    169   virtual bool GetFileContents(base::FilePath* filename,
    170                                std::string* file_contents) const;
    171   virtual bool GetHtml(base::string16* html, GURL* base_url) const;
    172   virtual bool HasString() const;
    173   virtual bool HasURL() const;
    174   virtual bool HasFile() const;
    175   virtual bool HasFileContents() const;
    176   virtual bool HasHtml() const;
    177   virtual bool HasCustomFormat(
    178       const OSExchangeData::CustomFormat& format) const;
    179   virtual void SetDownloadFileInfo(
    180       const OSExchangeData::DownloadFileInfo& download_info);
    181   virtual void SetInDragLoop(bool in_drag_loop) OVERRIDE;
    182 #if defined(USE_AURA)
    183   virtual void SetDragImage(const gfx::ImageSkia& image,
    184                             const gfx::Vector2d& cursor_offset) OVERRIDE;
    185   virtual const gfx::ImageSkia& GetDragImage() const OVERRIDE;
    186   virtual const gfx::Vector2d& GetDragImageOffset() const OVERRIDE;
    187 #endif
    188 
    189  private:
    190   scoped_refptr<DataObjectImpl> data_;
    191   base::win::ScopedComPtr<IDataObject> source_object_;
    192 
    193 #if defined(USE_AURA)
    194   // Drag image and offset data. Only used for Ash.
    195   gfx::ImageSkia drag_image_;
    196   gfx::Vector2d drag_image_offset_;
    197 #endif
    198 
    199   DISALLOW_COPY_AND_ASSIGN(OSExchangeDataProviderWin);
    200 };
    201 
    202 }  // namespace ui
    203 
    204 #endif  // UI_BASE_DRAGDROP_OS_EXCHANGE_DATA_PROVIDER_WIN_H_
    205