1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
31 #include <tools/diagnose_ex.h>
32 #include <rtl/tencinfo.h>
33 #include <svl/itemiter.hxx>
34 #include <svl/whiter.hxx>
35 #include <svtools/rtftoken.h>
36 #include <svl/itempool.hxx>
38 #include <comphelper/string.hxx>
40 #include <com/sun/star/lang/Locale.hpp>
41 #include <editeng/scriptspaceitem.hxx>
42 #include <editeng/fontitem.hxx>
43 #include <editeng/colritem.hxx>
44 #include <editeng/svxrtf.hxx>
45 #include <editeng/editids.hrc>
46 #include <vcl/svapp.hxx>
48 #include <com/sun/star/document/XDocumentProperties.hpp>
51 using namespace ::com::sun::star
;
54 SV_IMPL_PTRARR( SvxRTFItemStackList
, SvxRTFItemStackType
* )
56 CharSet
lcl_GetDefaultTextEncodingForRTF()
59 ::com::sun::star::lang::Locale aLocale
;
60 ::rtl::OUString aLangString
;
62 aLocale
= Application::GetSettings().GetLocale();
63 aLangString
= aLocale
.Language
;
65 if ( aLangString
== "ru" || aLangString
== "uk" )
66 return RTL_TEXTENCODING_MS_1251
;
67 if ( aLangString
== "tr" )
68 return RTL_TEXTENCODING_MS_1254
;
70 return RTL_TEXTENCODING_MS_1252
;
73 // -------------- Methods --------------------
75 SvxRTFParser::SvxRTFParser( SfxItemPool
& rPool
, SvStream
& rIn
,
76 uno::Reference
<document::XDocumentProperties
> i_xDocProps
,
78 : SvRTFParser( rIn
, 5 ),
82 m_xDocProps( i_xDocProps
),
86 bNewDoc
= bReadNewDoc
;
88 bChkStyleAttr
= bCalcValue
= bReadDocInfo
= bIsInReadStyleTab
= sal_False
;
89 bIsLeftToRightDef
= sal_True
;
92 RTFPlainAttrMapIds
aTmp( rPool
);
93 aPlainMap
.insert( aPlainMap
.begin(), (sal_uInt16
*)&aTmp
,
94 (sal_uInt16
*)&aTmp
+ (sizeof( RTFPlainAttrMapIds
) / sizeof(sal_uInt16
)) );
97 RTFPardAttrMapIds
aTmp( rPool
);
98 aPardMap
.insert( aPardMap
.begin(), (sal_uInt16
*)&aTmp
,
99 (sal_uInt16
*)&aTmp
+ (sizeof( RTFPardAttrMapIds
) / sizeof(sal_uInt16
)) );
101 pDfltFont
= new Font
;
102 pDfltColor
= new Color
;
105 void SvxRTFParser::EnterEnvironment()
109 void SvxRTFParser::LeaveEnvironment()
113 void SvxRTFParser::ResetPard()
117 SvxRTFParser::~SvxRTFParser()
119 if( !aColorTbl
.empty() )
121 if( !aAttrStack
.empty() )
131 void SvxRTFParser::SetInsPos( const SvxPosition
& rNew
)
135 pInsPos
= rNew
.Clone();
138 SvParserState
SvxRTFParser::CallParser()
140 DBG_ASSERT( pInsPos
, "no insertion position");
145 if( !aColorTbl
.empty() )
147 if( !aFontTbl
.empty() )
149 if( !aStyleTbl
.empty() )
151 if( !aAttrStack
.empty() )
154 bIsSetDfltTab
= sal_False
;
155 bNewGroup
= sal_False
;
160 // generate the correct WhichId table from the set WhichIds.
163 return SvRTFParser::CallParser();
166 void SvxRTFParser::Continue( int nToken
)
168 SvRTFParser::Continue( nToken
);
170 if( SVPAR_PENDING
!= GetStatus() )
173 //Regardless of what "color 0" is, word defaults to auto as the default colour.
179 // is called for each token that is recognized in CallParser
180 void SvxRTFParser::NextToken( int nToken
)
185 case RTF_COLORTBL
: ReadColorTable(); break;
186 case RTF_FONTTBL
: ReadFontTable(); break;
187 case RTF_STYLESHEET
: ReadStyleTable(); break;
192 if( !aFontTbl
.empty() )
193 // Can immediately be set
194 SetDefault( nToken
, nTokenValue
);
196 // is set after reading the font table
197 nDfltFont
= int(nTokenValue
);
204 SetDefault( nToken
, nTokenValue
);
208 case RTF_PICT
: ReadBitmapData(); break;
210 case RTF_LINE
: cCh
= '\n'; goto INSINGLECHAR
;
211 case RTF_TAB
: cCh
= '\t'; goto INSINGLECHAR
;
212 case RTF_SUBENTRYINDEX
: cCh
= ':'; goto INSINGLECHAR
;
214 case RTF_EMDASH
: cCh
= 0x2014; goto INSINGLECHAR
;
215 case RTF_ENDASH
: cCh
= 0x2013; goto INSINGLECHAR
;
216 case RTF_BULLET
: cCh
= 0x2022; goto INSINGLECHAR
;
217 case RTF_LQUOTE
: cCh
= 0x2018; goto INSINGLECHAR
;
218 case RTF_RQUOTE
: cCh
= 0x2019; goto INSINGLECHAR
;
219 case RTF_LDBLQUOTE
: cCh
= 0x201C; goto INSINGLECHAR
;
220 case RTF_RDBLQUOTE
: cCh
= 0x201D; goto INSINGLECHAR
;
222 aToken
= rtl::OUString(cCh
);
223 // no Break, aToken is set as Text
227 // all collected Attributes are set
228 for( sal_uInt16 n
= aAttrSetList
.Count(); n
; )
230 SvxRTFItemStackType
* pStkSet
= aAttrSetList
[--n
];
231 SetAttrSet( *pStkSet
);
232 aAttrSetList
.DeleteAndDestroy( n
);
242 if (bNewGroup
) // Nesting!
248 if( !bNewGroup
) // Empty Group ??
254 if (bReadDocInfo
&& bNewDoc
&& m_xDocProps
.is())
260 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
261 // First overwrite all (all have to be in one group!!)
262 // Could also appear in the RTF-filewithout the IGNORE-Flag; all Groups
263 // with the IGNORE-Flag are overwritten in the default branch.
265 case RTF_SWG_PRTDATA
:
277 // RTF_SHPRSLT disabled for #i19718#
280 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
285 if( RTF_IGNOREFLAG
!= GetStackPtr( -1 )->nTokenId
)
287 nToken
= SkipToken( -1 );
288 if( '{' == GetStackPtr( -1 )->nTokenId
)
289 nToken
= SkipToken( -1 );
291 ReadAttr( nToken
, &GetAttrSet() );
295 switch( nToken
& ~(0xff | RTF_SWGDEFS
) )
297 case RTF_PARFMT
: // hier gibts keine Swg-Defines
298 ReadAttr( nToken
, &GetAttrSet() );
305 if( RTF_SWGDEFS
& nToken
)
307 if( RTF_IGNOREFLAG
!= GetStackPtr( -1 )->nTokenId
)
309 nToken
= SkipToken( -1 );
310 if( '{' == GetStackPtr( -1 )->nTokenId
)
312 nToken
= SkipToken( -1 );
315 ReadAttr( nToken
, &GetAttrSet() );
319 if( /*( '{' == GetStackPtr( -1 )->nTokenId ) ||*/
320 ( RTF_IGNOREFLAG
== GetStackPtr( -1 )->nTokenId
&&
321 '{' == GetStackPtr( -2 )->nTokenId
) )
330 void SvxRTFParser::ReadStyleTable()
332 int nToken
, bSaveChkStyleAttr
= bChkStyleAttr
;
333 sal_uInt16 nStyleNo
= 0;
334 int _nOpenBrakets
= 1; // the first was already detected earlier!!
335 SvxRTFStyleType
* pStyle
= new SvxRTFStyleType( *pAttrPool
, &aWhichMap
[0] );
336 pStyle
->aAttrSet
.Put( GetRTFDefaults() );
338 bIsInReadStyleTab
= sal_True
;
339 bChkStyleAttr
= sal_False
; // Do not check Attribute against the Styles
341 while( _nOpenBrakets
&& IsParserWorking() )
343 switch( nToken
= GetNextToken() )
345 case '}': if( --_nOpenBrakets
&& IsParserWorking() )
346 // Style has been completely read,
347 // so this is still a stable status
348 SaveState( RTF_STYLESHEET
);
352 if( RTF_IGNOREFLAG
!= GetNextToken() )
353 nToken
= SkipToken( -1 );
354 else if( RTF_UNKNOWNCONTROL
!= ( nToken
= GetNextToken() ) &&
356 nToken
= SkipToken( -2 );
359 // filter out at once
361 nToken
= GetNextToken();
363 eState
= SVPAR_ERROR
;
370 case RTF_SBASEDON
: pStyle
->nBasedOn
= sal_uInt16(nTokenValue
); pStyle
->bBasedOnIsSet
=sal_True
; break;
371 case RTF_SNEXT
: pStyle
->nNext
= sal_uInt16(nTokenValue
); break;
372 case RTF_OUTLINELEVEL
:
373 case RTF_SOUTLVL
: pStyle
->nOutlineNo
= sal_uInt8(nTokenValue
); break;
374 case RTF_S
: nStyleNo
= (short)nTokenValue
; break;
375 case RTF_CS
: nStyleNo
= (short)nTokenValue
;
376 pStyle
->bIsCharFmt
= sal_True
;
381 pStyle
->sName
= DelCharAtEnd( aToken
, ';' );
383 if( !aStyleTbl
.empty() )
385 aStyleTbl
.erase(nStyleNo
);
387 // All data from the font is available, so off to the table
388 aStyleTbl
.insert( nStyleNo
, pStyle
);
389 pStyle
= new SvxRTFStyleType( *pAttrPool
, &aWhichMap
[0] );
390 pStyle
->aAttrSet
.Put( GetRTFDefaults() );
395 switch( nToken
& ~(0xff | RTF_SWGDEFS
) )
397 case RTF_PARFMT
: // hier gibts keine Swg-Defines
398 ReadAttr( nToken
, &pStyle
->aAttrSet
);
405 if( RTF_SWGDEFS
& nToken
)
407 if( RTF_IGNOREFLAG
!= GetStackPtr( -1 )->nTokenId
)
409 nToken
= SkipToken( -1 );
410 if( '{' == GetStackPtr( -1 )->nTokenId
)
412 nToken
= SkipToken( -1 );
415 ReadAttr( nToken
, &pStyle
->aAttrSet
);
421 delete pStyle
; // Delete the Last Style
422 SkipToken( -1 ); // the closing brace is evaluated "above"
424 // Flag back to old state
425 bChkStyleAttr
= bSaveChkStyleAttr
;
426 bIsInReadStyleTab
= sal_False
;
429 void SvxRTFParser::ReadColorTable()
432 sal_uInt8 nRed
= 0xff, nGreen
= 0xff, nBlue
= 0xff;
434 while( '}' != ( nToken
= GetNextToken() ) && IsParserWorking() )
438 case RTF_RED
: nRed
= sal_uInt8(nTokenValue
); break;
439 case RTF_GREEN
: nGreen
= sal_uInt8(nTokenValue
); break;
440 case RTF_BLUE
: nBlue
= sal_uInt8(nTokenValue
); break;
443 if( 1 == aToken
.Len()
444 ? aToken
.GetChar( 0 ) != ';'
445 : STRING_NOTFOUND
== aToken
.Search( ';' ) )
446 break; // At least the ';' must be found
451 if( IsParserWorking() )
453 // one color is finished, fill in the table
454 // try to map the values to SV internal names
455 ColorPtr pColor
= new Color( nRed
, nGreen
, nBlue
);
456 if( aColorTbl
.empty() &&
457 sal_uInt8(-1) == nRed
&& sal_uInt8(-1) == nGreen
&& sal_uInt8(-1) == nBlue
)
458 pColor
->SetColor( COL_AUTO
);
459 aColorTbl
.push_back( pColor
);
460 nRed
= 0, nGreen
= 0, nBlue
= 0;
462 // Color has been completely read,
463 // so this is still a stable status
464 SaveState( RTF_COLORTBL
);
469 SkipToken( -1 ); // the closing brace is evaluated "above"
472 void SvxRTFParser::ReadFontTable()
475 int _nOpenBrakets
= 1; // the first was already detected earlier!!
476 Font
* pFont
= new Font();
477 short nFontNo(0), nInsFontNo (0);
478 String sAltNm
, sFntNm
;
479 sal_Bool bIsAltFntNm
= sal_False
, bCheckNewFont
;
481 CharSet nSystemChar
= lcl_GetDefaultTextEncodingForRTF();
482 pFont
->SetCharSet( nSystemChar
);
483 SetEncoding( nSystemChar
);
485 while( _nOpenBrakets
&& IsParserWorking() )
487 bCheckNewFont
= sal_False
;
488 switch( ( nToken
= GetNextToken() ))
491 bIsAltFntNm
= sal_False
;
492 // Style has been completely read,
493 // so this is still a stable status
494 if( --_nOpenBrakets
<= 1 && IsParserWorking() )
495 SaveState( RTF_FONTTBL
);
496 bCheckNewFont
= sal_True
;
497 nInsFontNo
= nFontNo
;
500 if( RTF_IGNOREFLAG
!= GetNextToken() )
501 nToken
= SkipToken( -1 );
502 // immediately skip unknown and all known but non-evaluated
504 else if( RTF_UNKNOWNCONTROL
!= ( nToken
= GetNextToken() ) &&
505 RTF_PANOSE
!= nToken
&& RTF_FNAME
!= nToken
&&
506 RTF_FONTEMB
!= nToken
&& RTF_FONTFILE
!= nToken
)
507 nToken
= SkipToken( -2 );
510 // filter out at once
512 nToken
= GetNextToken();
514 eState
= SVPAR_ERROR
;
520 pFont
->SetFamily( FAMILY_ROMAN
);
523 pFont
->SetFamily( FAMILY_SWISS
);
526 pFont
->SetFamily( FAMILY_MODERN
);
529 pFont
->SetFamily( FAMILY_SCRIPT
);
532 pFont
->SetFamily( FAMILY_DECORATIVE
);
534 // for technical/symbolic font of the CharSet is changed!
536 pFont
->SetCharSet( RTL_TEXTENCODING_SYMBOL
);
537 // deliberate fall through
539 pFont
->SetFamily( FAMILY_DONTKNOW
);
542 if (-1 != nTokenValue
)
544 CharSet nCharSet
= rtl_getTextEncodingFromWindowsCharset(
545 (sal_uInt8
)nTokenValue
);
546 pFont
->SetCharSet(nCharSet
);
547 //When we're in a font, the fontname is in the font
548 //charset, except for symbol fonts I believe
549 if (nCharSet
== RTL_TEXTENCODING_SYMBOL
)
550 nCharSet
= RTL_TEXTENCODING_DONTKNOW
;
551 SetEncoding(nCharSet
);
555 switch( nTokenValue
)
558 pFont
->SetPitch( PITCH_FIXED
);
561 pFont
->SetPitch( PITCH_VARIABLE
);
566 bCheckNewFont
= sal_True
;
567 nInsFontNo
= nFontNo
;
568 nFontNo
= (short)nTokenValue
;
571 bIsAltFntNm
= sal_True
;
574 DelCharAtEnd( aToken
, ';' );
585 if( bCheckNewFont
&& 1 >= _nOpenBrakets
&& sFntNm
.Len() ) // one font is ready
587 // All data from the font is available, so off to the table
589 (sFntNm
+= ';' ) += sAltNm
;
591 pFont
->SetName( sFntNm
);
592 aFontTbl
.insert( nInsFontNo
, pFont
);
594 pFont
->SetCharSet( nSystemChar
);
599 // the last one we have to delete manually
601 SkipToken( -1 ); // the closing brace is evaluated "above"
603 // set the default font in the Document
604 if( bNewDoc
&& IsParserWorking() )
605 SetDefault( RTF_DEFF
, nDfltFont
);
608 void SvxRTFParser::ReadBitmapData()
610 SvRTFParser::ReadBitmapData();
613 void SvxRTFParser::ReadOLEData()
615 SvRTFParser::ReadOLEData();
618 String
& SvxRTFParser::GetTextToEndGroup( String
& rStr
)
621 int _nOpenBrakets
= 1, nToken
; // the first was already detected earlier!!
623 while( _nOpenBrakets
&& IsParserWorking() )
625 switch( nToken
= GetNextToken() )
627 case '}': --_nOpenBrakets
; break;
630 if( RTF_IGNOREFLAG
!= GetNextToken() )
631 nToken
= SkipToken( -1 );
632 else if( RTF_UNKNOWNCONTROL
!= GetNextToken() )
633 nToken
= SkipToken( -2 );
636 // filter out at once
638 nToken
= GetNextToken();
640 eState
= SVPAR_ERROR
;
652 SkipToken( -1 ); // the closing brace is evaluated "above"
656 util::DateTime
SvxRTFParser::GetDateTimeStamp( )
659 sal_Bool bWeiter
= sal_True
;
661 while( bWeiter
&& IsParserWorking() )
663 int nToken
= GetNextToken();
666 case RTF_YR
: aDT
.Year
= (sal_uInt16
)nTokenValue
; break;
667 case RTF_MO
: aDT
.Month
= (sal_uInt16
)nTokenValue
; break;
668 case RTF_DY
: aDT
.Day
= (sal_uInt16
)nTokenValue
; break;
669 case RTF_HR
: aDT
.Hours
= (sal_uInt16
)nTokenValue
; break;
670 case RTF_MIN
: aDT
.Minutes
= (sal_uInt16
)nTokenValue
; break;
675 SkipToken( -1 ); // the closing brace is evaluated "above"
679 void SvxRTFParser::ReadInfo( const sal_Char
* pChkForVerNo
)
681 int _nOpenBrakets
= 1, nToken
; // the first was already detected earlier!!
682 DBG_ASSERT(m_xDocProps
.is(),
683 "SvxRTFParser::ReadInfo: no DocumentProperties");
684 String sStr
, sComment
;
687 while( _nOpenBrakets
&& IsParserWorking() )
689 switch( nToken
= GetNextToken() )
691 case '}': --_nOpenBrakets
; break;
694 if( RTF_IGNOREFLAG
!= GetNextToken() )
695 nToken
= SkipToken( -1 );
696 else if( RTF_UNKNOWNCONTROL
!= GetNextToken() )
697 nToken
= SkipToken( -2 );
700 // filter out at once
702 nToken
= GetNextToken();
704 eState
= SVPAR_ERROR
;
712 m_xDocProps
->setTitle( GetTextToEndGroup( sStr
) );
715 m_xDocProps
->setSubject( GetTextToEndGroup( sStr
) );
718 m_xDocProps
->setAuthor( GetTextToEndGroup( sStr
) );
721 m_xDocProps
->setModifiedBy( GetTextToEndGroup( sStr
) );
725 ::rtl::OUString sTemp
= GetTextToEndGroup( sStr
);
726 m_xDocProps
->setKeywords(
727 ::comphelper::string::convertCommaSeparated(sTemp
) );
731 m_xDocProps
->setDescription( GetTextToEndGroup( sStr
) );
735 sBaseURL
= GetTextToEndGroup( sStr
) ;
739 m_xDocProps
->setCreationDate( GetDateTimeStamp() );
743 m_xDocProps
->setModificationDate( GetDateTimeStamp() );
747 m_xDocProps
->setPrintDate( GetDateTimeStamp() );
751 GetTextToEndGroup( sComment
);
759 nVersNo
= nTokenValue
;
776 COMPARE_EQUAL
== sComment
.CompareToAscii( pChkForVerNo
))
777 nVersionNo
= nVersNo
;
779 SkipToken( -1 ); // the closing brace is evaluated "above"
783 void SvxRTFParser::ClearColorTbl()
785 while ( !aColorTbl
.empty() )
787 delete aColorTbl
.back();
788 aColorTbl
.pop_back();
792 void SvxRTFParser::ClearFontTbl()
797 void SvxRTFParser::ClearStyleTbl()
802 void SvxRTFParser::ClearAttrStack()
804 SvxRTFItemStackType
* pTmp
;
805 for( size_t nCnt
= aAttrStack
.size(); nCnt
; --nCnt
)
807 pTmp
= aAttrStack
.back();
808 aAttrStack
.pop_back();
813 String
& SvxRTFParser::DelCharAtEnd( String
& rStr
, const sal_Unicode cDel
)
815 if( rStr
.Len() && ' ' == rStr
.GetChar( 0 ))
816 rStr
.EraseLeadingChars();
817 if( rStr
.Len() && ' ' == rStr
.GetChar( rStr
.Len()-1 ))
818 rStr
.EraseTrailingChars();
819 if( rStr
.Len() && cDel
== rStr
.GetChar( rStr
.Len()-1 ))
820 rStr
.Erase( rStr
.Len()-1 );
825 const Font
& SvxRTFParser::GetFont( sal_uInt16 nId
)
827 SvxRTFFontTbl::const_iterator it
= aFontTbl
.find( nId
);
829 if( it
== aFontTbl
.end() )
831 const SvxFontItem
& rDfltFont
= (const SvxFontItem
&)
832 pAttrPool
->GetDefaultItem(
833 ((RTFPlainAttrMapIds
*)&aPlainMap
[0])->nFont
);
834 pDfltFont
->SetName( rDfltFont
.GetStyleName() );
835 pDfltFont
->SetFamily( rDfltFont
.GetFamily() );
843 SvxRTFItemStackType
* SvxRTFParser::_GetAttrSet( int bCopyAttr
)
845 SvxRTFItemStackType
* pAkt
= aAttrStack
.empty() ? 0 : aAttrStack
.back();
846 SvxRTFItemStackType
* pNew
;
848 pNew
= new SvxRTFItemStackType( *pAkt
, *pInsPos
, bCopyAttr
);
850 pNew
= new SvxRTFItemStackType( *pAttrPool
, &aWhichMap
[0],
852 pNew
->SetRTFDefaults( GetRTFDefaults() );
854 aAttrStack
.push_back( pNew
);
855 bNewGroup
= sal_False
;
860 void SvxRTFParser::_ClearStyleAttr( SvxRTFItemStackType
& rStkType
)
862 // check attributes to the attributes of the stylesheet or to
863 // the default attrs of the document
864 SfxItemSet
&rSet
= rStkType
.GetAttrSet();
865 const SfxItemPool
& rPool
= *rSet
.GetPool();
866 const SfxPoolItem
* pItem
;
867 SfxWhichIter
aIter( rSet
);
869 if( !IsChkStyleAttr() ||
870 !rStkType
.GetAttrSet().Count() ||
871 aStyleTbl
.count( rStkType
.nStyleNo
) == 0 )
873 for( sal_uInt16 nWhich
= aIter
.GetCurWhich(); nWhich
; nWhich
= aIter
.NextWhich() )
875 if( SFX_WHICH_MAX
> nWhich
&&
876 SFX_ITEM_SET
== rSet
.GetItemState( nWhich
, sal_False
, &pItem
) &&
877 rPool
.GetDefaultItem( nWhich
) == *pItem
)
878 rSet
.ClearItem( nWhich
); // delete
883 // Delete all Attributes, which are already defined in the Style,
884 // from the current AttrSet.
885 SvxRTFStyleType
* pStyle
= aStyleTbl
.find( rStkType
.nStyleNo
)->second
;
886 SfxItemSet
&rStyleSet
= pStyle
->aAttrSet
;
887 const SfxPoolItem
* pSItem
;
888 for( sal_uInt16 nWhich
= aIter
.GetCurWhich(); nWhich
; nWhich
= aIter
.NextWhich() )
890 if( SFX_ITEM_SET
== rStyleSet
.GetItemState( nWhich
, sal_True
, &pSItem
))
892 if( SFX_ITEM_SET
== rSet
.GetItemState( nWhich
, sal_False
, &pItem
)
893 && *pItem
== *pSItem
)
894 rSet
.ClearItem( nWhich
); // delete
896 else if( SFX_WHICH_MAX
> nWhich
&&
897 SFX_ITEM_SET
== rSet
.GetItemState( nWhich
, sal_False
, &pItem
) &&
898 rPool
.GetDefaultItem( nWhich
) == *pItem
)
899 rSet
.ClearItem( nWhich
); // delete
904 void SvxRTFParser::AttrGroupEnd() // process the current, delete from Stack
906 if( !aAttrStack
.empty() )
908 SvxRTFItemStackType
*pOld
= aAttrStack
.empty() ? 0 : aAttrStack
.back();
909 aAttrStack
.pop_back();
910 SvxRTFItemStackType
*pAkt
= aAttrStack
.empty() ? 0 : aAttrStack
.back();
912 do { // middle check loop
913 sal_uLong nOldSttNdIdx
= pOld
->pSttNd
->GetIdx();
914 if( !pOld
->pChildList
&&
915 ((!pOld
->aAttrSet
.Count() && !pOld
->nStyleNo
) ||
916 (nOldSttNdIdx
== pInsPos
->GetNodeIdx() &&
917 pOld
->nSttCnt
== pInsPos
->GetCntIdx() )))
918 break; // no attributes or Area
920 // set only the attributes that are different from the parent
921 if( pAkt
&& pOld
->aAttrSet
.Count() )
923 SfxItemIter
aIter( pOld
->aAttrSet
);
924 const SfxPoolItem
* pItem
= aIter
.GetCurItem(), *pGet
;
927 if( SFX_ITEM_SET
== pAkt
->aAttrSet
.GetItemState(
928 pItem
->Which(), sal_False
, &pGet
) &&
930 pOld
->aAttrSet
.ClearItem( pItem
->Which() );
932 if( aIter
.IsAtEnd() )
934 pItem
= aIter
.NextItem();
937 if( !pOld
->aAttrSet
.Count() && !pOld
->pChildList
&&
942 // Set all attributes which have been defined from start until here
943 int bCrsrBack
= !pInsPos
->GetCntIdx();
946 // at the beginning of a paragraph? Move back one position
947 sal_uLong nNd
= pInsPos
->GetNodeIdx();
948 MovePos( sal_False
);
949 // if can not move backward then later dont move forward !
950 bCrsrBack
= nNd
!= pInsPos
->GetNodeIdx();
953 if( ( pOld
->pSttNd
->GetIdx() < pInsPos
->GetNodeIdx() ||
954 ( pOld
->pSttNd
->GetIdx() == pInsPos
->GetNodeIdx() &&
955 pOld
->nSttCnt
<= pInsPos
->GetCntIdx() ))
960 // all pard attributes are only valid until the previous
962 if( nOldSttNdIdx
== pInsPos
->GetNodeIdx() )
967 // Now it gets complicated:
968 // - all character attributes sre keep the area
969 // - all paragraph attributes to get the area
970 // up to the previous paragraph
971 SvxRTFItemStackType
* pNew
= new SvxRTFItemStackType(
972 *pOld
, *pInsPos
, sal_True
);
973 pNew
->aAttrSet
.SetParent( pOld
->aAttrSet
.GetParent() );
975 // Delete all paragraph attributes from pNew
976 for( sal_uInt16 n
= 0; n
< aPardMap
.size() &&
977 pNew
->aAttrSet
.Count(); ++n
)
979 pNew
->aAttrSet
.ClearItem( aPardMap
[n
] );
980 pNew
->SetRTFDefaults( GetRTFDefaults() );
983 if( pNew
->aAttrSet
.Count() == pOld
->aAttrSet
.Count() )
989 // Now span the real area of pNew from old
990 SetEndPrevPara( pOld
->pEndNd
, pOld
->nEndCnt
);
993 if( IsChkStyleAttr() )
995 _ClearStyleAttr( *pOld
);
996 _ClearStyleAttr( *pNew
); //#i10381#, methinks.
1006 // Last off the stack, thus cache it until the next text was
1007 // read. (Span no attributes!)
1009 aAttrSetList
.Insert( pOld
, aAttrSetList
.Count() );
1010 aAttrSetList
.Insert( pNew
, aAttrSetList
.Count() );
1012 pOld
= 0; // Do not delete pOld
1018 pOld
->pEndNd
= pInsPos
->MakeNodeIdx();
1019 pOld
->nEndCnt
= pInsPos
->GetCntIdx();
1023 If the parent (pAkt) sets something e.g. , and the child (pOld)
1024 unsets it and the style both are based on has it unset then
1025 clearing the pOld by looking at the style is clearly a disaster
1026 as the text ends up with pAkts bold and not pOlds no bold, this
1027 should be rethought out. For the moment its safest to just do
1028 the clean if we have no parent, all we suffer is too many
1029 redundant properties.
1031 if (IsChkStyleAttr() && !pAkt
)
1032 _ClearStyleAttr( *pOld
);
1037 // split up and create new entry, because it make no sense
1038 // to create a "so long" depend list. Bug 95010
1039 if( bCrsrBack
&& 50 < pAkt
->pChildList
->Count() )
1041 // at the beginning of a paragraph? Move back one position
1042 MovePos( sal_True
);
1043 bCrsrBack
= sal_False
;
1045 // Open a new Group.
1046 SvxRTFItemStackType
* pNew
= new SvxRTFItemStackType(
1047 *pAkt
, *pInsPos
, sal_True
);
1048 pNew
->SetRTFDefaults( GetRTFDefaults() );
1050 // Set all until here valid Attributes
1052 pAkt
= aAttrStack
.empty() ? 0 : aAttrStack
.back(); // can be changed after AttrGroupEnd!
1053 pNew
->aAttrSet
.SetParent( pAkt
? &pAkt
->aAttrSet
: 0 );
1054 aAttrStack
.push_back( pNew
);
1059 // Last off the stack, thus cache it until the next text was
1060 // read. (Span no attributes!)
1061 aAttrSetList
.Insert( pOld
, aAttrSetList
.Count() );
1067 // at the beginning of a paragraph? Move back one position
1068 MovePos( sal_True
);
1070 } while( sal_False
);
1075 bNewGroup
= sal_False
;
1079 void SvxRTFParser::SetAllAttrOfStk() // end all Attr. and set it into doc
1081 // repeat until all attributes will be taken from stack
1082 while( !aAttrStack
.empty() )
1085 for( sal_uInt16 n
= aAttrSetList
.Count(); n
; )
1087 SvxRTFItemStackType
* pStkSet
= aAttrSetList
[--n
];
1088 SetAttrSet( *pStkSet
);
1089 aAttrSetList
.DeleteAndDestroy( n
);
1093 // sets all the attributes that are different from the current
1094 void SvxRTFParser::SetAttrSet( SvxRTFItemStackType
&rSet
)
1096 // Was DefTab never read? then set to default
1097 if( !bIsSetDfltTab
)
1098 SetDefault( RTF_DEFTAB
, 720 );
1100 if( rSet
.pChildList
)
1101 rSet
.Compress( *this );
1102 if( rSet
.aAttrSet
.Count() || rSet
.nStyleNo
)
1103 SetAttrInDoc( rSet
);
1105 // then process all the children
1106 if( rSet
.pChildList
)
1107 for( sal_uInt16 n
= 0; n
< rSet
.pChildList
->Count(); ++n
)
1108 SetAttrSet( *(*rSet
.pChildList
)[ n
] );
1111 // Has no Text been inserted yet? (SttPos from the top Stack entry!)
1112 int SvxRTFParser::IsAttrSttPos()
1114 SvxRTFItemStackType
* pAkt
= aAttrStack
.empty() ? 0 : aAttrStack
.back();
1115 return !pAkt
|| (pAkt
->pSttNd
->GetIdx() == pInsPos
->GetNodeIdx() &&
1116 pAkt
->nSttCnt
== pInsPos
->GetCntIdx());
1120 void SvxRTFParser::SetAttrInDoc( SvxRTFItemStackType
& )
1124 void SvxRTFParser::BuildWhichTbl()
1127 aWhichMap
.push_back( 0 );
1129 // Building a Which-Map 'rWhichMap' from an Array of
1130 // 'pWhichIds' frm Which-Ids. It has the long 'nWhichIds'.
1131 // The Which-Map is not going to be deleted.
1132 SvParser::BuildWhichTbl( aWhichMap
, (sal_uInt16
*)&aPardMap
[0], aPardMap
.size() );
1133 SvParser::BuildWhichTbl( aWhichMap
, (sal_uInt16
*)&aPlainMap
[0], aPlainMap
.size() );
1136 const SfxItemSet
& SvxRTFParser::GetRTFDefaults()
1140 pRTFDefaults
= new SfxItemSet( *pAttrPool
, &aWhichMap
[0] );
1142 if( 0 != ( nId
= ((RTFPardAttrMapIds
*)&aPardMap
[0])->nScriptSpace
))
1144 SvxScriptSpaceItem
aItem( sal_False
, nId
);
1146 pAttrPool
->SetPoolDefaultItem( aItem
);
1148 pRTFDefaults
->Put( aItem
);
1151 return *pRTFDefaults
;
1155 SvxRTFStyleType::SvxRTFStyleType( SfxItemPool
& rPool
, const sal_uInt16
* pWhichRange
)
1156 : aAttrSet( rPool
, pWhichRange
)
1158 nOutlineNo
= sal_uInt8(-1); // not set
1160 bBasedOnIsSet
= sal_False
; //$flr #117411#
1162 bIsCharFmt
= sal_False
;
1166 SvxRTFItemStackType::SvxRTFItemStackType(
1167 SfxItemPool
& rPool
, const sal_uInt16
* pWhichRange
,
1168 const SvxPosition
& rPos
)
1169 : aAttrSet( rPool
, pWhichRange
),
1173 pSttNd
= rPos
.MakeNodeIdx();
1174 nSttCnt
= rPos
.GetCntIdx();
1179 SvxRTFItemStackType::SvxRTFItemStackType(
1180 const SvxRTFItemStackType
& rCpy
,
1181 const SvxPosition
& rPos
,
1183 : aAttrSet( *rCpy
.aAttrSet
.GetPool(), rCpy
.aAttrSet
.GetRanges() ),
1185 nStyleNo( rCpy
.nStyleNo
)
1187 pSttNd
= rPos
.MakeNodeIdx();
1188 nSttCnt
= rPos
.GetCntIdx();
1192 aAttrSet
.SetParent( &rCpy
.aAttrSet
);
1194 aAttrSet
.Put( rCpy
.aAttrSet
);
1197 SvxRTFItemStackType::~SvxRTFItemStackType()
1201 if( pSttNd
!= pEndNd
)
1206 void SvxRTFItemStackType::Add( SvxRTFItemStackType
* pIns
)
1209 pChildList
= new SvxRTFItemStackList( 4 );
1210 pChildList
->Insert( pIns
, pChildList
->Count() );
1213 void SvxRTFItemStackType::SetStartPos( const SvxPosition
& rPos
)
1215 if (pSttNd
!= pEndNd
)
1218 pSttNd
= rPos
.MakeNodeIdx();
1220 nSttCnt
= rPos
.GetCntIdx();
1223 void SvxRTFItemStackType::MoveFullNode(const SvxNodeIdx
&rOldNode
,
1224 const SvxNodeIdx
&rNewNode
)
1226 bool bSameEndAsStart
= (pSttNd
== pEndNd
) ? true : false;
1228 if (GetSttNodeIdx() == rOldNode
.GetIdx())
1231 pSttNd
= rNewNode
.Clone();
1232 if (bSameEndAsStart
)
1236 if (!bSameEndAsStart
&& GetEndNodeIdx() == rOldNode
.GetIdx())
1239 pEndNd
= rNewNode
.Clone();
1242 //And the same for all the children
1243 sal_uInt16 nCount
= pChildList
? pChildList
->Count() : 0;
1244 for (sal_uInt16 i
= 0; i
< nCount
; ++i
)
1246 SvxRTFItemStackType
* pStk
= (*pChildList
)[i
];
1247 pStk
->MoveFullNode(rOldNode
, rNewNode
);
1251 bool SvxRTFParser::UncompressableStackEntry(const SvxRTFItemStackType
&) const
1256 void SvxRTFItemStackType::Compress( const SvxRTFParser
& rParser
)
1258 ENSURE_OR_RETURN_VOID(pChildList
, "Compress: no ChildList" );
1259 ENSURE_OR_RETURN_VOID(pChildList
->Count(), "Compress: ChildList empty");
1262 SvxRTFItemStackType
* pTmp
= (*pChildList
)[0];
1264 if( !pTmp
->aAttrSet
.Count() ||
1265 pSttNd
->GetIdx() != pTmp
->pSttNd
->GetIdx() ||
1266 nSttCnt
!= pTmp
->nSttCnt
)
1269 SvxNodeIdx
* pLastNd
= pTmp
->pEndNd
;
1270 xub_StrLen nLastCnt
= pTmp
->nEndCnt
;
1272 SfxItemSet
aMrgSet( pTmp
->aAttrSet
);
1273 for( n
= 1; n
< pChildList
->Count(); ++n
)
1275 pTmp
= (*pChildList
)[n
];
1276 if( pTmp
->pChildList
)
1277 pTmp
->Compress( rParser
);
1280 ? (pLastNd
->GetIdx()+1 != pTmp
->pSttNd
->GetIdx() ||
1281 !rParser
.IsEndPara( pLastNd
, nLastCnt
) )
1282 : ( pTmp
->nSttCnt
!= nLastCnt
||
1283 pLastNd
->GetIdx() != pTmp
->pSttNd
->GetIdx() ))
1285 while( ++n
< pChildList
->Count() )
1286 if( (pTmp
= (*pChildList
)[n
])->pChildList
)
1287 pTmp
->Compress( rParser
);
1291 if (rParser
.UncompressableStackEntry(*pTmp
))
1296 // Search for all which are set over the whole area
1297 SfxItemIter
aIter( aMrgSet
);
1298 const SfxPoolItem
* pItem
;
1300 sal_uInt16 nWhich
= aIter
.GetCurItem()->Which();
1301 if( SFX_ITEM_SET
!= pTmp
->aAttrSet
.GetItemState( nWhich
,
1302 sal_False
, &pItem
) || *pItem
!= *aIter
.GetCurItem() )
1303 aMrgSet
.ClearItem( nWhich
);
1305 if( aIter
.IsAtEnd() )
1308 } while( sal_True
);
1310 if( !aMrgSet
.Count() )
1314 pLastNd
= pTmp
->pEndNd
;
1315 nLastCnt
= pTmp
->nEndCnt
;
1318 if( pEndNd
->GetIdx() != pLastNd
->GetIdx() || nEndCnt
!= nLastCnt
)
1322 aAttrSet
.Put( aMrgSet
);
1324 for( n
= 0; n
< pChildList
->Count(); ++n
)
1326 pTmp
= (*pChildList
)[n
];
1327 pTmp
->aAttrSet
.Differentiate( aMrgSet
);
1329 if( !pTmp
->pChildList
&& !pTmp
->aAttrSet
.Count() && !pTmp
->nStyleNo
)
1331 pChildList
->Remove( n
);
1337 if( !pChildList
->Count() )
1343 void SvxRTFItemStackType::SetRTFDefaults( const SfxItemSet
& rDefaults
)
1345 if( rDefaults
.Count() )
1347 SfxItemIter
aIter( rDefaults
);
1349 sal_uInt16 nWhich
= aIter
.GetCurItem()->Which();
1350 if( SFX_ITEM_SET
!= aAttrSet
.GetItemState( nWhich
, sal_False
))
1351 aAttrSet
.Put( *aIter
.GetCurItem() );
1353 if( aIter
.IsAtEnd() )
1356 } while( sal_True
);
1361 RTFPlainAttrMapIds::RTFPlainAttrMapIds( const SfxItemPool
& rPool
)
1363 nCaseMap
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CASEMAP
, sal_False
);
1364 nBgColor
= rPool
.GetTrueWhich( SID_ATTR_BRUSH_CHAR
, sal_False
);
1365 nColor
= rPool
.GetTrueWhich( SID_ATTR_CHAR_COLOR
, sal_False
);
1366 nContour
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CONTOUR
, sal_False
);
1367 nCrossedOut
= rPool
.GetTrueWhich( SID_ATTR_CHAR_STRIKEOUT
, sal_False
);
1368 nEscapement
= rPool
.GetTrueWhich( SID_ATTR_CHAR_ESCAPEMENT
, sal_False
);
1369 nFont
= rPool
.GetTrueWhich( SID_ATTR_CHAR_FONT
, sal_False
);
1370 nFontHeight
= rPool
.GetTrueWhich( SID_ATTR_CHAR_FONTHEIGHT
, sal_False
);
1371 nKering
= rPool
.GetTrueWhich( SID_ATTR_CHAR_KERNING
, sal_False
);
1372 nLanguage
= rPool
.GetTrueWhich( SID_ATTR_CHAR_LANGUAGE
, sal_False
);
1373 nPosture
= rPool
.GetTrueWhich( SID_ATTR_CHAR_POSTURE
, sal_False
);
1374 nShadowed
= rPool
.GetTrueWhich( SID_ATTR_CHAR_SHADOWED
, sal_False
);
1375 nUnderline
= rPool
.GetTrueWhich( SID_ATTR_CHAR_UNDERLINE
, sal_False
);
1376 nOverline
= rPool
.GetTrueWhich( SID_ATTR_CHAR_OVERLINE
, sal_False
);
1377 nWeight
= rPool
.GetTrueWhich( SID_ATTR_CHAR_WEIGHT
, sal_False
);
1378 nWordlineMode
= rPool
.GetTrueWhich( SID_ATTR_CHAR_WORDLINEMODE
, sal_False
);
1379 nAutoKerning
= rPool
.GetTrueWhich( SID_ATTR_CHAR_AUTOKERN
, sal_False
);
1381 nCJKFont
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CJK_FONT
, sal_False
);
1382 nCJKFontHeight
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CJK_FONTHEIGHT
, sal_False
);
1383 nCJKLanguage
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CJK_LANGUAGE
, sal_False
);
1384 nCJKPosture
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CJK_POSTURE
, sal_False
);
1385 nCJKWeight
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CJK_WEIGHT
, sal_False
);
1386 nCTLFont
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CTL_FONT
, sal_False
);
1387 nCTLFontHeight
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CTL_FONTHEIGHT
, sal_False
);
1388 nCTLLanguage
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CTL_LANGUAGE
, sal_False
);
1389 nCTLPosture
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CTL_POSTURE
, sal_False
);
1390 nCTLWeight
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CTL_WEIGHT
, sal_False
);
1391 nEmphasis
= rPool
.GetTrueWhich( SID_ATTR_CHAR_EMPHASISMARK
, sal_False
);
1392 nTwoLines
= rPool
.GetTrueWhich( SID_ATTR_CHAR_TWO_LINES
, sal_False
);
1393 nRuby
= 0; //rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_RUBY, sal_False );
1394 nCharScaleX
= rPool
.GetTrueWhich( SID_ATTR_CHAR_SCALEWIDTH
, sal_False
);
1395 nHorzVert
= rPool
.GetTrueWhich( SID_ATTR_CHAR_ROTATED
, sal_False
);
1396 nRelief
= rPool
.GetTrueWhich( SID_ATTR_CHAR_RELIEF
, sal_False
);
1397 nHidden
= rPool
.GetTrueWhich( SID_ATTR_CHAR_HIDDEN
, sal_False
);
1400 RTFPardAttrMapIds ::RTFPardAttrMapIds ( const SfxItemPool
& rPool
)
1402 nLinespacing
= rPool
.GetTrueWhich( SID_ATTR_PARA_LINESPACE
, sal_False
);
1403 nAdjust
= rPool
.GetTrueWhich( SID_ATTR_PARA_ADJUST
, sal_False
);
1404 nTabStop
= rPool
.GetTrueWhich( SID_ATTR_TABSTOP
, sal_False
);
1405 nHyphenzone
= rPool
.GetTrueWhich( SID_ATTR_PARA_HYPHENZONE
, sal_False
);
1406 nLRSpace
= rPool
.GetTrueWhich( SID_ATTR_LRSPACE
, sal_False
);
1407 nULSpace
= rPool
.GetTrueWhich( SID_ATTR_ULSPACE
, sal_False
);
1408 nBrush
= rPool
.GetTrueWhich( SID_ATTR_BRUSH
, sal_False
);
1409 nBox
= rPool
.GetTrueWhich( SID_ATTR_BORDER_OUTER
, sal_False
);
1410 nShadow
= rPool
.GetTrueWhich( SID_ATTR_BORDER_SHADOW
, sal_False
);
1411 nOutlineLvl
= rPool
.GetTrueWhich( SID_ATTR_PARA_OUTLLEVEL
, sal_False
);
1412 nSplit
= rPool
.GetTrueWhich( SID_ATTR_PARA_SPLIT
, sal_False
);
1413 nKeep
= rPool
.GetTrueWhich( SID_ATTR_PARA_KEEP
, sal_False
);
1414 nFontAlign
= rPool
.GetTrueWhich( SID_PARA_VERTALIGN
, sal_False
);
1415 nScriptSpace
= rPool
.GetTrueWhich( SID_ATTR_PARA_SCRIPTSPACE
, sal_False
);
1416 nHangPunct
= rPool
.GetTrueWhich( SID_ATTR_PARA_HANGPUNCTUATION
, sal_False
);
1417 nForbRule
= rPool
.GetTrueWhich( SID_ATTR_PARA_FORBIDDEN_RULES
, sal_False
);
1418 nDirection
= rPool
.GetTrueWhich( SID_ATTR_FRAMEDIRECTION
, sal_False
);
1421 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */