xref: /core/sw/source/ui/vba/vbaapplication.cxx (revision c9b57b72)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column:100 -*- */
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/task/XStatusIndicatorSupplier.hpp>
21 #include <com/sun/star/task/XStatusIndicator.hpp>
22 #include <com/sun/star/util/thePathSettings.hpp>
23 #include <com/sun/star/awt/XDevice.hpp>
24 
25 #include "vbaapplication.hxx"
26 #include "vbadocument.hxx"
27 #include "vbafilterpropsfromformat.hxx"
28 #include <sal/log.hxx>
29 #include <osl/file.hxx>
30 #include <vcl/svapp.hxx>
31 #include <vbahelper/vbahelper.hxx>
32 #include "vbawindow.hxx"
33 #include "vbasystem.hxx"
34 #include "vbaoptions.hxx"
35 #include "vbaselection.hxx"
36 #include "vbadocuments.hxx"
37 #include "vbaaddins.hxx"
38 #include "vbamailmerge.hxx"
39 #include "vbadialogs.hxx"
40 #include <ooo/vba/XConnectionPoint.hpp>
41 #include <ooo/vba/word/WdEnableCancelKey.hpp>
42 #include <ooo/vba/word/WdWindowState.hpp>
43 #include <ooo/vba/word/XApplicationOutgoing.hpp>
44 #include <ooo/vba/word/XBookmarks.hpp>
45 #include <comphelper/processfactory.hxx>
46 #include <comphelper/propertyvalue.hxx>
47 #include <editeng/acorrcfg.hxx>
48 #include <swdll.hxx>
49 #include <swmodule.hxx>
50 #include "vbalistgalleries.hxx"
51 #include <tools/urlobj.hxx>
52 
53 using namespace ::ooo;
54 using namespace ::ooo::vba;
55 using namespace ::com::sun::star;
56 
57 namespace {
58 
59 class SwVbaApplicationOutgoingConnectionPoint : public cppu::WeakImplHelper<XConnectionPoint>
60 {
61 private:
62     SwVbaApplication* mpApp;
63 
64 public:
65     SwVbaApplicationOutgoingConnectionPoint( SwVbaApplication* pApp );
66 
67     // XConnectionPoint
68     sal_uInt32 SAL_CALL Advise(const uno::Reference< XSink >& Sink ) override;
69     void SAL_CALL Unadvise( sal_uInt32 Cookie ) override;
70 };
71 
72 class SwWordBasic : public cppu::WeakImplHelper<word::XWordBasic>
73 {
74 private:
75     SwVbaApplication* mpApp;
76 
77 public:
78     SwWordBasic( SwVbaApplication* pApp );
79 
80     // XWordBasic
81     virtual sal_Int32 SAL_CALL getMailMergeMainDocumentType() override;
82     virtual void SAL_CALL setMailMergeMainDocumentType( sal_Int32 _mailmergemaindocumenttype ) override;
83 
84     virtual void SAL_CALL FileOpen( const OUString& Name, const uno::Any& ConfirmConversions, const uno::Any& ReadOnly, const uno::Any& AddToMru, const uno::Any& PasswordDoc, const uno::Any& PasswordDot, const uno::Any& Revert, const uno::Any& WritePasswordDoc, const uno::Any& WritePasswordDot ) override;
85     virtual void SAL_CALL FileSave() override;
86     virtual void SAL_CALL FileSaveAs( const css::uno::Any& Name,
87                                       const css::uno::Any& Format,
88                                       const css::uno::Any& LockAnnot,
89                                       const css::uno::Any& Password,
90                                       const css::uno::Any& AddToMru,
91                                       const css::uno::Any& WritePassword,
92                                       const css::uno::Any& RecommendReadOnly,
93                                       const css::uno::Any& EmbedFonts,
94                                       const css::uno::Any& NativePictureFormat,
95                                       const css::uno::Any& FormsData,
96                                       const css::uno::Any& SaveAsAOCELetter ) override;
97     virtual void SAL_CALL FileClose( const css::uno::Any& Save ) override;
98     virtual void SAL_CALL ToolsOptionsView( const css::uno::Any& DraftFont,
99                                             const css::uno::Any& WrapToWindow,
100                                             const css::uno::Any& PicturePlaceHolders,
101                                             const css::uno::Any& FieldCodes,
102                                             const css::uno::Any& BookMarks,
103                                             const css::uno::Any& FieldShading,
104                                             const css::uno::Any& StatusBar,
105                                             const css::uno::Any& HScroll,
106                                             const css::uno::Any& VScroll,
107                                             const css::uno::Any& StyleAreaWidth,
108                                             const css::uno::Any& Tabs,
109                                             const css::uno::Any& Spaces,
110                                             const css::uno::Any& Paras,
111                                             const css::uno::Any& Hyphens,
112                                             const css::uno::Any& Hidden,
113                                             const css::uno::Any& ShowAll,
114                                             const css::uno::Any& Drawings,
115                                             const css::uno::Any& Anchors,
116                                             const css::uno::Any& TextBoundaries,
117                                             const css::uno::Any& VRuler,
118                                             const css::uno::Any& Highlight ) override;
119     virtual css::uno::Any SAL_CALL WindowName( const css::uno::Any& Number ) override;
120     virtual css::uno::Any SAL_CALL ExistingBookmark( const OUString& Name ) override;
121     virtual void SAL_CALL MailMergeOpenDataSource(const OUString& Name, const css::uno::Any& Format,
122                                                   const css::uno::Any& ConfirmConversions, const css::uno::Any& ReadOnly,
123                                                   const css::uno::Any& LinkToSource, const css::uno::Any& AddToRecentFiles,
124                                                   const css::uno::Any& PasswordDocument, const css::uno::Any& PasswordTemplate,
125                                                   const css::uno::Any& Revert, const css::uno::Any& WritePasswordDocument,
126                                                   const css::uno::Any& WritePasswordTemplate, const css::uno::Any& Connection,
127                                                   const css::uno::Any& SQLStatement, const css::uno::Any& SQLStatement1,
128                                                   const css::uno::Any& OpenExclusive, const css::uno::Any& SubType) override;
129     virtual css::uno::Any SAL_CALL AppMaximize( const css::uno::Any& WindowName, const css::uno::Any& State ) override;
130     virtual css::uno::Any SAL_CALL DocMaximize( const css::uno::Any& State ) override;
131     virtual void SAL_CALL AppShow(  const css::uno::Any& WindowName ) override;
132     virtual css::uno::Any SAL_CALL AppCount() override;
133 };
134 
135 }
136 
137 SwVbaApplication::SwVbaApplication( uno::Reference<uno::XComponentContext >& xContext ):
138     SwVbaApplication_BASE( xContext )
139 {
140 }
141 
142 SwVbaApplication::~SwVbaApplication()
143 {
144 }
145 
146 sal_uInt32
147 SwVbaApplication::AddSink( const uno::Reference< XSink >& xSink )
148 {
149     {
150         SolarMutexGuard aGuard;
151         SwGlobals::ensure();
152     }
153     // No harm in potentially calling this several times
154     SW_MOD()->RegisterAutomationApplicationEventsCaller( uno::Reference< XSinkCaller >(this) );
155     mvSinks.push_back(xSink);
156     return mvSinks.size();
157 }
158 
159 void
160 SwVbaApplication::RemoveSink( sal_uInt32 nNumber )
161 {
162     if (nNumber < 1 || nNumber > mvSinks.size())
163         return;
164 
165     mvSinks[nNumber-1] = uno::Reference< XSink >();
166 }
167 
168 OUString SAL_CALL
169 SwVbaApplication::getName()
170 {
171     return "Microsoft Word";
172 }
173 
174 uno::Reference< word::XDocument > SAL_CALL
175 SwVbaApplication::getActiveDocument()
176 {
177     return new SwVbaDocument( this, mxContext, getCurrentDocument() );
178 }
179 
180 rtl::Reference<SwVbaWindow>
181 SwVbaApplication::getActiveSwVbaWindow()
182 {
183     // #FIXME so far can't determine Parent
184     uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW );
185     uno::Reference< frame::XController > xController( xModel->getCurrentController(), uno::UNO_SET_THROW );
186     return new SwVbaWindow( uno::Reference< XHelperInterface >(), mxContext, xModel, xController );
187 }
188 
189 uno::Reference< css::uno::XComponentContext > const &
190 SwVbaApplication::getContext() const
191 {
192     return mxContext;
193 }
194 
195 uno::Reference< word::XWindow > SAL_CALL
196 SwVbaApplication::getActiveWindow()
197 {
198     return getActiveSwVbaWindow();
199 }
200 
201 uno::Reference<word::XSystem > SAL_CALL
202 SwVbaApplication::getSystem()
203 {
204     return uno::Reference< word::XSystem >( new SwVbaSystem( mxContext ) );
205 }
206 
207 uno::Reference<word::XOptions > SAL_CALL
208 SwVbaApplication::getOptions()
209 {
210     return uno::Reference< word::XOptions >( new SwVbaOptions( mxContext ) );
211 }
212 
213 uno::Any SAL_CALL
214 SwVbaApplication::CommandBars( const uno::Any& aIndex )
215 {
216     try
217     {
218         return VbaApplicationBase::CommandBars( aIndex );
219     }
220     catch (const uno::RuntimeException&)
221     {
222         return uno::Any();
223     }
224 }
225 
226 uno::Reference< word::XSelection > SAL_CALL
227 SwVbaApplication::getSelection()
228 {
229     return new SwVbaSelection( this, mxContext, getCurrentDocument() );
230 }
231 
232 uno::Reference< word::XWordBasic > SAL_CALL
233 SwVbaApplication::getWordBasic()
234 {
235     uno::Reference< word::XWordBasic > xWB( new SwWordBasic( this ) );
236     return xWB;
237 }
238 
239 uno::Any SAL_CALL
240 SwVbaApplication::Documents( const uno::Any& index )
241 {
242     uno::Reference< XCollection > xCol( new SwVbaDocuments( this, mxContext ) );
243     if ( index.hasValue() )
244         return xCol->Item( index, uno::Any() );
245     return uno::Any( xCol );
246 }
247 
248 uno::Any SAL_CALL
249 SwVbaApplication::Addins( const uno::Any& index )
250 {
251     static uno::Reference< XCollection > xCol( new SwVbaAddins( this, mxContext ) );
252     if ( index.hasValue() )
253         return xCol->Item( index, uno::Any() );
254     return uno::Any( xCol );
255 }
256 
257 uno::Any SAL_CALL
258 SwVbaApplication::Dialogs( const uno::Any& index )
259 {
260     uno::Reference< word::XDialogs > xCol( new SwVbaDialogs( this, mxContext, getCurrentDocument() ));
261     if ( index.hasValue() )
262         return xCol->Item( index );
263     return uno::Any( xCol );
264 }
265 
266 uno::Any SAL_CALL
267 SwVbaApplication::ListGalleries( const uno::Any& index )
268 {
269     uno::Reference< text::XTextDocument > xTextDoc( getCurrentDocument(), uno::UNO_QUERY_THROW );
270     uno::Reference< XCollection > xCol( new SwVbaListGalleries( this, mxContext, xTextDoc ) );
271     if ( index.hasValue() )
272         return xCol->Item( index, uno::Any() );
273     return uno::Any( xCol );
274 }
275 
276 sal_Bool SAL_CALL SwVbaApplication::getDisplayAutoCompleteTips()
277 {
278     return SvxAutoCorrCfg::Get().IsAutoTextTip();
279 }
280 
281 void SAL_CALL SwVbaApplication::setDisplayAutoCompleteTips( sal_Bool _displayAutoCompleteTips )
282 {
283     SvxAutoCorrCfg::Get().SetAutoTextTip( _displayAutoCompleteTips );
284 }
285 
286 sal_Int32 SAL_CALL SwVbaApplication::getEnableCancelKey()
287 {
288     // the default value is wdCancelInterrupt in Word
289     return word::WdEnableCancelKey::wdCancelInterrupt;
290 }
291 
292 void SAL_CALL SwVbaApplication::setEnableCancelKey( sal_Int32/* _enableCancelKey */)
293 {
294     // seems not supported in Writer
295 }
296 
297 sal_Int32 SAL_CALL SwVbaApplication::getWindowState()
298 {
299     auto xWindow = getActiveWindow();
300     if (xWindow.is())
301     {
302         uno::Any aState = xWindow->getWindowState();
303         sal_Int32 nState;
304         if (aState >>= nState)
305             return nState;
306     }
307 
308     return word::WdWindowState::wdWindowStateNormal; // ?
309 }
310 
311 void SAL_CALL SwVbaApplication::setWindowState( sal_Int32 _windowstate )
312 {
313     try
314     {
315         auto xWindow = getActiveWindow();
316         if (xWindow.is())
317         {
318             uno::Any aState;
319             aState <<= _windowstate;
320             xWindow->setWindowState( aState );
321         }
322     }
323     catch (const uno::RuntimeException&)
324     {
325     }
326 }
327 
328 sal_Int32 SAL_CALL SwVbaApplication::getWidth()
329 {
330     auto pWindow = getActiveSwVbaWindow();
331     return pWindow->getWidth();
332 }
333 
334 void SAL_CALL SwVbaApplication::setWidth( sal_Int32 _width )
335 {
336     auto pWindow = getActiveSwVbaWindow();
337     pWindow->setWidth( _width );
338 }
339 
340 sal_Int32 SAL_CALL SwVbaApplication::getHeight()
341 {
342     auto pWindow = getActiveSwVbaWindow();
343     return pWindow->getHeight();
344 }
345 
346 void SAL_CALL SwVbaApplication::setHeight( sal_Int32 _height )
347 {
348     auto pWindow = getActiveSwVbaWindow();
349     pWindow->setHeight( _height );
350 }
351 
352 sal_Int32 SAL_CALL SwVbaApplication::getLeft()
353 {
354     auto pWindow = getActiveSwVbaWindow();
355     return pWindow->getLeft();
356 }
357 
358 void SAL_CALL SwVbaApplication::setLeft( sal_Int32 _left )
359 {
360     auto pWindow = getActiveSwVbaWindow();
361     pWindow->setLeft( _left );
362 }
363 
364 sal_Int32 SAL_CALL SwVbaApplication::getTop()
365 {
366     auto pWindow = getActiveSwVbaWindow();
367     return pWindow->getTop();
368 }
369 
370 void SAL_CALL SwVbaApplication::setTop( sal_Int32 _top )
371 {
372     auto pWindow = getActiveSwVbaWindow();
373     pWindow->setTop( _top );
374 }
375 
376 OUString SAL_CALL SwVbaApplication::getStatusBar()
377 {
378     return "";
379 }
380 
381 uno::Any SAL_CALL SwVbaApplication::getCustomizationContext()
382 {
383     return uno::Any(); // ???
384 }
385 
386 void SAL_CALL SwVbaApplication::setCustomizationContext(const uno::Any& /*_customizationcontext*/)
387 {
388     // ???
389 }
390 
391 void SAL_CALL SwVbaApplication::setStatusBar( const OUString& _statusbar )
392 {
393     // ScVbaAppSettings::setStatusBar() also uses the XStatusIndicator to show this, so maybe that is OK?
394     uno::Reference< frame::XModel > xModel = getCurrentDocument();
395     if (xModel.is())
396     {
397         uno::Reference< task::XStatusIndicatorSupplier > xStatusIndicatorSupplier( xModel->getCurrentController(), uno::UNO_QUERY );
398         if (xStatusIndicatorSupplier.is())
399         {
400             uno::Reference< task::XStatusIndicator > xStatusIndicator = xStatusIndicatorSupplier->getStatusIndicator();
401             if (xStatusIndicator.is())
402                 xStatusIndicator->start( _statusbar, 100 );
403         }
404     }
405 
406     // Yes, we intentionally use the "extensions.olebridge" tag here even if this is sw. We
407     // interpret setting the StatusBar property as a request from an Automation client to display
408     // the string in LibreOffice's debug output, and all other generic Automation support debug
409     // output (in extensions/source/ole) uses that tag. If the check for "cross-module" or mixed log
410     // areas in compilerplugins/clang/sallogareas.cxx is re-activated, this will have to be added as
411     // a special case.
412 
413     SAL_INFO("extensions.olebridge", "Client debug output: " << _statusbar);
414 }
415 
416 float SAL_CALL SwVbaApplication::CentimetersToPoints( float Centimeters )
417 {
418     return VbaApplicationBase::CentimetersToPoints( Centimeters );
419 }
420 
421 float SAL_CALL SwVbaApplication::PointsToCentimeters( float Points )
422 {
423     return o3tl::convert(Points, o3tl::Length::pt, o3tl::Length::cm);
424 }
425 
426 float SAL_CALL SwVbaApplication::PixelsToPoints( float Pixels, ::sal_Bool fVertical )
427 {
428     //Set up xDevice
429     uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW );
430     uno::Reference< frame::XController > xController( xModel->getCurrentController(), uno::UNO_SET_THROW );
431     uno::Reference< frame::XFrame > xFrame( xController->getFrame(), uno::UNO_SET_THROW );
432     uno::Reference< awt::XWindow > xWindow( xFrame->getContainerWindow(), uno::UNO_SET_THROW );
433     css::uno::Reference< css::awt::XDevice > xDevice( xWindow, css::uno::UNO_QUERY );
434 
435     return ooo::vba::PixelsToPoints(xDevice, Pixels, fVertical);
436 }
437 
438 float SAL_CALL SwVbaApplication::PointsToPixels( float Pixels, ::sal_Bool fVertical )
439 {
440     uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW );
441     uno::Reference< frame::XController > xController( xModel->getCurrentController(), uno::UNO_SET_THROW );
442     uno::Reference< frame::XFrame > xFrame( xController->getFrame(), uno::UNO_SET_THROW );
443     uno::Reference< awt::XWindow > xWindow( xFrame->getContainerWindow(), uno::UNO_SET_THROW );
444     css::uno::Reference< css::awt::XDevice > xDevice( xWindow, css::uno::UNO_QUERY );
445 
446     return ooo::vba::PointsToPixels(xDevice, Pixels, fVertical);
447 }
448 
449 float SAL_CALL SwVbaApplication::InchesToPoints( float Inches )
450 {
451     return o3tl::convert(Inches, o3tl::Length::ch, o3tl::Length::pt);
452 }
453 
454 float SAL_CALL SwVbaApplication::PointsToInches( float Points )
455 {
456     return o3tl::convert(Points, o3tl::Length::pt, o3tl::Length::ch);
457 }
458 
459 float SAL_CALL SwVbaApplication::MillimetersToPoints( float Millimeters )
460 {
461     return o3tl::convert(Millimeters, o3tl::Length::mm, o3tl::Length::pt);
462 }
463 
464 float SAL_CALL SwVbaApplication::PointsToMillimeters( float Points )
465 {
466     return o3tl::convert(Points, o3tl::Length::pt, o3tl::Length::mm);
467 }
468 
469 float SAL_CALL SwVbaApplication::PicasToPoints( float Picas )
470 {
471     return o3tl::convert(Picas, o3tl::Length::pc, o3tl::Length::pt);
472 }
473 
474 float SAL_CALL SwVbaApplication::PointsToPicas( float Points )
475 {
476     return o3tl::convert(Points, o3tl::Length::pt, o3tl::Length::pc);
477 }
478 
479 void SAL_CALL SwVbaApplication::ShowMe()
480 {
481     // Method no longer supported in word - deprecated
482 }
483 
484 void SAL_CALL SwVbaApplication::Resize( sal_Int32 Width, sal_Int32 Height )
485 {
486     // Have to do it like this as the Width and Height are hidden away in the ooo::vba::XWindowBase
487     // which ooo::vba::word::XApplication does not inherit from. SwVbaWindow, however, does inherit
488     // from XWindowBase. Ugh.
489     auto pWindow = getActiveSwVbaWindow();
490     pWindow->setWidth( Width );
491     pWindow->setHeight( Height );
492 }
493 
494 void SAL_CALL SwVbaApplication::Move( sal_Int32 Left, sal_Int32 Top )
495 {
496     // See comment in Resize().
497     auto pWindow = getActiveSwVbaWindow();
498     pWindow->setLeft( Left );
499     pWindow->setTop( Top );
500 }
501 
502 // XInterfaceWithIID
503 
504 OUString SAL_CALL
505 SwVbaApplication::getIID()
506 {
507     return "{82154421-0FBF-11d4-8313-005004526AB4}";
508 }
509 
510 // XConnectable
511 
512 OUString SAL_CALL
513 SwVbaApplication::GetIIDForClassItselfNotCoclass()
514 {
515     return "{82154423-0FBF-11D4-8313-005004526AB4}";
516 }
517 
518 TypeAndIID SAL_CALL
519 SwVbaApplication::GetConnectionPoint()
520 {
521     TypeAndIID aResult =
522         { word::XApplicationOutgoing::static_type(),
523           "{82154422-0FBF-11D4-8313-005004526AB4}"
524         };
525 
526     return aResult;
527 }
528 
529 uno::Reference<XConnectionPoint> SAL_CALL
530 SwVbaApplication::FindConnectionPoint()
531 {
532     uno::Reference<XConnectionPoint> xCP(new SwVbaApplicationOutgoingConnectionPoint(this));
533     return xCP;
534 }
535 
536 OUString
537 SwVbaApplication::getServiceImplName()
538 {
539     return "SwVbaApplication";
540 }
541 
542 uno::Sequence< OUString >
543 SwVbaApplication::getServiceNames()
544 {
545     static uno::Sequence< OUString > const aServiceNames
546     {
547         "ooo.vba.word.Application"
548     };
549     return aServiceNames;
550 }
551 
552 uno::Reference< frame::XModel >
553 SwVbaApplication::getCurrentDocument()
554 {
555     return getCurrentWordDoc( mxContext );
556 }
557 
558 // XSinkCaller
559 
560 void SAL_CALL
561 SwVbaApplication::CallSinks( const OUString& Method, uno::Sequence< uno::Any >& Arguments )
562 {
563     for (auto& i : mvSinks)
564     {
565         if (i.is())
566             i->Call(Method, Arguments);
567     }
568 }
569 
570 // SwVbaApplicationOutgoingConnectionPoint
571 
572 SwVbaApplicationOutgoingConnectionPoint::SwVbaApplicationOutgoingConnectionPoint( SwVbaApplication* pApp ) :
573     mpApp(pApp)
574 {
575 }
576 
577 // XConnectionPoint
578 sal_uInt32 SAL_CALL
579 SwVbaApplicationOutgoingConnectionPoint::Advise( const uno::Reference< XSink >& Sink )
580 {
581     return mpApp->AddSink(Sink);
582 }
583 
584 void SAL_CALL
585 SwVbaApplicationOutgoingConnectionPoint::Unadvise( sal_uInt32 Cookie )
586 {
587     mpApp->RemoveSink( Cookie );
588 }
589 
590 // SwWordBasic
591 
592 SwWordBasic::SwWordBasic( SwVbaApplication* pApp ) :
593     mpApp(pApp)
594 {
595 }
596 
597 // XWordBasic
598 sal_Int32 SAL_CALL
599 SwWordBasic::getMailMergeMainDocumentType()
600 {
601     return SwVbaMailMerge::get( mpApp->getParent(), mpApp->getContext() )->getMainDocumentType();
602 }
603 
604 // XWordBasic
605 void SAL_CALL
606 SwWordBasic::setMailMergeMainDocumentType( sal_Int32 _mailmergemaindocumenttype )
607 {
608     SwVbaMailMerge::get( mpApp->getParent(), mpApp->getContext() )->setMainDocumentType( _mailmergemaindocumenttype );
609 }
610 
611 void SAL_CALL
612 SwWordBasic::FileOpen( const OUString& Name, const uno::Any& ConfirmConversions, const uno::Any& ReadOnly, const uno::Any& AddToMru, const uno::Any& PasswordDoc, const uno::Any& PasswordDot, const uno::Any& Revert, const uno::Any& WritePasswordDoc, const uno::Any& WritePasswordDot )
613 {
614     uno::Any aDocuments = mpApp->Documents( uno::Any() );
615 
616     uno::Reference<word::XDocuments> rDocuments;
617 
618     if (aDocuments >>= rDocuments)
619         rDocuments->Open( Name, ConfirmConversions, ReadOnly, AddToMru, PasswordDoc, PasswordDot, Revert, WritePasswordDoc, WritePasswordDot, uno::Any(), uno::Any(), uno::Any(), uno::Any(), uno::Any(), uno::Any(), uno::Any() );
620 }
621 
622 void SAL_CALL
623 SwWordBasic::FileSave()
624 {
625     uno::Reference< frame::XModel > xModel( mpApp->getCurrentDocument(), uno::UNO_SET_THROW );
626     dispatchRequests(xModel,".uno:Save");
627 }
628 
629 void SAL_CALL
630 SwWordBasic::FileSaveAs( const css::uno::Any& Name,
631                          const css::uno::Any& Format,
632                          const css::uno::Any& /*LockAnnot*/,
633                          const css::uno::Any& /*Password*/,
634                          const css::uno::Any& /*AddToMru*/,
635                          const css::uno::Any& /*WritePassword*/,
636                          const css::uno::Any& /*RecommendReadOnly*/,
637                          const css::uno::Any& /*EmbedFonts*/,
638                          const css::uno::Any& /*NativePictureFormat*/,
639                          const css::uno::Any& /*FormsData*/,
640                          const css::uno::Any& /*SaveAsAOCELetter*/ )
641 {
642     SAL_INFO("sw.vba", "WordBasic.FileSaveAs(Name:=" << Name << ",Format:=" << Format << ")");
643 
644     uno::Reference< frame::XModel > xModel( mpApp->getCurrentDocument(), uno::UNO_SET_THROW );
645 
646     // Based on SwVbaDocument::SaveAs2000.
647 
648     OUString sFileName;
649     Name >>= sFileName;
650 
651     OUString sURL;
652     osl::FileBase::getFileURLFromSystemPath( sFileName, sURL );
653 
654     // Detect if there is no path then we need to use the current folder.
655     INetURLObject aURL( sURL );
656     sURL = aURL.GetMainURL( INetURLObject::DecodeMechanism::ToIUri );
657     if( sURL.isEmpty() )
658     {
659         // Need to add cur dir ( of this document ) or else the 'Work' dir
660         sURL = xModel->getURL();
661 
662         if ( sURL.isEmpty() )
663         {
664             // Not path available from 'this' document. Need to add the 'document'/work directory then.
665             // Based on SwVbaOptions::getValueEvent()
666             uno::Reference< util::XPathSettings > xPathSettings = util::thePathSettings::get( comphelper::getProcessComponentContext() );
667             OUString sPathUrl;
668             xPathSettings->getPropertyValue( "Work" ) >>= sPathUrl;
669             // Path could be a multipath, Microsoft doesn't support this feature in Word currently.
670             // Only the last path is from interest.
671             // No idea if this crack is relevant for WordBasic or not.
672             sal_Int32 nIndex = sPathUrl.lastIndexOf( ';' );
673             if( nIndex != -1 )
674             {
675                 sPathUrl = sPathUrl.copy( nIndex + 1 );
676             }
677 
678             aURL.SetURL( sPathUrl );
679         }
680         else
681         {
682             aURL.SetURL( sURL );
683             aURL.Append( sFileName );
684         }
685         sURL = aURL.GetMainURL( INetURLObject::DecodeMechanism::ToIUri );
686 
687     }
688     sal_Int32 nFileFormat = word::WdSaveFormat::wdFormatDocument;
689     Format >>= nFileFormat;
690 
691     uno::Sequence aProps{ comphelper::makePropertyValue("FilterName", css::uno::Any()),
692                           comphelper::makePropertyValue("FileName", sURL) };
693 
694     setFilterPropsFromFormat( nFileFormat, aProps );
695 
696     dispatchRequests(xModel,".uno:SaveAs",aProps);
697 }
698 
699 void SAL_CALL
700 SwWordBasic::FileClose( const css::uno::Any& Save )
701 {
702     uno::Reference< frame::XModel > xModel( mpApp->getCurrentDocument(), uno::UNO_SET_THROW );
703 
704     sal_Int16 nSave = 0;
705     if (Save.hasValue() && (Save >>= nSave) && (nSave == 0 || nSave == 1))
706         FileSave();
707 
708     // FIXME: Here I would much prefer to call VbaDocumentBase::Close() but not sure how to get at
709     // the VbaDocumentBase of the current document. (Probably it is easy and I haven't looked hard
710     // enough.)
711     //
712     // FIXME: Error handling. If there is no current document, return some kind of error? But for
713     // now, just ignore errors. This code is written to work for a very specific customer use case
714     // anyway, not for an arbitrary sequence of COM calls to the "VBA" API.
715     dispatchRequests(xModel,".uno:CloseDoc");
716 }
717 
718 void SAL_CALL
719 SwWordBasic::ToolsOptionsView( const css::uno::Any& DraftFont,
720                                const css::uno::Any& WrapToWindow,
721                                const css::uno::Any& PicturePlaceHolders,
722                                const css::uno::Any& FieldCodes,
723                                const css::uno::Any& BookMarks,
724                                const css::uno::Any& FieldShading,
725                                const css::uno::Any& StatusBar,
726                                const css::uno::Any& HScroll,
727                                const css::uno::Any& VScroll,
728                                const css::uno::Any& StyleAreaWidth,
729                                const css::uno::Any& Tabs,
730                                const css::uno::Any& Spaces,
731                                const css::uno::Any& Paras,
732                                const css::uno::Any& Hyphens,
733                                const css::uno::Any& Hidden,
734                                const css::uno::Any& ShowAll,
735                                const css::uno::Any& Drawings,
736                                const css::uno::Any& Anchors,
737                                const css::uno::Any& TextBoundaries,
738                                const css::uno::Any& VRuler,
739                                const css::uno::Any& Highlight )
740 {
741     SAL_INFO("sw.vba", "WordBasic.ToolsOptionsView("
742                 "DraftFont:=" << DraftFont
743              << ", WrapToWindow:=" << WrapToWindow
744              << ", PicturePlaceHolders:=" << PicturePlaceHolders
745              << ", FieldCodes:=" << FieldCodes
746              << ", BookMarks:=" << BookMarks
747              << ", FieldShading:=" << FieldShading
748              << ", StatusBar:=" << StatusBar
749              << ", HScroll:=" << HScroll
750              << ", VScroll:=" << VScroll
751              << ", StyleAreaWidth:=" << StyleAreaWidth
752              << ", Tabs:=" << Tabs
753              << ", Spaces:=" << Spaces
754              << ", Paras:=" << Paras
755              << ", Hyphens:=" << Hyphens
756              << ", Hidden:=" << Hidden
757              << ", ShowAll:=" << ShowAll
758              << ", Drawings:=" << Drawings
759              << ", Anchors:=" << Anchors
760              << ", TextBoundaries:=" << TextBoundaries
761              << ", VRuler:=" << VRuler
762               << ", Highlight:=" << Highlight
763              << ")");
764 }
765 
766 css::uno::Any SAL_CALL
767 SwWordBasic::WindowName( const css::uno::Any& /*Number*/ )
768 {
769     return css::uno::Any( mpApp->getActiveSwVbaWindow()->getCaption() );
770 }
771 
772 css::uno::Any SAL_CALL
773 SwWordBasic::ExistingBookmark( const OUString& Name )
774 {
775     uno::Reference< word::XBookmarks > xBookmarks( mpApp->getActiveDocument()->Bookmarks( uno::Any() ), uno::UNO_QUERY );
776     return css::uno::Any( xBookmarks.is() && xBookmarks->Exists( Name ) );
777 }
778 
779 void SAL_CALL
780 SwWordBasic::MailMergeOpenDataSource( const OUString& Name, const css::uno::Any& Format,
781                                       const css::uno::Any& ConfirmConversions, const css::uno::Any& ReadOnly,
782                                       const css::uno::Any& LinkToSource, const css::uno::Any& AddToRecentFiles,
783                                       const css::uno::Any& PasswordDocument, const css::uno::Any& PasswordTemplate,
784                                       const css::uno::Any& Revert, const css::uno::Any& WritePasswordDocument,
785                                       const css::uno::Any& WritePasswordTemplate, const css::uno::Any& Connection,
786                                       const css::uno::Any& SQLStatement, const css::uno::Any& SQLStatement1,
787                                       const css::uno::Any& OpenExclusive, const css::uno::Any& SubType )
788 {
789     mpApp->getActiveDocument()->getMailMerge()->OpenDataSource( Name, Format, ConfirmConversions, ReadOnly,
790                                                                 LinkToSource, AddToRecentFiles,
791                                                                 PasswordDocument, PasswordTemplate,
792                                                                 Revert, WritePasswordDocument,
793                                                                 WritePasswordTemplate, Connection,
794                                                                 SQLStatement, SQLStatement1,
795                                                                 OpenExclusive, SubType );
796 }
797 
798 css::uno::Any SAL_CALL
799 SwWordBasic::AppMaximize( const css::uno::Any& WindowName, const css::uno::Any& State )
800 {
801     SAL_INFO("sw.vba", "WordBasic.AppMaximize( WindowName:=" << WindowName << ", State:=" << State);
802 
803     // FIXME: Implement if necessary
804     return css::uno::Any( sal_Int32(0) );
805 }
806 
807 css::uno::Any SAL_CALL
808 SwWordBasic::DocMaximize( const css::uno::Any& State )
809 {
810     SAL_INFO("sw.vba", "WordBasic.DocMaximize(State:=" << State << ")");
811 
812     // FIXME: Implement if necessary
813     return css::uno::Any( sal_Int32(0) );
814 }
815 
816 void SAL_CALL
817 SwWordBasic::AppShow( const css::uno::Any& WindowName )
818 {
819     SAL_INFO("sw.vba", "WordBasic.AppShow(WindowName:=" << WindowName << ")");
820 
821     // FIXME: Implement if necessary
822 }
823 
824 css::uno::Any SAL_CALL
825 SwWordBasic::AppCount()
826 {
827     SAL_INFO("sw.vba", "WordBasic.AppCount()");
828 
829     // FIXME: Implement if necessary. Return a random number for now.
830     return css::uno::Any( sal_Int32(2) );
831 }
832 
833 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
834