diff options
Diffstat (limited to 'dtrans/source/win32/dnd')
-rw-r--r-- | dtrans/source/win32/dnd/dnd.xml | 46 | ||||
-rw-r--r-- | dtrans/source/win32/dnd/dndentry.cxx | 153 | ||||
-rw-r--r-- | dtrans/source/win32/dnd/exports.dxp | 3 | ||||
-rw-r--r-- | dtrans/source/win32/dnd/globals.cxx | 139 | ||||
-rw-r--r-- | dtrans/source/win32/dnd/globals.hxx | 94 | ||||
-rw-r--r-- | dtrans/source/win32/dnd/idroptarget.cxx | 114 | ||||
-rw-r--r-- | dtrans/source/win32/dnd/idroptarget.hxx | 74 | ||||
-rw-r--r-- | dtrans/source/win32/dnd/makefile.mk | 66 | ||||
-rw-r--r-- | dtrans/source/win32/dnd/source.cxx | 431 | ||||
-rw-r--r-- | dtrans/source/win32/dnd/source.hxx | 151 | ||||
-rw-r--r-- | dtrans/source/win32/dnd/sourcecontext.cxx | 156 | ||||
-rw-r--r-- | dtrans/source/win32/dnd/sourcecontext.hxx | 89 | ||||
-rw-r--r-- | dtrans/source/win32/dnd/target.cxx | 661 | ||||
-rw-r--r-- | dtrans/source/win32/dnd/target.hxx | 213 | ||||
-rw-r--r-- | dtrans/source/win32/dnd/targetdragcontext.cxx | 59 | ||||
-rw-r--r-- | dtrans/source/win32/dnd/targetdragcontext.hxx | 62 | ||||
-rw-r--r-- | dtrans/source/win32/dnd/targetdropcontext.cxx | 69 | ||||
-rw-r--r-- | dtrans/source/win32/dnd/targetdropcontext.hxx | 72 |
18 files changed, 2652 insertions, 0 deletions
diff --git a/dtrans/source/win32/dnd/dnd.xml b/dtrans/source/win32/dnd/dnd.xml new file mode 100644 index 000000000000..10db2ddb2326 --- /dev/null +++ b/dtrans/source/win32/dnd/dnd.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd"> +<module-description xmlns:xlink="http://www.w3.org/1999/xlink"> + <module-name> dnd </module-name> + <component-description> + <author> Joachim Lingner </author> + <name> com.sun.star.comp.datatransfer.dnd.OleDragAndDrop </name> + <description> + The win32 implementation of the drop target service. +</description> + <loader-name> com.sun.star.loader.SharedLibrary </loader-name> + <language> c++ </language> + <status value="beta"/> + <supported-service> com.sun.star.datatransfer.dnd.OleDragSource</supported-service> + <supported-service> com.sun.star.datatransfer.dnd.OleDropTarget</supported-service> + <service-dependency> ... </service-dependency> + <type> com.sun.star.datatransfer.dnd.DNDConstants </type> + <type> com.sun.star.datatransfer.dnd.XDropTarget </type> + <type> com.sun.star.datatransfer.dnd.XDropTargetDragContext </type> + <type> com.sun.star.datatransfer.dnd.XDropTargetListener </type> + <type> com.sun.star.datatransfer.dnd.XDropTargetDropContext </type> + <type> com.sun.star.datatransfer.dnd.XDragSourceContext </type> + <type> com.sun.star.datatransfer.dnd.XDragSource </type> + <type> com.sun.star.datatransfer.XTransferable </type> + <type> com.sun.star.lang.XComponent </type> + <type> com.sun.star.lang.XMultiServiceFactory </type> + <type> com.sun.star.lang.XSingleServiceFactory </type> + <type> com.sun.star.lang.XServiceInfo </type> + <type> com.sun.star.lang.XTypeProvider </type> + <type> com.sun.star.lang.IllegalArgumentException </type> + <type> com.sun.star.lang.XInitialization </type> + <type> com.sun.star.lang.XUnoTunnel </type> + <type> com.sun.star.uno.TypeClass </type> + <type> com.sun.star.uno.XWeak </type> + <type> com.sun.star.uno.XAggregation </type> + <type> com.sun.star.registry.XRegistryKey </type> + <type> com.sun.star.awt.MouseButton </type> + <type> com.sun.star.awt.MouseEvent </type> + </component-description> + <project-build-dependency> cppuhelper </project-build-dependency> + <project-build-dependency> cppu </project-build-dependency> + <project-build-dependency> sal </project-build-dependency> + <runtime-module-dependency> cppuhelper </runtime-module-dependency> + <runtime-module-dependency> cppu2 </runtime-module-dependency> + <runtime-module-dependency> sal2 </runtime-module-dependency> +</module-description> diff --git a/dtrans/source/win32/dnd/dndentry.cxx b/dtrans/source/win32/dnd/dndentry.cxx new file mode 100644 index 000000000000..2ea9b7746def --- /dev/null +++ b/dtrans/source/win32/dnd/dndentry.cxx @@ -0,0 +1,153 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" +#include <cppuhelper/factory.hxx> +#include <com/sun/star/container/XSet.hpp> +#include <osl/diagnose.h> + +#include "source.hxx" +#include "target.hxx" + +using namespace ::rtl ; +using namespace ::com::sun::star::uno ; +using namespace ::com::sun::star::registry ; +using namespace ::cppu ; +using namespace ::com::sun::star::lang; + +rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT; + +Reference< XInterface > SAL_CALL createDragSource( const Reference< XMultiServiceFactory >& rServiceManager ) +{ + DragSource* pSource= new DragSource( rServiceManager ); + return Reference<XInterface>( static_cast<XInitialization*>(pSource), UNO_QUERY); +} + +Reference< XInterface > SAL_CALL createDropTarget( const Reference< XMultiServiceFactory >& rServiceManager ) +{ + DropTarget* pTarget= new DropTarget( rServiceManager ); + return Reference<XInterface>( static_cast<XInitialization*>(pTarget), UNO_QUERY); +} + + +extern "C" +{ +sal_Bool SAL_CALL component_canUnload( TimeValue *pTime ) +{ + return g_moduleCount.canUnload( &g_moduleCount , pTime ); +} + +//---------------------------------------------------------------------- +// component_getImplementationEnvironment +//---------------------------------------------------------------------- + +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} + +//------------------------------------------------------------------------- +// component_writeInfo - to register a UNO-Service +// to register a UNO-Service use: regcomp -register -r *.rdb -c *.dll +// to view the registry use: regview *.rdb /SERVICES/ServiceName +// (you must use the full services name e.g. com.sun.star.frame.FilePicker +//------------------------------------------------------------------------- + +sal_Bool SAL_CALL component_writeInfo( void* /*pServiceManager*/, void* pRegistryKey ) +{ + sal_Bool bRetVal = sal_False; + + if ( pRegistryKey ) + { + try + { + Reference< XRegistryKey > pXNewKey( static_cast< XRegistryKey* >( pRegistryKey ) ); + pXNewKey->createKey( OUString( RTL_CONSTASCII_USTRINGPARAM( DNDSOURCE_REGKEY_NAME ) ) ); + bRetVal = sal_True; + + pXNewKey= static_cast< XRegistryKey* >( pRegistryKey ); + pXNewKey->createKey( OUString( RTL_CONSTASCII_USTRINGPARAM( DNDTARGET_REGKEY_NAME ) ) ); + bRetVal = sal_True; + } + catch( InvalidRegistryException& ) + { + OSL_ENSURE(sal_False, "InvalidRegistryException caught"); + bRetVal = sal_False; + } + } + + return bRetVal; +} + +//---------------------------------------------------------------------- +// component_getFactory +// returns a factory to create XFilePicker-Services +//---------------------------------------------------------------------- + +void* SAL_CALL component_getFactory( const sal_Char* pImplName, uno_Interface* pSrvManager, uno_Interface* /*pRegistryKey*/ ) +{ + void* pRet = 0; + Reference< XSingleServiceFactory > xFactory; + + if ( pSrvManager && ( 0 == rtl_str_compare( pImplName, DNDSOURCE_IMPL_NAME ) ) ) + { + Sequence< OUString > aSNS( 1 ); + aSNS.getArray( )[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( DNDSOURCE_SERVICE_NAME ) ); + + xFactory= createSingleFactory( + reinterpret_cast< XMultiServiceFactory* > ( pSrvManager ), + OUString::createFromAscii( pImplName ), + createDragSource, + aSNS, + &g_moduleCount.modCnt); + + } + else if( pSrvManager && ( 0 == rtl_str_compare( pImplName, DNDTARGET_IMPL_NAME ) ) ) + { + Sequence< OUString > aSNS( 1 ); + aSNS.getArray( )[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( DNDTARGET_SERVICE_NAME ) ); + + xFactory= createSingleFactory( + reinterpret_cast< XMultiServiceFactory* > ( pSrvManager ), + OUString::createFromAscii( pImplName ), + createDropTarget, + aSNS); + + } + + if ( xFactory.is() ) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + + return pRet; +} + +} // extern "C" diff --git a/dtrans/source/win32/dnd/exports.dxp b/dtrans/source/win32/dnd/exports.dxp new file mode 100644 index 000000000000..028ac4175990 --- /dev/null +++ b/dtrans/source/win32/dnd/exports.dxp @@ -0,0 +1,3 @@ +component_getImplementationEnvironment +component_writeInfo +component_getFactory diff --git a/dtrans/source/win32/dnd/globals.cxx b/dtrans/source/win32/dnd/globals.cxx new file mode 100644 index 000000000000..9c6bdba5c024 --- /dev/null +++ b/dtrans/source/win32/dnd/globals.cxx @@ -0,0 +1,139 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" +#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp> + +#include "globals.hxx" + +//--> TRA +#include <com/sun/star/datatransfer/XTransferable.hpp> + +// used as shortcut when drag-source and drop-target are the same +::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable > g_XTransferable; + +//<-- TRA + +using namespace com::sun::star::datatransfer::dnd::DNDConstants; + +sal_Int8 dndOleKeysToAction( DWORD grfKeyState, sal_Int8 nSourceActions) +{ + sal_Int8 ret= 0; + + // no MK_ALT, MK_CONTROL, MK_SHIFT + if( !(grfKeyState & MK_CONTROL) && + !(grfKeyState & MK_ALT) && + !(grfKeyState & MK_RBUTTON) && + !(grfKeyState & MK_SHIFT)) + { + if( nSourceActions & ACTION_MOVE ) + { + ret= ACTION_DEFAULT | ACTION_MOVE; + } + + else if( nSourceActions & ACTION_COPY ) + { + ret= ACTION_COPY; + } + + else if( nSourceActions & ACTION_LINK ) + { + ret= ACTION_LINK; + } + + else + ret = 0; + } + else if( grfKeyState & MK_SHIFT && + !(grfKeyState & MK_CONTROL)) + { + ret= ACTION_MOVE; + } + else if ( grfKeyState & MK_CONTROL && + !(grfKeyState & MK_SHIFT) ) + { + ret= ACTION_COPY; + } + else if ( grfKeyState & MK_CONTROL && + grfKeyState & MK_SHIFT) + { + ret= ACTION_LINK; + } + else if ( grfKeyState & MK_RBUTTON | + grfKeyState & MK_ALT) + { + ret= ACTION_COPY_OR_MOVE | ACTION_LINK; + } + return ret; +} + + +sal_Int8 dndOleDropEffectsToActions( DWORD dwEffect) +{ + sal_Int8 ret= ACTION_NONE; + if( dwEffect & DROPEFFECT_COPY) + ret |= ACTION_COPY; + if( dwEffect & DROPEFFECT_MOVE) + ret |= ACTION_MOVE; + if( dwEffect & DROPEFFECT_LINK) + ret |= ACTION_LINK; + + return ret; +} + +DWORD dndActionsToDropEffects( sal_Int8 actions) +{ + DWORD ret= DROPEFFECT_NONE; + if( actions & ACTION_MOVE) + ret |= DROPEFFECT_MOVE; + if( actions & ACTION_COPY) + ret |= DROPEFFECT_COPY; + if( actions & ACTION_LINK) + ret |= DROPEFFECT_LINK; + if( actions & ACTION_DEFAULT) + ret |= DROPEFFECT_COPY; + return ret; +} + +DWORD dndActionsToSingleDropEffect( sal_Int8 actions) +{ + DWORD effects= dndActionsToDropEffects( actions); + + sal_Int8 countEffect= 0; + + if( effects & DROPEFFECT_MOVE) + countEffect++; + if( effects & DROPEFFECT_COPY) + countEffect++; + if( effects & DROPEFFECT_LINK) + countEffect++; + + // DROPEFFECT_MOVE is the default effect + DWORD retVal= countEffect > 1 ? DROPEFFECT_MOVE : effects; + return retVal; +} diff --git a/dtrans/source/win32/dnd/globals.hxx b/dtrans/source/win32/dnd/globals.hxx new file mode 100644 index 000000000000..0f21d00d7371 --- /dev/null +++ b/dtrans/source/win32/dnd/globals.hxx @@ -0,0 +1,94 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _GLOBALS_HXX_ +#define _GLOBALS_HXX_ + +#ifndef _OSL_MUTEX_H_ +#include <osl/mutex.hxx> +#endif + +#if defined _MSC_VER +#pragma warning(push,1) +#endif +#include <wtypes.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif +#include <sal/types.h> + + +#define DNDSOURCE_SERVICE_NAME "com.sun.star.datatransfer.dnd.OleDragSource" +#define DNDSOURCE_IMPL_NAME "com.sun.star.comp.datatransfer.dnd.OleDragSource_V1" +#define DNDSOURCE_REGKEY_NAME "/com.sun.star.comp.datatransfer.dnd.OleDragSource_V1/UNO/SERVICES/com.sun.star.datatransfer.dnd.OleDragSource" + +#define DNDTARGET_SERVICE_NAME "com.sun.star.datatransfer.dnd.OleDropTarget" +#define DNDTARGET_IMPL_NAME "com.sun.star.comp.datatransfer.dnd.OleDropTarget_V1" +#define DNDTARGET_REGKEY_NAME "/com.sun.star.comp.datatransfer.dnd.OleDropTarget_V1/UNO/SERVICES/com.sun.star.datatransfer.dnd.OleDropTarget" + +// This maps key states as occur as parameter, e.g. in IDropTarget::DragEnter, +// IDropSource::QueryContinueDrag, to actions as are declared in +// com::sun::star::datatransfer::dnd::DNDConstants ( ACTION_MOVE etc). +// If the grfKeyState indicates the ALt or right mousebutton then the returned +// values combines all possible actions. This is because those key and button are +// used when the user expect a menu to appear when he drops. The menu then +// contains entries, such as move, copy, link, cancel. +// An odd fact is that the argument grfKeyState in IDropTarget::Drop does not +// contain mouse buttons (winnt 4 SP6). That indicates that the right mouse button +// is not considered relevant in a drag operation. Contrarily the file explorer +// gives that button a special meaning: the user has to select the effect from +// a context menu on drop. +sal_Int8 dndOleKeysToAction( DWORD grfKeyState, sal_Int8 sourceActions); + +// The function maps a windows DROPEFFECTs to actions +// ( com::sun::star::datatransfer::dnd::DNDConstants). +// The argument can be a combination of different DROPEFFECTS, +// In that case the return value is also a combination of the +// appropriate actions. +sal_Int8 dndOleDropEffectsToActions( DWORD dwEffect); + +// The function maps actions ( com::sun::star::datatransfer::dnd::DNDConstants) +// to window DROPEFFECTs. +// The argument can be a combination of different actions +// In that case the return value is also a combination of the +// appropriate DROPEFFECTS. +DWORD dndActionsToDropEffects( sal_Int8 actions); + +// If the argument constitutes only one action then it is mapped to the +// corresponding DROPEFFECT otherwise DROPEFFECT_MOVE is returned. This is +// why move is the default effect (no modifiers pressed, or right mouse button +// or Alt). +DWORD dndActionsToSingleDropEffect( sal_Int8 actions); + + + +struct MutexDummy +{ + osl::Mutex m_mutex; +}; + + +#endif diff --git a/dtrans/source/win32/dnd/idroptarget.cxx b/dtrans/source/win32/dnd/idroptarget.cxx new file mode 100644 index 000000000000..702c9a3e567e --- /dev/null +++ b/dtrans/source/win32/dnd/idroptarget.cxx @@ -0,0 +1,114 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" +#include "idroptarget.hxx" +#include <rtl/unload.h> + +#ifdef __MINGW32__ +#define __uuidof(I) IID_##I +#endif + +extern rtl_StandardModuleCount g_moduleCount; + +IDropTargetImpl::IDropTargetImpl( DropTarget& pTarget): m_nRefCount( 0), + m_rDropTarget( pTarget) +{ + g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); +} + +IDropTargetImpl::~IDropTargetImpl() +{ + g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); +} + + +//IDropTarget +HRESULT STDMETHODCALLTYPE IDropTargetImpl::QueryInterface( REFIID riid, void **ppvObject) +{ + if( !ppvObject) + return E_POINTER; + *ppvObject= NULL; + + if( riid == __uuidof( IUnknown)) + *ppvObject= static_cast<IUnknown*>( this); + else if ( riid == __uuidof( IDropTarget)) + *ppvObject= static_cast<IDropTarget*>( this); + + if(*ppvObject) + { + AddRef(); + return S_OK; + } + else + return E_NOINTERFACE; + +} + +ULONG STDMETHODCALLTYPE IDropTargetImpl::AddRef( void) +{ + return InterlockedIncrement( &m_nRefCount); +} + +ULONG STDMETHODCALLTYPE IDropTargetImpl::Release( void) +{ + LONG count= InterlockedDecrement( &m_nRefCount); + if( m_nRefCount == 0 ) + delete this; + return count; +} + +STDMETHODIMP IDropTargetImpl::DragEnter( IDataObject __RPC_FAR *pDataObj, + DWORD grfKeyState, + POINTL pt, + DWORD *pdwEffect) +{ + return m_rDropTarget.DragEnter( pDataObj, grfKeyState, + pt, pdwEffect); +} + +STDMETHODIMP IDropTargetImpl::DragOver( DWORD grfKeyState, + POINTL pt, + DWORD *pdwEffect) +{ + return m_rDropTarget.DragOver( grfKeyState, pt, pdwEffect); +} + +STDMETHODIMP IDropTargetImpl::DragLeave( void) +{ + return m_rDropTarget.DragLeave(); +} + +STDMETHODIMP IDropTargetImpl::Drop( IDataObject *pDataObj, + DWORD grfKeyState, + POINTL pt, + DWORD __RPC_FAR *pdwEffect) +{ + return m_rDropTarget.Drop( pDataObj, grfKeyState, + pt, pdwEffect); +} diff --git a/dtrans/source/win32/dnd/idroptarget.hxx b/dtrans/source/win32/dnd/idroptarget.hxx new file mode 100644 index 000000000000..dd3cbed3d893 --- /dev/null +++ b/dtrans/source/win32/dnd/idroptarget.hxx @@ -0,0 +1,74 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _IDROPTARGET_HXX_ +#define _IDROPTARGET_HXX_ + +#include "target.hxx" + +class IDropTargetImpl: public IDropTarget +{ + LONG m_nRefCount; + // Calls to IDropTarget functions are delegated to a DropTarget. + DropTarget& m_rDropTarget; + + virtual ~IDropTargetImpl(); // delete is only called by IUnknown::Release + IDropTargetImpl( const IDropTargetImpl& ); + IDropTargetImpl& operator=( const IDropTargetImpl& ); +public: + IDropTargetImpl( DropTarget& pTarget); + + // IDropTarget + virtual HRESULT STDMETHODCALLTYPE QueryInterface( + /* [in] */ REFIID riid, + /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); + + virtual ULONG STDMETHODCALLTYPE AddRef( ); + + virtual ULONG STDMETHODCALLTYPE Release( ); + + virtual HRESULT STDMETHODCALLTYPE DragEnter( + /* [unique][in] */ IDataObject __RPC_FAR *pDataObj, + /* [in] */ DWORD grfKeyState, + /* [in] */ POINTL pt, + /* [out][in] */ DWORD __RPC_FAR *pdwEffect); + + virtual HRESULT STDMETHODCALLTYPE DragOver( + /* [in] */ DWORD grfKeyState, + /* [in] */ POINTL pt, + /* [out][in] */ DWORD __RPC_FAR *pdwEffect); + + virtual HRESULT STDMETHODCALLTYPE DragLeave( ) ; + + virtual HRESULT STDMETHODCALLTYPE Drop( + /* [unique][in] */ IDataObject __RPC_FAR *pDataObj, + /* [in] */ DWORD grfKeyState, + /* [in] */ POINTL pt, + /* [out][in] */ DWORD __RPC_FAR *pdwEffect); + + +}; +#endif diff --git a/dtrans/source/win32/dnd/makefile.mk b/dtrans/source/win32/dnd/makefile.mk new file mode 100644 index 000000000000..54fd748a0889 --- /dev/null +++ b/dtrans/source/win32/dnd/makefile.mk @@ -0,0 +1,66 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=dtrans +TARGET=dnd +ENABLE_EXCEPTIONS=TRUE +COMP1TYPELIST=$(TARGET) +USE_BOUNDCHK= + +.IF "$(USE_BOUNDCHK)"=="TR" +bndchk=tr +stoponerror=tr +.ENDIF + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# ------------------------------------------------------------------ + +#CFLAGS+=-GR -DUNICODE -D_UNICODE + +#DBG_CONSOLE_OUT: when IDropTarget or IDropSource are called we write to a console +#DBG_CLIPBOARD_DATA: To provide DoDragDrop with an data object we call OleGetClipboard +#CFLAGS+= -DDBG_CONSOLE_OUT -DDBG_CLIPBOARD_DATA + + +SLOFILES= $(SLO)$/dndentry.obj \ + $(SLO)$/target.obj \ + $(SLO)$/idroptarget.obj \ + $(SLO)$/source.obj \ + $(SLO)$/globals.obj \ + $(SLO)$/targetdropcontext.obj \ + $(SLO)$/targetdragcontext.obj \ + $(SLO)$/sourcecontext.obj + + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/dtrans/source/win32/dnd/source.cxx b/dtrans/source/win32/dnd/source.cxx new file mode 100644 index 000000000000..8c05d8806601 --- /dev/null +++ b/dtrans/source/win32/dnd/source.cxx @@ -0,0 +1,431 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" +#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp> +#include <com/sun/star/datatransfer/XTransferable.hpp> +#include <com/sun/star/awt/MouseButton.hpp> +#include <com/sun/star/awt/MouseEvent.hpp> +#include <rtl/unload.h> + +#include <process.h> +#include <memory> + +#include "source.hxx" +#include "globals.hxx" +#include "sourcecontext.hxx" +#include "../../inc/DtObjFactory.hxx" +#include <rtl/ustring.h> +#include <process.h> +#include <winuser.h> +#include <stdio.h> + +#ifdef __MINGW32__ +#define __uuidof(I) IID_##I +#endif + +using namespace rtl; +using namespace cppu; +using namespace osl; +using namespace com::sun::star::datatransfer; +using namespace com::sun::star::datatransfer::dnd; +using namespace com::sun::star::datatransfer::dnd::DNDConstants; +using namespace com::sun::star::uno; +using namespace com::sun::star::awt::MouseButton; +using namespace com::sun::star::awt; +using namespace com::sun::star::lang; + +extern rtl_StandardModuleCount g_moduleCount; + +//--> TRA + +extern Reference< XTransferable > g_XTransferable; + +//<-- TRA + +unsigned __stdcall DndOleSTAFunc(LPVOID pParams); + +//---------------------------------------------------- +/** Ctor +*/ +DragSource::DragSource( const Reference<XMultiServiceFactory>& sf): + m_serviceFactory( sf), + WeakComponentImplHelper3< XDragSource, XInitialization, XServiceInfo >(m_mutex), +// m_pcurrentContext_impl(0), + m_hAppWindow(0), + m_MouseButton(0), + m_RunningDndOperationCount(0) +{ + g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); +} + +//---------------------------------------------------- +/** Dtor +*/ +DragSource::~DragSource() +{ + g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); +} + +//---------------------------------------------------- +/** First start a new drag and drop thread if + the last one has finished + + ???? + Do we really need a separate thread for + every Dnd opeartion or only if the source + thread is an MTA thread + ???? +*/ +void DragSource::StartDragImpl( + const DragGestureEvent& trigger, + sal_Int8 sourceActions, + sal_Int32 /*cursor*/, + sal_Int32 /*image*/, + const Reference<XTransferable >& trans, + const Reference<XDragSourceListener >& listener ) +{ + // The actions supported by the drag source + m_sourceActions= sourceActions; + // We need to know which mouse button triggered the operation. + // If it was the left one, then the drop occurs when that button + // has been released and if it was the right one then the drop + // occurs when the right button has been released. If the event is not + // set then we assume that the left button is pressed. + MouseEvent evtMouse; + trigger.Event >>= evtMouse; + m_MouseButton= evtMouse.Buttons; + + // The SourceContext class administers the XDragSourceListener s and + // fires events to them. An instance only exists in the scope of this + // functions. However, the drag and drop operation causes callbacks + // to the IDropSource interface implemented in this class (but only + // while this function executes). The source context is also used + // in DragSource::QueryContinueDrag. + m_currentContext= static_cast<XDragSourceContext*>( new SourceContext( + static_cast<DragSource*>(this), listener ) ); + + // Convert the XTransferable data object into an IDataObject object; + + //--> TRA + g_XTransferable = trans; + //<-- TRA + + m_spDataObject= m_aDataConverter.createDataObjFromTransferable( + m_serviceFactory, trans); + + // Obtain the id of the thread that created the window + DWORD processId; + m_threadIdWindow= GetWindowThreadProcessId( m_hAppWindow, &processId); + + // hold the instance for the DnD thread, it's to late + // to acquire at the start of the thread procedure + // the thread procedure is responsible for the release + acquire(); + + // The thread acccesses members of this instance but does not call acquire. + // Hopefully this instance is not destroyed before the thread has terminated. + unsigned threadId; + HANDLE hThread= reinterpret_cast<HANDLE>(_beginthreadex( + 0, 0, DndOleSTAFunc, reinterpret_cast<void*>(this), 0, &threadId)); + + // detach from thread + CloseHandle(hThread); +} + +// XInitialization + +//---------------------------------------------------- +/** aArguments contains a machine id +*/ +void SAL_CALL DragSource::initialize( const Sequence< Any >& aArguments ) + throw(Exception, RuntimeException) +{ + if( aArguments.getLength() >=2) + m_hAppWindow= *(HWND*)aArguments[1].getValue(); + OSL_ASSERT( IsWindow( m_hAppWindow) ); +} + +//---------------------------------------------------- +/** XDragSource +*/ +sal_Bool SAL_CALL DragSource::isDragImageSupported( ) + throw(RuntimeException) +{ + return 0; +} + +//---------------------------------------------------- +/** +*/ +sal_Int32 SAL_CALL DragSource::getDefaultCursor( sal_Int8 /*dragAction*/ ) + throw( IllegalArgumentException, RuntimeException) +{ + return 0; +} + +//---------------------------------------------------- +/** Notifies the XDragSourceListener by + calling dragDropEnd +*/ +void SAL_CALL DragSource::startDrag( + const DragGestureEvent& trigger, + sal_Int8 sourceActions, + sal_Int32 cursor, + sal_Int32 image, + const Reference<XTransferable >& trans, + const Reference<XDragSourceListener >& listener ) throw( RuntimeException) +{ + // Allow only one running dnd operation at a time, + // see XDragSource documentation + + long cnt = InterlockedIncrement(&m_RunningDndOperationCount); + + if (1 == cnt) + { + StartDragImpl(trigger, sourceActions, cursor, image, trans, listener); + } + else + { + //OSL_ENSURE(false, "Overlapping Drag&Drop operation rejected!"); + + cnt = InterlockedDecrement(&m_RunningDndOperationCount); + + DragSourceDropEvent dsde; + + dsde.DropAction = ACTION_NONE; + dsde.DropSuccess = false; + + try + { + listener->dragDropEnd(dsde); + } + catch(RuntimeException&) + { + OSL_ENSURE(false, "Runtime exception during event dispatching"); + } + } +} + +//---------------------------------------------------- +/**IDropTarget +*/ +HRESULT STDMETHODCALLTYPE DragSource::QueryInterface( REFIID riid, void **ppvObject) +{ + if( !ppvObject) + return E_POINTER; + *ppvObject= NULL; + + if( riid == __uuidof( IUnknown) ) + *ppvObject= static_cast<IUnknown*>( this); + else if ( riid == __uuidof( IDropSource) ) + *ppvObject= static_cast<IDropSource*>( this); + + if(*ppvObject) + { + AddRef(); + return S_OK; + } + else + return E_NOINTERFACE; + +} + +//---------------------------------------------------- +/** +*/ +ULONG STDMETHODCALLTYPE DragSource::AddRef( void) +{ + acquire(); + return (ULONG) m_refCount; +} + +//---------------------------------------------------- +/** +*/ +ULONG STDMETHODCALLTYPE DragSource::Release( void) +{ + ULONG ref= m_refCount; + release(); + return --ref; +} + +//---------------------------------------------------- +/** IDropSource +*/ +HRESULT STDMETHODCALLTYPE DragSource::QueryContinueDrag( +/* [in] */ BOOL fEscapePressed, +/* [in] */ DWORD grfKeyState) +{ +#if defined DBG_CONSOLE_OUT + printf("\nDragSource::QueryContinueDrag"); +#endif + + HRESULT retVal= S_OK; // default continue DnD + + if (fEscapePressed) + { + retVal= DRAGDROP_S_CANCEL; + } + else + { + if( ( m_MouseButton == MouseButton::RIGHT && !(grfKeyState & MK_RBUTTON) ) || + ( m_MouseButton == MouseButton::MIDDLE && !(grfKeyState & MK_MBUTTON) ) || + ( m_MouseButton == MouseButton::LEFT && !(grfKeyState & MK_LBUTTON) ) || + ( m_MouseButton == 0 && !(grfKeyState & MK_LBUTTON) ) ) + { + retVal= DRAGDROP_S_DROP; + } + } + + // fire dropActionChanged event. + // this is actually done by the context, which also detects whether the action + // changed at all + sal_Int8 dropAction= fEscapePressed ? ACTION_NONE : + dndOleKeysToAction( grfKeyState, m_sourceActions); + + sal_Int8 userAction= fEscapePressed ? ACTION_NONE : + dndOleKeysToAction( grfKeyState, -1 ); + + static_cast<SourceContext*>(m_currentContext.get())->fire_dropActionChanged( + dropAction, userAction); + + return retVal; +} + +//---------------------------------------------------- +/** +*/ +HRESULT STDMETHODCALLTYPE DragSource::GiveFeedback( +/* [in] */ DWORD +#if defined DBG_CONSOLE_OUT +dwEffect +#endif +) +{ +#if defined DBG_CONSOLE_OUT + printf("\nDragSource::GiveFeedback %d", dwEffect); +#endif + + return DRAGDROP_S_USEDEFAULTCURSORS; +} + +// XServiceInfo +OUString SAL_CALL DragSource::getImplementationName( ) throw (RuntimeException) +{ + return OUString(RTL_CONSTASCII_USTRINGPARAM(DNDSOURCE_IMPL_NAME));; +} +// XServiceInfo +sal_Bool SAL_CALL DragSource::supportsService( const OUString& ServiceName ) throw (RuntimeException) +{ + if( ServiceName.equals(OUString(RTL_CONSTASCII_USTRINGPARAM(DNDSOURCE_SERVICE_NAME )))) + return sal_True; + return sal_False; +} + +Sequence< OUString > SAL_CALL DragSource::getSupportedServiceNames( ) throw (RuntimeException) +{ + OUString names[1]= {OUString(RTL_CONSTASCII_USTRINGPARAM(DNDSOURCE_SERVICE_NAME))}; + + return Sequence<OUString>(names, 1); +} + +//---------------------------------------------------- +/**This function is called as extra thread from + DragSource::executeDrag. The function + carries out a drag and drop operation by calling + DoDragDrop. The thread also notifies all + XSourceListener. +*/ +unsigned __stdcall DndOleSTAFunc(LPVOID pParams) +{ + // The structure contains all arguments for DoDragDrop and other + DragSource *pSource= (DragSource*)pParams; + + // Drag and drop only works in a thread in which OleInitialize is called. + HRESULT hr= OleInitialize( NULL); + + if(SUCCEEDED(hr)) + { + // We force the creation of a thread message queue. This is necessary + // for a later call to AttachThreadInput + MSG msgtemp; + PeekMessage( &msgtemp, NULL, WM_USER, WM_USER, PM_NOREMOVE); + + DWORD threadId= GetCurrentThreadId(); + + // This thread is attached to the thread that created the window. Hence + // this thread also receives all mouse and keyboard messages which are + // needed by DoDragDrop + AttachThreadInput( threadId , pSource->m_threadIdWindow, TRUE ); + + DWORD dwEffect= 0; + hr= DoDragDrop( + pSource->m_spDataObject.get(), + static_cast<IDropSource*>(pSource), + dndActionsToDropEffects( pSource->m_sourceActions), + &dwEffect); + + // #105428 detach my message queue from the other threads + // message queue before calling fire_dragDropEnd else + // the office may appear to hang sometimes + AttachThreadInput( threadId, pSource->m_threadIdWindow, FALSE); + + //--> TRA + // clear the global transferable again + g_XTransferable = Reference< XTransferable >( ); + //<-- TRA + + OSL_ENSURE( hr != E_INVALIDARG, "IDataObject impl does not contain valid data"); + + //Fire event + sal_Int8 action= hr == DRAGDROP_S_DROP ? dndOleDropEffectsToActions( dwEffect) : ACTION_NONE; + + static_cast<SourceContext*>(pSource->m_currentContext.get())->fire_dragDropEnd( + hr == DRAGDROP_S_DROP ? sal_True : sal_False, action); + + // Destroy SourceContextslkfgj + pSource->m_currentContext= 0; + // Destroy the XTransferable wrapper + pSource->m_spDataObject=0; + + OleUninitialize(); + } + + InterlockedDecrement(&pSource->m_RunningDndOperationCount); + + // the DragSource was manually acquired by + // thread starting method DelayedStartDrag + pSource->release(); + + return 0; +} + + + + diff --git a/dtrans/source/win32/dnd/source.hxx b/dtrans/source/win32/dnd/source.hxx new file mode 100644 index 000000000000..decf3f61368f --- /dev/null +++ b/dtrans/source/win32/dnd/source.hxx @@ -0,0 +1,151 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SOURCE_HXX_ +#define _SOURCE_HXX_ + +#include <com/sun/star/datatransfer/dnd/XDragSource.hpp> +#include <com/sun/star/datatransfer/dnd/XDragSourceContext.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#ifndef _OSL_MUTEX_H_ +#include <osl/mutex.hxx> +#endif +#ifndef _CPPUHELPER_COMPBASE2_HXX_ +#include <cppuhelper/compbase3.hxx> +#endif +#include <com/sun/star/lang/XServiceInfo.hpp> +#include "../../inc/DtObjFactory.hxx" +#include "globals.hxx" +#include <oleidl.h> + +#include <systools/win32/comtools.hxx> + +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::uno; +using namespace cppu; +using namespace osl; +using namespace rtl; +using namespace ::com::sun::star::datatransfer; +using namespace ::com::sun::star::datatransfer::dnd; + + + +class SourceContext; +// RIGHT MOUSE BUTTON drag and drop not supportet currently. +// ALT modifier is considered to effect a user selection of effects +class DragSource: + public MutexDummy, + public WeakComponentImplHelper3<XDragSource, XInitialization, XServiceInfo>, + public IDropSource + +{ + Reference<XMultiServiceFactory> m_serviceFactory; + HWND m_hAppWindow; + + // The mouse button that set off the drag and drop operation + short m_MouseButton; + // Converts XTransferable objects to IDataObject objects. + CDTransObjFactory m_aDataConverter; + + DragSource(); + DragSource(const DragSource&); + DragSource &operator= ( const DragSource&); + + // First starting a new drag and drop thread if + // the last one has finished + void StartDragImpl( + const DragGestureEvent& trigger, + sal_Int8 sourceActions, + sal_Int32 cursor, + sal_Int32 image, + const Reference<XTransferable >& trans, + const Reference<XDragSourceListener >& listener); + +public: + long m_RunningDndOperationCount; + +public: + // only valid for one dnd operation + // the thread ID of the thread which created the window + DWORD m_threadIdWindow; + // The context notifies the XDragSourceListener s + Reference<XDragSourceContext> m_currentContext; + + // the wrapper for the Transferable ( startDrag) + IDataObjectPtr m_spDataObject; + + sal_Int8 m_sourceActions; + +public: + DragSource(const Reference<XMultiServiceFactory>& sf); + virtual ~DragSource(); + + // XInitialization + virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) + throw(Exception, RuntimeException); + + + // XDragSource + virtual sal_Bool SAL_CALL isDragImageSupported( ) throw(RuntimeException); + virtual sal_Int32 SAL_CALL getDefaultCursor( sal_Int8 dragAction ) + throw( IllegalArgumentException, RuntimeException); + virtual void SAL_CALL startDrag( const DragGestureEvent& trigger, + sal_Int8 sourceActions, + sal_Int32 cursor, + sal_Int32 image, + const Reference<XTransferable >& trans, + const Reference<XDragSourceListener >& listener ) + throw( RuntimeException); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName( ) throw (RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw (RuntimeException); + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw (RuntimeException); + + + + virtual HRESULT STDMETHODCALLTYPE QueryInterface( + /* [in] */ REFIID riid, + /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); + + virtual ULONG STDMETHODCALLTYPE AddRef( ); + + virtual ULONG STDMETHODCALLTYPE Release( ); + + + // IDropSource + virtual HRESULT STDMETHODCALLTYPE QueryContinueDrag( + /* [in] */ BOOL fEscapePressed, + /* [in] */ DWORD grfKeyState); + + virtual HRESULT STDMETHODCALLTYPE GiveFeedback( + /* [in] */ DWORD dwEffect); + +}; + + +#endif diff --git a/dtrans/source/win32/dnd/sourcecontext.cxx b/dtrans/source/win32/dnd/sourcecontext.cxx new file mode 100644 index 000000000000..da4d5c06eefb --- /dev/null +++ b/dtrans/source/win32/dnd/sourcecontext.cxx @@ -0,0 +1,156 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" + + +#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp> + +#include "sourcecontext.hxx" +#include <rtl/unload.h> + +using namespace com::sun::star::datatransfer::dnd; +using namespace com::sun::star::datatransfer::dnd::DNDConstants; +extern rtl_StandardModuleCount g_moduleCount; + +SourceContext::SourceContext( DragSource* pSource, + const Reference<XDragSourceListener>& listener): + WeakComponentImplHelper1<XDragSourceContext>(m_mutex), + m_pDragSource( pSource), + m_dragSource( static_cast<XDragSource*>( m_pDragSource) ) +{ + g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); +#if OSL_DEBUG_LEVEL > 1 + if( listener.is()) +#endif + rBHelper.addListener( ::getCppuType( &listener ), listener ); +} + +SourceContext::~SourceContext() +{ + g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); +} + +void SAL_CALL SourceContext::addDragSourceListener( + const Reference<XDragSourceListener >& ) + throw( RuntimeException) +{ +} + +void SAL_CALL SourceContext::removeDragSourceListener( + const Reference<XDragSourceListener >& ) + throw( RuntimeException) +{ +} + +sal_Int32 SAL_CALL SourceContext::getCurrentCursor( ) + throw( RuntimeException) +{ + return 0; +} + +void SAL_CALL SourceContext::setCursor( sal_Int32 /*cursorId*/ ) + throw( RuntimeException) +{ +} + +void SAL_CALL SourceContext::setImage( sal_Int32 /*imageId*/ ) + throw( RuntimeException) +{ +} + +void SAL_CALL SourceContext::transferablesFlavorsChanged( ) + throw( RuntimeException) +{ +} + + +// non -interface functions +// Fires XDragSourceListener::dragDropEnd events. +void SourceContext::fire_dragDropEnd( sal_Bool success, sal_Int8 effect) +{ + + DragSourceDropEvent e; + + if( success == sal_True) + { + e.DropAction= effect; + e.DropSuccess= sal_True; + } + else + { + e.DropAction= ACTION_NONE; + e.DropSuccess= sal_False; + } + e.DragSource= m_dragSource; + e.DragSourceContext= static_cast<XDragSourceContext*>( this); + e.Source= Reference<XInterface>( static_cast<XDragSourceContext*>( this), UNO_QUERY); + + OInterfaceContainerHelper* pContainer= rBHelper.getContainer( + getCppuType( (Reference<XDragSourceListener>* )0 ) ); + + if( pContainer) + { + OInterfaceIteratorHelper iter( *pContainer); + while( iter.hasMoreElements()) + { + Reference<XDragSourceListener> listener( + static_cast<XDragSourceListener*>( iter.next())); + listener->dragDropEnd( e); + } + } +} + + +void SourceContext::fire_dropActionChanged( sal_Int8 dropAction, sal_Int8 userAction) +{ + if( m_currentAction != dropAction) + { + m_currentAction= dropAction; + DragSourceDragEvent e; + e.DropAction= dropAction; + e.UserAction= userAction; + e.DragSource= m_dragSource; + e.DragSourceContext= static_cast<XDragSourceContext*>( this); + e.Source= Reference<XInterface>( static_cast<XDragSourceContext*>( this), UNO_QUERY); + + OInterfaceContainerHelper* pContainer= rBHelper.getContainer( + getCppuType( (Reference<XDragSourceListener>* )0 ) ); + + if( pContainer) + { + OInterfaceIteratorHelper iter( *pContainer); + while( iter.hasMoreElements()) + { + Reference<XDragSourceListener> listener( + static_cast<XDragSourceListener*>( iter.next())); + listener->dropActionChanged( e); + } + } + } +} diff --git a/dtrans/source/win32/dnd/sourcecontext.hxx b/dtrans/source/win32/dnd/sourcecontext.hxx new file mode 100644 index 000000000000..db3f093b21a9 --- /dev/null +++ b/dtrans/source/win32/dnd/sourcecontext.hxx @@ -0,0 +1,89 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SOURCECONTEXT_HXX_ +#define _SOURCECONTEXT_HXX_ + +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/datatransfer/dnd/XDragSourceContext.hpp> +#include <cppuhelper/compbase1.hxx> + + +#include "source.hxx" + +using namespace ::com::sun::star::datatransfer; +using namespace ::com::sun::star::datatransfer::dnd; +using namespace ::cppu; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; + + +// This class fires events to XDragSourceListener implementations. +// Of that interface only dragDropEnd and dropActionChanged are called. +// The functions dragEnter, dragExit and dragOver are not supported +// currently. +// An instance of SourceContext only lives as long as the drag and drop +// operation lasts. +class SourceContext: public MutexDummy, + public WeakComponentImplHelper1<XDragSourceContext> +{ + DragSource* m_pDragSource; + Reference<XDragSource> m_dragSource; + // the action ( copy, move etc) + sal_Int8 m_currentAction; + + SourceContext(); + SourceContext( const SourceContext&); + SourceContext &operator= (const SourceContext& ); + +public: + SourceContext( DragSource* pSource, const Reference<XDragSourceListener>& listener); + ~SourceContext(); + + virtual void SAL_CALL addDragSourceListener( const Reference<XDragSourceListener >& dsl ) + throw( RuntimeException); + virtual void SAL_CALL removeDragSourceListener( const Reference<XDragSourceListener >& dsl ) + throw( RuntimeException); + virtual sal_Int32 SAL_CALL getCurrentCursor( ) + throw( RuntimeException); + virtual void SAL_CALL setCursor( sal_Int32 cursorId ) + throw( RuntimeException); + virtual void SAL_CALL setImage( sal_Int32 imageId ) + throw( RuntimeException); + virtual void SAL_CALL transferablesFlavorsChanged( ) + throw( RuntimeException); + + + + // non - interface functions + void fire_dragDropEnd( sal_Bool success, sal_Int8 byte); + void fire_dropActionChanged( sal_Int8 dropAction, sal_Int8 userAction); + +}; + + + +#endif diff --git a/dtrans/source/win32/dnd/target.cxx b/dtrans/source/win32/dnd/target.cxx new file mode 100644 index 000000000000..6e2e28bcfc39 --- /dev/null +++ b/dtrans/source/win32/dnd/target.cxx @@ -0,0 +1,661 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" +#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp> +#include <com/sun/star/datatransfer/XTransferable.hpp> +#include <rtl/unload.h> + +#include <stdio.h> +#include "target.hxx" +#include "idroptarget.hxx" +#include "globals.hxx" +#include "targetdropcontext.hxx" +#include "targetdragcontext.hxx" +#include <rtl/ustring.h> +using namespace rtl; +using namespace cppu; +using namespace osl; +using namespace com::sun::star::datatransfer; +using namespace com::sun::star::datatransfer::dnd; +using namespace com::sun::star::datatransfer::dnd::DNDConstants; + +#define WM_REGISTERDRAGDROP WM_USER + 1 +#define WM_REVOKEDRAGDROP WM_USER + 2 +//--> TRA +extern Reference< XTransferable > g_XTransferable; + +//<-- TRA + +extern rtl_StandardModuleCount g_moduleCount; +DWORD WINAPI DndTargetOleSTAFunc(LPVOID pParams); + +DropTarget::DropTarget( const Reference<XMultiServiceFactory>& sf): + m_hWnd( NULL), + m_serviceFactory( sf), + WeakComponentImplHelper3<XInitialization,XDropTarget, XServiceInfo>(m_mutex), + m_bActive(sal_True), + m_nDefaultActions(ACTION_COPY|ACTION_MOVE|ACTION_LINK|ACTION_DEFAULT), + m_nCurrentDropAction( ACTION_NONE), + m_oleThreadId( 0), + m_pDropTarget( NULL), + m_threadIdWindow(0), + m_threadIdTarget(0), + m_hOleThread(0), + m_nLastDropAction(0) + + +{ + g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); +} + + +DropTarget::~DropTarget() +{ + g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); + +} +// called from WeakComponentImplHelperX::dispose +// WeakComponentImplHelper calls disposing before it destroys +// itself. +// NOTE: RevokeDragDrop decrements the ref count on the IDropTarget +// interface. (m_pDropTarget) +// If the HWND is invalid then it doesn't decrement and +// the IDropTarget object will live on. MEMORY LEAK +void SAL_CALL DropTarget::disposing() +{ + HRESULT hr= S_OK; + if( m_threadIdTarget) + { + // Call RevokeDragDrop and wait for the OLE thread to die; + PostThreadMessage( m_threadIdTarget, WM_REVOKEDRAGDROP, (WPARAM)this, 0); + WaitForSingleObject( m_hOleThread, INFINITE); + CloseHandle( m_hOleThread); + //OSL_ENSURE( SUCCEEDED( hr), "HWND not valid!" ); + } + else + { + hr= RevokeDragDrop( m_hWnd); + m_hWnd= 0; + } + if( m_pDropTarget) + { + CoLockObjectExternal( m_pDropTarget, FALSE, TRUE); + m_pDropTarget->Release(); + } + + if( m_oleThreadId) + { + if( m_oleThreadId == CoGetCurrentProcess() ) + OleUninitialize(); + } + +} + +void SAL_CALL DropTarget::initialize( const Sequence< Any >& aArguments ) + throw(Exception, RuntimeException) +{ + // The window must be registered for Dnd by RegisterDragDrop. We must ensure + // that RegisterDragDrop is called from an STA ( OleInitialize) thread. + // As long as the window is registered we need to receive OLE messages in + // an OLE thread. That is to say, if DropTarget::initialize was called from an + // MTA thread then we create an OLE thread in which the window is registered. + // The thread will stay alive until aver RevokeDragDrop has been called. + + // Additionally even if RegisterDragDrop is called from an STA thread we have + // to ensure that it is called from the same thread that created the Window + // otherwise meesages sent during DND won't reach the windows message queue. + // Calling AttachThreadInput first would resolve this problem but would block + // the message queue of the calling thread. So if the current thread + // (even if it's an STA thread) and the thread that created the window are not + // identical we need to create a new thread as we do when the calling thread is + // an MTA thread. + + if( aArguments.getLength() > 0) + { + // Get the window handle from aArgument. It is needed for RegisterDragDrop. + m_hWnd= *(HWND*)aArguments[0].getValue(); + OSL_ASSERT( IsWindow( m_hWnd) ); + + // Obtain the id of the thread that created the window + m_threadIdWindow= GetWindowThreadProcessId( m_hWnd, NULL); + + HRESULT hr= OleInitialize( NULL); + + // Current thread is MTA or Current thread and Window thread are not identical + if( hr == RPC_E_CHANGED_MODE || GetCurrentThreadId() != m_threadIdWindow ) + { + OSL_ENSURE( ! m_threadIdTarget,"initialize was called twice"); + // create the IDropTargetImplementation + m_pDropTarget= new IDropTargetImpl( *static_cast<DropTarget*>( this) ); + m_pDropTarget->AddRef(); + + + // Obtain the id of the thread that created the window + m_threadIdWindow= GetWindowThreadProcessId( m_hWnd, NULL); + // The event is set by the thread that we will create momentarily. + // It indicates that the thread is ready to receive messages. + HANDLE m_evtThreadReady= CreateEvent( NULL, FALSE, FALSE, NULL); + + m_hOleThread= CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)DndTargetOleSTAFunc, + &m_evtThreadReady, 0, &m_threadIdTarget); + WaitForSingleObject( m_evtThreadReady, INFINITE); + CloseHandle( m_evtThreadReady); + PostThreadMessage( m_threadIdTarget, WM_REGISTERDRAGDROP, (WPARAM)static_cast<DropTarget*>(this), 0); + } + else if( hr == S_OK || hr == S_FALSE) + { + // current thread is STA + // If OleInitialize has been called by the caller then we must not call + // OleUninitialize + if( hr == S_OK) + { + // caller did not call OleInitialize, so we call OleUninitialize + // remember the thread that will call OleUninitialize + m_oleThreadId= CoGetCurrentProcess(); // get a unique thread id + } + + // Get the window handle from aArgument. It is needed for RegisterDragDrop. + // create the IDropTargetImplementation + m_pDropTarget= new IDropTargetImpl( *static_cast<DropTarget*>( this) ); + m_pDropTarget->AddRef(); + // CoLockObjectExternal is prescribed by the protocol. It bumps up the ref count + if( SUCCEEDED( CoLockObjectExternal( m_pDropTarget, TRUE, FALSE))) + { + if( FAILED( RegisterDragDrop( m_hWnd, m_pDropTarget) ) ) + { + // do clean up if drag and drop is not possible + CoLockObjectExternal( m_pDropTarget, FALSE, FALSE); + m_pDropTarget->Release(); + m_hWnd= NULL; + } + } + } + else + throw Exception(); + + } +} + +// This function is called as extra thread from DragSource::startDrag. +// The function carries out a drag and drop operation by calling +// DoDragDrop. The thread also notifies all XSourceListener. +DWORD WINAPI DndTargetOleSTAFunc(LPVOID pParams) +{ + HRESULT hr= OleInitialize( NULL); + if( SUCCEEDED( hr) ) + { + MSG msg; + // force the creation of a message queue + PeekMessage( &msg, (HWND)NULL, 0, 0, PM_NOREMOVE); + // Signal the creator ( DropTarget::initialize) that the thread is + // ready to receive messages. + SetEvent( *(HANDLE*) pParams); + // Thread id is needed for attaching this message queue to the one of the + // thread where the window was created. + DWORD threadId= GetCurrentThreadId(); + // We force the creation of a thread message queue. This is necessary + // for a later call to AttachThreadInput + while( GetMessage(&msg, (HWND)NULL, 0, 0) ) + { + if( msg.message == WM_REGISTERDRAGDROP) + { + DropTarget *pTarget= (DropTarget*)msg.wParam; + // This thread is attached to the thread that created the window. Hence + // this thread also receives all mouse and keyboard messages which are + // needed + AttachThreadInput( threadId , pTarget->m_threadIdWindow, TRUE ); + + if( SUCCEEDED( CoLockObjectExternal(pTarget-> m_pDropTarget, TRUE, FALSE))) + { + if( FAILED( RegisterDragDrop( pTarget-> m_hWnd, pTarget-> m_pDropTarget) ) ) + { + // do clean up if drag and drop is not possible + CoLockObjectExternal( pTarget->m_pDropTarget, FALSE, FALSE); + pTarget->m_pDropTarget->Release(); + pTarget->m_hWnd= NULL; + } + } + } + else if( msg.message == WM_REVOKEDRAGDROP) + { + DropTarget *pTarget= (DropTarget*)msg.wParam; + RevokeDragDrop( pTarget-> m_hWnd); + // Detach this thread from the window thread + AttachThreadInput( threadId, pTarget->m_threadIdWindow, FALSE); + pTarget->m_hWnd= 0; + break; + } + TranslateMessage( &msg); + DispatchMessage( &msg); + } + OleUninitialize(); + } + return 0; +} + + + + +// XServiceInfo +OUString SAL_CALL DropTarget::getImplementationName( ) throw (RuntimeException) +{ + return OUString(RTL_CONSTASCII_USTRINGPARAM(DNDTARGET_IMPL_NAME));; +} +// XServiceInfo +sal_Bool SAL_CALL DropTarget::supportsService( const OUString& ServiceName ) throw (RuntimeException) +{ + if( ServiceName.equals(OUString(RTL_CONSTASCII_USTRINGPARAM(DNDTARGET_SERVICE_NAME )))) + return sal_True; + return sal_False; +} + +Sequence< OUString > SAL_CALL DropTarget::getSupportedServiceNames( ) throw (RuntimeException) +{ + OUString names[1]= {OUString(RTL_CONSTASCII_USTRINGPARAM(DNDTARGET_SERVICE_NAME))}; + return Sequence<OUString>(names, 1); +} + + +// XDropTarget ---------------------------------------------------------------- +void SAL_CALL DropTarget::addDropTargetListener( const Reference< XDropTargetListener >& dtl ) + throw(RuntimeException) +{ + rBHelper.addListener( ::getCppuType( &dtl ), dtl ); +} + +void SAL_CALL DropTarget::removeDropTargetListener( const Reference< XDropTargetListener >& dtl ) + throw(RuntimeException) +{ + rBHelper.removeListener( ::getCppuType( &dtl ), dtl ); +} + +sal_Bool SAL_CALL DropTarget::isActive( ) throw(RuntimeException) +{ + return m_bActive; //m_bDropTargetRegistered; +} + + +void SAL_CALL DropTarget::setActive( sal_Bool _b ) throw(RuntimeException) +{ + MutexGuard g(m_mutex); + m_bActive= _b; +} + + +sal_Int8 SAL_CALL DropTarget::getDefaultActions( ) throw(RuntimeException) +{ + return m_nDefaultActions; +} + +void SAL_CALL DropTarget::setDefaultActions( sal_Int8 actions ) throw(RuntimeException) +{ + OSL_ENSURE( actions < 8, "No valid default actions"); + m_nDefaultActions= actions; +} + + +HRESULT DropTarget::DragEnter( IDataObject *pDataObj, + DWORD grfKeyState, + POINTL pt, + DWORD *pdwEffect) +{ +#if defined DBG_CONSOLE_OUT + printf("\nDropTarget::DragEnter state: %x effect %d", grfKeyState, *pdwEffect); +#endif + if( m_bActive ) + { + // Intersection of pdwEffect and the allowed actions ( setDefaultActions) + m_nCurrentDropAction= getFilteredActions( grfKeyState, *pdwEffect); + // m_nLastDropAction has to be set by a listener. If no listener calls + //XDropTargetDragContext::acceptDrag and specifies an action then pdwEffect + // will be DROPEFFECT_NONE throughout + m_nLastDropAction= ACTION_DEFAULT | ACTION_MOVE; + + m_currentDragContext= static_cast<XDropTargetDragContext*>( new TargetDragContext( + static_cast<DropTarget*>(this) ) ); + + //--> TRA + + // shortcut + if ( g_XTransferable.is( ) ) + m_currentData = g_XTransferable; + else + { + // Convert the IDataObject to a XTransferable + m_currentData= m_aDataConverter.createTransferableFromDataObj( + m_serviceFactory, IDataObjectPtr(pDataObj)); + } + + //<-- TRA + + if( m_nCurrentDropAction != ACTION_NONE) + { + DropTargetDragEnterEvent e; + e.SupportedDataFlavors= m_currentData->getTransferDataFlavors(); + e.DropAction= m_nCurrentDropAction; + e.Source= Reference<XInterface>( static_cast<XDropTarget*>(this),UNO_QUERY); + e.Context= m_currentDragContext; + POINT point={ pt.x, pt.y}; + ScreenToClient( m_hWnd, &point); + e.LocationX= point.x; + e.LocationY= point.y; + e.SourceActions= dndOleDropEffectsToActions( *pdwEffect); + + fire_dragEnter( e); + // Check if the action derived from grfKeyState (m_nCurrentDropAction) or the action set + // by the listener (m_nCurrentDropAction) is allowed by the source. Only a allowed action is set + // in pdwEffect. The listener notification is asynchron, that is we cannot expext that the listener + // has already reacted to the notification. + // If there is more then one valid action which is the case when ALT or RIGHT MOUSE BUTTON is pressed + // then getDropEffect returns DROPEFFECT_MOVE which is the default value if no other modifier is pressed. + // On drop the target should present the user a dialog from which the user may change the action. + sal_Int8 allowedActions= dndOleDropEffectsToActions( *pdwEffect); + *pdwEffect= dndActionsToSingleDropEffect( m_nLastDropAction & allowedActions); + } + else + { + *pdwEffect= DROPEFFECT_NONE; + } + } + return S_OK; +} + +HRESULT DropTarget::DragOver( DWORD grfKeyState, + POINTL pt, + DWORD *pdwEffect) +{ + if( m_bActive) + { + m_nCurrentDropAction= getFilteredActions( grfKeyState, *pdwEffect); + + if( m_nCurrentDropAction) + { + DropTargetDragEvent e; + e.DropAction= m_nCurrentDropAction; + e.Source= Reference<XInterface>(static_cast<XDropTarget*>(this),UNO_QUERY); + e.Context= m_currentDragContext; + POINT point={ pt.x, pt.y}; + ScreenToClient( m_hWnd, &point); + e.LocationX= point.x; + e.LocationY= point.y; + e.SourceActions= dndOleDropEffectsToActions( *pdwEffect); + + // if grfKeyState has changed since the last DragOver then fire events. + // A listener might change m_nCurrentDropAction by calling the + // XDropTargetDragContext::acceptDrag function. But this is not important + // because in the afterwards fired dragOver event the action reflects + // grgKeyState again. + if( m_nLastDropAction != m_nCurrentDropAction) + fire_dropActionChanged( e); + + // The Event contains a XDropTargetDragContext implementation. + fire_dragOver( e); + // Check if the action derived from grfKeyState (m_nCurrentDropAction) or the action set + // by the listener (m_nCurrentDropAction) is allowed by the source. Only a allowed action is set + // in pdwEffect. The listener notification is asynchron, that is we cannot expext that the listener + // has already reacted to the notification. + // If there is more then one valid action which is the case when ALT or RIGHT MOUSE BUTTON is pressed + // then getDropEffect returns DROPEFFECT_MOVE which is the default value if no other modifier is pressed. + // On drop the target should present the user a dialog from which the user may change the action. + sal_Int8 allowedActions= dndOleDropEffectsToActions( *pdwEffect); + // set the last action to the current if listener has not changed the value yet + *pdwEffect= dndActionsToSingleDropEffect( m_nLastDropAction & allowedActions); + } + else + { + *pdwEffect= DROPEFFECT_NONE; + } + } +#if defined DBG_CONSOLE_OUT + printf("\nDropTarget::DragOver %d", *pdwEffect ); +#endif + return S_OK; +} + +HRESULT DropTarget::DragLeave( void) +{ +#if defined DBG_CONSOLE_OUT + printf("\nDropTarget::DragLeave"); +#endif + if( m_bActive) + { + + m_currentData=0; + m_currentDragContext= 0; + m_currentDropContext= 0; + m_nLastDropAction= 0; + + if( m_nDefaultActions != ACTION_NONE) + { + DropTargetEvent e; + e.Source= static_cast<XDropTarget*>(this); + + fire_dragExit( e); + } + } + return S_OK; +} + +HRESULT DropTarget::Drop( IDataObject * /*pDataObj*/, + DWORD grfKeyState, + POINTL pt, + DWORD *pdwEffect) +{ +#if defined DBG_CONSOLE_OUT + printf("\nDropTarget::Drop"); +#endif + if( m_bActive) + { + + m_bDropComplete= sal_False; + + m_nCurrentDropAction= getFilteredActions( grfKeyState, *pdwEffect); + m_currentDropContext= static_cast<XDropTargetDropContext*>( new TargetDropContext( static_cast<DropTarget*>(this )) ); + if( m_nCurrentDropAction) + { + DropTargetDropEvent e; + e.DropAction= m_nCurrentDropAction; + e.Source= Reference<XInterface>( static_cast<XDropTarget*>(this), UNO_QUERY); + e.Context= m_currentDropContext; + POINT point={ pt.x, pt.y}; + ScreenToClient( m_hWnd, &point); + e.LocationX= point.x; + e.LocationY= point.y; + e.SourceActions= dndOleDropEffectsToActions( *pdwEffect); + e.Transferable= m_currentData; + fire_drop( e); + + //if fire_drop returns than a listener might have modified m_nCurrentDropAction + if( m_bDropComplete == sal_True) + { + sal_Int8 allowedActions= dndOleDropEffectsToActions( *pdwEffect); + *pdwEffect= dndActionsToSingleDropEffect( m_nCurrentDropAction & allowedActions); + } + else + *pdwEffect= DROPEFFECT_NONE; + } + else + *pdwEffect= DROPEFFECT_NONE; + + m_currentData= 0; + m_currentDragContext= 0; + m_currentDropContext= 0; + m_nLastDropAction= 0; + } + return S_OK; +} + + + +void DropTarget::fire_drop( const DropTargetDropEvent& dte) +{ + OInterfaceContainerHelper* pContainer= rBHelper.getContainer( getCppuType( (Reference<XDropTargetListener>* )0 ) ); + if( pContainer) + { + OInterfaceIteratorHelper iter( *pContainer); + while( iter.hasMoreElements()) + { + Reference<XDropTargetListener> listener( static_cast<XDropTargetListener*>( iter.next())); + listener->drop( dte); + } + } +} + +void DropTarget::fire_dragEnter( const DropTargetDragEnterEvent& e ) +{ + OInterfaceContainerHelper* pContainer= rBHelper.getContainer( getCppuType( (Reference<XDropTargetListener>* )0 ) ); + if( pContainer) + { + OInterfaceIteratorHelper iter( *pContainer); + while( iter.hasMoreElements()) + { + Reference<XDropTargetListener> listener( static_cast<XDropTargetListener*>( iter.next())); + listener->dragEnter( e); + } + } +} + +void DropTarget::fire_dragExit( const DropTargetEvent& dte ) +{ + OInterfaceContainerHelper* pContainer= rBHelper.getContainer( getCppuType( (Reference<XDropTargetListener>* )0 ) ); + + if( pContainer) + { + OInterfaceIteratorHelper iter( *pContainer); + while( iter.hasMoreElements()) + { + Reference<XDropTargetListener> listener( static_cast<XDropTargetListener*>( iter.next())); + listener->dragExit( dte); + } + } +} + +void DropTarget::fire_dragOver( const DropTargetDragEvent& dtde ) +{ + OInterfaceContainerHelper* pContainer= rBHelper.getContainer( getCppuType( (Reference<XDropTargetListener>* )0 ) ); + if( pContainer) + { + OInterfaceIteratorHelper iter( *pContainer ); + while( iter.hasMoreElements()) + { + Reference<XDropTargetListener> listener( static_cast<XDropTargetListener*>( iter.next())); + listener->dragOver( dtde); + } + } +} + +void DropTarget::fire_dropActionChanged( const DropTargetDragEvent& dtde ) +{ + OInterfaceContainerHelper* pContainer= rBHelper.getContainer( getCppuType( (Reference<XDropTargetListener>* )0 ) ); + if( pContainer) + { + OInterfaceIteratorHelper iter( *pContainer); + while( iter.hasMoreElements()) + { + Reference<XDropTargetListener> listener( static_cast<XDropTargetListener*>( iter.next())); + listener->dropActionChanged( dtde); + } + } +} + +// Non - interface functions ============================================================ +// DropTarget fires events to XDropTargetListeners. The event object contains an +// XDropTargetDropContext implementaion. When the listener calls on that interface +// then the calls are delegated from DropContext (XDropTargetDropContext) to these +// functions. +// Only one listener which visible area is affected is allowed to call on +// XDropTargetDropContext +// Returning sal_False would cause the XDropTargetDropContext or ..DragContext implementation +// to throw an InvalidDNDOperationException, meaning that a Drag is not currently performed. +// return sal_False results in throwing a InvalidDNDOperationException in the caller. + +void DropTarget::_acceptDrop(sal_Int8 dropOperation, const Reference<XDropTargetDropContext>& context) +{ + if( context == m_currentDropContext) + { + m_nCurrentDropAction= dropOperation; + } +} + +void DropTarget::_rejectDrop( const Reference<XDropTargetDropContext>& context) +{ + if( context == m_currentDropContext) + { + m_nCurrentDropAction= ACTION_NONE; + } +} + +void DropTarget::_dropComplete(sal_Bool success, const Reference<XDropTargetDropContext>& context) +{ + if(context == m_currentDropContext) + { + m_bDropComplete= success; + } +} +// -------------------------------------------------------------------------------------- +// DropTarget fires events to XDropTargetListeners. The event object can contains an +// XDropTargetDragContext implementaion. When the listener calls on that interface +// then the calls are delegated from DragContext (XDropTargetDragContext) to these +// functions. +// Only one listener which visible area is affected is allowed to call on +// XDropTargetDragContext +void DropTarget::_acceptDrag( sal_Int8 dragOperation, const Reference<XDropTargetDragContext>& context) +{ + if( context == m_currentDragContext) + { + m_nLastDropAction= dragOperation; + } +} + +void DropTarget::_rejectDrag( const Reference<XDropTargetDragContext>& context) +{ + if(context == m_currentDragContext) + { + m_nLastDropAction= ACTION_NONE; + } +} + + +//-------------------------------------------------------------------------------------- + + +// This function determines the action dependend on the pressed +// key modifiers ( CTRL, SHIFT, ALT, Right Mouse Button). The result +// is then checked against the allowed actions which can be set through +// XDropTarget::setDefaultActions. Only those values which are also +// default actions are returned. If setDefaultActions has not been called +// beforehand the the default actions comprise all possible actions. +// params: grfKeyState - the modifier keys and mouse buttons currently pressed +inline sal_Int8 DropTarget::getFilteredActions( DWORD grfKeyState, DWORD dwEffect) +{ + sal_Int8 actions= dndOleKeysToAction( grfKeyState, dndOleDropEffectsToActions( dwEffect)); + return actions & m_nDefaultActions; +} + + diff --git a/dtrans/source/win32/dnd/target.hxx b/dtrans/source/win32/dnd/target.hxx new file mode 100644 index 000000000000..94982b54818f --- /dev/null +++ b/dtrans/source/win32/dnd/target.hxx @@ -0,0 +1,213 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _TARGET_HXX_ +#define _TARGET_HXX_ + +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/datatransfer/dnd/XDropTarget.hpp> +#include <com/sun/star/datatransfer/dnd/DropTargetDragEnterEvent.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> + +#ifndef _CPPUHELPER_COMPBASE2_HXX_ +#include <cppuhelper/compbase3.hxx> +#endif +#include <cppuhelper/interfacecontainer.hxx> +#ifndef _OSL_MUTEX_H_ +#include <osl/mutex.hxx> +#endif + +#if defined _MSC_VER +#pragma warning(push,1) +#endif +#include <oleidl.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif +#include "globals.hxx" +#include "../../inc/DtObjFactory.hxx" + + +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::uno; +using namespace cppu; +using namespace osl; +using namespace rtl; +using namespace ::com::sun::star::datatransfer; +using namespace ::com::sun::star::datatransfer::dnd; + + +// The client +// has to call XComponent::dispose. The thread that calls initialize +// must also execute the destruction of the instance. This is because +// initialize calls OleInitialize and the destructor calls OleUninitialize. +// If the service calls OleInitialize then it also calls OleUnitialize when +// it is destroyed. Therefore no second instance may exist which was +// created in the same thread and still needs OLE. +class DropTarget: public MutexDummy, + public WeakComponentImplHelper3< XInitialization, XDropTarget, XServiceInfo> + +{ +private: + friend DWORD WINAPI DndTargetOleSTAFunc(LPVOID pParams); + // The native window which acts as drop target. + // It is set in initialize. In case RegisterDragDrop fails it is set + // to NULL + HWND m_hWnd; // set by initialize + // Holds the thread id of the thread which created the window that is the + // drop target. Only used when DropTarget::initialize is called from an MTA + // thread + DWORD m_threadIdWindow; + // This is the thread id of the OLE thread that is created in DropTarget::initialize + // when the calling thread is an MTA + DWORD m_threadIdTarget; + // The handle of the thread that is created in DropTarget::initialize + // when the calling thread is an MTA + HANDLE m_hOleThread; + // The thread id of the thread which called initialize. When the service dies + // than m_oleThreadId is used to determine if the service successfully called + // OleInitialize. If so then OleUninitialize has to be called. + DWORD m_oleThreadId; + // An Instance of IDropTargetImpl which receives calls from the system's drag + // and drop implementation. It delegate the calls to name alike functions in + // this class. + IDropTarget* m_pDropTarget; + + Reference<XMultiServiceFactory> m_serviceFactory; + // If m_bActive == sal_True then events are fired to XDropTargetListener s, + // none otherwise. The default value is sal_True. + sal_Bool m_bActive; + sal_Int8 m_nDefaultActions; + + // This value is set when a XDropTargetListener calls accept or reject on + // the XDropTargetDropContext or XDropTargetDragContext. + // The values are from the DNDConstants group. + sal_Int8 m_nCurrentDropAction; + // This value is manipulated by the XDropTargetListener + sal_Int8 m_nLastDropAction; + + Reference<XTransferable> m_currentData; + // The current action is used to determine if the USER + // action has changed (dropActionChanged) +// sal_Int8 m_userAction; + // Set by listeners when they call XDropTargetDropContext::dropComplete + sal_Bool m_bDropComplete; + // converts IDataObject objects to XTransferable objects. + CDTransObjFactory m_aDataConverter; + Reference<XDropTargetDragContext> m_currentDragContext; + Reference<XDropTargetDropContext> m_currentDropContext; + + +private: + DropTarget(); + DropTarget(DropTarget&); + DropTarget &operator= (DropTarget&); + +public: + DropTarget(const Reference<XMultiServiceFactory>& sf); + virtual ~DropTarget(); + + // Overrides WeakComponentImplHelper::disposing which is called by + // WeakComponentImplHelper::dispose + // Must be called. + virtual void SAL_CALL disposing(); + // XInitialization + virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) + throw(Exception, RuntimeException); + + // XDropTarget + virtual void SAL_CALL addDropTargetListener( const Reference< XDropTargetListener >& dtl ) + throw(RuntimeException); + virtual void SAL_CALL removeDropTargetListener( const Reference< XDropTargetListener >& dtl ) + throw(RuntimeException); + // Default is not active + virtual sal_Bool SAL_CALL isActive( ) throw(RuntimeException); + virtual void SAL_CALL setActive( sal_Bool isActive ) throw(RuntimeException); + virtual sal_Int8 SAL_CALL getDefaultActions( ) throw(RuntimeException); + virtual void SAL_CALL setDefaultActions( sal_Int8 actions ) throw(RuntimeException); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName( ) throw (RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw (RuntimeException); + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw (RuntimeException); + + + // Functions called from the IDropTarget implementation ( m_pDropTarget) + virtual HRESULT DragEnter( + /* [unique][in] */ IDataObject *pDataObj, + /* [in] */ DWORD grfKeyState, + /* [in] */ POINTL pt, + /* [out][in] */ DWORD *pdwEffect); + + virtual HRESULT STDMETHODCALLTYPE DragOver( + /* [in] */ DWORD grfKeyState, + /* [in] */ POINTL pt, + /* [out][in] */ DWORD *pdwEffect); + + virtual HRESULT STDMETHODCALLTYPE DragLeave( ) ; + + virtual HRESULT STDMETHODCALLTYPE Drop( + /* [unique][in] */ IDataObject *pDataObj, + /* [in] */ DWORD grfKeyState, + /* [in] */ POINTL pt, + /* [out][in] */ DWORD *pdwEffect); + + +// Non - interface functions -------------------------------------------------- +// XDropTargetDropContext delegated from DropContext + + void _acceptDrop( sal_Int8 dropOperation, const Reference<XDropTargetDropContext>& context); + void _rejectDrop( const Reference<XDropTargetDropContext>& context); + void _dropComplete( sal_Bool success, const Reference<XDropTargetDropContext>& context); + +// XDropTargetDragContext delegated from DragContext + void _acceptDrag( sal_Int8 dragOperation, const Reference<XDropTargetDragContext>& context); + void _rejectDrag( const Reference<XDropTargetDragContext>& context); + + +protected: + // Gets the current action dependend on the pressed modifiers, the effects + // supported by the drop source (IDropSource) and the default actions of the + // drop target (XDropTarget, this class)) + inline sal_Int8 getFilteredActions( DWORD grfKeyState, DWORD sourceActions); + // Only filters with the default actions + inline sal_Int8 getFilteredActions( DWORD grfKeyState); + + + + void fire_drop( const DropTargetDropEvent& dte); + void fire_dragEnter( const DropTargetDragEnterEvent& dtde ); + void fire_dragExit( const DropTargetEvent& dte ); + void fire_dragOver( const DropTargetDragEvent& dtde ); + void fire_dropActionChanged( const DropTargetDragEvent& dtde ); + + + + +}; + + +#endif diff --git a/dtrans/source/win32/dnd/targetdragcontext.cxx b/dtrans/source/win32/dnd/targetdragcontext.cxx new file mode 100644 index 000000000000..15f7ea32a1ef --- /dev/null +++ b/dtrans/source/win32/dnd/targetdragcontext.cxx @@ -0,0 +1,59 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" +#include <rtl/unload.h> + +#include "targetdragcontext.hxx" + +extern rtl_StandardModuleCount g_moduleCount; +TargetDragContext::TargetDragContext( DropTarget* p) +{ + g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); + m_pDropTarget= p; + p->acquire(); +} + +TargetDragContext::~TargetDragContext() +{ + m_pDropTarget->release(); + g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); +} + +void SAL_CALL TargetDragContext::acceptDrag( sal_Int8 dragOperation ) + throw( RuntimeException) +{ + m_pDropTarget->_acceptDrag( dragOperation, static_cast<XDropTargetDragContext*>( this) ); + +} +void SAL_CALL TargetDragContext::rejectDrag( ) + throw( RuntimeException) +{ + m_pDropTarget->_rejectDrag( static_cast<XDropTargetDragContext*>( this) ); +} + diff --git a/dtrans/source/win32/dnd/targetdragcontext.hxx b/dtrans/source/win32/dnd/targetdragcontext.hxx new file mode 100644 index 000000000000..e4b24b95b0a0 --- /dev/null +++ b/dtrans/source/win32/dnd/targetdragcontext.hxx @@ -0,0 +1,62 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _TARGETDRAGCONTEXT_HXX_ +#define _TARGETDRAGCONTEXT_HXX_ + + +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/datatransfer/dnd/XDropTargetDragContext.hpp> +#include <com/sun/star/datatransfer/DataFlavor.hpp> + +#include "target.hxx" +using namespace ::com::sun::star::datatransfer; +using namespace ::com::sun::star::datatransfer::dnd; +using namespace ::cppu; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; + +class TargetDragContext: public WeakImplHelper1<XDropTargetDragContext> +{ + // some calls to the functions of XDropTargetDragContext are delegated + // to non-interface functions of m_pDropTarget + DropTarget* m_pDropTarget; + + TargetDragContext(); + TargetDragContext( const TargetDragContext&); + TargetDragContext &operator= ( const TargetDragContext&); +public: + TargetDragContext( DropTarget* pTarget); + ~TargetDragContext(); + + virtual void SAL_CALL acceptDrag( sal_Int8 dragOperation ) + throw( RuntimeException); + virtual void SAL_CALL rejectDrag( ) + throw( RuntimeException); +}; + +#endif diff --git a/dtrans/source/win32/dnd/targetdropcontext.cxx b/dtrans/source/win32/dnd/targetdropcontext.cxx new file mode 100644 index 000000000000..a009b8df7527 --- /dev/null +++ b/dtrans/source/win32/dnd/targetdropcontext.cxx @@ -0,0 +1,69 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" +#include <rtl/unload.h> + +#include "targetdropcontext.hxx" + +using namespace ::com::sun::star::datatransfer::dnd; +using namespace ::cppu; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; + +extern rtl_StandardModuleCount g_moduleCount; +TargetDropContext::TargetDropContext( DropTarget* p) +{ + g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); + m_pDropTarget= p; + p->acquire(); +} + +TargetDropContext::~TargetDropContext() +{ + m_pDropTarget->release(); + g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); +} + +void SAL_CALL TargetDropContext::acceptDrop( sal_Int8 dropOperation ) + throw( RuntimeException) +{ + m_pDropTarget->_acceptDrop( dropOperation, static_cast<XDropTargetDropContext*>( this) ); +} + +void SAL_CALL TargetDropContext::rejectDrop( ) + throw( RuntimeException) +{ + m_pDropTarget->_rejectDrop( static_cast<XDropTargetDropContext*>( this) ); +} + +void SAL_CALL TargetDropContext::dropComplete( sal_Bool success ) + throw( RuntimeException) +{ + m_pDropTarget->_dropComplete( success, static_cast<XDropTargetDropContext*>( this) ); +} diff --git a/dtrans/source/win32/dnd/targetdropcontext.hxx b/dtrans/source/win32/dnd/targetdropcontext.hxx new file mode 100644 index 000000000000..6ae6f0182a36 --- /dev/null +++ b/dtrans/source/win32/dnd/targetdropcontext.hxx @@ -0,0 +1,72 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _TARGETDROPCONTEXT_HXX_ +#define _TARGETDROPCONTEXT_HXX_ + +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/datatransfer/dnd/XDropTargetDropContext.hpp> + +#include "target.hxx" + +using namespace ::com::sun::star::datatransfer::dnd; +using namespace ::cppu; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; + +class TargetDropContext: public WeakImplHelper1<XDropTargetDropContext> +{ + // calls to the functions of XDropTargetDropContext are delegated + // to non-interface functions of m_pDropTarget + DropTarget* m_pDropTarget; + + TargetDropContext(); + TargetDropContext( const TargetDropContext&); + TargetDropContext &operator= ( const TargetDropContext&); +public: + TargetDropContext( DropTarget* pTarget); + ~TargetDropContext(); + + + // XDropTargetDragContext + virtual void SAL_CALL acceptDrop( sal_Int8 dropOperation ) + throw( RuntimeException); + virtual void SAL_CALL rejectDrop( ) + throw( RuntimeException); + + +/* virtual Sequence< DataFlavor > SAL_CALL getCurrentDataFlavors( ) + throw( RuntimeException); + virtual sal_Bool SAL_CALL isDataFlavorSupported( const DataFlavor& df ) + throw( RuntimeException); +*/ + + // XDropTargetDropContext (inherits XDropTargetDragContext) + virtual void SAL_CALL dropComplete( sal_Bool success ) + throw( RuntimeException); +}; +#endif |