diff options
author | Marcos Paulo de Souza <marcos.souza.org@gmail.com> | 2014-02-28 02:22:12 -0300 |
---|---|---|
committer | Matúš Kukan <matus.kukan@collabora.com> | 2014-03-10 09:15:54 +0100 |
commit | b8183958e6b5367eeebd5d07fa5f26561fa1dc4a (patch) | |
tree | 09260dc7a6255394f5eb4f31d84c8027d7f519ca /slideshow | |
parent | 1349f49a72be947aa708e7bcbc7de773894c5684 (diff) |
fdo#60698: Split out slideshow code from animations
Also remove the TargetPropertiesCreator service since just slideshow uses this.
Change-Id: I80816f6225b7bd9fb18f48e69eb5dfd6709b6e56
Diffstat (limited to 'slideshow')
-rw-r--r-- | slideshow/Library_slideshow.mk | 1 | ||||
-rw-r--r-- | slideshow/inc/pch/precompiled_slideshow.hxx | 1 | ||||
-rw-r--r-- | slideshow/source/engine/animationnodes/animationnodefactory.cxx | 9 | ||||
-rw-r--r-- | slideshow/source/engine/slide/slideimpl.cxx | 44 | ||||
-rw-r--r-- | slideshow/source/engine/slide/targetpropertiescreator.cxx | 365 | ||||
-rw-r--r-- | slideshow/source/engine/slide/targetpropertiescreator.hxx | 47 | ||||
-rw-r--r-- | slideshow/source/inc/tools.hxx | 54 |
7 files changed, 471 insertions, 50 deletions
diff --git a/slideshow/Library_slideshow.mk b/slideshow/Library_slideshow.mk index 49c0c1754260..fb5e93deb3f6 100644 --- a/slideshow/Library_slideshow.mk +++ b/slideshow/Library_slideshow.mk @@ -108,6 +108,7 @@ $(eval $(call gb_Library_add_exception_objects,slideshow,\ slideshow/source/engine/slideshowimpl \ slideshow/source/engine/slide/slideanimations \ slideshow/source/engine/slide/slideimpl \ + slideshow/source/engine/slide/targetpropertiescreator \ slideshow/source/engine/slide/userpaintoverlay \ slideshow/source/engine/slideview \ slideshow/source/engine/smilfunctionparser \ diff --git a/slideshow/inc/pch/precompiled_slideshow.hxx b/slideshow/inc/pch/precompiled_slideshow.hxx index 2a4ec7b0aac3..d755e3ddc4ec 100644 --- a/slideshow/inc/pch/precompiled_slideshow.hxx +++ b/slideshow/inc/pch/precompiled_slideshow.hxx @@ -78,7 +78,6 @@ #include <com/sun/star/animations/XAnimationNodeSupplier.hpp> #include <com/sun/star/animations/XAudio.hpp> #include <com/sun/star/animations/XIterateContainer.hpp> -#include <com/sun/star/animations/XTargetPropertiesCreator.hpp> #include <com/sun/star/animations/XTransitionFilter.hpp> #include <com/sun/star/awt/FontSlant.hpp> #include <com/sun/star/awt/FontUnderline.hpp> diff --git a/slideshow/source/engine/animationnodes/animationnodefactory.cxx b/slideshow/source/engine/animationnodes/animationnodefactory.cxx index 311cd05f7d57..15f9e079edbf 100644 --- a/slideshow/source/engine/animationnodes/animationnodefactory.cxx +++ b/slideshow/source/engine/animationnodes/animationnodefactory.cxx @@ -38,7 +38,6 @@ #include <com/sun/star/animations/XAudio.hpp> #include <com/sun/star/presentation/ParagraphTarget.hpp> #include <com/sun/star/beans/XPropertySet.hpp> -#include <animations/animationnodehelper.hxx> #include <basegfx/numeric/ftools.hxx> #include "animationnodefactory.hxx" @@ -309,8 +308,7 @@ bool implCreateIteratedNodes( // ONLY_TEXT, if a paragraph is referenced as the // master of an iteration effect. NodeCreator aCreator( rParent, aContext ); - if( !::anim::for_each_childNode( xNode, - aCreator ) ) + if( !for_each_childNode( xNode, aCreator ) ) { ENSURE_OR_RETURN_FALSE( false, @@ -431,8 +429,7 @@ bool implCreateIteratedNodes( } CloningNodeCreator aCreator( rParent, aContext ); - if( !::anim::for_each_childNode( xNode, - aCreator ) ) + if( !for_each_childNode( xNode, aCreator ) ) { ENSURE_OR_RETURN_FALSE( false, "implCreateIteratedNodes(): " @@ -565,7 +562,7 @@ BaseNodeSharedPtr implCreateAnimationNode( { // no iterate subset node, just plain child generation now NodeCreator aCreator( pCreatedContainer, rContext ); - if( !::anim::for_each_childNode( xNode, aCreator ) ) + if( !for_each_childNode( xNode, aCreator ) ) { OSL_FAIL( "implCreateAnimationNode(): " "child node creation failed" ); diff --git a/slideshow/source/engine/slide/slideimpl.cxx b/slideshow/source/engine/slide/slideimpl.cxx index 1ba3723d2459..08ccce20a810 100644 --- a/slideshow/source/engine/slide/slideimpl.cxx +++ b/slideshow/source/engine/slide/slideimpl.cxx @@ -39,11 +39,8 @@ #include <com/sun/star/presentation/ParagraphTarget.hpp> #include <com/sun/star/presentation/EffectNodeType.hpp> #include <com/sun/star/animations/XAnimationNodeSupplier.hpp> -#include <com/sun/star/animations/XTargetPropertiesCreator.hpp> #include <com/sun/star/drawing/TextAnimationKind.hpp> -#include <animations/animationnodehelper.hxx> - #include <cppuhelper/exc_hlp.hxx> #include <comphelper/anytostring.hxx> @@ -62,6 +59,7 @@ #include "usereventqueue.hxx" #include "userpaintoverlay.hxx" #include "event.hxx" +#include "targetpropertiescreator.hxx" #include "tools.hxx" #include <o3tl/compat_functional.hxx> @@ -849,7 +847,7 @@ bool SlideImpl::implPrefetchShow() // don't block nextEvent() from issuing the next // slide) MainSequenceSearcher aSearcher; - if( ::anim::for_each_childNode( mxRootNode, aSearcher ) ) + if( for_each_childNode( mxRootNode, aSearcher ) ) mbMainSequenceFound = aSearcher.getMainSequence().is(); // import successfully done @@ -966,44 +964,8 @@ bool SlideImpl::applyInitialShapeAttributes( // succeeded } - uno::Reference< animations::XTargetPropertiesCreator > xPropsCreator; - - try - { - ENSURE_OR_RETURN_FALSE( maContext.mxComponentContext.is(), - "SlideImpl::applyInitialShapeAttributes(): Invalid component context" ); - - uno::Reference<lang::XMultiComponentFactory> xFac( - maContext.mxComponentContext->getServiceManager() ); - - xPropsCreator.set( - xFac->createInstanceWithContext( - OUString( - "com.sun.star.animations.TargetPropertiesCreator"), - maContext.mxComponentContext ), - uno::UNO_QUERY_THROW ); - } - catch( uno::RuntimeException& ) - { - throw; - } - catch( uno::Exception& ) - { - OSL_FAIL( - OUStringToOString( - comphelper::anyToString(cppu::getCaughtException()), - RTL_TEXTENCODING_UTF8).getStr() ); - - // could not determine initial shape attributes - this - // is an error, as some effects might then be plainly - // invisible - ENSURE_OR_RETURN_FALSE( false, - "SlideImpl::applyInitialShapeAttributes(): " - "couldn't create TargetPropertiesCreator." ); - } - uno::Sequence< animations::TargetProperties > aProps( - xPropsCreator->createInitialTargetProperties( xRootAnimationNode ) ); + TargetPropertiesCreator::createInitialTargetProperties( xRootAnimationNode ) ); // apply extracted values to our shapes const ::std::size_t nSize( aProps.getLength() ); diff --git a/slideshow/source/engine/slide/targetpropertiescreator.cxx b/slideshow/source/engine/slide/targetpropertiescreator.cxx new file mode 100644 index 000000000000..5902c2980a27 --- /dev/null +++ b/slideshow/source/engine/slide/targetpropertiescreator.cxx @@ -0,0 +1,365 @@ +/* -*- 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 <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/animations/XIterateContainer.hpp> +#include <com/sun/star/presentation/ParagraphTarget.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> +#include <com/sun/star/drawing/XShape.hpp> +#include <com/sun/star/animations/AnimationNodeType.hpp> +#include <com/sun/star/animations/XAnimate.hpp> + +#include <boost/unordered_map.hpp> +#include <vector> + +#include "targetpropertiescreator.hxx" +#include "tools.hxx" + +namespace slideshow +{ +namespace internal +{ + namespace + { + // Vector containing all properties for a given shape + typedef ::std::vector< beans::NamedValue > VectorOfNamedValues; + + /** The hash map key + + This key contains both XShape reference and a paragraph + index, as we somehow have to handle shape and paragraph + targets with the same data structure. + */ + struct ShapeHashKey + { + /// Shape target + uno::Reference< drawing::XShape > mxRef; + + /** Paragraph index. + + If this is a pure shape target, mnParagraphIndex is + set to -1. + */ + sal_Int16 mnParagraphIndex; + + /// Comparison needed for boost::unordered_map + bool operator==( const ShapeHashKey& rRHS ) const + { + return mxRef == rRHS.mxRef && mnParagraphIndex == rRHS.mnParagraphIndex; + } + }; + + // A hash functor for ShapeHashKey objects + struct ShapeKeyHasher + { + ::std::size_t operator()( const ShapeHashKey& rKey ) const + { + // TODO(P2): Maybe a better hash function would be to + // spread mnParagraphIndex to 32 bit: a0b0c0d0e0... Hakmem + // should have a formula. + + // Yes it has: + // x = (x & 0x0000FF00) << 8) | (x >> 8) & 0x0000FF00 | x & 0xFF0000FF; + // x = (x & 0x00F000F0) << 4) | (x >> 4) & 0x00F000F0 | x & 0xF00FF00F; + // x = (x & 0x0C0C0C0C) << 2) | (x >> 2) & 0x0C0C0C0C | x & 0xC3C3C3C3; + // x = (x & 0x22222222) << 1) | (x >> 1) & 0x22222222 | x & 0x99999999; + + // Costs about 17 cycles on a RISC machine with infinite + // instruction level parallelism (~42 basic + // instructions). Thus I truly doubt this pays off... + return reinterpret_cast< ::std::size_t >(rKey.mxRef.get()) ^ (rKey.mnParagraphIndex << 16L); + } + }; + + // A hash map which maps a XShape to the corresponding vector of initial properties + typedef ::boost::unordered_map< ShapeHashKey, VectorOfNamedValues, ShapeKeyHasher > XShapeHash; + + + class NodeFunctor + { + public: + explicit NodeFunctor( XShapeHash& rShapeHash ) : + mrShapeHash( rShapeHash ), + mxTargetShape(), + mnParagraphIndex( -1 ) + { + } + + NodeFunctor( XShapeHash& rShapeHash, + const uno::Reference< drawing::XShape >& rTargetShape, + sal_Int16 nParagraphIndex ) : + mrShapeHash( rShapeHash ), + mxTargetShape( rTargetShape ), + mnParagraphIndex( nParagraphIndex ) + { + } + + void operator()( const uno::Reference< animations::XAnimationNode >& xNode ) const + { + if( !xNode.is() ) + { + OSL_FAIL( "AnimCore: NodeFunctor::operator(): invalid XAnimationNode" ); + return; + } + + uno::Reference< drawing::XShape > xTargetShape( mxTargetShape ); + sal_Int16 nParagraphIndex( mnParagraphIndex ); + + switch( xNode->getType() ) + { + case animations::AnimationNodeType::ITERATE: + { + // extract target shape from iterate node + // (will override the target for all children) + + uno::Reference< animations::XIterateContainer > xIterNode( xNode, + uno::UNO_QUERY ); + + // TODO(E1): I'm not too sure what to expect here... + if( !xIterNode->getTarget().hasValue() ) + { + OSL_FAIL( "animcore: NodeFunctor::operator(): no target on ITERATE node" ); + return; + } + + xTargetShape.set( xIterNode->getTarget(), + uno::UNO_QUERY ); + + if( !xTargetShape.is() ) + { + ::com::sun::star::presentation::ParagraphTarget aTarget; + + // no shape provided. Maybe a ParagraphTarget? + if( !(xIterNode->getTarget() >>= aTarget) ) + { + OSL_FAIL( "animcore: NodeFunctor::operator(): could not extract any " + "target information" ); + return; + } + + xTargetShape = aTarget.Shape; + nParagraphIndex = aTarget.Paragraph; + + if( !xTargetShape.is() ) + { + OSL_FAIL( "animcore: NodeFunctor::operator(): invalid shape in ParagraphTarget" ); + return; + } + } + } + // FALLTHROUGH intended + case animations::AnimationNodeType::PAR: + // FALLTHROUGH intended + case animations::AnimationNodeType::SEQ: + { + NodeFunctor aFunctor( mrShapeHash, + xTargetShape, + nParagraphIndex ); + if( !for_each_childNode( xNode, aFunctor ) ) + { + OSL_FAIL( "AnimCore: NodeFunctor::operator(): child node iteration failed, " + "or extraneous container nodes encountered" ); + } + } + break; + + case animations::AnimationNodeType::CUSTOM: + // FALLTHROUGH intended + case animations::AnimationNodeType::ANIMATE: + // FALLTHROUGH intended + case animations::AnimationNodeType::ANIMATEMOTION: + // FALLTHROUGH intended + case animations::AnimationNodeType::ANIMATECOLOR: + // FALLTHROUGH intended + case animations::AnimationNodeType::ANIMATETRANSFORM: + // FALLTHROUGH intended + case animations::AnimationNodeType::TRANSITIONFILTER: + // FALLTHROUGH intended + case animations::AnimationNodeType::AUDIO: + // FALLTHROUGH intended + /*default: + // ignore this node, no valuable content for now. + break;*/ + + case animations::AnimationNodeType::SET: + { + // evaluate set node content + uno::Reference< animations::XAnimate > xAnimateNode( xNode, + uno::UNO_QUERY ); + + if( !xAnimateNode.is() ) + break; // invalid node + + // determine target shape (if any) + ShapeHashKey aTarget; + if( xTargetShape.is() ) + { + // override target shape with parent-supplied + aTarget.mxRef = xTargetShape; + aTarget.mnParagraphIndex = nParagraphIndex; + } + else + { + // no parent-supplied target, retrieve + // node target + if( (xAnimateNode->getTarget() >>= aTarget.mxRef) ) + { + // pure shape target - set paragraph + // index to magic + aTarget.mnParagraphIndex = -1; + } + else + { + // not a pure shape target - maybe a + // ParagraphTarget? + presentation::ParagraphTarget aUnoTarget; + + if( !(xAnimateNode->getTarget() >>= aUnoTarget) ) + { + OSL_FAIL( "AnimCore: NodeFunctor::operator(): unknown target type encountered" ); + break; + } + + aTarget.mxRef = aUnoTarget.Shape; + aTarget.mnParagraphIndex = aUnoTarget.Paragraph; + } + } + + if( !aTarget.mxRef.is() ) + { + OSL_FAIL( "AnimCore: NodeFunctor::operator(): Found target, but XShape is NULL" ); + break; // invalid target XShape + } + + // check whether we already have an entry for + // this target (we only take the first set + // effect for every shape) + XShapeHash::const_iterator aIter; + if( (aIter=mrShapeHash.find( aTarget )) != mrShapeHash.end() ) + break; // already an entry in existence for given XShape + + // if this is an appear effect, hide shape + // initially. This is currently the only place + // where a shape effect influences shape + // attributes outside it's effective duration. + sal_Bool bVisible( sal_False ); + if( xAnimateNode->getAttributeName().equalsIgnoreAsciiCase("visibility") ) + { + + uno::Any aAny( xAnimateNode->getTo() ); + + // try to extract bool value + if( !(aAny >>= bVisible) ) + { + // try to extract string + OUString aString; + if( (aAny >>= aString) ) + { + // we also take the strings "true" and "false", + // as well as "on" and "off" here + if( aString.equalsIgnoreAsciiCase("true") || + aString.equalsIgnoreAsciiCase("on") ) + { + bVisible = sal_True; + } + if( aString.equalsIgnoreAsciiCase("false") || + aString.equalsIgnoreAsciiCase("off") ) + { + bVisible = sal_False; + } + } + } + } + // target is set the 'visible' value, + // so we should record the opposite value + mrShapeHash.insert( + XShapeHash::value_type( + aTarget, + VectorOfNamedValues( + 1, + beans::NamedValue( + //xAnimateNode->getAttributeName(), + OUString("visibility"), + uno::makeAny( !bVisible ) ) ) ) ); + break; + } + } + } + + private: + XShapeHash& mrShapeHash; + uno::Reference< drawing::XShape > mxTargetShape; + sal_Int16 mnParagraphIndex; + }; + } + + uno::Sequence< animations::TargetProperties > SAL_CALL TargetPropertiesCreator::createInitialTargetProperties + ( + const uno::Reference< animations::XAnimationNode >& xRootNode + ) //throw (uno::RuntimeException, std::exception) + { + // scan all nodes for visibility changes, and record first + // 'visibility=true' for each shape + XShapeHash aShapeHash( 101 ); + + NodeFunctor aFunctor( aShapeHash ); + + // TODO(F1): Maybe limit functor application to main sequence + // alone (CL said something that shape visibility is only + // affected by effects in the main sequence for PPT). + + // OTOH, client code can pass us only the main sequence (which + // it actually does right now, for the slideshow implementation). + aFunctor( xRootNode ); + + // output to result sequence + uno::Sequence< animations::TargetProperties > aRes( aShapeHash.size() ); + + ::std::size_t nCurrIndex(0); + XShapeHash::const_iterator aCurr( aShapeHash.begin() ); + const XShapeHash::const_iterator aEnd ( aShapeHash.end() ); + while( aCurr != aEnd ) + { + animations::TargetProperties& rCurrProps( aRes[ nCurrIndex++ ] ); + + if( aCurr->first.mnParagraphIndex == -1 ) + { + rCurrProps.Target = uno::makeAny( aCurr->first.mxRef ); + } + else + { + rCurrProps.Target = uno::makeAny( + presentation::ParagraphTarget( + aCurr->first.mxRef, + aCurr->first.mnParagraphIndex ) ); + } + + rCurrProps.Properties = ::comphelper::containerToSequence( aCurr->second ); + + ++aCurr; + } + + return aRes; + } + +} // namespace internal +} // namespace slideshow + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/slide/targetpropertiescreator.hxx b/slideshow/source/engine/slide/targetpropertiescreator.hxx new file mode 100644 index 000000000000..6c6bef6fad4c --- /dev/null +++ b/slideshow/source/engine/slide/targetpropertiescreator.hxx @@ -0,0 +1,47 @@ +/* -*- 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 <com/sun/star/animations/TargetProperties.hpp> + +#include <comphelper/broadcasthelper.hxx> +#include <cppuhelper/factory.hxx> +#include <cppuhelper/implementationentry.hxx> +#include <comphelper/sequence.hxx> + +using namespace ::com::sun::star; + +namespace slideshow +{ + namespace internal + { + class TargetPropertiesCreator : public ::comphelper::OBaseMutex + { + public: + static uno::Sequence< animations::TargetProperties > SAL_CALL createInitialTargetProperties( const uno::Reference< animations::XAnimationNode >& rootNode ); + + private: + // default: disabled copy/assignment + TargetPropertiesCreator(const TargetPropertiesCreator&); + TargetPropertiesCreator& operator=( const TargetPropertiesCreator& ); + }; + + } // namespace internal +} // namespace slideshow + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/tools.hxx b/slideshow/source/inc/tools.hxx index d9b82d4a6c0d..66f851bdfdb5 100644 --- a/slideshow/source/inc/tools.hxx +++ b/slideshow/source/inc/tools.hxx @@ -22,6 +22,12 @@ #include <com/sun/star/uno/Sequence.hxx> #include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/animations/XAnimationNode.hpp> +#include <com/sun/star/container/XEnumerationAccess.hpp> +#include <com/sun/star/container/XEnumeration.hpp> + +#include <vector> #include <cppcanvas/color.hxx> @@ -38,8 +44,6 @@ #include <string.h> #include <algorithm> - - namespace com { namespace sun { namespace star { namespace beans { struct NamedValue; } } } } @@ -388,6 +392,52 @@ namespace slideshow basegfx::B2IVector getSlideSizePixel( const basegfx::B2DVector& rSize, const boost::shared_ptr<UnoView>& pView ); } + + // TODO(Q1): this could possibly be implemented with a somewhat + // more lightweight template, by having the actual worker receive + // only a function pointer, and a thin templated wrapper around + // that which converts member functions into that. + + /** Apply given functor to every animation node child. + + @param xNode + Parent node + + @param rFunctor + Functor to apply. The functor must have an appropriate + operator()( const ::com::sun::star::uno::Reference< + ::com::sun::star::animations::XAnimationNode >& ) member. + + @return true, if the functor was successfully applied to + all children, false otherwise. + */ + template< typename Functor > inline bool for_each_childNode( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode, + Functor& rFunctor ) + { + try + { + // get an XEnumerationAccess to the children + ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumerationAccess > + xEnumerationAccess( xNode, + ::com::sun::star::uno::UNO_QUERY_THROW ); + ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration > + xEnumeration( xEnumerationAccess->createEnumeration(), + ::com::sun::star::uno::UNO_QUERY_THROW ); + + while( xEnumeration->hasMoreElements() ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode > + xChildNode( xEnumeration->nextElement(), + ::com::sun::star::uno::UNO_QUERY_THROW ); + rFunctor( xChildNode ); + } + return true; + } + catch( ::com::sun::star::uno::Exception& ) + { + return false; + } + } } #endif /* INCLUDED_SLIDESHOW_TOOLS_HXX */ |