2001-09-28 20:14:13 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
|
|
|
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
1999-03-25 04:38:25 +00:00
|
|
|
*
|
2001-09-28 20:14:13 +00:00
|
|
|
* The contents of this file are subject to the Netscape Public License
|
|
|
|
* Version 1.1 (the "License"); you may not use this file except in
|
|
|
|
* compliance with the License. You may obtain a copy of the License at
|
|
|
|
* http://www.mozilla.org/NPL/
|
1999-03-25 04:38:25 +00:00
|
|
|
*
|
2001-09-28 20:14:13 +00:00
|
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
|
|
* for the specific language governing rights and limitations under the
|
|
|
|
* License.
|
1999-03-25 04:38:25 +00:00
|
|
|
*
|
1999-11-06 03:40:37 +00:00
|
|
|
* The Original Code is mozilla.org code.
|
|
|
|
*
|
2001-09-28 20:14:13 +00:00
|
|
|
* The Initial Developer of the Original Code is
|
|
|
|
* Netscape Communications Corporation.
|
|
|
|
* Portions created by the Initial Developer are Copyright (C) 1998
|
|
|
|
* the Initial Developer. All Rights Reserved.
|
1999-11-06 03:40:37 +00:00
|
|
|
*
|
2001-09-28 20:14:13 +00:00
|
|
|
* Contributor(s):
|
2001-03-31 05:04:57 +00:00
|
|
|
* Sean Echevarria <Sean@Beatnik.com>
|
2002-01-30 23:31:46 +00:00
|
|
|
* Blake Ross <blaker@netscape.com>
|
2001-09-28 20:14:13 +00:00
|
|
|
*
|
|
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
|
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
|
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
|
|
* use your version of this file under the terms of the NPL, indicate your
|
|
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
|
|
* the provisions above, a recipient may use your version of this file under
|
|
|
|
* the terms of any one of the NPL, the GPL or the LGPL.
|
|
|
|
*
|
|
|
|
* ***** END LICENSE BLOCK ***** */
|
1999-03-23 15:37:34 +00:00
|
|
|
|
|
|
|
#include "nsDataObj.h"
|
2002-05-01 21:58:38 +00:00
|
|
|
#include "nsClipboard.h"
|
1999-03-23 15:37:34 +00:00
|
|
|
#include "nsString.h"
|
2001-09-29 08:28:41 +00:00
|
|
|
#include "nsReadableUtils.h"
|
1999-05-13 21:53:57 +00:00
|
|
|
#include "nsVoidArray.h"
|
1999-03-23 15:37:34 +00:00
|
|
|
#include "nsITransferable.h"
|
1999-08-25 08:35:06 +00:00
|
|
|
#include "nsISupportsPrimitives.h"
|
1999-03-23 15:37:34 +00:00
|
|
|
#include "IENUMFE.h"
|
1999-08-25 08:35:06 +00:00
|
|
|
#include "nsCOMPtr.h"
|
|
|
|
#include "nsIComponentManager.h"
|
1999-12-02 23:17:31 +00:00
|
|
|
#include "nsPrimitiveHelpers.h"
|
2000-05-02 22:39:08 +00:00
|
|
|
#include "nsXPIDLString.h"
|
2001-01-23 01:09:58 +00:00
|
|
|
#include "nsIImage.h"
|
|
|
|
#include "nsImageClipboard.h"
|
2001-03-31 05:04:57 +00:00
|
|
|
#include "prprf.h"
|
2002-05-15 18:55:21 +00:00
|
|
|
#include "nsCRT.h"
|
1999-03-23 15:37:34 +00:00
|
|
|
|
|
|
|
#include "OLE2.h"
|
|
|
|
#include "URLMON.h"
|
2000-05-02 22:39:08 +00:00
|
|
|
#include "shlobj.h"
|
1999-03-23 15:37:34 +00:00
|
|
|
|
2000-06-07 02:11:40 +00:00
|
|
|
#if 0
|
2000-10-28 22:17:53 +00:00
|
|
|
#define PRNTDEBUG(_x) printf(_x);
|
|
|
|
#define PRNTDEBUG2(_x1, _x2) printf(_x1, _x2);
|
|
|
|
#define PRNTDEBUG3(_x1, _x2, _x3) printf(_x1, _x2, _x3);
|
1999-05-04 22:44:16 +00:00
|
|
|
#else
|
2000-10-28 22:17:53 +00:00
|
|
|
#define PRNTDEBUG(_x) // printf(_x);
|
|
|
|
#define PRNTDEBUG2(_x1, _x2) // printf(_x1, _x2);
|
|
|
|
#define PRNTDEBUG3(_x1, _x2, _x3) // printf(_x1, _x2, _x3);
|
1999-05-04 22:44:16 +00:00
|
|
|
#endif
|
1999-04-30 19:41:14 +00:00
|
|
|
|
1999-03-23 15:37:34 +00:00
|
|
|
ULONG nsDataObj::g_cRef = 0;
|
|
|
|
|
1999-03-23 21:26:41 +00:00
|
|
|
EXTERN_C GUID CDECL CLSID_nsDataObj =
|
|
|
|
{ 0x1bba7640, 0xdf52, 0x11cf, { 0x82, 0x7b, 0, 0xa0, 0x24, 0x3a, 0xe5, 0x05 } };
|
1999-03-23 15:37:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Class nsDataObj
|
|
|
|
*/
|
|
|
|
|
1999-05-04 22:44:16 +00:00
|
|
|
//-----------------------------------------------------
|
|
|
|
// construction
|
|
|
|
//-----------------------------------------------------
|
1999-03-23 15:37:34 +00:00
|
|
|
nsDataObj::nsDataObj()
|
|
|
|
{
|
|
|
|
m_cRef = 0;
|
|
|
|
mTransferable = nsnull;
|
1999-05-13 21:53:57 +00:00
|
|
|
mDataFlavors = new nsVoidArray();
|
1999-03-23 15:37:34 +00:00
|
|
|
|
1999-05-04 22:44:16 +00:00
|
|
|
m_enumFE = new CEnumFormatEtc(32);
|
1999-03-23 15:37:34 +00:00
|
|
|
m_enumFE->AddRef();
|
1999-05-04 22:44:16 +00:00
|
|
|
|
1999-03-23 15:37:34 +00:00
|
|
|
}
|
|
|
|
|
1999-05-04 22:44:16 +00:00
|
|
|
//-----------------------------------------------------
|
|
|
|
// destruction
|
|
|
|
//-----------------------------------------------------
|
1999-03-23 15:37:34 +00:00
|
|
|
nsDataObj::~nsDataObj()
|
|
|
|
{
|
1999-05-04 22:44:16 +00:00
|
|
|
NS_IF_RELEASE(mTransferable);
|
1999-05-13 21:53:57 +00:00
|
|
|
PRInt32 i;
|
|
|
|
for (i=0;i<mDataFlavors->Count();i++) {
|
2000-01-29 20:24:50 +00:00
|
|
|
nsCAutoString* df = NS_REINTERPRET_CAST(nsCAutoString *, mDataFlavors->ElementAt(i));
|
1999-05-13 21:53:57 +00:00
|
|
|
delete df;
|
|
|
|
}
|
1999-05-04 22:44:16 +00:00
|
|
|
|
1999-05-18 21:40:33 +00:00
|
|
|
delete mDataFlavors;
|
|
|
|
|
2000-01-29 20:24:50 +00:00
|
|
|
m_cRef = 0;
|
1999-03-23 15:37:34 +00:00
|
|
|
m_enumFE->Release();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-05-04 22:44:16 +00:00
|
|
|
//-----------------------------------------------------
|
1999-03-23 15:37:34 +00:00
|
|
|
// IUnknown interface methods - see inknown.h for documentation
|
1999-05-04 22:44:16 +00:00
|
|
|
//-----------------------------------------------------
|
1999-03-23 15:37:34 +00:00
|
|
|
STDMETHODIMP nsDataObj::QueryInterface(REFIID riid, void** ppv)
|
|
|
|
{
|
|
|
|
*ppv=NULL;
|
|
|
|
|
|
|
|
if ( (IID_IUnknown == riid) || (IID_IDataObject == riid) ) {
|
|
|
|
*ppv = this;
|
|
|
|
AddRef();
|
|
|
|
return NOERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ResultFromScode(E_NOINTERFACE);
|
|
|
|
}
|
|
|
|
|
1999-05-04 22:44:16 +00:00
|
|
|
//-----------------------------------------------------
|
1999-03-23 15:37:34 +00:00
|
|
|
STDMETHODIMP_(ULONG) nsDataObj::AddRef()
|
|
|
|
{
|
|
|
|
++g_cRef;
|
2002-01-07 23:55:11 +00:00
|
|
|
++m_cRef;
|
|
|
|
NS_LOG_ADDREF(this, m_cRef, "nsDataObj", sizeof(*this));
|
2000-10-28 22:17:53 +00:00
|
|
|
//PRNTDEBUG3("nsDataObj::AddRef >>>>>>>>>>>>>>>>>> %d on %p\n", (m_cRef+1), this);
|
2002-01-07 23:55:11 +00:00
|
|
|
return m_cRef;
|
1999-03-23 15:37:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-05-04 22:44:16 +00:00
|
|
|
//-----------------------------------------------------
|
1999-03-23 15:37:34 +00:00
|
|
|
STDMETHODIMP_(ULONG) nsDataObj::Release()
|
|
|
|
{
|
2000-10-28 22:17:53 +00:00
|
|
|
//PRNTDEBUG3("nsDataObj::Release >>>>>>>>>>>>>>>>>> %d on %p\n", (m_cRef-1), this);
|
1999-03-23 15:37:34 +00:00
|
|
|
if (0 < g_cRef)
|
|
|
|
--g_cRef;
|
|
|
|
|
2002-01-07 23:55:11 +00:00
|
|
|
NS_LOG_RELEASE(this, m_cRef, "nsDataObj");
|
1999-03-23 15:37:34 +00:00
|
|
|
if (0 != --m_cRef)
|
|
|
|
return m_cRef;
|
|
|
|
|
|
|
|
delete this;
|
1999-05-04 22:44:16 +00:00
|
|
|
|
1999-03-23 15:37:34 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
1999-05-04 22:44:16 +00:00
|
|
|
//-----------------------------------------------------
|
1999-03-23 15:37:34 +00:00
|
|
|
BOOL nsDataObj::FormatsMatch(const FORMATETC& source, const FORMATETC& target) const
|
|
|
|
{
|
|
|
|
if ((source.cfFormat == target.cfFormat) &&
|
|
|
|
(source.dwAspect & target.dwAspect) &&
|
|
|
|
(source.tymed & target.tymed)) {
|
|
|
|
return TRUE;
|
|
|
|
} else {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-05-04 22:44:16 +00:00
|
|
|
//-----------------------------------------------------
|
1999-03-23 15:37:34 +00:00
|
|
|
// IDataObject methods
|
1999-05-04 22:44:16 +00:00
|
|
|
//-----------------------------------------------------
|
1999-03-23 15:37:34 +00:00
|
|
|
STDMETHODIMP nsDataObj::GetData(LPFORMATETC pFE, LPSTGMEDIUM pSTM)
|
|
|
|
{
|
2000-10-28 22:17:53 +00:00
|
|
|
PRNTDEBUG("nsDataObj::GetData\n");
|
|
|
|
PRNTDEBUG3(" format: %d Text: %d\n", pFE->cfFormat, CF_TEXT);
|
2000-05-02 22:39:08 +00:00
|
|
|
if ( !mTransferable )
|
1999-03-23 15:37:34 +00:00
|
|
|
return ResultFromScode(DATA_E_FORMATETC);
|
|
|
|
|
|
|
|
PRUint32 dfInx = 0;
|
|
|
|
|
2000-05-02 22:39:08 +00:00
|
|
|
static CLIPFORMAT fileDescriptorFlavor = ::RegisterClipboardFormat( CFSTR_FILEDESCRIPTOR );
|
|
|
|
static CLIPFORMAT fileFlavor = ::RegisterClipboardFormat( CFSTR_FILECONTENTS );
|
|
|
|
|
1999-03-23 15:37:34 +00:00
|
|
|
ULONG count;
|
|
|
|
FORMATETC fe;
|
|
|
|
m_enumFE->Reset();
|
|
|
|
while (NOERROR == m_enumFE->Next(1, &fe, &count)) {
|
2001-12-21 01:10:07 +00:00
|
|
|
nsCAutoString * df = NS_REINTERPRET_CAST(nsCAutoString*, mDataFlavors->SafeElementAt(dfInx));
|
2000-01-29 20:24:50 +00:00
|
|
|
if ( df ) {
|
1999-03-23 15:37:34 +00:00
|
|
|
if (FormatsMatch(fe, *pFE)) {
|
2001-03-27 06:02:54 +00:00
|
|
|
pSTM->pUnkForRelease = NULL; // caller is responsible for deleting this data
|
1999-03-23 15:37:34 +00:00
|
|
|
CLIPFORMAT format = pFE->cfFormat;
|
|
|
|
switch(format) {
|
2001-01-23 01:09:58 +00:00
|
|
|
|
|
|
|
// Someone is asking for plain or unicode text
|
1999-03-23 15:37:34 +00:00
|
|
|
case CF_TEXT:
|
2000-01-29 20:24:50 +00:00
|
|
|
case CF_UNICODETEXT:
|
2001-01-23 01:09:58 +00:00
|
|
|
return GetText(*df, *pFE, *pSTM);
|
|
|
|
break;
|
|
|
|
|
|
|
|
// Someone is asking for an image
|
|
|
|
case CF_DIB:
|
|
|
|
return GetDib(*df, *pFE, *pSTM);
|
|
|
|
|
2000-05-02 22:39:08 +00:00
|
|
|
// ... not yet implemented ...
|
1999-03-23 15:37:34 +00:00
|
|
|
//case CF_BITMAP:
|
|
|
|
// return GetBitmap(*pFE, *pSTM);
|
|
|
|
//case CF_METAFILEPICT:
|
|
|
|
// return GetMetafilePict(*pFE, *pSTM);
|
2000-05-02 22:39:08 +00:00
|
|
|
|
1999-03-23 15:37:34 +00:00
|
|
|
default:
|
2000-05-02 22:39:08 +00:00
|
|
|
|
|
|
|
if ( format == fileDescriptorFlavor )
|
|
|
|
return GetFileDescriptor ( *pFE, *pSTM );
|
|
|
|
else if ( format == fileFlavor )
|
|
|
|
return GetFileContents ( *pFE, *pSTM );
|
|
|
|
else {
|
2000-10-28 22:17:53 +00:00
|
|
|
PRNTDEBUG2("***** nsDataObj::GetData - Unknown format %x\n", format);
|
2001-01-23 01:09:58 +00:00
|
|
|
return GetText(*df, *pFE, *pSTM);
|
2000-05-02 22:39:08 +00:00
|
|
|
}
|
1999-03-23 15:37:34 +00:00
|
|
|
break;
|
2000-05-02 22:39:08 +00:00
|
|
|
|
1999-03-23 15:37:34 +00:00
|
|
|
} //switch
|
|
|
|
} // if
|
|
|
|
}
|
|
|
|
dfInx++;
|
|
|
|
} // while
|
|
|
|
|
|
|
|
return ResultFromScode(DATA_E_FORMATETC);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-05-04 22:44:16 +00:00
|
|
|
//-----------------------------------------------------
|
1999-03-23 15:37:34 +00:00
|
|
|
STDMETHODIMP nsDataObj::GetDataHere(LPFORMATETC pFE, LPSTGMEDIUM pSTM)
|
|
|
|
{
|
2000-10-28 22:17:53 +00:00
|
|
|
PRNTDEBUG("nsDataObj::GetDataHere\n");
|
1999-03-23 15:37:34 +00:00
|
|
|
return ResultFromScode(E_FAIL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-05-04 22:44:16 +00:00
|
|
|
//-----------------------------------------------------
|
|
|
|
// Other objects querying to see if we support a
|
|
|
|
// particular format
|
|
|
|
//-----------------------------------------------------
|
1999-03-23 15:37:34 +00:00
|
|
|
STDMETHODIMP nsDataObj::QueryGetData(LPFORMATETC pFE)
|
|
|
|
{
|
1999-05-04 22:44:16 +00:00
|
|
|
PRNTDEBUG("nsDataObj::QueryGetData ");
|
2000-10-28 22:17:53 +00:00
|
|
|
PRNTDEBUG3("format: %d Text: %d\n", pFE->cfFormat, CF_TEXT);
|
1999-04-17 13:49:39 +00:00
|
|
|
|
|
|
|
PRUint32 dfInx = 0;
|
|
|
|
|
|
|
|
ULONG count;
|
|
|
|
FORMATETC fe;
|
|
|
|
m_enumFE->Reset();
|
|
|
|
while (NOERROR == m_enumFE->Next(1, &fe, &count)) {
|
|
|
|
if (fe.cfFormat == pFE->cfFormat) {
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
}
|
2000-02-01 22:26:21 +00:00
|
|
|
|
2000-10-28 22:17:53 +00:00
|
|
|
PRNTDEBUG2("***** nsDataObj::QueryGetData - Unknown format %d\n", pFE->cfFormat);
|
1999-04-17 13:49:39 +00:00
|
|
|
return ResultFromScode(E_FAIL);
|
1999-03-23 15:37:34 +00:00
|
|
|
}
|
|
|
|
|
1999-05-04 22:44:16 +00:00
|
|
|
//-----------------------------------------------------
|
1999-03-23 15:37:34 +00:00
|
|
|
STDMETHODIMP nsDataObj::GetCanonicalFormatEtc
|
|
|
|
(LPFORMATETC pFEIn, LPFORMATETC pFEOut)
|
|
|
|
{
|
2000-10-28 22:17:53 +00:00
|
|
|
PRNTDEBUG("nsDataObj::GetCanonicalFormatEtc\n");
|
1999-03-23 15:37:34 +00:00
|
|
|
return ResultFromScode(E_FAIL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-05-04 22:44:16 +00:00
|
|
|
//-----------------------------------------------------
|
1999-03-23 15:37:34 +00:00
|
|
|
STDMETHODIMP nsDataObj::SetData(LPFORMATETC pFE, LPSTGMEDIUM pSTM, BOOL fRelease)
|
|
|
|
{
|
2000-10-28 22:17:53 +00:00
|
|
|
PRNTDEBUG("nsDataObj::SetData\n");
|
1999-05-04 22:44:16 +00:00
|
|
|
|
1999-03-23 15:37:34 +00:00
|
|
|
return ResultFromScode(E_FAIL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-05-04 22:44:16 +00:00
|
|
|
//-----------------------------------------------------
|
1999-03-23 15:37:34 +00:00
|
|
|
STDMETHODIMP nsDataObj::EnumFormatEtc(DWORD dwDir, LPENUMFORMATETC *ppEnum)
|
|
|
|
{
|
2000-10-28 22:17:53 +00:00
|
|
|
PRNTDEBUG("nsDataObj::EnumFormatEtc\n");
|
1999-03-23 15:37:34 +00:00
|
|
|
|
|
|
|
switch (dwDir) {
|
|
|
|
case DATADIR_GET: {
|
|
|
|
m_enumFE->Clone(ppEnum);
|
|
|
|
} break;
|
|
|
|
case DATADIR_SET:
|
|
|
|
*ppEnum=NULL;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
*ppEnum=NULL;
|
|
|
|
break;
|
|
|
|
} // switch
|
1999-05-04 22:44:16 +00:00
|
|
|
|
|
|
|
// Since a new one has been created,
|
|
|
|
// we will ref count the new clone here
|
|
|
|
// before giving it back
|
|
|
|
if (NULL == *ppEnum)
|
1999-03-23 15:37:34 +00:00
|
|
|
return ResultFromScode(E_FAIL);
|
|
|
|
else
|
|
|
|
(*ppEnum)->AddRef();
|
|
|
|
|
|
|
|
return NOERROR;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
1999-05-04 22:44:16 +00:00
|
|
|
//-----------------------------------------------------
|
1999-03-23 15:37:34 +00:00
|
|
|
STDMETHODIMP nsDataObj::DAdvise(LPFORMATETC pFE, DWORD dwFlags,
|
1999-05-04 22:44:16 +00:00
|
|
|
LPADVISESINK pIAdviseSink, DWORD* pdwConn)
|
1999-03-23 15:37:34 +00:00
|
|
|
{
|
2000-10-28 22:17:53 +00:00
|
|
|
PRNTDEBUG("nsDataObj::DAdvise\n");
|
1999-03-23 15:37:34 +00:00
|
|
|
return ResultFromScode(E_FAIL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-05-04 22:44:16 +00:00
|
|
|
//-----------------------------------------------------
|
1999-03-23 15:37:34 +00:00
|
|
|
STDMETHODIMP nsDataObj::DUnadvise(DWORD dwConn)
|
|
|
|
{
|
2000-10-28 22:17:53 +00:00
|
|
|
PRNTDEBUG("nsDataObj::DUnadvise\n");
|
1999-03-23 15:37:34 +00:00
|
|
|
return ResultFromScode(E_FAIL);
|
|
|
|
}
|
|
|
|
|
1999-05-04 22:44:16 +00:00
|
|
|
//-----------------------------------------------------
|
1999-03-23 15:37:34 +00:00
|
|
|
STDMETHODIMP nsDataObj::EnumDAdvise(LPENUMSTATDATA *ppEnum)
|
|
|
|
{
|
2000-10-28 22:17:53 +00:00
|
|
|
PRNTDEBUG("nsDataObj::EnumDAdvise\n");
|
1999-03-23 15:37:34 +00:00
|
|
|
return ResultFromScode(E_FAIL);
|
|
|
|
}
|
|
|
|
|
1999-05-04 22:44:16 +00:00
|
|
|
//-----------------------------------------------------
|
1999-03-23 15:37:34 +00:00
|
|
|
// other methods
|
1999-05-04 22:44:16 +00:00
|
|
|
//-----------------------------------------------------
|
1999-03-23 15:37:34 +00:00
|
|
|
ULONG nsDataObj::GetCumRefCount()
|
|
|
|
{
|
|
|
|
return g_cRef;
|
|
|
|
}
|
|
|
|
|
1999-05-04 22:44:16 +00:00
|
|
|
//-----------------------------------------------------
|
1999-03-23 15:37:34 +00:00
|
|
|
ULONG nsDataObj::GetRefCount() const
|
|
|
|
{
|
|
|
|
return m_cRef;
|
|
|
|
}
|
|
|
|
|
1999-05-04 22:44:16 +00:00
|
|
|
//-----------------------------------------------------
|
1999-03-23 15:37:34 +00:00
|
|
|
// GetData and SetData helper functions
|
1999-05-04 22:44:16 +00:00
|
|
|
//-----------------------------------------------------
|
1999-03-23 15:37:34 +00:00
|
|
|
HRESULT nsDataObj::AddSetFormat(FORMATETC& aFE)
|
|
|
|
{
|
2000-10-28 22:17:53 +00:00
|
|
|
PRNTDEBUG("nsDataObj::AddSetFormat\n");
|
1999-03-23 15:37:34 +00:00
|
|
|
return ResultFromScode(S_OK);
|
|
|
|
}
|
|
|
|
|
1999-05-04 22:44:16 +00:00
|
|
|
//-----------------------------------------------------
|
1999-03-23 15:37:34 +00:00
|
|
|
HRESULT nsDataObj::AddGetFormat(FORMATETC& aFE)
|
|
|
|
{
|
2000-10-28 22:17:53 +00:00
|
|
|
PRNTDEBUG("nsDataObj::AddGetFormat\n");
|
1999-03-23 15:37:34 +00:00
|
|
|
return ResultFromScode(S_OK);
|
|
|
|
}
|
|
|
|
|
1999-05-04 22:44:16 +00:00
|
|
|
//-----------------------------------------------------
|
2001-01-23 01:09:58 +00:00
|
|
|
HRESULT
|
2002-03-23 22:26:36 +00:00
|
|
|
nsDataObj::GetBitmap ( const nsACString& , FORMATETC&, STGMEDIUM& )
|
1999-03-23 15:37:34 +00:00
|
|
|
{
|
2000-10-28 22:17:53 +00:00
|
|
|
PRNTDEBUG("nsDataObj::GetBitmap\n");
|
1999-03-23 15:37:34 +00:00
|
|
|
return ResultFromScode(E_NOTIMPL);
|
|
|
|
}
|
|
|
|
|
2001-01-23 01:09:58 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
// GetDIB
|
|
|
|
//
|
|
|
|
// Someone is asking for a bitmap. The data in the transferable will be a straight
|
|
|
|
// nsIImage, so just QI it.
|
|
|
|
//
|
|
|
|
HRESULT
|
2002-03-23 22:26:36 +00:00
|
|
|
nsDataObj :: GetDib ( const nsACString& inFlavor, FORMATETC &, STGMEDIUM & aSTG )
|
1999-03-23 15:37:34 +00:00
|
|
|
{
|
2000-10-28 22:17:53 +00:00
|
|
|
PRNTDEBUG("nsDataObj::GetDib\n");
|
2001-01-23 01:09:58 +00:00
|
|
|
ULONG result = E_FAIL;
|
|
|
|
|
2002-04-23 14:24:48 +00:00
|
|
|
|
2001-01-23 01:09:58 +00:00
|
|
|
PRUint32 len = 0;
|
|
|
|
nsCOMPtr<nsISupports> genericDataWrapper;
|
2001-04-02 19:40:52 +00:00
|
|
|
mTransferable->GetTransferData(PromiseFlatCString(inFlavor).get(), getter_AddRefs(genericDataWrapper), &len);
|
2001-01-23 01:09:58 +00:00
|
|
|
nsCOMPtr<nsIImage> image ( do_QueryInterface(genericDataWrapper) );
|
2002-04-23 14:24:48 +00:00
|
|
|
if ( !image ) {
|
|
|
|
// In the 0.9.4 timeframe, I had some embedding clients put the nsIImage directly into the
|
|
|
|
// transferable. Newer code, however, wraps the nsIImage in a nsISupportsInterfacePointer.
|
|
|
|
// We should be backwards compatibile with code already out in the field. If we can't find
|
|
|
|
// the image directly out of the transferable, unwrap the image from its wrapper.
|
|
|
|
nsCOMPtr<nsISupportsInterfacePointer> ptr(do_QueryInterface(genericDataWrapper));
|
|
|
|
if ( ptr )
|
|
|
|
ptr->GetData(getter_AddRefs(image));
|
|
|
|
}
|
|
|
|
|
2001-01-23 01:09:58 +00:00
|
|
|
if ( image ) {
|
2001-03-27 06:02:54 +00:00
|
|
|
// use a the helper class to build up a bitmap. We now own the bits,
|
|
|
|
// and pass them back to the OS in |aSTG|.
|
2001-01-23 01:09:58 +00:00
|
|
|
nsImageToClipboard converter ( image );
|
|
|
|
HANDLE bits = nsnull;
|
|
|
|
nsresult rv = converter.GetPicture ( &bits );
|
|
|
|
if ( NS_SUCCEEDED(rv) && bits ) {
|
|
|
|
aSTG.hGlobal = bits;
|
|
|
|
aSTG.tymed = TYMED_HGLOBAL;
|
|
|
|
result = S_OK;
|
|
|
|
}
|
|
|
|
} // if we have an image
|
|
|
|
else
|
|
|
|
NS_WARNING ( "Definately not an image on clipboard" );
|
|
|
|
|
|
|
|
return ResultFromScode(result);
|
1999-03-23 15:37:34 +00:00
|
|
|
}
|
|
|
|
|
2000-05-02 22:39:08 +00:00
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// GetFileDescriptor
|
|
|
|
//
|
|
|
|
|
|
|
|
HRESULT
|
|
|
|
nsDataObj :: GetFileDescriptor ( FORMATETC& aFE, STGMEDIUM& aSTG )
|
|
|
|
{
|
|
|
|
HRESULT res = S_OK;
|
|
|
|
|
|
|
|
// How we handle this depends on if we're dealing with an internet
|
|
|
|
// shortcut, since those are done under the covers.
|
|
|
|
if ( IsInternetShortcut() )
|
|
|
|
res = GetFileDescriptorInternetShortcut ( aFE, aSTG );
|
|
|
|
else
|
2000-10-28 22:17:53 +00:00
|
|
|
NS_WARNING ( "Not yet implemented\n" );
|
2000-05-02 22:39:08 +00:00
|
|
|
|
|
|
|
return res;
|
|
|
|
|
|
|
|
} // GetFileDescriptor
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
HRESULT
|
|
|
|
nsDataObj :: GetFileContents ( FORMATETC& aFE, STGMEDIUM& aSTG )
|
|
|
|
{
|
|
|
|
HRESULT res = S_OK;
|
|
|
|
|
|
|
|
// How we handle this depends on if we're dealing with an internet
|
|
|
|
// shortcut, since those are done under the covers.
|
|
|
|
if ( IsInternetShortcut() )
|
|
|
|
res = GetFileContentsInternetShortcut ( aFE, aSTG );
|
|
|
|
else
|
2000-10-28 22:17:53 +00:00
|
|
|
NS_WARNING ( "Not yet implemented\n" );
|
2000-05-02 22:39:08 +00:00
|
|
|
|
|
|
|
return res;
|
|
|
|
|
|
|
|
} // GetFileContents
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// GetFileDescriptorInternetShortcut
|
|
|
|
//
|
|
|
|
// Create the special format for an internet shortcut and build up the data
|
|
|
|
// structures the shell is expecting.
|
|
|
|
//
|
|
|
|
HRESULT
|
|
|
|
nsDataObj :: GetFileDescriptorInternetShortcut ( FORMATETC& aFE, STGMEDIUM& aSTG )
|
|
|
|
{
|
|
|
|
HRESULT result = S_OK;
|
|
|
|
|
|
|
|
// setup format structure
|
|
|
|
FORMATETC fmetc = { 0, NULL, DVASPECT_CONTENT, 0, TYMED_HGLOBAL };
|
|
|
|
fmetc.cfFormat = RegisterClipboardFormat ( CFSTR_FILEDESCRIPTOR );
|
|
|
|
|
|
|
|
HGLOBAL fileGroupDescHand = ::GlobalAlloc(GMEM_ZEROINIT|GMEM_SHARE,sizeof(FILEGROUPDESCRIPTOR));
|
|
|
|
if ( fileGroupDescHand ) {
|
|
|
|
LPFILEGROUPDESCRIPTOR fileGroupDesc = NS_REINTERPRET_CAST(LPFILEGROUPDESCRIPTOR, ::GlobalLock(fileGroupDescHand));
|
|
|
|
|
2000-06-09 03:21:01 +00:00
|
|
|
nsAutoString title;
|
|
|
|
if ( NS_FAILED(ExtractShortcutTitle(title)) )
|
2000-06-05 00:34:11 +00:00
|
|
|
return E_OUTOFMEMORY;
|
2001-10-02 23:56:47 +00:00
|
|
|
|
|
|
|
char titleStr[MAX_PATH+1];
|
|
|
|
int lenTitleStr = WideCharToMultiByte(CP_ACP, 0, title.get(), title.Length(), titleStr, MAX_PATH, NULL, NULL);
|
|
|
|
if (!lenTitleStr && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
|
|
|
|
// this is a very rare situation
|
|
|
|
int len = title.Length() - 1;
|
|
|
|
while ((len > 0) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
|
|
|
|
lenTitleStr = WideCharToMultiByte(CP_ACP, 0, title.get(), len--, titleStr, MAX_PATH, NULL, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
titleStr[lenTitleStr] = '\0';
|
2002-01-30 23:31:46 +00:00
|
|
|
|
|
|
|
// replace any forbidden characters with
|
|
|
|
// dash, a la IE
|
|
|
|
char* pos;
|
|
|
|
const char* forbiddenChars = "\\:/";
|
|
|
|
for (int i = 0; i < PL_strlen(forbiddenChars); ++i) {
|
|
|
|
while (pos = PL_strchr((const char*)titleStr, forbiddenChars[i])) {
|
|
|
|
*pos = '-';
|
|
|
|
}
|
|
|
|
}
|
2000-05-02 22:39:08 +00:00
|
|
|
|
2002-01-30 23:31:46 +00:00
|
|
|
// one file in the file file:///c:/testcases/hellodescriptor block
|
2000-05-02 22:39:08 +00:00
|
|
|
fileGroupDesc->cItems = 1;
|
|
|
|
fileGroupDesc->fgd[0].dwFlags = FD_LINKUI;
|
|
|
|
|
|
|
|
// create the filename string -- |.URL| extensions imply an internet shortcut file. Make
|
|
|
|
// sure the filename isn't too long as to blow out the array, and still have enough room
|
2000-06-09 03:21:01 +00:00
|
|
|
// for our .URL suffix.
|
|
|
|
|
|
|
|
static const char* shortcutSuffix = ".URL";
|
|
|
|
static int suffixLen = strlen(shortcutSuffix);
|
|
|
|
int titleLen = strlen(titleStr);
|
|
|
|
int trimmedLen = titleLen > MAX_PATH - (suffixLen + 1) ? MAX_PATH - (suffixLen + 1) : titleLen;
|
2001-10-02 23:56:47 +00:00
|
|
|
titleStr[trimmedLen] = '\0';
|
2000-06-09 03:21:01 +00:00
|
|
|
sprintf(fileGroupDesc->fgd[0].cFileName, "%s%s", titleStr, shortcutSuffix);
|
|
|
|
|
2000-05-02 22:39:08 +00:00
|
|
|
::GlobalUnlock ( fileGroupDescHand );
|
|
|
|
aSTG.hGlobal = fileGroupDescHand;
|
2000-06-05 00:34:11 +00:00
|
|
|
aSTG.tymed = TYMED_HGLOBAL;
|
2000-05-02 22:39:08 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
result = E_OUTOFMEMORY;
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
} // GetFileDescriptorInternetShortcut
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// GetFileContentsInternetShortcut
|
|
|
|
//
|
|
|
|
// Create the special format for an internet shortcut and build up the data
|
|
|
|
// structures the shell is expecting.
|
|
|
|
//
|
|
|
|
HRESULT
|
|
|
|
nsDataObj :: GetFileContentsInternetShortcut ( FORMATETC& aFE, STGMEDIUM& aSTG )
|
|
|
|
{
|
|
|
|
HRESULT result = S_OK;
|
|
|
|
|
2000-06-05 00:34:11 +00:00
|
|
|
nsAutoString url;
|
2000-06-09 03:21:01 +00:00
|
|
|
if ( NS_FAILED(ExtractShortcutURL(url)) )
|
2000-06-05 00:34:11 +00:00
|
|
|
return E_OUTOFMEMORY;
|
2001-10-02 23:56:47 +00:00
|
|
|
char* urlStr = ToNewCString(url); // need to revisit here once we implement iDNS?!?!
|
2000-06-05 00:34:11 +00:00
|
|
|
if ( !urlStr )
|
|
|
|
return E_OUTOFMEMORY;
|
|
|
|
|
2000-05-02 22:39:08 +00:00
|
|
|
// setup format structure
|
|
|
|
FORMATETC fmetc = { 0, NULL, DVASPECT_CONTENT, 0, TYMED_HGLOBAL };
|
|
|
|
fmetc.cfFormat = RegisterClipboardFormat ( CFSTR_FILECONTENTS );
|
|
|
|
|
|
|
|
// create a global memory area and build up the file contents w/in it
|
2001-10-16 00:27:26 +00:00
|
|
|
static const char* shortcutFormatStr = "[InternetShortcut]\r\nURL=%s\r\n";
|
2001-03-31 05:04:57 +00:00
|
|
|
static const int formatLen = strlen(shortcutFormatStr) - 2; // don't include %s in the len
|
|
|
|
const int totalLen = formatLen + strlen(urlStr) + 1;
|
|
|
|
HGLOBAL hGlobalMemory = ::GlobalAlloc(GMEM_SHARE, totalLen);
|
2000-05-02 22:39:08 +00:00
|
|
|
if ( hGlobalMemory ) {
|
|
|
|
char* contents = NS_REINTERPRET_CAST(char*, ::GlobalLock(hGlobalMemory));
|
2001-03-31 05:04:57 +00:00
|
|
|
PR_snprintf( contents, totalLen, shortcutFormatStr, urlStr );
|
2000-05-02 22:39:08 +00:00
|
|
|
::GlobalUnlock(hGlobalMemory);
|
|
|
|
aSTG.hGlobal = hGlobalMemory;
|
2000-06-05 00:34:11 +00:00
|
|
|
aSTG.tymed = TYMED_HGLOBAL;
|
2000-05-02 22:39:08 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
result = E_OUTOFMEMORY;
|
2000-06-09 03:21:01 +00:00
|
|
|
|
2000-06-09 04:03:58 +00:00
|
|
|
nsMemory::Free ( urlStr );
|
2000-05-02 22:39:08 +00:00
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
} // GetFileContentsInternetShortcut
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// IsInternetShortcut
|
|
|
|
//
|
|
|
|
// Is the data that we're handling destined for an internet shortcut if
|
|
|
|
// dragged to the desktop? We can tell because there will be a mime type
|
|
|
|
// of |kURLMime| present in the transferable
|
|
|
|
//
|
|
|
|
PRBool
|
|
|
|
nsDataObj :: IsInternetShortcut ( )
|
|
|
|
{
|
|
|
|
PRBool retval = PR_FALSE;
|
|
|
|
|
|
|
|
if ( !mTransferable )
|
|
|
|
return PR_FALSE;
|
|
|
|
|
|
|
|
// get the list of flavors available in the transferable
|
|
|
|
nsCOMPtr<nsISupportsArray> flavorList;
|
|
|
|
mTransferable->FlavorsTransferableCanExport ( getter_AddRefs(flavorList) );
|
|
|
|
if ( !flavorList )
|
|
|
|
return PR_FALSE;
|
|
|
|
|
|
|
|
// go spelunking for the url flavor
|
|
|
|
PRUint32 cnt;
|
|
|
|
flavorList->Count(&cnt);
|
|
|
|
for ( PRUint32 i = 0;i < cnt; ++i ) {
|
|
|
|
nsCOMPtr<nsISupports> genericFlavor;
|
|
|
|
flavorList->GetElementAt (i, getter_AddRefs(genericFlavor));
|
2002-08-06 00:53:19 +00:00
|
|
|
nsCOMPtr<nsISupportsCString> currentFlavor (do_QueryInterface(genericFlavor));
|
2000-05-02 22:39:08 +00:00
|
|
|
if (currentFlavor) {
|
|
|
|
nsXPIDLCString flavorStr;
|
|
|
|
currentFlavor->ToString(getter_Copies(flavorStr));
|
|
|
|
if ( strcmp(flavorStr, kURLMime) == 0 ) {
|
|
|
|
retval = PR_TRUE; // found it!
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} // for each flavor
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
|
|
|
|
} // IsInternetShortcut
|
|
|
|
|
|
|
|
|
1999-05-04 22:44:16 +00:00
|
|
|
//-----------------------------------------------------
|
2002-03-23 22:26:36 +00:00
|
|
|
HRESULT nsDataObj::GetText(const nsACString & aDataFlavor, FORMATETC& aFE, STGMEDIUM& aSTG)
|
1999-03-23 15:37:34 +00:00
|
|
|
{
|
1999-08-25 08:35:06 +00:00
|
|
|
void* data;
|
1999-03-23 15:37:34 +00:00
|
|
|
PRUint32 len;
|
1999-08-25 08:35:06 +00:00
|
|
|
|
2000-01-29 20:24:50 +00:00
|
|
|
// if someone asks for text/plain, look up text/unicode instead in the transferable.
|
2001-01-23 01:09:58 +00:00
|
|
|
const char* flavorStr;
|
2001-04-02 19:40:52 +00:00
|
|
|
const nsPromiseFlatCString& flat = PromiseFlatCString(aDataFlavor);
|
2001-01-23 01:09:58 +00:00
|
|
|
if ( aDataFlavor.Equals("text/plain") )
|
2000-01-29 20:24:50 +00:00
|
|
|
flavorStr = kUnicodeMime;
|
|
|
|
else
|
2001-03-08 08:53:58 +00:00
|
|
|
flavorStr = flat.get();
|
1999-03-23 15:37:34 +00:00
|
|
|
|
1999-08-25 08:35:06 +00:00
|
|
|
// NOTE: CreateDataFromPrimitive creates new memory, that needs to be deleted
|
|
|
|
nsCOMPtr<nsISupports> genericDataWrapper;
|
|
|
|
mTransferable->GetTransferData(flavorStr, getter_AddRefs(genericDataWrapper), &len);
|
2000-01-29 20:24:50 +00:00
|
|
|
if ( !len )
|
|
|
|
return ResultFromScode(E_FAIL);
|
1999-12-02 23:17:31 +00:00
|
|
|
nsPrimitiveHelpers::CreateDataFromPrimitive ( flavorStr, genericDataWrapper, &data, len );
|
1999-03-23 15:37:34 +00:00
|
|
|
HGLOBAL hGlobalMemory = NULL;
|
|
|
|
PSTR pGlobalMemory = NULL;
|
|
|
|
|
|
|
|
aSTG.tymed = TYMED_HGLOBAL;
|
|
|
|
aSTG.pUnkForRelease = NULL;
|
|
|
|
|
2001-02-20 23:27:57 +00:00
|
|
|
// We play games under the hood and advertise flavors that we know we
|
|
|
|
// can support, only they require a bit of conversion or munging of the data.
|
|
|
|
// Do that here.
|
2000-01-29 20:24:50 +00:00
|
|
|
//
|
1999-12-02 23:17:31 +00:00
|
|
|
// The transferable gives us data that is null-terminated, but this isn't reflected in
|
|
|
|
// the |len| parameter. Windoze apps expect this null to be there so bump our data buffer
|
|
|
|
// by the appropriate size to account for the null (one char for CF_TEXT, one PRUnichar for
|
|
|
|
// CF_UNICODETEXT).
|
1999-04-30 19:41:14 +00:00
|
|
|
DWORD allocLen = (DWORD)len;
|
2000-01-29 20:24:50 +00:00
|
|
|
if ( aFE.cfFormat == CF_TEXT ) {
|
2001-02-20 23:27:57 +00:00
|
|
|
// Someone is asking for text/plain; convert the unicode (assuming it's present)
|
|
|
|
// to text with the correct platform encoding.
|
2000-01-29 20:24:50 +00:00
|
|
|
char* plainTextData = nsnull;
|
|
|
|
PRUnichar* castedUnicode = NS_REINTERPRET_CAST(PRUnichar*, data);
|
|
|
|
PRInt32 plainTextLen = 0;
|
|
|
|
nsPrimitiveHelpers::ConvertUnicodeToPlatformPlainText ( castedUnicode, len / 2, &plainTextData, &plainTextLen );
|
|
|
|
|
|
|
|
// replace the unicode data with our plaintext data. Recall that |plainTextLen| doesn't include
|
|
|
|
// the null in the length.
|
2000-06-03 09:46:12 +00:00
|
|
|
nsMemory::Free(data);
|
2000-01-29 20:24:50 +00:00
|
|
|
if ( plainTextData ) {
|
|
|
|
data = plainTextData;
|
|
|
|
allocLen = plainTextLen + sizeof(char);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
NS_WARNING ( "Oh no, couldn't convert unicode to plain text" );
|
|
|
|
return ResultFromScode(S_OK);
|
|
|
|
}
|
|
|
|
}
|
2002-05-01 21:58:38 +00:00
|
|
|
else if ( aFE.cfFormat == nsClipboard::CF_HTML ) {
|
2001-02-20 23:27:57 +00:00
|
|
|
// Someone is asking for win32's HTML flavor. Convert our html fragment
|
|
|
|
// from unicode to UTF-8 then put it into a format specified by msft.
|
|
|
|
NS_ConvertUCS2toUTF8 converter ( NS_REINTERPRET_CAST(PRUnichar*, data) );
|
|
|
|
char* utf8HTML = nsnull;
|
|
|
|
nsresult rv = BuildPlatformHTML ( converter.get(), &utf8HTML ); // null terminates
|
|
|
|
|
|
|
|
nsMemory::Free(data);
|
|
|
|
if ( NS_SUCCEEDED(rv) && utf8HTML ) {
|
|
|
|
// replace the unicode data with our HTML data. Don't forget the null.
|
|
|
|
data = utf8HTML;
|
|
|
|
allocLen = strlen(utf8HTML) + sizeof(char);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
NS_WARNING ( "Oh no, couldn't convert to HTML" );
|
|
|
|
return ResultFromScode(S_OK);
|
|
|
|
}
|
|
|
|
}
|
2000-08-17 04:19:14 +00:00
|
|
|
else {
|
2001-02-20 23:27:57 +00:00
|
|
|
// we assume that any data that isn't caught above is unicode. This may
|
2000-08-17 04:19:14 +00:00
|
|
|
// be an erroneous assumption, but is true so far.
|
1999-12-02 23:17:31 +00:00
|
|
|
allocLen += sizeof(PRUnichar);
|
2000-08-17 04:19:14 +00:00
|
|
|
}
|
|
|
|
|
2000-05-02 22:39:08 +00:00
|
|
|
hGlobalMemory = (HGLOBAL)::GlobalAlloc(GMEM_MOVEABLE, allocLen);
|
1999-04-30 19:41:14 +00:00
|
|
|
|
1999-03-23 15:37:34 +00:00
|
|
|
// Copy text to Global Memory Area
|
2000-01-29 20:24:50 +00:00
|
|
|
if ( hGlobalMemory ) {
|
1999-10-26 20:31:54 +00:00
|
|
|
char* dest = NS_REINTERPRET_CAST(char*, ::GlobalLock(hGlobalMemory));
|
|
|
|
char* source = NS_REINTERPRET_CAST(char*, data);
|
2000-01-29 20:24:50 +00:00
|
|
|
memcpy ( dest, source, allocLen ); // copies the null as well
|
1999-04-30 19:41:14 +00:00
|
|
|
BOOL status = ::GlobalUnlock(hGlobalMemory);
|
1999-03-23 15:37:34 +00:00
|
|
|
}
|
|
|
|
aSTG.hGlobal = hGlobalMemory;
|
|
|
|
|
2000-01-29 20:24:50 +00:00
|
|
|
// Now, delete the memory that was created by CreateDataFromPrimitive (or our text/plain data)
|
2000-06-03 09:46:12 +00:00
|
|
|
nsMemory::Free(data);
|
1999-07-20 21:02:02 +00:00
|
|
|
|
2000-01-29 20:24:50 +00:00
|
|
|
return ResultFromScode(S_OK);
|
1999-03-23 15:37:34 +00:00
|
|
|
}
|
|
|
|
|
1999-05-04 22:44:16 +00:00
|
|
|
//-----------------------------------------------------
|
1999-03-23 15:37:34 +00:00
|
|
|
HRESULT nsDataObj::GetMetafilePict(FORMATETC&, STGMEDIUM&)
|
|
|
|
{
|
|
|
|
return ResultFromScode(E_NOTIMPL);
|
|
|
|
}
|
|
|
|
|
1999-05-04 22:44:16 +00:00
|
|
|
//-----------------------------------------------------
|
1999-03-23 15:37:34 +00:00
|
|
|
HRESULT nsDataObj::SetBitmap(FORMATETC&, STGMEDIUM&)
|
|
|
|
{
|
|
|
|
return ResultFromScode(E_NOTIMPL);
|
|
|
|
}
|
1999-05-04 22:44:16 +00:00
|
|
|
|
|
|
|
//-----------------------------------------------------
|
1999-03-23 15:37:34 +00:00
|
|
|
HRESULT nsDataObj::SetDib (FORMATETC&, STGMEDIUM&)
|
|
|
|
{
|
|
|
|
return ResultFromScode(E_FAIL);
|
|
|
|
}
|
|
|
|
|
1999-05-04 22:44:16 +00:00
|
|
|
//-----------------------------------------------------
|
1999-03-23 15:37:34 +00:00
|
|
|
HRESULT nsDataObj::SetText (FORMATETC& aFE, STGMEDIUM& aSTG)
|
|
|
|
{
|
|
|
|
if (aFE.cfFormat == CF_TEXT && aFE.tymed == TYMED_HGLOBAL) {
|
|
|
|
HGLOBAL hString = (HGLOBAL)aSTG.hGlobal;
|
|
|
|
if(hString == NULL)
|
|
|
|
return(FALSE);
|
|
|
|
|
|
|
|
// get a pointer to the actual bytes
|
|
|
|
char * pString = (char *) GlobalLock(hString);
|
|
|
|
if(!pString)
|
|
|
|
return(FALSE);
|
|
|
|
|
|
|
|
GlobalUnlock(hString);
|
2000-04-26 01:13:55 +00:00
|
|
|
nsAutoString str; str.AssignWithConversion(pString);
|
1999-03-23 15:37:34 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
return ResultFromScode(E_FAIL);
|
|
|
|
}
|
|
|
|
|
1999-05-04 22:44:16 +00:00
|
|
|
//-----------------------------------------------------
|
1999-03-23 15:37:34 +00:00
|
|
|
HRESULT nsDataObj::SetMetafilePict (FORMATETC&, STGMEDIUM&)
|
|
|
|
{
|
|
|
|
return ResultFromScode(E_FAIL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
1999-05-04 22:44:16 +00:00
|
|
|
//-----------------------------------------------------
|
|
|
|
//-----------------------------------------------------
|
1999-03-23 15:37:34 +00:00
|
|
|
CLSID nsDataObj::GetClassID() const
|
|
|
|
{
|
|
|
|
return CLSID_nsDataObj;
|
|
|
|
}
|
|
|
|
|
1999-05-04 22:44:16 +00:00
|
|
|
//-----------------------------------------------------
|
|
|
|
// Registers a the DataFlavor/FE pair
|
|
|
|
//-----------------------------------------------------
|
1999-09-04 20:04:26 +00:00
|
|
|
void nsDataObj::AddDataFlavor(const char* aDataFlavor, LPFORMATETC aFE)
|
1999-03-23 15:37:34 +00:00
|
|
|
{
|
|
|
|
// These two lists are the mapping to and from data flavors and FEs
|
|
|
|
// Later, OLE will tell us it's needs a certain type of FORMATETC (text, unicode, etc)
|
|
|
|
// so we will look up data flavor that corresponds to the FE
|
|
|
|
// and then ask the transferable for that type of data
|
1999-09-04 20:04:26 +00:00
|
|
|
mDataFlavors->AppendElement(new nsCAutoString(aDataFlavor));
|
1999-03-23 15:37:34 +00:00
|
|
|
m_enumFE->AddFE(aFE);
|
|
|
|
}
|
|
|
|
|
1999-05-04 22:44:16 +00:00
|
|
|
//-----------------------------------------------------
|
|
|
|
// Sets the transferable object
|
|
|
|
//-----------------------------------------------------
|
1999-03-23 15:37:34 +00:00
|
|
|
void nsDataObj::SetTransferable(nsITransferable * aTransferable)
|
|
|
|
{
|
1999-05-04 22:44:16 +00:00
|
|
|
NS_IF_RELEASE(mTransferable);
|
|
|
|
|
1999-03-23 15:37:34 +00:00
|
|
|
mTransferable = aTransferable;
|
|
|
|
if (nsnull == mTransferable) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_ADDREF(mTransferable);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
1999-08-25 08:35:06 +00:00
|
|
|
|
2000-06-05 00:34:11 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
// ExtractURL
|
|
|
|
//
|
|
|
|
// Roots around in the transferable for the appropriate flavor that indicates
|
2000-06-09 03:21:01 +00:00
|
|
|
// a url and pulls out the url portion of the data. Used mostly for creating
|
|
|
|
// internet shortcuts on the desktop. The url flavor is of the format:
|
|
|
|
//
|
2001-03-31 05:04:57 +00:00
|
|
|
// <url> <linefeed> <page title>
|
2000-06-05 00:34:11 +00:00
|
|
|
//
|
|
|
|
nsresult
|
2000-06-09 03:21:01 +00:00
|
|
|
nsDataObj :: ExtractShortcutURL ( nsString & outURL )
|
2000-06-05 00:34:11 +00:00
|
|
|
{
|
|
|
|
NS_ASSERTION ( mTransferable, "We'd don't have a good transferable" );
|
|
|
|
nsresult rv = NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
PRUint32 len = 0;
|
|
|
|
nsCOMPtr<nsISupports> genericURL;
|
|
|
|
if ( NS_SUCCEEDED(mTransferable->GetTransferData(kURLMime, getter_AddRefs(genericURL), &len)) ) {
|
2002-08-06 00:53:19 +00:00
|
|
|
nsCOMPtr<nsISupportsString> urlObject ( do_QueryInterface(genericURL) );
|
2000-06-05 00:34:11 +00:00
|
|
|
if ( urlObject ) {
|
|
|
|
nsXPIDLString url;
|
|
|
|
urlObject->GetData ( getter_Copies(url) );
|
|
|
|
outURL = url;
|
2000-06-09 03:21:01 +00:00
|
|
|
|
2001-03-31 05:04:57 +00:00
|
|
|
// find the first linefeed in the data, that's where the url ends. trunc the
|
2000-06-09 03:21:01 +00:00
|
|
|
// result string at that point.
|
2001-03-31 05:04:57 +00:00
|
|
|
PRInt32 lineIndex = outURL.FindChar ( '\n' );
|
|
|
|
NS_ASSERTION ( lineIndex > 0, "Format for url flavor is <url> <linefeed> <page title>" );
|
|
|
|
if ( lineIndex > 0 ) {
|
|
|
|
outURL.Truncate ( lineIndex );
|
2000-06-09 03:21:01 +00:00
|
|
|
rv = NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} // if found flavor
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
} // ExtractShortcutURL
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// ExtractShortcutTitle
|
|
|
|
//
|
|
|
|
// Roots around in the transferable for the appropriate flavor that indicates
|
|
|
|
// a url and pulls out the title portion of the data. Used mostly for creating
|
|
|
|
// internet shortcuts on the desktop. The url flavor is of the format:
|
|
|
|
//
|
2001-03-31 05:04:57 +00:00
|
|
|
// <url> <linefeed> <page title>
|
2000-06-09 03:21:01 +00:00
|
|
|
//
|
|
|
|
nsresult
|
|
|
|
nsDataObj :: ExtractShortcutTitle ( nsString & outTitle )
|
|
|
|
{
|
|
|
|
NS_ASSERTION ( mTransferable, "We'd don't have a good transferable" );
|
|
|
|
nsresult rv = NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
PRUint32 len = 0;
|
|
|
|
nsCOMPtr<nsISupports> genericURL;
|
|
|
|
if ( NS_SUCCEEDED(mTransferable->GetTransferData(kURLMime, getter_AddRefs(genericURL), &len)) ) {
|
2002-08-06 00:53:19 +00:00
|
|
|
nsCOMPtr<nsISupportsString> urlObject ( do_QueryInterface(genericURL) );
|
2000-06-09 03:21:01 +00:00
|
|
|
if ( urlObject ) {
|
|
|
|
nsXPIDLString url;
|
|
|
|
nsAutoString holder;
|
|
|
|
urlObject->GetData ( getter_Copies(url) );
|
|
|
|
holder = url;
|
|
|
|
|
2001-03-31 05:04:57 +00:00
|
|
|
// find the first linefeed in the data, that's where the url ends. we want
|
|
|
|
// everything after that linefeed. FindChar() returns -1 if we can't find
|
|
|
|
PRInt32 lineIndex = holder.FindChar ( '\n' );
|
|
|
|
NS_ASSERTION ( lineIndex != -1, "Format for url flavor is <url> <linefeed> <page title>" );
|
|
|
|
if ( lineIndex != -1 ) {
|
|
|
|
holder.Mid ( outTitle, lineIndex + 1, (len/2) - (lineIndex + 1) );
|
2000-06-09 03:21:01 +00:00
|
|
|
rv = NS_OK;
|
|
|
|
}
|
2000-06-05 00:34:11 +00:00
|
|
|
}
|
|
|
|
} // if found flavor
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
|
2000-10-27 22:43:51 +00:00
|
|
|
} // ExtractShortcutTitle
|
2001-02-20 23:27:57 +00:00
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// BuildPlatformHTML
|
|
|
|
//
|
|
|
|
// Munge our HTML data to win32's CF_HTML spec. Basically, put the requisite
|
|
|
|
// header information on it. This will null terminate |outPlatformHTML|. See
|
|
|
|
// http://msdn.microsoft.com/workshop/networking/clipboard/htmlclipboard.asp
|
|
|
|
// for details.
|
|
|
|
//
|
|
|
|
// We assume that |inOurHTML| is already a fragment (ie, doesn't have <HTML>
|
|
|
|
// or <BODY> tags). We'll wrap the fragment with them to make other apps
|
|
|
|
// happy.
|
|
|
|
//
|
|
|
|
// This code is derived from sample code from MSDN. It's ugly, I agree.
|
|
|
|
//
|
|
|
|
nsresult
|
|
|
|
nsDataObj :: BuildPlatformHTML ( const char* inOurHTML, char** outPlatformHTML )
|
|
|
|
{
|
|
|
|
*outPlatformHTML = nsnull;
|
|
|
|
|
|
|
|
// Create temporary buffer for HTML header...
|
|
|
|
char *buf = NS_REINTERPRET_CAST(char*, nsMemory::Alloc(400 + strlen(inOurHTML)));
|
|
|
|
if( !buf )
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
// Create a template string for the HTML header...
|
|
|
|
strcpy(buf,
|
|
|
|
"Version:0.9\r\n"
|
|
|
|
"StartHTML:00000000\r\n"
|
|
|
|
"EndHTML:00000000\r\n"
|
|
|
|
"StartFragment:00000000\r\n"
|
|
|
|
"EndFragment:00000000\r\n"
|
|
|
|
"<html><body>\r\n"
|
|
|
|
"<!--StartFragment -->\r\n");
|
|
|
|
|
|
|
|
// Append the HTML...
|
|
|
|
strcat(buf, inOurHTML);
|
|
|
|
strcat(buf, "\r\n");
|
|
|
|
// Finish up the HTML format...
|
|
|
|
strcat(buf,
|
|
|
|
"<!--EndFragment-->\r\n"
|
|
|
|
"</body>\r\n"
|
|
|
|
"</html>");
|
|
|
|
|
|
|
|
// Now go back, calculate all the lengths, and write out the
|
|
|
|
// necessary header information. Note, wsprintf() truncates the
|
|
|
|
// string when you overwrite it so you follow up with code to replace
|
|
|
|
// the 0 appended at the end with a '\r'...
|
|
|
|
char *ptr = strstr(buf, "StartHTML");
|
|
|
|
wsprintf(ptr+10, "%08u", strstr(buf, "<html>") - buf);
|
|
|
|
*(ptr+10+8) = '\r';
|
|
|
|
|
|
|
|
ptr = strstr(buf, "EndHTML");
|
|
|
|
wsprintf(ptr+8, "%08u", strlen(buf));
|
|
|
|
*(ptr+8+8) = '\r';
|
|
|
|
|
|
|
|
ptr = strstr(buf, "StartFragment");
|
|
|
|
wsprintf(ptr+14, "%08u", strstr(buf, "<!--StartFrag") - buf);
|
|
|
|
*(ptr+14+8) = '\r';
|
|
|
|
|
|
|
|
ptr = strstr(buf, "EndFragment");
|
|
|
|
wsprintf(ptr+12, "%08u", strstr(buf, "<!--EndFrag") - buf);
|
|
|
|
*(ptr+12+8) = '\r';
|
|
|
|
|
|
|
|
*outPlatformHTML = buf;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|