1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include <com/sun/star/xml/sax/FastToken.hpp>
25 #include <com/sun/star/drawing/LineStyle.hpp>
26 #include <com/sun/star/beans/XMultiPropertySet.hpp>
27 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
28 #include <com/sun/star/container/XNamed.hpp>
29 
30 #include "oox/helper/attributelist.hxx"
31 #include "oox/ppt/pptshape.hxx"
32 #include "oox/ppt/pptshapecontext.hxx"
33 #include "oox/ppt/pptshapepropertiescontext.hxx"
34 #include "oox/ppt/slidepersist.hxx"
35 #include "oox/drawingml/shapestylecontext.hxx"
36 #include "oox/drawingml/fillpropertiesgroupcontext.hxx"
37 #include "oox/drawingml/lineproperties.hxx"
38 #include "oox/drawingml/drawingmltypes.hxx"
39 #include "oox/drawingml/customshapegeometry.hxx"
40 #include "oox/drawingml/textbodycontext.hxx"
41 
42 using rtl::OUString;
43 using namespace oox::core;
44 using namespace ::com::sun::star;
45 using namespace ::com::sun::star::uno;
46 using namespace ::com::sun::star::drawing;
47 using namespace ::com::sun::star::beans;
48 using namespace ::com::sun::star::text;
49 using namespace ::com::sun::star::xml::sax;
50 
51 namespace oox { namespace ppt {
52 
53 // CT_Shape
PPTShapeContext(ContextHandler & rParent,const SlidePersistPtr pSlidePersistPtr,oox::drawingml::ShapePtr pMasterShapePtr,oox::drawingml::ShapePtr pShapePtr)54 PPTShapeContext::PPTShapeContext( ContextHandler& rParent, const SlidePersistPtr pSlidePersistPtr, oox::drawingml::ShapePtr pMasterShapePtr, oox::drawingml::ShapePtr pShapePtr )
55 : oox::drawingml::ShapeContext( rParent, pMasterShapePtr, pShapePtr )
56 , mpSlidePersistPtr( pSlidePersistPtr )
57 {
58 }
59 
findPlaceholder(const sal_Int32 nMasterPlaceholder,sal_Int32 nSubTypeIndex,std::vector<oox::drawingml::ShapePtr> & rShapes)60 oox::drawingml::ShapePtr findPlaceholder( const sal_Int32 nMasterPlaceholder, sal_Int32 nSubTypeIndex, std::vector< oox::drawingml::ShapePtr >& rShapes )
61 {
62 	oox::drawingml::ShapePtr aShapePtr;
63 	std::vector< oox::drawingml::ShapePtr >::reverse_iterator aRevIter( rShapes.rbegin() );
64 	while( aRevIter != rShapes.rend() )
65 	{
66 		if ( (*aRevIter)->getSubType() == nMasterPlaceholder )
67 		{
68 			if ( ( nSubTypeIndex == -1 ) || ( nSubTypeIndex == (*aRevIter)->getSubTypeIndex() ) )
69 			{
70 				aShapePtr = *aRevIter;
71 				break;
72 			}
73 		}
74         std::vector< oox::drawingml::ShapePtr >& rChildren = (*aRevIter)->getChildren();
75         aShapePtr = findPlaceholder( nMasterPlaceholder, nSubTypeIndex, rChildren );
76 		if ( aShapePtr.get() )
77 			break;
78 		aRevIter++;
79 	}
80 	return aShapePtr;
81 }
82 
83 // if nFirstPlaceholder can't be found, it will be searched for nSecondPlaceholder
findPlaceholder(sal_Int32 nFirstPlaceholder,sal_Int32 nSecondPlaceholder,sal_Int32 nSubTypeIndex,std::vector<oox::drawingml::ShapePtr> & rShapes)84 oox::drawingml::ShapePtr findPlaceholder( sal_Int32 nFirstPlaceholder, sal_Int32 nSecondPlaceholder,
85 	sal_Int32 nSubTypeIndex, std::vector< oox::drawingml::ShapePtr >& rShapes )
86 {
87 	oox::drawingml::ShapePtr pPlaceholder = findPlaceholder( nFirstPlaceholder, nSubTypeIndex, rShapes );
88 	return !nSecondPlaceholder || pPlaceholder.get() ? pPlaceholder : findPlaceholder( nSecondPlaceholder, nSubTypeIndex, rShapes );
89 }
90 
createFastChildContext(sal_Int32 aElementToken,const Reference<XFastAttributeList> & xAttribs)91 Reference< XFastContextHandler > PPTShapeContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
92 {
93 	Reference< XFastContextHandler > xRet;
94 
95 	switch( aElementToken )
96 	{
97 		// nvSpPr CT_ShapeNonVisual begin
98 		//	case PPT_TOKEN( drElemPr ):
99 		//		break;
100 		case PPT_TOKEN( cNvPr ):
101 		{
102 			AttributeList aAttribs( xAttribs );
103 			mpShapePtr->setHidden( aAttribs.getBool( XML_hidden, false ) );
104 			mpShapePtr->setId( xAttribs->getOptionalValue( XML_id ) );
105 			mpShapePtr->setName( xAttribs->getOptionalValue( XML_name ) );
106 			break;
107 		}
108 		case PPT_TOKEN( ph ):
109 		{
110 			sal_Int32 nSubType( xAttribs->getOptionalValueToken( XML_type, XML_obj ) );
111 			mpShapePtr->setSubType( nSubType );
112 			mpShapePtr->setSubTypeIndex( xAttribs->getOptionalValue( XML_idx ).toInt32() );
113 			if ( nSubType )
114 			{
115 				PPTShape* pPPTShapePtr = dynamic_cast< PPTShape* >( mpShapePtr.get() );
116 				if ( pPPTShapePtr )
117 				{
118 					oox::ppt::ShapeLocation eShapeLocation = pPPTShapePtr->getShapeLocation();
119 					if ( ( eShapeLocation == Slide ) || ( eShapeLocation == Layout ) )
120 					{
121 						// inheriting properties from placeholder objects by cloning shape
122 						sal_Int32 nFirstPlaceholder = 0;
123 						sal_Int32 nSecondPlaceholder = 0;
124 						switch( nSubType )
125 						{
126 							case XML_ctrTitle :		// slide/layout
127 	  							nFirstPlaceholder = XML_ctrTitle;
128   								nSecondPlaceholder = XML_title;
129   							break;
130 
131 	  						case XML_subTitle :		// slide/layout
132 	  							nFirstPlaceholder = XML_subTitle;
133 	  							nSecondPlaceholder = XML_title;
134   							break;
135 
136 	 						case XML_obj :			// slide/layout
137 	  							nFirstPlaceholder = XML_obj;
138 	  							nSecondPlaceholder = XML_body;
139   							break;
140 
141 							case XML_dt :			// slide/layout/master/notes/notesmaster/handoutmaster
142 	  						case XML_sldNum :		// slide/layout/master/notes/notesmaster/handoutmaster
143 	  						case XML_ftr :			// slide/layout/master/notes/notesmaster/handoutmaster
144 	  						case XML_hdr :			// notes/notesmaster/handoutmaster
145 	  						case XML_body :			// slide/layout/master/notes/notesmaster
146 	  						case XML_title :		// slide/layout/master/
147 	  						case XML_chart :		// slide/layout
148 	  						case XML_tbl :			// slide/layout
149 	  						case XML_clipArt :		// slide/layout
150 	  						case XML_dgm :			// slide/layout
151 	  						case XML_media :		// slide/layout
152 	  						case XML_sldImg :		// notes/notesmaster
153 	  						case XML_pic :			// slide/layout
154 	  							nFirstPlaceholder = nSubType;
155 	  						default:
156 	  							break;
157 						}
158   						if ( nFirstPlaceholder )
159   						{
160   							oox::drawingml::ShapePtr pPlaceholder;
161   							if ( eShapeLocation == Layout )		// for layout objects the referenced object can be found within the same shape tree
162 								pPlaceholder = findPlaceholder( nFirstPlaceholder, nSecondPlaceholder, -1, mpSlidePersistPtr->getShapes()->getChildren() );
163   							else if ( eShapeLocation == Slide )	// normal slide shapes have to search within the corresponding master tree for referenced objects
164   							{
165   								SlidePersistPtr pMasterPersist( mpSlidePersistPtr->getMasterPersist() );
166   								if ( pMasterPersist.get() )
167 								{
168 									if ( mpSlidePersistPtr->isNotesPage() )
169 										pPlaceholder = findPlaceholder( nFirstPlaceholder, nSecondPlaceholder, -1, pMasterPersist->getShapes()->getChildren() );
170 									else
171 										pPlaceholder = findPlaceholder( nFirstPlaceholder, nSecondPlaceholder,
172 										pPPTShapePtr->getSubTypeIndex(), pMasterPersist->getShapes()->getChildren() );
173 								}
174   							}
175   							if ( pPlaceholder.get() )
176   							{
177   								mpShapePtr->applyShapeReference( *pPlaceholder.get() );
178   								PPTShape* pPPTShape = dynamic_cast< PPTShape* >( pPlaceholder.get() );
179   								if ( pPPTShape )
180   									pPPTShape->setReferenced( sal_True );
181   							}
182   						}
183 					}
184   				}
185 
186   			}
187 	  		break;
188 		}
189 
190 		// nvSpPr CT_ShapeNonVisual end
191 
192 		case PPT_TOKEN( spPr ):
193 			xRet = new PPTShapePropertiesContext( *this, *mpShapePtr );
194 			break;
195 
196 		case PPT_TOKEN( style ):
197 			xRet = new oox::drawingml::ShapeStyleContext( *this, *mpShapePtr );
198 			break;
199 
200 		case PPT_TOKEN( txBody ):
201 		{
202 			oox::drawingml::TextBodyPtr xTextBody( new oox::drawingml::TextBody );
203 			xTextBody->getTextProperties().maPropertyMap[ PROP_FontIndependentLineSpacing ] <<= static_cast< sal_Bool >( sal_True );
204 			mpShapePtr->setTextBody( xTextBody );
205 			xRet = new oox::drawingml::TextBodyContext( *this, *xTextBody );
206 			break;
207 		}
208 	}
209 
210 	if( !xRet.is() )
211 		xRet.set( this );
212 
213 	return xRet;
214 }
215 
216 
217 } }
218