tdf#130857 qt weld: Support mail merge "Server Auth" dialog
[LibreOffice.git] / svx / source / customshapes / EnhancedCustomShapeEngine.cxx
blob13155cb681d4143a192b34df31cc422ddf0d1409
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <com/sun/star/uno/Reference.h>
21 #include <com/sun/star/uno/XComponentContext.hpp>
22 #include <com/sun/star/awt/Rectangle.hpp>
23 #include <com/sun/star/beans/PropertyValue.hpp>
24 #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
25 #include <com/sun/star/lang/XInitialization.hpp>
26 #include <com/sun/star/lang/XServiceInfo.hpp>
27 #include <com/sun/star/drawing/XCustomShapeEngine.hpp>
28 #include <svx/EnhancedCustomShape2d.hxx>
29 #include "EnhancedCustomShape3d.hxx"
30 #include "EnhancedCustomShapeFontWork.hxx"
31 #include "EnhancedCustomShapeHandle.hxx"
32 #include <svx/unoshape.hxx>
33 #include <svx/unopage.hxx>
34 #include <svx/svdobj.hxx>
35 #include <svx/svdoashp.hxx>
36 #include <svx/svdogrp.hxx>
37 #include <editeng/outlobj.hxx>
38 #include <svl/itemset.hxx>
39 #include <svx/svdopath.hxx>
40 #include <svx/svdpage.hxx>
41 #include <svx/svditer.hxx>
42 #include <svx/xfillit0.hxx>
43 #include <svx/xlineit0.hxx>
44 #include <basegfx/polygon/b2dpolypolygontools.hxx>
45 #include <com/sun/star/document/XActionLockable.hpp>
46 #include <cppuhelper/implbase.hxx>
47 #include <cppuhelper/supportsservice.hxx>
49 using namespace css;
50 using namespace css::uno;
52 class SdrObject;
53 class SdrObjCustomShape;
55 namespace {
57 class EnhancedCustomShapeEngine : public cppu::WeakImplHelper
59 css::lang::XInitialization,
60 css::lang::XServiceInfo,
61 css::drawing::XCustomShapeEngine
64 css::uno::Reference< css::drawing::XShape > mxShape;
65 bool mbForceGroupWithText;
67 rtl::Reference<SdrObject> ImplForceGroupWithText(
68 const SdrObjCustomShape& rSdrObjCustomShape,
69 SdrObject* pRenderedShape);
71 public:
72 EnhancedCustomShapeEngine();
74 // XInterface
75 virtual void SAL_CALL acquire() noexcept override;
76 virtual void SAL_CALL release() noexcept override;
78 // XInitialization
79 virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) override;
81 // XServiceInfo
82 virtual OUString SAL_CALL getImplementationName() override;
83 virtual sal_Bool SAL_CALL supportsService( const OUString& rServiceName ) override;
84 virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
86 // XCustomShapeEngine
87 virtual css::uno::Reference< css::drawing::XShape > SAL_CALL render() override;
88 virtual css::awt::Rectangle SAL_CALL getTextBounds() override;
89 virtual css::drawing::PolyPolygonBezierCoords SAL_CALL getLineGeometry() override;
90 virtual css::uno::Sequence< css::uno::Reference< css::drawing::XCustomShapeHandle > > SAL_CALL getInteraction() override;
93 EnhancedCustomShapeEngine::EnhancedCustomShapeEngine() :
94 mbForceGroupWithText ( false )
98 // XInterface
99 void SAL_CALL EnhancedCustomShapeEngine::acquire() noexcept
101 OWeakObject::acquire();
103 void SAL_CALL EnhancedCustomShapeEngine::release() noexcept
105 OWeakObject::release();
108 // XInitialization
109 void SAL_CALL EnhancedCustomShapeEngine::initialize( const Sequence< Any >& aArguments )
111 Sequence< beans::PropertyValue > aParameter;
112 for ( const auto& rArgument : aArguments )
114 if ( rArgument >>= aParameter )
115 break;
117 for (const beans::PropertyValue& rProp : aParameter)
119 if ( rProp.Name == "CustomShape" )
120 rProp.Value >>= mxShape;
121 else if ( rProp.Name == "ForceGroupWithText" )
122 rProp.Value >>= mbForceGroupWithText;
126 // XServiceInfo
127 OUString SAL_CALL EnhancedCustomShapeEngine::getImplementationName()
129 return u"com.sun.star.drawing.EnhancedCustomShapeEngine"_ustr;
131 sal_Bool SAL_CALL EnhancedCustomShapeEngine::supportsService( const OUString& rServiceName )
133 return cppu::supportsService(this, rServiceName);
135 Sequence< OUString > SAL_CALL EnhancedCustomShapeEngine::getSupportedServiceNames()
137 return { u"com.sun.star.drawing.CustomShapeEngine"_ustr };
140 // XCustomShapeEngine
141 rtl::Reference<SdrObject> EnhancedCustomShapeEngine::ImplForceGroupWithText(
142 const SdrObjCustomShape& rSdrObjCustomShape,
143 SdrObject* pRenderedShape1)
145 rtl::Reference<SdrObject> pRenderedShape = pRenderedShape1;
146 const bool bHasText(rSdrObjCustomShape.HasText());
148 if ( pRenderedShape || bHasText )
150 // applying shadow
151 const SdrObject* pShadowGeometry(rSdrObjCustomShape.GetSdrObjectShadowFromCustomShape());
153 if ( pShadowGeometry )
155 if ( pRenderedShape )
157 if ( dynamic_cast<const SdrObjGroup*>( pRenderedShape.get() ) == nullptr )
159 auto pTmp = std::move(pRenderedShape);
160 pRenderedShape = new SdrObjGroup(rSdrObjCustomShape.getSdrModelFromSdrObject());
161 static_cast<SdrObjGroup*>(pRenderedShape.get())->GetSubList()->NbcInsertObject( pTmp.get() );
164 static_cast<SdrObjGroup*>(pRenderedShape.get())->GetSubList()->NbcInsertObject(
165 pShadowGeometry->CloneSdrObject(pShadowGeometry->getSdrModelFromSdrObject()).get(),
168 else
170 pRenderedShape = pShadowGeometry->CloneSdrObject(pShadowGeometry->getSdrModelFromSdrObject());
174 // apply text
175 if ( bHasText )
177 // #i37011# also create a text object and add at rPos + 1
178 rtl::Reference<SdrObject> pTextObj( SdrObjFactory::MakeNewObject(
179 rSdrObjCustomShape.getSdrModelFromSdrObject(),
180 rSdrObjCustomShape.GetObjInventor(),
181 SdrObjKind::Text) );
183 // Copy text content
184 OutlinerParaObject* pParaObj(rSdrObjCustomShape.GetOutlinerParaObject());
186 if( pParaObj )
187 pTextObj->NbcSetOutlinerParaObject( *pParaObj );
189 // copy all attributes
190 SfxItemSet aTargetItemSet(rSdrObjCustomShape.GetMergedItemSet());
192 // clear fill and line style
193 aTargetItemSet.Put(XLineStyleItem(drawing::LineStyle_NONE));
194 aTargetItemSet.Put(XFillStyleItem(drawing::FillStyle_NONE));
196 // get the text bounds and set at text object
197 tools::Rectangle aTextBounds(rSdrObjCustomShape.GetSnapRect());
198 auto pSdrObjCustomShape = dynamic_cast< SdrObjCustomShape* >(SdrObject::getSdrObjectFromXShape(mxShape));
200 if(pSdrObjCustomShape)
202 EnhancedCustomShape2d aCustomShape2d(*pSdrObjCustomShape);
203 aTextBounds = aCustomShape2d.GetTextRect();
206 pTextObj->SetSnapRect( aTextBounds );
208 // if rotated, copy GeoStat, too.
209 const GeoStat& rSourceGeo(rSdrObjCustomShape.GetGeoStat());
210 if ( rSourceGeo.m_nRotationAngle )
212 pTextObj->NbcRotate(
213 rSdrObjCustomShape.GetSnapRect().Center(),
214 rSourceGeo.m_nRotationAngle,
215 rSourceGeo.mfSinRotationAngle,
216 rSourceGeo.mfCosRotationAngle);
219 // set modified ItemSet at text object
220 pTextObj->SetMergedItemSet(aTargetItemSet);
222 if ( pRenderedShape )
224 if ( dynamic_cast<const SdrObjGroup*>( pRenderedShape.get() ) == nullptr )
226 auto pTmp = std::move(pRenderedShape);
227 pRenderedShape = new SdrObjGroup(rSdrObjCustomShape.getSdrModelFromSdrObject());
228 static_cast<SdrObjGroup*>(pRenderedShape.get())->GetSubList()->NbcInsertObject( pTmp.get() );
230 static_cast<SdrObjGroup*>(pRenderedShape.get())->GetSubList()->NbcInsertObject( pTextObj.get() );
232 else
233 pRenderedShape = std::move(pTextObj);
236 // force group
237 if ( pRenderedShape )
239 if ( dynamic_cast<const SdrObjGroup*>( pRenderedShape.get() ) == nullptr )
241 auto pTmp = std::move(pRenderedShape);
242 pRenderedShape = new SdrObjGroup(rSdrObjCustomShape.getSdrModelFromSdrObject());
243 static_cast<SdrObjGroup*>(pRenderedShape.get())->GetSubList()->NbcInsertObject( pTmp.get() );
248 return pRenderedShape;
251 Reference< drawing::XShape > SAL_CALL EnhancedCustomShapeEngine::render()
253 SdrObjCustomShape* pSdrObjCustomShape = dynamic_cast< SdrObjCustomShape* >(SdrObject::getSdrObjectFromXShape(mxShape));
255 if(!pSdrObjCustomShape)
257 return Reference< drawing::XShape >();
260 // retrieving the TextPath property to check if feature is enabled
261 const SdrCustomShapeGeometryItem& rGeometryItem(pSdrObjCustomShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ));
262 bool bTextPathOn = false;
263 const uno::Any* pAny = rGeometryItem.GetPropertyValueByName( u"TextPath"_ustr, u"TextPath"_ustr );
264 if ( pAny )
265 *pAny >>= bTextPathOn;
267 EnhancedCustomShape2d aCustomShape2d(*pSdrObjCustomShape);
268 Degree100 nRotateAngle = aCustomShape2d.GetRotateAngle();
270 bool bFlipV = aCustomShape2d.IsFlipVert();
271 bool bFlipH = aCustomShape2d.IsFlipHorz();
272 bool bLineGeometryNeededOnly = bTextPathOn;
274 rtl::Reference<SdrObject> xRenderedShape(aCustomShape2d.CreateObject(bLineGeometryNeededOnly));
275 if (xRenderedShape)
277 if ( bTextPathOn )
279 rtl::Reference<SdrObject> xRenderedFontWork(
280 EnhancedCustomShapeFontWork::CreateFontWork(
281 xRenderedShape.get(),
282 *pSdrObjCustomShape));
284 if (xRenderedFontWork)
286 xRenderedShape = std::move(xRenderedFontWork);
289 rtl::Reference<SdrObject> xRenderedShape3d(EnhancedCustomShape3d::Create3DObject(xRenderedShape.get(), *pSdrObjCustomShape));
290 if (xRenderedShape3d)
292 bFlipV = bFlipH = false;
293 nRotateAngle = 0_deg100;
294 xRenderedShape = std::move(xRenderedShape3d);
297 tools::Rectangle aRect(pSdrObjCustomShape->GetSnapRect());
298 const GeoStat& rGeoStat(pSdrObjCustomShape->GetGeoStat());
300 if ( rGeoStat.m_nShearAngle )
302 Degree100 nShearAngle = rGeoStat.m_nShearAngle;
303 double nTan = rGeoStat.mfTanShearAngle;
304 if (bFlipV != bFlipH)
306 nShearAngle = -nShearAngle;
307 nTan = -nTan;
310 xRenderedShape->Shear(pSdrObjCustomShape->GetSnapRect().Center(), nShearAngle, nTan, false);
312 if(nRotateAngle )
313 xRenderedShape->NbcRotate(pSdrObjCustomShape->GetSnapRect().Center(), nRotateAngle);
314 if ( bFlipV )
316 Point aLeft( aRect.Left(), ( aRect.Top() + aRect.Bottom() ) >> 1 );
317 Point aRight( aLeft.X() + 1000, aLeft.Y() );
318 xRenderedShape->NbcMirror( aLeft, aRight );
320 if ( bFlipH )
322 Point aTop( ( aRect.Left() + aRect.Right() ) >> 1, aRect.Top() );
323 Point aBottom( aTop.X(), aTop.Y() + 1000 );
324 xRenderedShape->NbcMirror( aTop, aBottom );
327 xRenderedShape->NbcSetStyleSheet(pSdrObjCustomShape->GetStyleSheet(), true);
328 xRenderedShape->RecalcSnapRect();
331 if ( mbForceGroupWithText )
333 xRenderedShape = ImplForceGroupWithText(
334 *pSdrObjCustomShape,
335 xRenderedShape.get());
338 Reference< drawing::XShape > xShape;
340 if (xRenderedShape)
342 aCustomShape2d.ApplyGluePoints(xRenderedShape.get());
343 xShape = SvxDrawPage::CreateShapeByTypeAndInventor( xRenderedShape->GetObjIdentifier(),
344 xRenderedShape->GetObjInventor(), xRenderedShape.get() );
347 return xShape;
350 awt::Rectangle SAL_CALL EnhancedCustomShapeEngine::getTextBounds()
352 awt::Rectangle aTextRect;
353 if (SdrObjCustomShape* pSdrObjCustomShape = dynamic_cast< SdrObjCustomShape* >(SdrObject::getSdrObjectFromXShape(mxShape)))
355 uno::Reference< document::XActionLockable > xLockable( mxShape, uno::UNO_QUERY );
357 if(xLockable.is() && !xLockable->isActionLocked())
359 EnhancedCustomShape2d aCustomShape2d(*pSdrObjCustomShape);
360 tools::Rectangle aRect( aCustomShape2d.GetTextRect() );
361 aTextRect.X = aRect.Left();
362 aTextRect.Y = aRect.Top();
363 aTextRect.Width = aRect.GetWidth();
364 aTextRect.Height = aRect.GetHeight();
368 return aTextRect;
371 drawing::PolyPolygonBezierCoords SAL_CALL EnhancedCustomShapeEngine::getLineGeometry()
373 drawing::PolyPolygonBezierCoords aPolyPolygonBezierCoords;
374 SdrObjCustomShape* pSdrObjCustomShape = dynamic_cast< SdrObjCustomShape* >(SdrObject::getSdrObjectFromXShape(mxShape));
376 if(pSdrObjCustomShape)
378 EnhancedCustomShape2d aCustomShape2d(*pSdrObjCustomShape);
379 rtl::Reference<SdrObject> pObj = aCustomShape2d.CreateLineGeometry();
381 if ( pObj )
383 tools::Rectangle aRect(pSdrObjCustomShape->GetSnapRect());
384 bool bFlipV = aCustomShape2d.IsFlipVert();
385 bool bFlipH = aCustomShape2d.IsFlipHorz();
386 const GeoStat& rGeoStat(pSdrObjCustomShape->GetGeoStat());
388 if ( rGeoStat.m_nShearAngle )
390 Degree100 nShearAngle = rGeoStat.m_nShearAngle;
391 double nTan = rGeoStat.mfTanShearAngle;
392 if (bFlipV != bFlipH)
394 nShearAngle = -nShearAngle;
395 nTan = -nTan;
397 pObj->Shear( aRect.Center(), nShearAngle, nTan, false);
399 Degree100 nRotateAngle = aCustomShape2d.GetRotateAngle();
400 if( nRotateAngle )
401 pObj->NbcRotate( aRect.Center(), nRotateAngle );
402 if ( bFlipH )
404 Point aTop( ( aRect.Left() + aRect.Right() ) >> 1, aRect.Top() );
405 Point aBottom( aTop.X(), aTop.Y() + 1000 );
406 pObj->NbcMirror( aTop, aBottom );
408 if ( bFlipV )
410 Point aLeft( aRect.Left(), ( aRect.Top() + aRect.Bottom() ) >> 1 );
411 Point aRight( aLeft.X() + 1000, aLeft.Y() );
412 pObj->NbcMirror( aLeft, aRight );
415 basegfx::B2DPolyPolygon aPolyPolygon;
416 SdrObjListIter aIter( *pObj, SdrIterMode::DeepWithGroups );
418 while ( aIter.IsMore() )
420 basegfx::B2DPolyPolygon aPP;
421 const SdrObject* pNext = aIter.Next();
423 if ( auto pPathObj = dynamic_cast<const SdrPathObj*>(pNext) )
425 aPP = pPathObj->GetPathPoly();
427 else
429 rtl::Reference<SdrObject> pNewObj = pNext->ConvertToPolyObj( false, false );
430 SdrPathObj* pPath = dynamic_cast<SdrPathObj*>( pNewObj.get() );
431 if ( pPath )
432 aPP = pPath->GetPathPoly();
435 if ( aPP.count() )
436 aPolyPolygon.append(aPP);
438 pObj.clear();
439 basegfx::utils::B2DPolyPolygonToUnoPolyPolygonBezierCoords( aPolyPolygon,
440 aPolyPolygonBezierCoords );
444 return aPolyPolygonBezierCoords;
447 Sequence< Reference< drawing::XCustomShapeHandle > > SAL_CALL EnhancedCustomShapeEngine::getInteraction()
449 sal_uInt32 i, nHdlCount = 0;
450 SdrObjCustomShape* pSdrObjCustomShape = dynamic_cast< SdrObjCustomShape* >(SdrObject::getSdrObjectFromXShape(mxShape));
452 if(pSdrObjCustomShape)
454 EnhancedCustomShape2d aCustomShape2d(*pSdrObjCustomShape);
455 nHdlCount = aCustomShape2d.GetHdlCount();
458 Sequence< Reference< drawing::XCustomShapeHandle > > aSeq( nHdlCount );
459 auto aSeqRange = asNonConstRange(aSeq);
461 for ( i = 0; i < nHdlCount; i++ )
462 aSeqRange[ i ] = new EnhancedCustomShapeHandle( mxShape, i );
463 return aSeq;
468 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
469 com_sun_star_drawing_EnhancedCustomShapeEngine_get_implementation(
470 css::uno::XComponentContext *,
471 css::uno::Sequence<css::uno::Any> const &)
473 return cppu::acquire(new EnhancedCustomShapeEngine);
476 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */