LCOV - code coverage report
Current view: top level - vcl/source/window - dndevdis.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 8 164 4.9 %
Date: 2014-11-03 Functions: 6 21 28.6 %
Legend: Lines: hit not hit

          Line data    Source code
       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 <dndevdis.hxx>
      21             : #include <dndlcon.hxx>
      22             : #include <window.h>
      23             : #include <svdata.hxx>
      24             : 
      25             : #include <osl/mutex.hxx>
      26             : #include <vcl/svapp.hxx>
      27             : #include <vcl/settings.hxx>
      28             : 
      29             : using namespace ::cppu;
      30             : using namespace ::com::sun::star::uno;
      31             : using namespace ::com::sun::star::lang;
      32             : using namespace ::com::sun::star::datatransfer;
      33             : using namespace ::com::sun::star::datatransfer::dnd;
      34             : 
      35             : // DNDEventDispatcher::DNDEventDispatcher
      36             : 
      37        3000 : DNDEventDispatcher::DNDEventDispatcher( vcl::Window * pTopWindow ):
      38             :     m_pTopWindow( pTopWindow ),
      39        3000 :     m_pCurrentWindow( NULL )
      40             : {
      41        3000 : }
      42             : 
      43             : // DNDEventDispatcher::~DNDEventDispatcher
      44             : 
      45        5996 : DNDEventDispatcher::~DNDEventDispatcher()
      46             : {
      47        5996 : }
      48             : 
      49           0 : vcl::Window* DNDEventDispatcher::findTopLevelWindow(Point location)
      50             : {
      51           0 :     SolarMutexGuard aSolarGuard;
      52             : 
      53             :     // find the window that is toplevel for this coordinates
      54             :     // because those coordinates come from outside, they must be mirrored if RTL layout is active
      55           0 :     if( Application::GetSettings().GetLayoutRTL() )
      56           0 :         m_pTopWindow->ImplMirrorFramePos( location );
      57           0 :     vcl::Window * pChildWindow = m_pTopWindow->ImplFindWindow( location );
      58             : 
      59           0 :     if( NULL == pChildWindow )
      60           0 :         pChildWindow = m_pTopWindow;
      61             : 
      62           0 :     while( pChildWindow->ImplGetClientWindow() )
      63           0 :         pChildWindow = pChildWindow->ImplGetClientWindow();
      64             : 
      65           0 :     if( pChildWindow->ImplIsAntiparallel() )
      66             :     {
      67           0 :         const OutputDevice *pChildWinOutDev = pChildWindow->GetOutDev();
      68           0 :         pChildWinOutDev->ReMirror( location );
      69             :     }
      70             : 
      71           0 :     return pChildWindow;
      72             : }
      73             : 
      74             : // DNDEventDispatcher::drop
      75             : 
      76           0 : void SAL_CALL DNDEventDispatcher::drop( const DropTargetDropEvent& dtde )
      77             :     throw(RuntimeException, std::exception)
      78             : {
      79           0 :     osl::MutexGuard aImplGuard( m_aMutex );
      80             : 
      81           0 :     Point location( dtde.LocationX, dtde.LocationY );
      82             : 
      83           0 :     vcl::Window* pChildWindow = findTopLevelWindow(location);
      84             : 
      85             :     // handle the case that drop is in an other vcl window than the last dragOver
      86           0 :     if( pChildWindow != m_pCurrentWindow )
      87             :     {
      88             :         // fire dragExit on listeners of previous window
      89           0 :         fireDragExitEvent( m_pCurrentWindow );
      90             : 
      91             :         fireDragEnterEvent( pChildWindow, static_cast < XDropTargetDragContext * > (this),
      92           0 :             dtde.DropAction, location, dtde.SourceActions, m_aDataFlavorList );
      93             :     }
      94             : 
      95           0 :     sal_Int32 nListeners = 0;
      96             : 
      97             :     // send drop event to the child window
      98             :     nListeners = fireDropEvent( pChildWindow, dtde.Context, dtde.DropAction,
      99           0 :         location, dtde.SourceActions, dtde.Transferable );
     100             : 
     101             :     // reject drop if no listeners found
     102           0 :     if( nListeners == 0 ) {
     103             :         OSL_TRACE( "rejecting drop due to missing listeners." );
     104           0 :         dtde.Context->rejectDrop();
     105             :     }
     106             : 
     107             :     // this is a drop -> no further drag overs
     108           0 :     m_pCurrentWindow = NULL;
     109           0 :     m_aDataFlavorList.realloc( 0 );
     110           0 : }
     111             : 
     112             : // DNDEventDispatcher::dragEnter
     113             : 
     114           0 : void SAL_CALL DNDEventDispatcher::dragEnter( const DropTargetDragEnterEvent& dtdee )
     115             :     throw(RuntimeException, std::exception)
     116             : {
     117           0 :     osl::MutexGuard aImplGuard( m_aMutex );
     118           0 :     Point location( dtdee.LocationX, dtdee.LocationY );
     119             : 
     120           0 :     vcl::Window * pChildWindow = findTopLevelWindow(location);
     121             : 
     122             :     // assume pointer write operation to be atomic
     123           0 :     m_pCurrentWindow = pChildWindow;
     124           0 :     m_aDataFlavorList = dtdee.SupportedDataFlavors;
     125             : 
     126             :     // fire dragEnter on listeners of current window
     127             :     sal_Int32 nListeners = fireDragEnterEvent( pChildWindow, dtdee.Context, dtdee.DropAction, location,
     128           0 :         dtdee.SourceActions, dtdee.SupportedDataFlavors );
     129             : 
     130             :     // reject drag if no listener found
     131           0 :     if( nListeners == 0 ) {
     132             :         OSL_TRACE( "rejecting drag enter due to missing listeners." );
     133           0 :         dtdee.Context->rejectDrag();
     134           0 :     }
     135             : 
     136           0 : }
     137             : 
     138             : // DNDEventDispatcher::dragExit
     139             : 
     140           0 : void SAL_CALL DNDEventDispatcher::dragExit( const DropTargetEvent& /*dte*/ )
     141             :     throw(RuntimeException, std::exception)
     142             : {
     143           0 :     osl::MutexGuard aImplGuard( m_aMutex );
     144             : 
     145           0 :     fireDragExitEvent( m_pCurrentWindow );
     146             : 
     147             :     // reset member values
     148           0 :     m_pCurrentWindow = NULL;
     149           0 :     m_aDataFlavorList.realloc( 0 );
     150           0 : }
     151             : 
     152             : // DNDEventDispatcher::dragOver
     153             : 
     154           0 : void SAL_CALL DNDEventDispatcher::dragOver( const DropTargetDragEvent& dtde )
     155             :     throw(RuntimeException, std::exception)
     156             : {
     157           0 :     osl::MutexGuard aImplGuard( m_aMutex );
     158             : 
     159           0 :     Point location( dtde.LocationX, dtde.LocationY );
     160             :     sal_Int32 nListeners;
     161             : 
     162           0 :     vcl::Window * pChildWindow = findTopLevelWindow(location);
     163             : 
     164           0 :     if( pChildWindow != m_pCurrentWindow )
     165             :     {
     166             :         // fire dragExit on listeners of previous window
     167           0 :         fireDragExitEvent( m_pCurrentWindow );
     168             : 
     169             :         // remember new window
     170           0 :         m_pCurrentWindow = pChildWindow;
     171             : 
     172             :         // fire dragEnter on listeners of current window
     173             :         nListeners = fireDragEnterEvent( pChildWindow, dtde.Context, dtde.DropAction, location,
     174           0 :             dtde.SourceActions, m_aDataFlavorList );
     175             :     }
     176             :     else
     177             :     {
     178             :         // fire dragOver on listeners of current window
     179             :         nListeners = fireDragOverEvent( pChildWindow, dtde.Context, dtde.DropAction, location,
     180           0 :             dtde.SourceActions );
     181             :     }
     182             : 
     183             :     // reject drag if no listener found
     184           0 :     if( nListeners == 0 )
     185             :     {
     186             :         OSL_TRACE( "rejecting drag over due to missing listeners." );
     187           0 :         dtde.Context->rejectDrag();
     188           0 :     }
     189           0 : }
     190             : 
     191             : // DNDEventDispatcher::dropActionChanged
     192             : 
     193           0 : void SAL_CALL DNDEventDispatcher::dropActionChanged( const DropTargetDragEvent& dtde )
     194             :     throw(RuntimeException, std::exception)
     195             : {
     196           0 :     osl::MutexGuard aImplGuard( m_aMutex );
     197             : 
     198           0 :     Point location( dtde.LocationX, dtde.LocationY );
     199             :     sal_Int32 nListeners;
     200             : 
     201           0 :     vcl::Window* pChildWindow = findTopLevelWindow(location);
     202             : 
     203           0 :     if( pChildWindow != m_pCurrentWindow )
     204             :     {
     205             :         // fire dragExit on listeners of previous window
     206           0 :         fireDragExitEvent( m_pCurrentWindow );
     207             : 
     208             :         // remember new window
     209           0 :         m_pCurrentWindow = pChildWindow;
     210             : 
     211             :         // fire dragEnter on listeners of current window
     212             :         nListeners = fireDragEnterEvent( pChildWindow, dtde.Context, dtde.DropAction, location,
     213           0 :             dtde.SourceActions, m_aDataFlavorList );
     214             :     }
     215             :     else
     216             :     {
     217             :         // fire dropActionChanged on listeners of current window
     218             :         nListeners = fireDropActionChangedEvent( pChildWindow, dtde.Context, dtde.DropAction, location,
     219           0 :             dtde.SourceActions );
     220             :     }
     221             : 
     222             :     // reject drag if no listener found
     223           0 :     if( nListeners == 0 )
     224             :     {
     225             :         OSL_TRACE( "rejecting dropActionChanged due to missing listeners." );
     226           0 :         dtde.Context->rejectDrag();
     227           0 :     }
     228           0 : }
     229             : 
     230             : // DNDEventDispatcher::dragGestureRecognized
     231             : 
     232           0 : void SAL_CALL DNDEventDispatcher::dragGestureRecognized( const DragGestureEvent& dge )
     233             :     throw(RuntimeException, std::exception)
     234             : {
     235           0 :     osl::MutexGuard aImplGuard( m_aMutex );
     236             : 
     237           0 :     Point origin( dge.DragOriginX, dge.DragOriginY );
     238             : 
     239           0 :     vcl::Window* pChildWindow = findTopLevelWindow(origin);
     240             : 
     241           0 :     fireDragGestureEvent( pChildWindow, dge.DragSource, dge.Event, origin, dge.DragAction );
     242           0 : }
     243             : 
     244             : // DNDEventDispatcher::disposing
     245             : 
     246        2348 : void SAL_CALL DNDEventDispatcher::disposing( const EventObject& )
     247             :     throw(RuntimeException, std::exception)
     248             : {
     249        2348 : }
     250             : 
     251             : // DNDEventDispatcher::acceptDrag
     252             : 
     253           0 : void SAL_CALL DNDEventDispatcher::acceptDrag( sal_Int8 /*dropAction*/ ) throw(RuntimeException, std::exception)
     254             : {
     255           0 : }
     256             : 
     257             : // DNDEventDispatcher::rejectDrag
     258             : 
     259           0 : void SAL_CALL DNDEventDispatcher::rejectDrag() throw(RuntimeException, std::exception)
     260             : {
     261           0 : }
     262             : 
     263             : // DNDEventDispatcher::fireDragEnterEvent
     264             : 
     265           0 : sal_Int32 DNDEventDispatcher::fireDragEnterEvent( vcl::Window *pWindow,
     266             :     const Reference< XDropTargetDragContext >& xContext, const sal_Int8 nDropAction,
     267             :     const Point& rLocation, const sal_Int8 nSourceActions, const Sequence< DataFlavor >& aFlavorList
     268             : )
     269             :     throw(RuntimeException)
     270             : {
     271           0 :     sal_Int32 n = 0;
     272             : 
     273           0 :     if( pWindow && pWindow->IsInputEnabled() && ! pWindow->IsInModalMode() )
     274             :     {
     275           0 :         SolarMutexClearableGuard aSolarGuard;
     276             : 
     277             :         // set an UI lock
     278           0 :         pWindow->IncrementLockCount();
     279             : 
     280             :         // query DropTarget from window
     281           0 :         Reference< XDropTarget > xDropTarget = pWindow->GetDropTarget();
     282             : 
     283           0 :         if( xDropTarget.is() )
     284             :         {
     285             :             // retrieve relative mouse position
     286           0 :             Point relLoc = pWindow->ImplFrameToOutput( rLocation );
     287           0 :             aSolarGuard.clear();
     288             : 
     289           0 :             n = static_cast < DNDListenerContainer * > ( xDropTarget.get() )->fireDragEnterEvent(
     290           0 :                 xContext, nDropAction, relLoc.X(), relLoc.Y(), nSourceActions, aFlavorList );
     291           0 :         }
     292             :     }
     293             : 
     294           0 :     return n;
     295             : }
     296             : 
     297             : // DNDEventDispatcher::fireDragOverEvent
     298             : 
     299           0 : sal_Int32 DNDEventDispatcher::fireDragOverEvent( vcl::Window *pWindow,
     300             :     const Reference< XDropTargetDragContext >& xContext, const sal_Int8 nDropAction,
     301             :     const Point& rLocation, const sal_Int8 nSourceActions
     302             : )
     303             :     throw(RuntimeException)
     304             : {
     305           0 :     sal_Int32 n = 0;
     306             : 
     307           0 :     if( pWindow && pWindow->IsInputEnabled() && ! pWindow->IsInModalMode() )
     308             :     {
     309           0 :         SolarMutexClearableGuard aSolarGuard;
     310             : 
     311             :         // query DropTarget from window
     312           0 :         Reference< XDropTarget > xDropTarget = pWindow->GetDropTarget();
     313             : 
     314           0 :         if( xDropTarget.is() )
     315             :         {
     316             :             // retrieve relative mouse position
     317           0 :             Point relLoc = pWindow->ImplFrameToOutput( rLocation );
     318           0 :             aSolarGuard.clear();
     319             : 
     320           0 :             n = static_cast < DNDListenerContainer * > ( xDropTarget.get() )->fireDragOverEvent(
     321           0 :                 xContext, nDropAction, relLoc.X(), relLoc.Y(), nSourceActions );
     322           0 :         }
     323             :     }
     324             : 
     325           0 :     return n;
     326             : }
     327             : 
     328             : // DNDEventDispatcher::fireDragExitEvent
     329             : 
     330           0 : sal_Int32 DNDEventDispatcher::fireDragExitEvent( vcl::Window *pWindow ) throw(RuntimeException)
     331             : {
     332           0 :     sal_Int32 n = 0;
     333             : 
     334           0 :     if( pWindow && pWindow->IsInputEnabled() && ! pWindow->IsInModalMode() )
     335             :     {
     336           0 :         SolarMutexClearableGuard aGuard;
     337             : 
     338             :         // query DropTarget from window
     339           0 :         Reference< XDropTarget > xDropTarget = pWindow->GetDropTarget();
     340             : 
     341           0 :         aGuard.clear();
     342             : 
     343           0 :         if( xDropTarget.is() )
     344           0 :             n = static_cast < DNDListenerContainer * > ( xDropTarget.get() )->fireDragExitEvent();
     345             : 
     346             :         // release UI lock
     347           0 :         pWindow->DecrementLockCount();
     348             :     }
     349             : 
     350           0 :     return n;
     351             : }
     352             : 
     353             : // DNDEventDispatcher::fireDropActionChangedEvent
     354             : 
     355           0 : sal_Int32 DNDEventDispatcher::fireDropActionChangedEvent( vcl::Window *pWindow,
     356             :     const Reference< XDropTargetDragContext >& xContext, const sal_Int8 nDropAction,
     357             :     const Point& rLocation, const sal_Int8 nSourceActions
     358             : )
     359             :     throw(RuntimeException)
     360             : {
     361           0 :     sal_Int32 n = 0;
     362             : 
     363           0 :     if( pWindow && pWindow->IsInputEnabled() && ! pWindow->IsInModalMode() )
     364             :     {
     365           0 :         SolarMutexClearableGuard aGuard;
     366             : 
     367             :         // query DropTarget from window
     368           0 :         Reference< XDropTarget > xDropTarget = pWindow->GetDropTarget();
     369             : 
     370           0 :         if( xDropTarget.is() )
     371             :         {
     372             :             // retrieve relative mouse position
     373           0 :             Point relLoc = pWindow->ImplFrameToOutput( rLocation );
     374           0 :             aGuard.clear();
     375             : 
     376           0 :             n = static_cast < DNDListenerContainer * > ( xDropTarget.get() )->fireDropActionChangedEvent(
     377           0 :                 xContext, nDropAction, relLoc.X(), relLoc.Y(), nSourceActions );
     378           0 :         }
     379             :     }
     380             : 
     381           0 :     return n;
     382             : }
     383             : 
     384             : // DNDEventDispatcher::fireDropEvent
     385             : 
     386           0 : sal_Int32 DNDEventDispatcher::fireDropEvent( vcl::Window *pWindow,
     387             :     const Reference< XDropTargetDropContext >& xContext, const sal_Int8 nDropAction, const Point& rLocation,
     388             :     const sal_Int8 nSourceActions, const Reference< XTransferable >& xTransferable
     389             : )
     390             :     throw(RuntimeException)
     391             : {
     392           0 :     sal_Int32 n = 0;
     393             : 
     394           0 :     if( pWindow && pWindow->IsInputEnabled() && ! pWindow->IsInModalMode() )
     395             :     {
     396           0 :         SolarMutexClearableGuard aGuard;
     397             : 
     398             :         // query DropTarget from window
     399           0 :         Reference< XDropTarget > xDropTarget = pWindow->GetDropTarget();
     400             : 
     401             :         // window may be destroyed in drop event handler
     402           0 :         ImplDelData         aDelData;
     403           0 :         pWindow->ImplAddDel( &aDelData );
     404             : 
     405           0 :         if( xDropTarget.is() )
     406             :         {
     407             :             // retrieve relative mouse position
     408           0 :             Point relLoc = pWindow->ImplFrameToOutput( rLocation );
     409           0 :             aGuard.clear();
     410             : 
     411           0 :             n = static_cast < DNDListenerContainer * > ( xDropTarget.get() )->fireDropEvent(
     412           0 :                 xContext, nDropAction, relLoc.X(), relLoc.Y(), nSourceActions, xTransferable );
     413             :         }
     414             : 
     415           0 :         if ( !aDelData.IsDead() )
     416             :         {
     417           0 :             pWindow->ImplRemoveDel( &aDelData );
     418             :             // release UI lock
     419           0 :             pWindow->DecrementLockCount();
     420           0 :         }
     421             : 
     422             :     }
     423             : 
     424           0 :     return n;
     425             : }
     426             : 
     427             : // DNDEventDispatcher::fireDragGestureRecognized
     428             : 
     429           0 : sal_Int32 DNDEventDispatcher::fireDragGestureEvent( vcl::Window *pWindow,
     430             :     const Reference< XDragSource >& xSource, const Any event,
     431             :     const Point& rOrigin, const sal_Int8 nDragAction
     432             : )
     433             :     throw(::com::sun::star::uno::RuntimeException)
     434             : {
     435           0 :     sal_Int32 n = 0;
     436             : 
     437           0 :     if( pWindow && pWindow->IsInputEnabled() && ! pWindow->IsInModalMode() )
     438             :     {
     439           0 :         SolarMutexClearableGuard aGuard;
     440             : 
     441             :         // query DropTarget from window
     442           0 :         Reference< XDragGestureRecognizer > xDragGestureRecognizer = pWindow->GetDragGestureRecognizer();
     443             : 
     444           0 :         if( xDragGestureRecognizer.is() )
     445             :         {
     446             :             // retrieve relative mouse position
     447           0 :             Point relLoc = pWindow->ImplFrameToOutput( rOrigin );
     448           0 :             aGuard.clear();
     449             : 
     450           0 :             n = static_cast < DNDListenerContainer * > ( xDragGestureRecognizer.get() )->fireDragGestureEvent(
     451           0 :                 nDragAction, relLoc.X(), relLoc.Y(), xSource, event );
     452             :         }
     453             : 
     454             :         // release UI lock
     455           0 :         pWindow->DecrementLockCount();
     456             :     }
     457             : 
     458           0 :     return n;
     459        1233 : }
     460             : 
     461             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10