1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 11 * Licensed to the Apache Software Foundation (ASF) under one or more 12 * contributor license agreements. See the NOTICE file distributed 13 * with this work for additional information regarding copyright 14 * ownership. The ASF licenses this file to you under the Apache 15 * License, Version 2.0 (the "License"); you may not use this file 16 * except in compliance with the License. You may obtain a copy of 17 * the License at http://www.apache.org/licenses/LICENSE-2.0 . 18 */ 19 #ifndef INCLUDED_DTRANS_SOURCE_WIN32_DND_TARGET_HXX 20 #define INCLUDED_DTRANS_SOURCE_WIN32_DND_TARGET_HXX 21 22 #include <com/sun/star/lang/XInitialization.hpp> 23 #include <com/sun/star/datatransfer/dnd/XDropTarget.hpp> 24 #include <com/sun/star/datatransfer/dnd/DropTargetDragEnterEvent.hpp> 25 #include <com/sun/star/lang/XServiceInfo.hpp> 26 27 #include <cppuhelper/compbase.hxx> 28 #include <cppuhelper/interfacecontainer.hxx> 29 #include <osl/mutex.hxx> 30 31 #include <oleidl.h> 32 #include "globals.hxx" 33 34 namespace com { namespace sun { namespace star { namespace uno { 35 class XComponentContext; 36 } } } } 37 38 using namespace ::com::sun::star::lang; 39 using namespace ::com::sun::star::uno; 40 using namespace cppu; 41 using namespace osl; 42 using namespace ::com::sun::star::datatransfer; 43 using namespace ::com::sun::star::datatransfer::dnd; 44 45 // The client 46 // has to call XComponent::dispose. The thread that calls initialize 47 // must also execute the destruction of the instance. This is because 48 // initialize calls OleInitialize and the destructor calls OleUninitialize. 49 // If the service calls OleInitialize then it also calls OleUnitialize when 50 // it is destroyed. Therefore no second instance may exist which was 51 // created in the same thread and still needs OLE. 52 class DropTarget: public MutexDummy, 53 public WeakComponentImplHelper< XInitialization, XDropTarget, XServiceInfo> 54 55 { 56 private: 57 friend DWORD WINAPI DndTargetOleSTAFunc(LPVOID pParams); 58 // The native window which acts as drop target. 59 // It is set in initialize. In case RegisterDragDrop fails it is set 60 // to NULL 61 HWND m_hWnd; // set by initialize 62 // Holds the thread id of the thread which created the window that is the 63 // drop target. Only used when DropTarget::initialize is called from an MTA 64 // thread 65 DWORD m_threadIdWindow; 66 // This is the thread id of the OLE thread that is created in DropTarget::initialize 67 // when the calling thread is an MTA 68 DWORD m_threadIdTarget; 69 // The handle of the thread that is created in DropTarget::initialize 70 // when the calling thread is an MTA 71 HANDLE m_hOleThread; 72 // The thread id of the thread which called initialize. When the service dies 73 // than m_oleThreadId is used to determine if the service successfully called 74 // OleInitialize. If so then OleUninitialize has to be called. 75 DWORD m_oleThreadId; 76 // An Instance of IDropTargetImpl which receives calls from the system's drag 77 // and drop implementation. It delegate the calls to name alike functions in 78 // this class. 79 IDropTarget* m_pDropTarget; 80 81 Reference<XComponentContext> m_xContext; 82 // If m_bActive == sal_True then events are fired to XDropTargetListener s, 83 // none otherwise. The default value is sal_True. 84 bool m_bActive; 85 sal_Int8 m_nDefaultActions; 86 87 // This value is set when a XDropTargetListener calls accept or reject on 88 // the XDropTargetDropContext or XDropTargetDragContext. 89 // The values are from the DNDConstants group. 90 sal_Int8 m_nCurrentDropAction; 91 // This value is manipulated by the XDropTargetListener 92 sal_Int8 m_nLastDropAction; 93 94 Reference<XTransferable> m_currentData; 95 // The current action is used to determine if the USER 96 // action has changed (dropActionChanged) 97 // sal_Int8 m_userAction; 98 // Set by listeners when they call XDropTargetDropContext::dropComplete 99 bool m_bDropComplete; 100 Reference<XDropTargetDragContext> m_currentDragContext; 101 Reference<XDropTargetDropContext> m_currentDropContext; 102 103 public: 104 explicit DropTarget(const Reference<XComponentContext>& rxContext); 105 virtual ~DropTarget() override; 106 DropTarget(DropTarget const &) = delete; 107 DropTarget &operator= (DropTarget const &) = delete; 108 109 // Overrides WeakComponentImplHelper::disposing which is called by 110 // WeakComponentImplHelper::dispose 111 // Must be called. 112 virtual void SAL_CALL disposing() override; 113 // XInitialization 114 virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) override; 115 116 // XDropTarget 117 virtual void SAL_CALL addDropTargetListener( const Reference< XDropTargetListener >& dtl ) override; 118 virtual void SAL_CALL removeDropTargetListener( const Reference< XDropTargetListener >& dtl ) override; 119 // Default is not active 120 virtual sal_Bool SAL_CALL isActive( ) override; 121 virtual void SAL_CALL setActive( sal_Bool isActive ) override; 122 virtual sal_Int8 SAL_CALL getDefaultActions( ) override; 123 virtual void SAL_CALL setDefaultActions( sal_Int8 actions ) override; 124 125 // XServiceInfo 126 virtual OUString SAL_CALL getImplementationName( ) override; 127 virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; 128 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override; 129 130 // Functions called from the IDropTarget implementation ( m_pDropTarget) 131 virtual HRESULT DragEnter( 132 /* [unique][in] */ IDataObject *pDataObj, 133 /* [in] */ DWORD grfKeyState, 134 /* [in] */ POINTL pt, 135 /* [out][in] */ DWORD *pdwEffect); 136 137 virtual HRESULT STDMETHODCALLTYPE DragOver( 138 /* [in] */ DWORD grfKeyState, 139 /* [in] */ POINTL pt, 140 /* [out][in] */ DWORD *pdwEffect); 141 142 virtual HRESULT STDMETHODCALLTYPE DragLeave( ) ; 143 144 virtual HRESULT STDMETHODCALLTYPE Drop( 145 /* [unique][in] */ IDataObject *pDataObj, 146 /* [in] */ DWORD grfKeyState, 147 /* [in] */ POINTL pt, 148 /* [out][in] */ DWORD *pdwEffect); 149 150 // Non - interface functions -------------------------------------------------- 151 // XDropTargetDropContext delegated from DropContext 152 153 void _acceptDrop( sal_Int8 dropOperation, const Reference<XDropTargetDropContext>& context); 154 void _rejectDrop( const Reference<XDropTargetDropContext>& context); 155 void _dropComplete( bool success, const Reference<XDropTargetDropContext>& context); 156 157 // XDropTargetDragContext delegated from DragContext 158 void _acceptDrag( sal_Int8 dragOperation, const Reference<XDropTargetDragContext>& context); 159 void _rejectDrag( const Reference<XDropTargetDragContext>& context); 160 161 protected: 162 // Gets the current action dependent on the pressed modifiers, the effects 163 // supported by the drop source (IDropSource) and the default actions of the 164 // drop target (XDropTarget, this class)) 165 inline sal_Int8 getFilteredActions( DWORD grfKeyState, DWORD sourceActions); 166 // Only filters with the default actions 167 inline sal_Int8 getFilteredActions( DWORD grfKeyState); 168 169 void fire_drop( const DropTargetDropEvent& dte); 170 void fire_dragEnter( const DropTargetDragEnterEvent& dtde ); 171 void fire_dragExit( const DropTargetEvent& dte ); 172 void fire_dragOver( const DropTargetDragEvent& dtde ); 173 void fire_dropActionChanged( const DropTargetDragEvent& dtde ); 174 175 }; 176 177 #endif 178 179 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 180