1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: rtfnum.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
33 #include <hintids.hxx>
34 #include <tools/stream.hxx>
35 #include <svtools/rtftoken.h>
36 #include <svtools/rtfkeywd.hxx>
37 #include <svtools/intitem.hxx>
38 #include <svtools/rtfout.hxx>
39 #include <svx/lrspitem.hxx>
40 #include <svx/fontitem.hxx>
41 #include <svx/fhgtitem.hxx>
42 #include <svx/wghtitem.hxx>
43 #include <svx/postitem.hxx>
44 #include <svx/cmapitem.hxx>
45 #include <svx/crsditem.hxx>
46 #include <svx/colritem.hxx>
47 #include <svx/udlnitem.hxx>
48 #include <svx/wrlmitem.hxx>
49 #include <shellio.hxx>
51 #include <swtypes.hxx>
52 #include <swparrtf.hxx>
58 #include <charfmt.hxx>
59 #include <charatr.hxx>
64 #include <numrule.hxx>
66 #define RTF_NUMRULE_NAME "RTF_Num"
68 SV_IMPL_VARARR( SwListArr
, SwListEntry
)
71 void lcl_ExpandNumFmts( SwNumRule
& rRule
)
73 // dann noch das NumFormat in alle Ebenen setzen
74 for( BYTE n
= 1; n
< MAXLEVEL
; ++n
)
75 if( !rRule
.GetNumFmt( n
) )
77 SwNumFmt
aNumFmt( rRule
.Get( 0 ));
78 aNumFmt
.SetAbsLSpace( aNumFmt
.GetAbsLSpace() * ( n
+ 1 ) );
79 rRule
.Set( n
, aNumFmt
);
83 SfxItemSet
& GetNumChrFmt( SwDoc
& rDoc
, SwNumRule
& rRule
, BYTE nNumLvl
)
85 SwCharFmt
* pChrFmt
= rRule
.Get( nNumLvl
).GetCharFmt();
88 String
sNm( rRule
.GetName() );
89 ( sNm
+= ' ' ) += String::CreateFromInt32( nNumLvl
+ 1 );
90 pChrFmt
= rDoc
.MakeCharFmt( sNm
, rDoc
.GetDfltCharFmt() );
91 if( !rRule
.GetNumFmt( nNumLvl
))
92 rRule
.Set( nNumLvl
, rRule
.Get( nNumLvl
) );
93 ((SwNumFmt
*)rRule
.GetNumFmt( nNumLvl
))->SetCharFmt( pChrFmt
);
95 return (SfxItemSet
&)pChrFmt
->GetAttrSet();
98 void SwRTFParser::ReadListLevel( SwNumRule
& rRule
, BYTE nNumLvl
)
101 int nNumOpenBrakets
= 1; // die erste wurde schon vorher erkannt !!
102 int nLvlTxtLevel
= 0, nLvlNumberLevel
= 0;
103 String sLvlText
, sLvlNumber
;
104 SwNumFmt
* pCurNumFmt
;
105 String aStringFollow
= aEmptyStr
;
107 if( MAXLEVEL
>= nNumLvl
)
109 pCurNumFmt
= (SwNumFmt
*)rRule
.GetNumFmt( nNumLvl
);
110 pCurNumFmt
->SetAbsLSpace( 0 );
111 pCurNumFmt
->SetFirstLineOffset( 0 );
116 while( nNumOpenBrakets
&& IsParserWorking() )
118 switch( ( nToken
= GetNextToken() ))
121 if( nNumOpenBrakets
)
123 if( nLvlTxtLevel
== nNumOpenBrakets
)
125 if( DelCharAtEnd( sLvlText
, ';' ).Len() &&
126 sLvlText
.Len() && sLvlText
.Len() ==
127 (USHORT
)(sLvlText
.GetChar( 0 )) + 1 )
128 sLvlText
.Erase( 0, 1 );
131 if( nLvlNumberLevel
== nNumOpenBrakets
)
133 DelCharAtEnd( sLvlNumber
, ';' );
142 if( RTF_IGNOREFLAG
!= GetNextToken() )
143 nToken
= SkipToken( -1 );
144 // Unknown und alle bekannten nicht ausgewerteten Gruppen
145 // sofort ueberspringen
146 else if( RTF_UNKNOWNCONTROL
!= ( nToken
= GetNextToken() ))
147 // RTF_PANOSE != nToken && RTF_FALT != nToken &&
148 // RTF_FALT != nToken && RTF_FNAME != nToken &&
149 // RTF_FONTEMB != nToken && RTF_FONTFILE != nToken )
150 nToken
= SkipToken( -2 );
153 // gleich herausfiltern
155 nToken
= GetNextToken();
157 eState
= SVPAR_ERROR
;
166 sal_Int16 eType
= SVX_NUM_ARABIC
;
167 switch( nTokenValue
)
169 case 1: eType
= SVX_NUM_ROMAN_UPPER
; break;
170 case 2: eType
= SVX_NUM_ROMAN_LOWER
; break;
171 case 3: eType
= SVX_NUM_CHARS_UPPER_LETTER_N
; break;
172 case 4: eType
= SVX_NUM_CHARS_LOWER_LETTER_N
; break;
174 case 23: eType
= SVX_NUM_CHAR_SPECIAL
; break;
177 pCurNumFmt
->SetNumberingType(eType
);
183 SvxAdjust eAdj
= SVX_ADJUST_LEFT
;
184 switch( nTokenValue
)
186 case 1: eAdj
= SVX_ADJUST_CENTER
; break;
187 case 2: eAdj
= SVX_ADJUST_RIGHT
; break;
190 pCurNumFmt
->SetNumAdjust( eAdj
);
194 case RTF_LEVELSTARTAT
:
195 if( pCurNumFmt
&& -1 != nTokenValue
)
196 pCurNumFmt
->SetStart( USHORT( nTokenValue
));
200 nLvlTxtLevel
= nNumOpenBrakets
;
203 case RTF_LEVELNUMBERS
:
204 nLvlNumberLevel
= nNumOpenBrakets
;
209 if( nLvlTxtLevel
== nNumOpenBrakets
)
211 else if( nLvlNumberLevel
== nNumOpenBrakets
)
212 sLvlNumber
+= aToken
;
215 case RTF_LEVELFOLLOW
:
216 /* removed; waiting for swnum02 to be integrated!
220 aStringFollow=String('\t');
223 aStringFollow=String(' ');
231 case RTF_LEVELPREVSPACE
:
232 case RTF_LEVELINDENT
:
235 case RTF_LEVELNORESTART
:
240 RTF_CHRFMT
== (nToken
& ~(0xff | RTF_SWGDEFS
) ) ||
241 RTF_PARFMT
== (nToken
& ~(0xff | RTF_SWGDEFS
) ) ))
243 SfxItemSet
aSet( pDoc
->GetAttrPool(), aTxtNodeSetRange
);
244 // put the current CharFmtAttr into the set
245 SfxItemSet
& rCFmtSet
= GetNumChrFmt( *pDoc
, rRule
, nNumLvl
);
246 aSet
.Put( rCFmtSet
);
247 // and put the current "LRSpace" into the set
249 SvxLRSpaceItem
aLR( RES_LR_SPACE
);
250 aLR
.SetTxtLeft( pCurNumFmt
->GetAbsLSpace() );
251 aLR
.SetTxtFirstLineOfst(pCurNumFmt
->GetFirstLineOffset());
255 ReadAttr( nToken
, &aSet
);
257 //#i24880# Word appears to ignore char background for numbering
258 aSet
.ClearItem(RES_CHRATR_BACKGROUND
);
260 // put all CharFmt Items into the charfmt
261 rCFmtSet
.Put( aSet
);
263 // test for LRSpace Item. If exist then set all relevant
264 // values on the numrule format
265 const SfxPoolItem
* pItem
;
266 if( SFX_ITEM_SET
== aSet
.GetItemState( RES_LR_SPACE
,
269 const SvxLRSpaceItem
& rLR
= *(SvxLRSpaceItem
*)pItem
;
270 pCurNumFmt
->SetAbsLSpace( static_cast< short >(rLR
.GetTxtLeft()) );
271 pCurNumFmt
->SetFirstLineOffset( rLR
.GetTxtFirstLineOfst());
274 // dann aus der Vorlage den Font holen
275 if( SVX_NUM_CHAR_SPECIAL
== pCurNumFmt
->GetNumberingType() )
276 pCurNumFmt
->SetBulletFont( FindFontOfItem(
277 pCurNumFmt
->GetCharFmt()->GetFont() ) );
283 if( IsParserWorking() && pCurNumFmt
)
285 // dann erzeuge mal die Pre/Postfix-Strings
286 if( sLvlText
.Len() &&
287 SVX_NUM_CHAR_SPECIAL
== pCurNumFmt
->GetNumberingType() )
289 pCurNumFmt
->SetBulletChar( sLvlText
.GetChar( 0 ) );
290 // dann aus der Vorlage den Font holen
291 if( pCurNumFmt
->GetCharFmt() )
292 pCurNumFmt
->SetBulletFont( FindFontOfItem(
293 pCurNumFmt
->GetCharFmt()->GetFont() ) );
295 else if( sLvlNumber
.Len() && sLvlText
.Len() )
297 // in sLvlText steht der Text, in sLvlNumber die Position
298 // der Ebenen in sLvlText
299 pCurNumFmt
->SetPrefix(
300 sLvlText
.Copy( 0, USHORT( sLvlNumber
.GetChar( 0 ))-1 ));
301 pCurNumFmt
->SetSuffix( sLvlText
.Copy(
302 USHORT( sLvlNumber
.GetChar( sLvlNumber
.Len()-1 )) ));
303 // wieviele Levels stehen im String?
304 pCurNumFmt
->SetIncludeUpperLevels( (BYTE
)sLvlNumber
.Len() );
308 pCurNumFmt
->SetNumberingType(SVX_NUM_NUMBER_NONE
);
309 pCurNumFmt
->SetSuffix( sLvlText
);
312 String newSuffix
=pCurNumFmt
->GetSuffix();
313 newSuffix
+=aStringFollow
;
314 pCurNumFmt
->SetSuffix(newSuffix
);
315 /* removed; waiting for swnum02 to be integrated!
316 if (aStringFollow.GetChar(0)=='\t' && !pCurNumFmt->IsItemize())
318 pCurNumFmt->SetAbsLSpace(0);
319 pCurNumFmt->SetFirstLineOffset(0);
327 void SwRTFParser::ReadListTable()
330 int nNumOpenBrakets
= 1; // die erste wurde schon vorher erkannt !!
334 SwNumRule
* pCurRule
= 0;
337 while( nNumOpenBrakets
&& IsParserWorking() )
339 switch( ( nToken
= GetNextToken() ))
341 case '}': if( --nNumOpenBrakets
&& IsParserWorking() )
343 // Style konnte vollstaendig gelesen werden,
344 // also ist das noch ein stabiler Status
345 SaveState( RTF_LISTTABLE
);
346 if( 1 == nNumOpenBrakets
)
349 aListArr
.Insert( aEntry
, aListArr
.Count() );
357 if( RTF_IGNOREFLAG
!= GetNextToken() )
358 nToken
= SkipToken( -1 );
359 // Unknown und alle bekannten nicht ausgewerteten Gruppen
360 // sofort ueberspringen
361 else if( RTF_UNKNOWNCONTROL
!= ( nToken
= GetNextToken() ))
362 // RTF_PANOSE != nToken && RTF_FALT != nToken &&
363 // RTF_FALT != nToken && RTF_FNAME != nToken &&
364 // RTF_FONTEMB != nToken && RTF_FONTFILE != nToken )
365 nToken
= SkipToken( -2 );
368 // gleich herausfiltern
370 nToken
= GetNextToken();
372 eState
= SVPAR_ERROR
;
381 if( pCurRule
&& pCurRule
->IsContinusNum() )
382 lcl_ExpandNumFmts( *pCurRule
);
384 String
sTmp( String::CreateFromAscii(
385 RTL_CONSTASCII_STRINGPARAM( RTF_NUMRULE_NAME
" 1" )));
386 aEntry
.nListDocPos
= pDoc
->MakeNumRule( sTmp
);
387 pCurRule
= pDoc
->GetNumRuleTbl()[ aEntry
.nListDocPos
];
388 // --> OD 2008-07-08 #i91400#
389 pCurRule
->SetName( pDoc
->GetUniqueNumRuleName( &sTmp
, FALSE
),
392 pCurRule
->SetAutoRule( FALSE
);
397 case RTF_LISTID
: aEntry
.nListId
= nTokenValue
; break;
398 case RTF_LISTTEMPLATEID
: aEntry
.nListTemplateId
= nTokenValue
; break;
400 case RTF_LISTRESTARTHDN
:
403 if (nNextCh
=='}') break; // #118989# empty listnames
404 if( RTF_TEXTTOKEN
== GetNextToken() )
406 String
sTmp( DelCharAtEnd( aToken
, ';' ));
407 if( sTmp
.Len() && !pDoc
->FindNumRulePtr( sTmp
))
409 // --> OD 2008-07-08 #i91400#
410 pCurRule
->SetName( sTmp
, *pDoc
);
418 pCurRule
->SetContinusNum( TRUE
);
423 if( ++nNumLvl
< MAXLEVEL
)
424 pCurRule
->Set( nNumLvl
, pCurRule
->Get( nNumLvl
));
425 ReadListLevel( *pCurRule
, nNumLvl
);
431 if( pCurRule
&& pCurRule
->IsContinusNum() )
432 lcl_ExpandNumFmts( *pCurRule
);
434 SkipToken( -1 ); // die schliesende Klammer wird "oben" ausgewertet
437 BOOL
lcl_IsEqual( SwNumRule
* pOrigRule
, SwNumRule
* pRule
)
440 if( pOrigRule
&& pRule
)
442 bRet
= pOrigRule
->GetRuleType() == pRule
->GetRuleType() &&
443 pOrigRule
->IsContinusNum() == pRule
->IsContinusNum() &&
444 pOrigRule
->IsAbsSpaces() == pRule
->IsAbsSpaces();
446 for( BYTE n
= 0; bRet
&& n
< MAXLEVEL
; ++n
)
448 const SwNumFmt
* pOFmt
= pOrigRule
->GetNumFmt( n
),
449 * pFmt
= pRule
->GetNumFmt( n
);
452 SwCharFmt
* pOCFmt
= pOFmt
->GetCharFmt(),
453 * pCFmt
= pFmt
->GetCharFmt();
454 if( pOCFmt
&& pCFmt
)
456 bRet
= 0 != (pCFmt
->GetAttrSet() == pOCFmt
->GetAttrSet());
459 bRet
= !pCFmt
&& !pOCFmt
;
462 ((SwNumFmt
*)pOFmt
)->SetCharFmt( 0 );
463 ((SwNumFmt
*)pFmt
)->SetCharFmt( 0 );
464 bRet
= *pOFmt
== *pFmt
;
465 ((SwNumFmt
*)pOFmt
)->SetCharFmt( pOCFmt
);
466 ((SwNumFmt
*)pFmt
)->SetCharFmt( pCFmt
);
470 bRet
= !pFmt
&& !pOFmt
;
476 void SwRTFParser::ReadListOverrideTable()
479 int nNumOpenBrakets
= 1; // die erste wurde schon vorher erkannt !!
481 SwNumRule
* pRule
= 0, *pOrigRule
= 0;
483 BOOL bOverrideFormat
= FALSE
, bOverrideStart
= FALSE
;
485 while( nNumOpenBrakets
&& IsParserWorking() )
487 switch( ( nToken
= GetNextToken() ))
490 if( --nNumOpenBrakets
&& IsParserWorking() )
492 // Style konnte vollstaendig gelesen werden,
493 // also ist das noch ein stabiler Status
494 SaveState( RTF_LISTOVERRIDETABLE
);
496 if( 1 == nNumOpenBrakets
)
498 bOverrideFormat
= FALSE
, bOverrideStart
= FALSE
;
501 if( lcl_IsEqual( pOrigRule
, pRule
))
503 // no changes on the rule -> use the original rule
504 aEntry
.nListDocPos
= pDoc
->FindNumRule(
505 pOrigRule
->GetName() );
506 // delete the temp Rule
507 RemoveUnusedNumRule( pRule
);
509 else if( pRule
->IsContinusNum() )
510 lcl_ExpandNumFmts( *pRule
);
513 if( aEntry
.nListId
&& aEntry
.nListNo
)
516 for( USHORT n
= aListArr
.Count(); n
; )
518 if( aListArr
[ --n
].nListId
== aEntry
.nListId
)
526 USHORT nMatch2
= static_cast< USHORT
>(nMatch
);
527 if (!aListArr
[nMatch2
].nListNo
)
529 aListArr
[nMatch2
].nListNo
= aEntry
.nListNo
;
533 aEntry
.nListDocPos
=aListArr
[nMatch2
].nListDocPos
;
534 aEntry
.nListTemplateId
=aListArr
[nMatch2
].nListTemplateId
;
535 aListArr
.Insert(aEntry
, aListArr
.Count());
538 aListArr
[nMatch2
].nListDocPos
= aEntry
.nListDocPos
;
550 if( RTF_IGNOREFLAG
!= GetNextToken() )
551 nToken
= SkipToken( -1 );
552 // Unknown und alle bekannten nicht ausgewerteten Gruppen
553 // sofort ueberspringen
554 else if( RTF_UNKNOWNCONTROL
!= ( nToken
= GetNextToken() ))
555 nToken
= SkipToken( -2 );
558 // gleich herausfiltern
560 nToken
= GetNextToken();
562 eState
= SVPAR_ERROR
;
569 case RTF_LISTOVERRIDE
: aEntry
.Clear(); break;
570 case RTF_LISTID
: aEntry
.nListId
= nTokenValue
; break;
571 case RTF_LS
: aEntry
.nListNo
= nTokenValue
; break;
572 case RTF_LISTOVERRIDECOUNT
:
576 // dann erzeugen wir mal schnell eine Kopie von der NumRule,
577 // denn diese wird jetzt mal kurz veraendert.
579 for( USHORT n
= 0; n
< aListArr
.Count(); ++n
)
580 if( aListArr
[ n
].nListId
== aEntry
.nListId
)
582 pRule
= pDoc
->GetNumRuleTbl()[
583 aListArr
[ n
].nListDocPos
];
586 String
sTmp( String::CreateFromAscii(
587 RTL_CONSTASCII_STRINGPARAM( RTF_NUMRULE_NAME
" 1" )));
588 aEntry
.nListDocPos
= pDoc
->MakeNumRule( sTmp
, pRule
);
589 pRule
= pDoc
->GetNumRuleTbl()[ aEntry
.nListDocPos
];
590 // --> OD 2008-07-08 #i91400#
591 pRule
->SetName( pDoc
->GetUniqueNumRuleName( &sTmp
, FALSE
),
594 pRule
->SetAutoRule( FALSE
);
596 aListArr
.Insert( aEntry
, aListArr
.Count() );
604 if( pRule
&& bOverrideFormat
)
606 if( ++nNumLvl
< MAXLEVEL
)
607 pRule
->Set( nNumLvl
, pRule
->Get( nNumLvl
));
608 ReadListLevel( *pRule
, nNumLvl
);
612 case RTF_LEVELSTARTAT
:
613 if( pRule
&& bOverrideStart
)
618 case RTF_LISTOVERRIDESTART
:
619 bOverrideStart
= TRUE
;
622 case RTF_LISTOVERRIDEFORMAT
:
623 bOverrideFormat
= TRUE
;
632 // search the outline numrule and set it into the doc
633 if( GetStyleTbl().Count() )
635 if( !bStyleTabValid
)
638 const SfxPoolItem
* pItem( 0 );
639 const SwTxtFmtColl
* pColl( 0 );
640 USHORT
nRulePos( USHRT_MAX
);
641 const SwNumRule
*pNumRule
= 0;
642 SvxRTFStyleType
* pStyle
= GetStyleTbl().First();
644 // --> OD 2007-12-17 #151213#
645 // suppress deletion of outline list style.
646 // refactoring of code: no assignments in if-condition
647 // if( MAXLEVEL > pStyle->nOutlineNo &&
648 // 0 != ( pColl = aTxtCollTbl.Get( (USHORT)GetStyleTbl().
650 // SFX_ITEM_SET == pColl->GetItemState( RES_PARATR_NUMRULE,
651 // FALSE, &pItem ) &&
652 // USHRT_MAX != (nRulePos = pDoc->FindNumRule(
653 // ((SwNumRuleItem*)pItem)->GetValue() )) &&
654 // (pNumRule = pDoc->GetNumRuleTbl()[ nRulePos ])->IsAutoRule() )
655 if ( MAXLEVEL
> pStyle
->nOutlineNo
)
657 pColl
= aTxtCollTbl
.Get( (USHORT
)GetStyleTbl().GetCurKey() );
660 const SfxItemState eItemState
=
661 pColl
->GetItemState( RES_PARATR_NUMRULE
, FALSE
, &pItem
);
662 if ( eItemState
== SFX_ITEM_SET
)
664 nRulePos
= pDoc
->FindNumRule( ((SwNumRuleItem
*)pItem
)->GetValue() );
665 if ( nRulePos
!= USHRT_MAX
)
667 pNumRule
= pDoc
->GetNumRuleTbl()[ nRulePos
];
668 if ( pNumRule
->IsAutoRule() &&
669 pNumRule
!= pDoc
->GetOutlineNumRule() )
671 pDoc
->SetOutlineNumRule( *pNumRule
);
672 pDoc
->DelNumRule( pNumRule
->GetName() );
673 // now pNumRule pointer is invalid !!!
675 // now decrement all position in the listtable, which will
676 // behind the doc-rule position
677 for( USHORT n
= aListArr
.Count(); n
; )
679 SwListEntry
& rEntry
= aListArr
[ --n
];
680 if( rEntry
.nListDocPos
== nRulePos
)
681 aListArr
.Remove( n
);
682 else if( rEntry
.nListDocPos
> nRulePos
)
683 --rEntry
.nListDocPos
;
693 pStyle
->aAttrSet
.ClearItem( FN_PARAM_NUM_LEVEL
);
695 } while( 0 != (pStyle
= GetStyleTbl().Next()) );
698 SkipToken( -1 ); // die schliesende Klammer wird "oben" ausgewertet
701 SwNumRule
* SwRTFParser::GetNumRuleOfListNo( long nListNo
, BOOL bRemoveFromList
)
705 for( USHORT n
= aListArr
.Count(); n
; )
706 if( ( pEntry
= &aListArr
[ --n
])->nListNo
== nListNo
)
708 if( bRemoveFromList
)
709 aListArr
.Remove( n
);
712 pEntry
->bRuleUsed
= TRUE
;
713 pRet
= pDoc
->GetNumRuleTbl()[ pEntry
->nListDocPos
];
720 void SwRTFParser::RemoveUnusedNumRule( SwNumRule
* pRule
)
724 for ( BYTE nLvl
= 0; nLvl
< MAXLEVEL
; ++nLvl
)
726 SwNumFmt
& rNFmt
= (SwNumFmt
&)pRule
->Get( nLvl
);
727 SwCharFmt
* pCFmt
= rNFmt
.GetCharFmt();
730 pCFmt
->Remove( &rNFmt
);
731 if( !pCFmt
->GetDepends() )
732 pDoc
->DelCharFmt( pCFmt
);
735 pDoc
->DelNumRule( pRule
->GetName() );
740 ASSERT( pRule
, "NumRulePointer 0 kann nicht geloescht werden" );
745 void SwRTFParser::RemoveUnusedNumRules()
750 for( n
= aListArr
.Count(); n
; )
752 if( !( pEntry
= &aListArr
[ --n
])->bRuleUsed
)
754 // really *NOT* used by anyone else?
756 for(USHORT j
= 0; j
< aListArr
.Count(); ++j
)
758 if (aListArr
[n
].nListNo
==aListArr
[j
].nListNo
)
759 unused
&=!aListArr
[j
].bRuleUsed
;
763 void * p
= pDoc
->GetNumRuleTbl()[pEntry
->nListDocPos
];
764 // dont delete named char formats
765 if( USHRT_MAX
== aDelArr
.GetPos( p
) &&
766 ((SwNumRule
*)p
)->GetName().EqualsAscii( RTF_NUMRULE_NAME
, 0,
767 sizeof( RTF_NUMRULE_NAME
)) )
768 aDelArr
.Insert( p
, aDelArr
.Count() );
773 for( n
= aDelArr
.Count(); n
; )
775 SwNumRule
* pDel
= (SwNumRule
*)aDelArr
[ --n
];
776 RemoveUnusedNumRule( pDel
);
780 const Font
* SwRTFParser::FindFontOfItem( const SvxFontItem
& rItem
) const
782 SvxRTFFontTbl
& rFntTbl
= ((SwRTFParser
*)this)->GetFontTbl();
783 const Font
* pFnt
= rFntTbl
.First();
786 if( pFnt
->GetFamily() == rItem
.GetFamily() &&
787 pFnt
->GetName() == rItem
.GetFamilyName() &&
788 pFnt
->GetStyleName() == rItem
.GetStyleName() &&
789 pFnt
->GetPitch() == rItem
.GetPitch() &&
790 pFnt
->GetCharSet() == rItem
.GetCharSet() )
793 pFnt
= rFntTbl
.Next();
799 SwNumRule
*SwRTFParser::ReadNumSecLevel( int nToken
)
801 // lese die \pnseclvl - Gruppe
802 // nTokenValue gibt schon den richtigen Level vor 1 - 9!
805 BOOL bContinus
= TRUE
;
807 if( RTF_PNSECLVL
== nToken
)
809 // suche die Rule - steht unter Nummer 3
812 nLevel
= MAXLEVEL
<= nTokenValue
? MAXLEVEL
- 1
813 : BYTE( nTokenValue
- 1 );
817 switch( nToken
= GetNextToken() )
819 case RTF_PNLVL
: nListNo
= 3;
821 nLevel
= MAXLEVEL
<= nTokenValue
823 : BYTE( nTokenValue
-1 );
841 // suche die Rule - steht unter Nummer 3
842 USHORT nNewFlag
= static_cast< USHORT
>(1 << nListNo
);
843 SwNumRule
* pCurRule
= GetNumRuleOfListNo( nListNo
,
844 0 != ( nNewNumSectDef
& nNewFlag
) );
847 // dann muessen wir die mal anlegen
848 nNewNumSectDef
&= ~nNewFlag
;
849 String
sTmp( String::CreateFromAscii(
850 RTL_CONSTASCII_STRINGPARAM( RTF_NUMRULE_NAME
" 1" )));
851 SwListEntry
aEntry( nListNo
, 0, pDoc
->MakeNumRule( sTmp
));
852 aEntry
.nListNo
= nListNo
;
853 aListArr
.Insert( aEntry
, aListArr
.Count() );
854 pCurRule
= pDoc
->GetNumRuleTbl()[ aEntry
.nListDocPos
];
855 // --> OD 2008-07-08 #i91400#
856 pCurRule
->SetName( pDoc
->GetUniqueNumRuleName( &sTmp
, FALSE
), *pDoc
);
858 pCurRule
->SetAutoRule( FALSE
);
859 pCurRule
->SetContinusNum( bContinus
);
862 if( !pCurRule
->GetNumFmt( nLevel
))
863 pCurRule
->Set( nLevel
, pCurRule
->Get( nLevel
));
864 SwNumFmt
* pCurNumFmt
= (SwNumFmt
*)pCurRule
->GetNumFmt( nLevel
);
865 if( RTF_PNLVLBLT
== nToken
)
866 pCurNumFmt
->SetNumberingType(SVX_NUM_CHAR_SPECIAL
);
867 pCurNumFmt
->SetSuffix( aEmptyStr
);
868 pCurNumFmt
->SetPrefix( aEmptyStr
);
869 pCurNumFmt
->SetNumberingType(SVX_NUM_NUMBER_NONE
);
871 if( bStyleTabValid
&& RTF_PNSECLVL
!= nToken
)
873 // dann den akt. Lvl und Rule am Absatz setzen.
874 // Dieses muss aber in den vorherigen "Kontext", sprich in den vor
875 // der Klammer offenen Attrset. Darum das SetNewGroup davor und dahinter
876 SetNewGroup( FALSE
);
877 GetAttrSet().Put( SfxUInt16Item( FN_PARAM_NUM_LEVEL
, nLevel
));
878 GetAttrSet().Put( SwNumRuleItem( pCurRule
->GetName() ));
882 FontUnderline eUnderline
;
883 int nNumOpenBrakets
= 1; // die erste wurde schon vorher erkannt !!
884 while( nNumOpenBrakets
&& IsParserWorking() )
886 switch( ( nToken
= GetNextToken() ))
889 if( --nNumOpenBrakets
&& IsParserWorking() )
891 // Style konnte vollstaendig gelesen werden,
892 // also ist das noch ein stabiler Status
893 SaveState( RTF_PNSECLVL
);
899 if( RTF_IGNOREFLAG
!= GetNextToken() )
900 nToken
= SkipToken( -1 );
901 // Unknown und alle bekannten nicht ausgewerteten Gruppen
902 // sofort ueberspringen
903 else if( RTF_UNKNOWNCONTROL
!= ( nToken
= GetNextToken() ))
904 nToken
= SkipToken( -2 );
907 // gleich herausfiltern
909 nToken
= GetNextToken();
911 eState
= SVPAR_ERROR
;
921 case RTF_PNDEC
: pCurNumFmt
->SetNumberingType(SVX_NUM_ARABIC
); break;
922 case RTF_PNUCLTR
: pCurNumFmt
->SetNumberingType(SVX_NUM_CHARS_UPPER_LETTER_N
); break;
923 case RTF_PNUCRM
: pCurNumFmt
->SetNumberingType(SVX_NUM_ROMAN_UPPER
); break;
924 case RTF_PNLCLTR
: pCurNumFmt
->SetNumberingType(SVX_NUM_CHARS_LOWER_LETTER_N
); break;
925 case RTF_PNLCRM
: pCurNumFmt
->SetNumberingType(SVX_NUM_ROMAN_LOWER
); break;
929 const Font
& rSVFont
= GetFont( USHORT(nTokenValue
) );
930 GetNumChrFmt( *pDoc
, *pCurRule
, nLevel
).Put(
931 SvxFontItem( rSVFont
.GetFamily(),
932 rSVFont
.GetName(), rSVFont
.GetStyleName(),
933 rSVFont
.GetPitch(), rSVFont
.GetCharSet(),
935 if( SVX_NUM_CHAR_SPECIAL
== pCurNumFmt
->GetNumberingType() )
936 pCurNumFmt
->SetBulletFont( &rSVFont
);
941 if( -1 == nTokenValue
)
945 GetNumChrFmt( *pDoc
, *pCurRule
, nLevel
).Put(
946 SvxFontHeightItem( (const USHORT
)nTokenValue
, 100, RES_CHRATR_FONTSIZE
));
952 GetNumChrFmt( *pDoc
, *pCurRule
, nLevel
).Put( SvxWeightItem(
953 nTokenValue
? WEIGHT_BOLD
: WEIGHT_NORMAL
, RES_CHRATR_WEIGHT
));
959 GetNumChrFmt( *pDoc
, *pCurRule
, nLevel
).Put( SvxPostureItem(
960 nTokenValue
? ITALIC_NORMAL
: ITALIC_NONE
, RES_CHRATR_POSTURE
));
967 GetNumChrFmt( *pDoc
, *pCurRule
, nLevel
).Put( SvxCaseMapItem(
968 nTokenValue
? SVX_CASEMAP_KAPITAELCHEN
969 : SVX_CASEMAP_NOT_MAPPED
, RES_CHRATR_CASEMAP
));
974 GetNumChrFmt( *pDoc
, *pCurRule
, nLevel
).Put( SvxCrossedOutItem(
975 nTokenValue
? STRIKEOUT_SINGLE
: STRIKEOUT_NONE
, RES_CHRATR_CROSSEDOUT
));
981 GetNumChrFmt( *pDoc
, *pCurRule
, nLevel
).Put( SvxColorItem(
982 GetColor( USHORT(nTokenValue
) ), RES_CHRATR_COLOR
));
988 eUnderline
= nTokenValue
? UNDERLINE_SINGLE
: UNDERLINE_NONE
;
989 goto NUMATTR_SETUNDERLINE
;
991 eUnderline
= UNDERLINE_DOTTED
;
992 goto NUMATTR_SETUNDERLINE
;
994 eUnderline
= UNDERLINE_DOUBLE
;
995 goto NUMATTR_SETUNDERLINE
;
997 eUnderline
= UNDERLINE_NONE
;
998 goto NUMATTR_SETUNDERLINE
;
1001 GetNumChrFmt( *pDoc
, *pCurRule
, nLevel
).Put(
1002 SvxWordLineModeItem( TRUE
, RES_CHRATR_WORDLINEMODE
));
1004 eUnderline
= UNDERLINE_SINGLE
;
1005 goto NUMATTR_SETUNDERLINE
;
1007 NUMATTR_SETUNDERLINE
:
1009 GetNumChrFmt( *pDoc
, *pCurRule
, nLevel
).Put(
1010 SvxUnderlineItem( eUnderline
, RES_CHRATR_UNDERLINE
));
1015 if( 0 > short( nTokenValue
) )
1016 nTokenValue
= - (short)nTokenValue
;
1017 pCurNumFmt
->SetFirstLineOffset( - short( nTokenValue
));
1018 pCurNumFmt
->SetAbsLSpace( (nLevel
+ 1 ) * USHORT( nTokenValue
));
1021 pCurNumFmt
->SetCharTextDistance( USHORT( nTokenValue
));
1027 BYTE nPrev
= 2, nLast
= nLevel
;
1028 while( nLast
&& 1 < pCurRule
->Get( --nLast
).GetIncludeUpperLevels() )
1030 pCurNumFmt
->SetIncludeUpperLevels( nPrev
);
1034 case RTF_PNQC
: pCurNumFmt
->SetNumAdjust( SVX_ADJUST_CENTER
); break;
1035 case RTF_PNQL
: pCurNumFmt
->SetNumAdjust( SVX_ADJUST_LEFT
); break;
1036 case RTF_PNQR
: pCurNumFmt
->SetNumAdjust( SVX_ADJUST_RIGHT
); break;
1039 pCurNumFmt
->SetStart( USHORT( nTokenValue
));
1045 case RTF_PNRESTART
: break;
1050 GetTextToEndGroup( sTmp
);
1051 if( SVX_NUM_CHAR_SPECIAL
== pCurNumFmt
->GetNumberingType() )
1053 pCurNumFmt
->SetBulletChar( sTmp
.GetChar( 0 ) );
1054 if( pCurNumFmt
->GetCharFmt() )
1055 pCurNumFmt
->SetBulletFont( FindFontOfItem(
1056 pCurNumFmt
->GetCharFmt()->GetFont() ) );
1059 pCurNumFmt
->SetSuffix( sTmp
);
1066 pCurNumFmt
->SetPrefix( GetTextToEndGroup( sTmp
) );
1072 // falls vollstaendige Numerierung an ist und das Zeichen davor ein
1073 // Punkt ist, dann will RTF den Punkt als Trenner zwischen den Ebenen
1074 // haben - das haben wir aber schon als default
1075 if( 1 < pCurNumFmt
->GetIncludeUpperLevels() &&
1076 1 == pCurNumFmt
->GetPrefix().Len() &&
1077 '.' == pCurNumFmt
->GetPrefix().GetChar( 0 ) &&
1078 SVX_NUM_CHAR_SPECIAL
!= pCurNumFmt
->GetNumberingType() )
1079 pCurNumFmt
->SetPrefix( aEmptyStr
);
1081 // falls das ein nicht numerierter Absatz mit ein Prefix-Text mit
1082 // einem Zeichen ist, dann setze den als Bulletzeichen
1083 if( pCurNumFmt
->GetCharFmt() && SVX_NUM_NUMBER_NONE
== pCurNumFmt
->GetNumberingType() &&
1084 3 == nListNo
&& 1 == pCurNumFmt
->GetPrefix().Len() )
1086 SwCharFmt
* pChFmt
= pCurNumFmt
->GetCharFmt();
1087 pCurNumFmt
->SetNumberingType(SVX_NUM_CHAR_SPECIAL
);
1088 pCurNumFmt
->SetBulletFont( FindFontOfItem( pChFmt
->GetFont() ) );
1090 pCurNumFmt
->SetBulletChar( pCurNumFmt
->GetPrefix().GetChar( 0 ) );
1091 pCurNumFmt
->SetPrefix( aEmptyStr
);
1093 // den Font oder sogar das gesamte CharFormat loeschen?
1094 if( SFX_ITEM_SET
== pChFmt
->GetItemState( RES_CHRATR_FONT
, FALSE
))
1096 if( 1 == pChFmt
->GetAttrSet().Count() )
1098 pCurNumFmt
->SetCharFmt( 0 );
1099 pDoc
->DelCharFmt( pChFmt
);
1102 pChFmt
->ResetFmtAttr( RES_CHRATR_FONT
);
1106 SkipToken( -1 ); // die schliesende Klammer wird "oben" ausgewertet
1113 // dann noch die Ausgabe-Funktionen (nur fuer WinWord 97)
1115 BOOL
lcl_IsExportNumRule( const SwNumRule
& rRule
, BYTE
* pEnd
= 0 )
1117 BYTE nEnd
= MAXLEVEL
;
1118 while( nEnd
-- && !rRule
.GetNumFmt( nEnd
))
1122 const SwNumFmt
* pNFmt
;
1125 for( nLvl
= 0; nLvl
< nEnd
; ++nLvl
)
1126 if( SVX_NUM_NUMBER_NONE
!= ( pNFmt
= &rRule
.Get( nLvl
))
1127 ->GetNumberingType() || pNFmt
->GetPrefix().Len() ||
1128 (pNFmt
->GetSuffix().Len() && pNFmt
->GetSuffix() != aDotStr
))
1133 return nLvl
!= nEnd
;
1136 void SwRTFWriter::OutRTFListTab()
1138 ByteString sOverrideList
;
1139 USHORT nId
= 1, nTmplId
= 1, n
;
1141 // prepare the NodeNum to generate the NumString
1142 SwNumberTree::tNumberVector aNumVector
;
1143 for( n
= 0; n
< MAXLEVEL
; ++n
)
1144 aNumVector
.push_back(n
);
1145 BYTE aNumLvlPos
[ MAXLEVEL
];
1150 for( n
= 0; n
< pNumRuleTbl
->Count(); ++n
)
1152 const SwNumRule
* pRule
= (*pNumRuleTbl
)[ n
];
1154 // mit der ersten Rule wird auch die ListTable geschrieben
1155 if( !sOverrideList
.Len() )
1156 OutComment( *this, OOO_STRING_SVTOOLS_RTF_LISTTABLE
);
1158 Strm() << '{' << OOO_STRING_SVTOOLS_RTF_LIST
<< OOO_STRING_SVTOOLS_RTF_LISTTEMPLATEID
;
1159 OutULong( nTmplId
);
1162 if( pRule
->IsContinusNum() )
1163 Strm() << OOO_STRING_SVTOOLS_RTF_LISTSIMPLE
;
1166 lcl_IsExportNumRule( *pRule
, &nEnd
);
1168 for( nLvl
= 0; nLvl
< nEnd
; ++nLvl
)
1170 const SwNumFmt
& rFmt
= pRule
->Get( nLvl
);
1172 if( nLvl
> 8 ) // RTF-kennt nur 9 Ebenen
1173 OutComment( *this, OOO_STRING_SVTOOLS_RTF_SOUTLVL
);
1175 Strm() << '{' << OOO_STRING_SVTOOLS_RTF_LISTLEVEL
<< OOO_STRING_SVTOOLS_RTF_LEVELNFC
;
1178 switch( rFmt
.GetNumberingType() )
1180 case SVX_NUM_ROMAN_UPPER
: nVal
= 1; break;
1181 case SVX_NUM_ROMAN_LOWER
: nVal
= 2; break;
1182 case SVX_NUM_CHARS_UPPER_LETTER
:
1183 case SVX_NUM_CHARS_UPPER_LETTER_N
: nVal
= 3; break;
1184 case SVX_NUM_CHARS_LOWER_LETTER
:
1185 case SVX_NUM_CHARS_LOWER_LETTER_N
: nVal
= 4; break;
1187 case SVX_NUM_BITMAP
:
1188 case SVX_NUM_CHAR_SPECIAL
: nVal
= 23; break;
1190 OutLong( nVal
) << OOO_STRING_SVTOOLS_RTF_LEVELJC
;
1192 switch( rFmt
.GetNumAdjust() )
1194 case SVX_ADJUST_CENTER
: nVal
= 1; break;
1195 case SVX_ADJUST_RIGHT
: nVal
= 2; break;
1196 default: nVal
= 0; break;
1198 OutLong( nVal
) << OOO_STRING_SVTOOLS_RTF_LEVELSTARTAT
;
1199 OutLong( rFmt
.GetStart() )
1200 << OOO_STRING_SVTOOLS_RTF_LEVELFOLLOW
<< "0{" << OOO_STRING_SVTOOLS_RTF_LEVELTEXT
<< ' ';
1202 BOOL bWriteBulletFont
= FALSE
;
1203 memset( aNumLvlPos
, 0, MAXLEVEL
);
1204 if( SVX_NUM_CHAR_SPECIAL
== rFmt
.GetNumberingType() ||
1205 SVX_NUM_BITMAP
== rFmt
.GetNumberingType() )
1208 ByteString
sNo( ByteString::CreateFromInt32( rFmt
.GetBulletChar()));
1209 Strm() << "\\u" << sNo
.GetBuffer() << " ?";
1210 bWriteBulletFont
= TRUE
;
1212 else if( SVX_NUM_NUMBER_NONE
== rFmt
.GetNumberingType() )
1214 String
sOut( rFmt
.GetPrefix() ); sOut
+= rFmt
.GetSuffix();
1218 OutHex( sOut
.Len() );
1219 RTFOutFuncs::Out_String( Strm(), sOut
,
1220 eDefaultEncoding
, bWriteHelpFmt
);
1225 memset( aNumLvlPos
, 0, MAXLEVEL
);
1226 BYTE
* pLvlPos
= aNumLvlPos
;
1227 // --> OD 2005-11-18 #128056#
1228 // correction of refactoring done by cws swnumtree:
1229 // - the numbering string has to be restrict to the level
1230 // currently working on.
1231 String
sNumStr( pRule
->MakeNumString( aNumVector
, FALSE
, TRUE
, nLvl
));
1234 // now search the nums in the string
1235 for( BYTE i
= 0; i
<= nLvl
; ++i
)
1237 String
sSrch( String::CreateFromInt32( i
));
1238 xub_StrLen nFnd
= sNumStr
.Search( sSrch
);
1239 if( STRING_NOTFOUND
!= nFnd
)
1241 *pLvlPos
= (BYTE
)(nFnd
+ rFmt
.GetPrefix().Len() + 1 );
1243 sNumStr
.SetChar( nFnd
, (sal_Unicode
)i
);
1248 OutHex( sNumStr
.Len() + rFmt
.GetPrefix().Len() +
1249 rFmt
.GetSuffix().Len() );
1251 if( rFmt
.GetPrefix().Len() )
1252 RTFOutFuncs::Out_String( Strm(), rFmt
.GetPrefix(),
1253 eDefaultEncoding
, bWriteHelpFmt
);
1256 for( xub_StrLen x
= 0; x
< sNumStr
.Len(); ++x
)
1257 if( sNumStr
.GetChar( x
) < 0x20 ||
1258 sNumStr
.GetChar( x
) > 0xFF )
1260 Strm() << "\\'"; OutHex( sNumStr
.GetChar( x
) );
1263 Strm() << (sal_Char
)sNumStr
.GetChar( x
);
1265 if( rFmt
.GetSuffix().Len() )
1266 RTFOutFuncs::Out_String( Strm(), rFmt
.GetSuffix(),
1267 eDefaultEncoding
, bWriteHelpFmt
);
1270 // write the levelnumbers
1271 Strm() << ";}{" << OOO_STRING_SVTOOLS_RTF_LEVELNUMBERS
;
1272 for( BYTE i
= 0; i
<= nLvl
&& aNumLvlPos
[ i
]; ++i
)
1274 Strm() << "\\'"; OutHex( aNumLvlPos
[ i
] );
1278 if( rFmt
.GetCharFmt() )
1279 Out_SfxItemSet( aRTFAttrFnTab
, *this,
1280 rFmt
.GetCharFmt()->GetAttrSet(), TRUE
);
1282 if( bWriteBulletFont
)
1284 Strm() << OOO_STRING_SVTOOLS_RTF_F
;
1285 const Font
* pFont
= rFmt
.GetBulletFont();
1287 // --> OD 2006-06-27 #b6440955#
1288 pFont
= &numfunc::GetDefBulletFont();
1290 OutULong( GetId( *pFont
));
1293 Strm() << OOO_STRING_SVTOOLS_RTF_FI
;
1294 OutLong( rFmt
.GetFirstLineOffset() ) << OOO_STRING_SVTOOLS_RTF_LI
;
1295 OutLong( rFmt
.GetAbsLSpace() );
1299 if( nLvl
> 8 ) // RTF-kennt nur 9 Ebenen
1303 if( !pRule
->IsAutoRule() )
1305 Strm() << '{' << OOO_STRING_SVTOOLS_RTF_LISTNAME
<< ' ';
1306 RTFOutFuncs::Out_String( Strm(), pRule
->GetName(), eDefaultEncoding
,
1307 bWriteHelpFmt
) << ";}" ;
1309 Strm() << OOO_STRING_SVTOOLS_RTF_LISTID
;
1310 OutULong( nId
) << '}' << sNewLine
;
1313 ((((((( sTmp
+= OOO_STRING_SVTOOLS_RTF_LISTOVERRIDE
) +=
1314 OOO_STRING_SVTOOLS_RTF_LISTID
) += ByteString::CreateFromInt32( nId
)) +=
1315 OOO_STRING_SVTOOLS_RTF_LISTOVERRIDECOUNT
) += '0' ) +=
1316 OOO_STRING_SVTOOLS_RTF_LS
) += ByteString::CreateFromInt32( n
)) += '}';
1317 sOverrideList
+= sTmp
;
1322 if( sOverrideList
.Len() )
1323 Strm() << "}{" << OOO_STRING_SVTOOLS_RTF_LISTOVERRIDETABLE
1324 << sOverrideList
.GetBuffer() << '}' << sNewLine
;
1327 USHORT
SwRTFWriter::GetId( const SwNumRuleItem
& rItem
) const
1329 USHORT n
, nId
= USHRT_MAX
;
1332 SwRTFWriter
* pThis
= (SwRTFWriter
*)this;
1333 pThis
->BuildNumRuleTbl();
1335 const String
& rNm
= rItem
.GetValue();
1336 for( n
= pNumRuleTbl
->Count(); n
; )
1337 if( (*pNumRuleTbl
)[ --n
]->GetName() == rNm
)
1346 USHORT
SwRTFWriter::GetNumRuleId( const SwNumRule
& rRule
)
1350 SwNumRulePtr pR
= (SwNumRulePtr
)&rRule
;
1351 return pNumRuleTbl
->GetPos( pR
);
1354 void SwRTFWriter::BuildNumRuleTbl()
1356 const SwNumRuleTbl
& rListTbl
= pDoc
->GetNumRuleTbl();
1358 pNumRuleTbl
= new SwNumRuleTbl( (BYTE
)rListTbl
.Count() );
1359 for( USHORT n
= rListTbl
.Count()+1; n
; )
1363 if( n
== rListTbl
.Count() )
1364 pRule
= (SwNumRule
*)pDoc
->GetOutlineNumRule();
1367 pRule
= rListTbl
[ n
];
1368 if( !pDoc
->IsUsed( *pRule
))
1372 if( lcl_IsExportNumRule( *pRule
))
1373 pNumRuleTbl
->Insert( pRule
, pNumRuleTbl
->Count() );
1377 BOOL
SwRTFWriter::OutListNum( const SwTxtNode
& rNd
)
1380 const SwNumRule
* pRule
= rNd
.GetNumRule();
1382 // --> OD 2008-03-18 #refactorlists#
1383 // if( pRule && MAXLEVEL > rNd.GetActualListLevel() )
1384 if( pRule
&& rNd
.IsInList() )
1387 // --> OD 2008-03-18 #refactorlists#
1388 ASSERT( rNd
.GetActualListLevel() >= 0 && rNd
.GetActualListLevel() < MAXLEVEL
,
1389 "<SwRTFWriter::OutListNum(..)> - text node does not have valid list level. Serious defect -> please inform OD" );
1392 bOutFmtAttr
= FALSE
;
1393 bOutListNumTxt
= TRUE
;
1396 const bool bExportNumRule
= USHRT_MAX
!= GetNumRuleId( *pRule
);
1397 const BYTE nLvl
= static_cast< BYTE
>(rNd
.GetActualListLevel());
1398 const SwNumFmt
* pFmt
= pRule
->GetNumFmt( nLvl
);
1400 pFmt
= &pRule
->Get( nLvl
);
1402 const SfxItemSet
& rNdSet
= rNd
.GetSwAttrSet();
1404 SfxItemSet
aSet( *rNdSet
.GetPool(), rNdSet
.GetRanges() );
1405 aSet
.SetParent( &rNdSet
);
1406 SvxLRSpaceItem
aLR( (SvxLRSpaceItem
&)rNdSet
.Get( RES_LR_SPACE
) );
1407 aLR
.SetTxtLeft( aLR
.GetTxtLeft() + pFmt
->GetAbsLSpace() );
1409 aLR
.SetTxtFirstLineOfst( pFmt
->GetFirstLineOffset() );
1410 if ( bExportNumRule
)
1411 Strm() << '{' << OOO_STRING_SVTOOLS_RTF_LISTTEXT
<< OOO_STRING_SVTOOLS_RTF_PARD
<< OOO_STRING_SVTOOLS_RTF_PLAIN
<< ' ';
1414 Out_SfxItemSet( aRTFAttrFnTab
, *this, aSet
, TRUE
);
1416 if( pFmt
->GetCharFmt() )
1417 Out_SfxItemSet( aRTFAttrFnTab
, *this,
1418 pFmt
->GetCharFmt()->GetAttrSet(), TRUE
);
1422 if( SVX_NUM_CHAR_SPECIAL
== pFmt
->GetNumberingType() || SVX_NUM_BITMAP
== pFmt
->GetNumberingType() )
1423 sTxt
= pFmt
->GetBulletChar();
1425 sTxt
= rNd
.GetNumString();
1430 bOutFmtAttr
= FALSE
;
1435 RTFOutFuncs::Out_String(Strm(), sTxt
, eDefaultEncoding
,
1439 if( bExportNumRule
)
1441 if( OUTLINE_RULE
!= pRule
->GetRuleType() )
1443 Strm() << OOO_STRING_SVTOOLS_RTF_TAB
<< '}' << OOO_STRING_SVTOOLS_RTF_ILVL
;
1444 if( nLvl
> 8 ) // RTF-kennt nur 9 Ebenen
1447 OutComment( *this, OOO_STRING_SVTOOLS_RTF_SOUTLVL
);
1448 OutULong( nLvl
) << '}';
1455 Strm() << OOO_STRING_SVTOOLS_RTF_TAB
<< '}';
1457 else if( sTxt
.Len() )
1458 Strm() << OOO_STRING_SVTOOLS_RTF_TAB
;
1460 bOutListNumTxt
= FALSE
;