Line data Source code
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 <com/sun/star/util/XCloneable.hpp>
21 : #include <com/sun/star/util/theMacroExpander.hpp>
22 : #include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
23 : #include <com/sun/star/container/XNameAccess.hpp>
24 : #include <com/sun/star/configuration/theDefaultProvider.hpp>
25 : #include <com/sun/star/xml/sax/InputSource.hpp>
26 : #include <com/sun/star/xml/sax/Parser.hpp>
27 : #include <com/sun/star/xml/sax/SAXParseException.hpp>
28 : #include <com/sun/star/beans/PropertyValue.hpp>
29 : #include <com/sun/star/presentation/EffectPresetClass.hpp>
30 : #include <com/sun/star/beans/NamedValue.hpp>
31 : #include <unotools/streamwrap.hxx>
32 : #include <comphelper/processfactory.hxx>
33 : #include <comphelper/random.hxx>
34 : #include <comphelper/string.hxx>
35 : #include <unotools/pathoptions.hxx>
36 : #include <tools/stream.hxx>
37 : #include <comphelper/expandmacro.hxx>
38 :
39 : #include <tools/debug.hxx>
40 : #include <rtl/uri.hxx>
41 : #include <rtl/strbuf.hxx>
42 : #include <vcl/svapp.hxx>
43 : #include <osl/mutex.hxx>
44 : #include <unotools/ucbstreamhelper.hxx>
45 : #include <CustomAnimationPreset.hxx>
46 :
47 : #include <algorithm>
48 :
49 : using namespace ::com::sun::star;
50 : using namespace ::com::sun::star::uno;
51 : using namespace ::com::sun::star::animations;
52 : using namespace ::com::sun::star::presentation;
53 :
54 : using ::com::sun::star::io::XInputStream;
55 : using ::com::sun::star::lang::XMultiServiceFactory;
56 : using ::com::sun::star::container::XNameAccess;
57 : using ::com::sun::star::beans::PropertyValue;
58 : using ::com::sun::star::util::XCloneable;
59 : using ::com::sun::star::beans::NamedValue;
60 :
61 : namespace sd {
62 :
63 4 : static Reference< XNameAccess > getNodeAccess( const Reference< XMultiServiceFactory >& xConfigProvider, const OUString& rNodePath )
64 : {
65 4 : Reference< XNameAccess > xConfigAccess;
66 :
67 : try
68 : {
69 4 : Sequence< Any > aArgs( 1 );
70 8 : PropertyValue aPropValue;
71 4 : aPropValue.Name = "nodepath";
72 4 : aPropValue.Value <<= rNodePath;
73 4 : aArgs[0] <<= aPropValue;
74 :
75 8 : xConfigAccess = Reference< XNameAccess >::query(
76 4 : xConfigProvider->createInstanceWithArguments( "com.sun.star.configuration.ConfigurationAccess" ,
77 12 : aArgs ));
78 : }
79 0 : catch (const Exception&)
80 : {
81 : OSL_FAIL( "sd::getNodeAccess(), Exception caught!" );
82 : }
83 :
84 4 : return xConfigAccess;
85 : }
86 :
87 4 : void implImportLabels( const Reference< XMultiServiceFactory >& xConfigProvider, const OUString& rNodePath, UStringMap& rStringMap )
88 : {
89 : try
90 : {
91 4 : Reference< XNameAccess > xConfigAccess( getNodeAccess( xConfigProvider, rNodePath ) );
92 4 : if( xConfigAccess.is() )
93 : {
94 4 : OUString aLabel( "Label" );
95 8 : Reference< XNameAccess > xNameAccess;
96 8 : Sequence< OUString > aNames( xConfigAccess->getElementNames() );
97 4 : const OUString* p = aNames.getConstArray();
98 4 : sal_Int32 n = aNames.getLength();
99 296 : while(n--)
100 : {
101 288 : xConfigAccess->getByName( *p ) >>= xNameAccess;
102 288 : if( xNameAccess.is() )
103 : {
104 288 : OUString aUIName;
105 288 : xNameAccess->getByName( aLabel ) >>= aUIName;
106 288 : if( !aUIName.isEmpty() )
107 : {
108 288 : rStringMap[ *p ] = aUIName;
109 288 : }
110 : }
111 :
112 288 : p++;
113 4 : }
114 4 : }
115 : }
116 0 : catch (const lang::WrappedTargetException&)
117 : {
118 : OSL_FAIL( "sd::implImportLabels(), WrappedTargetException caught!" );
119 : }
120 0 : catch (const Exception&)
121 : {
122 : OSL_FAIL( "sd::implImportLabels(), Exception caught!" );
123 : }
124 4 : }
125 :
126 0 : CustomAnimationPreset::CustomAnimationPreset( CustomAnimationEffectPtr pEffect )
127 : {
128 0 : maPresetId = pEffect->getPresetId();
129 0 : maProperty = pEffect->getProperty();
130 0 : mnPresetClass = pEffect->getPresetClass();
131 :
132 0 : add( pEffect );
133 :
134 0 : mfDuration = pEffect->getDuration();
135 0 : maDefaultSubTyp = pEffect->getPresetSubType();
136 :
137 0 : mbIsTextOnly = false;
138 :
139 0 : Sequence< NamedValue > aUserData( pEffect->getNode()->getUserData() );
140 0 : sal_Int32 nLength = aUserData.getLength();
141 0 : const NamedValue* p = aUserData.getConstArray();
142 :
143 0 : while( nLength-- )
144 : {
145 0 : if ( p->Name == "text-only" )
146 : {
147 0 : mbIsTextOnly = true;
148 0 : break;
149 : }
150 0 : p++;
151 0 : }
152 :
153 0 : }
154 :
155 0 : void CustomAnimationPreset::add( CustomAnimationEffectPtr pEffect )
156 : {
157 0 : maSubTypes[ pEffect->getPresetSubType() ] = pEffect;
158 0 : }
159 :
160 0 : UStringList CustomAnimationPreset::getSubTypes()
161 : {
162 0 : UStringList aSubTypes;
163 :
164 0 : if( maSubTypes.size() > 1 )
165 : {
166 0 : EffectsSubTypeMap::iterator aIter( maSubTypes.begin() );
167 0 : const EffectsSubTypeMap::iterator aEnd( maSubTypes.end() );
168 0 : while( aIter != aEnd )
169 0 : aSubTypes.push_back( (*aIter++).first );
170 : }
171 :
172 0 : return aSubTypes;
173 : }
174 :
175 0 : Reference< XAnimationNode > CustomAnimationPreset::create( const OUString& rstrSubType )
176 : {
177 : try
178 : {
179 0 : OUString strSubType( rstrSubType );
180 0 : if( strSubType.isEmpty() )
181 0 : strSubType = maDefaultSubTyp;
182 :
183 0 : CustomAnimationEffectPtr pEffect = maSubTypes[strSubType];
184 0 : if( pEffect.get() )
185 : {
186 0 : Reference< XCloneable > xCloneable( pEffect->getNode(), UNO_QUERY_THROW );
187 0 : Reference< XAnimationNode > xNode( xCloneable->createClone(), UNO_QUERY_THROW );
188 0 : return xNode;
189 0 : }
190 : }
191 0 : catch (const Exception&)
192 : {
193 : OSL_FAIL( "sd::CustomAnimationPresets::create(), exception caught!" );
194 : }
195 :
196 0 : Reference< XAnimationNode > xNode;
197 0 : return xNode;
198 : }
199 :
200 0 : UStringList CustomAnimationPreset::getProperties() const
201 : {
202 0 : OUString aProperties( maProperty );
203 0 : sal_uInt16 nTokens = comphelper::string::getTokenCount(aProperties, ';');
204 : sal_uInt16 nToken;
205 0 : UStringList aPropertyList;
206 0 : for( nToken = 0; nToken < nTokens; nToken++ )
207 0 : aPropertyList.push_back( aProperties.getToken( nToken, ';' ) );
208 :
209 0 : return aPropertyList;
210 :
211 : }
212 :
213 0 : bool CustomAnimationPreset::hasProperty( const OUString& rProperty )const
214 : {
215 0 : OUString aProperties( maProperty );
216 0 : OUString aProperty( rProperty );
217 0 : sal_uInt16 nTokens = comphelper::string::getTokenCount(aProperties, ';');
218 : sal_uInt16 nToken;
219 0 : for( nToken = 0; nToken < nTokens; nToken++ )
220 : {
221 0 : if( aProperties.getToken( nToken, ';' ) == aProperty )
222 0 : return true;
223 : }
224 :
225 0 : return false;
226 : }
227 :
228 0 : CustomAnimationPresets::CustomAnimationPresets()
229 : {
230 0 : }
231 :
232 0 : CustomAnimationPresets::~CustomAnimationPresets()
233 : {
234 0 : }
235 :
236 0 : void CustomAnimationPresets::init()
237 : {
238 0 : importResources();
239 0 : }
240 :
241 8 : Reference< XAnimationNode > implImportEffects( const Reference< XMultiServiceFactory >& xServiceFactory, const OUString& rPath )
242 : {
243 8 : Reference< XAnimationNode > xRootNode;
244 :
245 : try
246 : {
247 : // create stream
248 8 : SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( rPath, STREAM_READ );
249 8 : Reference<XInputStream> xInputStream( new utl::OInputStreamWrapper( pIStm, true ) );
250 :
251 : // prepare ParserInputSrouce
252 16 : xml::sax::InputSource aParserInput;
253 8 : aParserInput.sSystemId = rPath;
254 8 : aParserInput.aInputStream = xInputStream;
255 :
256 : // get parser
257 16 : Reference< xml::sax::XParser > xParser = xml::sax::Parser::create( comphelper::getComponentContext(xServiceFactory) );
258 :
259 : // get filter
260 16 : Reference< xml::sax::XDocumentHandler > xFilter( xServiceFactory->createInstance("com.sun.star.comp.Xmloff.AnimationsImport" ), UNO_QUERY );
261 :
262 : DBG_ASSERT( xFilter.is(), "Can't instantiate filter component." );
263 8 : if( !xFilter.is() )
264 0 : return xRootNode;
265 :
266 : // connect parser and filter
267 8 : xParser->setDocumentHandler( xFilter );
268 :
269 : // finally, parser the stream
270 8 : xParser->parseStream( aParserInput );
271 :
272 16 : Reference< XAnimationNodeSupplier > xAnimationNodeSupplier( xFilter, UNO_QUERY );
273 8 : if( xAnimationNodeSupplier.is() )
274 16 : xRootNode = xAnimationNodeSupplier->getAnimationNode();
275 : }
276 0 : catch (const xml::sax::SAXParseException&)
277 : {
278 : OSL_FAIL( "sd::implImportEffects(), SAXParseException caught!" );
279 : }
280 0 : catch (const xml::sax::SAXException&)
281 : {
282 : OSL_FAIL( "sd::implImportEffects(), SAXException caught!" );
283 : }
284 0 : catch (const io::IOException&)
285 : {
286 : OSL_FAIL( "sd::implImportEffects(), IOException caught!" );
287 : }
288 0 : catch (const Exception&)
289 : {
290 : OSL_FAIL( "sd::importEffects(), Exception caught!" );
291 : }
292 :
293 8 : return xRootNode;
294 : }
295 :
296 0 : void CustomAnimationPresets::importEffects()
297 : {
298 : try
299 : {
300 : uno::Reference< uno::XComponentContext > xContext(
301 0 : comphelper::getProcessComponentContext() );
302 : Reference< XMultiServiceFactory > xServiceFactory(
303 0 : xContext->getServiceManager(), UNO_QUERY_THROW );
304 :
305 : uno::Reference< util::XMacroExpander > xMacroExpander =
306 0 : util::theMacroExpander::get(xContext);
307 :
308 : Reference< XMultiServiceFactory > xConfigProvider =
309 0 : configuration::theDefaultProvider::get( xContext );
310 :
311 : // read path to transition effects files from config
312 : Any propValue = uno::makeAny(
313 : beans::PropertyValue(
314 : "nodepath", -1,
315 : uno::makeAny( OUString( "/org.openoffice.Office.Impress/Misc" )),
316 0 : beans::PropertyState_DIRECT_VALUE ) );
317 :
318 : Reference<container::XNameAccess> xNameAccess(
319 0 : xConfigProvider->createInstanceWithArguments(
320 : "com.sun.star.configuration.ConfigurationAccess",
321 0 : Sequence<Any>( &propValue, 1 ) ), UNO_QUERY_THROW );
322 0 : uno::Sequence< OUString > aFiles;
323 0 : xNameAccess->getByName( "EffectFiles" ) >>= aFiles;
324 :
325 0 : for( sal_Int32 i=0; i<aFiles.getLength(); ++i )
326 : {
327 0 : OUString aURL = ::comphelper::getExpandedFilePath(aFiles[i]);
328 :
329 0 : mxRootNode = implImportEffects( xServiceFactory, aURL );
330 :
331 0 : if( mxRootNode.is() )
332 : {
333 0 : Reference< XTimeContainer > xRootContainer( mxRootNode, UNO_QUERY_THROW );
334 0 : EffectSequenceHelper aSequence( xRootContainer );
335 :
336 0 : EffectSequence::iterator aIter( aSequence.getBegin() );
337 0 : const EffectSequence::iterator aEnd( aSequence.getEnd() );
338 :
339 0 : while( aIter != aEnd )
340 : {
341 0 : CustomAnimationEffectPtr pEffect = (*aIter);
342 :
343 0 : const OUString aPresetId( pEffect->getPresetId() );
344 0 : CustomAnimationPresetPtr pDescriptor = getEffectDescriptor( aPresetId );
345 0 : if( pDescriptor.get() )
346 0 : pDescriptor->add( pEffect );
347 : else
348 : {
349 0 : pDescriptor.reset( new CustomAnimationPreset( pEffect ) );
350 0 : pDescriptor->maLabel = getUINameForPresetId( pEffect->getPresetId() );
351 0 : maEffectDiscriptorMap[aPresetId] = pDescriptor;
352 : }
353 :
354 0 : ++aIter;
355 0 : }
356 : }
357 0 : }
358 : }
359 0 : catch (const xml::sax::SAXParseException&)
360 : {
361 : OSL_FAIL( "sd::CustomAnimationPresets::importEffects(), SAXParseException caught!" );
362 : }
363 0 : catch (const xml::sax::SAXException&)
364 : {
365 : OSL_FAIL( "sd::CustomAnimationPresets::importEffects(), SAXException caught!" );
366 : }
367 0 : catch (const io::IOException&)
368 : {
369 : OSL_FAIL( "sd::CustomAnimationPresets::importEffects(), IOException caught!" );
370 : }
371 0 : catch (const Exception&)
372 : {
373 : OSL_FAIL( "sd::CustomAnimationPresets::importEffects(), Exception caught!" );
374 : }
375 0 : }
376 :
377 0 : void CustomAnimationPresets::importResources()
378 : {
379 : try
380 : {
381 : // Get service factory
382 0 : Reference< XComponentContext > xContext( comphelper::getProcessComponentContext() );
383 :
384 : Reference< XMultiServiceFactory > xConfigProvider =
385 0 : configuration::theDefaultProvider::get( xContext );
386 :
387 0 : const OUString aPropertyPath("/org.openoffice.Office.UI.Effects/UserInterface/Properties" );
388 0 : implImportLabels( xConfigProvider, aPropertyPath, maPropertyNameMap );
389 :
390 0 : const OUString aEffectsPath( "/org.openoffice.Office.UI.Effects/UserInterface/Effects" );
391 0 : implImportLabels( xConfigProvider, aEffectsPath, maEffectNameMap );
392 :
393 0 : importEffects();
394 :
395 0 : const OUString aEntrancePath( "/org.openoffice.Office.UI.Effects/Presets/Entrance" );
396 0 : importPresets( xConfigProvider, aEntrancePath, maEntrancePresets );
397 :
398 0 : const OUString aEmphasisPath( "/org.openoffice.Office.UI.Effects/Presets/Emphasis" );
399 0 : importPresets( xConfigProvider, aEmphasisPath, maEmphasisPresets );
400 :
401 0 : const OUString aExitPath( "/org.openoffice.Office.UI.Effects/Presets/Exit" );
402 0 : importPresets( xConfigProvider, aExitPath, maExitPresets );
403 :
404 0 : const OUString aMotionPathsPath( "/org.openoffice.Office.UI.Effects/Presets/MotionPaths" );
405 0 : importPresets( xConfigProvider, aMotionPathsPath, maMotionPathsPresets );
406 :
407 0 : const OUString aMiscPath( "/org.openoffice.Office.UI.Effects/Presets/Misc" );
408 0 : importPresets( xConfigProvider, aMiscPath, maMiscPresets );
409 : }
410 0 : catch (const lang::WrappedTargetException&)
411 : {
412 : OSL_FAIL( "sd::CustomAnimationPresets::importResources(), WrappedTargetException caught!" );
413 : }
414 0 : catch (const Exception&)
415 : {
416 : OSL_FAIL( "sd::CustomAnimationPresets::importResources(), Exception caught!" );
417 : }
418 0 : }
419 :
420 0 : void CustomAnimationPresets::importPresets( const Reference< XMultiServiceFactory >& xConfigProvider, const OUString& rNodePath, PresetCategoryList& rPresetMap )
421 : {
422 : #ifdef DEBUG
423 : OUString aMissedPresetIds;
424 : #endif
425 :
426 : try
427 : {
428 0 : Reference< XNameAccess > xTypeAccess( getNodeAccess( xConfigProvider, rNodePath ) );
429 0 : if( xTypeAccess.is() )
430 : {
431 0 : Reference< XNameAccess > xCategoryAccess;
432 0 : const OUString aEffectsName( "Effects" );
433 0 : const OUString aLabelName( "Label" );
434 :
435 0 : Sequence< OUString > aNames( xTypeAccess->getElementNames() );
436 0 : const OUString* p = aNames.getConstArray();
437 0 : sal_Int32 n = aNames.getLength();
438 0 : while(n--)
439 : {
440 0 : xTypeAccess->getByName( *p ) >>= xCategoryAccess;
441 :
442 0 : if( xCategoryAccess.is() && xCategoryAccess->hasByName( aLabelName ) && xCategoryAccess->hasByName( aEffectsName ) )
443 : {
444 0 : OUString aLabel;
445 0 : xCategoryAccess->getByName( aLabelName ) >>= aLabel;
446 :
447 0 : Sequence< OUString > aEffects;
448 0 : xCategoryAccess->getByName( aEffectsName ) >>= aEffects;
449 :
450 0 : EffectDescriptorList aEffectsList;
451 :
452 0 : const OUString* pEffectNames = aEffects.getConstArray();
453 0 : sal_Int32 nEffectCount = aEffects.getLength();
454 0 : while( nEffectCount-- )
455 : {
456 0 : CustomAnimationPresetPtr pEffect = getEffectDescriptor( *pEffectNames );
457 0 : if( pEffect.get() )
458 : {
459 0 : aEffectsList.push_back( pEffect );
460 : }
461 : #ifdef DEBUG
462 : else
463 : {
464 : aMissedPresetIds += OUString(*pEffectNames);
465 : aMissedPresetIds += "\n";
466 : }
467 : #endif
468 0 : pEffectNames++;
469 0 : }
470 0 : rPresetMap.push_back( PresetCategoryPtr( new PresetCategory( aLabel, aEffectsList ) ) );
471 : }
472 :
473 0 : p++;
474 0 : }
475 0 : }
476 : }
477 0 : catch (const Exception&)
478 : {
479 : OSL_FAIL( "sd::CustomAnimationPresets::importPresets(), Exception caught!" );
480 : }
481 :
482 : #ifdef DEBUG
483 : if( !aMissedPresetIds.isEmpty() )
484 : {
485 : OStringBuffer aTmp("sd::CustomAnimationPresets::importPresets(), invalid preset id!\n");
486 : aTmp.append(OUStringToOString(aMissedPresetIds,
487 : RTL_TEXTENCODING_ASCII_US));
488 : OSL_FAIL(aTmp.getStr());
489 : }
490 : #endif
491 0 : }
492 :
493 0 : CustomAnimationPresetPtr CustomAnimationPresets::getEffectDescriptor( const OUString& rPresetId ) const
494 : {
495 0 : EffectDescriptorMap::const_iterator aIter( maEffectDiscriptorMap.find( rPresetId ) );
496 :
497 0 : if( aIter != maEffectDiscriptorMap.end() )
498 : {
499 0 : return (*aIter).second;
500 : }
501 : else
502 : {
503 0 : return CustomAnimationPresetPtr((CustomAnimationPreset*)0);
504 : }
505 : }
506 :
507 0 : const OUString& CustomAnimationPresets::getUINameForPresetId( const OUString& rPresetId ) const
508 : {
509 0 : return translateName( rPresetId, maEffectNameMap );
510 : }
511 :
512 0 : const OUString& CustomAnimationPresets::getUINameForProperty( const OUString& rPresetId ) const
513 : {
514 0 : return translateName( rPresetId, maPropertyNameMap );
515 : }
516 :
517 0 : const OUString& CustomAnimationPresets::translateName( const OUString& rId, const UStringMap& rNameMap ) const
518 : {
519 0 : UStringMap::const_iterator aIter( rNameMap.find( rId ) );
520 :
521 0 : if( aIter != rNameMap.end() )
522 : {
523 0 : return (*aIter).second;
524 : }
525 : else
526 : {
527 0 : return rId;
528 : }
529 : }
530 0 : void CustomAnimationPresets::changePresetSubType( CustomAnimationEffectPtr pEffect, const OUString& rPresetSubType ) const
531 : {
532 0 : if( pEffect.get() && pEffect->getPresetSubType() != rPresetSubType )
533 : {
534 0 : CustomAnimationPresetPtr pDescriptor( getEffectDescriptor( pEffect->getPresetId() ) );
535 :
536 0 : if( pDescriptor.get() )
537 : {
538 0 : Reference< XAnimationNode > xNewNode( pDescriptor->create( rPresetSubType ) );
539 0 : if( xNewNode.is() )
540 0 : pEffect->replaceNode( xNewNode );
541 0 : }
542 : }
543 0 : }
544 :
545 : CustomAnimationPresets* CustomAnimationPresets::mpCustomAnimationPresets = 0;
546 :
547 0 : const CustomAnimationPresets& CustomAnimationPresets::getCustomAnimationPresets()
548 : {
549 0 : if( !mpCustomAnimationPresets )
550 : {
551 0 : SolarMutexGuard aGuard;
552 :
553 0 : if( !mpCustomAnimationPresets )
554 : {
555 0 : mpCustomAnimationPresets = new sd::CustomAnimationPresets();
556 0 : mpCustomAnimationPresets->init();
557 0 : }
558 : }
559 :
560 0 : return *mpCustomAnimationPresets;
561 : }
562 :
563 0 : Reference< XAnimationNode > CustomAnimationPresets::getRandomPreset( sal_Int16 nPresetClass ) const
564 : {
565 0 : Reference< XAnimationNode > xNode;
566 :
567 0 : const PresetCategoryList* pCategoryList = 0;
568 0 : switch( nPresetClass )
569 : {
570 0 : case EffectPresetClass::ENTRANCE: pCategoryList = &maEntrancePresets; break;
571 0 : case EffectPresetClass::EXIT: pCategoryList = &maExitPresets; break;
572 0 : case EffectPresetClass::EMPHASIS: pCategoryList = &maEmphasisPresets; break;
573 0 : case EffectPresetClass::MOTIONPATH: pCategoryList = &maMotionPathsPresets; break;
574 : default:
575 0 : pCategoryList = 0;
576 : }
577 :
578 0 : if( pCategoryList && pCategoryList->size() )
579 : {
580 0 : sal_Int32 nCategory = comphelper::rng::uniform_size_distribution(0, pCategoryList->size()-1);
581 :
582 0 : PresetCategoryPtr pCategory = (*pCategoryList)[nCategory];
583 0 : if( pCategory.get() && !pCategory->maEffects.empty() )
584 : {
585 0 : sal_Int32 nDescriptor = comphelper::rng::uniform_size_distribution(0, pCategory->maEffects.size()-1);
586 0 : CustomAnimationPresetPtr pPreset = pCategory->maEffects[nDescriptor];
587 0 : if( pPreset.get() )
588 : {
589 0 : UStringList aSubTypes = pPreset->getSubTypes();
590 :
591 0 : OUString aSubType;
592 0 : if( !aSubTypes.empty() )
593 : {
594 0 : size_t nSubType = comphelper::rng::uniform_size_distribution(0, aSubTypes.size()-1);
595 0 : aSubType = aSubTypes[nSubType];
596 : }
597 0 : xNode = pPreset->create( aSubType );
598 0 : }
599 0 : }
600 : }
601 :
602 0 : return xNode;
603 : }
604 :
605 114 : }
606 :
607 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|