os_exchange_data_provider_win.h revision a93a17c8d99d686bd4a1511e5504e5e6cc9fcadf
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
28namespace ui {
29
30class 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(CLIPFORMAT cf, STGMEDIUM* medium)
103        : medium(medium),
104          owns_medium(true) {
105      format_etc.cfFormat = cf;
106      format_etc.dwAspect = DVASPECT_CONTENT;
107      format_etc.lindex = -1;
108      format_etc.ptd = NULL;
109      format_etc.tymed = medium ? medium->tymed : TYMED_HGLOBAL;
110    }
111
112    StoredDataInfo(FORMATETC* format_etc, STGMEDIUM* medium)
113        : format_etc(*format_etc),
114          medium(medium),
115          owns_medium(true) {
116    }
117
118    ~StoredDataInfo() {
119      if (owns_medium) {
120        ReleaseStgMedium(medium);
121        delete medium;
122      }
123      if (downloader.get())
124        downloader->Stop();
125    }
126  };
127
128  typedef ScopedVector<StoredDataInfo> StoredData;
129  StoredData contents_;
130
131  base::win::ScopedComPtr<IDataObject> source_object_;
132
133  bool is_aborting_;
134  bool in_drag_loop_;
135  bool in_async_mode_;
136  bool async_operation_started_;
137  Observer* observer_;
138};
139
140class UI_EXPORT OSExchangeDataProviderWin : public OSExchangeData::Provider {
141 public:
142  // Returns true if source has plain text that is a valid url.
143  static bool HasPlainTextURL(IDataObject* source);
144
145  // Returns true if source has plain text that is a valid URL and sets url to
146  // that url.
147  static bool GetPlainTextURL(IDataObject* source, GURL* url);
148
149  static DataObjectImpl* GetDataObjectImpl(const OSExchangeData& data);
150  static IDataObject* GetIDataObject(const OSExchangeData& data);
151  static IDataObjectAsyncCapability* GetIAsyncOperation(
152      const OSExchangeData& data);
153
154  explicit OSExchangeDataProviderWin(IDataObject* source);
155  OSExchangeDataProviderWin();
156
157  virtual ~OSExchangeDataProviderWin();
158
159  IDataObject* data_object() const { return data_.get(); }
160  IDataObjectAsyncCapability* async_operation() const { return data_.get(); }
161
162  // OSExchangeData::Provider methods.
163  virtual void SetString(const string16& data);
164  virtual void SetURL(const GURL& url, const string16& title);
165  virtual void SetFilename(const base::FilePath& path);
166  virtual void SetFilenames(
167      const std::vector<OSExchangeData::FileInfo>& filenames);
168  virtual void SetPickledData(OSExchangeData::CustomFormat format,
169                              const Pickle& data);
170  virtual void SetFileContents(const base::FilePath& filename,
171                               const std::string& file_contents);
172  virtual void SetHtml(const string16& html, const GURL& base_url);
173
174  virtual bool GetString(string16* data) const;
175  virtual bool GetURLAndTitle(GURL* url, string16* title) const;
176  virtual bool GetFilename(base::FilePath* path) const;
177  virtual bool GetFilenames(
178      std::vector<OSExchangeData::FileInfo>* filenames) const;
179  virtual bool GetPickledData(OSExchangeData::CustomFormat format,
180                              Pickle* data) const;
181  virtual bool GetFileContents(base::FilePath* filename,
182                               std::string* file_contents) const;
183  virtual bool GetHtml(string16* html, GURL* base_url) const;
184  virtual bool HasString() const;
185  virtual bool HasURL() const;
186  virtual bool HasFile() const;
187  virtual bool HasFileContents() const;
188  virtual bool HasHtml() const;
189  virtual bool HasCustomFormat(OSExchangeData::CustomFormat format) const;
190  virtual void SetDownloadFileInfo(
191      const OSExchangeData::DownloadFileInfo& download_info);
192  virtual void SetInDragLoop(bool in_drag_loop) OVERRIDE;
193#if defined(USE_AURA)
194  virtual void SetDragImage(const gfx::ImageSkia& image,
195                            const gfx::Vector2d& cursor_offset) OVERRIDE;
196  virtual const gfx::ImageSkia& GetDragImage() const OVERRIDE;
197  virtual const gfx::Vector2d& GetDragImageOffset() const OVERRIDE;
198#endif
199
200 private:
201  scoped_refptr<DataObjectImpl> data_;
202  base::win::ScopedComPtr<IDataObject> source_object_;
203
204#if defined(USE_AURA)
205  // Drag image and offset data. Only used for Ash.
206  gfx::ImageSkia drag_image_;
207  gfx::Vector2d drag_image_offset_;
208#endif
209
210  DISALLOW_COPY_AND_ASSIGN(OSExchangeDataProviderWin);
211};
212
213}  // namespace ui
214
215#endif  // UI_BASE_DRAGDROP_OS_EXCHANGE_DATA_PROVIDER_WIN_H_
216