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