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