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