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