/* -*- 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 .
*/
namespace
{
OUString lcl_getAppName( vcl::EnumContext::Application eApp )
{ switch ( eApp )
{ case vcl::EnumContext::Application::Writer: return u"Writer"_ustr; case vcl::EnumContext::Application::Calc: return u"Calc"_ustr; case vcl::EnumContext::Application::Impress: return u"Impress"_ustr; case vcl::EnumContext::Application::Draw: return u"Draw"_ustr; case vcl::EnumContext::Application::Formula: return u"Formula"_ustr; case vcl::EnumContext::Application::Base: return u"Base"_ustr; 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"); returnfalse;
}
} 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
{ usingnamespace org::freedesktop::PackageKit; usingnamespace svtools;
Reference< XSyncDbusSessionHelper > xSyncDbusSessionHelper(SyncDbusSessionHelper::create(comphelper::getProcessComponentContext()));
Sequence< OUString > vPackages { u"libreoffice-base"_ustr };
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;
}
/// Displays CREDITS or LICENSE in any of the available version staticvoid showDocument( constchar* pBaseName )
{ try {
Reference < XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() ); auto args(::comphelper::InitPropertySequence({
{"ViewOnly", Any(true)},
{"ReadOnly", Any(true)}
}));
case SID_QUITAPP: case SID_LOGOUT:
{ // protect against reentrant calls and avoid closing the same files in parallel if (pImpl->bInQuit || pImpl->bClosingDocs) return;
if ( rReq.GetSlot() == SID_LOGOUT )
{ for ( SfxObjectShell *pObjSh = SfxObjectShell::GetFirst();
pObjSh; pObjSh = SfxObjectShell::GetNext( *pObjSh ) )
{ if ( !pObjSh->IsModified() ) continue;
// 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;
}
// 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();
#if HAVE_FEATURE_SCRIPTING // Preselect a macro in the 'keyboard' page if (autoconst item = rReq.GetArg<SfxMacroInfoItem>(SID_MACROINFO)) {
aSet.Put(*item);
} #endif
case SID_CLOSEDOCS:
{ // protect against reentrant calls and avoid closing the same files in parallel if (pImpl->bInQuit || pImpl->bClosingDocs) return;
pImpl->bClosingDocs = true; // closed all status for all visible frames bool bClosedAll = true;
// Iterate over all documents and close them for (SfxObjectShell *pObjSh = SfxObjectShell::GetFirst(); pObjSh;)
{
SfxObjectShell* pNxtObjSh = SfxObjectShell::GetNext(*pObjSh); // can close immediately if (!pObjSh->IsModified())
{ // don't close the last remaining frame for close dispatch if (pNxtObjSh || !bClosedAll)
pObjSh->DoClose();
} else
{ // skip invisible frames when asking user to close
SfxViewFrame* pFrame = SfxViewFrame::GetFirst(pObjSh); if (pFrame && pFrame->GetWindow().IsReallyVisible())
{ // asks user to close if (pObjSh->PrepareClose())
{
pObjSh->SetModified(false); // get next pointer again after asking user since it can become invalid pointer from being manually closed by user // don't close the last remaining frame for close dispatch if ((pNxtObjSh = SfxObjectShell::GetNext(*pObjSh)) || !bClosedAll)
pObjSh->DoClose();
} // user disagrees to close else
{
bClosedAll = false; // get next pointer again after asking user since it can become invalid pointer from being manually closed by user
pNxtObjSh = SfxObjectShell::GetNext(*pObjSh);
}
}
}
pObjSh = pNxtObjSh;
}
pImpl->bClosingDocs = false;
// close dispatch status bool bDispatchOk = true; // open backing window if (bClosedAll)
{ // don't use pViewFrame = SfxViewFrame::Current() as dispatch won't load sometimes
SfxObjectShell* pObjSh = SfxObjectShell::GetFirst();
SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst(pObjSh); if (pViewFrame)
{
Reference<XFrame> xCurrentFrame = pViewFrame->GetFrame().GetFrameInterface(); if (xCurrentFrame.is())
{
uno::Reference<frame::XDispatchProvider> xProvider(xCurrentFrame, uno::UNO_QUERY); if (xProvider.is())
{
uno::Reference<frame::XDispatchHelper> xDispatcher
= frame::DispatchHelper::create(::comphelper::getProcessComponentContext()); // use .uno:CloseDoc to be able to close windows of the same document
css::uno::Any aResult =
xDispatcher->executeDispatch(xProvider,
u".uno:CloseDoc"_ustr,
u"_self"_ustr,
0,
uno::Sequence<beans::PropertyValue>());
css::frame::DispatchResultEvent aEvent;
bDispatchOk = (aResult >>= aEvent) && (aEvent.State == frame::DispatchResultState::SUCCESS);
}
}
}
} // terminate the application if the dispatch fails or // if there is no visible frame left after the command is run (e.g user manually closes the document again that was already cancelled for closing) if (!bDispatchOk || (!bClosedAll && !SfxObjectShell::GetFirst()))
{
SfxRequest aReq(SID_QUITAPP, SfxCallMode::SLOT, GetPool());
MiscExec_Impl(aReq);
}
if (!pNewThemeArg)
{ // we do not override custom themes if the unocommand was triggered from the UI // by clicking on a toolbar/notebookbar button for example. if (!ThemeColors::IsCustomTheme(sSchemeName))
{ bool bChangeToLightTheme = eAppearnceMode == AppearanceMode::DARK
|| (eAppearnceMode == AppearanceMode::AUTO
&& MiscSettings::GetUseDarkMode());
// note that a theme and an appearance mode are not orthogonal anymore, for // "Custom Themes", appearance mode is AUTO, for the "Automatic", "Light" and // "Dark" default themes, it's AUTO, LIGHT & DARK respectively. if (bChangeToLightTheme)
{
sSchemeName = svtools::LIGHT_COLOR_SCHEME;
eAppearnceMode = AppearanceMode::LIGHT;
} else
{
sSchemeName = svtools::DARK_COLOR_SCHEME;
eAppearnceMode = AppearanceMode::DARK;
}
}
} else
sSchemeName = pNewThemeArg->GetValue();
// kit explicitly ignores changes to the global color scheme, except for the current ViewShell, // so an attempted change to the same global color scheme when the now current ViewShell ignored // the last change requires re-sending the change. In which case individual shells will have to // decide if this color-scheme change is a change from their perspective to avoid unnecessary // invalidations. if (!pNewThemeArg || bIsLOK || aEditableConfig.GetCurrentSchemeName() != sSchemeName)
{ if (bIsLOK)
aEditableConfig.SetCurrentSchemeName(sSchemeName); else
aEditableConfig.LoadScheme(sSchemeName);
}
#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;
}
// 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();
// Save new toolbar mode for a current module
aAppNode.setNodeValue( u"Active"_ustr, Any( aNewName ) );
aAppNode.commit();
}
// Apply settings for all frames
pViewFrame = SfxViewFrame::GetFirst(); while( pViewFrame )
{ // in LOK case we want to apply changes only to the current view if (comphelper::LibreOfficeKit::isActive() &&
pViewFrame != &SfxViewShell::Current()->GetViewFrame())
{
pViewFrame = SfxViewFrame::GetNext( *pViewFrame ); continue;
}
void SfxApplication::MiscState_Impl(SfxItemSet &rSet)
{ const WhichRangesContainer & pRanges = rSet.GetRanges();
DBG_ASSERT(!pRanges.empty(), "Set without range"); for ( autoconst & pRange : pRanges )
{ for(sal_uInt16 nWhich = pRange.first; nWhich <= pRange.second; ++nWhich)
{ switch(nWhich)
{ case SID_TEMPLATE_ADDRESSBOOKSOURCE: if (!SvtModuleOptions().IsDataBaseInstalled())
rSet.Put(SfxVisibilityItem(nWhich, false)); break; case SID_QUITAPP:
{ if (pImpl->nDocModalMode || pImpl->bClosingDocs)
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
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());
while ( pView )
{ if (nRet == RET_OK)
{
SfxObjectShell* pObjSh = pView->GetObjectShell(); if (pObjSh)
{
pObjSh->SetConfigOptionsChecked(false);
// when active content is disabled via options dialog, // disable all current active embedded objects if (bDisableActiveContent)
lcl_disableActiveEmbeddedObjects(pObjSh);
}
}
pView->GetBindings().InvalidateAll(false);
pView = SfxViewFrame::GetNext( *pView );
} break;
}