Line data Source code
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 <stdio.h>
21 :
22 : #include <com/sun/star/frame/XLayoutManager.hpp>
23 : #include <com/sun/star/frame/XDesktop.hpp>
24 : #include <com/sun/star/lang/XServiceInfo.hpp>
25 : #include <com/sun/star/sheet/XCalculatable.hpp>
26 : #include <com/sun/star/sheet/XCellRangeAddressable.hpp>
27 : #include <com/sun/star/sheet/XCellRangeReferrer.hpp>
28 : #include <com/sun/star/sheet/XNamedRanges.hpp>
29 : #include <com/sun/star/sheet/XSpreadsheetView.hpp>
30 : #include <com/sun/star/sheet/XSpreadsheets.hpp>
31 : #include <com/sun/star/task/XStatusIndicatorSupplier.hpp>
32 : #include <com/sun/star/task/XStatusIndicator.hpp>
33 : #include <com/sun/star/util/PathSettings.hpp>
34 : #include <com/sun/star/view/XSelectionSupplier.hpp>
35 : #include <ooo/vba/XExecutableDialog.hpp>
36 : #include <ooo/vba/excel/XlCalculation.hpp>
37 : #include <ooo/vba/excel/XlMousePointer.hpp>
38 :
39 : #include "vbaapplication.hxx"
40 : #include "vbaworkbooks.hxx"
41 : #include "vbaworkbook.hxx"
42 : #include "vbaworksheets.hxx"
43 : #include "vbarange.hxx"
44 : #include "vbawsfunction.hxx"
45 : #include "vbadialogs.hxx"
46 : #include "vbawindow.hxx"
47 : #include "vbawindows.hxx"
48 : #include "vbaglobals.hxx"
49 : #include "vbamenubars.hxx"
50 : #include "tabvwsh.hxx"
51 : #include "gridwin.hxx"
52 : #include "vbanames.hxx"
53 : #include <vbahelper/vbashape.hxx>
54 : #include "vbatextboxshape.hxx"
55 : #include "vbaassistant.hxx"
56 : #include "sc.hrc"
57 : #include "macromgr.hxx"
58 : #include "defaultsoptions.hxx"
59 :
60 : #include <osl/file.hxx>
61 : #include <rtl/instance.hxx>
62 :
63 : #include <sfx2/request.hxx>
64 : #include <sfx2/objsh.hxx>
65 : #include <sfx2/viewfrm.hxx>
66 : #include <sfx2/app.hxx>
67 :
68 : #include <comphelper/processfactory.hxx>
69 :
70 : #include <toolkit/awt/vclxwindow.hxx>
71 : #include <toolkit/helper/vclunohelper.hxx>
72 :
73 : #include <tools/diagnose_ex.h>
74 : #include <tools/urlobj.hxx>
75 :
76 : #include <docuno.hxx>
77 :
78 : #include <basic/sbx.hxx>
79 : #include <basic/sbstar.hxx>
80 : #include <basic/sbuno.hxx>
81 : #include <basic/sbmeth.hxx>
82 :
83 : #include "convuno.hxx"
84 : #include "cellsuno.hxx"
85 : #include "miscuno.hxx"
86 : #include "unonames.hxx"
87 : #include "docsh.hxx"
88 : #include <vbahelper/helperdecl.hxx>
89 : #include "excelvbahelper.hxx"
90 :
91 : #include <basic/sbmod.hxx>
92 : #include <basic/sbxobj.hxx>
93 :
94 : #include "viewutil.hxx"
95 : #include "docoptio.hxx"
96 :
97 : using namespace ::ooo::vba;
98 : using namespace ::com::sun::star;
99 : using ::com::sun::star::uno::Reference;
100 : using ::com::sun::star::uno::UNO_QUERY_THROW;
101 : using ::com::sun::star::uno::UNO_QUERY;
102 :
103 : /** Global application settings shared by all open workbooks. */
104 : struct ScVbaAppSettings
105 : {
106 : sal_Int32 mnCalculation;
107 : bool mbDisplayAlerts;
108 : bool mbEnableEvents;
109 : bool mbExcel4Menus;
110 : bool mbDisplayNoteIndicator;
111 : bool mbShowWindowsInTaskbar;
112 : bool mbEnableCancelKey;
113 : explicit ScVbaAppSettings();
114 : };
115 :
116 4 : ScVbaAppSettings::ScVbaAppSettings() :
117 : mnCalculation( excel::XlCalculation::xlCalculationAutomatic ),
118 : mbDisplayAlerts( true ),
119 : mbEnableEvents( true ),
120 : mbExcel4Menus( false ),
121 : mbDisplayNoteIndicator( true ),
122 : mbShowWindowsInTaskbar( true ),
123 4 : mbEnableCancelKey( false )
124 : {
125 4 : }
126 :
127 : struct ScVbaStaticAppSettings : public ::rtl::Static< ScVbaAppSettings, ScVbaStaticAppSettings > {};
128 :
129 52 : ScVbaApplication::ScVbaApplication( const uno::Reference<uno::XComponentContext >& xContext ) :
130 : ScVbaApplication_BASE( xContext ),
131 52 : mrAppSettings( ScVbaStaticAppSettings::get() )
132 : {
133 52 : }
134 :
135 104 : ScVbaApplication::~ScVbaApplication()
136 : {
137 104 : }
138 :
139 4950 : /*static*/ bool ScVbaApplication::getDocumentEventsEnabled()
140 : {
141 4950 : return ScVbaStaticAppSettings::get().mbEnableEvents;
142 : }
143 :
144 0 : SfxObjectShell* ScVbaApplication::GetDocShell( const uno::Reference< frame::XModel >& xModel ) throw (uno::RuntimeException)
145 : {
146 0 : return static_cast< SfxObjectShell* >( excel::getDocShell( xModel ) );
147 : }
148 :
149 : OUString SAL_CALL
150 0 : ScVbaApplication::getExactName( const OUString& aApproximateName ) throw (uno::RuntimeException, std::exception)
151 : {
152 0 : uno::Reference< beans::XExactName > xWSF( new ScVbaWSFunction( this, mxContext ) );
153 0 : return xWSF->getExactName( aApproximateName );
154 : }
155 :
156 : uno::Reference< beans::XIntrospectionAccess > SAL_CALL
157 0 : ScVbaApplication::getIntrospection() throw(css::uno::RuntimeException, std::exception)
158 : {
159 0 : uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
160 0 : return xWSF->getIntrospection();
161 : }
162 :
163 : uno::Any SAL_CALL
164 0 : ScVbaApplication::invoke( const OUString& FunctionName, const uno::Sequence< uno::Any >& Params, uno::Sequence< sal_Int16 >& OutParamIndex, uno::Sequence< uno::Any >& OutParam) throw(lang::IllegalArgumentException, script::CannotConvertException, reflection::InvocationTargetException, uno::RuntimeException, std::exception)
165 : {
166 : /* When calling the functions directly at the Application object, no runtime
167 : errors are thrown, but the error is inserted into the return value. */
168 0 : uno::Any aAny;
169 : try
170 : {
171 0 : uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
172 0 : aAny = xWSF->invoke( FunctionName, Params, OutParamIndex, OutParam );
173 : }
174 0 : catch (const uno::Exception&)
175 : {
176 0 : aAny <<= script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), 1000, OUString() );
177 : }
178 0 : return aAny;
179 : }
180 :
181 : void SAL_CALL
182 0 : ScVbaApplication::setValue( const OUString& PropertyName, const uno::Any& Value ) throw(beans::UnknownPropertyException, script::CannotConvertException, reflection::InvocationTargetException, uno::RuntimeException, std::exception)
183 : {
184 0 : uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
185 0 : xWSF->setValue( PropertyName, Value );
186 0 : }
187 :
188 : uno::Any SAL_CALL
189 0 : ScVbaApplication::getValue( const OUString& PropertyName ) throw(beans::UnknownPropertyException, uno::RuntimeException, std::exception)
190 : {
191 0 : uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
192 0 : return xWSF->getValue( PropertyName );
193 : }
194 :
195 : sal_Bool SAL_CALL
196 0 : ScVbaApplication::hasMethod( const OUString& Name ) throw(uno::RuntimeException, std::exception)
197 : {
198 0 : uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
199 0 : return xWSF->hasMethod( Name );
200 : }
201 :
202 : sal_Bool SAL_CALL
203 0 : ScVbaApplication::hasProperty( const OUString& Name ) throw(uno::RuntimeException, std::exception)
204 : {
205 0 : uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) );
206 0 : return xWSF->hasProperty( Name );
207 : }
208 :
209 : uno::Reference< excel::XWorkbook >
210 526 : ScVbaApplication::getActiveWorkbook() throw (uno::RuntimeException, std::exception)
211 : {
212 526 : uno::Reference< frame::XModel > xModel( getCurrentExcelDoc( mxContext ), uno::UNO_SET_THROW );
213 1052 : uno::Reference< excel::XWorkbook > xWorkbook( getVBADocument( xModel ), uno::UNO_QUERY );
214 526 : if( xWorkbook.is() ) return xWorkbook;
215 : // #i116936# getVBADocument() may return null in documents without global VBA mode enabled
216 526 : return new ScVbaWorkbook( this, mxContext, xModel );
217 : }
218 :
219 : uno::Reference< excel::XWorkbook > SAL_CALL
220 0 : ScVbaApplication::getThisWorkbook() throw (uno::RuntimeException, std::exception)
221 : {
222 0 : uno::Reference< frame::XModel > xModel( getThisExcelDoc( mxContext ), uno::UNO_SET_THROW );
223 0 : uno::Reference< excel::XWorkbook > xWorkbook( getVBADocument( xModel ), uno::UNO_QUERY );
224 0 : if( xWorkbook.is() ) return xWorkbook;
225 : // #i116936# getVBADocument() may return null in documents without global VBA mode enabled
226 0 : return new ScVbaWorkbook( this, mxContext, xModel );
227 : }
228 :
229 : uno::Reference< XAssistant > SAL_CALL
230 0 : ScVbaApplication::getAssistant() throw (uno::RuntimeException, std::exception)
231 : {
232 0 : return uno::Reference< XAssistant >( new ScVbaAssistant( this, mxContext ) );
233 : }
234 :
235 : uno::Any SAL_CALL
236 50 : ScVbaApplication::getSelection() throw (uno::RuntimeException, std::exception)
237 : {
238 : OSL_TRACE("** ScVbaApplication::getSelection() ** ");
239 50 : uno::Reference< frame::XModel > xModel( getCurrentDocument() );
240 :
241 100 : Reference< view::XSelectionSupplier > xSelSupp( xModel->getCurrentController(), UNO_QUERY_THROW );
242 100 : Reference< beans::XPropertySet > xPropSet( xSelSupp, UNO_QUERY_THROW );
243 100 : OUString aPropName( SC_UNO_FILTERED_RANGE_SELECTION );
244 100 : uno::Any aOldVal = xPropSet->getPropertyValue( aPropName );
245 100 : uno::Any any;
246 50 : any <<= false;
247 50 : xPropSet->setPropertyValue( aPropName, any );
248 : uno::Reference< uno::XInterface > aSelection = ScUnoHelpFunctions::AnyToInterface(
249 100 : xSelSupp->getSelection() );
250 50 : xPropSet->setPropertyValue( aPropName, aOldVal );
251 :
252 50 : if (!aSelection.is())
253 : {
254 0 : throw uno::RuntimeException( "failed to obtain current selection" );
255 : }
256 :
257 100 : uno::Reference< lang::XServiceInfo > xServiceInfo( aSelection, uno::UNO_QUERY_THROW );
258 100 : OUString sImplementationName = xServiceInfo->getImplementationName();
259 :
260 50 : if( sImplementationName.equalsIgnoreAsciiCase("com.sun.star.drawing.SvxShapeCollection") )
261 : {
262 4 : uno::Reference< drawing::XShapes > xShapes( aSelection, uno::UNO_QUERY_THROW );
263 8 : uno::Reference< container::XIndexAccess > xIndexAccess( xShapes, uno::UNO_QUERY_THROW );
264 8 : uno::Reference< drawing::XShape > xShape( xIndexAccess->getByIndex(0), uno::UNO_QUERY_THROW );
265 : // if ScVbaShape::getType( xShape ) == office::MsoShapeType::msoAutoShape
266 : // and the uno object implements the com.sun.star.drawing.Text service
267 : // return a textboxshape object
268 4 : if ( ScVbaShape::getType( xShape ) == office::MsoShapeType::msoAutoShape )
269 : {
270 4 : uno::Reference< lang::XServiceInfo > xShapeServiceInfo( xShape, uno::UNO_QUERY_THROW );
271 4 : if ( xShapeServiceInfo->supportsService("com.sun.star.drawing.Text") )
272 : {
273 4 : return uno::makeAny( uno::Reference< msforms::XTextBoxShape >(new ScVbaTextBoxShape( mxContext, xShape, xShapes, xModel ) ) );
274 0 : }
275 : }
276 4 : return uno::makeAny( uno::Reference< msforms::XShape >(new ScVbaShape( this, mxContext, xShape, xShapes, xModel, ScVbaShape::getType( xShape ) ) ) );
277 : }
278 108 : else if( xServiceInfo->supportsService("com.sun.star.sheet.SheetCellRange") ||
279 62 : xServiceInfo->supportsService("com.sun.star.sheet.SheetCellRanges") )
280 : {
281 46 : uno::Reference< table::XCellRange > xRange( aSelection, ::uno::UNO_QUERY);
282 46 : if ( !xRange.is() )
283 : {
284 8 : uno::Reference< sheet::XSheetCellRangeContainer > xRanges( aSelection, ::uno::UNO_QUERY);
285 8 : if ( xRanges.is() )
286 8 : return uno::makeAny( uno::Reference< excel::XRange >( new ScVbaRange( excel::getUnoSheetModuleObj( xRanges ), mxContext, xRanges ) ) );
287 :
288 : }
289 38 : return uno::makeAny( uno::Reference< excel::XRange >(new ScVbaRange( excel::getUnoSheetModuleObj( xRange ), mxContext, xRange ) ) );
290 : }
291 : else
292 : {
293 0 : throw uno::RuntimeException( sImplementationName + OUString(" not supported" ) );
294 50 : }
295 : }
296 :
297 : uno::Reference< excel::XRange >
298 60 : ScVbaApplication::getActiveCell() throw (uno::RuntimeException, std::exception )
299 : {
300 60 : uno::Reference< sheet::XSpreadsheetView > xView( getCurrentDocument()->getCurrentController(), uno::UNO_QUERY_THROW );
301 120 : uno::Reference< table::XCellRange > xRange( xView->getActiveSheet(), ::uno::UNO_QUERY_THROW);
302 60 : ScTabViewShell* pViewShell = excel::getCurrentBestViewShell(mxContext);
303 60 : if ( !pViewShell )
304 0 : throw uno::RuntimeException("No ViewShell available" );
305 60 : ScViewData& rTabView = pViewShell->GetViewData();
306 :
307 60 : sal_Int32 nCursorX = rTabView.GetCurX();
308 60 : sal_Int32 nCursorY = rTabView.GetCurY();
309 :
310 : // #i117392# excel::getUnoSheetModuleObj() may return null in documents without global VBA mode enabled
311 120 : return new ScVbaRange( excel::getUnoSheetModuleObj( xRange ), mxContext, xRange->getCellRangeByPosition( nCursorX, nCursorY, nCursorX, nCursorY ) );
312 : }
313 :
314 : uno::Any SAL_CALL
315 0 : ScVbaApplication::International( sal_Int32 /*Index*/ ) throw (uno::RuntimeException, std::exception)
316 : {
317 : // complete stub for now
318 : // #TODO flesh out some of the Indices we could handle
319 0 : uno::Any aRet;
320 0 : return aRet;
321 : }
322 :
323 : uno::Any SAL_CALL
324 20 : ScVbaApplication::Workbooks( const uno::Any& aIndex ) throw (uno::RuntimeException, std::exception)
325 : {
326 20 : uno::Reference< XCollection > xWorkBooks( new ScVbaWorkbooks( this, mxContext ) );
327 20 : if ( aIndex.getValueTypeClass() == uno::TypeClass_VOID )
328 : {
329 : // void then somebody did Workbooks.something in vba
330 4 : return uno::Any( xWorkBooks );
331 : }
332 :
333 16 : return uno::Any ( xWorkBooks->Item( aIndex, uno::Any() ) );
334 : }
335 :
336 : uno::Any SAL_CALL
337 254 : ScVbaApplication::Worksheets( const uno::Any& aIndex ) throw (uno::RuntimeException, std::exception)
338 : {
339 254 : uno::Reference< excel::XWorkbook > xWorkbook( getActiveWorkbook(), uno::UNO_SET_THROW );
340 254 : return xWorkbook->Worksheets( aIndex );
341 : }
342 :
343 : uno::Any SAL_CALL
344 0 : ScVbaApplication::WorksheetFunction( ) throw (::com::sun::star::uno::RuntimeException, std::exception)
345 : {
346 0 : return uno::makeAny( uno::Reference< script::XInvocation >( new ScVbaWSFunction( this, mxContext ) ) );
347 : }
348 :
349 : uno::Any SAL_CALL
350 0 : ScVbaApplication::Evaluate( const OUString& Name ) throw (uno::RuntimeException, std::exception)
351 : {
352 : // #TODO Evaluate allows other things to be evaluated, e.g. functions
353 : // I think ( like SIN(3) etc. ) need to investigate that
354 : // named Ranges also? e.g. [MyRange] if so need a list of named ranges
355 0 : uno::Any aVoid;
356 0 : return uno::Any( getActiveWorkbook()->getActiveSheet()->Range( uno::Any( Name ), aVoid ) );
357 : }
358 :
359 : uno::Any
360 0 : ScVbaApplication::Dialogs( const uno::Any &aIndex ) throw (uno::RuntimeException, std::exception)
361 : {
362 0 : uno::Reference< excel::XDialogs > xDialogs( new ScVbaDialogs( uno::Reference< XHelperInterface >( this ), mxContext, getCurrentDocument() ) );
363 0 : if( !aIndex.hasValue() )
364 0 : return uno::Any( xDialogs );
365 0 : return uno::Any( xDialogs->Item( aIndex ) );
366 : }
367 :
368 : uno::Reference< excel::XWindow > SAL_CALL
369 26 : ScVbaApplication::getActiveWindow() throw (uno::RuntimeException, std::exception)
370 : {
371 26 : uno::Reference< frame::XModel > xModel = getCurrentDocument();
372 52 : uno::Reference< frame::XController > xController( xModel->getCurrentController(), uno::UNO_SET_THROW );
373 52 : uno::Reference< XHelperInterface > xParent( getActiveWorkbook(), uno::UNO_QUERY_THROW );
374 26 : uno::Reference< excel::XWindow > xWin( new ScVbaWindow( xParent, mxContext, xModel, xController ) );
375 52 : return xWin;
376 : }
377 :
378 : uno::Any SAL_CALL
379 2 : ScVbaApplication::getCutCopyMode() throw (uno::RuntimeException, std::exception)
380 : {
381 : //# FIXME TODO, implementation
382 2 : uno::Any result;
383 2 : result <<= sal_False;
384 2 : return result;
385 : }
386 :
387 : void SAL_CALL
388 2 : ScVbaApplication::setCutCopyMode( const uno::Any& /* _cutcopymode */ ) throw (uno::RuntimeException, std::exception)
389 : {
390 : //# FIXME TODO, implementation
391 2 : }
392 :
393 : uno::Any SAL_CALL
394 0 : ScVbaApplication::getStatusBar() throw (uno::RuntimeException, std::exception)
395 : {
396 0 : return uno::makeAny( !getDisplayStatusBar() );
397 : }
398 :
399 : void SAL_CALL
400 0 : ScVbaApplication::setStatusBar( const uno::Any& _statusbar ) throw (uno::RuntimeException, std::exception)
401 : {
402 0 : OUString sText;
403 0 : bool bDefault = false;
404 0 : uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_QUERY_THROW );
405 0 : uno::Reference< task::XStatusIndicatorSupplier > xStatusIndicatorSupplier( xModel->getCurrentController(), uno::UNO_QUERY_THROW );
406 0 : uno::Reference< task::XStatusIndicator > xStatusIndicator( xStatusIndicatorSupplier->getStatusIndicator(), uno::UNO_QUERY_THROW );
407 0 : if( _statusbar >>= sText )
408 : {
409 0 : setDisplayStatusBar( sal_True );
410 0 : if ( !sText.isEmpty() )
411 0 : xStatusIndicator->start( sText, 100 );
412 : else
413 0 : xStatusIndicator->end(); // restore normal state for empty text
414 : }
415 0 : else if( _statusbar >>= bDefault )
416 : {
417 0 : if( !bDefault )
418 : {
419 0 : xStatusIndicator->end();
420 0 : setDisplayStatusBar( sal_True );
421 : }
422 : }
423 : else
424 0 : throw uno::RuntimeException("Invalid prarameter. It should be a string or False" );
425 0 : }
426 :
427 : ::sal_Int32 SAL_CALL
428 10 : ScVbaApplication::getCalculation() throw (uno::RuntimeException, std::exception)
429 : {
430 : // TODO: in Excel, this is an application-wide setting
431 10 : uno::Reference<sheet::XCalculatable> xCalc(getCurrentDocument(), uno::UNO_QUERY_THROW);
432 10 : if(xCalc->isAutomaticCalculationEnabled())
433 4 : return excel::XlCalculation::xlCalculationAutomatic;
434 : else
435 6 : return excel::XlCalculation::xlCalculationManual;
436 : }
437 :
438 : void SAL_CALL
439 8 : ScVbaApplication::setCalculation( ::sal_Int32 _calculation ) throw (uno::RuntimeException, std::exception)
440 : {
441 : // TODO: in Excel, this is an application-wide setting
442 8 : uno::Reference< sheet::XCalculatable > xCalc(getCurrentDocument(), uno::UNO_QUERY_THROW);
443 8 : switch(_calculation)
444 : {
445 : case excel::XlCalculation::xlCalculationManual:
446 4 : xCalc->enableAutomaticCalculation(false);
447 4 : break;
448 : case excel::XlCalculation::xlCalculationAutomatic:
449 : case excel::XlCalculation::xlCalculationSemiautomatic:
450 4 : xCalc->enableAutomaticCalculation(sal_True);
451 4 : break;
452 8 : }
453 8 : }
454 :
455 : uno::Any SAL_CALL
456 50 : ScVbaApplication::Windows( const uno::Any& aIndex ) throw (uno::RuntimeException, std::exception)
457 : {
458 50 : uno::Reference< excel::XWindows > xWindows( new ScVbaWindows( this, mxContext ) );
459 50 : if ( aIndex.getValueTypeClass() == uno::TypeClass_VOID )
460 50 : return uno::Any( xWindows );
461 0 : return uno::Any( xWindows->Item( aIndex, uno::Any() ) );
462 : }
463 : void SAL_CALL
464 0 : ScVbaApplication::wait( double time ) throw (uno::RuntimeException, std::exception)
465 : {
466 0 : StarBASIC* pBasic = SfxGetpApp()->GetBasic();
467 0 : SbxArrayRef aArgs = new SbxArray;
468 0 : SbxVariableRef aRef = new SbxVariable;
469 0 : aRef->PutDouble( time );
470 0 : aArgs->Put( aRef, 1 );
471 0 : SbMethod* pMeth = static_cast<SbMethod*>(pBasic->GetRtl()->Find( OUString("WaitUntil"), SbxCLASS_METHOD ));
472 :
473 0 : if ( pMeth )
474 : {
475 0 : pMeth->SetParameters( aArgs );
476 0 : SbxVariableRef refTemp = pMeth;
477 : // forces a broadcast
478 0 : SbxVariableRef pNew = new SbxMethod( *((SbxMethod*)pMeth));
479 0 : }
480 0 : }
481 :
482 : uno::Any SAL_CALL
483 1342 : ScVbaApplication::Range( const uno::Any& Cell1, const uno::Any& Cell2 ) throw (uno::RuntimeException, std::exception)
484 : {
485 1342 : uno::Reference< excel::XRange > xVbRange = ScVbaRange::ApplicationRange( mxContext, Cell1, Cell2 );
486 1338 : return uno::makeAny( xVbRange );
487 : }
488 :
489 : uno::Any SAL_CALL
490 0 : ScVbaApplication::Names( const css::uno::Any& aIndex ) throw ( uno::RuntimeException, std::exception )
491 : {
492 0 : uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_QUERY_THROW );
493 0 : uno::Reference< beans::XPropertySet > xPropertySet( xModel, uno::UNO_QUERY_THROW );
494 0 : uno::Reference< sheet::XNamedRanges > xNamedRanges( xPropertySet->getPropertyValue(
495 0 : OUString( "NamedRanges" ) ), uno::UNO_QUERY_THROW );
496 :
497 0 : css::uno::Reference< excel::XNames > xNames ( new ScVbaNames( this , mxContext , xNamedRanges , xModel ) );
498 0 : if ( aIndex.getValueTypeClass() == uno::TypeClass_VOID )
499 : {
500 0 : return uno::Any( xNames );
501 : }
502 0 : return uno::Any( xNames->Item( aIndex, uno::Any() ) );
503 : }
504 :
505 : uno::Reference< excel::XWorksheet > SAL_CALL
506 160 : ScVbaApplication::getActiveSheet() throw (uno::RuntimeException, std::exception)
507 : {
508 160 : uno::Reference< excel::XWorksheet > result;
509 320 : uno::Reference< excel::XWorkbook > xWorkbook( getActiveWorkbook(), uno::UNO_QUERY );
510 160 : if ( xWorkbook.is() )
511 : {
512 : uno::Reference< excel::XWorksheet > xWorksheet(
513 160 : xWorkbook->getActiveSheet(), uno::UNO_QUERY );
514 160 : if ( xWorksheet.is() )
515 : {
516 160 : result = xWorksheet;
517 160 : }
518 : }
519 :
520 160 : if ( !result.is() )
521 : {
522 : // Fixme - check if this is reasonable/desired behavior
523 0 : throw uno::RuntimeException("No activeSheet available" );
524 : }
525 320 : return result;
526 :
527 : }
528 :
529 : /*******************************************************************************
530 : * In msdn:
531 : * Reference Optional Variant. The destination. Can be a Range
532 : * object, a string that contains a cell reference in R1C1-style notation,
533 : * or a string that contains a Visual Basic procedure name.
534 : * Scroll Optional Variant. True to scrol, False to not scroll through
535 : * the window. The default is False.
536 : * Parser is split to three parts, Range, R1C1 string and procedure name.
537 : * by test excel, it seems Scroll no effect. ???
538 : *******************************************************************************/
539 : void SAL_CALL
540 6 : ScVbaApplication::GoTo( const uno::Any& Reference, const uno::Any& Scroll ) throw (uno::RuntimeException, std::exception)
541 : {
542 : //test Scroll is a boolean
543 6 : bool bScroll = false;
544 : //R1C1-style string or a string of procedure name.
545 :
546 6 : if( Scroll.hasValue() )
547 : {
548 0 : bool aScroll = false;
549 0 : if( Scroll >>= aScroll )
550 : {
551 0 : bScroll = aScroll;
552 : }
553 : else
554 0 : throw uno::RuntimeException("second parameter should be boolean" );
555 : }
556 :
557 6 : OUString sRangeName;
558 6 : if( Reference >>= sRangeName )
559 : {
560 4 : uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_QUERY_THROW );
561 : uno::Reference< sheet::XSpreadsheetView > xSpreadsheet(
562 8 : xModel->getCurrentController(), uno::UNO_QUERY_THROW );
563 8 : uno::Reference< sheet::XSpreadsheet > xDoc = xSpreadsheet->getActiveSheet();
564 :
565 4 : ScTabViewShell* pShell = excel::getCurrentBestViewShell( mxContext );
566 4 : ScGridWindow* gridWindow = static_cast<ScGridWindow*>(pShell->GetWindow());
567 : try
568 : {
569 : uno::Reference< excel::XRange > xVbaSheetRange = ScVbaRange::getRangeObjectForName(
570 4 : mxContext, sRangeName, excel::getDocShell( xModel ), formula::FormulaGrammar::CONV_XL_R1C1 );
571 :
572 4 : if( bScroll )
573 : {
574 0 : xVbaSheetRange->Select();
575 0 : uno::Reference< excel::XWindow > xWindow = getActiveWindow();
576 0 : ScSplitPos eWhich = pShell->GetViewData().GetActivePart();
577 0 : sal_Int32 nValueX = pShell->GetViewData().GetPosX(WhichH(eWhich));
578 0 : sal_Int32 nValueY = pShell->GetViewData().GetPosY(WhichV(eWhich));
579 0 : xWindow->SmallScroll( uno::makeAny( (sal_Int16)(xVbaSheetRange->getRow() - 1) ),
580 : uno::makeAny( (sal_Int16)nValueY ),
581 0 : uno::makeAny( (sal_Int16)(xVbaSheetRange->getColumn() - 1) ),
582 0 : uno::makeAny( (sal_Int16)nValueX ) );
583 0 : gridWindow->GrabFocus();
584 : }
585 : else
586 : {
587 4 : xVbaSheetRange->Select();
588 4 : gridWindow->GrabFocus();
589 4 : }
590 : }
591 0 : catch (const uno::RuntimeException&)
592 : {
593 : //maybe this should be a procedure name
594 : //TODO for procedure name
595 : //browse::XBrowseNodeFactory is a singlton. OUString( "/singletons/com.sun.star.script.browse.theBrowseNodeFactory")
596 : //and the createView( browse::BrowseNodeFactoryViewTypes::MACROSELECTOR ) to get a root browse::XBrowseNode.
597 : //for query XInvocation interface.
598 : //but how to directly get the XInvocation?
599 0 : throw uno::RuntimeException("invalid reference for range name, it should be procedure name" );
600 : }
601 8 : return;
602 : }
603 4 : uno::Reference< excel::XRange > xRange;
604 2 : if( Reference >>= xRange )
605 : {
606 2 : uno::Reference< excel::XRange > xVbaRange( Reference, uno::UNO_QUERY );
607 2 : ScTabViewShell* pShell = excel::getCurrentBestViewShell( mxContext );
608 2 : ScGridWindow* gridWindow = static_cast<ScGridWindow*>(pShell->GetWindow());
609 2 : if ( xVbaRange.is() )
610 : {
611 : //TODO bScroll should be using, In this time, it doesenot have effection
612 2 : if( bScroll )
613 : {
614 0 : xVbaRange->Select();
615 0 : uno::Reference< excel::XWindow > xWindow = getActiveWindow();
616 0 : ScSplitPos eWhich = pShell->GetViewData().GetActivePart();
617 0 : sal_Int32 nValueX = pShell->GetViewData().GetPosX(WhichH(eWhich));
618 0 : sal_Int32 nValueY = pShell->GetViewData().GetPosY(WhichV(eWhich));
619 0 : xWindow->SmallScroll( uno::makeAny( (sal_Int16)(xVbaRange->getRow() - 1) ),
620 : uno::makeAny( (sal_Int16)nValueY ),
621 0 : uno::makeAny( (sal_Int16)(xVbaRange->getColumn() - 1) ),
622 0 : uno::makeAny( (sal_Int16)nValueX ) );
623 0 : gridWindow->GrabFocus();
624 : }
625 : else
626 : {
627 2 : xVbaRange->Select();
628 2 : gridWindow->GrabFocus();
629 : }
630 : }
631 2 : return;
632 : }
633 0 : throw uno::RuntimeException("invalid reference or name" );
634 : }
635 :
636 : sal_Int32 SAL_CALL
637 0 : ScVbaApplication::getCursor() throw (uno::RuntimeException, std::exception)
638 : {
639 0 : sal_Int32 nPointerStyle = getPointerStyle(getCurrentDocument());
640 :
641 0 : switch( nPointerStyle )
642 : {
643 : case POINTER_ARROW:
644 0 : return excel::XlMousePointer::xlNorthwestArrow;
645 : case POINTER_NULL:
646 0 : return excel::XlMousePointer::xlDefault;
647 : case POINTER_WAIT:
648 0 : return excel::XlMousePointer::xlWait;
649 : case POINTER_TEXT:
650 0 : return excel::XlMousePointer::xlIBeam;
651 : default:
652 0 : return excel::XlMousePointer::xlDefault;
653 : }
654 : }
655 :
656 : void SAL_CALL
657 0 : ScVbaApplication::setCursor( sal_Int32 _cursor ) throw (uno::RuntimeException, std::exception)
658 : {
659 : try
660 : {
661 0 : uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_QUERY_THROW );
662 0 : switch( _cursor )
663 : {
664 : case excel::XlMousePointer::xlNorthwestArrow:
665 : {
666 0 : const Pointer& rPointer( POINTER_ARROW );
667 0 : setCursorHelper( xModel, rPointer, false );
668 0 : break;
669 : }
670 : case excel::XlMousePointer::xlWait:
671 : case excel::XlMousePointer::xlIBeam:
672 : {
673 0 : const Pointer& rPointer( static_cast< PointerStyle >( _cursor ) );
674 : //It will set the edit window, toobar and statusbar's mouse pointer.
675 0 : setCursorHelper( xModel, rPointer, true );
676 0 : break;
677 : }
678 : case excel::XlMousePointer::xlDefault:
679 : {
680 0 : const Pointer& rPointer( POINTER_NULL );
681 0 : setCursorHelper( xModel, rPointer, false );
682 0 : break;
683 : }
684 : default:
685 0 : throw uno::RuntimeException("Unknown value for Cursor pointer" );
686 : // TODO: isn't this a flaw in the API? It should be allowed to throw an
687 : // IllegalArgumentException, or so
688 0 : }
689 : }
690 0 : catch (const uno::Exception&)
691 : {
692 : DBG_UNHANDLED_EXCEPTION();
693 : }
694 0 : }
695 :
696 : // #TODO perhaps we should switch the return type depending of the filter
697 : // type, e.g. return Calc for Calc and Excel if its an imported doc
698 : OUString SAL_CALL
699 8 : ScVbaApplication::getName() throw (uno::RuntimeException, std::exception)
700 : {
701 8 : static OUString appName("Microsoft Excel" );
702 8 : return appName;
703 : }
704 :
705 : // #TODO #FIXME get/setDisplayAlerts are just stub impl
706 : // here just the status of the switch is set
707 : // the function that throws an error message needs to
708 : // evaluate this switch in order to know whether it has to disable the
709 : // error message thrown by OpenOffice
710 :
711 : void SAL_CALL
712 6 : ScVbaApplication::setDisplayAlerts(sal_Bool displayAlerts) throw (uno::RuntimeException, std::exception)
713 : {
714 6 : mrAppSettings.mbDisplayAlerts = displayAlerts;
715 6 : }
716 :
717 : sal_Bool SAL_CALL
718 0 : ScVbaApplication::getDisplayAlerts() throw (uno::RuntimeException, std::exception)
719 : {
720 0 : return mrAppSettings.mbDisplayAlerts;
721 : }
722 :
723 : void SAL_CALL
724 88 : ScVbaApplication::setEnableEvents(sal_Bool bEnable) throw (uno::RuntimeException, std::exception)
725 : {
726 88 : mrAppSettings.mbEnableEvents = bEnable;
727 88 : }
728 :
729 : sal_Bool SAL_CALL
730 0 : ScVbaApplication::getEnableEvents() throw (uno::RuntimeException, std::exception)
731 : {
732 0 : return mrAppSettings.mbEnableEvents;
733 : }
734 :
735 : void SAL_CALL
736 0 : ScVbaApplication::setEnableCancelKey(sal_Bool bEnable) throw (uno::RuntimeException, std::exception)
737 : {
738 : // Stub, does nothing
739 0 : mrAppSettings.mbEnableCancelKey = bEnable;
740 0 : }
741 :
742 : sal_Bool SAL_CALL
743 0 : ScVbaApplication::getEnableCancelKey() throw (uno::RuntimeException, std::exception)
744 : {
745 0 : return mrAppSettings.mbEnableCancelKey;
746 : }
747 :
748 : sal_Bool SAL_CALL
749 0 : ScVbaApplication::getDisplayFullScreen() throw (uno::RuntimeException, std::exception)
750 : {
751 0 : SfxViewShell* pShell = excel::getCurrentBestViewShell( mxContext );
752 0 : if ( pShell )
753 0 : return ScViewUtil::IsFullScreen( *pShell );
754 0 : return sal_False;
755 : }
756 :
757 : void SAL_CALL
758 0 : ScVbaApplication::setDisplayFullScreen( sal_Bool bSet ) throw (uno::RuntimeException, std::exception)
759 : {
760 : // #FIXME calling ScViewUtil::SetFullScreen( *pShell, bSet );
761 : // directly results in a strange crash, using dispatch instead
762 0 : if ( bSet != getDisplayFullScreen() )
763 0 : dispatchRequests( getCurrentDocument(), OUString(".uno:FullScreen") );
764 0 : }
765 :
766 : sal_Bool SAL_CALL
767 0 : ScVbaApplication::getDisplayScrollBars() throw (uno::RuntimeException, std::exception)
768 : {
769 0 : ScTabViewShell* pShell = excel::getCurrentBestViewShell( mxContext );
770 0 : if ( pShell )
771 : {
772 0 : return ( pShell->GetViewData().IsHScrollMode() && pShell->GetViewData().IsVScrollMode() );
773 : }
774 0 : return true;
775 : }
776 :
777 : void SAL_CALL
778 0 : ScVbaApplication::setDisplayScrollBars( sal_Bool bSet ) throw (uno::RuntimeException, std::exception)
779 : {
780 : // use uno here as it does all he repainting etc. magic
781 0 : uno::Reference< sheet::XSpreadsheetView > xView( getCurrentDocument()->getCurrentController(), uno::UNO_QUERY_THROW );
782 0 : uno::Reference< beans::XPropertySet > xProps( xView, uno::UNO_QUERY );
783 0 : xProps->setPropertyValue("HasVerticalScrollBar", uno::makeAny( bSet ) );
784 0 : xProps->setPropertyValue("HasHorizontalScrollBar", uno::makeAny( bSet ) );
785 0 : }
786 :
787 : sal_Bool SAL_CALL
788 0 : ScVbaApplication::getDisplayExcel4Menus() throw (css::uno::RuntimeException, std::exception)
789 : {
790 0 : return mrAppSettings.mbExcel4Menus;
791 : }
792 :
793 : void SAL_CALL
794 0 : ScVbaApplication::setDisplayExcel4Menus( sal_Bool bSet ) throw (css::uno::RuntimeException, std::exception)
795 : {
796 0 : mrAppSettings.mbExcel4Menus = bSet;
797 0 : }
798 :
799 : sal_Bool SAL_CALL
800 0 : ScVbaApplication::getDisplayNoteIndicator() throw (css::uno::RuntimeException, std::exception)
801 : {
802 0 : return mrAppSettings.mbDisplayNoteIndicator;
803 : }
804 :
805 : void SAL_CALL
806 0 : ScVbaApplication::setDisplayNoteIndicator( sal_Bool bSet ) throw (css::uno::RuntimeException, std::exception)
807 : {
808 0 : mrAppSettings.mbDisplayNoteIndicator = bSet;
809 0 : }
810 :
811 : sal_Bool SAL_CALL
812 0 : ScVbaApplication::getShowWindowsInTaskbar() throw (css::uno::RuntimeException, std::exception)
813 : {
814 0 : return mrAppSettings.mbShowWindowsInTaskbar;
815 : }
816 :
817 : void SAL_CALL
818 0 : ScVbaApplication::setShowWindowsInTaskbar( sal_Bool bSet ) throw (css::uno::RuntimeException, std::exception)
819 : {
820 0 : mrAppSettings.mbShowWindowsInTaskbar = bSet;
821 0 : }
822 :
823 : sal_Bool SAL_CALL
824 0 : ScVbaApplication::getIteration() throw (css::uno::RuntimeException, std::exception)
825 : {
826 0 : return SC_MOD()->GetDocOptions().IsIter();
827 : }
828 :
829 : void SAL_CALL
830 0 : ScVbaApplication::setIteration( sal_Bool bSet ) throw (css::uno::RuntimeException, std::exception)
831 : {
832 : uno::Reference< lang::XMultiComponentFactory > xSMgr(
833 0 : mxContext->getServiceManager(), uno::UNO_QUERY_THROW );
834 :
835 : uno::Reference< frame::XDesktop > xDesktop
836 0 : (xSMgr->createInstanceWithContext( "com.sun.star.frame.Desktop" , mxContext), uno::UNO_QUERY_THROW );
837 0 : uno::Reference< container::XEnumeration > xComponents = xDesktop->getComponents()->createEnumeration();
838 0 : while ( xComponents->hasMoreElements() )
839 : {
840 0 : uno::Reference< lang::XServiceInfo > xServiceInfo( xComponents->nextElement(), uno::UNO_QUERY );
841 0 : if ( xServiceInfo.is() && xServiceInfo->supportsService( "com.sun.star.sheet.SpreadsheetDocument" ) )
842 : {
843 0 : uno::Reference< beans::XPropertySet > xProps( xServiceInfo, uno::UNO_QUERY );
844 0 : if ( xProps.is() )
845 0 : xProps->setPropertyValue( SC_UNO_ITERENABLED, uno::Any( bSet ) );
846 : }
847 0 : }
848 0 : ScDocOptions aOpts( SC_MOD()->GetDocOptions() );
849 0 : aOpts.SetIter( bSet );
850 0 : SC_MOD()->SetDocOptions( aOpts );
851 0 : }
852 :
853 : void SAL_CALL
854 4 : ScVbaApplication::Calculate() throw( script::BasicErrorException , uno::RuntimeException, std::exception )
855 : {
856 4 : uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_QUERY_THROW );
857 8 : uno::Reference< sheet::XCalculatable > xCalculatable( getCurrentDocument(), uno::UNO_QUERY_THROW );
858 8 : xCalculatable->calculateAll();
859 4 : }
860 :
861 12 : static uno::Reference< util::XPathSettings > lcl_getPathSettingsService( const uno::Reference< uno::XComponentContext >& xContext ) throw ( uno::RuntimeException )
862 : {
863 12 : static uno::Reference< util::XPathSettings > xPathSettings;
864 12 : if ( !xPathSettings.is() )
865 : {
866 2 : xPathSettings.set( util::PathSettings::create( xContext ) );
867 : }
868 12 : return xPathSettings;
869 : }
870 :
871 12 : OUString ScVbaApplication::getOfficePath( const OUString& _sPathType ) throw (uno::RuntimeException)
872 : {
873 12 : OUString sRetPath;
874 24 : uno::Reference< util::XPathSettings > xProps = lcl_getPathSettingsService( mxContext );
875 : try
876 : {
877 12 : OUString sUrl;
878 12 : xProps->getPropertyValue( _sPathType ) >>= sUrl;
879 :
880 : // if it's a list of paths then use the last one
881 12 : sal_Int32 nIndex = sUrl.lastIndexOf( ';' ) ;
882 12 : if ( nIndex > 0 )
883 8 : sUrl = sUrl.copy( nIndex + 1 );
884 12 : ::osl::File::getSystemPathFromFileURL( sUrl, sRetPath );
885 : }
886 0 : catch (const uno::Exception&)
887 : {
888 0 : DebugHelper::runtimeexception(SbERR_METHOD_FAILED, OUString());
889 : }
890 24 : return sRetPath;
891 : }
892 :
893 : void SAL_CALL
894 0 : ScVbaApplication::setDefaultFilePath( const OUString& DefaultFilePath ) throw (uno::RuntimeException, std::exception)
895 : {
896 0 : uno::Reference< util::XPathSettings > xProps = lcl_getPathSettingsService( mxContext );
897 0 : OUString aURL;
898 0 : osl::FileBase::getFileURLFromSystemPath( DefaultFilePath, aURL );
899 0 : xProps->setWork( aURL );
900 0 : }
901 :
902 : OUString SAL_CALL
903 4 : ScVbaApplication::getDefaultFilePath() throw (uno::RuntimeException, std::exception)
904 : {
905 4 : return getOfficePath( OUString("Work"));
906 : }
907 :
908 : OUString SAL_CALL
909 4 : ScVbaApplication::getLibraryPath() throw (uno::RuntimeException, std::exception)
910 : {
911 4 : return getOfficePath( OUString("Basic"));
912 : }
913 :
914 : OUString SAL_CALL
915 4 : ScVbaApplication::getTemplatesPath() throw (uno::RuntimeException, std::exception)
916 : {
917 4 : return getOfficePath( OUString("Template"));
918 : }
919 :
920 : OUString SAL_CALL
921 6 : ScVbaApplication::getPathSeparator() throw (uno::RuntimeException, std::exception)
922 : {
923 6 : return OUString( (sal_Unicode) SAL_PATHDELIMITER );
924 : }
925 :
926 : // Helpers for Intersect and Union
927 :
928 : namespace {
929 :
930 : typedef ::std::list< ScRange > ListOfScRange;
931 :
932 : /** Appends all ranges of a VBA Range object in the passed Any to the list of ranges. */
933 1080 : void lclAddToListOfScRange( ListOfScRange& rList, const uno::Any& rArg )
934 : throw (script::BasicErrorException, uno::RuntimeException)
935 : {
936 1080 : if( rArg.hasValue() )
937 : {
938 74 : uno::Reference< excel::XRange > xRange( rArg, uno::UNO_QUERY_THROW );
939 148 : uno::Reference< XCollection > xCol( xRange->Areas( uno::Any() ), uno::UNO_QUERY_THROW );
940 200 : for( sal_Int32 nIdx = 1, nCount = xCol->getCount(); nIdx <= nCount; ++nIdx )
941 : {
942 126 : uno::Reference< excel::XRange > xAreaRange( xCol->Item( uno::Any( nIdx ), uno::Any() ), uno::UNO_QUERY_THROW );
943 252 : uno::Reference< sheet::XCellRangeAddressable > xAddressable( xAreaRange->getCellRange(), uno::UNO_QUERY_THROW );
944 126 : ScRange aScRange;
945 126 : ScUnoConversion::FillScRange( aScRange, xAddressable->getRangeAddress() );
946 126 : rList.push_back( aScRange );
947 200 : }
948 : }
949 1080 : }
950 :
951 : /** Returns true, if the passed ranges can be expressed by a single range. The
952 : new range will be contained in r1 then, the range r2 can be removed. */
953 130 : bool lclTryJoin( ScRange& r1, const ScRange& r2 )
954 : {
955 : // 1) r2 is completely inside r1
956 130 : if( r1.In( r2 ) )
957 6 : return true;
958 :
959 : // 2) r1 is completely inside r2
960 124 : if( r2.In( r1 ) )
961 : {
962 4 : r1 = r2;
963 4 : return true;
964 : }
965 :
966 120 : SCCOL n1L = r1.aStart.Col();
967 120 : SCCOL n1R = r1.aEnd.Col();
968 120 : SCROW n1T = r1.aStart.Row();
969 120 : SCROW n1B = r1.aEnd.Row();
970 120 : SCCOL n2L = r2.aStart.Col();
971 120 : SCCOL n2R = r2.aEnd.Col();
972 120 : SCROW n2T = r2.aStart.Row();
973 120 : SCROW n2B = r2.aEnd.Row();
974 :
975 : // 3) r1 and r2 have equal upper and lower border
976 120 : if( (n1T == n2T) && (n1B == n2B) )
977 : {
978 : // check that r1 overlaps or touches r2
979 46 : if( ((n1L < n2L) && (n2L - 1 <= n1R)) || ((n2L < n1L) && (n1L - 1 <= n2R)) )
980 : {
981 30 : r1.aStart.SetCol( ::std::min( n1L, n2L ) );
982 30 : r1.aEnd.SetCol( ::std::max( n1R, n2R ) );
983 30 : return true;
984 : }
985 16 : return false;
986 : }
987 :
988 : // 4) r1 and r2 have equal left and right border
989 74 : if( (n1L == n2L) && (n1R == n2R) )
990 : {
991 : // check that r1 overlaps or touches r2
992 0 : if( ((n1T < n2T) && (n2T + 1 <= n1B)) || ((n2T < n1T) && (n1T + 1 <= n2B)) )
993 : {
994 0 : r1.aStart.SetRow( ::std::min( n1T, n2T ) );
995 0 : r1.aEnd.SetRow( ::std::max( n1B, n2B ) );
996 0 : return true;
997 : }
998 0 : return false;
999 : }
1000 :
1001 : // 5) cannot join these ranges
1002 74 : return false;
1003 : }
1004 :
1005 : /** Strips out ranges that are contained by other ranges, joins ranges that can be joined
1006 : together (aligned borders, e.g. A4:D10 and B4:E10 would be combined to A4:E10. */
1007 96 : void lclJoinRanges( ListOfScRange& rList )
1008 : {
1009 96 : ListOfScRange::iterator aOuterIt = rList.begin();
1010 352 : while( aOuterIt != rList.end() )
1011 : {
1012 160 : bool bAnyErased = false; // true = any range erased from rList
1013 160 : ListOfScRange::iterator aInnerIt = rList.begin();
1014 610 : while( aInnerIt != rList.end() )
1015 : {
1016 290 : bool bInnerErased = false; // true = aInnerIt erased from rList
1017 : // do not compare a range with itself
1018 290 : if( (aOuterIt != aInnerIt) && lclTryJoin( *aOuterIt, *aInnerIt ) )
1019 : {
1020 : // aOuterIt points to joined range, aInnerIt will be removed
1021 40 : aInnerIt = rList.erase( aInnerIt );
1022 40 : bInnerErased = bAnyErased = true;
1023 : }
1024 : /* If aInnerIt has been erased from rList, it already points to
1025 : the next element (return value of list::erase()). */
1026 290 : if( !bInnerErased )
1027 250 : ++aInnerIt;
1028 : }
1029 : // if any range has been erased, repeat outer loop with the same range
1030 160 : if( !bAnyErased )
1031 128 : ++aOuterIt;
1032 : }
1033 96 : }
1034 :
1035 : /** Intersects the passed list with all ranges of a VBA Range object in the passed Any. */
1036 812 : void lclIntersectRanges( ListOfScRange& rList, const uno::Any& rArg )
1037 : throw (script::BasicErrorException, uno::RuntimeException)
1038 : {
1039 : // extract the ranges from the passed argument, will throw on invalid data
1040 812 : ListOfScRange aList2;
1041 812 : lclAddToListOfScRange( aList2, rArg );
1042 : // do nothing, if the passed list is already empty
1043 812 : if( !rList.empty() && !aList2.empty() )
1044 : {
1045 : // save original list in a local
1046 30 : ListOfScRange aList1;
1047 30 : aList1.swap( rList );
1048 : // join ranges from passed argument
1049 30 : lclJoinRanges( aList2 );
1050 : // calculate intersection of the ranges in both lists
1051 74 : for( ListOfScRange::const_iterator aOuterIt = aList1.begin(), aOuterEnd = aList1.end(); aOuterIt != aOuterEnd; ++aOuterIt )
1052 : {
1053 90 : for( ListOfScRange::const_iterator aInnerIt = aList2.begin(), aInnerEnd = aList2.end(); aInnerIt != aInnerEnd; ++aInnerIt )
1054 : {
1055 46 : if( aOuterIt->Intersects( *aInnerIt ) )
1056 : {
1057 : ScRange aIsectRange(
1058 84 : std::max( aOuterIt->aStart.Col(), aInnerIt->aStart.Col() ),
1059 84 : std::max( aOuterIt->aStart.Row(), aInnerIt->aStart.Row() ),
1060 84 : std::max( aOuterIt->aStart.Tab(), aInnerIt->aStart.Tab() ),
1061 84 : std::min( aOuterIt->aEnd.Col(), aInnerIt->aEnd.Col() ),
1062 84 : std::min( aOuterIt->aEnd.Row(), aInnerIt->aEnd.Row() ),
1063 294 : std::min( aOuterIt->aEnd.Tab(), aInnerIt->aEnd.Tab() ) );
1064 42 : rList.push_back( aIsectRange );
1065 : }
1066 : }
1067 : }
1068 : // again, join the result ranges
1069 30 : lclJoinRanges( rList );
1070 812 : }
1071 812 : }
1072 :
1073 : /** Creates a VBA Range object from the passed list of ranges. */
1074 36 : uno::Reference< excel::XRange > lclCreateVbaRange(
1075 : const uno::Reference< uno::XComponentContext >& rxContext,
1076 : const uno::Reference< frame::XModel >& rxModel,
1077 : const ListOfScRange& rList ) throw (uno::RuntimeException)
1078 : {
1079 36 : ScDocShell* pDocShell = excel::getDocShell( rxModel );
1080 36 : if( !pDocShell ) throw uno::RuntimeException();
1081 :
1082 36 : ScRangeList aCellRanges;
1083 88 : for( ListOfScRange::const_iterator aIt = rList.begin(), aEnd = rList.end(); aIt != aEnd; ++aIt )
1084 52 : aCellRanges.Append( *aIt );
1085 :
1086 36 : if( aCellRanges.size() == 1 )
1087 : {
1088 24 : uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pDocShell, *aCellRanges.front() ) );
1089 24 : return new ScVbaRange( excel::getUnoSheetModuleObj( xRange ), rxContext, xRange );
1090 : }
1091 12 : if( aCellRanges.size() > 1 )
1092 : {
1093 12 : uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pDocShell, aCellRanges ) );
1094 12 : return new ScVbaRange( excel::getUnoSheetModuleObj( xRanges ), rxContext, xRanges );
1095 : }
1096 0 : return 0;
1097 : }
1098 :
1099 : } // namespace
1100 :
1101 28 : uno::Reference< excel::XRange > SAL_CALL ScVbaApplication::Intersect(
1102 : const uno::Reference< excel::XRange >& rArg1, const uno::Reference< excel::XRange >& rArg2,
1103 : const uno::Any& rArg3, const uno::Any& rArg4, const uno::Any& rArg5, const uno::Any& rArg6,
1104 : const uno::Any& rArg7, const uno::Any& rArg8, const uno::Any& rArg9, const uno::Any& rArg10,
1105 : const uno::Any& rArg11, const uno::Any& rArg12, const uno::Any& rArg13, const uno::Any& rArg14,
1106 : const uno::Any& rArg15, const uno::Any& rArg16, const uno::Any& rArg17, const uno::Any& rArg18,
1107 : const uno::Any& rArg19, const uno::Any& rArg20, const uno::Any& rArg21, const uno::Any& rArg22,
1108 : const uno::Any& rArg23, const uno::Any& rArg24, const uno::Any& rArg25, const uno::Any& rArg26,
1109 : const uno::Any& rArg27, const uno::Any& rArg28, const uno::Any& rArg29, const uno::Any& rArg30 )
1110 : throw (script::BasicErrorException, uno::RuntimeException, std::exception)
1111 : {
1112 28 : if( !rArg1.is() || !rArg2.is() )
1113 0 : DebugHelper::basicexception( SbERR_BAD_PARAMETER, OUString() );
1114 :
1115 : // initialize the result list with 1st parameter, join its ranges together
1116 28 : ListOfScRange aList;
1117 28 : lclAddToListOfScRange( aList, uno::Any( rArg1 ) );
1118 28 : lclJoinRanges( aList );
1119 :
1120 : // process all other parameters, this updates the list with intersection
1121 28 : lclIntersectRanges( aList, uno::Any( rArg2 ) );
1122 28 : lclIntersectRanges( aList, rArg3 );
1123 28 : lclIntersectRanges( aList, rArg4 );
1124 28 : lclIntersectRanges( aList, rArg5 );
1125 28 : lclIntersectRanges( aList, rArg6 );
1126 28 : lclIntersectRanges( aList, rArg7 );
1127 28 : lclIntersectRanges( aList, rArg8 );
1128 28 : lclIntersectRanges( aList, rArg9 );
1129 28 : lclIntersectRanges( aList, rArg10 );
1130 28 : lclIntersectRanges( aList, rArg11 );
1131 28 : lclIntersectRanges( aList, rArg12 );
1132 28 : lclIntersectRanges( aList, rArg13 );
1133 28 : lclIntersectRanges( aList, rArg14 );
1134 28 : lclIntersectRanges( aList, rArg15 );
1135 28 : lclIntersectRanges( aList, rArg16 );
1136 28 : lclIntersectRanges( aList, rArg17 );
1137 28 : lclIntersectRanges( aList, rArg18 );
1138 28 : lclIntersectRanges( aList, rArg19 );
1139 28 : lclIntersectRanges( aList, rArg20 );
1140 28 : lclIntersectRanges( aList, rArg21 );
1141 28 : lclIntersectRanges( aList, rArg22 );
1142 28 : lclIntersectRanges( aList, rArg23 );
1143 28 : lclIntersectRanges( aList, rArg24 );
1144 28 : lclIntersectRanges( aList, rArg25 );
1145 28 : lclIntersectRanges( aList, rArg26 );
1146 28 : lclIntersectRanges( aList, rArg27 );
1147 28 : lclIntersectRanges( aList, rArg28 );
1148 28 : lclIntersectRanges( aList, rArg29 );
1149 28 : lclIntersectRanges( aList, rArg30 );
1150 :
1151 : // create the VBA Range object
1152 28 : return lclCreateVbaRange( mxContext, getCurrentDocument(), aList );
1153 : }
1154 :
1155 8 : uno::Reference< excel::XRange > SAL_CALL ScVbaApplication::Union(
1156 : const uno::Reference< excel::XRange >& rArg1, const uno::Reference< excel::XRange >& rArg2,
1157 : const uno::Any& rArg3, const uno::Any& rArg4, const uno::Any& rArg5, const uno::Any& rArg6,
1158 : const uno::Any& rArg7, const uno::Any& rArg8, const uno::Any& rArg9, const uno::Any& rArg10,
1159 : const uno::Any& rArg11, const uno::Any& rArg12, const uno::Any& rArg13, const uno::Any& rArg14,
1160 : const uno::Any& rArg15, const uno::Any& rArg16, const uno::Any& rArg17, const uno::Any& rArg18,
1161 : const uno::Any& rArg19, const uno::Any& rArg20, const uno::Any& rArg21, const uno::Any& rArg22,
1162 : const uno::Any& rArg23, const uno::Any& rArg24, const uno::Any& rArg25, const uno::Any& rArg26,
1163 : const uno::Any& rArg27, const uno::Any& rArg28, const uno::Any& rArg29, const uno::Any& rArg30 )
1164 : throw (script::BasicErrorException, uno::RuntimeException, std::exception)
1165 : {
1166 8 : if( !rArg1.is() || !rArg2.is() )
1167 0 : DebugHelper::basicexception( SbERR_BAD_PARAMETER, OUString() );
1168 :
1169 8 : ListOfScRange aList;
1170 8 : lclAddToListOfScRange( aList, uno::Any( rArg1 ) );
1171 8 : lclAddToListOfScRange( aList, uno::Any( rArg2 ) );
1172 8 : lclAddToListOfScRange( aList, rArg3 );
1173 8 : lclAddToListOfScRange( aList, rArg4 );
1174 8 : lclAddToListOfScRange( aList, rArg5 );
1175 8 : lclAddToListOfScRange( aList, rArg6 );
1176 8 : lclAddToListOfScRange( aList, rArg7 );
1177 8 : lclAddToListOfScRange( aList, rArg8 );
1178 8 : lclAddToListOfScRange( aList, rArg9 );
1179 8 : lclAddToListOfScRange( aList, rArg10 );
1180 8 : lclAddToListOfScRange( aList, rArg11 );
1181 8 : lclAddToListOfScRange( aList, rArg12 );
1182 8 : lclAddToListOfScRange( aList, rArg13 );
1183 8 : lclAddToListOfScRange( aList, rArg14 );
1184 8 : lclAddToListOfScRange( aList, rArg15 );
1185 8 : lclAddToListOfScRange( aList, rArg16 );
1186 8 : lclAddToListOfScRange( aList, rArg17 );
1187 8 : lclAddToListOfScRange( aList, rArg18 );
1188 8 : lclAddToListOfScRange( aList, rArg19 );
1189 8 : lclAddToListOfScRange( aList, rArg20 );
1190 8 : lclAddToListOfScRange( aList, rArg21 );
1191 8 : lclAddToListOfScRange( aList, rArg22 );
1192 8 : lclAddToListOfScRange( aList, rArg23 );
1193 8 : lclAddToListOfScRange( aList, rArg24 );
1194 8 : lclAddToListOfScRange( aList, rArg25 );
1195 8 : lclAddToListOfScRange( aList, rArg26 );
1196 8 : lclAddToListOfScRange( aList, rArg27 );
1197 8 : lclAddToListOfScRange( aList, rArg28 );
1198 8 : lclAddToListOfScRange( aList, rArg29 );
1199 8 : lclAddToListOfScRange( aList, rArg30 );
1200 :
1201 : // simply join together all ranges as much as possible, strip out covered ranges etc.
1202 8 : lclJoinRanges( aList );
1203 :
1204 : // create the VBA Range object
1205 8 : return lclCreateVbaRange( mxContext, getCurrentDocument(), aList );
1206 : }
1207 :
1208 : double
1209 0 : ScVbaApplication::InchesToPoints( double Inches ) throw (uno::RuntimeException, std::exception )
1210 : {
1211 0 : double result = ( Inches * 72.0 );
1212 0 : return result;
1213 : }
1214 :
1215 : void
1216 0 : ScVbaApplication::Volatile( const uno::Any& aVolatile ) throw ( uno::RuntimeException, std::exception )
1217 : {
1218 0 : bool bVolatile = true;
1219 0 : aVolatile >>= bVolatile;
1220 0 : SbMethod* pMeth = StarBASIC::GetActiveMethod();
1221 0 : if ( pMeth )
1222 : {
1223 : OSL_TRACE("ScVbaApplication::Volatile() In method ->%s<-", OUStringToOString( pMeth->GetName(), RTL_TEXTENCODING_UTF8 ).getStr() );
1224 0 : uno::Reference< frame::XModel > xModel( getCurrentDocument() );
1225 0 : ScDocument& rDoc = excel::getDocShell( xModel )->GetDocument();
1226 0 : rDoc.GetMacroManager()->SetUserFuncVolatile( pMeth->GetName(), bVolatile);
1227 : }
1228 :
1229 : // this is bound to break when loading the document
1230 0 : return;
1231 : }
1232 :
1233 : sal_Bool SAL_CALL
1234 0 : ScVbaApplication::getDisplayFormulaBar()
1235 : throw (css::uno::RuntimeException, std::exception)
1236 : {
1237 0 : bool bRes = false;
1238 0 : ScTabViewShell* pViewShell = excel::getCurrentBestViewShell( mxContext );
1239 0 : if ( pViewShell )
1240 : {
1241 0 : SfxBoolItem sfxFormBar( FID_TOGGLEINPUTLINE);
1242 0 : SfxAllItemSet reqList( SfxGetpApp()->GetPool() );
1243 0 : reqList.Put( sfxFormBar );
1244 :
1245 0 : pViewShell->GetState( reqList );
1246 0 : const SfxPoolItem *pItem=0;
1247 0 : if ( reqList.GetItemState( FID_TOGGLEINPUTLINE, false, &pItem ) == SfxItemState::SET )
1248 0 : bRes = static_cast<const SfxBoolItem*>(pItem)->GetValue();
1249 : }
1250 0 : return bRes;
1251 : }
1252 :
1253 : void SAL_CALL
1254 0 : ScVbaApplication::setDisplayFormulaBar( sal_Bool _displayformulabar )
1255 : throw(css::uno::RuntimeException, std::exception)
1256 : {
1257 0 : ScTabViewShell* pViewShell = excel::getCurrentBestViewShell( mxContext );
1258 0 : if ( pViewShell && ( _displayformulabar != getDisplayFormulaBar() ) )
1259 : {
1260 0 : SfxBoolItem sfxFormBar( FID_TOGGLEINPUTLINE, _displayformulabar);
1261 0 : SfxAllItemSet reqList( SfxGetpApp()->GetPool() );
1262 0 : SfxRequest aReq( FID_TOGGLEINPUTLINE, SfxCallMode::SLOT, reqList );
1263 0 : pViewShell->Execute( aReq );
1264 : }
1265 0 : }
1266 :
1267 : uno::Any SAL_CALL
1268 0 : ScVbaApplication::Caller( const uno::Any& /*aIndex*/ ) throw ( uno::RuntimeException, std::exception )
1269 : {
1270 0 : StarBASIC* pBasic = SfxGetpApp()->GetBasic();
1271 0 : SbMethod* pMeth = static_cast<SbMethod*>(pBasic->GetRtl()->Find( OUString("FuncCaller"), SbxCLASS_METHOD ));
1272 0 : uno::Any aRet;
1273 0 : if ( pMeth )
1274 : {
1275 0 : SbxVariableRef refTemp = pMeth;
1276 : // forces a broadcast
1277 0 : SbxVariableRef pNew = new SbxMethod( *((SbxMethod*)pMeth));
1278 : OSL_TRACE("pNew has type %d and string value %s", pNew->GetType(), OUStringToOString( pNew->GetOUString(), RTL_TEXTENCODING_UTF8 ).getStr() );
1279 0 : aRet = sbxToUnoValue( pNew );
1280 : }
1281 0 : return aRet;
1282 : }
1283 :
1284 0 : uno::Any SAL_CALL ScVbaApplication::GetOpenFilename(
1285 : const uno::Any& rFileFilter, const uno::Any& rFilterIndex, const uno::Any& rTitle,
1286 : const uno::Any& rButtonText, const uno::Any& rMultiSelect ) throw (uno::RuntimeException)
1287 : {
1288 0 : uno::Sequence< uno::Any > aArgs( 6 );
1289 0 : aArgs[ 0 ] <<= getThisExcelDoc( mxContext );
1290 0 : aArgs[ 1 ] = rFileFilter;
1291 0 : aArgs[ 2 ] = rFilterIndex;
1292 0 : aArgs[ 3 ] = rTitle;
1293 0 : aArgs[ 4 ] = rButtonText;
1294 0 : aArgs[ 5 ] = rMultiSelect;
1295 0 : uno::Reference< lang::XMultiComponentFactory > xFactory( mxContext->getServiceManager(), uno::UNO_SET_THROW );
1296 0 : uno::Reference< XExecutableDialog > xFilePicker( xFactory->createInstanceWithArgumentsAndContext(
1297 0 : OUString( "ooo.vba.OpenFilePicker" ), aArgs, mxContext ), uno::UNO_QUERY_THROW );
1298 0 : return xFilePicker->execute();
1299 : }
1300 :
1301 0 : uno::Any SAL_CALL ScVbaApplication::GetSaveAsFilename(
1302 : const uno::Any& rInitialFileName, const uno::Any& rFileFilter, const uno::Any& rFilterIndex,
1303 : const uno::Any& rTitle, const uno::Any& rButtonText ) throw (uno::RuntimeException)
1304 : {
1305 0 : uno::Sequence< uno::Any > aArgs( 6 );
1306 0 : aArgs[ 0 ] <<= getThisExcelDoc( mxContext );
1307 0 : aArgs[ 1 ] = rInitialFileName;
1308 0 : aArgs[ 2 ] = rFileFilter;
1309 0 : aArgs[ 3 ] = rFilterIndex;
1310 0 : aArgs[ 4 ] = rTitle;
1311 0 : aArgs[ 5 ] = rButtonText;
1312 0 : uno::Reference< lang::XMultiComponentFactory > xFactory( mxContext->getServiceManager(), uno::UNO_SET_THROW );
1313 0 : uno::Reference< XExecutableDialog > xFilePicker( xFactory->createInstanceWithArgumentsAndContext(
1314 0 : OUString( "ooo.vba.SaveAsFilePicker" ), aArgs, mxContext ), uno::UNO_QUERY_THROW );
1315 0 : return xFilePicker->execute();
1316 : }
1317 :
1318 : uno::Reference< frame::XModel >
1319 206 : ScVbaApplication::getCurrentDocument() throw (css::uno::RuntimeException)
1320 : {
1321 206 : return getCurrentExcelDoc(mxContext);
1322 : }
1323 :
1324 : uno::Any SAL_CALL
1325 0 : ScVbaApplication::MenuBars( const uno::Any& aIndex ) throw (uno::RuntimeException, std::exception)
1326 : {
1327 0 : uno::Reference< XCommandBars > xCommandBars( CommandBars( uno::Any() ), uno::UNO_QUERY_THROW );
1328 0 : uno::Reference< XCollection > xMenuBars( new ScVbaMenuBars( this, mxContext, xCommandBars ) );
1329 0 : if ( aIndex.hasValue() )
1330 : {
1331 0 : return uno::Any ( xMenuBars->Item( aIndex, uno::Any() ) );
1332 : }
1333 :
1334 0 : return uno::Any( xMenuBars );
1335 : }
1336 :
1337 0 : void SAL_CALL ScVbaApplication::OnKey( const OUString& Key, const uno::Any& Procedure ) throw (uno::RuntimeException, std::exception)
1338 : {
1339 : try
1340 : {
1341 : // Perhaps we can catch some excel specific
1342 : // related behaviour here
1343 0 : VbaApplicationBase::OnKey( Key, Procedure );
1344 : }
1345 0 : catch( container::NoSuchElementException& )
1346 : {
1347 : // #TODO special handling for unhandled
1348 : // bindings
1349 : }
1350 0 : }
1351 :
1352 0 : void SAL_CALL ScVbaApplication::Undo() throw (uno::RuntimeException, std::exception)
1353 : {
1354 0 : uno::Reference< frame::XModel > xModel( getThisExcelDoc( mxContext ), uno::UNO_SET_THROW );
1355 :
1356 0 : ScTabViewShell* pViewShell = excel::getBestViewShell( xModel );
1357 0 : if ( pViewShell )
1358 0 : dispatchExecute( pViewShell, SID_UNDO );
1359 0 : }
1360 :
1361 : OUString
1362 0 : ScVbaApplication::getServiceImplName()
1363 : {
1364 0 : return OUString("ScVbaApplication");
1365 : }
1366 :
1367 : uno::Sequence< OUString >
1368 0 : ScVbaApplication::getServiceNames()
1369 : {
1370 0 : static uno::Sequence< OUString > aServiceNames;
1371 0 : if ( aServiceNames.getLength() == 0 )
1372 : {
1373 0 : aServiceNames.realloc( 1 );
1374 0 : aServiceNames[ 0 ] = "ooo.vba.excel.Application";
1375 : }
1376 0 : return aServiceNames;
1377 : }
1378 :
1379 : namespace application
1380 : {
1381 : namespace sdecl = comphelper::service_decl;
1382 4 : sdecl::vba_service_class_<ScVbaApplication, sdecl::with_args<false> > serviceImpl;
1383 4 : extern sdecl::ServiceDecl const serviceDecl(
1384 : serviceImpl,
1385 : "ScVbaApplication",
1386 : "ooo.vba.excel.Application" );
1387 12 : }
1388 :
1389 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|