diff options
author | Vladimir Glazunov <vg@openoffice.org> | 2010-08-25 15:47:38 +0200 |
---|---|---|
committer | Vladimir Glazunov <vg@openoffice.org> | 2010-08-25 15:47:38 +0200 |
commit | 4af9b31225fdf406b5b6cd9204f583d22a4c7666 (patch) | |
tree | 37fe3a6e96c1c2885ac0a1511e010049b7a05ad7 /sc/source/ui/vba | |
parent | 2998a94e194cd67050129d163d6bb155d667eda7 (diff) | |
parent | 48018b48b69b584bf3e97ee797c0dbd2c49385ca (diff) |
DEV300: merge 000330 till r. b727f1beb700
Diffstat (limited to 'sc/source/ui/vba')
-rw-r--r-- | sc/source/ui/vba/excelvbahelper.cxx | 50 | ||||
-rw-r--r-- | sc/source/ui/vba/excelvbahelper.hxx | 8 | ||||
-rw-r--r-- | sc/source/ui/vba/makefile.mk | 2 | ||||
-rw-r--r-- | sc/source/ui/vba/service.cxx | 12 | ||||
-rw-r--r-- | sc/source/ui/vba/vbaapplication.cxx | 89 | ||||
-rw-r--r-- | sc/source/ui/vba/vbaapplication.hxx | 7 | ||||
-rw-r--r-- | sc/source/ui/vba/vbachartobjects.cxx | 5 | ||||
-rw-r--r-- | sc/source/ui/vba/vbacomments.cxx | 6 | ||||
-rwxr-xr-x | sc/source/ui/vba/vbaeventshelper.cxx | 753 | ||||
-rwxr-xr-x | sc/source/ui/vba/vbaeventshelper.hxx | 88 | ||||
-rw-r--r-- | sc/source/ui/vba/vbaformatconditions.cxx | 6 | ||||
-rw-r--r-- | sc/source/ui/vba/vbaglobals.cxx | 1 | ||||
-rw-r--r-- | sc/source/ui/vba/vbaname.cxx | 4 | ||||
-rw-r--r-- | sc/source/ui/vba/vbanames.cxx | 2 | ||||
-rw-r--r-- | sc/source/ui/vba/vbapivottables.cxx | 4 | ||||
-rwxr-xr-x[-rw-r--r--] | sc/source/ui/vba/vbarange.cxx | 122 | ||||
-rw-r--r-- | sc/source/ui/vba/vbarange.hxx | 1 | ||||
-rw-r--r-- | sc/source/ui/vba/vbaworkbooks.cxx | 101 | ||||
-rw-r--r-- | sc/source/ui/vba/vbaworksheet.cxx | 21 | ||||
-rw-r--r-- | sc/source/ui/vba/vbaworksheet.hxx | 1 | ||||
-rw-r--r-- | sc/source/ui/vba/vbaworksheets.cxx | 51 |
21 files changed, 1206 insertions, 128 deletions
diff --git a/sc/source/ui/vba/excelvbahelper.cxx b/sc/source/ui/vba/excelvbahelper.cxx index b1c4db637434b..2c39d7154b4bd 100644 --- a/sc/source/ui/vba/excelvbahelper.cxx +++ b/sc/source/ui/vba/excelvbahelper.cxx @@ -31,6 +31,7 @@ #include "scmod.hxx" #include "cellsuno.hxx" #include <comphelper/processfactory.hxx> +#include <com/sun/star/sheet/XSheetCellRange.hpp> using namespace ::com::sun::star; using namespace ::ooo::vba; @@ -41,6 +42,27 @@ namespace vba { namespace excel { + +ScDocShell* GetDocShellFromRange( const uno::Reference< uno::XInterface >& xRange ) throw ( uno::RuntimeException ) +{ + ScCellRangesBase* pScCellRangesBase = ScCellRangesBase::getImplementation( xRange ); + if ( !pScCellRangesBase ) + { + throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Failed to access underlying doc shell uno range object" ) ), uno::Reference< uno::XInterface >() ); + } + return pScCellRangesBase->GetDocShell(); +} + +ScDocument* GetDocumentFromRange( const uno::Reference< uno::XInterface >& xRange ) throw ( uno::RuntimeException ) +{ + ScDocShell* pDocShell = GetDocShellFromRange( xRange ); + if ( !pDocShell ) + { + throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Failed to access underlying document from uno range object" ) ), uno::Reference< uno::XInterface >() ); + } + return pDocShell->GetDocument(); +} + void implSetZoom( const uno::Reference< frame::XModel >& xModel, sal_Int16 nZoom, std::vector< SCTAB >& nTabs ) { ScTabViewShell* pViewSh = excel::getBestViewShell( xModel ); @@ -207,12 +229,40 @@ getViewFrame( const uno::Reference< frame::XModel >& xModel ) return NULL; } +uno::Reference< XHelperInterface > +getUnoSheetModuleObj( const uno::Reference< table::XCellRange >& xRange ) throw ( uno::RuntimeException ) +{ + uno::Reference< sheet::XSheetCellRange > xSheetRange( xRange, uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySet > xProps( xSheetRange->getSpreadsheet(), uno::UNO_QUERY_THROW ); + rtl::OUString sCodeName; + xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("CodeName") ) ) >>= sCodeName; + // #TODO #FIXME ideally we should 'throw' here if we don't get a valid parent, but... it is possible + // to create a module ( and use 'Option VBASupport 1' ) for a calc document, in this scenario there + // are *NO* special document module objects ( of course being able to switch between vba/non vba mode at + // the document in the future could fix this, especially IF the switching of the vba mode takes care to + // create the special document module objects if they don't exist. + uno::Reference< XHelperInterface > xParent( ov::getUnoDocModule( sCodeName, GetDocShellFromRange( xRange ) ), uno::UNO_QUERY ); + + return xParent; +} + +uno::Reference< XHelperInterface > +getUnoSheetModuleObj( const uno::Reference< sheet::XSheetCellRangeContainer >& xRanges ) throw ( uno::RuntimeException ) +{ + uno::Reference< container::XEnumerationAccess > xEnumAccess( xRanges, uno::UNO_QUERY_THROW ); + uno::Reference< container::XEnumeration > xEnum = xEnumAccess->createEnumeration(); + uno::Reference< table::XCellRange > xRange( xEnum->nextElement(), uno::UNO_QUERY_THROW ); + + return getUnoSheetModuleObj( xRange ); +} + SfxItemSet* ScVbaCellRangeAccess::GetDataSet( ScCellRangesBase* pRangeObj ) { return pRangeObj ? pRangeObj->GetCurrentDataSet( true ) : 0; } + } //excel } //vba } //ooo diff --git a/sc/source/ui/vba/excelvbahelper.hxx b/sc/source/ui/vba/excelvbahelper.hxx index 9af804ab169f6..da0474e6ceb06 100644 --- a/sc/source/ui/vba/excelvbahelper.hxx +++ b/sc/source/ui/vba/excelvbahelper.hxx @@ -29,6 +29,9 @@ #include<vbahelper/vbahelper.hxx> #include <docsh.hxx> +#include <com/sun/star/table/XCellRange.hpp> +#include <com/sun/star/sheet/XSheetCellRangeContainer.hpp> +#include <ooo/vba/XHelperInterface.hpp> class ScCellRangesBase; @@ -48,6 +51,11 @@ namespace ooo ScDocShell* getDocShell( const css::uno::Reference< css::frame::XModel>& xModel ) ; ScTabViewShell* getCurrentBestViewShell( const css::uno::Reference< css::uno::XComponentContext >& xContext ); SfxViewFrame* getViewFrame( const css::uno::Reference< css::frame::XModel >& xModel ); + css::uno::Reference< ooo::vba::XHelperInterface > getUnoSheetModuleObj( const css::uno::Reference< css::sheet::XSheetCellRangeContainer >& xRanges ) throw ( css::uno::RuntimeException ); + css::uno::Reference< ooo::vba::XHelperInterface > getUnoSheetModuleObj( const css::uno::Reference< css::table::XCellRange >& xRange ) throw ( css::uno::RuntimeException ); + ScDocShell* GetDocShellFromRange( const css::uno::Reference< css::uno::XInterface >& xRange ) throw ( css::uno::RuntimeException ); + ScDocument* GetDocumentFromRange( const css::uno::Reference< css::uno::XInterface >& xRange ) throw ( css::uno::RuntimeException ); + css::uno::Reference< css::frame::XModel > GetModelFromRange( const css::uno::Reference< css::uno::XInterface >& xRange ) throw ( css::uno::RuntimeException ); class ScVbaCellRangeAccess { public: diff --git a/sc/source/ui/vba/makefile.mk b/sc/source/ui/vba/makefile.mk index 0a84b8dd12a52..4cb7e3eb064b6 100644 --- a/sc/source/ui/vba/makefile.mk +++ b/sc/source/ui/vba/makefile.mk @@ -102,7 +102,9 @@ SLOFILES= \ $(SLO)$/vbapagesetup.obj \ $(SLO)$/vbapagebreak.obj \ $(SLO)$/vbapagebreaks.obj \ + $(SLO)$/vbaeventshelper.obj \ $(SLO)$/service.obj + .ENDIF # --- Targets ------------------------------------------------------ diff --git a/sc/source/ui/vba/service.cxx b/sc/source/ui/vba/service.cxx index 8be0f6d9f726e..2b1f14cf154aa 100644 --- a/sc/source/ui/vba/service.cxx +++ b/sc/source/ui/vba/service.cxx @@ -66,6 +66,10 @@ namespace application { extern sdecl::ServiceDecl const serviceDecl; } +namespace vbaeventshelper +{ +extern sdecl::ServiceDecl const serviceDecl; +} namespace textframe { extern sdecl::ServiceDecl const serviceDecl; @@ -87,7 +91,7 @@ extern "C" #if 0 // Component registration if ( component_writeInfoHelper( pServiceManager, pRegistryKey, - range::serviceDecl, workbook::serviceDecl, worksheet::serviceDecl, globals::serviceDecl, window::serviceDecl, hyperlink::serviceDecl, application::serviceDecl ) ) + range::serviceDecl, workbook::serviceDecl, worksheet::serviceDecl, globals::serviceDecl, window::serviceDecl, hyperlink::serviceDecl, application::serviceDecl ) && component_writeInfoHelper( pServiceManager, pRegistryKey, vbaeventshelper::serviceDecl ) ) { // Singleton registration try @@ -110,7 +114,7 @@ extern "C" #else // Component registration return component_writeInfoHelper( pServiceManager, pRegistryKey, - range::serviceDecl, workbook::serviceDecl, worksheet::serviceDecl, globals::serviceDecl, window::serviceDecl, hyperlink::serviceDecl, application::serviceDecl ) && component_writeInfoHelper( pServiceManager, pRegistryKey, textframe::serviceDecl ); + range::serviceDecl, workbook::serviceDecl, worksheet::serviceDecl, globals::serviceDecl, window::serviceDecl, hyperlink::serviceDecl, application::serviceDecl ) && component_writeInfoHelper( pServiceManager, pRegistryKey, vbaeventshelper::serviceDecl, textframe::serviceDecl ); #endif } @@ -122,8 +126,8 @@ extern "C" OSL_TRACE("In component_getFactory for %s", pImplName ); void* pRet = component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey, range::serviceDecl, workbook::serviceDecl, worksheet::serviceDecl, globals::serviceDecl, window::serviceDecl, hyperlink::serviceDecl, application::serviceDecl ); - if( !pRet ) - pRet = component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey, textframe::serviceDecl ); + if( !pRet ) + pRet = component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey, vbaeventshelper::serviceDecl, textframe::serviceDecl ); OSL_TRACE("Ret is 0x%x", pRet); return pRet; } diff --git a/sc/source/ui/vba/vbaapplication.cxx b/sc/source/ui/vba/vbaapplication.cxx index aea8d8bc11d4d..8f5aba5c4acbf 100644 --- a/sc/source/ui/vba/vbaapplication.cxx +++ b/sc/source/ui/vba/vbaapplication.cxx @@ -24,14 +24,14 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ -#include <stdio.h> +#include <stdio.h> -#include<com/sun/star/sheet/XSpreadsheetView.hpp> +#include <com/sun/star/sheet/XSpreadsheetView.hpp> #include <com/sun/star/sheet/XSpreadsheets.hpp> -#include<com/sun/star/view/XSelectionSupplier.hpp> +#include <com/sun/star/view/XSelectionSupplier.hpp> #include <com/sun/star/lang/XServiceInfo.hpp> -#include<ooo/vba/excel/XlCalculation.hpp> +#include <ooo/vba/excel/XlCalculation.hpp> #include <com/sun/star/sheet/XCellRangeReferrer.hpp> #include <com/sun/star/sheet/XCalculatable.hpp> #include <com/sun/star/frame/XLayoutManager.hpp> @@ -117,7 +117,8 @@ public: ScVbaApplication::ScVbaApplication( const uno::Reference<uno::XComponentContext >& xContext ) : ScVbaApplication_BASE( xContext ), m_xCalculation( excel::XlCalculation::xlCalculationAutomatic ), - m_xDisplayAlerts( sal_True) + m_bDisplayAlerts( sal_True ), + m_bEnableEvents( sal_True ) { } @@ -193,18 +194,47 @@ ScVbaApplication::hasProperty( const ::rtl::OUString& Name ) throw(uno::RuntimeE uno::Reference< excel::XWorkbook > ScVbaApplication::getActiveWorkbook() throw (uno::RuntimeException) { - return new ActiveWorkbook( this, mxContext ); + uno::Reference< excel::XWorkbook > xWrkbk; + ScDocShell* pShell = excel::getDocShell( getCurrentExcelDoc( mxContext ) ); + if ( pShell ) + { + String aName; + if ( pShell->GetDocument() ) + { + aName = pShell->GetDocument()->GetCodeName(); + xWrkbk.set( getUnoDocModule( aName, pShell ), uno::UNO_QUERY ); + // fallback ( e.g. it's possible a new document was created via the api ) + // in that case the document will not have the appropriate Document Modules + // #TODO #FIXME ( needs to be fixes as part of providing support for an overall document + // vba mode etc. ) + if ( !xWrkbk.is() ) + return new ActiveWorkbook( this, mxContext ); + } + } + return xWrkbk; } uno::Reference< excel::XWorkbook > SAL_CALL ScVbaApplication::getThisWorkbook() throw (uno::RuntimeException) { - uno::Reference< frame::XModel > xModel = getThisExcelDoc(mxContext); - if( !xModel.is() ) - return uno::Reference< excel::XWorkbook >(); - - ScVbaWorkbook *pWb = new ScVbaWorkbook( this, mxContext, xModel ); - return uno::Reference< excel::XWorkbook > (pWb); + uno::Reference< excel::XWorkbook > xWrkbk; + ScDocShell* pShell = excel::getDocShell( getThisExcelDoc( mxContext ) ); + if ( pShell ) + { + String aName; + if ( pShell->GetDocument() ) + { + aName = pShell->GetDocument()->GetCodeName(); + xWrkbk.set( getUnoDocModule( aName, pShell ), uno::UNO_QUERY ); + // fallback ( e.g. it's possible a new document was created via the api ) + // in that case the document will not have the appropriate Document Modules + // #TODO #FIXME ( needs to be fixes as part of providing support for an overall document + // vba mode etc. ) + if ( !xWrkbk.is() ) + return new ActiveWorkbook( this, mxContext ); + } + } + return xWrkbk; } uno::Reference< XAssistant > SAL_CALL @@ -246,10 +276,10 @@ ScVbaApplication::getSelection() throw (uno::RuntimeException) { uno::Reference< sheet::XSheetCellRangeContainer > xRanges( getCurrentDocument()->getCurrentSelection(), ::uno::UNO_QUERY); if ( xRanges.is() ) - return uno::makeAny( uno::Reference< excel::XRange >( new ScVbaRange( this, mxContext, xRanges ) ) ); + return uno::makeAny( uno::Reference< excel::XRange >( new ScVbaRange( excel::getUnoSheetModuleObj( xRanges ), mxContext, xRanges ) ) ); } - return uno::makeAny( uno::Reference< excel::XRange >(new ScVbaRange( this, mxContext, xRange ) ) ); + return uno::makeAny( uno::Reference< excel::XRange >(new ScVbaRange( excel::getUnoSheetModuleObj( xRange ), mxContext, xRange ) ) ); } else { @@ -531,10 +561,8 @@ ScVbaApplication::GoTo( const uno::Any& Reference, const uno::Any& Scroll ) thro ScGridWindow* gridWindow = (ScGridWindow*)pShell->GetWindow(); try { - // FIXME: pass proper Worksheet parent uno::Reference< excel::XRange > xVbaSheetRange = ScVbaRange::getRangeObjectForName( - uno::Reference< XHelperInterface >(), mxContext, sRangeName, - excel::getDocShell( xModel ), formula::FormulaGrammar::CONV_XL_R1C1 ); + mxContext, sRangeName, excel::getDocShell( xModel ), formula::FormulaGrammar::CONV_XL_R1C1 ); if( bScroll ) { @@ -681,14 +709,27 @@ ScVbaApplication::getName() throw (uno::RuntimeException) void SAL_CALL ScVbaApplication::setDisplayAlerts(sal_Bool displayAlerts) throw (uno::RuntimeException) { - m_xDisplayAlerts = displayAlerts; + m_bDisplayAlerts = displayAlerts; } sal_Bool SAL_CALL ScVbaApplication::getDisplayAlerts() throw (uno::RuntimeException) { - return m_xDisplayAlerts; + return m_bDisplayAlerts; +} + +void SAL_CALL +ScVbaApplication::setEnableEvents(sal_Bool bEnable) throw (uno::RuntimeException) +{ + m_bEnableEvents = bEnable; } + +sal_Bool SAL_CALL +ScVbaApplication::getEnableEvents() throw (uno::RuntimeException) +{ + return m_bEnableEvents; +} + void SAL_CALL ScVbaApplication::Calculate() throw( script::BasicErrorException , uno::RuntimeException ) { @@ -1068,12 +1109,13 @@ ScVbaApplication::Intersect( const uno::Reference< excel::XRange >& Arg1, const ScDocShell* pDocShell = excel::getDocShell( xModel ); if ( aCellRanges.Count() == 1 ) { - xRefRange = new ScVbaRange( uno::Reference< XHelperInterface >(), mxContext, new ScCellRangeObj( pDocShell, *aCellRanges.First() ) ); + uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pDocShell, *aCellRanges.First() )); + xRefRange = new ScVbaRange( excel::getUnoSheetModuleObj( xRange ), mxContext, xRange ); } else if ( aCellRanges.Count() > 1 ) { uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pDocShell, aCellRanges ) ); - xRefRange = new ScVbaRange( uno::Reference< XHelperInterface >(), mxContext, xRanges ); + xRefRange = new ScVbaRange( excel::getUnoSheetModuleObj( xRanges ) , mxContext, xRanges ); } return xRefRange; @@ -1158,12 +1200,13 @@ ScVbaApplication::Union( const uno::Reference< excel::XRange >& Arg1, const uno: if ( aCellRanges.Count() == 1 ) { // normal range - xRange = new ScVbaRange( uno::Reference< XHelperInterface >(), mxContext, new ScCellRangeObj( pDocShell, *aCellRanges.First() ) ); + uno::Reference< table::XCellRange > xCalcRange( new ScCellRangeObj( pDocShell, *aCellRanges.First() ) ); + xRange = new ScVbaRange( excel::getUnoSheetModuleObj( xCalcRange ), mxContext, xCalcRange ); } else if ( aCellRanges.Count() > 1 ) // Multi-Area { uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pDocShell, aCellRanges ) ); - xRange = new ScVbaRange( uno::Reference< XHelperInterface >(), mxContext, xRanges ); + xRange = new ScVbaRange( excel::getUnoSheetModuleObj( xRanges ), mxContext, xRanges ); } // #FIXME need proper (WorkSheet) parent diff --git a/sc/source/ui/vba/vbaapplication.hxx b/sc/source/ui/vba/vbaapplication.hxx index 96638651bcd12..a7be5feb1d279 100644 --- a/sc/source/ui/vba/vbaapplication.hxx +++ b/sc/source/ui/vba/vbaapplication.hxx @@ -43,7 +43,9 @@ class ScVbaApplication : public ScVbaApplication_BASE { private: sal_Int32 m_xCalculation; - sal_Bool m_xDisplayAlerts; + sal_Bool m_bDisplayAlerts; + sal_Bool m_bEnableEvents; + rtl::OUString getOfficePath( const rtl::OUString& sPath ) throw ( css::uno::RuntimeException ); protected: @@ -100,6 +102,9 @@ public: virtual ::sal_Int32 SAL_CALL getCursor() throw (css::uno::RuntimeException); virtual void SAL_CALL setCursor( ::sal_Int32 _cursor ) throw (css::uno::RuntimeException); + virtual sal_Bool SAL_CALL getEnableEvents() throw (css::uno::RuntimeException); + virtual void SAL_CALL setEnableEvents( sal_Bool bEnable ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL Windows( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException); virtual void SAL_CALL wait( double time ) throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL Range( const css::uno::Any& Cell1, const css::uno::Any& Cell2 ) throw (css::uno::RuntimeException); diff --git a/sc/source/ui/vba/vbachartobjects.cxx b/sc/source/ui/vba/vbachartobjects.cxx index 41b26501f4ada..5117cfd758587 100644 --- a/sc/source/ui/vba/vbachartobjects.cxx +++ b/sc/source/ui/vba/vbachartobjects.cxx @@ -47,16 +47,15 @@ using namespace ::ooo::vba; class ChartObjectEnumerationImpl : public EnumerationHelperImpl { uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier; - uno::Reference< XHelperInterface > xParent; public: - ChartObjectEnumerationImpl( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Reference< drawing::XDrawPageSupplier >& _xDrawPageSupplier, const uno::Reference< XHelperInterface >& _xParent ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xContext, xEnumeration ), xDrawPageSupplier( _xDrawPageSupplier ), xParent( _xParent ) {} + ChartObjectEnumerationImpl( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Reference< drawing::XDrawPageSupplier >& _xDrawPageSupplier, const uno::Reference< XHelperInterface >& _xParent ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( _xParent, xContext, xEnumeration ), xDrawPageSupplier( _xDrawPageSupplier ) {} virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) { uno::Reference< table::XTableChart > xTableChart( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW ); // parent Object is sheet - return uno::makeAny( uno::Reference< excel::XChartObject > ( new ScVbaChartObject( xParent, m_xContext, xTableChart, xDrawPageSupplier ) ) ); + return uno::makeAny( uno::Reference< excel::XChartObject > ( new ScVbaChartObject( m_xParent, m_xContext, xTableChart, xDrawPageSupplier ) ) ); } }; diff --git a/sc/source/ui/vba/vbacomments.cxx b/sc/source/ui/vba/vbacomments.cxx index a68dd42457417..7a6d3d7749373 100644 --- a/sc/source/ui/vba/vbacomments.cxx +++ b/sc/source/ui/vba/vbacomments.cxx @@ -50,10 +50,11 @@ class CommentEnumeration : public EnumerationHelperImpl css::uno::Reference< css::frame::XModel > mxModel; public: CommentEnumeration( + const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Reference< frame::XModel >& xModel ) throw ( uno::RuntimeException ) : - EnumerationHelperImpl( xContext, xEnumeration ), + EnumerationHelperImpl( xParent, xContext, xEnumeration ), mxModel( xModel, uno::UNO_SET_THROW ) {} @@ -80,8 +81,7 @@ uno::Reference< container::XEnumeration > ScVbaComments::createEnumeration() throw (uno::RuntimeException) { uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW ); - - return new CommentEnumeration( mxContext, xEnumAccess->createEnumeration(), mxModel ); + return new CommentEnumeration( mxParent, mxContext, xEnumAccess->createEnumeration(), mxModel ); } uno::Any diff --git a/sc/source/ui/vba/vbaeventshelper.cxx b/sc/source/ui/vba/vbaeventshelper.cxx new file mode 100755 index 0000000000000..45667adf2f2c1 --- /dev/null +++ b/sc/source/ui/vba/vbaeventshelper.cxx @@ -0,0 +1,753 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "vbaeventshelper.hxx" + +#include <com/sun/star/awt/XWindowListener.hpp> +#include <com/sun/star/frame/XBorderResizeListener.hpp> +#include <com/sun/star/frame/XControllerBorder.hpp> +#include <com/sun/star/script/vba/VBAEventId.hpp> +#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> +#include <com/sun/star/util/XCloseListener.hpp> + +#include <ooo/vba/excel/XApplication.hpp> + +#include <cppuhelper/implbase4.hxx> +#include <toolkit/unohlp.hxx> +#include <vbahelper/helperdecl.hxx> +#include <vcl/svapp.hxx> +#include <vcl/window.hxx> + +#include "cellsuno.hxx" +#include "convuno.hxx" + +using namespace ::com::sun::star; +using namespace ::com::sun::star::script::vba::VBAEventId; +using namespace ::ooo::vba; + +// ============================================================================ + +typedef ::cppu::WeakImplHelper4< + awt::XWindowListener, util::XCloseListener, frame::XBorderResizeListener, util::XChangesListener > ScVbaEventsListener_BASE; + +// This class is to process Workbook window related event +class ScVbaEventsListener : public ScVbaEventsListener_BASE +{ +public : + ScVbaEventsListener( ScVbaEventsHelper& rVbaEvents, const uno::Reference< frame::XModel >& rxModel, ScDocShell* pDocShell ); + virtual ~ScVbaEventsListener(); + + void startListening(); + void stopListening(); + + // XWindowListener + virtual void SAL_CALL windowResized( const awt::WindowEvent& aEvent ) throw (uno::RuntimeException); + virtual void SAL_CALL windowMoved( const awt::WindowEvent& aEvent ) throw (uno::RuntimeException); + virtual void SAL_CALL windowShown( const lang::EventObject& aEvent ) throw (uno::RuntimeException); + virtual void SAL_CALL windowHidden( const lang::EventObject& aEvent ) throw (uno::RuntimeException); + virtual void SAL_CALL disposing( const lang::EventObject& aEvent ) throw (uno::RuntimeException); + + // XCloseListener + virtual void SAL_CALL queryClosing( const lang::EventObject& Source, ::sal_Bool GetsOwnership ) throw (util::CloseVetoException, uno::RuntimeException); + virtual void SAL_CALL notifyClosing( const lang::EventObject& Source ) throw (uno::RuntimeException); + + // XBorderResizeListener + virtual void SAL_CALL borderWidthsChanged( const uno::Reference< uno::XInterface >& aObject, const frame::BorderWidths& aNewSize ) throw (uno::RuntimeException); + + // XChangesListener + virtual void SAL_CALL changesOccurred( const util::ChangesEvent& aEvent ) throw (uno::RuntimeException); + +private: + uno::Reference< frame::XFrame > getFrame(); + uno::Reference< awt::XWindow > getContainerWindow(); + bool isMouseReleased(); + DECL_LINK( fireResizeMacro, void* ); + void processWindowResizeMacro(); + +private: + ::osl::Mutex maMutex; + ScVbaEventsHelper& mrVbaEvents; + uno::Reference< frame::XModel > mxModel; + ScDocShell* mpDocShell; + bool mbWindowResized; + bool mbBorderChanged; + bool mbDisposed; +}; + +// ---------------------------------------------------------------------------- + +ScVbaEventsListener::ScVbaEventsListener( ScVbaEventsHelper& rVbaEvents, const uno::Reference< frame::XModel >& rxModel, ScDocShell* pDocShell ) : + mrVbaEvents( rVbaEvents ), + mxModel( rxModel ), + mpDocShell( pDocShell ), + mbWindowResized( false ), + mbBorderChanged( false ), + mbDisposed( !rxModel.is() ) +{ + OSL_TRACE( "ScVbaEventsListener::ScVbaEventsListener( 0x%x ) - ctor ", this ); +} + +ScVbaEventsListener::~ScVbaEventsListener() +{ + OSL_TRACE( "ScVbaEventsListener::~ScVbaEventsListener( 0x%x ) - dtor ", this ); + stopListening(); +} + +void ScVbaEventsListener::startListening() +{ + if( !mbDisposed ) + { + // add window listener + try + { + uno::Reference< awt::XWindow > xWindow( getContainerWindow(), uno::UNO_QUERY_THROW ); + xWindow->addWindowListener( this ); + } + catch( uno::Exception& ) + { + } + // add close listener + try + { + uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( mxModel, uno::UNO_QUERY_THROW ); + xCloseBroadcaster->addCloseListener( this ); + } + catch( uno::Exception& ) + { + } + // add Border resize listener + try + { + uno::Reference< frame::XControllerBorder > xControllerBorder( mxModel->getCurrentController(), uno::UNO_QUERY_THROW ); + xControllerBorder->addBorderResizeListener( this ); + } + catch( uno::Exception& ) + { + } + // add content change listener + try + { + uno::Reference< util::XChangesNotifier > xChangesNotifier( mxModel, uno::UNO_QUERY_THROW ); + xChangesNotifier->addChangesListener( this ); + } + catch( uno::Exception& ) + { + } + } +} + +void ScVbaEventsListener::stopListening() +{ + if( !mbDisposed ) + { + try + { + uno::Reference< awt::XWindow > xWindow( getContainerWindow(), uno::UNO_QUERY_THROW ); + xWindow->removeWindowListener( this ); + } + catch( uno::Exception& ) + { + } + try + { + uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( mxModel, uno::UNO_QUERY_THROW ); + xCloseBroadcaster->removeCloseListener( this ); + } + catch( uno::Exception& ) + { + } + try + { + uno::Reference< frame::XControllerBorder > xControllerBorder( mxModel->getCurrentController(), uno::UNO_QUERY_THROW ); + xControllerBorder->removeBorderResizeListener( this ); + } + catch( uno::Exception& ) + { + } + try + { + uno::Reference< util::XChangesNotifier > xChangesNotifier( mxModel, uno::UNO_QUERY_THROW ); + xChangesNotifier->removeChangesListener( this ); + } + catch( uno::Exception& ) + { + } + } + mbDisposed = true; +} + +void SAL_CALL ScVbaEventsListener::windowResized( const awt::WindowEvent& /*aEvent*/ ) throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( maMutex ); + // Workbook_window_resize event + mbWindowResized = true; + if( !mbDisposed && mbBorderChanged ) + { + if( /*Window* pWindow =*/ VCLUnoHelper::GetWindow( getContainerWindow() ) ) + { + mbBorderChanged = mbWindowResized = false; + acquire(); // ensure we don't get deleted before the event is handled + Application::PostUserEvent( LINK( this, ScVbaEventsListener, fireResizeMacro ), 0 ); + } + } +} + +void SAL_CALL ScVbaEventsListener::windowMoved( const awt::WindowEvent& /*aEvent*/ ) throw ( uno::RuntimeException ) +{ + // not interest this time +} + +void SAL_CALL ScVbaEventsListener::windowShown( const lang::EventObject& /*aEvent*/ ) throw ( uno::RuntimeException ) +{ + // not interest this time +} + +void SAL_CALL ScVbaEventsListener::windowHidden( const lang::EventObject& /*aEvent*/ ) throw ( uno::RuntimeException ) +{ + // not interest this time +} + +void SAL_CALL ScVbaEventsListener::disposing( const lang::EventObject& /*aEvent*/ ) throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( maMutex ); + OSL_TRACE( "ScVbaEventsListener::disposing( 0x%x )", this ); + mbDisposed = true; +} + +void SAL_CALL ScVbaEventsListener::queryClosing( const lang::EventObject& /*Source*/, sal_Bool /*GetsOwnership*/ ) throw (util::CloseVetoException, uno::RuntimeException) +{ + // it can cancel the close, but need to throw a CloseVetoException, and it will be transmit to caller. +} + +void SAL_CALL ScVbaEventsListener::notifyClosing( const lang::EventObject& /*Source*/ ) throw (uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( maMutex ); + stopListening(); +} + +void SAL_CALL ScVbaEventsListener::borderWidthsChanged( const uno::Reference< uno::XInterface >& /*aObject*/, const frame::BorderWidths& /*aNewSize*/ ) throw (uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( maMutex ); + // work with WindowResized event to guard Window Resize event. + mbBorderChanged = true; + if( !mbDisposed && mbWindowResized ) + { + if( /*Window* pWindow =*/ VCLUnoHelper::GetWindow( getContainerWindow() ) ) + { + mbWindowResized = mbBorderChanged = false; + acquire(); // ensure we don't get deleted before the timer fires. + Application::PostUserEvent( LINK( this, ScVbaEventsListener, fireResizeMacro ), 0 ); + } + } +} + +void SAL_CALL ScVbaEventsListener::changesOccurred( const util::ChangesEvent& aEvent ) throw (uno::RuntimeException) +{ + sal_Int32 nCount = aEvent.Changes.getLength(); + if( nCount == 0 ) + return; + + util::ElementChange aChange = aEvent.Changes[ 0 ]; + rtl::OUString sOperation; + aChange.Accessor >>= sOperation; + if( !sOperation.equalsIgnoreAsciiCaseAscii("cell-change") ) + return; + + if( nCount == 1 ) + { + uno::Reference< table::XCellRange > xRangeObj; + aChange.ReplacedElement >>= xRangeObj; + if( xRangeObj.is() ) + { + uno::Sequence< uno::Any > aArgs(1); + aArgs[0] <<= xRangeObj; + mrVbaEvents.processVbaEvent( WORKSHEET_CHANGE, aArgs ); + } + return; + } + + ScRangeList aRangeList; + for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex ) + { + aChange = aEvent.Changes[ nIndex ]; + aChange.Accessor >>= sOperation; + uno::Reference< table::XCellRange > xRangeObj; + aChange.ReplacedElement >>= xRangeObj; + if( xRangeObj.is() && sOperation.equalsIgnoreAsciiCaseAscii("cell-change") ) + { + uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable( xRangeObj, uno::UNO_QUERY ); + if( xCellRangeAddressable.is() ) + { + ScRange aRange; + ScUnoConversion::FillScRange( aRange, xCellRangeAddressable->getRangeAddress() ); + aRangeList.Append( aRange ); + } + } + } + + if( (aRangeList.Count() > 0) && mpDocShell ) + { + uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( mpDocShell, aRangeList ) ); + uno::Sequence< uno::Any > aArgs(1); + aArgs[0] <<= xRanges; + mrVbaEvents.processVbaEvent( WORKSHEET_CHANGE, aArgs ); + } +} + +// ---------------------------------------------------------------------------- + +uno::Reference< frame::XFrame > ScVbaEventsListener::getFrame() +{ + if( !mbDisposed && mxModel.is() ) try + { + uno::Reference< frame::XController > xController( mxModel->getCurrentController(), uno::UNO_QUERY_THROW ); + return xController->getFrame(); + } + catch( uno::Exception& ) + { + } + return uno::Reference< frame::XFrame >(); +} + +uno::Reference< awt::XWindow > ScVbaEventsListener::getContainerWindow() +{ + try + { + uno::Reference< frame::XFrame > xFrame( getFrame(), uno::UNO_SET_THROW ); + return xFrame->getContainerWindow(); + } + catch( uno::Exception& ) + { + } + return uno::Reference< awt::XWindow >(); +} + +bool ScVbaEventsListener::isMouseReleased() +{ + if( Window* pWindow = VCLUnoHelper::GetWindow( getContainerWindow() ) ) + { + Window::PointerState aPointerState = pWindow->GetPointerState(); + return (aPointerState.mnState & ( MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT )) == 0; + } + return false; +} + +IMPL_LINK( ScVbaEventsListener, fireResizeMacro, void*, EMPTYARG ) +{ + if( !mbDisposed && isMouseReleased() ) + processWindowResizeMacro(); + release(); + return 0; +} + +void ScVbaEventsListener::processWindowResizeMacro() +{ + OSL_TRACE( "**** Attempt to FIRE MACRO **** " ); + if( !mbDisposed ) + mrVbaEvents.processVbaEvent( WORKBOOK_WINDOWRESIZE, uno::Sequence< uno::Any >() ); +} + +// ============================================================================ + +ScVbaEventsHelper::ScVbaEventsHelper( const uno::Sequence< uno::Any >& rArgs, const uno::Reference< uno::XComponentContext >& xContext ) : + VbaEventsHelperBase( rArgs, xContext ), + mbOpened( false ) +{ + mpDocShell = dynamic_cast< ScDocShell* >( mpShell ); // mpShell from base class + mpDoc = mpDocShell ? mpDocShell->GetDocument() : 0; + + if( !mxModel.is() || !mpDocShell || !mpDoc ) + return; + +#define REGISTER_EVENT( eventid, eventname, type, cancelindex, worksheet ) \ + registerEventHandler( eventid, eventname, type, cancelindex, uno::Any( worksheet ) ) + +#define REGISTER_WORKBOOK_EVENT( eventid, eventname, cancelindex ) \ + REGISTER_EVENT( WORKBOOK_##eventid, "Workbook_" eventname, EVENTHANDLER_DOCUMENT, cancelindex, false ) + +#define REGISTER_WORKSHEET_EVENT( eventid, eventname, cancelindex ) \ + REGISTER_EVENT( WORKSHEET_##eventid, "Worksheet_" eventname, EVENTHANDLER_DOCUMENT, cancelindex, true ); \ + REGISTER_EVENT( (USERDEFINED_START + WORKSHEET_##eventid), "Workbook_Sheet" eventname, EVENTHANDLER_DOCUMENT, (((cancelindex) >= 0) ? ((cancelindex) + 1) : -1), false ) + + // global + REGISTER_EVENT( AUTO_OPEN, "Auto_Open", EVENTHANDLER_GLOBAL, -1, false ); + REGISTER_EVENT( AUTO_CLOSE, "Auto_Close", EVENTHANDLER_GLOBAL, -1, false ); + + // 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_EVENT +#undef REGISTER_WORKBOOK_EVENT +#undef REGISTER_WORKSHEET_EVENT +} + +ScVbaEventsHelper::~ScVbaEventsHelper() +{ +} + +void SAL_CALL ScVbaEventsHelper::disposing( const lang::EventObject& rSource ) throw (uno::RuntimeException) +{ + mxListener.clear(); + VbaEventsHelperBase::disposing( rSource ); +} + +// protected ------------------------------------------------------------------ + +bool ScVbaEventsHelper::implEventsEnabled() throw (uno::RuntimeException) +{ + // document and document shell are needed during event processing + if( !mpDocShell || !mpDoc ) + throw uno::RuntimeException(); + + // get Application object and check if events are enabled (this is an Excel-only attribute) + uno::Reference< excel::XApplication > xApplication( mxApplication.get(), uno::UNO_QUERY ); + if( !xApplication.is() && mpShell ) + { + uno::Any aVBAGlobals; + mpShell->GetBasicManager()->GetGlobalUNOConstant( "VBAGlobals", aVBAGlobals ); + uno::Reference< XHelperInterface > xHelperInterface( aVBAGlobals, uno::UNO_QUERY ); + if( xHelperInterface.is() ) + { + xApplication.set( xHelperInterface->Application(), uno::UNO_QUERY ); + mxApplication = xApplication; + } + } + if( !xApplication.is() ) + throw uno::RuntimeException(); + + // return whether event processing is enabled + return xApplication->getEnableEvents(); +} + +bool ScVbaEventsHelper::implPrepareEvent( EventQueue& rEventQueue, + const EventHandlerInfo& rInfo, const uno::Sequence< uno::Any >& rArgs ) throw (uno::RuntimeException) +{ + // check preconditions for some events, add more events if needed + bool bExecuteEvent = true; + switch( rInfo.mnEventId ) + { + case WORKBOOK_ACTIVATE: + // while loading, framework fires this before 'opened' event, delay it + bExecuteEvent = mbOpened; + break; + case WORKBOOK_OPEN: + bExecuteEvent = !mbOpened; + if( bExecuteEvent ) + { + // execute delayed Activate event too (see above) + rEventQueue.push_back( WORKBOOK_ACTIVATE ); + rEventQueue.push_back( WORKBOOK_WINDOWACTIVATE ); + rEventQueue.push_back( AUTO_OPEN ); + } + break; + case WORKSHEET_SELECTIONCHANGE: + // if selection is not changed, then do not fire the event + bExecuteEvent = mbOpened && isSelectionChanged( rArgs, 0 ); + break; + } + + // add workbook event associated to a sheet event + bool bSheetEvent = false; + rInfo.maUserData >>= bSheetEvent; + if( bSheetEvent && bExecuteEvent ) + rEventQueue.push_back( EventQueueEntry( rInfo.mnEventId + USERDEFINED_START, rArgs ) ); + + return bExecuteEvent; +} + +uno::Sequence< uno::Any > ScVbaEventsHelper::implBuildArgumentList( const EventHandlerInfo& rInfo, + const uno::Sequence< uno::Any >& rArgs ) throw (lang::IllegalArgumentException) +{ + // 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 ); + aVbaArgs[ 0 ] = createWindow(); + 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, + const EventHandlerInfo& rInfo, bool /*bSuccess*/, bool bCancel ) throw (uno::RuntimeException) +{ + switch( rInfo.mnEventId ) + { + case WORKBOOK_OPEN: + mbOpened = true; + // register the listeners + if( !mxListener.is() ) + { + mxListener = new ScVbaEventsListener( *this, mxModel, mpDocShell ); + mxListener->startListening(); + } + break; + case WORKBOOK_BEFORECLOSE: + /* Execute Auto_Close only if not cancelled by event handler, but + before UI asks user whether to cancel closing the document. */ + if( !bCancel ) + rEventQueue.push_back( AUTO_CLOSE ); + break; + } +} + +::rtl::OUString ScVbaEventsHelper::implGetDocumentModuleName( const EventHandlerInfo& rInfo, + const uno::Sequence< uno::Any >& rArgs ) const throw (lang::IllegalArgumentException) +{ + bool bSheetEvent = false; + rInfo.maUserData >>= bSheetEvent; + SCTAB nTab = bSheetEvent ? getTabFromArgs( rArgs, 0 ) : -1; + if( bSheetEvent && (nTab < 0) ) + throw lang::IllegalArgumentException(); + + String aCodeName; + if( bSheetEvent ) + mpDoc->GetCodeName( nTab, aCodeName ); + else + aCodeName = mpDoc->GetCodeName(); + return aCodeName; +} + +// private -------------------------------------------------------------------- + +SCTAB ScVbaEventsHelper::getTabFromArgs( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) throw (lang::IllegalArgumentException) +{ + checkArgument( rArgs, nIndex ); + + // first try to extract a sheet index + SCTAB nTab = -1; + if( rArgs[ nIndex ] >>= nTab ) + return nTab; + + // next, try single range object + uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable = getXSomethingFromArgs< sheet::XCellRangeAddressable >( rArgs, nIndex ); + if( xCellRangeAddressable.is() ) + return xCellRangeAddressable->getRangeAddress().Sheet; + + // at last, try range list + 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(); +} + +bool ScVbaEventsHelper::isSelectionChanged( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) throw (lang::IllegalArgumentException, uno::RuntimeException) +{ + uno::Reference< uno::XInterface > xNewSelection = getXSomethingFromArgs< uno::XInterface >( rArgs, nIndex, false ); + if( ScCellRangesBase* pNewCellRanges = ScCellRangesBase::getImplementation( xNewSelection ) ) + { + bool bChanged = maOldSelection != pNewCellRanges->GetRangeList(); + maOldSelection = pNewCellRanges->GetRangeList(); + return bChanged; + } + maOldSelection.Clear(); + return true; +} + +uno::Any ScVbaEventsHelper::createWorksheet( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) const + throw (lang::IllegalArgumentException, uno::RuntimeException) +{ + // Eventually we will be able to pull the Workbook/Worksheet objects + // directly from basic and register them as listeners + + // extract sheet index, will throw, if parameter is invalid + SCTAB nTab = getTabFromArgs( rArgs, nIndex ); + + // create Workbook + uno::Sequence< uno::Any > aArgs( 2 ); + aArgs[ 0 ] <<= uno::Reference< uno::XInterface >(); + aArgs[ 1 ] <<= mxModel; + uno::Reference< uno::XInterface > xWorkbook( createVBAUnoAPIServiceWithArgs( mpShell, "ooo.vba.excel.Workbook", aArgs ), uno::UNO_SET_THROW ); + + // create WorkSheet + String aSheetName; + mpDoc->GetName( nTab, aSheetName ); + aArgs = uno::Sequence< uno::Any >( 3 ); + aArgs[ 0 ] <<= xWorkbook; + aArgs[ 1 ] <<= mxModel; + aArgs[ 2 ] <<= ::rtl::OUString( aSheetName ); + uno::Reference< uno::XInterface > xWorksheet( createVBAUnoAPIServiceWithArgs( mpShell, "ooo.vba.excel.Worksheet", aArgs ), uno::UNO_SET_THROW ); + return uno::Any( xWorksheet ); +} + +uno::Any ScVbaEventsHelper::createRange( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) const + throw (lang::IllegalArgumentException, uno::RuntimeException) +{ + 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(); + + uno::Sequence< uno::Any > aArgs( 2 ); + aArgs[ 0 ] <<= uno::Reference< uno::XInterface >(); // dummy parent + if ( xRanges.is() ) + aArgs[ 1 ] <<= xRanges; + else + aArgs[ 1 ] <<= xRange; + uno::Reference< uno::XInterface > xVbaRange( createVBAUnoAPIServiceWithArgs( mpShell, "ooo.vba.excel.Range", aArgs ), uno::UNO_SET_THROW ); + return uno::Any( xVbaRange ); +} + +uno::Any ScVbaEventsHelper::createHyperlink( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) const + throw (lang::IllegalArgumentException, uno::RuntimeException) +{ + uno::Sequence< uno::Any > aArgs( 2 ); + aArgs[ 0 ] <<= uno::Reference< uno::XInterface >(); // dummy parent + aArgs[ 1 ] <<= getXSomethingFromArgs< table::XCell >( rArgs, nIndex, false ); + uno::Reference< uno::XInterface > xHyperlink( createVBAUnoAPIServiceWithArgs( mpShell, "ooo.vba.excel.Hyperlink", aArgs ), uno::UNO_SET_THROW ); + return uno::Any( xHyperlink ); +} + +uno::Any ScVbaEventsHelper::createWindow() const throw (uno::RuntimeException) +{ + uno::Sequence< uno::Any > aArgs( 2 ); + aArgs[ 0 ] <<= createVBAUnoAPIService( mpShell, "ooo.vba.Application" ); + aArgs[ 1 ] <<= mxModel; + uno::Reference< uno::XInterface > xWindow( createVBAUnoAPIServiceWithArgs( mpShell, "ooo.vba.excel.Window", aArgs ), uno::UNO_SET_THROW ); + return uno::Any( xWindow ); +} + +// ============================================================================ + +namespace vbaeventshelper +{ +namespace sdecl = comphelper::service_decl; +sdecl::class_<ScVbaEventsHelper, sdecl::with_args<true> > serviceImpl; +extern sdecl::ServiceDecl const serviceDecl( + serviceImpl, + "ScVbaEventsHelper", + "com.sun.star.script.vba.VBASpreadsheetEventProcessor" ); +} + +// ============================================================================ diff --git a/sc/source/ui/vba/vbaeventshelper.hxx b/sc/source/ui/vba/vbaeventshelper.hxx new file mode 100755 index 0000000000000..a77f5128b3e96 --- /dev/null +++ b/sc/source/ui/vba/vbaeventshelper.hxx @@ -0,0 +1,88 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_VBAEVENTS_HXX +#define SC_VBAEVENTS_HXX + +#include <rtl/ref.hxx> +#include <vbahelper/vbaeventshelperbase.hxx> +#include "excelvbahelper.hxx" +#include "rangelst.hxx" + +namespace ooo { namespace vba { namespace excel { class XApplication; } } } + +class ScVbaEventsListener; + +// ============================================================================ + +class ScVbaEventsHelper : public VbaEventsHelperBase +{ +public: + ScVbaEventsHelper( + const css::uno::Sequence< css::uno::Any >& rArgs, + const css::uno::Reference< css::uno::XComponentContext >& rxContext ); + virtual ~ScVbaEventsHelper(); + + // XEventListener + virtual void SAL_CALL disposing( const css::lang::EventObject& rSource ) throw (css::uno::RuntimeException); + +protected: + virtual bool implEventsEnabled() throw (css::uno::RuntimeException); + virtual bool implPrepareEvent( EventQueue& rEventQueue, const EventHandlerInfo& rInfo, const css::uno::Sequence< css::uno::Any >& rArgs ) throw (css::uno::RuntimeException); + virtual css::uno::Sequence< css::uno::Any > implBuildArgumentList( const EventHandlerInfo& rInfo, const css::uno::Sequence< css::uno::Any >& rArgs ) throw (css::lang::IllegalArgumentException); + virtual void implPostProcessEvent( EventQueue& rEventQueue, const EventHandlerInfo& rInfo, bool bSuccess, bool bCancel ) throw (css::uno::RuntimeException); + virtual ::rtl::OUString implGetDocumentModuleName( const EventHandlerInfo& rInfo, const css::uno::Sequence< css::uno::Any >& rArgs ) const throw (css::lang::IllegalArgumentException); + +private: + /** Extracts a sheet index from the first element of the passed sequence. The + element may be an integer, or a Calc range or ranges object. */ + static SCTAB getTabFromArgs( const css::uno::Sequence< css::uno::Any >& rArgs, sal_Int32 nIndex ) throw (css::lang::IllegalArgumentException); + /** Checks if selection has been changed compared to selection of last call. + @return true, if the selection has been changed. */ + bool isSelectionChanged( const css::uno::Sequence< css::uno::Any >& rArgs, sal_Int32 nIndex ) throw (css::lang::IllegalArgumentException, css::uno::RuntimeException); + + /** Creates a VBA Worksheet object (the argument must contain a sheet index). */ + css::uno::Any createWorksheet( const css::uno::Sequence< css::uno::Any >& rArgs, sal_Int32 nIndex ) const throw (css::lang::IllegalArgumentException, css::uno::RuntimeException); + /** Creates a VBA Range object (the argument must contain a UNO range or UNO range list). */ + css::uno::Any createRange( const css::uno::Sequence< css::uno::Any >& rArgs, sal_Int32 nIndex ) const throw (css::lang::IllegalArgumentException, css::uno::RuntimeException); + /** Creates a VBA Hyperlink object (the argument must contain a UNO cell). */ + css::uno::Any createHyperlink( const css::uno::Sequence< css::uno::Any >& rArgs, sal_Int32 nIndex ) const throw (css::lang::IllegalArgumentException, css::uno::RuntimeException); + /** Creates a VBA Window object. */ + css::uno::Any createWindow() const throw (css::uno::RuntimeException); + +private: + mutable css::uno::WeakReference< ov::excel::XApplication > mxApplication; + ::rtl::Reference< ScVbaEventsListener > mxListener; + ScDocShell* mpDocShell; + ScDocument* mpDoc; + ScRangeList maOldSelection; + bool mbOpened; +}; + +// ============================================================================ + +#endif diff --git a/sc/source/ui/vba/vbaformatconditions.cxx b/sc/source/ui/vba/vbaformatconditions.cxx index 91d0429326dda..8dd67843ec003 100644 --- a/sc/source/ui/vba/vbaformatconditions.cxx +++ b/sc/source/ui/vba/vbaformatconditions.cxx @@ -45,11 +45,11 @@ static rtl::OUString FORMULA2( RTL_CONSTASCII_USTRINGPARAM("Formula2") ); static rtl::OUString STYLENAME( RTL_CONSTASCII_USTRINGPARAM("StyleName") ); static rtl::OUString sStyleNamePrefix( RTL_CONSTASCII_USTRINGPARAM("Excel_CondFormat") ); -ScVbaFormatConditions::ScVbaFormatConditions( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< sheet::XSheetConditionalEntries >& _xSheetConditionalEntries, const uno::Reference< frame::XModel >& xModel ) : ScVbaFormatConditions_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( _xSheetConditionalEntries, uno::UNO_QUERY_THROW ) ), mxSheetConditionalEntries( _xSheetConditionalEntries ) +ScVbaFormatConditions::ScVbaFormatConditions( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< sheet::XSheetConditionalEntries >& _xSheetConditionalEntries, const uno::Reference< frame::XModel >& /*xModel*/ ) : ScVbaFormatConditions_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( _xSheetConditionalEntries, uno::UNO_QUERY_THROW ) ), mxSheetConditionalEntries( _xSheetConditionalEntries ) { mxRangeParent.set( xParent, uno::UNO_QUERY_THROW ); - uno::Reference< excel::XWorkbook > xWorkbook = new ScVbaWorkbook( uno::Reference< XHelperInterface >( Application(), uno::UNO_QUERY_THROW ), xContext, xModel ); - mxStyles.set( xWorkbook->Styles( uno::Any() ), uno::UNO_QUERY_THROW ); + uno::Reference< excel::XApplication> xApp( Application(), uno::UNO_QUERY_THROW ); + mxStyles.set( xApp->getThisWorkbook()->Styles( uno::Any() ), uno::UNO_QUERY_THROW ); uno::Reference< sheet::XCellRangeAddressable > xCellRange( mxRangeParent->getCellRange(), uno::UNO_QUERY_THROW ); mxParentRangePropertySet.set( xCellRange, uno::UNO_QUERY_THROW ); diff --git a/sc/source/ui/vba/vbaglobals.cxx b/sc/source/ui/vba/vbaglobals.cxx index 0cddacafd1942..03f3ecd3c50cb 100644 --- a/sc/source/ui/vba/vbaglobals.cxx +++ b/sc/source/ui/vba/vbaglobals.cxx @@ -233,6 +233,7 @@ ScVbaGlobals::getAvailableServiceNames( ) throw (uno::RuntimeException) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "ooo.vba.excel.Worksheet" ) ), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "ooo.vba.excel.Application" ) ), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "ooo.vba.excel.Hyperlink" ) ), + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.script.vba.VBASpreadsheetEventProcessor" ) ) }; sal_Int32 nExcelServices = ( sizeof( names )/ sizeof( names[0] ) ); sal_Int32 startIndex = serviceNames.getLength(); diff --git a/sc/source/ui/vba/vbaname.cxx b/sc/source/ui/vba/vbaname.cxx index a6e8a402425f5..464b167df2509 100644 --- a/sc/source/ui/vba/vbaname.cxx +++ b/sc/source/ui/vba/vbaname.cxx @@ -232,10 +232,8 @@ ScVbaName::setRefersToR1C1Local( const ::rtl::OUString & rRefersTo ) throw (css: css::uno::Reference< ov::excel::XRange > ScVbaName::getRefersToRange() throw (css::uno::RuntimeException) { - // FIXME: pass proper Worksheet parent uno::Reference< ov::excel::XRange > xRange = ScVbaRange::getRangeObjectForName( - uno::Reference< XHelperInterface >(), mxContext, - mxNamedRange->getName(), excel::getDocShell( mxModel ), formula::FormulaGrammar::CONV_XL_R1C1 ); + mxContext, mxNamedRange->getName(), excel::getDocShell( mxModel ), formula::FormulaGrammar::CONV_XL_R1C1 ); return xRange; } diff --git a/sc/source/ui/vba/vbanames.cxx b/sc/source/ui/vba/vbanames.cxx index d074f32b689d4..2304874bdb1ba 100644 --- a/sc/source/ui/vba/vbanames.cxx +++ b/sc/source/ui/vba/vbanames.cxx @@ -48,7 +48,7 @@ class NamesEnumeration : public EnumerationHelperImpl uno::WeakReference< XHelperInterface > m_xParent; uno::Reference< sheet::XNamedRanges > m_xNames; public: - NamesEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Reference< frame::XModel >& xModel , const uno::Reference< sheet::XNamedRanges >& xNames ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xContext, xEnumeration ), m_xModel( xModel ), m_xParent( xParent ), m_xNames( xNames ) {} + NamesEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Reference< frame::XModel >& xModel , const uno::Reference< sheet::XNamedRanges >& xNames ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), m_xModel( xModel ), m_xParent( xParent ), m_xNames( xNames ) {} virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) { diff --git a/sc/source/ui/vba/vbapivottables.cxx b/sc/source/ui/vba/vbapivottables.cxx index 05a4201da977e..fcbf347a3cd44 100644 --- a/sc/source/ui/vba/vbapivottables.cxx +++ b/sc/source/ui/vba/vbapivottables.cxx @@ -42,7 +42,7 @@ uno::Any DataPilotToPivotTable( const uno::Any& aSource, uno::Reference< uno::XC class PivotTableEnumeration : public EnumerationHelperImpl { public: - PivotTableEnumeration( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xContext, xEnumeration ) {} + PivotTableEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ) {} virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) { @@ -59,7 +59,7 @@ uno::Reference< container::XEnumeration > ScVbaPivotTables::createEnumeration() throw (uno::RuntimeException) { uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW ); - return new PivotTableEnumeration( mxContext, xEnumAccess->createEnumeration() ); + return new PivotTableEnumeration( mxParent, mxContext, xEnumAccess->createEnumeration() ); } uno::Any diff --git a/sc/source/ui/vba/vbarange.cxx b/sc/source/ui/vba/vbarange.cxx index ccf5a3bc5b541..b50199f025d0a 100644..100755 --- a/sc/source/ui/vba/vbarange.cxx +++ b/sc/source/ui/vba/vbarange.cxx @@ -202,11 +202,10 @@ double lcl_Round2DecPlaces( double nVal ) return nVal; } -uno::Any lcl_makeRange( uno::Reference< uno::XComponentContext >& xContext, const uno::Any aAny, bool bIsRows, bool bIsColumns ) +uno::Any lcl_makeRange( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Any aAny, bool bIsRows, bool bIsColumns ) { uno::Reference< table::XCellRange > xCellRange( aAny, uno::UNO_QUERY_THROW ); - // #FIXME need proper (WorkSheet) parent - return uno::makeAny( uno::Reference< excel::XRange >( new ScVbaRange( uno::Reference< XHelperInterface >(), xContext, xCellRange, bIsRows, bIsColumns ) ) ); + return uno::makeAny( uno::Reference< excel::XRange >( new ScVbaRange( xParent, xContext, xCellRange, bIsRows, bIsColumns ) ) ); } uno::Reference< excel::XRange > lcl_makeXRangeFromSheetCellRanges( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< sheet::XSheetCellRanges >& xLocSheetCellRanges, ScDocShell* pDoc ) @@ -227,13 +226,11 @@ uno::Reference< excel::XRange > lcl_makeXRangeFromSheetCellRanges( const uno::Re if ( aCellRanges.First() == aCellRanges.Last() ) { uno::Reference< table::XCellRange > xTmpRange( new ScCellRangeObj( pDoc, *aCellRanges.First() ) ); - // #FIXME need proper (WorkSheet) parent xRange = new ScVbaRange( xParent, xContext, xTmpRange ); } else { uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pDoc, aCellRanges ) ); - // #FIXME need proper (WorkSheet) parent xRange = new ScVbaRange( xParent, xContext, xRanges ); } } @@ -269,12 +266,13 @@ SfxItemSet* ScVbaRange::getCurrentDataSet( ) throw ( uno::RuntimeException ) class SingleRangeEnumeration : public EnumerationHelper_BASE { + uno::Reference< XHelperInterface > m_xParent; uno::Reference< table::XCellRange > m_xRange; uno::Reference< uno::XComponentContext > mxContext; bool bHasMore; public: - SingleRangeEnumeration( const uno::Reference< css::uno::XComponentContext >& xContext, const uno::Reference< table::XCellRange >& xRange ) throw ( uno::RuntimeException ) : m_xRange( xRange ), mxContext( xContext ), bHasMore( true ) { } + SingleRangeEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< css::uno::XComponentContext >& xContext, const uno::Reference< table::XCellRange >& xRange ) throw ( uno::RuntimeException ) : m_xParent( xParent ), m_xRange( xRange ), mxContext( xContext ), bHasMore( true ) { } virtual ::sal_Bool SAL_CALL hasMoreElements( ) throw (uno::RuntimeException) { return bHasMore; } virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) { @@ -292,11 +290,12 @@ typedef ::cppu::WeakImplHelper2< container::XIndexAccess, container::XEnumeratio class SingleRangeIndexAccess : public SingleRange_BASE { private: + uno::Reference< XHelperInterface > mxParent; uno::Reference< table::XCellRange > m_xRange; uno::Reference< uno::XComponentContext > mxContext; SingleRangeIndexAccess(); // not defined public: - SingleRangeIndexAccess( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< table::XCellRange >& xRange ):m_xRange( xRange ), mxContext( xContext ) {} + SingleRangeIndexAccess( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< table::XCellRange >& xRange ):mxParent( xParent ), m_xRange( xRange ), mxContext( xContext ) {} // XIndexAccess virtual ::sal_Int32 SAL_CALL getCount() throw (::uno::RuntimeException) { return 1; } virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException) @@ -310,7 +309,7 @@ public: virtual ::sal_Bool SAL_CALL hasElements() throw (uno::RuntimeException) { return sal_True; } // XEnumerationAccess - virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration() throw (uno::RuntimeException) { return new SingleRangeEnumeration( mxContext, m_xRange ); } + virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration() throw (uno::RuntimeException) { return new SingleRangeEnumeration( mxParent, mxContext, m_xRange ); } }; @@ -322,10 +321,10 @@ class RangesEnumerationImpl : public EnumerationHelperImpl bool mbIsColumns; public: - RangesEnumerationImpl( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, bool bIsRows, bool bIsColumns ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xContext, xEnumeration ), mbIsRows( bIsRows ), mbIsColumns( bIsColumns ) {} + RangesEnumerationImpl( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, bool bIsRows, bool bIsColumns ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), mbIsRows( bIsRows ), mbIsColumns( bIsColumns ) {} virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) { - return lcl_makeRange( m_xContext, m_xEnumeration->nextElement(), mbIsRows, mbIsColumns ); + return lcl_makeRange( m_xParent, m_xContext, m_xEnumeration->nextElement(), mbIsRows, mbIsColumns ); } }; @@ -335,7 +334,7 @@ class ScVbaRangeAreas : public ScVbaCollectionBaseImpl bool mbIsRows; bool mbIsColumns; public: - ScVbaRangeAreas( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XIndexAccess >& xIndexAccess, bool bIsRows, bool bIsColumns ) : ScVbaCollectionBaseImpl( uno::Reference< XHelperInterface >(), xContext, xIndexAccess ), mbIsRows( bIsRows ), mbIsColumns( bIsColumns ) {} + ScVbaRangeAreas( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XIndexAccess >& xIndexAccess, bool bIsRows, bool bIsColumns ) : ScVbaCollectionBaseImpl( xParent, xContext, xIndexAccess ), mbIsRows( bIsRows ), mbIsColumns( bIsColumns ) {} // XEnumerationAccess virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration() throw (uno::RuntimeException); @@ -355,14 +354,13 @@ uno::Reference< container::XEnumeration > SAL_CALL ScVbaRangeAreas::createEnumeration() throw (uno::RuntimeException) { uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW ); - return new RangesEnumerationImpl( mxContext, xEnumAccess->createEnumeration(), mbIsRows, mbIsColumns ); - + return new RangesEnumerationImpl( mxParent, mxContext, xEnumAccess->createEnumeration(), mbIsRows, mbIsColumns ); } uno::Any ScVbaRangeAreas::createCollectionObject( const uno::Any& aSource ) { - return lcl_makeRange( mxContext, aSource, mbIsRows, mbIsColumns ); + return lcl_makeRange( mxParent, mxContext, aSource, mbIsRows, mbIsColumns ); } // assume that xIf is infact a ScCellRangesBase @@ -618,6 +616,7 @@ public: class CellsEnumeration : public CellsEnumeration_BASE { + uno::WeakReference< XHelperInterface > mxParent; uno::Reference< uno::XComponentContext > mxContext; uno::Reference< XCollection > m_xAreas; vCellPos m_CellPositions; @@ -645,7 +644,7 @@ class CellsEnumeration : public CellsEnumeration_BASE } } public: - CellsEnumeration( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< XCollection >& xAreas ): mxContext( xContext ), m_xAreas( xAreas ) + CellsEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< XCollection >& xAreas ): mxParent( xParent ), mxContext( xContext ), m_xAreas( xAreas ) { sal_Int32 nItems = m_xAreas->getCount(); for ( sal_Int32 index=1; index <= nItems; ++index ) @@ -664,8 +663,7 @@ public: uno::Reference< table::XCellRange > xRangeArea = getArea( aPos.m_nArea ); uno::Reference< table::XCellRange > xCellRange( xRangeArea->getCellByPosition( aPos.m_nCol, aPos.m_nRow ), uno::UNO_QUERY_THROW ); - // #FIXME need proper (WorkSheet) parent - return uno::makeAny( uno::Reference< excel::XRange >( new ScVbaRange( uno::Reference< XHelperInterface >(), mxContext, xCellRange ) ) ); + return uno::makeAny( uno::Reference< excel::XRange >( new ScVbaRange( mxParent, mxContext, xCellRange ) ) ); } }; @@ -1088,11 +1086,11 @@ public: return uno::Reference< sheet::XSheetCellCursor >( getSpreadSheet()->createCursorByRange( getSheetCellRange() ), uno::UNO_QUERY_THROW ); } - static uno::Reference< excel::XRange > createRangeFromRange( const uno::Reference<uno::XComponentContext >& xContext, const uno::Reference< table::XCellRange >& xRange, const uno::Reference< sheet::XCellRangeAddressable >& xCellRangeAddressable, sal_Int32 nStartColOffset = 0, sal_Int32 nStartRowOffset = 0, - sal_Int32 nEndColOffset = 0, sal_Int32 nEndRowOffset = 0 ) + static uno::Reference< excel::XRange > createRangeFromRange( const uno::Reference< XHelperInterface >& xParent, const uno::Reference<uno::XComponentContext >& xContext, + const uno::Reference< table::XCellRange >& xRange, const uno::Reference< sheet::XCellRangeAddressable >& xCellRangeAddressable, + sal_Int32 nStartColOffset = 0, sal_Int32 nStartRowOffset = 0, sal_Int32 nEndColOffset = 0, sal_Int32 nEndRowOffset = 0 ) { - // #FIXME need proper (WorkSheet) parent - return uno::Reference< excel::XRange >( new ScVbaRange( uno::Reference< XHelperInterface >(), xContext, + return uno::Reference< excel::XRange >( new ScVbaRange( xParent, xContext, xRange->getCellRangeByPosition( xCellRangeAddressable->getRangeAddress().StartColumn + nStartColOffset, xCellRangeAddressable->getRangeAddress().StartRow + nStartRowOffset, @@ -1178,7 +1176,7 @@ bool getScRangeListForAddress( const rtl::OUString& sName, ScDocShell* pDocSh, S ScVbaRange* -getRangeForName( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const rtl::OUString& sName, ScDocShell* pDocSh, table::CellRangeAddress& pAddr, formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_XL_A1 ) throw ( uno::RuntimeException ) +getRangeForName( const uno::Reference< uno::XComponentContext >& xContext, const rtl::OUString& sName, ScDocShell* pDocSh, table::CellRangeAddress& pAddr, formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_XL_A1 ) throw ( uno::RuntimeException ) { ScRangeList aCellRanges; ScRange refRange; @@ -1189,10 +1187,13 @@ getRangeForName( const uno::Reference< XHelperInterface >& xParent, const uno::R if ( aCellRanges.First() == aCellRanges.Last() ) { uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pDocSh, *aCellRanges.First() ) ); - return new ScVbaRange( xParent, xContext, xRange ); + uno::Reference< XHelperInterface > xFixThisParent = excel::getUnoSheetModuleObj( xRange ); + return new ScVbaRange( xFixThisParent, xContext, xRange ); } uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pDocSh, aCellRanges ) ); - return new ScVbaRange( xParent, xContext, xRanges ); + + uno::Reference< XHelperInterface > xFixThisParent = excel::getUnoSheetModuleObj( xRanges ); + return new ScVbaRange( xFixThisParent, xContext, xRanges ); } // ---------------------------------------------------------------------------- @@ -1284,12 +1285,12 @@ util::TriState lclGetMergedState( const uno::Reference< table::XCellRange >& rxC // ---------------------------------------------------------------------------- css::uno::Reference< excel::XRange > -ScVbaRange::getRangeObjectForName( const css::uno::Reference< ov::XHelperInterface >& xParent, +ScVbaRange::getRangeObjectForName( const uno::Reference< uno::XComponentContext >& xContext, const rtl::OUString& sRangeName, ScDocShell* pDocSh, formula::FormulaGrammar::AddressConvention eConv ) throw ( uno::RuntimeException ) { table::CellRangeAddress refAddr; - return getRangeForName( xParent, xContext, sRangeName, pDocSh, refAddr, eConv ); + return getRangeForName( xContext, sRangeName, pDocSh, refAddr, eConv ); } @@ -1348,13 +1349,13 @@ ScVbaRange::ScVbaRange( uno::Sequence< uno::Any> const & args, uno::Reference< container::XIndexAccess > xIndex; if ( mxRange.is() ) { - xIndex = new SingleRangeIndexAccess( mxContext, mxRange ); + xIndex = new SingleRangeIndexAccess( mxParent, mxContext, mxRange ); } else if ( mxRanges.is() ) { xIndex.set( mxRanges, uno::UNO_QUERY_THROW ); } - m_Areas = new ScVbaRangeAreas( mxContext, xIndex, mbIsRows, mbIsColumns ); + m_Areas = new ScVbaRangeAreas( mxParent, mxContext, xIndex, mbIsRows, mbIsColumns ); } ScVbaRange::ScVbaRange( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< table::XCellRange >& xRange, sal_Bool bIsRows, sal_Bool bIsColumns ) throw( lang::IllegalArgumentException ) @@ -1367,8 +1368,8 @@ ScVbaRange::ScVbaRange( const uno::Reference< XHelperInterface >& xParent, const if ( !xRange.is() ) throw lang::IllegalArgumentException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "range is not set " ) ), uno::Reference< uno::XInterface >() , 1 ); - uno::Reference< container::XIndexAccess > xIndex( new SingleRangeIndexAccess( mxContext, xRange ) ); - m_Areas = new ScVbaRangeAreas( mxContext, xIndex, mbIsRows, mbIsColumns ); + uno::Reference< container::XIndexAccess > xIndex( new SingleRangeIndexAccess( mxParent, mxContext, xRange ) ); + m_Areas = new ScVbaRangeAreas( mxParent, mxContext, xIndex, mbIsRows, mbIsColumns ); } @@ -1377,7 +1378,7 @@ ScVbaRange::ScVbaRange( const uno::Reference< XHelperInterface >& xParent, const { uno::Reference< container::XIndexAccess > xIndex( mxRanges, uno::UNO_QUERY_THROW ); - m_Areas = new ScVbaRangeAreas( mxContext, xIndex, mbIsRows, mbIsColumns ); + m_Areas = new ScVbaRangeAreas( xParent, mxContext, xIndex, mbIsRows, mbIsColumns ); } @@ -1806,11 +1807,11 @@ ScVbaRange::Offset( const ::uno::Any &nRowOff, const uno::Any &nColOff ) throw ( if ( aCellRanges.Count() > 1 ) // Multi-Area { uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pUnoRangesBase->GetDocShell(), aCellRanges ) ); - return new ScVbaRange( getParent(), mxContext, xRanges ); + return new ScVbaRange( mxParent, mxContext, xRanges ); } // normal range uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pUnoRangesBase->GetDocShell(), *aCellRanges.First() ) ); - return new ScVbaRange( getParent(), mxContext, xRange ); + return new ScVbaRange( mxParent, mxContext, xRange ); } uno::Reference< excel::XRange > @@ -1831,7 +1832,7 @@ ScVbaRange::CurrentRegion() throw (uno::RuntimeException) helper.getSheetCellCursor(); xSheetCellCursor->collapseToCurrentRegion(); uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable(xSheetCellCursor, uno::UNO_QUERY_THROW); - return RangeHelper::createRangeFromRange( mxContext, helper.getCellRangeFromSheet(), xCellRangeAddressable ); + return RangeHelper::createRangeFromRange( mxParent, mxContext, helper.getCellRangeFromSheet(), xCellRangeAddressable ); } uno::Reference< excel::XRange > @@ -1851,7 +1852,7 @@ ScVbaRange::CurrentArray() throw (uno::RuntimeException) helper.getSheetCellCursor(); xSheetCellCursor->collapseToCurrentArray(); uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable(xSheetCellCursor, uno::UNO_QUERY_THROW); - return RangeHelper::createRangeFromRange( mxContext, helper.getCellRangeFromSheet(), xCellRangeAddressable ); + return RangeHelper::createRangeFromRange( mxParent, mxContext, helper.getCellRangeFromSheet(), xCellRangeAddressable ); } uno::Any @@ -2069,7 +2070,7 @@ ScVbaRange::Cells( const uno::Any &nRowIndex, const uno::Any &nColumnIndex ) thr uno::Reference< table::XCellRange > xSheetRange = thisRange.getCellRangeFromSheet(); if( !bIsIndex && !bIsColumnIndex ) // .Cells // #FIXE needs proper parent ( Worksheet ) - return uno::Reference< excel::XRange >( new ScVbaRange( uno::Reference< XHelperInterface >(), mxContext, mxRange ) ); + return uno::Reference< excel::XRange >( new ScVbaRange( mxParent, mxContext, mxRange ) ); sal_Int32 nIndex = --nRow; if( bIsIndex && !bIsColumnIndex ) // .Cells(n) @@ -2087,7 +2088,7 @@ ScVbaRange::Cells( const uno::Any &nRowIndex, const uno::Any &nColumnIndex ) thr --nColumn; nRow = nRow + thisRangeAddress.StartRow; nColumn = nColumn + thisRangeAddress.StartColumn; - return new ScVbaRange( getParent(), mxContext, xSheetRange->getCellRangeByPosition( nColumn, nRow, nColumn, nRow ) ); + return new ScVbaRange( mxParent, mxContext, xSheetRange->getCellRangeByPosition( nColumn, nRow, nColumn, nRow ) ); } void @@ -2239,12 +2240,12 @@ ScVbaRange::Rows(const uno::Any& aIndex ) throw (uno::RuntimeException) throw uno::RuntimeException( rtl::OUString::createFromAscii("Internal failure, illegal param"), uno::Reference< uno::XInterface >() ); // return a normal range ( even for multi-selection uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pUnoRangesBase->GetDocShell(), aRange ) ); - return new ScVbaRange( getParent(), mxContext, xRange, true ); + return new ScVbaRange( mxParent, mxContext, xRange, true ); } // Rows() - no params if ( m_Areas->getCount() > 1 ) - return new ScVbaRange( getParent(), mxContext, mxRanges, true ); - return new ScVbaRange( getParent(), mxContext, mxRange, true ); + return new ScVbaRange( mxParent, mxContext, mxRanges, true ); + return new ScVbaRange( mxParent, mxContext, mxRange, true ); } uno::Reference< excel::XRange > @@ -2286,9 +2287,8 @@ ScVbaRange::Columns(const uno::Any& aIndex ) throw (uno::RuntimeException) throw uno::RuntimeException( rtl::OUString::createFromAscii("Internal failure, illegal param"), uno::Reference< uno::XInterface >() ); } // Columns() - no params - //return new ScVbaRange( getParent(), mxContext, mxRange, false, true ); uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pUnoRangesBase->GetDocShell(), aRange ) ); - return new ScVbaRange( getParent(), mxContext, xRange, false, true ); + return new ScVbaRange( mxParent, mxContext, xRange, false, true ); } void @@ -2473,7 +2473,7 @@ ScVbaRange::Resize( const uno::Any &RowSize, const uno::Any &ColumnSize ) throw xCursor->collapseToSize( nColumnSize, nRowSize ); uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable(xCursor, ::uno::UNO_QUERY_THROW ); uno::Reference< table::XCellRange > xRange( xSheetRange->getSpreadsheet(), ::uno::UNO_QUERY_THROW ); - return new ScVbaRange( getParent(), mxContext,xRange->getCellRangeByPosition( + return new ScVbaRange( mxParent, mxContext,xRange->getCellRangeByPosition( xCellRangeAddressable->getRangeAddress().StartColumn, xCellRangeAddressable->getRangeAddress().StartRow, xCellRangeAddressable->getRangeAddress().EndColumn, @@ -2563,7 +2563,6 @@ ScVbaRange::Range( const uno::Any &Cell1, const uno::Any &Cell2, bool bForceUseI // xAddressable now for this range xAddressable.set( xReferrer, uno::UNO_QUERY_THROW ); - if( !Cell1.hasValue() ) throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " Invalid Argument " ) ), @@ -2580,7 +2579,7 @@ ScVbaRange::Range( const uno::Any &Cell1, const uno::Any &Cell2, bool bForceUseI Cell1 >>= sName; RangeHelper referRange( xReferrer ); table::CellRangeAddress referAddress = referRange.getCellRangeAddressable()->getRangeAddress(); - return getRangeForName( getParent(), mxContext, sName, getScDocShell(), referAddress ); + return getRangeForName( mxContext, sName, getScDocShell(), referAddress ); } else @@ -2637,7 +2636,7 @@ ScVbaRange::Range( const uno::Any &Cell1, const uno::Any &Cell2, bool bForceUseI } } - return new ScVbaRange( getParent(), mxContext, xCellRange ); + return new ScVbaRange( mxParent, mxContext, xCellRange ); } @@ -2772,10 +2771,10 @@ ScVbaRange::getEntireColumnOrRow( bool bColumn ) throw (uno::RuntimeException) { uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pUnoRangesBase->GetDocShell(), aCellRanges ) ); - return new ScVbaRange( getParent(), mxContext, xRanges, !bColumn, bColumn ); + return new ScVbaRange( mxParent, mxContext, xRanges, !bColumn, bColumn ); } uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pUnoRangesBase->GetDocShell(), *aCellRanges.First() ) ); - return new ScVbaRange( getParent(), mxContext, xRange, !bColumn, bColumn ); + return new ScVbaRange( mxParent, mxContext, xRange, !bColumn, bColumn ); } uno::Reference< excel::XRange > SAL_CALL @@ -3121,7 +3120,7 @@ ScVbaRange::Find( const uno::Any& What, const uno::Any& After, const uno::Any& L uno::Reference< table::XCellRange > xCellRange( xInterface, uno::UNO_QUERY ); if ( xCellRange.is() ) { - uno::Reference< excel::XRange > xResultRange = new ScVbaRange( this, mxContext, xCellRange ); + uno::Reference< excel::XRange > xResultRange = new ScVbaRange( mxParent, mxContext, xCellRange ); if( xResultRange.is() ) { xResultRange->Select(); @@ -3148,7 +3147,7 @@ uno::Reference< table::XCellRange > processKey( const uno::Any& Key, uno::Refere table::CellRangeAddress aRefAddr; if ( !pDocSh ) throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Range::Sort no docshell to calculate key param")), uno::Reference< uno::XInterface >() ); - xKeyRange = getRangeForName( uno::Reference< XHelperInterface >(), xContext, sRangeName, pDocSh, aRefAddr ); + xKeyRange = getRangeForName( xContext, sRangeName, pDocSh, aRefAddr ); } else throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Range::Sort illegal type value for key param")), uno::Reference< uno::XInterface >() ); @@ -3582,7 +3581,7 @@ ScVbaRange::createEnumeration() throw (uno::RuntimeException) return new ColumnsRowEnumeration( mxContext, xRange, nElems ); } - return new CellsEnumeration( mxContext, m_Areas ); + return new CellsEnumeration( mxParent, mxContext, m_Areas ); } ::rtl::OUString SAL_CALL @@ -4073,15 +4072,14 @@ ScVbaRange::ApplicationRange( const uno::Reference< uno::XComponentContext >& xC uno::Reference< table::XCellRange > xRange = xReferrer->getReferredCells(); if ( xRange.is() ) { - // #FIXME need proper (WorkSheet) parent - uno::Reference< excel::XRange > xVbRange = new ScVbaRange( uno::Reference< XHelperInterface >(), xContext, xRange ); + uno::Reference< excel::XRange > xVbRange = new ScVbaRange( excel::getUnoSheetModuleObj( xRange ), xContext, xRange ); return xVbRange; } } } uno::Reference< sheet::XSpreadsheetView > xView( getCurrentExcelDoc(xContext)->getCurrentController(), uno::UNO_QUERY ); uno::Reference< table::XCellRange > xSheetRange( xView->getActiveSheet(), uno::UNO_QUERY_THROW ); - ScVbaRange* pRange = new ScVbaRange( uno::Reference< XHelperInterface >(), xContext, xSheetRange ); + ScVbaRange* pRange = new ScVbaRange( excel::getUnoSheetModuleObj( xSheetRange ), xContext, xSheetRange ); uno::Reference< excel::XRange > xVbSheetRange( pRange ); return pRange->Range( Cell1, Cell2, true ); } @@ -4569,7 +4567,7 @@ ScVbaRange::Insert( const uno::Any& Shift, const uno::Any& CopyOrigin ) throw (u // After the insert ( this range ) actually has moved ScRange aRange( static_cast< SCCOL >( thisAddress.StartColumn ), static_cast< SCROW >( thisAddress.StartRow ), static_cast< SCTAB >( thisAddress.Sheet ), static_cast< SCCOL >( thisAddress.EndColumn ), static_cast< SCROW >( thisAddress.EndRow ), static_cast< SCTAB >( thisAddress.Sheet ) ); uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( getDocShellFromRange( mxRange ) , aRange ) ); - uno::Reference< excel::XRange > xVbaRange( new ScVbaRange( getParent(), mxContext, xRange, mbIsRows, mbIsColumns ) ); + uno::Reference< excel::XRange > xVbaRange( new ScVbaRange( mxParent, mxContext, xRange, mbIsRows, mbIsColumns ) ); xVbaRange->PasteSpecial( uno::Any(), uno::Any(), uno::Any(), uno::Any() ); } } @@ -4955,18 +4953,18 @@ ScVbaRange::MergeArea() throw (script::BasicErrorException, uno::RuntimeExceptio if( aCellAddress.StartColumn ==0 && aCellAddress.EndColumn==0 && aCellAddress.StartRow==0 && aCellAddress.EndRow==0) { - return new ScVbaRange( getParent(),mxContext,mxRange ); + return new ScVbaRange( mxParent,mxContext,mxRange ); } else { ScRange refRange( static_cast< SCCOL >( aCellAddress.StartColumn ), static_cast< SCROW >( aCellAddress.StartRow ), static_cast< SCTAB >( aCellAddress.Sheet ), static_cast< SCCOL >( aCellAddress.EndColumn ), static_cast< SCROW >( aCellAddress.EndRow ), static_cast< SCTAB >( aCellAddress.Sheet ) ); uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( getScDocShell() , refRange ) ); - return new ScVbaRange( getParent(),mxContext,xRange ); + return new ScVbaRange( mxParent, mxContext,xRange ); } } } - return new ScVbaRange( getParent(),mxContext,mxRange ); + return new ScVbaRange( mxParent, mxContext, mxRange ); } void SAL_CALL @@ -5359,7 +5357,7 @@ ScVbaRange::PreviousNext( bool bIsPrevious ) uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( getScDocShell() , refRange ) ); - return new ScVbaRange( getParent(), mxContext, xRange ); + return new ScVbaRange( mxParent, mxContext, xRange ); } uno::Reference< excel::XRange > SAL_CALL @@ -5442,13 +5440,11 @@ ScVbaRange::SpecialCells( const uno::Any& _oType, const uno::Any& _oValue) throw if ( aCellRanges.First() == aCellRanges.Last() ) { uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( getScDocShell(), *aCellRanges.First() ) ); - // #FIXME need proper (WorkSheet) parent - return new ScVbaRange( getParent(), mxContext, xRange ); + return new ScVbaRange( mxParent, mxContext, xRange ); } uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( getScDocShell(), aCellRanges ) ); - // #FIXME need proper (WorkSheet) parent - return new ScVbaRange( getParent(), mxContext, xRanges ); + return new ScVbaRange( mxParent, mxContext, xRanges ); } else if ( bIsSingleCell ) { diff --git a/sc/source/ui/vba/vbarange.hxx b/sc/source/ui/vba/vbarange.hxx index a9147a0d78406..e7488e434f309 100644 --- a/sc/source/ui/vba/vbarange.hxx +++ b/sc/source/ui/vba/vbarange.hxx @@ -145,7 +145,6 @@ public: bool isSingleCellRange(); static css::uno::Reference< ov::excel::XRange > getRangeObjectForName( - const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const rtl::OUString& sRangeName, ScDocShell* pDocSh, formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_XL_A1 ) throw ( css::uno::RuntimeException ); diff --git a/sc/source/ui/vba/vbaworkbooks.cxx b/sc/source/ui/vba/vbaworkbooks.cxx index 9f9c5dacd7965..5298f60e0943f 100644 --- a/sc/source/ui/vba/vbaworkbooks.cxx +++ b/sc/source/ui/vba/vbaworkbooks.cxx @@ -46,6 +46,10 @@ #include <com/sun/star/document/XTypeDetection.hpp> #include <com/sun/star/uri/XUriReference.hpp> #include <com/sun/star/uri/XUriReferenceFactory.hpp> +#include <com/sun/star/script/vba/XVBACompatibility.hpp> +#include <com/sun/star/script/vba/XVBAModuleInfo.hpp> +#include <com/sun/star/script/ModuleInfo.hpp> +#include <com/sun/star/script/ModuleType.hpp> #include <sfx2/objsh.hxx> #include <tools/urlobj.hxx> @@ -56,21 +60,100 @@ #include <vbahelper/vbahelper.hxx> #include <hash_map> +#include <vector> #include <osl/file.hxx> using namespace ::ooo::vba; using namespace ::com::sun::star; const sal_Int16 CUSTOM_CHAR = 5; +void setUpDocumentModules( const uno::Reference< sheet::XSpreadsheetDocument >& xDoc ) +{ + uno::Reference< frame::XModel > xModel( xDoc, uno::UNO_QUERY ); + ScDocShell* pShell = excel::getDocShell( xModel ); + if ( pShell ) + { + uno::Reference<script::XLibraryContainer> xLibContainer = pShell->GetBasicContainer(); + uno::Reference<script::vba::XVBACompatibility> xVBACompat( xLibContainer, uno::UNO_QUERY_THROW ); + xVBACompat->setVBACompatibilityMode( sal_True ); + String aPrjName( RTL_CONSTASCII_USTRINGPARAM( "VBAProject" ) ); + pShell->GetBasicManager()->SetName( aPrjName ); + + if( xLibContainer.is() ) + { + if( !xLibContainer->hasByName( aPrjName ) ) + xLibContainer->createLibrary( aPrjName ); + uno::Any aLibAny = xLibContainer->getByName( aPrjName ); + uno::Reference< container::XNameContainer > xLib; + aLibAny >>= xLib; + if( xLib.is() ) + { + uno::Reference< script::vba::XVBAModuleInfo > xVBAModuleInfo( xLib, uno::UNO_QUERY_THROW ); + uno::Reference< lang::XMultiServiceFactory> xSF( pShell->GetModel(), uno::UNO_QUERY_THROW); + // bootstrap vbaglobals + xSF->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAGlobals"))); + uno::Reference< container::XNameAccess > xVBACodeNamedObjectAccess( xSF->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAObjectModuleObjectProvider"))), uno::UNO_QUERY_THROW ); + // set up the module info for the workbook and sheets in the nealy created + // spreadsheet + ScDocument* pDoc = pShell->GetDocument(); + String sCodeName = pDoc->GetCodeName(); + if ( sCodeName.Len() == 0 ) + { + sCodeName = String( RTL_CONSTASCII_USTRINGPARAM("ThisWorkbook") ); + pDoc->SetCodeName( sCodeName ); + } + + std::vector< rtl::OUString > sDocModuleNames; + sDocModuleNames.push_back( sCodeName ); + + uno::Reference<container::XNameAccess > xSheets( xDoc->getSheets(), uno::UNO_QUERY_THROW ); + uno::Sequence< rtl::OUString > sSheets( xSheets->getElementNames() ); + + for ( sal_Int32 index=0; index < sSheets.getLength() ; ++index ) + { + sDocModuleNames.push_back( sSheets[ index ] ); + } + + std::vector<rtl::OUString>::iterator it_end = sDocModuleNames.end(); + + for ( std::vector<rtl::OUString>::iterator it = sDocModuleNames.begin(); it != it_end; ++it ) + { + script::ModuleInfo sModuleInfo; + + sModuleInfo.ModuleObject.set( xVBACodeNamedObjectAccess->getByName( *it ), uno::UNO_QUERY ); + sModuleInfo.ModuleType = script::ModuleType::DOCUMENT; + xVBAModuleInfo->insertModuleInfo( *it, sModuleInfo ); + if( xLib->hasByName( *it ) ) + xLib->replaceByName( *it, uno::makeAny( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Option VBASupport 1\n") ) ) ); + else + xLib->insertByName( *it, uno::makeAny( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Option VBASupport 1\n" ) ) ) ); + } + } + } + } +} + static uno::Any -getWorkbook( uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< sheet::XSpreadsheetDocument > &xDoc, const uno::Any& aApplication ) +getWorkbook( uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< sheet::XSpreadsheetDocument > &xDoc, const uno::Reference< XHelperInterface >& xParent ) { // FIXME: fine as long as ScVbaWorkbook is stateless ... uno::Reference< frame::XModel > xModel( xDoc, uno::UNO_QUERY ); if( !xModel.is() ) return uno::Any(); - ScVbaWorkbook *pWb = new ScVbaWorkbook( uno::Reference< XHelperInterface >( aApplication, uno::UNO_QUERY_THROW ), xContext, xModel ); + ScDocShell* pShell = excel::getDocShell( xModel ); + if ( pShell ) + { + String sCodeName = pShell->GetDocument()->GetCodeName(); + uno::Reference< uno::XInterface > xIf = getUnoDocModule( sCodeName, pShell ); + if ( xIf.is() ) + { + OSL_TRACE(" *** Returning Module uno Object *** "); + return uno::makeAny( xIf ); + } + } + + ScVbaWorkbook *pWb = new ScVbaWorkbook( xParent, xContext, xModel ); return uno::Any( uno::Reference< excel::XWorkbook > (pWb) ); } @@ -78,12 +161,12 @@ class WorkBookEnumImpl : public EnumerationHelperImpl { uno::Any m_aApplication; public: - WorkBookEnumImpl( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Any& aApplication ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xContext, xEnumeration ), m_aApplication( aApplication ) {} + WorkBookEnumImpl( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Any& aApplication ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), m_aApplication( aApplication ) {} virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) { uno::Reference< sheet::XSpreadsheetDocument > xDoc( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW ); - return getWorkbook( m_xContext, xDoc, m_aApplication ); + return getWorkbook( m_xContext, xDoc, m_xParent ); } }; @@ -105,14 +188,14 @@ ScVbaWorkbooks::createEnumeration() throw (uno::RuntimeException) // safer to create an enumeration based on this objects state // rather than one effectively based of the desktop component uno::Reference< container::XEnumerationAccess > xEnumerationAccess( m_xIndexAccess, uno::UNO_QUERY_THROW ); - return new WorkBookEnumImpl( mxContext, xEnumerationAccess->createEnumeration(), Application() ); + return new WorkBookEnumImpl( mxParent, mxContext, xEnumerationAccess->createEnumeration(), Application() ); } uno::Any ScVbaWorkbooks::createCollectionObject( const css::uno::Any& aSource ) { uno::Reference< sheet::XSpreadsheetDocument > xDoc( aSource, uno::UNO_QUERY_THROW ); - return getWorkbook( mxContext, xDoc, Application() ); + return getWorkbook( mxContext, xDoc, mxParent ); } @@ -121,8 +204,10 @@ ScVbaWorkbooks::Add() throw (uno::RuntimeException) { uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( VbaDocumentsBase::Add() , uno::UNO_QUERY_THROW ); + // need to set up the document modules ( and vba mode ) here + setUpDocumentModules( xSpreadDoc ); if( xSpreadDoc.is() ) - return getWorkbook( mxContext, xSpreadDoc, Application() ); + return getWorkbook( mxContext, xSpreadDoc, mxParent ); return uno::Any(); } @@ -249,7 +334,7 @@ ScVbaWorkbooks::Open( const rtl::OUString& rFileName, const uno::Any& /*UpdateLi throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Bad Format")), uno::Reference< uno::XInterface >() ); uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( VbaDocumentsBase::Open( rFileName, ReadOnly, sProps ), uno::UNO_QUERY_THROW ); - uno::Any aRet = getWorkbook( mxContext, xSpreadDoc, Application() ); + uno::Any aRet = getWorkbook( mxContext, xSpreadDoc, mxParent ); uno::Reference< excel::XWorkbook > xWBook( aRet, uno::UNO_QUERY ); if ( xWBook.is() ) xWBook->Activate(); diff --git a/sc/source/ui/vba/vbaworksheet.cxx b/sc/source/ui/vba/vbaworksheet.cxx index 5b1963e3d2420..4eab79813474b 100644 --- a/sc/source/ui/vba/vbaworksheet.cxx +++ b/sc/source/ui/vba/vbaworksheet.cxx @@ -60,6 +60,7 @@ #include <com/sun/star/form/FormComponentType.hpp> #include <com/sun/star/form/XFormsSupplier.hpp> #include <ooo/vba/excel/XlEnableSelection.hpp> +#include <ooo/vba/excel/XWorkbook.hpp> #include <ooo/vba/XControlProvider.hpp> #include <comphelper/processfactory.hxx> @@ -672,24 +673,26 @@ ScVbaWorksheet::Hyperlinks( const uno::Any& aIndex ) throw (uno::RuntimeExceptio } uno::Any SAL_CALL +ScVbaWorksheet::Names( const css::uno::Any& aIndex ) throw (uno::RuntimeException) +{ + uno::Reference< excel::XWorkbook > xWorkbook( getParent(), uno::UNO_QUERY_THROW ); + return xWorkbook->Names( aIndex ); +} + +uno::Any SAL_CALL ScVbaWorksheet::OLEObjects( const uno::Any& Index ) throw (uno::RuntimeException) { - ScVbaOLEObjects* aOleObjects; uno::Reference< sheet::XSpreadsheet > xSpreadsheet( getSheet(), uno::UNO_QUERY_THROW ); uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( xSpreadsheet, uno::UNO_QUERY_THROW ); uno::Reference< drawing::XDrawPage > xDrawPage( xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY_THROW ); uno::Reference< container::XIndexAccess > xIndexAccess( xDrawPage, uno::UNO_QUERY_THROW ); - aOleObjects = new ScVbaOLEObjects( this, mxContext, xIndexAccess ); + uno::Reference< excel::XOLEObjects >xOleObjects( new ScVbaOLEObjects( this, mxContext, xIndexAccess ) ); if( Index.hasValue() ) - { - return aOleObjects->Item( Index, uno::Any() ); - } - else - { - return uno::makeAny( uno::Reference< excel::XOLEObjects> ( aOleObjects ) ); - } + return xOleObjects->Item( Index, uno::Any() ); + return uno::Any( xOleObjects ); } + uno::Any SAL_CALL ScVbaWorksheet::Shapes( const uno::Any& aIndex ) throw (uno::RuntimeException) { diff --git a/sc/source/ui/vba/vbaworksheet.hxx b/sc/source/ui/vba/vbaworksheet.hxx index d07cc1a8d55c3..196a195258d76 100644 --- a/sc/source/ui/vba/vbaworksheet.hxx +++ b/sc/source/ui/vba/vbaworksheet.hxx @@ -129,6 +129,7 @@ public: virtual css::uno::Any SAL_CALL PivotTables( const css::uno::Any& Index ) throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL Comments( const css::uno::Any& Index ) throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL Hyperlinks( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL Names( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL OLEObjects( const css::uno::Any& Index ) throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL Shapes( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException); diff --git a/sc/source/ui/vba/vbaworksheets.cxx b/sc/source/ui/vba/vbaworksheets.cxx index 60cf7b9040263..5344e6b3a9be0 100644 --- a/sc/source/ui/vba/vbaworksheets.cxx +++ b/sc/source/ui/vba/vbaworksheets.cxx @@ -52,6 +52,7 @@ #include "vbaglobals.hxx" #include "vbaworksheet.hxx" #include "vbaworkbook.hxx" +#include <unonames.hxx> using namespace ::ooo::vba; using namespace ::com::sun::star; @@ -63,6 +64,27 @@ typedef ::cppu::WeakImplHelper3< container::XNameAccess, container::XIndexAccess // (as added ) of the items typedef std::vector< uno::Reference< sheet::XSpreadsheet > > SheetMap; + +// #FIXME #TODO the implementation of the Sheets collections sucks, +// e.g. there is no support for tracking sheets added/removed from the collection + +uno::Reference< uno::XInterface > +lcl_getModulAsUnoObject( const uno::Reference< sheet::XSpreadsheet >& xSheet, const uno::Reference< frame::XModel >& xModel ) throw ( uno::RuntimeException ) +{ + uno::Reference< uno::XInterface > xRet; + if ( !xSheet.is() ) + throw uno::RuntimeException(); + uno::Reference< beans::XPropertySet > xProps( xSheet, uno::UNO_QUERY_THROW ); + rtl::OUString sName; + xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_CODENAME ) ) ) >>= sName; + + ScDocShell* pShell = excel::getDocShell( xModel ); + + if ( pShell ) + xRet = getUnoDocModule( sName, pShell ); + return xRet; +} + class WorkSheetsEnumeration : public SheetEnumeration_BASE { SheetMap mSheetMap; @@ -145,14 +167,24 @@ public: class SheetsEnumeration : public EnumerationHelperImpl { uno::Reference< frame::XModel > m_xModel; - uno::WeakReference< XHelperInterface > m_xParent; public: - SheetsEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Reference< frame::XModel >& xModel ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xContext, xEnumeration ), m_xModel( xModel ), m_xParent( xParent ) {} + SheetsEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Reference< frame::XModel >& xModel ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), m_xModel( xModel ) {} virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) { uno::Reference< sheet::XSpreadsheet > xSheet( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW ); - return uno::makeAny( uno::Reference< excel::XWorksheet > ( new ScVbaWorksheet( m_xParent, m_xContext, xSheet, m_xModel ) ) ); + uno::Reference< uno::XInterface > xIf = lcl_getModulAsUnoObject( xSheet, m_xModel ); + uno::Any aRet; + if ( !xIf.is() ) + { + // if the Sheet is in a document created by the api unfortunately ( at the + // moment, it actually wont have the special Document modules + uno::Reference< excel::XWorksheet > xNewSheet( new ScVbaWorksheet( m_xParent, m_xContext, xSheet, m_xModel ) ); + aRet <<= xNewSheet; + } + else + aRet <<= xIf; + return aRet; } }; @@ -188,7 +220,18 @@ uno::Any ScVbaWorksheets::createCollectionObject( const uno::Any& aSource ) { uno::Reference< sheet::XSpreadsheet > xSheet( aSource, uno::UNO_QUERY ); - return uno::makeAny( uno::Reference< excel::XWorksheet > ( new ScVbaWorksheet( getParent(), mxContext, xSheet, mxModel ) ) ); + uno::Reference< XInterface > xIf = lcl_getModulAsUnoObject( xSheet, mxModel ); + uno::Any aRet; + if ( !xIf.is() ) + { + // if the Sheet is in a document created by the api unfortunately ( at the + // moment, it actually wont have the special Document modules + uno::Reference< excel::XWorksheet > xNewSheet( new ScVbaWorksheet( getParent(), mxContext, xSheet, mxModel ) ); + aRet <<= xNewSheet; + } + else + aRet <<= xIf; + return aRet; } // XWorksheets |