nss: upgrade to release 3.73
[LibreOffice.git] / sd / source / core / CustomAnimationPreset.cxx
blobb40b271d9910be1c69ad168a7e44a93649c51644
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sal/config.h>
21 #include <sal/log.hxx>
23 #include <com/sun/star/io/IOException.hpp>
24 #include <com/sun/star/util/XCloneable.hpp>
25 #include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
26 #include <com/sun/star/container/XNameAccess.hpp>
27 #include <com/sun/star/configuration/theDefaultProvider.hpp>
28 #include <com/sun/star/xml/sax/InputSource.hpp>
29 #include <com/sun/star/xml/sax/FastParser.hpp>
30 #include <com/sun/star/xml/sax/SAXParseException.hpp>
31 #include <com/sun/star/presentation/EffectPresetClass.hpp>
32 #include <com/sun/star/beans/NamedValue.hpp>
33 #include <osl/diagnose.h>
34 #include <unotools/streamwrap.hxx>
35 #include <comphelper/getexpandeduri.hxx>
36 #include <comphelper/processfactory.hxx>
37 #include <comphelper/propertysequence.hxx>
38 #include <comphelper/random.hxx>
39 #include <comphelper/lok.hxx>
40 #include <unotools/syslocaleoptions.hxx>
41 #include <tools/stream.hxx>
42 #include <tools/diagnose_ex.h>
44 #include <tools/debug.hxx>
45 #include <vcl/svapp.hxx>
46 #include <unotools/ucbstreamhelper.hxx>
47 #include <CustomAnimationPreset.hxx>
49 #include <algorithm>
50 #include <vector>
52 using namespace ::com::sun::star;
53 using namespace ::com::sun::star::uno;
54 using namespace ::com::sun::star::animations;
55 using namespace ::com::sun::star::presentation;
57 using ::com::sun::star::io::XInputStream;
58 using ::com::sun::star::lang::XMultiServiceFactory;
59 using ::com::sun::star::container::XNameAccess;
60 using ::com::sun::star::util::XCloneable;
61 using ::com::sun::star::beans::NamedValue;
63 namespace sd {
65 static Reference< XNameAccess > getNodeAccess( const Reference< XMultiServiceFactory >& xConfigProvider, const OUString& rNodePath )
67 Reference< XNameAccess > xConfigAccess;
69 try
71 Sequence<Any> aArgs(comphelper::InitAnyPropertySequence(
73 {"nodepath", uno::Any(rNodePath)}
74 }));
76 xConfigAccess.set(
77 xConfigProvider->createInstanceWithArguments( "com.sun.star.configuration.ConfigurationAccess", aArgs ),
78 UNO_QUERY);
80 catch (const Exception&)
82 OSL_FAIL( "sd::getNodeAccess(), Exception caught!" );
85 return xConfigAccess;
88 void implImportLabels( const Reference< XMultiServiceFactory >& xConfigProvider, const OUString& rNodePath, UStringMap& rStringMap )
90 try
92 Reference< XNameAccess > xConfigAccess( getNodeAccess( xConfigProvider, rNodePath ) );
93 if( xConfigAccess.is() )
95 Reference< XNameAccess > xNameAccess;
96 const Sequence< OUString > aNames( xConfigAccess->getElementNames() );
97 for(const OUString& rName : aNames)
99 xConfigAccess->getByName( rName ) >>= xNameAccess;
100 if( xNameAccess.is() )
102 OUString aUIName;
103 xNameAccess->getByName( "Label" ) >>= aUIName;
104 if( !aUIName.isEmpty() )
106 rStringMap[ rName ] = aUIName;
112 catch (const lang::WrappedTargetException&)
114 OSL_FAIL( "sd::implImportLabels(), WrappedTargetException caught!" );
116 catch (const Exception&)
118 OSL_FAIL( "sd::implImportLabels(), Exception caught!" );
122 CustomAnimationPreset::CustomAnimationPreset( const CustomAnimationEffectPtr& pEffect )
124 maPresetId = pEffect->getPresetId();
125 maProperty = pEffect->getProperty();
127 add( pEffect );
129 mfDuration = pEffect->getDuration();
130 maDefaultSubTyp = pEffect->getPresetSubType();
132 Sequence< NamedValue > aUserData( pEffect->getNode()->getUserData() );
134 mbIsTextOnly = std::any_of(aUserData.begin(), aUserData.end(),
135 [](const NamedValue& rProp) { return rProp.Name == "text-only"; });
138 void CustomAnimationPreset::add( const CustomAnimationEffectPtr& pEffect )
140 maSubTypes[ pEffect->getPresetSubType() ] = pEffect;
143 std::vector<OUString> CustomAnimationPreset::getSubTypes()
145 std::vector<OUString> aSubTypes;
147 if( maSubTypes.size() > 1 )
149 std::transform(maSubTypes.begin(), maSubTypes.end(), std::back_inserter(aSubTypes),
150 [](EffectsSubTypeMap::value_type& rEntry) -> OUString { return rEntry.first; });
153 return aSubTypes;
156 Reference< XAnimationNode > CustomAnimationPreset::create( const OUString& rstrSubType )
160 OUString strSubType( rstrSubType );
161 if( strSubType.isEmpty() )
162 strSubType = maDefaultSubTyp;
164 CustomAnimationEffectPtr pEffect = maSubTypes[strSubType];
165 if( pEffect )
167 Reference< XCloneable > xCloneable( pEffect->getNode(), UNO_QUERY_THROW );
168 Reference< XAnimationNode > xNode( xCloneable->createClone(), UNO_QUERY_THROW );
169 return xNode;
172 catch (const Exception&)
174 OSL_FAIL( "sd::CustomAnimationPresets::create(), exception caught!" );
177 Reference< XAnimationNode > xNode;
178 return xNode;
181 std::vector<OUString> CustomAnimationPreset::getProperties() const
183 std::vector<OUString> aPropertyList;
184 if (!maProperty.isEmpty())
186 sal_Int32 nPos = 0;
189 aPropertyList.push_back(maProperty.getToken(0, ';', nPos));
191 while (nPos >= 0);
193 return aPropertyList;
196 bool CustomAnimationPreset::hasProperty( const OUString& rProperty )const
198 if (maProperty.isEmpty())
199 return false;
201 sal_Int32 nPos = 0;
204 if (maProperty.getToken(0, ';', nPos) == rProperty)
205 return true;
207 while (nPos >= 0);
209 return false;
212 CustomAnimationPresets::CustomAnimationPresets()
216 CustomAnimationPresets::~CustomAnimationPresets()
220 Reference< XAnimationNode > implImportEffects( const Reference< XMultiServiceFactory >& xServiceFactory, const OUString& rPath )
222 Reference< XAnimationNode > xRootNode;
226 // create stream
227 std::unique_ptr<SvStream> pIStm = ::utl::UcbStreamHelper::CreateStream( rPath, StreamMode::READ );
228 Reference<XInputStream> xInputStream( new utl::OInputStreamWrapper( std::move(pIStm) ) );
230 // prepare ParserInputSource
231 xml::sax::InputSource aParserInput;
232 aParserInput.sSystemId = rPath;
233 aParserInput.aInputStream = xInputStream;
235 // get filter
236 Reference< xml::sax::XFastParser > xFilter( xServiceFactory->createInstance("com.sun.star.comp.Xmloff.AnimationsImport" ), UNO_QUERY_THROW );
238 xFilter->parseStream( aParserInput );
240 Reference< XAnimationNodeSupplier > xAnimationNodeSupplier( xFilter, UNO_QUERY_THROW );
241 xRootNode = xAnimationNodeSupplier->getAnimationNode();
243 catch (const Exception&)
245 TOOLS_WARN_EXCEPTION("sd", "");
248 return xRootNode;
251 void CustomAnimationPresets::importEffects()
255 uno::Reference< uno::XComponentContext > xContext(
256 comphelper::getProcessComponentContext() );
257 Reference< XMultiServiceFactory > xServiceFactory(
258 xContext->getServiceManager(), UNO_QUERY_THROW );
260 Reference< XMultiServiceFactory > xConfigProvider =
261 configuration::theDefaultProvider::get( xContext );
263 // read path to transition effects files from config
264 uno::Sequence<uno::Any> aArgs(comphelper::InitAnyPropertySequence(
266 {"nodepath", uno::Any(OUString("/org.openoffice.Office.Impress/Misc"))}
267 }));
268 Reference<container::XNameAccess> xNameAccess(
269 xConfigProvider->createInstanceWithArguments(
270 "com.sun.star.configuration.ConfigurationAccess",
271 aArgs ), UNO_QUERY_THROW );
272 uno::Sequence< OUString > aFiles;
273 xNameAccess->getByName( "EffectFiles" ) >>= aFiles;
275 for( const auto& rFile : std::as_const(aFiles) )
277 OUString aURL = comphelper::getExpandedUri(xContext, rFile);
279 mxRootNode = implImportEffects( xServiceFactory, aURL );
281 if( mxRootNode.is() )
283 Reference< XTimeContainer > xRootContainer( mxRootNode, UNO_QUERY_THROW );
284 EffectSequenceHelper aSequence( xRootContainer );
286 EffectSequence::iterator aIter( aSequence.getBegin() );
287 const EffectSequence::iterator aEnd( aSequence.getEnd() );
289 while( aIter != aEnd )
291 CustomAnimationEffectPtr pEffect = *aIter;
293 const OUString aPresetId( pEffect->getPresetId() );
294 CustomAnimationPresetPtr pDescriptor = getEffectDescriptor( aPresetId );
295 if( pDescriptor )
296 pDescriptor->add( pEffect );
297 else
299 pDescriptor = std::make_shared<CustomAnimationPreset>( pEffect );
300 pDescriptor->maLabel = getUINameForPresetId( pEffect->getPresetId() );
301 maEffectDescriptorMap[aPresetId] = pDescriptor;
304 ++aIter;
309 catch (const xml::sax::SAXParseException&)
311 OSL_FAIL( "sd::CustomAnimationPresets::importEffects(), SAXParseException caught!" );
313 catch (const xml::sax::SAXException&)
315 OSL_FAIL( "sd::CustomAnimationPresets::importEffects(), SAXException caught!" );
317 catch (const io::IOException&)
319 OSL_FAIL( "sd::CustomAnimationPresets::importEffects(), IOException caught!" );
321 catch (const Exception&)
323 OSL_FAIL( "sd::CustomAnimationPresets::importEffects(), Exception caught!" );
327 void CustomAnimationPresets::importResources()
331 // Get service factory
332 Reference< XComponentContext > xContext( comphelper::getProcessComponentContext() );
334 Reference< XMultiServiceFactory > xConfigProvider =
335 configuration::theDefaultProvider::get( xContext );
337 implImportLabels( xConfigProvider, "/org.openoffice.Office.UI.Effects/UserInterface/Properties", maPropertyNameMap );
339 implImportLabels( xConfigProvider, "/org.openoffice.Office.UI.Effects/UserInterface/Effects", maEffectNameMap );
341 importEffects();
343 importPresets( xConfigProvider, "/org.openoffice.Office.UI.Effects/Presets/Entrance", maEntrancePresets );
345 importPresets( xConfigProvider, "/org.openoffice.Office.UI.Effects/Presets/Emphasis", maEmphasisPresets );
347 importPresets( xConfigProvider, "/org.openoffice.Office.UI.Effects/Presets/Exit", maExitPresets );
349 importPresets( xConfigProvider, "/org.openoffice.Office.UI.Effects/Presets/MotionPaths", maMotionPathsPresets );
351 importPresets( xConfigProvider, "/org.openoffice.Office.UI.Effects/Presets/Misc", maMiscPresets );
353 catch (const lang::WrappedTargetException&)
355 OSL_FAIL( "sd::CustomAnimationPresets::importResources(), WrappedTargetException caught!" );
357 catch (const Exception&)
359 OSL_FAIL( "sd::CustomAnimationPresets::importResources(), Exception caught!" );
363 void CustomAnimationPresets::importPresets( const Reference< XMultiServiceFactory >& xConfigProvider, const OUString& rNodePath, PresetCategoryList& rPresetMap )
365 #ifdef DEBUG
366 OUString aMissedPresetIds;
367 #endif
371 Reference< XNameAccess > xTypeAccess( getNodeAccess( xConfigProvider, rNodePath ) );
372 if( xTypeAccess.is() )
374 Reference< XNameAccess > xCategoryAccess;
376 const Sequence< OUString > aNames( xTypeAccess->getElementNames() );
377 for(const OUString& rName : aNames)
379 xTypeAccess->getByName( rName ) >>= xCategoryAccess;
381 if( xCategoryAccess.is() && xCategoryAccess->hasByName( "Label" ) && xCategoryAccess->hasByName( "Effects" ) )
383 OUString aLabel;
384 xCategoryAccess->getByName( "Label" ) >>= aLabel;
386 Sequence< OUString > aEffects;
387 xCategoryAccess->getByName( "Effects" ) >>= aEffects;
389 EffectDescriptorList aEffectsList;
391 for( const OUString& rEffectName : std::as_const(aEffects) )
393 CustomAnimationPresetPtr pEffect = getEffectDescriptor( rEffectName );
394 if( pEffect )
396 aEffectsList.push_back( pEffect );
398 #ifdef DEBUG
399 else
401 aMissedPresetIds += OUString(rEffectName);
402 aMissedPresetIds += "\n";
404 #endif
406 rPresetMap.push_back( std::make_shared<PresetCategory>( aLabel, aEffectsList ) );
411 catch (const Exception&)
413 OSL_FAIL( "sd::CustomAnimationPresets::importPresets(), Exception caught!" );
416 #ifdef DEBUG
417 SAL_WARN_IF(!aMissedPresetIds.isEmpty(), "sd", "sd::CustomAnimationPresets::importPresets(), invalid preset id: "
418 << aMissedPresetIds);
419 #endif
422 CustomAnimationPresetPtr CustomAnimationPresets::getEffectDescriptor( const OUString& rPresetId ) const
424 EffectDescriptorMap::const_iterator aIter( maEffectDescriptorMap.find( rPresetId ) );
426 if( aIter != maEffectDescriptorMap.end() )
428 return (*aIter).second;
430 else
432 return CustomAnimationPresetPtr(nullptr);
436 const OUString& CustomAnimationPresets::getUINameForPresetId( const OUString& rPresetId ) const
438 return translateName( rPresetId, maEffectNameMap );
441 const OUString& CustomAnimationPresets::getUINameForProperty( const OUString& rPresetId ) const
443 return translateName( rPresetId, maPropertyNameMap );
446 const OUString& CustomAnimationPresets::translateName( const OUString& rId, const UStringMap& rNameMap )
448 UStringMap::const_iterator aIter( rNameMap.find( rId ) );
450 if( aIter != rNameMap.end() )
452 return (*aIter).second;
454 else
456 return rId;
459 void CustomAnimationPresets::changePresetSubType( const CustomAnimationEffectPtr& pEffect, const OUString& rPresetSubType ) const
461 if( pEffect && pEffect->getPresetSubType() != rPresetSubType )
463 CustomAnimationPresetPtr pDescriptor( getEffectDescriptor( pEffect->getPresetId() ) );
465 if( pDescriptor )
467 Reference< XAnimationNode > xNewNode( pDescriptor->create( rPresetSubType ) );
468 if( xNewNode.is() )
469 pEffect->replaceNode( xNewNode );
474 std::map<OUString, CustomAnimationPresets> CustomAnimationPresets::mPresetsMap;
476 const CustomAnimationPresets& CustomAnimationPresets::getCustomAnimationPresets()
478 // Support localization per-view. Currently not useful for Desktop
479 // but very much critical for LOK. The cache now is per-language.
480 const OUString aLang = comphelper::LibreOfficeKit::isActive()
481 ? comphelper::LibreOfficeKit::getLanguageTag().getBcp47()
482 : SvtSysLocaleOptions().GetLanguageTag().getBcp47();
484 SolarMutexGuard aGuard;
485 const auto it = mPresetsMap.find(aLang);
486 if (it != mPresetsMap.end())
487 return it->second;
489 CustomAnimationPresets& rPresets = mPresetsMap[aLang];
490 rPresets.importResources();
491 return rPresets;
494 Reference< XAnimationNode > CustomAnimationPresets::getRandomPreset( sal_Int16 nPresetClass ) const
496 Reference< XAnimationNode > xNode;
498 const PresetCategoryList* pCategoryList = nullptr;
499 switch( nPresetClass )
501 case EffectPresetClass::ENTRANCE: pCategoryList = &maEntrancePresets; break;
502 case EffectPresetClass::EXIT: pCategoryList = &maExitPresets; break;
503 case EffectPresetClass::EMPHASIS: pCategoryList = &maEmphasisPresets; break;
504 case EffectPresetClass::MOTIONPATH: pCategoryList = &maMotionPathsPresets; break;
505 default:
506 pCategoryList = nullptr;
509 if( pCategoryList && !pCategoryList->empty() )
511 sal_Int32 nCategory = comphelper::rng::uniform_size_distribution(0, pCategoryList->size()-1);
513 PresetCategoryPtr pCategory = (*pCategoryList)[nCategory];
514 if( pCategory && !pCategory->maEffects.empty() )
516 sal_Int32 nDescriptor = comphelper::rng::uniform_size_distribution(0, pCategory->maEffects.size()-1);
517 CustomAnimationPresetPtr pPreset = pCategory->maEffects[nDescriptor];
518 if( pPreset )
520 std::vector<OUString> aSubTypes = pPreset->getSubTypes();
522 OUString aSubType;
523 if( !aSubTypes.empty() )
525 size_t nSubType = comphelper::rng::uniform_size_distribution(0, aSubTypes.size()-1);
526 aSubType = aSubTypes[nSubType];
528 xNode = pPreset->create( aSubType );
533 return xNode;
538 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */