Mozilla/mozilla/widget/src/beos/nsDragService.cpp
bzbarsky%mit.edu d2d337437c Introduce a GetPrimaryShell() API on nsIDocument. Convert existing callers of
GetShellAt(0) to using this API.  Bug 378780.  API introduction part by me,
r+sr=jst.  Mass-changes done by taras using squash, r+sr=me


git-svn-id: svn://10.0.0.236/trunk@225416 18797224-902f-48f8-a5cc-f745e15eee43
2007-05-01 22:24:25 +00:00

784 lines
28 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Pierre Phaneuf <pp@ludusdesign.com>
* Paul Ashford
* Fredrik Holmqvist <thesuckiestemail@yahoo.se>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <stdio.h>
#include "nsDragService.h"
#include "nsIDocument.h"
#include "nsIRegion.h"
#include "nsITransferable.h"
#include "nsIServiceManager.h"
#include "nsISupportsPrimitives.h"
#include "nsVoidArray.h"
#include "nsXPIDLString.h"
#include "nsPrimitiveHelpers.h"
#include "nsUnitConversion.h"
#include "nsWidgetsCID.h"
#include "nsCRT.h"
// if we want to do Image-dragging, also need to change Makefile.in
// to add
// -I$(topsrcdir)/gfx/src/beos \
// in INCLUDES
// and bug 294234 to be done.
// #include "nsIImage.h"
// #include "nsIImageBeOS.h"
//#include <Bitmap.h>
#include <AppDefs.h>
#include <TypeConstants.h>
#include <DataIO.h>
#include <Mime.h>
#include <Rect.h>
#include <Region.h>
#include <String.h>
#include <View.h>
#include "prlog.h"
#include "nsIPresShell.h"
#include "nsPresContext.h"
#include "nsIFrame.h"
#include "nsIView.h"
#include "nsIWidget.h"
static NS_DEFINE_CID(kCDragServiceCID, NS_DRAGSERVICE_CID);
static PRLogModuleInfo *sDragLm = NULL;
static nsIFrame*
GetPrimaryFrameFor(nsIDOMNode *aDOMNode)
{
nsCOMPtr<nsIContent> aContent = do_QueryInterface(aDOMNode);
if (nsnull == aContent)
return nsnull;
nsIDocument* doc = aContent->GetCurrentDoc();
if (nsnull == doc)
return nsnull;
nsIPresShell* presShell = doc->GetPrimaryShell();
if ( nsnull == presShell)
return nsnull;
return presShell->GetPrimaryFrameFor(aContent);
}
static bool
IsInternalDrag(BMessage * aMsg)
{
BString orig;
// We started this drag if originater is 'BeZilla'
return (nsnull != aMsg && B_OK == aMsg->FindString("be:originator", &orig) &&
0 == orig.Compare("BeZilla"));
}
NS_IMPL_THREADSAFE_ISUPPORTS3(nsDragService, nsIDragService, nsIDragSession, nsIDragSessionBeOS)
//NS_IMPL_THREADSAFE_ISUPPORTS1(nsBaseDragService, nsIDragSessionBeOS)
//-------------------------------------------------------------------------
//
// DragService constructor
// Enable logging: 'export NSPR_LOG_MODULES=nsDragService:5'
//-------------------------------------------------------------------------
nsDragService::nsDragService()
{
// set up our logging module
if (!sDragLm)
sDragLm = PR_NewLogModule("nsDragService");
PR_LOG(sDragLm, PR_LOG_DEBUG, ("\n\nnsDragService::nsDragService"));
mDragMessage = NULL;
mCanDrop = PR_FALSE;
}
//-------------------------------------------------------------------------
//
// DragService destructor
//
//-------------------------------------------------------------------------
nsDragService::~nsDragService()
{
PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService::~nsDragService"));
ResetDragInfo();
}
//-------------------------------------------------------------------------
//
// nsIDragService : InvokeDragSession
//
// Called when a drag is being initiated from within mozilla
// The code here gets the BView, the dragRect, builds the DragMessage and
// starts the drag.
//
//-------------------------------------------------------------------------
NS_IMETHODIMP
nsDragService::InvokeDragSession (nsIDOMNode *aDOMNode,
nsISupportsArray * aArrayTransferables,
nsIScriptableRegion * aRegion,
PRUint32 aActionType)
{
PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService::InvokeDragSession"));
nsBaseDragService::InvokeDragSession (aDOMNode, aArrayTransferables,
aRegion, aActionType);
ResetDragInfo();
// make sure that we have an array of transferables to use
if (nsnull == aArrayTransferables)
return NS_ERROR_INVALID_ARG;
// set our reference to the transferables. this will also addref
// the transferables since we're going to hang onto this beyond the
// length of this call
mSourceDataItems = aArrayTransferables;
// Get a box or a bitmap to drag
bool haveRect = false;
BRect dragRect;
if (nsnull != aRegion)
{
PRInt32 aX, aY, aWidth, aHeight;
// TODO. Region may represent multiple rects - when dragging multiple items.
aRegion->GetBoundingBox(&aX, &aY, &aWidth, &aHeight);
dragRect.Set( aX, aY, aX + aWidth, aY + aHeight);
haveRect = true;
// does this need to be offset?
}
// Get the frame for this content node (note: frames are not refcounted)
nsIFrame *aFrame = GetPrimaryFrameFor(aDOMNode);
if (nsnull == aFrame)
return PR_FALSE;
// Now that we have the frame, we have to convert its coordinates into global screen
// coordinates.
nsRect aRect = aFrame->GetRect();
// Find offset from our view
nsIView *containingView = nsnull;
nsPoint viewOffset(0,0);
aFrame->GetOffsetFromView(viewOffset, &containingView);
NS_ASSERTION(containingView, "No containing view!");
if (nsnull == containingView)
return PR_FALSE;
// get the widget associated with the containing view.
nsPoint aWidgetOffset;
nsCOMPtr<nsIWidget> aWidget = containingView->GetNearestWidget(&aWidgetOffset);
if (nsnull == aWidget)
return PR_FALSE;
BView *view = (BView *) aWidget->GetNativeData(NS_NATIVE_WIDGET);
// Don't have the rect yet, try to get it from the dom node
if (nsnull==haveRect)
{
float t2p = aFrame->GetPresContext()->TwipsToPixels();
// GetOffsetFromWidget() actually returns the _parent's_ offset from its widget, so we
// still have to add in the offset to |containingView|'s parent ourselves.
nsPoint aViewPos = containingView->GetPosition();
// Shift our offset rect by offset into our view, the view's offset to its parent, and
// the parent's offset to the closest widget. Then convert that to global coordinates.
// Recall that WidgetToScreen() will give us the global coordinates of the rectangle we
// give it, but it expects everything to be in pixels.
nsRect screenOffset;
screenOffset.MoveBy ( NSTwipsToIntPixels(aWidgetOffset.x + aViewPos.x + viewOffset.x, t2p),
NSTwipsToIntPixels(aWidgetOffset.y + aViewPos.y + viewOffset.y, t2p));
aWidget->WidgetToScreen ( screenOffset, screenOffset );
dragRect.Set(screenOffset.x, screenOffset.y,
screenOffset.x + NSTwipsToIntPixels(aRect.width, t2p),
screenOffset.y + NSTwipsToIntPixels(aRect.height, t2p));
haveRect = true;
}
mDragAction = aActionType;
mDragMessage = CreateDragMessage();
if (!view || !mDragMessage)
return PR_FALSE;
// Set the original click location, how to get this or is it needed ?
// sourceMessage->AddPoint("click_location", mPoint);
if (!view->LockLooper())
return PR_FALSE;
// Well, let's just use the view frame, maybe?
if (!haveRect)
{
dragRect = view->Frame();
// do we need to offset?
}
PR_LOG(sDragLm, PR_LOG_DEBUG, ("invoking mDragView->DragMessage"));
bool noBitmap = true;
//This is the code for image-dragging, currently disabled. See comments in beginning of file.
# ifdef 0
do
{
PRUint32 dataSize;
PRUint32 noItems;
mSourceDataItems->Count(&noItems);
if (noItems!=1)
{
PR_LOG(sDragLm, PR_LOG_DEBUG, ("Transferables are not ==1, no drag bitmap!"));
break;
}
nsCOMPtr<nsISupports> genericItem;
aArrayTransferables->GetElementAt(0, getter_AddRefs(genericItem));
nsCOMPtr<nsITransferable> aTransferable (do_QueryInterface(genericItem));
nsCOMPtr<nsISupports> genericDataWrapper;
nsresult rv = aTransferable->GetTransferData(kNativeImageMime, getter_AddRefs(genericDataWrapper), &dataSize);
if (NS_FAILED(rv))
{
PR_LOG(sDragLm, PR_LOG_DEBUG, ("Could not get nativeimage, no drag bitmap!"));
break;
}
nsCOMPtr<nsISupportsInterfacePointer> ptrPrimitive (do_QueryInterface(genericDataWrapper));
if (ptrPrimitive == NULL)
{
PR_LOG(sDragLm, PR_LOG_DEBUG, ("Could not get ptrPrimitive, no drag bitmap!"));
break;
}
nsCOMPtr<nsISupports> genericData;
ptrPrimitive->GetData(getter_AddRefs(genericData));
if (genericData == NULL)
{
PR_LOG(sDragLm, PR_LOG_DEBUG, ("Could not get data, no drag bitmap!"));
break;
}
//dependent on bug 294234 and how it's implemented. This code was for attachment 183634.
nsCOMPtr<nsIImageBeOS> image (do_QueryInterface(genericData));
if (image == NULL)
{
PR_LOG(sDragLm, PR_LOG_DEBUG, ("Could not get nsImage, no drag bitmap!"));
break;
}
BBitmap *aBitmap;
image->GetBitmap(&aBitmap);
if (aBitmap==NULL || !aBitmap->IsValid())
{
PR_LOG(sDragLm, PR_LOG_DEBUG, ("Could not get BBitmap, no drag bitmap %s!", aBitmap==NULL?"(null)":"(not valid)" ));
break;
}
view->DragMessage(mDragMessage, aBitmap, B_OP_OVER, BPoint(-4,-4), view);
noBitmap = false;
} while(false);
# endif
if (noBitmap)
view->DragMessage(mDragMessage, dragRect, view);
StartDragSession();
view->UnlockLooper();
return NS_OK;
}
//-------------------------------------------------------------------------
//
// nsIDragService : StartDragSession
//
// We overwrite this so we can log it
//
//-------------------------------------------------------------------------
NS_IMETHODIMP
nsDragService::StartDragSession()
{
PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService::StartDragSession()"));
return nsBaseDragService::StartDragSession();
}
//-------------------------------------------------------------------------
//
// nsIDragService : EndDragSession
//
// We overwrite this so we can log it
//
//-------------------------------------------------------------------------
NS_IMETHODIMP
nsDragService::EndDragSession(PRBool aDoneDrag)
{
PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService::EndDragSession()"));
//Don't reset drag info, keep it until there is a new drag, in case a negotiated drag'n'drop wants the info.
//We need the draginfo as we are ending starting the dragsession
//on entering/exiting different views (nsWindows) now.
//That way the dragsession is always ended when we go outside mozilla windows, but we do throw away the
// mSourceDocument and mSourceNode. We do hold on to the nsTransferable if it was a internal drag.
//ResetDragInfo();
return nsBaseDragService::EndDragSession(aDoneDrag);
}
//-------------------------------------------------------------------------
//
// nsIDragSession : SetCanDrop
//
// We overwrite this so we can log it
//
//-------------------------------------------------------------------------
NS_IMETHODIMP
nsDragService::SetCanDrop(PRBool aCanDrop)
{
PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService::SetCanDrop(%s)",
aCanDrop == PR_TRUE?"TRUE":"FALSE"));
return nsBaseDragService::SetCanDrop(aCanDrop);
}
//-------------------------------------------------------------------------
//
// nsIDragSession : GetCanDrop
//
// We overwrite this so we can log it
//
//-------------------------------------------------------------------------
NS_IMETHODIMP
nsDragService::GetCanDrop(PRBool *aCanDrop)
{
PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService::GetCanDrop()"));
return nsBaseDragService::GetCanDrop(aCanDrop);
}
//-------------------------------------------------------------------------
//
// nsIDragSession : GetNumDropItems
//
// Gets the number of items currently being dragged
//
//-------------------------------------------------------------------------
NS_IMETHODIMP
nsDragService::GetNumDropItems(PRUint32 * aNumItems)
{
PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService::GetNumDropItems()"));
if (nsnull == mDragMessage)
{
*aNumItems = 0;
PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService::GetNumDropItems(): WARNING! No dragmessage"));
return NS_OK;
}
// Did we start this drag?
if (IsInternalDrag(mDragMessage))
mSourceDataItems->Count(aNumItems);
else
// The only thing native that I can think of that may have multiple items
// would be file references, DND-docs don't say anything about multiple items.
*aNumItems = 1;
PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService::GetNumDropItems():%d", *aNumItems));
return NS_OK;
}
//-------------------------------------------------------------------------
//
// nsIDragSession : GetData
//
// Copies the data at the given index into the given nsITransferable
//
// This is usually called on Drop, but can be called before that
//
//-------------------------------------------------------------------------
NS_IMETHODIMP
nsDragService::GetData(nsITransferable * aTransferable, PRUint32 aItemIndex)
{
PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService::GetData %d", aItemIndex));
if (nsnull==mDragMessage)
return NS_ERROR_INVALID_ARG;
// get flavor list that includes all acceptable flavors (including
// ones obtained through conversion). Flavors are nsISupportsStrings
// so that they can be seen from JS.
nsresult rv = NS_ERROR_FAILURE;
nsCOMPtr<nsISupportsArray> flavorList;
rv = aTransferable->FlavorsTransferableCanImport(getter_AddRefs(flavorList));
if (NS_FAILED(rv))
return rv;
// count the number of flavors
PRUint32 cnt;
flavorList->Count (&cnt);
nsCOMPtr<nsISupports> genericWrapper;
nsCOMPtr<nsISupportsCString> currentFlavor;
nsXPIDLCString flavorStr;
nsCOMPtr<nsISupports> genericItem;
nsCOMPtr<nsISupports> data;
PRUint32 tmpDataLen = 0;
for (unsigned int i= 0; i < cnt; ++i )
{
flavorList->GetElementAt(i, getter_AddRefs(genericWrapper));
currentFlavor = do_QueryInterface(genericWrapper);
if (!currentFlavor)
continue;
currentFlavor->ToString(getter_Copies(flavorStr));
PR_LOG(sDragLm, PR_LOG_DEBUG, ("tnsDragService::GetData trying to get transfer data for %s",
(const char *)flavorStr));
if (IsInternalDrag(mDragMessage))
{
mSourceDataItems->GetElementAt(aItemIndex, getter_AddRefs(genericItem));
nsCOMPtr<nsITransferable> item (do_QueryInterface(genericItem));
if (!item)
continue;
rv = item->GetTransferData(flavorStr, getter_AddRefs(data), &tmpDataLen);
if (NS_FAILED(rv))
continue;
PR_LOG(sDragLm, PR_LOG_DEBUG, ("tnsDragService::GetData setting data."));
return aTransferable->SetTransferData(flavorStr, data, tmpDataLen);
}
else
{
//Check if transfer message is simple_data or older type of DND
//Check if message has data else continue
//Negotiate for data (if possible) or get data
//set and return
}
}
PR_LOG(sDragLm, PR_LOG_DEBUG, ("tnsDragService::GetData failed"));
return NS_ERROR_FAILURE;
}
//-------------------------------------------------------------------------
//
// nsIDragSession : IsDataFlavorSupported
//
// Tells whether the given flavor is supported by the current drag object
//
// Called on MouseOver events
//
//-------------------------------------------------------------------------
NS_IMETHODIMP
nsDragService::IsDataFlavorSupported (const char *aDataFlavor,
PRBool *_retval)
{
PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService::IsDataFlavorSupported %s", aDataFlavor));
if (!_retval)
return NS_ERROR_INVALID_ARG;
// set this to no by default
*_retval = PR_FALSE;
// check to make sure that we have a drag object set, here
if (nsnull == mDragMessage)
{
PR_LOG(sDragLm, PR_LOG_DEBUG, ("*** warning: IsDataFlavorSupported called without a valid drag context!"));
return NS_OK;
}
if (IsInternalDrag(mDragMessage))
{
PRUint32 numDragItems = 0;
// if we don't have mDataItems we didn't start this drag so it's
// an external client trying to fool us.
if (nsnull == mSourceDataItems)
return NS_OK;
mSourceDataItems->Count(&numDragItems);
if (0 == numDragItems)
PR_LOG(sDragLm, PR_LOG_DEBUG, ("*** warning: Number of dragged items is zero!"));
// For all dragged items compare their flavors to the one wanted. If there is a match DataFlavor is supported.
nsCOMPtr<nsISupports> genericItem;
nsCOMPtr <nsISupportsArray> flavorList;
PRUint32 numFlavors;
for (PRUint32 itemIndex = 0; itemIndex < numDragItems; ++itemIndex)
{
mSourceDataItems->GetElementAt(itemIndex, getter_AddRefs(genericItem));
nsCOMPtr<nsITransferable> currItem (do_QueryInterface(genericItem));
if (nsnull == currItem)
continue;
currItem->FlavorsTransferableCanExport(getter_AddRefs(flavorList));
if (nsnull == flavorList)
continue;
flavorList->Count( &numFlavors );
nsCOMPtr<nsISupports> genericWrapper;
nsXPIDLCString flavorStr;
for ( PRUint32 flavorIndex = 0; flavorIndex < numFlavors ; ++flavorIndex )
{
flavorList->GetElementAt (flavorIndex, getter_AddRefs(genericWrapper));
nsCOMPtr<nsISupportsCString> currentFlavor = do_QueryInterface(genericWrapper);
if (nsnull == currentFlavor)
continue;
currentFlavor->ToString ( getter_Copies(flavorStr) );
PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService::IsDataFlavorSupported checking %s against %s", (const char *)flavorStr, aDataFlavor));
if (0 != strcmp(flavorStr, aDataFlavor))
continue;
PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService::IsDataFlavorSupported Got the flavor!"));
*_retval = PR_TRUE;
return NS_OK;
}
}
}
else
{
PR_LOG(sDragLm, PR_LOG_DEBUG, ("*** warning: Native drag not implemented."));
// TODO: implement native checking
}
PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService::IsDataFlavorSupported FALSE"));
return NS_OK;
}
//-------------------------------------------------------------------------
//
// nsDragServoce : CreateDragMessage
//
// Builds the drag message needed for BeOS negotiated DND.
//
//-------------------------------------------------------------------------
BMessage *
nsDragService::CreateDragMessage()
{
PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService::GetInitialDragMessage"));
if (nsnull == mSourceDataItems)
return NULL;
unsigned int numDragItems = 0;
mSourceDataItems->Count(&numDragItems);
BMessage * returnMsg = new BMessage(B_SIMPLE_DATA);
returnMsg->AddString("be:originator", "BeZilla");
returnMsg->AddString("be:clip_name","BeZilla Drag Item");
if (mDragAction & DRAGDROP_ACTION_COPY)
returnMsg->AddInt32("be:actions",B_COPY_TARGET);
if (mDragAction & DRAGDROP_ACTION_MOVE)
returnMsg->AddInt32("be:actions",B_MOVE_TARGET);
if (mDragAction & DRAGDROP_ACTION_LINK)
returnMsg->AddInt32("be:actions",B_LINK_TARGET);
// Check to see if we're dragging > 1 item. If we are then we use
// an internal only type.
if (numDragItems > 1)
{
PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService:: Dragging a list of items ..."));
// returnMsg->AddString("be:types", gMimeListType);
// returnMsg->AddString("be:types", B_FILE_MIME_TYPE);
// returnMsg->AddString("be:filetypes", gMimeListType);
// returnMsg->AddString("be:type_descriptions", gMimeListType);
return returnMsg;
}
PRBool addedType = PR_FALSE;
nsCOMPtr<nsISupports> genericItem;
nsCOMPtr <nsISupportsArray> flavorList;
PRUint32 numFlavors;
nsCOMPtr<nsISupports> genericWrapper;
nsXPIDLCString flavorStr;
for (unsigned int itemIndex = 0; itemIndex < numDragItems; ++itemIndex)
{
mSourceDataItems->GetElementAt(itemIndex, getter_AddRefs(genericItem));
nsCOMPtr<nsITransferable> currItem (do_QueryInterface(genericItem));
if (nsnull == currItem)
continue;
currItem->FlavorsTransferableCanExport(getter_AddRefs(flavorList));
if (nsnull == flavorList)
continue;
flavorList->Count( &numFlavors );
for (PRUint32 flavorIndex = 0; flavorIndex < numFlavors ; ++flavorIndex )
{
flavorList->GetElementAt(flavorIndex, getter_AddRefs(genericWrapper));
nsCOMPtr<nsISupportsCString> currentFlavor = do_QueryInterface(genericWrapper);
if (nsnull == currentFlavor)
continue;
currentFlavor->ToString ( getter_Copies(flavorStr) );
PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService:: Adding a flavor to our message: %s",flavorStr.get()));
type_code aCode;
if (B_OK == returnMsg->GetInfo(flavorStr.get(), &aCode))
continue;
returnMsg->AddString("be:types",flavorStr.get());
//returnMsg->AddString("be:types", B_FILE_MIME_TYPE);
returnMsg->AddString("be:filetypes",flavorStr.get());
returnMsg->AddString("be:type_descriptions",flavorStr.get());
addedType = PR_TRUE;
// Check to see if this is text/unicode. If it is, add
// text/plain since we automatically support text/plain if
// we support text/unicode.
//tqh: but this may cause duplicates?
if (0 == strcmp(flavorStr, kUnicodeMime))
{
PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService:: Adding a TextMime for the UnicodeMime"));
returnMsg->AddString("be:types",kTextMime);
//returnMsg->AddString("be:types", B_FILE_MIME_TYPE);
returnMsg->AddString("be:filetypes",kTextMime);
returnMsg->AddString("be:type_descriptions",kTextMime);
}
}
}
if (addedType)
{
returnMsg->AddString("be:types", B_FILE_MIME_TYPE);
}
returnMsg->PrintToStream();
// If we did not add a type, we can't drag
NS_ASSERTION(addedType == PR_TRUE, "No flavor/mime in the drag message!");
return returnMsg;
}
//-------------------------------------------------------------------------
//
// nsIDragSessionBeOS : UpdateDragMessageIfNeeded
//
// Updates the drag message from the old one if we enter a mozilla view with
// a dragmessage from outside. IE one where "be:originator"-key != "BeZilla"
//
//-------------------------------------------------------------------------
NS_IMETHODIMP
nsDragService::UpdateDragMessageIfNeeded(BMessage *aDragMessage)
{
PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService::UpdateDragMessageIfNeeded()"));
if (aDragMessage == mDragMessage)
return NS_OK;
// Did we start this drag?
//It's already set properly by InvokeDragSession, so don't do anything and avoid throwing away
//mSourceDataItems
if (IsInternalDrag(aDragMessage))
return NS_OK;
PR_LOG(sDragLm, PR_LOG_DEBUG, ("updating."));
ResetDragInfo();
mDragMessage = aDragMessage;
return NS_OK;
}
//-------------------------------------------------------------------------
//
// nsIDragSessionBeOS : TransmitData
//
// When a negotiated drag'n'drop to another app occurs nsWindow
// calls this method with the other apps message which contains
// the info on what data the app wants. This function checks the
// message and transmits the data to the app, thereby ending the
// drag'n'drop to another app.
//-------------------------------------------------------------------------
NS_IMETHODIMP
nsDragService::TransmitData(BMessage *aNegotiationReply)
{
PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService::TransmitData()"));
/*
unsigned int numDragItems = 0;
mSourceDataItems->Count(&numDragItems);
returnMsg->AddString("be:originator", "BeZilla");
returnMsg->AddString("be:clip_name","BeZilla Drag Item");
// Check to see if we're dragging > 1 item. If we are then we use
// an internal only type.
if (numDragItems > 1)
{
PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService:: Dragging a list of items ..."));
delete aNegotiationReply;
return;
}
BMessage aReply = new BMessage(B_MIME_DATA);
char * aMimeType;
aNegotiationReply->FindString("be:types", &aMimeType);
nsCOMPtr<nsITransferable> item;
item->addDataFlavor(aMimeType);
GetData(item, 0);
aReply->AddData(aMimeType, item->);
*/
aNegotiationReply->PrintToStream();
delete aNegotiationReply;
return NS_OK;
}
//-------------------------------------------------------------------------
//
// nsIDragService : ResetDragInfo
//
// Resets the stored drag information.
//
//-------------------------------------------------------------------------
void
nsDragService::ResetDragInfo()
{
PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService::ResetDragInfo()"));
if (nsnull != mDragMessage) delete mDragMessage;
mDragMessage = NULL;
mSourceDataItems = NULL;
}
const char *
nsDragService::FlavorToBeMime(const char * flavor)
{
//text/plain ok
//text/unicode -> text/plain
if (0 == strcmp(flavor,kUnicodeMime)) return kTextMime;
//text/html ok
//AOLMAIL ignore!!
//image/png ok
//image/jpg
if (0 == strcmp(flavor,kJPEGImageMime)) return "image/jpeg";
//image/gif ok
//application/x-moz-file
if (0 == strcmp(flavor,kFileMime)) return "application/octet-stream";
//text/x-moz-url (only support this as a filetype (Be bookmark))
if (0 == strcmp(flavor,kURLMime)) return "application/x-vnd.Be-bookmark";
//text/x-moz-url-data - we need to read data to find out what type of URL.
//text/x-moz-url-desc - a url-description (same as title?)
//kNativeImageMime - don't support as BeOS image
//kNativeHTMLMime - don't support on BeOS side
//kFilePromiseURLMime
//kFilePromiseDestFilename
//kFilePromiseMime
//kFilePromiseDirectoryMime
// if (0==strcmp(flavor,kUnicodeMime))
}