LCOV - code coverage report
Current view: top level - sc/source/ui/vba - vbaeventshelper.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 289 410 70.5 %
Date: 2014-11-03 Functions: 33 45 73.3 %
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 "vbaeventshelper.hxx"
      21             : 
      22             : #include <com/sun/star/awt/XTopWindow.hpp>
      23             : #include <com/sun/star/awt/XTopWindowListener.hpp>
      24             : #include <com/sun/star/awt/XWindowListener.hpp>
      25             : #include <com/sun/star/frame/XBorderResizeListener.hpp>
      26             : #include <com/sun/star/frame/XControllerBorder.hpp>
      27             : #include <com/sun/star/script/ModuleType.hpp>
      28             : #include <com/sun/star/script/vba/VBAEventId.hpp>
      29             : #include <com/sun/star/sheet/XCellRangeAddressable.hpp>
      30             : #include <com/sun/star/sheet/XSheetCellRangeContainer.hpp>
      31             : #include <com/sun/star/table/XCellRange.hpp>
      32             : #include <com/sun/star/util/XChangesListener.hpp>
      33             : #include <com/sun/star/util/XChangesNotifier.hpp>
      34             : 
      35             : #include <cppuhelper/implbase4.hxx>
      36             : #include <toolkit/helper/vclunohelper.hxx>
      37             : #include <unotools/eventcfg.hxx>
      38             : #include <vcl/svapp.hxx>
      39             : #include <vcl/window.hxx>
      40             : 
      41             : #include "cellsuno.hxx"
      42             : #include "convuno.hxx"
      43             : #include "vbaapplication.hxx"
      44             : 
      45             : using namespace ::com::sun::star;
      46             : using namespace ::com::sun::star::script::vba::VBAEventId;
      47             : using namespace ::ooo::vba;
      48             : 
      49             : namespace {
      50             : 
      51             : /** Extracts a sheet index from the specified element of the passed sequence.
      52             :     The element may be an integer, a Calc range or ranges object, or a VBA Range object. */
      53        2008 : SCTAB lclGetTabFromArgs( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) throw (lang::IllegalArgumentException, uno::RuntimeException)
      54             : {
      55        2008 :     VbaEventsHelperBase::checkArgument( rArgs, nIndex );
      56             : 
      57             :     // first try to extract a sheet index
      58        2008 :     sal_Int32 nTab = -1;
      59        2008 :     if( rArgs[ nIndex ] >>= nTab )
      60             :     {
      61         754 :         if( (nTab < 0) || (nTab > MAXTAB) )
      62           0 :             throw lang::IllegalArgumentException();
      63         754 :         return static_cast< SCTAB >( nTab );
      64             :     }
      65             : 
      66             :     // try VBA Range object
      67        1254 :     uno::Reference< excel::XRange > xVbaRange = getXSomethingFromArgs< excel::XRange >( rArgs, nIndex );
      68        1254 :     if( xVbaRange.is() )
      69             :     {
      70        1092 :         uno::Reference< XHelperInterface > xVbaHelper( xVbaRange, uno::UNO_QUERY_THROW );
      71             :         // TODO: in the future, the parent may be an excel::XChart (chart sheet) -> will there be a common base interface?
      72        2184 :         uno::Reference< excel::XWorksheet > xVbaSheet( xVbaHelper->getParent(), uno::UNO_QUERY_THROW );
      73             :         // VBA sheet index is 1-based
      74        2184 :         return static_cast< SCTAB >( xVbaSheet->getIndex() - 1 );
      75             :     }
      76             : 
      77             :     // try single UNO range object
      78         324 :     uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable = getXSomethingFromArgs< sheet::XCellRangeAddressable >( rArgs, nIndex );
      79         162 :     if( xCellRangeAddressable.is() )
      80         140 :         return xCellRangeAddressable->getRangeAddress().Sheet;
      81             : 
      82             :     // at last, try UNO range list
      83          44 :     uno::Reference< sheet::XSheetCellRangeContainer > xRanges = getXSomethingFromArgs< sheet::XSheetCellRangeContainer >( rArgs, nIndex );
      84          22 :     if( xRanges.is() )
      85             :     {
      86           6 :         uno::Sequence< table::CellRangeAddress > aRangeAddresses = xRanges->getRangeAddresses();
      87           6 :         if( aRangeAddresses.getLength() > 0 )
      88           6 :             return aRangeAddresses[ 0 ].Sheet;
      89             :     }
      90             : 
      91        1270 :     throw lang::IllegalArgumentException();
      92             : }
      93             : 
      94             : /** Returns the AWT container window of the passed controller. */
      95         100 : uno::Reference< awt::XWindow > lclGetWindowForController( const uno::Reference< frame::XController >& rxController )
      96             : {
      97         100 :     if( rxController.is() ) try
      98             :     {
      99         100 :         uno::Reference< frame::XFrame > xFrame( rxController->getFrame(), uno::UNO_SET_THROW );
     100         100 :         return xFrame->getContainerWindow();
     101             :     }
     102           0 :     catch( uno::Exception& )
     103             :     {
     104             :     }
     105           0 :     return 0;
     106             : }
     107             : 
     108             : } // namespace
     109             : 
     110             : typedef ::cppu::WeakImplHelper4< awt::XTopWindowListener, awt::XWindowListener, frame::XBorderResizeListener, util::XChangesListener > ScVbaEventListener_BASE;
     111             : 
     112             : // This class is to process Workbook window related event
     113             : class ScVbaEventListener : public ScVbaEventListener_BASE
     114             : {
     115             : public :
     116             :     ScVbaEventListener( ScVbaEventsHelper& rVbaEvents, const uno::Reference< frame::XModel >& rxModel, ScDocShell* pDocShell );
     117             :     virtual ~ScVbaEventListener();
     118             : 
     119             :     /** Starts listening to the passed document controller. */
     120             :     void startControllerListening( const uno::Reference< frame::XController >& rxController );
     121             :     /** Stops listening to the passed document controller. */
     122             :     void stopControllerListening( const uno::Reference< frame::XController >& rxController );
     123             : 
     124             :     // XTopWindowListener
     125             :     virtual void SAL_CALL windowOpened( const lang::EventObject& rEvent ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE;
     126             :     virtual void SAL_CALL windowClosing( const lang::EventObject& rEvent ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE;
     127             :     virtual void SAL_CALL windowClosed( const lang::EventObject& rEvent ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE;
     128             :     virtual void SAL_CALL windowMinimized( const lang::EventObject& rEvent ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE;
     129             :     virtual void SAL_CALL windowNormalized( const lang::EventObject& rEvent ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE;
     130             :     virtual void SAL_CALL windowActivated( const lang::EventObject& rEvent ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE;
     131             :     virtual void SAL_CALL windowDeactivated( const lang::EventObject& rEvent ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE;
     132             : 
     133             :     // XWindowListener
     134             :     virtual void SAL_CALL windowResized( const awt::WindowEvent& rEvent ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE;
     135             :     virtual void SAL_CALL windowMoved( const awt::WindowEvent& rEvent ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE;
     136             :     virtual void SAL_CALL windowShown( const lang::EventObject& rEvent ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE;
     137             :     virtual void SAL_CALL windowHidden( const lang::EventObject& rEvent ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE;
     138             : 
     139             :     // XBorderResizeListener
     140             :     virtual void SAL_CALL borderWidthsChanged( const uno::Reference< uno::XInterface >& rSource, const frame::BorderWidths& aNewSize ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE;
     141             : 
     142             :     // XChangesListener
     143             :     virtual void SAL_CALL changesOccurred( const util::ChangesEvent& rEvent ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE;
     144             : 
     145             :     // XEventListener
     146             :     virtual void SAL_CALL disposing( const lang::EventObject& rEvent ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE;
     147             : 
     148             : private:
     149             :     /** Starts listening to the document model. */
     150             :     void startModelListening();
     151             :     /** Stops listening to the document model. */
     152             :     void stopModelListening();
     153             : 
     154             :     /** Returns the controller for the passed VCL window. */
     155             :     uno::Reference< frame::XController > getControllerForWindow( vcl::Window* pWindow ) const;
     156             : 
     157             :     /** Calls the Workbook_Window[Activate|Deactivate] event handler. */
     158             :     void processWindowActivateEvent( vcl::Window* pWindow, bool bActivate );
     159             :     /** Posts a Workbook_WindowResize user event. */
     160             :     void postWindowResizeEvent( vcl::Window* pWindow );
     161             :     /** Callback link for Application::PostUserEvent(). */
     162             :     DECL_LINK( processWindowResizeEvent, vcl::Window* );
     163             : 
     164             : private:
     165             :     typedef ::std::map< vcl::Window*, uno::Reference< frame::XController > > WindowControllerMap;
     166             : 
     167             :     ::osl::Mutex        maMutex;
     168             :     ScVbaEventsHelper&  mrVbaEvents;
     169             :     uno::Reference< frame::XModel > mxModel;
     170             :     ScDocShell*         mpDocShell;
     171             :     WindowControllerMap maControllers;          /// Maps VCL top windows to their controllers.
     172             :     vcl::Window*             mpActiveWindow;         /// Currently activated window, to prevent multiple (de)activation.
     173             :     bool                mbWindowResized;        /// True = window resize system event processed.
     174             :     bool                mbBorderChanged;        /// True = borders changed system event processed.
     175             :     bool                mbDisposed;
     176             : };
     177             : 
     178          50 : ScVbaEventListener::ScVbaEventListener( ScVbaEventsHelper& rVbaEvents, const uno::Reference< frame::XModel >& rxModel, ScDocShell* pDocShell ) :
     179             :     mrVbaEvents( rVbaEvents ),
     180             :     mxModel( rxModel ),
     181             :     mpDocShell( pDocShell ),
     182             :     mpActiveWindow( 0 ),
     183             :     mbWindowResized( false ),
     184             :     mbBorderChanged( false ),
     185          50 :     mbDisposed( !rxModel.is() )
     186             : {
     187          50 :     if( !mxModel.is() )
     188          50 :         return;
     189             : 
     190          50 :     startModelListening();
     191             :     try
     192             :     {
     193          50 :         uno::Reference< frame::XController > xController( mxModel->getCurrentController(), uno::UNO_QUERY_THROW );
     194          50 :         startControllerListening( xController );
     195             :     }
     196           0 :     catch( uno::Exception& )
     197             :     {
     198             :     }
     199             : }
     200             : 
     201           0 : ScVbaEventListener::~ScVbaEventListener()
     202             : {
     203           0 : }
     204             : 
     205          50 : void ScVbaEventListener::startControllerListening( const uno::Reference< frame::XController >& rxController )
     206             : {
     207          50 :     ::osl::MutexGuard aGuard( maMutex );
     208             : 
     209         100 :     uno::Reference< awt::XWindow > xWindow = lclGetWindowForController( rxController );
     210          50 :     if( xWindow.is() )
     211          50 :         try { xWindow->addWindowListener( this ); } catch( uno::Exception& ) {}
     212             : 
     213         100 :     uno::Reference< awt::XTopWindow > xTopWindow( xWindow, uno::UNO_QUERY );
     214          50 :     if( xTopWindow.is() )
     215          50 :         try { xTopWindow->addTopWindowListener( this ); } catch( uno::Exception& ) {}
     216             : 
     217         100 :     uno::Reference< frame::XControllerBorder > xControllerBorder( rxController, uno::UNO_QUERY );
     218          50 :     if( xControllerBorder.is() )
     219          50 :         try { xControllerBorder->addBorderResizeListener( this ); } catch( uno::Exception& ) {}
     220             : 
     221          50 :     if( vcl::Window* pWindow = VCLUnoHelper::GetWindow( xWindow ) )
     222         100 :         maControllers[ pWindow ] = rxController;
     223          50 : }
     224             : 
     225          50 : void ScVbaEventListener::stopControllerListening( const uno::Reference< frame::XController >& rxController )
     226             : {
     227          50 :     ::osl::MutexGuard aGuard( maMutex );
     228             : 
     229         100 :     uno::Reference< awt::XWindow > xWindow = lclGetWindowForController( rxController );
     230          50 :     if( xWindow.is() )
     231          50 :         try { xWindow->removeWindowListener( this ); } catch( uno::Exception& ) {}
     232             : 
     233         100 :     uno::Reference< awt::XTopWindow > xTopWindow( xWindow, uno::UNO_QUERY );
     234          50 :     if( xTopWindow.is() )
     235          50 :         try { xTopWindow->removeTopWindowListener( this ); } catch( uno::Exception& ) {}
     236             : 
     237         100 :     uno::Reference< frame::XControllerBorder > xControllerBorder( rxController, uno::UNO_QUERY );
     238          50 :     if( xControllerBorder.is() )
     239          50 :         try { xControllerBorder->removeBorderResizeListener( this ); } catch( uno::Exception& ) {}
     240             : 
     241          50 :     if( vcl::Window* pWindow = VCLUnoHelper::GetWindow( xWindow ) )
     242             :     {
     243          50 :         maControllers.erase( pWindow );
     244          50 :         if( pWindow == mpActiveWindow )
     245          10 :             mpActiveWindow = 0;
     246          50 :     }
     247          50 : }
     248             : 
     249           8 : void SAL_CALL ScVbaEventListener::windowOpened( const lang::EventObject& /*rEvent*/ ) throw (uno::RuntimeException, std::exception)
     250             : {
     251           8 : }
     252             : 
     253           0 : void SAL_CALL ScVbaEventListener::windowClosing( const lang::EventObject& /*rEvent*/ ) throw (uno::RuntimeException, std::exception)
     254             : {
     255           0 : }
     256             : 
     257           8 : void SAL_CALL ScVbaEventListener::windowClosed( const lang::EventObject& /*rEvent*/ ) throw (uno::RuntimeException, std::exception)
     258             : {
     259           8 : }
     260             : 
     261           0 : void SAL_CALL ScVbaEventListener::windowMinimized( const lang::EventObject& /*rEvent*/ ) throw (uno::RuntimeException, std::exception)
     262             : {
     263           0 : }
     264             : 
     265           0 : void SAL_CALL ScVbaEventListener::windowNormalized( const lang::EventObject& /*rEvent*/ ) throw (uno::RuntimeException, std::exception)
     266             : {
     267           0 : }
     268             : 
     269         112 : void SAL_CALL ScVbaEventListener::windowActivated( const lang::EventObject& rEvent ) throw (uno::RuntimeException, std::exception)
     270             : {
     271         112 :     ::osl::MutexGuard aGuard( maMutex );
     272             : 
     273         112 :     if( !mbDisposed )
     274             :     {
     275         112 :         uno::Reference< awt::XWindow > xWindow( rEvent.Source, uno::UNO_QUERY );
     276         112 :         vcl::Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
     277             :         OSL_TRACE( "ScVbaEventListener::windowActivated - pWindow = 0x%p, mpActiveWindow = 0x%p", pWindow, mpActiveWindow );
     278             :         // do not fire activation event multiple time for the same window
     279         112 :         if( pWindow && (pWindow != mpActiveWindow) )
     280             :         {
     281             :             // if another window is active, fire deactivation event first
     282         112 :             if( mpActiveWindow )
     283           0 :                 processWindowActivateEvent( mpActiveWindow, false );
     284             :             // fire activation event for the new window
     285         112 :             processWindowActivateEvent( pWindow, true );
     286         112 :             mpActiveWindow = pWindow;
     287         112 :         }
     288         112 :     }
     289         112 : }
     290             : 
     291         112 : void SAL_CALL ScVbaEventListener::windowDeactivated( const lang::EventObject& rEvent ) throw (uno::RuntimeException, std::exception)
     292             : {
     293         112 :     ::osl::MutexGuard aGuard( maMutex );
     294             : 
     295         112 :     if( !mbDisposed )
     296             :     {
     297         112 :         uno::Reference< awt::XWindow > xWindow( rEvent.Source, uno::UNO_QUERY );
     298         112 :         vcl::Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
     299             :         OSL_TRACE( "ScVbaEventListener::windowDeactivated - pWindow = 0x%p, mpActiveWindow = 0x%p", pWindow, mpActiveWindow );
     300             :         // do not fire the deactivation event, if the window is not active (prevent multiple deactivation)
     301         112 :         if( pWindow && (pWindow == mpActiveWindow) )
     302         102 :             processWindowActivateEvent( pWindow, false );
     303             :         // forget pointer to the active window
     304         112 :         mpActiveWindow = 0;
     305         112 :     }
     306         112 : }
     307             : 
     308          58 : void SAL_CALL ScVbaEventListener::windowResized( const awt::WindowEvent& rEvent ) throw (uno::RuntimeException, std::exception)
     309             : {
     310          58 :     ::osl::MutexGuard aGuard( maMutex );
     311             : 
     312          58 :     mbWindowResized = true;
     313          58 :     if( !mbDisposed && mbBorderChanged )
     314             :     {
     315          12 :         uno::Reference< awt::XWindow > xWindow( rEvent.Source, uno::UNO_QUERY );
     316          12 :         postWindowResizeEvent( VCLUnoHelper::GetWindow( xWindow ) );
     317          58 :     }
     318          58 : }
     319             : 
     320          58 : void SAL_CALL ScVbaEventListener::windowMoved( const awt::WindowEvent& /*rEvent*/ ) throw (uno::RuntimeException, std::exception)
     321             : {
     322          58 : }
     323             : 
     324           8 : void SAL_CALL ScVbaEventListener::windowShown( const lang::EventObject& /*rEvent*/ ) throw (uno::RuntimeException, std::exception)
     325             : {
     326           8 : }
     327             : 
     328           8 : void SAL_CALL ScVbaEventListener::windowHidden( const lang::EventObject& /*rEvent*/ ) throw (uno::RuntimeException, std::exception)
     329             : {
     330           8 : }
     331             : 
     332          72 : void SAL_CALL ScVbaEventListener::borderWidthsChanged( const uno::Reference< uno::XInterface >& rSource, const frame::BorderWidths& /*aNewSize*/ ) throw (uno::RuntimeException, std::exception)
     333             : {
     334          72 :     ::osl::MutexGuard aGuard( maMutex );
     335             : 
     336          72 :     mbBorderChanged = true;
     337          72 :     if( !mbDisposed && mbWindowResized )
     338             :     {
     339           0 :         uno::Reference< frame::XController > xController( rSource, uno::UNO_QUERY );
     340           0 :         uno::Reference< awt::XWindow > xWindow = lclGetWindowForController( xController );
     341           0 :         postWindowResizeEvent( VCLUnoHelper::GetWindow( xWindow ) );
     342          72 :     }
     343          72 : }
     344             : 
     345           0 : void SAL_CALL ScVbaEventListener::changesOccurred( const util::ChangesEvent& rEvent ) throw (uno::RuntimeException, std::exception)
     346             : {
     347           0 :     ::osl::MutexGuard aGuard( maMutex );
     348             : 
     349           0 :     sal_Int32 nCount = rEvent.Changes.getLength();
     350           0 :     if( mbDisposed || !mpDocShell || (nCount == 0) )
     351           0 :         return;
     352             : 
     353           0 :     util::ElementChange aChange = rEvent.Changes[ 0 ];
     354           0 :     OUString sOperation;
     355           0 :     aChange.Accessor >>= sOperation;
     356           0 :     if( !sOperation.equalsIgnoreAsciiCase("cell-change") )
     357           0 :         return;
     358             : 
     359           0 :     if( nCount == 1 )
     360             :     {
     361           0 :         uno::Reference< table::XCellRange > xRangeObj;
     362           0 :         aChange.ReplacedElement >>= xRangeObj;
     363           0 :         if( xRangeObj.is() )
     364             :         {
     365           0 :             uno::Sequence< uno::Any > aArgs( 1 );
     366           0 :             aArgs[0] <<= xRangeObj;
     367           0 :             mrVbaEvents.processVbaEventNoThrow( WORKSHEET_CHANGE, aArgs );
     368             :         }
     369           0 :         return;
     370             :     }
     371             : 
     372           0 :     ScRangeList aRangeList;
     373           0 :     for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex )
     374             :     {
     375           0 :         aChange = rEvent.Changes[ nIndex ];
     376           0 :         aChange.Accessor >>= sOperation;
     377           0 :         uno::Reference< table::XCellRange > xRangeObj;
     378           0 :         aChange.ReplacedElement >>= xRangeObj;
     379           0 :         if( xRangeObj.is() && sOperation.equalsIgnoreAsciiCase("cell-change") )
     380             :         {
     381           0 :             uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable( xRangeObj, uno::UNO_QUERY );
     382           0 :             if( xCellRangeAddressable.is() )
     383             :             {
     384           0 :                 ScRange aRange;
     385           0 :                 ScUnoConversion::FillScRange( aRange, xCellRangeAddressable->getRangeAddress() );
     386           0 :                 aRangeList.Append( aRange );
     387           0 :             }
     388             :         }
     389           0 :     }
     390             : 
     391           0 :     if (!aRangeList.empty())
     392             :     {
     393           0 :         uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( mpDocShell, aRangeList ) );
     394           0 :         uno::Sequence< uno::Any > aArgs(1);
     395           0 :         aArgs[0] <<= xRanges;
     396           0 :         mrVbaEvents.processVbaEventNoThrow( WORKSHEET_CHANGE, aArgs );
     397           0 :     }
     398             : }
     399             : 
     400          50 : void SAL_CALL ScVbaEventListener::disposing( const lang::EventObject& rEvent ) throw (uno::RuntimeException, std::exception)
     401             : {
     402          50 :     ::osl::MutexGuard aGuard( maMutex );
     403             : 
     404          50 :     uno::Reference< frame::XModel > xModel( rEvent.Source, uno::UNO_QUERY );
     405          50 :     if( xModel.is() )
     406             :     {
     407             :         OSL_ENSURE( xModel.get() == mxModel.get(), "ScVbaEventListener::disposing - disposing from unknown model" );
     408           0 :         stopModelListening();
     409           0 :         mbDisposed = true;
     410           0 :         return;
     411             :     }
     412             : 
     413          50 :     uno::Reference< frame::XController > xController( rEvent.Source, uno::UNO_QUERY );
     414          50 :     if( xController.is() )
     415             :     {
     416          50 :         stopControllerListening( xController );
     417          50 :         return;
     418           0 :     }
     419             : }
     420             : 
     421             : // private --------------------------------------------------------------------
     422             : 
     423          50 : void ScVbaEventListener::startModelListening()
     424             : {
     425             :     try
     426             :     {
     427          50 :         uno::Reference< util::XChangesNotifier > xChangesNotifier( mxModel, uno::UNO_QUERY_THROW );
     428          50 :         xChangesNotifier->addChangesListener( this );
     429             :     }
     430           0 :     catch( uno::Exception& )
     431             :     {
     432             :     }
     433          50 : }
     434             : 
     435           0 : void ScVbaEventListener::stopModelListening()
     436             : {
     437             :     try
     438             :     {
     439           0 :         uno::Reference< util::XChangesNotifier > xChangesNotifier( mxModel, uno::UNO_QUERY_THROW );
     440           0 :         xChangesNotifier->removeChangesListener( this );
     441             :     }
     442           0 :     catch( uno::Exception& )
     443             :     {
     444             :     }
     445           0 : }
     446             : 
     447         222 : uno::Reference< frame::XController > ScVbaEventListener::getControllerForWindow( vcl::Window* pWindow ) const
     448             : {
     449         222 :     WindowControllerMap::const_iterator aIt = maControllers.find( pWindow );
     450         222 :     return (aIt == maControllers.end()) ? uno::Reference< frame::XController >() : aIt->second;
     451             : }
     452             : 
     453         214 : void ScVbaEventListener::processWindowActivateEvent( vcl::Window* pWindow, bool bActivate )
     454             : {
     455         214 :     uno::Reference< frame::XController > xController = getControllerForWindow( pWindow );
     456         214 :     if( xController.is() )
     457             :     {
     458         214 :         uno::Sequence< uno::Any > aArgs( 1 );
     459         214 :         aArgs[ 0 ] <<= xController;
     460         214 :         mrVbaEvents.processVbaEventNoThrow( bActivate ? WORKBOOK_WINDOWACTIVATE : WORKBOOK_WINDOWDEACTIVATE, aArgs );
     461         214 :     }
     462         214 : }
     463             : 
     464          12 : void ScVbaEventListener::postWindowResizeEvent( vcl::Window* pWindow )
     465             : {
     466             :     // check that the passed window is still alive (it must be registered in maControllers)
     467          12 :     if( pWindow && (maControllers.count( pWindow ) > 0) )
     468             :     {
     469          12 :         mbWindowResized = mbBorderChanged = false;
     470          12 :         acquire();  // ensure we don't get deleted before the timer fires
     471          12 :         Application::PostUserEvent( LINK( this, ScVbaEventListener, processWindowResizeEvent ), pWindow );
     472             :     }
     473          12 : }
     474             : 
     475          24 : IMPL_LINK( ScVbaEventListener, processWindowResizeEvent, vcl::Window*, EMPTYARG pWindow )
     476             : {
     477          12 :     ::osl::MutexGuard aGuard( maMutex );
     478             : 
     479             :     /*  Check that the passed window is still alive (it must be registered in
     480             :         maControllers). While closing a document, postWindowResizeEvent() may
     481             :         be called on the last window which posts a user event via
     482             :         Application::PostUserEvent to call this event handler. VCL will trigger
     483             :         the handler some time later. Sometimes, the window gets deleted before.
     484             :         This is handled via the disposing() function which removes the window
     485             :         pointer from the member maControllers. Thus, checking whether
     486             :         maControllers contains pWindow ensures that the window is still alive. */
     487          12 :     if( !mbDisposed && pWindow && (maControllers.count( pWindow ) > 0) )
     488             :     {
     489             :         // do not fire event unless all mouse buttons have been released
     490           8 :         vcl::Window::PointerState aPointerState = pWindow->GetPointerState();
     491           8 :         if( (aPointerState.mnState & (MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT)) == 0 )
     492             :         {
     493           8 :             uno::Reference< frame::XController > xController = getControllerForWindow( pWindow );
     494           8 :             if( xController.is() )
     495             :             {
     496           8 :                 uno::Sequence< uno::Any > aArgs( 1 );
     497           8 :                 aArgs[ 0 ] <<= xController;
     498             :                 // #163419# do not throw exceptions into application core
     499           8 :                 mrVbaEvents.processVbaEventNoThrow( WORKBOOK_WINDOWRESIZE, aArgs );
     500           8 :             }
     501             :         }
     502             :     }
     503          12 :     release();
     504          12 :     return 0;
     505             : }
     506             : 
     507          52 : ScVbaEventsHelper::ScVbaEventsHelper( const uno::Sequence< uno::Any >& rArgs, const uno::Reference< uno::XComponentContext >& xContext ) :
     508             :     VbaEventsHelperBase( rArgs, xContext ),
     509          52 :     mbOpened( false )
     510             : {
     511          52 :     mpDocShell = dynamic_cast< ScDocShell* >( mpShell ); // mpShell from base class
     512          52 :     mpDoc = mpDocShell ? &mpDocShell->GetDocument() : 0;
     513             : 
     514          52 :     if( !mxModel.is() || !mpDocShell || !mpDoc )
     515          52 :         return;
     516             : 
     517             : #define REGISTER_EVENT( eventid, moduletype, classname, eventname, cancelindex, worksheet ) \
     518             :     registerEventHandler( eventid, moduletype, classname "_" eventname, cancelindex, uno::Any( worksheet ) )
     519             : #define REGISTER_AUTO_EVENT( eventid, eventname ) \
     520             :     REGISTER_EVENT( AUTO_##eventid, script::ModuleType::NORMAL, "Auto", eventname, -1, false )
     521             : #define REGISTER_WORKBOOK_EVENT( eventid, eventname, cancelindex ) \
     522             :     REGISTER_EVENT( WORKBOOK_##eventid, script::ModuleType::DOCUMENT, "Workbook", eventname, cancelindex, false )
     523             : #define REGISTER_WORKSHEET_EVENT( eventid, eventname, cancelindex ) \
     524             :     REGISTER_EVENT( WORKSHEET_##eventid, script::ModuleType::DOCUMENT, "Worksheet", eventname, cancelindex, true ); \
     525             :     REGISTER_EVENT( (USERDEFINED_START + WORKSHEET_##eventid), script::ModuleType::DOCUMENT, "Workbook", "Sheet" eventname, (((cancelindex) >= 0) ? ((cancelindex) + 1) : -1), false )
     526             : 
     527             :     // global
     528          52 :     REGISTER_AUTO_EVENT( OPEN,  "Open" );
     529          52 :     REGISTER_AUTO_EVENT( CLOSE, "Close" );
     530             : 
     531             :     // Workbook
     532          52 :     REGISTER_WORKBOOK_EVENT( ACTIVATE,            "Activate",           -1 );
     533          52 :     REGISTER_WORKBOOK_EVENT( DEACTIVATE,          "Deactivate",         -1 );
     534          52 :     REGISTER_WORKBOOK_EVENT( OPEN,                "Open",               -1 );
     535          52 :     REGISTER_WORKBOOK_EVENT( BEFORECLOSE,         "BeforeClose",        0 );
     536          52 :     REGISTER_WORKBOOK_EVENT( BEFOREPRINT,         "BeforePrint",        0 );
     537          52 :     REGISTER_WORKBOOK_EVENT( BEFORESAVE,          "BeforeSave",         1 );
     538          52 :     REGISTER_WORKBOOK_EVENT( AFTERSAVE,           "AfterSave",          -1 );
     539          52 :     REGISTER_WORKBOOK_EVENT( NEWSHEET,            "NewSheet",           -1 );
     540          52 :     REGISTER_WORKBOOK_EVENT( WINDOWACTIVATE,      "WindowActivate",     -1 );
     541          52 :     REGISTER_WORKBOOK_EVENT( WINDOWDEACTIVATE,    "WindowDeactivate",   -1 );
     542          52 :     REGISTER_WORKBOOK_EVENT( WINDOWRESIZE,        "WindowResize",       -1 );
     543             : 
     544             :     // Worksheet events. All events have a corresponding workbook event.
     545          52 :     REGISTER_WORKSHEET_EVENT( ACTIVATE,           "Activate",           -1 );
     546          52 :     REGISTER_WORKSHEET_EVENT( DEACTIVATE,         "Deactivate",         -1 );
     547          52 :     REGISTER_WORKSHEET_EVENT( BEFOREDOUBLECLICK,  "BeforeDoubleClick",  1 );
     548          52 :     REGISTER_WORKSHEET_EVENT( BEFORERIGHTCLICK,   "BeforeRightClick",   1 );
     549          52 :     REGISTER_WORKSHEET_EVENT( CALCULATE,          "Calculate",          -1 );
     550          52 :     REGISTER_WORKSHEET_EVENT( CHANGE,             "Change",             -1 );
     551          52 :     REGISTER_WORKSHEET_EVENT( SELECTIONCHANGE,    "SelectionChange",    -1 );
     552          52 :     REGISTER_WORKSHEET_EVENT( FOLLOWHYPERLINK,    "FollowHyperlink",    -1 );
     553             : 
     554             : #undef REGISTER_WORKSHEET_EVENT
     555             : #undef REGISTER_WORKBOOK_EVENT
     556             : #undef REGISTER_AUTO_EVENT
     557             : #undef REGISTER_EVENT
     558             : }
     559             : 
     560           0 : ScVbaEventsHelper::~ScVbaEventsHelper()
     561             : {
     562           0 : }
     563             : 
     564         510 : void SAL_CALL ScVbaEventsHelper::notifyEvent( const css::document::EventObject& rEvent ) throw (css::uno::RuntimeException, std::exception)
     565             : {
     566         510 :     static const uno::Sequence< uno::Any > saEmptyArgs;
     567        1944 :     if( (rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_OPENDOC )) ||
     568        1434 :         (rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_CREATEDOC )) )  // CREATEDOC triggered e.g. during VBA Workbooks.Add
     569             :     {
     570          50 :         processVbaEventNoThrow( WORKBOOK_OPEN, saEmptyArgs );
     571             :     }
     572         460 :     else if( rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_ACTIVATEDOC ) )
     573             :     {
     574          48 :         processVbaEventNoThrow( WORKBOOK_ACTIVATE, saEmptyArgs );
     575             :     }
     576         412 :     else if( rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_DEACTIVATEDOC ) )
     577             :     {
     578           2 :         processVbaEventNoThrow( WORKBOOK_DEACTIVATE, saEmptyArgs );
     579             :     }
     580        2460 :     else if( (rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_SAVEDOCDONE )) ||
     581        2866 :              (rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_SAVEASDOCDONE )) ||
     582        1226 :              (rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_SAVETODOCDONE )) )
     583             :     {
     584           2 :         uno::Sequence< uno::Any > aArgs( 1 );
     585           2 :         aArgs[ 0 ] <<= true;
     586           2 :         processVbaEventNoThrow( WORKBOOK_AFTERSAVE, aArgs );
     587             :     }
     588        2448 :     else if( (rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_SAVEDOCFAILED )) ||
     589        2856 :              (rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_SAVEASDOCFAILED )) ||
     590        1224 :              (rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_SAVETODOCFAILED )) )
     591             :     {
     592           0 :         uno::Sequence< uno::Any > aArgs( 1 );
     593           0 :         aArgs[ 0 ] <<= false;
     594           0 :         processVbaEventNoThrow( WORKBOOK_AFTERSAVE, aArgs );
     595             :     }
     596         408 :     else if( rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_CLOSEDOC ) )
     597             :     {
     598             :         /*  Trigger the WORKBOOK_WINDOWDEACTIVATE and WORKBOOK_DEACTIVATE
     599             :             events and stop listening to the model (done in base class). */
     600          52 :         uno::Reference< frame::XController > xController( mxModel->getCurrentController() );
     601          52 :         if( xController.is() )
     602             :         {
     603          52 :             uno::Sequence< uno::Any > aArgs( 1 );
     604          52 :             aArgs[ 0 ] <<= xController;
     605          52 :             processVbaEventNoThrow( WORKBOOK_WINDOWDEACTIVATE, aArgs );
     606             :         }
     607          52 :         processVbaEventNoThrow( WORKBOOK_DEACTIVATE, saEmptyArgs );
     608             :     }
     609         356 :     else if( rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_VIEWCREATED ) )
     610             :     {
     611          48 :         uno::Reference< frame::XController > xController( mxModel->getCurrentController() );
     612          48 :         if( mxListener.get() && xController.is() )
     613           0 :             mxListener->startControllerListening( xController );
     614             :     }
     615         510 :     VbaEventsHelperBase::notifyEvent( rEvent );
     616         510 : }
     617             : 
     618             : // protected ------------------------------------------------------------------
     619             : 
     620        3864 : bool ScVbaEventsHelper::implPrepareEvent( EventQueue& rEventQueue,
     621             :         const EventHandlerInfo& rInfo, const uno::Sequence< uno::Any >& rArgs ) throw (uno::RuntimeException)
     622             : {
     623             :     // document and document shell are needed during event processing
     624        3864 :     if( !mpShell || !mpDoc )
     625           0 :         throw uno::RuntimeException();
     626             : 
     627             :     /*  For document events: check if events are enabled via the
     628             :         Application.EnableEvents symbol (this is an Excel-only attribute).
     629             :         Check this again for every event, as the event handler may change the
     630             :         state of the EnableEvents symbol. Global events such as AUTO_OPEN and
     631             :         AUTO_CLOSE are always enabled. */
     632        3864 :     bool bExecuteEvent = (rInfo.mnModuleType != script::ModuleType::DOCUMENT) || ScVbaApplication::getDocumentEventsEnabled();
     633             : 
     634             :     // framework and Calc fire a few events before 'OnLoad', ignore them
     635        3864 :     if( bExecuteEvent )
     636        3864 :         bExecuteEvent = (rInfo.mnEventId == WORKBOOK_OPEN) ? !mbOpened : mbOpened;
     637             : 
     638             :     // special handling for some events
     639        3864 :     if( bExecuteEvent ) switch( rInfo.mnEventId )
     640             :     {
     641             :         case WORKBOOK_OPEN:
     642             :         {
     643             :             // execute delayed Activate event too (see above)
     644          50 :             rEventQueue.push_back( WORKBOOK_ACTIVATE );
     645          50 :             uno::Sequence< uno::Any > aArgs( 1 );
     646          50 :             aArgs[ 0 ] <<= mxModel->getCurrentController();
     647          50 :             rEventQueue.push_back( EventQueueEntry( WORKBOOK_WINDOWACTIVATE, aArgs ) );
     648          50 :             rEventQueue.push_back( AUTO_OPEN );
     649             :             // remember initial selection
     650          50 :             maOldSelection <<= mxModel->getCurrentSelection();
     651             :         }
     652          50 :         break;
     653             :         case WORKSHEET_SELECTIONCHANGE:
     654             :             // if selection is not changed, then do not fire the event
     655         620 :             bExecuteEvent = isSelectionChanged( rArgs, 0 );
     656         620 :         break;
     657             :     }
     658             : 
     659        3864 :     if( bExecuteEvent )
     660             :     {
     661             :         // add workbook event associated to a sheet event
     662        3054 :         bool bSheetEvent = false;
     663        3054 :         if( (rInfo.maUserData >>= bSheetEvent) && bSheetEvent )
     664        1270 :             rEventQueue.push_back( EventQueueEntry( rInfo.mnEventId + USERDEFINED_START, rArgs ) );
     665             :     }
     666             : 
     667        3864 :     return bExecuteEvent;
     668             : }
     669             : 
     670          68 : uno::Sequence< uno::Any > ScVbaEventsHelper::implBuildArgumentList( const EventHandlerInfo& rInfo,
     671             :         const uno::Sequence< uno::Any >& rArgs ) throw (lang::IllegalArgumentException, uno::RuntimeException)
     672             : {
     673             :     // fill arguments for workbook events associated to sheet events according to sheet events, sheet will be added below
     674          68 :     bool bSheetEventAsBookEvent = rInfo.mnEventId > USERDEFINED_START;
     675          68 :     sal_Int32 nEventId = bSheetEventAsBookEvent ? (rInfo.mnEventId - USERDEFINED_START) : rInfo.mnEventId;
     676             : 
     677          68 :     uno::Sequence< uno::Any > aVbaArgs;
     678          68 :     switch( nEventId )
     679             :     {
     680             :         // *** Workbook ***
     681             : 
     682             :         // no arguments
     683             :         case WORKBOOK_ACTIVATE:
     684             :         case WORKBOOK_DEACTIVATE:
     685             :         case WORKBOOK_OPEN:
     686           0 :         break;
     687             :         // 1 arg: cancel
     688             :         case WORKBOOK_BEFORECLOSE:
     689             :         case WORKBOOK_BEFOREPRINT:
     690           0 :             aVbaArgs.realloc( 1 );
     691             :             // current cancel state will be inserted by caller
     692           0 :         break;
     693             :         // 2 args: saveAs, cancel
     694             :         case WORKBOOK_BEFORESAVE:
     695           0 :             aVbaArgs.realloc( 2 );
     696           0 :             checkArgumentType< bool >( rArgs, 0 );
     697           0 :             aVbaArgs[ 0 ] = rArgs[ 0 ];
     698             :             // current cancel state will be inserted by caller
     699           0 :         break;
     700             :         // 1 arg: success
     701             :         case WORKBOOK_AFTERSAVE:
     702           0 :             aVbaArgs.realloc( 1 );
     703           0 :             checkArgumentType< bool >( rArgs, 0 );
     704           0 :             aVbaArgs[ 0 ] = rArgs[ 0 ];
     705           0 :         break;
     706             :         // 1 arg: window
     707             :         case WORKBOOK_WINDOWACTIVATE:
     708             :         case WORKBOOK_WINDOWDEACTIVATE:
     709             :         case WORKBOOK_WINDOWRESIZE:
     710           0 :             aVbaArgs.realloc( 1 );
     711           0 :             aVbaArgs[ 0 ] = createWindow( rArgs, 0 );
     712           0 :         break;
     713             :         // 1 arg: worksheet
     714             :         case WORKBOOK_NEWSHEET:
     715           0 :             aVbaArgs.realloc( 1 );
     716           0 :             aVbaArgs[ 0 ] = createWorksheet( rArgs, 0 );
     717           0 :         break;
     718             : 
     719             :         // *** Worksheet ***
     720             : 
     721             :         // no arguments
     722             :         case WORKSHEET_ACTIVATE:
     723             :         case WORKSHEET_CALCULATE:
     724             :         case WORKSHEET_DEACTIVATE:
     725           0 :         break;
     726             :         // 1 arg: range
     727             :         case WORKSHEET_CHANGE:
     728             :         case WORKSHEET_SELECTIONCHANGE:
     729          68 :             aVbaArgs.realloc( 1 );
     730          68 :             aVbaArgs[ 0 ] = createRange( rArgs, 0 );
     731          68 :         break;
     732             :         // 2 args: range, cancel
     733             :         case WORKSHEET_BEFOREDOUBLECLICK:
     734             :         case WORKSHEET_BEFORERIGHTCLICK:
     735           0 :             aVbaArgs.realloc( 2 );
     736           0 :             aVbaArgs[ 0 ] = createRange( rArgs, 0 );
     737             :             // current cancel state will be inserted by caller
     738           0 :         break;
     739             :         // 1 arg: hyperlink
     740             :         case WORKSHEET_FOLLOWHYPERLINK:
     741           0 :             aVbaArgs.realloc( 1 );
     742           0 :             aVbaArgs[ 0 ] = createHyperlink( rArgs, 0 );
     743           0 :         break;
     744             :     }
     745             : 
     746             :     /*  For workbook events associated to sheet events, the workbook event gets
     747             :         the same arguments but with a Worksheet object in front of them. */
     748          68 :     if( bSheetEventAsBookEvent )
     749             :     {
     750           0 :         sal_Int32 nLength = aVbaArgs.getLength();
     751           0 :         uno::Sequence< uno::Any > aVbaArgs2( nLength + 1 );
     752           0 :         aVbaArgs2[ 0 ] = createWorksheet( rArgs, 0 );
     753           0 :         for( sal_Int32 nIndex = 0; nIndex < nLength; ++nIndex )
     754           0 :             aVbaArgs2[ nIndex + 1 ] = aVbaArgs[ nIndex ];
     755           0 :         aVbaArgs = aVbaArgs2;
     756             :     }
     757             : 
     758          68 :     return aVbaArgs;
     759             : }
     760             : 
     761        3848 : void ScVbaEventsHelper::implPostProcessEvent( EventQueue& rEventQueue,
     762             :         const EventHandlerInfo& rInfo, bool bCancel ) throw (uno::RuntimeException)
     763             : {
     764        3848 :     switch( rInfo.mnEventId )
     765             :     {
     766             :         case WORKBOOK_OPEN:
     767          52 :             mbOpened = true;
     768             :             // register the listeners
     769          52 :             if( !mxListener.is() )
     770          50 :                 mxListener = new ScVbaEventListener( *this, mxModel, mpDocShell );
     771          52 :         break;
     772             :         case WORKBOOK_BEFORECLOSE:
     773             :             /*  Execute Auto_Close only if not cancelled by event handler, but
     774             :                 before UI asks user whether to cancel closing the document. */
     775           2 :             if( !bCancel )
     776           2 :                 rEventQueue.push_back( AUTO_CLOSE );
     777           2 :         break;
     778             :     }
     779        3848 : }
     780             : 
     781        4390 : OUString ScVbaEventsHelper::implGetDocumentModuleName( const EventHandlerInfo& rInfo,
     782             :         const uno::Sequence< uno::Any >& rArgs ) const
     783             :     throw (lang::IllegalArgumentException, uno::RuntimeException)
     784             : {
     785        4390 :     bool bSheetEvent = false;
     786        4390 :     rInfo.maUserData >>= bSheetEvent;
     787        4390 :     SCTAB nTab = bSheetEvent ? lclGetTabFromArgs( rArgs, 0 ) : -1;
     788        4374 :     if( bSheetEvent && (nTab < 0) )
     789           0 :         throw lang::IllegalArgumentException();
     790             : 
     791        4374 :     OUString aCodeName;
     792        4374 :     if( bSheetEvent )
     793        1992 :         mpDoc->GetCodeName( nTab, aCodeName );
     794             :     else
     795        2382 :         aCodeName = mpDoc->GetCodeName();
     796        4374 :     return aCodeName;
     797             : }
     798             : 
     799             : // private --------------------------------------------------------------------
     800             : 
     801             : namespace {
     802             : 
     803             : /** Compares the passed range lists representing sheet selections. Ignores
     804             :     selections that refer to different sheets (returns false in this case). */
     805         600 : bool lclSelectionChanged( const ScRangeList& rLeft, const ScRangeList& rRight )
     806             : {
     807             :     // one of the range lists empty? -> return false, if both lists empty
     808         600 :     bool bLeftEmpty = rLeft.empty();
     809         600 :     bool bRightEmpty = rRight.empty();
     810         600 :     if( bLeftEmpty || bRightEmpty )
     811           0 :         return !(bLeftEmpty && bRightEmpty);
     812             : 
     813             :     // check sheet indexes of the range lists (assuming that all ranges in a list are on the same sheet)
     814         600 :     if (rLeft[0]->aStart.Tab() != rRight[0]->aStart.Tab())
     815           8 :         return false;
     816             : 
     817             :     // compare all ranges
     818         592 :     return rLeft != rRight;
     819             : }
     820             : 
     821             : } // namespace
     822             : 
     823         620 : bool ScVbaEventsHelper::isSelectionChanged( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) throw (lang::IllegalArgumentException, uno::RuntimeException)
     824             : {
     825         620 :     uno::Reference< uno::XInterface > xOldSelection( maOldSelection, uno::UNO_QUERY );
     826        1240 :     uno::Reference< uno::XInterface > xNewSelection = getXSomethingFromArgs< uno::XInterface >( rArgs, nIndex, false );
     827         620 :     ScCellRangesBase* pOldCellRanges = ScCellRangesBase::getImplementation( xOldSelection );
     828         620 :     ScCellRangesBase* pNewCellRanges = ScCellRangesBase::getImplementation( xNewSelection );
     829         620 :     bool bChanged = !pOldCellRanges || !pNewCellRanges || lclSelectionChanged( pOldCellRanges->GetRangeList(), pNewCellRanges->GetRangeList() );
     830         620 :     maOldSelection <<= xNewSelection;
     831        1240 :     return bChanged;
     832             : }
     833             : 
     834           0 : uno::Any ScVbaEventsHelper::createWorksheet( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) const
     835             :         throw (lang::IllegalArgumentException, uno::RuntimeException)
     836             : {
     837             :     // extract sheet index, will throw, if parameter is invalid
     838           0 :     SCTAB nTab = lclGetTabFromArgs( rArgs, nIndex );
     839           0 :     return uno::Any( excel::getUnoSheetModuleObj( mxModel, nTab ) );
     840             : }
     841             : 
     842          68 : uno::Any ScVbaEventsHelper::createRange( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) const
     843             :         throw (lang::IllegalArgumentException, uno::RuntimeException)
     844             : {
     845             :     // it is possible to pass an existing VBA Range object
     846          68 :     uno::Reference< excel::XRange > xVbaRange = getXSomethingFromArgs< excel::XRange >( rArgs, nIndex );
     847          68 :     if( !xVbaRange.is() )
     848             :     {
     849          36 :         uno::Reference< sheet::XSheetCellRangeContainer > xRanges = getXSomethingFromArgs< sheet::XSheetCellRangeContainer >( rArgs, nIndex );
     850          72 :         uno::Reference< table::XCellRange > xRange = getXSomethingFromArgs< table::XCellRange >( rArgs, nIndex );
     851          36 :         if ( !xRanges.is() && !xRange.is() )
     852           0 :             throw lang::IllegalArgumentException();
     853             : 
     854          72 :         uno::Sequence< uno::Any > aArgs( 2 );
     855          36 :         if ( xRanges.is() )
     856             :         {
     857           4 :             aArgs[ 0 ] <<= excel::getUnoSheetModuleObj( xRanges );
     858           4 :             aArgs[ 1 ] <<= xRanges;
     859             :         }
     860             :         else
     861             :         {
     862          32 :             aArgs[ 0 ] <<= excel::getUnoSheetModuleObj( xRange );
     863          32 :             aArgs[ 1 ] <<= xRange;
     864             :         }
     865          72 :         xVbaRange.set( createVBAUnoAPIServiceWithArgs( mpShell, "ooo.vba.excel.Range", aArgs ), uno::UNO_QUERY_THROW );
     866             :     }
     867          68 :     return uno::Any( xVbaRange );
     868             : }
     869             : 
     870           0 : uno::Any ScVbaEventsHelper::createHyperlink( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) const
     871             :         throw (lang::IllegalArgumentException, uno::RuntimeException)
     872             : {
     873           0 :     uno::Reference< table::XCell > xCell = getXSomethingFromArgs< table::XCell >( rArgs, nIndex, false );
     874           0 :     uno::Sequence< uno::Any > aArgs( 2 );
     875           0 :     aArgs[ 0 ] <<= excel::getUnoSheetModuleObj( xCell );
     876           0 :     aArgs[ 1 ] <<= xCell;
     877           0 :     uno::Reference< uno::XInterface > xHyperlink( createVBAUnoAPIServiceWithArgs( mpShell, "ooo.vba.excel.Hyperlink", aArgs ), uno::UNO_SET_THROW );
     878           0 :     return uno::Any( xHyperlink );
     879             : }
     880             : 
     881           0 : uno::Any ScVbaEventsHelper::createWindow( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) const
     882             :         throw (lang::IllegalArgumentException, uno::RuntimeException)
     883             : {
     884           0 :     uno::Sequence< uno::Any > aArgs( 3 );
     885           0 :     aArgs[ 0 ] <<= getVBADocument( mxModel );
     886           0 :     aArgs[ 1 ] <<= mxModel;
     887           0 :     aArgs[ 2 ] <<= getXSomethingFromArgs< frame::XController >( rArgs, nIndex, false );
     888           0 :     uno::Reference< uno::XInterface > xWindow( createVBAUnoAPIServiceWithArgs( mpShell, "ooo.vba.excel.Window", aArgs ), uno::UNO_SET_THROW );
     889           0 :     return uno::Any( xWindow );
     890             : }
     891             : 
     892             : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
     893          52 : ScVbaEventsHelper_get_implementation(
     894             :     css::uno::XComponentContext *context,
     895             :     css::uno::Sequence<css::uno::Any> const &arguments)
     896             : {
     897          52 :     return cppu::acquire(new ScVbaEventsHelper(arguments, context));
     898          12 : }
     899             : 
     900             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10