/src/libreoffice/oox/source/ppt/slidepersist.cxx
Line | Count | Source |
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 <basegfx/matrix/b2dhommatrix.hxx> |
21 | | #include <com/sun/star/drawing/XDrawPage.hpp> |
22 | | #include <com/sun/star/text/XTextRange.hpp> |
23 | | #include <com/sun/star/drawing/XShapes.hpp> |
24 | | #include <com/sun/star/frame/XModel.hpp> |
25 | | #include <oox/ppt/timenode.hxx> |
26 | | #include <oox/ppt/pptshape.hxx> |
27 | | #include <oox/ppt/slidepersist.hxx> |
28 | | #include <drawingml/fillproperties.hxx> |
29 | | #include <oox/drawingml/shapepropertymap.hxx> |
30 | | #include <oox/helper/propertymap.hxx> |
31 | | #include <oox/helper/propertyset.hxx> |
32 | | #include <oox/vml/vmldrawing.hxx> |
33 | | #include <oox/token/properties.hxx> |
34 | | #include <oox/token/tokens.hxx> |
35 | | #include <oox/core/xmlfilterbase.hxx> |
36 | | #include <drawingml/textbody.hxx> |
37 | | #include <drawingml/textliststyle.hxx> |
38 | | #include <drawingml/textparagraphproperties.hxx> |
39 | | #include <drawingml/connectorhelper.hxx> |
40 | | |
41 | | #include <osl/diagnose.h> |
42 | | |
43 | | #include <com/sun/star/style/XStyle.hpp> |
44 | | #include <com/sun/star/style/XStyleFamiliesSupplier.hpp> |
45 | | #include <com/sun/star/container/XNamed.hpp> |
46 | | #include <com/sun/star/animations/XAnimationNodeSupplier.hpp> |
47 | | #include <com/sun/star/drawing/XGluePointsSupplier.hpp> |
48 | | #include <com/sun/star/container/XIdentifierContainer.hpp> |
49 | | #include <com/sun/star/drawing/EnhancedCustomShapeGluePointType.hpp> |
50 | | #include <com/sun/star/drawing/ConnectorType.hpp> |
51 | | #include <utility> |
52 | | #include <svx/svdobj.hxx> |
53 | | #include <svx/svdmodel.hxx> |
54 | | |
55 | | using namespace ::com::sun::star; |
56 | | using namespace ::oox::core; |
57 | | using namespace ::com::sun::star::uno; |
58 | | using namespace ::com::sun::star::drawing; |
59 | | using namespace ::com::sun::star::container; |
60 | | using namespace ::com::sun::star::animations; |
61 | | |
62 | | |
63 | | namespace oox::ppt { |
64 | | |
65 | | SlidePersist::SlidePersist( XmlFilterBase& rFilter, bool bMaster, bool bNotes, |
66 | | const css::uno::Reference< css::drawing::XDrawPage >& rxPage, |
67 | | oox::drawingml::ShapePtr pShapesPtr, drawingml::TextListStylePtr pDefaultTextStyle ) |
68 | 22.0k | : mpDrawingPtr( std::make_shared<oox::vml::Drawing>( rFilter, rxPage, oox::vml::VMLDRAWING_POWERPOINT ) ) |
69 | 22.0k | , mxPage( rxPage ) |
70 | 22.0k | , maShapesPtr(std::move( pShapesPtr )) |
71 | 22.0k | , mnLayoutValueToken( 0 ) |
72 | 22.0k | , mbMaster( bMaster ) |
73 | 22.0k | , mbNotes ( bNotes ) |
74 | 22.0k | , maDefaultTextStylePtr(std::move( pDefaultTextStyle )) |
75 | 22.0k | , maTitleTextStylePtr( std::make_shared<oox::drawingml::TextListStyle>() ) |
76 | 22.0k | , maBodyTextStylePtr( std::make_shared<oox::drawingml::TextListStyle>() ) |
77 | 22.0k | , maNotesTextStylePtr( std::make_shared<oox::drawingml::TextListStyle>() ) |
78 | 22.0k | , maOtherTextStylePtr( std::make_shared<oox::drawingml::TextListStyle>() ) |
79 | 22.0k | { |
80 | | #if OSL_DEBUG_LEVEL > 0 |
81 | | mxDebugPage = mxPage; |
82 | | #endif |
83 | 22.0k | } |
84 | | |
85 | | #if OSL_DEBUG_LEVEL > 0 |
86 | | css::uno::WeakReference< css::drawing::XDrawPage > SlidePersist::mxDebugPage; |
87 | | #endif |
88 | | |
89 | | SlidePersist::~SlidePersist() |
90 | 22.0k | { |
91 | 22.0k | } |
92 | | |
93 | | void SlidePersist::releaseShapes() |
94 | 4.78k | { |
95 | 4.78k | for (const auto& [sId, pShape] : maShapeMap) |
96 | 5.68k | { |
97 | 5.68k | if (pShape |
98 | 5.68k | && (pShape->getSubType() == XML_title || pShape->getSubType() == XML_ctrTitle)) |
99 | 300 | { |
100 | 300 | css::uno::Reference<css::text::XTextRange> xText(pShape->getXShape(), css::uno::UNO_QUERY); |
101 | 300 | if (xText.is()) |
102 | 300 | maTitleText = xText->getString(); |
103 | 300 | if (!maTitleText.isEmpty()) |
104 | 146 | break; |
105 | 300 | } |
106 | 5.68k | } |
107 | 4.78k | maShapesPtr.reset(); |
108 | 4.78k | maShapeMap.clear(); |
109 | 4.78k | mpBackgroundPropertiesPtr.reset(); |
110 | 4.78k | } |
111 | | |
112 | | // the list 'const PPTXLayoutInfo aLayoutInfo[...]' used in PowerPointExport |
113 | | // likely needs to be updated after any changes here |
114 | | sal_Int16 SlidePersist::getLayoutFromValueToken() const |
115 | 19.5k | { |
116 | 19.5k | sal_Int16 nLayout = 20; // 20 == blank (so many magic numbers :-( the description at com.sun.star.presentation.DrawPage.Layout does not help) |
117 | 19.5k | switch( mnLayoutValueToken ) |
118 | 19.5k | { |
119 | 1.69k | case XML_blank: nLayout = 20; break; |
120 | 15 | case XML_chart: nLayout = 2; break; |
121 | 0 | case XML_chartAndTx: nLayout = 7; break; |
122 | 0 | case XML_clipArtAndTx: nLayout = 9; break; |
123 | 0 | case XML_clipArtAndVertTx: nLayout = 30; break; |
124 | 473 | case XML_fourObj: nLayout = 18; break; |
125 | 1.08k | case XML_obj: nLayout = 11; break; |
126 | 0 | case XML_objAndTx: nLayout = 13; break; |
127 | 450 | case XML_objOverTx: nLayout = 14; break; |
128 | 0 | case XML_tbl: nLayout = 8; break; |
129 | 2.09k | case XML_title: nLayout = 0; break; |
130 | 962 | case XML_titleOnly: nLayout = 19; break; |
131 | 877 | case XML_twoObj: |
132 | 877 | case XML_twoColTx: nLayout = 3; break; |
133 | 471 | case XML_twoObjAndObj: |
134 | 471 | case XML_twoObjAndTx: nLayout = 15; break; |
135 | 471 | case XML_twoObjOverTx: nLayout = 16; break; |
136 | 621 | case XML_tx: nLayout = 1; break; |
137 | 0 | case XML_txAndChart: nLayout = 4; break; |
138 | 0 | case XML_txAndClipArt: |
139 | 0 | case XML_txAndMedia: nLayout = 6; break; |
140 | 0 | case XML_txAndObj: nLayout = 10; break; |
141 | 460 | case XML_objAndTwoObj: |
142 | 460 | case XML_txAndTwoObj: nLayout = 12; break; |
143 | 0 | case XML_txOverObj: nLayout = 17; break; |
144 | 442 | case XML_vertTitleAndTx: nLayout = 28; break; |
145 | 0 | case XML_vertTitleAndTxOverChart: nLayout = 27; break; |
146 | 410 | case XML_vertTx: nLayout = 29; break; |
147 | 439 | case XML_objOnly: nLayout = 32; break; |
148 | | |
149 | 390 | case XML_twoTxTwoObj: |
150 | 819 | case XML_objTx: |
151 | 1.21k | case XML_picTx: |
152 | 1.64k | case XML_secHead: |
153 | 1.64k | case XML_mediaAndTx: |
154 | 1.64k | case XML_dgm: |
155 | 1.64k | case XML_cust: |
156 | 8.56k | default: |
157 | 8.56k | nLayout = 20; |
158 | 19.5k | } |
159 | 19.5k | return nLayout; |
160 | 19.5k | } |
161 | | |
162 | | static void lcl_createShapeMap(oox::drawingml::ShapePtr rShapePtr, |
163 | | oox::drawingml::ShapeIdMap& rShapeMap) |
164 | 57.3k | { |
165 | 57.3k | std::vector<oox::drawingml::ShapePtr>& rChildren = rShapePtr->getChildren(); |
166 | 57.3k | if (!rChildren.empty()) |
167 | 12 | { |
168 | 12 | for (const auto& pIt : rChildren) |
169 | 24 | { |
170 | 24 | if (pIt->isConnectorShape()) |
171 | 6 | { |
172 | 6 | rShapeMap[pIt->getId()] = pIt; // add child itself |
173 | 6 | lcl_createShapeMap(pIt, rShapeMap); // and all its descendants |
174 | 6 | } |
175 | 24 | } |
176 | 12 | } |
177 | 57.3k | else |
178 | 57.3k | { |
179 | 57.3k | if(rShapePtr->isConnectorShape()) |
180 | 159 | rShapeMap[rShapePtr->getId()] = rShapePtr; |
181 | 57.3k | } |
182 | 57.3k | } |
183 | | |
184 | | void SlidePersist::createXShapes( XmlFilterBase& rFilterBase ) |
185 | 21.6k | { |
186 | 21.6k | applyTextStyles( rFilterBase ); |
187 | | |
188 | 21.6k | Reference< XShapes > xShapes( getPage() ); |
189 | 21.6k | std::vector< oox::drawingml::ShapePtr >& rShapes( maShapesPtr->getChildren() ); |
190 | 21.6k | oox::drawingml::ShapeIdMap aConnectorShapeMap; |
191 | | |
192 | 21.6k | for (auto const& shape : rShapes) |
193 | 22.5k | { |
194 | 22.5k | std::vector< oox::drawingml::ShapePtr >& rChildren( shape->getChildren() ); |
195 | 22.5k | for (auto const& child : rChildren) |
196 | 93.8k | { |
197 | 93.8k | PPTShape* pPPTShape = dynamic_cast< PPTShape* >( child.get() ); |
198 | 93.8k | basegfx::B2DHomMatrix aTransformation; |
199 | 93.8k | if ( pPPTShape ) |
200 | 93.8k | { |
201 | 93.8k | pPPTShape->addShape( rFilterBase, *this, getTheme().get(), xShapes, aTransformation, &getShapeMap() ); |
202 | | |
203 | 93.8k | const auto pIter = maShapeMap.find(pPPTShape->getId()); |
204 | 93.8k | if (pIter != maShapeMap.end()) |
205 | 57.3k | lcl_createShapeMap(pIter->second, aConnectorShapeMap); |
206 | 93.8k | } |
207 | 0 | else |
208 | 0 | child->addShape( rFilterBase, getTheme().get(), xShapes, aTransformation, maShapesPtr->getFillProperties(), &getShapeMap() ); |
209 | 93.8k | } |
210 | 22.5k | } |
211 | | |
212 | 21.6k | if (!aConnectorShapeMap.empty()) |
213 | 55 | { |
214 | 55 | for (auto& pIt : aConnectorShapeMap) |
215 | 159 | { |
216 | 159 | ConnectorHelper::applyConnections(pIt.second, getShapeMap()); |
217 | | |
218 | 159 | SdrObject* pObj = SdrObject::getSdrObjectFromXShape(pIt.second->getXShape()); |
219 | 159 | SdrModel& rModel(pObj->getSdrModelFromSdrObject()); |
220 | 159 | rModel.setLock(false); |
221 | | |
222 | 159 | if (pIt.second->getConnectorName() == u"bentConnector3"_ustr |
223 | 159 | || pIt.second->getConnectorName() == u"bentConnector4"_ustr |
224 | 159 | || pIt.second->getConnectorName() == u"bentConnector5"_ustr) |
225 | 0 | { |
226 | 0 | ConnectorHelper::applyBentHandleAdjustments(pIt.second); |
227 | 0 | } |
228 | 159 | else if (pIt.second->getConnectorName() == u"curvedConnector3"_ustr |
229 | 159 | || pIt.second->getConnectorName() == u"curvedConnector4"_ustr |
230 | 159 | || pIt.second->getConnectorName() == u"curvedConnector5"_ustr) |
231 | 0 | { |
232 | 0 | ConnectorHelper::applyCurvedHandleAdjustments(pIt.second); |
233 | 0 | } |
234 | 159 | else // bentConnector2 |
235 | 159 | createConnectorShapeConnection(pIt.second); |
236 | 159 | } |
237 | 55 | } |
238 | | |
239 | 21.6k | Reference< XAnimationNodeSupplier > xNodeSupplier( getPage(), UNO_QUERY); |
240 | 21.6k | if( !xNodeSupplier.is() ) |
241 | 117 | return; |
242 | | |
243 | 21.5k | Reference< XAnimationNode > xNode( xNodeSupplier->getAnimationNode() ); |
244 | 21.5k | if( xNode.is() && !maTimeNodeList.empty() ) |
245 | 815 | { |
246 | 815 | SlidePersistPtr pSlidePtr( shared_from_this() ); |
247 | 815 | TimeNodePtr pNode(maTimeNodeList.front()); |
248 | 815 | OSL_ENSURE( pNode, "pNode" ); |
249 | | |
250 | 815 | Reference<XAnimationNode> xDummy; |
251 | 815 | pNode->setNode(rFilterBase, xNode, pSlidePtr, xDummy); |
252 | 815 | } |
253 | 21.5k | } |
254 | | |
255 | | void SlidePersist::createBackground( const XmlFilterBase& rFilterBase ) |
256 | 21.6k | { |
257 | 21.6k | if ( mpBackgroundPropertiesPtr ) |
258 | 5.77k | { |
259 | 5.77k | ::Color nPhClr = maBackgroundColor.isUsed() ? |
260 | 3.68k | maBackgroundColor.getColor( rFilterBase.getGraphicHelper() ) : API_RGB_TRANSPARENT; |
261 | | |
262 | 5.77k | css::awt::Size aSize; |
263 | 5.77k | Reference< css::beans::XPropertySet > xSet(mxPage, UNO_QUERY); |
264 | 5.77k | xSet->getPropertyValue(u"Width"_ustr) >>= aSize.Width; |
265 | 5.77k | xSet->getPropertyValue(u"Height"_ustr) >>= aSize.Height; |
266 | | |
267 | 5.77k | oox::drawingml::ShapePropertyIds aPropertyIds = oox::drawingml::ShapePropertyInfo::DEFAULT.mrPropertyIds; |
268 | 5.77k | aPropertyIds[oox::drawingml::ShapeProperty::FillGradient] = PROP_FillGradientName; |
269 | 5.77k | oox::drawingml::ShapePropertyInfo aPropInfo( aPropertyIds, true, false, true, false, false ); |
270 | 5.77k | oox::drawingml::ShapePropertyMap aPropMap( rFilterBase.getModelObjectHelper(), aPropInfo ); |
271 | 5.77k | mpBackgroundPropertiesPtr->pushToPropMap( aPropMap, rFilterBase.getGraphicHelper(), 0, nPhClr, aSize); |
272 | 5.77k | PropertySet( mxPage ).setProperty( PROP_Background, aPropMap.makePropertySet() ); |
273 | 5.77k | } |
274 | 21.6k | } |
275 | | |
276 | | static void setTextStyle( Reference< beans::XPropertySet > const & rxPropSet, const XmlFilterBase& rFilter, |
277 | | oox::drawingml::TextListStylePtr const & pTextListStylePtr, int nLevel ) |
278 | 270k | { |
279 | 270k | ::oox::drawingml::TextParagraphProperties* pTextParagraphPropertiesPtr( &pTextListStylePtr->getListStyle()[ nLevel ] ); |
280 | 270k | if( pTextParagraphPropertiesPtr == nullptr ) |
281 | 0 | { |
282 | | // no properties. return |
283 | 0 | return; |
284 | 0 | } |
285 | | |
286 | 270k | PropertyMap& rTextParagraphPropertyMap( pTextParagraphPropertiesPtr->getTextParagraphPropertyMap() ); |
287 | | |
288 | 270k | PropertySet aPropSet( rxPropSet ); |
289 | 270k | aPropSet.setProperties( rTextParagraphPropertyMap ); |
290 | 270k | pTextParagraphPropertiesPtr->getTextCharacterProperties().pushToPropSet( aPropSet, rFilter ); |
291 | 270k | } |
292 | | |
293 | | void SlidePersist::applyTextStyles( const XmlFilterBase& rFilterBase ) |
294 | 21.6k | { |
295 | 21.6k | if ( !mbMaster ) |
296 | 4.78k | return; |
297 | | |
298 | 16.9k | try |
299 | 16.9k | { |
300 | 16.9k | Reference< style::XStyleFamiliesSupplier > aXStyleFamiliesSupplier( rFilterBase.getModel(), UNO_QUERY_THROW ); |
301 | 16.9k | Reference< container::XNameAccess > aXNameAccess( aXStyleFamiliesSupplier->getStyleFamilies() ); |
302 | 16.9k | Reference< container::XNamed > aXNamed( mxPage, UNO_QUERY_THROW ); |
303 | | |
304 | 16.9k | if ( aXNameAccess.is() ) |
305 | 16.9k | { |
306 | 16.9k | oox::drawingml::TextListStylePtr pTextListStylePtr; |
307 | 16.9k | OUString aStyle; |
308 | 16.9k | OUString aFamily; |
309 | | |
310 | 16.9k | static constexpr OUStringLiteral sOutline( u"outline1" ); |
311 | 16.9k | static constexpr OUString sTitle( u"title"_ustr ); |
312 | 16.9k | static constexpr OUStringLiteral sStandard( u"standard" ); |
313 | 16.9k | static constexpr OUStringLiteral sSubtitle( u"subtitle" ); |
314 | | |
315 | 84.5k | for( int i = 0; i < 4; i++ ) // todo: aggregation of bodystyle (subtitle) |
316 | 67.6k | { |
317 | 67.6k | switch( i ) |
318 | 67.6k | { |
319 | 16.9k | case 0 : // title style |
320 | 16.9k | { |
321 | 16.9k | pTextListStylePtr = maTitleTextStylePtr; |
322 | 16.9k | aStyle = sTitle; |
323 | 16.9k | aFamily= aXNamed->getName(); |
324 | 16.9k | break; |
325 | 0 | } |
326 | 16.9k | case 1 : // body style |
327 | 16.9k | { |
328 | 16.9k | pTextListStylePtr = maBodyTextStylePtr; |
329 | 16.9k | aStyle = sOutline; |
330 | 16.9k | aFamily= aXNamed->getName(); |
331 | 16.9k | break; |
332 | 0 | } |
333 | 16.9k | case 3 : // notes style |
334 | 16.9k | { |
335 | 16.9k | pTextListStylePtr = maNotesTextStylePtr; |
336 | 16.9k | aStyle = sTitle; |
337 | 16.9k | aFamily= aXNamed->getName(); |
338 | 16.9k | break; |
339 | 0 | } |
340 | 0 | case 4 : // standard style |
341 | 0 | { |
342 | 0 | pTextListStylePtr = maOtherTextStylePtr; |
343 | 0 | aStyle = sStandard; |
344 | 0 | aFamily = "graphics"; |
345 | 0 | break; |
346 | 0 | } |
347 | 0 | case 5 : // subtitle |
348 | 0 | { |
349 | 0 | pTextListStylePtr = maBodyTextStylePtr; |
350 | 0 | aStyle = sSubtitle; |
351 | 0 | aFamily = aXNamed->getName(); |
352 | 0 | break; |
353 | 0 | } |
354 | 67.6k | } |
355 | 67.6k | Reference< container::XNameAccess > xFamilies; |
356 | 67.6k | if ( aXNameAccess->hasByName( aFamily ) ) |
357 | 67.6k | { |
358 | 67.6k | if( aXNameAccess->getByName( aFamily ) >>= xFamilies ) |
359 | 67.6k | { |
360 | 67.6k | if ( xFamilies->hasByName( aStyle ) ) |
361 | 67.6k | { |
362 | 67.6k | Reference< style::XStyle > aXStyle; |
363 | 67.6k | if ( xFamilies->getByName( aStyle ) >>= aXStyle ) |
364 | 67.6k | { |
365 | 67.6k | Reference< beans::XPropertySet > xPropSet( aXStyle, UNO_QUERY_THROW ); |
366 | 67.6k | setTextStyle( xPropSet, rFilterBase, maDefaultTextStylePtr, 0 ); |
367 | 67.6k | setTextStyle( xPropSet, rFilterBase, pTextListStylePtr, 0 ); |
368 | 67.6k | if ( i == 1 /* BodyStyle */ ) |
369 | 16.9k | { |
370 | 84.5k | for ( int nLevel = 1; nLevel < 5; nLevel++ ) |
371 | 67.6k | { |
372 | 67.6k | { |
373 | 67.6k | char pOutline[ 9 ] = "outline1"; |
374 | 67.6k | pOutline[ 7 ] = static_cast< char >( '0' + nLevel ); |
375 | 67.6k | OUString sOutlineStyle( OUString::createFromAscii( pOutline ) ); |
376 | 67.6k | if ( xFamilies->hasByName( sOutlineStyle ) ) |
377 | 67.6k | { |
378 | 67.6k | xFamilies->getByName( sOutlineStyle ) >>= aXStyle; |
379 | 67.6k | if( aXStyle.is() ) |
380 | 67.6k | xPropSet.set( aXStyle, UNO_QUERY_THROW ); |
381 | 67.6k | } |
382 | 67.6k | } |
383 | 67.6k | setTextStyle( xPropSet, rFilterBase, maDefaultTextStylePtr, nLevel ); |
384 | 67.6k | setTextStyle( xPropSet, rFilterBase, pTextListStylePtr, nLevel ); |
385 | 67.6k | } |
386 | 16.9k | } |
387 | 67.6k | } |
388 | 67.6k | } |
389 | 67.6k | } |
390 | 67.6k | } |
391 | 67.6k | } |
392 | 16.9k | } |
393 | 16.9k | } |
394 | 16.9k | catch( const Exception& ) |
395 | 16.9k | { |
396 | 0 | } |
397 | 16.9k | } |
398 | | |
399 | | void SlidePersist::hideShapesAsMasterShapes() |
400 | 5 | { |
401 | 5 | std::vector< oox::drawingml::ShapePtr >& rShapes( maShapesPtr->getChildren() ); |
402 | 5 | for (auto const& shape : rShapes) |
403 | 3 | { |
404 | 3 | std::vector< oox::drawingml::ShapePtr >& rChildren( shape->getChildren() ); |
405 | 3 | for (auto const& child : rChildren) |
406 | 0 | { |
407 | 0 | PPTShape* pPPTShape = dynamic_cast< PPTShape* >( child.get() ); |
408 | 0 | if (!pPPTShape) |
409 | 0 | continue; |
410 | 0 | pPPTShape->setHiddenMasterShape( true ); |
411 | 0 | } |
412 | 3 | } |
413 | 5 | } |
414 | | |
415 | | // This angle determines in the direction of the line |
416 | | static sal_Int32 lcl_GetAngle(const uno::Reference<drawing::XShape>& rXShape, const awt::Point& rPt) |
417 | 0 | { |
418 | 0 | SdrObject* pObj = SdrObject::getSdrObjectFromXShape(rXShape); |
419 | 0 | tools::Rectangle aR(pObj->GetSnapRect()); |
420 | 0 | sal_Int32 nLeftX = rPt.X - aR.Left(); |
421 | 0 | sal_Int32 nTopY = rPt.Y - aR.Top(); |
422 | 0 | sal_Int32 nRightX = aR.Right() - rPt.X; |
423 | 0 | sal_Int32 nBottomY = aR.Bottom() - rPt.Y; |
424 | 0 | sal_Int32 nX = std::min(nLeftX, nRightX); |
425 | 0 | sal_Int32 nY = std::min(nTopY, nBottomY); |
426 | |
|
427 | 0 | sal_Int32 nAngle; |
428 | 0 | if (nX < nY) |
429 | 0 | { |
430 | 0 | if (nLeftX < nRightX) |
431 | 0 | nAngle = 180; // Left |
432 | 0 | else |
433 | 0 | nAngle = 0; // Right |
434 | 0 | } |
435 | 0 | else |
436 | 0 | { |
437 | 0 | if (nTopY < nBottomY) |
438 | 0 | nAngle = 270; // Top |
439 | 0 | else |
440 | 0 | nAngle = 90; // Bottom |
441 | 0 | } |
442 | 0 | return nAngle; |
443 | 0 | } |
444 | | |
445 | | Reference<XAnimationNode> SlidePersist::getAnimationNode(const OUString& sId) const |
446 | 52 | { |
447 | 52 | const auto pIter = maAnimNodesMap.find(sId); |
448 | 52 | if (pIter != maAnimNodesMap.end()) |
449 | 52 | return pIter->second; |
450 | | |
451 | 0 | Reference<XAnimationNode> aResult; |
452 | 0 | return aResult; |
453 | 52 | } |
454 | | |
455 | | static void lcl_SetEdgeLineValue(const uno::Reference<drawing::XShape>& rXConnector, |
456 | | const oox::drawingml::ShapePtr& rShapePtr) |
457 | 0 | { |
458 | 0 | sal_Int32 nEdge = 0; |
459 | 0 | awt::Point aStartPt, aEndPt; |
460 | 0 | tools::Rectangle aS, aE; // Start, End rectangle |
461 | 0 | uno::Reference<drawing::XShape> xStartSp, xEndSp; |
462 | 0 | uno::Reference<beans::XPropertySet> xPropSet(rXConnector, uno::UNO_QUERY); |
463 | 0 | xPropSet->getPropertyValue(u"EdgeStartPoint"_ustr) >>= aStartPt; |
464 | 0 | xPropSet->getPropertyValue(u"EdgeEndPoint"_ustr) >>= aEndPt; |
465 | 0 | xPropSet->getPropertyValue(u"StartShape"_ustr) >>= xStartSp; |
466 | 0 | xPropSet->getPropertyValue(u"EndShape"_ustr) >>= xEndSp; |
467 | 0 | xPropSet->setPropertyValue(u"EdgeNode1HorzDist"_ustr, Any(sal_Int32(0))); |
468 | 0 | xPropSet->setPropertyValue(u"EdgeNode1VertDist"_ustr, Any(sal_Int32(0))); |
469 | 0 | xPropSet->setPropertyValue(u"EdgeNode2HorzDist"_ustr, Any(sal_Int32(0))); |
470 | 0 | xPropSet->setPropertyValue(u"EdgeNode2VertDist"_ustr, Any(sal_Int32(0))); |
471 | |
|
472 | 0 | SdrObject* pStartObj = xStartSp.is() ? SdrObject::getSdrObjectFromXShape(xStartSp) : nullptr; |
473 | 0 | SdrObject* pEndObj = xEndSp.is() ? SdrObject::getSdrObjectFromXShape(xEndSp) : nullptr; |
474 | |
|
475 | 0 | sal_Int32 nStartA = -1; |
476 | 0 | sal_Int32 nEndA = -1; |
477 | 0 | if (pStartObj) |
478 | 0 | { |
479 | 0 | aS = pStartObj->GetSnapRect(); |
480 | 0 | nStartA = lcl_GetAngle(xStartSp, aStartPt); |
481 | 0 | } |
482 | 0 | if (pEndObj) |
483 | 0 | { |
484 | 0 | aE = pEndObj->GetSnapRect(); |
485 | 0 | nEndA = lcl_GetAngle(xEndSp, aEndPt); |
486 | 0 | } |
487 | |
|
488 | 0 | const OUString sConnectorName = rShapePtr->getConnectorName(); |
489 | 0 | if (sConnectorName == "bentConnector2") |
490 | 0 | { |
491 | 0 | awt::Size aConnSize = rXConnector->getSize(); |
492 | 0 | if (xStartSp.is() || xEndSp.is()) |
493 | 0 | { |
494 | 0 | if (nStartA >= 0) |
495 | 0 | { |
496 | 0 | switch (nStartA) |
497 | 0 | { |
498 | 0 | case 0: nEdge = aEndPt.X - aS.Right(); break; |
499 | 0 | case 180: nEdge = aEndPt.X - aS.Left(); break; |
500 | 0 | case 90: nEdge = aEndPt.Y - aS.Bottom(); break; |
501 | 0 | case 270: nEdge = aEndPt.Y - aS.Top(); break; |
502 | 0 | } |
503 | 0 | } |
504 | 0 | else |
505 | 0 | { |
506 | 0 | switch (nEndA) |
507 | 0 | { |
508 | 0 | case 0: nEdge = aStartPt.X - aE.Right(); break; |
509 | 0 | case 180: nEdge = aStartPt.X - aE.Left(); break; |
510 | 0 | case 90: nEdge = aStartPt.Y - aE.Bottom(); break; |
511 | 0 | case 270: nEdge = aStartPt.Y - aE.Top(); break; |
512 | 0 | } |
513 | 0 | } |
514 | 0 | } |
515 | 0 | else |
516 | 0 | { |
517 | 0 | bool bFlipH = rShapePtr->getFlipH(); |
518 | 0 | bool bFlipV = rShapePtr->getFlipV(); |
519 | 0 | sal_Int32 nConnectorAngle = rShapePtr->getRotation() / 60000; |
520 | 0 | if (aConnSize.Height < aConnSize.Width) |
521 | 0 | { |
522 | 0 | if ((nConnectorAngle == 90 && bFlipH && bFlipV) || (nConnectorAngle == 180) |
523 | 0 | || (nConnectorAngle == 270 && bFlipH)) |
524 | 0 | nEdge -= aConnSize.Width; |
525 | 0 | else |
526 | 0 | nEdge += aConnSize.Width; |
527 | 0 | } |
528 | 0 | else |
529 | 0 | { |
530 | 0 | if ((nConnectorAngle == 180 && bFlipV) || (nConnectorAngle == 270 && bFlipV) |
531 | 0 | || (nConnectorAngle == 90 && bFlipH && bFlipV) |
532 | 0 | || (nConnectorAngle == 0 && !bFlipV)) |
533 | 0 | nEdge -= aConnSize.Height; |
534 | 0 | else |
535 | 0 | nEdge += aConnSize.Height; |
536 | 0 | } |
537 | 0 | } |
538 | 0 | xPropSet->setPropertyValue(u"EdgeLine1Delta"_ustr, Any(nEdge / 2)); |
539 | 0 | } |
540 | 0 | } |
541 | | |
542 | | // create connection between two shape with a connector shape. |
543 | | void SlidePersist::createConnectorShapeConnection(const oox::drawingml::ShapePtr& pConnector) |
544 | 159 | { |
545 | 159 | oox::drawingml::ConnectorShapePropertiesList aConnectorShapeProperties |
546 | 159 | = pConnector->getConnectorShapeProperties(); |
547 | 159 | uno::Reference<drawing::XShape> xConnector(pConnector->getXShape(), uno::UNO_QUERY); |
548 | 159 | uno::Reference<beans::XPropertySet> xPropertySet(xConnector, uno::UNO_QUERY); |
549 | | |
550 | 159 | if (xConnector.is()) |
551 | 159 | { |
552 | 159 | sal_Int32 nCount = aConnectorShapeProperties.size(); |
553 | 181 | for (sal_Int32 j = 0; j < nCount; j++) |
554 | 22 | { |
555 | 22 | OUString aDestShapeId = aConnectorShapeProperties[j].maDestShapeId; |
556 | 22 | const auto pShape = maShapeMap.find(aDestShapeId); |
557 | 22 | if (pShape == maShapeMap.end()) |
558 | 0 | continue; |
559 | 22 | uno::Reference<drawing::XShape> xShape(pShape->second->getXShape(), uno::UNO_QUERY); |
560 | 22 | if (xShape.is()) |
561 | 22 | { |
562 | 22 | uno::Reference<drawing::XGluePointsSupplier> xSupplier(xShape, uno::UNO_QUERY); |
563 | 22 | css::uno::Reference<css::container::XIdentifierContainer> xGluePoints( |
564 | 22 | xSupplier->getGluePoints(), uno::UNO_QUERY); |
565 | | |
566 | 22 | sal_Int32 nCountGluePoints = xGluePoints->getIdentifiers().getLength(); |
567 | 22 | sal_Int32 nGlueId = aConnectorShapeProperties[j].mnDestGlueId; |
568 | | |
569 | | // The first 4 glue points belong to the bounding box. |
570 | 22 | if (nCountGluePoints > 4) |
571 | 0 | nGlueId += 4; |
572 | 22 | else |
573 | 22 | { |
574 | 22 | bool bFlipH = pShape->second->getFlipH(); |
575 | 22 | bool bFlipV = pShape->second->getFlipV(); |
576 | 22 | if ((!bFlipH && !bFlipV) || (bFlipH && bFlipV)) |
577 | 22 | { |
578 | | // change id of the left and right glue points of the bounding box (1 <-> 3) |
579 | 22 | if (nGlueId == 1) |
580 | 7 | nGlueId = 3; // Right |
581 | 15 | else if (nGlueId == 3) |
582 | 15 | nGlueId = 1; // Left |
583 | 22 | } |
584 | 22 | } |
585 | | |
586 | 22 | bool bStart = aConnectorShapeProperties[j].mbStartShape; |
587 | 22 | if (bStart) |
588 | 11 | { |
589 | 11 | xPropertySet->setPropertyValue(u"StartShape"_ustr, uno::Any(xShape)); |
590 | 11 | xPropertySet->setPropertyValue(u"StartGluePointIndex"_ustr, uno::Any(nGlueId)); |
591 | 11 | } |
592 | 11 | else |
593 | 11 | { |
594 | 11 | xPropertySet->setPropertyValue(u"EndShape"_ustr, uno::Any(xShape)); |
595 | 11 | xPropertySet->setPropertyValue(u"EndGluePointIndex"_ustr, uno::Any(nGlueId)); |
596 | 11 | } |
597 | 22 | } |
598 | 22 | } |
599 | 159 | uno::Reference<beans::XPropertySetInfo> xPropInfo = xPropertySet->getPropertySetInfo(); |
600 | 159 | if (xPropInfo->hasPropertyByName(u"EdgeKind"_ustr)) |
601 | 159 | { |
602 | 159 | ConnectorType aConnectorType; |
603 | 159 | xPropertySet->getPropertyValue(u"EdgeKind"_ustr) >>= aConnectorType; |
604 | 159 | if (aConnectorType == ConnectorType_STANDARD) |
605 | 0 | lcl_SetEdgeLineValue(xConnector, pConnector); |
606 | 159 | } |
607 | 159 | } |
608 | 159 | } |
609 | | |
610 | | } |
611 | | |
612 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |