Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/sc/source/ui/vba/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 52 kB image not shown  

Quelle  vbaapplication.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */


#include <com/sun/star/frame/XDesktop.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/script/BasicErrorException.hpp>
#include <com/sun/star/sheet/XCalculatable.hpp>
#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
#include <com/sun/star/sheet/XNamedRanges.hpp>
#include <com/sun/star/sheet/XSpreadsheetView.hpp>
#include <com/sun/star/task/XStatusIndicatorSupplier.hpp>
#include <com/sun/star/task/XStatusIndicator.hpp>
#include <com/sun/star/util/PathSettings.hpp>
#include <com/sun/star/view/XSelectionSupplier.hpp>
#include <ooo/vba/XCommandBars.hpp>
#include <ooo/vba/excel/XApplicationOutgoing.hpp>
#include <ooo/vba/excel/XlCalculation.hpp>
#include <ooo/vba/excel/XlMousePointer.hpp>
#include <ooo/vba/office/MsoShapeType.hpp>
#include <ooo/vba/office/MsoAutoShapeType.hpp>
#include <ooo/vba/office/MsoFileDialogType.hpp>

#include "vbaapplication.hxx"
#include "vbaworkbooks.hxx"
#include "vbaworkbook.hxx"
#include "vbarange.hxx"
#include "vbawsfunction.hxx"
#include "vbadialogs.hxx"
#include "vbawindow.hxx"
#include "vbawindows.hxx"
#include "vbamenubars.hxx"
#include <tabvwsh.hxx>
#include <gridwin.hxx>
#include "vbanames.hxx"
#include <vbahelper/vbashape.hxx>
#include "vbatextboxshape.hxx"
#include "vbaovalshape.hxx"
#include "vbalineshape.hxx"
#include "vbaassistant.hxx"
#include <sc.hrc>
#include <macromgr.hxx>
#include "vbafiledialog.hxx"
#include "vbafiledialogitems.hxx"

#include <osl/file.hxx>

#include <sfx2/bindings.hxx>
#include <sfx2/request.hxx>
#include <sfx2/app.hxx>
#include <vcl/svapp.hxx>

#include <comphelper/diagnose_ex.hxx>

#include <basic/sbx.hxx>
#include <basic/sbstar.hxx>
#include <basic/sbuno.hxx>
#include <basic/sbmeth.hxx>
#include <basic/sberrors.hxx>
#include <comphelper/sequence.hxx>
#include <cppu/unotype.hxx>

#include <convuno.hxx>
#include <cellsuno.hxx>
#include <unonames.hxx>
#include <docsh.hxx>
#include "excelvbahelper.hxx"
#include <basic/sbxobj.hxx>

#include <viewutil.hxx>
#include <docoptio.hxx>
#include <scmod.hxx>
#include <scdll.hxx>

#include <list>

using namespace ::ooo::vba;
using namespace ::com::sun::star;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::UNO_QUERY_THROW;
using ::com::sun::star::uno::UNO_QUERY;

/** Global application settings shared by all open workbooks. */
struct ScVbaAppSettings
{
    bool mbDisplayAlerts;
    bool mbEnableEvents;
    bool mbExcel4Menus;
    bool mbDisplayNoteIndicator;
    bool mbShowWindowsInTaskbar;
    bool mbEnableCancelKey;
    explicit ScVbaAppSettings();
};

ScVbaAppSettings::ScVbaAppSettings() :
    mbDisplayAlerts( true ),
    mbEnableEvents( true ),
    mbExcel4Menus( false ),
    mbDisplayNoteIndicator( true ),
    mbShowWindowsInTaskbar( true ),
    mbEnableCancelKey( false )
{
}

namespace {

ScVbaAppSettings& ScVbaStaticAppSettings()
{
    static ScVbaAppSettings SINGLETON;
    return SINGLETON;
}

class ScVbaApplicationOutgoingConnectionPoint : public cppu::WeakImplHelper<XConnectionPoint>
{
private:
    ScVbaApplication* mpApp;

public:
    ScVbaApplicationOutgoingConnectionPoint( ScVbaApplication* pApp );

    // XConnectionPoint
    sal_uInt32 SAL_CALL Advise(const uno::Reference< XSink >& Sink ) override;
    void SAL_CALL Unadvise( sal_uInt32 Cookie ) override;
};

}

sal_uInt32
ScVbaApplication::AddSink( const uno::Reference< XSink >& xSink )
{
    {
        SolarMutexGuard aGuard;
        ScDLL::Init();
    }
    // No harm in potentially calling this several times
    ScModule::get()->RegisterAutomationApplicationEventsCaller(uno::Reference<XSinkCaller>(this));
    mvSinks.push_back(xSink);
    return mvSinks.size();
}

void
ScVbaApplication::RemoveSink( sal_uInt32 nNumber )
{
    if (nNumber < 1 || nNumber > mvSinks.size())
        return;

    mvSinks[nNumber-1] = uno::Reference< XSink >();
}

ScVbaApplication::ScVbaApplication( const uno::Reference<uno::XComponentContext >& ;xContext ) :
    ScVbaApplication_BASE( xContext ),
    mrAppSettings( ScVbaStaticAppSettings() ),
    m_nDialogType(0)
{
}

ScVbaApplication::~ScVbaApplication()
{
}

/*static*/ bool ScVbaApplication::getDocumentEventsEnabled()
{
    return ScVbaStaticAppSettings().mbEnableEvents;
}

OUString SAL_CALL
ScVbaApplication::getExactName( const OUString& aApproximateName )
{
    uno::Reference< beans::XExactName > xWSF( new ScVbaWSFunction( this, mxContext ) );
    return xWSF->getExactName( aApproximateName );
}

uno::Reference< beans::XIntrospectionAccess > SAL_CALL
ScVbaApplication::getIntrospection()
{
    uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
    return xWSF->getIntrospection();
}

uno::Any SAL_CALL
ScVbaApplication::invoke( const OUString& FunctionName, const uno::Sequence< uno::Any >& Params, uno::Sequence< sal_Int16 >& OutParamIndex, uno::Sequence< uno::Any >& OutParam)
{
    /*  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 (const uno::Exception&)
    {
        aAny <<= script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), 1000, OUString() );
    }
    return aAny;
}

void SAL_CALL
ScVbaApplication::setValue( const OUString& PropertyName, const uno::Any& Value )
{
    uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
    xWSF->setValue( PropertyName, Value );
}

uno::Any SAL_CALL
ScVbaApplication::getValue( const OUString& PropertyName )
{
    uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
    return xWSF->getValue( PropertyName );
}

sal_Bool SAL_CALL
ScVbaApplication::hasMethod( const OUString& Name )
{
    uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
    return xWSF->hasMethod( Name );
}

sal_Bool SAL_CALL
ScVbaApplication::hasProperty( const OUString& Name )
{
    uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
    return xWSF->hasProperty( Name );
}

uno::Reference< excel::XWorkbook >
ScVbaApplication::getActiveWorkbook()
{
    uno::Reference< frame::XModel > xModel( getCurrentExcelDoc( mxContext ), uno::UNO_SET_THROW );
    uno::Reference< excel::XWorkbook > xWorkbook( getVBADocument( xModel ), uno::UNO_QUERY );
    if( xWorkbook.is() ) return xWorkbook;
    // #i116936# getVBADocument() may return null in documents without global VBA mode enabled
    return new ScVbaWorkbook( this, mxContext, xModel );
}

uno::Reference< excel::XWorkbook > SAL_CALL
ScVbaApplication::getThisWorkbook()
{
    uno::Reference< frame::XModel > xModel( getThisExcelDoc( mxContext ), uno::UNO_SET_THROW );
    uno::Reference< excel::XWorkbook > xWorkbook( getVBADocument( xModel ), uno::UNO_QUERY );
    if( xWorkbook.is() ) return xWorkbook;
    // #i116936# getVBADocument() may return null in documents without global VBA mode enabled
    return new ScVbaWorkbook( this, mxContext, xModel );
}

uno::Reference< XAssistant > SAL_CALL
ScVbaApplication::getAssistant()
{
    return uno::Reference< XAssistant >( new ScVbaAssistant( this, mxContext ) );
}

uno::Any SAL_CALL
ScVbaApplication::getSelection()
{
    uno::Reference< frame::XModel > xModel( getCurrentDocument() );

    Reference< view::XSelectionSupplier > xSelSupp( xModel->getCurrentController(), UNO_QUERY_THROW );
    Reference< beans::XPropertySet > xPropSet( xSelSupp, UNO_QUERY_THROW );
    OUString aPropName( SC_UNO_FILTERED_RANGE_SELECTION );
    uno::Any aOldVal = xPropSet->getPropertyValue( aPropName );
    uno::Any any;
    any <<= false;
    xPropSet->setPropertyValue( aPropName, any );
    uno::Reference<uno::XInterface> aSelection(xSelSupp->getSelection(), uno::UNO_QUERY);
    xPropSet->setPropertyValue( aPropName, aOldVal );

    if (!aSelection.is())
    {
        throw uno::RuntimeException( u"failed to obtain current selection"_ustr );
    }

    uno::Reference< lang::XServiceInfo > xServiceInfo( aSelection, uno::UNO_QUERY_THROW );
    OUString sImplementationName = xServiceInfo->getImplementationName();

    if( sImplementationName.equalsIgnoreAsciiCase("com.sun.star.drawing.SvxShapeCollection") )
    {
        uno::Reference< drawing::XShapes > xShapes( aSelection, 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
        sal_Int32 nType = ScVbaShape::getType( xShape );
        if ( nType == office::MsoShapeType::msoAutoShape )
        {
            // TODO Oval with text box
            if( ScVbaShape::getAutoShapeType( xShape ) == office::MsoAutoShapeType::msoShapeOval )
            {
                return uno::Any( uno::Reference< msforms::XOval >(new ScVbaOvalShape( mxContext, xShape, xShapes, xModel ) ) );
            }


            uno::Reference< lang::XServiceInfo > xShapeServiceInfo( xShape, uno::UNO_QUERY_THROW );
            if ( xShapeServiceInfo->supportsService(u"com.sun.star.drawing.Text"_ustr)  )
            {
                    return uno::Any( uno::Reference< msforms::XTextBoxShape >(
                                new ScVbaTextBoxShape( mxContext, xShape, xShapes, xModel ) ) );
            }
        }
        else if ( nType == office::MsoShapeType::msoLine )
        {
            return uno::Any( uno::Reference< msforms::XLine >( new ScVbaLineShape(
                            mxContext, xShape, xShapes, xModel ) ) );
        }
        return uno::Any( uno::Reference< msforms::XShape >(new ScVbaShape( this, mxContext, xShape, xShapes, xModel, ScVbaShape::getType( xShape ) ) ) );
    }
    else if( xServiceInfo->supportsService(u"com.sun.star.sheet.SheetCellRange"_ustr) ||
             xServiceInfo->supportsService(u"com.sun.star.sheet.SheetCellRanges"_ustr) )
    {
        uno::Reference< table::XCellRange > xRange( aSelection, ::uno::UNO_QUERY);
        if ( !xRange.is() )
        {
            uno::Reference< sheet::XSheetCellRangeContainer > xRanges( aSelection, ::uno::UNO_QUERY);
            if ( xRanges.is() )
                return uno::Any( uno::Reference< excel::XRange >( new ScVbaRange( excel::getUnoSheetModuleObj( xRanges ), mxContext, xRanges ) ) );

        }
        return uno::Any( uno::Reference< excel::XRange >(new ScVbaRange( excel::getUnoSheetModuleObj( xRange ), mxContext, xRange ) ) );
    }
    else
    {
        throw uno::RuntimeException( sImplementationName + " not supported" );
    }
}

uno::Reference< excel::XRange >
ScVbaApplication::getActiveCell()
{
    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(u"No ViewShell available"_ustr );
    ScViewData& rTabView = pViewShell->GetViewData();

    sal_Int32 nCursorX = rTabView.GetCurX();
    sal_Int32 nCursorY = rTabView.GetCurY();

    // #i117392# excel::getUnoSheetModuleObj() may return null in documents without global VBA mode enabled
    return new ScVbaRange( excel::getUnoSheetModuleObj( xRange ), mxContext, xRange->getCellRangeByPosition( nCursorX, nCursorY, nCursorX, nCursorY ) );
}

uno::Any SAL_CALL
ScVbaApplication::GetOpenFilename(const uno::Any& /*aFileFilter*/, const uno::Any& /*aFilterIndex*/, const uno::Any& aTitle, const uno::Any& /*aButtonText*/, const uno::Any& aMultiSelect)
{
    // TODO - take all parameters into account
    uno::Reference<excel::XFileDialog> xDialog(new ScVbaFileDialog(this, mxContext, office::MsoFileDialogType::msoFileDialogFilePicker));
    xDialog->setTitle(aTitle);
    xDialog->setAllowMultiSelect(aMultiSelect);

    bool bMultiSelect = false;
    aMultiSelect >>= bMultiSelect;

    if (xDialog->Show() == 0)
    {
        // return FALSE when canceled
        return uno::Any(false);
    }

    uno::Reference<excel::XFileDialogSelectedItems> xItems = xDialog->getSelectedItems();
    auto* pItems = dynamic_cast<ScVbaFileDialogSelectedItems*>(xItems.get());

    // Check, if the implementation of XFileDialogSelectedItems is what we expect
    if (!pItems)
        throw uno::RuntimeException(u"Unexpected XFileDialogSelectedItems implementation"_ustr);

    auto const & rItemVector = pItems->getItems();

    if (!bMultiSelect) // only 1 selection allowed - return path
    {
        OUString aPath;
        if (!rItemVector.empty())
            aPath = rItemVector.at(0);
        return uno::Any(aPath);
    }
    else
    {
        // convert to sequence
        return uno::Any(comphelper::containerToSequence(rItemVector));
    }
}

uno::Any SAL_CALL
ScVbaApplication::International( sal_Int32 /*Index*/ )
{
    // complete stub for now
    // #TODO flesh out some of the Indices we could handle
    uno::Any aRet;
    return aRet;
}

uno::Any SAL_CALL
ScVbaApplication::FileDialog( const uno::Any& DialogType )
{
    sal_Int32 nType = 0;
    DialogType >>= nType;

    if( !m_xFileDialog || nType != m_nDialogType )
    {
        m_nDialogType = nType;
        m_xFileDialog = uno::Reference<excel::XFileDialog> ( new ScVbaFileDialog( this, mxContext, nType ));
    }
    return uno::Any( m_xFileDialog );
}

uno::Any SAL_CALL
ScVbaApplication::Workbooks( const uno::Any& aIndex )
{
    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 xWorkBooks->Item( aIndex, uno::Any() );
}

uno::Any SAL_CALL
ScVbaApplication::Worksheets( const uno::Any& aIndex )
{
    uno::Reference< excel::XWorkbook > xWorkbook( getActiveWorkbook(), uno::UNO_SET_THROW );
    return xWorkbook->Worksheets( aIndex );
}

uno::Any SAL_CALL
ScVbaApplication::WorksheetFunction( )
{
    return uno::Any( uno::Reference< script::XInvocation >( new ScVbaWSFunction( this, mxContext ) ) );
}

uno::Any SAL_CALL
ScVbaApplication::Evaluate( const OUString& Name )
{
    // #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 )
{
    uno::Reference< excel::XDialogs > xDialogs( new ScVbaDialogs( uno::Reference< XHelperInterface >( this ), mxContext, getCurrentDocument() ) );
    if( !aIndex.hasValue() )
        return uno::Any( xDialogs );
    return xDialogs->Item( aIndex );
}

uno::Reference< excel::XWindow > SAL_CALL
ScVbaApplication::getActiveWindow()
{
    uno::Reference< frame::XModel > xModel = getCurrentDocument();
    uno::Reference< frame::XController > xController( xModel->getCurrentController(), uno::UNO_SET_THROW );
    uno::Reference< XHelperInterface > xParent( getActiveWorkbook(), uno::UNO_QUERY_THROW );
    uno::Reference< excel::XWindow > xWin( new ScVbaWindow( xParent, mxContext, xModel, xController ) );
    return xWin;
}

uno::Any SAL_CALL
ScVbaApplication::getCutCopyMode()
{
    //# FIXME TODO, implementation
    uno::Any result;
    result <<= false;
    return result;
}

void SAL_CALL
ScVbaApplication::setCutCopyMode( const uno::Any& /* _cutcopymode */ )
{
    //# FIXME TODO, implementation
}

uno::Any SAL_CALL
ScVbaApplication::getStatusBar()
{
    return uno::Any( !getDisplayStatusBar() );
}

css::uno::Any SAL_CALL ScVbaApplication::getWindowState()
{
    return getActiveWindow()->getWindowState();
}

void SAL_CALL ScVbaApplication::setWindowState(const css::uno::Any& rWindowState)
{
    getActiveWindow()->setWindowState(rWindowState);
}

void SAL_CALL
ScVbaApplication::setStatusBar( const uno::Any& _statusbar )
{
    OUString sText;
    bool bDefault = false;
    uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW );
    uno::Reference< task::XStatusIndicatorSupplier > xStatusIndicatorSupplier( xModel->getCurrentController(), uno::UNO_QUERY_THROW );
    uno::Reference< task::XStatusIndicator > xStatusIndicator( xStatusIndicatorSupplier->getStatusIndicator(), uno::UNO_SET_THROW );
    if( _statusbar >>= sText )
    {
        setDisplayStatusBar( true );
        if ( !sText.isEmpty() )
            xStatusIndicator->start( sText, 100 );
        else
            xStatusIndicator->end();        // restore normal state for empty text
    }
    else if( _statusbar >>= bDefault )
    {
        if( !bDefault )
        {
            xStatusIndicator->end();
            setDisplayStatusBar( true );
        }
    }
    else
        throw uno::RuntimeException(u"Invalid parameter. It should be a string or False"_ustr );
}

::sal_Int32 SAL_CALL
ScVbaApplication::getCalculation()
{
    // TODO: in Excel, this is an application-wide setting
    uno::Reference<sheet::XCalculatable> 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 )
{
    // TODO: in Excel, this is an application-wide setting
    uno::Reference< sheet::XCalculatable > xCalc(getCurrentDocument(), uno::UNO_QUERY_THROW);
    switch(_calculation)
    {
        case excel::XlCalculation::xlCalculationManual:
            xCalc->enableAutomaticCalculation(false);
            break;
        case excel::XlCalculation::xlCalculationAutomatic:
        case excel::XlCalculation::xlCalculationSemiautomatic:
            xCalc->enableAutomaticCalculation(true);
            break;
    }
}

uno::Any SAL_CALL
ScVbaApplication::Windows( const uno::Any& aIndex  )
{
    uno::Reference< excel::XWindows >  xWindows( new ScVbaWindows( this, mxContext ) );
    if ( aIndex.getValueTypeClass() == uno::TypeClass_VOID )
        return uno::Any( xWindows );
    return xWindows->Item( aIndex, uno::Any() );
}
void SAL_CALL
ScVbaApplication::wait( double time )
{
    StarBASIC* pBasic = SfxApplication::GetBasic();
    SbxArrayRef aArgs = new SbxArray;
    SbxVariableRef aRef = new SbxVariable;
    aRef->PutDouble( time );
    aArgs->Put(aRef.get(), 1);
    SbMethod* pMeth = static_cast<SbMethod*>(pBasic->GetRtl()->Find( u"WaitUntil"_ustr, SbxClassType::Method ));

    if ( pMeth )
    {
        pMeth->SetParameters( aArgs.get() );
        SbxVariableRef refTemp = pMeth;
        // forces a broadcast
        SbxVariableRef pNew = new  SbxMethod( *static_cast<SbxMethod*>(pMeth));
    }
}

uno::Any SAL_CALL
ScVbaApplication::Range( const uno::Any& Cell1, const uno::Any& Cell2 )
{
    uno::Reference< excel::XRange > xVbRange = ScVbaRange::ApplicationRange( mxContext, Cell1, Cell2 );
    return uno::Any( xVbRange );
}

uno::Any SAL_CALL
ScVbaApplication::Names( const css::uno::Any& aIndex )
{
    uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW );
    uno::Reference< beans::XPropertySet > xPropertySet( xModel, uno::UNO_QUERY_THROW );
    uno::Reference< sheet::XNamedRanges > xNamedRanges( xPropertySet->getPropertyValue(
        u"NamedRanges"_ustr ), 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 xNames->Item( aIndex, uno::Any() );
}

uno::Reference< excel::XWorksheet > SAL_CALL
ScVbaApplication::getActiveSheet()
{
    uno::Reference< excel::XWorksheet > result;
    uno::Reference< excel::XWorkbook > xWorkbook = getActiveWorkbook();
    if ( xWorkbook.is() )
    {
        uno::Reference< excel::XWorksheet > xWorksheet =
            xWorkbook->getActiveSheet();
        if ( xWorksheet.is() )
        {
            result = std::move(xWorksheet);
        }
    }

    if ( !result.is() )
    {
        // Fixme - check if this is reasonable/desired behavior
        throw uno::RuntimeException(u"No activeSheet available"_ustr );
    }
    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 scroll, 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::GoToconst uno::Any& Reference, const uno::Any& Scroll )
{
    //test Scroll is a boolean
    bool bScroll = false;
    //R1C1-style string or a string of procedure name.

    if( Scroll.hasValue() )
    {
        bool aScroll = false;
        if( !(Scroll >>= aScroll) )
            throw uno::RuntimeException(u"second parameter should be boolean"_ustr );

        bScroll = aScroll;

    }

    OUString sRangeName;
    if( Reference >>= sRangeName )
    {
        ScTabViewShell* pShell = excel::getCurrentBestViewShell( mxContext );
        if (!pShell)
            return;

        uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW );
        uno::Reference< sheet::XSpreadsheetView > xSpreadsheet(
                xModel->getCurrentController(), uno::UNO_QUERY_THROW );

        ScGridWindow* gridWindow = static_cast<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::Any( static_cast<sal_Int16>(xVbaSheetRange->getRow() - 1) ),
                         uno::Any( static_cast<sal_Int16>(nValueY) ),
                         uno::Any( static_cast<sal_Int16>(xVbaSheetRange->getColumn() - 1)  ),
                         uno::Any( static_cast<sal_Int16>(nValueX) ) );
                gridWindow->GrabFocus();
            }
            else
            {
                xVbaSheetRange->Select();
                gridWindow->GrabFocus();
            }
        }
        catch (const uno::RuntimeException&)
        {
            //maybe this should be a procedure name
            //TODO for procedure name
            //browse::XBrowseNodeFactory is a singleton. OUString( "/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(u"invalid reference for range name, it should be procedure name"_ustr );
        }
        return;
    }
    uno::Reference< excel::XRange > xRange;
    if( Reference >>= xRange )
    {
        ScTabViewShell* pShell = excel::getCurrentBestViewShell( mxContext );
        if (!pShell)
            return;

        uno::Reference< excel::XRange > xVbaRange( Reference, uno::UNO_QUERY );
        ScGridWindow* gridWindow = static_cast<ScGridWindow*>(pShell->GetWindow());
        if ( xVbaRange.is() )
        {
            //TODO bScroll should be used. At this time, it does not have effect
            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::Any( static_cast<sal_Int16>(xVbaRange->getRow() - 1) ),
                         uno::Any( static_cast<sal_Int16>(nValueY) ),
                         uno::Any( static_cast<sal_Int16>(xVbaRange->getColumn() - 1)  ),
                         uno::Any( static_cast<sal_Int16>(nValueX) ) );
                gridWindow->GrabFocus();
            }
            else
            {
                xVbaRange->Select();
                gridWindow->GrabFocus();
            }
        }
        return;
    }
    throw uno::RuntimeException(u"invalid reference or name"_ustr );
}

sal_Int32 SAL_CALL
ScVbaApplication::getCursor()
{
    PointerStyle nPointerStyle =  getPointerStyle(getCurrentDocument());

    switch( nPointerStyle )
    {
        case PointerStyle::Arrow:
            return excel::XlMousePointer::xlNorthwestArrow;
        case PointerStyle::Null:
            return excel::XlMousePointer::xlDefault;
        case PointerStyle::Wait:
            return excel::XlMousePointer::xlWait;
        case PointerStyle::Text:
            return excel::XlMousePointer::xlIBeam;
        default:
            return excel::XlMousePointer::xlDefault;
    }
}

void SAL_CALL
ScVbaApplication::setCursor( sal_Int32 _cursor )
{
    try
    {
        uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW );
        switch( _cursor )
        {
            case excel::XlMousePointer::xlNorthwestArrow:
            {
                setCursorHelper( xModel, PointerStyle::Arrow, false );
                break;
            }
            case excel::XlMousePointer::xlWait:
            case excel::XlMousePointer::xlIBeam:
            {
                PointerStyle nPointer( static_cast< PointerStyle >( _cursor ) );
                //It will set the edit window, toobar and statusbar's mouse pointer.
                setCursorHelper( xModel, nPointer, true );
                break;
            }
            case excel::XlMousePointer::xlDefault:
            {
                setCursorHelper( xModel, PointerStyle::Null, false );
                break;
            }
            default:
                throw uno::RuntimeException(u"Unknown value for Cursor pointer"_ustr );
                // 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("sc.ui");
    }
}

// #TODO perhaps we should switch the return type depending of the filter
// type, e.g. return Calc for Calc and Excel if it's an imported doc
OUString SAL_CALL
ScVbaApplication::getName()
{
    return u"Microsoft Excel"_ustr;
}

// #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)
{
    mrAppSettings.mbDisplayAlerts = displayAlerts;
}

sal_Bool SAL_CALL
ScVbaApplication::getDisplayAlerts()
{
    return mrAppSettings.mbDisplayAlerts;
}

void SAL_CALL
ScVbaApplication::setEnableEvents(sal_Bool bEnable)
{
    mrAppSettings.mbEnableEvents = bEnable;
}

sal_Bool SAL_CALL
ScVbaApplication::getEnableEvents()
{
    return mrAppSettings.mbEnableEvents;
}

void SAL_CALL
ScVbaApplication::setEnableCancelKey(sal_Bool bEnable)
{
    // Stub, does nothing
    mrAppSettings.mbEnableCancelKey = bEnable;
}

sal_Bool SAL_CALL
ScVbaApplication::getEnableCancelKey()
{
    return mrAppSettings.mbEnableCancelKey;
}

sal_Bool SAL_CALL
ScVbaApplication::getDisplayFullScreen()
{
    SfxViewShell* pShell  = excel::getCurrentBestViewShell( mxContext );
    if ( pShell )
        return ScViewUtil::IsFullScreen( *pShell );
    return false;
}

void SAL_CALL
ScVbaApplication::setDisplayFullScreen( sal_Bool bSet )
{
    // #FIXME calling  ScViewUtil::SetFullScreen( *pShell, bSet );
    // directly results in a strange crash, using dispatch instead
    if ( bSet != getDisplayFullScreen() )
        dispatchRequests( getCurrentDocument(), u".uno:FullScreen"_ustr );
}

sal_Bool SAL_CALL
ScVbaApplication::getDisplayScrollBars()
{
    ScTabViewShell* pShell  = excel::getCurrentBestViewShell( mxContext );
    if ( pShell )
    {
        return ( pShell->GetViewData().IsHScrollMode() && pShell->GetViewData().IsVScrollMode() );
    }
    return true;
}

void SAL_CALL
ScVbaApplication::setDisplayScrollBars( sal_Bool bSet )
{
    // use uno here as it does all he repainting etc. magic
    uno::Reference< sheet::XSpreadsheetView > xView( getCurrentDocument()->getCurrentController(), uno::UNO_QUERY_THROW );
    uno::Reference< beans::XPropertySet > xProps( xView, uno::UNO_QUERY );
    xProps->setPropertyValue(u"HasVerticalScrollBar"_ustr, uno::Any( bSet ) );
    xProps->setPropertyValue(u"HasHorizontalScrollBar"_ustr, uno::Any( bSet ) );
}

sal_Bool SAL_CALL
ScVbaApplication::getDisplayExcel4Menus()
{
    return mrAppSettings.mbExcel4Menus;
}

void SAL_CALL
ScVbaApplication::setDisplayExcel4Menus( sal_Bool bSet )
{
    mrAppSettings.mbExcel4Menus = bSet;
}

sal_Bool SAL_CALL
ScVbaApplication::getDisplayNoteIndicator()
{
    return mrAppSettings.mbDisplayNoteIndicator;
}

void SAL_CALL
ScVbaApplication::setDisplayNoteIndicator( sal_Bool bSet )
{
    mrAppSettings.mbDisplayNoteIndicator = bSet;
}

sal_Bool SAL_CALL
ScVbaApplication::getShowWindowsInTaskbar()
{
    return mrAppSettings.mbShowWindowsInTaskbar;
}

void SAL_CALL
ScVbaApplication::setShowWindowsInTaskbar( sal_Bool bSet )
{
    mrAppSettings.mbShowWindowsInTaskbar = bSet;
}

sal_Bool SAL_CALL
ScVbaApplication::getIteration()
{
    return ScModule::get()->GetDocOptions().IsIter();
}

void SAL_CALL
ScVbaApplication::setIteration( sal_Bool bSet )
{
    uno::Reference< lang::XMultiComponentFactory > xSMgr(
        mxContext->getServiceManager(), uno::UNO_SET_THROW );

    uno::Reference< frame::XDesktop > xDesktop
        (xSMgr->createInstanceWithContext( u"com.sun.star.frame.Desktop"_ustr , mxContext), uno::UNO_QUERY_THROW );
    uno::Reference< container::XEnumeration > xComponents = xDesktop->getComponents()->createEnumeration();
    while ( xComponents->hasMoreElements() )
    {
        uno::Reference< lang::XServiceInfo > xServiceInfo( xComponents->nextElement(), uno::UNO_QUERY );
        if ( xServiceInfo.is() && xServiceInfo->supportsService( u"com.sun.star.sheet.SpreadsheetDocument"_ustr ) )
        {
            uno::Reference< beans::XPropertySet > xProps( xServiceInfo, uno::UNO_QUERY );
            if ( xProps.is() )
                xProps->setPropertyValue(  SC_UNO_ITERENABLED, uno::Any( bSet ) );
        }
    }
    ScModule* mod = ScModule::get();
    ScDocOptions aOpts(mod->GetDocOptions());
    aOpts.SetIter( bSet );
    mod->SetDocOptions(aOpts);
}

void SAL_CALL
ScVbaApplication::Calculate()
{
    uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW );
    uno::Reference< sheet::XCalculatable > xCalculatable( getCurrentDocument(), uno::UNO_QUERY_THROW );
    xCalculatable->calculateAll();
}

/// @throws uno::RuntimeException
static uno::Reference< util::XPathSettings > const & lcl_getPathSettingsService( const uno::Reference< uno::XComponentContext >& xContext )
{
    static uno::Reference< util::XPathSettings > xPathSettings( util::PathSettings::create( xContext ) );
    return xPathSettings;
}

OUString ScVbaApplication::getOfficePath( const OUString& _sPathType )
{
    OUString sRetPath;
    const uno::Reference< util::XPathSettings >& xProps = lcl_getPathSettingsService( mxContext );
    try
    {
        OUString sUrl;
        xProps->getPropertyValue( _sPathType ) >>= sUrl;

        // if it's 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 (const uno::Exception&)
    {
        DebugHelper::runtimeexception(ERRCODE_BASIC_METHOD_FAILED);
    }
    return sRetPath;
}

void SAL_CALL
ScVbaApplication::setDefaultFilePath( const OUString& DefaultFilePath )
{
    const uno::Reference< util::XPathSettings >& xProps = lcl_getPathSettingsService( mxContext );
    OUString aURL;
    osl::FileBase::getFileURLFromSystemPath( DefaultFilePath, aURL );
    xProps->setWork( aURL );
}

OUString SAL_CALL
ScVbaApplication::getDefaultFilePath()
{
    return getOfficePath( u"Work"_ustr);
}

OUString SAL_CALL
ScVbaApplication::getLibraryPath()
{
    return getOfficePath( u"Basic"_ustr);
}

OUString SAL_CALL
ScVbaApplication::getTemplatesPath()
{
    return getOfficePath( u"Template"_ustr);
}

OUString SAL_CALL
ScVbaApplication::getPathSeparator()
{
    return OUString( sal_Unicode(SAL_PATHDELIMITER) );
}

OUString SAL_CALL
ScVbaApplication::getOperatingSystem()
{
    // TODO Solution should contain the version number of the operating system
    // too.
#if   defined(_WIN32)
        return "Windows";
#elif defined(MACOSX)
        return "Macintosh";
#elif defined(UNX)
        // M. Office is not available on Unix systems, so it is not documented.
        return u"Unix"_ustr;
#else
        return OUString("Unknown");
#endif
}

// Helpers for Intersect and Union

namespace {

typedef ::std::list< ScRange > ListOfScRange;

/** Appends all ranges of a VBA Range object in the passed Any to the list of ranges.

    @throws script::BasicErrorException
    @throws uno::RuntimeException
*/

void lclAddToListOfScRange( ListOfScRange& rList, const uno::Any& rArg )
{
    if( !rArg.hasValue() )
        return;

    uno::Reference< excel::XRange > xRange( rArg, uno::UNO_QUERY_THROW );
    uno::Reference< XCollection > xCol( xRange->Areas( uno::Any() ), uno::UNO_QUERY_THROW );
    for( sal_Int32 nIdx = 1, nCount = xCol->getCount(); nIdx <= nCount; ++nIdx )
    {
        uno::Reference< excel::XRange > xAreaRange( xCol->Item( uno::Any( nIdx ), uno::Any() ), uno::UNO_QUERY_THROW );
        uno::Reference< sheet::XCellRangeAddressable > xAddressable( xAreaRange->getCellRange(), uno::UNO_QUERY_THROW );
        ScRange aScRange;
        ScUnoConversion::FillScRange( aScRange, xAddressable->getRangeAddress() );
        rList.push_back( aScRange );
    }
}

/** Returns true, if the passed ranges can be expressed by a single range. The
    new range will be contained in r1 then, the range r2 can be removed. */

bool lclTryJoin( ScRange& r1, const ScRange& r2 )
{
    // 1) r2 is completely inside r1
    if( r1.Contains( r2 ) )
        return true;

    // 2) r1 is completely inside r2
    if( r2.Contains( r1 ) )
    {
        r1 = r2;
        return true;
    }

    SCCOL n1L = r1.aStart.Col();
    SCCOL n1R = r1.aEnd.Col();
    SCROW n1T = r1.aStart.Row();
    SCROW n1B = r1.aEnd.Row();
    SCCOL n2L = r2.aStart.Col();
    SCCOL n2R = r2.aEnd.Col();
    SCROW n2T = r2.aStart.Row();
    SCROW n2B = r2.aEnd.Row();

    // 3) r1 and r2 have equal upper and lower border
    if( (n1T == n2T) && (n1B == n2B) )
    {
        // check that r1 overlaps or touches r2
        if( ((n1L < n2L) && (n2L - 1 <= n1R)) || ((n2L < n1L) && (n1L - 1 <= n2R)) )
        {
            r1.aStart.SetCol( ::std::min( n1L, n2L ) );
            r1.aEnd.SetCol( ::std::max( n1R, n2R ) );
            return true;
        }
        return false;
    }

    // 4) r1 and r2 have equal left and right border
    if( (n1L == n2L) && (n1R == n2R) )
    {
        // check that r1 overlaps or touches r2
        if( ((n1T < n2T) && (n2T + 1 <= n1B)) || ((n2T < n1T) && (n1T + 1 <= n2B)) )
        {
            r1.aStart.SetRow( ::std::min( n1T, n2T ) );
            r1.aEnd.SetRow( ::std::max( n1B, n2B ) );
            return true;
        }
        return false;
    }

    // 5) cannot join these ranges
    return false;
}

/** Strips out ranges that are contained by other ranges, joins ranges that can be joined
    together (aligned borders, e.g. A4:D10 and B4:E10 would be combined to A4:E10. */

void lclJoinRanges( ListOfScRange& rList )
{
    ListOfScRange::iterator aOuterIt = rList.begin();
    while( aOuterIt != rList.end() )
    {
        bool bAnyErased = false;    // true = any range erased from rList
        ListOfScRange::iterator aInnerIt = rList.begin();
        while( aInnerIt != rList.end() )
        {
            bool bInnerErased = false;   // true = aInnerIt erased from rList
            // do not compare a range with itself
            if( (aOuterIt != aInnerIt) && lclTryJoin( *aOuterIt, *aInnerIt ) )
            {
                // aOuterIt points to joined range, aInnerIt will be removed
                aInnerIt = rList.erase( aInnerIt );
                bInnerErased = bAnyErased = true;
            }
            /*  If aInnerIt has been erased from rList, it already points to
                the next element (return value of list::erase()). */

            if( !bInnerErased )
                ++aInnerIt;
        }
        // if any range has been erased, repeat outer loop with the same range
        if( !bAnyErased )
            ++aOuterIt;
    }
}

/** Intersects the passed list with all ranges of a VBA Range object in the passed Any.

    @throws script::BasicErrorException
    @throws uno::RuntimeException
*/

void lclIntersectRanges( ListOfScRange& rList, const uno::Any& rArg )
{
    // extract the ranges from the passed argument, will throw on invalid data
    ListOfScRange aList2;
    lclAddToListOfScRange( aList2, rArg );
    // do nothing, if the passed list is already empty
    if( rList.empty() || aList2.empty() )
        return;

    // save original list in a local
    ListOfScRange aList1;
    aList1.swap( rList );
    // join ranges from passed argument
    lclJoinRanges( aList2 );
    // calculate intersection of the ranges in both lists
    forconst auto& rOuterItem : aList1 )
    {
        forconst auto& rInnerItem : aList2 )
        {
            if( rOuterItem.Intersects( rInnerItem ) )
            {
                ScRange aIsectRange(
                    std::max( rOuterItem.aStart.Col(), rInnerItem.aStart.Col() ),
                    std::max( rOuterItem.aStart.Row(), rInnerItem.aStart.Row() ),
                    std::max( rOuterItem.aStart.Tab(), rInnerItem.aStart.Tab() ),
                    std::min( rOuterItem.aEnd.Col(),   rInnerItem.aEnd.Col() ),
                    std::min( rOuterItem.aEnd.Row(),   rInnerItem.aEnd.Row() ),
                    std::min( rOuterItem.aEnd.Tab(),   rInnerItem.aEnd.Tab() ) );
                rList.push_back( aIsectRange );
            }
        }
    }
    // again, join the result ranges
    lclJoinRanges( rList );
}

/** Creates a VBA Range object from the passed list of ranges.

    @throws uno::RuntimeException
*/

uno::Reference< excel::XRange > lclCreateVbaRange(
        const uno::Reference< uno::XComponentContext >& rxContext,
        const uno::Reference< frame::XModel >& rxModel,
        const ListOfScRange& rList )
{
    ScDocShell* pDocShell = excel::getDocShell( rxModel );
    if( !pDocShell )
        throw uno::RuntimeException();

    ScRangeList aCellRanges;
    forconst auto& rItem : rList )
        aCellRanges.push_back( rItem );

    if( aCellRanges.size() == 1 )
    {
        uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pDocShell, aCellRanges.front() ) );
        return new ScVbaRange( excel::getUnoSheetModuleObj( xRange ), rxContext, xRange );
    }
    if( aCellRanges.size() > 1 )
    {
        uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pDocShell, aCellRanges ) );
        return new ScVbaRange( excel::getUnoSheetModuleObj( xRanges ), rxContext, xRanges );
    }
    return nullptr;
}

// namespace

uno::Reference< excel::XRange > SAL_CALL ScVbaApplication::Intersect(
        const uno::Reference< excel::XRange >& rArg1, const uno::Reference< excel::XRange >& rArg2,
        const uno::Any& rArg3, const uno::Any& rArg4, const uno::Any& rArg5, const uno::Any& rArg6,
        const uno::Any& rArg7, const uno::Any& rArg8, const uno::Any& rArg9, const uno::Any& rArg10,
        const uno::Any& rArg11, const uno::Any& rArg12, const uno::Any& rArg13, const uno::Any& rArg14,
        const uno::Any& rArg15, const uno::Any& rArg16, const uno::Any& rArg17, const uno::Any& rArg18,
        const uno::Any& rArg19, const uno::Any& rArg20, const uno::Any& rArg21, const uno::Any& rArg22,
        const uno::Any& rArg23, const uno::Any& rArg24, const uno::Any& rArg25, const uno::Any& rArg26,
        const uno::Any& rArg27, const uno::Any& rArg28, const uno::Any& rArg29, const uno::Any& rArg30 )
{
    if( !rArg1.is() || !rArg2.is() )
        DebugHelper::basicexception( ERRCODE_BASIC_BAD_PARAMETER, {} );

    // initialize the result list with 1st parameter, join its ranges together
    ListOfScRange aList;
    lclAddToListOfScRange( aList, uno::Any( rArg1 ) );
    lclJoinRanges( aList );

    // process all other parameters, this updates the list with intersection
    lclIntersectRanges( aList, uno::Any( rArg2 ) );
    lclIntersectRanges( aList, rArg3 );
    lclIntersectRanges( aList, rArg4 );
    lclIntersectRanges( aList, rArg5 );
    lclIntersectRanges( aList, rArg6 );
    lclIntersectRanges( aList, rArg7 );
    lclIntersectRanges( aList, rArg8 );
    lclIntersectRanges( aList, rArg9 );
    lclIntersectRanges( aList, rArg10 );
    lclIntersectRanges( aList, rArg11 );
    lclIntersectRanges( aList, rArg12 );
    lclIntersectRanges( aList, rArg13 );
    lclIntersectRanges( aList, rArg14 );
    lclIntersectRanges( aList, rArg15 );
    lclIntersectRanges( aList, rArg16 );
    lclIntersectRanges( aList, rArg17 );
    lclIntersectRanges( aList, rArg18 );
    lclIntersectRanges( aList, rArg19 );
    lclIntersectRanges( aList, rArg20 );
    lclIntersectRanges( aList, rArg21 );
    lclIntersectRanges( aList, rArg22 );
    lclIntersectRanges( aList, rArg23 );
    lclIntersectRanges( aList, rArg24 );
    lclIntersectRanges( aList, rArg25 );
    lclIntersectRanges( aList, rArg26 );
    lclIntersectRanges( aList, rArg27 );
    lclIntersectRanges( aList, rArg28 );
    lclIntersectRanges( aList, rArg29 );
    lclIntersectRanges( aList, rArg30 );

    // create the VBA Range object
    return lclCreateVbaRange( mxContext, getCurrentDocument(), aList );
}

uno::Reference< excel::XRange > SAL_CALL ScVbaApplication::Union(
        const uno::Reference< excel::XRange >& rArg1, const uno::Reference< excel::XRange >& rArg2,
        const uno::Any& rArg3, const uno::Any& rArg4, const uno::Any& rArg5, const uno::Any& rArg6,
        const uno::Any& rArg7, const uno::Any& rArg8, const uno::Any& rArg9, const uno::Any& rArg10,
        const uno::Any& rArg11, const uno::Any& rArg12, const uno::Any& rArg13, const uno::Any& rArg14,
        const uno::Any& rArg15, const uno::Any& rArg16, const uno::Any& rArg17, const uno::Any& rArg18,
        const uno::Any& rArg19, const uno::Any& rArg20, const uno::Any& rArg21, const uno::Any& rArg22,
        const uno::Any& rArg23, const uno::Any& rArg24, const uno::Any& rArg25, const uno::Any& rArg26,
        const uno::Any& rArg27, const uno::Any& rArg28, const uno::Any& rArg29, const uno::Any& rArg30 )
{
    if( !rArg1.is() || !rArg2.is() )
        DebugHelper::basicexception( ERRCODE_BASIC_BAD_PARAMETER, {} );

    ListOfScRange aList;
    lclAddToListOfScRange( aList, uno::Any( rArg1 ) );
    lclAddToListOfScRange( aList, uno::Any( rArg2 ) );
    lclAddToListOfScRange( aList, rArg3 );
    lclAddToListOfScRange( aList, rArg4 );
    lclAddToListOfScRange( aList, rArg5 );
    lclAddToListOfScRange( aList, rArg6 );
    lclAddToListOfScRange( aList, rArg7 );
    lclAddToListOfScRange( aList, rArg8 );
    lclAddToListOfScRange( aList, rArg9 );
    lclAddToListOfScRange( aList, rArg10 );
    lclAddToListOfScRange( aList, rArg11 );
    lclAddToListOfScRange( aList, rArg12 );
    lclAddToListOfScRange( aList, rArg13 );
    lclAddToListOfScRange( aList, rArg14 );
    lclAddToListOfScRange( aList, rArg15 );
    lclAddToListOfScRange( aList, rArg16 );
    lclAddToListOfScRange( aList, rArg17 );
    lclAddToListOfScRange( aList, rArg18 );
    lclAddToListOfScRange( aList, rArg19 );
    lclAddToListOfScRange( aList, rArg20 );
    lclAddToListOfScRange( aList, rArg21 );
    lclAddToListOfScRange( aList, rArg22 );
    lclAddToListOfScRange( aList, rArg23 );
    lclAddToListOfScRange( aList, rArg24 );
    lclAddToListOfScRange( aList, rArg25 );
    lclAddToListOfScRange( aList, rArg26 );
    lclAddToListOfScRange( aList, rArg27 );
    lclAddToListOfScRange( aList, rArg28 );
    lclAddToListOfScRange( aList, rArg29 );
    lclAddToListOfScRange( aList, rArg30 );

    // simply join together all ranges as much as possible, strip out covered ranges etc.
    lclJoinRanges( aList );

    // create the VBA Range object
    return lclCreateVbaRange( mxContext, getCurrentDocument(), aList );
}

double SAL_CALL
ScVbaApplication::InchesToPoints( double Inches )
{
   return o3tl::convert(Inches, o3tl::Length::in, o3tl::Length::pt);
}

double SAL_CALL
ScVbaApplication::CentimetersToPoints( double Centimeters )
{
   return o3tl::convert(Centimeters, o3tl::Length::cm, o3tl::Length::pt);
}

void
ScVbaApplication::Volatileconst uno::Any& aVolatile )
{
    bool bVolatile = true;
    aVolatile >>= bVolatile;
    SbMethod* pMeth = StarBASIC::GetActiveMethod();
    if ( pMeth )
    {
        uno::Reference< frame::XModel > xModel( getCurrentDocument() );
        if ( ScDocShell* pShell = excel::getDocShell( xModel ))
        {
            ScDocument& rDoc = pShell->GetDocument();
            rDoc.GetMacroManager()->SetUserFuncVolatile( pMeth->GetName(), bVolatile);
        }
    }

// this is bound to break when loading the document
}

sal_Bool SAL_CALL
ScVbaApplication::getDisplayFormulaBar()
{
    bool bRes = false;
    ScTabViewShell* pViewShell = excel::getCurrentBestViewShell( mxContext );
    if ( pViewShell )
    {
        SfxBoolItem sfxFormBar( FID_TOGGLEINPUTLINE);
        SfxAllItemSet reqList(  SfxGetpApp()->GetPool() );
        reqList.Put( sfxFormBar );

        pViewShell->GetState( reqList );
        if ( const SfxBoolItem *pItem = reqList.GetItemIfSet( FID_TOGGLEINPUTLINE, false ) )
            bRes = pItem->GetValue();
    }
    return bRes;
}

void SAL_CALL
ScVbaApplication::setDisplayFormulaBar( sal_Bool _displayformulabar )
{
    ScTabViewShell* pViewShell = excel::getCurrentBestViewShell( mxContext );
    if ( pViewShell && ( _displayformulabar !=  getDisplayFormulaBar() ) )
    {
        SfxAllItemSet reqList(  SfxGetpApp()->GetPool() );
        SfxRequest aReq( FID_TOGGLEINPUTLINE, SfxCallMode::SLOT, reqList );
        pViewShell->Execute( aReq );
    }
}

uno::Any SAL_CALL
ScVbaApplication::Caller( const uno::Any& /*aIndex*/ )
{
    StarBASIC* pBasic = SfxApplication::GetBasic();
    SbMethod* pMeth = static_cast<SbMethod*>(pBasic->GetRtl()->Find( u"FuncCaller"_ustr, SbxClassType::Method ));
    uno::Any aRet;
    if ( pMeth )
    {
        SbxVariableRef refTemp = pMeth;
        // forces a broadcast
        SbxVariableRef pNew = new  SbxMethod( *static_cast<SbxMethod*>(pMeth));
        aRet = sbxToUnoValue( pNew.get() );
    }
    return aRet;
}

uno::Reference< frame::XModel >
ScVbaApplication::getCurrentDocument()
{
    return getCurrentExcelDoc(mxContext);
}

uno::Any SAL_CALL
ScVbaApplication::MenuBars( const uno::Any& aIndex )
{
    uno::Reference< XCommandBars > xCommandBars( CommandBars( uno::Any() ), uno::UNO_QUERY_THROW );
    uno::Reference< XCollection > xMenuBars( new ScVbaMenuBars( this, mxContext, xCommandBars ) );
    if (  aIndex.hasValue() )
    {
        return xMenuBars->Item( aIndex, uno::Any() );
    }

    return uno::Any( xMenuBars );
}

uno::Any SAL_CALL
ScVbaApplication::Rows( const uno::Any& aIndex )
{
    uno::Reference< excel::XWorksheet > xWorksheet = getActiveSheet();
    if ( xWorksheet.is() )
        return uno::Any( xWorksheet->Rows( aIndex ) );
    return uno::Any();
}

void SAL_CALL ScVbaApplication::OnKey( const OUString& Key, const uno::Any& Procedure )
{
    try
    {
        // Perhaps we can catch some excel specific
        // related behaviour here
        VbaApplicationBase::OnKey( Key, Procedure );
    }
    catch( container::NoSuchElementException& )
    {
        // #TODO special handling for unhandled
        // bindings
    }
}

void SAL_CALL ScVbaApplication::setScreenUpdating(sal_Bool bUpdate)
{
    VbaApplicationBase::setScreenUpdating( bUpdate );

    uno::Reference< frame::XModel > xModel( getCurrentExcelDoc( mxContext ), uno::UNO_SET_THROW );

    ScDocShell* pDocShell = excel::getDocShell( xModel );
    if (!pDocShell)
        return;
    ScDocument& rDoc = pDocShell->GetDocument();

    if( bUpdate )
    {
        // Since setting ScreenUpdating from user code might be unpaired, avoid calling function,
        // that asserts correct lock/unlock order and number, when not locked.
        if(rDoc.IsAdjustHeightLocked())
            rDoc.UnlockAdjustHeight();
        if( !rDoc.IsAdjustHeightLocked() )
            pDocShell->UpdateAllRowHeights();
    }
    else
    {
        rDoc.LockAdjustHeight();
    }
}

void SAL_CALL ScVbaApplication::Undo()
{
    uno::Reference< frame::XModel > xModel( getThisExcelDoc( mxContext ), uno::UNO_SET_THROW );

    ScTabViewShell* pViewShell = excel::getBestViewShell( xModel );
    if ( pViewShell )
        dispatchExecute( pViewShell, SID_UNDO );
}

// XInterfaceWithIID

OUString SAL_CALL
ScVbaApplication::getIID()
{
    return u"{82154425-0FBF-11d4-8313-005004526AB4}"_ustr;
}

// XConnectable

OUString SAL_CALL
ScVbaApplication::GetIIDForClassItselfNotCoclass()
{
    return u"{82154426-0FBF-11D4-8313-005004526AB4}"_ustr;
}

TypeAndIID SAL_CALL
ScVbaApplication::GetConnectionPoint()
{
    TypeAndIID aResult =
        { cppu::UnoType<excel::XApplicationOutgoing>::get(),
          u"{82154427-0FBF-11D4-8313-005004526AB4}"_ustr
        };

    return aResult;
}

uno::Reference<XConnectionPoint> SAL_CALL
ScVbaApplication::FindConnectionPoint()
{
    uno::Reference<XConnectionPoint> xCP(new ScVbaApplicationOutgoingConnectionPoint(this));
    return xCP;
}

// XSinkCaller

void SAL_CALL
ScVbaApplication::CallSinks( const OUString& Method, uno::Sequence< uno::Any >& Arguments )
{
    for (auto& i : mvSinks)
    {
        if (i.is())
            i->Call(Method, Arguments);
    }
}

OUString
ScVbaApplication::getServiceImplName()
{
    return u"ScVbaApplication"_ustr;
}

uno::Sequence< OUString >
ScVbaApplication::getServiceNames()
{
    static uno::Sequence< OUString > aServiceNames
    {
        u"ooo.vba.excel.Application"_ustr
    };
    return aServiceNames;
}


extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
Calc_ScVbaApplication_get_implementation(
    css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& )
{
    return cppu::acquire(new ScVbaApplication(context));
}


// ScVbaApplicationOutgoingConnectionPoint

ScVbaApplicationOutgoingConnectionPoint::ScVbaApplicationOutgoingConnectionPoint( ScVbaApplication* pApp ) :
    mpApp(pApp)
{
}

// XConnectionPoint
sal_uInt32 SAL_CALL
ScVbaApplicationOutgoingConnectionPoint::Advise( const uno::Reference< XSink >& Sink )
{
    return mpApp->AddSink(Sink);
}

void SAL_CALL
ScVbaApplicationOutgoingConnectionPoint::Unadvise( sal_uInt32 Cookie )
{
    mpApp->RemoveSink( Cookie );
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=92 H=96 G=93

¤ Dauer der Verarbeitung: 0.22 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.