nss: upgrade to release 3.73
[LibreOffice.git] / sc / source / ui / vba / vbaapplication.cxx
blobced6d0c70eb3f853d3cd5ae35a06ea8617a41f54
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>
38 #include "vbaapplication.hxx"
39 #include "vbaworkbooks.hxx"
40 #include "vbaworkbook.hxx"
41 #include "vbarange.hxx"
42 #include "vbawsfunction.hxx"
43 #include "vbadialogs.hxx"
44 #include "vbawindow.hxx"
45 #include "vbawindows.hxx"
46 #include "vbamenubars.hxx"
47 #include <tabvwsh.hxx>
48 #include <gridwin.hxx>
49 #include "vbanames.hxx"
50 #include <vbahelper/vbashape.hxx>
51 #include "vbatextboxshape.hxx"
52 #include "vbaovalshape.hxx"
53 #include "vbalineshape.hxx"
54 #include "vbaassistant.hxx"
55 #include <sc.hrc>
56 #include <macromgr.hxx>
57 #include "vbafiledialog.hxx"
59 #include <osl/file.hxx>
60 #include <rtl/instance.hxx>
62 #include <sfx2/bindings.hxx>
63 #include <sfx2/request.hxx>
64 #include <sfx2/app.hxx>
65 #include <vcl/svapp.hxx>
67 #include <tools/diagnose_ex.h>
69 #include <basic/sbx.hxx>
70 #include <basic/sbstar.hxx>
71 #include <basic/sbuno.hxx>
72 #include <basic/sbmeth.hxx>
73 #include <basic/sberrors.hxx>
75 #include <convuno.hxx>
76 #include <cellsuno.hxx>
77 #include <unonames.hxx>
78 #include <docsh.hxx>
79 #include "excelvbahelper.hxx"
81 #include <basic/sbxobj.hxx>
83 #include <viewutil.hxx>
84 #include <docoptio.hxx>
85 #include <scmod.hxx>
86 #include <scdll.hxx>
88 using namespace ::ooo::vba;
89 using namespace ::com::sun::star;
90 using ::com::sun::star::uno::Reference;
91 using ::com::sun::star::uno::UNO_QUERY_THROW;
92 using ::com::sun::star::uno::UNO_QUERY;
94 /** Global application settings shared by all open workbooks. */
95 struct ScVbaAppSettings
97 bool mbDisplayAlerts;
98 bool mbEnableEvents;
99 bool mbExcel4Menus;
100 bool mbDisplayNoteIndicator;
101 bool mbShowWindowsInTaskbar;
102 bool mbEnableCancelKey;
103 explicit ScVbaAppSettings();
106 ScVbaAppSettings::ScVbaAppSettings() :
107 mbDisplayAlerts( true ),
108 mbEnableEvents( true ),
109 mbExcel4Menus( false ),
110 mbDisplayNoteIndicator( true ),
111 mbShowWindowsInTaskbar( true ),
112 mbEnableCancelKey( false )
116 namespace {
118 struct ScVbaStaticAppSettings : public ::rtl::Static< ScVbaAppSettings, ScVbaStaticAppSettings > {};
120 class ScVbaApplicationOutgoingConnectionPoint : public cppu::WeakImplHelper<XConnectionPoint>
122 private:
123 ScVbaApplication* mpApp;
125 public:
126 ScVbaApplicationOutgoingConnectionPoint( ScVbaApplication* pApp );
128 // XConnectionPoint
129 sal_uInt32 SAL_CALL Advise(const uno::Reference< XSink >& Sink ) override;
130 void SAL_CALL Unadvise( sal_uInt32 Cookie ) override;
135 sal_uInt32
136 ScVbaApplication::AddSink( const uno::Reference< XSink >& xSink )
139 SolarMutexGuard aGuard;
140 ScDLL::Init();
142 // No harm in potentially calling this several times
143 SC_MOD()->RegisterAutomationApplicationEventsCaller( uno::Reference< XSinkCaller >(this) );
144 mvSinks.push_back(xSink);
145 return mvSinks.size();
148 void
149 ScVbaApplication::RemoveSink( sal_uInt32 nNumber )
151 if (nNumber < 1 || nNumber > mvSinks.size())
152 return;
154 mvSinks[nNumber-1] = uno::Reference< XSink >();
157 ScVbaApplication::ScVbaApplication( const uno::Reference<uno::XComponentContext >& xContext ) :
158 ScVbaApplication_BASE( xContext ),
159 mrAppSettings( ScVbaStaticAppSettings::get() ),
160 m_nDialogType(0)
164 ScVbaApplication::~ScVbaApplication()
168 /*static*/ bool ScVbaApplication::getDocumentEventsEnabled()
170 return ScVbaStaticAppSettings::get().mbEnableEvents;
173 OUString SAL_CALL
174 ScVbaApplication::getExactName( const OUString& aApproximateName )
176 uno::Reference< beans::XExactName > xWSF( new ScVbaWSFunction( this, mxContext ) );
177 return xWSF->getExactName( aApproximateName );
180 uno::Reference< beans::XIntrospectionAccess > SAL_CALL
181 ScVbaApplication::getIntrospection()
183 uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
184 return xWSF->getIntrospection();
187 uno::Any SAL_CALL
188 ScVbaApplication::invoke( const OUString& FunctionName, const uno::Sequence< uno::Any >& Params, uno::Sequence< sal_Int16 >& OutParamIndex, uno::Sequence< uno::Any >& OutParam)
190 /* When calling the functions directly at the Application object, no runtime
191 errors are thrown, but the error is inserted into the return value. */
192 uno::Any aAny;
195 uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
196 aAny = xWSF->invoke( FunctionName, Params, OutParamIndex, OutParam );
198 catch (const uno::Exception&)
200 aAny <<= script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), 1000, OUString() );
202 return aAny;
205 void SAL_CALL
206 ScVbaApplication::setValue( const OUString& PropertyName, const uno::Any& Value )
208 uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
209 xWSF->setValue( PropertyName, Value );
212 uno::Any SAL_CALL
213 ScVbaApplication::getValue( const OUString& PropertyName )
215 uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
216 return xWSF->getValue( PropertyName );
219 sal_Bool SAL_CALL
220 ScVbaApplication::hasMethod( const OUString& Name )
222 uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
223 return xWSF->hasMethod( Name );
226 sal_Bool SAL_CALL
227 ScVbaApplication::hasProperty( const OUString& Name )
229 uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
230 return xWSF->hasProperty( Name );
233 uno::Reference< excel::XWorkbook >
234 ScVbaApplication::getActiveWorkbook()
236 uno::Reference< frame::XModel > xModel( getCurrentExcelDoc( mxContext ), uno::UNO_SET_THROW );
237 uno::Reference< excel::XWorkbook > xWorkbook( getVBADocument( xModel ), uno::UNO_QUERY );
238 if( xWorkbook.is() ) return xWorkbook;
239 // #i116936# getVBADocument() may return null in documents without global VBA mode enabled
240 return new ScVbaWorkbook( this, mxContext, xModel );
243 uno::Reference< excel::XWorkbook > SAL_CALL
244 ScVbaApplication::getThisWorkbook()
246 uno::Reference< frame::XModel > xModel( getThisExcelDoc( mxContext ), uno::UNO_SET_THROW );
247 uno::Reference< excel::XWorkbook > xWorkbook( getVBADocument( xModel ), uno::UNO_QUERY );
248 if( xWorkbook.is() ) return xWorkbook;
249 // #i116936# getVBADocument() may return null in documents without global VBA mode enabled
250 return new ScVbaWorkbook( this, mxContext, xModel );
253 uno::Reference< XAssistant > SAL_CALL
254 ScVbaApplication::getAssistant()
256 return uno::Reference< XAssistant >( new ScVbaAssistant( this, mxContext ) );
259 uno::Any SAL_CALL
260 ScVbaApplication::getSelection()
262 uno::Reference< frame::XModel > xModel( getCurrentDocument() );
264 Reference< view::XSelectionSupplier > xSelSupp( xModel->getCurrentController(), UNO_QUERY_THROW );
265 Reference< beans::XPropertySet > xPropSet( xSelSupp, UNO_QUERY_THROW );
266 OUString aPropName( SC_UNO_FILTERED_RANGE_SELECTION );
267 uno::Any aOldVal = xPropSet->getPropertyValue( aPropName );
268 uno::Any any;
269 any <<= false;
270 xPropSet->setPropertyValue( aPropName, any );
271 uno::Reference<uno::XInterface> aSelection(xSelSupp->getSelection(), uno::UNO_QUERY);
272 xPropSet->setPropertyValue( aPropName, aOldVal );
274 if (!aSelection.is())
276 throw uno::RuntimeException( "failed to obtain current selection" );
279 uno::Reference< lang::XServiceInfo > xServiceInfo( aSelection, uno::UNO_QUERY_THROW );
280 OUString sImplementationName = xServiceInfo->getImplementationName();
282 if( sImplementationName.equalsIgnoreAsciiCase("com.sun.star.drawing.SvxShapeCollection") )
284 uno::Reference< drawing::XShapes > xShapes( aSelection, uno::UNO_QUERY_THROW );
285 uno::Reference< container::XIndexAccess > xIndexAccess( xShapes, uno::UNO_QUERY_THROW );
286 uno::Reference< drawing::XShape > xShape( xIndexAccess->getByIndex(0), uno::UNO_QUERY_THROW );
287 // if ScVbaShape::getType( xShape ) == office::MsoShapeType::msoAutoShape
288 // and the uno object implements the com.sun.star.drawing.Text service
289 // return a textboxshape object
290 sal_Int32 nType = ScVbaShape::getType( xShape );
291 if ( nType == office::MsoShapeType::msoAutoShape )
293 // TODO Oval with text box
294 if( ScVbaShape::getAutoShapeType( xShape ) == office::MsoAutoShapeType::msoShapeOval )
296 return uno::makeAny( uno::Reference< msforms::XOval >(new ScVbaOvalShape( mxContext, xShape, xShapes, xModel ) ) );
300 uno::Reference< lang::XServiceInfo > xShapeServiceInfo( xShape, uno::UNO_QUERY_THROW );
301 if ( xShapeServiceInfo->supportsService("com.sun.star.drawing.Text") )
303 return uno::makeAny( uno::Reference< msforms::XTextBoxShape >(
304 new ScVbaTextBoxShape( mxContext, xShape, xShapes, xModel ) ) );
307 else if ( nType == office::MsoShapeType::msoLine )
309 return uno::makeAny( uno::Reference< msforms::XLine >( new ScVbaLineShape(
310 mxContext, xShape, xShapes, xModel ) ) );
312 return uno::makeAny( uno::Reference< msforms::XShape >(new ScVbaShape( this, mxContext, xShape, xShapes, xModel, ScVbaShape::getType( xShape ) ) ) );
314 else if( xServiceInfo->supportsService("com.sun.star.sheet.SheetCellRange") ||
315 xServiceInfo->supportsService("com.sun.star.sheet.SheetCellRanges") )
317 uno::Reference< table::XCellRange > xRange( aSelection, ::uno::UNO_QUERY);
318 if ( !xRange.is() )
320 uno::Reference< sheet::XSheetCellRangeContainer > xRanges( aSelection, ::uno::UNO_QUERY);
321 if ( xRanges.is() )
322 return uno::makeAny( uno::Reference< excel::XRange >( new ScVbaRange( excel::getUnoSheetModuleObj( xRanges ), mxContext, xRanges ) ) );
325 return uno::makeAny( uno::Reference< excel::XRange >(new ScVbaRange( excel::getUnoSheetModuleObj( xRange ), mxContext, xRange ) ) );
327 else
329 throw uno::RuntimeException( sImplementationName + " not supported" );
333 uno::Reference< excel::XRange >
334 ScVbaApplication::getActiveCell()
336 uno::Reference< sheet::XSpreadsheetView > xView( getCurrentDocument()->getCurrentController(), uno::UNO_QUERY_THROW );
337 uno::Reference< table::XCellRange > xRange( xView->getActiveSheet(), ::uno::UNO_QUERY_THROW);
338 ScTabViewShell* pViewShell = excel::getCurrentBestViewShell(mxContext);
339 if ( !pViewShell )
340 throw uno::RuntimeException("No ViewShell available" );
341 ScViewData& rTabView = pViewShell->GetViewData();
343 sal_Int32 nCursorX = rTabView.GetCurX();
344 sal_Int32 nCursorY = rTabView.GetCurY();
346 // #i117392# excel::getUnoSheetModuleObj() may return null in documents without global VBA mode enabled
347 return new ScVbaRange( excel::getUnoSheetModuleObj( xRange ), mxContext, xRange->getCellRangeByPosition( nCursorX, nCursorY, nCursorX, nCursorY ) );
350 uno::Any SAL_CALL
351 ScVbaApplication::International( sal_Int32 /*Index*/ )
353 // complete stub for now
354 // #TODO flesh out some of the Indices we could handle
355 uno::Any aRet;
356 return aRet;
359 uno::Any SAL_CALL
360 ScVbaApplication::FileDialog( const uno::Any& DialogType )
362 sal_Int32 nType = 0;
363 DialogType >>= nType;
365 if( !m_xFileDialog || nType != m_nDialogType )
367 m_nDialogType = nType;
368 m_xFileDialog = uno::Reference<excel::XFileDialog> ( new ScVbaFileDialog( this, mxContext, nType ));
370 return uno::Any( m_xFileDialog );
373 uno::Any SAL_CALL
374 ScVbaApplication::Workbooks( const uno::Any& aIndex )
376 uno::Reference< XCollection > xWorkBooks( new ScVbaWorkbooks( this, mxContext ) );
377 if ( aIndex.getValueTypeClass() == uno::TypeClass_VOID )
379 // void then somebody did Workbooks.something in vba
380 return uno::Any( xWorkBooks );
383 return xWorkBooks->Item( aIndex, uno::Any() );
386 uno::Any SAL_CALL
387 ScVbaApplication::Worksheets( const uno::Any& aIndex )
389 uno::Reference< excel::XWorkbook > xWorkbook( getActiveWorkbook(), uno::UNO_SET_THROW );
390 return xWorkbook->Worksheets( aIndex );
393 uno::Any SAL_CALL
394 ScVbaApplication::WorksheetFunction( )
396 return uno::makeAny( uno::Reference< script::XInvocation >( new ScVbaWSFunction( this, mxContext ) ) );
399 uno::Any SAL_CALL
400 ScVbaApplication::Evaluate( const OUString& Name )
402 // #TODO Evaluate allows other things to be evaluated, e.g. functions
403 // I think ( like SIN(3) etc. ) need to investigate that
404 // named Ranges also? e.g. [MyRange] if so need a list of named ranges
405 uno::Any aVoid;
406 return uno::Any( getActiveWorkbook()->getActiveSheet()->Range( uno::Any( Name ), aVoid ) );
409 uno::Any
410 ScVbaApplication::Dialogs( const uno::Any &aIndex )
412 uno::Reference< excel::XDialogs > xDialogs( new ScVbaDialogs( uno::Reference< XHelperInterface >( this ), mxContext, getCurrentDocument() ) );
413 if( !aIndex.hasValue() )
414 return uno::Any( xDialogs );
415 return xDialogs->Item( aIndex );
418 uno::Reference< excel::XWindow > SAL_CALL
419 ScVbaApplication::getActiveWindow()
421 uno::Reference< frame::XModel > xModel = getCurrentDocument();
422 uno::Reference< frame::XController > xController( xModel->getCurrentController(), uno::UNO_SET_THROW );
423 uno::Reference< XHelperInterface > xParent( getActiveWorkbook(), uno::UNO_QUERY_THROW );
424 uno::Reference< excel::XWindow > xWin( new ScVbaWindow( xParent, mxContext, xModel, xController ) );
425 return xWin;
428 uno::Any SAL_CALL
429 ScVbaApplication::getCutCopyMode()
431 //# FIXME TODO, implementation
432 uno::Any result;
433 result <<= false;
434 return result;
437 void SAL_CALL
438 ScVbaApplication::setCutCopyMode( const uno::Any& /* _cutcopymode */ )
440 //# FIXME TODO, implementation
443 uno::Any SAL_CALL
444 ScVbaApplication::getStatusBar()
446 return uno::makeAny( !getDisplayStatusBar() );
449 void SAL_CALL
450 ScVbaApplication::setStatusBar( const uno::Any& _statusbar )
452 OUString sText;
453 bool bDefault = false;
454 uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW );
455 uno::Reference< task::XStatusIndicatorSupplier > xStatusIndicatorSupplier( xModel->getCurrentController(), uno::UNO_QUERY_THROW );
456 uno::Reference< task::XStatusIndicator > xStatusIndicator( xStatusIndicatorSupplier->getStatusIndicator(), uno::UNO_SET_THROW );
457 if( _statusbar >>= sText )
459 setDisplayStatusBar( true );
460 if ( !sText.isEmpty() )
461 xStatusIndicator->start( sText, 100 );
462 else
463 xStatusIndicator->end(); // restore normal state for empty text
465 else if( _statusbar >>= bDefault )
467 if( !bDefault )
469 xStatusIndicator->end();
470 setDisplayStatusBar( true );
473 else
474 throw uno::RuntimeException("Invalid parameter. It should be a string or False" );
477 ::sal_Int32 SAL_CALL
478 ScVbaApplication::getCalculation()
480 // TODO: in Excel, this is an application-wide setting
481 uno::Reference<sheet::XCalculatable> xCalc(getCurrentDocument(), uno::UNO_QUERY_THROW);
482 if(xCalc->isAutomaticCalculationEnabled())
483 return excel::XlCalculation::xlCalculationAutomatic;
484 else
485 return excel::XlCalculation::xlCalculationManual;
488 void SAL_CALL
489 ScVbaApplication::setCalculation( ::sal_Int32 _calculation )
491 // TODO: in Excel, this is an application-wide setting
492 uno::Reference< sheet::XCalculatable > xCalc(getCurrentDocument(), uno::UNO_QUERY_THROW);
493 switch(_calculation)
495 case excel::XlCalculation::xlCalculationManual:
496 xCalc->enableAutomaticCalculation(false);
497 break;
498 case excel::XlCalculation::xlCalculationAutomatic:
499 case excel::XlCalculation::xlCalculationSemiautomatic:
500 xCalc->enableAutomaticCalculation(true);
501 break;
505 uno::Any SAL_CALL
506 ScVbaApplication::Windows( const uno::Any& aIndex )
508 uno::Reference< excel::XWindows > xWindows( new ScVbaWindows( this, mxContext ) );
509 if ( aIndex.getValueTypeClass() == uno::TypeClass_VOID )
510 return uno::Any( xWindows );
511 return xWindows->Item( aIndex, uno::Any() );
513 void SAL_CALL
514 ScVbaApplication::wait( double time )
516 StarBASIC* pBasic = SfxApplication::GetBasic();
517 SbxArrayRef aArgs = new SbxArray;
518 SbxVariableRef aRef = new SbxVariable;
519 aRef->PutDouble( time );
520 aArgs->Put32( aRef.get(), 1 );
521 SbMethod* pMeth = static_cast<SbMethod*>(pBasic->GetRtl()->Find( "WaitUntil", SbxClassType::Method ));
523 if ( pMeth )
525 pMeth->SetParameters( aArgs.get() );
526 SbxVariableRef refTemp = pMeth;
527 // forces a broadcast
528 SbxVariableRef pNew = new SbxMethod( *static_cast<SbxMethod*>(pMeth));
532 uno::Any SAL_CALL
533 ScVbaApplication::Range( const uno::Any& Cell1, const uno::Any& Cell2 )
535 uno::Reference< excel::XRange > xVbRange = ScVbaRange::ApplicationRange( mxContext, Cell1, Cell2 );
536 return uno::makeAny( xVbRange );
539 uno::Any SAL_CALL
540 ScVbaApplication::Names( const css::uno::Any& aIndex )
542 uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW );
543 uno::Reference< beans::XPropertySet > xPropertySet( xModel, uno::UNO_QUERY_THROW );
544 uno::Reference< sheet::XNamedRanges > xNamedRanges( xPropertySet->getPropertyValue(
545 "NamedRanges" ), uno::UNO_QUERY_THROW );
547 css::uno::Reference< excel::XNames > xNames ( new ScVbaNames( this , mxContext , xNamedRanges , xModel ) );
548 if ( aIndex.getValueTypeClass() == uno::TypeClass_VOID )
550 return uno::Any( xNames );
552 return xNames->Item( aIndex, uno::Any() );
555 uno::Reference< excel::XWorksheet > SAL_CALL
556 ScVbaApplication::getActiveSheet()
558 uno::Reference< excel::XWorksheet > result;
559 uno::Reference< excel::XWorkbook > xWorkbook = getActiveWorkbook();
560 if ( xWorkbook.is() )
562 uno::Reference< excel::XWorksheet > xWorksheet =
563 xWorkbook->getActiveSheet();
564 if ( xWorksheet.is() )
566 result = xWorksheet;
570 if ( !result.is() )
572 // Fixme - check if this is reasonable/desired behavior
573 throw uno::RuntimeException("No activeSheet available" );
575 return result;
579 /*******************************************************************************
580 * In msdn:
581 * Reference Optional Variant. The destination. Can be a Range
582 * object, a string that contains a cell reference in R1C1-style notation,
583 * or a string that contains a Visual Basic procedure name.
584 * Scroll Optional Variant. True to scroll, False to not scroll through
585 * the window. The default is False.
586 * Parser is split to three parts, Range, R1C1 string and procedure name.
587 * by test excel, it seems Scroll no effect. ???
588 *******************************************************************************/
589 void SAL_CALL
590 ScVbaApplication::GoTo( const uno::Any& Reference, const uno::Any& Scroll )
592 //test Scroll is a boolean
593 bool bScroll = false;
594 //R1C1-style string or a string of procedure name.
596 if( Scroll.hasValue() )
598 bool aScroll = false;
599 if( !(Scroll >>= aScroll) )
600 throw uno::RuntimeException("second parameter should be boolean" );
602 bScroll = aScroll;
606 OUString sRangeName;
607 if( Reference >>= sRangeName )
609 uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW );
610 uno::Reference< sheet::XSpreadsheetView > xSpreadsheet(
611 xModel->getCurrentController(), uno::UNO_QUERY_THROW );
613 ScTabViewShell* pShell = excel::getCurrentBestViewShell( mxContext );
614 ScGridWindow* gridWindow = static_cast<ScGridWindow*>(pShell->GetWindow());
617 uno::Reference< excel::XRange > xVbaSheetRange = ScVbaRange::getRangeObjectForName(
618 mxContext, sRangeName, excel::getDocShell( xModel ), formula::FormulaGrammar::CONV_XL_R1C1 );
620 if( bScroll )
622 xVbaSheetRange->Select();
623 uno::Reference< excel::XWindow > xWindow = getActiveWindow();
624 ScSplitPos eWhich = pShell->GetViewData().GetActivePart();
625 sal_Int32 nValueX = pShell->GetViewData().GetPosX(WhichH(eWhich));
626 sal_Int32 nValueY = pShell->GetViewData().GetPosY(WhichV(eWhich));
627 xWindow->SmallScroll( uno::makeAny( static_cast<sal_Int16>(xVbaSheetRange->getRow() - 1) ),
628 uno::makeAny( static_cast<sal_Int16>(nValueY) ),
629 uno::makeAny( static_cast<sal_Int16>(xVbaSheetRange->getColumn() - 1) ),
630 uno::makeAny( static_cast<sal_Int16>(nValueX) ) );
631 gridWindow->GrabFocus();
633 else
635 xVbaSheetRange->Select();
636 gridWindow->GrabFocus();
639 catch (const uno::RuntimeException&)
641 //maybe this should be a procedure name
642 //TODO for procedure name
643 //browse::XBrowseNodeFactory is a singleton. OUString( "/singletons/com.sun.star.script.browse.theBrowseNodeFactory")
644 //and the createView( browse::BrowseNodeFactoryViewTypes::MACROSELECTOR ) to get a root browse::XBrowseNode.
645 //for query XInvocation interface.
646 //but how to directly get the XInvocation?
647 throw uno::RuntimeException("invalid reference for range name, it should be procedure name" );
649 return;
651 uno::Reference< excel::XRange > xRange;
652 if( Reference >>= xRange )
654 uno::Reference< excel::XRange > xVbaRange( Reference, uno::UNO_QUERY );
655 ScTabViewShell* pShell = excel::getCurrentBestViewShell( mxContext );
656 ScGridWindow* gridWindow = static_cast<ScGridWindow*>(pShell->GetWindow());
657 if ( xVbaRange.is() )
659 //TODO bScroll should be used. At this time, it does not have effect
660 if( bScroll )
662 xVbaRange->Select();
663 uno::Reference< excel::XWindow > xWindow = getActiveWindow();
664 ScSplitPos eWhich = pShell->GetViewData().GetActivePart();
665 sal_Int32 nValueX = pShell->GetViewData().GetPosX(WhichH(eWhich));
666 sal_Int32 nValueY = pShell->GetViewData().GetPosY(WhichV(eWhich));
667 xWindow->SmallScroll( uno::makeAny( static_cast<sal_Int16>(xVbaRange->getRow() - 1) ),
668 uno::makeAny( static_cast<sal_Int16>(nValueY) ),
669 uno::makeAny( static_cast<sal_Int16>(xVbaRange->getColumn() - 1) ),
670 uno::makeAny( static_cast<sal_Int16>(nValueX) ) );
671 gridWindow->GrabFocus();
673 else
675 xVbaRange->Select();
676 gridWindow->GrabFocus();
679 return;
681 throw uno::RuntimeException("invalid reference or name" );
684 sal_Int32 SAL_CALL
685 ScVbaApplication::getCursor()
687 PointerStyle nPointerStyle = getPointerStyle(getCurrentDocument());
689 switch( nPointerStyle )
691 case PointerStyle::Arrow:
692 return excel::XlMousePointer::xlNorthwestArrow;
693 case PointerStyle::Null:
694 return excel::XlMousePointer::xlDefault;
695 case PointerStyle::Wait:
696 return excel::XlMousePointer::xlWait;
697 case PointerStyle::Text:
698 return excel::XlMousePointer::xlIBeam;
699 default:
700 return excel::XlMousePointer::xlDefault;
704 void SAL_CALL
705 ScVbaApplication::setCursor( sal_Int32 _cursor )
709 uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW );
710 switch( _cursor )
712 case excel::XlMousePointer::xlNorthwestArrow:
714 setCursorHelper( xModel, PointerStyle::Arrow, false );
715 break;
717 case excel::XlMousePointer::xlWait:
718 case excel::XlMousePointer::xlIBeam:
720 PointerStyle nPointer( static_cast< PointerStyle >( _cursor ) );
721 //It will set the edit window, toobar and statusbar's mouse pointer.
722 setCursorHelper( xModel, nPointer, true );
723 break;
725 case excel::XlMousePointer::xlDefault:
727 setCursorHelper( xModel, PointerStyle::Null, false );
728 break;
730 default:
731 throw uno::RuntimeException("Unknown value for Cursor pointer" );
732 // TODO: isn't this a flaw in the API? It should be allowed to throw an
733 // IllegalArgumentException, or so
736 catch (const uno::Exception&)
738 DBG_UNHANDLED_EXCEPTION("sc.ui");
742 // #TODO perhaps we should switch the return type depending of the filter
743 // type, e.g. return Calc for Calc and Excel if it's an imported doc
744 OUString SAL_CALL
745 ScVbaApplication::getName()
747 return "Microsoft Excel";
750 // #TODO #FIXME get/setDisplayAlerts are just stub impl
751 // here just the status of the switch is set
752 // the function that throws an error message needs to
753 // evaluate this switch in order to know whether it has to disable the
754 // error message thrown by OpenOffice
756 void SAL_CALL
757 ScVbaApplication::setDisplayAlerts(sal_Bool displayAlerts)
759 mrAppSettings.mbDisplayAlerts = displayAlerts;
762 sal_Bool SAL_CALL
763 ScVbaApplication::getDisplayAlerts()
765 return mrAppSettings.mbDisplayAlerts;
768 void SAL_CALL
769 ScVbaApplication::setEnableEvents(sal_Bool bEnable)
771 mrAppSettings.mbEnableEvents = bEnable;
774 sal_Bool SAL_CALL
775 ScVbaApplication::getEnableEvents()
777 return mrAppSettings.mbEnableEvents;
780 void SAL_CALL
781 ScVbaApplication::setEnableCancelKey(sal_Bool bEnable)
783 // Stub, does nothing
784 mrAppSettings.mbEnableCancelKey = bEnable;
787 sal_Bool SAL_CALL
788 ScVbaApplication::getEnableCancelKey()
790 return mrAppSettings.mbEnableCancelKey;
793 sal_Bool SAL_CALL
794 ScVbaApplication::getDisplayFullScreen()
796 SfxViewShell* pShell = excel::getCurrentBestViewShell( mxContext );
797 if ( pShell )
798 return ScViewUtil::IsFullScreen( *pShell );
799 return false;
802 void SAL_CALL
803 ScVbaApplication::setDisplayFullScreen( sal_Bool bSet )
805 // #FIXME calling ScViewUtil::SetFullScreen( *pShell, bSet );
806 // directly results in a strange crash, using dispatch instead
807 if ( bSet != getDisplayFullScreen() )
808 dispatchRequests( getCurrentDocument(), ".uno:FullScreen" );
811 sal_Bool SAL_CALL
812 ScVbaApplication::getDisplayScrollBars()
814 ScTabViewShell* pShell = excel::getCurrentBestViewShell( mxContext );
815 if ( pShell )
817 return ( pShell->GetViewData().IsHScrollMode() && pShell->GetViewData().IsVScrollMode() );
819 return true;
822 void SAL_CALL
823 ScVbaApplication::setDisplayScrollBars( sal_Bool bSet )
825 // use uno here as it does all he repainting etc. magic
826 uno::Reference< sheet::XSpreadsheetView > xView( getCurrentDocument()->getCurrentController(), uno::UNO_QUERY_THROW );
827 uno::Reference< beans::XPropertySet > xProps( xView, uno::UNO_QUERY );
828 xProps->setPropertyValue("HasVerticalScrollBar", uno::makeAny( bSet ) );
829 xProps->setPropertyValue("HasHorizontalScrollBar", uno::makeAny( bSet ) );
832 sal_Bool SAL_CALL
833 ScVbaApplication::getDisplayExcel4Menus()
835 return mrAppSettings.mbExcel4Menus;
838 void SAL_CALL
839 ScVbaApplication::setDisplayExcel4Menus( sal_Bool bSet )
841 mrAppSettings.mbExcel4Menus = bSet;
844 sal_Bool SAL_CALL
845 ScVbaApplication::getDisplayNoteIndicator()
847 return mrAppSettings.mbDisplayNoteIndicator;
850 void SAL_CALL
851 ScVbaApplication::setDisplayNoteIndicator( sal_Bool bSet )
853 mrAppSettings.mbDisplayNoteIndicator = bSet;
856 sal_Bool SAL_CALL
857 ScVbaApplication::getShowWindowsInTaskbar()
859 return mrAppSettings.mbShowWindowsInTaskbar;
862 void SAL_CALL
863 ScVbaApplication::setShowWindowsInTaskbar( sal_Bool bSet )
865 mrAppSettings.mbShowWindowsInTaskbar = bSet;
868 sal_Bool SAL_CALL
869 ScVbaApplication::getIteration()
871 return SC_MOD()->GetDocOptions().IsIter();
874 void SAL_CALL
875 ScVbaApplication::setIteration( sal_Bool bSet )
877 uno::Reference< lang::XMultiComponentFactory > xSMgr(
878 mxContext->getServiceManager(), uno::UNO_SET_THROW );
880 uno::Reference< frame::XDesktop > xDesktop
881 (xSMgr->createInstanceWithContext( "com.sun.star.frame.Desktop" , mxContext), uno::UNO_QUERY_THROW );
882 uno::Reference< container::XEnumeration > xComponents = xDesktop->getComponents()->createEnumeration();
883 while ( xComponents->hasMoreElements() )
885 uno::Reference< lang::XServiceInfo > xServiceInfo( xComponents->nextElement(), uno::UNO_QUERY );
886 if ( xServiceInfo.is() && xServiceInfo->supportsService( "com.sun.star.sheet.SpreadsheetDocument" ) )
888 uno::Reference< beans::XPropertySet > xProps( xServiceInfo, uno::UNO_QUERY );
889 if ( xProps.is() )
890 xProps->setPropertyValue( SC_UNO_ITERENABLED, uno::Any( bSet ) );
893 ScDocOptions aOpts( SC_MOD()->GetDocOptions() );
894 aOpts.SetIter( bSet );
895 SC_MOD()->SetDocOptions( aOpts );
898 void SAL_CALL
899 ScVbaApplication::Calculate()
901 uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW );
902 uno::Reference< sheet::XCalculatable > xCalculatable( getCurrentDocument(), uno::UNO_QUERY_THROW );
903 xCalculatable->calculateAll();
906 /// @throws uno::RuntimeException
907 static uno::Reference< util::XPathSettings > const & lcl_getPathSettingsService( const uno::Reference< uno::XComponentContext >& xContext )
909 static uno::Reference< util::XPathSettings > xPathSettings( util::PathSettings::create( xContext ) );
910 return xPathSettings;
913 OUString ScVbaApplication::getOfficePath( const OUString& _sPathType )
915 OUString sRetPath;
916 const uno::Reference< util::XPathSettings >& xProps = lcl_getPathSettingsService( mxContext );
919 OUString sUrl;
920 xProps->getPropertyValue( _sPathType ) >>= sUrl;
922 // if it's a list of paths then use the last one
923 sal_Int32 nIndex = sUrl.lastIndexOf( ';' ) ;
924 if ( nIndex > 0 )
925 sUrl = sUrl.copy( nIndex + 1 );
926 ::osl::File::getSystemPathFromFileURL( sUrl, sRetPath );
928 catch (const uno::Exception&)
930 DebugHelper::runtimeexception(ERRCODE_BASIC_METHOD_FAILED);
932 return sRetPath;
935 void SAL_CALL
936 ScVbaApplication::setDefaultFilePath( const OUString& DefaultFilePath )
938 const uno::Reference< util::XPathSettings >& xProps = lcl_getPathSettingsService( mxContext );
939 OUString aURL;
940 osl::FileBase::getFileURLFromSystemPath( DefaultFilePath, aURL );
941 xProps->setWork( aURL );
944 OUString SAL_CALL
945 ScVbaApplication::getDefaultFilePath()
947 return getOfficePath( "Work");
950 OUString SAL_CALL
951 ScVbaApplication::getLibraryPath()
953 return getOfficePath( "Basic");
956 OUString SAL_CALL
957 ScVbaApplication::getTemplatesPath()
959 return getOfficePath( "Template");
962 OUString SAL_CALL
963 ScVbaApplication::getPathSeparator()
965 return OUString( sal_Unicode(SAL_PATHDELIMITER) );
968 OUString SAL_CALL
969 ScVbaApplication::getOperatingSystem()
971 // TODO Solution should contain the version number of the operating system
972 // too.
973 #if defined(_WIN32)
974 return "Windows";
975 #elif defined(MACOSX)
976 return "Macintosh";
977 #elif defined(UNX)
978 // M. Office is not available on Unix systems, so it is not documented.
979 return "Unix";
980 #else
981 return OUString("Unknown");
982 #endif
985 // Helpers for Intersect and Union
987 namespace {
989 typedef ::std::list< ScRange > ListOfScRange;
991 /** Appends all ranges of a VBA Range object in the passed Any to the list of ranges.
993 @throws script::BasicErrorException
994 @throws uno::RuntimeException
996 void lclAddToListOfScRange( ListOfScRange& rList, const uno::Any& rArg )
998 if( !rArg.hasValue() )
999 return;
1001 uno::Reference< excel::XRange > xRange( rArg, uno::UNO_QUERY_THROW );
1002 uno::Reference< XCollection > xCol( xRange->Areas( uno::Any() ), uno::UNO_QUERY_THROW );
1003 for( sal_Int32 nIdx = 1, nCount = xCol->getCount(); nIdx <= nCount; ++nIdx )
1005 uno::Reference< excel::XRange > xAreaRange( xCol->Item( uno::Any( nIdx ), uno::Any() ), uno::UNO_QUERY_THROW );
1006 uno::Reference< sheet::XCellRangeAddressable > xAddressable( xAreaRange->getCellRange(), uno::UNO_QUERY_THROW );
1007 ScRange aScRange;
1008 ScUnoConversion::FillScRange( aScRange, xAddressable->getRangeAddress() );
1009 rList.push_back( aScRange );
1013 /** Returns true, if the passed ranges can be expressed by a single range. The
1014 new range will be contained in r1 then, the range r2 can be removed. */
1015 bool lclTryJoin( ScRange& r1, const ScRange& r2 )
1017 // 1) r2 is completely inside r1
1018 if( r1.In( r2 ) )
1019 return true;
1021 // 2) r1 is completely inside r2
1022 if( r2.In( r1 ) )
1024 r1 = r2;
1025 return true;
1028 SCCOL n1L = r1.aStart.Col();
1029 SCCOL n1R = r1.aEnd.Col();
1030 SCROW n1T = r1.aStart.Row();
1031 SCROW n1B = r1.aEnd.Row();
1032 SCCOL n2L = r2.aStart.Col();
1033 SCCOL n2R = r2.aEnd.Col();
1034 SCROW n2T = r2.aStart.Row();
1035 SCROW n2B = r2.aEnd.Row();
1037 // 3) r1 and r2 have equal upper and lower border
1038 if( (n1T == n2T) && (n1B == n2B) )
1040 // check that r1 overlaps or touches r2
1041 if( ((n1L < n2L) && (n2L - 1 <= n1R)) || ((n2L < n1L) && (n1L - 1 <= n2R)) )
1043 r1.aStart.SetCol( ::std::min( n1L, n2L ) );
1044 r1.aEnd.SetCol( ::std::max( n1R, n2R ) );
1045 return true;
1047 return false;
1050 // 4) r1 and r2 have equal left and right border
1051 if( (n1L == n2L) && (n1R == n2R) )
1053 // check that r1 overlaps or touches r2
1054 if( ((n1T < n2T) && (n2T + 1 <= n1B)) || ((n2T < n1T) && (n1T + 1 <= n2B)) )
1056 r1.aStart.SetRow( ::std::min( n1T, n2T ) );
1057 r1.aEnd.SetRow( ::std::max( n1B, n2B ) );
1058 return true;
1060 return false;
1063 // 5) cannot join these ranges
1064 return false;
1067 /** Strips out ranges that are contained by other ranges, joins ranges that can be joined
1068 together (aligned borders, e.g. A4:D10 and B4:E10 would be combined to A4:E10. */
1069 void lclJoinRanges( ListOfScRange& rList )
1071 ListOfScRange::iterator aOuterIt = rList.begin();
1072 while( aOuterIt != rList.end() )
1074 bool bAnyErased = false; // true = any range erased from rList
1075 ListOfScRange::iterator aInnerIt = rList.begin();
1076 while( aInnerIt != rList.end() )
1078 bool bInnerErased = false; // true = aInnerIt erased from rList
1079 // do not compare a range with itself
1080 if( (aOuterIt != aInnerIt) && lclTryJoin( *aOuterIt, *aInnerIt ) )
1082 // aOuterIt points to joined range, aInnerIt will be removed
1083 aInnerIt = rList.erase( aInnerIt );
1084 bInnerErased = bAnyErased = true;
1086 /* If aInnerIt has been erased from rList, it already points to
1087 the next element (return value of list::erase()). */
1088 if( !bInnerErased )
1089 ++aInnerIt;
1091 // if any range has been erased, repeat outer loop with the same range
1092 if( !bAnyErased )
1093 ++aOuterIt;
1097 /** Intersects the passed list with all ranges of a VBA Range object in the passed Any.
1099 @throws script::BasicErrorException
1100 @throws uno::RuntimeException
1102 void lclIntersectRanges( ListOfScRange& rList, const uno::Any& rArg )
1104 // extract the ranges from the passed argument, will throw on invalid data
1105 ListOfScRange aList2;
1106 lclAddToListOfScRange( aList2, rArg );
1107 // do nothing, if the passed list is already empty
1108 if( rList.empty() || aList2.empty() )
1109 return;
1111 // save original list in a local
1112 ListOfScRange aList1;
1113 aList1.swap( rList );
1114 // join ranges from passed argument
1115 lclJoinRanges( aList2 );
1116 // calculate intersection of the ranges in both lists
1117 for( const auto& rOuterItem : aList1 )
1119 for( const auto& rInnerItem : aList2 )
1121 if( rOuterItem.Intersects( rInnerItem ) )
1123 ScRange aIsectRange(
1124 std::max( rOuterItem.aStart.Col(), rInnerItem.aStart.Col() ),
1125 std::max( rOuterItem.aStart.Row(), rInnerItem.aStart.Row() ),
1126 std::max( rOuterItem.aStart.Tab(), rInnerItem.aStart.Tab() ),
1127 std::min( rOuterItem.aEnd.Col(), rInnerItem.aEnd.Col() ),
1128 std::min( rOuterItem.aEnd.Row(), rInnerItem.aEnd.Row() ),
1129 std::min( rOuterItem.aEnd.Tab(), rInnerItem.aEnd.Tab() ) );
1130 rList.push_back( aIsectRange );
1134 // again, join the result ranges
1135 lclJoinRanges( rList );
1138 /** Creates a VBA Range object from the passed list of ranges.
1140 @throws uno::RuntimeException
1142 uno::Reference< excel::XRange > lclCreateVbaRange(
1143 const uno::Reference< uno::XComponentContext >& rxContext,
1144 const uno::Reference< frame::XModel >& rxModel,
1145 const ListOfScRange& rList )
1147 ScDocShell* pDocShell = excel::getDocShell( rxModel );
1148 if( !pDocShell ) throw uno::RuntimeException();
1150 ScRangeList aCellRanges;
1151 for( const auto& rItem : rList )
1152 aCellRanges.push_back( rItem );
1154 if( aCellRanges.size() == 1 )
1156 uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pDocShell, aCellRanges.front() ) );
1157 return new ScVbaRange( excel::getUnoSheetModuleObj( xRange ), rxContext, xRange );
1159 if( aCellRanges.size() > 1 )
1161 uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pDocShell, aCellRanges ) );
1162 return new ScVbaRange( excel::getUnoSheetModuleObj( xRanges ), rxContext, xRanges );
1164 return nullptr;
1167 } // namespace
1169 uno::Reference< excel::XRange > SAL_CALL ScVbaApplication::Intersect(
1170 const uno::Reference< excel::XRange >& rArg1, const uno::Reference< excel::XRange >& rArg2,
1171 const uno::Any& rArg3, const uno::Any& rArg4, const uno::Any& rArg5, const uno::Any& rArg6,
1172 const uno::Any& rArg7, const uno::Any& rArg8, const uno::Any& rArg9, const uno::Any& rArg10,
1173 const uno::Any& rArg11, const uno::Any& rArg12, const uno::Any& rArg13, const uno::Any& rArg14,
1174 const uno::Any& rArg15, const uno::Any& rArg16, const uno::Any& rArg17, const uno::Any& rArg18,
1175 const uno::Any& rArg19, const uno::Any& rArg20, const uno::Any& rArg21, const uno::Any& rArg22,
1176 const uno::Any& rArg23, const uno::Any& rArg24, const uno::Any& rArg25, const uno::Any& rArg26,
1177 const uno::Any& rArg27, const uno::Any& rArg28, const uno::Any& rArg29, const uno::Any& rArg30 )
1179 if( !rArg1.is() || !rArg2.is() )
1180 DebugHelper::basicexception( ERRCODE_BASIC_BAD_PARAMETER, {} );
1182 // initialize the result list with 1st parameter, join its ranges together
1183 ListOfScRange aList;
1184 lclAddToListOfScRange( aList, uno::Any( rArg1 ) );
1185 lclJoinRanges( aList );
1187 // process all other parameters, this updates the list with intersection
1188 lclIntersectRanges( aList, uno::Any( rArg2 ) );
1189 lclIntersectRanges( aList, rArg3 );
1190 lclIntersectRanges( aList, rArg4 );
1191 lclIntersectRanges( aList, rArg5 );
1192 lclIntersectRanges( aList, rArg6 );
1193 lclIntersectRanges( aList, rArg7 );
1194 lclIntersectRanges( aList, rArg8 );
1195 lclIntersectRanges( aList, rArg9 );
1196 lclIntersectRanges( aList, rArg10 );
1197 lclIntersectRanges( aList, rArg11 );
1198 lclIntersectRanges( aList, rArg12 );
1199 lclIntersectRanges( aList, rArg13 );
1200 lclIntersectRanges( aList, rArg14 );
1201 lclIntersectRanges( aList, rArg15 );
1202 lclIntersectRanges( aList, rArg16 );
1203 lclIntersectRanges( aList, rArg17 );
1204 lclIntersectRanges( aList, rArg18 );
1205 lclIntersectRanges( aList, rArg19 );
1206 lclIntersectRanges( aList, rArg20 );
1207 lclIntersectRanges( aList, rArg21 );
1208 lclIntersectRanges( aList, rArg22 );
1209 lclIntersectRanges( aList, rArg23 );
1210 lclIntersectRanges( aList, rArg24 );
1211 lclIntersectRanges( aList, rArg25 );
1212 lclIntersectRanges( aList, rArg26 );
1213 lclIntersectRanges( aList, rArg27 );
1214 lclIntersectRanges( aList, rArg28 );
1215 lclIntersectRanges( aList, rArg29 );
1216 lclIntersectRanges( aList, rArg30 );
1218 // create the VBA Range object
1219 return lclCreateVbaRange( mxContext, getCurrentDocument(), aList );
1222 uno::Reference< excel::XRange > SAL_CALL ScVbaApplication::Union(
1223 const uno::Reference< excel::XRange >& rArg1, const uno::Reference< excel::XRange >& rArg2,
1224 const uno::Any& rArg3, const uno::Any& rArg4, const uno::Any& rArg5, const uno::Any& rArg6,
1225 const uno::Any& rArg7, const uno::Any& rArg8, const uno::Any& rArg9, const uno::Any& rArg10,
1226 const uno::Any& rArg11, const uno::Any& rArg12, const uno::Any& rArg13, const uno::Any& rArg14,
1227 const uno::Any& rArg15, const uno::Any& rArg16, const uno::Any& rArg17, const uno::Any& rArg18,
1228 const uno::Any& rArg19, const uno::Any& rArg20, const uno::Any& rArg21, const uno::Any& rArg22,
1229 const uno::Any& rArg23, const uno::Any& rArg24, const uno::Any& rArg25, const uno::Any& rArg26,
1230 const uno::Any& rArg27, const uno::Any& rArg28, const uno::Any& rArg29, const uno::Any& rArg30 )
1232 if( !rArg1.is() || !rArg2.is() )
1233 DebugHelper::basicexception( ERRCODE_BASIC_BAD_PARAMETER, {} );
1235 ListOfScRange aList;
1236 lclAddToListOfScRange( aList, uno::Any( rArg1 ) );
1237 lclAddToListOfScRange( aList, uno::Any( rArg2 ) );
1238 lclAddToListOfScRange( aList, rArg3 );
1239 lclAddToListOfScRange( aList, rArg4 );
1240 lclAddToListOfScRange( aList, rArg5 );
1241 lclAddToListOfScRange( aList, rArg6 );
1242 lclAddToListOfScRange( aList, rArg7 );
1243 lclAddToListOfScRange( aList, rArg8 );
1244 lclAddToListOfScRange( aList, rArg9 );
1245 lclAddToListOfScRange( aList, rArg10 );
1246 lclAddToListOfScRange( aList, rArg11 );
1247 lclAddToListOfScRange( aList, rArg12 );
1248 lclAddToListOfScRange( aList, rArg13 );
1249 lclAddToListOfScRange( aList, rArg14 );
1250 lclAddToListOfScRange( aList, rArg15 );
1251 lclAddToListOfScRange( aList, rArg16 );
1252 lclAddToListOfScRange( aList, rArg17 );
1253 lclAddToListOfScRange( aList, rArg18 );
1254 lclAddToListOfScRange( aList, rArg19 );
1255 lclAddToListOfScRange( aList, rArg20 );
1256 lclAddToListOfScRange( aList, rArg21 );
1257 lclAddToListOfScRange( aList, rArg22 );
1258 lclAddToListOfScRange( aList, rArg23 );
1259 lclAddToListOfScRange( aList, rArg24 );
1260 lclAddToListOfScRange( aList, rArg25 );
1261 lclAddToListOfScRange( aList, rArg26 );
1262 lclAddToListOfScRange( aList, rArg27 );
1263 lclAddToListOfScRange( aList, rArg28 );
1264 lclAddToListOfScRange( aList, rArg29 );
1265 lclAddToListOfScRange( aList, rArg30 );
1267 // simply join together all ranges as much as possible, strip out covered ranges etc.
1268 lclJoinRanges( aList );
1270 // create the VBA Range object
1271 return lclCreateVbaRange( mxContext, getCurrentDocument(), aList );
1274 double
1275 ScVbaApplication::InchesToPoints( double Inches )
1277 double result = Inches * 72.0;
1278 return result;
1281 void
1282 ScVbaApplication::Volatile( const uno::Any& aVolatile )
1284 bool bVolatile = true;
1285 aVolatile >>= bVolatile;
1286 SbMethod* pMeth = StarBASIC::GetActiveMethod();
1287 if ( pMeth )
1289 uno::Reference< frame::XModel > xModel( getCurrentDocument() );
1290 ScDocument& rDoc = excel::getDocShell( xModel )->GetDocument();
1291 rDoc.GetMacroManager()->SetUserFuncVolatile( pMeth->GetName(), bVolatile);
1294 // this is bound to break when loading the document
1297 sal_Bool SAL_CALL
1298 ScVbaApplication::getDisplayFormulaBar()
1300 bool bRes = false;
1301 ScTabViewShell* pViewShell = excel::getCurrentBestViewShell( mxContext );
1302 if ( pViewShell )
1304 SfxBoolItem sfxFormBar( FID_TOGGLEINPUTLINE);
1305 SfxAllItemSet reqList( SfxGetpApp()->GetPool() );
1306 reqList.Put( sfxFormBar );
1308 pViewShell->GetState( reqList );
1309 const SfxPoolItem *pItem=nullptr;
1310 if ( reqList.GetItemState( FID_TOGGLEINPUTLINE, false, &pItem ) == SfxItemState::SET )
1311 bRes = static_cast<const SfxBoolItem*>(pItem)->GetValue();
1313 return bRes;
1316 void SAL_CALL
1317 ScVbaApplication::setDisplayFormulaBar( sal_Bool _displayformulabar )
1319 ScTabViewShell* pViewShell = excel::getCurrentBestViewShell( mxContext );
1320 if ( pViewShell && ( _displayformulabar != getDisplayFormulaBar() ) )
1322 SfxAllItemSet reqList( SfxGetpApp()->GetPool() );
1323 SfxRequest aReq( FID_TOGGLEINPUTLINE, SfxCallMode::SLOT, reqList );
1324 pViewShell->Execute( aReq );
1328 uno::Any SAL_CALL
1329 ScVbaApplication::Caller( const uno::Any& /*aIndex*/ )
1331 StarBASIC* pBasic = SfxApplication::GetBasic();
1332 SbMethod* pMeth = static_cast<SbMethod*>(pBasic->GetRtl()->Find( "FuncCaller", SbxClassType::Method ));
1333 uno::Any aRet;
1334 if ( pMeth )
1336 SbxVariableRef refTemp = pMeth;
1337 // forces a broadcast
1338 SbxVariableRef pNew = new SbxMethod( *static_cast<SbxMethod*>(pMeth));
1339 aRet = sbxToUnoValue( pNew.get() );
1341 return aRet;
1344 uno::Reference< frame::XModel >
1345 ScVbaApplication::getCurrentDocument()
1347 return getCurrentExcelDoc(mxContext);
1350 uno::Any SAL_CALL
1351 ScVbaApplication::MenuBars( const uno::Any& aIndex )
1353 uno::Reference< XCommandBars > xCommandBars( CommandBars( uno::Any() ), uno::UNO_QUERY_THROW );
1354 uno::Reference< XCollection > xMenuBars( new ScVbaMenuBars( this, mxContext, xCommandBars ) );
1355 if ( aIndex.hasValue() )
1357 return xMenuBars->Item( aIndex, uno::Any() );
1360 return uno::Any( xMenuBars );
1363 uno::Any SAL_CALL
1364 ScVbaApplication::Rows( const uno::Any& aIndex )
1366 uno::Reference< excel::XWorksheet > xWorksheet = getActiveSheet();
1367 if ( xWorksheet.is() )
1368 return uno::Any( xWorksheet->Rows( aIndex ) );
1369 return uno::Any();
1372 void SAL_CALL ScVbaApplication::OnKey( const OUString& Key, const uno::Any& Procedure )
1376 // Perhaps we can catch some excel specific
1377 // related behaviour here
1378 VbaApplicationBase::OnKey( Key, Procedure );
1380 catch( container::NoSuchElementException& )
1382 // #TODO special handling for unhandled
1383 // bindings
1387 void SAL_CALL ScVbaApplication::setScreenUpdating(sal_Bool bUpdate)
1389 VbaApplicationBase::setScreenUpdating( bUpdate );
1391 uno::Reference< frame::XModel > xModel( getCurrentExcelDoc( mxContext ), uno::UNO_SET_THROW );
1392 ScDocShell* pDocShell = excel::getDocShell( xModel );
1393 ScDocument& rDoc = pDocShell->GetDocument();
1395 if( bUpdate )
1397 // Since setting ScreenUpdating from user code might be unpaired, avoid calling function,
1398 // that asserts correct lock/unlock order and number, when not locked.
1399 if(rDoc.IsAdjustHeightLocked())
1400 rDoc.UnlockAdjustHeight();
1401 if( !rDoc.IsAdjustHeightLocked() )
1402 pDocShell->UpdateAllRowHeights();
1404 else
1406 rDoc.LockAdjustHeight();
1410 void SAL_CALL ScVbaApplication::Undo()
1412 uno::Reference< frame::XModel > xModel( getThisExcelDoc( mxContext ), uno::UNO_SET_THROW );
1414 ScTabViewShell* pViewShell = excel::getBestViewShell( xModel );
1415 if ( pViewShell )
1416 dispatchExecute( pViewShell, SID_UNDO );
1419 // XInterfaceWithIID
1421 OUString SAL_CALL
1422 ScVbaApplication::getIID()
1424 return "{82154425-0FBF-11d4-8313-005004526AB4}";
1427 // XConnectable
1429 OUString SAL_CALL
1430 ScVbaApplication::GetIIDForClassItselfNotCoclass()
1432 return "{82154426-0FBF-11D4-8313-005004526AB4}";
1435 TypeAndIID SAL_CALL
1436 ScVbaApplication::GetConnectionPoint()
1438 TypeAndIID aResult =
1439 { excel::XApplicationOutgoing::static_type(),
1440 "{82154427-0FBF-11D4-8313-005004526AB4}"
1443 return aResult;
1446 uno::Reference<XConnectionPoint> SAL_CALL
1447 ScVbaApplication::FindConnectionPoint()
1449 uno::Reference<XConnectionPoint> xCP(new ScVbaApplicationOutgoingConnectionPoint(this));
1450 return xCP;
1453 // XSinkCaller
1455 void SAL_CALL
1456 ScVbaApplication::CallSinks( const OUString& Method, uno::Sequence< uno::Any >& Arguments )
1458 for (auto& i : mvSinks)
1460 if (i.is())
1461 i->Call(Method, Arguments);
1465 OUString
1466 ScVbaApplication::getServiceImplName()
1468 return "ScVbaApplication";
1471 uno::Sequence< OUString >
1472 ScVbaApplication::getServiceNames()
1474 static uno::Sequence< OUString > aServiceNames
1476 "ooo.vba.excel.Application"
1478 return aServiceNames;
1482 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
1483 Calc_ScVbaApplication_get_implementation(
1484 css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& )
1486 return cppu::acquire(new ScVbaApplication(context));
1490 // ScVbaApplicationOutgoingConnectionPoint
1492 ScVbaApplicationOutgoingConnectionPoint::ScVbaApplicationOutgoingConnectionPoint( ScVbaApplication* pApp ) :
1493 mpApp(pApp)
1497 // XConnectionPoint
1498 sal_uInt32 SAL_CALL
1499 ScVbaApplicationOutgoingConnectionPoint::Advise( const uno::Reference< XSink >& Sink )
1501 return mpApp->AddSink(Sink);
1504 void SAL_CALL
1505 ScVbaApplicationOutgoingConnectionPoint::Unadvise( sal_uInt32 Cookie )
1507 mpApp->RemoveSink( Cookie );
1510 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */