/************************************************************************* * * 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 * * for a copy of the LGPLv3 License. * ************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "vbaapplication.hxx" #include "vbaworkbooks.hxx" #include "vbaworkbook.hxx" #include "vbaworksheets.hxx" #include "vbarange.hxx" #include "vbawsfunction.hxx" #include "vbadialogs.hxx" #include "vbawindow.hxx" #include "vbawindows.hxx" #include "vbaglobals.hxx" #include "tabvwsh.hxx" #include "gridwin.hxx" #include "vbanames.hxx" #include #include "vbatextboxshape.hxx" #include "vbaassistant.hxx" #include "sc.hrc" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "convuno.hxx" #include "cellsuno.hxx" #include "docsh.hxx" #include #include "excelvbahelper.hxx" using namespace ::ooo::vba; using namespace ::com::sun::star; // Enable our own join detection for Intersection and Union // should be more efficient than using ScRangeList::Join ( because // we already are testing the same things ) #define OWN_JOIN 1 // #TODO is this defined somewhere else? #if ( defined UNX ) || ( defined OS2 ) //unix #define FILE_PATH_SEPERATOR "/" #else // windows #define FILE_PATH_SEPERATOR "\\" #endif uno::Any sbxToUnoValue( SbxVariable* pVar ); class ActiveWorkbook : public ScVbaWorkbook { protected: virtual uno::Reference< frame::XModel > getModel() { return getCurrentExcelDoc(mxContext); } public: ActiveWorkbook( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext) : ScVbaWorkbook( xParent, xContext ){} }; ScVbaApplication::ScVbaApplication( const uno::Reference& xContext ) : ScVbaApplication_BASE( xContext ), m_xCalculation( excel::XlCalculation::xlCalculationAutomatic ), m_bDisplayAlerts( sal_True ), m_bEnableEvents( sal_True ) { } ScVbaApplication::~ScVbaApplication() { } SfxObjectShell* ScVbaApplication::GetDocShell( const uno::Reference< frame::XModel >& xModel ) throw (uno::RuntimeException) { return static_cast< SfxObjectShell* >( excel::getDocShell( xModel ) ); } ::rtl::OUString SAL_CALL ScVbaApplication::getExactName( const ::rtl::OUString& aApproximateName ) throw (uno::RuntimeException) { uno::Reference< beans::XExactName > xWSF( new ScVbaWSFunction( this, mxContext ) ); return xWSF->getExactName( aApproximateName ); } uno::Reference< beans::XIntrospectionAccess > SAL_CALL ScVbaApplication::getIntrospection() throw(css::uno::RuntimeException) { uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) ); return xWSF->getIntrospection(); } uno::Any SAL_CALL ScVbaApplication::invoke( const ::rtl::OUString& FunctionName, const uno::Sequence< uno::Any >& Params, uno::Sequence< sal_Int16 >& OutParamIndex, uno::Sequence< uno::Any >& OutParam) throw(lang::IllegalArgumentException, script::CannotConvertException, reflection::InvocationTargetException, uno::RuntimeException) { /* When calling the functions directly at the Application object, no runtime errors are thrown, but the error is inserted into the return value. */ uno::Any aAny; try { uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) ); aAny = xWSF->invoke( FunctionName, Params, OutParamIndex, OutParam ); } catch( uno::Exception& ) { aAny <<= script::BasicErrorException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), 1000, ::rtl::OUString() ); } return aAny; } void SAL_CALL ScVbaApplication::setValue( const ::rtl::OUString& PropertyName, const uno::Any& Value ) throw(beans::UnknownPropertyException, script::CannotConvertException, reflection::InvocationTargetException, uno::RuntimeException) { uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) ); xWSF->setValue( PropertyName, Value ); } uno::Any SAL_CALL ScVbaApplication::getValue( const ::rtl::OUString& PropertyName ) throw(beans::UnknownPropertyException, uno::RuntimeException) { uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) ); return xWSF->getValue( PropertyName ); } sal_Bool SAL_CALL ScVbaApplication::hasMethod( const ::rtl::OUString& Name ) throw(uno::RuntimeException) { uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) ); return xWSF->hasMethod( Name ); } sal_Bool SAL_CALL ScVbaApplication::hasProperty( const ::rtl::OUString& Name ) throw(uno::RuntimeException) { uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) ); return xWSF->hasProperty( Name ); } uno::Reference< excel::XWorkbook > ScVbaApplication::getActiveWorkbook() throw (uno::RuntimeException) { 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< 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 ScVbaApplication::getAssistant() throw (uno::RuntimeException) { return uno::Reference< XAssistant >( new ScVbaAssistant( this, mxContext ) ); } uno::Any SAL_CALL ScVbaApplication::getSelection() throw (uno::RuntimeException) { OSL_TRACE("** ScVbaApplication::getSelection() ** "); uno::Reference< frame::XModel > xModel( getCurrentDocument() ); uno::Reference< lang::XServiceInfo > xServiceInfo( xModel->getCurrentSelection(), uno::UNO_QUERY_THROW ); rtl::OUString sImpementaionName = xServiceInfo->getImplementationName(); if( sImpementaionName.equalsIgnoreAsciiCaseAscii("com.sun.star.drawing.SvxShapeCollection") ) { uno::Reference< drawing::XShapes > xShapes( xModel->getCurrentSelection(), uno::UNO_QUERY_THROW ); uno::Reference< container::XIndexAccess > xIndexAccess( xShapes, uno::UNO_QUERY_THROW ); uno::Reference< drawing::XShape > xShape( xIndexAccess->getByIndex(0), uno::UNO_QUERY_THROW ); // if ScVbaShape::getType( xShape ) == office::MsoShapeType::msoAutoShape // and the uno object implements the com.sun.star.drawing.Text service // return a textboxshape object if ( ScVbaShape::getType( xShape ) == office::MsoShapeType::msoAutoShape ) { uno::Reference< lang::XServiceInfo > xShapeServiceInfo( xShape, uno::UNO_QUERY_THROW ); if ( xShapeServiceInfo->supportsService( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.Text" ) ) ) ) { return uno::makeAny( uno::Reference< msforms::XTextBoxShape >(new ScVbaTextBoxShape( mxContext, xShape, xShapes, xModel ) ) ); } } return uno::makeAny( uno::Reference< msforms::XShape >(new ScVbaShape( this, mxContext, xShape, xShapes, xModel, ScVbaShape::getType( xShape ) ) ) ); } else if( xServiceInfo->supportsService( rtl::OUString::createFromAscii("com.sun.star.sheet.SheetCellRange")) || xServiceInfo->supportsService( rtl::OUString::createFromAscii("com.sun.star.sheet.SheetCellRanges"))) { uno::Reference< table::XCellRange > xRange( getCurrentDocument()->getCurrentSelection(), ::uno::UNO_QUERY); if ( !xRange.is() ) { uno::Reference< sheet::XSheetCellRangeContainer > xRanges( getCurrentDocument()->getCurrentSelection(), ::uno::UNO_QUERY); if ( xRanges.is() ) return uno::makeAny( uno::Reference< excel::XRange >( new ScVbaRange( excel::getUnoSheetModuleObj( xRanges ), mxContext, xRanges ) ) ); } return uno::makeAny( uno::Reference< excel::XRange >(new ScVbaRange( excel::getUnoSheetModuleObj( xRange ), mxContext, xRange ) ) ); } else { throw uno::RuntimeException( sImpementaionName + rtl::OUString::createFromAscii(" not suported"), uno::Reference< uno::XInterface >() ); } } uno::Reference< excel::XRange > ScVbaApplication::getActiveCell() throw (uno::RuntimeException ) { uno::Reference< sheet::XSpreadsheetView > xView( getCurrentDocument()->getCurrentController(), uno::UNO_QUERY_THROW ); uno::Reference< table::XCellRange > xRange( xView->getActiveSheet(), ::uno::UNO_QUERY_THROW); ScTabViewShell* pViewShell = excel::getCurrentBestViewShell(mxContext); if ( !pViewShell ) throw uno::RuntimeException( rtl::OUString::createFromAscii("No ViewShell available"), uno::Reference< uno::XInterface >() ); ScViewData* pTabView = pViewShell->GetViewData(); if ( !pTabView ) throw uno::RuntimeException( rtl::OUString::createFromAscii("No ViewData available"), uno::Reference< uno::XInterface >() ); sal_Int32 nCursorX = pTabView->GetCurX(); sal_Int32 nCursorY = pTabView->GetCurY(); uno::Reference< XHelperInterface > xParent( excel::getUnoSheetModuleObj( xRange ), uno::UNO_QUERY_THROW ); return new ScVbaRange( xParent, mxContext, xRange->getCellRangeByPosition( nCursorX, nCursorY, nCursorX, nCursorY ) ); } uno::Any SAL_CALL ScVbaApplication::Workbooks( const uno::Any& aIndex ) throw (uno::RuntimeException) { uno::Reference< XCollection > xWorkBooks( new ScVbaWorkbooks( this, mxContext ) ); if ( aIndex.getValueTypeClass() == uno::TypeClass_VOID ) { // void then somebody did Workbooks.something in vba return uno::Any( xWorkBooks ); } return uno::Any ( xWorkBooks->Item( aIndex, uno::Any() ) ); } uno::Any SAL_CALL ScVbaApplication::Worksheets( const uno::Any& aIndex ) throw (uno::RuntimeException) { uno::Reference< excel::XWorkbook > xWorkbook( getActiveWorkbook(), uno::UNO_QUERY ); uno::Any result; if ( xWorkbook.is() ) result = xWorkbook->Worksheets( aIndex ); else // Fixme - check if this is reasonable/desired behavior throw uno::RuntimeException( rtl::OUString::createFromAscii( "No ActiveWorkBook available" ), uno::Reference< uno::XInterface >() ); return result; } uno::Any SAL_CALL ScVbaApplication::WorksheetFunction( ) throw (::com::sun::star::uno::RuntimeException) { return uno::makeAny( uno::Reference< script::XInvocation >( new ScVbaWSFunction( this, mxContext ) ) ); } uno::Any SAL_CALL ScVbaApplication::Evaluate( const ::rtl::OUString& Name ) throw (uno::RuntimeException) { // #TODO Evaluate allows other things to be evaluated, e.g. functions // I think ( like SIN(3) etc. ) need to investigate that // named Ranges also? e.g. [MyRange] if so need a list of named ranges uno::Any aVoid; return uno::Any( getActiveWorkbook()->getActiveSheet()->Range( uno::Any( Name ), aVoid ) ); } uno::Any ScVbaApplication::Dialogs( const uno::Any &aIndex ) throw (uno::RuntimeException) { uno::Reference< excel::XDialogs > xDialogs( new ScVbaDialogs( uno::Reference< XHelperInterface >( this ), mxContext, getCurrentDocument() ) ); if( !aIndex.hasValue() ) return uno::Any( xDialogs ); return uno::Any( xDialogs->Item( aIndex ) ); } uno::Reference< excel::XWindow > SAL_CALL ScVbaApplication::getActiveWindow() throw (uno::RuntimeException) { // #FIXME sofar can't determine Parent uno::Reference< frame::XModel > xModel = getCurrentDocument(); ScVbaWindow* pWin = new ScVbaWindow( uno::Reference< XHelperInterface >(), mxContext, xModel ); uno::Reference< excel::XWindow > xWin( pWin ); return xWin; } uno::Any SAL_CALL ScVbaApplication::getCutCopyMode() throw (uno::RuntimeException) { //# FIXME TODO, implementation uno::Any result; result <<= sal_False; return result; } void SAL_CALL ScVbaApplication::setCutCopyMode( const uno::Any& /*_cutcopymode*/ ) throw (uno::RuntimeException) { //# FIXME TODO, implementation } uno::Any SAL_CALL ScVbaApplication::getStatusBar() throw (uno::RuntimeException) { return uno::makeAny( !getDisplayStatusBar() ); } void SAL_CALL ScVbaApplication::setStatusBar( const uno::Any& _statusbar ) throw (uno::RuntimeException) { rtl::OUString sText; sal_Bool bDefault = sal_False; uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_QUERY_THROW ); uno::Reference< task::XStatusIndicatorSupplier > xStatusIndicatorSupplier( xModel->getCurrentController(), uno::UNO_QUERY_THROW ); uno::Reference< task::XStatusIndicator > xStatusIndicator( xStatusIndicatorSupplier->getStatusIndicator(), uno::UNO_QUERY_THROW ); if( _statusbar >>= sText ) { setDisplayStatusBar( sal_True ); xStatusIndicator->start( sText, 100 ); //xStatusIndicator->setText( sText ); } else if( _statusbar >>= bDefault ) { if( bDefault == sal_False ) { xStatusIndicator->end(); setDisplayStatusBar( sal_True ); } } else throw uno::RuntimeException( rtl::OUString::createFromAscii( "Invalid prarameter. It should be a string or False" ), uno::Reference< uno::XInterface >() ); } ::sal_Int32 SAL_CALL ScVbaApplication::getCalculation() throw (uno::RuntimeException) { uno::Reference xCalc(getCurrentDocument(), uno::UNO_QUERY_THROW); if(xCalc->isAutomaticCalculationEnabled()) return excel::XlCalculation::xlCalculationAutomatic; else return excel::XlCalculation::xlCalculationManual; } void SAL_CALL ScVbaApplication::setCalculation( ::sal_Int32 _calculation ) throw (uno::RuntimeException) { uno::Reference< sheet::XCalculatable > xCalc(getCurrentDocument(), uno::UNO_QUERY_THROW); switch(_calculation) { case excel::XlCalculation::xlCalculationManual: xCalc->enableAutomaticCalculation(sal_False); break; case excel::XlCalculation::xlCalculationAutomatic: case excel::XlCalculation::xlCalculationSemiautomatic: xCalc->enableAutomaticCalculation(sal_True); break; } } uno::Any SAL_CALL ScVbaApplication::Windows( const uno::Any& aIndex ) throw (uno::RuntimeException) { uno::Reference< excel::XWindows > xWindows( new ScVbaWindows( this, mxContext ) ); if ( aIndex.getValueTypeClass() == uno::TypeClass_VOID ) return uno::Any( xWindows ); return uno::Any( xWindows->Item( aIndex, uno::Any() ) ); } void SAL_CALL ScVbaApplication::wait( double time ) throw (uno::RuntimeException) { StarBASIC* pBasic = SFX_APP()->GetBasic(); SFX_APP()->EnterBasicCall(); SbxArrayRef aArgs = new SbxArray; SbxVariableRef aRef = new SbxVariable; aRef->PutDouble( time ); aArgs->Put( aRef, 1 ); SbMethod* pMeth = (SbMethod*)pBasic->GetRtl()->Find( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("WaitUntil") ), SbxCLASS_METHOD ); if ( pMeth ) { pMeth->SetParameters( aArgs ); SbxVariableRef refTemp = pMeth; // forces a broadcast SbxVariableRef pNew = new SbxMethod( *((SbxMethod*)pMeth)); } SFX_APP()->LeaveBasicCall(); } uno::Any SAL_CALL ScVbaApplication::Range( const uno::Any& Cell1, const uno::Any& Cell2 ) throw (uno::RuntimeException) { uno::Reference< excel::XRange > xVbRange = ScVbaRange::ApplicationRange( mxContext, Cell1, Cell2 ); return uno::makeAny( xVbRange ); } uno::Any SAL_CALL ScVbaApplication::Names( const css::uno::Any& aIndex ) throw ( uno::RuntimeException ) { uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_QUERY_THROW ); uno::Reference< beans::XPropertySet > xPropertySet( xModel, uno::UNO_QUERY_THROW ); uno::Reference< sheet::XNamedRanges > xNamedRanges( xPropertySet->getPropertyValue( rtl::OUString::createFromAscii("NamedRanges")) , uno::UNO_QUERY_THROW ); css::uno::Reference< excel::XNames > xNames ( new ScVbaNames( this , mxContext , xNamedRanges , xModel ) ); if ( aIndex.getValueTypeClass() == uno::TypeClass_VOID ) { return uno::Any( xNames ); } return uno::Any( xNames->Item( aIndex, uno::Any() ) ); } uno::Reference< excel::XWorksheet > SAL_CALL ScVbaApplication::getActiveSheet() throw (uno::RuntimeException) { uno::Reference< excel::XWorksheet > result; uno::Reference< excel::XWorkbook > xWorkbook( getActiveWorkbook(), uno::UNO_QUERY ); if ( xWorkbook.is() ) { uno::Reference< excel::XWorksheet > xWorksheet( xWorkbook->getActiveSheet(), uno::UNO_QUERY ); if ( xWorksheet.is() ) { result = xWorksheet; } } if ( !result.is() ) { // Fixme - check if this is reasonable/desired behavior throw uno::RuntimeException( rtl::OUString::createFromAscii( "No activeSheet available" ), uno::Reference< uno::XInterface >() ); } return result; } /******************************************************************************* * In msdn: * Reference Optional Variant. The destination. Can be a Range * object, a string that contains a cell reference in R1C1-style notation, * or a string that contains a Visual Basic procedure name. * Scroll Optional Variant. True to scrol, False to not scroll through * the window. The default is False. * Parser is split to three parts, Range, R1C1 string and procedure name. * by test excel, it seems Scroll no effect. ??? *******************************************************************************/ void SAL_CALL ScVbaApplication::GoTo( const uno::Any& Reference, const uno::Any& Scroll ) throw (uno::RuntimeException) { //test Scroll is a boolean sal_Bool bScroll = sal_False; //R1C1-style string or a string of procedure name. if( Scroll.hasValue() ) { sal_Bool aScroll = sal_False; if( Scroll >>= aScroll ) { bScroll = aScroll; } else throw uno::RuntimeException( rtl::OUString::createFromAscii( "sencond parameter should be boolean" ), uno::Reference< uno::XInterface >() ); } rtl::OUString sRangeName; if( Reference >>= sRangeName ) { uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_QUERY_THROW ); uno::Reference< sheet::XSpreadsheetView > xSpreadsheet( xModel->getCurrentController(), uno::UNO_QUERY_THROW ); uno::Reference< sheet::XSpreadsheet > xDoc = xSpreadsheet->getActiveSheet(); ScTabViewShell* pShell = excel::getCurrentBestViewShell( mxContext ); ScGridWindow* gridWindow = (ScGridWindow*)pShell->GetWindow(); try { uno::Reference< excel::XRange > xVbaSheetRange = ScVbaRange::getRangeObjectForName( mxContext, sRangeName, excel::getDocShell( xModel ), formula::FormulaGrammar::CONV_XL_R1C1 ); if( bScroll ) { xVbaSheetRange->Select(); uno::Reference< excel::XWindow > xWindow = getActiveWindow(); ScSplitPos eWhich = pShell->GetViewData()->GetActivePart(); sal_Int32 nValueX = pShell->GetViewData()->GetPosX(WhichH(eWhich)); sal_Int32 nValueY = pShell->GetViewData()->GetPosY(WhichV(eWhich)); xWindow->SmallScroll( uno::makeAny( (sal_Int16)(xVbaSheetRange->getRow() - 1) ), uno::makeAny( (sal_Int16)nValueY ), uno::makeAny( (sal_Int16)(xVbaSheetRange->getColumn() - 1) ), uno::makeAny( (sal_Int16)nValueX ) ); gridWindow->GrabFocus(); } else { xVbaSheetRange->Select(); gridWindow->GrabFocus(); } } catch( uno::RuntimeException ) { //maybe this should be a procedure name //TODO for procedure name //browse::XBrowseNodeFactory is a singlton. OUString::createFromAscii( "/singletons/com.sun.star.script.browse.theBrowseNodeFactory") //and the createView( browse::BrowseNodeFactoryViewTypes::MACROSELECTOR ) to get a root browse::XBrowseNode. //for query XInvocation interface. //but how to directly get the XInvocation? throw uno::RuntimeException( rtl::OUString::createFromAscii( "invalid reference for range name, it should be procedure name" ), uno::Reference< uno::XInterface >() ); } return; } uno::Reference< excel::XRange > xRange; if( Reference >>= xRange ) { uno::Reference< excel::XRange > xVbaRange( Reference, uno::UNO_QUERY ); ScTabViewShell* pShell = excel::getCurrentBestViewShell( mxContext ); ScGridWindow* gridWindow = (ScGridWindow*)pShell->GetWindow(); if ( xVbaRange.is() ) { //TODO bScroll should be using, In this time, it doesenot have effection if( bScroll ) { xVbaRange->Select(); uno::Reference< excel::XWindow > xWindow = getActiveWindow(); ScSplitPos eWhich = pShell->GetViewData()->GetActivePart(); sal_Int32 nValueX = pShell->GetViewData()->GetPosX(WhichH(eWhich)); sal_Int32 nValueY = pShell->GetViewData()->GetPosY(WhichV(eWhich)); xWindow->SmallScroll( uno::makeAny( (sal_Int16)(xVbaRange->getRow() - 1) ), uno::makeAny( (sal_Int16)nValueY ), uno::makeAny( (sal_Int16)(xVbaRange->getColumn() - 1) ), uno::makeAny( (sal_Int16)nValueX ) ); gridWindow->GrabFocus(); } else { xVbaRange->Select(); gridWindow->GrabFocus(); } } return; } throw uno::RuntimeException( rtl::OUString::createFromAscii( "invalid reference or name" ), uno::Reference< uno::XInterface >() ); } sal_Int32 SAL_CALL ScVbaApplication::getCursor() throw (uno::RuntimeException) { sal_Int32 nPointerStyle = getPointerStyle(getCurrentDocument()); switch( nPointerStyle ) { case POINTER_ARROW: return excel::XlMousePointer::xlNorthwestArrow; case POINTER_NULL: return excel::XlMousePointer::xlDefault; case POINTER_WAIT: return excel::XlMousePointer::xlWait; case POINTER_TEXT: return excel::XlMousePointer::xlIBeam; default: return excel::XlMousePointer::xlDefault; } } void SAL_CALL ScVbaApplication::setCursor( sal_Int32 _cursor ) throw (uno::RuntimeException) { try { uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_QUERY_THROW ); switch( _cursor ) { case excel::XlMousePointer::xlNorthwestArrow: { const Pointer& rPointer( POINTER_ARROW ); setCursorHelper( xModel, rPointer, sal_False ); break; } case excel::XlMousePointer::xlWait: case excel::XlMousePointer::xlIBeam: { const Pointer& rPointer( static_cast< PointerStyle >( _cursor ) ); //It will set the edit window, toobar and statusbar's mouse pointer. setCursorHelper( xModel, rPointer, sal_True ); break; } case excel::XlMousePointer::xlDefault: { const Pointer& rPointer( POINTER_NULL ); setCursorHelper( xModel, rPointer, sal_False ); break; } default: throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Unknown value for Cursor pointer")), uno::Reference< uno::XInterface >() ); // TODO: isn't this a flaw in the API? It should be allowed to throw an // IllegalArgumentException, or so } } catch( const uno::Exception& ) { DBG_UNHANDLED_EXCEPTION(); } } // #TODO perhaps we should switch the return type depending of the filter // type, e.g. return Calc for Calc and Excel if its an imported doc rtl::OUString SAL_CALL ScVbaApplication::getName() throw (uno::RuntimeException) { static rtl::OUString appName( RTL_CONSTASCII_USTRINGPARAM("Microsoft Excel" ) ); return appName; } // #TODO #FIXME get/setDisplayAlerts are just stub impl // here just the status of the switch is set // the function that throws an error message needs to // evaluate this switch in order to know whether it has to disable the // error message thrown by OpenOffice void SAL_CALL ScVbaApplication::setDisplayAlerts(sal_Bool displayAlerts) throw (uno::RuntimeException) { m_bDisplayAlerts = displayAlerts; } sal_Bool SAL_CALL ScVbaApplication::getDisplayAlerts() throw (uno::RuntimeException) { 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 ) { uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_QUERY_THROW ); uno::Reference< sheet::XCalculatable > xCalculatable( getCurrentDocument(), uno::UNO_QUERY_THROW ); xCalculatable->calculateAll(); } uno::Reference< beans::XPropertySet > lcl_getPathSettingsService( const uno::Reference< uno::XComponentContext >& xContext ) throw ( uno::RuntimeException ) { static uno::Reference< beans::XPropertySet > xPathSettings; if ( !xPathSettings.is() ) { uno::Reference< lang::XMultiComponentFactory > xSMgr( xContext->getServiceManager(), uno::UNO_QUERY_THROW ); xPathSettings.set( xSMgr->createInstanceWithContext(::rtl::OUString::createFromAscii("com.sun.star.util.PathSettings"), xContext), uno::UNO_QUERY_THROW ); } return xPathSettings; } rtl::OUString ScVbaApplication::getOfficePath( const rtl::OUString& _sPathType ) throw ( uno::RuntimeException ) { rtl::OUString sRetPath; uno::Reference< beans::XPropertySet > xProps = lcl_getPathSettingsService( mxContext ); try { rtl::OUString sUrl; xProps->getPropertyValue( _sPathType ) >>= sUrl; // if its a list of paths then use the last one sal_Int32 nIndex = sUrl.lastIndexOf( ';' ) ; if ( nIndex > 0 ) sUrl = sUrl.copy( nIndex + 1 ); ::osl::File::getSystemPathFromFileURL( sUrl, sRetPath ); } catch (uno::Exception&) { DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString()); } return sRetPath; } void SAL_CALL ScVbaApplication::setDefaultFilePath( const ::rtl::OUString& DefaultFilePath ) throw (script::BasicErrorException, uno::RuntimeException) { uno::Reference< beans::XPropertySet > xProps = lcl_getPathSettingsService( mxContext ); rtl::OUString aURL; osl::FileBase::getFileURLFromSystemPath( DefaultFilePath, aURL ); xProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Work")), uno::makeAny( aURL ) ); } ::rtl::OUString SAL_CALL ScVbaApplication::getDefaultFilePath( ) throw (script::BasicErrorException, uno::RuntimeException) { return getOfficePath( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Work"))); } ::rtl::OUString SAL_CALL ScVbaApplication::LibraryPath( ) throw (script::BasicErrorException, uno::RuntimeException) { return getOfficePath( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Basic"))); } ::rtl::OUString SAL_CALL ScVbaApplication::TemplatesPath( ) throw (script::BasicErrorException, uno::RuntimeException) { return getOfficePath( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Template"))); } ::rtl::OUString SAL_CALL ScVbaApplication::PathSeparator( ) throw (script::BasicErrorException, uno::RuntimeException) { static rtl::OUString sPathSep( RTL_CONSTASCII_USTRINGPARAM( FILE_PATH_SEPERATOR ) ); return sPathSep; } typedef std::list< ScRange > Ranges; typedef std::list< ScRangeList > RangesList; void lcl_addRangesToVec( RangesList& vRanges, const uno::Any& aArg ) throw ( script::BasicErrorException, uno::RuntimeException ) { ScRangeList theRanges; uno::Reference< excel::XRange > xRange( aArg, uno::UNO_QUERY_THROW ); uno::Reference< XCollection > xCol( xRange->Areas( uno::Any() ), uno::UNO_QUERY_THROW ); sal_Int32 nCount = xCol->getCount(); for( sal_Int32 i = 1; i <= nCount; ++i ) { uno::Reference< excel::XRange > xAreaRange( xCol->Item( uno::makeAny( sal_Int32(i) ), uno::Any() ), uno::UNO_QUERY_THROW ); uno::Reference< sheet::XCellRangeAddressable > xAddressable( xAreaRange->getCellRange(), uno::UNO_QUERY_THROW ); table::CellRangeAddress addr = xAddressable->getRangeAddress(); ScRange refRange; ScUnoConversion::FillScRange( refRange, addr ); theRanges.Append( refRange ); } vRanges.push_back( theRanges ); } void lcl_addRangeToVec( Ranges& vRanges, const uno::Any& aArg ) throw ( script::BasicErrorException, uno::RuntimeException ) { uno::Reference< excel::XRange > xRange( aArg, uno::UNO_QUERY_THROW ); uno::Reference< XCollection > xCol( xRange->Areas( uno::Any() ), uno::UNO_QUERY_THROW ); sal_Int32 nCount = xCol->getCount(); for( sal_Int32 i = 1; i <= nCount; ++i ) { uno::Reference< excel::XRange > xAreaRange( xCol->Item( uno::makeAny( sal_Int32(i) ), uno::Any() ), uno::UNO_QUERY_THROW ); uno::Reference< sheet::XCellRangeAddressable > xAddressable( xAreaRange->getCellRange(), uno::UNO_QUERY_THROW ); table::CellRangeAddress addr = xAddressable->getRangeAddress(); ScRange refRange; ScUnoConversion::FillScRange( refRange, addr ); vRanges.push_back( refRange ); } } bool lcl_canJoin( ScRange& r1, ScRange& r2 ) { bool bCanJoin = false; SCCOL startEndColDiff = r2.aStart.Col() - r1.aEnd.Col(); SCROW startEndRowDiff = r2.aStart.Row() - r1.aEnd.Row(); SCCOL startColDiff = r2.aStart.Col() - r1.aStart.Col(); SCCOL endColDiff = r2.aEnd.Col() - r1.aEnd.Col(); SCROW startRowDiff = r2.aStart.Row() - r1.aStart.Row(); SCROW endRowDiff = r2.aEnd.Row() - r1.aEnd.Row(); if ( ( startRowDiff == endRowDiff ) && startRowDiff == 0 && startColDiff >=0 && endColDiff > 0 && ( startEndColDiff <= 1 && startEndColDiff >= -r1.aEnd.Col() ) ) bCanJoin = true; else if ( ( startColDiff == endColDiff ) && startColDiff == 0 && startRowDiff >= 0 && endRowDiff > 0 && ( startEndRowDiff <= 1 && startEndRowDiff >= -r1.aEnd.Row() ) ) bCanJoin = true; #ifdef DEBUG String sr1; String sr2; r1.Format( sr1, SCA_VALID ) ; r2.Format( sr2, SCA_VALID ) ; OSL_TRACE(" canJoin address %s with %s %s ( startRowDiff(%d), endRowDiff(%d), startColDiff(%d) endColDiff(%d) startEndRowDiff(%d), startEndColDiff(%d) ", rtl::OUStringToOString( sr1, RTL_TEXTENCODING_UTF8 ).getStr(), rtl::OUStringToOString( sr2, RTL_TEXTENCODING_UTF8 ).getStr(), bCanJoin ? "true" : "false", startRowDiff, endRowDiff, startColDiff, endColDiff, startEndRowDiff, startEndColDiff ); #endif return bCanJoin; } // strips out ranges that contain other ranges, also // if the borders of the intersecting ranges are alligned // then the the range is extended to the larger // e.g. Range("A4:D10"), Range("B4:E10") would be combined // to Range("A4:E10") void lcl_strip_containedRanges( Ranges& vRanges ) { // get rid of ranges that are surrounded by other ranges Ranges::iterator it_outer = vRanges.begin(); while( it_outer != vRanges.end() ) { bool it_outer_erased = false; // true = it_outer erased from vRanges Ranges::iterator it_inner = vRanges.begin(); /* Exit the inner loop if outer iterator has been erased in its last iteration (this means it has been joined to last it_inner, or that the it_inner contains it completely). The inner loop will restart with next element of the outer loop, and all elements (from the beginning of the list) will be checked against that new element. */ while( !it_outer_erased && (it_inner != vRanges.end()) ) { bool it_inner_erased = false; // true = it_inner erased from vRanges if ( it_outer != it_inner ) { #ifdef DEBUG String r1; String r2; it_outer->Format( r1, SCA_VALID ) ; it_inner->Format( r2, SCA_VALID ) ; OSL_TRACE( "try strip/join address %s with %s ", rtl::OUStringToOString( r1, RTL_TEXTENCODING_UTF8 ).getStr(), rtl::OUStringToOString( r2, RTL_TEXTENCODING_UTF8 ).getStr() ); #endif if ( it_outer->In( *it_inner ) ) { it_inner = vRanges.erase( it_inner ); it_inner_erased = true; } else if ( it_inner->In( *it_outer ) ) { it_outer = vRanges.erase( it_outer ); it_outer_erased = true; } #ifndef OWN_JOIN else if ( (*it_inner).aStart.Row() == (*it_outer).aStart.Row() && (*it_inner).aEnd.Row() == (*it_outer).aEnd.Row() ) { it_outer->ExtendTo( *it_inner ); it_inner = vRanges.erase( it_inner ); it_inner_erased = true; } #else else if ( lcl_canJoin( *it_outer, *it_inner ) ) { it_outer->ExtendTo( *it_inner ); it_inner = vRanges.erase( it_inner ); it_inner_erased = true; } else if ( lcl_canJoin( *it_inner, *it_outer) ) { it_inner->ExtendTo( *it_outer ); it_outer = vRanges.erase( it_outer ); it_outer_erased = true; } #endif } /* If it_inner has not been erased from vRanges, continue inner loop with next element. Otherwise, it_inner already points to the next element (return value of list::erase()). */ if( !it_inner_erased ) ++it_inner; } /* If it_outer has not been erased from vRanges, continue outer loop with next element. Otherwise, it_outer already points to the next element (return value of list::erase()). */ if( !it_outer_erased ) ++it_outer; } } Ranges lcl_intersectionImpl( ScRangeList& rl1, ScRangeList& rl2 ) { Ranges intersections; for ( USHORT x = 0 ; x < rl1.Count(); ++x ) { for ( USHORT y = 0 ; y < rl2.Count(); ++y ) { #ifdef DEBUG String r1; String r2; rl1.GetObject( x )->Format( r1, SCA_VALID ) ; rl2.GetObject( y )->Format( r2, SCA_VALID ) ; OSL_TRACE( "comparing address %s with %s ", rtl::OUStringToOString( r1, RTL_TEXTENCODING_UTF8 ).getStr(), rtl::OUStringToOString( r2, RTL_TEXTENCODING_UTF8 ).getStr() ); #endif if( rl1.GetObject( x )->Intersects( *rl2.GetObject( y ) ) ) { ScRange aIntersection = ScRange( Max( rl1.GetObject( x )->aStart.Col(), rl2.GetObject( y )->aStart.Col() ), Max( rl1.GetObject( x )->aStart.Row(), rl2.GetObject( y )->aStart.Row() ), Max( rl1.GetObject( x )->aStart.Tab(), rl2.GetObject( y )->aStart.Tab() ), Min( rl1.GetObject( x )->aEnd.Col(), rl2.GetObject( y )->aEnd.Col() ), Min( rl1.GetObject( x )->aEnd.Row(), rl2.GetObject( y )->aEnd.Row() ), Min( rl1.GetObject( x )->aEnd.Tab(), rl2.GetObject( y )->aEnd.Tab() ) ); intersections.push_back( aIntersection ); } } } lcl_strip_containedRanges( intersections ); return intersections; } // Intersection of a set of ranges ( where each range is represented by a ScRangeList e.g. // any range can be a multi-area range ) // An intersection is performed between each range in the set of ranges. // The resulting set of intersections is then processed to strip out any // intersections that contain other intersections ( and also ranges that directly line up // are joined ) ( see lcl_strip_containedRanges ) RangesList lcl_intersections( RangesList& vRanges ) { RangesList intersections; RangesList::iterator it = vRanges.begin(); while( it != vRanges.end() ) { Ranges intermediateList; for( RangesList::iterator it_inner = vRanges.begin(); it_inner != vRanges.end(); ++it_inner ) { if ( it != it_inner ) { Ranges ranges = lcl_intersectionImpl( *it, *it_inner ); for ( Ranges::iterator range_it = ranges.begin(); range_it != ranges.end(); ++range_it ) intermediateList.push_back( *range_it ); } } it = vRanges.erase( it ); // remove it so we don't include it in the next pass. // 'it' is removed uncontidionally from vRanges, so the while loop will terminate ScRangeList argIntersect; lcl_strip_containedRanges( intermediateList ); for( Ranges::iterator it_inter = intermediateList.begin(); it_inter != intermediateList.end(); ++it_inter ) #ifndef OWN_JOIN argIntersect.Join( *it_inter ); #else argIntersect.Append( *it_inter ); #endif intersections.push_back( argIntersect ); } return intersections; } uno::Reference< excel::XRange > SAL_CALL ScVbaApplication::Intersect( const uno::Reference< excel::XRange >& Arg1, const uno::Reference< excel::XRange >& Arg2, const uno::Any& Arg3, const uno::Any& Arg4, const uno::Any& Arg5, const uno::Any& Arg6, const uno::Any& Arg7, const uno::Any& Arg8, const uno::Any& Arg9, const uno::Any& Arg10, const uno::Any& Arg11, const uno::Any& Arg12, const uno::Any& Arg13, const uno::Any& Arg14, const uno::Any& Arg15, const uno::Any& Arg16, const uno::Any& Arg17, const uno::Any& Arg18, const uno::Any& Arg19, const uno::Any& Arg20, const uno::Any& Arg21, const uno::Any& Arg22, const uno::Any& Arg23, const uno::Any& Arg24, const uno::Any& Arg25, const uno::Any& Arg26, const uno::Any& Arg27, const uno::Any& Arg28, const uno::Any& Arg29, const uno::Any& Arg30 ) throw (script::BasicErrorException, uno::RuntimeException) { if ( !Arg1.is() || !Arg2.is() ) DebugHelper::exception(SbERR_BAD_PARAMETER, rtl::OUString() ); RangesList vRanges; lcl_addRangesToVec( vRanges, uno::makeAny( Arg1 ) ); lcl_addRangesToVec( vRanges, uno::makeAny( Arg2 ) ); if ( Arg3.hasValue() ) lcl_addRangesToVec( vRanges, Arg3 ); if ( Arg4.hasValue() ) lcl_addRangesToVec( vRanges, Arg4 ); if ( Arg5.hasValue() ) lcl_addRangesToVec( vRanges, Arg5 ); if ( Arg6.hasValue() ) lcl_addRangesToVec( vRanges, Arg6 ); if ( Arg7.hasValue() ) lcl_addRangesToVec( vRanges, Arg7 ); if ( Arg8.hasValue() ) lcl_addRangesToVec( vRanges, Arg8 ); if ( Arg9.hasValue() ) lcl_addRangesToVec( vRanges, Arg9 ); if ( Arg10.hasValue() ) lcl_addRangesToVec( vRanges, Arg10 ); if ( Arg11.hasValue() ) lcl_addRangesToVec( vRanges, Arg11 ); if ( Arg12.hasValue() ) lcl_addRangesToVec( vRanges, Arg12 ); if ( Arg13.hasValue() ) lcl_addRangesToVec( vRanges, Arg13 ); if ( Arg14.hasValue() ) lcl_addRangesToVec( vRanges, Arg14 ); if ( Arg15.hasValue() ) lcl_addRangesToVec( vRanges, Arg15 ); if ( Arg16.hasValue() ) lcl_addRangesToVec( vRanges, Arg16 ); if ( Arg17.hasValue() ) lcl_addRangesToVec( vRanges, Arg17 ); if ( Arg18.hasValue() ) lcl_addRangesToVec( vRanges, Arg18 ); if ( Arg19.hasValue() ) lcl_addRangesToVec( vRanges, Arg19 ); if ( Arg20.hasValue() ) lcl_addRangesToVec( vRanges, Arg20 ); if ( Arg21.hasValue() ) lcl_addRangesToVec( vRanges, Arg21 ); if ( Arg22.hasValue() ) lcl_addRangesToVec( vRanges, Arg22 ); if ( Arg23.hasValue() ) lcl_addRangesToVec( vRanges, Arg23 ); if ( Arg24.hasValue() ) lcl_addRangesToVec( vRanges, Arg24 ); if ( Arg25.hasValue() ) lcl_addRangesToVec( vRanges, Arg25 ); if ( Arg26.hasValue() ) lcl_addRangesToVec( vRanges, Arg26 ); if ( Arg27.hasValue() ) lcl_addRangesToVec( vRanges, Arg27 ); if ( Arg28.hasValue() ) lcl_addRangesToVec( vRanges, Arg28 ); if ( Arg29.hasValue() ) lcl_addRangesToVec( vRanges, Arg29 ); if ( Arg30.hasValue() ) lcl_addRangesToVec( vRanges, Arg30 ); uno::Reference< excel::XRange > xRefRange; ScRangeList aCellRanges; // first pass - gets the set of all possible interections of Arg1..ArgN RangesList intersections = lcl_intersections( vRanges ); // second pass - gets the intersections of the intersections ( don't ask, but this // is what seems to happen ) if ( intersections.size() > 1) intersections = lcl_intersections( intersections ); for( RangesList::iterator it = intersections.begin(); it != intersections.end(); ++it ) { for ( USHORT x = 0 ; x < it->Count(); ++x ) #ifndef OWN_JOIN aCellRanges.Join( *it->GetObject(x) ); #else aCellRanges.Append( *it->GetObject(x) ); #endif } uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_QUERY_THROW ); ScDocShell* pDocShell = excel::getDocShell( xModel ); if ( aCellRanges.Count() == 1 ) { 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( excel::getUnoSheetModuleObj( xRanges ) , mxContext, xRanges ); } return xRefRange; } uno::Reference< excel::XRange > SAL_CALL ScVbaApplication::Union( const uno::Reference< excel::XRange >& Arg1, const uno::Reference< excel::XRange >& Arg2, const uno::Any& Arg3, const uno::Any& Arg4, const uno::Any& Arg5, const uno::Any& Arg6, const uno::Any& Arg7, const uno::Any& Arg8, const uno::Any& Arg9, const uno::Any& Arg10, const uno::Any& Arg11, const uno::Any& Arg12, const uno::Any& Arg13, const uno::Any& Arg14, const uno::Any& Arg15, const uno::Any& Arg16, const uno::Any& Arg17, const uno::Any& Arg18, const uno::Any& Arg19, const uno::Any& Arg20, const uno::Any& Arg21, const uno::Any& Arg22, const uno::Any& Arg23, const uno::Any& Arg24, const uno::Any& Arg25, const uno::Any& Arg26, const uno::Any& Arg27, const uno::Any& Arg28, const uno::Any& Arg29, const uno::Any& Arg30 ) throw (script::BasicErrorException, uno::RuntimeException) { if ( !Arg1.is() || !Arg2.is() ) DebugHelper::exception(SbERR_BAD_PARAMETER, rtl::OUString() ); uno::Reference< excel::XRange > xRange; Ranges vRanges; lcl_addRangeToVec( vRanges, uno::makeAny( Arg1 ) ); lcl_addRangeToVec( vRanges, uno::makeAny( Arg2 ) ); if ( Arg3.hasValue() ) lcl_addRangeToVec( vRanges, Arg3 ); if ( Arg4.hasValue() ) lcl_addRangeToVec( vRanges, Arg4 ); if ( Arg5.hasValue() ) lcl_addRangeToVec( vRanges, Arg5 ); if ( Arg6.hasValue() ) lcl_addRangeToVec( vRanges, Arg6 ); if ( Arg7.hasValue() ) lcl_addRangeToVec( vRanges, Arg7 ); if ( Arg8.hasValue() ) lcl_addRangeToVec( vRanges, Arg8 ); if ( Arg9.hasValue() ) lcl_addRangeToVec( vRanges, Arg9 ); if ( Arg10.hasValue() ) lcl_addRangeToVec( vRanges, Arg10 ); if ( Arg11.hasValue() ) lcl_addRangeToVec( vRanges, Arg11 ); if ( Arg12.hasValue() ) lcl_addRangeToVec( vRanges, Arg12 ); if ( Arg13.hasValue() ) lcl_addRangeToVec( vRanges, Arg13 ); if ( Arg14.hasValue() ) lcl_addRangeToVec( vRanges, Arg14 ); if ( Arg15.hasValue() ) lcl_addRangeToVec( vRanges, Arg15 ); if ( Arg16.hasValue() ) lcl_addRangeToVec( vRanges, Arg16 ); if ( Arg17.hasValue() ) lcl_addRangeToVec( vRanges, Arg17 ); if ( Arg18.hasValue() ) lcl_addRangeToVec( vRanges, Arg18 ); if ( Arg19.hasValue() ) lcl_addRangeToVec( vRanges, Arg19 ); if ( Arg20.hasValue() ) lcl_addRangeToVec( vRanges, Arg20 ); if ( Arg21.hasValue() ) lcl_addRangeToVec( vRanges, Arg21 ); if ( Arg22.hasValue() ) lcl_addRangeToVec( vRanges, Arg22 ); if ( Arg23.hasValue() ) lcl_addRangeToVec( vRanges, Arg23 ); if ( Arg24.hasValue() ) lcl_addRangeToVec( vRanges, Arg24 ); if ( Arg25.hasValue() ) lcl_addRangeToVec( vRanges, Arg25 ); if ( Arg26.hasValue() ) lcl_addRangeToVec( vRanges, Arg26 ); if ( Arg27.hasValue() ) lcl_addRangeToVec( vRanges, Arg27 ); if ( Arg28.hasValue() ) lcl_addRangeToVec( vRanges, Arg28 ); if ( Arg29.hasValue() ) lcl_addRangeToVec( vRanges, Arg29 ); if ( Arg30.hasValue() ) lcl_addRangeToVec( vRanges, Arg30 ); ScRangeList aCellRanges; lcl_strip_containedRanges( vRanges ); for( Ranges::iterator it = vRanges.begin(); it != vRanges.end(); ++it ) aCellRanges.Append( *it ); uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_QUERY_THROW ); ScDocShell* pDocShell = excel::getDocShell( xModel ); if ( aCellRanges.Count() == 1 ) { // normal range 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( excel::getUnoSheetModuleObj( xRanges ), mxContext, xRanges ); } // #FIXME need proper (WorkSheet) parent return xRange; } void ScVbaApplication::Volatile( const uno::Any& aVolatile ) throw ( uno::RuntimeException ) { sal_Bool bVolatile = sal_True; aVolatile >>= bVolatile; return; } void SAL_CALL ScVbaApplication::DoEvents() throw ( uno::RuntimeException ) { } ::sal_Bool SAL_CALL ScVbaApplication::getDisplayFormulaBar() throw ( css::uno::RuntimeException ) { sal_Bool bRes = sal_False; ScTabViewShell* pViewShell = excel::getCurrentBestViewShell( mxContext ); if ( pViewShell ) { SfxBoolItem sfxFormBar( FID_TOGGLEINPUTLINE); SfxAllItemSet reqList( SFX_APP()->GetPool() ); reqList.Put( sfxFormBar ); pViewShell->GetState( reqList ); const SfxPoolItem *pItem=0; if ( reqList.GetItemState( FID_TOGGLEINPUTLINE, sal_False, &pItem ) == SFX_ITEM_SET ) bRes = ((SfxBoolItem*)pItem)->GetValue(); } return bRes; } void SAL_CALL ScVbaApplication::setDisplayFormulaBar( ::sal_Bool _displayformulabar ) throw ( css::uno::RuntimeException ) { ScTabViewShell* pViewShell = excel::getCurrentBestViewShell( mxContext ); if ( pViewShell && ( _displayformulabar != getDisplayFormulaBar() ) ) { SfxBoolItem sfxFormBar( FID_TOGGLEINPUTLINE, _displayformulabar); SfxAllItemSet reqList( SFX_APP()->GetPool() ); SfxRequest aReq( FID_TOGGLEINPUTLINE, 0, reqList ); pViewShell->Execute( aReq ); } } uno::Any SAL_CALL ScVbaApplication::Caller( const uno::Any& /*aIndex*/ ) throw ( uno::RuntimeException ) { StarBASIC* pBasic = SFX_APP()->GetBasic(); SFX_APP()->EnterBasicCall(); SbMethod* pMeth = (SbMethod*)pBasic->GetRtl()->Find( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("FuncCaller") ), SbxCLASS_METHOD ); uno::Any aRet; if ( pMeth ) { SbxVariableRef refTemp = pMeth; // forces a broadcast SbxVariableRef pNew = new SbxMethod( *((SbxMethod*)pMeth)); OSL_TRACE("pNew has type %d and string value %s", pNew->GetType(), rtl::OUStringToOString( pNew->GetString(), RTL_TEXTENCODING_UTF8 ).getStr() ); aRet = sbxToUnoValue( pNew ); } SFX_APP()->LeaveBasicCall(); return aRet; } uno::Reference< frame::XModel > ScVbaApplication::getCurrentDocument() throw (css::uno::RuntimeException) { return getCurrentExcelDoc(mxContext); } rtl::OUString& ScVbaApplication::getServiceImplName() { static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaApplication") ); return sImplName; } uno::Sequence< rtl::OUString > ScVbaApplication::getServiceNames() { static uno::Sequence< rtl::OUString > aServiceNames; if ( aServiceNames.getLength() == 0 ) { aServiceNames.realloc( 1 ); aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Application" ) ); } return aServiceNames; } namespace application { namespace sdecl = comphelper::service_decl; sdecl::vba_service_class_ > serviceImpl; extern sdecl::ServiceDecl const serviceDecl( serviceImpl, "ScVbaApplication", "ooo.vba.excel.Application" ); }