xref: /core/sfx2/source/appl/appserv.cxx (revision 2d64651e)
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_options.h>
22 #include <com/sun/star/document/XEmbeddedScripts.hpp>
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/sdbc/DriverManager.hpp>
32 #include <com/sun/star/system/SystemShellExecute.hpp>
33 #include <com/sun/star/system/SystemShellExecuteFlags.hpp>
34 #include <com/sun/star/text/ModuleDispatcher.hpp>
35 #include <com/sun/star/task/OfficeRestartManager.hpp>
36 #include <com/sun/star/task/XInteractionHandler.hpp>
37 #include <com/sun/star/ui/dialogs/AddressBookSourcePilot.hpp>
38 #include <com/sun/star/ui/UIElementType.hpp>
39 #include <com/sun/star/ui/XUIElement.hpp>
40 #include <com/sun/star/uno/Reference.hxx>
41 #include <com/sun/star/util/XCloseable.hpp>
42 #include <com/sun/star/util/CloseVetoException.hpp>
43 #include <org/freedesktop/PackageKit/SyncDbusSessionHelper.hpp>
44 
45 #include <comphelper/lok.hxx>
46 #include <comphelper/namedvaluecollection.hxx>
47 #include <comphelper/processfactory.hxx>
48 #include <comphelper/propertysequence.hxx>
49 #include <comphelper/sequence.hxx>
50 
51 #include <svtools/addresstemplate.hxx>
52 #include <svtools/miscopt.hxx>
53 #include <svtools/restartdialog.hxx>
54 #include <svl/visitem.hxx>
55 
56 #include <unotools/configmgr.hxx>
57 #include <tools/svlibrary.h>
58 #include <tools/diagnose_ex.h>
59 #include <vcl/svapp.hxx>
60 #include <vcl/weld.hxx>
61 #include <svl/intitem.hxx>
62 #include <svl/eitem.hxx>
63 #include <svl/stritem.hxx>
64 #include <basic/sbstar.hxx>
65 #include <basic/basrdll.hxx>
66 #include <basic/sberrors.hxx>
67 #include <vcl/help.hxx>
68 #include <rtl/ustrbuf.hxx>
69 #include <sal/log.hxx>
70 #include <osl/file.hxx>
71 #include <osl/module.hxx>
72 #include <vcl/EnumContext.hxx>
73 
74 #include <unotools/moduleoptions.hxx>
75 #include <svtools/helpopt.hxx>
76 #include <toolkit/helper/vclunohelper.hxx>
77 #include <rtl/bootstrap.hxx>
78 
79 #include <com/sun/star/frame/ModuleManager.hpp>
80 #include <com/sun/star/beans/XPropertySet.hpp>
81 
82 #include <sfx2/app.hxx>
83 #include <sfx2/request.hxx>
84 #include <sfx2/dispatch.hxx>
85 #include <sfx2/bindings.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 
106 #include <comphelper/types.hxx>
107 #include <officecfg/Office/Common.hxx>
108 #include <unotools/confignode.hxx>
109 #include <officecfg/Setup.hxx>
110 #include <memory>
111 
112 #include <openuriexternally.hxx>
113 
114 using namespace ::com::sun::star;
115 using namespace ::com::sun::star::beans;
116 using namespace ::com::sun::star::uno;
117 using namespace ::com::sun::star::frame;
118 using namespace ::com::sun::star::container;
119 using namespace ::com::sun::star::util;
120 using namespace ::com::sun::star::script;
121 using namespace ::com::sun::star::system;
122 using namespace ::com::sun::star::lang;
123 using namespace ::com::sun::star::document;
124 using namespace ::com::sun::star::ui;
125 
126 namespace
127 {
128     OUString lcl_getAppName( vcl::EnumContext::Application eApp )
129     {
130         switch ( eApp )
131         {
132             case vcl::EnumContext::Application::Writer:
133                 return "Writer";
134                 break;
135             case vcl::EnumContext::Application::Calc:
136                 return "Calc";
137                 break;
138             case vcl::EnumContext::Application::Impress:
139                 return "Impress";
140                 break;
141             case vcl::EnumContext::Application::Draw:
142                 return "Draw";
143                 break;
144             case vcl::EnumContext::Application::Formula:
145                 return "Formula";
146                 break;
147             case vcl::EnumContext::Application::Base:
148                 return "Base";
149                 break;
150             default:
151                 return OUString();
152                 break;
153         }
154     }
155 
156     // lp#527938, debian#602953, fdo#33266, i#105408
157     bool lcl_isBaseAvailable()
158     {
159         try
160         {
161             // if we get css::sdbc::DriverManager, libsdbc2 is there
162             // and the bibliography is assumed to work
163             return css::sdbc::DriverManager::create(comphelper::getProcessComponentContext()).is();
164         }
165         catch (const Exception &)
166         {
167             TOOLS_INFO_EXCEPTION("sfx.appl", "assuming Base to be missing");
168             return false;
169         }
170     }
171     void lcl_tryLoadBibliography()
172     {
173         // lp#527938, debian#602953, fdo#33266, i#105408
174         // make sure we actually can instantiate services from base first
175         if(!lcl_isBaseAvailable())
176         {
177             if (officecfg::Office::Common::PackageKit::EnableBaseInstallation::get())
178             {
179                 try
180                 {
181                     using namespace org::freedesktop::PackageKit;
182                     using namespace svtools;
183                     Reference< XSyncDbusSessionHelper > xSyncDbusSessionHelper(SyncDbusSessionHelper::create(comphelper::getProcessComponentContext()));
184                     Sequence< OUString > vPackages { "libreoffice-base" };
185                     xSyncDbusSessionHelper->InstallPackageNames(vPackages, OUString());
186                     // I'll be back (hopefully)!
187                     SolarMutexGuard aGuard;
188                     executeRestartDialog(comphelper::getProcessComponentContext(), nullptr, RESTART_REASON_BIBLIOGRAPHY_INSTALL);
189                 }
190                 catch (const Exception &)
191                 {
192                     TOOLS_INFO_EXCEPTION("sfx.appl", "trying to install LibreOffice Base");
193                 }
194             }
195             return;
196         }
197 
198         try // fdo#48775
199         {
200             SfxStringItem aURL(SID_FILE_NAME, ".component:Bibliography/View1");
201             SfxStringItem aRef(SID_REFERER, "private:user");
202             SfxStringItem aTarget(SID_TARGETNAME, "_blank");
203             SfxViewFrame::Current()->GetDispatcher()->ExecuteList(SID_OPENDOC,
204                 SfxCallMode::ASYNCHRON, { &aURL, &aRef, &aTarget });
205         }
206         catch (const Exception &)
207         {
208             TOOLS_INFO_EXCEPTION( "sfx.appl", "trying to load bibliography database");
209         }
210     }
211 }
212 /// Find the correct location of the document (CREDITS.fodt, etc.), and return
213 /// it in rURL if found.
214 static bool checkURL( const char *pName, const char *pExt, OUString &rURL )
215 {
216     using namespace osl;
217     DirectoryItem aDirItem;
218 
219 #ifdef MACOSX
220     rURL = "$BRAND_BASE_DIR/Resources/" + OUString::createFromAscii( pName ) +
221            OUString::createFromAscii( pExt );
222 #else
223     rURL = "$BRAND_BASE_DIR/" + OUString::createFromAscii( pName ) +
224            OUString::createFromAscii( pExt );
225 #endif
226     rtl::Bootstrap::expandMacros( rURL );
227 
228     if (!rURL.isEmpty())
229         return DirectoryItem::get( rURL, aDirItem ) == DirectoryItem::E_None;
230     else
231         return false;
232 }
233 
234 /// Displays CREDITS or LICENSE in any of the available version
235 static void showDocument( const char* pBaseName )
236 {
237     try {
238         Reference < XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );
239         auto args(::comphelper::InitPropertySequence({
240             {"ViewOnly",    makeAny(true)},
241             {"ReadOnly",    makeAny(true)}
242         }));
243 
244         OUString aURL;
245         if ( checkURL ( pBaseName, ".fodt", aURL ) ||
246              checkURL ( pBaseName, ".html", aURL ) ||
247              checkURL ( pBaseName, "", aURL ) ) {
248             xDesktop->loadComponentFromURL( aURL, "_blank", 0, args );
249         }
250     } catch (const css::uno::Exception &) {
251     }
252 }
253 
254 namespace
255 {
256     Reference<XFrame> GetRequestFrame(const SfxRequest& rReq)
257     {
258         const SfxItemSet* pArgs = rReq.GetInternalArgs_Impl();
259         const SfxPoolItem* pItem = nullptr;
260         Reference <XFrame> xFrame;
261         if (pArgs && pArgs->GetItemState(SID_FILLFRAME, false, &pItem) == SfxItemState::SET)
262         {
263             OSL_ENSURE( dynamic_cast< const SfxUnoFrameItem *>( pItem ) !=  nullptr, "SfxApplication::OfaExec_Impl: XFrames are to be transported via SfxUnoFrameItem by now!" );
264             xFrame = static_cast< const SfxUnoFrameItem*>( pItem )->GetFrame();
265         }
266         return xFrame;
267     }
268 
269     vcl::Window* getFrameWindow(const Reference<XFrame>& rFrame)
270     {
271         if (rFrame.is())
272         {
273             try
274             {
275                 Reference< awt::XWindow > xContainerWindow(rFrame->getContainerWindow(), UNO_SET_THROW);
276                 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow(xContainerWindow);
277                 return pWindow;
278             }
279             catch (const Exception&)
280             {
281                 DBG_UNHANDLED_EXCEPTION("sfx.appl");
282             }
283         }
284 
285         SAL_WARN( "sfx.appl", "no parent for dialogs" );
286         return nullptr;
287     }
288 
289     class LicenseDialog : public weld::GenericDialogController
290     {
291     public:
292         LicenseDialog(weld::Window* pParent)
293             : GenericDialogController(pParent, "sfx/ui/licensedialog.ui",  "LicenseDialog")
294         {
295         }
296 
297         virtual short run() override
298         {
299             short nRet = GenericDialogController::run();
300             if (nRet == RET_OK)
301                 showDocument("LICENSE");
302             return nRet;
303         }
304     };
305 
306     class SafeModeQueryDialog : public weld::MessageDialogController
307     {
308     public:
309         SafeModeQueryDialog(weld::Window* pParent)
310             : MessageDialogController(pParent, "sfx/ui/safemodequerydialog.ui", "SafeModeQueryDialog")
311         {
312         }
313 
314         virtual short run() override
315         {
316             short nRet = MessageDialogController::run();
317             if (nRet == RET_OK)
318             {
319                 sfx2::SafeMode::putFlag();
320                 uno::Reference< uno::XComponentContext > xContext = comphelper::getProcessComponentContext();
321                 css::task::OfficeRestartManager::get(xContext)->requestRestart(
322                     css::uno::Reference< css::task::XInteractionHandler >());
323             }
324             return nRet;
325         }
326     };
327 }
328 
329 vcl::Window* SfxRequest::GetFrameWindow() const
330 {
331     return getFrameWindow(GetRequestFrame(*this));
332 }
333 
334 weld::Window* SfxRequest::GetFrameWeld() const
335 {
336     const SfxItemSet* pIntArgs = GetInternalArgs_Impl();
337     const SfxPoolItem* pItem = nullptr;
338     if (pIntArgs && pIntArgs->GetItemState(SID_DIALOG_PARENT, false, &pItem) == SfxItemState::SET)
339     {
340         assert(dynamic_cast<const SfxUnoAnyItem*>(pItem));
341         auto aAny = static_cast<const SfxUnoAnyItem*>(pItem)->GetValue();
342         Reference<awt::XWindow> xWindow;
343         aAny >>= xWindow;
344         return Application::GetFrameWeld(xWindow);
345     }
346 
347     vcl::Window* pWin = GetFrameWindow();
348     return pWin ? pWin->GetFrameWeld() : nullptr;
349 }
350 
351 void SfxApplication::MiscExec_Impl( SfxRequest& rReq )
352 {
353     bool bDone = false;
354     switch ( rReq.GetSlot() )
355     {
356         case SID_SETOPTIONS:
357         {
358             if( rReq.GetArgs() )
359                 SetOptions_Impl( *rReq.GetArgs() );
360             break;
361         }
362 
363         case SID_QUITAPP:
364         case SID_LOGOUT:
365         {
366             // protect against reentrant calls
367             if ( pImpl->bInQuit )
368                 return;
369 
370             if ( rReq.GetSlot() == SID_LOGOUT )
371             {
372                 for ( SfxObjectShell *pObjSh = SfxObjectShell::GetFirst();
373                     pObjSh; pObjSh = SfxObjectShell::GetNext( *pObjSh ) )
374                 {
375                     if ( !pObjSh->IsModified() )
376                         continue;
377 
378                     SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pObjSh );
379                     if ( !pFrame || !pFrame->GetWindow().IsReallyVisible() )
380                         continue;
381 
382                     if (pObjSh->PrepareClose())
383                         pObjSh->SetModified( false );
384                     else
385                         return;
386                 }
387 
388                 SfxStringItem aNameItem( SID_FILE_NAME, "vnd.sun.star.cmd:logout" );
389                 SfxStringItem aReferer( SID_REFERER, "private/user" );
390                 pImpl->pAppDispat->ExecuteList(SID_OPENDOC,
391                         SfxCallMode::SLOT, { &aNameItem, &aReferer });
392                 return;
393             }
394 
395             // try from nested requests again after 100ms
396             if( Application::GetDispatchLevel() > 1 )
397             {
398                 /* Don't save the request for closing the application and try it later
399                    again. This is an UI bound functionality ... and the user will  try it again
400                    if the dialog is closed. But we should not close the application automatically
401                    if this dialog is closed by the user ...
402                    So we ignore this request now and wait for a new user decision.
403                 */
404                 SAL_INFO("sfx.appl", "QueryExit => sal_False, DispatchLevel == " << Application::GetDispatchLevel() );
405                 return;
406             }
407 
408             // block reentrant calls
409             pImpl->bInQuit = true;
410             Reference < XDesktop2 > xDesktop = Desktop::create ( ::comphelper::getProcessComponentContext() );
411 
412             rReq.ForgetAllArgs();
413 
414             // if terminate() failed, pImpl->bInQuit will now be sal_False, allowing further calls of SID_QUITAPP
415             bool bTerminated = xDesktop->terminate();
416             if (!bTerminated)
417                 // if terminate() was successful, SfxApplication is now dead!
418                 pImpl->bInQuit = false;
419 
420             // Set return value, terminate if possible
421             rReq.SetReturnValue( SfxBoolItem( rReq.GetSlot(), bTerminated ) );
422             return;
423         }
424 
425         case SID_CONFIG:
426         case SID_TOOLBOXOPTIONS:
427         case SID_CONFIGSTATUSBAR:
428         case SID_CONFIGMENU:
429         case SID_CONFIGACCEL:
430         case SID_CONFIGEVENT:
431         {
432             SfxAbstractDialogFactory* pFact =
433                 SfxAbstractDialogFactory::Create();
434 
435             const SfxStringItem* pStringItem = rReq.GetArg<SfxStringItem>(SID_CONFIG);
436 
437             SfxItemSet aSet(
438                 GetPool(), svl::Items<SID_CONFIG, SID_CONFIG>{} );
439 
440             if ( pStringItem )
441             {
442                 aSet.Put( SfxStringItem(
443                     SID_CONFIG, pStringItem->GetValue() ) );
444             }
445 
446             Reference <XFrame> xFrame(GetRequestFrame(rReq));
447             ScopedVclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateCustomizeTabDialog(rReq.GetFrameWeld(),
448                 &aSet, xFrame ));
449 
450             const short nRet = pDlg->Execute();
451 
452             if ( nRet )
453                 bDone = true;
454             break;
455         }
456 
457         case SID_CLOSEDOCS:
458         {
459 
460             Reference < XDesktop2 > xDesktop  = Desktop::create( ::comphelper::getProcessComponentContext() );
461             Reference< XIndexAccess > xTasks = xDesktop->getFrames();
462             if ( !xTasks.is() )
463                 break;
464 
465             sal_Int32 n=0;
466             do
467             {
468                 if ( xTasks->getCount() <= n )
469                     break;
470 
471                 Any aAny = xTasks->getByIndex(n);
472                 Reference < XCloseable > xTask;
473                 aAny >>= xTask;
474                 try
475                 {
476                     xTask->close(true);
477                     n++;
478                 }
479                 catch( CloseVetoException& )
480                 {
481                 }
482             }
483             while( true );
484 
485             bool bOk = ( n == 0);
486             rReq.SetReturnValue( SfxBoolItem( 0, bOk ) );
487             bDone = true;
488             break;
489         }
490 
491         case SID_SAVEDOCS:
492         {
493             bool bOK = true;
494             for ( SfxObjectShell *pObjSh = SfxObjectShell::GetFirst();
495                   pObjSh;
496                   pObjSh = SfxObjectShell::GetNext( *pObjSh ) )
497             {
498                 SfxRequest aReq( SID_SAVEDOC, SfxCallMode::SLOT, pObjSh->GetPool() );
499                 if ( pObjSh->IsModified() )
500                 {
501                     pObjSh->ExecuteSlot( aReq );
502                     const SfxBoolItem *pItem = dynamic_cast<const SfxBoolItem*>( aReq.GetReturnValue()  );
503                     if ( !pItem || !pItem->GetValue() )
504                         bOK = false;
505                 }
506             }
507 
508             rReq.SetReturnValue( SfxBoolItem( 0, bOK ) );
509             rReq.Done();
510             break;
511         }
512 
513         case SID_SEND_FEEDBACK:
514         {
515             OUString module = SfxHelp::GetCurrentModuleIdentifier();
516             OUString sURL(officecfg::Office::Common::Menus::SendFeedbackURL::get() + //officecfg/registry/data/org/openoffice/Office/Common.xcu => https://hub.libreoffice.org/send-feedback/
517                 "?LOversion=" + utl::ConfigManager::getAboutBoxProductVersion() +
518                 "&LOlocale=" + utl::ConfigManager::getUILocale() +
519                 "&LOmodule=" + module.copy(module.lastIndexOf('.') + 1 )  );
520             sfx2::openUriExternally(sURL, false);
521             break;
522         }
523 
524         case SID_Q_AND_A:
525         {
526             // Askbot has URL's normalized to languages, not locales
527             // Get language from locale: ll or lll or ll-CC or lll-CC
528 
529             OUString sURL(officecfg::Office::Common::Menus::QA_URL::get() + //https://hub.libreoffice.org/forum/
530                 "?LOlocale=" + utl::ConfigManager::getUILocale());
531             sfx2::openUriExternally(sURL, false);
532             break;
533         }
534         case SID_DOCUMENTATION:
535         {
536             // Open documentation page based on locales
537             OUString sURL(officecfg::Office::Common::Menus::DocumentationURL::get() + //https://hub.libreoffice.org/documentation/
538                 "?LOlocale=" + utl::ConfigManager::getUILocale());
539             sfx2::openUriExternally(sURL, false);
540             break;
541         }
542         case SID_GETINVOLVED:
543         {
544             // Open get involved/join us page based on locales
545             OUString sURL(officecfg::Office::Common::Menus::GetInvolvedURL::get() + //https://hub.libreoffice.org/joinus/
546                 "?LOlocale=" + utl::ConfigManager::getUILocale());
547             sfx2::openUriExternally(sURL, false);
548             break;
549         }
550         case SID_DONATION:
551         {
552             // Open donation page based on language + script (BCP47) with language as fall back.
553             OUString aLang = LanguageTag(utl::ConfigManager::getUILocale()).getLanguage();
554             OUString aBcp47 = LanguageTag(utl::ConfigManager::getUILocale()).getBcp47();
555             OUString sURL(officecfg::Office::Common::Menus::DonationURL::get() + //https://hub.libreoffice.org/donation/
556                 "?BCP47=" + aBcp47 + "&LOlang=" + aLang );
557             sfx2::openUriExternally(sURL, false);
558             break;
559         }
560         case SID_WHATSNEW:
561         {
562             // Open release notes depending on version and locale
563             OUString sURL(officecfg::Office::Common::Menus::ReleaseNotesURL::get() + //https://hub.libreoffice.org/ReleaseNotes/
564                 "?LOvers=" + utl::ConfigManager::getProductVersion() +
565                 "&LOlocale=" + LanguageTag(utl::ConfigManager::getUILocale()).getBcp47() );
566             sfx2::openUriExternally(sURL, false);
567             break;
568         }
569         case SID_SHOW_LICENSE:
570         {
571             LicenseDialog aDialog(rReq.GetFrameWeld());
572             aDialog.run();
573             break;
574         }
575 
576         case SID_SHOW_CREDITS:
577         {
578             showDocument( "CREDITS" );
579             break;
580         }
581 
582         // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
583         case SID_HELPINDEX:
584         {
585             Help* pHelp = Application::GetHelp();
586             if ( pHelp )
587             {
588                 pHelp->Start(".uno:HelpIndex", Application::GetDefDialogParent()); // show start page
589                 bDone = true;
590             }
591             break;
592         }
593 
594         // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
595         case SID_HELPTIPS:
596         {
597             // Evaluate Parameter
598             const SfxBoolItem* pOnItem = rReq.GetArg<SfxBoolItem>(SID_HELPTIPS);
599             bool bOn = pOnItem
600                             ? pOnItem->GetValue()
601                             : !Help::IsQuickHelpEnabled();
602 
603             if ( bOn )
604                 Help::EnableQuickHelp();
605             else
606                 Help::DisableQuickHelp();
607             SvtHelpOptions().SetHelpTips( bOn );
608             Invalidate(SID_HELPTIPS);
609             bDone = true;
610 
611             // Record if possible
612             if ( !rReq.IsAPI() )
613                 rReq.AppendItem( SfxBoolItem( SID_HELPTIPS, bOn) );
614             break;
615         }
616         // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
617         case SID_EXTENDEDHELP:
618         {
619             Help::StartExtHelp();
620             break;
621         }
622         case SID_HELPBALLOONS:
623         {
624             // Evaluate Parameter
625             const SfxBoolItem* pOnItem = rReq.GetArg<SfxBoolItem>(SID_HELPBALLOONS);
626             bool bOn = pOnItem
627                             ? pOnItem->GetValue()
628                             : !Help::IsBalloonHelpEnabled();
629 
630             if ( bOn )
631                 Help::EnableBalloonHelp();
632             else
633                 Help::DisableBalloonHelp();
634             SvtHelpOptions().SetExtendedHelp( bOn );
635             Invalidate(SID_HELPBALLOONS);
636             bDone = true;
637 
638             // Record if possible
639             if ( !rReq.IsAPI() )
640                 rReq.AppendItem( SfxBoolItem( SID_HELPBALLOONS, bOn) );
641             break;
642         }
643         // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
644         case SID_TIPOFTHEDAY:
645         {
646             VclAbstractDialogFactory* pFact = VclAbstractDialogFactory::Create();
647             ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateTipOfTheDayDialog(rReq.GetFrameWeld()));
648             pDlg->Execute();
649             bDone = true;
650             break;
651         }
652 
653         // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
654         case SID_ABOUT:
655         {
656             SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
657             ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateAboutDialog(rReq.GetFrameWeld()));
658             pDlg->Execute();
659             bDone = true;
660             break;
661         }
662 
663         case SID_TEMPLATE_MANAGER:
664         {
665             SfxTemplateManagerDlg aDialog(rReq.GetFrameWeld());
666             aDialog.run();
667             bDone = true;
668             break;
669         }
670 
671         case SID_TEMPLATE_ADDRESSBOKSOURCE:
672         {
673             svt::AddressBookSourceDialog aDialog(rReq.GetFrameWeld(), ::comphelper::getProcessComponentContext());
674             aDialog.run();
675             bDone = true;
676             break;
677         }
678 
679 #if HAVE_FEATURE_SCRIPTING
680         case SID_BASICSTOP:
681             StarBASIC::Stop();
682             break;
683 
684         case SID_BASICBREAK :
685             BasicDLL::BasicBreak();
686             break;
687 #endif
688 
689         case SID_ZOOM_50_PERCENT:
690         case SID_ZOOM_75_PERCENT:
691         case SID_ZOOM_100_PERCENT:
692         case SID_ZOOM_150_PERCENT:
693         case SID_ZOOM_200_PERCENT:
694         case SID_ZOOM_OPTIMAL:
695         case SID_ZOOM_ENTIRE_PAGE:
696         case SID_ZOOM_PAGE_WIDTH:
697         {
698             SfxObjectShell* pCurrentShell = SfxObjectShell::Current();
699             if (!pCurrentShell)
700                 return;
701 
702             // make sure aZoom is initialized with a proper value if SetType
703             // doesn't work
704             SvxZoomItem aZoom( SvxZoomType::PERCENT, 100 );
705 
706             switch (rReq.GetSlot())
707             {
708                 case SID_ZOOM_50_PERCENT:
709                     aZoom.SetValue(50);
710                     break;
711                 case SID_ZOOM_75_PERCENT:
712                     aZoom.SetValue(75);
713                     break;
714                 case SID_ZOOM_100_PERCENT:
715                     aZoom.SetValue(100);
716                     break;
717                 case SID_ZOOM_150_PERCENT:
718                     aZoom.SetValue(150);
719                     break;
720                 case SID_ZOOM_200_PERCENT:
721                     aZoom.SetValue(200);
722                     break;
723                 case SID_ZOOM_OPTIMAL:
724                     aZoom.SetType( SvxZoomType::OPTIMAL );
725                     break;
726                 case SID_ZOOM_ENTIRE_PAGE:
727                     aZoom.SetType( SvxZoomType::WHOLEPAGE );
728                     break;
729                 case SID_ZOOM_PAGE_WIDTH:
730                     aZoom.SetType( SvxZoomType::PAGEWIDTH );
731                     break;
732             }
733 
734             pCurrentShell->GetDispatcher()->ExecuteList(SID_ATTR_ZOOM, SfxCallMode::ASYNCHRON, { &aZoom });
735 
736             break;
737         }
738         case SID_TOOLBAR_MODE:
739         {
740             const SfxStringItem* pModeName = rReq.GetArg<SfxStringItem>( SID_TOOLBAR_MODE );
741 
742             if ( !pModeName )
743             {
744                 bDone = true;
745                 break;
746             }
747 
748             OUString aNewName(pModeName->GetValue());
749             uno::Reference< uno::XComponentContext > xContext =
750                     ::comphelper::getProcessComponentContext();
751 
752             // Get information about current frame and module
753             Reference<XFrame> xCurrentFrame;
754             vcl::EnumContext::Application eCurrentApp = vcl::EnumContext::Application::NONE;
755             OUString aCurrentMode;
756 
757             SfxViewFrame* pViewFrame = SfxViewFrame::Current();
758             if( pViewFrame )
759             {
760                 xCurrentFrame = pViewFrame->GetFrame().GetFrameInterface();
761 
762                 const Reference<frame::XModuleManager> xModuleManager  = frame::ModuleManager::create( xContext );
763                 eCurrentApp = vcl::EnumContext::GetApplicationEnum( xModuleManager->identify( xCurrentFrame ) );
764 
765                 OUStringBuffer aPath("org.openoffice.Office.UI.ToolbarMode/Applications/");
766                 aPath.append( lcl_getAppName( eCurrentApp ) );
767 
768                 const utl::OConfigurationTreeRoot aAppNode(
769                                                     xContext,
770                                                     aPath.makeStringAndClear(),
771                                                     true);
772                 if ( !aAppNode.isValid() )
773                 {
774                     bDone = true;
775                     break;
776                 }
777 
778                 aCurrentMode = comphelper::getString( aAppNode.getNodeValue( "Active" ) );
779 
780                 if ( aCurrentMode == aNewName )
781                 {
782                     bDone = true;
783                     break;
784                 }
785 
786                 // Save new toolbar mode for a current module
787                 aAppNode.setNodeValue( "Active", makeAny( aNewName ) );
788                 aAppNode.commit();
789             }
790 
791             // Apply settings for all frames
792             pViewFrame = SfxViewFrame::GetFirst();
793             while( pViewFrame )
794             {
795                 Reference<XFrame> xFrame = pViewFrame->GetFrame().GetFrameInterface();
796 
797                 // We want to change mode only for a current app module, ignore other apps
798                 const Reference<frame::XModuleManager> xModuleManager  = frame::ModuleManager::create( xContext );
799                 vcl::EnumContext::Application eApp = vcl::EnumContext::GetApplicationEnum( xModuleManager->identify( xFrame ) );
800                 if ( eApp != eCurrentApp )
801                 {
802                     pViewFrame = SfxViewFrame::GetNext( *pViewFrame );
803                     continue;
804                 }
805 
806                 Reference<css::beans::XPropertySet> xPropSet( xFrame, UNO_QUERY );
807                 Reference<css::frame::XLayoutManager> xLayoutManager;
808                 if ( xPropSet.is() )
809                 {
810                     try
811                     {
812                         Any aValue = xPropSet->getPropertyValue( "LayoutManager" );
813                         aValue >>= xLayoutManager;
814                     }
815                     catch ( const css::uno::RuntimeException& )
816                     {
817                         throw;
818                     }
819                     catch ( css::uno::Exception& )
820                     {
821                     }
822                 }
823 
824                 if ( xLayoutManager.is() )
825                 {
826                     css::uno::Sequence<OUString> aMandatoryToolbars;
827                     css::uno::Sequence<OUString> aUserToolbars;
828                     std::vector<OUString> aBackupList;
829                     OUString aSidebarMode;
830 
831                     OUStringBuffer aPath( "org.openoffice.Office.UI.ToolbarMode/Applications/" );
832                     aPath.append( lcl_getAppName( eApp ) );
833                     aPath.append( "/Modes" );
834 
835                     // Read mode settings
836                     const utl::OConfigurationTreeRoot aModesNode(
837                                             xContext,
838                                             aPath.makeStringAndClear(),
839                                             true);
840                     if ( !aModesNode.isValid() )
841                     {
842                         bDone = true;
843                         break;
844                     }
845 
846                     const Sequence<OUString> aModeNodeNames( aModesNode.getNodeNames() );
847 
848                     for ( const auto& rModeNodeName : aModeNodeNames )
849                     {
850                         const utl::OConfigurationNode aModeNode( aModesNode.openNode( rModeNodeName ) );
851                         if ( !aModeNode.isValid() )
852                             continue;
853 
854                         OUString aCommandArg = comphelper::getString( aModeNode.getNodeValue( "CommandArg" ) );
855 
856                         if ( aCommandArg == aNewName )
857                         {
858                             aMandatoryToolbars = aModeNode.getNodeValue( "Toolbars" ).get< uno::Sequence<OUString> >();
859                             aUserToolbars = aModeNode.getNodeValue( "UserToolbars" ).get< uno::Sequence<OUString> >();
860                             aSidebarMode = comphelper::getString( aModeNode.getNodeValue( "Sidebar" ) );
861                             break;
862                         }
863                     }
864 
865                     // Backup visible toolbar list and hide all toolbars
866                     const Sequence<Reference<XUIElement>> aUIElements = xLayoutManager->getElements();
867                     for ( const Reference< XUIElement >& xUIElement : aUIElements )
868                     {
869                         Reference< XPropertySet > xPropertySet( xUIElement, UNO_QUERY );
870                         if ( xPropertySet.is() && xUIElement.is() )
871                         {
872                             try
873                             {
874                                 OUString aResName;
875                                 sal_Int16 nType( -1 );
876                                 xPropertySet->getPropertyValue( "Type" ) >>= nType;
877                                 xPropertySet->getPropertyValue( "ResourceURL" ) >>= aResName;
878 
879                                 if (( nType == css::ui::UIElementType::TOOLBAR ) &&
880                                     !aResName.isEmpty() )
881                                 {
882                                     if ( xLayoutManager->isElementVisible( aResName ) )
883                                     {
884                                         aBackupList.push_back( aResName );
885                                     }
886                                     xLayoutManager->hideElement( aResName );
887                                 }
888                             }
889                             catch ( const Exception& )
890                             {
891                             }
892                         }
893                     }
894 
895                     // Show toolbars
896                     for ( const OUString& rName : std::as_const(aMandatoryToolbars) )
897                     {
898                         xLayoutManager->createElement( rName );
899                         xLayoutManager->showElement( rName );
900                     }
901 
902                     for ( const OUString& rName : std::as_const(aUserToolbars) )
903                     {
904                         xLayoutManager->createElement( rName );
905                         xLayoutManager->showElement( rName );
906                     }
907 
908                     // Sidebar
909                     pViewFrame->ShowChildWindow( SID_SIDEBAR );
910 
911                     sfx2::sidebar::SidebarController* pSidebar =
912                             sfx2::sidebar::SidebarController::GetSidebarControllerForFrame( xFrame );
913                     if ( pSidebar )
914                     {
915                         if ( aSidebarMode == "Arrow" )
916                         {
917                             pSidebar->FadeOut();
918                         }
919                         else if ( aSidebarMode == "Tabs" )
920                         {
921                             pSidebar->FadeIn();
922                             pSidebar->RequestOpenDeck();
923                             pSidebar->RequestCloseDeck();
924                         }
925                         else if ( aSidebarMode == "Opened" )
926                         {
927                             pSidebar->FadeIn();
928                             pSidebar->RequestOpenDeck();
929                         }
930                     }
931 
932                     // Show/Hide the Notebookbar
933                     const SfxPoolItem* pItem;
934                     pViewFrame->GetDispatcher()->QueryState( SID_NOTEBOOKBAR, pItem );
935 
936                     // Save settings
937                     if ( pViewFrame == SfxViewFrame::Current() )
938                     {
939                         css::uno::Sequence<OUString> aBackup( comphelper::containerToSequence(aBackupList) );
940 
941                         for ( const auto& rModeNodeName : aModeNodeNames )
942                         {
943                             const utl::OConfigurationNode aModeNode( aModesNode.openNode( rModeNodeName ) );
944                             if ( !aModeNode.isValid() )
945                                 continue;
946 
947                             OUString aCommandArg = comphelper::getString( aModeNode.getNodeValue( "CommandArg" ) );
948 
949                             if ( aCommandArg == aCurrentMode )
950                             {
951                                 aModeNode.setNodeValue( "UserToolbars", makeAny( aBackup ) );
952                                 break;
953                             }
954                         }
955                         aModesNode.commit();
956                     }
957                 }
958 
959                 pViewFrame = SfxViewFrame::GetNext(*pViewFrame);
960             }
961 
962             bDone = true;
963             break;
964         }
965         case SID_AVAILABLE_TOOLBARS:
966         {
967             const SfxStringItem* pToolbarName = rReq.GetArg<SfxStringItem>(SID_AVAILABLE_TOOLBARS);
968 
969             if ( pToolbarName )
970             {
971                 Reference < XDesktop2 > xDesktop = Desktop::create ( ::comphelper::getProcessComponentContext() );
972                 Reference< XFrame > xFrame = xDesktop->getActiveFrame();
973 
974                 Reference< css::beans::XPropertySet > xPropSet( xFrame, UNO_QUERY );
975                 Reference< css::frame::XLayoutManager > xLayoutManager;
976                 if ( xPropSet.is() )
977                 {
978                     try
979                     {
980                         Any aValue = xPropSet->getPropertyValue("LayoutManager");
981                         aValue >>= xLayoutManager;
982                     }
983                     catch ( const css::uno::RuntimeException& )
984                     {
985                         throw;
986                     }
987                     catch ( css::uno::Exception& )
988                     {
989                     }
990                 }
991 
992                 if ( xLayoutManager.is() )
993                 {
994                     OUStringBuffer aBuf( "private:resource/toolbar/" );
995                     aBuf.append( pToolbarName->GetValue() );
996 
997                     // Evaluate Parameter
998                     OUString aToolbarName( aBuf.makeStringAndClear() );
999                     bool bShow( !xLayoutManager->isElementVisible( aToolbarName ));
1000 
1001                     if ( bShow )
1002                     {
1003                         xLayoutManager->createElement( aToolbarName );
1004                         xLayoutManager->showElement( aToolbarName );
1005                     }
1006                     else
1007                         xLayoutManager->hideElement( aToolbarName );
1008                 }
1009             }
1010 
1011             bDone = true;
1012             break;
1013         }
1014         case SID_MENUBAR:
1015         {
1016             sfx2::SfxNotebookBar::ToggleMenubar();
1017             bDone = true;
1018             break;
1019         }
1020         case SID_SAFE_MODE:
1021         {
1022             SafeModeQueryDialog aDialog(rReq.GetFrameWeld());
1023             aDialog.run();
1024             break;
1025         }
1026 
1027         default:
1028             break;
1029     }
1030 
1031     if ( bDone )
1032         rReq.Done();
1033 }
1034 
1035 void SfxApplication::MiscState_Impl(SfxItemSet &rSet)
1036 {
1037     const sal_uInt16 *pRanges = rSet.GetRanges();
1038     DBG_ASSERT(pRanges && *pRanges, "Set without range");
1039     while ( *pRanges )
1040     {
1041         for(sal_uInt16 nWhich = *pRanges++; nWhich <= *pRanges; ++nWhich)
1042         {
1043             switch(nWhich)
1044             {
1045                 case SID_TEMPLATE_ADDRESSBOKSOURCE:
1046                     if ( !SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::EModule::DATABASE) )
1047                         rSet.Put(SfxVisibilityItem(nWhich, false));
1048                     break;
1049                 case SID_QUITAPP:
1050                 {
1051                     if ( pImpl->nDocModalMode )
1052                         rSet.DisableItem(nWhich);
1053                     else
1054                         rSet.Put(SfxStringItem(nWhich, SfxResId(STR_QUITAPP)));
1055                     break;
1056                 }
1057 
1058                 case SID_CONFIG:
1059                 case SID_TOOLBOXOPTIONS:
1060                 case SID_CONFIGSTATUSBAR:
1061                 case SID_CONFIGMENU:
1062                 case SID_CONFIGACCEL:
1063                 case SID_CONFIGEVENT:
1064                 {
1065                     if( SvtMiscOptions().DisableUICustomization() )
1066                         rSet.DisableItem(nWhich);
1067                     break;
1068                 }
1069 
1070 #if HAVE_FEATURE_SCRIPTING
1071                 case SID_BASICSTOP:
1072                     if ( !StarBASIC::IsRunning() )
1073                         rSet.DisableItem(nWhich);
1074                     break;
1075 #endif
1076 
1077                 case SID_HELPTIPS:
1078                 {
1079                     rSet.Put( SfxBoolItem( SID_HELPTIPS, Help::IsQuickHelpEnabled() ) );
1080                 }
1081                 break;
1082                 case SID_HELPBALLOONS:
1083                 {
1084                     rSet.Put( SfxBoolItem( SID_HELPBALLOONS, Help::IsBalloonHelpEnabled() ) );
1085                 }
1086                 break;
1087 
1088                 case SID_EXTENDEDHELP:
1089                 {
1090                 }
1091                 break;
1092 
1093                 case SID_CLOSEDOCS:
1094                 {
1095                     Reference < XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );
1096                     Reference< XIndexAccess > xTasks = xDesktop->getFrames();
1097                     if ( !xTasks.is() || !xTasks->getCount() )
1098                         rSet.DisableItem(nWhich);
1099                     break;
1100                 }
1101 
1102                 case SID_SAVEDOCS:
1103                 {
1104                     bool bModified = false;
1105                     for ( SfxObjectShell *pObjSh = SfxObjectShell::GetFirst();
1106                           pObjSh;
1107                           pObjSh = SfxObjectShell::GetNext( *pObjSh ) )
1108                     {
1109                         if ( pObjSh->IsModified() )
1110                         {
1111                             bModified = true;
1112                             break;
1113                         }
1114                     }
1115 
1116                     if ( !bModified )
1117                         rSet.DisableItem( nWhich );
1118                     break;
1119                 }
1120 
1121                 case SID_TEMPLATE_MANAGER:
1122                     {
1123                         SvtMiscOptions aMiscOptions;
1124                         if ( !aMiscOptions.IsExperimentalMode() )
1125                         {
1126                            rSet.DisableItem( nWhich );
1127                            rSet.Put( SfxVisibilityItem( nWhich, false ) );
1128                         }
1129                     }
1130                     break;
1131 
1132                 case SID_ZOOM_50_PERCENT:
1133                 case SID_ZOOM_75_PERCENT:
1134                 case SID_ZOOM_100_PERCENT:
1135                 case SID_ZOOM_150_PERCENT:
1136                 case SID_ZOOM_200_PERCENT:
1137                 case SID_ZOOM_OPTIMAL:
1138                 case SID_ZOOM_ENTIRE_PAGE:
1139                 case SID_ZOOM_PAGE_WIDTH:
1140                     {
1141                         SfxObjectShell* pCurrentShell = SfxObjectShell::Current();
1142 
1143                         const SfxPoolItem *pItem;
1144                         SfxItemState aState = pCurrentShell ?
1145                             pCurrentShell->GetDispatcher()->QueryState(SID_ATTR_ZOOM, pItem) : SfxItemState::DISABLED;
1146                         if ( aState == SfxItemState::DISABLED )
1147                             rSet.DisableItem( nWhich );
1148                     }
1149                     break;
1150 
1151                 case SID_MENUBAR:
1152                 {
1153                     Reference < XDesktop2 > xDesktop = Desktop::create ( ::comphelper::getProcessComponentContext() );
1154                     Reference< XFrame > xFrame = xDesktop->getActiveFrame();
1155 
1156                     Reference< css::beans::XPropertySet > xPropSet( xFrame, UNO_QUERY );
1157                     Reference< css::frame::XLayoutManager > xLayoutManager;
1158                     if ( xPropSet.is() )
1159                     {
1160                         try
1161                         {
1162                             Any aValue = xPropSet->getPropertyValue("LayoutManager");
1163                             aValue >>= xLayoutManager;
1164                         }
1165                         catch ( const css::uno::RuntimeException& )
1166                         {
1167                             throw;
1168                         }
1169                         catch ( css::uno::Exception& )
1170                         {
1171                         }
1172                     }
1173 
1174                     if ( xLayoutManager.is() )
1175                     {
1176                         const bool bState
1177                             = xLayoutManager->getElement("private:resource/menubar/menubar").is()
1178                               && xLayoutManager->isElementVisible(
1179                                      "private:resource/menubar/menubar");
1180 
1181                         SfxBoolItem aItem( SID_MENUBAR, bState );
1182                         rSet.Put( aItem );
1183                     }
1184                     break;
1185                 }
1186                 case SID_SAFE_MODE:
1187                 {
1188                     // no restart in safe mode when already in safe mode
1189                     if ( Application::IsSafeModeEnabled() )
1190                        rSet.DisableItem( SID_SAFE_MODE );
1191                     break;
1192                 }
1193 
1194                 default:
1195                     break;
1196             }
1197         }
1198 
1199         ++pRanges;
1200     }
1201 }
1202 
1203 #if HAVE_FEATURE_SCRIPTING
1204 
1205 #ifndef DISABLE_DYNLOADING
1206 
1207 typedef rtl_uString* (*basicide_choose_macro)(void*, void*, void*, sal_Bool);
1208 
1209 extern "C" { static void thisModule() {} }
1210 
1211 #else
1212 
1213 extern "C" rtl_uString* basicide_choose_macro(void*, void*, void*, sal_Bool);
1214 
1215 #endif
1216 
1217 static OUString ChooseMacro(weld::Window* pParent, const Reference<XModel>& rxLimitToDocument, const Reference<XFrame>& xDocFrame, bool bChooseOnly)
1218 {
1219 #ifndef DISABLE_DYNLOADING
1220     osl::Module aMod;
1221 
1222     // load basctl module
1223     if (!aMod.loadRelative(
1224             &thisModule,
1225 #if ENABLE_MERGELIBS
1226             SVLIBRARY("merged")
1227 #else
1228             SVLIBRARY("basctl")
1229 #endif
1230         ))
1231     {
1232         SAL_WARN("sfx.appl", "cannot load basctl");
1233         return "";
1234     }
1235 
1236     // get symbol
1237     basicide_choose_macro pSymbol = reinterpret_cast<basicide_choose_macro>(aMod.getFunctionSymbol("basicide_choose_macro"));
1238     SAL_WARN_IF(!pSymbol, "sfx.appl", "SfxApplication::MacroOrganizer, no symbol!");
1239     if (!pSymbol)
1240         return OUString();
1241     aMod.release();
1242 #else
1243 #define pSymbol basicide_choose_macro
1244 #endif
1245 
1246     // call basicide_choose_macro in basctl
1247     rtl_uString* pScriptURL = pSymbol(pParent, rxLimitToDocument.get(), xDocFrame.get(), bChooseOnly);
1248     OUString aScriptURL( pScriptURL );
1249     rtl_uString_release( pScriptURL );
1250     return aScriptURL;
1251 
1252 #ifdef DISABLE_DYNLOADING
1253 #undef pSymbol
1254 #endif
1255 }
1256 
1257 #endif
1258 
1259 namespace
1260 {
1261 #if HAVE_FEATURE_SCRIPTING
1262     weld::Window* lcl_getDialogParent(const Reference<XFrame>& rxFrame)
1263     {
1264         Reference<awt::XWindow> xContainerWindow;
1265         if (rxFrame.is())
1266             xContainerWindow = rxFrame->getContainerWindow();
1267         return Application::GetFrameWeld(xContainerWindow);
1268     }
1269 
1270     SfxViewFrame* lcl_getBasicIDEViewFrame( SfxObjectShell const * i_pBasicIDE )
1271     {
1272         SfxViewFrame* pView = SfxViewFrame::GetFirst( i_pBasicIDE );
1273         while ( pView )
1274         {
1275             if ( pView->GetObjectShell()->GetFactory().GetDocumentServiceName() == "com.sun.star.script.BasicIDE" )
1276                 break;
1277             pView = SfxViewFrame::GetNext( *pView, i_pBasicIDE );
1278         }
1279         return pView;
1280     }
1281     Reference< XFrame > lcl_findStartModuleFrame( const Reference<XComponentContext> & rxContext )
1282     {
1283         try
1284         {
1285             Reference < XDesktop2 > xDesktop = Desktop::create( rxContext );
1286             Reference < XIndexAccess > xContainer( xDesktop->getFrames(), UNO_QUERY_THROW );
1287 
1288             Reference< XModuleManager2 > xCheck = ModuleManager::create(rxContext);
1289 
1290             sal_Int32 nCount = xContainer->getCount();
1291             for ( sal_Int32 i=0; i<nCount; ++i )
1292             {
1293                 try
1294                 {
1295                     Reference < XFrame > xFrame( xContainer->getByIndex(i), UNO_QUERY_THROW );
1296                     OUString sModule = xCheck->identify( xFrame );
1297                     if ( sModule == "com.sun.star.frame.StartModule" )
1298                         return xFrame;
1299                 }
1300                 catch( const UnknownModuleException& )
1301                 {
1302                     // silence
1303                 }
1304                 catch(const Exception&)
1305                 {
1306                     // re-throw, caught below
1307                     throw;
1308                 }
1309             }
1310         }
1311         catch( const Exception& )
1312         {
1313                DBG_UNHANDLED_EXCEPTION("sfx.appl");
1314         }
1315         return nullptr;
1316     }
1317 #endif // HAVE_FEATURE_SCRIPTING
1318 }
1319 
1320 void SfxApplication::OfaExec_Impl( SfxRequest& rReq )
1321 {
1322     switch ( rReq.GetSlot() )
1323     {
1324         case SID_OPTIONS_TREEDIALOG:
1325         {
1326             OUString sPageURL;
1327             const SfxStringItem* pURLItem = rReq.GetArg<SfxStringItem>(SID_OPTIONS_PAGEURL);
1328             if ( pURLItem )
1329                 sPageURL = pURLItem->GetValue();
1330             Reference <XFrame> xFrame(GetRequestFrame(rReq));
1331             SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
1332             VclPtr<VclAbstractDialog> pDlg =
1333                 pFact->CreateFrameDialog(rReq.GetFrameWeld(), xFrame, rReq.GetSlot(), sPageURL );
1334             short nRet = pDlg->Execute();
1335             pDlg.disposeAndClear();
1336             SfxViewFrame* pView = SfxViewFrame::GetFirst();
1337             while ( pView )
1338             {
1339                 if (nRet == RET_OK)
1340                 {
1341                     SfxObjectShell* pObjSh = pView->GetObjectShell();
1342                     if (pObjSh)
1343                         pObjSh->SetConfigOptionsChecked(false);
1344                 }
1345                 pView->GetBindings().InvalidateAll(false);
1346                 pView = SfxViewFrame::GetNext( *pView );
1347             }
1348             break;
1349         }
1350 
1351         case SID_MORE_DICTIONARIES:
1352         {
1353             try
1354             {
1355                 uno::Reference< uno::XComponentContext > xContext =
1356                     ::comphelper::getProcessComponentContext();
1357                 uno::Reference< css::system::XSystemShellExecute > xSystemShell(
1358                     css::system::SystemShellExecute::create(xContext) );
1359 
1360                 // read repository URL from configuration
1361                 OUString sTemplRepoURL(officecfg::Office::Common::Dictionaries::RepositoryURL::get());
1362 
1363                 if ( xSystemShell.is() && !sTemplRepoURL.isEmpty() )
1364                 {
1365                     // read locale from configuration
1366                     OUString sLocale(officecfg::Setup::L10N::ooLocale::get());
1367                     if (sLocale.isEmpty())
1368                         sLocale = "en-US";
1369 
1370                     OUString aURLBuf =  sTemplRepoURL + "?lang=" + sLocale;
1371                     xSystemShell->execute(
1372                         aURLBuf,
1373                         OUString(),
1374                         css::system::SystemShellExecuteFlags::URIS_ONLY );
1375                 }
1376             }
1377             catch( const css::uno::Exception& )
1378             {
1379                 TOOLS_WARN_EXCEPTION( "sfx.appl", "SfxApplication::OfaExec_Impl(SID_MORE_DICTIONARIES)" );
1380             }
1381             break;
1382         }
1383 #if HAVE_FEATURE_SCRIPTING
1384         case SID_BASICIDE_APPEAR:
1385         {
1386             SfxViewFrame* pView = lcl_getBasicIDEViewFrame( nullptr );
1387             if ( !pView )
1388             {
1389                 SfxObjectShell* pBasicIDE = SfxObjectShell::CreateObject( "com.sun.star.script.BasicIDE" );
1390                 pBasicIDE->DoInitNew();
1391                 pBasicIDE->SetModified( false );
1392                 try
1393                 {
1394                     // load the Basic IDE via direct access to the SFX frame loader. A generic loadComponentFromURL
1395                     // (which could be done via SfxViewFrame::LoadDocumentIntoFrame) is not feasible here, since the Basic IDE
1396                     // does not really play nice with the framework's concept. For instance, it is a "singleton document",
1397                     // which conflicts, at the latest, with the framework's concept of loading into _blank frames.
1398                     // So, since we know that our frame loader can handle it, we skip the generic framework loader
1399                     // mechanism, and the type detection (which doesn't know about the Basic IDE).
1400                     Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
1401                     Reference< XSynchronousFrameLoader > xLoader(
1402                         xContext->getServiceManager()->createInstanceWithContext("com.sun.star.comp.office.FrameLoader", xContext),
1403                         UNO_QUERY_THROW );
1404                     ::comphelper::NamedValueCollection aLoadArgs;
1405                     aLoadArgs.put( "Model", pBasicIDE->GetModel() );
1406                     aLoadArgs.put( "URL", OUString( "private:factory/sbasic"  ) );
1407 
1408                     Reference< XFrame > xTargetFrame( lcl_findStartModuleFrame( xContext ) );
1409                     if ( !xTargetFrame.is() )
1410                         xTargetFrame = SfxFrame::CreateBlankFrame();
1411                     ENSURE_OR_THROW( xTargetFrame.is(), "could not obtain a frameto load the Basic IDE into!" );
1412 
1413                     xLoader->load( aLoadArgs.getPropertyValues(), xTargetFrame );
1414                 }
1415                 catch( const Exception& )
1416                 {
1417                     DBG_UNHANDLED_EXCEPTION("sfx.appl");
1418                 }
1419 
1420                 pView = lcl_getBasicIDEViewFrame( pBasicIDE );
1421                 if ( pView )
1422                     pView->SetName( "BASIC:1" );
1423             }
1424 
1425             if ( pView )
1426                 pView->GetFrame().Appear();
1427 
1428             const SfxItemSet* pArgs = rReq.GetArgs();
1429             if ( pArgs && pView )
1430             {
1431                 SfxViewShell* pViewShell = pView->GetViewShell();
1432                 SfxObjectShell* pObjShell = pView->GetObjectShell();
1433                 if ( pViewShell && pObjShell )
1434                 {
1435                     SfxRequest aReq( SID_BASICIDE_SHOWWINDOW, SfxCallMode::SYNCHRON, pObjShell->GetPool() );
1436                     aReq.SetArgs( *pArgs );
1437                     pViewShell->ExecuteSlot( aReq );
1438                 }
1439             }
1440 
1441             rReq.Done();
1442         }
1443         break;
1444 
1445         case SID_BASICCHOOSER:
1446         {
1447             const SfxItemSet* pArgs = rReq.GetArgs();
1448             const SfxPoolItem* pItem;
1449             bool bChooseOnly = false;
1450             Reference< XModel > xLimitToModel;
1451             if(pArgs && SfxItemState::SET == pArgs->GetItemState(SID_RECORDMACRO, false, &pItem) )
1452             {
1453                 bool bRecord = static_cast<const SfxBoolItem*>(pItem)->GetValue();
1454                 if ( bRecord )
1455                 {
1456                     // !Hack
1457                     bChooseOnly = false;
1458                     SfxObjectShell* pCurrentShell = SfxObjectShell::Current();
1459                     OSL_ENSURE( pCurrentShell, "macro recording outside an SFX document?" );
1460                     if ( pCurrentShell )
1461                         xLimitToModel = pCurrentShell->GetModel();
1462                 }
1463             }
1464 
1465             Reference <XFrame> xFrame(GetRequestFrame(rReq));
1466             rReq.SetReturnValue(SfxStringItem(rReq.GetSlot(), ChooseMacro(rReq.GetFrameWeld(), xLimitToModel, xFrame, bChooseOnly)));
1467             rReq.Done();
1468         }
1469         break;
1470 
1471         case SID_MACROORGANIZER:
1472         {
1473             SAL_INFO("sfx.appl", "handling SID_MACROORGANIZER");
1474             const SfxItemSet* pArgs = rReq.GetArgs();
1475             const SfxPoolItem* pItem;
1476             sal_Int16 nTabId = 0;
1477             if(pArgs && SfxItemState::SET == pArgs->GetItemState(SID_MACROORGANIZER, false, &pItem) )
1478             {
1479                 nTabId = static_cast<const SfxUInt16Item*>(pItem)->GetValue();
1480             }
1481 
1482             SfxApplication::MacroOrganizer(rReq.GetFrameWeld(), nTabId);
1483             rReq.Done();
1484         }
1485         break;
1486 
1487         case SID_RUNMACRO:
1488         {
1489             SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
1490             SAL_INFO("sfx.appl", "SfxApplication::OfaExec_Impl: case ScriptOrg");
1491 
1492             Reference <XFrame> xFrame(GetRequestFrame(rReq));
1493             if ( !xFrame.is() )
1494             {
1495                 const SfxViewFrame* pViewFrame = SfxViewFrame::Current();
1496                 if ( pViewFrame )
1497                     xFrame = pViewFrame->GetFrame().GetFrameInterface();
1498             }
1499 
1500             do  // artificial loop for flow control
1501             {
1502                 ScopedVclPtr<AbstractScriptSelectorDialog> pDlg(pFact->CreateScriptSelectorDialog(lcl_getDialogParent(xFrame), xFrame));
1503                 OSL_ENSURE( pDlg, "SfxApplication::OfaExec_Impl( SID_RUNMACRO ): no dialog!" );
1504                 if ( !pDlg )
1505                     break;
1506                 pDlg->SetRunLabel();
1507 
1508                 short nDialogResult = pDlg->Execute();
1509                 if ( !nDialogResult )
1510                     break;
1511 
1512                 Sequence< Any > args;
1513                 Sequence< sal_Int16 > outIndex;
1514                 Sequence< Any > outArgs;
1515                 Any ret;
1516 
1517                 Reference< XInterface > xScriptContext;
1518 
1519                 Reference< XController > xController;
1520                 if ( xFrame.is() )
1521                     xController = xFrame->getController();
1522                 if ( xController.is() )
1523                     xScriptContext = xController->getModel();
1524                 if ( !xScriptContext.is() )
1525                     xScriptContext = xController;
1526 
1527                 SfxObjectShell::CallXScript( xScriptContext, pDlg->GetScriptURL(), args, ret, outIndex, outArgs );
1528             }
1529             while ( false );
1530             rReq.Done();
1531         }
1532         break;
1533 
1534         case SID_SCRIPTORGANIZER:
1535         {
1536             SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
1537             SAL_INFO("sfx.appl", "SfxApplication::OfaExec_Impl: case ScriptOrg");
1538             const SfxItemSet* pArgs = rReq.GetArgs();
1539             const SfxPoolItem* pItem;
1540             OUString aLanguage;
1541             if(pArgs && SfxItemState::SET == pArgs->GetItemState(SID_SCRIPTORGANIZER, false, &pItem) )
1542             {
1543                 aLanguage = static_cast<const SfxScriptOrganizerItem*>(pItem)->getLanguage();
1544             }
1545 
1546             OUString aLang( aLanguage );
1547             SAL_INFO("sfx.appl", "SfxApplication::OfaExec_Impl: about to create dialog for: " << aLang);
1548             ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateSvxScriptOrgDialog(rReq.GetFrameWeld(), aLanguage));
1549             if( pDlg )
1550             {
1551                 pDlg->Execute();
1552             }
1553             else
1554             {
1555                 SAL_WARN("sfx.appl", "no dialog!!!");
1556             }
1557             rReq.Done();
1558         }
1559         break;
1560 #endif // HAVE_FEATURE_SCRIPTING
1561 
1562         case SID_OFFICE_CHECK_PLZ:
1563         {
1564             bool bRet = false;
1565             const SfxStringItem* pStringItem = rReq.GetArg<SfxStringItem>(rReq.GetSlot());
1566 
1567             if ( pStringItem )
1568             {
1569                 bRet = true /*!!!SfxIniManager::CheckPLZ( aPLZ )*/;
1570             }
1571 #if HAVE_FEATURE_SCRIPTING
1572             else
1573                 SbxBase::SetError( ERRCODE_BASIC_WRONG_ARGS );
1574 #endif
1575             rReq.SetReturnValue( SfxBoolItem( rReq.GetSlot(), bRet ) );
1576         }
1577         break;
1578 
1579         case SID_AUTO_CORRECT_DLG:
1580         {
1581             SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
1582             SfxItemSet aSet(GetPool(), svl::Items<SID_AUTO_CORRECT_DLG, SID_AUTO_CORRECT_DLG>{});
1583             const SfxPoolItem* pItem=nullptr;
1584             const SfxItemSet* pSet = rReq.GetArgs();
1585             SfxItemPool* pSetPool = pSet ? pSet->GetPool() : nullptr;
1586             if ( pSet && pSet->GetItemState( pSetPool->GetWhich( SID_AUTO_CORRECT_DLG ), false, &pItem ) == SfxItemState::SET )
1587                 aSet.Put( *pItem );
1588 
1589             const SfxViewFrame* pViewFrame = SfxViewFrame::Current();
1590             ScopedVclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateAutoCorrTabDialog(pViewFrame ? pViewFrame->GetWindow().GetFrameWeld() : nullptr, &aSet));
1591             pDlg->Execute();
1592 
1593             break;
1594         }
1595 
1596         case SID_NEWSD :
1597         {
1598             SvtModuleOptions aModuleOpt;
1599             if ( !aModuleOpt.IsImpress() )
1600             {
1601                 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
1602                                                                          VclMessageType::Warning, VclButtonsType::Ok,
1603                                                                          SfxResId(STR_MODULENOTINSTALLED)));
1604                 xBox->run();
1605                 return;
1606             }
1607 
1608             Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
1609             Reference< frame::XDispatchProvider > xProv = drawing::ModuleDispatcher::create( xContext );
1610 
1611             OUString aCmd = OUString::createFromAscii( GetInterface()->GetSlot( rReq.GetSlot() )->GetUnoName() );
1612             Reference< frame::XDispatchHelper > xHelper( frame::DispatchHelper::create(xContext) );
1613             Sequence < beans::PropertyValue > aSeq;
1614             if ( rReq.GetArgs() )
1615                 TransformItems( rReq.GetSlot(), *rReq.GetArgs(), aSeq );
1616             Any aResult = xHelper->executeDispatch( xProv, aCmd, OUString(), 0, aSeq );
1617             frame::DispatchResultEvent aEvent;
1618             bool bSuccess = (aResult >>= aEvent) &&
1619                                 (aEvent.State == frame::DispatchResultState::SUCCESS);
1620             rReq.SetReturnValue( SfxBoolItem( rReq.GetSlot(), bSuccess ) );
1621         }
1622         break;
1623 
1624         case FN_LABEL :
1625         case FN_BUSINESS_CARD :
1626         case FN_XFORMS_INIT :
1627         {
1628             Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
1629             Reference< frame::XDispatchProvider > xProv = text::ModuleDispatcher::create( xContext );
1630 
1631             OUString aCmd = OUString::createFromAscii( GetInterface()->GetSlot( rReq.GetSlot() )->GetUnoName() );
1632             Reference< frame::XDispatchHelper > xHelper( frame::DispatchHelper::create(xContext) );
1633             Sequence < beans::PropertyValue > aSeq;
1634             if ( rReq.GetArgs() )
1635                 TransformItems( rReq.GetSlot(), *rReq.GetArgs(), aSeq );
1636             Any aResult = xHelper->executeDispatch( xProv, aCmd, OUString(), 0, aSeq );
1637             frame::DispatchResultEvent aEvent;
1638             bool bSuccess = (aResult >>= aEvent) &&
1639                                 (aEvent.State == frame::DispatchResultState::SUCCESS);
1640             rReq.SetReturnValue( SfxBoolItem( rReq.GetSlot(), bSuccess ) );
1641         }
1642         break;
1643 
1644         case SID_ADDRESS_DATA_SOURCE:
1645         {
1646             try
1647             {
1648                 Reference< uno::XComponentContext > xORB = ::comphelper::getProcessComponentContext();
1649                 Reference< ui::dialogs::XExecutableDialog > xDialog = ui::dialogs::AddressBookSourcePilot::createWithParent(xORB, nullptr);
1650                 xDialog->execute();
1651             }
1652             catch(const css::uno::Exception&)
1653             {
1654                 DBG_UNHANDLED_EXCEPTION("sfx.appl");
1655             }
1656         }
1657         break;
1658 
1659         case SID_COMP_BIBLIOGRAPHY:
1660             lcl_tryLoadBibliography();
1661         break;
1662     }
1663 }
1664 
1665 void SfxApplication::OfaState_Impl(SfxItemSet &rSet)
1666 {
1667     SvtModuleOptions aModuleOpt;
1668 
1669     if( !aModuleOpt.IsWriter())
1670     {
1671         rSet.DisableItem( FN_LABEL );
1672         rSet.DisableItem( FN_BUSINESS_CARD );
1673         rSet.DisableItem( FN_XFORMS_INIT );
1674     }
1675     if ( comphelper::LibreOfficeKit::isActive() )
1676         rSet.DisableItem( SID_AUTO_CORRECT_DLG );
1677 
1678     bool bMacrosDisabled
1679         = officecfg::Office::Common::Security::Scripting::DisableMacrosExecution::get();
1680     if (bMacrosDisabled)
1681     {
1682         rSet.DisableItem(SID_RUNMACRO);
1683         rSet.DisableItem(SID_MACROORGANIZER);
1684         rSet.DisableItem(SID_SCRIPTORGANIZER);
1685         rSet.DisableItem(SID_BASICIDE_APPEAR);
1686     }
1687 }
1688 
1689 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1690