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 .
21 #include <editeng/numitem.hxx>
23 #include <com/sun/star/text/HoriOrientation.hpp>
24 #include <com/sun/star/text/VertOrientation.hpp>
25 #include <com/sun/star/text/RelOrientation.hpp>
26 #include <editeng/brushitem.hxx>
27 #include <vcl/font.hxx>
28 #include <vcl/settings.hxx>
29 #include <editeng/editids.hrc>
30 #include <editeng/editrids.hrc>
31 #include <editeng/numdef.hxx>
32 #include <editeng/eeitem.hxx>
33 #include <vcl/graph.hxx>
34 #include <vcl/window.hxx>
35 #include <vcl/svapp.hxx>
36 #include <editeng/unolingu.hxx>
37 #include <com/sun/star/text/XNumberingFormatter.hpp>
38 #include <com/sun/star/text/DefaultNumberingProvider.hpp>
39 #include <com/sun/star/text/XDefaultNumberingProvider.hpp>
40 #include <com/sun/star/style/NumberingType.hpp>
41 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
42 #include <com/sun/star/beans/PropertyValue.hpp>
43 #include <comphelper/processfactory.hxx>
44 #include <tools/mapunit.hxx>
46 #include <editeng/unonrule.hxx>
48 #define DEF_WRITER_LSPACE 500 //Standard Indentation
49 #define DEF_DRAW_LSPACE 800 //Standard Indentation
51 #define NUMITEM_VERSION_03 0x03
52 #define NUMITEM_VERSION_04 0x04
54 using namespace ::com::sun::star
;
55 using namespace ::com::sun::star::lang
;
56 using namespace ::com::sun::star::uno
;
57 using namespace ::com::sun::star::text
;
58 using namespace ::com::sun::star::beans
;
59 using namespace ::com::sun::star::style
;
61 sal_Int32
SvxNumberType::nRefCount
= 0;
62 com::sun::star::uno::Reference
<com::sun::star::text::XNumberingFormatter
> SvxNumberType::xFormatter
= 0;
63 static void lcl_getFormatter(com::sun::star::uno::Reference
<com::sun::star::text::XNumberingFormatter
>& _xFormatter
)
69 Reference
<XComponentContext
> xContext( ::comphelper::getProcessComponentContext() );
70 Reference
<XDefaultNumberingProvider
> xRet
= text::DefaultNumberingProvider::create(xContext
);
71 _xFormatter
= Reference
<XNumberingFormatter
> (xRet
, UNO_QUERY
);
73 catch(const Exception
&)
75 SAL_WARN("editeng", "service missing: \"com.sun.star.text.DefaultNumberingProvider\"");
80 SvxNumberType::SvxNumberType(sal_Int16 nType
) :
87 SvxNumberType::SvxNumberType(const SvxNumberType
& rType
) :
88 nNumType(rType
.nNumType
),
89 bShowSymbol(rType
.bShowSymbol
)
94 SvxNumberType::~SvxNumberType()
100 OUString
SvxNumberType::GetNumStr( sal_uLong nNo
) const
102 const LanguageTag
& rLang
= Application::GetSettings().GetLanguageTag();
103 return GetNumStr( nNo
, rLang
.getLocale() );
106 OUString
SvxNumberType::GetNumStr( sal_uLong nNo
, const css::lang::Locale
& rLocale
) const
108 lcl_getFormatter(xFormatter
);
116 case NumberingType::CHAR_SPECIAL
:
117 case NumberingType::BITMAP
:
121 // '0' allowed for ARABIC numberings
122 if(NumberingType::ARABIC
== nNumType
&& 0 == nNo
)
123 return OUString('0');
126 Sequence
< PropertyValue
> aProperties(2);
127 PropertyValue
* pValues
= aProperties
.getArray();
128 pValues
[0].Name
= "NumberingType";
129 pValues
[0].Value
<<= nNumType
;
130 pValues
[1].Name
= "Value";
131 pValues
[1].Value
<<= (sal_Int32
)nNo
;
135 return xFormatter
->makeNumberingString( aProperties
, rLocale
);
137 catch(const Exception
&)
147 SvxNumberFormat::SvxNumberFormat( sal_Int16 eType
,
148 SvxNumPositionAndSpaceMode ePositionAndSpaceMode
)
149 : SvxNumberType(eType
),
150 eNumAdjust(SVX_ADJUST_LEFT
),
153 cBullet(SVX_DEF_BULLET
),
155 nBulletColor(COL_BLACK
),
156 mePositionAndSpaceMode( ePositionAndSpaceMode
),
159 nCharTextDistance(0),
160 meLabelFollowedBy( LISTTAB
),
162 mnFirstLineIndent( 0 ),
165 eVertOrient(text::VertOrientation::NONE
),
170 SvxNumberFormat::SvxNumberFormat(const SvxNumberFormat
& rFormat
) :
171 SvxNumberType(rFormat
),
172 mePositionAndSpaceMode( rFormat
.mePositionAndSpaceMode
),
179 SvxNumberFormat::SvxNumberFormat( SvStream
&rStream
)
181 , nBulletRelSize(100)
182 , nFirstLineOffset(0)
184 , nCharTextDistance(0)
186 sal_uInt16
nTmp16(0);
188 rStream
.ReadUInt16( nTmp16
); // Version number
190 rStream
.ReadUInt16( nTmp16
); SetNumberingType( nTmp16
);
191 rStream
.ReadUInt16( nTmp16
); eNumAdjust
= ( SvxAdjust
)nTmp16
;
192 rStream
.ReadUInt16( nTmp16
); nInclUpperLevels
= nTmp16
;
193 rStream
.ReadUInt16( nStart
);
194 rStream
.ReadUInt16( nTmp16
); cBullet
= (sal_Unicode
)nTmp16
;
196 rStream
.ReadInt16( nFirstLineOffset
);
197 rStream
.ReadInt16( nAbsLSpace
);
198 rStream
.SeekRel(2); //skip old now unused nLSpace;
200 rStream
.ReadInt16( nCharTextDistance
);
202 sPrefix
= rStream
.ReadUniOrByteString( rStream
.GetStreamCharSet() );
203 sSuffix
= rStream
.ReadUniOrByteString( rStream
.GetStreamCharSet() );
204 sCharStyleName
= rStream
.ReadUniOrByteString( rStream
.GetStreamCharSet() );
206 sal_uInt16 hasGraphicBrush
= 0;
207 rStream
.ReadUInt16( hasGraphicBrush
);
208 if ( hasGraphicBrush
)
210 pGraphicBrush
= new SvxBrushItem( SID_ATTR_BRUSH
);
211 pGraphicBrush
= static_cast<SvxBrushItem
*>(pGraphicBrush
->Create( rStream
, BRUSH_GRAPHIC_VERSION
));
213 else pGraphicBrush
= 0;
214 rStream
.ReadUInt16( nTmp16
); eVertOrient
= nTmp16
;
216 sal_uInt16 hasBulletFont
= 0;
217 rStream
.ReadUInt16( hasBulletFont
);
220 pBulletFont
= new vcl::Font( );
221 ReadFont( rStream
, *pBulletFont
);
223 else pBulletFont
= NULL
;
224 ReadPair( rStream
, aGraphicSize
);
226 ReadColor( rStream
, nBulletColor
);
227 rStream
.ReadUInt16( nBulletRelSize
);
228 rStream
.ReadUInt16( nTmp16
); SetShowSymbol( nTmp16
);
230 rStream
.ReadUInt16( nTmp16
); mePositionAndSpaceMode
= ( SvxNumPositionAndSpaceMode
)nTmp16
;
231 rStream
.ReadUInt16( nTmp16
); meLabelFollowedBy
= ( LabelFollowedBy
)nTmp16
;
232 rStream
.ReadInt32( nTmp32
); mnListtabPos
= nTmp32
;
233 rStream
.ReadInt32( nTmp32
); mnFirstLineIndent
= nTmp32
;
234 rStream
.ReadInt32( nTmp32
); mnIndentAt
= nTmp32
;
237 SvxNumberFormat::~SvxNumberFormat()
239 delete pGraphicBrush
;
243 SvStream
& SvxNumberFormat::Store(SvStream
&rStream
, FontToSubsFontConverter pConverter
)
245 if(pConverter
&& pBulletFont
)
247 cBullet
= ConvertFontToSubsFontChar(pConverter
, cBullet
);
248 OUString sFontName
= GetFontToSubsFontName(pConverter
);
249 pBulletFont
->SetName(sFontName
);
252 rStream
.WriteUInt16( NUMITEM_VERSION_04
);
254 rStream
.WriteUInt16( GetNumberingType() );
255 rStream
.WriteUInt16( eNumAdjust
);
256 rStream
.WriteUInt16( nInclUpperLevels
);
257 rStream
.WriteUInt16( nStart
);
258 rStream
.WriteUInt16( cBullet
);
260 rStream
.WriteInt16( nFirstLineOffset
);
261 rStream
.WriteInt16( nAbsLSpace
);
262 rStream
.WriteInt16( 0 ); // write a dummy for old now unused nLSpace
264 rStream
.WriteInt16( nCharTextDistance
);
265 rtl_TextEncoding eEnc
= osl_getThreadTextEncoding();
266 rStream
.WriteUniOrByteString(sPrefix
, eEnc
);
267 rStream
.WriteUniOrByteString(sSuffix
, eEnc
);
268 rStream
.WriteUniOrByteString(sCharStyleName
, eEnc
);
271 rStream
.WriteUInt16( 1 );
273 // in SD or SI force bullet itself to be stored,
274 // for that purpose throw away link when link and graphic
275 // are present, so Brush save is forced
276 if(!pGraphicBrush
->GetGraphicLink().isEmpty() && pGraphicBrush
->GetGraphic())
278 pGraphicBrush
->SetGraphicLink("");
281 pGraphicBrush
->Store(rStream
, BRUSH_GRAPHIC_VERSION
);
284 rStream
.WriteUInt16( 0 );
286 rStream
.WriteUInt16( eVertOrient
);
289 rStream
.WriteUInt16( 1 );
290 WriteFont( rStream
, *pBulletFont
);
293 rStream
.WriteUInt16( 0 );
294 WritePair( rStream
, aGraphicSize
);
296 Color nTempColor
= nBulletColor
;
297 if(COL_AUTO
== nBulletColor
.GetColor())
298 nTempColor
= COL_BLACK
;
299 WriteColor( rStream
, nTempColor
);
300 rStream
.WriteUInt16( nBulletRelSize
);
301 rStream
.WriteUInt16( sal_uInt16(IsShowSymbol()) );
303 rStream
.WriteUInt16( mePositionAndSpaceMode
);
304 rStream
.WriteUInt16( meLabelFollowedBy
);
305 rStream
.WriteInt32( mnListtabPos
);
306 rStream
.WriteInt32( mnFirstLineIndent
);
307 rStream
.WriteInt32( mnIndentAt
);
312 SvxNumberFormat
& SvxNumberFormat::operator=( const SvxNumberFormat
& rFormat
)
314 if (& rFormat
== this) { return *this; }
316 SetNumberingType(rFormat
.GetNumberingType());
317 eNumAdjust
= rFormat
.eNumAdjust
;
318 nInclUpperLevels
= rFormat
.nInclUpperLevels
;
319 nStart
= rFormat
.nStart
;
320 cBullet
= rFormat
.cBullet
;
321 mePositionAndSpaceMode
= rFormat
.mePositionAndSpaceMode
;
322 nFirstLineOffset
= rFormat
.nFirstLineOffset
;
323 nAbsLSpace
= rFormat
.nAbsLSpace
;
324 nCharTextDistance
= rFormat
.nCharTextDistance
;
325 meLabelFollowedBy
= rFormat
.meLabelFollowedBy
;
326 mnListtabPos
= rFormat
.mnListtabPos
;
327 mnFirstLineIndent
= rFormat
.mnFirstLineIndent
;
328 mnIndentAt
= rFormat
.mnIndentAt
;
329 eVertOrient
= rFormat
.eVertOrient
;
330 sPrefix
= rFormat
.sPrefix
;
331 sSuffix
= rFormat
.sSuffix
;
332 aGraphicSize
= rFormat
.aGraphicSize
;
333 nBulletColor
= rFormat
.nBulletColor
;
334 nBulletRelSize
= rFormat
.nBulletRelSize
;
335 SetShowSymbol(rFormat
.IsShowSymbol());
336 sCharStyleName
= rFormat
.sCharStyleName
;
337 DELETEZ(pGraphicBrush
);
338 if(rFormat
.pGraphicBrush
)
340 pGraphicBrush
= new SvxBrushItem(*rFormat
.pGraphicBrush
);
341 pGraphicBrush
->SetDoneLink( LINK( this, SvxNumberFormat
, GraphicArrived
) );
343 DELETEZ(pBulletFont
);
344 if(rFormat
.pBulletFont
)
345 pBulletFont
= new vcl::Font(*rFormat
.pBulletFont
);
349 bool SvxNumberFormat::operator==( const SvxNumberFormat
& rFormat
) const
351 if( GetNumberingType() != rFormat
.GetNumberingType() ||
352 eNumAdjust
!= rFormat
.eNumAdjust
||
353 nInclUpperLevels
!= rFormat
.nInclUpperLevels
||
354 nStart
!= rFormat
.nStart
||
355 cBullet
!= rFormat
.cBullet
||
356 mePositionAndSpaceMode
!= rFormat
.mePositionAndSpaceMode
||
357 nFirstLineOffset
!= rFormat
.nFirstLineOffset
||
358 nAbsLSpace
!= rFormat
.nAbsLSpace
||
359 nCharTextDistance
!= rFormat
.nCharTextDistance
||
360 meLabelFollowedBy
!= rFormat
.meLabelFollowedBy
||
361 mnListtabPos
!= rFormat
.mnListtabPos
||
362 mnFirstLineIndent
!= rFormat
.mnFirstLineIndent
||
363 mnIndentAt
!= rFormat
.mnIndentAt
||
364 eVertOrient
!= rFormat
.eVertOrient
||
365 sPrefix
!= rFormat
.sPrefix
||
366 sSuffix
!= rFormat
.sSuffix
||
367 aGraphicSize
!= rFormat
.aGraphicSize
||
368 nBulletColor
!= rFormat
.nBulletColor
||
369 nBulletRelSize
!= rFormat
.nBulletRelSize
||
370 IsShowSymbol() != rFormat
.IsShowSymbol() ||
371 sCharStyleName
!= rFormat
.sCharStyleName
375 (pGraphicBrush
&& !rFormat
.pGraphicBrush
) ||
376 (!pGraphicBrush
&& rFormat
.pGraphicBrush
) ||
377 (pGraphicBrush
&& *pGraphicBrush
!= *rFormat
.pGraphicBrush
)
383 (pBulletFont
&& !rFormat
.pBulletFont
) ||
384 (!pBulletFont
&& rFormat
.pBulletFont
) ||
385 (pBulletFont
&& *pBulletFont
!= *rFormat
.pBulletFont
)
393 void SvxNumberFormat::SetGraphicBrush( const SvxBrushItem
* pBrushItem
,
394 const Size
* pSize
, const sal_Int16
* pOrient
)
398 delete pGraphicBrush
;
401 else if ( !pGraphicBrush
|| (pGraphicBrush
&& !(*pBrushItem
== *pGraphicBrush
)) )
403 delete pGraphicBrush
;
404 pGraphicBrush
= static_cast<SvxBrushItem
*>(pBrushItem
->Clone());
405 pGraphicBrush
->SetDoneLink( LINK( this, SvxNumberFormat
, GraphicArrived
) );
409 eVertOrient
= *pOrient
;
411 eVertOrient
= text::VertOrientation::NONE
;
413 aGraphicSize
= *pSize
;
415 aGraphicSize
.Width() = aGraphicSize
.Height() = 0;
418 void SvxNumberFormat::SetGraphic( const OUString
& rName
)
420 if( pGraphicBrush
&& pGraphicBrush
->GetGraphicLink() == rName
)
423 delete pGraphicBrush
;
424 pGraphicBrush
= new SvxBrushItem( rName
, "", GPOS_AREA
, 0 );
425 pGraphicBrush
->SetDoneLink( LINK( this, SvxNumberFormat
, GraphicArrived
) );
426 if( eVertOrient
== text::VertOrientation::NONE
)
427 eVertOrient
= text::VertOrientation::TOP
;
429 aGraphicSize
.Width() = aGraphicSize
.Height() = 0;
432 void SvxNumberFormat::SetVertOrient(sal_Int16 eSet
)
437 sal_Int16
SvxNumberFormat::GetVertOrient() const
442 void SvxNumberFormat::SetBulletFont(const vcl::Font
* pFont
)
445 pBulletFont
= pFont
? new vcl::Font(*pFont
): 0;
448 void SvxNumberFormat::SetPositionAndSpaceMode( SvxNumPositionAndSpaceMode ePositionAndSpaceMode
)
450 mePositionAndSpaceMode
= ePositionAndSpaceMode
;
453 short SvxNumberFormat::GetAbsLSpace() const
455 return mePositionAndSpaceMode
== LABEL_WIDTH_AND_POSITION
457 : static_cast<short>( GetFirstLineIndent() + GetIndentAt() );
459 short SvxNumberFormat::GetFirstLineOffset() const
461 return mePositionAndSpaceMode
== LABEL_WIDTH_AND_POSITION
463 : static_cast<short>( GetFirstLineIndent() );
465 short SvxNumberFormat::GetCharTextDistance() const
467 return mePositionAndSpaceMode
== LABEL_WIDTH_AND_POSITION
? nCharTextDistance
: 0;
470 void SvxNumberFormat::SetLabelFollowedBy( const LabelFollowedBy eLabelFollowedBy
)
472 meLabelFollowedBy
= eLabelFollowedBy
;
474 void SvxNumberFormat::SetListtabPos( const long nListtabPos
)
476 mnListtabPos
= nListtabPos
;
478 void SvxNumberFormat::SetFirstLineIndent( const long nFirstLineIndent
)
480 mnFirstLineIndent
= nFirstLineIndent
;
482 void SvxNumberFormat::SetIndentAt( const long nIndentAt
)
484 mnIndentAt
= nIndentAt
;
487 IMPL_LINK_NOARG( SvxNumberFormat
, GraphicArrived
)
489 // if necessary, set the GrfSize:
490 if( !aGraphicSize
.Width() || !aGraphicSize
.Height() )
492 const Graphic
* pGrf
= pGraphicBrush
->GetGraphic();
494 aGraphicSize
= SvxNumberFormat::GetGraphicSizeMM100( pGrf
);
496 NotifyGraphicArrived();
500 void SvxNumberFormat::NotifyGraphicArrived()
504 Size
SvxNumberFormat::GetGraphicSizeMM100(const Graphic
* pGraphic
)
506 const MapMode
aMapMM100( MAP_100TH_MM
);
507 const Size
& rSize
= pGraphic
->GetPrefSize();
509 if ( pGraphic
->GetPrefMapMode().GetMapUnit() == MAP_PIXEL
)
511 OutputDevice
* pOutDev
= Application::GetDefaultDevice();
512 MapMode
aOldMap( pOutDev
->GetMapMode() );
513 pOutDev
->SetMapMode( aMapMM100
);
514 aRetSize
= pOutDev
->PixelToLogic( rSize
);
515 pOutDev
->SetMapMode( aOldMap
);
518 aRetSize
= OutputDevice::LogicToLogic( rSize
, pGraphic
->GetPrefMapMode(), aMapMM100
);
522 OUString
SvxNumberFormat::CreateRomanString( sal_uLong nNo
, bool bUpper
)
524 nNo
%= 4000; // more can not be displayed
525 // i, ii, iii, iv, v, vi, vii, vii, viii, ix
526 // (Dummy),1000,500,100,50,10,5,1
527 const char *cRomanArr
= bUpper
528 ? "MDCLXVI--" // +2 Dummy entries!
529 : "mdclxvi--"; // +2 Dummy entries!
532 sal_uInt16 nMask
= 1000;
535 sal_uInt8 nZahl
= sal_uInt8(nNo
/ nMask
);
542 sRet
+= OUString(*(cRomanArr
-1));
548 case 3: { sRet
+= OUString(*cRomanArr
); }
549 case 2: { sRet
+= OUString(*cRomanArr
); }
550 case 1: { sRet
+= OUString(*cRomanArr
); }
554 sRet
+= OUString(*cRomanArr
);
555 sRet
+= OUString(*(cRomanArr
-nDiff
));
558 case 5: { sRet
+= OUString(*(cRomanArr
-nDiff
)); }
562 nMask
/= 10; // for the next decade
568 OUString
SvxNumberFormat::GetCharFormatName()const
570 return sCharStyleName
;
573 sal_Int32
SvxNumRule::nRefCount
= 0;
574 static SvxNumberFormat
* pStdNumFmt
= 0;
575 static SvxNumberFormat
* pStdOutlineNumFmt
= 0;
576 SvxNumRule::SvxNumRule( SvxNumRuleFlags nFeatures
,
579 SvxNumRuleType eType
,
580 SvxNumberFormat::SvxNumPositionAndSpaceMode
581 eDefaultNumberFormatPositionAndSpaceMode
)
582 : nLevelCount(nLevels
),
583 nFeatureFlags(nFeatures
),
584 eNumberingType(eType
),
585 bContinuousNumbering(bCont
)
588 for(sal_uInt16 i
= 0; i
< SVX_MAX_NUM
; i
++)
592 aFmts
[i
] = new SvxNumberFormat(SVX_NUM_CHARS_UPPER_LETTER
);
593 // It is a distinction between writer and draw
594 if(nFeatures
& SvxNumRuleFlags::CONTINUOUS
)
596 if ( eDefaultNumberFormatPositionAndSpaceMode
==
597 SvxNumberFormat::LABEL_WIDTH_AND_POSITION
)
599 aFmts
[i
]->SetAbsLSpace( convertMm100ToTwip(DEF_WRITER_LSPACE
* (i
+1)) );
600 aFmts
[i
]->SetFirstLineOffset(convertMm100ToTwip(-DEF_WRITER_LSPACE
));
602 else if ( eDefaultNumberFormatPositionAndSpaceMode
==
603 SvxNumberFormat::LABEL_ALIGNMENT
)
605 // first line indent of general numbering in inch: -0,25 inch
606 const long cFirstLineIndent
= -1440/4;
607 // indent values of general numbering in inch:
608 // 0,5 0,75 1,0 1,25 1,5
609 // 1,75 2,0 2,25 2,5 2,75
610 const long cIndentAt
= 1440/4;
611 aFmts
[i
]->SetPositionAndSpaceMode( SvxNumberFormat::LABEL_ALIGNMENT
);
612 aFmts
[i
]->SetLabelFollowedBy( SvxNumberFormat::LISTTAB
);
613 aFmts
[i
]->SetListtabPos( cIndentAt
* (i
+2) );
614 aFmts
[i
]->SetFirstLineIndent( cFirstLineIndent
);
615 aFmts
[i
]->SetIndentAt( cIndentAt
* (i
+2) );
620 aFmts
[i
]->SetAbsLSpace( DEF_DRAW_LSPACE
* (i
) );
629 SvxNumRule::SvxNumRule(const SvxNumRule
& rCopy
)
632 aLocale
= rCopy
.aLocale
;
633 nLevelCount
= rCopy
.nLevelCount
;
634 nFeatureFlags
= rCopy
.nFeatureFlags
;
635 bContinuousNumbering
= rCopy
.bContinuousNumbering
;
636 eNumberingType
= rCopy
.eNumberingType
;
637 memset( aFmts
, 0, sizeof( aFmts
));
638 for(sal_uInt16 i
= 0; i
< SVX_MAX_NUM
; i
++)
641 aFmts
[i
] = new SvxNumberFormat(*rCopy
.aFmts
[i
]);
644 aFmtsSet
[i
] = rCopy
.aFmtsSet
[i
];
648 SvxNumRule::SvxNumRule( SvStream
&rStream
)
651 sal_uInt16
nTmp16(0);
652 rStream
.ReadUInt16( nTmp16
); // NUM_ITEM_VERSION
653 rStream
.ReadUInt16( nLevelCount
);
655 // first nFeatureFlags of old Versions
656 rStream
.ReadUInt16( nTmp16
); nFeatureFlags
= static_cast<SvxNumRuleFlags
>(nTmp16
);
657 rStream
.ReadUInt16( nTmp16
); bContinuousNumbering
= nTmp16
;
658 rStream
.ReadUInt16( nTmp16
); eNumberingType
= ( SvxNumRuleType
)nTmp16
;
660 for (sal_uInt16 i
= 0; i
< SVX_MAX_NUM
; i
++)
662 rStream
.ReadUInt16( nTmp16
);
663 bool hasNumberingFormat
= nTmp16
& 1;
664 aFmtsSet
[i
] = nTmp16
& 2; // fdo#68648 reset flag
665 if ( hasNumberingFormat
){
666 aFmts
[i
] = new SvxNumberFormat( rStream
);
671 aFmtsSet
[i
] = false; // actually only false is valid
674 //second nFeatureFlags for new versions
675 rStream
.ReadUInt16( nTmp16
); nFeatureFlags
= static_cast<SvxNumRuleFlags
>(nTmp16
);
678 SvStream
& SvxNumRule::Store( SvStream
&rStream
)
680 rStream
.WriteUInt16( NUMITEM_VERSION_03
);
681 rStream
.WriteUInt16( nLevelCount
);
682 //first save of nFeatureFlags for old versions
683 rStream
.WriteUInt16( static_cast<sal_uInt16
>(nFeatureFlags
) );
684 rStream
.WriteUInt16( sal_uInt16(bContinuousNumbering
) );
685 rStream
.WriteUInt16( static_cast<sal_uInt16
>(eNumberingType
) );
687 FontToSubsFontConverter pConverter
= 0;
688 bool bConvertBulletFont
= ( rStream
.GetVersion() <= SOFFICE_FILEFORMAT_50
) && ( rStream
.GetVersion() );
689 for(sal_uInt16 i
= 0; i
< SVX_MAX_NUM
; i
++)
691 sal_uInt16
nSetFlag(aFmtsSet
[i
] ? 2 : 0); // fdo#68648 store that too
694 rStream
.WriteUInt16( 1 | nSetFlag
);
695 if(bConvertBulletFont
&& aFmts
[i
]->GetBulletFont())
699 CreateFontToSubsFontConverter(aFmts
[i
]->GetBulletFont()->GetName(),
700 FontToSubsFontFlags::EXPORT
|FontToSubsFontFlags::ONLYOLDSOSYMBOLFONTS
);
702 aFmts
[i
]->Store(rStream
, pConverter
);
705 rStream
.WriteUInt16( 0 | nSetFlag
);
707 //second save of nFeatureFlags for new versions
708 rStream
.WriteUInt16( static_cast<sal_uInt16
>(nFeatureFlags
) );
710 DestroyFontToSubsFontConverter(pConverter
);
714 SvxNumRule::~SvxNumRule()
716 for(sal_uInt16 i
= 0; i
< SVX_MAX_NUM
; i
++)
721 DELETEZ(pStdOutlineNumFmt
);
725 SvxNumRule
& SvxNumRule::operator=( const SvxNumRule
& rCopy
)
727 nLevelCount
= rCopy
.nLevelCount
;
728 nFeatureFlags
= rCopy
.nFeatureFlags
;
729 bContinuousNumbering
= rCopy
.bContinuousNumbering
;
730 eNumberingType
= rCopy
.eNumberingType
;
731 for(sal_uInt16 i
= 0; i
< SVX_MAX_NUM
; i
++)
735 aFmts
[i
] = new SvxNumberFormat(*rCopy
.aFmts
[i
]);
738 aFmtsSet
[i
] = rCopy
.aFmtsSet
[i
];
743 bool SvxNumRule::operator==( const SvxNumRule
& rCopy
) const
745 if(nLevelCount
!= rCopy
.nLevelCount
||
746 nFeatureFlags
!= rCopy
.nFeatureFlags
||
747 bContinuousNumbering
!= rCopy
.bContinuousNumbering
||
748 eNumberingType
!= rCopy
.eNumberingType
)
750 for(sal_uInt16 i
= 0; i
< nLevelCount
; i
++)
753 (aFmtsSet
[i
] != rCopy
.aFmtsSet
[i
]) ||
754 (!aFmts
[i
] && rCopy
.aFmts
[i
]) ||
755 (aFmts
[i
] && !rCopy
.aFmts
[i
]) ||
756 (aFmts
[i
] && *aFmts
[i
] != *rCopy
.aFmts
[i
])
765 const SvxNumberFormat
* SvxNumRule::Get(sal_uInt16 nLevel
)const
767 DBG_ASSERT(nLevel
< SVX_MAX_NUM
, "Wrong Level" );
768 if( nLevel
< SVX_MAX_NUM
)
769 return aFmtsSet
[nLevel
] ? aFmts
[nLevel
] : 0;
774 const SvxNumberFormat
& SvxNumRule::GetLevel(sal_uInt16 nLevel
)const
778 pStdNumFmt
= new SvxNumberFormat(SVX_NUM_ARABIC
);
779 pStdOutlineNumFmt
= new SvxNumberFormat(SVX_NUM_NUMBER_NONE
);
782 DBG_ASSERT(nLevel
< SVX_MAX_NUM
, "Wrong Level" );
784 return ( ( nLevel
< SVX_MAX_NUM
) && aFmts
[nLevel
] ) ?
785 *aFmts
[nLevel
] : eNumberingType
== SvxNumRuleType::NUMBERING
?
786 *pStdNumFmt
: *pStdOutlineNumFmt
;
789 void SvxNumRule::SetLevel( sal_uInt16 i
, const SvxNumberFormat
& rNumFmt
, bool bIsValid
)
791 DBG_ASSERT(i
< SVX_MAX_NUM
, "Wrong Level" );
793 if( (i
< SVX_MAX_NUM
) )
795 bool bReplace
= !aFmtsSet
[i
];
798 const SvxNumberFormat
*pFmt
= Get(i
);
799 bReplace
= pFmt
== nullptr || rNumFmt
!= *pFmt
;
805 aFmts
[i
] = new SvxNumberFormat(rNumFmt
);
806 aFmtsSet
[i
] = bIsValid
;
811 void SvxNumRule::SetLevel(sal_uInt16 nLevel
, const SvxNumberFormat
* pFmt
)
813 DBG_ASSERT(nLevel
< SVX_MAX_NUM
, "Wrong Level" );
815 if( nLevel
< SVX_MAX_NUM
)
817 aFmtsSet
[nLevel
] = 0 != pFmt
;
819 SetLevel(nLevel
, *pFmt
);
822 delete aFmts
[nLevel
];
828 OUString
SvxNumRule::MakeNumString( const SvxNodeNum
& rNum
, bool bInclStrings
) const
831 if( SVX_NO_NUM
> rNum
.GetLevel() && !( SVX_NO_NUMLEVEL
& rNum
.GetLevel() ) )
833 const SvxNumberFormat
& rMyNFmt
= GetLevel( rNum
.GetLevel() );
834 if( SVX_NUM_NUMBER_NONE
!= rMyNFmt
.GetNumberingType() )
836 sal_uInt8 i
= rNum
.GetLevel();
838 if( !IsContinuousNumbering() &&
839 1 < rMyNFmt
.GetIncludeUpperLevels() ) // only on own level?
841 sal_uInt8 n
= rMyNFmt
.GetIncludeUpperLevels();
851 for( ; i
<= rNum
.GetLevel(); ++i
)
853 const SvxNumberFormat
& rNFmt
= GetLevel( i
);
854 if( SVX_NUM_NUMBER_NONE
== rNFmt
.GetNumberingType() )
860 if( rNum
.GetLevelVal()[ i
] )
862 if(SVX_NUM_BITMAP
!= rNFmt
.GetNumberingType())
863 aStr
+= rNFmt
.GetNumStr( rNum
.GetLevelVal()[ i
], aLocale
);
868 aStr
+= "0"; // all 0-levels are a 0
869 if( i
!= rNum
.GetLevel() && bDot
)
876 aStr
= rMyNFmt
.GetPrefix() + aStr
+ rMyNFmt
.GetSuffix();
882 // changes linked to embedded bitmaps
883 bool SvxNumRule::UnLinkGraphics()
886 for(sal_uInt16 i
= 0; i
< GetLevelCount(); i
++)
888 SvxNumberFormat
aFmt(GetLevel(i
));
889 const SvxBrushItem
* pBrush
= aFmt
.GetBrush();
890 const Graphic
* pGraphic
= NULL
;
891 if(SVX_NUM_BITMAP
== aFmt
.GetNumberingType())
894 !pBrush
->GetGraphicLink().isEmpty() &&
895 0 != (pGraphic
= pBrush
->GetGraphic()))
897 SvxBrushItem
aTempItem(*pBrush
);
898 aTempItem
.SetGraphicLink("");
899 aTempItem
.SetGraphic(*pGraphic
);
900 sal_Int16 eOrient
= aFmt
.GetVertOrient();
901 aFmt
.SetGraphicBrush( &aTempItem
, &aFmt
.GetGraphicSize(), &eOrient
);
905 else if((SVX_NUM_BITMAP
|LINK_TOKEN
) == aFmt
.GetNumberingType())
906 aFmt
.SetNumberingType(SVX_NUM_BITMAP
);
912 SvxNumBulletItem::SvxNumBulletItem(SvxNumRule
& rRule
) :
913 SfxPoolItem(SID_ATTR_NUMBERING_RULE
),
914 pNumRule(new SvxNumRule(rRule
))
918 SvxNumBulletItem::SvxNumBulletItem(SvxNumRule
& rRule
, sal_uInt16 _nWhich
) :
919 SfxPoolItem(_nWhich
),
920 pNumRule(new SvxNumRule(rRule
))
924 SfxPoolItem
* SvxNumBulletItem::Create(SvStream
&rStream
, sal_uInt16
/*nItemVersion*/ ) const
926 SvxNumRule
aNumRule( rStream
);
927 return new SvxNumBulletItem( aNumRule
, EE_PARA_NUMBULLET
);
930 SvxNumBulletItem::SvxNumBulletItem(const SvxNumBulletItem
& rCopy
) :
931 SfxPoolItem(rCopy
.Which())
933 pNumRule
= new SvxNumRule(*rCopy
.pNumRule
);
936 SvxNumBulletItem::~SvxNumBulletItem()
941 bool SvxNumBulletItem::operator==( const SfxPoolItem
& rCopy
) const
943 return *pNumRule
== *static_cast<const SvxNumBulletItem
&>(rCopy
).pNumRule
;
946 SfxPoolItem
* SvxNumBulletItem::Clone( SfxItemPool
* ) const
948 return new SvxNumBulletItem(*this);
951 sal_uInt16
SvxNumBulletItem::GetVersion( sal_uInt16
/*nFileVersion*/ ) const
953 return NUMITEM_VERSION_03
;
956 SvStream
& SvxNumBulletItem::Store(SvStream
&rStream
, sal_uInt16
/*nItemVersion*/ )const
958 pNumRule
->Store(rStream
);
962 bool SvxNumBulletItem::QueryValue( com::sun::star::uno::Any
& rVal
, sal_uInt8
/*nMemberId*/ ) const
964 rVal
<<= SvxCreateNumRule( pNumRule
);
968 bool SvxNumBulletItem::PutValue( const com::sun::star::uno::Any
& rVal
, sal_uInt8
/*nMemberId*/ )
970 uno::Reference
< container::XIndexReplace
> xRule
;
975 SvxNumRule
* pNewRule
= new SvxNumRule( SvxGetNumRule( xRule
) );
976 if( pNewRule
->GetLevelCount() != pNumRule
->GetLevelCount() ||
977 pNewRule
->GetNumRuleType() != pNumRule
->GetNumRuleType() )
979 SvxNumRule
* pConverted
= SvxConvertNumRule( pNewRule
, pNumRule
->GetLevelCount(), pNumRule
->GetNumRuleType() );
981 pNewRule
= pConverted
;
987 catch(const lang::IllegalArgumentException
&)
994 SvxNumRule
* SvxConvertNumRule( const SvxNumRule
* pRule
, sal_uInt16 nLevels
, SvxNumRuleType eType
)
996 const sal_uInt16 nSrcLevels
= pRule
->GetLevelCount();
997 SvxNumRule
* pNewRule
= new SvxNumRule( pRule
->GetFeatureFlags(), nLevels
, pRule
->IsContinuousNumbering(), eType
);
999 for( sal_uInt16 nLevel
= 0; (nLevel
< nLevels
) && (nLevel
< nSrcLevels
); nLevel
++ )
1000 pNewRule
->SetLevel( nLevel
, pRule
->GetLevel( nLevel
) );
1005 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */