2010-10-12 15:59:00 +02:00
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2012-11-30 12:23:25 +00:00
/*
* This file is part of the LibreOffice project .
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License , v . 2.0 . If a copy of the MPL was not distributed with this
* file , You can obtain one at http : //mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice :
*
* Licensed to the Apache Software Foundation ( ASF ) under one or more
* contributor license agreements . See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership . The ASF licenses this file to you under the Apache
* License , Version 2.0 ( the " License " ) ; you may not use this file
* except in compliance with the License . You may obtain a copy of
* the License at http : //www.apache.org/licenses/LICENSE-2.0 .
*/
2010-07-06 19:34:53 +02:00
# include "vbaeventshelper.hxx"
2011-05-23 23:44:53 -04:00
# include <com/sun/star/awt/XTopWindow.hpp>
# include <com/sun/star/awt/XTopWindowListener.hpp>
2010-07-06 19:34:53 +02:00
# include <com/sun/star/awt/XWindowListener.hpp>
# include <com/sun/star/frame/XBorderResizeListener.hpp>
# include <com/sun/star/frame/XControllerBorder.hpp>
2011-05-23 23:44:53 -04:00
# include <com/sun/star/script/ModuleType.hpp>
2010-07-12 11:17:00 +02:00
# include <com/sun/star/script/vba/VBAEventId.hpp>
2010-07-06 19:34:53 +02:00
# include <com/sun/star/sheet/XCellRangeAddressable.hpp>
# include <com/sun/star/sheet/XSheetCellRangeContainer.hpp>
# include <com/sun/star/table/XCellRange.hpp>
# include <com/sun/star/util/XChangesListener.hpp>
# include <com/sun/star/util/XChangesNotifier.hpp>
2010-07-27 11:53:35 +02:00
# include <cppuhelper/implbase4.hxx>
2013-06-28 04:38:06 +02:00
# include <toolkit/helper/vclunohelper.hxx>
2011-05-23 23:44:53 -04:00
# include <unotools/eventcfg.hxx>
2010-07-06 19:34:53 +02:00
# include <vcl/svapp.hxx>
# include <vcl/window.hxx>
# include "cellsuno.hxx"
# include "convuno.hxx"
2010-09-15 14:11:13 +02:00
# include "vbaapplication.hxx"
2010-07-06 19:34:53 +02:00
using namespace : : com : : sun : : star ;
2010-07-12 11:17:00 +02:00
using namespace : : com : : sun : : star : : script : : vba : : VBAEventId ;
2010-07-06 19:34:53 +02:00
using namespace : : ooo : : vba ;
2010-09-15 14:11:13 +02:00
namespace {
/** Extracts a sheet index from the specified element of the passed sequence.
2010-09-20 13:53:57 +02:00
The element may be an integer , a Calc range or ranges object , or a VBA Range object . */
2014-05-27 12:04:58 +02:00
SCTAB lclGetTabFromArgs ( const uno : : Sequence < uno : : Any > & rArgs , sal_Int32 nIndex ) throw ( lang : : IllegalArgumentException , uno : : RuntimeException )
2010-09-15 14:11:13 +02:00
{
VbaEventsHelperBase : : checkArgument ( rArgs , nIndex ) ;
// first try to extract a sheet index
2011-03-25 10:40:25 +01:00
sal_Int32 nTab = - 1 ;
2010-09-15 14:11:13 +02:00
if ( rArgs [ nIndex ] > > = nTab )
2011-05-23 23:44:53 -04:00
{
if ( ( nTab < 0 ) | | ( nTab > MAXTAB ) )
throw lang : : IllegalArgumentException ( ) ;
return static_cast < SCTAB > ( nTab ) ;
}
2010-09-15 14:11:13 +02:00
2010-09-20 13:53:57 +02:00
// try VBA Range object
uno : : Reference < excel : : XRange > xVbaRange = getXSomethingFromArgs < excel : : XRange > ( rArgs , nIndex ) ;
if ( xVbaRange . is ( ) )
{
uno : : Reference < XHelperInterface > xVbaHelper ( xVbaRange , uno : : UNO_QUERY_THROW ) ;
// TODO: in the future, the parent may be an excel::XChart (chart sheet) -> will there be a common base interface?
uno : : Reference < excel : : XWorksheet > xVbaSheet ( xVbaHelper - > getParent ( ) , uno : : UNO_QUERY_THROW ) ;
// VBA sheet index is 1-based
return static_cast < SCTAB > ( xVbaSheet - > getIndex ( ) - 1 ) ;
}
// try single UNO range object
2010-09-15 14:11:13 +02:00
uno : : Reference < sheet : : XCellRangeAddressable > xCellRangeAddressable = getXSomethingFromArgs < sheet : : XCellRangeAddressable > ( rArgs , nIndex ) ;
if ( xCellRangeAddressable . is ( ) )
return xCellRangeAddressable - > getRangeAddress ( ) . Sheet ;
2010-09-20 13:53:57 +02:00
// at last, try UNO range list
2010-09-15 14:11:13 +02:00
uno : : Reference < sheet : : XSheetCellRangeContainer > xRanges = getXSomethingFromArgs < sheet : : XSheetCellRangeContainer > ( rArgs , nIndex ) ;
if ( xRanges . is ( ) )
{
uno : : Sequence < table : : CellRangeAddress > aRangeAddresses = xRanges - > getRangeAddresses ( ) ;
if ( aRangeAddresses . getLength ( ) > 0 )
return aRangeAddresses [ 0 ] . Sheet ;
}
throw lang : : IllegalArgumentException ( ) ;
}
2011-05-23 23:44:53 -04:00
/** Returns the AWT container window of the passed controller. */
uno : : Reference < awt : : XWindow > lclGetWindowForController ( const uno : : Reference < frame : : XController > & rxController )
{
if ( rxController . is ( ) ) try
{
uno : : Reference < frame : : XFrame > xFrame ( rxController - > getFrame ( ) , uno : : UNO_SET_THROW ) ;
return xFrame - > getContainerWindow ( ) ;
}
catch ( uno : : Exception & )
{
}
return 0 ;
}
2010-09-15 14:11:13 +02:00
} // namespace
2011-05-23 23:44:53 -04:00
typedef : : cppu : : WeakImplHelper4 < awt : : XTopWindowListener , awt : : XWindowListener , frame : : XBorderResizeListener , util : : XChangesListener > ScVbaEventListener_BASE ;
2010-07-06 19:34:53 +02:00
// This class is to process Workbook window related event
2011-05-23 23:44:53 -04:00
class ScVbaEventListener : public ScVbaEventListener_BASE
2010-07-06 19:34:53 +02:00
{
public :
2011-05-23 23:44:53 -04:00
ScVbaEventListener ( ScVbaEventsHelper & rVbaEvents , const uno : : Reference < frame : : XModel > & rxModel , ScDocShell * pDocShell ) ;
virtual ~ ScVbaEventListener ( ) ;
/** Starts listening to the passed document controller. */
void startControllerListening ( const uno : : Reference < frame : : XController > & rxController ) ;
/** Stops listening to the passed document controller. */
void stopControllerListening ( const uno : : Reference < frame : : XController > & rxController ) ;
// XTopWindowListener
2014-03-27 18:12:18 +01:00
virtual void SAL_CALL windowOpened ( const lang : : EventObject & rEvent ) throw ( uno : : RuntimeException , std : : exception ) SAL_OVERRIDE ;
virtual void SAL_CALL windowClosing ( const lang : : EventObject & rEvent ) throw ( uno : : RuntimeException , std : : exception ) SAL_OVERRIDE ;
virtual void SAL_CALL windowClosed ( const lang : : EventObject & rEvent ) throw ( uno : : RuntimeException , std : : exception ) SAL_OVERRIDE ;
virtual void SAL_CALL windowMinimized ( const lang : : EventObject & rEvent ) throw ( uno : : RuntimeException , std : : exception ) SAL_OVERRIDE ;
virtual void SAL_CALL windowNormalized ( const lang : : EventObject & rEvent ) throw ( uno : : RuntimeException , std : : exception ) SAL_OVERRIDE ;
virtual void SAL_CALL windowActivated ( const lang : : EventObject & rEvent ) throw ( uno : : RuntimeException , std : : exception ) SAL_OVERRIDE ;
virtual void SAL_CALL windowDeactivated ( const lang : : EventObject & rEvent ) throw ( uno : : RuntimeException , std : : exception ) SAL_OVERRIDE ;
2010-07-06 19:34:53 +02:00
// XWindowListener
2014-03-27 18:12:18 +01:00
virtual void SAL_CALL windowResized ( const awt : : WindowEvent & rEvent ) throw ( uno : : RuntimeException , std : : exception ) SAL_OVERRIDE ;
virtual void SAL_CALL windowMoved ( const awt : : WindowEvent & rEvent ) throw ( uno : : RuntimeException , std : : exception ) SAL_OVERRIDE ;
virtual void SAL_CALL windowShown ( const lang : : EventObject & rEvent ) throw ( uno : : RuntimeException , std : : exception ) SAL_OVERRIDE ;
virtual void SAL_CALL windowHidden ( const lang : : EventObject & rEvent ) throw ( uno : : RuntimeException , std : : exception ) SAL_OVERRIDE ;
2010-07-06 19:34:53 +02:00
// XBorderResizeListener
2014-03-27 18:12:18 +01:00
virtual void SAL_CALL borderWidthsChanged ( const uno : : Reference < uno : : XInterface > & rSource , const frame : : BorderWidths & aNewSize ) throw ( uno : : RuntimeException , std : : exception ) SAL_OVERRIDE ;
2010-07-06 19:34:53 +02:00
2010-07-27 11:53:35 +02:00
// XChangesListener
2014-03-27 18:12:18 +01:00
virtual void SAL_CALL changesOccurred ( const util : : ChangesEvent & rEvent ) throw ( uno : : RuntimeException , std : : exception ) SAL_OVERRIDE ;
2011-05-23 23:44:53 -04:00
// XEventListener
2014-03-27 18:12:18 +01:00
virtual void SAL_CALL disposing ( const lang : : EventObject & rEvent ) throw ( uno : : RuntimeException , std : : exception ) SAL_OVERRIDE ;
2010-07-27 11:53:35 +02:00
2010-07-06 19:34:53 +02:00
private :
2011-05-23 23:44:53 -04:00
/** Starts listening to the document model. */
void startModelListening ( ) ;
/** Stops listening to the document model. */
void stopModelListening ( ) ;
/** Returns the controller for the passed VCL window. */
2014-09-23 11:20:40 +02:00
uno : : Reference < frame : : XController > getControllerForWindow ( vcl : : Window * pWindow ) const ;
2011-05-23 23:44:53 -04:00
/** Calls the Workbook_Window[Activate|Deactivate] event handler. */
2014-09-23 11:20:40 +02:00
void processWindowActivateEvent ( vcl : : Window * pWindow , bool bActivate ) ;
2011-05-23 23:44:53 -04:00
/** Posts a Workbook_WindowResize user event. */
2014-09-23 11:20:40 +02:00
void postWindowResizeEvent ( vcl : : Window * pWindow ) ;
2011-05-23 23:44:53 -04:00
/** Callback link for Application::PostUserEvent(). */
2014-09-23 11:20:40 +02:00
DECL_LINK ( processWindowResizeEvent , vcl : : Window * ) ;
2010-07-06 19:34:53 +02:00
private :
2015-03-09 14:29:30 +02:00
typedef : : std : : map < VclPtr < vcl : : Window > , uno : : Reference < frame : : XController > > WindowControllerMap ;
2011-05-23 23:44:53 -04:00
: : osl : : Mutex maMutex ;
ScVbaEventsHelper & mrVbaEvents ;
2010-07-06 19:34:53 +02:00
uno : : Reference < frame : : XModel > mxModel ;
2011-05-23 23:44:53 -04:00
ScDocShell * mpDocShell ;
WindowControllerMap maControllers ; /// Maps VCL top windows to their controllers.
2015-06-03 10:57:18 +01:00
std : : set < VclPtr < vcl : : Window > > maPostedWindows ; /// Keeps processWindowResizeEvent windows from being deleted between postWindowResizeEvent and processWindowResizeEvent
VclPtr < vcl : : Window > mpActiveWindow ; /// Currently activated window, to prevent multiple (de)activation.
2011-05-23 23:44:53 -04:00
bool mbWindowResized ; /// True = window resize system event processed.
bool mbBorderChanged ; /// True = borders changed system event processed.
bool mbDisposed ;
2010-07-06 19:34:53 +02:00
} ;
2011-05-23 23:44:53 -04:00
ScVbaEventListener : : ScVbaEventListener ( ScVbaEventsHelper & rVbaEvents , const uno : : Reference < frame : : XModel > & rxModel , ScDocShell * pDocShell ) :
2010-07-27 11:53:35 +02:00
mrVbaEvents ( rVbaEvents ) ,
2010-07-06 19:34:53 +02:00
mxModel ( rxModel ) ,
2010-07-27 11:53:35 +02:00
mpDocShell ( pDocShell ) ,
2011-05-23 23:44:53 -04:00
mpActiveWindow ( 0 ) ,
2010-07-27 11:53:35 +02:00
mbWindowResized ( false ) ,
mbBorderChanged ( false ) ,
mbDisposed ( ! rxModel . is ( ) )
2010-07-06 19:34:53 +02:00
{
2011-05-23 23:44:53 -04:00
if ( ! mxModel . is ( ) )
return ;
startModelListening ( ) ;
try
{
uno : : Reference < frame : : XController > xController ( mxModel - > getCurrentController ( ) , uno : : UNO_QUERY_THROW ) ;
startControllerListening ( xController ) ;
}
catch ( uno : : Exception & )
{
}
2010-07-06 19:34:53 +02:00
}
2011-05-23 23:44:53 -04:00
ScVbaEventListener : : ~ ScVbaEventListener ( )
2010-07-06 19:34:53 +02:00
{
}
2011-05-23 23:44:53 -04:00
void ScVbaEventListener : : startControllerListening ( const uno : : Reference < frame : : XController > & rxController )
2010-07-06 19:34:53 +02:00
{
2011-05-23 23:44:53 -04:00
: : osl : : MutexGuard aGuard ( maMutex ) ;
uno : : Reference < awt : : XWindow > xWindow = lclGetWindowForController ( rxController ) ;
if ( xWindow . is ( ) )
try { xWindow - > addWindowListener ( this ) ; } catch ( uno : : Exception & ) { }
uno : : Reference < awt : : XTopWindow > xTopWindow ( xWindow , uno : : UNO_QUERY ) ;
if ( xTopWindow . is ( ) )
try { xTopWindow - > addTopWindowListener ( this ) ; } catch ( uno : : Exception & ) { }
uno : : Reference < frame : : XControllerBorder > xControllerBorder ( rxController , uno : : UNO_QUERY ) ;
if ( xControllerBorder . is ( ) )
try { xControllerBorder - > addBorderResizeListener ( this ) ; } catch ( uno : : Exception & ) { }
2014-09-23 11:20:40 +02:00
if ( vcl : : Window * pWindow = VCLUnoHelper : : GetWindow ( xWindow ) )
2015-06-03 10:57:18 +01:00
{
2011-05-23 23:44:53 -04:00
maControllers [ pWindow ] = rxController ;
2015-06-03 10:57:18 +01:00
}
2011-05-23 23:44:53 -04:00
}
void ScVbaEventListener : : stopControllerListening ( const uno : : Reference < frame : : XController > & rxController )
{
: : osl : : MutexGuard aGuard ( maMutex ) ;
uno : : Reference < awt : : XWindow > xWindow = lclGetWindowForController ( rxController ) ;
if ( xWindow . is ( ) )
try { xWindow - > removeWindowListener ( this ) ; } catch ( uno : : Exception & ) { }
uno : : Reference < awt : : XTopWindow > xTopWindow ( xWindow , uno : : UNO_QUERY ) ;
if ( xTopWindow . is ( ) )
try { xTopWindow - > removeTopWindowListener ( this ) ; } catch ( uno : : Exception & ) { }
uno : : Reference < frame : : XControllerBorder > xControllerBorder ( rxController , uno : : UNO_QUERY ) ;
if ( xControllerBorder . is ( ) )
try { xControllerBorder - > removeBorderResizeListener ( this ) ; } catch ( uno : : Exception & ) { }
2014-09-23 11:20:40 +02:00
if ( vcl : : Window * pWindow = VCLUnoHelper : : GetWindow ( xWindow ) )
2010-07-06 19:34:53 +02:00
{
2011-05-23 23:44:53 -04:00
maControllers . erase ( pWindow ) ;
if ( pWindow = = mpActiveWindow )
mpActiveWindow = 0 ;
2010-07-06 19:34:53 +02:00
}
}
2014-02-25 21:31:58 +01:00
void SAL_CALL ScVbaEventListener : : windowOpened ( const lang : : EventObject & /*rEvent*/ ) throw ( uno : : RuntimeException , std : : exception )
2011-05-23 23:44:53 -04:00
{
}
2014-02-25 21:31:58 +01:00
void SAL_CALL ScVbaEventListener : : windowClosing ( const lang : : EventObject & /*rEvent*/ ) throw ( uno : : RuntimeException , std : : exception )
2011-05-23 23:44:53 -04:00
{
}
2014-02-25 21:31:58 +01:00
void SAL_CALL ScVbaEventListener : : windowClosed ( const lang : : EventObject & /*rEvent*/ ) throw ( uno : : RuntimeException , std : : exception )
2011-05-23 23:44:53 -04:00
{
}
2014-02-25 21:31:58 +01:00
void SAL_CALL ScVbaEventListener : : windowMinimized ( const lang : : EventObject & /*rEvent*/ ) throw ( uno : : RuntimeException , std : : exception )
2011-05-23 23:44:53 -04:00
{
}
2014-02-25 21:31:58 +01:00
void SAL_CALL ScVbaEventListener : : windowNormalized ( const lang : : EventObject & /*rEvent*/ ) throw ( uno : : RuntimeException , std : : exception )
2011-05-23 23:44:53 -04:00
{
}
2014-02-25 21:31:58 +01:00
void SAL_CALL ScVbaEventListener : : windowActivated ( const lang : : EventObject & rEvent ) throw ( uno : : RuntimeException , std : : exception )
2010-07-06 19:34:53 +02:00
{
2011-05-23 23:44:53 -04:00
: : osl : : MutexGuard aGuard ( maMutex ) ;
2010-07-27 11:53:35 +02:00
if ( ! mbDisposed )
2010-07-06 19:34:53 +02:00
{
2011-05-23 23:44:53 -04:00
uno : : Reference < awt : : XWindow > xWindow ( rEvent . Source , uno : : UNO_QUERY ) ;
2014-09-23 11:20:40 +02:00
vcl : : Window * pWindow = VCLUnoHelper : : GetWindow ( xWindow ) ;
2015-03-09 14:29:30 +02:00
OSL_TRACE ( " ScVbaEventListener::windowActivated - pWindow = 0x%p, mpActiveWindow = 0x%p " , pWindow , mpActiveWindow . get ( ) ) ;
2011-05-23 23:44:53 -04:00
// do not fire activation event multiple time for the same window
if ( pWindow & & ( pWindow ! = mpActiveWindow ) )
2010-07-27 11:53:35 +02:00
{
2011-05-23 23:44:53 -04:00
// if another window is active, fire deactivation event first
if ( mpActiveWindow )
processWindowActivateEvent ( mpActiveWindow , false ) ;
// fire activation event for the new window
processWindowActivateEvent ( pWindow , true ) ;
mpActiveWindow = pWindow ;
2010-07-27 11:53:35 +02:00
}
2010-07-06 19:34:53 +02:00
}
}
2014-02-25 21:31:58 +01:00
void SAL_CALL ScVbaEventListener : : windowDeactivated ( const lang : : EventObject & rEvent ) throw ( uno : : RuntimeException , std : : exception )
2010-07-06 19:34:53 +02:00
{
: : osl : : MutexGuard aGuard ( maMutex ) ;
2011-05-23 23:44:53 -04:00
if ( ! mbDisposed )
2010-07-06 19:34:53 +02:00
{
2011-05-23 23:44:53 -04:00
uno : : Reference < awt : : XWindow > xWindow ( rEvent . Source , uno : : UNO_QUERY ) ;
2014-09-23 11:20:40 +02:00
vcl : : Window * pWindow = VCLUnoHelper : : GetWindow ( xWindow ) ;
2015-03-09 14:29:30 +02:00
OSL_TRACE ( " ScVbaEventListener::windowDeactivated - pWindow = 0x%p, mpActiveWindow = 0x%p " , pWindow , mpActiveWindow . get ( ) ) ;
2011-05-23 23:44:53 -04:00
// do not fire the deactivation event, if the window is not active (prevent multiple deactivation)
if ( pWindow & & ( pWindow = = mpActiveWindow ) )
processWindowActivateEvent ( pWindow , false ) ;
// forget pointer to the active window
mpActiveWindow = 0 ;
2010-07-06 19:34:53 +02:00
}
}
2014-02-25 21:31:58 +01:00
void SAL_CALL ScVbaEventListener : : windowResized ( const awt : : WindowEvent & rEvent ) throw ( uno : : RuntimeException , std : : exception )
2010-07-06 19:34:53 +02:00
{
2011-05-23 23:44:53 -04:00
: : osl : : MutexGuard aGuard ( maMutex ) ;
2010-07-06 19:34:53 +02:00
2011-05-23 23:44:53 -04:00
mbWindowResized = true ;
if ( ! mbDisposed & & mbBorderChanged )
{
uno : : Reference < awt : : XWindow > xWindow ( rEvent . Source , uno : : UNO_QUERY ) ;
postWindowResizeEvent ( VCLUnoHelper : : GetWindow ( xWindow ) ) ;
}
2010-07-06 19:34:53 +02:00
}
2014-02-25 21:31:58 +01:00
void SAL_CALL ScVbaEventListener : : windowMoved ( const awt : : WindowEvent & /*rEvent*/ ) throw ( uno : : RuntimeException , std : : exception )
2010-07-06 19:34:53 +02:00
{
}
2014-02-25 21:31:58 +01:00
void SAL_CALL ScVbaEventListener : : windowShown ( const lang : : EventObject & /*rEvent*/ ) throw ( uno : : RuntimeException , std : : exception )
2010-07-06 19:34:53 +02:00
{
}
2014-02-25 21:31:58 +01:00
void SAL_CALL ScVbaEventListener : : windowHidden ( const lang : : EventObject & /*rEvent*/ ) throw ( uno : : RuntimeException , std : : exception )
2010-07-06 19:34:53 +02:00
{
}
2014-02-25 21:31:58 +01:00
void SAL_CALL ScVbaEventListener : : borderWidthsChanged ( const uno : : Reference < uno : : XInterface > & rSource , const frame : : BorderWidths & /*aNewSize*/ ) throw ( uno : : RuntimeException , std : : exception )
2010-07-06 19:34:53 +02:00
{
: : osl : : MutexGuard aGuard ( maMutex ) ;
mbBorderChanged = true ;
2010-07-27 11:53:35 +02:00
if ( ! mbDisposed & & mbWindowResized )
2010-07-06 19:34:53 +02:00
{
2011-05-23 23:44:53 -04:00
uno : : Reference < frame : : XController > xController ( rSource , uno : : UNO_QUERY ) ;
uno : : Reference < awt : : XWindow > xWindow = lclGetWindowForController ( xController ) ;
postWindowResizeEvent ( VCLUnoHelper : : GetWindow ( xWindow ) ) ;
2010-07-06 19:34:53 +02:00
}
}
2014-02-25 21:31:58 +01:00
void SAL_CALL ScVbaEventListener : : changesOccurred ( const util : : ChangesEvent & rEvent ) throw ( uno : : RuntimeException , std : : exception )
2010-07-27 11:53:35 +02:00
{
2011-05-23 23:44:53 -04:00
: : osl : : MutexGuard aGuard ( maMutex ) ;
sal_Int32 nCount = rEvent . Changes . getLength ( ) ;
if ( mbDisposed | | ! mpDocShell | | ( nCount = = 0 ) )
2010-07-27 11:53:35 +02:00
return ;
2011-05-23 23:44:53 -04:00
util : : ElementChange aChange = rEvent . Changes [ 0 ] ;
OUString sOperation ;
2010-07-27 11:53:35 +02:00
aChange . Accessor > > = sOperation ;
2013-03-19 11:32:06 +01:00
if ( ! sOperation . equalsIgnoreAsciiCase ( " cell-change " ) )
2010-07-27 11:53:35 +02:00
return ;
if ( nCount = = 1 )
{
uno : : Reference < table : : XCellRange > xRangeObj ;
aChange . ReplacedElement > > = xRangeObj ;
if ( xRangeObj . is ( ) )
{
2010-09-20 13:53:57 +02:00
uno : : Sequence < uno : : Any > aArgs ( 1 ) ;
2010-07-27 11:53:35 +02:00
aArgs [ 0 ] < < = xRangeObj ;
2011-05-23 23:44:53 -04:00
mrVbaEvents . processVbaEventNoThrow ( WORKSHEET_CHANGE , aArgs ) ;
2010-07-27 11:53:35 +02:00
}
return ;
}
ScRangeList aRangeList ;
for ( sal_Int32 nIndex = 0 ; nIndex < nCount ; + + nIndex )
{
2011-05-23 23:44:53 -04:00
aChange = rEvent . Changes [ nIndex ] ;
2010-07-27 11:53:35 +02:00
aChange . Accessor > > = sOperation ;
uno : : Reference < table : : XCellRange > xRangeObj ;
aChange . ReplacedElement > > = xRangeObj ;
2013-03-19 11:32:06 +01:00
if ( xRangeObj . is ( ) & & sOperation . equalsIgnoreAsciiCase ( " cell-change " ) )
2010-07-27 11:53:35 +02:00
{
uno : : Reference < sheet : : XCellRangeAddressable > xCellRangeAddressable ( xRangeObj , uno : : UNO_QUERY ) ;
if ( xCellRangeAddressable . is ( ) )
{
ScRange aRange ;
ScUnoConversion : : FillScRange ( aRange , xCellRangeAddressable - > getRangeAddress ( ) ) ;
aRangeList . Append ( aRange ) ;
}
}
}
2011-05-23 23:44:53 -04:00
if ( ! aRangeList . empty ( ) )
2010-07-27 11:53:35 +02:00
{
uno : : Reference < sheet : : XSheetCellRangeContainer > xRanges ( new ScCellRangesObj ( mpDocShell , aRangeList ) ) ;
uno : : Sequence < uno : : Any > aArgs ( 1 ) ;
aArgs [ 0 ] < < = xRanges ;
2011-05-23 23:44:53 -04:00
mrVbaEvents . processVbaEventNoThrow ( WORKSHEET_CHANGE , aArgs ) ;
2010-07-27 11:53:35 +02:00
}
}
2014-02-25 21:31:58 +01:00
void SAL_CALL ScVbaEventListener : : disposing ( const lang : : EventObject & rEvent ) throw ( uno : : RuntimeException , std : : exception )
2010-07-06 19:34:53 +02:00
{
2011-05-23 23:44:53 -04:00
: : osl : : MutexGuard aGuard ( maMutex ) ;
uno : : Reference < frame : : XModel > xModel ( rEvent . Source , uno : : UNO_QUERY ) ;
if ( xModel . is ( ) )
2010-07-06 19:34:53 +02:00
{
2011-05-23 23:44:53 -04:00
OSL_ENSURE ( xModel . get ( ) = = mxModel . get ( ) , " ScVbaEventListener::disposing - disposing from unknown model " ) ;
stopModelListening ( ) ;
mbDisposed = true ;
return ;
2010-07-06 19:34:53 +02:00
}
2011-05-23 23:44:53 -04:00
uno : : Reference < frame : : XController > xController ( rEvent . Source , uno : : UNO_QUERY ) ;
if ( xController . is ( ) )
2010-07-06 19:34:53 +02:00
{
2011-05-23 23:44:53 -04:00
stopControllerListening ( xController ) ;
return ;
2010-07-06 19:34:53 +02:00
}
}
2011-05-23 23:44:53 -04:00
// private --------------------------------------------------------------------
void ScVbaEventListener : : startModelListening ( )
2010-07-06 19:34:53 +02:00
{
try
{
2011-05-23 23:44:53 -04:00
uno : : Reference < util : : XChangesNotifier > xChangesNotifier ( mxModel , uno : : UNO_QUERY_THROW ) ;
xChangesNotifier - > addChangesListener ( this ) ;
2010-07-06 19:34:53 +02:00
}
catch ( uno : : Exception & )
{
}
}
2011-05-23 23:44:53 -04:00
void ScVbaEventListener : : stopModelListening ( )
2010-07-06 19:34:53 +02:00
{
2011-05-23 23:44:53 -04:00
try
{
uno : : Reference < util : : XChangesNotifier > xChangesNotifier ( mxModel , uno : : UNO_QUERY_THROW ) ;
xChangesNotifier - > removeChangesListener ( this ) ;
}
catch ( uno : : Exception & )
2010-07-06 19:34:53 +02:00
{
}
}
2014-09-23 11:20:40 +02:00
uno : : Reference < frame : : XController > ScVbaEventListener : : getControllerForWindow ( vcl : : Window * pWindow ) const
2010-07-06 19:34:53 +02:00
{
2011-05-23 23:44:53 -04:00
WindowControllerMap : : const_iterator aIt = maControllers . find ( pWindow ) ;
return ( aIt = = maControllers . end ( ) ) ? uno : : Reference < frame : : XController > ( ) : aIt - > second ;
}
2014-09-23 11:20:40 +02:00
void ScVbaEventListener : : processWindowActivateEvent ( vcl : : Window * pWindow , bool bActivate )
2011-05-23 23:44:53 -04:00
{
uno : : Reference < frame : : XController > xController = getControllerForWindow ( pWindow ) ;
if ( xController . is ( ) )
2010-08-25 13:43:42 +02:00
{
2011-05-23 23:44:53 -04:00
uno : : Sequence < uno : : Any > aArgs ( 1 ) ;
aArgs [ 0 ] < < = xController ;
mrVbaEvents . processVbaEventNoThrow ( bActivate ? WORKBOOK_WINDOWACTIVATE : WORKBOOK_WINDOWDEACTIVATE , aArgs ) ;
2010-08-25 13:43:42 +02:00
}
2011-05-23 23:44:53 -04:00
}
2014-09-23 11:20:40 +02:00
void ScVbaEventListener : : postWindowResizeEvent ( vcl : : Window * pWindow )
2011-05-23 23:44:53 -04:00
{
// check that the passed window is still alive (it must be registered in maControllers)
if ( pWindow & & ( maControllers . count ( pWindow ) > 0 ) )
2010-08-25 13:43:42 +02:00
{
2011-05-23 23:44:53 -04:00
mbWindowResized = mbBorderChanged = false ;
acquire ( ) ; // ensure we don't get deleted before the timer fires
2015-06-03 10:57:18 +01:00
maPostedWindows . insert ( pWindow ) ;
2011-05-23 23:44:53 -04:00
Application : : PostUserEvent ( LINK ( this , ScVbaEventListener , processWindowResizeEvent ) , pWindow ) ;
2010-08-25 13:43:42 +02:00
}
2010-07-06 19:34:53 +02:00
}
2015-05-09 22:07:19 +02:00
IMPL_LINK ( ScVbaEventListener , processWindowResizeEvent , vcl : : Window * , pWindow )
2010-07-06 19:34:53 +02:00
{
2011-05-23 23:44:53 -04:00
: : osl : : MutexGuard aGuard ( maMutex ) ;
/* Check that the passed window is still alive (it must be registered in
maControllers ) . While closing a document , postWindowResizeEvent ( ) may
be called on the last window which posts a user event via
Application : : PostUserEvent to call this event handler . VCL will trigger
the handler some time later . Sometimes , the window gets deleted before .
This is handled via the disposing ( ) function which removes the window
pointer from the member maControllers . Thus , checking whether
maControllers contains pWindow ensures that the window is still alive . */
2015-06-03 10:57:18 +01:00
if ( ! mbDisposed & & pWindow & & ! pWindow - > IsDisposed ( ) & & ( maControllers . count ( pWindow ) > 0 ) )
2010-10-06 10:15:43 +01:00
{
2011-05-23 23:44:53 -04:00
// do not fire event unless all mouse buttons have been released
2014-09-23 11:20:40 +02:00
vcl : : Window : : PointerState aPointerState = pWindow - > GetPointerState ( ) ;
2011-05-23 23:44:53 -04:00
if ( ( aPointerState . mnState & ( MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT ) ) = = 0 )
2010-10-06 10:15:43 +01:00
{
2011-05-23 23:44:53 -04:00
uno : : Reference < frame : : XController > xController = getControllerForWindow ( pWindow ) ;
if ( xController . is ( ) )
{
uno : : Sequence < uno : : Any > aArgs ( 1 ) ;
aArgs [ 0 ] < < = xController ;
// #163419# do not throw exceptions into application core
mrVbaEvents . processVbaEventNoThrow ( WORKBOOK_WINDOWRESIZE , aArgs ) ;
}
2010-10-06 10:15:43 +01:00
}
}
2015-06-03 10:57:18 +01:00
maPostedWindows . erase ( pWindow ) ;
2011-05-23 23:44:53 -04:00
release ( ) ;
return 0 ;
2010-07-06 19:34:53 +02:00
}
ScVbaEventsHelper : : ScVbaEventsHelper ( const uno : : Sequence < uno : : Any > & rArgs , const uno : : Reference < uno : : XComponentContext > & xContext ) :
VbaEventsHelperBase ( rArgs , xContext ) ,
2010-07-27 11:53:35 +02:00
mbOpened ( false )
2010-07-06 19:34:53 +02:00
{
mpDocShell = dynamic_cast < ScDocShell * > ( mpShell ) ; // mpShell from base class
2014-06-18 12:14:29 +02:00
mpDoc = mpDocShell ? & mpDocShell - > GetDocument ( ) : 0 ;
2010-07-06 19:34:53 +02:00
if ( ! mxModel . is ( ) | | ! mpDocShell | | ! mpDoc )
return ;
2011-05-23 23:44:53 -04:00
# define REGISTER_EVENT( eventid, moduletype, classname, eventname, cancelindex, worksheet ) \
registerEventHandler ( eventid , moduletype , classname " _ " eventname , cancelindex , uno : : Any ( worksheet ) )
# define REGISTER_AUTO_EVENT( eventid, eventname ) \
REGISTER_EVENT ( AUTO_ # # eventid , script : : ModuleType : : NORMAL , " Auto " , eventname , - 1 , false )
2010-07-06 19:34:53 +02:00
# define REGISTER_WORKBOOK_EVENT( eventid, eventname, cancelindex ) \
2011-05-23 23:44:53 -04:00
REGISTER_EVENT ( WORKBOOK_ # # eventid , script : : ModuleType : : DOCUMENT , " Workbook " , eventname , cancelindex , false )
2010-07-06 19:34:53 +02:00
# define REGISTER_WORKSHEET_EVENT( eventid, eventname, cancelindex ) \
2011-05-23 23:44:53 -04:00
REGISTER_EVENT ( WORKSHEET_ # # eventid , script : : ModuleType : : DOCUMENT , " Worksheet " , eventname , cancelindex , true ) ; \
REGISTER_EVENT ( ( USERDEFINED_START + WORKSHEET_ # # eventid ) , script : : ModuleType : : DOCUMENT , " Workbook " , " Sheet " eventname , ( ( ( cancelindex ) > = 0 ) ? ( ( cancelindex ) + 1 ) : - 1 ) , false )
2010-07-06 19:34:53 +02:00
// global
2011-05-23 23:44:53 -04:00
REGISTER_AUTO_EVENT ( OPEN , " Open " ) ;
REGISTER_AUTO_EVENT ( CLOSE , " Close " ) ;
2010-07-06 19:34:53 +02:00
// Workbook
REGISTER_WORKBOOK_EVENT ( ACTIVATE , " Activate " , - 1 ) ;
REGISTER_WORKBOOK_EVENT ( DEACTIVATE , " Deactivate " , - 1 ) ;
REGISTER_WORKBOOK_EVENT ( OPEN , " Open " , - 1 ) ;
REGISTER_WORKBOOK_EVENT ( BEFORECLOSE , " BeforeClose " , 0 ) ;
REGISTER_WORKBOOK_EVENT ( BEFOREPRINT , " BeforePrint " , 0 ) ;
REGISTER_WORKBOOK_EVENT ( BEFORESAVE , " BeforeSave " , 1 ) ;
REGISTER_WORKBOOK_EVENT ( AFTERSAVE , " AfterSave " , - 1 ) ;
REGISTER_WORKBOOK_EVENT ( NEWSHEET , " NewSheet " , - 1 ) ;
REGISTER_WORKBOOK_EVENT ( WINDOWACTIVATE , " WindowActivate " , - 1 ) ;
REGISTER_WORKBOOK_EVENT ( WINDOWDEACTIVATE , " WindowDeactivate " , - 1 ) ;
REGISTER_WORKBOOK_EVENT ( WINDOWRESIZE , " WindowResize " , - 1 ) ;
// Worksheet events. All events have a corresponding workbook event.
REGISTER_WORKSHEET_EVENT ( ACTIVATE , " Activate " , - 1 ) ;
REGISTER_WORKSHEET_EVENT ( DEACTIVATE , " Deactivate " , - 1 ) ;
REGISTER_WORKSHEET_EVENT ( BEFOREDOUBLECLICK , " BeforeDoubleClick " , 1 ) ;
REGISTER_WORKSHEET_EVENT ( BEFORERIGHTCLICK , " BeforeRightClick " , 1 ) ;
REGISTER_WORKSHEET_EVENT ( CALCULATE , " Calculate " , - 1 ) ;
REGISTER_WORKSHEET_EVENT ( CHANGE , " Change " , - 1 ) ;
REGISTER_WORKSHEET_EVENT ( SELECTIONCHANGE , " SelectionChange " , - 1 ) ;
REGISTER_WORKSHEET_EVENT ( FOLLOWHYPERLINK , " FollowHyperlink " , - 1 ) ;
# undef REGISTER_WORKSHEET_EVENT
2011-05-23 23:44:53 -04:00
# undef REGISTER_WORKBOOK_EVENT
# undef REGISTER_AUTO_EVENT
# undef REGISTER_EVENT
2010-07-06 19:34:53 +02:00
}
ScVbaEventsHelper : : ~ ScVbaEventsHelper ( )
{
}
2014-02-25 21:31:58 +01:00
void SAL_CALL ScVbaEventsHelper : : notifyEvent ( const css : : document : : EventObject & rEvent ) throw ( css : : uno : : RuntimeException , std : : exception )
2010-07-30 17:28:42 +02:00
{
2011-05-23 23:44:53 -04:00
static const uno : : Sequence < uno : : Any > saEmptyArgs ;
2015-04-28 15:01:43 +02:00
if ( ( rEvent . EventName = = GlobalEventConfig : : GetEventName ( GlobalEventId : : OPENDOC ) ) | |
( rEvent . EventName = = GlobalEventConfig : : GetEventName ( GlobalEventId : : CREATEDOC ) ) ) // CREATEDOC triggered e.g. during VBA Workbooks.Add
2011-05-23 23:44:53 -04:00
{
processVbaEventNoThrow ( WORKBOOK_OPEN , saEmptyArgs ) ;
}
2015-04-28 15:01:43 +02:00
else if ( rEvent . EventName = = GlobalEventConfig : : GetEventName ( GlobalEventId : : ACTIVATEDOC ) )
2011-05-23 23:44:53 -04:00
{
processVbaEventNoThrow ( WORKBOOK_ACTIVATE , saEmptyArgs ) ;
}
2015-04-28 15:01:43 +02:00
else if ( rEvent . EventName = = GlobalEventConfig : : GetEventName ( GlobalEventId : : DEACTIVATEDOC ) )
2011-05-23 23:44:53 -04:00
{
processVbaEventNoThrow ( WORKBOOK_DEACTIVATE , saEmptyArgs ) ;
}
2015-04-28 15:01:43 +02:00
else if ( ( rEvent . EventName = = GlobalEventConfig : : GetEventName ( GlobalEventId : : SAVEDOCDONE ) ) | |
( rEvent . EventName = = GlobalEventConfig : : GetEventName ( GlobalEventId : : SAVEASDOCDONE ) ) | |
( rEvent . EventName = = GlobalEventConfig : : GetEventName ( GlobalEventId : : SAVETODOCDONE ) ) )
2011-05-23 23:44:53 -04:00
{
uno : : Sequence < uno : : Any > aArgs ( 1 ) ;
aArgs [ 0 ] < < = true ;
processVbaEventNoThrow ( WORKBOOK_AFTERSAVE , aArgs ) ;
}
2015-04-28 15:01:43 +02:00
else if ( ( rEvent . EventName = = GlobalEventConfig : : GetEventName ( GlobalEventId : : SAVEDOCFAILED ) ) | |
( rEvent . EventName = = GlobalEventConfig : : GetEventName ( GlobalEventId : : SAVEASDOCFAILED ) ) | |
( rEvent . EventName = = GlobalEventConfig : : GetEventName ( GlobalEventId : : SAVETODOCFAILED ) ) )
2011-05-23 23:44:53 -04:00
{
uno : : Sequence < uno : : Any > aArgs ( 1 ) ;
aArgs [ 0 ] < < = false ;
processVbaEventNoThrow ( WORKBOOK_AFTERSAVE , aArgs ) ;
}
2015-04-28 15:01:43 +02:00
else if ( rEvent . EventName = = GlobalEventConfig : : GetEventName ( GlobalEventId : : CLOSEDOC ) )
2011-05-23 23:44:53 -04:00
{
/* Trigger the WORKBOOK_WINDOWDEACTIVATE and WORKBOOK_DEACTIVATE
events and stop listening to the model ( done in base class ) . * /
uno : : Reference < frame : : XController > xController ( mxModel - > getCurrentController ( ) ) ;
if ( xController . is ( ) )
{
uno : : Sequence < uno : : Any > aArgs ( 1 ) ;
aArgs [ 0 ] < < = xController ;
processVbaEventNoThrow ( WORKBOOK_WINDOWDEACTIVATE , aArgs ) ;
}
processVbaEventNoThrow ( WORKBOOK_DEACTIVATE , saEmptyArgs ) ;
}
2015-04-28 15:01:43 +02:00
else if ( rEvent . EventName = = GlobalEventConfig : : GetEventName ( GlobalEventId : : VIEWCREATED ) )
2011-05-23 23:44:53 -04:00
{
uno : : Reference < frame : : XController > xController ( mxModel - > getCurrentController ( ) ) ;
if ( mxListener . get ( ) & & xController . is ( ) )
mxListener - > startControllerListening ( xController ) ;
}
VbaEventsHelperBase : : notifyEvent ( rEvent ) ;
2010-07-30 17:28:42 +02:00
}
2015-03-17 12:25:11 +01:00
OUString ScVbaEventsHelper : : getImplementationName ( )
throw ( css : : uno : : RuntimeException , std : : exception )
{
return OUString ( " ScVbaEventsHelper " ) ;
}
css : : uno : : Sequence < OUString > ScVbaEventsHelper : : getSupportedServiceNames ( )
throw ( css : : uno : : RuntimeException , std : : exception )
{
return css : : uno : : Sequence < OUString > {
" com.sun.star.script.vba.VBASpreadsheetEventProcessor " } ;
}
2010-07-06 19:34:53 +02:00
// protected ------------------------------------------------------------------
2010-08-23 13:53:47 +02:00
bool ScVbaEventsHelper : : implPrepareEvent ( EventQueue & rEventQueue ,
const EventHandlerInfo & rInfo , const uno : : Sequence < uno : : Any > & rArgs ) throw ( uno : : RuntimeException )
2010-07-06 19:34:53 +02:00
{
// document and document shell are needed during event processing
2010-08-23 13:53:47 +02:00
if ( ! mpShell | | ! mpDoc )
2010-07-06 19:34:53 +02:00
throw uno : : RuntimeException ( ) ;
2011-05-23 23:44:53 -04:00
/* For document events: check if events are enabled via the
Application . EnableEvents symbol ( this is an Excel - only attribute ) .
Check this again for every event , as the event handler may change the
state of the EnableEvents symbol . Global events such as AUTO_OPEN and
AUTO_CLOSE are always enabled . */
bool bExecuteEvent = ( rInfo . mnModuleType ! = script : : ModuleType : : DOCUMENT ) | | ScVbaApplication : : getDocumentEventsEnabled ( ) ;
// framework and Calc fire a few events before 'OnLoad', ignore them
if ( bExecuteEvent )
bExecuteEvent = ( rInfo . mnEventId = = WORKBOOK_OPEN ) ? ! mbOpened : mbOpened ;
2010-07-06 19:34:53 +02:00
2010-08-18 17:20:31 +02:00
// special handling for some events
2011-05-23 23:44:53 -04:00
if ( bExecuteEvent ) switch ( rInfo . mnEventId )
2010-07-06 19:34:53 +02:00
{
case WORKBOOK_OPEN :
2011-05-23 23:44:53 -04:00
{
// execute delayed Activate event too (see above)
rEventQueue . push_back ( WORKBOOK_ACTIVATE ) ;
uno : : Sequence < uno : : Any > aArgs ( 1 ) ;
aArgs [ 0 ] < < = mxModel - > getCurrentController ( ) ;
rEventQueue . push_back ( EventQueueEntry ( WORKBOOK_WINDOWACTIVATE , aArgs ) ) ;
rEventQueue . push_back ( AUTO_OPEN ) ;
// remember initial selection
maOldSelection < < = mxModel - > getCurrentSelection ( ) ;
}
2010-07-06 19:34:53 +02:00
break ;
case WORKSHEET_SELECTIONCHANGE :
// if selection is not changed, then do not fire the event
2011-05-23 23:44:53 -04:00
bExecuteEvent = isSelectionChanged ( rArgs , 0 ) ;
2010-07-06 19:34:53 +02:00
break ;
}
2010-08-18 17:20:31 +02:00
if ( bExecuteEvent )
{
2010-08-23 13:53:47 +02:00
// add workbook event associated to a sheet event
2010-08-18 17:20:31 +02:00
bool bSheetEvent = false ;
if ( ( rInfo . maUserData > > = bSheetEvent ) & & bSheetEvent )
rEventQueue . push_back ( EventQueueEntry ( rInfo . mnEventId + USERDEFINED_START , rArgs ) ) ;
}
2010-07-06 19:34:53 +02:00
return bExecuteEvent ;
}
uno : : Sequence < uno : : Any > ScVbaEventsHelper : : implBuildArgumentList ( const EventHandlerInfo & rInfo ,
2015-07-02 09:15:23 +01:00
const uno : : Sequence < uno : : Any > & rArgs ) throw ( lang : : IllegalArgumentException , uno : : RuntimeException , std : : exception )
2010-07-06 19:34:53 +02:00
{
// fill arguments for workbook events associated to sheet events according to sheet events, sheet will be added below
bool bSheetEventAsBookEvent = rInfo . mnEventId > USERDEFINED_START ;
sal_Int32 nEventId = bSheetEventAsBookEvent ? ( rInfo . mnEventId - USERDEFINED_START ) : rInfo . mnEventId ;
uno : : Sequence < uno : : Any > aVbaArgs ;
switch ( nEventId )
{
// *** Workbook ***
// no arguments
case WORKBOOK_ACTIVATE :
case WORKBOOK_DEACTIVATE :
case WORKBOOK_OPEN :
break ;
// 1 arg: cancel
case WORKBOOK_BEFORECLOSE :
case WORKBOOK_BEFOREPRINT :
aVbaArgs . realloc ( 1 ) ;
// current cancel state will be inserted by caller
break ;
// 2 args: saveAs, cancel
case WORKBOOK_BEFORESAVE :
aVbaArgs . realloc ( 2 ) ;
checkArgumentType < bool > ( rArgs , 0 ) ;
aVbaArgs [ 0 ] = rArgs [ 0 ] ;
// current cancel state will be inserted by caller
break ;
// 1 arg: success
case WORKBOOK_AFTERSAVE :
aVbaArgs . realloc ( 1 ) ;
checkArgumentType < bool > ( rArgs , 0 ) ;
aVbaArgs [ 0 ] = rArgs [ 0 ] ;
break ;
// 1 arg: window
case WORKBOOK_WINDOWACTIVATE :
case WORKBOOK_WINDOWDEACTIVATE :
case WORKBOOK_WINDOWRESIZE :
aVbaArgs . realloc ( 1 ) ;
2011-05-23 23:44:53 -04:00
aVbaArgs [ 0 ] = createWindow ( rArgs , 0 ) ;
2010-07-06 19:34:53 +02:00
break ;
// 1 arg: worksheet
case WORKBOOK_NEWSHEET :
aVbaArgs . realloc ( 1 ) ;
aVbaArgs [ 0 ] = createWorksheet ( rArgs , 0 ) ;
break ;
// *** Worksheet ***
// no arguments
case WORKSHEET_ACTIVATE :
case WORKSHEET_CALCULATE :
case WORKSHEET_DEACTIVATE :
break ;
// 1 arg: range
case WORKSHEET_CHANGE :
case WORKSHEET_SELECTIONCHANGE :
aVbaArgs . realloc ( 1 ) ;
aVbaArgs [ 0 ] = createRange ( rArgs , 0 ) ;
break ;
// 2 args: range, cancel
case WORKSHEET_BEFOREDOUBLECLICK :
case WORKSHEET_BEFORERIGHTCLICK :
aVbaArgs . realloc ( 2 ) ;
aVbaArgs [ 0 ] = createRange ( rArgs , 0 ) ;
// current cancel state will be inserted by caller
break ;
// 1 arg: hyperlink
case WORKSHEET_FOLLOWHYPERLINK :
aVbaArgs . realloc ( 1 ) ;
aVbaArgs [ 0 ] = createHyperlink ( rArgs , 0 ) ;
break ;
}
/* For workbook events associated to sheet events, the workbook event gets
the same arguments but with a Worksheet object in front of them . */
if ( bSheetEventAsBookEvent )
{
sal_Int32 nLength = aVbaArgs . getLength ( ) ;
uno : : Sequence < uno : : Any > aVbaArgs2 ( nLength + 1 ) ;
aVbaArgs2 [ 0 ] = createWorksheet ( rArgs , 0 ) ;
for ( sal_Int32 nIndex = 0 ; nIndex < nLength ; + + nIndex )
aVbaArgs2 [ nIndex + 1 ] = aVbaArgs [ nIndex ] ;
aVbaArgs = aVbaArgs2 ;
}
return aVbaArgs ;
}
void ScVbaEventsHelper : : implPostProcessEvent ( EventQueue & rEventQueue ,
2011-05-23 23:44:53 -04:00
const EventHandlerInfo & rInfo , bool bCancel ) throw ( uno : : RuntimeException )
2010-07-06 19:34:53 +02:00
{
switch ( rInfo . mnEventId )
{
case WORKBOOK_OPEN :
mbOpened = true ;
2010-07-27 11:53:35 +02:00
// register the listeners
if ( ! mxListener . is ( ) )
2011-05-23 23:44:53 -04:00
mxListener = new ScVbaEventListener ( * this , mxModel , mpDocShell ) ;
2010-07-06 19:34:53 +02:00
break ;
case WORKBOOK_BEFORECLOSE :
2010-07-27 11:53:35 +02:00
/* Execute Auto_Close only if not cancelled by event handler, but
before UI asks user whether to cancel closing the document . */
if ( ! bCancel )
2010-07-06 19:34:53 +02:00
rEventQueue . push_back ( AUTO_CLOSE ) ;
break ;
}
}
2011-05-23 23:44:53 -04:00
OUString ScVbaEventsHelper : : implGetDocumentModuleName ( const EventHandlerInfo & rInfo ,
2014-06-02 15:25:11 +01:00
const uno : : Sequence < uno : : Any > & rArgs ) const
throw ( lang : : IllegalArgumentException , uno : : RuntimeException )
2010-07-06 19:34:53 +02:00
{
bool bSheetEvent = false ;
rInfo . maUserData > > = bSheetEvent ;
2010-09-15 14:11:13 +02:00
SCTAB nTab = bSheetEvent ? lclGetTabFromArgs ( rArgs , 0 ) : - 1 ;
2010-07-06 19:34:53 +02:00
if ( bSheetEvent & & ( nTab < 0 ) )
throw lang : : IllegalArgumentException ( ) ;
2013-04-07 12:06:47 +02:00
OUString aCodeName ;
2010-07-06 19:34:53 +02:00
if ( bSheetEvent )
mpDoc - > GetCodeName ( nTab , aCodeName ) ;
else
aCodeName = mpDoc - > GetCodeName ( ) ;
return aCodeName ;
}
// private --------------------------------------------------------------------
2010-09-15 14:11:13 +02:00
namespace {
2010-07-06 19:34:53 +02:00
2010-09-15 14:11:13 +02:00
/** Compares the passed range lists representing sheet selections. Ignores
selections that refer to different sheets ( returns false in this case ) . */
bool lclSelectionChanged ( const ScRangeList & rLeft , const ScRangeList & rRight )
{
// one of the range lists empty? -> return false, if both lists empty
2011-03-15 01:58:39 -04:00
bool bLeftEmpty = rLeft . empty ( ) ;
bool bRightEmpty = rRight . empty ( ) ;
2010-09-15 14:11:13 +02:00
if ( bLeftEmpty | | bRightEmpty )
return ! ( bLeftEmpty & & bRightEmpty ) ;
2010-07-06 19:34:53 +02:00
2010-09-15 14:11:13 +02:00
// check sheet indexes of the range lists (assuming that all ranges in a list are on the same sheet)
2011-05-23 23:44:53 -04:00
if ( rLeft [ 0 ] - > aStart . Tab ( ) ! = rRight [ 0 ] - > aStart . Tab ( ) )
2010-09-15 14:11:13 +02:00
return false ;
2010-07-06 19:34:53 +02:00
2010-09-15 14:11:13 +02:00
// compare all ranges
return rLeft ! = rRight ;
2010-07-06 19:34:53 +02:00
}
2010-09-15 14:11:13 +02:00
} // namespace
2010-07-06 19:34:53 +02:00
bool ScVbaEventsHelper : : isSelectionChanged ( const uno : : Sequence < uno : : Any > & rArgs , sal_Int32 nIndex ) throw ( lang : : IllegalArgumentException , uno : : RuntimeException )
{
2011-05-23 23:44:53 -04:00
uno : : Reference < uno : : XInterface > xOldSelection ( maOldSelection , uno : : UNO_QUERY ) ;
2010-07-06 19:34:53 +02:00
uno : : Reference < uno : : XInterface > xNewSelection = getXSomethingFromArgs < uno : : XInterface > ( rArgs , nIndex , false ) ;
2011-05-23 23:44:53 -04:00
ScCellRangesBase * pOldCellRanges = ScCellRangesBase : : getImplementation ( xOldSelection ) ;
ScCellRangesBase * pNewCellRanges = ScCellRangesBase : : getImplementation ( xNewSelection ) ;
bool bChanged = ! pOldCellRanges | | ! pNewCellRanges | | lclSelectionChanged ( pOldCellRanges - > GetRangeList ( ) , pNewCellRanges - > GetRangeList ( ) ) ;
maOldSelection < < = xNewSelection ;
return bChanged ;
2010-07-06 19:34:53 +02:00
}
uno : : Any ScVbaEventsHelper : : createWorksheet ( const uno : : Sequence < uno : : Any > & rArgs , sal_Int32 nIndex ) const
2015-07-04 20:04:09 +01:00
throw ( lang : : IllegalArgumentException , uno : : RuntimeException , std : : exception )
2010-07-06 19:34:53 +02:00
{
// extract sheet index, will throw, if parameter is invalid
2010-09-15 14:11:13 +02:00
SCTAB nTab = lclGetTabFromArgs ( rArgs , nIndex ) ;
2010-09-17 18:42:00 +02:00
return uno : : Any ( excel : : getUnoSheetModuleObj ( mxModel , nTab ) ) ;
2010-07-06 19:34:53 +02:00
}
uno : : Any ScVbaEventsHelper : : createRange ( const uno : : Sequence < uno : : Any > & rArgs , sal_Int32 nIndex ) const
2015-07-08 14:23:26 +01:00
throw ( lang : : IllegalArgumentException , uno : : RuntimeException , std : : exception )
2010-07-06 19:34:53 +02:00
{
2010-09-20 13:53:57 +02:00
// it is possible to pass an existing VBA Range object
uno : : Reference < excel : : XRange > xVbaRange = getXSomethingFromArgs < excel : : XRange > ( rArgs , nIndex ) ;
if ( ! xVbaRange . is ( ) )
2010-09-17 18:42:00 +02:00
{
2010-09-20 13:53:57 +02:00
uno : : Reference < sheet : : XSheetCellRangeContainer > xRanges = getXSomethingFromArgs < sheet : : XSheetCellRangeContainer > ( rArgs , nIndex ) ;
uno : : Reference < table : : XCellRange > xRange = getXSomethingFromArgs < table : : XCellRange > ( rArgs , nIndex ) ;
if ( ! xRanges . is ( ) & & ! xRange . is ( ) )
throw lang : : IllegalArgumentException ( ) ;
2010-07-06 19:34:53 +02:00
2010-09-20 13:53:57 +02:00
uno : : Sequence < uno : : Any > aArgs ( 2 ) ;
if ( xRanges . is ( ) )
{
aArgs [ 0 ] < < = excel : : getUnoSheetModuleObj ( xRanges ) ;
aArgs [ 1 ] < < = xRanges ;
}
else
{
aArgs [ 0 ] < < = excel : : getUnoSheetModuleObj ( xRange ) ;
aArgs [ 1 ] < < = xRange ;
}
xVbaRange . set ( createVBAUnoAPIServiceWithArgs ( mpShell , " ooo.vba.excel.Range " , aArgs ) , uno : : UNO_QUERY_THROW ) ;
2010-09-17 18:42:00 +02:00
}
2010-07-06 19:34:53 +02:00
return uno : : Any ( xVbaRange ) ;
}
uno : : Any ScVbaEventsHelper : : createHyperlink ( const uno : : Sequence < uno : : Any > & rArgs , sal_Int32 nIndex ) const
2015-07-08 14:21:20 +01:00
throw ( lang : : IllegalArgumentException , uno : : RuntimeException , std : : exception )
2010-07-06 19:34:53 +02:00
{
2010-09-17 18:42:00 +02:00
uno : : Reference < table : : XCell > xCell = getXSomethingFromArgs < table : : XCell > ( rArgs , nIndex , false ) ;
2010-07-06 19:34:53 +02:00
uno : : Sequence < uno : : Any > aArgs ( 2 ) ;
2010-09-17 18:42:00 +02:00
aArgs [ 0 ] < < = excel : : getUnoSheetModuleObj ( xCell ) ;
aArgs [ 1 ] < < = xCell ;
2010-07-06 19:34:53 +02:00
uno : : Reference < uno : : XInterface > xHyperlink ( createVBAUnoAPIServiceWithArgs ( mpShell , " ooo.vba.excel.Hyperlink " , aArgs ) , uno : : UNO_SET_THROW ) ;
return uno : : Any ( xHyperlink ) ;
}
2011-05-23 23:44:53 -04:00
uno : : Any ScVbaEventsHelper : : createWindow ( const uno : : Sequence < uno : : Any > & rArgs , sal_Int32 nIndex ) const
2015-06-29 12:09:52 +01:00
throw ( lang : : IllegalArgumentException , uno : : RuntimeException , std : : exception )
2010-07-06 19:34:53 +02:00
{
2011-05-23 23:44:53 -04:00
uno : : Sequence < uno : : Any > aArgs ( 3 ) ;
aArgs [ 0 ] < < = getVBADocument ( mxModel ) ;
2010-07-06 19:34:53 +02:00
aArgs [ 1 ] < < = mxModel ;
2011-05-23 23:44:53 -04:00
aArgs [ 2 ] < < = getXSomethingFromArgs < frame : : XController > ( rArgs , nIndex , false ) ;
2010-07-06 19:34:53 +02:00
uno : : Reference < uno : : XInterface > xWindow ( createVBAUnoAPIServiceWithArgs ( mpShell , " ooo.vba.excel.Window " , aArgs ) , uno : : UNO_SET_THROW ) ;
return uno : : Any ( xWindow ) ;
}
2014-02-20 23:42:49 +01:00
extern " C " SAL_DLLPUBLIC_EXPORT css : : uno : : XInterface * SAL_CALL
ScVbaEventsHelper_get_implementation (
css : : uno : : XComponentContext * context ,
css : : uno : : Sequence < css : : uno : : Any > const & arguments )
2010-07-06 19:34:53 +02:00
{
2014-02-20 23:42:49 +01:00
return cppu : : acquire ( new ScVbaEventsHelper ( arguments , context ) ) ;
2010-07-06 19:34:53 +02:00
}
2010-10-12 15:59:00 +02:00
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */