1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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"
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>
82 #include "excelvbahelper.hxx"
83 #include <basic/sbxobj.hxx>
85 #include <viewutil.hxx>
86 #include <docoptio.hxx>
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
;
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 )
122 ScVbaAppSettings
& ScVbaStaticAppSettings()
124 static ScVbaAppSettings SINGLETON
;
128 class ScVbaApplicationOutgoingConnectionPoint
: public cppu::WeakImplHelper
<XConnectionPoint
>
131 ScVbaApplication
* mpApp
;
134 ScVbaApplicationOutgoingConnectionPoint( ScVbaApplication
* pApp
);
137 sal_uInt32 SAL_CALL
Advise(const uno::Reference
< XSink
>& Sink
) override
;
138 void SAL_CALL
Unadvise( sal_uInt32 Cookie
) override
;
144 ScVbaApplication::AddSink( const uno::Reference
< XSink
>& xSink
)
147 SolarMutexGuard aGuard
;
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();
157 ScVbaApplication::RemoveSink( sal_uInt32 nNumber
)
159 if (nNumber
< 1 || nNumber
> mvSinks
.size())
162 mvSinks
[nNumber
-1] = uno::Reference
< XSink
>();
165 ScVbaApplication::ScVbaApplication( const uno::Reference
<uno::XComponentContext
>& xContext
) :
166 ScVbaApplication_BASE( xContext
),
167 mrAppSettings( ScVbaStaticAppSettings() ),
172 ScVbaApplication::~ScVbaApplication()
176 /*static*/ bool ScVbaApplication::getDocumentEventsEnabled()
178 return ScVbaStaticAppSettings().mbEnableEvents
;
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();
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. */
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() );
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
);
221 ScVbaApplication::getValue( const OUString
& PropertyName
)
223 uno::Reference
< script::XInvocation
> xWSF( new ScVbaWSFunction( this, mxContext
) );
224 return xWSF
->getValue( PropertyName
);
228 ScVbaApplication::hasMethod( const OUString
& Name
)
230 uno::Reference
< script::XInvocation
> xWSF( new ScVbaWSFunction( this, mxContext
) );
231 return xWSF
->hasMethod( Name
);
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
) );
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
);
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
);
328 uno::Reference
< sheet::XSheetCellRangeContainer
> xRanges( aSelection
, ::uno::UNO_QUERY
);
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
) ) );
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
);
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
) );
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
380 throw uno::RuntimeException(u
"Unexpected XFileDialogSelectedItems implementation"_ustr
);
382 auto const & rItemVector
= pItems
->getItems();
384 if (!bMultiSelect
) // only 1 selection allowed - return path
387 if (!rItemVector
.empty())
388 aPath
= rItemVector
.at(0);
389 return uno::Any(aPath
);
393 // convert to sequence
394 return uno::Any(comphelper::containerToSequence(rItemVector
));
399 ScVbaApplication::International( sal_Int32
/*Index*/ )
401 // complete stub for now
402 // #TODO flesh out some of the Indices we could handle
408 ScVbaApplication::FileDialog( const uno::Any
& DialogType
)
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
);
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() );
435 ScVbaApplication::Worksheets( const uno::Any
& aIndex
)
437 uno::Reference
< excel::XWorkbook
> xWorkbook( getActiveWorkbook(), uno::UNO_SET_THROW
);
438 return xWorkbook
->Worksheets( aIndex
);
442 ScVbaApplication::WorksheetFunction( )
444 return uno::Any( uno::Reference
< script::XInvocation
>( new ScVbaWSFunction( this, mxContext
) ) );
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
454 return uno::Any( getActiveWorkbook()->getActiveSheet()->Range( uno::Any( Name
), aVoid
) );
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
) );
477 ScVbaApplication::getCutCopyMode()
479 //# FIXME TODO, implementation
486 ScVbaApplication::setCutCopyMode( const uno::Any
& /* _cutcopymode */ )
488 //# FIXME TODO, implementation
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
);
508 ScVbaApplication::setStatusBar( const uno::Any
& _statusbar
)
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 );
521 xStatusIndicator
->end(); // restore normal state for empty text
523 else if( _statusbar
>>= bDefault
)
527 xStatusIndicator
->end();
528 setDisplayStatusBar( true );
532 throw uno::RuntimeException(u
"Invalid parameter. It should be a string or False"_ustr
);
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
;
543 return excel::XlCalculation::xlCalculationManual
;
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
);
553 case excel::XlCalculation::xlCalculationManual
:
554 xCalc
->enableAutomaticCalculation(false);
556 case excel::XlCalculation::xlCalculationAutomatic
:
557 case excel::XlCalculation::xlCalculationSemiautomatic
:
558 xCalc
->enableAutomaticCalculation(true);
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() );
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
));
583 pMeth
->SetParameters( aArgs
.get() );
584 SbxVariableRef refTemp
= pMeth
;
585 // forces a broadcast
586 SbxVariableRef pNew
= new SbxMethod( *static_cast<SbxMethod
*>(pMeth
));
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
);
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
);
630 // Fixme - check if this is reasonable/desired behavior
631 throw uno::RuntimeException(u
"No activeSheet available"_ustr
);
637 /*******************************************************************************
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 *******************************************************************************/
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
);
665 if( Reference
>>= sRangeName
)
667 ScTabViewShell
* pShell
= excel::getCurrentBestViewShell( mxContext
);
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
);
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();
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
);
712 uno::Reference
< excel::XRange
> xRange
;
713 if( Reference
>>= xRange
)
715 ScTabViewShell
* pShell
= excel::getCurrentBestViewShell( mxContext
);
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
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();
740 gridWindow
->GrabFocus();
745 throw uno::RuntimeException(u
"invalid reference or name"_ustr
);
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
;
764 return excel::XlMousePointer::xlDefault
;
769 ScVbaApplication::setCursor( sal_Int32 _cursor
)
773 uno::Reference
< frame::XModel
> xModel( getCurrentDocument(), uno::UNO_SET_THROW
);
776 case excel::XlMousePointer::xlNorthwestArrow
:
778 setCursorHelper( xModel
, PointerStyle::Arrow
, false );
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 );
789 case excel::XlMousePointer::xlDefault
:
791 setCursorHelper( xModel
, PointerStyle::Null
, false );
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
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
821 ScVbaApplication::setDisplayAlerts(sal_Bool displayAlerts
)
823 mrAppSettings
.mbDisplayAlerts
= displayAlerts
;
827 ScVbaApplication::getDisplayAlerts()
829 return mrAppSettings
.mbDisplayAlerts
;
833 ScVbaApplication::setEnableEvents(sal_Bool bEnable
)
835 mrAppSettings
.mbEnableEvents
= bEnable
;
839 ScVbaApplication::getEnableEvents()
841 return mrAppSettings
.mbEnableEvents
;
845 ScVbaApplication::setEnableCancelKey(sal_Bool bEnable
)
847 // Stub, does nothing
848 mrAppSettings
.mbEnableCancelKey
= bEnable
;
852 ScVbaApplication::getEnableCancelKey()
854 return mrAppSettings
.mbEnableCancelKey
;
858 ScVbaApplication::getDisplayFullScreen()
860 SfxViewShell
* pShell
= excel::getCurrentBestViewShell( mxContext
);
862 return ScViewUtil::IsFullScreen( *pShell
);
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
);
876 ScVbaApplication::getDisplayScrollBars()
878 ScTabViewShell
* pShell
= excel::getCurrentBestViewShell( mxContext
);
881 return ( pShell
->GetViewData().IsHScrollMode() && pShell
->GetViewData().IsVScrollMode() );
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
) );
897 ScVbaApplication::getDisplayExcel4Menus()
899 return mrAppSettings
.mbExcel4Menus
;
903 ScVbaApplication::setDisplayExcel4Menus( sal_Bool bSet
)
905 mrAppSettings
.mbExcel4Menus
= bSet
;
909 ScVbaApplication::getDisplayNoteIndicator()
911 return mrAppSettings
.mbDisplayNoteIndicator
;
915 ScVbaApplication::setDisplayNoteIndicator( sal_Bool bSet
)
917 mrAppSettings
.mbDisplayNoteIndicator
= bSet
;
921 ScVbaApplication::getShowWindowsInTaskbar()
923 return mrAppSettings
.mbShowWindowsInTaskbar
;
927 ScVbaApplication::setShowWindowsInTaskbar( sal_Bool bSet
)
929 mrAppSettings
.mbShowWindowsInTaskbar
= bSet
;
933 ScVbaApplication::getIteration()
935 return ScModule::get()->GetDocOptions().IsIter();
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
);
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
);
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
)
981 const uno::Reference
< util::XPathSettings
>& xProps
= lcl_getPathSettingsService( mxContext
);
985 xProps
->getPropertyValue( _sPathType
) >>= sUrl
;
987 // if it's a list of paths then use the last one
988 sal_Int32 nIndex
= sUrl
.lastIndexOf( ';' ) ;
990 sUrl
= sUrl
.copy( nIndex
+ 1 );
991 ::osl::File::getSystemPathFromFileURL( sUrl
, sRetPath
);
993 catch (const uno::Exception
&)
995 DebugHelper::runtimeexception(ERRCODE_BASIC_METHOD_FAILED
);
1001 ScVbaApplication::setDefaultFilePath( const OUString
& DefaultFilePath
)
1003 const uno::Reference
< util::XPathSettings
>& xProps
= lcl_getPathSettingsService( mxContext
);
1005 osl::FileBase::getFileURLFromSystemPath( DefaultFilePath
, aURL
);
1006 xProps
->setWork( aURL
);
1010 ScVbaApplication::getDefaultFilePath()
1012 return getOfficePath( u
"Work"_ustr
);
1016 ScVbaApplication::getLibraryPath()
1018 return getOfficePath( u
"Basic"_ustr
);
1022 ScVbaApplication::getTemplatesPath()
1024 return getOfficePath( u
"Template"_ustr
);
1028 ScVbaApplication::getPathSeparator()
1030 return OUString( sal_Unicode(SAL_PATHDELIMITER
) );
1034 ScVbaApplication::getOperatingSystem()
1036 // TODO Solution should contain the version number of the operating system
1040 #elif defined(MACOSX)
1043 // M. Office is not available on Unix systems, so it is not documented.
1044 return u
"Unix"_ustr
;
1046 return OUString("Unknown");
1050 // Helpers for Intersect and Union
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() )
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
);
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
) )
1086 // 2) r1 is completely inside r2
1087 if( r2
.Contains( r1
) )
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
) );
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
) );
1128 // 5) cannot join these ranges
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()). */
1156 // if any range has been erased, repeat outer loop with the same range
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() )
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
);
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
);
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
);
1341 ScVbaApplication::InchesToPoints( double Inches
)
1343 return o3tl::convert(Inches
, o3tl::Length::in
, o3tl::Length::pt
);
1347 ScVbaApplication::CentimetersToPoints( double Centimeters
)
1349 return o3tl::convert(Centimeters
, o3tl::Length::cm
, o3tl::Length::pt
);
1353 ScVbaApplication::Volatile( const uno::Any
& aVolatile
)
1355 bool bVolatile
= true;
1356 aVolatile
>>= bVolatile
;
1357 SbMethod
* pMeth
= StarBASIC::GetActiveMethod();
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
1372 ScVbaApplication::getDisplayFormulaBar()
1375 ScTabViewShell
* pViewShell
= excel::getCurrentBestViewShell( mxContext
);
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();
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
);
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
));
1409 SbxVariableRef refTemp
= pMeth
;
1410 // forces a broadcast
1411 SbxVariableRef pNew
= new SbxMethod( *static_cast<SbxMethod
*>(pMeth
));
1412 aRet
= sbxToUnoValue( pNew
.get() );
1417 uno::Reference
< frame::XModel
>
1418 ScVbaApplication::getCurrentDocument()
1420 return getCurrentExcelDoc(mxContext
);
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
);
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
) );
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
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
);
1469 ScDocument
& rDoc
= pDocShell
->GetDocument();
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();
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
);
1492 dispatchExecute( pViewShell
, SID_UNDO
);
1495 // XInterfaceWithIID
1498 ScVbaApplication::getIID()
1500 return u
"{82154425-0FBF-11d4-8313-005004526AB4}"_ustr
;
1506 ScVbaApplication::GetIIDForClassItselfNotCoclass()
1508 return u
"{82154426-0FBF-11D4-8313-005004526AB4}"_ustr
;
1512 ScVbaApplication::GetConnectionPoint()
1514 TypeAndIID aResult
=
1515 { cppu::UnoType
<excel::XApplicationOutgoing
>::get(),
1516 u
"{82154427-0FBF-11D4-8313-005004526AB4}"_ustr
1522 uno::Reference
<XConnectionPoint
> SAL_CALL
1523 ScVbaApplication::FindConnectionPoint()
1525 uno::Reference
<XConnectionPoint
> xCP(new ScVbaApplicationOutgoingConnectionPoint(this));
1532 ScVbaApplication::CallSinks( const OUString
& Method
, uno::Sequence
< uno::Any
>& Arguments
)
1534 for (auto& i
: mvSinks
)
1537 i
->Call(Method
, Arguments
);
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
) :
1575 ScVbaApplicationOutgoingConnectionPoint::Advise( const uno::Reference
< XSink
>& Sink
)
1577 return mpApp
->AddSink(Sink
);
1581 ScVbaApplicationOutgoingConnectionPoint::Unadvise( sal_uInt32 Cookie
)
1583 mpApp
->RemoveSink( Cookie
);
1586 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */