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