michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef _NSDATAOBJ_H_ michael@0: #define _NSDATAOBJ_H_ michael@0: michael@0: #include michael@0: #include michael@0: michael@0: #include "nsCOMPtr.h" michael@0: #include "nsString.h" michael@0: #include "nsIFile.h" michael@0: #include "nsIURI.h" michael@0: #include "nsIInputStream.h" michael@0: #include "nsIStreamListener.h" michael@0: #include "nsIChannel.h" michael@0: #include "nsCOMArray.h" michael@0: #include "nsITimer.h" michael@0: michael@0: class nsIThread; michael@0: michael@0: // The SDK shipping with VC11 has renamed IAsyncOperation to michael@0: // IDataObjectAsyncCapability. We try to detect this, and rename this in our michael@0: // code too to make sure that we pick the correct name when building. michael@0: #ifdef __IDataObjectAsyncCapability_INTERFACE_DEFINED__ michael@0: #define IAsyncOperation IDataObjectAsyncCapability michael@0: #define IID_IAsyncOperation IID_IDataObjectAsyncCapability michael@0: #else michael@0: // XXX for older version of PSDK where IAsyncOperation and related stuff is not available michael@0: // but thisdefine should be removed when parocles config is updated michael@0: #ifndef __IAsyncOperation_INTERFACE_DEFINED__ michael@0: // IAsyncOperation interface definition michael@0: EXTERN_C const IID IID_IAsyncOperation; michael@0: michael@0: MIDL_INTERFACE("3D8B0590-F691-11d2-8EA9-006097DF5BD4") michael@0: IAsyncOperation : public IUnknown michael@0: { michael@0: virtual HRESULT STDMETHODCALLTYPE SetAsyncMode(BOOL fDoOpAsync) = 0; michael@0: virtual HRESULT STDMETHODCALLTYPE GetAsyncMode(BOOL *pfIsOpAsync) = 0; michael@0: virtual HRESULT STDMETHODCALLTYPE StartOperation(IBindCtx *pbcReserved) = 0; michael@0: virtual HRESULT STDMETHODCALLTYPE InOperation(BOOL *pfInAsyncOp) = 0; michael@0: virtual HRESULT STDMETHODCALLTYPE EndOperation(HRESULT hResult, michael@0: IBindCtx *pbcReserved, michael@0: DWORD dwEffects) = 0; michael@0: }; michael@0: // this is not defined in the old headers for some reason michael@0: #ifndef FD_PROGRESSUI michael@0: #define FD_PROGRESSUI 0x4000 michael@0: #endif michael@0: michael@0: #endif // __IAsyncOperation_INTERFACE_DEFINED__ michael@0: #endif // __IDataObjectAsyncCapability_INTERFACE_DEFINED__ michael@0: michael@0: /* michael@0: * CFSTR_SHELLURL is deprecated and doesn't have a Unicode version. michael@0: * Therefore we are using CFSTR_INETURL instead of CFSTR_SHELLURL. michael@0: * See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/programmersguide/shell_basics/shell_basics_programming/transferring/clipboard.asp michael@0: */ michael@0: #ifndef CFSTR_INETURLA michael@0: #define CFSTR_INETURLA L"UniformResourceLocator" michael@0: #endif michael@0: #ifndef CFSTR_INETURLW michael@0: #define CFSTR_INETURLW L"UniformResourceLocatorW" michael@0: #endif michael@0: michael@0: // For support of MinGW w32api v2.4. michael@0: // When the next version of w32api is released with shlobj.h rev 1.35 michael@0: // http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/winsup/w32api/include/shlobj.h?cvsroot=src michael@0: // then that can be made the base required version and this code should be removed. michael@0: #ifndef CFSTR_FILEDESCRIPTORA michael@0: # define CFSTR_FILEDESCRIPTORA L"FileGroupDescriptor" michael@0: #endif michael@0: #ifndef CFSTR_FILEDESCRIPTORW michael@0: # define CFSTR_FILEDESCRIPTORW L"FileGroupDescriptorW" michael@0: #endif michael@0: michael@0: class CEnumFormatEtc; michael@0: class nsITransferable; michael@0: michael@0: /* michael@0: * This ole registered class is used to facilitate drag-drop of objects which michael@0: * can be adapted by an object derived from CfDragDrop. The CfDragDrop is michael@0: * associated with instances via SetDragDrop(). michael@0: */ michael@0: class nsDataObj : public IDataObject, michael@0: public IAsyncOperation michael@0: { michael@0: michael@0: protected: michael@0: nsCOMPtr mIOThread; michael@0: michael@0: public: // construction, destruction michael@0: nsDataObj(nsIURI *uri = nullptr); michael@0: virtual ~nsDataObj(); michael@0: michael@0: public: // IUnknown methods - see iunknown.h for documentation michael@0: STDMETHODIMP_(ULONG) AddRef (); michael@0: STDMETHODIMP QueryInterface(REFIID, void**); michael@0: STDMETHODIMP_(ULONG) Release (); michael@0: michael@0: // support for clipboard michael@0: void AddDataFlavor(const char* aDataFlavor, LPFORMATETC aFE); michael@0: void SetTransferable(nsITransferable * aTransferable); michael@0: michael@0: // Return the registered OLE class ID of this object's CfDataObj. michael@0: CLSID GetClassID() const; michael@0: michael@0: public: // IDataObject methods - these are general comments. see CfDragDrop michael@0: // for overriding behavior michael@0: michael@0: // Store data in pSTM according to the format specified by pFE, if the michael@0: // format is supported (supported formats are specified in CfDragDrop:: michael@0: // GetFormats) and return NOERROR; otherwise return DATA_E_FORMATETC. It michael@0: // is the callers responsibility to free pSTM if NOERROR is returned. michael@0: STDMETHODIMP GetData (LPFORMATETC pFE, LPSTGMEDIUM pSTM); michael@0: michael@0: // Similar to GetData except that the caller allocates the structure michael@0: // referenced by pSTM. michael@0: STDMETHODIMP GetDataHere (LPFORMATETC pFE, LPSTGMEDIUM pSTM); michael@0: michael@0: // Returns S_TRUE if this object supports the format specified by pSTM, michael@0: // S_FALSE otherwise. michael@0: STDMETHODIMP QueryGetData (LPFORMATETC pFE); michael@0: michael@0: // Set pCanonFE to the canonical format of pFE if one exists and return michael@0: // NOERROR, otherwise return DATA_S_SAMEFORMATETC. A canonical format michael@0: // implies an identical rendering. michael@0: STDMETHODIMP GetCanonicalFormatEtc (LPFORMATETC pFE, LPFORMATETC pCanonFE); michael@0: michael@0: // Set this objects data according to the format specified by pFE and michael@0: // the storage medium specified by pSTM and return NOERROR, if the format michael@0: // is supported. If release is TRUE this object must release the storage michael@0: // associated with pSTM. michael@0: STDMETHODIMP SetData (LPFORMATETC pFE, LPSTGMEDIUM pSTM, BOOL release); michael@0: michael@0: // Set ppEnum to an IEnumFORMATETC object which will iterate all of the michael@0: // data formats that this object supports. direction is either DATADIR_GET michael@0: // or DATADIR_SET. michael@0: STDMETHODIMP EnumFormatEtc (DWORD direction, LPENUMFORMATETC* ppEnum); michael@0: michael@0: // Set up an advisory connection to this object based on the format specified michael@0: // by pFE, flags, and the pAdvise. Set pConn to the established advise michael@0: // connection. michael@0: STDMETHODIMP DAdvise (LPFORMATETC pFE, DWORD flags, LPADVISESINK pAdvise, michael@0: DWORD* pConn); michael@0: michael@0: // Turn off advising of a previous call to DAdvise which set pConn. michael@0: STDMETHODIMP DUnadvise (DWORD pConn); michael@0: michael@0: // Set ppEnum to an IEnumSTATDATA object which will iterate over the michael@0: // existing objects which have established advisory connections to this michael@0: // object. michael@0: STDMETHODIMP EnumDAdvise (LPENUMSTATDATA *ppEnum); michael@0: michael@0: // IAsyncOperation methods michael@0: STDMETHOD(EndOperation)(HRESULT hResult, IBindCtx *pbcReserved, DWORD dwEffects); michael@0: STDMETHOD(GetAsyncMode)(BOOL *pfIsOpAsync); michael@0: STDMETHOD(InOperation)(BOOL *pfInAsyncOp); michael@0: STDMETHOD(SetAsyncMode)(BOOL fDoOpAsync); michael@0: STDMETHOD(StartOperation)(IBindCtx *pbcReserved); michael@0: michael@0: public: // other methods michael@0: michael@0: // Gets the filename from the kFilePromiseURLMime flavour michael@0: HRESULT GetDownloadDetails(nsIURI **aSourceURI, michael@0: nsAString &aFilename); michael@0: michael@0: protected: michael@0: // help determine the kind of drag michael@0: bool IsFlavourPresent(const char *inFlavour); michael@0: michael@0: virtual HRESULT AddSetFormat(FORMATETC& FE); michael@0: virtual HRESULT AddGetFormat(FORMATETC& FE); michael@0: michael@0: virtual HRESULT GetFile ( FORMATETC& aFE, STGMEDIUM& aSTG ); michael@0: virtual HRESULT GetText ( const nsACString& aDF, FORMATETC& aFE, STGMEDIUM & aSTG ); michael@0: virtual HRESULT GetDib ( const nsACString& inFlavor, FORMATETC &, STGMEDIUM & aSTG ); michael@0: virtual HRESULT GetMetafilePict(FORMATETC& FE, STGMEDIUM& STM); michael@0: michael@0: virtual HRESULT DropImage( FORMATETC& aFE, STGMEDIUM& aSTG ); michael@0: virtual HRESULT DropFile( FORMATETC& aFE, STGMEDIUM& aSTG ); michael@0: virtual HRESULT DropTempFile( FORMATETC& aFE, STGMEDIUM& aSTG ); michael@0: michael@0: virtual HRESULT GetUniformResourceLocator ( FORMATETC& aFE, STGMEDIUM& aSTG, bool aIsUnicode ) ; michael@0: virtual HRESULT ExtractUniformResourceLocatorA ( FORMATETC& aFE, STGMEDIUM& aSTG ) ; michael@0: virtual HRESULT ExtractUniformResourceLocatorW ( FORMATETC& aFE, STGMEDIUM& aSTG ) ; michael@0: virtual HRESULT GetFileDescriptor ( FORMATETC& aFE, STGMEDIUM& aSTG, bool aIsUnicode ) ; michael@0: virtual HRESULT GetFileContents ( FORMATETC& aFE, STGMEDIUM& aSTG ) ; michael@0: virtual HRESULT GetPreferredDropEffect ( FORMATETC& aFE, STGMEDIUM& aSTG ); michael@0: michael@0: virtual HRESULT SetBitmap(FORMATETC& FE, STGMEDIUM& STM); michael@0: virtual HRESULT SetDib (FORMATETC& FE, STGMEDIUM& STM); michael@0: virtual HRESULT SetText (FORMATETC& FE, STGMEDIUM& STM); michael@0: virtual HRESULT SetMetafilePict(FORMATETC& FE, STGMEDIUM& STM); michael@0: michael@0: // Provide the structures needed for an internet shortcut by the shell michael@0: virtual HRESULT GetFileDescriptorInternetShortcutA ( FORMATETC& aFE, STGMEDIUM& aSTG ) ; michael@0: virtual HRESULT GetFileDescriptorInternetShortcutW ( FORMATETC& aFE, STGMEDIUM& aSTG ) ; michael@0: virtual HRESULT GetFileContentsInternetShortcut ( FORMATETC& aFE, STGMEDIUM& aSTG ) ; michael@0: michael@0: // IStream implementation michael@0: virtual HRESULT GetFileDescriptor_IStreamA ( FORMATETC& aFE, STGMEDIUM& aSTG ) ; michael@0: virtual HRESULT GetFileDescriptor_IStreamW ( FORMATETC& aFE, STGMEDIUM& aSTG ) ; michael@0: virtual HRESULT GetFileContents_IStream ( FORMATETC& aFE, STGMEDIUM& aSTG ) ; michael@0: michael@0: nsresult ExtractShortcutURL ( nsString & outURL ) ; michael@0: nsresult ExtractShortcutTitle ( nsString & outTitle ) ; michael@0: michael@0: // munge our HTML data to win32's CF_HTML spec. Will null terminate michael@0: nsresult BuildPlatformHTML ( const char* inOurHTML, char** outPlatformHTML ) ; michael@0: michael@0: // Used for the SourceURL part of CF_HTML michael@0: nsCString mSourceURL; michael@0: michael@0: BOOL FormatsMatch(const FORMATETC& source, const FORMATETC& target) const; michael@0: michael@0: ULONG m_cRef; // the reference count michael@0: michael@0: nsTArray mDataFlavors; michael@0: michael@0: nsITransferable * mTransferable; // nsDataObj owns and ref counts nsITransferable, michael@0: // the nsITransferable does know anything about the nsDataObj michael@0: michael@0: CEnumFormatEtc * m_enumFE; // Ownership Rules: michael@0: // nsDataObj owns and ref counts CEnumFormatEtc, michael@0: michael@0: nsCOMPtr mCachedTempFile; michael@0: michael@0: BOOL mIsAsyncMode; michael@0: BOOL mIsInOperation; michael@0: /////////////////////////////////////////////////////////////////////////////// michael@0: // CStream class implementation michael@0: // this class is used in Drag and drop with download sample michael@0: // called from IDataObject::GetData michael@0: class CStream : public IStream, public nsIStreamListener michael@0: { michael@0: nsCOMPtr mChannel; michael@0: nsTArray mChannelData; michael@0: bool mChannelRead; michael@0: nsresult mChannelResult; michael@0: uint32_t mStreamRead; michael@0: michael@0: protected: michael@0: virtual ~CStream(); michael@0: nsresult WaitForCompletion(); michael@0: michael@0: public: michael@0: CStream(); michael@0: nsresult Init(nsIURI *pSourceURI); michael@0: michael@0: NS_DECL_ISUPPORTS michael@0: NS_DECL_NSIREQUESTOBSERVER michael@0: NS_DECL_NSISTREAMLISTENER michael@0: michael@0: // IUnknown michael@0: STDMETHOD(QueryInterface)(REFIID refiid, void** ppvResult); michael@0: michael@0: // IStream michael@0: STDMETHOD(Clone)(IStream** ppStream); michael@0: STDMETHOD(Commit)(DWORD dwFrags); michael@0: STDMETHOD(CopyTo)(IStream* pDestStream, ULARGE_INTEGER nBytesToCopy, ULARGE_INTEGER* nBytesRead, ULARGE_INTEGER* nBytesWritten); michael@0: STDMETHOD(LockRegion)(ULARGE_INTEGER nStart, ULARGE_INTEGER nBytes, DWORD dwFlags); michael@0: STDMETHOD(Read)(void* pvBuffer, ULONG nBytesToRead, ULONG* nBytesRead); michael@0: STDMETHOD(Revert)(void); michael@0: STDMETHOD(Seek)(LARGE_INTEGER nMove, DWORD dwOrigin, ULARGE_INTEGER* nNewPos); michael@0: STDMETHOD(SetSize)(ULARGE_INTEGER nNewSize); michael@0: STDMETHOD(Stat)(STATSTG* statstg, DWORD dwFlags); michael@0: STDMETHOD(UnlockRegion)(ULARGE_INTEGER nStart, ULARGE_INTEGER nBytes, DWORD dwFlags); michael@0: STDMETHOD(Write)(const void* pvBuffer, ULONG nBytesToRead, ULONG* nBytesRead); michael@0: }; michael@0: michael@0: HRESULT CreateStream(IStream **outStream); michael@0: michael@0: private: michael@0: michael@0: // Drag and drop helper data for implementing drag and drop image support michael@0: typedef struct { michael@0: FORMATETC fe; michael@0: STGMEDIUM stgm; michael@0: } DATAENTRY, *LPDATAENTRY; michael@0: michael@0: nsTArray mDataEntryList; michael@0: nsCOMPtr mTimer; michael@0: michael@0: bool LookupArbitraryFormat(FORMATETC *aFormat, LPDATAENTRY *aDataEntry, BOOL aAddorUpdate); michael@0: bool CopyMediumData(STGMEDIUM *aMediumDst, STGMEDIUM *aMediumSrc, LPFORMATETC aFormat, BOOL aSetData); michael@0: static void RemoveTempFile(nsITimer* aTimer, void* aClosure); michael@0: }; michael@0: michael@0: michael@0: #endif // _NSDATAOBJ_H_ michael@0: