Branch data Line data Source code
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/vml/vmlshape.hxx"
21 : :
22 : : #include <com/sun/star/beans/PropertyValues.hpp>
23 : : #include <com/sun/star/beans/XPropertySet.hpp>
24 : : #include <com/sun/star/awt/XControlModel.hpp>
25 : : #include <com/sun/star/drawing/PointSequenceSequence.hpp>
26 : : #include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
27 : : #include <com/sun/star/drawing/XShapes.hpp>
28 : : #include <com/sun/star/drawing/XControlShape.hpp>
29 : : #include <com/sun/star/graphic/XGraphic.hpp>
30 : : #include <com/sun/star/text/HoriOrientation.hpp>
31 : : #include <com/sun/star/text/RelOrientation.hpp>
32 : : #include <com/sun/star/text/SizeType.hpp>
33 : : #include <com/sun/star/text/VertOrientation.hpp>
34 : : #include <com/sun/star/text/XTextContent.hpp>
35 : : #include <com/sun/star/text/XTextDocument.hpp>
36 : : #include <com/sun/star/text/XTextFrame.hpp>
37 : : #include <com/sun/star/text/TextContentAnchorType.hpp>
38 : : #include <rtl/math.hxx>
39 : : #include <rtl/ustrbuf.hxx>
40 : : #include <rtl/oustringostreaminserter.hxx>
41 : : #include "oox/drawingml/shapepropertymap.hxx"
42 : : #include "oox/helper/graphichelper.hxx"
43 : : #include "oox/helper/propertyset.hxx"
44 : : #include "oox/ole/axcontrol.hxx"
45 : : #include "oox/ole/axcontrolfragment.hxx"
46 : : #include "oox/ole/oleobjecthelper.hxx"
47 : : #include "oox/vml/vmldrawing.hxx"
48 : : #include "oox/vml/vmlshapecontainer.hxx"
49 : : #include "oox/vml/vmltextbox.hxx"
50 : : #include "oox/core/xmlfilterbase.hxx"
51 : : #include "oox/helper/containerhelper.hxx"
52 : :
53 : : using ::com::sun::star::beans::XPropertySet;
54 : : using ::com::sun::star::uno::Any;
55 : :
56 : : using namespace ::com::sun::star;
57 : : using namespace ::com::sun::star::text;
58 : :
59 : : namespace oox {
60 : : namespace vml {
61 : :
62 : : // ============================================================================
63 : :
64 : : using namespace ::com::sun::star::awt;
65 : : using namespace ::com::sun::star::drawing;
66 : : using namespace ::com::sun::star::graphic;
67 : : using namespace ::com::sun::star::uno;
68 : : using namespace ::com::sun::star::io;
69 : :
70 : : using ::oox::core::XmlFilterBase;
71 : : using ::rtl::OUString;
72 : : using ::rtl::OUStringBuffer;
73 : :
74 : : // ============================================================================
75 : :
76 : : namespace {
77 : :
78 : : const sal_Int32 VML_SHAPETYPE_PICTUREFRAME = 75;
79 : : const sal_Int32 VML_SHAPETYPE_HOSTCONTROL = 201;
80 : :
81 : : // ----------------------------------------------------------------------------
82 : :
83 : 0 : Point lclGetAbsPoint( const Point& rRelPoint, const Rectangle& rShapeRect, const Rectangle& rCoordSys )
84 : : {
85 : 0 : double fWidthRatio = static_cast< double >( rShapeRect.Width ) / rCoordSys.Width;
86 : 0 : double fHeightRatio = static_cast< double >( rShapeRect.Height ) / rCoordSys.Height;
87 : 0 : Point aAbsPoint;
88 : 0 : aAbsPoint.X = static_cast< sal_Int32 >( rShapeRect.X + fWidthRatio * (rRelPoint.X - rCoordSys.X) + 0.5 );
89 : 0 : aAbsPoint.Y = static_cast< sal_Int32 >( rShapeRect.Y + fHeightRatio * (rRelPoint.Y - rCoordSys.Y) + 0.5 );
90 : 0 : return aAbsPoint;
91 : : }
92 : :
93 : 12 : Rectangle lclGetAbsRect( const Rectangle& rRelRect, const Rectangle& rShapeRect, const Rectangle& rCoordSys )
94 : : {
95 : 12 : double fWidthRatio = static_cast< double >( rShapeRect.Width ) / rCoordSys.Width;
96 : 12 : double fHeightRatio = static_cast< double >( rShapeRect.Height ) / rCoordSys.Height;
97 : 12 : Rectangle aAbsRect;
98 : 12 : aAbsRect.X = static_cast< sal_Int32 >( rShapeRect.X + fWidthRatio * (rRelRect.X - rCoordSys.X) + 0.5 );
99 : 12 : aAbsRect.Y = static_cast< sal_Int32 >( rShapeRect.Y + fHeightRatio * (rRelRect.Y - rCoordSys.Y) + 0.5 );
100 : 12 : aAbsRect.Width = static_cast< sal_Int32 >( fWidthRatio * rRelRect.Width + 0.5 );
101 : 12 : aAbsRect.Height = static_cast< sal_Int32 >( fHeightRatio * rRelRect.Height + 0.5 );
102 : 12 : return aAbsRect;
103 : : }
104 : :
105 : : } // namespace
106 : :
107 : : // ============================================================================
108 : :
109 : 87 : ShapeTypeModel::ShapeTypeModel():
110 : : mbAutoHeight( sal_False ),
111 [ + - ][ + - ]: 87 : mbVisible( sal_True )
[ + - ][ + - ]
112 : : {
113 : 87 : }
114 : :
115 : 27 : void ShapeTypeModel::assignUsed( const ShapeTypeModel& rSource )
116 : : {
117 : 27 : moShapeType.assignIfUsed( rSource.moShapeType );
118 : 27 : moCoordPos.assignIfUsed( rSource.moCoordPos );
119 : 27 : moCoordSize.assignIfUsed( rSource.moCoordSize );
120 : : /* The style properties position, left, top, width, height, margin-left,
121 : : margin-top are not derived from shape template to shape. */
122 : 27 : maStrokeModel.assignUsed( rSource.maStrokeModel );
123 : 27 : maFillModel.assignUsed( rSource.maFillModel );
124 : 27 : moGraphicPath.assignIfUsed( rSource.moGraphicPath );
125 : 27 : moGraphicTitle.assignIfUsed( rSource.moGraphicTitle );
126 : 27 : }
127 : :
128 : : // ----------------------------------------------------------------------------
129 : :
130 : 87 : ShapeType::ShapeType( Drawing& rDrawing ) :
131 : 87 : mrDrawing( rDrawing )
132 : : {
133 : 87 : }
134 : :
135 : 87 : ShapeType::~ShapeType()
136 : : {
137 [ - + ]: 117 : }
138 : :
139 : 36 : sal_Int32 ShapeType::getShapeType() const
140 : : {
141 : 36 : return maTypeModel.moShapeType.get( 0 );
142 : : }
143 : :
144 : 33 : OUString ShapeType::getGraphicPath() const
145 : : {
146 : 33 : return maTypeModel.moGraphicPath.get( OUString() );
147 : : }
148 : :
149 : 6 : Rectangle ShapeType::getCoordSystem() const
150 : : {
151 [ + - ]: 6 : Int32Pair aCoordPos = maTypeModel.moCoordPos.get( Int32Pair( 0, 0 ) );
152 [ + - ]: 6 : Int32Pair aCoordSize = maTypeModel.moCoordSize.get( Int32Pair( 1000, 1000 ) );
153 : 6 : return Rectangle( aCoordPos.first, aCoordPos.second, aCoordSize.first, aCoordSize.second );
154 : : }
155 : :
156 : 51 : Rectangle ShapeType::getRectangle( const ShapeParentAnchor* pParentAnchor ) const
157 : : {
158 : : return pParentAnchor ?
159 [ + + ][ # # ]: 63 : lclGetAbsRect( getRelRectangle(), pParentAnchor->maShapeRect, pParentAnchor->maCoordSys ) :
160 [ + + ][ + - ]: 114 : getAbsRectangle();
161 : : }
162 : :
163 : 39 : Rectangle ShapeType::getAbsRectangle() const
164 : : {
165 [ + - ]: 39 : const GraphicHelper& rGraphicHelper = mrDrawing.getFilter().getGraphicHelper();
166 : :
167 [ + - ]: 39 : sal_Int32 nWidth = ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maWidth, 0, true, true );
168 [ + + ]: 39 : if ( nWidth == 0 )
169 : 6 : nWidth = 1;
170 : :
171 [ + - ]: 39 : sal_Int32 nHeight = ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maHeight, 0, false, true );
172 [ + + ]: 39 : if ( nHeight == 0 )
173 : 3 : nHeight = 1;
174 : :
175 : : return Rectangle(
176 [ + - ][ + - ]: 39 : ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maLeft, 0, true, true ) + ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maMarginLeft, 0, true, true ),
177 [ + - ][ + - ]: 39 : ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maTop, 0, false, true ) + ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maMarginTop, 0, false, true ),
178 : 39 : nWidth, nHeight );
179 : : }
180 : :
181 : 12 : Rectangle ShapeType::getRelRectangle() const
182 : : {
183 : : return Rectangle(
184 : 12 : maTypeModel.maLeft.toInt32(),
185 : 12 : maTypeModel.maTop.toInt32(),
186 : 12 : maTypeModel.maWidth.toInt32(),
187 : 24 : maTypeModel.maHeight.toInt32() );
188 : : }
189 : :
190 : : // ============================================================================
191 : :
192 : 6 : ClientData::ClientData() :
193 : : mnObjType( XML_TOKEN_INVALID ),
194 : : mnTextHAlign( XML_Left ),
195 : : mnTextVAlign( XML_Top ),
196 : : mnCol( -1 ),
197 : : mnRow( -1 ),
198 : : mnChecked( VML_CLIENTDATA_UNCHECKED ),
199 : : mnDropStyle( XML_Combo ),
200 : : mnDropLines( 1 ),
201 : : mnVal( 0 ),
202 : : mnMin( 0 ),
203 : : mnMax( 0 ),
204 : : mnInc( 0 ),
205 : : mnPage( 0 ),
206 : : mnSelType( XML_Single ),
207 : : mnVTEdit( VML_CLIENTDATA_TEXT ),
208 : : mbPrintObject( true ),
209 : : mbVisible( false ),
210 : : mbDde( false ),
211 : : mbNo3D( false ),
212 : : mbNo3D2( false ),
213 : : mbMultiLine( false ),
214 : : mbVScroll( false ),
215 : 6 : mbSecretEdit( false )
216 : : {
217 : 6 : }
218 : :
219 : : // ----------------------------------------------------------------------------
220 : :
221 [ + - ]: 57 : ShapeModel::ShapeModel()
222 : : {
223 : 57 : }
224 : :
225 [ + - ]: 57 : ShapeModel::~ShapeModel()
226 : : {
227 : 57 : }
228 : :
229 : 27 : TextBox& ShapeModel::createTextBox()
230 : : {
231 [ + - ]: 27 : mxTextBox.reset( new TextBox );
232 : 27 : return *mxTextBox;
233 : : }
234 : :
235 : 6 : ClientData& ShapeModel::createClientData()
236 : : {
237 : 6 : mxClientData.reset( new ClientData );
238 : 6 : return *mxClientData;
239 : : }
240 : :
241 : : // ----------------------------------------------------------------------------
242 : :
243 : 57 : ShapeBase::ShapeBase( Drawing& rDrawing ) :
244 [ + - ]: 57 : ShapeType( rDrawing )
245 : : {
246 : 57 : }
247 : :
248 : 63 : void ShapeBase::finalizeFragmentImport()
249 : : {
250 : : // resolve shape template reference
251 [ + + ][ + + ]: 63 : if( (maShapeModel.maType.getLength() > 1) && (maShapeModel.maType[ 0 ] == '#') )
[ + + ]
252 [ + - ][ + + ]: 39 : if( const ShapeType* pShapeType = mrDrawing.getShapes().getShapeTypeById( maShapeModel.maType.copy( 1 ), true ) )
253 : 27 : maTypeModel.assignUsed( pShapeType->getTypeModel() );
254 : 63 : }
255 : :
256 : 24 : OUString ShapeBase::getShapeName() const
257 : : {
258 [ + + ]: 24 : if( !maTypeModel.maShapeName.isEmpty() )
259 : 6 : return maTypeModel.maShapeName;
260 : :
261 [ + - ]: 18 : OUString aBaseName = mrDrawing.getShapeBaseName( *this );
262 [ + + ]: 18 : if( !aBaseName.isEmpty() )
263 : : {
264 [ + - ]: 3 : sal_Int32 nShapeIdx = mrDrawing.getLocalShapeIndex( getShapeId() );
265 [ + - ]: 3 : if( nShapeIdx > 0 )
266 [ + - ][ + - ]: 3 : return OUStringBuffer( aBaseName ).append( sal_Unicode( ' ' ) ).append( nShapeIdx ).makeStringAndClear();
[ + - ][ + - ]
267 : : }
268 : :
269 : 24 : return OUString();
270 : : }
271 : :
272 : 18 : const ShapeType* ShapeBase::getChildTypeById( const OUString& ) const
273 : : {
274 : 18 : return 0;
275 : : }
276 : :
277 : 0 : const ShapeBase* ShapeBase::getChildById( const OUString& ) const
278 : : {
279 : 0 : return 0;
280 : : }
281 : :
282 : 57 : Reference< XShape > ShapeBase::convertAndInsert( const Reference< XShapes >& rxShapes, const ShapeParentAnchor* pParentAnchor ) const
283 : : {
284 : 57 : Reference< XShape > xShape;
285 [ + + ][ + - ]: 57 : if( mrDrawing.isShapeSupported( *this ) )
286 : : {
287 : : /* Calculate shape rectangle. Applications may do something special
288 : : according to some imported shape client data (e.g. Excel cell anchor). */
289 [ + - ]: 54 : Rectangle aShapeRect = calcShapeRectangle( pParentAnchor );
290 : :
291 : : // convert the shape, if the calculated rectangle is not empty
292 [ - + ][ # # ]: 54 : if( ((aShapeRect.Width > 0) || (aShapeRect.Height > 0)) && rxShapes.is() )
[ + - ][ + - ]
293 : : {
294 [ + - ][ + - ]: 54 : xShape = implConvertAndInsert( rxShapes, aShapeRect );
295 [ + + ]: 54 : if( xShape.is() )
296 : : {
297 : : // set imported or generated shape name (not supported by form controls)
298 [ + - ]: 48 : PropertySet aShapeProp( xShape );
299 [ + - ][ + + ]: 48 : if( aShapeProp.hasProperty( PROP_Name ) )
300 [ + - ][ + - ]: 21 : aShapeProp.setProperty( PROP_Name, getShapeName() );
301 [ + - ]: 48 : Reference< XControlShape > xControlShape( xShape, uno::UNO_QUERY );
302 [ + + ][ - + ]: 48 : if ( xControlShape.is() && !getTypeModel().mbVisible )
[ - + ]
303 : : {
304 [ # # ][ # # ]: 0 : PropertySet aControlShapeProp( xControlShape->getControl() );
[ # # ]
305 [ # # ][ # # ]: 0 : aControlShapeProp.setProperty( PROP_EnableVisible, uno::makeAny( sal_False ) );
[ # # ]
306 : : }
307 : : /* Notify the drawing that a new shape has been inserted. For
308 : : convenience, pass the rectangle that contains position and
309 : : size of the shape. */
310 : 48 : bool bGroupChild = pParentAnchor != 0;
311 [ + - ][ + - ]: 54 : mrDrawing.notifyXShapeInserted( xShape, aShapeRect, *this, bGroupChild );
312 : : }
313 : : }
314 : : }
315 : 57 : return xShape;
316 : : }
317 : :
318 : 3 : void ShapeBase::convertFormatting( const Reference< XShape >& rxShape, const ShapeParentAnchor* pParentAnchor ) const
319 : : {
320 [ + - ]: 3 : if( rxShape.is() )
321 : : {
322 : : /* Calculate shape rectangle. Applications may do something special
323 : : according to some imported shape client data (e.g. Excel cell anchor). */
324 [ + - ]: 3 : Rectangle aShapeRect = calcShapeRectangle( pParentAnchor );
325 : :
326 : : // convert the shape, if the calculated rectangle is not empty
327 [ - + ][ # # ]: 3 : if( (aShapeRect.Width > 0) || (aShapeRect.Height > 0) )
328 : : {
329 [ + - ][ + - ]: 3 : rxShape->setPosition( Point( aShapeRect.X, aShapeRect.Y ) );
330 [ + - ][ + - ]: 3 : rxShape->setSize( Size( aShapeRect.Width, aShapeRect.Height ) );
331 [ + - ]: 3 : convertShapeProperties( rxShape );
332 : : }
333 : : }
334 : 3 : }
335 : :
336 : : // protected ------------------------------------------------------------------
337 : :
338 : 57 : Rectangle ShapeBase::calcShapeRectangle( const ShapeParentAnchor* pParentAnchor ) const
339 : : {
340 : : /* Calculate shape rectangle. Applications may do something special
341 : : according to some imported shape client data (e.g. Excel cell anchor). */
342 : 57 : Rectangle aShapeRect;
343 : 57 : const ClientData* pClientData = getClientData();
344 [ - + ][ + + ]: 57 : if( !pClientData || !mrDrawing.convertClientAnchor( aShapeRect, pClientData->maAnchor ) )
[ + + ]
345 : 51 : aShapeRect = getRectangle( pParentAnchor );
346 : 57 : return aShapeRect;
347 : : }
348 : :
349 : 39 : void ShapeBase::convertShapeProperties( const Reference< XShape >& rxShape ) const
350 : : {
351 [ + - ][ + - ]: 39 : ::oox::drawingml::ShapePropertyMap aPropMap( mrDrawing.getFilter().getModelObjectHelper() );
352 [ + - ]: 39 : const GraphicHelper& rGraphicHelper = mrDrawing.getFilter().getGraphicHelper();
353 [ + - ]: 39 : maTypeModel.maStrokeModel.pushToPropMap( aPropMap, rGraphicHelper );
354 [ + - ]: 39 : maTypeModel.maFillModel.pushToPropMap( aPropMap, rGraphicHelper );
355 : :
356 : : // TextFrames have FillColor, not BackColor
357 [ + - ]: 39 : uno::Reference<lang::XServiceInfo> xSInfo(rxShape, uno::UNO_QUERY_THROW);
358 [ + - ][ + - ]: 39 : if (xSInfo->supportsService("com.sun.star.text.TextFrame") && aPropMap.hasProperty(PROP_FillColor))
[ + + ][ + - ]
[ + + ][ + - ]
[ + - ][ + +
# # # # ]
359 : : {
360 [ + - ][ + - ]: 15 : aPropMap.setProperty(PROP_BackColor, aPropMap[PROP_FillColor]);
361 [ + - ]: 15 : aPropMap.erase(PROP_FillColor);
362 : : }
363 : :
364 [ + - ][ + - ]: 39 : PropertySet( rxShape ).setProperties( aPropMap );
[ + - ]
365 : 39 : }
366 : :
367 : : // ============================================================================
368 : :
369 : 51 : SimpleShape::SimpleShape( Drawing& rDrawing, const OUString& rService ) :
370 : : ShapeBase( rDrawing ),
371 : 51 : maService( rService )
372 : : {
373 : 51 : }
374 : :
375 : 45 : void lcl_SetAnchorType(PropertySet& rPropSet, const ShapeTypeModel& rTypeModel)
376 : : {
377 [ + + ]: 45 : if ( rTypeModel.maPosition == "absolute" )
378 : : {
379 [ + + ][ + - ]: 39 : if (rTypeModel.moWrapAnchorX.get() == "page" && rTypeModel.moWrapAnchorY.get() == "page")
[ + + ]
380 : : {
381 : : // I'm not sure if AT_PAGE is always correct here (not sure what the parent that
382 : : // the spec talks about can be), but with Writer SwXDrawPage::add()
383 : : // always in practice uses this because of pDoc->GetCurrentLayout() being NULL at this point.
384 [ + - ]: 3 : rPropSet.setProperty(PROP_AnchorType, text::TextContentAnchorType_AT_PAGE);
385 : : }
386 : : else
387 : : // Map to as-character by default, that fixes vertical position of some textframes.
388 [ + - ]: 36 : rPropSet.setProperty(PROP_AnchorType, text::TextContentAnchorType_AT_CHARACTER);
389 : : }
390 [ - + ]: 6 : else if( rTypeModel.maPosition == "relative" )
391 : : { // I'm not very sure this is correct either.
392 [ # # ]: 0 : rPropSet.setProperty(PROP_AnchorType, text::TextContentAnchorType_AT_PARAGRAPH);
393 : : }
394 : : else // static (is the default) means anchored inline
395 : : {
396 [ + - ]: 6 : rPropSet.setProperty(PROP_AnchorType, text::TextContentAnchorType_AS_CHARACTER);
397 : : }
398 : 45 : }
399 : :
400 : 33 : Reference< XShape > SimpleShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
401 : : {
402 : 33 : Rectangle aShapeRect(rShapeRect);
403 [ + + ]: 33 : if (!maTypeModel.maFlip.isEmpty())
404 : : {
405 [ + - ]: 3 : if (maTypeModel.maFlip.equalsAscii("x"))
406 : : {
407 : 3 : aShapeRect.X += aShapeRect.Width;
408 : 3 : aShapeRect.Width *= -1;
409 : : }
410 [ # # ]: 0 : else if (maTypeModel.maFlip.equalsAscii("y"))
411 : : {
412 : 0 : aShapeRect.Y += aShapeRect.Height;
413 : 0 : aShapeRect.Height *= -1;
414 : : }
415 : : }
416 : :
417 [ + - ]: 33 : Reference< XShape > xShape = mrDrawing.createAndInsertXShape( maService, rxShapes, aShapeRect );
418 [ + - ]: 33 : convertShapeProperties( xShape );
419 : :
420 [ + + ]: 33 : if ( maService.equalsAscii( "com.sun.star.text.TextFrame" ) )
421 : : {
422 [ + - ][ + - ]: 24 : PropertySet( xShape ).setAnyProperty( PROP_FrameIsAutomaticHeight, makeAny( maTypeModel.mbAutoHeight ) );
[ + - ][ + - ]
423 [ + - ][ + - ]: 24 : PropertySet( xShape ).setAnyProperty( PROP_SizeType, makeAny( maTypeModel.mbAutoHeight ? SizeType::MIN : SizeType::FIX ) );
[ + - ][ + - ]
[ - + ]
424 [ + + ]: 24 : if (maTypeModel.maPositionHorizontal == "center")
425 [ + - ][ + - ]: 9 : PropertySet(xShape).setAnyProperty(PROP_HoriOrient, makeAny(text::HoriOrientation::CENTER));
[ + - ][ + - ]
426 : : }
427 : :
428 : : // Import Legacy Fragments (if any)
429 [ + - ][ - + ]: 33 : if( xShape.is() && !maShapeModel.maLegacyDiagramPath.isEmpty() )
[ - + ]
430 : : {
431 [ # # ][ # # ]: 0 : Reference< XInputStream > xInStrm( mrDrawing.getFilter().openInputStream( maShapeModel.maLegacyDiagramPath ), UNO_SET_THROW );
432 [ # # ]: 0 : if( xInStrm.is() )
433 [ # # ][ # # ]: 0 : PropertySet( xShape ).setProperty( PROP_LegacyFragment, xInStrm );
[ # # ]
434 : : }
435 : :
436 [ + - ]: 33 : PropertySet aPropertySet(xShape);
437 [ + - ][ + + ]: 33 : if (xShape.is() && !maTypeModel.maRotation.isEmpty())
[ + + ]
438 : : {
439 [ + - ][ + - ]: 3 : aPropertySet.setAnyProperty(PROP_RotateAngle, makeAny(maTypeModel.maRotation.toInt32() * 100));
440 : : // If rotation is used, simple setPosition() is not enough.
441 [ + - ][ + - ]: 3 : aPropertySet.setAnyProperty(PROP_HoriOrientPosition, makeAny( aShapeRect.X ) );
442 [ + - ][ + - ]: 3 : aPropertySet.setAnyProperty(PROP_VertOrientPosition, makeAny( aShapeRect.Y ) );
443 : : }
444 : :
445 [ + - ]: 33 : lcl_SetAnchorType(aPropertySet, maTypeModel);
446 : :
447 [ + - ]: 33 : return xShape;
448 : : }
449 : :
450 : : // ============================================================================
451 : :
452 : 12 : RectangleShape::RectangleShape( Drawing& rDrawing ) :
453 [ + - ]: 12 : SimpleShape( rDrawing, CREATE_OUSTRING( "com.sun.star.drawing.RectangleShape" ) )
454 : : {
455 : 12 : }
456 : :
457 : : // ============================================================================
458 : :
459 : 0 : EllipseShape::EllipseShape( Drawing& rDrawing ) :
460 [ # # ]: 0 : SimpleShape( rDrawing, CREATE_OUSTRING( "com.sun.star.drawing.EllipseShape" ) )
461 : : {
462 : 0 : }
463 : :
464 : : // ============================================================================
465 : :
466 : 0 : PolyLineShape::PolyLineShape( Drawing& rDrawing ) :
467 [ # # ]: 0 : SimpleShape( rDrawing, CREATE_OUSTRING( "com.sun.star.drawing.PolyLineShape" ) )
468 : : {
469 : 0 : }
470 : :
471 : 0 : Reference< XShape > PolyLineShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
472 : : {
473 [ # # ]: 0 : Reference< XShape > xShape = SimpleShape::implConvertAndInsert( rxShapes, rShapeRect );
474 : : // polygon path
475 [ # # ]: 0 : Rectangle aCoordSys = getCoordSystem();
476 [ # # ][ # # ]: 0 : if( !maShapeModel.maPoints.empty() && (aCoordSys.Width > 0) && (aCoordSys.Height > 0) )
[ # # ][ # # ]
477 : : {
478 [ # # ]: 0 : ::std::vector< Point > aAbsPoints;
479 [ # # ][ # # ]: 0 : for( ShapeModel::PointVector::const_iterator aIt = maShapeModel.maPoints.begin(), aEnd = maShapeModel.maPoints.end(); aIt != aEnd; ++aIt )
480 [ # # ]: 0 : aAbsPoints.push_back( lclGetAbsPoint( *aIt, rShapeRect, aCoordSys ) );
481 [ # # ]: 0 : PointSequenceSequence aPointSeq( 1 );
482 [ # # ][ # # ]: 0 : aPointSeq[ 0 ] = ContainerHelper::vectorToSequence( aAbsPoints );
[ # # ][ # # ]
483 [ # # ]: 0 : PropertySet aPropSet( xShape );
484 [ # # ][ # # ]: 0 : aPropSet.setProperty( PROP_PolyPolygon, aPointSeq );
[ # # ]
485 : : }
486 : 0 : return xShape;
487 : : }
488 : :
489 : 3 : LineShape::LineShape(Drawing& rDrawing)
490 [ + - ]: 3 : : SimpleShape(rDrawing, "com.sun.star.drawing.LineShape")
491 : : {
492 : 3 : }
493 : :
494 : 3 : Reference<XShape> LineShape::implConvertAndInsert(const Reference<XShapes>& rxShapes, const Rectangle& rShapeRect) const
495 : : {
496 [ + - ]: 3 : const GraphicHelper& rGraphicHelper = mrDrawing.getFilter().getGraphicHelper();
497 : 3 : Rectangle aShapeRect(rShapeRect);
498 : 3 : sal_Int32 nIndex = 0;
499 : :
500 [ + - ]: 3 : aShapeRect.X = ConversionHelper::decodeMeasureToHmm(rGraphicHelper, maShapeModel.maFrom.getToken(0, ',', nIndex), 0, true, true);
501 [ + - ]: 3 : aShapeRect.Y = ConversionHelper::decodeMeasureToHmm(rGraphicHelper, maShapeModel.maFrom.getToken(0, ',', nIndex), 0, false, true);
502 : 3 : nIndex = 0;
503 [ + - ]: 3 : aShapeRect.Width = ConversionHelper::decodeMeasureToHmm(rGraphicHelper, maShapeModel.maTo.getToken(0, ',', nIndex), 0, true, true) - aShapeRect.X;
504 [ + - ]: 3 : aShapeRect.Height = ConversionHelper::decodeMeasureToHmm(rGraphicHelper, maShapeModel.maTo.getToken(0, ',', nIndex), 0, false, true) - aShapeRect.Y;
505 : :
506 [ + - ]: 3 : return SimpleShape::implConvertAndInsert(rxShapes, aShapeRect);
507 : : }
508 : :
509 : : // ============================================================================
510 : :
511 : 36 : CustomShape::CustomShape( Drawing& rDrawing ) :
512 [ + - ]: 36 : SimpleShape( rDrawing, CREATE_OUSTRING( "com.sun.star.drawing.CustomShape" ) )
513 : : {
514 : 36 : }
515 : :
516 : 18 : Reference< XShape > CustomShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
517 : : {
518 : : // try to create a custom shape
519 : 18 : Reference< XShape > xShape = SimpleShape::implConvertAndInsert( rxShapes, rShapeRect );
520 [ + - ]: 18 : if( xShape.is() ) try
521 : : {
522 : : // create the custom shape geometry
523 [ + + ]: 18 : Reference< XEnhancedCustomShapeDefaulter > xDefaulter( xShape, UNO_QUERY_THROW );
524 [ + - ][ + - ]: 3 : xDefaulter->createCustomShapeDefaults( OUString::valueOf( getShapeType() ) );
[ + - ]
525 : : // convert common properties
526 [ - + ][ + - ]: 18 : convertShapeProperties( xShape );
527 : : }
528 [ + - ]: 15 : catch( Exception& )
529 : : {
530 : : }
531 : 18 : return xShape;
532 : : }
533 : :
534 : : // ============================================================================
535 : :
536 : 36 : ComplexShape::ComplexShape( Drawing& rDrawing ) :
537 : 36 : CustomShape( rDrawing )
538 : : {
539 : 36 : }
540 : :
541 : 33 : Reference< XShape > ComplexShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
542 : : {
543 : 33 : XmlFilterBase& rFilter = mrDrawing.getFilter();
544 [ + - ]: 33 : sal_Int32 nShapeType = getShapeType();
545 [ + - ]: 33 : OUString aGraphicPath = getGraphicPath();
546 : :
547 : : // try to find registered OLE object info
548 [ + - ][ - + ]: 33 : if( const OleObjectInfo* pOleObjectInfo = mrDrawing.getOleObjectInfo( maTypeModel.maShapeId ) )
549 : : {
550 : : OSL_ENSURE( nShapeType == VML_SHAPETYPE_PICTUREFRAME, "ComplexShape::implConvertAndInsert - unexpected shape type" );
551 : :
552 : : // if OLE object is embedded into a DrawingML shape (PPTX), do not create it here
553 [ # # ]: 0 : if( pOleObjectInfo->mbDmlShape )
554 : 0 : return Reference< XShape >();
555 : :
556 [ # # ]: 0 : PropertyMap aOleProps;
557 : 0 : Size aOleSize( rShapeRect.Width, rShapeRect.Height );
558 [ # # ][ # # ]: 0 : if( rFilter.getOleObjectHelper().importOleObject( aOleProps, *pOleObjectInfo, aOleSize ) )
[ # # ]
559 : : {
560 [ # # ][ # # ]: 0 : Reference< XShape > xShape = mrDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.OLE2Shape" ), rxShapes, rShapeRect );
561 [ # # ]: 0 : if( xShape.is() )
562 : : {
563 : : // set the replacement graphic
564 [ # # ]: 0 : if( !aGraphicPath.isEmpty() )
565 : : {
566 [ # # ][ # # ]: 0 : Reference< XGraphic > xGraphic = rFilter.getGraphicHelper().importEmbeddedGraphic( aGraphicPath );
567 [ # # ]: 0 : if( xGraphic.is() )
568 [ # # ][ # # ]: 0 : aOleProps[ PROP_Graphic ] <<= xGraphic;
569 : : }
570 : :
571 [ # # ]: 0 : PropertySet aPropSet( xShape );
572 [ # # ]: 0 : aPropSet.setProperties( aOleProps );
573 : :
574 [ # # ]: 0 : return xShape;
575 [ # # ]: 0 : }
576 [ # # ]: 0 : }
577 : : }
578 : :
579 : : // try to find registered form control info
580 [ + - ]: 33 : const ControlInfo* pControlInfo = mrDrawing.getControlInfo( maTypeModel.maShapeId );
581 [ - + ][ # # ]: 33 : if( pControlInfo && !pControlInfo->maFragmentPath.isEmpty() )
[ - + ]
582 : : {
583 : : OSL_ENSURE( nShapeType == VML_SHAPETYPE_HOSTCONTROL, "ComplexShape::implConvertAndInsert - unexpected shape type" );
584 [ # # ]: 0 : OUString aShapeName = getShapeName();
585 [ # # ]: 0 : if( !aShapeName.isEmpty() )
586 : : {
587 : : OSL_ENSURE( aShapeName == pControlInfo->maName, "ComplexShape::implConvertAndInsert - control name mismatch" );
588 : : // load the control properties from fragment
589 [ # # ]: 0 : ::oox::ole::EmbeddedControl aControl( aShapeName );
590 [ # # ][ # # ]: 0 : if( rFilter.importFragment( new ::oox::ole::AxControlFragment( rFilter, pControlInfo->maFragmentPath, aControl ) ) )
[ # # ]
591 : : {
592 : : // create and return the control shape (including control model)
593 : 0 : sal_Int32 nCtrlIndex = -1;
594 [ # # ]: 0 : Reference< XShape > xShape = mrDrawing.createAndInsertXControlShape( aControl, rxShapes, rShapeRect, nCtrlIndex );
595 : : // on error, proceed and try to create picture from replacement image
596 [ # # ]: 0 : if( xShape.is() )
597 [ # # ]: 0 : return xShape;
598 [ # # ][ # # ]: 0 : }
599 [ # # ]: 0 : }
600 : : }
601 : :
602 : : // host application wants to create the shape (do not try failed OLE controls again)
603 [ + + ][ + - ]: 33 : if( (nShapeType == VML_SHAPETYPE_HOSTCONTROL) && !pControlInfo )
604 : : {
605 : : OSL_ENSURE( getClientData(), "ComplexShape::implConvertAndInsert - missing client data" );
606 [ + - ]: 3 : Reference< XShape > xShape = mrDrawing.createAndInsertClientXShape( *this, rxShapes, rShapeRect );
607 [ + - ]: 3 : if( xShape.is() )
608 [ - + ]: 3 : return xShape;
609 : : }
610 : :
611 : : // try to create a picture object
612 [ + + ]: 30 : if( !aGraphicPath.isEmpty() )
613 : : {
614 [ + - ][ + - ]: 12 : Reference< XShape > xShape = mrDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.GraphicObjectShape" ), rxShapes, rShapeRect );
615 [ + - ]: 12 : if( xShape.is() )
616 : : {
617 [ + - ][ + - ]: 12 : OUString aGraphicUrl = rFilter.getGraphicHelper().importEmbeddedGraphicObject( aGraphicPath );
618 [ + - ]: 12 : PropertySet aPropSet( xShape );
619 [ + - ]: 12 : if( !aGraphicUrl.isEmpty() )
620 : : {
621 [ + - ]: 12 : aPropSet.setProperty( PROP_GraphicURL, aGraphicUrl );
622 : : }
623 : : // If the shape has an absolute position, set the properties accordingly.
624 [ + + ]: 12 : if ( maTypeModel.maPosition == "absolute" )
625 : : {
626 [ + - ]: 6 : aPropSet.setProperty(PROP_HoriOrientPosition, rShapeRect.X);
627 [ + - ]: 6 : aPropSet.setProperty(PROP_VertOrientPosition, rShapeRect.Y);
628 [ + - ]: 6 : aPropSet.setProperty(PROP_Opaque, sal_False);
629 : : }
630 : :
631 [ + - ]: 12 : lcl_SetAnchorType(aPropSet, maTypeModel);
632 : :
633 [ - + ]: 12 : if ( maTypeModel.maPositionVerticalRelative == "page" )
634 : : {
635 [ # # ]: 0 : aPropSet.setProperty(PROP_VertOrientRelation, text::RelOrientation::PAGE_FRAME);
636 [ + - ]: 12 : }
637 : : }
638 : 12 : return xShape;
639 : : }
640 : :
641 : : // default: try to create a custom shape
642 [ + - ]: 33 : return CustomShape::implConvertAndInsert( rxShapes, rShapeRect );
643 : : }
644 : :
645 : : // ============================================================================
646 : :
647 : 6 : GroupShape::GroupShape( Drawing& rDrawing ) :
648 : : ShapeBase( rDrawing ),
649 [ + - ][ + - ]: 6 : mxChildren( new ShapeContainer( rDrawing ) )
650 : : {
651 : 6 : }
652 : :
653 [ + - ]: 6 : GroupShape::~GroupShape()
654 : : {
655 [ - + ]: 12 : }
656 : :
657 : 9 : void GroupShape::finalizeFragmentImport()
658 : : {
659 : : // basic shape processing
660 : 9 : ShapeBase::finalizeFragmentImport();
661 : : // finalize all child shapes
662 : 9 : mxChildren->finalizeFragmentImport();
663 : 9 : }
664 : :
665 : 9 : const ShapeType* GroupShape::getChildTypeById( const OUString& rShapeId ) const
666 : : {
667 : 9 : return mxChildren->getShapeTypeById( rShapeId, true );
668 : : }
669 : :
670 : 0 : const ShapeBase* GroupShape::getChildById( const OUString& rShapeId ) const
671 : : {
672 : 0 : return mxChildren->getShapeById( rShapeId, true );
673 : : }
674 : :
675 : 6 : Reference< XShape > GroupShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
676 : : {
677 : 6 : Reference< XShape > xGroupShape;
678 : : // check that this shape contains children and a valid coordinate system
679 : 6 : ShapeParentAnchor aParentAnchor;
680 : 6 : aParentAnchor.maShapeRect = rShapeRect;
681 [ + - ]: 6 : aParentAnchor.maCoordSys = getCoordSystem();
682 [ + - ][ + - ]: 6 : if( !mxChildren->empty() && (aParentAnchor.maCoordSys.Width > 0) && (aParentAnchor.maCoordSys.Height > 0) ) try
[ + - ][ + - ]
683 : : {
684 [ + - ][ + - ]: 6 : xGroupShape = mrDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.GroupShape" ), rxShapes, rShapeRect );
[ + - ]
685 [ + - ]: 6 : Reference< XShapes > xChildShapes( xGroupShape, UNO_QUERY_THROW );
686 [ + - ]: 6 : mxChildren->convertAndInsert( xChildShapes, &aParentAnchor );
687 : : // no child shape has been created - delete the group shape
688 [ + - ][ + - ]: 6 : if( !xChildShapes->hasElements() )
[ + - ]
689 : : {
690 [ + - ][ + - ]: 6 : rxShapes->remove( xGroupShape );
691 : 6 : xGroupShape.clear();
692 [ # # ]: 6 : }
693 : : }
694 [ # # ]: 0 : catch( Exception& )
695 : : {
696 : : }
697 : 6 : return xGroupShape;
698 : : }
699 : :
700 : : // ============================================================================
701 : :
702 : : } // namespace vml
703 [ + - ][ + - ]: 285 : } // namespace oox
704 : :
705 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|