LibreOffice Module oox (master) 1
slidepersist.cxx
Go to the documentation of this file.
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
21#include <com/sun/star/drawing/XDrawPage.hpp>
22#include <com/sun/star/drawing/XShapes.hpp>
23#include <com/sun/star/frame/XModel.hpp>
24#include <oox/ppt/timenode.hxx>
25#include <oox/ppt/pptshape.hxx>
32#include <oox/token/properties.hxx>
33#include <oox/token/tokens.hxx>
37
38#include <osl/diagnose.h>
39
40#include <com/sun/star/style/XStyle.hpp>
41#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
42#include <com/sun/star/container/XNamed.hpp>
43#include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
44#include <com/sun/star/drawing/XGluePointsSupplier.hpp>
45#include <com/sun/star/container/XIdentifierContainer.hpp>
46#include <com/sun/star/drawing/EnhancedCustomShapeGluePointType.hpp>
47#include <com/sun/star/drawing/ConnectorType.hpp>
48#include <utility>
49#include <svx/svdobj.hxx>
50
51using namespace ::com::sun::star;
52using namespace ::oox::core;
53using namespace ::com::sun::star::uno;
54using namespace ::com::sun::star::drawing;
55using namespace ::com::sun::star::container;
56using namespace ::com::sun::star::animations;
57
58
59namespace oox::ppt {
60
61SlidePersist::SlidePersist( XmlFilterBase& rFilter, bool bMaster, bool bNotes,
62 const css::uno::Reference< css::drawing::XDrawPage >& rxPage,
63 oox::drawingml::ShapePtr pShapesPtr, drawingml::TextListStylePtr pDefaultTextStyle )
64: mpDrawingPtr( std::make_shared<oox::vml::Drawing>( rFilter, rxPage, oox::vml::VMLDRAWING_POWERPOINT ) )
65, mxPage( rxPage )
66, maShapesPtr(std::move( pShapesPtr ))
67, mnLayoutValueToken( 0 )
68, mbMaster( bMaster )
69, mbNotes ( bNotes )
70, maDefaultTextStylePtr(std::move( pDefaultTextStyle ))
71, maTitleTextStylePtr( std::make_shared<oox::drawingml::TextListStyle>() )
72, maBodyTextStylePtr( std::make_shared<oox::drawingml::TextListStyle>() )
73, maNotesTextStylePtr( std::make_shared<oox::drawingml::TextListStyle>() )
74, maOtherTextStylePtr( std::make_shared<oox::drawingml::TextListStyle>() )
75{
76#if OSL_DEBUG_LEVEL > 0
78#endif
79}
80
81#if OSL_DEBUG_LEVEL > 0
82css::uno::WeakReference< css::drawing::XDrawPage > SlidePersist::mxDebugPage;
83#endif
84
86{
87}
88
90{
91 sal_Int16 nLayout = 20; // 20 == blank (so many magic numbers :-( the description at com.sun.star.presentation.DrawPage.Layout does not help)
92 switch( mnLayoutValueToken )
93 {
94 case XML_blank: nLayout = 20; break;
95 case XML_chart: nLayout = 2; break;
96 case XML_chartAndTx: nLayout = 7; break;
97 case XML_clipArtAndTx: nLayout = 9; break;
98 case XML_clipArtAndVertTx: nLayout = 24; break;
99 case XML_fourObj: nLayout = 18; break;
100 case XML_obj: nLayout = 11; break;
101 case XML_objAndTx: nLayout = 13; break;
102 case XML_objOverTx: nLayout = 14; break;
103 case XML_tbl: nLayout = 8; break;
104 case XML_title: nLayout = 0; break;
105 case XML_titleOnly: nLayout = 19; break;
106 case XML_twoObj:
107 case XML_twoColTx: nLayout = 3; break;
108 case XML_twoObjAndTx: nLayout = 15; break;
109 case XML_twoObjOverTx: nLayout = 16; break;
110 case XML_tx: nLayout = 1; break;
111 case XML_txAndChart: nLayout = 4; break;
112 case XML_txAndClipArt: nLayout = 6; break;
113 case XML_txAndMedia: nLayout = 6; break;
114 case XML_txAndObj: nLayout = 10; break;
115 case XML_txAndTwoObj: nLayout = 12; break;
116 case XML_txOverObj: nLayout = 17; break;
117 case XML_vertTitleAndTx: nLayout = 22; break;
118 case XML_vertTitleAndTxOverChart: nLayout = 21; break;
119 case XML_vertTx: nLayout = 23; break;
120
121 case XML_twoTxTwoObj:
122 case XML_twoObjAndObj:
123 case XML_objTx:
124 case XML_picTx:
125 case XML_secHead:
126 case XML_objOnly:
127 case XML_objAndTwoObj:
128 case XML_mediaAndTx:
129 case XML_dgm:
130 case XML_cust:
131 default:
132 nLayout = 20;
133 }
134 return nLayout;
135}
136
137void SlidePersist::createXShapes( XmlFilterBase& rFilterBase )
138{
139 applyTextStyles( rFilterBase );
140
141 Reference< XShapes > xShapes( getPage() );
142 std::vector< oox::drawingml::ShapePtr >& rShapes( maShapesPtr->getChildren() );
143
144 for (auto const& shape : rShapes)
145 {
146 std::vector< oox::drawingml::ShapePtr >& rChildren( shape->getChildren() );
147 for (auto const& child : rChildren)
148 {
149 PPTShape* pPPTShape = dynamic_cast< PPTShape* >( child.get() );
150 basegfx::B2DHomMatrix aTransformation;
151 if ( pPPTShape )
152 {
153 pPPTShape->addShape( rFilterBase, *this, getTheme().get(), xShapes, aTransformation, &getShapeMap() );
154 if (pPPTShape->isConnectorShape())
155 maConnectorShapeId.push_back(pPPTShape->getId());
156 if (!pPPTShape->getChildren().empty())
157 {
158 for (size_t i = 0; i < pPPTShape->getChildren().size(); i++)
159 {
160 if (pPPTShape->getChildren()[i]->isConnectorShape())
161 maConnectorShapeId.push_back(pPPTShape->getChildren()[i]->getId());
162 }
163 }
164 }
165 else
166 child->addShape( rFilterBase, getTheme().get(), xShapes, aTransformation, maShapesPtr->getFillProperties(), &getShapeMap() );
167 }
168 }
169
170 if (!maConnectorShapeId.empty())
172
173 Reference< XAnimationNodeSupplier > xNodeSupplier( getPage(), UNO_QUERY);
174 if( !xNodeSupplier.is() )
175 return;
176
177 Reference< XAnimationNode > xNode( xNodeSupplier->getAnimationNode() );
178 if( xNode.is() && !maTimeNodeList.empty() )
179 {
180 SlidePersistPtr pSlidePtr( shared_from_this() );
181 TimeNodePtr pNode(maTimeNodeList.front());
182 OSL_ENSURE( pNode, "pNode" );
183
184 Reference<XAnimationNode> xDummy;
185 pNode->setNode(rFilterBase, xNode, pSlidePtr, xDummy);
186 }
187}
188
189void SlidePersist::createBackground( const XmlFilterBase& rFilterBase )
190{
192 {
193 ::Color nPhClr = maBackgroundColor.isUsed() ?
194 maBackgroundColor.getColor( rFilterBase.getGraphicHelper() ) : API_RGB_TRANSPARENT;
195
196 css::awt::Size aSize;
197 Reference< css::beans::XPropertySet > xSet(mxPage, UNO_QUERY);
198 xSet->getPropertyValue("Width") >>= aSize.Width;
199 xSet->getPropertyValue("Height") >>= aSize.Height;
200
203 oox::drawingml::ShapePropertyInfo aPropInfo( aPropertyIds, true, false, true, false, false );
204 oox::drawingml::ShapePropertyMap aPropMap( rFilterBase.getModelObjectHelper(), aPropInfo );
205 mpBackgroundPropertiesPtr->pushToPropMap( aPropMap, rFilterBase.getGraphicHelper(), 0, nPhClr, aSize);
206 PropertySet( mxPage ).setProperty( PROP_Background, aPropMap.makePropertySet() );
207 }
208}
209
210static void setTextStyle( Reference< beans::XPropertySet > const & rxPropSet, const XmlFilterBase& rFilter,
211 oox::drawingml::TextListStylePtr const & pTextListStylePtr, int nLevel )
212{
213 ::oox::drawingml::TextParagraphProperties* pTextParagraphPropertiesPtr( &pTextListStylePtr->getListStyle()[ nLevel ] );
214 if( pTextParagraphPropertiesPtr == nullptr )
215 {
216 // no properties. return
217 return;
218 }
219
220 PropertyMap& rTextParagraphPropertyMap( pTextParagraphPropertiesPtr->getTextParagraphPropertyMap() );
221
222 PropertySet aPropSet( rxPropSet );
223 aPropSet.setProperties( rTextParagraphPropertyMap );
224 pTextParagraphPropertiesPtr->getTextCharacterProperties().pushToPropSet( aPropSet, rFilter );
225}
226
227void SlidePersist::applyTextStyles( const XmlFilterBase& rFilterBase )
228{
229 if ( !mbMaster )
230 return;
231
232 try
233 {
234 Reference< style::XStyleFamiliesSupplier > aXStyleFamiliesSupplier( rFilterBase.getModel(), UNO_QUERY_THROW );
235 Reference< container::XNameAccess > aXNameAccess( aXStyleFamiliesSupplier->getStyleFamilies() );
236 Reference< container::XNamed > aXNamed( mxPage, UNO_QUERY_THROW );
237
238 if ( aXNameAccess.is() )
239 {
240 oox::drawingml::TextListStylePtr pTextListStylePtr;
241 OUString aStyle;
242 OUString aFamily;
243
244 static constexpr OUStringLiteral sOutline( u"outline1" );
245 static constexpr OUStringLiteral sTitle( u"title" );
246 static constexpr OUStringLiteral sStandard( u"standard" );
247 static constexpr OUStringLiteral sSubtitle( u"subtitle" );
248
249 for( int i = 0; i < 4; i++ ) // todo: aggregation of bodystyle (subtitle)
250 {
251 switch( i )
252 {
253 case 0 : // title style
254 {
255 pTextListStylePtr = maTitleTextStylePtr;
256 aStyle = sTitle;
257 aFamily= aXNamed->getName();
258 break;
259 }
260 case 1 : // body style
261 {
262 pTextListStylePtr = maBodyTextStylePtr;
263 aStyle = sOutline;
264 aFamily= aXNamed->getName();
265 break;
266 }
267 case 3 : // notes style
268 {
269 pTextListStylePtr = maNotesTextStylePtr;
270 aStyle = sTitle;
271 aFamily= aXNamed->getName();
272 break;
273 }
274 case 4 : // standard style
275 {
276 pTextListStylePtr = maOtherTextStylePtr;
277 aStyle = sStandard;
278 aFamily = "graphics";
279 break;
280 }
281 case 5 : // subtitle
282 {
283 pTextListStylePtr = maBodyTextStylePtr;
284 aStyle = sSubtitle;
285 aFamily = aXNamed->getName();
286 break;
287 }
288 }
289 Reference< container::XNameAccess > xFamilies;
290 if ( aXNameAccess->hasByName( aFamily ) )
291 {
292 if( aXNameAccess->getByName( aFamily ) >>= xFamilies )
293 {
294 if ( xFamilies->hasByName( aStyle ) )
295 {
296 Reference< style::XStyle > aXStyle;
297 if ( xFamilies->getByName( aStyle ) >>= aXStyle )
298 {
299 Reference< beans::XPropertySet > xPropSet( aXStyle, UNO_QUERY_THROW );
300 setTextStyle( xPropSet, rFilterBase, maDefaultTextStylePtr, 0 );
301 setTextStyle( xPropSet, rFilterBase, pTextListStylePtr, 0 );
302 if ( i == 1 /* BodyStyle */ )
303 {
304 for ( int nLevel = 1; nLevel < 5; nLevel++ )
305 {
306 {
307 char pOutline[ 9 ] = "outline1";
308 pOutline[ 7 ] = static_cast< char >( '0' + nLevel );
309 OUString sOutlineStyle( OUString::createFromAscii( pOutline ) );
310 if ( xFamilies->hasByName( sOutlineStyle ) )
311 {
312 xFamilies->getByName( sOutlineStyle ) >>= aXStyle;
313 if( aXStyle.is() )
314 xPropSet.set( aXStyle, UNO_QUERY_THROW );
315 }
316 }
317 setTextStyle( xPropSet, rFilterBase, maDefaultTextStylePtr, nLevel );
318 setTextStyle( xPropSet, rFilterBase, pTextListStylePtr, nLevel );
319 }
320 }
321 }
322 }
323 }
324 }
325 }
326 }
327 }
328 catch( const Exception& )
329 {
330 }
331}
332
334{
335 std::vector< oox::drawingml::ShapePtr >& rShapes( maShapesPtr->getChildren() );
336 for (auto const& shape : rShapes)
337 {
338 std::vector< oox::drawingml::ShapePtr >& rChildren( shape->getChildren() );
339 for (auto const& child : rChildren)
340 {
341 PPTShape* pPPTShape = dynamic_cast< PPTShape* >( child.get() );
342 if (!pPPTShape)
343 continue;
344 pPPTShape->setHiddenMasterShape( true );
345 }
346 }
347}
348
349// This angle determines in the direction of the line
350static sal_Int32 lcl_GetAngle(uno::Reference<drawing::XShape>& rXShape, awt::Point& rPt)
351{
353 tools::Rectangle aR(pObj->GetSnapRect());
354 sal_Int32 nLeftX = rPt.X - aR.Left();
355 sal_Int32 nTopY = rPt.Y - aR.Top();
356 sal_Int32 nRightX = aR.Right() - rPt.X;
357 sal_Int32 nBottomY = aR.Bottom() - rPt.Y;
358 sal_Int32 nX = std::min(nLeftX, nRightX);
359 sal_Int32 nY = std::min(nTopY, nBottomY);
360
361 sal_Int32 nAngle;
362 if (nX < nY)
363 {
364 if (nLeftX < nRightX)
365 nAngle = 180; // Left
366 else
367 nAngle = 0; // Right
368 }
369 else
370 {
371 if (nTopY < nBottomY)
372 nAngle = 270; // Top
373 else
374 nAngle = 90; // Bottom
375 }
376 return nAngle;
377}
378
379Reference<XAnimationNode> SlidePersist::getAnimationNode(const OUString& sId) const
380{
381 const auto& pIter = maAnimNodesMap.find(sId);
382 if (pIter != maAnimNodesMap.end())
383 return pIter->second;
384
385 Reference<XAnimationNode> aResult;
386 return aResult;
387}
388
389static void lcl_SetEdgeLineValue(uno::Reference<drawing::XShape>& rXConnector,
390 oox::drawingml::ShapePtr& rShapePtr)
391{
392 sal_Int32 nEdge = 0;
393 awt::Point aStartPt, aEndPt;
394 tools::Rectangle aS, aE; // Start, End rectangle
395 uno::Reference<drawing::XShape> xStartSp, xEndSp;
396 uno::Reference<beans::XPropertySet> xPropSet(rXConnector, uno::UNO_QUERY);
397 xPropSet->getPropertyValue("EdgeStartPoint") >>= aStartPt;
398 xPropSet->getPropertyValue("EdgeEndPoint") >>= aEndPt;
399 xPropSet->getPropertyValue("StartShape") >>= xStartSp;
400 xPropSet->getPropertyValue("EndShape") >>= xEndSp;
401 xPropSet->setPropertyValue("EdgeNode1HorzDist", Any(sal_Int32(0)));
402 xPropSet->setPropertyValue("EdgeNode1VertDist", Any(sal_Int32(0)));
403 xPropSet->setPropertyValue("EdgeNode2HorzDist", Any(sal_Int32(0)));
404 xPropSet->setPropertyValue("EdgeNode2VertDist", Any(sal_Int32(0)));
405
406 SdrObject* pStartObj = xStartSp.is() ? SdrObject::getSdrObjectFromXShape(xStartSp) : nullptr;
407 SdrObject* pEndObj = xEndSp.is() ? SdrObject::getSdrObjectFromXShape(xEndSp) : nullptr;
408
409 sal_Int32 nStartA = -1;
410 sal_Int32 nEndA = -1;
411 if (pStartObj)
412 {
413 aS = pStartObj->GetSnapRect();
414 nStartA = lcl_GetAngle(xStartSp, aStartPt);
415 }
416 if (pEndObj)
417 {
418 aE = pEndObj->GetSnapRect();
419 nEndA = lcl_GetAngle(xEndSp, aEndPt);
420 }
421
422 // bentConnector3, bentConnector4, bentConnector5
423 if (!rShapePtr->getConnectorAdjustments().empty())
424 {
425 sal_Int32 nAdjustValue = 0;
426 for (size_t i = 0; i < rShapePtr->getConnectorAdjustments().size(); i++)
427 {
428 bool bVertical = false;
429 if (xStartSp.is() || xEndSp.is())
430 bVertical = xStartSp.is() ? ((nStartA == 90 || nStartA == 270) ? true : false)
431 : ((nEndA == 90 || nEndA == 270) ? true : false);
432 else
433 {
434 sal_Int32 nAng = rShapePtr->getRotation() / 60000;
435 bVertical = (nAng == 90 || nAng == 270) ? true : false;
436 }
437
438 if (i % 2 == 1)
439 bVertical = !bVertical;
440
441 nAdjustValue = rShapePtr->getConnectorAdjustments()[i].toInt32();
442 if (bVertical)
443 {
444 sal_Int32 nY = aStartPt.Y + ((nAdjustValue * (aEndPt.Y - aStartPt.Y)) / 100000);
445 if (xStartSp.is() && xEndSp.is())
446 {
447 if (aS.Top() <= aE.Top())
448 {
449 if (nStartA == 270 && i != 2)
450 nEdge = nY - aS.Top();
451 else
452 {
453 if (aS.Bottom() < aE.Top() && nEndA != 90)
454 {
455 nEdge = nY - (aS.Bottom() + ((aE.Top() - aS.Bottom()) / 2));
456 }
457 else
458 nEdge = nY - aE.Bottom();
459 }
460 }
461 else
462 {
463 if (nStartA == 90 && i != 2)
464 nEdge = nY - aS.Bottom();
465 else
466 {
467 if (aE.Bottom() < aS.Top() && nEndA != 270)
468 nEdge = nY - (aS.Top() + ((aE.Bottom() - aS.Top()) / 2));
469 else
470 nEdge = nY - aE.Top();
471 }
472 }
473 }
474 else if ((xStartSp.is() && !xEndSp.is()) || (!xStartSp.is() && xEndSp.is()))
475 {
476 if (aStartPt.Y < aEndPt.Y)
477 {
478 if (xStartSp.is())
479 nEdge = (nStartA == 90)
480 ? nY - (aEndPt.Y - ((aEndPt.Y - aS.Bottom()) / 2))
481 : nY - aS.Top();
482 else
483 nEdge = (nEndA == 90)
484 ? nY - aE.Bottom()
485 : nY - (aStartPt.Y + ((aE.Top() - aStartPt.Y) / 2));
486 }
487 else
488 {
489 if (xStartSp.is())
490 nEdge = (nStartA == 90) ? nY - aS.Bottom()
491 : nY - (aEndPt.Y + ((aS.Top() - aEndPt.Y) / 2));
492 else
493 nEdge = (nEndA == 90)
494 ? nY - (aStartPt.Y - ((aStartPt.Y - aE.Bottom()) / 2))
495 : nY - aE.Top();
496 }
497 }
498 else
499 {
500 nEdge = (aStartPt.Y < aEndPt.Y)
501 ? nY - (aStartPt.Y + (rXConnector->getSize().Height / 2))
502 : nY - (aStartPt.Y - (rXConnector->getSize().Height / 2));
503 }
504 }
505 else // Horizontal
506 {
507 sal_Int32 nX = aStartPt.X + ((nAdjustValue * (aEndPt.X - aStartPt.X)) / 100000);
508 if (xStartSp.is() && xEndSp.is())
509 {
510 if (aS.Left() <= aE.Left())
511 {
512 if (nStartA == 180 && i != 2)
513 nEdge = nX - aS.Left();
514 else
515 {
516 if (aS.Right() < aE.Left() && nEndA != 0)
517 nEdge = nX - (aS.Right() + ((aE.Left() - aS.Right()) / 2));
518 else
519 nEdge = nX - aE.Right();
520 }
521 }
522 else
523 {
524 if (nStartA == 0 && i != 2)
525 nEdge = nX - aS.Right();
526 else
527 {
528 if (aE.Right() < aS.Left() && nEndA != 180)
529 nEdge = nX - (aS.Left() + ((aE.Right() - aS.Left()) / 2));
530 else
531 nEdge = nX - aE.Left();
532 }
533 }
534 }
535 else if ((xStartSp.is() && !xEndSp.is()) || (!xStartSp.is() && xEndSp.is()))
536 {
537 if (aStartPt.X < aEndPt.X)
538 {
539 if (xStartSp.is())
540 nEdge = (nStartA == 0)
541 ? nX - (aS.Right() + ((aEndPt.X - aS.Right()) / 2))
542 : nX - aS.Left();
543 else
544 nEdge = (nEndA == 0)
545 ? nX - aE.Right()
546 : nX - (aStartPt.X + ((aE.Left() - aStartPt.X) / 2));
547 }
548 else
549 {
550 if (xStartSp.is())
551 nEdge = (nStartA == 0) ? nX - aS.Right()
552 : nX - (aEndPt.X + ((aS.Left() - aEndPt.X) / 2));
553 else
554 nEdge = (nEndA == 0)
555 ? nX - (aE.Right() + ((aStartPt.X - aE.Right()) / 2))
556 : nX - aE.Left();
557 }
558 }
559 else
560 {
561 nEdge = (aStartPt.X < aEndPt.X)
562 ? nX - (aStartPt.X + (rXConnector->getSize().Width / 2))
563 : nX - (aStartPt.X - (rXConnector->getSize().Width / 2));
564 }
565 }
566 xPropSet->setPropertyValue("EdgeLine" + OUString::number(i + 1) + "Delta", Any(nEdge));
567 }
568 }
569 else
570 {
571 const OUString sConnectorName = rShapePtr->getConnectorName();
572 if (sConnectorName == "bentConnector2")
573 {
574 awt::Size aConnSize = rXConnector->getSize();
575 if (xStartSp.is() || xEndSp.is())
576 {
577 if (nStartA >= 0)
578 {
579 switch (nStartA)
580 {
581 case 0: nEdge = aEndPt.X - aS.Right(); break;
582 case 180: nEdge = aEndPt.X - aS.Left(); break;
583 case 90: nEdge = aEndPt.Y - aS.Bottom(); break;
584 case 270: nEdge = aEndPt.Y - aS.Top(); break;
585 }
586 } else {
587 switch (nEndA)
588 {
589 case 0: nEdge = aStartPt.X - aE.Right(); break;
590 case 180: nEdge = aStartPt.X - aE.Left(); break;
591 case 90: nEdge = aStartPt.Y - aE.Bottom(); break;
592 case 270: nEdge = aStartPt.Y - aE.Top(); break;
593 }
594 }
595 }
596 else
597 {
598 bool bFlipH = rShapePtr->getFlipH();
599 bool bFlipV = rShapePtr->getFlipV();
600 sal_Int32 nConnectorAngle = rShapePtr->getRotation() / 60000;
601 if (aConnSize.Height < aConnSize.Width)
602 {
603 if ((nConnectorAngle == 90 && bFlipH && bFlipV) || (nConnectorAngle == 180)
604 || (nConnectorAngle == 270 && bFlipH))
605 nEdge -= aConnSize.Width;
606 else
607 nEdge += aConnSize.Width;
608 }
609 else
610 {
611 if ((nConnectorAngle == 180 && bFlipV) || (nConnectorAngle == 270 && bFlipV)
612 || (nConnectorAngle == 90 && bFlipH && bFlipV)
613 || (nConnectorAngle == 0 && !bFlipV))
614 nEdge -= aConnSize.Height;
615 else
616 nEdge += aConnSize.Height;
617 }
618 }
619 xPropSet->setPropertyValue("EdgeLine1Delta", Any(nEdge / 2));
620 }
621 }
622}
623
624// create connection between two shape with a connector shape.
626{
627 sal_Int32 nConnectorShapeCount = maConnectorShapeId.size();
628 for (sal_Int32 i = 0; i < nConnectorShapeCount; i++)
629 {
630 const auto& pIt = maShapeMap.find(maConnectorShapeId[i]);
631 if (pIt == maShapeMap.end())
632 continue;
633 oox::drawingml::ConnectorShapePropertiesList aConnectorShapeProperties
634 = pIt->second->getConnectorShapeProperties();
635 uno::Reference<drawing::XShape> xConnector(pIt->second->getXShape(), uno::UNO_QUERY);
636 uno::Reference<beans::XPropertySet> xPropertySet(xConnector, uno::UNO_QUERY);
637
638 if (xConnector.is())
639 {
640 sal_Int32 nCount = aConnectorShapeProperties.size();
641 for (sal_Int32 j = 0; j < nCount; j++)
642 {
643 OUString aDestShapeId = aConnectorShapeProperties[j].maDestShapeId;
644 const auto& pShape = maShapeMap.find(aDestShapeId);
645 if (pShape == maShapeMap.end())
646 continue;
647 uno::Reference<drawing::XShape> xShape(pShape->second->getXShape(), uno::UNO_QUERY);
648 if (xShape.is())
649 {
650 uno::Reference<drawing::XGluePointsSupplier> xSupplier(xShape, uno::UNO_QUERY);
651 css::uno::Reference<css::container::XIdentifierContainer> xGluePoints(
652 xSupplier->getGluePoints(), uno::UNO_QUERY);
653
654 sal_Int32 nCountGluePoints = xGluePoints->getIdentifiers().getLength();
655 sal_Int32 nGlueId = aConnectorShapeProperties[j].mnDestGlueId;
656
657 // The first 4 glue points belong to the bounding box.
658 if (nCountGluePoints > 4)
659 nGlueId += 4;
660 else
661 {
662 bool bFlipH = pShape->second->getFlipH();
663 bool bFlipV = pShape->second->getFlipV();
664 if ((!bFlipH && !bFlipV) || (bFlipH && bFlipV))
665 {
666 // change id of the left and right glue points of the bounding box (1 <-> 3)
667 if (nGlueId == 1)
668 nGlueId = 3; // Right
669 else if (nGlueId == 3)
670 nGlueId = 1; // Left
671 }
672 }
673
674 bool bStart = aConnectorShapeProperties[j].mbStartShape;
675 if (bStart)
676 {
677 xPropertySet->setPropertyValue("StartShape", uno::Any(xShape));
678 xPropertySet->setPropertyValue("StartGluePointIndex", uno::Any(nGlueId));
679 }
680 else
681 {
682 xPropertySet->setPropertyValue("EndShape", uno::Any(xShape));
683 xPropertySet->setPropertyValue("EndGluePointIndex", uno::Any(nGlueId));
684 }
685 }
686 }
687 uno::Reference<beans::XPropertySetInfo> xPropInfo = xPropertySet->getPropertySetInfo();
688 if (xPropInfo->hasPropertyByName("EdgeKind"))
689 {
690 ConnectorType aConnectorType;
691 xPropertySet->getPropertyValue("EdgeKind") >>= aConnectorType;
692 if (aConnectorType == ConnectorType_STANDARD)
693 lcl_SetEdgeLineValue(xConnector, pIt->second);
694 }
695 }
696 }
697 maConnectorShapeId.clear();
698}
699
700}
701
702/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static SdrObject * getSdrObjectFromXShape(const css::uno::Reference< css::uno::XInterface > &xInt)
virtual const tools::Rectangle & GetSnapRect() const
A helper that maps property identifiers to property values.
Definition: propertymap.hxx:52
css::uno::Reference< css::beans::XPropertySet > makePropertySet() const
Creates a property set supporting the XPropertySet interface and inserts all properties.
A wrapper for a UNO property set.
Definition: propertyset.hxx:58
void setProperties(const css::uno::Sequence< OUString > &rPropNames, const css::uno::Sequence< css::uno::Any > &rValues)
Puts the passed properties into the property set.
bool setProperty(sal_Int32 nPropId, const Type &rValue)
Puts the passed value into the property set.
bool isUsed() const
Returns true, if the color is initialized.
Definition: color.hxx:92
::Color getColor(const GraphicHelper &rGraphicHelper, ::Color nPhClr=API_RGB_TRANSPARENT) const
Returns the final RGB color value.
Definition: color.cxx:644
std::vector< ShapePtr > & getChildren()
Definition: shape.hxx:168
const OUString & getId() const
Definition: shape.hxx:175
void setHiddenMasterShape(bool bHiddenMasterShape)
Definition: shape.hxx:179
bool isConnectorShape() const
Definition: shape.hxx:143
TextCharacterProperties & getTextCharacterProperties()
void addShape(oox::core::XmlFilterBase &rFilterBase, const SlidePersist &rPersist, const oox::drawingml::Theme *pTheme, const css::uno::Reference< css::drawing::XShapes > &rxShapes, basegfx::B2DHomMatrix &aTransformation, ::oox::drawingml::ShapeIdMap *pShapeMap)
Definition: pptshape.cxx:160
::oox::drawingml::ShapeIdMap & getShapeMap()
oox::drawingml::TextListStylePtr maOtherTextStylePtr
std::map< OUString, ::oox::drawingml::ShapePtr > maShapeMap
void createBackground(const oox::core::XmlFilterBase &rFilterBase)
oox::drawingml::TextListStylePtr maBodyTextStylePtr
oox::drawingml::TextListStylePtr maTitleTextStylePtr
const css::uno::Reference< css::drawing::XDrawPage > & getPage() const
oox::drawingml::ShapePtr maShapesPtr
void createXShapes(oox::core::XmlFilterBase &rFilterBase)
static css::uno::WeakReference< css::drawing::XDrawPage > mxDebugPage
std::vector< OUString > maConnectorShapeId
const oox::drawingml::ThemePtr & getTheme() const
css::uno::Reference< css::drawing::XDrawPage > mxPage
oox::drawingml::TextListStylePtr maDefaultTextStylePtr
css::uno::Reference< css::animations::XAnimationNode > getAnimationNode(const OUString &sId) const
oox::drawingml::TextListStylePtr maNotesTextStylePtr
void applyTextStyles(const oox::core::XmlFilterBase &rFilterBase)
std::map< OUString, css::uno::Reference< css::animations::XAnimationNode > > maAnimNodesMap
SlidePersist(oox::core::XmlFilterBase &rFilter, bool bMaster, bool bNotes, const css::uno::Reference< css::drawing::XDrawPage > &, oox::drawingml::ShapePtr pShapesPtr, ::oox::drawingml::TextListStylePtr)
oox::drawingml::Color maBackgroundColor
::std::vector< std::shared_ptr< TimeNode > > maTimeNodeList
oox::drawingml::FillPropertiesPtr mpBackgroundPropertiesPtr
sal_Int16 getLayoutFromValueToken() const
constexpr tools::Long Top() const
constexpr tools::Long Right() const
constexpr tools::Long Left() const
constexpr tools::Long Bottom() const
int nCount
float u
size
@ Exception
std::shared_ptr< T > make_shared(Args &&... args)
@ FillGradient
Explicit fill gradient or name of a fill gradient stored in a global container.
std::shared_ptr< Shape > ShapePtr
std::vector< ConnectorShapeProperties > ConnectorShapePropertiesList
Definition: shape.hxx:79
std::shared_ptr< TextListStyle > TextListStylePtr
std::shared_ptr< TimeNode > TimeNodePtr
Definition: timenode.hxx:44
std::shared_ptr< SlidePersist > SlidePersistPtr
static sal_Int32 lcl_GetAngle(uno::Reference< drawing::XShape > &rXShape, awt::Point &rPt)
static void setTextStyle(Reference< beans::XPropertySet > const &rxPropSet, const XmlFilterBase &rFilter, oox::drawingml::TextListStylePtr const &pTextListStylePtr, int nLevel)
static void lcl_SetEdgeLineValue(uno::Reference< drawing::XShape > &rXConnector, oox::drawingml::ShapePtr &rShapePtr)
@ VMLDRAWING_POWERPOINT
PowerPoint: OLE objects are part of DrawingML.
Definition: vmldrawing.hxx:57
const ::Color API_RGB_TRANSPARENT(ColorTransparency, 0xffffffff)
Transparent color for API calls.
const ShapePropertyIds & mrPropertyIds
static ShapePropertyInfo DEFAULT
True = use named fill hatch instead of explicit fill hatch.
void pushToPropSet(PropertySet &rPropSet, const ::oox::core::XmlFilterBase &rFilter) const
Writes the properties to the passed property set.
OUString sId
constexpr OUStringLiteral PROP_FillGradientName