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

Generated by: LCOV version 1.10