xref: /core/sfx2/source/appl/appserv.cxx (revision 9d9cd780)
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 <config_features.h>
21 #include <config_wasm_strip.h>
22 
23 #include <com/sun/star/drawing/ModuleDispatcher.hpp>
24 #include <com/sun/star/frame/Desktop.hpp>
25 #include <com/sun/star/frame/DispatchResultEvent.hpp>
26 #include <com/sun/star/frame/DispatchResultState.hpp>
27 #include <com/sun/star/frame/DispatchHelper.hpp>
28 #include <com/sun/star/frame/UnknownModuleException.hpp>
29 #include <com/sun/star/frame/XLayoutManager.hpp>
30 #include <com/sun/star/frame/XSynchronousFrameLoader.hpp>
31 #include <com/sun/star/embed/EmbedStates.hpp>
32 #include <com/sun/star/embed/XEmbeddedObject.hpp>
33 #include <com/sun/star/util/XModifiable.hpp>
34 #include <com/sun/star/sdbc/DriverManager.hpp>
35 #include <com/sun/star/text/ModuleDispatcher.hpp>
36 #include <com/sun/star/task/OfficeRestartManager.hpp>
37 #include <com/sun/star/task/XInteractionHandler.hpp>
38 #include <com/sun/star/ui/dialogs/AddressBookSourcePilot.hpp>
39 #include <com/sun/star/ui/UIElementType.hpp>
40 #include <com/sun/star/ui/XUIElement.hpp>
41 #include <com/sun/star/uno/Reference.hxx>
42 #include <com/sun/star/util/XCloseable.hpp>
43 #include <com/sun/star/util/CloseVetoException.hpp>
44 #include <org/freedesktop/PackageKit/SyncDbusSessionHelper.hpp>
45 
46 #include <comphelper/dispatchcommand.hxx>
47 #include <comphelper/lok.hxx>
48 #include <comphelper/namedvaluecollection.hxx>
49 #include <comphelper/processfactory.hxx>
50 #include <comphelper/propertysequence.hxx>
51 #include <comphelper/propertyvalue.hxx>
52 #include <comphelper/sequence.hxx>
53 
54 #include <svtools/addresstemplate.hxx>
55 #include <svtools/restartdialog.hxx>
56 #include <svtools/colorcfg.hxx>
57 #include <svl/visitem.hxx>
58 
59 #include <unotools/configmgr.hxx>
60 #include <comphelper/diagnose_ex.hxx>
61 #include <vcl/weld.hxx>
62 #include <svl/intitem.hxx>
63 #include <svl/eitem.hxx>
64 #include <svl/stritem.hxx>
65 #include <basic/sbstar.hxx>
66 #include <basic/basrdll.hxx>
67 #include <basic/sberrors.hxx>
68 #include <vcl/help.hxx>
69 #include <sal/log.hxx>
70 #include <osl/file.hxx>
71 #include <vcl/EnumContext.hxx>
72 #include <vcl/toolbox.hxx>
73 
74 #include <unotools/moduleoptions.hxx>
75 #include <rtl/bootstrap.hxx>
76 
77 #include <com/sun/star/frame/ModuleManager.hpp>
78 #include <com/sun/star/beans/XPropertySet.hpp>
79 
80 #include <sfx2/app.hxx>
81 #include <sfx2/request.hxx>
82 #include <sfx2/dispatch.hxx>
83 #include <sfx2/bindings.hxx>
84 #include <sfx2/minfitem.hxx>
85 #include <sfx2/msg.hxx>
86 #include <sfx2/objface.hxx>
87 #include <sfx2/objsh.hxx>
88 #include <sfx2/viewsh.hxx>
89 #include <sfx2/docfac.hxx>
90 #include <sfx2/strings.hrc>
91 #include <sfx2/sfxresid.hxx>
92 #include <appdata.hxx>
93 #include <sfx2/viewfrm.hxx>
94 #include <sfx2/sfxdlg.hxx>
95 #include <sfx2/sfxsids.hrc>
96 #include <sorgitm.hxx>
97 #include <sfx2/sfxhelp.hxx>
98 #include <sfx2/zoomitem.hxx>
99 #include <sfx2/templatedlg.hxx>
100 #include <sfx2/notebookbar/SfxNotebookBar.hxx>
101 #include <sfx2/sidebar/SidebarController.hxx>
102 #include <sfx2/safemode.hxx>
103 #include <sfx2/sfxuno.hxx>
104 #include <DevelopmentToolDockingWindow.hxx>
105 
106 #include <comphelper/types.hxx>
107 #include <officecfg/Office/Common.hxx>
108 #include <officecfg/Setup.hxx>
109 #include <unotools/confignode.hxx>
110 #include <memory>
111 
112 #include <openuriexternally.hxx>
113 
114 #include "getbasctlfunction.hxx"
115 
116 using namespace ::com::sun::star;
117 using namespace ::com::sun::star::beans;
118 using namespace ::com::sun::star::uno;
119 using namespace ::com::sun::star::frame;
120 using namespace ::com::sun::star::container;
121 using namespace ::com::sun::star::util;
122 using namespace ::com::sun::star::lang;
123 using namespace ::com::sun::star::ui;
124 
125 namespace
126 {
lcl_getAppName(vcl::EnumContext::Application eApp)127     OUString lcl_getAppName( vcl::EnumContext::Application eApp )
128     {
129         switch ( eApp )
130         {
131             case vcl::EnumContext::Application::Writer:
132                 return u"Writer"_ustr;
133             case vcl::EnumContext::Application::Calc:
134                 return u"Calc"_ustr;
135             case vcl::EnumContext::Application::Impress:
136                 return u"Impress"_ustr;
137             case vcl::EnumContext::Application::Draw:
138                 return u"Draw"_ustr;
139             case vcl::EnumContext::Application::Formula:
140                 return u"Formula"_ustr;
141             case vcl::EnumContext::Application::Base:
142                 return u"Base"_ustr;
143             default:
144                 return OUString();
145         }
146     }
147 
148     // lp#527938, debian#602953, fdo#33266, i#105408
lcl_isBaseAvailable()149     bool lcl_isBaseAvailable()
150     {
151         try
152         {
153             // if we get css::sdbc::DriverManager, libsdbc2 is there
154             // and the bibliography is assumed to work
155             return css::sdbc::DriverManager::create(comphelper::getProcessComponentContext()).is();
156         }
157         catch (const Exception &)
158         {
159             TOOLS_INFO_EXCEPTION("sfx.appl", "assuming Base to be missing");
160             return false;
161         }
162     }
lcl_tryLoadBibliography()163     void lcl_tryLoadBibliography()
164     {
165         // lp#527938, debian#602953, fdo#33266, i#105408
166         // make sure we actually can instantiate services from base first
167         if(!lcl_isBaseAvailable())
168         {
169             if (officecfg::Office::Common::PackageKit::EnableBaseInstallation::get())
170             {
171                 try
172                 {
173                     using namespace org::freedesktop::PackageKit;
174                     using namespace svtools;
175                     Reference< XSyncDbusSessionHelper > xSyncDbusSessionHelper(SyncDbusSessionHelper::create(comphelper::getProcessComponentContext()));
176                     Sequence< OUString > vPackages { u"libreoffice-base"_ustr };
177                     xSyncDbusSessionHelper->InstallPackageNames(vPackages, OUString());
178                     // I'll be back (hopefully)!
179                     SolarMutexGuard aGuard;
180                     executeRestartDialog(comphelper::getProcessComponentContext(), nullptr, RESTART_REASON_BIBLIOGRAPHY_INSTALL);
181                 }
182                 catch (const Exception &)
183                 {
184                     TOOLS_INFO_EXCEPTION("sfx.appl", "trying to install LibreOffice Base");
185                 }
186             }
187             return;
188         }
189 
190         try // fdo#48775
191         {
192             SfxStringItem aURL(SID_FILE_NAME, u".component:Bibliography/View1"_ustr);
193             SfxStringItem aRef(SID_REFERER, u"private:user"_ustr);
194             SfxStringItem aTarget(SID_TARGETNAME, u"_blank"_ustr);
195             if (const SfxViewFrame* pViewFrame = SfxViewFrame::Current())
196             {
197                 pViewFrame->GetDispatcher()->ExecuteList(SID_OPENDOC,
198                         SfxCallMode::ASYNCHRON, { &aURL, &aRef, &aTarget });
199             }
200         }
201         catch (const Exception &)
202         {
203             TOOLS_INFO_EXCEPTION( "sfx.appl", "trying to load bibliography database");
204         }
205     }
lcl_disableActiveEmbeddedObjects(SfxObjectShell * pObjSh)206     void lcl_disableActiveEmbeddedObjects(SfxObjectShell* pObjSh)
207     {
208         if (!pObjSh)
209             return;
210 
211         comphelper::EmbeddedObjectContainer& rContainer = pObjSh->getEmbeddedObjectContainer();
212         if (!rContainer.HasEmbeddedObjects())
213             return;
214 
215         const uno::Sequence<OUString> aNames = rContainer.GetObjectNames();
216         for (const auto& rName : aNames)
217         {
218             uno::Reference<embed::XEmbeddedObject> xEmbeddedObj
219                 = rContainer.GetEmbeddedObject(rName);
220             if (!xEmbeddedObj.is())
221                 continue;
222 
223             try
224             {
225                 if (xEmbeddedObj->getCurrentState() != embed::EmbedStates::LOADED)
226                 {
227                     xEmbeddedObj->changeState(embed::EmbedStates::LOADED);
228                 }
229             }
230             catch (const uno::Exception&)
231             {
232             }
233         }
234     }
235 }
236 /// Find the correct location of the document (CREDITS.fodt, etc.), and return
237 /// it in rURL if found.
checkURL(const char * pName,const char * pExt,OUString & rURL)238 static bool checkURL( const char *pName, const char *pExt, OUString &rURL )
239 {
240     using namespace osl;
241     DirectoryItem aDirItem;
242 
243 #ifdef MACOSX
244     rURL = "$BRAND_BASE_DIR/Resources/" + OUString::createFromAscii( pName ) +
245            OUString::createFromAscii( pExt );
246 #else
247     rURL = "$BRAND_BASE_DIR/" + OUString::createFromAscii( pName ) +
248            OUString::createFromAscii( pExt );
249 #endif
250     rtl::Bootstrap::expandMacros( rURL );
251 
252     if (!rURL.isEmpty())
253         return DirectoryItem::get( rURL, aDirItem ) == DirectoryItem::E_None;
254     else
255         return false;
256 }
257 
258 /// Displays CREDITS or LICENSE in any of the available version
showDocument(const char * pBaseName)259 static void showDocument( const char* pBaseName )
260 {
261     try {
262         Reference < XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );
263         auto args(::comphelper::InitPropertySequence({
264             {"ViewOnly",    Any(true)},
265             {"ReadOnly",    Any(true)}
266         }));
267 
268         OUString aURL;
269         if ( checkURL ( pBaseName, ".fodt", aURL ) ||
270              checkURL ( pBaseName, ".html", aURL ) ||
271              checkURL ( pBaseName, "", aURL ) ) {
272             xDesktop->loadComponentFromURL( aURL, u"_blank"_ustr, 0, args );
273         }
274     } catch (const css::uno::Exception &) {
275     }
276 }
277 
278 namespace
279 {
GetRequestFrame(const SfxRequest & rReq)280     Reference<XFrame> GetRequestFrame(const SfxRequest& rReq)
281     {
282         const SfxItemSet* pArgs = rReq.GetInternalArgs_Impl();
283         const SfxUnoFrameItem* pItem = nullptr;
284         Reference <XFrame> xFrame;
285         if (pArgs && (pItem = pArgs->GetItemIfSet(SID_FILLFRAME, false)))
286         {
287             xFrame = pItem->GetFrame();
288         }
289         return xFrame;
290     }
291 
GetDocFrame(const SfxRequest & rReq)292     Reference<XFrame> GetDocFrame(const SfxRequest& rReq)
293     {
294         const SfxFrameItem* pFrameItem = rReq.GetArg<SfxFrameItem>(SID_DOCFRAME);
295         SfxFrame* pFrame = pFrameItem ? pFrameItem->GetFrame() : nullptr;
296         return pFrame ? pFrame->GetFrameInterface() : nullptr;
297     }
298 
299     class LicenseDialog : public weld::GenericDialogController
300     {
301     public:
LicenseDialog(weld::Window * pParent)302         LicenseDialog(weld::Window* pParent)
303             : GenericDialogController(pParent, u"sfx/ui/licensedialog.ui"_ustr,  u"LicenseDialog"_ustr)
304         {
305         }
306 
run()307         virtual short run() override
308         {
309             short nRet = GenericDialogController::run();
310             if (nRet == RET_OK)
311                 showDocument("LICENSE");
312             return nRet;
313         }
314     };
315 
316     class SafeModeQueryDialog : public weld::MessageDialogController
317     {
318     public:
SafeModeQueryDialog(weld::Window * pParent)319         SafeModeQueryDialog(weld::Window* pParent)
320             : MessageDialogController(pParent, u"sfx/ui/safemodequerydialog.ui"_ustr, u"SafeModeQueryDialog"_ustr)
321         {
322         }
323 
run()324         virtual short run() override
325         {
326             short nRet = MessageDialogController::run();
327             if (nRet == RET_OK)
328             {
329                 sfx2::SafeMode::putFlag();
330                 uno::Reference< uno::XComponentContext > xContext = comphelper::getProcessComponentContext();
331                 css::task::OfficeRestartManager::get(xContext)->requestRestart(
332                     css::uno::Reference< css::task::XInteractionHandler >());
333             }
334             return nRet;
335         }
336     };
337 }
338 
GetFrameWeld() const339 weld::Window* SfxRequest::GetFrameWeld() const
340 {
341     const SfxItemSet* pIntArgs = GetInternalArgs_Impl();
342     const SfxUnoAnyItem* pItem = nullptr;
343     if (pIntArgs && (pItem = pIntArgs->GetItemIfSet(SID_DIALOG_PARENT, false)))
344     {
345         auto aAny = pItem->GetValue();
346         Reference<awt::XWindow> xWindow;
347         aAny >>= xWindow;
348         return Application::GetFrameWeld(xWindow);
349     }
350 
351     Reference<XFrame> xFrame(GetRequestFrame(*this));
352     if (!xFrame)
353         xFrame = GetDocFrame(*this);
354     if (!xFrame)
355     {
356         SAL_WARN("sfx.appl", "no parent for dialogs");
357         return nullptr;
358     }
359     return Application::GetFrameWeld(xFrame->getContainerWindow());
360 }
361 
MiscExec_Impl(SfxRequest & rReq)362 void SfxApplication::MiscExec_Impl( SfxRequest& rReq )
363 {
364     bool bDone = false;
365     switch ( rReq.GetSlot() )
366     {
367         case SID_SETOPTIONS:
368         {
369             if( rReq.GetArgs() )
370                 SetOptions( *rReq.GetArgs() );
371             break;
372         }
373 
374         case SID_QUITAPP:
375         case SID_LOGOUT:
376         {
377             // protect against reentrant calls and avoid closing the same files in parallel
378             if (pImpl->bInQuit || pImpl->bClosingDocs)
379                 return;
380 
381             if ( rReq.GetSlot() == SID_LOGOUT )
382             {
383                 for ( SfxObjectShell *pObjSh = SfxObjectShell::GetFirst();
384                     pObjSh; pObjSh = SfxObjectShell::GetNext( *pObjSh ) )
385                 {
386                     if ( !pObjSh->IsModified() )
387                         continue;
388 
389                     SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pObjSh );
390                     if ( !pFrame || !pFrame->GetWindow().IsReallyVisible() )
391                         continue;
392 
393                     if (pObjSh->PrepareClose())
394                         pObjSh->SetModified( false );
395                     else
396                         return;
397                 }
398 
399                 SfxStringItem aNameItem( SID_FILE_NAME, u"vnd.sun.star.cmd:logout"_ustr );
400                 SfxStringItem aReferer( SID_REFERER, u"private/user"_ustr );
401                 pImpl->pAppDispat->ExecuteList(SID_OPENDOC,
402                         SfxCallMode::SLOT, { &aNameItem, &aReferer });
403                 return;
404             }
405 
406             // try from nested requests again after 100ms
407             if( Application::GetDispatchLevel() > 1 )
408             {
409                 /* Don't save the request for closing the application and try it later
410                    again. This is an UI bound functionality ... and the user will  try it again
411                    if the dialog is closed. But we should not close the application automatically
412                    if this dialog is closed by the user ...
413                    So we ignore this request now and wait for a new user decision.
414                 */
415                 SAL_INFO("sfx.appl", "QueryExit => sal_False, DispatchLevel == " << Application::GetDispatchLevel() );
416                 return;
417             }
418 
419             // block reentrant calls
420             pImpl->bInQuit = true;
421             Reference < XDesktop2 > xDesktop = Desktop::create ( ::comphelper::getProcessComponentContext() );
422 
423             rReq.ForgetAllArgs();
424 
425             // if terminate() failed, pImpl->bInQuit will now be sal_False, allowing further calls of SID_QUITAPP
426             bool bTerminated = xDesktop->terminate();
427             if (!bTerminated)
428                 // if terminate() was successful, SfxApplication is now dead!
429                 pImpl->bInQuit = false;
430 
431             // Set return value, terminate if possible
432             rReq.SetReturnValue( SfxBoolItem( rReq.GetSlot(), bTerminated ) );
433             return;
434         }
435 
436         case SID_CONFIG:
437         case SID_TOOLBOXOPTIONS:
438         case SID_CONFIGSTATUSBAR:
439         case SID_CONFIGMENU:
440         case SID_CONFIGACCEL:
441         case SID_CONFIGEVENT:
442         {
443             SfxAbstractDialogFactory* pFact =
444                 SfxAbstractDialogFactory::Create();
445 
446             const SfxStringItem* pStringItem = rReq.GetArg<SfxStringItem>(SID_CONFIG);
447 
448             SfxItemSetFixed<SID_CONFIG, SID_CONFIG, SID_MACROINFO, SID_MACROINFO> aSet( GetPool() );
449 
450             // SID_CONFIG property will determine the default page shown
451             if ( pStringItem )
452             {
453                 aSet.Put( SfxStringItem(
454                     SID_CONFIG, pStringItem->GetValue() ) );
455             }
456             else if (rReq.GetSlot() == SID_CONFIGEVENT)
457             {
458                 aSet.Put( SfxStringItem(
459                     SID_CONFIG, u"private:resource/event/"_ustr ) );
460             }
461             else if (rReq.GetSlot() == SID_TOOLBOXOPTIONS)
462             {
463                 aSet.Put( SfxStringItem(
464                     SID_CONFIG, u"private:resource/toolbar/"_ustr ) );
465             }
466 
467 #if HAVE_FEATURE_SCRIPTING
468             // Preselect a macro in the 'keyboard' page
469             if (auto const item = rReq.GetArg<SfxMacroInfoItem>(SID_MACROINFO)) {
470                 aSet.Put(*item);
471             }
472 #endif
473 
474             Reference <XFrame> xFrame(GetRequestFrame(rReq));
475             ScopedVclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateCustomizeTabDialog(rReq.GetFrameWeld(),
476                 &aSet, xFrame ));
477 
478             const short nRet = pDlg->Execute();
479 
480             if ( nRet )
481                 bDone = true;
482             break;
483         }
484 
485         case SID_CLOSEDOCS:
486         {
487             // protect against reentrant calls and avoid closing the same files in parallel
488             if (pImpl->bInQuit || pImpl->bClosingDocs)
489                 return;
490 
491             pImpl->bClosingDocs = true;
492             // closed all status for all visible frames
493             bool bClosedAll = true;
494 
495             // Iterate over all documents and close them
496             for (SfxObjectShell *pObjSh = SfxObjectShell::GetFirst(); pObjSh;)
497             {
498                 SfxObjectShell* pNxtObjSh = SfxObjectShell::GetNext(*pObjSh);
499                 // can close immediately
500                 if (!pObjSh->IsModified() || pObjSh->isSaveLocked())
501                 {
502                     // don't close the last remaining frame for close dispatch
503                     if (pNxtObjSh || !bClosedAll)
504                         pObjSh->DoClose();
505                 }
506                 else
507                 {
508                     // skip invisible frames when asking user to close
509                     SfxViewFrame* pFrame = SfxViewFrame::GetFirst(pObjSh);
510                     if (pFrame && pFrame->GetWindow().IsReallyVisible())
511                     {
512                         // asks user to close
513                         if (pObjSh->PrepareClose())
514                         {
515                             pObjSh->SetModified(false);
516                             // get next pointer again after asking user since it can become invalid pointer from being manually closed by user
517                             // don't close the last remaining frame for close dispatch
518                             if ((pNxtObjSh = SfxObjectShell::GetNext(*pObjSh)) || !bClosedAll)
519                                 pObjSh->DoClose();
520                         }
521                         // user disagrees to close
522                         else
523                         {
524                             bClosedAll = false;
525                             // get next pointer again after asking user since it can become invalid pointer from being manually closed by user
526                             pNxtObjSh = SfxObjectShell::GetNext(*pObjSh);
527                         }
528                     }
529                 }
530                 pObjSh = pNxtObjSh;
531             }
532 
533             pImpl->bClosingDocs = false;
534 
535             // close dispatch status
536             bool bDispatchOk = true;
537             // open backing window
538             if (bClosedAll)
539             {
540                 // don't use pViewFrame = SfxViewFrame::Current() as dispatch won't load sometimes
541                 SfxObjectShell* pObjSh = SfxObjectShell::GetFirst();
542                 SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst(pObjSh);
543                 if (pViewFrame)
544                 {
545                     Reference<XFrame> xCurrentFrame = pViewFrame->GetFrame().GetFrameInterface();
546                     if (xCurrentFrame.is())
547                     {
548                         uno::Reference<frame::XDispatchProvider> xProvider(xCurrentFrame, uno::UNO_QUERY);
549                         if (xProvider.is())
550                         {
551                             uno::Reference<frame::XDispatchHelper> xDispatcher
552                                 = frame::DispatchHelper::create(::comphelper::getProcessComponentContext());
553                             // use .uno:CloseDoc to be able to close windows of the same document
554                             css::uno::Any aResult =
555                                 xDispatcher->executeDispatch(xProvider,
556                                                              u".uno:CloseDoc"_ustr,
557                                                              u"_self"_ustr,
558                                                              0,
559                                                              uno::Sequence<beans::PropertyValue>());
560                             css::frame::DispatchResultEvent aEvent;
561                             bDispatchOk = (aResult >>= aEvent) && (aEvent.State == frame::DispatchResultState::SUCCESS);
562                         }
563                     }
564                 }
565             }
566             // terminate the application if the dispatch fails or
567             // if there is no visible frame left after the command is run (e.g user manually closes the document again that was already cancelled for closing)
568             if (!bDispatchOk || (!bClosedAll && !SfxObjectShell::GetFirst()))
569             {
570                 SfxRequest aReq(SID_QUITAPP, SfxCallMode::SLOT, GetPool());
571                 MiscExec_Impl(aReq);
572             }
573 
574             rReq.SetReturnValue(SfxBoolItem(0, bDispatchOk));
575             bDone = true;
576             break;
577         }
578 
579         case SID_SAVEDOCS:
580         {
581             bool bOK = true;
582             for ( SfxObjectShell *pObjSh = SfxObjectShell::GetFirst();
583                   pObjSh;
584                   pObjSh = SfxObjectShell::GetNext( *pObjSh ) )
585             {
586                 SfxRequest aReq( SID_SAVEDOC, SfxCallMode::SLOT, pObjSh->GetPool() );
587                 if ( pObjSh->IsModified() && !pObjSh->isSaveLocked() )
588                 {
589                     pObjSh->ExecuteSlot( aReq );
590                     const SfxBoolItem* pItem(dynamic_cast<const SfxBoolItem*>(aReq.GetReturnValue().getItem()));
591                     if ( !pItem || !pItem->GetValue() )
592                         bOK = false;
593                 }
594             }
595 
596             rReq.SetReturnValue( SfxBoolItem( 0, bOK ) );
597             rReq.Done();
598             break;
599         }
600 
601         case SID_SEND_FEEDBACK:
602         {
603             OUString module = SfxHelp::GetCurrentModuleIdentifier();
604             OUString sURL(officecfg::Office::Common::Menus::SendFeedbackURL::get() + //officecfg/registry/data/org/openoffice/Office/Common.xcu => https://hub.libreoffice.org/send-feedback/
605                 "?LOversion=" + utl::ConfigManager::getAboutBoxProductVersion() +
606                 "&LOlocale=" + utl::ConfigManager::getUILocale() +
607                 "&LOmodule=" + module.subView(module.lastIndexOf('.') + 1 )  );
608             sfx2::openUriExternally(sURL, false, rReq.GetFrameWeld());
609             break;
610         }
611 
612         case SID_Q_AND_A:
613         {
614             // Askbot has URL's normalized to languages, not locales
615             // Get language from locale: ll or lll or ll-CC or lll-CC
616 
617             OUString sURL(officecfg::Office::Common::Menus::QA_URL::get() + //https://hub.libreoffice.org/forum/
618                 "?LOlocale=" + utl::ConfigManager::getUILocale());
619             sfx2::openUriExternally(sURL, false, rReq.GetFrameWeld());
620             break;
621         }
622         case SID_DOCUMENTATION:
623         {
624             // Open documentation page based on locales
625             OUString sURL(officecfg::Office::Common::Menus::DocumentationURL::get() + //https://hub.libreoffice.org/documentation/
626                 "?LOlocale=" + utl::ConfigManager::getUILocale());
627             sfx2::openUriExternally(sURL, false, rReq.GetFrameWeld());
628             break;
629         }
630 #if !ENABLE_WASM_STRIP_PINGUSER
631         case SID_GETINVOLVED:
632         {
633             // Open get involved/join us page based on locales
634             OUString sURL(officecfg::Office::Common::Menus::GetInvolvedURL::get() + //https://hub.libreoffice.org/joinus/
635                 "?LOlocale=" + utl::ConfigManager::getUILocale());
636             sfx2::openUriExternally(sURL, false, rReq.GetFrameWeld());
637             break;
638         }
639         case SID_DONATION:
640         {
641             // Open donation page based on language + script (BCP47) with language as fall back.
642             OUString aLang = LanguageTag(utl::ConfigManager::getUILocale()).getLanguage();
643             OUString aBcp47 = LanguageTag(utl::ConfigManager::getUILocale()).getBcp47();
644             OUString sURL(officecfg::Office::Common::Menus::DonationURL::get() + //https://hub.libreoffice.org/donation/
645                 "?BCP47=" + aBcp47 + "&LOlang=" + aLang );
646             sfx2::openUriExternally(sURL, false, rReq.GetFrameWeld());
647             break;
648         }
649         case SID_WHATSNEW:
650         {
651             // Open release notes depending on version and locale
652             OUString sURL(officecfg::Office::Common::Menus::ReleaseNotesURL::get() + //https://hub.libreoffice.org/ReleaseNotes/
653                 "?LOvers=" + utl::ConfigManager::getProductVersion() +
654                 "&LOlocale=" + LanguageTag(utl::ConfigManager::getUILocale()).getBcp47() );
655             sfx2::openUriExternally(sURL, false, rReq.GetFrameWeld());
656             break;
657         }
658         case SID_HYPHENATIONMISSING:
659         {
660             // Open wiki page about hyphenation
661             OUString sURL(officecfg::Office::Common::Menus::HyphenationMissingURL::get() + //https://hub.libreoffice.org/HyphenationMissing/
662                 "?LOlocale=" + utl::ConfigManager::getUILocale());
663             sfx2::openUriExternally(sURL, false, rReq.GetFrameWeld());
664             break;
665         }
666 #endif
667         case SID_SHOW_LICENSE:
668         {
669             LicenseDialog aDialog(rReq.GetFrameWeld());
670             aDialog.run();
671             break;
672         }
673 
674         case SID_SHOW_CREDITS:
675         {
676             showDocument( "CREDITS" );
677             break;
678         }
679 
680         case FN_CHANGE_THEME:
681         {
682             const SfxStringItem* pNewThemeArg = rReq.GetArg<SfxStringItem>(FN_PARAM_NEW_THEME);
683             OUString sSchemeName
684                 = pNewThemeArg ? pNewThemeArg->GetValue() : u"COLOR_SCHEME_LIBREOFFICE_AUTOMATIC"_ustr;
685             if (!pNewThemeArg)
686             {
687                 // toggle between light and dark mode
688 
689                 // There are two separate things that can be dark mode themed: UI and document
690                 // The modes can be 0 (automatic - what the OS/VCL asks for), 1 (light), or 2 (dark)
691 
692                 // Since only gtk/osx/win support UI theme, toggle based on document colors
693                 // Automatic in this case means "whatever GetUseDarkMode() says"
694                 const bool bWasInDarkMode
695                     = MiscSettings::GetAppColorMode() == 2
696                       || (MiscSettings::GetAppColorMode() == 0 && MiscSettings::GetUseDarkMode());
697 
698                 // Set the UI theme. It would be nicest to use automatic whenever possible
699                 sal_Int32 nUseMode = 0; // automatic
700                 if (MiscSettings::GetDarkMode() != 0)
701                     MiscSettings::SetDarkMode(nUseMode);
702 
703                 if (MiscSettings::GetUseDarkMode() == bWasInDarkMode)
704                 {
705                     // automatic didn't toggle, so force the desired theme
706                     nUseMode = bWasInDarkMode ? 1 : 2;
707                     MiscSettings::SetDarkMode(nUseMode);
708                 }
709 
710                 // Now set the document theme
711                 // If the UI can be themed, then the document theme can always remain on automatic.
712                 nUseMode = 0;
713                 // NOTE: since SetDarkMode has run, GetUseDarkMode might return a different result.
714                 if (MiscSettings::GetUseDarkMode() == bWasInDarkMode)
715                 {
716                     nUseMode = bWasInDarkMode ? 1 : 2;
717                     sSchemeName = bWasInDarkMode ? u"Light" : u"Dark";
718                 }
719                 MiscSettings::SetAppColorMode(nUseMode);
720             }
721             svtools::EditableColorConfig aEditableConfig;
722             // kit explicitly ignores changes to the global color scheme, except for the current ViewShell,
723             // so an attempted change to the same global color scheme when the now current ViewShell ignored
724             // the last change requires re-sending the change. In which case individual shells will have to
725             // decide if this color-scheme change is a change from their perspective to avoid unnecessary
726             // invalidations.
727             if (!pNewThemeArg || comphelper::LibreOfficeKit::isActive()
728                 || aEditableConfig.GetCurrentSchemeName() != sSchemeName)
729             {
730                 aEditableConfig.LoadScheme(sSchemeName);
731             }
732 
733             Invalidate(FN_CHANGE_THEME);
734             break;
735         }
736 
737         // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
738         case SID_HELPINDEX:
739         {
740             Help* pHelp = Application::GetHelp();
741             if ( pHelp )
742             {
743                 pHelp->Start(u".uno:HelpIndex"_ustr, rReq.GetFrameWeld()); // show start page
744                 bDone = true;
745             }
746             break;
747         }
748 
749         // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
750         case SID_HELPTIPS:
751         {
752             // Evaluate Parameter
753             const SfxBoolItem* pOnItem = rReq.GetArg<SfxBoolItem>(SID_HELPTIPS);
754             bool bOn = pOnItem
755                             ? pOnItem->GetValue()
756                             : !Help::IsQuickHelpEnabled();
757 
758             if ( bOn )
759                 Help::EnableQuickHelp();
760             else
761                 Help::DisableQuickHelp();
762             auto xChanges = comphelper::ConfigurationChanges::create();
763             officecfg::Office::Common::Help::Tip::set(bOn, xChanges);
764             xChanges->commit();
765             Invalidate(SID_HELPTIPS);
766             bDone = true;
767 
768             // Record if possible
769             if ( !rReq.IsAPI() )
770                 rReq.AppendItem( SfxBoolItem( SID_HELPTIPS, bOn) );
771             break;
772         }
773         // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
774         case SID_EXTENDEDHELP:
775         {
776             Help::StartExtHelp();
777             break;
778         }
779         case SID_HELPBALLOONS:
780         {
781             // Evaluate Parameter
782             const SfxBoolItem* pOnItem = rReq.GetArg<SfxBoolItem>(SID_HELPBALLOONS);
783             bool bOn = pOnItem
784                             ? pOnItem->GetValue()
785                             : !Help::IsBalloonHelpEnabled();
786 
787             if ( bOn )
788                 Help::EnableBalloonHelp();
789             else
790                 Help::DisableBalloonHelp();
791             auto xChanges = comphelper::ConfigurationChanges::create();
792             officecfg::Office::Common::Help::ExtendedTip::set(bOn, xChanges);
793             xChanges->commit();
794             Invalidate(SID_HELPBALLOONS);
795             bDone = true;
796 
797             // Record if possible
798             if ( !rReq.IsAPI() )
799                 rReq.AppendItem( SfxBoolItem( SID_HELPBALLOONS, bOn) );
800             break;
801         }
802         // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
803 #if !ENABLE_WASM_STRIP_PINGUSER
804         case SID_TIPOFTHEDAY:
805         {
806             SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
807             ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateTipOfTheDayDialog(rReq.GetFrameWeld()));
808             pDlg->StartExecuteAsync(nullptr);
809             bDone = true;
810             break;
811         }
812 #endif
813         // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
814         case SID_WIDGET_TEST_DIALOG:
815         {
816             SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
817             VclPtr<VclAbstractDialog> pDlg(pFact->CreateWidgetTestDialog(rReq.GetFrameWeld()));
818             pDlg->StartExecuteAsync([pDlg](sal_Int32 /*nResult*/){
819                 pDlg->disposeOnce();
820             });
821             bDone = true;
822             break;
823         }
824 
825         // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
826         case SID_ABOUT:
827         {
828             SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
829             ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateAboutDialog(rReq.GetFrameWeld()));
830             pDlg->StartExecuteAsync(nullptr);
831             bDone = true;
832             break;
833         }
834 
835         case SID_TEMPLATE_MANAGER:
836         {
837             SfxTemplateManagerDlg aDialog(rReq.GetFrameWeld());
838             aDialog.run();
839             bDone = true;
840             break;
841         }
842 
843         case SID_TEMPLATE_ADDRESSBOOKSOURCE:
844         {
845             svt::AddressBookSourceDialog aDialog(rReq.GetFrameWeld(), ::comphelper::getProcessComponentContext());
846             aDialog.run();
847             bDone = true;
848             break;
849         }
850 
851 #if HAVE_FEATURE_SCRIPTING
852         case SID_BASICSTOP:
853             StarBASIC::Stop();
854             break;
855 
856         case SID_BASICBREAK :
857             BasicDLL::BasicBreak();
858             break;
859 #endif
860 
861         case SID_ZOOM_50_PERCENT:
862         case SID_ZOOM_75_PERCENT:
863         case SID_ZOOM_100_PERCENT:
864         case SID_ZOOM_150_PERCENT:
865         case SID_ZOOM_200_PERCENT:
866         case SID_ZOOM_OPTIMAL:
867         case SID_ZOOM_ENTIRE_PAGE:
868         case SID_ZOOM_PAGE_WIDTH:
869         {
870             SfxObjectShell* pCurrentShell = SfxObjectShell::Current();
871             if (!pCurrentShell)
872                 return;
873 
874             // make sure aZoom is initialized with a proper value if SetType
875             // doesn't work
876             SvxZoomItem aZoom( SvxZoomType::PERCENT, 100 );
877 
878             switch (rReq.GetSlot())
879             {
880                 case SID_ZOOM_50_PERCENT:
881                     aZoom.SetValue(50);
882                     break;
883                 case SID_ZOOM_75_PERCENT:
884                     aZoom.SetValue(75);
885                     break;
886                 case SID_ZOOM_100_PERCENT:
887                     aZoom.SetValue(100);
888                     break;
889                 case SID_ZOOM_150_PERCENT:
890                     aZoom.SetValue(150);
891                     break;
892                 case SID_ZOOM_200_PERCENT:
893                     aZoom.SetValue(200);
894                     break;
895                 case SID_ZOOM_OPTIMAL:
896                     aZoom.SetType( SvxZoomType::OPTIMAL );
897                     break;
898                 case SID_ZOOM_ENTIRE_PAGE:
899                     aZoom.SetType( SvxZoomType::WHOLEPAGE );
900                     break;
901                 case SID_ZOOM_PAGE_WIDTH:
902                     aZoom.SetType( SvxZoomType::PAGEWIDTH );
903                     break;
904             }
905 
906             pCurrentShell->GetDispatcher()->ExecuteList(SID_ATTR_ZOOM, SfxCallMode::ASYNCHRON, { &aZoom });
907 
908             break;
909         }
910         case SID_TOOLBAR_MODE:
911         {
912             const SfxStringItem* pModeName = rReq.GetArg<SfxStringItem>( SID_TOOLBAR_MODE );
913 
914             if ( !pModeName )
915             {
916                 bDone = true;
917                 break;
918             }
919 
920             OUString aNewName(pModeName->GetValue());
921             uno::Reference< uno::XComponentContext > xContext =
922                     ::comphelper::getProcessComponentContext();
923 
924             // Get information about current frame and module
925             Reference<XFrame> xCurrentFrame;
926             vcl::EnumContext::Application eCurrentApp = vcl::EnumContext::Application::NONE;
927             OUString aCurrentMode;
928 
929             SfxViewFrame* pViewFrame = SfxViewFrame::Current();
930             if (pViewFrame)
931             {
932                 xCurrentFrame = pViewFrame->GetFrame().GetFrameInterface();
933 
934                 const Reference<frame::XModuleManager> xModuleManager  = frame::ModuleManager::create( xContext );
935                 eCurrentApp = vcl::EnumContext::GetApplicationEnum( xModuleManager->identify( xCurrentFrame ) );
936 
937                 OUString aPath = "org.openoffice.Office.UI.ToolbarMode/Applications/" +
938                     lcl_getAppName( eCurrentApp );
939 
940                 const utl::OConfigurationTreeRoot aAppNode(
941                                                     xContext,
942                                                     aPath,
943                                                     true);
944                 if ( !aAppNode.isValid() )
945                 {
946                     bDone = true;
947                     break;
948                 }
949 
950                 aCurrentMode = comphelper::getString( aAppNode.getNodeValue( u"Active"_ustr ) );
951 
952                 if ( !comphelper::LibreOfficeKit::isActive() && aCurrentMode == aNewName )
953                 {
954                     bDone = true;
955                     break;
956                 }
957 
958                 // Save new toolbar mode for a current module
959                 aAppNode.setNodeValue( u"Active"_ustr, Any( aNewName ) );
960                 aAppNode.commit();
961             }
962 
963             // Apply settings for all frames
964             pViewFrame = SfxViewFrame::GetFirst();
965             while( pViewFrame )
966             {
967                 // in LOK case we want to apply changes only to the current view
968                 if (comphelper::LibreOfficeKit::isActive() &&
969                     pViewFrame != &SfxViewShell::Current()->GetViewFrame())
970                 {
971                     pViewFrame = SfxViewFrame::GetNext( *pViewFrame );
972                     continue;
973                 }
974 
975                 Reference<XFrame> xFrame = pViewFrame->GetFrame().GetFrameInterface();
976 
977                 // We want to change mode only for a current app module, ignore other apps
978                 const Reference<frame::XModuleManager> xModuleManager  = frame::ModuleManager::create( xContext );
979                 vcl::EnumContext::Application eApp = vcl::EnumContext::GetApplicationEnum( xModuleManager->identify( xFrame ) );
980                 if ( eApp != eCurrentApp )
981                 {
982                     pViewFrame = SfxViewFrame::GetNext( *pViewFrame );
983                     continue;
984                 }
985 
986                 Reference<css::beans::XPropertySet> xPropSet( xFrame, UNO_QUERY );
987                 Reference<css::frame::XLayoutManager> xLayoutManager;
988                 if ( xPropSet.is() )
989                 {
990                     try
991                     {
992                         Any aValue = xPropSet->getPropertyValue( u"LayoutManager"_ustr );
993                         aValue >>= xLayoutManager;
994                     }
995                     catch ( const css::uno::RuntimeException& )
996                     {
997                         throw;
998                     }
999                     catch ( css::uno::Exception& )
1000                     {
1001                     }
1002                 }
1003 
1004                 if ( xLayoutManager.is() )
1005                 {
1006                     css::uno::Sequence<OUString> aMandatoryToolbars;
1007                     css::uno::Sequence<OUString> aUserToolbars;
1008                     std::vector<OUString> aBackupList;
1009                     OUString aSidebarMode;
1010 
1011                     OUString aPath = "org.openoffice.Office.UI.ToolbarMode/Applications/" +
1012                         lcl_getAppName( eApp ) +
1013                         "/Modes";
1014 
1015                     // Read mode settings
1016                     const utl::OConfigurationTreeRoot aModesNode(
1017                                             xContext,
1018                                             aPath,
1019                                             true);
1020                     if ( !aModesNode.isValid() )
1021                     {
1022                         bDone = true;
1023                         break;
1024                     }
1025 
1026                     const Sequence<OUString> aModeNodeNames( aModesNode.getNodeNames() );
1027 
1028                     for ( const auto& rModeNodeName : aModeNodeNames )
1029                     {
1030                         const utl::OConfigurationNode aModeNode( aModesNode.openNode( rModeNodeName ) );
1031                         if ( !aModeNode.isValid() )
1032                             continue;
1033 
1034                         OUString aCommandArg = comphelper::getString( aModeNode.getNodeValue( u"CommandArg"_ustr ) );
1035 
1036                         if ( aCommandArg == aNewName )
1037                         {
1038                             aMandatoryToolbars = aModeNode.getNodeValue( u"Toolbars"_ustr ).get< uno::Sequence<OUString> >();
1039                             aUserToolbars = aModeNode.getNodeValue( u"UserToolbars"_ustr ).get< uno::Sequence<OUString> >();
1040                             aSidebarMode = comphelper::getString( aModeNode.getNodeValue( u"Sidebar"_ustr ) );
1041                             break;
1042                         }
1043                     }
1044 
1045                     // Backup visible toolbar list and hide all toolbars
1046                     const Sequence<Reference<XUIElement>> aUIElements = xLayoutManager->getElements();
1047                     for ( const Reference< XUIElement >& xUIElement : aUIElements )
1048                     {
1049                         Reference< XPropertySet > xPropertySet( xUIElement, UNO_QUERY );
1050                         if ( xPropertySet.is() && xUIElement.is() )
1051                         {
1052                             try
1053                             {
1054                                 OUString aResName;
1055                                 sal_Int16 nType( -1 );
1056                                 xPropertySet->getPropertyValue( u"Type"_ustr ) >>= nType;
1057                                 xPropertySet->getPropertyValue( u"ResourceURL"_ustr ) >>= aResName;
1058 
1059                                 if (( nType == css::ui::UIElementType::TOOLBAR ) &&
1060                                     !aResName.isEmpty() )
1061                                 {
1062                                     if ( xLayoutManager->isElementVisible( aResName ) )
1063                                     {
1064                                         aBackupList.push_back( aResName );
1065                                     }
1066                                     xLayoutManager->hideElement( aResName );
1067                                 }
1068                             }
1069                             catch ( const Exception& )
1070                             {
1071                             }
1072                         }
1073                     }
1074 
1075                     // Show/Hide the Notebookbar
1076                     const SfxStringItem pItem(SID_NOTEBOOKBAR, aNewName);
1077                     pViewFrame->GetDispatcher()->ExecuteList(SID_NOTEBOOKBAR, SfxCallMode::SYNCHRON, {&pItem});
1078                     SfxPoolItemHolder aNbItem;
1079                     pViewFrame->GetDispatcher()->QueryState(SID_NOTEBOOKBAR, aNbItem);
1080 
1081                     // Show toolbars
1082                     for (const OUString& rName : aMandatoryToolbars)
1083                     {
1084                         xLayoutManager->createElement( rName );
1085                         xLayoutManager->showElement( rName );
1086                     }
1087 
1088                     for (const OUString& rName : aUserToolbars)
1089                     {
1090                         xLayoutManager->createElement( rName );
1091                         xLayoutManager->showElement( rName );
1092                     }
1093 
1094                     // Sidebar
1095                     pViewFrame->ShowChildWindow( SID_SIDEBAR );
1096 
1097                     if (comphelper::LibreOfficeKit::isActive())
1098                         aSidebarMode = "Opened";
1099 
1100                     sfx2::sidebar::SidebarController* pSidebar =
1101                             sfx2::sidebar::SidebarController::GetSidebarControllerForFrame( xFrame );
1102                     if ( pSidebar )
1103                     {
1104                         if ( aSidebarMode == "Arrow" )
1105                         {
1106                             pSidebar->FadeOut();
1107                         }
1108                         else if ( aSidebarMode == "Tabs" )
1109                         {
1110                             pSidebar->FadeIn();
1111                             pSidebar->RequestOpenDeck();
1112                             pSidebar->RequestCloseDeck();
1113                         }
1114                         else if ( aSidebarMode == "Opened" )
1115                         {
1116                             pSidebar->FadeIn();
1117                             pSidebar->RequestOpenDeck();
1118                         }
1119                     }
1120 
1121                     // Save settings
1122                     if ( pViewFrame == SfxViewFrame::Current() )
1123                     {
1124                         css::uno::Sequence<OUString> aBackup( comphelper::containerToSequence(aBackupList) );
1125 
1126                         for ( const auto& rModeNodeName : aModeNodeNames )
1127                         {
1128                             const utl::OConfigurationNode aModeNode( aModesNode.openNode( rModeNodeName ) );
1129                             if ( !aModeNode.isValid() )
1130                                 continue;
1131 
1132                             OUString aCommandArg = comphelper::getString( aModeNode.getNodeValue( u"CommandArg"_ustr ) );
1133 
1134                             if ( aCommandArg == aCurrentMode )
1135                             {
1136                                 aModeNode.setNodeValue( u"UserToolbars"_ustr, Any( aBackup ) );
1137                                 break;
1138                             }
1139                         }
1140                         aModesNode.commit();
1141                     }
1142                 }
1143 
1144                 pViewFrame = SfxViewFrame::GetNext(*pViewFrame);
1145             }
1146 
1147             bDone = true;
1148             break;
1149         }
1150         case SID_TOOLBAR_MODE_UI:
1151         {
1152             SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
1153             ScopedVclPtr<VclAbstractDialog> pDlg(
1154                 pFact->CreateToolbarmodeDialog(rReq.GetFrameWeld()));
1155             pDlg->Execute();
1156             bDone = true;
1157             break;
1158         }
1159         case SID_AVAILABLE_TOOLBARS:
1160         {
1161             const SfxStringItem* pToolbarName = rReq.GetArg<SfxStringItem>(SID_AVAILABLE_TOOLBARS);
1162 
1163             if ( pToolbarName )
1164             {
1165                 Reference < XDesktop2 > xDesktop = Desktop::create ( ::comphelper::getProcessComponentContext() );
1166                 Reference< XFrame > xFrame = xDesktop->getActiveFrame();
1167 
1168                 Reference< css::beans::XPropertySet > xPropSet( xFrame, UNO_QUERY );
1169                 Reference< css::frame::XLayoutManager > xLayoutManager;
1170                 if ( xPropSet.is() )
1171                 {
1172                     try
1173                     {
1174                         Any aValue = xPropSet->getPropertyValue(u"LayoutManager"_ustr);
1175                         aValue >>= xLayoutManager;
1176                     }
1177                     catch ( const css::uno::RuntimeException& )
1178                     {
1179                         throw;
1180                     }
1181                     catch ( css::uno::Exception& )
1182                     {
1183                     }
1184                 }
1185 
1186                 if ( xLayoutManager.is() )
1187                 {
1188                     OUString aToolbarName = "private:resource/toolbar/" +
1189                         pToolbarName->GetValue();
1190 
1191                     // Evaluate Parameter
1192                     bool bShow( !xLayoutManager->isElementVisible( aToolbarName ));
1193 
1194                     if ( bShow )
1195                     {
1196                         xLayoutManager->createElement( aToolbarName );
1197                         xLayoutManager->showElement( aToolbarName );
1198                     }
1199                     else
1200                         xLayoutManager->hideElement( aToolbarName );
1201                 }
1202             }
1203 
1204             bDone = true;
1205             break;
1206         }
1207         case SID_MENUBAR:
1208         {
1209             sfx2::SfxNotebookBar::ToggleMenubar();
1210             bDone = true;
1211             break;
1212         }
1213         case SID_DEVELOPMENT_TOOLS_DOCKING_WINDOW:
1214         {
1215             SfxViewShell* pViewShell = SfxViewShell::Current();
1216             SfxViewFrame& rViewFrame = pViewShell->GetViewFrame();
1217             auto nID = rReq.GetSlot();
1218             rViewFrame.ToggleChildWindow(nID);
1219 
1220             bDone = true;
1221             break;
1222         }
1223         case SID_INSPECT_SELECTED_OBJECT:
1224         {
1225             SfxViewShell* pViewShell = SfxViewShell::Current();
1226             SfxViewFrame& rViewFrame = pViewShell->GetViewFrame();
1227 
1228             rViewFrame.ShowChildWindow(SID_DEVELOPMENT_TOOLS_DOCKING_WINDOW, true);
1229 
1230             SfxChildWindow* pChild = rViewFrame.GetChildWindow(SID_DEVELOPMENT_TOOLS_DOCKING_WINDOW);
1231             if (!pChild)
1232                 return;
1233 
1234             auto pDockingWin = dynamic_cast<DevelopmentToolDockingWindow*>(pChild->GetWindow());
1235             if (pDockingWin)
1236             {
1237                 pDockingWin->changeToCurrentSelection();
1238             }
1239 
1240             bDone = true;
1241             break;
1242         }
1243         case SID_SAFE_MODE:
1244         {
1245             SafeModeQueryDialog aDialog(rReq.GetFrameWeld());
1246             aDialog.run();
1247             break;
1248         }
1249         case SID_TOOLBAR_LOCK:
1250         {
1251             if (SfxViewFrame* pViewFrame = SfxViewFrame::Current())
1252             {
1253                 Reference<XFrame> xCurrentFrame;
1254                 uno::Reference<uno::XComponentContext> xContext
1255                     = ::comphelper::getProcessComponentContext();
1256                 xCurrentFrame = pViewFrame->GetFrame().GetFrameInterface();
1257                 const Reference<frame::XModuleManager> xModuleManager
1258                     = frame::ModuleManager::create(xContext);
1259                 const utl::OConfigurationTreeRoot aAppNode(
1260                     xContext, u"org.openoffice.Office.UI.GlobalSettings/Toolbars/States"_ustr, true);
1261                 if (aAppNode.isValid())
1262                 {
1263                     bool isLocked = comphelper::getBOOL(aAppNode.getNodeValue(u"Locked"_ustr));
1264                     aAppNode.setNodeValue(u"Locked"_ustr, Any(!isLocked));
1265                     aAppNode.commit();
1266                     //TODO: apply immediately w/o restart needed
1267                     SolarMutexGuard aGuard;
1268                     svtools::executeRestartDialog(comphelper::getProcessComponentContext(), nullptr,
1269                                                   svtools::RESTART_REASON_UI_CHANGE);
1270                 }
1271             }
1272             break;
1273         }
1274         default:
1275             break;
1276     }
1277 
1278     if ( bDone )
1279         rReq.Done();
1280 }
1281 
MiscState_Impl(SfxItemSet & rSet)1282 void SfxApplication::MiscState_Impl(SfxItemSet &rSet)
1283 {
1284     const WhichRangesContainer & pRanges = rSet.GetRanges();
1285     DBG_ASSERT(!pRanges.empty(), "Set without range");
1286     for ( auto const & pRange : pRanges )
1287     {
1288         for(sal_uInt16 nWhich = pRange.first; nWhich <= pRange.second; ++nWhich)
1289         {
1290             switch(nWhich)
1291             {
1292                 case SID_TEMPLATE_ADDRESSBOOKSOURCE:
1293                     if ( !SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::EModule::DATABASE) )
1294                         rSet.Put(SfxVisibilityItem(nWhich, false));
1295                     break;
1296                 case SID_QUITAPP:
1297                 {
1298                     if (pImpl->nDocModalMode || pImpl->bClosingDocs)
1299                         rSet.DisableItem(nWhich);
1300                     else
1301                         rSet.Put(SfxStringItem(nWhich, SfxResId(STR_QUITAPP)));
1302                     break;
1303                 }
1304 
1305                 case SID_CONFIG:
1306                 case SID_TOOLBOXOPTIONS:
1307                 case SID_CONFIGSTATUSBAR:
1308                 case SID_CONFIGMENU:
1309                 case SID_CONFIGACCEL:
1310                 case SID_CONFIGEVENT:
1311                 {
1312                     if( officecfg::Office::Common::Misc::DisableUICustomization::get() )
1313                         rSet.DisableItem(nWhich);
1314                     break;
1315                 }
1316 
1317 #if HAVE_FEATURE_SCRIPTING
1318                 case SID_BASICSTOP:
1319                     if ( !StarBASIC::IsRunning() )
1320                         rSet.DisableItem(nWhich);
1321                     break;
1322 #endif
1323 
1324                 case FN_CHANGE_THEME:
1325                 {
1326                     const bool bIsDarkMode
1327                         = MiscSettings::GetAppColorMode() == 2
1328                           || (!MiscSettings::GetAppColorMode() && MiscSettings::GetUseDarkMode());
1329                     rSet.Put(SfxBoolItem(FN_CHANGE_THEME, bIsDarkMode));
1330                     break;
1331                 }
1332                 case SID_HELPTIPS:
1333                 {
1334                     rSet.Put( SfxBoolItem( SID_HELPTIPS, Help::IsQuickHelpEnabled() ) );
1335                 }
1336                 break;
1337                 case SID_HELPBALLOONS:
1338                 {
1339                     rSet.Put( SfxBoolItem( SID_HELPBALLOONS, Help::IsBalloonHelpEnabled() ) );
1340                 }
1341                 break;
1342 
1343                 case SID_EXTENDEDHELP:
1344                 {
1345                 }
1346                 break;
1347 
1348                 case SID_CLOSEDOCS:
1349                 {
1350                     if ( pImpl->nDocModalMode || pImpl->bInQuit )
1351                     {
1352                         rSet.DisableItem(nWhich);
1353                         return;
1354                     }
1355 
1356                     Reference < XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );
1357                     Reference< XIndexAccess > xTasks = xDesktop->getFrames();
1358 
1359                     if ( !xTasks.is() || !xTasks->getCount() )
1360                         rSet.DisableItem(nWhich);
1361                     break;
1362                 }
1363 
1364                 case SID_SAVEDOCS:
1365                 {
1366                     bool bModified = false;
1367                     for ( SfxObjectShell *pObjSh = SfxObjectShell::GetFirst();
1368                           pObjSh;
1369                           pObjSh = SfxObjectShell::GetNext( *pObjSh ) )
1370                     {
1371                         if ( pObjSh->IsModified() && !pObjSh->isSaveLocked() )
1372                         {
1373                             bModified = true;
1374                             break;
1375                         }
1376                     }
1377 
1378                     if ( !bModified )
1379                         rSet.DisableItem( nWhich );
1380                     break;
1381                 }
1382 
1383                 case SID_TEMPLATE_MANAGER:
1384                     {
1385                         if ( !officecfg::Office::Common::Misc::ExperimentalMode::get() )
1386                         {
1387                            rSet.DisableItem( nWhich );
1388                            rSet.Put( SfxVisibilityItem( nWhich, false ) );
1389                         }
1390                     }
1391                     break;
1392 
1393                 case SID_ZOOM_50_PERCENT:
1394                 case SID_ZOOM_75_PERCENT:
1395                 case SID_ZOOM_100_PERCENT:
1396                 case SID_ZOOM_150_PERCENT:
1397                 case SID_ZOOM_200_PERCENT:
1398                 case SID_ZOOM_OPTIMAL:
1399                 case SID_ZOOM_ENTIRE_PAGE:
1400                 case SID_ZOOM_PAGE_WIDTH:
1401                     {
1402                         SfxObjectShell* pCurrentShell(SfxObjectShell::Current());
1403 
1404                         SfxPoolItemHolder aResult;
1405                         const SfxItemState aState(pCurrentShell ?
1406                             pCurrentShell->GetDispatcher()->QueryState(SID_ATTR_ZOOM, aResult) : SfxItemState::DISABLED);
1407                         if ( aState == SfxItemState::DISABLED )
1408                             rSet.DisableItem( nWhich );
1409                     }
1410                     break;
1411 
1412                 case SID_MENUBAR:
1413                 {
1414                     Reference < XDesktop2 > xDesktop = Desktop::create ( ::comphelper::getProcessComponentContext() );
1415                     Reference< XFrame > xFrame = xDesktop->getActiveFrame();
1416 
1417                     Reference< css::beans::XPropertySet > xPropSet( xFrame, UNO_QUERY );
1418                     Reference< css::frame::XLayoutManager > xLayoutManager;
1419                     if ( xPropSet.is() )
1420                     {
1421                         try
1422                         {
1423                             Any aValue = xPropSet->getPropertyValue(u"LayoutManager"_ustr);
1424                             aValue >>= xLayoutManager;
1425                         }
1426                         catch ( const css::uno::RuntimeException& )
1427                         {
1428                             throw;
1429                         }
1430                         catch ( css::uno::Exception& )
1431                         {
1432                         }
1433                     }
1434 
1435                     if ( xLayoutManager.is() )
1436                     {
1437                         const bool bState
1438                             = xLayoutManager->getElement(u"private:resource/menubar/menubar"_ustr).is()
1439                               && xLayoutManager->isElementVisible(
1440                                      u"private:resource/menubar/menubar"_ustr);
1441 
1442                         SfxBoolItem aItem( SID_MENUBAR, bState );
1443                         rSet.Put( aItem );
1444                     }
1445                     break;
1446                 }
1447                 case SID_SAFE_MODE:
1448                 {
1449                     // no restart in safe mode when already in safe mode
1450                     if ( Application::IsSafeModeEnabled() )
1451                        rSet.DisableItem( SID_SAFE_MODE );
1452                     break;
1453                 }
1454                 case SID_DEVELOPMENT_TOOLS_DOCKING_WINDOW:
1455                 {
1456                     bool bSuccess = false;
1457                     auto* pViewShell = SfxViewShell::Current();
1458                     if (pViewShell)
1459                     {
1460                         auto& rViewFrame = pViewShell->GetViewFrame();
1461                         if (rViewFrame.KnowsChildWindow(nWhich))
1462                         {
1463                             rSet.Put(SfxBoolItem(nWhich, rViewFrame.HasChildWindow(nWhich)));
1464                             bSuccess = true;
1465                         }
1466                     }
1467 
1468                     if (!bSuccess)
1469                         rSet.DisableItem(nWhich);
1470                 }
1471                 break;
1472                 case SID_INSPECT_SELECTED_OBJECT:
1473                 {
1474                     bool bSuccess = false;
1475                     auto* pViewShell = SfxViewShell::Current();
1476                     if (pViewShell)
1477                     {
1478                         auto& rViewFrame = pViewShell->GetViewFrame();
1479                         if (rViewFrame.KnowsChildWindow(SID_DEVELOPMENT_TOOLS_DOCKING_WINDOW))
1480                         {
1481                             bSuccess = true;
1482                         }
1483                     }
1484                     if (!bSuccess)
1485                         rSet.DisableItem(nWhich);
1486                 }
1487                 break;
1488                 case SID_TOOLBAR_LOCK:
1489                 {
1490                     rSet.Put( SfxBoolItem( SID_TOOLBAR_LOCK, ToolBox::AlwaysLocked() ));
1491                 }
1492                 break;
1493                 default:
1494                     break;
1495             }
1496         }
1497     }
1498 }
1499 
1500 #if HAVE_FEATURE_SCRIPTING
1501 
1502 #ifndef DISABLE_DYNLOADING
1503 
1504 typedef rtl_uString* (*basicide_choose_macro)(void*, void*, void*, sal_Bool);
1505 
1506 #else
1507 
1508 extern "C" rtl_uString* basicide_choose_macro(void*, void*, void*, sal_Bool);
1509 
1510 #endif
1511 
ChooseMacro(weld::Window * pParent,const Reference<XModel> & rxLimitToDocument,const Reference<XFrame> & xDocFrame,bool bChooseOnly)1512 static OUString ChooseMacro(weld::Window* pParent, const Reference<XModel>& rxLimitToDocument, const Reference<XFrame>& xDocFrame, bool bChooseOnly)
1513 {
1514 #ifndef DISABLE_DYNLOADING
1515     basicide_choose_macro pSymbol = reinterpret_cast<basicide_choose_macro>(sfx2::getBasctlFunction("basicide_choose_macro"));
1516 #else
1517 #define pSymbol basicide_choose_macro
1518 #endif
1519 
1520     // call basicide_choose_macro in basctl
1521     rtl_uString* pScriptURL = pSymbol(pParent, rxLimitToDocument.get(), xDocFrame.get(), bChooseOnly);
1522     OUString aScriptURL( pScriptURL );
1523     rtl_uString_release( pScriptURL );
1524     return aScriptURL;
1525 
1526 #ifdef DISABLE_DYNLOADING
1527 #undef pSymbol
1528 #endif
1529 }
1530 
1531 #endif
1532 
1533 namespace
1534 {
1535 #if HAVE_FEATURE_SCRIPTING
lcl_getDialogParent(const Reference<XFrame> & rxFrame)1536     weld::Window* lcl_getDialogParent(const Reference<XFrame>& rxFrame)
1537     {
1538         Reference<awt::XWindow> xContainerWindow;
1539         if (rxFrame.is())
1540             xContainerWindow = rxFrame->getContainerWindow();
1541         return Application::GetFrameWeld(xContainerWindow);
1542     }
1543 
lcl_getBasicIDEViewFrame(SfxObjectShell const * i_pBasicIDE)1544     SfxViewFrame* lcl_getBasicIDEViewFrame( SfxObjectShell const * i_pBasicIDE )
1545     {
1546         SfxViewFrame* pView = SfxViewFrame::GetFirst( i_pBasicIDE );
1547         while ( pView )
1548         {
1549             if ( pView->GetObjectShell()->GetFactory().GetDocumentServiceName() == "com.sun.star.script.BasicIDE" )
1550                 break;
1551             pView = SfxViewFrame::GetNext( *pView, i_pBasicIDE );
1552         }
1553         return pView;
1554     }
lcl_findStartModuleFrame(const Reference<XComponentContext> & rxContext)1555     Reference< XFrame > lcl_findStartModuleFrame( const Reference<XComponentContext> & rxContext )
1556     {
1557         try
1558         {
1559             Reference < XDesktop2 > xDesktop = Desktop::create( rxContext );
1560             Reference < XIndexAccess > xContainer( xDesktop->getFrames(), UNO_QUERY_THROW );
1561 
1562             Reference< XModuleManager2 > xCheck = ModuleManager::create(rxContext);
1563 
1564             sal_Int32 nCount = xContainer->getCount();
1565             for ( sal_Int32 i=0; i<nCount; ++i )
1566             {
1567                 try
1568                 {
1569                     Reference < XFrame > xFrame( xContainer->getByIndex(i), UNO_QUERY_THROW );
1570                     OUString sModule = xCheck->identify( xFrame );
1571                     if ( sModule == "com.sun.star.frame.StartModule" )
1572                         return xFrame;
1573                 }
1574                 catch( const UnknownModuleException& )
1575                 {
1576                     // silence
1577                 }
1578                 catch(const Exception&)
1579                 {
1580                     // re-throw, caught below
1581                     throw;
1582                 }
1583             }
1584         }
1585         catch( const Exception& )
1586         {
1587                DBG_UNHANDLED_EXCEPTION("sfx.appl");
1588         }
1589         return nullptr;
1590     }
1591 #endif // HAVE_FEATURE_SCRIPTING
1592 }
1593 
OfaExec_Impl(SfxRequest & rReq)1594 void SfxApplication::OfaExec_Impl( SfxRequest& rReq )
1595 {
1596     switch ( rReq.GetSlot() )
1597     {
1598         case SID_OPTIONS_TREEDIALOG:
1599         {
1600             OUString sPageURL;
1601             const SfxStringItem* pURLItem = rReq.GetArg<SfxStringItem>(SID_OPTIONS_PAGEURL);
1602             if ( pURLItem )
1603                 sPageURL = pURLItem->GetValue();
1604 
1605             sal_uInt16 nPageID = 0;
1606             const SfxUInt16Item* pIDItem = rReq.GetArg<SfxUInt16Item>(SID_OPTIONS_PAGEID);
1607             if (pIDItem)
1608                 nPageID = pIDItem->GetValue();
1609 
1610             Reference <XFrame> xFrame(GetRequestFrame(rReq));
1611             SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
1612             VclPtr<VclAbstractDialog> pDlg =
1613                 pFact->CreateFrameDialog(rReq.GetFrameWeld(), xFrame, rReq.GetSlot(), nPageID, sPageURL);
1614             short nRet = pDlg->Execute();
1615             pDlg.disposeAndClear();
1616             SfxViewFrame* pView = SfxViewFrame::GetFirst();
1617             bool bDisableActiveContent
1618                     = officecfg::Office::Common::Security::Scripting::DisableActiveContent::get();
1619 
1620             while ( pView )
1621             {
1622                 if (nRet == RET_OK)
1623                 {
1624                     SfxObjectShell* pObjSh = pView->GetObjectShell();
1625                     if (pObjSh)
1626                     {
1627                         pObjSh->SetConfigOptionsChecked(false);
1628 
1629                         // when active content is disabled via options dialog,
1630                         // disable all current active embedded objects
1631                         if (bDisableActiveContent)
1632                             lcl_disableActiveEmbeddedObjects(pObjSh);
1633                     }
1634                 }
1635                 pView->GetBindings().InvalidateAll(false);
1636                 pView = SfxViewFrame::GetNext( *pView );
1637             }
1638             break;
1639         }
1640 
1641         case SID_OPTIONS_SECURITY:
1642         {
1643             SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
1644             VclPtr<AbstractSecurityOptionsDialog> pDlg =
1645                 pFact->CreateSvxSecurityOptionsDialog(rReq.GetFrameWeld());
1646 
1647             if (pDlg->Execute() == RET_OK) {
1648                 pDlg->SetSecurityOptions();
1649             }
1650 
1651             pDlg.disposeAndClear();
1652             break;
1653         }
1654 
1655         case SID_MORE_DICTIONARIES:
1656         {
1657             uno::Sequence<beans::PropertyValue> aArgs{ comphelper::makePropertyValue(
1658                 u"AdditionsTag"_ustr, u"Dictionary"_ustr) };
1659             comphelper::dispatchCommand(u".uno:AdditionsDialog"_ustr, aArgs);
1660             break;
1661         }
1662 #if HAVE_FEATURE_SCRIPTING
1663         case SID_BASICIDE_APPEAR:
1664         {
1665             SfxViewFrame* pView = lcl_getBasicIDEViewFrame( nullptr );
1666             if ( !pView )
1667             {
1668                 SfxObjectShell* pBasicIDE = SfxObjectShell::CreateObject( u"com.sun.star.script.BasicIDE"_ustr );
1669                 pBasicIDE->DoInitNew();
1670                 pBasicIDE->SetModified( false );
1671                 try
1672                 {
1673                     // load the Basic IDE via direct access to the SFX frame loader. A generic loadComponentFromURL
1674                     // (which could be done via SfxViewFrame::LoadDocumentIntoFrame) is not feasible here, since the Basic IDE
1675                     // does not really play nice with the framework's concept. For instance, it is a "singleton document",
1676                     // which conflicts, at the latest, with the framework's concept of loading into _blank frames.
1677                     // So, since we know that our frame loader can handle it, we skip the generic framework loader
1678                     // mechanism, and the type detection (which doesn't know about the Basic IDE).
1679                     Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
1680                     Reference< XSynchronousFrameLoader > xLoader(
1681                         xContext->getServiceManager()->createInstanceWithContext(u"com.sun.star.comp.office.FrameLoader"_ustr, xContext),
1682                         UNO_QUERY_THROW );
1683                     ::comphelper::NamedValueCollection aLoadArgs;
1684                     aLoadArgs.put( u"Model"_ustr, pBasicIDE->GetModel() );
1685                     aLoadArgs.put( u"URL"_ustr, u"private:factory/sbasic"_ustr );
1686 
1687                     Reference< XFrame > xTargetFrame( lcl_findStartModuleFrame( xContext ) );
1688                     if ( !xTargetFrame.is() )
1689                         xTargetFrame = SfxFrame::CreateBlankFrame();
1690                     ENSURE_OR_THROW( xTargetFrame.is(), "could not obtain a frameto load the Basic IDE into!" );
1691 
1692                     xLoader->load( aLoadArgs.getPropertyValues(), xTargetFrame );
1693                 }
1694                 catch( const Exception& )
1695                 {
1696                     DBG_UNHANDLED_EXCEPTION("sfx.appl");
1697                 }
1698 
1699                 pView = lcl_getBasicIDEViewFrame( pBasicIDE );
1700                 if ( pView )
1701                     pView->SetName( u"BASIC:1"_ustr );
1702             }
1703 
1704             if ( pView )
1705                 pView->GetFrame().Appear();
1706 
1707             const SfxItemSet* pArgs = rReq.GetArgs();
1708             if ( pArgs && pView )
1709             {
1710                 SfxViewShell* pViewShell = pView->GetViewShell();
1711                 SfxObjectShell* pObjShell = pView->GetObjectShell();
1712                 if ( pViewShell && pObjShell )
1713                 {
1714                     SfxRequest aReq( SID_BASICIDE_SHOWWINDOW, SfxCallMode::SYNCHRON, pObjShell->GetPool() );
1715                     aReq.SetArgs( *pArgs );
1716                     pViewShell->ExecuteSlot( aReq );
1717                 }
1718             }
1719 
1720             rReq.Done();
1721         }
1722         break;
1723 
1724         case SID_BASICCHOOSER:
1725         {
1726             const SfxItemSet* pArgs = rReq.GetArgs();
1727             const SfxBoolItem* pItem;
1728             bool bChooseOnly = false;
1729             Reference< XModel > xLimitToModel;
1730             if(pArgs && (pItem = pArgs->GetItemIfSet(SID_RECORDMACRO, false)) )
1731             {
1732                 bool bRecord = pItem->GetValue();
1733                 if ( bRecord )
1734                 {
1735                     // !Hack
1736                     bChooseOnly = false;
1737                     SfxObjectShell* pCurrentShell = SfxObjectShell::Current();
1738                     OSL_ENSURE( pCurrentShell, "macro recording outside an SFX document?" );
1739                     if ( pCurrentShell )
1740                         xLimitToModel = pCurrentShell->GetModel();
1741                 }
1742             }
1743 
1744             Reference <XFrame> xFrame(GetRequestFrame(rReq));
1745             rReq.SetReturnValue(SfxStringItem(rReq.GetSlot(), ChooseMacro(rReq.GetFrameWeld(), xLimitToModel, xFrame, bChooseOnly)));
1746             rReq.Done();
1747         }
1748         break;
1749 
1750         case SID_MACROORGANIZER:
1751         {
1752             SAL_INFO("sfx.appl", "handling SID_MACROORGANIZER");
1753             const SfxItemSet* pArgs = rReq.GetArgs();
1754             sal_Int16 nTabId = 0;
1755             Reference <XFrame> xFrame;
1756             if (pArgs)
1757             {
1758                 if (const SfxUInt16Item* pItem = pArgs->GetItemIfSet(SID_MACROORGANIZER, false))
1759                     nTabId = pItem->GetValue();
1760                 if (const SfxBoolItem* pItem = rReq.GetArg<SfxBoolItem>(FN_PARAM_2))
1761                 {
1762                     // if set then default to showing the macros of the document associated
1763                     // with this frame
1764                     if (pItem->GetValue())
1765                         xFrame = GetRequestFrame(rReq);
1766                 }
1767             }
1768             SfxApplication::MacroOrganizer(rReq.GetFrameWeld(), xFrame, nTabId);
1769             rReq.Done();
1770         }
1771         break;
1772 
1773         case SID_RUNMACRO:
1774         {
1775             SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
1776             SAL_INFO("sfx.appl", "SfxApplication::OfaExec_Impl: case ScriptOrg");
1777 
1778             Reference <XFrame> xFrame(GetRequestFrame(rReq));
1779             if ( !xFrame.is() )
1780             {
1781                 if (const SfxViewFrame* pViewFrame = SfxViewFrame::Current())
1782                     xFrame = pViewFrame->GetFrame().GetFrameInterface();
1783             }
1784 
1785             do  // artificial loop for flow control
1786             {
1787                 VclPtr<AbstractScriptSelectorDialog> pDlg(pFact->CreateScriptSelectorDialog(lcl_getDialogParent(xFrame), xFrame));
1788                 OSL_ENSURE( pDlg, "SfxApplication::OfaExec_Impl( SID_RUNMACRO ): no dialog!" );
1789                 if ( !pDlg )
1790                     break;
1791                 pDlg->SetRunLabel();
1792 
1793                 pDlg->StartExecuteAsync([pDlg, xFrame](sal_Int32 nDialogResult) {
1794                     if ( !nDialogResult )
1795                     {
1796                         pDlg->disposeOnce();
1797                         return;
1798                     }
1799 
1800                     Sequence< Any > args;
1801                     Sequence< sal_Int16 > outIndex;
1802                     Sequence< Any > outArgs;
1803                     Any ret;
1804 
1805                     Reference< XInterface > xScriptContext;
1806 
1807                     Reference< XController > xController;
1808                     if ( xFrame.is() )
1809                         xController = xFrame->getController();
1810                     if ( xController.is() )
1811                         xScriptContext = xController->getModel();
1812                     if ( !xScriptContext.is() )
1813                         xScriptContext = xController;
1814 
1815                     SfxObjectShell::CallXScript( xScriptContext, pDlg->GetScriptURL(), args, ret, outIndex, outArgs );
1816                     pDlg->disposeOnce();
1817                 });
1818             }
1819             while ( false );
1820             rReq.Done();
1821         }
1822         break;
1823 
1824         case SID_SCRIPTORGANIZER:
1825         {
1826             SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
1827             SAL_INFO("sfx.appl", "SfxApplication::OfaExec_Impl: case ScriptOrg");
1828             const SfxItemSet* pArgs = rReq.GetArgs();
1829             const SfxScriptOrganizerItem* pItem;
1830             OUString aLanguage;
1831             if(pArgs && (pItem = pArgs->GetItemIfSet(SID_SCRIPTORGANIZER, false) ))
1832             {
1833                 aLanguage = pItem->getLanguage();
1834             }
1835 
1836             OUString aLang( aLanguage );
1837             SAL_INFO("sfx.appl", "SfxApplication::OfaExec_Impl: about to create dialog for: " << aLang);
1838             ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateSvxScriptOrgDialog(rReq.GetFrameWeld(), aLanguage));
1839             if( pDlg )
1840             {
1841                 pDlg->Execute();
1842             }
1843             else
1844             {
1845                 SAL_WARN("sfx.appl", "no dialog!!!");
1846             }
1847             rReq.Done();
1848         }
1849         break;
1850 #endif // HAVE_FEATURE_SCRIPTING
1851 
1852         case SID_OFFICE_CHECK_PLZ:
1853         {
1854             bool bRet = false;
1855             const SfxStringItem* pStringItem = rReq.GetArg<SfxStringItem>(rReq.GetSlot());
1856 
1857             if ( pStringItem )
1858             {
1859                 bRet = true /*!!!SfxIniManager::CheckPLZ( aPLZ )*/;
1860             }
1861 #if HAVE_FEATURE_SCRIPTING
1862             else
1863                 SbxBase::SetError( ERRCODE_BASIC_WRONG_ARGS );
1864 #endif
1865             rReq.SetReturnValue( SfxBoolItem( rReq.GetSlot(), bRet ) );
1866         }
1867         break;
1868 
1869         case SID_AUTO_CORRECT_DLG:
1870         {
1871             SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
1872             SfxItemSetFixed<SID_AUTO_CORRECT_DLG, SID_AUTO_CORRECT_DLG> aSet(GetPool());
1873             const SfxPoolItem* pItem=nullptr;
1874             const SfxItemSet* pSet = rReq.GetArgs();
1875             if ( pSet && pSet->GetItemState( SID_AUTO_CORRECT_DLG, false, &pItem ) == SfxItemState::SET )
1876                 aSet.Put( *pItem );
1877 
1878             ScopedVclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateAutoCorrTabDialog(rReq.GetFrameWeld(), &aSet));
1879             pDlg->Execute();
1880 
1881             break;
1882         }
1883 
1884         case SID_NEWSD :
1885         {
1886             SvtModuleOptions aModuleOpt;
1887             if ( !aModuleOpt.IsImpress() )
1888             {
1889                 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(rReq.GetFrameWeld(),
1890                                                                          VclMessageType::Warning, VclButtonsType::Ok,
1891                                                                          SfxResId(STR_MODULENOTINSTALLED)));
1892                 xBox->run();
1893                 return;
1894             }
1895 
1896             Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
1897             Reference< frame::XDispatchProvider > xProv = drawing::ModuleDispatcher::create( xContext );
1898 
1899             OUString aCmd = GetInterface()->GetSlot( rReq.GetSlot() )->GetUnoName();
1900             Reference< frame::XDispatchHelper > xHelper( frame::DispatchHelper::create(xContext) );
1901             Sequence < beans::PropertyValue > aSeq;
1902             if ( rReq.GetArgs() )
1903                 TransformItems( rReq.GetSlot(), *rReq.GetArgs(), aSeq );
1904             Any aResult = xHelper->executeDispatch( xProv, aCmd, OUString(), 0, aSeq );
1905             frame::DispatchResultEvent aEvent;
1906             bool bSuccess = (aResult >>= aEvent) &&
1907                                 (aEvent.State == frame::DispatchResultState::SUCCESS);
1908             rReq.SetReturnValue( SfxBoolItem( rReq.GetSlot(), bSuccess ) );
1909         }
1910         break;
1911 
1912         case FN_LABEL :
1913         case FN_BUSINESS_CARD :
1914         case FN_XFORMS_INIT :
1915         {
1916             Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
1917             Reference< frame::XDispatchProvider > xProv = text::ModuleDispatcher::create( xContext );
1918 
1919             OUString aCmd = GetInterface()->GetSlot( rReq.GetSlot() )->GetUnoName();
1920             Reference< frame::XDispatchHelper > xHelper( frame::DispatchHelper::create(xContext) );
1921             Sequence < beans::PropertyValue > aSeq;
1922             if ( rReq.GetArgs() )
1923                 TransformItems( rReq.GetSlot(), *rReq.GetArgs(), aSeq );
1924             Any aResult = xHelper->executeDispatch( xProv, aCmd, OUString(), 0, aSeq );
1925             frame::DispatchResultEvent aEvent;
1926             bool bSuccess = (aResult >>= aEvent) &&
1927                                 (aEvent.State == frame::DispatchResultState::SUCCESS);
1928             rReq.SetReturnValue( SfxBoolItem( rReq.GetSlot(), bSuccess ) );
1929         }
1930         break;
1931 
1932         case SID_ADDRESS_DATA_SOURCE:
1933         {
1934             try
1935             {
1936                 Reference< uno::XComponentContext > xORB = ::comphelper::getProcessComponentContext();
1937                 Reference< ui::dialogs::XExecutableDialog > xDialog = ui::dialogs::AddressBookSourcePilot::createWithParent(xORB, nullptr);
1938                 xDialog->execute();
1939             }
1940             catch(const css::uno::Exception&)
1941             {
1942                 DBG_UNHANDLED_EXCEPTION("sfx.appl");
1943             }
1944         }
1945         break;
1946 
1947         case SID_COMP_BIBLIOGRAPHY:
1948             lcl_tryLoadBibliography();
1949         break;
1950     }
1951 }
1952 
OfaState_Impl(SfxItemSet & rSet)1953 void SfxApplication::OfaState_Impl(SfxItemSet &rSet)
1954 {
1955     SvtModuleOptions aModuleOpt;
1956 
1957     if( !aModuleOpt.IsWriter())
1958     {
1959         rSet.DisableItem( FN_LABEL );
1960         rSet.DisableItem( FN_BUSINESS_CARD );
1961         rSet.DisableItem( FN_XFORMS_INIT );
1962     }
1963     if ( comphelper::LibreOfficeKit::isActive() )
1964         rSet.DisableItem( SID_AUTO_CORRECT_DLG );
1965 
1966     bool bMacrosDisabled
1967         = officecfg::Office::Common::Security::Scripting::DisableMacrosExecution::get();
1968     if (bMacrosDisabled)
1969     {
1970         rSet.DisableItem(SID_RUNMACRO);
1971         rSet.DisableItem(SID_MACROORGANIZER);
1972         rSet.DisableItem(SID_SCRIPTORGANIZER);
1973         rSet.DisableItem(SID_BASICIDE_APPEAR);
1974     }
1975 }
1976 
1977 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1978