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