1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
22 #include <XPropertyTable.hxx>
23 #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
24 #include <com/sun/star/drawing/LineDash.hpp>
25 #include <com/sun/star/awt/Gradient.hpp>
26 #include <com/sun/star/awt/XBitmap.hpp>
27 #include <com/sun/star/graphic/XGraphic.hpp>
28 #include <com/sun/star/drawing/Hatch.hpp>
29 #include <com/sun/star/lang/XServiceInfo.hpp>
30 #include <com/sun/star/container/XNameContainer.hpp>
31 #include <o3tl/any.hxx>
32 #include <vcl/svapp.hxx>
34 #include <cppuhelper/implbase.hxx>
35 #include <cppuhelper/supportsservice.hxx>
36 #include <svx/xdef.hxx>
38 #include <svx/unoapi.hxx>
39 #include <basegfx/polygon/b2dpolypolygontools.hxx>
40 #include <docmodel/uno/UnoGradientTools.hxx>
42 using namespace com::sun::star
;
43 using namespace ::cppu
;
47 class SvxUnoXPropertyTable
: public WeakImplHelper
< container::XNameContainer
, lang::XServiceInfo
>
50 XPropertyList
& mrList
;
53 tools::Long
getCount() const { return mrList
.Count(); }
54 const XPropertyEntry
* get(tools::Long index
) const;
56 SvxUnoXPropertyTable( sal_Int16 nWhich
, XPropertyList
& rList
) noexcept
;
58 /// @throws uno::RuntimeException
59 virtual uno::Any
getAny( const XPropertyEntry
* pEntry
) const = 0;
60 /// @throws uno::RuntimeException
61 /// @throws lang::IllegalArgumentException
62 virtual std::unique_ptr
<XPropertyEntry
> createEntry(const OUString
& rName
, const uno::Any
& rAny
) const = 0;
65 virtual sal_Bool SAL_CALL
supportsService( const OUString
& ServiceName
) override
;
68 virtual void SAL_CALL
insertByName( const OUString
& aName
, const uno::Any
& aElement
) override
;
69 virtual void SAL_CALL
removeByName( const OUString
& Name
) override
;
72 virtual void SAL_CALL
replaceByName( const OUString
& aName
, const uno::Any
& aElement
) override
;
75 virtual uno::Any SAL_CALL
getByName( const OUString
& aName
) override
;
76 virtual uno::Sequence
< OUString
> SAL_CALL
getElementNames( ) override
;
77 virtual sal_Bool SAL_CALL
hasByName( const OUString
& aName
) override
;
80 virtual sal_Bool SAL_CALL
hasElements( ) override
;
85 SvxUnoXPropertyTable::SvxUnoXPropertyTable( sal_Int16 nWhich
, XPropertyList
& rList
) noexcept
86 : mrList( rList
), mnWhich( nWhich
)
90 const XPropertyEntry
* SvxUnoXPropertyTable::get(tools::Long index
) const
92 return mrList
.Get(index
);
96 sal_Bool SAL_CALL
SvxUnoXPropertyTable::supportsService( const OUString
& ServiceName
)
98 return cppu::supportsService(this, ServiceName
);
102 void SAL_CALL
SvxUnoXPropertyTable::insertByName( const OUString
& aName
, const uno::Any
& aElement
)
104 SolarMutexGuard aGuard
;
106 if( hasByName( aName
) )
107 throw container::ElementExistException();
109 OUString aInternalName
= SvxUnogetInternalNameForItem(mnWhich
, aName
);
111 std::unique_ptr
<XPropertyEntry
> pNewEntry(createEntry(aInternalName
, aElement
));
113 throw lang::IllegalArgumentException();
115 mrList
.Insert(std::move(pNewEntry
));
118 void SAL_CALL
SvxUnoXPropertyTable::removeByName( const OUString
& Name
)
120 SolarMutexGuard aGuard
;
122 OUString aInternalName
= SvxUnogetInternalNameForItem(mnWhich
, Name
);
124 const tools::Long nCount
= getCount();
126 for( i
= 0; i
< nCount
; i
++ )
128 const XPropertyEntry
* pEntry
= get(i
);
129 if (pEntry
&& aInternalName
== pEntry
->GetName())
136 throw container::NoSuchElementException();
140 void SAL_CALL
SvxUnoXPropertyTable::replaceByName( const OUString
& aName
, const uno::Any
& aElement
)
142 SolarMutexGuard aGuard
;
144 OUString aInternalName
= SvxUnogetInternalNameForItem(mnWhich
, aName
);
146 const tools::Long nCount
= getCount();
148 for( i
= 0; i
< nCount
; i
++ )
150 const XPropertyEntry
* pEntry
= get(i
);
151 if (pEntry
&& aInternalName
== pEntry
->GetName())
153 std::unique_ptr
<XPropertyEntry
> pNewEntry(createEntry(aInternalName
, aElement
));
155 throw lang::IllegalArgumentException();
157 mrList
.Replace(std::move(pNewEntry
), i
);
162 throw container::NoSuchElementException();
166 uno::Any SAL_CALL
SvxUnoXPropertyTable::getByName( const OUString
& aName
)
168 SolarMutexGuard aGuard
;
170 OUString aInternalName
= SvxUnogetInternalNameForItem(mnWhich
, aName
);
172 const tools::Long nCount
= getCount();
174 for( i
= 0; i
< nCount
; i
++ )
176 const XPropertyEntry
* pEntry
= get(i
);
178 if (pEntry
&& aInternalName
== pEntry
->GetName())
179 return getAny( pEntry
);
182 throw container::NoSuchElementException();
185 uno::Sequence
< OUString
> SAL_CALL
SvxUnoXPropertyTable::getElementNames()
187 SolarMutexGuard aGuard
;
189 const tools::Long nCount
= getCount();
190 uno::Sequence
< OUString
> aNames( nCount
);
191 OUString
* pNames
= aNames
.getArray();
193 for( i
= 0; i
< nCount
; i
++ )
195 const XPropertyEntry
* pEntry
= get(i
);
198 *pNames
++ = SvxUnogetApiNameForItem(mnWhich
, pEntry
->GetName());
204 sal_Bool SAL_CALL
SvxUnoXPropertyTable::hasByName( const OUString
& aName
)
206 SolarMutexGuard aGuard
;
208 OUString aInternalName
= SvxUnogetInternalNameForItem(mnWhich
, aName
);
210 const tools::Long nCount
= mrList
.Count();
212 for( i
= 0; i
< nCount
; i
++ )
214 const XPropertyEntry
* pEntry
= get(i
);
215 if (pEntry
&& aInternalName
== pEntry
->GetName())
223 sal_Bool SAL_CALL
SvxUnoXPropertyTable::hasElements( )
225 SolarMutexGuard aGuard
;
227 return getCount() != 0;
232 class SvxUnoXColorTable
: public SvxUnoXPropertyTable
235 explicit SvxUnoXColorTable( XPropertyList
& rList
) noexcept
: SvxUnoXPropertyTable( XATTR_LINECOLOR
, rList
) {};
237 // SvxUnoXPropertyTable
238 virtual uno::Any
getAny( const XPropertyEntry
* pEntry
) const noexcept override
;
239 virtual std::unique_ptr
<XPropertyEntry
> createEntry(const OUString
& rName
, const uno::Any
& rAny
) const override
;
242 virtual uno::Type SAL_CALL
getElementType() override
;
245 virtual OUString SAL_CALL
getImplementationName( ) override
;
246 virtual uno::Sequence
< OUString
> SAL_CALL
getSupportedServiceNames( ) override
;
251 uno::Reference
< container::XNameContainer
> SvxUnoXColorTable_createInstance( XPropertyList
& rList
) noexcept
253 return new SvxUnoXColorTable( rList
);
256 // SvxUnoXPropertyTable
257 uno::Any
SvxUnoXColorTable::getAny( const XPropertyEntry
* pEntry
) const noexcept
259 return uno::Any( static_cast<sal_Int32
>(static_cast<const XColorEntry
*>(pEntry
)->GetColor()) );
262 std::unique_ptr
<XPropertyEntry
> SvxUnoXColorTable::createEntry(const OUString
& rName
, const uno::Any
& rAny
) const
265 if( !(rAny
>>= aColor
) )
266 return std::unique_ptr
<XPropertyEntry
>();
268 return std::make_unique
<XColorEntry
>(aColor
, rName
);
272 uno::Type SAL_CALL
SvxUnoXColorTable::getElementType()
274 return ::cppu::UnoType
<sal_Int32
>::get();
278 OUString SAL_CALL
SvxUnoXColorTable::getImplementationName( )
280 return u
"SvxUnoXColorTable"_ustr
;
283 uno::Sequence
< OUString
> SAL_CALL
SvxUnoXColorTable::getSupportedServiceNames( )
285 return { u
"com.sun.star.drawing.ColorTable"_ustr
};
290 class SvxUnoXLineEndTable
: public SvxUnoXPropertyTable
293 explicit SvxUnoXLineEndTable( XPropertyList
& rTable
) noexcept
: SvxUnoXPropertyTable( XATTR_LINEEND
, rTable
) {};
295 // SvxUnoXPropertyTable
296 virtual uno::Any
getAny( const XPropertyEntry
* pEntry
) const noexcept override
;
297 virtual std::unique_ptr
<XPropertyEntry
> createEntry(const OUString
& rName
, const uno::Any
& rAny
) const override
;
300 virtual uno::Type SAL_CALL
getElementType() override
;
303 virtual OUString SAL_CALL
getImplementationName( ) override
;
304 virtual uno::Sequence
< OUString
> SAL_CALL
getSupportedServiceNames( ) override
;
309 uno::Reference
< container::XNameContainer
> SvxUnoXLineEndTable_createInstance( XPropertyList
& rTable
) noexcept
311 return new SvxUnoXLineEndTable( rTable
);
314 // SvxUnoXPropertyTable
315 uno::Any
SvxUnoXLineEndTable::getAny( const XPropertyEntry
* pEntry
) const noexcept
317 drawing::PolyPolygonBezierCoords aBezier
;
318 basegfx::utils::B2DPolyPolygonToUnoPolyPolygonBezierCoords( static_cast<const XLineEndEntry
*>(pEntry
)->GetLineEnd(),
320 return uno::Any(aBezier
);
323 std::unique_ptr
<XPropertyEntry
> SvxUnoXLineEndTable::createEntry(const OUString
& rName
, const uno::Any
& rAny
) const
325 auto pCoords
= o3tl::tryAccess
<drawing::PolyPolygonBezierCoords
>(rAny
);
327 return std::unique_ptr
<XLineEndEntry
>();
329 basegfx::B2DPolyPolygon aPolyPolygon
;
330 if( pCoords
->Coordinates
.getLength() > 0 )
331 aPolyPolygon
= basegfx::utils::UnoPolyPolygonBezierCoordsToB2DPolyPolygon( *pCoords
);
333 // #86265# make sure polygon is closed
334 aPolyPolygon
.setClosed(true);
336 return std::make_unique
<XLineEndEntry
>(aPolyPolygon
, rName
);
340 uno::Type SAL_CALL
SvxUnoXLineEndTable::getElementType()
342 return cppu::UnoType
<drawing::PolyPolygonBezierCoords
>::get();
346 OUString SAL_CALL
SvxUnoXLineEndTable::getImplementationName( )
348 return u
"SvxUnoXLineEndTable"_ustr
;
351 uno::Sequence
< OUString
> SAL_CALL
SvxUnoXLineEndTable::getSupportedServiceNames( )
353 return { u
"com.sun.star.drawing.LineEndTable"_ustr
};
358 class SvxUnoXDashTable
: public SvxUnoXPropertyTable
361 explicit SvxUnoXDashTable( XPropertyList
& rTable
) noexcept
: SvxUnoXPropertyTable( XATTR_LINEDASH
, rTable
) {};
363 // SvxUnoXPropertyTable
364 virtual uno::Any
getAny( const XPropertyEntry
* pEntry
) const noexcept override
;
365 virtual std::unique_ptr
<XPropertyEntry
> createEntry(const OUString
& rName
, const uno::Any
& rAny
) const override
;
368 virtual uno::Type SAL_CALL
getElementType() override
;
371 virtual OUString SAL_CALL
getImplementationName( ) override
;
372 virtual uno::Sequence
< OUString
> SAL_CALL
getSupportedServiceNames( ) override
;
377 uno::Reference
< container::XNameContainer
> SvxUnoXDashTable_createInstance( XPropertyList
& rTable
) noexcept
379 return new SvxUnoXDashTable( rTable
);
382 // SvxUnoXPropertyTable
383 uno::Any
SvxUnoXDashTable::getAny( const XPropertyEntry
* pEntry
) const noexcept
385 const XDash
& rXD
= static_cast<const XDashEntry
*>(pEntry
)->GetDash();
387 drawing::LineDash aLineDash
;
389 aLineDash
.Style
= static_cast<css::drawing::DashStyle
>(static_cast<sal_uInt16
>(rXD
.GetDashStyle()));
390 aLineDash
.Dots
= rXD
.GetDots();
391 aLineDash
.DotLen
= rXD
.GetDotLen();
392 aLineDash
.Dashes
= rXD
.GetDashes();
393 aLineDash
.DashLen
= rXD
.GetDashLen();
394 aLineDash
.Distance
= rXD
.GetDistance();
396 return uno::Any(aLineDash
);
399 std::unique_ptr
<XPropertyEntry
> SvxUnoXDashTable::createEntry(const OUString
& rName
, const uno::Any
& rAny
) const
401 drawing::LineDash aLineDash
;
402 if(!(rAny
>>= aLineDash
))
403 return std::unique_ptr
<XDashEntry
>();
407 aXDash
.SetDashStyle(static_cast<css::drawing::DashStyle
>(static_cast<sal_uInt16
>(aLineDash
.Style
)));
408 aXDash
.SetDots(aLineDash
.Dots
);
409 aXDash
.SetDotLen(aLineDash
.DotLen
);
410 aXDash
.SetDashes(aLineDash
.Dashes
);
411 aXDash
.SetDashLen(aLineDash
.DashLen
);
412 aXDash
.SetDistance(aLineDash
.Distance
);
414 return std::make_unique
<XDashEntry
>(aXDash
, rName
);
418 uno::Type SAL_CALL
SvxUnoXDashTable::getElementType()
420 return cppu::UnoType
<drawing::LineDash
>::get();
424 OUString SAL_CALL
SvxUnoXDashTable::getImplementationName( )
426 return u
"SvxUnoXDashTable"_ustr
;
429 uno::Sequence
< OUString
> SAL_CALL
SvxUnoXDashTable::getSupportedServiceNames( )
431 return { u
"com.sun.star.drawing.DashTable"_ustr
};
436 class SvxUnoXHatchTable
: public SvxUnoXPropertyTable
439 explicit SvxUnoXHatchTable( XPropertyList
& rTable
) noexcept
: SvxUnoXPropertyTable( XATTR_FILLHATCH
, rTable
) {};
441 // SvxUnoXPropertyTable
442 virtual uno::Any
getAny( const XPropertyEntry
* pEntry
) const noexcept override
;
443 virtual std::unique_ptr
<XPropertyEntry
> createEntry(const OUString
& rName
, const uno::Any
& rAny
) const override
;
446 virtual uno::Type SAL_CALL
getElementType() override
;
449 virtual OUString SAL_CALL
getImplementationName( ) override
;
450 virtual uno::Sequence
< OUString
> SAL_CALL
getSupportedServiceNames( ) override
;
455 uno::Reference
< container::XNameContainer
> SvxUnoXHatchTable_createInstance( XPropertyList
& rTable
) noexcept
457 return new SvxUnoXHatchTable( rTable
);
460 // SvxUnoXPropertyTable
461 uno::Any
SvxUnoXHatchTable::getAny( const XPropertyEntry
* pEntry
) const noexcept
463 const XHatch
& aHatch
= static_cast<const XHatchEntry
*>(pEntry
)->GetHatch();
465 drawing::Hatch aUnoHatch
;
467 aUnoHatch
.Style
= aHatch
.GetHatchStyle();
468 aUnoHatch
.Color
= sal_Int32(aHatch
.GetColor());
469 aUnoHatch
.Distance
= aHatch
.GetDistance();
470 aUnoHatch
.Angle
= aHatch
.GetAngle().get();
472 return uno::Any(aUnoHatch
);
475 std::unique_ptr
<XPropertyEntry
> SvxUnoXHatchTable::createEntry(const OUString
& rName
, const uno::Any
& rAny
) const
477 drawing::Hatch aUnoHatch
;
478 if(!(rAny
>>= aUnoHatch
))
479 return std::unique_ptr
<XHatchEntry
>();
482 aXHatch
.SetHatchStyle( aUnoHatch
.Style
);
483 aXHatch
.SetColor( Color(ColorTransparency
, aUnoHatch
.Color
) );
484 aXHatch
.SetDistance( aUnoHatch
.Distance
);
485 aXHatch
.SetAngle( Degree10(aUnoHatch
.Angle
) );
487 return std::make_unique
<XHatchEntry
>(aXHatch
, rName
);
491 uno::Type SAL_CALL
SvxUnoXHatchTable::getElementType()
493 return cppu::UnoType
<drawing::Hatch
>::get();
497 OUString SAL_CALL
SvxUnoXHatchTable::getImplementationName( )
499 return u
"SvxUnoXHatchTable"_ustr
;
502 uno::Sequence
< OUString
> SAL_CALL
SvxUnoXHatchTable::getSupportedServiceNames( )
504 return { u
"com.sun.star.drawing.HatchTable"_ustr
};
509 class SvxUnoXGradientTable
: public SvxUnoXPropertyTable
512 explicit SvxUnoXGradientTable( XPropertyList
& rTable
) noexcept
: SvxUnoXPropertyTable( XATTR_FILLGRADIENT
, rTable
) {};
514 // SvxUnoXPropertyTable
515 virtual uno::Any
getAny( const XPropertyEntry
* pEntry
) const noexcept override
;
516 virtual std::unique_ptr
<XPropertyEntry
> createEntry(const OUString
& rName
, const uno::Any
& rAny
) const override
;
519 virtual uno::Type SAL_CALL
getElementType() override
;
522 virtual OUString SAL_CALL
getImplementationName( ) override
;
523 virtual uno::Sequence
< OUString
> SAL_CALL
getSupportedServiceNames( ) override
;
528 uno::Reference
< container::XNameContainer
> SvxUnoXGradientTable_createInstance( XPropertyList
& rTable
) noexcept
530 return new SvxUnoXGradientTable( rTable
);
533 // SvxUnoXPropertyTable
534 uno::Any
SvxUnoXGradientTable::getAny( const XPropertyEntry
* pEntry
) const noexcept
536 const basegfx::BGradient
& aBGradient
= static_cast<const XGradientEntry
*>(pEntry
)->GetGradient();
538 awt::Gradient2 aGradient
= model::gradient::createUnoGradient2(aBGradient
);
539 assert(aGradient
.ColorStops
.get() && "cid#1524745 aGradient.ColorStops._pSequence won't be null here");
541 return uno::Any(aGradient
);
544 std::unique_ptr
<XPropertyEntry
> SvxUnoXGradientTable::createEntry(const OUString
& rName
, const uno::Any
& rAny
) const
546 if (!rAny
.has
<css::awt::Gradient
>() || !rAny
.has
<css::awt::Gradient2
>())
547 return std::unique_ptr
<XPropertyEntry
>();
549 const basegfx::BGradient aBGradient
= model::gradient::getFromAny(rAny
);
550 return std::make_unique
<XGradientEntry
>(aBGradient
, rName
);
554 uno::Type SAL_CALL
SvxUnoXGradientTable::getElementType()
556 return cppu::UnoType
<awt::Gradient
>::get();
560 OUString SAL_CALL
SvxUnoXGradientTable::getImplementationName( )
562 return u
"SvxUnoXGradientTable"_ustr
;
565 uno::Sequence
< OUString
> SAL_CALL
SvxUnoXGradientTable::getSupportedServiceNames( )
567 return { u
"com.sun.star.drawing.GradientTable"_ustr
};
572 class SvxUnoXBitmapTable
: public SvxUnoXPropertyTable
575 explicit SvxUnoXBitmapTable( XPropertyList
& rTable
) noexcept
: SvxUnoXPropertyTable( XATTR_FILLBITMAP
, rTable
) {};
577 // SvxUnoXPropertyTable
578 virtual uno::Any
getAny( const XPropertyEntry
* pEntry
) const override
;
579 virtual std::unique_ptr
<XPropertyEntry
> createEntry(const OUString
& rName
, const uno::Any
& rAny
) const override
;
582 virtual uno::Type SAL_CALL
getElementType() override
;
585 virtual OUString SAL_CALL
getImplementationName( ) override
;
586 virtual uno::Sequence
< OUString
> SAL_CALL
getSupportedServiceNames( ) override
;
591 uno::Reference
< container::XNameContainer
> SvxUnoXBitmapTable_createInstance( XPropertyList
& rTable
) noexcept
593 return new SvxUnoXBitmapTable( rTable
);
596 // SvxUnoXPropertyTable
597 uno::Any
SvxUnoXBitmapTable::getAny( const XPropertyEntry
* pEntry
) const
599 auto xBitmapEntry
= static_cast<const XBitmapEntry
*>(pEntry
);
600 css::uno::Reference
<css::awt::XBitmap
> xBitmap(xBitmapEntry
->GetGraphicObject().GetGraphic().GetXGraphic(), uno::UNO_QUERY
);
601 return uno::Any(xBitmap
);
604 std::unique_ptr
<XPropertyEntry
> SvxUnoXBitmapTable::createEntry(const OUString
& rName
, const uno::Any
& rAny
) const
606 if (!rAny
.has
<uno::Reference
<awt::XBitmap
>>())
607 return std::unique_ptr
<XPropertyEntry
>();
609 auto xBitmap
= rAny
.get
<uno::Reference
<awt::XBitmap
>>();
613 uno::Reference
<graphic::XGraphic
> xGraphic(xBitmap
, uno::UNO_QUERY
);
617 Graphic
aGraphic(xGraphic
);
618 if (aGraphic
.IsNone())
621 GraphicObject
aGraphicObject(std::move(aGraphic
));
622 return std::make_unique
<XBitmapEntry
>(aGraphicObject
, rName
);
626 uno::Type SAL_CALL
SvxUnoXBitmapTable::getElementType()
628 return ::cppu::UnoType
<awt::XBitmap
>::get();
632 OUString SAL_CALL
SvxUnoXBitmapTable::getImplementationName( )
634 return u
"SvxUnoXBitmapTable"_ustr
;
637 uno::Sequence
< OUString
> SAL_CALL
SvxUnoXBitmapTable::getSupportedServiceNames( )
639 return { u
"com.sun.star.drawing.BitmapTable"_ustr
};
642 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */