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 .
22 #include <tools/diagnose_ex.h>
23 #include <rtl/tencinfo.h>
24 #include <svl/itemiter.hxx>
25 #include <svl/whiter.hxx>
26 #include <svtools/rtftoken.h>
27 #include <svl/itempool.hxx>
29 #include <comphelper/string.hxx>
31 #include <com/sun/star/lang/Locale.hpp>
32 #include <editeng/scriptspaceitem.hxx>
33 #include <editeng/fontitem.hxx>
34 #include <editeng/colritem.hxx>
35 #include <editeng/svxrtf.hxx>
36 #include <editeng/editids.hrc>
37 #include <vcl/svapp.hxx>
38 #include <vcl/settings.hxx>
40 #include <com/sun/star/document/XDocumentProperties.hpp>
43 using namespace ::com::sun::star
;
46 static rtl_TextEncoding
lcl_GetDefaultTextEncodingForRTF()
49 OUString
aLangString( Application::GetSettings().GetLanguageTag().getLanguage());
51 if ( aLangString
== "ru" || aLangString
== "uk" )
52 return RTL_TEXTENCODING_MS_1251
;
53 if ( aLangString
== "tr" )
54 return RTL_TEXTENCODING_MS_1254
;
56 return RTL_TEXTENCODING_MS_1252
;
59 // -------------- Methods --------------------
61 SvxRTFParser::SvxRTFParser( SfxItemPool
& rPool
, SvStream
& rIn
,
62 uno::Reference
<document::XDocumentProperties
> i_xDocProps
,
63 bool const bReadNewDoc
)
64 : SvRTFParser( rIn
, 5 )
70 , m_xDocProps( i_xDocProps
)
74 , bNewDoc( bReadNewDoc
)
76 , bIsSetDfltTab( false)
77 , bChkStyleAttr( false )
79 , bPardTokenRead( false)
80 , bReadDocInfo( false )
81 , bIsLeftToRightDef( true)
82 , bIsInReadStyleTab( false)
84 pDfltFont
= new vcl::Font
;
85 pDfltColor
= new Color
;
88 SvxRTFParser::~SvxRTFParser()
90 if( !aColorTbl
.empty() )
92 if( !aAttrStack
.empty() )
102 void SvxRTFParser::SetInsPos( const SvxPosition
& rNew
)
106 pInsPos
= rNew
.Clone();
109 SvParserState
SvxRTFParser::CallParser()
111 DBG_ASSERT( pInsPos
, "no insertion position");
116 if( !aColorTbl
.empty() )
118 if( !aFontTbl
.empty() )
120 if( !aStyleTbl
.empty() )
122 if( !aAttrStack
.empty() )
125 bIsSetDfltTab
= false;
131 // generate the correct WhichId table from the set WhichIds.
134 return SvRTFParser::CallParser();
137 void SvxRTFParser::Continue( int nToken
)
139 SvRTFParser::Continue( nToken
);
141 if( SVPAR_PENDING
!= GetStatus() )
144 //Regardless of what "color 0" is, word defaults to auto as the default colour.
150 // is called for each token that is recognized in CallParser
151 void SvxRTFParser::NextToken( int nToken
)
156 case RTF_COLORTBL
: ReadColorTable(); break;
157 case RTF_FONTTBL
: ReadFontTable(); break;
158 case RTF_STYLESHEET
: ReadStyleTable(); break;
163 if( !aFontTbl
.empty() )
164 // Can immediately be set
165 SetDefault( nToken
, nTokenValue
);
167 // is set after reading the font table
168 nDfltFont
= int(nTokenValue
);
175 SetDefault( nToken
, nTokenValue
);
179 case RTF_PICT
: ReadBitmapData(); break;
181 case RTF_LINE
: cCh
= '\n'; goto INSINGLECHAR
;
182 case RTF_TAB
: cCh
= '\t'; goto INSINGLECHAR
;
183 case RTF_SUBENTRYINDEX
: cCh
= ':'; goto INSINGLECHAR
;
185 case RTF_EMDASH
: cCh
= 0x2014; goto INSINGLECHAR
;
186 case RTF_ENDASH
: cCh
= 0x2013; goto INSINGLECHAR
;
187 case RTF_BULLET
: cCh
= 0x2022; goto INSINGLECHAR
;
188 case RTF_LQUOTE
: cCh
= 0x2018; goto INSINGLECHAR
;
189 case RTF_RQUOTE
: cCh
= 0x2019; goto INSINGLECHAR
;
190 case RTF_LDBLQUOTE
: cCh
= 0x201C; goto INSINGLECHAR
;
191 case RTF_RDBLQUOTE
: cCh
= 0x201D; goto INSINGLECHAR
;
193 aToken
= OUString(cCh
);
194 // no Break, aToken is set as Text
198 // all collected Attributes are set
199 for( sal_uInt16 n
= aAttrSetList
.size(); n
; )
201 SvxRTFItemStackType
* pStkSet
= &aAttrSetList
[--n
];
202 SetAttrSet( *pStkSet
);
203 aAttrSetList
.pop_back();
213 if (bNewGroup
) // Nesting!
218 if( !bNewGroup
) // Empty Group ??
223 if (bReadDocInfo
&& bNewDoc
&& m_xDocProps
.is())
229 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
230 // First overwrite all (all have to be in one group!!)
231 // Could also appear in the RTF-filewithout the IGNORE-Flag; all Groups
232 // with the IGNORE-Flag are overwritten in the default branch.
234 case RTF_SWG_PRTDATA
:
246 // RTF_SHPRSLT disabled for #i19718#
249 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
254 if( RTF_IGNOREFLAG
!= GetStackPtr( -1 )->nTokenId
)
256 nToken
= SkipToken( -1 );
257 if( '{' == GetStackPtr( -1 )->nTokenId
)
258 nToken
= SkipToken( -1 );
260 ReadAttr( nToken
, &GetAttrSet() );
264 switch( nToken
& ~(0xff | RTF_SWGDEFS
) )
266 case RTF_PARFMT
: // hier gibts keine Swg-Defines
267 ReadAttr( nToken
, &GetAttrSet() );
274 if( RTF_SWGDEFS
& nToken
)
276 if( RTF_IGNOREFLAG
!= GetStackPtr( -1 )->nTokenId
)
278 nToken
= SkipToken( -1 );
279 if( '{' == GetStackPtr( -1 )->nTokenId
)
281 nToken
= SkipToken( -1 );
284 ReadAttr( nToken
, &GetAttrSet() );
288 if( /*( '{' == GetStackPtr( -1 )->nTokenId ) ||*/
289 ( RTF_IGNOREFLAG
== GetStackPtr( -1 )->nTokenId
&&
290 '{' == GetStackPtr( -2 )->nTokenId
) )
299 void SvxRTFParser::ReadStyleTable()
301 int nToken
, bSaveChkStyleAttr
= bChkStyleAttr
? 1 : 0;
302 sal_uInt16 nStyleNo
= 0;
303 bool bHasStyleNo
= false;
304 int _nOpenBrakets
= 1; // the first was already detected earlier!!
305 SvxRTFStyleType
* pStyle
= new SvxRTFStyleType( *pAttrPool
, &aWhichMap
[0] );
306 pStyle
->aAttrSet
.Put( GetRTFDefaults() );
308 bIsInReadStyleTab
= true;
309 bChkStyleAttr
= false; // Do not check Attribute against the Styles
311 while( _nOpenBrakets
&& IsParserWorking() )
313 switch( nToken
= GetNextToken() )
315 case '}': if( --_nOpenBrakets
&& IsParserWorking() )
316 // Style has been completely read,
317 // so this is still a stable status
318 SaveState( RTF_STYLESHEET
);
322 if( RTF_IGNOREFLAG
!= GetNextToken() )
323 nToken
= SkipToken( -1 );
324 else if( RTF_UNKNOWNCONTROL
!= ( nToken
= GetNextToken() ) &&
326 nToken
= SkipToken( -2 );
329 // filter out at once
331 nToken
= GetNextToken();
333 eState
= SVPAR_ERROR
;
340 case RTF_SBASEDON
: pStyle
->nBasedOn
= sal_uInt16(nTokenValue
); pStyle
->bBasedOnIsSet
=true; break;
341 case RTF_SNEXT
: pStyle
->nNext
= sal_uInt16(nTokenValue
); break;
342 case RTF_OUTLINELEVEL
:
343 case RTF_SOUTLVL
: pStyle
->nOutlineNo
= sal_uInt8(nTokenValue
); break;
344 case RTF_S
: nStyleNo
= (short)nTokenValue
;
347 case RTF_CS
: nStyleNo
= (short)nTokenValue
;
349 pStyle
->bIsCharFmt
= true;
355 pStyle
->sName
= DelCharAtEnd( aToken
, ';' );
357 if( !aStyleTbl
.empty() )
359 aStyleTbl
.erase(nStyleNo
);
361 // All data from the font is available, so off to the table
362 aStyleTbl
.insert( nStyleNo
, pStyle
);
363 pStyle
= new SvxRTFStyleType( *pAttrPool
, &aWhichMap
[0] );
364 pStyle
->aAttrSet
.Put( GetRTFDefaults() );
370 switch( nToken
& ~(0xff | RTF_SWGDEFS
) )
372 case RTF_PARFMT
: // hier gibts keine Swg-Defines
373 ReadAttr( nToken
, &pStyle
->aAttrSet
);
380 if( RTF_SWGDEFS
& nToken
)
382 if( RTF_IGNOREFLAG
!= GetStackPtr( -1 )->nTokenId
)
384 nToken
= SkipToken( -1 );
385 if( '{' == GetStackPtr( -1 )->nTokenId
)
387 nToken
= SkipToken( -1 );
390 ReadAttr( nToken
, &pStyle
->aAttrSet
);
396 delete pStyle
; // Delete the Last Style
397 SkipToken( -1 ); // the closing brace is evaluated "above"
399 // Flag back to old state
400 bChkStyleAttr
= bSaveChkStyleAttr
;
401 bIsInReadStyleTab
= false;
404 void SvxRTFParser::ReadColorTable()
407 sal_uInt8 nRed
= 0xff, nGreen
= 0xff, nBlue
= 0xff;
409 while( '}' != ( nToken
= GetNextToken() ) && IsParserWorking() )
413 case RTF_RED
: nRed
= sal_uInt8(nTokenValue
); break;
414 case RTF_GREEN
: nGreen
= sal_uInt8(nTokenValue
); break;
415 case RTF_BLUE
: nBlue
= sal_uInt8(nTokenValue
); break;
418 if( 1 == aToken
.getLength()
420 : -1 == aToken
.indexOf( ";" ) )
421 break; // At least the ';' must be found
426 if( IsParserWorking() )
428 // one color is finished, fill in the table
429 // try to map the values to SV internal names
430 ColorPtr pColor
= new Color( nRed
, nGreen
, nBlue
);
431 if( aColorTbl
.empty() &&
432 sal_uInt8(-1) == nRed
&& sal_uInt8(-1) == nGreen
&& sal_uInt8(-1) == nBlue
)
433 pColor
->SetColor( COL_AUTO
);
434 aColorTbl
.push_back( pColor
);
435 nRed
= 0, nGreen
= 0, nBlue
= 0;
437 // Color has been completely read,
438 // so this is still a stable status
439 SaveState( RTF_COLORTBL
);
444 SkipToken( -1 ); // the closing brace is evaluated "above"
447 void SvxRTFParser::ReadFontTable()
450 int _nOpenBrakets
= 1; // the first was already detected earlier!!
451 vcl::Font
* pFont
= new vcl::Font();
452 short nFontNo(0), nInsFontNo (0);
453 OUString sAltNm
, sFntNm
;
454 bool bIsAltFntNm
= false;
456 rtl_TextEncoding nSystemChar
= lcl_GetDefaultTextEncodingForRTF();
457 pFont
->SetCharSet( nSystemChar
);
458 SetEncoding( nSystemChar
);
460 while( _nOpenBrakets
&& IsParserWorking() )
462 bool bCheckNewFont
= false;
463 switch( ( nToken
= GetNextToken() ))
467 // Style has been completely read,
468 // so this is still a stable status
469 if( --_nOpenBrakets
<= 1 && IsParserWorking() )
470 SaveState( RTF_FONTTBL
);
471 bCheckNewFont
= true;
472 nInsFontNo
= nFontNo
;
475 if( RTF_IGNOREFLAG
!= GetNextToken() )
476 nToken
= SkipToken( -1 );
477 // immediately skip unknown and all known but non-evaluated
479 else if( RTF_UNKNOWNCONTROL
!= ( nToken
= GetNextToken() ) &&
480 RTF_PANOSE
!= nToken
&& RTF_FNAME
!= nToken
&&
481 RTF_FONTEMB
!= nToken
&& RTF_FONTFILE
!= nToken
)
482 nToken
= SkipToken( -2 );
485 // filter out at once
487 nToken
= GetNextToken();
489 eState
= SVPAR_ERROR
;
495 pFont
->SetFamily( FAMILY_ROMAN
);
498 pFont
->SetFamily( FAMILY_SWISS
);
501 pFont
->SetFamily( FAMILY_MODERN
);
504 pFont
->SetFamily( FAMILY_SCRIPT
);
507 pFont
->SetFamily( FAMILY_DECORATIVE
);
509 // for technical/symbolic font of the rtl_TextEncoding is changed!
511 pFont
->SetCharSet( RTL_TEXTENCODING_SYMBOL
);
512 // deliberate fall through
514 pFont
->SetFamily( FAMILY_DONTKNOW
);
517 if (-1 != nTokenValue
)
519 rtl_TextEncoding nrtl_TextEncoding
= rtl_getTextEncodingFromWindowsCharset(
520 (sal_uInt8
)nTokenValue
);
521 pFont
->SetCharSet(nrtl_TextEncoding
);
522 //When we're in a font, the fontname is in the font
523 //charset, except for symbol fonts I believe
524 if (nrtl_TextEncoding
== RTL_TEXTENCODING_SYMBOL
)
525 nrtl_TextEncoding
= RTL_TEXTENCODING_DONTKNOW
;
526 SetEncoding(nrtl_TextEncoding
);
530 switch( nTokenValue
)
533 pFont
->SetPitch( PITCH_FIXED
);
536 pFont
->SetPitch( PITCH_VARIABLE
);
541 bCheckNewFont
= true;
542 nInsFontNo
= nFontNo
;
543 nFontNo
= (short)nTokenValue
;
549 DelCharAtEnd( aToken
, ';' );
550 if ( !aToken
.isEmpty() )
560 if( bCheckNewFont
&& 1 >= _nOpenBrakets
&& !sFntNm
.isEmpty() ) // one font is ready
562 // All data from the font is available, so off to the table
563 if (!sAltNm
.isEmpty())
564 sFntNm
= sFntNm
+ ";" + sAltNm
;
566 pFont
->SetName( sFntNm
);
567 aFontTbl
.insert( nInsFontNo
, pFont
);
568 pFont
= new vcl::Font();
569 pFont
->SetCharSet( nSystemChar
);
574 // the last one we have to delete manually
576 SkipToken( -1 ); // the closing brace is evaluated "above"
578 // set the default font in the Document
579 if( bNewDoc
&& IsParserWorking() )
580 SetDefault( RTF_DEFF
, nDfltFont
);
583 void SvxRTFParser::ReadBitmapData()
585 SvRTFParser::ReadBitmapData();
588 void SvxRTFParser::ReadOLEData()
590 SvRTFParser::ReadOLEData();
593 OUString
& SvxRTFParser::GetTextToEndGroup( OUString
& rStr
)
596 int _nOpenBrakets
= 1, nToken
= 0; // the first was already detected earlier!!
598 while( _nOpenBrakets
&& IsParserWorking() )
600 switch( nToken
= GetNextToken() )
602 case '}': --_nOpenBrakets
; break;
605 if( RTF_IGNOREFLAG
!= GetNextToken() )
606 nToken
= SkipToken( -1 );
607 else if( RTF_UNKNOWNCONTROL
!= GetNextToken() )
608 nToken
= SkipToken( -2 );
611 // filter out at once
613 nToken
= GetNextToken();
615 eState
= SVPAR_ERROR
;
627 SkipToken( -1 ); // the closing brace is evaluated "above"
631 util::DateTime
SvxRTFParser::GetDateTimeStamp( )
634 bool bContinue
= true;
636 while( bContinue
&& IsParserWorking() )
638 int nToken
= GetNextToken();
641 case RTF_YR
: aDT
.Year
= (sal_uInt16
)nTokenValue
; break;
642 case RTF_MO
: aDT
.Month
= (sal_uInt16
)nTokenValue
; break;
643 case RTF_DY
: aDT
.Day
= (sal_uInt16
)nTokenValue
; break;
644 case RTF_HR
: aDT
.Hours
= (sal_uInt16
)nTokenValue
; break;
645 case RTF_MIN
: aDT
.Minutes
= (sal_uInt16
)nTokenValue
; break;
650 SkipToken( -1 ); // the closing brace is evaluated "above"
654 void SvxRTFParser::ReadInfo( const sal_Char
* pChkForVerNo
)
656 int _nOpenBrakets
= 1, nToken
= 0; // the first was already detected earlier!!
657 DBG_ASSERT(m_xDocProps
.is(),
658 "SvxRTFParser::ReadInfo: no DocumentProperties");
659 OUString sStr
, sComment
;
662 while( _nOpenBrakets
&& IsParserWorking() )
664 switch( nToken
= GetNextToken() )
666 case '}': --_nOpenBrakets
; break;
669 if( RTF_IGNOREFLAG
!= GetNextToken() )
670 nToken
= SkipToken( -1 );
671 else if( RTF_UNKNOWNCONTROL
!= GetNextToken() )
672 nToken
= SkipToken( -2 );
675 // filter out at once
677 nToken
= GetNextToken();
679 eState
= SVPAR_ERROR
;
687 m_xDocProps
->setTitle( GetTextToEndGroup( sStr
) );
690 m_xDocProps
->setSubject( GetTextToEndGroup( sStr
) );
693 m_xDocProps
->setAuthor( GetTextToEndGroup( sStr
) );
696 m_xDocProps
->setModifiedBy( GetTextToEndGroup( sStr
) );
700 OUString sTemp
= GetTextToEndGroup( sStr
);
701 m_xDocProps
->setKeywords(
702 ::comphelper::string::convertCommaSeparated(sTemp
) );
706 m_xDocProps
->setDescription( GetTextToEndGroup( sStr
) );
710 sBaseURL
= GetTextToEndGroup( sStr
) ;
714 m_xDocProps
->setCreationDate( GetDateTimeStamp() );
718 m_xDocProps
->setModificationDate( GetDateTimeStamp() );
722 m_xDocProps
->setPrintDate( GetDateTimeStamp() );
726 GetTextToEndGroup( sComment
);
734 nVersNo
= nTokenValue
;
751 sComment
== OUString::createFromAscii( pChkForVerNo
) )
752 nVersionNo
= nVersNo
;
754 SkipToken( -1 ); // the closing brace is evaluated "above"
758 void SvxRTFParser::ClearColorTbl()
760 while ( !aColorTbl
.empty() )
762 delete aColorTbl
.back();
763 aColorTbl
.pop_back();
767 void SvxRTFParser::ClearFontTbl()
772 void SvxRTFParser::ClearStyleTbl()
777 void SvxRTFParser::ClearAttrStack()
779 SvxRTFItemStackType
* pTmp
;
780 for( size_t nCnt
= aAttrStack
.size(); nCnt
; --nCnt
)
782 pTmp
= aAttrStack
.back();
783 aAttrStack
.pop_back();
788 OUString
& SvxRTFParser::DelCharAtEnd( OUString
& rStr
, const sal_Unicode cDel
)
790 if( !rStr
.isEmpty() && ' ' == rStr
[ 0 ])
791 rStr
= comphelper::string::stripStart(rStr
, ' ');
792 if( !rStr
.isEmpty() && ' ' == rStr
[ rStr
.getLength()-1 ])
793 rStr
= comphelper::string::stripEnd(rStr
, ' ');
794 if( !rStr
.isEmpty() && cDel
== rStr
[ rStr
.getLength()-1 ])
795 rStr
= rStr
.copy( 0, rStr
.getLength()-1 );
800 const vcl::Font
& SvxRTFParser::GetFont( sal_uInt16 nId
)
802 SvxRTFFontTbl::const_iterator it
= aFontTbl
.find( nId
);
803 const vcl::Font
* pFont
;
804 if( it
== aFontTbl
.end() )
806 const SvxFontItem
& rDfltFont
= static_cast<const SvxFontItem
&>(
807 pAttrPool
->GetDefaultItem( aPlainMap
.nFont
));
808 pDfltFont
->SetName( rDfltFont
.GetStyleName() );
809 pDfltFont
->SetFamily( rDfltFont
.GetFamily() );
817 SvxRTFItemStackType
* SvxRTFParser::_GetAttrSet( bool const bCopyAttr
)
819 SvxRTFItemStackType
* pAkt
= aAttrStack
.empty() ? 0 : aAttrStack
.back();
820 SvxRTFItemStackType
* pNew
;
822 pNew
= new SvxRTFItemStackType( *pAkt
, *pInsPos
, bCopyAttr
);
824 pNew
= new SvxRTFItemStackType( *pAttrPool
, &aWhichMap
[0],
826 pNew
->SetRTFDefaults( GetRTFDefaults() );
828 aAttrStack
.push_back( pNew
);
834 void SvxRTFParser::_ClearStyleAttr( SvxRTFItemStackType
& rStkType
)
836 // check attributes to the attributes of the stylesheet or to
837 // the default attrs of the document
838 SfxItemSet
&rSet
= rStkType
.GetAttrSet();
839 const SfxItemPool
& rPool
= *rSet
.GetPool();
840 const SfxPoolItem
* pItem
;
841 SfxWhichIter
aIter( rSet
);
843 if( !IsChkStyleAttr() ||
844 !rStkType
.GetAttrSet().Count() ||
845 aStyleTbl
.count( rStkType
.nStyleNo
) == 0 )
847 for( sal_uInt16 nWhich
= aIter
.GetCurWhich(); nWhich
; nWhich
= aIter
.NextWhich() )
849 if( SFX_WHICH_MAX
> nWhich
&&
850 SfxItemState::SET
== rSet
.GetItemState( nWhich
, false, &pItem
) &&
851 rPool
.GetDefaultItem( nWhich
) == *pItem
)
852 rSet
.ClearItem( nWhich
); // delete
857 // Delete all Attributes, which are already defined in the Style,
858 // from the current AttrSet.
859 SvxRTFStyleType
* pStyle
= aStyleTbl
.find( rStkType
.nStyleNo
)->second
;
860 SfxItemSet
&rStyleSet
= pStyle
->aAttrSet
;
861 const SfxPoolItem
* pSItem
;
862 for( sal_uInt16 nWhich
= aIter
.GetCurWhich(); nWhich
; nWhich
= aIter
.NextWhich() )
864 if( SfxItemState::SET
== rStyleSet
.GetItemState( nWhich
, true, &pSItem
))
866 if( SfxItemState::SET
== rSet
.GetItemState( nWhich
, false, &pItem
)
867 && *pItem
== *pSItem
)
868 rSet
.ClearItem( nWhich
); // delete
870 else if( SFX_WHICH_MAX
> nWhich
&&
871 SfxItemState::SET
== rSet
.GetItemState( nWhich
, false, &pItem
) &&
872 rPool
.GetDefaultItem( nWhich
) == *pItem
)
873 rSet
.ClearItem( nWhich
); // delete
878 void SvxRTFParser::AttrGroupEnd() // process the current, delete from Stack
880 if( !aAttrStack
.empty() )
882 SvxRTFItemStackType
*pOld
= aAttrStack
.empty() ? 0 : aAttrStack
.back();
883 aAttrStack
.pop_back();
884 SvxRTFItemStackType
*pAkt
= aAttrStack
.empty() ? 0 : aAttrStack
.back();
886 do { // middle check loop
887 sal_Int32 nOldSttNdIdx
= pOld
->pSttNd
->GetIdx();
888 if( !pOld
->pChildList
&&
889 ((!pOld
->aAttrSet
.Count() && !pOld
->nStyleNo
) ||
890 (nOldSttNdIdx
== pInsPos
->GetNodeIdx() &&
891 pOld
->nSttCnt
== pInsPos
->GetCntIdx() )))
892 break; // no attributes or Area
894 // set only the attributes that are different from the parent
895 if( pAkt
&& pOld
->aAttrSet
.Count() )
897 SfxItemIter
aIter( pOld
->aAttrSet
);
898 const SfxPoolItem
* pItem
= aIter
.GetCurItem(), *pGet
;
901 if( SfxItemState::SET
== pAkt
->aAttrSet
.GetItemState(
902 pItem
->Which(), false, &pGet
) &&
904 pOld
->aAttrSet
.ClearItem( pItem
->Which() );
906 if( aIter
.IsAtEnd() )
908 pItem
= aIter
.NextItem();
911 if( !pOld
->aAttrSet
.Count() && !pOld
->pChildList
&&
916 // Set all attributes which have been defined from start until here
917 bool bCrsrBack
= !pInsPos
->GetCntIdx();
920 // at the beginning of a paragraph? Move back one position
921 sal_Int32 nNd
= pInsPos
->GetNodeIdx();
923 // if can not move backward then later dont move forward !
924 bCrsrBack
= nNd
!= pInsPos
->GetNodeIdx();
927 if( ( pOld
->pSttNd
->GetIdx() < pInsPos
->GetNodeIdx() ||
928 ( pOld
->pSttNd
->GetIdx() == pInsPos
->GetNodeIdx() &&
929 pOld
->nSttCnt
<= pInsPos
->GetCntIdx() ))
934 // all pard attributes are only valid until the previous
936 if( nOldSttNdIdx
== pInsPos
->GetNodeIdx() )
941 // Now it gets complicated:
942 // - all character attributes sre keep the area
943 // - all paragraph attributes to get the area
944 // up to the previous paragraph
945 SvxRTFItemStackType
* pNew
= new SvxRTFItemStackType(
946 *pOld
, *pInsPos
, true );
947 pNew
->aAttrSet
.SetParent( pOld
->aAttrSet
.GetParent() );
949 // Delete all paragraph attributes from pNew
950 for( sal_uInt16 n
= 0; n
< (sizeof(aPardMap
) / sizeof(sal_uInt16
)) &&
951 pNew
->aAttrSet
.Count(); ++n
)
952 if( reinterpret_cast<sal_uInt16
*>(&aPardMap
)[n
] )
953 pNew
->aAttrSet
.ClearItem( reinterpret_cast<sal_uInt16
*>(&aPardMap
)[n
] );
954 pNew
->SetRTFDefaults( GetRTFDefaults() );
957 if( pNew
->aAttrSet
.Count() == pOld
->aAttrSet
.Count() )
963 // Now span the real area of pNew from old
964 SetEndPrevPara( pOld
->pEndNd
, pOld
->nEndCnt
);
967 if( IsChkStyleAttr() )
969 _ClearStyleAttr( *pOld
);
970 _ClearStyleAttr( *pNew
); //#i10381#, methinks.
980 // Last off the stack, thus cache it until the next text was
981 // read. (Span no attributes!)
983 aAttrSetList
.push_back( pOld
);
984 aAttrSetList
.push_back( pNew
);
986 pOld
= 0; // Do not delete pOld
992 pOld
->pEndNd
= pInsPos
->MakeNodeIdx();
993 pOld
->nEndCnt
= pInsPos
->GetCntIdx();
997 If the parent (pAkt) sets something e.g. , and the child (pOld)
998 unsets it and the style both are based on has it unset then
999 clearing the pOld by looking at the style is clearly a disaster
1000 as the text ends up with pAkts bold and not pOlds no bold, this
1001 should be rethought out. For the moment its safest to just do
1002 the clean if we have no parent, all we suffer is too many
1003 redundant properties.
1005 if (IsChkStyleAttr() && !pAkt
)
1006 _ClearStyleAttr( *pOld
);
1011 // split up and create new entry, because it make no sense
1012 // to create a "so long" depend list. Bug 95010
1013 if( bCrsrBack
&& 50 < pAkt
->pChildList
->size() )
1015 // at the beginning of a paragraph? Move back one position
1019 // Open a new Group.
1020 SvxRTFItemStackType
* pNew
= new SvxRTFItemStackType(
1021 *pAkt
, *pInsPos
, true );
1022 pNew
->SetRTFDefaults( GetRTFDefaults() );
1024 // Set all until here valid Attributes
1026 pAkt
= aAttrStack
.empty() ? 0 : aAttrStack
.back(); // can be changed after AttrGroupEnd!
1027 pNew
->aAttrSet
.SetParent( pAkt
? &pAkt
->aAttrSet
: 0 );
1028 aAttrStack
.push_back( pNew
);
1033 // Last off the stack, thus cache it until the next text was
1034 // read. (Span no attributes!)
1035 aAttrSetList
.push_back( pOld
);
1041 // at the beginning of a paragraph? Move back one position
1053 void SvxRTFParser::SetAllAttrOfStk() // end all Attr. and set it into doc
1055 // repeat until all attributes will be taken from stack
1056 while( !aAttrStack
.empty() )
1059 for( sal_uInt16 n
= aAttrSetList
.size(); n
; )
1061 SvxRTFItemStackType
* pStkSet
= &aAttrSetList
[--n
];
1062 SetAttrSet( *pStkSet
);
1063 aAttrSetList
.pop_back();
1067 // sets all the attributes that are different from the current
1068 void SvxRTFParser::SetAttrSet( SvxRTFItemStackType
&rSet
)
1070 // Was DefTab never read? then set to default
1071 if( !bIsSetDfltTab
)
1072 SetDefault( RTF_DEFTAB
, 720 );
1074 if( rSet
.pChildList
)
1075 rSet
.Compress( *this );
1076 if( rSet
.aAttrSet
.Count() || rSet
.nStyleNo
)
1077 SetAttrInDoc( rSet
);
1079 // then process all the children
1080 if( rSet
.pChildList
)
1081 for( sal_uInt16 n
= 0; n
< rSet
.pChildList
->size(); ++n
)
1082 SetAttrSet( (*rSet
.pChildList
)[ n
] );
1085 // Has no text been inserted yet? (SttPos from the top Stack entry!)
1086 bool SvxRTFParser::IsAttrSttPos()
1088 SvxRTFItemStackType
* pAkt
= aAttrStack
.empty() ? 0 : aAttrStack
.back();
1089 return !pAkt
|| (pAkt
->pSttNd
->GetIdx() == pInsPos
->GetNodeIdx() &&
1090 pAkt
->nSttCnt
== pInsPos
->GetCntIdx());
1094 void SvxRTFParser::SetAttrInDoc( SvxRTFItemStackType
& )
1098 void SvxRTFParser::BuildWhichTable()
1101 aWhichMap
.push_back( 0 );
1103 // Building a Which-Map 'rWhichMap' from an array of
1104 // 'pWhichIds' from Which-Ids. It has the long 'nWhichIds'.
1105 // The Which-Map is not going to be deleted.
1106 SvParser::BuildWhichTable( aWhichMap
, reinterpret_cast<sal_uInt16
*>(&aPardMap
), sizeof(aPardMap
) / sizeof(sal_uInt16
) );
1107 SvParser::BuildWhichTable( aWhichMap
, reinterpret_cast<sal_uInt16
*>(&aPlainMap
), sizeof(aPlainMap
) / sizeof(sal_uInt16
) );
1110 const SfxItemSet
& SvxRTFParser::GetRTFDefaults()
1114 pRTFDefaults
= new SfxItemSet( *pAttrPool
, &aWhichMap
[0] );
1116 if( 0 != ( nId
= aPardMap
.nScriptSpace
))
1118 SvxScriptSpaceItem
aItem( false, nId
);
1120 pAttrPool
->SetPoolDefaultItem( aItem
);
1122 pRTFDefaults
->Put( aItem
);
1125 return *pRTFDefaults
;
1129 SvxRTFStyleType::SvxRTFStyleType( SfxItemPool
& rPool
, const sal_uInt16
* pWhichRange
)
1130 : aAttrSet( rPool
, pWhichRange
)
1132 nOutlineNo
= sal_uInt8(-1); // not set
1134 bBasedOnIsSet
= false; //$flr #117411#
1140 SvxRTFItemStackType::SvxRTFItemStackType(
1141 SfxItemPool
& rPool
, const sal_uInt16
* pWhichRange
,
1142 const SvxPosition
& rPos
)
1143 : aAttrSet( rPool
, pWhichRange
),
1147 pSttNd
= rPos
.MakeNodeIdx();
1148 nSttCnt
= rPos
.GetCntIdx();
1153 SvxRTFItemStackType::SvxRTFItemStackType(
1154 const SvxRTFItemStackType
& rCpy
,
1155 const SvxPosition
& rPos
,
1156 bool const bCopyAttr
)
1157 : aAttrSet( *rCpy
.aAttrSet
.GetPool(), rCpy
.aAttrSet
.GetRanges() ),
1159 nStyleNo( rCpy
.nStyleNo
)
1161 pSttNd
= rPos
.MakeNodeIdx();
1162 nSttCnt
= rPos
.GetCntIdx();
1166 aAttrSet
.SetParent( &rCpy
.aAttrSet
);
1168 aAttrSet
.Put( rCpy
.aAttrSet
);
1171 SvxRTFItemStackType::~SvxRTFItemStackType()
1175 if( pSttNd
!= pEndNd
)
1180 void SvxRTFItemStackType::Add( SvxRTFItemStackType
* pIns
)
1183 pChildList
= new SvxRTFItemStackList();
1184 pChildList
->push_back( pIns
);
1187 void SvxRTFItemStackType::SetStartPos( const SvxPosition
& rPos
)
1189 if (pSttNd
!= pEndNd
)
1192 pSttNd
= rPos
.MakeNodeIdx();
1194 nSttCnt
= rPos
.GetCntIdx();
1197 void SvxRTFItemStackType::MoveFullNode(const SvxNodeIdx
&rOldNode
,
1198 const SvxNodeIdx
&rNewNode
)
1200 bool bSameEndAsStart
= (pSttNd
== pEndNd
);
1202 if (GetSttNodeIdx() == rOldNode
.GetIdx())
1205 pSttNd
= rNewNode
.Clone();
1206 if (bSameEndAsStart
)
1210 if (!bSameEndAsStart
&& GetEndNodeIdx() == rOldNode
.GetIdx())
1213 pEndNd
= rNewNode
.Clone();
1216 //And the same for all the children
1217 sal_Int32 nCount
= pChildList
? pChildList
->size() : 0;
1218 for (sal_Int32 i
= 0; i
< nCount
; ++i
)
1220 SvxRTFItemStackType
* pStk
= &(*pChildList
)[i
];
1221 pStk
->MoveFullNode(rOldNode
, rNewNode
);
1225 void SvxRTFItemStackType::Compress( const SvxRTFParser
& rParser
)
1227 ENSURE_OR_RETURN_VOID(pChildList
, "Compress: no ChildList" );
1228 ENSURE_OR_RETURN_VOID(!pChildList
->empty(), "Compress: ChildList empty");
1231 SvxRTFItemStackType
* pTmp
= &(*pChildList
)[0];
1233 if( !pTmp
->aAttrSet
.Count() ||
1234 pSttNd
->GetIdx() != pTmp
->pSttNd
->GetIdx() ||
1235 nSttCnt
!= pTmp
->nSttCnt
)
1238 SvxNodeIdx
* pLastNd
= pTmp
->pEndNd
;
1239 sal_Int32 nLastCnt
= pTmp
->nEndCnt
;
1241 SfxItemSet
aMrgSet( pTmp
->aAttrSet
);
1242 for( n
= 1; n
< pChildList
->size(); ++n
)
1244 pTmp
= &(*pChildList
)[n
];
1245 if( pTmp
->pChildList
)
1246 pTmp
->Compress( rParser
);
1249 ? (pLastNd
->GetIdx()+1 != pTmp
->pSttNd
->GetIdx() ||
1250 !rParser
.IsEndPara( pLastNd
, nLastCnt
) )
1251 : ( pTmp
->nSttCnt
!= nLastCnt
||
1252 pLastNd
->GetIdx() != pTmp
->pSttNd
->GetIdx() ))
1254 while( ++n
< pChildList
->size() )
1255 if( (pTmp
= &(*pChildList
)[n
])->pChildList
)
1256 pTmp
->Compress( rParser
);
1262 // Search for all which are set over the whole area
1263 SfxItemIter
aIter( aMrgSet
);
1264 const SfxPoolItem
* pItem
;
1266 sal_uInt16 nWhich
= aIter
.GetCurItem()->Which();
1267 if( SfxItemState::SET
!= pTmp
->aAttrSet
.GetItemState( nWhich
,
1268 false, &pItem
) || *pItem
!= *aIter
.GetCurItem() )
1269 aMrgSet
.ClearItem( nWhich
);
1271 if( aIter
.IsAtEnd() )
1276 if( !aMrgSet
.Count() )
1280 pLastNd
= pTmp
->pEndNd
;
1281 nLastCnt
= pTmp
->nEndCnt
;
1284 if( pEndNd
->GetIdx() != pLastNd
->GetIdx() || nEndCnt
!= nLastCnt
)
1288 aAttrSet
.Put( aMrgSet
);
1290 for( n
= 0; n
< pChildList
->size(); ++n
)
1292 pTmp
= &(*pChildList
)[n
];
1293 pTmp
->aAttrSet
.Differentiate( aMrgSet
);
1295 if( !pTmp
->pChildList
&& !pTmp
->aAttrSet
.Count() && !pTmp
->nStyleNo
)
1297 pChildList
->erase( pChildList
->begin() + n
);
1301 if( pChildList
->empty() )
1307 void SvxRTFItemStackType::SetRTFDefaults( const SfxItemSet
& rDefaults
)
1309 if( rDefaults
.Count() )
1311 SfxItemIter
aIter( rDefaults
);
1313 sal_uInt16 nWhich
= aIter
.GetCurItem()->Which();
1314 if( SfxItemState::SET
!= aAttrSet
.GetItemState( nWhich
, false ))
1315 aAttrSet
.Put( *aIter
.GetCurItem() );
1317 if( aIter
.IsAtEnd() )
1325 RTFPlainAttrMapIds::RTFPlainAttrMapIds( const SfxItemPool
& rPool
)
1327 nCaseMap
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CASEMAP
, false );
1328 nBgColor
= rPool
.GetTrueWhich( SID_ATTR_BRUSH_CHAR
, false );
1329 nColor
= rPool
.GetTrueWhich( SID_ATTR_CHAR_COLOR
, false );
1330 nContour
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CONTOUR
, false );
1331 nCrossedOut
= rPool
.GetTrueWhich( SID_ATTR_CHAR_STRIKEOUT
, false );
1332 nEscapement
= rPool
.GetTrueWhich( SID_ATTR_CHAR_ESCAPEMENT
, false );
1333 nFont
= rPool
.GetTrueWhich( SID_ATTR_CHAR_FONT
, false );
1334 nFontHeight
= rPool
.GetTrueWhich( SID_ATTR_CHAR_FONTHEIGHT
, false );
1335 nKering
= rPool
.GetTrueWhich( SID_ATTR_CHAR_KERNING
, false );
1336 nLanguage
= rPool
.GetTrueWhich( SID_ATTR_CHAR_LANGUAGE
, false );
1337 nPosture
= rPool
.GetTrueWhich( SID_ATTR_CHAR_POSTURE
, false );
1338 nShadowed
= rPool
.GetTrueWhich( SID_ATTR_CHAR_SHADOWED
, false );
1339 nUnderline
= rPool
.GetTrueWhich( SID_ATTR_CHAR_UNDERLINE
, false );
1340 nOverline
= rPool
.GetTrueWhich( SID_ATTR_CHAR_OVERLINE
, false );
1341 nWeight
= rPool
.GetTrueWhich( SID_ATTR_CHAR_WEIGHT
, false );
1342 nWordlineMode
= rPool
.GetTrueWhich( SID_ATTR_CHAR_WORDLINEMODE
, false );
1343 nAutoKerning
= rPool
.GetTrueWhich( SID_ATTR_CHAR_AUTOKERN
, false );
1345 nCJKFont
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CJK_FONT
, false );
1346 nCJKFontHeight
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CJK_FONTHEIGHT
, false );
1347 nCJKLanguage
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CJK_LANGUAGE
, false );
1348 nCJKPosture
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CJK_POSTURE
, false );
1349 nCJKWeight
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CJK_WEIGHT
, false );
1350 nCTLFont
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CTL_FONT
, false );
1351 nCTLFontHeight
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CTL_FONTHEIGHT
, false );
1352 nCTLLanguage
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CTL_LANGUAGE
, false );
1353 nCTLPosture
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CTL_POSTURE
, false );
1354 nCTLWeight
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CTL_WEIGHT
, false );
1355 nEmphasis
= rPool
.GetTrueWhich( SID_ATTR_CHAR_EMPHASISMARK
, false );
1356 nTwoLines
= rPool
.GetTrueWhich( SID_ATTR_CHAR_TWO_LINES
, false );
1357 nRuby
= 0; //rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_RUBY, sal_False );
1358 nCharScaleX
= rPool
.GetTrueWhich( SID_ATTR_CHAR_SCALEWIDTH
, false );
1359 nHorzVert
= rPool
.GetTrueWhich( SID_ATTR_CHAR_ROTATED
, false );
1360 nRelief
= rPool
.GetTrueWhich( SID_ATTR_CHAR_RELIEF
, false );
1361 nHidden
= rPool
.GetTrueWhich( SID_ATTR_CHAR_HIDDEN
, false );
1364 RTFPardAttrMapIds ::RTFPardAttrMapIds ( const SfxItemPool
& rPool
)
1366 nLinespacing
= rPool
.GetTrueWhich( SID_ATTR_PARA_LINESPACE
, false );
1367 nAdjust
= rPool
.GetTrueWhich( SID_ATTR_PARA_ADJUST
, false );
1368 nTabStop
= rPool
.GetTrueWhich( SID_ATTR_TABSTOP
, false );
1369 nHyphenzone
= rPool
.GetTrueWhich( SID_ATTR_PARA_HYPHENZONE
, false );
1370 nLRSpace
= rPool
.GetTrueWhich( SID_ATTR_LRSPACE
, false );
1371 nULSpace
= rPool
.GetTrueWhich( SID_ATTR_ULSPACE
, false );
1372 nBrush
= rPool
.GetTrueWhich( SID_ATTR_BRUSH
, false );
1373 nBox
= rPool
.GetTrueWhich( SID_ATTR_BORDER_OUTER
, false );
1374 nShadow
= rPool
.GetTrueWhich( SID_ATTR_BORDER_SHADOW
, false );
1375 nOutlineLvl
= rPool
.GetTrueWhich( SID_ATTR_PARA_OUTLLEVEL
, false );
1376 nSplit
= rPool
.GetTrueWhich( SID_ATTR_PARA_SPLIT
, false );
1377 nKeep
= rPool
.GetTrueWhich( SID_ATTR_PARA_KEEP
, false );
1378 nFontAlign
= rPool
.GetTrueWhich( SID_PARA_VERTALIGN
, false );
1379 nScriptSpace
= rPool
.GetTrueWhich( SID_ATTR_PARA_SCRIPTSPACE
, false );
1380 nHangPunct
= rPool
.GetTrueWhich( SID_ATTR_PARA_HANGPUNCTUATION
, false );
1381 nForbRule
= rPool
.GetTrueWhich( SID_ATTR_PARA_FORBIDDEN_RULES
, false );
1382 nDirection
= rPool
.GetTrueWhich( SID_ATTR_FRAMEDIRECTION
, false );
1385 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */