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 .
20 #include <sal/config.h>
22 #include <com/sun/star/awt/FontDescriptor.hpp>
23 #include <com/sun/star/beans/PropertyValue.hpp>
24 #include <com/sun/star/lang/IllegalArgumentException.hpp>
25 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
26 #include <com/sun/star/text/HoriOrientation.hpp>
27 #include <com/sun/star/awt/XBitmap.hpp>
28 #include <com/sun/star/graphic/XGraphic.hpp>
29 #include <cppuhelper/supportsservice.hxx>
30 #include <cppuhelper/implbase1.hxx>
31 #include <vcl/font.hxx>
32 #include <vcl/svapp.hxx>
33 #include <vcl/graph.hxx>
34 #include <vcl/GraphicObject.hxx>
35 #include <vcl/GraphicLoader.hxx>
36 #include <tools/debug.hxx>
38 #include <editeng/brushitem.hxx>
39 #include <editeng/unoprnms.hxx>
40 #include <editeng/numitem.hxx>
41 #include <editeng/unofdesc.hxx>
42 #include <editeng/unonrule.hxx>
43 #include <editeng/editids.hrc>
44 #include <editeng/numdef.hxx>
45 #include <o3tl/enumarray.hxx>
48 using ::com::sun::star::util::XCloneable
;
49 using ::com::sun::star::ucb::XAnyCompare
;
52 using namespace ::std
;
53 using namespace ::com::sun::star
;
54 using namespace ::com::sun::star::uno
;
55 using namespace ::com::sun::star::lang
;
56 using namespace ::com::sun::star::container
;
58 const SvxAdjust aUnoToSvxAdjust
[] =
69 const o3tl::enumarray
<SvxAdjust
, unsigned short> aSvxToUnoAdjust
71 text::HoriOrientation::LEFT
,
72 text::HoriOrientation::RIGHT
,
73 text::HoriOrientation::FULL
,
74 text::HoriOrientation::CENTER
,
75 text::HoriOrientation::FULL
,
76 text::HoriOrientation::LEFT
79 static SvxAdjust
ConvertUnoAdjust( unsigned short nAdjust
)
81 DBG_ASSERT( nAdjust
<= 7, "Enum has changed! [CL]" );
82 return aUnoToSvxAdjust
[nAdjust
];
85 static unsigned short ConvertUnoAdjust( SvxAdjust eAdjust
)
87 DBG_ASSERT( static_cast<int>(eAdjust
) <= 6, "Enum has changed! [CL]" );
88 return aSvxToUnoAdjust
[eAdjust
];
91 UNO3_GETIMPLEMENTATION_IMPL( SvxUnoNumberingRules
);
93 SvxUnoNumberingRules::SvxUnoNumberingRules(const SvxNumRule
& rRule
)
98 SvxUnoNumberingRules::~SvxUnoNumberingRules() throw()
103 void SAL_CALL
SvxUnoNumberingRules::replaceByIndex( sal_Int32 Index
, const uno::Any
& Element
)
105 SolarMutexGuard aGuard
;
107 if( Index
< 0 || Index
>= maRule
.GetLevelCount() )
108 throw IndexOutOfBoundsException();
110 Sequence
< beans::PropertyValue
> aSeq
;
112 if( !( Element
>>= aSeq
) )
113 throw IllegalArgumentException();
114 setNumberingRuleByIndex( aSeq
, Index
);
118 sal_Int32 SAL_CALL
SvxUnoNumberingRules::getCount()
120 SolarMutexGuard aGuard
;
122 return maRule
.GetLevelCount();
125 Any SAL_CALL
SvxUnoNumberingRules::getByIndex( sal_Int32 Index
)
127 SolarMutexGuard aGuard
;
129 if( Index
< 0 || Index
>= maRule
.GetLevelCount() )
130 throw IndexOutOfBoundsException();
132 return Any( getNumberingRuleByIndex(Index
) );
136 Type SAL_CALL
SvxUnoNumberingRules::getElementType()
138 return cppu::UnoType
<Sequence
< beans::PropertyValue
>>::get();
141 sal_Bool SAL_CALL
SvxUnoNumberingRules::hasElements()
147 sal_Int16 SAL_CALL
SvxUnoNumberingRules::compare( const Any
& rAny1
, const Any
& rAny2
)
149 return SvxUnoNumberingRules::Compare( rAny1
, rAny2
);
153 Reference
< XCloneable
> SAL_CALL
SvxUnoNumberingRules::createClone( )
155 return new SvxUnoNumberingRules(maRule
);
158 OUString SAL_CALL
SvxUnoNumberingRules::getImplementationName( )
160 return "SvxUnoNumberingRules";
163 sal_Bool SAL_CALL
SvxUnoNumberingRules::supportsService( const OUString
& ServiceName
)
165 return cppu::supportsService(this, ServiceName
);
168 Sequence
< OUString
> SAL_CALL
SvxUnoNumberingRules::getSupportedServiceNames( )
170 return { "com.sun.star.text.NumberingRules" };
173 Sequence
<beans::PropertyValue
> SvxUnoNumberingRules::getNumberingRuleByIndex(sal_Int32 nIndex
) const
175 // NumberingRule aRule;
176 const SvxNumberFormat
& rFmt
= maRule
.GetLevel(static_cast<sal_uInt16
>(nIndex
));
179 const int nProps
= 15;
180 std::unique_ptr
<beans::PropertyValue
[]> pArray(new beans::PropertyValue
[nProps
]);
184 aVal
<<= static_cast<sal_uInt16
>(rFmt
.GetNumberingType());
185 beans::PropertyValue
aAlignProp( UNO_NAME_NRULE_NUMBERINGTYPE
, -1, aVal
, beans::PropertyState_DIRECT_VALUE
);
186 pArray
[nIdx
++] = aAlignProp
;
190 SvxAdjust eAdj
= rFmt
.GetNumAdjust();
191 aVal
<<= ConvertUnoAdjust(eAdj
);
192 pArray
[nIdx
++] = beans::PropertyValue( UNO_NAME_NRULE_ADJUST
, -1, aVal
, beans::PropertyState_DIRECT_VALUE
);
196 aVal
<<= rFmt
.GetPrefix();
197 beans::PropertyValue
aPrefixProp( UNO_NAME_NRULE_PREFIX
, -1, aVal
, beans::PropertyState_DIRECT_VALUE
);
198 pArray
[nIdx
++] = aPrefixProp
;
202 aVal
<<= rFmt
.GetSuffix();
203 beans::PropertyValue
aSuffixProp( UNO_NAME_NRULE_SUFFIX
, -1, aVal
, beans::PropertyState_DIRECT_VALUE
);
204 pArray
[nIdx
++] = aSuffixProp
;
207 if(SVX_NUM_CHAR_SPECIAL
== rFmt
.GetNumberingType())
209 sal_UCS4 nCode
= rFmt
.GetBulletChar();
210 OUString
aStr( &nCode
, 1 );
212 beans::PropertyValue
aBulletProp( "BulletChar", -1, aVal
, beans::PropertyState_DIRECT_VALUE
);
213 pArray
[nIdx
++] = aBulletProp
;
216 if( rFmt
.GetBulletFont() )
218 awt::FontDescriptor aDesc
;
219 SvxUnoFontDescriptor::ConvertFromFont( *rFmt
.GetBulletFont(), aDesc
);
221 pArray
[nIdx
++] = beans::PropertyValue( UNO_NAME_NRULE_BULLET_FONT
, -1, aVal
, beans::PropertyState_DIRECT_VALUE
);
225 const SvxBrushItem
* pBrush
= rFmt
.GetBrush();
226 const Graphic
* pGraphic
= nullptr;
228 pGraphic
= pBrush
->GetGraphic();
231 uno::Reference
<awt::XBitmap
> xBitmap(pGraphic
->GetXGraphic(), uno::UNO_QUERY
);
234 const beans::PropertyValue
aGraphicProp("GraphicBitmap", -1, aVal
, beans::PropertyState_DIRECT_VALUE
);
235 pArray
[nIdx
++] = aGraphicProp
;
240 const Size
aSize( rFmt
.GetGraphicSize() );
241 const awt::Size
aUnoSize( aSize
.Width(), aSize
.Height() );
243 const beans::PropertyValue
aGraphicSizeProp("GraphicSize", -1, aVal
, beans::PropertyState_DIRECT_VALUE
);
244 pArray
[nIdx
++] = aGraphicSizeProp
;
247 aVal
<<= static_cast<sal_Int16
>(rFmt
.GetStart());
248 pArray
[nIdx
++] = beans::PropertyValue(UNO_NAME_NRULE_START_WITH
, -1, aVal
, beans::PropertyState_DIRECT_VALUE
);
250 aVal
<<= rFmt
.GetAbsLSpace();
251 pArray
[nIdx
++] = beans::PropertyValue(UNO_NAME_NRULE_LEFT_MARGIN
, -1, aVal
, beans::PropertyState_DIRECT_VALUE
);
253 aVal
<<= rFmt
.GetFirstLineOffset();
254 pArray
[nIdx
++] = beans::PropertyValue(UNO_NAME_NRULE_FIRST_LINE_OFFSET
, -1, aVal
, beans::PropertyState_DIRECT_VALUE
);
256 pArray
[nIdx
++] = beans::PropertyValue("SymbolTextDistance", -1, aVal
, beans::PropertyState_DIRECT_VALUE
);
258 aVal
<<= rFmt
.GetBulletColor();
259 pArray
[nIdx
++] = beans::PropertyValue(UNO_NAME_NRULE_BULLET_COLOR
, -1, aVal
, beans::PropertyState_DIRECT_VALUE
);
261 aVal
<<= static_cast<sal_Int16
>(rFmt
.GetBulletRelSize());
262 pArray
[nIdx
++] = beans::PropertyValue(UNO_NAME_NRULE_BULLET_RELSIZE
, -1, aVal
, beans::PropertyState_DIRECT_VALUE
);
264 DBG_ASSERT( nIdx
<= nProps
, "FixMe: overflow in Array!!! [CL]" );
265 Sequence
< beans::PropertyValue
> aSeq(pArray
.get(), nIdx
);
270 void SvxUnoNumberingRules::setNumberingRuleByIndex(const Sequence
<beans::PropertyValue
>& rProperties
, sal_Int32 nIndex
)
272 SvxNumberFormat
aFmt(maRule
.GetLevel( static_cast<sal_uInt16
>(nIndex
) ));
273 for(const beans::PropertyValue
& rProp
: rProperties
)
275 const OUString
& rPropName
= rProp
.Name
;
276 const Any
& aVal
= rProp
.Value
;
278 if ( rPropName
== UNO_NAME_NRULE_NUMBERINGTYPE
)
280 sal_Int16 nSet
= sal_Int16();
283 // There is no reason to limit numbering types.
286 aFmt
.SetNumberingType(static_cast<SvxNumType
>(nSet
));
290 else if ( rPropName
== UNO_NAME_NRULE_PREFIX
)
293 if( aVal
>>= aPrefix
)
295 aFmt
.SetPrefix(aPrefix
);
299 else if ( rPropName
== UNO_NAME_NRULE_SUFFIX
)
302 if( aVal
>>= aSuffix
)
304 aFmt
.SetSuffix(aSuffix
);
308 else if ( rPropName
== UNO_NAME_NRULE_BULLETID
)
310 sal_Int16 nSet
= sal_Int16();
315 aFmt
.SetBulletChar(nSet
);
320 else if ( rPropName
== "BulletChar" )
327 sal_Int32 nIndexUtf16
= 0;
328 aFmt
.SetBulletChar(aStr
.iterateCodePoints(&nIndexUtf16
));
332 aFmt
.SetBulletChar(0);
337 else if ( rPropName
== UNO_NAME_NRULE_ADJUST
)
339 sal_Int16 nAdjust
= sal_Int16();
340 if( aVal
>>= nAdjust
)
342 aFmt
.SetNumAdjust(ConvertUnoAdjust( static_cast<unsigned short>(nAdjust
) ));
346 else if ( rPropName
== UNO_NAME_NRULE_BULLET_FONT
)
348 awt::FontDescriptor aDesc
;
352 SvxUnoFontDescriptor::ConvertToFont( aDesc
, aFont
);
353 aFmt
.SetBulletFont(&aFont
);
357 else if ( rPropName
== "GraphicURL" )
362 Graphic aGraphic
= vcl::graphic::loadFromURL(aURL
);
363 if (!aGraphic
.IsNone())
365 SvxBrushItem
aBrushItem(aGraphic
, GPOS_AREA
, SID_ATTR_BRUSH
);
366 aFmt
.SetGraphicBrush(&aBrushItem
);
371 else if ( rPropName
== "GraphicBitmap" )
373 uno::Reference
<awt::XBitmap
> xBitmap
;
374 if (aVal
>>= xBitmap
)
376 uno::Reference
<graphic::XGraphic
> xGraphic(xBitmap
, uno::UNO_QUERY
);
377 Graphic
aGraphic(xGraphic
);
378 SvxBrushItem
aBrushItem(aGraphic
, GPOS_AREA
, SID_ATTR_BRUSH
);
379 aFmt
.SetGraphicBrush( &aBrushItem
);
383 else if ( rPropName
== "GraphicSize" )
386 if( aVal
>>= aUnoSize
)
388 aFmt
.SetGraphicSize( Size( aUnoSize
.Width
, aUnoSize
.Height
) );
392 else if ( rPropName
== UNO_NAME_NRULE_START_WITH
)
394 sal_Int16 nStart
= sal_Int16();
395 if( aVal
>>= nStart
)
397 aFmt
.SetStart( nStart
);
401 else if ( rPropName
== UNO_NAME_NRULE_LEFT_MARGIN
)
403 sal_Int32 nMargin
= 0;
404 if( aVal
>>= nMargin
)
406 aFmt
.SetAbsLSpace(nMargin
);
410 else if ( rPropName
== UNO_NAME_NRULE_FIRST_LINE_OFFSET
)
412 sal_Int32 nMargin
= 0;
413 if( aVal
>>= nMargin
)
415 aFmt
.SetFirstLineOffset(nMargin
);
419 else if ( rPropName
== "SymbolTextDistance" )
421 sal_Int32 nTextDistance
= 0;
422 if( aVal
>>= nTextDistance
)
424 aFmt
.SetCharTextDistance(static_cast<sal_uInt16
>(nTextDistance
));
428 else if ( rPropName
== UNO_NAME_NRULE_BULLET_COLOR
)
430 sal_Int32 nColor
= 0;
431 if( aVal
>>= nColor
)
433 aFmt
.SetBulletColor( static_cast<Color
>(nColor
) );
437 else if ( rPropName
== UNO_NAME_NRULE_BULLET_RELSIZE
)
439 sal_Int16 nSize
= sal_Int16();
442 // [AOO Bug 120650] the slide content corrupt when open in Aoo
443 // [TDF# 126234] when MS Office document being imported, the value of the relative size
444 // of the bullet could be as high as 400%
445 if ((nSize
>400)||(nSize
<=0))
450 aFmt
.SetBulletRelSize( static_cast<short>(nSize
) );
459 throw IllegalArgumentException();
462 // check that we always have a brush item for bitmap numbering
463 if( aFmt
.GetNumberingType() == SVX_NUM_BITMAP
)
465 if( nullptr == aFmt
.GetBrush() )
467 GraphicObject aGrafObj
;
468 SvxBrushItem
aBrushItem( aGrafObj
, GPOS_AREA
, SID_ATTR_BRUSH
);
469 aFmt
.SetGraphicBrush( &aBrushItem
);
472 maRule
.SetLevel( static_cast<sal_uInt16
>(nIndex
), aFmt
);
475 const SvxNumRule
& SvxGetNumRule( Reference
< XIndexReplace
> const & xRule
)
477 SvxUnoNumberingRules
* pRule
= comphelper::getUnoTunnelImplementation
<SvxUnoNumberingRules
>( xRule
);
478 if( pRule
== nullptr )
479 throw IllegalArgumentException();
481 return pRule
->getNumRule();
484 css::uno::Reference
< css::container::XIndexReplace
> SvxCreateNumRule(const SvxNumRule
* pRule
)
486 DBG_ASSERT( pRule
, "No default SvxNumRule!" );
489 return new SvxUnoNumberingRules( *pRule
);
493 SvxNumRule
aDefaultRule( SvxNumRuleFlags::BULLET_REL_SIZE
| SvxNumRuleFlags::BULLET_COLOR
, SVX_MAX_NUM
, false);
494 return new SvxUnoNumberingRules( aDefaultRule
);
500 class SvxUnoNumberingRulesCompare
: public ::cppu::WeakAggImplHelper1
< XAnyCompare
>
503 virtual sal_Int16 SAL_CALL
compare( const Any
& Any1
, const Any
& Any2
) override
;
508 sal_Int16 SAL_CALL
SvxUnoNumberingRulesCompare::compare( const Any
& Any1
, const Any
& Any2
)
510 return SvxUnoNumberingRules::Compare( Any1
, Any2
);
513 sal_Int16
SvxUnoNumberingRules::Compare( const Any
& Any1
, const Any
& Any2
)
515 Reference
< XIndexReplace
> x1( Any1
, UNO_QUERY
), x2( Any2
, UNO_QUERY
);
516 if( x1
.is() && x2
.is() )
518 if( x1
.get() == x2
.get() )
521 SvxUnoNumberingRules
* pRule1
= comphelper::getUnoTunnelImplementation
<SvxUnoNumberingRules
>( x1
);
524 SvxUnoNumberingRules
* pRule2
= comphelper::getUnoTunnelImplementation
<SvxUnoNumberingRules
>( x2
);
527 const SvxNumRule
& rRule1
= pRule1
->getNumRule();
528 const SvxNumRule
& rRule2
= pRule2
->getNumRule();
530 const sal_uInt16 nLevelCount1
= rRule1
.GetLevelCount();
531 const sal_uInt16 nLevelCount2
= rRule2
.GetLevelCount();
533 if( nLevelCount1
== 0 || nLevelCount2
== 0 )
536 for( sal_uInt16 i
= 0; (i
< nLevelCount1
) && (i
< nLevelCount2
); i
++ )
538 if( rRule1
.GetLevel(i
) != rRule2
.GetLevel(i
) )
549 Reference
< XAnyCompare
> SvxCreateNumRuleCompare() throw()
551 return new SvxUnoNumberingRulesCompare
;
554 css::uno::Reference
< css::container::XIndexReplace
> SvxCreateNumRule()
556 SvxNumRule
aTempRule( SvxNumRuleFlags::NONE
, 10, false );
557 return SvxCreateNumRule( &aTempRule
);
560 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */