implement accepting drops of files onto mozilla.

This commit is contained in:
pinkerton%netscape.com 2000-04-26 01:04:13 +00:00
parent 842e221a57
commit 01c33fc3e5
3 changed files with 83 additions and 52 deletions

View File

@ -256,7 +256,7 @@ nsresult nsClipboard::GetGlobalData(HGLOBAL aHGBL, void ** aData, PRUint32 * aLe
}
//-------------------------------------------------------------------------
nsresult nsClipboard::GetNativeDataOffClipboard(nsIWidget * aWindow, UINT aFormat, void ** aData, PRUint32 * aLen)
nsresult nsClipboard::GetNativeDataOffClipboard(nsIWidget * aWindow, UINT /*aIndex*/, UINT aFormat, void ** aData, PRUint32 * aLen)
{
HGLOBAL hglb;
nsresult result = NS_ERROR_FAILURE;
@ -381,13 +381,14 @@ PRUint8 * GetDIBBits(BITMAPINFO * aBitmapInfo)
}
//-------------------------------------------------------------------------
nsresult nsClipboard::GetNativeDataOffClipboard(IDataObject * aDataObject, UINT aFormat, void ** aData, PRUint32 * aLen)
nsresult nsClipboard::GetNativeDataOffClipboard(IDataObject * aDataObject, UINT aIndex, UINT aFormat, void ** aData, PRUint32 * aLen)
{
nsresult result = NS_ERROR_FAILURE;
*aData = nsnull;
*aLen = 0;
if (nsnull == aDataObject) {
if ( !aDataObject )
return result;
}
UINT format = aFormat;
HRESULT hres = S_FALSE;
@ -471,11 +472,8 @@ nsresult nsClipboard::GetNativeDataOffClipboard(IDataObject * aDataObject, UINT
::GlobalUnlock (hGlobal) ;
result = NS_OK;
} else {
*aData = nsnull;
aLen = 0;
}
// XXX NOTE this is temporary
// until the rest of the image code gets in
NS_ASSERTION(0, "Take this out when editor can handle images");
@ -483,27 +481,29 @@ nsresult nsClipboard::GetNativeDataOffClipboard(IDataObject * aDataObject, UINT
case CF_HDROP :
{
HDROP dropFiles = (HDROP)(*aData);
// in the case of a file drop, multiple files are stashed within a
// single data object. In order to match mozilla's D&D apis, we
// just pull out the file at the requested index, pretending as
// if there really are multiple drag items.
HDROP dropFiles = (HDROP) ::GlobalLock(stm.hGlobal);
char fileName[1024];
UINT numFiles = DragQueryFile(dropFiles, 0xFFFFFFFF, NULL, 0);
UINT numFiles = ::DragQueryFile(dropFiles, 0xFFFFFFFF, NULL, 0);
NS_ASSERTION ( numFiles > 0, "File drop flavor, but no files...hmmmm" );
NS_ASSERTION ( aIndex < numFiles, "Asked for a file index out of range of list" );
if (numFiles > 0) {
nsVoidArray * fileList = new nsVoidArray();
for (UINT i=0;i<numFiles;i++) {
UINT bytesCopied = ::DragQueryFile(dropFiles, i, fileName, 1024);
//nsAutoString name((char *)fileName, bytesCopied-1);
nsString name = fileName;
printf("name [%s]\n", name.ToNewCString());
nsFilePath filePath(name);
nsFileSpec * fileSpec = new nsFileSpec(filePath);
fileList->AppendElement(fileSpec);
UINT fileNameLen = ::DragQueryFile(dropFiles, aIndex, nsnull, 0);
char* buffer = NS_REINTERPRET_CAST(char*, nsAllocator::Alloc(fileNameLen + 1));
if ( buffer ) {
::DragQueryFile(dropFiles, aIndex, buffer, fileNameLen + 1);
*aData = buffer;
*aLen = fileNameLen;
result = NS_OK;
}
*aLen = (PRUint32)numFiles;
*aData = fileList;
} else {
*aData = nsnull;
*aLen = 0;
else
result = NS_ERROR_OUT_OF_MEMORY;
}
::GlobalUnlock (stm.hGlobal) ;
} break;
default: {
@ -533,12 +533,14 @@ nsresult nsClipboard::GetNativeDataOffClipboard(IDataObject * aDataObject, UINT
} //switch
}
ReleaseStgMedium(&stm);
return result;
}
//-------------------------------------------------------------------------
nsresult nsClipboard::GetDataFromDataObject(IDataObject * aDataObject,
UINT anIndex,
nsIWidget * aWindow,
nsITransferable * aTransferable)
{
@ -572,18 +574,18 @@ nsresult nsClipboard::GetDataFromDataObject(IDataObject * aDataObject,
PRUint32 dataLen;
PRBool dataFound = PR_FALSE;
if (nsnull != aDataObject) {
if ( NS_SUCCEEDED(GetNativeDataOffClipboard(aDataObject, format, &data, &dataLen)) )
if ( NS_SUCCEEDED(GetNativeDataOffClipboard(aDataObject, anIndex, format, &data, &dataLen)) )
dataFound = PR_TRUE;
}
else if (nsnull != aWindow) {
if ( NS_SUCCEEDED(GetNativeDataOffClipboard(aWindow, format, &data, &dataLen)) )
if ( NS_SUCCEEDED(GetNativeDataOffClipboard(aWindow, anIndex, format, &data, &dataLen)) )
dataFound = PR_TRUE;
}
if ( !dataFound ) {
// if we are looking for text/unicode and we fail to find it on the clipboard first,
// try again with text/plain. If that is present, convert it to unicode.
if ( strcmp(flavorStr, kUnicodeMime) == 0 ) {
nsresult loadResult = GetNativeDataOffClipboard(aDataObject, GetFormat(kTextMime), &data, &dataLen);
nsresult loadResult = GetNativeDataOffClipboard(aDataObject, anIndex, GetFormat(kTextMime), &data, &dataLen);
if ( NS_SUCCEEDED(loadResult) && data ) {
const char* castedText = NS_REINTERPRET_CAST(char*, data);
PRUnichar* convertedText = nsnull;
@ -602,19 +604,32 @@ nsresult nsClipboard::GetDataFromDataObject(IDataObject * aDataObject,
} // if we try one last ditch effort to find our data
if ( dataFound ) {
// the DOM only wants LF, so convert from Win32 line endings to DOM line
// endings.
PRInt32 signedLen = NS_STATIC_CAST(PRInt32, dataLen);
nsLinebreakHelpers::ConvertPlatformToDOMLinebreaks ( flavorStr, &data, &signedLen );
dataLen = signedLen;
nsCOMPtr<nsISupports> genericDataWrapper;
nsPrimitiveHelpers::CreatePrimitiveForData ( flavorStr, data, dataLen, getter_AddRefs(genericDataWrapper) );
if ( strcmp(flavorStr, kFileMime) == 0 ) {
// we have a file path in |data|. Create an nsLocalFile object.
char* filepath = NS_REINTERPRET_CAST(char*, data);
nsCOMPtr<nsILocalFile> file;
if ( NS_SUCCEEDED(NS_NewLocalFile(filepath, getter_AddRefs(file))) )
genericDataWrapper = do_QueryInterface(file);
}
else {
// we probably have some form of text. The DOM only wants LF, so convert from Win32 line
// endings to DOM line endings.
PRInt32 signedLen = NS_STATIC_CAST(PRInt32, dataLen);
nsLinebreakHelpers::ConvertPlatformToDOMLinebreaks ( flavorStr, &data, &signedLen );
dataLen = signedLen;
nsCOMPtr<nsISupports> genericDataWrapper;
nsPrimitiveHelpers::CreatePrimitiveForData ( flavorStr, data, dataLen, getter_AddRefs(genericDataWrapper) );
}
NS_ASSERTION ( genericDataWrapper, "About to put null data into the transferable" );
aTransferable->SetTransferData(flavorStr, genericDataWrapper, dataLen);
nsAllocator::Free ( NS_REINTERPRET_CAST(char*, data) );
nsAllocator::Free ( NS_REINTERPRET_CAST(char*, data) );
res = NS_OK;
// we found one, get out of the loop
break;
}
@ -639,10 +654,10 @@ NS_IMETHODIMP nsClipboard::GetNativeClipboardData ( nsITransferable * aTransfera
IDataObject * dataObj;
if (S_OK == ::OleGetClipboard(&dataObj)) {
// Use OLE IDataObject for clipboard operations
res = GetDataFromDataObject(dataObj, nsnull, aTransferable);
res = GetDataFromDataObject(dataObj, 0, nsnull, aTransferable);
} else {
// do it the old manula way
res = GetDataFromDataObject(nsnull, mWindow, aTransferable);
res = GetDataFromDataObject(nsnull, 0, mWindow, aTransferable);
}
return res;

View File

@ -53,13 +53,14 @@ public:
static nsresult SetupNativeDataObject(nsITransferable * aTransferable,
IDataObject * aDataObj);
static nsresult GetDataFromDataObject(IDataObject * aDataObject,
static nsresult GetDataFromDataObject(IDataObject * aDataObject,
UINT anIndex,
nsIWidget * aWindow,
nsITransferable * aTransferable);
static nsresult GetNativeDataOffClipboard(nsIWidget * aWindow, UINT aFormat, void ** aData, PRUint32 * aLen);
static nsresult GetNativeDataOffClipboard(nsIWidget * aWindow, UINT aIndex, UINT aFormat, void ** aData, PRUint32 * aLen);
static nsresult GetNativeDataOffClipboard(IDataObject * aDataObject, UINT aFormat, void ** aData, PRUint32 * aLen);
static nsresult GetNativeDataOffClipboard(IDataObject * aDataObject, UINT aIndex, UINT aFormat, void ** aData, PRUint32 * aLen);
static nsresult GetGlobalData(HGLOBAL aHGBL, void ** aData, PRUint32 * aLen);

View File

@ -136,16 +136,31 @@ NS_IMETHODIMP nsDragService::GetNumDropItems (PRUint32 * aNumItems)
UINT format = nsClipboard::GetFormat(MULTI_MIME);
FORMATETC fe;
SET_FORMATETC(fe, format, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL);
if (S_OK != mDataObject->QueryGetData(&fe)) {
*aNumItems = 1;
return NS_OK;
if ( mDataObject->QueryGetData(&fe) == S_OK ) {
// If it is the get the number of items in the collection
nsDataObjCollection * dataObjCol = NS_STATIC_CAST(nsDataObjCollection*, mDataObject);
if ( dataObjCol )
*aNumItems = dataObjCol->GetNumDataObjects();
}
else {
// Next check if we have a file drop. Return the number of files in
// the file drop as the number of items we have, pretending like we
// actually have > 1 drag item.
FORMATETC fe2;
SET_FORMATETC(fe2, CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL);
if ( mDataObject->QueryGetData(&fe2) ) {
STGMEDIUM stm;
if ( mDataObject->GetData(&fe2, &stm) ) {
HDROP hdrop = (HDROP) GlobalLock(stm.hGlobal);
*aNumItems = ::DragQueryFile(hdrop, 0xFFFFFFFF, NULL, 0);
::GlobalUnlock(stm.hGlobal);
::ReleaseStgMedium(&stm);
}
}
else
*aNumItems = 1;
}
// If it is the get the number of items in the collection
nsDataObjCollection * dataObjCol = NS_STATIC_CAST(nsDataObjCollection*, mDataObject);
if ( dataObjCol )
*aNumItems = dataObjCol->GetNumDataObjects();
return NS_OK;
}
@ -168,7 +183,7 @@ NS_IMETHODIMP nsDragService::GetData (nsITransferable * aTransferable, PRUint32
if (S_OK != mDataObject->QueryGetData(&fe)) {
// Since there is only one object, they better be asking for item "0"
if (anItem == 0) {
return nsClipboard::GetDataFromDataObject(mDataObject, nsnull, aTransferable);
return nsClipboard::GetDataFromDataObject(mDataObject, anItem, nsnull, aTransferable);
} else {
return NS_ERROR_FAILURE;
}
@ -179,7 +194,7 @@ NS_IMETHODIMP nsDragService::GetData (nsITransferable * aTransferable, PRUint32
PRUint32 cnt = dataObjCol->GetNumDataObjects();
if (anItem >= 0 && anItem < cnt) {
IDataObject * dataObj = dataObjCol->GetDataObjectAt(anItem);
return nsClipboard::GetDataFromDataObject(dataObj, nsnull, aTransferable);
return nsClipboard::GetDataFromDataObject(dataObj, 0, nsnull, aTransferable);
}
}