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 #pragma once 20 21 #include <com/sun/star/lang/XInitialization.hpp> 22 #include <com/sun/star/datatransfer/dnd/XDropTarget.hpp> 23 #include <com/sun/star/datatransfer/dnd/DropTargetDragEnterEvent.hpp> 24 #include <com/sun/star/lang/XServiceInfo.hpp> 25 26 #include <cppuhelper/compbase.hxx> 27 #include <cppuhelper/interfacecontainer.hxx> 28 #include <osl/mutex.hxx> 29 30 #include <oleidl.h> 31 #include "globals.hxx" 32 33 namespace com::sun::star::uno 34 { 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 119 removeDropTargetListener(const Reference<XDropTargetListener>& dtl) override; 120 // Default is not active 121 virtual sal_Bool SAL_CALL isActive() override; 122 virtual void SAL_CALL setActive(sal_Bool isActive) override; 123 virtual sal_Int8 SAL_CALL getDefaultActions() override; 124 virtual void SAL_CALL setDefaultActions(sal_Int8 actions) override; 125 126 // XServiceInfo 127 virtual OUString SAL_CALL getImplementationName() override; 128 virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override; 129 virtual Sequence<OUString> SAL_CALL getSupportedServiceNames() override; 130 131 // Functions called from the IDropTarget implementation ( m_pDropTarget) 132 virtual HRESULT DragEnter( 133 /* [unique][in] */ IDataObject* pDataObj, 134 /* [in] */ DWORD grfKeyState, 135 /* [in] */ POINTL pt, 136 /* [out][in] */ DWORD* pdwEffect); 137 138 virtual HRESULT STDMETHODCALLTYPE DragOver( 139 /* [in] */ DWORD grfKeyState, 140 /* [in] */ POINTL pt, 141 /* [out][in] */ DWORD* pdwEffect); 142 143 virtual HRESULT STDMETHODCALLTYPE DragLeave(); 144 145 virtual HRESULT STDMETHODCALLTYPE Drop( 146 /* [unique][in] */ IDataObject* pDataObj, 147 /* [in] */ DWORD grfKeyState, 148 /* [in] */ POINTL pt, 149 /* [out][in] */ DWORD* pdwEffect); 150 151 // Non - interface functions -------------------------------------------------- 152 // XDropTargetDropContext delegated from DropContext 153 154 void _acceptDrop(sal_Int8 dropOperation, const Reference<XDropTargetDropContext>& context); 155 void _rejectDrop(const Reference<XDropTargetDropContext>& context); 156 void _dropComplete(bool success, const Reference<XDropTargetDropContext>& context); 157 158 // XDropTargetDragContext delegated from DragContext 159 void _acceptDrag(sal_Int8 dragOperation, const Reference<XDropTargetDragContext>& context); 160 void _rejectDrag(const Reference<XDropTargetDragContext>& context); 161 162 protected: 163 // Gets the current action dependent on the pressed modifiers, the effects 164 // supported by the drop source (IDropSource) and the default actions of the 165 // drop target (XDropTarget, this class)) 166 inline sal_Int8 getFilteredActions(DWORD grfKeyState, DWORD sourceActions); 167 // Only filters with the default actions 168 inline sal_Int8 getFilteredActions(DWORD grfKeyState); 169 170 void fire_drop(const DropTargetDropEvent& dte); 171 void fire_dragEnter(const DropTargetDragEnterEvent& dtde); 172 void fire_dragExit(const DropTargetEvent& dte); 173 void fire_dragOver(const DropTargetDragEvent& dtde); 174 void fire_dropActionChanged(const DropTargetDragEvent& dtde); 175 }; 176 177 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 178