Bug 194067 support unicode file name on drag and drop(D&D). patch by Masatoshi Kimura (:emk) <VYV03354@nifty.ne.jp> r=ere, sr=roc

This commit is contained in:
masayuki%d-toybox.com 2006-05-02 06:20:16 +00:00
Родитель 12c7ecac2e
Коммит 49201d2111
4 изменённых файлов: 31 добавлений и 36 удалений

Просмотреть файл

@ -57,6 +57,7 @@
#include "nsISupportsPrimitives.h"
#include "nsXPIDLString.h"
#include "nsReadableUtils.h"
#include "nsUnicharUtils.h"
#include "nsPrimitiveHelpers.h"
#include "nsImageClipboard.h"
#include "nsIWidget.h"
@ -502,16 +503,16 @@ nsresult nsClipboard::GetNativeDataOffClipboard(IDataObject * aDataObject, UINT
// if there really are multiple drag items.
HDROP dropFiles = (HDROP) GlobalLock(stm.hGlobal);
UINT numFiles = ::DragQueryFile(dropFiles, 0xFFFFFFFF, NULL, 0);
UINT numFiles = ::DragQueryFileW(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) {
UINT fileNameLen = ::DragQueryFile(dropFiles, aIndex, nsnull, 0);
char* buffer = NS_REINTERPRET_CAST(char*, nsMemory::Alloc(fileNameLen + 1));
UINT fileNameLen = ::DragQueryFileW(dropFiles, aIndex, nsnull, 0);
PRUnichar* buffer = NS_REINTERPRET_CAST(PRUnichar*, nsMemory::Alloc((fileNameLen + 1) * sizeof(PRUnichar)));
if ( buffer ) {
::DragQueryFile(dropFiles, aIndex, buffer, fileNameLen + 1);
::DragQueryFileW(dropFiles, aIndex, buffer, fileNameLen + 1);
*aData = buffer;
*aLen = fileNameLen;
*aLen = fileNameLen * sizeof(PRUnichar);
result = NS_OK;
}
else
@ -635,13 +636,13 @@ nsresult nsClipboard::GetDataFromDataObject(IDataObject * aDataObject,
// Hopefully by this point we've found it and can go about our business
if ( dataFound ) {
nsCOMPtr<nsISupports> genericDataWrapper;
if ( strcmp(flavorStr, kFileMime) == 0 ) {
// we have a file path in |data|. Create an nsLocalFile object.
nsDependentCString filepath(NS_REINTERPRET_CAST(char*, data));
nsCOMPtr<nsILocalFile> file;
if ( NS_SUCCEEDED(NS_NewNativeLocalFile(filepath, PR_FALSE, getter_AddRefs(file))) )
genericDataWrapper = do_QueryInterface(file);
}
if ( strcmp(flavorStr, kFileMime) == 0 ) {
// we have a file path in |data|. Create an nsLocalFile object.
nsDependentString filepath(NS_REINTERPRET_CAST(PRUnichar*, data));
nsCOMPtr<nsILocalFile> file;
if ( NS_SUCCEEDED(NS_NewLocalFile(filepath, PR_FALSE, getter_AddRefs(file))) )
genericDataWrapper = do_QueryInterface(file);
}
else if ( strcmp(flavorStr, kNativeHTMLMime) == 0) {
// the editor folks want CF_HTML exactly as it's on the clipboard, no conversions,
// no fancy stuff. Pull it off the clipboard, stuff it into a wrapper and hand
@ -664,9 +665,9 @@ nsresult nsClipboard::GetDataFromDataObject(IDataObject * aDataObject,
NS_ASSERTION ( genericDataWrapper, "About to put null data into the transferable" );
aTransferable->SetTransferData(flavorStr, genericDataWrapper, dataLen);
nsMemory::Free ( NS_REINTERPRET_CAST(char*, data) );
nsMemory::Free(data);
res = NS_OK;
// we found one, get out of the loop
break;
}
@ -758,9 +759,9 @@ nsClipboard :: FindURLFromLocalFile ( IDataObject* inDataObject, UINT inIndex, v
nsresult loadResult = GetNativeDataOffClipboard(inDataObject, inIndex, GetFormat(kFileMime), outData, outDataLen);
if ( NS_SUCCEEDED(loadResult) && *outData ) {
// we have a file path in |data|. Is it an internet shortcut or a normal file?
const char* filepath = NS_REINTERPRET_CAST(char*, *outData);
const nsDependentString filepath(NS_STATIC_CAST(PRUnichar*, *outData));
nsCOMPtr<nsILocalFile> file;
nsresult rv = NS_NewNativeLocalFile(nsDependentCString(filepath), PR_TRUE, getter_AddRefs(file));
nsresult rv = NS_NewLocalFile(filepath, PR_TRUE, getter_AddRefs(file));
if (NS_FAILED(rv))
return dataFound;
@ -819,12 +820,9 @@ nsClipboard :: ResolveShortcut ( nsILocalFile* aFile, nsACString& outURL )
// A file is an Internet Shortcut if it ends with .URL
//
PRBool
nsClipboard :: IsInternetShortcut ( const char* inFileName )
nsClipboard :: IsInternetShortcut ( const nsAString& inFileName )
{
if ( strstr(inFileName, ".URL") || strstr(inFileName, ".url") )
return PR_TRUE;
return PR_FALSE;
return StringEndsWith(inFileName, NS_LITERAL_STRING(".url"), nsCaseInsensitiveStringComparator());
} // IsInternetShortcut

Просмотреть файл

@ -90,7 +90,7 @@ protected:
NS_IMETHOD SetNativeClipboardData ( PRInt32 aWhichClipboard );
NS_IMETHOD GetNativeClipboardData ( nsITransferable * aTransferable, PRInt32 aWhichClipboard );
static PRBool IsInternetShortcut ( const char* inFileName ) ;
static PRBool IsInternetShortcut ( const nsAString& inFileName ) ;
static PRBool FindURLFromLocalFile ( IDataObject* inDataObject, UINT inIndex, void** outData, PRUint32* outDataLen ) ;
static PRBool FindUnicodeFromPlainText ( IDataObject* inDataObject, UINT inIndex, void** outData, PRUint32* outDataLen ) ;
static PRBool FindPlatformHTML ( IDataObject* inDataObject, UINT inIndex, void** outData, PRUint32* outDataLen );

Просмотреть файл

@ -985,17 +985,16 @@ HRESULT nsDataObj::GetFile(const nsACString & aDataFlavor, FORMATETC& aFE, STGME
}
// Pass the file name back to the drop target so that it can copy to the drop location
nsCAutoString path;
rv = mCachedTempFile->GetNativePath(path);
nsAutoString path;
rv = mCachedTempFile->GetPath(path);
if (NS_FAILED(rv)) return ResultFromScode(E_FAIL);
const char* pFileName = path.get();
// Two null characters are needed to terminate the file name list
PRUint32 allocLen = path.Length() + 2;
HGLOBAL hGlobalMemory = NULL;
aSTG.tymed = TYMED_HGLOBAL;
aSTG.pUnkForRelease = NULL;
hGlobalMemory = GlobalAlloc(GMEM_MOVEABLE, sizeof(DROPFILES) + allocLen);
if (hGlobalMemory) {
aSTG.pUnkForRelease = NULL;
hGlobalMemory = GlobalAlloc(GMEM_MOVEABLE, sizeof(DROPFILES) + allocLen * sizeof(PRUnichar));
if (hGlobalMemory) {
DROPFILES* pDropFile = NS_REINTERPRET_CAST(DROPFILES*, GlobalLock(hGlobalMemory));
// First, populate drop file structure
@ -1003,18 +1002,16 @@ HRESULT nsDataObj::GetFile(const nsACString & aDataFlavor, FORMATETC& aFE, STGME
pDropFile->fNC = 0;
pDropFile->pt.x = 0;
pDropFile->pt.y = 0;
pDropFile->fWide = 0;
pDropFile->fWide = TRUE;
// Copy the filename right after the DROPFILES structure
char* dest = NS_REINTERPRET_CAST(char*, pDropFile);
dest += pDropFile->pFiles;
const char* source = pFileName;
memcpy (NS_REINTERPRET_CAST(char*, dest), source, allocLen - 1); // copies the null character in pFileName as well
PRUnichar* dest = NS_REINTERPRET_CAST(PRUnichar*, NS_REINTERPRET_CAST(char*, pDropFile) + pDropFile->pFiles);
memcpy(dest, path.get(), (allocLen - 1) * sizeof(PRUnichar)); // copies the null character in path as well
// Two null characters are needed at the end of the file name.
// Lookup the CF_HDROP shell clipboard format for more info.
// Add the second null character right after the first one.
dest[allocLen - 1] = '\0';
dest[allocLen - 1] = L'\0';
GlobalUnlock(hGlobalMemory);
}

Просмотреть файл

@ -379,7 +379,7 @@ nsDragService::GetNumDropItems(PRUint32 * aNumItems)
STGMEDIUM stm;
if (mDataObject->GetData(&fe2, &stm) == S_OK) {
HDROP hdrop = (HDROP)GlobalLock(stm.hGlobal);
*aNumItems = ::DragQueryFile(hdrop, 0xFFFFFFFF, NULL, 0);
*aNumItems = ::DragQueryFileW(hdrop, 0xFFFFFFFF, NULL, 0);
::GlobalUnlock(stm.hGlobal);
::ReleaseStgMedium(&stm);
}