summaryrefslogtreecommitdiffstats
path: root/sfx2/source/appl/appserv.cxx
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
commited5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch)
tree7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /sfx2/source/appl/appserv.cxx
parentInitial commit. (diff)
downloadlibreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz
libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sfx2/source/appl/appserv.cxx')
-rw-r--r--sfx2/source/appl/appserv.cxx1726
1 files changed, 1726 insertions, 0 deletions
diff --git a/sfx2/source/appl/appserv.cxx b/sfx2/source/appl/appserv.cxx
new file mode 100644
index 000000000..ee603ab5e
--- /dev/null
+++ b/sfx2/source/appl/appserv.cxx
@@ -0,0 +1,1726 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <config_features.h>
+#include <config_wasm_strip.h>
+
+#include <com/sun/star/drawing/ModuleDispatcher.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/frame/DispatchResultEvent.hpp>
+#include <com/sun/star/frame/DispatchResultState.hpp>
+#include <com/sun/star/frame/DispatchHelper.hpp>
+#include <com/sun/star/frame/UnknownModuleException.hpp>
+#include <com/sun/star/frame/XLayoutManager.hpp>
+#include <com/sun/star/frame/XSynchronousFrameLoader.hpp>
+#include <com/sun/star/sdbc/DriverManager.hpp>
+#include <com/sun/star/text/ModuleDispatcher.hpp>
+#include <com/sun/star/task/OfficeRestartManager.hpp>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <com/sun/star/ui/dialogs/AddressBookSourcePilot.hpp>
+#include <com/sun/star/ui/UIElementType.hpp>
+#include <com/sun/star/ui/XUIElement.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/util/XCloseable.hpp>
+#include <com/sun/star/util/CloseVetoException.hpp>
+#include <org/freedesktop/PackageKit/SyncDbusSessionHelper.hpp>
+
+#include <comphelper/dispatchcommand.hxx>
+#include <comphelper/lok.hxx>
+#include <comphelper/namedvaluecollection.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/propertysequence.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <comphelper/sequence.hxx>
+
+#include <svtools/addresstemplate.hxx>
+#include <svtools/restartdialog.hxx>
+#include <svl/visitem.hxx>
+
+#include <unotools/configmgr.hxx>
+#include <tools/diagnose_ex.h>
+#include <vcl/weld.hxx>
+#include <svl/intitem.hxx>
+#include <svl/eitem.hxx>
+#include <svl/stritem.hxx>
+#include <basic/sbstar.hxx>
+#include <basic/basrdll.hxx>
+#include <basic/sberrors.hxx>
+#include <vcl/help.hxx>
+#include <sal/log.hxx>
+#include <osl/file.hxx>
+#include <vcl/EnumContext.hxx>
+#include <vcl/toolbox.hxx>
+
+#include <unotools/moduleoptions.hxx>
+#include <rtl/bootstrap.hxx>
+
+#include <com/sun/star/frame/ModuleManager.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+#include <sfx2/app.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/msg.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/viewsh.hxx>
+#include <sfx2/docfac.hxx>
+#include <sfx2/strings.hrc>
+#include <sfx2/sfxresid.hxx>
+#include <appdata.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/sfxdlg.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <sorgitm.hxx>
+#include <sfx2/sfxhelp.hxx>
+#include <sfx2/zoomitem.hxx>
+#include <sfx2/templatedlg.hxx>
+#include <sfx2/notebookbar/SfxNotebookBar.hxx>
+#include <sfx2/sidebar/SidebarController.hxx>
+#include <sfx2/safemode.hxx>
+#include <sfx2/sfxuno.hxx>
+#include <sfx2/devtools/DevelopmentToolDockingWindow.hxx>
+
+#include <comphelper/types.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <unotools/confignode.hxx>
+#include <memory>
+
+#include <openuriexternally.hxx>
+
+#include "getbasctlfunction.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::ui;
+
+namespace
+{
+ OUString lcl_getAppName( vcl::EnumContext::Application eApp )
+ {
+ switch ( eApp )
+ {
+ case vcl::EnumContext::Application::Writer:
+ return "Writer";
+ case vcl::EnumContext::Application::Calc:
+ return "Calc";
+ case vcl::EnumContext::Application::Impress:
+ return "Impress";
+ case vcl::EnumContext::Application::Draw:
+ return "Draw";
+ case vcl::EnumContext::Application::Formula:
+ return "Formula";
+ case vcl::EnumContext::Application::Base:
+ return "Base";
+ default:
+ return OUString();
+ }
+ }
+
+ // lp#527938, debian#602953, fdo#33266, i#105408
+ bool lcl_isBaseAvailable()
+ {
+ try
+ {
+ // if we get css::sdbc::DriverManager, libsdbc2 is there
+ // and the bibliography is assumed to work
+ return css::sdbc::DriverManager::create(comphelper::getProcessComponentContext()).is();
+ }
+ catch (const Exception &)
+ {
+ TOOLS_INFO_EXCEPTION("sfx.appl", "assuming Base to be missing");
+ return false;
+ }
+ }
+ void lcl_tryLoadBibliography()
+ {
+ // lp#527938, debian#602953, fdo#33266, i#105408
+ // make sure we actually can instantiate services from base first
+ if(!lcl_isBaseAvailable())
+ {
+ if (officecfg::Office::Common::PackageKit::EnableBaseInstallation::get())
+ {
+ try
+ {
+ using namespace org::freedesktop::PackageKit;
+ using namespace svtools;
+ Reference< XSyncDbusSessionHelper > xSyncDbusSessionHelper(SyncDbusSessionHelper::create(comphelper::getProcessComponentContext()));
+ Sequence< OUString > vPackages { "libreoffice-base" };
+ xSyncDbusSessionHelper->InstallPackageNames(vPackages, OUString());
+ // I'll be back (hopefully)!
+ SolarMutexGuard aGuard;
+ executeRestartDialog(comphelper::getProcessComponentContext(), nullptr, RESTART_REASON_BIBLIOGRAPHY_INSTALL);
+ }
+ catch (const Exception &)
+ {
+ TOOLS_INFO_EXCEPTION("sfx.appl", "trying to install LibreOffice Base");
+ }
+ }
+ return;
+ }
+
+ try // fdo#48775
+ {
+ SfxStringItem aURL(SID_FILE_NAME, ".component:Bibliography/View1");
+ SfxStringItem aRef(SID_REFERER, "private:user");
+ SfxStringItem aTarget(SID_TARGETNAME, "_blank");
+ const SfxViewFrame* pViewFrame = SfxViewFrame::Current();
+ if ( pViewFrame )
+ pViewFrame->GetDispatcher()->ExecuteList(SID_OPENDOC,
+ SfxCallMode::ASYNCHRON, { &aURL, &aRef, &aTarget });
+ }
+ catch (const Exception &)
+ {
+ TOOLS_INFO_EXCEPTION( "sfx.appl", "trying to load bibliography database");
+ }
+ }
+}
+/// Find the correct location of the document (CREDITS.fodt, etc.), and return
+/// it in rURL if found.
+static bool checkURL( const char *pName, const char *pExt, OUString &rURL )
+{
+ using namespace osl;
+ DirectoryItem aDirItem;
+
+#ifdef MACOSX
+ rURL = "$BRAND_BASE_DIR/Resources/" + OUString::createFromAscii( pName ) +
+ OUString::createFromAscii( pExt );
+#else
+ rURL = "$BRAND_BASE_DIR/" + OUString::createFromAscii( pName ) +
+ OUString::createFromAscii( pExt );
+#endif
+ rtl::Bootstrap::expandMacros( rURL );
+
+ if (!rURL.isEmpty())
+ return DirectoryItem::get( rURL, aDirItem ) == DirectoryItem::E_None;
+ else
+ return false;
+}
+
+/// Displays CREDITS or LICENSE in any of the available version
+static void showDocument( const char* pBaseName )
+{
+ try {
+ Reference < XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );
+ auto args(::comphelper::InitPropertySequence({
+ {"ViewOnly", Any(true)},
+ {"ReadOnly", Any(true)}
+ }));
+
+ OUString aURL;
+ if ( checkURL ( pBaseName, ".fodt", aURL ) ||
+ checkURL ( pBaseName, ".html", aURL ) ||
+ checkURL ( pBaseName, "", aURL ) ) {
+ xDesktop->loadComponentFromURL( aURL, "_blank", 0, args );
+ }
+ } catch (const css::uno::Exception &) {
+ }
+}
+
+namespace
+{
+ Reference<XFrame> GetRequestFrame(const SfxRequest& rReq)
+ {
+ const SfxItemSet* pArgs = rReq.GetInternalArgs_Impl();
+ const SfxUnoFrameItem* pItem = nullptr;
+ Reference <XFrame> xFrame;
+ if (pArgs && (pItem = pArgs->GetItemIfSet(SID_FILLFRAME, false)))
+ {
+ xFrame = pItem->GetFrame();
+ }
+ return xFrame;
+ }
+
+ class LicenseDialog : public weld::GenericDialogController
+ {
+ public:
+ LicenseDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "sfx/ui/licensedialog.ui", "LicenseDialog")
+ {
+ }
+
+ virtual short run() override
+ {
+ short nRet = GenericDialogController::run();
+ if (nRet == RET_OK)
+ showDocument("LICENSE");
+ return nRet;
+ }
+ };
+
+ class SafeModeQueryDialog : public weld::MessageDialogController
+ {
+ public:
+ SafeModeQueryDialog(weld::Window* pParent)
+ : MessageDialogController(pParent, "sfx/ui/safemodequerydialog.ui", "SafeModeQueryDialog")
+ {
+ }
+
+ virtual short run() override
+ {
+ short nRet = MessageDialogController::run();
+ if (nRet == RET_OK)
+ {
+ sfx2::SafeMode::putFlag();
+ uno::Reference< uno::XComponentContext > xContext = comphelper::getProcessComponentContext();
+ css::task::OfficeRestartManager::get(xContext)->requestRestart(
+ css::uno::Reference< css::task::XInteractionHandler >());
+ }
+ return nRet;
+ }
+ };
+}
+
+weld::Window* SfxRequest::GetFrameWeld() const
+{
+ const SfxItemSet* pIntArgs = GetInternalArgs_Impl();
+ const SfxUnoAnyItem* pItem = nullptr;
+ if (pIntArgs && (pItem = pIntArgs->GetItemIfSet(SID_DIALOG_PARENT, false)))
+ {
+ auto aAny = pItem->GetValue();
+ Reference<awt::XWindow> xWindow;
+ aAny >>= xWindow;
+ return Application::GetFrameWeld(xWindow);
+ }
+
+ Reference<XFrame> xFrame(GetRequestFrame(*this));
+ if (!xFrame)
+ {
+ SAL_WARN("sfx.appl", "no parent for dialogs");
+ return nullptr;
+ }
+ return Application::GetFrameWeld(xFrame->getContainerWindow());
+}
+
+void SfxApplication::MiscExec_Impl( SfxRequest& rReq )
+{
+ bool bDone = false;
+ switch ( rReq.GetSlot() )
+ {
+ case SID_SETOPTIONS:
+ {
+ if( rReq.GetArgs() )
+ SetOptions_Impl( *rReq.GetArgs() );
+ break;
+ }
+
+ case SID_QUITAPP:
+ case SID_LOGOUT:
+ {
+ // protect against reentrant calls
+ if ( pImpl->bInQuit )
+ return;
+
+ if ( rReq.GetSlot() == SID_LOGOUT )
+ {
+ for ( SfxObjectShell *pObjSh = SfxObjectShell::GetFirst();
+ pObjSh; pObjSh = SfxObjectShell::GetNext( *pObjSh ) )
+ {
+ if ( !pObjSh->IsModified() )
+ continue;
+
+ SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pObjSh );
+ if ( !pFrame || !pFrame->GetWindow().IsReallyVisible() )
+ continue;
+
+ if (pObjSh->PrepareClose())
+ pObjSh->SetModified( false );
+ else
+ return;
+ }
+
+ SfxStringItem aNameItem( SID_FILE_NAME, "vnd.sun.star.cmd:logout" );
+ SfxStringItem aReferer( SID_REFERER, "private/user" );
+ pImpl->pAppDispat->ExecuteList(SID_OPENDOC,
+ SfxCallMode::SLOT, { &aNameItem, &aReferer });
+ return;
+ }
+
+ // try from nested requests again after 100ms
+ if( Application::GetDispatchLevel() > 1 )
+ {
+ /* Don't save the request for closing the application and try it later
+ again. This is an UI bound functionality ... and the user will try it again
+ if the dialog is closed. But we should not close the application automatically
+ if this dialog is closed by the user ...
+ So we ignore this request now and wait for a new user decision.
+ */
+ SAL_INFO("sfx.appl", "QueryExit => sal_False, DispatchLevel == " << Application::GetDispatchLevel() );
+ return;
+ }
+
+ // block reentrant calls
+ pImpl->bInQuit = true;
+ Reference < XDesktop2 > xDesktop = Desktop::create ( ::comphelper::getProcessComponentContext() );
+
+ rReq.ForgetAllArgs();
+
+ // if terminate() failed, pImpl->bInQuit will now be sal_False, allowing further calls of SID_QUITAPP
+ bool bTerminated = xDesktop->terminate();
+ if (!bTerminated)
+ // if terminate() was successful, SfxApplication is now dead!
+ pImpl->bInQuit = false;
+
+ // Set return value, terminate if possible
+ rReq.SetReturnValue( SfxBoolItem( rReq.GetSlot(), bTerminated ) );
+ return;
+ }
+
+ case SID_CONFIG:
+ case SID_TOOLBOXOPTIONS:
+ case SID_CONFIGSTATUSBAR:
+ case SID_CONFIGMENU:
+ case SID_CONFIGACCEL:
+ case SID_CONFIGEVENT:
+ {
+ SfxAbstractDialogFactory* pFact =
+ SfxAbstractDialogFactory::Create();
+
+ const SfxStringItem* pStringItem = rReq.GetArg<SfxStringItem>(SID_CONFIG);
+
+ SfxItemSetFixed<SID_CONFIG, SID_CONFIG> aSet( GetPool() );
+
+ if ( pStringItem )
+ {
+ aSet.Put( SfxStringItem(
+ SID_CONFIG, pStringItem->GetValue() ) );
+ }
+
+ Reference <XFrame> xFrame(GetRequestFrame(rReq));
+ ScopedVclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateCustomizeTabDialog(rReq.GetFrameWeld(),
+ &aSet, xFrame ));
+
+ const short nRet = pDlg->Execute();
+
+ if ( nRet )
+ bDone = true;
+ break;
+ }
+
+ case SID_CLOSEDOCS:
+ {
+
+ Reference < XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );
+ Reference< XIndexAccess > xTasks = xDesktop->getFrames();
+ if ( !xTasks.is() )
+ break;
+
+ sal_Int32 n=0;
+ do
+ {
+ if ( xTasks->getCount() <= n )
+ break;
+
+ Any aAny = xTasks->getByIndex(n);
+ Reference < XCloseable > xTask;
+ aAny >>= xTask;
+ try
+ {
+ xTask->close(true);
+ n++;
+ }
+ catch( CloseVetoException& )
+ {
+ }
+ }
+ while( true );
+
+ bool bOk = ( n == 0);
+ rReq.SetReturnValue( SfxBoolItem( 0, bOk ) );
+ bDone = true;
+ break;
+ }
+
+ case SID_SAVEDOCS:
+ {
+ bool bOK = true;
+ for ( SfxObjectShell *pObjSh = SfxObjectShell::GetFirst();
+ pObjSh;
+ pObjSh = SfxObjectShell::GetNext( *pObjSh ) )
+ {
+ SfxRequest aReq( SID_SAVEDOC, SfxCallMode::SLOT, pObjSh->GetPool() );
+ if ( pObjSh->IsModified() && !pObjSh->isSaveLocked())
+ {
+ pObjSh->ExecuteSlot( aReq );
+ const SfxBoolItem *pItem = dynamic_cast<const SfxBoolItem*>( aReq.GetReturnValue() );
+ if ( !pItem || !pItem->GetValue() )
+ bOK = false;
+ }
+ }
+
+ rReq.SetReturnValue( SfxBoolItem( 0, bOK ) );
+ rReq.Done();
+ break;
+ }
+
+ case SID_SEND_FEEDBACK:
+ {
+ OUString module = SfxHelp::GetCurrentModuleIdentifier();
+ OUString sURL(officecfg::Office::Common::Menus::SendFeedbackURL::get() + //officecfg/registry/data/org/openoffice/Office/Common.xcu => https://hub.libreoffice.org/send-feedback/
+ "?LOversion=" + utl::ConfigManager::getAboutBoxProductVersion() +
+ "&LOlocale=" + utl::ConfigManager::getUILocale() +
+ "&LOmodule=" + module.subView(module.lastIndexOf('.') + 1 ) );
+ sfx2::openUriExternally(sURL, false, rReq.GetFrameWeld());
+ break;
+ }
+
+ case SID_Q_AND_A:
+ {
+ // Askbot has URL's normalized to languages, not locales
+ // Get language from locale: ll or lll or ll-CC or lll-CC
+
+ OUString sURL(officecfg::Office::Common::Menus::QA_URL::get() + //https://hub.libreoffice.org/forum/
+ "?LOlocale=" + utl::ConfigManager::getUILocale());
+ sfx2::openUriExternally(sURL, false, rReq.GetFrameWeld());
+ break;
+ }
+ case SID_DOCUMENTATION:
+ {
+ // Open documentation page based on locales
+ OUString sURL(officecfg::Office::Common::Menus::DocumentationURL::get() + //https://hub.libreoffice.org/documentation/
+ "?LOlocale=" + utl::ConfigManager::getUILocale());
+ sfx2::openUriExternally(sURL, false, rReq.GetFrameWeld());
+ break;
+ }
+#if !ENABLE_WASM_STRIP_PINGUSER
+ case SID_GETINVOLVED:
+ {
+ // Open get involved/join us page based on locales
+ OUString sURL(officecfg::Office::Common::Menus::GetInvolvedURL::get() + //https://hub.libreoffice.org/joinus/
+ "?LOlocale=" + utl::ConfigManager::getUILocale());
+ sfx2::openUriExternally(sURL, false, rReq.GetFrameWeld());
+ break;
+ }
+ case SID_DONATION:
+ {
+ // Open donation page based on language + script (BCP47) with language as fall back.
+ OUString aLang = LanguageTag(utl::ConfigManager::getUILocale()).getLanguage();
+ OUString aBcp47 = LanguageTag(utl::ConfigManager::getUILocale()).getBcp47();
+ OUString sURL(officecfg::Office::Common::Menus::DonationURL::get() + //https://hub.libreoffice.org/donation/
+ "?BCP47=" + aBcp47 + "&LOlang=" + aLang );
+ sfx2::openUriExternally(sURL, false, rReq.GetFrameWeld());
+ break;
+ }
+ case SID_WHATSNEW:
+ {
+ // Open release notes depending on version and locale
+ OUString sURL(officecfg::Office::Common::Menus::ReleaseNotesURL::get() + //https://hub.libreoffice.org/ReleaseNotes/
+ "?LOvers=" + utl::ConfigManager::getProductVersion() +
+ "&LOlocale=" + LanguageTag(utl::ConfigManager::getUILocale()).getBcp47() );
+ sfx2::openUriExternally(sURL, false, rReq.GetFrameWeld());
+ break;
+ }
+ case SID_HYPHENATIONMISSING:
+ {
+ // Open wiki page about hyphenation
+ OUString sURL(officecfg::Office::Common::Menus::HyphenationMissingURL::get() + //https://hub.libreoffice.org/HyphenationMissing/
+ "?LOlocale=" + utl::ConfigManager::getUILocale());
+ sfx2::openUriExternally(sURL, false, rReq.GetFrameWeld());
+ break;
+ }
+#endif
+ case SID_SHOW_LICENSE:
+ {
+ LicenseDialog aDialog(rReq.GetFrameWeld());
+ aDialog.run();
+ break;
+ }
+
+ case SID_SHOW_CREDITS:
+ {
+ showDocument( "CREDITS" );
+ break;
+ }
+
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ case SID_HELPINDEX:
+ {
+ Help* pHelp = Application::GetHelp();
+ if ( pHelp )
+ {
+ pHelp->Start(".uno:HelpIndex", rReq.GetFrameWeld()); // show start page
+ bDone = true;
+ }
+ break;
+ }
+
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ case SID_HELPTIPS:
+ {
+ // Evaluate Parameter
+ const SfxBoolItem* pOnItem = rReq.GetArg<SfxBoolItem>(SID_HELPTIPS);
+ bool bOn = pOnItem
+ ? pOnItem->GetValue()
+ : !Help::IsQuickHelpEnabled();
+
+ if ( bOn )
+ Help::EnableQuickHelp();
+ else
+ Help::DisableQuickHelp();
+ auto xChanges = comphelper::ConfigurationChanges::create();
+ officecfg::Office::Common::Help::Tip::set(bOn, xChanges);
+ xChanges->commit();
+ Invalidate(SID_HELPTIPS);
+ bDone = true;
+
+ // Record if possible
+ if ( !rReq.IsAPI() )
+ rReq.AppendItem( SfxBoolItem( SID_HELPTIPS, bOn) );
+ break;
+ }
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ case SID_EXTENDEDHELP:
+ {
+ Help::StartExtHelp();
+ break;
+ }
+ case SID_HELPBALLOONS:
+ {
+ // Evaluate Parameter
+ const SfxBoolItem* pOnItem = rReq.GetArg<SfxBoolItem>(SID_HELPBALLOONS);
+ bool bOn = pOnItem
+ ? pOnItem->GetValue()
+ : !Help::IsBalloonHelpEnabled();
+
+ if ( bOn )
+ Help::EnableBalloonHelp();
+ else
+ Help::DisableBalloonHelp();
+ auto xChanges = comphelper::ConfigurationChanges::create();
+ officecfg::Office::Common::Help::ExtendedTip::set(bOn, xChanges);
+ xChanges->commit();
+ Invalidate(SID_HELPBALLOONS);
+ bDone = true;
+
+ // Record if possible
+ if ( !rReq.IsAPI() )
+ rReq.AppendItem( SfxBoolItem( SID_HELPBALLOONS, bOn) );
+ break;
+ }
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if !ENABLE_WASM_STRIP_PINGUSER
+ case SID_TIPOFTHEDAY:
+ {
+ SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
+ ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateTipOfTheDayDialog(rReq.GetFrameWeld()));
+ pDlg->StartExecuteAsync(nullptr);
+ bDone = true;
+ break;
+ }
+#endif
+
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ case SID_ABOUT:
+ {
+ SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
+ ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateAboutDialog(rReq.GetFrameWeld()));
+ pDlg->StartExecuteAsync(nullptr);
+ bDone = true;
+ break;
+ }
+
+ case SID_TEMPLATE_MANAGER:
+ {
+ SfxTemplateManagerDlg aDialog(rReq.GetFrameWeld());
+ aDialog.run();
+ bDone = true;
+ break;
+ }
+
+ case SID_TEMPLATE_ADDRESSBOOKSOURCE:
+ {
+ svt::AddressBookSourceDialog aDialog(rReq.GetFrameWeld(), ::comphelper::getProcessComponentContext());
+ aDialog.run();
+ bDone = true;
+ break;
+ }
+
+#if HAVE_FEATURE_SCRIPTING
+ case SID_BASICSTOP:
+ StarBASIC::Stop();
+ break;
+
+ case SID_BASICBREAK :
+ BasicDLL::BasicBreak();
+ break;
+#endif
+
+ case SID_ZOOM_50_PERCENT:
+ case SID_ZOOM_75_PERCENT:
+ case SID_ZOOM_100_PERCENT:
+ case SID_ZOOM_150_PERCENT:
+ case SID_ZOOM_200_PERCENT:
+ case SID_ZOOM_OPTIMAL:
+ case SID_ZOOM_ENTIRE_PAGE:
+ case SID_ZOOM_PAGE_WIDTH:
+ {
+ SfxObjectShell* pCurrentShell = SfxObjectShell::Current();
+ if (!pCurrentShell)
+ return;
+
+ // make sure aZoom is initialized with a proper value if SetType
+ // doesn't work
+ SvxZoomItem aZoom( SvxZoomType::PERCENT, 100 );
+
+ switch (rReq.GetSlot())
+ {
+ case SID_ZOOM_50_PERCENT:
+ aZoom.SetValue(50);
+ break;
+ case SID_ZOOM_75_PERCENT:
+ aZoom.SetValue(75);
+ break;
+ case SID_ZOOM_100_PERCENT:
+ aZoom.SetValue(100);
+ break;
+ case SID_ZOOM_150_PERCENT:
+ aZoom.SetValue(150);
+ break;
+ case SID_ZOOM_200_PERCENT:
+ aZoom.SetValue(200);
+ break;
+ case SID_ZOOM_OPTIMAL:
+ aZoom.SetType( SvxZoomType::OPTIMAL );
+ break;
+ case SID_ZOOM_ENTIRE_PAGE:
+ aZoom.SetType( SvxZoomType::WHOLEPAGE );
+ break;
+ case SID_ZOOM_PAGE_WIDTH:
+ aZoom.SetType( SvxZoomType::PAGEWIDTH );
+ break;
+ }
+
+ pCurrentShell->GetDispatcher()->ExecuteList(SID_ATTR_ZOOM, SfxCallMode::ASYNCHRON, { &aZoom });
+
+ break;
+ }
+ case SID_TOOLBAR_MODE:
+ {
+ const SfxStringItem* pModeName = rReq.GetArg<SfxStringItem>( SID_TOOLBAR_MODE );
+
+ if ( !pModeName )
+ {
+ bDone = true;
+ break;
+ }
+
+ OUString aNewName(pModeName->GetValue());
+ uno::Reference< uno::XComponentContext > xContext =
+ ::comphelper::getProcessComponentContext();
+
+ // Get information about current frame and module
+ Reference<XFrame> xCurrentFrame;
+ vcl::EnumContext::Application eCurrentApp = vcl::EnumContext::Application::NONE;
+ OUString aCurrentMode;
+
+ SfxViewFrame* pViewFrame = SfxViewFrame::Current();
+ if( pViewFrame )
+ {
+ xCurrentFrame = pViewFrame->GetFrame().GetFrameInterface();
+
+ const Reference<frame::XModuleManager> xModuleManager = frame::ModuleManager::create( xContext );
+ eCurrentApp = vcl::EnumContext::GetApplicationEnum( xModuleManager->identify( xCurrentFrame ) );
+
+ OUString aPath = "org.openoffice.Office.UI.ToolbarMode/Applications/" +
+ lcl_getAppName( eCurrentApp );
+
+ const utl::OConfigurationTreeRoot aAppNode(
+ xContext,
+ aPath,
+ true);
+ if ( !aAppNode.isValid() )
+ {
+ bDone = true;
+ break;
+ }
+
+ aCurrentMode = comphelper::getString( aAppNode.getNodeValue( "Active" ) );
+
+ if ( aCurrentMode == aNewName )
+ {
+ bDone = true;
+ break;
+ }
+
+ // Save new toolbar mode for a current module
+ aAppNode.setNodeValue( "Active", Any( aNewName ) );
+ aAppNode.commit();
+ }
+
+ // Apply settings for all frames
+ pViewFrame = SfxViewFrame::GetFirst();
+ while( pViewFrame )
+ {
+ Reference<XFrame> xFrame = pViewFrame->GetFrame().GetFrameInterface();
+
+ // We want to change mode only for a current app module, ignore other apps
+ const Reference<frame::XModuleManager> xModuleManager = frame::ModuleManager::create( xContext );
+ vcl::EnumContext::Application eApp = vcl::EnumContext::GetApplicationEnum( xModuleManager->identify( xFrame ) );
+ if ( eApp != eCurrentApp )
+ {
+ pViewFrame = SfxViewFrame::GetNext( *pViewFrame );
+ continue;
+ }
+
+ Reference<css::beans::XPropertySet> xPropSet( xFrame, UNO_QUERY );
+ Reference<css::frame::XLayoutManager> xLayoutManager;
+ if ( xPropSet.is() )
+ {
+ try
+ {
+ Any aValue = xPropSet->getPropertyValue( "LayoutManager" );
+ aValue >>= xLayoutManager;
+ }
+ catch ( const css::uno::RuntimeException& )
+ {
+ throw;
+ }
+ catch ( css::uno::Exception& )
+ {
+ }
+ }
+
+ if ( xLayoutManager.is() )
+ {
+ css::uno::Sequence<OUString> aMandatoryToolbars;
+ css::uno::Sequence<OUString> aUserToolbars;
+ std::vector<OUString> aBackupList;
+ OUString aSidebarMode;
+
+ OUString aPath = "org.openoffice.Office.UI.ToolbarMode/Applications/" +
+ lcl_getAppName( eApp ) +
+ "/Modes";
+
+ // Read mode settings
+ const utl::OConfigurationTreeRoot aModesNode(
+ xContext,
+ aPath,
+ true);
+ if ( !aModesNode.isValid() )
+ {
+ bDone = true;
+ break;
+ }
+
+ const Sequence<OUString> aModeNodeNames( aModesNode.getNodeNames() );
+
+ for ( const auto& rModeNodeName : aModeNodeNames )
+ {
+ const utl::OConfigurationNode aModeNode( aModesNode.openNode( rModeNodeName ) );
+ if ( !aModeNode.isValid() )
+ continue;
+
+ OUString aCommandArg = comphelper::getString( aModeNode.getNodeValue( "CommandArg" ) );
+
+ if ( aCommandArg == aNewName )
+ {
+ aMandatoryToolbars = aModeNode.getNodeValue( "Toolbars" ).get< uno::Sequence<OUString> >();
+ aUserToolbars = aModeNode.getNodeValue( "UserToolbars" ).get< uno::Sequence<OUString> >();
+ aSidebarMode = comphelper::getString( aModeNode.getNodeValue( "Sidebar" ) );
+ break;
+ }
+ }
+
+ // Backup visible toolbar list and hide all toolbars
+ const Sequence<Reference<XUIElement>> aUIElements = xLayoutManager->getElements();
+ for ( const Reference< XUIElement >& xUIElement : aUIElements )
+ {
+ Reference< XPropertySet > xPropertySet( xUIElement, UNO_QUERY );
+ if ( xPropertySet.is() && xUIElement.is() )
+ {
+ try
+ {
+ OUString aResName;
+ sal_Int16 nType( -1 );
+ xPropertySet->getPropertyValue( "Type" ) >>= nType;
+ xPropertySet->getPropertyValue( "ResourceURL" ) >>= aResName;
+
+ if (( nType == css::ui::UIElementType::TOOLBAR ) &&
+ !aResName.isEmpty() )
+ {
+ if ( xLayoutManager->isElementVisible( aResName ) )
+ {
+ aBackupList.push_back( aResName );
+ }
+ xLayoutManager->hideElement( aResName );
+ }
+ }
+ catch ( const Exception& )
+ {
+ }
+ }
+ }
+
+ // Show/Hide the Notebookbar
+ const SfxStringItem pItem(SID_NOTEBOOKBAR, aNewName);
+ pViewFrame->GetDispatcher()->ExecuteList(SID_NOTEBOOKBAR, SfxCallMode::SYNCHRON, {&pItem});
+
+ // Show toolbars
+ for ( const OUString& rName : std::as_const(aMandatoryToolbars) )
+ {
+ xLayoutManager->createElement( rName );
+ xLayoutManager->showElement( rName );
+ }
+
+ for ( const OUString& rName : std::as_const(aUserToolbars) )
+ {
+ xLayoutManager->createElement( rName );
+ xLayoutManager->showElement( rName );
+ }
+
+ // Sidebar
+ pViewFrame->ShowChildWindow( SID_SIDEBAR );
+
+ if (comphelper::LibreOfficeKit::isActive())
+ aSidebarMode = "Opened";
+
+ sfx2::sidebar::SidebarController* pSidebar =
+ sfx2::sidebar::SidebarController::GetSidebarControllerForFrame( xFrame );
+ if ( pSidebar )
+ {
+ if ( aSidebarMode == "Arrow" )
+ {
+ pSidebar->FadeOut();
+ }
+ else if ( aSidebarMode == "Tabs" )
+ {
+ pSidebar->FadeIn();
+ pSidebar->RequestOpenDeck();
+ pSidebar->RequestCloseDeck();
+ }
+ else if ( aSidebarMode == "Opened" )
+ {
+ pSidebar->FadeIn();
+ pSidebar->RequestOpenDeck();
+ }
+ }
+
+ // Save settings
+ if ( pViewFrame == SfxViewFrame::Current() )
+ {
+ css::uno::Sequence<OUString> aBackup( comphelper::containerToSequence(aBackupList) );
+
+ for ( const auto& rModeNodeName : aModeNodeNames )
+ {
+ const utl::OConfigurationNode aModeNode( aModesNode.openNode( rModeNodeName ) );
+ if ( !aModeNode.isValid() )
+ continue;
+
+ OUString aCommandArg = comphelper::getString( aModeNode.getNodeValue( "CommandArg" ) );
+
+ if ( aCommandArg == aCurrentMode )
+ {
+ aModeNode.setNodeValue( "UserToolbars", Any( aBackup ) );
+ break;
+ }
+ }
+ aModesNode.commit();
+ }
+ }
+
+ pViewFrame = SfxViewFrame::GetNext(*pViewFrame);
+ }
+
+ bDone = true;
+ break;
+ }
+ case SID_TOOLBAR_MODE_UI:
+ {
+ SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
+ ScopedVclPtr<VclAbstractDialog> pDlg(
+ pFact->CreateToolbarmodeDialog(rReq.GetFrameWeld()));
+ pDlg->Execute();
+ bDone = true;
+ break;
+ }
+ case SID_AVAILABLE_TOOLBARS:
+ {
+ const SfxStringItem* pToolbarName = rReq.GetArg<SfxStringItem>(SID_AVAILABLE_TOOLBARS);
+
+ if ( pToolbarName )
+ {
+ Reference < XDesktop2 > xDesktop = Desktop::create ( ::comphelper::getProcessComponentContext() );
+ Reference< XFrame > xFrame = xDesktop->getActiveFrame();
+
+ Reference< css::beans::XPropertySet > xPropSet( xFrame, UNO_QUERY );
+ Reference< css::frame::XLayoutManager > xLayoutManager;
+ if ( xPropSet.is() )
+ {
+ try
+ {
+ Any aValue = xPropSet->getPropertyValue("LayoutManager");
+ aValue >>= xLayoutManager;
+ }
+ catch ( const css::uno::RuntimeException& )
+ {
+ throw;
+ }
+ catch ( css::uno::Exception& )
+ {
+ }
+ }
+
+ if ( xLayoutManager.is() )
+ {
+ OUString aToolbarName = "private:resource/toolbar/" +
+ pToolbarName->GetValue();
+
+ // Evaluate Parameter
+ bool bShow( !xLayoutManager->isElementVisible( aToolbarName ));
+
+ if ( bShow )
+ {
+ xLayoutManager->createElement( aToolbarName );
+ xLayoutManager->showElement( aToolbarName );
+ }
+ else
+ xLayoutManager->hideElement( aToolbarName );
+ }
+ }
+
+ bDone = true;
+ break;
+ }
+ case SID_MENUBAR:
+ {
+ sfx2::SfxNotebookBar::ToggleMenubar();
+ bDone = true;
+ break;
+ }
+ case SID_DEVELOPMENT_TOOLS_DOCKING_WINDOW:
+ {
+ SfxViewShell* pViewShell = SfxViewShell::Current();
+ SfxViewFrame* pViewFrame = pViewShell->GetViewFrame();
+ auto nID = rReq.GetSlot();
+ pViewFrame->ToggleChildWindow(nID);
+
+ bDone = true;
+ break;
+ }
+ case SID_INSPECT_SELECTED_OBJECT:
+ {
+ SfxViewShell* pViewShell = SfxViewShell::Current();
+ SfxViewFrame* pViewFrame = pViewShell->GetViewFrame();
+
+ pViewFrame->ShowChildWindow(SID_DEVELOPMENT_TOOLS_DOCKING_WINDOW, true);
+
+ SfxChildWindow* pChild = pViewFrame->GetChildWindow(SID_DEVELOPMENT_TOOLS_DOCKING_WINDOW);
+ if (!pChild)
+ return;
+
+ auto pDockingWin = dynamic_cast<DevelopmentToolDockingWindow*>(pChild->GetWindow());
+ if (pDockingWin)
+ {
+ pDockingWin->changeToCurrentSelection();
+ }
+
+ bDone = true;
+ break;
+ }
+ case SID_SAFE_MODE:
+ {
+ SafeModeQueryDialog aDialog(rReq.GetFrameWeld());
+ aDialog.run();
+ break;
+ }
+ case SID_TOOLBAR_LOCK:
+ {
+ SfxViewFrame* pViewFrame = SfxViewFrame::Current();
+ if (pViewFrame)
+ {
+ Reference<XFrame> xCurrentFrame;
+ uno::Reference<uno::XComponentContext> xContext
+ = ::comphelper::getProcessComponentContext();
+ xCurrentFrame = pViewFrame->GetFrame().GetFrameInterface();
+ const Reference<frame::XModuleManager> xModuleManager
+ = frame::ModuleManager::create(xContext);
+ const utl::OConfigurationTreeRoot aAppNode(
+ xContext, "org.openoffice.Office.UI.GlobalSettings/Toolbars/States", true);
+ if (aAppNode.isValid())
+ {
+ bool isLocked = comphelper::getBOOL(aAppNode.getNodeValue("Locked"));
+ aAppNode.setNodeValue("Locked", Any(!isLocked));
+ aAppNode.commit();
+ //TODO: apply immediately w/o restart needed
+ SolarMutexGuard aGuard;
+ svtools::executeRestartDialog(comphelper::getProcessComponentContext(), nullptr,
+ svtools::RESTART_REASON_UI_CHANGE);
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ if ( bDone )
+ rReq.Done();
+}
+
+void SfxApplication::MiscState_Impl(SfxItemSet &rSet)
+{
+ const WhichRangesContainer & pRanges = rSet.GetRanges();
+ DBG_ASSERT(!pRanges.empty(), "Set without range");
+ for ( auto const & pRange : pRanges )
+ {
+ for(sal_uInt16 nWhich = pRange.first; nWhich <= pRange.second; ++nWhich)
+ {
+ switch(nWhich)
+ {
+ case SID_TEMPLATE_ADDRESSBOOKSOURCE:
+ if ( !SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::EModule::DATABASE) )
+ rSet.Put(SfxVisibilityItem(nWhich, false));
+ break;
+ case SID_QUITAPP:
+ {
+ if ( pImpl->nDocModalMode )
+ rSet.DisableItem(nWhich);
+ else
+ rSet.Put(SfxStringItem(nWhich, SfxResId(STR_QUITAPP)));
+ break;
+ }
+
+ case SID_CONFIG:
+ case SID_TOOLBOXOPTIONS:
+ case SID_CONFIGSTATUSBAR:
+ case SID_CONFIGMENU:
+ case SID_CONFIGACCEL:
+ case SID_CONFIGEVENT:
+ {
+ if( officecfg::Office::Common::Misc::DisableUICustomization::get() )
+ rSet.DisableItem(nWhich);
+ break;
+ }
+
+#if HAVE_FEATURE_SCRIPTING
+ case SID_BASICSTOP:
+ if ( !StarBASIC::IsRunning() )
+ rSet.DisableItem(nWhich);
+ break;
+#endif
+
+ case SID_HELPTIPS:
+ {
+ rSet.Put( SfxBoolItem( SID_HELPTIPS, Help::IsQuickHelpEnabled() ) );
+ }
+ break;
+ case SID_HELPBALLOONS:
+ {
+ rSet.Put( SfxBoolItem( SID_HELPBALLOONS, Help::IsBalloonHelpEnabled() ) );
+ }
+ break;
+
+ case SID_EXTENDEDHELP:
+ {
+ }
+ break;
+
+ case SID_CLOSEDOCS:
+ {
+ Reference < XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );
+ Reference< XIndexAccess > xTasks = xDesktop->getFrames();
+ if ( !xTasks.is() || !xTasks->getCount() )
+ rSet.DisableItem(nWhich);
+ break;
+ }
+
+ case SID_SAVEDOCS:
+ {
+ bool bModified = false;
+ for ( SfxObjectShell *pObjSh = SfxObjectShell::GetFirst();
+ pObjSh;
+ pObjSh = SfxObjectShell::GetNext( *pObjSh ) )
+ {
+ if ( pObjSh->IsModified() && !pObjSh->isSaveLocked() )
+ {
+ bModified = true;
+ break;
+ }
+ }
+
+ if ( !bModified )
+ rSet.DisableItem( nWhich );
+ break;
+ }
+
+ case SID_TEMPLATE_MANAGER:
+ {
+ if ( !officecfg::Office::Common::Misc::ExperimentalMode::get() )
+ {
+ rSet.DisableItem( nWhich );
+ rSet.Put( SfxVisibilityItem( nWhich, false ) );
+ }
+ }
+ break;
+
+ case SID_ZOOM_50_PERCENT:
+ case SID_ZOOM_75_PERCENT:
+ case SID_ZOOM_100_PERCENT:
+ case SID_ZOOM_150_PERCENT:
+ case SID_ZOOM_200_PERCENT:
+ case SID_ZOOM_OPTIMAL:
+ case SID_ZOOM_ENTIRE_PAGE:
+ case SID_ZOOM_PAGE_WIDTH:
+ {
+ SfxObjectShell* pCurrentShell = SfxObjectShell::Current();
+
+ const SfxPoolItem *pItem;
+ SfxItemState aState = pCurrentShell ?
+ pCurrentShell->GetDispatcher()->QueryState(SID_ATTR_ZOOM, pItem) : SfxItemState::DISABLED;
+ if ( aState == SfxItemState::DISABLED )
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_MENUBAR:
+ {
+ Reference < XDesktop2 > xDesktop = Desktop::create ( ::comphelper::getProcessComponentContext() );
+ Reference< XFrame > xFrame = xDesktop->getActiveFrame();
+
+ Reference< css::beans::XPropertySet > xPropSet( xFrame, UNO_QUERY );
+ Reference< css::frame::XLayoutManager > xLayoutManager;
+ if ( xPropSet.is() )
+ {
+ try
+ {
+ Any aValue = xPropSet->getPropertyValue("LayoutManager");
+ aValue >>= xLayoutManager;
+ }
+ catch ( const css::uno::RuntimeException& )
+ {
+ throw;
+ }
+ catch ( css::uno::Exception& )
+ {
+ }
+ }
+
+ if ( xLayoutManager.is() )
+ {
+ const bool bState
+ = xLayoutManager->getElement("private:resource/menubar/menubar").is()
+ && xLayoutManager->isElementVisible(
+ "private:resource/menubar/menubar");
+
+ SfxBoolItem aItem( SID_MENUBAR, bState );
+ rSet.Put( aItem );
+ }
+ break;
+ }
+ case SID_SAFE_MODE:
+ {
+ // no restart in safe mode when already in safe mode
+ if ( Application::IsSafeModeEnabled() )
+ rSet.DisableItem( SID_SAFE_MODE );
+ break;
+ }
+ case SID_DEVELOPMENT_TOOLS_DOCKING_WINDOW:
+ {
+ bool bSuccess = false;
+ auto* pViewShell = SfxViewShell::Current();
+ if (pViewShell)
+ {
+ auto* pViewFrame = pViewShell->GetViewFrame();
+ if (pViewFrame && pViewFrame->KnowsChildWindow(nWhich))
+ {
+ rSet.Put(SfxBoolItem(nWhich, pViewFrame->HasChildWindow(nWhich)));
+ bSuccess = true;
+ }
+ }
+
+ if (!bSuccess)
+ rSet.DisableItem(nWhich);
+ }
+ break;
+ case SID_INSPECT_SELECTED_OBJECT:
+ {
+ bool bSuccess = false;
+ auto* pViewShell = SfxViewShell::Current();
+ if (pViewShell)
+ {
+ auto* pViewFrame = pViewShell->GetViewFrame();
+ if (pViewFrame && pViewFrame->KnowsChildWindow(SID_DEVELOPMENT_TOOLS_DOCKING_WINDOW))
+ {
+ bSuccess = true;
+ }
+ }
+ if (!bSuccess)
+ rSet.DisableItem(nWhich);
+ }
+ break;
+ case SID_TOOLBAR_LOCK:
+ {
+ rSet.Put( SfxBoolItem( SID_TOOLBAR_LOCK, ToolBox::AlwaysLocked() ));
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+}
+
+#if HAVE_FEATURE_SCRIPTING
+
+#ifndef DISABLE_DYNLOADING
+
+typedef rtl_uString* (*basicide_choose_macro)(void*, void*, void*, sal_Bool);
+
+#else
+
+extern "C" rtl_uString* basicide_choose_macro(void*, void*, void*, sal_Bool);
+
+#endif
+
+static OUString ChooseMacro(weld::Window* pParent, const Reference<XModel>& rxLimitToDocument, const Reference<XFrame>& xDocFrame, bool bChooseOnly)
+{
+#ifndef DISABLE_DYNLOADING
+ basicide_choose_macro pSymbol = reinterpret_cast<basicide_choose_macro>(sfx2::getBasctlFunction("basicide_choose_macro"));
+#else
+#define pSymbol basicide_choose_macro
+#endif
+
+ // call basicide_choose_macro in basctl
+ rtl_uString* pScriptURL = pSymbol(pParent, rxLimitToDocument.get(), xDocFrame.get(), bChooseOnly);
+ OUString aScriptURL( pScriptURL );
+ rtl_uString_release( pScriptURL );
+ return aScriptURL;
+
+#ifdef DISABLE_DYNLOADING
+#undef pSymbol
+#endif
+}
+
+#endif
+
+namespace
+{
+#if HAVE_FEATURE_SCRIPTING
+ weld::Window* lcl_getDialogParent(const Reference<XFrame>& rxFrame)
+ {
+ Reference<awt::XWindow> xContainerWindow;
+ if (rxFrame.is())
+ xContainerWindow = rxFrame->getContainerWindow();
+ return Application::GetFrameWeld(xContainerWindow);
+ }
+
+ SfxViewFrame* lcl_getBasicIDEViewFrame( SfxObjectShell const * i_pBasicIDE )
+ {
+ SfxViewFrame* pView = SfxViewFrame::GetFirst( i_pBasicIDE );
+ while ( pView )
+ {
+ if ( pView->GetObjectShell()->GetFactory().GetDocumentServiceName() == "com.sun.star.script.BasicIDE" )
+ break;
+ pView = SfxViewFrame::GetNext( *pView, i_pBasicIDE );
+ }
+ return pView;
+ }
+ Reference< XFrame > lcl_findStartModuleFrame( const Reference<XComponentContext> & rxContext )
+ {
+ try
+ {
+ Reference < XDesktop2 > xDesktop = Desktop::create( rxContext );
+ Reference < XIndexAccess > xContainer( xDesktop->getFrames(), UNO_QUERY_THROW );
+
+ Reference< XModuleManager2 > xCheck = ModuleManager::create(rxContext);
+
+ sal_Int32 nCount = xContainer->getCount();
+ for ( sal_Int32 i=0; i<nCount; ++i )
+ {
+ try
+ {
+ Reference < XFrame > xFrame( xContainer->getByIndex(i), UNO_QUERY_THROW );
+ OUString sModule = xCheck->identify( xFrame );
+ if ( sModule == "com.sun.star.frame.StartModule" )
+ return xFrame;
+ }
+ catch( const UnknownModuleException& )
+ {
+ // silence
+ }
+ catch(const Exception&)
+ {
+ // re-throw, caught below
+ throw;
+ }
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("sfx.appl");
+ }
+ return nullptr;
+ }
+#endif // HAVE_FEATURE_SCRIPTING
+}
+
+void SfxApplication::OfaExec_Impl( SfxRequest& rReq )
+{
+ switch ( rReq.GetSlot() )
+ {
+ case SID_OPTIONS_TREEDIALOG:
+ {
+ OUString sPageURL;
+ const SfxStringItem* pURLItem = rReq.GetArg<SfxStringItem>(SID_OPTIONS_PAGEURL);
+ if ( pURLItem )
+ sPageURL = pURLItem->GetValue();
+ Reference <XFrame> xFrame(GetRequestFrame(rReq));
+ SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
+ VclPtr<VclAbstractDialog> pDlg =
+ pFact->CreateFrameDialog(rReq.GetFrameWeld(), xFrame, rReq.GetSlot(), sPageURL );
+ short nRet = pDlg->Execute();
+ pDlg.disposeAndClear();
+ SfxViewFrame* pView = SfxViewFrame::GetFirst();
+ while ( pView )
+ {
+ if (nRet == RET_OK)
+ {
+ SfxObjectShell* pObjSh = pView->GetObjectShell();
+ if (pObjSh)
+ pObjSh->SetConfigOptionsChecked(false);
+ }
+ pView->GetBindings().InvalidateAll(false);
+ pView = SfxViewFrame::GetNext( *pView );
+ }
+ break;
+ }
+
+ case SID_MORE_DICTIONARIES:
+ {
+ uno::Sequence<beans::PropertyValue> aArgs{ comphelper::makePropertyValue(
+ "AdditionsTag", OUString("Dictionary")) };
+ comphelper::dispatchCommand(".uno:AdditionsDialog", aArgs);
+ break;
+ }
+#if HAVE_FEATURE_SCRIPTING
+ case SID_BASICIDE_APPEAR:
+ {
+ SfxViewFrame* pView = lcl_getBasicIDEViewFrame( nullptr );
+ if ( !pView )
+ {
+ SfxObjectShell* pBasicIDE = SfxObjectShell::CreateObject( "com.sun.star.script.BasicIDE" );
+ pBasicIDE->DoInitNew();
+ pBasicIDE->SetModified( false );
+ try
+ {
+ // load the Basic IDE via direct access to the SFX frame loader. A generic loadComponentFromURL
+ // (which could be done via SfxViewFrame::LoadDocumentIntoFrame) is not feasible here, since the Basic IDE
+ // does not really play nice with the framework's concept. For instance, it is a "singleton document",
+ // which conflicts, at the latest, with the framework's concept of loading into _blank frames.
+ // So, since we know that our frame loader can handle it, we skip the generic framework loader
+ // mechanism, and the type detection (which doesn't know about the Basic IDE).
+ Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+ Reference< XSynchronousFrameLoader > xLoader(
+ xContext->getServiceManager()->createInstanceWithContext("com.sun.star.comp.office.FrameLoader", xContext),
+ UNO_QUERY_THROW );
+ ::comphelper::NamedValueCollection aLoadArgs;
+ aLoadArgs.put( "Model", pBasicIDE->GetModel() );
+ aLoadArgs.put( "URL", OUString( "private:factory/sbasic" ) );
+
+ Reference< XFrame > xTargetFrame( lcl_findStartModuleFrame( xContext ) );
+ if ( !xTargetFrame.is() )
+ xTargetFrame = SfxFrame::CreateBlankFrame();
+ ENSURE_OR_THROW( xTargetFrame.is(), "could not obtain a frameto load the Basic IDE into!" );
+
+ xLoader->load( aLoadArgs.getPropertyValues(), xTargetFrame );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("sfx.appl");
+ }
+
+ pView = lcl_getBasicIDEViewFrame( pBasicIDE );
+ if ( pView )
+ pView->SetName( "BASIC:1" );
+ }
+
+ if ( pView )
+ pView->GetFrame().Appear();
+
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ if ( pArgs && pView )
+ {
+ SfxViewShell* pViewShell = pView->GetViewShell();
+ SfxObjectShell* pObjShell = pView->GetObjectShell();
+ if ( pViewShell && pObjShell )
+ {
+ SfxRequest aReq( SID_BASICIDE_SHOWWINDOW, SfxCallMode::SYNCHRON, pObjShell->GetPool() );
+ aReq.SetArgs( *pArgs );
+ pViewShell->ExecuteSlot( aReq );
+ }
+ }
+
+ rReq.Done();
+ }
+ break;
+
+ case SID_BASICCHOOSER:
+ {
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ const SfxBoolItem* pItem;
+ bool bChooseOnly = false;
+ Reference< XModel > xLimitToModel;
+ if(pArgs && (pItem = pArgs->GetItemIfSet(SID_RECORDMACRO, false)) )
+ {
+ bool bRecord = pItem->GetValue();
+ if ( bRecord )
+ {
+ // !Hack
+ bChooseOnly = false;
+ SfxObjectShell* pCurrentShell = SfxObjectShell::Current();
+ OSL_ENSURE( pCurrentShell, "macro recording outside an SFX document?" );
+ if ( pCurrentShell )
+ xLimitToModel = pCurrentShell->GetModel();
+ }
+ }
+
+ Reference <XFrame> xFrame(GetRequestFrame(rReq));
+ rReq.SetReturnValue(SfxStringItem(rReq.GetSlot(), ChooseMacro(rReq.GetFrameWeld(), xLimitToModel, xFrame, bChooseOnly)));
+ rReq.Done();
+ }
+ break;
+
+ case SID_MACROORGANIZER:
+ {
+ SAL_INFO("sfx.appl", "handling SID_MACROORGANIZER");
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ const SfxUInt16Item* pItem;
+ sal_Int16 nTabId = 0;
+ if(pArgs && (pItem = pArgs->GetItemIfSet(SID_MACROORGANIZER, false) ))
+ {
+ nTabId = pItem->GetValue();
+ }
+
+ SfxApplication::MacroOrganizer(rReq.GetFrameWeld(), nTabId);
+ rReq.Done();
+ }
+ break;
+
+ case SID_RUNMACRO:
+ {
+ SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
+ SAL_INFO("sfx.appl", "SfxApplication::OfaExec_Impl: case ScriptOrg");
+
+ Reference <XFrame> xFrame(GetRequestFrame(rReq));
+ if ( !xFrame.is() )
+ {
+ const SfxViewFrame* pViewFrame = SfxViewFrame::Current();
+ if ( pViewFrame )
+ xFrame = pViewFrame->GetFrame().GetFrameInterface();
+ }
+
+ do // artificial loop for flow control
+ {
+ VclPtr<AbstractScriptSelectorDialog> pDlg(pFact->CreateScriptSelectorDialog(lcl_getDialogParent(xFrame), xFrame));
+ OSL_ENSURE( pDlg, "SfxApplication::OfaExec_Impl( SID_RUNMACRO ): no dialog!" );
+ if ( !pDlg )
+ break;
+ pDlg->SetRunLabel();
+
+ pDlg->StartExecuteAsync([pDlg, xFrame](sal_Int32 nDialogResult) {
+ if ( !nDialogResult )
+ {
+ pDlg->disposeOnce();
+ return;
+ }
+
+ Sequence< Any > args;
+ Sequence< sal_Int16 > outIndex;
+ Sequence< Any > outArgs;
+ Any ret;
+
+ Reference< XInterface > xScriptContext;
+
+ Reference< XController > xController;
+ if ( xFrame.is() )
+ xController = xFrame->getController();
+ if ( xController.is() )
+ xScriptContext = xController->getModel();
+ if ( !xScriptContext.is() )
+ xScriptContext = xController;
+
+ SfxObjectShell::CallXScript( xScriptContext, pDlg->GetScriptURL(), args, ret, outIndex, outArgs );
+ pDlg->disposeOnce();
+ });
+ }
+ while ( false );
+ rReq.Done();
+ }
+ break;
+
+ case SID_SCRIPTORGANIZER:
+ {
+ SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
+ SAL_INFO("sfx.appl", "SfxApplication::OfaExec_Impl: case ScriptOrg");
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ const SfxScriptOrganizerItem* pItem;
+ OUString aLanguage;
+ if(pArgs && (pItem = pArgs->GetItemIfSet(SID_SCRIPTORGANIZER, false) ))
+ {
+ aLanguage = pItem->getLanguage();
+ }
+
+ OUString aLang( aLanguage );
+ SAL_INFO("sfx.appl", "SfxApplication::OfaExec_Impl: about to create dialog for: " << aLang);
+ ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateSvxScriptOrgDialog(rReq.GetFrameWeld(), aLanguage));
+ if( pDlg )
+ {
+ pDlg->Execute();
+ }
+ else
+ {
+ SAL_WARN("sfx.appl", "no dialog!!!");
+ }
+ rReq.Done();
+ }
+ break;
+#endif // HAVE_FEATURE_SCRIPTING
+
+ case SID_OFFICE_CHECK_PLZ:
+ {
+ bool bRet = false;
+ const SfxStringItem* pStringItem = rReq.GetArg<SfxStringItem>(rReq.GetSlot());
+
+ if ( pStringItem )
+ {
+ bRet = true /*!!!SfxIniManager::CheckPLZ( aPLZ )*/;
+ }
+#if HAVE_FEATURE_SCRIPTING
+ else
+ SbxBase::SetError( ERRCODE_BASIC_WRONG_ARGS );
+#endif
+ rReq.SetReturnValue( SfxBoolItem( rReq.GetSlot(), bRet ) );
+ }
+ break;
+
+ case SID_AUTO_CORRECT_DLG:
+ {
+ SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
+ SfxItemSetFixed<SID_AUTO_CORRECT_DLG, SID_AUTO_CORRECT_DLG> aSet(GetPool());
+ const SfxPoolItem* pItem=nullptr;
+ const SfxItemSet* pSet = rReq.GetArgs();
+ if ( pSet && pSet->GetItemState( SID_AUTO_CORRECT_DLG, false, &pItem ) == SfxItemState::SET )
+ aSet.Put( *pItem );
+
+ ScopedVclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateAutoCorrTabDialog(rReq.GetFrameWeld(), &aSet));
+ pDlg->Execute();
+
+ break;
+ }
+
+ case SID_NEWSD :
+ {
+ SvtModuleOptions aModuleOpt;
+ if ( !aModuleOpt.IsImpress() )
+ {
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(rReq.GetFrameWeld(),
+ VclMessageType::Warning, VclButtonsType::Ok,
+ SfxResId(STR_MODULENOTINSTALLED)));
+ xBox->run();
+ return;
+ }
+
+ Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
+ Reference< frame::XDispatchProvider > xProv = drawing::ModuleDispatcher::create( xContext );
+
+ OUString aCmd = OUString::createFromAscii( GetInterface()->GetSlot( rReq.GetSlot() )->GetUnoName() );
+ Reference< frame::XDispatchHelper > xHelper( frame::DispatchHelper::create(xContext) );
+ Sequence < beans::PropertyValue > aSeq;
+ if ( rReq.GetArgs() )
+ TransformItems( rReq.GetSlot(), *rReq.GetArgs(), aSeq );
+ Any aResult = xHelper->executeDispatch( xProv, aCmd, OUString(), 0, aSeq );
+ frame::DispatchResultEvent aEvent;
+ bool bSuccess = (aResult >>= aEvent) &&
+ (aEvent.State == frame::DispatchResultState::SUCCESS);
+ rReq.SetReturnValue( SfxBoolItem( rReq.GetSlot(), bSuccess ) );
+ }
+ break;
+
+ case FN_LABEL :
+ case FN_BUSINESS_CARD :
+ case FN_XFORMS_INIT :
+ {
+ Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
+ Reference< frame::XDispatchProvider > xProv = text::ModuleDispatcher::create( xContext );
+
+ OUString aCmd = OUString::createFromAscii( GetInterface()->GetSlot( rReq.GetSlot() )->GetUnoName() );
+ Reference< frame::XDispatchHelper > xHelper( frame::DispatchHelper::create(xContext) );
+ Sequence < beans::PropertyValue > aSeq;
+ if ( rReq.GetArgs() )
+ TransformItems( rReq.GetSlot(), *rReq.GetArgs(), aSeq );
+ Any aResult = xHelper->executeDispatch( xProv, aCmd, OUString(), 0, aSeq );
+ frame::DispatchResultEvent aEvent;
+ bool bSuccess = (aResult >>= aEvent) &&
+ (aEvent.State == frame::DispatchResultState::SUCCESS);
+ rReq.SetReturnValue( SfxBoolItem( rReq.GetSlot(), bSuccess ) );
+ }
+ break;
+
+ case SID_ADDRESS_DATA_SOURCE:
+ {
+ try
+ {
+ Reference< uno::XComponentContext > xORB = ::comphelper::getProcessComponentContext();
+ Reference< ui::dialogs::XExecutableDialog > xDialog = ui::dialogs::AddressBookSourcePilot::createWithParent(xORB, nullptr);
+ xDialog->execute();
+ }
+ catch(const css::uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("sfx.appl");
+ }
+ }
+ break;
+
+ case SID_COMP_BIBLIOGRAPHY:
+ lcl_tryLoadBibliography();
+ break;
+ }
+}
+
+void SfxApplication::OfaState_Impl(SfxItemSet &rSet)
+{
+ SvtModuleOptions aModuleOpt;
+
+ if( !aModuleOpt.IsWriter())
+ {
+ rSet.DisableItem( FN_LABEL );
+ rSet.DisableItem( FN_BUSINESS_CARD );
+ rSet.DisableItem( FN_XFORMS_INIT );
+ }
+ if ( comphelper::LibreOfficeKit::isActive() )
+ rSet.DisableItem( SID_AUTO_CORRECT_DLG );
+
+ bool bMacrosDisabled
+ = officecfg::Office::Common::Security::Scripting::DisableMacrosExecution::get();
+ if (bMacrosDisabled)
+ {
+ rSet.DisableItem(SID_RUNMACRO);
+ rSet.DisableItem(SID_MACROORGANIZER);
+ rSet.DisableItem(SID_SCRIPTORGANIZER);
+ rSet.DisableItem(SID_BASICIDE_APPEAR);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */