/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape 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/NPL/ * * 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 Communicator client code. * * The Initial Developer of the Original Code is Netscape Communications * Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): * Pierre Phaneuf */ // // Mike Pinkerton // Netscape Communications // // Significant portions of the collapse/expanding code donated by Chris Lattner // (sabre@skylab.org). Thanks Chris! // // See documentation in associated header file // #include "nsToolboxFrame.h" #include "nsToolbarFrame.h" // needed for MIME definitions #include "nsIStyleContext.h" #include "nsCSSRendering.h" #include "nsIReflowCommand.h" #include "nsHTMLIIDs.h" #include "nsIPresContext.h" #include "nsIWidget.h" #include "nsINameSpaceManager.h" #include "nsBoxLayoutState.h" #include "nsIServiceManager.h" #include "nsWidgetsCID.h" #include "nsIDragService.h" #include "nsIDragSession.h" #include "nsITransferable.h" #include "nsIFormatConverter.h" #include "nsCOMPtr.h" #include "nsIDOMUIEvent.h" #include "nsIDOMDragListener.h" #include "nsIDOMEventReceiver.h" #include "nsIDOMEventListener.h" #include "nsISupportsPrimitives.h" #include "nsISupportsArray.h" #include "nsHTMLAtoms.h" // Drag & Drop, Clipboard Support static NS_DEFINE_CID(kCDragServiceCID, NS_DRAGSERVICE_CID); static NS_DEFINE_CID(kCTransferableCID, NS_TRANSFERABLE_CID); static NS_DEFINE_IID(kCDataFlavorCID, NS_DATAFLAVOR_CID); static NS_DEFINE_IID(kCXIFFormatConverterCID, NS_XIFFORMATCONVERTER_CID); NS_IMPL_ADDREF(nsToolboxFrame::DragListenerDelegate); NS_IMPL_RELEASE(nsToolboxFrame::DragListenerDelegate); NS_IMPL_QUERY_INTERFACE2(nsToolboxFrame::DragListenerDelegate, nsIDOMDragListener, nsIDOMEventListener) // // NS_NewToolboxFrame // // Creates a new toolbox frame and returns it in |aNewFrame| // nsresult NS_NewToolboxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ) { NS_PRECONDITION(aNewFrame, "null OUT ptr"); if (nsnull == aNewFrame) { return NS_ERROR_NULL_POINTER; } nsToolboxFrame* it = new (aPresShell) nsToolboxFrame (aPresShell); if (nsnull == it) return NS_ERROR_OUT_OF_MEMORY; //it->SetFlags(aFlags); *aNewFrame = it; return NS_OK; } // NS_NewToolboxFrame // // nsToolboxFrame cntr // // Init, if necessary // nsToolboxFrame :: nsToolboxFrame (nsIPresShell* aShell):nsBoxFrame(aShell) , mDragListenerDelegate(nsnull) { } // // nsToolboxFrame dstr // // Cleanup, as necessary // nsToolboxFrame :: ~nsToolboxFrame ( ) { if (mDragListenerDelegate) { mDragListenerDelegate->NotifyFrameDestroyed(); NS_RELEASE(mDragListenerDelegate); } } NS_IMETHODIMP nsToolboxFrame::Init(nsIPresContext* aPresContext, nsIContent* aContent, nsIFrame* aParent, nsIStyleContext* aContext, nsIFrame* aPrevInFlow) { nsresult rv = nsBoxFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow); // Register the delegate as a drag listener. mDragListenerDelegate = new DragListenerDelegate(this); if (! mDragListenerDelegate) return NS_ERROR_OUT_OF_MEMORY; NS_ADDREF(mDragListenerDelegate); nsCOMPtr content; rv = GetContent(getter_AddRefs(content)); if (NS_FAILED(rv)) return rv; nsCOMPtr reciever(do_QueryInterface(content)); reciever->AddEventListenerByIID(NS_STATIC_CAST(nsIDOMDragListener*, mDragListenerDelegate), NS_GET_IID(nsIDOMDragListener)); return rv; } //////////////////////////////////////////////////////////////////////// nsresult nsToolboxFrame::HandleEvent(nsIDOMEvent* aEvent) { //printf("nsToolbarDragListener::HandleEvent\n"); return NS_OK; } //////////////////////////////////////////////////////////////////////// nsresult nsToolboxFrame::DragEnter(nsIDOMEvent* aDragEvent) { nsIDragService* dragService; nsresult rv = nsServiceManager::GetService(kCDragServiceCID, NS_GET_IID(nsIDragService), (nsISupports **)&dragService); if ( NS_SUCCEEDED(rv) ) { nsCOMPtr dragSession(do_QueryInterface(dragService)); if ( dragSession ) { PRBool flavorSupported = PR_FALSE; dragSession->IsDataFlavorSupported(TOOLBAR_MIME, &flavorSupported); if ( flavorSupported ) { dragSession->SetCanDrop(PR_TRUE); rv = NS_ERROR_BASE; // consume event } } nsServiceManager::ReleaseService(kCDragServiceCID, dragService); } else { rv = NS_OK; } return rv; } //////////////////////////////////////////////////////////////////////// nsresult nsToolboxFrame::DragOver(nsIDOMEvent* aDragEvent) { // now tell the drag session whether we can drop here nsIDragService* dragService; nsresult rv = nsServiceManager::GetService(kCDragServiceCID, NS_GET_IID(nsIDragService), (nsISupports **)&dragService); if ( NS_SUCCEEDED(rv) ) { nsCOMPtr dragSession(do_QueryInterface(dragService)); if ( dragSession ) { PRBool flavorSupported = PR_FALSE; dragSession->IsDataFlavorSupported(TOOLBAR_MIME, &flavorSupported); if ( flavorSupported ) { // Right here you need to figure out where the mouse is // and whether you can drop here dragSession->SetCanDrop(PR_TRUE); rv = NS_ERROR_BASE; // consume event } } nsServiceManager::ReleaseService(kCDragServiceCID, dragService); } // NS_OK means event is NOT consumed return rv; } //////////////////////////////////////////////////////////////////////// nsresult nsToolboxFrame::DragExit(nsIDOMEvent* aDragEvent) { return NS_ERROR_BASE; // consumes event } //////////////////////////////////////////////////////////////////////// nsresult nsToolboxFrame::DragDrop(nsIDOMEvent* aMouseEvent) { // Create drag service for getting state of drag nsIDragService* dragService; nsresult rv = nsServiceManager::GetService(kCDragServiceCID, NS_GET_IID(nsIDragService), (nsISupports **)&dragService); if (NS_OK == rv) { nsCOMPtr dragSession(do_QueryInterface(dragService)); if (dragSession) { // Create transferable for getting the drag data nsCOMPtr trans; rv = nsComponentManager::CreateInstance(kCTransferableCID, nsnull, NS_GET_IID(nsITransferable), (void**) getter_AddRefs(trans)); if ( NS_SUCCEEDED(rv) && trans ) { // Add the toolbar Flavor to the transferable, because that is the only type of data we are // looking for at the moment. trans->AddDataFlavor(TOOLBAR_MIME); // Fill the transferable with data for each drag item in succession PRUint32 numItems = 0; if (NS_SUCCEEDED(dragSession->GetNumDropItems(&numItems))) { //printf("Num Drop Items %d\n", numItems); PRUint32 i; for (i=0;iGetData(trans, i))) { // Get the string data out of the transferable as a nsISupportsString. nsCOMPtr data; PRUint32 len; char* whichFlavor = nsnull; trans->GetAnyTransferData(&whichFlavor, getter_AddRefs(data), &len); nsCOMPtr dataAsString ( do_QueryInterface(data) ); // If the string was not empty then make it so. if ( dataAsString ) { char* stuffToPaste; dataAsString->ToString ( &stuffToPaste ); printf("Dropped: %s\n", stuffToPaste); dragSession->SetCanDrop(PR_TRUE); } nsAllocator::Free ( whichFlavor ); } } // foreach drag item } } // if valid transferable } // if valid drag session nsServiceManager::ReleaseService(kCDragServiceCID, dragService); } // if valid drag service return NS_ERROR_BASE; // consume the event; }