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 <sal/log.hxx>
21 
22 #include <oox/helper/attributelist.hxx>
23 #include <oox/ppt/pptshape.hxx>
24 #include <oox/ppt/pptshapecontext.hxx>
25 #include <oox/ppt/pptshapepropertiescontext.hxx>
26 #include <oox/ppt/slidepersist.hxx>
27 #include <drawingml/shapestylecontext.hxx>
28 #include <oox/drawingml/drawingmltypes.hxx>
29 #include <drawingml/textbodycontext.hxx>
30 #include <drawingml/transform2dcontext.hxx>
31 #include <oox/token/namespaces.hxx>
32 #include <oox/token/properties.hxx>
33 #include <oox/token/tokens.hxx>
34 
35 using namespace oox::core;
36 using namespace ::com::sun::star;
37 using namespace ::com::sun::star::uno;
38 using namespace ::com::sun::star::text;
39 
40 namespace oox::ppt {
41 
42 // CT_Shape
PPTShapeContext(ContextHandler2Helper const & rParent,const SlidePersistPtr & rSlidePersistPtr,const oox::drawingml::ShapePtr & pMasterShapePtr,const oox::drawingml::ShapePtr & pShapePtr)43 PPTShapeContext::PPTShapeContext( ContextHandler2Helper const & rParent, const SlidePersistPtr& rSlidePersistPtr, const oox::drawingml::ShapePtr& pMasterShapePtr, const oox::drawingml::ShapePtr& pShapePtr )
44 : oox::drawingml::ShapeContext( rParent, pMasterShapePtr, pShapePtr )
45 , mpSlidePersistPtr( rSlidePersistPtr )
46 {
47 }
48 
onCreateContext(sal_Int32 aElementToken,const AttributeList & rAttribs)49 ContextHandlerRef PPTShapeContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
50 {
51     if( getNamespace( aElementToken ) == NMSP_dsp )
52         aElementToken = NMSP_ppt | getBaseToken( aElementToken );
53 
54     switch( aElementToken )
55     {
56         // nvSpPr CT_ShapeNonVisual begin
57         //  case PPT_TOKEN( drElemPr ):
58         //      break;
59         case PPT_TOKEN( cNvPr ):
60         {
61             mpShapePtr->setHidden( rAttribs.getBool( XML_hidden, false ) );
62             mpShapePtr->setId( rAttribs.getString( XML_id ).get() );
63             mpShapePtr->setName( rAttribs.getString( XML_name ).get() );
64             break;
65         }
66         case PPT_TOKEN( ph ):
67         {
68             SlidePersistPtr pMasterPersist( mpSlidePersistPtr->getMasterPersist() );
69             OptValue< sal_Int32 > oSubType( rAttribs.getToken( XML_type) );
70             sal_Int32 nSubType( rAttribs.getToken( XML_type, XML_obj ) );
71             oox::drawingml::ShapePtr pTmpPlaceholder;
72 
73             mpShapePtr->setSubType( nSubType );
74 
75             if( rAttribs.hasAttribute( XML_idx ) )
76             {
77                 sal_Int32 nSubTypeIndex = rAttribs.getString( XML_idx ).get().toInt32();
78                 mpShapePtr->setSubTypeIndex( nSubTypeIndex );
79 
80                 if(!oSubType.has() && pMasterPersist)
81                 {
82                     pTmpPlaceholder = PPTShape::findPlaceholderByIndex( nSubTypeIndex, pMasterPersist->getShapes()->getChildren() );
83 
84                     if(pTmpPlaceholder)
85                         nSubType = pTmpPlaceholder->getSubType(); // When we don't have type attribute on slide but have on slidelayout we have to use it instead of default type
86                 }
87             }
88 
89             if ( nSubType )
90             {
91                 PPTShape* pPPTShapePtr = dynamic_cast< PPTShape* >( mpShapePtr.get() );
92                 if ( pPPTShapePtr )
93                 {
94                     oox::ppt::ShapeLocation eShapeLocation = pPPTShapePtr->getShapeLocation();
95                     if ( ( eShapeLocation == Slide ) || ( eShapeLocation == Layout ) )
96                     {
97                         // inheriting properties from placeholder objects by cloning shape
98                         sal_Int32 nFirstPlaceholder = 0;
99                         sal_Int32 nSecondPlaceholder = 0;
100                         switch( nSubType )
101                         {
102                             case XML_ctrTitle :     // slide/layout
103                                   nFirstPlaceholder = XML_ctrTitle;
104                                   nSecondPlaceholder = XML_title;
105                               break;
106 
107                               case XML_subTitle :       // slide/layout
108                                   nFirstPlaceholder = XML_subTitle;
109                                   nSecondPlaceholder = XML_body;
110                               break;
111 
112                              case XML_obj :         // slide/layout
113                                   nFirstPlaceholder = XML_obj;
114                                   nSecondPlaceholder = XML_body;
115                               break;
116 
117                             case XML_dt :           // slide/layout/master/notes/notesmaster/handoutmaster
118                               case XML_sldNum :     // slide/layout/master/notes/notesmaster/handoutmaster
119                               case XML_ftr :            // slide/layout/master/notes/notesmaster/handoutmaster
120                               case XML_hdr :            // notes/notesmaster/handoutmaster
121                               case XML_body :           // slide/layout/master/notes/notesmaster
122                               case XML_title :      // slide/layout/master/
123                               case XML_chart :      // slide/layout
124                               case XML_tbl :            // slide/layout
125                               case XML_clipArt :        // slide/layout
126                               case XML_dgm :            // slide/layout
127                               case XML_media :      // slide/layout
128                               case XML_sldImg :     // notes/notesmaster
129                               case XML_pic :            // slide/layout
130                                   nFirstPlaceholder = nSubType;
131                                   break;
132                               default:
133                                   break;
134                         }
135                         if ( nFirstPlaceholder )
136                           {
137                               oox::drawingml::ShapePtr pPlaceholder;
138                               if ( eShapeLocation == Layout )       // for layout objects the referenced object can be found within the same shape tree
139                               {
140                                   pPlaceholder = PPTShape::findPlaceholder( nFirstPlaceholder, nSecondPlaceholder,
141                                           pPPTShapePtr->getSubTypeIndex(), mpSlidePersistPtr->getShapes()->getChildren(), true );
142                               }
143                               else if ( eShapeLocation == Slide )   // normal slide shapes have to search within the corresponding master tree for referenced objects
144                               {
145                                   if ( pMasterPersist )
146                                   {
147                                       pPlaceholder = PPTShape::findPlaceholder( nFirstPlaceholder, nSecondPlaceholder,
148                                               pPPTShapePtr->getSubTypeIndex(), pMasterPersist->getShapes()->getChildren() );
149                                   }
150                               }
151                               if ( pPlaceholder )
152                               {
153                                   SAL_INFO("oox.ppt","shape " << mpShapePtr->getId() <<
154                                           " will get shape reference " << pPlaceholder->getId() << " applied");
155                                   mpShapePtr->applyShapeReference( *pPlaceholder );
156                                   PPTShape* pPPTShape = dynamic_cast< PPTShape* >( pPlaceholder.get() );
157                                   if ( pPPTShape )
158                                       pPPTShape->setReferenced( true );
159                                   pPPTShapePtr->setPlaceholder( pPlaceholder );
160                               }
161                           }
162                     }
163                   }
164 
165             }
166             break;
167         }
168 
169         // nvSpPr CT_ShapeNonVisual end
170 
171         case PPT_TOKEN( spPr ):
172             return new PPTShapePropertiesContext( *this, *mpShapePtr );
173 
174         case PPT_TOKEN( style ):
175             return new oox::drawingml::ShapeStyleContext( *this, *mpShapePtr );
176 
177         case PPT_TOKEN( txBody ):
178         {
179             oox::drawingml::TextBodyPtr xTextBody = std::make_shared<oox::drawingml::TextBody>( mpShapePtr->getTextBody() );
180             xTextBody->getTextProperties().maPropertyMap.setProperty( PROP_FontIndependentLineSpacing, true );
181             mpShapePtr->setTextBody( xTextBody );
182             return new oox::drawingml::TextBodyContext( *this, mpShapePtr );
183         }
184         case PPT_TOKEN( txXfrm ):
185         {
186             return new oox::drawingml::Transform2DContext( *this, rAttribs, *mpShapePtr, true );
187         }
188     }
189 
190     return this;
191 }
192 
193 }
194 
195 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
196