summaryrefslogtreecommitdiffstats
path: root/sc/source/ui/vba
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
commited5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch)
tree7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /sc/source/ui/vba
parentInitial commit. (diff)
downloadlibreoffice-upstream.tar.xz
libreoffice-upstream.zip
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sc/source/ui/vba')
-rw-r--r--sc/source/ui/vba/excelvbahelper.cxx399
-rw-r--r--sc/source/ui/vba/excelvbahelper.hxx97
-rw-r--r--sc/source/ui/vba/helperdecl.hxx47
-rw-r--r--sc/source/ui/vba/vbaapplication.cxx1566
-rw-r--r--sc/source/ui/vba/vbaapplication.hxx168
-rw-r--r--sc/source/ui/vba/vbaassistant.cxx116
-rw-r--r--sc/source/ui/vba/vbaassistant.hxx57
-rw-r--r--sc/source/ui/vba/vbaaxes.cxx211
-rw-r--r--sc/source/ui/vba/vbaaxes.hxx47
-rw-r--r--sc/source/ui/vba/vbaaxis.cxx656
-rw-r--r--sc/source/ui/vba/vbaaxis.hxx90
-rw-r--r--sc/source/ui/vba/vbaaxistitle.cxx44
-rw-r--r--sc/source/ui/vba/vbaaxistitle.hxx36
-rw-r--r--sc/source/ui/vba/vbaborders.cxx591
-rw-r--r--sc/source/ui/vba/vbaborders.hxx67
-rw-r--r--sc/source/ui/vba/vbacharacters.cxx134
-rw-r--r--sc/source/ui/vba/vbacharacters.hxx61
-rw-r--r--sc/source/ui/vba/vbachart.cxx1056
-rw-r--r--sc/source/ui/vba/vbachart.hxx103
-rw-r--r--sc/source/ui/vba/vbachartobject.cxx147
-rw-r--r--sc/source/ui/vba/vbachartobject.hxx61
-rw-r--r--sc/source/ui/vba/vbachartobjects.cxx206
-rw-r--r--sc/source/ui/vba/vbachartobjects.hxx60
-rw-r--r--sc/source/ui/vba/vbacharttitle.cxx44
-rw-r--r--sc/source/ui/vba/vbacharttitle.hxx35
-rw-r--r--sc/source/ui/vba/vbacomment.cxx234
-rw-r--r--sc/source/ui/vba/vbacomment.hxx72
-rw-r--r--sc/source/ui/vba/vbacomments.cxx113
-rw-r--r--sc/source/ui/vba/vbacomments.hxx49
-rw-r--r--sc/source/ui/vba/vbacondition.cxx143
-rw-r--r--sc/source/ui/vba/vbacondition.hxx48
-rw-r--r--sc/source/ui/vba/vbadialog.cxx85
-rw-r--r--sc/source/ui/vba/vbadialog.hxx40
-rw-r--r--sc/source/ui/vba/vbadialogs.cxx51
-rw-r--r--sc/source/ui/vba/vbadialogs.hxx43
-rw-r--r--sc/source/ui/vba/vbaeventshelper.cxx898
-rw-r--r--sc/source/ui/vba/vbaeventshelper.hxx84
-rw-r--r--sc/source/ui/vba/vbafiledialog.cxx174
-rw-r--r--sc/source/ui/vba/vbafiledialog.hxx58
-rw-r--r--sc/source/ui/vba/vbafiledialogitems.cxx123
-rw-r--r--sc/source/ui/vba/vbafiledialogitems.hxx43
-rw-r--r--sc/source/ui/vba/vbafont.cxx329
-rw-r--r--sc/source/ui/vba/vbafont.hxx76
-rw-r--r--sc/source/ui/vba/vbaformat.cxx814
-rw-r--r--sc/source/ui/vba/vbaformat.hxx154
-rw-r--r--sc/source/ui/vba/vbaformatcondition.cxx157
-rw-r--r--sc/source/ui/vba/vbaformatcondition.hxx67
-rw-r--r--sc/source/ui/vba/vbaformatconditions.cxx289
-rw-r--r--sc/source/ui/vba/vbaformatconditions.hxx66
-rw-r--r--sc/source/ui/vba/vbaglobals.cxx265
-rw-r--r--sc/source/ui/vba/vbaglobals.hxx82
-rw-r--r--sc/source/ui/vba/vbahyperlink.cxx236
-rw-r--r--sc/source/ui/vba/vbahyperlink.hxx86
-rw-r--r--sc/source/ui/vba/vbahyperlinks.cxx277
-rw-r--r--sc/source/ui/vba/vbahyperlinks.hxx136
-rw-r--r--sc/source/ui/vba/vbainterior.cxx413
-rw-r--r--sc/source/ui/vba/vbainterior.hxx83
-rw-r--r--sc/source/ui/vba/vbalineshape.cxx34
-rw-r--r--sc/source/ui/vba/vbalineshape.hxx34
-rw-r--r--sc/source/ui/vba/vbamenu.cxx67
-rw-r--r--sc/source/ui/vba/vbamenu.hxx37
-rw-r--r--sc/source/ui/vba/vbamenubar.cxx48
-rw-r--r--sc/source/ui/vba/vbamenubar.hxx33
-rw-r--r--sc/source/ui/vba/vbamenubars.cxx118
-rw-r--r--sc/source/ui/vba/vbamenubars.hxx40
-rw-r--r--sc/source/ui/vba/vbamenuitem.cxx64
-rw-r--r--sc/source/ui/vba/vbamenuitem.hxx38
-rw-r--r--sc/source/ui/vba/vbamenuitems.cxx138
-rw-r--r--sc/source/ui/vba/vbamenuitems.hxx42
-rw-r--r--sc/source/ui/vba/vbamenus.cxx124
-rw-r--r--sc/source/ui/vba/vbamenus.hxx42
-rw-r--r--sc/source/ui/vba/vbaname.cxx216
-rw-r--r--sc/source/ui/vba/vbaname.hxx69
-rw-r--r--sc/source/ui/vba/vbanames.cxx260
-rw-r--r--sc/source/ui/vba/vbanames.hxx69
-rw-r--r--sc/source/ui/vba/vbaoleobject.cxx150
-rw-r--r--sc/source/ui/vba/vbaoleobject.hxx57
-rw-r--r--sc/source/ui/vba/vbaoleobjects.cxx184
-rw-r--r--sc/source/ui/vba/vbaoleobjects.hxx47
-rw-r--r--sc/source/ui/vba/vbaoutline.cxx58
-rw-r--r--sc/source/ui/vba/vbaoutline.hxx43
-rw-r--r--sc/source/ui/vba/vbaovalshape.cxx34
-rw-r--r--sc/source/ui/vba/vbaovalshape.hxx34
-rw-r--r--sc/source/ui/vba/vbapagebreak.cxx142
-rw-r--r--sc/source/ui/vba/vbapagebreak.hxx87
-rw-r--r--sc/source/ui/vba/vbapagebreaks.cxx322
-rw-r--r--sc/source/ui/vba/vbapagebreaks.hxx83
-rw-r--r--sc/source/ui/vba/vbapagesetup.cxx631
-rw-r--r--sc/source/ui/vba/vbapagesetup.hxx90
-rw-r--r--sc/source/ui/vba/vbapalette.cxx115
-rw-r--r--sc/source/ui/vba/vbapalette.hxx44
-rw-r--r--sc/source/ui/vba/vbapane.cxx196
-rw-r--r--sc/source/ui/vba/vbapane.hxx55
-rw-r--r--sc/source/ui/vba/vbapivotcache.cxx50
-rw-r--r--sc/source/ui/vba/vbapivotcache.hxx40
-rw-r--r--sc/source/ui/vba/vbapivottable.cxx53
-rw-r--r--sc/source/ui/vba/vbapivottable.hxx40
-rw-r--r--sc/source/ui/vba/vbapivottables.cxx89
-rw-r--r--sc/source/ui/vba/vbapivottables.hxx49
-rw-r--r--sc/source/ui/vba/vbarange.cxx5720
-rw-r--r--sc/source/ui/vba/vbarange.hxx327
-rw-r--r--sc/source/ui/vba/vbasheetobject.cxx540
-rw-r--r--sc/source/ui/vba/vbasheetobject.hxx209
-rw-r--r--sc/source/ui/vba/vbasheetobjects.cxx555
-rw-r--r--sc/source/ui/vba/vbasheetobjects.hxx102
-rw-r--r--sc/source/ui/vba/vbastyle.cxx183
-rw-r--r--sc/source/ui/vba/vbastyle.hxx62
-rw-r--r--sc/source/ui/vba/vbastyles.cxx199
-rw-r--r--sc/source/ui/vba/vbastyles.hxx50
-rw-r--r--sc/source/ui/vba/vbatextboxshape.cxx60
-rw-r--r--sc/source/ui/vba/vbatextboxshape.hxx39
-rw-r--r--sc/source/ui/vba/vbatextframe.cxx67
-rw-r--r--sc/source/ui/vba/vbatextframe.hxx40
-rw-r--r--sc/source/ui/vba/vbatitle.hxx141
-rw-r--r--sc/source/ui/vba/vbavalidation.cxx382
-rw-r--r--sc/source/ui/vba/vbavalidation.hxx64
-rw-r--r--sc/source/ui/vba/vbawindow.cxx868
-rw-r--r--sc/source/ui/vba/vbawindow.hxx126
-rw-r--r--sc/source/ui/vba/vbawindows.cxx249
-rw-r--r--sc/source/ui/vba/vbawindows.hxx48
-rw-r--r--sc/source/ui/vba/vbaworkbook.cxx420
-rw-r--r--sc/source/ui/vba/vbaworkbook.hxx73
-rw-r--r--sc/source/ui/vba/vbaworkbooks.cxx291
-rw-r--r--sc/source/ui/vba/vbaworkbooks.hxx56
-rw-r--r--sc/source/ui/vba/vbaworksheet.cxx1052
-rw-r--r--sc/source/ui/vba/vbaworksheet.hxx167
-rw-r--r--sc/source/ui/vba/vbaworksheets.cxx535
-rw-r--r--sc/source/ui/vba/vbaworksheets.hxx68
-rw-r--r--sc/source/ui/vba/vbawsfunction.cxx298
-rw-r--r--sc/source/ui/vba/vbawsfunction.hxx45
130 files changed, 29089 insertions, 0 deletions
diff --git a/sc/source/ui/vba/excelvbahelper.cxx b/sc/source/ui/vba/excelvbahelper.cxx
new file mode 100644
index 000000000..317b06454
--- /dev/null
+++ b/sc/source/ui/vba/excelvbahelper.cxx
@@ -0,0 +1,399 @@
+/* -*- 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 "excelvbahelper.hxx"
+
+#include <basic/basmgr.hxx>
+#include <comphelper/processfactory.hxx>
+#include <vbahelper/vbahelper.hxx>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/sheet/XSheetCellRange.hpp>
+#include <com/sun/star/sheet/GlobalSheetSettings.hpp>
+#include <com/sun/star/sheet/XUnnamedDatabaseRanges.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XDatabaseRange.hpp>
+
+#include <document.hxx>
+#include <docuno.hxx>
+#include <tabvwsh.hxx>
+#include <transobj.hxx>
+#include <cellsuno.hxx>
+#include <gridwin.hxx>
+
+#include <com/sun/star/script/vba/VBAEventId.hpp>
+#include <com/sun/star/script/vba/XVBACompatibility.hpp>
+#include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
+#include <com/sun/star/script/vba/XVBAModuleInfo.hpp>
+#include <com/sun/star/script/ModuleInfo.hpp>
+#include <com/sun/star/script/ModuleType.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+namespace ooo::vba::excel {
+
+uno::Reference< sheet::XUnnamedDatabaseRanges >
+GetUnnamedDataBaseRanges( const ScDocShell* pShell )
+{
+ uno::Reference< frame::XModel > xModel;
+ if ( pShell )
+ xModel.set( pShell->GetModel(), uno::UNO_SET_THROW );
+ uno::Reference< beans::XPropertySet > xModelProps( xModel, uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XUnnamedDatabaseRanges > xUnnamedDBRanges( xModelProps->getPropertyValue("UnnamedDatabaseRanges"), uno::UNO_QUERY_THROW );
+ return xUnnamedDBRanges;
+}
+
+// returns the XDatabaseRange for the autofilter on sheet (nSheet)
+// also populates sName with the name of range
+uno::Reference< sheet::XDatabaseRange >
+GetAutoFiltRange( const ScDocShell* pShell, sal_Int16 nSheet )
+{
+ uno::Reference< sheet::XUnnamedDatabaseRanges > xUnnamedDBRanges( GetUnnamedDataBaseRanges( pShell ), uno::UNO_SET_THROW );
+ uno::Reference< sheet::XDatabaseRange > xDataBaseRange;
+ if (xUnnamedDBRanges->hasByTable( nSheet ) )
+ {
+ uno::Reference< sheet::XDatabaseRange > xDBRange( xUnnamedDBRanges->getByTable( nSheet ) , uno::UNO_QUERY_THROW );
+ bool bHasAuto = false;
+ uno::Reference< beans::XPropertySet > xProps( xDBRange, uno::UNO_QUERY_THROW );
+ xProps->getPropertyValue("AutoFilter") >>= bHasAuto;
+ if ( bHasAuto )
+ {
+ xDataBaseRange=xDBRange;
+ }
+ }
+ return xDataBaseRange;
+}
+
+ScDocShell* GetDocShellFromRange( const uno::Reference< uno::XInterface >& xRange )
+{
+ ScCellRangesBase* pScCellRangesBase = comphelper::getFromUnoTunnel<ScCellRangesBase>( xRange );
+ if ( !pScCellRangesBase )
+ {
+ throw uno::RuntimeException("Failed to access underlying doc shell uno range object" );
+ }
+ return pScCellRangesBase->GetDocShell();
+}
+
+uno::Reference< XHelperInterface >
+getUnoSheetModuleObj( const uno::Reference< table::XCellRange >& xRange )
+{
+ uno::Reference< sheet::XSheetCellRange > xSheetRange( xRange, uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XSpreadsheet > xSheet( xSheetRange->getSpreadsheet(), uno::UNO_SET_THROW );
+ return getUnoSheetModuleObj( xSheet );
+}
+
+void implSetZoom( const uno::Reference< frame::XModel >& xModel, sal_Int16 nZoom, std::vector< SCTAB >& nTabs )
+{
+ ScTabViewShell* pViewSh = excel::getBestViewShell( xModel );
+ Fraction aFract( nZoom, 100 );
+ pViewSh->GetViewData().SetZoom( aFract, aFract, nTabs );
+ pViewSh->RefreshZoom();
+}
+
+namespace {
+
+class PasteCellsWarningReseter
+{
+private:
+ bool bInitialWarningState;
+ /// @throws uno::RuntimeException
+ static uno::Reference< sheet::XGlobalSheetSettings > const & getGlobalSheetSettings()
+ {
+ static uno::Reference< sheet::XGlobalSheetSettings > xProps = sheet::GlobalSheetSettings::create( comphelper::getProcessComponentContext() );
+ return xProps;
+ }
+
+ /// @throws uno::RuntimeException
+ static bool getReplaceCellsWarning()
+ {
+ return getGlobalSheetSettings()->getReplaceCellsWarning();
+ }
+
+ /// @throws uno::RuntimeException
+ static void setReplaceCellsWarning( bool bState )
+ {
+ getGlobalSheetSettings()->setReplaceCellsWarning( bState );
+ }
+public:
+ /// @throws uno::RuntimeException
+ PasteCellsWarningReseter()
+ {
+ bInitialWarningState = getReplaceCellsWarning();
+ if ( bInitialWarningState )
+ setReplaceCellsWarning( false );
+ }
+ ~PasteCellsWarningReseter()
+ {
+ if ( bInitialWarningState )
+ {
+ // don't allow dtor to throw
+ try
+ {
+ setReplaceCellsWarning( true );
+ }
+ catch ( uno::Exception& /*e*/ ){}
+ }
+ }
+};
+
+}
+
+void
+implnPaste( const uno::Reference< frame::XModel>& xModel )
+{
+ PasteCellsWarningReseter resetWarningBox;
+ ScTabViewShell* pViewShell = getBestViewShell( xModel );
+ if ( pViewShell )
+ {
+ pViewShell->PasteFromSystem();
+ pViewShell->CellContentChanged();
+ }
+}
+
+void
+implnCopy( const uno::Reference< frame::XModel>& xModel )
+{
+ ScTabViewShell* pViewShell = getBestViewShell( xModel );
+ ScDocShell* pDocShell = getDocShell( xModel );
+ if ( !(pViewShell && pDocShell) )
+ return;
+
+ pViewShell->CopyToClip(nullptr,false,false,true);
+
+ // mark the copied transfer object so it is used in ScVbaRange::Insert
+ uno::Reference<datatransfer::XTransferable2> xTransferable(ScTabViewShell::GetClipData(pViewShell->GetViewData().GetActiveWin()));
+ ScTransferObj* pClipObj = ScTransferObj::GetOwnClipboard(xTransferable);
+ if (pClipObj)
+ {
+ pClipObj->SetUseInApi( true );
+ pDocShell->SetClipData(xTransferable);
+ }
+}
+
+void
+implnCut( const uno::Reference< frame::XModel>& xModel )
+{
+ ScTabViewShell* pViewShell = getBestViewShell( xModel );
+ ScDocShell* pDocShell = getDocShell( xModel );
+ if ( !(pViewShell && pDocShell) )
+ return;
+
+ pViewShell->CutToClip();
+
+ // mark the copied transfer object so it is used in ScVbaRange::Insert
+ uno::Reference<datatransfer::XTransferable2> xTransferable(ScTabViewShell::GetClipData(pViewShell->GetViewData().GetActiveWin()));
+ ScTransferObj* pClipObj = ScTransferObj::GetOwnClipboard(xTransferable);
+ if (pClipObj)
+ {
+ pClipObj->SetUseInApi( true );
+ pDocShell->SetClipData(xTransferable);
+ }
+}
+
+void implnPasteSpecial( const uno::Reference< frame::XModel>& xModel, InsertDeleteFlags nFlags, ScPasteFunc nFunction, bool bSkipEmpty, bool bTranspose)
+{
+ PasteCellsWarningReseter resetWarningBox;
+
+ ScTabViewShell* pTabViewShell = getBestViewShell(xModel);
+ if (!pTabViewShell)
+ return;
+
+ ScDocShell* pDocShell = getDocShell(xModel);
+ if (!pDocShell)
+ return;
+
+ ScViewData& rView = pTabViewShell->GetViewData();
+ vcl::Window* pWin = rView.GetActiveWin();
+ if (!pWin)
+ return;
+
+ const ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard(ScTabViewShell::GetClipData(pWin));
+ if (pOwnClip)
+ {
+ pTabViewShell->PasteFromClip(nFlags, pOwnClip->GetDocument(),
+ nFunction, bSkipEmpty, bTranspose, false,
+ INS_NONE, InsertDeleteFlags::NONE, true);
+
+ pTabViewShell->CellContentChanged();
+ }
+}
+
+ScDocShell*
+getDocShell( const css::uno::Reference< css::frame::XModel>& xModel )
+{
+ uno::Reference< uno::XInterface > xIf( xModel, uno::UNO_QUERY_THROW );
+ ScModelObj* pModel = dynamic_cast< ScModelObj* >( xIf.get() );
+ ScDocShell* pDocShell = nullptr;
+ if ( pModel )
+ pDocShell = static_cast<ScDocShell*>(pModel->GetEmbeddedObject());
+ return pDocShell;
+
+}
+
+ScTabViewShell*
+getBestViewShell( const css::uno::Reference< css::frame::XModel>& xModel )
+{
+ ScDocShell* pDocShell = getDocShell( xModel );
+ if ( pDocShell )
+ return pDocShell->GetBestViewShell();
+ return nullptr;
+}
+
+ScTabViewShell*
+getCurrentBestViewShell( const uno::Reference< uno::XComponentContext >& xContext )
+{
+ uno::Reference< frame::XModel > xModel = getCurrentExcelDoc( xContext );
+ return getBestViewShell( xModel );
+}
+
+SfxViewFrame*
+getViewFrame( const uno::Reference< frame::XModel >& xModel )
+{
+ ScTabViewShell* pViewShell = getBestViewShell( xModel );
+ if ( pViewShell )
+ return pViewShell->GetViewFrame();
+ return nullptr;
+}
+
+uno::Reference< XHelperInterface >
+getUnoSheetModuleObj( const uno::Reference< sheet::XSpreadsheet >& xSheet )
+{
+ uno::Reference< beans::XPropertySet > xProps( xSheet, uno::UNO_QUERY_THROW );
+ OUString sCodeName;
+ xProps->getPropertyValue("CodeName") >>= sCodeName;
+ // #TODO #FIXME ideally we should 'throw' here if we don't get a valid parent, but... it is possible
+ // to create a module ( and use 'Option VBASupport 1' ) for a calc document, in this scenario there
+ // are *NO* special document module objects ( of course being able to switch between vba/non vba mode at
+ // the document in the future could fix this, especially IF the switching of the vba mode takes care to
+ // create the special document module objects if they don't exist.
+ return getUnoDocModule( sCodeName, GetDocShellFromRange( xSheet ) );
+}
+
+uno::Reference< XHelperInterface >
+getUnoSheetModuleObj( const uno::Reference< sheet::XSheetCellRangeContainer >& xRanges )
+{
+ uno::Reference< container::XEnumerationAccess > xEnumAccess( xRanges, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XEnumeration > xEnum = xEnumAccess->createEnumeration();
+ uno::Reference< table::XCellRange > xRange( xEnum->nextElement(), uno::UNO_QUERY_THROW );
+ return getUnoSheetModuleObj( xRange );
+}
+
+uno::Reference< XHelperInterface >
+getUnoSheetModuleObj( const uno::Reference< table::XCell >& xCell )
+{
+ uno::Reference< sheet::XSheetCellRange > xSheetRange( xCell, uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XSpreadsheet > xSheet( xSheetRange->getSpreadsheet(), uno::UNO_SET_THROW );
+ return getUnoSheetModuleObj( xSheet );
+}
+
+uno::Reference< XHelperInterface >
+getUnoSheetModuleObj( const uno::Reference< frame::XModel >& xModel, SCTAB nTab )
+{
+ uno::Reference< sheet::XSpreadsheetDocument > xDoc( xModel, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xSheets( xDoc->getSheets(), uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XSpreadsheet > xSheet( xSheets->getByIndex( nTab ), uno::UNO_QUERY_THROW );
+ return getUnoSheetModuleObj( xSheet );
+}
+
+void setUpDocumentModules( const uno::Reference< sheet::XSpreadsheetDocument >& xDoc )
+{
+ uno::Reference< frame::XModel > xModel( xDoc, uno::UNO_QUERY );
+ ScDocShell* pShell = excel::getDocShell( xModel );
+ if ( !pShell )
+ return;
+
+ OUString aPrjName( "Standard" );
+ pShell->GetBasicManager()->SetName( aPrjName );
+
+ /* Set library container to VBA compatibility mode. This will create
+ the VBA Globals object and store it in the Basic manager of the
+ document. */
+ uno::Reference<script::XLibraryContainer> xLibContainer = pShell->GetBasicContainer();
+ uno::Reference<script::vba::XVBACompatibility> xVBACompat( xLibContainer, uno::UNO_QUERY_THROW );
+ xVBACompat->setVBACompatibilityMode( true );
+
+ if( xLibContainer.is() )
+ {
+ if( !xLibContainer->hasByName( aPrjName ) )
+ xLibContainer->createLibrary( aPrjName );
+ uno::Any aLibAny = xLibContainer->getByName( aPrjName );
+ uno::Reference< container::XNameContainer > xLib;
+ aLibAny >>= xLib;
+ if( xLib.is() )
+ {
+ uno::Reference< script::vba::XVBAModuleInfo > xVBAModuleInfo( xLib, uno::UNO_QUERY_THROW );
+ uno::Reference< lang::XMultiServiceFactory> xSF( pShell->GetModel(), uno::UNO_QUERY_THROW);
+ uno::Reference< container::XNameAccess > xVBACodeNamedObjectAccess( xSF->createInstance("ooo.vba.VBAObjectModuleObjectProvider"), uno::UNO_QUERY_THROW );
+ // set up the module info for the workbook and sheets in the newly created
+ // spreadsheet
+ ScDocument& rDoc = pShell->GetDocument();
+ OUString sCodeName = rDoc.GetCodeName();
+ if ( sCodeName.isEmpty() )
+ {
+ sCodeName = "ThisWorkbook";
+ rDoc.SetCodeName( sCodeName );
+ }
+
+ std::vector< OUString > sDocModuleNames { sCodeName };
+
+ for ( SCTAB index = 0; index < rDoc.GetTableCount(); index++)
+ {
+ OUString aName;
+ rDoc.GetCodeName( index, aName );
+ sDocModuleNames.push_back( aName );
+ }
+
+ for ( const auto& rName : sDocModuleNames )
+ {
+ script::ModuleInfo sModuleInfo;
+
+ uno::Any aName= xVBACodeNamedObjectAccess->getByName( rName );
+ sModuleInfo.ModuleObject.set( aName, uno::UNO_QUERY );
+ sModuleInfo.ModuleType = script::ModuleType::DOCUMENT;
+ xVBAModuleInfo->insertModuleInfo( rName, sModuleInfo );
+ if( xLib->hasByName( rName ) )
+ xLib->replaceByName( rName, uno::Any( OUString( "Option VBASupport 1\n") ) );
+ else
+ xLib->insertByName( rName, uno::Any( OUString( "Option VBASupport 1\n" ) ) );
+ }
+ }
+ }
+
+ /* Trigger the Workbook_Open event, event processor will register
+ itself as listener for specific events. */
+ try
+ {
+ uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( pShell->GetDocument().GetVbaEventProcessor(), uno::UNO_SET_THROW );
+ uno::Sequence< uno::Any > aArgs;
+ xVbaEvents->processVbaEvent( script::vba::VBAEventId::WORKBOOK_OPEN, aArgs );
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+SfxItemSet*
+ScVbaCellRangeAccess::GetDataSet( ScCellRangesBase* pRangeObj )
+{
+ return pRangeObj ? pRangeObj->GetCurrentDataSet( true ) : nullptr;
+}
+
+} // namespace ooo::vba::excel
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/excelvbahelper.hxx b/sc/source/ui/vba/excelvbahelper.hxx
new file mode 100644
index 000000000..0b72481e3
--- /dev/null
+++ b/sc/source/ui/vba/excelvbahelper.hxx
@@ -0,0 +1,97 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <sal/config.h>
+
+#include <comphelper/servicehelper.hxx>
+
+#include <vector>
+#include <global.hxx>
+
+namespace com::sun::star::frame { class XModel; }
+namespace com::sun::star::uno { class XComponentContext; }
+
+namespace com::sun::star::sheet { class XDatabaseRange; }
+namespace com::sun::star::sheet { class XUnnamedDatabaseRanges; }
+namespace com::sun::star::table { class XCell; }
+namespace com::sun::star::table { class XCellRange; }
+namespace com::sun::star::sheet { class XSheetCellRangeContainer; }
+namespace com::sun::star::sheet { class XSpreadsheet; }
+namespace com::sun::star::sheet { class XSpreadsheetDocument; }
+namespace ooo::vba { class XHelperInterface; }
+
+class ScCellRangesBase;
+class ScTabViewShell;
+class SfxViewFrame;
+
+namespace ooo::vba::excel {
+
+// nTabs empty means apply zoom to all sheets
+void implSetZoom( const css::uno::Reference< css::frame::XModel >& xModel, sal_Int16 nZoom, std::vector< SCTAB >& nTabs );
+void implnCopy( const css::uno::Reference< css::frame::XModel>& xModel );
+void implnPaste ( const css::uno::Reference< css::frame::XModel>& xModel );
+void implnCut( const css::uno::Reference< css::frame::XModel>& xModel );
+void implnPasteSpecial( const css::uno::Reference< css::frame::XModel>& xModel, InsertDeleteFlags nFlags, ScPasteFunc nFunction, bool bSkipEmpty, bool bTranspose);
+ScTabViewShell* getBestViewShell( const css::uno::Reference< css::frame::XModel>& xModel ) ;
+ScDocShell* getDocShell( const css::uno::Reference< css::frame::XModel>& xModel ) ;
+ScTabViewShell* getCurrentBestViewShell( const css::uno::Reference< css::uno::XComponentContext >& xContext );
+SfxViewFrame* getViewFrame( const css::uno::Reference< css::frame::XModel >& xModel );
+
+/// @throws css::uno::RuntimeException
+css::uno::Reference< css::sheet::XUnnamedDatabaseRanges > GetUnnamedDataBaseRanges( const ScDocShell* pShell );
+
+/// @throws css::uno::RuntimeException
+css::uno::Reference< css::sheet::XDatabaseRange > GetAutoFiltRange( const ScDocShell* pShell, sal_Int16 nSheet );
+/// @throws css::uno::RuntimeException
+css::uno::Reference< ooo::vba::XHelperInterface > getUnoSheetModuleObj( const css::uno::Reference< css::sheet::XSpreadsheet >& xSheet );
+/// @throws css::uno::RuntimeException
+css::uno::Reference< ooo::vba::XHelperInterface > getUnoSheetModuleObj( const css::uno::Reference< css::sheet::XSheetCellRangeContainer >& xRanges );
+/// @throws css::uno::RuntimeException
+css::uno::Reference< ooo::vba::XHelperInterface > getUnoSheetModuleObj( const css::uno::Reference< css::table::XCellRange >& xRange );
+/// @throws css::uno::RuntimeException
+css::uno::Reference< ooo::vba::XHelperInterface > getUnoSheetModuleObj( const css::uno::Reference< css::table::XCell >& xCell );
+/// @throws css::uno::RuntimeException
+css::uno::Reference< ooo::vba::XHelperInterface > getUnoSheetModuleObj( const css::uno::Reference< css::frame::XModel >& xModel, SCTAB nTab );
+
+/// @throws css::uno::RuntimeException
+ScDocShell* GetDocShellFromRange( const css::uno::Reference< css::uno::XInterface >& xRange );
+void setUpDocumentModules( const css::uno::Reference< css::sheet::XSpreadsheetDocument >& xDoc );
+
+class ScVbaCellRangeAccess
+{
+public:
+ static SfxItemSet* GetDataSet( ScCellRangesBase* pRangeObj );
+};
+
+// Extracts an implementation object (via XUnoTunnel) from a UNO object.
+// Will throw if unsuccessful.
+/// @throws css::uno::RuntimeException
+template < typename ImplObject >
+ ImplObject* getImplFromDocModuleWrapper( const css::uno::Reference< css::uno::XInterface >& rxWrapperIf )
+ {
+ ImplObject* pObj = comphelper::getFromUnoTunnel<ImplObject>(rxWrapperIf);
+ if ( !pObj )
+ throw css::uno::RuntimeException("Internal error, can't extract implementation object", rxWrapperIf );
+ return pObj;
+ }
+
+} // namespace ooo::vba::excel
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/helperdecl.hxx b/sc/source/ui/vba/helperdecl.hxx
new file mode 100644
index 000000000..b1163047e
--- /dev/null
+++ b/sc/source/ui/vba/helperdecl.hxx
@@ -0,0 +1,47 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <comphelper/servicedecl.hxx>
+
+namespace comphelper::service_decl {
+template <typename ImplT_, typename WithArgsT = with_args<false> >
+struct vba_service_class_ : public serviceimpl_base< detail::OwnServiceImpl<ImplT_>, WithArgsT >
+{
+ typedef serviceimpl_base< detail::OwnServiceImpl<ImplT_>, WithArgsT > baseT;
+ /** Default ctor. Implementation class without args, expecting
+ component context as single argument.
+ */
+ vba_service_class_() : baseT() {}
+ template <typename PostProcessFuncT>
+ /** Ctor to pass a post processing function/functor.
+
+ @tpl PostProcessDefaultT let your compiler deduce this
+ @param postProcessFunc function/functor that gets the yet unacquired
+ ImplT_ pointer returning a
+ uno::Reference<uno::XInterface>
+ */
+ explicit vba_service_class_( PostProcessFuncT const& postProcessFunc ) : baseT( postProcessFunc ) {}
+};
+
+} // namespace service_decl
+} // namespace comphelper
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaapplication.cxx b/sc/source/ui/vba/vbaapplication.cxx
new file mode 100644
index 000000000..2fda7fa86
--- /dev/null
+++ b/sc/source/ui/vba/vbaapplication.cxx
@@ -0,0 +1,1566 @@
+/* -*- 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 <tools/diagnose_ex.h>
+
+#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 <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
+ SC_MOD()->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( "failed to obtain current selection" );
+ }
+
+ 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("com.sun.star.drawing.Text") )
+ {
+ 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("com.sun.star.sheet.SheetCellRange") ||
+ xServiceInfo->supportsService("com.sun.star.sheet.SheetCellRanges") )
+ {
+ 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("No ViewShell available" );
+ 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("Unexpected XFileDialogSelectedItems implementation");
+
+ 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("Invalid parameter. It should be a string or False" );
+}
+
+::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( "WaitUntil", 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(
+ "NamedRanges" ), uno::UNO_QUERY_THROW );
+
+ css::uno::Reference< excel::XNames > xNames ( new ScVbaNames( this , mxContext , xNamedRanges , xModel ) );
+ if ( aIndex.getValueTypeClass() == uno::TypeClass_VOID )
+ {
+ return uno::Any( xNames );
+ }
+ return 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 = xWorksheet;
+ }
+ }
+
+ if ( !result.is() )
+ {
+ // Fixme - check if this is reasonable/desired behavior
+ throw uno::RuntimeException("No activeSheet available" );
+ }
+ 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::GoTo( const 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("second parameter should be boolean" );
+
+ bScroll = aScroll;
+
+ }
+
+ OUString sRangeName;
+ if( Reference >>= sRangeName )
+ {
+ uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW );
+ uno::Reference< sheet::XSpreadsheetView > xSpreadsheet(
+ xModel->getCurrentController(), uno::UNO_QUERY_THROW );
+
+ ScTabViewShell* pShell = excel::getCurrentBestViewShell( mxContext );
+ 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("invalid reference for range name, it should be procedure name" );
+ }
+ return;
+ }
+ uno::Reference< excel::XRange > xRange;
+ if( Reference >>= xRange )
+ {
+ uno::Reference< excel::XRange > xVbaRange( Reference, uno::UNO_QUERY );
+ ScTabViewShell* pShell = excel::getCurrentBestViewShell( mxContext );
+ ScGridWindow* gridWindow = 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("invalid reference or name" );
+}
+
+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("Unknown value for Cursor pointer" );
+ // 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 "Microsoft Excel";
+}
+
+// #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(), ".uno:FullScreen" );
+}
+
+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("HasVerticalScrollBar", uno::Any( bSet ) );
+ xProps->setPropertyValue("HasHorizontalScrollBar", 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 SC_MOD()->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( "com.sun.star.frame.Desktop" , 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( "com.sun.star.sheet.SpreadsheetDocument" ) )
+ {
+ uno::Reference< beans::XPropertySet > xProps( xServiceInfo, uno::UNO_QUERY );
+ if ( xProps.is() )
+ xProps->setPropertyValue( SC_UNO_ITERENABLED, uno::Any( bSet ) );
+ }
+ }
+ ScDocOptions aOpts( SC_MOD()->GetDocOptions() );
+ aOpts.SetIter( bSet );
+ SC_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( "Work");
+}
+
+OUString SAL_CALL
+ScVbaApplication::getLibraryPath()
+{
+ return getOfficePath( "Basic");
+}
+
+OUString SAL_CALL
+ScVbaApplication::getTemplatesPath()
+{
+ return getOfficePath( "Template");
+}
+
+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 "Unix";
+#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
+ for( const auto& rOuterItem : aList1 )
+ {
+ for( const 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;
+ for( const 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
+ScVbaApplication::InchesToPoints( double Inches )
+{
+ double result = Inches * 72.0;
+ return result;
+}
+
+void
+ScVbaApplication::Volatile( const uno::Any& aVolatile )
+{
+ bool bVolatile = true;
+ aVolatile >>= bVolatile;
+ SbMethod* pMeth = StarBASIC::GetActiveMethod();
+ if ( pMeth )
+ {
+ uno::Reference< frame::XModel > xModel( getCurrentDocument() );
+ ScDocument& rDoc = excel::getDocShell( xModel )->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( "FuncCaller", 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 );
+ 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 "{82154425-0FBF-11d4-8313-005004526AB4}";
+}
+
+// XConnectable
+
+OUString SAL_CALL
+ScVbaApplication::GetIIDForClassItselfNotCoclass()
+{
+ return "{82154426-0FBF-11D4-8313-005004526AB4}";
+}
+
+TypeAndIID SAL_CALL
+ScVbaApplication::GetConnectionPoint()
+{
+ TypeAndIID aResult =
+ { excel::XApplicationOutgoing::static_type(),
+ "{82154427-0FBF-11D4-8313-005004526AB4}"
+ };
+
+ 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 "ScVbaApplication";
+}
+
+uno::Sequence< OUString >
+ScVbaApplication::getServiceNames()
+{
+ static uno::Sequence< OUString > aServiceNames
+ {
+ "ooo.vba.excel.Application"
+ };
+ 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: */
diff --git a/sc/source/ui/vba/vbaapplication.hxx b/sc/source/ui/vba/vbaapplication.hxx
new file mode 100644
index 000000000..db9c91cdd
--- /dev/null
+++ b/sc/source/ui/vba/vbaapplication.hxx
@@ -0,0 +1,168 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <vector>
+
+#include <ooo/vba/XSinkCaller.hpp>
+#include <ooo/vba/excel/XApplication.hpp>
+
+#include <vbahelper/vbaapplicationbase.hxx>
+#include <cppuhelper/implbase.hxx>
+
+namespace com::sun::star::uno { class XComponentContext; }
+namespace ooo::vba { class XSink; }
+namespace ooo::vba::excel { class XFileDialog; }
+
+typedef cppu::ImplInheritanceHelper< VbaApplicationBase, ov::excel::XApplication, ov::XSinkCaller > ScVbaApplication_BASE;
+
+struct ScVbaAppSettings;
+
+class ScVbaApplication : public ScVbaApplication_BASE
+{
+private:
+ // note: member variables moved to struct "ScVbaAppSettings", see cxx file, to be shared by all application instances
+ ScVbaAppSettings& mrAppSettings;
+
+ // must be stored in order to get result paths from the same instance
+ css::uno::Reference< ov::excel::XFileDialog > m_xFileDialog;
+ sal_Int32 m_nDialogType;
+
+ /// @throws css::uno::RuntimeException
+ OUString getOfficePath( const OUString& sPath );
+
+ std::vector<css::uno::Reference< ooo::vba::XSink >> mvSinks;
+
+protected:
+ virtual css::uno::Reference< css::frame::XModel > getCurrentDocument() override;
+
+public:
+ explicit ScVbaApplication( const css::uno::Reference< css::uno::XComponentContext >& m_xContext );
+ virtual ~ScVbaApplication() override;
+
+ /** Returns true, if VBA document events are enabled. */
+ static bool getDocumentEventsEnabled();
+
+ sal_uInt32 AddSink( const css::uno::Reference< ooo::vba::XSink >& xSink );
+ void RemoveSink( sal_uInt32 nNumber );
+
+ // XExactName
+ virtual OUString SAL_CALL getExactName( const OUString& aApproximateName ) override;
+
+ // XInvocation
+ virtual css::uno::Reference< css::beans::XIntrospectionAccess > SAL_CALL getIntrospection() override;
+ virtual css::uno::Any SAL_CALL invoke(const OUString& FunctionName, const css::uno::Sequence< css::uno::Any >& Params, css::uno::Sequence< sal_Int16 >& OutParamIndex, css::uno::Sequence< css::uno::Any >& OutParam) override;
+ virtual void SAL_CALL setValue(const OUString& PropertyName, const css::uno::Any& Value) override;
+ virtual css::uno::Any SAL_CALL getValue(const OUString& PropertyName) override;
+ virtual sal_Bool SAL_CALL hasMethod(const OUString& Name) override;
+ virtual sal_Bool SAL_CALL hasProperty(const OUString& Name) override;
+
+ // XApplication
+ virtual void SAL_CALL setDefaultFilePath( const OUString& DefaultFilePath ) override;
+ virtual OUString SAL_CALL getDefaultFilePath() override;
+ virtual OUString SAL_CALL getPathSeparator() override;
+ virtual OUString SAL_CALL getLibraryPath() override;
+ virtual OUString SAL_CALL getTemplatesPath() override;
+ virtual OUString SAL_CALL getOperatingSystem() override;
+
+ virtual OUString SAL_CALL getName() override;
+ virtual sal_Bool SAL_CALL getDisplayAlerts() override;
+ virtual void SAL_CALL setDisplayAlerts( sal_Bool displayAlerts ) override;
+ virtual ::sal_Int32 SAL_CALL getCalculation() override;
+ virtual void SAL_CALL setCalculation( ::sal_Int32 _calculation ) override;
+ virtual css::uno::Any SAL_CALL getSelection() override;
+ virtual css::uno::Reference< ov::excel::XWorkbook > SAL_CALL getActiveWorkbook() override;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL getActiveCell() override;
+ virtual css::uno::Reference< ov::excel::XWindow > SAL_CALL getActiveWindow() override;
+ virtual css::uno::Reference< ov::excel::XWorksheet > SAL_CALL getActiveSheet() override;
+ virtual sal_Bool SAL_CALL getDisplayFormulaBar() override;
+ virtual void SAL_CALL setDisplayFormulaBar(sal_Bool _displayformulabar) override;
+
+ virtual css::uno::Reference< ov::XAssistant > SAL_CALL getAssistant() override;
+ virtual css::uno::Reference< ov::excel::XWorkbook > SAL_CALL getThisWorkbook() override;
+
+ virtual css::uno::Any SAL_CALL GetOpenFilename(const css::uno::Any& FileFilter, const css::uno::Any& FilterIndex, const css::uno::Any& Title, const css::uno::Any& ButtonText, const css::uno::Any& MultiSelect) override;
+ virtual css::uno::Any SAL_CALL International( sal_Int32 Index ) override;
+ virtual css::uno::Any SAL_CALL FileDialog( const css::uno::Any& DialogType ) override;
+ virtual css::uno::Any SAL_CALL Workbooks( const css::uno::Any& aIndex ) override;
+ virtual css::uno::Any SAL_CALL Worksheets( const css::uno::Any& aIndex ) override;
+ virtual css::uno::Any SAL_CALL WorksheetFunction( ) override;
+ virtual css::uno::Any SAL_CALL Evaluate( const OUString& Name ) override;
+ virtual css::uno::Any SAL_CALL Dialogs( const css::uno::Any& DialogIndex ) override;
+ virtual css::uno::Any SAL_CALL getCutCopyMode() override;
+ virtual void SAL_CALL setCutCopyMode( const css::uno::Any& _cutcopymode ) override;
+ virtual css::uno::Any SAL_CALL getStatusBar() override;
+ virtual void SAL_CALL setStatusBar( const css::uno::Any& _statusbar ) override;
+ virtual css::uno::Any SAL_CALL getWindowState() override;
+ virtual void SAL_CALL setWindowState(const css::uno::Any& rWindowState) override;
+ virtual ::sal_Int32 SAL_CALL getCursor() override;
+ virtual void SAL_CALL setCursor( ::sal_Int32 _cursor ) override;
+ virtual void SAL_CALL OnKey( const OUString& Key, const css::uno::Any& Procedure ) override;
+ virtual void SAL_CALL setScreenUpdating( sal_Bool bUpdate ) override;
+ virtual sal_Bool SAL_CALL getEnableEvents() override;
+ virtual void SAL_CALL setEnableEvents( sal_Bool bEnable ) override;
+ virtual sal_Bool SAL_CALL getEnableCancelKey() override;
+ virtual void SAL_CALL setEnableCancelKey( sal_Bool bEnable ) override;
+
+ virtual sal_Bool SAL_CALL getDisplayFullScreen() override;
+ virtual void SAL_CALL setDisplayFullScreen( sal_Bool bSet ) override;
+ virtual sal_Bool SAL_CALL getDisplayScrollBars() override;
+ virtual void SAL_CALL setDisplayScrollBars( sal_Bool bSet ) override;
+ virtual sal_Bool SAL_CALL getDisplayExcel4Menus() override;
+ virtual void SAL_CALL setDisplayExcel4Menus( sal_Bool bSet ) override;
+
+ virtual sal_Bool SAL_CALL getDisplayNoteIndicator() override;
+ virtual void SAL_CALL setDisplayNoteIndicator( sal_Bool bSet ) override;
+ virtual sal_Bool SAL_CALL getShowWindowsInTaskbar() override;
+ virtual void SAL_CALL setShowWindowsInTaskbar( sal_Bool bSet ) override;
+ virtual sal_Bool SAL_CALL getIteration() override;
+ virtual void SAL_CALL setIteration( sal_Bool bSet ) override;
+
+ virtual css::uno::Any SAL_CALL Windows( const css::uno::Any& aIndex ) override;
+ virtual void SAL_CALL wait( double time ) override;
+ virtual css::uno::Any SAL_CALL Range( const css::uno::Any& Cell1, const css::uno::Any& Cell2 ) override;
+ virtual css::uno::Any SAL_CALL Names( const css::uno::Any& aIndex ) override;
+ virtual void SAL_CALL GoTo( const css::uno::Any& Reference, const css::uno::Any& Scroll ) override;
+ virtual void SAL_CALL Calculate() override;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Intersect( const css::uno::Reference< ov::excel::XRange >& Arg1, const css::uno::Reference< ov::excel::XRange >& Arg2, const css::uno::Any& Arg3, const css::uno::Any& Arg4, const css::uno::Any& Arg5, const css::uno::Any& Arg6, const css::uno::Any& Arg7, const css::uno::Any& Arg8, const css::uno::Any& Arg9, const css::uno::Any& Arg10, const css::uno::Any& Arg11, const css::uno::Any& Arg12, const css::uno::Any& Arg13, const css::uno::Any& Arg14, const css::uno::Any& Arg15, const css::uno::Any& Arg16, const css::uno::Any& Arg17, const css::uno::Any& Arg18, const css::uno::Any& Arg19, const css::uno::Any& Arg20, const css::uno::Any& Arg21, const css::uno::Any& Arg22, const css::uno::Any& Arg23, const css::uno::Any& Arg24, const css::uno::Any& Arg25, const css::uno::Any& Arg26, const css::uno::Any& Arg27, const css::uno::Any& Arg28, const css::uno::Any& Arg29, const css::uno::Any& Arg30 ) override;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Union( const css::uno::Reference< ov::excel::XRange >& Arg1, const css::uno::Reference< ov::excel::XRange >& Arg2, const css::uno::Any& Arg3, const css::uno::Any& Arg4, const css::uno::Any& Arg5, const css::uno::Any& Arg6, const css::uno::Any& Arg7, const css::uno::Any& Arg8, const css::uno::Any& Arg9, const css::uno::Any& Arg10, const css::uno::Any& Arg11, const css::uno::Any& Arg12, const css::uno::Any& Arg13, const css::uno::Any& Arg14, const css::uno::Any& Arg15, const css::uno::Any& Arg16, const css::uno::Any& Arg17, const css::uno::Any& Arg18, const css::uno::Any& Arg19, const css::uno::Any& Arg20, const css::uno::Any& Arg21, const css::uno::Any& Arg22, const css::uno::Any& Arg23, const css::uno::Any& Arg24, const css::uno::Any& Arg25, const css::uno::Any& Arg26, const css::uno::Any& Arg27, const css::uno::Any& Arg28, const css::uno::Any& Arg29, const css::uno::Any& Arg30 ) override;
+ virtual double SAL_CALL InchesToPoints( double InchesToPoints ) override;
+ virtual void SAL_CALL Volatile( const css::uno::Any& Volatile ) override;
+ virtual css::uno::Any SAL_CALL MenuBars( const css::uno::Any& aIndex ) override;
+ virtual css::uno::Any SAL_CALL Rows( const css::uno::Any& aIndex ) override;
+ virtual css::uno::Any SAL_CALL Caller( const css::uno::Any& aIndex ) override;
+ virtual void SAL_CALL Undo() override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+
+ // XInterfaceWithIID
+ virtual OUString SAL_CALL getIID() override;
+
+ // XConnectable
+ virtual OUString SAL_CALL GetIIDForClassItselfNotCoclass() override;
+ virtual ov::TypeAndIID SAL_CALL GetConnectionPoint() override;
+ virtual css::uno::Reference<ov::XConnectionPoint> SAL_CALL FindConnectionPoint() override;
+
+ // XSinkCaller
+ virtual void SAL_CALL CallSinks( const OUString& Method, css::uno::Sequence< css::uno::Any >& Arguments ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaassistant.cxx b/sc/source/ui/vba/vbaassistant.cxx
new file mode 100644
index 000000000..ea13fbcd6
--- /dev/null
+++ b/sc/source/ui/vba/vbaassistant.cxx
@@ -0,0 +1,116 @@
+/* -*- 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 <ooo/vba/office/MsoAnimationType.hpp>
+
+#include"vbaassistant.hxx"
+
+using namespace com::sun::star;
+using namespace ooo::vba;
+
+using namespace ooo::vba::office::MsoAnimationType;
+
+constexpr OUStringLiteral g_sName = u"Clippit";
+
+ScVbaAssistant::ScVbaAssistant( const uno::Reference< XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext ): ScVbaAssistantImpl_BASE(rParent, rContext)
+{
+ m_bIsVisible = false;
+ m_nPointsLeft = 795;
+ m_nPointsTop = 248;
+ m_nAnimation = msoAnimationIdle;
+}
+
+ScVbaAssistant::~ScVbaAssistant()
+{
+}
+
+sal_Bool SAL_CALL ScVbaAssistant::getVisible()
+{
+ return m_bIsVisible;
+}
+
+void SAL_CALL ScVbaAssistant::setVisible( sal_Bool bVisible )
+{
+ m_bIsVisible = bVisible;
+}
+
+sal_Bool SAL_CALL ScVbaAssistant::getOn()
+{
+ return false;
+}
+
+void SAL_CALL ScVbaAssistant::setOn( sal_Bool bOn )
+{
+ setVisible( bOn );
+}
+
+::sal_Int32 SAL_CALL
+ScVbaAssistant::getTop()
+{
+ return m_nPointsTop;
+}
+void SAL_CALL
+ScVbaAssistant::setTop( ::sal_Int32 _top )
+{
+ m_nPointsTop = _top;
+}
+::sal_Int32 SAL_CALL
+ScVbaAssistant::getLeft()
+{
+ return m_nPointsLeft;
+}
+void SAL_CALL
+ScVbaAssistant::setLeft( ::sal_Int32 _left )
+{
+ m_nPointsLeft = _left;
+}
+::sal_Int32 SAL_CALL
+ScVbaAssistant::getAnimation()
+{
+ return m_nAnimation;
+}
+void SAL_CALL
+ScVbaAssistant::setAnimation( ::sal_Int32 _animation )
+{
+ m_nAnimation = _animation;
+}
+
+OUString SAL_CALL
+ScVbaAssistant::Name( )
+{
+ return g_sName;
+}
+
+OUString
+ScVbaAssistant::getServiceImplName()
+{
+ return "ScVbaAssistant";
+}
+
+uno::Sequence< OUString >
+ScVbaAssistant::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.Assistant"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaassistant.hxx b/sc/source/ui/vba/vbaassistant.hxx
new file mode 100644
index 000000000..674e64445
--- /dev/null
+++ b/sc/source/ui/vba/vbaassistant.hxx
@@ -0,0 +1,57 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <cppuhelper/implbase.hxx>
+#include <ooo/vba/XAssistant.hpp>
+
+#include <vbahelper/vbahelperinterface.hxx>
+
+typedef ::cppu::WeakImplHelper< ov::XAssistant > Assistant;
+typedef InheritedHelperInterfaceImpl< Assistant > ScVbaAssistantImpl_BASE;
+
+class ScVbaAssistant : public ScVbaAssistantImpl_BASE
+{
+private:
+ bool m_bIsVisible;
+ sal_Int32 m_nPointsLeft;
+ sal_Int32 m_nPointsTop;
+ sal_Int32 m_nAnimation;
+public:
+ ScVbaAssistant( const css::uno::Reference< ov::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext );
+ virtual ~ScVbaAssistant() override;
+ // XAssistant
+ virtual sal_Bool SAL_CALL getOn() override;
+ virtual void SAL_CALL setOn( sal_Bool _on ) override;
+ virtual sal_Bool SAL_CALL getVisible() override;
+ virtual void SAL_CALL setVisible( sal_Bool _visible ) override;
+ virtual ::sal_Int32 SAL_CALL getTop() override;
+ virtual void SAL_CALL setTop( ::sal_Int32 _top ) override;
+ virtual ::sal_Int32 SAL_CALL getLeft() override;
+ virtual void SAL_CALL setLeft( ::sal_Int32 _left ) override;
+ virtual ::sal_Int32 SAL_CALL getAnimation() override;
+ virtual void SAL_CALL setAnimation( ::sal_Int32 _animation ) override;
+
+ virtual OUString SAL_CALL Name( ) override;
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaaxes.cxx b/sc/source/ui/vba/vbaaxes.cxx
new file mode 100644
index 000000000..c295158b7
--- /dev/null
+++ b/sc/source/ui/vba/vbaaxes.cxx
@@ -0,0 +1,211 @@
+/* -*- 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 "vbaaxes.hxx"
+#include "vbaaxis.hxx"
+#include "vbachart.hxx"
+#include <basic/sberrors.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <cppuhelper/implbase.hxx>
+#include <com/sun/star/script/BasicErrorException.hpp>
+#include <ooo/vba/excel/XlAxisType.hpp>
+#include <ooo/vba/excel/XlAxisGroup.hpp>
+#include <ooo/vba/excel/XAxis.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+using namespace ::ooo::vba::excel::XlAxisType;
+using namespace ::ooo::vba::excel::XlAxisGroup;
+
+// each 'Item' in the Axes collection is indexed via 2 indexes, group and type.
+// We need to 'flatten' this into a single index in order to be able to wrap
+// iteration over the set of Axis(s) in a XIndexAccess implementation
+
+typedef ::std::pair<sal_Int32, sal_Int32 > AxesCoordinate; // type and group combination
+
+namespace {
+
+class EnumWrapper : public EnumerationHelper_BASE
+{
+ uno::Reference<container::XIndexAccess > m_xIndexAccess;
+ sal_Int32 nIndex;
+public:
+ explicit EnumWrapper( const uno::Reference< container::XIndexAccess >& xIndexAccess ) : m_xIndexAccess( xIndexAccess ), nIndex( 0 ) {}
+ virtual sal_Bool SAL_CALL hasMoreElements( ) override
+ {
+ return ( nIndex < m_xIndexAccess->getCount() );
+ }
+
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ if ( nIndex < m_xIndexAccess->getCount() )
+ return m_xIndexAccess->getByIndex( nIndex++ );
+ throw container::NoSuchElementException();
+ }
+};
+
+}
+
+uno::Reference< excel::XAxis >
+ScVbaAxes::createAxis( const uno::Reference< excel::XChart >& xChart, const uno::Reference< uno::XComponentContext >& xContext, sal_Int32 nType, sal_Int32 nAxisGroup )
+{
+ ScVbaChart* pChart = static_cast< ScVbaChart* >( xChart.get() );
+ if ( !pChart )
+ throw uno::RuntimeException("Object failure, can't access chart implementation" );
+
+ uno::Reference< beans::XPropertySet > xAxisPropertySet;
+ if ((nType == xlCategory) || (nType == xlSeriesAxis) || (nType == xlValue))
+ {
+ if ((nAxisGroup != xlPrimary) && (nAxisGroup != xlSecondary))
+ DebugHelper::runtimeexception(ERRCODE_BASIC_METHOD_FAILED);
+ xAxisPropertySet.set( pChart->getAxisPropertySet(nType, nAxisGroup), uno::UNO_SET_THROW );
+ }
+ else
+ DebugHelper::runtimeexception(ERRCODE_BASIC_METHOD_FAILED);
+ uno::Reference< XHelperInterface > xParent( xChart, uno::UNO_QUERY_THROW );
+ return new ScVbaAxis( xParent, xContext, xAxisPropertySet, nType, nAxisGroup);
+}
+
+namespace {
+
+class AxisIndexWrapper : public ::cppu::WeakImplHelper< container::XIndexAccess >
+{
+ // if necessary for better performance we could change this into a map and cache the
+ // indices -> Axis, currently we create a new Axis object
+ // on each getByIndex
+ uno::Reference< uno::XComponentContext > mxContext;
+ std::vector< AxesCoordinate > mCoordinates;
+ uno::Reference< excel::XChart > mxChart;
+public:
+ AxisIndexWrapper( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< excel::XChart >& xChart ) : mxContext( xContext ), mxChart( xChart )
+ {
+ if ( !mxChart.is() )
+ return;
+
+ ScVbaChart* pChart = static_cast< ScVbaChart* >( mxChart.get() );
+ // primary
+ bool bBool = false;
+ uno::Reference< beans::XPropertySet > xDiagramPropertySet( pChart->xDiagramPropertySet() );
+ if ( ( xDiagramPropertySet->getPropertyValue("HasXAxis") >>= bBool ) && bBool )
+ mCoordinates.emplace_back( xlPrimary, xlCategory );
+ if ( ( xDiagramPropertySet->getPropertyValue("HasYAxis") >>= bBool ) && bBool )
+ mCoordinates.emplace_back( xlPrimary, xlSeriesAxis );
+
+ if ( pChart->is3D() )
+ mCoordinates.emplace_back( xlPrimary, xlValue );
+
+ // secondary
+ if ( ( xDiagramPropertySet->getPropertyValue("HasSecondaryXAxis") >>= bBool ) && bBool )
+ mCoordinates.emplace_back( xlSecondary, xlCategory );
+ if ( ( xDiagramPropertySet->getPropertyValue("HasSecondaryYAxis") >>= bBool ) && bBool )
+ mCoordinates.emplace_back( xlSecondary, xlSeriesAxis );
+
+ }
+ virtual ::sal_Int32 SAL_CALL getCount() override { return mCoordinates.size(); }
+ virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override
+ {
+ try
+ {
+ AxesCoordinate dIndexes = mCoordinates[ Index ];
+ return uno::Any( ScVbaAxes::createAxis( mxChart, mxContext, dIndexes.second, dIndexes.first ) );
+ }
+ catch (const css::script::BasicErrorException&)
+ {
+ css::uno::Any anyEx = cppu::getCaughtException();
+ throw css::lang::WrappedTargetException(
+ "Error Getting Index!",
+ static_cast < OWeakObject * > ( this ),
+ anyEx );
+ }
+ }
+ // XElementAccess
+ virtual uno::Type SAL_CALL getElementType() override
+ {
+ return cppu::UnoType<excel::XAxis>::get();
+ }
+ virtual sal_Bool SAL_CALL hasElements( ) override
+ {
+ return ( !mCoordinates.empty() );
+ }
+};
+
+uno::Reference< container::XIndexAccess > createIndexWrapper( const uno::Reference< excel::XChart >& xChart, const uno::Reference< uno::XComponentContext >& xContext )
+{
+ return new AxisIndexWrapper( xContext, xChart );
+}
+
+}
+
+// #FIXME The collection semantics will never work as this object is not yet initialised correctly
+ScVbaAxes::ScVbaAxes( const uno::Reference< XHelperInterface >& xParent,const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< excel::XChart >& xChart ) : ScVbaAxes_BASE( xParent, xContext, createIndexWrapper( xChart, xContext )), moChartParent( xChart )
+{
+}
+
+uno::Type SAL_CALL
+ScVbaAxes::getElementType()
+{
+ return cppu::UnoType<excel::XAxes>::get();
+}
+
+uno::Reference< container::XEnumeration > SAL_CALL
+ScVbaAxes::createEnumeration()
+{
+ return new EnumWrapper( m_xIndexAccess );
+}
+
+uno::Any SAL_CALL
+ScVbaAxes::Item( const css::uno::Any& _nType, const css::uno::Any& _oAxisGroup)
+{
+ // #TODO map the possible index combinations to a container::XIndexAccess wrapper impl
+ // using a vector of valid std::pair maybe?
+ // body helper api port bits
+ sal_Int32 nAxisGroup = xlPrimary;
+ sal_Int32 nType = -1;
+ if ( !_nType.hasValue() || !( _nType >>= nType ) )
+ throw uno::RuntimeException("Axes::Item Failed to extract type" );
+
+ if ( _oAxisGroup.hasValue() )
+ _oAxisGroup >>= nAxisGroup ;
+
+ return uno::Any( createAxis( moChartParent, mxContext, nType, nAxisGroup ) );
+}
+
+uno::Any
+ScVbaAxes::createCollectionObject(const css::uno::Any& aSource)
+{
+ return aSource; // pass through ( it's already an XAxis object
+}
+
+OUString
+ScVbaAxes::getServiceImplName()
+{
+ return "ScVbaAxes";
+}
+
+uno::Sequence< OUString >
+ScVbaAxes::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.Axes"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaaxes.hxx b/sc/source/ui/vba/vbaaxes.hxx
new file mode 100644
index 000000000..cb7c48a7f
--- /dev/null
+++ b/sc/source/ui/vba/vbaaxes.hxx
@@ -0,0 +1,47 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <ooo/vba/excel/XAxes.hpp>
+#include <vbahelper/vbacollectionimpl.hxx>
+
+namespace ooo::vba::excel { class XAxis; }
+namespace ooo::vba::excel { class XChart; }
+
+typedef CollTestImplHelper< ov::excel::XAxes > ScVbaAxes_BASE;
+class ScVbaAxes : public ScVbaAxes_BASE
+{
+ css::uno::Reference< ov::excel::XChart > moChartParent; // not the true parent I guess
+public:
+ ScVbaAxes( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< ov::excel::XChart >& xChart );
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+ // XCollection
+ virtual css::uno::Any SAL_CALL Item( const css::uno::Any& aIndex, const css::uno::Any& aIndex2 ) override;
+ virtual css::uno::Any createCollectionObject(const css::uno::Any&) override;
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+ /// @throws css::uno::RuntimeException
+ /// @throws css::script::BasicErrorException
+ static css::uno::Reference< ov::excel::XAxis > createAxis( const css::uno::Reference< ov::excel::XChart >& xChart, const css::uno::Reference< css::uno::XComponentContext >& xContext, sal_Int32 nType, sal_Int32 nAxisGroup );
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaaxis.cxx b/sc/source/ui/vba/vbaaxis.cxx
new file mode 100644
index 000000000..c34649fa5
--- /dev/null
+++ b/sc/source/ui/vba/vbaaxis.cxx
@@ -0,0 +1,656 @@
+/* -*- 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 "vbaaxis.hxx"
+#include <ooo/vba/excel/XlAxisCrosses.hpp>
+#include <ooo/vba/excel/XlAxisType.hpp>
+#include <ooo/vba/excel/XlScaleType.hpp>
+#include "vbaaxistitle.hxx"
+#include "vbachart.hxx"
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+using namespace ::ooo::vba::excel::XlAxisCrosses;
+using namespace ::ooo::vba::excel::XlAxisType;
+using namespace ::ooo::vba::excel::XlScaleType;
+
+constexpr OUStringLiteral ORIGIN(u"Origin");
+constexpr OUStringLiteral AUTOORIGIN(u"AutoOrigin");
+constexpr OUStringLiteral VBA_MIN(u"Max");
+constexpr OUStringLiteral VBA_MAX(u"Min");
+ScVbaChart*
+ScVbaAxis::getChartPtr()
+{
+ ScVbaChart* pChart = static_cast< ScVbaChart* >( moChartParent.get() );
+ if ( !pChart )
+ throw uno::RuntimeException("Can't access parent chart impl" );
+ return pChart;
+}
+
+bool
+ScVbaAxis::isValueAxis()
+{
+ if ( getType() == xlCategory )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+ return true;
+}
+
+ScVbaAxis::ScVbaAxis( const uno::Reference< XHelperInterface >& xParent,const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< beans::XPropertySet >& _xPropertySet, sal_Int32 _nType, sal_Int32 _nGroup ) : ScVbaAxis_BASE( xParent, xContext ), mxPropertySet( _xPropertySet ), mnType( _nType ), mnGroup( _nGroup ), bCrossesAreCustomized( false )
+{
+ oShapeHelper.reset( new ShapeHelper( uno::Reference< drawing::XShape >( mxPropertySet, uno::UNO_QUERY ) ) );
+ moChartParent.set( xParent, uno::UNO_QUERY_THROW );
+ setType(_nType);
+ setCrosses(xlAxisCrossesAutomatic);
+}
+
+void SAL_CALL
+ScVbaAxis::Delete( )
+{
+ uno::Reference< lang::XComponent > xComponent( mxPropertySet, uno::UNO_QUERY_THROW );
+ xComponent->dispose();
+}
+
+ uno::Reference< ::ooo::vba::excel::XAxisTitle > SAL_CALL
+ScVbaAxis::getAxisTitle( )
+{
+ uno::Reference< excel::XAxisTitle > xAxisTitle;
+ try
+ {
+ ScVbaChart* pChart = getChartPtr();
+
+ if (getHasTitle() )
+ {
+ int nType = getType();
+ switch(nType)
+ {
+ case xlCategory:
+ xAxisTitle = new ScVbaAxisTitle(this, mxContext, pChart->xAxisXSupplier->getXAxisTitle());
+ break;
+ case xlSeriesAxis:
+ xAxisTitle = new ScVbaAxisTitle(this, mxContext, pChart->xAxisZSupplier->getZAxisTitle());
+ break;
+ default: // xlValue:
+ xAxisTitle = new ScVbaAxisTitle(this, mxContext, pChart->xAxisYSupplier->getYAxisTitle());
+ break;
+ }
+ }
+ }
+ catch (const uno::Exception& e)
+ {
+ DebugHelper::basicexception(e);
+ }
+ return xAxisTitle;
+
+}
+
+void SAL_CALL
+ScVbaAxis::setDisplayUnit( ::sal_Int32 /*DisplayUnit*/ )
+{
+ DebugHelper::basicexception(ERRCODE_BASIC_NOT_IMPLEMENTED, {});
+}
+
+::sal_Int32 SAL_CALL
+ScVbaAxis::getDisplayUnit( )
+{
+ DebugHelper::basicexception(ERRCODE_BASIC_NOT_IMPLEMENTED, {});
+ return -1;
+}
+
+void SAL_CALL
+ScVbaAxis::setCrosses( ::sal_Int32 _nCrosses )
+{
+ try
+ {
+ double fNum = 0.0;
+ switch (_nCrosses)
+ {
+ case xlAxisCrossesAutomatic: //Microsoft Excel sets the axis crossing point.
+ mxPropertySet->setPropertyValue(AUTOORIGIN, uno::Any( true ) );
+ bCrossesAreCustomized = false;
+ return;
+ case xlAxisCrossesMinimum: // The axis crosses at the minimum value.
+ mxPropertySet->getPropertyValue(VBA_MIN) >>= fNum;
+ setCrossesAt( fNum );
+ bCrossesAreCustomized = false;
+ break;
+ case xlAxisCrossesMaximum: // The axis crosses at the maximum value.
+ mxPropertySet->getPropertyValue(VBA_MAX) >>= fNum;
+ setCrossesAt(fNum);
+ bCrossesAreCustomized = false;
+ break;
+ default: //xlAxisCrossesCustom
+ bCrossesAreCustomized = true;
+ break;
+ }
+ mxPropertySet->setPropertyValue(AUTOORIGIN, uno::Any(false) );
+ }
+ catch (const uno::Exception&)
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+}
+::sal_Int32 SAL_CALL
+ScVbaAxis::getCrosses( )
+{
+ sal_Int32 nCrosses = xlAxisCrossesCustom;
+ try
+ {
+ bool bisAutoOrigin = false;
+ mxPropertySet->getPropertyValue(AUTOORIGIN) >>= bisAutoOrigin;
+ if (bisAutoOrigin)
+ nCrosses = xlAxisCrossesAutomatic;
+ else
+ {
+ if (bCrossesAreCustomized)
+ nCrosses = xlAxisCrossesCustom;
+ else
+ {
+ double forigin = 0.0;
+ mxPropertySet->getPropertyValue(ORIGIN) >>= forigin;
+ double fmin = 0.0;
+ mxPropertySet->getPropertyValue(VBA_MIN) >>= fmin;
+ if (forigin == fmin)
+ nCrosses = xlAxisCrossesMinimum;
+ else
+ nCrosses = xlAxisCrossesMaximum;
+ }
+ }
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {} );
+ }
+ return nCrosses;
+}
+
+ void SAL_CALL
+ScVbaAxis::setCrossesAt( double _fCrossesAt )
+{
+ try
+ {
+ setMaximumScaleIsAuto( false );
+ setMinimumScaleIsAuto( false );
+ mxPropertySet->setPropertyValue(ORIGIN, uno::Any(_fCrossesAt));
+ }
+ catch (const uno::Exception& e)
+ {
+ DebugHelper::basicexception(e);
+ }
+}
+
+ double SAL_CALL
+ScVbaAxis::getCrossesAt( )
+{
+ double fCrosses = 0.0;
+ try
+ {
+ mxPropertySet->getPropertyValue(ORIGIN) >>= fCrosses;
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+ return fCrosses;
+}
+
+void SAL_CALL
+ScVbaAxis::setType( ::sal_Int32 _nType )
+{
+ mnType = _nType;
+}
+
+::sal_Int32 SAL_CALL
+ScVbaAxis::getType( )
+{
+ return mnType;
+}
+
+void SAL_CALL
+ScVbaAxis::setHasTitle( sal_Bool _bHasTitle )
+{
+ try
+ {
+ ScVbaChart* pChart = getChartPtr();
+ sal_Int32 nType = getType();
+ switch(nType)
+ {
+ case xlCategory:
+ pChart->mxDiagramPropertySet->setPropertyValue("HasXAxisTitle", uno::Any(_bHasTitle));
+ break;
+ case xlSeriesAxis:
+ pChart->mxDiagramPropertySet->setPropertyValue("HasZAxisTitle", uno::Any(_bHasTitle));
+ break;
+ default: // xlValue:
+ pChart->mxDiagramPropertySet->setPropertyValue("HasYAxisTitle", uno::Any(_bHasTitle));
+ }
+
+ }
+ catch (const uno::Exception& e)
+ {
+ DebugHelper::basicexception(e);
+ }
+}
+
+ sal_Bool SAL_CALL
+ScVbaAxis::getHasTitle( )
+{
+ bool bHasTitle = false;
+ try
+ {
+ ScVbaChart* pChart = getChartPtr();
+ int nType = getType();
+ switch(nType)
+ {
+ case xlCategory:
+ pChart->mxDiagramPropertySet->getPropertyValue("HasXAxisTitle") >>= bHasTitle;
+ break;
+ case xlSeriesAxis:
+ pChart->mxDiagramPropertySet->getPropertyValue("HasZAxisTitle") >>= bHasTitle;
+ break;
+ default: // xlValue:
+ pChart->mxDiagramPropertySet->getPropertyValue("HasYAxisTitle") >>= bHasTitle;
+ }
+ }
+ catch (const uno::Exception& e)
+ {
+ DebugHelper::basicexception(e);
+ }
+ return bHasTitle;
+}
+
+void SAL_CALL
+ScVbaAxis::setMinorUnit( double _fMinorUnit )
+{
+ try
+ {
+ if (isValueAxis())
+ mxPropertySet->setPropertyValue("StepHelp", uno::Any(_fMinorUnit));
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+}
+
+double SAL_CALL
+ScVbaAxis::getMinorUnit( )
+{
+ double fMinor = 1.0;
+ try
+ {
+ if (isValueAxis())
+ mxPropertySet->getPropertyValue("StepHelp") >>= fMinor;
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+ return fMinor;
+}
+
+void SAL_CALL
+ScVbaAxis::setMinorUnitIsAuto( sal_Bool _bMinorUnitIsAuto )
+{
+ try
+ {
+ if (isValueAxis())
+ mxPropertySet->setPropertyValue("AutoStepHelp", uno::Any(_bMinorUnitIsAuto));
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {} );
+ }
+}
+
+ sal_Bool SAL_CALL
+ScVbaAxis::getMinorUnitIsAuto( )
+{
+ bool bIsAuto = false;
+ try
+ {
+ if (isValueAxis())
+ {
+ mxPropertySet->getPropertyValue("AutoStepHelp") >>= bIsAuto;
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+ return bIsAuto;
+}
+
+void SAL_CALL
+ScVbaAxis::setReversePlotOrder( sal_Bool /*ReversePlotOrder*/ )
+{
+ DebugHelper::basicexception(ERRCODE_BASIC_NOT_IMPLEMENTED, {});
+}
+
+sal_Bool SAL_CALL
+ScVbaAxis::getReversePlotOrder( )
+{
+ DebugHelper::basicexception(ERRCODE_BASIC_NOT_IMPLEMENTED, {});
+ return false;
+}
+
+void SAL_CALL
+ScVbaAxis::setMajorUnit( double _fMajorUnit )
+{
+ try
+ {
+ if (isValueAxis())
+ {
+ mxPropertySet->setPropertyValue("StepMain", uno::Any(_fMajorUnit));
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+}
+
+double SAL_CALL
+ScVbaAxis::getMajorUnit( )
+{
+ double fMax = 1.0;
+ try
+ {
+ if (isValueAxis())
+ mxPropertySet->getPropertyValue("StepMain") >>= fMax;
+ }
+ catch (const uno::Exception&)
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {} );
+ }
+ return fMax;
+}
+
+void SAL_CALL
+ScVbaAxis::setMajorUnitIsAuto( sal_Bool _bMajorUnitIsAuto )
+{
+ try
+ {
+ if (isValueAxis())
+ {
+ mxPropertySet->setPropertyValue("AutoStepMain", uno::Any( _bMajorUnitIsAuto ));
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+}
+
+sal_Bool SAL_CALL
+ScVbaAxis::getMajorUnitIsAuto( )
+{
+ bool bIsAuto = false;
+ try
+ {
+ if (isValueAxis())
+ {
+ mxPropertySet->getPropertyValue("AutoStepMain") >>= bIsAuto;
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+ return bIsAuto;
+}
+
+void SAL_CALL
+ScVbaAxis::setMaximumScale( double _fMaximumScale )
+{
+ try
+ {
+ if ( isValueAxis() )
+ {
+ mxPropertySet->setPropertyValue("Max", uno::Any(_fMaximumScale));
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+}
+
+double SAL_CALL
+ScVbaAxis::getMaximumScale( )
+{
+ double fMax = 1.0;
+ try
+ {
+ if (isValueAxis())
+ {
+ mxPropertySet->getPropertyValue("Max") >>= fMax;
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+ return fMax;
+
+}
+
+void SAL_CALL
+ScVbaAxis::setMaximumScaleIsAuto( sal_Bool _bMaximumScaleIsAuto )
+{
+ try
+ {
+ if ( isValueAxis() )
+ mxPropertySet->setPropertyValue("AutoMax", uno::Any( _bMaximumScaleIsAuto ));
+
+ }
+ catch (const uno::Exception&)
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+}
+
+sal_Bool SAL_CALL
+ScVbaAxis::getMaximumScaleIsAuto( )
+{
+ bool bIsAuto = false;
+ try
+ {
+ if (isValueAxis())
+ mxPropertySet->getPropertyValue("AutoMax") >>= bIsAuto;
+ }
+ catch (const uno::Exception&)
+ {
+ DebugHelper::basicexception( ERRCODE_BASIC_METHOD_FAILED, {} );
+ }
+ return bIsAuto;
+}
+
+void SAL_CALL
+ScVbaAxis::setMinimumScale( double _fMinimumScale )
+{
+ try
+ {
+ if (isValueAxis())
+ mxPropertySet->setPropertyValue("Min", uno::Any( _fMinimumScale ) );
+ }
+ catch ( uno::Exception& )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {} );
+ }
+}
+
+double SAL_CALL
+ScVbaAxis::getMinimumScale( )
+{
+ double fMin = 0.0;
+ try
+ {
+ if (isValueAxis())
+ mxPropertySet->getPropertyValue("Min") >>= fMin;
+ }
+ catch (const uno::Exception& e)
+ {
+ DebugHelper::basicexception(e);
+ }
+ return fMin;
+}
+
+void SAL_CALL
+ScVbaAxis::setMinimumScaleIsAuto( sal_Bool _bMinimumScaleIsAuto )
+{
+ try
+ {
+ if (isValueAxis())
+ {
+ mxPropertySet->setPropertyValue("AutoMin", uno::Any(_bMinimumScaleIsAuto));
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+}
+
+sal_Bool SAL_CALL
+ScVbaAxis::getMinimumScaleIsAuto( )
+{
+ bool bIsAuto = false;
+ try
+ {
+ if (isValueAxis())
+ {
+ mxPropertySet->getPropertyValue("AutoMin") >>= bIsAuto;
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+ return bIsAuto;
+}
+
+::sal_Int32 SAL_CALL
+ScVbaAxis::getAxisGroup( )
+{
+ return mnGroup;
+}
+
+void SAL_CALL
+ScVbaAxis::setScaleType( ::sal_Int32 _nScaleType )
+{
+ try
+ {
+ if (isValueAxis())
+ {
+ switch (_nScaleType)
+ {
+ case xlScaleLinear:
+ mxPropertySet->setPropertyValue("Logarithmic", uno::Any( false ) );
+ break;
+ case xlScaleLogarithmic:
+ mxPropertySet->setPropertyValue("Logarithmic", uno::Any( true ) );
+ break;
+ default:
+ // According to MS the parameter is ignored and no Error is thrown
+ break;
+ }
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+}
+
+::sal_Int32 SAL_CALL
+ScVbaAxis::getScaleType( )
+{
+ sal_Int32 nScaleType = xlScaleLinear;
+ try
+ {
+ if (isValueAxis())
+ {
+ bool bisLogarithmic = false;
+ mxPropertySet->getPropertyValue( "Logarithmic" ) >>= bisLogarithmic;
+ if (bisLogarithmic)
+ nScaleType = xlScaleLogarithmic;
+ else
+ nScaleType = xlScaleLinear;
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+ return nScaleType;
+}
+
+double SAL_CALL
+ScVbaAxis::getHeight( )
+{
+ return oShapeHelper->getHeight();
+}
+
+void SAL_CALL ScVbaAxis::setHeight( double height )
+{
+ oShapeHelper->setHeight( height );
+}
+double SAL_CALL ScVbaAxis::getWidth( )
+{
+ return oShapeHelper->getWidth( );
+}
+void SAL_CALL ScVbaAxis::setWidth( double width )
+{
+ oShapeHelper->setWidth( width );
+}
+double SAL_CALL ScVbaAxis::getTop( )
+{
+ return oShapeHelper->getTop( );
+}
+void SAL_CALL ScVbaAxis::setTop( double top )
+{
+ oShapeHelper->setTop( top );
+}
+double SAL_CALL ScVbaAxis::getLeft( )
+{
+ return oShapeHelper->getLeft( );
+}
+void SAL_CALL ScVbaAxis::setLeft( double left )
+{
+ oShapeHelper->setLeft( left );
+}
+
+OUString
+ScVbaAxis::getServiceImplName()
+{
+ return "ScVbaAxis";
+}
+
+uno::Sequence< OUString >
+ScVbaAxis::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.Axis"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaaxis.hxx b/sc/source/ui/vba/vbaaxis.hxx
new file mode 100644
index 000000000..6636fb617
--- /dev/null
+++ b/sc/source/ui/vba/vbaaxis.hxx
@@ -0,0 +1,90 @@
+/* -*- 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 .
+ */
+#pragma once
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <ooo/vba/excel/XAxis.hpp>
+#include <ooo/vba/excel/XChart.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <memory>
+typedef InheritedHelperInterfaceWeakImpl< ov::excel::XAxis > ScVbaAxis_BASE;
+class ScVbaChart;
+class ScVbaAxis : public ScVbaAxis_BASE
+{
+ css::uno::Reference< ov::excel::XChart > moChartParent;
+ css::uno::Reference< css::beans::XPropertySet > mxPropertySet;
+ sal_Int32 mnType;
+ sal_Int32 mnGroup;
+ bool bCrossesAreCustomized;
+ /// @throws css::uno::RuntimeException
+ ScVbaChart* getChartPtr();
+ /// @throws css::script::BasicErrorException
+ bool isValueAxis();
+ std::unique_ptr<ov::ShapeHelper> oShapeHelper;
+
+public:
+ ScVbaAxis( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::beans::XPropertySet >& _xPropertySet, sal_Int32 _nType, sal_Int32 _nGroup );
+ // Methods
+ virtual void SAL_CALL Delete( ) override;
+ virtual css::uno::Reference< ::ooo::vba::excel::XAxisTitle > SAL_CALL getAxisTitle( ) override;
+ virtual void SAL_CALL setDisplayUnit( ::sal_Int32 DisplayUnit ) override;
+ virtual ::sal_Int32 SAL_CALL getDisplayUnit( ) override;
+ virtual void SAL_CALL setCrosses( ::sal_Int32 Crosses ) override;
+ virtual ::sal_Int32 SAL_CALL getCrosses( ) override;
+ virtual void SAL_CALL setCrossesAt( double CrossesAt ) override;
+ virtual double SAL_CALL getCrossesAt( ) override;
+ virtual void SAL_CALL setType( ::sal_Int32 Type ) override;
+ virtual ::sal_Int32 SAL_CALL getType( ) override;
+ virtual void SAL_CALL setHasTitle( sal_Bool HasTitle ) override;
+ virtual sal_Bool SAL_CALL getHasTitle( ) override;
+ virtual void SAL_CALL setMinorUnit( double MinorUnit ) override;
+ virtual double SAL_CALL getMinorUnit( ) override;
+ virtual void SAL_CALL setMinorUnitIsAuto( sal_Bool MinorUnitIsAuto ) override;
+ virtual sal_Bool SAL_CALL getMinorUnitIsAuto( ) override;
+ virtual void SAL_CALL setReversePlotOrder( sal_Bool ReversePlotOrder ) override;
+ virtual sal_Bool SAL_CALL getReversePlotOrder( ) override;
+ virtual void SAL_CALL setMajorUnit( double MajorUnit ) override;
+ virtual double SAL_CALL getMajorUnit( ) override;
+ virtual void SAL_CALL setMajorUnitIsAuto( sal_Bool MajorUnitIsAuto ) override;
+ virtual sal_Bool SAL_CALL getMajorUnitIsAuto( ) override;
+ virtual void SAL_CALL setMaximumScale( double MaximumScale ) override;
+ virtual double SAL_CALL getMaximumScale( ) override;
+ virtual void SAL_CALL setMaximumScaleIsAuto( sal_Bool MaximumScaleIsAuto ) override;
+ virtual sal_Bool SAL_CALL getMaximumScaleIsAuto( ) override;
+ virtual void SAL_CALL setMinimumScale( double MinimumScale ) override;
+ virtual double SAL_CALL getMinimumScale( ) override;
+ virtual void SAL_CALL setMinimumScaleIsAuto( sal_Bool MinimumScaleIsAuto ) override;
+ virtual sal_Bool SAL_CALL getMinimumScaleIsAuto( ) override;
+ virtual ::sal_Int32 SAL_CALL getAxisGroup( ) override;
+ virtual void SAL_CALL setScaleType( ::sal_Int32 ScaleType ) override;
+ virtual ::sal_Int32 SAL_CALL getScaleType( ) override;
+ virtual double SAL_CALL getHeight( ) override;
+ virtual void SAL_CALL setHeight( double height ) override;
+ virtual double SAL_CALL getWidth( ) override;
+ virtual void SAL_CALL setWidth( double width ) override;
+ virtual double SAL_CALL getTop( ) override;
+ virtual void SAL_CALL setTop( double top ) override;
+ virtual double SAL_CALL getLeft( ) override;
+ virtual void SAL_CALL setLeft( double left ) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaaxistitle.cxx b/sc/source/ui/vba/vbaaxistitle.cxx
new file mode 100644
index 000000000..5336ef7a7
--- /dev/null
+++ b/sc/source/ui/vba/vbaaxistitle.cxx
@@ -0,0 +1,44 @@
+/* -*- 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 "vbaaxistitle.hxx"
+#include <comphelper/sequence.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+ScVbaAxisTitle::ScVbaAxisTitle( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< drawing::XShape >& _xTitleShape ) : AxisTitleBase( xParent, xContext, _xTitleShape )
+{
+}
+
+OUString
+ScVbaAxisTitle::getServiceImplName()
+{
+ return "ScVbaAxisTitle";
+}
+
+uno::Sequence< OUString >
+ScVbaAxisTitle::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames = comphelper::concatSequences(
+ AxisTitleBase::getServiceNames(),
+ uno::Sequence<OUString> { "ooo.vba.excel.AxisTitle" } );
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaaxistitle.hxx b/sc/source/ui/vba/vbaaxistitle.hxx
new file mode 100644
index 000000000..9226a58a3
--- /dev/null
+++ b/sc/source/ui/vba/vbaaxistitle.hxx
@@ -0,0 +1,36 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include "vbatitle.hxx"
+#include <cppuhelper/implbase.hxx>
+#include <ooo/vba/excel/XAxisTitle.hpp>
+
+typedef TitleImpl< cppu::WeakImplHelper< ov::excel::XAxisTitle > > AxisTitleBase;
+
+class ScVbaAxisTitle : public AxisTitleBase
+{
+public:
+ ScVbaAxisTitle( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::drawing::XShape >& _xTitleShape );
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaborders.cxx b/sc/source/ui/vba/vbaborders.cxx
new file mode 100644
index 000000000..22434f971
--- /dev/null
+++ b/sc/source/ui/vba/vbaborders.cxx
@@ -0,0 +1,591 @@
+/* -*- 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 "vbaborders.hxx"
+
+#include <sal/macros.h>
+#include <cppuhelper/implbase.hxx>
+#include <ooo/vba/excel/XlBordersIndex.hpp>
+#include <ooo/vba/excel/XlBorderWeight.hpp>
+#include <ooo/vba/excel/XlLineStyle.hpp>
+#include <ooo/vba/excel/XlColorIndex.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/table/TableBorder.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/table/XColumnRowRange.hpp>
+
+#include "vbapalette.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+using namespace ::ooo::vba::excel;
+
+typedef ::cppu::WeakImplHelper<container::XIndexAccess > RangeBorders_Base;
+typedef InheritedHelperInterfaceWeakImpl<excel::XBorder > ScVbaBorder_Base;
+
+// #TODO sort these indexes to match the order in which Excel iterates over the
+// borders, the enumeration will match the order in this list
+const sal_Int16 supportedIndexTable[] = { XlBordersIndex::xlEdgeLeft, XlBordersIndex::xlEdgeTop, XlBordersIndex::xlEdgeBottom, XlBordersIndex::xlEdgeRight, XlBordersIndex::xlDiagonalDown, XlBordersIndex::xlDiagonalUp, XlBordersIndex::xlInsideVertical, XlBordersIndex::xlInsideHorizontal };
+
+constexpr OUStringLiteral sTableBorder = u"TableBorder";
+
+// Equiv widths in 1/100 mm
+const sal_Int32 OOLineThin = 26;
+const sal_Int32 OOLineMedium = 88;
+const sal_Int32 OOLineThick = 141;
+const sal_Int32 OOLineHairline = 2;
+
+namespace {
+
+class ScVbaBorder : public ScVbaBorder_Base
+{
+private:
+ uno::Reference< beans::XPropertySet > m_xProps;
+ sal_Int32 m_LineType;
+ ScVbaPalette m_Palette;
+ void setBorderLine( const table::BorderLine& rBorderLine )
+ {
+ table::TableBorder aTableBorder;
+ m_xProps->getPropertyValue( sTableBorder ) >>= aTableBorder;
+
+ switch ( m_LineType )
+ {
+ case XlBordersIndex::xlEdgeLeft:
+ aTableBorder.IsLeftLineValid = true;
+ aTableBorder.LeftLine= rBorderLine;
+ break;
+ case XlBordersIndex::xlEdgeTop:
+ aTableBorder.IsTopLineValid = true;
+ aTableBorder.TopLine = rBorderLine;
+ break;
+
+ case XlBordersIndex::xlEdgeBottom:
+ aTableBorder.IsBottomLineValid = true;
+ aTableBorder.BottomLine = rBorderLine;
+ break;
+ case XlBordersIndex::xlEdgeRight:
+ aTableBorder.IsRightLineValid = true;
+ aTableBorder.RightLine = rBorderLine;
+ break;
+ case XlBordersIndex::xlInsideVertical:
+ aTableBorder.IsVerticalLineValid = true;
+ aTableBorder.VerticalLine = rBorderLine;
+ break;
+ case XlBordersIndex::xlInsideHorizontal:
+ aTableBorder.IsHorizontalLineValid = true;
+ aTableBorder.HorizontalLine = rBorderLine;
+ break;
+ case XlBordersIndex::xlDiagonalDown:
+ case XlBordersIndex::xlDiagonalUp:
+ // #TODO have to ignore at the moment, would be
+ // nice to investigate what we can do here
+ break;
+ default:
+ return;
+ }
+ m_xProps->setPropertyValue( sTableBorder, uno::Any(aTableBorder) );
+ }
+
+ bool getBorderLine( table::BorderLine& rBorderLine )
+ {
+ table::TableBorder aTableBorder;
+ m_xProps->getPropertyValue( sTableBorder ) >>= aTableBorder;
+ switch ( m_LineType )
+ {
+ case XlBordersIndex::xlEdgeLeft:
+ if ( aTableBorder.IsLeftLineValid )
+ rBorderLine = aTableBorder.LeftLine;
+ break;
+ case XlBordersIndex::xlEdgeTop:
+ if ( aTableBorder.IsTopLineValid )
+ rBorderLine = aTableBorder.TopLine;
+ break;
+
+ case XlBordersIndex::xlEdgeBottom:
+ if ( aTableBorder.IsBottomLineValid )
+ rBorderLine = aTableBorder.BottomLine;
+ break;
+ case XlBordersIndex::xlEdgeRight:
+ if ( aTableBorder.IsRightLineValid )
+ rBorderLine = aTableBorder.RightLine;
+ break;
+ case XlBordersIndex::xlInsideVertical:
+ if ( aTableBorder.IsVerticalLineValid )
+ rBorderLine = aTableBorder.VerticalLine;
+ break;
+ case XlBordersIndex::xlInsideHorizontal:
+ if ( aTableBorder.IsHorizontalLineValid )
+ rBorderLine = aTableBorder.HorizontalLine;
+ break;
+
+ case XlBordersIndex::xlDiagonalDown:
+ case XlBordersIndex::xlDiagonalUp:
+ // #TODO have to ignore at the moment, would be
+ // nice to investigate what we can do here
+ break;
+ default:
+ return false;
+ }
+ return true;
+ }
+
+protected:
+ virtual OUString getServiceImplName() override
+ {
+ return "ScVbaBorder";
+ }
+ virtual css::uno::Sequence<OUString> getServiceNames() override
+ {
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.Border"
+ };
+ return aServiceNames;
+ }
+public:
+ ScVbaBorder( const uno::Reference< beans::XPropertySet > & xProps, const uno::Reference< uno::XComponentContext >& xContext, sal_Int32 lineType, const ScVbaPalette& rPalette) : ScVbaBorder_Base( uno::Reference< XHelperInterface >( xProps, uno::UNO_QUERY ), xContext ), m_xProps( xProps ), m_LineType( lineType ), m_Palette( rPalette ) {}
+
+ // XBorder
+ uno::Any SAL_CALL getColor() override
+ {
+ table::BorderLine aBorderLine;
+ if ( getBorderLine( aBorderLine ) )
+ return uno::Any( OORGBToXLRGB( Color(ColorTransparency, aBorderLine.Color) ) );
+ throw uno::RuntimeException("No Implementation available" );
+ }
+ void SAL_CALL setColor( const uno::Any& _color ) override
+ {
+ sal_Int32 nColor = 0;
+ _color >>= nColor;
+ table::BorderLine aBorderLine;
+ if ( !getBorderLine( aBorderLine ) )
+ throw uno::RuntimeException("No Implementation available" );
+
+ aBorderLine.Color = XLRGBToOORGB( nColor );
+ setBorderLine( aBorderLine );
+
+ }
+
+ uno::Any SAL_CALL getColorIndex() override
+ {
+ sal_Int32 nColor = 0;
+ XLRGBToOORGB( getColor() ) >>= nColor;
+ uno::Reference< container::XIndexAccess > xIndex = m_Palette.getPalette();
+ sal_Int32 nElems = xIndex->getCount();
+ sal_Int32 nIndex = -1;
+ for ( sal_Int32 count=0; count<nElems; ++count )
+ {
+ sal_Int32 nPaletteColor = 0;
+ xIndex->getByIndex( count ) >>= nPaletteColor;
+ if ( nPaletteColor == nColor )
+ {
+ nIndex = count + 1;
+ break;
+ }
+ }
+ return uno::Any(nIndex);
+ }
+
+ void SAL_CALL setColorIndex( const uno::Any& _colorindex ) override
+ {
+ sal_Int32 nColor = 0;
+ _colorindex >>= nColor;
+ if ( !nColor || nColor == XlColorIndex::xlColorIndexAutomatic )
+ nColor = 1;
+ setColor( OORGBToXLRGB( m_Palette.getPalette()->getByIndex( --nColor ) ) );
+ }
+ uno::Any SAL_CALL getWeight() override
+ {
+ table::BorderLine aBorderLine;
+ if ( getBorderLine( aBorderLine ) )
+ {
+ switch ( aBorderLine.OuterLineWidth )
+ {
+ case 0: // Thin = default OO thickness
+ case OOLineThin:
+ return uno::Any( XlBorderWeight::xlThin );
+ case OOLineMedium:
+ return uno::Any( XlBorderWeight::xlMedium );
+ case OOLineThick:
+ return uno::Any( XlBorderWeight::xlThick );
+ case OOLineHairline:
+ return uno::Any( XlBorderWeight::xlHairline );
+ default:
+ break;
+ }
+ }
+ throw uno::RuntimeException("Method failed" );
+ }
+ void SAL_CALL setWeight( const uno::Any& _weight ) override
+ {
+ sal_Int32 nWeight = 0;
+ _weight >>= nWeight;
+ table::BorderLine aBorderLine;
+ if ( !getBorderLine( aBorderLine ) )
+ throw uno::RuntimeException("Method failed" );
+
+ switch ( nWeight )
+ {
+ case XlBorderWeight::xlThin:
+ aBorderLine.OuterLineWidth = OOLineThin;
+ break;
+ case XlBorderWeight::xlMedium:
+ aBorderLine.OuterLineWidth = OOLineMedium;
+ break;
+ case XlBorderWeight::xlThick:
+ aBorderLine.OuterLineWidth = OOLineThick;
+ break;
+ case XlBorderWeight::xlHairline:
+ aBorderLine.OuterLineWidth = OOLineHairline;
+ break;
+ default:
+ throw uno::RuntimeException("Bad param" );
+ }
+ setBorderLine( aBorderLine );
+
+ }
+
+ void SAL_CALL setTintAndShade( const uno::Any& /*rAny*/ ) override
+ {
+ // TODO implement
+ }
+ uno::Any SAL_CALL getTintAndShade() override
+ {
+ // TODO implement
+ return uno::Any(static_cast<double>(0));
+ }
+
+ uno::Any SAL_CALL getLineStyle() override
+ {
+ // always return xlContinuous;
+ return uno::Any( XlLineStyle::xlContinuous );
+ }
+ void SAL_CALL setLineStyle( const uno::Any& _linestyle ) override
+ {
+ // Urk no choice but to silently ignore we don't support this attribute
+ // #TODO would be nice to support the excel line styles
+ sal_Int32 nLineStyle = 0;
+ _linestyle >>= nLineStyle;
+ table::BorderLine aBorderLine;
+ if ( !getBorderLine( aBorderLine ) )
+ throw uno::RuntimeException("Method failed" );
+
+ switch ( nLineStyle )
+ {
+ case XlLineStyle::xlContinuous:
+ case XlLineStyle::xlDash:
+ case XlLineStyle::xlDashDot:
+ case XlLineStyle::xlDashDotDot:
+ case XlLineStyle::xlDot:
+ case XlLineStyle::xlDouble:
+ case XlLineStyle::xlLineStyleNone:
+ case XlLineStyle::xlSlantDashDot:
+ break;
+ default:
+ throw uno::RuntimeException("Bad param" );
+ }
+ setBorderLine( aBorderLine );
+
+ }
+};
+
+class RangeBorders : public RangeBorders_Base
+{
+private:
+ uno::Reference< table::XCellRange > m_xRange;
+ uno::Reference< uno::XComponentContext > m_xContext;
+ ScVbaPalette m_Palette;
+ sal_Int32 getTableIndex( sal_Int32 nConst )
+ {
+ // okay return position of the index in the table
+ sal_Int32 nIndexes = getCount();
+ sal_Int32 realIndex = 0;
+ const sal_Int16* pTableEntry = supportedIndexTable;
+ for ( ; realIndex < nIndexes; ++realIndex, ++pTableEntry )
+ {
+ if ( *pTableEntry == nConst )
+ return realIndex;
+ }
+ return getCount(); // error condition
+ }
+public:
+ RangeBorders( const uno::Reference< table::XCellRange >& xRange, const uno::Reference< uno::XComponentContext > & xContext, const ScVbaPalette& rPalette ) : m_xRange( xRange ), m_xContext( xContext ), m_Palette( rPalette )
+ {
+ }
+ // XIndexAccess
+ virtual ::sal_Int32 SAL_CALL getCount( ) override
+ {
+ return SAL_N_ELEMENTS( supportedIndexTable );
+ }
+ virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override
+ {
+
+ sal_Int32 nIndex = getTableIndex( Index );
+ if ( nIndex >= 0 && nIndex < getCount() )
+ {
+ uno::Reference< beans::XPropertySet > xProps( m_xRange, uno::UNO_QUERY_THROW );
+ return uno::Any( uno::Reference< excel::XBorder >( new ScVbaBorder( xProps, m_xContext, supportedIndexTable[ nIndex ], m_Palette )) );
+ }
+ throw lang::IndexOutOfBoundsException();
+ }
+ virtual uno::Type SAL_CALL getElementType( ) override
+ {
+ return cppu::UnoType<excel::XBorder>::get();
+ }
+ virtual sal_Bool SAL_CALL hasElements( ) override
+ {
+ return true;
+ }
+};
+
+}
+
+static uno::Reference< container::XIndexAccess >
+rangeToBorderIndexAccess( const uno::Reference< table::XCellRange >& xRange, const uno::Reference< uno::XComponentContext > & xContext, const ScVbaPalette& rPalette )
+{
+ return new RangeBorders( xRange, xContext, rPalette );
+}
+
+namespace {
+
+class RangeBorderEnumWrapper : public EnumerationHelper_BASE
+{
+ uno::Reference<container::XIndexAccess > m_xIndexAccess;
+ sal_Int32 nIndex;
+public:
+ explicit RangeBorderEnumWrapper( const uno::Reference< container::XIndexAccess >& xIndexAccess ) : m_xIndexAccess( xIndexAccess ), nIndex( 0 ) {}
+ virtual sal_Bool SAL_CALL hasMoreElements( ) override
+ {
+ return ( nIndex < m_xIndexAccess->getCount() );
+ }
+
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ if ( nIndex < m_xIndexAccess->getCount() )
+ return m_xIndexAccess->getByIndex( nIndex++ );
+ throw container::NoSuchElementException();
+ }
+};
+
+}
+
+ScVbaBorders::ScVbaBorders( const uno::Reference< XHelperInterface >& xParent,
+ const uno::Reference< uno::XComponentContext > & xContext,
+ const uno::Reference< table::XCellRange >& xRange,
+ const ScVbaPalette& rPalette )
+ : ScVbaBorders_BASE( xParent, xContext, rangeToBorderIndexAccess( xRange ,xContext, rPalette ) ), bRangeIsSingleCell( false )
+{
+ uno::Reference< table::XColumnRowRange > xColumnRowRange(xRange, uno::UNO_QUERY_THROW );
+ if ( xColumnRowRange->getRows()->getCount() == 1 && xColumnRowRange->getColumns()->getCount() == 1 )
+ bRangeIsSingleCell = true;
+ m_xProps.set( xRange, uno::UNO_QUERY_THROW );
+}
+
+uno::Reference< container::XEnumeration >
+ScVbaBorders::createEnumeration()
+{
+ return new RangeBorderEnumWrapper( m_xIndexAccess );
+}
+
+uno::Any
+ScVbaBorders::createCollectionObject( const css::uno::Any& aSource )
+{
+ return aSource; // it's already a Border object
+}
+
+uno::Type
+ScVbaBorders::getElementType()
+{
+ return cppu::UnoType<excel::XBorders>::get();
+}
+
+uno::Any
+ScVbaBorders::getItemByIntIndex( const sal_Int32 nIndex )
+{
+ return createCollectionObject( m_xIndexAccess->getByIndex( nIndex ) );
+}
+
+uno::Any SAL_CALL ScVbaBorders::getColor()
+{
+ sal_Int32 count = getCount();
+ uno::Any color;
+ for( sal_Int32 i = 0; i < count ; i++ )
+ {
+ if( XlBordersIndex::xlDiagonalDown != supportedIndexTable[i] && XlBordersIndex::xlDiagonalUp != supportedIndexTable[i] )
+ {
+ uno::Reference< XBorder > xBorder( getItemByIntIndex( supportedIndexTable[i] ), uno::UNO_QUERY_THROW );
+ if( color.hasValue() )
+ {
+ if( color != xBorder->getColor() )
+ return uno::Any( uno::Reference< uno::XInterface >() );
+ }
+ else
+ color = xBorder->getColor();
+ }
+ }
+ return color;
+}
+void SAL_CALL ScVbaBorders::setColor( const uno::Any& _color )
+{
+ sal_Int32 count = getCount();
+ for( sal_Int32 i = 0; i < count ; i++ )
+ {
+ uno::Reference< XBorder > xBorder( getItemByIntIndex( supportedIndexTable[i] ), uno::UNO_QUERY_THROW );
+ xBorder->setColor( _color );
+ }
+}
+uno::Any SAL_CALL ScVbaBorders::getColorIndex()
+{
+ sal_Int32 count = getCount();
+ uno::Any nColorIndex;
+ for( sal_Int32 i = 0; i < count ; i++ )
+ {
+ if( XlBordersIndex::xlDiagonalDown != supportedIndexTable[i] && XlBordersIndex::xlDiagonalUp != supportedIndexTable[i] )
+ {
+ uno::Reference< XBorder > xBorder( getItemByIntIndex( supportedIndexTable[i] ), uno::UNO_QUERY_THROW );
+ if( nColorIndex.hasValue() )
+ {
+ if( nColorIndex != xBorder->getColorIndex() )
+ return uno::Any( uno::Reference< uno::XInterface >() );
+ }
+ else
+ nColorIndex = xBorder->getColorIndex();
+ }
+ }
+ return nColorIndex;
+}
+void SAL_CALL ScVbaBorders::setColorIndex( const uno::Any& _colorindex )
+{
+ sal_Int32 count = getCount();
+ for( sal_Int32 i = 0; i < count ; i++ )
+ {
+ uno::Reference< XBorder > xBorder( getItemByIntIndex( supportedIndexTable[i] ), uno::UNO_QUERY_THROW );
+ xBorder->setColorIndex( _colorindex );
+ }
+}
+
+static bool
+lcl_areAllLineWidthsSame( const table::TableBorder& maTableBorder, bool bIsCell )
+{
+
+ bool bRes = false;
+ if (bIsCell)
+ {
+ bRes = ((maTableBorder.TopLine.OuterLineWidth == maTableBorder.BottomLine.OuterLineWidth) &&
+(maTableBorder.TopLine.OuterLineWidth == maTableBorder.LeftLine.OuterLineWidth) &&
+(maTableBorder.TopLine.OuterLineWidth == maTableBorder.RightLine.OuterLineWidth));
+ }
+ else
+ {
+ bRes = ((maTableBorder.TopLine.OuterLineWidth == maTableBorder.BottomLine.OuterLineWidth) &&
+(maTableBorder.TopLine.OuterLineWidth == maTableBorder.LeftLine.OuterLineWidth) &&
+(maTableBorder.TopLine.OuterLineWidth == maTableBorder.HorizontalLine.OuterLineWidth) &&
+(maTableBorder.TopLine.OuterLineWidth == maTableBorder.VerticalLine.OuterLineWidth) &&
+(maTableBorder.TopLine.OuterLineWidth == maTableBorder.RightLine.OuterLineWidth));
+ }
+ return bRes;
+}
+
+uno::Any SAL_CALL ScVbaBorders::getLineStyle()
+{
+ table::TableBorder aTableBorder;
+ m_xProps->getPropertyValue( sTableBorder ) >>= aTableBorder;
+
+ sal_Int32 aLinestyle = XlLineStyle::xlLineStyleNone;
+
+ if ( lcl_areAllLineWidthsSame( aTableBorder, bRangeIsSingleCell ))
+ {
+ if (aTableBorder.TopLine.LineDistance != 0)
+ {
+ aLinestyle = XlLineStyle::xlDouble;
+ }
+ else if ( aTableBorder.TopLine.OuterLineWidth != 0 )
+ {
+ aLinestyle = XlLineStyle::xlContinuous;
+ }
+ }
+ return uno::Any( aLinestyle );
+}
+void SAL_CALL ScVbaBorders::setLineStyle( const uno::Any& _linestyle )
+{
+ sal_Int32 count = getCount();
+ for( sal_Int32 i = 0; i < count ; i++ )
+ {
+ uno::Reference< XBorder > xBorder( getItemByIntIndex( supportedIndexTable[i] ), uno::UNO_QUERY_THROW );
+ xBorder->setLineStyle( _linestyle );
+ }
+}
+uno::Any SAL_CALL ScVbaBorders::getWeight()
+{
+ sal_Int32 count = getCount();
+ uno::Any weight;
+ for( sal_Int32 i = 0; i < count ; i++ )
+ {
+ if( XlBordersIndex::xlDiagonalDown != supportedIndexTable[i] && XlBordersIndex::xlDiagonalUp != supportedIndexTable[i] )
+ {
+ uno::Reference< XBorder > xBorder( getItemByIntIndex( supportedIndexTable[i] ), uno::UNO_QUERY_THROW );
+ if( weight.hasValue() )
+ {
+ if( weight != xBorder->getWeight() )
+ return uno::Any( uno::Reference< uno::XInterface >() );
+ }
+ else
+ weight = xBorder->getWeight();
+ }
+ }
+ return weight;
+}
+
+uno::Any SAL_CALL ScVbaBorders::getTintAndShade()
+{
+ // TODO implement
+ return uno::Any(static_cast<double>(0));
+}
+
+void SAL_CALL ScVbaBorders::setTintAndShade(const uno::Any& /*rAny*/)
+{
+ // TODO implement
+}
+
+void SAL_CALL ScVbaBorders::setWeight( const uno::Any& _weight )
+{
+ sal_Int32 count = getCount();
+ for( sal_Int32 i = 0; i < count ; i++ )
+ {
+ uno::Reference< XBorder > xBorder( getItemByIntIndex( supportedIndexTable[i] ), uno::UNO_QUERY_THROW );
+ xBorder->setWeight( _weight );
+ }
+}
+
+OUString
+ScVbaBorders::getServiceImplName()
+{
+ return "ScVbaBorders";
+}
+
+uno::Sequence< OUString >
+ScVbaBorders::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.Borders"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaborders.hxx b/sc/source/ui/vba/vbaborders.hxx
new file mode 100644
index 000000000..6d3621101
--- /dev/null
+++ b/sc/source/ui/vba/vbaborders.hxx
@@ -0,0 +1,67 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <ooo/vba/excel/XBorders.hpp>
+
+#include <vbahelper/vbacollectionimpl.hxx>
+
+namespace com::sun::star::beans { class XPropertySet; }
+namespace com::sun::star::uno { class XComponentContext; }
+namespace com::sun::star::table { class XCellRange; }
+
+typedef CollTestImplHelper< ov::excel::XBorders > ScVbaBorders_BASE;
+class ScVbaPalette;
+class ScVbaBorders : public ScVbaBorders_BASE
+{
+ // XEnumerationAccess
+ virtual css::uno::Any getItemByIntIndex( const sal_Int32 nIndex ) override;
+ bool bRangeIsSingleCell;
+ css::uno::Reference< css::beans::XPropertySet > m_xProps;
+public:
+ ScVbaBorders( const css::uno::Reference< ov::XHelperInterface >& xParent,
+ const css::uno::Reference< css::uno::XComponentContext > & xContext,
+ const css::uno::Reference< css::table::XCellRange >& xRange,
+ const ScVbaPalette& rPalette );
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+
+ // XBorders
+
+ // ScVbaCollectionBaseImpl
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+
+ virtual css::uno::Any SAL_CALL getColor() override;
+ virtual void SAL_CALL setColor( const css::uno::Any& _color ) override;
+ virtual css::uno::Any SAL_CALL getColorIndex() override;
+ virtual void SAL_CALL setColorIndex( const css::uno::Any& _colorindex ) override;
+ virtual css::uno::Any SAL_CALL getLineStyle() override;
+ virtual void SAL_CALL setLineStyle( const css::uno::Any& _linestyle ) override;
+ virtual css::uno::Any SAL_CALL getWeight() override;
+ virtual void SAL_CALL setWeight( const css::uno::Any& ) override;
+ virtual css::uno::Any SAL_CALL getTintAndShade() override;
+ virtual void SAL_CALL setTintAndShade( const css::uno::Any& ) override;
+ // xxxxBASE
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbacharacters.cxx b/sc/source/ui/vba/vbacharacters.cxx
new file mode 100644
index 000000000..3fd00b207
--- /dev/null
+++ b/sc/source/ui/vba/vbacharacters.cxx
@@ -0,0 +1,134 @@
+/* -*- 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 "vbacharacters.hxx"
+
+#include "vbafont.hxx"
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+ScVbaCharacters::ScVbaCharacters( const uno::Reference< XHelperInterface >& xParent,
+ const uno::Reference< uno::XComponentContext >& xContext,
+ const ScVbaPalette& dPalette,
+ const uno::Reference< text::XSimpleText>& xRange,
+ const css::uno::Any& Start,
+ const css::uno::Any& Length,
+ bool Replace )
+ : ScVbaCharacters_BASE( xParent, xContext ),
+ m_xSimpleText(xRange), m_aPalette( dPalette), bReplace( Replace )
+{
+ sal_Int16 nLength(-1);
+ sal_Int16 nStart(1);
+ Start >>= nStart;
+ if ( nStart < 1 )
+ nStart = 1; // silently correct user error ( as ms )
+ nStart--; // OOo is 0 based
+ Length >>=nLength;
+ uno::Reference< text::XTextCursor > xTextCursor( m_xSimpleText->createTextCursor(), uno::UNO_SET_THROW );
+ xTextCursor->collapseToStart();
+ if ( nStart )
+ {
+ if ( ( nStart + 1 ) > m_xSimpleText->getString().getLength() )
+ //nStart = m_xSimpleText->getString().getLength();
+ xTextCursor->gotoEnd( false );
+ xTextCursor->goRight( nStart, false );
+ }
+ if ( nLength < 0 ) // expand to end
+ xTextCursor->gotoEnd( true );
+ else
+ xTextCursor->goRight( nLength, true );
+ m_xTextRange.set( xTextCursor, uno::UNO_QUERY_THROW );
+
+}
+
+OUString SAL_CALL
+ScVbaCharacters::getCaption()
+{
+ return m_xTextRange->getString();
+}
+void SAL_CALL
+ScVbaCharacters::setCaption( const OUString& _caption )
+{
+ m_xTextRange->setString( _caption );
+
+}
+
+::sal_Int32 SAL_CALL
+ScVbaCharacters::getCount()
+{
+ return getCaption().getLength();
+}
+
+OUString SAL_CALL
+ScVbaCharacters::getText()
+{
+ return getCaption();
+}
+void SAL_CALL
+ScVbaCharacters::setText( const OUString& _text )
+{
+ setCaption( _text );
+}
+uno::Reference< excel::XFont > SAL_CALL
+ScVbaCharacters::getFont()
+{
+ uno::Reference< beans::XPropertySet > xProps( m_xTextRange, uno::UNO_QUERY_THROW );
+ return uno::Reference< excel::XFont >( new ScVbaFont( this, mxContext, m_aPalette, xProps ) );
+}
+void SAL_CALL
+ScVbaCharacters::setFont( const uno::Reference< excel::XFont >& /*_font*/ )
+{
+ // #TODO #FIXME needs implementation, or can't be done?
+ throw uno::RuntimeException("Not Implemented" );
+}
+
+// Methods
+void SAL_CALL
+ScVbaCharacters::Insert( const OUString& rString )
+{
+ m_xSimpleText->insertString( m_xTextRange, rString, bReplace );
+}
+
+void SAL_CALL
+ScVbaCharacters::Delete( )
+{
+ // #FIXME #TODO is this a bit suspect? I wonder should the contents
+ // of the cell be deleted from the parent ( range )
+ m_xSimpleText->setString(OUString());
+}
+
+OUString
+ScVbaCharacters::getServiceImplName()
+{
+ return "ScVbaCharacters";
+}
+
+uno::Sequence< OUString >
+ScVbaCharacters::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.Characters"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbacharacters.hxx b/sc/source/ui/vba/vbacharacters.hxx
new file mode 100644
index 000000000..1d9c3c82f
--- /dev/null
+++ b/sc/source/ui/vba/vbacharacters.hxx
@@ -0,0 +1,61 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <ooo/vba/excel/XCharacters.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/text/XSimpleText.hpp>
+
+#include <vbahelper/vbahelperinterface.hxx>
+#include "vbapalette.hxx"
+typedef InheritedHelperInterfaceWeakImpl< ov::excel::XCharacters > ScVbaCharacters_BASE;
+
+class ScVbaCharacters : public ScVbaCharacters_BASE
+{
+private:
+ css::uno::Reference< css::text::XTextRange > m_xTextRange;
+ css::uno::Reference< css::text::XSimpleText > m_xSimpleText;
+ ScVbaPalette m_aPalette;
+ // Add because of MSO has different behavior.
+ bool bReplace;
+public:
+ /// @throws css::lang::IllegalArgumentException
+ /// @throws css::uno::RuntimeException
+ ScVbaCharacters( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const ScVbaPalette& dPalette, const css::uno::Reference< css::text::XSimpleText >& xRange, const css::uno::Any& Start, const css::uno::Any& Length, bool bReplace = false );
+
+ // Attributes
+ virtual OUString SAL_CALL getCaption() override;
+ virtual void SAL_CALL setCaption( const OUString& _caption ) override;
+ virtual ::sal_Int32 SAL_CALL getCount() override;
+ virtual OUString SAL_CALL getText() override;
+ virtual void SAL_CALL setText( const OUString& _text ) override;
+ virtual css::uno::Reference< ov::excel::XFont > SAL_CALL getFont() override;
+ virtual void SAL_CALL setFont( const css::uno::Reference< ov::excel::XFont >& _font ) override;
+
+ // Methods
+ virtual void SAL_CALL Insert( const OUString& String ) override;
+ virtual void SAL_CALL Delete( ) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbachart.cxx b/sc/source/ui/vba/vbachart.cxx
new file mode 100644
index 000000000..5d9cd56a8
--- /dev/null
+++ b/sc/source/ui/vba/vbachart.cxx
@@ -0,0 +1,1056 @@
+/* -*- 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 "vbachart.hxx"
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/chart/XAxisXSupplier.hpp>
+#include <com/sun/star/chart/XAxisYSupplier.hpp>
+#include <com/sun/star/chart/XAxisZSupplier.hpp>
+#include <com/sun/star/chart/XTwoAxisXSupplier.hpp>
+#include <com/sun/star/chart/XTwoAxisYSupplier.hpp>
+#include <com/sun/star/chart/XChartDataArray.hpp>
+#include <com/sun/star/chart/ChartSymbolType.hpp>
+#include <com/sun/star/chart/ChartSolidType.hpp>
+#include <com/sun/star/chart/ChartDataRowSource.hpp>
+#include <ooo/vba/excel/XlChartType.hpp>
+#include <ooo/vba/excel/XlRowCol.hpp>
+#include <ooo/vba/excel/XlAxisType.hpp>
+#include <ooo/vba/excel/XlAxisGroup.hpp>
+
+#include <basic/sberrors.hxx>
+#include "vbachartobject.hxx"
+#include "vbarange.hxx"
+#include "vbacharttitle.hxx"
+#include "vbaaxes.hxx"
+#include <document.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+using namespace ::ooo::vba::excel::XlChartType;
+using namespace ::ooo::vba::excel::XlRowCol;
+using namespace ::ooo::vba::excel::XlAxisType;
+using namespace ::ooo::vba::excel::XlAxisGroup;
+
+constexpr OUStringLiteral CHART_NAME(u"Name");
+// #TODO move this constant to vbaseries.[ch]xx ( when it exists )
+constexpr OUStringLiteral DEFAULTSERIESPREFIX(u"Series");
+constexpr OUStringLiteral DATAROWSOURCE(u"DataRowSource");
+constexpr OUStringLiteral UPDOWN(u"UpDown");
+constexpr OUStringLiteral VOLUME(u"Volume");
+constexpr OUStringLiteral LINES(u"Lines");
+constexpr OUStringLiteral SPLINETYPE(u"SplineType");
+constexpr OUStringLiteral SYMBOLTYPE(u"SymbolType");
+constexpr OUStringLiteral DEEP(u"Deep");
+constexpr OUStringLiteral SOLIDTYPE(u"SolidType");
+constexpr OUStringLiteral VERTICAL(u"Vertical");
+constexpr OUStringLiteral PERCENT(u"Percent");
+constexpr OUStringLiteral STACKED(u"Stacked");
+constexpr OUStringLiteral DIM3D(u"Dim3D");
+constexpr OUStringLiteral HASMAINTITLE(u"HasMainTitle");
+constexpr OUStringLiteral HASLEGEND(u"HasLegend");
+
+ScVbaChart::ScVbaChart( const css::uno::Reference< ov::XHelperInterface >& _xParent, const css::uno::Reference< css::uno::XComponentContext >& _xContext, const css::uno::Reference< css::lang::XComponent >& _xChartComponent, const css::uno::Reference< css::table::XTableChart >& _xTableChart ) : ChartImpl_BASE( _xParent, _xContext ), mxTableChart( _xTableChart )
+{
+ mxChartDocument.set( _xChartComponent, uno::UNO_QUERY_THROW ) ;
+ // #TODO is it possible that the XPropertySet interface is not set
+ // code in setPlotBy seems to indicate that this is possible? but
+ // additionally there is no check in most of the places where it is used
+ // ( and therefore could possibly be NULL )
+ // I'm going to let it throw for the moment ( npower )
+ mxDiagramPropertySet.set( mxChartDocument->getDiagram(), uno::UNO_QUERY_THROW );
+ mxChartPropertySet.set( _xChartComponent, uno::UNO_QUERY_THROW ) ;
+}
+
+OUString SAL_CALL
+ScVbaChart::getName()
+{
+ OUString sName;
+ uno::Reference< beans::XPropertySet > xProps( mxChartDocument, uno::UNO_QUERY_THROW );
+ try
+ {
+ xProps->getPropertyValue( CHART_NAME ) >>= sName;
+ }
+ catch( const uno::Exception & ) // swallow exceptions
+ {
+ }
+ return sName;
+}
+
+uno::Any SAL_CALL
+ScVbaChart::SeriesCollection(const uno::Any&)
+{
+ return uno::Any();
+}
+
+::sal_Int32 SAL_CALL
+ScVbaChart::getChartType()
+{
+ sal_Int32 nChartType = -1;
+ try
+ {
+ OUString sDiagramType = mxChartDocument->getDiagram()->getDiagramType();
+ if ( sDiagramType == "com.sun.star.chart.AreaDiagram" )
+ {
+ if (is3D())
+ {
+ nChartType = getStackedType(xl3DAreaStacked, xl3DAreaStacked100, xl3DArea);
+ }
+ else
+ {
+ nChartType = getStackedType(xlAreaStacked, xlAreaStacked100, xlArea);
+ }
+ }
+ else if ( sDiagramType == "com.sun.star.chart.PieDiagram" )
+ {
+ if (is3D())
+ nChartType = xl3DPie;
+ else
+ nChartType = xlPie; /*TODO XlChartType xlPieExploded, XlChartType xlPieOfPie */
+ }
+ else if ( sDiagramType == "com.sun.star.chart.BarDiagram" )
+ {
+ sal_Int32 nSolidType = chart::ChartSolidType::RECTANGULAR_SOLID;
+ if (mxDiagramPropertySet->getPropertySetInfo()->hasPropertyByName(SOLIDTYPE))
+ { //in 2D diagrams 'SolidType' may not be set
+ if (is3D())
+ mxDiagramPropertySet->getPropertyValue(SOLIDTYPE) >>= nSolidType;
+ }
+ switch (nSolidType)
+ {
+ case chart::ChartSolidType::CONE:
+ nChartType = getSolidType(xlConeCol, xlConeColStacked, xlConeColStacked100, xlConeColClustered, xlConeBarStacked, xlConeBarStacked100, xlConeBarClustered);
+ break;
+ case chart::ChartSolidType::CYLINDER:
+ nChartType = getSolidType(xlCylinderCol, xlCylinderColStacked, xlCylinderColStacked100, xlCylinderColClustered, xlCylinderBarStacked, xlCylinderBarStacked100, xlCylinderBarClustered);
+ break;
+ case chart::ChartSolidType::PYRAMID:
+ nChartType = getSolidType(xlPyramidCol, xlPyramidColStacked, xlPyramidColStacked100, xlPyramidColClustered, xlPyramidBarStacked, xlPyramidBarStacked100, xlPyramidBarClustered);
+ break;
+ default: // RECTANGULAR_SOLID
+ if (is3D())
+ {
+ nChartType = getSolidType(xl3DColumn, xl3DColumnStacked, xl3DColumnStacked100, xl3DColumnClustered, xl3DBarStacked, xl3DBarStacked100, xl3DBarClustered);
+ }
+ else
+ {
+ nChartType = getSolidType(xlColumnClustered, xlColumnStacked, xlColumnStacked100, xlColumnClustered, xlBarStacked, xlBarStacked100, xlBarClustered);
+ }
+ break;
+ }
+ }
+ else if ( sDiagramType == "com.sun.star.chart.StockDiagram" )
+ {
+ bool bVolume = false;
+ mxDiagramPropertySet->getPropertyValue(VOLUME) >>= bVolume;
+ if (bVolume)
+ {
+ nChartType = getStockUpDownValue(xlStockVOHLC, xlStockVHLC);
+ }
+ else
+ {
+ nChartType = getStockUpDownValue(xlStockOHLC, xlStockHLC);
+ }
+ }
+ else if ( sDiagramType == "com.sun.star.chart.XYDiagram" )
+ {
+ bool bHasLines = false;
+ mxDiagramPropertySet->getPropertyValue(LINES) >>= bHasLines;
+ sal_Int32 nSplineType = 0;
+ mxDiagramPropertySet->getPropertyValue(SPLINETYPE) >>= nSplineType;
+ if (nSplineType == 1)
+ {
+ nChartType = getMarkerType(xlXYScatterSmooth, xlXYScatterSmoothNoMarkers);
+ }
+ else if (bHasLines)
+ {
+ nChartType = getMarkerType(xlXYScatterLines, xlXYScatterLinesNoMarkers);
+ }
+ else
+ {
+ nChartType = xlXYScatter;
+ }
+ }
+ else if ( sDiagramType == "com.sun.star.chart.LineDiagram" )
+ {
+ if (is3D())
+ {
+ nChartType = xl3DLine;
+ }
+ else if (hasMarkers())
+ {
+ nChartType = getStackedType(xlLineMarkersStacked, xlLineMarkersStacked100, xlLineMarkers);
+ }
+ else
+ {
+ nChartType = getStackedType(xlLineStacked, xlLineStacked100, xlLine);
+ }
+ }
+ else if ( sDiagramType == "com.sun.star.chart.DonutDiagram" )
+ {
+ nChartType = xlDoughnut; // TODO DoughnutExploded ??
+ }
+ else if ( sDiagramType == "com.sun.star.chart.NetDiagram" )
+ {
+ nChartType = getMarkerType(xlRadarMarkers, xlRadar);
+ }
+ }
+ catch ( const uno::Exception& )
+ {
+ throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
+ }
+ return nChartType;
+}
+
+void SAL_CALL
+ScVbaChart::setChartType( ::sal_Int32 _nChartType )
+{
+ try
+ {
+ switch (_nChartType)
+ {
+ case xlColumnClustered:
+ case xlColumnStacked:
+ case xlColumnStacked100:
+ case xl3DColumnClustered:
+ case xl3DColumnStacked:
+ case xl3DColumnStacked100:
+ case xl3DColumn:
+ case xlBarClustered:
+ case xlBarStacked:
+ case xlBarStacked100:
+ case xl3DBarClustered:
+ case xl3DBarStacked:
+ case xl3DBarStacked100:
+ case xlConeColClustered:
+ case xlConeColStacked:
+ case xlConeColStacked100:
+ case xlConeBarClustered:
+ case xlConeBarStacked:
+ case xlConeBarStacked100:
+ case xlConeCol:
+ case xlPyramidColClustered:
+ case xlPyramidColStacked:
+ case xlPyramidColStacked100:
+ case xlPyramidBarClustered:
+ case xlPyramidBarStacked:
+ case xlPyramidBarStacked100:
+ case xlPyramidCol:
+ case xlCylinderColClustered:
+ case xlCylinderColStacked:
+ case xlCylinderColStacked100:
+ case xlCylinderBarClustered:
+ case xlCylinderBarStacked:
+ case xlCylinderBarStacked100:
+ case xlCylinderCol:
+ case xlSurface: // not possible
+ case xlSurfaceWireframe:
+ case xlSurfaceTopView:
+ case xlSurfaceTopViewWireframe:
+ setDiagram( "com.sun.star.chart.BarDiagram");
+ break;
+ case xlLine:
+ case xl3DLine:
+ case xlLineStacked:
+ case xlLineStacked100:
+ case xlLineMarkers:
+ case xlLineMarkersStacked:
+ case xlLineMarkersStacked100:
+ setDiagram( "com.sun.star.chart.LineDiagram");
+ break;
+ case xl3DArea:
+ case xlArea:
+ case xlAreaStacked:
+ case xlAreaStacked100:
+ case xl3DAreaStacked:
+ case xl3DAreaStacked100:
+ setDiagram( "com.sun.star.chart.AreaDiagram" );
+ break;
+ case xlDoughnut:
+ case xlDoughnutExploded:
+ setDiagram( "com.sun.star.chart.DonutDiagram" );
+ break;
+ case xlStockHLC:
+ case xlStockOHLC:
+ case xlStockVHLC:
+ case xlStockVOHLC:
+ setDiagram( "com.sun.star.chart.StockDiagram");
+ mxDiagramPropertySet->setPropertyValue( UPDOWN, uno::Any((_nChartType == xlStockOHLC) || (_nChartType == xlStockVOHLC)));
+ mxDiagramPropertySet->setPropertyValue( VOLUME, uno::Any((_nChartType == xlStockVHLC) || (_nChartType == xlStockVOHLC)));
+ break;
+
+ case xlPieOfPie: // not possible
+ case xlPieExploded: // SegmentOffset on ChartDataPointProperties -> get from XDiagram //How does Excel do this?
+ case xl3DPieExploded:
+ case xl3DPie:
+ case xlPie:
+ case xlBarOfPie: // not possible (Zoom pie)
+ setDiagram( "com.sun.star.chart.PieDiagram");
+ break;
+
+ case xlRadar:
+ case xlRadarMarkers:
+ case xlRadarFilled:
+ setDiagram( "com.sun.star.chart.NetDiagram");
+ break;
+ case xlXYScatter:
+ case xlBubble: // not possible
+ case xlBubble3DEffect: // not possible
+ case xlXYScatterLines:
+ case xlXYScatterLinesNoMarkers:
+ case xlXYScatterSmooth:
+ case xlXYScatterSmoothNoMarkers:
+ setDiagram( "com.sun.star.chart.XYDiagram");
+ switch(_nChartType)
+ {
+ case xlXYScatter:
+ case xlBubble: // not possible
+ case xlBubble3DEffect: // not possible
+ mxDiagramPropertySet->setPropertyValue(LINES, uno::Any( false ));
+ break;
+ case xlXYScatterLines:
+ case xlXYScatterLinesNoMarkers:
+ mxDiagramPropertySet->setPropertyValue(LINES, uno::Any( true ));
+ break;
+ case xlXYScatterSmooth:
+ case xlXYScatterSmoothNoMarkers:
+ mxDiagramPropertySet->setPropertyValue(SPLINETYPE, uno::Any( sal_Int32(1)));
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_CONVERSION), OUString() );
+ }
+
+ switch (_nChartType)
+ {
+ case xlLineMarkers:
+ case xlLineMarkersStacked:
+ case xlLineMarkersStacked100:
+ case xlRadarMarkers:
+ case xlXYScatterLines:
+ case xlXYScatterSmooth:
+ case xlXYScatter:
+ case xlBubble: // not possible
+ case xlBubble3DEffect: // not possible
+ mxDiagramPropertySet->setPropertyValue(SYMBOLTYPE, uno::Any( chart::ChartSymbolType::AUTO));
+ break;
+ default:
+ if (mxDiagramPropertySet->getPropertySetInfo()->hasPropertyByName(SYMBOLTYPE))
+ {
+ mxDiagramPropertySet->setPropertyValue(SYMBOLTYPE, uno::Any(chart::ChartSymbolType::NONE));
+ }
+ break;
+ }
+
+ switch (_nChartType)
+ {
+ case xlConeCol:
+ case xlPyramidCol:
+ case xlCylinderCol:
+ case xl3DColumn:
+ case xlSurface: // not possible
+ case xlSurfaceWireframe:
+ case xlSurfaceTopView:
+ case xlSurfaceTopViewWireframe:
+ mxDiagramPropertySet->setPropertyValue(DEEP,uno::Any( true ));
+ break;
+ default:
+ if (mxDiagramPropertySet->getPropertySetInfo()->hasPropertyByName(DEEP))
+ {
+ mxDiagramPropertySet->setPropertyValue(DEEP, uno::Any( false));
+ }
+ break;
+ }
+
+ switch (_nChartType)
+ {
+ case xlConeColClustered:
+ case xlConeColStacked:
+ case xlConeColStacked100:
+ case xlConeBarClustered:
+ case xlConeBarStacked:
+ case xlConeBarStacked100:
+ case xlConeCol:
+ mxDiagramPropertySet->setPropertyValue(SOLIDTYPE, uno::Any(chart::ChartSolidType::CONE));
+ break;
+ case xlPyramidColClustered:
+ case xlPyramidColStacked:
+ case xlPyramidColStacked100:
+ case xlPyramidBarClustered:
+ case xlPyramidBarStacked:
+ case xlPyramidBarStacked100:
+ case xlPyramidCol:
+ mxDiagramPropertySet->setPropertyValue(SOLIDTYPE, uno::Any(chart::ChartSolidType::PYRAMID));
+ break;
+ case xlCylinderColClustered:
+ case xlCylinderColStacked:
+ case xlCylinderColStacked100:
+ case xlCylinderBarClustered:
+ case xlCylinderBarStacked:
+ case xlCylinderBarStacked100:
+ case xlCylinderCol:
+ mxDiagramPropertySet->setPropertyValue(SOLIDTYPE, uno::Any(chart::ChartSolidType::CYLINDER));
+ break;
+ default:
+ if (mxDiagramPropertySet->getPropertySetInfo()->hasPropertyByName(SOLIDTYPE))
+ {
+ mxDiagramPropertySet->setPropertyValue(SOLIDTYPE, uno::Any(chart::ChartSolidType::RECTANGULAR_SOLID));
+ }
+ break;
+ }
+
+ switch ( _nChartType)
+ {
+ case xlConeCol:
+ case xlConeColClustered:
+ case xlConeColStacked:
+ case xlConeColStacked100:
+ case xlPyramidColClustered:
+ case xlPyramidColStacked:
+ case xlPyramidColStacked100:
+ case xlCylinderColClustered:
+ case xlCylinderColStacked:
+ case xlCylinderColStacked100:
+ case xlColumnClustered:
+ case xlColumnStacked:
+ case xlColumnStacked100:
+ case xl3DColumnClustered:
+ case xl3DColumnStacked:
+ case xl3DColumnStacked100:
+ case xlSurface: // not possible
+ case xlSurfaceWireframe:
+ case xlSurfaceTopView:
+ case xlSurfaceTopViewWireframe:
+ mxDiagramPropertySet->setPropertyValue(VERTICAL, uno::Any( true));
+ break;
+ default:
+ if (mxDiagramPropertySet->getPropertySetInfo()->hasPropertyByName(VERTICAL))
+ {
+ mxDiagramPropertySet->setPropertyValue(VERTICAL, uno::Any(false));
+ }
+ break;
+ }
+
+ switch (_nChartType)
+ {
+ case xlColumnStacked:
+ case xl3DColumnStacked:
+ case xlBarStacked:
+ case xl3DBarStacked:
+ case xlLineStacked:
+ case xlLineMarkersStacked:
+ case xlAreaStacked:
+ case xl3DAreaStacked:
+ case xlCylinderColStacked:
+ case xlCylinderBarStacked:
+ case xlConeColStacked:
+ case xlConeBarStacked:
+ case xlPyramidColStacked:
+ case xlPyramidBarStacked:
+ mxDiagramPropertySet->setPropertyValue(PERCENT, uno::Any( false ));
+ mxDiagramPropertySet->setPropertyValue(STACKED, uno::Any( true ));
+ break;
+ case xlPyramidColStacked100:
+ case xlPyramidBarStacked100:
+ case xlConeColStacked100:
+ case xlConeBarStacked100:
+ case xlCylinderBarStacked100:
+ case xlCylinderColStacked100:
+ case xl3DAreaStacked100:
+ case xlLineMarkersStacked100:
+ case xlAreaStacked100:
+ case xlLineStacked100:
+ case xl3DBarStacked100:
+ case xlBarStacked100:
+ case xl3DColumnStacked100:
+ case xlColumnStacked100:
+ mxDiagramPropertySet->setPropertyValue(STACKED, uno::Any( true));
+ mxDiagramPropertySet->setPropertyValue(PERCENT, uno::Any( true ));
+ break;
+ default:
+ mxDiagramPropertySet->setPropertyValue(PERCENT, uno::Any( false));
+ mxDiagramPropertySet->setPropertyValue(STACKED, uno::Any( false));
+ break;
+ }
+ switch (_nChartType)
+ {
+ case xl3DArea:
+ case xl3DAreaStacked:
+ case xl3DAreaStacked100:
+ case xl3DBarClustered:
+ case xl3DBarStacked:
+ case xl3DBarStacked100:
+ case xl3DColumn:
+ case xl3DColumnClustered:
+ case xl3DColumnStacked:
+ case xl3DColumnStacked100:
+ case xl3DLine:
+ case xl3DPie:
+ case xl3DPieExploded:
+ case xlConeColClustered:
+ case xlConeColStacked:
+ case xlConeColStacked100:
+ case xlConeBarClustered:
+ case xlConeBarStacked:
+ case xlConeBarStacked100:
+ case xlConeCol:
+ case xlPyramidColClustered:
+ case xlPyramidColStacked:
+ case xlPyramidColStacked100:
+ case xlPyramidBarClustered:
+ case xlPyramidBarStacked:
+ case xlPyramidBarStacked100:
+ case xlPyramidCol:
+ case xlCylinderColClustered:
+ case xlCylinderColStacked:
+ case xlCylinderColStacked100:
+ case xlCylinderBarClustered:
+ case xlCylinderBarStacked:
+ case xlCylinderBarStacked100:
+ case xlCylinderCol:
+ mxDiagramPropertySet->setPropertyValue(DIM3D, uno::Any( true));
+ break;
+ default:
+ if (mxDiagramPropertySet->getPropertySetInfo()->hasPropertyByName(DIM3D))
+ {
+ mxDiagramPropertySet->setPropertyValue(DIM3D, uno::Any( false));
+ }
+ break;
+ }
+ }
+ catch ( const uno::Exception& )
+ {
+ throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
+ }
+}
+
+void SAL_CALL
+ScVbaChart::Activate()
+{
+ // #TODO how are Chart sheets handled ( I know we don't even consider
+ // them in the worksheets/sheets collections ), but...???
+ // note: in vba for excel the parent of a Chart sheet is a workbook,
+ // e.g. 'ThisWorkbook'
+ uno::Reference< XHelperInterface > xParent( getParent() );
+ ScVbaChartObject* pChartObj = static_cast< ScVbaChartObject* >( xParent.get() );
+ if ( !pChartObj )
+ throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), "no ChartObject as parent" );
+
+ pChartObj->Activate();
+
+}
+
+void SAL_CALL
+ScVbaChart::setSourceData( const css::uno::Reference< ::ooo::vba::excel::XRange >& _xCalcRange, const css::uno::Any& _aPlotBy )
+{
+ try
+ {
+ table::CellRangeAddress aSingleRangeAddress;
+
+ uno::Reference< sheet::XCellRangeAddressable > xAddressable( _xCalcRange->getCellRange(), uno::UNO_QUERY_THROW );
+ aSingleRangeAddress = xAddressable->getRangeAddress();
+
+ mxTableChart->setRanges({ aSingleRangeAddress } );
+
+ bool bsetRowHeaders = false;
+ bool bsetColumnHeaders = false;
+
+ ScVbaRange* pRange = static_cast< ScVbaRange* >( _xCalcRange.get() );
+ if ( pRange )
+ {
+ ScDocument& rDoc = pRange->getScDocument();
+ bsetRowHeaders = rDoc.HasRowHeader( static_cast< SCCOL >( aSingleRangeAddress.StartColumn ), static_cast< SCROW >( aSingleRangeAddress.StartRow ), static_cast< SCCOL >( aSingleRangeAddress.EndColumn ), static_cast< SCROW >( aSingleRangeAddress.EndRow ), static_cast< SCTAB >( aSingleRangeAddress.Sheet ) );
+ bsetColumnHeaders = rDoc.HasColHeader( static_cast< SCCOL >( aSingleRangeAddress.StartColumn ), static_cast< SCROW >( aSingleRangeAddress.StartRow ), static_cast< SCCOL >( aSingleRangeAddress.EndColumn ), static_cast< SCROW >( aSingleRangeAddress.EndRow ), static_cast< SCTAB >( aSingleRangeAddress.Sheet ));
+ }
+ mxTableChart->setHasRowHeaders(bsetRowHeaders);
+ mxTableChart->setHasColumnHeaders(bsetColumnHeaders);
+
+ if ((!bsetColumnHeaders) || (!bsetRowHeaders))
+ {
+ uno::Reference< chart::XChartDataArray > xChartDataArray( mxChartDocument->getData(), uno::UNO_QUERY_THROW );
+ if (!bsetColumnHeaders)
+ {
+ xChartDataArray->setColumnDescriptions( getDefaultSeriesDescriptions(xChartDataArray->getColumnDescriptions().getLength() ));
+ }
+ if (!bsetRowHeaders)
+ {
+ xChartDataArray->setRowDescriptions(getDefaultSeriesDescriptions(xChartDataArray->getRowDescriptions().getLength() ));
+ }
+ }
+
+ if ( _aPlotBy.hasValue() )
+ {
+ sal_Int32 nVal = 0;
+ _aPlotBy >>= nVal;
+ setPlotBy( nVal );
+ }
+ else
+ {
+ sal_Int32 nRows = aSingleRangeAddress.EndRow - aSingleRangeAddress.StartRow;
+ sal_Int32 nCols = aSingleRangeAddress.EndColumn - aSingleRangeAddress.StartColumn;
+ // AutoDetect emulation
+ if ( nRows > nCols )
+ setPlotBy( xlColumns );
+ else if ( nRows <= nCols )
+ setPlotBy( xlRows );
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
+ }
+}
+
+uno::Sequence< OUString >
+ScVbaChart::getDefaultSeriesDescriptions( sal_Int32 _nCount )
+{
+ uno::Sequence< OUString > sDescriptions ( _nCount );
+ std::generate_n(sDescriptions.getArray(), _nCount,
+ [i = 1]() mutable -> OUString { return DEFAULTSERIESPREFIX + OUString::number(i++); });
+ return sDescriptions;
+}
+
+void
+ScVbaChart::setDefaultChartType()
+{
+ setChartType( xlColumnClustered );
+}
+
+void
+ScVbaChart::setPlotBy( ::sal_Int32 _nPlotBy )
+{
+ try
+ {
+ if ( !mxDiagramPropertySet.is() )
+ setDefaultChartType();
+ switch (_nPlotBy)
+ {
+ case xlRows:
+ mxDiagramPropertySet->setPropertyValue( DATAROWSOURCE, uno::Any( chart::ChartDataRowSource_ROWS ) );
+ break;
+ case xlColumns:
+ mxDiagramPropertySet->setPropertyValue( DATAROWSOURCE, uno::Any( chart::ChartDataRowSource_COLUMNS) );
+ break;
+ default:
+ throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
+ }
+}
+
+::sal_Int32 SAL_CALL
+ScVbaChart::getPlotBy( )
+{
+ try
+ {
+ chart::ChartDataRowSource aChartDataRowSource;
+ mxDiagramPropertySet->getPropertyValue(DATAROWSOURCE) >>= aChartDataRowSource;
+ if (aChartDataRowSource == chart::ChartDataRowSource_COLUMNS)
+ {
+ return xlColumns;
+ }
+ else
+ {
+ return xlRows;
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
+ }
+}
+
+void
+ScVbaChart::setDiagram( const OUString& _sDiagramType )
+{
+ try
+ {
+ uno::Reference< lang::XMultiServiceFactory > xMSF( mxChartDocument, uno::UNO_QUERY_THROW );
+ uno::Reference< chart::XDiagram > xDiagram( xMSF->createInstance( _sDiagramType ), uno::UNO_QUERY_THROW );
+ mxChartDocument->setDiagram( xDiagram );
+ mxDiagramPropertySet.set( xDiagram, uno::UNO_QUERY_THROW );
+ }
+ catch ( const uno::Exception& )
+ {
+ throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
+ }
+}
+
+// #TODO find out why we have Location/getLocation? there is afaik no
+// Location property, just a Location function for the Chart object
+sal_Int32 SAL_CALL
+ScVbaChart::Location()
+{
+ return getLocation();
+}
+
+sal_Int32 SAL_CALL
+ScVbaChart::getLocation()
+{
+ return -1;
+}
+
+void SAL_CALL
+ScVbaChart::setLocation( ::sal_Int32 /*where*/, const css::uno::Any& /*Name*/ )
+{
+ // Helper api just stubs out the code <shrug>
+ // #TODO come back and make sense out of this
+// String sheetName = null;
+//
+// if ((name != null) && name instanceof String) {
+// sheetName = (String) name;
+// }
+// XSpreadsheetDocument xShDoc = (XSpreadsheetDocument) UnoRuntime.queryInterface( XSpreadsheetDocument.class,getXModel() );
+// com.sun.star.sheet.XSpreadsheets xSheets = xShDoc.Sheets();
+//
+// switch (where) {
+// case ClLocationType.clLocationAsObject_value: //{
+//
+// if (sheetName == null) {
+// DebugHelper.writeInfo("Can't embed in Chart without knowing SheetName");
+// return;
+// }
+//
+// try {
+// Any any = (Any) xSheets.getByName(sheetName);
+// chartSheet = (XSpreadsheet) any.getObject();
+//
+// // chartSheet = (XSpreadsheet) xSheets.getByName( sheetName );
+// } catch (NoSuchElementException e) {
+// // TODO Auto-generated catch block
+// e.printStackTrace();
+//
+// return;
+// } catch (WrappedTargetException e) {
+// // TODO Auto-generated catch block
+// e.printStackTrace();
+//
+// return;
+// } catch (java.lang.Exception e) {
+// e.printStackTrace();
+// }
+//
+// XTableChartsSupplier xTCS = (XTableChartsSupplier) UnoRuntime.queryInterface( XTableChartsSupplier.class, chartSheet);
+// XTableCharts xTableCharts = xTCS.getCharts();
+// XIndexAccess xIA = (XIndexAccess) UnoRuntime.queryInterface( XIndexAccess.class, xTableCharts);
+// int numCharts = xIA.getCount();
+// chartName = "Chart " + (numCharts + 1);
+//
+// //}
+// break;
+//
+// case ClLocationType.clLocationAsNewSheet_value:
+// case ClLocationType.clLocationAutomatic_value:default: //{
+// chartName = "Chart 1"; // Since it's a new sheet, it's the first on it...
+//
+// XIndexAccess xSheetIA = (XIndexAccess) UnoRuntime.queryInterface( XIndexAccess.class, xSheets);
+//
+// short newSheetNum = (short) (xSheetIA.getCount() + 1);
+//
+// if (sheetName == null){
+// sheetName = "ChartSheet " + newSheetNum; // Why not?
+// }
+// // DPK TODO : Probably should use Sheets to create this!
+// xSheets.insertNewByName(sheetName, newSheetNum);
+//
+// try {
+// chartSheet =
+// (XSpreadsheet) xSheets.getByName(sheetName);
+// } catch (NoSuchElementException e) {
+// // TODO Auto-generated catch block
+// e.printStackTrace();
+//
+// return;
+// } catch (WrappedTargetException e) {
+// // TODO Auto-generated catch block
+// e.printStackTrace();
+//
+// return;
+// }
+//
+// //}
+// break;
+// }
+//
+// // Last thing should be a call to createChartForReal(), one of them
+// // should succeed.
+// createChartForReal();
+
+}
+
+sal_Bool SAL_CALL
+ScVbaChart::getHasTitle( )
+{
+ bool bHasTitle = false;
+ try
+ {
+ mxChartPropertySet->getPropertyValue(HASMAINTITLE) >>= bHasTitle;
+ }
+ catch (const uno::Exception&)
+ {
+ throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
+ }
+ return bHasTitle;
+}
+
+void SAL_CALL
+ScVbaChart::setHasTitle( sal_Bool bTitle )
+{
+ try
+ {
+ mxChartPropertySet->setPropertyValue(HASMAINTITLE, uno::Any( bTitle ));
+ }
+ catch (const uno::Exception&)
+ {
+ throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
+ }
+
+}
+
+sal_Bool SAL_CALL
+ScVbaChart::getHasLegend( )
+{
+ bool bHasLegend = false;
+ try
+ {
+ mxChartPropertySet->getPropertyValue(HASLEGEND) >>= bHasLegend;
+ }
+ catch (const uno::Exception&)
+ {
+ throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
+ }
+ return bHasLegend;
+}
+
+void SAL_CALL
+ScVbaChart::setHasLegend( sal_Bool bLegend )
+{
+ try
+ {
+ mxChartPropertySet->setPropertyValue(HASLEGEND, uno::Any(bLegend));
+ }
+ catch (const uno::Exception&)
+ {
+ throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
+ }
+}
+
+uno::Reference< excel::XChartTitle > SAL_CALL
+ScVbaChart::getChartTitle( )
+{
+ uno::Reference< drawing::XShape > xTitleShape = mxChartDocument->getTitle();
+ // #TODO check parent
+ return new ScVbaChartTitle(this, mxContext, xTitleShape);
+}
+
+uno::Any SAL_CALL
+ScVbaChart::Axes( const uno::Any& Type, const uno::Any& AxisGroup )
+{
+ // mmm chart probably is the parent, #TODO check parent
+ uno::Reference< excel::XAxes > xAxes = new ScVbaAxes( this, mxContext, this );
+ if ( !Type.hasValue() )
+ return uno::Any( xAxes );
+ return xAxes->Item( Type, AxisGroup );
+}
+bool
+ScVbaChart::is3D()
+{
+ // #TODO perhaps provide limited Debughelper functionality
+ bool is3d = false;
+ mxDiagramPropertySet->getPropertyValue(DIM3D) >>= is3d;
+ return is3d;
+}
+
+sal_Int32
+ScVbaChart::getStackedType( sal_Int32 _nStacked, sal_Int32 _n100PercentStacked, sal_Int32 _nUnStacked )
+{
+ // #TODO perhaps provide limited Debughelper functionality
+ if (isStacked())
+ {
+ if (is100PercentStacked())
+ return _n100PercentStacked;
+ else
+ return _nStacked;
+ }
+ else
+ return _nUnStacked;
+}
+
+bool
+ScVbaChart::isStacked()
+{
+ // #TODO perhaps provide limited Debughelper functionality
+ bool bStacked = false;
+ mxDiagramPropertySet->getPropertyValue(STACKED) >>= bStacked;
+ return bStacked;
+}
+
+bool
+ScVbaChart::is100PercentStacked()
+{
+ // #TODO perhaps provide limited Debughelper functionality
+ bool b100Percent = false;
+ mxDiagramPropertySet->getPropertyValue(PERCENT) >>= b100Percent;
+ return b100Percent;
+}
+
+sal_Int32
+ScVbaChart::getSolidType(sal_Int32 _nDeep, sal_Int32 _nVertiStacked, sal_Int32 _nVerti100PercentStacked, sal_Int32 _nVertiUnStacked, sal_Int32 _nHoriStacked, sal_Int32 _nHori100PercentStacked, sal_Int32 _nHoriUnStacked)
+{
+ try
+ {
+ bool bIsVertical = true;
+ mxDiagramPropertySet->getPropertyValue(VERTICAL) >>= bIsVertical;
+ bool bIsDeep = false;
+ mxDiagramPropertySet->getPropertyValue(DEEP) >>= bIsDeep;
+
+ if (bIsDeep)
+ {
+ return _nDeep;
+ }
+ else
+ {
+ if (bIsVertical)
+ {
+ return getStackedType(_nVertiStacked, _nVerti100PercentStacked, _nVertiUnStacked);
+ }
+ else
+ {
+ return getStackedType(_nHoriStacked, _nHori100PercentStacked, _nHoriUnStacked);
+ }
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
+ }
+}
+
+sal_Int32
+ScVbaChart::getStockUpDownValue(sal_Int32 _nUpDown, sal_Int32 _nNotUpDown)
+{
+ try
+ {
+ bool bUpDown = false;
+ mxDiagramPropertySet->getPropertyValue(UPDOWN) >>= bUpDown;
+ if (bUpDown)
+ {
+ return _nUpDown;
+ }
+ else
+ {
+ return _nNotUpDown;
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
+ }
+}
+
+bool
+ScVbaChart::hasMarkers()
+{
+ bool bHasMarkers = false;
+ try
+ {
+ sal_Int32 nSymbol=0;
+ mxDiagramPropertySet->getPropertyValue(SYMBOLTYPE) >>= nSymbol;
+ bHasMarkers = nSymbol != chart::ChartSymbolType::NONE;
+ }
+ catch (const uno::Exception&)
+ {
+ throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
+ }
+ return bHasMarkers;
+}
+
+sal_Int32
+ScVbaChart::getMarkerType(sal_Int32 _nWithMarkers, sal_Int32 _nWithoutMarkers)
+{
+ if (hasMarkers())
+ return _nWithMarkers;
+ return _nWithoutMarkers;
+}
+
+void
+ScVbaChart::assignDiagramAttributes()
+{
+ xAxisXSupplier.set( mxDiagramPropertySet, uno::UNO_QUERY_THROW );
+ xAxisYSupplier.set( mxDiagramPropertySet, uno::UNO_QUERY_THROW );
+ xAxisZSupplier.set( mxDiagramPropertySet, uno::UNO_QUERY_THROW );
+ xTwoAxisXSupplier.set( mxDiagramPropertySet, uno::UNO_QUERY_THROW );
+ xTwoAxisYSupplier.set( mxDiagramPropertySet, uno::UNO_QUERY_THROW );
+}
+
+uno::Reference< beans::XPropertySet >
+ScVbaChart::getAxisPropertySet(sal_Int32 _nAxisType, sal_Int32 _nAxisGroup)
+{
+ assignDiagramAttributes();
+ uno::Reference< beans::XPropertySet > xAxisProps;
+ switch(_nAxisType)
+ {
+ case xlCategory:
+ if (_nAxisGroup == xlPrimary)
+ {
+ xAxisProps = xAxisXSupplier->getXAxis();
+ }
+ else if (_nAxisGroup == xlSecondary)
+ {
+ xAxisProps = xTwoAxisXSupplier->getSecondaryXAxis();
+ }
+ break;
+ case xlSeriesAxis:
+ xAxisProps = xAxisZSupplier->getZAxis();
+ break;
+ case xlValue:
+ if (_nAxisGroup == xlPrimary)
+ xAxisProps = xAxisYSupplier->getYAxis();
+ else if (_nAxisGroup == xlSecondary)
+ xAxisProps = xTwoAxisYSupplier->getSecondaryYAxis();
+ break;
+ default:
+ return xAxisProps;
+ }
+ return xAxisProps;
+}
+
+OUString
+ScVbaChart::getServiceImplName()
+{
+ return "ScVbaChart";
+}
+
+uno::Sequence< OUString >
+ScVbaChart::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.Chart"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbachart.hxx b/sc/source/ui/vba/vbachart.hxx
new file mode 100644
index 000000000..eedf13b9f
--- /dev/null
+++ b/sc/source/ui/vba/vbachart.hxx
@@ -0,0 +1,103 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/table/XTableChart.hpp>
+#include <com/sun/star/chart/XChartDocument.hpp>
+#include <com/sun/star/chart/XAxisXSupplier.hpp>
+#include <com/sun/star/chart/XAxisYSupplier.hpp>
+#include <com/sun/star/chart/XAxisZSupplier.hpp>
+#include <com/sun/star/chart/XTwoAxisXSupplier.hpp>
+#include <com/sun/star/chart/XTwoAxisYSupplier.hpp>
+#include <ooo/vba/excel/XChart.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+
+typedef InheritedHelperInterfaceWeakImpl<ov::excel::XChart > ChartImpl_BASE;
+
+class ScVbaChart : public ChartImpl_BASE
+{
+friend class ScVbaAxis;
+
+ css::uno::Reference< css::chart::XChartDocument > mxChartDocument;
+ css::uno::Reference< css::table::XTableChart > mxTableChart;
+ css::uno::Reference< css::beans::XPropertySet > mxDiagramPropertySet;
+ css::uno::Reference< css::beans::XPropertySet > mxChartPropertySet;
+ css::uno::Reference< css::chart::XAxisXSupplier > xAxisXSupplier;
+ css::uno::Reference< css::chart::XAxisYSupplier> xAxisYSupplier;
+ css::uno::Reference< css::chart::XAxisZSupplier > xAxisZSupplier;
+ css::uno::Reference< css::chart::XTwoAxisXSupplier > xTwoAxisXSupplier;
+ css::uno::Reference< css::chart::XTwoAxisYSupplier > xTwoAxisYSupplier;
+
+ static css::uno::Sequence< OUString > getDefaultSeriesDescriptions( sal_Int32 nCount );
+ /// @throws css::script::BasicErrorException
+ void setDefaultChartType() ;
+ /// @throws css::script::BasicErrorException
+ void setDiagram( const OUString& _sDiagramType);
+ /// @throws css::uno::RuntimeException
+ bool isStacked();
+ /// @throws css::uno::RuntimeException
+ bool is100PercentStacked();
+ /// @throws css::uno::RuntimeException
+ sal_Int32 getStackedType( sal_Int32 _nStacked, sal_Int32 _n100PercentStacked, sal_Int32 _nUnStacked );
+ /// @throws css::script::BasicErrorException
+ sal_Int32 getSolidType(sal_Int32 _nDeep, sal_Int32 _nVertiStacked, sal_Int32 _nVerti100PercentStacked, sal_Int32 _nVertiUnStacked, sal_Int32 _nHoriStacked, sal_Int32 _nHori100PercentStacked, sal_Int32 _nHoriUnStacked);
+ /// @throws css::script::BasicErrorException
+ sal_Int32 getStockUpDownValue(sal_Int32 _nUpDown, sal_Int32 _nNotUpDown);
+ /// @throws css::script::BasicErrorException
+ bool hasMarkers();
+ /// @throws css::script::BasicErrorException
+ sal_Int32 getMarkerType(sal_Int32 _nWithMarkers, sal_Int32 _nWithoutMarkers);
+ void assignDiagramAttributes();
+public:
+ ScVbaChart( const css::uno::Reference< ov::XHelperInterface >& _xParent, const css::uno::Reference< css::uno::XComponentContext >& _xContext, const css::uno::Reference< css::lang::XComponent >& _xChartComponent, const css::uno::Reference< css::table::XTableChart >& _xTableChart );
+
+ // Non-interface
+ const css::uno::Reference< css::beans::XPropertySet >& xDiagramPropertySet() const { return mxDiagramPropertySet; }
+ /// @throws css::uno::RuntimeException
+ bool is3D();
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference< css::beans::XPropertySet > getAxisPropertySet(sal_Int32 _nAxisType, sal_Int32 _nAxisGroup);
+ // Methods
+ virtual OUString SAL_CALL getName() override;
+ virtual css::uno::Any SAL_CALL SeriesCollection(const css::uno::Any&) override;
+ virtual ::sal_Int32 SAL_CALL getChartType() override;
+ virtual void SAL_CALL setChartType( ::sal_Int32 _charttype ) override;
+ virtual void SAL_CALL Activate( ) override;
+ virtual void SAL_CALL setSourceData( const css::uno::Reference< ::ooo::vba::excel::XRange >& range, const css::uno::Any& PlotBy ) override;
+ virtual ::sal_Int32 SAL_CALL Location( ) override;
+ virtual ::sal_Int32 SAL_CALL getLocation( ) override;
+ virtual void SAL_CALL setLocation( ::sal_Int32 where, const css::uno::Any& Name ) override;
+ virtual sal_Bool SAL_CALL getHasTitle( ) override;
+ virtual void SAL_CALL setHasTitle( sal_Bool bTitle ) override;
+ virtual sal_Bool SAL_CALL getHasLegend( ) override;
+ virtual void SAL_CALL setHasLegend( sal_Bool bLegend ) override;
+ virtual void SAL_CALL setPlotBy( ::sal_Int32 xlRowCol ) override;
+ virtual ::sal_Int32 SAL_CALL getPlotBy( ) override;
+ virtual css::uno::Reference< ov::excel::XChartTitle > SAL_CALL getChartTitle( ) override;
+ virtual css::uno::Any SAL_CALL Axes( const css::uno::Any& Type, const css::uno::Any& AxisGroup ) override;
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbachartobject.cxx b/sc/source/ui/vba/vbachartobject.cxx
new file mode 100644
index 000000000..5246a9040
--- /dev/null
+++ b/sc/source/ui/vba/vbachartobject.cxx
@@ -0,0 +1,147 @@
+/* -*- 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 "vbachart.hxx"
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/document/XEmbeddedObjectSupplier.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/script/BasicErrorException.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+#include <basic/sberrors.hxx>
+#include "vbachartobject.hxx"
+#include "vbachartobjects.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+constexpr OUStringLiteral PERSIST_NAME(u"PersistName");
+
+ScVbaChartObject::ScVbaChartObject( const css::uno::Reference< ov::XHelperInterface >& _xParent, const css::uno::Reference< css::uno::XComponentContext >& _xContext, const css::uno::Reference< css::table::XTableChart >& _xTableChart, const css::uno::Reference< css::drawing::XDrawPageSupplier >& _xDrawPageSupplier ) : ChartObjectImpl_BASE( _xParent, _xContext ), xTableChart( _xTableChart ), xDrawPageSupplier( _xDrawPageSupplier )
+{
+ xDrawPage = xDrawPageSupplier->getDrawPage();
+ xEmbeddedObjectSupplier.set( xTableChart, uno::UNO_QUERY_THROW );
+ xNamed.set( xTableChart, uno::UNO_QUERY_THROW );
+ sPersistName = getPersistName();
+ xShape = setShape();
+ setName(sPersistName);
+ oShapeHelper.reset(new ShapeHelper(xShape));
+}
+
+OUString const & ScVbaChartObject::getPersistName()
+{
+ if ( sPersistName.isEmpty() )
+ sPersistName = xNamed->getName();
+ return sPersistName;
+}
+
+uno::Reference< drawing::XShape >
+ScVbaChartObject::setShape()
+{
+ try
+ {
+ sal_Int32 nItems = xDrawPage->getCount();
+ for (int i = 0; i < nItems; i++)
+ {
+ xShape.set( xDrawPage->getByIndex(i), uno::UNO_QUERY_THROW );
+ if (xShape->getShapeType() == "com.sun.star.drawing.OLE2Shape")
+ {
+ uno::Reference< beans::XPropertySet > xShapePropertySet(xShape, uno::UNO_QUERY_THROW );
+ OUString sName;
+ xShapePropertySet->getPropertyValue(PERSIST_NAME ) >>=sName;
+ if ( sName == sPersistName )
+ {
+ xNamedShape.set( xShape, uno::UNO_QUERY_THROW );
+ return xShape;
+ }
+ }
+ }
+ }
+ catch (uno::Exception& )
+ {
+ throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
+ }
+ return nullptr;
+}
+
+void SAL_CALL
+ScVbaChartObject::setName( const OUString& sName )
+{
+ xNamedShape->setName(sName);
+}
+
+OUString SAL_CALL
+ScVbaChartObject::getName()
+{
+ return xNamedShape->getName();
+}
+
+void SAL_CALL
+ScVbaChartObject::Delete()
+{
+ // parent of this object is sheet
+ uno::Reference< excel::XWorksheet > xParent( getParent(), uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XChartObjects > xColl( xParent->ChartObjects( uno::Any() ), uno::UNO_QUERY_THROW );
+ ScVbaChartObjects* pChartObjectsImpl = static_cast< ScVbaChartObjects* >( xColl.get() );
+ if (!pChartObjectsImpl)
+ throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), "Parent is not ChartObjects" );
+
+ pChartObjectsImpl->removeByName( getPersistName() );
+
+}
+
+void
+ScVbaChartObject::Activate()
+{
+ try
+ {
+ // #TODO #FIXME should be ThisWorkbook or equivalent, or in
+ // fact probably the chart object should be created with
+ // the XModel owner
+ //uno::Reference< view::XSelectionSupplier > xSelectionSupplier( getXModel().getCurrentController());
+ uno::Reference< view::XSelectionSupplier > xSelectionSupplier( getCurrentExcelDoc(mxContext)->getCurrentController(), uno::UNO_QUERY_THROW );
+ xSelectionSupplier->select(uno::Any(xShape));
+ }
+ catch (uno::Exception& )
+ {
+ throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), "ChartObject Activate internal error" );
+ }
+}
+
+uno::Reference< excel::XChart > SAL_CALL
+ScVbaChartObject::getChart()
+{
+ return new ScVbaChart( this, mxContext, xEmbeddedObjectSupplier->getEmbeddedObject(), xTableChart );
+}
+
+OUString
+ScVbaChartObject::getServiceImplName()
+{
+ return "ScVbaChartObject";
+}
+
+uno::Sequence< OUString >
+ScVbaChartObject::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.ChartObject"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbachartobject.hxx b/sc/source/ui/vba/vbachartobject.hxx
new file mode 100644
index 000000000..85a014052
--- /dev/null
+++ b/sc/source/ui/vba/vbachartobject.hxx
@@ -0,0 +1,61 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/table/XTableChart.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/document/XEmbeddedObjectSupplier.hpp>
+#include <ooo/vba/excel/XChartObject.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <memory>
+
+typedef InheritedHelperInterfaceWeakImpl<ov::excel::XChartObject > ChartObjectImpl_BASE;
+
+class ScVbaChartObject : public ChartObjectImpl_BASE
+{
+
+ css::uno::Reference< css::table::XTableChart > xTableChart;
+ css::uno::Reference< css::document::XEmbeddedObjectSupplier > xEmbeddedObjectSupplier;
+ css::uno::Reference< css::drawing::XDrawPageSupplier > xDrawPageSupplier;
+ css::uno::Reference< css::drawing::XDrawPage > xDrawPage;
+ css::uno::Reference< css::drawing::XShape > xShape;
+ css::uno::Reference< css::container::XNamed > xNamed;
+ OUString sPersistName;
+ std::unique_ptr<ov::ShapeHelper> oShapeHelper;
+ css::uno::Reference< css::container::XNamed > xNamedShape;
+ OUString const & getPersistName();
+ /// @throws css::script::BasicErrorException
+ css::uno::Reference< css::drawing::XShape > setShape();
+public:
+ ScVbaChartObject( const css::uno::Reference< ov::XHelperInterface >& _xParent, const css::uno::Reference< css::uno::XComponentContext >& _xContext, const css::uno::Reference< css::table::XTableChart >& _xTableChart, const css::uno::Reference< css::drawing::XDrawPageSupplier >& _xDrawPageSupplier );
+ virtual OUString SAL_CALL getName() override;
+ virtual void SAL_CALL setName( const OUString& sName ) override;
+ virtual css::uno::Reference< ov::excel::XChart > SAL_CALL getChart() override;
+ virtual void SAL_CALL Delete() override;
+ /// @throws css::script::BasicErrorException
+ void Activate();
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbachartobjects.cxx b/sc/source/ui/vba/vbachartobjects.cxx
new file mode 100644
index 000000000..674c92511
--- /dev/null
+++ b/sc/source/ui/vba/vbachartobjects.cxx
@@ -0,0 +1,206 @@
+/* -*- 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/table/XTableChartsSupplier.hpp>
+#include <com/sun/star/table/XTableChart.hpp>
+#include <com/sun/star/script/BasicErrorException.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <ooo/vba/excel/XlChartType.hpp>
+
+#include "vbachartobjects.hxx"
+#include "vbachartobject.hxx"
+#include <docsh.hxx>
+#include <cellsuno.hxx>
+
+#include <string_view>
+#include <vector>
+#include <basic/sberrors.hxx>
+#include <comphelper/sequence.hxx>
+#include <tools/diagnose_ex.h>
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+namespace {
+
+class ChartObjectEnumerationImpl : public EnumerationHelperImpl
+{
+ uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier;
+
+public:
+ /// @throws uno::RuntimeException
+ ChartObjectEnumerationImpl( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Reference< drawing::XDrawPageSupplier >& _xDrawPageSupplier, const uno::Reference< XHelperInterface >& _xParent ) : EnumerationHelperImpl( _xParent, xContext, xEnumeration ), xDrawPageSupplier( _xDrawPageSupplier ) {}
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ uno::Any ret;
+
+ try
+ {
+ uno::Reference< table::XTableChart > xTableChart( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW );
+ // parent Object is sheet
+ ret <<= uno::Reference< excel::XChartObject > ( new ScVbaChartObject( m_xParent, m_xContext, xTableChart, xDrawPageSupplier ) );
+ }
+ catch (const lang::WrappedTargetException&)
+ {
+ throw;
+ }
+ catch (const container::NoSuchElementException&)
+ {
+ throw;
+ }
+ catch (const uno::RuntimeException&)
+ {
+ throw;
+ }
+ catch (const uno::Exception&)
+ {
+ css::uno::Any anyEx(cppu::getCaughtException());
+ throw lang::WrappedTargetException(
+ "Error creating ScVbaChartObject!",
+ static_cast < OWeakObject * > ( this ),
+ anyEx );
+ }
+ return ret;
+ }
+};
+
+}
+
+ScVbaChartObjects::ScVbaChartObjects( const css::uno::Reference< ov::XHelperInterface >& _xParent, const css::uno::Reference< css::uno::XComponentContext >& _xContext, const css::uno::Reference< css::table::XTableCharts >& _xTableCharts, const uno::Reference< drawing::XDrawPageSupplier >& _xDrawPageSupplier ) : ChartObjects_BASE(_xParent, _xContext, css::uno::Reference< css::container::XIndexAccess >( _xTableCharts, css::uno::UNO_QUERY ) ), xTableCharts( _xTableCharts ) , xDrawPageSupplier( _xDrawPageSupplier )
+{
+
+}
+
+void
+ScVbaChartObjects::removeByName(const OUString& _sChartName)
+{
+ xTableCharts->removeByName( _sChartName );
+}
+
+uno::Sequence< OUString >
+ScVbaChartObjects::getChartObjectNames() const
+{
+ uno::Sequence< OUString > sChartNames;
+ try
+ {
+ // c++ hackery
+ uno::Reference< uno::XInterface > xIf( xDrawPageSupplier, uno::UNO_QUERY_THROW );
+ ScCellRangesBase* pUno= dynamic_cast< ScCellRangesBase* >( xIf.get() );
+ ScDocShell* pDocShell = nullptr;
+ if ( !pUno )
+ throw uno::RuntimeException("Failed to obtain the impl class from the drawpage" );
+ pDocShell = pUno->GetDocShell();
+ if ( !pDocShell )
+ throw uno::RuntimeException("Failed to obtain the docshell implclass" );
+
+ uno::Reference< sheet::XSpreadsheetDocument > xSpreadsheetDocument( pDocShell->GetModel(), uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XSpreadsheets > xSpreadsheets = xSpreadsheetDocument->getSheets();
+ std::vector< OUString > aChartNamesVector;
+
+ const uno::Sequence< OUString > sSheetNames = xSpreadsheets->getElementNames();
+ for (const auto& rSheetName : sSheetNames)
+ {
+ uno::Reference< table::XTableChartsSupplier > xLocTableChartsSupplier( xSpreadsheets->getByName(rSheetName), uno::UNO_QUERY_THROW );
+ const uno::Sequence< OUString > scurchartnames = xLocTableChartsSupplier->getCharts()->getElementNames();
+ aChartNamesVector.insert( aChartNamesVector.end(), scurchartnames.begin(), scurchartnames.end() );
+ }
+ sChartNames = comphelper::containerToSequence( aChartNamesVector );
+ }
+ catch (uno::Exception& )
+ {
+ throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
+ }
+ return sChartNames;
+}
+
+// XChartObjects
+uno::Any SAL_CALL
+ScVbaChartObjects::Add( double _nX, double _nY, double _nWidth, double _nHeight )
+{
+ try
+ {
+ uno::Sequence< table::CellRangeAddress > aCellRangeAddress( 1 );
+ awt::Rectangle aRectangle;
+ aRectangle.X = Millimeter::getInHundredthsOfOneMillimeter(_nX);
+ aRectangle.Y = Millimeter::getInHundredthsOfOneMillimeter(_nY);
+ aRectangle.Width = Millimeter::getInHundredthsOfOneMillimeter(_nWidth);
+ aRectangle.Height = Millimeter::getInHundredthsOfOneMillimeter(_nHeight);
+ // Note the space at the end of the stem ("Chart "). In ChartSheets only "Chart" is the stem
+ OUString sPersistChartName = ContainerUtilities::getUniqueName( getChartObjectNames(), "Chart " , std::u16string_view(), 1);
+ xTableCharts->addNewByName(sPersistChartName, aRectangle, aCellRangeAddress, true, false );
+ uno::Reference< excel::XChartObject > xChartObject( getItemByStringIndex( sPersistChartName ), uno::UNO_QUERY_THROW );
+ xChartObject->getChart()->setChartType(excel::XlChartType::xlColumnClustered);
+ return uno::Any( xChartObject );
+ }
+ catch (const uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("sc");
+ }
+ return aNULL();
+}
+void SAL_CALL ScVbaChartObjects::Delete( )
+{
+ const uno::Sequence< OUString > sChartNames = xTableCharts->getElementNames();
+ for (const auto& rChartName : sChartNames)
+ removeByName(rChartName);
+}
+
+// XEnumerationAccess
+
+uno::Reference< container::XEnumeration >
+ScVbaChartObjects::createEnumeration()
+{
+ css::uno::Reference< container::XEnumerationAccess > xEnumAccess( xTableCharts, uno::UNO_QUERY_THROW );
+ return new ChartObjectEnumerationImpl( mxContext, xEnumAccess->createEnumeration(), xDrawPageSupplier, getParent() /* sheet */);
+}
+
+// XElementAccess
+
+uno::Type
+ScVbaChartObjects::getElementType()
+{
+ return cppu::UnoType<excel::XChartObject>::get();
+}
+
+// ScVbaCollectionBaseImpl
+uno::Any
+ScVbaChartObjects::createCollectionObject( const css::uno::Any& aSource )
+{
+ uno::Reference< table::XTableChart > xTableChart( aSource, uno::UNO_QUERY_THROW );
+ // correct parent object is sheet
+ return uno::Any( uno::Reference< excel::XChartObject > ( new ScVbaChartObject( getParent(), mxContext, xTableChart, xDrawPageSupplier ) ) );
+}
+
+OUString
+ScVbaChartObjects::getServiceImplName()
+{
+ return "ScVbaChartObjects";
+}
+
+css::uno::Sequence<OUString>
+ScVbaChartObjects::getServiceNames()
+{
+ static uno::Sequence< OUString > const sNames
+ {
+ "ooo.vba.excel.ChartObjects"
+ };
+ return sNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbachartobjects.hxx b/sc/source/ui/vba/vbachartobjects.hxx
new file mode 100644
index 000000000..ce116e734
--- /dev/null
+++ b/sc/source/ui/vba/vbachartobjects.hxx
@@ -0,0 +1,60 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <ooo/vba/excel/XChartObjects.hpp>
+#include <vbahelper/vbacollectionimpl.hxx>
+
+namespace com::sun::star::container { class XEnumeration; }
+namespace com::sun::star::drawing { class XDrawPageSupplier; }
+namespace com::sun::star::table { class XTableCharts; }
+namespace com::sun::star::uno { class XComponentContext; }
+
+typedef CollTestImplHelper< ov::excel::XChartObjects > ChartObjects_BASE;
+
+class ScVbaChartObjects : public ChartObjects_BASE
+{
+
+ css::uno::Reference< css::table::XTableCharts > xTableCharts;
+ css::uno::Reference< css::drawing::XDrawPageSupplier > xDrawPageSupplier;
+ // method associated with populating the hashmap ( I'm not convinced this is necessary )
+ //css::uno::Reference< ov::excel::XChartObject > putByPersistName( const rtl:::OUString& _sPersistChartName );
+public:
+ ScVbaChartObjects( const css::uno::Reference< ov::XHelperInterface >& _xParent, const css::uno::Reference< css::uno::XComponentContext >& _xContext, const css::uno::Reference< css::table::XTableCharts >& _xTableCharts, const css::uno::Reference< css::drawing::XDrawPageSupplier >& _xDrawPageSupplier );
+
+ /// @throws css::script::BasicErrorException
+ css::uno::Sequence< OUString > getChartObjectNames() const;
+ void removeByName(const OUString& _sChartName);
+
+ // XChartObjects
+ virtual css::uno::Any SAL_CALL Add( double Left, double Top, double Width, double Height ) override;
+ virtual void SAL_CALL Delete( ) override;
+ // XEnumerationAccess
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+ // XElementAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ // ScVbaCollectionBaseImpl
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+ // ChartObjects_BASE
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbacharttitle.cxx b/sc/source/ui/vba/vbacharttitle.cxx
new file mode 100644
index 000000000..2e881fd61
--- /dev/null
+++ b/sc/source/ui/vba/vbacharttitle.cxx
@@ -0,0 +1,44 @@
+/* -*- 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 "vbacharttitle.hxx"
+#include <comphelper/sequence.hxx>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+ScVbaChartTitle::ScVbaChartTitle( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< drawing::XShape >& _xTitleShape ) : ChartTitleBase( xParent, xContext, _xTitleShape )
+{
+}
+
+OUString
+ScVbaChartTitle::getServiceImplName()
+{
+ return "ScVbaChartTitle";
+}
+
+uno::Sequence< OUString >
+ScVbaChartTitle::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames = comphelper::concatSequences(
+ ChartTitleBase::getServiceNames(),
+ uno::Sequence< OUString > { "ooo.vba.excel.Chart" } );
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbacharttitle.hxx b/sc/source/ui/vba/vbacharttitle.hxx
new file mode 100644
index 000000000..2b816357e
--- /dev/null
+++ b/sc/source/ui/vba/vbacharttitle.hxx
@@ -0,0 +1,35 @@
+/* -*- 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 .
+ */
+#pragma once
+#include "vbatitle.hxx"
+#include <cppuhelper/implbase.hxx>
+#include <ooo/vba/excel/XChartTitle.hpp>
+
+typedef TitleImpl< cppu::WeakImplHelper< ov::excel::XChartTitle > > ChartTitleBase;
+
+class ScVbaChartTitle : public ChartTitleBase
+{
+public:
+ ScVbaChartTitle( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::drawing::XShape >& _xTitleShape );
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbacomment.cxx b/sc/source/ui/vba/vbacomment.cxx
new file mode 100644
index 000000000..a9b1cf7c4
--- /dev/null
+++ b/sc/source/ui/vba/vbacomment.cxx
@@ -0,0 +1,234 @@
+/* -*- 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 "vbacomment.hxx"
+
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XSheetAnnotationAnchor.hpp>
+#include <com/sun/star/sheet/XSheetAnnotationsSupplier.hpp>
+#include <com/sun/star/sheet/XSheetAnnotationShapeSupplier.hpp>
+#include <com/sun/star/sheet/XSheetCellRange.hpp>
+#include <com/sun/star/sheet/XCellAddressable.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/table/XCell.hpp>
+#include <com/sun/star/text/XSimpleText.hpp>
+#include <com/sun/star/text/XTextCursor.hpp>
+#include <com/sun/star/text/XTextRange.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <ooo/vba/office/MsoShapeType.hpp>
+
+#include <vbahelper/vbashape.hxx>
+#include <sal/log.hxx>
+#include "vbacomments.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+ScVbaComment::ScVbaComment(
+ const uno::Reference< XHelperInterface >& xParent,
+ const uno::Reference< uno::XComponentContext >& xContext,
+ const uno::Reference< frame::XModel >& xModel,
+ const uno::Reference< table::XCellRange >& xRange ) :
+ ScVbaComment_BASE( xParent, xContext ),
+ mxModel( xModel, uno::UNO_SET_THROW ),
+ mxRange( xRange )
+{
+ if ( !xRange.is() )
+ throw lang::IllegalArgumentException("range is not set ", uno::Reference< uno::XInterface >() , 1 );
+ getAnnotation();
+}
+
+// private helper functions
+
+uno::Reference< sheet::XSheetAnnotation >
+ScVbaComment::getAnnotation()
+{
+ uno::Reference< table::XCell > xCell( mxRange->getCellByPosition(0, 0), uno::UNO_SET_THROW );
+ uno::Reference< sheet::XSheetAnnotationAnchor > xAnnoAnchor( xCell, uno::UNO_QUERY_THROW );
+ return uno::Reference< sheet::XSheetAnnotation > ( xAnnoAnchor->getAnnotation(), uno::UNO_SET_THROW );
+}
+
+uno::Reference< sheet::XSheetAnnotations >
+ScVbaComment::getAnnotations() const
+{
+ uno::Reference< sheet::XSheetCellRange > xSheetCellRange(mxRange, ::uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XSpreadsheet > xSheet = xSheetCellRange->getSpreadsheet();
+ uno::Reference< sheet::XSheetAnnotationsSupplier > xAnnosSupp( xSheet, uno::UNO_QUERY_THROW );
+
+ return uno::Reference< sheet::XSheetAnnotations > ( xAnnosSupp->getAnnotations(), uno::UNO_SET_THROW );
+}
+
+sal_Int32
+ScVbaComment::getAnnotationIndex()
+{
+ uno::Reference< sheet::XSheetAnnotations > xAnnos = getAnnotations();
+ table::CellAddress aAddress = getAnnotation()->getPosition();
+
+ sal_Int32 aIndex = 0;
+ sal_Int32 aCount = xAnnos->getCount();
+
+ for ( ; aIndex < aCount ; aIndex++ )
+ {
+ uno::Reference< sheet::XSheetAnnotation > xAnno( xAnnos->getByIndex( aIndex ), uno::UNO_QUERY_THROW );
+ table::CellAddress aAnnoAddress = xAnno->getPosition();
+
+ if ( aAnnoAddress.Column == aAddress.Column && aAnnoAddress.Row == aAddress.Row && aAnnoAddress.Sheet == aAddress.Sheet )
+ {
+ SAL_INFO("sc.ui", "terminating search, index is " << aIndex);
+ break;
+ }
+ }
+ SAL_INFO("sc.ui", "returning index is " << aIndex);
+
+ return aIndex;
+}
+
+uno::Reference< excel::XComment >
+ScVbaComment::getCommentByIndex( sal_Int32 Index )
+{
+ uno::Reference< container::XIndexAccess > xIndexAccess( getAnnotations(), uno::UNO_QUERY_THROW );
+ // parent is sheet ( parent of the range which is the parent of the comment )
+ uno::Reference< XCollection > xColl( new ScVbaComments( getParent()->getParent(), mxContext, mxModel, xIndexAccess ) );
+
+ return uno::Reference< excel::XComment > ( xColl->Item( uno::Any( Index ), uno::Any() ), uno::UNO_QUERY_THROW );
+ }
+
+// public vba functions
+
+OUString SAL_CALL
+ScVbaComment::getAuthor()
+{
+ return getAnnotation()->getAuthor();
+}
+
+void SAL_CALL
+ScVbaComment::setAuthor( const OUString& /*_author*/ )
+{
+ // #TODO #FIXME implementation needed
+}
+
+uno::Reference< msforms::XShape > SAL_CALL
+ScVbaComment::getShape()
+{
+ uno::Reference< sheet::XSheetAnnotationShapeSupplier > xAnnoShapeSupp( getAnnotation(), uno::UNO_QUERY_THROW );
+ uno::Reference< drawing::XShape > xAnnoShape( xAnnoShapeSupp->getAnnotationShape(), uno::UNO_SET_THROW );
+ uno::Reference< sheet::XSheetCellRange > xCellRange( mxRange, uno::UNO_QUERY_THROW );
+ uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupp( xCellRange->getSpreadsheet(), uno::UNO_QUERY_THROW );
+ uno::Reference< drawing::XShapes > xShapes( xDrawPageSupp->getDrawPage(), uno::UNO_QUERY_THROW );
+ return new ScVbaShape( this, mxContext, xAnnoShape, xShapes, mxModel, office::MsoShapeType::msoComment );
+}
+
+sal_Bool SAL_CALL
+ScVbaComment::getVisible()
+{
+ return getAnnotation()->getIsVisible();
+}
+
+void SAL_CALL
+ScVbaComment::setVisible( sal_Bool _visible )
+{
+ getAnnotation()->setIsVisible( _visible );
+}
+
+void SAL_CALL
+ScVbaComment::Delete()
+{
+ getAnnotations()->removeByIndex( getAnnotationIndex() );
+}
+
+uno::Reference< excel::XComment > SAL_CALL
+ScVbaComment::Next()
+{
+ // index: uno = 0, vba = 1
+ return getCommentByIndex( getAnnotationIndex() + 2 );
+}
+
+uno::Reference< excel::XComment > SAL_CALL
+ScVbaComment::Previous()
+{
+ // index: uno = 0, vba = 1
+ return getCommentByIndex( getAnnotationIndex() );
+}
+
+OUString SAL_CALL
+ScVbaComment::Text( const uno::Any& aText, const uno::Any& aStart, const uno::Any& Overwrite )
+{
+ OUString sText;
+ aText >>= sText;
+
+ uno::Reference< text::XSimpleText > xAnnoText( getAnnotation(), uno::UNO_QUERY_THROW );
+ OUString sAnnoText = xAnnoText->getString();
+
+ if ( aStart.hasValue() )
+ {
+ sal_Int16 nStart = 0;
+ bool bOverwrite = true;
+ Overwrite >>= bOverwrite;
+
+ if ( aStart >>= nStart )
+ {
+ uno::Reference< text::XTextCursor > xTextCursor( xAnnoText->createTextCursor(), uno::UNO_SET_THROW );
+
+ if ( bOverwrite )
+ {
+ xTextCursor->collapseToStart();
+ xTextCursor->gotoStart( false );
+ xTextCursor->goRight( nStart - 1, false );
+ xTextCursor->gotoEnd( true );
+ }
+ else
+ {
+ xTextCursor->collapseToStart();
+ xTextCursor->gotoStart( false );
+ xTextCursor->goRight( nStart - 1 , true );
+ }
+
+ uno::Reference< text::XTextRange > xRange( xTextCursor, uno::UNO_QUERY_THROW );
+ xAnnoText->insertString( xRange, sText, bOverwrite );
+ return xAnnoText->getString();
+ }
+ throw uno::RuntimeException("ScVbaComment::Text - bad Start value " );
+ }
+ else if ( aText.hasValue() )
+ {
+ uno::Reference< sheet::XCellAddressable > xCellAddr(mxRange->getCellByPosition(0, 0), uno::UNO_QUERY_THROW );
+ table::CellAddress aAddress = xCellAddr->getCellAddress();
+ getAnnotations()->insertNew( aAddress, sText );
+ }
+
+ return sAnnoText;
+}
+
+OUString
+ScVbaComment::getServiceImplName()
+{
+ return "ScVbaComment";
+}
+
+uno::Sequence< OUString >
+ScVbaComment::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.ScVbaComment"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbacomment.hxx b/sc/source/ui/vba/vbacomment.hxx
new file mode 100644
index 000000000..fe801899c
--- /dev/null
+++ b/sc/source/ui/vba/vbacomment.hxx
@@ -0,0 +1,72 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <ooo/vba/excel/XComment.hpp>
+#include <ooo/vba/msforms/XShape.hpp>
+#include <com/sun/star/sheet/XSheetAnnotations.hpp>
+#include <com/sun/star/sheet/XSheetAnnotation.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+#include <vbahelper/vbahelperinterface.hxx>
+
+typedef InheritedHelperInterfaceWeakImpl< ov::excel::XComment > ScVbaComment_BASE;
+
+class ScVbaComment : public ScVbaComment_BASE
+{
+ css::uno::Reference< css::frame::XModel > mxModel;
+ css::uno::Reference< css::table::XCellRange > mxRange;
+
+private:
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference< css::sheet::XSheetAnnotation > getAnnotation();
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference< css::sheet::XSheetAnnotations > getAnnotations() const;
+ /// @throws css::uno::RuntimeException
+ sal_Int32 getAnnotationIndex();
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference< ov::excel::XComment > getCommentByIndex( sal_Int32 Index );
+public:
+ /// @throws css::lang::IllegalArgumentException
+ /// @throws css::uno::RuntimeException
+ ScVbaComment(
+ const css::uno::Reference< ov::XHelperInterface >& xParent,
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ const css::uno::Reference< css::frame::XModel >& xModel,
+ const css::uno::Reference< css::table::XCellRange >& xRange );
+
+ // Attributes
+ virtual OUString SAL_CALL getAuthor() override;
+ virtual void SAL_CALL setAuthor( const OUString& _author ) override;
+ virtual css::uno::Reference< ov::msforms::XShape > SAL_CALL getShape() override;
+ virtual sal_Bool SAL_CALL getVisible() override;
+ virtual void SAL_CALL setVisible( sal_Bool _visible ) override;
+
+ // Methods
+ virtual void SAL_CALL Delete() override;
+ virtual css::uno::Reference< ov::excel::XComment > SAL_CALL Next() override;
+ virtual css::uno::Reference< ov::excel::XComment > SAL_CALL Previous() override;
+ virtual OUString SAL_CALL Text( const css::uno::Any& Text, const css::uno::Any& Start, const css::uno::Any& Overwrite ) override;
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbacomments.cxx b/sc/source/ui/vba/vbacomments.cxx
new file mode 100644
index 000000000..470e468b7
--- /dev/null
+++ b/sc/source/ui/vba/vbacomments.cxx
@@ -0,0 +1,113 @@
+/* -*- 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 "vbacomments.hxx"
+#include "vbacomment.hxx"
+
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/sheet/XSheetAnnotation.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+static uno::Any AnnotationToComment( const uno::Any& aSource, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< frame::XModel >& xModel )
+{
+ uno::Reference< sheet::XSheetAnnotation > xAnno( aSource, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XChild > xChild( xAnno, uno::UNO_QUERY_THROW );
+ uno::Reference< table::XCellRange > xCellRange( xChild->getParent(), uno::UNO_QUERY_THROW );
+
+ // #FIXME needs to find the correct Parent
+ return uno::Any( uno::Reference< excel::XComment > (
+ new ScVbaComment( uno::Reference< XHelperInterface >(), xContext, xModel, xCellRange ) ) );
+}
+
+namespace {
+
+class CommentEnumeration : public EnumerationHelperImpl
+{
+ css::uno::Reference< css::frame::XModel > mxModel;
+public:
+ /// @throws uno::RuntimeException
+ CommentEnumeration(
+ const uno::Reference< XHelperInterface >& xParent,
+ const uno::Reference< uno::XComponentContext >& xContext,
+ const uno::Reference< container::XEnumeration >& xEnumeration,
+ const uno::Reference< frame::XModel >& xModel ) :
+ EnumerationHelperImpl( xParent, xContext, xEnumeration ),
+ mxModel( xModel, uno::UNO_SET_THROW )
+ {}
+
+ virtual uno::Any SAL_CALL nextElement() override
+ {
+ return AnnotationToComment( m_xEnumeration->nextElement(), m_xContext, mxModel );
+ }
+
+};
+
+}
+
+ScVbaComments::ScVbaComments(
+ const uno::Reference< XHelperInterface >& xParent,
+ const uno::Reference< uno::XComponentContext > & xContext,
+ const uno::Reference< frame::XModel >& xModel,
+ const uno::Reference< container::XIndexAccess >& xIndexAccess ) :
+ ScVbaComments_BASE( xParent, xContext, xIndexAccess ),
+ mxModel( xModel, uno::UNO_SET_THROW )
+{
+}
+
+// public helper functions
+
+uno::Reference< container::XEnumeration >
+ScVbaComments::createEnumeration()
+{
+ uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
+ return new CommentEnumeration( mxParent, mxContext, xEnumAccess->createEnumeration(), mxModel );
+}
+
+uno::Any
+ScVbaComments::createCollectionObject( const css::uno::Any& aSource )
+{
+ return AnnotationToComment( aSource, mxContext, mxModel );
+}
+
+uno::Type
+ScVbaComments::getElementType()
+{
+ return cppu::UnoType<excel::XComment>::get();
+}
+
+OUString
+ScVbaComments::getServiceImplName()
+{
+ return "ScVbaComments";
+}
+
+css::uno::Sequence<OUString>
+ScVbaComments::getServiceNames()
+{
+ static uno::Sequence< OUString > const sNames
+ {
+ "ooo.vba.excel.Comments"
+ };
+ return sNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbacomments.hxx b/sc/source/ui/vba/vbacomments.hxx
new file mode 100644
index 000000000..83a62b6e8
--- /dev/null
+++ b/sc/source/ui/vba/vbacomments.hxx
@@ -0,0 +1,49 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <ooo/vba/excel/XComments.hpp>
+
+#include <vbahelper/vbacollectionimpl.hxx>
+
+typedef CollTestImplHelper< ov::excel::XComments > ScVbaComments_BASE;
+
+class ScVbaComments : public ScVbaComments_BASE
+{
+public:
+ ScVbaComments(
+ const css::uno::Reference< ov::XHelperInterface >& xParent,
+ const css::uno::Reference< css::uno::XComponentContext > & xContext,
+ const css::uno::Reference< css::frame::XModel >& xModel,
+ const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess );
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+
+ // ScVbaComments_BASE
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+
+private:
+ css::uno::Reference< css::frame::XModel > mxModel;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbacondition.cxx b/sc/source/ui/vba/vbacondition.cxx
new file mode 100644
index 000000000..c5577a7f8
--- /dev/null
+++ b/sc/source/ui/vba/vbacondition.cxx
@@ -0,0 +1,143 @@
+/* -*- 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 "vbacondition.hxx"
+#include <ooo/vba/excel/XlFormatConditionOperator.hpp>
+#include <ooo/vba/excel/XFormatCondition.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/sheet/XSheetCondition.hpp>
+#include <basic/sberrors.hxx>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+const sal_Int32 ISFORMULA = 98765432;
+
+template <typename... Ifc>
+ScVbaCondition<Ifc...>::ScVbaCondition(
+ const uno::Reference<XHelperInterface>& xParent,
+ const uno::Reference<uno::XComponentContext>& xContext,
+ const uno::Reference<sheet::XSheetCondition>& _xSheetCondition)
+ : ScVbaCondition_BASE(xParent, xContext)
+ , mxSheetCondition(_xSheetCondition)
+{
+ mxAddressable.set(xParent, uno::UNO_QUERY_THROW);
+}
+
+template <typename... Ifc>
+sheet::ConditionOperator ScVbaCondition<Ifc...>::retrieveAPIOperator(const uno::Any& _aOperator)
+{
+ sheet::ConditionOperator aRetAPIOperator = sheet::ConditionOperator_NONE;
+ sal_Int32 nOperator = 0;
+ if (_aOperator >>= nOperator)
+ {
+ switch (nOperator)
+ {
+ case excel::XlFormatConditionOperator::xlBetween:
+ aRetAPIOperator = sheet::ConditionOperator_BETWEEN;
+ break;
+ case excel::XlFormatConditionOperator::xlNotBetween:
+ aRetAPIOperator = sheet::ConditionOperator_NOT_BETWEEN;
+ break;
+ case excel::XlFormatConditionOperator::xlEqual:
+ aRetAPIOperator = sheet::ConditionOperator_EQUAL;
+ break;
+ case excel::XlFormatConditionOperator::xlNotEqual:
+ aRetAPIOperator = sheet::ConditionOperator_NOT_EQUAL;
+ break;
+ case excel::XlFormatConditionOperator::xlGreater:
+ aRetAPIOperator = sheet::ConditionOperator_GREATER;
+ break;
+ case excel::XlFormatConditionOperator::xlLess:
+ aRetAPIOperator = sheet::ConditionOperator_LESS;
+ break;
+ case excel::XlFormatConditionOperator::xlGreaterEqual:
+ aRetAPIOperator = sheet::ConditionOperator_GREATER_EQUAL;
+ break;
+ case excel::XlFormatConditionOperator::xlLessEqual:
+ aRetAPIOperator = sheet::ConditionOperator_LESS_EQUAL;
+ break;
+ default:
+ aRetAPIOperator = sheet::ConditionOperator_NONE;
+ break;
+ }
+ }
+ return aRetAPIOperator;
+}
+
+template <typename... Ifc> OUString ScVbaCondition<Ifc...>::Formula1()
+{
+ return mxSheetCondition->getFormula1();
+}
+
+template <typename... Ifc> OUString ScVbaCondition<Ifc...>::Formula2()
+{
+ return mxSheetCondition->getFormula2();
+}
+
+template <typename... Ifc> sal_Int32 ScVbaCondition<Ifc...>::Operator(bool _bIncludeFormulaValue)
+{
+ sal_Int32 retvalue = -1;
+ sheet::ConditionOperator aConditionalOperator = mxSheetCondition->getOperator();
+ switch (aConditionalOperator)
+ {
+ case sheet::ConditionOperator_EQUAL:
+ retvalue = excel::XlFormatConditionOperator::xlEqual;
+ break;
+ case sheet::ConditionOperator_NOT_EQUAL:
+ retvalue = excel::XlFormatConditionOperator::xlNotEqual;
+ break;
+ case sheet::ConditionOperator_GREATER:
+ retvalue = excel::XlFormatConditionOperator::xlGreater;
+ break;
+ case sheet::ConditionOperator_GREATER_EQUAL:
+ retvalue = excel::XlFormatConditionOperator::xlGreaterEqual;
+ break;
+ case sheet::ConditionOperator_LESS:
+ retvalue = excel::XlFormatConditionOperator::xlLess;
+ break;
+ case sheet::ConditionOperator_LESS_EQUAL:
+ retvalue = excel::XlFormatConditionOperator::xlLessEqual;
+ break;
+ case sheet::ConditionOperator_BETWEEN:
+ retvalue = excel::XlFormatConditionOperator::xlBetween;
+ break;
+ case sheet::ConditionOperator_NOT_BETWEEN:
+ retvalue = excel::XlFormatConditionOperator::xlNotBetween;
+ break;
+ case sheet::ConditionOperator_FORMULA:
+ if (_bIncludeFormulaValue)
+ {
+ //#FIXME huh what's this all about
+ // from helperapi/impl/.../calc/ConditionImpl
+ retvalue = ISFORMULA;
+ break;
+ }
+ [[fallthrough]]; //TODO ???
+ case sheet::ConditionOperator_NONE:
+ default:
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, u"Operator not supported");
+ break;
+ }
+ return retvalue;
+}
+
+template class ScVbaCondition<excel::XFormatCondition>;
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbacondition.hxx b/sc/source/ui/vba/vbacondition.hxx
new file mode 100644
index 000000000..78faf0d5e
--- /dev/null
+++ b/sc/source/ui/vba/vbacondition.hxx
@@ -0,0 +1,48 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <vbahelper/vbahelperinterface.hxx>
+#include <com/sun/star/sheet/ConditionOperator.hpp>
+
+namespace com::sun::star::sheet { class XCellRangeAddressable; }
+namespace com::sun::star::sheet { class XSheetCondition; }
+
+template< typename... Ifc >
+class ScVbaCondition : public InheritedHelperInterfaceWeakImpl< Ifc... >
+{
+typedef InheritedHelperInterfaceWeakImpl< Ifc... > ScVbaCondition_BASE;
+protected:
+ css::uno::Reference< css::sheet::XCellRangeAddressable > mxAddressable;
+ css::uno::Reference< css::sheet::XSheetCondition > mxSheetCondition;
+public:
+ ScVbaCondition( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::sheet::XSheetCondition >& _xSheetCondition );
+
+ /// @throws css::script::BasicErrorException
+ static css::sheet::ConditionOperator retrieveAPIOperator( const css::uno::Any& _aOperator);
+
+ virtual OUString SAL_CALL Formula1( ) override;
+ virtual OUString SAL_CALL Formula2( ) override;
+ /// @throws css::script::BasicErrorException
+ virtual sal_Int32 Operator(bool _bIncludeFormulaValue);
+ virtual sal_Int32 SAL_CALL Operator() override = 0;
+
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbadialog.cxx b/sc/source/ui/vba/vbadialog.cxx
new file mode 100644
index 000000000..5537c65a3
--- /dev/null
+++ b/sc/source/ui/vba/vbadialog.cxx
@@ -0,0 +1,85 @@
+/* -*- 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 "vbadialog.hxx"
+
+#include <sal/macros.h>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+const std::u16string_view aStringList[]=
+{
+ u".uno:Open",
+ u".uno:FormatCellDialog",
+ u".uno:InsertCell",
+ u".uno:Print",
+ u".uno:PasteSpecial",
+ u".uno:ToolProtectionDocument",
+ u".uno:ColumnWidth",
+ u".uno:DefineName",
+ u".uno:ConfigureDialog",
+ u".uno:HyperlinkDialog",
+ u".uno:InsertGraphic",
+ u".uno:InsertObject",
+ u".uno:PageFormatDialog",
+ u".uno:DataSort",
+ u".uno:RowHeight",
+ u".uno:AutoCorrectDlg",
+ u".uno:ConditionalFormatDialog",
+ u".uno:DataConsolidate",
+ u".uno:CreateNames",
+ u".uno:FillSeries",
+ u".uno:Validation",
+ u".uno:DefineLabelRange",
+ u".uno:DataFilterAutoFilter",
+ u".uno:DataFilterSpecialFilter",
+ u".uno:AutoFormat"
+};
+
+const sal_Int32 nDialogSize = SAL_N_ELEMENTS(aStringList);
+
+OUString
+ScVbaDialog::mapIndexToName( sal_Int32 nIndex )
+{
+ if( nIndex < nDialogSize )
+ return OUString(aStringList[ nIndex ]);
+ return OUString();
+}
+
+OUString
+ScVbaDialog::getServiceImplName()
+{
+ return "ScVbaDialog";
+}
+
+uno::Sequence< OUString >
+ScVbaDialog::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.Dialog"
+ };
+ return aServiceNames;
+}
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbadialog.hxx b/sc/source/ui/vba/vbadialog.hxx
new file mode 100644
index 000000000..9317cbfaf
--- /dev/null
+++ b/sc/source/ui/vba/vbadialog.hxx
@@ -0,0 +1,40 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <cppuhelper/implbase.hxx>
+#include <ooo/vba/excel/XDialog.hpp>
+#include <vbahelper/vbadialogbase.hxx>
+
+typedef cppu::ImplInheritanceHelper< VbaDialogBase, ov::excel::XDialog > ScVbaDialog_BASE;
+
+class ScVbaDialog : public ScVbaDialog_BASE
+{
+public:
+ ScVbaDialog( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::frame::XModel >& xModel, sal_Int32 nIndex ):ScVbaDialog_BASE( xParent, xContext, xModel, nIndex ) {}
+
+ // Methods
+ virtual OUString mapIndexToName( sal_Int32 nIndex ) override;
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbadialogs.cxx b/sc/source/ui/vba/vbadialogs.cxx
new file mode 100644
index 000000000..9264728a2
--- /dev/null
+++ b/sc/source/ui/vba/vbadialogs.cxx
@@ -0,0 +1,51 @@
+/* -*- 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 <ooo/vba/excel/XDialog.hpp>
+#include "vbadialogs.hxx"
+#include "vbadialog.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+uno::Any
+ScVbaDialogs::Item( const uno::Any &aItem )
+{
+ sal_Int32 nIndex = 0;
+ aItem >>= nIndex;
+ uno::Reference< excel::XDialog > aDialog( new ScVbaDialog( uno::Reference< XHelperInterface >( Application(),uno::UNO_QUERY_THROW ), mxContext, m_xModel, nIndex ) );
+ return uno::Any( aDialog );
+}
+
+OUString
+ScVbaDialogs::getServiceImplName()
+{
+ return "ScVbaDialogs";
+}
+
+uno::Sequence< OUString >
+ScVbaDialogs::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.Dialogs"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbadialogs.hxx b/sc/source/ui/vba/vbadialogs.hxx
new file mode 100644
index 000000000..97cbbda04
--- /dev/null
+++ b/sc/source/ui/vba/vbadialogs.hxx
@@ -0,0 +1,43 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <ooo/vba/excel/XDialogs.hpp>
+#include <vbahelper/vbadialogsbase.hxx>
+#include <cppuhelper/implbase.hxx>
+
+namespace ooo::vba { class XHelperInterface; }
+namespace com::sun::star::uno { class XComponentContext; }
+
+typedef cppu::ImplInheritanceHelper< VbaDialogsBase, ov::excel::XDialogs > ScVbaDialogs_BASE;
+
+class ScVbaDialogs : public ScVbaDialogs_BASE
+{
+public:
+ ScVbaDialogs( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > &xContext, const css::uno::Reference< css::frame::XModel >& xModel ): ScVbaDialogs_BASE( xParent, xContext, xModel ) {}
+
+ // XCollection
+ virtual css::uno::Any SAL_CALL Item( const css::uno::Any& Index ) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaeventshelper.cxx b/sc/source/ui/vba/vbaeventshelper.cxx
new file mode 100644
index 000000000..bd00fdcac
--- /dev/null
+++ b/sc/source/ui/vba/vbaeventshelper.cxx
@@ -0,0 +1,898 @@
+/* -*- 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 "vbaeventshelper.hxx"
+#include "excelvbahelper.hxx"
+
+#include <com/sun/star/awt/XTopWindow.hpp>
+#include <com/sun/star/awt/XTopWindowListener.hpp>
+#include <com/sun/star/awt/XWindowListener.hpp>
+#include <com/sun/star/frame/XBorderResizeListener.hpp>
+#include <com/sun/star/frame/XControllerBorder.hpp>
+#include <com/sun/star/script/ModuleType.hpp>
+#include <com/sun/star/script/vba/VBAEventId.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/sheet/XSheetCellRangeContainer.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/util/XChangesListener.hpp>
+#include <com/sun/star/util/XChangesNotifier.hpp>
+
+#include <cppuhelper/implbase.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <unotools/eventcfg.hxx>
+#include <vcl/event.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/window.hxx>
+#include <vbahelper/vbaaccesshelper.hxx>
+
+#include <docsh.hxx>
+#include <document.hxx>
+#include <cellsuno.hxx>
+#include <convuno.hxx>
+#include "vbaapplication.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::script::vba::VBAEventId;
+using namespace ::ooo::vba;
+
+namespace {
+
+/** Extracts a sheet index from the specified element of the passed sequence.
+ The element may be an integer, a Calc range or ranges object, or a VBA Range object.
+
+ @throws lang::IllegalArgumentException
+ @throws uno::RuntimeException
+*/
+SCTAB lclGetTabFromArgs( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex )
+{
+ VbaEventsHelperBase::checkArgument( rArgs, nIndex );
+
+ // first try to extract a sheet index
+ sal_Int32 nTab = -1;
+ if( rArgs[ nIndex ] >>= nTab )
+ {
+ if( (nTab < 0) || (nTab > MAXTAB) )
+ throw lang::IllegalArgumentException();
+ return static_cast< SCTAB >( nTab );
+ }
+
+ // try VBA Range object
+ uno::Reference< excel::XRange > xVbaRange = getXSomethingFromArgs< excel::XRange >( rArgs, nIndex );
+ if( xVbaRange.is() )
+ {
+ uno::Reference< XHelperInterface > xVbaHelper( xVbaRange, uno::UNO_QUERY_THROW );
+ // TODO: in the future, the parent may be an excel::XChart (chart sheet) -> will there be a common base interface?
+ uno::Reference< excel::XWorksheet > xVbaSheet( xVbaHelper->getParent(), uno::UNO_QUERY_THROW );
+ // VBA sheet index is 1-based
+ return static_cast< SCTAB >( xVbaSheet->getIndex() - 1 );
+ }
+
+ // try single UNO range object
+ uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable = getXSomethingFromArgs< sheet::XCellRangeAddressable >( rArgs, nIndex );
+ if( xCellRangeAddressable.is() )
+ return xCellRangeAddressable->getRangeAddress().Sheet;
+
+ // at last, try UNO range list
+ uno::Reference< sheet::XSheetCellRangeContainer > xRanges = getXSomethingFromArgs< sheet::XSheetCellRangeContainer >( rArgs, nIndex );
+ if( xRanges.is() )
+ {
+ uno::Sequence< table::CellRangeAddress > aRangeAddresses = xRanges->getRangeAddresses();
+ if( aRangeAddresses.hasElements() )
+ return aRangeAddresses[ 0 ].Sheet;
+ }
+
+ throw lang::IllegalArgumentException();
+}
+
+/** Returns the AWT container window of the passed controller. */
+uno::Reference< awt::XWindow > lclGetWindowForController( const uno::Reference< frame::XController >& rxController )
+{
+ if( rxController.is() ) try
+ {
+ uno::Reference< frame::XFrame > xFrame( rxController->getFrame(), uno::UNO_SET_THROW );
+ return xFrame->getContainerWindow();
+ }
+ catch( uno::Exception& )
+ {
+ }
+ return nullptr;
+}
+
+} // namespace
+
+// This class is to process Workbook window related event
+class ScVbaEventListener : public ::cppu::WeakImplHelper< awt::XTopWindowListener,
+ awt::XWindowListener,
+ frame::XBorderResizeListener,
+ util::XChangesListener >
+{
+public:
+ ScVbaEventListener( ScVbaEventsHelper& rVbaEvents, const uno::Reference< frame::XModel >& rxModel, ScDocShell* pDocShell );
+
+ /** Starts listening to the passed document controller. */
+ void startControllerListening( const uno::Reference< frame::XController >& rxController );
+ /** Stops listening to the passed document controller. */
+ void stopControllerListening( const uno::Reference< frame::XController >& rxController );
+
+ // XTopWindowListener
+ virtual void SAL_CALL windowOpened( const lang::EventObject& rEvent ) override;
+ virtual void SAL_CALL windowClosing( const lang::EventObject& rEvent ) override;
+ virtual void SAL_CALL windowClosed( const lang::EventObject& rEvent ) override;
+ virtual void SAL_CALL windowMinimized( const lang::EventObject& rEvent ) override;
+ virtual void SAL_CALL windowNormalized( const lang::EventObject& rEvent ) override;
+ virtual void SAL_CALL windowActivated( const lang::EventObject& rEvent ) override;
+ virtual void SAL_CALL windowDeactivated( const lang::EventObject& rEvent ) override;
+
+ // XWindowListener
+ virtual void SAL_CALL windowResized( const awt::WindowEvent& rEvent ) override;
+ virtual void SAL_CALL windowMoved( const awt::WindowEvent& rEvent ) override;
+ virtual void SAL_CALL windowShown( const lang::EventObject& rEvent ) override;
+ virtual void SAL_CALL windowHidden( const lang::EventObject& rEvent ) override;
+
+ // XBorderResizeListener
+ virtual void SAL_CALL borderWidthsChanged( const uno::Reference< uno::XInterface >& rSource, const frame::BorderWidths& aNewSize ) override;
+
+ // XChangesListener
+ virtual void SAL_CALL changesOccurred( const util::ChangesEvent& rEvent ) override;
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const lang::EventObject& rEvent ) override;
+
+private:
+ /** Starts listening to the document model. */
+ void startModelListening();
+ /** Stops listening to the document model. */
+ void stopModelListening();
+
+ /** Returns the controller for the passed VCL window. */
+ uno::Reference< frame::XController > getControllerForWindow( vcl::Window* pWindow ) const;
+
+ /** Calls the Workbook_Window[Activate|Deactivate] event handler. */
+ void processWindowActivateEvent( vcl::Window* pWindow, bool bActivate );
+ /** Posts a Workbook_WindowResize user event. */
+ void postWindowResizeEvent( vcl::Window* pWindow );
+ /** Callback link for Application::PostUserEvent(). */
+ DECL_LINK( processWindowResizeEvent, void*, void );
+
+private:
+ typedef ::std::map< VclPtr<vcl::Window>, uno::Reference< frame::XController > > WindowControllerMap;
+
+ ::osl::Mutex maMutex;
+ ScVbaEventsHelper& mrVbaEvents;
+ uno::Reference< frame::XModel > mxModel;
+ ScDocShell* mpDocShell;
+ WindowControllerMap maControllers; /// Maps VCL top windows to their controllers.
+ std::multiset< VclPtr<vcl::Window> > m_PostedWindows; /// Keeps processWindowResizeEvent windows from being deleted between postWindowResizeEvent and processWindowResizeEvent
+ VclPtr<vcl::Window> mpActiveWindow; /// Currently activated window, to prevent multiple (de)activation.
+ bool mbWindowResized; /// True = window resize system event processed.
+ bool mbBorderChanged; /// True = borders changed system event processed.
+ bool mbDisposed;
+};
+
+ScVbaEventListener::ScVbaEventListener( ScVbaEventsHelper& rVbaEvents, const uno::Reference< frame::XModel >& rxModel, ScDocShell* pDocShell ) :
+ mrVbaEvents( rVbaEvents ),
+ mxModel( rxModel ),
+ mpDocShell( pDocShell ),
+ mpActiveWindow( nullptr ),
+ mbWindowResized( false ),
+ mbBorderChanged( false ),
+ mbDisposed( !rxModel.is() )
+{
+ if( !mxModel.is() )
+ return;
+
+ startModelListening();
+ try
+ {
+ uno::Reference< frame::XController > xController( mxModel->getCurrentController(), uno::UNO_SET_THROW );
+ startControllerListening( xController );
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+void ScVbaEventListener::startControllerListening( const uno::Reference< frame::XController >& rxController )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ uno::Reference< awt::XWindow > xWindow = lclGetWindowForController( rxController );
+ if( xWindow.is() )
+ try { xWindow->addWindowListener( this ); } catch( uno::Exception& ) {}
+
+ uno::Reference< awt::XTopWindow > xTopWindow( xWindow, uno::UNO_QUERY );
+ if( xTopWindow.is() )
+ try { xTopWindow->addTopWindowListener( this ); } catch( uno::Exception& ) {}
+
+ uno::Reference< frame::XControllerBorder > xControllerBorder( rxController, uno::UNO_QUERY );
+ if( xControllerBorder.is() )
+ try { xControllerBorder->addBorderResizeListener( this ); } catch( uno::Exception& ) {}
+
+ if( VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow ) )
+ {
+ maControllers[ pWindow ] = rxController;
+ }
+}
+
+void ScVbaEventListener::stopControllerListening( const uno::Reference< frame::XController >& rxController )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ uno::Reference< awt::XWindow > xWindow = lclGetWindowForController( rxController );
+ if( xWindow.is() )
+ try { xWindow->removeWindowListener( this ); } catch( uno::Exception& ) {}
+
+ uno::Reference< awt::XTopWindow > xTopWindow( xWindow, uno::UNO_QUERY );
+ if( xTopWindow.is() )
+ try { xTopWindow->removeTopWindowListener( this ); } catch( uno::Exception& ) {}
+
+ uno::Reference< frame::XControllerBorder > xControllerBorder( rxController, uno::UNO_QUERY );
+ if( xControllerBorder.is() )
+ try { xControllerBorder->removeBorderResizeListener( this ); } catch( uno::Exception& ) {}
+
+ if( VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow ) )
+ {
+ maControllers.erase( pWindow );
+ if( pWindow == mpActiveWindow )
+ mpActiveWindow = nullptr;
+ }
+}
+
+void SAL_CALL ScVbaEventListener::windowOpened( const lang::EventObject& /*rEvent*/ )
+{
+}
+
+void SAL_CALL ScVbaEventListener::windowClosing( const lang::EventObject& /*rEvent*/ )
+{
+}
+
+void SAL_CALL ScVbaEventListener::windowClosed( const lang::EventObject& /*rEvent*/ )
+{
+}
+
+void SAL_CALL ScVbaEventListener::windowMinimized( const lang::EventObject& /*rEvent*/ )
+{
+}
+
+void SAL_CALL ScVbaEventListener::windowNormalized( const lang::EventObject& /*rEvent*/ )
+{
+}
+
+void SAL_CALL ScVbaEventListener::windowActivated( const lang::EventObject& rEvent )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ if( mbDisposed )
+ return;
+
+ uno::Reference< awt::XWindow > xWindow( rEvent.Source, uno::UNO_QUERY );
+ VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
+ // do not fire activation event multiple time for the same window
+ if( pWindow && (pWindow != mpActiveWindow) )
+ {
+ // if another window is active, fire deactivation event first
+ if( mpActiveWindow )
+ processWindowActivateEvent( mpActiveWindow, false );
+ // fire activation event for the new window
+ processWindowActivateEvent( pWindow, true );
+ mpActiveWindow = pWindow;
+ }
+}
+
+void SAL_CALL ScVbaEventListener::windowDeactivated( const lang::EventObject& rEvent )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ if( !mbDisposed )
+ {
+ uno::Reference< awt::XWindow > xWindow( rEvent.Source, uno::UNO_QUERY );
+ VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
+ // do not fire the deactivation event, if the window is not active (prevent multiple deactivation)
+ if( pWindow && (pWindow == mpActiveWindow) )
+ processWindowActivateEvent( pWindow, false );
+ // forget pointer to the active window
+ mpActiveWindow = nullptr;
+ }
+}
+
+void SAL_CALL ScVbaEventListener::windowResized( const awt::WindowEvent& rEvent )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ mbWindowResized = true;
+ if( !mbDisposed && mbBorderChanged )
+ {
+ uno::Reference< awt::XWindow > xWindow( rEvent.Source, uno::UNO_QUERY );
+ postWindowResizeEvent( VCLUnoHelper::GetWindow( xWindow ) );
+ }
+}
+
+void SAL_CALL ScVbaEventListener::windowMoved( const awt::WindowEvent& /*rEvent*/ )
+{
+}
+
+void SAL_CALL ScVbaEventListener::windowShown( const lang::EventObject& /*rEvent*/ )
+{
+}
+
+void SAL_CALL ScVbaEventListener::windowHidden( const lang::EventObject& /*rEvent*/ )
+{
+}
+
+void SAL_CALL ScVbaEventListener::borderWidthsChanged( const uno::Reference< uno::XInterface >& rSource, const frame::BorderWidths& /*aNewSize*/ )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ mbBorderChanged = true;
+ if( !mbDisposed && mbWindowResized )
+ {
+ uno::Reference< frame::XController > xController( rSource, uno::UNO_QUERY );
+ uno::Reference< awt::XWindow > xWindow = lclGetWindowForController( xController );
+ postWindowResizeEvent( VCLUnoHelper::GetWindow( xWindow ) );
+ }
+}
+
+void SAL_CALL ScVbaEventListener::changesOccurred( const util::ChangesEvent& rEvent )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ sal_Int32 nCount = rEvent.Changes.getLength();
+ if( mbDisposed || !mpDocShell || (nCount == 0) )
+ return;
+
+ util::ElementChange aChange = rEvent.Changes[ 0 ];
+ OUString sOperation;
+ aChange.Accessor >>= sOperation;
+ if( !sOperation.equalsIgnoreAsciiCase("cell-change") )
+ return;
+
+ if( nCount == 1 )
+ {
+ uno::Reference< table::XCellRange > xRangeObj;
+ aChange.ReplacedElement >>= xRangeObj;
+ if( xRangeObj.is() )
+ {
+ uno::Sequence< uno::Any > aArgs{ uno::Any(xRangeObj) };
+ mrVbaEvents.processVbaEventNoThrow( WORKSHEET_CHANGE, aArgs );
+ }
+ return;
+ }
+
+ ScRangeList aRangeList;
+ for( const util::ElementChange& rChange : rEvent.Changes )
+ {
+ rChange.Accessor >>= sOperation;
+ uno::Reference< table::XCellRange > xRangeObj;
+ rChange.ReplacedElement >>= xRangeObj;
+ if( xRangeObj.is() && sOperation.equalsIgnoreAsciiCase("cell-change") )
+ {
+ uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable( xRangeObj, uno::UNO_QUERY );
+ if( xCellRangeAddressable.is() )
+ {
+ ScRange aRange;
+ ScUnoConversion::FillScRange( aRange, xCellRangeAddressable->getRangeAddress() );
+ aRangeList.push_back( aRange );
+ }
+ }
+ }
+
+ if (!aRangeList.empty())
+ {
+ uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( mpDocShell, aRangeList ) );
+ uno::Sequence< uno::Any > aArgs{ uno::Any(xRanges) };
+ mrVbaEvents.processVbaEventNoThrow( WORKSHEET_CHANGE, aArgs );
+ }
+}
+
+void SAL_CALL ScVbaEventListener::disposing( const lang::EventObject& rEvent )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ uno::Reference< frame::XModel > xModel( rEvent.Source, uno::UNO_QUERY );
+ if( xModel.is() )
+ {
+ OSL_ENSURE( xModel.get() == mxModel.get(), "ScVbaEventListener::disposing - disposing from unknown model" );
+ stopModelListening();
+ mbDisposed = true;
+ return;
+ }
+
+ uno::Reference< frame::XController > xController( rEvent.Source, uno::UNO_QUERY );
+ if( xController.is() )
+ {
+ stopControllerListening( xController );
+ return;
+ }
+}
+
+// private --------------------------------------------------------------------
+
+void ScVbaEventListener::startModelListening()
+{
+ try
+ {
+ uno::Reference< util::XChangesNotifier > xChangesNotifier( mxModel, uno::UNO_QUERY_THROW );
+ xChangesNotifier->addChangesListener( this );
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+void ScVbaEventListener::stopModelListening()
+{
+ try
+ {
+ uno::Reference< util::XChangesNotifier > xChangesNotifier( mxModel, uno::UNO_QUERY_THROW );
+ xChangesNotifier->removeChangesListener( this );
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+uno::Reference< frame::XController > ScVbaEventListener::getControllerForWindow( vcl::Window* pWindow ) const
+{
+ WindowControllerMap::const_iterator aIt = maControllers.find( pWindow );
+ return (aIt == maControllers.end()) ? uno::Reference< frame::XController >() : aIt->second;
+}
+
+void ScVbaEventListener::processWindowActivateEvent( vcl::Window* pWindow, bool bActivate )
+{
+ uno::Reference< frame::XController > xController = getControllerForWindow( pWindow );
+ if( xController.is() )
+ {
+ uno::Sequence< uno::Any > aArgs{ uno::Any(xController) };
+ mrVbaEvents.processVbaEventNoThrow( bActivate ? WORKBOOK_WINDOWACTIVATE : WORKBOOK_WINDOWDEACTIVATE, aArgs );
+ }
+}
+
+void ScVbaEventListener::postWindowResizeEvent( vcl::Window* pWindow )
+{
+ // check that the passed window is still alive (it must be registered in maControllers)
+ if( pWindow && (maControllers.count( pWindow ) > 0) )
+ {
+ mbWindowResized = mbBorderChanged = false;
+ acquire(); // ensure we don't get deleted before the timer fires
+ m_PostedWindows.insert(pWindow);
+ Application::PostUserEvent( LINK( this, ScVbaEventListener, processWindowResizeEvent ), pWindow );
+ }
+}
+
+IMPL_LINK( ScVbaEventListener, processWindowResizeEvent, void*, p, void )
+{
+ vcl::Window* pWindow = static_cast<vcl::Window*>(p);
+ ::osl::MutexGuard aGuard( maMutex );
+
+ /* Check that the passed window is still alive (it must be registered in
+ maControllers). While closing a document, postWindowResizeEvent() may
+ be called on the last window which posts a user event via
+ Application::PostUserEvent to call this event handler. VCL will trigger
+ the handler some time later. Sometimes, the window gets deleted before.
+ This is handled via the disposing() function which removes the window
+ pointer from the member maControllers. Thus, checking whether
+ maControllers contains pWindow ensures that the window is still alive. */
+ if( !mbDisposed && pWindow && !pWindow->isDisposed() && (maControllers.count(pWindow) > 0) )
+ {
+ // do not fire event unless all mouse buttons have been released
+ vcl::Window::PointerState aPointerState = pWindow->GetPointerState();
+ if( (aPointerState.mnState & (MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT)) == 0 )
+ {
+ uno::Reference< frame::XController > xController = getControllerForWindow( pWindow );
+ if( xController.is() )
+ {
+ uno::Sequence< uno::Any > aArgs{ uno::Any(xController) };
+ // #163419# do not throw exceptions into application core
+ mrVbaEvents.processVbaEventNoThrow( WORKBOOK_WINDOWRESIZE, aArgs );
+ }
+ }
+ }
+ {
+ // note: there may be multiple processWindowResizeEvent outstanding
+ // for pWindow, so it may have been added to m_PostedWindows multiple
+ // times - so this must delete exactly one of these elements!
+ auto const iter(m_PostedWindows.find(pWindow));
+ assert(iter != m_PostedWindows.end());
+ m_PostedWindows.erase(iter);
+ }
+ release();
+}
+
+ScVbaEventsHelper::ScVbaEventsHelper( const uno::Sequence< uno::Any >& rArgs ) :
+ VbaEventsHelperBase( rArgs ),
+ mbOpened( false )
+{
+ mpDocShell = dynamic_cast< ScDocShell* >( mpShell ); // mpShell from base class
+ mpDoc = mpDocShell ? &mpDocShell->GetDocument() : nullptr;
+
+ if( !mxModel.is() || !mpDocShell || !mpDoc )
+ return;
+
+ // global
+ auto registerAutoEvent = [this](sal_Int32 nID, const char* sName)
+ { registerEventHandler(nID, script::ModuleType::NORMAL, OString(OString::Concat("Auto_") + sName).getStr(), -1, uno::Any(false)); };
+ registerAutoEvent(AUTO_OPEN, "Open");
+ registerAutoEvent(AUTO_CLOSE, "Close");
+
+ // Workbook
+ auto registerWorkbookEvent = [this](sal_Int32 nID, const char* sName, sal_Int32 nCancelIndex)
+ { registerEventHandler(nID, script::ModuleType::DOCUMENT, OString(OString::Concat("Workbook_") + sName).getStr(), nCancelIndex, uno::Any(false)); };
+ registerWorkbookEvent( WORKBOOK_ACTIVATE, "Activate", -1 );
+ registerWorkbookEvent( WORKBOOK_DEACTIVATE, "Deactivate", -1 );
+ registerWorkbookEvent( WORKBOOK_OPEN, "Open", -1 );
+ registerWorkbookEvent( WORKBOOK_BEFORECLOSE, "BeforeClose", 0 );
+ registerWorkbookEvent( WORKBOOK_BEFOREPRINT, "BeforePrint", 0 );
+ registerWorkbookEvent( WORKBOOK_BEFORESAVE, "BeforeSave", 1 );
+ registerWorkbookEvent( WORKBOOK_AFTERSAVE, "AfterSave", -1 );
+ registerWorkbookEvent( WORKBOOK_NEWSHEET, "NewSheet", -1 );
+ registerWorkbookEvent( WORKBOOK_WINDOWACTIVATE, "WindowActivate", -1 );
+ registerWorkbookEvent( WORKBOOK_WINDOWDEACTIVATE, "WindowDeactivate", -1 );
+ registerWorkbookEvent( WORKBOOK_WINDOWRESIZE, "WindowResize", -1 );
+
+ // Worksheet events. All events have a corresponding workbook event.
+ auto registerWorksheetEvent = [this](sal_Int32 nID, const char* sName, sal_Int32 nCancelIndex)
+ {
+ registerEventHandler(nID, script::ModuleType::DOCUMENT, OString(OString::Concat("Worksheet_") + sName).getStr(),
+ nCancelIndex, uno::Any(true));
+ registerEventHandler(USERDEFINED_START + nID, script::ModuleType::DOCUMENT,
+ OString(OString::Concat("Workbook_Worksheet") + sName).getStr(),
+ ((nCancelIndex >= 0) ? (nCancelIndex + 1) : -1), uno::Any(false));
+ };
+ registerWorksheetEvent( WORKSHEET_ACTIVATE, "Activate", -1 );
+ registerWorksheetEvent( WORKSHEET_DEACTIVATE, "Deactivate", -1 );
+ registerWorksheetEvent( WORKSHEET_BEFOREDOUBLECLICK, "BeforeDoubleClick", 1 );
+ registerWorksheetEvent( WORKSHEET_BEFORERIGHTCLICK, "BeforeRightClick", 1 );
+ registerWorksheetEvent( WORKSHEET_CALCULATE, "Calculate", -1 );
+ registerWorksheetEvent( WORKSHEET_CHANGE, "Change", -1 );
+ registerWorksheetEvent( WORKSHEET_SELECTIONCHANGE, "SelectionChange", -1 );
+ registerWorksheetEvent( WORKSHEET_FOLLOWHYPERLINK, "FollowHyperlink", -1 );
+}
+
+ScVbaEventsHelper::~ScVbaEventsHelper()
+{
+}
+
+void SAL_CALL ScVbaEventsHelper::notifyEvent( const css::document::EventObject& rEvent )
+{
+ static const uno::Sequence< uno::Any > saEmptyArgs;
+ if( (rEvent.EventName == GlobalEventConfig::GetEventName( GlobalEventId::OPENDOC )) ||
+ (rEvent.EventName == GlobalEventConfig::GetEventName( GlobalEventId::CREATEDOC )) ) // CREATEDOC triggered e.g. during VBA Workbooks.Add
+ {
+ processVbaEventNoThrow( WORKBOOK_OPEN, saEmptyArgs );
+ }
+ else if( rEvent.EventName == GlobalEventConfig::GetEventName( GlobalEventId::ACTIVATEDOC ) )
+ {
+ processVbaEventNoThrow( WORKBOOK_ACTIVATE, saEmptyArgs );
+ }
+ else if( rEvent.EventName == GlobalEventConfig::GetEventName( GlobalEventId::DEACTIVATEDOC ) )
+ {
+ processVbaEventNoThrow( WORKBOOK_DEACTIVATE, saEmptyArgs );
+ }
+ else if( (rEvent.EventName == GlobalEventConfig::GetEventName( GlobalEventId::SAVEDOCDONE )) ||
+ (rEvent.EventName == GlobalEventConfig::GetEventName( GlobalEventId::SAVEASDOCDONE )) ||
+ (rEvent.EventName == GlobalEventConfig::GetEventName( GlobalEventId::SAVETODOCDONE )) )
+ {
+ uno::Sequence< uno::Any > aArgs{ uno::Any(true) };
+ processVbaEventNoThrow( WORKBOOK_AFTERSAVE, aArgs );
+ }
+ else if( (rEvent.EventName == GlobalEventConfig::GetEventName( GlobalEventId::SAVEDOCFAILED )) ||
+ (rEvent.EventName == GlobalEventConfig::GetEventName( GlobalEventId::SAVEASDOCFAILED )) ||
+ (rEvent.EventName == GlobalEventConfig::GetEventName( GlobalEventId::SAVETODOCFAILED )) )
+ {
+ uno::Sequence< uno::Any > aArgs{ uno::Any(false) };
+ processVbaEventNoThrow( WORKBOOK_AFTERSAVE, aArgs );
+ }
+ else if( rEvent.EventName == GlobalEventConfig::GetEventName( GlobalEventId::CLOSEDOC ) )
+ {
+ /* Trigger the WORKBOOK_WINDOWDEACTIVATE and WORKBOOK_DEACTIVATE
+ events and stop listening to the model (done in base class). */
+ uno::Reference< frame::XController > xController( mxModel->getCurrentController() );
+ if( xController.is() )
+ {
+ uno::Sequence< uno::Any > aArgs{ uno::Any(xController) };
+ processVbaEventNoThrow( WORKBOOK_WINDOWDEACTIVATE, aArgs );
+ }
+ processVbaEventNoThrow( WORKBOOK_DEACTIVATE, saEmptyArgs );
+ }
+ else if( rEvent.EventName == GlobalEventConfig::GetEventName( GlobalEventId::VIEWCREATED ) )
+ {
+ uno::Reference< frame::XController > xController( mxModel->getCurrentController() );
+ if( mxListener && xController.is() )
+ mxListener->startControllerListening( xController );
+ }
+ VbaEventsHelperBase::notifyEvent( rEvent );
+}
+
+OUString ScVbaEventsHelper::getImplementationName()
+{
+ return "ScVbaEventsHelper";
+}
+
+css::uno::Sequence<OUString> ScVbaEventsHelper::getSupportedServiceNames()
+{
+ return css::uno::Sequence<OUString>{
+ "com.sun.star.script.vba.VBASpreadsheetEventProcessor"};
+}
+
+// protected ------------------------------------------------------------------
+
+bool ScVbaEventsHelper::implPrepareEvent( EventQueue& rEventQueue,
+ const EventHandlerInfo& rInfo, const uno::Sequence< uno::Any >& rArgs )
+{
+ // document and document shell are needed during event processing
+ if( !mpShell || !mpDoc )
+ throw uno::RuntimeException();
+
+ /* For document events: check if events are enabled via the
+ Application.EnableEvents symbol (this is an Excel-only attribute).
+ Check this again for every event, as the event handler may change the
+ state of the EnableEvents symbol. Global events such as AUTO_OPEN and
+ AUTO_CLOSE are always enabled. */
+ bool bExecuteEvent = (rInfo.mnModuleType != script::ModuleType::DOCUMENT) || ScVbaApplication::getDocumentEventsEnabled();
+
+ // framework and Calc fire a few events before 'OnLoad', ignore them
+ if( bExecuteEvent )
+ bExecuteEvent = (rInfo.mnEventId == WORKBOOK_OPEN) ? !mbOpened : mbOpened;
+
+ // special handling for some events
+ if( bExecuteEvent ) switch( rInfo.mnEventId )
+ {
+ case WORKBOOK_OPEN:
+ {
+ // execute delayed Activate event too (see above)
+ rEventQueue.emplace_back(WORKBOOK_ACTIVATE );
+ uno::Sequence< uno::Any > aArgs{ uno::Any(mxModel->getCurrentController()) };
+ rEventQueue.emplace_back( WORKBOOK_WINDOWACTIVATE, aArgs );
+ rEventQueue.emplace_back(AUTO_OPEN );
+ // remember initial selection
+ maOldSelection <<= mxModel->getCurrentSelection();
+ }
+ break;
+ case WORKSHEET_SELECTIONCHANGE:
+ // if selection is not changed, then do not fire the event
+ bExecuteEvent = isSelectionChanged( rArgs, 0 );
+ break;
+ }
+
+ if( bExecuteEvent )
+ {
+ // add workbook event associated to a sheet event
+ bool bSheetEvent = false;
+ if( (rInfo.maUserData >>= bSheetEvent) && bSheetEvent )
+ rEventQueue.emplace_back( rInfo.mnEventId + USERDEFINED_START, rArgs );
+ }
+
+ return bExecuteEvent;
+}
+
+uno::Sequence< uno::Any > ScVbaEventsHelper::implBuildArgumentList( const EventHandlerInfo& rInfo,
+ const uno::Sequence< uno::Any >& rArgs )
+{
+ // fill arguments for workbook events associated to sheet events according to sheet events, sheet will be added below
+ bool bSheetEventAsBookEvent = rInfo.mnEventId > USERDEFINED_START;
+ sal_Int32 nEventId = bSheetEventAsBookEvent ? (rInfo.mnEventId - USERDEFINED_START) : rInfo.mnEventId;
+
+ uno::Sequence< uno::Any > aVbaArgs;
+ switch( nEventId )
+ {
+ // *** Workbook ***
+
+ // no arguments
+ case WORKBOOK_ACTIVATE:
+ case WORKBOOK_DEACTIVATE:
+ case WORKBOOK_OPEN:
+ break;
+ // 1 arg: cancel
+ case WORKBOOK_BEFORECLOSE:
+ case WORKBOOK_BEFOREPRINT:
+ aVbaArgs.realloc( 1 );
+ // current cancel state will be inserted by caller
+ break;
+ // 2 args: saveAs, cancel
+ case WORKBOOK_BEFORESAVE:
+ checkArgumentType< bool >( rArgs, 0 );
+ aVbaArgs = { rArgs[ 0 ], {} };
+ // current cancel state will be inserted by caller
+ break;
+ // 1 arg: success
+ case WORKBOOK_AFTERSAVE:
+ checkArgumentType< bool >( rArgs, 0 );
+ aVbaArgs = { rArgs[ 0 ] };
+ break;
+ // 1 arg: window
+ case WORKBOOK_WINDOWACTIVATE:
+ case WORKBOOK_WINDOWDEACTIVATE:
+ case WORKBOOK_WINDOWRESIZE:
+ aVbaArgs = { createWindow( rArgs, 0 ) };
+ break;
+ // 1 arg: worksheet
+ case WORKBOOK_NEWSHEET:
+ aVbaArgs = { createWorksheet( rArgs, 0 ) };
+ break;
+
+ // *** Worksheet ***
+
+ // no arguments
+ case WORKSHEET_ACTIVATE:
+ case WORKSHEET_CALCULATE:
+ case WORKSHEET_DEACTIVATE:
+ break;
+ // 1 arg: range
+ case WORKSHEET_CHANGE:
+ case WORKSHEET_SELECTIONCHANGE:
+ aVbaArgs = { createRange( rArgs, 0 ) };
+ break;
+ // 2 args: range, cancel
+ case WORKSHEET_BEFOREDOUBLECLICK:
+ case WORKSHEET_BEFORERIGHTCLICK:
+ aVbaArgs = { createRange( rArgs, 0 ), {} };
+ // current cancel state will be inserted by caller
+ break;
+ // 1 arg: hyperlink
+ case WORKSHEET_FOLLOWHYPERLINK:
+ aVbaArgs = { createHyperlink( rArgs, 0 ) };
+ break;
+ }
+
+ /* For workbook events associated to sheet events, the workbook event gets
+ the same arguments but with a Worksheet object in front of them. */
+ if( bSheetEventAsBookEvent )
+ {
+ sal_Int32 nLength = aVbaArgs.getLength();
+ uno::Sequence< uno::Any > aVbaArgs2( nLength + 1 );
+ auto pVbaArgs2 = aVbaArgs2.getArray();
+ *pVbaArgs2 = createWorksheet( rArgs, 0 );
+ std::copy_n(std::cbegin(aVbaArgs), nLength, std::next(pVbaArgs2));
+ aVbaArgs = aVbaArgs2;
+ }
+
+ return aVbaArgs;
+}
+
+void ScVbaEventsHelper::implPostProcessEvent( EventQueue& rEventQueue,
+ const EventHandlerInfo& rInfo, bool bCancel )
+{
+ switch( rInfo.mnEventId )
+ {
+ case WORKBOOK_OPEN:
+ mbOpened = true;
+ // register the listeners
+ if( !mxListener.is() )
+ mxListener = new ScVbaEventListener( *this, mxModel, mpDocShell );
+ break;
+ case WORKBOOK_BEFORECLOSE:
+ /* Execute Auto_Close only if not cancelled by event handler, but
+ before UI asks user whether to cancel closing the document. */
+ if( !bCancel )
+ rEventQueue.emplace_back(AUTO_CLOSE );
+ break;
+ }
+}
+
+OUString ScVbaEventsHelper::implGetDocumentModuleName( const EventHandlerInfo& rInfo,
+ const uno::Sequence< uno::Any >& rArgs ) const
+{
+ bool bSheetEvent = false;
+ rInfo.maUserData >>= bSheetEvent;
+ SCTAB nTab = bSheetEvent ? lclGetTabFromArgs( rArgs, 0 ) : -1;
+ if( bSheetEvent && (nTab < 0) )
+ throw lang::IllegalArgumentException();
+
+ OUString aCodeName;
+ if( bSheetEvent )
+ mpDoc->GetCodeName( nTab, aCodeName );
+ else
+ aCodeName = mpDoc->GetCodeName();
+ return aCodeName;
+}
+
+// private --------------------------------------------------------------------
+
+namespace {
+
+/** Compares the passed range lists representing sheet selections. Ignores
+ selections that refer to different sheets (returns false in this case). */
+bool lclSelectionChanged( const ScRangeList& rLeft, const ScRangeList& rRight )
+{
+ // one of the range lists empty? -> return false, if both lists empty
+ bool bLeftEmpty = rLeft.empty();
+ bool bRightEmpty = rRight.empty();
+ if( bLeftEmpty || bRightEmpty )
+ return !(bLeftEmpty && bRightEmpty);
+
+ // check sheet indexes of the range lists (assuming that all ranges in a list are on the same sheet)
+ if (rLeft[0].aStart.Tab() != rRight[0].aStart.Tab())
+ return false;
+
+ // compare all ranges
+ return rLeft != rRight;
+}
+
+} // namespace
+
+bool ScVbaEventsHelper::isSelectionChanged( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex )
+{
+ uno::Reference< uno::XInterface > xOldSelection( maOldSelection, uno::UNO_QUERY );
+ uno::Reference< uno::XInterface > xNewSelection = getXSomethingFromArgs< uno::XInterface >( rArgs, nIndex, false );
+ ScCellRangesBase* pOldCellRanges = comphelper::getFromUnoTunnel<ScCellRangesBase>( xOldSelection );
+ ScCellRangesBase* pNewCellRanges = comphelper::getFromUnoTunnel<ScCellRangesBase>( xNewSelection );
+ bool bChanged = !pOldCellRanges || !pNewCellRanges || lclSelectionChanged( pOldCellRanges->GetRangeList(), pNewCellRanges->GetRangeList() );
+ maOldSelection <<= xNewSelection;
+ return bChanged;
+}
+
+uno::Any ScVbaEventsHelper::createWorksheet( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) const
+{
+ // extract sheet index, will throw, if parameter is invalid
+ SCTAB nTab = lclGetTabFromArgs( rArgs, nIndex );
+ return uno::Any( excel::getUnoSheetModuleObj( mxModel, nTab ) );
+}
+
+uno::Any ScVbaEventsHelper::createRange( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) const
+{
+ // it is possible to pass an existing VBA Range object
+ uno::Reference< excel::XRange > xVbaRange = getXSomethingFromArgs< excel::XRange >( rArgs, nIndex );
+ if( !xVbaRange.is() )
+ {
+ uno::Reference< sheet::XSheetCellRangeContainer > xRanges = getXSomethingFromArgs< sheet::XSheetCellRangeContainer >( rArgs, nIndex );
+ uno::Reference< table::XCellRange > xRange = getXSomethingFromArgs< table::XCellRange >( rArgs, nIndex );
+ if ( !xRanges.is() && !xRange.is() )
+ throw lang::IllegalArgumentException();
+
+ uno::Sequence< uno::Any > aArgs;
+ if ( xRanges.is() )
+ {
+ aArgs = { uno::Any(excel::getUnoSheetModuleObj( xRanges )), uno::Any(xRanges) };
+ }
+ else
+ {
+ aArgs = { uno::Any(excel::getUnoSheetModuleObj( xRange )), uno::Any(xRange) };
+ }
+ xVbaRange.set( createVBAUnoAPIServiceWithArgs( mpShell, "ooo.vba.excel.Range", aArgs ), uno::UNO_QUERY_THROW );
+ }
+ return uno::Any( xVbaRange );
+}
+
+uno::Any ScVbaEventsHelper::createHyperlink( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) const
+{
+ uno::Reference< table::XCell > xCell = getXSomethingFromArgs< table::XCell >( rArgs, nIndex, false );
+ uno::Sequence< uno::Any > aArgs{ uno::Any(excel::getUnoSheetModuleObj( xCell )),
+ uno::Any(xCell) };
+ uno::Reference< uno::XInterface > xHyperlink( createVBAUnoAPIServiceWithArgs( mpShell, "ooo.vba.excel.Hyperlink", aArgs ), uno::UNO_SET_THROW );
+ return uno::Any( xHyperlink );
+}
+
+uno::Any ScVbaEventsHelper::createWindow( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) const
+{
+ uno::Sequence< uno::Any > aArgs{ uno::Any(getVBADocument( mxModel )),
+ uno::Any(mxModel),
+ uno::Any(getXSomethingFromArgs< frame::XController >( rArgs, nIndex, false )) };
+ uno::Reference< uno::XInterface > xWindow( createVBAUnoAPIServiceWithArgs( mpShell, "ooo.vba.excel.Window", aArgs ), uno::UNO_SET_THROW );
+ return uno::Any( xWindow );
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
+ScVbaEventsHelper_get_implementation(
+ css::uno::XComponentContext * /*context*/,
+ css::uno::Sequence<css::uno::Any> const &arguments)
+{
+ return cppu::acquire(new ScVbaEventsHelper(arguments));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaeventshelper.hxx b/sc/source/ui/vba/vbaeventshelper.hxx
new file mode 100644
index 000000000..e5bf11ecb
--- /dev/null
+++ b/sc/source/ui/vba/vbaeventshelper.hxx
@@ -0,0 +1,84 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <rtl/ref.hxx>
+#include <vbahelper/vbaeventshelperbase.hxx>
+
+class ScDocShell;
+class ScDocument;
+class ScVbaEventListener;
+
+class ScVbaEventsHelper : public VbaEventsHelperBase
+{
+public:
+ ScVbaEventsHelper( const css::uno::Sequence< css::uno::Any >& rArgs );
+ virtual ~ScVbaEventsHelper() override;
+
+ virtual void SAL_CALL notifyEvent( const css::document::EventObject& rEvent ) override;
+
+ OUString SAL_CALL getImplementationName() override;
+
+ css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
+
+protected:
+ virtual bool implPrepareEvent( EventQueue& rEventQueue, const EventHandlerInfo& rInfo, const css::uno::Sequence< css::uno::Any >& rArgs ) override;
+ virtual css::uno::Sequence< css::uno::Any > implBuildArgumentList( const EventHandlerInfo& rInfo, const css::uno::Sequence< css::uno::Any >& rArgs ) override;
+ virtual void implPostProcessEvent( EventQueue& rEventQueue, const EventHandlerInfo& rInfo, bool bCancel ) override;
+ virtual OUString implGetDocumentModuleName( const EventHandlerInfo& rInfo, const css::uno::Sequence< css::uno::Any >& rArgs ) const override;
+
+private:
+ /** Checks if selection has been changed compared to selection of last call.
+ @return true, if the selection has been changed.
+ @throws css::lang::IllegalArgumentException
+ @throws css::uno::RuntimeException
+ */
+ bool isSelectionChanged( const css::uno::Sequence< css::uno::Any >& rArgs, sal_Int32 nIndex );
+
+ /** Creates a VBA Worksheet object (the argument must contain a sheet index).
+ @throws css::lang::IllegalArgumentException
+ @throws css::uno::RuntimeException
+ */
+ css::uno::Any createWorksheet( const css::uno::Sequence< css::uno::Any >& rArgs, sal_Int32 nIndex ) const;
+ /** Creates a VBA Range object (the argument must contain a UNO range or UNO range list).
+ @throws css::lang::IllegalArgumentException
+ @throws css::uno::RuntimeException
+ */
+ css::uno::Any createRange( const css::uno::Sequence< css::uno::Any >& rArgs, sal_Int32 nIndex ) const;
+ /** Creates a VBA Hyperlink object (the argument must contain a UNO cell).
+ @throws css::lang::IllegalArgumentException
+ @throws css::uno::RuntimeException
+ */
+ css::uno::Any createHyperlink( const css::uno::Sequence< css::uno::Any >& rArgs, sal_Int32 nIndex ) const;
+ /** Creates a VBA Window object (the argument must contain a model controller).
+ @throws css::lang::IllegalArgumentException
+ @throws css::uno::RuntimeException
+ */
+ css::uno::Any createWindow( const css::uno::Sequence< css::uno::Any >& rArgs, sal_Int32 nIndex ) const;
+
+private:
+ ::rtl::Reference< ScVbaEventListener > mxListener;
+ css::uno::Any maOldSelection;
+ ScDocShell* mpDocShell;
+ ScDocument* mpDoc;
+ bool mbOpened;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbafiledialog.cxx b/sc/source/ui/vba/vbafiledialog.cxx
new file mode 100644
index 000000000..f7f31db2a
--- /dev/null
+++ b/sc/source/ui/vba/vbafiledialog.cxx
@@ -0,0 +1,174 @@
+/* -*- 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 "vbafiledialog.hxx"
+#include "vbafiledialogitems.hxx"
+
+#include <osl/file.hxx>
+
+#include <ooo/vba/office/MsoFileDialogType.hpp>
+
+#include <com/sun/star/ui/dialogs/FilePicker.hpp>
+#include <com/sun/star/ui/dialogs/FolderPicker.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+ScVbaFileDialog::ScVbaFileDialog( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const sal_Int32 nType )
+ : ScVbaFileDialog_BASE( xParent, xContext)
+ , m_nType(nType)
+ , m_sTitle("FileDialog")
+ , m_bMultiSelectMode(false)
+{}
+
+uno::Any
+ScVbaFileDialog::getInitialFileName() { return uno::Any( m_sInitialFileName ); }
+
+void ScVbaFileDialog::setInitialFileName( const css::uno::Any& rName )
+{
+ OUString sDefaultPath;
+
+ if( rName >>= sDefaultPath )
+ {
+ OUString sDefaultURL;
+ sal_Int32 eSuccess = osl::FileBase::getFileURLFromSystemPath(
+ sDefaultPath, sDefaultURL ) ;
+ if( eSuccess == osl::FileBase::RC::E_INVAL )
+ m_sInitialFileName = sDefaultPath; // the user may gave it in URL form
+ else
+ m_sInitialFileName = sDefaultURL;
+ }
+}
+
+css::uno::Any ScVbaFileDialog::getTitle() { return uno::Any( m_sTitle ); }
+
+void ScVbaFileDialog::setTitle( const css::uno::Any& rTitle )
+{
+ rTitle >>= m_sTitle;
+}
+
+uno::Any ScVbaFileDialog::getAllowMultiSelect()
+{
+ return uno::Any(m_bMultiSelectMode);
+}
+
+void ScVbaFileDialog::setAllowMultiSelect(const uno::Any& rAllowMultiSelect)
+{
+ rAllowMultiSelect >>= m_bMultiSelectMode;
+}
+
+uno::Reference< excel::XFileDialogSelectedItems > SAL_CALL ScVbaFileDialog::getSelectedItems()
+{
+ // TODO use InitialFileName when m_xItems is empty
+ return m_xItems;
+}
+
+sal_Int32 ScVbaFileDialog::Show()
+{
+ std::vector<OUString> sSelectedPaths;
+ sal_Int32 nRet = -1;
+
+ switch (m_nType)
+ {
+ case office::MsoFileDialogType::msoFileDialogOpen:
+ // TODO implement
+ break;
+ case office::MsoFileDialogType::msoFileDialogSaveAs:
+ // TODO implement
+ break;
+ case office::MsoFileDialogType::msoFileDialogFilePicker:
+ {
+ uno::Reference<ui::dialogs::XFilePicker3> xFilePicker =
+ ui::dialogs::FilePicker::createWithMode(
+ mxContext, ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE );
+
+ if( !m_sInitialFileName.isEmpty() )
+ xFilePicker->setDisplayDirectory( m_sInitialFileName );
+
+ if( xFilePicker->execute() != ui::dialogs::ExecutableDialogResults::OK )
+ {
+ nRet = 0; // cancel pressed
+ break;
+ }
+
+ const uno::Sequence<OUString> aSelectedFiles = xFilePicker->getSelectedFiles();
+ for( const auto& sURL : aSelectedFiles )
+ {
+ OUString sPath;
+ osl::FileBase::getSystemPathFromFileURL(sURL, sPath);
+
+ sSelectedPaths.push_back(sPath);
+ }
+ }
+ break;
+ case office::MsoFileDialogType::msoFileDialogFolderPicker:
+ {
+ uno::Reference< ui::dialogs::XFolderPicker2 > xFolderPicker =
+ ui::dialogs::FolderPicker::create(mxContext);
+
+ if( !m_sInitialFileName.isEmpty() )
+ xFolderPicker->setDisplayDirectory( m_sInitialFileName );
+
+ if( xFolderPicker->execute() != ui::dialogs::ExecutableDialogResults::OK )
+ {
+ nRet = 0; // cancel pressed
+ break;
+ }
+
+ OUString sURL = xFolderPicker->getDirectory();
+
+ if(!sURL.isEmpty())
+ {
+ OUString sPath;
+ osl::FileBase::getSystemPathFromFileURL(sURL, sPath);
+
+ sSelectedPaths.push_back(sPath);
+ }
+
+ }
+ break;
+ default:
+ throw uno::RuntimeException();
+ }
+
+ m_xItems = css::uno::Reference< ov::excel::XFileDialogSelectedItems >(
+ new ScVbaFileDialogSelectedItems(this, mxContext, std::move(sSelectedPaths)) );
+ return nRet;
+}
+
+// XHelperInterface
+OUString
+ScVbaFileDialog::getServiceImplName()
+{
+ return "ScVbaFileDialog";
+}
+
+uno::Sequence<OUString>
+ScVbaFileDialog::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.FileDialog"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbafiledialog.hxx b/sc/source/ui/vba/vbafiledialog.hxx
new file mode 100644
index 000000000..f339e4a97
--- /dev/null
+++ b/sc/source/ui/vba/vbafiledialog.hxx
@@ -0,0 +1,58 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <ooo/vba/excel/XFileDialog.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+
+namespace com::sun::star::uno { class XComponentContext; }
+namespace ooo::vba { class XHelperInterface; }
+namespace ooo::vba::excel { class XFileDialogSelectedItems; }
+
+typedef InheritedHelperInterfaceWeakImpl< ov::excel::XFileDialog > ScVbaFileDialog_BASE;
+
+class ScVbaFileDialog : public ScVbaFileDialog_BASE
+{
+private:
+ sal_Int32 m_nType;
+ OUString m_sTitle;
+ OUString m_sInitialFileName;
+ bool m_bMultiSelectMode;
+ css::uno::Reference< ov::excel::XFileDialogSelectedItems> m_xItems;
+public:
+ ScVbaFileDialog( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const sal_Int32 nType);
+
+ virtual css::uno::Any SAL_CALL getInitialFileName() override;
+ virtual void SAL_CALL setInitialFileName( const css::uno::Any& rName ) override;
+ virtual css::uno::Any SAL_CALL getTitle() override;
+ virtual void SAL_CALL setTitle( const css::uno::Any& rTitle ) override;
+ virtual css::uno::Any SAL_CALL getAllowMultiSelect() override;
+ virtual void SAL_CALL setAllowMultiSelect(const css::uno::Any& rAllowMultiSelect) override;
+
+ virtual css::uno::Reference< ov::excel::XFileDialogSelectedItems > SAL_CALL getSelectedItems() override;
+
+ virtual sal_Int32 SAL_CALL Show() override;
+
+ //XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbafiledialogitems.cxx b/sc/source/ui/vba/vbafiledialogitems.cxx
new file mode 100644
index 000000000..d34ace3c5
--- /dev/null
+++ b/sc/source/ui/vba/vbafiledialogitems.cxx
@@ -0,0 +1,123 @@
+/* -*- 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 <o3tl/safeint.hxx>
+
+#include "vbafiledialogitems.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+namespace {
+
+class FileDialogItemEnumeration : public ::cppu::WeakImplHelper< container::XEnumeration >
+{
+ std::vector< OUString > m_sItems;
+ std::vector< OUString >::iterator mIt;
+public:
+ explicit FileDialogItemEnumeration( std::vector< OUString >&& rVector ) : m_sItems( std::move(rVector) ), mIt( m_sItems.begin() ) {}
+ virtual sal_Bool SAL_CALL hasMoreElements() override
+ {
+ return ( mIt != m_sItems.end() );
+ }
+ virtual uno::Any SAL_CALL nextElement() override
+ {
+ if( !hasMoreElements() )
+ throw container::NoSuchElementException();
+ OUString sPath = *mIt++;
+ return uno::Any( sPath );
+ }
+};
+
+}
+
+ScVbaFileDialogSelectedItems::ScVbaFileDialogSelectedItems(
+ const css::uno::Reference< ov::XHelperInterface >& xParent
+ ,const css::uno::Reference< css::uno::XComponentContext >& xContext
+ ,std::vector< OUString >&& rItems)
+ : FileDialogSelectedItems_BASE( xParent, xContext, uno::Reference< container::XIndexAccess>() )
+ , m_sItems(std::move(rItems)) {}
+
+
+// XEnumerationAccess
+uno::Type SAL_CALL
+ScVbaFileDialogSelectedItems::getElementType()
+{
+ return cppu::UnoType<OUString>::get();
+}
+
+uno::Reference< container::XEnumeration >
+ScVbaFileDialogSelectedItems::createEnumeration()
+{
+ return uno::Reference< container::XEnumeration >( new FileDialogItemEnumeration( std::vector(m_sItems) ) );
+}
+
+uno::Any
+ScVbaFileDialogSelectedItems::createCollectionObject( const uno::Any& aSource )
+{
+ sal_Int32 nPosition = -1;
+ if (!(aSource >>= nPosition))
+ throw uno::RuntimeException("not an sal_Int32");
+ if (nPosition < 0 || o3tl::make_unsigned(nPosition) >= m_sItems.size())
+ throw uno::RuntimeException("out of range");
+
+ OUString sPath = m_sItems[nPosition];
+ return uno::Any( sPath );
+}
+
+// Methods
+uno::Any SAL_CALL
+ScVbaFileDialogSelectedItems::Item( const uno::Any& aIndex, const uno::Any& /*aIndex*/ )
+{
+ sal_Int32 nPosition = -1;
+ aIndex >>= nPosition;
+
+ --nPosition; // vba indexing starts with 1
+
+ if( nPosition < 0 || nPosition >= getCount() )
+ {
+ throw uno::RuntimeException();
+ }
+
+ return createCollectionObject( uno::Any( nPosition ) );
+}
+
+sal_Int32 ScVbaFileDialogSelectedItems::getCount()
+{
+ return m_sItems.size();
+}
+
+// XHelperInterface
+OUString
+ScVbaFileDialogSelectedItems::getServiceImplName()
+{
+ return "ScVbaFileDialogSelectedItems";
+}
+
+uno::Sequence<OUString>
+ScVbaFileDialogSelectedItems::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.FileDialogSelectedItems"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbafiledialogitems.hxx b/sc/source/ui/vba/vbafiledialogitems.hxx
new file mode 100644
index 000000000..5a01df010
--- /dev/null
+++ b/sc/source/ui/vba/vbafiledialogitems.hxx
@@ -0,0 +1,43 @@
+/* -*- 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/.
+ */
+#pragma once
+
+#include <ooo/vba/excel/XFileDialogSelectedItems.hpp>
+#include <vbahelper/vbacollectionimpl.hxx>
+
+typedef CollTestImplHelper< ov::excel::XFileDialogSelectedItems > FileDialogSelectedItems_BASE;
+
+class ScVbaFileDialogSelectedItems final : public FileDialogSelectedItems_BASE
+{
+ const std::vector<OUString> m_sItems;
+public:
+ std::vector<OUString> const& getItems()
+ {
+ return m_sItems;
+ }
+
+ ScVbaFileDialogSelectedItems( const css::uno::Reference< ov::XHelperInterface >& xParent,
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ std::vector<OUString>&& sItems);
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+
+ // Methods
+ virtual css::uno::Any SAL_CALL Item( const css::uno::Any& Index, const css::uno::Any& /*Index2*/ ) override;
+ virtual sal_Int32 SAL_CALL getCount() override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbafont.cxx b/sc/source/ui/vba/vbafont.cxx
new file mode 100644
index 000000000..99afd919b
--- /dev/null
+++ b/sc/source/ui/vba/vbafont.cxx
@@ -0,0 +1,329 @@
+/* -*- 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/awt/FontUnderline.hpp>
+#include <ooo/vba/excel/XlColorIndex.hpp>
+#include <ooo/vba/excel/XlUnderlineStyle.hpp>
+#include <svl/itemset.hxx>
+#include <o3tl/string_view.hxx>
+#include "excelvbahelper.hxx"
+#include "vbafont.hxx"
+#include "vbapalette.hxx"
+#include <scitems.hxx>
+#include <cellsuno.hxx>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+ScVbaFont::ScVbaFont(
+ const uno::Reference< XHelperInterface >& xParent,
+ const uno::Reference< uno::XComponentContext >& xContext,
+ const ScVbaPalette& dPalette,
+ const uno::Reference< beans::XPropertySet >& xPropertySet,
+ ScCellRangeObj* pRangeObj, bool bFormControl ) :
+ ScVbaFont_BASE( xParent, xContext, dPalette.getPalette(), xPropertySet, bFormControl ),
+ mpRangeObj( pRangeObj )
+{
+}
+
+SfxItemSet*
+ScVbaFont::GetDataSet()
+{
+ return mpRangeObj ? excel::ScVbaCellRangeAccess::GetDataSet( mpRangeObj ) : nullptr;
+}
+
+ScVbaFont::~ScVbaFont()
+{
+}
+
+uno::Any SAL_CALL
+ScVbaFont::getSize()
+{
+ if ( GetDataSet() )
+ if ( GetDataSet()->GetItemState( ATTR_FONT_HEIGHT) == SfxItemState::DONTCARE )
+ return aNULL();
+ return ScVbaFont_BASE::getSize();
+}
+
+void SAL_CALL
+ScVbaFont::setColorIndex( const uno::Any& _colorindex )
+{
+ if(mbFormControl)
+ return;
+
+ sal_Int32 nIndex = 0;
+ _colorindex >>= nIndex;
+ // #FIXME xlColorIndexAutomatic & xlColorIndexNone are not really
+ // handled properly here
+
+ if ( !nIndex || ( nIndex == excel::XlColorIndex::xlColorIndexAutomatic ) )
+ {
+ nIndex = 1; // check default ( assume black )
+ ScVbaFont_BASE::setColorIndex( uno::Any( nIndex ) );
+ }
+ else
+ ScVbaFont_BASE::setColorIndex( _colorindex );
+}
+
+uno::Any SAL_CALL
+ScVbaFont::getColorIndex()
+{
+ if(mbFormControl)
+ return uno::Any( sal_Int32(0) );
+ if ( GetDataSet() )
+ if ( GetDataSet()->GetItemState( ATTR_FONT_COLOR) == SfxItemState::DONTCARE )
+ return aNULL();
+ return ScVbaFont_BASE::getColorIndex();
+}
+
+void SAL_CALL
+ScVbaFont::setStandardFontSize( const uno::Any& /*aValue*/ )
+{
+//XXX #TODO# #FIXME#
+ //mxFont->setPropertyValue("CharSize", ( uno::Any )fValue );
+ throw uno::RuntimeException(
+ "setStandardFontSize not supported" );
+}
+
+uno::Any SAL_CALL
+ScVbaFont::getStandardFontSize()
+{
+//XXX #TODO# #FIXME#
+ throw uno::RuntimeException( "getStandardFontSize not supported" );
+ // return uno::Any();
+}
+
+void SAL_CALL
+ScVbaFont::setStandardFont( const uno::Any& /*aValue*/ )
+{
+//XXX #TODO# #FIXME#
+ throw uno::RuntimeException("setStandardFont not supported" );
+}
+
+uno::Any SAL_CALL
+ScVbaFont::getStandardFont()
+{
+//XXX #TODO# #FIXME#
+ throw uno::RuntimeException("getStandardFont not supported");
+ // return uno::Any();
+}
+
+void SAL_CALL
+ScVbaFont::setFontStyle( const uno::Any& aValue )
+{
+ bool bBold = false;
+ bool bItalic = false;
+
+ OUString aStyles;
+ aValue >>= aStyles;
+
+ for (sal_Int32 nIdx{ 0 }; nIdx>=0; )
+ {
+ const std::u16string_view aToken{ o3tl::getToken(aStyles, 0, ' ', nIdx ) };
+ if (o3tl::equalsIgnoreAsciiCase(aToken, u"Bold"))
+ {
+ bBold = true;
+ if (bItalic)
+ break;
+ }
+ else if (o3tl::equalsIgnoreAsciiCase(aToken, u"Italic"))
+ {
+ bItalic = true;
+ if (bBold)
+ break;
+ }
+ }
+
+ setBold( uno::Any( bBold ) );
+ setItalic( uno::Any( bItalic ) );
+}
+
+uno::Any SAL_CALL
+ScVbaFont::getFontStyle()
+{
+ OUStringBuffer aStyles;
+ bool bValue = false;
+ getBold() >>= bValue;
+ if( bValue )
+ aStyles.append("Bold");
+
+ getItalic() >>= bValue;
+ if( bValue )
+ {
+ if( !aStyles.isEmpty() )
+ aStyles.append(" ");
+ aStyles.append("Italic");
+ }
+ return uno::Any( aStyles.makeStringAndClear() );
+}
+
+uno::Any SAL_CALL
+ScVbaFont::getBold()
+{
+ if ( GetDataSet() )
+ if ( GetDataSet()->GetItemState( ATTR_FONT_WEIGHT) == SfxItemState::DONTCARE )
+ return aNULL();
+ return ScVbaFont_BASE::getBold();
+}
+
+void SAL_CALL
+ScVbaFont::setUnderline( const uno::Any& aValue )
+{
+ if(mbFormControl)
+ return;
+
+ // default
+ sal_Int32 nValue = excel::XlUnderlineStyle::xlUnderlineStyleNone;
+ aValue >>= nValue;
+ switch ( nValue )
+ {
+// NOTE:: #TODO #FIMXE
+// xlUnderlineStyleDoubleAccounting & xlUnderlineStyleSingleAccounting
+// don't seem to be supported in Openoffice.
+// The import filter converts them to single or double underlines as appropriate
+// So, here at the moment we are similarly silently converting
+// xlUnderlineStyleSingleAccounting to xlUnderlineStyleSingle.
+
+ case excel::XlUnderlineStyle::xlUnderlineStyleNone:
+ nValue = awt::FontUnderline::NONE;
+ break;
+ case excel::XlUnderlineStyle::xlUnderlineStyleSingle:
+ case excel::XlUnderlineStyle::xlUnderlineStyleSingleAccounting:
+ nValue = awt::FontUnderline::SINGLE;
+ break;
+ case excel::XlUnderlineStyle::xlUnderlineStyleDouble:
+ case excel::XlUnderlineStyle::xlUnderlineStyleDoubleAccounting:
+ nValue = awt::FontUnderline::DOUBLE;
+ break;
+ default:
+ throw uno::RuntimeException("Unknown value for Underline" );
+ }
+
+ mxFont->setPropertyValue("CharUnderline", uno::Any(nValue) );
+
+}
+
+uno::Any SAL_CALL
+ScVbaFont::getUnderline()
+{
+ if ( GetDataSet() )
+ if ( GetDataSet()->GetItemState( ATTR_FONT_UNDERLINE) == SfxItemState::DONTCARE )
+ return aNULL();
+
+ sal_Int32 nValue = awt::FontUnderline::NONE;
+
+ if(mbFormControl)
+ return uno::Any( nValue );
+
+ mxFont->getPropertyValue("CharUnderline") >>= nValue;
+ switch ( nValue )
+ {
+ case awt::FontUnderline::DOUBLE:
+ nValue = excel::XlUnderlineStyle::xlUnderlineStyleDouble;
+ break;
+ case awt::FontUnderline::SINGLE:
+ nValue = excel::XlUnderlineStyle::xlUnderlineStyleSingle;
+ break;
+ case awt::FontUnderline::NONE:
+ nValue = excel::XlUnderlineStyle::xlUnderlineStyleNone;
+ break;
+ default:
+ throw uno::RuntimeException("Unknown value retrieved for Underline" );
+
+ }
+ return uno::Any( nValue );
+}
+
+uno::Any SAL_CALL
+ScVbaFont::getStrikethrough()
+{
+ if ( GetDataSet() )
+ if ( GetDataSet()->GetItemState( ATTR_FONT_CROSSEDOUT) == SfxItemState::DONTCARE )
+ return aNULL();
+ return ScVbaFont_BASE::getStrikethrough();
+}
+
+uno::Any SAL_CALL
+ScVbaFont::getShadow()
+{
+ if ( GetDataSet() )
+ if ( GetDataSet()->GetItemState( ATTR_FONT_SHADOWED) == SfxItemState::DONTCARE )
+ return aNULL();
+ return ScVbaFont_BASE::getShadow();
+}
+
+uno::Any SAL_CALL
+ScVbaFont::getItalic()
+{
+ if ( GetDataSet() )
+ if ( GetDataSet()->GetItemState( ATTR_FONT_POSTURE) == SfxItemState::DONTCARE )
+ return aNULL();
+
+ return ScVbaFont_BASE::getItalic();
+}
+
+uno::Any SAL_CALL
+ScVbaFont::getName()
+{
+ if ( GetDataSet() )
+ if ( GetDataSet()->GetItemState( ATTR_FONT) == SfxItemState::DONTCARE )
+ return aNULL();
+ return ScVbaFont_BASE::getName();
+}
+uno::Any
+ScVbaFont::getColor()
+{
+ // #TODO #FIXME - behave like getXXX above ( wrt. GetDataSet )
+ uno::Any aAny = OORGBToXLRGB( mxFont->getPropertyValue("CharColor") );
+ return aAny;
+}
+
+void SAL_CALL
+ScVbaFont::setOutlineFont( const uno::Any& aValue )
+{
+ if(!mbFormControl)
+ mxFont->setPropertyValue("CharContoured", aValue );
+}
+
+uno::Any SAL_CALL
+ScVbaFont::getOutlineFont()
+{
+ if ( GetDataSet() )
+ if ( GetDataSet()->GetItemState( ATTR_FONT_CONTOUR) == SfxItemState::DONTCARE )
+ return aNULL();
+ return mbFormControl ? uno::Any( false ) : mxFont->getPropertyValue("CharContoured");
+}
+
+OUString
+ScVbaFont::getServiceImplName()
+{
+ return "ScVbaFont";
+}
+
+uno::Sequence< OUString >
+ScVbaFont::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.Font"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbafont.hxx b/sc/source/ui/vba/vbafont.hxx
new file mode 100644
index 000000000..d6a01b9a0
--- /dev/null
+++ b/sc/source/ui/vba/vbafont.hxx
@@ -0,0 +1,76 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <cppuhelper/implbase.hxx>
+
+#include <ooo/vba/excel/XFont.hpp>
+#include <vbahelper/vbafontbase.hxx>
+
+namespace com::sun::star::beans
+{
+class XPropertySet;
+}
+
+class ScCellRangeObj;
+class SfxItemSet;
+class ScVbaPalette;
+
+typedef cppu::ImplInheritanceHelper<VbaFontBase, ov::excel::XFont> ScVbaFont_BASE;
+
+class ScVbaFont : public ScVbaFont_BASE
+{
+ ScCellRangeObj* mpRangeObj;
+ SfxItemSet* GetDataSet();
+
+public:
+ /// @throws css::uno::RuntimeException
+ ScVbaFont(const css::uno::Reference<ov::XHelperInterface>& xParent,
+ const css::uno::Reference<css::uno::XComponentContext>& xContext,
+ const ScVbaPalette& dPalette,
+ const css::uno::Reference<css::beans::XPropertySet>& xPropertySet,
+ ScCellRangeObj* pRangeObj = nullptr, bool bFormControl = false);
+ virtual ~ScVbaFont() override; // {}
+
+ // Attributes
+ virtual css::uno::Any SAL_CALL getSize() override;
+ virtual css::uno::Any SAL_CALL getStandardFontSize() override;
+ virtual void SAL_CALL setStandardFontSize(const css::uno::Any& _standardfontsize) override;
+ virtual css::uno::Any SAL_CALL getStandardFont() override;
+ virtual void SAL_CALL setStandardFont(const css::uno::Any& _standardfont) override;
+ virtual css::uno::Any SAL_CALL getFontStyle() override;
+ virtual void SAL_CALL setFontStyle(const css::uno::Any& _fontstyle) override;
+ virtual css::uno::Any SAL_CALL getColorIndex() override;
+ virtual void SAL_CALL setColorIndex(const css::uno::Any& _colorindex) override;
+ virtual css::uno::Any SAL_CALL getBold() override;
+ virtual css::uno::Any SAL_CALL getUnderline() override;
+ virtual void SAL_CALL setUnderline(const css::uno::Any& _underline) override;
+ virtual css::uno::Any SAL_CALL getStrikethrough() override;
+ virtual css::uno::Any SAL_CALL getShadow() override;
+ virtual css::uno::Any SAL_CALL getItalic() override;
+ virtual css::uno::Any SAL_CALL getName() override;
+ virtual css::uno::Any SAL_CALL getColor() override;
+ virtual css::uno::Any SAL_CALL getOutlineFont() override;
+ virtual void SAL_CALL setOutlineFont(const css::uno::Any& _outlinefont) override;
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaformat.cxx b/sc/source/ui/vba/vbaformat.cxx
new file mode 100644
index 000000000..a027279ae
--- /dev/null
+++ b/sc/source/ui/vba/vbaformat.cxx
@@ -0,0 +1,814 @@
+/* -*- 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 "vbaformat.hxx"
+#include <ooo/vba/excel/XFont.hpp>
+#include <ooo/vba/excel/XStyle.hpp>
+#include <ooo/vba/excel/XlVAlign.hpp>
+#include <ooo/vba/excel/XlHAlign.hpp>
+#include <ooo/vba/excel/XlOrientation.hpp>
+#include <ooo/vba/excel/Constants.hpp>
+#include <ooo/vba/excel/XRange.hpp>
+#include <com/sun/star/table/CellVertJustify2.hpp>
+#include <com/sun/star/table/CellHoriJustify.hpp>
+#include <com/sun/star/table/CellOrientation.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/text/WritingMode.hpp>
+#include <com/sun/star/util/CellProtection.hpp>
+#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
+#include <com/sun/star/util/XNumberFormats.hpp>
+#include <com/sun/star/util/XNumberFormatTypes.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+
+#include <basic/sberrors.hxx>
+#include <rtl/math.hxx>
+
+#include "excelvbahelper.hxx"
+#include "vbaborders.hxx"
+#include "vbapalette.hxx"
+#include "vbafont.hxx"
+#include "vbainterior.hxx"
+
+#include <docsh.hxx>
+#include <unonames.hxx>
+#include <cellsuno.hxx>
+#include <scitems.hxx>
+#include <attrib.hxx>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+constexpr OUStringLiteral FORMATSTRING = u"FormatString";
+constexpr OUStringLiteral LOCALE = u"Locale";
+
+template< typename... Ifc >
+ScVbaFormat< Ifc... >::ScVbaFormat( const uno::Reference< XHelperInterface >& xParent,
+ const uno::Reference< uno::XComponentContext > & xContext,
+ const uno::Reference< beans::XPropertySet >& _xPropertySet,
+ const uno::Reference< frame::XModel >& xModel,
+ bool bCheckAmbiguoity )
+ : ScVbaFormat_BASE( xParent, xContext ),
+ m_aDefaultLocale( "en", "US", OUString() ),
+ mxPropertySet( _xPropertySet ),
+ mxModel( xModel ),
+ mbCheckAmbiguoity( bCheckAmbiguoity ),
+ mbAddIndent( false )
+{
+ try
+ {
+ if ( !mxModel.is() )
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, u"XModel Interface could not be retrieved" );
+ // mxServiceInfo is unused,
+ // mxNumberFormatsSupplier is initialized when needed in initializeNumberFormats.
+ }
+ catch (const uno::Exception& )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {} );
+ }
+}
+
+template< typename... Ifc >
+void SAL_CALL
+ScVbaFormat< Ifc... >::setVerticalAlignment( const uno::Any& _oAlignment)
+{
+ try
+ {
+ uno::Any aVal;
+ sal_Int32 nAlignment = 0;
+ if ( !(_oAlignment >>= nAlignment ))
+ throw uno::RuntimeException();
+ switch (nAlignment)
+ {
+ case excel::XlVAlign::xlVAlignBottom :
+ aVal <<= table::CellVertJustify2::BOTTOM;
+ break;
+ case excel::XlVAlign::xlVAlignCenter :
+ aVal <<= table::CellVertJustify2::CENTER;
+ break;
+ case excel::XlVAlign::xlVAlignDistributed:
+ case excel::XlVAlign::xlVAlignJustify:
+ aVal <<= table::CellVertJustify2::STANDARD;
+ break;
+
+ case excel::XlVAlign::xlVAlignTop:
+ aVal <<= table::CellVertJustify2::TOP;
+ break;
+ default:
+ aVal <<= table::CellVertJustify2::STANDARD;
+ break;
+ }
+ mxPropertySet->setPropertyValue( SC_UNONAME_CELLVJUS, aVal );
+ }
+ catch (const uno::Exception&)
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+}
+
+template< typename... Ifc >
+uno::Any SAL_CALL
+ScVbaFormat< Ifc... >::getVerticalAlignment( )
+{
+ uno::Any aResult = aNULL();
+ try
+ {
+ if (!isAmbiguous( SC_UNONAME_CELLVJUS ) )
+ {
+ sal_Int32 aAPIAlignment = table::CellVertJustify2::STANDARD;
+ mxPropertySet->getPropertyValue( SC_UNONAME_CELLVJUS ) >>= aAPIAlignment;
+ switch( aAPIAlignment )
+ {
+ case table::CellVertJustify2::BOTTOM:
+ aResult <<= excel::XlVAlign::xlVAlignBottom;
+ break;
+ case table::CellVertJustify2::CENTER:
+ aResult <<= excel::XlVAlign::xlVAlignCenter;
+ break;
+ case table::CellVertJustify2::STANDARD:
+ aResult <<= excel::XlVAlign::xlVAlignBottom;
+ break;
+ case table::CellVertJustify2::TOP:
+ aResult <<= excel::XlVAlign::xlVAlignTop;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ catch (const uno::Exception& )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+ return aResult;
+}
+
+template< typename... Ifc >
+void SAL_CALL
+ScVbaFormat< Ifc... >::setHorizontalAlignment( const uno::Any& HorizontalAlignment )
+{
+ try
+ {
+ uno::Any aVal;
+ sal_Int32 nAlignment = 0;
+ if ( !( HorizontalAlignment >>= nAlignment ) )
+ throw uno::RuntimeException();
+ switch ( nAlignment )
+ {
+ case excel::XlHAlign::xlHAlignJustify:
+ aVal <<= table::CellHoriJustify_BLOCK;
+ break;
+ case excel::XlHAlign::xlHAlignCenter:
+ aVal <<= table::CellHoriJustify_CENTER;
+ break;
+ case excel::XlHAlign::xlHAlignDistributed:
+ aVal <<= table::CellHoriJustify_BLOCK;
+ break;
+ case excel::XlHAlign::xlHAlignLeft:
+ aVal <<= table::CellHoriJustify_LEFT;
+ break;
+ case excel::XlHAlign::xlHAlignRight:
+ aVal <<= table::CellHoriJustify_RIGHT;
+ break;
+ }
+ // #FIXME what about the default case above?
+ // shouldn't need the test below
+ if ( aVal.hasValue() )
+ mxPropertySet->setPropertyValue( SC_UNONAME_CELLHJUS, aVal );
+ }
+ catch (const uno::Exception& )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {} );
+ }
+
+}
+
+template< typename... Ifc >
+uno::Any SAL_CALL
+ScVbaFormat< Ifc... >::getHorizontalAlignment( )
+{
+ uno::Any NRetAlignment = aNULL();
+ try
+ {
+ OUString sHoriJust( SC_UNONAME_CELLHJUS );
+ if (!isAmbiguous(sHoriJust))
+ {
+ table::CellHoriJustify aAPIAlignment = table::CellHoriJustify_BLOCK;
+
+ if ( mxPropertySet->getPropertyValue(sHoriJust) >>= aAPIAlignment )
+ {
+ switch( aAPIAlignment )
+ {
+ case table::CellHoriJustify_BLOCK:
+ NRetAlignment <<= excel::XlHAlign::xlHAlignJustify;
+ break;
+ case table::CellHoriJustify_CENTER:
+ NRetAlignment <<= excel::XlHAlign::xlHAlignCenter;
+ break;
+ case table::CellHoriJustify_LEFT:
+ NRetAlignment <<= excel::XlHAlign::xlHAlignLeft;
+ break;
+ case table::CellHoriJustify_RIGHT:
+ NRetAlignment <<= excel::XlHAlign::xlHAlignRight;
+ break;
+ default: // handle those other cases with a NULL return
+ break;
+ }
+ }
+ }
+ }
+ catch (const uno::Exception& )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {} );
+ }
+ return NRetAlignment;
+}
+
+template< typename... Ifc >
+void SAL_CALL
+ScVbaFormat< Ifc... >::setOrientation( const uno::Any& _aOrientation )
+{
+ try
+ {
+ sal_Int32 nOrientation = 0;
+ if ( !( _aOrientation >>= nOrientation ) )
+ throw uno::RuntimeException();
+ uno::Any aVal;
+ switch( nOrientation )
+ {
+ case excel::XlOrientation::xlDownward:
+ aVal <<= table::CellOrientation_TOPBOTTOM;
+ break;
+ case excel::XlOrientation::xlHorizontal:
+ aVal <<= table::CellOrientation_STANDARD;
+ mxPropertySet->setPropertyValue( SC_UNONAME_ROTANG, uno::Any( sal_Int32(0) ) );
+ break;
+ case excel::XlOrientation::xlUpward:
+ aVal <<= table::CellOrientation_BOTTOMTOP;
+ break;
+ case excel::XlOrientation::xlVertical:
+ aVal <<= table::CellOrientation_STACKED;
+ break;
+ }
+ // #FIXME what about the default case above?
+ // shouldn't need the test below
+ if ( aVal.hasValue() )
+ mxPropertySet->setPropertyValue( SC_UNONAME_CELLORI, aVal );
+
+ }
+ catch (const uno::Exception& )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {} );
+ }
+}
+template< typename... Ifc >
+uno::Any SAL_CALL
+ScVbaFormat< Ifc... >::getOrientation( )
+{
+ uno::Any NRetOrientation = aNULL();
+ try
+ {
+ if (!isAmbiguous(SC_UNONAME_CELLORI))
+ {
+ table::CellOrientation aOrientation = table::CellOrientation_STANDARD;
+ if ( !( mxPropertySet->getPropertyValue( SC_UNONAME_CELLORI ) >>= aOrientation ) )
+ throw uno::RuntimeException();
+
+ switch(aOrientation)
+ {
+ case table::CellOrientation_STANDARD:
+ NRetOrientation <<= excel::XlOrientation::xlHorizontal;
+ break;
+ case table::CellOrientation_BOTTOMTOP:
+ NRetOrientation <<= excel::XlOrientation::xlUpward;
+ break;
+ case table::CellOrientation_TOPBOTTOM:
+ NRetOrientation <<= excel::XlOrientation::xlDownward;
+ break;
+ case table::CellOrientation_STACKED:
+ NRetOrientation <<= excel::XlOrientation::xlVertical;
+ break;
+ default:
+ NRetOrientation <<= excel::XlOrientation::xlHorizontal;
+ }
+ }
+ }
+ catch (const uno::Exception& )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+ return NRetOrientation;
+}
+
+template< typename... Ifc >
+void SAL_CALL
+ScVbaFormat< Ifc... >::setWrapText( const uno::Any& _aWrapText )
+{
+ try
+ {
+ mxPropertySet->setPropertyValue( SC_UNONAME_WRAP, _aWrapText);
+ }
+ catch (const uno::Exception& )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {} );
+ }
+}
+
+template< typename... Ifc >
+uno::Any SAL_CALL
+ScVbaFormat< Ifc... >::getWrapText( )
+{
+ uno::Any aWrap = aNULL();
+ try
+ {
+ OUString aPropName( SC_UNONAME_WRAP );
+ if (!isAmbiguous( aPropName ))
+ {
+ aWrap = mxPropertySet->getPropertyValue(aPropName);
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {} );
+ }
+ return aWrap;
+}
+
+template< typename... Ifc >
+uno::Any SAL_CALL
+ScVbaFormat< Ifc... >::Borders( const uno::Any& Index )
+{
+ ScVbaPalette aPalette( excel::getDocShell( mxModel ) );
+ uno::Reference< XCollection > xColl = new ScVbaBorders( thisHelperIface(), ScVbaFormat_BASE::mxContext, uno::Reference< table::XCellRange >( mxPropertySet, uno::UNO_QUERY_THROW ), aPalette );
+
+ if ( Index.hasValue() )
+ {
+ return xColl->Item( Index, uno::Any() );
+ }
+ return uno::Any( xColl );
+}
+
+template< typename... Ifc >
+uno::Reference< excel::XFont > SAL_CALL
+ScVbaFormat< Ifc... >::Font( )
+{
+ ScVbaPalette aPalette( excel::getDocShell( mxModel ) );
+ return new ScVbaFont( thisHelperIface(), ScVbaFormat_BASE::mxContext, aPalette, mxPropertySet );
+}
+
+template< typename... Ifc >
+uno::Reference< excel::XInterior > SAL_CALL
+ScVbaFormat< Ifc... >::Interior( )
+{
+ return new ScVbaInterior( thisHelperIface(), ScVbaFormat_BASE::mxContext, mxPropertySet );
+}
+
+template< typename... Ifc >
+uno::Any SAL_CALL
+ScVbaFormat< Ifc... >::getNumberFormatLocal( )
+{
+ uno::Any aRet{ OUString() };
+ try
+ {
+ OUString sPropName( SC_UNO_DP_NUMBERFO );
+ if (!isAmbiguous( sPropName ))
+ {
+
+ initializeNumberFormats();
+
+ sal_Int32 nFormat = 0;
+ if ( ! (mxPropertySet->getPropertyValue( sPropName ) >>= nFormat ) )
+ throw uno::RuntimeException();
+
+ OUString sFormat;
+ xNumberFormats->getByKey(nFormat)->getPropertyValue( FORMATSTRING ) >>= sFormat;
+ aRet <<= sFormat.toAsciiLowerCase();
+
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+ return aRet;
+
+}
+
+template< typename... Ifc >
+void SAL_CALL
+ScVbaFormat< Ifc... >::setNumberFormatLocal( const uno::Any& _oLocalFormatString )
+{
+ try
+ {
+ OUString sLocalFormatString;
+ sal_Int32 nFormat = -1;
+ OUString sNumFormat( SC_UNO_DP_NUMBERFO );
+ if ( !(_oLocalFormatString >>= sLocalFormatString )
+ || !( mxPropertySet->getPropertyValue(sNumFormat) >>= nFormat ) )
+ throw uno::RuntimeException();
+
+ sLocalFormatString = sLocalFormatString.toAsciiUpperCase();
+ initializeNumberFormats();
+ lang::Locale aRangeLocale;
+ xNumberFormats->getByKey(nFormat)->getPropertyValue( LOCALE ) >>= aRangeLocale;
+ sal_Int32 nNewFormat = xNumberFormats->queryKey(sLocalFormatString, aRangeLocale, true);
+
+ if (nNewFormat == -1)
+ nNewFormat = xNumberFormats->addNew(sLocalFormatString, aRangeLocale);
+ mxPropertySet->setPropertyValue(sNumFormat, uno::Any( nNewFormat ));
+ }
+ catch (const uno::Exception& )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {} );
+ }
+}
+
+template< typename... Ifc >
+void SAL_CALL
+ScVbaFormat< Ifc... >::setNumberFormat( const uno::Any& _oFormatString )
+{
+ try
+ {
+ OUString sFormatString;
+ if ( !( _oFormatString >>= sFormatString ) )
+ throw uno::RuntimeException();
+
+ sFormatString = sFormatString.toAsciiUpperCase();
+
+ lang::Locale aDefaultLocale = m_aDefaultLocale;
+ initializeNumberFormats();
+ sal_Int32 nFormat = xNumberFormats->queryKey(sFormatString, aDefaultLocale, true);
+
+ if (nFormat == -1)
+ nFormat = xNumberFormats->addNew(sFormatString, aDefaultLocale);
+
+ lang::Locale aRangeLocale;
+ xNumberFormats->getByKey(nFormat)->getPropertyValue( LOCALE ) >>= aRangeLocale;
+ sal_Int32 nNewFormat = xNumberFormatTypes->getFormatForLocale(nFormat, aRangeLocale);
+ mxPropertySet->setPropertyValue( SC_UNO_DP_NUMBERFO, uno::Any( nNewFormat));
+ }
+ catch (const uno::Exception& )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+
+}
+
+template< typename... Ifc >
+void SAL_CALL
+ScVbaFormat< Ifc... >::setIndentLevel( const uno::Any& _aLevel )
+{
+ try
+ {
+ sal_Int32 nLevel = 0;
+ if ( !(_aLevel >>= nLevel ) )
+ throw uno::RuntimeException();
+ table::CellHoriJustify aAPIAlignment = table::CellHoriJustify_STANDARD;
+
+ OUString sHoriJust( SC_UNONAME_CELLHJUS );
+ if ( !( mxPropertySet->getPropertyValue(sHoriJust) >>= aAPIAlignment ) )
+ throw uno::RuntimeException();
+ if (aAPIAlignment == table::CellHoriJustify_STANDARD)
+ mxPropertySet->setPropertyValue( sHoriJust, uno::Any( table::CellHoriJustify_LEFT) ) ;
+ mxPropertySet->setPropertyValue( SC_UNONAME_PINDENT, uno::Any( sal_Int16(nLevel * 352.8) ) );
+ }
+ catch (const uno::Exception&)
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+}
+
+template< typename... Ifc >
+uno::Any SAL_CALL
+ScVbaFormat< Ifc... >::getIndentLevel( )
+{
+ uno::Any NRetIndentLevel = aNULL();
+ try
+ {
+ OUString sParaIndent( SC_UNONAME_PINDENT );
+ if (!isAmbiguous(sParaIndent))
+ {
+ sal_Int16 IndentLevel = 0;
+ if ( mxPropertySet->getPropertyValue(sParaIndent) >>= IndentLevel )
+ NRetIndentLevel <<= sal_Int32( rtl::math::round(static_cast<double>( IndentLevel ) / 352.8));
+ else
+ NRetIndentLevel <<= sal_Int32(0);
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+ return NRetIndentLevel;
+}
+
+template< typename... Ifc >
+void SAL_CALL
+ScVbaFormat< Ifc... >::setLocked( const uno::Any& _aLocked )
+{
+ try
+ {
+ bool bIsLocked = false;
+ if ( !( _aLocked >>= bIsLocked ) )
+ throw uno::RuntimeException();
+ util::CellProtection aCellProtection;
+ OUString sCellProt( SC_UNONAME_CELLPRO );
+ mxPropertySet->getPropertyValue(sCellProt) >>= aCellProtection;
+ aCellProtection.IsLocked = bIsLocked;
+ mxPropertySet->setPropertyValue(sCellProt, uno::Any( aCellProtection ) );
+ }
+ catch (const uno::Exception&)
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {} );
+ }
+}
+
+template< typename... Ifc >
+void SAL_CALL
+ScVbaFormat< Ifc... >::setFormulaHidden( const uno::Any& FormulaHidden )
+{
+ try
+ {
+ bool bIsFormulaHidden = false;
+ FormulaHidden >>= bIsFormulaHidden;
+ util::CellProtection aCellProtection;
+ OUString sCellProt( SC_UNONAME_CELLPRO );
+ mxPropertySet->getPropertyValue(sCellProt) >>= aCellProtection;
+ aCellProtection.IsFormulaHidden = bIsFormulaHidden;
+ mxPropertySet->setPropertyValue(sCellProt,uno::Any(aCellProtection));
+ }
+ catch (const uno::Exception&)
+ {
+ DebugHelper::basicexception( ERRCODE_BASIC_METHOD_FAILED, {} );
+ }
+}
+
+template< typename... Ifc >
+uno::Any SAL_CALL
+ScVbaFormat< Ifc... >::getLocked( )
+{
+ uno::Any aCellProtection = aNULL();
+ try
+ {
+ OUString sCellProt( SC_UNONAME_CELLPRO );
+
+ if (!isAmbiguous(sCellProt))
+ {
+ SfxItemSet* pDataSet = getCurrentDataSet();
+ if ( pDataSet )
+ {
+ const ScProtectionAttr& rProtAttr = pDataSet->Get(ATTR_PROTECTION);
+ SfxItemState eState = pDataSet->GetItemState(ATTR_PROTECTION);
+ if(eState != SfxItemState::DONTCARE)
+ aCellProtection <<= rProtAttr.GetProtection();
+ }
+ else // fallback to propertyset
+ {
+ util::CellProtection cellProtection;
+ mxPropertySet->getPropertyValue(sCellProt) >>= cellProtection;
+ aCellProtection <<= cellProtection.IsLocked;
+ }
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+ return aCellProtection;
+}
+
+template< typename... Ifc >
+uno::Any SAL_CALL
+ScVbaFormat< Ifc... >::getFormulaHidden( )
+{
+ uno::Any aBoolRet = aNULL();
+ try
+ {
+ OUString sCellProt( SC_UNONAME_CELLPRO );
+ if (!isAmbiguous(sCellProt))
+ {
+ SfxItemSet* pDataSet = getCurrentDataSet();
+ if ( pDataSet )
+ {
+ const ScProtectionAttr& rProtAttr = pDataSet->Get(ATTR_PROTECTION);
+ SfxItemState eState = pDataSet->GetItemState(ATTR_PROTECTION);
+ if(eState != SfxItemState::DONTCARE)
+ aBoolRet <<= rProtAttr.GetHideFormula();
+ }
+ else
+ {
+ util::CellProtection aCellProtection;
+ mxPropertySet->getPropertyValue(sCellProt) >>= aCellProtection;
+ aBoolRet <<= aCellProtection.IsFormulaHidden;
+ }
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+ return aBoolRet;
+}
+
+template< typename... Ifc >
+void SAL_CALL
+ScVbaFormat< Ifc... >::setShrinkToFit( const uno::Any& ShrinkToFit )
+{
+ try
+ {
+ mxPropertySet->setPropertyValue( SC_UNONAME_SHRINK_TO_FIT, ShrinkToFit);
+ }
+ catch (const uno::Exception& )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_NOT_IMPLEMENTED, {} );
+ }
+
+}
+
+template< typename... Ifc >
+uno::Any SAL_CALL
+ScVbaFormat< Ifc... >::getShrinkToFit( )
+{
+ uno::Any aRet = aNULL();
+ try
+ {
+ OUString sShrinkToFit( SC_UNONAME_SHRINK_TO_FIT );
+ if (!isAmbiguous(sShrinkToFit))
+ aRet = mxPropertySet->getPropertyValue(sShrinkToFit);
+ }
+ catch (const uno::Exception& )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_NOT_IMPLEMENTED, {});
+ }
+ return aRet;
+}
+
+template< typename... Ifc >
+void SAL_CALL
+ScVbaFormat< Ifc... >::setReadingOrder( const uno::Any& ReadingOrder )
+{
+ try
+ {
+ sal_Int32 nReadingOrder = 0;
+ if ( !(ReadingOrder >>= nReadingOrder ))
+ throw uno::RuntimeException();
+ uno::Any aVal = aNULL();
+ switch(nReadingOrder)
+ {
+ case excel::Constants::xlLTR:
+ aVal <<= sal_Int16(text::WritingMode_LR_TB);
+ break;
+ case excel::Constants::xlRTL:
+ aVal <<= sal_Int16(text::WritingMode_RL_TB);
+ break;
+ case excel::Constants::xlContext:
+ // TODO implement xlContext
+ // Reading order has to depend on the language of the first letter
+ // written.
+ aVal <<= sal_Int16(text::WritingMode_LR_TB);
+ break;
+ default:
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+ mxPropertySet->setPropertyValue( SC_UNONAME_WRITING, aVal );
+ }
+ catch (const uno::Exception& )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+
+}
+
+template< typename... Ifc >
+uno::Any SAL_CALL
+ScVbaFormat< Ifc... >::getReadingOrder( )
+{
+ uno::Any NRetReadingOrder = aNULL();
+ try
+ {
+ OUString sWritingMode( SC_UNONAME_WRITING );
+ if (!isAmbiguous(sWritingMode))
+ {
+ text::WritingMode aWritingMode = text::WritingMode_LR_TB;
+ if ( ( mxPropertySet->getPropertyValue(sWritingMode) ) >>= aWritingMode )
+ switch (aWritingMode)
+ {
+ case text::WritingMode_LR_TB:
+ NRetReadingOrder <<= excel::Constants::xlLTR;
+ break;
+ case text::WritingMode_RL_TB:
+ NRetReadingOrder <<= excel::Constants::xlRTL;
+ break;
+ default:
+ NRetReadingOrder <<= excel::Constants::xlRTL;
+ }
+ }
+ }
+ catch (const uno::Exception& )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_NOT_IMPLEMENTED, {});
+ }
+ return NRetReadingOrder;
+
+}
+
+template< typename... Ifc >
+uno::Any SAL_CALL
+ScVbaFormat< Ifc... >::getNumberFormat( )
+{
+ uno::Any aFormat = aNULL();
+ try
+ {
+ sal_Int32 nFormat = -1;
+ OUString sNumFormat( SC_UNO_DP_NUMBERFO );
+ if (!isAmbiguous(sNumFormat) &&
+ ( mxPropertySet->getPropertyValue(sNumFormat) >>= nFormat) )
+ {
+ initializeNumberFormats();
+
+ sal_Int32 nNewFormat = xNumberFormatTypes->getFormatForLocale(nFormat, m_aDefaultLocale );
+ OUString sFormat;
+ xNumberFormats->getByKey(nNewFormat)->getPropertyValue( FORMATSTRING ) >>= sFormat;
+ aFormat <<= sFormat;
+ }
+ }
+ catch (const uno::Exception& )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+ return aFormat;
+}
+
+template< typename... Ifc >
+bool
+ScVbaFormat< Ifc... >::isAmbiguous(const OUString& _sPropertyName)
+{
+ bool bResult = false;
+ try
+ {
+ if (mbCheckAmbiguoity)
+ bResult = ( getXPropertyState()->getPropertyState(_sPropertyName) == beans::PropertyState_AMBIGUOUS_VALUE );
+ }
+ catch (const uno::Exception& )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+ return bResult;
+}
+
+template< typename... Ifc >
+void
+ScVbaFormat< Ifc... >::initializeNumberFormats()
+{
+ if ( !xNumberFormats.is() )
+ {
+ mxNumberFormatsSupplier.set( mxModel, uno::UNO_QUERY_THROW );
+ xNumberFormats = mxNumberFormatsSupplier->getNumberFormats();
+ xNumberFormatTypes.set( xNumberFormats, uno::UNO_QUERY ); // _THROW?
+ }
+}
+
+template< typename... Ifc >
+uno::Reference< beans::XPropertyState > const &
+ScVbaFormat< Ifc... >::getXPropertyState()
+{
+ if ( !xPropertyState.is() )
+ xPropertyState.set( mxPropertySet, uno::UNO_QUERY_THROW );
+ return xPropertyState;
+}
+
+template< typename... Ifc >
+ScCellRangesBase*
+ScVbaFormat< Ifc... >::getCellRangesBase()
+{
+ return comphelper::getFromUnoTunnel<ScCellRangesBase>( mxPropertySet );
+}
+
+template< typename... Ifc >
+SfxItemSet*
+ScVbaFormat< Ifc... >::getCurrentDataSet()
+{
+ SfxItemSet* pDataSet = excel::ScVbaCellRangeAccess::GetDataSet( getCellRangesBase() );
+ if ( !pDataSet )
+ throw uno::RuntimeException("Can't access Itemset for XPropertySet" );
+ return pDataSet;
+}
+
+template class ScVbaFormat< excel::XStyle >;
+template class ScVbaFormat< excel::XRange >;
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaformat.hxx b/sc/source/ui/vba/vbaformat.hxx
new file mode 100644
index 000000000..f3c6750ce
--- /dev/null
+++ b/sc/source/ui/vba/vbaformat.hxx
@@ -0,0 +1,154 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <com/sun/star/lang/Locale.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+
+namespace com::sun::star::beans { class XPropertySet; }
+namespace com::sun::star::beans { class XPropertyState; }
+namespace com::sun::star::frame { class XModel; }
+namespace com::sun::star::util { class XNumberFormats; }
+namespace com::sun::star::util { class XNumberFormatsSupplier; }
+namespace com::sun::star::util { class XNumberFormatTypes; }
+namespace ooo::vba::excel { class XFont; }
+namespace ooo::vba::excel { class XInterior; }
+
+class ScCellRangesBase;
+class SfxItemSet;
+
+template< typename... Ifc >
+class ScVbaFormat : public InheritedHelperInterfaceWeakImpl< Ifc... >
+{
+typedef InheritedHelperInterfaceWeakImpl< Ifc... > ScVbaFormat_BASE;
+ css::lang::Locale m_aDefaultLocale;
+protected:
+ css::uno::Reference< css::beans::XPropertySet > mxPropertySet;
+ css::uno::Reference< css::util::XNumberFormatsSupplier > mxNumberFormatsSupplier;
+ css::uno::Reference< css::util::XNumberFormats > xNumberFormats;
+ css::uno::Reference< css::util::XNumberFormatTypes > xNumberFormatTypes;
+ css::uno::Reference< css::frame::XModel > mxModel;
+ css::uno::Reference< css::beans::XPropertyState > xPropertyState;
+ bool mbCheckAmbiguoity;
+ bool mbAddIndent;
+ /// @throws css::script::BasicErrorException
+ bool isAmbiguous(const OUString& _sPropertyName);
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference< css::beans::XPropertyState > const & getXPropertyState();
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ void initializeNumberFormats();
+ /// @throws css::uno::RuntimeException
+ SfxItemSet* getCurrentDataSet( );
+protected:
+ /// @throws css::uno::RuntimeException
+ virtual ScCellRangesBase* getCellRangesBase();
+public:
+ /// @throws css::script::BasicErrorException
+ ScVbaFormat( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::beans::XPropertySet >& _xPropertySet, const css::uno::Reference< css::frame::XModel >& xModel, bool bCheckAmbiguoity );
+ virtual css::uno::Reference< ov::XHelperInterface > thisHelperIface() = 0;
+ /// @throws css::uno::RuntimeException
+ void SAL_CALL setAddIndent( const css::uno::Any& BAddIndent) { BAddIndent >>= mbAddIndent; }
+ /// @throws css::uno::RuntimeException
+ css::uno::Any SAL_CALL getAddIndent() { return css::uno::Any( mbAddIndent ); }
+ // Interface Methods
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ virtual css::uno::Any SAL_CALL Borders( const css::uno::Any& Index );
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ virtual css::uno::Reference< ::ooo::vba::excel::XFont > SAL_CALL Font( );
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ virtual css::uno::Reference< ::ooo::vba::excel::XInterior > SAL_CALL Interior( );
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ virtual void SAL_CALL setNumberFormat( const css::uno::Any& NumberFormat );
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ virtual css::uno::Any SAL_CALL getNumberFormat( );
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ virtual void SAL_CALL setNumberFormatLocal( const css::uno::Any& NumberFormatLocal );
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ virtual css::uno::Any SAL_CALL getNumberFormatLocal( );
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ virtual void SAL_CALL setIndentLevel( const css::uno::Any& IndentLevel );
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ virtual css::uno::Any SAL_CALL getIndentLevel( );
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ virtual void SAL_CALL setHorizontalAlignment( const css::uno::Any& HorizontalAlignment );
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ virtual css::uno::Any SAL_CALL getHorizontalAlignment( );
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ virtual void SAL_CALL setVerticalAlignment( const css::uno::Any& VerticalAlignment );
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ virtual css::uno::Any SAL_CALL getVerticalAlignment( );
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ virtual void SAL_CALL setOrientation( const css::uno::Any& Orientation );
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ virtual css::uno::Any SAL_CALL getOrientation( );
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ virtual void SAL_CALL setShrinkToFit( const css::uno::Any& ShrinkToFit );
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ virtual css::uno::Any SAL_CALL getShrinkToFit( );
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ virtual void SAL_CALL setWrapText( const css::uno::Any& WrapText );
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ virtual css::uno::Any SAL_CALL getWrapText( );
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ virtual void SAL_CALL setLocked( const css::uno::Any& Locked );
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ virtual css::uno::Any SAL_CALL getLocked( );
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ virtual void SAL_CALL setFormulaHidden( const css::uno::Any& FormulaHidden );
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ virtual css::uno::Any SAL_CALL getFormulaHidden( );
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ virtual void SAL_CALL setMergeCells( const css::uno::Any& MergeCells ) = 0;
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ virtual css::uno::Any SAL_CALL getMergeCells( ) = 0;
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ virtual void SAL_CALL setReadingOrder( const css::uno::Any& ReadingOrder );
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ virtual css::uno::Any SAL_CALL getReadingOrder( );
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaformatcondition.cxx b/sc/source/ui/vba/vbaformatcondition.cxx
new file mode 100644
index 000000000..d9804399c
--- /dev/null
+++ b/sc/source/ui/vba/vbaformatcondition.cxx
@@ -0,0 +1,157 @@
+/* -*- 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 "vbaformatcondition.hxx"
+#include "vbaformatconditions.hxx"
+#include <unonames.hxx>
+#include <ooo/vba/excel/XlFormatConditionType.hpp>
+#include <basic/sberrors.hxx>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+/// @throws css::script::BasicErrorException
+static ScVbaFormatConditions*
+lcl_getScVbaFormatConditionsPtr( const uno::Reference< excel::XFormatConditions >& xFormatConditions )
+{
+ ScVbaFormatConditions* pFormatConditions = static_cast< ScVbaFormatConditions* >( xFormatConditions.get() );
+ if ( !pFormatConditions )
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {} );
+ return pFormatConditions;
+}
+
+ScVbaFormatCondition::ScVbaFormatCondition( const uno::Reference< XHelperInterface >& xParent,
+ const uno::Reference< uno::XComponentContext > & xContext,
+ const uno::Reference< sheet::XSheetConditionalEntry >& _xSheetConditionalEntry,
+ const uno::Reference< excel::XStyle >& _xStyle,
+ const uno::Reference< excel::XFormatConditions >& _xFormatConditions,
+ const uno::Reference< css::beans::XPropertySet >& _xPropertySet )
+ : ScVbaFormatCondition_BASE( xParent, xContext,
+ uno::Reference< sheet::XSheetCondition >( _xSheetConditionalEntry, css::uno::UNO_QUERY_THROW ) ),
+ moFormatConditions( _xFormatConditions ), mxStyle( _xStyle ), mxParentRangePropertySet( _xPropertySet )
+{
+ mxSheetConditionalEntries = lcl_getScVbaFormatConditionsPtr( moFormatConditions )->getSheetConditionalEntries();
+
+ msStyleName = mxStyle->getName();
+}
+
+void SAL_CALL
+ScVbaFormatCondition::Delete( )
+{
+ ScVbaFormatConditions* pFormatConditions = lcl_getScVbaFormatConditionsPtr( moFormatConditions );
+ pFormatConditions->removeFormatCondition(msStyleName, true);
+ notifyRange();
+}
+
+void SAL_CALL
+ScVbaFormatCondition::Modify( ::sal_Int32 _nType, const uno::Any& _aOperator, const uno::Any& _aFormula1, const uno::Any& _aFormula2 )
+{
+ try
+ {
+ ScVbaFormatConditions* pFormatConditions = lcl_getScVbaFormatConditionsPtr( moFormatConditions );
+ pFormatConditions->removeFormatCondition(msStyleName, false);
+ pFormatConditions->Add(_nType, _aOperator, _aFormula1, _aFormula2, mxStyle);
+ }
+ catch (const uno::Exception&)
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {} );
+ }
+}
+
+uno::Reference< excel::XInterior > SAL_CALL
+ScVbaFormatCondition::Interior( )
+{
+ return mxStyle->Interior();
+}
+
+uno::Reference< excel::XFont > SAL_CALL
+ScVbaFormatCondition::Font( )
+{
+ return mxStyle->Font();
+}
+uno::Any SAL_CALL
+ScVbaFormatCondition::Borders( const uno::Any& Index )
+{ return mxStyle->Borders( Index );
+}
+
+sheet::ConditionOperator
+ScVbaFormatCondition::retrieveAPIType(sal_Int32 _nVBAType, const uno::Reference< sheet::XSheetCondition >& _xSheetCondition )
+{
+ sheet::ConditionOperator aAPIType = sheet::ConditionOperator_NONE;
+ switch (_nVBAType)
+ {
+ case excel::XlFormatConditionType::xlExpression:
+ aAPIType = sheet::ConditionOperator_FORMULA;
+ break;
+ case excel::XlFormatConditionType::xlCellValue:
+ if ( _xSheetCondition.is() && (_xSheetCondition->getOperator() == sheet::ConditionOperator_FORMULA ) )
+ aAPIType = sheet::ConditionOperator_NONE;
+ break;
+ default:
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {} );
+ }
+ return aAPIType;
+}
+
+::sal_Int32 SAL_CALL
+ScVbaFormatCondition::Type( )
+{
+ sal_Int32 nReturnType = 0;
+ if ( mxSheetCondition->getOperator() == sheet::ConditionOperator_FORMULA)
+ nReturnType = excel::XlFormatConditionType::xlExpression;
+ else
+ nReturnType = excel::XlFormatConditionType::xlCellValue;
+ return nReturnType;
+}
+
+::sal_Int32 SAL_CALL
+ScVbaFormatCondition::Operator( )
+{
+ return ScVbaFormatCondition_BASE::Operator( true );
+}
+
+void
+ScVbaFormatCondition::notifyRange()
+{
+ try
+ {
+ mxParentRangePropertySet->setPropertyValue(SC_UNONAME_CONDFMT, uno::Any( mxSheetConditionalEntries));
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {} );
+ }
+}
+
+OUString
+ScVbaFormatCondition::getServiceImplName()
+{
+ return "ScVbaFormatCondition";
+}
+
+uno::Sequence< OUString >
+ScVbaFormatCondition::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.FormatCondition"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaformatcondition.hxx b/sc/source/ui/vba/vbaformatcondition.hxx
new file mode 100644
index 000000000..7d09a11b9
--- /dev/null
+++ b/sc/source/ui/vba/vbaformatcondition.hxx
@@ -0,0 +1,67 @@
+/* -*- 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 .
+ */
+#pragma once
+#include <ooo/vba/excel/XFormatCondition.hpp>
+#include <ooo/vba/excel/XFormatConditions.hpp>
+#include <ooo/vba/excel/XStyle.hpp>
+#include <com/sun/star/sheet/XSheetConditionalEntries.hpp>
+#include <com/sun/star/sheet/XSheetConditionalEntry.hpp>
+#include <com/sun/star/sheet/XSheetCondition.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include "vbacondition.hxx"
+
+typedef ScVbaCondition< ov::excel::XFormatCondition > ScVbaFormatCondition_BASE;
+class ScVbaFormatCondition final : public ScVbaFormatCondition_BASE
+{
+ OUString msStyleName;
+ css::uno::Reference< css::sheet::XSheetConditionalEntries > mxSheetConditionalEntries;
+ css::uno::Reference< ov::excel::XFormatConditions> moFormatConditions;
+ css::uno::Reference< ov::excel::XStyle > mxStyle;
+ css::uno::Reference< css::beans::XPropertySet > mxParentRangePropertySet;
+
+public:
+ /// @throws css::uno::RuntimeException
+ /// @throws css::script::BasicErrorException
+ ScVbaFormatCondition( const css::uno::Reference< ov::XHelperInterface >& xParent,
+ const css::uno::Reference< css::uno::XComponentContext > & xContext,
+ const css::uno::Reference< css::sheet::XSheetConditionalEntry >& _xSheetConditionalEntry,
+ const css::uno::Reference< ov::excel::XStyle >&,
+ const css::uno::Reference< ov::excel::XFormatConditions >& _xFormatConditions,
+ const css::uno::Reference< css::beans::XPropertySet >& _xPropertySet );
+
+ /// @throws css::script::BasicErrorException
+ void notifyRange();
+ /// @throws css::script::BasicErrorException
+ static css::sheet::ConditionOperator retrieveAPIType(sal_Int32 _nVBAType, const css::uno::Reference< css::sheet::XSheetCondition >& _xSheetCondition );
+
+ //Methods
+ virtual void SAL_CALL Delete( ) override;
+ virtual void SAL_CALL Modify( ::sal_Int32 Type, const css::uno::Any& Operator, const css::uno::Any& Formula1, const css::uno::Any& Formula2 ) override;
+ virtual ::sal_Int32 SAL_CALL Type( ) override;
+ using ScVbaFormatCondition_BASE::Operator;
+ virtual ::sal_Int32 SAL_CALL Operator( ) override;
+ virtual css::uno::Reference< ::ooo::vba::excel::XInterior > SAL_CALL Interior( ) override;
+ virtual css::uno::Any SAL_CALL Borders( const css::uno::Any& Index ) override;
+ virtual css::uno::Reference< ::ooo::vba::excel::XFont > SAL_CALL Font( ) override;
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaformatconditions.cxx b/sc/source/ui/vba/vbaformatconditions.cxx
new file mode 100644
index 000000000..bbf167b3c
--- /dev/null
+++ b/sc/source/ui/vba/vbaformatconditions.cxx
@@ -0,0 +1,289 @@
+/* -*- 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 <ooo/vba/excel/XRange.hpp>
+#include <com/sun/star/sheet/XSheetConditionalEntry.hpp>
+#include <basic/sberrors.hxx>
+#include <comphelper/sequence.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <vector>
+#include <unonames.hxx>
+#include "vbaformatconditions.hxx"
+#include "vbaformatcondition.hxx"
+#include "vbastyles.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+void SAL_CALL
+ScVbaFormatConditions::Delete( )
+{
+ try
+ {
+ ScVbaStyles* pStyles = static_cast< ScVbaStyles* >( mxStyles.get() );
+ if ( !pStyles )
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {} );
+ sal_Int32 nCount = mxSheetConditionalEntries->getCount();
+ for (sal_Int32 i = nCount - 1; i >= 0; i--)
+ {
+ uno::Reference< sheet::XSheetConditionalEntry > xSheetConditionalEntry( mxSheetConditionalEntries->getByIndex(i), uno::UNO_QUERY_THROW );
+ pStyles->Delete(xSheetConditionalEntry->getStyleName());
+ mxSheetConditionalEntries->removeByIndex(i);
+ }
+ notifyRange();
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+}
+
+uno::Type SAL_CALL
+ScVbaFormatConditions::getElementType()
+{
+ return cppu::UnoType<excel::XFormatCondition>::get();
+}
+
+static uno::Any xSheetConditionToFormatCondition( const uno::Reference< XHelperInterface >& xRangeParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< excel::XStyles >& xStyles, const uno::Reference< excel::XFormatConditions >& xFormatConditions, const uno::Reference< beans::XPropertySet >& xRangeProps, const uno::Any& aObject )
+{
+ uno::Reference< sheet::XSheetConditionalEntry > xSheetConditionalEntry;
+ aObject >>= xSheetConditionalEntry;
+
+ uno::Reference< excel::XStyle > xStyle( xStyles->Item( uno::Any( xSheetConditionalEntry->getStyleName() ), uno::Any() ), uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XFormatCondition > xCondition = new ScVbaFormatCondition( xRangeParent, xContext, xSheetConditionalEntry, xStyle, xFormatConditions, xRangeProps );
+ return uno::Any( xCondition );
+}
+
+uno::Any
+ScVbaFormatConditions::createCollectionObject(const uno::Any& aObject )
+{
+ return xSheetConditionToFormatCondition( uno::Reference< XHelperInterface >( mxRangeParent, uno::UNO_QUERY_THROW ), mxContext, mxStyles, this, mxParentRangePropertySet, aObject );
+}
+
+namespace {
+
+class EnumWrapper : public EnumerationHelper_BASE
+{
+ uno::Reference<container::XIndexAccess > m_xIndexAccess;
+ uno::Reference<excel::XRange > m_xParentRange;
+ uno::Reference<uno::XComponentContext > m_xContext;
+ uno::Reference<excel::XStyles > m_xStyles;
+ uno::Reference<excel::XFormatConditions > m_xParentCollection;
+ uno::Reference<beans::XPropertySet > m_xProps;
+
+ sal_Int32 nIndex;
+public:
+ EnumWrapper( const uno::Reference< container::XIndexAccess >& xIndexAccess, const uno::Reference<excel::XRange >& xRange, const uno::Reference<uno::XComponentContext >& xContext, const uno::Reference<excel::XStyles >& xStyles, const uno::Reference< excel::XFormatConditions >& xCollection, const uno::Reference<beans::XPropertySet >& xProps ) : m_xIndexAccess( xIndexAccess ), m_xParentRange( xRange ), m_xContext( xContext ), m_xStyles( xStyles ), m_xParentCollection( xCollection ), m_xProps( xProps ), nIndex( 0 ) {}
+ virtual sal_Bool SAL_CALL hasMoreElements( ) override
+ {
+ return ( nIndex < m_xIndexAccess->getCount() );
+ }
+
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ try
+ {
+ if ( nIndex < m_xIndexAccess->getCount() )
+ return xSheetConditionToFormatCondition( uno::Reference< XHelperInterface >( m_xParentRange, uno::UNO_QUERY_THROW ), m_xContext, m_xStyles, m_xParentCollection, m_xProps, m_xIndexAccess->getByIndex( nIndex++ ) );
+ }
+ catch (const container::NoSuchElementException&)
+ {
+ throw;
+ }
+ catch (const lang::WrappedTargetException&)
+ {
+ throw;
+ }
+ catch (const uno::RuntimeException&)
+ {
+ throw;
+ }
+ catch (const uno::Exception& e)
+ {
+ css::uno::Any a(cppu::getCaughtException());
+ throw css::lang::WrappedTargetException(
+ "wrapped Exception " + e.Message,
+ css::uno::Reference<css::uno::XInterface>(), a);
+ }
+ throw container::NoSuchElementException();
+ }
+};
+
+}
+
+uno::Reference< excel::XFormatCondition > SAL_CALL
+ScVbaFormatConditions::Add( ::sal_Int32 _nType, const uno::Any& _aOperator, const uno::Any& _aFormula1, const uno::Any& _aFormula2 )
+{
+ return Add( _nType, _aOperator, _aFormula1, _aFormula2, uno::Reference< excel::XStyle >() );
+}
+
+uno::Reference< excel::XFormatCondition >
+ScVbaFormatConditions::Add( ::sal_Int32 _nType, const uno::Any& _aOperator, const uno::Any& _aFormula1, const uno::Any& _aFormula2, const css::uno::Reference< excel::XStyle >& _xStyle )
+{
+ // #TODO
+ // #FIXME
+ // This method will NOT handle r1c1 formulas [*]and only assumes that
+ // the formulas are _xlA1 based ( need to hook into calc work this should
+ // address this )
+ // [*] reason: getA1Formula method below is just a hook and just
+ // returns what it gets ( e.g. doesn't convert anything )
+ uno::Reference< excel::XStyle > xStyle( _xStyle );
+ uno::Reference< excel::XFormatCondition > xFormatCondition;
+ try
+ {
+ OUString sStyleName;
+ if ( !xStyle.is() )
+ {
+ sStyleName = getStyleName();
+ xStyle = mxStyles->Add(sStyleName, uno::Any() );
+ }
+ else
+ {
+ sStyleName = xStyle->getName();
+ }
+
+ std::vector< beans::PropertyValue > aPropertyValueVector;
+ sheet::ConditionOperator aType = ScVbaFormatCondition::retrieveAPIType(_nType, uno::Reference< sheet::XSheetCondition >() );
+ uno::Any aValue;
+
+ if ( aType == sheet::ConditionOperator_FORMULA)
+ aValue <<= sheet::ConditionOperator_FORMULA;
+ else
+ aValue <<= ScVbaFormatCondition::retrieveAPIOperator(_aOperator);
+
+ beans::PropertyValue aProperty( "Operator", 0, aValue, beans::PropertyState_DIRECT_VALUE );
+ aPropertyValueVector.push_back( aProperty );
+
+ if ( _aFormula1.hasValue() )
+ {
+ beans::PropertyValue aProp( "Formula1", 0, uno::Any( getA1Formula( _aFormula1 ) ), beans::PropertyState_DIRECT_VALUE );
+ aPropertyValueVector.push_back( aProp );
+ }
+ if ( _aFormula2.hasValue() )
+ {
+ beans::PropertyValue aProp( "Formula2", 0, uno::Any( getA1Formula( _aFormula2 ) ), beans::PropertyState_DIRECT_VALUE );
+ aPropertyValueVector.push_back( aProp );
+ }
+ aProperty.Name = "StyleName";
+ aProperty.Value <<= sStyleName;
+
+ mxSheetConditionalEntries->addNew(comphelper::containerToSequence(aPropertyValueVector));
+ for (sal_Int32 i = mxSheetConditionalEntries->getCount()-1; i >= 0; i--)
+ {
+ uno::Reference< sheet::XSheetConditionalEntry > xSheetConditionalEntry( mxSheetConditionalEntries->getByIndex(i), uno::UNO_QUERY_THROW );
+ if (xSheetConditionalEntry->getStyleName() == sStyleName)
+ {
+ xFormatCondition = new ScVbaFormatCondition(uno::Reference< XHelperInterface >( mxRangeParent, uno::UNO_QUERY_THROW ), mxContext, xSheetConditionalEntry, xStyle, this, mxParentRangePropertySet);
+ notifyRange();
+ return xFormatCondition;
+ }
+ }
+ }
+ catch (uno::Exception& )
+ {
+ }
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {} );
+ return xFormatCondition;
+}
+
+uno::Reference< container::XEnumeration > SAL_CALL
+ScVbaFormatConditions::createEnumeration()
+{
+ return new EnumWrapper( m_xIndexAccess, mxRangeParent, mxContext, mxStyles, this, mxParentRangePropertySet );
+}
+
+void
+ScVbaFormatConditions::notifyRange()
+{
+ try
+ {
+ mxParentRangePropertySet->setPropertyValue(SC_UNONAME_CONDFMT, uno::Any( mxSheetConditionalEntries ));
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+}
+
+OUString
+ScVbaFormatConditions::getA1Formula(const css::uno::Any& _aFormula)
+{
+ // #TODO, #FIXME hook-in proper formula conversion detection & logic
+ OUString sFormula;
+ if ( !( _aFormula >>= sFormula ) )
+ DebugHelper::basicexception(ERRCODE_BASIC_BAD_PARAMETER, {} );
+ return sFormula;
+}
+
+OUString
+ScVbaFormatConditions::getStyleName()
+{
+ ScVbaStyles* pStyles = static_cast< ScVbaStyles* >( mxStyles.get() );
+ if ( !pStyles )
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {} );
+ uno::Sequence< OUString > sCellStyleNames = pStyles->getStyleNames();
+ return ContainerUtilities::getUniqueName(sCellStyleNames, "Excel_CondFormat", u"_");
+}
+
+void
+ScVbaFormatConditions::removeFormatCondition( const OUString& _sStyleName, bool _bRemoveStyle)
+{
+ try
+ {
+ sal_Int32 nElems = mxSheetConditionalEntries->getCount();
+ for (sal_Int32 i = 0; i < nElems; i++)
+ {
+ uno::Reference< sheet::XSheetConditionalEntry > xSheetConditionalEntry( mxSheetConditionalEntries->getByIndex(i), uno::UNO_QUERY_THROW );
+ if (_sStyleName == xSheetConditionalEntry->getStyleName())
+ {
+ mxSheetConditionalEntries->removeByIndex(i);
+ if (_bRemoveStyle)
+ {
+ ScVbaStyles* pStyles = static_cast< ScVbaStyles* >( mxStyles.get() );
+ if ( !pStyles )
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ pStyles->Delete( _sStyleName );
+ }
+ return;
+ }
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+}
+
+OUString
+ScVbaFormatConditions::getServiceImplName()
+{
+ return "ScVbaFormatConditions";
+}
+
+uno::Sequence< OUString >
+ScVbaFormatConditions::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.FormatConditions"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaformatconditions.hxx b/sc/source/ui/vba/vbaformatconditions.hxx
new file mode 100644
index 000000000..fd5a7fc83
--- /dev/null
+++ b/sc/source/ui/vba/vbaformatconditions.hxx
@@ -0,0 +1,66 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <ooo/vba/excel/XFormatConditions.hpp>
+#include <vbahelper/vbacollectionimpl.hxx>
+
+namespace com::sun::star::beans { class XPropertySet; }
+namespace com::sun::star::sheet { class XSheetConditionalEntries; }
+namespace ooo::vba::excel { class XRange; }
+namespace ooo::vba::excel { class XStyle; }
+namespace ooo::vba::excel { class XStyles; }
+
+// This class is used only as a target for casting, it seems,
+// and no objects of this type are created as such, I think.
+
+class ScVbaFormatConditions: public CollTestImplHelper< ov::excel::XFormatConditions >
+{
+ css::uno::Reference< css::sheet::XSheetConditionalEntries > mxSheetConditionalEntries;
+ css::uno::Reference< ov::excel::XStyles > mxStyles;
+ css::uno::Reference< ov::excel::XRange > mxRangeParent;
+ css::uno::Reference< css::beans::XPropertySet > mxParentRangePropertySet;
+public:
+ /// @throws css::script::BasicErrorException
+ void notifyRange();
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference< ov::excel::XFormatCondition > Add( ::sal_Int32 Type, const css::uno::Any& Operator, const css::uno::Any& Formula1, const css::uno::Any& Formula2, const css::uno::Reference< ov::excel::XStyle >& _xCalcStyle );
+ /// @throws css::script::BasicErrorException
+ static OUString getA1Formula(const css::uno::Any& _aFormula);
+ OUString getStyleName();
+ /// @throws css::script::BasicErrorException
+ void removeFormatCondition( const OUString& _sStyleName, bool _bRemoveStyle);
+ const css::uno::Reference< css::sheet::XSheetConditionalEntries >& getSheetConditionalEntries() const { return mxSheetConditionalEntries; }
+ // XFormatConditions
+ virtual void SAL_CALL Delete( ) override;
+ virtual css::uno::Reference< ov::excel::XFormatCondition > SAL_CALL Add( ::sal_Int32 Type, const css::uno::Any& Operator, const css::uno::Any& Formula1, const css::uno::Any& Formula2 ) override;
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+ virtual css::uno::Any createCollectionObject(const css::uno::Any&) override;
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+
+ ScVbaFormatConditions() = delete;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaglobals.cxx b/sc/source/ui/vba/vbaglobals.cxx
new file mode 100644
index 000000000..734553d50
--- /dev/null
+++ b/sc/source/ui/vba/vbaglobals.cxx
@@ -0,0 +1,265 @@
+/* -*- 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 "vbaglobals.hxx"
+
+#include <com/sun/star/lang/XMultiComponentFactory.hpp>
+#include <comphelper/sequence.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+
+#include "vbaapplication.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::ooo::vba;
+
+// ScVbaGlobals
+
+//ScVbaGlobals::ScVbaGlobals( css::uno::Reference< css::uno::XComponentContext >const& rxContext, ) : ScVbaGlobals_BASE( uno::Reference< XHelperInterface >(), rxContext )
+
+ScVbaGlobals::ScVbaGlobals( uno::Sequence< uno::Any > const& aArgs, uno::Reference< uno::XComponentContext >const& rxContext ) : ScVbaGlobals_BASE( uno::Reference< XHelperInterface >(), rxContext, "ExcelDocumentContext" )
+{
+ uno::Sequence< beans::PropertyValue > aInitArgs( aArgs.hasElements() ? 2 : 1 );
+ auto pInitArgs = aInitArgs.getArray();
+ pInitArgs[ 0 ].Name = "Application";
+ pInitArgs[ 0 ].Value <<= getApplication();
+ if ( aArgs.hasElements() )
+ {
+ pInitArgs[ 1 ].Name = "ExcelDocumentContext";
+ pInitArgs[ 1 ].Value <<= getXSomethingFromArgs< frame::XModel >( aArgs, 0 );
+ }
+ init( aInitArgs );
+}
+
+ScVbaGlobals::~ScVbaGlobals()
+{
+}
+
+// XGlobals
+
+uno::Reference<excel::XApplication > const &
+ScVbaGlobals::getApplication()
+{
+ if ( !mxApplication.is() )
+ mxApplication.set( new ScVbaApplication( mxContext) );
+ return mxApplication;
+}
+
+uno::Reference<excel::XApplication > SAL_CALL
+ScVbaGlobals::getExcel()
+{
+ return getApplication();
+}
+
+uno::Reference< excel::XWorkbook > SAL_CALL
+ScVbaGlobals::getActiveWorkbook()
+{
+ uno::Reference< excel::XWorkbook > xWorkbook( getApplication()->getActiveWorkbook(), uno::UNO_SET_THROW);
+ return xWorkbook;
+}
+
+uno::Reference< excel::XWindow > SAL_CALL
+ScVbaGlobals::getActiveWindow()
+{
+ return getApplication()->getActiveWindow();
+}
+
+uno::Reference< excel::XWorksheet > SAL_CALL
+ScVbaGlobals::getActiveSheet()
+{
+ return getApplication()->getActiveSheet();
+}
+
+uno::Any SAL_CALL
+ScVbaGlobals::WorkBooks( const uno::Any& aIndex )
+{
+ return getApplication()->Workbooks(aIndex);
+}
+
+uno::Any SAL_CALL
+ScVbaGlobals::WorkSheets(const uno::Any& aIndex)
+{
+ return getApplication()->Worksheets( aIndex );
+}
+uno::Any SAL_CALL
+ScVbaGlobals::Sheets( const uno::Any& aIndex )
+{
+ return WorkSheets( aIndex );
+}
+
+uno::Any SAL_CALL
+ScVbaGlobals::Range( const uno::Any& Cell1, const uno::Any& Cell2 )
+{
+ return getApplication()->Range( Cell1, Cell2 );
+}
+
+uno::Any SAL_CALL
+ScVbaGlobals::Names( const css::uno::Any& aIndex )
+{
+ return getApplication()->Names( aIndex );
+}
+
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaGlobals::getActiveCell()
+{
+ return getApplication()->getActiveCell();
+}
+
+uno::Reference< XAssistant > SAL_CALL
+ScVbaGlobals::getAssistant()
+{
+ return getApplication()->getAssistant();
+}
+
+uno::Any SAL_CALL
+ScVbaGlobals::getSelection()
+{
+ return getApplication()->getSelection();
+}
+
+uno::Reference< excel::XWorkbook > SAL_CALL
+ScVbaGlobals::getThisWorkbook()
+{
+ return getApplication()->getThisWorkbook();
+}
+void SAL_CALL
+ScVbaGlobals::Calculate()
+{
+ return getApplication()->Calculate();
+}
+
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaGlobals::Cells( const uno::Any& RowIndex, const uno::Any& ColumnIndex )
+{
+ return getApplication()->getActiveSheet()->Cells( RowIndex, ColumnIndex );
+}
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaGlobals::Columns( const uno::Any& aIndex )
+{
+ return getApplication()->getActiveSheet()->Columns( aIndex );
+}
+
+uno::Any SAL_CALL
+ScVbaGlobals::CommandBars( const uno::Any& aIndex )
+{
+ uno::Reference< XApplicationBase > xBase( getApplication(), uno::UNO_QUERY_THROW );
+ return xBase->CommandBars( aIndex );
+}
+
+css::uno::Reference< ov::excel::XRange > SAL_CALL
+ScVbaGlobals::Union( const css::uno::Reference< ov::excel::XRange >& Arg1, const css::uno::Reference< ov::excel::XRange >& Arg2, const css::uno::Any& Arg3, const css::uno::Any& Arg4, const css::uno::Any& Arg5, const css::uno::Any& Arg6, const css::uno::Any& Arg7, const css::uno::Any& Arg8, const css::uno::Any& Arg9, const css::uno::Any& Arg10, const css::uno::Any& Arg11, const css::uno::Any& Arg12, const css::uno::Any& Arg13, const css::uno::Any& Arg14, const css::uno::Any& Arg15, const css::uno::Any& Arg16, const css::uno::Any& Arg17, const css::uno::Any& Arg18, const css::uno::Any& Arg19, const css::uno::Any& Arg20, const css::uno::Any& Arg21, const css::uno::Any& Arg22, const css::uno::Any& Arg23, const css::uno::Any& Arg24, const css::uno::Any& Arg25, const css::uno::Any& Arg26, const css::uno::Any& Arg27, const css::uno::Any& Arg28, const css::uno::Any& Arg29, const css::uno::Any& Arg30 )
+{
+ return getApplication()->Union( Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10, Arg11, Arg12, Arg13, Arg14, Arg15, Arg16, Arg17, Arg18, Arg19, Arg20, Arg21, Arg22, Arg23, Arg24, Arg25, Arg26, Arg27, Arg28, Arg29, Arg30 );
+}
+css::uno::Reference< ov::excel::XRange > SAL_CALL
+ScVbaGlobals::Intersect( const css::uno::Reference< ov::excel::XRange >& Arg1, const css::uno::Reference< ov::excel::XRange >& Arg2, const css::uno::Any& Arg3, const css::uno::Any& Arg4, const css::uno::Any& Arg5, const css::uno::Any& Arg6, const css::uno::Any& Arg7, const css::uno::Any& Arg8, const css::uno::Any& Arg9, const css::uno::Any& Arg10, const css::uno::Any& Arg11, const css::uno::Any& Arg12, const css::uno::Any& Arg13, const css::uno::Any& Arg14, const css::uno::Any& Arg15, const css::uno::Any& Arg16, const css::uno::Any& Arg17, const css::uno::Any& Arg18, const css::uno::Any& Arg19, const css::uno::Any& Arg20, const css::uno::Any& Arg21, const css::uno::Any& Arg22, const css::uno::Any& Arg23, const css::uno::Any& Arg24, const css::uno::Any& Arg25, const css::uno::Any& Arg26, const css::uno::Any& Arg27, const css::uno::Any& Arg28, const css::uno::Any& Arg29, const css::uno::Any& Arg30 )
+{
+ return getApplication()->Intersect( Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10, Arg11, Arg12, Arg13, Arg14, Arg15, Arg16, Arg17, Arg18, Arg19, Arg20, Arg21, Arg22, Arg23, Arg24, Arg25, Arg26, Arg27, Arg28, Arg29, Arg30 );
+}
+
+uno::Any SAL_CALL
+ScVbaGlobals::Evaluate( const OUString& Name )
+{
+ return getApplication()->Evaluate( Name );
+}
+
+css::uno::Any SAL_CALL
+ScVbaGlobals::WorksheetFunction( )
+{
+ return getApplication()->WorksheetFunction();
+}
+
+uno::Any SAL_CALL
+ScVbaGlobals::Windows( const uno::Any& aIndex )
+{
+ return getApplication()->Windows( aIndex );
+}
+
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaGlobals::Rows( const uno::Any& aIndex )
+{
+ return getApplication()->getActiveSheet()->Rows( aIndex );
+
+}
+
+uno::Any SAL_CALL
+ScVbaGlobals::getDebug()
+{
+ try // return empty object on error
+ {
+ uno::Reference< lang::XMultiComponentFactory > xServiceManager( mxContext->getServiceManager(), uno::UNO_SET_THROW );
+ uno::Reference< uno::XInterface > xVBADebug = xServiceManager->createInstanceWithContext(
+ "ooo.vba.Debug", mxContext );
+ return uno::Any( xVBADebug );
+ }
+ catch( uno::Exception& )
+ {
+ }
+ return uno::Any();
+}
+
+uno::Any SAL_CALL
+ScVbaGlobals::MenuBars( const uno::Any& aIndex )
+{
+ return getApplication()->MenuBars(aIndex);
+}
+
+uno::Sequence< OUString > SAL_CALL
+ScVbaGlobals::getAvailableServiceNames( )
+{
+ static const uno::Sequence< OUString > serviceNames = comphelper::concatSequences(
+ ScVbaGlobals_BASE::getAvailableServiceNames(),
+ uno::Sequence< OUString >
+ {
+ "ooo.vba.excel.Range",
+ "ooo.vba.excel.Workbook",
+ "ooo.vba.excel.Window",
+ "ooo.vba.excel.Worksheet",
+ "ooo.vba.excel.Application",
+ "ooo.vba.excel.Hyperlink",
+ "com.sun.star.script.vba.VBASpreadsheetEventProcessor"
+ } );
+ return serviceNames;
+}
+
+OUString
+ScVbaGlobals::getServiceImplName()
+{
+ return "ScVbaGlobals";
+}
+
+uno::Sequence< OUString >
+ScVbaGlobals::getServiceNames()
+{
+ static uno::Sequence< OUString > aServiceNames
+ {
+ "ooo.vba.excel.Globals"
+ };
+ return aServiceNames;
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
+ScVbaGlobals_get_implementation(
+ css::uno::XComponentContext *context,
+ css::uno::Sequence<css::uno::Any> const &arguments)
+{
+ return cppu::acquire(new ScVbaGlobals(arguments, context));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaglobals.hxx b/sc/source/ui/vba/vbaglobals.hxx
new file mode 100644
index 000000000..6f978c591
--- /dev/null
+++ b/sc/source/ui/vba/vbaglobals.hxx
@@ -0,0 +1,82 @@
+/* -*- 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 .
+ */
+#ifndef SC_VBA_GLOBALS
+#define SC_VBA_GLOBALS
+
+#include <ooo/vba/excel/XGlobals.hpp>
+
+#include <cppuhelper/implbase.hxx>
+
+#include <vbahelper/vbaglobalbase.hxx>
+
+namespace com::sun::star::uno { class XComponentContext; }
+namespace ooo::vba::excel { class XApplication; }
+
+
+typedef ::cppu::ImplInheritanceHelper< VbaGlobalsBase, ov::excel::XGlobals > ScVbaGlobals_BASE;
+
+class ScVbaGlobals : public ScVbaGlobals_BASE
+{
+ css::uno::Reference< ov::excel::XApplication > mxApplication;
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference< ov::excel::XApplication > const & getApplication();
+public:
+
+ ScVbaGlobals( css::uno::Sequence< css::uno::Any > const& aArgs,
+ css::uno::Reference< css::uno::XComponentContext >const& rxContext );
+ virtual ~ScVbaGlobals() override;
+
+ // XGlobals
+ virtual css::uno::Reference< ov::excel::XWorkbook > SAL_CALL getActiveWorkbook() override;
+ virtual css::uno::Reference< ov::excel::XWindow > SAL_CALL getActiveWindow() override;
+ virtual css::uno::Reference< ov::excel::XWorksheet > SAL_CALL getActiveSheet() override;
+ virtual css::uno::Reference< ov::XAssistant > SAL_CALL getAssistant() override;
+ virtual void SAL_CALL Calculate( ) override;
+
+ virtual css::uno::Any SAL_CALL getSelection() override;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL getActiveCell() override;
+ virtual css::uno::Reference< ov::excel::XWorkbook > SAL_CALL getThisWorkbook() override;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Cells( const css::uno::Any& RowIndex, const css::uno::Any& ColumnIndex ) override;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Columns( const css::uno::Any& aIndex ) override;
+ virtual css::uno::Any SAL_CALL CommandBars( const css::uno::Any& aIndex ) override;
+ virtual css::uno::Any SAL_CALL Evaluate( const OUString& Name ) override;
+
+ virtual css::uno::Any SAL_CALL WorkSheets(const css::uno::Any& aIndex ) override;
+ virtual css::uno::Any SAL_CALL WorkBooks(const css::uno::Any& aIndex ) override;
+ virtual css::uno::Any SAL_CALL WorksheetFunction( ) override;
+ virtual css::uno::Any SAL_CALL Windows( const css::uno::Any& aIndex ) override;
+ virtual css::uno::Any SAL_CALL Sheets( const css::uno::Any& aIndex ) override;
+ virtual css::uno::Any SAL_CALL Range( const css::uno::Any& Cell1, const css::uno::Any& Cell2 ) override;
+ virtual css::uno::Reference< ::ooo::vba::excel::XRange > SAL_CALL Rows( const css::uno::Any& aIndex ) override;
+ virtual css::uno::Any SAL_CALL Names( const css::uno::Any& aIndex ) override;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Intersect( const css::uno::Reference< ov::excel::XRange >& Arg1, const css::uno::Reference< ov::excel::XRange >& Arg2, const css::uno::Any& Arg3, const css::uno::Any& Arg4, const css::uno::Any& Arg5, const css::uno::Any& Arg6, const css::uno::Any& Arg7, const css::uno::Any& Arg8, const css::uno::Any& Arg9, const css::uno::Any& Arg10, const css::uno::Any& Arg11, const css::uno::Any& Arg12, const css::uno::Any& Arg13, const css::uno::Any& Arg14, const css::uno::Any& Arg15, const css::uno::Any& Arg16, const css::uno::Any& Arg17, const css::uno::Any& Arg18, const css::uno::Any& Arg19, const css::uno::Any& Arg20, const css::uno::Any& Arg21, const css::uno::Any& Arg22, const css::uno::Any& Arg23, const css::uno::Any& Arg24, const css::uno::Any& Arg25, const css::uno::Any& Arg26, const css::uno::Any& Arg27, const css::uno::Any& Arg28, const css::uno::Any& Arg29, const css::uno::Any& Arg30 ) override;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Union( const css::uno::Reference< ov::excel::XRange >& Arg1, const css::uno::Reference< ov::excel::XRange >& Arg2, const css::uno::Any& Arg3, const css::uno::Any& Arg4, const css::uno::Any& Arg5, const css::uno::Any& Arg6, const css::uno::Any& Arg7, const css::uno::Any& Arg8, const css::uno::Any& Arg9, const css::uno::Any& Arg10, const css::uno::Any& Arg11, const css::uno::Any& Arg12, const css::uno::Any& Arg13, const css::uno::Any& Arg14, const css::uno::Any& Arg15, const css::uno::Any& Arg16, const css::uno::Any& Arg17, const css::uno::Any& Arg18, const css::uno::Any& Arg19, const css::uno::Any& Arg20, const css::uno::Any& Arg21, const css::uno::Any& Arg22, const css::uno::Any& Arg23, const css::uno::Any& Arg24, const css::uno::Any& Arg25, const css::uno::Any& Arg26, const css::uno::Any& Arg27, const css::uno::Any& Arg28, const css::uno::Any& Arg29, const css::uno::Any& Arg30 ) override;
+ virtual css::uno::Reference< ov::excel::XApplication > SAL_CALL getExcel() override;
+ virtual css::uno::Any SAL_CALL getDebug() override;
+ virtual css::uno::Any SAL_CALL MenuBars( const css::uno::Any& aIndex ) override;
+
+ // XMultiServiceFactory
+ virtual css::uno::Sequence< OUString > SAL_CALL getAvailableServiceNames( ) override;
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+#endif
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbahyperlink.cxx b/sc/source/ui/vba/vbahyperlink.cxx
new file mode 100644
index 000000000..2bd355421
--- /dev/null
+++ b/sc/source/ui/vba/vbahyperlink.cxx
@@ -0,0 +1,236 @@
+/* -*- 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 "vbahyperlink.hxx"
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/text/XTextFieldsSupplier.hpp>
+#include <ooo/vba/office/MsoHyperlinkType.hpp>
+#include <ooo/vba/msforms/XShape.hpp>
+#include "vbarange.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+ScVbaHyperlink::ScVbaHyperlink( const uno::Sequence< uno::Any >& rArgs,
+ const uno::Reference< uno::XComponentContext >& rxContext ) :
+ HyperlinkImpl_BASE( getXSomethingFromArgs< XHelperInterface >( rArgs, 0 ), rxContext ),
+ mxCell( getXSomethingFromArgs< table::XCell >( rArgs, 1, false ) ),
+ mnType( office::MsoHyperlinkType::msoHyperlinkRange )
+{
+ uno::Reference< text::XTextFieldsSupplier > xTextFields( mxCell, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xIndex( xTextFields->getTextFields(), uno::UNO_QUERY_THROW );
+ mxTextField.set( xIndex->getByIndex(0), uno::UNO_QUERY_THROW );
+}
+
+ScVbaHyperlink::ScVbaHyperlink( const uno::Reference< XHelperInterface >& rxAnchor,
+ const uno::Reference< uno::XComponentContext >& rxContext,
+ const uno::Any& rAddress, const uno::Any& rSubAddress,
+ const uno::Any& rScreenTip, const uno::Any& rTextToDisplay ) :
+ HyperlinkImpl_BASE( rxAnchor, rxContext ) // parent of Hyperlink is the anchor object
+{
+ // extract parameters, Address must not be empty
+ UrlComponents aUrlComp;
+ OUString aTextToDisplay;
+ if( !(rAddress >>= aUrlComp.first) || aUrlComp.first.isEmpty() )
+ throw uno::RuntimeException("Cannot get address" );
+ rSubAddress >>= aUrlComp.second;
+ rScreenTip >>= maScreenTip;
+ rTextToDisplay >>= aTextToDisplay;
+
+ // get anchor range or anchor shape
+ uno::Reference< excel::XRange > xAnchorRange( rxAnchor, uno::UNO_QUERY );
+ if( xAnchorRange.is() )
+ {
+ mnType = office::MsoHyperlinkType::msoHyperlinkRange;
+ // only single ranges are allowed
+ uno::Reference< table::XCellRange > xUnoRange( ScVbaRange::getCellRange( xAnchorRange ), uno::UNO_QUERY_THROW );
+ // insert the hyperlink into the top-left cell only
+ mxCell.set( xUnoRange->getCellByPosition( 0, 0 ), uno::UNO_SET_THROW );
+ uno::Reference< text::XText > xText( mxCell, uno::UNO_QUERY_THROW );
+ // use cell text or URL if no TextToDisplay has been passed
+ if( aTextToDisplay.isEmpty() )
+ {
+ aTextToDisplay = xText->getString();
+ if( aTextToDisplay.isEmpty() )
+ {
+ OUStringBuffer aBuffer( aUrlComp.first );
+ if( !aUrlComp.second.isEmpty() )
+ aBuffer.append( " - " + aUrlComp.second );
+ aTextToDisplay = aBuffer.makeStringAndClear();
+ }
+ }
+ // create and initialize a new URL text field
+ uno::Reference< lang::XMultiServiceFactory > xFactory( ScVbaRange::getUnoModel( xAnchorRange ), uno::UNO_QUERY_THROW );
+ uno::Reference< text::XTextContent > xUrlField( xFactory->createInstance("com.sun.star.text.TextField.URL"), uno::UNO_QUERY_THROW );
+ mxTextField.set( xUrlField, uno::UNO_QUERY_THROW );
+ setUrlComponents( aUrlComp );
+ setTextToDisplay( aTextToDisplay );
+ // insert the text field into the document
+ xText->setString( OUString() );
+ uno::Reference< text::XTextRange > xRange( xText->createTextCursor(), uno::UNO_QUERY_THROW );
+ xText->insertTextContent( xRange, xUrlField, false );
+ }
+ else
+ {
+ uno::Reference< msforms::XShape > xAnchorShape( rxAnchor, uno::UNO_QUERY_THROW );
+ mnType = office::MsoHyperlinkType::msoHyperlinkShape;
+ // FIXME: insert hyperlink into shape
+ throw uno::RuntimeException();
+ }
+}
+
+ScVbaHyperlink::~ScVbaHyperlink()
+{
+}
+
+OUString ScVbaHyperlink::getName()
+{
+ // it seems this attribute is same as TextToDisplay
+ return getTextToDisplay();
+}
+
+void ScVbaHyperlink::setName( const OUString& rName )
+{
+ setTextToDisplay( rName );
+}
+
+OUString ScVbaHyperlink::getAddress()
+{
+ return getUrlComponents().first;
+}
+
+void ScVbaHyperlink::setAddress( const OUString& rAddress )
+{
+ UrlComponents aUrlComp = getUrlComponents();
+ aUrlComp.first = rAddress;
+ setUrlComponents( aUrlComp );
+}
+
+OUString ScVbaHyperlink::getSubAddress()
+{
+ return getUrlComponents().second;
+}
+
+void ScVbaHyperlink::setSubAddress( const OUString& rSubAddress )
+{
+ UrlComponents aUrlComp = getUrlComponents();
+ aUrlComp.second = rSubAddress;
+ setUrlComponents( aUrlComp );
+}
+
+OUString SAL_CALL ScVbaHyperlink::getScreenTip()
+{
+ return maScreenTip;
+}
+
+void SAL_CALL ScVbaHyperlink::setScreenTip( const OUString& rScreenTip )
+{
+ maScreenTip = rScreenTip;
+}
+
+OUString ScVbaHyperlink::getTextToDisplay()
+{
+ ensureTextField();
+ OUString aTextToDisplay;
+ mxTextField->getPropertyValue("Representation") >>= aTextToDisplay;
+ return aTextToDisplay;
+}
+
+void ScVbaHyperlink::setTextToDisplay( const OUString& rTextToDisplay )
+{
+ ensureTextField();
+ mxTextField->setPropertyValue("Representation", uno::Any( rTextToDisplay ) );
+}
+
+sal_Int32 SAL_CALL ScVbaHyperlink::getType()
+{
+ return mnType;
+}
+
+uno::Reference< excel::XRange > SAL_CALL ScVbaHyperlink::getRange()
+{
+ if( mnType == office::MsoHyperlinkType::msoHyperlinkRange )
+ {
+ // if constructed from Hyperlinks object, range has been passed as parent
+ uno::Reference< excel::XRange > xAnchorRange( getParent(), uno::UNO_QUERY );
+ if( !xAnchorRange.is() )
+ {
+ // if constructed via service c'tor, create new range based on cell
+ uno::Reference< table::XCellRange > xRange( mxCell, uno::UNO_QUERY_THROW );
+ // FIXME: need to pass current worksheet as the parent of XRange.
+ xAnchorRange.set( new ScVbaRange( uno::Reference< XHelperInterface >(), mxContext, xRange ) );
+ }
+ return xAnchorRange;
+ }
+ // error if called at a shape Hyperlink object
+ throw uno::RuntimeException();
+}
+
+uno::Reference< msforms::XShape > SAL_CALL ScVbaHyperlink::getShape()
+{
+ // error if called at a range Hyperlink object
+ return uno::Reference< msforms::XShape >( getParent(), uno::UNO_QUERY_THROW );
+}
+
+VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaHyperlink, "ooo.vba.excel.Hyperlink" )
+
+// private --------------------------------------------------------------------
+
+void ScVbaHyperlink::ensureTextField()
+{
+ if( !mxTextField.is() )
+ throw uno::RuntimeException();
+}
+
+ScVbaHyperlink::UrlComponents ScVbaHyperlink::getUrlComponents()
+{
+ ensureTextField();
+ OUString aUrl;
+ mxTextField->getPropertyValue("URL") >>= aUrl;
+ sal_Int32 nHashPos = aUrl.indexOf( '#' );
+ if( nHashPos < 0 )
+ return UrlComponents( aUrl, OUString() );
+ return UrlComponents( aUrl.copy( 0, nHashPos ), aUrl.copy( nHashPos + 1 ) );
+}
+
+void ScVbaHyperlink::setUrlComponents( const UrlComponents& rUrlComp )
+{
+ ensureTextField();
+ OUStringBuffer aUrl( rUrlComp.first );
+ if( !rUrlComp.second.isEmpty() )
+ aUrl.append( '#' ).append( rUrlComp.second );
+ mxTextField->setPropertyValue("URL", uno::Any( aUrl.makeStringAndClear() ) );
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+Calc_ScVbaHyperlink_get_implementation(
+ css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& args)
+{
+ return cppu::acquire(new ScVbaHyperlink(args, context));
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbahyperlink.hxx b/sc/source/ui/vba/vbahyperlink.hxx
new file mode 100644
index 000000000..391853be7
--- /dev/null
+++ b/sc/source/ui/vba/vbahyperlink.hxx
@@ -0,0 +1,86 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <ooo/vba/excel/XHyperlink.hpp>
+
+#include <vbahelper/vbahelperinterface.hxx>
+#include <tools/long.hxx>
+
+namespace ooo::vba::excel { class XRange; }
+namespace com::sun::star::beans { class XPropertySet; }
+namespace com::sun::star::table { class XCell; }
+
+typedef InheritedHelperInterfaceWeakImpl< ov::excel::XHyperlink > HyperlinkImpl_BASE;
+
+class ScVbaHyperlink : public HyperlinkImpl_BASE
+{
+public:
+ /// @throws css::lang::IllegalArgumentException
+ /// @throws css::uno::RuntimeException
+ ScVbaHyperlink(
+ const css::uno::Sequence< css::uno::Any >& rArgs,
+ const css::uno::Reference< css::uno::XComponentContext >& rxContext );
+
+ /// @throws css::uno::RuntimeException
+ ScVbaHyperlink(
+ const css::uno::Reference< ov::XHelperInterface >& rxAnchor,
+ const css::uno::Reference< css::uno::XComponentContext >& rxContext,
+ const css::uno::Any& rAddress, const css::uno::Any& rSubAddress,
+ const css::uno::Any& rScreenTip, const css::uno::Any& rTextToDisplay );
+
+ virtual ~ScVbaHyperlink() override;
+
+ // Attributes
+ virtual OUString SAL_CALL getName() override;
+ virtual void SAL_CALL setName( const OUString& rName ) override;
+ virtual OUString SAL_CALL getAddress() override;
+ virtual void SAL_CALL setAddress( const OUString& rAddress ) override;
+ virtual OUString SAL_CALL getSubAddress() override;
+ virtual void SAL_CALL setSubAddress( const OUString& rSubAddress ) override;
+ virtual OUString SAL_CALL getScreenTip() override;
+ virtual void SAL_CALL setScreenTip( const OUString& rScreenTip ) override;
+ virtual OUString SAL_CALL getTextToDisplay() override;
+ virtual void SAL_CALL setTextToDisplay( const OUString& rTextToDisplay ) override;
+ virtual sal_Int32 SAL_CALL getType() override;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL getRange() override;
+ virtual css::uno::Reference< ov::msforms::XShape > SAL_CALL getShape() override;
+
+ // XHelperInterface
+ VBAHELPER_DECL_XHELPERINTERFACE
+
+private:
+ typedef ::std::pair< OUString, OUString > UrlComponents;
+
+ /// @throws css::uno::RuntimeException
+ void ensureTextField();
+ /// @throws css::uno::RuntimeException
+ UrlComponents getUrlComponents();
+ /// @throws css::uno::RuntimeException
+ void setUrlComponents( const UrlComponents& rUrlComp );
+
+private:
+ css::uno::Reference< css::table::XCell > mxCell;
+ css::uno::Reference< css::beans::XPropertySet > mxTextField;
+ OUString maScreenTip;
+ tools::Long mnType;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbahyperlinks.cxx b/sc/source/ui/vba/vbahyperlinks.cxx
new file mode 100644
index 000000000..d309f5f44
--- /dev/null
+++ b/sc/source/ui/vba/vbahyperlinks.cxx
@@ -0,0 +1,277 @@
+/* -*- 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 "vbahyperlinks.hxx"
+#include <algorithm>
+#include <vector>
+#include <cppuhelper/implbase.hxx>
+#include <ooo/vba/office/MsoHyperlinkType.hpp>
+#include <rangelst.hxx>
+#include "vbahyperlink.hxx"
+#include "vbarange.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+namespace {
+
+/** Returns true, if every range of rxInner is contained in any range of rScOuter.
+
+ @throws css::uno::RuntimeException
+*/
+bool lclContains( const ScRangeList& rScOuter, const uno::Reference< excel::XRange >& rxInner )
+{
+ const ScRangeList& rScInner = ScVbaRange::getScRangeList( rxInner );
+ if( rScInner.empty() || rScOuter.empty() )
+ throw uno::RuntimeException("Empty range objects" );
+
+ for( size_t nIndex = 0, nCount = rScInner.size(); nIndex < nCount; ++nIndex )
+ if( !rScOuter.Contains( rScInner[ nIndex ] ) )
+ return false;
+ return true;
+}
+
+/** Functor to decide whether the anchors of two Hyperlink objects are equal. */
+struct EqualAnchorFunctor
+{
+ uno::Reference< excel::XRange > mxAnchorRange;
+ uno::Reference< msforms::XShape > mxAnchorShape;
+ sal_Int32 mnType;
+ /// @throws uno::RuntimeException
+ explicit EqualAnchorFunctor( const uno::Reference< excel::XHyperlink >& rxHlink );
+ /// @throws uno::RuntimeException
+ bool operator()( const uno::Reference< excel::XHyperlink >& rxHlink ) const;
+};
+
+EqualAnchorFunctor::EqualAnchorFunctor( const uno::Reference< excel::XHyperlink >& rxHlink ) :
+ mnType( rxHlink->getType() )
+{
+ switch( mnType )
+ {
+ case office::MsoHyperlinkType::msoHyperlinkRange:
+ mxAnchorRange.set( rxHlink->getRange(), uno::UNO_SET_THROW );
+ break;
+ case office::MsoHyperlinkType::msoHyperlinkShape:
+ case office::MsoHyperlinkType::msoHyperlinkInlineShape:
+ mxAnchorShape.set( rxHlink->getShape(), uno::UNO_SET_THROW );
+ break;
+ default:
+ throw uno::RuntimeException();
+ }
+}
+
+bool EqualAnchorFunctor::operator()( const uno::Reference< excel::XHyperlink >& rxHlink ) const
+{
+ sal_Int32 nType = rxHlink->getType();
+ if( nType != mnType )
+ return false;
+
+ switch( nType )
+ {
+ case office::MsoHyperlinkType::msoHyperlinkRange:
+ {
+ uno::Reference< excel::XRange > xAnchorRange( rxHlink->getRange(), uno::UNO_SET_THROW );
+ const ScRangeList& rScRanges1 = ScVbaRange::getScRangeList( xAnchorRange );
+ const ScRangeList& rScRanges2 = ScVbaRange::getScRangeList( mxAnchorRange );
+ return (rScRanges1.size() == 1) && (rScRanges2.size() == 1) && (rScRanges1[ 0 ] == rScRanges2[ 0 ]);
+ }
+ case office::MsoHyperlinkType::msoHyperlinkShape:
+ case office::MsoHyperlinkType::msoHyperlinkInlineShape:
+ {
+ uno::Reference< msforms::XShape > xAnchorShape( rxHlink->getShape(), uno::UNO_SET_THROW );
+ return xAnchorShape.get() == mxAnchorShape.get();
+ }
+ default:
+ throw uno::RuntimeException();
+ }
+}
+
+} // namespace
+
+namespace detail {
+
+class ScVbaHlinkContainer : public ::cppu::WeakImplHelper< container::XIndexAccess >
+{
+public:
+ /// @throws uno::RuntimeException
+ explicit ScVbaHlinkContainer();
+ /// @throws uno::RuntimeException
+ explicit ScVbaHlinkContainer( const ScVbaHlinkContainerRef& rxSheetContainer, const ScRangeList& rScRanges );
+
+ /** Inserts the passed hyperlink into the collection. Will remove a
+ Hyperlink object with the same anchor as the passed Hyperlink object.
+
+ @throws uno::RuntimeException
+ */
+ void insertHyperlink( const uno::Reference< excel::XHyperlink >& rxHlink );
+
+ // XIndexAccess
+ virtual sal_Int32 SAL_CALL getCount() override;
+ virtual uno::Any SAL_CALL getByIndex( sal_Int32 nIndex ) override;
+
+ // XElementAccess
+ virtual uno::Type SAL_CALL getElementType() override;
+ virtual sal_Bool SAL_CALL hasElements() override;
+
+private:
+ typedef ::std::vector< uno::Reference< excel::XHyperlink > > HyperlinkVector;
+ HyperlinkVector maHlinks;
+};
+
+ScVbaHlinkContainer::ScVbaHlinkContainer()
+{
+ // TODO FIXME: fill with existing hyperlinks
+}
+
+ScVbaHlinkContainer::ScVbaHlinkContainer( const ScVbaHlinkContainerRef& rxSheetContainer,
+ const ScRangeList& rScRanges )
+{
+ for( sal_Int32 nIndex = 0, nCount = rxSheetContainer->getCount(); nIndex < nCount; ++nIndex )
+ {
+ uno::Reference< excel::XHyperlink > xHlink( rxSheetContainer->getByIndex( nIndex ), uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XRange > xHlinkRange( xHlink->getRange(), uno::UNO_SET_THROW );
+ if( lclContains( rScRanges, xHlinkRange ) )
+ maHlinks.push_back( xHlink );
+ }
+}
+
+void ScVbaHlinkContainer::insertHyperlink( const uno::Reference< excel::XHyperlink >& rxHlink )
+{
+ HyperlinkVector::iterator aIt = ::std::find_if( maHlinks.begin(), maHlinks.end(), EqualAnchorFunctor( rxHlink ) );
+ if( aIt == maHlinks.end() )
+ maHlinks.push_back( rxHlink );
+ else
+ *aIt = rxHlink;
+}
+
+sal_Int32 SAL_CALL ScVbaHlinkContainer::getCount()
+{
+ return static_cast< sal_Int32 >( maHlinks.size() );
+}
+
+uno::Any SAL_CALL ScVbaHlinkContainer::getByIndex( sal_Int32 nIndex )
+{
+ if( (0 <= nIndex) && (nIndex < getCount()) )
+ return uno::Any( maHlinks[ static_cast< size_t >( nIndex ) ] );
+ throw lang::IndexOutOfBoundsException();
+}
+
+uno::Type SAL_CALL ScVbaHlinkContainer::getElementType()
+{
+ return cppu::UnoType<excel::XHyperlink>::get();
+}
+
+sal_Bool SAL_CALL ScVbaHlinkContainer::hasElements()
+{
+ return !maHlinks.empty();
+}
+
+ScVbaHlinkContainerMember::ScVbaHlinkContainerMember( ScVbaHlinkContainer* pContainer ) :
+ mxContainer( pContainer )
+{
+}
+
+ScVbaHlinkContainerMember::~ScVbaHlinkContainerMember()
+{
+}
+
+} // namespace detail
+
+ScVbaHyperlinks::ScVbaHyperlinks( const uno::Reference< XHelperInterface >& rxParent,
+ const uno::Reference< uno::XComponentContext >& rxContext ) :
+ detail::ScVbaHlinkContainerMember( new detail::ScVbaHlinkContainer ),
+ ScVbaHyperlinks_BASE( rxParent, rxContext, uno::Reference< container::XIndexAccess >( mxContainer ) )
+{
+}
+
+ScVbaHyperlinks::ScVbaHyperlinks( const uno::Reference< XHelperInterface >& rxParent,
+ const uno::Reference< uno::XComponentContext >& rxContext,
+ const ScVbaHyperlinksRef& rxSheetHlinks, const ScRangeList& rScRanges ) :
+ detail::ScVbaHlinkContainerMember( new detail::ScVbaHlinkContainer( rxSheetHlinks->mxContainer, rScRanges ) ),
+ ScVbaHyperlinks_BASE( rxParent, rxContext, uno::Reference< container::XIndexAccess >( mxContainer ) ),
+ mxSheetHlinks( rxSheetHlinks )
+{
+}
+
+ScVbaHyperlinks::~ScVbaHyperlinks()
+{
+}
+
+// XHyperlinks ----------------------------------------------------------------
+
+uno::Reference< excel::XHyperlink > SAL_CALL ScVbaHyperlinks::Add(
+ const uno::Any& rAnchor, const uno::Any& rAddress, const uno::Any& rSubAddress,
+ const uno::Any& rScreenTip, const uno::Any& rTextToDisplay )
+{
+ /* If this Hyperlinks object has been created from a Range object, the
+ call to Add() is passed to the Hyperlinks object of the parent
+ worksheet. This container will not be modified (it will not contain the
+ inserted hyperlink).
+ For details, see documentation in hyperlinks.hxx.
+ */
+ if( mxSheetHlinks.is() )
+ return mxSheetHlinks->Add( rAnchor, rAddress, rSubAddress, rScreenTip, rTextToDisplay );
+
+ // get anchor object (can be a Range or a Shape object)
+ uno::Reference< XHelperInterface > xAnchor( rAnchor, uno::UNO_QUERY_THROW );
+
+ /* Create the Hyperlink object, this tries to insert the hyperlink into
+ the spreadsheet document. Parent of the Hyperlink is the anchor object. */
+ uno::Reference< excel::XHyperlink > xHlink( new ScVbaHyperlink(
+ xAnchor, mxContext, rAddress, rSubAddress, rScreenTip, rTextToDisplay ) );
+
+ /* If creation of the hyperlink did not throw, insert it into the
+ collection. */
+ mxContainer->insertHyperlink( xHlink );
+ return xHlink;
+}
+
+void SAL_CALL ScVbaHyperlinks::Delete()
+{
+ // FIXME not implemented
+ throw uno::RuntimeException();
+}
+
+// XEnumerationAccess ---------------------------------------------------------
+
+uno::Reference< container::XEnumeration > SAL_CALL ScVbaHyperlinks::createEnumeration()
+{
+ return new SimpleIndexAccessToEnumeration( m_xIndexAccess );
+}
+
+// XElementAccess -------------------------------------------------------------
+
+uno::Type SAL_CALL ScVbaHyperlinks::getElementType()
+{
+ return cppu::UnoType<excel::XHyperlink>::get();
+}
+
+// ScVbaCollectionBase --------------------------------------------------------
+
+uno::Any ScVbaHyperlinks::createCollectionObject( const uno::Any& rSource )
+{
+ // container stores XHyperlink objects, just return the passed object
+ return rSource;
+}
+
+// XHelperInterface -----------------------------------------------------------
+
+VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaHyperlinks, "ooo.vba.excel.Hyperlinks" )
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbahyperlinks.hxx b/sc/source/ui/vba/vbahyperlinks.hxx
new file mode 100644
index 000000000..7538fe50b
--- /dev/null
+++ b/sc/source/ui/vba/vbahyperlinks.hxx
@@ -0,0 +1,136 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <ooo/vba/excel/XHyperlinks.hpp>
+#include <rtl/ref.hxx>
+#include <vbahelper/vbacollectionimpl.hxx>
+
+class ScRangeList;
+
+namespace detail {
+
+class ScVbaHlinkContainer;
+typedef ::rtl::Reference< ScVbaHlinkContainer > ScVbaHlinkContainerRef;
+
+/** Base class for ScVbaHyperlinks to get an initialized ScVbaHlinkContainer
+ class member before the ScVbaHyperlinks_BASE base class will be constructed.
+ */
+struct ScVbaHlinkContainerMember
+{
+ ScVbaHlinkContainerRef mxContainer;
+
+ explicit ScVbaHlinkContainerMember( ScVbaHlinkContainer* pContainer );
+ ~ScVbaHlinkContainerMember();
+};
+
+} // namespace detail
+
+class ScVbaHyperlinks;
+typedef ::rtl::Reference< ScVbaHyperlinks > ScVbaHyperlinksRef;
+
+typedef CollTestImplHelper< ov::excel::XHyperlinks > ScVbaHyperlinks_BASE;
+
+/** Represents a collection of hyperlinks of a worksheet or of a range.
+
+ When a Hyperlinks collection object has been constructed from a VBA
+ Worksheet object, it will always represent the current set of all
+ hyperlinks existing in the sheet. Insertion and deletion of hyperlinks will
+ be reflected by the instance.
+
+ When a Hyperlinks collection object has been constructed from a VBA Range
+ object, it will represent the set of hyperlinks that have existed at its
+ construction time, and that are located completely inside the range(s)
+ represented by the Range object. Insertion and deletion of hyperlinks will
+ *not* be reflected by that instance. The instance will always offer all
+ hyperlinks it has been constructed with, even if they no longer exist.
+ Furthermore, the instance will not offer hyperlinks inserted later, even if
+ the instance itself has been used to insert the new hyperlinks.
+
+ VBA code example:
+
+ With ThisWorkbook.Worksheets(1)
+
+ Set hlinks = .Hyperlinks ' global Hyperlinks object
+ Set myrange = .Range("A1:C3")
+ Set rangelinks1 = myrange.Hyperlinks ' hyperlinks of range A1:C3
+
+ MsgBox hlinks.Count ' 0
+ MsgBox rangelinks1.Count ' 0
+
+ hlinks.Add .Range("A1"), "http://example.com"
+ ' a new hyperlink has been added in cell A1
+
+ MsgBox hlinks.Count ' 1
+ MsgBox rangelinks1.Count ' still 0!
+ Set rangelinks2 = myrange.Hyperlinks ' hyperlinks of range A1:C3
+ MsgBox rangelinks2.Count ' 1 (constructed after Add)
+
+ rangelinks1.Add .Range("A2"), "http://example.com"
+ ' a new hyperlink has been constructed via the rangelinks1 object
+ ' but this addition has been done by the worksheet Hyperlinks object
+
+ MsgBox hlinks.Count ' 2
+ MsgBox rangelinks1.Count ' still 0!!!
+ MsgBox rangelinks2.Count ' still 1!!!
+ MsgBox myrange.Hyperlinks.Count ' 2 (constructed after Add)
+
+ End With
+ */
+class ScVbaHyperlinks : private detail::ScVbaHlinkContainerMember, public ScVbaHyperlinks_BASE
+{
+public:
+ /// @throws css::uno::RuntimeException
+ explicit ScVbaHyperlinks(
+ const css::uno::Reference< ov::XHelperInterface >& rxParent,
+ const css::uno::Reference< css::uno::XComponentContext >& rxContext );
+
+ /// @throws css::uno::RuntimeException
+ explicit ScVbaHyperlinks(
+ const css::uno::Reference< ov::XHelperInterface >& rxParent,
+ const css::uno::Reference< css::uno::XComponentContext >& rxContext,
+ const ScVbaHyperlinksRef& rxSheetHlinks, const ScRangeList& rScRanges );
+
+ virtual ~ScVbaHyperlinks() override;
+
+ // XHyperlinks
+ virtual css::uno::Reference< ov::excel::XHyperlink > SAL_CALL Add(
+ const css::uno::Any& rAnchor, const css::uno::Any& rAddress, const css::uno::Any& rSubAddress,
+ const css::uno::Any& rScreenTip, const css::uno::Any& rTextToDisplay ) override;
+
+ virtual void SAL_CALL Delete() override;
+
+ // XEnumerationAccess
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+
+ // XElementAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+
+ // ScVbaCollectionBase
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& rSource ) override;
+
+ // XHelperInterface
+ VBAHELPER_DECL_XHELPERINTERFACE
+
+private:
+ ScVbaHyperlinksRef mxSheetHlinks;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbainterior.cxx b/sc/source/ui/vba/vbainterior.cxx
new file mode 100644
index 000000000..2849ed672
--- /dev/null
+++ b/sc/source/ui/vba/vbainterior.cxx
@@ -0,0 +1,413 @@
+/* -*- 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/beans/XPropertySet.hpp>
+#include <com/sun/star/xml/AttributeData.hpp>
+
+#include <ooo/vba/excel/XlColorIndex.hpp>
+#include <ooo/vba/excel/XlPattern.hpp>
+
+#include <map>
+
+#include <sal/macros.h>
+
+#include "vbainterior.hxx"
+#include "vbapalette.hxx"
+#include <document.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+using namespace ::ooo::vba::excel::XlPattern;
+
+constexpr OUStringLiteral BACKCOLOR = u"CellBackColor";
+constexpr OUStringLiteral PATTERN = u"Pattern";
+constexpr OUStringLiteral PATTERNCOLOR = u"PatternColor";
+
+static std::map< sal_Int32, sal_Int32 > aPatternMap {
+ { xlPatternAutomatic, 0 },
+ { xlPatternChecker, 9 },
+ { xlPatternCrissCross, 16 },
+ { xlPatternDown, 7 },
+ { xlPatternGray16, 17 },
+ { xlPatternGray25, 4 },
+ { xlPatternGray50, 2 },
+ { xlPatternGray75, 3 },
+ { xlPatternGray8, 18 },
+ { xlPatternGrid, 15 },
+ { xlPatternHorizontal, 5 },
+ { xlPatternLightDown, 13 },
+ { xlPatternLightHorizontal, 11 },
+ { xlPatternLightUp, 14 },
+ { xlPatternLightVertical, 12 },
+ { xlPatternNone, 0 },
+ { xlPatternSemiGray75, 10 },
+ { xlPatternSolid, 0 },
+ { xlPatternUp, 8 },
+ { xlPatternVertical, 6 }
+};
+
+ScVbaInterior::ScVbaInterior( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< beans::XPropertySet >& xProps, ScDocument* pScDoc ) : ScVbaInterior_BASE( xParent, xContext ), m_xProps(xProps), m_pScDoc( pScDoc )
+{
+ // auto color
+ m_aPattColor = Color(0);
+ m_nPattern = 0;
+ if ( !m_xProps.is() )
+ throw lang::IllegalArgumentException("properties", uno::Reference< uno::XInterface >(), 2 );
+}
+
+uno::Any
+ScVbaInterior::getColor()
+{
+ return uno::Any( OORGBToXLRGB( GetBackColor() ) );
+}
+
+void
+ScVbaInterior::setColor( const uno::Any& _color )
+{
+ sal_Int32 nColor = 0;
+ if( _color >>= nColor )
+ {
+ SetUserDefinedAttributes( BACKCOLOR, SetAttributeData( XLRGBToOORGB( nColor ) ) );
+ SetMixedColor();
+ }
+}
+
+void
+ScVbaInterior::SetMixedColor()
+{
+ // pattern
+ uno::Any aPattern = GetUserDefinedAttributes( PATTERN );
+ if( aPattern.hasValue() )
+ {
+ m_nPattern = GetAttributeData( aPattern );
+ }
+ sal_Int32 nPattern = aPatternMap[ m_nPattern ];
+ // pattern color
+ uno::Any aPatternColor = GetUserDefinedAttributes( PATTERNCOLOR );
+ if( aPatternColor.hasValue() )
+ {
+ sal_uInt32 nPatternColor = GetAttributeData( aPatternColor );
+ m_aPattColor = Color(ColorTransparency, nPatternColor);
+ }
+ Color nPatternColor = m_aPattColor;
+ // back color
+ Color aBackColor( GetBackColor() );
+ // set mixed color
+ Color aMixedColor;
+ if( nPattern > 0 )
+ aMixedColor = GetPatternColor( nPatternColor, aBackColor, static_cast<sal_uInt32>(nPattern) );
+ else
+ aMixedColor = GetPatternColor( aBackColor, aBackColor, static_cast<sal_uInt32>(nPattern) );
+ Color nMixedColor = aMixedColor.GetRGBColor();
+ m_xProps->setPropertyValue( BACKCOLOR , uno::Any( nMixedColor ) );
+}
+
+uno::Reference< container::XIndexAccess >
+ScVbaInterior::getPalette() const
+{
+ if ( !m_pScDoc )
+ throw uno::RuntimeException();
+ SfxObjectShell* pShell = m_pScDoc->GetDocumentShell();
+ ScVbaPalette aPalette( pShell );
+ return aPalette.getPalette();
+}
+
+void SAL_CALL
+ScVbaInterior::setColorIndex( const css::uno::Any& _colorindex )
+{
+ sal_Int32 nIndex = 0;
+ _colorindex >>= nIndex;
+
+ // hackly for excel::XlColorIndex::xlColorIndexNone
+ if( nIndex == excel::XlColorIndex::xlColorIndexNone )
+ {
+ m_xProps->setPropertyValue( BACKCOLOR, uno::Any( sal_Int32( -1 ) ) );
+ }
+ else
+ {
+ // setColor expects colors in XL RGB values
+ // #FIXME this is daft we convert OO RGB val to XL RGB val and
+ // then back again to OO RGB value
+ setColor( OORGBToXLRGB( GetIndexColor( nIndex ) ) );
+ }
+}
+uno::Any
+ScVbaInterior::GetIndexColor( sal_Int32 nColorIndex )
+{
+ sal_Int32 nIndex = nColorIndex;
+ // #FIXME xlColorIndexAutomatic & xlColorIndexNone are not really
+ // handled properly here
+ if ( !nIndex || ( nIndex == excel::XlColorIndex::xlColorIndexAutomatic ) || ( nIndex == excel::XlColorIndex::xlColorIndexNone ) )
+ nIndex = 2; // default is white ( this maybe will probably break, e.g. we may at some stage need to know what this interior is, a cell or something else and then pick a default colour based on that )
+ --nIndex; // OOo indices are zero bases
+ uno::Reference< container::XIndexAccess > xIndex = getPalette();
+ return xIndex->getByIndex( nIndex );
+}
+
+sal_Int32
+ScVbaInterior::GetColorIndex( const sal_Int32 nColor )
+{
+ uno::Reference< container::XIndexAccess > xIndex = getPalette();
+ sal_Int32 nElems = xIndex->getCount();
+ sal_Int32 nIndex = -1;
+ for ( sal_Int32 count=0; count<nElems; ++count )
+ {
+ sal_Int32 nPaletteColor = 0;
+ xIndex->getByIndex( count ) >>= nPaletteColor;
+ if ( nPaletteColor == nColor )
+ {
+ nIndex = count + 1; // 1 based
+ break;
+ }
+ }
+ return nIndex;
+}
+
+uno::Any SAL_CALL
+ScVbaInterior::getColorIndex()
+{
+ sal_Int32 nColor = 0;
+ // hackly for excel::XlColorIndex::xlColorIndexNone
+ uno::Any aColor = m_xProps->getPropertyValue( BACKCOLOR );
+ if( ( aColor >>= nColor ) && ( nColor == -1 ) )
+ {
+ nColor = excel::XlColorIndex::xlColorIndexNone;
+ return uno::Any( nColor );
+ }
+
+ // getColor returns Xl ColorValue, need to convert it to OO val
+ // as the palette deals with OO RGB values
+ // #FIXME this is daft in getColor we convert OO RGB val to XL RGB val
+ // and then back again to OO RGB value
+ XLRGBToOORGB( getColor() ) >>= nColor;
+
+ return uno::Any( GetColorIndex( nColor ) );
+}
+Color
+ScVbaInterior::GetPatternColor( const Color& rPattColor, const Color& rBackColor, sal_uInt32 nXclPattern )
+{
+ // 0x00 == 0% transparence (full rPattColor)
+ // 0x80 == 100% transparence (full rBackColor)
+ static const sal_uInt8 pnRatioTable[] =
+ {
+ 0x80, 0x00, 0x40, 0x20, 0x60, 0x40, 0x40, 0x40, // 00 - 07
+ 0x40, 0x40, 0x20, 0x60, 0x60, 0x60, 0x60, 0x48, // 08 - 15
+ 0x50, 0x70, 0x78 // 16 - 18
+ };
+ return ( nXclPattern < SAL_N_ELEMENTS( pnRatioTable ) ) ?
+ GetMixedColor( rPattColor, rBackColor, pnRatioTable[ nXclPattern ] ) : rPattColor;
+}
+Color
+ScVbaInterior::GetMixedColor( const Color& rFore, const Color& rBack, sal_uInt8 nTrans )
+{
+ return Color(
+ ColorTransparency, nTrans,
+ GetMixedColorComp( rFore.GetRed(), rBack.GetRed(), nTrans ),
+ GetMixedColorComp( rFore.GetGreen(), rBack.GetGreen(), nTrans ),
+ GetMixedColorComp( rFore.GetBlue(), rBack.GetBlue(), nTrans ));
+}
+sal_uInt8
+ScVbaInterior::GetMixedColorComp( sal_uInt8 nFore, sal_uInt8 nBack, sal_uInt8 nTrans )
+{
+ sal_uInt32 nTemp = ((static_cast< sal_Int32 >( nBack ) - nFore) * nTrans) / 0x80 + nFore;
+ return static_cast< sal_uInt8 >( nTemp );
+}
+uno::Reference< container::XNameContainer >
+ScVbaInterior::GetAttributeContainer()
+{
+ return uno::Reference < container::XNameContainer > ( m_xProps->getPropertyValue("UserDefinedAttributes"), uno::UNO_QUERY_THROW );
+}
+sal_Int32
+ScVbaInterior::GetAttributeData( uno::Any const & aValue )
+{
+ xml::AttributeData aDataValue;
+ if( aValue >>= aDataValue )
+ {
+ return aDataValue.Value.toInt32();
+ }
+ return 0;
+}
+uno::Any
+ScVbaInterior::SetAttributeData( sal_Int32 nValue )
+{
+ xml::AttributeData aAttributeData;
+ aAttributeData.Type = "sal_Int32";
+ aAttributeData.Value = OUString::number( nValue );
+ return uno::Any( aAttributeData );
+}
+uno::Any
+ScVbaInterior::GetUserDefinedAttributes( const OUString& sName )
+{
+ uno::Reference< container::XNameContainer > xNameContainer( GetAttributeContainer(), uno::UNO_SET_THROW );
+ if( xNameContainer->hasByName( sName ) )
+ {
+ return xNameContainer->getByName( sName );
+ }
+ return uno::Any();
+}
+void
+ScVbaInterior::SetUserDefinedAttributes( const OUString& sName, const uno::Any& aValue )
+{
+ if( aValue.hasValue() )
+ {
+ uno::Reference< container::XNameContainer > xNameContainer( GetAttributeContainer(), uno::UNO_SET_THROW );
+ if( xNameContainer->hasByName( sName ) )
+ xNameContainer->removeByName( sName );
+ xNameContainer->insertByName( sName, aValue );
+ m_xProps->setPropertyValue("UserDefinedAttributes", uno::Any( xNameContainer ) );
+ }
+}
+// OOo do not support below API
+uno::Any SAL_CALL
+ScVbaInterior::getPattern()
+{
+ // XlPattern
+ uno::Any aPattern = GetUserDefinedAttributes( PATTERN );
+ if( aPattern.hasValue() )
+ return uno::Any( GetAttributeData( aPattern ) );
+ return uno::Any( excel::XlPattern::xlPatternNone );
+}
+void SAL_CALL
+ScVbaInterior::setPattern( const uno::Any& _pattern )
+{
+ if( !(_pattern >>= m_nPattern) )
+ throw uno::RuntimeException("Invalid Pattern index" );
+
+ SetUserDefinedAttributes( PATTERN, SetAttributeData( m_nPattern ) );
+ SetMixedColor();
+
+}
+Color
+ScVbaInterior::GetBackColor()
+{
+ sal_Int32 nColor = 0;
+ Color aBackColor;
+ uno::Any aColor = GetUserDefinedAttributes( BACKCOLOR );
+ if( aColor.hasValue() )
+ {
+ nColor = GetAttributeData( aColor );
+ aBackColor = Color(ColorTransparency, nColor);
+ }
+ else
+ {
+ uno::Any aAny = OORGBToXLRGB( m_xProps->getPropertyValue( BACKCOLOR ) );
+ if( aAny >>= nColor )
+ {
+ nColor = XLRGBToOORGB( nColor );
+ aBackColor = Color(ColorTransparency, nColor);
+ SetUserDefinedAttributes( BACKCOLOR, SetAttributeData( nColor ) );
+ }
+ }
+ return aBackColor;
+}
+uno::Any SAL_CALL
+ScVbaInterior::getPatternColor()
+{
+ // 0 is the default color. no filled.
+ uno::Any aPatternColor = GetUserDefinedAttributes( PATTERNCOLOR );
+ if( aPatternColor.hasValue() )
+ {
+ sal_uInt32 nPatternColor = GetAttributeData( aPatternColor );
+ return uno::Any( OORGBToXLRGB( Color(ColorTransparency, nPatternColor) ) );
+ }
+ return uno::Any( sal_Int32( 0 ) );
+}
+void SAL_CALL
+ScVbaInterior::setPatternColor( const uno::Any& _patterncolor )
+{
+ sal_Int32 nPattColor = 0;
+ if( !(_patterncolor >>= nPattColor) )
+ throw uno::RuntimeException("Invalid Pattern Color" );
+
+ SetUserDefinedAttributes( PATTERNCOLOR, SetAttributeData( XLRGBToOORGB( nPattColor ) ) );
+ SetMixedColor();
+
+}
+uno::Any SAL_CALL
+ScVbaInterior::getPatternColorIndex()
+{
+ sal_Int32 nColor = 0;
+ XLRGBToOORGB( getPatternColor() ) >>= nColor;
+
+ return uno::Any( GetColorIndex( nColor ) );
+}
+void SAL_CALL
+ScVbaInterior::setPatternColorIndex( const uno::Any& _patterncolorindex )
+{
+ sal_Int32 nColorIndex = 0;
+ if( !(_patterncolorindex >>= nColorIndex) )
+ throw uno::RuntimeException("Invalid Pattern Color" );
+
+ if( nColorIndex == 0 )
+ return;
+ Color nPattColor;
+ GetIndexColor( nColorIndex ) >>= nPattColor;
+ setPatternColor( uno::Any( OORGBToXLRGB( nPattColor ) ) );
+
+}
+
+uno::Any SAL_CALL ScVbaInterior::getThemeColor()
+{
+ // Just a stub for now.
+ return uno::Any(static_cast<sal_Int32>(0));
+}
+
+void SAL_CALL ScVbaInterior::setThemeColor(const uno::Any& /*rAny*/)
+{
+ // Just a stub for now.
+}
+
+uno::Any SAL_CALL ScVbaInterior::getTintAndShade()
+{
+ // Just a stub for now.
+ return uno::Any(static_cast<double>(0));
+}
+
+void SAL_CALL ScVbaInterior::setTintAndShade(const uno::Any& /*rAny*/)
+{
+ // Just a stub for now.
+}
+
+uno::Any SAL_CALL ScVbaInterior::getPatternTintAndShade()
+{
+ // Just a stub for now.
+ return uno::Any(static_cast<double>(0));
+}
+
+void SAL_CALL ScVbaInterior::setPatternTintAndShade(const uno::Any& /*rAny*/)
+{
+ // Just a stub for now.
+}
+
+OUString
+ScVbaInterior::getServiceImplName()
+{
+ return "ScVbaInterior";
+}
+
+uno::Sequence< OUString >
+ScVbaInterior::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.Interior"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbainterior.hxx b/sc/source/ui/vba/vbainterior.hxx
new file mode 100644
index 000000000..1ea226e63
--- /dev/null
+++ b/sc/source/ui/vba/vbainterior.hxx
@@ -0,0 +1,83 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <ooo/vba/excel/XInterior.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+
+#include <vbahelper/vbahelperinterface.hxx>
+
+#include <tools/color.hxx>
+
+class ScDocument;
+
+typedef InheritedHelperInterfaceWeakImpl< ov::excel::XInterior > ScVbaInterior_BASE;
+
+class ScVbaInterior final : public ScVbaInterior_BASE
+{
+ css::uno::Reference< css::beans::XPropertySet > m_xProps;
+ ScDocument* m_pScDoc;
+ Color m_aPattColor;
+ sal_Int32 m_nPattern;
+
+ css::uno::Reference< css::container::XIndexAccess > getPalette() const;
+ css::uno::Reference< css::container::XNameContainer > GetAttributeContainer();
+ static css::uno::Any SetAttributeData( sal_Int32 nValue );
+ static sal_Int32 GetAttributeData( css::uno::Any const & aValue );
+ Color GetBackColor();
+ static Color GetPatternColor( const Color& rPattColor, const Color& rBackColor, sal_uInt32 nXclPattern );
+ static Color GetMixedColor( const Color& rFore, const Color& rBack, sal_uInt8 nTrans );
+ static sal_uInt8 GetMixedColorComp( sal_uInt8 nFore, sal_uInt8 nBack, sal_uInt8 nTrans );
+ css::uno::Any GetIndexColor( sal_Int32 nColorIndex );
+ sal_Int32 GetColorIndex( const sal_Int32 nColor );
+ css::uno::Any GetUserDefinedAttributes( const OUString& sName );
+ void SetUserDefinedAttributes( const OUString& sName, const css::uno::Any& aValue );
+ void SetMixedColor();
+
+public:
+ /// @throws css::lang::IllegalArgumentException
+ ScVbaInterior( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ const css::uno::Reference< css::beans::XPropertySet >& xProps, ScDocument* pScDoc = nullptr);
+
+ virtual css::uno::Any SAL_CALL getColor() override ;
+ virtual void SAL_CALL setColor( const css::uno::Any& _color ) override ;
+
+ virtual css::uno::Any SAL_CALL getColorIndex() override;
+ virtual void SAL_CALL setColorIndex( const css::uno::Any& _colorindex ) override;
+ virtual css::uno::Any SAL_CALL getPattern() override;
+ virtual void SAL_CALL setPattern( const css::uno::Any& _pattern ) override;
+ virtual css::uno::Any SAL_CALL getPatternColor() override;
+ virtual void SAL_CALL setPatternColor( const css::uno::Any& _patterncolor ) override;
+ virtual css::uno::Any SAL_CALL getPatternColorIndex() override;
+ virtual void SAL_CALL setPatternColorIndex( const css::uno::Any& _patterncolorindex ) override;
+ css::uno::Any SAL_CALL getThemeColor() override;
+ void SAL_CALL setThemeColor(const css::uno::Any& rAny) override;
+ css::uno::Any SAL_CALL getTintAndShade() override;
+ void SAL_CALL setTintAndShade(const css::uno::Any& rAny) override;
+ css::uno::Any SAL_CALL getPatternTintAndShade() override;
+ void SAL_CALL setPatternTintAndShade(const css::uno::Any& rAny) override;
+ //XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbalineshape.cxx b/sc/source/ui/vba/vbalineshape.cxx
new file mode 100644
index 000000000..fac0f1715
--- /dev/null
+++ b/sc/source/ui/vba/vbalineshape.cxx
@@ -0,0 +1,34 @@
+/* -*- 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 "vbalineshape.hxx"
+
+using namespace com::sun::star;
+using namespace ooo::vba;
+
+/*
+ * This is implemented as a new class in order to provide XTypeProvider
+ * interface. This is needed by TypeOf ... Is ... basic operator.
+ */
+
+ScVbaLineShape::ScVbaLineShape( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< drawing::XShape >& xShape, const uno::Reference< drawing::XShapes >& xShapes, const uno::Reference< frame::XModel >& xModel ) : LineShapeImpl_BASE( uno::Reference< XHelperInterface >(), xContext, xShape, xShapes, xModel, ScVbaShape::getType( xShape ) )
+{}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbalineshape.hxx b/sc/source/ui/vba/vbalineshape.hxx
new file mode 100644
index 000000000..953bc87a3
--- /dev/null
+++ b/sc/source/ui/vba/vbalineshape.hxx
@@ -0,0 +1,34 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <ooo/vba/msforms/XLine.hpp>
+#include <cppuhelper/implbase.hxx>
+#include <vbahelper/vbashape.hxx>
+
+typedef cppu::ImplInheritanceHelper< ScVbaShape, ov::msforms::XLine > LineShapeImpl_BASE;
+
+class ScVbaLineShape : public LineShapeImpl_BASE
+{
+public:
+ ScVbaLineShape( const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::drawing::XShape >& xShape, const css::uno::Reference< css::drawing::XShapes >& xShapes, const css::uno::Reference< css::frame::XModel >& xModel );
+
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbamenu.cxx b/sc/source/ui/vba/vbamenu.cxx
new file mode 100644
index 000000000..38b4feb11
--- /dev/null
+++ b/sc/source/ui/vba/vbamenu.cxx
@@ -0,0 +1,67 @@
+/* -*- 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/.
+ */
+
+#include "vbamenu.hxx"
+#include "vbamenuitems.hxx"
+#include <ooo/vba/XCommandBarControls.hpp>
+
+using namespace com::sun::star;
+using namespace ooo::vba;
+
+ScVbaMenu::ScVbaMenu( const uno::Reference< ov::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, const uno::Reference< XCommandBarControl >& rCommandBarControl ) : Menu_BASE( rParent, rContext ), m_xCommandBarControl( rCommandBarControl )
+{
+}
+
+OUString SAL_CALL
+ScVbaMenu::getCaption()
+{
+ return m_xCommandBarControl->getCaption();
+}
+
+void SAL_CALL
+ScVbaMenu::setCaption( const OUString& _caption )
+{
+ m_xCommandBarControl->setCaption( _caption );
+}
+
+void SAL_CALL
+ScVbaMenu::Delete( )
+{
+ m_xCommandBarControl->Delete();
+}
+
+uno::Any SAL_CALL
+ScVbaMenu::MenuItems( const uno::Any& aIndex )
+{
+ uno::Reference< XCommandBarControls > xCommandBarControls( m_xCommandBarControl->Controls( uno::Any() ), uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XMenuItems > xMenuItems( new ScVbaMenuItems( this, mxContext, xCommandBarControls ) );
+ if( aIndex.hasValue() )
+ {
+ return xMenuItems->Item( aIndex, uno::Any() );
+ }
+ return uno::Any( xMenuItems );
+}
+
+OUString
+ScVbaMenu::getServiceImplName()
+{
+ return "ScVbaMenu";
+}
+
+uno::Sequence<OUString>
+ScVbaMenu::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.Menu"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbamenu.hxx b/sc/source/ui/vba/vbamenu.hxx
new file mode 100644
index 000000000..284e2bc76
--- /dev/null
+++ b/sc/source/ui/vba/vbamenu.hxx
@@ -0,0 +1,37 @@
+/* -*- 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/.
+ */
+#pragma once
+
+#include <ooo/vba/excel/XMenu.hpp>
+#include <ooo/vba/XCommandBarControl.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+
+typedef InheritedHelperInterfaceWeakImpl< ov::excel::XMenu > Menu_BASE;
+
+class ScVbaMenu : public Menu_BASE
+{
+private:
+ css::uno::Reference< ov::XCommandBarControl > m_xCommandBarControl;
+
+public:
+ /// @throws css::uno::RuntimeException
+ ScVbaMenu( const css::uno::Reference< ov::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, const css::uno::Reference< ov::XCommandBarControl >& rCommandBarControl );
+
+ virtual OUString SAL_CALL getCaption() override;
+ virtual void SAL_CALL setCaption( const OUString& _caption ) override;
+
+ virtual void SAL_CALL Delete( ) override;
+ virtual css::uno::Any SAL_CALL MenuItems( const css::uno::Any& aIndex ) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbamenubar.cxx b/sc/source/ui/vba/vbamenubar.cxx
new file mode 100644
index 000000000..bd25c02a7
--- /dev/null
+++ b/sc/source/ui/vba/vbamenubar.cxx
@@ -0,0 +1,48 @@
+/* -*- 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/.
+ */
+#include "vbamenubar.hxx"
+#include "vbamenus.hxx"
+#include <ooo/vba/XCommandBarControls.hpp>
+
+using namespace com::sun::star;
+using namespace ooo::vba;
+
+ScVbaMenuBar::ScVbaMenuBar( const uno::Reference< ov::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, const uno::Reference< XCommandBar >& rCommandBar ) : MenuBar_BASE(rParent, rContext), m_xCommandBar(rCommandBar)
+{
+}
+
+uno::Any SAL_CALL
+ScVbaMenuBar::Menus( const uno::Any& aIndex )
+{
+ uno::Reference< XCommandBarControls > xCommandBarControls( m_xCommandBar->Controls( uno::Any() ), uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XMenus > xMenus( new ScVbaMenus( this, mxContext, xCommandBarControls ) );
+ if( aIndex.hasValue() )
+ {
+ return xMenus->Item( aIndex, uno::Any() );
+ }
+ return uno::Any( xMenus );
+}
+
+OUString
+ScVbaMenuBar::getServiceImplName()
+{
+ return "ScVbaMenuBar";
+}
+
+uno::Sequence<OUString>
+ScVbaMenuBar::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.MenuBar"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbamenubar.hxx b/sc/source/ui/vba/vbamenubar.hxx
new file mode 100644
index 000000000..75c1854c6
--- /dev/null
+++ b/sc/source/ui/vba/vbamenubar.hxx
@@ -0,0 +1,33 @@
+/* -*- 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/.
+ */
+#pragma once
+
+#include <ooo/vba/excel/XMenuBar.hpp>
+#include <ooo/vba/XCommandBar.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+
+typedef InheritedHelperInterfaceWeakImpl< ov::excel::XMenuBar > MenuBar_BASE;
+
+class ScVbaMenuBar : public MenuBar_BASE
+{
+private:
+ css::uno::Reference< ov::XCommandBar > m_xCommandBar;
+
+public:
+ /// @throws css::uno::RuntimeException
+ ScVbaMenuBar( const css::uno::Reference< ov::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, const css::uno::Reference< ov::XCommandBar >& rCommandBar );
+
+ virtual css::uno::Any SAL_CALL Menus( const css::uno::Any& aIndex ) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbamenubars.cxx b/sc/source/ui/vba/vbamenubars.cxx
new file mode 100644
index 000000000..6bcea2baa
--- /dev/null
+++ b/sc/source/ui/vba/vbamenubars.cxx
@@ -0,0 +1,118 @@
+/* -*- 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/.
+ */
+#include "vbamenubars.hxx"
+#include "vbamenubar.hxx"
+#include <cppuhelper/implbase.hxx>
+#include <ooo/vba/excel/XlSheetType.hpp>
+#include <ooo/vba/XCommandBars.hpp>
+
+using namespace com::sun::star;
+using namespace ooo::vba;
+
+namespace {
+
+class MenuBarEnumeration : public ::cppu::WeakImplHelper< container::XEnumeration >
+{
+ uno::Reference< XHelperInterface > m_xParent;
+ uno::Reference< uno::XComponentContext > m_xContext;
+ uno::Reference< container::XEnumeration > m_xEnumeration;
+public:
+ /// @throws uno::RuntimeException
+ MenuBarEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration) : m_xParent( xParent ), m_xContext( xContext ), m_xEnumeration( xEnumeration )
+ {
+ }
+ virtual sal_Bool SAL_CALL hasMoreElements() override
+ {
+ return m_xEnumeration->hasMoreElements();
+ }
+ virtual uno::Any SAL_CALL nextElement() override
+ {
+ // FIXME: should be add menubar
+ if( !hasMoreElements() )
+ throw container::NoSuchElementException();
+
+ uno::Reference< XCommandBar > xCommandBar( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XMenuBar > xMenuBar( new ScVbaMenuBar( m_xParent, m_xContext, xCommandBar ) );
+ return uno::Any( xMenuBar );
+ }
+};
+
+}
+
+ScVbaMenuBars::ScVbaMenuBars( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< XCommandBars >& xCommandBars ) : MenuBars_BASE( xParent, xContext, uno::Reference< container::XIndexAccess>() ), m_xCommandBars( xCommandBars )
+{
+}
+
+ScVbaMenuBars::~ScVbaMenuBars()
+{
+}
+
+// XEnumerationAccess
+uno::Type SAL_CALL
+ScVbaMenuBars::getElementType()
+{
+ return cppu::UnoType<excel::XMenuBar>::get();
+}
+
+uno::Reference< container::XEnumeration >
+ScVbaMenuBars::createEnumeration()
+{
+ uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xCommandBars, uno::UNO_QUERY_THROW );
+ return uno::Reference< container::XEnumeration >( new MenuBarEnumeration( this, mxContext, xEnumAccess->createEnumeration() ) );
+}
+
+uno::Any
+ScVbaMenuBars::createCollectionObject( const uno::Any& aSource )
+{
+ // make no sense
+ return aSource;
+}
+
+sal_Int32 SAL_CALL
+ScVbaMenuBars::getCount()
+{
+ return m_xCommandBars->getCount();
+}
+
+// ScVbaCollectionBaseImpl
+uno::Any SAL_CALL
+ScVbaMenuBars::Item( const uno::Any& aIndex, const uno::Any& /*aIndex2*/ )
+{
+ sal_Int16 nIndex = 0;
+ aIndex >>= nIndex;
+ if( nIndex == excel::XlSheetType::xlWorksheet )
+ {
+ uno::Any aSource;
+ aSource <<= OUString( "Worksheet Menu Bar" );
+ uno::Reference< XCommandBar > xCommandBar( m_xCommandBars->Item( aSource, uno::Any() ), uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XMenuBar > xMenuBar( new ScVbaMenuBar( this, mxContext, xCommandBar ) );
+ return uno::Any( xMenuBar );
+ }
+
+ throw uno::RuntimeException("Not implemented" );
+}
+
+// XHelperInterface
+OUString
+ScVbaMenuBars::getServiceImplName()
+{
+ return "ScVbaMenuBars";
+}
+
+uno::Sequence<OUString>
+ScVbaMenuBars::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.MenuBars"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbamenubars.hxx b/sc/source/ui/vba/vbamenubars.hxx
new file mode 100644
index 000000000..1303a0ff3
--- /dev/null
+++ b/sc/source/ui/vba/vbamenubars.hxx
@@ -0,0 +1,40 @@
+/* -*- 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/.
+ */
+#pragma once
+
+#include <ooo/vba/excel/XMenuBars.hpp>
+#include <vbahelper/vbacollectionimpl.hxx>
+
+namespace ooo::vba { class XCommandBars; }
+
+typedef CollTestImplHelper< ov::excel::XMenuBars > MenuBars_BASE;
+
+class ScVbaMenuBars : public MenuBars_BASE
+{
+private:
+ css::uno::Reference< ov::XCommandBars > m_xCommandBars;
+
+public:
+ /// @throws css::uno::RuntimeException
+ ScVbaMenuBars( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< ov::XCommandBars >& xCommandBars );
+ virtual ~ScVbaMenuBars() override;
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+
+ virtual sal_Int32 SAL_CALL getCount() override;
+ virtual css::uno::Any SAL_CALL Item( const css::uno::Any& aIndex, const css::uno::Any& /*aIndex2*/ ) override;
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbamenuitem.cxx b/sc/source/ui/vba/vbamenuitem.cxx
new file mode 100644
index 000000000..2dba780ba
--- /dev/null
+++ b/sc/source/ui/vba/vbamenuitem.cxx
@@ -0,0 +1,64 @@
+/* -*- 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/.
+ */
+#include "vbamenuitem.hxx"
+
+using namespace com::sun::star;
+using namespace ooo::vba;
+
+ScVbaMenuItem::ScVbaMenuItem( const uno::Reference< ov::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, const uno::Reference< XCommandBarControl >& rCommandBarControl ) : MenuItem_BASE( rParent, rContext ), m_xCommandBarControl( rCommandBarControl )
+{
+}
+
+OUString SAL_CALL
+ScVbaMenuItem::getCaption()
+{
+ return m_xCommandBarControl->getCaption();
+}
+
+void SAL_CALL
+ScVbaMenuItem::setCaption( const OUString& _caption )
+{
+ m_xCommandBarControl->setCaption( _caption );
+}
+
+OUString SAL_CALL
+ScVbaMenuItem::getOnAction()
+{
+ return m_xCommandBarControl->getOnAction();
+}
+
+void SAL_CALL
+ScVbaMenuItem::setOnAction( const OUString& _onaction )
+{
+ m_xCommandBarControl->setOnAction( _onaction );
+}
+
+void SAL_CALL
+ScVbaMenuItem::Delete( )
+{
+ m_xCommandBarControl->Delete();
+}
+
+OUString
+ScVbaMenuItem::getServiceImplName()
+{
+ return "ScVbaMenuItem";
+}
+
+uno::Sequence<OUString>
+ScVbaMenuItem::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.MenuItem"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbamenuitem.hxx b/sc/source/ui/vba/vbamenuitem.hxx
new file mode 100644
index 000000000..bf8c35b29
--- /dev/null
+++ b/sc/source/ui/vba/vbamenuitem.hxx
@@ -0,0 +1,38 @@
+/* -*- 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/.
+ */
+#pragma once
+
+#include <ooo/vba/excel/XMenuItem.hpp>
+#include <ooo/vba/XCommandBarControl.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+
+typedef InheritedHelperInterfaceWeakImpl< ov::excel::XMenuItem > MenuItem_BASE;
+
+class ScVbaMenuItem : public MenuItem_BASE
+{
+private:
+ css::uno::Reference< ov::XCommandBarControl > m_xCommandBarControl;
+
+public:
+ /// @throws css::uno::RuntimeException
+ ScVbaMenuItem( const css::uno::Reference< ov::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, const css::uno::Reference< ov::XCommandBarControl >& rCommandBarControl );
+
+ virtual OUString SAL_CALL getCaption() override;
+ virtual void SAL_CALL setCaption( const OUString& _caption ) override;
+ virtual OUString SAL_CALL getOnAction() override;
+ virtual void SAL_CALL setOnAction( const OUString& _onaction ) override;
+
+ virtual void SAL_CALL Delete( ) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbamenuitems.cxx b/sc/source/ui/vba/vbamenuitems.cxx
new file mode 100644
index 000000000..646fd82cb
--- /dev/null
+++ b/sc/source/ui/vba/vbamenuitems.cxx
@@ -0,0 +1,138 @@
+/* -*- 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/.
+ */
+#include "vbamenuitems.hxx"
+#include "vbamenuitem.hxx"
+#include "vbamenu.hxx"
+#include <cppuhelper/implbase.hxx>
+#include <ooo/vba/office/MsoControlType.hpp>
+#include <ooo/vba/XCommandBarControls.hpp>
+
+using namespace com::sun::star;
+using namespace ooo::vba;
+
+typedef ::cppu::WeakImplHelper< container::XEnumeration > MenuEnumeration_BASE;
+
+namespace {
+
+class MenuEnumeration : public MenuEnumeration_BASE
+{
+ uno::Reference< XHelperInterface > m_xParent;
+ uno::Reference< uno::XComponentContext > m_xContext;
+ uno::Reference< container::XEnumeration > m_xEnumeration;
+public:
+ /// @throws uno::RuntimeException
+ MenuEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration) : m_xParent( xParent ), m_xContext( xContext ), m_xEnumeration( xEnumeration )
+ {
+ }
+ virtual sal_Bool SAL_CALL hasMoreElements() override
+ {
+ return m_xEnumeration->hasMoreElements();
+ }
+ virtual uno::Any SAL_CALL nextElement() override
+ {
+ // FIXME: should be add menu
+ if( !hasMoreElements() )
+ throw container::NoSuchElementException();
+
+ uno::Reference< XCommandBarControl > xCommandBarControl( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW );
+ if( xCommandBarControl->getType() == office::MsoControlType::msoControlPopup )
+ {
+ uno::Reference< excel::XMenu > xMenu( new ScVbaMenu( m_xParent, m_xContext, xCommandBarControl ) );
+ return uno::Any( xMenu );
+ }
+ else if( xCommandBarControl->getType() == office::MsoControlType::msoControlButton )
+ {
+ uno::Reference< excel::XMenuItem > xMenuItem( new ScVbaMenuItem( m_xParent, m_xContext, xCommandBarControl ) );
+ return uno::Any( xMenuItem );
+ }
+ nextElement();
+
+ return uno::Any();
+ }
+};
+
+}
+
+ScVbaMenuItems::ScVbaMenuItems( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< XCommandBarControls >& xCommandBarControls ) : MenuItems_BASE( xParent, xContext, uno::Reference< container::XIndexAccess>() ), m_xCommandBarControls( xCommandBarControls )
+{
+}
+
+// XEnumerationAccess
+uno::Type SAL_CALL
+ScVbaMenuItems::getElementType()
+{
+ return cppu::UnoType<excel::XMenuItem>::get();
+}
+
+uno::Reference< container::XEnumeration >
+ScVbaMenuItems::createEnumeration()
+{
+ uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xCommandBarControls, uno::UNO_QUERY_THROW );
+ return uno::Reference< container::XEnumeration >( new MenuEnumeration( this, mxContext, xEnumAccess->createEnumeration() ) );
+}
+
+uno::Any
+ScVbaMenuItems::createCollectionObject( const uno::Any& aSource )
+{
+ // make no sense
+ return aSource;
+}
+
+sal_Int32 SAL_CALL
+ScVbaMenuItems::getCount()
+{
+ // FIXME: should check if it is a popup menu
+ return m_xCommandBarControls->getCount();
+}
+
+// ScVbaCollectionBaseImpl
+uno::Any SAL_CALL
+ScVbaMenuItems::Item( const uno::Any& aIndex, const uno::Any& /*aIndex2*/ )
+{
+ uno::Reference< XCommandBarControl > xCommandBarControl( m_xCommandBarControls->Item( aIndex, uno::Any() ), uno::UNO_QUERY_THROW );
+ if( xCommandBarControl->getType() == office::MsoControlType::msoControlPopup )
+ return uno::Any( uno::Reference< excel::XMenu > ( new ScVbaMenu( this, mxContext, xCommandBarControl ) ) );
+ else if( xCommandBarControl->getType() == office::MsoControlType::msoControlButton )
+ return uno::Any( uno::Reference< excel::XMenuItem > ( new ScVbaMenuItem( this, mxContext, xCommandBarControl ) ) );
+ throw uno::RuntimeException();
+}
+
+uno::Reference< excel::XMenuItem > SAL_CALL ScVbaMenuItems::Add( const OUString& Caption, const css::uno::Any& OnAction, const css::uno::Any& /*ShortcutKey*/, const css::uno::Any& Before, const css::uno::Any& Restore, const css::uno::Any& /*StatusBar*/, const css::uno::Any& /*HelpFile*/, const css::uno::Any& /*HelpContextID*/ )
+{
+ uno::Reference< XCommandBarControl > xCommandBarControl = m_xCommandBarControls->Add(
+ uno::Any( office::MsoControlType::msoControlButton ),
+ uno::Any(), uno::Any(), Before, Restore );
+ xCommandBarControl->setCaption( Caption );
+ if( OnAction.hasValue() )
+ {
+ OUString sAction;
+ OnAction >>= sAction;
+ xCommandBarControl->setOnAction( sAction );
+ }
+ return uno::Reference< excel::XMenuItem >( new ScVbaMenuItem( this, mxContext, xCommandBarControl ) );
+}
+
+// XHelperInterface
+OUString
+ScVbaMenuItems::getServiceImplName()
+{
+ return "ScVbaMenuItems";
+}
+
+uno::Sequence<OUString>
+ScVbaMenuItems::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.MenuItems"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbamenuitems.hxx b/sc/source/ui/vba/vbamenuitems.hxx
new file mode 100644
index 000000000..71f43e634
--- /dev/null
+++ b/sc/source/ui/vba/vbamenuitems.hxx
@@ -0,0 +1,42 @@
+/* -*- 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/.
+ */
+#pragma once
+
+#include <ooo/vba/excel/XMenuItems.hpp>
+#include <vbahelper/vbacollectionimpl.hxx>
+
+namespace ooo::vba { class XCommandBarControls; }
+namespace ooo::vba::excel { class XMenuItem; }
+
+typedef CollTestImplHelper< ov::excel::XMenuItems > MenuItems_BASE;
+
+class ScVbaMenuItems : public MenuItems_BASE
+{
+private:
+ css::uno::Reference< ov::XCommandBarControls > m_xCommandBarControls;
+
+public:
+ /// @throws css::uno::RuntimeException
+ ScVbaMenuItems( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< ov::XCommandBarControls >& xCommandBarControls );
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+
+ // Methods
+ virtual sal_Int32 SAL_CALL getCount() override;
+ virtual css::uno::Any SAL_CALL Item( const css::uno::Any& Index, const css::uno::Any& /*Index2*/ ) override;
+ virtual css::uno::Reference< ov::excel::XMenuItem > SAL_CALL Add( const OUString& Caption, const css::uno::Any& OnAction, const css::uno::Any& ShortcutKey, const css::uno::Any& Before, const css::uno::Any& Restore, const css::uno::Any& StatusBar, const css::uno::Any& HelpFile, const css::uno::Any& HelpContextID ) override;
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbamenus.cxx b/sc/source/ui/vba/vbamenus.cxx
new file mode 100644
index 000000000..807f0cf5a
--- /dev/null
+++ b/sc/source/ui/vba/vbamenus.cxx
@@ -0,0 +1,124 @@
+/* -*- 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/.
+ */
+#include "vbamenus.hxx"
+#include "vbamenu.hxx"
+#include <cppuhelper/implbase.hxx>
+#include <ooo/vba/office/MsoControlType.hpp>
+#include <ooo/vba/XCommandBarControls.hpp>
+
+using namespace com::sun::star;
+using namespace ooo::vba;
+
+typedef ::cppu::WeakImplHelper< container::XEnumeration > MenuEnumeration_BASE;
+
+namespace {
+
+class MenuEnumeration : public MenuEnumeration_BASE
+{
+ uno::Reference< XHelperInterface > m_xParent;
+ uno::Reference< uno::XComponentContext > m_xContext;
+ uno::Reference< container::XEnumeration > m_xEnumeration;
+public:
+ /// @throws uno::RuntimeException
+ MenuEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration) : m_xParent( xParent ), m_xContext( xContext ), m_xEnumeration( xEnumeration )
+ {
+ }
+ virtual sal_Bool SAL_CALL hasMoreElements() override
+ {
+ return m_xEnumeration->hasMoreElements();
+ }
+ virtual uno::Any SAL_CALL nextElement() override
+ {
+ // FIXME: should be add menu
+ if( !hasMoreElements() )
+ throw container::NoSuchElementException();
+
+ uno::Reference< XCommandBarControl > xCommandBarControl( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW );
+ if( xCommandBarControl->getType() == office::MsoControlType::msoControlPopup )
+ {
+ uno::Reference< excel::XMenu > xMenu( new ScVbaMenu( m_xParent, m_xContext, xCommandBarControl ) );
+ return uno::Any( xMenu );
+ }
+ nextElement();
+
+ return uno::Any();
+ }
+};
+
+}
+
+ScVbaMenus::ScVbaMenus( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< XCommandBarControls >& xCommandBarControls ) : Menus_BASE( xParent, xContext, uno::Reference< container::XIndexAccess>() ), m_xCommandBarControls( xCommandBarControls )
+{
+}
+
+// XEnumerationAccess
+uno::Type SAL_CALL
+ScVbaMenus::getElementType()
+{
+ return cppu::UnoType<excel::XMenu>::get();
+}
+
+uno::Reference< container::XEnumeration >
+ScVbaMenus::createEnumeration()
+{
+ uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xCommandBarControls, uno::UNO_QUERY_THROW );
+ return uno::Reference< container::XEnumeration >( new MenuEnumeration( this, mxContext, xEnumAccess->createEnumeration() ) );
+}
+
+uno::Any
+ScVbaMenus::createCollectionObject( const uno::Any& aSource )
+{
+ // make no sense
+ return aSource;
+}
+
+sal_Int32 SAL_CALL
+ScVbaMenus::getCount()
+{
+ // FIXME: should check if it is a popup menu
+ return m_xCommandBarControls->getCount();
+}
+
+// ScVbaCollectionBaseImpl
+uno::Any SAL_CALL
+ScVbaMenus::Item( const uno::Any& aIndex, const uno::Any& /*aIndex2*/ )
+{
+ uno::Reference< XCommandBarControl > xCommandBarControl( m_xCommandBarControls->Item( aIndex, uno::Any() ), uno::UNO_QUERY_THROW );
+ if( xCommandBarControl->getType() != office::MsoControlType::msoControlPopup )
+ throw uno::RuntimeException();
+ return uno::Any( uno::Reference< excel::XMenu > ( new ScVbaMenu( this, mxContext, xCommandBarControl ) ) );
+}
+
+uno::Reference< excel::XMenu > SAL_CALL ScVbaMenus::Add( const OUString& Caption, const css::uno::Any& Before, const css::uno::Any& Restore )
+{
+ uno::Reference< XCommandBarControl > xCommandBarControl = m_xCommandBarControls->Add(
+ uno::Any( office::MsoControlType::msoControlPopup ),
+ uno::Any(), uno::Any(), Before, Restore );
+ xCommandBarControl->setCaption( Caption );
+ return uno::Reference< excel::XMenu >( new ScVbaMenu( this, mxContext, xCommandBarControl ) );
+}
+
+// XHelperInterface
+OUString
+ScVbaMenus::getServiceImplName()
+{
+ return "ScVbaMenus";
+}
+
+uno::Sequence<OUString>
+ScVbaMenus::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.Menus"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbamenus.hxx b/sc/source/ui/vba/vbamenus.hxx
new file mode 100644
index 000000000..2a14cf3cb
--- /dev/null
+++ b/sc/source/ui/vba/vbamenus.hxx
@@ -0,0 +1,42 @@
+/* -*- 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/.
+ */
+#pragma once
+
+#include <ooo/vba/excel/XMenus.hpp>
+#include <vbahelper/vbacollectionimpl.hxx>
+
+namespace ooo::vba { class XCommandBarControls; }
+namespace ooo::vba::excel { class XMenu; }
+
+typedef CollTestImplHelper< ov::excel::XMenus > Menus_BASE;
+
+class ScVbaMenus : public Menus_BASE
+{
+private:
+ css::uno::Reference< ov::XCommandBarControls > m_xCommandBarControls;
+
+public:
+ /// @throws css::uno::RuntimeException
+ ScVbaMenus( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< ov::XCommandBarControls >& xCommandBarControls );
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+
+ // Methods
+ virtual sal_Int32 SAL_CALL getCount() override;
+ virtual css::uno::Any SAL_CALL Item( const css::uno::Any& Index, const css::uno::Any& /*Index2*/ ) override;
+ virtual css::uno::Reference< ov::excel::XMenu > SAL_CALL Add( const OUString& Caption, const css::uno::Any& Before, const css::uno::Any& Restore ) override;
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaname.cxx b/sc/source/ui/vba/vbaname.cxx
new file mode 100644
index 000000000..7ef8fe129
--- /dev/null
+++ b/sc/source/ui/vba/vbaname.cxx
@@ -0,0 +1,216 @@
+/* -*- 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 "excelvbahelper.hxx"
+#include "vbaname.hxx"
+#include "vbarange.hxx"
+#include <docsh.hxx>
+#include <rangenam.hxx>
+#include <nameuno.hxx>
+#include <compiler.hxx>
+#include <tokenarray.hxx>
+
+#include <memory>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+ScVbaName::ScVbaName(const css::uno::Reference< ov::XHelperInterface >& xParent,
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ const css::uno::Reference< css::sheet::XNamedRange >& xName,
+ const css::uno::Reference< css::sheet::XNamedRanges >& xNames,
+ const css::uno::Reference< css::frame::XModel >& xModel ):
+ NameImpl_BASE( xParent , xContext ),
+ mxModel( xModel ),
+ mxNamedRange( xName ),
+ mxNames( xNames )
+{
+}
+
+ScVbaName::~ScVbaName()
+{
+}
+
+OUString
+ScVbaName::getName()
+{
+ return mxNamedRange->getName();
+}
+
+void
+ScVbaName::setName( const OUString & rName )
+{
+ mxNamedRange->setName( rName );
+}
+
+OUString
+ScVbaName::getNameLocal()
+{
+ return getName();
+}
+
+void
+ScVbaName::setNameLocal( const OUString & rName )
+{
+ setName( rName );
+}
+
+sal_Bool
+ScVbaName::getVisible()
+{
+ return true;
+}
+
+void
+ScVbaName::setVisible( sal_Bool /*bVisible*/ )
+{
+}
+
+OUString ScVbaName::getContent( const formula::FormulaGrammar::Grammar eGrammar )
+{
+ ScNamedRangeObj* pNamedRange = dynamic_cast< ScNamedRangeObj* >( mxNamedRange.get() );
+ OUString aContent;
+ if ( pNamedRange )
+ {
+ ScRangeData* pData = pNamedRange->GetRangeData_Impl();
+ if (pData)
+ aContent = pData->GetSymbol( eGrammar );
+ }
+ if (aContent.indexOf('=') != 0)
+ aContent = "=" + aContent;
+ return aContent;
+}
+
+void ScVbaName::setContent( const OUString& rContent, const formula::FormulaGrammar::Grammar eGrammar )
+{
+ OUString sContent( rContent );
+ if (sContent.startsWith("="))
+ sContent = sContent.copy(1);
+ ScNamedRangeObj* pNamedRange = dynamic_cast< ScNamedRangeObj* >( mxNamedRange.get() );
+
+ // We should be able to do the below by just setting calling SetCode on pNamedRange
+ // right?
+ if ( !(pNamedRange && pNamedRange->pDocShell) )
+ return;
+
+ ScDocument& rDoc = pNamedRange->pDocShell->GetDocument();
+ ScRangeData* pOldData = pNamedRange->GetRangeData_Impl();
+ if (pOldData)
+ {
+ // Shorter way of doing this ?
+ ScCompiler aComp( rDoc, pOldData->GetPos(), eGrammar );
+ std::unique_ptr<ScTokenArray> pArray(aComp.CompileString(sContent));
+ pOldData->SetCode(*pArray);
+ }
+}
+
+OUString
+ScVbaName::getValue()
+{
+ OUString sResult = getContent( formula::FormulaGrammar::GRAM_NATIVE_XL_A1 );
+
+ return sResult;
+}
+
+void
+ScVbaName::setValue( const OUString & rValue )
+{
+ setContent( rValue, formula::FormulaGrammar::GRAM_NATIVE_XL_A1 );
+}
+
+OUString
+ScVbaName::getRefersTo()
+{
+ return getValue();
+}
+
+void
+ScVbaName::setRefersTo( const OUString & rRefersTo )
+{
+ setValue( rRefersTo );
+}
+
+OUString
+ScVbaName::getRefersToLocal()
+{
+ return getRefersTo();
+}
+
+void
+ScVbaName::setRefersToLocal( const OUString & rRefersTo )
+{
+ setRefersTo( rRefersTo );
+}
+
+OUString
+ScVbaName::getRefersToR1C1()
+{
+ OUString sResult = getContent( formula::FormulaGrammar::GRAM_NATIVE_XL_R1C1 );
+ return sResult;
+}
+
+void
+ScVbaName::setRefersToR1C1( const OUString & rRefersTo )
+{
+ setContent( rRefersTo, formula::FormulaGrammar::GRAM_NATIVE_XL_R1C1 );
+}
+
+OUString
+ScVbaName::getRefersToR1C1Local()
+{
+ return getRefersToR1C1();
+}
+
+void
+ScVbaName::setRefersToR1C1Local( const OUString & rRefersTo )
+{
+ setRefersTo( rRefersTo );
+}
+
+css::uno::Reference< ov::excel::XRange >
+ScVbaName::getRefersToRange()
+{
+ uno::Reference< ov::excel::XRange > xRange = ScVbaRange::getRangeObjectForName(
+ mxContext, mxNamedRange->getName(), excel::getDocShell( mxModel ), formula::FormulaGrammar::CONV_XL_R1C1 );
+ return xRange;
+}
+
+void
+ScVbaName::Delete()
+{
+ mxNames->removeByName( mxNamedRange->getName() );
+}
+
+OUString
+ScVbaName::getServiceImplName()
+{
+ return "ScVbaName";
+}
+
+uno::Sequence< OUString >
+ScVbaName::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.Name"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaname.hxx b/sc/source/ui/vba/vbaname.hxx
new file mode 100644
index 000000000..194b047fa
--- /dev/null
+++ b/sc/source/ui/vba/vbaname.hxx
@@ -0,0 +1,69 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <ooo/vba/excel/XName.hpp>
+
+#include <vbahelper/vbahelperinterface.hxx>
+#include <formula/grammar.hxx>
+
+namespace com::sun::star::sheet { class XNamedRange; }
+namespace com::sun::star::sheet { class XNamedRanges; }
+
+typedef InheritedHelperInterfaceWeakImpl< ov::excel::XName > NameImpl_BASE;
+
+class ScVbaName : public NameImpl_BASE
+{
+ css::uno::Reference< css::frame::XModel > mxModel;
+ css::uno::Reference< css::sheet::XNamedRange > mxNamedRange;
+ css::uno::Reference< css::sheet::XNamedRanges > mxNames;
+ OUString getContent( const formula::FormulaGrammar::Grammar eGrammar );
+ void setContent( const OUString& sContent, const formula::FormulaGrammar::Grammar eGrammar );
+public:
+ ScVbaName( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::sheet::XNamedRange >& xName , const css::uno::Reference< css::sheet::XNamedRanges >& xNames , const css::uno::Reference< css::frame::XModel >& xModel );
+ virtual ~ScVbaName() override;
+
+ // Attributes
+ virtual OUString SAL_CALL getName() override;
+ virtual void SAL_CALL setName( const OUString &rName ) override;
+ virtual OUString SAL_CALL getNameLocal() override;
+ virtual void SAL_CALL setNameLocal( const OUString &rName ) override;
+ virtual sal_Bool SAL_CALL getVisible() override;
+ virtual void SAL_CALL setVisible( sal_Bool bVisible ) override;
+ virtual OUString SAL_CALL getValue() override;
+ virtual void SAL_CALL setValue( const OUString &rValue ) override;
+ virtual OUString SAL_CALL getRefersTo() override;
+ virtual void SAL_CALL setRefersTo( const OUString &rRefersTo ) override;
+ virtual OUString SAL_CALL getRefersToLocal() override;
+ virtual void SAL_CALL setRefersToLocal( const OUString &rRefersTo ) override;
+ virtual OUString SAL_CALL getRefersToR1C1() override;
+ virtual void SAL_CALL setRefersToR1C1( const OUString &rRefersTo ) override;
+ virtual OUString SAL_CALL getRefersToR1C1Local() override;
+ virtual void SAL_CALL setRefersToR1C1Local( const OUString &rRefersTo ) override;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL getRefersToRange() override;
+
+ // Methods
+ virtual void SAL_CALL Delete() override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbanames.cxx b/sc/source/ui/vba/vbanames.cxx
new file mode 100644
index 000000000..287dbcf3c
--- /dev/null
+++ b/sc/source/ui/vba/vbanames.cxx
@@ -0,0 +1,260 @@
+/* -*- 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/table/XCellRange.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/sheet/XNamedRange.hpp>
+#include <com/sun/star/sheet/XNamedRanges.hpp>
+
+#include "excelvbahelper.hxx"
+#include "vbanames.hxx"
+#include "vbaname.hxx"
+#include "vbarange.hxx"
+#include <tabvwsh.hxx>
+#include <viewdata.hxx>
+#include <compiler.hxx>
+#include <tokenarray.hxx>
+#include <cellsuno.hxx>
+
+#include <memory>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+namespace {
+
+class NamesEnumeration : public EnumerationHelperImpl
+{
+ uno::Reference< frame::XModel > m_xModel;
+ uno::Reference< sheet::XNamedRanges > m_xNames;
+public:
+ /// @throws uno::RuntimeException
+ NamesEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Reference< frame::XModel >& xModel , const uno::Reference< sheet::XNamedRanges >& xNames ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), m_xModel( xModel ), m_xNames( xNames ) {}
+
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ uno::Reference< sheet::XNamedRange > xNamed( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW );
+ return uno::Any( uno::Reference< excel::XName > ( new ScVbaName( m_xParent, m_xContext, xNamed ,m_xNames , m_xModel ) ) );
+ }
+
+};
+
+}
+
+ScVbaNames::ScVbaNames(const css::uno::Reference< ov::XHelperInterface >& xParent,
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ const css::uno::Reference< css::sheet::XNamedRanges >& xNames,
+ const css::uno::Reference< css::frame::XModel >& xModel ):
+ ScVbaNames_BASE( xParent , xContext , uno::Reference< container::XIndexAccess >( xNames, uno::UNO_QUERY ) ),
+ mxModel( xModel ),
+ mxNames( xNames )
+{
+ m_xNameAccess.set( xNames, uno::UNO_QUERY_THROW );
+}
+
+ScVbaNames::~ScVbaNames()
+{
+}
+
+ScDocument&
+ScVbaNames::getScDocument()
+{
+ uno::Reference< frame::XModel > xModel( getModel() , uno::UNO_SET_THROW );
+ ScTabViewShell * pTabViewShell = excel::getBestViewShell( xModel );
+ if ( !pTabViewShell )
+ throw uno::RuntimeException( "No ViewShell available" );
+ ScViewData& rViewData = pTabViewShell->GetViewData();
+ return rViewData.GetDocument();
+}
+
+css::uno::Any
+ScVbaNames::Add( const css::uno::Any& Name ,
+ const css::uno::Any& RefersTo,
+ const css::uno::Any& /*Visible*/,
+ const css::uno::Any& /*MacroType*/,
+ const css::uno::Any& /*ShoutcutKey*/,
+ const css::uno::Any& /*Category*/,
+ const css::uno::Any& NameLocal,
+ const css::uno::Any& /*RefersToLocal*/,
+ const css::uno::Any& /*CategoryLocal*/,
+ const css::uno::Any& RefersToR1C1,
+ const css::uno::Any& RefersToR1C1Local )
+{
+ OUString sName;
+ uno::Reference< excel::XRange > xRange;
+ if ( Name.hasValue() )
+ Name >>= sName;
+ else if ( NameLocal.hasValue() )
+ NameLocal >>= sName;
+ if ( !sName.isEmpty() )
+ {
+ if (ScRangeData::IsNameValid(sName, getScDocument())
+ != ScRangeData::IsNameValidType::NAME_VALID)
+ {
+ const sal_Int32 nIndex{ sName.indexOf('!') };
+ if (nIndex>=0)
+ sName = sName.copy(nIndex+1);
+ if (ScRangeData::IsNameValid(sName, getScDocument())
+ != ScRangeData::IsNameValidType::NAME_VALID)
+ throw uno::RuntimeException( "This Name is not valid ." );
+ }
+ }
+ uno::Reference< table::XCellRange > xUnoRange;
+ if ( RefersTo.hasValue() || RefersToR1C1.hasValue() || RefersToR1C1Local.hasValue() )
+ {
+ OUString sFormula;
+
+ formula::FormulaGrammar::Grammar eGram = formula::FormulaGrammar::GRAM_NATIVE_XL_A1;
+ if ( RefersTo.hasValue() )
+ {
+ if ( RefersTo.getValueTypeClass() == uno::TypeClass_STRING )
+ RefersTo >>= sFormula;
+ else
+ RefersTo >>= xRange;
+ }
+ if ( RefersToR1C1.hasValue() )
+ {
+ if ( RefersToR1C1.getValueTypeClass() == uno::TypeClass_STRING )
+ {
+ RefersToR1C1 >>= sFormula;
+ eGram = formula::FormulaGrammar::GRAM_NATIVE_XL_R1C1;
+ }
+ else
+ RefersToR1C1 >>= xRange;
+ }
+ if ( RefersToR1C1Local.hasValue() )
+ {
+ if ( RefersToR1C1Local.getValueTypeClass() == uno::TypeClass_STRING )
+ {
+ RefersToR1C1Local >>= sFormula;
+ eGram = formula::FormulaGrammar::GRAM_NATIVE_XL_R1C1;
+ }
+ else
+ RefersToR1C1Local >>= xRange;
+ }
+ if ( !xRange.is() && !sFormula.isEmpty() )
+ {
+ ScAddress aBlank;
+ ScCompiler aComp( getScDocument(), aBlank, eGram );
+ std::unique_ptr<ScTokenArray> pTokens(aComp.CompileString(sFormula));
+ if ( pTokens )
+ {
+ ScRange aRange;
+ ScDocShell* pDocSh = excel::getDocShell(getModel());
+ if (pTokens->IsValidReference(aRange, aBlank))
+ xUnoRange = new ScCellRangeObj( pDocSh, aRange );
+ else
+ {
+ // assume it's an address try strip the '=' if it's there
+ // and try and create a range ( must be a better way )
+ if ( sFormula.startsWith("=") )
+ sFormula = sFormula.copy(1);
+ ScRangeList aCellRanges;
+ ScRefFlags nFlags = ScRefFlags::ZERO;
+ formula::FormulaGrammar::AddressConvention eConv = ( eGram == formula::FormulaGrammar::GRAM_NATIVE_XL_A1 ) ? formula::FormulaGrammar::CONV_XL_A1 : formula::FormulaGrammar::CONV_XL_R1C1;
+ if ( ScVbaRange::getCellRangesForAddress( nFlags, sFormula, pDocSh, aCellRanges, eConv , ',' ) )
+ {
+ if ( aCellRanges.size() == 1 )
+ xUnoRange = new ScCellRangeObj( pDocSh, aCellRanges.front() );
+ else
+ {
+ uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pDocSh, aCellRanges ) );
+ xRange = new ScVbaRange( mxParent, mxContext, xRanges );
+ }
+ }
+
+ }
+ }
+ }
+ }
+
+ if ( xRange.is() || xUnoRange.is() )
+ {
+ if ( !xRange.is() )
+ xRange = new ScVbaRange( mxParent, mxContext, xUnoRange );
+
+ uno::Reference< excel::XRange > xArea( xRange->Areas( uno::Any( sal_Int32(1) ) ), uno::UNO_QUERY );
+
+ uno::Any aAny = xArea->getCellRange() ;
+
+ uno::Reference< sheet::XCellRangeAddressable > thisRangeAdd( aAny, ::uno::UNO_QUERY_THROW);
+
+ table::CellRangeAddress aAddr = thisRangeAdd->getRangeAddress();
+ uno::Any aAny2;
+ if ( mxNames.is() )
+ {
+ table::CellAddress aCellAddr( aAddr.Sheet , aAddr.StartColumn , aAddr.StartRow );
+ if ( mxNames->hasByName( sName ) )
+ mxNames->removeByName(sName);
+ OUStringBuffer sTmp = "$";
+ uno::Reference< ov::XCollection > xCol( xRange->Areas( uno::Any() ), uno::UNO_QUERY );
+ for ( sal_Int32 nArea = 1; nArea <= xCol->getCount(); ++nArea )
+ {
+ xArea.set( xRange->Areas( uno::Any( nArea ) ), uno::UNO_QUERY_THROW );
+
+ OUString sRangeAdd = xArea->Address( aAny2, aAny2 , aAny2 , aAny2, aAny2 );
+ if ( nArea > 1 )
+ sTmp.append(",");
+ sTmp.append("'" + xRange->getWorksheet()->getName() + "'." + sRangeAdd);
+ }
+ mxNames->addNewByName( sName, sTmp.makeStringAndClear(), aCellAddr, 0/*nUnoType*/);
+ return Item( uno::Any( sName ), uno::Any() );
+ }
+ }
+ return css::uno::Any();
+}
+
+// XEnumerationAccess
+css::uno::Type
+ScVbaNames::getElementType()
+{
+ return cppu::UnoType<ov::excel::XName>::get();
+}
+
+uno::Reference< container::XEnumeration >
+ScVbaNames::createEnumeration()
+{
+ uno::Reference< container::XEnumerationAccess > xEnumAccess( mxNames, uno::UNO_QUERY_THROW );
+ return new NamesEnumeration( getParent(), mxContext, xEnumAccess->createEnumeration(), mxModel , mxNames );
+}
+
+uno::Any
+ScVbaNames::createCollectionObject( const uno::Any& aSource )
+{
+ uno::Reference< sheet::XNamedRange > xName( aSource, uno::UNO_QUERY );
+ return uno::Any( uno::Reference< excel::XName > ( new ScVbaName( getParent(), mxContext, xName, mxNames , mxModel ) ) );
+}
+
+OUString
+ScVbaNames::getServiceImplName()
+{
+ return "ScVbaNames";
+}
+
+css::uno::Sequence<OUString>
+ScVbaNames::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.NamedRanges"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbanames.hxx b/sc/source/ui/vba/vbanames.hxx
new file mode 100644
index 000000000..96f03d435
--- /dev/null
+++ b/sc/source/ui/vba/vbanames.hxx
@@ -0,0 +1,69 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <ooo/vba/excel/XNames.hpp>
+#include <vbahelper/vbacollectionimpl.hxx>
+
+namespace com::sun::star::sheet { class XNamedRanges; }
+
+class ScDocument;
+
+typedef CollTestImplHelper< ov::excel::XNames > ScVbaNames_BASE;
+
+class ScVbaNames final : public ScVbaNames_BASE
+{
+ css::uno::Reference< css::frame::XModel > mxModel;
+ css::uno::Reference< css::sheet::XNamedRanges > mxNames;
+
+ const css::uno::Reference< css::frame::XModel >& getModel() const { return mxModel; }
+
+public:
+ ScVbaNames( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::sheet::XNamedRanges >& xNames , const css::uno::Reference< css::frame::XModel >& xModel );
+
+ ScDocument& getScDocument();
+
+ virtual ~ScVbaNames() override;
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+
+ // Methods
+ virtual css::uno::Any SAL_CALL Add( const css::uno::Any& aName ,
+ const css::uno::Any& aRefersTo,
+ const css::uno::Any& aVisible,
+ const css::uno::Any& aMacroType,
+ const css::uno::Any& aShoutcutKey,
+ const css::uno::Any& aCategory,
+ const css::uno::Any& aNameLocal,
+ const css::uno::Any& aRefersToLocal,
+ const css::uno::Any& aCategoryLocal,
+ const css::uno::Any& aRefersToR1C1,
+ const css::uno::Any& aRefersToR1C1Local ) override;
+
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+
+ // ScVbaNames_BASE
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaoleobject.cxx b/sc/source/ui/vba/vbaoleobject.cxx
new file mode 100644
index 000000000..f2cd5de40
--- /dev/null
+++ b/sc/source/ui/vba/vbaoleobject.cxx
@@ -0,0 +1,150 @@
+/* -*- 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/awt/XControlModel.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/lang/XMultiComponentFactory.hpp>
+#include <ooo/vba/XControlProvider.hpp>
+
+#include "vbaoleobject.hxx"
+
+using namespace com::sun::star;
+using namespace ooo::vba;
+
+ScVbaOLEObject::ScVbaOLEObject( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext,
+ css::uno::Reference< css::drawing::XControlShape > const & xControlShape )
+: OLEObjectImpl_BASE( xParent, xContext )
+{
+ //init m_xWindowPeer
+ uno::Reference< awt::XControlModel > xControlModel( xControlShape->getControl(), css::uno::UNO_SET_THROW );
+ uno::Reference< container::XChild > xChild( xControlModel, uno::UNO_QUERY_THROW );
+ xChild.set( xChild->getParent(), uno::UNO_QUERY_THROW );
+ xChild.set( xChild->getParent(), uno::UNO_QUERY_THROW );
+ uno::Reference<frame::XModel> xModel( xChild->getParent(), uno::UNO_QUERY_THROW );
+ uno::Reference<lang::XMultiComponentFactory > xServiceManager( mxContext->getServiceManager(), uno::UNO_SET_THROW );
+ uno::Reference< XControlProvider > xControlProvider( xServiceManager->createInstanceWithContext("ooo.vba.ControlProvider", mxContext ), uno::UNO_QUERY_THROW );
+ m_xControl.set( xControlProvider->createControl( xControlShape, xModel ) );
+}
+
+uno::Reference< uno::XInterface > SAL_CALL
+ScVbaOLEObject::getObject()
+{
+ return uno::Reference< uno::XInterface >( m_xControl, uno::UNO_QUERY_THROW );
+}
+
+sal_Bool SAL_CALL
+ScVbaOLEObject::getEnabled()
+{
+ return m_xControl->getEnabled();
+}
+
+void SAL_CALL
+ScVbaOLEObject::setEnabled( sal_Bool _enabled )
+{
+ m_xControl->setEnabled( _enabled );
+}
+
+sal_Bool SAL_CALL
+ScVbaOLEObject::getVisible()
+{
+ return m_xControl->getVisible();
+}
+
+void SAL_CALL
+ScVbaOLEObject::setVisible( sal_Bool _visible )
+{
+ m_xControl->setVisible( _visible );
+}
+
+double SAL_CALL
+ScVbaOLEObject::getLeft()
+{
+ return m_xControl->getLeft();
+}
+
+void SAL_CALL
+ScVbaOLEObject::setLeft( double _left )
+{
+ m_xControl->setLeft( _left );
+
+}
+
+double SAL_CALL
+ScVbaOLEObject::getTop()
+{
+ return m_xControl->getTop();
+}
+
+void SAL_CALL
+ScVbaOLEObject::setTop( double _top )
+{
+ m_xControl->setTop( _top );
+}
+
+double SAL_CALL
+ScVbaOLEObject::getHeight()
+{
+ return m_xControl->getHeight();
+}
+
+void SAL_CALL
+ScVbaOLEObject::setHeight( double _height )
+{
+ m_xControl->setHeight( _height );
+}
+
+double SAL_CALL
+ScVbaOLEObject::getWidth()
+{
+ return m_xControl->getWidth();
+}
+
+void SAL_CALL
+ScVbaOLEObject::setWidth( double _width )
+{
+ m_xControl->setWidth( _width );
+}
+
+OUString SAL_CALL ScVbaOLEObject::getLinkedCell()
+{
+ return m_xControl->getControlSource();
+}
+
+void SAL_CALL ScVbaOLEObject::setLinkedCell( const OUString& _linkedcell )
+{
+ m_xControl->setControlSource( _linkedcell );
+}
+
+OUString
+ScVbaOLEObject::getServiceImplName()
+{
+ return "ScVbaOLEObject";
+}
+
+uno::Sequence< OUString >
+ScVbaOLEObject::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.OLEObject"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaoleobject.hxx b/sc/source/ui/vba/vbaoleobject.hxx
new file mode 100644
index 000000000..9eecf5fdc
--- /dev/null
+++ b/sc/source/ui/vba/vbaoleobject.hxx
@@ -0,0 +1,57 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <com/sun/star/drawing/XControlShape.hpp>
+#include <ooo/vba/excel/XOLEObject.hpp>
+#include <ooo/vba/msforms/XControl.hpp>
+
+#include <vbahelper/vbahelperinterface.hxx>
+
+typedef InheritedHelperInterfaceWeakImpl< ov::excel::XOLEObject > OLEObjectImpl_BASE;
+
+class ScVbaOLEObject final : public OLEObjectImpl_BASE
+{
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+ css::uno::Reference< ov::msforms::XControl> m_xControl;
+public:
+ ScVbaOLEObject( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ css::uno::Reference< css::drawing::XControlShape > const & xControlShape );
+
+ // XOLEObject Attributes
+ virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getObject() override;
+ virtual sal_Bool SAL_CALL getEnabled() override;
+ virtual void SAL_CALL setEnabled( sal_Bool _enabled ) override;
+ virtual sal_Bool SAL_CALL getVisible() override;
+ virtual void SAL_CALL setVisible( sal_Bool _visible ) override;
+
+ virtual double SAL_CALL getLeft() override;
+ virtual void SAL_CALL setLeft( double _left ) override;
+ virtual double SAL_CALL getTop() override;
+ virtual void SAL_CALL setTop( double _top ) override;
+ virtual double SAL_CALL getHeight() override;
+ virtual void SAL_CALL setHeight( double _height ) override;
+ virtual double SAL_CALL getWidth() override;
+ virtual void SAL_CALL setWidth( double _width ) override;
+ virtual OUString SAL_CALL getLinkedCell() override;
+ virtual void SAL_CALL setLinkedCell( const OUString& _linkedcell ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaoleobjects.cxx b/sc/source/ui/vba/vbaoleobjects.cxx
new file mode 100644
index 000000000..11a8c3934
--- /dev/null
+++ b/sc/source/ui/vba/vbaoleobjects.cxx
@@ -0,0 +1,184 @@
+/* -*- 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/drawing/XControlShape.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <ooo/vba/excel/XOLEObject.hpp>
+
+#include "vbaoleobject.hxx"
+#include "vbaoleobjects.hxx"
+#include <cppuhelper/implbase.hxx>
+
+using namespace com::sun::star;
+using namespace ooo::vba;
+
+typedef ::cppu::WeakImplHelper< container::XIndexAccess > XIndexAccess_BASE;
+
+namespace {
+
+class IndexAccessWrapper : public XIndexAccess_BASE
+{
+typedef std::vector< uno::Reference< drawing::XControlShape > > OLEObjects;
+ OLEObjects vObjects;
+public:
+ explicit IndexAccessWrapper( const uno::Reference< container::XIndexAccess >& xIndexAccess )
+ {
+ sal_Int32 nLen = xIndexAccess->getCount();
+ for ( sal_Int32 index = 0; index < nLen; ++index )
+ {
+ uno::Reference< drawing::XControlShape > xControlShape( xIndexAccess->getByIndex( index), uno::UNO_QUERY);
+ if ( xControlShape.is() )
+ vObjects.push_back( xControlShape );
+ }
+ }
+
+ virtual ::sal_Int32 SAL_CALL getCount() override
+ {
+ return vObjects.size();
+ }
+
+ virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override
+ {
+ if ( Index < 0 || Index >= getCount() )
+ throw lang::IndexOutOfBoundsException();
+ return uno::Any( vObjects[ Index ] );
+ }
+
+ // Methods XElementAccess
+ virtual uno::Type SAL_CALL getElementType() override
+ {
+ return cppu::UnoType<drawing::XControlShape>::get();
+ }
+
+ virtual sal_Bool SAL_CALL hasElements() override
+ {
+ return ( getCount() > 0 );
+ }
+
+};
+
+class EnumWrapper : public EnumerationHelper_BASE
+{
+
+ uno::Reference<XHelperInterface > m_xParent;
+ uno::Reference<uno::XComponentContext > m_xContext;
+ uno::Reference<container::XIndexAccess > m_xIndexAccess;
+ sal_Int32 nIndex;
+public:
+ EnumWrapper( const uno::Reference< XHelperInterface >& xParent,
+ const uno::Reference< uno::XComponentContext >& xContext,
+ const uno::Reference< container::XIndexAccess >& xIndexAccess )
+ : m_xParent( xParent ), m_xContext( xContext), m_xIndexAccess( xIndexAccess ), nIndex( 0 ) {}
+
+ virtual sal_Bool SAL_CALL hasMoreElements( ) override
+ {
+ return ( nIndex < m_xIndexAccess->getCount() );
+ }
+
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ if ( nIndex < m_xIndexAccess->getCount() )
+ {
+ uno::Reference< drawing::XControlShape > xControlShape ( m_xIndexAccess->getByIndex( nIndex++ ), uno::UNO_QUERY_THROW );
+ return uno::Any( uno::Reference< ov::excel::XOLEObject >( new ScVbaOLEObject( m_xParent, m_xContext, xControlShape ) ) );
+ }
+ throw container::NoSuchElementException();
+ }
+};
+
+uno::Reference< container::XIndexAccess > oleObjectIndexWrapper( const uno::Reference< container::XIndexAccess >& xIndexAccess )
+{
+ return new IndexAccessWrapper( xIndexAccess );
+}
+
+}
+
+ScVbaOLEObjects::ScVbaOLEObjects( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext,
+ const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess )
+ : OLEObjectsImpl_BASE( xParent, xContext, oleObjectIndexWrapper( xIndexAccess ) )
+{
+}
+uno::Reference< container::XEnumeration >
+ScVbaOLEObjects::createEnumeration()
+{
+ return new EnumWrapper( getParent(), mxContext, m_xIndexAccess );
+}
+
+uno::Any
+ScVbaOLEObjects::createCollectionObject( const css::uno::Any& aSource )
+{
+ if( aSource.hasValue() )
+ {
+ uno::Reference< drawing::XControlShape > xControlShape( aSource, uno::UNO_QUERY_THROW );
+ // parent of OLEObject is the same parent as the collection ( e.g. the sheet )
+ return uno::Any( uno::Reference< ov::excel::XOLEObject >( new ScVbaOLEObject( getParent(), mxContext, xControlShape ) ) );
+ }
+ return uno::Any();
+}
+
+uno::Any
+ScVbaOLEObjects::getItemByStringIndex( const OUString& sIndex )
+{
+ try
+ {
+ return OLEObjectsImpl_BASE::getItemByStringIndex( sIndex );
+ }
+ catch (const uno::RuntimeException&)
+ {
+ uno::Reference< container::XIndexAccess > xIndexAccess( m_xIndexAccess, uno::UNO_SET_THROW );
+ sal_Int32 nCount = xIndexAccess->getCount();
+ for( int index = 0; index < nCount; index++ )
+ {
+ uno::Any aUnoObj = xIndexAccess->getByIndex( index );
+ uno::Reference< drawing::XControlShape > xControlShape( aUnoObj, uno::UNO_QUERY_THROW );
+ uno::Reference< awt::XControlModel > xControlModel( xControlShape->getControl() );
+ uno::Reference< container::XNamed > xNamed( xControlModel, uno::UNO_QUERY_THROW );
+ if( sIndex == xNamed->getName() )
+ {
+ return createCollectionObject( aUnoObj );
+ }
+
+ }
+ return uno::Any();
+ }
+}
+
+uno::Type
+ScVbaOLEObjects::getElementType()
+{
+ return cppu::UnoType<ooo::vba::excel::XOLEObject>::get();
+}
+
+OUString
+ScVbaOLEObjects::getServiceImplName()
+{
+ return "ScVbaOLEObjects";
+}
+
+uno::Sequence< OUString >
+ScVbaOLEObjects::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.OLEObjects"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaoleobjects.hxx b/sc/source/ui/vba/vbaoleobjects.hxx
new file mode 100644
index 000000000..9d4eab048
--- /dev/null
+++ b/sc/source/ui/vba/vbaoleobjects.hxx
@@ -0,0 +1,47 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <ooo/vba/excel/XOLEObjects.hpp>
+
+#include <vbahelper/vbacollectionimpl.hxx>
+
+typedef CollTestImplHelper<ov::excel::XOLEObjects> OLEObjectsImpl_BASE;
+
+class ScVbaOLEObjects : public OLEObjectsImpl_BASE
+{
+protected:
+ virtual css::uno::Any getItemByStringIndex(const OUString& sIndex) override;
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+
+public:
+ ScVbaOLEObjects(const css::uno::Reference<ov::XHelperInterface>& xParent,
+ const css::uno::Reference<css::uno::XComponentContext>& xContext,
+ const css::uno::Reference<css::container::XIndexAccess>& xIndexAccess);
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference<css::container::XEnumeration> SAL_CALL createEnumeration() override;
+
+ // ScVbaCollectionBaseImpl
+ virtual css::uno::Any createCollectionObject(const css::uno::Any& aSource) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaoutline.cxx b/sc/source/ui/vba/vbaoutline.cxx
new file mode 100644
index 000000000..60bc12921
--- /dev/null
+++ b/sc/source/ui/vba/vbaoutline.cxx
@@ -0,0 +1,58 @@
+/* -*- 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 "vbaoutline.hxx"
+#include <com/sun/star/sheet/XSheetOutline.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+void
+ScVbaOutline::ShowLevels( const uno::Any& RowLevels, const uno::Any& ColumnLevels )
+{
+ if (mxOutline.is())
+ {
+ sal_Int16 nLevel = 0;
+ if (RowLevels >>= nLevel)
+ {
+ mxOutline->showLevel(nLevel, table::TableOrientation_ROWS);
+ }
+ if (ColumnLevels >>= nLevel)
+ {
+ mxOutline->showLevel(nLevel,table::TableOrientation_COLUMNS);
+ }
+ }
+}
+
+OUString
+ScVbaOutline::getServiceImplName()
+{
+ return "ScVbaOutline";
+}
+
+uno::Sequence< OUString >
+ScVbaOutline::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.Outline"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaoutline.hxx b/sc/source/ui/vba/vbaoutline.hxx
new file mode 100644
index 000000000..4554083e9
--- /dev/null
+++ b/sc/source/ui/vba/vbaoutline.hxx
@@ -0,0 +1,43 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <ooo/vba/excel/XOutline.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+
+namespace com::sun::star::uno { class XComponentContext; }
+namespace com::sun::star::sheet { class XSheetOutline; }
+
+typedef InheritedHelperInterfaceWeakImpl< ov::excel::XOutline > ScVbaOutline_BASE;
+
+class ScVbaOutline : public ScVbaOutline_BASE
+{
+ css::uno::Reference< css::sheet::XSheetOutline > mxOutline;
+public:
+ ScVbaOutline( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ css::uno::Reference<css::sheet::XSheetOutline> const & outline): ScVbaOutline_BASE( xParent, xContext) , mxOutline(outline)
+ {}
+
+ virtual void SAL_CALL ShowLevels( const css::uno::Any& RowLevels, const css::uno::Any& ColumnLevels ) override ;
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaovalshape.cxx b/sc/source/ui/vba/vbaovalshape.cxx
new file mode 100644
index 000000000..8efc877ee
--- /dev/null
+++ b/sc/source/ui/vba/vbaovalshape.cxx
@@ -0,0 +1,34 @@
+/* -*- 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 "vbaovalshape.hxx"
+
+using namespace com::sun::star;
+using namespace ooo::vba;
+
+/*
+ * This is implemented as a new class in order to provide XTypeProvider
+ * interface. This is needed by TypeOf ... Is ... basic operator.
+ */
+
+ScVbaOvalShape::ScVbaOvalShape( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< drawing::XShape >& xShape, const uno::Reference< drawing::XShapes >& xShapes, const uno::Reference< frame::XModel >& xModel ) : OvalShapeImpl_BASE( uno::Reference< XHelperInterface >(), xContext, xShape, xShapes, xModel, ScVbaShape::getType( xShape ) )
+{}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaovalshape.hxx b/sc/source/ui/vba/vbaovalshape.hxx
new file mode 100644
index 000000000..1155cd1fc
--- /dev/null
+++ b/sc/source/ui/vba/vbaovalshape.hxx
@@ -0,0 +1,34 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <ooo/vba/msforms/XOval.hpp>
+#include <cppuhelper/implbase.hxx>
+#include <vbahelper/vbashape.hxx>
+
+typedef cppu::ImplInheritanceHelper< ScVbaShape, ov::msforms::XOval > OvalShapeImpl_BASE;
+
+class ScVbaOvalShape : public OvalShapeImpl_BASE
+{
+public:
+ ScVbaOvalShape( const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::drawing::XShape >& xShape, const css::uno::Reference< css::drawing::XShapes >& xShapes, const css::uno::Reference< css::frame::XModel >& xModel );
+
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbapagebreak.cxx b/sc/source/ui/vba/vbapagebreak.cxx
new file mode 100644
index 000000000..3d9269c72
--- /dev/null
+++ b/sc/source/ui/vba/vbapagebreak.cxx
@@ -0,0 +1,142 @@
+/* -*- 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 "vbapagebreak.hxx"
+#include "vbarange.hxx"
+#include <basic/sberrors.hxx>
+#include <ooo/vba/excel/XlPageBreak.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+template< typename... Ifc >
+ScVbaPageBreak< Ifc... >::ScVbaPageBreak( const uno::Reference< XHelperInterface >& xParent,
+ const uno::Reference< uno::XComponentContext >& xContext,
+ const uno::Reference< beans::XPropertySet >& xProps,
+ sheet::TablePageBreakData aTablePageBreakData):
+ ScVbaPageBreak_BASE( xParent, xContext ),
+ mxRowColPropertySet( xProps ),
+ maTablePageBreakData( aTablePageBreakData )
+{
+}
+
+template< typename... Ifc >
+sal_Int32 ScVbaPageBreak< Ifc... >::getType()
+{
+ uno::Any aValue = mxRowColPropertySet->getPropertyValue("IsStartOfNewPage");
+ bool hasPageBreak = false;
+ aValue >>= hasPageBreak;
+
+ if( !hasPageBreak )
+ return excel::XlPageBreak::xlPageBreakNone;
+
+ if( maTablePageBreakData.ManualBreak )
+ return excel::XlPageBreak::xlPageBreakManual;
+
+ return excel::XlPageBreak::xlPageBreakAutomatic;
+}
+
+template< typename... Ifc >
+void ScVbaPageBreak< Ifc... >::setType(sal_Int32 type)
+{
+ if( (type != excel::XlPageBreak::xlPageBreakNone) &&
+ (type != excel::XlPageBreak::xlPageBreakManual) &&
+ (type != excel::XlPageBreak::xlPageBreakAutomatic) )
+ {
+ DebugHelper::runtimeexception(ERRCODE_BASIC_BAD_PARAMETER);
+ }
+
+ if( type == excel::XlPageBreak::xlPageBreakNone )
+ {
+ mxRowColPropertySet->setPropertyValue("IsStartOfNewPage", uno::Any(false));
+ return;
+ }
+
+ mxRowColPropertySet->setPropertyValue("IsStartOfNewPage", uno::Any(true));
+ if( type == excel::XlPageBreak::xlPageBreakManual )
+ maTablePageBreakData.ManualBreak = true;
+ else
+ maTablePageBreakData.ManualBreak = false;
+}
+
+template< typename... Ifc >
+void ScVbaPageBreak< Ifc... >::Delete()
+{
+ mxRowColPropertySet->setPropertyValue("IsStartOfNewPage", uno::Any(false));
+}
+
+template< typename... Ifc >
+uno::Reference< excel::XRange> ScVbaPageBreak< Ifc... >::Location()
+{
+ uno::Reference< table::XCellRange > xRange( mxRowColPropertySet, uno::UNO_QUERY_THROW );
+ return new ScVbaRange( ScVbaPageBreak_BASE::getParent(), ScVbaPageBreak_BASE::mxContext, xRange);
+}
+
+template class ScVbaPageBreak< excel::XHPageBreak >;
+
+/* class ScVbaHPageBreak */
+OUString
+ScVbaHPageBreak::getServiceImplName()
+{
+ return "ScVbaHPageBreak";
+}
+
+uno::Sequence< OUString >
+ScVbaHPageBreak::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.HPageBreak"
+ };
+ return aServiceNames;
+}
+
+template class ScVbaPageBreak< excel::XVPageBreak >;
+
+/* class ScVbaVPageBreak */
+ScVbaVPageBreak::ScVbaVPageBreak( const css::uno::Reference< ov::XHelperInterface >& xParent,
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ const css::uno::Reference< css::beans::XPropertySet >& xProps,
+ css::sheet::TablePageBreakData aTablePageBreakData )
+: ScVbaVPageBreak_BASE( xParent, xContext, xProps, aTablePageBreakData )
+{
+}
+
+ScVbaVPageBreak::~ScVbaVPageBreak()
+{
+}
+
+OUString
+ScVbaVPageBreak::getServiceImplName()
+{
+ return "ScVbaVPageBreak";
+}
+
+uno::Sequence< OUString >
+ScVbaVPageBreak::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.VPageBreak"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbapagebreak.hxx b/sc/source/ui/vba/vbapagebreak.hxx
new file mode 100644
index 000000000..537258923
--- /dev/null
+++ b/sc/source/ui/vba/vbapagebreak.hxx
@@ -0,0 +1,87 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <ooo/vba/excel/XHPageBreak.hpp>
+#include <ooo/vba/excel/XVPageBreak.hpp>
+#include <com/sun/star/sheet/TablePageBreakData.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+
+namespace com::sun::star::beans { class XPropertySet; }
+namespace com::sun::star::uno { class XComponentContext; }
+namespace ooo::vba::excel { class XRange; }
+
+template< typename... Ifc >
+class ScVbaPageBreak : public InheritedHelperInterfaceWeakImpl< Ifc... >
+{
+typedef InheritedHelperInterfaceWeakImpl< Ifc... > ScVbaPageBreak_BASE;
+protected:
+ css::uno::Reference< css::beans::XPropertySet > mxRowColPropertySet;
+ css::sheet::TablePageBreakData maTablePageBreakData;
+public:
+ /// @throws css::uno::RuntimeException
+ ScVbaPageBreak( const css::uno::Reference< ov::XHelperInterface >& xParent,
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ const css::uno::Reference< css::beans::XPropertySet >& xProps,
+ css::sheet::TablePageBreakData aTablePageBreakData);
+
+ virtual sal_Int32 SAL_CALL getType( ) override;
+ virtual void SAL_CALL setType(sal_Int32 type) override;
+
+ virtual void SAL_CALL Delete() override;
+ virtual css::uno::Reference< ov::excel::XRange> SAL_CALL Location() override;
+};
+
+typedef ScVbaPageBreak < ov::excel::XHPageBreak > ScVbaHPageBreak_BASE;
+
+class ScVbaHPageBreak : public ScVbaHPageBreak_BASE
+{
+public:
+ /// @throws css::uno::RuntimeException
+ ScVbaHPageBreak( const css::uno::Reference< ov::XHelperInterface >& xParent,
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ const css::uno::Reference< css::beans::XPropertySet >& xProps,
+ css::sheet::TablePageBreakData aTablePageBreakData):
+ ScVbaHPageBreak_BASE( xParent,xContext,xProps,aTablePageBreakData ){}
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+//VPageBreak
+typedef ScVbaPageBreak < ov::excel::XVPageBreak > ScVbaVPageBreak_BASE;
+
+class ScVbaVPageBreak : public ScVbaVPageBreak_BASE
+{
+public:
+ /// @throws css::uno::RuntimeException
+ ScVbaVPageBreak( const css::uno::Reference< ov::XHelperInterface >& xParent,
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ const css::uno::Reference< css::beans::XPropertySet >& xProps,
+ css::sheet::TablePageBreakData aTablePageBreakData);
+
+ virtual ~ScVbaVPageBreak() override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbapagebreaks.cxx b/sc/source/ui/vba/vbapagebreaks.cxx
new file mode 100644
index 000000000..36d9f5c7f
--- /dev/null
+++ b/sc/source/ui/vba/vbapagebreaks.cxx
@@ -0,0 +1,322 @@
+/* -*- 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 "vbapagebreaks.hxx"
+#include "vbapagebreak.hxx"
+#include <basic/sberrors.hxx>
+#include <cppuhelper/implbase.hxx>
+#include <ooo/vba/excel/XWorksheet.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sheet/XSheetPageBreak.hpp>
+#include <com/sun/star/table/XColumnRowRange.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+namespace {
+
+class RangePageBreaks : public ::cppu::WeakImplHelper<container::XIndexAccess >
+{
+private:
+ uno::Reference< XHelperInterface > mxParent;
+ uno::Reference< uno::XComponentContext > mxContext;
+ uno::Reference< sheet::XSheetPageBreak > mxSheetPageBreak;
+ bool m_bColumn;
+
+public:
+ RangePageBreaks( const uno::Reference< XHelperInterface >& xParent,
+ const uno::Reference< uno::XComponentContext >& xContext,
+ const uno::Reference< sheet::XSheetPageBreak >& xSheetPageBreak,
+ bool bColumn ) : mxParent( xParent ), mxContext( xContext ), mxSheetPageBreak( xSheetPageBreak ), m_bColumn( bColumn )
+ {
+ }
+
+ /// @throws css::uno::RuntimeException
+ sal_Int32 getAPIStartofRange( const uno::Reference< excel::XRange >& xRange )
+ {
+ if( m_bColumn )
+ return xRange->getColumn() - 1;
+ return xRange->getRow() - 1;
+ }
+
+ /// @throws uno::RuntimeException
+ sal_Int32 getAPIEndIndexofRange( const uno::Reference< excel::XRange >& xRange, sal_Int32 nUsedStart )
+ {
+ if( m_bColumn )
+ return nUsedStart + xRange->Columns( uno::Any() )->getCount() - 1;
+ return nUsedStart + xRange->Rows( uno::Any() )->getCount();
+ }
+
+ /// @throws uno::RuntimeException
+ uno::Sequence<sheet::TablePageBreakData> getAllPageBreaks()
+ {
+ if( m_bColumn )
+ return mxSheetPageBreak->getColumnPageBreaks();
+ return mxSheetPageBreak->getRowPageBreaks();
+ }
+
+ /// @throws uno::RuntimeException
+ uno::Reference<container::XIndexAccess> getRowColContainer() const
+ {
+ uno::Reference< table::XColumnRowRange > xColumnRowRange( mxSheetPageBreak, uno::UNO_QUERY_THROW );
+ uno::Reference<container::XIndexAccess> xIndexAccess;
+ if( m_bColumn )
+ xIndexAccess.set( xColumnRowRange->getColumns(), uno::UNO_QUERY_THROW );
+ else
+ xIndexAccess.set( xColumnRowRange->getRows(), uno::UNO_QUERY_THROW );
+ return xIndexAccess;
+ }
+
+ /// @throws uno::RuntimeException
+ sheet::TablePageBreakData getTablePageBreakData( sal_Int32 nAPIItemIndex );
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ uno::Any Add( const css::uno::Any& Before );
+
+ // XIndexAccess
+ virtual sal_Int32 SAL_CALL getCount( ) override;
+ virtual uno::Any SAL_CALL getByIndex( sal_Int32 Index ) override;
+ virtual uno::Type SAL_CALL getElementType( ) override
+ {
+ if( m_bColumn )
+ return cppu::UnoType<excel::XVPageBreak>::get();
+ return cppu::UnoType<excel::XHPageBreak>::get();
+ }
+ virtual sal_Bool SAL_CALL hasElements( ) override
+ {
+ return true;
+ }
+};
+
+}
+
+/** @TODO Unlike MS Excel this method only considers the pagebreaks that intersect the used range
+* To become completely compatible the print area has to be considered. As far as I found out this printarea
+* also considers the position and sizes of shapes and manually inserted page breaks
+* Note: In MS there is a limit of 1026 horizontal page breaks per sheet.
+*/
+sal_Int32 SAL_CALL RangePageBreaks::getCount( )
+{
+ uno::Reference< excel::XWorksheet > xWorksheet( mxParent, uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XRange > xRange = xWorksheet->getUsedRange();
+ sal_Int32 nUsedStart = getAPIStartofRange( xRange );
+ sal_Int32 nUsedEnd = getAPIEndIndexofRange( xRange, nUsedStart );
+ const uno::Sequence<sheet::TablePageBreakData> aTablePageBreakData = getAllPageBreaks();
+
+ auto pPageBreak = std::find_if(aTablePageBreakData.begin(), aTablePageBreakData.end(),
+ [nUsedEnd](const sheet::TablePageBreakData& rPageBreak) { return rPageBreak.Position > nUsedEnd + 1; });
+
+ return static_cast<sal_Int32>(std::distance(aTablePageBreakData.begin(), pPageBreak));
+}
+
+uno::Any SAL_CALL RangePageBreaks::getByIndex( sal_Int32 Index )
+{
+ if( (Index < getCount()) && ( Index >= 0 ))
+ {
+ sheet::TablePageBreakData aTablePageBreakData = getTablePageBreakData( Index );
+ uno::Reference< container::XIndexAccess > xIndexAccess = getRowColContainer();
+ sal_Int32 nPos = aTablePageBreakData.Position;
+ if( (nPos < xIndexAccess->getCount()) && (nPos > -1) )
+ {
+ uno::Reference< beans::XPropertySet > xRowColPropertySet( xIndexAccess->getByIndex(nPos), uno::UNO_QUERY_THROW );
+ if( m_bColumn )
+ return uno::Any( uno::Reference< excel::XVPageBreak >( new ScVbaVPageBreak( mxParent, mxContext, xRowColPropertySet, aTablePageBreakData) ));
+ return uno::Any( uno::Reference< excel::XHPageBreak >( new ScVbaHPageBreak( mxParent, mxContext, xRowColPropertySet, aTablePageBreakData) ));
+ }
+ }
+ throw lang::IndexOutOfBoundsException();
+}
+
+sheet::TablePageBreakData RangePageBreaks::getTablePageBreakData( sal_Int32 nAPIItemIndex )
+{
+ sal_Int32 index = -1;
+ sheet::TablePageBreakData aTablePageBreakData;
+ uno::Reference< excel::XWorksheet > xWorksheet( mxParent, uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XRange > xRange = xWorksheet->getUsedRange();
+ sal_Int32 nUsedStart = getAPIStartofRange( xRange );
+ sal_Int32 nUsedEnd = getAPIEndIndexofRange( xRange, nUsedStart );
+ const uno::Sequence<sheet::TablePageBreakData> aTablePageBreakDataList = getAllPageBreaks();
+
+ for( const auto& rTablePageBreakData : aTablePageBreakDataList )
+ {
+ aTablePageBreakData = rTablePageBreakData;
+ sal_Int32 nPos = aTablePageBreakData.Position;
+ if( nPos > nUsedEnd + 1 )
+ DebugHelper::runtimeexception(ERRCODE_BASIC_METHOD_FAILED);
+ index++;
+ if( index == nAPIItemIndex )
+ return aTablePageBreakData;
+ }
+
+ return aTablePageBreakData;
+}
+
+uno::Any RangePageBreaks::Add( const css::uno::Any& Before )
+{
+ uno::Reference< excel::XRange > xRange;
+ Before >>= xRange;
+ if( !xRange.is() )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_BAD_ARGUMENT, {});
+ }
+
+ sal_Int32 nAPIRowColIndex = getAPIStartofRange( xRange );
+ uno::Reference< container::XIndexAccess > xIndexAccess = getRowColContainer();
+ uno::Reference< beans::XPropertySet > xRowColPropertySet( xIndexAccess->getByIndex(nAPIRowColIndex), uno::UNO_QUERY_THROW );
+ xRowColPropertySet->setPropertyValue("IsStartOfNewPage", uno::Any(true));
+ sheet::TablePageBreakData aTablePageBreakData;
+ aTablePageBreakData.ManualBreak = true;
+ aTablePageBreakData.Position = nAPIRowColIndex;
+ if( m_bColumn )
+ return uno::Any( uno::Reference< excel::XVPageBreak >( new ScVbaVPageBreak( mxParent, mxContext, xRowColPropertySet, aTablePageBreakData) ));
+ return uno::Any( uno::Reference< excel::XHPageBreak >( new ScVbaHPageBreak( mxParent, mxContext, xRowColPropertySet, aTablePageBreakData) ));
+}
+
+namespace {
+
+class RangePageBreaksEnumWrapper : public EnumerationHelper_BASE
+{
+ uno::Reference<container::XIndexAccess > m_xIndexAccess;
+ sal_Int32 nIndex;
+public:
+ explicit RangePageBreaksEnumWrapper( const uno::Reference< container::XIndexAccess >& xIndexAccess ) : m_xIndexAccess( xIndexAccess ), nIndex( 0 ) {}
+ virtual sal_Bool SAL_CALL hasMoreElements( ) override
+ {
+ return ( nIndex < m_xIndexAccess->getCount() );
+ }
+
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ if ( nIndex < m_xIndexAccess->getCount() )
+ return m_xIndexAccess->getByIndex( nIndex++ );
+ throw container::NoSuchElementException();
+ }
+};
+
+}
+
+ScVbaHPageBreaks::ScVbaHPageBreaks( const uno::Reference< XHelperInterface >& xParent,
+ const uno::Reference< uno::XComponentContext >& xContext,
+ const uno::Reference< sheet::XSheetPageBreak >& xSheetPageBreak):
+ ScVbaHPageBreaks_BASE( xParent,xContext, new RangePageBreaks( xParent, xContext, xSheetPageBreak, false ))
+{
+}
+
+uno::Any SAL_CALL ScVbaHPageBreaks::Add( const uno::Any& Before)
+{
+ RangePageBreaks* pPageBreaks = dynamic_cast< RangePageBreaks* >( m_xIndexAccess.get() );
+ if( pPageBreaks )
+ {
+ return pPageBreaks->Add( Before );
+ }
+ return uno::Any();
+}
+
+uno::Reference< container::XEnumeration >
+ScVbaHPageBreaks::createEnumeration()
+{
+ return new RangePageBreaksEnumWrapper( m_xIndexAccess );
+}
+
+uno::Any
+ScVbaHPageBreaks::createCollectionObject( const css::uno::Any& aSource )
+{
+ return aSource; // it's already a pagebreak object
+}
+
+uno::Type
+ScVbaHPageBreaks::getElementType()
+{
+ return cppu::UnoType<excel::XHPageBreak>::get();
+}
+
+OUString
+ScVbaHPageBreaks::getServiceImplName()
+{
+ return "ScVbaHPageBreaks";
+}
+
+uno::Sequence< OUString >
+ScVbaHPageBreaks::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.HPageBreaks"
+ };
+ return aServiceNames;
+}
+
+//VPageBreak
+ScVbaVPageBreaks::ScVbaVPageBreaks( const uno::Reference< XHelperInterface >& xParent,
+ const uno::Reference< uno::XComponentContext >& xContext,
+ const uno::Reference< sheet::XSheetPageBreak >& xSheetPageBreak )
+: ScVbaVPageBreaks_BASE( xParent, xContext, new RangePageBreaks( xParent, xContext, xSheetPageBreak, true ) )
+{
+}
+
+ScVbaVPageBreaks::~ScVbaVPageBreaks()
+{
+}
+
+uno::Any SAL_CALL
+ScVbaVPageBreaks::Add( const uno::Any& Before )
+{
+ RangePageBreaks* pPageBreaks = dynamic_cast< RangePageBreaks* >( m_xIndexAccess.get() );
+ if( pPageBreaks )
+ {
+ return pPageBreaks->Add( Before );
+ }
+ return uno::Any();
+}
+
+uno::Reference< container::XEnumeration >
+ScVbaVPageBreaks::createEnumeration()
+{
+ return new RangePageBreaksEnumWrapper( m_xIndexAccess );
+}
+
+uno::Any
+ScVbaVPageBreaks::createCollectionObject( const css::uno::Any& aSource )
+{
+ return aSource; // it's already a pagebreak object
+}
+
+uno::Type
+ScVbaVPageBreaks::getElementType()
+{
+ return cppu::UnoType<excel::XVPageBreak>::get();
+}
+
+OUString
+ScVbaVPageBreaks::getServiceImplName()
+{
+ return "ScVbaVPageBreaks";
+}
+
+uno::Sequence< OUString >
+ScVbaVPageBreaks::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.VPageBreaks"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbapagebreaks.hxx b/sc/source/ui/vba/vbapagebreaks.hxx
new file mode 100644
index 000000000..a04f94145
--- /dev/null
+++ b/sc/source/ui/vba/vbapagebreaks.hxx
@@ -0,0 +1,83 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <ooo/vba/excel/XHPageBreaks.hpp>
+#include <ooo/vba/excel/XVPageBreaks.hpp>
+#include <vbahelper/vbacollectionimpl.hxx>
+
+namespace com::sun::star::sheet
+{
+class XSheetPageBreak;
+}
+namespace com::sun::star::uno
+{
+class XComponentContext;
+}
+
+typedef CollTestImplHelper<ov::excel::XHPageBreaks> ScVbaHPageBreaks_BASE;
+
+class ScVbaHPageBreaks : public ScVbaHPageBreaks_BASE
+{
+public:
+ /// @throws css::uno::RuntimeException
+ ScVbaHPageBreaks(const css::uno::Reference<ov::XHelperInterface>& xParent,
+ const css::uno::Reference<css::uno::XComponentContext>& xContext,
+ const css::uno::Reference<css::sheet::XSheetPageBreak>& xSheetPageBreak);
+
+ // XHPageBreaks
+ virtual css::uno::Any SAL_CALL Add(const css::uno::Any& Before) override;
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference<css::container::XEnumeration> SAL_CALL createEnumeration() override;
+ virtual css::uno::Any createCollectionObject(const css::uno::Any&) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+//VPageBreaks
+typedef CollTestImplHelper<ov::excel::XVPageBreaks> ScVbaVPageBreaks_BASE;
+
+class ScVbaVPageBreaks : public ScVbaVPageBreaks_BASE
+{
+public:
+ /// @throws css::uno::RuntimeException
+ ScVbaVPageBreaks(const css::uno::Reference<ov::XHelperInterface>& xParent,
+ const css::uno::Reference<css::uno::XComponentContext>& xContext,
+ const css::uno::Reference<css::sheet::XSheetPageBreak>& xSheetPageBreak);
+
+ virtual ~ScVbaVPageBreaks() override;
+
+ // XVPageBreaks
+ virtual css::uno::Any SAL_CALL Add(const css::uno::Any& Before) override;
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference<css::container::XEnumeration> SAL_CALL createEnumeration() override;
+ virtual css::uno::Any createCollectionObject(const css::uno::Any&) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbapagesetup.cxx b/sc/source/ui/vba/vbapagesetup.cxx
new file mode 100644
index 000000000..7b7b23d16
--- /dev/null
+++ b/sc/source/ui/vba/vbapagesetup.cxx
@@ -0,0 +1,631 @@
+/* -*- 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 "vbapagesetup.hxx"
+#include <convuno.hxx>
+#include <rangelst.hxx>
+#include <docsh.hxx>
+#include "excelvbahelper.hxx"
+#include "vbarange.hxx"
+#include <com/sun/star/sheet/XPrintAreas.hpp>
+#include <com/sun/star/sheet/XHeaderFooterContent.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <ooo/vba/excel/XlPageOrientation.hpp>
+#include <ooo/vba/excel/XlOrder.hpp>
+#include <ooo/vba/excel/Constants.hpp>
+#include <ooo/vba/excel/XlPaperSize.hpp>
+#include <basic/sberrors.hxx>
+#include <filter/msfilter/util.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+#define ZOOM_IN 10
+#define ZOOM_MAX 400
+
+ScVbaPageSetup::ScVbaPageSetup(const uno::Reference< XHelperInterface >& xParent,
+ const uno::Reference< uno::XComponentContext >& xContext,
+ const uno::Reference< sheet::XSpreadsheet >& xSheet,
+ const uno::Reference< frame::XModel >& xModel):
+ ScVbaPageSetup_BASE( xParent, xContext ), mxSheet( xSheet ), mbIsLandscape( false )
+{
+ // query for current page style
+ mxModel.set( xModel, uno::UNO_SET_THROW );
+ uno::Reference< beans::XPropertySet > xSheetProps( mxSheet, uno::UNO_QUERY_THROW );
+ uno::Any aValue = xSheetProps->getPropertyValue("PageStyle");
+ OUString aStyleName;
+ aValue >>= aStyleName;
+
+ uno::Reference< style::XStyleFamiliesSupplier > xStyleFamiliesSup( mxModel, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XNameAccess > xStyleFamilies = xStyleFamiliesSup->getStyleFamilies();
+ uno::Reference< container::XNameAccess > xPageStyle( xStyleFamilies->getByName("PageStyles"), uno::UNO_QUERY_THROW );
+ mxPageProps.set( xPageStyle->getByName(aStyleName), uno::UNO_QUERY_THROW );
+ mnOrientLandscape = excel::XlPageOrientation::xlLandscape;
+ mnOrientPortrait = excel::XlPageOrientation::xlPortrait;
+ mxPageProps->getPropertyValue("IsLandscape") >>= mbIsLandscape;
+}
+
+OUString SAL_CALL ScVbaPageSetup::getPrintArea()
+{
+ OUString aPrintArea;
+ uno::Reference< sheet::XPrintAreas > xPrintAreas( mxSheet, uno::UNO_QUERY_THROW );
+ const uno::Sequence< table::CellRangeAddress > aSeq = xPrintAreas->getPrintAreas();
+ if( aSeq.hasElements() )
+ {
+ ScRangeList aRangeList;
+ for( const auto& rRange : aSeq )
+ {
+ ScRange aRange;
+ ScUnoConversion::FillScRange( aRange, rRange );
+ aRangeList.push_back( aRange );
+ }
+ ScDocument& rDoc = excel::getDocShell( mxModel )->GetDocument();
+ aRangeList.Format( aPrintArea, ScRefFlags::RANGE_ABS, rDoc, formula::FormulaGrammar::CONV_XL_A1, ',' );
+ }
+
+ return aPrintArea;
+}
+
+void SAL_CALL ScVbaPageSetup::setPrintArea( const OUString& rAreas )
+{
+ uno::Reference< sheet::XPrintAreas > xPrintAreas( mxSheet, uno::UNO_QUERY_THROW );
+ if( rAreas.isEmpty() ||
+ rAreas.equalsIgnoreAsciiCase( "FALSE" ) )
+ {
+ // print the whole sheet
+ uno::Sequence< table::CellRangeAddress > aSeq;
+ xPrintAreas->setPrintAreas( aSeq );
+ }
+ else
+ {
+ ScRangeList aCellRanges;
+ ScRange aRange;
+ if( getScRangeListForAddress( rAreas, excel::getDocShell( mxModel ) , aRange, aCellRanges ) )
+ {
+ uno::Sequence< table::CellRangeAddress > aSeq( aCellRanges.size() );
+ auto aSeqRange = asNonConstRange(aSeq);
+ for ( size_t i = 0, nRanges = aCellRanges.size(); i < nRanges; ++i )
+ {
+ ScRange & rRange = aCellRanges[ i ];
+ table::CellRangeAddress aRangeAddress;
+ ScUnoConversion::FillApiRange( aRangeAddress, rRange );
+ aSeqRange[ i++ ] = aRangeAddress;
+ }
+ xPrintAreas->setPrintAreas( aSeq );
+ }
+ }
+}
+
+double SAL_CALL ScVbaPageSetup::getHeaderMargin()
+{
+ return VbaPageSetupBase::getHeaderMargin();
+}
+
+void SAL_CALL ScVbaPageSetup::setHeaderMargin( double margin )
+{
+ VbaPageSetupBase::setHeaderMargin( margin );
+}
+
+double SAL_CALL ScVbaPageSetup::getFooterMargin()
+{
+ return VbaPageSetupBase::getFooterMargin();
+}
+
+void SAL_CALL ScVbaPageSetup::setFooterMargin( double margin )
+{
+ VbaPageSetupBase::setFooterMargin( margin );
+}
+
+uno::Any SAL_CALL ScVbaPageSetup::getFitToPagesTall()
+{
+ return mxPageProps->getPropertyValue("ScaleToPagesY");
+}
+
+void SAL_CALL ScVbaPageSetup::setFitToPagesTall( const uno::Any& fitToPagesTall)
+{
+ try
+ {
+ sal_uInt16 scaleToPageY = 0;
+ bool aValue;
+ if( fitToPagesTall.getValueTypeClass() != uno::TypeClass_BOOLEAN || (fitToPagesTall >>= aValue))
+ {
+ fitToPagesTall >>= scaleToPageY;
+ }
+
+ mxPageProps->setPropertyValue("ScaleToPagesY", uno::Any( scaleToPageY ));
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+uno::Any SAL_CALL ScVbaPageSetup::getFitToPagesWide()
+{
+ return mxPageProps->getPropertyValue("ScaleToPagesX");
+}
+
+void SAL_CALL ScVbaPageSetup::setFitToPagesWide( const uno::Any& fitToPagesWide)
+{
+ try
+ {
+ sal_uInt16 scaleToPageX = 0;
+ bool aValue = false;
+ if( fitToPagesWide.getValueTypeClass() != uno::TypeClass_BOOLEAN || (fitToPagesWide >>= aValue))
+ {
+ fitToPagesWide >>= scaleToPageX;
+ }
+
+ mxPageProps->setPropertyValue("ScaleToPagesX", uno::Any( scaleToPageX ));
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+uno::Any SAL_CALL ScVbaPageSetup::getZoom()
+{
+ return mxPageProps->getPropertyValue("PageScale");
+}
+
+void SAL_CALL ScVbaPageSetup::setZoom( const uno::Any& zoom)
+{
+ sal_uInt16 pageScale = 0;
+ try
+ {
+ if( zoom.getValueTypeClass() == uno::TypeClass_BOOLEAN )
+ {
+ bool aValue = false;
+ zoom >>= aValue;
+ if( aValue )
+ {
+ DebugHelper::runtimeexception(ERRCODE_BASIC_BAD_PARAMETER);
+ }
+ }
+ else
+ {
+ zoom >>= pageScale;
+ if(( pageScale < ZOOM_IN )||( pageScale > ZOOM_MAX ))
+ {
+ DebugHelper::runtimeexception(ERRCODE_BASIC_BAD_PARAMETER);
+ }
+ }
+
+ // these only exist in S08
+ sal_uInt16 nScale = 0;
+ mxPageProps->setPropertyValue("ScaleToPages", uno::Any( nScale ));
+ mxPageProps->setPropertyValue("ScaleToPagesX", uno::Any( nScale ));
+ mxPageProps->setPropertyValue("ScaleToPagesY", uno::Any( nScale ));
+ }
+ catch (const beans::UnknownPropertyException&)
+ {
+ if( pageScale == 0 )
+ {
+ DebugHelper::runtimeexception(ERRCODE_BASIC_BAD_PARAMETER);
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ }
+
+ mxPageProps->setPropertyValue("PageScale", uno::Any( pageScale ));
+}
+
+OUString SAL_CALL ScVbaPageSetup::getLeftHeader()
+{
+ OUString leftHeader;
+ try
+ {
+ uno::Reference<sheet::XHeaderFooterContent> xHeaderContent( mxPageProps->getPropertyValue("RightPageHeaderContent"), uno::UNO_QUERY_THROW);
+ uno::Reference< text::XText > xText = xHeaderContent->getLeftText();
+ leftHeader = xText->getString();
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ return leftHeader;
+}
+
+void SAL_CALL ScVbaPageSetup::setLeftHeader( const OUString& leftHeader)
+{
+ try
+ {
+ uno::Reference<sheet::XHeaderFooterContent> xHeaderContent( mxPageProps->getPropertyValue("RightPageHeaderContent"), uno::UNO_QUERY_THROW);
+ uno::Reference< text::XText > xText = xHeaderContent->getLeftText();
+ xText->setString( leftHeader );
+ mxPageProps->setPropertyValue("RightPageHeaderContent", uno::Any(xHeaderContent) );
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+OUString SAL_CALL ScVbaPageSetup::getCenterHeader()
+{
+ OUString centerHeader;
+ try
+ {
+ uno::Reference<sheet::XHeaderFooterContent> xHeaderContent( mxPageProps->getPropertyValue("RightPageHeaderContent"), uno::UNO_QUERY_THROW);
+ uno::Reference< text::XText > xText = xHeaderContent->getCenterText();
+ centerHeader = xText->getString();
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ return centerHeader;
+}
+
+void SAL_CALL ScVbaPageSetup::setCenterHeader( const OUString& centerHeader)
+{
+ try
+ {
+ uno::Reference<sheet::XHeaderFooterContent> xHeaderContent( mxPageProps->getPropertyValue("RightPageHeaderContent"), uno::UNO_QUERY_THROW);
+ uno::Reference< text::XText > xText = xHeaderContent->getCenterText();
+ xText->setString( centerHeader );
+ mxPageProps->setPropertyValue("RightPageHeaderContent", uno::Any(xHeaderContent) );
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+OUString SAL_CALL ScVbaPageSetup::getRightHeader()
+{
+ OUString rightHeader;
+ try
+ {
+ uno::Reference<sheet::XHeaderFooterContent> xHeaderContent( mxPageProps->getPropertyValue("RightPageHeaderContent"), uno::UNO_QUERY_THROW);
+ uno::Reference< text::XText > xText = xHeaderContent->getRightText();
+ rightHeader = xText->getString();
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ return rightHeader;
+}
+
+void SAL_CALL ScVbaPageSetup::setRightHeader( const OUString& rightHeader)
+{
+ try
+ {
+ uno::Reference<sheet::XHeaderFooterContent> xHeaderContent( mxPageProps->getPropertyValue("RightPageHeaderContent"), uno::UNO_QUERY_THROW);
+ uno::Reference< text::XText > xText = xHeaderContent->getRightText();
+ xText->setString( rightHeader );
+ mxPageProps->setPropertyValue("RightPageHeaderContent", uno::Any(xHeaderContent) );
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+OUString SAL_CALL ScVbaPageSetup::getLeftFooter()
+{
+ OUString leftFooter;
+ try
+ {
+ uno::Reference<sheet::XHeaderFooterContent> xFooterContent( mxPageProps->getPropertyValue("RightPageFooterContent"), uno::UNO_QUERY_THROW);
+ uno::Reference< text::XText > xText = xFooterContent->getLeftText();
+ leftFooter = xText->getString();
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ return leftFooter;
+}
+
+void SAL_CALL ScVbaPageSetup::setLeftFooter( const OUString& leftFooter)
+{
+ try
+ {
+ uno::Reference<sheet::XHeaderFooterContent> xFooterContent( mxPageProps->getPropertyValue("RightPageFooterContent"), uno::UNO_QUERY_THROW);
+ uno::Reference< text::XText > xText = xFooterContent->getLeftText();
+ xText->setString( leftFooter );
+ mxPageProps->setPropertyValue("RightPageFooterContent", uno::Any(xFooterContent) );
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+OUString SAL_CALL ScVbaPageSetup::getCenterFooter()
+{
+ OUString centerFooter;
+ try
+ {
+ uno::Reference<sheet::XHeaderFooterContent> xFooterContent( mxPageProps->getPropertyValue("RightPageFooterContent"), uno::UNO_QUERY_THROW);
+ uno::Reference< text::XText > xText = xFooterContent->getCenterText();
+ centerFooter = xText->getString();
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ return centerFooter;
+}
+
+void SAL_CALL ScVbaPageSetup::setCenterFooter( const OUString& centerFooter)
+{
+ try
+ {
+ uno::Reference<sheet::XHeaderFooterContent> xFooterContent( mxPageProps->getPropertyValue("RightPageFooterContent"), uno::UNO_QUERY_THROW);
+ uno::Reference< text::XText > xText = xFooterContent->getCenterText();
+ xText->setString( centerFooter );
+ mxPageProps->setPropertyValue("RightPageFooterContent", uno::Any(xFooterContent) );
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+}
+
+OUString SAL_CALL ScVbaPageSetup::getRightFooter()
+{
+ OUString rightFooter;
+ try
+ {
+ uno::Reference<sheet::XHeaderFooterContent> xFooterContent( mxPageProps->getPropertyValue("RightPageFooterContent"), uno::UNO_QUERY_THROW);
+ uno::Reference< text::XText > xText = xFooterContent->getRightText();
+ rightFooter = xText->getString();
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ return rightFooter;
+}
+
+void SAL_CALL ScVbaPageSetup::setRightFooter( const OUString& rightFooter)
+{
+ try
+ {
+ uno::Reference<sheet::XHeaderFooterContent> xFooterContent( mxPageProps->getPropertyValue("RightPageFooterContent"), uno::UNO_QUERY_THROW);
+ uno::Reference< text::XText > xText = xFooterContent->getRightText();
+ xText->setString( rightFooter );
+ mxPageProps->setPropertyValue("RightPageFooterContent", uno::Any(xFooterContent) );
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+sal_Int32 SAL_CALL ScVbaPageSetup::getOrder()
+{
+ sal_Int32 order = excel::XlOrder::xlDownThenOver;
+ try
+ {
+ uno::Any aValue = mxPageProps->getPropertyValue("PrintDownFirst");
+ bool bPrintDownFirst = false;
+ aValue >>= bPrintDownFirst;
+ if( !bPrintDownFirst )
+ order = excel::XlOrder::xlOverThenDown;
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ return order;
+}
+
+void SAL_CALL ScVbaPageSetup::setOrder(sal_Int32 order)
+{
+ bool bOrder = true;
+ switch( order )
+ {
+ case excel::XlOrder::xlDownThenOver:
+ break;
+ case excel::XlOrder::xlOverThenDown:
+ bOrder = false;
+ break;
+ default:
+ DebugHelper::runtimeexception(ERRCODE_BASIC_BAD_PARAMETER);
+ }
+
+ try
+ {
+ mxPageProps->setPropertyValue("PrintDownFirst", uno::Any( bOrder ));
+ }
+ catch (const uno::Exception&)
+ {
+ }
+}
+
+sal_Int32 SAL_CALL ScVbaPageSetup::getFirstPageNumber()
+{
+ sal_Int16 number = 0;
+ try
+ {
+ uno::Any aValue = mxPageProps->getPropertyValue("FirstPageNumber");
+ aValue >>= number;
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ if( number ==0 )
+ {
+ number = excel::Constants::xlAutomatic;
+ }
+
+ return number;
+}
+
+void SAL_CALL ScVbaPageSetup::setFirstPageNumber( sal_Int32 firstPageNumber)
+{
+ if( firstPageNumber == excel::Constants::xlAutomatic )
+ firstPageNumber = 0;
+
+ try
+ {
+ uno::Any aValue;
+ aValue <<= static_cast<sal_Int16>(firstPageNumber);
+ mxPageProps->setPropertyValue("FirstPageNumber", aValue );
+ }
+ catch (const uno::Exception&)
+ {
+ }
+}
+
+sal_Bool SAL_CALL ScVbaPageSetup::getCenterVertically()
+{
+ bool centerVertically = false;
+ try
+ {
+ uno::Any aValue = mxPageProps->getPropertyValue("CenterVertically");
+ aValue >>= centerVertically;
+ }
+ catch (const uno::Exception&)
+ {
+ }
+ return centerVertically;
+}
+
+void SAL_CALL ScVbaPageSetup::setCenterVertically( sal_Bool centerVertically)
+{
+ try
+ {
+ mxPageProps->setPropertyValue("CenterVertically", uno::Any( centerVertically ));
+ }
+ catch (const uno::Exception&)
+ {
+ }
+}
+
+sal_Bool SAL_CALL ScVbaPageSetup::getCenterHorizontally()
+{
+ bool centerHorizontally = false;
+ try
+ {
+ uno::Any aValue = mxPageProps->getPropertyValue("CenterHorizontally");
+ aValue >>= centerHorizontally;
+ }
+ catch (const uno::Exception&)
+ {
+ }
+ return centerHorizontally;
+}
+
+void SAL_CALL ScVbaPageSetup::setCenterHorizontally( sal_Bool centerHorizontally)
+{
+ try
+ {
+ mxPageProps->setPropertyValue("CenterHorizontally", uno::Any( centerHorizontally ));
+ }
+ catch (const uno::Exception&)
+ {
+ }
+}
+
+sal_Bool SAL_CALL ScVbaPageSetup::getPrintHeadings()
+{
+ bool printHeadings = false;
+ try
+ {
+ uno::Any aValue = mxPageProps->getPropertyValue("PrintHeaders");
+ aValue >>= printHeadings;
+ }
+ catch (const uno::Exception&)
+ {
+ }
+ return printHeadings;
+}
+
+void SAL_CALL ScVbaPageSetup::setPrintHeadings( sal_Bool printHeadings)
+{
+ try
+ {
+ mxPageProps->setPropertyValue("PrintHeaders", uno::Any( printHeadings ));
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+sal_Bool SAL_CALL ScVbaPageSetup::getPrintGridlines()
+{
+ return false;
+}
+
+void SAL_CALL ScVbaPageSetup::setPrintGridlines( sal_Bool /*_printgridlines*/ )
+{
+}
+
+OUString SAL_CALL ScVbaPageSetup::getPrintTitleRows()
+{
+ return OUString();
+}
+void SAL_CALL ScVbaPageSetup::setPrintTitleRows( const OUString& /*_printtitlerows*/ )
+{
+}
+OUString SAL_CALL ScVbaPageSetup::getPrintTitleColumns()
+{
+ return OUString();
+}
+
+void SAL_CALL ScVbaPageSetup::setPrintTitleColumns( const OUString& /*_printtitlecolumns*/ )
+{
+}
+
+sal_Int32 SAL_CALL ScVbaPageSetup::getPaperSize()
+{
+ awt::Size aSize; // current papersize
+ mxPageProps->getPropertyValue( "Size" ) >>= aSize;
+ if ( mbIsLandscape )
+ ::std::swap( aSize.Width, aSize.Height );
+
+ sal_Int32 nPaperSizeIndex = msfilter::util::PaperSizeConv::getMSPaperSizeIndex( aSize );
+ if ( nPaperSizeIndex == 0 )
+ nPaperSizeIndex = excel::XlPaperSize::xlPaperUser;
+ return nPaperSizeIndex;
+}
+
+void SAL_CALL ScVbaPageSetup::setPaperSize( sal_Int32 papersize )
+{
+ if ( papersize != excel::XlPaperSize::xlPaperUser )
+ {
+ awt::Size aPaperSize;
+ const msfilter::util::ApiPaperSize& rConvertedSize = msfilter::util::PaperSizeConv::getApiSizeForMSPaperSizeIndex( papersize );
+ aPaperSize.Height = rConvertedSize.mnHeight;
+ aPaperSize.Width = rConvertedSize.mnWidth;
+ if ( mbIsLandscape )
+ ::std::swap( aPaperSize.Width, aPaperSize.Height );
+ mxPageProps->setPropertyValue( "Size", uno::Any( aPaperSize ) );
+ }
+}
+
+OUString
+ScVbaPageSetup::getServiceImplName()
+{
+ return "ScVbaPageSetup";
+}
+
+uno::Sequence< OUString >
+ScVbaPageSetup::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.PageSetup"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbapagesetup.hxx b/sc/source/ui/vba/vbapagesetup.hxx
new file mode 100644
index 000000000..75e3ed1d3
--- /dev/null
+++ b/sc/source/ui/vba/vbapagesetup.hxx
@@ -0,0 +1,90 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <cppuhelper/implbase.hxx>
+#include <ooo/vba/excel/XPageSetup.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <vbahelper/vbapagesetupbase.hxx>
+
+typedef cppu::ImplInheritanceHelper<VbaPageSetupBase, ov::excel::XPageSetup> ScVbaPageSetup_BASE;
+
+class ScVbaPageSetup : public ScVbaPageSetup_BASE
+{
+ css::uno::Reference<css::sheet::XSpreadsheet> mxSheet;
+ bool mbIsLandscape;
+
+public:
+ /// @throws css::uno::RuntimeException
+ ScVbaPageSetup(const css::uno::Reference<ov::XHelperInterface>& xParent,
+ const css::uno::Reference<css::uno::XComponentContext>& xContext,
+ const css::uno::Reference<css::sheet::XSpreadsheet>& xSheet,
+ const css::uno::Reference<css::frame::XModel>& xModel);
+
+ // Attribute
+ virtual OUString SAL_CALL getPrintArea() override;
+ virtual void SAL_CALL setPrintArea(const OUString& rAreas) override;
+ virtual double SAL_CALL getHeaderMargin() override;
+ void SAL_CALL setHeaderMargin(double margin) override;
+ double SAL_CALL getFooterMargin() override;
+ void SAL_CALL setFooterMargin(double margin) override;
+ virtual css::uno::Any SAL_CALL getFitToPagesTall() override;
+ virtual void SAL_CALL setFitToPagesTall(const css::uno::Any& fitToPagesTall) override;
+ virtual css::uno::Any SAL_CALL getFitToPagesWide() override;
+ virtual void SAL_CALL setFitToPagesWide(const css::uno::Any& fitToPagesWide) override;
+ virtual css::uno::Any SAL_CALL getZoom() override;
+ virtual void SAL_CALL setZoom(const css::uno::Any& zoom) override;
+ virtual OUString SAL_CALL getLeftHeader() override;
+ virtual void SAL_CALL setLeftHeader(const OUString& leftHeader) override;
+ virtual OUString SAL_CALL getCenterHeader() override;
+ virtual void SAL_CALL setCenterHeader(const OUString& centerHeader) override;
+ virtual OUString SAL_CALL getRightHeader() override;
+ virtual void SAL_CALL setRightHeader(const OUString& rightHeader) override;
+ virtual OUString SAL_CALL getLeftFooter() override;
+ virtual void SAL_CALL setLeftFooter(const OUString& leftFooter) override;
+ virtual OUString SAL_CALL getCenterFooter() override;
+ virtual void SAL_CALL setCenterFooter(const OUString& centerFooter) override;
+ virtual OUString SAL_CALL getRightFooter() override;
+ virtual void SAL_CALL setRightFooter(const OUString& rightFooter) override;
+ virtual sal_Int32 SAL_CALL getOrder() override;
+ virtual void SAL_CALL setOrder(sal_Int32 order) override;
+ virtual sal_Int32 SAL_CALL getFirstPageNumber() override;
+ virtual void SAL_CALL setFirstPageNumber(sal_Int32 firstPageNumber) override;
+ virtual sal_Bool SAL_CALL getCenterVertically() override;
+ virtual void SAL_CALL setCenterVertically(sal_Bool centerVertically) override;
+ virtual sal_Bool SAL_CALL getCenterHorizontally() override;
+ virtual void SAL_CALL setCenterHorizontally(sal_Bool centerHorizontally) override;
+ virtual sal_Bool SAL_CALL getPrintHeadings() override;
+ virtual void SAL_CALL setPrintHeadings(sal_Bool printHeadings) override;
+
+ virtual sal_Bool SAL_CALL getPrintGridlines() override;
+ virtual void SAL_CALL setPrintGridlines(sal_Bool _printgridlines) override;
+ virtual OUString SAL_CALL getPrintTitleRows() override;
+ virtual void SAL_CALL setPrintTitleRows(const OUString& _printtitlerows) override;
+ virtual OUString SAL_CALL getPrintTitleColumns() override;
+ virtual void SAL_CALL setPrintTitleColumns(const OUString& _printtitlecolumns) override;
+ virtual sal_Int32 SAL_CALL getPaperSize() override;
+ virtual void SAL_CALL setPaperSize(sal_Int32 papersize) override;
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbapalette.cxx b/sc/source/ui/vba/vbapalette.cxx
new file mode 100644
index 000000000..81caebab6
--- /dev/null
+++ b/sc/source/ui/vba/vbapalette.cxx
@@ -0,0 +1,115 @@
+/* -*- 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 "vbapalette.hxx"
+
+#include <sal/macros.h>
+#include <cppuhelper/implbase.hxx>
+#include <sfx2/objsh.hxx>
+#include <docsh.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+#include "excelvbahelper.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+/** Standard EGA colors, bright. */
+#define EXC_PALETTE_EGA_COLORS_LIGHT \
+ Color(0x000000), Color(0xFFFFFF), Color(0xFF0000), Color(0x00FF00), Color(0x0000FF), Color(0xFFFF00), Color(0xFF00FF), Color(0x00FFFF)
+/** Standard EGA colors), dark. */
+#define EXC_PALETTE_EGA_COLORS_DARK \
+ Color(0x800000), Color(0x008000), Color(0x000080), Color(0x808000), Color(0x800080), Color(0x008080), Color(0xC0C0C0), Color(0x808080)
+
+const Color spnDefColorTable8[] =
+{
+/* 8 */ EXC_PALETTE_EGA_COLORS_LIGHT,
+/* 16 */ EXC_PALETTE_EGA_COLORS_DARK,
+/* 24 */ Color(0x9999FF), Color(0x993366), Color(0xFFFFCC), Color(0xCCFFFF), Color(0x660066), Color(0xFF8080), Color(0x0066CC), Color(0xCCCCFF),
+/* 32 */ Color(0x000080), Color(0xFF00FF), Color(0xFFFF00), Color(0x00FFFF), Color(0x800080), Color(0x800000), Color(0x008080), Color(0x0000FF),
+/* 40 */ Color(0x00CCFF), Color(0xCCFFFF), Color(0xCCFFCC), Color(0xFFFF99), Color(0x99CCFF), Color(0xFF99CC), Color(0xCC99FF), Color(0xFFCC99),
+/* 48 */ Color(0x3366FF), Color(0x33CCCC), Color(0x99CC00), Color(0xFFCC00), Color(0xFF9900), Color(0xFF6600), Color(0x666699), Color(0x969696),
+/* 56 */ Color(0x003366), Color(0x339966), Color(0x003300), Color(0x333300), Color(0x993300), Color(0x993366), Color(0x333399), Color(0x333333)
+};
+
+typedef ::cppu::WeakImplHelper< container::XIndexAccess > XIndexAccess_BASE;
+
+namespace {
+
+class DefaultPalette : public XIndexAccess_BASE
+{
+public:
+ DefaultPalette(){}
+
+ // Methods XIndexAccess
+ virtual ::sal_Int32 SAL_CALL getCount() override
+ {
+ return SAL_N_ELEMENTS(spnDefColorTable8);
+ }
+
+ virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override
+ {
+ if ( Index < 0 || Index >= getCount() )
+ throw lang::IndexOutOfBoundsException();
+ return uno::Any( sal_Int32( spnDefColorTable8[ Index ] ) );
+ }
+
+ // Methods XElementAccess
+ virtual uno::Type SAL_CALL getElementType() override
+ {
+ return ::cppu::UnoType<sal_Int32>::get();
+ }
+ virtual sal_Bool SAL_CALL hasElements() override
+ {
+ return true;
+ }
+
+};
+
+}
+
+ScVbaPalette::ScVbaPalette( const uno::Reference< frame::XModel >& rxModel ) :
+ m_pShell( excel::getDocShell( rxModel ) )
+{
+}
+
+uno::Reference< container::XIndexAccess >
+ScVbaPalette::getDefaultPalette()
+{
+ return new DefaultPalette();
+}
+
+uno::Reference< container::XIndexAccess >
+ScVbaPalette::getPalette() const
+{
+ uno::Reference< container::XIndexAccess > xIndex;
+ uno::Reference< beans::XPropertySet > xProps;
+ if ( !m_pShell )
+ throw uno::RuntimeException("Can't extract palette, no doc shell" );
+
+ xProps.set( m_pShell->GetModel(), uno::UNO_QUERY_THROW );
+
+ xIndex.set( xProps->getPropertyValue("ColorPalette"), uno::UNO_QUERY );
+ if ( !xIndex.is() )
+ return new DefaultPalette();
+ return xIndex;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbapalette.hxx b/sc/source/ui/vba/vbapalette.hxx
new file mode 100644
index 000000000..cc0d66f3c
--- /dev/null
+++ b/sc/source/ui/vba/vbapalette.hxx
@@ -0,0 +1,44 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <com/sun/star/uno/Reference.hxx>
+
+namespace com::sun::star {
+ namespace container { class XIndexAccess; }
+ namespace frame { class XModel; }
+}
+
+class SfxObjectShell;
+
+class ScVbaPalette
+{
+private:
+ SfxObjectShell* m_pShell;
+public:
+ explicit ScVbaPalette( SfxObjectShell* pShell ) : m_pShell( pShell ) {}
+ explicit ScVbaPalette( const css::uno::Reference< css::frame::XModel >& rxModel );
+ // if no palette available e.g. because the document doesn't have a
+ // palette defined then a default palette will be returned.
+ css::uno::Reference< css::container::XIndexAccess > getPalette() const;
+ static css::uno::Reference< css::container::XIndexAccess > getDefaultPalette();
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbapane.cxx b/sc/source/ui/vba/vbapane.cxx
new file mode 100644
index 000000000..1f7f0b540
--- /dev/null
+++ b/sc/source/ui/vba/vbapane.cxx
@@ -0,0 +1,196 @@
+/* -*- 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 "vbapane.hxx"
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include "vbarange.hxx"
+
+using namespace com::sun::star;
+using namespace ooo::vba;
+
+ScVbaPane::ScVbaPane(
+ const css::uno::Reference< ov::XHelperInterface >& xParent,
+ const uno::Reference< uno::XComponentContext >& xContext,
+ const uno::Reference< frame::XModel >& rModel,
+ const uno::Reference< sheet::XViewPane >& rViewPane ) :
+ m_xModel(rModel, uno::UNO_SET_THROW),
+ m_xViewPane(rViewPane, uno::UNO_SET_THROW),
+ m_xParent(xParent),
+ m_xContext(xContext)
+{
+}
+
+sal_Int32 SAL_CALL
+ScVbaPane::getScrollColumn()
+{
+ return ( m_xViewPane->getFirstVisibleColumn() + 1 );
+}
+
+void SAL_CALL
+ScVbaPane::setScrollColumn( sal_Int32 _scrollcolumn )
+{
+ if( _scrollcolumn < 1 )
+ {
+ throw uno::RuntimeException("Column number should not be less than 1" );
+ }
+ m_xViewPane->setFirstVisibleColumn( _scrollcolumn - 1 );
+}
+
+sal_Int32 SAL_CALL
+ScVbaPane::getScrollRow()
+{
+ return ( m_xViewPane->getFirstVisibleRow() + 1 );
+}
+
+void SAL_CALL
+ScVbaPane::setScrollRow( sal_Int32 _scrollrow )
+{
+ if( _scrollrow < 1 )
+ {
+ throw uno::RuntimeException("Row number should not be less than 1" );
+ }
+ m_xViewPane->setFirstVisibleRow( _scrollrow - 1 );
+}
+
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaPane::getVisibleRange()
+{
+ // TODO: Excel includes partly visible rows/columns, Calc does not
+ table::CellRangeAddress aRangeAddr = m_xViewPane->getVisibleRange();
+ uno::Reference< sheet::XSpreadsheetDocument > xDoc( m_xModel, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xSheetsIA( xDoc->getSheets(), uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XSpreadsheet > xSheet( xSheetsIA->getByIndex( aRangeAddr.Sheet ), uno::UNO_QUERY_THROW );
+ uno::Reference< table::XCellRange > xRange( xSheet->getCellRangeByPosition( aRangeAddr.StartColumn, aRangeAddr.StartRow, aRangeAddr.EndColumn, aRangeAddr.EndRow ), uno::UNO_SET_THROW );
+ // TODO: m_xParent is the window, Range needs the worksheet
+ return new ScVbaRange( m_xParent, m_xContext, xRange );
+}
+
+//Method
+void SAL_CALL
+ScVbaPane::SmallScroll( const uno::Any& Down, const uno::Any& Up, const uno::Any& ToRight, const uno::Any& ToLeft )
+{
+ OUString messageBuffer;
+ sal_Int32 downRows = 0;
+ sal_Int32 rightCols = 0;
+ table::CellRangeAddress visibleRange = m_xViewPane->getVisibleRange();
+
+ if( Down.hasValue() )
+ {
+ sal_Int32 down = 0;
+ if( Down >>= down )
+ downRows += down;
+ else
+ messageBuffer += "Error getting parameter: Down\n";
+ }
+ if( Up.hasValue() )
+ {
+ sal_Int32 up = 0;
+ if( Up >>= up )
+ downRows -= up;
+ else
+ messageBuffer += "Error getting parameter: Up\n";
+ }
+ if( ToRight.hasValue() )
+ {
+ sal_Int32 right = 0;
+ if( ToRight >>= right )
+ rightCols += right;
+ else
+ messageBuffer += "Error getting parameter: ToRight\n";
+ }
+ if( ToLeft.hasValue() )
+ {
+ sal_Int32 left = 0;
+ if( ToLeft >>= left )
+ rightCols -= left;
+ else
+ messageBuffer += "Error getting parameter: ToLeft\n";
+ }
+ if( !messageBuffer.isEmpty() )
+ throw uno::RuntimeException( messageBuffer );
+
+ sal_Int32 newStartRow = visibleRange.StartRow + downRows;
+ if( newStartRow < 0 )
+ newStartRow = 0;
+ sal_Int32 newStartCol = visibleRange.StartColumn + rightCols;
+ if( newStartCol < 0 )
+ newStartCol = 0;
+ m_xViewPane->setFirstVisibleRow( newStartRow );
+ m_xViewPane->setFirstVisibleColumn( newStartCol );
+}
+
+void SAL_CALL
+ScVbaPane::LargeScroll( const uno::Any& Down, const uno::Any& Up, const uno::Any& ToRight, const uno::Any& ToLeft )
+{
+ OUString messageBuffer;
+ table::CellRangeAddress visibleRange = m_xViewPane->getVisibleRange();
+
+ sal_Int32 vertPageSize = 1 + visibleRange.EndRow - visibleRange.StartRow;
+ sal_Int32 horizPageSize = 1 + visibleRange.EndColumn - visibleRange.StartColumn;
+ sal_Int32 downPages = 0;
+ sal_Int32 acrossPages = 0;
+ if( Down.hasValue() )
+ {
+ sal_Int32 down = 0;
+ if( Down >>= down )
+ downPages += down;
+ else
+ messageBuffer += "Error getting parameter: Down\n";
+ }
+ if( Up.hasValue() )
+ {
+ sal_Int32 up = 0;
+ if( Up >>= up )
+ downPages -= up;
+ else
+ messageBuffer += "Error getting parameter: Up\n";
+ }
+ if( ToRight.hasValue() )
+ {
+ sal_Int32 right = 0;
+ if( ToRight >>= right )
+ acrossPages += right;
+ else
+ messageBuffer += "Error getting parameter: ToRight\n";
+ }
+ if( ToLeft.hasValue() )
+ {
+ sal_Int32 left = 0;
+ if( ToLeft >>= left )
+ acrossPages -= left;
+ else
+ messageBuffer += "Error getting parameter: ToLeft\n";
+ }
+ if( !messageBuffer.isEmpty() )
+ throw uno::RuntimeException( messageBuffer );
+
+ sal_Int32 newStartRow = visibleRange.StartRow + (downPages * vertPageSize );
+ if( newStartRow < 0 )
+ newStartRow = 0;
+ sal_Int32 newStartCol = visibleRange.StartColumn + (acrossPages * horizPageSize );
+ if( newStartCol < 0 )
+ newStartCol = 0;
+ m_xViewPane->setFirstVisibleRow( newStartRow );
+ m_xViewPane->setFirstVisibleColumn( newStartCol );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbapane.hxx b/sc/source/ui/vba/vbapane.hxx
new file mode 100644
index 000000000..cf4fd8328
--- /dev/null
+++ b/sc/source/ui/vba/vbapane.hxx
@@ -0,0 +1,55 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <com/sun/star/sheet/XViewPane.hpp>
+#include <cppuhelper/implbase.hxx>
+#include <cppuhelper/weakref.hxx>
+#include <ooo/vba/excel/XPane.hpp>
+#include <vbahelper/vbahelper.hxx>
+
+class ScVbaPane final : public cppu::WeakImplHelper< ov::excel::XPane >
+{
+public:
+ /// @throws css::uno::RuntimeException
+ ScVbaPane(
+ const css::uno::Reference< ov::XHelperInterface >& rParent,
+ const css::uno::Reference< css::uno::XComponentContext >& rContext,
+ const css::uno::Reference< css::frame::XModel >& rModel,
+ const css::uno::Reference< css::sheet::XViewPane >& rViewPane );
+
+ // XPane attributes
+ virtual sal_Int32 SAL_CALL getScrollColumn() override;
+ virtual void SAL_CALL setScrollColumn( sal_Int32 _scrollcolumn ) override;
+ virtual sal_Int32 SAL_CALL getScrollRow() override;
+ virtual void SAL_CALL setScrollRow( sal_Int32 _scrollrow ) override;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL getVisibleRange() override;
+
+ // XPane methods
+ virtual void SAL_CALL SmallScroll( const css::uno::Any& Down, const css::uno::Any& Up, const css::uno::Any& ToRight, const css::uno::Any& ToLeft ) override;
+ virtual void SAL_CALL LargeScroll( const css::uno::Any& Down, const css::uno::Any& Up, const css::uno::Any& ToRight, const css::uno::Any& ToLeft ) override;
+
+private:
+ css::uno::Reference< css::frame::XModel > m_xModel;
+ css::uno::Reference< css::sheet::XViewPane > m_xViewPane;
+ css::uno::WeakReference< ov::XHelperInterface > m_xParent;
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbapivotcache.cxx b/sc/source/ui/vba/vbapivotcache.cxx
new file mode 100644
index 000000000..54c6a4ad7
--- /dev/null
+++ b/sc/source/ui/vba/vbapivotcache.cxx
@@ -0,0 +1,50 @@
+/* -*- 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 "vbapivotcache.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+ScVbaPivotCache::ScVbaPivotCache( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< sheet::XDataPilotTable >& xTable ) : PivotCacheImpl_BASE( xParent, xContext ), m_xTable( xTable )
+{
+}
+
+void SAL_CALL
+ScVbaPivotCache::Refresh()
+{
+ m_xTable->refresh();
+}
+
+OUString
+ScVbaPivotCache::getServiceImplName()
+{
+ return "ScVbaPivotCache";
+}
+
+uno::Sequence< OUString >
+ScVbaPivotCache::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.PivotCache"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbapivotcache.hxx b/sc/source/ui/vba/vbapivotcache.hxx
new file mode 100644
index 000000000..c02f30920
--- /dev/null
+++ b/sc/source/ui/vba/vbapivotcache.hxx
@@ -0,0 +1,40 @@
+/* -*- 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 .
+ */
+#pragma once
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/sheet/XDataPilotTable.hpp>
+
+#include <ooo/vba/excel/XPivotCache.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+
+typedef InheritedHelperInterfaceWeakImpl<ov::excel::XPivotCache > PivotCacheImpl_BASE;
+
+class ScVbaPivotCache : public PivotCacheImpl_BASE
+{
+ css::uno::Reference< css::sheet::XDataPilotTable > m_xTable;
+public:
+ ScVbaPivotCache( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::sheet::XDataPilotTable >& xTable );
+
+ virtual void SAL_CALL Refresh() override;
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbapivottable.cxx b/sc/source/ui/vba/vbapivottable.cxx
new file mode 100644
index 000000000..775ac390c
--- /dev/null
+++ b/sc/source/ui/vba/vbapivottable.cxx
@@ -0,0 +1,53 @@
+/* -*- 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 "vbapivottable.hxx"
+#include "vbapivotcache.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+ScVbaPivotTable::ScVbaPivotTable( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< sheet::XDataPilotTable >& xTable ) : PivotTableImpl_BASE( uno::Reference< XHelperInterface >(), xContext), m_xTable( xTable )
+{
+}
+
+uno::Reference< excel::XPivotCache >
+ScVbaPivotTable::PivotCache()
+{
+ // #FIXME with a quick example failed to determine what the parent
+ // should be, leaving as null at the moment
+ return new ScVbaPivotCache( uno::Reference< XHelperInterface >(), mxContext, m_xTable );
+}
+
+OUString
+ScVbaPivotTable::getServiceImplName()
+{
+ return "ScVbaPivotTable";
+}
+
+uno::Sequence< OUString >
+ScVbaPivotTable::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.PivotTable"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbapivottable.hxx b/sc/source/ui/vba/vbapivottable.hxx
new file mode 100644
index 000000000..3d3392168
--- /dev/null
+++ b/sc/source/ui/vba/vbapivottable.hxx
@@ -0,0 +1,40 @@
+/* -*- 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 .
+ */
+#pragma once
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/sheet/XDataPilotTable.hpp>
+#include <ooo/vba/excel/XPivotTable.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+
+typedef InheritedHelperInterfaceWeakImpl<ov::excel::XPivotTable> PivotTableImpl_BASE;
+
+class ScVbaPivotTable : public PivotTableImpl_BASE
+{
+ css::uno::Reference<css::sheet::XDataPilotTable> m_xTable;
+
+public:
+ ScVbaPivotTable(const css::uno::Reference<css::uno::XComponentContext>& xContext,
+ const css::uno::Reference<css::sheet::XDataPilotTable>& xTable);
+ virtual css::uno::Reference<ov::excel::XPivotCache> SAL_CALL PivotCache() override;
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbapivottables.cxx b/sc/source/ui/vba/vbapivottables.cxx
new file mode 100644
index 000000000..f49fbeaeb
--- /dev/null
+++ b/sc/source/ui/vba/vbapivottables.cxx
@@ -0,0 +1,89 @@
+/* -*- 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 "vbapivottables.hxx"
+#include "vbapivottable.hxx"
+#include <com/sun/star/sheet/XDataPilotTable.hpp>
+#include <ooo/vba/excel/XPivotTable.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+static uno::Any DataPilotToPivotTable( const uno::Any& aSource, const uno::Reference< uno::XComponentContext > & xContext )
+{
+ uno::Reference< sheet::XDataPilotTable > xTable( aSource, uno::UNO_QUERY_THROW );
+ return uno::Any( uno::Reference< excel::XPivotTable > ( new ScVbaPivotTable( xContext, xTable ) ) );
+}
+
+namespace {
+
+class PivotTableEnumeration : public EnumerationHelperImpl
+{
+public:
+ /// @throws uno::RuntimeException
+ PivotTableEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ) {}
+
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ return DataPilotToPivotTable( m_xEnumeration->nextElement(), m_xContext );
+ }
+
+};
+
+}
+
+ScVbaPivotTables::ScVbaPivotTables( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< container::XIndexAccess >& xIndexAccess ): ScVbaPivotTables_BASE( xParent, xContext, xIndexAccess )
+{
+}
+
+uno::Reference< container::XEnumeration >
+ScVbaPivotTables::createEnumeration()
+{
+ uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
+ return new PivotTableEnumeration( mxParent, mxContext, xEnumAccess->createEnumeration() );
+}
+
+uno::Any
+ScVbaPivotTables::createCollectionObject( const css::uno::Any& aSource )
+{
+ return DataPilotToPivotTable( aSource, mxContext );
+}
+
+uno::Type
+ScVbaPivotTables::getElementType()
+{
+ return cppu::UnoType<excel::XPivotTable>::get();
+}
+
+OUString
+ScVbaPivotTables::getServiceImplName()
+{
+ return "ScVbaPivotTables";
+}
+
+css::uno::Sequence<OUString>
+ScVbaPivotTables::getServiceNames()
+{
+ static uno::Sequence< OUString > const sNames
+ {
+ "ooo.vba.excel.PivotTables"
+ };
+ return sNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbapivottables.hxx b/sc/source/ui/vba/vbapivottables.hxx
new file mode 100644
index 000000000..69b16b96f
--- /dev/null
+++ b/sc/source/ui/vba/vbapivottables.hxx
@@ -0,0 +1,49 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <ooo/vba/excel/XPivotTables.hpp>
+
+#include <vbahelper/vbacollectionimpl.hxx>
+
+namespace com::sun::star::uno { class XComponentContext; }
+
+typedef CollTestImplHelper< ov::excel::XPivotTables > ScVbaPivotTables_BASE;
+
+class ScVbaPivotTables : public ScVbaPivotTables_BASE
+{
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+
+public:
+ ScVbaPivotTables( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess );
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+
+ // XPivotTables
+
+ // ScVbaPivotTables_BASE
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+
+ virtual OUString getServiceImplName() override;
+
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbarange.cxx b/sc/source/ui/vba/vbarange.cxx
new file mode 100644
index 000000000..99933f165
--- /dev/null
+++ b/sc/source/ui/vba/vbarange.cxx
@@ -0,0 +1,5720 @@
+/* -*- 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 "vbarange.hxx"
+
+#include <comphelper/types.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <o3tl/any.hxx>
+#include <o3tl/safeint.hxx>
+#include <o3tl/unit_conversion.hxx>
+#include <rtl/math.hxx>
+#include <tools/diagnose_ex.h>
+#include <o3tl/string_view.hxx>
+
+#include <com/sun/star/script/ArrayWrapper.hpp>
+#include <com/sun/star/script/XTypeConverter.hpp>
+#include <com/sun/star/script/vba/VBAEventId.hpp>
+#include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
+#include <com/sun/star/sheet/XDatabaseRange.hpp>
+#include <com/sun/star/sheet/XUnnamedDatabaseRanges.hpp>
+#include <com/sun/star/sheet/XGoalSeek.hpp>
+#include <com/sun/star/sheet/XSheetOperation.hpp>
+#include <com/sun/star/sheet/CellFlags.hpp>
+#include <com/sun/star/table/XColumnRowRange.hpp>
+#include <com/sun/star/sheet/XCellAddressable.hpp>
+#include <com/sun/star/table/CellContentType.hpp>
+#include <com/sun/star/sheet/XCellSeries.hpp>
+#include <com/sun/star/text/XTextRange.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/sheet/XSpreadsheetView.hpp>
+#include <com/sun/star/sheet/XCellRangeReferrer.hpp>
+#include <com/sun/star/sheet/XSheetCellRange.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XSheetCellCursor.hpp>
+#include <com/sun/star/sheet/XArrayFormulaRange.hpp>
+#include <com/sun/star/sheet/XNamedRange.hpp>
+#include <com/sun/star/sheet/XNamedRanges.hpp>
+#include <com/sun/star/sheet/XPrintAreas.hpp>
+#include <com/sun/star/sheet/XCellRangesQuery.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+#include <com/sun/star/table/XTableRows.hpp>
+#include <com/sun/star/table/XTableColumns.hpp>
+#include <com/sun/star/table/TableSortField.hpp>
+#include <com/sun/star/util/XMergeable.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
+#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
+#include <com/sun/star/util/XNumberFormats.hpp>
+#include <com/sun/star/util/NumberFormat.hpp>
+#include <com/sun/star/util/XNumberFormatTypes.hpp>
+#include <com/sun/star/util/XReplaceable.hpp>
+#include <com/sun/star/util/XSortable.hpp>
+#include <com/sun/star/sheet/XCellRangeMovement.hpp>
+#include <com/sun/star/sheet/FormulaResult.hpp>
+#include <com/sun/star/sheet/FilterOperator2.hpp>
+#include <com/sun/star/sheet/TableFilterField2.hpp>
+#include <com/sun/star/sheet/XSheetFilterDescriptor2.hpp>
+#include <com/sun/star/sheet/FilterConnection.hpp>
+#include <com/sun/star/util/TriState.hpp>
+
+#include <com/sun/star/sheet/XSubTotalCalculatable.hpp>
+#include <com/sun/star/sheet/XSubTotalDescriptor.hpp>
+#include <com/sun/star/sheet/GeneralFunction.hpp>
+
+#include <com/sun/star/sheet/XSheetAnnotationsSupplier.hpp>
+#include <com/sun/star/sheet/XSheetAnnotations.hpp>
+
+#include <ooo/vba/excel/XlPasteSpecialOperation.hpp>
+#include <ooo/vba/excel/XlPasteType.hpp>
+#include <ooo/vba/excel/XlFindLookIn.hpp>
+#include <ooo/vba/excel/XlLookAt.hpp>
+#include <ooo/vba/excel/XlSearchOrder.hpp>
+#include <ooo/vba/excel/XlSortOrder.hpp>
+#include <ooo/vba/excel/XlYesNoGuess.hpp>
+#include <ooo/vba/excel/XlSortOrientation.hpp>
+#include <ooo/vba/excel/XlSortMethod.hpp>
+#include <ooo/vba/excel/XlDirection.hpp>
+#include <ooo/vba/excel/XlSortDataOption.hpp>
+#include <ooo/vba/excel/XlDeleteShiftDirection.hpp>
+#include <ooo/vba/excel/XlInsertShiftDirection.hpp>
+#include <ooo/vba/excel/XlReferenceStyle.hpp>
+#include <ooo/vba/excel/XlBordersIndex.hpp>
+#include <ooo/vba/excel/XlPageBreak.hpp>
+#include <ooo/vba/excel/XlAutoFilterOperator.hpp>
+#include <ooo/vba/excel/XlAutoFillType.hpp>
+#include <ooo/vba/excel/XlCellType.hpp>
+#include <ooo/vba/excel/XlSpecialCellsValue.hpp>
+#include <ooo/vba/excel/XlConsolidationFunction.hpp>
+#include <ooo/vba/excel/XlSearchDirection.hpp>
+
+#include <scitems.hxx>
+#include <svl/srchitem.hxx>
+#include <cellsuno.hxx>
+#include <dbdata.hxx>
+#include <docfunc.hxx>
+#include <columnspanset.hxx>
+#include <queryparam.hxx>
+#include <sortparam.hxx>
+
+#include <sfx2/dispatch.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sc.hrc>
+#include <unonames.hxx>
+
+#include "excelvbahelper.hxx"
+#include "vbaapplication.hxx"
+#include "vbafont.hxx"
+#include "vbacomment.hxx"
+#include "vbainterior.hxx"
+#include "vbacharacters.hxx"
+#include "vbaborders.hxx"
+#include "vbaworksheet.hxx"
+#include "vbavalidation.hxx"
+#include "vbahyperlinks.hxx"
+
+#include <tabvwsh.hxx>
+#include <rangelst.hxx>
+#include <convuno.hxx>
+#include <compiler.hxx>
+#include <patattr.hxx>
+#include <olinetab.hxx>
+#include <transobj.hxx>
+#include <queryentry.hxx>
+#include <markdata.hxx>
+#include <basic/sberrors.hxx>
+#include <cppuhelper/implbase.hxx>
+
+#include <global.hxx>
+
+#include "vbastyle.hxx"
+#include "vbaname.hxx"
+#include <vector>
+#include <vbahelper/vbacollectionimpl.hxx>
+
+#include <com/sun/star/bridge/oleautomation/Date.hpp>
+#include <tokenarray.hxx>
+#include <tokenuno.hxx>
+
+#include <memory>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+using ::std::vector;
+
+// difference between VBA and file format width, in character units
+const double fExtraWidth = 182.0 / 256.0;
+
+const sal_Int16 supportedIndexTable[] = { excel::XlBordersIndex::xlEdgeLeft, excel::XlBordersIndex::xlEdgeTop, excel::XlBordersIndex::xlEdgeBottom, excel::XlBordersIndex::xlEdgeRight, excel::XlBordersIndex::xlDiagonalDown, excel::XlBordersIndex::xlDiagonalUp, excel::XlBordersIndex::xlInsideVertical, excel::XlBordersIndex::xlInsideHorizontal };
+
+static sal_uInt16 lcl_pointsToTwips( double nVal )
+{
+ nVal = nVal * static_cast<double>(20);
+ short nTwips = static_cast<short>(nVal);
+ return nTwips;
+}
+static double lcl_TwipsToPoints( sal_uInt16 nVal )
+{
+ double nPoints = nVal;
+ return nPoints / 20;
+}
+
+static double lcl_Round2DecPlaces( double nVal )
+{
+ nVal = (nVal * double(100));
+ tools::Long tmp = static_cast<tools::Long>(nVal);
+ if ( ( nVal - tmp ) >= 0.5 )
+ ++tmp;
+ nVal = double(tmp)/100;
+ return nVal;
+}
+
+static uno::Any lcl_makeRange( const uno::Reference< XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, const uno::Any& rAny, bool bIsRows, bool bIsColumns )
+{
+ uno::Reference< table::XCellRange > xCellRange(rAny, uno::UNO_QUERY_THROW);
+ return uno::Any( uno::Reference< excel::XRange >( new ScVbaRange( rParent, rContext, xCellRange, bIsRows, bIsColumns ) ) );
+}
+
+static uno::Reference< excel::XRange > lcl_makeXRangeFromSheetCellRanges( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< sheet::XSheetCellRanges >& xLocSheetCellRanges, ScDocShell* pDoc )
+{
+ uno::Reference< excel::XRange > xRange;
+ const uno::Sequence< table::CellRangeAddress > sAddresses = xLocSheetCellRanges->getRangeAddresses();
+ ScRangeList aCellRanges;
+ if ( sAddresses.hasElements() )
+ {
+ for ( const auto& rAddress : sAddresses )
+ {
+ ScRange refRange;
+ ScUnoConversion::FillScRange( refRange, rAddress );
+ aCellRanges.push_back( refRange );
+ }
+ // Single range
+ if ( aCellRanges.size() == 1 )
+ {
+ uno::Reference< table::XCellRange > xTmpRange( new ScCellRangeObj( pDoc, aCellRanges.front() ) );
+ xRange = new ScVbaRange( xParent, xContext, xTmpRange );
+ }
+ else
+ {
+ uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pDoc, aCellRanges ) );
+ xRange = new ScVbaRange( xParent, xContext, xRanges );
+ }
+ }
+ return xRange;
+}
+
+ScCellRangesBase* ScVbaRange::getCellRangesBase()
+{
+ if( mxRanges.is() )
+ return comphelper::getFromUnoTunnel<ScCellRangesBase>( mxRanges );
+ if( mxRange.is() )
+ return comphelper::getFromUnoTunnel<ScCellRangesBase>( mxRange );
+ throw uno::RuntimeException("General Error creating range - Unknown" );
+}
+
+ScCellRangeObj* ScVbaRange::getCellRangeObj()
+{
+ return dynamic_cast< ScCellRangeObj* >( getCellRangesBase() );
+}
+
+SfxItemSet* ScVbaRange::getCurrentDataSet( )
+{
+ SfxItemSet* pDataSet = excel::ScVbaCellRangeAccess::GetDataSet( getCellRangesBase() );
+ if ( !pDataSet )
+ throw uno::RuntimeException("Can't access Itemset for range" );
+ return pDataSet;
+}
+
+void ScVbaRange::fireChangeEvent()
+{
+ if( !ScVbaApplication::getDocumentEventsEnabled() )
+ return;
+
+ ScDocument& rDoc = getScDocument();
+ const uno::Reference< script::vba::XVBAEventProcessor >& xVBAEvents = rDoc.GetVbaEventProcessor();
+ if( xVBAEvents.is() ) try
+ {
+ uno::Sequence< uno::Any > aArgs{ uno::Any(uno::Reference< excel::XRange >( this )) };
+ xVBAEvents->processVbaEvent( script::vba::VBAEventId::WORKSHEET_CHANGE, aArgs );
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+namespace {
+
+class SingleRangeEnumeration : public EnumerationHelper_BASE
+{
+ uno::Reference< table::XCellRange > m_xRange;
+ bool bHasMore;
+public:
+ /// @throws uno::RuntimeException
+ explicit SingleRangeEnumeration( const uno::Reference< table::XCellRange >& xRange ) : m_xRange( xRange ), bHasMore( true ) { }
+ virtual sal_Bool SAL_CALL hasMoreElements( ) override { return bHasMore; }
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ if ( !bHasMore )
+ throw container::NoSuchElementException();
+ bHasMore = false;
+ return uno::Any( m_xRange );
+ }
+};
+
+// very simple class to pass to ScVbaCollectionBaseImpl containing
+// just one item
+
+class SingleRangeIndexAccess : public ::cppu::WeakImplHelper< container::XIndexAccess,
+ container::XEnumerationAccess >
+{
+private:
+ uno::Reference< table::XCellRange > m_xRange;
+
+public:
+ explicit SingleRangeIndexAccess( const uno::Reference< table::XCellRange >& xRange ) : m_xRange( xRange ) {}
+ // XIndexAccess
+ virtual ::sal_Int32 SAL_CALL getCount() override { return 1; }
+ virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override
+ {
+ if ( Index != 0 )
+ throw lang::IndexOutOfBoundsException();
+ return uno::Any( m_xRange );
+ }
+ // XElementAccess
+ virtual uno::Type SAL_CALL getElementType() override { return cppu::UnoType<table::XCellRange>::get(); }
+ virtual sal_Bool SAL_CALL hasElements() override { return true; }
+ // XEnumerationAccess
+ virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration() override { return new SingleRangeEnumeration( m_xRange ); }
+
+};
+
+class RangesEnumerationImpl : public EnumerationHelperImpl
+{
+ bool mbIsRows;
+ bool mbIsColumns;
+public:
+ /// @throws uno::RuntimeException
+ RangesEnumerationImpl( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, bool bIsRows, bool bIsColumns ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), mbIsRows( bIsRows ), mbIsColumns( bIsColumns ) {}
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ return lcl_makeRange( m_xParent, m_xContext, m_xEnumeration->nextElement(), mbIsRows, mbIsColumns );
+ }
+};
+
+class ScVbaRangeAreas : public ScVbaCollectionBaseImpl
+{
+ bool mbIsRows;
+ bool mbIsColumns;
+public:
+ ScVbaRangeAreas( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XIndexAccess >& xIndexAccess, bool bIsRows, bool bIsColumns ) : ScVbaCollectionBaseImpl( xParent, xContext, xIndexAccess ), mbIsRows( bIsRows ), mbIsColumns( bIsColumns ) {}
+
+ // XEnumerationAccess
+ virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration() override;
+
+ // XElementAccess
+ virtual uno::Type SAL_CALL getElementType() override { return cppu::UnoType<excel::XRange>::get(); }
+
+ virtual uno::Any createCollectionObject( const uno::Any& aSource ) override;
+
+ virtual OUString getServiceImplName() override { return OUString(); }
+
+ virtual uno::Sequence< OUString > getServiceNames() override { return uno::Sequence< OUString >(); }
+
+};
+
+}
+
+uno::Reference< container::XEnumeration > SAL_CALL
+ScVbaRangeAreas::createEnumeration()
+{
+ uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
+ return new RangesEnumerationImpl( mxParent, mxContext, xEnumAccess->createEnumeration(), mbIsRows, mbIsColumns );
+}
+
+uno::Any
+ScVbaRangeAreas::createCollectionObject( const uno::Any& aSource )
+{
+ return lcl_makeRange( mxParent, mxContext, aSource, mbIsRows, mbIsColumns );
+}
+
+// assume that xIf is in fact a ScCellRangesBase
+/// @throws uno::RuntimeException
+static ScDocShell*
+getDocShellFromIf( const uno::Reference< uno::XInterface >& xIf )
+{
+ ScCellRangesBase* pUno = comphelper::getFromUnoTunnel<ScCellRangesBase>( xIf );
+ if ( !pUno )
+ throw uno::RuntimeException("Failed to access underlying uno range object" );
+ return pUno->GetDocShell();
+}
+
+/// @throws uno::RuntimeException
+static ScDocShell*
+getDocShellFromRange( const uno::Reference< table::XCellRange >& xRange )
+{
+ // need the ScCellRangesBase to get docshell
+ uno::Reference< uno::XInterface > xIf( xRange );
+ return getDocShellFromIf(xIf );
+}
+
+/// @throws uno::RuntimeException
+static ScDocShell*
+getDocShellFromRanges( const uno::Reference< sheet::XSheetCellRangeContainer >& xRanges )
+{
+ // need the ScCellRangesBase to get docshell
+ uno::Reference< uno::XInterface > xIf( xRanges );
+ return getDocShellFromIf(xIf );
+}
+
+/// @throws uno::RuntimeException
+static uno::Reference< frame::XModel > getModelFromXIf( const uno::Reference< uno::XInterface >& xIf )
+{
+ ScDocShell* pDocShell = getDocShellFromIf(xIf );
+ return pDocShell->GetModel();
+}
+
+/// @throws uno::RuntimeException
+static uno::Reference< frame::XModel > getModelFromRange( const uno::Reference< table::XCellRange >& xRange )
+{
+ // the XInterface for getImplementation can be any derived interface, no need for queryInterface
+ uno::Reference< uno::XInterface > xIf( xRange );
+ return getModelFromXIf( xIf );
+}
+
+static ScDocument&
+getDocumentFromRange( const uno::Reference< table::XCellRange >& xRange )
+{
+ ScDocShell* pDocShell = getDocShellFromRange( xRange );
+ if ( !pDocShell )
+ throw uno::RuntimeException("Failed to access underlying docshell from uno range object" );
+ ScDocument& rDoc = pDocShell->GetDocument();
+ return rDoc;
+}
+
+ScDocument&
+ScVbaRange::getScDocument()
+{
+ if ( mxRanges.is() )
+ {
+ uno::Reference< container::XIndexAccess > xIndex( mxRanges, uno::UNO_QUERY_THROW );
+ uno::Reference< table::XCellRange > xRange( xIndex->getByIndex( 0 ), uno::UNO_QUERY_THROW );
+ return getDocumentFromRange( xRange );
+ }
+ return getDocumentFromRange( mxRange );
+}
+
+ScDocShell*
+ScVbaRange::getScDocShell()
+{
+ if ( mxRanges.is() )
+ {
+ uno::Reference< container::XIndexAccess > xIndex( mxRanges, uno::UNO_QUERY_THROW );
+ uno::Reference< table::XCellRange > xRange( xIndex->getByIndex( 0 ), uno::UNO_QUERY_THROW );
+ return getDocShellFromRange( xRange );
+ }
+ return getDocShellFromRange( mxRange );
+}
+
+ScVbaRange* ScVbaRange::getImplementation( const uno::Reference< excel::XRange >& rxRange )
+{
+ // FIXME: always save to use dynamic_cast? Or better to (implement and) use XTunnel?
+ return dynamic_cast< ScVbaRange* >( rxRange.get() );
+}
+
+uno::Reference< frame::XModel > ScVbaRange::getUnoModel()
+{
+ if( ScDocShell* pDocShell = getScDocShell() )
+ return pDocShell->GetModel();
+ throw uno::RuntimeException();
+}
+
+uno::Reference< frame::XModel > ScVbaRange::getUnoModel( const uno::Reference< excel::XRange >& rxRange )
+{
+ if( ScVbaRange* pScVbaRange = getImplementation( rxRange ) )
+ return pScVbaRange->getUnoModel();
+ throw uno::RuntimeException();
+}
+
+const ScRangeList& ScVbaRange::getScRangeList()
+{
+ if( ScCellRangesBase* pScRangesBase = getCellRangesBase() )
+ return pScRangesBase->GetRangeList();
+ throw uno::RuntimeException("Cannot obtain UNO range implementation object" );
+}
+
+const ScRangeList& ScVbaRange::getScRangeList( const uno::Reference< excel::XRange >& rxRange )
+{
+ if( ScVbaRange* pScVbaRange = getImplementation( rxRange ) )
+ return pScVbaRange->getScRangeList();
+ throw uno::RuntimeException("Cannot obtain VBA range implementation object" );
+}
+
+namespace {
+
+class NumFormatHelper
+{
+ uno::Reference< util::XNumberFormatsSupplier > mxSupplier;
+ uno::Reference< beans::XPropertySet > mxRangeProps;
+ uno::Reference< util::XNumberFormats > mxFormats;
+public:
+ explicit NumFormatHelper( const uno::Reference< table::XCellRange >& xRange )
+ {
+ mxSupplier.set( getModelFromRange( xRange ), uno::UNO_QUERY_THROW );
+ mxRangeProps.set( xRange, uno::UNO_QUERY_THROW);
+ mxFormats = mxSupplier->getNumberFormats();
+ }
+ uno::Reference< beans::XPropertySet > getNumberProps()
+ {
+ tools::Long nIndexKey = 0;
+ uno::Any aValue = mxRangeProps->getPropertyValue( "NumberFormat" );
+ aValue >>= nIndexKey;
+
+ if ( mxFormats.is() )
+ return mxFormats->getByKey( nIndexKey );
+ return uno::Reference< beans::XPropertySet > ();
+ }
+
+ bool isBooleanType()
+ {
+
+ return (getNumberFormat() & util::NumberFormat::LOGICAL) != 0;
+ }
+
+ bool isDateType()
+ {
+ sal_Int16 nType = getNumberFormat();
+ return ( nType & util::NumberFormat::DATETIME ) != 0;
+ }
+
+ OUString getNumberFormatString()
+ {
+ uno::Reference< uno::XInterface > xIf( mxRangeProps, uno::UNO_QUERY_THROW );
+ ScCellRangesBase* pUnoCellRange = comphelper::getFromUnoTunnel<ScCellRangesBase>( xIf );
+ if ( pUnoCellRange )
+ {
+
+ SfxItemSet* pDataSet = excel::ScVbaCellRangeAccess::GetDataSet( pUnoCellRange );
+ SfxItemState eState = pDataSet->GetItemState( ATTR_VALUE_FORMAT);
+ // one of the cells in the range is not like the other ;-)
+ // so return a zero length format to indicate that
+ if ( eState == SfxItemState::DONTCARE )
+ return OUString();
+ }
+
+ uno::Reference< beans::XPropertySet > xNumberProps( getNumberProps(), uno::UNO_SET_THROW );
+ OUString aFormatString;
+ uno::Any aString = xNumberProps->getPropertyValue( "FormatString" );
+ aString >>= aFormatString;
+ return aFormatString;
+ }
+
+ sal_Int16 getNumberFormat()
+ {
+ uno::Reference< beans::XPropertySet > xNumberProps = getNumberProps();
+ sal_Int16 nType = ::comphelper::getINT16(
+ xNumberProps->getPropertyValue( "Type" ) );
+ return nType;
+ }
+
+ void setNumberFormat( const OUString& rFormat )
+ {
+ // #163288# treat "General" as "Standard" format
+ sal_Int32 nNewIndex = 0;
+ if( !rFormat.equalsIgnoreAsciiCase( "General" ) )
+ {
+ lang::Locale aLocale;
+ uno::Reference< beans::XPropertySet > xNumProps = getNumberProps();
+ xNumProps->getPropertyValue( "Locale" ) >>= aLocale;
+ nNewIndex = mxFormats->queryKey( rFormat, aLocale, false );
+ if ( nNewIndex == -1 ) // format not defined
+ nNewIndex = mxFormats->addNew( rFormat, aLocale );
+ }
+ mxRangeProps->setPropertyValue( "NumberFormat", uno::Any( nNewIndex ) );
+ }
+
+ void setNumberFormat( sal_Int16 nType )
+ {
+ uno::Reference< beans::XPropertySet > xNumberProps = getNumberProps();
+ lang::Locale aLocale;
+ xNumberProps->getPropertyValue( "Locale" ) >>= aLocale;
+ uno::Reference<util::XNumberFormatTypes> xTypes( mxFormats, uno::UNO_QUERY );
+ if ( xTypes.is() )
+ {
+ sal_Int32 nNewIndex = xTypes->getStandardFormat( nType, aLocale );
+ mxRangeProps->setPropertyValue( "NumberFormat", uno::Any( nNewIndex ) );
+ }
+ }
+
+};
+
+struct CellPos
+{
+ CellPos( sal_Int32 nRow, sal_Int32 nCol, sal_Int32 nArea ):m_nRow(nRow), m_nCol(nCol), m_nArea( nArea ) {};
+sal_Int32 m_nRow;
+sal_Int32 m_nCol;
+sal_Int32 m_nArea;
+};
+
+}
+
+typedef ::cppu::WeakImplHelper< container::XEnumeration > CellsEnumeration_BASE;
+typedef ::std::vector< CellPos > vCellPos;
+
+namespace {
+
+// #FIXME - QUICK
+// we could probably could and should modify CellsEnumeration below
+// to handle rows and columns (but I do this separately for now
+// and... this class only handles single areas (does it have to handle
+// multi area ranges??)
+class ColumnsRowEnumeration: public CellsEnumeration_BASE
+{
+ uno::Reference< excel::XRange > mxRange;
+ sal_Int32 mMaxElems;
+ sal_Int32 mCurElem;
+
+public:
+ ColumnsRowEnumeration( const uno::Reference< excel::XRange >& xRange, sal_Int32 nElems ) : mxRange( xRange ), mMaxElems( nElems ), mCurElem( 0 )
+ {
+ }
+
+ virtual sal_Bool SAL_CALL hasMoreElements() override { return mCurElem < mMaxElems; }
+
+ virtual uno::Any SAL_CALL nextElement() override
+ {
+ if ( !hasMoreElements() )
+ throw container::NoSuchElementException();
+ sal_Int32 vbaIndex = 1 + mCurElem++;
+ return uno::Any( mxRange->Item( uno::Any( vbaIndex ), uno::Any() ) );
+ }
+};
+
+class CellsEnumeration : public CellsEnumeration_BASE
+{
+ uno::WeakReference< XHelperInterface > mxParent;
+ uno::Reference< uno::XComponentContext > mxContext;
+ uno::Reference< XCollection > m_xAreas;
+ vCellPos m_CellPositions;
+ vCellPos::const_iterator m_it;
+
+ /// @throws uno::RuntimeException
+ uno::Reference< table::XCellRange > getArea( sal_Int32 nVBAIndex )
+ {
+ if ( nVBAIndex < 1 || nVBAIndex > m_xAreas->getCount() )
+ throw uno::RuntimeException();
+ uno::Reference< excel::XRange > xRange( m_xAreas->Item( uno::Any(nVBAIndex), uno::Any() ), uno::UNO_QUERY_THROW );
+ uno::Reference< table::XCellRange > xCellRange( ScVbaRange::getCellRange( xRange ), uno::UNO_QUERY_THROW );
+ return xCellRange;
+ }
+
+ void populateArea( sal_Int32 nVBAIndex )
+ {
+ uno::Reference< table::XCellRange > xRange = getArea( nVBAIndex );
+ uno::Reference< table::XColumnRowRange > xColumnRowRange(xRange, uno::UNO_QUERY_THROW );
+ sal_Int32 nRowCount = xColumnRowRange->getRows()->getCount();
+ sal_Int32 nColCount = xColumnRowRange->getColumns()->getCount();
+ for ( sal_Int32 i=0; i<nRowCount; ++i )
+ {
+ for ( sal_Int32 j=0; j<nColCount; ++j )
+ m_CellPositions.emplace_back( i,j,nVBAIndex );
+ }
+ }
+public:
+ CellsEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< XCollection >& xAreas ): mxParent( xParent ), mxContext( xContext ), m_xAreas( xAreas )
+ {
+ sal_Int32 nItems = m_xAreas->getCount();
+ for ( sal_Int32 index=1; index <= nItems; ++index )
+ {
+ populateArea( index );
+ }
+ m_it = m_CellPositions.begin();
+ }
+ virtual sal_Bool SAL_CALL hasMoreElements() override { return m_it != m_CellPositions.end(); }
+
+ virtual uno::Any SAL_CALL nextElement() override
+ {
+ if ( !hasMoreElements() )
+ throw container::NoSuchElementException();
+ CellPos aPos = *m_it++;
+
+ uno::Reference< table::XCellRange > xRangeArea = getArea( aPos.m_nArea );
+ uno::Reference< table::XCellRange > xCellRange( xRangeArea->getCellByPosition( aPos.m_nCol, aPos.m_nRow ), uno::UNO_QUERY_THROW );
+ return uno::Any( uno::Reference< excel::XRange >( new ScVbaRange( mxParent, mxContext, xCellRange ) ) );
+
+ }
+};
+
+}
+
+constexpr OUStringLiteral ISVISIBLE = u"IsVisible";
+const char EQUALS[] = "=";
+const char NOTEQUALS[] = "<>";
+const char GREATERTHAN[] = ">";
+const char GREATERTHANEQUALS[] = ">=";
+const char LESSTHAN[] = "<";
+const char LESSTHANEQUALS[] = "<=";
+constexpr OUStringLiteral STR_ERRORMESSAGE_APPLIESTOSINGLERANGEONLY(u"The command you chose cannot be performed with multiple selections.\nSelect a single range and click the command again");
+constexpr OUStringLiteral CELLSTYLE = u"CellStyle";
+
+namespace {
+
+class CellValueSetter : public ValueSetter
+{
+protected:
+ uno::Any maValue;
+public:
+ explicit CellValueSetter( const uno::Any& aValue );
+ virtual bool processValue( const uno::Any& aValue, const uno::Reference< table::XCell >& xCell ) override;
+ virtual void visitNode( sal_Int32 x, sal_Int32 y, const uno::Reference< table::XCell >& xCell ) override;
+
+};
+
+}
+
+CellValueSetter::CellValueSetter( const uno::Any& aValue ): maValue( aValue ) {}
+
+void
+CellValueSetter::visitNode( sal_Int32 /*i*/, sal_Int32 /*j*/, const uno::Reference< table::XCell >& xCell )
+{
+ processValue( maValue, xCell );
+}
+
+bool
+CellValueSetter::processValue( const uno::Any& aValue, const uno::Reference< table::XCell >& xCell )
+{
+
+ bool isExtracted = false;
+ switch ( aValue.getValueTypeClass() )
+ {
+ case uno::TypeClass_BOOLEAN:
+ {
+ bool bState = false;
+ if ( aValue >>= bState )
+ {
+ uno::Reference< table::XCellRange > xRange( xCell, uno::UNO_QUERY_THROW );
+ if ( bState )
+ xCell->setValue( double(1) );
+ else
+ xCell->setValue( double(0) );
+ NumFormatHelper cellNumFormat( xRange );
+ cellNumFormat.setNumberFormat( util::NumberFormat::LOGICAL );
+ }
+ break;
+ }
+ case uno::TypeClass_STRING:
+ {
+ OUString aString;
+ if ( aValue >>= aString )
+ {
+ // The required behavior for a string value is:
+ // 1. If the first character is a single quote, use the rest as a string cell, regardless of the cell's number format.
+ // 2. Otherwise, if the cell's number format is "text", use the string value as a string cell.
+ // 3. Otherwise, parse the string value in English locale, and apply a corresponding number format with the cell's locale
+ // if the cell's number format was "General".
+ // Case 1 is handled here, the rest in ScCellObj::InputEnglishString
+
+ if ( aString.toChar() == '\'' ) // case 1 - handle with XTextRange
+ {
+ OUString aRemainder( aString.copy(1) ); // strip the quote
+ uno::Reference< text::XTextRange > xTextRange( xCell, uno::UNO_QUERY_THROW );
+ xTextRange->setString( aRemainder );
+ }
+ else
+ {
+ // call implementation method InputEnglishString
+ ScCellObj* pCellObj = dynamic_cast< ScCellObj* >( xCell.get() );
+ if ( pCellObj )
+ pCellObj->InputEnglishString( aString );
+ }
+ }
+ else
+ isExtracted = false;
+ break;
+ }
+ default:
+ {
+ double nDouble = 0.0;
+ if ( aValue >>= nDouble )
+ {
+ uno::Reference< table::XCellRange > xRange( xCell, uno::UNO_QUERY_THROW );
+ NumFormatHelper cellFormat( xRange );
+ // If we are setting a number and the cell types was logical
+ // then we need to reset the logical format. ( see case uno::TypeClass_BOOLEAN:
+ // handling above )
+ if ( cellFormat.isBooleanType() )
+ cellFormat.setNumberFormat("General");
+ xCell->setValue( nDouble );
+ }
+ else
+ isExtracted = false;
+ break;
+ }
+ }
+ return isExtracted;
+
+}
+
+namespace {
+
+class CellValueGetter : public ValueGetter
+{
+protected:
+ uno::Any maValue;
+public:
+ CellValueGetter() {}
+ virtual void visitNode( sal_Int32 x, sal_Int32 y, const uno::Reference< table::XCell >& xCell ) override;
+ virtual void processValue( const uno::Any& aValue ) override;
+ const uno::Any& getValue() const override { return maValue; }
+
+};
+
+}
+
+void
+CellValueGetter::processValue( const uno::Any& aValue )
+{
+ maValue = aValue;
+}
+void CellValueGetter::visitNode( sal_Int32 /*x*/, sal_Int32 /*y*/, const uno::Reference< table::XCell >& xCell )
+{
+ uno::Any aValue;
+ table::CellContentType eType = xCell->getType();
+ if( eType == table::CellContentType_VALUE || eType == table::CellContentType_FORMULA )
+ {
+ if ( eType == table::CellContentType_FORMULA )
+ {
+
+ OUString sFormula = xCell->getFormula();
+ if ( sFormula == "=TRUE()" )
+ aValue <<= true;
+ else if ( sFormula == "=FALSE()" )
+ aValue <<= false;
+ else
+ {
+ uno::Reference< beans::XPropertySet > xProp( xCell, uno::UNO_QUERY_THROW );
+
+ sal_Int32 nResultType = sheet::FormulaResult::VALUE;
+ // some formulas give textual results
+ xProp->getPropertyValue( "FormulaResultType2" ) >>= nResultType;
+
+ if ( nResultType == sheet::FormulaResult::STRING )
+ {
+ uno::Reference< text::XTextRange > xTextRange(xCell, ::uno::UNO_QUERY_THROW);
+ aValue <<= xTextRange->getString();
+ }
+ else
+ aValue <<= xCell->getValue();
+ }
+ }
+ else
+ {
+ uno::Reference< table::XCellRange > xRange( xCell, uno::UNO_QUERY_THROW );
+ NumFormatHelper cellFormat( xRange );
+ if ( cellFormat.isBooleanType() )
+ aValue <<= ( xCell->getValue() != 0.0 );
+ else if ( cellFormat.isDateType() )
+ aValue <<= bridge::oleautomation::Date( xCell->getValue() );
+ else
+ aValue <<= xCell->getValue();
+ }
+ }
+ if( eType == table::CellContentType_TEXT )
+ {
+ uno::Reference< text::XTextRange > xTextRange(xCell, ::uno::UNO_QUERY_THROW);
+ aValue <<= xTextRange->getString();
+ }
+ processValue( aValue );
+}
+
+namespace {
+
+class CellFormulaValueSetter : public CellValueSetter
+{
+private:
+ ScDocument& m_rDoc;
+ formula::FormulaGrammar::Grammar m_eGrammar;
+public:
+ CellFormulaValueSetter( const uno::Any& aValue, ScDocument& rDoc, formula::FormulaGrammar::Grammar eGram ):CellValueSetter( aValue ), m_rDoc( rDoc ), m_eGrammar( eGram ){}
+protected:
+ bool processValue( const uno::Any& aValue, const uno::Reference< table::XCell >& xCell ) override
+ {
+ OUString sFormula;
+ double aDblValue = 0.0;
+ if ( aValue >>= sFormula )
+ {
+ // convert to GRAM_API style grammar because XCell::setFormula
+ // always compile it in that grammar. Perhaps
+ // css.sheet.FormulaParser should be used in future to directly
+ // pass formula tokens when that API stabilizes.
+ if ( m_eGrammar != formula::FormulaGrammar::GRAM_API && ( o3tl::starts_with(o3tl::trim(sFormula), u"=") ) )
+ {
+ uno::Reference< uno::XInterface > xIf( xCell, uno::UNO_QUERY_THROW );
+ ScCellRangesBase* pUnoRangesBase = dynamic_cast< ScCellRangesBase* >( xIf.get() );
+ if ( pUnoRangesBase )
+ {
+ const ScRangeList& rCellRanges = pUnoRangesBase->GetRangeList();
+ if (!rCellRanges.empty())
+ {
+ ScCompiler aCompiler( m_rDoc, rCellRanges.front().aStart, m_eGrammar );
+ // compile the string in the format passed in
+ std::unique_ptr<ScTokenArray> pArray(aCompiler.CompileString(sFormula));
+ // convert to API grammar
+ aCompiler.SetGrammar( formula::FormulaGrammar::GRAM_API );
+ OUString sConverted;
+ aCompiler.CreateStringFromTokenArray(sConverted);
+ sFormula = EQUALS + sConverted;
+ }
+ }
+ }
+
+ xCell->setFormula( sFormula );
+ return true;
+ }
+ else if ( aValue >>= aDblValue )
+ {
+ xCell->setValue( aDblValue );
+ return true;
+ }
+ return false;
+ }
+
+};
+
+class CellFormulaValueGetter : public CellValueGetter
+{
+private:
+ ScDocument& m_rDoc;
+ formula::FormulaGrammar::Grammar m_eGrammar;
+public:
+ CellFormulaValueGetter(ScDocument& rDoc, formula::FormulaGrammar::Grammar eGram ) : m_rDoc( rDoc ), m_eGrammar( eGram ) {}
+ virtual void visitNode( sal_Int32 /*x*/, sal_Int32 /*y*/, const uno::Reference< table::XCell >& xCell ) override
+ {
+ uno::Any aValue;
+ aValue <<= xCell->getFormula();
+ // XCell::getFormula() returns the formula in API grammar, convert.
+ if ((xCell->getType() == table::CellContentType_FORMULA)
+ && m_eGrammar != formula::FormulaGrammar::GRAM_API)
+ {
+ uno::Reference< uno::XInterface > xIf( xCell, uno::UNO_QUERY_THROW );
+ ScCellRangesBase* pUnoRangesBase = dynamic_cast< ScCellRangesBase* >( xIf.get() );
+ if (pUnoRangesBase)
+ {
+ OUString sVal;
+ aValue >>= sVal;
+ const ScRangeList& rCellRanges = pUnoRangesBase->GetRangeList();
+ if (!rCellRanges.empty())
+ {
+ // Compile string from API grammar.
+ ScCompiler aCompiler( m_rDoc, rCellRanges.front().aStart, formula::FormulaGrammar::GRAM_API );
+ std::unique_ptr<ScTokenArray> pArray(aCompiler.CompileString(sVal));
+ // Convert to desired grammar.
+ aCompiler.SetGrammar( m_eGrammar );
+ OUString sConverted;
+ aCompiler.CreateStringFromTokenArray(sConverted);
+ sVal = EQUALS + sConverted;
+ aValue <<= sVal;
+ }
+ }
+ }
+
+ processValue( aValue );
+ }
+
+};
+
+class Dim2ArrayValueGetter : public ArrayVisitor
+{
+protected:
+ uno::Any maValue;
+ ValueGetter& mValueGetter;
+ void processValue( sal_Int32 x, sal_Int32 y, const uno::Any& aValue )
+ {
+ uno::Sequence< uno::Sequence< uno::Any > >& aMatrix = const_cast<css::uno::Sequence<css::uno::Sequence<css::uno::Any>> &>(*o3tl::doAccess<uno::Sequence<uno::Sequence<uno::Any>>>(maValue));
+ aMatrix.getArray()[x].getArray()[y] = aValue;
+ }
+
+public:
+ Dim2ArrayValueGetter(sal_Int32 nRowCount, sal_Int32 nColCount, ValueGetter& rValueGetter ): mValueGetter(rValueGetter)
+ {
+ uno::Sequence< uno::Sequence< uno::Any > > aMatrix;
+ aMatrix.realloc( nRowCount );
+ auto pMatrix = aMatrix.getArray();
+ for ( sal_Int32 index = 0; index < nRowCount; ++index )
+ pMatrix[index].realloc( nColCount );
+ maValue <<= aMatrix;
+ }
+ void visitNode( sal_Int32 x, sal_Int32 y, const uno::Reference< table::XCell >& xCell ) override
+
+ {
+ mValueGetter.visitNode( x, y, xCell );
+ processValue( x, y, mValueGetter.getValue() );
+ }
+ const uno::Any& getValue() const { return maValue; }
+
+};
+
+}
+
+constexpr OUStringLiteral sNA = u"#N/A";
+
+namespace {
+
+class Dim1ArrayValueSetter : public ArrayVisitor
+{
+ uno::Sequence< uno::Any > aMatrix;
+ sal_Int32 nColCount;
+ ValueSetter& mCellValueSetter;
+public:
+ Dim1ArrayValueSetter( const uno::Any& aValue, ValueSetter& rCellValueSetter ):mCellValueSetter( rCellValueSetter )
+ {
+ aValue >>= aMatrix;
+ nColCount = aMatrix.getLength();
+ }
+ virtual void visitNode( sal_Int32 /*x*/, sal_Int32 y, const uno::Reference< table::XCell >& xCell ) override
+ {
+ if ( y < nColCount )
+ mCellValueSetter.processValue( aMatrix[ y ], xCell );
+ else
+ mCellValueSetter.processValue( uno::Any( OUString(sNA) ), xCell );
+ }
+};
+
+class Dim2ArrayValueSetter : public ArrayVisitor
+{
+ uno::Sequence< uno::Sequence< uno::Any > > aMatrix;
+ ValueSetter& mCellValueSetter;
+ sal_Int32 nRowCount;
+ sal_Int32 nColCount;
+public:
+ Dim2ArrayValueSetter( const uno::Any& aValue, ValueSetter& rCellValueSetter ) : mCellValueSetter( rCellValueSetter )
+ {
+ aValue >>= aMatrix;
+ nRowCount = aMatrix.getLength();
+ nColCount = aMatrix[0].getLength();
+ }
+
+ virtual void visitNode( sal_Int32 x, sal_Int32 y, const uno::Reference< table::XCell >& xCell ) override
+ {
+ if ( x < nRowCount && y < nColCount )
+ mCellValueSetter.processValue( aMatrix[ x ][ y ], xCell );
+ else
+ mCellValueSetter.processValue( uno::Any( OUString(sNA) ), xCell );
+
+ }
+};
+
+class RangeProcessor
+{
+public:
+ virtual void process( const uno::Reference< excel::XRange >& xRange ) = 0;
+
+protected:
+ ~RangeProcessor() {}
+};
+
+class RangeValueProcessor : public RangeProcessor
+{
+ const uno::Any& m_aVal;
+public:
+ explicit RangeValueProcessor( const uno::Any& rVal ):m_aVal( rVal ) {}
+ virtual ~RangeValueProcessor() {}
+ virtual void process( const uno::Reference< excel::XRange >& xRange ) override
+ {
+ xRange->setValue( m_aVal );
+ }
+};
+
+class RangeFormulaProcessor : public RangeProcessor
+{
+ const uno::Any& m_aVal;
+public:
+ explicit RangeFormulaProcessor( const uno::Any& rVal ):m_aVal( rVal ) {}
+ virtual ~RangeFormulaProcessor() {}
+ virtual void process( const uno::Reference< excel::XRange >& xRange ) override
+ {
+ xRange->setFormula( m_aVal );
+ }
+};
+
+class RangeCountProcessor : public RangeProcessor
+{
+ sal_Int32 nCount;
+public:
+ RangeCountProcessor():nCount(0){}
+ virtual ~RangeCountProcessor() {}
+ virtual void process( const uno::Reference< excel::XRange >& xRange ) override
+ {
+ nCount = nCount + xRange->getCount();
+ }
+ sal_Int32 value() { return nCount; }
+};
+class AreasVisitor
+{
+private:
+ uno::Reference< XCollection > m_Areas;
+public:
+ explicit AreasVisitor( const uno::Reference< XCollection >& rAreas ):m_Areas( rAreas ){}
+
+ void visit( RangeProcessor& processor )
+ {
+ if ( m_Areas.is() )
+ {
+ sal_Int32 nItems = m_Areas->getCount();
+ for ( sal_Int32 index=1; index <= nItems; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::Any(index), uno::Any() ), uno::UNO_QUERY_THROW );
+ processor.process( xRange );
+ }
+ }
+ }
+};
+
+class RangeHelper
+{
+ uno::Reference< table::XCellRange > m_xCellRange;
+
+public:
+ /// @throws uno::RuntimeException
+ explicit RangeHelper( const uno::Reference< table::XCellRange >& xCellRange ) : m_xCellRange( xCellRange )
+ {
+ if ( !m_xCellRange.is() )
+ throw uno::RuntimeException();
+ }
+ /// @throws uno::RuntimeException
+ explicit RangeHelper( const uno::Any& rCellRange )
+ {
+ m_xCellRange.set(rCellRange, uno::UNO_QUERY_THROW);
+ }
+ /// @throws uno::RuntimeException
+ uno::Reference< sheet::XSheetCellRange > getSheetCellRange() const
+ {
+ return uno::Reference< sheet::XSheetCellRange >(m_xCellRange, uno::UNO_QUERY_THROW);
+ }
+ /// @throws uno::RuntimeException
+ uno::Reference< sheet::XSpreadsheet > getSpreadSheet() const
+ {
+ return getSheetCellRange()->getSpreadsheet();
+ }
+
+ /// @throws uno::RuntimeException
+ uno::Reference< table::XCellRange > getCellRangeFromSheet() const
+ {
+ return uno::Reference< table::XCellRange >(getSpreadSheet(), uno::UNO_QUERY_THROW );
+ }
+
+ /// @throws uno::RuntimeException
+ uno::Reference< sheet::XCellRangeAddressable > getCellRangeAddressable() const
+ {
+ return uno::Reference< sheet::XCellRangeAddressable >(m_xCellRange, ::uno::UNO_QUERY_THROW);
+
+ }
+
+ /// @throws uno::RuntimeException
+ uno::Reference< sheet::XSheetCellCursor > getSheetCellCursor() const
+ {
+ return uno::Reference< sheet::XSheetCellCursor >( getSpreadSheet()->createCursorByRange( getSheetCellRange() ), uno::UNO_SET_THROW );
+ }
+
+ static uno::Reference< excel::XRange > createRangeFromRange( const uno::Reference< XHelperInterface >& xParent, const uno::Reference<uno::XComponentContext >& xContext,
+ const uno::Reference< table::XCellRange >& xRange, const uno::Reference< sheet::XCellRangeAddressable >& xCellRangeAddressable )
+ {
+ const table::CellRangeAddress aRA( xCellRangeAddressable->getRangeAddress());
+ return uno::Reference< excel::XRange >( new ScVbaRange( xParent, xContext,
+ xRange->getCellRangeByPosition( aRA.StartColumn, aRA.StartRow, aRA.EndColumn, aRA.EndRow)));
+ }
+
+};
+
+}
+
+bool
+ScVbaRange::getCellRangesForAddress( ScRefFlags& rResFlags, std::u16string_view sAddress, ScDocShell* pDocSh, ScRangeList& rCellRanges, formula::FormulaGrammar::AddressConvention eConv, char cDelimiter )
+{
+
+ if ( pDocSh )
+ {
+ ScDocument& rDoc = pDocSh->GetDocument();
+ rResFlags = rCellRanges.Parse( sAddress, rDoc, eConv, 0, cDelimiter );
+ if ( rResFlags & ScRefFlags::VALID )
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool getScRangeListForAddress( const OUString& sName, ScDocShell* pDocSh, const ScRange& refRange, ScRangeList& aCellRanges, formula::FormulaGrammar::AddressConvention aConv )
+{
+ // see if there is a match with a named range
+ uno::Reference< beans::XPropertySet > xProps( pDocSh->GetModel(), uno::UNO_QUERY_THROW );
+ uno::Reference< container::XNameAccess > xNameAccess( xProps->getPropertyValue( "NamedRanges" ), uno::UNO_QUERY_THROW );
+ // Strange enough you can have Range( "namedRange1, namedRange2, etc," )
+ // loop around each ',' separated name
+ std::vector< OUString > vNames;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ OUString aToken = sName.getToken( 0, ',', nIndex );
+ vNames.push_back( aToken );
+ } while ( nIndex >= 0 );
+
+ if ( vNames.empty() )
+ vNames.push_back( sName );
+
+ for ( const auto& rName : vNames )
+ {
+ formula::FormulaGrammar::AddressConvention eConv = aConv;
+ // spaces are illegal ( but the user of course can enter them )
+ OUString sAddress = rName.trim();
+ // if a local name ( on the active sheet ) exists this will
+ // take precedence over a global with the same name
+ if ( !xNameAccess->hasByName( sAddress ) )
+ {
+ // try a local name
+ ScDocument& rDoc = pDocSh->GetDocument();
+ SCTAB nCurTab = ScDocShell::GetCurTab();
+ ScRangeName* pRangeName = rDoc.GetRangeName(nCurTab);
+ if (pRangeName)
+ {
+ // TODO: Handle local names correctly:
+ // bool bLocalName = pRangeName->findByUpperName(ScGlobal::getCharClass().uppercase(sAddress)) != nullptr;
+ }
+ }
+ char aChar = 0;
+ if ( xNameAccess->hasByName( sAddress ) )
+ {
+ uno::Reference< sheet::XNamedRange > xNamed( xNameAccess->getByName( sAddress ), uno::UNO_QUERY_THROW );
+ sAddress = xNamed->getContent();
+ // As the address comes from OOO, the addressing
+ // style is may not be XL_A1
+ eConv = pDocSh->GetDocument().GetAddressConvention();
+ aChar = ';';
+ }
+
+ ScRefFlags nFlags = ScRefFlags::ZERO;
+ if ( !ScVbaRange::getCellRangesForAddress( nFlags, sAddress, pDocSh, aCellRanges, eConv, aChar ) )
+ return false;
+
+ bool bTabFromReferrer = !( nFlags & ScRefFlags::TAB_3D );
+
+ for ( size_t i = 0, nRanges = aCellRanges.size(); i < nRanges; ++i )
+ {
+ ScRange & rRange = aCellRanges[ i ];
+ rRange.aStart.SetCol( refRange.aStart.Col() + rRange.aStart.Col() );
+ rRange.aStart.SetRow( refRange.aStart.Row() + rRange.aStart.Row() );
+ rRange.aStart.SetTab( bTabFromReferrer ? refRange.aStart.Tab() : rRange.aStart.Tab() );
+ rRange.aEnd.SetCol( refRange.aStart.Col() + rRange.aEnd.Col() );
+ rRange.aEnd.SetRow( refRange.aStart.Row() + rRange.aEnd.Row() );
+ rRange.aEnd.SetTab( bTabFromReferrer ? refRange.aEnd.Tab() : rRange.aEnd.Tab() );
+ }
+ }
+ return true;
+}
+
+/// @throws uno::RuntimeException
+static rtl::Reference<ScVbaRange>
+getRangeForName( const uno::Reference< uno::XComponentContext >& xContext, const OUString& sName, ScDocShell* pDocSh, const table::CellRangeAddress& pAddr, formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_XL_A1 )
+{
+ ScRangeList aCellRanges;
+ ScRange refRange;
+ ScUnoConversion::FillScRange( refRange, pAddr );
+ if ( !getScRangeListForAddress ( sName, pDocSh, refRange, aCellRanges, eConv ) )
+ throw uno::RuntimeException();
+ // Single range
+ if ( aCellRanges.size() == 1 )
+ {
+ uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pDocSh, aCellRanges.front() ) );
+ uno::Reference< XHelperInterface > xFixThisParent = excel::getUnoSheetModuleObj( xRange );
+ return new ScVbaRange( xFixThisParent, xContext, xRange );
+ }
+ uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pDocSh, aCellRanges ) );
+
+ uno::Reference< XHelperInterface > xFixThisParent = excel::getUnoSheetModuleObj( xRanges );
+ return new ScVbaRange( xFixThisParent, xContext, xRanges );
+}
+
+namespace {
+
+/// @throws uno::RuntimeException
+template< typename RangeType >
+table::CellRangeAddress lclGetRangeAddress( const uno::Reference< RangeType >& rxCellRange )
+{
+ return uno::Reference< sheet::XCellRangeAddressable >( rxCellRange, uno::UNO_QUERY_THROW )->getRangeAddress();
+}
+
+/// @throws uno::RuntimeException
+void lclClearRange( const uno::Reference< table::XCellRange >& rxCellRange )
+{
+ using namespace ::com::sun::star::sheet::CellFlags;
+ sal_Int32 const nFlags = VALUE | DATETIME | STRING | ANNOTATION | FORMULA | HARDATTR | STYLES | EDITATTR | FORMATTED;
+ uno::Reference< sheet::XSheetOperation > xSheetOperation( rxCellRange, uno::UNO_QUERY_THROW );
+ xSheetOperation->clearContents( nFlags );
+}
+
+/// @throws uno::RuntimeException
+uno::Reference< sheet::XSheetCellRange > lclExpandToMerged( const uno::Reference< table::XCellRange >& rxCellRange, bool bRecursive )
+{
+ uno::Reference< sheet::XSheetCellRange > xNewCellRange( rxCellRange, uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XSpreadsheet > xSheet( xNewCellRange->getSpreadsheet(), uno::UNO_SET_THROW );
+ table::CellRangeAddress aNewAddress = lclGetRangeAddress( xNewCellRange );
+ table::CellRangeAddress aOldAddress;
+ // expand as long as there are new merged ranges included
+ do
+ {
+ aOldAddress = aNewAddress;
+ uno::Reference< sheet::XSheetCellCursor > xCursor( xSheet->createCursorByRange( xNewCellRange ), uno::UNO_SET_THROW );
+ if (xCursor.is())
+ {
+ xCursor->collapseToMergedArea();
+ xNewCellRange.set( xCursor, uno::UNO_QUERY_THROW );
+ aNewAddress = lclGetRangeAddress( xNewCellRange );
+ }
+ }
+ while( bRecursive && (aOldAddress != aNewAddress) );
+ return xNewCellRange;
+}
+
+/// @throws uno::RuntimeException
+uno::Reference< sheet::XSheetCellRangeContainer > lclExpandToMerged( const uno::Reference< sheet::XSheetCellRangeContainer >& rxCellRanges )
+{
+ if( !rxCellRanges.is() )
+ throw uno::RuntimeException("Missing cell ranges object" );
+ sal_Int32 nCount = rxCellRanges->getCount();
+ if( nCount < 1 )
+ throw uno::RuntimeException("Missing cell ranges object" );
+
+ ScRangeList aScRanges;
+ for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex )
+ {
+ uno::Reference< table::XCellRange > xRange( rxCellRanges->getByIndex( nIndex ), uno::UNO_QUERY_THROW );
+ table::CellRangeAddress aRangeAddr = lclGetRangeAddress( lclExpandToMerged( xRange, /*bRecursive*/true ) );
+ ScRange aScRange;
+ ScUnoConversion::FillScRange( aScRange, aRangeAddr );
+ aScRanges.push_back( aScRange );
+ }
+ return new ScCellRangesObj( getDocShellFromRanges( rxCellRanges ), aScRanges );
+}
+
+/// @throws uno::RuntimeException
+void lclExpandAndMerge( const uno::Reference< table::XCellRange >& rxCellRange, bool bMerge )
+{
+ uno::Reference< util::XMergeable > xMerge( lclExpandToMerged( rxCellRange, true ), uno::UNO_QUERY_THROW );
+ // Calc cannot merge over merged ranges, always unmerge first
+ xMerge->merge( false );
+ if( !bMerge )
+ return;
+
+ // clear all contents of the covered cells (not the top-left cell)
+ table::CellRangeAddress aRangeAddr = lclGetRangeAddress( rxCellRange );
+ sal_Int32 nLastColIdx = aRangeAddr.EndColumn - aRangeAddr.StartColumn;
+ sal_Int32 nLastRowIdx = aRangeAddr.EndRow - aRangeAddr.StartRow;
+ // clear cells of top row, right of top-left cell
+ if( nLastColIdx > 0 )
+ lclClearRange( rxCellRange->getCellRangeByPosition( 1, 0, nLastColIdx, 0 ) );
+ // clear all rows below top row
+ if( nLastRowIdx > 0 )
+ lclClearRange( rxCellRange->getCellRangeByPosition( 0, 1, nLastColIdx, nLastRowIdx ) );
+ // merge the range
+ xMerge->merge( true );
+}
+
+/// @throws uno::RuntimeException
+util::TriState lclGetMergedState( const uno::Reference< table::XCellRange >& rxCellRange )
+{
+ /* 1) Check if range is completely inside one single merged range. To do
+ this, try to extend from top-left cell only (not from entire range).
+ This will exclude cases where this range consists of several merged
+ ranges (or parts of them). */
+ table::CellRangeAddress aRangeAddr = lclGetRangeAddress( rxCellRange );
+ uno::Reference< table::XCellRange > xTopLeft( rxCellRange->getCellRangeByPosition( 0, 0, 0, 0 ), uno::UNO_SET_THROW );
+ uno::Reference< sheet::XSheetCellRange > xExpanded( lclExpandToMerged( xTopLeft, false ), uno::UNO_SET_THROW );
+ table::CellRangeAddress aExpAddr = lclGetRangeAddress( xExpanded );
+ // check that expanded range has more than one cell (really merged)
+ if( ((aExpAddr.StartColumn < aExpAddr.EndColumn) || (aExpAddr.StartRow < aExpAddr.EndRow)) && ScUnoConversion::Contains( aExpAddr, aRangeAddr ) )
+ return util::TriState_YES;
+
+ /* 2) Check if this range contains any merged cells (completely or
+ partly). This seems to be hardly possible via API, as
+ XMergeable::getIsMerged() returns only true, if the top-left cell of a
+ merged range is part of this range, so cases where just the lower part
+ of a merged range is part of this range are not covered. */
+ ScRange aScRange;
+ ScUnoConversion::FillScRange( aScRange, aRangeAddr );
+ bool bHasMerged = getDocumentFromRange( rxCellRange ).HasAttrib( aScRange, HasAttrFlags::Merged | HasAttrFlags::Overlapped );
+ return bHasMerged ? util::TriState_INDETERMINATE : util::TriState_NO;
+}
+
+} // namespace
+
+css::uno::Reference< excel::XRange >
+ScVbaRange::getRangeObjectForName(
+ const uno::Reference< uno::XComponentContext >& xContext, const OUString& sRangeName,
+ ScDocShell* pDocSh, formula::FormulaGrammar::AddressConvention eConv )
+{
+ table::CellRangeAddress refAddr;
+ return getRangeForName( xContext, sRangeName, pDocSh, refAddr, eConv );
+}
+
+/// @throws uno::RuntimeException
+static table::CellRangeAddress getCellRangeAddressForVBARange( const uno::Any& aParam, ScDocShell* pDocSh )
+{
+ uno::Reference< table::XCellRange > xRangeParam;
+ switch ( aParam.getValueTypeClass() )
+ {
+ case uno::TypeClass_STRING:
+ {
+ OUString rString;
+ aParam >>= rString;
+ ScRangeList aCellRanges;
+ ScRange refRange;
+ if ( getScRangeListForAddress ( rString, pDocSh, refRange, aCellRanges ) )
+ {
+ if ( aCellRanges.size() == 1 )
+ {
+ table::CellRangeAddress aRangeAddress;
+ ScUnoConversion::FillApiRange( aRangeAddress, aCellRanges.front() );
+ return aRangeAddress;
+ }
+ }
+ }
+ break;
+
+ case uno::TypeClass_INTERFACE:
+ {
+ uno::Reference< excel::XRange > xRange;
+ aParam >>= xRange;
+ if ( xRange.is() )
+ xRange->getCellRange() >>= xRangeParam;
+ }
+ break;
+
+ default:
+ throw uno::RuntimeException("Can't extract CellRangeAddress from type" );
+ }
+ return lclGetRangeAddress( xRangeParam );
+}
+
+/// @throws uno::RuntimeException
+static uno::Reference< XCollection >
+lcl_setupBorders( const uno::Reference< excel::XRange >& xParentRange, const uno::Reference<uno::XComponentContext>& xContext, const uno::Reference< table::XCellRange >& xRange )
+{
+ uno::Reference< XHelperInterface > xParent( xParentRange, uno::UNO_QUERY_THROW );
+ ScDocument& rDoc = getDocumentFromRange(xRange);
+ ScVbaPalette aPalette( rDoc.GetDocumentShell() );
+ uno::Reference< XCollection > borders( new ScVbaBorders( xParent, xContext, xRange, aPalette ) );
+ return borders;
+}
+
+ScVbaRange::ScVbaRange( uno::Sequence< uno::Any> const & args,
+ uno::Reference< uno::XComponentContext> const & xContext ) : ScVbaRange_BASE( getXSomethingFromArgs< XHelperInterface >( args, 0 ), xContext, getXSomethingFromArgs< beans::XPropertySet >( args, 1, false ), getModelFromXIf( getXSomethingFromArgs< uno::XInterface >( args, 1 ) ), true ), mbIsRows( false ), mbIsColumns( false )
+{
+ mxRange.set( mxPropertySet, uno::UNO_QUERY );
+ mxRanges.set( mxPropertySet, uno::UNO_QUERY );
+ uno::Reference< container::XIndexAccess > xIndex;
+ if ( mxRange.is() )
+ {
+ xIndex = new SingleRangeIndexAccess( mxRange );
+ }
+ else if ( mxRanges.is() )
+ {
+ xIndex.set( mxRanges, uno::UNO_QUERY_THROW );
+ }
+ m_Areas = new ScVbaRangeAreas( mxParent, mxContext, xIndex, mbIsRows, mbIsColumns );
+}
+
+ScVbaRange::ScVbaRange( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< table::XCellRange >& xRange, bool bIsRows, bool bIsColumns )
+: ScVbaRange_BASE( xParent, xContext, uno::Reference< beans::XPropertySet >( xRange, uno::UNO_QUERY_THROW ), getModelFromRange( xRange), true ), mxRange( xRange ),
+ mbIsRows( bIsRows ),
+ mbIsColumns( bIsColumns )
+{
+ if ( !xContext.is() )
+ throw lang::IllegalArgumentException("context is not set ", uno::Reference< uno::XInterface >() , 1 );
+ if ( !xRange.is() )
+ throw lang::IllegalArgumentException("range is not set ", uno::Reference< uno::XInterface >() , 1 );
+
+ uno::Reference< container::XIndexAccess > xIndex( new SingleRangeIndexAccess( xRange ) );
+ m_Areas = new ScVbaRangeAreas( mxParent, mxContext, xIndex, mbIsRows, mbIsColumns );
+
+}
+
+ScVbaRange::ScVbaRange(const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< sheet::XSheetCellRangeContainer >& xRanges, bool bIsRows, bool bIsColumns)
+: ScVbaRange_BASE( xParent, xContext, uno::Reference< beans::XPropertySet >( xRanges, uno::UNO_QUERY_THROW ), getModelFromXIf( uno::Reference< uno::XInterface >( xRanges, uno::UNO_QUERY_THROW ) ), true ), mxRanges( xRanges ),mbIsRows( bIsRows ), mbIsColumns( bIsColumns )
+
+{
+ uno::Reference< container::XIndexAccess > xIndex( mxRanges, uno::UNO_QUERY_THROW );
+ m_Areas = new ScVbaRangeAreas( xParent, mxContext, xIndex, mbIsRows, mbIsColumns );
+
+}
+
+ScVbaRange::~ScVbaRange()
+{
+}
+
+uno::Reference< XCollection >& ScVbaRange::getBorders()
+{
+ if ( !m_Borders.is() )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::Any( sal_Int32(1) ), uno::Any() ), uno::UNO_QUERY_THROW );
+ m_Borders = lcl_setupBorders( this, mxContext, uno::Reference< table::XCellRange >( xRange->getCellRange(), uno::UNO_QUERY_THROW ) );
+ }
+ return m_Borders;
+}
+
+void
+ScVbaRange::visitArray( ArrayVisitor& visitor )
+{
+ ScDocShell* pDocSh = nullptr;
+ if(ScCellRangeObj* range = dynamic_cast<ScCellRangeObj*>(mxRange.get()))
+ pDocSh = range->GetDocShell();
+ if ( pDocSh )
+ pDocSh->LockPaint();
+ table::CellRangeAddress aRangeAddr = lclGetRangeAddress( mxRange );
+ sal_Int32 nRowCount = aRangeAddr.EndRow - aRangeAddr.StartRow + 1;
+ sal_Int32 nColCount = aRangeAddr.EndColumn - aRangeAddr.StartColumn + 1;
+ for ( sal_Int32 i=0; i<nRowCount; ++i )
+ {
+ for ( sal_Int32 j=0; j<nColCount; ++j )
+ {
+ uno::Reference< table::XCell > xCell( mxRange->getCellByPosition( j, i ), uno::UNO_SET_THROW );
+
+ visitor.visitNode( i, j, xCell );
+ }
+ }
+ if ( pDocSh )
+ pDocSh->UnlockPaint();
+}
+
+uno::Any
+ScVbaRange::getValue( ValueGetter& valueGetter)
+{
+ uno::Reference< table::XColumnRowRange > xColumnRowRange(mxRange, uno::UNO_QUERY_THROW );
+ // single cell range
+ if ( isSingleCellRange() )
+ {
+ visitArray( valueGetter );
+ return valueGetter.getValue();
+ }
+ sal_Int32 nRowCount = xColumnRowRange->getRows()->getCount();
+ sal_Int32 nColCount = xColumnRowRange->getColumns()->getCount();
+ // multi cell range ( return array )
+ Dim2ArrayValueGetter arrayGetter( nRowCount, nColCount, valueGetter );
+ visitArray( arrayGetter );
+ return uno::Any( script::ArrayWrapper( false, arrayGetter.getValue() ) );
+}
+
+uno::Any SAL_CALL
+ScVbaRange::getValue()
+{
+ // #TODO code within the test below "if ( m_Areas... " can be removed
+ // Test is performed only because m_xRange is NOT set to be
+ // the first range in m_Areas ( to force failure while
+ // the implementations for each method are being updated )
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_SET_THROW );
+ return xRange->getValue();
+ }
+
+ CellValueGetter valueGetter;
+ return getValue( valueGetter );
+
+}
+
+void
+ScVbaRange::setValue( const uno::Any& aValue, ValueSetter& valueSetter )
+{
+ uno::TypeClass aClass = aValue.getValueTypeClass();
+ if ( aClass == uno::TypeClass_SEQUENCE )
+ {
+ const uno::Reference< script::XTypeConverter >& xConverter = getTypeConverter( mxContext );
+ uno::Any aConverted;
+ try
+ {
+ // test for single dimension, could do
+ // with a better test than this
+ if ( aValue.getValueTypeName().indexOf('[') == aValue.getValueTypeName().lastIndexOf('[') )
+ {
+ aConverted = xConverter->convertTo( aValue, cppu::UnoType<uno::Sequence< uno::Any >>::get() );
+ Dim1ArrayValueSetter setter( aConverted, valueSetter );
+ visitArray( setter );
+ }
+ else
+ {
+ aConverted = xConverter->convertTo( aValue, cppu::UnoType<uno::Sequence< uno::Sequence< uno::Any > >>::get() );
+ Dim2ArrayValueSetter setter( aConverted, valueSetter );
+ visitArray( setter );
+ }
+ }
+ catch ( const uno::Exception& )
+ {
+ TOOLS_WARN_EXCEPTION("sc", "Bahhh, caught" );
+ }
+ }
+ else
+ {
+ visitArray( valueSetter );
+ }
+ fireChangeEvent();
+}
+
+void SAL_CALL
+ScVbaRange::setValue( const uno::Any &aValue )
+{
+ // If this is a multiple selection apply setValue over all areas
+ if ( m_Areas->getCount() > 1 )
+ {
+ AreasVisitor aVisitor( m_Areas );
+ RangeValueProcessor valueProcessor( aValue );
+ aVisitor.visit( valueProcessor );
+ return;
+ }
+ CellValueSetter valueSetter( aValue );
+ setValue( aValue, valueSetter );
+}
+
+void SAL_CALL
+ScVbaRange::Clear()
+{
+ using namespace ::com::sun::star::sheet::CellFlags;
+ sal_Int32 const nFlags = VALUE | DATETIME | STRING | FORMULA | HARDATTR | EDITATTR | FORMATTED;
+ ClearContents( nFlags, true );
+}
+
+//helper ClearContent
+void
+ScVbaRange::ClearContents( sal_Int32 nFlags, bool bFireEvent )
+{
+ // #TODO code within the test below "if ( m_Areas... " can be removed
+ // Test is performed only because m_xRange is NOT set to be
+ // the first range in m_Areas ( to force failure while
+ // the implementations for each method are being updated )
+ if ( m_Areas->getCount() > 1 )
+ {
+ sal_Int32 nItems = m_Areas->getCount();
+ for ( sal_Int32 index=1; index <= nItems; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::Any(index), uno::Any() ), uno::UNO_QUERY_THROW );
+ ScVbaRange* pRange = getImplementation( xRange );
+ if ( pRange )
+ pRange->ClearContents( nFlags, false ); // do not fire for single ranges
+ }
+ // fire change event for the entire range list
+ if( bFireEvent ) fireChangeEvent();
+ return;
+ }
+
+ uno::Reference< sheet::XSheetOperation > xSheetOperation(mxRange, uno::UNO_QUERY_THROW);
+ xSheetOperation->clearContents( nFlags );
+ if( bFireEvent ) fireChangeEvent();
+}
+
+void SAL_CALL
+ScVbaRange::ClearComments()
+{
+ ClearContents( sheet::CellFlags::ANNOTATION, false );
+}
+
+void SAL_CALL
+ScVbaRange::ClearContents()
+{
+ using namespace ::com::sun::star::sheet::CellFlags;
+ sal_Int32 const nFlags = VALUE | DATETIME | STRING | FORMULA;
+ ClearContents( nFlags, true );
+}
+
+void SAL_CALL
+ScVbaRange::ClearFormats()
+{
+ // FIXME: need to check if we need to combine FORMATTED
+ using namespace ::com::sun::star::sheet::CellFlags;
+ sal_Int32 const nFlags = HARDATTR | FORMATTED | EDITATTR;
+ ClearContents( nFlags, false );
+}
+
+void
+ScVbaRange::setFormulaValue( const uno::Any& rFormula, formula::FormulaGrammar::Grammar eGram )
+{
+ // If this is a multiple selection apply setFormula over all areas
+ if ( m_Areas->getCount() > 1 )
+ {
+ AreasVisitor aVisitor( m_Areas );
+ RangeFormulaProcessor valueProcessor( rFormula );
+ aVisitor.visit( valueProcessor );
+ return;
+ }
+ CellFormulaValueSetter formulaValueSetter( rFormula, getScDocument(), eGram );
+ setValue( rFormula, formulaValueSetter );
+}
+
+uno::Any
+ScVbaRange::getFormulaValue( formula::FormulaGrammar::Grammar eGram )
+{
+ // #TODO code within the test below "if ( m_Areas... " can be removed
+ // Test is performed only because m_xRange is NOT set to be
+ // the first range in m_Areas ( to force failure while
+ // the implementations for each method are being updated )
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_SET_THROW );
+ return xRange->getFormula();
+ }
+ CellFormulaValueGetter valueGetter( getScDocument(), eGram );
+ return getValue( valueGetter );
+
+}
+
+uno::Any
+ScVbaRange::getFormula()
+{
+ return getFormulaValue( formula::FormulaGrammar::GRAM_ENGLISH_XL_A1 );
+}
+
+void
+ScVbaRange::setFormula(const uno::Any &rFormula )
+{
+ setFormulaValue( rFormula, formula::FormulaGrammar::GRAM_ENGLISH_XL_A1 );
+}
+
+uno::Any
+ScVbaRange::getFormulaR1C1()
+{
+ return getFormulaValue( formula::FormulaGrammar::GRAM_ENGLISH_XL_R1C1 );
+}
+
+void
+ScVbaRange::setFormulaR1C1(const uno::Any& rFormula )
+{
+ setFormulaValue( rFormula, formula::FormulaGrammar::GRAM_ENGLISH_XL_R1C1 );
+}
+
+uno::Any
+ScVbaRange::getFormulaLocal()
+{
+ return getFormulaValue( formula::FormulaGrammar::GRAM_NATIVE_XL_A1 );
+}
+
+void
+ScVbaRange::setFormulaLocal(const uno::Any &rFormula )
+{
+ setFormulaValue( rFormula, formula::FormulaGrammar::GRAM_NATIVE_XL_A1 );
+}
+
+uno::Any
+ScVbaRange::getFormulaR1C1Local()
+{
+ return getFormulaValue( formula::FormulaGrammar::GRAM_NATIVE_XL_R1C1 );
+}
+
+void
+ScVbaRange::setFormulaR1C1Local(const uno::Any& rFormula )
+{
+ setFormulaValue( rFormula, formula::FormulaGrammar::GRAM_NATIVE_XL_R1C1 );
+}
+
+sal_Int32
+ScVbaRange::getCount()
+{
+ // If this is a multiple selection apply setValue over all areas
+ if ( m_Areas->getCount() > 1 )
+ {
+ AreasVisitor aVisitor( m_Areas );
+ RangeCountProcessor valueProcessor;
+ aVisitor.visit( valueProcessor );
+ return valueProcessor.value();
+ }
+ sal_Int32 rowCount = 0;
+ sal_Int32 colCount = 0;
+ uno::Reference< table::XColumnRowRange > xColumnRowRange(mxRange, uno::UNO_QUERY_THROW );
+ rowCount = xColumnRowRange->getRows()->getCount();
+ colCount = xColumnRowRange->getColumns()->getCount();
+
+ if( mbIsRows )
+ return rowCount;
+ if( mbIsColumns )
+ return colCount;
+ return rowCount * colCount;
+}
+
+sal_Int32
+ScVbaRange::getRow()
+{
+ // #TODO code within the test below "if ( m_Areas... " can be removed
+ // Test is performed only because m_xRange is NOT set to be
+ // the first range in m_Areas ( to force failure while
+ // the implementations for each method are being updated )
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_SET_THROW );
+ return xRange->getRow();
+ }
+ uno::Reference< sheet::XCellAddressable > xCellAddressable(mxRange->getCellByPosition(0, 0), uno::UNO_QUERY_THROW );
+ return xCellAddressable->getCellAddress().Row + 1; // Zero value indexing
+}
+
+sal_Int32
+ScVbaRange::getColumn()
+{
+ // #TODO code within the test below "if ( m_Areas... " can be removed
+ // Test is performed only because m_xRange is NOT set to be
+ // the first range in m_Areas ( to force failure while
+ // the implementations for each method are being updated )
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_SET_THROW );
+ return xRange->getColumn();
+ }
+ uno::Reference< sheet::XCellAddressable > xCellAddressable(mxRange->getCellByPosition(0, 0), uno::UNO_QUERY_THROW );
+ return xCellAddressable->getCellAddress().Column + 1; // Zero value indexing
+}
+
+uno::Any
+ScVbaRange::HasFormula()
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ sal_Int32 nItems = m_Areas->getCount();
+ uno::Any aResult = aNULL();
+ for ( sal_Int32 index=1; index <= nItems; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::Any(index), uno::Any() ), uno::UNO_QUERY_THROW );
+ // if the HasFormula for any area is different to another
+ // return null
+ if ( index > 1 )
+ if ( aResult != xRange->HasFormula() )
+ return aNULL();
+ aResult = xRange->HasFormula();
+ if ( aNULL() == aResult )
+ return aNULL();
+ }
+ return aResult;
+ }
+ uno::Reference< uno::XInterface > xIf( mxRange, uno::UNO_QUERY_THROW );
+ ScCellRangesBase* pThisRanges = dynamic_cast< ScCellRangesBase * > ( xIf.get() );
+ if ( pThisRanges )
+ {
+ uno::Reference<uno::XInterface> xRanges( pThisRanges->queryFormulaCells( sheet::FormulaResult::ERROR | sheet::FormulaResult::VALUE | sheet::FormulaResult::STRING ), uno::UNO_QUERY_THROW );
+ ScCellRangesBase* pFormulaRanges = dynamic_cast< ScCellRangesBase * > ( xRanges.get() );
+ assert(pFormulaRanges);
+ // check if there are no formula cell, return false
+ if ( pFormulaRanges->GetRangeList().empty() )
+ return uno::Any(false);
+
+ // check if there are holes (where some cells are not formulas)
+ // or returned range is not equal to this range
+ if ( ( pFormulaRanges->GetRangeList().size() > 1 )
+ || ( pFormulaRanges->GetRangeList().front().aStart != pThisRanges->GetRangeList().front().aStart )
+ || ( pFormulaRanges->GetRangeList().front().aEnd != pThisRanges->GetRangeList().front().aEnd )
+ )
+ return aNULL(); // should return aNULL;
+ }
+ return uno::Any( true );
+}
+void
+ScVbaRange::fillSeries( sheet::FillDirection nFillDirection, sheet::FillMode nFillMode, sheet::FillDateMode nFillDateMode, double fStep, double fEndValue )
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ // Multi-Area Range
+ uno::Reference< XCollection > xCollection( m_Areas, uno::UNO_SET_THROW );
+ for ( sal_Int32 index = 1; index <= xCollection->getCount(); ++index )
+ {
+ uno::Reference< excel::XRange > xRange( xCollection->Item( uno::Any( index ), uno::Any() ), uno::UNO_QUERY_THROW );
+ ScVbaRange* pThisRange = getImplementation( xRange );
+ pThisRange->fillSeries( nFillDirection, nFillMode, nFillDateMode, fStep, fEndValue );
+
+ }
+ return;
+ }
+
+ uno::Reference< sheet::XCellSeries > xCellSeries(mxRange, uno::UNO_QUERY_THROW );
+ xCellSeries->fillSeries( nFillDirection, nFillMode, nFillDateMode, fStep, fEndValue );
+ fireChangeEvent();
+}
+
+void
+ScVbaRange::FillLeft()
+{
+ fillSeries(sheet::FillDirection_TO_LEFT,
+ sheet::FillMode_SIMPLE, sheet::FillDateMode_FILL_DATE_DAY, 0, 0x7FFFFFFF);
+}
+
+void
+ScVbaRange::FillRight()
+{
+ fillSeries(sheet::FillDirection_TO_RIGHT,
+ sheet::FillMode_SIMPLE, sheet::FillDateMode_FILL_DATE_DAY, 0, 0x7FFFFFFF);
+}
+
+void
+ScVbaRange::FillUp()
+{
+ fillSeries(sheet::FillDirection_TO_TOP,
+ sheet::FillMode_SIMPLE, sheet::FillDateMode_FILL_DATE_DAY, 0, 0x7FFFFFFF);
+}
+
+void
+ScVbaRange::FillDown()
+{
+ fillSeries(sheet::FillDirection_TO_BOTTOM,
+ sheet::FillMode_SIMPLE, sheet::FillDateMode_FILL_DATE_DAY, 0, 0x7FFFFFFF);
+}
+
+OUString
+ScVbaRange::getText()
+{
+ // #TODO code within the test below "if ( m_Areas... " can be removed
+ // Test is performed only because m_xRange is NOT set to be
+ // the first range in m_Areas ( to force failure while
+ // the implementations for each method are being updated )
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_SET_THROW );
+ return xRange->getText();
+ }
+ uno::Reference< text::XTextRange > xTextRange(mxRange->getCellByPosition(0,0), uno::UNO_QUERY_THROW );
+ return xTextRange->getString();
+}
+
+uno::Reference< excel::XRange >
+ScVbaRange::Offset( const ::uno::Any &nRowOff, const uno::Any &nColOff )
+{
+ SCROW nRowOffset = 0;
+ SCCOL nColOffset = 0;
+ bool bIsRowOffset = ( nRowOff >>= nRowOffset );
+ bool bIsColumnOffset = ( nColOff >>= nColOffset );
+ ScCellRangesBase* pUnoRangesBase = getCellRangesBase();
+
+ ScRangeList aCellRanges = pUnoRangesBase->GetRangeList();
+
+ for ( size_t i = 0, nRanges = aCellRanges.size(); i < nRanges; ++i )
+ {
+ ScRange & rRange = aCellRanges[ i ];
+ if ( bIsColumnOffset )
+ {
+ rRange.aStart.SetCol( rRange.aStart.Col() + nColOffset );
+ rRange.aEnd.SetCol( rRange.aEnd.Col() + nColOffset );
+ }
+ if ( bIsRowOffset )
+ {
+ rRange.aStart.SetRow( rRange.aStart.Row() + nRowOffset );
+ rRange.aEnd.SetRow( rRange.aEnd.Row() + nRowOffset );
+ }
+ }
+
+ if ( aCellRanges.size() > 1 ) // Multi-Area
+ {
+ uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pUnoRangesBase->GetDocShell(), aCellRanges ) );
+ return new ScVbaRange( mxParent, mxContext, xRanges );
+ }
+ // normal range
+ const ScRange aRange( obtainRangeEvenIfRangeListIsEmpty( aCellRanges));
+ uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pUnoRangesBase->GetDocShell(), aRange));
+ return new ScVbaRange( mxParent, mxContext, xRange );
+}
+
+uno::Reference< excel::XRange >
+ScVbaRange::CurrentRegion()
+{
+ // #TODO code within the test below "if ( m_Areas... " can be removed
+ // Test is performed only because m_xRange is NOT set to be
+ // the first range in m_Areas ( to force failure while
+ // the implementations for each method are being updated )
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_SET_THROW );
+ return xRange->CurrentRegion();
+ }
+
+ RangeHelper helper( mxRange );
+ uno::Reference< sheet::XSheetCellCursor > xSheetCellCursor =
+ helper.getSheetCellCursor();
+ xSheetCellCursor->collapseToCurrentRegion();
+ uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable(xSheetCellCursor, uno::UNO_QUERY_THROW);
+ return RangeHelper::createRangeFromRange( mxParent, mxContext, helper.getCellRangeFromSheet(), xCellRangeAddressable );
+}
+
+uno::Reference< excel::XRange >
+ScVbaRange::CurrentArray()
+{
+ // #TODO code within the test below "if ( m_Areas... " can be removed
+ // Test is performed only because m_xRange is NOT set to be
+ // the first range in m_Areas ( to force failure while
+ // the implementations for each method are being updated )
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_SET_THROW );
+ return xRange->CurrentArray();
+ }
+ RangeHelper helper( mxRange );
+ uno::Reference< sheet::XSheetCellCursor > xSheetCellCursor =
+ helper.getSheetCellCursor();
+ xSheetCellCursor->collapseToCurrentArray();
+ uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable(xSheetCellCursor, uno::UNO_QUERY_THROW);
+ return RangeHelper::createRangeFromRange( mxParent, mxContext, helper.getCellRangeFromSheet(), xCellRangeAddressable );
+}
+
+uno::Any
+ScVbaRange::getFormulaArray()
+{
+ // #TODO code within the test below "if ( m_Areas... " can be removed
+ // Test is performed only because m_xRange is NOT set to be
+ // the first range in m_Areas ( to force failure while
+ // the implementations for each method are being updated )
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_SET_THROW );
+ return xRange->getFormulaArray();
+ }
+
+ // return a formula if there is one or else an array
+ // still not sure when the return as array code should run
+ // ( I think it is if there is more than one formula ) at least
+ // that is what the doc says ( but I am not even sure how to detect that )
+ // for the moment any tests we have pass
+ uno::Reference< sheet::XArrayFormulaRange> xFormulaArray( mxRange, uno::UNO_QUERY_THROW );
+ if ( !xFormulaArray->getArrayFormula().isEmpty() )
+ return uno::Any( xFormulaArray->getArrayFormula() );
+
+ uno::Reference< sheet::XCellRangeFormula> xCellRangeFormula( mxRange, uno::UNO_QUERY_THROW );
+ const uno::Reference< script::XTypeConverter >& xConverter = getTypeConverter( mxContext );
+ uno::Any aSingleValueOrMatrix;
+ // When dealing with a single element ( embedded in the sequence of sequence ) unwrap and return
+ // that value
+ uno::Sequence< uno::Sequence<OUString> > aTmpSeq = xCellRangeFormula->getFormulaArray();
+ if ( aTmpSeq.getLength() == 1 )
+ {
+ if ( aTmpSeq[ 0 ].getLength() == 1 )
+ aSingleValueOrMatrix <<= aTmpSeq[ 0 ][ 0 ];
+ }
+ else
+ aSingleValueOrMatrix = xConverter->convertTo( uno::Any( aTmpSeq ) , cppu::UnoType<uno::Sequence< uno::Sequence< uno::Any > >>::get() ) ;
+ return aSingleValueOrMatrix;
+}
+
+void
+ScVbaRange::setFormulaArray(const uno::Any& rFormula)
+{
+ // #TODO code within the test below "if ( m_Areas... " can be removed
+ // Test is performed only because m_xRange is NOT set to be
+ // the first range in m_Areas ( to force failure while
+ // the implementations for each method are being updated )
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_SET_THROW );
+ return xRange->setFormulaArray( rFormula );
+ }
+ // #TODO need to distinguish between getFormula and getFormulaArray e.g. (R1C1)
+ // but for the moment it's just easier to treat them the same for setting
+ // seems
+ uno::Reference< lang::XMultiServiceFactory > xModelFactory( getUnoModel(), uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XFormulaParser > xParser( xModelFactory->createInstance( "com.sun.star.sheet.FormulaParser" ), uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XCellRangeAddressable > xSource( mxRange, uno::UNO_QUERY_THROW);
+
+ table::CellRangeAddress aRangeAddress = xSource->getRangeAddress();
+ // #TODO check if api orders the address
+ // e.g. do we need to order the RangeAddress to get the topleft ( or can we assume it
+ // is in the correct order )
+ table::CellAddress aAddress;
+ aAddress.Sheet = aRangeAddress.Sheet;
+ aAddress.Column = aRangeAddress.StartColumn;
+ aAddress.Row = aRangeAddress.StartRow;
+ OUString sFormula;
+ rFormula >>= sFormula;
+ uno::Sequence<sheet::FormulaToken> aTokens = xParser->parseFormula( sFormula, aAddress );
+ ScTokenArray aTokenArray(getScDocument());
+ (void)ScTokenConversion::ConvertToTokenArray( getScDocument(), aTokenArray, aTokens );
+
+ getScDocShell()->GetDocFunc().EnterMatrix( getScRangeList()[0], nullptr, &aTokenArray, OUString(), true, true, OUString(), formula::FormulaGrammar::GRAM_API );
+}
+
+OUString
+ScVbaRange::Characters(const uno::Any& Start, const uno::Any& Length)
+{
+ // #TODO code within the test below "if ( m_Areas... " can be removed
+ // Test is performed only because m_xRange is NOT set to be
+ // the first range in m_Areas ( to force failure while
+ // the implementations for each method are being updated )
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_SET_THROW );
+ return xRange->Characters( Start, Length );
+ }
+
+ tools::Long nIndex = 0, nCount = 0;
+ OUString rString;
+ uno::Reference< text::XTextRange > xTextRange(mxRange, ::uno::UNO_QUERY_THROW );
+ rString = xTextRange->getString();
+ if( !( Start >>= nIndex ) && !( Length >>= nCount ) )
+ return rString;
+ if(!( Start >>= nIndex ) )
+ nIndex = 1;
+ if(!( Length >>= nCount ) )
+ nIndex = rString.getLength();
+ return rString.copy( --nIndex, nCount ); // Zero value indexing
+}
+
+OUString
+ScVbaRange::Address( const uno::Any& RowAbsolute, const uno::Any& ColumnAbsolute, const uno::Any& ReferenceStyle, const uno::Any& External, const uno::Any& RelativeTo )
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ // Multi-Area Range
+ OUStringBuffer sAddress;
+ uno::Reference< XCollection > xCollection( m_Areas, uno::UNO_SET_THROW );
+ uno::Any aExternalCopy = External;
+ for ( sal_Int32 index = 1; index <= xCollection->getCount(); ++index )
+ {
+ uno::Reference< excel::XRange > xRange( xCollection->Item( uno::Any( index ), uno::Any() ), uno::UNO_QUERY_THROW );
+ if ( index > 1 )
+ {
+ sAddress.append(",");
+ // force external to be false
+ // only first address should have the
+ // document and sheet specifications
+ aExternalCopy <<= false;
+ }
+ sAddress.append(xRange->Address( RowAbsolute, ColumnAbsolute, ReferenceStyle, aExternalCopy, RelativeTo ));
+ }
+ return sAddress.makeStringAndClear();
+
+ }
+ ScAddress::Details dDetails( formula::FormulaGrammar::CONV_XL_A1, 0, 0 );
+ if ( ReferenceStyle.hasValue() )
+ {
+ sal_Int32 refStyle = excel::XlReferenceStyle::xlA1;
+ ReferenceStyle >>= refStyle;
+ if ( refStyle == excel::XlReferenceStyle::xlR1C1 )
+ dDetails = ScAddress::Details( formula::FormulaGrammar::CONV_XL_R1C1, 0, 0 );
+ }
+ // default
+ ScRefFlags nFlags = ScRefFlags::RANGE_ABS;
+ ScDocShell* pDocShell = getScDocShell();
+ ScDocument& rDoc = pDocShell->GetDocument();
+
+ RangeHelper thisRange( mxRange );
+ table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+ ScRange aRange( static_cast< SCCOL >( thisAddress.StartColumn ), static_cast< SCROW >( thisAddress.StartRow ), static_cast< SCTAB >( thisAddress.Sheet ), static_cast< SCCOL >( thisAddress.EndColumn ), static_cast< SCROW >( thisAddress.EndRow ), static_cast< SCTAB >( thisAddress.Sheet ) );
+ constexpr ScRefFlags ROW_ABS = ScRefFlags::ROW_ABS | ScRefFlags::ROW2_ABS;
+ constexpr ScRefFlags COL_ABS = ScRefFlags::COL_ABS | ScRefFlags::COL2_ABS;
+
+ if ( RowAbsolute.hasValue() )
+ {
+ bool bVal = true;
+ RowAbsolute >>= bVal;
+ if ( !bVal )
+ nFlags &= ~ROW_ABS;
+ }
+ if ( ColumnAbsolute.hasValue() )
+ {
+ bool bVal = true;
+ ColumnAbsolute >>= bVal;
+ if ( !bVal )
+ nFlags &= ~COL_ABS;
+ }
+ if ( External.hasValue() )
+ {
+ bool bLocal = false;
+ External >>= bLocal;
+ if ( bLocal )
+ nFlags |= ScRefFlags::TAB_3D | ScRefFlags::FORCE_DOC;
+ }
+ if ( RelativeTo.hasValue() )
+ {
+ // #TODO should I throw an error if R1C1 is not set?
+
+ table::CellRangeAddress refAddress = getCellRangeAddressForVBARange( RelativeTo, pDocShell );
+ dDetails = ScAddress::Details( formula::FormulaGrammar::CONV_XL_R1C1, static_cast< SCROW >( refAddress.StartRow ), static_cast< SCCOL >( refAddress.StartColumn ) );
+ }
+ return aRange.Format(rDoc, nFlags, dDetails);
+}
+
+uno::Reference < excel::XFont >
+ScVbaRange::Font()
+{
+ uno::Reference< beans::XPropertySet > xProps(mxRange, ::uno::UNO_QUERY );
+ ScDocument& rDoc = getScDocument();
+ if ( mxRange.is() )
+ xProps.set(mxRange, ::uno::UNO_QUERY );
+ else if ( mxRanges.is() )
+ xProps.set(mxRanges, ::uno::UNO_QUERY );
+
+ ScVbaPalette aPalette( rDoc.GetDocumentShell() );
+ ScCellRangeObj* pRangeObj = nullptr;
+ try
+ {
+ pRangeObj = getCellRangeObj();
+ }
+ catch( uno::Exception& )
+ {
+ }
+ return new ScVbaFont( this, mxContext, aPalette, xProps, pRangeObj );
+}
+
+uno::Reference< excel::XRange >
+ScVbaRange::Cells( const uno::Any &nRowIndex, const uno::Any &nColumnIndex )
+{
+ // #TODO code within the test below "if ( m_Areas... " can be removed
+ // Test is performed only because m_xRange is NOT set to be
+ // the first range in m_Areas ( to force failure while
+ // the implementations for each method are being updated )
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_SET_THROW );
+ return xRange->Cells( nRowIndex, nColumnIndex );
+ }
+
+ // Performance: Use a common helper method for ScVbaRange::Cells and ScVbaWorksheet::Cells,
+ // instead of creating a new ScVbaRange object in often-called ScVbaWorksheet::Cells
+ return CellsHelper( getScDocument(), mxParent, mxContext, mxRange, nRowIndex, nColumnIndex );
+}
+
+// static
+uno::Reference< excel::XRange >
+ScVbaRange::CellsHelper( const ScDocument& rDoc,
+ const uno::Reference< ov::XHelperInterface >& xParent,
+ const uno::Reference< uno::XComponentContext >& xContext,
+ const uno::Reference< css::table::XCellRange >& xRange,
+ const uno::Any &nRowIndex, const uno::Any &nColumnIndex )
+{
+ sal_Int32 nRow = 0, nColumn = 0;
+
+ bool bIsIndex = nRowIndex.hasValue();
+ bool bIsColumnIndex = nColumnIndex.hasValue();
+
+ // Sometimes we might get a float or a double or whatever
+ // set in the Any, we should convert as appropriate
+ // #FIXME - perhaps worth turning this into some sort of
+ // conversion routine e.g. bSuccess = getValueFromAny( nRow, nRowIndex, cppu::UnoType<sal_Int32>::get() )
+ if ( nRowIndex.hasValue() && !( nRowIndex >>= nRow ) )
+ {
+ const uno::Reference< script::XTypeConverter >& xConverter = getTypeConverter( xContext );
+ uno::Any aConverted;
+ try
+ {
+ aConverted = xConverter->convertTo( nRowIndex, cppu::UnoType<sal_Int32>::get() );
+ bIsIndex = ( aConverted >>= nRow );
+ }
+ catch( uno::Exception& ) {} // silence any errors
+ }
+
+ if ( bIsColumnIndex )
+ {
+ // Column index can be a col address e.g Cells( 1, "B" ) etc.
+ OUString sCol;
+ if ( nColumnIndex >>= sCol )
+ {
+ ScAddress::Details dDetails( formula::FormulaGrammar::CONV_XL_A1, 0, 0 );
+ ScRange tmpRange;
+ ScRefFlags flags = tmpRange.ParseCols( rDoc, sCol, dDetails );
+ if ( (flags & ScRefFlags::COL_VALID) == ScRefFlags::ZERO )
+ throw uno::RuntimeException();
+ nColumn = tmpRange.aStart.Col() + 1;
+ }
+ else
+ {
+ if ( !( nColumnIndex >>= nColumn ) )
+ {
+ const uno::Reference< script::XTypeConverter >& xConverter = getTypeConverter( xContext );
+ uno::Any aConverted;
+ try
+ {
+ aConverted = xConverter->convertTo( nColumnIndex, cppu::UnoType<sal_Int32>::get() );
+ bIsColumnIndex = ( aConverted >>= nColumn );
+ }
+ catch( uno::Exception& ) {} // silence any errors
+ }
+ }
+ }
+ RangeHelper thisRange( xRange );
+ table::CellRangeAddress thisRangeAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+ uno::Reference< table::XCellRange > xSheetRange = thisRange.getCellRangeFromSheet();
+ if( !bIsIndex && !bIsColumnIndex ) // .Cells
+ // #FIXME needs proper parent ( Worksheet )
+ return uno::Reference< excel::XRange >( new ScVbaRange( xParent, xContext, xRange ) );
+
+ sal_Int32 nIndex = --nRow;
+ if( bIsIndex && !bIsColumnIndex ) // .Cells(n)
+ {
+ uno::Reference< table::XColumnRowRange > xColumnRowRange(xRange, ::uno::UNO_QUERY_THROW);
+ sal_Int32 nColCount = xColumnRowRange->getColumns()->getCount();
+
+ if ( !nIndex || nIndex < 0 )
+ nRow = 0;
+ else
+ nRow = nIndex / nColCount;
+ nColumn = nIndex % nColCount;
+ }
+ else
+ --nColumn;
+ nRow = nRow + thisRangeAddress.StartRow;
+ nColumn = nColumn + thisRangeAddress.StartColumn;
+ return new ScVbaRange( xParent, xContext, xSheetRange->getCellRangeByPosition( nColumn, nRow, nColumn, nRow ) );
+}
+
+void
+ScVbaRange::Select()
+{
+ ScCellRangesBase* pUnoRangesBase = getCellRangesBase();
+ if ( !pUnoRangesBase )
+ throw uno::RuntimeException("Failed to access underlying uno range object" );
+ ScDocShell* pShell = pUnoRangesBase->GetDocShell();
+ if ( !pShell )
+ return;
+
+ uno::Reference< frame::XModel > xModel( pShell->GetModel(), uno::UNO_SET_THROW );
+ uno::Reference< view::XSelectionSupplier > xSelection( xModel->getCurrentController(), uno::UNO_QUERY_THROW );
+ if ( mxRanges.is() )
+ xSelection->select( uno::Any( lclExpandToMerged( mxRanges ) ) );
+ else
+ xSelection->select( uno::Any( lclExpandToMerged( mxRange, true ) ) );
+ // set focus on document e.g.
+ // ThisComponent.CurrentController.Frame.getContainerWindow.SetFocus
+ try
+ {
+ uno::Reference< frame::XController > xController( xModel->getCurrentController(), uno::UNO_SET_THROW );
+ uno::Reference< frame::XFrame > xFrame( xController->getFrame(), uno::UNO_SET_THROW );
+ uno::Reference< awt::XWindow > xWin( xFrame->getContainerWindow(), uno::UNO_SET_THROW );
+ xWin->setFocus();
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+static bool cellInRange( const table::CellRangeAddress& rAddr, sal_Int32 nCol, sal_Int32 nRow )
+{
+ return nCol >= rAddr.StartColumn && nCol <= rAddr.EndColumn &&
+ nRow >= rAddr.StartRow && nRow <= rAddr.EndRow;
+}
+
+static void setCursor( SCCOL nCol, SCROW nRow, const uno::Reference< frame::XModel >& xModel, bool bInSel = true )
+{
+ ScTabViewShell* pShell = excel::getBestViewShell( xModel );
+ if ( pShell )
+ {
+ if ( bInSel )
+ pShell->SetCursor( nCol, nRow );
+ else
+ pShell->MoveCursorAbs( nCol, nRow, SC_FOLLOW_NONE, false, false, true );
+ }
+}
+
+void
+ScVbaRange::Activate()
+{
+ // get first cell of current range
+ uno::Reference< table::XCellRange > xCellRange;
+ if ( mxRanges.is() )
+ {
+ uno::Reference< container::XIndexAccess > xIndex( mxRanges, uno::UNO_QUERY_THROW );
+ xCellRange.set( xIndex->getByIndex( 0 ), uno::UNO_QUERY_THROW );
+ }
+ else
+ xCellRange.set( mxRange, uno::UNO_SET_THROW );
+
+ RangeHelper thisRange( xCellRange );
+ uno::Reference< sheet::XCellRangeAddressable > xThisRangeAddress = thisRange.getCellRangeAddressable();
+ table::CellRangeAddress thisRangeAddress = xThisRangeAddress->getRangeAddress();
+ uno::Reference< frame::XModel > xModel;
+ ScDocShell* pShell = getScDocShell();
+
+ if ( pShell )
+ xModel = pShell->GetModel();
+
+ if ( !xModel.is() )
+ throw uno::RuntimeException();
+
+ // get current selection
+ uno::Reference< sheet::XCellRangeAddressable > xRange( xModel->getCurrentSelection(), ::uno::UNO_QUERY);
+
+ uno::Reference< sheet::XSheetCellRanges > xRanges( xModel->getCurrentSelection(), ::uno::UNO_QUERY);
+
+ if ( xRanges.is() )
+ {
+ const uno::Sequence< table::CellRangeAddress > nAddrs = xRanges->getRangeAddresses();
+ for ( const auto& rAddr : nAddrs )
+ {
+ if ( cellInRange( rAddr, thisRangeAddress.StartColumn, thisRangeAddress.StartRow ) )
+ {
+ setCursor( static_cast< SCCOL >( thisRangeAddress.StartColumn ), static_cast< SCROW >( thisRangeAddress.StartRow ), xModel );
+ return;
+ }
+
+ }
+ }
+
+ if ( xRange.is() && cellInRange( xRange->getRangeAddress(), thisRangeAddress.StartColumn, thisRangeAddress.StartRow ) )
+ setCursor( static_cast< SCCOL >( thisRangeAddress.StartColumn ), static_cast< SCROW >( thisRangeAddress.StartRow ), xModel );
+ else
+ {
+ // if this range is multi cell select the range other
+ // wise just position the cell at this single range position
+ if ( isSingleCellRange() )
+ // This top-leftmost cell of this Range is not in the current
+ // selection so just select this range
+ setCursor( static_cast< SCCOL >( thisRangeAddress.StartColumn ), static_cast< SCROW >( thisRangeAddress.StartRow ), xModel, false );
+ else
+ Select();
+ }
+
+}
+
+ScRange ScVbaRange::obtainRangeEvenIfRangeListIsEmpty( const ScRangeList& rCellRanges ) const
+{
+ // XXX It may be that using the current range list was never correct, but
+ // always the initial sheet range would be instead, history is unclear.
+
+ if (!rCellRanges.empty())
+ return rCellRanges.front();
+
+ table::CellRangeAddress aRA( lclGetRangeAddress( mxRange ));
+ return ScRange( aRA.StartColumn, aRA.StartRow, aRA.Sheet, aRA.EndColumn, aRA.EndRow, aRA.Sheet);
+}
+
+uno::Reference< excel::XRange >
+ScVbaRange::Rows(const uno::Any& aIndex )
+{
+ if ( aIndex.hasValue() )
+ {
+ ScCellRangesBase* pUnoRangesBase = getCellRangesBase();
+ ScRange aRange( obtainRangeEvenIfRangeListIsEmpty( pUnoRangesBase->GetRangeList()));
+
+ sal_Int32 nValue = 0;
+ OUString sAddress;
+ if( aIndex >>= nValue )
+ {
+ aRange.aStart.SetRow( aRange.aStart.Row() + --nValue );
+ aRange.aEnd.SetRow( aRange.aStart.Row() );
+ }
+ else if ( aIndex >>= sAddress )
+ {
+ ScAddress::Details dDetails( formula::FormulaGrammar::CONV_XL_A1, 0, 0 );
+ ScRange tmpRange;
+ tmpRange.ParseRows( getScDocument(), sAddress, dDetails );
+ SCROW nStartRow = tmpRange.aStart.Row();
+ SCROW nEndRow = tmpRange.aEnd.Row();
+
+ aRange.aStart.SetRow( aRange.aStart.Row() + nStartRow );
+ aRange.aEnd.SetRow( aRange.aStart.Row() + ( nEndRow - nStartRow ));
+ }
+ else
+ throw uno::RuntimeException("Illegal param" );
+
+ if ( aRange.aStart.Row() < 0 || aRange.aEnd.Row() < 0 )
+ throw uno::RuntimeException("Internal failure, illegal param" );
+ // return a normal range ( even for multi-selection
+ uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pUnoRangesBase->GetDocShell(), aRange ) );
+ return new ScVbaRange( mxParent, mxContext, xRange, true );
+ }
+ // Rows() - no params
+ if ( m_Areas->getCount() > 1 )
+ return new ScVbaRange( mxParent, mxContext, mxRanges, true );
+ return new ScVbaRange( mxParent, mxContext, mxRange, true );
+}
+
+uno::Reference< excel::XRange >
+ScVbaRange::Columns(const uno::Any& aIndex )
+{
+ ScCellRangesBase* pUnoRangesBase = getCellRangesBase();
+ ScRange aRange( obtainRangeEvenIfRangeListIsEmpty( pUnoRangesBase->GetRangeList()));
+
+ if ( aIndex.hasValue() )
+ {
+ OUString sAddress;
+ sal_Int32 nValue = 0;
+ if ( aIndex >>= nValue )
+ {
+ aRange.aStart.SetCol( aRange.aStart.Col() + static_cast< SCCOL > ( --nValue ) );
+ aRange.aEnd.SetCol( aRange.aStart.Col() );
+ }
+
+ else if ( aIndex >>= sAddress )
+ {
+ ScAddress::Details dDetails( formula::FormulaGrammar::CONV_XL_A1, 0, 0 );
+ ScRange tmpRange;
+ tmpRange.ParseCols( getScDocument(), sAddress, dDetails );
+ SCCOL nStartCol = tmpRange.aStart.Col();
+ SCCOL nEndCol = tmpRange.aEnd.Col();
+
+ aRange.aStart.SetCol( aRange.aStart.Col() + nStartCol );
+ aRange.aEnd.SetCol( aRange.aStart.Col() + ( nEndCol - nStartCol ));
+ }
+ else
+ throw uno::RuntimeException("Illegal param" );
+
+ if ( aRange.aStart.Col() < 0 || aRange.aEnd.Col() < 0 )
+ throw uno::RuntimeException("Internal failure, illegal param" );
+ }
+ // Columns() - no params
+ uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pUnoRangesBase->GetDocShell(), aRange ) );
+ return new ScVbaRange( mxParent, mxContext, xRange, false, true );
+}
+
+void
+ScVbaRange::setMergeCells( const uno::Any& aIsMerged )
+{
+ bool bMerge = extractBoolFromAny( aIsMerged );
+
+ if( mxRanges.is() )
+ {
+ sal_Int32 nCount = mxRanges->getCount();
+
+ // VBA does nothing (no error) if the own ranges overlap somehow
+ ::std::vector< table::CellRangeAddress > aList;
+ for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex )
+ {
+ uno::Reference< sheet::XCellRangeAddressable > xRangeAddr( mxRanges->getByIndex( nIndex ), uno::UNO_QUERY_THROW );
+ table::CellRangeAddress aAddress = xRangeAddr->getRangeAddress();
+ if (std::any_of(aList.begin(), aList.end(),
+ [&aAddress](const table::CellRangeAddress& rAddress)
+ { return ScUnoConversion::Intersects( rAddress, aAddress ); }))
+ return;
+ aList.push_back( aAddress );
+ }
+
+ // (un)merge every range after it has been extended to intersecting merged ranges from sheet
+ for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex )
+ {
+ uno::Reference< table::XCellRange > xRange( mxRanges->getByIndex( nIndex ), uno::UNO_QUERY_THROW );
+ lclExpandAndMerge( xRange, bMerge );
+ }
+ return;
+ }
+
+ // otherwise, merge single range
+ lclExpandAndMerge( mxRange, bMerge );
+}
+
+uno::Any
+ScVbaRange::getMergeCells()
+{
+ if( mxRanges.is() )
+ {
+ sal_Int32 nCount = mxRanges->getCount();
+ for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex )
+ {
+ uno::Reference< table::XCellRange > xRange( mxRanges->getByIndex( nIndex ), uno::UNO_QUERY_THROW );
+ util::TriState eMerged = lclGetMergedState( xRange );
+ /* Excel always returns NULL, if one range of the range list is
+ partly or completely merged. Even if all ranges are completely
+ merged, the return value is still NULL. */
+ if( eMerged != util::TriState_NO )
+ return aNULL();
+ }
+ // no range is merged anyhow, return false
+ return uno::Any( false );
+ }
+
+ // otherwise, check single range
+ switch( lclGetMergedState( mxRange ) )
+ {
+ case util::TriState_YES: return uno::Any( true );
+ case util::TriState_NO: return uno::Any( false );
+ default: return aNULL();
+ }
+}
+
+void
+ScVbaRange::Copy(const ::uno::Any& Destination)
+{
+ if ( Destination.hasValue() )
+ {
+ // TODO copy with multiple selections should work here too
+ if ( m_Areas->getCount() > 1 )
+ throw uno::RuntimeException("That command cannot be used on multiple selections" );
+ uno::Reference< excel::XRange > xRange( Destination, uno::UNO_QUERY_THROW );
+ uno::Any aRange = xRange->getCellRange();
+ uno::Reference< table::XCellRange > xCellRange;
+ aRange >>= xCellRange;
+ uno::Reference< sheet::XSheetCellRange > xSheetCellRange(xCellRange, ::uno::UNO_QUERY_THROW);
+ uno::Reference< sheet::XSpreadsheet > xSheet = xSheetCellRange->getSpreadsheet();
+ uno::Reference< table::XCellRange > xDest( xSheet, uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XCellRangeMovement > xMover( xSheet, uno::UNO_QUERY_THROW);
+ uno::Reference< sheet::XCellAddressable > xDestination( xDest->getCellByPosition(
+ xRange->getColumn()-1,xRange->getRow()-1), uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XCellRangeAddressable > xSource( mxRange, uno::UNO_QUERY);
+ xMover->copyRange( xDestination->getCellAddress(), xSource->getRangeAddress() );
+ if ( ScVbaRange* pRange = getImplementation( xRange ) )
+ pRange->fireChangeEvent();
+ }
+ else
+ {
+ Select();
+ excel::implnCopy(getUnoModel());
+ }
+}
+
+void
+ScVbaRange::Cut(const ::uno::Any& Destination)
+{
+ if ( m_Areas->getCount() > 1 )
+ throw uno::RuntimeException("That command cannot be used on multiple selections" );
+ if (Destination.hasValue())
+ {
+ uno::Reference< excel::XRange > xRange( Destination, uno::UNO_QUERY_THROW );
+ uno::Reference< table::XCellRange > xCellRange( xRange->getCellRange(), uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XSheetCellRange > xSheetCellRange(xCellRange, ::uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XSpreadsheet > xSheet = xSheetCellRange->getSpreadsheet();
+ uno::Reference< table::XCellRange > xDest( xSheet, uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XCellRangeMovement > xMover( xSheet, uno::UNO_QUERY_THROW);
+ uno::Reference< sheet::XCellAddressable > xDestination( xDest->getCellByPosition(
+ xRange->getColumn()-1,xRange->getRow()-1), uno::UNO_QUERY);
+ uno::Reference< sheet::XCellRangeAddressable > xSource( mxRange, uno::UNO_QUERY);
+ xMover->moveRange( xDestination->getCellAddress(), xSource->getRangeAddress() );
+ }
+ else
+ {
+ uno::Reference< frame::XModel > xModel = getModelFromRange( mxRange );
+ Select();
+ excel::implnCut( xModel );
+ }
+}
+
+void
+ScVbaRange::setNumberFormat( const uno::Any& aFormat )
+{
+ OUString sFormat;
+ aFormat >>= sFormat;
+ if ( m_Areas->getCount() > 1 )
+ {
+ sal_Int32 nItems = m_Areas->getCount();
+ for ( sal_Int32 index=1; index <= nItems; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::Any(index), uno::Any() ), uno::UNO_QUERY_THROW );
+ xRange->setNumberFormat( aFormat );
+ }
+ return;
+ }
+ NumFormatHelper numFormat( mxRange );
+ numFormat.setNumberFormat( sFormat );
+}
+
+uno::Any
+ScVbaRange::getNumberFormat()
+{
+
+ if ( m_Areas->getCount() > 1 )
+ {
+ sal_Int32 nItems = m_Areas->getCount();
+ uno::Any aResult = aNULL();
+ for ( sal_Int32 index=1; index <= nItems; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::Any(index), uno::Any() ), uno::UNO_QUERY_THROW );
+ // if the numberformat of one area is different to another
+ // return null
+ if ( index > 1 )
+ if ( aResult != xRange->getNumberFormat() )
+ return aNULL();
+ aResult = xRange->getNumberFormat();
+ if ( aNULL() == aResult )
+ return aNULL();
+ }
+ return aResult;
+ }
+ NumFormatHelper numFormat( mxRange );
+ OUString sFormat = numFormat.getNumberFormatString();
+ if ( !sFormat.isEmpty() )
+ return uno::Any( sFormat );
+ return aNULL();
+}
+
+uno::Reference< excel::XRange >
+ScVbaRange::Resize( const uno::Any &RowSize, const uno::Any &ColumnSize )
+{
+ tools::Long nRowSize = 0, nColumnSize = 0;
+ bool bIsRowChanged = ( RowSize >>= nRowSize ), bIsColumnChanged = ( ColumnSize >>= nColumnSize );
+ uno::Reference< table::XColumnRowRange > xColumnRowRange(mxRange, ::uno::UNO_QUERY_THROW);
+ uno::Reference< sheet::XSheetCellRange > xSheetRange(mxRange, ::uno::UNO_QUERY_THROW);
+ uno::Reference< sheet::XSheetCellCursor > xCursor( xSheetRange->getSpreadsheet()->createCursorByRange(xSheetRange), ::uno::UNO_SET_THROW );
+
+ if( !bIsRowChanged )
+ nRowSize = xColumnRowRange->getRows()->getCount();
+ if( !bIsColumnChanged )
+ nColumnSize = xColumnRowRange->getColumns()->getCount();
+
+ xCursor->collapseToSize( nColumnSize, nRowSize );
+ uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable(xCursor, ::uno::UNO_QUERY_THROW );
+ uno::Reference< table::XCellRange > xRange( xSheetRange->getSpreadsheet(), ::uno::UNO_QUERY_THROW );
+ return new ScVbaRange( mxParent, mxContext,xRange->getCellRangeByPosition(
+ xCellRangeAddressable->getRangeAddress().StartColumn,
+ xCellRangeAddressable->getRangeAddress().StartRow,
+ xCellRangeAddressable->getRangeAddress().EndColumn,
+ xCellRangeAddressable->getRangeAddress().EndRow ) );
+}
+
+void
+ScVbaRange::setWrapText( const uno::Any& aIsWrapped )
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ sal_Int32 nItems = m_Areas->getCount();
+ for ( sal_Int32 index=1; index <= nItems; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::Any(index), uno::Any() ), uno::UNO_QUERY_THROW );
+ xRange->setWrapText( aIsWrapped );
+ }
+ return;
+ }
+
+ uno::Reference< beans::XPropertySet > xProps(mxRange, ::uno::UNO_QUERY_THROW );
+ bool bIsWrapped = extractBoolFromAny( aIsWrapped );
+ xProps->setPropertyValue( "IsTextWrapped", uno::Any( bIsWrapped ) );
+}
+
+uno::Any
+ScVbaRange::getWrapText()
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ sal_Int32 nItems = m_Areas->getCount();
+ uno::Any aResult;
+ for ( sal_Int32 index=1; index <= nItems; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::Any(index), uno::Any() ), uno::UNO_QUERY_THROW );
+ if ( index > 1 )
+ if ( aResult != xRange->getWrapText() )
+ return aNULL();
+ aResult = xRange->getWrapText();
+ }
+ return aResult;
+ }
+
+ SfxItemSet* pDataSet = getCurrentDataSet();
+
+ SfxItemState eState = pDataSet->GetItemState( ATTR_LINEBREAK);
+ if ( eState == SfxItemState::DONTCARE )
+ return aNULL();
+
+ uno::Reference< beans::XPropertySet > xProps(mxRange, ::uno::UNO_QUERY_THROW );
+ uno::Any aValue = xProps->getPropertyValue( "IsTextWrapped" );
+ return aValue;
+}
+
+uno::Reference< excel::XInterior > ScVbaRange::Interior( )
+{
+ uno::Reference< beans::XPropertySet > xProps( mxRange, uno::UNO_QUERY_THROW );
+ return new ScVbaInterior ( this, mxContext, xProps, &getScDocument() );
+}
+uno::Reference< excel::XRange >
+ScVbaRange::Range( const uno::Any &Cell1, const uno::Any &Cell2 )
+{
+ return Range( Cell1, Cell2, false );
+}
+uno::Reference< excel::XRange >
+ScVbaRange::Range( const uno::Any &Cell1, const uno::Any &Cell2, bool bForceUseInpuRangeTab )
+
+{
+ uno::Reference< table::XCellRange > xCellRange = mxRange;
+
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< container::XIndexAccess > xIndex( mxRanges, uno::UNO_QUERY_THROW );
+ xCellRange.set( xIndex->getByIndex( 0 ), uno::UNO_QUERY_THROW );
+ }
+ else
+ xCellRange.set( mxRange );
+
+ RangeHelper thisRange( xCellRange );
+ uno::Reference< table::XCellRange > xRanges = thisRange.getCellRangeFromSheet();
+ uno::Reference< sheet::XCellRangeAddressable > xAddressable( xRanges, uno::UNO_QUERY_THROW );
+
+ uno::Reference< table::XCellRange > xReferrer =
+ xRanges->getCellRangeByPosition( getColumn()-1, getRow()-1,
+ xAddressable->getRangeAddress().EndColumn,
+ xAddressable->getRangeAddress().EndRow );
+ // xAddressable now for this range
+ xAddressable.set( xReferrer, uno::UNO_QUERY_THROW );
+
+ if( !Cell1.hasValue() )
+ throw uno::RuntimeException( "Invalid Argument" );
+
+ table::CellRangeAddress parentRangeAddress = xAddressable->getRangeAddress();
+
+ ScRange aRange;
+ // Cell1 defined only
+ if ( !Cell2.hasValue() )
+ {
+ OUString sName;
+ Cell1 >>= sName;
+ RangeHelper referRange( xReferrer );
+ table::CellRangeAddress referAddress = referRange.getCellRangeAddressable()->getRangeAddress();
+ return getRangeForName( mxContext, sName, getScDocShell(), referAddress );
+
+ }
+ else
+ {
+ table::CellRangeAddress cell1, cell2;
+ cell1 = getCellRangeAddressForVBARange( Cell1, getScDocShell() );
+ // Cell1 & Cell2 defined
+ // Excel seems to combine the range as the range defined by
+ // the combination of Cell1 & Cell2
+
+ cell2 = getCellRangeAddressForVBARange( Cell2, getScDocShell() );
+
+ table::CellRangeAddress resultAddress;
+ resultAddress.StartColumn = ( cell1.StartColumn < cell2.StartColumn ) ? cell1.StartColumn : cell2.StartColumn;
+ resultAddress.StartRow = ( cell1.StartRow < cell2.StartRow ) ? cell1.StartRow : cell2.StartRow;
+ resultAddress.EndColumn = std::max( cell1.EndColumn, cell2.EndColumn );
+ resultAddress.EndRow = std::max( cell1.EndRow, cell2.EndRow );
+ if ( bForceUseInpuRangeTab )
+ {
+ // this is a call from Application.Range( x,y )
+ // it's possible for x or y to specify a different sheet from
+ // the current or active on ( but they must be the same )
+ if ( cell1.Sheet != cell2.Sheet )
+ throw uno::RuntimeException();
+ parentRangeAddress.Sheet = cell1.Sheet;
+ }
+ else
+ {
+ // this is not a call from Application.Range( x,y )
+ // if a different sheet from this range is specified it's
+ // an error
+ if ( parentRangeAddress.Sheet != cell1.Sheet
+ || parentRangeAddress.Sheet != cell2.Sheet
+ )
+ throw uno::RuntimeException();
+
+ }
+ ScUnoConversion::FillScRange( aRange, resultAddress );
+ }
+ ScRange parentAddress;
+ ScUnoConversion::FillScRange( parentAddress, parentRangeAddress);
+ if ( aRange.aStart.Col() >= 0 && aRange.aStart.Row() >= 0 && aRange.aEnd.Col() >= 0 && aRange.aEnd.Row() >= 0 )
+ {
+ sal_Int32 nStartX = parentAddress.aStart.Col() + aRange.aStart.Col();
+ sal_Int32 nStartY = parentAddress.aStart.Row() + aRange.aStart.Row();
+ sal_Int32 nEndX = parentAddress.aStart.Col() + aRange.aEnd.Col();
+ sal_Int32 nEndY = parentAddress.aStart.Row() + aRange.aEnd.Row();
+
+ if ( nStartX <= nEndX && nEndX <= parentAddress.aEnd.Col() &&
+ nStartY <= nEndY && nEndY <= parentAddress.aEnd.Row() )
+ {
+ ScRange aNew( static_cast<SCCOL>(nStartX), static_cast<SCROW>(nStartY), parentAddress.aStart.Tab(),
+ static_cast<SCCOL>(nEndX), static_cast<SCROW>(nEndY), parentAddress.aEnd.Tab() );
+ xCellRange = new ScCellRangeObj( getScDocShell(), aNew );
+ }
+ }
+
+ return new ScVbaRange( mxParent, mxContext, xCellRange );
+
+}
+
+// Allow access to underlying openoffice uno api ( useful for debugging
+// with openoffice basic )
+uno::Any SAL_CALL ScVbaRange::getCellRange( )
+{
+ uno::Any aAny;
+ if ( mxRanges.is() )
+ aAny <<= mxRanges;
+ else if ( mxRange.is() )
+ aAny <<= mxRange;
+ return aAny;
+}
+
+uno::Any ScVbaRange::getCellRange( const uno::Reference< excel::XRange >& rxRange )
+{
+ if( ScVbaRange* pVbaRange = getImplementation( rxRange ) )
+ return pVbaRange->getCellRange();
+ throw uno::RuntimeException();
+}
+
+static InsertDeleteFlags getPasteFlags (sal_Int32 Paste)
+{
+ InsertDeleteFlags nFlags = InsertDeleteFlags::NONE;
+ switch (Paste) {
+ case excel::XlPasteType::xlPasteComments:
+ nFlags = InsertDeleteFlags::NOTE;break;
+ case excel::XlPasteType::xlPasteFormats:
+ nFlags = InsertDeleteFlags::ATTRIB;break;
+ case excel::XlPasteType::xlPasteFormulas:
+ nFlags = InsertDeleteFlags::FORMULA;break;
+ case excel::XlPasteType::xlPasteFormulasAndNumberFormats :
+ case excel::XlPasteType::xlPasteValues:
+ nFlags = ( InsertDeleteFlags::VALUE | InsertDeleteFlags::DATETIME | InsertDeleteFlags::STRING | InsertDeleteFlags::SPECIAL_BOOLEAN ); break;
+ case excel::XlPasteType::xlPasteValuesAndNumberFormats:
+ nFlags = InsertDeleteFlags::VALUE | InsertDeleteFlags::ATTRIB; break;
+ case excel::XlPasteType::xlPasteColumnWidths:
+ case excel::XlPasteType::xlPasteValidation:
+ nFlags = InsertDeleteFlags::NONE;break;
+ case excel::XlPasteType::xlPasteAll:
+ case excel::XlPasteType::xlPasteAllExceptBorders:
+ default:
+ nFlags = InsertDeleteFlags::ALL;break;
+ }
+ return nFlags;
+}
+
+static ScPasteFunc
+getPasteFormulaBits( sal_Int32 Operation)
+{
+ ScPasteFunc nFormulaBits = ScPasteFunc::NONE;
+ switch (Operation)
+ {
+ case excel::XlPasteSpecialOperation::xlPasteSpecialOperationAdd:
+ nFormulaBits = ScPasteFunc::ADD; break;
+ case excel::XlPasteSpecialOperation::xlPasteSpecialOperationSubtract:
+ nFormulaBits = ScPasteFunc::SUB;break;
+ case excel::XlPasteSpecialOperation::xlPasteSpecialOperationMultiply:
+ nFormulaBits = ScPasteFunc::MUL;break;
+ case excel::XlPasteSpecialOperation::xlPasteSpecialOperationDivide:
+ nFormulaBits = ScPasteFunc::DIV;break;
+
+ case excel::XlPasteSpecialOperation::xlPasteSpecialOperationNone:
+ default:
+ nFormulaBits = ScPasteFunc::NONE; break;
+ }
+
+ return nFormulaBits;
+}
+void SAL_CALL
+ScVbaRange::PasteSpecial( const uno::Any& Paste, const uno::Any& Operation, const uno::Any& SkipBlanks, const uno::Any& Transpose )
+{
+ if ( m_Areas->getCount() > 1 )
+ throw uno::RuntimeException("That command cannot be used on multiple selections" );
+ ScDocShell* pShell = getScDocShell();
+
+ if (!pShell)
+ throw uno::RuntimeException("That command cannot be used with no ScDocShell" );
+
+ uno::Reference< frame::XModel > xModel(pShell->GetModel(), uno::UNO_SET_THROW);
+ uno::Reference< view::XSelectionSupplier > xSelection( xModel->getCurrentController(), uno::UNO_QUERY_THROW );
+ // select this range
+ xSelection->select( uno::Any( mxRange ) );
+ // set up defaults
+ sal_Int32 nPaste = excel::XlPasteType::xlPasteAll;
+ sal_Int32 nOperation = excel::XlPasteSpecialOperation::xlPasteSpecialOperationNone;
+ bool bTranspose = false;
+ bool bSkipBlanks = false;
+
+ if ( Paste.hasValue() )
+ Paste >>= nPaste;
+ if ( Operation.hasValue() )
+ Operation >>= nOperation;
+ if ( SkipBlanks.hasValue() )
+ SkipBlanks >>= bSkipBlanks;
+ if ( Transpose.hasValue() )
+ Transpose >>= bTranspose;
+
+ InsertDeleteFlags nFlags = getPasteFlags(nPaste);
+ ScPasteFunc nFormulaBits = getPasteFormulaBits(nOperation);
+
+ excel::implnPasteSpecial(xModel, nFlags, nFormulaBits, bSkipBlanks, bTranspose);
+}
+
+uno::Reference< excel::XRange >
+ScVbaRange::getEntireColumnOrRow( bool bColumn )
+{
+ ScCellRangesBase* pUnoRangesBase = getCellRangesBase();
+ // copy the range list
+ ScRangeList aCellRanges = pUnoRangesBase->GetRangeList();
+ ScDocument& rDoc = getScDocument();
+
+ for ( size_t i = 0, nRanges = aCellRanges.size(); i < nRanges; ++i )
+ {
+ ScRange & rRange = aCellRanges[ i ];
+ if ( bColumn )
+ {
+ rRange.aStart.SetRow( 0 );
+ rRange.aEnd.SetRow( rDoc.MaxRow() );
+ }
+ else
+ {
+ rRange.aStart.SetCol( 0 );
+ rRange.aEnd.SetCol( rDoc.MaxCol() );
+ }
+ }
+ if ( aCellRanges.size() > 1 ) // Multi-Area
+ {
+ uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pUnoRangesBase->GetDocShell(), aCellRanges ) );
+
+ return new ScVbaRange( mxParent, mxContext, xRanges, !bColumn, bColumn );
+ }
+ const ScRange aRange( obtainRangeEvenIfRangeListIsEmpty( aCellRanges));
+ uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pUnoRangesBase->GetDocShell(), aRange));
+ return new ScVbaRange( mxParent, mxContext, xRange, !bColumn, bColumn );
+}
+
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaRange::getEntireRow()
+{
+ return getEntireColumnOrRow(false);
+}
+
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaRange::getEntireColumn()
+{
+ return getEntireColumnOrRow(true);
+}
+
+uno::Reference< excel::XComment > SAL_CALL
+ScVbaRange::AddComment( const uno::Any& Text )
+{
+ // if there is already a comment in the top-left cell then throw
+ if( getComment().is() )
+ throw uno::RuntimeException();
+
+ // workaround: Excel allows to create empty comment, Calc does not
+ OUString aNoteText;
+ if( Text.hasValue() && !(Text >>= aNoteText) )
+ throw uno::RuntimeException();
+ if( aNoteText.isEmpty() )
+ aNoteText = " ";
+
+ // try to create a new annotation
+ table::CellRangeAddress aRangePos = lclGetRangeAddress( mxRange );
+ table::CellAddress aNotePos( aRangePos.Sheet, aRangePos.StartColumn, aRangePos.StartRow );
+ uno::Reference< sheet::XSheetCellRange > xCellRange( mxRange, uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XSheetAnnotationsSupplier > xAnnosSupp( xCellRange->getSpreadsheet(), uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XSheetAnnotations > xAnnos( xAnnosSupp->getAnnotations(), uno::UNO_SET_THROW );
+ xAnnos->insertNew( aNotePos, aNoteText );
+ return new ScVbaComment( this, mxContext, getUnoModel(), mxRange );
+}
+
+uno::Reference< excel::XComment > SAL_CALL
+ScVbaRange::getComment()
+{
+ // intentional behavior to return a null object if no
+ // comment defined
+ uno::Reference< excel::XComment > xComment( new ScVbaComment( this, mxContext, getUnoModel(), mxRange ) );
+ if ( xComment->Text( uno::Any(), uno::Any(), uno::Any() ).isEmpty() )
+ return nullptr;
+ return xComment;
+
+}
+
+/// @throws uno::RuntimeException
+static uno::Reference< beans::XPropertySet >
+getRowOrColumnProps( const uno::Reference< table::XCellRange >& xCellRange, bool bRows )
+{
+ uno::Reference< table::XColumnRowRange > xColRow( xCellRange, uno::UNO_QUERY_THROW );
+ uno::Reference< beans::XPropertySet > xProps;
+ if ( bRows )
+ xProps.set( xColRow->getRows(), uno::UNO_QUERY_THROW );
+ else
+ xProps.set( xColRow->getColumns(), uno::UNO_QUERY_THROW );
+ return xProps;
+}
+
+uno::Any SAL_CALL
+ScVbaRange::getHidden()
+{
+ // if multi-area result is the result of the
+ // first area
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::Any(sal_Int32(1)), uno::Any() ), uno::UNO_QUERY_THROW );
+ return xRange->getHidden();
+ }
+ bool bIsVisible = false;
+ try
+ {
+ uno::Reference< beans::XPropertySet > xProps = getRowOrColumnProps( mxRange, mbIsRows );
+ if ( !( xProps->getPropertyValue( ISVISIBLE ) >>= bIsVisible ) )
+ throw uno::RuntimeException("Failed to get IsVisible property" );
+ }
+ catch( const uno::Exception& e )
+ {
+ css::uno::Any anyEx = cppu::getCaughtException();
+ throw css::lang::WrappedTargetRuntimeException( e.Message,
+ nullptr, anyEx );
+ }
+ return uno::Any( !bIsVisible );
+}
+
+void SAL_CALL
+ScVbaRange::setHidden( const uno::Any& _hidden )
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ sal_Int32 nItems = m_Areas->getCount();
+ for ( sal_Int32 index=1; index <= nItems; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::Any(index), uno::Any() ), uno::UNO_QUERY_THROW );
+ xRange->setHidden( _hidden );
+ }
+ return;
+ }
+
+ bool bHidden = extractBoolFromAny( _hidden );
+ try
+ {
+ uno::Reference< beans::XPropertySet > xProps = getRowOrColumnProps( mxRange, mbIsRows );
+ xProps->setPropertyValue( ISVISIBLE, uno::Any( !bHidden ) );
+ }
+ catch( const uno::Exception& e )
+ {
+ css::uno::Any anyEx = cppu::getCaughtException();
+ throw css::lang::WrappedTargetRuntimeException( e.Message,
+ nullptr, anyEx );
+ }
+}
+
+sal_Bool SAL_CALL
+ScVbaRange::Replace( const OUString& What, const OUString& Replacement, const uno::Any& LookAt, const uno::Any& SearchOrder, const uno::Any& MatchCase, const uno::Any& MatchByte, const uno::Any& SearchFormat, const uno::Any& ReplaceFormat )
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ for ( sal_Int32 index = 1; index <= m_Areas->getCount(); ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::Any( index ), uno::Any() ), uno::UNO_QUERY_THROW );
+ xRange->Replace( What, Replacement, LookAt, SearchOrder, MatchCase, MatchByte, SearchFormat, ReplaceFormat );
+ }
+ return true; // seems to return true always ( or at least I haven't found the trick of
+ }
+
+ // sanity check required params
+ if ( What.isEmpty() )
+ throw uno::RuntimeException("Range::Replace, missing params" );
+ OUString sWhat = VBAToRegexp( What);
+ // #TODO #FIXME SearchFormat & ReplacesFormat are not processed
+ // What do we do about MatchByte... we don't seem to support that
+ const SvxSearchItem& globalSearchOptions = ScGlobal::GetSearchItem();
+ SvxSearchItem newOptions( globalSearchOptions );
+
+ uno::Reference< util::XReplaceable > xReplace( mxRange, uno::UNO_QUERY );
+ if ( xReplace.is() )
+ {
+ uno::Reference< util::XReplaceDescriptor > xDescriptor =
+ xReplace->createReplaceDescriptor();
+
+ xDescriptor->setSearchString( sWhat);
+ xDescriptor->setPropertyValue( SC_UNO_SRCHREGEXP, uno::Any( true ) );
+ xDescriptor->setReplaceString( Replacement);
+ if ( LookAt.hasValue() )
+ {
+ // sets SearchWords ( true is Cell match )
+ sal_Int16 nLook = ::comphelper::getINT16( LookAt );
+ bool bSearchWords = false;
+ if ( nLook == excel::XlLookAt::xlPart )
+ bSearchWords = false;
+ else if ( nLook == excel::XlLookAt::xlWhole )
+ bSearchWords = true;
+ else
+ throw uno::RuntimeException("Range::Replace, illegal value for LookAt" );
+ // set global search props ( affects the find dialog
+ // and of course the defaults for this method
+ newOptions.SetWordOnly( bSearchWords );
+ xDescriptor->setPropertyValue( SC_UNO_SRCHWORDS, uno::Any( bSearchWords ) );
+ }
+ // sets SearchByRow ( true for Rows )
+ if ( SearchOrder.hasValue() )
+ {
+ sal_Int16 nSearchOrder = ::comphelper::getINT16( SearchOrder );
+ bool bSearchByRow = false;
+ if ( nSearchOrder == excel::XlSearchOrder::xlByColumns )
+ bSearchByRow = false;
+ else if ( nSearchOrder == excel::XlSearchOrder::xlByRows )
+ bSearchByRow = true;
+ else
+ throw uno::RuntimeException("Range::Replace, illegal value for SearchOrder" );
+
+ newOptions.SetRowDirection( bSearchByRow );
+ xDescriptor->setPropertyValue( SC_UNO_SRCHBYROW, uno::Any( bSearchByRow ) );
+ }
+ if ( MatchCase.hasValue() )
+ {
+ bool bMatchCase = false;
+
+ // SearchCaseSensitive
+ MatchCase >>= bMatchCase;
+ xDescriptor->setPropertyValue( SC_UNO_SRCHCASE, uno::Any( bMatchCase ) );
+ }
+
+ ScGlobal::SetSearchItem( newOptions );
+ // ignore MatchByte for the moment, it's not supported in
+ // OOo.org afaik
+
+ uno::Reference< container::XIndexAccess > xIndexAccess = xReplace->findAll( xDescriptor );
+ xReplace->replaceAll( xDescriptor );
+ if ( xIndexAccess.is() && xIndexAccess->getCount() > 0 )
+ {
+ for ( sal_Int32 i = 0; i < xIndexAccess->getCount(); ++i )
+ {
+ uno::Reference< table::XCellRange > xCellRange( xIndexAccess->getByIndex( i ), uno::UNO_QUERY );
+ if ( xCellRange.is() )
+ {
+ uno::Reference< excel::XRange > xRange( new ScVbaRange( mxParent, mxContext, xCellRange ) );
+ uno::Reference< container::XEnumerationAccess > xEnumAccess( xRange, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XEnumeration > xEnum = xEnumAccess->createEnumeration();
+ while ( xEnum->hasMoreElements() )
+ {
+ uno::Reference< excel::XRange > xNextRange( xEnum->nextElement(), uno::UNO_QUERY_THROW );
+ ScVbaRange* pRange = dynamic_cast< ScVbaRange * > ( xNextRange.get() );
+ if ( pRange )
+ pRange->fireChangeEvent();
+ }
+ }
+ }
+ }
+ }
+ return true; // always
+}
+
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaRange::Find( const uno::Any& What, const uno::Any& After, const uno::Any& LookIn, const uno::Any& LookAt, const uno::Any& SearchOrder, const uno::Any& SearchDirection, const uno::Any& MatchCase, const uno::Any& /*MatchByte*/, const uno::Any& /*SearchFormat*/ )
+{
+ // return a Range object that represents the first cell where that information is found.
+ OUString sWhat;
+ sal_Int32 nWhat = 0;
+ double fWhat = 0.0;
+
+ // string.
+ if( What >>= sWhat )
+ {}
+ else if( What >>= nWhat )
+ {
+ sWhat = OUString::number( nWhat );
+ }
+ else if( What >>= fWhat )
+ {
+ sWhat = OUString::number( fWhat );
+ }
+ else
+ throw uno::RuntimeException("Range::Find, missing search-for-what param" );
+
+ OUString sSearch = VBAToRegexp( sWhat );
+
+ const SvxSearchItem& globalSearchOptions = ScGlobal::GetSearchItem();
+ SvxSearchItem newOptions( globalSearchOptions );
+
+ uno::Reference< util::XSearchable > xSearch( mxRange, uno::UNO_QUERY );
+ if( xSearch.is() )
+ {
+ uno::Reference< util::XSearchDescriptor > xDescriptor = xSearch->createSearchDescriptor();
+ xDescriptor->setSearchString( sSearch );
+ xDescriptor->setPropertyValue( SC_UNO_SRCHREGEXP, uno::Any( true ) );
+
+ uno::Reference< excel::XRange > xAfterRange;
+ uno::Reference< table::XCellRange > xStartCell;
+ if( After >>= xAfterRange )
+ {
+ // After must be a single cell in the range
+ if( xAfterRange->getCount() > 1 )
+ throw uno::RuntimeException("After must be a single cell." );
+ uno::Reference< excel::XRange > xCell( Cells( uno::Any( xAfterRange->getRow() ), uno::Any( xAfterRange->getColumn() ) ), uno::UNO_SET_THROW );
+ xStartCell.set( xAfterRange->getCellRange(), uno::UNO_QUERY_THROW );
+ }
+
+ // LookIn
+ if( LookIn.hasValue() )
+ {
+ sal_Int32 nLookIn = 0;
+ if( LookIn >>= nLookIn )
+ {
+ SvxSearchCellType nSearchType;
+ switch( nLookIn )
+ {
+ case excel::XlFindLookIn::xlComments :
+ nSearchType = SvxSearchCellType::NOTE; // Notes
+ break;
+ case excel::XlFindLookIn::xlFormulas :
+ nSearchType = SvxSearchCellType::FORMULA;
+ break;
+ case excel::XlFindLookIn::xlValues :
+ nSearchType = SvxSearchCellType::VALUE;
+ break;
+ default:
+ throw uno::RuntimeException("Range::Find, illegal value for LookIn." );
+ }
+ newOptions.SetCellType( nSearchType );
+ xDescriptor->setPropertyValue( "SearchType", uno::Any( static_cast<sal_uInt16>(nSearchType) ) );
+ }
+ }
+
+ // LookAt
+ if ( LookAt.hasValue() )
+ {
+ sal_Int16 nLookAt = ::comphelper::getINT16( LookAt );
+ bool bSearchWords = false;
+ if ( nLookAt == excel::XlLookAt::xlPart )
+ bSearchWords = false;
+ else if ( nLookAt == excel::XlLookAt::xlWhole )
+ bSearchWords = true;
+ else
+ throw uno::RuntimeException("Range::Find, illegal value for LookAt" );
+ newOptions.SetWordOnly( bSearchWords );
+ xDescriptor->setPropertyValue( SC_UNO_SRCHWORDS, uno::Any( bSearchWords ) );
+ }
+
+ // SearchOrder
+ if ( SearchOrder.hasValue() )
+ {
+ sal_Int16 nSearchOrder = ::comphelper::getINT16( SearchOrder );
+ bool bSearchByRow = false;
+ if ( nSearchOrder == excel::XlSearchOrder::xlByColumns )
+ bSearchByRow = false;
+ else if ( nSearchOrder == excel::XlSearchOrder::xlByRows )
+ bSearchByRow = true;
+ else
+ throw uno::RuntimeException("Range::Find, illegal value for SearchOrder" );
+
+ newOptions.SetRowDirection( bSearchByRow );
+ xDescriptor->setPropertyValue( SC_UNO_SRCHBYROW, uno::Any( bSearchByRow ) );
+ }
+
+ // SearchDirection
+ if ( SearchDirection.hasValue() )
+ {
+ sal_Int32 nSearchDirection = 0;
+ if( SearchDirection >>= nSearchDirection )
+ {
+ bool bSearchBackwards = false;
+ if ( nSearchDirection == excel::XlSearchDirection::xlNext )
+ bSearchBackwards = false;
+ else if( nSearchDirection == excel::XlSearchDirection::xlPrevious )
+ bSearchBackwards = true;
+ else
+ throw uno::RuntimeException("Range::Find, illegal value for SearchDirection" );
+ newOptions.SetBackward( bSearchBackwards );
+ xDescriptor->setPropertyValue( "SearchBackwards", uno::Any( bSearchBackwards ) );
+ }
+ }
+
+ // MatchCase
+ bool bMatchCase = false;
+ if ( MatchCase.hasValue() )
+ {
+ // SearchCaseSensitive
+ if( !( MatchCase >>= bMatchCase ) )
+ throw uno::RuntimeException("Range::Find illegal value for MatchCase" );
+ }
+ xDescriptor->setPropertyValue( SC_UNO_SRCHCASE, uno::Any( bMatchCase ) );
+
+ // MatchByte
+ // SearchFormat
+ // ignore
+
+ ScGlobal::SetSearchItem( newOptions );
+
+ uno::Reference< uno::XInterface > xInterface = xStartCell.is() ? xSearch->findNext( xStartCell, xDescriptor) : xSearch->findFirst( xDescriptor );
+ uno::Reference< table::XCellRange > xCellRange( xInterface, uno::UNO_QUERY );
+ // if we are searching from a starting cell and failed to find a match
+ // then try from the beginning
+ if ( !xCellRange.is() && xStartCell.is() )
+ {
+ xInterface = xSearch->findFirst( xDescriptor );
+ xCellRange.set( xInterface, uno::UNO_QUERY );
+ }
+ if ( xCellRange.is() )
+ {
+ uno::Reference< excel::XRange > xResultRange = new ScVbaRange( mxParent, mxContext, xCellRange );
+ if( xResultRange.is() )
+ {
+ return xResultRange;
+ }
+ }
+
+ }
+
+ return uno::Reference< excel::XRange >();
+}
+
+static uno::Reference< table::XCellRange > processKey( const uno::Any& Key, const uno::Reference< uno::XComponentContext >& xContext, ScDocShell* pDocSh )
+{
+ uno::Reference< excel::XRange > xKeyRange;
+ if ( Key.getValueType() == cppu::UnoType<excel::XRange>::get() )
+ {
+ xKeyRange.set( Key, uno::UNO_QUERY_THROW );
+ }
+ else if ( Key.getValueType() == ::cppu::UnoType<OUString>::get() )
+
+ {
+ OUString sRangeName = ::comphelper::getString( Key );
+ table::CellRangeAddress aRefAddr;
+ if ( !pDocSh )
+ throw uno::RuntimeException("Range::Sort no docshell to calculate key param" );
+ xKeyRange = getRangeForName( xContext, sRangeName, pDocSh, aRefAddr );
+ }
+ else
+ throw uno::RuntimeException("Range::Sort illegal type value for key param" );
+ uno::Reference< table::XCellRange > xKey;
+ xKey.set( xKeyRange->getCellRange(), uno::UNO_QUERY_THROW );
+ return xKey;
+}
+
+// helper method for Sort
+/// @throws uno::RuntimeException
+static sal_Int32 findSortPropertyIndex( const uno::Sequence< beans::PropertyValue >& props,
+const OUString& sPropName )
+{
+ const beans::PropertyValue* pProp = std::find_if(props.begin(), props.end(),
+ [&sPropName](const beans::PropertyValue& rProp) { return rProp.Name == sPropName; });
+
+ if ( pProp == props.end() )
+ throw uno::RuntimeException("Range::Sort unknown sort property" );
+ return static_cast<sal_Int32>(std::distance(props.begin(), pProp));
+}
+
+// helper method for Sort
+/// @throws uno::RuntimeException
+static void updateTableSortField( const uno::Reference< table::XCellRange >& xParentRange,
+ const uno::Reference< table::XCellRange >& xColRowKey, sal_Int16 nOrder,
+ table::TableSortField& aTableField, bool bIsSortColumn, bool bMatchCase )
+{
+ RangeHelper parentRange( xParentRange );
+ RangeHelper colRowRange( xColRowKey );
+
+ table::CellRangeAddress parentRangeAddress = parentRange.getCellRangeAddressable()->getRangeAddress();
+
+ table::CellRangeAddress colRowKeyAddress = colRowRange.getCellRangeAddressable()->getRangeAddress();
+
+ // make sure that upper left point of key range is within the
+ // parent range
+ if (
+ ( bIsSortColumn || colRowKeyAddress.StartColumn < parentRangeAddress.StartColumn ||
+ colRowKeyAddress.StartColumn > parentRangeAddress.EndColumn )
+ &&
+ ( !bIsSortColumn || colRowKeyAddress.StartRow < parentRangeAddress.StartRow ||
+ colRowKeyAddress.StartRow > parentRangeAddress.EndRow )
+ )
+ throw uno::RuntimeException("Illegal Key param" );
+
+ //determine col/row index
+ if ( bIsSortColumn )
+ aTableField.Field = colRowKeyAddress.StartRow - parentRangeAddress.StartRow;
+ else
+ aTableField.Field = colRowKeyAddress.StartColumn - parentRangeAddress.StartColumn;
+ aTableField.IsCaseSensitive = bMatchCase;
+
+ if ( nOrder == excel::XlSortOrder::xlAscending )
+ aTableField.IsAscending = true;
+ else
+ aTableField.IsAscending = false;
+
+
+}
+
+void SAL_CALL
+ScVbaRange::Sort( const uno::Any& Key1, const uno::Any& Order1, const uno::Any& Key2, const uno::Any& /*Type*/, const uno::Any& Order2, const uno::Any& Key3, const uno::Any& Order3, const uno::Any& Header, const uno::Any& OrderCustom, const uno::Any& MatchCase, const uno::Any& Orientation, const uno::Any& SortMethod, const uno::Any& DataOption1, const uno::Any& DataOption2, const uno::Any& DataOption3 )
+{
+ // #TODO# #FIXME# can we do something with Type
+ if ( m_Areas->getCount() > 1 )
+ throw uno::RuntimeException("That command cannot be used on multiple selections" );
+
+ sal_Int16 nDataOption1 = excel::XlSortDataOption::xlSortNormal;
+ sal_Int16 nDataOption2 = excel::XlSortDataOption::xlSortNormal;
+ sal_Int16 nDataOption3 = excel::XlSortDataOption::xlSortNormal;
+
+ ScDocument& rDoc = getScDocument();
+
+ uno::Reference< table::XCellRange > xRangeCurrent;
+ if (isSingleCellRange())
+ {
+ // Expand to CurrentRegion
+ uno::Reference< excel::XRange > xCurrent( CurrentRegion());
+ if (xCurrent.is())
+ {
+ const ScVbaRange* pRange = getImplementation( xCurrent );
+ if (pRange)
+ xRangeCurrent = pRange->mxRange;
+ }
+ }
+ if (!xRangeCurrent.is())
+ xRangeCurrent = mxRange;
+ RangeHelper thisRange( xRangeCurrent );
+ table::CellRangeAddress thisRangeAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+
+ ScSortParam aSortParam;
+ SCTAB nTab = thisRangeAddress.Sheet;
+ rDoc.GetSortParam( aSortParam, nTab );
+
+ if ( DataOption1.hasValue() )
+ DataOption1 >>= nDataOption1;
+ if ( DataOption2.hasValue() )
+ DataOption2 >>= nDataOption2;
+ if ( DataOption3.hasValue() )
+ DataOption3 >>= nDataOption3;
+
+ // 1) #TODO #FIXME need to process DataOption[1..3] not used currently
+ // 2) #TODO #FIXME need to refactor this ( below ) into an IsSingleCell() method
+ uno::Reference< table::XColumnRowRange > xColumnRowRange(xRangeCurrent, uno::UNO_QUERY_THROW );
+
+ // set up defaults
+
+ sal_Int16 nOrder1 = aSortParam.maKeyState[0].bAscending ? excel::XlSortOrder::xlAscending : excel::XlSortOrder::xlDescending;
+ sal_Int16 nOrder2 = aSortParam.maKeyState[1].bAscending ? excel::XlSortOrder::xlAscending : excel::XlSortOrder::xlDescending;
+ sal_Int16 nOrder3 = aSortParam.maKeyState[2].bAscending ? excel::XlSortOrder::xlAscending : excel::XlSortOrder::xlDescending;
+
+ sal_Int16 nCustom = aSortParam.nUserIndex;
+ sal_Int16 nSortMethod = excel::XlSortMethod::xlPinYin;
+ bool bMatchCase = aSortParam.bCaseSens;
+
+ // seems to work opposite to expected, see below
+ sal_Int16 nOrientation = aSortParam.bByRow ? excel::XlSortOrientation::xlSortColumns : excel::XlSortOrientation::xlSortRows;
+
+ if ( Orientation.hasValue() )
+ {
+ // Documentation says xlSortRows is default but that doesn't appear to be
+ // the case. Also it appears that xlSortColumns is the default which
+ // strangely enough sorts by Row
+ nOrientation = ::comphelper::getINT16( Orientation );
+ // persist new option to be next calls default
+ if ( nOrientation == excel::XlSortOrientation::xlSortRows )
+ aSortParam.bByRow = false;
+ else
+ aSortParam.bByRow = true;
+
+ }
+
+ bool bIsSortColumns=false; // sort by row
+
+ if ( nOrientation == excel::XlSortOrientation::xlSortRows )
+ bIsSortColumns = true;
+ sal_Int16 nHeader = aSortParam.nCompatHeader;
+ bool bContainsHeader = false;
+
+ if ( Header.hasValue() )
+ {
+ nHeader = ::comphelper::getINT16( Header );
+ aSortParam.nCompatHeader = nHeader;
+ }
+
+ if ( nHeader == excel::XlYesNoGuess::xlGuess )
+ {
+ bool bHasColHeader = rDoc.HasColHeader( static_cast< SCCOL >( thisRangeAddress.StartColumn ), static_cast< SCROW >( thisRangeAddress.StartRow ), static_cast< SCCOL >( thisRangeAddress.EndColumn ), static_cast< SCROW >( thisRangeAddress.EndRow ), static_cast< SCTAB >( thisRangeAddress.Sheet ));
+ bool bHasRowHeader = rDoc.HasRowHeader( static_cast< SCCOL >( thisRangeAddress.StartColumn ), static_cast< SCROW >( thisRangeAddress.StartRow ), static_cast< SCCOL >( thisRangeAddress.EndColumn ), static_cast< SCROW >( thisRangeAddress.EndRow ), static_cast< SCTAB >( thisRangeAddress.Sheet ) );
+ if ( bHasColHeader || bHasRowHeader )
+ nHeader = excel::XlYesNoGuess::xlYes;
+ else
+ nHeader = excel::XlYesNoGuess::xlNo;
+ aSortParam.nCompatHeader = nHeader;
+ }
+
+ if ( nHeader == excel::XlYesNoGuess::xlYes )
+ bContainsHeader = true;
+
+ if ( SortMethod.hasValue() )
+ {
+ nSortMethod = ::comphelper::getINT16( SortMethod );
+ }
+
+ if ( OrderCustom.hasValue() )
+ {
+ OrderCustom >>= nCustom;
+ --nCustom; // 0-based in OOo
+ aSortParam.nUserIndex = nCustom;
+ }
+
+ if ( MatchCase.hasValue() )
+ {
+ MatchCase >>= bMatchCase;
+ aSortParam.bCaseSens = bMatchCase;
+ }
+
+ if ( Order1.hasValue() )
+ {
+ nOrder1 = ::comphelper::getINT16(Order1);
+ if ( nOrder1 == excel::XlSortOrder::xlAscending )
+ aSortParam.maKeyState[0].bAscending = true;
+ else
+ aSortParam.maKeyState[0].bAscending = false;
+
+ }
+ if ( Order2.hasValue() )
+ {
+ nOrder2 = ::comphelper::getINT16(Order2);
+ if ( nOrder2 == excel::XlSortOrder::xlAscending )
+ aSortParam.maKeyState[1].bAscending = true;
+ else
+ aSortParam.maKeyState[1].bAscending = false;
+ }
+ if ( Order3.hasValue() )
+ {
+ nOrder3 = ::comphelper::getINT16(Order3);
+ if ( nOrder3 == excel::XlSortOrder::xlAscending )
+ aSortParam.maKeyState[2].bAscending = true;
+ else
+ aSortParam.maKeyState[2].bAscending = false;
+ }
+
+ uno::Reference< table::XCellRange > xKey1;
+ uno::Reference< table::XCellRange > xKey2;
+ uno::Reference< table::XCellRange > xKey3;
+ ScDocShell* pDocShell = getScDocShell();
+ xKey1 = processKey( Key1, mxContext, pDocShell );
+ if ( !xKey1.is() )
+ throw uno::RuntimeException("Range::Sort needs a key1 param" );
+
+ if ( Key2.hasValue() )
+ xKey2 = processKey( Key2, mxContext, pDocShell );
+ if ( Key3.hasValue() )
+ xKey3 = processKey( Key3, mxContext, pDocShell );
+
+ uno::Reference< util::XSortable > xSort( xRangeCurrent, uno::UNO_QUERY_THROW );
+ uno::Sequence< beans::PropertyValue > sortDescriptor = xSort->createSortDescriptor();
+ auto psortDescriptor = sortDescriptor.getArray();
+ sal_Int32 nTableSortFieldIndex = findSortPropertyIndex( sortDescriptor, "SortFields" );
+
+ uno::Sequence< table::TableSortField > sTableFields(1);
+ sal_Int32 nTableIndex = 0;
+ updateTableSortField( xRangeCurrent, xKey1, nOrder1, sTableFields.getArray()[ nTableIndex++ ], bIsSortColumns, bMatchCase );
+
+ if ( xKey2.is() )
+ {
+ sTableFields.realloc( sTableFields.getLength() + 1 );
+ updateTableSortField( xRangeCurrent, xKey2, nOrder2, sTableFields.getArray()[ nTableIndex++ ], bIsSortColumns, bMatchCase );
+ }
+ if ( xKey3.is() )
+ {
+ sTableFields.realloc( sTableFields.getLength() + 1 );
+ updateTableSortField( xRangeCurrent, xKey3, nOrder3, sTableFields.getArray()[ nTableIndex++ ], bIsSortColumns, bMatchCase );
+ }
+ psortDescriptor[ nTableSortFieldIndex ].Value <<= sTableFields;
+
+ sal_Int32 nIndex = findSortPropertyIndex( sortDescriptor, "IsSortColumns" );
+ psortDescriptor[ nIndex ].Value <<= bIsSortColumns;
+
+ nIndex = findSortPropertyIndex( sortDescriptor, "ContainsHeader" );
+ psortDescriptor[ nIndex ].Value <<= bContainsHeader;
+
+ rDoc.SetSortParam( aSortParam, nTab );
+ xSort->sort( sortDescriptor );
+
+ // #FIXME #TODO
+ // The SortMethod param is not processed ( not sure what its all about, need to
+ (void)nSortMethod;
+}
+
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaRange::End( ::sal_Int32 Direction )
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_SET_THROW );
+ return xRange->End( Direction );
+ }
+
+ // #FIXME #TODO
+ // euch! found my orig implementation sucked, so
+ // trying this even sucker one (really need to use/expose code in
+ // around ScTabView::MoveCursorArea(), that's the bit that calculates
+ // where the cursor should go)
+ // Main problem with this method is the ultra hacky attempt to preserve
+ // the ActiveCell, there should be no need to go to these extremes
+
+ // Save ActiveSheet/ActiveCell pos (to restore later)
+ uno::Any aDft;
+ uno::Reference< excel::XApplication > xApplication( Application(), uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XWorksheet > sActiveSheet = xApplication->getActiveSheet();
+ OUString sActiveCell = xApplication->getActiveCell()->Address(aDft, aDft, aDft, aDft, aDft );
+
+ // position current cell upper left of this range
+ Cells( uno::Any( sal_Int32(1) ), uno::Any( sal_Int32(1) ) )->Select();
+
+ uno::Reference< frame::XModel > xModel = getModelFromRange( mxRange );
+
+ SfxViewFrame* pViewFrame = excel::getViewFrame( xModel );
+ if ( pViewFrame )
+ {
+ SfxAllItemSet aArgs( SfxGetpApp()->GetPool() );
+ // Hoping this will make sure this slot is called
+ // synchronously
+ SfxBoolItem sfxAsync( SID_ASYNCHRON, false );
+ aArgs.Put( sfxAsync, sfxAsync.Which() );
+ SfxDispatcher* pDispatcher = pViewFrame->GetDispatcher();
+
+ sal_uInt16 nSID = 0;
+
+ switch( Direction )
+ {
+ case excel::XlDirection::xlDown:
+ nSID = SID_CURSORBLKDOWN;
+ break;
+ case excel::XlDirection::xlUp:
+ nSID = SID_CURSORBLKUP;
+ break;
+ case excel::XlDirection::xlToLeft:
+ nSID = SID_CURSORBLKLEFT;
+ break;
+ case excel::XlDirection::xlToRight:
+ nSID = SID_CURSORBLKRIGHT;
+ break;
+ default:
+ throw uno::RuntimeException(": Invalid ColumnIndex" );
+ }
+ if ( pDispatcher )
+ {
+ pDispatcher->Execute( nSID, SfxCallMode::SYNCHRON, aArgs );
+ }
+ }
+
+ // result is the ActiveCell
+ OUString sMoved = xApplication->getActiveCell()->Address(aDft, aDft, aDft, aDft, aDft );
+
+ uno::Any aVoid;
+ uno::Reference< excel::XRange > resultCell;
+ resultCell.set( xApplication->getActiveSheet()->Range( uno::Any( sMoved ), aVoid ), uno::UNO_SET_THROW );
+
+ // restore old ActiveCell
+ uno::Reference< excel::XRange > xOldActiveCell( sActiveSheet->Range( uno::Any( sActiveCell ), aVoid ), uno::UNO_SET_THROW );
+ xOldActiveCell->Select();
+
+
+ // return result
+ return resultCell;
+}
+
+bool
+ScVbaRange::isSingleCellRange() const
+{
+ uno::Reference< sheet::XCellRangeAddressable > xAddressable( mxRange, uno::UNO_QUERY );
+ if ( xAddressable.is() )
+ {
+ table::CellRangeAddress aRangeAddr = xAddressable->getRangeAddress();
+ return ( aRangeAddr.EndColumn == aRangeAddr.StartColumn && aRangeAddr.EndRow == aRangeAddr.StartRow );
+ }
+ return false;
+}
+
+uno::Reference< excel::XCharacters > SAL_CALL
+ScVbaRange::characters( const uno::Any& Start, const uno::Any& Length )
+{
+ if ( !isSingleCellRange() )
+ throw uno::RuntimeException("Can't create Characters property for multicell range " );
+ uno::Reference< text::XSimpleText > xSimple(mxRange->getCellByPosition(0,0) , uno::UNO_QUERY_THROW );
+ ScDocument& rDoc = getDocumentFromRange(mxRange);
+
+ ScVbaPalette aPalette( rDoc.GetDocumentShell() );
+ return new ScVbaCharacters( this, mxContext, aPalette, xSimple, Start, Length );
+}
+
+ void SAL_CALL
+ScVbaRange::Delete( const uno::Any& Shift )
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ sal_Int32 nItems = m_Areas->getCount();
+ for ( sal_Int32 index=1; index <= nItems; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::Any(index), uno::Any() ), uno::UNO_QUERY_THROW );
+ xRange->Delete( Shift );
+ }
+ return;
+ }
+ sheet::CellDeleteMode mode = sheet::CellDeleteMode_NONE ;
+ RangeHelper thisRange( mxRange );
+ table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+ if ( Shift.hasValue() )
+ {
+ sal_Int32 nShift = 0;
+ Shift >>= nShift;
+ switch ( nShift )
+ {
+ case excel::XlDeleteShiftDirection::xlShiftUp:
+ mode = sheet::CellDeleteMode_UP;
+ break;
+ case excel::XlDeleteShiftDirection::xlShiftToLeft:
+ mode = sheet::CellDeleteMode_LEFT;
+ break;
+ default:
+ throw uno::RuntimeException("Illegal parameter " );
+ }
+ }
+ else
+ {
+ ScDocument& rDoc = getScDocument();
+ bool bFullRow = ( thisAddress.StartColumn == 0 && thisAddress.EndColumn == rDoc.MaxCol() );
+ sal_Int32 nCols = thisAddress.EndColumn - thisAddress.StartColumn;
+ sal_Int32 nRows = thisAddress.EndRow - thisAddress.StartRow;
+ if ( mbIsRows || bFullRow || ( nCols >= nRows ) )
+ mode = sheet::CellDeleteMode_UP;
+ else
+ mode = sheet::CellDeleteMode_LEFT;
+ }
+ uno::Reference< sheet::XCellRangeMovement > xCellRangeMove( thisRange.getSpreadSheet(), uno::UNO_QUERY_THROW );
+ xCellRangeMove->removeRange( thisAddress, mode );
+
+}
+
+//XElementAccess
+sal_Bool SAL_CALL
+ScVbaRange::hasElements()
+{
+ uno::Reference< table::XColumnRowRange > xColumnRowRange(mxRange, uno::UNO_QUERY );
+ if ( xColumnRowRange.is() )
+ if ( xColumnRowRange->getRows()->getCount() ||
+ xColumnRowRange->getColumns()->getCount() )
+ return true;
+ return false;
+}
+
+// XEnumerationAccess
+uno::Reference< container::XEnumeration > SAL_CALL
+ScVbaRange::createEnumeration()
+{
+ if ( mbIsColumns || mbIsRows )
+ {
+ uno::Reference< table::XColumnRowRange > xColumnRowRange(mxRange, uno::UNO_QUERY );
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::Any( sal_Int32(1) ), uno::Any() ), uno::UNO_QUERY_THROW );
+ sal_Int32 nElems = 0;
+ if ( mbIsColumns )
+ nElems = xColumnRowRange->getColumns()->getCount();
+ else
+ nElems = xColumnRowRange->getRows()->getCount();
+ return new ColumnsRowEnumeration( xRange, nElems );
+
+ }
+ return new CellsEnumeration( mxParent, mxContext, m_Areas );
+}
+
+OUString SAL_CALL
+ScVbaRange::getDefaultMethodName( )
+{
+ return "Item";
+}
+
+// returns calc internal col. width ( in points )
+double
+ScVbaRange::getCalcColWidth(const table::CellRangeAddress& rAddress)
+{
+ ScDocument& rDoc = getScDocument();
+ sal_uInt16 nWidth = rDoc.GetOriginalWidth( static_cast< SCCOL >( rAddress.StartColumn ), static_cast< SCTAB >( rAddress.Sheet ) );
+ double nPoints = lcl_TwipsToPoints( nWidth );
+ nPoints = lcl_Round2DecPlaces( nPoints );
+ return nPoints;
+}
+
+double
+ScVbaRange::getCalcRowHeight(const table::CellRangeAddress& rAddress)
+{
+ ScDocument& rDoc = getDocumentFromRange( mxRange );
+ sal_uInt16 nWidth = rDoc.GetOriginalHeight( rAddress.StartRow, rAddress.Sheet );
+ double nPoints = lcl_TwipsToPoints( nWidth );
+ nPoints = lcl_Round2DecPlaces( nPoints );
+ return nPoints;
+}
+
+// return Char Width in points
+static double getDefaultCharWidth( ScDocShell* pDocShell )
+{
+ ScDocument& rDoc = pDocShell->GetDocument();
+ OutputDevice* pRefDevice = rDoc.GetRefDevice();
+ ScPatternAttr* pAttr = rDoc.GetDefPattern();
+ vcl::Font aDefFont;
+ pAttr->GetFont( aDefFont, SC_AUTOCOL_BLACK, pRefDevice );
+ pRefDevice->SetFont( aDefFont );
+ tools::Long nCharWidth = pRefDevice->GetTextWidth( OUString( '0' ) ); // 1/100th mm
+ return o3tl::convert<double>(nCharWidth, o3tl::Length::mm100, o3tl::Length::pt);
+}
+
+uno::Any SAL_CALL
+ScVbaRange::getColumnWidth()
+{
+ sal_Int32 nLen = m_Areas->getCount();
+ if ( nLen > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::Any( sal_Int32(1) ), uno::Any() ), uno::UNO_QUERY_THROW );
+ return xRange->getColumnWidth();
+ }
+
+ double nColWidth = 0;
+ ScDocShell* pShell = getScDocShell();
+ if ( pShell )
+ {
+ double defaultCharWidth = getDefaultCharWidth( pShell );
+ RangeHelper thisRange( mxRange );
+ table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+ sal_Int32 nStartCol = thisAddress.StartColumn;
+ sal_Int32 nEndCol = thisAddress.EndColumn;
+ sal_uInt16 nColTwips = 0;
+ for( sal_Int32 nCol = nStartCol ; nCol <= nEndCol; ++nCol )
+ {
+ thisAddress.StartColumn = nCol;
+ sal_uInt16 nCurTwips = pShell->GetDocument().GetOriginalWidth( static_cast< SCCOL >( thisAddress.StartColumn ), static_cast< SCTAB >( thisAddress.Sheet ) );
+ if ( nCol == nStartCol )
+ nColTwips = nCurTwips;
+ if ( nColTwips != nCurTwips )
+ return aNULL();
+ }
+ nColWidth = lcl_TwipsToPoints( nColTwips );
+ if ( nColWidth != 0.0 )
+ nColWidth = ( nColWidth / defaultCharWidth ) - fExtraWidth;
+ }
+ nColWidth = lcl_Round2DecPlaces( nColWidth );
+ return uno::Any( nColWidth );
+}
+
+void SAL_CALL
+ScVbaRange::setColumnWidth( const uno::Any& _columnwidth )
+{
+ sal_Int32 nLen = m_Areas->getCount();
+ if ( nLen > 1 )
+ {
+ for ( sal_Int32 index = 1; index != nLen; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::Any( index ), uno::Any() ), uno::UNO_QUERY_THROW );
+ xRange->setColumnWidth( _columnwidth );
+ }
+ return;
+ }
+ double nColWidth = 0;
+ _columnwidth >>= nColWidth;
+ nColWidth = lcl_Round2DecPlaces( nColWidth );
+ ScDocShell* pDocShell = getScDocShell();
+ if ( !pDocShell )
+ return;
+
+ if ( nColWidth != 0.0 )
+ nColWidth = ( nColWidth + fExtraWidth ) * getDefaultCharWidth( pDocShell );
+ RangeHelper thisRange( mxRange );
+ table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+ sal_uInt16 nTwips = lcl_pointsToTwips( nColWidth );
+
+ std::vector<sc::ColRowSpan> aColArr(1, sc::ColRowSpan(thisAddress.StartColumn, thisAddress.EndColumn));
+ // #163561# use mode SC_SIZE_DIRECT: hide for width 0, show for other values
+ pDocShell->GetDocFunc().SetWidthOrHeight(
+ true, aColArr, thisAddress.Sheet, SC_SIZE_DIRECT, nTwips, true, true);
+}
+
+uno::Any SAL_CALL
+ScVbaRange::getWidth()
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::Any( sal_Int32(1) ), uno::Any() ), uno::UNO_QUERY_THROW );
+ return xRange->getWidth();
+ }
+ uno::Reference< table::XColumnRowRange > xColRowRange( mxRange, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xIndexAccess( xColRowRange->getColumns(), uno::UNO_QUERY_THROW );
+ sal_Int32 nElems = xIndexAccess->getCount();
+ double nWidth = 0;
+ for ( sal_Int32 index=0; index<nElems; ++index )
+ {
+ uno::Reference< sheet::XCellRangeAddressable > xAddressable( xIndexAccess->getByIndex( index ), uno::UNO_QUERY_THROW );
+ double nTmpWidth = getCalcColWidth( xAddressable->getRangeAddress() );
+ nWidth += nTmpWidth;
+ }
+ return uno::Any( nWidth );
+}
+
+uno::Any SAL_CALL
+ScVbaRange::Areas( const uno::Any& item)
+{
+ if ( !item.hasValue() )
+ return uno::Any( m_Areas );
+ return m_Areas->Item( item, uno::Any() );
+}
+
+uno::Reference< excel::XRange >
+ScVbaRange::getArea( sal_Int32 nIndex )
+{
+ if ( !m_Areas.is() )
+ throw uno::RuntimeException("No areas available" );
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::Any( ++nIndex ), uno::Any() ), uno::UNO_QUERY_THROW );
+ return xRange;
+}
+
+uno::Any
+ScVbaRange::Borders( const uno::Any& item )
+{
+ if ( !item.hasValue() )
+ return uno::Any( getBorders() );
+ return getBorders()->Item( item, uno::Any() );
+}
+
+uno::Any SAL_CALL
+ScVbaRange::BorderAround( const css::uno::Any& LineStyle, const css::uno::Any& Weight,
+ const css::uno::Any& ColorIndex, const css::uno::Any& Color )
+{
+ sal_Int32 nCount = getBorders()->getCount();
+
+ for( sal_Int32 i = 0; i < nCount; i++ )
+ {
+ const sal_Int32 nLineType = supportedIndexTable[i];
+ switch( nLineType )
+ {
+ case excel::XlBordersIndex::xlEdgeLeft:
+ case excel::XlBordersIndex::xlEdgeTop:
+ case excel::XlBordersIndex::xlEdgeBottom:
+ case excel::XlBordersIndex::xlEdgeRight:
+ {
+ uno::Reference< excel::XBorder > xBorder( m_Borders->Item( uno::Any( nLineType ), uno::Any() ), uno::UNO_QUERY_THROW );
+ if( LineStyle.hasValue() )
+ {
+ xBorder->setLineStyle( LineStyle );
+ }
+ if( Weight.hasValue() )
+ {
+ xBorder->setWeight( Weight );
+ }
+ if( ColorIndex.hasValue() )
+ {
+ xBorder->setColorIndex( ColorIndex );
+ }
+ if( Color.hasValue() )
+ {
+ xBorder->setColor( Color );
+ }
+ break;
+ }
+ case excel::XlBordersIndex::xlInsideVertical:
+ case excel::XlBordersIndex::xlInsideHorizontal:
+ case excel::XlBordersIndex::xlDiagonalDown:
+ case excel::XlBordersIndex::xlDiagonalUp:
+ break;
+ default:
+ return uno::Any( false );
+ }
+ }
+ return uno::Any( true );
+}
+
+uno::Any SAL_CALL
+ScVbaRange::getRowHeight()
+{
+ sal_Int32 nLen = m_Areas->getCount();
+ if ( nLen > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::Any( sal_Int32(1) ), uno::Any() ), uno::UNO_QUERY_THROW );
+ return xRange->getRowHeight();
+ }
+
+ // if any row's RowHeight in the
+ // range is different from any other, then return NULL
+ RangeHelper thisRange( mxRange );
+ table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+
+ sal_Int32 nStartRow = thisAddress.StartRow;
+ sal_Int32 nEndRow = thisAddress.EndRow;
+ sal_uInt16 nRowTwips = 0;
+ // #TODO probably possible to use the SfxItemSet (and see if
+ // SfxItemState::DONTCARE is set) to improve performance
+// #CHECKME looks like this is general behaviour not just row Range specific
+// if ( mbIsRows )
+ ScDocShell* pShell = getScDocShell();
+ if ( pShell )
+ {
+ for ( sal_Int32 nRow = nStartRow ; nRow <= nEndRow; ++nRow )
+ {
+ thisAddress.StartRow = nRow;
+ sal_uInt16 nCurTwips = pShell->GetDocument().GetOriginalHeight( thisAddress.StartRow, thisAddress.Sheet );
+ if ( nRow == nStartRow )
+ nRowTwips = nCurTwips;
+ if ( nRowTwips != nCurTwips )
+ return aNULL();
+ }
+ }
+ double nHeight = lcl_Round2DecPlaces( lcl_TwipsToPoints( nRowTwips ) );
+ return uno::Any( nHeight );
+}
+
+void SAL_CALL
+ScVbaRange::setRowHeight( const uno::Any& _rowheight)
+{
+ sal_Int32 nLen = m_Areas->getCount();
+ if ( nLen > 1 )
+ {
+ for ( sal_Int32 index = 1; index != nLen; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::Any( index ), uno::Any() ), uno::UNO_QUERY_THROW );
+ xRange->setRowHeight( _rowheight );
+ }
+ return;
+ }
+ double nHeight = 0; // Incoming height is in points
+ _rowheight >>= nHeight;
+ nHeight = lcl_Round2DecPlaces( nHeight );
+ RangeHelper thisRange( mxRange );
+ table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+ sal_uInt16 nTwips = lcl_pointsToTwips( nHeight );
+
+ ScDocShell* pDocShell = getDocShellFromRange( mxRange );
+ std::vector<sc::ColRowSpan> aRowArr(1, sc::ColRowSpan(thisAddress.StartRow, thisAddress.EndRow));
+ pDocShell->GetDocFunc().SetWidthOrHeight(
+ false, aRowArr, thisAddress.Sheet, SC_SIZE_ORIGINAL, nTwips, true, true);
+}
+
+uno::Any SAL_CALL
+ScVbaRange::getPageBreak()
+{
+ sal_Int32 nPageBreak = excel::XlPageBreak::xlPageBreakNone;
+ ScDocShell* pShell = getDocShellFromRange( mxRange );
+ if ( pShell )
+ {
+ RangeHelper thisRange( mxRange );
+ table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+ bool bColumn = false;
+
+ if (thisAddress.StartRow==0)
+ bColumn = true;
+
+ uno::Reference< frame::XModel > xModel = pShell->GetModel();
+ if ( xModel.is() )
+ {
+ ScDocument& rDoc = getDocumentFromRange( mxRange );
+
+ ScBreakType nBreak = ScBreakType::NONE;
+ if ( !bColumn )
+ nBreak = rDoc.HasRowBreak(thisAddress.StartRow, thisAddress.Sheet);
+ else
+ nBreak = rDoc.HasColBreak(thisAddress.StartColumn, thisAddress.Sheet);
+
+ if (nBreak & ScBreakType::Page)
+ nPageBreak = excel::XlPageBreak::xlPageBreakAutomatic;
+
+ if (nBreak & ScBreakType::Manual)
+ nPageBreak = excel::XlPageBreak::xlPageBreakManual;
+ }
+ }
+
+ return uno::Any( nPageBreak );
+}
+
+void SAL_CALL
+ScVbaRange::setPageBreak( const uno::Any& _pagebreak)
+{
+ sal_Int32 nPageBreak = 0;
+ _pagebreak >>= nPageBreak;
+
+ ScDocShell* pShell = getDocShellFromRange( mxRange );
+ if ( !pShell )
+ return;
+
+ RangeHelper thisRange( mxRange );
+ table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+ if ((thisAddress.StartColumn==0) && (thisAddress.StartRow==0))
+ return;
+ bool bColumn = false;
+
+ if (thisAddress.StartRow==0)
+ bColumn = true;
+
+ ScAddress aAddr( static_cast<SCCOL>(thisAddress.StartColumn), thisAddress.StartRow, thisAddress.Sheet );
+ uno::Reference< frame::XModel > xModel = pShell->GetModel();
+ if ( xModel.is() )
+ {
+ ScTabViewShell* pViewShell = excel::getBestViewShell( xModel );
+ if ( nPageBreak == excel::XlPageBreak::xlPageBreakManual )
+ pViewShell->InsertPageBreak( bColumn, true, &aAddr);
+ else if ( nPageBreak == excel::XlPageBreak::xlPageBreakNone )
+ pViewShell->DeletePageBreak( bColumn, true, &aAddr);
+ }
+}
+
+uno::Any SAL_CALL
+ScVbaRange::getHeight()
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::Any( sal_Int32(1) ), uno::Any() ), uno::UNO_QUERY_THROW );
+ return xRange->getHeight();
+ }
+
+ uno::Reference< table::XColumnRowRange > xColRowRange( mxRange, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xIndexAccess( xColRowRange->getRows(), uno::UNO_QUERY_THROW );
+ sal_Int32 nElems = xIndexAccess->getCount();
+ double nHeight = 0;
+ for ( sal_Int32 index=0; index<nElems; ++index )
+ {
+ uno::Reference< sheet::XCellRangeAddressable > xAddressable( xIndexAccess->getByIndex( index ), uno::UNO_QUERY_THROW );
+ nHeight += getCalcRowHeight(xAddressable->getRangeAddress() );
+ }
+ return uno::Any( nHeight );
+}
+
+awt::Point
+ScVbaRange::getPosition() const
+{
+ awt::Point aPoint;
+ uno::Reference< beans::XPropertySet > xProps;
+ if ( mxRange.is() )
+ xProps.set( mxRange, uno::UNO_QUERY_THROW );
+ else
+ xProps.set( mxRanges, uno::UNO_QUERY_THROW );
+ xProps->getPropertyValue( "Position" ) >>= aPoint;
+ return aPoint;
+}
+uno::Any SAL_CALL
+ScVbaRange::getLeft()
+{
+ // helperapi returns the first ranges left ( and top below )
+ if ( m_Areas->getCount() > 1 )
+ return getArea( 0 )->getLeft();
+ awt::Point aPoint = getPosition();
+ return uno::Any(o3tl::convert<double>(aPoint.X, o3tl::Length::mm100, o3tl::Length::pt));
+}
+
+uno::Any SAL_CALL
+ScVbaRange::getTop()
+{
+ // helperapi returns the first ranges top
+ if ( m_Areas->getCount() > 1 )
+ return getArea( 0 )->getTop();
+ awt::Point aPoint= getPosition();
+ return uno::Any(o3tl::convert<double>(aPoint.Y, o3tl::Length::mm100, o3tl::Length::pt));
+}
+
+static uno::Reference< sheet::XCellRangeReferrer > getNamedRange( const uno::Reference< uno::XInterface >& xIf, const uno::Reference< table::XCellRange >& thisRange )
+{
+ uno::Reference< beans::XPropertySet > xProps( xIf, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XNameAccess > xNameAccess( xProps->getPropertyValue( "NamedRanges" ), uno::UNO_QUERY_THROW );
+
+ const uno::Sequence< OUString > sNames = xNameAccess->getElementNames();
+// uno::Reference< table::XCellRange > thisRange( getCellRange(), uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XCellRangeReferrer > xNamedRange;
+ for ( const auto& rName : sNames )
+ {
+ uno::Reference< sheet::XCellRangeReferrer > xName( xNameAccess->getByName( rName ), uno::UNO_QUERY );
+ if ( xName.is() )
+ {
+ if ( thisRange == xName->getReferredCells() )
+ {
+ xNamedRange = xName;
+ break;
+ }
+ }
+ }
+ return xNamedRange;
+}
+
+uno::Reference< excel::XName >
+ScVbaRange::getName()
+{
+ uno::Reference< beans::XPropertySet > xProps( getUnoModel(), uno::UNO_QUERY );
+ uno::Reference< table::XCellRange > thisRange( getCellRange(), uno::UNO_QUERY_THROW );
+ // Application range
+ uno::Reference< sheet::XCellRangeReferrer > xNamedRange = getNamedRange( xProps, thisRange );
+
+ if ( !xNamedRange.is() )
+ {
+ // not in application range then assume it might be in
+ // sheet namedranges
+ RangeHelper aRange( thisRange );
+ uno::Reference< sheet::XSpreadsheet > xSheet = aRange.getSpreadSheet();
+ xProps.set( xSheet, uno::UNO_QUERY );
+ // impl here
+ xNamedRange = getNamedRange( xProps, thisRange );
+ }
+ if ( xProps.is() && xNamedRange.is() )
+ {
+ uno::Reference< sheet::XNamedRanges > xNamedRanges( xProps, uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XNamedRange > xName( xNamedRange, uno::UNO_QUERY_THROW );
+ return new ScVbaName( mxParent, mxContext, xName, xNamedRanges, getUnoModel() );
+ }
+ return uno::Reference< excel::XName >();
+}
+
+uno::Reference< excel::XWorksheet >
+ScVbaRange::getWorksheet()
+{
+ // #TODO #FIXME parent should always be set up ( currently that's not
+ // the case )
+ uno::Reference< excel::XWorksheet > xSheet( getParent(), uno::UNO_QUERY );
+ if ( !xSheet.is() )
+ {
+ uno::Reference< table::XCellRange > xRange = mxRange;
+
+ if ( mxRanges.is() ) // assign xRange to first range
+ {
+ uno::Reference< container::XIndexAccess > xIndex( mxRanges, uno::UNO_QUERY_THROW );
+ xRange.set( xIndex->getByIndex( 0 ), uno::UNO_QUERY_THROW );
+ }
+ ScDocShell* pDocShell = getDocShellFromRange(xRange);
+ RangeHelper rHelper(xRange);
+ // parent should be Thisworkbook
+ xSheet.set( new ScVbaWorksheet( uno::Reference< XHelperInterface >(), mxContext,rHelper.getSpreadSheet(),pDocShell->GetModel()) );
+ }
+ return xSheet;
+}
+
+// #TODO remove this ugly application processing
+// Process an application Range request e.g. 'Range("a1,b2,a4:b6")
+uno::Reference< excel::XRange >
+ScVbaRange::ApplicationRange( const uno::Reference< uno::XComponentContext >& xContext, const css::uno::Any &Cell1, const css::uno::Any &Cell2 )
+{
+ // Although the documentation seems clear that Range without a
+ // qualifier then it's a shortcut for ActiveSheet.Range
+ // however, similarly Application.Range is apparently also a
+ // shortcut for ActiveSheet.Range
+ // The is however a subtle behavioural difference I've come across
+ // wrt to named ranges.
+ // If a named range "test" exists { Sheet1!$A1 } and the active sheet
+ // is Sheet2 then the following will fail
+ // msgbox ActiveSheet.Range("test").Address ' fails
+ // msgbox WorkSheets("Sheet2").Range("test").Address
+ // but!!!
+ // msgbox Range("test").Address ' works
+ // msgbox Application.Range("test").Address ' works
+
+ // Single param Range
+ OUString sRangeName;
+ Cell1 >>= sRangeName;
+ if ( Cell1.hasValue() && !Cell2.hasValue() && !sRangeName.isEmpty() )
+ {
+ uno::Reference< beans::XPropertySet > xPropSet( getCurrentExcelDoc(xContext), uno::UNO_QUERY_THROW );
+
+ uno::Reference< container::XNameAccess > xNamed( xPropSet->getPropertyValue( "NamedRanges" ), uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XCellRangeReferrer > xReferrer;
+ try
+ {
+ xReferrer.set ( xNamed->getByName( sRangeName ), uno::UNO_QUERY );
+ }
+ catch( uno::Exception& /*e*/ )
+ {
+ // do nothing
+ }
+ if ( xReferrer.is() )
+ {
+ uno::Reference< table::XCellRange > xRange = xReferrer->getReferredCells();
+ if ( xRange.is() )
+ {
+ uno::Reference< excel::XRange > xVbRange = new ScVbaRange( excel::getUnoSheetModuleObj( xRange ), xContext, xRange );
+ return xVbRange;
+ }
+ }
+ }
+
+ uno::Reference<table::XCellRange> xSheetRange;
+
+ try
+ {
+ uno::Reference<sheet::XSpreadsheetView> xView(
+ getCurrentExcelDoc(xContext)->getCurrentController(), uno::UNO_QUERY_THROW);
+
+ xSheetRange.set(xView->getActiveSheet(), uno::UNO_QUERY_THROW);
+ }
+ catch (const uno::Exception&)
+ {
+ return uno::Reference<excel::XRange>();
+ }
+
+ rtl::Reference<ScVbaRange> pRange = new ScVbaRange( excel::getUnoSheetModuleObj( xSheetRange ), xContext, xSheetRange );
+ return pRange->Range( Cell1, Cell2, true );
+}
+
+// Helper functions for AutoFilter
+static ScDBData* lcl_GetDBData_Impl( ScDocShell* pDocShell, sal_Int16 nSheet )
+{
+ ScDBData* pRet = nullptr;
+ if (pDocShell)
+ {
+ pRet = pDocShell->GetDocument().GetAnonymousDBData(nSheet);
+ }
+ return pRet;
+}
+
+static void lcl_SelectAll( ScDocShell* pDocShell, const ScQueryParam& aParam )
+{
+ if ( !pDocShell )
+ return;
+
+ ScViewData* pViewData = ScDocShell::GetViewData();
+ if ( !pViewData )
+ {
+ ScTabViewShell* pViewSh = pDocShell->GetBestViewShell( true );
+ pViewData = pViewSh ? &pViewSh->GetViewData() : nullptr;
+ }
+
+ if ( pViewData )
+ {
+ pViewData->GetView()->Query( aParam, nullptr, true );
+ }
+}
+
+static ScQueryParam lcl_GetQueryParam( ScDocShell* pDocShell, sal_Int16 nSheet )
+{
+ ScDBData* pDBData = lcl_GetDBData_Impl( pDocShell, nSheet );
+ ScQueryParam aParam;
+ if (pDBData)
+ {
+ pDBData->GetQueryParam( aParam );
+ }
+ return aParam;
+}
+
+static void lcl_SetAllQueryForField( ScDocShell* pDocShell, SCCOLROW nField, sal_Int16 nSheet )
+{
+ ScQueryParam aParam = lcl_GetQueryParam( pDocShell, nSheet );
+ aParam.RemoveEntryByField(nField);
+ lcl_SelectAll( pDocShell, aParam );
+}
+
+// Modifies sCriteria, and nOp depending on the value of sCriteria
+static void lcl_setTableFieldsFromCriteria( OUString& sCriteria1, const uno::Reference< beans::XPropertySet >& xDescProps, sheet::TableFilterField2& rFilterField )
+{
+ // #TODO make this more efficient and cycle through
+ // sCriteria1 character by character to pick up <,<>,=, * etc.
+ // right now I am more concerned with just getting it to work right
+
+ sCriteria1 = sCriteria1.trim();
+ // table of translation of criteria text to FilterOperators
+ // <>searchtext - NOT_EQUAL
+ // =searchtext - EQUAL
+ // *searchtext - startwith
+ // <>*searchtext - doesn't startwith
+ // *searchtext* - contains
+ // <>*searchtext* - doesn't contain
+ // [>|>=|<=|...]searchtext for GREATER_value, GREATER_EQUAL_value etc.
+ if ( sCriteria1.startsWith( EQUALS ) )
+ {
+ if ( o3tl::make_unsigned(sCriteria1.getLength()) == strlen(EQUALS) )
+ rFilterField.Operator = sheet::FilterOperator2::EMPTY;
+ else
+ {
+ rFilterField.Operator = sheet::FilterOperator2::EQUAL;
+ sCriteria1 = sCriteria1.copy( strlen(EQUALS) );
+ sCriteria1 = VBAToRegexp( sCriteria1 );
+ // UseRegularExpressions
+ if ( xDescProps.is() )
+ xDescProps->setPropertyValue( "UseRegularExpressions", uno::Any( true ) );
+ }
+
+ }
+ else if ( sCriteria1.startsWith( NOTEQUALS ) )
+ {
+ if ( o3tl::make_unsigned(sCriteria1.getLength()) == strlen(NOTEQUALS) )
+ rFilterField.Operator = sheet::FilterOperator2::NOT_EMPTY;
+ else
+ {
+ rFilterField.Operator = sheet::FilterOperator2::NOT_EQUAL;
+ sCriteria1 = sCriteria1.copy( strlen(NOTEQUALS) );
+ sCriteria1 = VBAToRegexp( sCriteria1 );
+ // UseRegularExpressions
+ if ( xDescProps.is() )
+ xDescProps->setPropertyValue( "UseRegularExpressions", uno::Any( true ) );
+ }
+ }
+ else if ( sCriteria1.startsWith( GREATERTHAN ) )
+ {
+ if ( sCriteria1.startsWith( GREATERTHANEQUALS ) )
+ {
+ sCriteria1 = sCriteria1.copy( strlen(GREATERTHANEQUALS) );
+ rFilterField.Operator = sheet::FilterOperator2::GREATER_EQUAL;
+ }
+ else
+ {
+ sCriteria1 = sCriteria1.copy( strlen(GREATERTHAN) );
+ rFilterField.Operator = sheet::FilterOperator2::GREATER;
+ }
+
+ }
+ else if ( sCriteria1.startsWith( LESSTHAN ) )
+ {
+ if ( sCriteria1.startsWith( LESSTHANEQUALS ) )
+ {
+ sCriteria1 = sCriteria1.copy( strlen(LESSTHANEQUALS) );
+ rFilterField.Operator = sheet::FilterOperator2::LESS_EQUAL;
+ }
+ else
+ {
+ sCriteria1 = sCriteria1.copy( strlen(LESSTHAN) );
+ rFilterField.Operator = sheet::FilterOperator2::LESS;
+ }
+
+ }
+ else
+ rFilterField.Operator = sheet::FilterOperator2::EQUAL;
+
+ // tdf#107885 - check if criteria is numeric using locale dependent settings without group separator
+ // or, if the decimal separator is different from the English locale, without any locale.
+ sal_Int32 nParseEnd = 0;
+ rtl_math_ConversionStatus eStatus = rtl_math_ConversionStatus_Ok;
+ double fValue = ScGlobal::getLocaleData().stringToDouble( sCriteria1, false, &eStatus, &nParseEnd );
+ if ( nParseEnd == sCriteria1.getLength() && eStatus == rtl_math_ConversionStatus_Ok )
+ {
+ rFilterField.IsNumeric = true;
+ rFilterField.NumericValue = fValue;
+ }
+ else if ( ScGlobal::getLocaleData().getNumDecimalSep().toChar() != '.' )
+ {
+ eStatus = rtl_math_ConversionStatus_Ok;
+ fValue = ::rtl::math::stringToDouble( sCriteria1, '.', 0, &eStatus, &nParseEnd );
+ if ( nParseEnd == sCriteria1.getLength() && eStatus == rtl_math_ConversionStatus_Ok )
+ {
+ rFilterField.IsNumeric = true;
+ rFilterField.NumericValue = fValue;
+ }
+ }
+
+ rFilterField.StringValue = sCriteria1;
+}
+
+void SAL_CALL
+ScVbaRange::AutoFilter( const uno::Any& aField, const uno::Any& Criteria1, const uno::Any& Operator, const uno::Any& Criteria2, const uno::Any& /*VisibleDropDown*/ )
+{
+ // Is there an existing autofilter
+ RangeHelper thisRange( mxRange );
+ table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+ sal_Int16 nSheet = thisAddress.Sheet;
+ ScDocShell* pShell = getScDocShell();
+ bool bHasAuto = false;
+ uno::Reference< sheet::XDatabaseRange > xDataBaseRange = excel::GetAutoFiltRange( pShell, nSheet );
+ if ( xDataBaseRange.is() )
+ bHasAuto = true;
+
+ if ( !bHasAuto )
+ {
+ if ( m_Areas->getCount() > 1 )
+ throw uno::RuntimeException( STR_ERRORMESSAGE_APPLIESTOSINGLERANGEONLY );
+
+ table::CellRangeAddress autoFiltAddress;
+ //CurrentRegion()
+ if ( isSingleCellRange() )
+ {
+ uno::Reference< excel::XRange > xCurrent( CurrentRegion() );
+ if ( xCurrent.is() )
+ {
+ ScVbaRange* pRange = getImplementation( xCurrent );
+ if ( pRange )
+ {
+ if ( pRange->isSingleCellRange() )
+ throw uno::RuntimeException("Can't create AutoFilter" );
+ RangeHelper currentRegion( pRange->mxRange );
+ autoFiltAddress = currentRegion.getCellRangeAddressable()->getRangeAddress();
+ }
+ }
+ }
+ else // multi-cell range
+ {
+ RangeHelper multiCellRange( mxRange );
+ autoFiltAddress = multiCellRange.getCellRangeAddressable()->getRangeAddress();
+ // #163530# Filter box shows only entry of first row
+ ScDocument* pDocument = ( pShell ? &pShell->GetDocument() : nullptr );
+ if ( pDocument )
+ {
+ SCCOL nStartCol = autoFiltAddress.StartColumn;
+ SCROW nStartRow = autoFiltAddress.StartRow;
+ SCCOL nEndCol = autoFiltAddress.EndColumn;
+ SCROW nEndRow = autoFiltAddress.EndRow;
+ pDocument->GetDataArea( autoFiltAddress.Sheet, nStartCol, nStartRow, nEndCol, nEndRow, true, true );
+ autoFiltAddress.StartColumn = nStartCol;
+ autoFiltAddress.StartRow = nStartRow;
+ autoFiltAddress.EndColumn = nEndCol;
+ autoFiltAddress.EndRow = nEndRow;
+ }
+ }
+
+ uno::Reference< sheet::XUnnamedDatabaseRanges > xDBRanges = excel::GetUnnamedDataBaseRanges( pShell );
+ if ( xDBRanges.is() )
+ {
+ if ( !xDBRanges->hasByTable( nSheet ) )
+ xDBRanges->setByTable( autoFiltAddress );
+ xDataBaseRange.set( xDBRanges->getByTable(nSheet ), uno::UNO_QUERY_THROW );
+ }
+ if ( !xDataBaseRange.is() )
+ throw uno::RuntimeException("Failed to find the autofilter placeholder range" );
+
+ uno::Reference< beans::XPropertySet > xDBRangeProps( xDataBaseRange, uno::UNO_QUERY_THROW );
+ // set autofilter
+ xDBRangeProps->setPropertyValue( "AutoFilter", uno::Any(true) );
+ // set header (autofilter always need column headers)
+ uno::Reference< beans::XPropertySet > xFiltProps( xDataBaseRange->getFilterDescriptor(), uno::UNO_QUERY_THROW );
+ xFiltProps->setPropertyValue( "ContainsHeader", uno::Any( true ) );
+ }
+
+ sal_Int32 nField = 0; // *IS* 1 based
+ sal_Int32 nOperator = excel::XlAutoFilterOperator::xlAnd;
+
+ sheet::FilterConnection nConn = sheet::FilterConnection_AND;
+ double nCriteria1 = 0;
+
+ bool bHasCritValue = Criteria1.hasValue();
+ bool bCritHasNumericValue = false; // not sure if a numeric criteria is possible
+ if ( bHasCritValue )
+ bCritHasNumericValue = ( Criteria1 >>= nCriteria1 );
+
+ if ( !aField.hasValue() && ( Criteria1.hasValue() || Operator.hasValue() || Criteria2.hasValue() ) )
+ throw uno::RuntimeException();
+ uno::Any Field( aField );
+ if ( !( Field >>= nField ) )
+ {
+ const uno::Reference< script::XTypeConverter >& xConverter = getTypeConverter( mxContext );
+ try
+ {
+ Field = xConverter->convertTo( aField, cppu::UnoType<sal_Int32>::get() );
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+ // Use the normal uno api, sometimes e.g. when you want to use ALL as the filter
+ // we can't use refresh as the uno interface doesn't have a concept of ALL
+ // in this case we just call the core calc functionality -
+ if ( Field >>= nField )
+ {
+ uno::Reference< sheet::XSheetFilterDescriptor2 > xDesc(
+ xDataBaseRange->getFilterDescriptor(), uno::UNO_QUERY );
+ if ( xDesc.is() )
+ {
+ OUString sCriteria1;
+ bool bAcceptCriteria2 = true;
+ bool bAll = false;
+ uno::Sequence< sheet::TableFilterField2 > sTabFilts;
+ sheet::TableFilterField2* pTabFilts = nullptr;
+ uno::Reference< beans::XPropertySet > xDescProps( xDesc, uno::UNO_QUERY_THROW );
+ if ( Criteria1.hasValue() )
+ {
+ sTabFilts.realloc( 1 );
+ pTabFilts = sTabFilts.getArray();
+ pTabFilts[0].Operator = sheet::FilterOperator2::EQUAL;// sensible default
+ if ( !bCritHasNumericValue )
+ {
+ Criteria1 >>= sCriteria1;
+ if ( sCriteria1.isEmpty() )
+ {
+ uno::Sequence< OUString > aCriteria1;
+ Criteria1 >>= aCriteria1;
+ sal_uInt16 nLength = aCriteria1.getLength();
+ if ( nLength )
+ {
+ // When sequence is provided for Criteria1 don't care about Criteria2
+ bAcceptCriteria2 = false;
+
+ auto pCriteria1 = aCriteria1.getArray();
+ sTabFilts.realloc( nLength );
+ pTabFilts = sTabFilts.getArray();
+ for ( sal_uInt16 i = 0; i < nLength; ++i )
+ {
+ lcl_setTableFieldsFromCriteria( pCriteria1[i], xDescProps, pTabFilts[i] );
+ pTabFilts[i].Connection = sheet::FilterConnection_OR;
+ pTabFilts[i].Field = (nField - 1);
+ }
+ }
+ else
+ bAll = true;
+ }
+ else
+ {
+ pTabFilts[0].IsNumeric = bCritHasNumericValue;
+ if ( bHasCritValue && !sCriteria1.isEmpty() )
+ lcl_setTableFieldsFromCriteria( sCriteria1, xDescProps, pTabFilts[0] );
+ else
+ bAll = true;
+ }
+ }
+ else // numeric
+ {
+ pTabFilts[0].IsNumeric = true;
+ pTabFilts[0].NumericValue = nCriteria1;
+ }
+ }
+ else // no value specified
+ bAll = true;
+ // not sure what the relationship between Criteria1 and Operator is,
+ // e.g. can you have an Operator without a Criteria? In LibreOffice it
+ if ( Operator.hasValue() && ( Operator >>= nOperator ) )
+ {
+ // if it's a bottom/top Ten(Percent/Value) and there
+ // is no value specified for criteria1 set it to 10
+ if ( !bCritHasNumericValue && sCriteria1.isEmpty() && ( nOperator != excel::XlAutoFilterOperator::xlOr ) && ( nOperator != excel::XlAutoFilterOperator::xlAnd ) )
+ {
+ pTabFilts[0].IsNumeric = true;
+ pTabFilts[0].NumericValue = 10;
+ bAll = false;
+ }
+ switch ( nOperator )
+ {
+ case excel::XlAutoFilterOperator::xlBottom10Items:
+ pTabFilts[0].Operator = sheet::FilterOperator2::BOTTOM_VALUES;
+ break;
+ case excel::XlAutoFilterOperator::xlBottom10Percent:
+ pTabFilts[0].Operator = sheet::FilterOperator2::BOTTOM_PERCENT;
+ break;
+ case excel::XlAutoFilterOperator::xlTop10Items:
+ pTabFilts[0].Operator = sheet::FilterOperator2::TOP_VALUES;
+ break;
+ case excel::XlAutoFilterOperator::xlTop10Percent:
+ pTabFilts[0].Operator = sheet::FilterOperator2::TOP_PERCENT;
+ break;
+ case excel::XlAutoFilterOperator::xlOr:
+ nConn = sheet::FilterConnection_OR;
+ break;
+ case excel::XlAutoFilterOperator::xlAnd:
+ nConn = sheet::FilterConnection_AND;
+ break;
+ default:
+ throw uno::RuntimeException("UnknownOption" );
+
+ }
+
+ }
+ if ( !bAll && bAcceptCriteria2 )
+ {
+ pTabFilts[0].Connection = sheet::FilterConnection_AND;
+ pTabFilts[0].Field = (nField - 1);
+
+ uno::Sequence< OUString > aCriteria2;
+ if ( Criteria2.hasValue() ) // there is a Criteria2
+ {
+ sTabFilts.realloc(2);
+ pTabFilts = sTabFilts.getArray();
+ pTabFilts[1].Field = sTabFilts[0].Field;
+ pTabFilts[1].Connection = nConn;
+
+ OUString sCriteria2;
+ if ( Criteria2 >>= sCriteria2 )
+ {
+ if ( !sCriteria2.isEmpty() )
+ {
+ uno::Reference< beans::XPropertySet > xProps;
+ lcl_setTableFieldsFromCriteria( sCriteria2, xProps, pTabFilts[1] );
+ pTabFilts[1].IsNumeric = false;
+ }
+ }
+ else if ( Criteria2 >>= aCriteria2 )
+ {
+ sal_uInt16 nLength = aCriteria2.getLength();
+ if ( nLength )
+ {
+ // For compatibility use only the last value from the sequence
+ lcl_setTableFieldsFromCriteria( aCriteria2.getArray()[nLength - 1], xDescProps, pTabFilts[1] );
+ }
+ }
+ else // numeric
+ {
+ Criteria2 >>= pTabFilts[1].NumericValue;
+ pTabFilts[1].IsNumeric = true;
+ pTabFilts[1].Operator = sheet::FilterOperator2::EQUAL;
+ }
+ }
+ }
+
+ xDesc->setFilterFields2( sTabFilts );
+ if ( !bAll )
+ {
+ xDataBaseRange->refresh();
+ }
+ else
+ // was 0 based now seems to be 1
+ lcl_SetAllQueryForField( pShell, nField, nSheet );
+ }
+ }
+ else
+ {
+ // this is just to toggle autofilter on and off ( not to be confused with
+ // a VisibleDropDown option combined with a field, in that case just the
+ // button should be disabled ) - currently we don't support that
+ uno::Reference< beans::XPropertySet > xDBRangeProps( xDataBaseRange, uno::UNO_QUERY_THROW );
+ if ( bHasAuto )
+ {
+ // find the any field with the query and select all
+ ScQueryParam aParam = lcl_GetQueryParam( pShell, nSheet );
+ for (SCSIZE i = 0; i< aParam.GetEntryCount(); ++i)
+ {
+ ScQueryEntry& rEntry = aParam.GetEntry(i);
+ if ( rEntry.bDoQuery )
+ lcl_SetAllQueryForField( pShell, rEntry.nField, nSheet );
+ }
+ // remove existing filters
+ uno::Reference< sheet::XSheetFilterDescriptor2 > xSheetFilterDescriptor(
+ xDataBaseRange->getFilterDescriptor(), uno::UNO_QUERY );
+ if( xSheetFilterDescriptor.is() )
+ xSheetFilterDescriptor->setFilterFields2( uno::Sequence< sheet::TableFilterField2 >() );
+ }
+ xDBRangeProps->setPropertyValue( "AutoFilter", uno::Any(!bHasAuto) );
+
+ }
+}
+
+void SAL_CALL
+ScVbaRange::Insert( const uno::Any& Shift, const uno::Any& /*CopyOrigin*/ )
+{
+ // It appears (from the web) that the undocumented CopyOrigin
+ // param should contain member of enum XlInsertFormatOrigin
+ // which can have values xlFormatFromLeftOrAbove or xlFormatFromRightOrBelow
+ // #TODO investigate resultant behaviour using these constants
+ // currently just processing Shift
+
+ sheet::CellInsertMode mode = sheet::CellInsertMode_NONE;
+ if ( Shift.hasValue() )
+ {
+ sal_Int32 nShift = 0;
+ Shift >>= nShift;
+ switch ( nShift )
+ {
+ case excel::XlInsertShiftDirection::xlShiftToRight:
+ mode = sheet::CellInsertMode_RIGHT;
+ break;
+ case excel::XlInsertShiftDirection::xlShiftDown:
+ mode = sheet::CellInsertMode_DOWN;
+ break;
+ default:
+ throw uno::RuntimeException("Illegal parameter " );
+ }
+ }
+ else
+ {
+ if ( getRow() >= getColumn() )
+ mode = sheet::CellInsertMode_DOWN;
+ else
+ mode = sheet::CellInsertMode_RIGHT;
+ }
+ RangeHelper thisRange( mxRange );
+ table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+ uno::Reference< sheet::XCellRangeMovement > xCellRangeMove( thisRange.getSpreadSheet(), uno::UNO_QUERY_THROW );
+ xCellRangeMove->insertCells( thisAddress, mode );
+
+ // Paste from clipboard only if the clipboard content was copied via VBA, and not already pasted via VBA again.
+ // "Insert" behavior should not depend on random clipboard content previously copied by the user.
+ ScDocShell* pDocShell = getDocShellFromRange( mxRange );
+ const ScTransferObj* pClipObj = pDocShell ? ScTransferObj::GetOwnClipboard(pDocShell->GetClipData()) : nullptr;
+ if ( pClipObj && pClipObj->GetUseInApi() )
+ {
+ // After the insert ( this range ) actually has moved
+ ScRange aRange( static_cast< SCCOL >( thisAddress.StartColumn ), static_cast< SCROW >( thisAddress.StartRow ), static_cast< SCTAB >( thisAddress.Sheet ), static_cast< SCCOL >( thisAddress.EndColumn ), static_cast< SCROW >( thisAddress.EndRow ), static_cast< SCTAB >( thisAddress.Sheet ) );
+ uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( getDocShellFromRange( mxRange ) , aRange ) );
+ uno::Reference< excel::XRange > xVbaRange( new ScVbaRange( mxParent, mxContext, xRange, mbIsRows, mbIsColumns ) );
+ xVbaRange->PasteSpecial( uno::Any(), uno::Any(), uno::Any(), uno::Any() );
+ }
+}
+
+void SAL_CALL
+ScVbaRange::Autofit()
+{
+ sal_Int32 nLen = m_Areas->getCount();
+ if ( nLen > 1 )
+ {
+ for ( sal_Int32 index = 1; index != nLen; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::Any( index ), uno::Any() ), uno::UNO_QUERY_THROW );
+ xRange->Autofit();
+ }
+ return;
+ }
+
+ // if the range is a not a row or column range autofit will
+ // throw an error
+ if ( !( mbIsColumns || mbIsRows ) )
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ ScDocShell* pDocShell = getDocShellFromRange( mxRange );
+ if ( !pDocShell )
+ return;
+
+ RangeHelper thisRange( mxRange );
+ table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+
+ std::vector<sc::ColRowSpan> aColArr(1, sc::ColRowSpan(thisAddress.StartColumn,thisAddress.EndColumn));
+ bool bDirection = true;
+ if ( mbIsRows )
+ {
+ bDirection = false;
+ aColArr[0].mnStart = thisAddress.StartRow;
+ aColArr[0].mnEnd = thisAddress.EndRow;
+ }
+ pDocShell->GetDocFunc().SetWidthOrHeight(
+ bDirection, aColArr, thisAddress.Sheet, SC_SIZE_OPTIMAL, 0, true, true);
+}
+
+uno::Any SAL_CALL
+ScVbaRange::Hyperlinks( const uno::Any& aIndex )
+{
+ /* The range object always returns a new Hyperlinks object containing a
+ fixed list of existing hyperlinks in the range.
+ See vbahyperlinks.hxx for more details. */
+
+ // get the global hyperlink object of the sheet (sheet should always be the parent of a Range object)
+ uno::Reference< excel::XWorksheet > xWorksheet( getParent(), uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XHyperlinks > xSheetHlinks( xWorksheet->Hyperlinks( uno::Any() ), uno::UNO_QUERY_THROW );
+ ScVbaHyperlinksRef xScSheetHlinks( dynamic_cast< ScVbaHyperlinks* >( xSheetHlinks.get() ) );
+ if( !xScSheetHlinks.is() )
+ throw uno::RuntimeException("Cannot obtain hyperlinks implementation object" );
+
+ // create a new local hyperlinks object based on the sheet hyperlinks
+ ScVbaHyperlinksRef xHlinks( new ScVbaHyperlinks( getParent(), mxContext, xScSheetHlinks, getScRangeList() ) );
+ if( aIndex.hasValue() )
+ return xHlinks->Item( aIndex, uno::Any() );
+ return uno::Any( uno::Reference< excel::XHyperlinks >( xHlinks ) );
+}
+
+css::uno::Reference< excel::XValidation > SAL_CALL
+ScVbaRange::getValidation()
+{
+ if ( !m_xValidation.is() )
+ m_xValidation = new ScVbaValidation( this, mxContext, mxRange );
+ return m_xValidation;
+}
+
+namespace {
+
+/// @throws uno::RuntimeException
+sal_Unicode lclGetPrefixChar( const uno::Reference< table::XCell >& rxCell )
+{
+ /* TODO/FIXME: We need an apostroph-prefix property at the cell to
+ implement this correctly. For now, return an apostroph for every text
+ cell.
+
+ TODO/FIXME: When Application.TransitionNavigKeys is supported and true,
+ this function needs to inspect the cell formatting and return different
+ prefixes according to the horizontal cell alignment.
+ */
+ return (rxCell->getType() == table::CellContentType_TEXT) ? '\'' : 0;
+}
+
+/// @throws uno::RuntimeException
+sal_Unicode lclGetPrefixChar( const uno::Reference< table::XCellRange >& rxRange )
+{
+ /* This implementation is able to handle different prefixes (needed if
+ Application.TransitionNavigKeys is true). The function lclGetPrefixChar
+ for single cells called from here may return any prefix. If that
+ function returns an empty prefix (NUL character) or different non-empty
+ prefixes for two cells, this function returns 0.
+ */
+ sal_Unicode cCurrPrefix = 0;
+ table::CellRangeAddress aRangeAddr = lclGetRangeAddress( rxRange );
+ sal_Int32 nEndCol = aRangeAddr.EndColumn - aRangeAddr.StartColumn;
+ sal_Int32 nEndRow = aRangeAddr.EndRow - aRangeAddr.StartRow;
+ for( sal_Int32 nRow = 0; nRow <= nEndRow; ++nRow )
+ {
+ for( sal_Int32 nCol = 0; nCol <= nEndCol; ++nCol )
+ {
+ uno::Reference< table::XCell > xCell( rxRange->getCellByPosition( nCol, nRow ), uno::UNO_SET_THROW );
+ sal_Unicode cNewPrefix = lclGetPrefixChar( xCell );
+ if( (cNewPrefix == 0) || ((cCurrPrefix != 0) && (cNewPrefix != cCurrPrefix)) )
+ return 0;
+ cCurrPrefix = cNewPrefix;
+ }
+ }
+ // all cells contain the same prefix - return it
+ return cCurrPrefix;
+}
+
+/// @throws uno::RuntimeException
+sal_Unicode lclGetPrefixChar( const uno::Reference< sheet::XSheetCellRangeContainer >& rxRanges )
+{
+ sal_Unicode cCurrPrefix = 0;
+ uno::Reference< container::XEnumerationAccess > xRangesEA( rxRanges, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XEnumeration > xRangesEnum( xRangesEA->createEnumeration(), uno::UNO_SET_THROW );
+ while( xRangesEnum->hasMoreElements() )
+ {
+ uno::Reference< table::XCellRange > xRange( xRangesEnum->nextElement(), uno::UNO_QUERY_THROW );
+ sal_Unicode cNewPrefix = lclGetPrefixChar( xRange );
+ if( (cNewPrefix == 0) || ((cCurrPrefix != 0) && (cNewPrefix != cCurrPrefix)) )
+ return 0;
+ cCurrPrefix = cNewPrefix;
+ }
+ // all ranges contain the same prefix - return it
+ return cCurrPrefix;
+}
+
+uno::Any lclGetPrefixVariant( sal_Unicode cPrefixChar )
+{
+ return uno::Any( (cPrefixChar == 0) ? OUString() : OUString( cPrefixChar ) );
+}
+
+} // namespace
+
+uno::Any SAL_CALL ScVbaRange::getPrefixCharacter()
+{
+ /* (1) If Application.TransitionNavigKeys is false, this function returns
+ an apostroph character if the text cell begins with an apostroph
+ character (formula return values are not taken into account); otherwise
+ an empty string.
+
+ (2) If Application.TransitionNavigKeys is true, this function returns
+ an apostroph character, if the cell is left-aligned; a double-quote
+ character, if the cell is right-aligned; a circumflex character, if the
+ cell is centered; a backslash character, if the cell is set to filled;
+ or an empty string, if nothing of the above.
+
+ If a range or a list of ranges contains texts with leading apostroph
+ character as well as other cells, this function returns an empty
+ string.
+ */
+
+ if( mxRange.is() )
+ return lclGetPrefixVariant( lclGetPrefixChar( mxRange ) );
+ if( mxRanges.is() )
+ return lclGetPrefixVariant( lclGetPrefixChar( mxRanges ) );
+ throw uno::RuntimeException("Unexpected empty Range object" );
+}
+
+uno::Any ScVbaRange::getShowDetail()
+{
+ // #FIXME, If the specified range is in a PivotTable report
+
+ // In MSO VBA, the specified range must be a single summary column or row in an outline. otherwise throw exception
+ if( m_Areas->getCount() > 1 )
+ throw uno::RuntimeException("Can not get Range.ShowDetail attribute " );
+
+ RangeHelper helper( mxRange );
+ uno::Reference< sheet::XSheetCellCursor > xSheetCellCursor = helper.getSheetCellCursor();
+ xSheetCellCursor->collapseToCurrentRegion();
+ uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable(xSheetCellCursor, uno::UNO_QUERY_THROW);
+ table::CellRangeAddress aOutlineAddress = xCellRangeAddressable->getRangeAddress();
+
+ // check if the specified range is a single summary column or row.
+ table::CellRangeAddress thisAddress = helper.getCellRangeAddressable()->getRangeAddress();
+ if( (thisAddress.StartRow != thisAddress.EndRow || thisAddress.EndRow != aOutlineAddress.EndRow ) &&
+ (thisAddress.StartColumn != thisAddress.EndColumn || thisAddress.EndColumn != aOutlineAddress.EndColumn ))
+ {
+ throw uno::RuntimeException("Can not set Range.ShowDetail attribute" );
+ }
+
+ bool bColumn = thisAddress.StartRow != thisAddress.EndRow;
+ ScDocument& rDoc = getDocumentFromRange( mxRange );
+ ScOutlineTable* pOutlineTable = rDoc.GetOutlineTable(static_cast<SCTAB>(thisAddress.Sheet), true);
+ const ScOutlineArray& rOutlineArray = bColumn ? pOutlineTable->GetColArray(): pOutlineTable->GetRowArray();
+ SCCOLROW nPos = bColumn ? static_cast<SCCOLROW>(thisAddress.EndColumn-1):static_cast<SCCOLROW>(thisAddress.EndRow-1);
+ const ScOutlineEntry* pEntry = rOutlineArray.GetEntryByPos( 0, nPos );
+ if( pEntry )
+ {
+ const bool bShowDetail = !pEntry->IsHidden();
+ return uno::Any( bShowDetail );
+ }
+
+ return aNULL();
+}
+
+void ScVbaRange::setShowDetail(const uno::Any& aShowDetail)
+{
+ // #FIXME, If the specified range is in a PivotTable report
+
+ // In MSO VBA, the specified range must be a single summary column or row in an outline. otherwise throw exception
+ if( m_Areas->getCount() > 1 )
+ throw uno::RuntimeException("Can not set Range.ShowDetail attribute" );
+
+ bool bShowDetail = extractBoolFromAny( aShowDetail );
+
+ RangeHelper helper( mxRange );
+ uno::Reference< sheet::XSheetCellCursor > xSheetCellCursor = helper.getSheetCellCursor();
+ xSheetCellCursor->collapseToCurrentRegion();
+ uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable(xSheetCellCursor, uno::UNO_QUERY_THROW);
+ table::CellRangeAddress aOutlineAddress = xCellRangeAddressable->getRangeAddress();
+
+ // check if the specified range is a single summary column or row.
+ table::CellRangeAddress thisAddress = helper.getCellRangeAddressable()->getRangeAddress();
+ if( (thisAddress.StartRow != thisAddress.EndRow || thisAddress.EndRow != aOutlineAddress.EndRow ) &&
+ (thisAddress.StartColumn != thisAddress.EndColumn || thisAddress.EndColumn != aOutlineAddress.EndColumn ))
+ {
+ throw uno::RuntimeException("Can not set Range.ShowDetail attribute" );
+ }
+
+ // #FIXME, seems there is a different behavior between MSO and OOo.
+ // In OOo, the showDetail will show all the level entries, while only show the first level entry in MSO
+ uno::Reference< sheet::XSheetOutline > xSheetOutline( helper.getSpreadSheet(), uno::UNO_QUERY_THROW );
+ if( bShowDetail )
+ xSheetOutline->showDetail( aOutlineAddress );
+ else
+ xSheetOutline->hideDetail( aOutlineAddress );
+
+}
+
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaRange::MergeArea()
+{
+ uno::Reference< sheet::XSheetCellRange > xMergeShellCellRange(mxRange->getCellRangeByPosition(0,0,0,0), uno::UNO_QUERY_THROW);
+ uno::Reference< sheet::XSheetCellCursor > xMergeSheetCursor(xMergeShellCellRange->getSpreadsheet()->createCursorByRange( xMergeShellCellRange ), uno::UNO_SET_THROW);
+ if( xMergeSheetCursor.is() )
+ {
+ xMergeSheetCursor->collapseToMergedArea();
+ uno::Reference<sheet::XCellRangeAddressable> xMergeCellAddress(xMergeSheetCursor, uno::UNO_QUERY_THROW);
+ table::CellRangeAddress aCellAddress = xMergeCellAddress->getRangeAddress();
+ if( aCellAddress.StartColumn ==0 && aCellAddress.EndColumn==0 &&
+ aCellAddress.StartRow==0 && aCellAddress.EndRow==0)
+ {
+ return new ScVbaRange( mxParent,mxContext,mxRange );
+ }
+ else
+ {
+ ScRange refRange( static_cast< SCCOL >( aCellAddress.StartColumn ), static_cast< SCROW >( aCellAddress.StartRow ), static_cast< SCTAB >( aCellAddress.Sheet ),
+ static_cast< SCCOL >( aCellAddress.EndColumn ), static_cast< SCROW >( aCellAddress.EndRow ), static_cast< SCTAB >( aCellAddress.Sheet ) );
+ uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( getScDocShell() , refRange ) );
+ return new ScVbaRange( mxParent, mxContext,xRange );
+ }
+ }
+ return new ScVbaRange( mxParent, mxContext, mxRange );
+}
+
+void SAL_CALL
+ScVbaRange::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 )
+{
+ ScDocShell* pShell = nullptr;
+
+ sal_Int32 nItems = m_Areas->getCount();
+ uno::Sequence< table::CellRangeAddress > printAreas( nItems );
+ auto printAreasRange = asNonConstRange(printAreas);
+ uno::Reference< sheet::XPrintAreas > xPrintAreas;
+ for ( sal_Int32 index=1; index <= nItems; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::Any(index), uno::Any() ), uno::UNO_QUERY_THROW );
+
+ RangeHelper thisRange( xRange->getCellRange() );
+ table::CellRangeAddress rangeAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+ if ( index == 1 )
+ {
+ ScVbaRange* pRange = getImplementation( xRange );
+ // initialise the doc shell and the printareas
+ pShell = getDocShellFromRange( pRange->mxRange );
+ xPrintAreas.set( thisRange.getSpreadSheet(), uno::UNO_QUERY_THROW );
+ }
+ printAreasRange[ index - 1 ] = rangeAddress;
+ }
+ if ( pShell && xPrintAreas.is() )
+ {
+ xPrintAreas->setPrintAreas( printAreas );
+ uno::Reference< frame::XModel > xModel = pShell->GetModel();
+ PrintOutHelper( excel::getBestViewShell( xModel ), From, To, Copies, Preview, ActivePrinter, PrintToFile, Collate, PrToFileName, true );
+ }
+}
+
+void SAL_CALL
+ScVbaRange::AutoFill( const uno::Reference< excel::XRange >& Destination, const uno::Any& Type )
+{
+ uno::Reference< excel::XRange > xDest( Destination, uno::UNO_SET_THROW );
+ ScVbaRange* pRange = getImplementation( xDest );
+ RangeHelper destRangeHelper( pRange->mxRange );
+ table::CellRangeAddress destAddress = destRangeHelper.getCellRangeAddressable()->getRangeAddress();
+
+ RangeHelper thisRange( mxRange );
+ table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+ ScRange sourceRange;
+ ScRange destRange;
+
+ ScUnoConversion::FillScRange( destRange, destAddress );
+ ScUnoConversion::FillScRange( sourceRange, thisAddress );
+
+ FillDir eDir = FILL_TO_BOTTOM;
+ double fStep = 1.0;
+
+ ScRange aRange( destRange );
+ ScRange aSourceRange( destRange );
+
+ // default to include the number of Rows in the source range;
+ SCCOLROW nSourceCount = ( sourceRange.aEnd.Row() - sourceRange.aStart.Row() ) + 1;
+ SCCOLROW nCount = 0;
+
+ if ( sourceRange != destRange )
+ {
+ // Find direction of fill, vertical or horizontal
+ if ( sourceRange.aStart == destRange.aStart )
+ {
+ if ( sourceRange.aEnd.Row() == destRange.aEnd.Row() )
+ {
+ nSourceCount = ( sourceRange.aEnd.Col() - sourceRange.aStart.Col() + 1 );
+ aSourceRange.aEnd.SetCol( static_cast<SCCOL>( aSourceRange.aStart.Col() + nSourceCount - 1 ) );
+ eDir = FILL_TO_RIGHT;
+ nCount = aRange.aEnd.Col() - aSourceRange.aEnd.Col();
+ }
+ else if ( sourceRange.aEnd.Col() == destRange.aEnd.Col() )
+ {
+ aSourceRange.aEnd.SetRow( static_cast<SCROW>( aSourceRange.aStart.Row() + nSourceCount ) - 1 );
+ nCount = aRange.aEnd.Row() - aSourceRange.aEnd.Row();
+ eDir = FILL_TO_BOTTOM;
+ }
+ }
+
+ else if ( aSourceRange.aEnd == destRange.aEnd )
+ {
+ if ( sourceRange.aStart.Col() == destRange.aStart.Col() )
+ {
+ aSourceRange.aStart.SetRow( static_cast<SCROW>( aSourceRange.aEnd.Row() - nSourceCount + 1 ) );
+ nCount = aSourceRange.aStart.Row() - aRange.aStart.Row();
+ eDir = FILL_TO_TOP;
+ fStep = -fStep;
+ }
+ else if ( sourceRange.aStart.Row() == destRange.aStart.Row() )
+ {
+ nSourceCount = ( sourceRange.aEnd.Col() - sourceRange.aStart.Col() ) + 1;
+ aSourceRange.aStart.SetCol( static_cast<SCCOL>( aSourceRange.aEnd.Col() - nSourceCount + 1 ) );
+ nCount = aSourceRange.aStart.Col() - aRange.aStart.Col();
+ eDir = FILL_TO_LEFT;
+ fStep = -fStep;
+ }
+ }
+ }
+
+ FillCmd eCmd = FILL_AUTO;
+ FillDateCmd eDateCmd = FILL_DAY;
+
+ if ( Type.hasValue() )
+ {
+ sal_Int16 nFillType = excel::XlAutoFillType::xlFillDefault;
+ Type >>= nFillType;
+ switch ( nFillType )
+ {
+ case excel::XlAutoFillType::xlFillCopy:
+ eCmd = FILL_SIMPLE;
+ fStep = 0.0;
+ break;
+ case excel::XlAutoFillType::xlFillDays:
+ eCmd = FILL_DATE;
+ break;
+ case excel::XlAutoFillType::xlFillMonths:
+ eCmd = FILL_DATE;
+ eDateCmd = FILL_MONTH;
+ break;
+ case excel::XlAutoFillType::xlFillWeekdays:
+ eCmd = FILL_DATE;
+ eDateCmd = FILL_WEEKDAY;
+ break;
+ case excel::XlAutoFillType::xlFillYears:
+ eCmd = FILL_DATE;
+ eDateCmd = FILL_YEAR;
+ break;
+ case excel::XlAutoFillType::xlGrowthTrend:
+ eCmd = FILL_GROWTH;
+ break;
+ case excel::XlAutoFillType::xlFillFormats:
+ throw uno::RuntimeException("xlFillFormat not supported for AutoFill" );
+ case excel::XlAutoFillType::xlFillValues:
+ case excel::XlAutoFillType::xlFillSeries:
+ case excel::XlAutoFillType::xlLinearTrend:
+ eCmd = FILL_LINEAR;
+ break;
+ case excel::XlAutoFillType::xlFillDefault:
+ default:
+ eCmd = FILL_AUTO;
+ break;
+ }
+ }
+ ScDocShell* pDocSh = getDocShellFromRange( mxRange );
+ pDocSh->GetDocFunc().FillAuto( aSourceRange, nullptr, eDir, eCmd, eDateCmd,
+ nCount, fStep, MAXDOUBLE/*fEndValue*/, true, true );
+}
+sal_Bool SAL_CALL
+ScVbaRange::GoalSeek( const uno::Any& Goal, const uno::Reference< excel::XRange >& ChangingCell )
+{
+ ScDocShell* pDocShell = getScDocShell();
+ bool bRes = true;
+ ScVbaRange* pRange = static_cast< ScVbaRange* >( ChangingCell.get() );
+ if ( pDocShell && pRange )
+ {
+ uno::Reference< sheet::XGoalSeek > xGoalSeek( pDocShell->GetModel(), uno::UNO_QUERY_THROW );
+ RangeHelper thisRange( mxRange );
+ table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+ RangeHelper changingCellRange( pRange->mxRange );
+ table::CellRangeAddress changingCellAddr = changingCellRange.getCellRangeAddressable()->getRangeAddress();
+ OUString sGoal = getAnyAsString( Goal );
+ table::CellAddress thisCell( thisAddress.Sheet, thisAddress.StartColumn, thisAddress.StartRow );
+ table::CellAddress changingCell( changingCellAddr.Sheet, changingCellAddr.StartColumn, changingCellAddr.StartRow );
+ sheet::GoalResult res = xGoalSeek->seekGoal( thisCell, changingCell, sGoal );
+ ChangingCell->setValue( uno::Any( res.Result ) );
+
+ // openoffice behaves differently, result is 0 if the divergence is too great
+ // but... if it detects 0 is the value it requires then it will use that
+ // e.g. divergence & result both = 0.0 does NOT mean there is an error
+ if ( ( res.Divergence != 0.0 ) && ( res.Result == 0.0 ) )
+ bRes = false;
+ }
+ else
+ bRes = false;
+ return bRes;
+}
+
+void
+ScVbaRange::Calculate( )
+{
+ getWorksheet()->Calculate();
+}
+
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaRange::Item( const uno::Any& row, const uno::Any& column )
+{
+ if ( mbIsRows || mbIsColumns )
+ {
+ if ( column.hasValue() )
+ DebugHelper::basicexception(ERRCODE_BASIC_BAD_PARAMETER, {} );
+ uno::Reference< excel::XRange > xRange;
+ if ( mbIsColumns )
+ xRange = Columns( row );
+ else
+ xRange = Rows( row );
+ return xRange;
+ }
+ return Cells( row, column );
+}
+
+void
+ScVbaRange::AutoOutline( )
+{
+ // #TODO #FIXME needs to check for summary row/col ( whatever they are )
+ // not valid for multi Area Addresses
+ if ( m_Areas->getCount() > 1 )
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, STR_ERRORMESSAGE_APPLIESTOSINGLERANGEONLY);
+ // So needs to either span an entire Row or a just be a single cell
+ // ( that contains a summary RowColumn )
+ // also the Single cell cause doesn't seem to be handled specially in
+ // this code ( ported from the helperapi RangeImpl.java,
+ // RangeRowsImpl.java, RangesImpl.java, RangeSingleCellImpl.java
+ RangeHelper thisRange( mxRange );
+ table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+
+ if ( isSingleCellRange() || mbIsRows )
+ {
+ uno::Reference< sheet::XSheetOutline > xSheetOutline( thisRange.getSpreadSheet(), uno::UNO_QUERY_THROW );
+ xSheetOutline->autoOutline( thisAddress );
+ }
+ else
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+}
+
+void SAL_CALL
+ScVbaRange:: ClearOutline( )
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ sal_Int32 nItems = m_Areas->getCount();
+ for ( sal_Int32 index=1; index <= nItems; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::Any(index), uno::Any() ), uno::UNO_QUERY_THROW );
+ xRange->ClearOutline();
+ }
+ return;
+ }
+ RangeHelper thisRange( mxRange );
+ uno::Reference< sheet::XSheetOutline > xSheetOutline( thisRange.getSpreadSheet(), uno::UNO_QUERY_THROW );
+ xSheetOutline->clearOutline();
+}
+
+void
+ScVbaRange::groupUnGroup( bool bUnGroup )
+{
+ if ( m_Areas->getCount() > 1 )
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, STR_ERRORMESSAGE_APPLIESTOSINGLERANGEONLY);
+ table::TableOrientation nOrient = table::TableOrientation_ROWS;
+ if ( mbIsColumns )
+ nOrient = table::TableOrientation_COLUMNS;
+ RangeHelper thisRange( mxRange );
+ table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
+ uno::Reference< sheet::XSheetOutline > xSheetOutline( thisRange.getSpreadSheet(), uno::UNO_QUERY_THROW );
+ if ( bUnGroup )
+ xSheetOutline->ungroup( thisAddress, nOrient );
+ else
+ xSheetOutline->group( thisAddress, nOrient );
+}
+
+void SAL_CALL
+ScVbaRange::Group( )
+{
+ groupUnGroup(false);
+}
+void SAL_CALL
+ScVbaRange::Ungroup( )
+{
+ groupUnGroup(true);
+}
+
+/// @throws uno::RuntimeException
+static void lcl_mergeCellsOfRange( const uno::Reference< table::XCellRange >& xCellRange, bool _bMerge )
+{
+ uno::Reference< util::XMergeable > xMergeable( xCellRange, uno::UNO_QUERY_THROW );
+ xMergeable->merge(_bMerge);
+}
+void SAL_CALL
+ScVbaRange::Merge( const uno::Any& Across )
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ sal_Int32 nItems = m_Areas->getCount();
+ for ( sal_Int32 index=1; index <= nItems; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::Any(index), uno::Any() ), uno::UNO_QUERY_THROW );
+ xRange->Merge(Across);
+ }
+ return;
+ }
+ bool bAcross = false;
+ Across >>= bAcross;
+ if ( !bAcross )
+ lcl_mergeCellsOfRange( mxRange, true );
+ else
+ {
+ uno::Reference< excel::XRange > oRangeRowsImpl = Rows( uno::Any() );
+ // #TODO #FIXME this seems incredibly lame, this can't be right
+ for (sal_Int32 i=1; i <= oRangeRowsImpl->getCount();i++)
+ {
+ oRangeRowsImpl->Cells( uno::Any( i ), uno::Any() )->Merge( uno::Any( false ) );
+ }
+ }
+}
+
+void SAL_CALL
+ScVbaRange::UnMerge( )
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ sal_Int32 nItems = m_Areas->getCount();
+ for ( sal_Int32 index=1; index <= nItems; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::Any(index), uno::Any() ), uno::UNO_QUERY_THROW );
+ xRange->UnMerge();
+ }
+ return;
+ }
+ lcl_mergeCellsOfRange( mxRange, false);
+}
+
+uno::Any SAL_CALL
+ScVbaRange::getStyle()
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::Any( sal_Int32( 1 ) ), uno::Any() ), uno::UNO_QUERY_THROW );
+ return xRange->getStyle();
+ }
+ uno::Reference< beans::XPropertySet > xProps( mxRange, uno::UNO_QUERY_THROW );
+ OUString sStyleName;
+ xProps->getPropertyValue( CELLSTYLE ) >>= sStyleName;
+ ScDocShell* pShell = getScDocShell();
+ uno::Reference< frame::XModel > xModel( pShell->GetModel() );
+ uno::Reference< excel::XStyle > xStyle = new ScVbaStyle( this, mxContext, sStyleName, xModel );
+ return uno::Any( xStyle );
+}
+void SAL_CALL
+ScVbaRange::setStyle( const uno::Any& _style )
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::Any( sal_Int32( 1 ) ), uno::Any() ), uno::UNO_QUERY_THROW );
+ xRange->setStyle( _style );
+ return;
+ }
+ uno::Reference< beans::XPropertySet > xProps( mxRange, uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XStyle > xStyle;
+ _style >>= xStyle;
+ if ( xStyle.is() )
+ xProps->setPropertyValue( CELLSTYLE, uno::Any( xStyle->getName() ) );
+}
+
+uno::Reference< excel::XRange >
+ScVbaRange::PreviousNext( bool bIsPrevious )
+{
+ ScMarkData markedRange(getScDocument().GetSheetLimits());
+ ScRange refRange;
+ RangeHelper thisRange( mxRange );
+
+ ScUnoConversion::FillScRange( refRange, thisRange.getCellRangeAddressable()->getRangeAddress());
+ markedRange. SetMarkArea( refRange );
+ short nMove = bIsPrevious ? -1 : 1;
+
+ SCCOL nNewX = refRange.aStart.Col();
+ SCROW nNewY = refRange.aStart.Row();
+ SCTAB nTab = refRange.aStart.Tab();
+
+ ScDocument& rDoc = getScDocument();
+ rDoc.GetNextPos( nNewX,nNewY, nTab, nMove,0, true,true, markedRange );
+ refRange.aStart.SetCol( nNewX );
+ refRange.aStart.SetRow( nNewY );
+ refRange.aStart.SetTab( nTab );
+ refRange.aEnd.SetCol( nNewX );
+ refRange.aEnd.SetRow( nNewY );
+ refRange.aEnd.SetTab( nTab );
+
+ uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( getScDocShell() , refRange ) );
+
+ return new ScVbaRange( mxParent, mxContext, xRange );
+}
+
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaRange::Next()
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::Any( sal_Int32( 1 ) ), uno::Any() ) , uno::UNO_QUERY_THROW );
+ return xRange->Next();
+ }
+ return PreviousNext( false );
+}
+
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaRange::Previous()
+{
+ if ( m_Areas->getCount() > 1 )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::Any( sal_Int32( 1 ) ), uno::Any() ), uno::UNO_QUERY_THROW );
+ return xRange->Previous();
+ }
+ return PreviousNext( true );
+}
+
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaRange::SpecialCells( const uno::Any& _oType, const uno::Any& _oValue)
+{
+ bool bIsSingleCell = isSingleCellRange();
+ bool bIsMultiArea = ( m_Areas->getCount() > 1 );
+ ScVbaRange* pRangeToUse = this;
+ uno::Reference< excel::XRange > xUsedRange( getWorksheet()->getUsedRange() );
+ sal_Int32 nType = 0;
+ if ( !( _oType >>= nType ) )
+ DebugHelper::basicexception(ERRCODE_BASIC_BAD_PARAMETER, {} );
+ switch(nType)
+ {
+ case excel::XlCellType::xlCellTypeSameFormatConditions:
+ case excel::XlCellType::xlCellTypeAllValidation:
+ case excel::XlCellType::xlCellTypeSameValidation:
+ DebugHelper::basicexception(ERRCODE_BASIC_NOT_IMPLEMENTED, {});
+ break;
+ case excel::XlCellType::xlCellTypeBlanks:
+ case excel::XlCellType::xlCellTypeComments:
+ case excel::XlCellType::xlCellTypeConstants:
+ case excel::XlCellType::xlCellTypeFormulas:
+ case excel::XlCellType::xlCellTypeVisible:
+ case excel::XlCellType::xlCellTypeLastCell:
+ {
+ if ( bIsMultiArea )
+ {
+ // need to process each area, gather the results and
+ // create a new range from those
+ std::vector< table::CellRangeAddress > rangeResults;
+ sal_Int32 nItems = m_Areas->getCount() + 1;
+ for ( sal_Int32 index=1; index <= nItems; ++index )
+ {
+ uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::Any(index), uno::Any() ), uno::UNO_QUERY_THROW );
+ xRange = xRange->SpecialCells( _oType, _oValue);
+ ScVbaRange* pRange = getImplementation( xRange );
+ if ( xRange.is() && pRange )
+ {
+ sal_Int32 nElems = pRange->m_Areas->getCount() + 1;
+ for ( sal_Int32 nArea = 1; nArea < nElems; ++nArea )
+ {
+ uno::Reference< excel::XRange > xTmpRange( m_Areas->Item( uno::Any( nArea ), uno::Any() ), uno::UNO_QUERY_THROW );
+ RangeHelper rHelper( xTmpRange->getCellRange() );
+ rangeResults.push_back( rHelper.getCellRangeAddressable()->getRangeAddress() );
+ }
+ }
+ }
+ ScRangeList aCellRanges;
+ for ( const auto& rRangeResult : rangeResults )
+ {
+ ScRange refRange;
+ ScUnoConversion::FillScRange( refRange, rRangeResult );
+ aCellRanges.push_back( refRange );
+ }
+ // Single range
+ if ( aCellRanges.size() == 1 )
+ {
+ uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( getScDocShell(), aCellRanges.front() ) );
+ return new ScVbaRange( mxParent, mxContext, xRange );
+ }
+ uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( getScDocShell(), aCellRanges ) );
+
+ return new ScVbaRange( mxParent, mxContext, xRanges );
+ }
+ else if ( bIsSingleCell )
+ {
+ pRangeToUse = static_cast< ScVbaRange* >( xUsedRange.get() );
+ }
+
+ break;
+ }
+ default:
+ DebugHelper::basicexception(ERRCODE_BASIC_BAD_PARAMETER, {} );
+ break;
+ }
+ if ( !pRangeToUse )
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {} );
+ return pRangeToUse->SpecialCellsImpl( nType, _oValue );
+}
+
+/// @throws script::BasicErrorException
+static sal_Int32 lcl_getFormulaResultFlags(const uno::Any& aType)
+{
+ sal_Int32 nType = excel::XlSpecialCellsValue::xlNumbers;
+ aType >>= nType;
+ sal_Int32 nRes = sheet::FormulaResult::VALUE;
+
+ switch(nType)
+ {
+ case excel::XlSpecialCellsValue::xlErrors:
+ nRes= sheet::FormulaResult::ERROR;
+ break;
+ case excel::XlSpecialCellsValue::xlLogical:
+ //TODO bc93774: ask NN if this is really an appropriate substitute
+ nRes = sheet::FormulaResult::VALUE;
+ break;
+ case excel::XlSpecialCellsValue::xlNumbers:
+ nRes = sheet::FormulaResult::VALUE;
+ break;
+ case excel::XlSpecialCellsValue::xlTextValues:
+ nRes = sheet::FormulaResult::STRING;
+ break;
+ default:
+ DebugHelper::basicexception(ERRCODE_BASIC_BAD_PARAMETER, {} );
+ }
+ return nRes;
+}
+
+uno::Reference< excel::XRange >
+ScVbaRange::SpecialCellsImpl( sal_Int32 nType, const uno::Any& _oValue)
+{
+ uno::Reference< excel::XRange > xRange;
+ try
+ {
+ uno::Reference< sheet::XCellRangesQuery > xQuery( mxRange, uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XSheetCellRanges > xLocSheetCellRanges;
+ switch(nType)
+ {
+ case excel::XlCellType::xlCellTypeAllFormatConditions:
+ case excel::XlCellType::xlCellTypeSameFormatConditions:
+ case excel::XlCellType::xlCellTypeAllValidation:
+ case excel::XlCellType::xlCellTypeSameValidation:
+ // Shouldn't get here ( should be filtered out by
+ // ScVbaRange::SpecialCells()
+ DebugHelper::basicexception(ERRCODE_BASIC_NOT_IMPLEMENTED, {});
+ break;
+ case excel::XlCellType::xlCellTypeBlanks:
+ xLocSheetCellRanges = xQuery->queryEmptyCells();
+ break;
+ case excel::XlCellType::xlCellTypeComments:
+ xLocSheetCellRanges = xQuery->queryContentCells(sheet::CellFlags::ANNOTATION);
+ break;
+ case excel::XlCellType::xlCellTypeConstants:
+ xLocSheetCellRanges = xQuery->queryContentCells(23);
+ break;
+ case excel::XlCellType::xlCellTypeFormulas:
+ {
+ sal_Int32 nFormulaResult = lcl_getFormulaResultFlags(_oValue);
+ xLocSheetCellRanges = xQuery->queryFormulaCells(nFormulaResult);
+ break;
+ }
+ case excel::XlCellType::xlCellTypeLastCell:
+ xRange = Cells( uno::Any( getCount() ), uno::Any() );
+ [[fallthrough]]; //TODO ???
+ case excel::XlCellType::xlCellTypeVisible:
+ xLocSheetCellRanges = xQuery->queryVisibleCells();
+ break;
+ default:
+ DebugHelper::basicexception(ERRCODE_BASIC_BAD_PARAMETER, {} );
+ break;
+ }
+ if (xLocSheetCellRanges.is())
+ {
+ xRange = lcl_makeXRangeFromSheetCellRanges( getParent(), mxContext, xLocSheetCellRanges, getScDocShell() );
+ }
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, u"No cells were found");
+ }
+ return xRange;
+}
+
+void SAL_CALL
+ScVbaRange::RemoveSubtotal( )
+{
+ uno::Reference< sheet::XSubTotalCalculatable > xSub( mxRange, uno::UNO_QUERY_THROW );
+ xSub->removeSubTotals();
+}
+
+void SAL_CALL
+ScVbaRange::Subtotal( ::sal_Int32 _nGroupBy, ::sal_Int32 _nFunction, const uno::Sequence< ::sal_Int32 >& _nTotalList, const uno::Any& aReplace, const uno::Any& PageBreaks, const uno::Any& /*SummaryBelowData*/ )
+{
+ try
+ {
+ bool bDoReplace = false;
+ aReplace >>= bDoReplace;
+ bool bAddPageBreaks = false;
+ PageBreaks >>= bAddPageBreaks;
+
+ uno::Reference< sheet::XSubTotalCalculatable> xSub(mxRange, uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XSubTotalDescriptor > xSubDesc = xSub->createSubTotalDescriptor(true);
+ uno::Reference< beans::XPropertySet > xSubDescPropertySet( xSubDesc, uno::UNO_QUERY_THROW );
+ xSubDescPropertySet->setPropertyValue("InsertPageBreaks", uno::Any( bAddPageBreaks));
+ sal_Int32 nLen = _nTotalList.getLength();
+ uno::Sequence< sheet::SubTotalColumn > aColumns( nLen );
+ auto aColumnsRange = asNonConstRange(aColumns);
+ for (int i = 0; i < nLen; i++)
+ {
+ aColumnsRange[i].Column = _nTotalList[i] - 1;
+ switch (_nFunction)
+ {
+ case excel::XlConsolidationFunction::xlAverage:
+ aColumnsRange[i].Function = sheet::GeneralFunction_AVERAGE;
+ break;
+ case excel::XlConsolidationFunction::xlCount:
+ aColumnsRange[i].Function = sheet::GeneralFunction_COUNT;
+ break;
+ case excel::XlConsolidationFunction::xlCountNums:
+ aColumnsRange[i].Function = sheet::GeneralFunction_COUNTNUMS;
+ break;
+ case excel::XlConsolidationFunction::xlMax:
+ aColumnsRange[i].Function = sheet::GeneralFunction_MAX;
+ break;
+ case excel::XlConsolidationFunction::xlMin:
+ aColumnsRange[i].Function = sheet::GeneralFunction_MIN;
+ break;
+ case excel::XlConsolidationFunction::xlProduct:
+ aColumnsRange[i].Function = sheet::GeneralFunction_PRODUCT;
+ break;
+ case excel::XlConsolidationFunction::xlStDev:
+ aColumnsRange[i].Function = sheet::GeneralFunction_STDEV;
+ break;
+ case excel::XlConsolidationFunction::xlStDevP:
+ aColumnsRange[i].Function = sheet::GeneralFunction_STDEVP;
+ break;
+ case excel::XlConsolidationFunction::xlSum:
+ aColumnsRange[i].Function = sheet::GeneralFunction_SUM;
+ break;
+ case excel::XlConsolidationFunction::xlUnknown:
+ aColumnsRange[i].Function = sheet::GeneralFunction_NONE;
+ break;
+ case excel::XlConsolidationFunction::xlVar:
+ aColumnsRange[i].Function = sheet::GeneralFunction_VAR;
+ break;
+ case excel::XlConsolidationFunction::xlVarP:
+ aColumnsRange[i].Function = sheet::GeneralFunction_VARP;
+ break;
+ default:
+ DebugHelper::basicexception(ERRCODE_BASIC_BAD_PARAMETER, {}) ;
+ return;
+ }
+ }
+ xSubDesc->addNew(aColumns, _nGroupBy - 1);
+ xSub->applySubTotals(xSubDesc, bDoReplace);
+ }
+ catch (const uno::Exception&)
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+}
+
+OUString
+ScVbaRange::getServiceImplName()
+{
+ return "ScVbaRange";
+}
+
+uno::Sequence< OUString >
+ScVbaRange::getServiceNames()
+{
+ return { "ooo.vba.excel.Range" };
+}
+
+sal_Bool SAL_CALL
+ScVbaRange::hasError()
+{
+ double dResult = 0.0;
+ uno::Reference< excel::XApplication > xApplication( Application(), uno::UNO_QUERY_THROW );
+ uno::Reference< script::XInvocation > xInvoc( xApplication->WorksheetFunction(), uno::UNO_QUERY_THROW );
+
+ uno::Reference< excel::XRange > aRange( this );
+ uno::Sequence< uno::Any > Params{ uno::Any(aRange) };
+ uno::Sequence< sal_Int16 > OutParamIndex;
+ uno::Sequence< uno::Any > OutParam;
+ xInvoc->invoke( "IsError", Params, OutParamIndex, OutParam ) >>= dResult;
+ return dResult > 0.0;
+}
+
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+Calc_ScVbaRange_get_implementation(
+ css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& args)
+{
+ return cppu::acquire(new ScVbaRange(args, context));
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbarange.hxx b/sc/source/ui/vba/vbarange.hxx
new file mode 100644
index 000000000..118ad044c
--- /dev/null
+++ b/sc/source/ui/vba/vbarange.hxx
@@ -0,0 +1,327 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <ooo/vba/excel/XRange.hpp>
+
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/sheet/FillDateMode.hpp>
+#include <com/sun/star/sheet/FillMode.hpp>
+#include <com/sun/star/sheet/FillDirection.hpp>
+
+#include "vbaformat.hxx"
+#include <address.hxx>
+#include <formula/grammar.hxx>
+
+namespace com::sun::star::sheet { class XSheetCellRangeContainer; }
+namespace com::sun::star::table { class XCell; }
+namespace com::sun::star::table { class XCellRange; }
+namespace com::sun::star::table { struct CellRangeAddress; }
+namespace com::sun::star::lang { class XServiceInfo; }
+namespace ooo::vba { class XCollection; }
+namespace ooo::vba::excel { class XComment; }
+namespace ooo::vba::excel { class XFont; }
+
+class SfxItemSet;
+class ScCellRangesBase;
+class ScCellRangeObj;
+class ScDocShell;
+class ScDocument;
+class ScRangeList;
+
+class ArrayVisitor
+{
+public:
+ virtual void visitNode( sal_Int32 x, sal_Int32 y, const css::uno::Reference< css::table::XCell >& xCell ) = 0;
+ virtual ~ArrayVisitor(){}
+};
+
+class ValueSetter : public ArrayVisitor
+{
+public:
+ virtual bool processValue( const css::uno::Any& aValue, const css::uno::Reference< css::table::XCell >& xCell ) = 0;
+
+};
+
+class ValueGetter : public ArrayVisitor
+{
+
+public:
+ virtual void processValue( const css::uno::Any& aValue ) = 0;
+ virtual const css::uno::Any& getValue() const = 0;
+};
+
+typedef ScVbaFormat< ov::excel::XRange > ScVbaRange_BASE;
+
+class ScVbaRange : public ScVbaRange_BASE
+{
+ css::uno::Reference< ov::XCollection > m_Areas;
+ css::uno::Reference< ov::XCollection > m_Borders;
+ css::uno::Reference< css::table::XCellRange > mxRange;
+ css::uno::Reference< css::sheet::XSheetCellRangeContainer > mxRanges;
+ bool mbIsRows;
+ bool mbIsColumns;
+ css::uno::Reference< ov::excel::XValidation > m_xValidation;
+ /// @throws css::uno::RuntimeException
+ double getCalcColWidth(const css::table::CellRangeAddress&);
+ /// @throws css::uno::RuntimeException
+ double getCalcRowHeight(const css::table::CellRangeAddress&);
+ void visitArray( ArrayVisitor& visitor );
+
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference< ov::excel::XRange > getEntireColumnOrRow( bool bColumn );
+
+ /// @throws css::uno::RuntimeException
+ void fillSeries( css::sheet::FillDirection nFillDirection, css::sheet::FillMode nFillMode, css::sheet::FillDateMode nFillDateMode, double fStep, double fEndValue );
+
+ /// @throws css::uno::RuntimeException
+ void ClearContents( sal_Int32 nFlags, bool bFireEvent );
+
+ /// @throws css::uno::RuntimeException
+ css::uno::Any getValue( ValueGetter& rValueGetter );
+ /// @throws css::uno::RuntimeException
+ void setValue( const css::uno::Any& aValue, ValueSetter& setter );
+
+ /// @throws css::uno::RuntimeException
+ css::uno::Any getFormulaValue( formula::FormulaGrammar::Grammar );
+ /// @throws css::uno::RuntimeException
+ void setFormulaValue( const css::uno::Any& aValue, formula::FormulaGrammar::Grammar );
+
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference< ov::excel::XRange > getArea( sal_Int32 nIndex );
+ /// @throws css::uno::RuntimeException
+ ScCellRangeObj* getCellRangeObj( );
+ css::uno::Reference< ov::XCollection >& getBorders();
+ /// @throws css::uno::RuntimeException
+ void groupUnGroup( bool bUnGroup );
+ css::uno::Reference< ov::excel::XRange > PreviousNext( bool bIsPrevious );
+ /// @throws css::script::BasicErrorException
+ css::uno::Reference< ov::excel::XRange > SpecialCellsImpl( sal_Int32 nType, const css::uno::Any& _oValue);
+ /// @throws css::uno::RuntimeException
+ css::awt::Point getPosition() const;
+
+ /** Fires a Worksheet_Change event for this range or range list. */
+ void fireChangeEvent();
+
+ /// @throws css::uno::RuntimeException
+ ScRange obtainRangeEvenIfRangeListIsEmpty( const ScRangeList& rCellRanges ) const;
+
+protected:
+ virtual ScCellRangesBase* getCellRangesBase() override;
+ /// @throws css::uno::RuntimeException
+ SfxItemSet* getCurrentDataSet();
+public:
+ /// @throws css::lang::IllegalArgumentException
+ ScVbaRange( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::table::XCellRange >& xRange, bool bIsRows = false, bool bIsColumns = false );
+ /// @throws css::lang::IllegalArgumentException
+ /// @throws css::uno::RuntimeException
+ ScVbaRange( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::sheet::XSheetCellRangeContainer >& xRanges, bool bIsRows = false, bool bIsColumns = false );
+ /// @throws css::lang::IllegalArgumentException
+ /// @throws css::uno::RuntimeException
+ ScVbaRange( css::uno::Sequence< css::uno::Any > const& aArgs, css::uno::Reference< css::uno::XComponentContext >const& xContext );
+
+ /// @throws css::uno::RuntimeException
+ ScDocument& getScDocument();
+ /// @throws css::uno::RuntimeException
+ ScDocShell* getScDocShell();
+
+ /** Returns the ScVbaRange implementation object for the passed VBA Range object. */
+ static ScVbaRange* getImplementation( const css::uno::Reference< ov::excel::XRange >& rxRange );
+
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference< css::frame::XModel > getUnoModel();
+ /// @throws css::uno::RuntimeException
+ static css::uno::Reference< css::frame::XModel > getUnoModel( const css::uno::Reference< ov::excel::XRange >& rxRange );
+
+ /// @throws css::uno::RuntimeException
+ const ScRangeList& getScRangeList();
+ /// @throws css::uno::RuntimeException
+ static const ScRangeList& getScRangeList( const css::uno::Reference< ov::excel::XRange >& rxRange );
+
+ virtual ~ScVbaRange() override;
+ virtual css::uno::Reference< ov::XHelperInterface > thisHelperIface() override { return this; }
+ bool isSingleCellRange() const;
+
+ /// @throws css::uno::RuntimeException
+ static css::uno::Reference< ov::excel::XRange > getRangeObjectForName(
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ const OUString& sRangeName, ScDocShell* pDocSh,
+ formula::FormulaGrammar::AddressConvention eConv );
+
+ /// @throws css::uno::RuntimeException
+ static css::uno::Reference< ov::excel::XRange > CellsHelper(
+ const ScDocument& rDoc,
+ const css::uno::Reference< ov::XHelperInterface >& xParent,
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ const css::uno::Reference< css::table::XCellRange >& xRange,
+ const css::uno::Any &nRowIndex, const css::uno::Any &nColumnIndex );
+
+ // Attributes
+ virtual css::uno::Any SAL_CALL getValue() override;
+ virtual void SAL_CALL setValue( const css::uno::Any& aValue ) override;
+ virtual css::uno::Any SAL_CALL getFormula() override;
+ virtual void SAL_CALL setFormula( const css::uno::Any& rFormula ) override;
+ virtual css::uno::Any SAL_CALL getFormulaArray() override;
+ virtual void SAL_CALL setFormulaArray(const css::uno::Any& rFormula) override;
+ virtual css::uno::Any SAL_CALL getFormulaR1C1() override;
+ virtual void SAL_CALL setFormulaR1C1( const css::uno::Any &rFormula ) override;
+ virtual css::uno::Any SAL_CALL getFormulaLocal() override;
+ virtual void SAL_CALL setFormulaLocal( const css::uno::Any &rFormula ) override;
+ virtual css::uno::Any SAL_CALL getFormulaR1C1Local() override;
+ virtual void SAL_CALL setFormulaR1C1Local( const css::uno::Any &rFormula ) override;
+ virtual ::sal_Int32 SAL_CALL getCount() override;
+ virtual ::sal_Int32 SAL_CALL getRow() override;
+ virtual ::sal_Int32 SAL_CALL getColumn() override;
+ virtual OUString SAL_CALL getText() override;
+ using ScVbaRange_BASE::setNumberFormat;
+ virtual void SAL_CALL setNumberFormat( const css::uno::Any& rNumberFormat ) override;
+ virtual css::uno::Any SAL_CALL getNumberFormat() override;
+ virtual void SAL_CALL setMergeCells( const css::uno::Any& bMerge ) override;
+ virtual css::uno::Any SAL_CALL getMergeCells() override;
+ virtual void SAL_CALL setWrapText( const css::uno::Any& bIsWrapped ) override;
+ virtual css::uno::Any SAL_CALL getWrapText() override;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL getEntireRow() override;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL getEntireColumn() override;
+ virtual css::uno::Reference< ov::excel::XComment > SAL_CALL getComment() override;
+ virtual css::uno::Any SAL_CALL getHidden() override;
+ virtual void SAL_CALL setHidden( const css::uno::Any& _hidden ) override;
+ virtual css::uno::Any SAL_CALL getColumnWidth() override;
+ virtual void SAL_CALL setColumnWidth( const css::uno::Any& _columnwidth ) override;
+ virtual css::uno::Any SAL_CALL getRowHeight() override;
+ virtual void SAL_CALL setRowHeight( const css::uno::Any& _rowheight ) override;
+ virtual css::uno::Any SAL_CALL getWidth() override;
+ virtual css::uno::Any SAL_CALL getHeight() override;
+ virtual css::uno::Any SAL_CALL getTop() override;
+ virtual css::uno::Any SAL_CALL getLeft() override;
+
+ virtual css::uno::Reference< ov::excel::XName > SAL_CALL getName() override;
+ virtual css::uno::Reference< ov::excel::XWorksheet > SAL_CALL getWorksheet() override;
+ virtual css::uno::Any SAL_CALL getPageBreak() override;
+ virtual void SAL_CALL setPageBreak( const css::uno::Any& _pagebreak ) override;
+ virtual css::uno::Reference< ov::excel::XValidation > SAL_CALL getValidation() override;
+ virtual css::uno::Any SAL_CALL getPrefixCharacter() override;
+ virtual css::uno::Any SAL_CALL getShowDetail() override;
+ virtual void SAL_CALL setShowDetail(const css::uno::Any& aShowDetail) override;
+ // Methods
+ virtual css::uno::Reference< ov::excel::XComment > SAL_CALL AddComment( const css::uno::Any& Text ) override;
+ virtual void SAL_CALL Clear() override;
+ virtual void SAL_CALL ClearComments() override;
+ virtual void SAL_CALL ClearContents() override;
+ virtual void SAL_CALL ClearFormats() override;
+ virtual css::uno::Any SAL_CALL HasFormula() override;
+ virtual void SAL_CALL FillLeft() override;
+ virtual void SAL_CALL FillRight() override;
+ virtual void SAL_CALL FillUp() override;
+ virtual void SAL_CALL FillDown() override;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Offset( const css::uno::Any &nRowOffset, const css::uno::Any &nColOffset ) override;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL CurrentRegion() override;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL CurrentArray() override;
+ virtual OUString SAL_CALL Characters( const css::uno::Any& nIndex, const css::uno::Any& nCount ) override;
+
+ virtual OUString SAL_CALL Address( const css::uno::Any& RowAbsolute, const css::uno::Any& ColumnAbsolute, const css::uno::Any& ReferenceStyle, const css::uno::Any& External, const css::uno::Any& RelativeTo ) override;
+
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Cells( const css::uno::Any &nRow, const css::uno::Any &nCol ) override;
+ virtual void SAL_CALL Select() override;
+ virtual void SAL_CALL Activate() override;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Rows( const css::uno::Any& nIndex ) override;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Columns( const css::uno::Any &nIndex ) override;
+ virtual void SAL_CALL Copy( const css::uno::Any& Destination ) override;
+ virtual void SAL_CALL Cut( const css::uno::Any& Destination ) override;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Resize( const css::uno::Any& RowSize, const css::uno::Any& ColumnSize ) override;
+ virtual css::uno::Reference< ov::excel::XFont > SAL_CALL Font() override;
+ virtual css::uno::Reference< ov::excel::XInterior > SAL_CALL Interior( ) override ;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Range( const css::uno::Any &Cell1, const css::uno::Any &Cell2 ) override;
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference< ov::excel::XRange > Range( const css::uno::Any &Cell1, const css::uno::Any &Cell2, bool bForceUseInpuRangeTab );
+ virtual css::uno::Any SAL_CALL getCellRange( ) override;
+ /// @throws css::uno::RuntimeException
+ static css::uno::Any getCellRange( const css::uno::Reference< ov::excel::XRange >& rxRange );
+ virtual void SAL_CALL PasteSpecial( const css::uno::Any& Paste, const css::uno::Any& Operation, const css::uno::Any& SkipBlanks, const css::uno::Any& Transpose ) override;
+ virtual sal_Bool SAL_CALL Replace( const OUString& What, const OUString& Replacement, const css::uno::Any& LookAt, const css::uno::Any& SearchOrder, const css::uno::Any& MatchCase, const css::uno::Any& MatchByte, const css::uno::Any& SearchFormat, const css::uno::Any& ReplaceFormat ) override;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Find( const css::uno::Any& What, const css::uno::Any& After, const css::uno::Any& LookIn, const css::uno::Any& LookAt, const css::uno::Any& SearchOrder, const css::uno::Any& SearchDirection, const css::uno::Any& MatchCase, const css::uno::Any& MatchByte, const css::uno::Any& SearchFormat ) override;
+ virtual void SAL_CALL Sort( const css::uno::Any& Key1, const css::uno::Any& Order1, const css::uno::Any& Key2, const css::uno::Any& Type, const css::uno::Any& Order2, const css::uno::Any& Key3, const css::uno::Any& Order3, const css::uno::Any& Header, const css::uno::Any& OrderCustom, const css::uno::Any& MatchCase, const css::uno::Any& Orientation, const css::uno::Any& SortMethod, const css::uno::Any& DataOption1, const css::uno::Any& DataOption2, const css::uno::Any& DataOption3 ) override;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL End( ::sal_Int32 Direction ) override;
+ virtual css::uno::Reference< ov::excel::XCharacters > SAL_CALL characters( const css::uno::Any& Start, const css::uno::Any& Length ) override;
+ virtual void SAL_CALL Delete( const css::uno::Any& Shift ) override;
+ virtual css::uno::Any SAL_CALL Areas( const css::uno::Any& ) override;
+ virtual css::uno::Any SAL_CALL Borders( const css::uno::Any& ) override;
+ virtual css::uno::Any SAL_CALL BorderAround( const css::uno::Any& LineStyle,
+ const css::uno::Any& Weight, const css::uno::Any& ColorIndex, const css::uno::Any& Color ) override;
+ virtual css::uno::Any SAL_CALL Hyperlinks( const css::uno::Any& aIndex ) override;
+
+ virtual void SAL_CALL AutoFilter( const css::uno::Any& Field, const css::uno::Any& Criteria1, const css::uno::Any& Operator, const css::uno::Any& Criteria2, const css::uno::Any& VisibleDropDown ) override;
+ virtual void SAL_CALL Insert( const css::uno::Any& Shift, const css::uno::Any& CopyOrigin ) override;
+ virtual void SAL_CALL Autofit() override;
+ virtual void SAL_CALL PrintOut( const css::uno::Any& From, const css::uno::Any& To, const css::uno::Any& Copies, const css::uno::Any& Preview, const css::uno::Any& ActivePrinter, const css::uno::Any& PrintToFile, const css::uno::Any& Collate, const css::uno::Any& PrToFileName ) override;
+ virtual void SAL_CALL AutoFill( const css::uno::Reference< ov::excel::XRange >& Destination, const css::uno::Any& Type ) override ;
+ void SAL_CALL Calculate( ) override;
+ virtual void SAL_CALL AutoOutline( ) override;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Item( const css::uno::Any& row, const css::uno::Any& column ) override;
+ virtual void SAL_CALL ClearOutline( ) override;
+ virtual void SAL_CALL Ungroup( ) override;
+ virtual void SAL_CALL Group( ) override;
+ virtual void SAL_CALL Merge( const css::uno::Any& Across ) override;
+ virtual void SAL_CALL UnMerge( ) override;
+ virtual css::uno::Any SAL_CALL getStyle() override;
+ virtual void SAL_CALL setStyle( const css::uno::Any& _style ) override;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Next() override;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Previous() override;
+ virtual void SAL_CALL RemoveSubtotal( ) override;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL MergeArea() override;
+ virtual void SAL_CALL Subtotal( ::sal_Int32 GroupBy, ::sal_Int32 Function, const css::uno::Sequence< ::sal_Int32 >& TotalList, const css::uno::Any& Replace, const css::uno::Any& PageBreaks, const css::uno::Any& SummaryBelowData ) override;
+
+ // XEnumerationAccess
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+ // XElementAccess
+ virtual css::uno::Type SAL_CALL getElementType() override
+ {
+ return cppu::UnoType<ov::excel::XRange>::get();
+
+ }
+ virtual sal_Bool SAL_CALL hasElements() override;
+ // XDefaultMethod
+ OUString SAL_CALL getDefaultMethodName( ) override;
+ // XDefaultProperty
+ OUString SAL_CALL getDefaultPropertyName( ) override { return "Value"; }
+
+// #TODO completely rewrite ScVbaRange, it's become a hackfest
+// it needs to be closer to ScCellRangeBase in that the underlying
+// object model should probably be a ScRangelst.
+// * would be nice to be able to construct a range from an address only
+// * or a list of address ( multi-area )
+// * object should be a lightweight as possible
+// * we shouldn't need hacks like this below
+ /// @throws css::uno::RuntimeException
+ static css::uno::Reference< ov::excel::XRange > ApplicationRange( const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Any &Cell1, const css::uno::Any &Cell2 );
+ static bool getCellRangesForAddress(ScRefFlags &rResFlags, std::u16string_view sAddress, ScDocShell* pDocSh, ScRangeList& rCellRanges, formula::FormulaGrammar::AddressConvention eConv, char cDelimiter );
+ virtual sal_Bool SAL_CALL GoalSeek( const css::uno::Any& Goal, const css::uno::Reference< ov::excel::XRange >& ChangingCell ) override;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL SpecialCells( const css::uno::Any& _oType, const css::uno::Any& _oValue) override;
+ // XErrorQuery
+ virtual sal_Bool SAL_CALL hasError( ) override;
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/// @throws css::uno::RuntimeException
+bool getScRangeListForAddress( const OUString& sName, ScDocShell* pDocSh, const ScRange& refRange,
+ ScRangeList& aCellRanges,
+ formula::FormulaGrammar::AddressConvention aConv = formula::FormulaGrammar::CONV_XL_A1 );
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbasheetobject.cxx b/sc/source/ui/vba/vbasheetobject.cxx
new file mode 100644
index 000000000..52513095f
--- /dev/null
+++ b/sc/source/ui/vba/vbasheetobject.cxx
@@ -0,0 +1,540 @@
+/* -*- 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 "vbasheetobject.hxx"
+#include <com/sun/star/awt/TextAlign.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/drawing/XControlShape.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/script/ScriptEventDescriptor.hpp>
+#include <com/sun/star/script/XEventAttacherManager.hpp>
+#include <com/sun/star/style/VerticalAlignment.hpp>
+#include <comphelper/documentinfo.hxx>
+#include <ooo/vba/excel/Constants.hpp>
+#include <ooo/vba/excel/XlOrientation.hpp>
+#include <ooo/vba/excel/XlPlacement.hpp>
+#include <filter/msfilter/msvbahelper.hxx>
+#include "vbafont.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+constexpr OUStringLiteral gaListenerType = u"XActionListener";
+constexpr OUStringLiteral gaEventMethod = u"actionPerformed";
+
+
+ScVbaButtonCharacters::ScVbaButtonCharacters(
+ const uno::Reference< XHelperInterface >& rxParent,
+ const uno::Reference< uno::XComponentContext >& rxContext,
+ const uno::Reference< beans::XPropertySet >& rxPropSet,
+ const ScVbaPalette& rPalette,
+ const uno::Any& rStart,
+ const uno::Any& rLength ) :
+ ScVbaButtonCharacters_BASE( rxParent, rxContext ),
+ maPalette( rPalette ),
+ mxPropSet( rxPropSet, uno::UNO_SET_THROW )
+{
+ // extract optional start parameter (missing or invalid -> from beginning)
+ if( !(rStart >>= mnStart) || (mnStart < 1) )
+ mnStart = 1;
+ --mnStart; // VBA is 1-based, rtl string is 0-based
+
+ // extract optional length parameter (missing or invalid -> to end)
+ if( !(rLength >>= mnLength) || (mnLength < 1) )
+ mnLength = SAL_MAX_INT32;
+}
+
+ScVbaButtonCharacters::~ScVbaButtonCharacters()
+{
+}
+
+// XCharacters attributes
+
+OUString SAL_CALL ScVbaButtonCharacters::getCaption()
+{
+ // ignore invalid mnStart and/or mnLength members
+ OUString aString = getFullString();
+ sal_Int32 nStart = ::std::min( mnStart, aString.getLength() );
+ sal_Int32 nLength = ::std::min( mnLength, aString.getLength() - nStart );
+ return aString.copy( nStart, nLength );
+}
+
+void SAL_CALL ScVbaButtonCharacters::setCaption( const OUString& rCaption )
+{
+ /* Replace the covered text with the passed text, ignore invalid mnStart
+ and/or mnLength members. This operation does not affect the mnLength
+ parameter. If the inserted text is longer than mnLength, the additional
+ characters are not covered by this object. If the inserted text is
+ shorter than mnLength, other uncovered characters from the original
+ string will be covered now, thus may be changed with subsequent
+ operations. */
+ OUString aString = getFullString();
+ sal_Int32 nStart = ::std::min( mnStart, aString.getLength() );
+ sal_Int32 nLength = ::std::min( mnLength, aString.getLength() - nStart );
+ setFullString( aString.replaceAt( nStart, nLength, rCaption ) );
+}
+
+sal_Int32 SAL_CALL ScVbaButtonCharacters::getCount()
+{
+ // always return the total length of the caption
+ return getFullString().getLength();
+}
+
+OUString SAL_CALL ScVbaButtonCharacters::getText()
+{
+ // Text attribute same as Caption attribute?
+ return getCaption();
+}
+
+void SAL_CALL ScVbaButtonCharacters::setText( const OUString& rText )
+{
+ // Text attribute same as Caption attribute?
+ setCaption( rText );
+}
+
+uno::Reference< excel::XFont > SAL_CALL ScVbaButtonCharacters::getFont()
+{
+ return new ScVbaFont( this, mxContext, maPalette, mxPropSet, nullptr, true );
+}
+
+void SAL_CALL ScVbaButtonCharacters::setFont( const uno::Reference< excel::XFont >& /*rxFont*/ )
+{
+ // TODO
+}
+
+// XCharacters methods
+
+void SAL_CALL ScVbaButtonCharacters::Insert( const OUString& rString )
+{
+ /* The Insert() operation is in fact "replace covered characters", at
+ least for buttons... It seems there is no easy way to really insert a
+ substring. This operation does not affect the mnLength parameter. */
+ setCaption( rString );
+}
+
+void SAL_CALL ScVbaButtonCharacters::Delete()
+{
+ /* The Delete() operation is nothing else than "replace with empty string".
+ This does not affect the mnLength parameter, multiple calls of Delete()
+ will remove characters as long as there are some more covered by this
+ object. */
+ setCaption( OUString() );
+}
+
+// XHelperInterface
+
+VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaButtonCharacters, "ooo.vba.excel.Characters" )
+
+// private
+
+OUString ScVbaButtonCharacters::getFullString() const
+{
+ return mxPropSet->getPropertyValue( "Label" ).get< OUString >();
+}
+
+void ScVbaButtonCharacters::setFullString( const OUString& rString )
+{
+ mxPropSet->setPropertyValue( "Label", uno::Any( rString ) );
+}
+
+ScVbaSheetObjectBase::ScVbaSheetObjectBase(
+ const uno::Reference< XHelperInterface >& rxParent,
+ const uno::Reference< uno::XComponentContext >& rxContext,
+ const uno::Reference< frame::XModel >& rxModel,
+ const uno::Reference< drawing::XShape >& rxShape ) :
+ ScVbaSheetObject_BASE( rxParent, rxContext ),
+ maPalette( rxModel ),
+ mxModel( rxModel, uno::UNO_SET_THROW ),
+ mxShape( rxShape, uno::UNO_SET_THROW ),
+ mxShapeProps( rxShape, uno::UNO_QUERY_THROW )
+{
+}
+
+// XSheetObject attributes
+
+double SAL_CALL ScVbaSheetObjectBase::getLeft()
+{
+ return HmmToPoints( mxShape->getPosition().X );
+}
+
+void SAL_CALL ScVbaSheetObjectBase::setLeft( double fLeft )
+{
+ if( fLeft < 0.0 )
+ throw uno::RuntimeException();
+ mxShape->setPosition( awt::Point( PointsToHmm( fLeft ), mxShape->getPosition().Y ) );
+}
+
+double SAL_CALL ScVbaSheetObjectBase::getTop()
+{
+ return HmmToPoints( mxShape->getPosition().Y );
+}
+
+void SAL_CALL ScVbaSheetObjectBase::setTop( double fTop )
+{
+ if( fTop < 0.0 )
+ throw uno::RuntimeException();
+ mxShape->setPosition( awt::Point( mxShape->getPosition().X, PointsToHmm( fTop ) ) );
+}
+
+double SAL_CALL ScVbaSheetObjectBase::getWidth()
+{
+ return HmmToPoints( mxShape->getSize().Width );
+}
+
+void SAL_CALL ScVbaSheetObjectBase::setWidth( double fWidth )
+{
+ if( fWidth <= 0.0 )
+ throw uno::RuntimeException();
+ mxShape->setSize( awt::Size( PointsToHmm( fWidth ), mxShape->getSize().Height ) );
+}
+
+double SAL_CALL ScVbaSheetObjectBase::getHeight()
+{
+ return HmmToPoints( mxShape->getSize().Height );
+}
+
+void SAL_CALL ScVbaSheetObjectBase::setHeight( double fHeight )
+{
+ if( fHeight <= 0.0 )
+ throw uno::RuntimeException();
+ mxShape->setSize( awt::Size( mxShape->getSize().Width, PointsToHmm( fHeight ) ) );
+}
+
+OUString SAL_CALL ScVbaSheetObjectBase::getName()
+{
+ return mxShapeProps->getPropertyValue( "Name" ).get< OUString >();
+}
+
+void SAL_CALL ScVbaSheetObjectBase::setName( const OUString& rName )
+{
+ mxShapeProps->setPropertyValue( "Name", uno::Any( rName ) );
+}
+
+sal_Int32 SAL_CALL ScVbaSheetObjectBase::getPlacement()
+{
+ sal_Int32 const nRet = excel::XlPlacement::xlMoveAndSize;
+#if 0 // TODO: not working at the moment.
+ SvxShape* pShape = SdrObject::getSdrObjectFromXShape( mxShape );
+ if(pShape)
+ {
+ SdrObject* pObj = pShape->GetSdrObject();
+ if (pObj)
+ {
+ ScAnchorType eType = ScDrawLayer::GetAnchor(pObj);
+ if (eType == SCA_PAGE)
+ nRet = excel::XlPlacement::xlFreeFloating;
+ }
+ }
+#endif
+ return nRet;
+}
+
+void SAL_CALL ScVbaSheetObjectBase::setPlacement( sal_Int32 /*nPlacement*/ )
+{
+#if 0 // TODO: not working at the moment.
+ SvxShape* pShape = SdrObject::getSdrObjectFromXShape( mxShape );
+ if(pShape)
+ {
+ SdrObject* pObj = pShape->GetSdrObject();
+ if (pObj)
+ {
+ ScAnchorType eType = SCA_CELL;
+ if ( nPlacement == excel::XlPlacement::xlFreeFloating )
+ eType = SCA_PAGE;
+
+ // xlMove is not supported, treated as SCA_CELL (xlMoveAndSize)
+
+ ScDrawLayer::SetAnchor(pObj, eType);
+ }
+ }
+#endif
+}
+
+sal_Bool SAL_CALL ScVbaSheetObjectBase::getPrintObject()
+{
+ // not supported
+ return true;
+}
+
+void SAL_CALL ScVbaSheetObjectBase::setPrintObject( sal_Bool /*bPrintObject*/ )
+{
+ // not supported
+}
+
+// private
+
+void ScVbaSheetObjectBase::setDefaultProperties( sal_Int32 nIndex )
+{
+ OUString aName = implGetBaseName() + OUStringChar(' ') + OUString::number( nIndex + 1 );
+ setName( aName );
+ implSetDefaultProperties();
+}
+
+void ScVbaSheetObjectBase::implSetDefaultProperties()
+{
+}
+
+ScVbaControlObjectBase::ScVbaControlObjectBase(
+ const uno::Reference< XHelperInterface >& rxParent,
+ const uno::Reference< uno::XComponentContext >& rxContext,
+ const uno::Reference< frame::XModel >& rxModel,
+ const uno::Reference< container::XIndexContainer >& rxFormIC,
+ const uno::Reference< drawing::XControlShape >& rxControlShape ) :
+ ScVbaControlObject_BASE( rxParent, rxContext, rxModel, uno::Reference< drawing::XShape >( rxControlShape, uno::UNO_QUERY_THROW ) ),
+ mxFormIC( rxFormIC, uno::UNO_SET_THROW ),
+ mxControlProps( rxControlShape->getControl(), uno::UNO_QUERY_THROW ),
+ mbNotifyMacroEventRead(false)
+{
+}
+
+// XSheetObject attributes
+
+OUString SAL_CALL ScVbaControlObjectBase::getName()
+{
+ return mxControlProps->getPropertyValue( "Name" ).get< OUString >();
+}
+
+void SAL_CALL ScVbaControlObjectBase::setName( const OUString& rName )
+{
+ mxControlProps->setPropertyValue( "Name", uno::Any( rName ) );
+}
+
+OUString SAL_CALL ScVbaControlObjectBase::getOnAction()
+{
+ uno::Reference< script::XEventAttacherManager > xEventMgr( mxFormIC, uno::UNO_QUERY_THROW );
+ sal_Int32 nIndex = getModelIndexInForm();
+ const uno::Sequence< script::ScriptEventDescriptor > aEvents = xEventMgr->getScriptEvents( nIndex );
+ if( aEvents.hasElements() )
+ {
+ const script::ScriptEventDescriptor* pEvent = std::find_if(aEvents.begin(), aEvents.end(),
+ [](const script::ScriptEventDescriptor& rEvent) {
+ return (rEvent.ListenerType == gaListenerType)
+ && (rEvent.EventMethod == gaEventMethod)
+ && (rEvent.ScriptType == "Script");
+ });
+ if (pEvent != aEvents.end())
+ return extractMacroName( pEvent->ScriptCode );
+ }
+ return OUString();
+}
+
+void ScVbaControlObjectBase::NotifyMacroEventRead()
+{
+ if (mbNotifyMacroEventRead)
+ return;
+ comphelper::DocumentInfo::notifyMacroEventRead(mxModel);
+ mbNotifyMacroEventRead = true;
+}
+
+void SAL_CALL ScVbaControlObjectBase::setOnAction( const OUString& rMacroName )
+{
+ uno::Reference< script::XEventAttacherManager > xEventMgr( mxFormIC, uno::UNO_QUERY_THROW );
+ sal_Int32 nIndex = getModelIndexInForm();
+
+ // first, remove a registered event (try/catch just in case implementation throws)
+ try { xEventMgr->revokeScriptEvent( nIndex, gaListenerType, gaEventMethod, OUString() ); } catch( uno::Exception& ) {}
+
+ // if a macro name has been passed, try to attach it to the event
+ if( rMacroName.isEmpty() )
+ return;
+
+ MacroResolvedInfo aResolvedMacro = resolveVBAMacro( getSfxObjShell( mxModel ), rMacroName );
+ if( !aResolvedMacro.mbFound )
+ throw uno::RuntimeException();
+ script::ScriptEventDescriptor aDescriptor;
+ aDescriptor.ListenerType = gaListenerType;
+ aDescriptor.EventMethod = gaEventMethod;
+ aDescriptor.ScriptType = "Script";
+ aDescriptor.ScriptCode = makeMacroURL( aResolvedMacro.msResolvedMacro );
+ NotifyMacroEventRead();
+ xEventMgr->registerScriptEvent( nIndex, aDescriptor );
+}
+
+sal_Bool SAL_CALL ScVbaControlObjectBase::getPrintObject()
+{
+ return mxControlProps->getPropertyValue( "Printable" ).get<bool>();
+}
+
+void SAL_CALL ScVbaControlObjectBase::setPrintObject( sal_Bool bPrintObject )
+{
+ mxControlProps->setPropertyValue( "Printable", uno::Any( bPrintObject ) );
+}
+
+// XControlObject attributes
+
+sal_Bool SAL_CALL ScVbaControlObjectBase::getAutoSize()
+{
+ // not supported
+ return false;
+}
+
+void SAL_CALL ScVbaControlObjectBase::setAutoSize( sal_Bool /*bAutoSize*/ )
+{
+ // not supported
+}
+
+// private
+
+sal_Int32 ScVbaControlObjectBase::getModelIndexInForm() const
+{
+ for( sal_Int32 nIndex = 0, nCount = mxFormIC->getCount(); nIndex < nCount; ++nIndex )
+ {
+ uno::Reference< beans::XPropertySet > xProps( mxFormIC->getByIndex( nIndex ), uno::UNO_QUERY_THROW );
+ if( mxControlProps.get() == xProps.get() )
+ return nIndex;
+ }
+ throw uno::RuntimeException();
+}
+
+ScVbaButton::ScVbaButton(
+ const uno::Reference< XHelperInterface >& rxParent,
+ const uno::Reference< uno::XComponentContext >& rxContext,
+ const uno::Reference< frame::XModel >& rxModel,
+ const uno::Reference< container::XIndexContainer >& rxFormIC,
+ const uno::Reference< drawing::XControlShape >& rxControlShape ) :
+ ScVbaButton_BASE( rxParent, rxContext, rxModel, rxFormIC, rxControlShape )
+{
+}
+
+// XButton attributes
+
+OUString SAL_CALL ScVbaButton::getCaption()
+{
+ return mxControlProps->getPropertyValue( "Label" ).get< OUString >();
+}
+
+void SAL_CALL ScVbaButton::setCaption( const OUString& rCaption )
+{
+ mxControlProps->setPropertyValue( "Label", uno::Any( rCaption ) );
+}
+
+uno::Reference< excel::XFont > SAL_CALL ScVbaButton::getFont()
+{
+ return new ScVbaFont( this, mxContext, maPalette, mxControlProps, nullptr, true );
+}
+
+void SAL_CALL ScVbaButton::setFont( const uno::Reference< excel::XFont >& /*rxFont*/ )
+{
+ // TODO
+}
+
+sal_Int32 SAL_CALL ScVbaButton::getHorizontalAlignment()
+{
+ switch( mxControlProps->getPropertyValue( "Align" ).get< sal_Int16 >() )
+ {
+ case awt::TextAlign::LEFT: return excel::Constants::xlLeft;
+ case awt::TextAlign::RIGHT: return excel::Constants::xlRight;
+ case awt::TextAlign::CENTER: return excel::Constants::xlCenter;
+ }
+ return excel::Constants::xlCenter;
+}
+
+void SAL_CALL ScVbaButton::setHorizontalAlignment( sal_Int32 nAlign )
+{
+ sal_Int32 nAwtAlign = awt::TextAlign::CENTER;
+ switch( nAlign )
+ {
+ case excel::Constants::xlLeft: nAwtAlign = awt::TextAlign::LEFT; break;
+ case excel::Constants::xlRight: nAwtAlign = awt::TextAlign::RIGHT; break;
+ case excel::Constants::xlCenter: nAwtAlign = awt::TextAlign::CENTER; break;
+ }
+ // form controls expect short value
+ mxControlProps->setPropertyValue( "Align", uno::Any( static_cast< sal_Int16 >( nAwtAlign ) ) );
+}
+
+sal_Int32 SAL_CALL ScVbaButton::getVerticalAlignment()
+{
+ switch( mxControlProps->getPropertyValue( "VerticalAlign" ).get< style::VerticalAlignment >() )
+ {
+ case style::VerticalAlignment_TOP: return excel::Constants::xlTop;
+ case style::VerticalAlignment_BOTTOM: return excel::Constants::xlBottom;
+ case style::VerticalAlignment_MIDDLE: return excel::Constants::xlCenter;
+ default:;
+ }
+ return excel::Constants::xlCenter;
+}
+
+void SAL_CALL ScVbaButton::setVerticalAlignment( sal_Int32 nAlign )
+{
+ style::VerticalAlignment eAwtAlign = style::VerticalAlignment_MIDDLE;
+ switch( nAlign )
+ {
+ case excel::Constants::xlTop: eAwtAlign = style::VerticalAlignment_TOP; break;
+ case excel::Constants::xlBottom: eAwtAlign = style::VerticalAlignment_BOTTOM; break;
+ case excel::Constants::xlCenter: eAwtAlign = style::VerticalAlignment_MIDDLE; break;
+ }
+ mxControlProps->setPropertyValue( "VerticalAlign", uno::Any( eAwtAlign ) );
+}
+
+sal_Int32 SAL_CALL ScVbaButton::getOrientation()
+{
+ // not supported
+ return excel::XlOrientation::xlHorizontal;
+}
+
+void SAL_CALL ScVbaButton::setOrientation( sal_Int32 /*nOrientation*/ )
+{
+ // not supported
+}
+
+uno::Any SAL_CALL ScVbaButton::getValue()
+{
+ return mxControlProps->getPropertyValue( "State" );
+}
+
+void SAL_CALL ScVbaButton::setValue( const uno::Any &nValue )
+{
+ return mxControlProps->setPropertyValue( "State", nValue );
+}
+
+OUString SAL_CALL ScVbaButton::getText()
+{
+ return mxControlProps->getPropertyValue( "Label" ).get< OUString >();
+}
+
+void SAL_CALL ScVbaButton::setText( const OUString &aText )
+{
+ return mxControlProps->setPropertyValue( "Label", uno::Any( aText ) );
+}
+
+// XButton methods
+
+uno::Reference< excel::XCharacters > SAL_CALL ScVbaButton::Characters( const uno::Any& rStart, const uno::Any& rLength )
+{
+ return new ScVbaButtonCharacters( this, mxContext, mxControlProps, maPalette, rStart, rLength );
+}
+
+// XHelperInterface
+
+VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaButton, "ooo.vba.excel.Button" )
+
+// private
+
+OUString ScVbaButton::implGetBaseName() const
+{
+ return "Button";
+}
+
+void ScVbaButton::implSetDefaultProperties()
+{
+ setCaption( getName() );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbasheetobject.hxx b/sc/source/ui/vba/vbasheetobject.hxx
new file mode 100644
index 000000000..d88b15034
--- /dev/null
+++ b/sc/source/ui/vba/vbasheetobject.hxx
@@ -0,0 +1,209 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <ooo/vba/excel/XButton.hpp>
+#include <ooo/vba/excel/XControlObject.hpp>
+#include <ooo/vba/excel/XSheetObject.hpp>
+#include <cppuhelper/implbase.hxx>
+#include <vbahelper/vbahelperinterface.hxx>
+#include "vbapalette.hxx"
+
+namespace com::sun::star {
+ namespace container { class XIndexContainer; }
+ namespace drawing { class XControlShape; }
+}
+
+typedef InheritedHelperInterfaceWeakImpl< ov::excel::XCharacters > ScVbaButtonCharacters_BASE;
+
+/** Simple implementation of the Characters symbol for drawing button objects. */
+class ScVbaButtonCharacters : public ScVbaButtonCharacters_BASE
+{
+public:
+ /// @throws css::uno::RuntimeException
+ explicit ScVbaButtonCharacters(
+ const css::uno::Reference< ov::XHelperInterface >& rxParent,
+ const css::uno::Reference< css::uno::XComponentContext >& rxContext,
+ const css::uno::Reference< css::beans::XPropertySet >& rxPropSet,
+ const ScVbaPalette& rPalette,
+ const css::uno::Any& rStart,
+ const css::uno::Any& rLength );
+ virtual ~ScVbaButtonCharacters() override;
+
+ // XCharacters attributes
+ virtual OUString SAL_CALL getCaption() override;
+ virtual void SAL_CALL setCaption( const OUString& rCaption ) override;
+ virtual OUString SAL_CALL getText() override;
+ virtual void SAL_CALL setText( const OUString& rText ) override;
+ virtual sal_Int32 SAL_CALL getCount() override;
+ virtual css::uno::Reference< ov::excel::XFont > SAL_CALL getFont() override;
+ virtual void SAL_CALL setFont( const css::uno::Reference< ov::excel::XFont >& rxFont ) override;
+
+ // XCharacters methods
+ virtual void SAL_CALL Insert( const OUString& rString ) override;
+ virtual void SAL_CALL Delete() override;
+
+ // XHelperInterface
+ VBAHELPER_DECL_XHELPERINTERFACE
+
+private:
+ /// @throws css::uno::RuntimeException
+ OUString getFullString() const;
+ /// @throws css::uno::RuntimeException
+ void setFullString( const OUString& rString );
+
+private:
+ ScVbaPalette maPalette;
+ css::uno::Reference< css::beans::XPropertySet > mxPropSet;
+ sal_Int32 mnStart;
+ sal_Int32 mnLength;
+};
+
+typedef InheritedHelperInterfaceWeakImpl< ov::excel::XSheetObject > ScVbaSheetObject_BASE;
+
+/** Base class for drawing objects embedded in sheets. */
+class ScVbaSheetObjectBase : public ScVbaSheetObject_BASE
+{
+public:
+ /// @throws css::uno::RuntimeException
+ explicit ScVbaSheetObjectBase(
+ const css::uno::Reference< ov::XHelperInterface >& rxParent,
+ const css::uno::Reference< css::uno::XComponentContext >& rxContext,
+ const css::uno::Reference< css::frame::XModel >& rxModel,
+ const css::uno::Reference< css::drawing::XShape >& rxShape );
+
+ // XSheetObject attributes
+ virtual double SAL_CALL getLeft() override;
+ virtual void SAL_CALL setLeft( double fLeft ) override;
+ virtual double SAL_CALL getTop() override;
+ virtual void SAL_CALL setTop( double fTop ) override;
+ virtual double SAL_CALL getWidth() override;
+ virtual void SAL_CALL setWidth( double fWidth ) override;
+ virtual double SAL_CALL getHeight() override;
+ virtual void SAL_CALL setHeight( double fHeight ) override;
+ virtual OUString SAL_CALL getName() override;
+ virtual void SAL_CALL setName( const OUString& rName ) override;
+ virtual sal_Int32 SAL_CALL getPlacement() override;
+ virtual void SAL_CALL setPlacement( sal_Int32 nPlacement ) override;
+ virtual sal_Bool SAL_CALL getPrintObject() override;
+ virtual void SAL_CALL setPrintObject( sal_Bool bPrintObject ) override;
+
+ /** Sets default properties after a new object has been created.
+
+ @throws css::uno::RuntimeException
+ */
+ void setDefaultProperties( sal_Int32 nIndex );
+
+protected:
+ /** Derived classes return the base name used for new objects. */
+ virtual OUString implGetBaseName() const = 0;
+ /** Derived classes set default properties for new drawing objects.
+
+ @throws css::uno::RuntimeException
+ */
+ virtual void implSetDefaultProperties();
+
+protected:
+ ScVbaPalette maPalette;
+ css::uno::Reference< css::frame::XModel > mxModel;
+ css::uno::Reference< css::drawing::XShape > mxShape;
+ css::uno::Reference< css::beans::XPropertySet > mxShapeProps;
+};
+
+typedef ::cppu::ImplInheritanceHelper< ScVbaSheetObjectBase, ov::excel::XControlObject > ScVbaControlObject_BASE;
+
+class ScVbaControlObjectBase : public ScVbaControlObject_BASE
+{
+public:
+ /// @throws css::uno::RuntimeException
+ explicit ScVbaControlObjectBase(
+ const css::uno::Reference< ov::XHelperInterface >& rxParent,
+ const css::uno::Reference< css::uno::XComponentContext >& rxContext,
+ const css::uno::Reference< css::frame::XModel >& rxModel,
+ const css::uno::Reference< css::container::XIndexContainer >& rxFormIC,
+ const css::uno::Reference< css::drawing::XControlShape >& rxControlShape );
+
+ // XSheetObject attributes
+ virtual OUString SAL_CALL getName() override;
+ virtual void SAL_CALL setName( const OUString& rName ) override;
+ virtual OUString SAL_CALL getOnAction() override;
+ virtual void SAL_CALL setOnAction( const OUString& rMacroName ) override;
+ virtual sal_Bool SAL_CALL getPrintObject() override;
+ virtual void SAL_CALL setPrintObject( sal_Bool bPrintObject ) override;
+
+ // XControlObject attributes
+ virtual sal_Bool SAL_CALL getAutoSize() override;
+ virtual void SAL_CALL setAutoSize( sal_Bool bAutoSize ) override;
+
+ /// Notify that the document contains a macro event handler
+ void NotifyMacroEventRead();
+
+protected:
+ /// @throws css::uno::RuntimeException
+ sal_Int32 getModelIndexInForm() const;
+
+protected:
+ css::uno::Reference< css::container::XIndexContainer > mxFormIC;
+ css::uno::Reference< css::beans::XPropertySet > mxControlProps;
+ bool mbNotifyMacroEventRead;
+};
+
+typedef ::cppu::ImplInheritanceHelper< ScVbaControlObjectBase, ov::excel::XButton > ScVbaButton_BASE;
+
+class ScVbaButton : public ScVbaButton_BASE
+{
+public:
+ /// @throws css::uno::RuntimeException
+ explicit ScVbaButton(
+ const css::uno::Reference< ov::XHelperInterface >& rxParent,
+ const css::uno::Reference< css::uno::XComponentContext >& rxContext,
+ const css::uno::Reference< css::frame::XModel >& rxModel,
+ const css::uno::Reference< css::container::XIndexContainer >& rxFormIC,
+ const css::uno::Reference< css::drawing::XControlShape >& rxControlShape );
+
+ // XButton attributes
+ virtual OUString SAL_CALL getCaption() override;
+ virtual void SAL_CALL setCaption( const OUString& rCaption ) override;
+ virtual css::uno::Reference< ov::excel::XFont > SAL_CALL getFont() override;
+ virtual void SAL_CALL setFont( const css::uno::Reference< ov::excel::XFont >& rxFont ) override;
+ virtual sal_Int32 SAL_CALL getHorizontalAlignment() override;
+ virtual void SAL_CALL setHorizontalAlignment( sal_Int32 nAlign ) override;
+ virtual sal_Int32 SAL_CALL getVerticalAlignment() override;
+ virtual void SAL_CALL setVerticalAlignment( sal_Int32 nAlign ) override;
+ virtual sal_Int32 SAL_CALL getOrientation() override;
+ virtual void SAL_CALL setOrientation( sal_Int32 nOrientation ) override;
+ virtual css::uno::Any SAL_CALL getValue() override;
+ virtual void SAL_CALL setValue( const css::uno::Any &nValue ) override;
+ virtual OUString SAL_CALL getText() override;
+ virtual void SAL_CALL setText( const OUString &aText ) override;
+
+ // XButton methods
+ css::uno::Reference< ov::excel::XCharacters > SAL_CALL Characters(
+ const css::uno::Any& rStart, const css::uno::Any& rLength ) override;
+
+ // XHelperInterface
+ VBAHELPER_DECL_XHELPERINTERFACE
+
+protected:
+ virtual OUString implGetBaseName() const override;
+ virtual void implSetDefaultProperties() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbasheetobjects.cxx b/sc/source/ui/vba/vbasheetobjects.cxx
new file mode 100644
index 000000000..32e025a3c
--- /dev/null
+++ b/sc/source/ui/vba/vbasheetobjects.cxx
@@ -0,0 +1,555 @@
+/* -*- 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 "vbasheetobjects.hxx"
+#include <vector>
+#include <rtl/math.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/drawing/XControlShape.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/drawing/XShapes.hpp>
+#include <com/sun/star/form/FormComponentType.hpp>
+#include <com/sun/star/form/XForm.hpp>
+#include <com/sun/star/form/XFormComponent.hpp>
+#include <com/sun/star/form/XFormsSupplier.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include "vbasheetobject.hxx"
+#include <cppuhelper/implbase.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+namespace {
+
+template< typename Type >
+bool lclGetProperty( Type& orValue, const uno::Reference< beans::XPropertySet >& rxPropSet, const OUString& rPropName )
+{
+ try
+ {
+ return rxPropSet->getPropertyValue( rPropName ) >>= orValue;
+ }
+ catch( uno::Exception& )
+ {
+ }
+ return false;
+}
+
+/** Rounds the passed value to a multiple of 0.75 and converts it to 1/100 mm.
+
+ @throws uno::RuntimeException
+*/
+double lclPointsToHmm( const uno::Any& rPoints )
+{
+ return PointsToHmm( ::rtl::math::approxFloor( rPoints.get< double >() / 0.75 ) * 0.75 );
+}
+
+} // namespace
+
+// Base implementations
+
+/** Container for a specific type of drawing object in a spreadsheet.
+
+ Derived classes provide all required functionality specific to the type of
+ shapes covered by the container.
+ */
+class ScVbaObjectContainer : public ::cppu::WeakImplHelper< container::XIndexAccess >
+{
+public:
+ /// @throws uno::RuntimeException
+ explicit ScVbaObjectContainer(
+ const uno::Reference< XHelperInterface >& rxParent,
+ const uno::Reference< uno::XComponentContext >& rxContext,
+ const uno::Reference< frame::XModel >& rxModel,
+ const uno::Reference< sheet::XSpreadsheet >& rxSheet,
+ const uno::Type& rVbaType );
+
+ /** Returns the VBA helper interface of the VBA collection object. */
+ const uno::Reference< XHelperInterface >& getParent() const { return mxParent; }
+ /** Returns the component context of the VBA collection object. */
+ const uno::Reference< uno::XComponentContext >& getContext() const { return mxContext; }
+ /** Returns the VBA type information of the objects in this container. */
+ const uno::Type& getVbaType() const { return maVbaType; }
+
+ /** Collects all shapes supported by this instance and inserts them into
+ the internal shape vector.
+
+ @throws uno::RuntimeException
+ */
+ void collectShapes();
+ /** Creates and returns a new UNO shape.
+
+ @throws uno::RuntimeException
+ */
+ uno::Reference< drawing::XShape > createShape( const awt::Point& rPos, const awt::Size& rSize );
+ /** Inserts the passed shape into the draw page and into this container, and returns its index in the draw page.
+
+ @throws uno::RuntimeException
+ */
+ sal_Int32 insertShape( const uno::Reference< drawing::XShape >& rxShape );
+ /** Creates and returns a new VBA implementation object for the passed shape.
+
+ @throws uno::RuntimeException
+ */
+ ::rtl::Reference< ScVbaSheetObjectBase > createVbaObject( const uno::Reference< drawing::XShape >& rxShape );
+ /** Creates and returns a new VBA implementation object for the passed shape in an Any.
+
+ @throws uno::RuntimeException
+ */
+ uno::Any createCollectionObject( const uno::Any& rSource );
+ /** Returns the VBA implementation object with the specified name.
+
+ @throws uno::RuntimeException
+ */
+ uno::Any getItemByStringIndex( const OUString& rIndex );
+
+ // XIndexAccess
+ virtual sal_Int32 SAL_CALL getCount() override;
+ virtual uno::Any SAL_CALL getByIndex( sal_Int32 nIndex ) override;
+
+ // XElementAccess
+ virtual uno::Type SAL_CALL getElementType() override;
+ virtual sal_Bool SAL_CALL hasElements() override;
+
+protected:
+ /** Derived classes return true, if the passed shape is supported by the instance. */
+ virtual bool implPickShape( const uno::Reference< drawing::XShape >& rxShape ) const = 0;
+ /** Derived classes create and return a new VBA implementation object for the passed shape.
+
+ @throws uno::RuntimeException
+ */
+ virtual rtl::Reference<ScVbaSheetObjectBase> implCreateVbaObject( const uno::Reference< drawing::XShape >& rxShape ) = 0;
+ /** Derived classes return the service name of the UNO shape. */
+ virtual OUString implGetShapeServiceName() const = 0;
+
+ /** Returns the shape name via 'Name' property of the UNO shape. May be overwritten.
+
+ @throws uno::RuntimeException
+ */
+ virtual OUString implGetShapeName( const uno::Reference< drawing::XShape >& rxShape ) const;
+ /** Is called when a new UNO shape has been created but not yet inserted into the drawing page.
+
+ @throws uno::RuntimeException
+ */
+ virtual void implOnShapeCreated( const uno::Reference< drawing::XShape >& rxShape );
+
+protected:
+ uno::Reference< XHelperInterface > mxParent;
+ uno::Reference< uno::XComponentContext > mxContext;
+ uno::Reference< frame::XModel > mxModel;
+ uno::Reference< lang::XMultiServiceFactory > mxFactory;
+ uno::Reference< drawing::XShapes > mxShapes;
+
+private:
+ typedef ::std::vector< uno::Reference< drawing::XShape > > ShapeVector;
+ const uno::Type maVbaType;
+ ShapeVector maShapes;
+};
+
+ScVbaObjectContainer::ScVbaObjectContainer(
+ const uno::Reference< XHelperInterface >& rxParent,
+ const uno::Reference< uno::XComponentContext >& rxContext,
+ const uno::Reference< frame::XModel >& rxModel,
+ const uno::Reference< sheet::XSpreadsheet >& rxSheet,
+ const uno::Type& rVbaType ) :
+ mxParent( rxParent ),
+ mxContext( rxContext ),
+ mxModel( rxModel, uno::UNO_SET_THROW ),
+ mxFactory( rxModel, uno::UNO_QUERY_THROW ),
+ maVbaType( rVbaType )
+{
+ uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupp( rxSheet, uno::UNO_QUERY_THROW );
+ mxShapes.set( xDrawPageSupp->getDrawPage(), uno::UNO_QUERY_THROW );
+}
+
+void ScVbaObjectContainer::collectShapes()
+{
+ maShapes.clear();
+ for( sal_Int32 nIndex = 0, nCount = mxShapes->getCount(); nIndex < nCount; ++nIndex )
+ {
+ uno::Reference< drawing::XShape > xShape( mxShapes->getByIndex( nIndex ), uno::UNO_QUERY_THROW );
+ if( implPickShape( xShape ) )
+ maShapes.push_back( xShape );
+ }
+}
+
+uno::Reference< drawing::XShape > ScVbaObjectContainer::createShape( const awt::Point& rPos, const awt::Size& rSize )
+{
+ uno::Reference< drawing::XShape > xShape( mxFactory->createInstance( implGetShapeServiceName() ), uno::UNO_QUERY_THROW );
+ xShape->setPosition( rPos );
+ xShape->setSize( rSize );
+ implOnShapeCreated( xShape );
+ return xShape;
+}
+
+sal_Int32 ScVbaObjectContainer::insertShape( const uno::Reference< drawing::XShape >& rxShape )
+{
+ mxShapes->add( rxShape );
+ maShapes.push_back( rxShape );
+ return mxShapes->getCount() - 1;
+}
+
+::rtl::Reference< ScVbaSheetObjectBase > ScVbaObjectContainer::createVbaObject(
+ const uno::Reference< drawing::XShape >& rxShape )
+{
+ return implCreateVbaObject( rxShape );
+}
+
+uno::Any ScVbaObjectContainer::createCollectionObject( const uno::Any& rSource )
+{
+ uno::Reference< drawing::XShape > xShape( rSource, uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XSheetObject > xSheetObject( implCreateVbaObject( xShape ) );
+ return uno::Any( xSheetObject );
+}
+
+uno::Any ScVbaObjectContainer::getItemByStringIndex( const OUString& rIndex )
+{
+ auto aIt = std::find_if(maShapes.begin(), maShapes.end(),
+ [&rIndex, this](const ShapeVector::value_type& rxShape) { return rIndex == implGetShapeName( rxShape ); });
+ if (aIt != maShapes.end())
+ return createCollectionObject( uno::Any( *aIt ) );
+ throw uno::RuntimeException();
+}
+
+// XIndexAccess
+
+sal_Int32 SAL_CALL ScVbaObjectContainer::getCount()
+{
+ return static_cast< sal_Int32 >( maShapes.size() );
+}
+
+uno::Any SAL_CALL ScVbaObjectContainer::getByIndex( sal_Int32 nIndex )
+{
+ if( (0 <= nIndex) && (nIndex < getCount()) )
+ return uno::Any( maShapes[ static_cast< size_t >( nIndex ) ] );
+ throw lang::IndexOutOfBoundsException();
+}
+
+// XElementAccess
+
+uno::Type SAL_CALL ScVbaObjectContainer::getElementType()
+{
+ return cppu::UnoType<drawing::XShape>::get();
+}
+
+sal_Bool SAL_CALL ScVbaObjectContainer::hasElements()
+{
+ return !maShapes.empty();
+}
+
+// private
+
+OUString ScVbaObjectContainer::implGetShapeName( const uno::Reference< drawing::XShape >& rxShape ) const
+{
+ uno::Reference< beans::XPropertySet > xPropSet( rxShape, uno::UNO_QUERY_THROW );
+ return xPropSet->getPropertyValue( "Name" ).get< OUString >();
+}
+
+void ScVbaObjectContainer::implOnShapeCreated( const uno::Reference< drawing::XShape >& /*rxShape*/ )
+{
+}
+
+namespace {
+
+class ScVbaObjectEnumeration : public SimpleEnumerationBase
+{
+public:
+ explicit ScVbaObjectEnumeration( const ScVbaObjectContainerRef& rxContainer );
+ virtual uno::Any createCollectionObject( const uno::Any& rSource ) override;
+
+private:
+ ScVbaObjectContainerRef mxContainer;
+};
+
+}
+
+ScVbaObjectEnumeration::ScVbaObjectEnumeration( const ScVbaObjectContainerRef& rxContainer ) :
+ SimpleEnumerationBase( rxContainer ),
+ mxContainer( rxContainer )
+{
+}
+
+uno::Any ScVbaObjectEnumeration::createCollectionObject( const uno::Any& rSource )
+{
+ return mxContainer->createCollectionObject( rSource );
+}
+
+ScVbaSheetObjectsBase::ScVbaSheetObjectsBase( const ScVbaObjectContainerRef& rxContainer ) :
+ ScVbaSheetObjects_BASE( rxContainer->getParent(), rxContainer->getContext(), rxContainer ),
+ mxContainer( rxContainer )
+{
+ mxContainer->collectShapes();
+}
+
+ScVbaSheetObjectsBase::~ScVbaSheetObjectsBase()
+{
+}
+
+void ScVbaSheetObjectsBase::collectShapes()
+{
+ mxContainer->collectShapes();
+}
+
+// XEnumerationAccess
+
+uno::Reference< container::XEnumeration > SAL_CALL ScVbaSheetObjectsBase::createEnumeration()
+{
+ return new ScVbaObjectEnumeration( mxContainer );
+}
+
+// XElementAccess
+
+uno::Type SAL_CALL ScVbaSheetObjectsBase::getElementType()
+{
+ return mxContainer->getVbaType();
+}
+
+// ScVbaCollectionBase
+
+uno::Any ScVbaSheetObjectsBase::createCollectionObject( const uno::Any& rSource )
+{
+ return mxContainer->createCollectionObject( rSource );
+}
+
+uno::Any ScVbaSheetObjectsBase::getItemByStringIndex( const OUString& rIndex )
+{
+ return mxContainer->getItemByStringIndex( rIndex );
+}
+
+// Graphic object containers supporting ooo.vba.excel.XGraphicObject
+
+ScVbaGraphicObjectsBase::ScVbaGraphicObjectsBase( const ScVbaObjectContainerRef& rxContainer ) :
+ ScVbaGraphicObjects_BASE( rxContainer )
+{
+}
+
+// XGraphicObjects
+
+uno::Any SAL_CALL ScVbaGraphicObjectsBase::Add( const uno::Any& rLeft, const uno::Any& rTop, const uno::Any& rWidth, const uno::Any& rHeight )
+{
+ /* Extract double values from passed Anys (the lclPointsToHmm() helper
+ function will throw a RuntimeException on any error), and convert from
+ points to 1/100 mm. */
+ awt::Point aPos( static_cast<sal_Int32>(lclPointsToHmm( rLeft )), static_cast<sal_Int32>(lclPointsToHmm( rTop )) );
+ awt::Size aSize( static_cast<sal_Int32>(lclPointsToHmm( rWidth )), static_cast<sal_Int32>(lclPointsToHmm( rHeight )) );
+ // TODO: translate coordinates for RTL sheets
+ if( (aPos.X < 0) || (aPos.Y < 0) || (aSize.Width <= 0) || (aSize.Height <= 0) )
+ throw uno::RuntimeException();
+
+ // create the UNO shape
+ uno::Reference< drawing::XShape > xShape( mxContainer->createShape( aPos, aSize ), uno::UNO_SET_THROW );
+ sal_Int32 nIndex = mxContainer->insertShape( xShape );
+
+ // create and return the VBA object
+ ::rtl::Reference< ScVbaSheetObjectBase > xVbaObject = mxContainer->createVbaObject( xShape );
+ xVbaObject->setDefaultProperties( nIndex );
+ return uno::Any( uno::Reference< excel::XSheetObject >( xVbaObject ) );
+}
+
+// Drawing controls
+
+namespace {
+
+class ScVbaControlContainer : public ScVbaObjectContainer
+{
+public:
+ /// @throws uno::RuntimeException
+ explicit ScVbaControlContainer(
+ const uno::Reference< XHelperInterface >& rxParent,
+ const uno::Reference< uno::XComponentContext >& rxContext,
+ const uno::Reference< frame::XModel >& rxModel,
+ const uno::Reference< sheet::XSpreadsheet >& rxSheet,
+ const uno::Type& rVbaType,
+ const OUString& rModelServiceName,
+ sal_Int16 /* css::form::FormComponentType */ eType );
+
+protected:
+ /// @throws uno::RuntimeException
+ uno::Reference< container::XIndexContainer > const & createForm();
+
+ virtual bool implPickShape( const uno::Reference< drawing::XShape >& rxShape ) const override;
+ virtual OUString implGetShapeServiceName() const override;
+ virtual bool implCheckProperties( const uno::Reference< beans::XPropertySet >& rxModelProps ) const;
+ virtual OUString implGetShapeName( const uno::Reference< drawing::XShape >& rxShape ) const override;
+ virtual void implOnShapeCreated( const uno::Reference< drawing::XShape >& rxShape ) override;
+
+protected:
+ uno::Reference< container::XIndexContainer > mxFormIC;
+ OUString maModelServiceName;
+ sal_Int16 /* css::form::FormComponentType */ meType;
+};
+
+}
+
+ScVbaControlContainer::ScVbaControlContainer(
+ const uno::Reference< XHelperInterface >& rxParent,
+ const uno::Reference< uno::XComponentContext >& rxContext,
+ const uno::Reference< frame::XModel >& rxModel,
+ const uno::Reference< sheet::XSpreadsheet >& rxSheet,
+ const uno::Type& rVbaType,
+ const OUString& rModelServiceName,
+ sal_Int16 /* css::form::FormComponentType */ eType ) :
+ ScVbaObjectContainer( rxParent, rxContext, rxModel, rxSheet, rVbaType ),
+ maModelServiceName( rModelServiceName ),
+ meType( eType )
+{
+}
+
+uno::Reference< container::XIndexContainer > const & ScVbaControlContainer::createForm()
+{
+ if( !mxFormIC.is() )
+ {
+ uno::Reference< form::XFormsSupplier > xFormsSupp( mxShapes, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XNameContainer > xFormsNC( xFormsSupp->getForms(), uno::UNO_SET_THROW );
+ OUString aFormName = "Standard";
+ if( xFormsNC->hasByName( aFormName ) )
+ {
+ mxFormIC.set( xFormsNC->getByName( aFormName ), uno::UNO_QUERY_THROW );
+ }
+ else
+ {
+ uno::Reference< form::XForm > xForm( mxFactory->createInstance( "com.sun.star.form.component.Form" ), uno::UNO_QUERY_THROW );
+ xFormsNC->insertByName( aFormName, uno::Any( xForm ) );
+ mxFormIC.set( xForm, uno::UNO_QUERY_THROW );
+ }
+ }
+ return mxFormIC;
+}
+
+bool ScVbaControlContainer::implPickShape( const uno::Reference< drawing::XShape >& rxShape ) const
+{
+ try
+ {
+ uno::Reference< drawing::XControlShape > xControlShape( rxShape, uno::UNO_QUERY_THROW );
+ uno::Reference< beans::XPropertySet > xModelProps( xControlShape->getControl(), uno::UNO_QUERY_THROW );
+ sal_Int16 nClassId = -1;
+ return lclGetProperty( nClassId, xModelProps, "ClassId" ) &&
+ (nClassId == meType) && implCheckProperties( xModelProps );
+ }
+ catch( uno::Exception& )
+ {
+ }
+ return false;
+}
+
+OUString ScVbaControlContainer::implGetShapeServiceName() const
+{
+ return "com.sun.star.drawing.ControlShape";
+}
+
+bool ScVbaControlContainer::implCheckProperties( const uno::Reference< beans::XPropertySet >& /*rxModelProps*/ ) const
+{
+ return true;
+}
+
+OUString ScVbaControlContainer::implGetShapeName( const uno::Reference< drawing::XShape >& rxShape ) const
+{
+ uno::Reference< drawing::XControlShape > xControlShape( rxShape, uno::UNO_QUERY_THROW );
+ return uno::Reference< container::XNamed >( xControlShape->getControl(), uno::UNO_QUERY_THROW )->getName();
+}
+
+void ScVbaControlContainer::implOnShapeCreated( const uno::Reference< drawing::XShape >& rxShape )
+{
+ // passed shape must be a control shape
+ uno::Reference< drawing::XControlShape > xControlShape( rxShape, uno::UNO_QUERY_THROW );
+
+ // create the UNO control model
+ uno::Reference< form::XFormComponent > xFormComponent( mxFactory->createInstance( maModelServiceName ), uno::UNO_QUERY_THROW );
+ uno::Reference< awt::XControlModel > xControlModel( xFormComponent, uno::UNO_QUERY_THROW );
+
+ // insert the control model into the form and the shape
+ createForm();
+ mxFormIC->insertByIndex( mxFormIC->getCount(), uno::Any( xFormComponent ) );
+ xControlShape->setControl( xControlModel );
+}
+
+// Push button
+
+namespace {
+
+class ScVbaButtonContainer : public ScVbaControlContainer
+{
+ bool mbOptionButtons;
+public:
+ /// @throws uno::RuntimeException
+ explicit ScVbaButtonContainer(
+ const uno::Reference< XHelperInterface >& rxParent,
+ const uno::Reference< uno::XComponentContext >& rxContext,
+ const uno::Reference< frame::XModel >& rxModel,
+ const uno::Reference< sheet::XSpreadsheet >& rxSheet,
+ bool bOptionButtons);
+
+protected:
+ virtual rtl::Reference<ScVbaSheetObjectBase> implCreateVbaObject( const uno::Reference< drawing::XShape >& rxShape ) override;
+ virtual bool implCheckProperties( const uno::Reference< beans::XPropertySet >& rxModelProps ) const override;
+};
+
+}
+
+ScVbaButtonContainer::ScVbaButtonContainer(
+ const uno::Reference< XHelperInterface >& rxParent,
+ const uno::Reference< uno::XComponentContext >& rxContext,
+ const uno::Reference< frame::XModel >& rxModel,
+ const uno::Reference< sheet::XSpreadsheet >& rxSheet,
+ bool bOptionButtons ) :
+ ScVbaControlContainer(
+ rxParent, rxContext, rxModel, rxSheet,
+ cppu::UnoType<excel::XButton>::get(),
+ ( bOptionButtons ?
+ OUString( "com.sun.star.form.component.RadioButton" ) :
+ OUString( "com.sun.star.form.component.CommandButton" ) ),
+ ( bOptionButtons ?
+ form::FormComponentType::RADIOBUTTON :
+ form::FormComponentType::COMMANDBUTTON) ),
+ mbOptionButtons(bOptionButtons)
+{
+}
+
+rtl::Reference<ScVbaSheetObjectBase> ScVbaButtonContainer::implCreateVbaObject( const uno::Reference< drawing::XShape >& rxShape )
+{
+ uno::Reference< drawing::XControlShape > xControlShape( rxShape, uno::UNO_QUERY_THROW );
+ return new ScVbaButton( mxParent, mxContext, mxModel, createForm(), xControlShape );
+}
+
+bool ScVbaButtonContainer::implCheckProperties( const uno::Reference< beans::XPropertySet >& rxModelProps ) const
+{
+ if (mbOptionButtons)
+ return true;
+
+ // do not insert toggle buttons into the 'Buttons' collection
+ bool bToggle = false;
+ return lclGetProperty( bToggle, rxModelProps, "Toggle" ) && !bToggle;
+}
+
+ScVbaButtons::ScVbaButtons(
+ const uno::Reference< XHelperInterface >& rxParent,
+ const uno::Reference< uno::XComponentContext >& rxContext,
+ const uno::Reference< frame::XModel >& rxModel,
+ const uno::Reference< sheet::XSpreadsheet >& rxSheet,
+ bool bOptionButtons) :
+ ScVbaGraphicObjectsBase( new ScVbaButtonContainer( rxParent, rxContext, rxModel, rxSheet, bOptionButtons ) )
+{
+}
+
+VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaButtons, "ooo.vba.excel.Buttons" )
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbasheetobjects.hxx b/sc/source/ui/vba/vbasheetobjects.hxx
new file mode 100644
index 000000000..38d2d1c8d
--- /dev/null
+++ b/sc/source/ui/vba/vbasheetobjects.hxx
@@ -0,0 +1,102 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <cppuhelper/implbase.hxx>
+#include <ooo/vba/excel/XGraphicObjects.hpp>
+#include <vbahelper/vbacollectionimpl.hxx>
+#include <rtl/ref.hxx>
+
+namespace com::sun::star {
+ namespace container { class XEnumeration; }
+ namespace frame { class XModel; }
+ namespace sheet { class XSpreadsheet; }
+}
+
+class ScVbaObjectContainer;
+typedef ::rtl::Reference< ScVbaObjectContainer > ScVbaObjectContainerRef;
+
+typedef CollTestImplHelper< ov::XCollection > ScVbaSheetObjects_BASE;
+
+/** Base class for collections containing a specific type of drawing object
+ embedded in a sheet (worksheet, chart sheet, or dialog sheet).
+ */
+class ScVbaSheetObjectsBase : public ScVbaSheetObjects_BASE
+{
+public:
+ /// @throws css::uno::RuntimeException
+ explicit ScVbaSheetObjectsBase( const ScVbaObjectContainerRef& rxContainer );
+ virtual ~ScVbaSheetObjectsBase() override;
+
+ /** Updates the collection by fetching all shapes from the draw page.
+
+ @throws css::uno::RuntimeException
+ */
+ void collectShapes();
+
+ // XEnumerationAccess
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+
+ // XElementAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+
+ // ScVbaCollectionBase
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& rSource ) override;
+ virtual css::uno::Any getItemByStringIndex( const OUString& rIndex ) override;
+
+protected:
+ ScVbaObjectContainerRef mxContainer;
+};
+
+typedef ::cppu::ImplInheritanceHelper< ScVbaSheetObjectsBase, ov::excel::XGraphicObjects > ScVbaGraphicObjects_BASE;
+
+/** Base class for collections containing a specific type of graphic object
+ from a sheet.
+ */
+class ScVbaGraphicObjectsBase : public ScVbaGraphicObjects_BASE
+{
+public:
+ /// @throws css::uno::RuntimeException
+ explicit ScVbaGraphicObjectsBase( const ScVbaObjectContainerRef& rxContainer );
+
+ // XGraphicObjects
+ virtual css::uno::Any SAL_CALL Add(
+ const css::uno::Any& rLeft,
+ const css::uno::Any& rTop,
+ const css::uno::Any& rWidth,
+ const css::uno::Any& rHeight ) override;
+};
+
+/** Collection containing all button controls from a sheet (not ActiveX controls). */
+class ScVbaButtons : public ScVbaGraphicObjectsBase
+{
+public:
+ /// @throws css::uno::RuntimeException
+ explicit ScVbaButtons(
+ const css::uno::Reference< ov::XHelperInterface >& rxParent,
+ const css::uno::Reference< css::uno::XComponentContext >& rxContext,
+ const css::uno::Reference< css::frame::XModel >& rxModel,
+ const css::uno::Reference< css::sheet::XSpreadsheet >& rxSheet,
+ bool bOptionButtons);
+
+ VBAHELPER_DECL_XHELPERINTERFACE
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbastyle.cxx b/sc/source/ui/vba/vbastyle.cxx
new file mode 100644
index 000000000..ae393804d
--- /dev/null
+++ b/sc/source/ui/vba/vbastyle.cxx
@@ -0,0 +1,183 @@
+/* -*- 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 "vbastyle.hxx"
+#include <basic/sberrors.hxx>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+constexpr OUStringLiteral DISPLAYNAME = u"DisplayName";
+
+uno::Reference< container::XNameAccess >
+ScVbaStyle::getStylesNameContainer( const uno::Reference< frame::XModel >& xModel )
+{
+ uno::Reference< style::XStyleFamiliesSupplier > xStyleSupplier( xModel, uno::UNO_QUERY_THROW);
+ uno::Reference< container::XNameAccess > xStylesAccess( xStyleSupplier->getStyleFamilies()->getByName("CellStyles"), uno::UNO_QUERY_THROW );
+ return xStylesAccess;
+}
+
+/// @throws script::BasicErrorException
+/// @throws uno::RuntimeException
+static uno::Reference< beans::XPropertySet >
+lcl_getStyleProps( const OUString& sStyleName, const uno::Reference< frame::XModel >& xModel )
+{
+
+ uno::Reference< beans::XPropertySet > xStyleProps( ScVbaStyle::getStylesNameContainer( xModel )->getByName( sStyleName ), uno::UNO_QUERY_THROW );
+ return xStyleProps;
+}
+
+void ScVbaStyle::initialise()
+{
+ if (!mxModel.is() )
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, u"XModel Interface could not be retrieved" );
+ uno::Reference< lang::XServiceInfo > xServiceInfo( mxPropertySet, uno::UNO_QUERY_THROW );
+ if ( !xServiceInfo->supportsService("com.sun.star.style.CellStyle") )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {} );
+ }
+ mxStyle.set( mxPropertySet, uno::UNO_QUERY_THROW );
+
+ uno::Reference< style::XStyleFamiliesSupplier > xStyleSupplier( mxModel, uno::UNO_QUERY_THROW );
+ mxStyleFamilyNameContainer.set( ScVbaStyle::getStylesNameContainer( mxModel ), uno::UNO_QUERY_THROW );
+
+}
+
+ScVbaStyle::ScVbaStyle( const uno::Reference< ov::XHelperInterface >& xParent,
+ const uno::Reference< uno::XComponentContext > & xContext,
+ const OUString& sStyleName, const uno::Reference< frame::XModel >& _xModel )
+ : ScVbaStyle_BASE( xParent, xContext, lcl_getStyleProps( sStyleName, _xModel ), _xModel, false )
+{
+ try
+ {
+ initialise();
+ }
+ catch (const uno::Exception& )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+}
+
+ScVbaStyle::ScVbaStyle( const uno::Reference< XHelperInterface >& xParent,
+ const uno::Reference< uno::XComponentContext > & xContext,
+ const uno::Reference< beans::XPropertySet >& _xPropertySet,
+ const uno::Reference< frame::XModel >& _xModel )
+ : ScVbaStyle_BASE( xParent, xContext, _xPropertySet, _xModel, false )
+{
+ try
+ {
+ initialise();
+ }
+ catch (const uno::Exception& )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+}
+
+sal_Bool SAL_CALL
+ScVbaStyle::BuiltIn()
+{
+ return !mxStyle->isUserDefined();
+
+}
+void SAL_CALL
+ScVbaStyle::setName( const OUString& Name )
+{
+ mxStyle->setName(Name);
+}
+
+OUString SAL_CALL
+ScVbaStyle::getName()
+{
+ return mxStyle->getName();
+}
+
+void SAL_CALL
+ScVbaStyle::setNameLocal( const OUString& NameLocal )
+{
+ try
+ {
+ mxPropertySet->setPropertyValue(DISPLAYNAME, uno::Any( NameLocal ) );
+ }
+ catch (const uno::Exception& e)
+ {
+ DebugHelper::basicexception(e);
+ }
+}
+
+OUString SAL_CALL
+ScVbaStyle::getNameLocal()
+{
+ OUString sName;
+ try
+ {
+ mxPropertySet->getPropertyValue(DISPLAYNAME) >>= sName;
+ }
+ catch (const uno::Exception& )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {} );
+ }
+ return sName;
+}
+
+void SAL_CALL
+ScVbaStyle::Delete()
+{
+ try
+ {
+ mxStyleFamilyNameContainer->removeByName(mxStyle->getName());
+ }
+ catch (const uno::Exception& )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+}
+
+void SAL_CALL
+ScVbaStyle::setMergeCells( const uno::Any& /*MergeCells*/ )
+{
+ DebugHelper::basicexception(ERRCODE_BASIC_NOT_IMPLEMENTED, {});
+}
+
+uno::Any SAL_CALL
+ScVbaStyle::getMergeCells( )
+{
+ DebugHelper::basicexception(ERRCODE_BASIC_NOT_IMPLEMENTED, {});
+ return uno::Any();
+}
+
+OUString
+ScVbaStyle::getServiceImplName()
+{
+ return "ScVbaStyle";
+}
+
+uno::Sequence< OUString >
+ScVbaStyle::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.XStyle"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbastyle.hxx b/sc/source/ui/vba/vbastyle.hxx
new file mode 100644
index 000000000..cc002ce6f
--- /dev/null
+++ b/sc/source/ui/vba/vbastyle.hxx
@@ -0,0 +1,62 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <ooo/vba/excel/XStyle.hpp>
+#include <com/sun/star/style/XStyle.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include "vbaformat.hxx"
+
+typedef ScVbaFormat< ov::excel::XStyle > ScVbaStyle_BASE;
+
+class ScVbaStyle final : public ScVbaStyle_BASE
+{
+ css::uno::Reference< css::style::XStyle > mxStyle;
+ css::uno::Reference< css::container::XNameContainer > mxStyleFamilyNameContainer;
+ /// @throws css::uno::RuntimeException
+ /// @throws css::script::BasicErrorException
+ void initialise();
+public:
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ ScVbaStyle( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const OUString& sStyleName, const css::uno::Reference< css::frame::XModel >& _xModel );
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ ScVbaStyle( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::beans::XPropertySet >& _xPropertySet, const css::uno::Reference< css::frame::XModel >& _xModel );
+ /// @throws css::uno::RuntimeException
+ static css::uno::Reference< css::container::XNameAccess > getStylesNameContainer( const css::uno::Reference< css::frame::XModel >& xModel );
+ virtual css::uno::Reference< ov::XHelperInterface > thisHelperIface() override { return this; };
+ // XStyle Methods
+ virtual sal_Bool SAL_CALL BuiltIn() override;
+ virtual void SAL_CALL setName( const OUString& Name ) override;
+ virtual OUString SAL_CALL getName() override;
+ virtual void SAL_CALL setNameLocal( const OUString& NameLocal ) override;
+ virtual OUString SAL_CALL getNameLocal() override;
+ virtual void SAL_CALL Delete() override;
+ // XFormat
+ virtual void SAL_CALL setMergeCells( const css::uno::Any& MergeCells ) override;
+ virtual css::uno::Any SAL_CALL getMergeCells( ) override;
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbastyles.cxx b/sc/source/ui/vba/vbastyles.cxx
new file mode 100644
index 000000000..c21adf064
--- /dev/null
+++ b/sc/source/ui/vba/vbastyles.cxx
@@ -0,0 +1,199 @@
+/* -*- 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 "vbastyles.hxx"
+#include "vbastyle.hxx"
+#include <basic/sberrors.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <ooo/vba/excel/XRange.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+static css::uno::Any
+lcl_createAPIStyleToVBAObject( const css::uno::Any& aObject, const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< frame::XModel >& xModel )
+{
+ uno::Reference< beans::XPropertySet > xStyleProps( aObject, uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XStyle > xStyle( new ScVbaStyle( xParent, xContext, xStyleProps, xModel ) );
+ return uno::Any( xStyle );
+}
+
+ScVbaStyles::ScVbaStyles( const uno::Reference< XHelperInterface >& xParent,
+ const uno::Reference< css::uno::XComponentContext > & xContext,
+ const uno::Reference< frame::XModel >& xModel )
+: ScVbaStyles_BASE( xParent,
+ xContext,
+ uno::Reference< container::XIndexAccess >( ScVbaStyle::getStylesNameContainer( xModel ), uno::UNO_QUERY_THROW ) ),
+ mxModel( xModel )
+{
+ try
+ {
+ mxMSF.set( mxModel, uno::UNO_QUERY_THROW );
+ mxNameContainerCellStyles.set( m_xNameAccess, uno::UNO_QUERY_THROW );
+ }
+ catch (uno::Exception& )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+}
+
+uno::Sequence< OUString >
+ScVbaStyles::getStyleNames()
+{
+ return mxNameContainerCellStyles->getElementNames();
+}
+
+uno::Any
+ScVbaStyles::createCollectionObject(const uno::Any& aObject)
+{
+ return lcl_createAPIStyleToVBAObject( aObject, mxParent, mxContext, mxModel );
+}
+
+uno::Type SAL_CALL
+ScVbaStyles::getElementType()
+{
+ return cppu::UnoType<excel::XStyle>::get();
+}
+
+namespace {
+
+class EnumWrapper : public EnumerationHelper_BASE
+{
+ uno::Reference<container::XIndexAccess > m_xIndexAccess;
+ uno::Reference<XHelperInterface > m_xParent;
+ uno::Reference<uno::XComponentContext > m_xContext;
+ uno::Reference<frame::XModel > m_xModel;
+
+ sal_Int32 nIndex;
+public:
+ EnumWrapper( const uno::Reference< container::XIndexAccess >& xIndexAccess, const uno::Reference<XHelperInterface >& xParent, const uno::Reference<uno::XComponentContext >& xContext, const uno::Reference<frame::XModel >& xModel ) : m_xIndexAccess( xIndexAccess ), m_xParent( xParent ), m_xContext( xContext ), m_xModel( xModel ), nIndex( 0 ) {}
+ virtual sal_Bool SAL_CALL hasMoreElements( ) override
+ {
+ return ( nIndex < m_xIndexAccess->getCount() );
+ }
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ try
+ {
+ if ( nIndex < m_xIndexAccess->getCount() )
+ return lcl_createAPIStyleToVBAObject( m_xIndexAccess->getByIndex( nIndex++ ), m_xParent, m_xContext, m_xModel );
+ }
+ catch (const container::NoSuchElementException&)
+ {
+ throw;
+ }
+ catch (const lang::WrappedTargetException&)
+ {
+ throw;
+ }
+ catch (const uno::RuntimeException&)
+ {
+ throw;
+ }
+ catch (const uno::Exception& e)
+ {
+ css::uno::Any a(cppu::getCaughtException());
+ throw css::lang::WrappedTargetException(
+ "wrapped Exception " + e.Message,
+ css::uno::Reference<css::uno::XInterface>(), a);
+ }
+ throw container::NoSuchElementException();
+ }
+};
+
+}
+
+uno::Reference< container::XEnumeration > SAL_CALL
+ScVbaStyles::createEnumeration()
+{
+ return new EnumWrapper( m_xIndexAccess, mxParent, mxContext, mxModel );
+}
+
+uno::Reference< excel::XStyle > SAL_CALL
+ScVbaStyles::Add( const OUString& _sName, const uno::Any& _aBasedOn )
+{
+ uno::Reference< excel::XStyle > aRet;
+ try
+ {
+ OUString sParentCellStyleName("Default");
+ if ( _aBasedOn.hasValue() )
+ {
+ uno::Reference< excel::XRange > oRange;
+ if ( _aBasedOn >>= oRange)
+ {
+ uno::Reference< excel::XStyle > oStyle( oRange->getStyle(), uno::UNO_QUERY_THROW );
+ sParentCellStyleName = oStyle->getName();
+ }
+ else
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_BAD_ARGUMENT, {});
+ }
+ }
+
+ uno::Reference< style::XStyle > xStyle( mxMSF->createInstance("com.sun.star.style.CellStyle"), uno::UNO_QUERY_THROW );
+
+ if (!mxNameContainerCellStyles->hasByName(_sName))
+ {
+ mxNameContainerCellStyles->insertByName(_sName, uno::Any( xStyle) );
+ }
+ if (sParentCellStyleName != "Default")
+ {
+ xStyle->setParentStyle( sParentCellStyleName );
+ }
+ aRet.set( Item( uno::Any( _sName ), uno::Any() ), uno::UNO_QUERY_THROW );
+ }
+ catch (const uno::Exception&)
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+ return aRet;
+}
+
+void
+ScVbaStyles::Delete(const OUString& _sStyleName)
+{
+ try
+ {
+ if (mxNameContainerCellStyles->hasByName( _sStyleName ) )
+ mxNameContainerCellStyles->removeByName( _sStyleName );
+ }
+ catch (const uno::Exception&)
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+}
+
+OUString
+ScVbaStyles::getServiceImplName()
+{
+ return "ScVbaStyles";
+}
+
+uno::Sequence< OUString >
+ScVbaStyles::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.XStyles"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbastyles.hxx b/sc/source/ui/vba/vbastyles.hxx
new file mode 100644
index 000000000..78990bca9
--- /dev/null
+++ b/sc/source/ui/vba/vbastyles.hxx
@@ -0,0 +1,50 @@
+/* -*- 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 .
+ */
+#pragma once
+#include <ooo/vba/excel/XStyles.hpp>
+#include <vbahelper/vbacollectionimpl.hxx>
+
+namespace com::sun::star::lang { class XMultiServiceFactory; }
+namespace com::sun::star::container { class XNameContainer; }
+
+typedef CollTestImplHelper< ov::excel::XStyles > ScVbaStyles_BASE;
+class ScVbaStyles: public ScVbaStyles_BASE
+{
+ css::uno::Reference< css::frame::XModel > mxModel;
+ css::uno::Reference< css::lang::XMultiServiceFactory > mxMSF;
+ css::uno::Reference< css::container::XNameContainer > mxNameContainerCellStyles;
+public:
+ /// @throws css::script::BasicErrorException
+ ScVbaStyles( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::frame::XModel >& xModel );
+ /// @throws css::uno::RuntimeException
+ css::uno::Sequence< OUString > getStyleNames();
+ /// @throws css::script::BasicErrorException
+ void Delete(const OUString& _sStyleName);
+ // XStyles
+ virtual css::uno::Reference< ov::excel::XStyle > SAL_CALL Add( const OUString& Name, const css::uno::Any& BasedOn ) override;
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+ virtual css::uno::Any createCollectionObject(const css::uno::Any&) override;
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbatextboxshape.cxx b/sc/source/ui/vba/vbatextboxshape.cxx
new file mode 100644
index 000000000..66a85e49e
--- /dev/null
+++ b/sc/source/ui/vba/vbatextboxshape.cxx
@@ -0,0 +1,60 @@
+/* -*- 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 "excelvbahelper.hxx"
+#include "vbatextboxshape.hxx"
+#include "vbacharacters.hxx"
+#include <com/sun/star/text/XSimpleText.hpp>
+#include <docsh.hxx>
+
+using namespace com::sun::star;
+using namespace ooo::vba;
+
+ScVbaTextBoxShape::ScVbaTextBoxShape( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< drawing::XShape >& xShape, const uno::Reference< drawing::XShapes >& xShapes, const uno::Reference< frame::XModel >& xModel ) : TextBoxShapeImpl_BASE( uno::Reference< XHelperInterface >(), xContext, xShape, xShapes, xModel, ScVbaShape::getType( xShape ) )
+{
+ m_xTextRange.set( xShape , uno::UNO_QUERY_THROW );
+}
+
+OUString SAL_CALL
+ScVbaTextBoxShape::getText()
+{
+ return m_xTextRange->getString();
+}
+
+void SAL_CALL
+ScVbaTextBoxShape::setText( const OUString& _text )
+{
+ m_xTextRange->setString( _text );
+}
+
+uno::Reference< excel::XCharacters > SAL_CALL
+ScVbaTextBoxShape::characters( const uno::Any& Start, const uno::Any& Length )
+{
+ ScDocShell* pDocShell = excel::getDocShell( m_xModel );
+ ScDocument* pDoc = pDocShell ? &pDocShell->GetDocument() : nullptr;
+
+ if ( !pDoc )
+ throw uno::RuntimeException("Failed to access document from shell" );
+ uno::Reference< text::XSimpleText > xSimple( m_xTextRange, uno::UNO_QUERY_THROW );
+
+ ScVbaPalette aPalette( pDoc->GetDocumentShell() );
+ return new ScVbaCharacters( this, mxContext, aPalette, xSimple, Start, Length, true );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbatextboxshape.hxx b/sc/source/ui/vba/vbatextboxshape.hxx
new file mode 100644
index 000000000..c97fca8d8
--- /dev/null
+++ b/sc/source/ui/vba/vbatextboxshape.hxx
@@ -0,0 +1,39 @@
+/* -*- 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 .
+ */
+#pragma once
+#include <cppuhelper/implbase.hxx>
+#include <com/sun/star/text/XTextRange.hpp>
+#include <ooo/vba/msforms/XTextBoxShape.hpp>
+#include <vbahelper/vbashape.hxx>
+
+typedef cppu::ImplInheritanceHelper< ScVbaShape, ov::msforms::XTextBoxShape > TextBoxShapeImpl_BASE;
+
+class ScVbaTextBoxShape : public TextBoxShapeImpl_BASE
+{
+ css::uno::Reference< css::text::XTextRange > m_xTextRange;
+public:
+ ScVbaTextBoxShape( const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::drawing::XShape >& xShape, const css::uno::Reference< css::drawing::XShapes >& xShapes, const css::uno::Reference< css::frame::XModel >& xModel );
+
+ // Attributes
+ virtual OUString SAL_CALL getText() override;
+ virtual void SAL_CALL setText( const OUString& _text ) override;
+ virtual css::uno::Reference< ov::excel::XCharacters > SAL_CALL characters( const css::uno::Any& Start, const css::uno::Any& Length ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbatextframe.cxx b/sc/source/ui/vba/vbatextframe.cxx
new file mode 100644
index 000000000..9f921a8fa
--- /dev/null
+++ b/sc/source/ui/vba/vbatextframe.cxx
@@ -0,0 +1,67 @@
+/* -*- 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/drawing/XShape.hpp>
+#include <sfx2/objsh.hxx>
+#include "vbatextframe.hxx"
+#include "vbacharacters.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+ScVbaTextFrame::ScVbaTextFrame( uno::Sequence< uno::Any> const & args, uno::Reference< uno::XComponentContext> const & xContext ) : ScVbaTextFrame_BASE( getXSomethingFromArgs< XHelperInterface >( args, 0 ), xContext, getXSomethingFromArgs< drawing::XShape >( args, 1, false ) )
+{
+}
+
+// Methods
+uno::Any SAL_CALL
+ScVbaTextFrame::Characters()
+{
+ uno::Reference< text::XSimpleText > xSimpleText( m_xShape, uno::UNO_QUERY_THROW );
+ ScVbaPalette aPalette( SfxObjectShell::Current() );
+ uno::Any aStart( sal_Int32( 1 ) );
+ uno::Any aLength(sal_Int32( -1 ) );
+ return uno::Any( uno::Reference< ov::excel::XCharacters >( new ScVbaCharacters( this, mxContext, aPalette, xSimpleText, aStart, aLength, true ) ) );
+}
+
+OUString
+ScVbaTextFrame::getServiceImplName()
+{
+ return "ScVbaTextFrame";
+}
+
+uno::Sequence< OUString >
+ScVbaTextFrame::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.TextFrame"
+ };
+ return aServiceNames;
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
+ScVbaTextFrame_get_implementation(
+ css::uno::XComponentContext *context,
+ css::uno::Sequence<css::uno::Any> const &arguments)
+{
+ return cppu::acquire(new ScVbaTextFrame(arguments, context));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbatextframe.hxx b/sc/source/ui/vba/vbatextframe.hxx
new file mode 100644
index 000000000..eb7a59a93
--- /dev/null
+++ b/sc/source/ui/vba/vbatextframe.hxx
@@ -0,0 +1,40 @@
+/* -*- 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 .
+ */
+#pragma once
+#include <cppuhelper/implbase.hxx>
+#include <ooo/vba/excel/XTextFrame.hpp>
+#include <vbahelper/vbatextframe.hxx>
+
+//typedef InheritedHelperInterfaceWeakImpl< ov::excel::XTextFrame > ScVbaTextFrame_BASE;
+typedef cppu::ImplInheritanceHelper<VbaTextFrame, ov::excel::XTextFrame> ScVbaTextFrame_BASE;
+
+class ScVbaTextFrame : public ScVbaTextFrame_BASE
+{
+public:
+ /// @throws css::lang::IllegalArgumentException
+ ScVbaTextFrame(css::uno::Sequence<css::uno::Any> const& aArgs,
+ css::uno::Reference<css::uno::XComponentContext> const& xContext);
+ // Methods
+ virtual css::uno::Any SAL_CALL Characters() override;
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbatitle.hxx b/sc/source/ui/vba/vbatitle.hxx
new file mode 100644
index 000000000..550be0060
--- /dev/null
+++ b/sc/source/ui/vba/vbatitle.hxx
@@ -0,0 +1,141 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <vbahelper/vbahelperinterface.hxx>
+#include "vbainterior.hxx"
+#include "vbafont.hxx"
+#include "vbapalette.hxx"
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/script/BasicErrorException.hpp>
+#include <basic/sberrors.hxx>
+#include <memory>
+
+template< typename... Ifc >
+class TitleImpl : public InheritedHelperInterfaceImpl< Ifc... >
+{
+typedef InheritedHelperInterfaceImpl< Ifc... > BaseClass;
+
+ css::uno::Reference< css::drawing::XShape > xTitleShape;
+ css::uno::Reference< css::beans::XPropertySet > xShapePropertySet;
+ std::unique_ptr<ov::ShapeHelper> oShapeHelper;
+ ScVbaPalette m_Palette;
+public:
+ TitleImpl( const css::uno::Reference< ov::XHelperInterface >& xParent,
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ const css::uno::Reference< css::drawing::XShape >& _xTitleShape )
+ : BaseClass( xParent, xContext ), xTitleShape( _xTitleShape ), m_Palette(nullptr)
+ {
+ xShapePropertySet.set( xTitleShape, css::uno::UNO_QUERY_THROW );
+ oShapeHelper.reset( new ov::ShapeHelper(xTitleShape) );
+ }
+ css::uno::Reference< ov::excel::XInterior > SAL_CALL Interior( ) override
+ {
+ // #TODO find out what the proper parent should be
+ // leaving as set by the helperapi for the moment
+ // #TODO we really need the ScDocument to pass to ScVbaInterior
+ // otherwise attempts to access the palette will fail
+ return new ScVbaInterior( BaseClass::mxParent, BaseClass::mxContext, xShapePropertySet );
+ }
+ css::uno::Reference< ov::excel::XFont > SAL_CALL Font( ) override
+ {
+ // #TODO find out what the proper parent should be
+ // leaving as set by the helperapi for the moment
+ return new ScVbaFont( BaseClass::mxParent, BaseClass::mxContext, m_Palette, xShapePropertySet );
+
+ }
+ void SAL_CALL setText( const OUString& Text ) override
+ {
+ try
+ {
+ xShapePropertySet->setPropertyValue("String", css::uno::Any( Text ));
+ }
+ catch ( css::uno::Exception& )
+ {
+ throw css::script::BasicErrorException( OUString(), css::uno::Reference< css::uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
+ }
+ }
+ OUString SAL_CALL getText( ) override
+ {
+ OUString sText;
+ try
+ {
+ xShapePropertySet->getPropertyValue("String") >>= sText;
+ }
+ catch ( css::uno::Exception& )
+ {
+ throw css::script::BasicErrorException( OUString(), css::uno::Reference< css::uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
+ }
+ return sText;
+ }
+
+ void SAL_CALL setTop( double Top ) override
+ {
+ oShapeHelper->setTop( Top );
+ }
+ double SAL_CALL getTop( ) override
+ {
+ return oShapeHelper->getTop();
+ }
+ void SAL_CALL setLeft( double Left ) override
+ {
+ oShapeHelper->setLeft( Left );
+ }
+ double SAL_CALL getLeft( ) override
+ {
+ return oShapeHelper->getLeft();
+ }
+ void SAL_CALL setOrientation( ::sal_Int32 _nOrientation ) override
+ {
+ try
+ {
+ xShapePropertySet->setPropertyValue("TextRotation", css::uno::Any(_nOrientation*100));
+ }
+ catch (css::uno::Exception& )
+ {
+ throw css::script::BasicErrorException( OUString(), css::uno::Reference< css::uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
+ }
+ }
+ ::sal_Int32 SAL_CALL getOrientation( ) override
+ {
+ sal_Int32 nSOOrientation = 0;
+ try
+ {
+ xShapePropertySet->getPropertyValue("TextRotation") >>= nSOOrientation;
+ }
+ catch (css::uno::Exception& )
+ {
+ throw css::script::BasicErrorException( OUString(), css::uno::Reference< css::uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
+ }
+ return static_cast< sal_Int32 >(nSOOrientation / 100) ;
+ }
+// XHelperInterface
+ OUString getServiceImplName() override
+ {
+ return "TitleImpl";
+ }
+ css::uno::Sequence< OUString > getServiceNames() override
+ {
+ static const css::uno::Sequence< OUString > aServiceNames{ "ooo.vba.excel.XTitle" };
+ return aServiceNames;
+ }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbavalidation.cxx b/sc/source/ui/vba/vbavalidation.cxx
new file mode 100644
index 000000000..a30b43fe7
--- /dev/null
+++ b/sc/source/ui/vba/vbavalidation.cxx
@@ -0,0 +1,382 @@
+/* -*- 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 "vbavalidation.hxx"
+#include "vbaformatcondition.hxx"
+#include <com/sun/star/sheet/XSheetCondition.hpp>
+#include <com/sun/star/sheet/ValidationType.hpp>
+#include <com/sun/star/sheet/ValidationAlertStyle.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <ooo/vba/excel/XlDVType.hpp>
+#include <ooo/vba/excel/XlDVAlertStyle.hpp>
+
+#include <unonames.hxx>
+#include <rangelst.hxx>
+#include "excelvbahelper.hxx"
+#include "vbarange.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+static void
+lcl_setValidationProps( const uno::Reference< table::XCellRange >& xRange, const uno::Reference< beans::XPropertySet >& xProps )
+{
+ uno::Reference< beans::XPropertySet > xRangeProps( xRange, uno::UNO_QUERY_THROW );
+ xRangeProps->setPropertyValue( SC_UNONAME_VALIDAT , uno::Any( xProps ) );
+}
+
+static uno::Reference< beans::XPropertySet >
+lcl_getValidationProps( const uno::Reference< table::XCellRange >& xRange )
+{
+ uno::Reference< beans::XPropertySet > xProps( xRange, uno::UNO_QUERY_THROW );
+ uno::Reference< beans::XPropertySet > xValProps;
+ xValProps.set( xProps->getPropertyValue( SC_UNONAME_VALIDAT ), uno::UNO_QUERY_THROW );
+ return xValProps;
+}
+
+sal_Bool SAL_CALL
+ScVbaValidation::getIgnoreBlank()
+{
+ uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps( m_xRange ) );
+ bool bBlank = false;
+ xProps->getPropertyValue( SC_UNONAME_IGNOREBL ) >>= bBlank;
+ return bBlank;
+}
+
+void SAL_CALL
+ScVbaValidation::setIgnoreBlank( sal_Bool _ignoreblank )
+{
+ uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps( m_xRange ) );
+ xProps->setPropertyValue( SC_UNONAME_IGNOREBL, uno::Any( _ignoreblank ) );
+ lcl_setValidationProps( m_xRange, xProps );
+}
+
+sal_Bool SAL_CALL
+ScVbaValidation::getInCellDropdown()
+{
+ uno::Reference< beans::XPropertySet > xProps = lcl_getValidationProps( m_xRange );
+ sal_Int32 nShowList = 0;
+ xProps->getPropertyValue( SC_UNONAME_SHOWLIST ) >>= nShowList;
+ return nShowList != 0;
+}
+
+void SAL_CALL
+ScVbaValidation::setInCellDropdown( sal_Bool _incelldropdown )
+{
+ sal_Int32 nDropDown = 0;
+ if ( _incelldropdown )
+ nDropDown = 1;
+ uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps(m_xRange) );
+ xProps->setPropertyValue( SC_UNONAME_SHOWLIST, uno::Any( nDropDown ) );
+ lcl_setValidationProps( m_xRange, xProps );
+}
+
+sal_Bool SAL_CALL
+ScVbaValidation::getShowInput()
+{
+ uno::Reference< beans::XPropertySet > xProps = lcl_getValidationProps( m_xRange );
+ bool bShowInput = false;
+ xProps->getPropertyValue( SC_UNONAME_SHOWINP ) >>= bShowInput;
+ return bShowInput;
+}
+
+void SAL_CALL
+ScVbaValidation:: setShowInput( sal_Bool _showinput )
+{
+ uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps(m_xRange) );
+ xProps->setPropertyValue( SC_UNONAME_IGNOREBL, uno::Any( _showinput ) );
+ lcl_setValidationProps( m_xRange, xProps );
+}
+
+sal_Bool SAL_CALL
+ScVbaValidation::getShowError()
+{
+ uno::Reference< beans::XPropertySet > xProps = lcl_getValidationProps( m_xRange );
+ bool bShowError = false;
+ xProps->getPropertyValue( SC_UNONAME_SHOWERR ) >>= bShowError;
+ return bShowError;
+}
+
+void SAL_CALL
+ScVbaValidation::setShowError( sal_Bool _showerror )
+{
+ uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps( m_xRange ) );
+ xProps->setPropertyValue( SC_UNONAME_SHOWERR, uno::Any( _showerror ) );
+ lcl_setValidationProps( m_xRange, xProps );
+}
+
+OUString SAL_CALL
+ScVbaValidation::getErrorTitle()
+{
+ uno::Reference< beans::XPropertySet > xProps = lcl_getValidationProps( m_xRange );
+ OUString sErrorTitle;
+ xProps->getPropertyValue( SC_UNONAME_ERRTITLE ) >>= sErrorTitle;
+ return sErrorTitle;
+}
+
+void
+ScVbaValidation::setErrorTitle( const OUString& _errormessage )
+{
+ uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps( m_xRange ) );
+ xProps->setPropertyValue( SC_UNONAME_ERRTITLE, uno::Any( _errormessage ) );
+ lcl_setValidationProps( m_xRange, xProps );
+}
+
+OUString SAL_CALL
+ScVbaValidation::getInputMessage()
+{
+ uno::Reference< beans::XPropertySet > xProps = lcl_getValidationProps( m_xRange );
+ OUString sMsg;
+ xProps->getPropertyValue( SC_UNONAME_INPMESS ) >>= sMsg;
+ return sMsg;
+}
+
+void SAL_CALL
+ScVbaValidation::setInputMessage( const OUString& _inputmessage )
+{
+ uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps( m_xRange ) );
+ xProps->setPropertyValue( SC_UNONAME_INPMESS, uno::Any( _inputmessage ) );
+ lcl_setValidationProps( m_xRange, xProps );
+}
+
+OUString SAL_CALL
+ScVbaValidation::getInputTitle()
+{
+ uno::Reference< beans::XPropertySet > xProps = lcl_getValidationProps( m_xRange );
+ OUString sString;
+ xProps->getPropertyValue( SC_UNONAME_INPTITLE ) >>= sString;
+ return sString;
+}
+
+void SAL_CALL
+ScVbaValidation::setInputTitle( const OUString& _inputtitle )
+{
+ uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps( m_xRange ) );
+ xProps->setPropertyValue( SC_UNONAME_INPTITLE, uno::Any( _inputtitle ) );
+ lcl_setValidationProps( m_xRange, xProps );
+}
+
+OUString SAL_CALL
+ScVbaValidation::getErrorMessage()
+{
+ uno::Reference< beans::XPropertySet > xProps = lcl_getValidationProps( m_xRange );
+ OUString sString;
+ xProps->getPropertyValue( SC_UNONAME_ERRMESS ) >>= sString;
+ return sString;
+}
+
+void SAL_CALL
+ScVbaValidation::setErrorMessage( const OUString& _errormessage )
+{
+ uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps( m_xRange ) );
+ xProps->setPropertyValue( SC_UNONAME_ERRMESS, uno::Any( _errormessage ) );
+ lcl_setValidationProps( m_xRange, xProps );
+}
+
+void SAL_CALL
+ScVbaValidation::Delete( )
+{
+ OUString sBlank;
+ uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps( m_xRange ) );
+ uno::Reference< sheet::XSheetCondition > xCond( xProps, uno::UNO_QUERY_THROW );
+ xProps->setPropertyValue( SC_UNONAME_IGNOREBL, uno::Any( true ) );
+ xProps->setPropertyValue( SC_UNONAME_SHOWINP, uno::Any( true ) );
+ xProps->setPropertyValue( SC_UNONAME_SHOWERR, uno::Any( true ) );
+ xProps->setPropertyValue( SC_UNONAME_ERRTITLE, uno::Any( sBlank ) );
+ xProps->setPropertyValue( SC_UNONAME_INPMESS, uno::Any( sBlank) );
+ xProps->setPropertyValue( SC_UNONAME_ERRALSTY, uno::Any( sheet::ValidationAlertStyle_STOP) );
+ xProps->setPropertyValue( SC_UNONAME_TYPE, uno::Any( sheet::ValidationType_ANY ) );
+ xCond->setFormula1( sBlank );
+ xCond->setFormula2( sBlank );
+ xCond->setOperator( sheet::ConditionOperator_NONE );
+
+ lcl_setValidationProps( m_xRange, xProps );
+}
+
+// Fix the defect that validation cannot work when the input should be limited between a lower bound and an upper bound
+void SAL_CALL
+ScVbaValidation::Add( const uno::Any& Type, const uno::Any& AlertStyle, const uno::Any& Operator, const uno::Any& Formula1, const uno::Any& Formula2 )
+{
+ uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps( m_xRange ) );
+ uno::Reference< sheet::XSheetCondition > xCond( xProps, uno::UNO_QUERY_THROW );
+
+ sheet::ValidationType nValType = sheet::ValidationType_ANY;
+ xProps->getPropertyValue( SC_UNONAME_TYPE ) >>= nValType;
+ if ( nValType != sheet::ValidationType_ANY )
+ throw uno::RuntimeException("validation object already exists" );
+ sal_Int32 nType = -1;
+ if ( !Type.hasValue() || !( Type >>= nType ) )
+ throw uno::RuntimeException("missing required param" );
+
+ Delete(); // set up defaults
+ OUString sFormula1;
+ Formula1 >>= sFormula1;
+ OUString sFormula2;
+ Formula2 >>= sFormula2;
+ switch ( nType )
+ {
+ case excel::XlDVType::xlValidateList:
+ {
+ // for validate list
+ // at least formula1 is required
+ if ( !Formula1.hasValue() )
+ throw uno::RuntimeException("missing param" );
+ nValType = sheet::ValidationType_LIST;
+ xProps->setPropertyValue( SC_UNONAME_TYPE, uno::Any(nValType ));
+ // #TODO validate required params
+ // #TODO need to correct the ';' delimited formula on get/set
+ break;
+ }
+ case excel::XlDVType::xlValidateWholeNumber:
+ nValType = sheet::ValidationType_WHOLE;
+ xProps->setPropertyValue( SC_UNONAME_TYPE, uno::Any(nValType ));
+ break;
+ default:
+ throw uno::RuntimeException("unsupported operation..." );
+ }
+
+ sheet::ValidationAlertStyle eStyle = sheet::ValidationAlertStyle_STOP;
+ sal_Int32 nVbaAlertStyle = excel::XlDVAlertStyle::xlValidAlertStop;
+ if ( AlertStyle.hasValue() && ( AlertStyle >>= nVbaAlertStyle ) )
+ {
+ switch( nVbaAlertStyle )
+ {
+ case excel::XlDVAlertStyle::xlValidAlertStop:
+ // yes I know it's already defaulted but safer to assume
+ // someone probably could change the code above
+ eStyle = sheet::ValidationAlertStyle_STOP;
+ break;
+ case excel::XlDVAlertStyle::xlValidAlertWarning:
+ eStyle = sheet::ValidationAlertStyle_WARNING;
+ break;
+ case excel::XlDVAlertStyle::xlValidAlertInformation:
+ eStyle = sheet::ValidationAlertStyle_INFO;
+ break;
+ default:
+ throw uno::RuntimeException("bad param..." );
+
+ }
+ }
+
+ xProps->setPropertyValue( SC_UNONAME_ERRALSTY, uno::Any( eStyle ) );
+
+ // i#108860: fix the defect that validation cannot work when the input
+ // should be limited between a lower bound and an upper bound
+ if ( Operator.hasValue() )
+ {
+ css::sheet::ConditionOperator conOperator = ScVbaFormatCondition::retrieveAPIOperator( Operator );
+ xCond->setOperator( conOperator );
+ }
+
+ if ( !sFormula1.isEmpty() )
+ xCond->setFormula1( sFormula1 );
+ if ( !sFormula2.isEmpty() )
+ xCond->setFormula2( sFormula2 );
+
+ lcl_setValidationProps( m_xRange, xProps );
+}
+
+OUString SAL_CALL
+ScVbaValidation::getFormula1()
+{
+ uno::Reference< sheet::XSheetCondition > xCond( lcl_getValidationProps( m_xRange ), uno::UNO_QUERY_THROW );
+ OUString sString = xCond->getFormula1();
+
+ ScRefFlags nFlags = ScRefFlags::ZERO;
+ ScRangeList aCellRanges;
+
+ ScDocShell* pDocSh = excel::GetDocShellFromRange( m_xRange );
+ // in calc validation formula is either a range or formula
+ // that results in range.
+ // In VBA both formula and address can have a leading '='
+ // in result of getFormula1, however it *seems* that a named range or
+ // real formula has to (or is expected to) have the '='
+ if ( pDocSh && !ScVbaRange::getCellRangesForAddress( nFlags, sString, pDocSh, aCellRanges, formula::FormulaGrammar::CONV_XL_A1, 0 ) )
+ sString = "=" + sString;
+ return sString;
+}
+
+OUString SAL_CALL
+ScVbaValidation::getFormula2()
+{
+ uno::Reference< sheet::XSheetCondition > xCond( lcl_getValidationProps( m_xRange ), uno::UNO_QUERY_THROW );
+ return xCond->getFormula2();
+}
+
+sal_Int32 SAL_CALL
+ScVbaValidation::getType()
+{
+ uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps( m_xRange ) );
+ sheet::ValidationType nValType = sheet::ValidationType_ANY;
+ xProps->getPropertyValue( SC_UNONAME_TYPE ) >>= nValType;
+ sal_Int32 nExcelType = excel::XlDVType::xlValidateList; // pick a default
+ if ( xProps.is() )
+ {
+ switch ( nValType )
+ {
+ case sheet::ValidationType_LIST:
+ nExcelType = excel::XlDVType::xlValidateList;
+ break;
+ case sheet::ValidationType_ANY: // not ANY not really a great match for anything I fear:-(
+ nExcelType = excel::XlDVType::xlValidateInputOnly;
+ break;
+ case sheet::ValidationType_CUSTOM:
+ nExcelType = excel::XlDVType::xlValidateCustom;
+ break;
+ case sheet::ValidationType_WHOLE:
+ nExcelType = excel::XlDVType::xlValidateWholeNumber;
+ break;
+ case sheet::ValidationType_DECIMAL:
+ nExcelType = excel::XlDVType::xlValidateDecimal;
+ break;
+ case sheet::ValidationType_DATE:
+ nExcelType = excel::XlDVType::xlValidateDate;
+ break;
+ case sheet::ValidationType_TIME:
+ nExcelType = excel::XlDVType::xlValidateTime;
+ break;
+ case sheet::ValidationType_TEXT_LEN:
+ nExcelType = excel::XlDVType::xlValidateTextLength;
+ break;
+ case sheet::ValidationType::ValidationType_MAKE_FIXED_SIZE:
+ default:
+ break;
+ }
+ }
+ return nExcelType;
+}
+
+OUString
+ScVbaValidation::getServiceImplName()
+{
+ return "ScVbaValidation";
+}
+
+uno::Sequence< OUString >
+ScVbaValidation::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.Validation"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbavalidation.hxx b/sc/source/ui/vba/vbavalidation.hxx
new file mode 100644
index 000000000..ab16c0533
--- /dev/null
+++ b/sc/source/ui/vba/vbavalidation.hxx
@@ -0,0 +1,64 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <ooo/vba/excel/XValidation.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+
+namespace com::sun::star::table { class XCellRange; }
+namespace com::sun::star::uno { class XComponentContext; }
+
+typedef InheritedHelperInterfaceWeakImpl<ov::excel::XValidation > ValidationImpl_BASE;
+
+class ScVbaValidation : public ValidationImpl_BASE
+{
+ css::uno::Reference< css::table::XCellRange > m_xRange;
+
+public:
+ ScVbaValidation( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::table::XCellRange >& xRange ) : ValidationImpl_BASE( xParent, xContext ), m_xRange( xRange) {}
+ // Attributes
+ virtual sal_Bool SAL_CALL getIgnoreBlank() override;
+ virtual void SAL_CALL setIgnoreBlank( sal_Bool _ignoreblank ) override;
+ virtual sal_Bool SAL_CALL getInCellDropdown() override;
+ virtual void SAL_CALL setInCellDropdown( sal_Bool _incelldropdown ) override;
+ virtual sal_Bool SAL_CALL getShowInput() override;
+ virtual void SAL_CALL setShowInput( sal_Bool _showinput ) override;
+ virtual sal_Bool SAL_CALL getShowError() override;
+ virtual void SAL_CALL setShowError( sal_Bool _showerror ) override;
+ virtual OUString SAL_CALL getInputTitle() override;
+ virtual void SAL_CALL setInputTitle( const OUString& _inputtitle ) override;
+ virtual OUString SAL_CALL getErrorTitle() override;
+ virtual void SAL_CALL setErrorTitle( const OUString& _errortitle ) override;
+ virtual OUString SAL_CALL getInputMessage() override;
+ virtual void SAL_CALL setInputMessage( const OUString& _inputmessage ) override;
+ virtual OUString SAL_CALL getErrorMessage() override;
+ virtual void SAL_CALL setErrorMessage( const OUString& _errormessage ) override;
+ virtual OUString SAL_CALL getFormula1() override ;
+ virtual OUString SAL_CALL getFormula2() override;
+ virtual sal_Int32 SAL_CALL getType() override;
+ // Methods
+ virtual void SAL_CALL Delete( ) override;
+ virtual void SAL_CALL Add( const css::uno::Any& Type, const css::uno::Any& AlertStyle, const css::uno::Any& Operator, const css::uno::Any& Formula1, const css::uno::Any& Formula2 ) override;
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbawindow.cxx b/sc/source/ui/vba/vbawindow.cxx
new file mode 100644
index 000000000..3e7cc4f56
--- /dev/null
+++ b/sc/source/ui/vba/vbawindow.cxx
@@ -0,0 +1,868 @@
+/* -*- 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 "excelvbahelper.hxx"
+#include "vbawindow.hxx"
+#include "vbaworksheets.hxx"
+#include "vbaworksheet.hxx"
+#include "vbaworkbook.hxx"
+#include "vbapane.hxx"
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XViewSplitable.hpp>
+#include <com/sun/star/sheet/XViewFreezable.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/view/DocumentZoomType.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <o3tl/safeint.hxx>
+#include <ooo/vba/excel/XApplication.hpp>
+#include <ooo/vba/excel/XlWindowState.hpp>
+#include <ooo/vba/excel/XlWindowView.hpp>
+#include <basic/sberrors.hxx>
+#include <comphelper/sequence.hxx>
+#include <cppuhelper/implbase.hxx>
+
+#include <docsh.hxx>
+#include <tabvwsh.hxx>
+#include <docuno.hxx>
+#include <sc.hrc>
+#include <sfx2/viewfrm.hxx>
+#include <vcl/wrkwin.hxx>
+#include <unonames.hxx>
+#include <markdata.hxx>
+#include <unordered_map>
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+using namespace ::ooo::vba::excel::XlWindowState;
+
+typedef std::unordered_map< OUString,
+SCTAB > NameIndexHash;
+
+typedef std::vector< uno::Reference< sheet::XSpreadsheet > > Sheets;
+
+typedef ::cppu::WeakImplHelper< container::XEnumerationAccess
+ , css::container::XIndexAccess
+ , css::container::XNameAccess
+ > SelectedSheets_BASE;
+
+namespace {
+
+class SelectedSheetsEnum : public ::cppu::WeakImplHelper< container::XEnumeration >
+{
+public:
+ uno::Reference< uno::XComponentContext > m_xContext;
+ Sheets m_sheets;
+ uno::Reference< frame::XModel > m_xModel;
+ Sheets::const_iterator m_it;
+
+ /// @throws uno::RuntimeException
+ SelectedSheetsEnum( const uno::Reference< uno::XComponentContext >& xContext, Sheets&& sheets, const uno::Reference< frame::XModel >& xModel )
+ : m_xContext( xContext ), m_sheets( std::move(sheets) ), m_xModel( xModel )
+ {
+ m_it = m_sheets.begin();
+ }
+ // XEnumeration
+ virtual sal_Bool SAL_CALL hasMoreElements( ) override
+ {
+ return m_it != m_sheets.end();
+ }
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ if ( !hasMoreElements() )
+ {
+ throw container::NoSuchElementException();
+ }
+ // #FIXME needs ThisWorkbook as parent
+ return uno::Any( uno::Reference< excel::XWorksheet > ( new ScVbaWorksheet( uno::Reference< XHelperInterface >(), m_xContext, *(m_it++), m_xModel ) ) );
+ }
+
+};
+
+class SelectedSheetsEnumAccess : public SelectedSheets_BASE
+{
+ uno::Reference< uno::XComponentContext > m_xContext;
+ NameIndexHash namesToIndices;
+ Sheets sheets;
+ uno::Reference< frame::XModel > m_xModel;
+public:
+ SelectedSheetsEnumAccess( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< frame::XModel >& xModel ):m_xContext( xContext ), m_xModel( xModel )
+ {
+ ScModelObj* pModel = static_cast< ScModelObj* >( m_xModel.get() );
+ if ( !pModel )
+ throw uno::RuntimeException("Cannot obtain current document" );
+ ScDocShell* pDocShell = static_cast<ScDocShell*>(pModel->GetEmbeddedObject());
+ if ( !pDocShell )
+ throw uno::RuntimeException("Cannot obtain docshell" );
+ ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel );
+ if ( !pViewShell )
+ throw uno::RuntimeException("Cannot obtain view shell" );
+
+ SCTAB nTabCount = pDocShell->GetDocument().GetTableCount();
+ SCTAB nIndex = 0;
+ const ScMarkData& rMarkData = pViewShell->GetViewData().GetMarkData();
+ sheets.reserve( nTabCount );
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadSheet( m_xModel, uno::UNO_QUERY_THROW );
+ uno::Reference <container::XIndexAccess> xIndex( xSpreadSheet->getSheets(), uno::UNO_QUERY_THROW );
+ for (const auto& rTab : rMarkData)
+ {
+ if (rTab >= nTabCount)
+ break;
+ uno::Reference< sheet::XSpreadsheet > xSheet( xIndex->getByIndex( rTab ), uno::UNO_QUERY_THROW );
+ uno::Reference< container::XNamed > xNamed( xSheet, uno::UNO_QUERY_THROW );
+ sheets.push_back( xSheet );
+ namesToIndices[ xNamed->getName() ] = nIndex++;
+ }
+
+ }
+
+ //XEnumerationAccess
+ virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) override
+ {
+ return new SelectedSheetsEnum( m_xContext, std::vector(sheets), m_xModel );
+ }
+ // XIndexAccess
+ virtual ::sal_Int32 SAL_CALL getCount( ) override
+ {
+ return sheets.size();
+ }
+ virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override
+ {
+ if ( Index < 0
+ || o3tl::make_unsigned( Index ) >= sheets.size() )
+ throw lang::IndexOutOfBoundsException();
+
+ return uno::Any( sheets[ Index ] );
+ }
+
+ //XElementAccess
+ virtual uno::Type SAL_CALL getElementType( ) override
+ {
+ return cppu::UnoType<excel::XWorksheet>::get();
+ }
+
+ virtual sal_Bool SAL_CALL hasElements( ) override
+ {
+ return ( !sheets.empty() );
+ }
+
+ //XNameAccess
+ virtual uno::Any SAL_CALL getByName( const OUString& aName ) override
+ {
+ NameIndexHash::const_iterator it = namesToIndices.find( aName );
+ if ( it == namesToIndices.end() )
+ throw container::NoSuchElementException();
+ return uno::Any( sheets[ it->second ] );
+
+ }
+
+ virtual uno::Sequence< OUString > SAL_CALL getElementNames( ) override
+ {
+ return comphelper::mapKeysToSequence( namesToIndices );
+ }
+
+ virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override
+ {
+ NameIndexHash::const_iterator it = namesToIndices.find( aName );
+ return (it != namesToIndices.end());
+ }
+
+};
+
+}
+
+ScVbaWindow::ScVbaWindow(
+ const uno::Reference< XHelperInterface >& xParent,
+ const uno::Reference< uno::XComponentContext >& xContext,
+ const uno::Reference< frame::XModel >& xModel,
+ const uno::Reference< frame::XController >& xController ) :
+ WindowImpl_BASE( xParent, xContext, xModel, xController )
+{
+ init();
+}
+
+ScVbaWindow::ScVbaWindow(
+ const uno::Sequence< uno::Any >& args,
+ const uno::Reference< uno::XComponentContext >& xContext ) :
+ WindowImpl_BASE( args, xContext )
+{
+ init();
+}
+
+void
+ScVbaWindow::init()
+{
+ /* This method is called from the constructor, thus the own refcount is
+ still zero. The implementation of ActivePane() uses a UNO reference of
+ this (to set this window as parent of the pane object). This requires
+ the own refcount to be non-zero, otherwise this instance will be
+ destructed immediately! Guard the call to ActivePane() in try/catch to
+ not miss the decrementation of the reference count on exception. */
+ osl_atomic_increment( &m_refCount );
+ try
+ {
+ m_xPane = ActivePane();
+ }
+ catch( uno::Exception& )
+ {
+ }
+ osl_atomic_decrement( &m_refCount );
+}
+
+uno::Reference< beans::XPropertySet >
+ScVbaWindow::getControllerProps() const
+{
+ return uno::Reference< beans::XPropertySet >( getController(), uno::UNO_QUERY_THROW );
+}
+
+uno::Reference< beans::XPropertySet >
+ScVbaWindow::getFrameProps() const
+{
+ return uno::Reference< beans::XPropertySet >( getController()->getFrame(), uno::UNO_QUERY_THROW );
+}
+
+uno::Reference< awt::XDevice >
+ScVbaWindow::getDevice() const
+{
+ return uno::Reference< awt::XDevice >( getWindow(), uno::UNO_QUERY_THROW );
+}
+
+void
+ScVbaWindow::Scroll( const uno::Any& Down, const uno::Any& Up, const uno::Any& ToRight, const uno::Any& ToLeft, bool bLargeScroll )
+{
+ if( !m_xPane.is() )
+ throw uno::RuntimeException();
+ if( bLargeScroll )
+ m_xPane->LargeScroll( Down, Up, ToRight, ToLeft );
+ else
+ m_xPane->SmallScroll( Down, Up, ToRight, ToLeft );
+}
+
+void SAL_CALL
+ScVbaWindow::SmallScroll( const uno::Any& Down, const uno::Any& Up, const uno::Any& ToRight, const uno::Any& ToLeft )
+{
+ Scroll( Down, Up, ToRight, ToLeft, false );
+}
+
+void SAL_CALL
+ScVbaWindow::LargeScroll( const uno::Any& Down, const uno::Any& Up, const uno::Any& ToRight, const uno::Any& ToLeft )
+{
+ Scroll( Down, Up, ToRight, ToLeft, true );
+}
+
+uno::Any SAL_CALL
+ScVbaWindow::SelectedSheets( const uno::Any& aIndex )
+{
+ uno::Reference< container::XEnumerationAccess > xEnumAccess( new SelectedSheetsEnumAccess( mxContext, m_xModel ) );
+ // #FIXME needs a workbook as a parent
+ uno::Reference< excel::XWorksheets > xSheets( new ScVbaWorksheets( uno::Reference< XHelperInterface >(), mxContext, xEnumAccess, m_xModel ) );
+ if ( aIndex.hasValue() )
+ {
+ uno::Reference< XCollection > xColl( xSheets, uno::UNO_QUERY_THROW );
+ return xColl->Item( aIndex, uno::Any() );
+ }
+ return uno::Any( xSheets );
+}
+
+void SAL_CALL
+ScVbaWindow::ScrollWorkbookTabs( const uno::Any& /*Sheets*/, const uno::Any& /*Position*/ )
+{
+// #TODO #FIXME need some implementation to scroll through the tabs
+// but where is this done?
+/*
+ sal_Int32 nSheets = 0;
+ sal_Int32 nPosition = 0;
+ throw uno::RuntimeException("No Implemented" );
+ sal_Bool bSheets = ( Sheets >>= nSheets );
+ sal_Bool bPosition = ( Position >>= nPosition );
+ if ( bSheets || bPosition ) // at least one param specified
+ if ( bSheets )
+ ;// use sheets
+ else if ( bPosition )
+ ; //use position
+*/
+
+}
+
+uno::Any SAL_CALL
+ScVbaWindow::getCaption()
+{
+ // tdf#118129 - return only the caption property of the frame
+ OUString sTitle;
+ getFrameProps()->getPropertyValue(SC_UNONAME_TITLE) >>= sTitle;
+ return uno::Any( sTitle );
+}
+
+void SAL_CALL
+ScVbaWindow::setCaption( const uno::Any& _caption )
+{
+ getFrameProps()->setPropertyValue( SC_UNONAME_TITLE, _caption );
+}
+
+uno::Any SAL_CALL
+ScVbaWindow::getScrollRow()
+{
+ sal_Int32 nValue = 0;
+ // !! TODO !! get view shell from controller
+ ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel );
+ if ( pViewShell )
+ {
+ ScSplitPos eWhich = pViewShell->GetViewData().GetActivePart();
+ nValue = pViewShell->GetViewData().GetPosY(WhichV(eWhich));
+ }
+
+ return uno::Any( nValue + 1);
+}
+
+void SAL_CALL
+ScVbaWindow::setScrollRow( const uno::Any& _scrollrow )
+{
+ // !! TODO !! get view shell from controller
+ ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel );
+ if ( pViewShell )
+ {
+ sal_Int32 scrollRow = 0;
+ _scrollrow >>= scrollRow;
+ ScSplitPos eWhich = pViewShell->GetViewData().GetActivePart();
+ sal_Int32 nOldValue = pViewShell->GetViewData().GetPosY(WhichV(eWhich)) + 1;
+ pViewShell->ScrollLines(0, scrollRow - nOldValue);
+ }
+}
+
+uno::Any SAL_CALL
+ScVbaWindow::getScrollColumn()
+{
+ sal_Int32 nValue = 0;
+ // !! TODO !! get view shell from controller
+ ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel );
+ if ( pViewShell )
+ {
+ ScSplitPos eWhich = pViewShell->GetViewData().GetActivePart();
+ nValue = pViewShell->GetViewData().GetPosX(WhichH(eWhich));
+ }
+
+ return uno::Any( nValue + 1);
+}
+
+void SAL_CALL
+ScVbaWindow::setScrollColumn( const uno::Any& _scrollcolumn )
+{
+ // !! TODO !! get view shell from controller
+ ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel );
+ if ( pViewShell )
+ {
+ sal_Int32 scrollColumn = 0;
+ _scrollcolumn >>= scrollColumn;
+ ScSplitPos eWhich = pViewShell->GetViewData().GetActivePart();
+ sal_Int32 nOldValue = pViewShell->GetViewData().GetPosX(WhichH(eWhich)) + 1;
+ pViewShell->ScrollLines(scrollColumn - nOldValue, 0);
+ }
+}
+
+uno::Any SAL_CALL
+ScVbaWindow::getWindowState()
+{
+ sal_Int32 nwindowState = xlNormal;
+ // !! TODO !! get view shell from controller
+ ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel );
+ SfxViewFrame* pViewFrame = pViewShell -> GetViewFrame();
+ WorkWindow* pWork = static_cast<WorkWindow*>( pViewFrame->GetFrame().GetSystemWindow() );
+ if ( pWork )
+ {
+ if ( pWork -> IsMaximized())
+ nwindowState = xlMaximized;
+ else if (pWork -> IsMinimized())
+ nwindowState = xlMinimized;
+ }
+ return uno::Any( nwindowState );
+}
+
+void SAL_CALL
+ScVbaWindow::setWindowState( const uno::Any& _windowstate )
+{
+ sal_Int32 nwindowState = xlMaximized;
+ _windowstate >>= nwindowState;
+ // !! TODO !! get view shell from controller
+ ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel );
+ SfxViewFrame* pViewFrame = pViewShell -> GetViewFrame();
+ WorkWindow* pWork = static_cast<WorkWindow*>( pViewFrame->GetFrame().GetSystemWindow() );
+ if ( pWork )
+ {
+ if ( nwindowState == xlMaximized)
+ pWork -> Maximize();
+ else if (nwindowState == xlMinimized)
+ pWork -> Minimize();
+ else if (nwindowState == xlNormal)
+ pWork -> Restore();
+ else
+ throw uno::RuntimeException("Invalid Parameter" );
+ }
+}
+
+void
+ScVbaWindow::Activate()
+{
+ rtl::Reference<ScVbaWorkbook> workbook( new ScVbaWorkbook( uno::Reference< XHelperInterface >( Application(), uno::UNO_QUERY_THROW ), mxContext, m_xModel ) );
+
+ workbook->Activate();
+}
+
+void
+ScVbaWindow::Close( const uno::Any& SaveChanges, const uno::Any& FileName, const uno::Any& RouteWorkBook )
+{
+ rtl::Reference< ScVbaWorkbook > workbook( new ScVbaWorkbook( uno::Reference< XHelperInterface >( Application(), uno::UNO_QUERY_THROW ), mxContext, m_xModel ) );
+ workbook->Close(SaveChanges, FileName, RouteWorkBook );
+}
+
+uno::Reference< excel::XPane > SAL_CALL
+ScVbaWindow::ActivePane()
+{
+ uno::Reference< sheet::XViewPane > xViewPane( getController(), uno::UNO_QUERY_THROW );
+ return new ScVbaPane( this, mxContext, m_xModel, xViewPane );
+}
+
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaWindow::ActiveCell( )
+{
+ uno::Reference< excel::XApplication > xApplication( Application(), uno::UNO_QUERY_THROW );
+ return xApplication->getActiveCell();
+}
+
+uno::Any SAL_CALL
+ScVbaWindow::Selection( )
+{
+ uno::Reference< excel::XApplication > xApplication( Application(), uno::UNO_QUERY_THROW );
+ return xApplication->getSelection();
+}
+
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaWindow::RangeSelection()
+{
+ /* TODO / FIXME: According to documentation, this method returns the range
+ selection even if shapes are selected. */
+ return uno::Reference< excel::XRange >( Selection(), uno::UNO_QUERY_THROW );
+}
+
+sal_Bool SAL_CALL
+ScVbaWindow::getDisplayGridlines()
+{
+ bool bGrid = true;
+ getControllerProps()->getPropertyValue( SC_UNO_SHOWGRID ) >>= bGrid;
+ return bGrid;
+}
+
+void SAL_CALL
+ScVbaWindow::setDisplayGridlines( sal_Bool _displaygridlines )
+{
+ getControllerProps()->setPropertyValue( SC_UNO_SHOWGRID, uno::Any( _displaygridlines ));
+}
+
+sal_Bool SAL_CALL
+ScVbaWindow::getDisplayHeadings()
+{
+ bool bHeading = true;
+ getControllerProps()->getPropertyValue( SC_UNO_COLROWHDR ) >>= bHeading;
+ return bHeading;
+}
+
+void SAL_CALL
+ScVbaWindow::setDisplayHeadings( sal_Bool _bDisplayHeadings )
+{
+ getControllerProps()->setPropertyValue( SC_UNO_COLROWHDR, uno::Any( _bDisplayHeadings ));
+}
+
+sal_Bool SAL_CALL
+ScVbaWindow::getDisplayHorizontalScrollBar()
+{
+ bool bHorizontalScrollBar = true;
+ getControllerProps()->getPropertyValue( SC_UNO_HORSCROLL ) >>= bHorizontalScrollBar;
+ return bHorizontalScrollBar;
+}
+
+void SAL_CALL
+ScVbaWindow::setDisplayHorizontalScrollBar( sal_Bool _bDisplayHorizontalScrollBar )
+{
+ getControllerProps()->setPropertyValue( SC_UNO_HORSCROLL, uno::Any( _bDisplayHorizontalScrollBar ));
+}
+
+sal_Bool SAL_CALL
+ScVbaWindow::getDisplayOutline()
+{
+ bool bOutline = true;
+ getControllerProps()->getPropertyValue( SC_UNO_OUTLSYMB ) >>= bOutline;
+ return bOutline;
+}
+
+void SAL_CALL
+ScVbaWindow::setDisplayOutline( sal_Bool _bDisplayOutline )
+{
+ getControllerProps()->setPropertyValue( SC_UNO_OUTLSYMB, uno::Any( _bDisplayOutline ));
+}
+
+sal_Bool SAL_CALL
+ScVbaWindow::getDisplayVerticalScrollBar()
+{
+ bool bVerticalScrollBar = true;
+ getControllerProps()->getPropertyValue( SC_UNO_VERTSCROLL ) >>= bVerticalScrollBar;
+ return bVerticalScrollBar;
+}
+
+void SAL_CALL
+ScVbaWindow::setDisplayVerticalScrollBar( sal_Bool _bDisplayVerticalScrollBar )
+{
+ getControllerProps()->setPropertyValue( SC_UNO_VERTSCROLL, uno::Any( _bDisplayVerticalScrollBar ));
+}
+
+sal_Bool SAL_CALL
+ScVbaWindow::getDisplayWorkbookTabs()
+{
+ bool bWorkbookTabs = true;
+ getControllerProps()->getPropertyValue( SC_UNO_SHEETTABS ) >>= bWorkbookTabs;
+ return bWorkbookTabs;
+}
+
+void SAL_CALL
+ScVbaWindow::setDisplayWorkbookTabs( sal_Bool _bDisplayWorkbookTabs )
+{
+ getControllerProps()->setPropertyValue( SC_UNO_SHEETTABS, uno::Any( _bDisplayWorkbookTabs ));
+}
+
+sal_Bool SAL_CALL
+ScVbaWindow::getFreezePanes()
+{
+ uno::Reference< sheet::XViewFreezable > xViewFreezable( getController(), uno::UNO_QUERY_THROW );
+ return xViewFreezable->hasFrozenPanes();
+}
+
+void SAL_CALL
+ScVbaWindow::setFreezePanes( sal_Bool _bFreezePanes )
+{
+ uno::Reference< sheet::XViewPane > xViewPane( getController(), uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XViewSplitable > xViewSplitable( xViewPane, uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XViewFreezable > xViewFreezable( xViewPane, uno::UNO_QUERY_THROW );
+ if( _bFreezePanes )
+ {
+ if( xViewSplitable->getIsWindowSplit() )
+ {
+ // if there is a split we freeze at the split
+ sal_Int32 nColumn = getSplitColumn();
+ sal_Int32 nRow = getSplitRow();
+ xViewFreezable->freezeAtPosition( nColumn, nRow );
+ }
+ else
+ {
+ // otherwise we freeze in the center of the visible sheet
+ table::CellRangeAddress aCellRangeAddress = xViewPane->getVisibleRange();
+ sal_Int32 nColumn = aCellRangeAddress.StartColumn + (( aCellRangeAddress.EndColumn - aCellRangeAddress.StartColumn )/2 );
+ sal_Int32 nRow = aCellRangeAddress.StartRow + (( aCellRangeAddress.EndRow - aCellRangeAddress.StartRow )/2 );
+ xViewFreezable->freezeAtPosition( nColumn, nRow );
+ }
+ }
+ else
+ {
+ //remove the freeze panes
+ xViewSplitable->splitAtPosition(0,0);
+ }
+}
+
+sal_Bool SAL_CALL
+ScVbaWindow::getSplit()
+{
+ uno::Reference< sheet::XViewSplitable > xViewSplitable( getController(), uno::UNO_QUERY_THROW );
+ return xViewSplitable->getIsWindowSplit();
+}
+
+void SAL_CALL
+ScVbaWindow::setSplit( sal_Bool _bSplit )
+{
+ if( !_bSplit )
+ {
+ uno::Reference< sheet::XViewSplitable > xViewSplitable( getController(), uno::UNO_QUERY_THROW );
+ xViewSplitable->splitAtPosition(0,0);
+ }
+ else
+ {
+ uno::Reference< sheet::XViewFreezable > xViewFreezable( getController(), uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XRange > xRange = ActiveCell();
+ sal_Int32 nRow = xRange->getRow();
+ sal_Int32 nColumn = xRange->getColumn();
+ SplitAtDefinedPosition( nColumn-1, nRow-1 );
+ }
+}
+
+sal_Int32 SAL_CALL
+ScVbaWindow::getSplitColumn()
+{
+ uno::Reference< sheet::XViewSplitable > xViewSplitable( getController(), uno::UNO_QUERY_THROW );
+ return xViewSplitable->getSplitColumn();
+}
+
+void SAL_CALL
+ScVbaWindow::setSplitColumn( sal_Int32 _splitcolumn )
+{
+ if( getSplitColumn() != _splitcolumn )
+ {
+ uno::Reference< sheet::XViewFreezable > xViewFreezable( getController(), uno::UNO_QUERY_THROW );
+ sal_Int32 nRow = getSplitRow();
+ SplitAtDefinedPosition( _splitcolumn, nRow );
+ }
+}
+
+double SAL_CALL
+ScVbaWindow::getSplitHorizontal()
+{
+ uno::Reference< sheet::XViewSplitable > xViewSplitable( getController(), uno::UNO_QUERY_THROW );
+ return PixelsToPoints( getDevice(), xViewSplitable->getSplitHorizontal(), true );
+}
+
+void SAL_CALL
+ScVbaWindow::setSplitHorizontal( double _splithorizontal )
+{
+ uno::Reference< sheet::XViewSplitable > xViewSplitable( getController(), uno::UNO_QUERY_THROW );
+ double fHoriPixels = PointsToPixels( getDevice(), _splithorizontal, true );
+ xViewSplitable->splitAtPosition( static_cast< sal_Int32 >( fHoriPixels ), 0 );
+}
+
+sal_Int32 SAL_CALL
+ScVbaWindow::getSplitRow()
+{
+ uno::Reference< sheet::XViewSplitable > xViewSplitable( getController(), uno::UNO_QUERY_THROW );
+ return xViewSplitable->getSplitRow();
+}
+
+void SAL_CALL
+ScVbaWindow::setSplitRow( sal_Int32 _splitrow )
+{
+ if( getSplitRow() != _splitrow )
+ {
+ uno::Reference< sheet::XViewFreezable > xViewFreezable( getController(), uno::UNO_QUERY_THROW );
+ sal_Int32 nColumn = getSplitColumn();
+ SplitAtDefinedPosition( nColumn, _splitrow );
+ }
+}
+
+double SAL_CALL
+ScVbaWindow::getSplitVertical()
+{
+ uno::Reference< sheet::XViewSplitable > xViewSplitable( getController(), uno::UNO_QUERY_THROW );
+ return PixelsToPoints( getDevice(), xViewSplitable->getSplitVertical(), false );
+}
+
+void SAL_CALL
+ScVbaWindow::setSplitVertical(double _splitvertical )
+{
+ uno::Reference< sheet::XViewSplitable > xViewSplitable( getController(), uno::UNO_QUERY_THROW );
+ double fVertiPixels = PointsToPixels( getDevice(), _splitvertical, false );
+ xViewSplitable->splitAtPosition( 0, static_cast<sal_Int32>( fVertiPixels ) );
+}
+
+void ScVbaWindow::SplitAtDefinedPosition( sal_Int32 nColumns, sal_Int32 nRows )
+{
+ uno::Reference< sheet::XViewSplitable > xViewSplitable( getController(), uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XViewFreezable > xViewFreezable( xViewSplitable, uno::UNO_QUERY_THROW );
+ // nColumns and nRows means split columns/rows
+ if( nColumns == 0 && nRows == 0 )
+ return;
+
+ sal_Int32 cellColumn = nColumns + 1;
+ sal_Int32 cellRow = nRows + 1;
+
+ ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel );
+ if ( pViewShell )
+ {
+ //firstly remove the old splitter
+ xViewSplitable->splitAtPosition(0,0);
+
+ uno::Reference< excel::XApplication > xApplication( Application(), uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XWorksheet > xSheet( xApplication->getActiveSheet(), uno::UNO_SET_THROW );
+ xSheet->Cells(uno::Any(cellRow), uno::Any(cellColumn))->Select();
+
+ //pViewShell->FreezeSplitters( FALSE );
+ dispatchExecute( pViewShell, SID_WINDOW_SPLIT );
+ }
+}
+
+uno::Any SAL_CALL
+ScVbaWindow::getZoom()
+{
+ uno::Reference< beans::XPropertySet > xProps = getControllerProps();
+ OUString sName( SC_UNO_ZOOMTYPE );
+ sal_Int16 nZoomType = view::DocumentZoomType::PAGE_WIDTH;
+ xProps->getPropertyValue( sName ) >>= nZoomType;
+ if( nZoomType == view::DocumentZoomType::PAGE_WIDTH )
+ {
+ return uno::Any( true );
+ }
+ else if( nZoomType == view::DocumentZoomType::BY_VALUE )
+ {
+ sName = SC_UNO_ZOOMVALUE;
+ sal_Int16 nZoom = 100;
+ xProps->getPropertyValue( sName ) >>= nZoom;
+ return uno::Any( nZoom );
+ }
+ return uno::Any();
+}
+
+void SAL_CALL ScVbaWindow::setZoom(const uno::Any& _zoom)
+{
+ sal_Int16 nZoom = 100;
+ _zoom >>= nZoom;
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( m_xModel, uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XWorksheet > xActiveSheet = ActiveSheet();
+ SCTAB nTab = 0;
+ if ( !ScVbaWorksheets::nameExists (xSpreadDoc, xActiveSheet->getName(), nTab) )
+ throw uno::RuntimeException();
+ std::vector< SCTAB > vTabs { nTab };
+ excel::implSetZoom( m_xModel, nZoom, vTabs );
+}
+
+uno::Reference< excel::XWorksheet > SAL_CALL
+ScVbaWindow::ActiveSheet( )
+{
+ uno::Reference< excel::XApplication > xApplication( Application(), uno::UNO_QUERY_THROW );
+ return xApplication->getActiveSheet();
+}
+
+uno::Any SAL_CALL
+ScVbaWindow::getView()
+{
+ bool bPageBreak = false;
+ sal_Int32 nWindowView = excel::XlWindowView::xlNormalView;
+
+ ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel );
+ if (pViewShell)
+ bPageBreak = pViewShell->GetViewData().IsPagebreakMode();
+
+ if( bPageBreak )
+ nWindowView = excel::XlWindowView::xlPageBreakPreview;
+ else
+ nWindowView = excel::XlWindowView::xlNormalView;
+
+ return uno::Any( nWindowView );
+}
+
+void SAL_CALL
+ScVbaWindow::setView( const uno::Any& _view)
+{
+ sal_Int32 nWindowView = excel::XlWindowView::xlNormalView;
+ _view >>= nWindowView;
+ sal_uInt16 nSlot = FID_NORMALVIEWMODE;
+ switch ( nWindowView )
+ {
+ case excel::XlWindowView::xlNormalView:
+ nSlot = FID_NORMALVIEWMODE;
+ break;
+ case excel::XlWindowView::xlPageBreakPreview:
+ nSlot = FID_PAGEBREAKMODE;
+ break;
+ default:
+ DebugHelper::runtimeexception(ERRCODE_BASIC_BAD_PARAMETER);
+ }
+ // !! TODO !! get view shell from controller
+ ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel );
+ if ( pViewShell )
+ dispatchExecute( pViewShell, nSlot );
+}
+
+uno::Reference< excel::XRange > SAL_CALL
+ScVbaWindow::getVisibleRange()
+{
+ uno::Reference< container::XIndexAccess > xPanesIA( getController(), uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XViewPane > xTopLeftPane( xPanesIA->getByIndex( 0 ), uno::UNO_QUERY_THROW );
+ uno::Reference< excel::XPane > xPane( new ScVbaPane( this, mxContext, m_xModel, xTopLeftPane ) );
+ return xPane->getVisibleRange();
+}
+
+sal_Int32 SAL_CALL
+ScVbaWindow::PointsToScreenPixelsX(sal_Int32 _points)
+{
+ sal_Int32 nHundredthsofOneMillimeters = Millimeter::getInHundredthsOfOneMillimeter( _points );
+ double fConvertFactor = getDevice()->getInfo().PixelPerMeterX/100000;
+ return static_cast<sal_Int32>(fConvertFactor * nHundredthsofOneMillimeters );
+}
+
+sal_Int32 SAL_CALL
+ScVbaWindow::PointsToScreenPixelsY(sal_Int32 _points)
+{
+ sal_Int32 nHundredthsofOneMillimeters = Millimeter::getInHundredthsOfOneMillimeter( _points );
+ double fConvertFactor = getDevice()->getInfo().PixelPerMeterY/100000;
+ return static_cast<sal_Int32>(fConvertFactor * nHundredthsofOneMillimeters );
+}
+
+void SAL_CALL
+ScVbaWindow::PrintOut( const css::uno::Any& From, const css::uno::Any&To, const css::uno::Any& Copies, const css::uno::Any& Preview, const css::uno::Any& ActivePrinter, const css::uno::Any& PrintToFile, const css::uno::Any& Collate, const css::uno::Any& PrToFileName )
+{
+ // need test, print current active sheet
+ // !! TODO !! get view shell from controller
+ PrintOutHelper( excel::getBestViewShell( m_xModel ), From, To, Copies, Preview, ActivePrinter, PrintToFile, Collate, PrToFileName, true );
+}
+
+void SAL_CALL
+ScVbaWindow::PrintPreview( const css::uno::Any& EnableChanges )
+{
+ // need test, print preview current active sheet
+ // !! TODO !! get view shell from controller
+ PrintPreviewHelper( EnableChanges, excel::getBestViewShell( m_xModel ) );
+}
+
+double SAL_CALL ScVbaWindow::getTabRatio()
+{
+ ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel );
+ if ( pViewShell && pViewShell->GetViewData().GetView() )
+ {
+ double fRatio = ScTabView::GetRelTabBarWidth();
+ if ( fRatio >= 0.0 && fRatio <= 1.0 )
+ return fRatio;
+ }
+ return 0.0;
+}
+
+void SAL_CALL ScVbaWindow::setTabRatio( double fRatio )
+{
+ ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel );
+ if ( pViewShell && pViewShell->GetViewData().GetView() )
+ {
+ if ( fRatio >= 0.0 && fRatio <= 1.0 )
+ pViewShell->GetViewData().GetView()->SetRelTabBarWidth( fRatio );
+ }
+}
+
+OUString
+ScVbaWindow::getServiceImplName()
+{
+ return "ScVbaWindow";
+}
+
+uno::Sequence< OUString >
+ScVbaWindow::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.Window"
+ };
+ return aServiceNames;
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+Calc_ScVbaWindow_get_implementation(
+ css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& args)
+{
+ return cppu::acquire(new ScVbaWindow(args, context));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbawindow.hxx b/sc/source/ui/vba/vbawindow.hxx
new file mode 100644
index 000000000..c4c0a0bec
--- /dev/null
+++ b/sc/source/ui/vba/vbawindow.hxx
@@ -0,0 +1,126 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <ooo/vba/excel/XWindow.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <ooo/vba/excel/XPane.hpp>
+#include <com/sun/star/awt/XDevice.hpp>
+#include <cppuhelper/implbase.hxx>
+
+#include <vbahelper/vbawindowbase.hxx>
+
+typedef cppu::ImplInheritanceHelper< VbaWindowBase, ov::excel::XWindow > WindowImpl_BASE;
+
+class ScVbaWindow : public WindowImpl_BASE
+{
+private:
+ css::uno::Reference< ov::excel::XPane > m_xPane;
+
+ void init();
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference< css::beans::XPropertySet > getControllerProps() const;
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference< css::beans::XPropertySet > getFrameProps() const;
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference< css::awt::XDevice > getDevice() const;
+
+protected:
+ void SplitAtDefinedPosition( sal_Int32 nColumns, sal_Int32 nRows );
+
+public:
+ /// @throws css::uno::RuntimeException
+ void Scroll( const css::uno::Any& Down, const css::uno::Any& Up, const css::uno::Any& ToRight, const css::uno::Any& ToLeft, bool bLargeScroll );
+
+public:
+ /// @throws css::uno::RuntimeException
+ ScVbaWindow(
+ const css::uno::Reference< ov::XHelperInterface >& xParent,
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ const css::uno::Reference< css::frame::XModel >& xModel,
+ const css::uno::Reference< css::frame::XController >& xController );
+ /// @throws css::uno::RuntimeException
+ ScVbaWindow(
+ const css::uno::Sequence< css::uno::Any >& aArgs,
+ const css::uno::Reference< css::uno::XComponentContext >& xContext );
+
+ // XWindow
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL ActiveCell( ) override;
+ virtual css::uno::Reference< ov::excel::XPane > SAL_CALL ActivePane() override;
+ virtual css::uno::Reference< ov::excel::XWorksheet > SAL_CALL ActiveSheet( ) override;
+ virtual void SAL_CALL setCaption( const css::uno::Any& _caption ) override;
+ virtual css::uno::Any SAL_CALL getCaption() override;
+ virtual sal_Bool SAL_CALL getDisplayGridlines() override;
+ virtual void SAL_CALL setDisplayGridlines( sal_Bool _displaygridlines ) override;
+ virtual sal_Bool SAL_CALL getDisplayHeadings() override;
+ virtual void SAL_CALL setDisplayHeadings( sal_Bool _bDisplayHeadings ) override;
+ virtual sal_Bool SAL_CALL getDisplayHorizontalScrollBar() override;
+ virtual void SAL_CALL setDisplayHorizontalScrollBar( sal_Bool _bDisplayHorizontalScrollBar ) override;
+ virtual sal_Bool SAL_CALL getDisplayOutline() override;
+ virtual void SAL_CALL setDisplayOutline( sal_Bool _bDisplayOutline ) override;
+ virtual sal_Bool SAL_CALL getDisplayVerticalScrollBar() override;
+ virtual void SAL_CALL setDisplayVerticalScrollBar( sal_Bool _bDisplayVerticalScrollBar ) override;
+ virtual sal_Bool SAL_CALL getDisplayWorkbookTabs() override;
+ virtual void SAL_CALL setDisplayWorkbookTabs( sal_Bool _bDisplayWorkbookTabs ) override;
+ virtual sal_Bool SAL_CALL getFreezePanes() override;
+ virtual void SAL_CALL setFreezePanes( sal_Bool _bFreezePanes ) override;
+ virtual sal_Bool SAL_CALL getSplit() override;
+ virtual void SAL_CALL setSplit( sal_Bool _bSplit ) override;
+ virtual sal_Int32 SAL_CALL getSplitColumn() override ;
+ virtual void SAL_CALL setSplitColumn( sal_Int32 _splitcolumn ) override ;
+ virtual double SAL_CALL getSplitHorizontal() override ;
+ virtual void SAL_CALL setSplitHorizontal( double _splithorizontal ) override ;
+ virtual sal_Int32 SAL_CALL getSplitRow() override ;
+ virtual void SAL_CALL setSplitRow( sal_Int32 _splitrow ) override ;
+ virtual double SAL_CALL getSplitVertical() override ;
+ virtual void SAL_CALL setSplitVertical( double _splitvertical ) override ;
+ virtual css::uno::Any SAL_CALL getScrollRow() override ;
+ virtual void SAL_CALL setScrollRow( const css::uno::Any& _scrollrow ) override ;
+ virtual css::uno::Any SAL_CALL getScrollColumn() override ;
+ virtual void SAL_CALL setScrollColumn( const css::uno::Any& _scrollcolumn ) override ;
+ virtual css::uno::Any SAL_CALL getView() override;
+ virtual void SAL_CALL setView( const css::uno::Any& _view ) override;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL getVisibleRange() override;
+ virtual css::uno::Any SAL_CALL getWindowState() override;
+ virtual void SAL_CALL setWindowState( const css::uno::Any& _windowstate ) override;
+ virtual css::uno::Any SAL_CALL getZoom() override;
+ virtual void SAL_CALL setZoom(const css::uno::Any& _zoom) override;
+ virtual double SAL_CALL getTabRatio() override ;
+ virtual void SAL_CALL setTabRatio( double _tabratio ) override ;
+
+ // Methods
+ virtual void SAL_CALL SmallScroll( const css::uno::Any& Down, const css::uno::Any& Up, const css::uno::Any& ToRight, const css::uno::Any& ToLeft ) override;
+ virtual void SAL_CALL LargeScroll( const css::uno::Any& Down, const css::uno::Any& Up, const css::uno::Any& ToRight, const css::uno::Any& ToLeft ) override;
+ virtual css::uno::Any SAL_CALL SelectedSheets( const css::uno::Any& aIndex ) override;
+ virtual void SAL_CALL ScrollWorkbookTabs( const css::uno::Any& Sheets, const css::uno::Any& Position ) override;
+ virtual void SAL_CALL Activate( ) override;
+ virtual void SAL_CALL Close( const css::uno::Any& SaveChanges, const css::uno::Any& FileName, const css::uno::Any& RouteWorkBook ) override;
+ virtual css::uno::Any SAL_CALL Selection( ) override;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL RangeSelection() override;
+ virtual sal_Int32 SAL_CALL PointsToScreenPixelsX(sal_Int32 _points) override;
+ virtual sal_Int32 SAL_CALL PointsToScreenPixelsY(sal_Int32 _points) override;
+ virtual void SAL_CALL PrintOut( const css::uno::Any& From, const css::uno::Any&To, const css::uno::Any& Copies, const css::uno::Any& Preview, const css::uno::Any& ActivePrinter, const css::uno::Any& PrintToFile, const css::uno::Any& Collate, const css::uno::Any& PrToFileName ) override;
+ virtual void SAL_CALL PrintPreview( const css::uno::Any& EnableChanges ) override;
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbawindows.cxx b/sc/source/ui/vba/vbawindows.cxx
new file mode 100644
index 000000000..3a9960378
--- /dev/null
+++ b/sc/source/ui/vba/vbawindows.cxx
@@ -0,0 +1,249 @@
+/* -*- 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 "vbawindows.hxx"
+
+
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <cppuhelper/implbase.hxx>
+#include <comphelper/sequence.hxx>
+#include <o3tl/safeint.hxx>
+#include <rtl/ref.hxx>
+
+#include "vbawindow.hxx"
+#include "vbaworkbook.hxx"
+
+#include <unordered_map>
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+typedef std::unordered_map< OUString,
+sal_Int32 > NameIndexHash;
+
+static uno::Reference< XHelperInterface > lcl_createWorkbookHIParent( const uno::Reference< frame::XModel >& xModel, const uno::Reference< uno::XComponentContext >& xContext, const uno::Any& aApplication )
+{
+ return new ScVbaWorkbook( uno::Reference< XHelperInterface >( aApplication, uno::UNO_QUERY_THROW ), xContext, xModel );
+}
+
+static uno::Any ComponentToWindow( const uno::Any& aSource, const uno::Reference< uno::XComponentContext > & xContext, const uno::Any& aApplication )
+{
+ uno::Reference< frame::XModel > xModel( aSource, uno::UNO_QUERY_THROW );
+ // !! TODO !! iterate over all controllers
+ uno::Reference< frame::XController > xController( xModel->getCurrentController(), uno::UNO_SET_THROW );
+ uno::Reference< excel::XWindow > xWin( new ScVbaWindow( lcl_createWorkbookHIParent( xModel, xContext, aApplication ), xContext, xModel, xController ) );
+ return uno::Any( xWin );
+}
+
+typedef std::vector < uno::Reference< sheet::XSpreadsheetDocument > > Components;
+
+namespace {
+
+// #TODO more or less the same as class in workwindows ( code sharing needed )
+class WindowComponentEnumImpl : public EnumerationHelper_BASE
+{
+protected:
+ uno::Reference< uno::XComponentContext > m_xContext;
+ Components m_components;
+ Components::const_iterator m_it;
+
+public:
+ /// @throws uno::RuntimeException
+ WindowComponentEnumImpl( const uno::Reference< uno::XComponentContext >& xContext, Components&& components )
+ : m_xContext( xContext ), m_components( std::move(components) )
+ {
+ m_it = m_components.begin();
+ }
+
+ /// @throws uno::RuntimeException
+ explicit WindowComponentEnumImpl( const uno::Reference< uno::XComponentContext >& xContext ) : m_xContext( xContext )
+ {
+ uno::Reference< frame::XDesktop2 > xDesktop = frame::Desktop::create(m_xContext);
+ uno::Reference< container::XEnumeration > xComponents = xDesktop->getComponents()->createEnumeration();
+ while( xComponents->hasMoreElements() )
+ {
+ uno::Reference< sheet::XSpreadsheetDocument > xNext( xComponents->nextElement(), uno::UNO_QUERY );
+ if ( xNext.is() )
+ m_components.push_back( xNext );
+ }
+ m_it = m_components.begin();
+ }
+ // XEnumeration
+ virtual sal_Bool SAL_CALL hasMoreElements( ) override
+ {
+ return m_it != m_components.end();
+ }
+
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ if ( !hasMoreElements() )
+ {
+ throw container::NoSuchElementException();
+ }
+ return css::uno::Any( *(m_it++) );
+ }
+};
+
+class WindowEnumImpl : public WindowComponentEnumImpl
+{
+ uno::Any m_aApplication;
+public:
+ WindowEnumImpl( const uno::Reference< uno::XComponentContext >& xContext, const uno::Any& aApplication ): WindowComponentEnumImpl( xContext ), m_aApplication( aApplication ) {}
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ return ComponentToWindow( WindowComponentEnumImpl::nextElement(), m_xContext, m_aApplication );
+ }
+};
+
+}
+
+typedef ::cppu::WeakImplHelper< container::XEnumerationAccess
+ , css::container::XIndexAccess
+ , css::container::XNameAccess
+ > WindowsAccessImpl_BASE;
+
+namespace {
+
+class WindowsAccessImpl : public WindowsAccessImpl_BASE
+{
+ uno::Reference< uno::XComponentContext > m_xContext;
+ Components m_windows;
+ NameIndexHash namesToIndices;
+public:
+ explicit WindowsAccessImpl( const uno::Reference< uno::XComponentContext >& xContext ):m_xContext( xContext )
+ {
+ uno::Reference< container::XEnumeration > xEnum = new WindowComponentEnumImpl( m_xContext );
+ sal_Int32 nIndex=0;
+ while( xEnum->hasMoreElements() )
+ {
+ uno::Reference< sheet::XSpreadsheetDocument > xNext( xEnum->nextElement(), uno::UNO_QUERY );
+ if ( xNext.is() )
+ {
+ m_windows.push_back( xNext );
+ uno::Reference< frame::XModel > xModel( xNext, uno::UNO_QUERY_THROW ); // that the spreadsheetdocument is a xmodel is a given
+ // !! TODO !! iterate over all controllers
+ uno::Reference< frame::XController > xController( xModel->getCurrentController(), uno::UNO_SET_THROW );
+ uno::Reference< XHelperInterface > xTemp; // temporary needed for g++ 3.3.5
+ rtl::Reference< ScVbaWindow > window( new ScVbaWindow( xTemp, m_xContext, xModel, xController ) );
+ OUString sCaption;
+ window->getCaption() >>= sCaption;
+ namesToIndices[ sCaption ] = nIndex++;
+ }
+ }
+
+ }
+
+ //XEnumerationAccess
+ virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) override
+ {
+ return new WindowComponentEnumImpl( m_xContext, std::vector(m_windows) );
+ }
+ // XIndexAccess
+ virtual ::sal_Int32 SAL_CALL getCount( ) override
+ {
+ return m_windows.size();
+ }
+ virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override
+ {
+ if ( Index < 0
+ || o3tl::make_unsigned( Index ) >= m_windows.size() )
+ throw lang::IndexOutOfBoundsException();
+ return css::uno::Any( m_windows[ Index ] ); // returns xspreadsheetdoc
+ }
+
+ //XElementAccess
+ virtual uno::Type SAL_CALL getElementType( ) override
+ {
+ return cppu::UnoType<sheet::XSpreadsheetDocument>::get();
+ }
+
+ virtual sal_Bool SAL_CALL hasElements( ) override
+ {
+ return ( !m_windows.empty() );
+ }
+
+ //XNameAccess
+ virtual uno::Any SAL_CALL getByName( const OUString& aName ) override
+ {
+ NameIndexHash::const_iterator it = namesToIndices.find( aName );
+ if ( it == namesToIndices.end() )
+ throw container::NoSuchElementException();
+ return css::uno::Any( m_windows[ it->second ] );
+
+ }
+
+ virtual uno::Sequence< OUString > SAL_CALL getElementNames( ) override
+ {
+ return comphelper::mapKeysToSequence( namesToIndices );
+ }
+
+ virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override
+ {
+ NameIndexHash::const_iterator it = namesToIndices.find( aName );
+ return (it != namesToIndices.end());
+ }
+
+};
+
+}
+
+ScVbaWindows::ScVbaWindows( const uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext ) : ScVbaWindows_BASE( xParent, xContext, uno::Reference< container::XIndexAccess > ( new WindowsAccessImpl( xContext ) ) )
+{
+}
+uno::Reference< container::XEnumeration >
+ScVbaWindows::createEnumeration()
+{
+ return new WindowEnumImpl( mxContext, Application() );
+}
+
+uno::Any
+ScVbaWindows::createCollectionObject( const css::uno::Any& aSource )
+{
+ return ComponentToWindow( aSource, mxContext, Application() );
+}
+
+uno::Type
+ScVbaWindows::getElementType()
+{
+ return cppu::UnoType<excel::XWindows>::get();
+}
+
+void SAL_CALL
+ScVbaWindows::Arrange( ::sal_Int32 /*ArrangeStyle*/, const uno::Any& /*ActiveWorkbook*/, const uno::Any& /*SyncHorizontal*/, const uno::Any& /*SyncVertical*/ )
+{
+ //#TODO #FIXME see what can be done for an implementation here
+}
+
+OUString
+ScVbaWindows::getServiceImplName()
+{
+ return "ScVbaWindows";
+}
+
+css::uno::Sequence<OUString>
+ScVbaWindows::getServiceNames()
+{
+ static uno::Sequence< OUString > const sNames
+ {
+ "ooo.vba.excel.Windows"
+ };
+ return sNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbawindows.hxx b/sc/source/ui/vba/vbawindows.hxx
new file mode 100644
index 000000000..b827bf7e4
--- /dev/null
+++ b/sc/source/ui/vba/vbawindows.hxx
@@ -0,0 +1,48 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <ooo/vba/excel/XWindows.hpp>
+
+#include <vbahelper/vbacollectionimpl.hxx>
+
+namespace com::sun::star::uno { class XComponentContext; }
+
+typedef CollTestImplHelper< ov::excel::XWindows > ScVbaWindows_BASE;
+
+class ScVbaWindows : public ScVbaWindows_BASE
+{
+public:
+ ScVbaWindows( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext );
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+
+ // XWindows
+ virtual void SAL_CALL Arrange( ::sal_Int32 ArrangeStyle, const css::uno::Any& ActiveWorkbook, const css::uno::Any& SyncHorizontal, const css::uno::Any& SyncVertical ) override;
+ // ScVbaCollectionBaseImpl
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaworkbook.cxx b/sc/source/ui/vba/vbaworkbook.cxx
new file mode 100644
index 000000000..23cc523a1
--- /dev/null
+++ b/sc/source/ui/vba/vbaworkbook.cxx
@@ -0,0 +1,420 @@
+/* -*- 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 <comphelper/propertyvalue.hxx>
+#include <tools/urlobj.hxx>
+
+#include <com/sun/star/util/XProtectable.hpp>
+#include <com/sun/star/sheet/XNamedRanges.hpp>
+#include <com/sun/star/sheet/XSpreadsheetView.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <ooo/vba/excel/XlFileFormat.hpp>
+#include <ooo/vba/excel/XApplication.hpp>
+
+#include "vbaworksheet.hxx"
+#include "vbaworksheets.hxx"
+#include "vbaworkbook.hxx"
+#include "vbawindows.hxx"
+#include "vbastyles.hxx"
+#include "excelvbahelper.hxx"
+#include "vbapalette.hxx"
+#include <osl/file.hxx>
+#include "vbanames.hxx"
+#include <docoptio.hxx>
+#include <docsh.hxx>
+
+// Much of the impl. for the equivalent UNO module is
+// sc/source/ui/unoobj/docuno.cxx, viewuno.cxx
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+uno::Sequence< sal_Int32 > ScVbaWorkbook::ColorData;
+
+void SAL_CALL
+ScVbaWorkbook::ResetColors( )
+{
+ uno::Reference< container::XIndexAccess > xIndexAccess( ScVbaPalette::getDefaultPalette(), uno::UNO_SET_THROW );
+ sal_Int32 nLen = xIndexAccess->getCount();
+ ColorData.realloc( nLen );
+
+ sal_Int32* pDest = ColorData.getArray();
+ for ( sal_Int32 index=0; index < nLen; ++pDest, ++index )
+ xIndexAccess->getByIndex( index ) >>= *pDest;
+}
+
+::uno::Any SAL_CALL
+ScVbaWorkbook::Colors( const ::uno::Any& Index )
+{
+ uno::Any aRet;
+ if ( Index.hasValue() )
+ {
+ sal_Int32 nIndex = 0;
+ Index >>= nIndex;
+ aRet <<= XLRGBToOORGB( ColorData[ --nIndex ] );
+ }
+ else
+ aRet <<= ColorData;
+ return aRet;
+}
+
+bool ScVbaWorkbook::setFilterPropsFromFormat( sal_Int32 nFormat, uno::Sequence< beans::PropertyValue >& rProps )
+{
+ auto [begin, end] = asNonConstRange(rProps);
+ auto pProp = std::find_if(begin, end,
+ [](const beans::PropertyValue& rProp) { return rProp.Name == "FilterName"; });
+ bool bRes = pProp != end;
+ if (bRes)
+ {
+ switch( nFormat )
+ {
+ case excel::XlFileFormat::xlCSV:
+ pProp->Value <<= OUString(SC_TEXT_CSV_FILTER_NAME);
+ break;
+ case excel::XlFileFormat::xlDBF4:
+ pProp->Value <<= OUString("DBF");
+ break;
+ case excel::XlFileFormat::xlDIF:
+ pProp->Value <<= OUString("DIF");
+ break;
+ case excel::XlFileFormat::xlWK3:
+ pProp->Value <<= OUString("Lotus");
+ break;
+ case excel::XlFileFormat::xlExcel4Workbook:
+ pProp->Value <<= OUString("MS Excel 4.0");
+ break;
+ case excel::XlFileFormat::xlExcel5:
+ pProp->Value <<= OUString("MS Excel 5.0/95");
+ break;
+ case excel::XlFileFormat::xlHtml:
+ pProp->Value <<= OUString("HTML (StarCalc)");
+ break;
+ case excel::XlFileFormat::xlExcel9795:
+ default:
+ pProp->Value <<= OUString("MS Excel 97");
+ break;
+ }
+ }
+ return bRes;
+}
+
+::sal_Int32 SAL_CALL
+ScVbaWorkbook::getFileFormat( )
+{
+ sal_Int32 aFileFormat = 0;
+ OUString aFilterName;
+ uno::Sequence< beans::PropertyValue > aArgs = getModel()->getArgs();
+
+ // #FIXME - seems suspect should we not walk through the properties
+ // to find the FilterName
+ if ( aArgs[0].Name == "FilterName" ) {
+ aArgs[0].Value >>= aFilterName;
+ } else {
+ aArgs[1].Value >>= aFilterName;
+ }
+
+ if (aFilterName == SC_TEXT_CSV_FILTER_NAME) {
+ aFileFormat = excel::XlFileFormat::xlCSV; //xlFileFormat.
+ }
+
+ if ( aFilterName == "DBF" ) {
+ aFileFormat = excel::XlFileFormat::xlDBF4;
+ }
+
+ if ( aFilterName == "DIF" ) {
+ aFileFormat = excel::XlFileFormat::xlDIF;
+ }
+
+ if ( aFilterName == "Lotus" ) {
+ aFileFormat = excel::XlFileFormat::xlWK3;
+ }
+
+ if ( aFilterName == "MS Excel 4.0" ) {
+ aFileFormat = excel::XlFileFormat::xlExcel4Workbook;
+ }
+
+ if ( aFilterName == "MS Excel 5.0/95" ) {
+ aFileFormat = excel::XlFileFormat::xlExcel5;
+ }
+
+ if ( aFilterName == "MS Excel 97" ) {
+ aFileFormat = excel::XlFileFormat::xlExcel9795;
+ }
+
+ if (aFilterName == "HTML (StarCalc)") {
+ aFileFormat = excel::XlFileFormat::xlHtml;
+ }
+
+ if ( aFilterName == "calc_StarOffice_XML_Calc_Template" ) {
+ aFileFormat = excel::XlFileFormat::xlTemplate;
+ }
+
+ if (aFilterName == "StarOffice XML (Calc)") {
+ aFileFormat = excel::XlFileFormat::xlWorkbookNormal;
+ }
+ if ( aFilterName == "calc8" ) {
+ aFileFormat = excel::XlFileFormat::xlWorkbookNormal;
+ }
+
+ return aFileFormat;
+}
+
+void
+ScVbaWorkbook::init()
+{
+ if ( !ColorData.hasElements() )
+ ResetColors();
+ uno::Reference< frame::XModel > xModel = getModel();
+ if ( xModel.is() )
+ excel::getDocShell( xModel )->RegisterAutomationWorkbookObject( this );
+}
+
+ScVbaWorkbook::ScVbaWorkbook( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, css::uno::Reference< css::frame::XModel > const & xModel ) : ScVbaWorkbook_BASE( xParent, xContext, xModel )
+{
+ init();
+}
+
+ScVbaWorkbook::ScVbaWorkbook( uno::Sequence< uno::Any> const & args,
+ uno::Reference< uno::XComponentContext> const & xContext ) : ScVbaWorkbook_BASE( args, xContext )
+{
+ init();
+}
+
+uno::Reference< excel::XWorksheet >
+ScVbaWorkbook::getActiveSheet()
+{
+ uno::Reference< frame::XModel > xModel( getCurrentExcelDoc( mxContext ), uno::UNO_SET_THROW );
+ uno::Reference< sheet::XSpreadsheetView > xView( xModel->getCurrentController(), uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XSpreadsheet > xSheet( xView->getActiveSheet(), uno::UNO_SET_THROW );
+ // #162503# return the original sheet module wrapper object, instead of a new instance
+ uno::Reference< excel::XWorksheet > xWorksheet( excel::getUnoSheetModuleObj( xSheet ), uno::UNO_QUERY );
+ if( xWorksheet.is() ) return xWorksheet;
+ // #i116936# excel::getUnoSheetModuleObj() may return null in documents without global VBA mode enabled
+ return new ScVbaWorksheet( this, mxContext, xSheet, xModel );
+}
+
+uno::Any SAL_CALL
+ScVbaWorkbook::Sheets( const uno::Any& aIndex )
+{
+ return Worksheets( aIndex );
+}
+
+uno::Any SAL_CALL
+ScVbaWorkbook::Worksheets( const uno::Any& aIndex )
+{
+ uno::Reference< frame::XModel > xModel( getModel() );
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( xModel, uno::UNO_QUERY_THROW );
+ uno::Reference<container::XIndexAccess > xSheets( xSpreadDoc->getSheets(), uno::UNO_QUERY_THROW );
+ uno::Reference< XCollection > xWorkSheets( new ScVbaWorksheets( this, mxContext, xSheets, xModel ) );
+ if ( aIndex.getValueTypeClass() == uno::TypeClass_VOID )
+ {
+ return uno::Any( xWorkSheets );
+ }
+ // pass on to collection
+ return xWorkSheets->Item( aIndex, uno::Any() );
+}
+uno::Any SAL_CALL
+ScVbaWorkbook::Windows( const uno::Any& aIndex )
+{
+
+ uno::Reference< excel::XWindows > xWindows( new ScVbaWindows( getParent(), mxContext ) );
+ if ( aIndex.getValueTypeClass() == uno::TypeClass_VOID )
+ return uno::Any( xWindows );
+ return xWindows->Item( aIndex, uno::Any() );
+}
+
+void SAL_CALL
+ScVbaWorkbook::Activate()
+{
+ VbaDocumentBase::Activate();
+}
+
+void
+ScVbaWorkbook::Protect( const uno::Any &aPassword )
+{
+ VbaDocumentBase::Protect( aPassword );
+}
+
+sal_Bool
+ScVbaWorkbook::getProtectStructure()
+{
+ uno::Reference< util::XProtectable > xProt( getModel(), uno::UNO_QUERY_THROW );
+ return xProt->isProtected();
+}
+
+sal_Bool SAL_CALL ScVbaWorkbook::getPrecisionAsDisplayed()
+{
+ uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_SET_THROW );
+ ScDocument& rDoc = excel::getDocShell( xModel )->GetDocument();
+ return rDoc.GetDocOptions().IsCalcAsShown();
+}
+
+void SAL_CALL ScVbaWorkbook::setPrecisionAsDisplayed( sal_Bool _precisionAsDisplayed )
+{
+ uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_SET_THROW );
+ ScDocument& rDoc = excel::getDocShell( xModel )->GetDocument();
+ ScDocOptions aOpt = rDoc.GetDocOptions();
+ aOpt.SetCalcAsShown( _precisionAsDisplayed );
+ rDoc.SetDocOptions( aOpt );
+}
+
+OUString SAL_CALL ScVbaWorkbook::getAuthor()
+{
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS( getModel(), uno::UNO_QUERY );
+ if (!xDPS.is())
+ return "?";
+ uno::Reference<document::XDocumentProperties> xDocProps = xDPS->getDocumentProperties();
+ return xDocProps->getAuthor();
+}
+
+void SAL_CALL ScVbaWorkbook::setAuthor( const OUString& _author )
+{
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS( getModel(), uno::UNO_QUERY );
+ if (!xDPS.is())
+ return;
+ uno::Reference<document::XDocumentProperties> xDocProps = xDPS->getDocumentProperties();
+ xDocProps->setAuthor( _author );
+}
+
+void
+ScVbaWorkbook::SaveCopyAs( const OUString& sFileName )
+{
+ OUString aURL;
+ osl::FileBase::getFileURLFromSystemPath( sFileName, aURL );
+ uno::Reference< frame::XStorable > xStor( getModel(), uno::UNO_QUERY_THROW );
+ uno::Sequence< beans::PropertyValue > storeProps{ comphelper::makePropertyValue(
+ "FilterName", OUString( "MS Excel 97" )) };
+ xStor->storeToURL( aURL, storeProps );
+}
+
+void SAL_CALL
+ScVbaWorkbook::SaveAs( const uno::Any& FileName, const uno::Any& FileFormat, const uno::Any& /*Password*/, const uno::Any& /*WriteResPassword*/, const uno::Any& /*ReadOnlyRecommended*/, const uno::Any& /*CreateBackup*/, const uno::Any& /*AccessMode*/, const uno::Any& /*ConflictResolution*/, const uno::Any& /*AddToMru*/, const uno::Any& /*TextCodepage*/, const uno::Any& /*TextVisualLayout*/, const uno::Any& /*Local*/ )
+{
+ OUString sFileName;
+ FileName >>= sFileName;
+ OUString sURL;
+ osl::FileBase::getFileURLFromSystemPath( sFileName, sURL );
+ // detect if there is no path then we need
+ // to use the current folder
+ INetURLObject aURL( sURL );
+ sURL = aURL.GetMainURL( INetURLObject::DecodeMechanism::ToIUri );
+ if( sURL.isEmpty() )
+ {
+ // need to add cur dir ( of this workbook ) or else the 'Work' dir
+ sURL = getModel()->getURL();
+
+ if ( sURL.isEmpty() )
+ {
+ // not path available from 'this' document
+ // need to add the 'document'/work directory then
+ uno::Reference< excel::XApplication > xApplication ( Application(),uno::UNO_QUERY_THROW );
+ OUString sWorkPath = xApplication->getDefaultFilePath();
+ OUString sWorkURL;
+ osl::FileBase::getFileURLFromSystemPath( sWorkPath, sWorkURL );
+ aURL.SetURL( sWorkURL );
+ }
+ else
+ {
+ aURL.SetURL( sURL );
+ aURL.Append( sFileName );
+ }
+ sURL = aURL.GetMainURL( INetURLObject::DecodeMechanism::ToIUri );
+
+ }
+
+ sal_Int32 nFileFormat = excel::XlFileFormat::xlExcel9795;
+ FileFormat >>= nFileFormat;
+
+ uno::Sequence storeProps{ comphelper::makePropertyValue("FilterName", uno::Any()) };
+ setFilterPropsFromFormat( nFileFormat, storeProps );
+
+ uno::Reference< frame::XStorable > xStor( getModel(), uno::UNO_QUERY_THROW );
+ xStor->storeAsURL( sURL, storeProps );
+}
+
+css::uno::Any SAL_CALL
+ScVbaWorkbook::Styles( const uno::Any& Item )
+{
+ // quick look and Styles object doesn't seem to have a valid parent
+ // or a least the object browser just shows an object that has no
+ // variables ( therefore... leave as NULL for now )
+ uno::Reference< XCollection > dStyles = new ScVbaStyles( uno::Reference< XHelperInterface >(), mxContext, getModel() );
+ if ( Item.hasValue() )
+ return dStyles->Item( Item, uno::Any() );
+ return uno::Any( dStyles );
+}
+
+uno::Any SAL_CALL
+ScVbaWorkbook::Names( const uno::Any& aIndex )
+{
+ uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_SET_THROW );
+ uno::Reference< beans::XPropertySet > xProps( xModel, uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XNamedRanges > xNamedRanges( xProps->getPropertyValue("NamedRanges"), uno::UNO_QUERY_THROW );
+ uno::Reference< XCollection > xNames( new ScVbaNames( this, mxContext, xNamedRanges, xModel ) );
+ if ( aIndex.hasValue() )
+ return xNames->Item( aIndex, uno::Any() );
+ return uno::Any( xNames );
+}
+
+OUString
+ScVbaWorkbook::getServiceImplName()
+{
+ return "ScVbaWorkbook";
+}
+
+uno::Sequence< OUString >
+ScVbaWorkbook::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.Workbook"
+ };
+ return aServiceNames;
+}
+
+OUString SAL_CALL
+ScVbaWorkbook::getCodeName()
+{
+ uno::Reference< beans::XPropertySet > xModelProp( getModel(), uno::UNO_QUERY_THROW );
+ return xModelProp->getPropertyValue("CodeName").get< OUString >();
+}
+
+sal_Int64
+ScVbaWorkbook::getSomething(const uno::Sequence<sal_Int8 >& rId )
+{
+ if (comphelper::isUnoTunnelId<ScVbaWorksheet>(rId)) // ???
+ {
+ return comphelper::getSomething_cast(this);
+ }
+ return 0;
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+Calc_ScVbaWorkbook_get_implementation(
+ css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& args)
+{
+ return cppu::acquire(new ScVbaWorkbook(args, context));
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaworkbook.hxx b/sc/source/ui/vba/vbaworkbook.hxx
new file mode 100644
index 000000000..886f771bf
--- /dev/null
+++ b/sc/source/ui/vba/vbaworkbook.hxx
@@ -0,0 +1,73 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <com/sun/star/frame/XModel.hpp>
+#include <ooo/vba/excel/XWorkbook.hpp>
+#include <cppuhelper/implbase.hxx>
+#include <vbahelper/vbadocumentbase.hxx>
+
+typedef cppu::ImplInheritanceHelper< VbaDocumentBase, ov::excel::XWorkbook > ScVbaWorkbook_BASE;
+
+class ScVbaWorkbook : public ScVbaWorkbook_BASE
+{
+ static css::uno::Sequence< sal_Int32 > ColorData;
+ static bool setFilterPropsFromFormat( sal_Int32 nFormat, css::uno::Sequence< css::beans::PropertyValue >& rProps );
+ void init();
+
+public:
+ ScVbaWorkbook( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ css::uno::Reference< css::frame::XModel > const & xModel );
+ ScVbaWorkbook( css::uno::Sequence< css::uno::Any > const& aArgs, css::uno::Reference< css::uno::XComponentContext >const& xContext );
+
+ // Attributes
+ virtual sal_Bool SAL_CALL getProtectStructure() override;
+ virtual css::uno::Reference< ov::excel::XWorksheet > SAL_CALL getActiveSheet() override;
+ virtual sal_Bool SAL_CALL getPrecisionAsDisplayed() override;
+ virtual void SAL_CALL setPrecisionAsDisplayed( sal_Bool _precisionAsDisplayed ) override;
+ virtual OUString SAL_CALL getAuthor() override;
+ virtual void SAL_CALL setAuthor( const OUString& _author ) override;
+
+ // Methods
+ virtual css::uno::Any SAL_CALL Worksheets( const css::uno::Any& aIndex ) override;
+ virtual css::uno::Any SAL_CALL Sheets( const css::uno::Any& aIndex ) override;
+ virtual css::uno::Any SAL_CALL Windows( const css::uno::Any& aIndex ) override;
+ virtual void SAL_CALL Activate() override;
+ virtual void SAL_CALL Protect( const css::uno::Any & aPassword ) override;
+ virtual void SAL_CALL SaveAs( const css::uno::Any& FileName, const css::uno::Any& FileFormat, const css::uno::Any& Password, const css::uno::Any& WriteResPassword, const css::uno::Any& ReadOnlyRecommended, const css::uno::Any& CreateBackup, const css::uno::Any& AccessMode, const css::uno::Any& ConflictResolution, const css::uno::Any& AddToMru, const css::uno::Any& TextCodepage, const css::uno::Any& TextVisualLayout, const css::uno::Any& Local ) override;
+ virtual css::uno::Any SAL_CALL Names( const css::uno::Any& aIndex ) override;
+
+ virtual css::uno::Any SAL_CALL Styles( const css::uno::Any& Item ) override;
+ virtual void SAL_CALL ResetColors( ) override;
+ virtual css::uno::Any SAL_CALL Colors( const css::uno::Any& Index ) override;
+ virtual ::sal_Int32 SAL_CALL getFileFormat( ) override;
+ virtual void SAL_CALL SaveCopyAs( const OUString& Filename ) override;
+
+ // code name
+ virtual OUString SAL_CALL getCodeName() override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+
+ // XUnoTunnel
+ virtual ::sal_Int64 SAL_CALL getSomething(const css::uno::Sequence<sal_Int8 >& rId ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaworkbooks.cxx b/sc/source/ui/vba/vbaworkbooks.cxx
new file mode 100644
index 000000000..e3b608b33
--- /dev/null
+++ b/sc/source/ui/vba/vbaworkbooks.cxx
@@ -0,0 +1,291 @@
+/* -*- 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/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/document/XTypeDetection.hpp>
+
+#include <tools/urlobj.hxx>
+
+#include "excelvbahelper.hxx"
+#include "vbaworkbook.hxx"
+#include "vbaworkbooks.hxx"
+#include <vbahelper/vbahelper.hxx>
+
+#include <comphelper/propertyvalue.hxx>
+#include <o3tl/string_view.hxx>
+#include <osl/file.hxx>
+#include <rtl/ref.hxx>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+const sal_Int16 CUSTOM_CHAR = 5;
+
+static uno::Any
+getWorkbook( const uno::Reference< uno::XComponentContext >& xContext,
+ const uno::Reference< sheet::XSpreadsheetDocument > &xDoc,
+ const uno::Reference< XHelperInterface >& xParent )
+{
+ // FIXME: fine as long as ScVbaWorkbook is stateless ...
+ uno::Reference< frame::XModel > xModel( xDoc, uno::UNO_QUERY );
+ if( !xModel.is() )
+ return uno::Any();
+
+ uno::Reference< excel::XWorkbook > xWb( getVBADocument( xModel ), uno::UNO_QUERY );
+ if ( xWb.is() )
+ {
+ return uno::Any( xWb );
+ }
+
+ rtl::Reference<ScVbaWorkbook> pWb = new ScVbaWorkbook( xParent, xContext, xModel );
+ return uno::Any( uno::Reference< excel::XWorkbook > (pWb) );
+}
+
+namespace {
+
+class WorkBookEnumImpl : public EnumerationHelperImpl
+{
+public:
+ /// @throws uno::RuntimeException
+ WorkBookEnumImpl( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ) {}
+
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ uno::Reference< sheet::XSpreadsheetDocument > xDoc( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW );
+ return getWorkbook( m_xContext, xDoc, m_xParent );
+ }
+
+};
+
+}
+
+ScVbaWorkbooks::ScVbaWorkbooks( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< css::uno::XComponentContext >& xContext ) : ScVbaWorkbooks_BASE( xParent, xContext, VbaDocumentsBase::EXCEL_DOCUMENT )
+{
+}
+// XEnumerationAccess
+uno::Type
+ScVbaWorkbooks::getElementType()
+{
+ return cppu::UnoType<excel::XWorkbook>::get();
+}
+uno::Reference< container::XEnumeration >
+ScVbaWorkbooks::createEnumeration()
+{
+ // #FIXME it's possible the WorkBookEnumImpl here doesn't reflect
+ // the state of this object ( although it should ) would be
+ // safer to create an enumeration based on this objects state
+ // rather than one effectively based of the desktop component
+ uno::Reference< container::XEnumerationAccess > xEnumerationAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
+ return new WorkBookEnumImpl( mxParent, mxContext, xEnumerationAccess->createEnumeration() );
+}
+
+uno::Any
+ScVbaWorkbooks::createCollectionObject( const css::uno::Any& aSource )
+{
+ uno::Reference< sheet::XSpreadsheetDocument > xDoc( aSource, uno::UNO_QUERY_THROW );
+ return getWorkbook( mxContext, xDoc, mxParent );
+}
+
+uno::Any SAL_CALL
+ScVbaWorkbooks::Add( const uno::Any& Template )
+{
+ uno::Reference< sheet::XSpreadsheetDocument > xSpreadDoc;
+ sal_Int32 nWorkbookType = 0;
+ OUString aTemplateFileName;
+ if( Template >>= nWorkbookType )
+ {
+ // nWorkbookType is a constant from XlWBATemplate (added in Excel 2007)
+ // TODO: create chart-sheet if supported by Calc
+
+ xSpreadDoc.set( createDocument(), uno::UNO_QUERY_THROW );
+ // create a document with one sheet only
+ uno::Reference< sheet::XSpreadsheets > xSheets( xSpreadDoc->getSheets(), uno::UNO_SET_THROW );
+ uno::Reference< container::XIndexAccess > xSheetsIA( xSheets, uno::UNO_QUERY_THROW );
+ while( xSheetsIA->getCount() > 1 )
+ {
+ uno::Reference< container::XNamed > xSheetName( xSheetsIA->getByIndex( xSheetsIA->getCount() - 1 ), uno::UNO_QUERY_THROW );
+ xSheets->removeByName( xSheetName->getName() );
+ }
+ }
+ else if( Template >>= aTemplateFileName )
+ {
+ // TODO: create document from template
+ xSpreadDoc.set( createDocument(), uno::UNO_QUERY_THROW );
+ }
+ else if( !Template.hasValue() )
+ {
+ // regular spreadsheet document with configured number of sheets
+ xSpreadDoc.set( createDocument(), uno::UNO_QUERY_THROW );
+ }
+ else
+ {
+ // illegal argument
+ throw uno::RuntimeException();
+ }
+
+ // need to set up the document modules ( and vba mode ) here
+ excel::setUpDocumentModules( xSpreadDoc );
+ if (!xSpreadDoc.is())
+ return uno::Any();
+
+ uno::Any aRet = getWorkbook( mxContext, xSpreadDoc, mxParent );
+ uno::Reference< excel::XWorkbook > xWBook( aRet, uno::UNO_QUERY );
+ if (xWBook.is())
+ xWBook->Activate();
+ return aRet;
+}
+
+void SAL_CALL
+ScVbaWorkbooks::Close()
+{
+}
+
+bool
+ScVbaWorkbooks::isTextFile( std::u16string_view sType )
+{
+ // will return true if the file is
+ // a) a variant of a text file
+ // b) a csv file
+ // c) unknown
+ // returning true basically means treat this like a csv file
+ return sType == u"generic_Text" || sType.empty();
+}
+
+bool
+ScVbaWorkbooks::isSpreadSheetFile( std::u16string_view sType )
+{
+ // include calc_QPro etc. ? ( not for the moment anyway )
+ return o3tl::starts_with( sType, u"calc_MS" )
+ || o3tl::starts_with( sType, u"MS Excel" )
+ || o3tl::starts_with( sType, u"calc8" )
+ || o3tl::starts_with( sType, u"calc_StarOffice" );
+}
+
+OUString
+ScVbaWorkbooks::getFileFilterType( const OUString& rFileName )
+{
+ uno::Reference< document::XTypeDetection > xTypeDetect( mxContext->getServiceManager()->createInstanceWithContext("com.sun.star.document.TypeDetection", mxContext), uno::UNO_QUERY_THROW );
+ uno::Sequence aMediaDesc{ comphelper::makePropertyValue("URL", rFileName) };
+ OUString sType = xTypeDetect->queryTypeByDescriptor( aMediaDesc, true );
+ return sType;
+}
+
+// #TODO# #FIXME# can any of the unused params below be used?
+uno::Any SAL_CALL
+ScVbaWorkbooks::Open( const OUString& rFileName, const uno::Any& /*UpdateLinks*/, const uno::Any& ReadOnly, const uno::Any& Format, const uno::Any& /*Password*/, const uno::Any& /*WriteResPassword*/, const uno::Any& /*IgnoreReadOnlyRecommended*/, const uno::Any& /*Origin*/, const uno::Any& Delimiter, const uno::Any& /*Editable*/, const uno::Any& /*Notify*/, const uno::Any& /*Converter*/, const uno::Any& /*AddToMru*/ )
+{
+ // we need to detect if this is a URL, if not then assume it's a file path
+ OUString aURL;
+ INetURLObject aObj;
+ aObj.SetURL( rFileName );
+ bool bIsURL = aObj.GetProtocol() != INetProtocol::NotValid;
+ if ( bIsURL )
+ aURL = rFileName;
+ else
+ osl::FileBase::getFileURLFromSystemPath( rFileName, aURL );
+
+ uno::Sequence< beans::PropertyValue > sProps;
+
+ OUString sType = getFileFilterType( aURL );
+ // A text file means it needs to be processed as a csv file
+ if ( isTextFile( sType ) )
+ {
+ // Values for format
+ // 1 Tabs
+ // 2 Commas
+ // 3 Spaces
+ // 4 Semicolons
+ // 5 Nothing
+ // 6 Custom character (see the Delimiter argument
+ // no format means use the current delimiter
+ sal_Int16 const delims[] { 0 /*default not used*/, 9/*tab*/, 44/*comma*/, 32/*space*/, 59/*semicolon*/ };
+
+ OUString sFormat;
+ sal_Int16 nFormat = 0; // default indicator
+
+ if ( Format.hasValue() )
+ {
+ Format >>= nFormat; // val of nFormat overwritten if extracted
+ // validate param
+ if ( nFormat < 1 || nFormat > 6 )
+ throw uno::RuntimeException("Illegal value for Format" );
+ }
+
+ sal_Int16 nDelim = getCurrentDelim();
+
+ if ( nFormat > 0 && nFormat < CUSTOM_CHAR )
+ {
+ nDelim = delims[ nFormat ];
+ }
+ else if ( nFormat > CUSTOM_CHAR )
+ {
+ // Need to check Delimiter param
+ if ( !Delimiter.hasValue() )
+ throw uno::RuntimeException("Expected value for Delimiter" );
+ OUString sStr;
+ Delimiter >>= sStr;
+ if ( sStr.isEmpty() )
+ throw uno::RuntimeException("Incorrect value for Delimiter" );
+
+ nDelim = sStr[0];
+
+ }
+
+ getCurrentDelim() = nDelim; //set new current
+
+ sFormat = OUString::number( nDelim ) + ",34,0,1";
+
+ sProps = { comphelper::makePropertyValue("FilterOptions", sFormat),
+ comphelper::makePropertyValue("FilterName", OUString( SC_TEXT_CSV_FILTER_NAME )),
+ // Ensure WORKAROUND_CSV_TXT_BUG_i60158 gets called in typedetection.cxx so
+ // csv is forced for deep detected 'writerxxx' types
+ comphelper::makePropertyValue(
+ "DocumentService", OUString("com.sun.star.sheet.SpreadsheetDocument")) };
+ }
+ else if ( !isSpreadSheetFile( sType ) )
+ throw uno::RuntimeException("Bad Format" );
+
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( openDocument( rFileName, ReadOnly, sProps ), uno::UNO_QUERY_THROW );
+ uno::Any aRet = getWorkbook( mxContext, xSpreadDoc, mxParent );
+ uno::Reference< excel::XWorkbook > xWBook( aRet, uno::UNO_QUERY );
+ if ( xWBook.is() )
+ xWBook->Activate();
+ return aRet;
+}
+
+OUString
+ScVbaWorkbooks::getServiceImplName()
+{
+ return "ScVbaWorkbooks";
+}
+
+css::uno::Sequence<OUString>
+ScVbaWorkbooks::getServiceNames()
+{
+ static uno::Sequence< OUString > const sNames
+ {
+ "ooo.vba.excel.Workbooks"
+ };
+ return sNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaworkbooks.hxx b/sc/source/ui/vba/vbaworkbooks.hxx
new file mode 100644
index 000000000..45d41757a
--- /dev/null
+++ b/sc/source/ui/vba/vbaworkbooks.hxx
@@ -0,0 +1,56 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include <cppuhelper/implbase.hxx>
+#include <ooo/vba/excel/XWorkbooks.hpp>
+#include <vbahelper/vbadocumentsbase.hxx>
+
+typedef cppu::ImplInheritanceHelper< VbaDocumentsBase, ov::excel::XWorkbooks > ScVbaWorkbooks_BASE;
+
+class ScVbaWorkbooks : public ScVbaWorkbooks_BASE
+{
+private:
+ OUString getFileFilterType( const OUString& rString );
+ static bool isTextFile( std::u16string_view rString );
+ static bool isSpreadSheetFile( std::u16string_view rString );
+ static sal_Int16& getCurrentDelim(){ static sal_Int16 nDelim = 44; return nDelim; }
+public:
+ ScVbaWorkbooks( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext );
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+
+ // ScVbaWorkbooks_BASE
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+
+ // XWorkbooks
+ virtual css::uno::Any SAL_CALL Add( const css::uno::Any& Template ) override;
+ virtual void SAL_CALL Close( ) override;
+ virtual css::uno::Any SAL_CALL Open( const OUString& Filename, const css::uno::Any& UpdateLinks, const css::uno::Any& ReadOnly, const css::uno::Any& Format, const css::uno::Any& Password, const css::uno::Any& WriteResPassword, const css::uno::Any& IgnoreReadOnlyRecommended, const css::uno::Any& Origin, const css::uno::Any& Delimiter, const css::uno::Any& Editable, const css::uno::Any& Notify, const css::uno::Any& Converter, const css::uno::Any& AddToMru ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaworksheet.cxx b/sc/source/ui/vba/vbaworksheet.cxx
new file mode 100644
index 000000000..c51284427
--- /dev/null
+++ b/sc/source/ui/vba/vbaworksheet.cxx
@@ -0,0 +1,1052 @@
+/* -*- 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 <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( "getNewSpreadsheetName() xSpreadDoc is null", 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( "removeAllSheets() xSpreadDoc is null", 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
+ {
+ uno::Reference< uno::XComponentContext > xContext(
+ comphelper::getProcessComponentContext() );
+
+ uno::Reference <frame::XDesktop2 > xComponentLoader = frame::Desktop::create(xContext);
+
+ uno::Reference<lang::XComponent > xComponent( xComponentLoader->loadComponentFromURL(
+ "private:factory/scalc",
+ "_blank", 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,
+ const uno::Reference< sheet::XSpreadsheet >& xSheet,
+ const uno::Reference< frame::XModel >& xModel ) : WorksheetImpl_BASE( xParent, xContext ), mxSheet( xSheet ), mxModel(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;
+ 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, true, true );
+ }
+ }
+ // 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( "IsVisible" ) >>= 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( "IsVisible", 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("Sheet Name does not exist." );
+
+ uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_SET_THROW );
+ ScDocument& rDoc = excel::getDocShell( xModel )->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("Sheet Name does not exist." );
+
+ uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_SET_THROW );
+ ScDocument& rDoc = excel::getDocShell( xModel )->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()
+{
+ uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_SET_THROW );
+ ScDocument& rDoc = excel::getDocShell( xModel )->GetDocument();
+ ScDBData* pDBData = rDoc.GetAnonymousDBData(getSheetID());
+ if (pDBData)
+ return pDBData->HasAutoFilter();
+ return false;
+}
+
+void SAL_CALL ScVbaWorksheet::setAutoFilterMode( sal_Bool bAutoFilterMode )
+{
+ uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_SET_THROW );
+ ScDocShell* pDocShell = excel::getDocShell( xModel );
+ 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 )
+ {
+ uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_SET_THROW );
+ ScDocument& rDoc = excel::getDocShell( xModel )->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,".uno:SpellDialog");
+}
+
+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 );
+ ScDocument& rDoc = excel::getDocShell( xModel )->GetDocument();
+ return ScVbaRange::CellsHelper( rDoc, this, mxContext, xRange, nRow, nCol );
+}
+
+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() )
+ {
+ uno::Reference< XCollection > xColl( mxCharts, uno::UNO_QUERY_THROW );
+ return xColl->Item( Index, uno::Any() );
+ }
+ else
+ return uno::Any( 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("NamedRanges"), 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 );
+ 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("Unsupported"); // 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("ooo.vba.ControlProvider", 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();
+ for( int 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 "ScVbaWorksheet";
+}
+
+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
+ {
+ "ooo.vba.excel.Worksheet"
+ };
+ return aServiceNames;
+}
+
+OUString SAL_CALL
+ScVbaWorksheet::getCodeName()
+{
+ uno::Reference< beans::XPropertySet > xSheetProp( mxSheet, uno::UNO_QUERY_THROW );
+ return xSheetProp->getPropertyValue("CodeName").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 );
+}
+
+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: */
diff --git a/sc/source/ui/vba/vbaworksheet.hxx b/sc/source/ui/vba/vbaworksheet.hxx
new file mode 100644
index 000000000..5eee3df4a
--- /dev/null
+++ b/sc/source/ui/vba/vbaworksheet.hxx
@@ -0,0 +1,167 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <ooo/vba/excel/XWorksheet.hpp>
+#include <rtl/ref.hxx>
+
+#include <vbahelper/vbahelperinterface.hxx>
+#include <types.hxx>
+
+namespace com::sun::star::frame { class XModel; }
+namespace com::sun::star::sheet { class XSpreadsheet; }
+namespace com::sun::star::uno { class XComponentContext; }
+namespace ooo::vba::excel { class XOutline; }
+namespace ooo::vba::excel { class XPageSetup; }
+namespace ooo::vba::excel { class XRange; }
+
+namespace ooo::vba::excel {
+ class XChartObjects;
+ class XHyperlinks;
+}
+
+class ScVbaSheetObjectsBase;
+
+typedef InheritedHelperInterfaceWeakImpl< ov::excel::XWorksheet > WorksheetImpl_BASE;
+
+class ScVbaWorksheet : public WorksheetImpl_BASE
+{
+ css::uno::Reference< css::sheet::XSpreadsheet > mxSheet;
+ css::uno::Reference< css::frame::XModel > mxModel;
+ css::uno::Reference< ov::excel::XChartObjects > mxCharts;
+ css::uno::Reference< ov::excel::XHyperlinks > mxHlinks;
+ ::rtl::Reference< ScVbaSheetObjectsBase > mxButtons[2];
+ bool mbVeryHidden;
+
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference< ov::excel::XWorksheet > getSheetAtOffset(SCTAB offset);
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference< ov::excel::XRange > getSheetRange();
+
+ css::uno::Reference< css::container::XNameAccess > getFormControls() const;
+ css::uno::Any getControlShape( std::u16string_view sName );
+
+ css::uno::Any getButtons( const css::uno::Any &rIndex, bool bOptionButtons );
+
+public:
+ /// @throws css::uno::RuntimeException
+ ScVbaWorksheet( const css::uno::Reference< ov::XHelperInterface >& xParent,
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ const css::uno::Reference< css::sheet::XSpreadsheet >& xSheet,
+ const css::uno::Reference< css::frame::XModel >& xModel ) ;
+ /// @throws css::lang::IllegalArgumentException
+ /// @throws css::uno::RuntimeException
+ ScVbaWorksheet( css::uno::Sequence< css::uno::Any > const& aArgs, css::uno::Reference< css::uno::XComponentContext >const& xContext );
+
+ virtual ~ScVbaWorksheet() override;
+
+ const css::uno::Reference< css::frame::XModel >& getModel() const
+ { return mxModel; }
+ const css::uno::Reference< css::sheet::XSpreadsheet >& getSheet() const
+ { return mxSheet; }
+ static const css::uno::Sequence<sal_Int8>& getUnoTunnelId();
+ css::uno::Reference< ov::excel::XWorksheet > createSheetCopyInNewDoc( const OUString& );
+ css::uno::Reference< ov::excel::XWorksheet > createSheetCopy(css::uno::Reference< ov::excel::XWorksheet> const & xSheet, bool bAfter);
+
+ // Attributes
+ virtual OUString SAL_CALL getName() override;
+ virtual void SAL_CALL setName( const OUString &rName ) override;
+ virtual sal_Int32 SAL_CALL getVisible() override;
+ virtual void SAL_CALL setVisible( sal_Int32 nVisible ) override;
+ virtual ::sal_Int32 SAL_CALL getStandardWidth() override;
+ virtual ::sal_Int32 SAL_CALL getStandardHeight() override;
+ virtual sal_Bool SAL_CALL getProtectionMode() override;
+ virtual sal_Bool SAL_CALL getProtectContents() override;
+ virtual sal_Bool SAL_CALL getProtectDrawingObjects() override;
+ virtual sal_Bool SAL_CALL getProtectScenarios() override;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL getUsedRange() override ;
+ virtual css::uno::Any SAL_CALL ChartObjects( const css::uno::Any& Index ) override;
+ virtual css::uno::Reference< ov::excel::XOutline > SAL_CALL Outline( ) override;
+ virtual css::uno::Reference< ov::excel::XPageSetup > SAL_CALL PageSetup( ) override;
+ virtual css::uno::Any SAL_CALL HPageBreaks( const css::uno::Any& aIndex ) override;
+ virtual css::uno::Any SAL_CALL VPageBreaks( const css::uno::Any& aIndex ) override;
+ virtual css::uno::Reference< ov::excel::XWorksheet > SAL_CALL getNext() override;
+ virtual css::uno::Reference< ov::excel::XWorksheet > SAL_CALL getPrevious() override;
+ virtual sal_Int16 SAL_CALL getIndex() override;
+ virtual sal_Int32 SAL_CALL getEnableSelection() override;
+ virtual void SAL_CALL setEnableSelection( sal_Int32 nSelection ) override;
+ virtual sal_Bool SAL_CALL getAutoFilterMode() override;
+ virtual void SAL_CALL setAutoFilterMode( sal_Bool bAutoFilterMode ) override;
+
+ // Methods
+ virtual void SAL_CALL Activate() override;
+ virtual void SAL_CALL Select() override;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Range( const css::uno::Any& Cell1, const css::uno::Any& Cell2 ) override;
+ virtual void SAL_CALL Move( const css::uno::Any& Before, const css::uno::Any& After ) override ;
+ virtual void SAL_CALL Copy( const css::uno::Any& Before, const css::uno::Any& After ) override;
+ virtual void SAL_CALL Paste( const css::uno::Any& Destination, const css::uno::Any& Link ) override;
+ virtual void SAL_CALL Delete( ) override;
+ virtual void SAL_CALL Protect( const css::uno::Any& Password, const css::uno::Any& DrawingObjects, const css::uno::Any& Contents, const css::uno::Any& Scenarios, const css::uno::Any& UserInterfaceOnly ) override;
+ virtual void SAL_CALL Unprotect( const css::uno::Any& Password ) override;
+
+ virtual void SAL_CALL Calculate( ) override;
+ virtual void SAL_CALL CheckSpelling( const css::uno::Any& CustomDictionary,const css::uno::Any& IgnoreUppercase,const css::uno::Any& AlwaysSuggest, const css::uno::Any& SpellingLang ) override;
+ // Hacks (?)
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Cells( const css::uno::Any &nRow, const css::uno::Any &nCol ) override;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Rows(const css::uno::Any& aIndex ) override;
+ virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Columns(const css::uno::Any& aIndex ) override;
+
+ virtual css::uno::Any SAL_CALL Evaluate( const OUString& Name ) override;
+ virtual css::uno::Any SAL_CALL PivotTables( const css::uno::Any& Index ) override;
+ virtual css::uno::Any SAL_CALL Comments( const css::uno::Any& Index ) override;
+ virtual css::uno::Any SAL_CALL Hyperlinks( const css::uno::Any& aIndex ) override;
+ virtual css::uno::Any SAL_CALL Names( const css::uno::Any& aIndex ) override;
+
+ virtual css::uno::Any SAL_CALL OLEObjects( const css::uno::Any& Index ) override;
+ virtual css::uno::Any SAL_CALL Shapes( const css::uno::Any& aIndex ) override;
+
+ virtual css::uno::Any SAL_CALL Buttons( const css::uno::Any& rIndex ) override;
+ virtual css::uno::Any SAL_CALL CheckBoxes( const css::uno::Any& rIndex ) override;
+ virtual css::uno::Any SAL_CALL DropDowns( const css::uno::Any& rIndex ) override;
+ virtual css::uno::Any SAL_CALL GroupBoxes( const css::uno::Any& rIndex ) override;
+ virtual css::uno::Any SAL_CALL Labels( const css::uno::Any& rIndex ) override;
+ virtual css::uno::Any SAL_CALL ListBoxes( const css::uno::Any& rIndex ) override;
+ virtual css::uno::Any SAL_CALL OptionButtons( const css::uno::Any& rIndex ) override;
+ virtual css::uno::Any SAL_CALL ScrollBars( const css::uno::Any& rIndex ) override;
+ virtual css::uno::Any SAL_CALL Spinners( const css::uno::Any& rIndex ) override;
+
+ virtual void SAL_CALL setEnableCalculation( sal_Bool EnableCalculation ) override;
+ virtual sal_Bool SAL_CALL getEnableCalculation( ) override;
+ virtual void SAL_CALL ShowDataForm( ) override;
+ // XInvocation
+ virtual css::uno::Reference< css::beans::XIntrospectionAccess > SAL_CALL getIntrospection( ) override;
+ virtual css::uno::Any SAL_CALL invoke( const OUString& aFunctionName, const css::uno::Sequence< css::uno::Any >& aParams, css::uno::Sequence< ::sal_Int16 >& aOutParamIndex, css::uno::Sequence< css::uno::Any >& aOutParam ) override;
+ virtual void SAL_CALL setValue( const OUString& aPropertyName, const css::uno::Any& aValue ) override;
+ virtual css::uno::Any SAL_CALL getValue( const OUString& aPropertyName ) override;
+ virtual sal_Bool SAL_CALL hasMethod( const OUString& aName ) override;
+ virtual sal_Bool SAL_CALL hasProperty( const OUString& aName ) override;
+ // CodeName
+ virtual OUString SAL_CALL getCodeName() override;
+ /// @throws css::uno::RuntimeException
+ sal_Int16 getSheetID() const;
+
+ virtual void SAL_CALL PrintOut( const css::uno::Any& From, const css::uno::Any& To, const css::uno::Any& Copies, const css::uno::Any& Preview, const css::uno::Any& ActivePrinter, const css::uno::Any& PrintToFile, const css::uno::Any& Collate, const css::uno::Any& PrToFileName, const css::uno::Any& IgnorePrintAreas ) override;
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+ // XUnoTunnel
+ virtual ::sal_Int64 SAL_CALL getSomething(const css::uno::Sequence<sal_Int8 >& rId ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaworksheets.cxx b/sc/source/ui/vba/vbaworksheets.cxx
new file mode 100644
index 000000000..5df1bc622
--- /dev/null
+++ b/sc/source/ui/vba/vbaworksheets.cxx
@@ -0,0 +1,535 @@
+/* -*- 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 "vbaworksheets.hxx"
+
+#include <sfx2/viewfrm.hxx>
+
+#include <cppuhelper/implbase.hxx>
+
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+#include <com/sun/star/script/XTypeConverter.hpp>
+
+#include <ooo/vba/excel/XApplication.hpp>
+#include <tabvwsh.hxx>
+
+#include "excelvbahelper.hxx"
+#include "vbaworksheet.hxx"
+#include <markdata.hxx>
+
+#include <vector>
+#include <prevwsh.hxx>
+#include <preview.hxx>
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+// a map ( or hashmap ) won't do as we need also to preserve the order
+// (as added ) of the items
+typedef std::vector< uno::Reference< sheet::XSpreadsheet > > SheetMap;
+
+// #FIXME #TODO the implementation of the Sheets collections sucks,
+// e.g. there is no support for tracking sheets added/removed from the collection
+
+namespace {
+
+class WorkSheetsEnumeration : public ::cppu::WeakImplHelper< container::XEnumeration >
+{
+ SheetMap mSheetMap;
+ SheetMap::iterator mIt;
+public:
+ explicit WorkSheetsEnumeration( SheetMap&& sMap ) : mSheetMap( std::move(sMap) ), mIt( mSheetMap.begin() ) {}
+ virtual sal_Bool SAL_CALL hasMoreElements( ) override
+ {
+ return ( mIt != mSheetMap.end() );
+ }
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ if ( !hasMoreElements() )
+ throw container::NoSuchElementException();
+ uno::Reference< sheet::XSpreadsheet > xSheet( *mIt++ );
+ return uno::Any( xSheet ) ;
+ }
+};
+
+class SheetCollectionHelper : public ::cppu::WeakImplHelper< container::XNameAccess,
+ container::XIndexAccess,
+ container::XEnumerationAccess >
+{
+ SheetMap mSheetMap;
+ SheetMap::iterator cachePos;
+public:
+ explicit SheetCollectionHelper( SheetMap&& sMap ) : mSheetMap( std::move(sMap) ), cachePos(mSheetMap.begin()) {}
+ // XElementAccess
+ virtual uno::Type SAL_CALL getElementType( ) override { return cppu::UnoType<sheet::XSpreadsheet>::get(); }
+ virtual sal_Bool SAL_CALL hasElements( ) override { return ( !mSheetMap.empty() ); }
+ // XNameAccess
+ virtual uno::Any SAL_CALL getByName( const OUString& aName ) override
+ {
+ if ( !hasByName(aName) )
+ throw container::NoSuchElementException();
+ return uno::Any( *cachePos );
+ }
+ virtual uno::Sequence< OUString > SAL_CALL getElementNames( ) override
+ {
+ uno::Sequence< OUString > sNames( mSheetMap.size() );
+ OUString* pString = sNames.getArray();
+
+ for ( const auto& rItem : mSheetMap )
+ {
+ uno::Reference< container::XNamed > xName( rItem, uno::UNO_QUERY_THROW );
+ *pString = xName->getName();
+ ++pString;
+ }
+ return sNames;
+ }
+ virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override
+ {
+ cachePos = mSheetMap.begin();
+ SheetMap::iterator it_end = mSheetMap.end();
+ for ( ; cachePos != it_end; ++cachePos )
+ {
+ uno::Reference< container::XNamed > xName( *cachePos, uno::UNO_QUERY_THROW );
+ if ( aName == xName->getName() )
+ break;
+ }
+ return ( cachePos != it_end );
+ }
+
+ // XElementAccess
+ virtual ::sal_Int32 SAL_CALL getCount( ) override { return mSheetMap.size(); }
+ virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override
+ {
+ if ( Index < 0 || Index >= getCount() )
+ throw lang::IndexOutOfBoundsException();
+
+ return uno::Any( mSheetMap[ Index ] );
+
+ }
+ // XEnumerationAccess
+ virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) override
+ {
+ return new WorkSheetsEnumeration( std::vector(mSheetMap) );
+ }
+};
+
+class SheetsEnumeration : public EnumerationHelperImpl
+{
+ uno::Reference< frame::XModel > m_xModel;
+public:
+ /// @throws uno::RuntimeException
+ SheetsEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Reference< frame::XModel >& xModel ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), m_xModel( xModel ) {}
+
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ uno::Reference< sheet::XSpreadsheet > xSheet( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW );
+ uno::Reference< XHelperInterface > xIf = excel::getUnoSheetModuleObj( xSheet );
+ uno::Any aRet;
+ if ( !xIf.is() )
+ {
+ // if the Sheet is in a document created by the api unfortunately ( at the
+ // moment, it actually won't have the special Document modules
+ uno::Reference< excel::XWorksheet > xNewSheet( new ScVbaWorksheet( m_xParent, m_xContext, xSheet, m_xModel ) );
+ aRet <<= xNewSheet;
+ }
+ else
+ aRet <<= xIf;
+ return aRet;
+ }
+
+};
+
+}
+
+ScVbaWorksheets::ScVbaWorksheets( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< css::uno::XComponentContext > & xContext, const uno::Reference< container::XIndexAccess >& xSheets, const uno::Reference< frame::XModel >& xModel ): ScVbaWorksheets_BASE( xParent, xContext, xSheets ), mxModel( xModel ), m_xSheets( uno::Reference< sheet::XSpreadsheets >( xSheets, uno::UNO_QUERY ) )
+{
+}
+
+ScVbaWorksheets::ScVbaWorksheets( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< css::uno::XComponentContext > & xContext, const uno::Reference< container::XEnumerationAccess >& xEnumAccess, const uno::Reference< frame::XModel >& xModel ): ScVbaWorksheets_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( xEnumAccess, uno::UNO_QUERY ) ), mxModel(xModel)
+{
+}
+
+// XEnumerationAccess
+uno::Type
+ScVbaWorksheets::getElementType()
+{
+ return cppu::UnoType<excel::XWorksheet>::get();
+}
+
+uno::Reference< container::XEnumeration >
+ScVbaWorksheets::createEnumeration()
+{
+ if ( !m_xSheets.is() )
+ {
+ uno::Reference< container::XEnumerationAccess > xAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
+ return xAccess->createEnumeration();
+ }
+ uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xSheets, uno::UNO_QUERY_THROW );
+ return new SheetsEnumeration( this, mxContext, xEnumAccess->createEnumeration(), mxModel );
+}
+
+uno::Any
+ScVbaWorksheets::createCollectionObject( const uno::Any& aSource )
+{
+ uno::Reference< sheet::XSpreadsheet > xSheet( aSource, uno::UNO_QUERY );
+ uno::Reference< XHelperInterface > xIf = excel::getUnoSheetModuleObj( xSheet );
+ uno::Any aRet;
+ if ( !xIf.is() )
+ {
+ // if the Sheet is in a document created by the api unfortunately ( at the
+ // moment, it actually won't have the special Document modules
+ uno::Reference< excel::XWorksheet > xNewSheet( new ScVbaWorksheet( getParent(), mxContext, xSheet, mxModel ) );
+ aRet <<= xNewSheet;
+ }
+ else
+ aRet <<= xIf;
+ return aRet;
+}
+
+// XWorksheets
+uno::Any
+ScVbaWorksheets::Add( const uno::Any& Before, const uno::Any& After,
+ const uno::Any& Count, const uno::Any& Type )
+{
+ if ( isSelectedSheets() )
+ return uno::Any(); // or should we throw?
+
+ OUString aStringSheet;
+ bool bBefore(true);
+ SCTAB nSheetIndex = 0;
+ SCTAB nNewSheets = 1, nType = 0;
+ Count >>= nNewSheets;
+ Type >>= nType;
+ SCTAB nCount = 0;
+
+ uno::Reference< excel::XWorksheet > xBeforeAfterSheet;
+
+ if ( Before.hasValue() )
+ {
+ if ( Before >>= xBeforeAfterSheet )
+ aStringSheet = xBeforeAfterSheet->getName();
+ else
+ Before >>= aStringSheet;
+ }
+
+ if (aStringSheet.isEmpty() && After.hasValue() )
+ {
+ if ( After >>= xBeforeAfterSheet )
+ aStringSheet = xBeforeAfterSheet->getName();
+ else
+ After >>= aStringSheet;
+ bBefore = false;
+ }
+ if (aStringSheet.isEmpty())
+ {
+ uno::Reference< excel::XApplication > xApplication( Application(), uno::UNO_QUERY_THROW );
+ aStringSheet = xApplication->getActiveWorkbook()->getActiveSheet()->getName();
+ bBefore = true;
+ }
+ nCount = static_cast< SCTAB >( m_xIndexAccess->getCount() );
+ for (SCTAB i=0; i < nCount; i++)
+ {
+ uno::Reference< sheet::XSpreadsheet > xSheet(m_xIndexAccess->getByIndex(i), uno::UNO_QUERY);
+ uno::Reference< container::XNamed > xNamed( xSheet, uno::UNO_QUERY_THROW );
+ if (xNamed->getName() == aStringSheet)
+ {
+ nSheetIndex = i;
+ break;
+ }
+ }
+
+ if(!bBefore)
+ nSheetIndex++;
+
+ SCTAB nSheetName = nCount + 1;
+ OUString aStringBase( "Sheet" );
+ uno::Any result;
+ for (SCTAB i=0; i < nNewSheets; i++, nSheetName++)
+ {
+ OUString aStringName = aStringBase + OUString::number(nSheetName);
+ while (m_xNameAccess->hasByName(aStringName))
+ {
+ nSheetName++;
+ aStringName = aStringBase + OUString::number(nSheetName);
+ }
+ m_xSheets->insertNewByName(aStringName, nSheetIndex + i);
+ result = getItemByStringIndex( aStringName );
+ }
+ uno::Reference< excel::XWorksheet > xNewSheet( result, uno::UNO_QUERY );
+ if ( xNewSheet.is() )
+ xNewSheet->Activate();
+ return result;
+}
+
+void
+ScVbaWorksheets::Delete()
+{
+ // #TODO #INVESTIGATE
+ // mmm this method could be trouble if the underlying
+ // uno objects ( the m_xIndexAccess etc ) aren't aware of the
+ // contents that are deleted
+ sal_Int32 nElems = getCount();
+ for ( sal_Int32 nItem = 1; nItem <= nElems; ++nItem )
+ {
+ uno::Reference< excel::XWorksheet > xSheet( Item( uno::Any( nItem ), uno::Any() ), uno::UNO_QUERY_THROW );
+ xSheet->Delete();
+ }
+}
+
+bool
+ScVbaWorksheets::isSelectedSheets() const
+{
+ return !m_xSheets.is();
+}
+
+void SAL_CALL
+ScVbaWorksheets::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 )
+{
+ sal_Int32 nTo = 0;
+ sal_Int32 nFrom = 0;
+ bool bSelection = false;
+ From >>= nFrom;
+ To >>= nTo;
+
+ if ( !( nFrom || nTo ) )
+ if ( isSelectedSheets() )
+ bSelection = true;
+
+ PrintOutHelper( excel::getBestViewShell( mxModel ), From, To, Copies, Preview, ActivePrinter, PrintToFile, Collate, PrToFileName, bSelection );
+}
+
+uno::Any SAL_CALL
+ScVbaWorksheets::getVisible()
+{
+ bool bVisible = true;
+ uno::Reference< container::XEnumeration > xEnum( createEnumeration(), uno::UNO_SET_THROW );
+ while ( xEnum->hasMoreElements() )
+ {
+ uno::Reference< excel::XWorksheet > xSheet( xEnum->nextElement(), uno::UNO_QUERY_THROW );
+ if ( xSheet->getVisible() == 0 )
+ {
+ bVisible = false;
+ break;
+ }
+ }
+ return uno::Any( bVisible );
+}
+
+void SAL_CALL
+ScVbaWorksheets::setVisible( const uno::Any& _visible )
+{
+ bool bState = false;
+ if ( !(_visible >>= bState) )
+ throw uno::RuntimeException("Visible property doesn't support non boolean #FIXME" );
+
+ uno::Reference< container::XEnumeration > xEnum( createEnumeration(), uno::UNO_SET_THROW );
+ while ( xEnum->hasMoreElements() )
+ {
+ uno::Reference< excel::XWorksheet > xSheet( xEnum->nextElement(), uno::UNO_QUERY_THROW );
+ xSheet->setVisible( bState ? 1 : 0 );
+ }
+
+}
+
+void SAL_CALL
+ScVbaWorksheets::Select( const uno::Any& Replace )
+{
+ ScTabViewShell* pViewShell = excel::getBestViewShell( mxModel );
+ if ( !pViewShell )
+ throw uno::RuntimeException("Cannot obtain view shell" );
+
+ ScMarkData& rMarkData = pViewShell->GetViewData().GetMarkData();
+ bool bReplace = true;
+ Replace >>= bReplace;
+ // Replace is defaulted to True, meaning this current collection
+ // becomes the Selection, if it were false then the current selection would
+ // be extended
+ bool bSelectSingle = bReplace;
+ sal_Int32 nElems = getCount();
+ for ( sal_Int32 nItem = 1; nItem <= nElems; ++nItem )
+ {
+ uno::Reference< excel::XWorksheet > xSheet( Item( uno::Any( nItem ), uno::Any() ), uno::UNO_QUERY_THROW );
+ ScVbaWorksheet* pSheet = excel::getImplFromDocModuleWrapper<ScVbaWorksheet>( xSheet );
+ if ( bSelectSingle )
+ {
+ rMarkData.SelectOneTable( static_cast< SCTAB >( pSheet->getSheetID() ) );
+ bSelectSingle = false;
+ }
+ else
+ rMarkData.SelectTable( static_cast< SCTAB >( pSheet->getSheetID() ), true );
+ }
+
+}
+
+void SAL_CALL
+ScVbaWorksheets::Copy ( const uno::Any& Before, const uno::Any& After)
+{
+ uno::Reference<excel::XWorksheet> xSheet;
+ sal_Int32 nElems = getCount();
+ bool bAfter = After.hasValue();
+ std::vector< uno::Reference< excel::XWorksheet > > Sheets;
+ sal_Int32 nItem = 0;
+
+ for ( nItem = 1; nItem <= nElems; ++nItem)
+ {
+ uno::Reference<excel::XWorksheet> xWorksheet(Item( uno::Any( nItem ), uno::Any() ), uno::UNO_QUERY_THROW );
+ Sheets.push_back(xWorksheet);
+ }
+ bool bNewDoc = (!(Before >>= xSheet) && !(After >>=xSheet)&& !(Before.hasValue()) && !(After.hasValue()));
+
+ uno::Reference< excel::XWorksheet > xSrcSheet;
+ if ( bNewDoc )
+ {
+ bAfter = true;
+ xSrcSheet = Sheets.at(0);
+ ScVbaWorksheet* pSrcSheet = excel::getImplFromDocModuleWrapper<ScVbaWorksheet>( xSrcSheet );
+ xSheet = pSrcSheet->createSheetCopyInNewDoc(xSrcSheet->getName());
+ nItem = 1;
+ }
+ else
+ {
+ nItem=0;
+ }
+
+ for (; nItem < nElems; ++nItem )
+ {
+ xSrcSheet = Sheets[nItem];
+ ScVbaWorksheet* pSrcSheet = excel::getImplFromDocModuleWrapper<ScVbaWorksheet>( xSrcSheet );
+ if ( bAfter )
+ xSheet = pSrcSheet->createSheetCopy(xSheet, bAfter);
+ else
+ pSrcSheet->createSheetCopy(xSheet, bAfter);
+ }
+}
+
+//ScVbaCollectionBaseImpl
+uno::Any SAL_CALL
+ScVbaWorksheets::Item(const uno::Any& Index, const uno::Any& Index2)
+{
+ if ( Index.getValueTypeClass() == uno::TypeClass_SEQUENCE )
+ {
+ const uno::Reference< script::XTypeConverter >& xConverter = getTypeConverter(mxContext);
+ uno::Any aConverted = xConverter->convertTo( Index, cppu::UnoType<uno::Sequence< uno::Any >>::get() );
+ SheetMap aSheets;
+ uno::Sequence< uno::Any > sIndices;
+ aConverted >>= sIndices;
+ for( const auto& rIndex : std::as_const(sIndices) )
+ {
+ uno::Reference< excel::XWorksheet > xWorkSheet( ScVbaWorksheets_BASE::Item( rIndex, Index2 ), uno::UNO_QUERY_THROW );
+ ScVbaWorksheet* pWorkSheet = excel::getImplFromDocModuleWrapper<ScVbaWorksheet>( xWorkSheet );
+ uno::Reference< sheet::XSpreadsheet > xSheet( pWorkSheet->getSheet() , uno::UNO_SET_THROW );
+ uno::Reference< container::XNamed > xName( xSheet, uno::UNO_QUERY_THROW );
+ aSheets.push_back( xSheet );
+ }
+ uno::Reference< container::XIndexAccess > xIndexAccess = new SheetCollectionHelper( std::move(aSheets) );
+ uno::Reference< XCollection > xSelectedSheets( new ScVbaWorksheets( getParent(), mxContext, xIndexAccess, mxModel ) );
+ return uno::Any( xSelectedSheets );
+ }
+ return ScVbaWorksheets_BASE::Item( Index, Index2 );
+}
+
+OUString
+ScVbaWorksheets::getServiceImplName()
+{
+ return "ScVbaWorksheets";
+}
+
+css::uno::Sequence<OUString>
+ScVbaWorksheets::getServiceNames()
+{
+ static uno::Sequence< OUString > const sNames
+ {
+ "ooo.vba.excel.Worksheets"
+ };
+ return sNames;
+}
+
+bool ScVbaWorksheets::nameExists( const uno::Reference <sheet::XSpreadsheetDocument>& xSpreadDoc, std::u16string_view name, SCTAB& nTab )
+{
+ if (!xSpreadDoc.is())
+ throw lang::IllegalArgumentException( "nameExists() xSpreadDoc is null", uno::Reference< uno::XInterface >(), 1 );
+ uno::Reference <container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY );
+ if ( xIndex.is() )
+ {
+ SCTAB nCount = static_cast< SCTAB >( xIndex->getCount() );
+ for (SCTAB i=0; i < nCount; i++)
+ {
+ uno::Reference< container::XNamed > xNamed( xIndex->getByIndex(i), uno::UNO_QUERY_THROW );
+ if (xNamed->getName() == name)
+ {
+ nTab = i;
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+void ScVbaWorksheets::PrintPreview( const css::uno::Any& /*EnableChanges*/ )
+{
+ // need test, print preview current active sheet
+ // !! TODO !! get view shell from controller
+ ScTabViewShell* pViewShell = excel::getBestViewShell( mxModel );
+ SfxViewFrame* pViewFrame = nullptr;
+ if ( pViewShell )
+ pViewFrame = pViewShell->GetViewFrame();
+ if ( !pViewFrame )
+ return;
+
+ if ( pViewFrame->GetFrame().IsInPlace() )
+ return;
+
+ dispatchExecute( pViewShell, SID_VIEWSHELL1 );
+ SfxViewShell* pShell = SfxViewShell::Get( pViewFrame->GetFrame().GetFrameInterface()->getController() );
+
+ ScPreviewShell* pPrvShell = dynamic_cast< ScPreviewShell* >( pShell );
+ if ( !pPrvShell )
+ return;
+
+ ScPreview* pPrvView = pPrvShell->GetPreview();
+ const ScDocument& rDoc = pViewShell->GetViewData().GetDocument();
+ ScMarkData aMarkData(rDoc.GetSheetLimits());
+ sal_Int32 nElems = getCount();
+ for ( sal_Int32 nItem = 1; nItem <= nElems; ++nItem )
+ {
+ uno::Reference< excel::XWorksheet > xSheet( Item( uno::Any( nItem ), uno::Any() ), uno::UNO_QUERY_THROW );
+ ScVbaWorksheet* pSheet = excel::getImplFromDocModuleWrapper<ScVbaWorksheet>( xSheet );
+ if ( pSheet )
+ aMarkData.SelectTable(static_cast< SCTAB >( pSheet->getSheetID() ), true );
+ }
+ // save old selection, setting the selectedtabs in the preview
+ // can affect the current selection when preview has been
+ // closed
+ ScMarkData::MarkedTabsType aOldTabs = pPrvView->GetSelectedTabs();
+ pPrvView->SetSelectedTabs( aMarkData );
+ // force update
+ pPrvView->DataChanged(false);
+ // set sensible first page
+ tools::Long nPage = pPrvView->GetFirstPage( 1 );
+ pPrvView->SetPageNo( nPage );
+ WaitUntilPreviewIsClosed( pViewFrame );
+ // restore old tab selection
+ pViewShell = excel::getBestViewShell( mxModel );
+ pViewShell->GetViewData().GetMarkData().SetSelectedTabs(aOldTabs);
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbaworksheets.hxx b/sc/source/ui/vba/vbaworksheets.hxx
new file mode 100644
index 000000000..b795fbf5a
--- /dev/null
+++ b/sc/source/ui/vba/vbaworksheets.hxx
@@ -0,0 +1,68 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <ooo/vba/excel/XWorksheets.hpp>
+
+#include <vbahelper/vbacollectionimpl.hxx>
+
+#include <types.hxx>
+
+namespace com::sun::star::container { class XEnumerationAccess; }
+namespace com::sun::star::sheet { class XSpreadsheetDocument; }
+namespace com::sun::star::sheet { class XSpreadsheets; }
+namespace com::sun::star::uno { class XComponentContext; }
+
+typedef CollTestImplHelper< ov::excel::XWorksheets > ScVbaWorksheets_BASE;
+
+class ScVbaWorksheets : public ScVbaWorksheets_BASE
+{
+ css::uno::Reference< css::frame::XModel > mxModel;
+ css::uno::Reference< css::sheet::XSpreadsheets > m_xSheets;
+public:
+ ScVbaWorksheets( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::container::XIndexAccess >& xSheets, const css::uno::Reference< css::frame::XModel >& xModel );
+ ScVbaWorksheets( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::container::XEnumerationAccess >& xEnum, const css::uno::Reference< css::frame::XModel >& xModel );
+
+ bool isSelectedSheets() const;
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+
+ // XWorksheets
+ virtual css::uno::Any SAL_CALL getVisible() override;
+ virtual void SAL_CALL setVisible( const css::uno::Any& _visible ) override;
+ virtual css::uno::Any SAL_CALL Add( const css::uno::Any& Before, const css::uno::Any& After, const css::uno::Any& Count, const css::uno::Any& Type ) override;
+ virtual void SAL_CALL Delete( ) override;
+ virtual void SAL_CALL PrintOut( const css::uno::Any& From, const css::uno::Any& To, const css::uno::Any& Copies, const css::uno::Any& Preview, const css::uno::Any& ActivePrinter, const css::uno::Any& PrintToFile, const css::uno::Any& Collate, const css::uno::Any& PrToFileName ) override;
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+ virtual void SAL_CALL Select( const css::uno::Any& Replace ) override;
+ virtual void SAL_CALL Copy ( const css::uno::Any& Before, const css::uno::Any& After) override;
+ virtual void SAL_CALL PrintPreview( const css::uno::Any& EnableChanges ) override;
+ // ScVbaWorksheets_BASE
+ virtual css::uno::Any SAL_CALL Item( const css::uno::Any& Index1, const css::uno::Any& Index2 ) override;
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+
+ /// @throws css::lang::IllegalArgumentException
+ /// @throws css::uno::RuntimeException
+ static bool nameExists( const css::uno::Reference <css::sheet::XSpreadsheetDocument>& xSpreadDoc, std::u16string_view name, SCTAB& nTab );
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbawsfunction.cxx b/sc/source/ui/vba/vbawsfunction.cxx
new file mode 100644
index 000000000..6af173223
--- /dev/null
+++ b/sc/source/ui/vba/vbawsfunction.cxx
@@ -0,0 +1,298 @@
+/* -*- 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/beans/XPropertySet.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/beans/XIntrospectionAccess.hpp>
+#include <com/sun/star/sheet/XFunctionAccess.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <ooo/vba/excel/XRange.hpp>
+
+#include "vbawsfunction.hxx"
+#include <compiler.hxx>
+
+using namespace com::sun::star;
+using namespace ooo::vba;
+
+namespace {
+
+void lclConvertDoubleToBoolean( uno::Any& rAny )
+{
+ if( rAny.has< double >() )
+ {
+ double fValue = rAny.get< double >();
+ if( fValue == 0.0 )
+ rAny <<= false;
+ else if( fValue == 1.0 )
+ rAny <<= true;
+ // do nothing for other values or types
+ }
+}
+
+void lclConvertBooleanToDouble( uno::Any& rAny )
+{
+ bool bValue( false );
+ if ( rAny >>= bValue )
+ {
+ if ( bValue )
+ rAny <<= 1.0;
+ else
+ rAny <<= 0.0;
+ }
+}
+
+} // namespace
+
+ScVbaWSFunction::ScVbaWSFunction( const uno::Reference< XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext ) :
+ ScVbaWSFunction_BASE( xParent, xContext )
+{
+}
+
+uno::Reference< beans::XIntrospectionAccess >
+ScVbaWSFunction::getIntrospection()
+{
+ return uno::Reference<beans::XIntrospectionAccess>();
+}
+
+uno::Any SAL_CALL
+ScVbaWSFunction::invoke(const OUString& FunctionName, const uno::Sequence< uno::Any >& Params, uno::Sequence< sal_Int16 >& /*OutParamIndex*/, uno::Sequence< uno::Any >& /*OutParam*/)
+{
+ // create copy of parameters, replace Excel range objects with UNO range objects
+ uno::Sequence< uno::Any > aParamTemp( Params );
+ if( aParamTemp.hasElements() )
+ {
+ for( uno::Any & rArray : asNonConstRange(aParamTemp) )
+ {
+ switch( rArray.getValueType().getTypeClass() )
+ {
+ case uno::TypeClass_BOOLEAN:
+ lclConvertBooleanToDouble( rArray );
+ break;
+ case uno::TypeClass_INTERFACE:
+ {
+ uno::Reference< excel::XRange > myRange( rArray, uno::UNO_QUERY );
+ if( myRange.is() )
+ rArray = myRange->getCellRange();
+ }
+ break;
+ case uno::TypeClass_SEQUENCE:
+ {
+ // the sheet.FunctionAccess service doesn't deal with Sequences, only Sequences of Sequence
+ uno::Type aType = rArray.getValueType();
+ if ( aType.equals( cppu::UnoType<uno::Sequence<sal_Int16>>::get() ) )
+ {
+ uno::Sequence< uno::Sequence< sal_Int16 > > aTmp(1);
+ rArray >>= aTmp.getArray()[ 0 ];
+ rArray <<= aTmp;
+ }
+ else if ( aType.equals( cppu::UnoType<uno::Sequence<sal_Int32>>::get() ) )
+ {
+ uno::Sequence< uno::Sequence< sal_Int32 > > aTmp(1);
+ rArray >>= aTmp.getArray()[ 0 ];
+ rArray <<= aTmp;
+ }
+ else if ( aType.equals( cppu::UnoType<uno::Sequence<double>>::get() ) )
+ {
+ uno::Sequence< uno::Sequence< double > > aTmp(1);
+ rArray >>= aTmp.getArray()[ 0 ];
+ rArray <<= aTmp;
+ }
+ else if ( aType.equals( cppu::UnoType<uno::Sequence<OUString>>::get() ) )
+ {
+ uno::Sequence< uno::Sequence< OUString > > aTmp(1);
+ rArray >>= aTmp.getArray()[ 0 ];
+ rArray <<= aTmp;
+ }
+ else if ( aType.equals( cppu::UnoType<uno::Sequence<uno::Any>>::get() ) )
+ {
+ uno::Sequence< uno::Sequence<uno::Any > > aTmp(1);
+ rArray >>= aTmp.getArray()[ 0 ];
+ rArray <<= aTmp;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ uno::Any aRet;
+ bool bAsArray = true;
+
+ // special handing for some functions that don't work correctly in FunctionAccess
+ formula::FormulaCompiler aCompiler;
+ OpCode eOpCode = aCompiler.GetEnglishOpCode( FunctionName.toAsciiUpperCase() );
+ switch( eOpCode )
+ {
+ // ISLOGICAL does not work in array formula mode
+ case ocIsLogical:
+ {
+ if( aParamTemp.getLength() != 1 )
+ throw lang::IllegalArgumentException();
+ const uno::Any& rParam = aParamTemp[ 0 ];
+ if( rParam.has< bool >() )
+ {
+ aRet <<= true;
+ }
+ else if( rParam.has< uno::Reference< table::XCellRange > >() ) try
+ {
+ uno::Reference< sheet::XCellRangeAddressable > xRangeAddr( rParam, uno::UNO_QUERY_THROW );
+ table::CellRangeAddress aRangeAddr = xRangeAddr->getRangeAddress();
+ bAsArray = (aRangeAddr.StartColumn != aRangeAddr.EndColumn) || (aRangeAddr.StartRow != aRangeAddr.EndRow);
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+ break;
+ default:;
+ }
+
+ if( !aRet.hasValue() )
+ {
+ uno::Reference< lang::XMultiComponentFactory > xSMgr( mxContext->getServiceManager(), uno::UNO_SET_THROW );
+ uno::Reference< sheet::XFunctionAccess > xFunctionAccess( xSMgr->createInstanceWithContext(
+ "com.sun.star.sheet.FunctionAccess", mxContext ),
+ uno::UNO_QUERY_THROW );
+ uno::Reference< beans::XPropertySet > xPropSet( xFunctionAccess, uno::UNO_QUERY_THROW );
+ xPropSet->setPropertyValue("IsArrayFunction", uno::Any( bAsArray ) );
+ aRet = xFunctionAccess->callFunction( FunctionName, aParamTemp );
+ }
+
+ /* Convert return value from double to Boolean for some functions that
+ return Booleans. */
+ typedef uno::Sequence< uno::Sequence< uno::Any > > AnySeqSeq;
+ if( (eOpCode == ocIsEmpty) || (eOpCode == ocIsString) || (eOpCode == ocIsNonString) || (eOpCode == ocIsLogical) ||
+ (eOpCode == ocIsRef) || (eOpCode == ocIsValue) || (eOpCode == ocIsFormula) || (eOpCode == ocIsNA) ||
+ (eOpCode == ocIsErr) || (eOpCode == ocIsError) || (eOpCode == ocIsEven) || (eOpCode == ocIsOdd) ||
+ (eOpCode == ocAnd) || (eOpCode == ocOr) || (eOpCode == ocXor) || (eOpCode == ocNot) || (eOpCode == ocTrue) || (eOpCode == ocFalse) )
+ {
+ if( aRet.has< AnySeqSeq >() )
+ {
+ AnySeqSeq aAnySeqSeq = aRet.get< AnySeqSeq >();
+ for( auto& rAnySeq : asNonConstRange(aAnySeqSeq) )
+ for( auto& rAny : asNonConstRange(rAnySeq) )
+ lclConvertDoubleToBoolean( rAny );
+ aRet <<= aAnySeqSeq;
+ }
+ else
+ {
+ lclConvertDoubleToBoolean( aRet );
+ }
+ }
+
+ /* Hack/workaround (?): shorten single-row matrix to simple array, shorten
+ 1x1 matrix to single value. */
+ if( aRet.has< AnySeqSeq >() )
+ {
+ AnySeqSeq aAnySeqSeq = aRet.get< AnySeqSeq >();
+ if( aAnySeqSeq.getLength() == 1 )
+ {
+ if( aAnySeqSeq[ 0 ].getLength() == 1 )
+ aRet = aAnySeqSeq[ 0 ][ 0 ];
+ else
+ aRet <<= aAnySeqSeq[ 0 ];
+ }
+ }
+
+#if 0
+ // MATCH function should alwayse return a double value, but currently if the first argument is XCellRange, MATCH function returns an array instead of a double value. Don't know why?
+ // To fix this issue in safe, current solution is to convert this array to a double value just for MATCH function.
+ OUString aUpper( FunctionName.toAsciiUpperCase() );
+ ScCompiler aCompiler( NULL, ScAddress() );
+ OpCode eOp = aCompiler.GetEnglishOpCode( aUpper );
+ if( eOp == ocMatch )
+ {
+ double fVal = 0.0;
+ if( aRet >>= fVal )
+ return aRet;
+ uno::Sequence< uno::Sequence< uno::Any > > aSequence;
+ if( !( ( aRet >>= aSequence ) && ( aSequence.getLength() > 0 ) &&
+ ( aSequence[0].getLength() > 0 ) && ( aSequence[0][0] >>= fVal ) ) )
+ throw uno::RuntimeException();
+ aRet <<= fVal;
+ }
+#endif
+
+ return aRet;
+}
+
+void SAL_CALL
+ScVbaWSFunction::setValue(const OUString& /*PropertyName*/, const uno::Any& /*Value*/)
+{
+ throw beans::UnknownPropertyException();
+}
+
+uno::Any SAL_CALL
+ScVbaWSFunction::getValue(const OUString& /*PropertyName*/)
+{
+ throw beans::UnknownPropertyException();
+}
+
+sal_Bool SAL_CALL
+ScVbaWSFunction::hasMethod(const OUString& Name)
+{
+ bool bIsFound = false;
+ try
+ {
+ // the function name contained in the com.sun.star.sheet.FunctionDescription service is alwayse localized.
+ // but the function name used in WorksheetFunction is a programmatic name (seems English).
+ // So m_xNameAccess->hasByName( Name ) may fail to find name when a function name has a localized name.
+ if( ScCompiler::IsEnglishSymbol( Name ) )
+ bIsFound = true;
+ }
+ catch( uno::Exception& /*e*/ )
+ {
+ // failed to find name
+ }
+ return bIsFound;
+}
+
+sal_Bool SAL_CALL
+ScVbaWSFunction::hasProperty(const OUString& /*Name*/)
+{
+ return false;
+}
+
+OUString SAL_CALL
+ScVbaWSFunction::getExactName( const OUString& aApproximateName )
+{
+ OUString sName = aApproximateName.toAsciiUpperCase();
+ if ( !hasMethod( sName ) )
+ return OUString();
+ return sName;
+}
+
+OUString
+ScVbaWSFunction::getServiceImplName()
+{
+ return "ScVbaWSFunction";
+}
+
+uno::Sequence< OUString >
+ScVbaWSFunction::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.excel.WorksheetFunction"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/vba/vbawsfunction.hxx b/sc/source/ui/vba/vbawsfunction.hxx
new file mode 100644
index 000000000..9a5dd821f
--- /dev/null
+++ b/sc/source/ui/vba/vbawsfunction.hxx
@@ -0,0 +1,45 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <ooo/vba/excel/XWorksheetFunction.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+#include <vbahelper/vbahelperinterface.hxx>
+
+typedef InheritedHelperInterfaceWeakImpl< ov::excel::XWorksheetFunction > ScVbaWSFunction_BASE;
+
+class ScVbaWSFunction : public ScVbaWSFunction_BASE
+{
+public:
+ ScVbaWSFunction( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext);
+
+ virtual css::uno::Reference< css::beans::XIntrospectionAccess > SAL_CALL getIntrospection() override;
+ virtual css::uno::Any SAL_CALL invoke(const OUString& FunctionName, const css::uno::Sequence< css::uno::Any >& Params, css::uno::Sequence< sal_Int16 >& OutParamIndex, css::uno::Sequence< css::uno::Any >& OutParam) override;
+ virtual void SAL_CALL setValue(const OUString& PropertyName, const css::uno::Any& Value) override;
+ virtual css::uno::Any SAL_CALL getValue(const OUString& PropertyName) override;
+ virtual sal_Bool SAL_CALL hasMethod(const OUString& Name) override;
+ virtual sal_Bool SAL_CALL hasProperty(const OUString& Name) override;
+ virtual OUString SAL_CALL getExactName( const OUString& aApproximateName ) override;
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */