Backing out the previous checkin for bug 267426 due to Sunbird bustage.

This commit is contained in:
emaijala%kolumbus.fi 2006-02-05 18:07:38 +00:00
Родитель d6e8dffdab
Коммит 6c719817f2
6 изменённых файлов: 17 добавлений и 437 удалений

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

@ -95,7 +95,6 @@ EXTRA_DSO_LDOPTS = \
$(LIBS_DIR) \
$(EXTRA_DSO_LIBS) \
$(MOZ_COMPONENT_LIBS) \
$(MOZ_UNICHARUTIL_LIBS) \
$(NULL)
include $(topsrcdir)/config/rules.mk

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

@ -67,9 +67,6 @@ REQUIRES = xpcom \
xuldoc \
view \
imglib2 \
uriloader \
webbrowserpersist \
unicharutil \
$(NULL)
ifdef MOZ_ENABLE_CAIRO_GFX

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

@ -65,9 +65,6 @@
#include "nsCRT.h"
#include "nsPrintfCString.h"
#include "nsIStringBundle.h"
#include "nsEscape.h"
#include "nsIURL.h"
#include "nsNetUtil.h"
#if 0
#define PRNTDEBUG(_x) printf(_x);
@ -941,47 +938,30 @@ HRESULT nsDataObj::GetFile(const nsACString & aDataFlavor, FORMATETC& aFE, STGME
{
HRESULT res = S_OK;
if (strcmp(PromiseFlatCString(aDataFlavor).get(), kFilePromiseMime) == 0) {
// If we have a cached file just pass it to HGLOBAL
// otherwise create an empty file in the temp location.
// The download will start after the user drops the file.
// XXX We are copying the file twice below. Once from the original location to the temporary
// one (here) and then from the temporary location to the drop location (done by the drop target
// when this function returns). If the file being drag-dropped is in the cache, we should be able to
// just pass back its file name to the drop target and save a copy. Need help here!
nsresult rv;
if (!mCachedTempFile) {
// Get system temp directory
// Save the file to a temporary location.
nsCOMPtr<nsILocalFile> dropDirectory;
nsCOMPtr<nsIProperties> directoryService =
do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
if (!directoryService || NS_FAILED(rv))
return ResultFromScode(E_FAIL);
if (!directoryService || NS_FAILED(rv)) return ResultFromScode(E_FAIL);
directoryService->Get(NS_OS_TEMP_DIR,
NS_GET_IID(nsIFile),
getter_AddRefs(dropDirectory));
nsCOMPtr<nsILocalFile> destFile = do_QueryInterface(dropDirectory);
if (!destFile)
return E_FAIL;
// Get the filename form the kFilePromiseURLFlavour
nsAutoString wideFileName;
nsCOMPtr<nsIURI> sourceURI;
rv = nsDataObj::GetDownloadDetails(mTransferable,
getter_AddRefs(sourceURI),
wideFileName);
if (NS_FAILED(rv))
return rv;
rv = destFile->Append(wideFileName);
if (NS_FAILED(rv))
return rv;
// Try to create the file.
rv = destFile->Create(nsIFile::NORMAL_FILE_TYPE, 0600);
// Bail out if it fails for a reason other than the existence of the file.
if (NS_FAILED(rv) && rv != NS_ERROR_FILE_ALREADY_EXISTS)
return rv;
mCachedTempFile = do_QueryInterface(destFile);
if (!mCachedTempFile)
return ResultFromScode(E_FAIL);
nsCOMPtr<nsISupports> localFileISupports = do_QueryInterface(dropDirectory);
rv = mTransferable->SetTransferData(kFilePromiseDirectoryMime, localFileISupports, sizeof(nsILocalFile*));
if (NS_FAILED(rv)) return ResultFromScode(E_FAIL);
nsCOMPtr<nsISupports> fileDataPrimitive;
PRUint32 dataSize = 0;
rv = mTransferable->GetTransferData(kFilePromiseMime, getter_AddRefs(fileDataPrimitive), &dataSize);
if (NS_FAILED(rv)) return ResultFromScode(E_FAIL);
mCachedTempFile = do_QueryInterface(fileDataPrimitive);
if (!mCachedTempFile) return ResultFromScode(E_FAIL);
}
// Pass the file name back to the drop target so that it can copy to the drop location
@ -1376,59 +1356,3 @@ nsDataObj::ExtractUniformResourceLocatorW(FORMATETC& aFE, STGMEDIUM& aSTG )
return result;
}
// Gets the filename from the kFilePromiseURLMime flavour
nsresult nsDataObj::GetDownloadDetails(nsITransferable *aTransferable,
nsIURI **aSourceURI,
nsAString &aFilename)
{
if (!aTransferable)
return NS_ERROR_FAILURE;
// get the URI from the kFilePromiseURLMime flavor
nsCOMPtr<nsISupports> urlPrimitive;
PRUint32 dataSize = 0;
aTransferable->GetTransferData(kFilePromiseURLMime, getter_AddRefs(urlPrimitive), &dataSize);
nsCOMPtr<nsISupportsString> srcUrlPrimitive = do_QueryInterface(urlPrimitive);
if (!srcUrlPrimitive)
return NS_ERROR_FAILURE;
// Get data for flavor
// The format of the data is (URLSTRING\nFILENAME)
nsAutoString strData;
srcUrlPrimitive->GetData(strData);
if (strData.IsEmpty())
return NS_ERROR_FAILURE;
// Now figure if there is a "\n" delimiter in the data string.
// If there is, the string after the "\n" is a filename.
// If there is no delimiter then just get the filename from the url.
nsCAutoString strFileName;
nsCOMPtr<nsIURI> sourceURI;
// New line char is used as a delimiter (hardcoded)
PRInt32 nPos = strData.FindChar('\n');
// Store source uri
NS_NewURI(aSourceURI, Substring(strData, 0, nPos));
if (nPos != -1) {
// if there is delimiter
CopyUTF16toUTF8(Substring(strData, nPos + 1, strData.Length()), strFileName);
} else {
// no filename was supplied - try to get it from a URL
nsCOMPtr<nsIURL> sourceURL = do_QueryInterface(*aSourceURI);
sourceURL->GetFileName(strFileName);
}
// check for an error; the URL must point to a file
if (strFileName.IsEmpty())
return NS_ERROR_FAILURE;
NS_UnescapeURL(strFileName);
NS_ConvertUTF8toUTF16 wideFileName(strFileName);
// make the name safe for the filesystem
MangleTextToValidFilename(wideFileName);
aFilename = wideFileName;
return NS_OK;
}

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

@ -186,11 +186,6 @@ class nsDataObj : public IDataObject
// released the interface pointer after a drop).
ULONG GetRefCount() const;
// Gets the filename from the kFilePromiseURLMime flavour
static nsresult GetDownloadDetails(nsITransferable *aTransferable,
nsIURI **aSourceURI,
nsAString &aFilename);
protected:
// Help determine if the drag should create an internet shortcut

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

@ -59,21 +59,6 @@
#include "nsAutoPtr.h"
#include "nsString.h"
#include "nsEscape.h"
#include "nsISupportsPrimitives.h"
#include "nsNetUtil.h"
#include "nsIURL.h"
#include "nsCWebBrowserPersist.h"
#include "nsIDownload.h"
#include "nsToolkit.h"
#include "nsCRT.h"
#include "nsDirectoryServiceDefs.h"
#include "nsUnicharUtils.h"
// Static member declaration
nsString nsDragService::mDropPath;
nsString nsDragService::mFileName;
//-------------------------------------------------------------------------
//
@ -161,104 +146,7 @@ nsDragService::InvokeDragSession(nsIDOMNode *aDOMNode,
}
} // else dragging a single object
// Before starting get the file name to monitor if there is any
nsAutoString strData; // holds kFilePromiseURLMime flavour data
PRBool bDownload = PR_FALSE; // Used after drag ends to fugure if the download should start
nsCOMPtr<nsIURI> sourceURI;
nsCOMPtr<nsISupports> urlPrimitive;
nsCOMPtr<nsISupports> transSupports;
anArrayTransferables->GetElementAt(0, getter_AddRefs(transSupports));
nsCOMPtr<nsITransferable> trans = (do_QueryInterface(transSupports));
if (trans) {
// Get the filename form the kFilePromiseURLFlavour
nsAutoString wideFileName;
// if this fails there is no kFilePromiseMime flavour or no filename
rv = nsDataObj::GetDownloadDetails(trans,
getter_AddRefs(sourceURI),
wideFileName);
if (SUCCEEDED(rv))
{
// Start listening to the shell notifications
if (StartWatchingShell(wideFileName)) {
// Set download flag if all went ok so far
bDownload = PR_TRUE;
}
}
}
// Kick off the native drag session
rv = StartInvokingDragSession(itemToDrag, aActionType);
// Check if the download flag was set
// if not then we are done
if (!bDownload)
return rv;
if (NS_FAILED(rv)) // See if dragsession failed
{
::DestroyWindow(mHiddenWnd);
return rv;
}
// Construct target URI from nsILocalFile
// Init file for the download
nsCOMPtr<nsILocalFile> dropLocalFile(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID));
if (!dropLocalFile)
{
::DestroyWindow(mHiddenWnd);
return NS_ERROR_FAILURE;
}
// init with path we get from GetDropPath
// if it fails then there is no target path.
// This could happen if the drag operation was cancelled.
nsAutoString fileName;
if (!GetDropPath(fileName))
return NS_OK;
// hidden window is destroyed by now
rv = dropLocalFile->InitWithPath(fileName);
if (NS_FAILED(rv))
return rv;
// Create a new FileURI to pass to the nsIDownload
nsCOMPtr<nsIURI> targetURI;
nsCOMPtr<nsIFile> file = do_QueryInterface(dropLocalFile);
if (!file)
return NS_ERROR_FAILURE;
rv = NS_NewFileURI(getter_AddRefs(targetURI), file);
if (NS_FAILED(rv))
return rv;
// Start download
nsCOMPtr<nsISupports> fileAsSupports = do_QueryInterface(dropLocalFile);
nsCOMPtr<nsIWebBrowserPersist> persist = do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID, &rv);
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsITransfer> transfer = do_CreateInstance("@mozilla.org/transfer;1", &rv);
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsIWebProgressListener> listener = do_QueryInterface(transfer);
rv = persist->SetProgressListener(listener);
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsICancelable> cancelable = do_QueryInterface(persist);
rv = transfer->Init(sourceURI, targetURI, NS_LITERAL_STRING(""), nsnull, PR_Now(), nsnull, cancelable);
if (NS_FAILED(rv))
return rv;
rv = persist->SaveURI(sourceURI, nsnull, nsnull, nsnull, nsnull, fileAsSupports);
if (NS_FAILED(rv))
return rv;
return rv;
return StartInvokingDragSession(itemToDrag, aActionType);
}
//-------------------------------------------------------------------------
@ -563,185 +451,3 @@ nsDragService::EndDragSession()
return NS_OK;
}
// Start monitoring shell events - when user drops we'll get a notification from shell
// containing drop location
// aFileName is a filename to monitor
// returns true if all went ok
// if hidden window was created and shell is watching out for files being created
PRBool nsDragService::StartWatchingShell(const nsAString& aFileName)
{
// init member varable with the file name to watch
mFileName = aFileName;
nsDragService::mDropPath = NS_LITERAL_STRING("");
// Create hidden window to process shell notifications
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)HiddenWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = NULL;
wc.hIcon = NULL;
wc.hCursor = NULL;
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = TEXT("DHHidden");
unsigned short res = RegisterClass(&wc);
mHiddenWnd = CreateWindowEx(WS_EX_TOOLWINDOW,
TEXT("DHHidden"),
TEXT("DHHidden"),
WS_POPUP,
0,
0,
100,
100,
NULL,
NULL,
NULL,
NULL);
if (mHiddenWnd == NULL)
return PR_FALSE;
// Now let the explorer know what we want
// Get My Computer PIDL
LPITEMIDLIST pidl;
HRESULT hr = ::SHGetFolderLocation(NULL, CSIDL_DESKTOP, NULL, 0, &pidl);
if (SUCCEEDED(hr)) {
SHChangeNotifyStruct notify;
notify.pidl = pidl;
notify.fRecursive = TRUE;
HMODULE hShell32 = ::GetModuleHandleA("SHELL32.DLL");
if (hShell32 == NULL) {
::DestroyWindow(mHiddenWnd);
return PR_FALSE;
}
// Have to use ordinals in the call to GetProcAddress instead of function names.
// The reason for this is because on some older systems (prior to WinXP)
// this function has no name in shell32.dll.
DWORD dwOrdinal = 2;
// get reg func
SHCNRegPtr reg;
reg = (SHCNRegPtr)::GetProcAddress(hShell32, (LPCSTR)dwOrdinal);
if (reg == NULL) {
::DestroyWindow(mHiddenWnd);
return PR_FALSE;
}
mNotifyHandle = (reg)(mHiddenWnd,
0x2,
0x1,
WM_USER,
1,
&notify);
}
// destroy hidden window if failed to register notification handle
if (mNotifyHandle == 0) {
::DestroyWindow(mHiddenWnd);
}
return (mNotifyHandle != 0);
}
// Get the drop path if there is one:)
// returns true if there is a drop path
PRBool nsDragService::GetDropPath(nsAString& aDropPath) const
{
// we failed to create window so there is no drop path
if (mHiddenWnd == NULL)
return PR_FALSE;
// If we get 0 for this that means we failed to register notification callback
if (mNotifyHandle == 0)
return PR_FALSE;
// Do clean up stuff (reverses all that's been done in Start)
HMODULE hShell32 = ::GetModuleHandleA("SHELL32.DLL");
if (hShell32 == NULL)
return PR_FALSE;
// Have to use ordinals in the call to GetProcAddress instead of function names.
// The reason for this is because on some older systems (prior to WinXP)
// this function has no name in shell32.dll.
DWORD dwOrdinal = 4;
SHCNDeregPtr dereg;
dereg = (SHCNDeregPtr)::GetProcAddress(hShell32, (LPCSTR)dwOrdinal);
if (dereg == NULL)
return PR_FALSE;
(dereg)(mNotifyHandle);
::DestroyWindow(mHiddenWnd);
// if drop path is too short then there is no drop location
if (mDropPath.IsEmpty())
return PR_FALSE;
aDropPath = mDropPath;
return PR_TRUE;
}
// Hidden window procedure - this is where shell sends notifications
// When notification is received, perform some checking and copy path to the member variable
LRESULT WINAPI nsDragService::HiddenWndProc(HWND aWnd, UINT aMsg, WPARAM awParam, LPARAM alParam)
{
switch (aMsg) {
case WM_USER:
if (alParam == SHCNE_RENAMEITEM) {
// we got notification from shell
// as wParam we get 2 PIDL
LPCITEMIDLIST* ppidl = (LPCITEMIDLIST*)awParam;
// Get From path (where the file is comming from)
WCHAR szPathFrom[MAX_PATH + 1];
WCHAR szPathTo[MAX_PATH + 1];
nsToolkit::mSHGetPathFromIDList(ppidl[0], szPathFrom);
// Get To path (where the file is going to)
nsToolkit::mSHGetPathFromIDList(ppidl[1], szPathTo);
// first is from where the file is coming
// and the second is where the file is going
nsAutoString pathFrom(szPathFrom); // where the file is comming from
nsAutoString pathTo(szPathTo); // where the file is going to
// Get OS Temp directory
// Get system temp directory
nsresult rv;
nsCOMPtr<nsILocalFile> tempDir;
nsCOMPtr<nsIProperties> directoryService =
do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
if (!directoryService || NS_FAILED(rv))
return ResultFromScode(E_FAIL);
directoryService->Get(NS_OS_TEMP_DIR,
NS_GET_IID(nsIFile),
getter_AddRefs(tempDir));
// append file name to Temp directory string
nsAutoString tempPath;
tempDir->Append(mFileName);
tempDir->GetPath(tempPath);
// Now check if there is our filename in the path
// and also check for the source directory - it should be OS Temp dir
// this way we can ensure that this is the file that we need
PRInt32 fileNameLength = mFileName.Length();
if (Substring(pathTo, (pathTo.Length() - fileNameLength), fileNameLength).Equals(mFileName) &&
tempPath.Equals(pathFrom, nsCaseInsensitiveStringComparator()))
{
// This is what we wanted to get
mDropPath = pathTo;
}
return 0;
}
break;
}
return ::DefWindowProc(aWnd, aMsg, awParam, alParam);
}

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

@ -39,38 +39,11 @@
#define nsDragService_h__
#include "nsBaseDragService.h"
#include <windows.h>
#include <shlobj.h>
struct IDropSource;
struct IDataObject;
class nsNativeDragTarget;
class nsDataObjCollection;
class nsString;
// some older versions of MS PSDK do not have definitions for these, even though
// the functions are there and exported from the shell32.dll,
// so I had to add them manually. For example if one tries to build without those
// using VC6 standard libs one will get an error.
#ifndef SHCNE_RENAMEITEM_DEF
#define SHCNE_RENAMEITEM_DEF 0x00000001
// Structure
typedef struct {
LPCITEMIDLIST pidl;
BOOL fRecursive;
} SHChangeNotifyStruct;
#endif // SHCNE_RENAMEITEM_DEF
// Register for shell notifications func ptr
typedef ULONG (*SHCNRegPtr)(HWND hWnd, // Ordinal of 2
int fSources,
LONG fEvents,
UINT wMsg,
int cEntries,
SHChangeNotifyStruct *pschn);
// Unregister form from the shell notifications func ptr
typedef BOOL (*SHCNDeregPtr)(ULONG ulID); // Ordinal of 4
/**
* Native Win32 DragService wrapper
@ -106,23 +79,9 @@ protected:
// collections
PRBool IsCollectionObject(IDataObject* inDataObj);
// Begin monitoring the shell for events (this would allow to figure drop location)
PRBool StartWatchingShell(const nsAString& aFileName);
// Should be called after drag is over to get the drop path (if any)
PRBool GetDropPath(nsAString& aDropPath) const;
// Hidden window procedure - here we shall receive notification from the shell
static LRESULT WINAPI HiddenWndProc(HWND aWnd, UINT aMsg, WPARAM awParam, LPARAM alParam);
IDropSource * mNativeDragSrc;
nsNativeDragTarget * mNativeDragTarget;
IDataObject * mDataObject;
static nsString mFileName; // File name to look for
static nsString mDropPath; // Drop path
HWND mHiddenWnd; // Handle to a hidden window for notifications
PRInt32 mNotifyHandle; // Handle to installed hook (SHChangeNotify)
};
#endif // nsDragService_h__