Bug Summary

File:home/maarten/src/libreoffice/core/sc/source/ui/vba/vbaapplication.cxx
Warning:line 530, column 1
Potential leak of memory pointed to by 'pNew.pObj'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name vbaapplication.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/mdds/include -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/sc/source/core/inc -I /home/maarten/src/libreoffice/core/sc/source/filter/inc -I /home/maarten/src/libreoffice/core/sc/source/ui/inc -I /home/maarten/src/libreoffice/core/sc/inc -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/oovbaapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/sc/source/ui/vba/vbaapplication.cxx
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
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
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"
58
59#include <osl/file.hxx>
60#include <rtl/instance.hxx>
61
62#include <sfx2/bindings.hxx>
63#include <sfx2/request.hxx>
64#include <sfx2/app.hxx>
65#include <vcl/svapp.hxx>
66
67#include <tools/diagnose_ex.h>
68
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>
74
75#include <convuno.hxx>
76#include <cellsuno.hxx>
77#include <unonames.hxx>
78#include <docsh.hxx>
79#include "excelvbahelper.hxx"
80
81#include <basic/sbxobj.hxx>
82
83#include <viewutil.hxx>
84#include <docoptio.hxx>
85#include <scmod.hxx>
86#include <scdll.hxx>
87
88using namespace ::ooo::vba;
89using namespace ::com::sun::star;
90using ::com::sun::star::uno::Reference;
91using ::com::sun::star::uno::UNO_QUERY_THROW;
92using ::com::sun::star::uno::UNO_QUERY;
93
94/** Global application settings shared by all open workbooks. */
95struct ScVbaAppSettings
96{
97 bool mbDisplayAlerts;
98 bool mbEnableEvents;
99 bool mbExcel4Menus;
100 bool mbDisplayNoteIndicator;
101 bool mbShowWindowsInTaskbar;
102 bool mbEnableCancelKey;
103 explicit ScVbaAppSettings();
104};
105
106ScVbaAppSettings::ScVbaAppSettings() :
107 mbDisplayAlerts( true ),
108 mbEnableEvents( true ),
109 mbExcel4Menus( false ),
110 mbDisplayNoteIndicator( true ),
111 mbShowWindowsInTaskbar( true ),
112 mbEnableCancelKey( false )
113{
114}
115
116namespace {
117
118struct ScVbaStaticAppSettings : public ::rtl::Static< ScVbaAppSettings, ScVbaStaticAppSettings > {};
119
120class ScVbaApplicationOutgoingConnectionPoint : public cppu::WeakImplHelper<XConnectionPoint>
121{
122private:
123 ScVbaApplication* mpApp;
124
125public:
126 ScVbaApplicationOutgoingConnectionPoint( ScVbaApplication* pApp );
127
128 // XConnectionPoint
129 sal_uInt32 SAL_CALL Advise(const uno::Reference< XSink >& Sink ) override;
130 void SAL_CALL Unadvise( sal_uInt32 Cookie ) override;
131};
132
133}
134
135sal_uInt32
136ScVbaApplication::AddSink( const uno::Reference< XSink >& xSink )
137{
138 {
139 SolarMutexGuard aGuard;
140 ScDLL::Init();
141 }
142 // No harm in potentially calling this several times
143 SC_MOD()( static_cast<ScModule*>(SfxApplication::GetModule(SfxToolsModule
::Calc)) )
->RegisterAutomationApplicationEventsCaller( uno::Reference< XSinkCaller >(this) );
144 mvSinks.push_back(xSink);
145 return mvSinks.size();
146}
147
148void
149ScVbaApplication::RemoveSink( sal_uInt32 nNumber )
150{
151 if (nNumber < 1 || nNumber > mvSinks.size())
152 return;
153
154 mvSinks[nNumber-1] = uno::Reference< XSink >();
155}
156
157ScVbaApplication::ScVbaApplication( const uno::Reference<uno::XComponentContext >& xContext ) :
158 ScVbaApplication_BASE( xContext ),
159 mrAppSettings( ScVbaStaticAppSettings::get() ),
160 m_nDialogType(0)
161{
162}
163
164ScVbaApplication::~ScVbaApplication()
165{
166}
167
168/*static*/ bool ScVbaApplication::getDocumentEventsEnabled()
169{
170 return ScVbaStaticAppSettings::get().mbEnableEvents;
171}
172
173OUString SAL_CALL
174ScVbaApplication::getExactName( const OUString& aApproximateName )
175{
176 uno::Reference< beans::XExactName > xWSF( new ScVbaWSFunction( this, mxContext ) );
177 return xWSF->getExactName( aApproximateName );
178}
179
180uno::Reference< beans::XIntrospectionAccess > SAL_CALL
181ScVbaApplication::getIntrospection()
182{
183 uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
184 return xWSF->getIntrospection();
185}
186
187uno::Any SAL_CALL
188ScVbaApplication::invoke( const OUString& FunctionName, const uno::Sequence< uno::Any >& Params, uno::Sequence< sal_Int16 >& OutParamIndex, uno::Sequence< uno::Any >& OutParam)
189{
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;
193 try
194 {
195 uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
196 aAny = xWSF->invoke( FunctionName, Params, OutParamIndex, OutParam );
197 }
198 catch (const uno::Exception&)
199 {
200 aAny <<= script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), 1000, OUString() );
201 }
202 return aAny;
203}
204
205void SAL_CALL
206ScVbaApplication::setValue( const OUString& PropertyName, const uno::Any& Value )
207{
208 uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
209 xWSF->setValue( PropertyName, Value );
210}
211
212uno::Any SAL_CALL
213ScVbaApplication::getValue( const OUString& PropertyName )
214{
215 uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
216 return xWSF->getValue( PropertyName );
217}
218
219sal_Bool SAL_CALL
220ScVbaApplication::hasMethod( const OUString& Name )
221{
222 uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
223 return xWSF->hasMethod( Name );
224}
225
226sal_Bool SAL_CALL
227ScVbaApplication::hasProperty( const OUString& Name )
228{
229 uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
230 return xWSF->hasProperty( Name );
231}
232
233uno::Reference< excel::XWorkbook >
234ScVbaApplication::getActiveWorkbook()
235{
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 );
241}
242
243uno::Reference< excel::XWorkbook > SAL_CALL
244ScVbaApplication::getThisWorkbook()
245{
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 );
251}
252
253uno::Reference< XAssistant > SAL_CALL
254ScVbaApplication::getAssistant()
255{
256 return uno::Reference< XAssistant >( new ScVbaAssistant( this, mxContext ) );
257}
258
259uno::Any SAL_CALL
260ScVbaApplication::getSelection()
261{
262 uno::Reference< frame::XModel > xModel( getCurrentDocument() );
263
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"FilteredRangeSelection" );
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 );
273
274 if (!aSelection.is())
275 {
276 throw uno::RuntimeException( "failed to obtain current selection" );
277 }
278
279 uno::Reference< lang::XServiceInfo > xServiceInfo( aSelection, uno::UNO_QUERY_THROW );
280 OUString sImplementationName = xServiceInfo->getImplementationName();
281
282 if( sImplementationName.equalsIgnoreAsciiCase("com.sun.star.drawing.SvxShapeCollection") )
283 {
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 )
292 {
293 // TODO Oval with text box
294 if( ScVbaShape::getAutoShapeType( xShape ) == office::MsoAutoShapeType::msoShapeOval )
295 {
296 return uno::makeAny( uno::Reference< msforms::XOval >(new ScVbaOvalShape( mxContext, xShape, xShapes, xModel ) ) );
297 }
298
299
300 uno::Reference< lang::XServiceInfo > xShapeServiceInfo( xShape, uno::UNO_QUERY_THROW );
301 if ( xShapeServiceInfo->supportsService("com.sun.star.drawing.Text") )
302 {
303 return uno::makeAny( uno::Reference< msforms::XTextBoxShape >(
304 new ScVbaTextBoxShape( mxContext, xShape, xShapes, xModel ) ) );
305 }
306 }
307 else if ( nType == office::MsoShapeType::msoLine )
308 {
309 return uno::makeAny( uno::Reference< msforms::XLine >( new ScVbaLineShape(
310 mxContext, xShape, xShapes, xModel ) ) );
311 }
312 return uno::makeAny( uno::Reference< msforms::XShape >(new ScVbaShape( this, mxContext, xShape, xShapes, xModel, ScVbaShape::getType( xShape ) ) ) );
313 }
314 else if( xServiceInfo->supportsService("com.sun.star.sheet.SheetCellRange") ||
315 xServiceInfo->supportsService("com.sun.star.sheet.SheetCellRanges") )
316 {
317 uno::Reference< table::XCellRange > xRange( aSelection, ::uno::UNO_QUERY);
318 if ( !xRange.is() )
319 {
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 ) ) );
323
324 }
325 return uno::makeAny( uno::Reference< excel::XRange >(new ScVbaRange( excel::getUnoSheetModuleObj( xRange ), mxContext, xRange ) ) );
326 }
327 else
328 {
329 throw uno::RuntimeException( sImplementationName + " not supported" );
330 }
331}
332
333uno::Reference< excel::XRange >
334ScVbaApplication::getActiveCell()
335{
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();
342
343 sal_Int32 nCursorX = rTabView.GetCurX();
344 sal_Int32 nCursorY = rTabView.GetCurY();
345
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 ) );
348}
349
350uno::Any SAL_CALL
351ScVbaApplication::International( sal_Int32 /*Index*/ )
352{
353 // complete stub for now
354 // #TODO flesh out some of the Indices we could handle
355 uno::Any aRet;
356 return aRet;
357}
358
359uno::Any SAL_CALL
360ScVbaApplication::FileDialog( const uno::Any& DialogType )
361{
362 sal_Int32 nType = 0;
363 DialogType >>= nType;
364
365 if( !m_xFileDialog || nType != m_nDialogType )
366 {
367 m_nDialogType = nType;
368 m_xFileDialog = uno::Reference<excel::XFileDialog> ( new ScVbaFileDialog( this, mxContext, nType ));
369 }
370 return uno::Any( m_xFileDialog );
371}
372
373uno::Any SAL_CALL
374ScVbaApplication::Workbooks( const uno::Any& aIndex )
375{
376 uno::Reference< XCollection > xWorkBooks( new ScVbaWorkbooks( this, mxContext ) );
377 if ( aIndex.getValueTypeClass() == uno::TypeClass_VOID )
378 {
379 // void then somebody did Workbooks.something in vba
380 return uno::Any( xWorkBooks );
381 }
382
383 return xWorkBooks->Item( aIndex, uno::Any() );
384}
385
386uno::Any SAL_CALL
387ScVbaApplication::Worksheets( const uno::Any& aIndex )
388{
389 uno::Reference< excel::XWorkbook > xWorkbook( getActiveWorkbook(), uno::UNO_SET_THROW );
390 return xWorkbook->Worksheets( aIndex );
391}
392
393uno::Any SAL_CALL
394ScVbaApplication::WorksheetFunction( )
395{
396 return uno::makeAny( uno::Reference< script::XInvocation >( new ScVbaWSFunction( this, mxContext ) ) );
397}
398
399uno::Any SAL_CALL
400ScVbaApplication::Evaluate( const OUString& Name )
401{
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 ) );
407}
408
409uno::Any
410ScVbaApplication::Dialogs( const uno::Any &aIndex )
411{
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 );
416}
417
418uno::Reference< excel::XWindow > SAL_CALL
419ScVbaApplication::getActiveWindow()
420{
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;
426}
427
428uno::Any SAL_CALL
429ScVbaApplication::getCutCopyMode()
430{
431 //# FIXME TODO, implementation
432 uno::Any result;
433 result <<= false;
434 return result;
435}
436
437void SAL_CALL
438ScVbaApplication::setCutCopyMode( const uno::Any& /* _cutcopymode */ )
439{
440 //# FIXME TODO, implementation
441}
442
443uno::Any SAL_CALL
444ScVbaApplication::getStatusBar()
445{
446 return uno::makeAny( !getDisplayStatusBar() );
447}
448
449void SAL_CALL
450ScVbaApplication::setStatusBar( const uno::Any& _statusbar )
451{
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 )
458 {
459 setDisplayStatusBar( true );
460 if ( !sText.isEmpty() )
461 xStatusIndicator->start( sText, 100 );
462 else
463 xStatusIndicator->end(); // restore normal state for empty text
464 }
465 else if( _statusbar >>= bDefault )
466 {
467 if( !bDefault )
468 {
469 xStatusIndicator->end();
470 setDisplayStatusBar( true );
471 }
472 }
473 else
474 throw uno::RuntimeException("Invalid parameter. It should be a string or False" );
475}
476
477::sal_Int32 SAL_CALL
478ScVbaApplication::getCalculation()
479{
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;
486}
487
488void SAL_CALL
489ScVbaApplication::setCalculation( ::sal_Int32 _calculation )
490{
491 // TODO: in Excel, this is an application-wide setting
492 uno::Reference< sheet::XCalculatable > xCalc(getCurrentDocument(), uno::UNO_QUERY_THROW);
493 switch(_calculation)
494 {
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;
502 }
503}
504
505uno::Any SAL_CALL
506ScVbaApplication::Windows( const uno::Any& aIndex )
507{
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() );
512}
513void SAL_CALL
514ScVbaApplication::wait( double time )
515{
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 ));
522
523 if ( pMeth )
1
Assuming 'pMeth' is non-null
2
Taking true branch
524 {
525 pMeth->SetParameters( aArgs.get() );
526 SbxVariableRef refTemp = pMeth;
527 // forces a broadcast
528 SbxVariableRef pNew = new SbxMethod( *static_cast<SbxMethod*>(pMeth));
3
Memory is allocated
529 }
530}
4
Potential leak of memory pointed to by 'pNew.pObj'
531
532uno::Any SAL_CALL
533ScVbaApplication::Range( const uno::Any& Cell1, const uno::Any& Cell2 )
534{
535 uno::Reference< excel::XRange > xVbRange = ScVbaRange::ApplicationRange( mxContext, Cell1, Cell2 );
536 return uno::makeAny( xVbRange );
537}
538
539uno::Any SAL_CALL
540ScVbaApplication::Names( const css::uno::Any& aIndex )
541{
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 );
546
547 css::uno::Reference< excel::XNames > xNames ( new ScVbaNames( this , mxContext , xNamedRanges , xModel ) );
548 if ( aIndex.getValueTypeClass() == uno::TypeClass_VOID )
549 {
550 return uno::Any( xNames );
551 }
552 return xNames->Item( aIndex, uno::Any() );
553}
554
555uno::Reference< excel::XWorksheet > SAL_CALL
556ScVbaApplication::getActiveSheet()
557{
558 uno::Reference< excel::XWorksheet > result;
559 uno::Reference< excel::XWorkbook > xWorkbook = getActiveWorkbook();
560 if ( xWorkbook.is() )
561 {
562 uno::Reference< excel::XWorksheet > xWorksheet =
563 xWorkbook->getActiveSheet();
564 if ( xWorksheet.is() )
565 {
566 result = xWorksheet;
567 }
568 }
569
570 if ( !result.is() )
571 {
572 // Fixme - check if this is reasonable/desired behavior
573 throw uno::RuntimeException("No activeSheet available" );
574 }
575 return result;
576
577}
578
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*******************************************************************************/
589void SAL_CALL
590ScVbaApplication::GoTo( const uno::Any& Reference, const uno::Any& Scroll )
591{
592 //test Scroll is a boolean
593 bool bScroll = false;
594 //R1C1-style string or a string of procedure name.
595
596 if( Scroll.hasValue() )
597 {
598 bool aScroll = false;
599 if( !(Scroll >>= aScroll) )
600 throw uno::RuntimeException("second parameter should be boolean" );
601
602 bScroll = aScroll;
603
604 }
605
606 OUString sRangeName;
607 if( Reference >>= sRangeName )
608 {
609 uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW );
610 uno::Reference< sheet::XSpreadsheetView > xSpreadsheet(
611 xModel->getCurrentController(), uno::UNO_QUERY_THROW );
612
613 ScTabViewShell* pShell = excel::getCurrentBestViewShell( mxContext );
614 ScGridWindow* gridWindow = static_cast<ScGridWindow*>(pShell->GetWindow());
615 try
616 {
617 uno::Reference< excel::XRange > xVbaSheetRange = ScVbaRange::getRangeObjectForName(
618 mxContext, sRangeName, excel::getDocShell( xModel ), formula::FormulaGrammar::CONV_XL_R1C1 );
619
620 if( bScroll )
621 {
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();
632 }
633 else
634 {
635 xVbaSheetRange->Select();
636 gridWindow->GrabFocus();
637 }
638 }
639 catch (const uno::RuntimeException&)
640 {
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" );
648 }
649 return;
650 }
651 uno::Reference< excel::XRange > xRange;
652 if( Reference >>= xRange )
653 {
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() )
658 {
659 //TODO bScroll should be used. At this time, it does not have effect
660 if( bScroll )
661 {
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();
672 }
673 else
674 {
675 xVbaRange->Select();
676 gridWindow->GrabFocus();
677 }
678 }
679 return;
680 }
681 throw uno::RuntimeException("invalid reference or name" );
682}
683
684sal_Int32 SAL_CALL
685ScVbaApplication::getCursor()
686{
687 PointerStyle nPointerStyle = getPointerStyle(getCurrentDocument());
688
689 switch( nPointerStyle )
690 {
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;
701 }
702}
703
704void SAL_CALL
705ScVbaApplication::setCursor( sal_Int32 _cursor )
706{
707 try
708 {
709 uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW );
710 switch( _cursor )
711 {
712 case excel::XlMousePointer::xlNorthwestArrow:
713 {
714 setCursorHelper( xModel, PointerStyle::Arrow, false );
715 break;
716 }
717 case excel::XlMousePointer::xlWait:
718 case excel::XlMousePointer::xlIBeam:
719 {
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;
724 }
725 case excel::XlMousePointer::xlDefault:
726 {
727 setCursorHelper( xModel, PointerStyle::Null, false );
728 break;
729 }
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
734 }
735 }
736 catch (const uno::Exception&)
737 {
738 DBG_UNHANDLED_EXCEPTION("sc.ui")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/sc/source/ui/vba/vbaapplication.cxx"
":" "738" ": ", "sc.ui" );
;
739 }
740}
741
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
744OUString SAL_CALL
745ScVbaApplication::getName()
746{
747 return "Microsoft Excel";
748}
749
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
755
756void SAL_CALL
757ScVbaApplication::setDisplayAlerts(sal_Bool displayAlerts)
758{
759 mrAppSettings.mbDisplayAlerts = displayAlerts;
760}
761
762sal_Bool SAL_CALL
763ScVbaApplication::getDisplayAlerts()
764{
765 return mrAppSettings.mbDisplayAlerts;
766}
767
768void SAL_CALL
769ScVbaApplication::setEnableEvents(sal_Bool bEnable)
770{
771 mrAppSettings.mbEnableEvents = bEnable;
772}
773
774sal_Bool SAL_CALL
775ScVbaApplication::getEnableEvents()
776{
777 return mrAppSettings.mbEnableEvents;
778}
779
780void SAL_CALL
781ScVbaApplication::setEnableCancelKey(sal_Bool bEnable)
782{
783 // Stub, does nothing
784 mrAppSettings.mbEnableCancelKey = bEnable;
785}
786
787sal_Bool SAL_CALL
788ScVbaApplication::getEnableCancelKey()
789{
790 return mrAppSettings.mbEnableCancelKey;
791}
792
793sal_Bool SAL_CALL
794ScVbaApplication::getDisplayFullScreen()
795{
796 SfxViewShell* pShell = excel::getCurrentBestViewShell( mxContext );
797 if ( pShell )
798 return ScViewUtil::IsFullScreen( *pShell );
799 return false;
800}
801
802void SAL_CALL
803ScVbaApplication::setDisplayFullScreen( sal_Bool bSet )
804{
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" );
809}
810
811sal_Bool SAL_CALL
812ScVbaApplication::getDisplayScrollBars()
813{
814 ScTabViewShell* pShell = excel::getCurrentBestViewShell( mxContext );
815 if ( pShell )
816 {
817 return ( pShell->GetViewData().IsHScrollMode() && pShell->GetViewData().IsVScrollMode() );
818 }
819 return true;
820}
821
822void SAL_CALL
823ScVbaApplication::setDisplayScrollBars( sal_Bool bSet )
824{
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 ) );
830}
831
832sal_Bool SAL_CALL
833ScVbaApplication::getDisplayExcel4Menus()
834{
835 return mrAppSettings.mbExcel4Menus;
836}
837
838void SAL_CALL
839ScVbaApplication::setDisplayExcel4Menus( sal_Bool bSet )
840{
841 mrAppSettings.mbExcel4Menus = bSet;
842}
843
844sal_Bool SAL_CALL
845ScVbaApplication::getDisplayNoteIndicator()
846{
847 return mrAppSettings.mbDisplayNoteIndicator;
848}
849
850void SAL_CALL
851ScVbaApplication::setDisplayNoteIndicator( sal_Bool bSet )
852{
853 mrAppSettings.mbDisplayNoteIndicator = bSet;
854}
855
856sal_Bool SAL_CALL
857ScVbaApplication::getShowWindowsInTaskbar()
858{
859 return mrAppSettings.mbShowWindowsInTaskbar;
860}
861
862void SAL_CALL
863ScVbaApplication::setShowWindowsInTaskbar( sal_Bool bSet )
864{
865 mrAppSettings.mbShowWindowsInTaskbar = bSet;
866}
867
868sal_Bool SAL_CALL
869ScVbaApplication::getIteration()
870{
871 return SC_MOD()( static_cast<ScModule*>(SfxApplication::GetModule(SfxToolsModule
::Calc)) )
->GetDocOptions().IsIter();
872}
873
874void SAL_CALL
875ScVbaApplication::setIteration( sal_Bool bSet )
876{
877 uno::Reference< lang::XMultiComponentFactory > xSMgr(
878 mxContext->getServiceManager(), uno::UNO_SET_THROW );
879
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() )
884 {
885 uno::Reference< lang::XServiceInfo > xServiceInfo( xComponents->nextElement(), uno::UNO_QUERY );
886 if ( xServiceInfo.is() && xServiceInfo->supportsService( "com.sun.star.sheet.SpreadsheetDocument" ) )
887 {
888 uno::Reference< beans::XPropertySet > xProps( xServiceInfo, uno::UNO_QUERY );
889 if ( xProps.is() )
890 xProps->setPropertyValue( SC_UNO_ITERENABLED"IsIterationEnabled", uno::Any( bSet ) );
891 }
892 }
893 ScDocOptions aOpts( SC_MOD()( static_cast<ScModule*>(SfxApplication::GetModule(SfxToolsModule
::Calc)) )
->GetDocOptions() );
894 aOpts.SetIter( bSet );
895 SC_MOD()( static_cast<ScModule*>(SfxApplication::GetModule(SfxToolsModule
::Calc)) )
->SetDocOptions( aOpts );
896}
897
898void SAL_CALL
899ScVbaApplication::Calculate()
900{
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();
904}
905
906/// @throws uno::RuntimeException
907static uno::Reference< util::XPathSettings > const & lcl_getPathSettingsService( const uno::Reference< uno::XComponentContext >& xContext )
908{
909 static uno::Reference< util::XPathSettings > xPathSettings( util::PathSettings::create( xContext ) );
910 return xPathSettings;
911}
912
913OUString ScVbaApplication::getOfficePath( const OUString& _sPathType )
914{
915 OUString sRetPath;
916 const uno::Reference< util::XPathSettings >& xProps = lcl_getPathSettingsService( mxContext );
917 try
918 {
919 OUString sUrl;
920 xProps->getPropertyValue( _sPathType ) >>= sUrl;
921
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 );
927 }
928 catch (const uno::Exception&)
929 {
930 DebugHelper::runtimeexception(ERRCODE_BASIC_METHOD_FAILEDErrCode( ErrCodeArea::Sbx, ErrCodeClass::Runtime, 89 ));
931 }
932 return sRetPath;
933}
934
935void SAL_CALL
936ScVbaApplication::setDefaultFilePath( const OUString& DefaultFilePath )
937{
938 const uno::Reference< util::XPathSettings >& xProps = lcl_getPathSettingsService( mxContext );
939 OUString aURL;
940 osl::FileBase::getFileURLFromSystemPath( DefaultFilePath, aURL );
941 xProps->setWork( aURL );
942}
943
944OUString SAL_CALL
945ScVbaApplication::getDefaultFilePath()
946{
947 return getOfficePath( "Work");
948}
949
950OUString SAL_CALL
951ScVbaApplication::getLibraryPath()
952{
953 return getOfficePath( "Basic");
954}
955
956OUString SAL_CALL
957ScVbaApplication::getTemplatesPath()
958{
959 return getOfficePath( "Template");
960}
961
962OUString SAL_CALL
963ScVbaApplication::getPathSeparator()
964{
965 return OUString( sal_Unicode(SAL_PATHDELIMITER'/') );
966}
967
968OUString SAL_CALL
969ScVbaApplication::getOperatingSystem()
970{
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(UNX1)
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
983}
984
985// Helpers for Intersect and Union
986
987namespace {
988
989typedef ::std::list< ScRange > ListOfScRange;
990
991/** Appends all ranges of a VBA Range object in the passed Any to the list of ranges.
992
993 @throws script::BasicErrorException
994 @throws uno::RuntimeException
995*/
996void lclAddToListOfScRange( ListOfScRange& rList, const uno::Any& rArg )
997{
998 if( !rArg.hasValue() )
999 return;
1000
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 )
1004 {
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 );
1010 }
1011}
1012
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. */
1015bool lclTryJoin( ScRange& r1, const ScRange& r2 )
1016{
1017 // 1) r2 is completely inside r1
1018 if( r1.In( r2 ) )
1019 return true;
1020
1021 // 2) r1 is completely inside r2
1022 if( r2.In( r1 ) )
1023 {
1024 r1 = r2;
1025 return true;
1026 }
1027
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();
1036
1037 // 3) r1 and r2 have equal upper and lower border
1038 if( (n1T == n2T) && (n1B == n2B) )
1039 {
1040 // check that r1 overlaps or touches r2
1041 if( ((n1L < n2L) && (n2L - 1 <= n1R)) || ((n2L < n1L) && (n1L - 1 <= n2R)) )
1042 {
1043 r1.aStart.SetCol( ::std::min( n1L, n2L ) );
1044 r1.aEnd.SetCol( ::std::max( n1R, n2R ) );
1045 return true;
1046 }
1047 return false;
1048 }
1049
1050 // 4) r1 and r2 have equal left and right border
1051 if( (n1L == n2L) && (n1R == n2R) )
1052 {
1053 // check that r1 overlaps or touches r2
1054 if( ((n1T < n2T) && (n2T + 1 <= n1B)) || ((n2T < n1T) && (n1T + 1 <= n2B)) )
1055 {
1056 r1.aStart.SetRow( ::std::min( n1T, n2T ) );
1057 r1.aEnd.SetRow( ::std::max( n1B, n2B ) );
1058 return true;
1059 }
1060 return false;
1061 }
1062
1063 // 5) cannot join these ranges
1064 return false;
1065}
1066
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. */
1069void lclJoinRanges( ListOfScRange& rList )
1070{
1071 ListOfScRange::iterator aOuterIt = rList.begin();
1072 while( aOuterIt != rList.end() )
1073 {
1074 bool bAnyErased = false; // true = any range erased from rList
1075 ListOfScRange::iterator aInnerIt = rList.begin();
1076 while( aInnerIt != rList.end() )
1077 {
1078 bool bInnerErased = false; // true = aInnerIt erased from rList
1079 // do not compare a range with itself
1080 if( (aOuterIt != aInnerIt) && lclTryJoin( *aOuterIt, *aInnerIt ) )
1081 {
1082 // aOuterIt points to joined range, aInnerIt will be removed
1083 aInnerIt = rList.erase( aInnerIt );
1084 bInnerErased = bAnyErased = true;
1085 }
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;
1090 }
1091 // if any range has been erased, repeat outer loop with the same range
1092 if( !bAnyErased )
1093 ++aOuterIt;
1094 }
1095}
1096
1097/** Intersects the passed list with all ranges of a VBA Range object in the passed Any.
1098
1099 @throws script::BasicErrorException
1100 @throws uno::RuntimeException
1101*/
1102void lclIntersectRanges( ListOfScRange& rList, const uno::Any& rArg )
1103{
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;
1110
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 )
1118 {
1119 for( const auto& rInnerItem : aList2 )
1120 {
1121 if( rOuterItem.Intersects( rInnerItem ) )
1122 {
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 );
1131 }
1132 }
1133 }
1134 // again, join the result ranges
1135 lclJoinRanges( rList );
1136}
1137
1138/** Creates a VBA Range object from the passed list of ranges.
1139
1140 @throws uno::RuntimeException
1141*/
1142uno::Reference< excel::XRange > lclCreateVbaRange(
1143 const uno::Reference< uno::XComponentContext >& rxContext,
1144 const uno::Reference< frame::XModel >& rxModel,
1145 const ListOfScRange& rList )
1146{
1147 ScDocShell* pDocShell = excel::getDocShell( rxModel );
1148 if( !pDocShell ) throw uno::RuntimeException();
1149
1150 ScRangeList aCellRanges;
1151 for( const auto& rItem : rList )
1152 aCellRanges.push_back( rItem );
1153
1154 if( aCellRanges.size() == 1 )
1155 {
1156 uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pDocShell, aCellRanges.front() ) );
1157 return new ScVbaRange( excel::getUnoSheetModuleObj( xRange ), rxContext, xRange );
1158 }
1159 if( aCellRanges.size() > 1 )
1160 {
1161 uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pDocShell, aCellRanges ) );
1162 return new ScVbaRange( excel::getUnoSheetModuleObj( xRanges ), rxContext, xRanges );
1163 }
1164 return nullptr;
1165}
1166
1167} // namespace
1168
1169uno::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 )
1178{
1179 if( !rArg1.is() || !rArg2.is() )
1180 DebugHelper::basicexception( ERRCODE_BASIC_BAD_PARAMETERErrCode( ErrCodeArea::Sbx, ErrCodeClass::Runtime, 7), OUString() );
1181
1182 // initialize the result list with 1st parameter, join its ranges together
1183 ListOfScRange aList;
1184 lclAddToListOfScRange( aList, uno::Any( rArg1 ) );
1185 lclJoinRanges( aList );
1186
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 );
1217
1218 // create the VBA Range object
1219 return lclCreateVbaRange( mxContext, getCurrentDocument(), aList );
1220}
1221
1222uno::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 )
1231{
1232 if( !rArg1.is() || !rArg2.is() )
1233 DebugHelper::basicexception( ERRCODE_BASIC_BAD_PARAMETERErrCode( ErrCodeArea::Sbx, ErrCodeClass::Runtime, 7), OUString() );
1234
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 );
1266
1267 // simply join together all ranges as much as possible, strip out covered ranges etc.
1268 lclJoinRanges( aList );
1269
1270 // create the VBA Range object
1271 return lclCreateVbaRange( mxContext, getCurrentDocument(), aList );
1272}
1273
1274double
1275ScVbaApplication::InchesToPoints( double Inches )
1276{
1277 double result = Inches * 72.0;
1278 return result;
1279}
1280
1281void
1282ScVbaApplication::Volatile( const uno::Any& aVolatile )
1283{
1284 bool bVolatile = true;
1285 aVolatile >>= bVolatile;
1286 SbMethod* pMeth = StarBASIC::GetActiveMethod();
1287 if ( pMeth )
1288 {
1289 uno::Reference< frame::XModel > xModel( getCurrentDocument() );
1290 ScDocument& rDoc = excel::getDocShell( xModel )->GetDocument();
1291 rDoc.GetMacroManager()->SetUserFuncVolatile( pMeth->GetName(), bVolatile);
1292 }
1293
1294// this is bound to break when loading the document
1295}
1296
1297sal_Bool SAL_CALL
1298ScVbaApplication::getDisplayFormulaBar()
1299{
1300 bool bRes = false;
1301 ScTabViewShell* pViewShell = excel::getCurrentBestViewShell( mxContext );
1302 if ( pViewShell )
1303 {
1304 SfxBoolItem sfxFormBar( FID_TOGGLEINPUTLINE((((((26000 + 200) + 20)) + 20)) + 1));
1305 SfxAllItemSet reqList( SfxGetpApp()->GetPool() );
1306 reqList.Put( sfxFormBar );
1307
1308 pViewShell->GetState( reqList );
1309 const SfxPoolItem *pItem=nullptr;
1310 if ( reqList.GetItemState( FID_TOGGLEINPUTLINE((((((26000 + 200) + 20)) + 20)) + 1), false, &pItem ) == SfxItemState::SET )
1311 bRes = static_cast<const SfxBoolItem*>(pItem)->GetValue();
1312 }
1313 return bRes;
1314}
1315
1316void SAL_CALL
1317ScVbaApplication::setDisplayFormulaBar( sal_Bool _displayformulabar )
1318{
1319 ScTabViewShell* pViewShell = excel::getCurrentBestViewShell( mxContext );
1320 if ( pViewShell && ( _displayformulabar != getDisplayFormulaBar() ) )
1321 {
1322 SfxAllItemSet reqList( SfxGetpApp()->GetPool() );
1323 SfxRequest aReq( FID_TOGGLEINPUTLINE((((((26000 + 200) + 20)) + 20)) + 1), SfxCallMode::SLOT, reqList );
1324 pViewShell->Execute( aReq );
1325 }
1326}
1327
1328uno::Any SAL_CALL
1329ScVbaApplication::Caller( const uno::Any& /*aIndex*/ )
1330{
1331 StarBASIC* pBasic = SfxApplication::GetBasic();
1332 SbMethod* pMeth = static_cast<SbMethod*>(pBasic->GetRtl()->Find( "FuncCaller", SbxClassType::Method ));
1333 uno::Any aRet;
1334 if ( pMeth )
1335 {
1336 SbxVariableRef refTemp = pMeth;
1337 // forces a broadcast
1338 SbxVariableRef pNew = new SbxMethod( *static_cast<SbxMethod*>(pMeth));
1339 aRet = sbxToUnoValue( pNew.get() );
1340 }
1341 return aRet;
1342}
1343
1344uno::Reference< frame::XModel >
1345ScVbaApplication::getCurrentDocument()
1346{
1347 return getCurrentExcelDoc(mxContext);
1348}
1349
1350uno::Any SAL_CALL
1351ScVbaApplication::MenuBars( const uno::Any& aIndex )
1352{
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() )
1356 {
1357 return xMenuBars->Item( aIndex, uno::Any() );
1358 }
1359
1360 return uno::Any( xMenuBars );
1361}
1362
1363uno::Any SAL_CALL
1364ScVbaApplication::Rows( const uno::Any& aIndex )
1365{
1366 uno::Reference< excel::XWorksheet > xWorksheet = getActiveSheet();
1367 if ( xWorksheet.is() )
1368 return uno::Any( xWorksheet->Rows( aIndex ) );
1369 return uno::Any();
1370}
1371
1372void SAL_CALL ScVbaApplication::OnKey( const OUString& Key, const uno::Any& Procedure )
1373{
1374 try
1375 {
1376 // Perhaps we can catch some excel specific
1377 // related behaviour here
1378 VbaApplicationBase::OnKey( Key, Procedure );
1379 }
1380 catch( container::NoSuchElementException& )
1381 {
1382 // #TODO special handling for unhandled
1383 // bindings
1384 }
1385}
1386
1387void SAL_CALL ScVbaApplication::setScreenUpdating(sal_Bool bUpdate)
1388{
1389 VbaApplicationBase::setScreenUpdating( bUpdate );
1390
1391 uno::Reference< frame::XModel > xModel( getCurrentExcelDoc( mxContext ), uno::UNO_SET_THROW );
1392 ScDocShell* pDocShell = excel::getDocShell( xModel );
1393 ScDocument& rDoc = pDocShell->GetDocument();
1394
1395 if( bUpdate )
1396 {
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();
1403 }
1404 else
1405 {
1406 rDoc.LockAdjustHeight();
1407 }
1408}
1409
1410void SAL_CALL ScVbaApplication::Undo()
1411{
1412 uno::Reference< frame::XModel > xModel( getThisExcelDoc( mxContext ), uno::UNO_SET_THROW );
1413
1414 ScTabViewShell* pViewShell = excel::getBestViewShell( xModel );
1415 if ( pViewShell )
1416 dispatchExecute( pViewShell, SID_UNDO(5000 + 701) );
1417}
1418
1419// XInterfaceWithIID
1420
1421OUString SAL_CALL
1422ScVbaApplication::getIID()
1423{
1424 return "{82154425-0FBF-11d4-8313-005004526AB4}";
1425}
1426
1427// XConnectable
1428
1429OUString SAL_CALL
1430ScVbaApplication::GetIIDForClassItselfNotCoclass()
1431{
1432 return "{82154426-0FBF-11D4-8313-005004526AB4}";
1433}
1434
1435TypeAndIID SAL_CALL
1436ScVbaApplication::GetConnectionPoint()
1437{
1438 TypeAndIID aResult =
1439 { excel::XApplicationOutgoing::static_type(),
1440 "{82154427-0FBF-11D4-8313-005004526AB4}"
1441 };
1442
1443 return aResult;
1444}
1445
1446uno::Reference<XConnectionPoint> SAL_CALL
1447ScVbaApplication::FindConnectionPoint()
1448{
1449 uno::Reference<XConnectionPoint> xCP(new ScVbaApplicationOutgoingConnectionPoint(this));
1450 return xCP;
1451}
1452
1453// XSinkCaller
1454
1455void SAL_CALL
1456ScVbaApplication::CallSinks( const OUString& Method, uno::Sequence< uno::Any >& Arguments )
1457{
1458 for (auto& i : mvSinks)
1459 {
1460 if (i.is())
1461 i->Call(Method, Arguments);
1462 }
1463}
1464
1465OUString
1466ScVbaApplication::getServiceImplName()
1467{
1468 return "ScVbaApplication";
1469}
1470
1471uno::Sequence< OUString >
1472ScVbaApplication::getServiceNames()
1473{
1474 static uno::Sequence< OUString > aServiceNames
1475 {
1476 "ooo.vba.excel.Application"
1477 };
1478 return aServiceNames;
1479}
1480
1481
1482extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) css::uno::XInterface*
1483Calc_ScVbaApplication_get_implementation(
1484 css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& )
1485{
1486 return cppu::acquire(new ScVbaApplication(context));
1487}
1488
1489
1490// ScVbaApplicationOutgoingConnectionPoint
1491
1492ScVbaApplicationOutgoingConnectionPoint::ScVbaApplicationOutgoingConnectionPoint( ScVbaApplication* pApp ) :
1493 mpApp(pApp)
1494{
1495}
1496
1497// XConnectionPoint
1498sal_uInt32 SAL_CALL
1499ScVbaApplicationOutgoingConnectionPoint::Advise( const uno::Reference< XSink >& Sink )
1500{
1501 return mpApp->AddSink(Sink);
1502}
1503
1504void SAL_CALL
1505ScVbaApplicationOutgoingConnectionPoint::Unadvise( sal_uInt32 Cookie )
1506{
1507 mpApp->RemoveSink( Cookie );
1508}
1509
1510/* vim:set shiftwidth=4 softtabstop=4 expandtab: */