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 <editeng/editids.hrc>
29 #include <editeng/editrids.hrc>
30 #include <editeng/numdef.hxx>
31 #include <editeng/eeitem.hxx>
32 #include <vcl/graph.hxx>
33 #include <vcl/window.hxx>
34 #include <vcl/svapp.hxx>
35 #include <editeng/unolingu.hxx>
36 #include <com/sun/star/text/XNumberingFormatter.hpp>
37 #include <com/sun/star/text/DefaultNumberingProvider.hpp>
38 #include <com/sun/star/text/XDefaultNumberingProvider.hpp>
39 #include <com/sun/star/style/NumberingType.hpp>
40 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
41 #include <com/sun/star/beans/PropertyValue.hpp>
42 #include <comphelper/processfactory.hxx>
44 #include <editeng/unonrule.hxx>
46 #define MM100_TO_TWIP(MM100) ((MM100*72L+63L)/127L)
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 String
SvxNumberType::GetNumStr( sal_uLong nNo
) const
102 const LanguageTag
& rLang
= Application::GetSettings().GetLanguageTag();
103 return GetNumStr( nNo
, rLang
.getLocale() );
106 String
SvxNumberType::GetNumStr( sal_uLong nNo
, const Locale
& rLocale
) const
108 lcl_getFormatter(xFormatter
);
117 case NumberingType::CHAR_SPECIAL
:
118 case NumberingType::BITMAP
:
122 // '0' allowed for ARABIC numberings
123 if(NumberingType::ARABIC
== nNumType
&& 0 == nNo
)
127 Sequence
< PropertyValue
> aProperties(2);
128 PropertyValue
* pValues
= aProperties
.getArray();
129 pValues
[0].Name
= OUString("NumberingType");
130 pValues
[0].Value
<<= nNumType
;
131 pValues
[1].Name
= OUString("Value");
132 pValues
[1].Value
<<= (sal_Int32
)nNo
;
136 aTmpStr
= xFormatter
->makeNumberingString( aProperties
, rLocale
);
138 catch(const Exception
&)
148 SvxNumberFormat::SvxNumberFormat( sal_Int16 eType
,
149 SvxNumPositionAndSpaceMode ePositionAndSpaceMode
)
150 : SvxNumberType(eType
),
151 eNumAdjust(SVX_ADJUST_LEFT
),
154 cBullet(SVX_DEF_BULLET
),
156 nBulletColor(COL_BLACK
),
157 mePositionAndSpaceMode( ePositionAndSpaceMode
),
161 nCharTextDistance(0),
162 meLabelFollowedBy( LISTTAB
),
164 mnFirstLineIndent( 0 ),
167 eVertOrient(text::VertOrientation::NONE
),
172 SvxNumberFormat::SvxNumberFormat(const SvxNumberFormat
& rFormat
) :
173 SvxNumberType(rFormat
),
174 mePositionAndSpaceMode( rFormat
.mePositionAndSpaceMode
),
181 SvxNumberFormat::SvxNumberFormat( SvStream
&rStream
)
185 rStream
>> nTmp16
; // Version number
187 rStream
>> nTmp16
; SetNumberingType( nTmp16
);
188 rStream
>> nTmp16
; eNumAdjust
= ( SvxAdjust
)nTmp16
;
189 rStream
>> nTmp16
; nInclUpperLevels
= nTmp16
;
191 rStream
>> nTmp16
; cBullet
= (sal_Unicode
)nTmp16
;
193 rStream
>> nFirstLineOffset
;
194 rStream
>> nAbsLSpace
;
197 rStream
>> nCharTextDistance
;
199 sPrefix
= rStream
.ReadUniOrByteString( rStream
.GetStreamCharSet() );
200 sSuffix
= rStream
.ReadUniOrByteString( rStream
.GetStreamCharSet() );
201 sCharStyleName
= rStream
.ReadUniOrByteString( rStream
.GetStreamCharSet() );
203 sal_uInt16 hasGraphicBrush
= 0;
204 rStream
>> hasGraphicBrush
;
205 if ( hasGraphicBrush
)
207 pGraphicBrush
= new SvxBrushItem( SID_ATTR_BRUSH
);
208 pGraphicBrush
= (SvxBrushItem
*)(pGraphicBrush
->Create( rStream
, BRUSH_GRAPHIC_VERSION
));
210 else pGraphicBrush
= 0;
211 rStream
>> nTmp16
; eVertOrient
= nTmp16
;
213 sal_uInt16 hasBulletFont
= 0;
214 rStream
>> hasBulletFont
;
217 pBulletFont
= new Font( );
218 rStream
>> *pBulletFont
;
220 else pBulletFont
= NULL
;
221 rStream
>> aGraphicSize
;
223 rStream
>> nBulletColor
;
224 rStream
>> nBulletRelSize
;
225 rStream
>> nTmp16
; SetShowSymbol( nTmp16
);
227 rStream
>> nTmp16
; mePositionAndSpaceMode
= ( SvxNumPositionAndSpaceMode
)nTmp16
;
228 rStream
>> nTmp16
; meLabelFollowedBy
= ( LabelFollowedBy
)nTmp16
;
229 rStream
>> nTmp32
; mnListtabPos
= nTmp32
;
230 rStream
>> nTmp32
; mnFirstLineIndent
= nTmp32
;
231 rStream
>> nTmp32
; mnIndentAt
= nTmp32
;
234 SvxNumberFormat::~SvxNumberFormat()
236 delete pGraphicBrush
;
240 SvStream
& SvxNumberFormat::Store(SvStream
&rStream
, FontToSubsFontConverter pConverter
)
242 if(pConverter
&& pBulletFont
)
244 cBullet
= ConvertFontToSubsFontChar(pConverter
, cBullet
);
245 String sFontName
= GetFontToSubsFontName(pConverter
);
246 pBulletFont
->SetName(sFontName
);
249 rStream
<< (sal_uInt16
)NUMITEM_VERSION_04
;
251 rStream
<< (sal_uInt16
)GetNumberingType();
252 rStream
<< (sal_uInt16
)eNumAdjust
;
253 rStream
<< (sal_uInt16
)nInclUpperLevels
;
255 rStream
<< (sal_uInt16
)cBullet
;
257 rStream
<< nFirstLineOffset
;
258 rStream
<< nAbsLSpace
;
261 rStream
<< nCharTextDistance
;
262 rtl_TextEncoding eEnc
= osl_getThreadTextEncoding();
263 rStream
.WriteUniOrByteString(sPrefix
, eEnc
);
264 rStream
.WriteUniOrByteString(sSuffix
, eEnc
);
265 rStream
.WriteUniOrByteString(sCharStyleName
, eEnc
);
268 rStream
<< (sal_uInt16
)1;
270 // in SD or SI force bullet itself to be stored,
271 // for that purpose throw away link when link and graphic
272 // are present, so Brush save is forced
273 if(pGraphicBrush
->GetGraphicLink() && pGraphicBrush
->GetGraphic())
276 pGraphicBrush
->SetGraphicLink(aEmpty
);
279 pGraphicBrush
->Store(rStream
, BRUSH_GRAPHIC_VERSION
);
282 rStream
<< (sal_uInt16
)0;
284 rStream
<< (sal_uInt16
)eVertOrient
;
287 rStream
<< (sal_uInt16
)1;
288 rStream
<< *pBulletFont
;
291 rStream
<< (sal_uInt16
)0;
292 rStream
<< aGraphicSize
;
294 Color nTempColor
= nBulletColor
;
295 if(COL_AUTO
== nBulletColor
.GetColor())
296 nTempColor
= COL_BLACK
;
297 rStream
<< nTempColor
;
298 rStream
<< nBulletRelSize
;
299 rStream
<< (sal_uInt16
)IsShowSymbol();
301 rStream
<< ( sal_uInt16
) mePositionAndSpaceMode
;
302 rStream
<< ( sal_uInt16
) meLabelFollowedBy
;
303 rStream
<< ( sal_Int32
) mnListtabPos
;
304 rStream
<< ( sal_Int32
) mnFirstLineIndent
;
305 rStream
<< ( sal_Int32
) mnIndentAt
;
310 SvxNumberFormat
* SvxNumberFormat::Create( SvStream
&rStream
)
312 return new SvxNumberFormat( rStream
);
315 SvxNumberFormat
& SvxNumberFormat::operator=( const SvxNumberFormat
& rFormat
)
317 if (& rFormat
== this) { return *this; }
319 SetNumberingType(rFormat
.GetNumberingType());
320 eNumAdjust
= rFormat
.eNumAdjust
;
321 nInclUpperLevels
= rFormat
.nInclUpperLevels
;
322 nStart
= rFormat
.nStart
;
323 cBullet
= rFormat
.cBullet
;
324 mePositionAndSpaceMode
= rFormat
.mePositionAndSpaceMode
;
325 nFirstLineOffset
= rFormat
.nFirstLineOffset
;
326 nAbsLSpace
= rFormat
.nAbsLSpace
;
327 nLSpace
= rFormat
.nLSpace
;
328 nCharTextDistance
= rFormat
.nCharTextDistance
;
329 meLabelFollowedBy
= rFormat
.meLabelFollowedBy
;
330 mnListtabPos
= rFormat
.mnListtabPos
;
331 mnFirstLineIndent
= rFormat
.mnFirstLineIndent
;
332 mnIndentAt
= rFormat
.mnIndentAt
;
333 eVertOrient
= rFormat
.eVertOrient
;
334 sPrefix
= rFormat
.sPrefix
;
335 sSuffix
= rFormat
.sSuffix
;
336 aGraphicSize
= rFormat
.aGraphicSize
;
337 nBulletColor
= rFormat
.nBulletColor
;
338 nBulletRelSize
= rFormat
.nBulletRelSize
;
339 SetShowSymbol(rFormat
.IsShowSymbol());
340 sCharStyleName
= rFormat
.sCharStyleName
;
341 DELETEZ(pGraphicBrush
);
342 if(rFormat
.pGraphicBrush
)
344 pGraphicBrush
= new SvxBrushItem(*rFormat
.pGraphicBrush
);
345 pGraphicBrush
->SetDoneLink( STATIC_LINK( this, SvxNumberFormat
, GraphicArrived
) );
347 DELETEZ(pBulletFont
);
348 if(rFormat
.pBulletFont
)
349 pBulletFont
= new Font(*rFormat
.pBulletFont
);
353 sal_Bool
SvxNumberFormat::operator==( const SvxNumberFormat
& rFormat
) const
355 if( GetNumberingType() != rFormat
.GetNumberingType() ||
356 eNumAdjust
!= rFormat
.eNumAdjust
||
357 nInclUpperLevels
!= rFormat
.nInclUpperLevels
||
358 nStart
!= rFormat
.nStart
||
359 cBullet
!= rFormat
.cBullet
||
360 mePositionAndSpaceMode
!= rFormat
.mePositionAndSpaceMode
||
361 nFirstLineOffset
!= rFormat
.nFirstLineOffset
||
362 nAbsLSpace
!= rFormat
.nAbsLSpace
||
363 nLSpace
!= rFormat
.nLSpace
||
364 nCharTextDistance
!= rFormat
.nCharTextDistance
||
365 meLabelFollowedBy
!= rFormat
.meLabelFollowedBy
||
366 mnListtabPos
!= rFormat
.mnListtabPos
||
367 mnFirstLineIndent
!= rFormat
.mnFirstLineIndent
||
368 mnIndentAt
!= rFormat
.mnIndentAt
||
369 eVertOrient
!= rFormat
.eVertOrient
||
370 sPrefix
!= rFormat
.sPrefix
||
371 sSuffix
!= rFormat
.sSuffix
||
372 aGraphicSize
!= rFormat
.aGraphicSize
||
373 nBulletColor
!= rFormat
.nBulletColor
||
374 nBulletRelSize
!= rFormat
.nBulletRelSize
||
375 IsShowSymbol() != rFormat
.IsShowSymbol() ||
376 sCharStyleName
!= rFormat
.sCharStyleName
380 (pGraphicBrush
&& !rFormat
.pGraphicBrush
) ||
381 (!pGraphicBrush
&& rFormat
.pGraphicBrush
) ||
382 (pGraphicBrush
&& *pGraphicBrush
!= *rFormat
.pGraphicBrush
)
388 (pBulletFont
&& !rFormat
.pBulletFont
) ||
389 (!pBulletFont
&& rFormat
.pBulletFont
) ||
390 (pBulletFont
&& *pBulletFont
!= *rFormat
.pBulletFont
)
398 void SvxNumberFormat::SetGraphicBrush( const SvxBrushItem
* pBrushItem
,
399 const Size
* pSize
, const sal_Int16
* pOrient
)
403 delete pGraphicBrush
;
406 else if ( !pGraphicBrush
|| (pGraphicBrush
&& !(*pBrushItem
== *pGraphicBrush
)) )
408 delete pGraphicBrush
;
409 pGraphicBrush
= (SvxBrushItem
*)pBrushItem
->Clone();
410 pGraphicBrush
->SetDoneLink( STATIC_LINK( this, SvxNumberFormat
, GraphicArrived
) );
414 eVertOrient
= *pOrient
;
416 eVertOrient
= text::VertOrientation::NONE
;
418 aGraphicSize
= *pSize
;
420 aGraphicSize
.Width() = aGraphicSize
.Height() = 0;
423 void SvxNumberFormat::SetGraphic( const String
& rName
)
427 0 != (pName
= pGraphicBrush
->GetGraphicLink())
431 delete pGraphicBrush
;
433 pGraphicBrush
= new SvxBrushItem( rName
, sTmp
, GPOS_AREA
, 0 );
434 pGraphicBrush
->SetDoneLink( STATIC_LINK( this, SvxNumberFormat
, GraphicArrived
) );
435 if( eVertOrient
== text::VertOrientation::NONE
)
436 eVertOrient
= text::VertOrientation::TOP
;
438 aGraphicSize
.Width() = aGraphicSize
.Height() = 0;
441 void SvxNumberFormat::SetVertOrient(sal_Int16 eSet
)
446 sal_Int16
SvxNumberFormat::GetVertOrient() const
451 void SvxNumberFormat::SetBulletFont(const Font
* pFont
)
454 pBulletFont
= pFont
? new Font(*pFont
): 0;
457 SvxNumberFormat::SvxNumPositionAndSpaceMode
SvxNumberFormat::GetPositionAndSpaceMode() const
459 return mePositionAndSpaceMode
;
461 void SvxNumberFormat::SetPositionAndSpaceMode( SvxNumPositionAndSpaceMode ePositionAndSpaceMode
)
463 mePositionAndSpaceMode
= ePositionAndSpaceMode
;
466 short SvxNumberFormat::GetLSpace() const
468 return mePositionAndSpaceMode
== LABEL_WIDTH_AND_POSITION
? nLSpace
: 0;
470 short SvxNumberFormat::GetAbsLSpace() const
472 return mePositionAndSpaceMode
== LABEL_WIDTH_AND_POSITION
474 : static_cast<short>( GetFirstLineIndent() + GetIndentAt() );
476 short SvxNumberFormat::GetFirstLineOffset() const
478 return mePositionAndSpaceMode
== LABEL_WIDTH_AND_POSITION
480 : static_cast<short>( GetFirstLineIndent() );
482 short SvxNumberFormat::GetCharTextDistance() const
484 return mePositionAndSpaceMode
== LABEL_WIDTH_AND_POSITION
? nCharTextDistance
: 0;
487 void SvxNumberFormat::SetLabelFollowedBy( const LabelFollowedBy eLabelFollowedBy
)
489 meLabelFollowedBy
= eLabelFollowedBy
;
491 SvxNumberFormat::LabelFollowedBy
SvxNumberFormat::GetLabelFollowedBy() const
493 return meLabelFollowedBy
;
495 void SvxNumberFormat::SetListtabPos( const long nListtabPos
)
497 mnListtabPos
= nListtabPos
;
499 long SvxNumberFormat::GetListtabPos() const
503 void SvxNumberFormat::SetFirstLineIndent( const long nFirstLineIndent
)
505 mnFirstLineIndent
= nFirstLineIndent
;
507 long SvxNumberFormat::GetFirstLineIndent() const
509 return mnFirstLineIndent
;
511 void SvxNumberFormat::SetIndentAt( const long nIndentAt
)
513 mnIndentAt
= nIndentAt
;
515 long SvxNumberFormat::GetIndentAt() const
520 IMPL_STATIC_LINK( SvxNumberFormat
, GraphicArrived
, void *, EMPTYARG
)
522 // if necessary, set the GrfSize:
523 if( !pThis
->aGraphicSize
.Width() || !pThis
->aGraphicSize
.Height() )
525 const Graphic
* pGrf
= pThis
->pGraphicBrush
->GetGraphic();
527 pThis
->aGraphicSize
= SvxNumberFormat::GetGraphicSizeMM100( pGrf
);
529 pThis
->NotifyGraphicArrived();
533 void SvxNumberFormat::NotifyGraphicArrived()
537 Size
SvxNumberFormat::GetGraphicSizeMM100(const Graphic
* pGraphic
)
539 const MapMode
aMapMM100( MAP_100TH_MM
);
540 const Size
& rSize
= pGraphic
->GetPrefSize();
542 if ( pGraphic
->GetPrefMapMode().GetMapUnit() == MAP_PIXEL
)
544 OutputDevice
* pOutDev
= Application::GetDefaultDevice();
545 MapMode
aOldMap( pOutDev
->GetMapMode() );
546 pOutDev
->SetMapMode( aMapMM100
);
547 aRetSize
= pOutDev
->PixelToLogic( rSize
);
548 pOutDev
->SetMapMode( aOldMap
);
551 aRetSize
= OutputDevice::LogicToLogic( rSize
, pGraphic
->GetPrefMapMode(), aMapMM100
);
555 String
SvxNumberFormat::CreateRomanString( sal_uLong nNo
, sal_Bool bUpper
)
557 nNo
%= 4000; // more can not be displayed
558 // i, ii, iii, iv, v, vi, vii, vii, viii, ix
559 // (Dummy),1000,500,100,50,10,5,1
560 const char *cRomanArr
= bUpper
561 ? "MDCLXVI--" // +2 Dummy entries!
562 : "mdclxvi--"; // +2 Dummy entries!
565 sal_uInt16 nMask
= 1000;
568 sal_uInt8 nZahl
= sal_uInt8(nNo
/ nMask
);
575 sRet
+= sal_Unicode(*(cRomanArr
-1));
581 case 3: { sRet
+= sal_Unicode(*cRomanArr
); }
582 case 2: { sRet
+= sal_Unicode(*cRomanArr
); }
583 case 1: { sRet
+= sal_Unicode(*cRomanArr
); }
587 sRet
+= sal_Unicode(*cRomanArr
);
588 sRet
+= sal_Unicode(*(cRomanArr
-nDiff
));
591 case 5: { sRet
+= sal_Unicode(*(cRomanArr
-nDiff
)); }
595 nMask
/= 10; // for the next decade
601 const String
& SvxNumberFormat::GetCharFmtName()const
603 return sCharStyleName
;
606 sal_Int32
SvxNumRule::nRefCount
= 0;
607 static SvxNumberFormat
* pStdNumFmt
= 0;
608 static SvxNumberFormat
* pStdOutlineNumFmt
= 0;
609 SvxNumRule::SvxNumRule( sal_uLong nFeatures
,
612 SvxNumRuleType eType
,
613 SvxNumberFormat::SvxNumPositionAndSpaceMode
614 eDefaultNumberFormatPositionAndSpaceMode
)
615 : nLevelCount(nLevels
),
616 nFeatureFlags(nFeatures
),
617 eNumberingType(eType
),
618 bContinuousNumbering(bCont
)
621 for(sal_uInt16 i
= 0; i
< SVX_MAX_NUM
; i
++)
625 aFmts
[i
] = new SvxNumberFormat(SVX_NUM_CHARS_UPPER_LETTER
);
626 // It is a distinction between writer and draw
627 if(nFeatures
& NUM_CONTINUOUS
)
629 if ( eDefaultNumberFormatPositionAndSpaceMode
==
630 SvxNumberFormat::LABEL_WIDTH_AND_POSITION
)
632 aFmts
[i
]->SetLSpace( MM100_TO_TWIP(DEF_WRITER_LSPACE
) );
633 aFmts
[i
]->SetAbsLSpace( MM100_TO_TWIP(DEF_WRITER_LSPACE
* (i
+1)) );
634 aFmts
[i
]->SetFirstLineOffset(MM100_TO_TWIP(-DEF_WRITER_LSPACE
));
636 else if ( eDefaultNumberFormatPositionAndSpaceMode
==
637 SvxNumberFormat::LABEL_ALIGNMENT
)
639 // first line indent of general numbering in inch: -0,25 inch
640 const long cFirstLineIndent
= -1440/4;
641 // indent values of general numbering in inch:
642 // 0,5 0,75 1,0 1,25 1,5
643 // 1,75 2,0 2,25 2,5 2,75
644 const long cIndentAt
= 1440/4;
645 aFmts
[i
]->SetPositionAndSpaceMode( SvxNumberFormat::LABEL_ALIGNMENT
);
646 aFmts
[i
]->SetLabelFollowedBy( SvxNumberFormat::LISTTAB
);
647 aFmts
[i
]->SetListtabPos( cIndentAt
* (i
+2) );
648 aFmts
[i
]->SetFirstLineIndent( cFirstLineIndent
);
649 aFmts
[i
]->SetIndentAt( cIndentAt
* (i
+2) );
654 aFmts
[i
]->SetLSpace( DEF_DRAW_LSPACE
);
655 aFmts
[i
]->SetAbsLSpace( DEF_DRAW_LSPACE
* (i
) );
660 aFmtsSet
[i
] = sal_False
;
664 SvxNumRule::SvxNumRule(const SvxNumRule
& rCopy
)
667 aLocale
= rCopy
.aLocale
;
668 nLevelCount
= rCopy
.nLevelCount
;
669 nFeatureFlags
= rCopy
.nFeatureFlags
;
670 bContinuousNumbering
= rCopy
.bContinuousNumbering
;
671 eNumberingType
= rCopy
.eNumberingType
;
672 memset( aFmts
, 0, sizeof( aFmts
));
673 for(sal_uInt16 i
= 0; i
< SVX_MAX_NUM
; i
++)
676 aFmts
[i
] = new SvxNumberFormat(*rCopy
.aFmts
[i
]);
679 aFmtsSet
[i
] = rCopy
.aFmtsSet
[i
];
683 SvxNumRule::SvxNumRule( SvStream
&rStream
)
686 rStream
>> nTmp16
; // NUM_ITEM_VERSION
687 rStream
>> nLevelCount
;
689 // first nFeatureFlags of old Versions
690 rStream
>> nTmp16
; nFeatureFlags
= nTmp16
;
691 rStream
>> nTmp16
; bContinuousNumbering
= nTmp16
;
692 rStream
>> nTmp16
; eNumberingType
= ( SvxNumRuleType
)nTmp16
;
694 for (sal_uInt16 i
= 0; i
< SVX_MAX_NUM
; i
++)
697 sal_Bool hasNumberingFormat
= nTmp16
& 1;
698 aFmtsSet
[i
] = nTmp16
& 2; // fdo#68648 reset flag
699 if ( hasNumberingFormat
){
700 aFmts
[i
] = new SvxNumberFormat( rStream
);
705 aFmtsSet
[i
] = sal_False
; // actually only false is valid
708 //second nFeatureFlags for new versions
709 rStream
>> nTmp16
; nFeatureFlags
= nTmp16
;
712 SvxNumRule
* SvxNumRule::Create( SvStream
& rStream
)
714 return new SvxNumRule( rStream
);
717 SvStream
& SvxNumRule::Store( SvStream
&rStream
)
719 rStream
<<(sal_uInt16
)NUMITEM_VERSION_03
;
720 rStream
<<nLevelCount
;
721 //first save of nFeatureFlags for old versions
722 rStream
<<(sal_uInt16
)nFeatureFlags
;
723 rStream
<<(sal_uInt16
)bContinuousNumbering
;
724 rStream
<<(sal_uInt16
)eNumberingType
;
726 FontToSubsFontConverter pConverter
= 0;
727 sal_Bool bConvertBulletFont
= ( rStream
.GetVersion() <= SOFFICE_FILEFORMAT_50
) && ( rStream
.GetVersion() );
728 for(sal_uInt16 i
= 0; i
< SVX_MAX_NUM
; i
++)
730 sal_uInt16
nSetFlag(aFmtsSet
[i
] ? 2 : 0); // fdo#68648 store that too
733 rStream
<< sal_uInt16(1 | nSetFlag
);
734 if(bConvertBulletFont
&& aFmts
[i
]->GetBulletFont())
738 CreateFontToSubsFontConverter(aFmts
[i
]->GetBulletFont()->GetName(),
739 FONTTOSUBSFONT_EXPORT
|FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS
);
741 aFmts
[i
]->Store(rStream
, pConverter
);
744 rStream
<< sal_uInt16(0 | nSetFlag
);
746 //second save of nFeatureFlags for new versions
747 rStream
<<(sal_uInt16
)nFeatureFlags
;
749 DestroyFontToSubsFontConverter(pConverter
);
753 SvxNumRule::~SvxNumRule()
755 for(sal_uInt16 i
= 0; i
< SVX_MAX_NUM
; i
++)
760 DELETEZ(pStdOutlineNumFmt
);
764 SvxNumRule
& SvxNumRule::operator=( const SvxNumRule
& rCopy
)
766 nLevelCount
= rCopy
.nLevelCount
;
767 nFeatureFlags
= rCopy
.nFeatureFlags
;
768 bContinuousNumbering
= rCopy
.bContinuousNumbering
;
769 eNumberingType
= rCopy
.eNumberingType
;
770 for(sal_uInt16 i
= 0; i
< SVX_MAX_NUM
; i
++)
774 aFmts
[i
] = new SvxNumberFormat(*rCopy
.aFmts
[i
]);
777 aFmtsSet
[i
] = rCopy
.aFmtsSet
[i
];
782 int SvxNumRule::operator==( const SvxNumRule
& rCopy
) const
784 if(nLevelCount
!= rCopy
.nLevelCount
||
785 nFeatureFlags
!= rCopy
.nFeatureFlags
||
786 bContinuousNumbering
!= rCopy
.bContinuousNumbering
||
787 eNumberingType
!= rCopy
.eNumberingType
)
789 for(sal_uInt16 i
= 0; i
< nLevelCount
; i
++)
792 (aFmtsSet
[i
] != rCopy
.aFmtsSet
[i
]) ||
793 (!aFmts
[i
] && rCopy
.aFmts
[i
]) ||
794 (aFmts
[i
] && !rCopy
.aFmts
[i
]) ||
795 (aFmts
[i
] && *aFmts
[i
] != *rCopy
.aFmts
[i
])
804 const SvxNumberFormat
* SvxNumRule::Get(sal_uInt16 nLevel
)const
806 DBG_ASSERT(nLevel
< SVX_MAX_NUM
, "Wrong Level" );
807 if( nLevel
< SVX_MAX_NUM
)
808 return aFmtsSet
[nLevel
] ? aFmts
[nLevel
] : 0;
813 const SvxNumberFormat
& SvxNumRule::GetLevel(sal_uInt16 nLevel
)const
817 pStdNumFmt
= new SvxNumberFormat(SVX_NUM_ARABIC
);
818 pStdOutlineNumFmt
= new SvxNumberFormat(SVX_NUM_NUMBER_NONE
);
821 DBG_ASSERT(nLevel
< SVX_MAX_NUM
, "Wrong Level" );
823 return ( ( nLevel
< SVX_MAX_NUM
) && aFmts
[nLevel
] ) ?
824 *aFmts
[nLevel
] : eNumberingType
== SVX_RULETYPE_NUMBERING
?
825 *pStdNumFmt
: *pStdOutlineNumFmt
;
828 void SvxNumRule::SetLevel( sal_uInt16 i
, const SvxNumberFormat
& rNumFmt
, sal_Bool bIsValid
)
830 DBG_ASSERT(i
< SVX_MAX_NUM
, "Wrong Level" );
832 if( (i
< SVX_MAX_NUM
) && (!aFmtsSet
[i
] || !(rNumFmt
== *Get( i
))) )
835 aFmts
[ i
] = new SvxNumberFormat( rNumFmt
);
836 aFmtsSet
[i
] = bIsValid
;
840 void SvxNumRule::SetLevel(sal_uInt16 nLevel
, const SvxNumberFormat
* pFmt
)
842 DBG_ASSERT(nLevel
< SVX_MAX_NUM
, "Wrong Level" );
844 if( nLevel
< SVX_MAX_NUM
)
846 aFmtsSet
[nLevel
] = 0 != pFmt
;
848 SetLevel(nLevel
, *pFmt
);
851 delete aFmts
[nLevel
];
857 String
SvxNumRule::MakeNumString( const SvxNodeNum
& rNum
, sal_Bool bInclStrings
) const
860 if( SVX_NO_NUM
> rNum
.GetLevel() && !( SVX_NO_NUMLEVEL
& rNum
.GetLevel() ) )
862 const SvxNumberFormat
& rMyNFmt
= GetLevel( rNum
.GetLevel() );
863 if( SVX_NUM_NUMBER_NONE
!= rMyNFmt
.GetNumberingType() )
865 sal_uInt8 i
= rNum
.GetLevel();
867 if( !IsContinuousNumbering() &&
868 1 < rMyNFmt
.GetIncludeUpperLevels() ) // only on own level?
870 sal_uInt8 n
= rMyNFmt
.GetIncludeUpperLevels();
880 for( ; i
<= rNum
.GetLevel(); ++i
)
882 const SvxNumberFormat
& rNFmt
= GetLevel( i
);
883 if( SVX_NUM_NUMBER_NONE
== rNFmt
.GetNumberingType() )
888 sal_Bool bDot
= sal_True
;
889 if( rNum
.GetLevelVal()[ i
] )
891 if(SVX_NUM_BITMAP
!= rNFmt
.GetNumberingType())
892 aStr
+= rNFmt
.GetNumStr( rNum
.GetLevelVal()[ i
], aLocale
);
897 aStr
+= sal_Unicode('0'); // all 0-levels are a 0
898 if( i
!= rNum
.GetLevel() && bDot
)
899 aStr
+= sal_Unicode('.');
905 aStr
.Insert( rMyNFmt
.GetPrefix(), 0 );
906 aStr
+= rMyNFmt
.GetSuffix();
912 // changes linked to embedded bitmaps
913 sal_Bool
SvxNumRule::UnLinkGraphics()
915 sal_Bool bRet
= sal_False
;
916 for(sal_uInt16 i
= 0; i
< GetLevelCount(); i
++)
918 SvxNumberFormat
aFmt(GetLevel(i
));
919 const SvxBrushItem
* pBrush
= aFmt
.GetBrush();
920 const String
* pLinkStr
;
921 const Graphic
* pGraphic
;
922 if(SVX_NUM_BITMAP
== aFmt
.GetNumberingType())
925 0 != (pLinkStr
= pBrush
->GetGraphicLink()) &&
927 0 !=(pGraphic
= pBrush
->GetGraphic()))
929 SvxBrushItem
aTempItem(*pBrush
);
930 aTempItem
.SetGraphicLink( String());
931 aTempItem
.SetGraphic(*pGraphic
);
932 sal_Int16 eOrient
= aFmt
.GetVertOrient();
933 aFmt
.SetGraphicBrush( &aTempItem
, &aFmt
.GetGraphicSize(), &eOrient
);
937 else if((SVX_NUM_BITMAP
|LINK_TOKEN
) == aFmt
.GetNumberingType())
938 aFmt
.SetNumberingType(SVX_NUM_BITMAP
);
944 SvxNumBulletItem::SvxNumBulletItem(SvxNumRule
& rRule
) :
945 SfxPoolItem(SID_ATTR_NUMBERING_RULE
),
946 pNumRule(new SvxNumRule(rRule
))
950 SvxNumBulletItem::SvxNumBulletItem(SvxNumRule
& rRule
, sal_uInt16 _nWhich
) :
951 SfxPoolItem(_nWhich
),
952 pNumRule(new SvxNumRule(rRule
))
956 SfxPoolItem
* SvxNumBulletItem::Create(SvStream
&rStream
, sal_uInt16
/*nItemVersion*/ ) const
958 SvxNumRule
aNumRule( rStream
);
959 return new SvxNumBulletItem( aNumRule
, EE_PARA_NUMBULLET
);
962 SvxNumBulletItem::SvxNumBulletItem(const SvxNumBulletItem
& rCopy
) :
963 SfxPoolItem(rCopy
.Which())
965 pNumRule
= new SvxNumRule(*rCopy
.pNumRule
);
968 SvxNumBulletItem::~SvxNumBulletItem()
973 int SvxNumBulletItem::operator==( const SfxPoolItem
& rCopy
) const
975 return *pNumRule
== *((SvxNumBulletItem
&)rCopy
).pNumRule
;
978 SfxPoolItem
* SvxNumBulletItem::Clone( SfxItemPool
* ) const
980 return new SvxNumBulletItem(*this);
983 sal_uInt16
SvxNumBulletItem::GetVersion( sal_uInt16
/*nFileVersion*/ ) const
985 return NUMITEM_VERSION_03
;
988 SvStream
& SvxNumBulletItem::Store(SvStream
&rStream
, sal_uInt16
/*nItemVersion*/ )const
990 pNumRule
->Store(rStream
);
994 bool SvxNumBulletItem::QueryValue( com::sun::star::uno::Any
& rVal
, sal_uInt8
/*nMemberId*/ ) const
996 rVal
<<= SvxCreateNumRule( pNumRule
);
1000 bool SvxNumBulletItem::PutValue( const com::sun::star::uno::Any
& rVal
, sal_uInt8
/*nMemberId*/ )
1002 uno::Reference
< container::XIndexReplace
> xRule
;
1003 if( rVal
>>= xRule
)
1007 SvxNumRule
* pNewRule
= new SvxNumRule( SvxGetNumRule( xRule
) );
1008 if( pNewRule
->GetLevelCount() != pNumRule
->GetLevelCount() ||
1009 pNewRule
->GetNumRuleType() != pNumRule
->GetNumRuleType() )
1011 SvxNumRule
* pConverted
= SvxConvertNumRule( pNewRule
, pNumRule
->GetLevelCount(), pNumRule
->GetNumRuleType() );
1013 pNewRule
= pConverted
;
1016 pNumRule
= pNewRule
;
1019 catch(const lang::IllegalArgumentException
&)
1026 SvxNumRule
* SvxConvertNumRule( const SvxNumRule
* pRule
, sal_uInt16 nLevels
, SvxNumRuleType eType
)
1028 const sal_uInt16 nSrcLevels
= pRule
->GetLevelCount();
1029 SvxNumRule
* pNewRule
= new SvxNumRule( pRule
->GetFeatureFlags(), nLevels
, pRule
->IsContinuousNumbering(), eType
);
1031 for( sal_uInt16 nLevel
= 0; (nLevel
< nLevels
) && (nLevel
< nSrcLevels
); nLevel
++ )
1032 pNewRule
->SetLevel( nLevel
, pRule
->GetLevel( nLevel
) );
1037 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */