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