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