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