1
0
Fork 0
libreoffice/sd/source/core/TransitionPreset.cxx
Daniel Baumann 8e63e14cf6
Adding upstream version 4:25.2.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
2025-06-22 16:20:04 +02:00

398 lines
16 KiB
C++

/* -*- 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 <set>
#include <com/sun/star/animations/XTransitionFilter.hpp>
#include <com/sun/star/container/XEnumerationAccess.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/configuration/theDefaultProvider.hpp>
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/animations/AnimationNodeType.hpp>
#include <com/sun/star/animations/TransitionType.hpp>
#include <com/sun/star/animations/TransitionSubType.hpp>
#include <unotools/configmgr.hxx>
#include <comphelper/getexpandeduri.hxx>
#include <comphelper/processfactory.hxx>
#include <comphelper/propertysequence.hxx>
#include <comphelper/lok.hxx>
#include <unotools/syslocaleoptions.hxx>
#include <officecfg/Office/Impress.hxx>
#include <officecfg/Office/UI/Effects.hxx>
#include <comphelper/diagnose_ex.hxx>
#include <sal/log.hxx>
#include <vcl/svapp.hxx>
#include <CustomAnimationPreset.hxx>
#include <TransitionPreset.hxx>
using namespace ::com::sun::star;
using namespace ::com::sun::star::animations;
using ::com::sun::star::uno::UNO_QUERY_THROW;
using ::com::sun::star::uno::Any;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Exception;
using ::com::sun::star::lang::XMultiServiceFactory;
using ::com::sun::star::container::XEnumerationAccess;
using ::com::sun::star::container::XEnumeration;
using ::com::sun::star::beans::NamedValue;
namespace sd {
TransitionPreset::TransitionPreset( const css::uno::Reference< css::animations::XAnimationNode >& xNode )
{
// first locate preset id
const Sequence< NamedValue > aUserData( xNode->getUserData() );
const NamedValue* pProp = std::find_if(aUserData.begin(), aUserData.end(),
[](const NamedValue& rProp) { return rProp.Name == "preset-id"; });
if (pProp != aUserData.end())
pProp->Value >>= maPresetId;
// second, locate transition filter element
Reference< XEnumerationAccess > xEnumerationAccess( xNode, UNO_QUERY_THROW );
Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), css::uno::UNO_SET_THROW );
Reference< XTransitionFilter > xTransition( xEnumeration->nextElement(), UNO_QUERY_THROW );
mnTransition = xTransition->getTransition();
mnSubtype = xTransition->getSubtype();
mbDirection = xTransition->getDirection();
mnFadeColor = xTransition->getFadeColor();
}
bool TransitionPreset::importTransitionsFile( TransitionPresetList& rList,
Reference< XMultiServiceFactory > const & xServiceFactory,
const OUString& aURL )
{
SAL_INFO("sd.transitions", "Importing " << aURL);
Reference< container::XNameAccess > xTransitionSets( officecfg::Office::UI::Effects::UserInterface::TransitionSets::get() );
Reference< container::XNameAccess > xTransitionGroups( officecfg::Office::UI::Effects::UserInterface::TransitionGroups::get() );
Reference< container::XNameAccess > xTransitionVariants( officecfg::Office::UI::Effects::UserInterface::TransitionVariants::get() );
Reference< container::XNameAccess > xTransitions( officecfg::Office::UI::Effects::UserInterface::Transitions::get() );
// import transition presets
Reference< XAnimationNode > xAnimationNode;
const std::set<sal_Int16> LOKSupportedTransitionTypes = {
TransitionType::BARWIPE,
TransitionType::BOXWIPE,
TransitionType::FOURBOXWIPE,
TransitionType::ELLIPSEWIPE,
TransitionType::CLOCKWIPE,
TransitionType::PINWHEELWIPE,
TransitionType::PUSHWIPE,
TransitionType::SLIDEWIPE,
TransitionType::FADE,
TransitionType::RANDOMBARWIPE,
TransitionType::CHECKERBOARDWIPE,
TransitionType::DISSOLVE,
TransitionType::SNAKEWIPE,
TransitionType::PARALLELSNAKESWIPE,
TransitionType::IRISWIPE,
TransitionType::BARNDOORWIPE,
TransitionType::VEEWIPE,
TransitionType::ZIGZAGWIPE,
TransitionType::BARNZIGZAGWIPE,
TransitionType::FANWIPE,
TransitionType::SINGLESWEEPWIPE,
TransitionType::WATERFALLWIPE,
TransitionType::SPIRALWIPE,
TransitionType::MISCDIAGONALWIPE,
TransitionType::BOXSNAKESWIPE,
TransitionType::BLINDSWIPE,
TransitionType::MISCSHAPEWIPE,
TransitionType::ZOOM
};
const std::set<sal_Int16> LOKSupportedTransitionSubTypes = {
TransitionSubType::DEFAULT,
TransitionSubType::LEFTTORIGHT,
TransitionSubType::TOPTOBOTTOM,
TransitionSubType::CORNERSIN,
TransitionSubType::CORNERSOUT,
TransitionSubType::VERTICAL,
TransitionSubType::HORIZONTAL,
TransitionSubType::DOWN,
TransitionSubType::CIRCLE,
TransitionSubType::CLOCKWISETWELVE,
TransitionSubType::CLOCKWISETHREE,
TransitionSubType::CLOCKWISESIX,
TransitionSubType::CLOCKWISENINE,
TransitionSubType::TWOBLADEVERTICAL,
TransitionSubType::TWOBLADEHORIZONTAL,
TransitionSubType::FOURBLADE,
TransitionSubType::FROMLEFT,
TransitionSubType::FROMTOP,
TransitionSubType::FROMRIGHT,
TransitionSubType::FROMBOTTOM,
TransitionSubType::CROSSFADE,
TransitionSubType::FADETOCOLOR,
TransitionSubType::FADEFROMCOLOR,
TransitionSubType::FADEOVERCOLOR,
TransitionSubType::THREEBLADE,
TransitionSubType::EIGHTBLADE,
TransitionSubType::ONEBLADE,
TransitionSubType::ACROSS,
TransitionSubType::TOPLEFTVERTICAL,
TransitionSubType::TOPLEFTHORIZONTAL,
TransitionSubType::TOPLEFTDIAGONAL,
TransitionSubType::TOPRIGHTDIAGONAL,
TransitionSubType::BOTTOMRIGHTDIAGONAL,
TransitionSubType::BOTTOMLEFTDIAGONAL,
TransitionSubType::RECTANGLE,
TransitionSubType::DIAMOND,
TransitionSubType::TOPLEFT,
TransitionSubType::TOPRIGHT,
TransitionSubType::BOTTOMRIGHT,
TransitionSubType::BOTTOMLEFT,
TransitionSubType::TOPCENTER,
TransitionSubType::RIGHTCENTER,
TransitionSubType::BOTTOMCENTER,
TransitionSubType::LEFTCENTER,
TransitionSubType::LEFT,
TransitionSubType::UP,
TransitionSubType::RIGHT,
TransitionSubType::DIAGONALBOTTOMLEFT,
TransitionSubType::DIAGONALTOPLEFT,
TransitionSubType::CENTERTOP,
TransitionSubType::CENTERRIGHT,
TransitionSubType::TOP,
TransitionSubType::BOTTOM,
TransitionSubType::CLOCKWISETOP,
TransitionSubType::CLOCKWISERIGHT,
TransitionSubType::CLOCKWISEBOTTOM,
TransitionSubType::CLOCKWISELEFT,
TransitionSubType::CLOCKWISETOPLEFT,
TransitionSubType::COUNTERCLOCKWISEBOTTOMLEFT,
TransitionSubType::CLOCKWISEBOTTOMRIGHT,
TransitionSubType::COUNTERCLOCKWISETOPRIGHT,
TransitionSubType::VERTICALLEFT,
TransitionSubType::VERTICALRIGHT,
TransitionSubType::HORIZONTALLEFT,
TransitionSubType::HORIZONTALRIGHT,
TransitionSubType::TOPLEFTCLOCKWISE,
TransitionSubType::TOPRIGHTCLOCKWISE,
TransitionSubType::BOTTOMRIGHTCLOCKWISE,
TransitionSubType::BOTTOMLEFTCLOCKWISE,
TransitionSubType::TOPLEFTCOUNTERCLOCKWISE,
TransitionSubType::TOPRIGHTCOUNTERCLOCKWISE,
TransitionSubType::BOTTOMRIGHTCOUNTERCLOCKWISE,
TransitionSubType::BOTTOMLEFTCOUNTERCLOCKWISE,
TransitionSubType::DOUBLEBARNDOOR,
TransitionSubType::DOUBLEDIAMOND,
TransitionSubType::VERTICALTOPSAME,
TransitionSubType::VERTICALBOTTOMSAME,
TransitionSubType::VERTICALTOPLEFTOPPOSITE,
TransitionSubType::VERTICALBOTTOMLEFTOPPOSITE,
TransitionSubType::HORIZONTALLEFTSAME,
TransitionSubType::HORIZONTALRIGHTSAME,
TransitionSubType::HORIZONTALTOPLEFTOPPOSITE,
TransitionSubType::HORIZONTALTOPRIGHTOPPOSITE,
TransitionSubType::DIAGONALBOTTOMLEFTOPPOSITE,
TransitionSubType::DIAGONALTOPLEFTOPPOSITE,
TransitionSubType::TWOBOXTOP,
TransitionSubType::TWOBOXBOTTOM,
TransitionSubType::TWOBOXLEFT,
TransitionSubType::TWOBOXRIGHT,
TransitionSubType::FOURBOXVERTICAL,
TransitionSubType::FOURBOXHORIZONTAL,
TransitionSubType::COMBVERTICAL,
TransitionSubType::COMBHORIZONTAL,
TransitionSubType::FANOUTHORIZONTAL,
TransitionSubType::HEART,
TransitionSubType::ROTATEIN
};
const std::set<sal_Int16> LOKMiscShapeWipeNonSupportedTransitionSubTypes = {
TransitionSubType::DIAMOND,
TransitionSubType::HEART,
TransitionSubType::CIRCLE,
TransitionSubType::VERTICAL,
TransitionSubType::TOPLEFT
};
try {
xAnimationNode = implImportEffects( xServiceFactory, aURL );
Reference< XEnumerationAccess > xEnumerationAccess( xAnimationNode, UNO_QUERY_THROW );
Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), css::uno::UNO_SET_THROW );
while( xEnumeration->hasMoreElements() )
{
Reference< XAnimationNode > xChildNode( xEnumeration->nextElement(), UNO_QUERY_THROW );
if( xChildNode->getType() == AnimationNodeType::PAR )
{
TransitionPresetPtr pPreset( new TransitionPreset( xChildNode ) );
if( comphelper::LibreOfficeKit::isActive() )
{
sal_Int16 eTransitionType = pPreset->getTransition();
sal_Int16 eTransitionSubType = pPreset->getSubtype();
if( LOKSupportedTransitionTypes.find(eTransitionType) == LOKSupportedTransitionTypes.end()
|| LOKSupportedTransitionSubTypes.find(eTransitionSubType) == LOKSupportedTransitionSubTypes.end() )
{
continue;
}
if( eTransitionType == TransitionType::MISCSHAPEWIPE
&& LOKMiscShapeWipeNonSupportedTransitionSubTypes.find(eTransitionSubType) != LOKMiscShapeWipeNonSupportedTransitionSubTypes.end() )
{
continue;
}
}
OUString aPresetId( pPreset->getPresetId() );
if( !aPresetId.isEmpty() )
{
Reference< container::XNameAccess > xTransitionNode;
if (xTransitions->hasByName( aPresetId ) &&
(xTransitions->getByName( aPresetId ) >>= xTransitionNode) &&
xTransitionNode.is() )
{
OUString sSet;
OUString sVariant;
xTransitionNode->getByName( u"Set"_ustr ) >>= sSet;
xTransitionNode->getByName( u"Variant"_ustr ) >>= sVariant;
Reference< container::XNameAccess > xSetNode;
xTransitionSets->getByName( sSet ) >>= xSetNode;
if( xSetNode.is() )
{
pPreset->maSetId = sSet;
xSetNode->getByName( u"Label"_ustr ) >>= sSet;
pPreset->maSetLabel = sSet;
OUString sGroup;
xSetNode->getByName( u"Group"_ustr ) >>= sGroup;
Reference< container::XNameAccess > xGroupNode;
xTransitionGroups->getByName( sGroup ) >>= xGroupNode;
if( xGroupNode.is() )
{
xGroupNode->getByName( u"Label"_ustr ) >>= sGroup;
if( !sVariant.isEmpty() )
{
Reference< container::XNameAccess > xVariantNode;
xTransitionVariants->getByName( sVariant ) >>= xVariantNode;
if( xVariantNode.is() )
{
xVariantNode->getByName( u"Label"_ustr ) >>= sVariant;
pPreset->maVariantLabel = sVariant;
}
}
pPreset->maSetLabel = sSet;
SAL_INFO("sd.transitions", aPresetId << ": " << sGroup << "/" << sSet << (sVariant.isEmpty() ? OUString() : OUString("/" + sVariant)));
rList.push_back( pPreset );
}
else
SAL_WARN("sd.transitions", "group node " << sGroup << " not found");
}
else
SAL_WARN("sd.transitions", "set node " << sSet << " not found");
}
else
SAL_WARN("sd.transitions", "transition node " << aPresetId << " not found");
}
}
else
{
SAL_WARN("sd.transitions", " malformed xml configuration file " << aURL );
break;
}
}
} catch( Exception& ) {
return false;
}
return true;
}
bool TransitionPreset::importTransitionPresetList( TransitionPresetList& rList )
{
if (comphelper::IsFuzzing())
return false;
bool bRet = false;
try
{
const uno::Reference< uno::XComponentContext >& xContext(
comphelper::getProcessComponentContext() );
Reference< XMultiServiceFactory > xServiceFactory(
xContext->getServiceManager(), UNO_QUERY_THROW );
// import ui strings
Reference< XMultiServiceFactory > xConfigProvider =
configuration::theDefaultProvider::get( xContext );
// read path to transition effects files from config
uno::Sequence< OUString > aFiles;
aFiles = officecfg::Office::Impress::Misc::TransitionFiles::get();
for (const auto& rFile : aFiles)
{
OUString aURL = comphelper::getExpandedUri(xContext, rFile);
bRet |= importTransitionsFile( rList,
xServiceFactory,
aURL );
}
return bRet;
}
catch( Exception& )
{
TOOLS_WARN_EXCEPTION( "sd", "sd::TransitionPreset::importResources()" );
}
return bRet;
}
std::map<OUString, TransitionPresetList> sd::TransitionPreset::mPresetsMap;
const TransitionPresetList& TransitionPreset::getTransitionPresetList()
{
// Support localization per-view. Currently not useful for Desktop
// but very much critical for LOK. The cache now is per-language.
const OUString aLang = comphelper::LibreOfficeKit::isActive()
? comphelper::LibreOfficeKit::getLanguageTag().getBcp47()
: SvtSysLocaleOptions().GetLanguageTag().getBcp47();
SolarMutexGuard aGuard;
const auto it = mPresetsMap.find(aLang);
if (it != mPresetsMap.end())
return it->second;
TransitionPresetList& rList = mPresetsMap[aLang];
sd::TransitionPreset::importTransitionPresetList(rList);
return rList;
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */