cid#1607171 Data race condition
[LibreOffice.git] / sc / source / ui / vba / vbaapplication.cxx
blob03955113b20031a23408289f33835be57ad35016
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/frame/XDesktop.hpp>
21 #include <com/sun/star/lang/XServiceInfo.hpp>
22 #include <com/sun/star/script/BasicErrorException.hpp>
23 #include <com/sun/star/sheet/XCalculatable.hpp>
24 #include <com/sun/star/sheet/XCellRangeAddressable.hpp>
25 #include <com/sun/star/sheet/XNamedRanges.hpp>
26 #include <com/sun/star/sheet/XSpreadsheetView.hpp>
27 #include <com/sun/star/task/XStatusIndicatorSupplier.hpp>
28 #include <com/sun/star/task/XStatusIndicator.hpp>
29 #include <com/sun/star/util/PathSettings.hpp>
30 #include <com/sun/star/view/XSelectionSupplier.hpp>
31 #include <ooo/vba/XCommandBars.hpp>
32 #include <ooo/vba/excel/XApplicationOutgoing.hpp>
33 #include <ooo/vba/excel/XlCalculation.hpp>
34 #include <ooo/vba/excel/XlMousePointer.hpp>
35 #include <ooo/vba/office/MsoShapeType.hpp>
36 #include <ooo/vba/office/MsoAutoShapeType.hpp>
37 #include <ooo/vba/office/MsoFileDialogType.hpp>
39 #include "vbaapplication.hxx"
40 #include "vbaworkbooks.hxx"
41 #include "vbaworkbook.hxx"
42 #include "vbarange.hxx"
43 #include "vbawsfunction.hxx"
44 #include "vbadialogs.hxx"
45 #include "vbawindow.hxx"
46 #include "vbawindows.hxx"
47 #include "vbamenubars.hxx"
48 #include <tabvwsh.hxx>
49 #include <gridwin.hxx>
50 #include "vbanames.hxx"
51 #include <vbahelper/vbashape.hxx>
52 #include "vbatextboxshape.hxx"
53 #include "vbaovalshape.hxx"
54 #include "vbalineshape.hxx"
55 #include "vbaassistant.hxx"
56 #include <sc.hrc>
57 #include <macromgr.hxx>
58 #include "vbafiledialog.hxx"
59 #include "vbafiledialogitems.hxx"
61 #include <osl/file.hxx>
63 #include <sfx2/bindings.hxx>
64 #include <sfx2/request.hxx>
65 #include <sfx2/app.hxx>
66 #include <vcl/svapp.hxx>
68 #include <comphelper/diagnose_ex.hxx>
70 #include <basic/sbx.hxx>
71 #include <basic/sbstar.hxx>
72 #include <basic/sbuno.hxx>
73 #include <basic/sbmeth.hxx>
74 #include <basic/sberrors.hxx>
75 #include <comphelper/sequence.hxx>
76 #include <cppu/unotype.hxx>
78 #include <convuno.hxx>
79 #include <cellsuno.hxx>
80 #include <unonames.hxx>
81 #include <docsh.hxx>
82 #include "excelvbahelper.hxx"
83 #include <basic/sbxobj.hxx>
85 #include <viewutil.hxx>
86 #include <docoptio.hxx>
87 #include <scmod.hxx>
88 #include <scdll.hxx>
90 #include <list>
92 using namespace ::ooo::vba;
93 using namespace ::com::sun::star;
94 using ::com::sun::star::uno::Reference;
95 using ::com::sun::star::uno::UNO_QUERY_THROW;
96 using ::com::sun::star::uno::UNO_QUERY;
98 /** Global application settings shared by all open workbooks. */
99 struct ScVbaAppSettings
101 bool mbDisplayAlerts;
102 bool mbEnableEvents;
103 bool mbExcel4Menus;
104 bool mbDisplayNoteIndicator;
105 bool mbShowWindowsInTaskbar;
106 bool mbEnableCancelKey;
107 explicit ScVbaAppSettings();
110 ScVbaAppSettings::ScVbaAppSettings() :
111 mbDisplayAlerts( true ),
112 mbEnableEvents( true ),
113 mbExcel4Menus( false ),
114 mbDisplayNoteIndicator( true ),
115 mbShowWindowsInTaskbar( true ),
116 mbEnableCancelKey( false )
120 namespace {
122 ScVbaAppSettings& ScVbaStaticAppSettings()
124 static ScVbaAppSettings SINGLETON;
125 return SINGLETON;
128 class ScVbaApplicationOutgoingConnectionPoint : public cppu::WeakImplHelper<XConnectionPoint>
130 private:
131 ScVbaApplication* mpApp;
133 public:
134 ScVbaApplicationOutgoingConnectionPoint( ScVbaApplication* pApp );
136 // XConnectionPoint
137 sal_uInt32 SAL_CALL Advise(const uno::Reference< XSink >& Sink ) override;
138 void SAL_CALL Unadvise( sal_uInt32 Cookie ) override;
143 sal_uInt32
144 ScVbaApplication::AddSink( const uno::Reference< XSink >& xSink )
147 SolarMutexGuard aGuard;
148 ScDLL::Init();
150 // No harm in potentially calling this several times
151 ScModule::get()->RegisterAutomationApplicationEventsCaller(uno::Reference<XSinkCaller>(this));
152 mvSinks.push_back(xSink);
153 return mvSinks.size();
156 void
157 ScVbaApplication::RemoveSink( sal_uInt32 nNumber )
159 if (nNumber < 1 || nNumber > mvSinks.size())
160 return;
162 mvSinks[nNumber-1] = uno::Reference< XSink >();
165 ScVbaApplication::ScVbaApplication( const uno::Reference<uno::XComponentContext >& xContext ) :
166 ScVbaApplication_BASE( xContext ),
167 mrAppSettings( ScVbaStaticAppSettings() ),
168 m_nDialogType(0)
172 ScVbaApplication::~ScVbaApplication()
176 /*static*/ bool ScVbaApplication::getDocumentEventsEnabled()
178 return ScVbaStaticAppSettings().mbEnableEvents;
181 OUString SAL_CALL
182 ScVbaApplication::getExactName( const OUString& aApproximateName )
184 uno::Reference< beans::XExactName > xWSF( new ScVbaWSFunction( this, mxContext ) );
185 return xWSF->getExactName( aApproximateName );
188 uno::Reference< beans::XIntrospectionAccess > SAL_CALL
189 ScVbaApplication::getIntrospection()
191 uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
192 return xWSF->getIntrospection();
195 uno::Any SAL_CALL
196 ScVbaApplication::invoke( const OUString& FunctionName, const uno::Sequence< uno::Any >& Params, uno::Sequence< sal_Int16 >& OutParamIndex, uno::Sequence< uno::Any >& OutParam)
198 /* When calling the functions directly at the Application object, no runtime
199 errors are thrown, but the error is inserted into the return value. */
200 uno::Any aAny;
203 uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
204 aAny = xWSF->invoke( FunctionName, Params, OutParamIndex, OutParam );
206 catch (const uno::Exception&)
208 aAny <<= script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), 1000, OUString() );
210 return aAny;
213 void SAL_CALL
214 ScVbaApplication::setValue( const OUString& PropertyName, const uno::Any& Value )
216 uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
217 xWSF->setValue( PropertyName, Value );
220 uno::Any SAL_CALL
221 ScVbaApplication::getValue( const OUString& PropertyName )
223 uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
224 return xWSF->getValue( PropertyName );
227 sal_Bool SAL_CALL
228 ScVbaApplication::hasMethod( const OUString& Name )
230 uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
231 return xWSF->hasMethod( Name );
234 sal_Bool SAL_CALL
235 ScVbaApplication::hasProperty( const OUString& Name )
237 uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
238 return xWSF->hasProperty( Name );
241 uno::Reference< excel::XWorkbook >
242 ScVbaApplication::getActiveWorkbook()
244 uno::Reference< frame::XModel > xModel( getCurrentExcelDoc( mxContext ), uno::UNO_SET_THROW );
245 uno::Reference< excel::XWorkbook > xWorkbook( getVBADocument( xModel ), uno::UNO_QUERY );
246 if( xWorkbook.is() ) return xWorkbook;
247 // #i116936# getVBADocument() may return null in documents without global VBA mode enabled
248 return new ScVbaWorkbook( this, mxContext, xModel );
251 uno::Reference< excel::XWorkbook > SAL_CALL
252 ScVbaApplication::getThisWorkbook()
254 uno::Reference< frame::XModel > xModel( getThisExcelDoc( mxContext ), uno::UNO_SET_THROW );
255 uno::Reference< excel::XWorkbook > xWorkbook( getVBADocument( xModel ), uno::UNO_QUERY );
256 if( xWorkbook.is() ) return xWorkbook;
257 // #i116936# getVBADocument() may return null in documents without global VBA mode enabled
258 return new ScVbaWorkbook( this, mxContext, xModel );
261 uno::Reference< XAssistant > SAL_CALL
262 ScVbaApplication::getAssistant()
264 return uno::Reference< XAssistant >( new ScVbaAssistant( this, mxContext ) );
267 uno::Any SAL_CALL
268 ScVbaApplication::getSelection()
270 uno::Reference< frame::XModel > xModel( getCurrentDocument() );
272 Reference< view::XSelectionSupplier > xSelSupp( xModel->getCurrentController(), UNO_QUERY_THROW );
273 Reference< beans::XPropertySet > xPropSet( xSelSupp, UNO_QUERY_THROW );
274 OUString aPropName( SC_UNO_FILTERED_RANGE_SELECTION );
275 uno::Any aOldVal = xPropSet->getPropertyValue( aPropName );
276 uno::Any any;
277 any <<= false;
278 xPropSet->setPropertyValue( aPropName, any );
279 uno::Reference<uno::XInterface> aSelection(xSelSupp->getSelection(), uno::UNO_QUERY);
280 xPropSet->setPropertyValue( aPropName, aOldVal );
282 if (!aSelection.is())
284 throw uno::RuntimeException( u"failed to obtain current selection"_ustr );
287 uno::Reference< lang::XServiceInfo > xServiceInfo( aSelection, uno::UNO_QUERY_THROW );
288 OUString sImplementationName = xServiceInfo->getImplementationName();
290 if( sImplementationName.equalsIgnoreAsciiCase("com.sun.star.drawing.SvxShapeCollection") )
292 uno::Reference< drawing::XShapes > xShapes( aSelection, uno::UNO_QUERY_THROW );
293 uno::Reference< container::XIndexAccess > xIndexAccess( xShapes, uno::UNO_QUERY_THROW );
294 uno::Reference< drawing::XShape > xShape( xIndexAccess->getByIndex(0), uno::UNO_QUERY_THROW );
295 // if ScVbaShape::getType( xShape ) == office::MsoShapeType::msoAutoShape
296 // and the uno object implements the com.sun.star.drawing.Text service
297 // return a textboxshape object
298 sal_Int32 nType = ScVbaShape::getType( xShape );
299 if ( nType == office::MsoShapeType::msoAutoShape )
301 // TODO Oval with text box
302 if( ScVbaShape::getAutoShapeType( xShape ) == office::MsoAutoShapeType::msoShapeOval )
304 return uno::Any( uno::Reference< msforms::XOval >(new ScVbaOvalShape( mxContext, xShape, xShapes, xModel ) ) );
308 uno::Reference< lang::XServiceInfo > xShapeServiceInfo( xShape, uno::UNO_QUERY_THROW );
309 if ( xShapeServiceInfo->supportsService(u"com.sun.star.drawing.Text"_ustr) )
311 return uno::Any( uno::Reference< msforms::XTextBoxShape >(
312 new ScVbaTextBoxShape( mxContext, xShape, xShapes, xModel ) ) );
315 else if ( nType == office::MsoShapeType::msoLine )
317 return uno::Any( uno::Reference< msforms::XLine >( new ScVbaLineShape(
318 mxContext, xShape, xShapes, xModel ) ) );
320 return uno::Any( uno::Reference< msforms::XShape >(new ScVbaShape( this, mxContext, xShape, xShapes, xModel, ScVbaShape::getType( xShape ) ) ) );
322 else if( xServiceInfo->supportsService(u"com.sun.star.sheet.SheetCellRange"_ustr) ||
323 xServiceInfo->supportsService(u"com.sun.star.sheet.SheetCellRanges"_ustr) )
325 uno::Reference< table::XCellRange > xRange( aSelection, ::uno::UNO_QUERY);
326 if ( !xRange.is() )
328 uno::Reference< sheet::XSheetCellRangeContainer > xRanges( aSelection, ::uno::UNO_QUERY);
329 if ( xRanges.is() )
330 return uno::Any( uno::Reference< excel::XRange >( new ScVbaRange( excel::getUnoSheetModuleObj( xRanges ), mxContext, xRanges ) ) );
333 return uno::Any( uno::Reference< excel::XRange >(new ScVbaRange( excel::getUnoSheetModuleObj( xRange ), mxContext, xRange ) ) );
335 else
337 throw uno::RuntimeException( sImplementationName + " not supported" );
341 uno::Reference< excel::XRange >
342 ScVbaApplication::getActiveCell()
344 uno::Reference< sheet::XSpreadsheetView > xView( getCurrentDocument()->getCurrentController(), uno::UNO_QUERY_THROW );
345 uno::Reference< table::XCellRange > xRange( xView->getActiveSheet(), ::uno::UNO_QUERY_THROW);
346 ScTabViewShell* pViewShell = excel::getCurrentBestViewShell(mxContext);
347 if ( !pViewShell )
348 throw uno::RuntimeException(u"No ViewShell available"_ustr );
349 ScViewData& rTabView = pViewShell->GetViewData();
351 sal_Int32 nCursorX = rTabView.GetCurX();
352 sal_Int32 nCursorY = rTabView.GetCurY();
354 // #i117392# excel::getUnoSheetModuleObj() may return null in documents without global VBA mode enabled
355 return new ScVbaRange( excel::getUnoSheetModuleObj( xRange ), mxContext, xRange->getCellRangeByPosition( nCursorX, nCursorY, nCursorX, nCursorY ) );
358 uno::Any SAL_CALL
359 ScVbaApplication::GetOpenFilename(const uno::Any& /*aFileFilter*/, const uno::Any& /*aFilterIndex*/, const uno::Any& aTitle, const uno::Any& /*aButtonText*/, const uno::Any& aMultiSelect)
361 // TODO - take all parameters into account
362 uno::Reference<excel::XFileDialog> xDialog(new ScVbaFileDialog(this, mxContext, office::MsoFileDialogType::msoFileDialogFilePicker));
363 xDialog->setTitle(aTitle);
364 xDialog->setAllowMultiSelect(aMultiSelect);
366 bool bMultiSelect = false;
367 aMultiSelect >>= bMultiSelect;
369 if (xDialog->Show() == 0)
371 // return FALSE when canceled
372 return uno::Any(false);
375 uno::Reference<excel::XFileDialogSelectedItems> xItems = xDialog->getSelectedItems();
376 auto* pItems = dynamic_cast<ScVbaFileDialogSelectedItems*>(xItems.get());
378 // Check, if the implementation of XFileDialogSelectedItems is what we expect
379 if (!pItems)
380 throw uno::RuntimeException(u"Unexpected XFileDialogSelectedItems implementation"_ustr);
382 auto const & rItemVector = pItems->getItems();
384 if (!bMultiSelect) // only 1 selection allowed - return path
386 OUString aPath;
387 if (!rItemVector.empty())
388 aPath = rItemVector.at(0);
389 return uno::Any(aPath);
391 else
393 // convert to sequence
394 return uno::Any(comphelper::containerToSequence(rItemVector));
398 uno::Any SAL_CALL
399 ScVbaApplication::International( sal_Int32 /*Index*/ )
401 // complete stub for now
402 // #TODO flesh out some of the Indices we could handle
403 uno::Any aRet;
404 return aRet;
407 uno::Any SAL_CALL
408 ScVbaApplication::FileDialog( const uno::Any& DialogType )
410 sal_Int32 nType = 0;
411 DialogType >>= nType;
413 if( !m_xFileDialog || nType != m_nDialogType )
415 m_nDialogType = nType;
416 m_xFileDialog = uno::Reference<excel::XFileDialog> ( new ScVbaFileDialog( this, mxContext, nType ));
418 return uno::Any( m_xFileDialog );
421 uno::Any SAL_CALL
422 ScVbaApplication::Workbooks( const uno::Any& aIndex )
424 uno::Reference< XCollection > xWorkBooks( new ScVbaWorkbooks( this, mxContext ) );
425 if ( aIndex.getValueTypeClass() == uno::TypeClass_VOID )
427 // void then somebody did Workbooks.something in vba
428 return uno::Any( xWorkBooks );
431 return xWorkBooks->Item( aIndex, uno::Any() );
434 uno::Any SAL_CALL
435 ScVbaApplication::Worksheets( const uno::Any& aIndex )
437 uno::Reference< excel::XWorkbook > xWorkbook( getActiveWorkbook(), uno::UNO_SET_THROW );
438 return xWorkbook->Worksheets( aIndex );
441 uno::Any SAL_CALL
442 ScVbaApplication::WorksheetFunction( )
444 return uno::Any( uno::Reference< script::XInvocation >( new ScVbaWSFunction( this, mxContext ) ) );
447 uno::Any SAL_CALL
448 ScVbaApplication::Evaluate( const OUString& Name )
450 // #TODO Evaluate allows other things to be evaluated, e.g. functions
451 // I think ( like SIN(3) etc. ) need to investigate that
452 // named Ranges also? e.g. [MyRange] if so need a list of named ranges
453 uno::Any aVoid;
454 return uno::Any( getActiveWorkbook()->getActiveSheet()->Range( uno::Any( Name ), aVoid ) );
457 uno::Any
458 ScVbaApplication::Dialogs( const uno::Any &aIndex )
460 uno::Reference< excel::XDialogs > xDialogs( new ScVbaDialogs( uno::Reference< XHelperInterface >( this ), mxContext, getCurrentDocument() ) );
461 if( !aIndex.hasValue() )
462 return uno::Any( xDialogs );
463 return xDialogs->Item( aIndex );
466 uno::Reference< excel::XWindow > SAL_CALL
467 ScVbaApplication::getActiveWindow()
469 uno::Reference< frame::XModel > xModel = getCurrentDocument();
470 uno::Reference< frame::XController > xController( xModel->getCurrentController(), uno::UNO_SET_THROW );
471 uno::Reference< XHelperInterface > xParent( getActiveWorkbook(), uno::UNO_QUERY_THROW );
472 uno::Reference< excel::XWindow > xWin( new ScVbaWindow( xParent, mxContext, xModel, xController ) );
473 return xWin;
476 uno::Any SAL_CALL
477 ScVbaApplication::getCutCopyMode()
479 //# FIXME TODO, implementation
480 uno::Any result;
481 result <<= false;
482 return result;
485 void SAL_CALL
486 ScVbaApplication::setCutCopyMode( const uno::Any& /* _cutcopymode */ )
488 //# FIXME TODO, implementation
491 uno::Any SAL_CALL
492 ScVbaApplication::getStatusBar()
494 return uno::Any( !getDisplayStatusBar() );
497 css::uno::Any SAL_CALL ScVbaApplication::getWindowState()
499 return getActiveWindow()->getWindowState();
502 void SAL_CALL ScVbaApplication::setWindowState(const css::uno::Any& rWindowState)
504 getActiveWindow()->setWindowState(rWindowState);
507 void SAL_CALL
508 ScVbaApplication::setStatusBar( const uno::Any& _statusbar )
510 OUString sText;
511 bool bDefault = false;
512 uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW );
513 uno::Reference< task::XStatusIndicatorSupplier > xStatusIndicatorSupplier( xModel->getCurrentController(), uno::UNO_QUERY_THROW );
514 uno::Reference< task::XStatusIndicator > xStatusIndicator( xStatusIndicatorSupplier->getStatusIndicator(), uno::UNO_SET_THROW );
515 if( _statusbar >>= sText )
517 setDisplayStatusBar( true );
518 if ( !sText.isEmpty() )
519 xStatusIndicator->start( sText, 100 );
520 else
521 xStatusIndicator->end(); // restore normal state for empty text
523 else if( _statusbar >>= bDefault )
525 if( !bDefault )
527 xStatusIndicator->end();
528 setDisplayStatusBar( true );
531 else
532 throw uno::RuntimeException(u"Invalid parameter. It should be a string or False"_ustr );
535 ::sal_Int32 SAL_CALL
536 ScVbaApplication::getCalculation()
538 // TODO: in Excel, this is an application-wide setting
539 uno::Reference<sheet::XCalculatable> xCalc(getCurrentDocument(), uno::UNO_QUERY_THROW);
540 if(xCalc->isAutomaticCalculationEnabled())
541 return excel::XlCalculation::xlCalculationAutomatic;
542 else
543 return excel::XlCalculation::xlCalculationManual;
546 void SAL_CALL
547 ScVbaApplication::setCalculation( ::sal_Int32 _calculation )
549 // TODO: in Excel, this is an application-wide setting
550 uno::Reference< sheet::XCalculatable > xCalc(getCurrentDocument(), uno::UNO_QUERY_THROW);
551 switch(_calculation)
553 case excel::XlCalculation::xlCalculationManual:
554 xCalc->enableAutomaticCalculation(false);
555 break;
556 case excel::XlCalculation::xlCalculationAutomatic:
557 case excel::XlCalculation::xlCalculationSemiautomatic:
558 xCalc->enableAutomaticCalculation(true);
559 break;
563 uno::Any SAL_CALL
564 ScVbaApplication::Windows( const uno::Any& aIndex )
566 uno::Reference< excel::XWindows > xWindows( new ScVbaWindows( this, mxContext ) );
567 if ( aIndex.getValueTypeClass() == uno::TypeClass_VOID )
568 return uno::Any( xWindows );
569 return xWindows->Item( aIndex, uno::Any() );
571 void SAL_CALL
572 ScVbaApplication::wait( double time )
574 StarBASIC* pBasic = SfxApplication::GetBasic();
575 SbxArrayRef aArgs = new SbxArray;
576 SbxVariableRef aRef = new SbxVariable;
577 aRef->PutDouble( time );
578 aArgs->Put(aRef.get(), 1);
579 SbMethod* pMeth = static_cast<SbMethod*>(pBasic->GetRtl()->Find( u"WaitUntil"_ustr, SbxClassType::Method ));
581 if ( pMeth )
583 pMeth->SetParameters( aArgs.get() );
584 SbxVariableRef refTemp = pMeth;
585 // forces a broadcast
586 SbxVariableRef pNew = new SbxMethod( *static_cast<SbxMethod*>(pMeth));
590 uno::Any SAL_CALL
591 ScVbaApplication::Range( const uno::Any& Cell1, const uno::Any& Cell2 )
593 uno::Reference< excel::XRange > xVbRange = ScVbaRange::ApplicationRange( mxContext, Cell1, Cell2 );
594 return uno::Any( xVbRange );
597 uno::Any SAL_CALL
598 ScVbaApplication::Names( const css::uno::Any& aIndex )
600 uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW );
601 uno::Reference< beans::XPropertySet > xPropertySet( xModel, uno::UNO_QUERY_THROW );
602 uno::Reference< sheet::XNamedRanges > xNamedRanges( xPropertySet->getPropertyValue(
603 u"NamedRanges"_ustr ), uno::UNO_QUERY_THROW );
605 css::uno::Reference< excel::XNames > xNames ( new ScVbaNames( this , mxContext , xNamedRanges , xModel ) );
606 if ( aIndex.getValueTypeClass() == uno::TypeClass_VOID )
608 return uno::Any( xNames );
610 return xNames->Item( aIndex, uno::Any() );
613 uno::Reference< excel::XWorksheet > SAL_CALL
614 ScVbaApplication::getActiveSheet()
616 uno::Reference< excel::XWorksheet > result;
617 uno::Reference< excel::XWorkbook > xWorkbook = getActiveWorkbook();
618 if ( xWorkbook.is() )
620 uno::Reference< excel::XWorksheet > xWorksheet =
621 xWorkbook->getActiveSheet();
622 if ( xWorksheet.is() )
624 result = std::move(xWorksheet);
628 if ( !result.is() )
630 // Fixme - check if this is reasonable/desired behavior
631 throw uno::RuntimeException(u"No activeSheet available"_ustr );
633 return result;
637 /*******************************************************************************
638 * In msdn:
639 * Reference Optional Variant. The destination. Can be a Range
640 * object, a string that contains a cell reference in R1C1-style notation,
641 * or a string that contains a Visual Basic procedure name.
642 * Scroll Optional Variant. True to scroll, False to not scroll through
643 * the window. The default is False.
644 * Parser is split to three parts, Range, R1C1 string and procedure name.
645 * by test excel, it seems Scroll no effect. ???
646 *******************************************************************************/
647 void SAL_CALL
648 ScVbaApplication::GoTo( const uno::Any& Reference, const uno::Any& Scroll )
650 //test Scroll is a boolean
651 bool bScroll = false;
652 //R1C1-style string or a string of procedure name.
654 if( Scroll.hasValue() )
656 bool aScroll = false;
657 if( !(Scroll >>= aScroll) )
658 throw uno::RuntimeException(u"second parameter should be boolean"_ustr );
660 bScroll = aScroll;
664 OUString sRangeName;
665 if( Reference >>= sRangeName )
667 ScTabViewShell* pShell = excel::getCurrentBestViewShell( mxContext );
668 if (!pShell)
669 return;
671 uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW );
672 uno::Reference< sheet::XSpreadsheetView > xSpreadsheet(
673 xModel->getCurrentController(), uno::UNO_QUERY_THROW );
675 ScGridWindow* gridWindow = static_cast<ScGridWindow*>(pShell->GetWindow());
678 uno::Reference< excel::XRange > xVbaSheetRange = ScVbaRange::getRangeObjectForName(
679 mxContext, sRangeName, excel::getDocShell( xModel ), formula::FormulaGrammar::CONV_XL_R1C1 );
681 if( bScroll )
683 xVbaSheetRange->Select();
684 uno::Reference< excel::XWindow > xWindow = getActiveWindow();
685 ScSplitPos eWhich = pShell->GetViewData().GetActivePart();
686 sal_Int32 nValueX = pShell->GetViewData().GetPosX(WhichH(eWhich));
687 sal_Int32 nValueY = pShell->GetViewData().GetPosY(WhichV(eWhich));
688 xWindow->SmallScroll( uno::Any( static_cast<sal_Int16>(xVbaSheetRange->getRow() - 1) ),
689 uno::Any( static_cast<sal_Int16>(nValueY) ),
690 uno::Any( static_cast<sal_Int16>(xVbaSheetRange->getColumn() - 1) ),
691 uno::Any( static_cast<sal_Int16>(nValueX) ) );
692 gridWindow->GrabFocus();
694 else
696 xVbaSheetRange->Select();
697 gridWindow->GrabFocus();
700 catch (const uno::RuntimeException&)
702 //maybe this should be a procedure name
703 //TODO for procedure name
704 //browse::XBrowseNodeFactory is a singleton. OUString( "/singletons/com.sun.star.script.browse.theBrowseNodeFactory")
705 //and the createView( browse::BrowseNodeFactoryViewTypes::MACROSELECTOR ) to get a root browse::XBrowseNode.
706 //for query XInvocation interface.
707 //but how to directly get the XInvocation?
708 throw uno::RuntimeException(u"invalid reference for range name, it should be procedure name"_ustr );
710 return;
712 uno::Reference< excel::XRange > xRange;
713 if( Reference >>= xRange )
715 ScTabViewShell* pShell = excel::getCurrentBestViewShell( mxContext );
716 if (!pShell)
717 return;
719 uno::Reference< excel::XRange > xVbaRange( Reference, uno::UNO_QUERY );
720 ScGridWindow* gridWindow = static_cast<ScGridWindow*>(pShell->GetWindow());
721 if ( xVbaRange.is() )
723 //TODO bScroll should be used. At this time, it does not have effect
724 if( bScroll )
726 xVbaRange->Select();
727 uno::Reference< excel::XWindow > xWindow = getActiveWindow();
728 ScSplitPos eWhich = pShell->GetViewData().GetActivePart();
729 sal_Int32 nValueX = pShell->GetViewData().GetPosX(WhichH(eWhich));
730 sal_Int32 nValueY = pShell->GetViewData().GetPosY(WhichV(eWhich));
731 xWindow->SmallScroll( uno::Any( static_cast<sal_Int16>(xVbaRange->getRow() - 1) ),
732 uno::Any( static_cast<sal_Int16>(nValueY) ),
733 uno::Any( static_cast<sal_Int16>(xVbaRange->getColumn() - 1) ),
734 uno::Any( static_cast<sal_Int16>(nValueX) ) );
735 gridWindow->GrabFocus();
737 else
739 xVbaRange->Select();
740 gridWindow->GrabFocus();
743 return;
745 throw uno::RuntimeException(u"invalid reference or name"_ustr );
748 sal_Int32 SAL_CALL
749 ScVbaApplication::getCursor()
751 PointerStyle nPointerStyle = getPointerStyle(getCurrentDocument());
753 switch( nPointerStyle )
755 case PointerStyle::Arrow:
756 return excel::XlMousePointer::xlNorthwestArrow;
757 case PointerStyle::Null:
758 return excel::XlMousePointer::xlDefault;
759 case PointerStyle::Wait:
760 return excel::XlMousePointer::xlWait;
761 case PointerStyle::Text:
762 return excel::XlMousePointer::xlIBeam;
763 default:
764 return excel::XlMousePointer::xlDefault;
768 void SAL_CALL
769 ScVbaApplication::setCursor( sal_Int32 _cursor )
773 uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW );
774 switch( _cursor )
776 case excel::XlMousePointer::xlNorthwestArrow:
778 setCursorHelper( xModel, PointerStyle::Arrow, false );
779 break;
781 case excel::XlMousePointer::xlWait:
782 case excel::XlMousePointer::xlIBeam:
784 PointerStyle nPointer( static_cast< PointerStyle >( _cursor ) );
785 //It will set the edit window, toobar and statusbar's mouse pointer.
786 setCursorHelper( xModel, nPointer, true );
787 break;
789 case excel::XlMousePointer::xlDefault:
791 setCursorHelper( xModel, PointerStyle::Null, false );
792 break;
794 default:
795 throw uno::RuntimeException(u"Unknown value for Cursor pointer"_ustr );
796 // TODO: isn't this a flaw in the API? It should be allowed to throw an
797 // IllegalArgumentException, or so
800 catch (const uno::Exception&)
802 DBG_UNHANDLED_EXCEPTION("sc.ui");
806 // #TODO perhaps we should switch the return type depending of the filter
807 // type, e.g. return Calc for Calc and Excel if it's an imported doc
808 OUString SAL_CALL
809 ScVbaApplication::getName()
811 return u"Microsoft Excel"_ustr;
814 // #TODO #FIXME get/setDisplayAlerts are just stub impl
815 // here just the status of the switch is set
816 // the function that throws an error message needs to
817 // evaluate this switch in order to know whether it has to disable the
818 // error message thrown by OpenOffice
820 void SAL_CALL
821 ScVbaApplication::setDisplayAlerts(sal_Bool displayAlerts)
823 mrAppSettings.mbDisplayAlerts = displayAlerts;
826 sal_Bool SAL_CALL
827 ScVbaApplication::getDisplayAlerts()
829 return mrAppSettings.mbDisplayAlerts;
832 void SAL_CALL
833 ScVbaApplication::setEnableEvents(sal_Bool bEnable)
835 mrAppSettings.mbEnableEvents = bEnable;
838 sal_Bool SAL_CALL
839 ScVbaApplication::getEnableEvents()
841 return mrAppSettings.mbEnableEvents;
844 void SAL_CALL
845 ScVbaApplication::setEnableCancelKey(sal_Bool bEnable)
847 // Stub, does nothing
848 mrAppSettings.mbEnableCancelKey = bEnable;
851 sal_Bool SAL_CALL
852 ScVbaApplication::getEnableCancelKey()
854 return mrAppSettings.mbEnableCancelKey;
857 sal_Bool SAL_CALL
858 ScVbaApplication::getDisplayFullScreen()
860 SfxViewShell* pShell = excel::getCurrentBestViewShell( mxContext );
861 if ( pShell )
862 return ScViewUtil::IsFullScreen( *pShell );
863 return false;
866 void SAL_CALL
867 ScVbaApplication::setDisplayFullScreen( sal_Bool bSet )
869 // #FIXME calling ScViewUtil::SetFullScreen( *pShell, bSet );
870 // directly results in a strange crash, using dispatch instead
871 if ( bSet != getDisplayFullScreen() )
872 dispatchRequests( getCurrentDocument(), u".uno:FullScreen"_ustr );
875 sal_Bool SAL_CALL
876 ScVbaApplication::getDisplayScrollBars()
878 ScTabViewShell* pShell = excel::getCurrentBestViewShell( mxContext );
879 if ( pShell )
881 return ( pShell->GetViewData().IsHScrollMode() && pShell->GetViewData().IsVScrollMode() );
883 return true;
886 void SAL_CALL
887 ScVbaApplication::setDisplayScrollBars( sal_Bool bSet )
889 // use uno here as it does all he repainting etc. magic
890 uno::Reference< sheet::XSpreadsheetView > xView( getCurrentDocument()->getCurrentController(), uno::UNO_QUERY_THROW );
891 uno::Reference< beans::XPropertySet > xProps( xView, uno::UNO_QUERY );
892 xProps->setPropertyValue(u"HasVerticalScrollBar"_ustr, uno::Any( bSet ) );
893 xProps->setPropertyValue(u"HasHorizontalScrollBar"_ustr, uno::Any( bSet ) );
896 sal_Bool SAL_CALL
897 ScVbaApplication::getDisplayExcel4Menus()
899 return mrAppSettings.mbExcel4Menus;
902 void SAL_CALL
903 ScVbaApplication::setDisplayExcel4Menus( sal_Bool bSet )
905 mrAppSettings.mbExcel4Menus = bSet;
908 sal_Bool SAL_CALL
909 ScVbaApplication::getDisplayNoteIndicator()
911 return mrAppSettings.mbDisplayNoteIndicator;
914 void SAL_CALL
915 ScVbaApplication::setDisplayNoteIndicator( sal_Bool bSet )
917 mrAppSettings.mbDisplayNoteIndicator = bSet;
920 sal_Bool SAL_CALL
921 ScVbaApplication::getShowWindowsInTaskbar()
923 return mrAppSettings.mbShowWindowsInTaskbar;
926 void SAL_CALL
927 ScVbaApplication::setShowWindowsInTaskbar( sal_Bool bSet )
929 mrAppSettings.mbShowWindowsInTaskbar = bSet;
932 sal_Bool SAL_CALL
933 ScVbaApplication::getIteration()
935 return ScModule::get()->GetDocOptions().IsIter();
938 void SAL_CALL
939 ScVbaApplication::setIteration( sal_Bool bSet )
941 uno::Reference< lang::XMultiComponentFactory > xSMgr(
942 mxContext->getServiceManager(), uno::UNO_SET_THROW );
944 uno::Reference< frame::XDesktop > xDesktop
945 (xSMgr->createInstanceWithContext( u"com.sun.star.frame.Desktop"_ustr , mxContext), uno::UNO_QUERY_THROW );
946 uno::Reference< container::XEnumeration > xComponents = xDesktop->getComponents()->createEnumeration();
947 while ( xComponents->hasMoreElements() )
949 uno::Reference< lang::XServiceInfo > xServiceInfo( xComponents->nextElement(), uno::UNO_QUERY );
950 if ( xServiceInfo.is() && xServiceInfo->supportsService( u"com.sun.star.sheet.SpreadsheetDocument"_ustr ) )
952 uno::Reference< beans::XPropertySet > xProps( xServiceInfo, uno::UNO_QUERY );
953 if ( xProps.is() )
954 xProps->setPropertyValue( SC_UNO_ITERENABLED, uno::Any( bSet ) );
957 ScModule* mod = ScModule::get();
958 ScDocOptions aOpts(mod->GetDocOptions());
959 aOpts.SetIter( bSet );
960 mod->SetDocOptions(aOpts);
963 void SAL_CALL
964 ScVbaApplication::Calculate()
966 uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW );
967 uno::Reference< sheet::XCalculatable > xCalculatable( getCurrentDocument(), uno::UNO_QUERY_THROW );
968 xCalculatable->calculateAll();
971 /// @throws uno::RuntimeException
972 static uno::Reference< util::XPathSettings > const & lcl_getPathSettingsService( const uno::Reference< uno::XComponentContext >& xContext )
974 static uno::Reference< util::XPathSettings > xPathSettings( util::PathSettings::create( xContext ) );
975 return xPathSettings;
978 OUString ScVbaApplication::getOfficePath( const OUString& _sPathType )
980 OUString sRetPath;
981 const uno::Reference< util::XPathSettings >& xProps = lcl_getPathSettingsService( mxContext );
984 OUString sUrl;
985 xProps->getPropertyValue( _sPathType ) >>= sUrl;
987 // if it's a list of paths then use the last one
988 sal_Int32 nIndex = sUrl.lastIndexOf( ';' ) ;
989 if ( nIndex > 0 )
990 sUrl = sUrl.copy( nIndex + 1 );
991 ::osl::File::getSystemPathFromFileURL( sUrl, sRetPath );
993 catch (const uno::Exception&)
995 DebugHelper::runtimeexception(ERRCODE_BASIC_METHOD_FAILED);
997 return sRetPath;
1000 void SAL_CALL
1001 ScVbaApplication::setDefaultFilePath( const OUString& DefaultFilePath )
1003 const uno::Reference< util::XPathSettings >& xProps = lcl_getPathSettingsService( mxContext );
1004 OUString aURL;
1005 osl::FileBase::getFileURLFromSystemPath( DefaultFilePath, aURL );
1006 xProps->setWork( aURL );
1009 OUString SAL_CALL
1010 ScVbaApplication::getDefaultFilePath()
1012 return getOfficePath( u"Work"_ustr);
1015 OUString SAL_CALL
1016 ScVbaApplication::getLibraryPath()
1018 return getOfficePath( u"Basic"_ustr);
1021 OUString SAL_CALL
1022 ScVbaApplication::getTemplatesPath()
1024 return getOfficePath( u"Template"_ustr);
1027 OUString SAL_CALL
1028 ScVbaApplication::getPathSeparator()
1030 return OUString( sal_Unicode(SAL_PATHDELIMITER) );
1033 OUString SAL_CALL
1034 ScVbaApplication::getOperatingSystem()
1036 // TODO Solution should contain the version number of the operating system
1037 // too.
1038 #if defined(_WIN32)
1039 return "Windows";
1040 #elif defined(MACOSX)
1041 return "Macintosh";
1042 #elif defined(UNX)
1043 // M. Office is not available on Unix systems, so it is not documented.
1044 return u"Unix"_ustr;
1045 #else
1046 return OUString("Unknown");
1047 #endif
1050 // Helpers for Intersect and Union
1052 namespace {
1054 typedef ::std::list< ScRange > ListOfScRange;
1056 /** Appends all ranges of a VBA Range object in the passed Any to the list of ranges.
1058 @throws script::BasicErrorException
1059 @throws uno::RuntimeException
1061 void lclAddToListOfScRange( ListOfScRange& rList, const uno::Any& rArg )
1063 if( !rArg.hasValue() )
1064 return;
1066 uno::Reference< excel::XRange > xRange( rArg, uno::UNO_QUERY_THROW );
1067 uno::Reference< XCollection > xCol( xRange->Areas( uno::Any() ), uno::UNO_QUERY_THROW );
1068 for( sal_Int32 nIdx = 1, nCount = xCol->getCount(); nIdx <= nCount; ++nIdx )
1070 uno::Reference< excel::XRange > xAreaRange( xCol->Item( uno::Any( nIdx ), uno::Any() ), uno::UNO_QUERY_THROW );
1071 uno::Reference< sheet::XCellRangeAddressable > xAddressable( xAreaRange->getCellRange(), uno::UNO_QUERY_THROW );
1072 ScRange aScRange;
1073 ScUnoConversion::FillScRange( aScRange, xAddressable->getRangeAddress() );
1074 rList.push_back( aScRange );
1078 /** Returns true, if the passed ranges can be expressed by a single range. The
1079 new range will be contained in r1 then, the range r2 can be removed. */
1080 bool lclTryJoin( ScRange& r1, const ScRange& r2 )
1082 // 1) r2 is completely inside r1
1083 if( r1.Contains( r2 ) )
1084 return true;
1086 // 2) r1 is completely inside r2
1087 if( r2.Contains( r1 ) )
1089 r1 = r2;
1090 return true;
1093 SCCOL n1L = r1.aStart.Col();
1094 SCCOL n1R = r1.aEnd.Col();
1095 SCROW n1T = r1.aStart.Row();
1096 SCROW n1B = r1.aEnd.Row();
1097 SCCOL n2L = r2.aStart.Col();
1098 SCCOL n2R = r2.aEnd.Col();
1099 SCROW n2T = r2.aStart.Row();
1100 SCROW n2B = r2.aEnd.Row();
1102 // 3) r1 and r2 have equal upper and lower border
1103 if( (n1T == n2T) && (n1B == n2B) )
1105 // check that r1 overlaps or touches r2
1106 if( ((n1L < n2L) && (n2L - 1 <= n1R)) || ((n2L < n1L) && (n1L - 1 <= n2R)) )
1108 r1.aStart.SetCol( ::std::min( n1L, n2L ) );
1109 r1.aEnd.SetCol( ::std::max( n1R, n2R ) );
1110 return true;
1112 return false;
1115 // 4) r1 and r2 have equal left and right border
1116 if( (n1L == n2L) && (n1R == n2R) )
1118 // check that r1 overlaps or touches r2
1119 if( ((n1T < n2T) && (n2T + 1 <= n1B)) || ((n2T < n1T) && (n1T + 1 <= n2B)) )
1121 r1.aStart.SetRow( ::std::min( n1T, n2T ) );
1122 r1.aEnd.SetRow( ::std::max( n1B, n2B ) );
1123 return true;
1125 return false;
1128 // 5) cannot join these ranges
1129 return false;
1132 /** Strips out ranges that are contained by other ranges, joins ranges that can be joined
1133 together (aligned borders, e.g. A4:D10 and B4:E10 would be combined to A4:E10. */
1134 void lclJoinRanges( ListOfScRange& rList )
1136 ListOfScRange::iterator aOuterIt = rList.begin();
1137 while( aOuterIt != rList.end() )
1139 bool bAnyErased = false; // true = any range erased from rList
1140 ListOfScRange::iterator aInnerIt = rList.begin();
1141 while( aInnerIt != rList.end() )
1143 bool bInnerErased = false; // true = aInnerIt erased from rList
1144 // do not compare a range with itself
1145 if( (aOuterIt != aInnerIt) && lclTryJoin( *aOuterIt, *aInnerIt ) )
1147 // aOuterIt points to joined range, aInnerIt will be removed
1148 aInnerIt = rList.erase( aInnerIt );
1149 bInnerErased = bAnyErased = true;
1151 /* If aInnerIt has been erased from rList, it already points to
1152 the next element (return value of list::erase()). */
1153 if( !bInnerErased )
1154 ++aInnerIt;
1156 // if any range has been erased, repeat outer loop with the same range
1157 if( !bAnyErased )
1158 ++aOuterIt;
1162 /** Intersects the passed list with all ranges of a VBA Range object in the passed Any.
1164 @throws script::BasicErrorException
1165 @throws uno::RuntimeException
1167 void lclIntersectRanges( ListOfScRange& rList, const uno::Any& rArg )
1169 // extract the ranges from the passed argument, will throw on invalid data
1170 ListOfScRange aList2;
1171 lclAddToListOfScRange( aList2, rArg );
1172 // do nothing, if the passed list is already empty
1173 if( rList.empty() || aList2.empty() )
1174 return;
1176 // save original list in a local
1177 ListOfScRange aList1;
1178 aList1.swap( rList );
1179 // join ranges from passed argument
1180 lclJoinRanges( aList2 );
1181 // calculate intersection of the ranges in both lists
1182 for( const auto& rOuterItem : aList1 )
1184 for( const auto& rInnerItem : aList2 )
1186 if( rOuterItem.Intersects( rInnerItem ) )
1188 ScRange aIsectRange(
1189 std::max( rOuterItem.aStart.Col(), rInnerItem.aStart.Col() ),
1190 std::max( rOuterItem.aStart.Row(), rInnerItem.aStart.Row() ),
1191 std::max( rOuterItem.aStart.Tab(), rInnerItem.aStart.Tab() ),
1192 std::min( rOuterItem.aEnd.Col(), rInnerItem.aEnd.Col() ),
1193 std::min( rOuterItem.aEnd.Row(), rInnerItem.aEnd.Row() ),
1194 std::min( rOuterItem.aEnd.Tab(), rInnerItem.aEnd.Tab() ) );
1195 rList.push_back( aIsectRange );
1199 // again, join the result ranges
1200 lclJoinRanges( rList );
1203 /** Creates a VBA Range object from the passed list of ranges.
1205 @throws uno::RuntimeException
1207 uno::Reference< excel::XRange > lclCreateVbaRange(
1208 const uno::Reference< uno::XComponentContext >& rxContext,
1209 const uno::Reference< frame::XModel >& rxModel,
1210 const ListOfScRange& rList )
1212 ScDocShell* pDocShell = excel::getDocShell( rxModel );
1213 if( !pDocShell )
1214 throw uno::RuntimeException();
1216 ScRangeList aCellRanges;
1217 for( const auto& rItem : rList )
1218 aCellRanges.push_back( rItem );
1220 if( aCellRanges.size() == 1 )
1222 uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pDocShell, aCellRanges.front() ) );
1223 return new ScVbaRange( excel::getUnoSheetModuleObj( xRange ), rxContext, xRange );
1225 if( aCellRanges.size() > 1 )
1227 uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pDocShell, aCellRanges ) );
1228 return new ScVbaRange( excel::getUnoSheetModuleObj( xRanges ), rxContext, xRanges );
1230 return nullptr;
1233 } // namespace
1235 uno::Reference< excel::XRange > SAL_CALL ScVbaApplication::Intersect(
1236 const uno::Reference< excel::XRange >& rArg1, const uno::Reference< excel::XRange >& rArg2,
1237 const uno::Any& rArg3, const uno::Any& rArg4, const uno::Any& rArg5, const uno::Any& rArg6,
1238 const uno::Any& rArg7, const uno::Any& rArg8, const uno::Any& rArg9, const uno::Any& rArg10,
1239 const uno::Any& rArg11, const uno::Any& rArg12, const uno::Any& rArg13, const uno::Any& rArg14,
1240 const uno::Any& rArg15, const uno::Any& rArg16, const uno::Any& rArg17, const uno::Any& rArg18,
1241 const uno::Any& rArg19, const uno::Any& rArg20, const uno::Any& rArg21, const uno::Any& rArg22,
1242 const uno::Any& rArg23, const uno::Any& rArg24, const uno::Any& rArg25, const uno::Any& rArg26,
1243 const uno::Any& rArg27, const uno::Any& rArg28, const uno::Any& rArg29, const uno::Any& rArg30 )
1245 if( !rArg1.is() || !rArg2.is() )
1246 DebugHelper::basicexception( ERRCODE_BASIC_BAD_PARAMETER, {} );
1248 // initialize the result list with 1st parameter, join its ranges together
1249 ListOfScRange aList;
1250 lclAddToListOfScRange( aList, uno::Any( rArg1 ) );
1251 lclJoinRanges( aList );
1253 // process all other parameters, this updates the list with intersection
1254 lclIntersectRanges( aList, uno::Any( rArg2 ) );
1255 lclIntersectRanges( aList, rArg3 );
1256 lclIntersectRanges( aList, rArg4 );
1257 lclIntersectRanges( aList, rArg5 );
1258 lclIntersectRanges( aList, rArg6 );
1259 lclIntersectRanges( aList, rArg7 );
1260 lclIntersectRanges( aList, rArg8 );
1261 lclIntersectRanges( aList, rArg9 );
1262 lclIntersectRanges( aList, rArg10 );
1263 lclIntersectRanges( aList, rArg11 );
1264 lclIntersectRanges( aList, rArg12 );
1265 lclIntersectRanges( aList, rArg13 );
1266 lclIntersectRanges( aList, rArg14 );
1267 lclIntersectRanges( aList, rArg15 );
1268 lclIntersectRanges( aList, rArg16 );
1269 lclIntersectRanges( aList, rArg17 );
1270 lclIntersectRanges( aList, rArg18 );
1271 lclIntersectRanges( aList, rArg19 );
1272 lclIntersectRanges( aList, rArg20 );
1273 lclIntersectRanges( aList, rArg21 );
1274 lclIntersectRanges( aList, rArg22 );
1275 lclIntersectRanges( aList, rArg23 );
1276 lclIntersectRanges( aList, rArg24 );
1277 lclIntersectRanges( aList, rArg25 );
1278 lclIntersectRanges( aList, rArg26 );
1279 lclIntersectRanges( aList, rArg27 );
1280 lclIntersectRanges( aList, rArg28 );
1281 lclIntersectRanges( aList, rArg29 );
1282 lclIntersectRanges( aList, rArg30 );
1284 // create the VBA Range object
1285 return lclCreateVbaRange( mxContext, getCurrentDocument(), aList );
1288 uno::Reference< excel::XRange > SAL_CALL ScVbaApplication::Union(
1289 const uno::Reference< excel::XRange >& rArg1, const uno::Reference< excel::XRange >& rArg2,
1290 const uno::Any& rArg3, const uno::Any& rArg4, const uno::Any& rArg5, const uno::Any& rArg6,
1291 const uno::Any& rArg7, const uno::Any& rArg8, const uno::Any& rArg9, const uno::Any& rArg10,
1292 const uno::Any& rArg11, const uno::Any& rArg12, const uno::Any& rArg13, const uno::Any& rArg14,
1293 const uno::Any& rArg15, const uno::Any& rArg16, const uno::Any& rArg17, const uno::Any& rArg18,
1294 const uno::Any& rArg19, const uno::Any& rArg20, const uno::Any& rArg21, const uno::Any& rArg22,
1295 const uno::Any& rArg23, const uno::Any& rArg24, const uno::Any& rArg25, const uno::Any& rArg26,
1296 const uno::Any& rArg27, const uno::Any& rArg28, const uno::Any& rArg29, const uno::Any& rArg30 )
1298 if( !rArg1.is() || !rArg2.is() )
1299 DebugHelper::basicexception( ERRCODE_BASIC_BAD_PARAMETER, {} );
1301 ListOfScRange aList;
1302 lclAddToListOfScRange( aList, uno::Any( rArg1 ) );
1303 lclAddToListOfScRange( aList, uno::Any( rArg2 ) );
1304 lclAddToListOfScRange( aList, rArg3 );
1305 lclAddToListOfScRange( aList, rArg4 );
1306 lclAddToListOfScRange( aList, rArg5 );
1307 lclAddToListOfScRange( aList, rArg6 );
1308 lclAddToListOfScRange( aList, rArg7 );
1309 lclAddToListOfScRange( aList, rArg8 );
1310 lclAddToListOfScRange( aList, rArg9 );
1311 lclAddToListOfScRange( aList, rArg10 );
1312 lclAddToListOfScRange( aList, rArg11 );
1313 lclAddToListOfScRange( aList, rArg12 );
1314 lclAddToListOfScRange( aList, rArg13 );
1315 lclAddToListOfScRange( aList, rArg14 );
1316 lclAddToListOfScRange( aList, rArg15 );
1317 lclAddToListOfScRange( aList, rArg16 );
1318 lclAddToListOfScRange( aList, rArg17 );
1319 lclAddToListOfScRange( aList, rArg18 );
1320 lclAddToListOfScRange( aList, rArg19 );
1321 lclAddToListOfScRange( aList, rArg20 );
1322 lclAddToListOfScRange( aList, rArg21 );
1323 lclAddToListOfScRange( aList, rArg22 );
1324 lclAddToListOfScRange( aList, rArg23 );
1325 lclAddToListOfScRange( aList, rArg24 );
1326 lclAddToListOfScRange( aList, rArg25 );
1327 lclAddToListOfScRange( aList, rArg26 );
1328 lclAddToListOfScRange( aList, rArg27 );
1329 lclAddToListOfScRange( aList, rArg28 );
1330 lclAddToListOfScRange( aList, rArg29 );
1331 lclAddToListOfScRange( aList, rArg30 );
1333 // simply join together all ranges as much as possible, strip out covered ranges etc.
1334 lclJoinRanges( aList );
1336 // create the VBA Range object
1337 return lclCreateVbaRange( mxContext, getCurrentDocument(), aList );
1340 double SAL_CALL
1341 ScVbaApplication::InchesToPoints( double Inches )
1343 return o3tl::convert(Inches, o3tl::Length::in, o3tl::Length::pt);
1346 double SAL_CALL
1347 ScVbaApplication::CentimetersToPoints( double Centimeters )
1349 return o3tl::convert(Centimeters, o3tl::Length::cm, o3tl::Length::pt);
1352 void
1353 ScVbaApplication::Volatile( const uno::Any& aVolatile )
1355 bool bVolatile = true;
1356 aVolatile >>= bVolatile;
1357 SbMethod* pMeth = StarBASIC::GetActiveMethod();
1358 if ( pMeth )
1360 uno::Reference< frame::XModel > xModel( getCurrentDocument() );
1361 if ( ScDocShell* pShell = excel::getDocShell( xModel ))
1363 ScDocument& rDoc = pShell->GetDocument();
1364 rDoc.GetMacroManager()->SetUserFuncVolatile( pMeth->GetName(), bVolatile);
1368 // this is bound to break when loading the document
1371 sal_Bool SAL_CALL
1372 ScVbaApplication::getDisplayFormulaBar()
1374 bool bRes = false;
1375 ScTabViewShell* pViewShell = excel::getCurrentBestViewShell( mxContext );
1376 if ( pViewShell )
1378 SfxBoolItem sfxFormBar( FID_TOGGLEINPUTLINE);
1379 SfxAllItemSet reqList( SfxGetpApp()->GetPool() );
1380 reqList.Put( sfxFormBar );
1382 pViewShell->GetState( reqList );
1383 if ( const SfxBoolItem *pItem = reqList.GetItemIfSet( FID_TOGGLEINPUTLINE, false ) )
1384 bRes = pItem->GetValue();
1386 return bRes;
1389 void SAL_CALL
1390 ScVbaApplication::setDisplayFormulaBar( sal_Bool _displayformulabar )
1392 ScTabViewShell* pViewShell = excel::getCurrentBestViewShell( mxContext );
1393 if ( pViewShell && ( _displayformulabar != getDisplayFormulaBar() ) )
1395 SfxAllItemSet reqList( SfxGetpApp()->GetPool() );
1396 SfxRequest aReq( FID_TOGGLEINPUTLINE, SfxCallMode::SLOT, reqList );
1397 pViewShell->Execute( aReq );
1401 uno::Any SAL_CALL
1402 ScVbaApplication::Caller( const uno::Any& /*aIndex*/ )
1404 StarBASIC* pBasic = SfxApplication::GetBasic();
1405 SbMethod* pMeth = static_cast<SbMethod*>(pBasic->GetRtl()->Find( u"FuncCaller"_ustr, SbxClassType::Method ));
1406 uno::Any aRet;
1407 if ( pMeth )
1409 SbxVariableRef refTemp = pMeth;
1410 // forces a broadcast
1411 SbxVariableRef pNew = new SbxMethod( *static_cast<SbxMethod*>(pMeth));
1412 aRet = sbxToUnoValue( pNew.get() );
1414 return aRet;
1417 uno::Reference< frame::XModel >
1418 ScVbaApplication::getCurrentDocument()
1420 return getCurrentExcelDoc(mxContext);
1423 uno::Any SAL_CALL
1424 ScVbaApplication::MenuBars( const uno::Any& aIndex )
1426 uno::Reference< XCommandBars > xCommandBars( CommandBars( uno::Any() ), uno::UNO_QUERY_THROW );
1427 uno::Reference< XCollection > xMenuBars( new ScVbaMenuBars( this, mxContext, xCommandBars ) );
1428 if ( aIndex.hasValue() )
1430 return xMenuBars->Item( aIndex, uno::Any() );
1433 return uno::Any( xMenuBars );
1436 uno::Any SAL_CALL
1437 ScVbaApplication::Rows( const uno::Any& aIndex )
1439 uno::Reference< excel::XWorksheet > xWorksheet = getActiveSheet();
1440 if ( xWorksheet.is() )
1441 return uno::Any( xWorksheet->Rows( aIndex ) );
1442 return uno::Any();
1445 void SAL_CALL ScVbaApplication::OnKey( const OUString& Key, const uno::Any& Procedure )
1449 // Perhaps we can catch some excel specific
1450 // related behaviour here
1451 VbaApplicationBase::OnKey( Key, Procedure );
1453 catch( container::NoSuchElementException& )
1455 // #TODO special handling for unhandled
1456 // bindings
1460 void SAL_CALL ScVbaApplication::setScreenUpdating(sal_Bool bUpdate)
1462 VbaApplicationBase::setScreenUpdating( bUpdate );
1464 uno::Reference< frame::XModel > xModel( getCurrentExcelDoc( mxContext ), uno::UNO_SET_THROW );
1466 ScDocShell* pDocShell = excel::getDocShell( xModel );
1467 if (!pDocShell)
1468 return;
1469 ScDocument& rDoc = pDocShell->GetDocument();
1471 if( bUpdate )
1473 // Since setting ScreenUpdating from user code might be unpaired, avoid calling function,
1474 // that asserts correct lock/unlock order and number, when not locked.
1475 if(rDoc.IsAdjustHeightLocked())
1476 rDoc.UnlockAdjustHeight();
1477 if( !rDoc.IsAdjustHeightLocked() )
1478 pDocShell->UpdateAllRowHeights();
1480 else
1482 rDoc.LockAdjustHeight();
1486 void SAL_CALL ScVbaApplication::Undo()
1488 uno::Reference< frame::XModel > xModel( getThisExcelDoc( mxContext ), uno::UNO_SET_THROW );
1490 ScTabViewShell* pViewShell = excel::getBestViewShell( xModel );
1491 if ( pViewShell )
1492 dispatchExecute( pViewShell, SID_UNDO );
1495 // XInterfaceWithIID
1497 OUString SAL_CALL
1498 ScVbaApplication::getIID()
1500 return u"{82154425-0FBF-11d4-8313-005004526AB4}"_ustr;
1503 // XConnectable
1505 OUString SAL_CALL
1506 ScVbaApplication::GetIIDForClassItselfNotCoclass()
1508 return u"{82154426-0FBF-11D4-8313-005004526AB4}"_ustr;
1511 TypeAndIID SAL_CALL
1512 ScVbaApplication::GetConnectionPoint()
1514 TypeAndIID aResult =
1515 { cppu::UnoType<excel::XApplicationOutgoing>::get(),
1516 u"{82154427-0FBF-11D4-8313-005004526AB4}"_ustr
1519 return aResult;
1522 uno::Reference<XConnectionPoint> SAL_CALL
1523 ScVbaApplication::FindConnectionPoint()
1525 uno::Reference<XConnectionPoint> xCP(new ScVbaApplicationOutgoingConnectionPoint(this));
1526 return xCP;
1529 // XSinkCaller
1531 void SAL_CALL
1532 ScVbaApplication::CallSinks( const OUString& Method, uno::Sequence< uno::Any >& Arguments )
1534 for (auto& i : mvSinks)
1536 if (i.is())
1537 i->Call(Method, Arguments);
1541 OUString
1542 ScVbaApplication::getServiceImplName()
1544 return u"ScVbaApplication"_ustr;
1547 uno::Sequence< OUString >
1548 ScVbaApplication::getServiceNames()
1550 static uno::Sequence< OUString > aServiceNames
1552 u"ooo.vba.excel.Application"_ustr
1554 return aServiceNames;
1558 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
1559 Calc_ScVbaApplication_get_implementation(
1560 css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& )
1562 return cppu::acquire(new ScVbaApplication(context));
1566 // ScVbaApplicationOutgoingConnectionPoint
1568 ScVbaApplicationOutgoingConnectionPoint::ScVbaApplicationOutgoingConnectionPoint( ScVbaApplication* pApp ) :
1569 mpApp(pApp)
1573 // XConnectionPoint
1574 sal_uInt32 SAL_CALL
1575 ScVbaApplicationOutgoingConnectionPoint::Advise( const uno::Reference< XSink >& Sink )
1577 return mpApp->AddSink(Sink);
1580 void SAL_CALL
1581 ScVbaApplicationOutgoingConnectionPoint::Unadvise( sal_uInt32 Cookie )
1583 mpApp->RemoveSink( Cookie );
1586 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */