merge the formfield patch from ooo-build
[ooovba.git] / sd / source / core / CustomAnimationPreset.cxx
blobd00e4bd79c68edd145ad65aac0c56f2e15e696e6
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: CustomAnimationPreset.cxx,v $
10 * $Revision: 1.7.74.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sd.hxx"
33 #include <com/sun/star/util/XCloneable.hpp>
34 #include <com/sun/star/util/XMacroExpander.hpp>
35 #include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
36 #include <com/sun/star/container/XNameAccess.hpp>
37 #include <com/sun/star/xml/sax/InputSource.hpp>
38 #include <com/sun/star/xml/sax/XParser.hpp>
39 #include <com/sun/star/xml/sax/SAXParseException.hpp>
40 #include <com/sun/star/beans/PropertyValue.hpp>
41 #include <com/sun/star/beans/XPropertySet.hpp>
42 #include <com/sun/star/presentation/EffectPresetClass.hpp>
43 #include <com/sun/star/beans/NamedValue.hpp>
44 #include <tools/urlobj.hxx>
45 #include <unotools/streamwrap.hxx>
46 #include <comphelper/processfactory.hxx>
47 #include <svtools/pathoptions.hxx>
48 #include <tools/stream.hxx>
50 #include <tools/debug.hxx>
51 #include <rtl/uri.hxx>
52 #include <vcl/svapp.hxx>
53 #include <vos/mutex.hxx>
54 #include <unotools/ucbstreamhelper.hxx>
55 #include <CustomAnimationPreset.hxx>
57 #include <algorithm>
59 using namespace ::vos;
60 using namespace ::com::sun::star;
61 using namespace ::com::sun::star::animations;
62 using namespace ::com::sun::star::presentation;
64 using ::rtl::OUString;
65 using ::com::sun::star::uno::UNO_QUERY;
66 using ::com::sun::star::uno::UNO_QUERY_THROW;
67 using ::com::sun::star::uno::Any;
68 using ::com::sun::star::uno::Sequence;
69 using ::com::sun::star::uno::Reference;
70 using ::com::sun::star::uno::Exception;
71 using ::com::sun::star::io::XInputStream;
72 using ::com::sun::star::lang::XMultiServiceFactory;
73 using ::com::sun::star::container::XNameAccess;
74 using ::com::sun::star::beans::PropertyValue;
75 using ::com::sun::star::util::XCloneable;
76 using ::com::sun::star::beans::NamedValue;
78 namespace sd {
80 static Reference< XNameAccess > getNodeAccess( const Reference< XMultiServiceFactory >& xConfigProvider, const OUString& rNodePath )
82 Reference< XNameAccess > xConfigAccess;
84 try
86 Sequence< Any > aArgs( 1 );
87 PropertyValue aPropValue;
88 aPropValue.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ));
89 aPropValue.Value <<= rNodePath;
90 aArgs[0] <<= aPropValue;
92 xConfigAccess = Reference< XNameAccess >::query(
93 xConfigProvider->createInstanceWithArguments(
94 OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationAccess" )),
95 aArgs ));
97 catch( Exception& e )
99 (void)e;
100 DBG_ERROR( "sd::getNodeAccess(), Exception catched!" );
103 return xConfigAccess;
106 void implImportLabels( const Reference< XMultiServiceFactory >& xConfigProvider, const OUString& rNodePath, UStringMap& rStringMap )
110 Reference< XNameAccess > xConfigAccess( getNodeAccess( xConfigProvider, rNodePath ) );
111 if( xConfigAccess.is() )
113 OUString aLabel( RTL_CONSTASCII_USTRINGPARAM( "Label" ) );
114 Reference< XNameAccess > xNameAccess;
115 Sequence< OUString > aNames( xConfigAccess->getElementNames() );
116 const OUString* p = aNames.getConstArray();
117 sal_Int32 n = aNames.getLength();
118 while(n--)
120 xConfigAccess->getByName( *p ) >>= xNameAccess;
121 if( xNameAccess.is() )
123 OUString aUIName;
124 xNameAccess->getByName( aLabel ) >>= aUIName;
125 if( aUIName.getLength() )
127 rStringMap[ *p ] = aUIName;
131 p++;
135 catch( lang::WrappedTargetException& e )
137 (void)e;
138 DBG_ERROR( "sd::implImportLabels(), WrappedTargetException catched!" );
140 catch( Exception& e )
142 (void)e;
143 DBG_ERROR( "sd::implImportLabels(), Exception catched!" );
147 CustomAnimationPreset::CustomAnimationPreset( CustomAnimationEffectPtr pEffect )
149 maPresetId = pEffect->getPresetId();
150 maProperty = pEffect->getProperty();
151 mnPresetClass = pEffect->getPresetClass();
153 add( pEffect );
155 mfDuration = pEffect->getDuration();
156 maDefaultSubTyp = pEffect->getPresetSubType();
158 mbIsTextOnly = false;
160 Sequence< NamedValue > aUserData( pEffect->getNode()->getUserData() );
161 sal_Int32 nLength = aUserData.getLength();
162 const NamedValue* p = aUserData.getConstArray();
164 while( nLength-- )
166 if( p->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "text-only" ) ) )
168 mbIsTextOnly = true;
169 break;
171 p++;
176 void CustomAnimationPreset::add( CustomAnimationEffectPtr pEffect )
178 maSubTypes[ pEffect->getPresetSubType() ] = pEffect;
181 UStringList CustomAnimationPreset::getSubTypes()
183 UStringList aSubTypes;
185 if( maSubTypes.size() > 1 )
187 EffectsSubTypeMap::iterator aIter( maSubTypes.begin() );
188 const EffectsSubTypeMap::iterator aEnd( maSubTypes.end() );
189 while( aIter != aEnd )
190 aSubTypes.push_back( (*aIter++).first );
193 return aSubTypes;
196 Reference< XAnimationNode > CustomAnimationPreset::create( const rtl::OUString& rstrSubType )
200 OUString strSubType( rstrSubType );
201 if( strSubType.getLength() == 0 )
202 strSubType = maDefaultSubTyp;
204 CustomAnimationEffectPtr pEffect = maSubTypes[strSubType];
205 if( pEffect.get() )
207 Reference< XCloneable > xCloneable( pEffect->getNode(), UNO_QUERY_THROW );
208 Reference< XAnimationNode > xNode( xCloneable->createClone(), UNO_QUERY_THROW );
209 return xNode;
212 catch( Exception& e )
214 (void)e;
215 DBG_ERROR( "sd::CustomAnimationPresets::create(), exception catched!" );
218 Reference< XAnimationNode > xNode;
219 return xNode;
222 UStringList CustomAnimationPreset::getProperties() const
224 String aProperties( maProperty );
225 USHORT nTokens = aProperties.GetTokenCount();
226 USHORT nToken;
227 UStringList aPropertyList;
228 for( nToken = 0; nToken < nTokens; nToken++ )
229 aPropertyList.push_back( aProperties.GetToken( nToken ) );
231 return aPropertyList;
235 bool CustomAnimationPreset::hasProperty( const OUString& rProperty )const
237 String aProperties( maProperty );
238 String aProperty( rProperty );
239 USHORT nTokens = aProperties.GetTokenCount();
240 USHORT nToken;
241 for( nToken = 0; nToken < nTokens; nToken++ )
243 if( aProperties.GetToken( nToken ) == aProperty )
244 return true;
247 return false;
250 CustomAnimationPresets::CustomAnimationPresets()
254 CustomAnimationPresets::~CustomAnimationPresets()
258 void CustomAnimationPresets::init()
260 importResources();
263 Reference< XAnimationNode > implImportEffects( const Reference< XMultiServiceFactory >& xServiceFactory, const OUString& rPath )
265 Reference< XAnimationNode > xRootNode;
269 // create stream
270 SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( rPath, STREAM_READ );
271 Reference<XInputStream> xInputStream( new utl::OInputStreamWrapper( pIStm, sal_True ) );
273 // prepare ParserInputSrouce
274 xml::sax::InputSource aParserInput;
275 aParserInput.sSystemId = rPath;
276 aParserInput.aInputStream = xInputStream;
278 // get parser
279 Reference< xml::sax::XParser > xParser(
280 xServiceFactory->createInstance(
281 OUString::createFromAscii("com.sun.star.xml.sax.Parser") ),
282 UNO_QUERY );
284 DBG_ASSERT( xParser.is(), "Can't create parser" );
285 if( !xParser.is() )
286 return xRootNode;
288 // get filter
289 Reference< xml::sax::XDocumentHandler > xFilter(
290 xServiceFactory->createInstance(
291 OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Xmloff.AnimationsImport" ) ) ), UNO_QUERY );
293 DBG_ASSERT( xFilter.is(), "Can't instantiate filter component." );
294 if( !xFilter.is() )
295 return xRootNode;
297 // connect parser and filter
298 xParser->setDocumentHandler( xFilter );
300 // finally, parser the stream
301 xParser->parseStream( aParserInput );
303 Reference< XAnimationNodeSupplier > xAnimationNodeSupplier( xFilter, UNO_QUERY );
304 if( xAnimationNodeSupplier.is() )
305 xRootNode = xAnimationNodeSupplier->getAnimationNode();
307 catch( xml::sax::SAXParseException& r )
309 (void)r;
310 DBG_ERROR( "sd::implImportEffects(), SAXParseException catched!" );
312 catch( xml::sax::SAXException& r )
314 (void)r;
315 DBG_ERROR( "sd::implImportEffects(), SAXException catched!" );
317 catch( io::IOException& r )
319 (void)r;
320 DBG_ERROR( "sd::implImportEffects(), IOException catched!" );
322 catch( Exception& r )
324 (void)r;
325 DBG_ERROR( "sd::importEffects(), Exception catched!" );
328 return xRootNode;
331 #define EXPAND_PROTOCOL "vnd.sun.star.expand:"
333 void CustomAnimationPresets::importEffects()
337 // Get service factory
338 Reference< XMultiServiceFactory > xServiceFactory( comphelper::getProcessServiceFactory() );
339 DBG_ASSERT( xServiceFactory.is(), "sd::CustomAnimationPresets::import(), got no service manager" );
340 if( !xServiceFactory.is() )
341 return;
343 uno::Reference< beans::XPropertySet > xProps( xServiceFactory, UNO_QUERY );
344 uno::Reference< uno::XComponentContext > xContext;
345 xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xContext;
347 uno::Reference< util::XMacroExpander > xMacroExpander;
348 if( xContext.is() )
349 xMacroExpander.set( xContext->getValueByName(
350 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/singletons/com.sun.star.util.theMacroExpander"))),
351 UNO_QUERY );
353 Reference< XMultiServiceFactory > xConfigProvider(
354 xServiceFactory->createInstance(
355 OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ))),
356 UNO_QUERY_THROW );
358 // read path to transition effects files from config
359 Any propValue = uno::makeAny(
360 beans::PropertyValue(
361 OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" )), -1,
362 uno::makeAny( OUString( RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Office.Impress/Misc") )),
363 beans::PropertyState_DIRECT_VALUE ) );
365 Reference<container::XNameAccess> xNameAccess(
366 xConfigProvider->createInstanceWithArguments(
367 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationAccess")),
368 Sequence<Any>( &propValue, 1 ) ), UNO_QUERY_THROW );
369 uno::Sequence< rtl::OUString > aFiles;
370 xNameAccess->getByName(
371 OUString( RTL_CONSTASCII_USTRINGPARAM("EffectFiles"))) >>= aFiles;
373 for( sal_Int32 i=0; i<aFiles.getLength(); ++i )
375 rtl::OUString aURL = aFiles[i];
376 if( aURL.compareToAscii( RTL_CONSTASCII_STRINGPARAM( EXPAND_PROTOCOL )) == 0 )
378 // cut protocol
379 rtl::OUString aMacro( aURL.copy( sizeof ( EXPAND_PROTOCOL ) -1 ) );
380 // decode uric class chars
381 aMacro = rtl::Uri::decode( aMacro, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
382 // expand macro string
383 aURL = xMacroExpander->expandMacros( aMacro );
386 mxRootNode = implImportEffects( xServiceFactory, aURL );
388 if( mxRootNode.is() )
390 Reference< XTimeContainer > xRootContainer( mxRootNode, UNO_QUERY_THROW );
391 EffectSequenceHelper aSequence( xRootContainer );
393 EffectSequence::iterator aIter( aSequence.getBegin() );
394 const EffectSequence::iterator aEnd( aSequence.getEnd() );
396 while( aIter != aEnd )
398 CustomAnimationEffectPtr pEffect = (*aIter);
400 const OUString aPresetId( pEffect->getPresetId() );
401 CustomAnimationPresetPtr pDescriptor = getEffectDescriptor( aPresetId );
402 if( pDescriptor.get() )
403 pDescriptor->add( pEffect );
404 else
406 pDescriptor.reset( new CustomAnimationPreset( pEffect ) );
407 pDescriptor->maLabel = getUINameForPresetId( pEffect->getPresetId() );
408 maEffectDiscriptorMap[aPresetId] = pDescriptor;
411 aIter++;
416 catch( xml::sax::SAXParseException& r )
418 (void)r;
419 DBG_ERROR( "sd::CustomAnimationPresets::importEffects(), SAXParseException catched!" );
421 catch( xml::sax::SAXException& r )
423 (void)r;
424 DBG_ERROR( "sd::CustomAnimationPresets::importEffects(), SAXException catched!" );
426 catch( io::IOException& r )
428 (void)r;
429 DBG_ERROR( "sd::CustomAnimationPresets::importEffects(), IOException catched!" );
431 catch( Exception& r )
433 (void)r;
434 DBG_ERROR( "sd::CustomAnimationPresets::importEffects(), Exception catched!" );
438 void CustomAnimationPresets::importResources()
442 // Get service factory
443 Reference< XMultiServiceFactory > xServiceFactory( comphelper::getProcessServiceFactory() );
444 DBG_ASSERT( xServiceFactory.is(), "sd::CustomAnimationPresets::import(), got no service manager" );
445 if( !xServiceFactory.is() )
446 return;
448 Reference< XMultiServiceFactory > xConfigProvider(
449 xServiceFactory->createInstance(
450 OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ))),
451 UNO_QUERY );
453 const OUString aPropertyPath( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.UI.Effects/UserInterface/Properties" ) );
454 implImportLabels( xConfigProvider, aPropertyPath, maPropertyNameMap );
456 const OUString aEffectsPath( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.UI.Effects/UserInterface/Effects" ) );
457 implImportLabels( xConfigProvider, aEffectsPath, maEffectNameMap );
459 importEffects();
461 const OUString aEntrancePath( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.UI.Effects/Presets/Entrance" ) );
462 importPresets( xConfigProvider, aEntrancePath, maEntrancePresets );
464 const OUString aEmphasisPath( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.UI.Effects/Presets/Emphasis" ) );
465 importPresets( xConfigProvider, aEmphasisPath, maEmphasisPresets );
467 const OUString aExitPath( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.UI.Effects/Presets/Exit" ) );
468 importPresets( xConfigProvider, aExitPath, maExitPresets );
470 const OUString aMotionPathsPath( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.UI.Effects/Presets/MotionPaths" ) );
471 importPresets( xConfigProvider, aMotionPathsPath, maMotionPathsPresets );
473 const OUString aMiscPath( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.UI.Effects/Presets/Misc" ) );
474 importPresets( xConfigProvider, aMiscPath, maMiscPresets );
476 catch( lang::WrappedTargetException& e )
478 (void)e;
479 DBG_ERROR( "sd::CustomAnimationPresets::importResources(), WrappedTargetException catched!" );
481 catch( Exception& e )
483 (void)e;
484 DBG_ERROR( "sd::CustomAnimationPresets::importResources(), Exception catched!" );
488 void CustomAnimationPresets::importPresets( const Reference< XMultiServiceFactory >& xConfigProvider, const OUString& rNodePath, PresetCategoryList& rPresetMap )
490 #ifdef DEBUG
491 String aMissedPresetIds;
492 #endif
496 Reference< XNameAccess > xTypeAccess( getNodeAccess( xConfigProvider, rNodePath ) );
497 if( xTypeAccess.is() )
499 Reference< XNameAccess > xCategoryAccess;
500 const OUString aEffectsName( RTL_CONSTASCII_USTRINGPARAM( "Effects" ) );
501 const OUString aLabelName( RTL_CONSTASCII_USTRINGPARAM( "Label" ) );
503 Sequence< OUString > aNames( xTypeAccess->getElementNames() );
504 const OUString* p = aNames.getConstArray();
505 sal_Int32 n = aNames.getLength();
506 while(n--)
508 xTypeAccess->getByName( *p ) >>= xCategoryAccess;
510 if( xCategoryAccess.is() && xCategoryAccess->hasByName( aLabelName ) && xCategoryAccess->hasByName( aEffectsName ) )
512 OUString aLabel;
513 xCategoryAccess->getByName( aLabelName ) >>= aLabel;
515 Sequence< OUString > aEffects;
516 xCategoryAccess->getByName( aEffectsName ) >>= aEffects;
518 EffectDescriptorList aEffectsList;
520 const OUString* pEffectNames = aEffects.getConstArray();
521 sal_Int32 nEffectCount = aEffects.getLength();
522 while( nEffectCount-- )
524 CustomAnimationPresetPtr pEffect = getEffectDescriptor( *pEffectNames );
525 if( pEffect.get() )
527 aEffectsList.push_back( pEffect );
529 #ifdef DEBUG
530 else
532 aMissedPresetIds += String(*pEffectNames);
533 aMissedPresetIds += String( RTL_CONSTASCII_USTRINGPARAM("\n") );
535 #endif
536 pEffectNames++;
538 rPresetMap.push_back( PresetCategoryPtr( new PresetCategory( aLabel, aEffectsList ) ) );
541 p++;
545 catch( Exception& e )
547 (void)e;
548 DBG_ERROR( "sd::CustomAnimationPresets::importPresets(), Exception catched!" );
551 #ifdef DEBUG
552 if( aMissedPresetIds.Len() )
554 ByteString aTmp( "sd::CustomAnimationPresets::importPresets(), invalid preset id!\n" );
555 aTmp += ByteString( aMissedPresetIds, RTL_TEXTENCODING_ASCII_US );
556 DBG_ERROR( aTmp.GetBuffer() );
558 #endif
561 CustomAnimationPresetPtr CustomAnimationPresets::getEffectDescriptor( const rtl::OUString& rPresetId ) const
563 EffectDescriptorMap::const_iterator aIter( maEffectDiscriptorMap.find( rPresetId ) );
565 if( aIter != maEffectDiscriptorMap.end() )
567 return (*aIter).second;
569 else
571 return CustomAnimationPresetPtr((CustomAnimationPreset*)0);
575 const rtl::OUString& CustomAnimationPresets::getUINameForPresetId( const rtl::OUString& rPresetId ) const
577 return translateName( rPresetId, maEffectNameMap );
580 const rtl::OUString& CustomAnimationPresets::getUINameForProperty( const rtl::OUString& rPresetId ) const
582 return translateName( rPresetId, maPropertyNameMap );
585 const rtl::OUString& CustomAnimationPresets::translateName( const rtl::OUString& rId, const UStringMap& rNameMap ) const
587 UStringMap::const_iterator aIter( rNameMap.find( rId ) );
589 if( aIter != rNameMap.end() )
591 return (*aIter).second;
593 else
595 return rId;
598 void CustomAnimationPresets::changePresetSubType( CustomAnimationEffectPtr pEffect, const rtl::OUString& rPresetSubType ) const
600 if( pEffect.get() && pEffect->getPresetSubType() != rPresetSubType )
602 CustomAnimationPresetPtr pDescriptor( getEffectDescriptor( pEffect->getPresetId() ) );
604 if( pDescriptor.get() )
606 Reference< XAnimationNode > xNewNode( pDescriptor->create( rPresetSubType ) );
607 if( xNewNode.is() )
608 pEffect->replaceNode( xNewNode );
613 CustomAnimationPresets* CustomAnimationPresets::mpCustomAnimationPresets = 0;
615 const CustomAnimationPresets& CustomAnimationPresets::getCustomAnimationPresets()
617 if( !mpCustomAnimationPresets )
619 OGuard aGuard( Application::GetSolarMutex() );
621 if( !mpCustomAnimationPresets )
623 mpCustomAnimationPresets = new sd::CustomAnimationPresets();
624 mpCustomAnimationPresets->init();
628 return *mpCustomAnimationPresets;
631 Reference< XAnimationNode > CustomAnimationPresets::getRandomPreset( sal_Int16 nPresetClass ) const
633 Reference< XAnimationNode > xNode;
635 const PresetCategoryList* pCategoryList = 0;
636 switch( nPresetClass )
638 case EffectPresetClass::ENTRANCE: pCategoryList = &maEntrancePresets; break;
639 case EffectPresetClass::EXIT: pCategoryList = &maExitPresets; break;
640 case EffectPresetClass::EMPHASIS: pCategoryList = &maEmphasisPresets; break;
641 case EffectPresetClass::MOTIONPATH: pCategoryList = &maMotionPathsPresets; break;
642 default:
643 pCategoryList = 0;
646 if( pCategoryList && pCategoryList->size() )
648 sal_Int32 nCategory = (rand() * pCategoryList->size() / RAND_MAX);
650 PresetCategoryPtr pCategory = (*pCategoryList)[nCategory];
651 if( pCategory.get() && pCategory->maEffects.size() )
653 sal_Int32 nDescriptor = (rand() * pCategory->maEffects.size() / RAND_MAX);
654 CustomAnimationPresetPtr pPreset = pCategory->maEffects[nDescriptor];
655 if( pPreset.get() )
657 UStringList aSubTypes = pPreset->getSubTypes();
659 OUString aSubType;
660 if( aSubTypes.size() )
662 sal_Int32 nSubType = (rand() * aSubTypes.size() / RAND_MAX);
663 aSubType = aSubTypes[nSubType];
665 xNode = pPreset->create( aSubType );
670 return xNode;