summaryrefslogtreecommitdiff
path: root/slideshow/source/engine/slide
diff options
context:
space:
mode:
Diffstat (limited to 'slideshow/source/engine/slide')
-rw-r--r--slideshow/source/engine/slide/slideimpl.cxx44
-rw-r--r--slideshow/source/engine/slide/targetpropertiescreator.cxx365
-rw-r--r--slideshow/source/engine/slide/targetpropertiescreator.hxx47
3 files changed, 415 insertions, 41 deletions
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: */