nss: upgrade to release 3.73
[LibreOffice.git] / editeng / source / uno / unonrule.cxx
blob03b766d446d7809436f7904fcfcce521af46579b
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 <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>
46 #include <memory>
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[] =
60 SvxAdjust::Left,
61 SvxAdjust::Right,
62 SvxAdjust::Center,
63 SvxAdjust::Left,
64 SvxAdjust::Left,
65 SvxAdjust::Left,
66 SvxAdjust::Block
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)
94 : maRule( rRule )
98 SvxUnoNumberingRules::~SvxUnoNumberingRules() throw()
102 //XIndexReplace
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 );
117 // XIndexAccess
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) );
135 //XElementAccess
136 Type SAL_CALL SvxUnoNumberingRules::getElementType()
138 return cppu::UnoType<Sequence< beans::PropertyValue >>::get();
141 sal_Bool SAL_CALL SvxUnoNumberingRules::hasElements()
143 return true;
146 // XAnyCompare
147 sal_Int16 SAL_CALL SvxUnoNumberingRules::compare( const Any& rAny1, const Any& rAny2 )
149 return SvxUnoNumberingRules::Compare( rAny1, rAny2 );
152 // XCloneable
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));
177 sal_uInt16 nIdx = 0;
179 const int nProps = 15;
180 std::unique_ptr<beans::PropertyValue[]> pArray(new beans::PropertyValue[nProps]);
182 Any aVal;
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 );
211 aVal <<= aStr;
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 );
220 aVal <<= 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;
227 if (pBrush)
228 pGraphic = pBrush->GetGraphic();
229 if (pGraphic)
231 uno::Reference<awt::XBitmap> xBitmap(pGraphic->GetXGraphic(), uno::UNO_QUERY);
232 aVal <<= xBitmap;
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() );
242 aVal <<= aUnoSize;
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);
267 return aSeq;
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();
281 aVal >>= nSet;
283 // There is no reason to limit numbering types.
284 if ( nSet>=0 )
286 aFmt.SetNumberingType(static_cast<SvxNumType>(nSet));
287 continue;
290 else if ( rPropName == UNO_NAME_NRULE_PREFIX )
292 OUString aPrefix;
293 if( aVal >>= aPrefix )
295 aFmt.SetPrefix(aPrefix);
296 continue;
299 else if ( rPropName == UNO_NAME_NRULE_SUFFIX )
301 OUString aSuffix;
302 if( aVal >>= aSuffix )
304 aFmt.SetSuffix(aSuffix);
305 continue;
308 else if ( rPropName == UNO_NAME_NRULE_BULLETID )
310 sal_Int16 nSet = sal_Int16();
311 if( aVal >>= nSet )
313 if(nSet < 0x100)
315 aFmt.SetBulletChar(nSet);
316 continue;
320 else if ( rPropName == "BulletChar" )
322 OUString aStr;
323 if( aVal >>= aStr )
325 if(!aStr.isEmpty())
327 sal_Int32 nIndexUtf16 = 0;
328 aFmt.SetBulletChar(aStr.iterateCodePoints(&nIndexUtf16));
330 else
332 aFmt.SetBulletChar(0);
334 continue;
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) ));
343 continue;
346 else if ( rPropName == UNO_NAME_NRULE_BULLET_FONT )
348 awt::FontDescriptor aDesc;
349 if( aVal >>= aDesc )
351 vcl::Font aFont;
352 SvxUnoFontDescriptor::ConvertToFont( aDesc, aFont );
353 aFmt.SetBulletFont(&aFont);
354 continue;
357 else if ( rPropName == "GraphicURL" )
359 OUString aURL;
360 if (aVal >>= aURL)
362 Graphic aGraphic = vcl::graphic::loadFromURL(aURL);
363 if (!aGraphic.IsNone())
365 SvxBrushItem aBrushItem(aGraphic, GPOS_AREA, SID_ATTR_BRUSH);
366 aFmt.SetGraphicBrush(&aBrushItem);
368 continue;
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 );
380 continue;
383 else if ( rPropName == "GraphicSize" )
385 awt::Size aUnoSize;
386 if( aVal >>= aUnoSize )
388 aFmt.SetGraphicSize( Size( aUnoSize.Width, aUnoSize.Height ) );
389 continue;
392 else if ( rPropName == UNO_NAME_NRULE_START_WITH )
394 sal_Int16 nStart = sal_Int16();
395 if( aVal >>= nStart )
397 aFmt.SetStart( nStart );
398 continue;
401 else if ( rPropName == UNO_NAME_NRULE_LEFT_MARGIN )
403 sal_Int32 nMargin = 0;
404 if( aVal >>= nMargin )
406 aFmt.SetAbsLSpace(nMargin);
407 continue;
410 else if ( rPropName == UNO_NAME_NRULE_FIRST_LINE_OFFSET )
412 sal_Int32 nMargin = 0;
413 if( aVal >>= nMargin )
415 aFmt.SetFirstLineOffset(nMargin);
416 continue;
419 else if ( rPropName == "SymbolTextDistance" )
421 sal_Int32 nTextDistance = 0;
422 if( aVal >>= nTextDistance )
424 aFmt.SetCharTextDistance(static_cast<sal_uInt16>(nTextDistance));
425 continue;
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) );
434 continue;
437 else if ( rPropName == UNO_NAME_NRULE_BULLET_RELSIZE )
439 sal_Int16 nSize = sal_Int16();
440 if( aVal >>= nSize )
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))
447 nSize = 100;
450 aFmt.SetBulletRelSize( static_cast<short>(nSize) );
451 continue;
454 else
456 continue;
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!" );
487 if( pRule )
489 return new SvxUnoNumberingRules( *pRule );
491 else
493 SvxNumRule aDefaultRule( SvxNumRuleFlags::BULLET_REL_SIZE | SvxNumRuleFlags::BULLET_COLOR, SVX_MAX_NUM, false);
494 return new SvxUnoNumberingRules( aDefaultRule );
498 namespace {
500 class SvxUnoNumberingRulesCompare : public ::cppu::WeakAggImplHelper1< XAnyCompare >
502 public:
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() )
519 return 0;
521 SvxUnoNumberingRules* pRule1 = comphelper::getUnoTunnelImplementation<SvxUnoNumberingRules>( x1 );
522 if( pRule1 )
524 SvxUnoNumberingRules* pRule2 = comphelper::getUnoTunnelImplementation<SvxUnoNumberingRules>( x2 );
525 if( pRule2 )
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 )
534 return -1;
536 for( sal_uInt16 i = 0; (i < nLevelCount1) && (i < nLevelCount2); i++ )
538 if( rRule1.GetLevel(i) != rRule2.GetLevel(i) )
539 return -1;
541 return 0;
546 return -1;
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: */