diff options
-rw-r--r-- | vcl/source/window/dndevdis.cxx | 341 | ||||
-rw-r--r-- | vcl/source/window/dndevdis.hxx | 112 | ||||
-rw-r--r-- | vcl/source/window/dndlcon.cxx | 448 | ||||
-rw-r--r-- | vcl/source/window/dndlcon.hxx | 144 | ||||
-rw-r--r-- | vcl/source/window/makefile.mk | 17 | ||||
-rw-r--r-- | vcl/source/window/syswin.cxx | 86 | ||||
-rw-r--r-- | vcl/source/window/window.cxx | 41 | ||||
-rw-r--r-- | vcl/source/window/winproc.cxx | 36 |
8 files changed, 1213 insertions, 12 deletions
diff --git a/vcl/source/window/dndevdis.cxx b/vcl/source/window/dndevdis.cxx new file mode 100644 index 000000000000..80b562b4dce6 --- /dev/null +++ b/vcl/source/window/dndevdis.cxx @@ -0,0 +1,341 @@ +/************************************************************************* + * + * $RCSfile: dndevdis.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: obr $ $Date: 2001-02-05 09:45:05 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source 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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include <dndevdis.hxx> +#include <dndlcon.hxx> + +#include <vos/mutex.hxx> +#include <svapp.hxx> + +using namespace ::vos; +using namespace ::cppu; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::datatransfer; +using namespace ::com::sun::star::datatransfer::dnd; + +//================================================================================================== +// DNDEventDispatcher::DNDEventDispatcher +//================================================================================================== + +DNDEventDispatcher::DNDEventDispatcher( Window * pTopWindow ): + m_pTopWindow( pTopWindow ), + m_pCurrentWindow( NULL ) +{ +} + +//================================================================================================== +// DNDEventDispatcher::~DNDEventDispatcher +//================================================================================================== + +DNDEventDispatcher::~DNDEventDispatcher() +{ +} + +//================================================================================================== +// DNDEventDispatcher::drop +//================================================================================================== + +void SAL_CALL DNDEventDispatcher::drop( const DropTargetDropEvent& dtde ) + throw(RuntimeException) +{ + Point location( dtde.Location.X, dtde.Location.Y ); + sal_Bool bSendDragEnter = sal_False; + + // find the window that is toplevel for this coordinates + OClearableGuard aGuard( Application::GetSolarMutex() ); + Window * pChildWindow = m_pTopWindow->ImplFindWindow( location ); + aGuard.clear(); + + // handle the case that drop is in an other vcl window than the last dragOver + if( pChildWindow != m_pCurrentWindow ) + { + // fire dragExit on listeners of previous window + dragExit( dtde ); + + // remember to send drag enter later + bSendDragEnter = sal_True; + } + + sal_Int32 nListeners = 0; + + // send drop event to the child window + if( pChildWindow ) + { + OClearableGuard aGuard2( Application::GetSolarMutex() ); + + // query DropTarget from child window + Reference< XDropTarget > xDropTarget = pChildWindow->GetDropTarget(); + + if( xDropTarget.is() ) + { + // retrieve relative mouse position + Point relLoc = pChildWindow->ImplFrameToOutput( location ); + aGuard2.clear(); + + // send DragEnterEvent if other window than at last dragOver + if( bSendDragEnter ) + { + static_cast < DNDListenerContainer * > ( xDropTarget.get() )-> + fireDragEnterEvent( static_cast < XDropTargetDragContext * > (dtde.Context.get()), + dtde.DropAction, ::com::sun::star::awt::Point( relLoc.X(), relLoc.Y() ), + dtde.SourceActions ); + } + + // fire...Event returns the number of listeners found + nListeners = static_cast < DNDListenerContainer * > ( xDropTarget.get() )-> + fireDropEvent( dtde.Context, dtde.DropAction, + ::com::sun::star::awt::Point( relLoc.X(), relLoc.Y() ), + dtde.SourceActions, dtde.Transferable ); + } + } + + // reject drop if no listeners found + if( nListeners == 0 ) + dtde.Context->reject(); +} + +//================================================================================================== +// DNDEventDispatcher::dragEnter +//================================================================================================== + +void SAL_CALL DNDEventDispatcher::dragEnter( const DropTargetDragEvent& dtde ) + throw(RuntimeException) +{ + sal_Int32 nListeners; + + // find the window that is toplevel for this coordinates + OClearableGuard aGuard( Application::GetSolarMutex() ); + Window * pChildWindow = m_pTopWindow->ImplFindWindow( Point( dtde.Location.X, dtde.Location.Y ) ); + aGuard.clear(); + + // assume pointer write operation to be atomic + m_pCurrentWindow = pChildWindow; + + // fire dropActionChanged on listeners of current window + nListeners = dragAction( 3, pChildWindow, dtde ); + + // reject drag if no listener found + if( nListeners == 0 ) + dtde.Context->reject(); +} + +//================================================================================================== +// DNDEventDispatcher::dragExit +//================================================================================================== + +void SAL_CALL DNDEventDispatcher::dragExit( const DropTargetEvent& dte ) + throw(RuntimeException) +{ + Window * pChildWindow = m_pCurrentWindow; + + // send the last window a drag exit + if( pChildWindow ) + { + OClearableGuard aGuard( Application::GetSolarMutex() ); + + // query DropTarget from child window + Reference< XDropTarget > xDropTarget = pChildWindow->GetDropTarget(); + aGuard.clear(); + + if( xDropTarget.is() ) + static_cast < DNDListenerContainer * > ( xDropTarget.get() )->fireDragExitEvent(); + } + + // reset current window + m_pCurrentWindow = NULL; +} + +//================================================================================================== +// DNDEventDispatcher::dragOver +//================================================================================================== + +void SAL_CALL DNDEventDispatcher::dragOver( const DropTargetDragEvent& dtde ) + throw(RuntimeException) +{ + sal_Int32 nListeners; + + // find the window that is toplevel for this coordinates + OClearableGuard aGuard( Application::GetSolarMutex() ); + Window * pChildWindow = m_pTopWindow->ImplFindWindow( Point( dtde.Location.X, dtde.Location.Y ) ); + aGuard.clear(); + + if( pChildWindow != m_pCurrentWindow ) + { + // fire dragExit on listeners of previous window + dragExit( dtde ); + + // remember new window + m_pCurrentWindow = pChildWindow; + + // fire dragEnter on listeners of current window + nListeners = dragAction( 1, pChildWindow, dtde ); + } + else + { + // fire dropActionChanged on listeners of current window + nListeners = dragAction( 2, pChildWindow, dtde ); + } + + // reject drag if no listener found + if( nListeners == 0 ) + dtde.Context->reject(); +} + +//================================================================================================== +// DNDEventDispatcher::dropActionChanged +//================================================================================================== + +void SAL_CALL DNDEventDispatcher::dropActionChanged( const DropTargetDragEvent& dtde ) + throw(RuntimeException) +{ + sal_Int32 nListeners; + + // find the window that is toplevel for this coordinates + OClearableGuard aGuard( Application::GetSolarMutex() ); + Window * pChildWindow = m_pTopWindow->ImplFindWindow( Point( dtde.Location.X, dtde.Location.Y ) ); + aGuard.clear(); + + if( pChildWindow != m_pCurrentWindow ) + { + // fire dragExit on listeners of previous window + dragExit( dtde ); + + // remember new window + m_pCurrentWindow = pChildWindow; + + // fire dragEnter on listeners of current window + nListeners = dragAction( 1, pChildWindow, dtde ); + } + else + { + // fire dropActionChanged on listeners of current window + nListeners = dragAction( 3, pChildWindow, dtde ); + } + + // reject drag if no listener found + if( nListeners == 0 ) + dtde.Context->reject(); +} + + +//================================================================================================== +// DNDEventDispatcher::disposing +//================================================================================================== + +void SAL_CALL DNDEventDispatcher::disposing( const EventObject& eo ) + throw(RuntimeException) +{ +} + +//================================================================================================== +// DNDEventDispatcher::dragAction +//================================================================================================== + +sal_Int32 DNDEventDispatcher::dragAction( sal_Int8 action, Window * pWindow, const DropTargetDragEvent& dtde ) +{ + sal_Int32 n = 0; + + if( pWindow ) + { + OClearableGuard aGuard( Application::GetSolarMutex() ); + + // query DropTarget from window + Reference< XDropTarget > xDropTarget = pWindow->GetDropTarget(); + + if( xDropTarget.is() ) + { + // retrieve relative mouse position + Point relLoc = pWindow->ImplFrameToOutput( Point( dtde.Location.X, dtde.Location.Y ) ); + aGuard.clear(); + + // fire...Event returns the number of listeners found + switch( action ) + { + case 1: + n = static_cast < DNDListenerContainer * > ( xDropTarget.get() )-> + fireDragEnterEvent( dtde.Context, dtde.DropAction, + ::com::sun::star::awt::Point( relLoc.X(), relLoc.Y() ), + dtde.SourceActions ); + break; + + case 2: + n = static_cast < DNDListenerContainer * > ( xDropTarget.get() )-> + fireDragOverEvent( dtde.Context, dtde.DropAction, + ::com::sun::star::awt::Point( relLoc.X(), relLoc.Y() ), + dtde.SourceActions ); + break; + + case 3: + n = static_cast < DNDListenerContainer * > ( xDropTarget.get() )-> + fireDropActionChangedEvent( dtde.Context, dtde.DropAction, + ::com::sun::star::awt::Point( relLoc.X(), relLoc.Y() ), + dtde.SourceActions ); + break; + + default: + ; + } + } + } + + return n; +} diff --git a/vcl/source/window/dndevdis.hxx b/vcl/source/window/dndevdis.hxx new file mode 100644 index 000000000000..8c726cb17d16 --- /dev/null +++ b/vcl/source/window/dndevdis.hxx @@ -0,0 +1,112 @@ +/************************************************************************* + * + * $RCSfile: dndevdis.hxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: obr $ $Date: 2001-02-05 09:45:05 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source 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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _DNDEVDIS_HXX_ +#define _DNDEVDIS_HXX_ + +#ifndef _COM_SUN_STAR_DATATRANSFER_DND_XDROPTARGETLISTENER_HPP_ +#include <com/sun/star/datatransfer/dnd/XDropTargetListener.hpp> +#endif + +#ifndef _CPPUHELPER_IMPLBASE1_HXX_ +#include <cppuhelper/implbase1.hxx> +#endif + +#ifndef _SV_WINDOW_HXX +#include <window.hxx> +#endif + +class DNDEventDispatcher: public ::cppu::WeakImplHelper1< + ::com::sun::star::datatransfer::dnd::XDropTargetListener > +{ + Window * m_pTopWindow; + Window * m_pCurrentWindow; + + // actions: 1 : DragEnter 2 : DragOver 3 : DropActionChanged + sal_Int32 dragAction( sal_Int8 action, Window * pWindow, const ::com::sun::star::datatransfer::dnd::DropTargetDragEvent& dtde ); + +public: + + DNDEventDispatcher( Window * pTopWindow ); + virtual ~DNDEventDispatcher(); + + /* + * XDropTargetListener + */ + + virtual void SAL_CALL drop( const ::com::sun::star::datatransfer::dnd::DropTargetDropEvent& dtde ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL dragEnter( const ::com::sun::star::datatransfer::dnd::DropTargetDragEvent& dtde ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL dragExit( const ::com::sun::star::datatransfer::dnd::DropTargetEvent& dte ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL dragOver( const ::com::sun::star::datatransfer::dnd::DropTargetDragEvent& dtde ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL dropActionChanged( const ::com::sun::star::datatransfer::dnd::DropTargetDragEvent& dtde ) throw(::com::sun::star::uno::RuntimeException); + + /* + * XEventListener + */ + + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& eo ) throw(::com::sun::star::uno::RuntimeException); +}; + +//================================================================================================== +// +//================================================================================================== + +#endif diff --git a/vcl/source/window/dndlcon.cxx b/vcl/source/window/dndlcon.cxx new file mode 100644 index 000000000000..21ea6fe80eb3 --- /dev/null +++ b/vcl/source/window/dndlcon.cxx @@ -0,0 +1,448 @@ +/************************************************************************* + * + * $RCSfile: dndlcon.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: obr $ $Date: 2001-02-05 09:45:05 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source 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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include<dndlcon.hxx> + +using namespace ::cppu; +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::datatransfer; +using namespace ::com::sun::star::datatransfer::dnd; + +//================================================================================================== +// +//================================================================================================== + +DNDListenerContainer::DNDListenerContainer() : m_aMutex(), + WeakComponentImplHelper2< XDragGestureRecognizer, XDropTarget >(m_aMutex) +{ + m_bActive = sal_False; + +// FIXME: set drop target default actions. +// m_nDefaultActions = ; +} + +//================================================================================================== +// +//================================================================================================== + +DNDListenerContainer::~DNDListenerContainer() +{ +} + +//================================================================================================== +// DNDListenerContainer::addDragGestureListener +//================================================================================================== + +void SAL_CALL DNDListenerContainer::addDragGestureListener( const Reference< XDragGestureListener >& dgl ) + throw(RuntimeException) +{ + rBHelper.addListener( getCppuType( ( const Reference< XDragGestureListener > * ) 0 ), dgl ); +} + +//================================================================================================== +// DNDListenerContainer::removeDragGestureListener +//================================================================================================== + +void SAL_CALL DNDListenerContainer::removeDragGestureListener( const Reference< XDragGestureListener >& dgl ) + throw(RuntimeException) +{ + rBHelper.removeListener( getCppuType( ( const Reference< XDragGestureListener > * ) 0 ), dgl ); +} + +//================================================================================================== +// DNDListenerContainer::resetRecognizer +//================================================================================================== + +void SAL_CALL DNDListenerContainer::resetRecognizer( ) + throw(RuntimeException) +{ +} + +//================================================================================================== +// DNDListenerContainer::addDropTargetListener +//================================================================================================== + +void SAL_CALL DNDListenerContainer::addDropTargetListener( const Reference< XDropTargetListener >& dtl ) + throw(RuntimeException) +{ + rBHelper.addListener( getCppuType( ( const Reference< XDropTargetListener > * ) 0 ), dtl ); +} + +//================================================================================================== +// DNDListenerContainer::removeDropTargetListener +//================================================================================================== + +void SAL_CALL DNDListenerContainer::removeDropTargetListener( const Reference< XDropTargetListener >& dtl ) + throw(RuntimeException) +{ + rBHelper.removeListener( getCppuType( ( const Reference< XDropTargetListener > * ) 0 ), dtl ); +} + +//================================================================================================== +// DNDListenerContainer::isActive +//================================================================================================== + +sal_Bool SAL_CALL DNDListenerContainer::isActive( ) + throw(RuntimeException) +{ + return m_bActive; +} + +//================================================================================================== +// DNDListenerContainer::setActive +//================================================================================================== + +void SAL_CALL DNDListenerContainer::setActive( sal_Bool active ) + throw(RuntimeException) +{ + m_bActive = active; +} + +//================================================================================================== +// DNDListenerContainer::getDefaultActions +//================================================================================================== + +sal_Int8 SAL_CALL DNDListenerContainer::getDefaultActions( ) + throw(RuntimeException) +{ + return m_nDefaultActions; +} + +//================================================================================================== +// DNDListenerContainer::setDefaultActions +//================================================================================================== + +void SAL_CALL DNDListenerContainer::setDefaultActions( sal_Int8 actions ) + throw(RuntimeException) +{ + m_nDefaultActions = actions; +} + +//================================================================================================== +// DNDListenerContainer::fireDropEvent +//================================================================================================== + +sal_uInt32 DNDListenerContainer::fireDropEvent( const Reference< XDropTargetDropContext >& context, + const sal_Int8 dropAction, const Point& location, const sal_Int8 sourceActions, + const Reference< XTransferable >& transferable ) +{ + sal_uInt32 nRet = 0; + + // fire DropTargetDropEvent on all XDropTargetListeners + OInterfaceContainerHelper *pContainer = rBHelper.getContainer( getCppuType( ( Reference < XDropTargetListener > * ) 0) ); + + if( pContainer ) + { + // do not construct the event before you are sure at least one listener is registered + DropTargetDropEvent aEvent( static_cast < XDropTarget * > (this), 0, context, dropAction, location, sourceActions, transferable ); + OInterfaceIteratorHelper aIterator( *pContainer ); + + while (aIterator.hasMoreElements()) + { + // FIXME: this can be simplified as soon as the Iterator has a remove method + Reference< XInterface > xElement( aIterator.next() ); + + try + { + // this may result in a runtime exception + Reference < XDropTargetListener > xListener( xElement, UNO_QUERY ); + + if( xListener.is() ) + { + xListener->drop( aEvent ); + nRet++; + } + } + + catch( RuntimeException exc ) + { + pContainer->removeInterface( xElement ); + } + } + } + + return nRet; +} + +//================================================================================================== +// DNDListenerContainer::fireDragExitEvent +//================================================================================================== + +sal_uInt32 DNDListenerContainer::fireDragExitEvent() +{ + sal_uInt32 nRet = 0; + + // fire DropTargetDropEvent on all XDropTargetListeners + OInterfaceContainerHelper *pContainer = rBHelper.getContainer( getCppuType( ( Reference < XDropTargetListener > * ) 0) ); + + if( pContainer ) + { + // do not construct the event before you are sure at least one listener is registered + DropTargetEvent aEvent( static_cast < XDropTarget * > (this), 0 ); + OInterfaceIteratorHelper aIterator( *pContainer ); + + while (aIterator.hasMoreElements()) + { + // FIXME: this can be simplified as soon as the Iterator has a remove method + Reference< XInterface > xElement( aIterator.next() ); + + try + { + // this may result in a runtime exception + Reference < XDropTargetListener > xListener( xElement, UNO_QUERY ); + + if( xListener.is() ) + { + xListener->dragExit( aEvent ); + nRet++; + } + } + + catch( RuntimeException exc ) + { + pContainer->removeInterface( xElement ); + } + } + } + + return nRet; +} + +//================================================================================================== +// DNDListenerContainer::fireDragOverEvent +//================================================================================================== + +sal_uInt32 DNDListenerContainer::fireDragOverEvent( const Reference< XDropTargetDragContext >& context, + const sal_Int8 dropAction, const Point& location, const sal_Int8 sourceActions ) +{ + sal_uInt32 nRet = 0; + + // fire DropTargetDropEvent on all XDropTargetListeners + OInterfaceContainerHelper *pContainer = rBHelper.getContainer( getCppuType( ( Reference < XDropTargetListener > * ) 0) ); + + if( pContainer ) + { + // do not construct the event before you are sure at least one listener is registered + DropTargetDragEvent aEvent( static_cast < XDropTarget * > (this), 0, context, dropAction, location, sourceActions ); + OInterfaceIteratorHelper aIterator( *pContainer ); + + while (aIterator.hasMoreElements()) + { + // FIXME: this can be simplified as soon as the Iterator has a remove method + Reference< XInterface > xElement( aIterator.next() ); + + try + { + // this may result in a runtime exception + Reference < XDropTargetListener > xListener( xElement, UNO_QUERY ); + + if( xListener.is() ) + { + xListener->dragOver( aEvent ); + nRet++; + } + } + + catch( RuntimeException exc ) + { + pContainer->removeInterface( xElement ); + } + } + } + + return nRet; +} + +//================================================================================================== +// DNDListenerContainer::fireDragEnterEvent +//================================================================================================== + +sal_uInt32 DNDListenerContainer::fireDragEnterEvent( const Reference< XDropTargetDragContext >& context, + const sal_Int8 dropAction, const Point& location, const sal_Int8 sourceActions ) +{ + sal_uInt32 nRet = 0; + + // fire DropTargetDropEvent on all XDropTargetListeners + OInterfaceContainerHelper *pContainer = rBHelper.getContainer( getCppuType( ( Reference < XDropTargetListener > * ) 0) ); + + if( pContainer ) + { + // do not construct the event before you are sure at least one listener is registered + DropTargetDragEvent aEvent( static_cast < XDropTarget * > (this), 0, context, dropAction, location, sourceActions ); + OInterfaceIteratorHelper aIterator( *pContainer ); + + while (aIterator.hasMoreElements()) + { + // FIXME: this can be simplified as soon as the Iterator has a remove method + Reference< XInterface > xElement( aIterator.next() ); + + try + { + // this may result in a runtime exception + Reference < XDropTargetListener > xListener( xElement, UNO_QUERY ); + + if( xListener.is() ) + { + xListener->dragEnter( aEvent ); + nRet++; + } + } + + catch( RuntimeException exc ) + { + pContainer->removeInterface( xElement ); + } + } + } + + return nRet; +} + +//================================================================================================== +// DNDListenerContainer::fireDropActionChangedEvent +//================================================================================================== + +sal_uInt32 DNDListenerContainer::fireDropActionChangedEvent( const Reference< XDropTargetDragContext >& context, + const sal_Int8 dropAction, const Point& location, const sal_Int8 sourceActions ) +{ + sal_uInt32 nRet = 0; + + // fire DropTargetDropEvent on all XDropTargetListeners + OInterfaceContainerHelper *pContainer = rBHelper.getContainer( getCppuType( ( Reference < XDropTargetListener > * ) 0) ); + + if( pContainer ) + { + // do not construct the event before you are sure at least one listener is registered + DropTargetDragEvent aEvent( static_cast < XDropTarget * > (this), 0, context, dropAction, location, sourceActions ); + OInterfaceIteratorHelper aIterator( *pContainer ); + + while (aIterator.hasMoreElements()) + { + // FIXME: this can be simplified as soon as the Iterator has a remove method + Reference< XInterface > xElement( aIterator.next() ); + + try + { + // this may result in a runtime exception + Reference < XDropTargetListener > xListener( xElement, UNO_QUERY ); + + if( xListener.is() ) + { + xListener->dropActionChanged( aEvent ); + nRet++; + } + } + + catch( RuntimeException exc ) + { + pContainer->removeInterface( xElement ); + } + } + } + + return nRet; +} + +//================================================================================================== +// DNDListenerContainer::fireDragGestureEvent +//================================================================================================== + +sal_uInt32 DNDListenerContainer::fireDragGestureEvent( const sal_Int8 dragAction, const Point& dragOrigin, + const Reference< XDragSource >& dragSource, const Any& triggerEvent ) +{ + sal_uInt32 nRet = 0; + + // fire DropTargetDropEvent on all XDropTargetListeners + OInterfaceContainerHelper *pContainer = rBHelper.getContainer( getCppuType( ( Reference < XDragGestureListener > * ) 0) ); + + if( pContainer ) + { + // do not construct the event before you are sure at least one listener is registered + DragGestureEvent aEvent( static_cast < XDragGestureRecognizer * > (this), dragAction, dragOrigin, dragSource, triggerEvent ); + OInterfaceIteratorHelper aIterator( *pContainer ); + + while( aIterator.hasMoreElements() ) + { + // FIXME: this can be simplified as soon as the Iterator has a remove method + Reference< XInterface > xElement( aIterator.next() ); + + try + { + // this may result in a runtime exception + Reference < XDragGestureListener > xListener( xElement, UNO_QUERY ); + + if( xListener.is() ) + { + xListener->dragGestureRecognized( aEvent ); + nRet++; + } + } + + catch( RuntimeException exc ) + { + pContainer->removeInterface( xElement ); + } + } + } + + return nRet; +} diff --git a/vcl/source/window/dndlcon.hxx b/vcl/source/window/dndlcon.hxx new file mode 100644 index 000000000000..024c87bc90ad --- /dev/null +++ b/vcl/source/window/dndlcon.hxx @@ -0,0 +1,144 @@ +/************************************************************************* + * + * $RCSfile: dndlcon.hxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: obr $ $Date: 2001-02-05 09:45:05 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source 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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _DNDLCON_HXX_ +#define _DNDLCON_HXX_ + +#ifndef _COM_SUN_STAR_DATATRANSFER_DND_XDRAGGESTURERECOGNIZER_HPP_ +#include <com/sun/star/datatransfer/dnd/XDragGestureRecognizer.hpp> +#endif + +#ifndef _COM_SUN_STAR_DATATRANSFER_DND_XDRAGSOURCE_HPP_ +#include <com/sun/star/datatransfer/dnd/XDragSource.hpp> +#endif + +#ifndef _COM_SUN_STAR_DATATRANSFER_DND_XDROPTARGET_HPP_ +#include <com/sun/star/datatransfer/dnd/XDropTarget.hpp> +#endif + +#ifndef _CPPUHELPER_COMPBASE2_HXX_ +#include <cppuhelper/compbase2.hxx> +#endif + +class DNDListenerContainer : public ::cppu::WeakComponentImplHelper2< + ::com::sun::star::datatransfer::dnd::XDragGestureRecognizer, \ + ::com::sun::star::datatransfer::dnd::XDropTarget > +{ + ::osl::Mutex m_aMutex; + + sal_Bool m_bActive; + sal_Int8 m_nDefaultActions; + +public: + + DNDListenerContainer(); + virtual ~DNDListenerContainer(); + + sal_uInt32 fireDropEvent( + const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDropTargetDropContext >& context, + const sal_Int8 dropAction, const ::com::sun::star::awt::Point& location, const sal_Int8 sourceActions, + const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable >& transferable ); + + sal_uInt32 fireDragExitEvent(); + + sal_uInt32 fireDragOverEvent( + const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDropTargetDragContext >& context, + const sal_Int8 dropAction, const ::com::sun::star::awt::Point& location, const sal_Int8 sourceActions ); + + sal_uInt32 fireDragEnterEvent( + const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDropTargetDragContext >& context, + const sal_Int8 dropAction, const ::com::sun::star::awt::Point& location, const sal_Int8 sourceActions ); + + sal_uInt32 fireDropActionChangedEvent( + const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDropTargetDragContext >& context, + const sal_Int8 dropAction, const ::com::sun::star::awt::Point& location, const sal_Int8 sourceActions ); + + sal_uInt32 fireDragGestureEvent( + const sal_Int8 dragAction, const ::com::sun::star::awt::Point& dragOrigin, + const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragSource >& dragSource, + const ::com::sun::star::uno::Any& triggerEvent ); + + /* + * XDragGestureRecognizer + */ + + virtual void SAL_CALL addDragGestureListener( const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragGestureListener >& dgl ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeDragGestureListener( const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragGestureListener >& dgl ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL resetRecognizer( ) throw(::com::sun::star::uno::RuntimeException); + + /* + * XDropTarget + */ + + virtual void SAL_CALL addDropTargetListener( const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDropTargetListener >& dtl ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeDropTargetListener( const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDropTargetListener >& dtl ) throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isActive( ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setActive( sal_Bool active ) throw(::com::sun::star::uno::RuntimeException); + virtual sal_Int8 SAL_CALL getDefaultActions( ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setDefaultActions( sal_Int8 actions ) throw(::com::sun::star::uno::RuntimeException); +}; + + +//================================================================================================== +// +//================================================================================================== + +#endif diff --git a/vcl/source/window/makefile.mk b/vcl/source/window/makefile.mk index 43cf5afbe073..0d1098146286 100644 --- a/vcl/source/window/makefile.mk +++ b/vcl/source/window/makefile.mk @@ -2,9 +2,9 @@ # # $RCSfile: makefile.mk,v $ # -# $Revision: 1.2 $ +# $Revision: 1.3 $ # -# last change: $Author: th $ $Date: 2000-11-03 09:05:08 $ +# last change: $Author: obr $ $Date: 2001-02-05 09:45:05 $ # # The Contents of this file are made available subject to the terms of # either of the following licenses @@ -105,7 +105,9 @@ SLOFILES= $(SLO)$/accel.obj \ $(SLO)$/window2.obj \ $(SLO)$/winproc.obj \ $(SLO)$/wrkwin.obj \ - $(SLO)$/scrwnd.obj + $(SLO)$/scrwnd.obj \ + $(SLO)$/dndevdis.obj \ + $(SLO)$/dndlcon.obj .IF "$(remote)"!="" EXCEPTIONSFILES= \ @@ -127,10 +129,15 @@ EXCEPTIONSFILES= \ $(SLO)$/tabpage.obj \ $(SLO)$/toolbox.obj \ $(SLO)$/toolbox2.obj \ - $(SLO)$/dialog.obj + $(SLO)$/dialog.obj \ + $(SLO)$/dndevdis.obj \ + $(SLO)$/dndlcon.obj .ELSE EXCEPTIONSFILES= \ - $(SLO)$/window.obj + $(SLO)$/window.obj \ + $(SLO)$/syswin.obj \ + $(SLO)$/dndevdis.obj \ + $(SLO)$/dndlcon.obj .ENDIF # --- Targets ------------------------------------------------------ diff --git a/vcl/source/window/syswin.cxx b/vcl/source/window/syswin.cxx index 9eb9c5b06ce1..097ac1ca132f 100644 --- a/vcl/source/window/syswin.cxx +++ b/vcl/source/window/syswin.cxx @@ -2,9 +2,9 @@ * * $RCSfile: syswin.cxx,v $ * - * $Revision: 1.2 $ + * $Revision: 1.3 $ * - * last change: $Author: th $ $Date: 2000-11-24 18:50:30 $ + * last change: $Author: obr $ $Date: 2001-02-05 09:45:05 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -103,12 +103,30 @@ #endif #include <unowrap.hxx> +#include <dndevdis.hxx> #ifdef REMOTE_APPSERVER #include "rmwindow.hxx" #endif +#ifndef _COMPHELPER_PROCESSFACTORY_HXX_ +#include <comphelper/processfactory.hxx> +#endif +#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_ +#include <com/sun/star/lang/XComponent.hpp> +#endif +#ifndef _COM_SUN_STAR_DATATRANSFER_DND_XDRAGSOURCE_HPP_ +#include <com/sun/star/datatransfer/dnd/XDragSource.hpp> +#endif +#ifndef _COM_SUN_STAR_DATATRANSFER_DND_XDROPTARGETFACTORY_HPP_ +#include <com/sun/star/datatransfer/dnd/XDropTargetFactory.hpp> +#endif + #pragma hdrstop +using namespace rtl; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::datatransfer::dnd; // ======================================================================= @@ -125,6 +143,62 @@ SystemWindow::SystemWindow( WindowType nType ) : mbDockBtn = FALSE; mbHideBtn = FALSE; mnMenuBarMode = MENUBAR_MODE_NORMAL; + + try { +#ifdef REMOTE_APPSERVER + // Reference< XMultiServiceFactory > xFactory; + +#else + + Reference< XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory(); + if ( xFactory.is() ) + { + Sequence< sal_Int8 > windowId( 4 ); + + /* + * IMHO this belongs in the platform dependend part of vcl, but the vcl guys say it + * is better to implement it here to reduce dependencies on the other ports like Mac etc. + */ + + const SystemEnvData * pEnvData = GetSystemData(); + if( pEnvData ) + { + Reference< XInterface > xInstance; + +#if defined WNT + xInstance = xFactory->createInstance( OUString::createFromAscii( "com.sun.star.datatransfer.dnd.OleDragAndDrop" ) ); + * ( reinterpret_cast < HWND * > ( windowId.getArray() ) ) = pEnvData->hWnd; +#elif defined UNX + xInstance = xFactory->createInstance( OUString::createFromAscii( "com.sun.star.datatransfer.dnd.X11DragAndDrop" ) ); + * ( reinterpret_cast < long * > ( windowId.getArray() ) ) = pEnvData->aWindow; +#endif + + // FIXME: add service names for macos etc. here + + // remember drag source + mxDragSource = Reference< XDragSource >( xInstance, UNO_QUERY ); + + // create drop target + Reference< XDropTargetFactory > xDropTargetFactory( xInstance, UNO_QUERY ); + if( xDropTargetFactory.is() ) + { + mxDropTarget = xDropTargetFactory->createDropTarget( windowId ); + } + } + } +#endif + + if( mxDropTarget.is() ) + mxDropTarget->addDropTargetListener( new DNDEventDispatcher( this ) ); + } + + // createInstance can throw any exception + catch( Exception exc ) + { + // release all instances + mxDropTarget.clear(); + mxDragSource.clear(); + } } // ----------------------------------------------------------------------- @@ -152,6 +226,14 @@ long SystemWindow::Notify( NotifyEvent& rNEvt ) BOOL SystemWindow::Close() { + // shutdown drag and drop for this window + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > xComponent( mxDropTarget, ::com::sun::star::uno::UNO_QUERY ); + + // DNDEventDispatcher does not hold a reference of the DropTarget, + // so it's ok if it does not support XComponent + if( xComponent.is() ) + xComponent->dispose(); + if ( mxWindowPeer.is() ) { // #76482# This window can be destroyed in WindowEvent_Close. diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx index d70beb6c4095..b9d601a63f8f 100644 --- a/vcl/source/window/window.cxx +++ b/vcl/source/window/window.cxx @@ -2,9 +2,9 @@ * * $RCSfile: window.cxx,v $ * - * $Revision: 1.8 $ + * $Revision: 1.9 $ * - * last change: $Author: th $ $Date: 2000-12-07 16:21:03 $ + * last change: $Author: obr $ $Date: 2001-02-05 09:45:05 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -156,6 +156,7 @@ #endif #include <unowrap.hxx> +#include <dndlcon.hxx> #pragma hdrstop @@ -3787,6 +3788,12 @@ Window::~Window() { DBG_DTOR( Window, ImplDbgCheckWindow ); + // shutdown drag and drop + ::com::sun::star::uno::Reference < ::com::sun::star::lang::XComponent > xComponent( mxDNDListenerContainer, ::com::sun::star::uno::UNO_QUERY ); + + if( xComponent.is() ) + xComponent->dispose(); + mbInDtor = TRUE; UnoWrapperBase* pWrapper = Application::GetUnoWrapper(); @@ -6498,7 +6505,7 @@ const SystemEnvData* Window::GetSystemData() const DBG_CHKTHIS( Window, ImplDbgCheckWindow ); #ifndef REMOTE_APPSERVER - return mpFrame->GetSystemData(); + return mpFrame ? mpFrame->GetSystemData() : NULL; #else return NULL; #endif @@ -6575,3 +6582,31 @@ void Window::ImplCallActivateListeners( Window *pOld ) ImplGetParent()->ImplCallActivateListeners( pOld ); } } + +// ----------------------------------------------------------------------- + +::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDropTarget > Window::GetDropTarget() +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if( ! mxDNDListenerContainer.is() ) + mxDNDListenerContainer = static_cast < ::com::sun::star::datatransfer::dnd::XDropTarget * > ( new DNDListenerContainer() ); + + // this object is located in the same process, so there will be no runtime exception + return ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDropTarget > + ( mxDNDListenerContainer, ::com::sun::star::uno::UNO_QUERY ); +} + +// ----------------------------------------------------------------------- + +::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragGestureRecognizer > Window::GetDragGestureRecognizer() +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if( ! mxDNDListenerContainer.is() ) + mxDNDListenerContainer = static_cast < ::com::sun::star::datatransfer::dnd::XDropTarget * > ( new DNDListenerContainer() ); + + // this object is located in the same process, so there will be no runtime exception + return ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragGestureRecognizer > + ( mxDNDListenerContainer, ::com::sun::star::uno::UNO_QUERY ); +} diff --git a/vcl/source/window/winproc.cxx b/vcl/source/window/winproc.cxx index e07ab77f8826..dfaea6ffff26 100644 --- a/vcl/source/window/winproc.cxx +++ b/vcl/source/window/winproc.cxx @@ -2,9 +2,9 @@ * * $RCSfile: winproc.cxx,v $ * - * $Revision: 1.7 $ + * $Revision: 1.8 $ * - * last change: $Author: th $ $Date: 2000-12-15 13:46:47 $ + * last change: $Author: obr $ $Date: 2001-02-05 09:45:05 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -144,6 +144,13 @@ #endif #undef private +#include <dndlcon.hxx> + +#ifndef _COM_SUN_STAR_DATATRANSFER_DND_XDRAGSOURCE_HPP_ +#include <com/sun/star/datatransfer/dnd/XDragSource.hpp> +#endif + + #pragma hdrstop // ======================================================================= @@ -633,6 +640,7 @@ long ImplHandleMouseEvent( Window* pWindow, USHORT nSVEvent, BOOL bMouseLeave, !(((nMouseY-nDragH) <= pMouseDownWin->mpFrameData->mnFirstMouseY) && ((nMouseY+nDragH) >= pMouseDownWin->mpFrameData->mnFirstMouseY)) ) { +#if 1 pMouseDownWin->mpFrameData->mbStartDragCalled = TRUE; Point aCmdMousePos( pMouseDownWin->mpFrameData->mnFirstMouseX, pMouseDownWin->mpFrameData->mnFirstMouseY ); @@ -646,6 +654,30 @@ long ImplHandleMouseEvent( Window* pWindow, USHORT nSVEvent, BOOL bMouseLeave, if ( aDelData.IsDelete() ) return 1; pMouseDownWin->ImplRemoveDel( &aDelData ); +#else + pMouseDownWin->mpFrameData->mbStartDragCalled = TRUE; + + // query DropTarget from child window + ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragGestureRecognizer > xDragGestureRecognizer = + pMouseDownWin->GetDragGestureRecognizer(); + + if( xDragGestureRecognizer.is() ) + { + // retrieve mouse position relative to mouse down window + Point relLoc = pMouseDownWin->ImplFrameToOutput( Point( + pMouseDownWin->mpFrameData->mnFirstMouseX, + pMouseDownWin->mpFrameData->mnFirstMouseX ) ); + + // FIXME: where do I get Action from ? + // FIXME: Fill any with data. + + // fire...Event returns the number of listeners found + static_cast < DNDListenerContainer * > ( xDragGestureRecognizer.get() )->fireDragGestureEvent( 0, + ::com::sun::star::awt::Point( relLoc.X(), relLoc.Y() ), + pMouseDownWin->GetSystemWindow()->mxDragSource, + ::com::sun::star::uno::Any() ); + } +#endif } } } |