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>
32 #include <vcl/font.hxx>
33 #include <vcl/svapp.hxx>
34 #include <vcl/graph.hxx>
35 #include <vcl/GraphicObject.hxx>
36 #include <vcl/GraphicLoader.hxx>
37 #include <tools/debug.hxx>
39 #include <editeng/brushitem.hxx>
40 #include <editeng/unoprnms.hxx>
41 #include <editeng/numitem.hxx>
42 #include <editeng/unofdesc.hxx>
43 #include <editeng/unonrule.hxx>
44 #include <editeng/editids.hrc>
45 #include <o3tl/enumarray.hxx>
46 #include <o3tl/temporary.hxx>
49 using ::com::sun::star::util::XCloneable
;
50 using ::com::sun::star::ucb::XAnyCompare
;
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
, sal_Int16
> 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 SvxUnoNumberingRules::SvxUnoNumberingRules(SvxNumRule aRule
)
92 : maRule(std::move( aRule
))
96 SvxUnoNumberingRules::~SvxUnoNumberingRules() noexcept
101 void SAL_CALL
SvxUnoNumberingRules::replaceByIndex( sal_Int32 Index
, const uno::Any
& Element
)
103 SolarMutexGuard aGuard
;
105 if( Index
< 0 || Index
>= maRule
.GetLevelCount() )
106 throw IndexOutOfBoundsException();
108 Sequence
< beans::PropertyValue
> aSeq
;
110 if( !( Element
>>= aSeq
) )
111 throw IllegalArgumentException();
112 setNumberingRuleByIndex( aSeq
, Index
);
116 sal_Int32 SAL_CALL
SvxUnoNumberingRules::getCount()
118 SolarMutexGuard aGuard
;
120 return maRule
.GetLevelCount();
123 Any SAL_CALL
SvxUnoNumberingRules::getByIndex( sal_Int32 Index
)
125 SolarMutexGuard aGuard
;
127 if( Index
< 0 || Index
>= maRule
.GetLevelCount() )
128 throw IndexOutOfBoundsException();
130 return Any( getNumberingRuleByIndex(Index
) );
134 Type SAL_CALL
SvxUnoNumberingRules::getElementType()
136 return cppu::UnoType
<Sequence
< beans::PropertyValue
>>::get();
139 sal_Bool SAL_CALL
SvxUnoNumberingRules::hasElements()
145 sal_Int16 SAL_CALL
SvxUnoNumberingRules::compare( const Any
& rAny1
, const Any
& rAny2
)
147 return SvxUnoNumberingRules::Compare( rAny1
, rAny2
);
151 Reference
< XCloneable
> SAL_CALL
SvxUnoNumberingRules::createClone( )
153 return new SvxUnoNumberingRules(maRule
);
156 OUString SAL_CALL
SvxUnoNumberingRules::getImplementationName( )
158 return u
"SvxUnoNumberingRules"_ustr
;
161 sal_Bool SAL_CALL
SvxUnoNumberingRules::supportsService( const OUString
& ServiceName
)
163 return cppu::supportsService(this, ServiceName
);
166 Sequence
< OUString
> SAL_CALL
SvxUnoNumberingRules::getSupportedServiceNames( )
168 return { u
"com.sun.star.text.NumberingRules"_ustr
};
171 Sequence
<beans::PropertyValue
> SvxUnoNumberingRules::getNumberingRuleByIndex(sal_Int32 nIndex
) const
173 // NumberingRule aRule;
174 const SvxNumberFormat
& rFmt
= maRule
.GetLevel(static_cast<sal_uInt16
>(nIndex
));
177 const int nProps
= 15;
178 std::unique_ptr
<beans::PropertyValue
[]> pArray(new beans::PropertyValue
[nProps
]);
182 aVal
<<= static_cast<sal_uInt16
>(rFmt
.GetNumberingType());
183 pArray
[nIdx
++] = beans::PropertyValue(UNO_NAME_NRULE_NUMBERINGTYPE
, -1, aVal
, beans::PropertyState_DIRECT_VALUE
);
187 SvxAdjust eAdj
= rFmt
.GetNumAdjust();
188 aVal
<<= ConvertUnoAdjust(eAdj
);
189 pArray
[nIdx
++] = beans::PropertyValue(UNO_NAME_NRULE_ADJUST
, -1, aVal
, beans::PropertyState_DIRECT_VALUE
);
193 aVal
<<= rFmt
.GetPrefix();
194 pArray
[nIdx
++] = beans::PropertyValue(UNO_NAME_NRULE_PREFIX
, -1, aVal
, beans::PropertyState_DIRECT_VALUE
);
198 aVal
<<= rFmt
.GetSuffix();
199 pArray
[nIdx
++] = beans::PropertyValue(UNO_NAME_NRULE_SUFFIX
, -1, aVal
, beans::PropertyState_DIRECT_VALUE
);
202 if(SVX_NUM_CHAR_SPECIAL
== rFmt
.GetNumberingType())
204 sal_UCS4 nCode
= rFmt
.GetBulletChar();
205 OUString
aStr( &nCode
, 1 );
207 pArray
[nIdx
++] = beans::PropertyValue(u
"BulletChar"_ustr
, -1, aVal
, beans::PropertyState_DIRECT_VALUE
);
210 if( rFmt
.GetBulletFont() )
212 awt::FontDescriptor aDesc
;
213 SvxUnoFontDescriptor::ConvertFromFont( *rFmt
.GetBulletFont(), aDesc
);
215 pArray
[nIdx
++] = beans::PropertyValue(UNO_NAME_NRULE_BULLET_FONT
, -1, aVal
, beans::PropertyState_DIRECT_VALUE
);
219 const SvxBrushItem
* pBrush
= rFmt
.GetBrush();
220 const Graphic
* pGraphic
= nullptr;
222 pGraphic
= pBrush
->GetGraphic();
225 uno::Reference
<awt::XBitmap
> xBitmap(pGraphic
->GetXGraphic(), uno::UNO_QUERY
);
228 pArray
[nIdx
++] = beans::PropertyValue(u
"GraphicBitmap"_ustr
, -1, aVal
, beans::PropertyState_DIRECT_VALUE
);
233 const Size
aSize( rFmt
.GetGraphicSize() );
234 const awt::Size
aUnoSize( aSize
.Width(), aSize
.Height() );
236 pArray
[nIdx
++] = beans::PropertyValue(u
"GraphicSize"_ustr
, -1, aVal
, beans::PropertyState_DIRECT_VALUE
);
239 aVal
<<= static_cast<sal_Int16
>(rFmt
.GetStart());
240 pArray
[nIdx
++] = beans::PropertyValue(UNO_NAME_NRULE_START_WITH
, -1, aVal
, beans::PropertyState_DIRECT_VALUE
);
242 aVal
<<= rFmt
.GetAbsLSpace();
243 pArray
[nIdx
++] = beans::PropertyValue(UNO_NAME_NRULE_LEFT_MARGIN
, -1, aVal
, beans::PropertyState_DIRECT_VALUE
);
245 aVal
<<= rFmt
.GetFirstLineOffset();
246 pArray
[nIdx
++] = beans::PropertyValue(UNO_NAME_NRULE_FIRST_LINE_OFFSET
, -1, aVal
, beans::PropertyState_DIRECT_VALUE
);
248 pArray
[nIdx
++] = beans::PropertyValue(u
"SymbolTextDistance"_ustr
, -1, aVal
, beans::PropertyState_DIRECT_VALUE
);
250 aVal
<<= rFmt
.GetBulletColor();
251 pArray
[nIdx
++] = beans::PropertyValue(UNO_NAME_NRULE_BULLET_COLOR
, -1, aVal
, beans::PropertyState_DIRECT_VALUE
);
253 aVal
<<= static_cast<sal_Int16
>(rFmt
.GetBulletRelSize());
254 pArray
[nIdx
++] = beans::PropertyValue(UNO_NAME_NRULE_BULLET_RELSIZE
, -1, aVal
, beans::PropertyState_DIRECT_VALUE
);
256 DBG_ASSERT( nIdx
<= nProps
, "FixMe: overflow in Array!!! [CL]" );
257 Sequence
< beans::PropertyValue
> aSeq(pArray
.get(), nIdx
);
262 void SvxUnoNumberingRules::setNumberingRuleByIndex(const Sequence
<beans::PropertyValue
>& rProperties
, sal_Int32 nIndex
)
264 SvxNumberFormat
aFmt(maRule
.GetLevel( static_cast<sal_uInt16
>(nIndex
) ));
265 for(const beans::PropertyValue
& rProp
: rProperties
)
267 const OUString
& rPropName
= rProp
.Name
;
268 const Any
& aVal
= rProp
.Value
;
270 if ( rPropName
== UNO_NAME_NRULE_NUMBERINGTYPE
)
272 sal_Int16 nSet
= sal_Int16();
275 // There is no reason to limit numbering types.
278 aFmt
.SetNumberingType(static_cast<SvxNumType
>(nSet
));
282 else if ( rPropName
== UNO_NAME_NRULE_PREFIX
)
285 if( aVal
>>= aPrefix
)
287 aFmt
.SetPrefix(aPrefix
);
291 else if ( rPropName
== UNO_NAME_NRULE_SUFFIX
)
294 if( aVal
>>= aSuffix
)
296 aFmt
.SetSuffix(aSuffix
);
300 else if ( rPropName
== UNO_NAME_NRULE_BULLETID
)
302 sal_Int16 nSet
= sal_Int16();
307 aFmt
.SetBulletChar(nSet
);
312 else if ( rPropName
== "BulletChar" )
319 aFmt
.SetBulletChar(aStr
.iterateCodePoints(&o3tl::temporary(sal_Int32(0))));
323 aFmt
.SetBulletChar(0);
328 else if ( rPropName
== UNO_NAME_NRULE_ADJUST
)
330 sal_Int16 nAdjust
= sal_Int16();
331 if( aVal
>>= nAdjust
)
333 aFmt
.SetNumAdjust(ConvertUnoAdjust( static_cast<unsigned short>(nAdjust
) ));
337 else if ( rPropName
== UNO_NAME_NRULE_BULLET_FONT
)
339 awt::FontDescriptor aDesc
;
343 SvxUnoFontDescriptor::ConvertToFont( aDesc
, aFont
);
344 aFmt
.SetBulletFont(&aFont
);
348 else if ( rPropName
== "GraphicURL" )
353 Graphic aGraphic
= vcl::graphic::loadFromURL(aURL
);
354 if (!aGraphic
.IsNone())
356 SvxBrushItem
aBrushItem(aGraphic
, GPOS_AREA
, SID_ATTR_BRUSH
);
357 aFmt
.SetGraphicBrush(&aBrushItem
);
362 else if ( rPropName
== "GraphicBitmap" )
364 uno::Reference
<awt::XBitmap
> xBitmap
;
365 if (aVal
>>= xBitmap
)
367 uno::Reference
<graphic::XGraphic
> xGraphic(xBitmap
, uno::UNO_QUERY
);
368 Graphic
aGraphic(xGraphic
);
369 SvxBrushItem
aBrushItem(aGraphic
, GPOS_AREA
, SID_ATTR_BRUSH
);
370 aFmt
.SetGraphicBrush( &aBrushItem
);
374 else if ( rPropName
== "GraphicSize" )
377 if( aVal
>>= aUnoSize
)
379 aFmt
.SetGraphicSize( Size( aUnoSize
.Width
, aUnoSize
.Height
) );
383 else if ( rPropName
== UNO_NAME_NRULE_START_WITH
)
385 sal_Int16 nStart
= sal_Int16();
386 if( aVal
>>= nStart
)
388 aFmt
.SetStart( nStart
);
392 else if ( rPropName
== UNO_NAME_NRULE_LEFT_MARGIN
)
394 sal_Int32 nMargin
= 0;
395 if( aVal
>>= nMargin
)
397 aFmt
.SetAbsLSpace(nMargin
);
401 else if ( rPropName
== UNO_NAME_NRULE_FIRST_LINE_OFFSET
)
403 sal_Int32 nMargin
= 0;
404 if( aVal
>>= nMargin
)
406 aFmt
.SetFirstLineOffset(nMargin
);
410 else if ( rPropName
== "SymbolTextDistance" )
412 sal_Int32 nTextDistance
= 0;
413 if( aVal
>>= nTextDistance
)
415 aFmt
.SetCharTextDistance(static_cast<sal_uInt16
>(nTextDistance
));
419 else if ( rPropName
== UNO_NAME_NRULE_BULLET_COLOR
)
422 if( aVal
>>= aColor
)
424 aFmt
.SetBulletColor( aColor
);
428 else if ( rPropName
== UNO_NAME_NRULE_BULLET_RELSIZE
)
430 sal_Int16 nSize
= sal_Int16();
433 // [AOO Bug 120650] the slide content corrupt when open in Aoo
434 // [TDF# 126234] when MS Office document being imported, the value of the relative size
435 // of the bullet could be as high as 400%
436 if ((nSize
>400)||(nSize
<=0))
441 aFmt
.SetBulletRelSize( static_cast<short>(nSize
) );
450 throw IllegalArgumentException();
453 // check that we always have a brush item for bitmap numbering
454 if( aFmt
.GetNumberingType() == SVX_NUM_BITMAP
)
456 if( nullptr == aFmt
.GetBrush() )
458 GraphicObject aGrafObj
;
459 SvxBrushItem
aBrushItem( aGrafObj
, GPOS_AREA
, SID_ATTR_BRUSH
);
460 aFmt
.SetGraphicBrush( &aBrushItem
);
463 maRule
.SetLevel( static_cast<sal_uInt16
>(nIndex
), aFmt
);
466 const SvxNumRule
& SvxGetNumRule( Reference
< XIndexReplace
> const & xRule
)
468 SvxUnoNumberingRules
* pRule
= dynamic_cast<SvxUnoNumberingRules
*>( xRule
.get() );
469 if( pRule
== nullptr )
470 throw IllegalArgumentException();
472 return pRule
->getNumRule();
475 css::uno::Reference
< css::container::XIndexReplace
> SvxCreateNumRule(const SvxNumRule
& rRule
)
477 return new SvxUnoNumberingRules( rRule
);
482 class SvxUnoNumberingRulesCompare
: public ::cppu::WeakImplHelper
< XAnyCompare
>
485 virtual sal_Int16 SAL_CALL
compare( const Any
& Any1
, const Any
& Any2
) override
;
490 sal_Int16 SAL_CALL
SvxUnoNumberingRulesCompare::compare( const Any
& Any1
, const Any
& Any2
)
492 return SvxUnoNumberingRules::Compare( Any1
, Any2
);
495 sal_Int16
SvxUnoNumberingRules::Compare( const Any
& Any1
, const Any
& Any2
)
497 Reference
< XIndexReplace
> x1( Any1
, UNO_QUERY
), x2( Any2
, UNO_QUERY
);
501 if( x1
.get() == x2
.get() )
504 SvxUnoNumberingRules
* pRule1
= dynamic_cast<SvxUnoNumberingRules
*>( x1
.get() );
507 SvxUnoNumberingRules
* pRule2
= dynamic_cast<SvxUnoNumberingRules
*>( x2
.get() );
511 const SvxNumRule
& rRule1
= pRule1
->getNumRule();
512 const SvxNumRule
& rRule2
= pRule2
->getNumRule();
514 const sal_uInt16 nLevelCount1
= rRule1
.GetLevelCount();
515 const sal_uInt16 nLevelCount2
= rRule2
.GetLevelCount();
517 if( nLevelCount1
== 0 || nLevelCount2
== 0 )
520 for( sal_uInt16 i
= 0; (i
< nLevelCount1
) && (i
< nLevelCount2
); i
++ )
522 if( rRule1
.GetLevel(i
) != rRule2
.GetLevel(i
) )
528 Reference
< XAnyCompare
> SvxCreateNumRuleCompare() noexcept
530 return new SvxUnoNumberingRulesCompare
;
533 css::uno::Reference
< css::container::XIndexReplace
> SvxCreateNumRule()
535 SvxNumRule
aTempRule( SvxNumRuleFlags::NONE
, 10, false );
536 return SvxCreateNumRule( aTempRule
);
539 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */