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 38 kB image not shown  

Quelle  vbaworksheet.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 <sal/config.h>

#include <string_view>

#include "vbaworksheet.hxx"
#include "vbanames.hxx"

#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/XIntrospectionAccess.hpp>
#include <com/sun/star/container/XNamed.hpp>
#include <com/sun/star/util/XProtectable.hpp>
#include <com/sun/star/table/XCellRange.hpp>
#include <com/sun/star/sheet/XSpreadsheetView.hpp>
#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
#include <com/sun/star/sheet/XCalculatable.hpp>
#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
#include <com/sun/star/sheet/XSheetCellRange.hpp>
#include <com/sun/star/sheet/XSheetCellCursor.hpp>
#include <com/sun/star/sheet/XSheetAnnotationsSupplier.hpp>
#include <com/sun/star/sheet/XUsedAreaCursor.hpp>
#include <com/sun/star/sheet/XSpreadsheets.hpp>
#include <com/sun/star/sheet/XSheetOutline.hpp>
#include <com/sun/star/sheet/XSheetPageBreak.hpp>
#include <com/sun/star/sheet/XDataPilotTablesSupplier.hpp>
#include <com/sun/star/sheet/XNamedRanges.hpp>
#include <com/sun/star/frame/Desktop.hpp>
#include <com/sun/star/table/XTableChartsSupplier.hpp>
#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
#include <com/sun/star/drawing/XControlShape.hpp>
#include <com/sun/star/form/XFormsSupplier.hpp>
#include <ooo/vba/excel/XApplication.hpp>
#include <ooo/vba/excel/XlEnableSelection.hpp>
#include <ooo/vba/excel/XlSheetVisibility.hpp>
#include <ooo/vba/XControlProvider.hpp>

#include <basic/sberrors.hxx>
#include <comphelper/processfactory.hxx>
#include <comphelper/servicehelper.hxx>
#include <utility>
#include <vbahelper/vbashapes.hxx>

//zhangyun showdataform
#include <scabstdlg.hxx>
#include <tabvwsh.hxx>

#include <tabprotection.hxx>
#include "excelvbahelper.hxx"
#include "vbaoutline.hxx"
#include "vbarange.hxx"
#include "vbacomments.hxx"
#include "vbachartobjects.hxx"
#include "vbapivottables.hxx"
#include "vbaoleobjects.hxx"
#include "vbapagesetup.hxx"
#include "vbapagebreaks.hxx"
#include "vbaworksheets.hxx"
#include "vbahyperlinks.hxx"
#include "vbasheetobjects.hxx"
#include <dbdata.hxx>

#include <attrib.hxx>

#define STANDARDWIDTH 2267
#define STANDARDHEIGHT 427

using namespace com::sun::star;
using namespace ooo::vba;

static void getNewSpreadsheetName (OUString &aNewName, std::u16string_view aOldName, const uno::Reference <sheet::XSpreadsheetDocument>& xSpreadDoc )
{
    if (!xSpreadDoc.is())
        throw lang::IllegalArgumentException( u"getNewSpreadsheetName() xSpreadDoc is null"_ustr, uno::Reference< uno::XInterface  >(), 1 );
    static const char aUnderScore[] =  "_";
    int currentNum =2;
    aNewName = OUString::Concat(aOldName) + aUnderScore + OUString::number(currentNum) ;
    SCTAB nTab = 0;
    while ( ScVbaWorksheets::nameExists(xSpreadDoc,aNewName, nTab ) )
    {
        aNewName = OUString::Concat(aOldName) + aUnderScore + OUString::number(++currentNum);
    }
}

static void removeAllSheets( const uno::Reference <sheet::XSpreadsheetDocument>& xSpreadDoc, const OUString& aSheetName)
{
    if (!xSpreadDoc.is())
        throw lang::IllegalArgumentException( u"removeAllSheets() xSpreadDoc is null"_ustr, uno::Reference< uno::XInterface  >(), 1 );
    uno::Reference<sheet::XSpreadsheets> xSheets = xSpreadDoc->getSheets();
    uno::Reference <container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY );

    if ( !xIndex.is() )
        return;

    uno::Reference<container::XNameContainer> xNameContainer(xSheets,uno::UNO_QUERY_THROW);
    for (sal_Int32 i = xIndex->getCount() -1; i>= 1; i--)
    {
        uno::Reference< sheet::XSpreadsheet > xSheet(xIndex->getByIndex(i), uno::UNO_QUERY);
        uno::Reference< container::XNamed > xNamed( xSheet, uno::UNO_QUERY_THROW );
        xNameContainer->removeByName(xNamed->getName());
    }

    uno::Reference< sheet::XSpreadsheet > xSheet(xIndex->getByIndex(0), uno::UNO_QUERY);
    uno::Reference< container::XNamed > xNamed( xSheet, uno::UNO_QUERY_THROW );
    xNamed->setName(aSheetName);
}

static uno::Reference<frame::XModel>
openNewDoc(const OUString& aSheetName )
{
    uno::Reference<frame::XModel> xModel;
    try
    {
        const uno::Reference< uno::XComponentContext >& xContext(
            comphelper::getProcessComponentContext() );

        uno::Reference <frame::XDesktop2 > xComponentLoader = frame::Desktop::create(xContext);

        uno::Reference<lang::XComponent > xComponent( xComponentLoader->loadComponentFromURL(
                u"private:factory/scalc"_ustr,
                u"_blank"_ustr, 0,
                uno::Sequence < css::beans::PropertyValue >() ) );
        uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( xComponent, uno::UNO_QUERY_THROW );
        removeAllSheets(xSpreadDoc,aSheetName);
        xModel.set(xSpreadDoc,uno::UNO_QUERY_THROW);
    }
    catch ( uno::Exception & /*e*/ )
    {
    }
    return xModel;
}

ScVbaWorksheet::ScVbaWorksheet(const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext,
        uno::Reference< sheet::XSpreadsheet > xSheet,
        uno::Reference< frame::XModel > xModel ) : WorksheetImpl_BASE( xParent, xContext ), mxSheet(std::move( xSheet )), mxModel(std::move(xModel)), mbVeryHidden( false )
{
}

ScVbaWorksheet::ScVbaWorksheet( uno::Sequence< uno::Any> const & args,
    uno::Reference< uno::XComponentContext> const & xContext ) :  WorksheetImpl_BASE( getXSomethingFromArgs< XHelperInterface >( args, 0 ), xContext ), mxModel( getXSomethingFromArgs< frame::XModel >( args, 1 ) ), mbVeryHidden( false )
{
    if ( args.getLength() < 3 )
        throw lang::IllegalArgumentException();

    OUString sSheetName;
    args[2] >>= sSheetName;

    uno::Reference< sheet::XSpreadsheetDocument > xSpreadDoc( mxModel, uno::UNO_QUERY_THROW );
    uno::Reference< container::XNameAccess > xNameAccess( xSpreadDoc->getSheets(), uno::UNO_QUERY_THROW );
    mxSheet.set( xNameAccess->getByName( sSheetName ), uno::UNO_QUERY_THROW );
}

ScVbaWorksheet::~ScVbaWorksheet()
{
}

const uno::Sequence<sal_Int8>& ScVbaWorksheet::getUnoTunnelId()
{
    static const comphelper::UnoIdInit theScVbaWorksheetUnoTunnelId;
    return theScVbaWorksheetUnoTunnelId.getSeq();
}

uno::Reference< ov::excel::XWorksheet >
ScVbaWorksheet::createSheetCopyInNewDoc(const OUString& aCurrSheetName)
{
    uno::Reference< sheet::XSheetCellCursor > xSheetCellCursor = getSheet()->createCursor( );
    uno::Reference<sheet::XUsedAreaCursor> xUsedCursor(xSheetCellCursor,uno::UNO_QUERY_THROW);
    uno::Reference<excel::XRange> xRange =  new ScVbaRange( this, mxContext, xSheetCellCursor);
    if (xRange.is())
        xRange->Select();
    excel::implnCopy(mxModel);
    uno::Reference<frame::XModel> xModel = openNewDoc(aCurrSheetName);
    if (xModel.is())
    {
        excel::implnPaste(xModel);
    }
    uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( xModel, uno::UNO_QUERY_THROW );
    excel::setUpDocumentModules(xSpreadDoc);
    uno::Reference <sheet::XSpreadsheets> xSheets( xSpreadDoc->getSheets(), uno::UNO_SET_THROW );
    uno::Reference <container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY_THROW );
    uno::Reference< sheet::XSpreadsheet > xSheet(xIndex->getByIndex(0), uno::UNO_QUERY_THROW);

    ScDocShell* pShell = excel::getDocShell( xModel );
    OUString aCodeName;
    if (pShell)
        pShell->GetDocument().GetCodeName( 0, aCodeName );
    return uno::Reference< excel::XWorksheet >( getUnoDocModule( aCodeName, pShell ), uno::UNO_QUERY_THROW );
}

css::uno::Reference< ov::excel::XWorksheet >
ScVbaWorksheet::createSheetCopy(uno::Reference<excel::XWorksheet> const & xSheet, bool bAfter)
{
    OUString aCurrSheetName = getName();
    ScVbaWorksheet* pDestSheet = excel::getImplFromDocModuleWrapper<ScVbaWorksheet>( xSheet );

    uno::Reference <sheet::XSpreadsheetDocument> xDestDoc( pDestSheet->getModel(), uno::UNO_QUERY );
    uno::Reference <sheet::XSpreadsheetDocument> xSrcDoc( getModel(), uno::UNO_QUERY );

    SCTAB nDest = 0;
    SCTAB nSrc = 0;
    OUString aSheetName = xSheet->getName();
    bool bSameDoc = ( pDestSheet->getModel() == getModel() );
    bool bDestSheetExists = ScVbaWorksheets::nameExists (xDestDoc, aSheetName, nDest );
    bool bSheetExists = ScVbaWorksheets::nameExists (xSrcDoc, aCurrSheetName, nSrc );

    // set sheet name to be newSheet name
    aSheetName = aCurrSheetName;
    if ( bSheetExists && bDestSheetExists )
    {
        SCTAB nDummy=0;
        if(bAfter)
              nDest++;
        uno::Reference<sheet::XSpreadsheets> xSheets = xDestDoc->getSheets();
        if ( bSameDoc || ScVbaWorksheets::nameExists( xDestDoc, aCurrSheetName, nDummy ) )
            getNewSpreadsheetName(aSheetName,aCurrSheetName,xDestDoc);
        if ( bSameDoc )
            xSheets->copyByName(aCurrSheetName,aSheetName,nDest);
        else
        {
            ScDocShell* pDestDocShell = excel::getDocShell( pDestSheet->getModel() );
            ScDocShell* pSrcDocShell = excel::getDocShell( getModel() );
            if ( pDestDocShell && pSrcDocShell )
                pDestDocShell->TransferTab( *pSrcDocShell, nSrc, nDest, truetrue );
        }
    }
    // return new sheet
    uno::Reference< excel::XApplication > xApplication( Application(), uno::UNO_QUERY_THROW );
    uno::Reference< excel::XWorksheet > xNewSheet( xApplication->Worksheets( uno::Any( aSheetName ) ), uno::UNO_QUERY_THROW );
    return xNewSheet;
}

OUString
ScVbaWorksheet::getName()
{
    uno::Reference< container::XNamed > xNamed( getSheet(), uno::UNO_QUERY_THROW );
    return xNamed->getName();
}

void
ScVbaWorksheet::setName(const OUString &rName )
{
    uno::Reference< container::XNamed > xNamed( getSheet(), uno::UNO_QUERY_THROW );
    xNamed->setName( rName );
}

sal_Int32
ScVbaWorksheet::getVisible()
{
    uno::Reference< beans::XPropertySet > xProps( getSheet(), uno::UNO_QUERY_THROW );
    bool bVisible = false;
    xProps->getPropertyValue( u"IsVisible"_ustr ) >>= bVisible;
    using namespace ::ooo::vba::excel::XlSheetVisibility;
    return bVisible ? xlSheetVisible : (mbVeryHidden ? xlSheetVeryHidden : xlSheetHidden);
}

void
ScVbaWorksheet::setVisible( sal_Int32 nVisible )
{
    using namespace ::ooo::vba::excel::XlSheetVisibility;
    bool bVisible = true;
    switch( nVisible )
    {
        case xlSheetVisible: case 1:  // Excel accepts -1 and 1 for visible sheets
            bVisible = true;
            mbVeryHidden = false;
        break;
        case xlSheetHidden:
            bVisible = false;
            mbVeryHidden = false;
        break;
        case xlSheetVeryHidden:
            bVisible = false;
            mbVeryHidden = true;
        break;
        default:
            throw uno::RuntimeException();
    }
    uno::Reference< beans::XPropertySet > xProps( getSheet(), uno::UNO_QUERY_THROW );
    xProps->setPropertyValue( u"IsVisible"_ustr, uno::Any( bVisible ) );
}

sal_Int16
ScVbaWorksheet::getIndex()
{
    return getSheetID() + 1;
}

sal_Int32
ScVbaWorksheet::getEnableSelection()
{
    uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY_THROW );
    SCTAB nTab = 0;
    if ( !ScVbaWorksheets::nameExists(xSpreadDoc, getName(), nTab) )
        throw uno::RuntimeException(u"Sheet Name does not exist."_ustr );

    if ( ScDocShell* pShell = excel::getDocShell( getModel() ))
    {
        ScDocument& rDoc = pShell->GetDocument();
        const ScTableProtection* pProtect = rDoc.GetTabProtection(nTab);
        bool bLockedCells = false;
        bool bUnlockedCells = false;
        if( pProtect )
        {
            bLockedCells   = pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
            bUnlockedCells = pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
        }
        if( bLockedCells )
            return excel::XlEnableSelection::xlNoRestrictions;
        if( bUnlockedCells )
            return excel::XlEnableSelection::xlUnlockedCells;
    }
    return excel::XlEnableSelection::xlNoSelection;

}

void
ScVbaWorksheet::setEnableSelection( sal_Int32 nSelection )
{
    if( (nSelection != excel::XlEnableSelection::xlNoRestrictions) &&
        (nSelection != excel::XlEnableSelection::xlUnlockedCells) &&
        (nSelection != excel::XlEnableSelection::xlNoSelection) )
    {
        DebugHelper::runtimeexception(ERRCODE_BASIC_BAD_PARAMETER);
    }

    uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY_THROW );
    SCTAB nTab = 0;
    if ( !ScVbaWorksheets::nameExists(xSpreadDoc, getName(), nTab) )
        throw uno::RuntimeException(u"Sheet Name does not exist."_ustr );

    if ( ScDocShell* pShell = excel::getDocShell( getModel() ))
    {
        ScDocument& rDoc = pShell->GetDocument();
        const ScTableProtection* pProtect = rDoc.GetTabProtection(nTab);
        // default is xlNoSelection
        bool bLockedCells = false;
        bool bUnlockedCells = false;
        if( nSelection == excel::XlEnableSelection::xlNoRestrictions )
        {
            bLockedCells = true;
            bUnlockedCells = true;
        }
        else if( nSelection == excel::XlEnableSelection::xlUnlockedCells )
        {
            bUnlockedCells = true;
        }
        if( pProtect )
        {
            ScTableProtection aNewProtect(*pProtect);
            aNewProtect.setOption(ScTableProtection::SELECT_LOCKED_CELLS, bLockedCells);
            aNewProtect.setOption(ScTableProtection::SELECT_UNLOCKED_CELLS, bUnlockedCells);
            rDoc.SetTabProtection(nTab, &aNewProtect);
        }
    }
}

sal_Bool SAL_CALL ScVbaWorksheet::getAutoFilterMode()
{
    if ( ScDocShell* pShell = excel::getDocShell( getModel() ))
    {
        ScDocument& rDoc = pShell->GetDocument();
        ScDBData* pDBData = rDoc.GetAnonymousDBData(getSheetID());
        if (pDBData)
            return pDBData->HasAutoFilter();
    }
    return false;
}

void SAL_CALL ScVbaWorksheet::setAutoFilterMode( sal_Bool bAutoFilterMode )
{
    ScDocShell* pDocShell = excel::getDocShell( getModel() );
    if (!pDocShell)
        return;
    ScDocument& rDoc = pDocShell->GetDocument();
    ScDBData* pDBData = rDoc.GetAnonymousDBData(getSheetID());
    if (!pDBData)
        return;

    pDBData->SetAutoFilter(bAutoFilterMode);
    ScRange aRange;
    pDBData->GetArea(aRange);
    if (bAutoFilterMode)
        rDoc.ApplyFlagsTab( aRange.aStart.Col(), aRange.aStart.Row(),
                                aRange.aEnd.Col(), aRange.aStart.Row(),
                                aRange.aStart.Tab(), ScMF::Auto );
    else if (!bAutoFilterMode)
        rDoc.RemoveFlagsTab(aRange.aStart.Col(), aRange.aStart.Row(),
                                aRange.aEnd.Col(), aRange.aStart.Row(),
                                aRange.aStart.Tab(), ScMF::Auto );
    ScRange aPaintRange(aRange.aStart, aRange.aEnd);
    aPaintRange.aEnd.SetRow(aPaintRange.aStart.Row());
    pDocShell->PostPaint(aPaintRange, PaintPartFlags::Grid);
}

uno::Reference< excel::XRange >
ScVbaWorksheet::getUsedRange()
{
    uno::Reference< sheet::XSheetCellRange > xSheetCellRange(getSheet(), uno::UNO_QUERY_THROW );
    uno::Reference< sheet::XSheetCellCursor > xSheetCellCursor( getSheet()->createCursorByRange( xSheetCellRange ), uno::UNO_SET_THROW );
    uno::Reference<sheet::XUsedAreaCursor> xUsedCursor(xSheetCellCursor,uno::UNO_QUERY_THROW);
    xUsedCursor->gotoStartOfUsedArea( false );
    xUsedCursor->gotoEndOfUsedArea( true );
    return new ScVbaRange(this, mxContext, xSheetCellCursor);
}

uno::Reference< excel::XOutline >
ScVbaWorksheet::Outline( )
{
    uno::Reference<sheet::XSheetOutline> xOutline(getSheet(),uno::UNO_QUERY_THROW);
    return new ScVbaOutline( this, mxContext, xOutline);
}

uno::Reference< excel::XPageSetup >
ScVbaWorksheet::PageSetup( )
{
    return new ScVbaPageSetup( this, mxContext, getSheet(), getModel() );
}

uno::Any
ScVbaWorksheet::HPageBreaks( const uno::Any& aIndex )
{
    uno::Reference< sheet::XSheetPageBreak > xSheetPageBreak(getSheet(),uno::UNO_QUERY_THROW);
    uno::Reference< excel::XHPageBreaks > xHPageBreaks( new ScVbaHPageBreaks( this, mxContext, xSheetPageBreak));
    if ( aIndex.hasValue() )
        return xHPageBreaks->Item( aIndex, uno::Any());
    return uno::Any( xHPageBreaks );
}

uno::Any
ScVbaWorksheet::VPageBreaks( const uno::Any& aIndex )
{
    uno::Reference< sheet::XSheetPageBreak > xSheetPageBreak( getSheet(), uno::UNO_QUERY_THROW );
    uno::Reference< excel::XVPageBreaks > xVPageBreaks( new ScVbaVPageBreaks( this, mxContext, xSheetPageBreak ) );
    if( aIndex.hasValue() )
        return xVPageBreaks->Item( aIndex, uno::Any());
    return uno::Any( xVPageBreaks );
}

sal_Int32
ScVbaWorksheet::getStandardWidth()
{
    return STANDARDWIDTH ;
}

sal_Int32
ScVbaWorksheet::getStandardHeight()
{
    return STANDARDHEIGHT;
}

sal_Bool
ScVbaWorksheet::getProtectionMode()
{
    return false;
}

sal_Bool
ScVbaWorksheet::getProtectContents()
{
    uno::Reference<util::XProtectable > xProtectable(getSheet(), uno::UNO_QUERY_THROW);
    return xProtectable->isProtected();
}

sal_Bool
ScVbaWorksheet::getProtectDrawingObjects()
{
    SCTAB nTab = 0;
    OUString aSheetName = getName();
    uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY_THROW );
    bool bSheetExists = ScVbaWorksheets::nameExists (xSpreadDoc, aSheetName, nTab);
    if ( bSheetExists )
    {
        if ( ScDocShell* pShell = excel::getDocShell( getModel() ))
        {
            ScDocument& rDoc = pShell->GetDocument();
            const ScTableProtection* pProtect = rDoc.GetTabProtection(nTab);
            if ( pProtect )
                return pProtect->isOptionEnabled( ScTableProtection::OBJECTS );
        }
    }
    return false;
}

sal_Bool
ScVbaWorksheet::getProtectScenarios()
{
    return false;
}

void
ScVbaWorksheet::Activate()
{
    uno::Reference< sheet::XSpreadsheetView > xSpreadsheet(
            getModel()->getCurrentController(), uno::UNO_QUERY_THROW );
    xSpreadsheet->setActiveSheet(getSheet());
}

void
ScVbaWorksheet::Select()
{
    Activate();
}

void
ScVbaWorksheet::Move( const uno::Any& Before, const uno::Any& After )
{
    uno::Reference<excel::XWorksheet> xSheet;
    OUString aCurrSheetName = getName();

    if (!(Before >>= xSheet) && !(After >>=xSheet)&& !(Before.hasValue()) && !(After.hasValue()))
    {
        uno::Reference< sheet::XSheetCellCursor > xSheetCellCursor = getSheet()->createCursor( );
        uno::Reference<sheet::XUsedAreaCursor> xUsedCursor(xSheetCellCursor,uno::UNO_QUERY_THROW);
        // #FIXME needs worksheet as parent
        uno::Reference<excel::XRange> xRange =  new ScVbaRange( this, mxContext, xSheetCellCursor);
        if (xRange.is())
            xRange->Select();
        excel::implnCopy(mxModel);
        uno::Reference<frame::XModel> xModel = openNewDoc(aCurrSheetName);
        if (xModel.is())
        {
            excel::implnPaste(xModel);
            Delete();
        }
        return ;
    }

    uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY_THROW );
    SCTAB nDest = 0;
    if ( ScVbaWorksheets::nameExists (xSpreadDoc, xSheet->getName(), nDest) )
    {
        bool bAfter = After.hasValue();
        if (bAfter)
            nDest++;
        uno::Reference<sheet::XSpreadsheets> xSheets = xSpreadDoc->getSheets();
        xSheets->moveByName(aCurrSheetName,nDest);
    }
}

void
ScVbaWorksheet::Copy( const uno::Any& Before, const uno::Any& After )
{
    uno::Reference<excel::XWorksheet> xSheet;
    if (!(Before >>= xSheet) && !(After >>=xSheet)&& !(Before.hasValue()) && !(After.hasValue()))
    {
        createSheetCopyInNewDoc(getName());
        return;
    }

    uno::Reference<excel::XWorksheet> xNewSheet = createSheetCopy(xSheet, After.hasValue());
    xNewSheet->Activate();
}

void
ScVbaWorksheet::Paste( const uno::Any& Destination, const uno::Any& /*Link*/ )
{
    // #TODO# #FIXME# Link is not used
    uno::Reference<excel::XRange> xRange( Destination, uno::UNO_QUERY );
    if ( xRange.is() )
        xRange->Select();
    excel::implnPaste( mxModel );
}

void
ScVbaWorksheet::Delete()
{
    uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY_THROW );
    OUString aSheetName = getName();
    SCTAB nTab = 0;
    if (!ScVbaWorksheets::nameExists(xSpreadDoc, aSheetName, nTab ))
    {
        return;
    }
    uno::Reference<sheet::XSpreadsheets> xSheets = xSpreadDoc->getSheets();
    uno::Reference<container::XNameContainer> xNameContainer(xSheets,uno::UNO_QUERY_THROW);
    xNameContainer->removeByName(aSheetName);
    mxSheet.clear();
}

uno::Reference< excel::XWorksheet >
ScVbaWorksheet::getSheetAtOffset(SCTAB offset)
{
    uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY_THROW );
    uno::Reference <sheet::XSpreadsheets> xSheets( xSpreadDoc->getSheets(), uno::UNO_SET_THROW );
    uno::Reference <container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY_THROW );

    SCTAB nIdx = 0;
    if ( !ScVbaWorksheets::nameExists (xSpreadDoc, getName(), nIdx ) )
        return uno::Reference< excel::XWorksheet >();
    nIdx = nIdx + offset;
    uno::Reference< sheet::XSpreadsheet > xSheet(xIndex->getByIndex(nIdx), uno::UNO_QUERY_THROW);
    // parent will be the parent of 'this' worksheet
    return new ScVbaWorksheet (getParent(), mxContext, xSheet, getModel());
}

uno::Reference< excel::XWorksheet >
ScVbaWorksheet::getNext()
{
    return getSheetAtOffset(static_cast<SCTAB>(1));
}

uno::Reference< excel::XWorksheet >
ScVbaWorksheet::getPrevious()
{
    return getSheetAtOffset(-1);
}

void
ScVbaWorksheet::Protect( const uno::Any& Password, const uno::Any& /*DrawingObjects*/, const uno::Any& /*Contents*/, const uno::Any& /*Scenarios*/, const uno::Any& /*UserInterfaceOnly*/ )
{
    // #TODO# #FIXME# is there anything we can do with the unused param
    // can the implementation use anything else here
    uno::Reference<util::XProtectable > xProtectable(getSheet(), uno::UNO_QUERY_THROW);
    OUString aPasswd;
    Password >>= aPasswd;
    xProtectable->protect( aPasswd );
}

void
ScVbaWorksheet::Unprotect( const uno::Any& Password )
{
    uno::Reference<util::XProtectable > xProtectable(getSheet(), uno::UNO_QUERY_THROW);
    OUString aPasswd;
    Password >>= aPasswd;
    xProtectable->unprotect( aPasswd );
}

void
ScVbaWorksheet::Calculate()
{
    uno::Reference <sheet::XCalculatable> xReCalculate(getModel(), uno::UNO_QUERY_THROW);
    xReCalculate->calculate();
}

uno::Reference< excel::XRange >
ScVbaWorksheet::Range( const ::uno::Any& Cell1, const ::uno::Any& Cell2 )
{
    uno::Reference< excel::XRange > xSheetRange( new ScVbaRange( this, mxContext
, uno::Reference< table::XCellRange >( getSheet(), uno::UNO_QUERY_THROW ) ) );
    return xSheetRange->Range( Cell1, Cell2 );
}

void
ScVbaWorksheet::CheckSpelling( const uno::Any& /*CustomDictionary*/,const uno::Any& /*IgnoreUppercase*/,const uno::Any& /*AlwaysSuggest*/, const uno::Any& /*SpellingLang*/ )
{
    // #TODO# #FIXME# unused params above, can we do anything with those
    uno::Reference< frame::XModel > xModel( getModel() );
    dispatchRequests(xModel,u".uno:SpellDialog"_ustr);
}

uno::Reference< excel::XRange >
ScVbaWorksheet::getSheetRange()
{
    uno::Reference< table::XCellRange > xRange( getSheet(),uno::UNO_QUERY_THROW );
    return uno::Reference< excel::XRange >( new ScVbaRange( this, mxContext, xRange ) );
}

// These are hacks - we prolly (somehow) need to inherit
// the vbarange functionality here ...
uno::Reference< excel::XRange >
ScVbaWorksheet::Cells( const ::uno::Any &nRow, const ::uno::Any &nCol )
{
    // Performance optimization for often-called Cells method:
    // Use a common helper method instead of creating a new ScVbaRange object
    uno::Reference< table::XCellRange > xRange( getSheet(), uno::UNO_QUERY_THROW );
    uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_SET_THROW );
    if(ScDocShell* pShell = excel::getDocShell( xModel ))
        return ScVbaRange::CellsHelper(pShell->GetDocument(), this, mxContext, xRange, nRow, nCol );
    throw uno::RuntimeException();
}

uno::Reference< excel::XRange >
ScVbaWorksheet::Rows(const uno::Any& aIndex )
{
    return getSheetRange()->Rows( aIndex );
}

uno::Reference< excel::XRange >
ScVbaWorksheet::Columns( const uno::Any& aIndex )
{
    return getSheetRange()->Columns( aIndex );
}

uno::Any SAL_CALL
ScVbaWorksheet::ChartObjects( const uno::Any& Index )
{
    if ( !mxCharts.is() )
    {
        uno::Reference< table::XTableChartsSupplier > xChartSupplier( getSheet(), uno::UNO_QUERY_THROW );
        uno::Reference< table::XTableCharts > xTableCharts = xChartSupplier->getCharts();

        uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( mxSheet, uno::UNO_QUERY_THROW );
        mxCharts = new ScVbaChartObjects(  this, mxContext, xTableCharts, xDrawPageSupplier );
    }
    if ( Index.hasValue() )
    {
        return mxCharts->Item( Index, uno::Any() );
    }
    else
        return uno::Any( uno::Reference<ov::excel::XChartObjects>(mxCharts) );

}

uno::Any SAL_CALL
ScVbaWorksheet::PivotTables( const uno::Any& Index )
{
    uno::Reference< css::sheet::XSpreadsheet > xSheet = getSheet();
    uno::Reference< sheet::XDataPilotTablesSupplier > xTables(xSheet, uno::UNO_QUERY_THROW ) ;
    uno::Reference< container::XIndexAccess > xIndexAccess( xTables->getDataPilotTables(), uno::UNO_QUERY_THROW );

    uno::Reference< XCollection > xColl(  new ScVbaPivotTables( this, mxContext, xIndexAccess ) );
    if ( Index.hasValue() )
        return xColl->Item( Index, uno::Any() );
    return uno::Any( xColl );
}

uno::Any SAL_CALL
ScVbaWorksheet::Comments( const uno::Any& Index )
{
    uno::Reference< css::sheet::XSpreadsheet > xSheet = getSheet();
    uno::Reference< sheet::XSheetAnnotationsSupplier > xAnnosSupp( xSheet, uno::UNO_QUERY_THROW );
    uno::Reference< sheet::XSheetAnnotations > xAnnos( xAnnosSupp->getAnnotations(), uno::UNO_SET_THROW );
    uno::Reference< container::XIndexAccess > xIndexAccess( xAnnos, uno::UNO_QUERY_THROW );
    uno::Reference< XCollection > xColl(  new ScVbaComments( this, mxContext, mxModel, xIndexAccess ) );
    if ( Index.hasValue() )
        return xColl->Item( Index, uno::Any() );
    return uno::Any( xColl );
}

uno::Any SAL_CALL
ScVbaWorksheet::Hyperlinks( const uno::Any& aIndex )
{
    /*  The worksheet always returns the same Hyperlinks object.
        See vbahyperlinks.hxx for more details. */

    if( !mxHlinks.is() )
        mxHlinks.set( new ScVbaHyperlinks( this, mxContext ) );
    if( aIndex.hasValue() )
        return uno::Reference< XCollection >( mxHlinks, uno::UNO_QUERY_THROW )->Item( aIndex, uno::Any() );
    return uno::Any( mxHlinks );
}

uno::Any SAL_CALL
ScVbaWorksheet::Names( const css::uno::Any& aIndex )
{
    css::uno::Reference<css::beans::XPropertySet> xProps(getSheet(), css::uno::UNO_QUERY_THROW);
    uno::Reference< sheet::XNamedRanges > xNamedRanges(  xProps->getPropertyValue(u"NamedRanges"_ustr), uno::UNO_QUERY_THROW );
    uno::Reference< XCollection > xNames( new ScVbaNames( this, mxContext, xNamedRanges, mxModel ) );
    if ( aIndex.hasValue() )
        return xNames->Item( aIndex, uno::Any() );
    return uno::Any( xNames );
}

uno::Any SAL_CALL
ScVbaWorksheet::OLEObjects( const uno::Any& Index )
{
    uno::Reference< sheet::XSpreadsheet > xSpreadsheet( getSheet(), uno::UNO_SET_THROW );
    uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( xSpreadsheet, uno::UNO_QUERY_THROW );
    uno::Reference< drawing::XDrawPage > xDrawPage( xDrawPageSupplier->getDrawPage(), uno::UNO_SET_THROW );
    uno::Reference< container::XIndexAccess > xIndexAccess( xDrawPage, uno::UNO_QUERY_THROW );

    uno::Reference< excel::XOLEObjects >xOleObjects( new ScVbaOLEObjects( this, mxContext, xIndexAccess ) );
    if( Index.hasValue() )
        return xOleObjects->Item( Index, uno::Any() );
    return uno::Any( xOleObjects );
}

uno::Any SAL_CALL
ScVbaWorksheet::Shapes( const uno::Any& aIndex )
{
    uno::Reference< sheet::XSpreadsheet > xSpreadsheet( getSheet(), uno::UNO_SET_THROW );
    uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( xSpreadsheet, uno::UNO_QUERY_THROW );
    uno::Reference< drawing::XShapes > xShapes( xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY_THROW );
    uno::Reference< container::XIndexAccess > xIndexAccess( xShapes, uno::UNO_QUERY_THROW );

    uno::Reference< msforms::XShapes> xVbaShapes( new ScVbaShapes( this, mxContext, xIndexAccess, getModel() ) );
    if ( aIndex.hasValue() )
        return xVbaShapes->Item( aIndex, uno::Any() );
    return uno::Any( xVbaShapes );
}

uno::Any
ScVbaWorksheet::getButtons( const uno::Any &rIndex, bool bOptionButtons )
{
    ::rtl::Reference< ScVbaSheetObjectsBase > &rxButtons = bOptionButtons ? mxButtons[0] : mxButtons[1];

    if( !rxButtons.is() )
        rxButtons.set( new ScVbaButtons( this, mxContext, mxModel, mxSheet, bOptionButtons ) );
    else
        rxButtons->collectShapes();
    if( rIndex.hasValue() )
        return rxButtons->Item( rIndex, uno::Any() );
    return uno::Any( uno::Reference< XCollection >( rxButtons ) );
}

uno::Any SAL_CALL
ScVbaWorksheet::Buttons( const uno::Any& rIndex )
{
    return getButtons( rIndex, false );
}

uno::Any SAL_CALL
ScVbaWorksheet::CheckBoxes( const uno::Any& /*rIndex*/ )
{
    throw uno::RuntimeException();
}

uno::Any SAL_CALL
ScVbaWorksheet::DropDowns( const uno::Any& /*rIndex*/ )
{
    throw uno::RuntimeException();
}

uno::Any SAL_CALL
ScVbaWorksheet::GroupBoxes( const uno::Any& /*rIndex*/ )
{
    throw uno::RuntimeException();
}

uno::Any SAL_CALL
ScVbaWorksheet::Labels( const uno::Any& /*rIndex*/ )
{
    throw uno::RuntimeException();
}

uno::Any SAL_CALL
ScVbaWorksheet::ListBoxes( const uno::Any& /*rIndex*/ )
{
    throw uno::RuntimeException();
}

uno::Any SAL_CALL
ScVbaWorksheet::OptionButtons( const uno::Any& rIndex )
{
    return getButtons( rIndex, true );
}

uno::Any SAL_CALL
ScVbaWorksheet::ScrollBars( const uno::Any& /*rIndex*/ )
{
    throw uno::RuntimeException();
}

uno::Any SAL_CALL
ScVbaWorksheet::Spinners( const uno::Any& /*rIndex*/ )
{
    throw uno::RuntimeException();
}

void SAL_CALL
ScVbaWorksheet::ShowDataForm( )
{
    uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_SET_THROW );
    if (ScTabViewShell* pTabViewShell = excel::getBestViewShell( xModel ))
    {
        ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
        ScopedVclPtr<AbstractScDataFormDlg> pDlg(pFact->CreateScDataFormDlg(pTabViewShell->GetFrameWeld(),
                                                                        pTabViewShell));
        pDlg->Execute();
    }
}

uno::Any SAL_CALL
ScVbaWorksheet::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( Range( uno::Any( Name ), aVoid ) );
}

uno::Reference< beans::XIntrospectionAccess > SAL_CALL
ScVbaWorksheet::getIntrospection(  )
{
    return uno::Reference< beans::XIntrospectionAccess >();
}

uno::Any SAL_CALL
ScVbaWorksheet::invoke( const OUString& /*aFunctionName*/, const uno::Sequence< uno::Any >& /*aParams*/, uno::Sequence< ::sal_Int16 >& /*aOutParamIndex*/, uno::Sequence< uno::Any >& /*aOutParam*/ )
{
    throw uno::RuntimeException(u"Unsupported"_ustr); // unsupported operation
}

void SAL_CALL
ScVbaWorksheet::setValue( const OUString& aPropertyName, const uno::Any& aValue )
{
    setDefaultPropByIntrospection( getValue( aPropertyName ), aValue );
}
uno::Any SAL_CALL
ScVbaWorksheet::getValue( const OUString& aPropertyName )
{
    uno::Reference< drawing::XControlShape > xControlShape( getControlShape( aPropertyName ), uno::UNO_QUERY_THROW );

    uno::Reference<lang::XMultiComponentFactory > xServiceManager( mxContext->getServiceManager(), uno::UNO_SET_THROW );
    uno::Reference< XControlProvider > xControlProvider( xServiceManager->createInstanceWithContext(u"ooo.vba.ControlProvider"_ustr, mxContext ), uno::UNO_QUERY_THROW );
    uno::Reference< msforms::XControl > xControl( xControlProvider->createControl(  xControlShape, getModel() ) );
    return uno::Any( xControl );
}

sal_Bool SAL_CALL
ScVbaWorksheet::hasMethod( const OUString& /*aName*/ )
{
    return false;
}

uno::Reference< container::XNameAccess >
ScVbaWorksheet::getFormControls() const
{
    uno::Reference< container::XNameAccess > xFormControls;
    try
    {
        uno::Reference< sheet::XSpreadsheet > xSpreadsheet( getSheet(), uno::UNO_SET_THROW );
        uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( xSpreadsheet, uno::UNO_QUERY_THROW );
        uno::Reference< form::XFormsSupplier >  xFormSupplier( xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY_THROW );
        uno::Reference< container::XIndexAccess > xIndexAccess( xFormSupplier->getForms(), uno::UNO_QUERY_THROW );
        // get the www-standard container ( maybe we should access the
        // 'www-standard' by name rather than index, this seems an
        // implementation detail
        if( xIndexAccess->hasElements() )
            xFormControls.set( xIndexAccess->getByIndex(0), uno::UNO_QUERY );

    }
    catch( uno::Exception& )
    {
    }
    return xFormControls;

                }
sal_Bool SAL_CALL
ScVbaWorksheet::hasProperty( const OUString& aName )
{
    uno::Reference< container::XNameAccess > xFormControls( getFormControls() );
    if ( xFormControls.is() )
        return xFormControls->hasByName( aName );
    return false;
}

uno::Any
ScVbaWorksheet::getControlShape( std::u16string_view sName )
{
    // ideally we would get an XControl object but it appears an XControl
    // implementation only exists for a Control implementation obtained from the
    // view ( e.g. in basic you would get this from
    // thiscomponent.currentcontroller.getControl( controlModel ) )
    // and the thing to realise is that it is only possible to get an XControl
    // for a currently displayed control :-( often we would want to modify
    // a control not on the active sheet. But... you can always access the
    // XControlShape from the DrawPage whether that is the active drawpage or not

    uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( getSheet(), uno::UNO_QUERY_THROW );
    uno::Reference< container::XIndexAccess > xIndexAccess( xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY_THROW );

    sal_Int32 nCount = xIndexAccess->getCount();
    forint index = 0; index < nCount; index++ )
    {
        uno::Any aUnoObj =  xIndexAccess->getByIndex( index );
         // It seems there are some drawing objects that can not query into Control shapes?
        uno::Reference< drawing::XControlShape > xControlShape( aUnoObj, uno::UNO_QUERY );
        if( xControlShape.is() )
        {
            uno::Reference< container::XNamed > xNamed( xControlShape->getControl(), uno::UNO_QUERY_THROW );
            if( sName == xNamed->getName() )
            {
                return aUnoObj;
            }
        }
    }
    return uno::Any();
}

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

void SAL_CALL
ScVbaWorksheet::setEnableCalculation( sal_Bool bEnableCalculation )
{
    uno::Reference <sheet::XCalculatable> xCalculatable(getModel(), uno::UNO_QUERY_THROW);
    xCalculatable->enableAutomaticCalculation( bEnableCalculation);
}
sal_Bool SAL_CALL
ScVbaWorksheet::getEnableCalculation(  )
{
    uno::Reference <sheet::XCalculatable> xCalculatable(getModel(), uno::UNO_QUERY_THROW);
    return xCalculatable->isAutomaticCalculationEnabled();
}

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

OUString SAL_CALL
ScVbaWorksheet::getCodeName()
{
    uno::Reference< beans::XPropertySet > xSheetProp( mxSheet, uno::UNO_QUERY_THROW );
    return xSheetProp->getPropertyValue(u"CodeName"_ustr).get< OUString >();
}

sal_Int16
ScVbaWorksheet::getSheetID() const
{
    uno::Reference< sheet::XCellRangeAddressable > xAddressable( mxSheet, uno::UNO_QUERY_THROW ); // if ActiveSheet, mxSheet is null.
    return xAddressable->getRangeAddress().Sheet;
}

void SAL_CALL
ScVbaWorksheet::PrintOut( const uno::Any& From, const uno::Any& To, const uno::Any& Copies, const uno::Any& Preview, const uno::Any& ActivePrinter, const uno::Any& PrintToFile, const uno::Any& Collate, const uno::Any& PrToFileName, const uno::Any& )
{
    sal_Int32 nTo = 0;
    sal_Int32 nFrom = 0;
    bool bSelection = false;
    From >>= nFrom;
    To >>= nTo;

    if ( !( nFrom || nTo ) )
        bSelection = true;

    uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_SET_THROW );
    PrintOutHelper( excel::getBestViewShell( xModel ), From, To, Copies, Preview, ActivePrinter, PrintToFile, Collate, PrToFileName, bSelection );
}

void SAL_CALL
ScVbaWorksheet::ExportAsFixedFormat(const css::uno::Any& Type, const css::uno::Any& FileName, const css::uno::Any& Quality,
    const css::uno::Any& IncludeDocProperties, const css::uno::Any& /*IgnorePrintAreas*/, const css::uno::Any& From,
    const css::uno::Any& To, const css::uno::Any& OpenAfterPublish, const css::uno::Any& /*FixedFormatExtClassPtr*/)
{
    uno::Reference< frame::XModel > xModel(getModel(), uno::UNO_SET_THROW);
    uno::Reference< excel::XApplication > xApplication(Application(), uno::UNO_QUERY_THROW);

    excel::ExportAsFixedFormatHelper(xModel, xApplication, Type, FileName, Quality,
        IncludeDocProperties, From, To, OpenAfterPublish);
}

sal_Int64 SAL_CALL
ScVbaWorksheet::getSomething(const uno::Sequence<sal_Int8 > & rId)
{
    return comphelper::getSomethingImpl(rId, this);
}

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

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

Messung V0.5
C=96 H=98 G=96

¤ Dauer der Verarbeitung: 0.11 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.