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 <oox/ppt/animationspersist.hxx>
21 
22 #include <rtl/ustring.hxx>
23 #include <sal/log.hxx>
24 #include <com/sun/star/uno/Any.hxx>
25 #include <com/sun/star/drawing/XShape.hpp>
26 #include <com/sun/star/text/XText.hpp>
27 #include <com/sun/star/presentation/ParagraphTarget.hpp>
28 #include <com/sun/star/presentation/ShapeAnimationSubType.hpp>
29 #include <com/sun/star/animations/Event.hpp>
30 #include <com/sun/star/animations/XAnimationNode.hpp>
31 
32 #include <oox/drawingml/shape.hxx>
33 #include <oox/helper/attributelist.hxx>
34 #include <oox/helper/addtosequence.hxx>
35 #include <oox/token/namespaces.hxx>
36 #include <oox/token/tokens.hxx>
37 
38 using namespace ::com::sun::star::uno;
39 using namespace ::com::sun::star::presentation;
40 using namespace ::com::sun::star::animations;
41 using namespace ::com::sun::star::drawing;
42 using namespace ::com::sun::star::text;
43 
44 namespace oox
45 {
46 
addToSequence(const Any & rOldValue,const Any & rNewValue)47 Any addToSequence( const Any& rOldValue, const Any& rNewValue )
48 {
49     if( !rNewValue.hasValue() )
50     {
51         return rOldValue;
52     }
53     else if( !rOldValue.hasValue() )
54     {
55         return rNewValue;
56     }
57     else
58     {
59         Sequence< Any > aNewSeq;
60         if( rOldValue >>= aNewSeq )
61         {
62             sal_Int32 nSize = aNewSeq.getLength();
63             aNewSeq.realloc(nSize+1);
64             aNewSeq[nSize] = rNewValue;
65         }
66         else
67         {
68             aNewSeq.realloc(2);
69             aNewSeq[0] = rOldValue;
70             aNewSeq[1] = rNewValue;
71         }
72         return makeAny( aNewSeq );
73     }
74 }
75 
76 } // namespace oox
77 
78 namespace oox { namespace ppt {
79 
convert(css::uno::Any & rTarget,sal_Int16 & rSubType) const80     void ShapeTargetElement::convert( css::uno::Any & rTarget, sal_Int16 & rSubType ) const
81     {
82         switch(mnType)
83         {
84         case XML_subSp:
85             rSubType = ShapeAnimationSubType::AS_WHOLE;
86             break;
87         case XML_bg:
88             rSubType = ShapeAnimationSubType::ONLY_BACKGROUND;
89             break;
90         case XML_txEl:
91         {
92             ParagraphTarget aParaTarget;
93             Reference< XShape > xShape;
94             rTarget >>= xShape;
95             aParaTarget.Shape = xShape;
96             rSubType = ShapeAnimationSubType::ONLY_TEXT;
97 
98             Reference< XText > xText( xShape, UNO_QUERY );
99             if( xText.is() )
100             {
101                 switch(mnRangeType)
102                 {
103                 case XML_charRg:
104                     // TODO calculate the corresponding paragraph for the text range...
105                     SAL_INFO("oox.ppt", "OOX: TODO calculate the corresponding paragraph for the text range..." );
106                     break;
107                 case XML_pRg:
108                     aParaTarget.Paragraph = static_cast< sal_Int16 >( maRange.start );
109                     // TODO what to do with more than one.
110                     SAL_INFO("oox.ppt", "OOX: TODO what to do with more than one" );
111                     break;
112                 }
113                 rTarget <<= aParaTarget;
114             }
115             break;
116         }
117         default:
118             break;
119         }
120     }
121 
convert(const SlidePersistPtr & pSlide,sal_Int16 & nSubType) const122     Any AnimTargetElement::convert(const SlidePersistPtr & pSlide, sal_Int16 & nSubType) const
123     {
124         Any aTarget;
125         // see sd/source/files/ppt/pptinanimations.cxx:3191 (in importTargetElementContainer())
126         switch(mnType)
127         {
128         case XML_inkTgt:
129             // TODO
130             SAL_INFO("oox.ppt", "OOX: TODO inkTgt" );
131             break;
132         case XML_sldTgt:
133             // TODO
134             SAL_INFO("oox.ppt", "OOX: TODO sldTgt" );
135             break;
136         case XML_sndTgt:
137             aTarget <<= msValue;
138             break;
139         case XML_spTgt:
140         {
141             OUString sShapeName = msValue;
142 
143             // bnc#705982 - catch referenced diagram fallback shapes
144             if( maShapeTarget.mnType == XML_dgm )
145                 sShapeName = maShapeTarget.msSubShapeId;
146 
147             Any rTarget;
148             ::oox::drawingml::ShapePtr pShape = pSlide->getShape( sShapeName );
149             SAL_WARN_IF( !pShape, "oox.ppt", "failed to locate Shape" );
150 
151             if( !pShape && maShapeTarget.mnType == XML_dgm )
152             {
153                 pShape = pSlide->getShape( msValue );
154             }
155 
156             if( pShape )
157             {
158                 Reference< XShape > xShape( pShape->getXShape() );
159                 SAL_WARN_IF( !xShape.is(), "oox.ppt", "fail to get XShape from shape" );
160                 if( xShape.is() )
161                 {
162                     rTarget <<= xShape;
163                     maShapeTarget.convert(rTarget, nSubType);
164                     aTarget = rTarget;
165                 }
166             }
167             break;
168         }
169         default:
170             break;
171         }
172         return aTarget;
173     }
174 
175     // Convert a time node condition to XAnimation.Begin or XAnimation.End
convert(const SlidePersistPtr & pSlide) const176     Any AnimationCondition::convert(const SlidePersistPtr & pSlide) const
177     {
178         Any aAny;
179         Event aEvent;
180         if(mpTarget && (maValue >>= aEvent))
181         {
182             sal_Int16 nSubType;
183             aAny = mpTarget->convert( pSlide, nSubType );
184             aEvent.Source = aAny;
185             aAny <<= aEvent;
186         }
187         else if (mnType == PPT_TOKEN(tn) && (maValue >>= aEvent))
188         {
189             OUString sId;
190             aEvent.Source >>= sId;
191             css::uno::Reference<XAnimationNode> xNode = pSlide->getAnimationNode(sId);
192             if (xNode.is())
193             {
194                 aEvent.Source <<= xNode;
195             }
196             else
197                 aEvent.Source.clear();
198             aAny <<= aEvent;
199         }
200         else
201         {
202             aAny = maValue;
203         }
204         return aAny;
205     }
206 
convertList(const SlidePersistPtr & pSlide,const AnimationConditionList & l)207     Any AnimationCondition::convertList(const SlidePersistPtr & pSlide, const AnimationConditionList & l)
208     {
209         Any aAny;
210 
211         if (l.size() == 1)
212             return l[0].convert(pSlide);
213 
214         for (auto const& elem : l)
215         {
216             aAny = addToSequence( aAny, elem.convert(pSlide) );
217         }
218         return aAny;
219     }
220 
221 } }
222 
223 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
224