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:
mkaply%us.ibm.com
2003-03-26 01:01:27 +00:00
parent 4d00a17c03
commit 325f6d6a00
5 changed files with 207 additions and 20 deletions

View File

@@ -41,6 +41,7 @@ REQUIRES = gfx \
pref \
plugin \
webshell \
webbrowserpersist \
$(NULL)
ifdef ENABLE_TESTS

View File

@@ -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)
{

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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; }