r=pedemont, sr=blizzard (platform specific) OS/2 only - allowing dropping of objects onto the browser, make holding down Ctrl download stuff git-svn-id: svn://10.0.0.236/trunk@140308 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -41,6 +41,7 @@ REQUIRES = gfx \
|
||||
pref \
|
||||
plugin \
|
||||
webshell \
|
||||
webbrowserpersist \
|
||||
$(NULL)
|
||||
|
||||
ifdef ENABLE_TESTS
|
||||
|
||||
@@ -40,6 +40,11 @@
|
||||
#include "nsString.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsIWebBrowserPersist.h"
|
||||
#include "nsILocalFile.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
|
||||
void WriteTypeEA(const char* filename, const char* type);
|
||||
@@ -62,20 +67,49 @@ MRESULT EXPENTRY nsDragWindowProc(HWND hWnd, ULONG msg, MPARAM mp1,
|
||||
ULONG ulLength;
|
||||
PSZ pszURL;
|
||||
CHAR chPath[CCHMAXPATH];
|
||||
CHAR chOrigPath[CCHMAXPATH];
|
||||
nsDragService* dragservice;
|
||||
switch (msg) {
|
||||
case DM_RENDERPREPARE:
|
||||
pdragtransfer = (PDRAGTRANSFER)mp1;
|
||||
if (pdragtransfer->usOperation == DO_COPY) {
|
||||
ulLength = DrgQueryStrNameLen(pdragtransfer->pditem->hstrSourceName);
|
||||
pszURL = (PSZ)nsMemory::Alloc(ulLength+1);
|
||||
DrgQueryStrName(pdragtransfer->pditem->hstrSourceName, ulLength+1, pszURL);
|
||||
nsCOMPtr<nsIURI> linkURI;
|
||||
NS_NewURI(getter_AddRefs(linkURI), pszURL);
|
||||
nsCOMPtr<nsIURL> linkURL(do_QueryInterface(linkURI));
|
||||
/* use URI for filename */
|
||||
nsCAutoString filename;
|
||||
linkURL->GetFileName(filename);
|
||||
if (filename.IsEmpty()) {
|
||||
filename = pszURL;
|
||||
}
|
||||
DrgDeleteStrHandle(pdragtransfer->pditem->hstrTargetName);
|
||||
pdragtransfer->pditem->hstrTargetName = DrgAddStrHandle(ToNewCString(filename));
|
||||
return (MRESULT)TRUE;
|
||||
}
|
||||
break;
|
||||
case DM_RENDER:
|
||||
pdragtransfer = (PDRAGTRANSFER)mp1;
|
||||
dragservice = (nsDragService*)pdragtransfer->pditem->ulItemID;
|
||||
DrgQueryStrName(pdragtransfer->hstrRenderToName, CCHMAXPATH, chPath);
|
||||
strcpy(chOrigPath, chPath);
|
||||
ulLength = DrgQueryStrNameLen(pdragtransfer->pditem->hstrSourceName);
|
||||
pszURL = (PSZ)nsMemory::Alloc(ulLength+1);
|
||||
DrgQueryStrName(pdragtransfer->pditem->hstrSourceName, ulLength+1, pszURL);
|
||||
fp = fopen(chPath, "wb+");
|
||||
fwrite(pszURL, ulLength, 1, fp);
|
||||
fclose(fp);
|
||||
WriteTypeEA(chPath, "UniformResourceLocator");
|
||||
if (pdragtransfer->usOperation == DO_COPY) {
|
||||
dragservice->WriteData(chPath, pszURL);
|
||||
} else {
|
||||
fp = fopen(chPath, "wb+");
|
||||
fwrite(pszURL, ulLength, 1, fp);
|
||||
fclose(fp);
|
||||
WriteTypeEA(chPath, "UniformResourceLocator");
|
||||
}
|
||||
nsMemory::Free(pszURL);
|
||||
DrgPostTransferMsg(pdragtransfer->hwndClient, DM_RENDERCOMPLETE, pdragtransfer, DMFL_RENDEROK,0,TRUE);
|
||||
DrgFreeDragtransfer(pdragtransfer);
|
||||
DosMove(chOrigPath, chPath);
|
||||
return (MRESULT)TRUE;
|
||||
break;
|
||||
default:
|
||||
@@ -92,6 +126,11 @@ nsDragService::~nsDragService()
|
||||
|
||||
NS_IMETHODIMP nsDragService::InvokeDragSession(nsIDOMNode *aDOMNode, nsISupportsArray *aTransferables, nsIScriptableRegion *aRegion, PRUint32 aActionType)
|
||||
{
|
||||
if (!aDOMNode && !aRegion && !aActionType) {
|
||||
/* Utter hack for drag drop - provide a way for nsWindow to set mSourceDataItems */
|
||||
mSourceDataItems = aTransferables;
|
||||
return NS_OK;
|
||||
}
|
||||
nsBaseDragService::InvokeDragSession ( aDOMNode, aTransferables, aRegion, aActionType );
|
||||
|
||||
// set our reference to the transferables. this will also addref
|
||||
@@ -109,7 +148,7 @@ NS_IMETHODIMP nsDragService::InvokeDragSession(nsIDOMNode *aDOMNode, nsISupports
|
||||
pDragInfo->usOperation = DO_DEFAULT;
|
||||
DRAGITEM dragitem;
|
||||
dragitem.hwndItem = mDragWnd;
|
||||
dragitem.ulItemID = (ULONG)0;
|
||||
dragitem.ulItemID = (ULONG)this;
|
||||
dragitem.hstrType = DrgAddStrHandle("UniformResourceLocator");
|
||||
dragitem.hstrRMF = DrgAddStrHandle("<DRM_OS2FILE,DRF_UNKNOWN>");
|
||||
dragitem.hstrContainerName = DrgAddStrHandle("");
|
||||
@@ -147,7 +186,12 @@ NS_IMETHODIMP nsDragService::InvokeDragSession(nsIDOMNode *aDOMNode, nsISupports
|
||||
} else {
|
||||
dragitem.hstrRMF = DrgAddStrHandle("<DRM_UNKNOWN,DRF_UNKNOWN>"); /* Moz only drag */
|
||||
}
|
||||
dragitem.fsControl = DC_OPEN;
|
||||
|
||||
#ifndef DC_PREPAREITEM
|
||||
#define DC_PREPAREITEM 0x0040;
|
||||
#endif
|
||||
|
||||
dragitem.fsControl = DC_OPEN | DC_PREPAREITEM;
|
||||
dragitem.cxOffset = 2;
|
||||
dragitem.cyOffset = 2;
|
||||
dragitem.fsSupportedOps = DO_COPYABLE|DO_MOVEABLE|DO_LINKABLE;
|
||||
@@ -165,7 +209,7 @@ NS_IMETHODIMP nsDragService::InvokeDragSession(nsIDOMNode *aDOMNode, nsISupports
|
||||
#ifdef DEBUG
|
||||
if (!hwndDest) {
|
||||
ERRORID eid = WinGetLastError((HAB)0);
|
||||
printf("Drag did not finish - error = %x error=%x\n", eid);
|
||||
printf("Drag did not finish - error=%x\n", eid);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -174,6 +218,8 @@ NS_IMETHODIMP nsDragService::InvokeDragSession(nsIDOMNode *aDOMNode, nsISupports
|
||||
DrgFreeDraginfo(pDragInfo);
|
||||
}
|
||||
|
||||
mSourceDataItems = 0;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -272,6 +318,33 @@ NS_IMETHODIMP nsDragService::IsDataFlavorSupported(const char *aDataFlavor, PRBo
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
BOOL nsDragService::WriteData(PSZ szDest, PSZ szURL)
|
||||
{
|
||||
FILE *fp;
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIWebBrowserPersist> webPersist(do_CreateInstance("@mozilla.org/embedding/browser/nsWebBrowserPersist;1", &rv));
|
||||
nsCOMPtr<nsIURI> linkURI;
|
||||
rv = NS_NewURI(getter_AddRefs(linkURI), szURL);
|
||||
nsCOMPtr<nsILocalFile> file;
|
||||
NS_NewNativeLocalFile(nsDependentCString(szDest), TRUE, getter_AddRefs(file));
|
||||
|
||||
nsCAutoString temp;
|
||||
file->GetNativePath(temp);
|
||||
fp = fopen(temp.get(), "wb+");
|
||||
fwrite(szURL, strlen(szURL), 1, fp);
|
||||
fclose(fp);
|
||||
nsCAutoString filename;
|
||||
nsCOMPtr<nsIURL> linkURL(do_QueryInterface(linkURI));
|
||||
linkURL->GetFileName(filename);
|
||||
if (filename.IsEmpty()) {
|
||||
/* If we don't have a filename, just mark it text/html */
|
||||
/* This can only be fixed if we write mime type on putting */
|
||||
/* any file to disk */
|
||||
WriteTypeEA(temp.get(), "text/html");
|
||||
}
|
||||
webPersist->SaveURI(linkURI, nsnull, nsnull, nsnull, nsnull, file);
|
||||
}
|
||||
|
||||
/* Helper functions */
|
||||
void WriteTypeEA(const char* filename, const char* type)
|
||||
{
|
||||
|
||||
@@ -57,6 +57,8 @@ public:
|
||||
NS_IMETHOD GetData(nsITransferable *aTransferable, PRUint32 aItemIndex);
|
||||
NS_IMETHOD IsDataFlavorSupported(const char *aDataFlavor, PRBool *_retval);
|
||||
|
||||
BOOL WriteData(PSZ szDest, PSZ szURL);
|
||||
|
||||
HWND mDragWnd;
|
||||
|
||||
// our source data items
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
//#include "nsMenu.h"
|
||||
#include "nsDragService.h"
|
||||
#include "nsILocalFile.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
#include "nsIRollupListener.h"
|
||||
#include "nsIMenuRollup.h"
|
||||
@@ -61,6 +62,8 @@
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsIFile.h"
|
||||
|
||||
#include "nsISupportsPrimitives.h"
|
||||
|
||||
#include "nsOS2Uni.h"
|
||||
#include "nsPaletteOS2.h"
|
||||
|
||||
@@ -159,7 +162,7 @@ nsWindow::nsWindow() : nsBaseWidget()
|
||||
mFrameIcon = 0;
|
||||
mPS = 0;
|
||||
mPSRefs = 0;
|
||||
mDragInside = FALSE;
|
||||
mNativeDrag = FALSE;
|
||||
mDeadKey = 0;
|
||||
mHaveDeadKey = FALSE;
|
||||
// This is so that frame windows can be destroyed from their destructors.
|
||||
@@ -372,13 +375,16 @@ void nsWindow::InitEvent(nsGUIEvent& event, PRUint32 aEventType, nsPoint* aPoint
|
||||
{
|
||||
event.widget = this;
|
||||
NS_ADDREF(event.widget);
|
||||
event.nativeMsg = nsnull;
|
||||
event.nativeMsg = 0;
|
||||
|
||||
if (nsnull == aPoint) { // use the point from the event
|
||||
// get the message position in client coordinates and in twips
|
||||
POINTL ptl;
|
||||
WinQueryMsgPos( 0/*hab*/, &ptl);
|
||||
WinMapWindowPoints( HWND_DESKTOP, mWnd, &ptl, 1);
|
||||
if ((aEventType == NS_DRAGDROP_DROP) && (mNativeDrag)) {
|
||||
ptl.x = ptl.y = 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
printf("++++++++++nsWindow::InitEvent (!pt) mapped point = %ld, %ld\n", ptl.x, ptl.y);
|
||||
@@ -946,6 +952,11 @@ void nsWindow::RealDoCreate( HWND hwndP,
|
||||
if( mParent)
|
||||
mParent->AddChild( this);
|
||||
|
||||
mContentType = aInitData? aInitData->mContentType : eContentTypeInherit;
|
||||
if (mContentType == eContentTypeInherit && aParent) {
|
||||
mContentType = aParent->mContentType;
|
||||
}
|
||||
|
||||
// call the event callback to notify about creation
|
||||
|
||||
DispatchStandardEvent( NS_CREATE );
|
||||
@@ -1887,7 +1898,7 @@ void* nsWindow::GetNativeData(PRUint32 aDataType)
|
||||
case NS_NATIVE_GRAPHIC:
|
||||
if( !mPS)
|
||||
{
|
||||
if( mDragInside) {
|
||||
if( mNativeDrag) {
|
||||
mPS = DrgGetPS(mWnd);
|
||||
} else {
|
||||
mPS = WinGetPS(mWnd);
|
||||
@@ -1924,7 +1935,7 @@ void nsWindow::FreeNativeData(void * data, PRUint32 aDataType)
|
||||
if( !mPSRefs)
|
||||
{
|
||||
BOOL rc;
|
||||
if( mDragInside) rc = DrgReleasePS( mPS);
|
||||
if( mNativeDrag) rc = DrgReleasePS( mPS);
|
||||
else rc = WinReleasePS( mPS);
|
||||
#ifdef DEBUG
|
||||
if( !rc)
|
||||
@@ -2595,7 +2606,7 @@ PRBool nsWindow::ProcessMessage( ULONG msg, MPARAM mp1, MPARAM mp2, MRESULT &rc)
|
||||
// is a drag inside the window; we need to do *this* so that we can
|
||||
// generate DRAGENTER messages [which os/2 doesn't provide].
|
||||
case DM_DROPHELP:
|
||||
mDragInside = FALSE;
|
||||
mNativeDrag = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3389,11 +3400,25 @@ PRBool nsWindow::OnDragOver(MPARAM mp1, MPARAM mp2, MRESULT &mr)
|
||||
USHORT usDrop = DOR_DROP;
|
||||
USHORT usDefaultOp = DO_MOVE;
|
||||
PDRAGINFO pdraginfo = (PDRAGINFO)mp1;
|
||||
DRAGITEM dragitem;
|
||||
|
||||
nsCOMPtr<nsIDragService> dragService = do_GetService("@mozilla.org/widget/dragservice;1", &rv);
|
||||
nsCOMPtr<nsIDragSession> dragSession;
|
||||
dragService->GetCurrentSession(getter_AddRefs(dragSession));
|
||||
if (dragSession) {
|
||||
DrgAccessDraginfo(pdraginfo);
|
||||
if (!dragSession) {
|
||||
/* Check to see if we can handle it. If we can, create a drag session */
|
||||
DrgQueryDragitem(pdraginfo, sizeof(DRAGITEM), &dragitem, 0);
|
||||
if (DrgVerifyRMF(&dragitem, "DRM_OS2FILE","DRF_TEXT") ||
|
||||
DrgVerifyRMF(&dragitem, "DRM_OS2FILE","DRF_UNKNOWN")) {
|
||||
dragService->StartDragSession();
|
||||
dragService->GetCurrentSession(getter_AddRefs(dragSession));
|
||||
mNativeDrag = TRUE;
|
||||
} else {
|
||||
usDrop = DOR_NEVERDROP;
|
||||
}
|
||||
}
|
||||
if ((dragSession) && (!mNativeDrag)) {
|
||||
PRBool canDrop;
|
||||
dragSession->GetCanDrop(&canDrop);
|
||||
if (!canDrop)
|
||||
@@ -3412,9 +3437,12 @@ PRBool nsWindow::OnDragOver(MPARAM mp1, MPARAM mp2, MRESULT &mr)
|
||||
dragSession->SetDragAction(nsIDragService::DRAGDROP_ACTION_MOVE);
|
||||
break;
|
||||
}
|
||||
} else if (mNativeDrag && (mContentType == eContentTypeContent)) {
|
||||
usDefaultOp = DO_MOVE;
|
||||
} else {
|
||||
usDrop = DOR_NEVERDROP;
|
||||
}
|
||||
DrgFreeDraginfo(pdraginfo);
|
||||
|
||||
mr = MRFROM2SHORT(usDrop, usDefaultOp);
|
||||
|
||||
@@ -3425,24 +3453,35 @@ PRBool nsWindow::OnDragOver(MPARAM mp1, MPARAM mp2, MRESULT &mr)
|
||||
|
||||
PRBool nsWindow::OnDragLeave( MPARAM mp1, MPARAM mp2)
|
||||
{
|
||||
// gWidgetModuleData->dragService->InitDragExit( (PDRAGINFO) mp1);
|
||||
// DispatchDragDropEvent( NS_DRAGDROP_EXIT);
|
||||
// gWidgetModuleData->dragService->TermDragExit();
|
||||
if (mNativeDrag) {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIDragService> dragService = do_GetService("@mozilla.org/widget/dragservice;1", &rv);
|
||||
nsCOMPtr<nsIDragSession> dragSession;
|
||||
dragService->GetCurrentSession(getter_AddRefs(dragSession));
|
||||
if (dragSession) {
|
||||
dragService->EndDragSession();
|
||||
mNativeDrag = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// mDragInside = FALSE;
|
||||
DispatchDragDropEvent(NS_DRAGDROP_EXIT);
|
||||
|
||||
return PR_TRUE;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
extern BOOL GetURLObjectContents(PDRAGITEM pDragItem);
|
||||
|
||||
PRBool nsWindow::OnDrop(MPARAM mp1, MPARAM mp2)
|
||||
{
|
||||
nsresult rv;
|
||||
PDRAGINFO pdraginfo = (PDRAGINFO)mp1;
|
||||
DRAGITEM dragitem;
|
||||
|
||||
nsCOMPtr<nsIDragService> dragService = do_GetService("@mozilla.org/widget/dragservice;1", &rv);
|
||||
nsCOMPtr<nsIDragSession> dragSession;
|
||||
dragService->GetCurrentSession(getter_AddRefs(dragSession));
|
||||
|
||||
DrgAccessDraginfo(pdraginfo);
|
||||
switch (pdraginfo->usOperation) {
|
||||
case DO_COPY:
|
||||
dragSession->SetDragAction(nsIDragService::DRAGDROP_ACTION_COPY);
|
||||
@@ -3455,7 +3494,78 @@ PRBool nsWindow::OnDrop(MPARAM mp1, MPARAM mp2)
|
||||
break;
|
||||
}
|
||||
|
||||
DispatchDragDropEvent( NS_DRAGDROP_DROP);
|
||||
if (mNativeDrag) {
|
||||
dragSession->SetDragAction(nsIDragService::DRAGDROP_ACTION_MOVE);
|
||||
// now create the transferable and stuff data into it.
|
||||
nsCOMPtr<nsITransferable> trans(do_CreateInstance("@mozilla.org/widget/transferable;1"));
|
||||
|
||||
DrgQueryDragitem(pdraginfo, sizeof(DRAGITEM), &dragitem, 0);
|
||||
if (DrgVerifyType(&dragitem, "UniformResourceLocator"))
|
||||
{
|
||||
GetURLObjectContents(&dragitem);
|
||||
}
|
||||
|
||||
PSZ pszURL;
|
||||
PSZ pszProtocol;
|
||||
PSZ pszTargetName;
|
||||
ULONG ulLength;
|
||||
ulLength = DrgQueryStrNameLen(dragitem.hstrSourceName);
|
||||
pszURL = (PSZ)nsMemory::Alloc(ulLength+1);
|
||||
DrgQueryStrName(dragitem.hstrSourceName, ulLength+1, pszURL);
|
||||
ulLength = DrgQueryStrNameLen(dragitem.hstrContainerName);
|
||||
pszProtocol = (PSZ)nsMemory::Alloc(ulLength+1);
|
||||
DrgQueryStrName(dragitem.hstrContainerName, ulLength+1, pszProtocol);
|
||||
ulLength = DrgQueryStrNameLen(dragitem.hstrTargetName);
|
||||
pszTargetName = (PSZ)nsMemory::Alloc(ulLength+1);
|
||||
DrgQueryStrName(dragitem.hstrTargetName, ulLength+1, pszTargetName);
|
||||
|
||||
|
||||
// add a special flavor if we're an anchor to indicate that we have a URL
|
||||
// in the drag data
|
||||
nsCAutoString dragData;
|
||||
if (DrgVerifyType(&dragitem, "UniformResourceLocator"))
|
||||
{
|
||||
dragData += pszProtocol;
|
||||
dragData += pszURL;
|
||||
} else {
|
||||
nsCOMPtr<nsILocalFile> file;
|
||||
char filepath[CCHMAXPATH];
|
||||
strcpy(filepath, pszProtocol);
|
||||
strcat(filepath, pszURL);
|
||||
if ( NS_SUCCEEDED(NS_NewNativeLocalFile(nsDependentCString(filepath), PR_TRUE, getter_AddRefs(file))) ) {
|
||||
nsCAutoString urlSpec;
|
||||
NS_GetURLSpecFromFile(file, urlSpec);
|
||||
dragData += urlSpec;
|
||||
|
||||
}
|
||||
}
|
||||
dragData += NS_LITERAL_CSTRING("\n");
|
||||
dragData += pszTargetName;
|
||||
nsMemory::Free(pszURL);
|
||||
nsMemory::Free(pszProtocol);
|
||||
nsMemory::Free(pszTargetName);
|
||||
DrgFreeDraginfo(pdraginfo);
|
||||
|
||||
nsCOMPtr<nsISupportsString> urlPrimitive(do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
|
||||
if ( !urlPrimitive )
|
||||
return NS_ERROR_FAILURE;
|
||||
urlPrimitive->SetData(NS_ConvertASCIItoUCS2(dragData));
|
||||
trans->SetTransferData(kURLMime, urlPrimitive, dragData.Length() * 2);
|
||||
|
||||
nsCOMPtr<nsISupportsArray> transArray(do_CreateInstance("@mozilla.org/supports-array;1"));
|
||||
if ( !transArray )
|
||||
return NS_ERROR_FAILURE;
|
||||
transArray->InsertElementAt(trans, 0);
|
||||
|
||||
dragService->InvokeDragSession(0, transArray, 0, 0);
|
||||
}
|
||||
|
||||
DispatchDragDropEvent(NS_DRAGDROP_DROP);
|
||||
|
||||
if (mNativeDrag && dragSession) {
|
||||
dragService->EndDragSession();
|
||||
mNativeDrag = PR_FALSE;
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
@@ -242,7 +242,7 @@ protected:
|
||||
HPOINTER mFrameIcon; // current frame icon
|
||||
HPS mPS; // cache PS for window
|
||||
ULONG mPSRefs; // number of refs to cache ps
|
||||
BOOL mDragInside; // track draginside state
|
||||
BOOL mNativeDrag; // is the drag from outside Mozilla
|
||||
VDKEY mDeadKey; // dead key from previous keyevent
|
||||
BOOL mHaveDeadKey; // is mDeadKey valid [0 may be a valid dead key, for all I know]
|
||||
HWND mHackDestroyWnd; // access GetMainWindow() window from destructor
|
||||
@@ -250,6 +250,7 @@ protected:
|
||||
PRBool mIsTopWidgetWindow;
|
||||
BOOL mIsScrollBar;
|
||||
BOOL mInSetFocus;
|
||||
nsContentType mContentType;
|
||||
|
||||
HWND GetParentHWND() const;
|
||||
HWND GetHWND() const { return mWnd; }
|
||||
|
||||
Reference in New Issue
Block a user