LibreOffice Module vcl (master)  1
dndlistenercontainer.cxx
Go to the documentation of this file.
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 
20 #include <dndlistenercontainer.hxx>
21 
22 using namespace ::cppu;
23 using namespace ::com::sun::star::uno;
24 using namespace ::com::sun::star::datatransfer;
25 using namespace ::com::sun::star::datatransfer::dnd;
26 
28  : WeakComponentImplHelper< XDragGestureRecognizer, XDropTargetDragContext, XDropTargetDropContext, XDropTarget >(GetMutex())
29 {
30  m_bActive = true;
31  m_nDefaultActions = nDefaultActions;
32 }
33 
35 {
36 }
37 
38 void SAL_CALL DNDListenerContainer::addDragGestureListener( const Reference< XDragGestureListener >& dgl )
39 {
40  rBHelper.addListener( cppu::UnoType<XDragGestureListener>::get(), dgl );
41 }
42 
43 void SAL_CALL DNDListenerContainer::removeDragGestureListener( const Reference< XDragGestureListener >& dgl )
44 {
45  rBHelper.removeListener( cppu::UnoType<XDragGestureListener>::get(), dgl );
46 }
47 
49 {
50 }
51 
52 void SAL_CALL DNDListenerContainer::addDropTargetListener( const Reference< XDropTargetListener >& dtl )
53 {
54  rBHelper.addListener( cppu::UnoType<XDropTargetListener>::get(), dtl );
55 }
56 
57 void SAL_CALL DNDListenerContainer::removeDropTargetListener( const Reference< XDropTargetListener >& dtl )
58 {
59  rBHelper.removeListener( cppu::UnoType<XDropTargetListener>::get(), dtl );
60 }
61 
63 {
64  return m_bActive;
65 }
66 
68 {
69  m_bActive = active;
70 }
71 
73 {
74  return m_nDefaultActions;
75 }
76 
78 {
79  m_nDefaultActions = actions;
80 }
81 
82 sal_uInt32 DNDListenerContainer::fireDropEvent( const Reference< XDropTargetDropContext >& context,
83  sal_Int8 dropAction, sal_Int32 locationX, sal_Int32 locationY, sal_Int8 sourceActions,
84  const Reference< XTransferable >& transferable )
85 {
86  sal_uInt32 nRet = 0;
87 
88  // fire DropTargetDropEvent on all XDropTargetListeners
89  OInterfaceContainerHelper *pContainer = rBHelper.getContainer( cppu::UnoType<XDropTargetListener>::get());
90 
91  if( pContainer && m_bActive )
92  {
93  OInterfaceIteratorHelper aIterator( *pContainer );
94 
95  // remember context to use in own context methods
96  m_xDropTargetDropContext = context;
97 
98  // do not construct the event before you are sure at least one listener is registered
99  DropTargetDropEvent aEvent( static_cast < XDropTarget * > (this), 0,
100  static_cast < XDropTargetDropContext * > (this), dropAction,
101  locationX, locationY, sourceActions, transferable );
102 
103  while (aIterator.hasMoreElements())
104  {
105  // FIXME: this can be simplified as soon as the Iterator has a remove method
106  Reference< XInterface > xElement( aIterator.next() );
107 
108  try
109  {
110  // this may result in a runtime exception
111  Reference < XDropTargetListener > xListener( xElement, UNO_QUERY );
112 
113  if( xListener.is() )
114  {
115  // fire drop until the first one has accepted
116  if( m_xDropTargetDropContext.is() )
117  xListener->drop( aEvent );
118  else
119  {
120  DropTargetEvent aDTEvent( static_cast < XDropTarget * > (this), 0 );
121  xListener->dragExit( aDTEvent );
122  }
123 
124  nRet++;
125  }
126  }
127  catch (const RuntimeException&)
128  {
129  pContainer->removeInterface( xElement );
130  }
131  }
132 
133  // if context still valid, then reject drop
134  if( m_xDropTargetDropContext.is() )
135  {
136  m_xDropTargetDropContext.clear();
137 
138  try
139  {
140  context->rejectDrop();
141  }
142  catch (const RuntimeException&)
143  {
144  }
145  }
146  }
147 
148  return nRet;
149 }
150 
152 {
153  sal_uInt32 nRet = 0;
154 
155  // fire DropTargetDropEvent on all XDropTargetListeners
156  OInterfaceContainerHelper *pContainer = rBHelper.getContainer( cppu::UnoType<XDropTargetListener>::get());
157 
158  if( pContainer && m_bActive )
159  {
160  OInterfaceIteratorHelper aIterator( *pContainer );
161 
162  // do not construct the event before you are sure at least one listener is registered
163  DropTargetEvent aEvent( static_cast < XDropTarget * > (this), 0 );
164 
165  while (aIterator.hasMoreElements())
166  {
167  // FIXME: this can be simplified as soon as the Iterator has a remove method
168  Reference< XInterface > xElement( aIterator.next() );
169 
170  try
171  {
172  // this may result in a runtime exception
173  Reference < XDropTargetListener > xListener( xElement, UNO_QUERY );
174 
175  if( xListener.is() )
176  {
177  xListener->dragExit( aEvent );
178  nRet++;
179  }
180  }
181  catch (const RuntimeException&)
182  {
183  pContainer->removeInterface( xElement );
184  }
185  }
186  }
187 
188  return nRet;
189 }
190 
191 sal_uInt32 DNDListenerContainer::fireDragOverEvent( const Reference< XDropTargetDragContext >& context,
192  sal_Int8 dropAction, sal_Int32 locationX, sal_Int32 locationY, sal_Int8 sourceActions )
193 {
194  sal_uInt32 nRet = 0;
195 
196  // fire DropTargetDropEvent on all XDropTargetListeners
197  OInterfaceContainerHelper *pContainer = rBHelper.getContainer( cppu::UnoType<XDropTargetListener>::get());
198 
199  if( pContainer && m_bActive )
200  {
201  OInterfaceIteratorHelper aIterator( *pContainer );
202 
203  // remember context to use in own context methods
204  m_xDropTargetDragContext = context;
205 
206  // do not construct the event before you are sure at least one listener is registered
207  DropTargetDragEvent aEvent( static_cast < XDropTarget * > (this), 0,
208  static_cast < XDropTargetDragContext * > (this),
209  dropAction, locationX, locationY, sourceActions );
210 
211  while (aIterator.hasMoreElements())
212  {
213  // FIXME: this can be simplified as soon as the Iterator has a remove method
214  Reference< XInterface > xElement( aIterator.next() );
215 
216  try
217  {
218  // this may result in a runtime exception
219  Reference < XDropTargetListener > xListener( xElement, UNO_QUERY );
220 
221  if( xListener.is() )
222  {
223  if( m_xDropTargetDragContext.is() )
224  xListener->dragOver( aEvent );
225  nRet++;
226  }
227  }
228  catch (const RuntimeException&)
229  {
230  pContainer->removeInterface( xElement );
231  }
232  }
233 
234  // if context still valid, then reject drag
235  if( m_xDropTargetDragContext.is() )
236  {
237  m_xDropTargetDragContext.clear();
238 
239  try
240  {
241  context->rejectDrag();
242  }
243  catch (const RuntimeException&)
244  {
245  }
246  }
247  }
248 
249  return nRet;
250 }
251 
252 sal_uInt32 DNDListenerContainer::fireDragEnterEvent( const Reference< XDropTargetDragContext >& context,
253  sal_Int8 dropAction, sal_Int32 locationX, sal_Int32 locationY, sal_Int8 sourceActions,
254  const Sequence< DataFlavor >& dataFlavors )
255 {
256  sal_uInt32 nRet = 0;
257 
258  // fire DropTargetDropEvent on all XDropTargetListeners
259  OInterfaceContainerHelper *pContainer = rBHelper.getContainer( cppu::UnoType<XDropTargetListener>::get());
260 
261  if( pContainer && m_bActive )
262  {
263  OInterfaceIteratorHelper aIterator( *pContainer );
264 
265  // remember context to use in own context methods
266  m_xDropTargetDragContext = context;
267 
268  // do not construct the event before you are sure at least one listener is registered
269  DropTargetDragEnterEvent aEvent( static_cast < XDropTarget * > (this), 0,
270  static_cast < XDropTargetDragContext * > (this),
271  dropAction, locationX, locationY, sourceActions, dataFlavors );
272 
273  while (aIterator.hasMoreElements())
274  {
275  // FIXME: this can be simplified as soon as the Iterator has a remove method
276  Reference< XInterface > xElement( aIterator.next() );
277 
278  try
279  {
280  // this may result in a runtime exception
281  Reference < XDropTargetListener > xListener( xElement, UNO_QUERY );
282 
283  if( xListener.is() )
284  {
285  if( m_xDropTargetDragContext.is() )
286  xListener->dragEnter( aEvent );
287  nRet++;
288  }
289  }
290  catch (const RuntimeException&)
291  {
292  pContainer->removeInterface( xElement );
293  }
294  }
295 
296  // if context still valid, then reject drag
297  if( m_xDropTargetDragContext.is() )
298  {
299  m_xDropTargetDragContext.clear();
300 
301  try
302  {
303  context->rejectDrag();
304  }
305  catch (const RuntimeException&)
306  {
307  }
308  }
309  }
310 
311  return nRet;
312 }
313 
314 sal_uInt32 DNDListenerContainer::fireDropActionChangedEvent( const Reference< XDropTargetDragContext >& context,
315  sal_Int8 dropAction, sal_Int32 locationX, sal_Int32 locationY, sal_Int8 sourceActions )
316 {
317  sal_uInt32 nRet = 0;
318 
319  // fire DropTargetDropEvent on all XDropTargetListeners
320  OInterfaceContainerHelper *pContainer = rBHelper.getContainer( cppu::UnoType<XDropTargetListener>::get());
321 
322  if( pContainer && m_bActive )
323  {
324  OInterfaceIteratorHelper aIterator( *pContainer );
325 
326  // remember context to use in own context methods
327  m_xDropTargetDragContext = context;
328 
329  // do not construct the event before you are sure at least one listener is registered
330  DropTargetDragEvent aEvent( static_cast < XDropTarget * > (this), 0,
331  static_cast < XDropTargetDragContext * > (this),
332  dropAction, locationX, locationY, sourceActions );
333 
334  while (aIterator.hasMoreElements())
335  {
336  // FIXME: this can be simplified as soon as the Iterator has a remove method
337  Reference< XInterface > xElement( aIterator.next() );
338 
339  try
340  {
341  // this may result in a runtime exception
342  Reference < XDropTargetListener > xListener( xElement, UNO_QUERY );
343 
344  if( xListener.is() )
345  {
346  if( m_xDropTargetDragContext.is() )
347  xListener->dropActionChanged( aEvent );
348  nRet++;
349  }
350  }
351  catch (const RuntimeException&)
352  {
353  pContainer->removeInterface( xElement );
354  }
355  }
356 
357  // if context still valid, then reject drag
358  if( m_xDropTargetDragContext.is() )
359  {
360  m_xDropTargetDragContext.clear();
361 
362  try
363  {
364  context->rejectDrag();
365  }
366  catch (const RuntimeException&)
367  {
368  }
369  }
370  }
371 
372  return nRet;
373 }
374 
375 sal_uInt32 DNDListenerContainer::fireDragGestureEvent( sal_Int8 dragAction, sal_Int32 dragOriginX,
376  sal_Int32 dragOriginY, const Reference< XDragSource >& dragSource, const Any& triggerEvent )
377 {
378  sal_uInt32 nRet = 0;
379 
380  // fire DropTargetDropEvent on all XDropTargetListeners
381  OInterfaceContainerHelper *pContainer = rBHelper.getContainer( cppu::UnoType<XDragGestureListener>::get());
382 
383  if( pContainer )
384  {
385  OInterfaceIteratorHelper aIterator( *pContainer );
386 
387  // do not construct the event before you are sure at least one listener is registered
388  DragGestureEvent aEvent( static_cast < XDragGestureRecognizer * > (this), dragAction,
389  dragOriginX, dragOriginY, dragSource, triggerEvent );
390 
391  while( aIterator.hasMoreElements() )
392  {
393  // FIXME: this can be simplified as soon as the Iterator has a remove method
394  Reference< XInterface > xElement( aIterator.next() );
395 
396  try
397  {
398  // this may result in a runtime exception
399  Reference < XDragGestureListener > xListener( xElement, UNO_QUERY );
400 
401  if( xListener.is() )
402  {
403  xListener->dragGestureRecognized( aEvent );
404  nRet++;
405  }
406  }
407  catch (const RuntimeException&)
408  {
409  pContainer->removeInterface( xElement );
410  }
411  }
412  }
413 
414  return nRet;
415 }
416 
417 void SAL_CALL DNDListenerContainer::acceptDrag( sal_Int8 dragOperation )
418 {
419  if( m_xDropTargetDragContext.is() )
420  {
421  m_xDropTargetDragContext->acceptDrag( dragOperation );
422  m_xDropTargetDragContext.clear();
423  }
424 }
425 
427 {
428  // nothing to do here
429 }
430 
431 void SAL_CALL DNDListenerContainer::acceptDrop( sal_Int8 dropOperation )
432 {
433  if( m_xDropTargetDropContext.is() )
434  m_xDropTargetDropContext->acceptDrop( dropOperation );
435 }
436 
438 {
439  // nothing to do here
440 }
441 
443 {
444  if( m_xDropTargetDropContext.is() )
445  {
446  m_xDropTargetDropContext->dropComplete( success );
447  m_xDropTargetDropContext.clear();
448  }
449 }
450 
451 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual void SAL_CALL acceptDrag(sal_Int8 dragOperation) override
virtual void SAL_CALL addDragGestureListener(const css::uno::Reference< css::datatransfer::dnd::XDragGestureListener > &dgl) override
signed char sal_Int8
sal_uInt32 fireDragEnterEvent(const css::uno::Reference< css::datatransfer::dnd::XDropTargetDragContext > &context, sal_Int8 dropAction, sal_Int32 locationX, sal_Int32 locationY, sal_Int8 sourceActions, const css::uno::Sequence< css::datatransfer::DataFlavor > &dataFlavor)
virtual void SAL_CALL dropComplete(sal_Bool success) override
sal_uInt32 fireDropActionChangedEvent(const css::uno::Reference< css::datatransfer::dnd::XDropTargetDragContext > &context, sal_Int8 dropAction, sal_Int32 locationX, sal_Int32 locationY, sal_Int8 sourceActions)
virtual void SAL_CALL rejectDrop() override
sal_uInt32 fireDropEvent(const css::uno::Reference< css::datatransfer::dnd::XDropTargetDropContext > &context, sal_Int8 dropAction, sal_Int32 locationX, sal_Int32 locationY, sal_Int8 sourceActions, const css::uno::Reference< css::datatransfer::XTransferable > &transferable)
virtual void SAL_CALL removeDragGestureListener(const css::uno::Reference< css::datatransfer::dnd::XDragGestureListener > &dgl) override
virtual ~DNDListenerContainer() override
sal_uInt32 fireDragOverEvent(const css::uno::Reference< css::datatransfer::dnd::XDropTargetDragContext > &context, sal_Int8 dropAction, sal_Int32 locationX, sal_Int32 locationY, sal_Int8 sourceActions)
css::uno::Reference< css::datatransfer::dnd::XDropTargetDragContext > m_xDropTargetDragContext
virtual void SAL_CALL setDefaultActions(sal_Int8 actions) override
virtual void SAL_CALL removeDropTargetListener(const css::uno::Reference< css::datatransfer::dnd::XDropTargetListener > &dtl) override
unsigned char sal_Bool
virtual void SAL_CALL acceptDrop(sal_Int8 dropOperation) override
virtual sal_Int8 SAL_CALL getDefaultActions() override
virtual void SAL_CALL resetRecognizer() override
virtual void SAL_CALL rejectDrag() override
css::uno::Reference< css::datatransfer::dnd::XDropTargetDropContext > m_xDropTargetDropContext
sal_uInt32 fireDragGestureEvent(sal_Int8 dragAction, sal_Int32 dragOriginX, sal_Int32 dragOriginY, const css::uno::Reference< css::datatransfer::dnd::XDragSource > &dragSource, const css::uno::Any &triggerEvent)
virtual void SAL_CALL addDropTargetListener(const css::uno::Reference< css::datatransfer::dnd::XDropTargetListener > &dtl) override
virtual sal_Bool SAL_CALL isActive() override
virtual void SAL_CALL setActive(sal_Bool active) override
DNDListenerContainer(sal_Int8 nDefaultActions)