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: ~Observer()39 virtual ~Observer() { } 40 }; 41 42 DataObjectImpl(); 43 44 // Accessors. set_observer(Observer * observer)45 void set_observer(Observer* observer) { observer_ = observer; } set_in_drag_loop(bool in_drag_loop)46 void set_in_drag_loop(bool in_drag_loop) { in_drag_loop_ = in_drag_loop; } 47 48 // Number of known formats. size()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 StoredDataInfoStoredDataInfo102 StoredDataInfo(const FORMATETC& format_etc, STGMEDIUM* medium) 103 : format_etc(format_etc), medium(medium), owns_medium(true) {} 104 ~StoredDataInfoStoredDataInfo105 ~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 data_object()146 IDataObject* data_object() const { return data_.get(); } async_operation()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(OSExchangeData::FilenameToURLPolicy policy, 164 GURL* url, 165 base::string16* title) const; 166 virtual bool GetFilename(base::FilePath* path) const; 167 virtual bool GetFilenames( 168 std::vector<OSExchangeData::FileInfo>* filenames) const; 169 virtual bool GetPickledData(const OSExchangeData::CustomFormat& format, 170 Pickle* data) const; 171 virtual bool GetFileContents(base::FilePath* filename, 172 std::string* file_contents) const; 173 virtual bool GetHtml(base::string16* html, GURL* base_url) const; 174 virtual bool HasString() const; 175 virtual bool HasURL() const; 176 virtual bool HasFile() const; 177 virtual bool HasFileContents() const; 178 virtual bool HasHtml() const; 179 virtual bool HasCustomFormat( 180 const OSExchangeData::CustomFormat& format) const; 181 virtual void SetDownloadFileInfo( 182 const OSExchangeData::DownloadFileInfo& download_info); 183 virtual void SetInDragLoop(bool in_drag_loop) OVERRIDE; 184 #if defined(USE_AURA) 185 virtual void SetDragImage(const gfx::ImageSkia& image, 186 const gfx::Vector2d& cursor_offset) OVERRIDE; 187 virtual const gfx::ImageSkia& GetDragImage() const OVERRIDE; 188 virtual const gfx::Vector2d& GetDragImageOffset() const OVERRIDE; 189 #endif 190 191 private: 192 scoped_refptr<DataObjectImpl> data_; 193 base::win::ScopedComPtr<IDataObject> source_object_; 194 195 #if defined(USE_AURA) 196 // Drag image and offset data. Only used for Ash. 197 gfx::ImageSkia drag_image_; 198 gfx::Vector2d drag_image_offset_; 199 #endif 200 201 DISALLOW_COPY_AND_ASSIGN(OSExchangeDataProviderWin); 202 }; 203 204 } // namespace ui 205 206 #endif // UI_BASE_DRAGDROP_OS_EXCHANGE_DATA_PROVIDER_WIN_H_ 207